V4L/DVB (12788): tm6000: Add initial DVB-T support
[safe/jmp/linux-2.6] / drivers / staging / tm6000 / tm6000-core.c
1 /*
2    tm6000-core.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        - DVB-T support
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 #include <linux/video_decoder.h>
28 #include "tm6000.h"
29 #include "tm6000-regs.h"
30 #include <media/v4l2-common.h>
31 #include <media/tuner.h>
32
33 #ifdef HACK /* HACK */
34 #include "tm6000-hack.c"
35 #endif
36
37 #define USB_TIMEOUT     5*HZ /* ms */
38
39 int tm6000_read_write_usb (struct tm6000_core *dev, u8 req_type, u8 req,
40                            u16 value, u16 index, u8 *buf, u16 len)
41 {
42         int          ret, i;
43         unsigned int pipe;
44         static int   ini=0, last=0, n=0;
45         u8           *data=NULL;
46
47         if (len)
48                 data = kzalloc(len, GFP_KERNEL);
49
50
51         if (req_type & USB_DIR_IN)
52                 pipe=usb_rcvctrlpipe(dev->udev, 0);
53         else {
54                 pipe=usb_sndctrlpipe(dev->udev, 0);
55                 memcpy(data, buf, len);
56         }
57
58         if (tm6000_debug & V4L2_DEBUG_I2C) {
59                 if (!ini)
60                         last=ini=jiffies;
61
62                 printk("%06i (dev %p, pipe %08x): ", n, dev->udev, pipe);
63
64                 printk( "%s: %06u ms %06u ms %02x %02x %02x %02x %02x %02x %02x %02x ",
65                         (req_type & USB_DIR_IN)?" IN":"OUT",
66                         jiffies_to_msecs(jiffies-last),
67                         jiffies_to_msecs(jiffies-ini),
68                         req_type, req,value&0xff,value>>8, index&0xff, index>>8,
69                         len&0xff, len>>8);
70                 last=jiffies;
71                 n++;
72
73                 if ( !(req_type & USB_DIR_IN) ) {
74                         printk(">>> ");
75                         for (i=0;i<len;i++) {
76                                 printk(" %02x",buf[i]);
77                         }
78                         printk("\n");
79                 }
80         }
81
82         ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index, data,
83                               len, USB_TIMEOUT);
84
85         if (req_type &  USB_DIR_IN)
86                 memcpy(buf, data, len);
87
88         if (tm6000_debug & V4L2_DEBUG_I2C) {
89                 if (ret<0) {
90                         if (req_type &  USB_DIR_IN)
91                                 printk("<<< (len=%d)\n",len);
92
93                         printk("%s: Error #%d\n", __FUNCTION__, ret);
94                 } else if (req_type &  USB_DIR_IN) {
95                         printk("<<< ");
96                         for (i=0;i<len;i++) {
97                                 printk(" %02x",buf[i]);
98                         }
99                         printk("\n");
100                 }
101         }
102
103         kfree(data);
104
105         msleep(5);
106
107         return ret;
108 }
109
110 int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
111 {
112         return
113                 tm6000_read_write_usb (dev, USB_DIR_OUT | USB_TYPE_VENDOR,
114                                        req, value, index, NULL, 0);
115 }
116
117 int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
118 {
119         int rc;
120         u8 buf[1];
121
122         rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
123                                        value, index, buf, 1);
124
125         if (rc<0)
126                 return rc;
127
128         return *buf;
129 }
130
131 int tm6000_get_reg16 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
132 {
133         int rc;
134         u8 buf[2];
135
136         rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
137                                        value, index, buf, 2);
138
139         if (rc<0)
140                 return rc;
141
142         return buf[1]|buf[0]<<8;
143 }
144
145 void tm6000_set_fourcc_format(struct tm6000_core *dev)
146 {
147         if (dev->fourcc==V4L2_PIX_FMT_UYVY) {
148                 /* Sets driver to UYUV */
149                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xc1, 0xd0);
150         } else {
151                 /* Sets driver to YUV2 */
152                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xc1, 0x90);
153         }
154 }
155
156 int tm6000_init_analog_mode (struct tm6000_core *dev)
157 {
158
159         /* Enables soft reset */
160         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x3f, 0x01);
161
162         if (dev->scaler) {
163                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xc0, 0x20);
164         } else {
165                 /* Enable Hfilter and disable TS Drop err */
166                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xc0, 0x80);
167         }
168         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xc3, 0x88);
169         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xda, 0x23);
170         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xd1, 0xc0);
171         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xd2, 0xd8);
172         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xd6, 0x06);
173         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xdf, 0x1f);
174
175         /* AP Software reset */
176         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xff, 0x08);
177         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xff, 0x00);
178
179         tm6000_set_fourcc_format(dev);
180
181         /* Disables soft reset */
182         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x3f, 0x00);
183
184         /* E3: Select input 0 - TV tuner */
185         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe3, 0x00);
186         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x60);
187
188         /* Tuner firmware can now be loaded */
189
190         tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_1, 0x00);
191         msleep(11);
192
193         /* This controls input */
194         tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_2, 0x0);
195         tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_3, 0x01);
196         msleep(20);
197
198         /*FIXME: Hack!!! */
199         struct v4l2_frequency f;
200         mutex_lock(&dev->lock);
201         f.frequency=dev->freq;
202         tm6000_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
203         mutex_unlock(&dev->lock);
204
205         msleep(100);
206         tm6000_set_standard (dev, &dev->norm);
207         tm6000_set_audio_bitrate (dev,48000);
208
209
210         return 0;
211 }
212
213 int tm6000_init_digital_mode (struct tm6000_core *dev)
214 {
215         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
216         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
217         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
218         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
219         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
220         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
221         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
222         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
223         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
224         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
225         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
226         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
227         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
228         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
229         msleep(50);
230
231         tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
232         tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
233         tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
234
235         msleep(100);
236
237         return 0;
238 }
239
240 /* The meaning of those initializations are unknown */
241 u8 init_tab[][2] = {
242         /* REG  VALUE */
243         { 0xdf, 0x1f },
244         { 0xff, 0x08 },
245         { 0xff, 0x00 },
246         { 0xd5, 0x4f },
247         { 0xda, 0x23 },
248         { 0xdb, 0x08 },
249         { 0xe2, 0x00 },
250         { 0xe3, 0x10 },
251         { 0xe5, 0x00 },
252         { 0xe8, 0x00 },
253         { 0xeb, 0x64 },         /* 48000 bits/sample, external input */
254         { 0xee, 0xc2 },
255         { 0x3f, 0x01 },         /* Start of soft reset */
256         { 0x00, 0x00 },
257         { 0x01, 0x07 },
258         { 0x02, 0x5f },
259         { 0x03, 0x00 },
260         { 0x05, 0x64 },
261         { 0x07, 0x01 },
262         { 0x08, 0x82 },
263         { 0x09, 0x36 },
264         { 0x0a, 0x50 },
265         { 0x0c, 0x6a },
266         { 0x11, 0xc9 },
267         { 0x12, 0x07 },
268         { 0x13, 0x3b },
269         { 0x14, 0x47 },
270         { 0x15, 0x6f },
271         { 0x17, 0xcd },
272         { 0x18, 0x1e },
273         { 0x19, 0x8b },
274         { 0x1a, 0xa2 },
275         { 0x1b, 0xe9 },
276         { 0x1c, 0x1c },
277         { 0x1d, 0xcc },
278         { 0x1e, 0xcc },
279         { 0x1f, 0xcd },
280         { 0x20, 0x3c },
281         { 0x21, 0x3c },
282         { 0x2d, 0x48 },
283         { 0x2e, 0x88 },
284         { 0x30, 0x22 },
285         { 0x31, 0x61 },
286         { 0x32, 0x74 },
287         { 0x33, 0x1c },
288         { 0x34, 0x74 },
289         { 0x35, 0x1c },
290         { 0x36, 0x7a },
291         { 0x37, 0x26 },
292         { 0x38, 0x40 },
293         { 0x39, 0x0a },
294         { 0x42, 0x55 },
295         { 0x51, 0x11 },
296         { 0x55, 0x01 },
297         { 0x57, 0x02 },
298         { 0x58, 0x35 },
299         { 0x59, 0xa0 },
300         { 0x80, 0x15 },
301         { 0x82, 0x42 },
302         { 0xc1, 0xd0 },
303         { 0xc3, 0x88 },
304         { 0x3f, 0x00 },         /* End of the soft reset */
305 };
306
307 int tm6000_init (struct tm6000_core *dev)
308 {
309         int board, rc=0, i;
310
311 #ifdef HACK /* HACK */
312         init_tm6000(dev);
313         return 0;
314 #else
315
316         /* Load board's initialization table */
317         for (i=0; i< ARRAY_SIZE(init_tab); i++) {
318                 rc= tm6000_set_reg (dev, REQ_07_SET_GET_AVREG,
319                         init_tab[i][0],init_tab[i][1]);
320                 if (rc<0) {
321                         printk (KERN_ERR "Error %i while setting reg %d to value %d\n",
322                         rc, init_tab[i][0],init_tab[i][1]);
323                         return rc;
324                 }
325         }
326
327         /* Check board version - maybe 10Moons specific */
328         board=tm6000_get_reg16 (dev, 0x40, 0, 0);
329         if (board >=0) {
330                 printk (KERN_INFO "Board version = 0x%04x\n",board);
331         } else {
332                 printk (KERN_ERR "Error %i while retrieving board version\n",board);
333         }
334
335         tm6000_set_reg (dev, REQ_05_SET_GET_USBREG, 0x18, 0x00);
336         msleep(5); /* Just to be conservative */
337
338         /* Reset GPIO1 and GPIO4. */
339         for (i=0; i< 2; i++) {
340                 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_1, 0);
341                 if (rc<0) {
342                         printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
343                         return rc;
344                 }
345
346                 msleep(10); /* Just to be conservative */
347                 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_1, 1);
348                 if (rc<0) {
349                         printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
350                         return rc;
351                 }
352
353                 msleep(10);
354                 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 0);
355                 if (rc<0) {
356                         printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
357                         return rc;
358                 }
359
360                 msleep(10);
361                 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 1);
362                 if (rc<0) {
363                         printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
364                         return rc;
365                 }
366
367                 if (!i)
368                         rc=tm6000_get_reg16(dev, 0x40,0,0);
369         }
370
371         msleep(50);
372
373         return 0;
374
375 #endif /* HACK */
376 }
377
378 #define tm6000_wrt(dev,req,reg,val, data...)                            \
379         { const static u8 _val[] = data;                                \
380         tm6000_read_write_usb(dev,USB_DIR_OUT | USB_TYPE_VENDOR,        \
381         req,reg, val, (u8 *) _val, ARRAY_SIZE(_val));                   \
382         }
383
384 /*
385 TM5600/6000 register values to set video standards.
386         There's an adjust, common to all, for composite video
387         Additional adjustments are required for S-Video, based on std.
388
389       Standards values for TV             S-Video Changes
390 REG   PAL   PAL_M PAL_N SECAM NTSC  Comp. PAL  PAL_M PAL_N SECAM NTSC
391 0xdf  0x1f  0x1f  0x1f  0x1f  0x1f
392 0xe2  0x00  0x00  0x00  0x00  0x00
393 0xe8  0x0f  0x0f  0x0f  0x0f  0x0f        0x00 0x00  0x00  0x00  0x00
394 0xeb  0x60  0x60  0x60  0x60  0x60  0x64  0x64 0x64  0x64  0x64  0x64
395 0xd5  0x5f  0x5f  0x5f  0x4f  0x4f        0x4f 0x4f  0x4f  0x4f  0x4f
396 0xe3  0x00  0x00  0x00  0x00  0x00  0x10  0x10 0x10  0x10  0x10  0x10
397 0xe5  0x00  0x00  0x00  0x00  0x00        0x10 0x10  0x10  0x10  0x10
398 0x3f  0x01  0x01  0x01  0x01  0x01
399 0x00  0x32  0x04  0x36  0x38  0x00        0x33 0x05  0x37  0x39  0x01
400 0x01  0x0e  0x0e  0x0e  0x0e  0x0f
401 0x02  0x5f  0x5f  0x5f  0x5f  0x5f
402 0x03  0x02  0x00  0x02  0x02  0x00        0x04 0x04  0x04  0x03  0x03
403 0x07  0x01  0x01  0x01  0x01  0x01        0x00                   0x00
404 0x17  0xcd  0xcd  0xcd  0xcd  0xcd                               0x8b
405 0x18  0x25  0x1e  0x1e  0x24  0x1e
406 0x19  0xd5  0x83  0x91  0x92  0x8b
407 0x1a  0x63  0x0a  0x1f  0xe8  0xa2
408 0x1b  0x50  0xe0  0x0c  0xed  0xe9
409 0x1c  0x1c  0x1c  0x1c  0x1c  0x1c
410 0x1d  0xcc  0xcc  0xcc  0xcc  0xcc
411 0x1e  0xcc  0xcc  0xcc  0xcc  0xcc
412 0x1f  0xcd  0xcd  0xcd  0xcd  0xcd
413 0x2e  0x8c  0x88  0x8c  0x8c  0x88                   0x88
414 0x30  0x2c  0x20  0x2c  0x2c  0x22        0x2a 0x22  0x22  0x2a
415 0x31  0xc1  0x61  0xc1  0xc1  0x61
416 0x33  0x0c  0x0c  0x0c  0x2c  0x1c
417 0x35  0x1c  0x1c  0x1c  0x18  0x1c
418 0x82  0x52  0x52  0x52  0x42  0x42
419 0x04  0xdc  0xdc  0xdc        0xdd
420 0x0d  0x07  0x07  0x07  0x87  0x07
421 0x3f  0x00  0x00  0x00  0x00  0x00
422 */
423
424 int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm)
425 {
426         dev->norm=*norm;
427
428         /* HACK: Should use, instead, the common code!!! */
429         if (*norm & V4L2_STD_PAL_M) {
430                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xdf, 0x1f);
431                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe2, 0x00);
432                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe8, 0x0f);
433                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x60);
434                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xd5, 0x5f);
435                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe3, 0x00);
436                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe5, 0x00);
437                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x3f, 0x01);
438                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x04);
439                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x01, 0x0e);
440                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x02, 0x5f);
441                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x00);
442                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x07, 0x01);
443                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x18, 0x1e);
444                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x19, 0x83);
445                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1a, 0x0a);
446                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1b, 0xe0);
447                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1c, 0x1c);
448                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1d, 0xcc);
449                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1e, 0xcc);
450                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1f, 0xcd);
451                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x2e, 0x88);
452                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x20);
453                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x31, 0x61);
454                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x33, 0x0c);
455                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x35, 0x1c);
456                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x82, 0x52);
457                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x04, 0xdc);
458                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x0d, 0x07);
459                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x3f, 0x00);
460                 return 0;
461         }
462
463         /* */
464 //      tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x01);
465 //      tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00);
466
467         /* Set registers common to all standards */
468         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xdf, 0x1f);
469         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe2, 0x00);
470
471         switch (dev->input) {
472         case TM6000_INPUT_TV:
473                 /* Seems to disable ADC2 - needed for TV and RCA */
474                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe8, 0x0f);
475
476                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x60);
477
478                 if (*norm & V4L2_STD_PAL) {
479                         /* Enable UV_FLT_EN */
480                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xd5, 0x5f);
481                 } else {
482                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xd5, 0x4f);
483                 }
484
485                 /* E3: Select input 0 */
486                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe3, 0x00);
487
488                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe5, 0x10);
489
490                 break;
491         case TM6000_INPUT_COMPOSITE:
492                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x64);
493                 /* E3: Select input 1 */
494                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe3, 0x10);
495                 break;
496         case TM6000_INPUT_SVIDEO:
497                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe8, 0x00);
498
499                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x64);
500
501                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xd5, 0x4f);
502                 /* E3: Select input 1 */
503                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe3, 0x10);
504
505                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xe5, 0x10);
506
507                 break;
508         }
509
510         /* Software reset */
511         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x3f, 0x01);
512
513         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x02, 0x5f);
514
515         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x07, 0x01);
516 //      tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x17, 0xcd);
517
518         /* Horizontal Sync DTO = 0x1ccccccd */
519         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1c, 0x1c);
520         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1d, 0xcc);
521         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1e, 0xcc);
522         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1f, 0xcd);
523
524         /* Vertical Height */
525         if (*norm & V4L2_STD_525_60) {
526                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x31, 0x61);
527         } else {
528                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x31, 0xc1);
529         }
530
531         /* Horizontal Length */
532         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x2f, 640/8);
533
534         if (*norm & V4L2_STD_PAL) {
535                 /* Common to All PAL Standards */
536
537                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x01, 0x0e);
538
539                 /* Vsync Hsinc Lockout End */
540                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x33, 0x0c);
541
542                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x35, 0x1c);
543                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x82, 0x52);
544                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x04, 0xdc);
545                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x0d, 0x07);
546                 if (*norm & V4L2_STD_PAL_M) {
547
548                         /* Chroma DTO */
549                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x18, 0x1e);
550                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x19, 0x83);
551                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1a, 0x0a);
552                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1b, 0xe0);
553
554                         /* Active Video Horiz Start Time */
555                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x2e, 0x88);
556
557                         if (dev->input==TM6000_INPUT_SVIDEO) {
558                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x05);
559                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x04);
560                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x22);
561                         } else {
562                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x04);
563                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x00);
564                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x20);
565                         }
566                 } else if (*norm & V4L2_STD_PAL_N) {
567                         /* Chroma DTO */
568                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x18, 0x1e);
569                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x19, 0x91);
570                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1a, 0x1f);
571                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1b, 0x0c);
572
573                         if (dev->input==TM6000_INPUT_SVIDEO) {
574                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x37);
575                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x04);
576                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x2e, 0x88);
577                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x22);
578                         } else {
579                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x36);
580                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x02);
581                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x2e, 0x8c);
582                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x2c);
583                         }
584                 } else {        // Other PAL standards
585                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x18, 0x25);
586                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x19, 0xd5);
587                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1a, 0x63);
588                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1b, 0x50);
589                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x2e, 0x8c);
590
591                         if (dev->input==TM6000_INPUT_SVIDEO) {
592                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x33);
593                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x04);
594                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x2a);
595
596                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x2c);
597                         } else {
598                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x32);
599                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x02);
600                                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x2c);
601                         }
602                 }
603         } if (*norm & V4L2_STD_SECAM) {
604                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x01, 0x0e);
605                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x18, 0x24);
606                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x19, 0x92);
607                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1a, 0xe8);
608                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1b, 0xed);
609                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x2e, 0x8c);
610
611                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x33, 0x2c);
612                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x35, 0x18);
613                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x82, 0x42);
614                 // Register 0x04 is not initialized on SECAM
615                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x0d, 0x87);
616
617                 if (dev->input==TM6000_INPUT_SVIDEO) {
618                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x39);
619                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x03);
620                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x2a);
621                 } else {
622                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x38);
623                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x02);
624                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x2c);
625                 }
626         } else {        /* NTSC */
627                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x01, 0x0f);
628                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x18, 0x1e);
629                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x19, 0x8b);
630                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1a, 0xa2);
631                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x1b, 0xe9);
632                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x2e, 0x88);
633                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x30, 0x22);
634
635                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x33, 0x1c);
636                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x35, 0x1c);
637                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x82, 0x42);
638                 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x0d, 0x07);
639                 if (dev->input==TM6000_INPUT_SVIDEO) {
640                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x01);
641                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x03);
642
643                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x07, 0x00);
644                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x17, 0x8b);
645                 } else {
646                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00, 0x00);
647                         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x03, 0x00);
648                 }
649         }
650
651
652         /* End of software reset */
653         tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x3f, 0x00);
654
655         msleep(40);
656
657         return 0;
658 }
659
660 int tm6000_set_audio_bitrate (struct tm6000_core *dev, int bitrate)
661 {
662         int val;
663
664         val=tm6000_get_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x0);
665 printk("Original value=%d\n",val);
666         if (val<0)
667                 return val;
668
669         val &= 0x0f;            /* Preserve the audio input control bits */
670         switch (bitrate) {
671         case 44100:
672                 val|=0xd0;
673                 break;
674         case 48000:
675                 val|=0x60;
676                 break;
677         }
678         val=tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, val);
679
680         return val;
681 }