|
别人有做过的
触摸屏控制ADS7846的原理及应用.pdf
(101.93 KB, 下载次数: 9)
程序:
1. init/exit:
- static struct spi_driver ads7846_driver = {
-
- .driver = {
-
- .name = "ads7846",
-
- .bus = &spi_bus_type,
-
- .owner = THIS_MODULE,
-
- },
-
- .probe = ads7846_probe, //spi_regiser_driver()之后会运行。
-
- .remove = __devexit_p(ads7846_remove),
-
- .suspend = ads7846_suspend,
-
- .resume = ads7846_resume,
-
- };
-
-
-
- static int __init ads7846_init(void)
-
- {
-
- return spi_register_driver(&ads7846_driver); //注册spi总线驱动的方法。
-
- }
-
- module_init(ads7846_init);
-
-
-
- static void __exit ads7846_exit(void)
-
- {
-
- spi_unregister_driver(&ads7846_driver); //注销
-
- }
-
- module_exit(ads7846_exit);
spi_bus_type
- struct bus_type spi_bus_type = {
-
- .name = "spi",
-
- .dev_attrs = spi_dev_attrs, //设备属性
-
- .match = spi_match_device, //自动匹配设备
-
- .uevent = spi_uevent, //uevent
-
- .suspend = spi_suspend,
-
- .resume = spi_resume,
-
- };
-
- EXPORT_SYMBOL_GPL(spi_bus_type);
- static int __devinit ads7846_probe(struct spi_device *spi)
-
- {
-
- struct ads7846 *ts;
-
- struct ads7846_packet *packet;
-
- struct input_dev *input_dev;
-
- struct ads7846_platform_data *pdata = spi->dev.platform_data;
-
- unsigned long irq_flags;
-
- int err;
-
-
-
- if (!spi->irq) { //确定spi_device有中断
-
- dev_dbg(&spi->dev, "no IRQ?\n");
-
- return -ENODEV;
-
- }
-
-
-
- if (!pdata) { //确定spi_device->dev.platform_data有内容。这个内容和中断号一样,应该都来自boardxx.c在arch/arm/mach-omap2/下。
-
- dev_dbg(&spi->dev, "no platform data?\n");
-
- return -ENODEV;
-
- }
-
-
-
- /* don't exceed max specified sample rate */
-
- if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) { //SPI总线支持的最大时钟频率。
-
- dev_dbg(&spi->dev, "f(sample) %d KHz?\n",
-
- (spi->max_speed_hz/SAMPLE_BITS)/1000);
-
- return -EINVAL;
-
- }
-
-
-
- /* We'd set TX word size 8 bits and RX word size to 13 bits ... except
- * that even if the hardware can do that, the SPI controller driver
- * may not. So we stick to very-portable 8 bit words, both RX and TX.
- */
-
- spi->bits_per_word = 8; //spi的字长设为8
-
- spi->mode = SPI_MODE_0; //spi工作模式
-
- err = spi_setup(spi); //配置spi总线工作方式。
-
- if (err < 0)
-
- return err;
-
-
-
- ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); //分配ts内存
-
- packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL); //分配packet内存
-
- input_dev = input_allocate_device(); //分配input_dev内存
-
- if (!ts || !packet || !input_dev) {
-
- err = -ENOMEM;
-
- goto err_free_mem;
-
- }
-
-
-
- dev_set_drvdata(&spi->dev, ts); //把ts指针赋给 spi_device->dev->private_data指针。传输地址作用。
-
-
-
- ts->packet = packet;
-
- ts->pdata = pdata;
-
- ts->spi = spi;
-
- ts->input = input_dev;
-
- ts->vref_mv = pdata->vref_mv;
-
- ts->swap_xy = pdata->swap_xy;
-
-
-
- mutex_init(&ts->lock); //初始化锁
-
- init_waitqueue_head(&ts->wait); //初始化一个等待队列
-
-
-
- ts->model = pdata->model ? : 7846;
-
- ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
-
- ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
-
- ts->pressure_max = pdata->pressure_max ? : ~0;
-
- if (pdata->filter != NULL) { //这一堆初始化不知道啥作用,估计是防抖的作用吧。
-
- if (pdata->filter_init != NULL) {
-
- err = pdata->filter_init(pdata, &ts->filter_data);
-
- if (err < 0)
-
- goto err_free_mem;
-
- }
-
- ts->filter = pdata->filter;
-
- ts->filter_cleanup = pdata->filter_cleanup;
-
- } else if (pdata->debounce_max) {
-
- ts->debounce_max = pdata->debounce_max;
-
- if (ts->debounce_max < 2)
-
- ts->debounce_max = 2;
-
- ts->debounce_tol = pdata->debounce_tol;
-
- ts->debounce_rep = pdata->debounce_rep;
-
- ts->filter = ads7846_debounce_filter; //设置ads7846_debounce_filter()为防抖函数
- ts->filter_data = ts;
-
- } else {
-
- ts->filter = ads7846_no_filter;
-
- }
-
-
-
- err = ads7846_setup_pendown(spi, ts); //从内容来看这应该是获取ads7846中断号的意思。
-
- if (err)
-
- goto err_cleanup_filter;
-
-
-
- if (pdata->penirq_recheck_delay_usecs)
-
- ts->penirq_recheck_delay_usecs =
-
- pdata->penirq_recheck_delay_usecs;
-
-
-
- ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync;
-
-
-
- snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev));
-
- snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model);
-
-
-
- input_dev->name = ts->name; //一堆input设备初始化
-
- input_dev->phys = ts->phys;
-
- input_dev->dev.parent = &spi->dev;
-
-
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-
- input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
- input_set_abs_params(input_dev, ABS_X, //x值
-
- pdata->x_min ? : 0,
-
- pdata->x_max ? : MAX_12BIT,
-
- 0, 0);
-
- input_set_abs_params(input_dev, ABS_Y, //y值
-
- pdata->y_min ? : 0,
-
- pdata->y_max ? : MAX_12BIT,
-
- 0, 0);
-
- input_set_abs_params(input_dev, ABS_PRESSURE, //压力值
-
- pdata->pressure_min, pdata->pressure_max, 0, 0);
-
-
-
- ads7846_setup_spi_msg(ts, pdata); //spi_msg,Set up the transfers to read touchscreen state 初始化spi_msg.
-
-
-
- ts->reg = regulator_get(&spi->dev, "vcc"); //电源管理相关
-
- if (IS_ERR(ts->reg)) {
-
- err = PTR_ERR(ts->reg);
-
- dev_err(&spi->dev, "unable to get regulator: %d\n", err);
-
- goto err_free_gpio;
-
- }
-
-
-
- err = regulator_enable(ts->reg); //使能regulator
-
- if (err) {
-
- dev_err(&spi->dev, "unable to enable regulator: %d\n", err);
-
- goto err_put_regulator;
-
- }
-
-
-
- irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING; //触发方式
-
- irq_flags |= IRQF_ONESHOT;
-
-
-
- err = request_threaded_irq(spi->irq, ads7846_hard_irq, ads7846_irq,
-
- irq_flags, spi->dev.driver->name, ts); //注册一个中断,中断号spi->irq,中断处理程序ads7846_hard_irq。建立线程ads7846_irq.
- if (err && !pdata->irq_flags) {
-
- dev_info(&spi->dev,
-
- "trying pin change workaround on irq %d\n", spi->irq);
-
- irq_flags |= IRQF_TRIGGER_RISING;
-
- err = request_threaded_irq(spi->irq,
-
- ads7846_hard_irq, ads7846_irq,
-
- irq_flags, spi->dev.driver->name, ts);
-
- }
-
-
-
- if (err) {
-
- dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
-
- goto err_disable_regulator;
-
- }
-
-
-
- err = ads784x_hwmon_register(spi, ts); //注册成hwmon设备
-
- if (err)
-
- goto err_free_irq;
-
-
-
- dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq);
-
-
-
- /*
- * Take a first sample, leaving nPENIRQ active and vREF off; avoid
- * the touchscreen, in case it's not connected.
- */
-
- if (ts->model == 7845)
-
- ads7845_read12_ser(&spi->dev, PWRDOWN); //个别芯片特别处理
-
- else
-
- (void) ads7846_read12_ser(&spi->dev,
-
- READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
-
-
-
- err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); //在sys下建立一group attr.
-
- if (err)
-
- goto err_remove_hwmon;
-
-
-
- err = input_register_device(input_dev); //注册input设备。
-
- if (err)
-
- goto err_remove_attr_group;
-
-
-
- device_init_wakeup(&spi->dev, pdata->wakeup); //初始化换醒功能,与wait对应。
-
-
-
- return 0;
-
-
-
- err_remove_attr_group:
-
- sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group);
-
- err_remove_hwmon:
-
- ads784x_hwmon_unregister(spi, ts);
-
- err_free_irq:
-
- free_irq(spi->irq, ts);
-
- err_disable_regulator:
-
- regulator_disable(ts->reg);
-
- err_put_regulator:
-
- regulator_put(ts->reg);
-
- err_free_gpio:
-
- if (ts->gpio_pendown != -1)
-
- gpio_free(ts->gpio_pendown);
-
- err_cleanup_filter:
-
- if (ts->filter_cleanup)
-
- ts->filter_cleanup(ts->filter_data);
-
- err_free_mem:
-
- input_free_device(input_dev);
-
- kfree(packet);
-
- kfree(ts);
-
- return err;
-
- }
-
-
-
- static int __devexit ads7846_remove(struct spi_device *spi)
-
- {
-
- struct ads7846 *ts = dev_get_drvdata(&spi->dev);
-
-
-
- device_init_wakeup(&spi->dev, false);
-
-
-
- sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group);
-
-
-
- ads7846_disable(ts);
-
- free_irq(ts->spi->irq, ts);
-
-
-
- input_unregister_device(ts->input);
-
-
-
- ads784x_hwmon_unregister(spi, ts);
-
-
-
- regulator_disable(ts->reg);
-
- regulator_put(ts->reg);
-
-
-
- if (ts->gpio_pendown != -1)
-
- gpio_free(ts->gpio_pendown);
-
-
-
- if (ts->filter_cleanup)
-
- ts->filter_cleanup(ts->filter_data);
-
-
-
- kfree(ts->packet);
-
- kfree(ts);
-
-
-
- dev_dbg(&spi->dev, "unregistered touchscreen\n");
-
-
-
- return 0;
-
- }
- static void ads7846_dev_init(void)
-
- {
-
- if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0) //获取中断gpio
-
- printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
-
-
-
- gpio_direction_input(OMAP3_EVM_TS_GPIO); //gipo设置为输入
-
- gpio_set_debounce(OMAP3_EVM_TS_GPIO, 0xa); //设置防抖处理,10ms之内算是抖动,不处理。
-
- }
详见:
http://blog.csdn.net/lamdoc/article/details/7691564 |
|