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); |
7f6301d1 FS |
230 | if (ret < 0) { |
231 | em28xx_warn("reading from i2c device at 0x%x failed (error=%i)\n", | |
232 | addr, ret); | |
233 | return ret; | |
45f04e82 | 234 | } |
7f6301d1 FS |
235 | /* NOTE: some devices with two i2c busses have the bad habit to return 0 |
236 | * bytes if we are on bus B AND there was no write attempt to the | |
237 | * specified slave address before AND no device is present at the | |
238 | * requested slave address. | |
239 | * Anyway, the next check will fail with -ENODEV in this case, so avoid | |
240 | * spamming the system log on device probing and do nothing here. | |
241 | */ | |
45f04e82 FS |
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 | 286 | int addr, rc, i, byte; |
3190fbee | 287 | u8 reg; |
a6c2ba28 | 288 | |
aab3125c MCC |
289 | rc = rt_mutex_trylock(&dev->i2c_bus_lock); |
290 | if (rc < 0) | |
291 | return rc; | |
292 | ||
293 | /* Switch I2C bus if needed */ | |
294 | if (bus != dev->cur_i2c_bus) { | |
295 | if (bus == 1) | |
3190fbee | 296 | reg = EM2874_I2C_SECONDARY_BUS_SELECT; |
aab3125c | 297 | else |
3190fbee MCC |
298 | reg = 0; |
299 | em28xx_write_reg_bits(dev, EM28XX_R06_I2C_CLK, reg, | |
300 | EM2874_I2C_SECONDARY_BUS_SELECT); | |
aab3125c MCC |
301 | dev->cur_i2c_bus = bus; |
302 | } | |
303 | ||
304 | if (num <= 0) { | |
305 | rt_mutex_unlock(&dev->i2c_bus_lock); | |
a6c2ba28 | 306 | return 0; |
aab3125c | 307 | } |
a6c2ba28 AM |
308 | for (i = 0; i < num; i++) { |
309 | addr = msgs[i].addr << 1; | |
d90f0677 | 310 | if (i2c_debug) |
d7a80eaa FS |
311 | printk(KERN_DEBUG "%s at %s: %s %s addr=%02x len=%d:", |
312 | dev->name, __func__ , | |
313 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | |
314 | i == num - 1 ? "stop" : "nonstop", | |
315 | addr, msgs[i].len); | |
6ea54d93 | 316 | if (!msgs[i].len) { /* no len: check only for device presence */ |
505b6d0b | 317 | if (dev->board.is_em2800) |
596d92d5 MCC |
318 | rc = em2800_i2c_check_for_device(dev, addr); |
319 | else | |
3acf2809 | 320 | rc = em28xx_i2c_check_for_device(dev, addr); |
45f04e82 | 321 | if (rc == -ENODEV) { |
d90f0677 | 322 | if (i2c_debug) |
45f04e82 | 323 | printk(" no device\n"); |
aab3125c | 324 | rt_mutex_unlock(&dev->i2c_bus_lock); |
a6c2ba28 AM |
325 | return rc; |
326 | } | |
596d92d5 | 327 | } else if (msgs[i].flags & I2C_M_RD) { |
a6c2ba28 | 328 | /* read bytes */ |
505b6d0b | 329 | if (dev->board.is_em2800) |
596d92d5 MCC |
330 | rc = em2800_i2c_recv_bytes(dev, addr, |
331 | msgs[i].buf, | |
332 | msgs[i].len); | |
333 | else | |
3acf2809 | 334 | rc = em28xx_i2c_recv_bytes(dev, addr, |
596d92d5 MCC |
335 | msgs[i].buf, |
336 | msgs[i].len); | |
d90f0677 | 337 | if (i2c_debug) { |
6ea54d93 | 338 | for (byte = 0; byte < msgs[i].len; byte++) |
a6c2ba28 | 339 | printk(" %02x", msgs[i].buf[byte]); |
a6c2ba28 AM |
340 | } |
341 | } else { | |
342 | /* write bytes */ | |
d90f0677 | 343 | if (i2c_debug) { |
a6c2ba28 AM |
344 | for (byte = 0; byte < msgs[i].len; byte++) |
345 | printk(" %02x", msgs[i].buf[byte]); | |
346 | } | |
505b6d0b | 347 | if (dev->board.is_em2800) |
596d92d5 MCC |
348 | rc = em2800_i2c_send_bytes(dev, addr, |
349 | msgs[i].buf, | |
350 | msgs[i].len); | |
351 | else | |
3acf2809 | 352 | rc = em28xx_i2c_send_bytes(dev, addr, |
596d92d5 MCC |
353 | msgs[i].buf, |
354 | msgs[i].len, | |
355 | i == num - 1); | |
a6c2ba28 | 356 | } |
45f04e82 | 357 | if (rc < 0) { |
d90f0677 | 358 | if (i2c_debug) |
45f04e82 | 359 | printk(" ERROR: %i\n", rc); |
aab3125c | 360 | rt_mutex_unlock(&dev->i2c_bus_lock); |
45f04e82 FS |
361 | return rc; |
362 | } | |
d90f0677 | 363 | if (i2c_debug) |
a6c2ba28 AM |
364 | printk("\n"); |
365 | } | |
366 | ||
aab3125c | 367 | rt_mutex_unlock(&dev->i2c_bus_lock); |
a6c2ba28 | 368 | return num; |
a6c2ba28 AM |
369 | } |
370 | ||
03910cc3 MCC |
371 | /* based on linux/sunrpc/svcauth.h and linux/hash.h |
372 | * The original hash function returns a different value, if arch is x86_64 | |
373 | * or i386. | |
374 | */ | |
375 | static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) | |
376 | { | |
377 | unsigned long hash = 0; | |
378 | unsigned long l = 0; | |
379 | int len = 0; | |
380 | unsigned char c; | |
381 | do { | |
382 | if (len == length) { | |
383 | c = (char)len; | |
384 | len = -1; | |
385 | } else | |
386 | c = *buf++; | |
387 | l = (l << 8) | c; | |
388 | len++; | |
389 | if ((len & (32 / 8 - 1)) == 0) | |
390 | hash = ((hash^l) * 0x9e370001UL); | |
391 | } while (len); | |
392 | ||
393 | return (hash >> (32 - bits)) & 0xffffffffUL; | |
394 | } | |
395 | ||
d832c5b2 FS |
396 | /* Helper function to read data blocks from i2c clients with 8 or 16 bit |
397 | * address width, 8 bit register width and auto incrementation been activated */ | |
aab3125c MCC |
398 | static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, |
399 | bool addr_w16, u16 len, u8 *data) | |
d832c5b2 FS |
400 | { |
401 | int remain = len, rsize, rsize_max, ret; | |
402 | u8 buf[2]; | |
403 | ||
404 | /* Sanity check */ | |
405 | if (addr + remain > (addr_w16 * 0xff00 + 0xff + 1)) | |
406 | return -EINVAL; | |
407 | /* Select address */ | |
408 | buf[0] = addr >> 8; | |
409 | buf[1] = addr & 0xff; | |
aab3125c | 410 | ret = i2c_master_send(&dev->i2c_client[bus], buf + !addr_w16, 1 + addr_w16); |
d832c5b2 FS |
411 | if (ret < 0) |
412 | return ret; | |
413 | /* Read data */ | |
414 | if (dev->board.is_em2800) | |
415 | rsize_max = 4; | |
416 | else | |
417 | rsize_max = 64; | |
418 | while (remain > 0) { | |
419 | if (remain > rsize_max) | |
420 | rsize = rsize_max; | |
421 | else | |
422 | rsize = remain; | |
423 | ||
aab3125c | 424 | ret = i2c_master_recv(&dev->i2c_client[bus], data, rsize); |
d832c5b2 FS |
425 | if (ret < 0) |
426 | return ret; | |
427 | ||
428 | remain -= rsize; | |
429 | data += rsize; | |
430 | } | |
431 | ||
432 | return len; | |
433 | } | |
434 | ||
aab3125c MCC |
435 | static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, |
436 | u8 **eedata, u16 *eedata_len) | |
a6c2ba28 | 437 | { |
510e884c FS |
438 | const u16 len = 256; |
439 | /* FIXME common length/size for bytes to read, to display, hash | |
440 | * calculation and returned device dataset. Simplifies the code a lot, | |
441 | * but we might have to deal with multiple sizes in the future ! */ | |
d832c5b2 | 442 | int i, err; |
510e884c FS |
443 | struct em28xx_eeprom *dev_config; |
444 | u8 buf, *data; | |
a6c2ba28 | 445 | |
a217968f | 446 | *eedata = NULL; |
510e884c | 447 | *eedata_len = 0; |
a217968f | 448 | |
aab3125c MCC |
449 | /* EEPROM is always on i2c bus 0 on all known devices. */ |
450 | ||
451 | dev->i2c_client[bus].addr = 0xa0 >> 1; | |
596d92d5 MCC |
452 | |
453 | /* Check if board has eeprom */ | |
aab3125c | 454 | err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); |
f2a01a00 | 455 | if (err < 0) { |
12d7ce18 | 456 | em28xx_info("board has no eeprom\n"); |
c41109fc | 457 | return -ENODEV; |
f2a01a00 | 458 | } |
596d92d5 | 459 | |
a217968f FS |
460 | data = kzalloc(len, GFP_KERNEL); |
461 | if (data == NULL) | |
462 | return -ENOMEM; | |
463 | ||
d832c5b2 | 464 | /* Read EEPROM content */ |
aab3125c MCC |
465 | err = em28xx_i2c_read_block(dev, bus, 0x0000, |
466 | dev->eeprom_addrwidth_16bit, | |
a217968f | 467 | len, data); |
d832c5b2 | 468 | if (err != len) { |
12d7ce18 | 469 | em28xx_errdev("failed to read eeprom (err=%d)\n", err); |
510e884c | 470 | goto error; |
a6c2ba28 | 471 | } |
90271964 | 472 | |
87b52439 | 473 | /* Display eeprom content */ |
a6c2ba28 | 474 | for (i = 0; i < len; i++) { |
87b52439 FS |
475 | if (0 == (i % 16)) { |
476 | if (dev->eeprom_addrwidth_16bit) | |
477 | em28xx_info("i2c eeprom %04x:", i); | |
478 | else | |
479 | em28xx_info("i2c eeprom %02x:", i); | |
480 | } | |
a217968f | 481 | printk(" %02x", data[i]); |
a6c2ba28 AM |
482 | if (15 == (i % 16)) |
483 | printk("\n"); | |
484 | } | |
510e884c FS |
485 | if (dev->eeprom_addrwidth_16bit) |
486 | em28xx_info("i2c eeprom %04x: ... (skipped)\n", i); | |
a6c2ba28 | 487 | |
87b52439 | 488 | if (dev->eeprom_addrwidth_16bit && |
a217968f | 489 | data[0] == 0x26 && data[3] == 0x00) { |
87b52439 | 490 | /* new eeprom format; size 4-64kb */ |
510e884c FS |
491 | u16 mc_start; |
492 | u16 hwconf_offset; | |
493 | ||
a217968f | 494 | dev->hash = em28xx_hash_mem(data, len, 32); |
510e884c FS |
495 | mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ |
496 | ||
497 | em28xx_info("EEPROM ID = %02x %02x %02x %02x, " | |
498 | "EEPROM hash = 0x%08lx\n", | |
499 | data[0], data[1], data[2], data[3], dev->hash); | |
500 | em28xx_info("EEPROM info:\n"); | |
501 | em28xx_info("\tmicrocode start address = 0x%04x, " | |
87b52439 | 502 | "boot configuration = 0x%02x\n", |
510e884c | 503 | mc_start, data[2]); |
87b52439 FS |
504 | /* boot configuration (address 0x0002): |
505 | * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz | |
506 | * [1] always selects 12 kb RAM | |
507 | * [2] USB device speed: 1 = force Full Speed; 0 = auto detect | |
508 | * [4] 1 = force fast mode and no suspend for device testing | |
509 | * [5:7] USB PHY tuning registers; determined by device | |
510 | * characterization | |
511 | */ | |
512 | ||
510e884c FS |
513 | /* Read hardware config dataset offset from address |
514 | * (microcode start + 46) */ | |
aab3125c MCC |
515 | err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2, |
516 | data); | |
510e884c FS |
517 | if (err != 2) { |
518 | em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", | |
519 | err); | |
520 | goto error; | |
521 | } | |
522 | ||
523 | /* Calculate hardware config dataset start address */ | |
524 | hwconf_offset = mc_start + data[0] + (data[1] << 8); | |
525 | ||
526 | /* Read hardware config dataset */ | |
527 | /* NOTE: the microcode copy can be multiple pages long, but | |
528 | * we assume the hardware config dataset is the same as in | |
529 | * the old eeprom and not longer than 256 bytes. | |
530 | * tveeprom is currently also limited to 256 bytes. | |
87b52439 | 531 | */ |
aab3125c MCC |
532 | err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len, |
533 | data); | |
510e884c FS |
534 | if (err != len) { |
535 | em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", | |
536 | err); | |
537 | goto error; | |
538 | } | |
87b52439 | 539 | |
510e884c FS |
540 | /* Verify hardware config dataset */ |
541 | /* NOTE: not all devices provide this type of dataset */ | |
542 | if (data[0] != 0x1a || data[1] != 0xeb || | |
543 | data[2] != 0x67 || data[3] != 0x95) { | |
544 | em28xx_info("\tno hardware configuration dataset found in eeprom\n"); | |
545 | kfree(data); | |
546 | return 0; | |
547 | } | |
548 | ||
549 | /* TODO: decrypt eeprom data for camera bridges (em25xx, em276x+) */ | |
550 | ||
551 | } else if (!dev->eeprom_addrwidth_16bit && | |
552 | data[0] == 0x1a && data[1] == 0xeb && | |
553 | data[2] == 0x67 && data[3] == 0x95) { | |
554 | dev->hash = em28xx_hash_mem(data, len, 32); | |
555 | em28xx_info("EEPROM ID = %02x %02x %02x %02x, " | |
556 | "EEPROM hash = 0x%08lx\n", | |
557 | data[0], data[1], data[2], data[3], dev->hash); | |
558 | em28xx_info("EEPROM info:\n"); | |
559 | } else { | |
87b52439 | 560 | em28xx_info("unknown eeprom format or eeprom corrupted !\n"); |
510e884c FS |
561 | err = -ENODEV; |
562 | goto error; | |
f55eacbe FS |
563 | } |
564 | ||
a217968f | 565 | *eedata = data; |
510e884c FS |
566 | *eedata_len = len; |
567 | dev_config = (void *)eedata; | |
a217968f | 568 | |
510e884c | 569 | switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { |
a6c2ba28 | 570 | case 0: |
12d7ce18 | 571 | em28xx_info("\tNo audio on board.\n"); |
a6c2ba28 AM |
572 | break; |
573 | case 1: | |
12d7ce18 | 574 | em28xx_info("\tAC97 audio (5 sample rates)\n"); |
a6c2ba28 AM |
575 | break; |
576 | case 2: | |
12d7ce18 | 577 | em28xx_info("\tI2S audio, sample rate=32k\n"); |
a6c2ba28 AM |
578 | break; |
579 | case 3: | |
12d7ce18 | 580 | em28xx_info("\tI2S audio, 3 sample rates\n"); |
a6c2ba28 AM |
581 | break; |
582 | } | |
583 | ||
510e884c | 584 | if (le16_to_cpu(dev_config->chip_conf) & 1 << 3) |
12d7ce18 | 585 | em28xx_info("\tUSB Remote wakeup capable\n"); |
a6c2ba28 | 586 | |
510e884c | 587 | if (le16_to_cpu(dev_config->chip_conf) & 1 << 2) |
12d7ce18 | 588 | em28xx_info("\tUSB Self power capable\n"); |
a6c2ba28 | 589 | |
510e884c | 590 | switch (le16_to_cpu(dev_config->chip_conf) & 0x3) { |
a6c2ba28 | 591 | case 0: |
12d7ce18 | 592 | em28xx_info("\t500mA max power\n"); |
a6c2ba28 AM |
593 | break; |
594 | case 1: | |
12d7ce18 | 595 | em28xx_info("\t400mA max power\n"); |
a6c2ba28 AM |
596 | break; |
597 | case 2: | |
12d7ce18 | 598 | em28xx_info("\t300mA max power\n"); |
a6c2ba28 AM |
599 | break; |
600 | case 3: | |
12d7ce18 | 601 | em28xx_info("\t200mA max power\n"); |
a6c2ba28 AM |
602 | break; |
603 | } | |
12d7ce18 | 604 | em28xx_info("\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", |
510e884c FS |
605 | dev_config->string_idx_table, |
606 | le16_to_cpu(dev_config->string1), | |
607 | le16_to_cpu(dev_config->string2), | |
608 | le16_to_cpu(dev_config->string3)); | |
a6c2ba28 AM |
609 | |
610 | return 0; | |
510e884c FS |
611 | |
612 | error: | |
613 | kfree(data); | |
614 | return err; | |
a6c2ba28 AM |
615 | } |
616 | ||
617 | /* ----------------------------------------------------------- */ | |
618 | ||
a6c2ba28 AM |
619 | /* |
620 | * functionality() | |
621 | */ | |
aab3125c | 622 | static u32 functionality(struct i2c_adapter *i2c_adap) |
a6c2ba28 | 623 | { |
aab3125c MCC |
624 | struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; |
625 | struct em28xx *dev = i2c_bus->dev; | |
626 | ||
eaf33c40 FS |
627 | u32 func_flags = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
628 | if (dev->board.is_em2800) | |
629 | func_flags &= ~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA; | |
630 | return func_flags; | |
a6c2ba28 AM |
631 | } |
632 | ||
3acf2809 MCC |
633 | static struct i2c_algorithm em28xx_algo = { |
634 | .master_xfer = em28xx_i2c_xfer, | |
a6c2ba28 AM |
635 | .functionality = functionality, |
636 | }; | |
637 | ||
3acf2809 | 638 | static struct i2c_adapter em28xx_adap_template = { |
a6c2ba28 | 639 | .owner = THIS_MODULE, |
3acf2809 | 640 | .name = "em28xx", |
3acf2809 | 641 | .algo = &em28xx_algo, |
a6c2ba28 AM |
642 | }; |
643 | ||
3acf2809 MCC |
644 | static struct i2c_client em28xx_client_template = { |
645 | .name = "em28xx internal", | |
a6c2ba28 AM |
646 | }; |
647 | ||
648 | /* ----------------------------------------------------------- */ | |
649 | ||
650 | /* | |
651 | * i2c_devs | |
652 | * incomplete list of known devices | |
653 | */ | |
654 | static char *i2c_devs[128] = { | |
0b3966e4 | 655 | [0x3e >> 1] = "remote IR sensor", |
a6c2ba28 | 656 | [0x4a >> 1] = "saa7113h", |
729841ed | 657 | [0x52 >> 1] = "drxk", |
a6c2ba28 | 658 | [0x60 >> 1] = "remote IR sensor", |
da45a2a5 | 659 | [0x8e >> 1] = "remote IR sensor", |
a6c2ba28 AM |
660 | [0x86 >> 1] = "tda9887", |
661 | [0x80 >> 1] = "msp34xx", | |
662 | [0x88 >> 1] = "msp34xx", | |
663 | [0xa0 >> 1] = "eeprom", | |
2bd1d9eb | 664 | [0xb0 >> 1] = "tda9874", |
a6c2ba28 | 665 | [0xb8 >> 1] = "tvp5150a", |
791a08fc | 666 | [0xba >> 1] = "webcam sensor or tvp5150a", |
a6c2ba28 AM |
667 | [0xc0 >> 1] = "tuner (analog)", |
668 | [0xc2 >> 1] = "tuner (analog)", | |
669 | [0xc4 >> 1] = "tuner (analog)", | |
670 | [0xc6 >> 1] = "tuner (analog)", | |
671 | }; | |
672 | ||
673 | /* | |
674 | * do_i2c_scan() | |
675 | * check i2c address range for devices | |
676 | */ | |
aab3125c | 677 | void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) |
a6c2ba28 | 678 | { |
fad7b958 | 679 | u8 i2c_devicelist[128]; |
a6c2ba28 AM |
680 | unsigned char buf; |
681 | int i, rc; | |
682 | ||
fad7b958 SS |
683 | memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist)); |
684 | ||
53c4e955 | 685 | for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { |
aab3125c MCC |
686 | dev->i2c_client[bus].addr = i; |
687 | rc = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); | |
a6c2ba28 AM |
688 | if (rc < 0) |
689 | continue; | |
fad7b958 | 690 | i2c_devicelist[i] = i; |
aab3125c MCC |
691 | em28xx_info("found i2c device @ 0x%x on bus %d [%s]\n", |
692 | i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); | |
a6c2ba28 | 693 | } |
fad7b958 | 694 | |
aab3125c MCC |
695 | if (bus == dev->def_i2c_bus) |
696 | dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, | |
697 | ARRAY_SIZE(i2c_devicelist), 32); | |
a6c2ba28 AM |
698 | } |
699 | ||
a6c2ba28 | 700 | /* |
3acf2809 | 701 | * em28xx_i2c_register() |
a6c2ba28 AM |
702 | * register i2c bus |
703 | */ | |
aab3125c | 704 | int em28xx_i2c_register(struct em28xx *dev, unsigned bus) |
a6c2ba28 | 705 | { |
f2a01a00 DSL |
706 | int retval; |
707 | ||
3acf2809 MCC |
708 | BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); |
709 | BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); | |
f2a01a00 | 710 | |
aab3125c MCC |
711 | if (bus >= NUM_I2C_BUSES) |
712 | return -ENODEV; | |
713 | ||
714 | dev->i2c_adap[bus] = em28xx_adap_template; | |
715 | dev->i2c_adap[bus].dev.parent = &dev->udev->dev; | |
716 | strcpy(dev->i2c_adap[bus].name, dev->name); | |
717 | ||
718 | dev->i2c_bus[bus].bus = bus; | |
719 | dev->i2c_bus[bus].dev = dev; | |
720 | dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus]; | |
721 | i2c_set_adapdata(&dev->i2c_adap[bus], &dev->v4l2_dev); | |
722 | ||
723 | retval = i2c_add_adapter(&dev->i2c_adap[bus]); | |
f2a01a00 DSL |
724 | if (retval < 0) { |
725 | em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", | |
726 | __func__, retval); | |
727 | return retval; | |
728 | } | |
a6c2ba28 | 729 | |
aab3125c MCC |
730 | dev->i2c_client[bus] = em28xx_client_template; |
731 | dev->i2c_client[bus].adapter = &dev->i2c_adap[bus]; | |
a6c2ba28 | 732 | |
aab3125c MCC |
733 | /* Up to now, all eeproms are at bus 0 */ |
734 | if (!bus) { | |
735 | retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); | |
736 | if ((retval < 0) && (retval != -ENODEV)) { | |
737 | em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", | |
738 | __func__, retval); | |
c41109fc | 739 | |
aab3125c MCC |
740 | return retval; |
741 | } | |
f2a01a00 | 742 | } |
a6c2ba28 AM |
743 | |
744 | if (i2c_scan) | |
aab3125c | 745 | em28xx_do_i2c_scan(dev, bus); |
c41109fc | 746 | |
a6c2ba28 AM |
747 | return 0; |
748 | } | |
749 | ||
750 | /* | |
3acf2809 | 751 | * em28xx_i2c_unregister() |
a6c2ba28 AM |
752 | * unregister i2c_bus |
753 | */ | |
aab3125c | 754 | int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus) |
a6c2ba28 | 755 | { |
aab3125c MCC |
756 | if (bus >= NUM_I2C_BUSES) |
757 | return -ENODEV; | |
758 | ||
759 | i2c_del_adapter(&dev->i2c_adap[bus]); | |
a6c2ba28 AM |
760 | return 0; |
761 | } |