linux内核I2C总线驱动(三)

I2c的应用编写,这里我不叫驱动编写哈。

 

上次我们分析了i2c的来源,我们应该看看,系统给我们提供了什么,同时配合官方手册来做讲解欧克~

 

最讨厌的是很多东西他不在H文件里在C文件里

\kernel-3.4.39\drivers\i2c\i2c-core.c

 

i2c_verify_client—返回参数i2c_client,或NULL dev: device,可能在遍历驱动模型树时从某个驱动模型迭代器返回,可能使用驱动模型迭代器如@device_for_each_child(),您不能对所找到的节点进行太多假设。

使用这个函数可以避免错误地将一些非i2c设备当作i2c_client而导致的oopses。

 

 

官方:

Description

Systems using the Linux I2C driver stack can declare tables of board info while they initialize. This should be done in board-specific init code near arch_initcall() time, or equivalent, before any I2C adapter driver is registered. For example, mainboard init code could define several devices, as could the init code for each daughtercard in a board stack.

The I2C devices will be created later, after the adapter for the relevant bus has been registered. After that moment, standard driver model tools are used to bind “new style” I2C drivers to the devices. The bus number for any device declared using this routine is not available for dynamic allocation.

The board info passed can safely be __initdata, but be careful of embedded pointers (for platform_data, functions, etc) since that won’t be copied. Device properties are deep-copied though.

struct i2c_client * i2c_verify_client(struct device * dev)

return parameter as i2c_client, or NULL

Parameters

struct device * dev

device, probably from some driver model iterator

给一个device检查是否有对应的client

 

i2c_new_device—实例化一个i2c设备

管理设备的适配器

描述一个I2C设备;

bus_num被忽略

可以睡

创建一个i2c设备。

绑定是通过驱动程序模型处理的

探针()/ remove()方法。

一个驱动程序可能被绑定到这个设备,当我们

从这个功能返回,或任何稍后的时刻(例如,可能热插拔将

加载驱动模块)。

这个呼叫不适合主板使用

初始化逻辑,通常在arch_initcall()期间运行

在i2c_adapter出现之前。

这将返回新的i2c客户机,该客户机可以保存以备以后使用

i2c_unregister_device ();

或NULL表示错误。

 

官方:

Description

Create an i2c device. Binding is handled through driver model probe()/remove() methods. A driver may be bound to this device when we return from this function, or any later moment (e.g. maybe hotplugging will load the driver module). This call is not appropriate for use by mainboard initialization logic, which usually runs during an arch_initcall() long before any i2c_adapter could exist.

This returns the new i2c client, which may be saved for later use with i2c_unregister_device(); or an ERR_PTR to describe the error.

struct i2c_client * i2c_new_device(struct i2c_adapter * adap, struct i2c_board_info const * info)

instantiate an i2c device

Parameters

struct i2c_adapter * adap

the adapter managing the device

struct i2c_board_info const * info

describes one I2C device; bus_num is ignored

Context

can sleep

新建一个i2c device

 

i2c_unregister_device—i2c_new_device()的反向效果

@client: i2c_new_device()返回的值

可以睡

 

官方:

Description

This deprecated function has the same functionality as i2c_new_client_device, it just returns NULL instead of an ERR_PTR in case of an error for compatibility with current I2C API. It will be removed once all users are converted.

This returns the new i2c client, which may be saved for later use with i2c_unregister_device(); or NULL to indicate an error.

void i2c_unregister_device(struct i2c_client * client)

reverse effect of i2c_new_*_device()

Parameters

struct i2c_client * client

value returned from i2c_new_*_device()

Context

can sleep

 

注销一个i2c device

 

i2c_new_dummy -返回一个绑定到虚拟驱动程序的新的i2c设备

管理设备的适配器

要使用的7位地址

可以睡

这将返回一个绑定到“虚拟”驱动程序的I2C客户机,以供使用

对于使用多个地址的设备。

这类芯片的例子

包括各种EEPROMS(如24c04和24c08型)。

这些虚拟设备有两个主要用途。

首先,大多数I2C和SMBus调用

除了i2c_transfer()需要一个客户端句柄;

假人就是那个把手。

第二,这防止指定的地址被绑定到

不同的驱动程序。

这将返回新的i2c客户端,应该将其保存以备以后使用

i2c_unregister_device ();

或NULL表示错误。

 

官方:

struct i2c_client * i2c_new_dummy_device(struct i2c_adapter * adapter, u16 address)

return a new i2c device bound to a dummy driver

Parameters

struct i2c_adapter * adapter

the adapter managing the device

u16 address

seven bit address to be used

Context

can sleep

我理解是一个快速的绑定注册接口,不知道对不对

 

i2c_add_adapter—声明i2c适配器,使用动态总线号

要添加的适配器

可以睡

*这个例程用来声明一个I2C适配器,当它的总线号码

*不重要。

示例:用于动态添加的I2C适配器

* USB链接或PCI插件卡。

*当返回0时,分配并存储了一个新的总线号

*在adap- nr中,指定的适配器对客户端可用。

*否则,返回负的errno值。

 

官方:

Description

Helper function to be called from an I2C bus driver’s interrupt handler. It will schedule the Host Notify IRQ.

int i2c_add_adapter(struct i2c_adapter * adapter)

declare i2c adapter, use dynamic bus number

Parameters

struct i2c_adapter * adapter

the adapter to add

Context

can sleep

这个是给芯片层级使用的,添加一个i2c适配器

 

* i2c_add_numbered_adapter -声明i2c适配器,使用静态总线号码

* @adap:要注册的适配器(adap->nr已初始化)

上下文:可以睡觉

 

官方:

Description

This routine is used to declare an I2C adapter when its bus number doesn’t matter or when its bus number is specified by an dt alias. Examples of bases when the bus number doesn’t matter: I2C adapters dynamically added by USB links or PCI plugin cards.

When this returns zero, a new bus number was allocated and stored in adap->nr, and the specified adapter became available for clients. Otherwise, a negative errno value is returned.

int i2c_add_numbered_adapter(struct i2c_adapter * adap)

declare i2c adapter, use static bus number

Parameters

struct i2c_adapter * adap

the adapter to register (with adap->nr initialized)

Context

can sleep

 

使用静态号码注册适配器

 

* i2c_del_adapter -取消注册I2C适配器

* @adap:适配器被取消注册

上下文:可以睡觉

*取消先前注册的I2C适配器的注册

 

官方:

Description

This routine is used to declare an I2C adapter when its bus number matters. For example, use it for I2C adapters from system-on-chip CPUs, or otherwise built in to the system’s mainboard, and where i2c_board_info is used to properly configure I2C devices.

If the requested bus number is set to -1, then this function will behave identically to i2c_add_adapter, and will dynamically assign a bus number.

If no devices have pre-been declared for this bus, then be sure to register the adapter before any dynamically allocated ones. Otherwise the required bus ID may not be available.

When this returns zero, the specified adapter became available for clients using the bus number provided in adap->nr. Also, the table of I2C devices pre-declared using i2c_register_board_info() is scanned, and the appropriate driver model device nodes are created. Otherwise, a negative errno value is returned.

void i2c_del_adapter(struct i2c_adapter * adap)

unregister I2C adapter

Parameters

struct i2c_adapter * adap

the adapter being unregistered

Context

can sleep

 

* i2c_transfer—执行单个或组合的I2C消息

处理I2C总线

* @msgs:在发出STOP之前要执行的一条或多条消息

*终止操作;

每条消息都有一个开头。

* @num:要执行的消息数。

*返回负的errno,否则为执行的消息数。

*注意,没有要求每条消息都要发送到

*相同的从地址,尽管这是最常见的模型。

 

官方:

Description

Returns negative errno, else the number of messages executed.

Adapter lock must be held when calling this function. No debug logging takes place. adap->algo->master_xfer existence isn’t checked.

int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg * msgs, int num)

execute a single or combined I2C message

Parameters

struct i2c_adapter * adap

Handle to I2C bus

struct i2c_msg * msgs

One or more messages to execute before STOP is issued to terminate the operation; each message begins with a START.

int num

Number of messages to be executed.

 

我们最常用的发送和接受函数

 

* i2c_master_send -在主传输模式下发出一条I2C消息

从设备的句柄

将被写入从服务器的数据

* @count:写多少字节,必须小于64k,因为msg。

len是u16

*返回负的errno,或者返回写入的字节数。

 

官方:

Description

Returns negative errno, or else the number of bytes read.

int i2c_master_send(const struct i2c_client * client, const char * buf, int count)

issue a single I2C message in master transmit mode

Parameters

const struct i2c_client * client

Handle to slave device

const char * buf

Data that will be written to the slave

int count

How many bytes to write, must be less than 64k since msg.len is u16

 

作为主控,发送数据函数

 

* i2c_master_recv -在主接收模式下发出一条I2C消息

从设备的句柄

* @buf:存储从slave读取的数据的位置

* @count:读取多少字节,必须小于64k,因为msg。

len是u16

*返回负的errno,或者返回读取的字节数。

 

官方:

int i2c_master_recv(const struct i2c_client * client, char * buf, int count)

issue a single I2C message in master receive mode

Parameters

const struct i2c_client * client

Handle to slave device

char * buf

Where to store data read from slave

int count

How many bytes to read, must be less than 64k since msg.len is u16

 

最常用的接收函数了

 

* i2c_smbus_read_byte - SMBus“接收字节”协议

从设备的句柄

*执行SMBus的“接收字节”协议,返回负errno

* else从设备接收的字节。

 

官方:

s32 i2c_smbus_read_byte(const struct i2c_client * client)

SMBus “receive byte” protocol

Parameters

const struct i2c_client * client

Handle to slave device

 

按照SMB协议读取

 

官方:

Description

This executes the SMBus “receive byte” protocol, returning negative errno else the byte received from the device.

s32 i2c_smbus_write_byte(const struct i2c_client * client, u8 value)

SMBus “send byte” protocol

Parameters

const struct i2c_client * client

Handle to slave device

u8 value

Byte to be sent

 

很关键的函数,但是没有什么说明,从官方也没得到什么

这个函数用来获取适配器

 

同样很关键的函数,也是没找到任何注释

作用是i2c_put_adapter函数和i2c_get_adapter相对应的函数,它用来释放适配器

 

 

是个宏,本质是i2c_register_driver

 

 

一个i2c_driver与一个或多个i2c_client (device)节点一起使用

* i2c从芯片,在与一些i2c_adapter相关联的总线实例上。

 

就是注册一个driver说的这么麻烦

 

 

kernel-3.4.39\include\linux\i2c.h下还是给了很多方法和说明的,有兴趣的可以看一下

 

 

 

总结:

I2c驱动的编写基本过程是

 

i2c_get_adapter 得到想要的适配器

i2c_new_device 新建一个设备

i2c_put_adapter 释放得到的适配器

i2c_add_driver 把新建的设备进行添加(关联、注册)你愿意怎么说都好

 

这样在你初始化后芯片地址被扫描到就会执行相应的probe函数

 

在pobe函数内 注册字符设备和初始化i2c从芯片即可了

 

怎么样是不是很简单呢?

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值