驱动篇:I 2 C 总线驱动实例(二)(摘录)

驱动篇:I 2 C 总线驱动实例(二)

SAA7113H 是飞利浦半导体推出的 9 位视频 AD 芯片,它可以选择 4 路视频输入中的 1 路,并采样为 9 位的数字信号
驱动篇:I 2 C 总线驱动实例(二)(摘录)对 SAA7113H 输入通道的选择以及采样方式的设置都需通过其 I 2 C 接口进行,以0x4A 地址可读 SAA7113H 寄存器,以 0x4B 可写 SAA7113H 寄存器。SAA7113H 的 I 2 C接口连接在 S3C2410 的 I 2 C 控制器上,作为 S3C2410 I 2 C 控制器的从设备。SAA7113H的写时序与图 15.7 给出的写时序是一致的,但是读时序则需通过两条 I 2 C 消息解决,在第 1 条消息中应该给 SAA7113H 写入寄存器子地址
驱动篇:I 2 C 总线驱动实例(二)(摘录) 由于不需要给 SAA7113H 实现文件操作接口,在设备驱动模块的加载和卸载函数中均不再需要注册和注销字符设备的操作
SAA7113H 设备驱动的模块加载和卸载函数

 static int __init saa711x_init (void)
 {
return i2c_add_driver(&i2c_driver_saa711x); //注册 i2c_driver
 }
 static void __exit saa711x_exit (void)
{
i2c_del_driver(&i2c_driver_saa711x); //注销 i2c_driver
 }
 module_init(saa711x_init);
 module_exit(saa711x_exit);

SAA7113H 设备驱动模块加载和卸载中添加和删除的i2c_driver_ saa711x 结构体的 attach_adapter 指针被赋值为 saa711x_attach_adapter,detach_client 指 针 被 赋 值 为 saa711x_detach_client , 而 command 指 针 被 赋 值 为saa711x_command,以下为三个函数的实现

static struct i2c_driver i2c_driver_saa711x = {
 .driver = {
 .name = "saa711x",
 },
.id = I2C_DRIVERID_SAA711X,
/* 成员函数 */
.attach_adapter = saa711x_attach_adapter,
.detach_client = saa711x_detach_client,
.command = saa711x_command,
 };

i2c_driver 成员函数

 saa711x_attach_adapter (struct i2c_adapter *adapter)
 {
dprintk(1, KERN_INFO "saa711x.c: starting probe for adapter %s(0x%x)\n",I2C_NAME(adapter), adapter->id);
return i2c_probe(adapter, &addr_data, &saa711x_detect_client);
7
//saa711x_detect_client
会 调 用
i2c_set_clientdata() 、
i2c_attach_client()
 }


 static int saa711x_detach_client (struct i2c_client *client)
 {
 struct saa711x *decoder = i2c_get_clientdata(client);
 int err;
 err = i2c_detach_client(client);
 if (err) {
return err;
}
 kfree(decoder);
 kfree(client);
return 0;
 }



 static int saa711x_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
struct saa711x *decoder = i2c_get_clientdata(client);
 switch (cmd) //处理不同的命令
 {
 case 0:
 case DECODER_INIT:
...
case DECODER_DUMP:
...
case DECODER_GET_CAPABILITIES:
...
case DECODER_GET_STATUS:
...
case DECODER_SET_VBI_BYPASS:
...
case DECODER_SET_NORM:
     ...
case DECODER_SET_INPUT:
{
 int *iarg = arg;
 if (*iarg < 0 || *iarg > 9)
 {
return - EINVAL;
 }
 if (decoder->input != *iarg)
 {
 decoder->input = *iarg;
 saa711x_write(client, 0x02, (decoder->reg[0x02] &0xf0) |
decoder->input);
saa711x_write(client, 0x09, (decoder->reg[0x09] &0x7f) |
((decoder->input > 3) ? 0x80 : 0));
}
 }
 break;
case DECODER_SET_OUTPUT:
...
case DECODER_ENABLE_OUTPUT:
...
case DECODER_SET_PICTURE:
...
default:

return - EINVAL;
}
return 0;
 }

Linux I 2 C 驱动体系结构有相当的复杂度,它主要由 3 部分组成,即 I 2 C 核心、I 2 C总线驱动和 I 2 C 设备驱动。 I 2 C 核心是 I2C 总线驱动和 I 2 C 设备驱动的中间枢纽, 它以通用的、与平台无关的接口实现了 I 2 C 中设备与适配器的沟通。I 2 C 总线驱动填充i2c_adapter 和 i2c_algorithm 结构体, I 2 C 设备驱动填充 i2c_driver 和 i2c_client 结构体。
另外,系统中 i2c-dev.c 文件定义的主设备号为 89 的设备可以方便地给应用程序提供读写 I 2 C 设备寄存器的能力,使得工程师大多数时候并不需要为具体的 I 2 C 设备驱动定义文件操作接口。最后,工程师在设计 I 2 C 设备驱动的程序,并不是一定要遵守 Linux I 2 C 驱动的体系结构,完全可以把它当作一个普通的字符设备处理。

上一篇:C# 获取网卡信息


下一篇:RMDB与hadoop的实时整合