1、 ts40 /wake-gpio = /* . */ 9 10 11 12 13 14 15 16 17 18 19 20 21 22表示i2c2总线上下挂在了多个i2c设备。其中ts40是表示此i2c设备的设备类型为触摸屏,设备地址为0x40(7位地址,注意:在i2c的传输函数中,会将此地址左移一位,因此实际上gslx680的i2c设备地址为0x80)。该节点下有多个属性:1、compatible = 属性用于驱动和设备的绑定。表示特定的设备名称,此处为gslX680;2、reg = 属性表示此设备的i2c地址为0x40,等同于40;3、wake-gpio = 表示复位引脚使用的是GPIO0
2、 中的GPIO_D3这个引脚,低电平有效。irp-gpio = 表示中断引脚使用的是GPIO0中的GPIO_A2这个引脚,高电平触发。很奇怪,为什么这里没有上电的信息,以及在整个驱动程序中都没有给ic上电的操作。在前面的MTK平台上的tp驱动都有上电的动作,暂时还搞不懂在RK平台上为什么没有。4、revert_x = dev.of_node; enum of_gpio_flags wake_flags; unsigned long irq_flags; / 检查i2c适配器的能力GSLX680 Enter %sn, _func_); if (!i2c_check_functionality(c
3、lient-adapter, I2C_FUNC_I2C) dev_err(&client-dev, I2C functionality not supportedn return -ENODEV; / 为ts申请内核空间 ts = kzalloc(sizeof(*ts), GFP_KERNEL); if(!ts) return -ENOMEM;=kzalloc success=n ts-client = client; i2c_set_clientdata(client, ts);device_id = id-driver_data; / 从设备节点np中获取到irq和wake 的gpio的信
4、息irq_pin=of_get_named_gpio_flags(np, irp-gpio, 0, (enum of_gpio_flags *)&irq_flags);wake_pin=of_get_named_gpio_flags(np, wake-gpio, 0, &wake_flags); / 为设备申请gpio,并设置默认电平 if(gpio_is_valid(ts-wake_pin) rc = devm_gpio_request_one(&dev, ts-wake_pin, (wake_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW
5、: GPIOF_OUT_INIT_HIGH, gslX680 wake pin if(rc != 0)gslX680 wake pin errorn return -EIO; g_wake_pin = ts-wake_pin; /msleep(100); else dev_info(&wake pin invalidnirq_pin)irq_pin, (irq_flags &gslX680 irq pin if (rc !gslX680 irq pin errornirq pin invalidn / 创建工作队列,申请input设备 rc = gslX680_ts_init(client,
6、ts); if(rc client); check_mem_data(ts- / 申请中断号irq=gpio_to_irq(ts-irq_pin); /If not defined in client if (ts-irq) / 为client-dev设备的中断号ts-irq申请irq_flags触发的中断,中断服务子程序为gsl_ts_irq rc = devm_request_threaded_irq(&irq, NULL, gsl_ts_irq, irq_flags | IRQF_ONESHOT, client-name, ts); printk(KERN_ALERT Cannot al
7、locate ts INT!ERRNO:%dn, rc); goto error_req_irq_fail; /disable_irq(ts-irq);gsl x680 irq req failntp.tp_resume = gsl_ts_late_resume;tp.tp_suspend = gsl_ts_early_suspend; tp_register_fb(&ts-tp);#ifdef CONFIG_HAS_EARLYSUSPENDearly_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; /ts-early_suspend
8、.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1;early_suspend.suspend = gsl_ts_early_suspend;early_suspend.resume = gsl_ts_late_resume; register_early_suspend(&early_suspend);#ifdef GSL_MONITOR printk( gsl_ts_probe () : queue gsl_monitor_workqueuen INIT_DELAYED_WORK(&gsl_monitor_work, gsl_monitor_worker
9、); gsl_monitor_workqueue = create_singlethread_workqueue(gsl_monitor_workqueue queue_delayed_work(gsl_monitor_workqueue, &gsl_monitor_work, 1000);GSLX680 End %sn return 0;/exit_set_irq_mode: error_req_irq_fail: free_irq(ts-irq, ts);error_mutex_destroy: input_free_device(ts-input); kfree(ts); return
10、rc; 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 1
11、28 129 130 131(1)、自定义的数据结构gsl_ts一般在自己的驱动程序中,都会为该驱动程序封装一个数据结构,这里的gsl_ts就充当这种角色。在该驱动程序中自定义了一个数据结构:struct gsl_ts struct i2c_client *client; struct input_dev *input; struct work_struct work; struct workqueue_struct *wq; struct gsl_ts_data *dd; u8 *touch_data; u8 device_id; int irq; int irq_pin; int wake
12、_pin; struct tp_device tp;#if defined(CONFIG_HAS_EARLYSUSPEND) struct early_suspend early_suspend;client表示一个i2c的设备;input表示一个输入设备;work表示一个工作,用于处理中断到来之后获取坐标等信息;wq表示一个工作队列,将上面的work加入到该工作队列中;dd和touch_data用来存储坐标的相关信息;device_id表示i2c设备的设备号;irq申请的中断号;irq_pin中断引脚;wake_pin复位引脚;这两个引脚信息可以通过dts获取到.tp创建一个为tp_devi
13、ce的数据结构,里面有个成员notifier_block用来接收LCD背光灯的亮暗的通知进而调用suspend()和resume()。主要的实现在tp_suspend.h中。至于这里面的详细机制还不是很明白。(2)、检查i2c适配器的能力在很多i2c设备驱动程序中,一进入probe()就要检查i2c适配器的能力。现在还不清楚这么做的目的是什么。后面会仔细的学习一下linux 的i2c子系统。(3)、获取wake和irq的引脚信息在前面配置dts说过:dts中设备节点的属性的值可以通过of_接口获取到。/ 从设备节点np中获取到irq和wake 的gpio的信息可以通过设备节点np获取到它irq
14、-gpio这一个属性的值存放在ts-irq_pin中,以及将其flag刚到变量irq_flags中。因此我们可以知道:irq_pin = GPIO_A2irq_flag = IRQ_TYPE_LEVEL_HIGH同理,wake_pin也是一样。(4)、申请gpio并设置输出电平将irq和wake 引脚电平都设置输出低电平。(5)、gslX680_ts_initstatic int gslX680_ts_init(struct i2c_client *client, struct gsl_ts *ts) struct input_dev *input_device; int rc = 0;GSL
15、X680 Enter %sn / 配置获取坐标信息dd = &devicests-device_id; if(ts-device_id = 0)dd-data_size = MAX_FINGERS * ts-touch_bytes + ts-touch_meta_data;touch_index = 0; / 申请空间存放坐标信息touch_data = kzalloc(ts-data_size, GFP_KERNEL);touch_data) pr_err(%s: Unable to allocate memoryn / 申请一个input_dev 设备 input_device = input_allocate_device();input_device) rc = -ENOMEM; goto error_alloc_dev; / 初始化input_deviceinput = input_device; input_device-name = GSLX680_I2C_NAME; input_devi
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1