Linux教程

Linux内核驱动:gpio模拟i2c驱动(待完善)

本文主要是介绍Linux内核驱动:gpio模拟i2c驱动(待完善),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

  • 一、配置
    • 1. config配置
    • 2. dts配置
  • 二、代码分析
  • 三、应用读写

本文基于linux 4.19 版本内核进行分析。
Linux内核很多驱动都使用到I2C子系统。EEPROM、RTC,电池,tp等。
inux内核的i2c-gpio是使用GPIO模拟I2C协议的驱动,在内核中已经实现了,我们要做的只需要配置2根GPIO即可。
GPIO模拟I2C协议的驱动位于drivers/i2c/busses目录。驱动名称为“i2c-gpio”,驱动文件为drivers/i2c/busses/i2c-gpio.c
在这里插入图片描述

一、配置

1. config配置

1.1. GPIO支持要先保证是选上的
在这里插入图片描述
1.2. 先配置内核

Device Drivers->
    I2C support  --->
        I2C Hardware Bus support  --->
            <*> GPIO-based bitbanging I2C

从配置中看到将驱动整合到内核中,而不是module形式。这样能保证在其它I2C板级信息注册之前,已经存在了i2c总线。
另外,还需要GPIO库支持:

[*] GPIO Support  --->  

否则无法不会出现选项“GPIO-based bitbanging I2C”。

2. dts配置

首先需要在dtsi文件加上节点

i2c-gpio: i2c-gpio {
compatible = “i2c-gpio”;
status = “disabled”;
};

在dts文件加上器件描述:

&i2c-gpio {
pinctrl-names = “default”;
status = “okay”;

eeprom: m24c08@23 {
compatible = “st,m24512”;
reg = <0x23>;
status = “okay”;
};
};

二、代码分析

i2c-gpio.c文件中提供的接口:

static void i2c_gpio_setsda_dir(void *data, int state)
static void i2c_gpio_setsda_val(void *data, int state)
static void i2c_gpio_setscl_dir(void *data, int state)
static void i2c_gpio_setscl_val(void *data, int state)
static int i2c_gpio_getsda(void *data)
static int i2c_gpio_getscl(void *data)

跟普通的gpio模拟i2c所实现的接口一致,是实现的gpio的sda,scl的设置,仅此而已。
kernel/driver/i2c/algos/i2c-algo-bit.c中是系统中默认提供的gpio模拟i2c的框架代码。

static inline void sdalo(struct i2c_algo_bit_data *adap)
static inline void sdahi(struct i2c_algo_bit_data *adap)
static inline void scllo(struct i2c_algo_bit_data *adap)
static int sclhi(struct i2c_algo_bit_data *adap)
static void i2c_start(struct i2c_algo_bit_data *adap)
static void i2c_repstart(struct i2c_algo_bit_data *adap)
static void i2c_stop(struct i2c_algo_bit_data *adap)
static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)
static int i2c_inb(struct i2c_adapter *i2c_adap)
static int test_bus(struct i2c_algo_bit_data *adap, char *name)
static int try_address(struct i2c_adapter *i2c_adap,
                          unsigned char addr, int retries)
static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
static int acknak(struct i2c_adapter *i2c_adap, int is_ack)
static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
static int bit_xfer(struct i2c_adapter *i2c_adap,
                       struct i2c_msg msgs[], int num)
/* -----exported algorithm data: -------------------------------------   */
 
static const struct i2c_algorithm i2c_bit_algo = {
         .master_xfer    = bit_xfer,
         .functionality   = bit_func,
};

这里对于任何一个做过gpio模拟i2c模拟的童鞋来说都没有陌生的东西,不明白的可以看看i2c的协议,比我说的清楚。
这里说下出现的struct i2c_algorithm,其中的master_xfer就是我们调用i2c_master_send/i2c_master_recv的时候最终调用的接口。

三、应用读写

参考:
[1]:https://blog.csdn.net/skywalkzf/article/details/6575773

这篇关于Linux内核驱动:gpio模拟i2c驱动(待完善)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!