diff options
Diffstat (limited to 'drivers/media/usb/usbvision/usbvision-i2c.c')
-rw-r--r-- | drivers/media/usb/usbvision/usbvision-i2c.c | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/drivers/media/usb/usbvision/usbvision-i2c.c b/drivers/media/usb/usbvision/usbvision-i2c.c new file mode 100644 index 000000000000..89fec029e924 --- /dev/null +++ b/drivers/media/usb/usbvision/usbvision-i2c.c | |||
@@ -0,0 +1,456 @@ | |||
1 | /* | ||
2 | * usbvision_i2c.c | ||
3 | * i2c algorithm for USB-I2C Bridges | ||
4 | * | ||
5 | * Copyright (c) 1999-2007 Joerg Heckenbach <joerg@heckenbach-aw.de> | ||
6 | * Dwaine Garden <dwainegarden@rogers.com> | ||
7 | * | ||
8 | * This module is part of usbvision driver project. | ||
9 | * Updates to driver completed by Dwaine P. Garden | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | */ | ||
25 | |||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/uaccess.h> | ||
32 | #include <linux/ioport.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/usb.h> | ||
35 | #include <linux/i2c.h> | ||
36 | #include "usbvision.h" | ||
37 | |||
38 | #define DBG_I2C (1 << 0) | ||
39 | |||
40 | static int i2c_debug; | ||
41 | |||
42 | module_param(i2c_debug, int, 0644); /* debug_i2c_usb mode of the device driver */ | ||
43 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | ||
44 | |||
45 | #define PDEBUG(level, fmt, args...) { \ | ||
46 | if (i2c_debug & (level)) \ | ||
47 | printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \ | ||
48 | __func__, __LINE__ , ## args); \ | ||
49 | } | ||
50 | |||
51 | static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf, | ||
52 | short len); | ||
53 | static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf, | ||
54 | short len); | ||
55 | |||
56 | static inline int try_write_address(struct i2c_adapter *i2c_adap, | ||
57 | unsigned char addr, int retries) | ||
58 | { | ||
59 | struct usb_usbvision *usbvision; | ||
60 | int i, ret = -1; | ||
61 | char buf[4]; | ||
62 | |||
63 | usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap); | ||
64 | buf[0] = 0x00; | ||
65 | for (i = 0; i <= retries; i++) { | ||
66 | ret = (usbvision_i2c_write(usbvision, addr, buf, 1)); | ||
67 | if (ret == 1) | ||
68 | break; /* success! */ | ||
69 | udelay(5); | ||
70 | if (i == retries) /* no success */ | ||
71 | break; | ||
72 | udelay(10); | ||
73 | } | ||
74 | if (i) { | ||
75 | PDEBUG(DBG_I2C, "Needed %d retries for address %#2x", i, addr); | ||
76 | PDEBUG(DBG_I2C, "Maybe there's no device at this address"); | ||
77 | } | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | static inline int try_read_address(struct i2c_adapter *i2c_adap, | ||
82 | unsigned char addr, int retries) | ||
83 | { | ||
84 | struct usb_usbvision *usbvision; | ||
85 | int i, ret = -1; | ||
86 | char buf[4]; | ||
87 | |||
88 | usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap); | ||
89 | for (i = 0; i <= retries; i++) { | ||
90 | ret = (usbvision_i2c_read(usbvision, addr, buf, 1)); | ||
91 | if (ret == 1) | ||
92 | break; /* success! */ | ||
93 | udelay(5); | ||
94 | if (i == retries) /* no success */ | ||
95 | break; | ||
96 | udelay(10); | ||
97 | } | ||
98 | if (i) { | ||
99 | PDEBUG(DBG_I2C, "Needed %d retries for address %#2x", i, addr); | ||
100 | PDEBUG(DBG_I2C, "Maybe there's no device at this address"); | ||
101 | } | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | static inline int usb_find_address(struct i2c_adapter *i2c_adap, | ||
106 | struct i2c_msg *msg, int retries, | ||
107 | unsigned char *add) | ||
108 | { | ||
109 | unsigned short flags = msg->flags; | ||
110 | |||
111 | unsigned char addr; | ||
112 | int ret; | ||
113 | |||
114 | addr = (msg->addr << 1); | ||
115 | if (flags & I2C_M_RD) | ||
116 | addr |= 1; | ||
117 | |||
118 | add[0] = addr; | ||
119 | if (flags & I2C_M_RD) | ||
120 | ret = try_read_address(i2c_adap, addr, retries); | ||
121 | else | ||
122 | ret = try_write_address(i2c_adap, addr, retries); | ||
123 | |||
124 | if (ret != 1) | ||
125 | return -EREMOTEIO; | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int | ||
131 | usbvision_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) | ||
132 | { | ||
133 | struct i2c_msg *pmsg; | ||
134 | struct usb_usbvision *usbvision; | ||
135 | int i, ret; | ||
136 | unsigned char addr = 0; | ||
137 | |||
138 | usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap); | ||
139 | |||
140 | for (i = 0; i < num; i++) { | ||
141 | pmsg = &msgs[i]; | ||
142 | ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr); | ||
143 | if (ret != 0) { | ||
144 | PDEBUG(DBG_I2C, "got NAK from device, message #%d", i); | ||
145 | return (ret < 0) ? ret : -EREMOTEIO; | ||
146 | } | ||
147 | |||
148 | if (pmsg->flags & I2C_M_RD) { | ||
149 | /* read bytes into buffer */ | ||
150 | ret = (usbvision_i2c_read(usbvision, addr, pmsg->buf, pmsg->len)); | ||
151 | if (ret < pmsg->len) | ||
152 | return (ret < 0) ? ret : -EREMOTEIO; | ||
153 | } else { | ||
154 | /* write bytes from buffer */ | ||
155 | ret = (usbvision_i2c_write(usbvision, addr, pmsg->buf, pmsg->len)); | ||
156 | if (ret < pmsg->len) | ||
157 | return (ret < 0) ? ret : -EREMOTEIO; | ||
158 | } | ||
159 | } | ||
160 | return num; | ||
161 | } | ||
162 | |||
163 | static u32 functionality(struct i2c_adapter *adap) | ||
164 | { | ||
165 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
166 | } | ||
167 | |||
168 | /* -----exported algorithm data: ------------------------------------- */ | ||
169 | |||
170 | static struct i2c_algorithm usbvision_algo = { | ||
171 | .master_xfer = usbvision_i2c_xfer, | ||
172 | .smbus_xfer = NULL, | ||
173 | .functionality = functionality, | ||
174 | }; | ||
175 | |||
176 | |||
177 | /* ----------------------------------------------------------------------- */ | ||
178 | /* usbvision specific I2C functions */ | ||
179 | /* ----------------------------------------------------------------------- */ | ||
180 | static struct i2c_adapter i2c_adap_template; | ||
181 | |||
182 | int usbvision_i2c_register(struct usb_usbvision *usbvision) | ||
183 | { | ||
184 | static unsigned short saa711x_addrs[] = { | ||
185 | 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */ | ||
186 | 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ | ||
187 | I2C_CLIENT_END }; | ||
188 | |||
189 | if (usbvision->registered_i2c) | ||
190 | return 0; | ||
191 | |||
192 | memcpy(&usbvision->i2c_adap, &i2c_adap_template, | ||
193 | sizeof(struct i2c_adapter)); | ||
194 | |||
195 | sprintf(usbvision->i2c_adap.name, "%s-%d-%s", i2c_adap_template.name, | ||
196 | usbvision->dev->bus->busnum, usbvision->dev->devpath); | ||
197 | PDEBUG(DBG_I2C, "Adaptername: %s", usbvision->i2c_adap.name); | ||
198 | usbvision->i2c_adap.dev.parent = &usbvision->dev->dev; | ||
199 | |||
200 | i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev); | ||
201 | |||
202 | if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) { | ||
203 | printk(KERN_ERR "usbvision_i2c_register: can't write reg\n"); | ||
204 | return -EBUSY; | ||
205 | } | ||
206 | |||
207 | PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]"); | ||
208 | PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]"); | ||
209 | |||
210 | /* register new adapter to i2c module... */ | ||
211 | |||
212 | usbvision->i2c_adap.algo = &usbvision_algo; | ||
213 | |||
214 | usbvision->i2c_adap.timeout = 100; /* default values, should */ | ||
215 | usbvision->i2c_adap.retries = 3; /* be replaced by defines */ | ||
216 | |||
217 | i2c_add_adapter(&usbvision->i2c_adap); | ||
218 | |||
219 | PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name); | ||
220 | |||
221 | /* Request the load of the i2c modules we need */ | ||
222 | switch (usbvision_device_data[usbvision->dev_model].codec) { | ||
223 | case CODEC_SAA7113: | ||
224 | case CODEC_SAA7111: | ||
225 | /* Without this delay the detection of the saa711x is | ||
226 | hit-and-miss. */ | ||
227 | mdelay(10); | ||
228 | v4l2_i2c_new_subdev(&usbvision->v4l2_dev, | ||
229 | &usbvision->i2c_adap, | ||
230 | "saa7115_auto", 0, saa711x_addrs); | ||
231 | break; | ||
232 | } | ||
233 | if (usbvision_device_data[usbvision->dev_model].tuner == 1) { | ||
234 | struct v4l2_subdev *sd; | ||
235 | enum v4l2_i2c_tuner_type type; | ||
236 | struct tuner_setup tun_setup; | ||
237 | |||
238 | sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev, | ||
239 | &usbvision->i2c_adap, | ||
240 | "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | ||
241 | /* depending on whether we found a demod or not, select | ||
242 | the tuner type. */ | ||
243 | type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; | ||
244 | |||
245 | sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev, | ||
246 | &usbvision->i2c_adap, | ||
247 | "tuner", 0, v4l2_i2c_tuner_addrs(type)); | ||
248 | |||
249 | if (sd == NULL) | ||
250 | return -ENODEV; | ||
251 | if (usbvision->tuner_type != -1) { | ||
252 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; | ||
253 | tun_setup.type = usbvision->tuner_type; | ||
254 | tun_setup.addr = v4l2_i2c_subdev_addr(sd); | ||
255 | call_all(usbvision, tuner, s_type_addr, &tun_setup); | ||
256 | } | ||
257 | } | ||
258 | usbvision->registered_i2c = 1; | ||
259 | |||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | int usbvision_i2c_unregister(struct usb_usbvision *usbvision) | ||
264 | { | ||
265 | if (!usbvision->registered_i2c) | ||
266 | return 0; | ||
267 | |||
268 | i2c_del_adapter(&(usbvision->i2c_adap)); | ||
269 | usbvision->registered_i2c = 0; | ||
270 | |||
271 | PDEBUG(DBG_I2C, "i2c bus for %s unregistered", usbvision->i2c_adap.name); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int | ||
277 | usbvision_i2c_read_max4(struct usb_usbvision *usbvision, unsigned char addr, | ||
278 | char *buf, short len) | ||
279 | { | ||
280 | int rc, retries; | ||
281 | |||
282 | for (retries = 5;;) { | ||
283 | rc = usbvision_write_reg(usbvision, USBVISION_SER_ADRS, addr); | ||
284 | if (rc < 0) | ||
285 | return rc; | ||
286 | |||
287 | /* Initiate byte read cycle */ | ||
288 | /* USBVISION_SER_CONT <- d0-d2 n. of bytes to r/w */ | ||
289 | /* d3 0=Wr 1=Rd */ | ||
290 | rc = usbvision_write_reg(usbvision, USBVISION_SER_CONT, | ||
291 | (len & 0x07) | 0x18); | ||
292 | if (rc < 0) | ||
293 | return rc; | ||
294 | |||
295 | /* Test for Busy and ACK */ | ||
296 | do { | ||
297 | /* USBVISION_SER_CONT -> d4 == 0 busy */ | ||
298 | rc = usbvision_read_reg(usbvision, USBVISION_SER_CONT); | ||
299 | } while (rc > 0 && ((rc & 0x10) != 0)); /* Retry while busy */ | ||
300 | if (rc < 0) | ||
301 | return rc; | ||
302 | |||
303 | /* USBVISION_SER_CONT -> d5 == 1 Not ack */ | ||
304 | if ((rc & 0x20) == 0) /* Ack? */ | ||
305 | break; | ||
306 | |||
307 | /* I2C abort */ | ||
308 | rc = usbvision_write_reg(usbvision, USBVISION_SER_CONT, 0x00); | ||
309 | if (rc < 0) | ||
310 | return rc; | ||
311 | |||
312 | if (--retries < 0) | ||
313 | return -1; | ||
314 | } | ||
315 | |||
316 | switch (len) { | ||
317 | case 4: | ||
318 | buf[3] = usbvision_read_reg(usbvision, USBVISION_SER_DAT4); | ||
319 | case 3: | ||
320 | buf[2] = usbvision_read_reg(usbvision, USBVISION_SER_DAT3); | ||
321 | case 2: | ||
322 | buf[1] = usbvision_read_reg(usbvision, USBVISION_SER_DAT2); | ||
323 | case 1: | ||
324 | buf[0] = usbvision_read_reg(usbvision, USBVISION_SER_DAT1); | ||
325 | break; | ||
326 | default: | ||
327 | printk(KERN_ERR | ||
328 | "usbvision_i2c_read_max4: buffer length > 4\n"); | ||
329 | } | ||
330 | |||
331 | if (i2c_debug & DBG_I2C) { | ||
332 | int idx; | ||
333 | |||
334 | for (idx = 0; idx < len; idx++) | ||
335 | PDEBUG(DBG_I2C, "read %x from address %x", (unsigned char)buf[idx], addr); | ||
336 | } | ||
337 | return len; | ||
338 | } | ||
339 | |||
340 | |||
341 | static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision, | ||
342 | unsigned char addr, const char *buf, | ||
343 | short len) | ||
344 | { | ||
345 | int rc, retries; | ||
346 | int i; | ||
347 | unsigned char value[6]; | ||
348 | unsigned char ser_cont; | ||
349 | |||
350 | ser_cont = (len & 0x07) | 0x10; | ||
351 | |||
352 | value[0] = addr; | ||
353 | value[1] = ser_cont; | ||
354 | for (i = 0; i < len; i++) | ||
355 | value[i + 2] = buf[i]; | ||
356 | |||
357 | for (retries = 5;;) { | ||
358 | rc = usb_control_msg(usbvision->dev, | ||
359 | usb_sndctrlpipe(usbvision->dev, 1), | ||
360 | USBVISION_OP_CODE, | ||
361 | USB_DIR_OUT | USB_TYPE_VENDOR | | ||
362 | USB_RECIP_ENDPOINT, 0, | ||
363 | (__u16) USBVISION_SER_ADRS, value, | ||
364 | len + 2, HZ); | ||
365 | |||
366 | if (rc < 0) | ||
367 | return rc; | ||
368 | |||
369 | rc = usbvision_write_reg(usbvision, USBVISION_SER_CONT, | ||
370 | (len & 0x07) | 0x10); | ||
371 | if (rc < 0) | ||
372 | return rc; | ||
373 | |||
374 | /* Test for Busy and ACK */ | ||
375 | do { | ||
376 | rc = usbvision_read_reg(usbvision, USBVISION_SER_CONT); | ||
377 | } while (rc > 0 && ((rc & 0x10) != 0)); /* Retry while busy */ | ||
378 | if (rc < 0) | ||
379 | return rc; | ||
380 | |||
381 | if ((rc & 0x20) == 0) /* Ack? */ | ||
382 | break; | ||
383 | |||
384 | /* I2C abort */ | ||
385 | usbvision_write_reg(usbvision, USBVISION_SER_CONT, 0x00); | ||
386 | |||
387 | if (--retries < 0) | ||
388 | return -1; | ||
389 | |||
390 | } | ||
391 | |||
392 | if (i2c_debug & DBG_I2C) { | ||
393 | int idx; | ||
394 | |||
395 | for (idx = 0; idx < len; idx++) | ||
396 | PDEBUG(DBG_I2C, "wrote %x at address %x", (unsigned char)buf[idx], addr); | ||
397 | } | ||
398 | return len; | ||
399 | } | ||
400 | |||
401 | static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf, | ||
402 | short len) | ||
403 | { | ||
404 | char *buf_ptr = buf; | ||
405 | int retval; | ||
406 | int wrcount = 0; | ||
407 | int count; | ||
408 | int max_len = 4; | ||
409 | |||
410 | while (len > 0) { | ||
411 | count = (len > max_len) ? max_len : len; | ||
412 | retval = usbvision_i2c_write_max4(usbvision, addr, buf_ptr, count); | ||
413 | if (retval > 0) { | ||
414 | len -= count; | ||
415 | buf_ptr += count; | ||
416 | wrcount += count; | ||
417 | } else | ||
418 | return (retval < 0) ? retval : -EFAULT; | ||
419 | } | ||
420 | return wrcount; | ||
421 | } | ||
422 | |||
423 | static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char addr, char *buf, | ||
424 | short len) | ||
425 | { | ||
426 | char temp[4]; | ||
427 | int retval, i; | ||
428 | int rdcount = 0; | ||
429 | int count; | ||
430 | |||
431 | while (len > 0) { | ||
432 | count = (len > 3) ? 4 : len; | ||
433 | retval = usbvision_i2c_read_max4(usbvision, addr, temp, count); | ||
434 | if (retval > 0) { | ||
435 | for (i = 0; i < len; i++) | ||
436 | buf[rdcount + i] = temp[i]; | ||
437 | len -= count; | ||
438 | rdcount += count; | ||
439 | } else | ||
440 | return (retval < 0) ? retval : -EFAULT; | ||
441 | } | ||
442 | return rdcount; | ||
443 | } | ||
444 | |||
445 | static struct i2c_adapter i2c_adap_template = { | ||
446 | .owner = THIS_MODULE, | ||
447 | .name = "usbvision", | ||
448 | }; | ||
449 | |||
450 | /* | ||
451 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
452 | * --------------------------------------------------------------------------- | ||
453 | * Local variables: | ||
454 | * c-basic-offset: 8 | ||
455 | * End: | ||
456 | */ | ||