在 drivers/i2c/busses 下包含各种 I2C 总线驱动,如 S3C2440 的 I2C 总线驱动 i2c-s3c2410.c,使用
GPIO 模拟 I2C 总线的驱动 i2c-gpio.c,这里只分析 i2c-gpio.c。
i2c-gpio.c 它是 gpio 模拟 I2C 总线的驱动,总线也是个设备,在这里将总线当作平台设备处理,
那驱动当然是平台设备驱动,看它的驱动注册和注销函数。
[html] view plaincopyprint?
ret = platform_driver_register(&i2c_gpio_driver);
if (ret)
printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret);
int ret;
1. static int __init i2c_gpio_init(void)
2. {
3.
4.
5.
6.
7.
8.
9.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10. 10. }
11. 11. module_init(i2c_gpio_init);
12. 12.
13. 13. static void __exit i2c_gpio_exit(void)
14. 14. {
15. 15.
16. 16. }
17. 17. module_exit(i2c_gpio_exit);
return ret;
platform_driver_unregister(&i2c_gpio_driver);
没有什么好说的,它的初始化和注销函数就是注册和注销一个平台设备驱动,直接看它的
platform_driver 结构 i2c_gpio_driver
[html] view plaincopyprint?
.driver
.name
.owner
= {
= "i2c-gpio",
= THIS_MODULE,
1. 1. static struct platform_driver i2c_gpio_driver = {
2. 2.
3. 3.
4. 4.
5. 5.
6. 6.
7. 7.
8. 8. };
= i2c_gpio_probe,
= __devexit_p(i2c_gpio_remove),
},
.probe
.remove
平台驱动设备放在 arch/arm/mach-xxxx/board-xxx.c 中
[html] view plaincopyprint?
defined(CONFIG_I2C_GPIO_MODULE)
.sda_pin = PINID_GPMI_D05,
.scl_pin = PINID_GPMI_D04,
.udelay = 5, //100KHz
.timeout = 100,
.sda_is_open_drain = 1,
.scl_is_open_drain = 1,
1. #if defined(CONFIG_I2C_GPIO) | \
2.
3. static struct i2c_gpio_platform_data i2c_gpio_adapter_data = {
4.
5.
6.
7.
8.
9.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10. 10. };
11. 11.
12. 12. static struct platform_device i2c_gpio = {
13. 13.
14. 14.
15. 15.
16. 16.
17. 17.
18. 18.
19. 19. };
20. 20. #endif
.platform_data = &i2c_gpio_adapter_data,
.release = mxs_nop_release,
},
.name = "i2c-gpio",
.id = 0,
.dev = {
在这里 struct platform_device 结构中的 name 字段要和 struct platform_driver 中 driver 字段中
name 字段要相同,因为平台总线就是通过这个来判断设备和驱动是否匹配的。注意这里的
id 将它赋值了 0,至于到底有什么用,后面再来细看。这个结构里面还包含一个最重要的数
据 i2c_gpio_adapter_data,它 struct i2c_gpio_platform_data 结构类型变量,这个结构体类型定
义在 include/linux/i2c-gpio.h 中。
[html] view plaincopyprint?
sda_pin;
scl_pin;
1. 1. struct i2c_gpio_platform_data {
2. 2.
3. 3.
4. 4.
5. 5.
6. 6.
7. 7.
8. 8.
9. 9. };
unsigned int
unsigned int
int
int
unsigned int
unsigned int
unsigned int
udelay;
timeout;
sda_is_open_drain:1;
scl_is_open_drain:1;
scl_is_output_only:1;
这个结构体主要描述 gpio 模拟 i2c 总线,sda_pin 和 scl_pin 表示使用哪两个 IO 管脚来模拟
I2C 总线,udelay 和 timeout 分别为它的时钟频率和超时时间,sda_is_open_drain 和
scl_is_open_drain 表示 sda、scl 这两个管脚是否是开漏(opendrain)电路,如果是设置为 1,
scl_is_output_only 表示 scl 这个管脚是否只是作为输出,如果是设置为 1。
回到驱动中,看其中最重要的 i2c_gpio_probe。
[html] view plaincopyprint?
struct i2c_gpio_platform_data *pdata;
struct i2c_algo_bit_data *bit_data;
struct i2c_adapter *adap;
int ret;
1. static int __devinit i2c_gpio_probe(struct platform_device *pdev)
1.
2. {
2.
3.
3.
4.
4.
5.
5.
6.
6.
7.
7.
8.
8.
9.
9.
10. 10.
11. 11.
12. 12.
13. 13.
14. 14.
15. 15.
16. 16.
ret = -ENOMEM;
adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
if (!adap)
pdata = pdev->dev.platform_data;
if (!pdata)
return -ENXIO;
goto err_alloc_adap;
bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL);
17. 17.
18. 18.
19. 19.
20. 20.
21. 21.
22. 22.
23. 23.
24. 24.
25. 25.
26. 26.
27. 27.
28. 28.
29. 29.
30. 30.
31. 31.
32. 32.
33. 33.
34. 34.
35. 35.
36. 36.
37. 37.
38. 38.
39. 39.
40. 40.
if (!bit_data)
goto err_alloc_bit_data;
ret = gpio_request(pdata->sda_pin, "sda");
if (ret)
goto err_request_sda;
ret = gpio_request(pdata->scl_pin, "scl");
if (ret)
goto err_request_scl;
if (pdata->sda_is_open_drain) {
gpio_direction_output(pdata->sda_pin, 1);
bit_data->setsda = i2c_gpio_setsda_val;
} else {
gpio_direction_input(pdata->sda_pin);
bit_data->setsda = i2c_gpio_setsda_dir;
}
if (pdata->scl_is_open_drain || pdata->scl_is_output_only) {
gpio_direction_output(pdata->scl_pin, 1);
bit_data->setscl = i2c_gpio_setscl_val;
} else {
gpio_direction_input(pdata->scl_pin);
bit_data->setscl = i2c_gpio_setscl_dir;
41. 41.
42. 42.
43. 43.
44. 44.
45. 45.
46. 46.
47. 47.
48. 48.
49. 49.
50. 50.
51. 51.
52. 52.
53. 53.
54. 54.
55. 55.
56. 56.
57. 57.
58. 58.
59. 59.
60. 60.
61. 61.
62. 62.
63. 63.
64. 64.
65. 65.
66. 66.
67. 67.
68. 68.
69. 69.
70. 70.
71. 71.
72. 72.
73. 73.
74. 74.
75. 75.
76. 76.
77. 77.
78. 78.
79. 79.
80. 80.
81. 81.
82. 82.
83. 83.
}
if (!pdata->scl_is_output_only)
bit_data->getscl = i2c_gpio_getscl;
bit_data->getsda = i2c_gpio_getsda;
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 */
bit_data->data = pdata;
adap->owner = THIS_MODULE;
snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id);
adap->algo_data = bit_data;
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->dev.parent = &pdev->dev;
/*
* If "dev->id" is negative we consider it as zero.
* The reason to do so is to avoid sysfs names that only make
* sense when there are multiple adapters.
*/
adap->nr = (pdev->id != -1) ? pdev->id : 0;
ret = i2c_bit_add_numbered_bus(adap);
if (ret)
goto err_add_bus;
platform_set_drvdata(pdev, adap);
dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
pdata->sda_pin, pdata->scl_pin,
pdata->scl_is_output_only
? ", no clock stretching" : "");
gpio_free(pdata->scl_pin);
gpio_free(pdata->sda_pin);
return 0;
84. 84.
85. 85.
86. 86. err_add_bus:
87. 87.
88. 88. err_request_scl:
89. 89.
90. 90. err_request_sda:
91. 91.
kfree(bit_data);
92. 92. err_alloc_bit_data:
93. 93.
kfree(adap);
94. 94. err_alloc_adap:
95. 95.
return ret;
96. 96. }
从这句开始 pdata= pdev->dev.platform_data;这不正是我们在平台设备结构中定义的数据吗。
然后是使用 kzalloc 申请两段内存空间,一个是为结构 struct i2c_adapter 申请的,另一个是为
结构 structi2c_algo_bit_data 申请的。
struct i2c_adapter 结构定义在 include/linux/i2c.h 中
[html] view plaincopyprint?
struct module *owner;
unsigned int id;
unsigned int class;
const struct i2c_algorithm *algo; /* the algorithm to access the bus
/* classes to allow probing for */
1.
2.
3.
4.
5.
void *algo_data;
1. struct i2c_adapter {
2.
3.
4.
5.
*/
6.
6.
7.
7.
8.
8.
9.
9.
10. 10.
11. 11.
12. 12.
13. 13.
14. 14.
15. 15.
16. 16.
17. 17.
18. 18.
19. 19. };
int timeout;
int retries;
struct device dev;
int nr;
char name[48];
struct completion dev_released;
/* data fields that are valid for all devices
u8 level;
struct mutex bus_lock;
*/
/* nesting level for lockdep */
/* in jiffies */
/* the adapter device */
在 I2C 子系统中,I2C 适配器使用结构 struct i2c_adapter 描述,代表一条实际的 I2C 总线。
struct i2c_algo_bit_data 结构定义在 include/linux/i2c-algo-bit.h 中
[html] view plaincopyprint?
/* private data for lowlevel routines */
void *data;
void (*setsda) (void *data, int state);
void (*setscl) (void *data, int state);
int
int
(*getsda) (void *data);
(*getscl) (void *data);
1. struct i2c_algo_bit_data {
1.
2.
2.
3.
3.
4.
4.
5.
5.
6.
6.
7.
7.
8.
8.
9.
9.
10. 10.
11. 11.
12. 12.
13. 13.
14. 14. };
/* local settings */
int udelay;
int timeout;
/* half clock cycle time in us,
minimum 2 us for fast-mode I2C,
minimum 5 us for standard-mode I2C and SMBus,
maximum 50 us for SMBus */
/* in jiffies */
这个结构主要用来定义对 GPIO 管脚的一些操作,还是回到 probe 中
接下来使用 gpio_request 去申请这个两个 GPIO 管脚,申请的目的是为了防止重复使用管脚。
然后是根据 struct i2c_gpio_platform_data 结构中定义的后面三个数据对 struct
i2c_algo_bit_data 结构中的函数指针做一些赋值操作。接下来是 I2C 时钟频率和超时设置,
如果在 struct i2c_gpio_platform_data 结构中定义了值,那么就采用定义的值,否则就采用默
认的值。然后是对 struct i2c_adapter 结构的一些赋值操作,比如指定它的父设备为这里的平
台设备,前面在平台设备中定义了一个 id,这里用到了,赋给了 struct i2c_adapter 中的 nr
成员,这个值表示总线号,这里的总线号和硬件无关,只是在软件上的区分。然后到了最后
的主角 i2c_bit_add_numbered_bus,这个函数定义在 drivers/i2c/algos/i2c-algo-bit.c 中
[html] view plaincopyprint?
int err;
1. 1. int i2c_bit_add_numbered_bus(struct i2c_adapter *adap)
2. 2. {
3. 3.
4. 4.
5. 5.
6. 6.
7. 7.
8. 8.
9. 9.
10. 0. }
err = i2c_bit_prepare_bus(adap);
if (err)
return i2c_add_numbered_adapter(adap);
return err;
先看 i2c_bit_prepare_bus 函数
[html] view plaincopyprint?
if (bit_test) {
struct i2c_algo_bit_data *bit_adap = adap->algo_data;
int ret = test_bus(bit_adap, adap->name);
if (ret < 0)
1. static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
1.
2. {
2.
3.
3.
4.
4.
5.
5.
6.
6.
7.
7.
8.
8.
9.
9.
10. 10.
11. 11.
12. 12.
13. 13.
14. 14.
15. 15.
16. 16. }
/* register new adapter to i2c module... */
adap->algo = &i2c_bit_algo;
adap->retries = 3;
return -ENODEV;
}
return 0;
bit_test 为模块参数,这里不管它,看这样一句 adap->algo= &i2c_bit_algo;
来看这个结构定义
[html] view plaincopyprint?
1. 1. static const struct i2c_algorithm i2c_bit_algo = {
2. 2.
3. 3.
4. 4. };
.master_xfer
.functionality
= bit_xfer,
= bit_func,
先看这个结构类型在哪里定义的 include/linux/i2c.h
[html] view plaincopyprint?
1.
2.
3.
4.
5.
6.
7.
8.
1. struct i2c_algorithm {
2.
r
3.
4.
5.
6.
7.
8.
int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
/* If an adapter algorithm can't do I2C-level access, set master_xfe
to NULL. If an adapter algorithm can do SMBus access, set
smbus_xfer. If set to NULL, the SMBus protocol is simulated
using common I2C messages */
/* master_xfer should return the number of messages successfully
processed, or a negative value on error */
9.
9.
10. 10.
11. 11.
12. 12.
13. 13.
14. 14.
15. 15.
16. 16. };
int num);
int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data *data);
/* To determine what the adapter supports */
u32 (*functionality) (struct i2c_adapter *);
其实也没什么,就三个函数指针外加一长串注释
这个结构的 master_xfer 指针为主机的数据传输,具体来看 bit_xfer 这个函数,这个函数和 I2C
协议相关,I2C 协议规定要先发送起始信号,才能开始进行数据的传输,最后数据传输完成
后发送停止信号,看接下来代码对 I2C 协议要熟悉,所以这里的关键点是 I2C 协议。
{
struct i2c_msg *pmsg;
struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
int i, ret;
unsigned short nak_ok;
struct i2c_msg msgs[], int num)
1. static int bit_xfer(struct i2c_adapter *i2c_adap,
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
}
ret = bit_doAddress(i2c_adap, pmsg);
if ((ret != 0) && !nak_ok) {
if (i) {
bit_dbg(3, &i2c_adap->dev, "emitting "
"repeated start condition\n");
i2c_repstart(adap);
bit_dbg(3, &i2c_adap->dev, "emitting start condition\n");
/*发送起始信号*/
i2c_start(adap);
for (i = 0; i < num; i++) {
pmsg = &msgs[i];
nak_ok = pmsg->flags & I2C_M_IGNORE_NAK;
if (!(pmsg->flags & I2C_M_NOSTART)) {
bit_dbg(1, &i2c_adap->dev, "NAK from "