Rev 170 | Rev 463 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
170 | giacomo | 1 | /* |
2 | bttv-if.c -- interfaces to other kernel modules |
||
3 | all the i2c code is here |
||
4 | also the gpio interface exported by bttv (used by lirc) |
||
5 | |||
6 | bttv - Bt848 frame grabber driver |
||
7 | |||
8 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) |
||
9 | & Marcus Metzler (mocm@thp.uni-koeln.de) |
||
428 | giacomo | 10 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> |
170 | giacomo | 11 | |
12 | This program is free software; you can redistribute it and/or modify |
||
13 | it under the terms of the GNU General Public License as published by |
||
14 | the Free Software Foundation; either version 2 of the License, or |
||
15 | (at your option) any later version. |
||
16 | |||
17 | This program is distributed in the hope that it will be useful, |
||
18 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
20 | GNU General Public License for more details. |
||
21 | |||
22 | You should have received a copy of the GNU General Public License |
||
23 | along with this program; if not, write to the Free Software |
||
24 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
25 | |||
26 | */ |
||
27 | |||
428 | giacomo | 28 | #include <linuxcomp.h> |
170 | giacomo | 29 | |
428 | giacomo | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> |
||
32 | #include <linux/delay.h> |
||
170 | giacomo | 33 | |
34 | #include <asm/io.h> |
||
35 | |||
428 | giacomo | 36 | #include "drivers/bttvp.h" |
170 | giacomo | 37 | |
428 | giacomo | 38 | static struct i2c_algo_bit_data bttv_i2c_algo_bit_template; |
39 | static struct i2c_adapter bttv_i2c_adap_sw_template; |
||
40 | static struct i2c_adapter bttv_i2c_adap_hw_template; |
||
170 | giacomo | 41 | static struct i2c_client bttv_i2c_client_template; |
42 | |||
428 | giacomo | 43 | #ifndef I2C_PEC |
44 | static void bttv_inc_use(struct i2c_adapter *adap); |
||
45 | static void bttv_dec_use(struct i2c_adapter *adap); |
||
46 | #endif |
||
47 | static int attach_inform(struct i2c_client *client); |
||
48 | |||
49 | EXPORT_SYMBOL(bttv_get_cardinfo); |
||
50 | EXPORT_SYMBOL(bttv_get_pcidev); |
||
51 | EXPORT_SYMBOL(bttv_get_id); |
||
52 | EXPORT_SYMBOL(bttv_gpio_enable); |
||
53 | EXPORT_SYMBOL(bttv_read_gpio); |
||
54 | EXPORT_SYMBOL(bttv_write_gpio); |
||
55 | EXPORT_SYMBOL(bttv_get_gpio_queue); |
||
56 | EXPORT_SYMBOL(bttv_i2c_call); |
||
57 | |||
58 | static int i2c_debug = 0; |
||
59 | static int i2c_hw = 0; |
||
60 | MODULE_PARM(i2c_debug,"i"); |
||
61 | MODULE_PARM(i2c_hw,"i"); |
||
62 | |||
170 | giacomo | 63 | /* ----------------------------------------------------------------------- */ |
64 | /* Exported functions - for other modules which want to access the */ |
||
65 | /* gpio ports (IR for example) */ |
||
66 | /* see bttv.h for comments */ |
||
67 | |||
428 | giacomo | 68 | int bttv_get_cardinfo(unsigned int card, int *type, unsigned *cardid) |
170 | giacomo | 69 | { |
70 | if (card >= bttv_num) { |
||
71 | return -1; |
||
72 | } |
||
73 | *type = bttvs[card].type; |
||
74 | *cardid = bttvs[card].cardid; |
||
75 | return 0; |
||
76 | } |
||
77 | |||
428 | giacomo | 78 | struct pci_dev* bttv_get_pcidev(unsigned int card) |
79 | { |
||
80 | if (card >= bttv_num) |
||
81 | return NULL; |
||
82 | return bttvs[card].dev; |
||
83 | } |
||
84 | |||
85 | int bttv_get_id(unsigned int card) |
||
86 | { |
||
87 | printk("bttv_get_id is obsolete, use bttv_get_cardinfo instead\n"); |
||
88 | if (card >= bttv_num) { |
||
89 | return -1; |
||
90 | } |
||
91 | return bttvs[card].type; |
||
92 | } |
||
93 | |||
94 | |||
170 | giacomo | 95 | int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data) |
96 | { |
||
97 | struct bttv *btv; |
||
98 | |||
99 | if (card >= bttv_num) { |
||
100 | return -EINVAL; |
||
101 | } |
||
102 | |||
103 | btv = &bttvs[card]; |
||
104 | btaor(data, ~mask, BT848_GPIO_OUT_EN); |
||
105 | if (bttv_gpio) |
||
106 | bttv_gpio_tracking(btv,"extern enable"); |
||
107 | return 0; |
||
108 | } |
||
109 | |||
110 | int bttv_read_gpio(unsigned int card, unsigned long *data) |
||
111 | { |
||
112 | struct bttv *btv; |
||
113 | |||
114 | if (card >= bttv_num) { |
||
115 | return -EINVAL; |
||
116 | } |
||
117 | |||
118 | btv = &bttvs[card]; |
||
119 | |||
120 | if(btv->shutdown) { |
||
121 | return -ENODEV; |
||
122 | } |
||
123 | |||
124 | /* prior setting BT848_GPIO_REG_INP is (probably) not needed |
||
125 | because we set direct input on init */ |
||
428 | giacomo | 126 | *data = btread(BT848_GPIO_DATA); |
170 | giacomo | 127 | return 0; |
128 | } |
||
129 | |||
130 | int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data) |
||
131 | { |
||
132 | struct bttv *btv; |
||
133 | |||
134 | if (card >= bttv_num) { |
||
135 | return -EINVAL; |
||
136 | } |
||
137 | |||
138 | btv = &bttvs[card]; |
||
139 | |||
140 | /* prior setting BT848_GPIO_REG_INP is (probably) not needed |
||
141 | because direct input is set on init */ |
||
428 | giacomo | 142 | btaor(data & mask, ~mask, BT848_GPIO_DATA); |
170 | giacomo | 143 | if (bttv_gpio) |
144 | bttv_gpio_tracking(btv,"extern write"); |
||
145 | return 0; |
||
146 | } |
||
147 | |||
428 | giacomo | 148 | wait_queue_head_t* bttv_get_gpio_queue(unsigned int card) |
149 | { |
||
150 | struct bttv *btv; |
||
151 | |||
152 | if (card >= bttv_num) { |
||
153 | return NULL; |
||
154 | } |
||
155 | |||
156 | btv = &bttvs[card]; |
||
157 | if (bttvs[card].shutdown) { |
||
158 | return NULL; |
||
159 | } |
||
160 | return &btv->gpioq; |
||
161 | } |
||
162 | |||
163 | |||
170 | giacomo | 164 | /* ----------------------------------------------------------------------- */ |
428 | giacomo | 165 | /* I2C functions - bitbanging adapter (software i2c) */ |
170 | giacomo | 166 | |
167 | void bttv_bit_setscl(void *data, int state) |
||
168 | { |
||
169 | struct bttv *btv = (struct bttv*)data; |
||
428 | giacomo | 170 | |
170 | giacomo | 171 | if (state) |
172 | btv->i2c_state |= 0x02; |
||
173 | else |
||
174 | btv->i2c_state &= ~0x02; |
||
175 | btwrite(btv->i2c_state, BT848_I2C); |
||
428 | giacomo | 176 | btread(BT848_I2C); |
170 | giacomo | 177 | } |
178 | |||
179 | void bttv_bit_setsda(void *data, int state) |
||
180 | { |
||
181 | struct bttv *btv = (struct bttv*)data; |
||
428 | giacomo | 182 | |
170 | giacomo | 183 | if (state) |
184 | btv->i2c_state |= 0x01; |
||
185 | else |
||
186 | btv->i2c_state &= ~0x01; |
||
187 | btwrite(btv->i2c_state, BT848_I2C); |
||
428 | giacomo | 188 | btread(BT848_I2C); |
170 | giacomo | 189 | } |
190 | |||
191 | static int bttv_bit_getscl(void *data) |
||
192 | { |
||
193 | struct bttv *btv = (struct bttv*)data; |
||
194 | int state; |
||
195 | |||
196 | state = btread(BT848_I2C) & 0x02 ? 1 : 0; |
||
197 | return state; |
||
198 | } |
||
199 | |||
200 | static int bttv_bit_getsda(void *data) |
||
201 | { |
||
202 | struct bttv *btv = (struct bttv*)data; |
||
203 | int state; |
||
204 | |||
205 | state = btread(BT848_I2C) & 0x01; |
||
206 | return state; |
||
207 | } |
||
208 | |||
428 | giacomo | 209 | static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { |
210 | .setsda = bttv_bit_setsda, |
||
211 | .setscl = bttv_bit_setscl, |
||
212 | .getsda = bttv_bit_getsda, |
||
213 | .getscl = bttv_bit_getscl, |
||
214 | .udelay = 16, |
||
215 | .mdelay = 10, |
||
216 | .timeout = 200, |
||
217 | }; |
||
218 | |||
219 | static struct i2c_adapter bttv_i2c_adap_sw_template = { |
||
220 | #ifdef I2C_PEC |
||
221 | .owner = THIS_MODULE, |
||
222 | #else |
||
223 | .inc_use = bttv_inc_use, |
||
224 | .dec_use = bttv_dec_use, |
||
225 | #endif |
||
226 | #ifdef I2C_ADAP_CLASS_TV_ANALOG |
||
227 | .class = I2C_ADAP_CLASS_TV_ANALOG, |
||
228 | #endif |
||
229 | I2C_DEVNAME("bt848"), |
||
230 | .id = I2C_HW_B_BT848, |
||
231 | .client_register = attach_inform, |
||
232 | }; |
||
233 | |||
234 | /* ----------------------------------------------------------------------- */ |
||
235 | /* I2C functions - hardware i2c */ |
||
236 | |||
237 | static int algo_control(struct i2c_adapter *adapter, |
||
238 | unsigned int cmd, unsigned long arg) |
||
170 | giacomo | 239 | { |
428 | giacomo | 240 | return 0; |
170 | giacomo | 241 | } |
242 | |||
428 | giacomo | 243 | static u32 functionality(struct i2c_adapter *adap) |
170 | giacomo | 244 | { |
428 | giacomo | 245 | return I2C_FUNC_SMBUS_EMUL; |
170 | giacomo | 246 | } |
247 | |||
428 | giacomo | 248 | static int |
249 | bttv_i2c_wait_done(struct bttv *btv) |
||
170 | giacomo | 250 | { |
428 | giacomo | 251 | u32 stat; |
252 | unsigned long timeout; |
||
170 | giacomo | 253 | |
428 | giacomo | 254 | timeout = jiffies + HZ/100 + 1; /* 10ms */ |
255 | for (;;) { |
||
256 | stat = btread(BT848_INT_STAT); |
||
257 | if (stat & BT848_INT_I2CDONE) |
||
170 | giacomo | 258 | break; |
428 | giacomo | 259 | if (time_after(jiffies,timeout)) |
260 | return -EIO; |
||
261 | udelay(10); |
||
262 | } |
||
263 | btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT); |
||
264 | return ((stat & BT848_INT_RACK) ? 1 : 0); |
||
265 | } |
||
266 | |||
267 | #define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\ |
||
268 | BT848_I2C_SCL | BT848_I2C_SDA) |
||
269 | |||
270 | static int |
||
271 | bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last) |
||
272 | { |
||
273 | u32 xmit; |
||
274 | int retval,cnt; |
||
275 | |||
276 | /* start, address + first byte */ |
||
277 | xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW; |
||
278 | if (msg->len > 1 || !last) |
||
279 | xmit |= BT878_I2C_NOSTOP; |
||
280 | btwrite(xmit, BT848_I2C); |
||
281 | retval = bttv_i2c_wait_done(btv); |
||
282 | if (retval < 0) |
||
283 | goto err; |
||
284 | if (retval == 0) |
||
285 | goto eio; |
||
286 | if (i2c_debug) { |
||
287 | printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]); |
||
288 | if (!(xmit & BT878_I2C_NOSTOP)) |
||
289 | printk(" >\n"); |
||
290 | } |
||
291 | |||
292 | for (cnt = 1; cnt < msg->len; cnt++ ) { |
||
293 | /* following bytes */ |
||
294 | xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART; |
||
295 | if (cnt < msg->len-1 || !last) |
||
296 | xmit |= BT878_I2C_NOSTOP; |
||
297 | btwrite(xmit, BT848_I2C); |
||
298 | retval = bttv_i2c_wait_done(btv); |
||
299 | if (retval < 0) |
||
300 | goto err; |
||
301 | if (retval == 0) |
||
302 | goto eio; |
||
303 | if (i2c_debug) { |
||
304 | printk(" %02x", msg->buf[cnt]); |
||
305 | if (!(xmit & BT878_I2C_NOSTOP)) |
||
306 | printk(" >\n"); |
||
170 | giacomo | 307 | } |
308 | } |
||
428 | giacomo | 309 | return msg->len; |
310 | |||
311 | eio: |
||
312 | retval = -EIO; |
||
313 | err: |
||
314 | if (i2c_debug) |
||
315 | printk(" ERR: %d\n",retval); |
||
316 | return retval; |
||
170 | giacomo | 317 | } |
318 | |||
428 | giacomo | 319 | static int |
320 | bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last) |
||
170 | giacomo | 321 | { |
428 | giacomo | 322 | u32 xmit; |
323 | u32 cnt; |
||
324 | int retval; |
||
170 | giacomo | 325 | |
428 | giacomo | 326 | for(cnt = 0; cnt < msg->len; cnt++) { |
327 | xmit = (msg->addr << 25) | (1 << 24) | I2C_HW; |
||
328 | if (cnt < msg->len-1) |
||
329 | xmit |= BT848_I2C_W3B; |
||
330 | if (cnt < msg->len-1 || !last) |
||
331 | xmit |= BT878_I2C_NOSTOP; |
||
332 | if (cnt) |
||
333 | xmit |= BT878_I2C_NOSTART; |
||
334 | btwrite(xmit, BT848_I2C); |
||
335 | retval = bttv_i2c_wait_done(btv); |
||
336 | if (retval < 0) |
||
337 | goto err; |
||
338 | if (retval == 0) |
||
339 | goto eio; |
||
340 | msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff; |
||
341 | if (i2c_debug) { |
||
342 | if (!(xmit & BT878_I2C_NOSTART)) |
||
343 | printk(" <R %02x", (msg->addr << 1) +1); |
||
344 | printk(" =%02x", msg->buf[cnt]); |
||
345 | if (!(xmit & BT878_I2C_NOSTOP)) |
||
346 | printk(" >\n"); |
||
170 | giacomo | 347 | } |
348 | } |
||
428 | giacomo | 349 | return msg->len; |
350 | |||
351 | eio: |
||
352 | retval = -EIO; |
||
353 | err: |
||
354 | if (i2c_debug) |
||
355 | printk(" ERR: %d\n",retval); |
||
356 | return retval; |
||
170 | giacomo | 357 | } |
358 | |||
428 | giacomo | 359 | int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) |
170 | giacomo | 360 | { |
428 | giacomo | 361 | struct bttv *btv = i2c_get_adapdata(i2c_adap); |
362 | int retval = 0; |
||
170 | giacomo | 363 | int i; |
428 | giacomo | 364 | |
365 | if (i2c_debug) |
||
366 | printk("bt-i2c:"); |
||
367 | btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT); |
||
368 | for (i = 0 ; i < num; i++) { |
||
369 | if (msgs[i].flags & I2C_M_RD) { |
||
370 | /* read */ |
||
371 | retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num); |
||
372 | if (retval < 0) |
||
373 | goto err; |
||
374 | } else { |
||
375 | /* write */ |
||
376 | retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num); |
||
377 | if (retval < 0) |
||
378 | goto err; |
||
379 | } |
||
170 | giacomo | 380 | } |
428 | giacomo | 381 | return num; |
382 | |||
383 | err: |
||
384 | return retval; |
||
170 | giacomo | 385 | } |
386 | |||
428 | giacomo | 387 | static struct i2c_algorithm bttv_algo = { |
388 | .name = "bt878", |
||
389 | .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, |
||
390 | .master_xfer = bttv_i2c_xfer, |
||
391 | .algo_control = algo_control, |
||
392 | .functionality = functionality, |
||
170 | giacomo | 393 | }; |
394 | |||
428 | giacomo | 395 | static struct i2c_adapter bttv_i2c_adap_hw_template = { |
396 | #ifdef I2C_PEC |
||
397 | .owner = THIS_MODULE, |
||
398 | #else |
||
399 | .inc_use = bttv_inc_use, |
||
400 | .dec_use = bttv_dec_use, |
||
401 | #endif |
||
402 | #ifdef I2C_ADAP_CLASS_TV_ANALOG |
||
403 | .class = I2C_ADAP_CLASS_TV_ANALOG, |
||
404 | #endif |
||
405 | I2C_DEVNAME("bt878"), |
||
406 | .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, |
||
407 | .algo = &bttv_algo, |
||
408 | .client_register = attach_inform, |
||
170 | giacomo | 409 | }; |
410 | |||
428 | giacomo | 411 | /* ----------------------------------------------------------------------- */ |
412 | /* I2C functions - common stuff */ |
||
413 | |||
414 | #ifndef I2C_PEC |
||
415 | static void bttv_inc_use(struct i2c_adapter *adap) |
||
416 | { |
||
417 | MOD_INC_USE_COUNT; |
||
418 | } |
||
419 | |||
420 | static void bttv_dec_use(struct i2c_adapter *adap) |
||
421 | { |
||
422 | MOD_DEC_USE_COUNT; |
||
423 | } |
||
424 | #endif |
||
425 | |||
426 | static int attach_inform(struct i2c_client *client) |
||
427 | { |
||
428 | struct bttv *btv = i2c_get_adapdata(client->adapter); |
||
429 | |||
430 | if (btv->tuner_type != UNSET) |
||
431 | bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type); |
||
432 | if (btv->pinnacle_id != UNSET) |
||
433 | bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE, |
||
434 | &btv->pinnacle_id); |
||
435 | |||
436 | if (bttv_debug) |
||
437 | printk("bttv%d: i2c attach [client=%s]\n", |
||
438 | btv->nr, i2c_clientname(client)); |
||
439 | return 0; |
||
440 | } |
||
441 | |||
442 | void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) |
||
443 | { |
||
444 | if (0 != btv->i2c_rc) |
||
445 | return; |
||
446 | i2c_clients_command(&btv->i2c_adap, cmd, arg); |
||
447 | } |
||
448 | |||
449 | void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg) |
||
450 | { |
||
451 | if (card >= bttv_num) |
||
452 | return; |
||
453 | bttv_call_i2c_clients(&bttvs[card], cmd, arg); |
||
454 | } |
||
455 | |||
170 | giacomo | 456 | static struct i2c_client bttv_i2c_client_template = { |
428 | giacomo | 457 | I2C_DEVNAME("bttv internal"), |
458 | .id = -1, |
||
170 | giacomo | 459 | }; |
460 | |||
461 | |||
462 | /* read I2C */ |
||
463 | int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) |
||
464 | { |
||
465 | unsigned char buffer = 0; |
||
466 | |||
467 | if (0 != btv->i2c_rc) |
||
468 | return -1; |
||
469 | if (bttv_verbose && NULL != probe_for) |
||
428 | giacomo | 470 | printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ", |
170 | giacomo | 471 | btv->nr,probe_for,addr); |
472 | btv->i2c_client.addr = addr >> 1; |
||
473 | if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { |
||
474 | if (NULL != probe_for) { |
||
475 | if (bttv_verbose) |
||
476 | printk("not found\n"); |
||
477 | } else |
||
428 | giacomo | 478 | printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n", |
170 | giacomo | 479 | btv->nr,addr); |
480 | return -1; |
||
481 | } |
||
482 | if (bttv_verbose && NULL != probe_for) |
||
483 | printk("found\n"); |
||
484 | return buffer; |
||
485 | } |
||
486 | |||
487 | /* write I2C */ |
||
488 | int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, |
||
489 | unsigned char b2, int both) |
||
490 | { |
||
491 | unsigned char buffer[2]; |
||
492 | int bytes = both ? 2 : 1; |
||
493 | |||
494 | if (0 != btv->i2c_rc) |
||
495 | return -1; |
||
496 | btv->i2c_client.addr = addr >> 1; |
||
497 | buffer[0] = b1; |
||
498 | buffer[1] = b2; |
||
499 | if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) |
||
500 | return -1; |
||
501 | return 0; |
||
502 | } |
||
503 | |||
504 | /* read EEPROM content */ |
||
428 | giacomo | 505 | void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) |
170 | giacomo | 506 | { |
507 | int i; |
||
508 | |||
509 | if (bttv_I2CWrite(btv, addr, 0, -1, 0)<0) { |
||
428 | giacomo | 510 | printk(KERN_WARNING "bttv: readee error\n"); |
170 | giacomo | 511 | return; |
512 | } |
||
513 | btv->i2c_client.addr = addr >> 1; |
||
514 | for (i=0; i<256; i+=16) { |
||
515 | if (16 != i2c_master_recv(&btv->i2c_client,eedata+i,16)) { |
||
428 | giacomo | 516 | printk(KERN_WARNING "bttv: readee error\n"); |
170 | giacomo | 517 | break; |
518 | } |
||
519 | } |
||
520 | } |
||
521 | |||
522 | /* init + register i2c algo-bit adapter */ |
||
428 | giacomo | 523 | int __devinit init_bttv_i2c(struct bttv *btv) |
170 | giacomo | 524 | { |
428 | giacomo | 525 | int use_hw = (btv->id == 878) && i2c_hw; |
526 | |||
170 | giacomo | 527 | memcpy(&btv->i2c_client, &bttv_i2c_client_template, |
428 | giacomo | 528 | sizeof(bttv_i2c_client_template)); |
170 | giacomo | 529 | |
428 | giacomo | 530 | if (use_hw) { |
531 | /* bt878 */ |
||
532 | memcpy(&btv->i2c_adap, &bttv_i2c_adap_hw_template, |
||
533 | sizeof(bttv_i2c_adap_hw_template)); |
||
534 | } else { |
||
535 | /* bt848 */ |
||
536 | memcpy(&btv->i2c_adap, &bttv_i2c_adap_sw_template, |
||
537 | sizeof(bttv_i2c_adap_sw_template)); |
||
538 | memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template, |
||
539 | sizeof(bttv_i2c_algo_bit_template)); |
||
540 | btv->i2c_algo.data = btv; |
||
541 | btv->i2c_adap.algo_data = &btv->i2c_algo; |
||
542 | } |
||
543 | |||
544 | btv->i2c_adap.dev.parent = &btv->dev->dev; |
||
545 | snprintf(btv->i2c_adap.name, sizeof(btv->i2c_adap.name), |
||
546 | "bt%d #%d [%s]", btv->id, btv->nr, use_hw ? "hw" : "sw"); |
||
547 | |||
548 | i2c_set_adapdata(&btv->i2c_adap, btv); |
||
170 | giacomo | 549 | btv->i2c_client.adapter = &btv->i2c_adap; |
550 | |||
428 | giacomo | 551 | if (use_hw) { |
552 | btv->i2c_rc = i2c_add_adapter(&btv->i2c_adap); |
||
553 | } else { |
||
554 | bttv_bit_setscl(btv,1); |
||
555 | bttv_bit_setsda(btv,1); |
||
556 | btv->i2c_rc = i2c_bit_add_bus(&btv->i2c_adap); |
||
557 | } |
||
170 | giacomo | 558 | return btv->i2c_rc; |
559 | } |
||
560 | |||
428 | giacomo | 561 | int __devexit fini_bttv_i2c(struct bttv *btv) |
170 | giacomo | 562 | { |
428 | giacomo | 563 | int use_hw = (btv->id == 878) && i2c_hw; |
564 | |||
565 | if (0 != btv->i2c_rc) |
||
566 | return 0; |
||
567 | |||
568 | if (use_hw) { |
||
569 | return i2c_del_adapter(&btv->i2c_adap); |
||
570 | } else { |
||
571 | return i2c_bit_del_bus(&btv->i2c_adap); |
||
170 | giacomo | 572 | } |
573 | } |
||
574 | |||
575 | /* |
||
576 | * Local variables: |
||
577 | * c-basic-offset: 8 |
||
578 | * End: |
||
579 | */ |