原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://ticktick.blog.51cto.com/823160/760020
- static struct i2c_driver tvp5158_i2c_driver = {
- .driver = {
- .name = "tvp5158_i2c_driver",
- },
- .attach_adapter = &tvp5158_attach_adapter,
- .detach_client = &tvp5158_detach_client,
- .command = NULL,
- };
- struct tvp5158_obj{
- struct i2c_client client;
- int users; // how many users using the driver
- };
- struct tvp5158_obj* g_tvp5158_obj;
- static unsigned short normal_i2c[] = {
- 0xbc >> 1,
- 0xbe >> 1,
- I2C_CLIENT_END
- };
- I2C_CLIENT_INSMOD;
- static int tvp5158_attach_adapter(struct i2c_adapter *adapter)
- {
- return i2c_probe(adapter, &addr_data, &tvp5158_detect_client);
- }
- static int tvp5158_detect_client(struct i2c_adapter *adapter,int address,int kind)
- {
- struct tvp5158_obj *pObj;
- int err = 0;
- printk(KERN_INFO "I2C: tvp5158_detect_client at address %x ...\n", address);
- if( g_tvp5158_obj != NULL ) {
- //already allocated,inc user count, and return the allocated handle
- g_tvp5158_obj->users++;
- return 0;
- }
- /* alloc obj */
- pObj = kmalloc(sizeof(struct tvp5158_obj), GFP_KERNEL);
- if (pObj==0){
- return -ENOMEM;
- }
- memset(pObj, 0, sizeof(struct tvp5158_obj));
- pObj->client.addr = address;
- pObj->client.adapter = adapter;
- pObj->client.driver = &tvp5158_i2c_driver;
- pObj->client.flags = I2C_CLIENT_ALLOW_USE;
- pObj->users++;
- /* attach i2c client to sys i2c clients list */
- if((err = i2c_attach_client(&pObj->client))){
- printk( KERN_ERR "I2C: ERROR: i2c_attach_client fail! address=%x\n",address);
- return err;
- }
- // store the pObj
- g_tvp5158_obj = pObj;
- printk( KERN_ERR "I2C: i2c_attach_client ok! address=%x\n",address);
- return 0;
- }
- static int tvp5158_detach_client(struct i2c_client *client)
- {
- int err;
- if( ! client->adapter ){
- return -ENODEV;
- }
- if( (err = i2c_detach_client(client)) ) {
- printk( KERN_ERR "Client deregistration failed (address=%x), client not detached.\n", client->addr);
- return err;
- }
- client->adapter = NULL;
- if( g_tvp5158_obj ){
- kfree(g_tvp5158_obj);
- }
- return 0;
- }
- extern int i2c_master_send(struct i2c_client *,const char* ,int);
- extern int i2c_master_recv(struct i2c_client *,char* ,int);
- extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num);
- static int __init tvp5158_i2c_init(void)
- {
- g_tvp5158_obj = NULL;
- return i2c_add_driver(&tvp5158_i2c_driver);
- }
- static void __exit tvp5158_i2c_exit(void)
- {
- i2c_del_driver(&tvp5158_i2c_driver);
- }
- module_init(tvp5158_i2c_init);
- module_exit(tvp5158_i2c_exit);
- MODULE_DESCRIPTION("TVP5158 i2c driver");
- MODULE_AUTHOR("Lujun @hust");
- MODULE_LICENSE("GPL");