aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-i2c.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-12-07 19:01:15 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:03:24 -0500
commitd9009201207c4bdce9b95a0bd903b3f087e8eda1 (patch)
tree86801fb674777c7a4693622363ac18a7a7896ec1 /drivers/media/video/ivtv/ivtv-i2c.c
parent9d1a16a4fc39bd908d85e0b7ce167048200d2d2b (diff)
V4L/DVB (6765): ivtv: convert to bus-based i2c API
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-i2c.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c110
1 files changed, 83 insertions, 27 deletions
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 7f513ecc0781..9acfde68116a 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -92,7 +92,8 @@
92#define IVTV_TEA5767_I2C_ADDR 0x60 92#define IVTV_TEA5767_I2C_ADDR 0x60
93#define IVTV_UPD64031A_I2C_ADDR 0x12 93#define IVTV_UPD64031A_I2C_ADDR 0x12
94#define IVTV_UPD64083_I2C_ADDR 0x5c 94#define IVTV_UPD64083_I2C_ADDR 0x5c
95#define IVTV_TDA985X_I2C_ADDR 0x5b 95#define IVTV_VP27SMPX_I2C_ADDR 0x5b
96#define IVTV_M52790_I2C_ADDR 0x48
96 97
97/* This array should match the IVTV_HW_ defines */ 98/* This array should match the IVTV_HW_ defines */
98static const u8 hw_driverids[] = { 99static const u8 hw_driverids[] = {
@@ -105,7 +106,6 @@ static const u8 hw_driverids[] = {
105 I2C_DRIVERID_CS53L32A, 106 I2C_DRIVERID_CS53L32A,
106 I2C_DRIVERID_TVEEPROM, 107 I2C_DRIVERID_TVEEPROM,
107 I2C_DRIVERID_SAA711X, 108 I2C_DRIVERID_SAA711X,
108 I2C_DRIVERID_TVAUDIO,
109 I2C_DRIVERID_UPD64031A, 109 I2C_DRIVERID_UPD64031A,
110 I2C_DRIVERID_UPD64083, 110 I2C_DRIVERID_UPD64083,
111 I2C_DRIVERID_SAA717X, 111 I2C_DRIVERID_SAA717X,
@@ -116,8 +116,28 @@ static const u8 hw_driverids[] = {
116}; 116};
117 117
118/* This array should match the IVTV_HW_ defines */ 118/* This array should match the IVTV_HW_ defines */
119static const u8 hw_addrs[] = {
120 IVTV_CX25840_I2C_ADDR,
121 IVTV_SAA7115_I2C_ADDR,
122 IVTV_SAA7127_I2C_ADDR,
123 IVTV_MSP3400_I2C_ADDR,
124 0,
125 IVTV_WM8775_I2C_ADDR,
126 IVTV_CS53L32A_I2C_ADDR,
127 0,
128 IVTV_SAA7115_I2C_ADDR,
129 IVTV_UPD64031A_I2C_ADDR,
130 IVTV_UPD64083_I2C_ADDR,
131 IVTV_SAA717x_I2C_ADDR,
132 IVTV_WM8739_I2C_ADDR,
133 IVTV_VP27SMPX_I2C_ADDR,
134 IVTV_M52790_I2C_ADDR,
135 0 /* IVTV_HW_GPIO dummy driver ID */
136};
137
138/* This array should match the IVTV_HW_ defines */
119static const char * const hw_drivernames[] = { 139static const char * const hw_drivernames[] = {
120 "cx2584x", 140 "cx25840",
121 "saa7115", 141 "saa7115",
122 "saa7127", 142 "saa7127",
123 "msp3400", 143 "msp3400",
@@ -125,8 +145,7 @@ static const char * const hw_drivernames[] = {
125 "wm8775", 145 "wm8775",
126 "cs53l32a", 146 "cs53l32a",
127 "tveeprom", 147 "tveeprom",
128 "saa7114", 148 "saa7115",
129 "tvaudio",
130 "upd64031a", 149 "upd64031a",
131 "upd64083", 150 "upd64083",
132 "saa717x", 151 "saa717x",
@@ -136,21 +155,57 @@ static const char * const hw_drivernames[] = {
136 "gpio", 155 "gpio",
137}; 156};
138 157
139static int attach_inform(struct i2c_client *client) 158int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
140{ 159{
141 struct ivtv *itv = (struct ivtv *)i2c_get_adapdata(client->adapter); 160 struct i2c_board_info info;
161 struct i2c_client *c;
162 u8 id;
142 int i; 163 int i;
143 164
144 IVTV_DEBUG_I2C("i2c client attach\n"); 165 IVTV_DEBUG_I2C("i2c client register\n");
145 for (i = 0; i < I2C_CLIENTS_MAX; i++) { 166 if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
146 if (itv->i2c_clients[i] == NULL) { 167 return -1;
147 itv->i2c_clients[i] = client; 168 id = hw_driverids[idx];
148 break; 169 memset(&info, 0, sizeof(info));
149 } 170 strcpy(info.driver_name, hw_drivernames[idx]);
150 } 171 info.addr = hw_addrs[idx];
172 for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {}
173
151 if (i == I2C_CLIENTS_MAX) { 174 if (i == I2C_CLIENTS_MAX) {
152 IVTV_ERR("Insufficient room for new I2C client\n"); 175 IVTV_ERR("insufficient room for new I2C client!\n");
176 return -ENOMEM;
153 } 177 }
178
179 if (id != I2C_DRIVERID_TUNER) {
180 c = i2c_new_device(&itv->i2c_adap, &info);
181 if (c->driver == NULL)
182 i2c_unregister_device(c);
183 else
184 itv->i2c_clients[i] = c;
185 return itv->i2c_clients[i] ? 0 : -ENODEV;
186 }
187
188 /* special tuner handling */
189 c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->radio);
190 if (c && c->driver == NULL)
191 i2c_unregister_device(c);
192 else if (c)
193 itv->i2c_clients[i++] = c;
194 c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->demod);
195 if (c && c->driver == NULL)
196 i2c_unregister_device(c);
197 else if (c)
198 itv->i2c_clients[i++] = c;
199 c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->tv);
200 if (c && c->driver == NULL)
201 i2c_unregister_device(c);
202 else if (c)
203 itv->i2c_clients[i++] = c;
204 return 0;
205}
206
207static int attach_inform(struct i2c_client *client)
208{
154 return 0; 209 return 0;
155} 210}
156 211
@@ -478,9 +533,6 @@ static struct i2c_adapter ivtv_i2c_adap_hw_template = {
478 .client_register = attach_inform, 533 .client_register = attach_inform,
479 .client_unregister = detach_inform, 534 .client_unregister = detach_inform,
480 .owner = THIS_MODULE, 535 .owner = THIS_MODULE,
481#ifdef I2C_ADAP_CLASS_TV_ANALOG
482 .class = I2C_ADAP_CLASS_TV_ANALOG,
483#endif
484}; 536};
485 537
486static void ivtv_setscl_old(void *data, int state) 538static void ivtv_setscl_old(void *data, int state)
@@ -534,9 +586,6 @@ static struct i2c_adapter ivtv_i2c_adap_template = {
534 .client_register = attach_inform, 586 .client_register = attach_inform,
535 .client_unregister = detach_inform, 587 .client_unregister = detach_inform,
536 .owner = THIS_MODULE, 588 .owner = THIS_MODULE,
537#ifdef I2C_ADAP_CLASS_TV_ANALOG
538 .class = I2C_ADAP_CLASS_TV_ANALOG,
539#endif
540}; 589};
541 590
542static const struct i2c_algo_bit_data ivtv_i2c_algo_template = { 591static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
@@ -561,12 +610,9 @@ int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg
561 IVTV_DEBUG_I2C("call_i2c_client addr=%02x\n", addr); 610 IVTV_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
562 for (i = 0; i < I2C_CLIENTS_MAX; i++) { 611 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
563 client = itv->i2c_clients[i]; 612 client = itv->i2c_clients[i];
564 if (client == NULL) { 613 if (client == NULL || client->driver == NULL ||
565 continue; 614 client->driver->command == NULL)
566 }
567 if (client->driver->command == NULL) {
568 continue; 615 continue;
569 }
570 if (addr == client->addr) { 616 if (addr == client->addr) {
571 retval = client->driver->command(client, cmd, arg); 617 retval = client->driver->command(client, cmd, arg);
572 return retval; 618 return retval;
@@ -587,7 +633,7 @@ static int ivtv_i2c_id_addr(struct ivtv *itv, u32 id)
587 633
588 for (i = 0; i < I2C_CLIENTS_MAX; i++) { 634 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
589 client = itv->i2c_clients[i]; 635 client = itv->i2c_clients[i];
590 if (client == NULL) 636 if (client == NULL || client->driver == NULL)
591 continue; 637 continue;
592 if (id == client->driver->id) { 638 if (id == client->driver->id) {
593 retval = client->addr; 639 retval = client->addr;
@@ -713,6 +759,16 @@ int init_ivtv_i2c(struct ivtv *itv)
713{ 759{
714 IVTV_DEBUG_I2C("i2c init\n"); 760 IVTV_DEBUG_I2C("i2c init\n");
715 761
762 /* Sanity checks for the I2C hardware arrays. They must be the
763 * same size and GPIO must be the last entry.
764 */
765 if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) ||
766 ARRAY_SIZE(hw_drivernames) != ARRAY_SIZE(hw_addrs) ||
767 IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1)) ||
768 hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
769 IVTV_ERR("Mismatched I2C hardware arrays\n");
770 return -ENODEV;
771 }
716 if (itv->options.newi2c > 0) { 772 if (itv->options.newi2c > 0) {
717 memcpy(&itv->i2c_adap, &ivtv_i2c_adap_hw_template, 773 memcpy(&itv->i2c_adap, &ivtv_i2c_adap_hw_template,
718 sizeof(struct i2c_adapter)); 774 sizeof(struct i2c_adapter));