diff options
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-i2c.c')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-i2c.c | 568 |
1 files changed, 568 insertions, 0 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c new file mode 100644 index 000000000000..1683bd9d51ee --- /dev/null +++ b/drivers/media/usb/em28xx/em28xx-i2c.c | |||
@@ -0,0 +1,568 @@ | |||
1 | /* | ||
2 | em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@infradead.org> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
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 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/usb.h> | ||
27 | #include <linux/i2c.h> | ||
28 | |||
29 | #include "em28xx.h" | ||
30 | #include "tuner-xc2028.h" | ||
31 | #include <media/v4l2-common.h> | ||
32 | #include <media/tuner.h> | ||
33 | |||
34 | /* ----------------------------------------------------------- */ | ||
35 | |||
36 | static unsigned int i2c_scan; | ||
37 | module_param(i2c_scan, int, 0444); | ||
38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | ||
39 | |||
40 | static unsigned int i2c_debug; | ||
41 | module_param(i2c_debug, int, 0644); | ||
42 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | ||
43 | |||
44 | #define dprintk2(lvl, fmt, args...) \ | ||
45 | do { \ | ||
46 | if (i2c_debug >= lvl) { \ | ||
47 | printk(KERN_DEBUG "%s at %s: " fmt, \ | ||
48 | dev->name, __func__ , ##args); \ | ||
49 | } \ | ||
50 | } while (0) | ||
51 | |||
52 | /* | ||
53 | * em2800_i2c_send_max4() | ||
54 | * send up to 4 bytes to the i2c device | ||
55 | */ | ||
56 | static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr, | ||
57 | char *buf, int len) | ||
58 | { | ||
59 | int ret; | ||
60 | int write_timeout; | ||
61 | unsigned char b2[6]; | ||
62 | BUG_ON(len < 1 || len > 4); | ||
63 | b2[5] = 0x80 + len - 1; | ||
64 | b2[4] = addr; | ||
65 | b2[3] = buf[0]; | ||
66 | if (len > 1) | ||
67 | b2[2] = buf[1]; | ||
68 | if (len > 2) | ||
69 | b2[1] = buf[2]; | ||
70 | if (len > 3) | ||
71 | b2[0] = buf[3]; | ||
72 | |||
73 | ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); | ||
74 | if (ret != 2 + len) { | ||
75 | em28xx_warn("writing to i2c device failed (error=%i)\n", ret); | ||
76 | return -EIO; | ||
77 | } | ||
78 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
79 | write_timeout -= 5) { | ||
80 | ret = dev->em28xx_read_reg(dev, 0x05); | ||
81 | if (ret == 0x80 + len - 1) | ||
82 | return len; | ||
83 | msleep(5); | ||
84 | } | ||
85 | em28xx_warn("i2c write timed out\n"); | ||
86 | return -EIO; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * em2800_i2c_send_bytes() | ||
91 | */ | ||
92 | static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf, | ||
93 | short len) | ||
94 | { | ||
95 | char *bufPtr = buf; | ||
96 | int ret; | ||
97 | int wrcount = 0; | ||
98 | int count; | ||
99 | int maxLen = 4; | ||
100 | struct em28xx *dev = (struct em28xx *)data; | ||
101 | while (len > 0) { | ||
102 | count = (len > maxLen) ? maxLen : len; | ||
103 | ret = em2800_i2c_send_max4(dev, addr, bufPtr, count); | ||
104 | if (ret > 0) { | ||
105 | len -= count; | ||
106 | bufPtr += count; | ||
107 | wrcount += count; | ||
108 | } else | ||
109 | return (ret < 0) ? ret : -EFAULT; | ||
110 | } | ||
111 | return wrcount; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * em2800_i2c_check_for_device() | ||
116 | * check if there is a i2c_device at the supplied address | ||
117 | */ | ||
118 | static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr) | ||
119 | { | ||
120 | char msg; | ||
121 | int ret; | ||
122 | int write_timeout; | ||
123 | msg = addr; | ||
124 | ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1); | ||
125 | if (ret < 0) { | ||
126 | em28xx_warn("setting i2c device address failed (error=%i)\n", | ||
127 | ret); | ||
128 | return ret; | ||
129 | } | ||
130 | msg = 0x84; | ||
131 | ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1); | ||
132 | if (ret < 0) { | ||
133 | em28xx_warn("preparing i2c read failed (error=%i)\n", ret); | ||
134 | return ret; | ||
135 | } | ||
136 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
137 | write_timeout -= 5) { | ||
138 | unsigned reg = dev->em28xx_read_reg(dev, 0x5); | ||
139 | |||
140 | if (reg == 0x94) | ||
141 | return -ENODEV; | ||
142 | else if (reg == 0x84) | ||
143 | return 0; | ||
144 | msleep(5); | ||
145 | } | ||
146 | return -ENODEV; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * em2800_i2c_recv_bytes() | ||
151 | * read from the i2c device | ||
152 | */ | ||
153 | static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr, | ||
154 | char *buf, int len) | ||
155 | { | ||
156 | int ret; | ||
157 | /* check for the device and set i2c read address */ | ||
158 | ret = em2800_i2c_check_for_device(dev, addr); | ||
159 | if (ret) { | ||
160 | em28xx_warn | ||
161 | ("preparing read at i2c address 0x%x failed (error=%i)\n", | ||
162 | addr, ret); | ||
163 | return ret; | ||
164 | } | ||
165 | ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len); | ||
166 | if (ret < 0) { | ||
167 | em28xx_warn("reading from i2c device at 0x%x failed (error=%i)", | ||
168 | addr, ret); | ||
169 | return ret; | ||
170 | } | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * em28xx_i2c_send_bytes() | ||
176 | */ | ||
177 | static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf, | ||
178 | short len, int stop) | ||
179 | { | ||
180 | int wrcount = 0; | ||
181 | struct em28xx *dev = (struct em28xx *)data; | ||
182 | int write_timeout, ret; | ||
183 | |||
184 | wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); | ||
185 | |||
186 | /* Seems to be required after a write */ | ||
187 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
188 | write_timeout -= 5) { | ||
189 | ret = dev->em28xx_read_reg(dev, 0x05); | ||
190 | if (!ret) | ||
191 | break; | ||
192 | msleep(5); | ||
193 | } | ||
194 | |||
195 | return wrcount; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * em28xx_i2c_recv_bytes() | ||
200 | * read a byte from the i2c device | ||
201 | */ | ||
202 | static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr, | ||
203 | char *buf, int len) | ||
204 | { | ||
205 | int ret; | ||
206 | ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); | ||
207 | if (ret < 0) { | ||
208 | em28xx_warn("reading i2c device failed (error=%i)\n", ret); | ||
209 | return ret; | ||
210 | } | ||
211 | if (dev->em28xx_read_reg(dev, 0x5) != 0) | ||
212 | return -ENODEV; | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * em28xx_i2c_check_for_device() | ||
218 | * check if there is a i2c_device at the supplied address | ||
219 | */ | ||
220 | static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr) | ||
221 | { | ||
222 | int ret; | ||
223 | |||
224 | ret = dev->em28xx_read_reg_req(dev, 2, addr); | ||
225 | if (ret < 0) { | ||
226 | em28xx_warn("reading from i2c device failed (error=%i)\n", ret); | ||
227 | return ret; | ||
228 | } | ||
229 | if (dev->em28xx_read_reg(dev, 0x5) != 0) | ||
230 | return -ENODEV; | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * em28xx_i2c_xfer() | ||
236 | * the main i2c transfer function | ||
237 | */ | ||
238 | static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
239 | struct i2c_msg msgs[], int num) | ||
240 | { | ||
241 | struct em28xx *dev = i2c_adap->algo_data; | ||
242 | int addr, rc, i, byte; | ||
243 | |||
244 | if (num <= 0) | ||
245 | return 0; | ||
246 | for (i = 0; i < num; i++) { | ||
247 | addr = msgs[i].addr << 1; | ||
248 | dprintk2(2, "%s %s addr=%x len=%d:", | ||
249 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | ||
250 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); | ||
251 | if (!msgs[i].len) { /* no len: check only for device presence */ | ||
252 | if (dev->board.is_em2800) | ||
253 | rc = em2800_i2c_check_for_device(dev, addr); | ||
254 | else | ||
255 | rc = em28xx_i2c_check_for_device(dev, addr); | ||
256 | if (rc < 0) { | ||
257 | dprintk2(2, " no device\n"); | ||
258 | return rc; | ||
259 | } | ||
260 | |||
261 | } else if (msgs[i].flags & I2C_M_RD) { | ||
262 | /* read bytes */ | ||
263 | if (dev->board.is_em2800) | ||
264 | rc = em2800_i2c_recv_bytes(dev, addr, | ||
265 | msgs[i].buf, | ||
266 | msgs[i].len); | ||
267 | else | ||
268 | rc = em28xx_i2c_recv_bytes(dev, addr, | ||
269 | msgs[i].buf, | ||
270 | msgs[i].len); | ||
271 | if (i2c_debug >= 2) { | ||
272 | for (byte = 0; byte < msgs[i].len; byte++) | ||
273 | printk(" %02x", msgs[i].buf[byte]); | ||
274 | } | ||
275 | } else { | ||
276 | /* write bytes */ | ||
277 | if (i2c_debug >= 2) { | ||
278 | for (byte = 0; byte < msgs[i].len; byte++) | ||
279 | printk(" %02x", msgs[i].buf[byte]); | ||
280 | } | ||
281 | if (dev->board.is_em2800) | ||
282 | rc = em2800_i2c_send_bytes(dev, addr, | ||
283 | msgs[i].buf, | ||
284 | msgs[i].len); | ||
285 | else | ||
286 | rc = em28xx_i2c_send_bytes(dev, addr, | ||
287 | msgs[i].buf, | ||
288 | msgs[i].len, | ||
289 | i == num - 1); | ||
290 | } | ||
291 | if (rc < 0) | ||
292 | goto err; | ||
293 | if (i2c_debug >= 2) | ||
294 | printk("\n"); | ||
295 | } | ||
296 | |||
297 | return num; | ||
298 | err: | ||
299 | dprintk2(2, " ERROR: %i\n", rc); | ||
300 | return rc; | ||
301 | } | ||
302 | |||
303 | /* based on linux/sunrpc/svcauth.h and linux/hash.h | ||
304 | * The original hash function returns a different value, if arch is x86_64 | ||
305 | * or i386. | ||
306 | */ | ||
307 | static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) | ||
308 | { | ||
309 | unsigned long hash = 0; | ||
310 | unsigned long l = 0; | ||
311 | int len = 0; | ||
312 | unsigned char c; | ||
313 | do { | ||
314 | if (len == length) { | ||
315 | c = (char)len; | ||
316 | len = -1; | ||
317 | } else | ||
318 | c = *buf++; | ||
319 | l = (l << 8) | c; | ||
320 | len++; | ||
321 | if ((len & (32 / 8 - 1)) == 0) | ||
322 | hash = ((hash^l) * 0x9e370001UL); | ||
323 | } while (len); | ||
324 | |||
325 | return (hash >> (32 - bits)) & 0xffffffffUL; | ||
326 | } | ||
327 | |||
328 | static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) | ||
329 | { | ||
330 | unsigned char buf, *p = eedata; | ||
331 | struct em28xx_eeprom *em_eeprom = (void *)eedata; | ||
332 | int i, err, size = len, block; | ||
333 | |||
334 | if (dev->chip_id == CHIP_ID_EM2874 || | ||
335 | dev->chip_id == CHIP_ID_EM28174 || | ||
336 | dev->chip_id == CHIP_ID_EM2884) { | ||
337 | /* Empia switched to a 16-bit addressable eeprom in newer | ||
338 | devices. While we could certainly write a routine to read | ||
339 | the eeprom, there is nothing of use in there that cannot be | ||
340 | accessed through registers, and there is the risk that we | ||
341 | could corrupt the eeprom (since a 16-bit read call is | ||
342 | interpreted as a write call by 8-bit eeproms). | ||
343 | */ | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | dev->i2c_client.addr = 0xa0 >> 1; | ||
348 | |||
349 | /* Check if board has eeprom */ | ||
350 | err = i2c_master_recv(&dev->i2c_client, &buf, 0); | ||
351 | if (err < 0) { | ||
352 | em28xx_errdev("board has no eeprom\n"); | ||
353 | memset(eedata, 0, len); | ||
354 | return -ENODEV; | ||
355 | } | ||
356 | |||
357 | buf = 0; | ||
358 | |||
359 | err = i2c_master_send(&dev->i2c_client, &buf, 1); | ||
360 | if (err != 1) { | ||
361 | printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", | ||
362 | dev->name, err); | ||
363 | return err; | ||
364 | } | ||
365 | while (size > 0) { | ||
366 | if (size > 16) | ||
367 | block = 16; | ||
368 | else | ||
369 | block = size; | ||
370 | |||
371 | if (block != | ||
372 | (err = i2c_master_recv(&dev->i2c_client, p, block))) { | ||
373 | printk(KERN_WARNING | ||
374 | "%s: i2c eeprom read error (err=%d)\n", | ||
375 | dev->name, err); | ||
376 | return err; | ||
377 | } | ||
378 | size -= block; | ||
379 | p += block; | ||
380 | } | ||
381 | for (i = 0; i < len; i++) { | ||
382 | if (0 == (i % 16)) | ||
383 | printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i); | ||
384 | printk(" %02x", eedata[i]); | ||
385 | if (15 == (i % 16)) | ||
386 | printk("\n"); | ||
387 | } | ||
388 | |||
389 | if (em_eeprom->id == 0x9567eb1a) | ||
390 | dev->hash = em28xx_hash_mem(eedata, len, 32); | ||
391 | |||
392 | printk(KERN_INFO "%s: EEPROM ID= 0x%08x, EEPROM hash = 0x%08lx\n", | ||
393 | dev->name, em_eeprom->id, dev->hash); | ||
394 | |||
395 | printk(KERN_INFO "%s: EEPROM info:\n", dev->name); | ||
396 | |||
397 | switch (em_eeprom->chip_conf >> 4 & 0x3) { | ||
398 | case 0: | ||
399 | printk(KERN_INFO "%s:\tNo audio on board.\n", dev->name); | ||
400 | break; | ||
401 | case 1: | ||
402 | printk(KERN_INFO "%s:\tAC97 audio (5 sample rates)\n", | ||
403 | dev->name); | ||
404 | break; | ||
405 | case 2: | ||
406 | printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", | ||
407 | dev->name); | ||
408 | break; | ||
409 | case 3: | ||
410 | printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", | ||
411 | dev->name); | ||
412 | break; | ||
413 | } | ||
414 | |||
415 | if (em_eeprom->chip_conf & 1 << 3) | ||
416 | printk(KERN_INFO "%s:\tUSB Remote wakeup capable\n", dev->name); | ||
417 | |||
418 | if (em_eeprom->chip_conf & 1 << 2) | ||
419 | printk(KERN_INFO "%s:\tUSB Self power capable\n", dev->name); | ||
420 | |||
421 | switch (em_eeprom->chip_conf & 0x3) { | ||
422 | case 0: | ||
423 | printk(KERN_INFO "%s:\t500mA max power\n", dev->name); | ||
424 | break; | ||
425 | case 1: | ||
426 | printk(KERN_INFO "%s:\t400mA max power\n", dev->name); | ||
427 | break; | ||
428 | case 2: | ||
429 | printk(KERN_INFO "%s:\t300mA max power\n", dev->name); | ||
430 | break; | ||
431 | case 3: | ||
432 | printk(KERN_INFO "%s:\t200mA max power\n", dev->name); | ||
433 | break; | ||
434 | } | ||
435 | printk(KERN_INFO "%s:\tTable at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", | ||
436 | dev->name, | ||
437 | em_eeprom->string_idx_table, | ||
438 | em_eeprom->string1, | ||
439 | em_eeprom->string2, | ||
440 | em_eeprom->string3); | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /* ----------------------------------------------------------- */ | ||
446 | |||
447 | /* | ||
448 | * functionality() | ||
449 | */ | ||
450 | static u32 functionality(struct i2c_adapter *adap) | ||
451 | { | ||
452 | return I2C_FUNC_SMBUS_EMUL; | ||
453 | } | ||
454 | |||
455 | static struct i2c_algorithm em28xx_algo = { | ||
456 | .master_xfer = em28xx_i2c_xfer, | ||
457 | .functionality = functionality, | ||
458 | }; | ||
459 | |||
460 | static struct i2c_adapter em28xx_adap_template = { | ||
461 | .owner = THIS_MODULE, | ||
462 | .name = "em28xx", | ||
463 | .algo = &em28xx_algo, | ||
464 | }; | ||
465 | |||
466 | static struct i2c_client em28xx_client_template = { | ||
467 | .name = "em28xx internal", | ||
468 | }; | ||
469 | |||
470 | /* ----------------------------------------------------------- */ | ||
471 | |||
472 | /* | ||
473 | * i2c_devs | ||
474 | * incomplete list of known devices | ||
475 | */ | ||
476 | static char *i2c_devs[128] = { | ||
477 | [0x4a >> 1] = "saa7113h", | ||
478 | [0x52 >> 1] = "drxk", | ||
479 | [0x60 >> 1] = "remote IR sensor", | ||
480 | [0x8e >> 1] = "remote IR sensor", | ||
481 | [0x86 >> 1] = "tda9887", | ||
482 | [0x80 >> 1] = "msp34xx", | ||
483 | [0x88 >> 1] = "msp34xx", | ||
484 | [0xa0 >> 1] = "eeprom", | ||
485 | [0xb0 >> 1] = "tda9874", | ||
486 | [0xb8 >> 1] = "tvp5150a", | ||
487 | [0xba >> 1] = "webcam sensor or tvp5150a", | ||
488 | [0xc0 >> 1] = "tuner (analog)", | ||
489 | [0xc2 >> 1] = "tuner (analog)", | ||
490 | [0xc4 >> 1] = "tuner (analog)", | ||
491 | [0xc6 >> 1] = "tuner (analog)", | ||
492 | }; | ||
493 | |||
494 | /* | ||
495 | * do_i2c_scan() | ||
496 | * check i2c address range for devices | ||
497 | */ | ||
498 | void em28xx_do_i2c_scan(struct em28xx *dev) | ||
499 | { | ||
500 | u8 i2c_devicelist[128]; | ||
501 | unsigned char buf; | ||
502 | int i, rc; | ||
503 | |||
504 | memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist)); | ||
505 | |||
506 | for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { | ||
507 | dev->i2c_client.addr = i; | ||
508 | rc = i2c_master_recv(&dev->i2c_client, &buf, 0); | ||
509 | if (rc < 0) | ||
510 | continue; | ||
511 | i2c_devicelist[i] = i; | ||
512 | printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", | ||
513 | dev->name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); | ||
514 | } | ||
515 | |||
516 | dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, | ||
517 | ARRAY_SIZE(i2c_devicelist), 32); | ||
518 | } | ||
519 | |||
520 | /* | ||
521 | * em28xx_i2c_register() | ||
522 | * register i2c bus | ||
523 | */ | ||
524 | int em28xx_i2c_register(struct em28xx *dev) | ||
525 | { | ||
526 | int retval; | ||
527 | |||
528 | BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); | ||
529 | BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); | ||
530 | dev->i2c_adap = em28xx_adap_template; | ||
531 | dev->i2c_adap.dev.parent = &dev->udev->dev; | ||
532 | strcpy(dev->i2c_adap.name, dev->name); | ||
533 | dev->i2c_adap.algo_data = dev; | ||
534 | i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev); | ||
535 | |||
536 | retval = i2c_add_adapter(&dev->i2c_adap); | ||
537 | if (retval < 0) { | ||
538 | em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", | ||
539 | __func__, retval); | ||
540 | return retval; | ||
541 | } | ||
542 | |||
543 | dev->i2c_client = em28xx_client_template; | ||
544 | dev->i2c_client.adapter = &dev->i2c_adap; | ||
545 | |||
546 | retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); | ||
547 | if ((retval < 0) && (retval != -ENODEV)) { | ||
548 | em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", | ||
549 | __func__, retval); | ||
550 | |||
551 | return retval; | ||
552 | } | ||
553 | |||
554 | if (i2c_scan) | ||
555 | em28xx_do_i2c_scan(dev); | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * em28xx_i2c_unregister() | ||
562 | * unregister i2c_bus | ||
563 | */ | ||
564 | int em28xx_i2c_unregister(struct em28xx *dev) | ||
565 | { | ||
566 | i2c_del_adapter(&dev->i2c_adap); | ||
567 | return 0; | ||
568 | } | ||