TSC2046 是 ads7846 的下一代产品,都是TI的电阻屏芯片。
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);
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);
- 2. ads7846_probe/ads7846_remove:
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