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