首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将platform_driver和i2c_driver相结合的内核驱动程序

将platform_driver和i2c_driver相结合的内核驱动程序
EN

Stack Overflow用户
提问于 2020-12-18 11:23:12
回答 1查看 445关注 1票数 1

我正在为LCD编写内核驱动程序。该液晶显示器使用8条GPIO线(d0...d7)发送数据到显示,一些gpio控制信号(打开/关闭,启用背光和r/w)和一个电位器控制显示对比度,连接到I2C总线。

我编写了一个platform_driver,它使用“探测”和“删除”回调来注册/注销一个misc设备,该设备可以从用户空间中创建一个/dev/lcd字符设备,用来发送一个缓冲区以打印在屏幕上。我能够读取DTS上正确定义的GPIOS,也可以管理这些GPIOS在LCD上打印字符串。这是骨架:

代码语言:javascript
运行
复制
#define MODULE_NAME     "lcd"
static void lcd_hw_setup(void)
{ ...  }
static int lcd_open(struct inode *inode, struct file *file)
{ ... }
static ssize_t lcd_write (struct file *file, const char *buf, size_t     count, loff_t *ppos)
{ ... }
static int lcd_close(struct inode *inode, struct file *file)
{ ... }
/* declare & initialize file_operations structure */
static const struct file_operations lcd_dev_fops = {
    .owner = THIS_MODULE,
    .open = lcd_open,
    .write = lcd_write,
    .release = lcd_close
};
/* declare & initialize miscdevice structure */
static struct miscdevice lcd_misc = {
    .minor = MISC_DYNAMIC_MINOR, /* major = 10 assigned by the misc framework */
    .name = MODULE_NAME, /* /dev/lcd */
    .fops = &lcd_dev_fops,
};
static int lcd_probe(struct platform_device *pdev)
{
    struct device *dev;
    pr_info(MODULE_NAME ": lcd_probe init\n");
    /* Register the misc device with the kernel */
    misc_register(&lcd_misc);
    dev = &pdev->dev;
    /* gpiod_get calls to get gpios from DTS */
    lcd_hw_setup();
    pr_info(MODULE_NAME ": lcd_probe ok\n");
    return 0;
}
static int lcd_remove(struct platform_device *pdev)
{
    pr_info(MODULE_NAME ": lcd_remove\n");
    /* Release gpio resources */
    ... 
    /* Unregister the device with the kernel */
    misc_deregister(&lcd_misc);
    return 0;
}
/* declare a list of devices supported by this driver */
static const struct of_device_id lcd_of_ids[] = {
    { .compatible = "my-lcd" },
    { /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, lcd_of_ids);
/* declare & initialize platform_driver structure */
static struct platform_driver lcd_pdrv = {
    .probe = lcd_probe,
    .remove = lcd_remove,
    .driver = {
        .name = "my-lcd", /* match with compatible */
        .of_match_table = lcd_of_ids,
        .owner = THIS_MODULE,
    },
};
/* register platform driver */
module_platform_driver(lcd_pdrv);

效果很好。

现在,我需要向I2C电位器发送一个初始化值来设置显示对比度。这需要调用i2c_smbus_write_byte_data。为此,我需要访问i2c_client结构。

我找到了一些I2C示例,它们创建了一个i2c_driver,它提供了探测和删除回调,并在探测函数中接收到该i2c_client结构的指针。但我没有办法把i2c_driver和我的platform_driver联系起来。他们似乎是完全独立的司机。

我的问题:

  • 可以将platform_driver和i2c_driver合并到一个内核模块中吗?我的意思是,我可以在一个内核模块中添加一个module_platform_driver和module_i2c_driver调用吗?

  • ,或者我需要创建第二个驱动程序来控制I2C电位计。在这种特殊情况下,两个内核模块之间都存在依赖关系。应该如何管理该依赖关系?

请在这方面提供一些帮助是非常有帮助的。非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2020-12-22 10:33:54

作为最初的工作,我开发了第二个驱动程序(一个i2c_driver),它只是为了从探测回调调用i2c_smbus_write_byte_data函数。这是可行的,但我想知道这是否是解决这个问题的正确方法。谢谢!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65356171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档