spi总线触摸屏ads7846(即TSC2046)驱动

本文介绍了如何驱动电阻屏芯片ADS7846,它是TSC2046的前身,两者均由TI公司生产。内容涵盖了驱动的初始化和退出流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);


 

spi_bus_type, 在/drivers/spi/spi.c 中定义:
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);


  1. 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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值