diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2007-12-07 19:01:15 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:03:24 -0500 |
commit | d9009201207c4bdce9b95a0bd903b3f087e8eda1 (patch) | |
tree | 86801fb674777c7a4693622363ac18a7a7896ec1 /drivers/media/video/ivtv/ivtv-i2c.c | |
parent | 9d1a16a4fc39bd908d85e0b7ce167048200d2d2b (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.c | 110 |
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 */ |
98 | static const u8 hw_driverids[] = { | 99 | static 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 */ |
119 | static 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 */ | ||
119 | static const char * const hw_drivernames[] = { | 139 | static 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 | ||
139 | static int attach_inform(struct i2c_client *client) | 158 | int 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 | |||
207 | static 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 | ||
486 | static void ivtv_setscl_old(void *data, int state) | 538 | static 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 | ||
542 | static const struct i2c_algo_bit_data ivtv_i2c_algo_template = { | 591 | static 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)); |