免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7044 | 回复: 15
打印 上一主题 下一主题

请问Linux下I2C设备驱动该如何写? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-05 15:36 |只看该作者 |倒序浏览
我想写一个Linux下的I2C设备驱动,基于系统中现有的I2C子系统,采用probe的方式来实现,请问此类代码是采用什么样的一种固定框架?我看了内核中一些设备的代码,觉得很复杂,而我只是想实现很简单的功能;网上也查了一些资料,但并没有找到详细叙述。
目前我的代码如下:
  1. static const struct i2c_device_id dm2016_ids[] =
  2. {
  3.     {"dm2016", 0},
  4.     {/* END OF LIST */}
  5. };
  6. MODULE_DEVICE_TABLE(i2c, dm2016_ids);


  7. struct dm2016_data {
  8.     struct i2c_client *client;
  9. };

  10. static int __devinit dm2016_probe(struct i2c_client *client, const struct i2c_device_id *id)
  11. {
  12.     struct dm2016_data *pstDM2016Data = NULL;
  13.     struct device *pstDev = &client->dev;
  14.     int s32Ret = 0;

  15.     pstDM2016Data = kzalloc(sizeof(*pstDev), GFP_KERNEL);
  16.     if (NULL == pstDM2016Data)
  17.     {
  18.         dev_err(pstDev, "alloc dm2016 data memory fail!\n");
  19.         return -ENOMEM;
  20.     }

  21.     pstDM2016Data->client = client;
  22.     i2c_set_clientdata(client, pstDM2016Data);


  23.     dev_info(pstDev, "create dm2016 client OK!\n");
  24.     return 0;
  25. }

  26. static int __devexit dm2016_remove(struct i2c_client *client)
  27. {
  28.     struct dm2016_data *pstDM2016Data = i2c_get_clientdata(client);

  29.     kfree(pstDM2016Data);

  30.     return 0;
  31. }


  32. static struct i2c_driver dm2016_driver = {
  33.     .driver = {
  34.         .name = "dm2016",
  35.         .owner = THIS_MODULE,
  36.     },
  37.     .probe = dm2016_probe,
  38.     .remove = __devexit_p(dm2016_remove),
  39.     .id_table = dm2016_ids,
  40. };

  41. static int __init dm2016_init(void)
  42. {
  43.     return i2c_add_driver(&dm2016_driver);
  44. }

  45. static void __exit dm2016_exit(void)
  46. {
  47.     i2c_del_driver(&dm2016_driver);
  48. }
复制代码
我想为设备定义自己的读写函数以及类似ioctl这样的操作,请问我在dm2016_probe函数中要做哪些操作?还有结构体dm2016_data需要哪些成员?
谢谢!

论坛徽章:
0
2 [报告]
发表于 2013-08-06 17:20 |只看该作者
要简单的就不用i2c框架,用misc或一般的udev就可以了
qq: 2379374402
群:163617970

论坛徽章:
0
3 [报告]
发表于 2013-08-06 22:56 |只看该作者
wwxxxxll 发表于 2013-08-06 17:20
要简单的就不用i2c框架,用misc或一般的udev就可以了
qq: 2379374402
群:163617970

我本来也是想用misc的,可是发现内核中现有的i2c读写接口函数参数都是struct i2c_client *client,这如果不用i2c子系统就不好搞吧。

论坛徽章:
0
4 [报告]
发表于 2013-08-07 10:39 |只看该作者
本帖最后由 wwxxxxll 于 2013-08-07 10:41 编辑

回复 3# 虫虫2003


我就是用misc写的i2c和spi和加速度传感器通讯,也用misc写过1-wire与ds18b20通讯
没有什么不好搞的
写usb或网卡的话就必须用系统提供的模型了
有兴趣加入我们的群。欢迎每一位linux驱动同好加入!

论坛徽章:
0
5 [报告]
发表于 2013-08-07 14:19 |只看该作者
wwxxxxll 发表于 2013-08-07 10:39
回复 3# 虫虫2003


能否给一个简单的示例代码或框架?

论坛徽章:
0
6 [报告]
发表于 2013-08-08 10:01 |只看该作者
这是用i2c和spi与重力加速度模块通信,i2c和spi是用gpio模拟的,在hi3515平台上
我把i2c和spi写成模块不是设备驱动,
然后用cdev写个重力加速度模块的设备驱动模块,然后用一个宏选择调用i2c或spi。
若想深入交流,请加我!

i2c_spi.rar

6.45 KB, 下载次数: 127

论坛徽章:
0
7 [报告]
发表于 2013-08-09 22:12 |只看该作者
wwxxxxll 发表于 2013-08-08 10:01
这是用i2c和spi与重力加速度模块通信,i2c和spi是用gpio模拟的,在hi3515平台上
我把i2c和spi写成模块不是 ...


谢谢你提供的代码,海思的平台我也搞过几个,包括3515,上面的i2c设备驱动我也做过,它的i2c驱动接口还是比较简单的,像
  1. i2c_write(unsigned char devaddress, unsigned char address, unsigned char data)
复制代码
这样,直接提供设备地址、寄存器地址、数据就行了,最终就是利用读写接口函数完成结构体file_operations中的一系列函数。但是我现在做的这个是Linux标准内核下的i2c设备驱动,而内核i2c提供的读写接口都是这样的
  1. s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, u8 length, const u8 *values)
复制代码
我要想调用这些函数就得先得到*client,而这就必须使用probe方式,也就是我问题中那种代码框架。可是我现在既不知道probe函数里面要做什么事情,也不知道在哪里实现像file_operations中read、write、ioctl这类设备读写函数。不知你是否明白我的意思。

论坛徽章:
0
8 [报告]
发表于 2013-08-10 22:53 |只看该作者
可以在probe里注册一个字符设备,然后实现read,write 等操作

论坛徽章:
0
9 [报告]
发表于 2013-08-11 02:26 |只看该作者
heyangya 发表于 2013-08-10 22:53
可以在probe里注册一个字符设备,然后实现read,write 等操作


我想要实现复杂点的操作,就是类似ioctl,通过应用层传递的参数来实现一个基于读写的复杂操作,不知有没有。否则如果只有最简单的读写操作,那不是得把ioctl的工作放到应用层去做?

论坛徽章:
0
10 [报告]
发表于 2013-08-11 09:25 |只看该作者
字符设备的操作函数集包括open,close,read,write,ioctl......你想干什么都可以
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP