V4L/DVB (12801): tm6000: Add support for ADSTech Mini Dual TV (PTV-339).
[safe/jmp/linux-2.6] / drivers / staging / tm6000 / tm6000-i2c.c
1 /*
2    tm6000-i2c.c - driver for TM5600/TM6000 USB video capture devices
3
4    Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
5
6    Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
7         - Fix SMBus Read Byte command
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 version 2
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/usb.h>
26 #include <linux/i2c.h>
27
28 #include "tm6000.h"
29 #include "tm6000-regs.h"
30 #include <media/v4l2-common.h>
31 #include <media/tuner.h>
32 #include "tuner-xc2028.h"
33
34
35 /*FIXME: Hack to avoid needing to patch i2c-id.h */
36 #define I2C_HW_B_TM6000 I2C_HW_B_EM28XX
37 /* ----------------------------------------------------------- */
38
39 static unsigned int i2c_scan = 0;
40 module_param(i2c_scan, int, 0444);
41 MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
42
43 static unsigned int i2c_debug = 0;
44 module_param(i2c_debug, int, 0644);
45 MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
46
47 #define i2c_dprintk(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
48                         printk(KERN_DEBUG "%s at %s: " fmt, \
49                         dev->name, __FUNCTION__ , ##args); } while (0)
50
51
52 /* Returns 0 if address is found */
53 static int tm6000_i2c_scan(struct i2c_adapter *i2c_adap, int addr)
54 {
55         struct tm6000_core *dev = i2c_adap->algo_data;
56
57 #if 1
58         /* HACK: i2c scan is not working yet */
59         if (
60                 (dev->caps.has_tuner   && (addr==dev->tuner_addr)) ||
61                 (dev->caps.has_tda9874 && (addr==0xb0)) ||
62                 (dev->caps.has_eeprom  && (addr==0xa0))
63            ) {
64                 printk("Hack: enabling device at addr 0x%02x\n",addr);
65                 return (1);
66         } else {
67                 return -ENODEV;
68         }
69 #else
70         int rc=-ENODEV;
71         char buf[1];
72
73         /* This sends addr + 1 byte with 0 */
74         rc = tm6000_read_write_usb (dev,
75                 USB_DIR_IN | USB_TYPE_VENDOR,
76                 REQ_16_SET_GET_I2CSEQ,
77                 addr, 0,
78                 buf, 0);
79         msleep(10);
80
81         if (rc<0) {
82                 if (i2c_debug>=2)
83                         printk("no device at addr 0x%02x\n",addr);
84         }
85
86         printk("Hack: check on addr 0x%02x returned %d\n",addr,rc);
87
88         return rc;
89 #endif
90 }
91
92 static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
93                            struct i2c_msg msgs[], int num)
94 {
95         struct tm6000_core *dev = i2c_adap->algo_data;
96         int addr, rc, i, byte;
97         u8 prev_reg = 0;
98
99         if (num <= 0)
100                 return 0;
101         for (i = 0; i < num; i++) {
102                 addr = (msgs[i].addr << 1) &0xff;
103                 i2c_dprintk(2,"%s %s addr=0x%x len=%d:",
104                          (msgs[i].flags & I2C_M_RD) ? "read" : "write",
105                          i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
106                 if (!msgs[i].len) {
107                         /* Do I2C scan */
108                         rc=tm6000_i2c_scan(i2c_adap, addr);
109                 } else if (msgs[i].flags & I2C_M_RD) {
110                         /* Read bytes */
111         /* I2C is assumed to have always a subaddr at the first byte of the
112            message bus. Also, the first i2c value of the answer is returned
113            out of message data.
114          */
115                         /* SMBus Read Byte command */
116                         if(msgs[i].len == 1) {
117                                 // we use the previously used register to read from
118                                 rc = tm6000_read_write_usb (dev,
119                                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
120                                         REQ_16_SET_GET_I2CSEQ,
121                                         addr | prev_reg<<8, 0,
122                                         msgs[i].buf, msgs[i].len);
123                         }
124                         else {
125                                 rc = tm6000_read_write_usb (dev,
126                                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
127                                         REQ_16_SET_GET_I2CSEQ,
128                                         addr|(*msgs[i].buf)<<8, 0,
129                                         msgs[i].buf, msgs[i].len);
130                         }
131                         if (i2c_debug>=2) {
132                                 for (byte = 0; byte < msgs[i].len; byte++) {
133                                         printk(" %02x", msgs[i].buf[byte]);
134                                 }
135                         }
136                 } else {
137                         /* write bytes */
138                         if (i2c_debug>=2) {
139                                 for (byte = 0; byte < msgs[i].len; byte++)
140                                         printk(" %02x", msgs[i].buf[byte]);
141                         }
142
143                         /* SMBus Write Byte command followed by a read command */
144                         if(msgs[i].len == 1 && i+1 < num && msgs[i+1].flags & I2C_M_RD
145                                             && msgs[i+1].addr == msgs[i].addr) {
146                                 prev_reg = msgs[i].buf[0];
147                                 continue;
148                         }
149
150                         rc = tm6000_read_write_usb (dev,
151                                 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
152                                 REQ_16_SET_GET_I2CSEQ,
153                                 addr|(*msgs[i].buf)<<8, 0,
154                                 msgs[i].buf+1, msgs[i].len-1);
155
156                         if(msgs[i].len >= 1) {
157                                 prev_reg = msgs[i].buf[0];
158                         }
159                         else {
160                                 prev_reg = 0;
161                         }
162                 }
163                 if (i2c_debug>=2)
164                         printk("\n");
165                 if (rc < 0)
166                         goto err;
167         }
168
169         return num;
170 err:
171         i2c_dprintk(2," ERROR: %i\n", rc);
172         return rc;
173 }
174
175
176 static int tm6000_i2c_eeprom( struct tm6000_core *dev,
177                               unsigned char *eedata, int len )
178 {
179         int i, rc;
180         unsigned char *p = eedata;
181         unsigned char bytes[17];
182
183         dev->i2c_client.addr = 0xa0 >> 1;
184
185 //006779:  OUT: 000006 ms 089867 ms c0 0e a0 00 00 00 01 00 <<<  00
186 //006780:  OUT: 000005 ms 089873 ms c0 10 a0 00 00 00 01 00 <<<  00
187 //006781:  OUT: 000108 ms 089878 ms 40 0e a0 00 00 00 01 00 >>>  99
188 //006782:  OUT: 000015 ms 089986 ms c0 0e a0 00 01 00 01 00 <<<  99
189 //006783:  OUT: 000004 ms 090001 ms c0 0e a0 00 10 00 01 00 <<<  99
190 //006784:  OUT: 000005 ms 090005 ms 40 10 a0 00 00 00 01 00 >>>  00
191 //006785:  OUT: 000308 ms 090010 ms 40 0e a0 00 00 00 01 00 >>>  00
192
193
194         for (i = 0; i < len; i++) {
195                 bytes[0x14+i] = 0;
196
197                 rc = i2c_master_recv(&dev->i2c_client, p, 1);
198                 if (rc<1) {
199                         if (p==eedata) {
200                                 printk (KERN_WARNING "%s doesn't have eeprom",
201                                         dev->name);
202                         } else {
203                                 printk(KERN_WARNING
204                                 "%s: i2c eeprom read error (err=%d)\n",
205                                 dev->name, rc);
206                         }
207                         return -1;
208                 }
209                 p++;
210                 if (0 == (i % 16))
211                         printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
212                 printk(" %02x", eedata[i]);
213                 if ((eedata[i]>=' ')&&(eedata[i]<='z')) {
214                         bytes[i%16]=eedata[i];
215                 } else {
216                         bytes[i%16]='.';
217                 }
218                 if (15 == (i % 16)) {
219                         bytes[i%16]='\0';
220                         printk("  %s\n", bytes);
221                 }
222         }
223         if ((i%16)!=15) {
224                 bytes[i%16]='\0';
225                 printk("  %s\n", bytes);
226         }
227         return 0;
228 }
229
230 /* ----------------------------------------------------------- */
231
232 /*
233  * algo_control()
234  */
235 static int algo_control(struct i2c_adapter *adapter,
236                         unsigned int cmd, unsigned long arg)
237 {
238         return 0;
239 }
240
241 /*
242  * functionality()
243  */
244 static u32 functionality(struct i2c_adapter *adap)
245 {
246         return I2C_FUNC_SMBUS_EMUL;
247 }
248
249 #ifndef I2C_PEC
250 static void inc_use(struct i2c_adapter *adap)
251 {
252         MOD_INC_USE_COUNT;
253 }
254
255 static void dec_use(struct i2c_adapter *adap)
256 {
257         MOD_DEC_USE_COUNT;
258 }
259 #endif
260
261 #define mass_write(addr, reg, data...)                                  \
262         { const static u8 _val[] = data;                                \
263         rc=tm6000_read_write_usb(dev,USB_DIR_OUT | USB_TYPE_VENDOR,     \
264         REQ_16_SET_GET_I2CSEQ,(reg<<8)+addr, 0x00, (u8 *) _val,         \
265         ARRAY_SIZE(_val));                                              \
266         if (rc<0) {                                                     \
267                 printk(KERN_ERR "Error on line %d: %d\n",__LINE__,rc);  \
268                 return rc;                                              \
269         }                                                               \
270         msleep (10);                                                    \
271         }
272
273 /* Tuner callback to provide the proper gpio changes needed for xc2028 */
274
275 static int tm6000_tuner_callback(void *ptr, int command, int arg)
276 {
277         int rc=0;
278         struct tm6000_core *dev = ptr;
279
280         if (dev->tuner_type!=TUNER_XC2028)
281                 return 0;
282
283         switch (command) {
284         case XC2028_RESET_CLK:
285                 tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT,
286                                         0x02, arg);
287                 msleep(10);
288                 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
289                                         TM6000_GPIO_CLK, 0);
290                 if (rc<0)
291                         return rc;
292                 msleep(10);
293                 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
294                                         TM6000_GPIO_CLK, 1);
295                 break;
296         case XC2028_TUNER_RESET:
297                 /* Reset codes during load firmware */
298                 switch (arg) {
299                 case 0:
300                         tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
301                                         dev->tuner_reset_gpio, 0x00);
302                         msleep(130);
303                         tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
304                                         dev->tuner_reset_gpio, 0x01);
305                         msleep(130);
306                         break;
307                 case 1:
308                         tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT,
309                                                 0x02, 0x01);
310                         msleep(10);
311                         break;
312
313                 case 2:
314                         rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
315                                                 TM6000_GPIO_CLK, 0);
316                         if (rc<0)
317                                 return rc;
318                         msleep(100);
319                         rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
320                                                 TM6000_GPIO_CLK, 1);
321                         msleep(100);
322                         break;
323                 }
324         }
325         return (rc);
326 }
327
328 static int attach_inform(struct i2c_client *client)
329 {
330         struct tm6000_core *dev = client->adapter->algo_data;
331         struct tuner_setup tun_setup;
332         unsigned char eedata[11];
333
334         i2c_dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
335                 client->driver->driver.name, client->addr, client->name);
336
337         switch (client->addr<<1) {
338         case 0xb0:
339                 request_module("tvaudio");
340                 return 0;
341         }
342
343         /* If tuner, initialize the tuner part */
344         if ( dev->tuner_addr != client->addr<<1 ) {
345                 return 0;
346         }
347
348         memset (&tun_setup, 0, sizeof(tun_setup));
349
350         tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
351         tun_setup.type = dev->tuner_type;
352         tun_setup.addr = dev->tuner_addr>>1;
353         tun_setup.tuner_callback = tm6000_tuner_callback;
354
355         client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
356
357         return 0;
358 }
359
360 static struct i2c_algorithm tm6000_algo = {
361         .master_xfer   = tm6000_i2c_xfer,
362         .algo_control  = algo_control,
363         .functionality = functionality,
364 };
365
366 static struct i2c_adapter tm6000_adap_template = {
367 #ifdef I2C_PEC
368         .owner = THIS_MODULE,
369 #else
370         .inc_use = inc_use,
371         .dec_use = dec_use,
372 #endif
373         .class = I2C_CLASS_TV_ANALOG,
374         .name = "tm6000",
375         .id = I2C_HW_B_TM6000,
376         .algo = &tm6000_algo,
377         .client_register = attach_inform,
378 };
379
380 static struct i2c_client tm6000_client_template = {
381         .name = "tm6000 internal",
382 };
383
384 /* ----------------------------------------------------------- */
385
386 /*
387  * i2c_devs
388  * incomplete list of known devices
389  */
390 static char *i2c_devs[128] = {
391         [0xc2 >> 1] = "tuner (analog)",
392 };
393
394 /*
395  * do_i2c_scan()
396  * check i2c address range for devices
397  */
398 static void do_i2c_scan(char *name, struct i2c_client *c)
399 {
400         unsigned char buf;
401         int i, rc;
402
403         for (i = 0; i < 128; i++) {
404                 c->addr = i;
405                 rc = i2c_master_recv(c, &buf, 0);
406                 if (rc < 0)
407                         continue;
408                 printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name,
409                        i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
410         }
411 }
412
413 /*
414  * tm6000_i2c_call_clients()
415  * send commands to all attached i2c devices
416  */
417 void tm6000_i2c_call_clients(struct tm6000_core *dev, unsigned int cmd, void *arg)
418 {
419         BUG_ON(NULL == dev->i2c_adap.algo_data);
420         i2c_clients_command(&dev->i2c_adap, cmd, arg);
421 }
422
423 /*
424  * tm6000_i2c_register()
425  * register i2c bus
426  */
427 int tm6000_i2c_register(struct tm6000_core *dev)
428 {
429         dev->i2c_adap = tm6000_adap_template;
430         dev->i2c_adap.dev.parent = &dev->udev->dev;
431         strcpy(dev->i2c_adap.name, dev->name);
432         dev->i2c_adap.algo_data = dev;
433         i2c_add_adapter(&dev->i2c_adap);
434
435         dev->i2c_client = tm6000_client_template;
436         dev->i2c_client.adapter = &dev->i2c_adap;
437
438         if (i2c_scan)
439                 do_i2c_scan(dev->name, &dev->i2c_client);
440
441         return 0;
442 }
443
444 /*
445  * tm6000_i2c_unregister()
446  * unregister i2c_bus
447  */
448 int tm6000_i2c_unregister(struct tm6000_core *dev)
449 {
450         i2c_del_adapter(&dev->i2c_adap);
451         return 0;
452 }