tiny4412 linux-4.2 移植(五)EEPROM

简介

EEPROM经常用来测试板子的i2c总线,linux源码自带at24.c,配置比较简单,打开内核相关配置,再加上dts配置就行了。
tiny4412 linux-4.2 移植(五)EEPROM_第1张图片

配置

从原理图可以看出它用到了i2c0,没有用到其他io脚,所以在dts中只需要配置i2c0就行了

#dts 
&i2c_0 {
    samsung,i2c-sda-delay = <100>;    //esynos4412所有dts中的delay都是100,所以这个选择100
    samsung,i2c-max-bus-freq = <400000>;    //最高400 kbit/s,当然你可以填100000 Supports up to 400 kbit/s in the Fast mode.
    status = "okay";
    eeprom: eeprom@50 {
        compatible = "atmel,24c16";
        reg = <0x50>;
        pagesize = <16>;
    };
};
# make menuconfig
Device Drivers  --->
        Misc devices  --->
                EEPROM support  --->
                        <*> I2C EEPROMs / RAMs / ROMs from most vendors
        I2C support  --->
            I2C Hardware Bus support  --->  
                <*> S3C2410 I2C Driver

at24.c简单分析

static int at24_write(void *priv, unsigned int off, void *val, size_t count){
    struct at24_data *at24 = priv;
    struct device *dev = at24_base_client_dev(at24);

    mutex_lock(&at24->lock);    //加锁
    /*
     * 对于有些挂载在I2C,SPI总线上的扩展GPIO,读写操作可能会导致睡眠,因此不能在中断函数中。如果
     * soc本身(比如100个)gpio不够用, 那么就要另外接一个gpio controller, 上面再提供额外的50个gpio,
     * 这个controller连接到soc上是通过总线比如i2c总线连上去的。这个时候写gpio值,就是通过i2c总线去写新加的那
     * 个gpio controller的寄存器的值,所以有可能会有睡眠发生,所以要用can_sleep
     */
    gpiod_set_value_cansleep(at24->wp_gpio, 0);   
    ret = at24_regmap_write(at24, buf, off, count);    --->
        ---->static ssize_t at24_regmap_write{
                 //首先从struct at24_data中取出struct i2c_client和struct regmap
                 at24_client = at24_translate_offset(at24, &offset);
                 struct i2c_client *client = at24_client->client; 
                 struct regmap *regmap = at24_client->regmap;
                 ret = regmap_bulk_write(regmap, offset, buf, count); 
             }
}
static int at24_probe(struct i2c_client *client){
    i2c_fn_i2c = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);    //监测是否是i2c功能
    i2c_check_functionality(client->adapter,        //是否支持块操作
                           I2C_FUNC_SMBUS_WRITE_I2C_BLOCK);
    if (!i2c_fn_i2c && !i2c_fn_block)    //如果不是i2c也不支持块操作,则设置page为1
        pdata.page_size = 1;

    struct at24_platform_data pdata = { };
    err = at24_get_pdata(dev, &pdata);    --->    
        ---> device_property_read_u32(dev, "pagesize", &val)//获得dts中的数据
    /*
     * regmap 机制是在 Linux 3.1 加入进来的特性。主要目的是减少慢速 I/O 驱动上的重复逻辑,
     * 提供一种通用的接口来操作底层硬件上的寄存器。其实这就是内核做的一次重构。regmap 除了能做
     * 到统一的 I/O 接口,还可以在驱动和硬件 IC 之间做一层缓存,从而能减少底层 I/O 的操作次数。
     */
    regmap_config.val_bits = 8;
    regmap_config.reg_bits = (pdata.flags & AT24_FLAG_ADDR16) ? 16 : 8;
    regmap_config.disable_locking = true;
       regmap = devm_regmap_init_i2c(client, &regmap_config);   
}

你可能感兴趣的:(Tiny4412,Linux_4.2移植)