一. device的注册
1.0 按键设备的注册

按键设备的定义在arch/arm/mach-s3c64xx中

  1. /* gpio buttons */
  2. static struct gpio_keys_button gpio_buttons[] = {
  3. {
  4. .gpio        = S3C64XX_GPN(0),
  5. //.code        = 25,
  6. .code        = KEY_UP,
  7. .desc        = \"BUTTON1\",
  8. .active_low    = 1,
  9. .wakeup        = 0,
  10. },
  11. {
  12. .gpio        = S3C64XX_GPN(1),
  13. //.code        = 42,
  14. .code        = KEY_DOWN,
  15. .desc        = \"BUTTON2\",
  16. .active_low    = 1,
  17. .wakeup        = 0,
  18. },
  19. {
  20. .gpio        = S3C64XX_GPN(2),
  21. //.code        = 50,
  22. .code        = KEY_LEFT,
  23. .desc        = \"BUTTON3\",
  24. .active_low    = 1,
  25. .wakeup        = 0,
  26. },
  27. {
  28. .gpio        = S3C64XX_GPN(3),
  29. //.code        = 10,
  30. .code        = KEY_RIGHT,
  31. .desc        = \"BUTTON4\",
  32. .active_low    = 1,
  33. .wakeup        = 0,
  34. },
  35. {
  36. .gpio        = S3C64XX_GPN(4),
  37. //.code        = 24,
  38. .code        = KEY_ENTER,
  39. .desc        = \"BUTTON5\",
  40. .active_low    = 1,
  41. .wakeup        = 0,
  42. },
  43. {
  44. .gpio        = S3C64XX_GPN(5),
  45. //.code        = 38,
  46. .code        = KEY_ESC,
  47. .desc        = \"BUTTON6\",
  48. .active_low    = 1,
  49. .wakeup        = 0,
  50. }
  51. };
  52. static struct gpio_keys_platform_data gpio_button_data = {
  53. .buttons    = gpio_buttons,
  54. .nbuttons    = ARRAY_SIZE(gpio_buttons),
  55. };
  56. static struct platform_device gpio_button_device = {
  57. .name        = \"gpio-keys\",
  58. .id        = -1,
  59. .num_resources    = 0,
  60. .dev        = {
  61. .platform_data    = &gpio_button_data,
  62. }
  63. };
  64. static struct platform_device *smdk6410_devices[] __initdata = {
  65. &gpio_button_device,        //把key_button添加到总的设备列表中
  66. }
  67. //在arch/arm/mach-s3c64xx/mach-smdk6410.c中
  68. static void __init smdk6410_machine_init(void)
  69. {
  70. //在driver/base/platform.c中一起注册
  71. platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
  72. }

二. device_driver
 Device Drivers  --->
          Input device support  --->
               [*]   Keyboards  --->
                    <*>   GPIO Buttons 
                    <*>   Samsung keypad support
2.0 两个宏

  1. #define WAIT4INT(x)              //只是针对于S3C_ADCTSC寄存器
  2. (((x)<<8) |              //<bit8> 0->down 1->up interrupt signal
  3. S3C_ADCTSC_YM_SEN |      //<bit7> 1 = Switch enable (YM = VSSA_ADC)
  4. S3C_ADCTSC_YP_SEN |      //<bit6> 1 = Switch disable (YP=AIN5, Hi-z)
  5. //XM_SEN                //<bit5> 0 = Switch disable (XM = AIN6, Hi-z)
  6. S3C_ADCTSC_XP_SEN |      //<bit4> 1 = Switch disable (XP=AIN7, Hi-z)
  7. //PULL_UP               //<bit3> 0 = XP Pull-up Enable.
  8. //AUTO_PST              //<bit2> 0 = Normal ADC conversion.
  9. S3C_ADCTSC_XY_PST(3))    //<bit1-0> 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

WAIT4INT(x) :
            当x=0时,设为等侍down中断
             当x=1时,设为等侍up中断
2.1 初始化
ok6410的touchscreen在内核源码的位置:driver/input/touchscreen/s3c-ts.c
device 与 device_driver按名字s3c-ts匹配之后,就进入s3c_ts_probe 函数

  1. static struct platform_driver s3c_ts_driver = {
  2. .probe = s3c_ts_probe,
  3. .remove = s3c_ts_remove,
  4. .suspend = s3c_ts_suspend,
  5. .resume = s3c_ts_resume,
  6. .driver        = {
  7. .owner    = THIS_MODULE,
  8. .name    = "s3c-ts",
  9. },
  10. };
  11. static int __init s3c_ts_init(void)
  12. {
  13. return platform_driver_register(&s3c_ts_driver);
  14. }
  15. static void __exit s3c_ts_exit(void)
  16. {
  17. platform_driver_unregister(&s3c_ts_driver);
  18. }
  19. module_init(s3c_ts_init);
  20. 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. //下面这几行是要把ts的配置信息写到寄存器中去
  16. s3c_ts_cfg = s3c_ts_get_platdata(&pdev->dev);                        //获取ts的配置信息,
  17. //ts的私有信息:在arch/arm/mach-s3c64xx/mach-smdk6410.c中
  18. //enable prescaler && 设置prescaler_value=s3c_ts_cfg->presc
  19. writel(S3C_ADCCON_PRSCEN | S3C_ADCCON_PRSCVL(s3c_ts_cfg->presc&0xff), ts_base+S3C_ADCCON);
  20. //s3c_ts_cfg->delay=0x10000 --> External input clock
  21. writel(s3c_ts_cfg->delay & 0xffff, ts_base+S3C_ADCDLY);
  22. //A/D converter resolution selection--> 12-bit A/D conversion
  23. writel(readl(ts_base+S3C_ADCCON)|S3C_ADCCON_RESSEL_12BIT, ts_base+S3C_ADCCON);
  24. //设为等侍down中断模式
  25. writel(WAIT4INT(0), ts_base+S3C_ADCTSC);
  1. ts = kzalloc(sizeof(struct s3c_ts_info), GFP_KERNEL);           //下面这几行是要初始化s3c_ts_info结构体
  2. input_dev = input_allocate_device();
  3. ts->dev = input_dev;
  4. ts->dev->evbit[0] = ts->dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  5. ts->dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
  6. if (s3c_ts_cfg->resol_bit==12) {
  7. input_set_abs_params(ts->dev, ABS_X, 0, 0xFFF, 0, 0);                //设置x轴的最大最小值
  8. input_set_abs_params(ts->dev, ABS_Y, 0, 0xFFF, 0, 0);                //设置y轴的最大最小值
  9. }
  10. input_set_abs_params(ts->dev, ABS_PRESSURE, 0, 1, 0, 0);                 //设置Press状态的最大最小值(按下或空闲)
  11. sprintf(ts->phys, "input(ts)");
  12. ts->dev->name = s3c_ts_name;
  13. ts->dev->phys = ts->phys;
  14. ts->dev->id.bustype = BUS_RS232;
  15. ts->dev->id.vendor = 0xDEAD;
  16. ts->dev->id.product = 0xBEEF;
  17. ts->dev->id.version = S3C_TSVERSION;
  18. ts->shift = s3c_ts_cfg->oversampling_shift;
  19. ts->resol_bit = s3c_ts_cfg->resol_bit;
  20. ts->s3c_adc_con = s3c_ts_cfg->s3c_adc_con;
  21. /* For IRQ_PENDUP */
  22. ts_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);                //获取中断号
  23. //申请中断,RANDOM表示设备可以看作随机的发生源
  24. ret = request_irq(ts_irq->start, stylus_updown, IRQF_SAMPLE_RANDOM, "s3c_updown", ts); //申请中断
  25. /* For IRQ_ADC */
  26. ts_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 1);               //获取中断号
  27. ret = request_irq(ts_irq->start, stylus_action, IRQF_SAMPLE_RANDOM | IRQF_SHARED, "s3c_action", ts); //申请共享中断
  28. /* All went ok, so register to the input system */
  29. ret = input_register_device(ts->dev);                                    //把这个input_dev添加到input系统中
  30. }

ts底板图:

ts连到核心板图:

TSXP --> AIN7
TSYP --> AIN5

2.3 IRQ_PENDN

  1. static irqreturn_t stylus_updown(int irqno, void *param)
  2. {
  3. unsigned long data0;
  4. unsigned long data1;
  5. if (!ADC_locked4TS())                              //进入中断函数,如果没有加锁,则加上锁
  6. if (s3c_ts_adc_lock(LOCK_TS))                  //如果加锁失败,则直接返回
  7. return IRQ_HANDLED;
  8. data0 = readl(ts_base+S3C_ADCDAT0);
  9. data1 = readl(ts_base+S3C_ADCDAT1);
  10. touch_timer_fire(0);
  11. if(ts->s3c_adc_con==ADC_TYPE_2) {
  12. //ADCCLRINTPNDNUP: INT_PNDNUP interrupt clear
  13. __raw_writel(0x0, ts_base+S3C_ADCCLRWK);
  14. //ADCCLRINT: Clear ADC Interrupt
  15. __raw_writel(0x0, ts_base+S3C_ADCCLRINT);
  16. }
  17. return IRQ_HANDLED;
  18. }

2.3.1 fire

  1. static void touch_timer_fire(unsigned long data)
  2. {
  3. unsigned long data0;
  4. unsigned long data1;
  5. int pendown;
  6. if (!ADC_locked4TS())                       //如果当前状态是free,说明加锁失败,直接返回
  7. return;
  8. //这儿的数据读取,是为了判断是down还是up状态
  9. data0 = readl(ts_base+S3C_ADCDAT0);         //读
  10. data1 = readl(ts_base+S3C_ADCDAT1);         //读
  11. //data0的bit15: 0->按下状态; 1->松开状态
  12. //如果data0与data1都不为松开状态,就是按下状态
  13. pendown = (!(data0 & S3C_ADCDAT0_UPDOWN)) && (!(data1 & S3C_ADCDAT1_UPDOWN));
  14. if (pendown) <

Linux内核---31.按键驱动分析(未完成)相关推荐

  1. linux内核SPI总线驱动分析(一)

    下面有两个大的模块: 一个是SPI总线驱动的分析            (研究了具体实现的过程) 另一个是SPI总线驱动的编写(不用研究具体的实现过程) SPI总线驱动分析   1 SPI概述     ...

  2. linux内核spi总线驱动分析,Linux下的SPI总线驱动(三)

    版权所有,转载请说明转自 原创作者:南京邮电大学  通信与信息系统专业 研二 魏清 五.SPI测试代码 对于SPI总线驱动,我们可以分为SPI控制设备驱动和SPI接口设备驱动.而作为驱动开发人员主要是 ...

  3. Linux内核---30.触摸屏驱动分析

    查看input系统 root@OK6410:~# cat /proc/bus/input/devices I: Bus=0013 Vendor=dead Product=beef Version=01 ...

  4. 【Linux驱动开发】Linux 自带按键驱动

    一.基础 1.以下介绍了 input 子系统的基础,使用的自己编的按键驱动.实际上内核自带了按键驱动(一般默认使能). [Linux驱动开发]INPUT 子系统实验 2.内核自带按键驱动简介 Linu ...

  5. Linux内核的Nand驱动流程分析

    最近在做Linux内核移植,总体的感觉是这样的,想要彻底的阅读Linux内核代码几乎是不可能的,至少这还不是嵌入式学期初期的重要任务.内核代码解压后有250M左右,据统计,有400多万行,而且涉及到了 ...

  6. Linux keypad 设备树,matrix_keypad 矩阵按键驱动分析

    matrix_keypad 矩阵按键驱动分析 //主要函数调用过程 matrix_keypad_probe matrix_keypad_parse_dt //根据设备树构造 pdata pdata-& ...

  7. 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】Linux内核抢占实现机制分析

    Linux内核抢占实现机制分析 Sailor_forever  sailing_9806@163.com 转载请注明 http://blog.csdn.net/sailor_8318/archive/ ...

  8. 【usb】linux内核USB键盘驱动解析--普通键值上报及转化

    一.概况 建议阅读前置文章[usb]linux内核USB键盘驱动解析–特殊键值上报及转化 以Linux5.10内核中USB键盘驱动为例进行解析:https://mirrors.edge.kernel. ...

  9. linux pl320 mbox控制器驱动分析 - (1) pl320手册分析

    linux pl320 mbox控制器驱动分析 1 pl320简介 1.1 pl320用途 1.2 pl320 IPCM 由以下部分组成: 1.3 pl320 IPCM可配置的参数 1.4 功能操作 ...

最新文章

  1. 使用leangoo做多团队敏捷开发项目管理
  2. B树和B+树分别是什么?区别在哪里?MySQL使用的是哪一种树?
  3. servlet知识点
  4. 图像降噪算法——时域降噪算法
  5. 项目进度管理:规划项目进度管理
  6. 软设考试笔记--数据库系统
  7. 【源码】net_device结构
  8. 论文浅尝 | PairRE: 通过成对的关系向量实现知识图谱嵌入
  9. 如何正确地使用#region指令
  10. 世界质量大师登场,告诉你质量的最大秘密!【优思学院】
  11. imx6ul pinctrl 驱动浅析
  12. cad转图片格式后不清晰怎么办?三步即可解决
  13. 平面向量内积坐标公式推导_向量的数量积的坐标运算公式是如何推导出的 两个向量的向量积公式是怎...
  14. IK如何实现同义词搜索
  15. oracle中todate函数实例,pl/sql to_date 函数使用实例讲解
  16. hexo+yilia添加背景特效
  17. 新手怎样才能快速的学会建网站
  18. docker创建CentOS云主机(docker实践)
  19. 变焦 焦距 等效焦距
  20. Kettle 实现数据同步

热门文章

  1. 手把手教你实现在Monaco Editor中使用VSCode主题
  2. 【Java案例】图形的面积与周长计算程序
  3. 手机中微信无法直接打开棋牌游戏类app下载链怎么办?
  4. oracle 索引 种类,详解 Navicat for Oracle 索引类型
  5. 降噪音质好的耳机推荐,2021年降噪耳机排行!
  6. matlab画图 legend的位置
  7. HTML表格无法保存图片,怎样将EXCLE表格或HTML保存为图片形式? | excle怎么存成图片的格式...
  8. Selenium基础 — 键盘操作
  9. selenium实现12306火车购票网站滑块自动验证登录
  10. Java基于springmvc实现文档预览(openoffice+swftools+flexpaper)(排坑记录)