我的基于input子系统的触摸板驱动,起不来,望赐教

发布于 2022-09-18 19:00:56 字数 23204 浏览 8 评论 0

在linuxdrivers.cn上发表过,转贴到这里问问.

这几天研究触摸板的Linux驱动。看了不少资料,发现主要的代码没有多少,关键倒是和Linux内核交互的东西高不明白。
拿内核源码的驱动改成自己的,硬是起不来,又不知道如何解决。
下面是我的源代码框架,贴在这里,顺便列出自己不明白的地方,请达人指教:

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>

#define DRIVER_DESC "Serial touchpad driver"

MODULE_AUTHOR("foobar<foobar@foobar.com>");

MODULE_DESCRIPTION(DRIVER_DESC);

MODULE_LICENSE("GPL");

/**
 * Per-touchpad data.
 */

struct sertp {
        struct input_dev *dev; /**< input device */
        struct serio *serio; /**< serio struct */
        s32 id; /**< device id */
        u8 buf[8]; /**< buffer to receive data */
        u8 pre_cnt; /**< received byte pre_cnter */
        s8 phys[32];
};

static irqreturn_t sertp_interrupt(struct serio *serio,
                                   u8 data,
                                   u32 flags,
                                   struct pt_regs *regs)
{
        struct sertp *sertp = serio_get_drvdata(serio);

        printk (KERN_ALERT "sertp_interrupt\n");

        sertp_process_data(sertp, data, regs); /* start processing data */

        return IRQ_HANDLED;
}

static void sertp_disconnect(struct serio *serio)
{
        struct sertp *sertp = serio_get_drvdata(serio);

        printk (KERN_ALERT "sertp_disconnect\n");

     input_unregister_device(sertp->dev);
     serio_close(serio);
     serio_set_drvdata(serio, NULL);
     kfree(sertp);
 }

static int sertp_connect(struct serio *serio, struct serio_driver *drv)
{
     struct sertp *sertp;
     struct input_dev *input_dev;
     int err;
     printk (KERN_ALERT "sertp_connect\n");     /* allocate our struct data and input device */
     sertp = kzalloc(sizeof(struct sertp), GFP_KERNEL);
     input_dev = input_allocate_device();
     if (!sertp || !input_dev) {
         err = -ENOMEM;
         goto fail;
     }

     sertp->serio = serio;
     sertp->id = serio->id.id;
     sertp->dev = input_dev;
     snprintf(sertp->phys, sizeof(sertp->phys), "%s/input0", serio->phys); /* Q0 */
     input_dev->private = sertp;
     input_dev->name = "Serial TouchPad";
     input_dev->phys = sertp->phys; /* Q1 */
     input_dev->id.bustype = BUS_RS232;
     input_dev->id.vendor  = SERIO_ANY; /* Q2 */
     input_dev->id.product = sertp->id;
     input_dev->id.version = 0x0100;
     input_dev->cdev.dev = &serio->dev;
     input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
     input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
     input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_HWHEEL);
     serio_set_drvdata(serio, sertp);
     err = serio_open(serio, drv);
     if (err) goto fail;
     input_register_device(sertp->dev);
     return 0;
 fail:     serio_set_drvdata(serio, NULL);
     input_free_device(input_dev);
     kfree(sertp);
     return err;
}

static struct serio_device_id sertp_serio_ids[] = {
     {         .type  = SERIO_RS232,
               .proto = SERIO_ANY, /* Q3 */
              .extra = SERIO_ANY,
              .id    = SERIO_ANY,
     },
     { 0 }
};

MODULE_DEVICE_TABLE(serio, sertp_serio_ids);

static struct serio_driver sertp_drv = {
     .driver        = {
         .name    = "sertp",
     },
     .description    = DRIVER_DESC,
     .id_table    = sertp_serio_ids,
     .interrupt    = sertp_interrupt,
     .connect    = sertp_connect,
     .disconnect    = sertp_disconnect,
};

static int __init sertp_init(void)
{
     printk (KERN_ALERT "sertp_init\n");
     serio_register_driver(&sertp_drv);
     return 0;
}

static void __exit sertp_exit(void)
{
     printk (KERN_ALERT "sertp_exit\n");

     serio_unregister_driver(&sertp_drv);
}

/* Module interfaces */
module_init(sertp_init);
module_exit(sertp_exit);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

左秋 2022-09-25 19:00:56

这样说的话是中断问题而不是input子系统的问题吧~

你先跑裸机 看看中断是否能触发~

能的话再换到linux下,看看中断能不能触发

一步步调试吧~

bustype、vendor、product和version这4个字段是自己写的 加载什么样的驱动就写死的了  不会动态获取的~

雨巷深深 2022-09-25 19:00:56

是中断的问题吗?
问题是我的connect函数都没有调用啊!

梦情居士 2022-09-25 19:00:56

connect没有调用的话说明设备关键字匹配不正确或者没有匹配吧 = =

尝试一下在/drivers/input/input.c的input_attach_handler中加一个

printk(KERN_INFO "device:%s   handler:%s \n" , dev->name , handler->name);

看看你的设备和驱动之间是否进行过匹配,然后试试看匹配是否通过

匹配正确的话才能进入到connect中~ = 3=

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文