Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at d430a227d272fa514bade388bf511dba4ec2962a 142 lines 4.6 kB view raw
1/* 2 * v4l2-i2c-drv-legacy.h - contains I2C handling code that's identical 3 * for all V4L2 I2C drivers. Use this header if the 4 * I2C driver is used by both legacy drivers and 5 * drivers converted to the bus-based I2C API. 6 * 7 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 */ 23 24struct v4l2_i2c_driver_data { 25 const char * const name; 26 int driverid; 27 int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); 28 int (*probe)(struct i2c_client *client, const struct i2c_device_id *id); 29 int (*remove)(struct i2c_client *client); 30 int (*suspend)(struct i2c_client *client, pm_message_t state); 31 int (*resume)(struct i2c_client *client); 32 int (*legacy_probe)(struct i2c_adapter *adapter); 33 int legacy_class; 34 const struct i2c_device_id *id_table; 35}; 36 37static struct v4l2_i2c_driver_data v4l2_i2c_data; 38static const struct i2c_client_address_data addr_data; 39static struct i2c_driver v4l2_i2c_driver_legacy; 40static char v4l2_i2c_drv_name_legacy[32]; 41 42static int v4l2_i2c_drv_attach_legacy(struct i2c_adapter *adapter, int address, int kind) 43{ 44 return v4l2_i2c_attach(adapter, address, &v4l2_i2c_driver_legacy, 45 v4l2_i2c_drv_name_legacy, v4l2_i2c_data.probe); 46} 47 48static int v4l2_i2c_drv_probe_legacy(struct i2c_adapter *adapter) 49{ 50 if (v4l2_i2c_data.legacy_probe) { 51 if (v4l2_i2c_data.legacy_probe(adapter)) 52 return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy); 53 return 0; 54 } 55 if (adapter->class & v4l2_i2c_data.legacy_class) 56 return i2c_probe(adapter, &addr_data, v4l2_i2c_drv_attach_legacy); 57 return 0; 58} 59 60static int v4l2_i2c_drv_detach_legacy(struct i2c_client *client) 61{ 62 int err; 63 64 if (v4l2_i2c_data.remove) 65 v4l2_i2c_data.remove(client); 66 67 err = i2c_detach_client(client); 68 if (err) 69 return err; 70 kfree(client); 71 72 return 0; 73} 74 75static int v4l2_i2c_drv_suspend_helper(struct i2c_client *client, pm_message_t state) 76{ 77 return v4l2_i2c_data.suspend ? v4l2_i2c_data.suspend(client, state) : 0; 78} 79 80static int v4l2_i2c_drv_resume_helper(struct i2c_client *client) 81{ 82 return v4l2_i2c_data.resume ? v4l2_i2c_data.resume(client) : 0; 83} 84 85/* ----------------------------------------------------------------------- */ 86 87/* i2c implementation */ 88static struct i2c_driver v4l2_i2c_driver_legacy = { 89 .driver = { 90 .owner = THIS_MODULE, 91 }, 92 .attach_adapter = v4l2_i2c_drv_probe_legacy, 93 .detach_client = v4l2_i2c_drv_detach_legacy, 94 .suspend = v4l2_i2c_drv_suspend_helper, 95 .resume = v4l2_i2c_drv_resume_helper, 96}; 97 98/* ----------------------------------------------------------------------- */ 99 100/* i2c implementation */ 101static struct i2c_driver v4l2_i2c_driver = { 102 .suspend = v4l2_i2c_drv_suspend_helper, 103 .resume = v4l2_i2c_drv_resume_helper, 104}; 105 106static int __init v4l2_i2c_drv_init(void) 107{ 108 int err; 109 110 strlcpy(v4l2_i2c_drv_name_legacy, v4l2_i2c_data.name, sizeof(v4l2_i2c_drv_name_legacy)); 111 strlcat(v4l2_i2c_drv_name_legacy, "'", sizeof(v4l2_i2c_drv_name_legacy)); 112 113 if (v4l2_i2c_data.legacy_class == 0) 114 v4l2_i2c_data.legacy_class = I2C_CLASS_TV_ANALOG; 115 116 v4l2_i2c_driver_legacy.driver.name = v4l2_i2c_drv_name_legacy; 117 v4l2_i2c_driver_legacy.id = v4l2_i2c_data.driverid; 118 v4l2_i2c_driver_legacy.command = v4l2_i2c_data.command; 119 err = i2c_add_driver(&v4l2_i2c_driver_legacy); 120 121 if (err) 122 return err; 123 v4l2_i2c_driver.driver.name = v4l2_i2c_data.name; 124 v4l2_i2c_driver.id = v4l2_i2c_data.driverid; 125 v4l2_i2c_driver.command = v4l2_i2c_data.command; 126 v4l2_i2c_driver.probe = v4l2_i2c_data.probe; 127 v4l2_i2c_driver.remove = v4l2_i2c_data.remove; 128 v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table; 129 err = i2c_add_driver(&v4l2_i2c_driver); 130 if (err) 131 i2c_del_driver(&v4l2_i2c_driver_legacy); 132 return err; 133} 134 135static void __exit v4l2_i2c_drv_cleanup(void) 136{ 137 i2c_del_driver(&v4l2_i2c_driver_legacy); 138 i2c_del_driver(&v4l2_i2c_driver); 139} 140 141module_init(v4l2_i2c_drv_init); 142module_exit(v4l2_i2c_drv_cleanup);