分类: 嵌入式
2015-10-25 22:25:50
原文地址:linux下IIC驱动开发分析(3) 作者:putiancaijunyu
在系统开机时,首先装载的是I
static struct i2c_adapter pb1550_board_adapter =
{
name: "pb1550 adapter",
id: I
algo: NULL,
algo_data: &pb1550_i
inc_use: pb1550_inc_use,
dec_use: pb1550_dec_use,
client_register: pb1550_reg,
client_unregister: pb1550_unreg,
client_count: 0,
};
这个样例挂接了一个叫做“pb1550 adapter”的驱动。但这个模块并未提供读写函数,具体的读写方法由第二个模块,struct i
static struct i2c_algorithm au1550_algo =
{
.name = "Au1550 algorithm",
.id = I
.master_xfer = au1550_xfer,
.functionality = au1550_func,
};
i
这个样例给上述总线驱动增加了读写“算法”。通常情况下每个I
全部填妥后,通过调用:
i
将这两个模块注册到操作系统里,总线驱动就算装上了。对于AMD au1550,这部分已经由AMD提供了。
I
设备驱动透过I
当系统开机、I
static struct i
.owner = THIS_MODULE,
.name = DEV_NAME,
// .id = I
.flags = I
.attach_adapter = zlg7290_attach_adapter,
.detach_client = zlg7290_detach_client,
};
i
这个i
如何探测总线上的设备、Linux中i
I
static int my_attach(struct i
{
return i2c_probe(adapter, &addr_data, zlg7290_detect);
}
static int zlg7290_detect (struct i
{
..........
}
注意探测可能会找到多个设备,因而不仅一个I
每当设备驱动探测到了一个它能支持的设备,它就创建一个struct i
struct i
……
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &zlg7290_driver;
new_client->flags = 0;
/* Fill in the remaining client fields */
strlcpy(new_client->name, DEV_NAME, I
/* Tell the I
if ((err = i2c_attach_client(new_client))){
printk("i
goto exit_kfree;
}
可见,一个i
当得到I
/*
* The master routines are the ones normally used to transmit data to devices
* on a bus (or read from them). Apart from two basic transfer functions to
* transmit one message at a time, a more complex version can be used to
* transmit an arbitrary number of messages without interruption.
*/
extern int i
extern int i
addr_data是在 include/linux/i
static struct i
.normal_i
.probe = probe, \
.ignore = ignore, \
.forces = forces, \
}
若自己不定义,则用i
/* i
struct i
unsigned short *normal_i
unsigned short *probe;
unsigned short *ignore;
unsigned short **forces;
};
根据作者自行定义设备地址与否,有两种情形:
a. 采用默认定义,一般是不会work,毕竟大多数i
b. 作者自行定义地址结构
典型例子如下:
若自行定义,则参考如下:
/* Addresses to scan */
static unsigned short normal_i
I
static unsigned short probe[2] = {I
static unsigned short ignore[2] = {I
static struct i
normal_i
probe,
ignore,
};
或者根本就不定义完整的i
在my_probe()中把实际的地址赋于i
最后,i
forces[][], probe[], normal_i
I