jackbella 发表于 2013-8-30 12:19:02

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

代码如下:
驱动代码:#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"myIOsetData"

/*set the data of the 6410IO
IO_id: A-Q exceptedL
IO_number: 0-x
status: 0:low 1:high
return:ture:0 failed:-EINVAL
*/



static int s3c6410_ioSetData(char IO_id ,unsigned char IO_number,unsigned char status )
{
           unsigned tmp;
switch(IO_id)
        {
        case 'A':tmp=readl(S3C64XX_GPADAT);break;
        case 'B':tmp=readl(S3C64XX_GPBDAT);break;
        case 'C':tmp=readl(S3C64XX_GPCDAT);break;
        case 'D':tmp=readl(S3C64XX_GPDDAT);break;
        case 'E':tmp=readl(S3C64XX_GPEDAT);break;
        case 'F':tmp=readl(S3C64XX_GPFDAT);break;
        case 'G':tmp=readl(S3C64XX_GPGDAT);break;
        case 'H':tmp=readl(S3C64XX_GPHDAT);break;
        case 'I':tmp=readl(S3C64XX_GPIDAT);break;
        case 'J':tmp=readl(S3C64XX_GPJDAT);break;
        case 'K':tmp=readl(S3C64XX_GPKDAT);break;
        case 'L':break;
        case 'M':tmp=readl(S3C64XX_GPMDAT);break;
        case 'N':tmp=readl(S3C64XX_GPNDAT);break;
        case 'O':tmp=readl(S3C64XX_GPODAT);break;
        case 'P':tmp=readl(S3C64XX_GPPDAT);break;
        case 'Q':tmp=readl(S3C64XX_GPQDAT);break;
        default :return -EINVAL;break;
        }       
                switch(status)
                {
                        case 0:tmp &= (~(1<<IO_number));break;
                        case 1:tmp |= (1<<IO_number);break;
                        default:return -EINVAL;break;
                }
   
       switch(IO_id)
        {
        case 'A':writel(tmp,S3C64XX_GPADAT);break;
        case 'B':writel(tmp,S3C64XX_GPBDAT);break;
        case 'C':writel(tmp,S3C64XX_GPCDAT);break;
        case 'D':writel(tmp,S3C64XX_GPDDAT);break;
        case 'E':writel(tmp,S3C64XX_GPEDAT);break;
        case 'F':writel(tmp,S3C64XX_GPFDAT);break;
        case 'G':writel(tmp,S3C64XX_GPGDAT);break;
        case 'H':writel(tmp,S3C64XX_GPHDAT);break;
        case 'I':writel(tmp,S3C64XX_GPIDAT);break;
        case 'J':writel(tmp,S3C64XX_GPJDAT);break;
        case 'K':writel(tmp,S3C64XX_GPKDAT);break;
        case 'L':break;
        case 'M':writel(tmp,S3C64XX_GPMDAT);break;
        case 'N':writel(tmp,S3C64XX_GPNDAT);break;
        case 'O':writel(tmp,S3C64XX_GPODAT);break;
        case 'P':writel(tmp,S3C64XX_GPPDAT);break;
        case 'Q':writel(tmp,S3C64XX_GPQDAT);break;
        default :return -EINVAL;break;
        }       
        return 0;
       
}

/*set the data of the 6410IO
cmd: A-Q exceptedL
arg: 0-x
return:ture:0 failed:-EINVAL
*/
/*
typedef enum
{
A_HIGH,
A_LOW,
B_HIGH,
B_LOW,
C_HIGH,
C_LOW,
D_HIGH,
D_LOW,
E_HIGH,
E_LOW,
F_HIGH,
F_LOW,
G_HIGH,
G_LOW,
H_HIGH,
H_LOW,
I_HIGH,
I_LOW,
J_HIGH,
J_LOW,
K_HIGH,
K_LOW,
L_HIGH,
L_LOW,
M_HIGH,
M_LOW,
N_HIGH,
N_LOW,
O_HIGH,
O_LOW,
P_HIGH,
P_LOW,
Q_HIGH,
Q_LOW
}IO_6410_SetData;
*/

static long s3c6410_SetData_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_ioSetData(tmp,arg,1);
}
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_ioSetData(tmp,arg,0);
}
return 0;
}
static struct file_operations dev_fops = {   
        .owner                        = THIS_MODULE,
        .unlocked_ioctl        = s3c6410_SetData_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");

#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' exceptedL
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 exceptedL
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");
页: [1]
查看完整版本: 自己写了三个简单的驱动,都是io口操作的可以在用户空间直接控制6410的IO口了