S3C6410触摸屏驱动分析

2024-09-19  

一. device的注册

1.0 两个注册

//在smdk6410_machine_init中既注册了touchscreen的私有信息也注册了ts资源


1 在arch/arm/mach-s3c64xx/mach-smdk6410.c中

2 static void __init smdk6410_machine_init(void)

3 {

4     //在arch/arm/mach-s3c64xx/dev-ts.c中

5     s3c_ts_set_platdata(&s3c_ts_platform);                                  //1.设备私有信息的注册

6     //在driver/base/platform.c中

7     platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));   //2.设备资源的注册

8 }


1.1 ts私有信息的注册

在arch/arm/mach-s3c64xx/mach-smdk6410.c中


 1 static struct s3c_ts_mach_info s3c_ts_platform __initdata = {

 2     .delay               = 10000,                    //延时

 3     .presc               = 49,                       //分频

 4     .oversampling_shift  = 2,                        //分频

 5     .resol_bit           = 12,                       //精度     

 6     .s3c_adc_con         = ADC_TYPE_2,               //分频     

 7 };

 8 smdk6410_machine_init

 9 {

10     //下面这个函数在arch/arm/mach-s3c64xx/dev-ts.c中

11     s3c_ts_set_platdata(&s3c_ts_platform);

12 }


1.2 ts设备资源的注册


 1 //在arch/arm/mach-s3c64xx/dev-ts.c中

 2 static struct resource s3c_ts_resource[] = {

 3     [0] = {

 4         .start = SAMSUNG_PA_ADC,                        //0x7E00B000

 5         .end = SAMSUNG_PA_ADC + SZ_256 - 1,             //0x7E00B100    

 6         .flags = IORESOURCE_MEM,

 7     },

 8     [1] = {

 9         .start = IRQ_PENDN,                             //0x5e=94

10         .end = IRQ_PENDN,

11         .flags = IORESOURCE_IRQ,

12     },

13     [2] = {

14         .start = IRQ_ADC,                                //0x5f=95

15         .end = IRQ_ADC,

16         .flags = IORESOURCE_IRQ,

17     }

18 };

19 struct platform_device s3c_device_ts = {

20     .name         = 's3c-ts',

21     .id         = -1,

22     .num_resources     = ARRAY_SIZE(s3c_ts_resource),

23     .resource     = s3c_ts_resource,

24 };

25 //在arch/arm/mach-s3c64xx/mach-smdk6410.c中

26 static struct platform_device *smdk6410_devices[] __initdata = {

27     &s3c_device_ts,                //把ts放入到总的ts列表中

28 }

29 //在arch/arm/mach-s3c64xx/mach-smdk6410.c中

30 static void __init smdk6410_machine_init(void)

31 {

32     //在driver/base/platform.c中一起注册

33     platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));

34 }


二. device_driver

2.0 两个宏


 1 #define WAIT4INT(x)              //只是针对于S3C_ADCTSC寄存器

 2         (((x)<<8) |              // 0->down 1->up interrupt signal

 3         S3C_ADCTSC_YM_SEN |      // 1 = Switch enable (YM = VSSA_ADC)

 4         S3C_ADCTSC_YP_SEN |      // 1 = Switch disable (YP=AIN5, Hi-z) 

 5         //XM_SEN                // 0 = Switch disable (XM = AIN6, Hi-z)

 6         S3C_ADCTSC_XP_SEN |      // 1 = Switch disable (XP=AIN7, Hi-z)

 7         //PULL_UP               // 0 = XP Pull-up Enable.

 8         //AUTO_PST              // 0 = Normal ADC conversion.         

 9         S3C_ADCTSC_XY_PST(3))    // 3: Waiting for Interrupt Mode 

10 #define AUTOPST     

11     (S3C_ADCTSC_YM_SEN |        //1 = Switch enable (YM = VSSA_ADC)

12     S3C_ADCTSC_YP_SEN |         //1 = Switch disable (YP=AIN5, Hi-z) 

13     S3C_ADCTSC_XP_SEN |         //1 = Switch disable (XP=AIN7, Hi-z) 

14     S3C_ADCTSC_AUTO_PST |       //1 = Auto Sequential measurement of X-position, Y-position

15     S3C_ADCTSC_XY_PST(0))       //0 = No operation mode

16 WAIT4INT(x) :

17             当x=0时,设为等侍down中断

18              当x=1时,设为等侍up中断


2.1 初始化

ok6410的touchscreen在内核源码的位置:driver/input/touchscreen/s3c-ts.c

device 与 device_driver按名字s3c-ts匹配之后,就进入s3c_ts_probe函数


static struct platform_driver s3c_ts_driver = {

    .probe = s3c_ts_probe,

    .remove = s3c_ts_remove,

    .suspend = s3c_ts_suspend,

    .resume = s3c_ts_resume,

    .driver        = {

        .owner    = THIS_MODULE,

        .name    = 's3c-ts',

    },

};

static int __init s3c_ts_init(void)

{

    return platform_driver_register(&s3c_ts_driver);

}

static void __exit s3c_ts_exit(void)

{

    platform_driver_unregister(&s3c_ts_driver);

}

module_init(s3c_ts_init);

module_exit(s3c_ts_exit);


2.2 probe函数


 1 static int __init s3c_ts_probe(struct platform_device *pdev)

 2 {

 3     struct resource *res;

 4     struct device *dev;

 5     struct input_dev *input_dev;

 6     struct s3c_ts_mach_info * s3c_ts_cfg;

 7     int ret, size;

 8     dev = &pdev->dev;

 9     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);                //获取ts寄存器地址

10     size = (res->end - res->start) + 1;

11     ts_mem = request_mem_region(res->start, size, pdev->name);           //申请I/O内存

12     ts_base = ioremap(res->start, size);                                 //request_mem_region申请的内存在使用前要调用ioremap

13     ts_clock = clk_get(&pdev->dev, 'adc');                               //获取clock    

14     clk_enable(ts_clock);                                                //在初始化时disable了ts_clock,这个地方要enable

15     

16                                                                 //下面这几行是要把ts的配置信息写到寄存器中去

17     s3c_ts_cfg = s3c_ts_get_platdata(&pdev->dev);                        //获取ts的配置信息,

18                                                                          //ts的私有信息:在arch/arm/mach-s3c64xx/mach-smdk6410.c中

19     //enable prescaler && 设置prescaler_value=s3c_ts_cfg->presc

20     writel(S3C_ADCCON_PRSCEN | S3C_ADCCON_PRSCVL(s3c_ts_cfg->presc&0xff), ts_base+S3C_ADCCON);

21    

22    //s3c_ts_cfg->delay=0x10000 --> External input clock 

23     writel(s3c_ts_cfg->delay & 0xffff, ts_base+S3C_ADCDLY);

24     

25     //A/D converter resolution selection--> 12-bit A/D conversion

26     writel(readl(ts_base+S3C_ADCCON)|S3C_ADCCON_RESSEL_12BIT, ts_base+S3C_ADCCON);

27     //设为等侍down中断模式

28     writel(WAIT4INT(0), ts_base+S3C_ADCTSC);

29     ts = kzalloc(sizeof(struct s3c_ts_info), GFP_KERNEL);           //下面这几行是要初始化s3c_ts_info结构体

30     input_dev = input_allocate_device();

31    

32     ts->dev = input_dev;

33     ts->dev->evbit[0] = ts->dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);

34     ts->dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

35     if (s3c_ts_cfg->resol_bit==12) {

36         input_set_abs_params(ts->dev, ABS_X, 0, 0xFFF, 0, 0);                //设置x轴的最大最小值

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。