1. 程式人生 > >[RK3288][Android6.0] AT24C02驅動分析及功能增加小結

[RK3288][Android6.0] AT24C02驅動分析及功能增加小結

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.dts
index 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";
+    
[email protected]
{ + compatible = "24c02"; + reg = <0x50>; + status = "okay"; + }; }; &fb { diff --git a/arch/arm/boot/dts/rk3288-pinctrl.dtsi b/arch/arm/boot/dts/rk3288-pinctrl.dtsi index 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_defconfig index 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=y diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 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