嵌入式爱好者

查看: 15525|回复: 5

[Linux] 自己写了三个简单的驱动,都是io口操作的,可以在用户空间直接控制6410的IO口了

[复制链接]

0

主题

0

帖子

3

积分

扫一扫,手机访问本帖
发表于 2013-8-30 12:19:33 | 显示全部楼层 |阅读模式
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-a.h>
#include <mach/gpio-bank-b.h>
#include <mach/gpio-bank-c.h>
#include <mach/gpio-bank-d.h>
#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-f.h>
#include <mach/gpio-bank-g.h>
#include <mach/gpio-bank-h.h>
#include <mach/gpio-bank-i.h>
#include <mach/gpio-bank-j.h>
#include <mach/gpio-bank-k.h>
#include <mach/gpio-bank-m.h>
#include <mach/gpio-bank-n.h>
#include <mach/gpio-bank-o.h>
#include <mach/gpio-bank-p.h>
#include <mach/gpio-bank-q.h>
#define DEVICE_NAME  "myIOsetDir"

/*set the direction of the 6410IO
IO_id: 'A'-'Q' excepted  L
IO_number: 0-x
status: 0:input 1:output
return:ture:0 failed:-EINVAL
*/
int s3c6410_ioSetDir(char IO_id ,unsigned char IO_number,unsigned char status )
{

unsigned tmp=0;
unsigned char n=0;
switch(IO_id)
        {
        case 'A':n=1;tmp=readl(S3C64XX_GPACON);break;
        case 'B':n=2;tmp=readl(S3C64XX_GPBCON);break;
        case 'C':n=3;tmp=readl(S3C64XX_GPCCON);break;
        case 'D':n=4;tmp=readl(S3C64XX_GPDCON);break;
        case 'E':n=5;tmp=readl(S3C64XX_GPECON);break;
        case 'F':n=6;tmp=readl(S3C64XX_GPFCON);break;
        case 'G':n=7;tmp=readl(S3C64XX_GPGCON);break;
        case 'H':n=8;if(IO_number<=7) tmp=readl(S3C64XX_GPHCON0) else tmp=readl(S3C64XX_GPHCON1);break;
        case 'I':n=9;tmp=readl(S3C64XX_GPICON);break;
        case 'J':n=10;tmp=readl(S3C64XX_GPJCON);break;
        case 'K':n=11;tmp=readl(S3C64XX_GPKCON);break;
        case 'L':n=12;break;
        case 'M':n=13;tmp=readl(S3C64XX_GPMCON);break;
        case 'N':n=14;tmp=readl(S3C64XX_GPNCON);break;
        case 'O':n=15;tmp=readl(S3C64XX_GPOCON);break;
        case 'P':n=16;tmp=readl(S3C64XX_GPPCON);break;
        case 'Q':n=17;tmp=readl(S3C64XX_GPQCON);break;
        default :return -EINVAL;break;
        }       

        if((n==1)||(n==2)||(n==3)||(n==4)||(n==5)||(n==7)||(n==8)||(n==13))
        {
        switch(status)
                {
                case 0 :tmp&=(~(0x0f<<(4*IO_number)));break;
                case 1 :tmp|=(1<<(4*IO_number));break;
                default:return -EINVAL;break;
                }
        }
        else if((n==6)||(n==9)||(n==10)||(n==11)||(n==14)||(n==15)||(n==16)||(n==17))
        {
                switch(status)
                {
                case 0 :tmp&=~(0x03<<(2*IO_number));break;
                case 1 :tmp|=(1<<(2*IO_number));break;
                default:return -EINVAL;break;
                }
        }

switch(IO_id)
        {
        case 'A':writel(tmp,S3C64XX_GPACON);break;
        case 'B':writel(tmp,S3C64XX_GPBCON);break;
        case 'C':writel(tmp,S3C64XX_GPCCON);break;
        case 'D':writel(tmp,S3C64XX_GPDCON);break;
        case 'E':writel(tmp,S3C64XX_GPECON);break;
        case 'F':writel(tmp,S3C64XX_GPFCON);break;
        case 'G':writel(tmp,S3C64XX_GPGCON);break;
        case 'H':if(IO_number<=7) writel(tmp,S3C64XX_GPHCON0) else writel(tmp,S3C64XX_GPHCON1);break;
        case 'I':writel(tmp,S3C64XX_GPICON);break;
        case 'J':writel(tmp,S3C64XX_GPJCON);break;
        case 'K':writel(tmp,S3C64XX_GPKCON);break;
        case 'L':break;
        case 'M':writel(tmp,S3C64XX_GPMCON);break;
        case 'N':writel(tmp,S3C64XX_GPNCON);break;
        case 'O':writel(tmp,S3C64XX_GPOCON);break;
        case 'P':writel(tmp,S3C64XX_GPPCON);break;
        case 'Q':writel(tmp,S3C64XX_GPQCON);break;
        default :return -EINVAL;break;
        }       
        return 0;

}

/*set the data of the 6410IO
cmd: A-Q excepted  L
arg: 0-x
return:ture:0 failed:-EINVAL
*/
/*
typedef enum
{
A_IN,
A_OUT,
B_IN,
B_OUT,
C_IN,
C_OUT,
D_IN,
D_OUT,
E_IN,
E_OUT,
F_IN,
F_OUT,
G_IN,
G_OUT,
H_IN,
H_OUT,
I_IN,
I_OUT,
J_IN,
J_OUT,
K_IN,
K_OUT,
L_IN,
L_OUT,
M_IN,
M_OUT,
N_IN,
N_OUT,
O_IN,
O_OUT,
P_IN,
P_OUT,
Q_IN,
Q_OUT
}IO_6410_SetDir;
*/

static long s3c6410_SetDir_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
char tmp=0;
if(cmd%2==0)
{
switch(cmd)
{
case 0:
case 1: tmp='A'; break;
case 2:
case 3:tmp='B';break;
case 4:
case 5:tmp='C';break;
case 6:
case 7:tmp='D';break;
case 8:
case 9:tmp='E';break;
case 10:
case 11:tmp='F';break;
case 12:
case 13:tmp='G';break;
case 14:
case 15:tmp='H';break;
case 16:
case 17:tmp='I';break;
case 18:
case 19:tmp='J';break;
case 20:
case 21:tmp='K';break;
case 22:
case 23:return -EINVAL;break;
case 24:
case 25:tmp='M';break;
case 26:
case 27:tmp='N';break;
case 28:
case 29:tmp='O';break;
case 30:
case 31:tmp='P';break;
case 32:
case 33:tmp='Q';break;

default:return -EINVAL;break;
}
s3c6410_ioSetDir(tmp,arg,0);
}
else
{switch(cmd)
{
case 0:
case 1: tmp='A'; break;
case 2:
case 3:tmp='B';break;
case 4:
case 5:tmp='C';break;
case 6:
case 7:tmp='D';break;
case 8:
case 9:tmp='E';break;
case 10:
case 11:tmp='F';break;
case 12:
case 13:tmp='G';break;
case 14:
case 15:tmp='H';break;
case 16:
case 17:tmp='I';break;
case 18:
case 19:tmp='J';break;
case 20:
case 21:tmp='K';break;
case 22:
case 23:return -EINVAL;break;
case 24:
case 25:tmp='M';break;
case 26:
case 27:tmp='N';break;
case 28:
case 29:tmp='O';break;
case 30:
case 31:tmp='P';break;
case 32:
case 33:tmp='Q';break;

default:return -EINVAL;break;
}
s3c6410_ioSetDir(tmp,arg,1);
}
return 0;
}
static struct file_operations dev_fops = {   
        .owner                        = THIS_MODULE,
        .unlocked_ioctl        = s3c6410_SetDir_ioctl,   
};

static struct miscdevice misc = {   
        .minor = MISC_DYNAMIC_MINOR,
        .name = DEVICE_NAME,
        .fops = &dev_fops,
};

static int __init dev_init(void)
{
        int ret;
    ret = misc_register(&misc);  
        return ret;
}

static void __exit dev_exit(void)
{
        misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("jack sun");
回复

使用道具 举报

110

主题

1358

帖子

1443

积分

A40i/T3/T507/T527通行证i.MX6Q通行证i.MX6UL通行证i.MX8MM通行证i.MX8MP通行证RK3568通行证RK3588通行证RK3399通行证LS1028A通行证G2L通行证LS1012A通行证LS1043A\46A通行证TCU通行证FDU产品通行证FCU1401通行证FCU1301通行证FCU11xx通行证FCU1201通行证FCU2201通行证FCU2301/FCU2302通行证FCU2401通行证5G转接卡通行证FCU3001通行证AM5718通行证Hi3519A通信证AM335x通行证i.MX RT通行证XX18通行证AM62x资料下载FDU070K02\FDU101K02通行证i.MX9352通行证

发表于 2013-9-5 08:49:56 | 显示全部楼层
多谢楼主的无私分享,希望楼主再接再厉,多多发布自己的成果,让咱们的论坛活跃起来!!!!
顶!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
该会员没有填写今日想说内容.
点评回复 支持 反对

使用道具 举报

0

主题

9

帖子

38

积分

发表于 2013-9-5 18:02:33 | 显示全部楼层
驱动思想对于新手很有帮助,谢谢!
点评回复 支持 反对

使用道具 举报

0

主题

1

帖子

16

积分

发表于 2017-7-3 01:48:54 | 显示全部楼层
楼主,您好,我很想看看您的程序,能发我邮箱吗?谢谢!!! 597966906@qq.com
点评回复 支持 反对

使用道具 举报

5

主题

28

帖子

60

积分

发表于 2017-7-18 21:11:17 | 显示全部楼层
多谢楼主分享 学习学习!
点评回复 支持 反对

使用道具 举报

0

主题

6

帖子

36

积分

XX18通行证

发表于 2018-4-27 09:50:52 | 显示全部楼层
学习学习学习学习学习学习
点评回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2025-1-8 12:34

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表