1. linux内核i2c设备驱动里的s3c_i2c_irq_nextbyte()函数中的retry_write为什么不在ack
to_i2c_client(dev) 这个函数返回值是一个指针,这个指针是个struct i2c_client 类型的指针,这个指针指向块内存,内存中存放着 to_i2c_client(dev)这个函数产生的数据。。
2. 用linux 调用内核中的统一I2C驱动 i2c总是 busy,求大神支招,谢谢! 程序很短
最近我也遇到这个问题了,纠结了一天,在网友的支持下解决了,这个天嵌的版本中,i2c和他的摄像头驱动(OV9650驱动)相冲突,你在编译内核之前,将摄像头的驱动全部去掉,这样子重新编译之后,i2c就可以正常测试使用了。
3. Linux内核gpio
本文基于 RockPI 4A 单板 Linux 4.4 内核介绍 RK3399 Linux GPIO 功能。
GPIO(General Purpose Input/Output Port) :通用输入输出端口。
除作为一般的输入/输出功能外,还可以配置为中断和模拟 PWM、I2C 等接口功能。
RK3399 GPIO 属性如下:
1、一共有5组 GPIO(GPIO0~4) ,每组 GPIO 为一个 Bank ,共32个引脚。每个 Bank 包括4个 Group (GPIOA(0~7) ~ D(0~7)) 。不是所有 Bank 都有 GPIOA~D 的编号, RK3399 共122个 GPIO 引脚。
2、所有 GPIO 都可被配置为 CA55或CA53 的中断功能,且 GPIO0 和 GPIO1 可用于系统低功耗唤醒模式。
3、在上电复位后,所有 GPIO 默认输入状态。
4、软件可配置 GPIO 驱动强度。
RK3399 引脚在系统中显示如下:
RK3399 GPIO 引脚号计算方式:
例:
以 ROCKPI 4A 单板 WIFI 模块电源( GPIO0_B2 )为例,介绍 DTS 中 GPIO 配置。
在系统启动后,可以查看 GPIO ,命令如下:
注:
如果debugfs没有挂载,使用下面命令挂载
Linux 内核 GPIO 主要实现文件:
GPIO 子系统有两套 API :
1、基于描述符(descriptor-based)
前缀为: gpiod_ 。
参考: Documentation/gpio/consumer.txt
2、老版本接口(legacy)
前缀为: gpio_ 。
参考: Documentation/gpio/gpio-legacy.txt
3、常用API
GPIO 还有很多接口,就不一一列举了。
RK3399 GPIO 控制器驱动实现文件: drivers/pinctrl/pinctrl-rockchip.c ,涉及主要函数:
所有 GPIO 子系统的 API 最终都会调到 SOC 的 GPIO 控制器驱动函数。
ROCKPi 4A 单板有个40个引脚的扩展口,引用 radxa 图片,见下图。
1、进入测试目录
2、导出GPIO
在使用 GPIO2_A7 前,需要导出该引脚。方法:配置 export 后,会出现 gpio71 节点。
测试时,注意不要使用在程序中已经申请过或配置为其它功能的 GPIO 引脚。
3、配置GPIO方向
设置 GPIO2_A7 的输入/输出方向。
in :表示输入。
out :表示输出。
active_low :用于中断配置中高电平或低电平有效。
edge :用于中断配置中上升沿或下降沿有效。
4、配置GPIO输出值
在 GPIO 为输入时,通过 value 查询 GPIO 的输入电平(高或低电平)。
在 GPIO 为输出时,通过 value 配置 GPIO 的输出电平(高或低电平)。
5、查看GPIO
查看已经导出的 GPIO71 。
6、取消导出
使用完 GPIO2_A7 后,需要进行释放。方法:配置 unexport 后, gpio71 节点会消失。
4. 用linux 调用内核中的统一I2C驱动 i2c总是 busy,求大神支招
希望能帮到你。
没这样用过,以前都是直接对/sys/bus/i2c/devices/0-0050/eeprom操作。
代码里有两次写,一次读,是在哪一次出错?
5. 如何用linux 内核提供的i2c bus总线进行fan风扇驱动开发
希望能帮到你。 没这样用过,以前都是直接对/sys/bus/i2c/devices/0-0050/eeprom操作。 代码里有两次写,一次读,是在哪一次出错?
6. linux i2c时钟rtc该怎样配置内核
i2c是master和client架构,master就是主控制器这边的驱动,client就是设备这边的驱动,master一般都写好了,你只需要写相应的client驱动,也就是设备驱动,然后在板级文件里面注册一个设备。就可以啦。
7. linux下怎么直接使用iic接口
利用Linux中IIC设备子系统移植IIC设备驱动
背景描述
IIC总线在嵌入式系统中应用十分广泛,常见的有eeprom,rtc。一般的处理器会包含IIC的控制器,用来完成IIC时序的控制;另外一方面,由于IIC的时序简单,使用GPIO口来模拟时序也是常见的做法。面对不同的IIC控制器,各种各样的芯片以及linux源码,如何更快做好IIC设备驱动。
问题描述
在我们的方案中,我们会用到eeprom,rtc以及tw2865。由于Hi3520的IIC控制器设计有问题,无法正常使用。而IIC控制器的SDA和SCL管脚正好是和两个GPIO管脚复用的。Hisi将控制gpio来实现IIC的时序,从而对IIC设备进行操作。这种设计方式简单明了,但使用IIC子系统,可以更方便的移植和维护其他的设备驱动。
问题分析
Hisi对于gpio口,rtc芯片以及tw2865的处理方式如下:将gpio口做成一个模块化的驱动,该驱动模拟IIC时序,并向外提供一些函数接口,比如:EXPORT_SYMBOL(gpio_i2c_read_tw2815);等。对于具体的rtc芯片,将其注册为一个misc设备,并利用gpio模块导出的函数进行rtc芯片的配置操作。
其实对于linux-2.6.24\drivers\i2c目录下代码,我们可以加以利用。
Linux的IIC字结构分为三个组成部分:
IIC核心
IIC核心提供了IIC总线驱动和设备驱动的注册、注销方法,IICalgorithm上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码。
IIC总线驱动
IIC总线驱动是对IIC硬件体系结构中适配器端的实现。
IIC设备驱动
IIC设备驱动是对IIC硬件体系总设备端的实现。
我们查看下该目录下的makefile和kconfig:
obj-$(CONFIG_I2C_BOARDINFO) +=i2c-boardinfo.o
obj-$(CONFIG_I2C) += i2c-core.o
obj-$(CONFIG_I2C_CHARDEV) +=i2c-dev.o
obj-y +=busses/ chips/ algos/
i2c-core.c就是IIC核心,buses中的文件是主流处理器中IIC总线的总线驱动,而chips中的文件就是常用芯片的驱动,algos中的文件实现了一些总线适配器的algorithm,其中就包括我们要用到的i2c-algo-bit.c文件。
我们首先利用i2c-gpio.c和i2c-algo-bit.c做好总线驱动。
在i2c-gpio.c中,mole_initi2c_gpio_initplatform_driver_probe(&i2c_gpio_driver,i2c_gpio_probe);
将其注册为platform虚拟总线的驱动。
在staticint __init i2c_gpio_probe(struct platform_device *pdev)中,
定义了如下三个结构体:
structi2c_gpio_platform_data *pdata;//平台相关的gpio的设置
structi2c_algo_bit_data *bit_data;//包含algorithm的具体函数,setor
get SDA和SCL
structi2c_adapter *adap;//适配器
i2c_gpio_probe主要做了下面几件事:
填充bit_data结构的各个函数指针,关联到具体的操作SDA和SCl函数。
填充adap结构,adap->algo_data= bit_data;
pdata= pdev->dev.platform_data;
bit_data->data= pdata;
pdev->dev->driver_data= adap;
在i2c-core中注册适配器类型。
inti2c_bit_add_numbered_bus(struct i2c_adapter *adap)
在staticint i2c_bit_prepare_bus(struct i2c_adapter *adap)中
adap->algo= &i2c_bit_algo;
将i2c_bit_algo与adap关联上。
static const structi2c_algorithm i2c_bit_algo = {
.master_xfer = bit_xfer,
.functionality = bit_func,
};
其中,master_xfer函数指针就是IIC传输函数指针。
I2c-algo-bit.c还实现了IIC开始条件,结束条件的模拟,发送字节,接收字节以及应答位的处理。
i2c-gpio.c中的i2c_gpio_setsda_val等函数是与具体平台gpio相关的。
修改对应arch-hi3520v100目录下的gpio.h中的各个函数,这些函数是通过操作寄存器来控制gpio的方向和值。
在对应mach-hi3520v100中的platform-devices.c中添加如下:
static structi2c_gpio_platform_data pdata = {
.sda_pin = 1<<0,
.sda_is_open_drain = 1,
.scl_pin = 1<<1,
.scl_is_open_drain = 1,
.udelay = 4, /* ~100 kHz */
};
static struct platform_devicehisilicon_i2c_gpio_device = {
.name = "i2c-gpio",
.id = -1,
.dev.platform_data = &pdata,
};
static struct platform_device*hisilicon_plat_devs[] __initdata = {
&hisilicon_i2c_gpio_device,
};
int __inithisilicon_register_platform_devices(void)
{
platform_add_devices(hisilicon_plat_devs,ARRAY_SIZE (hisilicon_plat_devs));
return 0;
}
通过platform添加devices和driver,使得pdev->dev.platform_data=pdata
综合上面的过程,我们完成了adapter的注册,并将用gpio口模拟的algorithm与adapter完成了关联。
这样,在rtc-x1205.c中,x1205_attach函数利用i2c核心完成client和adap的关联。
在x1205_probe函数中填充i2c_client结构体,并调用i2c_attach_client通知iic核心。
接着注册rtc驱动。
最后我们要读取时间,就需要构造i2c_msg结构体,如下所示:
struct i2c_msg msgs[] = {
{ client->addr, 0, 2,dt_addr }, /* setup read ptr */
{ client->addr, I2C_M_RD,8, buf }, /* read date */
};
/* read date registers */
if((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
dev_err(&client->dev,"%s: read error\n", __FUNCTION__);
return -EIO;
}
dt_addr是寄存器的地址,I2C_M_RD表示iicread。
8. linux内核中i2c总线驱动对所有的i2c设备是否是通用的
i2C总线的驱动程序一般针对不同的CPU是不一样的,所以都位于arch目录下对应的cpu架构的common文件夹下。
对同一种架构的来看,I2C驱动仅实现底层的通信。故其是通用的。
9. 求教高手,在linux内核中怎么修改i2c的通信速率为400KHz
1、先查看I2C设备速率。
sudocat/sys/mole/i2c_bcm2708/parameters/baudrate
默认的I2C速度为100KHz,对于多数I2C设备而言100KHz并不算快。
cd/etc/modprobe.d#进入/etc/modprobe.d目录
sudonanocustom.conf#在该目录新建一个名为custom.conf文件,并插入以下内容
#optionsi2c_bcm2708baudrate=400000
sudoreboot#重启系统