Commit | Line | Data |
---|---|---|
a6c2ba28 | 1 | /* |
f7abcd38 | 2 | em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices |
a6c2ba28 | 3 | |
f7abcd38 MCC |
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
5 | Markus Rechberger <mrechberger@gmail.com> | |
2e7c6dc3 | 6 | Mauro Carvalho Chehab <mchehab@infradead.org> |
f7abcd38 | 7 | Sascha Sommer <saschasommer@freenet.de> |
a6c2ba28 AM |
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> | |
a6c2ba28 | 28 | |
f7abcd38 | 29 | #include "em28xx.h" |
6c362c8e | 30 | #include "tuner-xc2028.h" |
5e453dc7 | 31 | #include <media/v4l2-common.h> |
d5e52653 | 32 | #include <media/tuner.h> |
a6c2ba28 AM |
33 | |
34 | /* ----------------------------------------------------------- */ | |
35 | ||
ff699e6b | 36 | static unsigned int i2c_scan; |
a6c2ba28 AM |
37 | module_param(i2c_scan, int, 0444); |
38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | |
39 | ||
ff699e6b | 40 | static unsigned int i2c_debug; |
a6c2ba28 AM |
41 | module_param(i2c_debug, int, 0644); |
42 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | |
43 | ||
a6c2ba28 | 44 | /* |
f5ae371a FS |
45 | * em2800_i2c_send_bytes() |
46 | * send up to 4 bytes to the em2800 i2c device | |
596d92d5 | 47 | */ |
f5ae371a | 48 | static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) |
596d92d5 MCC |
49 | { |
50 | int ret; | |
51 | int write_timeout; | |
a6bad040 | 52 | u8 b2[6]; |
f5ae371a FS |
53 | |
54 | if (len < 1 || len > 4) | |
55 | return -EOPNOTSUPP; | |
56 | ||
596d92d5 MCC |
57 | BUG_ON(len < 1 || len > 4); |
58 | b2[5] = 0x80 + len - 1; | |
59 | b2[4] = addr; | |
60 | b2[3] = buf[0]; | |
61 | if (len > 1) | |
62 | b2[2] = buf[1]; | |
63 | if (len > 2) | |
64 | b2[1] = buf[2]; | |
65 | if (len > 3) | |
66 | b2[0] = buf[3]; | |
67 | ||
2fcc82d8 | 68 | /* trigger write */ |
3acf2809 | 69 | ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); |
596d92d5 | 70 | if (ret != 2 + len) { |
45f04e82 FS |
71 | em28xx_warn("failed to trigger write to i2c address 0x%x " |
72 | "(error=%i)\n", addr, ret); | |
73 | return (ret < 0) ? ret : -EIO; | |
596d92d5 | 74 | } |
2fcc82d8 FS |
75 | /* wait for completion */ |
76 | for (write_timeout = EM2800_I2C_XFER_TIMEOUT; write_timeout > 0; | |
596d92d5 | 77 | write_timeout -= 5) { |
3acf2809 | 78 | ret = dev->em28xx_read_reg(dev, 0x05); |
45f04e82 | 79 | if (ret == 0x80 + len - 1) { |
596d92d5 | 80 | return len; |
45f04e82 FS |
81 | } else if (ret == 0x94 + len - 1) { |
82 | return -ENODEV; | |
83 | } else if (ret < 0) { | |
84 | em28xx_warn("failed to get i2c transfer status from " | |
85 | "bridge register (error=%i)\n", ret); | |
86 | return ret; | |
87 | } | |
e8e41da4 | 88 | msleep(5); |
596d92d5 | 89 | } |
45f04e82 | 90 | em28xx_warn("write to i2c device at 0x%x timed out\n", addr); |
596d92d5 MCC |
91 | return -EIO; |
92 | } | |
93 | ||
596d92d5 | 94 | /* |
2fcc82d8 FS |
95 | * em2800_i2c_recv_bytes() |
96 | * read up to 4 bytes from the em2800 i2c device | |
596d92d5 | 97 | */ |
2fcc82d8 | 98 | static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) |
596d92d5 | 99 | { |
2fcc82d8 | 100 | u8 buf2[4]; |
596d92d5 | 101 | int ret; |
2fcc82d8 FS |
102 | int read_timeout; |
103 | int i; | |
104 | ||
105 | if (len < 1 || len > 4) | |
106 | return -EOPNOTSUPP; | |
107 | ||
108 | /* trigger read */ | |
109 | buf2[1] = 0x84 + len - 1; | |
110 | buf2[0] = addr; | |
111 | ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2); | |
112 | if (ret != 2) { | |
113 | em28xx_warn("failed to trigger read from i2c address 0x%x " | |
114 | "(error=%i)\n", addr, ret); | |
115 | return (ret < 0) ? ret : -EIO; | |
596d92d5 | 116 | } |
d45b9b8a | 117 | |
2fcc82d8 FS |
118 | /* wait for completion */ |
119 | for (read_timeout = EM2800_I2C_XFER_TIMEOUT; read_timeout > 0; | |
120 | read_timeout -= 5) { | |
121 | ret = dev->em28xx_read_reg(dev, 0x05); | |
122 | if (ret == 0x84 + len - 1) { | |
123 | break; | |
124 | } else if (ret == 0x94 + len - 1) { | |
596d92d5 | 125 | return -ENODEV; |
2fcc82d8 FS |
126 | } else if (ret < 0) { |
127 | em28xx_warn("failed to get i2c transfer status from " | |
128 | "bridge register (error=%i)\n", ret); | |
129 | return ret; | |
130 | } | |
e8e41da4 | 131 | msleep(5); |
596d92d5 | 132 | } |
2fcc82d8 FS |
133 | if (ret != 0x84 + len - 1) |
134 | em28xx_warn("read from i2c device at 0x%x timed out\n", addr); | |
135 | ||
136 | /* get the received message */ | |
137 | ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); | |
138 | if (ret != len) { | |
139 | em28xx_warn("reading from i2c device at 0x%x failed: " | |
140 | "couldn't get the received message from the bridge " | |
141 | "(error=%i)\n", addr, ret); | |
142 | return (ret < 0) ? ret : -EIO; | |
143 | } | |
144 | for (i = 0; i < len; i++) | |
145 | buf[i] = buf2[len - 1 - i]; | |
146 | ||
147 | return ret; | |
596d92d5 MCC |
148 | } |
149 | ||
150 | /* | |
2fcc82d8 FS |
151 | * em2800_i2c_check_for_device() |
152 | * check if there is an i2c device at the supplied address | |
596d92d5 | 153 | */ |
2fcc82d8 | 154 | static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr) |
596d92d5 | 155 | { |
2fcc82d8 | 156 | u8 buf; |
596d92d5 | 157 | int ret; |
f5ae371a | 158 | |
2fcc82d8 FS |
159 | ret = em2800_i2c_recv_bytes(dev, addr, &buf, 1); |
160 | if (ret == 1) | |
161 | return 0; | |
162 | return (ret < 0) ? ret : -EIO; | |
596d92d5 MCC |
163 | } |
164 | ||
165 | /* | |
3acf2809 | 166 | * em28xx_i2c_send_bytes() |
a6c2ba28 | 167 | */ |
a6bad040 FS |
168 | static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, |
169 | u16 len, int stop) | |
a6c2ba28 | 170 | { |
bbc70e64 | 171 | int write_timeout, ret; |
a6c2ba28 | 172 | |
f5ae371a FS |
173 | if (len < 1 || len > 64) |
174 | return -EOPNOTSUPP; | |
45f04e82 FS |
175 | /* NOTE: limited by the USB ctrl message constraints |
176 | * Zero length reads always succeed, even if no device is connected */ | |
f5ae371a | 177 | |
45f04e82 FS |
178 | /* Write to i2c device */ |
179 | ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); | |
180 | if (ret != len) { | |
181 | if (ret < 0) { | |
182 | em28xx_warn("writing to i2c device at 0x%x failed " | |
183 | "(error=%i)\n", addr, ret); | |
184 | return ret; | |
185 | } else { | |
186 | em28xx_warn("%i bytes write to i2c device at 0x%x " | |
187 | "requested, but %i bytes written\n", | |
188 | len, addr, ret); | |
189 | return -EIO; | |
190 | } | |
191 | } | |
a6c2ba28 | 192 | |
45f04e82 | 193 | /* Check success of the i2c operation */ |
2fcc82d8 | 194 | for (write_timeout = EM2800_I2C_XFER_TIMEOUT; write_timeout > 0; |
bbc70e64 MCC |
195 | write_timeout -= 5) { |
196 | ret = dev->em28xx_read_reg(dev, 0x05); | |
45f04e82 FS |
197 | if (ret == 0) { /* success */ |
198 | return len; | |
199 | } else if (ret == 0x10) { | |
200 | return -ENODEV; | |
201 | } else if (ret < 0) { | |
202 | em28xx_warn("failed to read i2c transfer status from " | |
203 | "bridge (error=%i)\n", ret); | |
204 | return ret; | |
205 | } | |
bbc70e64 | 206 | msleep(5); |
45f04e82 FS |
207 | /* NOTE: do we really have to wait for success ? |
208 | Never seen anything else than 0x00 or 0x10 | |
209 | (even with high payload) ... */ | |
bbc70e64 | 210 | } |
45f04e82 FS |
211 | em28xx_warn("write to i2c device at 0x%x timed out\n", addr); |
212 | return -EIO; | |
a6c2ba28 AM |
213 | } |
214 | ||
215 | /* | |
3acf2809 | 216 | * em28xx_i2c_recv_bytes() |
a6c2ba28 AM |
217 | * read a byte from the i2c device |
218 | */ | |
a6bad040 | 219 | static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) |
a6c2ba28 AM |
220 | { |
221 | int ret; | |
f5ae371a FS |
222 | |
223 | if (len < 1 || len > 64) | |
224 | return -EOPNOTSUPP; | |
45f04e82 FS |
225 | /* NOTE: limited by the USB ctrl message constraints |
226 | * Zero length reads always succeed, even if no device is connected */ | |
f5ae371a | 227 | |
45f04e82 | 228 | /* Read data from i2c device */ |
3acf2809 | 229 | ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); |
45f04e82 FS |
230 | if (ret != len) { |
231 | if (ret < 0) { | |
232 | em28xx_warn("reading from i2c device at 0x%x failed " | |
233 | "(error=%i)\n", addr, ret); | |
234 | return ret; | |
235 | } else { | |
236 | em28xx_warn("%i bytes requested from i2c device at " | |
237 | "0x%x, but %i bytes received\n", | |
238 | len, addr, ret); | |
239 | return -EIO; | |
240 | } | |
241 | } | |
242 | ||
243 | /* Check success of the i2c operation */ | |
244 | ret = dev->em28xx_read_reg(dev, 0x05); | |
a6c2ba28 | 245 | if (ret < 0) { |
45f04e82 FS |
246 | em28xx_warn("failed to read i2c transfer status from " |
247 | "bridge (error=%i)\n", ret); | |
a6c2ba28 AM |
248 | return ret; |
249 | } | |
45f04e82 FS |
250 | if (ret > 0) { |
251 | if (ret == 0x10) { | |
252 | return -ENODEV; | |
253 | } else { | |
254 | em28xx_warn("unknown i2c error (status=%i)\n", ret); | |
255 | return -EIO; | |
256 | } | |
257 | } | |
258 | return len; | |
a6c2ba28 AM |
259 | } |
260 | ||
261 | /* | |
3acf2809 | 262 | * em28xx_i2c_check_for_device() |
a6c2ba28 AM |
263 | * check if there is a i2c_device at the supplied address |
264 | */ | |
a6bad040 | 265 | static int em28xx_i2c_check_for_device(struct em28xx *dev, u16 addr) |
a6c2ba28 | 266 | { |
a6c2ba28 | 267 | int ret; |
45f04e82 | 268 | u8 buf; |
a6c2ba28 | 269 | |
45f04e82 FS |
270 | ret = em28xx_i2c_recv_bytes(dev, addr, &buf, 1); |
271 | if (ret == 1) | |
272 | return 0; | |
273 | return (ret < 0) ? ret : -EIO; | |
a6c2ba28 AM |
274 | } |
275 | ||
276 | /* | |
3acf2809 | 277 | * em28xx_i2c_xfer() |
a6c2ba28 AM |
278 | * the main i2c transfer function |
279 | */ | |
3acf2809 | 280 | static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, |
a6c2ba28 AM |
281 | struct i2c_msg msgs[], int num) |
282 | { | |
aab3125c MCC |
283 | struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; |
284 | struct em28xx *dev = i2c_bus->dev; | |
285 | unsigned bus = i2c_bus->bus; | |
a6c2ba28 AM |
286 | int addr, rc, i, byte; |
287 | ||
aab3125c MCC |
288 | rc = rt_mutex_trylock(&dev->i2c_bus_lock); |
289 | if (rc < 0) | |
290 | return rc; | |
291 | ||
292 | /* Switch I2C bus if needed */ | |
293 | if (bus != dev->cur_i2c_bus) { | |
294 | if (bus == 1) | |
295 | dev->cur_i2c_bus |= EM2874_I2C_SECONDARY_BUS_SELECT; | |
296 | else | |
297 | dev->cur_i2c_bus &= ~EM2874_I2C_SECONDARY_BUS_SELECT; | |
298 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->cur_i2c_bus); | |
299 | dev->cur_i2c_bus = bus; | |
300 | } | |
301 | ||
302 | if (num <= 0) { | |
303 | rt_mutex_unlock(&dev->i2c_bus_lock); | |
a6c2ba28 | 304 | return 0; |
aab3125c | 305 | } |
a6c2ba28 AM |
306 | for (i = 0; i < num; i++) { |
307 | addr = msgs[i].addr << 1; | |
d90f0677 | 308 | if (i2c_debug) |
d7a80eaa FS |
309 | printk(KERN_DEBUG "%s at %s: %s %s addr=%02x len=%d:", |
310 | dev->name, __func__ , | |
311 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | |
312 | i == num - 1 ? "stop" : "nonstop", | |
313 | addr, msgs[i].len); | |
6ea54d93 | 314 | if (!msgs[i].len) { /* no len: check only for device presence */ |
505b6d0b | 315 | if (dev->board.is_em2800) |
596d92d5 MCC |
316 | rc = em2800_i2c_check_for_device(dev, addr); |
317 | else | |
3acf2809 | 318 | rc = em28xx_i2c_check_for_device(dev, addr); |
45f04e82 | 319 | if (rc == -ENODEV) { |
d90f0677 | 320 | if (i2c_debug) |
45f04e82 | 321 | printk(" no device\n"); |
aab3125c | 322 | rt_mutex_unlock(&dev->i2c_bus_lock); |
a6c2ba28 AM |
323 | return rc; |
324 | } | |
596d92d5 | 325 | } else if (msgs[i].flags & I2C_M_RD) { |
a6c2ba28 | 326 | /* read bytes */ |
505b6d0b | 327 | if (dev->board.is_em2800) |
596d92d5 MCC |
328 | rc = em2800_i2c_recv_bytes(dev, addr, |
329 | msgs[i].buf, | |
330 | msgs[i].len); | |
331 | else | |
3acf2809 | 332 | rc = em28xx_i2c_recv_bytes(dev, addr, |
596d92d5 MCC |
333 | msgs[i].buf, |
334 | msgs[i].len); | |
d90f0677 | 335 | if (i2c_debug) { |
6ea54d93 | 336 | for (byte = 0; byte < msgs[i].len; byte++) |
a6c2ba28 | 337 | printk(" %02x", msgs[i].buf[byte]); |
a6c2ba28 AM |
338 | } |
339 | } else { | |
340 | /* write bytes */ | |
d90f0677 | 341 | if (i2c_debug) { |
a6c2ba28 AM |
342 | for (byte = 0; byte < msgs[i].len; byte++) |
343 | printk(" %02x", msgs[i].buf[byte]); | |
344 | } | |
505b6d0b | 345 | if (dev->board.is_em2800) |
596d92d5 MCC |
346 | rc = em2800_i2c_send_bytes(dev, addr, |
347 | msgs[i].buf, | |
348 | msgs[i].len); | |
349 | else | |
3acf2809 | 350 | rc = em28xx_i2c_send_bytes(dev, addr, |
596d92d5 MCC |
351 | msgs[i].buf, |
352 | msgs[i].len, | |
353 | i == num - 1); | |
a6c2ba28 | 354 | } |
45f04e82 | 355 | if (rc < 0) { |
d90f0677 | 356 | if (i2c_debug) |
45f04e82 | 357 | printk(" ERROR: %i\n", rc); |
aab3125c | 358 | rt_mutex_unlock(&dev->i2c_bus_lock); |
45f04e82 FS |
359 | return rc; |
360 | } | |
d90f0677 | 361 | if (i2c_debug) |
a6c2ba28 AM |
362 | printk("\n"); |
363 | } | |
364 | ||
aab3125c | 365 | rt_mutex_unlock(&dev->i2c_bus_lock); |
a6c2ba28 | 366 | return num; |
a6c2ba28 AM |
367 | } |
368 | ||
03910cc3 MCC |
369 | /* based on linux/sunrpc/svcauth.h and linux/hash.h |
370 | * The original hash function returns a different value, if arch is x86_64 | |
371 | * or i386. | |
372 | */ | |
373 | static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) | |
374 | { | |
375 | unsigned long hash = 0; | |
376 | unsigned long l = 0; | |
377 | int len = 0; | |
378 | unsigned char c; | |
379 | do { | |
380 | if (len == length) { | |
381 | c = (char)len; | |
382 | len = -1; | |
383 | } else | |
384 | c = *buf++; | |
385 | l = (l << 8) | c; | |
386 | len++; | |
387 | if ((len & (32 / 8 - 1)) == 0) | |
388 | hash = ((hash^l) * 0x9e370001UL); | |
389 | } while (len); | |
390 | ||
391 | return (hash >> (32 - bits)) & 0xffffffffUL; | |
392 | } | |
393 | ||
d832c5b2 FS |
394 | /* Helper function to read data blocks from i2c clients with 8 or 16 bit |
395 | * address width, 8 bit register width and auto incrementation been activated */ | |
aab3125c MCC |
396 | static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, |
397 | bool addr_w16, u16 len, u8 *data) | |
d832c5b2 FS |
398 | { |
399 | int remain = len, rsize, rsize_max, ret; | |
400 | u8 buf[2]; | |
401 | ||
402 | /* Sanity check */ | |
403 | if (addr + remain > (addr_w16 * 0xff00 + 0xff + 1)) | |
404 | return -EINVAL; | |
405 | /* Select address */ | |
406 | buf[0] = addr >> 8; | |
407 | buf[1] = addr & 0xff; | |
aab3125c | 408 | ret = i2c_master_send(&dev->i2c_client[bus], buf + !addr_w16, 1 + addr_w16); |
d832c5b2 FS |
409 | if (ret < 0) |
410 | return ret; | |
411 | /* Read data */ | |
412 | if (dev->board.is_em2800) | |
413 | rsize_max = 4; | |
414 | else | |
415 | rsize_max = 64; | |
416 | while (remain > 0) { | |
417 | if (remain > rsize_max) | |
418 | rsize = rsize_max; | |
419 | else | |
420 | rsize = remain; | |
421 | ||
aab3125c | 422 | ret = i2c_master_recv(&dev->i2c_client[bus], data, rsize); |
d832c5b2 FS |
423 | if (ret < 0) |
424 | return ret; | |
425 | ||
426 | remain -= rsize; | |
427 | data += rsize; | |
428 | } | |
429 | ||
430 | return len; | |
431 | } | |
432 | ||
aab3125c MCC |
433 | static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, |
434 | u8 **eedata, u16 *eedata_len) | |
a6c2ba28 | 435 | { |
510e884c FS |
436 | const u16 len = 256; |
437 | /* FIXME common length/size for bytes to read, to display, hash | |
438 | * calculation and returned device dataset. Simplifies the code a lot, | |
439 | * but we might have to deal with multiple sizes in the future ! */ | |
d832c5b2 | 440 | int i, err; |
510e884c FS |
441 | struct em28xx_eeprom *dev_config; |
442 | u8 buf, *data; | |
a6c2ba28 | 443 | |
a217968f | 444 | *eedata = NULL; |
510e884c | 445 | *eedata_len = 0; |
a217968f | 446 | |
aab3125c MCC |
447 | /* EEPROM is always on i2c bus 0 on all known devices. */ |
448 | ||
449 | dev->i2c_client[bus].addr = 0xa0 >> 1; | |
596d92d5 MCC |
450 | |
451 | /* Check if board has eeprom */ | |
aab3125c | 452 | err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); |
f2a01a00 | 453 | if (err < 0) { |
12d7ce18 | 454 | em28xx_info("board has no eeprom\n"); |
c41109fc | 455 | return -ENODEV; |
f2a01a00 | 456 | } |
596d92d5 | 457 | |
a217968f FS |
458 | data = kzalloc(len, GFP_KERNEL); |
459 | if (data == NULL) | |
460 | return -ENOMEM; | |
461 | ||
d832c5b2 | 462 | /* Read EEPROM content */ |
aab3125c MCC |
463 | err = em28xx_i2c_read_block(dev, bus, 0x0000, |
464 | dev->eeprom_addrwidth_16bit, | |
a217968f | 465 | len, data); |
d832c5b2 | 466 | if (err != len) { |
12d7ce18 | 467 | em28xx_errdev("failed to read eeprom (err=%d)\n", err); |
510e884c | 468 | goto error; |
a6c2ba28 | 469 | } |
90271964 | 470 | |
87b52439 | 471 | /* Display eeprom content */ |
a6c2ba28 | 472 | for (i = 0; i < len; i++) { |
87b52439 FS |
473 | if (0 == (i % 16)) { |
474 | if (dev->eeprom_addrwidth_16bit) | |
475 | em28xx_info("i2c eeprom %04x:", i); | |
476 | else | |
477 | em28xx_info("i2c eeprom %02x:", i); | |
478 | } | |
a217968f | 479 | printk(" %02x", data[i]); |
a6c2ba28 AM |
480 | if (15 == (i % 16)) |
481 | printk("\n"); | |
482 | } | |
510e884c FS |
483 | if (dev->eeprom_addrwidth_16bit) |
484 | em28xx_info("i2c eeprom %04x: ... (skipped)\n", i); | |
a6c2ba28 | 485 | |
87b52439 | 486 | if (dev->eeprom_addrwidth_16bit && |
a217968f | 487 | data[0] == 0x26 && data[3] == 0x00) { |
87b52439 | 488 | /* new eeprom format; size 4-64kb */ |
510e884c FS |
489 | u16 mc_start; |
490 | u16 hwconf_offset; | |
491 | ||
a217968f | 492 | dev->hash = em28xx_hash_mem(data, len, 32); |
510e884c FS |
493 | mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ |
494 | ||
495 | em28xx_info("EEPROM ID = %02x %02x %02x %02x, " | |
496 | "EEPROM hash = 0x%08lx\n", | |
497 | data[0], data[1], data[2], data[3], dev->hash); | |
498 | em28xx_info("EEPROM info:\n"); | |
499 | em28xx_info("\tmicrocode start address = 0x%04x, " | |
87b52439 | 500 | "boot configuration = 0x%02x\n", |
510e884c | 501 | mc_start, data[2]); |
87b52439 FS |
502 | /* boot configuration (address 0x0002): |
503 | * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz | |
504 | * [1] always selects 12 kb RAM | |
505 | * [2] USB device speed: 1 = force Full Speed; 0 = auto detect | |
506 | * [4] 1 = force fast mode and no suspend for device testing | |
507 | * [5:7] USB PHY tuning registers; determined by device | |
508 | * characterization | |
509 | */ | |
510 | ||
510e884c FS |
511 | /* Read hardware config dataset offset from address |
512 | * (microcode start + 46) */ | |
aab3125c MCC |
513 | err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2, |
514 | data); | |
510e884c FS |
515 | if (err != 2) { |
516 | em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", | |
517 | err); | |
518 | goto error; | |
519 | } | |
520 | ||
521 | /* Calculate hardware config dataset start address */ | |
522 | hwconf_offset = mc_start + data[0] + (data[1] << 8); | |
523 | ||
524 | /* Read hardware config dataset */ | |
525 | /* NOTE: the microcode copy can be multiple pages long, but | |
526 | * we assume the hardware config dataset is the same as in | |
527 | * the old eeprom and not longer than 256 bytes. | |
528 | * tveeprom is currently also limited to 256 bytes. | |
87b52439 | 529 | */ |
aab3125c MCC |
530 | err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len, |
531 | data); | |
510e884c FS |
532 | if (err != len) { |
533 | em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", | |
534 | err); | |
535 | goto error; | |
536 | } | |
87b52439 | 537 | |
510e884c FS |
538 | /* Verify hardware config dataset */ |
539 | /* NOTE: not all devices provide this type of dataset */ | |
540 | if (data[0] != 0x1a || data[1] != 0xeb || | |
541 | data[2] != 0x67 || data[3] != 0x95) { | |
542 | em28xx_info("\tno hardware configuration dataset found in eeprom\n"); | |
543 | kfree(data); | |
544 | return 0; | |
545 | } | |
546 | ||
547 | /* TODO: decrypt eeprom data for camera bridges (em25xx, em276x+) */ | |
548 | ||
549 | } else if (!dev->eeprom_addrwidth_16bit && | |
550 | data[0] == 0x1a && data[1] == 0xeb && | |
551 | data[2] == 0x67 && data[3] == 0x95) { | |
552 | dev->hash = em28xx_hash_mem(data, len, 32); | |
553 | em28xx_info("EEPROM ID = %02x %02x %02x %02x, " | |
554 | "EEPROM hash = 0x%08lx\n", | |
555 | data[0], data[1], data[2], data[3], dev->hash); | |
556 | em28xx_info("EEPROM info:\n"); | |
557 | } else { | |
87b52439 | 558 | em28xx_info("unknown eeprom format or eeprom corrupted !\n"); |
510e884c FS |
559 | err = -ENODEV; |
560 | goto error; | |
f55eacbe FS |
561 | } |
562 | ||
a217968f | 563 | *eedata = data; |
510e884c FS |
564 | *eedata_len = len; |
565 | dev_config = (void *)eedata; | |
a217968f | 566 | |
510e884c | 567 | switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { |
a6c2ba28 | 568 | case 0: |
12d7ce18 | 569 | em28xx_info("\tNo audio on board.\n"); |
a6c2ba28 AM |
570 | break; |
571 | case 1: | |
12d7ce18 | 572 | em28xx_info("\tAC97 audio (5 sample rates)\n"); |
a6c2ba28 AM |
573 | break; |
574 | case 2: | |
12d7ce18 | 575 | em28xx_info("\tI2S audio, sample rate=32k\n"); |
a6c2ba28 AM |
576 | break; |
577 | case 3: | |
12d7ce18 | 578 | em28xx_info("\tI2S audio, 3 sample rates\n"); |
a6c2ba28 AM |
579 | break; |
580 | } | |
581 | ||
510e884c | 582 | if (le16_to_cpu(dev_config->chip_conf) & 1 << 3) |
12d7ce18 | 583 | em28xx_info("\tUSB Remote wakeup capable\n"); |
a6c2ba28 | 584 | |
510e884c | 585 | if (le16_to_cpu(dev_config->chip_conf) & 1 << 2) |
12d7ce18 | 586 | em28xx_info("\tUSB Self power capable\n"); |
a6c2ba28 | 587 | |
510e884c | 588 | switch (le16_to_cpu(dev_config->chip_conf) & 0x3) { |
a6c2ba28 | 589 | case 0: |
12d7ce18 | 590 | em28xx_info("\t500mA max power\n"); |
a6c2ba28 AM |
591 | break; |
592 | case 1: | |
12d7ce18 | 593 | em28xx_info("\t400mA max power\n"); |
a6c2ba28 AM |
594 | break; |
595 | case 2: | |
12d7ce18 | 596 | em28xx_info("\t300mA max power\n"); |
a6c2ba28 AM |
597 | break; |
598 | case 3: | |
12d7ce18 | 599 | em28xx_info("\t200mA max power\n"); |
a6c2ba28 AM |
600 | break; |
601 | } | |
12d7ce18 | 602 | em28xx_info("\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", |
510e884c FS |
603 | dev_config->string_idx_table, |
604 | le16_to_cpu(dev_config->string1), | |
605 | le16_to_cpu(dev_config->string2), | |
606 | le16_to_cpu(dev_config->string3)); | |
a6c2ba28 AM |
607 | |
608 | return 0; | |
510e884c FS |
609 | |
610 | error: | |
611 | kfree(data); | |
612 | return err; | |
a6c2ba28 AM |
613 | } |
614 | ||
615 | /* ----------------------------------------------------------- */ | |
616 | ||
a6c2ba28 AM |
617 | /* |
618 | * functionality() | |
619 | */ | |
aab3125c | 620 | static u32 functionality(struct i2c_adapter *i2c_adap) |
a6c2ba28 | 621 | { |
aab3125c MCC |
622 | struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; |
623 | struct em28xx *dev = i2c_bus->dev; | |
624 | ||
eaf33c40 FS |
625 | u32 func_flags = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
626 | if (dev->board.is_em2800) | |
627 | func_flags &= ~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA; | |
628 | return func_flags; | |
a6c2ba28 AM |
629 | } |
630 | ||
3acf2809 MCC |
631 | static struct i2c_algorithm em28xx_algo = { |
632 | .master_xfer = em28xx_i2c_xfer, | |
a6c2ba28 AM |
633 | .functionality = functionality, |
634 | }; | |
635 | ||
3acf2809 | 636 | static struct i2c_adapter em28xx_adap_template = { |
a6c2ba28 | 637 | .owner = THIS_MODULE, |
3acf2809 | 638 | .name = "em28xx", |
3acf2809 | 639 | .algo = &em28xx_algo, |
a6c2ba28 AM |
640 | }; |
641 | ||
3acf2809 MCC |
642 | static struct i2c_client em28xx_client_template = { |
643 | .name = "em28xx internal", | |
a6c2ba28 AM |
644 | }; |
645 | ||
646 | /* ----------------------------------------------------------- */ | |
647 | ||
648 | /* | |
649 | * i2c_devs | |
650 | * incomplete list of known devices | |
651 | */ | |
652 | static char *i2c_devs[128] = { | |
0b3966e4 | 653 | [0x3e >> 1] = "remote IR sensor", |
a6c2ba28 | 654 | [0x4a >> 1] = "saa7113h", |
729841ed | 655 | [0x52 >> 1] = "drxk", |
a6c2ba28 | 656 | [0x60 >> 1] = "remote IR sensor", |
da45a2a5 | 657 | [0x8e >> 1] = "remote IR sensor", |
a6c2ba28 AM |
658 | [0x86 >> 1] = "tda9887", |
659 | [0x80 >> 1] = "msp34xx", | |
660 | [0x88 >> 1] = "msp34xx", | |
661 | [0xa0 >> 1] = "eeprom", | |
2bd1d9eb | 662 | [0xb0 >> 1] = "tda9874", |
a6c2ba28 | 663 | [0xb8 >> 1] = "tvp5150a", |
791a08fc | 664 | [0xba >> 1] = "webcam sensor or tvp5150a", |
a6c2ba28 AM |
665 | [0xc0 >> 1] = "tuner (analog)", |
666 | [0xc2 >> 1] = "tuner (analog)", | |
667 | [0xc4 >> 1] = "tuner (analog)", | |
668 | [0xc6 >> 1] = "tuner (analog)", | |
669 | }; | |
670 | ||
671 | /* | |
672 | * do_i2c_scan() | |
673 | * check i2c address range for devices | |
674 | */ | |
aab3125c | 675 | void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) |
a6c2ba28 | 676 | { |
fad7b958 | 677 | u8 i2c_devicelist[128]; |
a6c2ba28 AM |
678 | unsigned char buf; |
679 | int i, rc; | |
680 | ||
fad7b958 SS |
681 | memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist)); |
682 | ||
53c4e955 | 683 | for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { |
aab3125c MCC |
684 | dev->i2c_client[bus].addr = i; |
685 | rc = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); | |
a6c2ba28 AM |
686 | if (rc < 0) |
687 | continue; | |
fad7b958 | 688 | i2c_devicelist[i] = i; |
aab3125c MCC |
689 | em28xx_info("found i2c device @ 0x%x on bus %d [%s]\n", |
690 | i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); | |
a6c2ba28 | 691 | } |
fad7b958 | 692 | |
aab3125c MCC |
693 | if (bus == dev->def_i2c_bus) |
694 | dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, | |
695 | ARRAY_SIZE(i2c_devicelist), 32); | |
a6c2ba28 AM |
696 | } |
697 | ||
a6c2ba28 | 698 | /* |
3acf2809 | 699 | * em28xx_i2c_register() |
a6c2ba28 AM |
700 | * register i2c bus |
701 | */ | |
aab3125c | 702 | int em28xx_i2c_register(struct em28xx *dev, unsigned bus) |
a6c2ba28 | 703 | { |
f2a01a00 DSL |
704 | int retval; |
705 | ||
3acf2809 MCC |
706 | BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); |
707 | BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); | |
f2a01a00 | 708 | |
aab3125c MCC |
709 | if (bus >= NUM_I2C_BUSES) |
710 | return -ENODEV; | |
711 | ||
712 | dev->i2c_adap[bus] = em28xx_adap_template; | |
713 | dev->i2c_adap[bus].dev.parent = &dev->udev->dev; | |
714 | strcpy(dev->i2c_adap[bus].name, dev->name); | |
715 | ||
716 | dev->i2c_bus[bus].bus = bus; | |
717 | dev->i2c_bus[bus].dev = dev; | |
718 | dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus]; | |
719 | i2c_set_adapdata(&dev->i2c_adap[bus], &dev->v4l2_dev); | |
720 | ||
721 | retval = i2c_add_adapter(&dev->i2c_adap[bus]); | |
f2a01a00 DSL |
722 | if (retval < 0) { |
723 | em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", | |
724 | __func__, retval); | |
725 | return retval; | |
726 | } | |
a6c2ba28 | 727 | |
aab3125c MCC |
728 | dev->i2c_client[bus] = em28xx_client_template; |
729 | dev->i2c_client[bus].adapter = &dev->i2c_adap[bus]; | |
a6c2ba28 | 730 | |
aab3125c MCC |
731 | /* Up to now, all eeproms are at bus 0 */ |
732 | if (!bus) { | |
733 | retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); | |
734 | if ((retval < 0) && (retval != -ENODEV)) { | |
735 | em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", | |
736 | __func__, retval); | |
c41109fc | 737 | |
aab3125c MCC |
738 | return retval; |
739 | } | |
f2a01a00 | 740 | } |
a6c2ba28 AM |
741 | |
742 | if (i2c_scan) | |
aab3125c | 743 | em28xx_do_i2c_scan(dev, bus); |
c41109fc | 744 | |
a6c2ba28 AM |
745 | return 0; |
746 | } | |
747 | ||
748 | /* | |
3acf2809 | 749 | * em28xx_i2c_unregister() |
a6c2ba28 AM |
750 | * unregister i2c_bus |
751 | */ | |
aab3125c | 752 | int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus) |
a6c2ba28 | 753 | { |
aab3125c MCC |
754 | if (bus >= NUM_I2C_BUSES) |
755 | return -ENODEV; | |
756 | ||
757 | i2c_del_adapter(&dev->i2c_adap[bus]); | |
a6c2ba28 AM |
758 | return 0; |
759 | } |