55 linux内核里基于GPIO口的I2C控制器驱动
来源:互联网 发布:php posix getpid 编辑:程序博客网 时间:2024/05/18 12:42
当SOC里的I2C控制器不稳定,或I2C控制器不够用时,我们可以基于GPIO实现I2C控制器的功能.
在linux内核里已提供了相应的代码,是一个平台驱动,只需写平台设备描述相关资源即可.
make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- Device Drivers ---> <*> I2C support ---> <*> I2C device interface I2C Hardware Bus support ---> <*> GPIO-based bitbanging I2C //基于GPIO实现的I2C控制器驱动
驱动源码在”drivers/i2c/busses/i2c-gpio.c”里
static struct platform_driver i2c_gpio_driver = { .driver = { .name = "i2c-gpio", //匹配名为"i2c-gpio"的平台设备 .owner = THIS_MODULE, .of_match_table = of_match_ptr(i2c_gpio_dt_ids), }, .probe = i2c_gpio_probe, .remove = __devexit_p(i2c_gpio_remove),};//通过阅读平台驱动里的probe函数可以得知平台设备需要提供的参数static int __devinit i2c_gpio_probe(struct platform_device *pdev){ struct i2c_gpio_private_data *priv; struct i2c_gpio_platform_data *pdata; struct i2c_algo_bit_data *bit_data; struct i2c_adapter *adap; int ret; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; adap = &priv->adap; bit_data = &priv->bit_data; pdata = &priv->pdata; if (pdev->dev.of_node) { //此内核没用到设备树,这里不成立 ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata); if (ret) return ret; } else { if (!pdev->dev.platform_data) //可以通过平台设备的platform_data成员提供struct i2c_gpio_platform_data类型的数据 return -ENXIO; memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); } .... if (pdata->udelay) bit_data->udelay = pdata->udelay; else if (pdata->scl_is_output_only) bit_data->udelay = 50; /* 10 kHz */ else bit_data->udelay = 5; /* 100 kHz */ if (pdata->timeout) bit_data->timeout = pdata->timeout; else bit_data->timeout = HZ / 10; /* 100 ms */ ... adap->nr = (pdev->id != -1) ? pdev->id : 0; //i2c_adapter对象的号使用平台设备的id ret = i2c_bit_add_numbered_bus(adap);struct i2c_gpio_platform_data { unsigned int sda_pin; // SDA脚的IO口 unsigned int scl_pin; // SCL脚的IO口 int udelay; //通过此成员确定SCL的时钟频率, SCL frequency is (500 / udelay) kHz int timeout; //多久没收到应答后认为传输失败 unsigned int sda_is_open_drain:1; //是否有上拉, 没有则设1 unsigned int scl_is_open_drain:1; unsigned int scl_is_output_only:1; //时钟信号是否只由主机提供};
/////////////////////////////////////////////////
把PA9(SDA), PA10(SCL)这两个IO口实现I2C控制器的接口
myi2c9.c
#include <linux/init.h>#include <linux/module.h>#include <linux/platform_device.h>#include <linux/i2c-gpio.h>#include <mach/gpio.h>struct i2c_gpio_platform_data pdata = { .sda_pin = GPIOA(9), .scl_pin = GPIOA(10), .udelay = 2, // 250Khz .timeout = 0, //使用默认值,此内核里是100ms};struct platform_device mypdev = { .name = "i2c-gpio", .id = 9, // i2c_adapter对象的号就是9 .dev = { .platform_data = &pdata, },};module_driver(mypdev, platform_device_register, platform_device_unregister);MODULE_LICENSE("GPL");
加模块后,应在”/dev”目录下有i2c-9设备文件
在”/sys/bus/i2c/devices”目录下有i2c-9子目录
阅读全文
0 0
- 55 linux内核里基于GPIO口的I2C控制器驱动
- 62 linux内核里基于GPIO口的SPI控制器驱动
- 54 OrangePi linux内核里的i2c控制器驱动
- 17 H5里的i2c控制器驱动
- linux GPIO-i2c驱动
- tcc893x基于Linux内核的I2C总结(I2C基础、I2C适配器驱动分析)
- 61 OrangePi Linux内核里的spi控制器驱动
- 我的内核学习笔记12:linux i2c-gpio驱动应用实例
- Linux 内核gpio模拟I2C
- linux 内核GPIO 模拟 I2C
- Linux 内核设备驱动之GPIO驱动之GPIO 控制器描述
- Linux 内核设备驱动之GPIO驱动之GPIO 控制器设备描述
- linux内核里的GPIO操作函数
- linux内核里的GPIO操作函数
- Linux内核驱动GPIO的使用
- Linux内核驱动GPIO的使用
- Linux内核驱动GPIO的使用
- Linux内核驱动GPIO的使用
- 上下界网络流——学习笔记
- display:flex 布局教程
- b'字符串'引发的疑问?
- Android-一些问题
- 解释器模式(Interpreter)(类行为型模式)
- 55 linux内核里基于GPIO口的I2C控制器驱动
- 栈和堆
- 【转】学习Javascript闭包(Closure)
- 模拟微信打飞机的demo
- 毕业后,你折腾了多久做了多少努力才找到正确的方向或者道路?
- 仿苹果按钮
- String intern() method in Java. Why we use it?
- Ubuntu下安装OpenCV
- 为什么onActivityResult会提前执行