saa711x驱动分析Word文档格式.docx
- 文档编号:20396465
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:14
- 大小:20.29KB
saa711x驱动分析Word文档格式.docx
《saa711x驱动分析Word文档格式.docx》由会员分享,可在线阅读,更多相关《saa711x驱动分析Word文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
detach_client为脱离i2c_client函数指针。
command为实现针对设备的控制命令指针,类似ioctl。
下面分别对saa711x_probe(),saa711x_detach(),saa711x_command()作分析。
2.
saa711x_probe()函数
saa711x_probe()是实现attach_adapter的函数。
可以简单的通过调用i2c_probe()函数来实现。
staticintsaa711x_probe(structi2c_adapter*adapter)
if(adapter->
class&
I2C_CLASS_TV_ANALOG||adapter->
I2C_CLASS_TV_DIGITAL)
returni2c_probe(adapter,&
addr_data,&
saa711x_attach);
return0;
adapter:
内核指针数组adapters[]的一个元素,代表当前被扫描的i2c总线。
addr_data:
在ltc3445.h中由I2C_CLIENT_INSMOD宏创建的静态二维数组,表示使用该驱动程序的所有设备的所有可能地址的集合。
saa711x_attach:
为一个在地址成功检测时被调用的回调函数,用于创建描述该设备的i2c_client数据结构并初始化。
i2c_probe函数用于认领adapter所指适配器上的所有合适的设备。
设备可能使用的地址的“线索”由addr_data二元数组指出,如果检测到存在实际设备,则调用saa711x_attach回调函数分配、初始化设备的i2c_client等数据结构。
由此引出了函数saa7111x_attach():
staticintsaa711x_attach(structi2c_adapter*adapter,intaddress,intkind);
i2c_adapter类型的适配器address:
chipaddress。
下面分析该函数的代码:
structi2c_client*client;
//具体设备名
structsaa711x_state*state;
//saa711x_state结构体
/*
saa711x_state的结构体如下:
structsaa711x_state{
v4l2_std_idstd;
intinput;
intoutput;
intenable;
intradio;
intbright;
intcontrast;
inthue;
intsat;
intwidth;
intheight;
u32ident;
u32audclk_freq;
u32crystal_freq;
u8ucgc;
u8cgcdiv;
u8apll;
*/
if(!
i2c_check_functionality(adapter,I2C_FUNC_SMBUS_BYTE_DATA))
这里调用了函数i2c_check_functionality()判断指定适配器是否支持相应的方法。
I2C_FUNC_SMBUS_BYTE_DATA:
HandlestheSMBUSread_byte_dataandwrite_byte_datacommands.
接着是对i2c_client初始化,初始化的过程中用到了saa711x_write和saa711x_read两个函数。
l
saa711x_write():
staticinlineintsaa711x_write(structi2c_client*client,u8reg,u8value)
returni2c_smbus_write_byte_data(client,reg,value);
这个函数的功能是把value的值写到client设备的reg寄存器中。
它通过调用i2c_smbus_write_byte_data来实现。
s32i2c_smbus_write_byte_data(structi2c_client*client,u8command,u8value)
unioni2c_smbus_datadata;
data.byte=value;
returni2c_smbus_xfer(client->
adapter,client->
addr,client->
flags,
I2C_SMBUS_WRITE,command,
I2C_SMBUS_BYTE_DATA,&
data);
EXPORT_SYMBOL(i2c_smbus_write_byte_data);
可以看出实际上是调用i2c_smbus_xfer()来实现。
这个函数通过适配器驱动提供的总线访问方法(i2c_algorithm的smbus_xfer方法)尝试访问处于addr地址上的设备。
s32i2c_smbus_xfer(structi2c_adapter*adapter,u16addr,unsignedshortflags,
charread_write,u8command,intsize,
unioni2c_smbus_data*data)
s32res;
flags&
=I2C_M_TEN|I2C_CLIENT_PEC;
algo->
smbus_xfer){
mutex_lock(&
adapter->
bus_lock);
res=adapter->
smbus_xfer(adapter,addr,flags,read_write,
command,size,data);
mutex_unlock(&
}else
res=i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
returnres;
而目前i2c中没有实现smbus_xfer方法而只实现了master_xfer方法,所以相关的操作就由i2c_smbus_xfer_emulated函数来模拟。
这个函数比较长,所以只分析它的参数。
其中size为I2C_SMBUS_QUICK的一段。
第二个参数为需要检测的设备地址,第四个参数read_write为0,表示进行写入操作。
如果使用这个总线地址和设备通信成功,则说明设备使用的正是这个地址。
saa711x_read():
staticinlineintsaa711x_read(structi2c_client*client,u8reg)
returni2c_smbus_read_byte_data(client,reg);
这个函数的功能是把client设备的reg寄存器中的值读出并返回。
它通过调用i2c_smbus_read_byte_data来实现。
s32i2c_smbus_read_byte_data(structi2c_client*client,u8command)
if(i2c_smbus_xfer(client->
I2C_SMBUS_READ,command,I2C_SMBUS_BYTE_DATA,&
data))
return-1;
else
returndata.byte;
EXPORT_SYMBOL(i2c_smbus_read_byte_data);
可以看出,它也是调用i2c_smbus_xfer函数来实现的,因此和saa711x_write()的过程基本一样。
再回头看i2c_client的初始化:
分配i2c_client的内存空间
client=kzalloc(sizeof(structi2c_client),GFP_KERNEL);
if(client==0)
return-ENOMEM;
初始化client的addr,adapter和driver。
没什么可说的。
client->
addr=address;
adapter=adapter;
driver=&
i2c_driver_saa711x;
初始化client的name。
snprintf(client->
name,sizeof(client->
name)-1,"
);
for(i=0;
i<
0x0f;
i++){
saa711x_write(client,0,i);
name[i]=(saa711x_read(client,0)&
0x0f)+'
0'
;
if(name[i]>
'
9'
)
name[i]+='
a'
-'
-1;
}
name[i]='
\0'
查看芯片号是否为saa711x。
saa711x_write(client,0,5);
chip_id=saa711x_read(client,0)&
/*Checkwhetherthischipispartofthesaa711xseries*/
if(memcmp(name,"
1f711"
5)){
v4l_dbg(1,debug,client,"
chipfound@0x%x(ID%s)doesnotmatchaknownsaa711xchip.\n"
address<
<
1,name);
kfree(client);
saa711%d"
chip_id);
v4l_info(client,"
saa711%dfound(%s)@0x%x(%s)\n"
chip_id,name,address<
1,adapter->
name);
到此,i2c_client结构体client初始化完毕。
下面开始对saa711x_state结构体state进行初始化。
state=kzalloc(sizeof(structsaa711x_state),GFP_KERNEL);
i2c_set_clientdata(client,state);
//将state存到client->
dev中
if(state==NULL){
state->
input=-1;
output=SAA7115_IPORT_ON;
enable=1;
radio=0;
bright=128;
contrast=64;
hue=0;
sat=64;
然后根据芯片号确认是哪款芯片。
并选择不同的初始化函数。
switch(chip_id){
case1:
ident=V4L2_IDENT_SAA7111;
break;
case3:
ident=V4L2_IDENT_SAA7113;
case4:
ident=V4L2_IDENT_SAA7114;
case5:
ident=V4L2_IDENT_SAA7115;
case8:
ident=V4L2_IDENT_SAA7118;
default:
WARNING:
Chipisnotknown-Fallingbacktosaa7111\n"
audclk_freq=48000;
writinginitvalues\n"
/*initto60hz/48khz*/
crystal_freq=SAA7115_FREQ_24_576_MHZ;
switch(state->
ident){
caseV4L2_IDENT_SAA7111:
saa711x_writeregs(client,saa7111_init);
caseV4L2_IDENT_SAA7113:
saa711x_writeregs(client,saa7113_init);
crystal_freq=SAA7115_FREQ_32_11_MHZ;
saa711x_writeregs(client,saa7115_init_auto_input);
以7111的初始化函数saa7111_init()为例分析芯片的初始化。
这里用到了saa711x_writeregs()函数。
在saa711x_writeregs()中又调用了i2c_get_clientdata(),saa711x_has_reg()以及saa711x_write()。
saa711x_write()在前面已经分析过了,这里重点分析i2c_getclientdata()和saa711x_has_reg()。
i2c_get_clientdata()是i2c的一个API。
staticinlinevoid*i2c_get_clientdata(structi2c_client*dev)
returndev_get_drvdata(&
dev->
dev);
staticinlinevoid*
dev_get_drvdata(structdevice*dev)
returndev->
driver_data;
很明显,是将一个i2c_client结构体中的dev->
driver_data返回。
saa711x_has_reg()函数
/*Sanityroutinetocheckifaregisterispresent*/
staticintsaa711x_has_reg(constintid,constu8reg)
if(id==V4L2_IDENT_SAA7111)
returnreg<
0x20&
&
reg!
=0x01&
=0x0f&
(reg<
0x13||reg>
0x19)&
=0x1d&
=0x1e;
/*commonforsaa7113/4/5/8*/
if(unlikely((reg>
=0x3b&
reg<
=0x3f)||reg==0x5c||reg==0x5f||
reg==0xa3||reg==0xa7||reg==0xab||reg==0xaf||(reg>
=0xb5&
=0xb7)||
reg==0xd3||reg==0xd7||reg==0xdb||reg==0xdf||(reg>
=0xe5&
=0xe7)||
reg==0x82||(reg>
=0x89&
=0x8e)))
switch(id){
returnreg!
=0x14&
0x18||reg>
0x1e)&
0x20||reg>
0x3f)&
=0x5d&
0x63;
caseV4L2_IDENT_SAA7114:
return(reg<
0x1a||reg>
0x2f)&
0x63||reg>
0x7f)&
=0x33&
=0x37&
=0x81&
0xf0;
caseV4L2_IDENT_SAA7115:
=0x65&
0xfc||reg>
0xfe);
caseV4L2_IDENT_SAA7118:
0x1d)&
0x22)&
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- saa711x 驱动 分析