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