[RK3288][Android6.0] AT24C02驱动分析及功能增加小结

来源:互联网 发布:淘宝装饰店铺教程 编辑:程序博客网 时间:2024/05/18 22:56
Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92

Spec:
网上很多,如
https://wenku.baidu.com/view/0020131fff00bed5b8f31d05.html

驱动:
文件:
kernel/drivers/misc/eeprom/at24.c
支持at24cxx所有系列,当然也支持at24c02, 这些系列不同的区别仅在于eeprom的大小.
static const struct i2c_device_id at24_ids[] = {    { "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) },    { "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) },    { "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) },    { "spd", AT24_DEVICE_MAGIC(2048 / 8,        AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },    { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },......};
驱动可以同时支持多个eeprom同时挂载,但需要修改eeprom的大小,比如支持at24c02,需要将2048改成4096.
static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id){......num_addresses =    DIV_ROUND_UP(chip.byte_len,            (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256);......}
驱动没有创建字符设备提供给上层, 而是以sysfs文件的读写方式来操作,对应读写操作函数:
at24_bin_read()和at24_bin_write()

操作路径:
/sys/bus/i2c/drivers/at24/5-0050/eeprom
5-0050是表示i2c通道5,地址是0x50,会根据设备连接i2c端口以及地址变化.

使用:
#echo "at24c02 test" > /sys/bus/i2c/drivers/at24/5-0050/eeprom
#cat /sys/bus/i2c/drivers/at24/5-0050/eeprom

如果需要偏移若干地址读写,可以编写一个ap来操作,可参考:
http://blog.csdn.net/dzw19911024/article/details/53813862

实际案例:
原理图:

改动如下:
diff --git a/arch/arm/boot/dts/rk3288-b.dts b/arch/arm/boot/dts/rk3288-b.dtsindex 1ff653a..ad3bc1a 100644--- a/arch/arm/boot/dts/rk3288-b.dts+++ b/arch/arm/boot/dts/rk3288-b.dts@@ -324,6 +324,7 @@  &i2c3 {     status = "okay";+ };  &i2c4 {@@ -340,8 +341,14 @@     }; }; +//Kris,170510, add eeprom. &i2c5 {-    status = "disabled";+    status = "okay";+    eeprom@50 {+        compatible = "24c02";+        reg = <0x50>;+        status = "okay";+    }; };  &fb {diff --git a/arch/arm/boot/dts/rk3288-pinctrl.dtsi b/arch/arm/boot/dts/rk3288-pinctrl.dtsiindex a35d4d7..4a4ebc8 100755--- a/arch/arm/boot/dts/rk3288-pinctrl.dtsi+++ b/arch/arm/boot/dts/rk3288-pinctrl.dtsi@@ -404,21 +404,21 @@          gpio7_i2c5 {             i2c5_sda:i2c5-sda {-                rockchip,pins = <EDPHDMII2C_SDA>;+                rockchip,pins = <I2C5HDMI_SDA>;                 rockchip,pull = <VALUE_PULL_NORMAL>;                 rockchip,drive = <VALUE_DRV_DEFAULT>;                 //rockchip,tristate = <VALUE_TRI_DEFAULT>;             };              i2c5_scl:i2c5-scl {-                rockchip,pins = <EDPHDMII2C_SCL>;+                rockchip,pins = <I2C5HDMI_SCL>;                 rockchip,pull = <VALUE_PULL_NORMAL>;                 rockchip,drive = <VALUE_DRV_DEFAULT>;                 //rockchip,tristate = <VALUE_TRI_DEFAULT>;             };              i2c5_gpio: i2c5-gpio {-                rockchip,pins = <FUNC_TO_GPIO(EDPHDMII2C_SDA)>, <FUNC_TO_GPIO(EDPHDMII2C_SCL)>;+                rockchip,pins = <FUNC_TO_GPIO(I2C5HDMI_SDA)>, <FUNC_TO_GPIO(I2C5HDMI_SCL)>;                 rockchip,drive = <VALUE_DRV_DEFAULT>;             };         };diff --git a/arch/arm/configs/rockchip_b_defconfig b/arch/arm/configs/rockchip_b_defconfigindex a7037c2..092dc3c 100644--- a/arch/arm/configs/rockchip_b_defconfig+++ b/arch/arm/configs/rockchip_b_defconfig@@ -662,3 +662,5 @@ CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_DEV_ROCKCHIP=y CONFIG_CRYPTO_DEV_ROCKCHIP_ENCRYPT=y CONFIG_XMF10411=y+#Kris,170510, add eeprom+CONFIG_EEPROM_AT24=ydiff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.cindex 2baeec5..a6391a9 100644--- a/drivers/misc/eeprom/at24.c+++ b/drivers/misc/eeprom/at24.c@@ -213,11 +213,15 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,         msg[0].addr = client->addr;         msg[0].buf = msgbuf;         msg[0].len = i;+        //Kris, 170510, set scl_rate.+        msg[0].scl_rate = 100*1000;          msg[1].addr = client->addr;         msg[1].flags = I2C_M_RD;         msg[1].buf = buf;         msg[1].len = count;+        //Kris, 170510, set scl_rate.+        msg[1].scl_rate = 100*1000;     }      /*@@ -331,6 +335,7 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf,     /* Get corresponding I2C address and adjust offset */     client = at24_translate_offset(at24, &offset); +     /* write_max is at most a page */     if (count > at24->write_max)         count = at24->write_max;@@ -355,6 +360,8 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf,         msg.buf[i++] = offset;         memcpy(&msg.buf[i], buf, count);         msg.len = i + count;+        //Kris, 170510, set scl_rate.+        msg.scl_rate = 100*1000;     }

参考:
地址设置:
http://blog.csdn.net/qq_27312943/article/details/53325885
驱动解析:
http://blog.csdn.net/yj4231/article/details/18182775

1 0