2 tm6000-core.c - driver for TM5600/TM6000 USB video capture devices
4 Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
6 Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
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
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.
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.
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>
29 #include "tm6000-regs.h"
30 #include <media/v4l2-common.h>
31 #include <media/tuner.h>
33 #ifdef HACK /* HACK */
34 #include "tm6000-hack.c"
37 #define USB_TIMEOUT 5*HZ /* ms */
39 int tm6000_read_write_usb (struct tm6000_core *dev, u8 req_type, u8 req,
40 u16 value, u16 index, u8 *buf, u16 len)
44 static int ini=0, last=0, n=0;
48 data = kzalloc(len, GFP_KERNEL);
51 if (req_type & USB_DIR_IN)
52 pipe=usb_rcvctrlpipe(dev->udev, 0);
54 pipe=usb_sndctrlpipe(dev->udev, 0);
55 memcpy(data, buf, len);
58 if (tm6000_debug & V4L2_DEBUG_I2C) {
62 printk("%06i (dev %p, pipe %08x): ", n, dev->udev, pipe);
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,
73 if ( !(req_type & USB_DIR_IN) ) {
76 printk(" %02x",buf[i]);
82 ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index, data,
85 if (req_type & USB_DIR_IN)
86 memcpy(buf, data, len);
88 if (tm6000_debug & V4L2_DEBUG_I2C) {
90 if (req_type & USB_DIR_IN)
91 printk("<<< (len=%d)\n",len);
93 printk("%s: Error #%d\n", __FUNCTION__, ret);
94 } else if (req_type & USB_DIR_IN) {
97 printk(" %02x",buf[i]);
110 int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
113 tm6000_read_write_usb (dev, USB_DIR_OUT | USB_TYPE_VENDOR,
114 req, value, index, NULL, 0);
117 int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
122 rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
123 value, index, buf, 1);
131 int tm6000_get_reg16 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
136 rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
137 value, index, buf, 2);
142 return buf[1]|buf[0]<<8;
145 void tm6000_set_fourcc_format(struct tm6000_core *dev)
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);
151 /* Sets driver to YUV2 */
152 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xc1, 0x90);
156 int tm6000_init_analog_mode (struct tm6000_core *dev)
159 /* Enables soft reset */
160 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x3f, 0x01);
163 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xc0, 0x20);
165 /* Enable Hfilter and disable TS Drop err */
166 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xc0, 0x80);
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);
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);
179 tm6000_set_fourcc_format(dev);
181 /* Disables soft reset */
182 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x3f, 0x00);
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);
188 /* Tuner firmware can now be loaded */
190 tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_1, 0x00);
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);
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);
206 tm6000_set_standard (dev, &dev->norm);
207 tm6000_set_audio_bitrate (dev,48000);
213 int tm6000_init_digital_mode (struct tm6000_core *dev)
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);
230 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
231 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
232 tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
235 tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
237 tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
239 tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
245 /* The meaning of those initializations are unknown */
258 { 0xeb, 0x64 }, /* 48000 bits/sample, external input */
260 { 0x3f, 0x01 }, /* Start of soft reset */
309 { 0x3f, 0x00 }, /* End of the soft reset */
312 int tm6000_init (struct tm6000_core *dev)
316 #ifdef HACK /* HACK */
321 /* Load board's initialization table */
322 for (i=0; i< ARRAY_SIZE(init_tab); i++) {
323 rc= tm6000_set_reg (dev, REQ_07_SET_GET_AVREG,
324 init_tab[i][0],init_tab[i][1]);
326 printk (KERN_ERR "Error %i while setting reg %d to value %d\n",
327 rc, init_tab[i][0],init_tab[i][1]);
332 /* Check board version - maybe 10Moons specific */
333 board=tm6000_get_reg16 (dev, 0x40, 0, 0);
335 printk (KERN_INFO "Board version = 0x%04x\n",board);
337 printk (KERN_ERR "Error %i while retrieving board version\n",board);
340 tm6000_set_reg (dev, REQ_05_SET_GET_USBREG, 0x18, 0x00);
341 msleep(5); /* Just to be conservative */
343 /* Reset GPIO1 and GPIO4. */
344 for (i=0; i< 2; i++) {
345 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_1, 0);
347 printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
351 msleep(10); /* Just to be conservative */
352 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_1, 1);
354 printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
359 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 0);
361 printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
366 rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 1);
368 printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
373 rc=tm6000_get_reg16(dev, 0x40,0,0);
383 int tm6000_set_audio_bitrate (struct tm6000_core *dev, int bitrate)
387 val=tm6000_get_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x0);
388 printk("Original value=%d\n",val);
392 val &= 0x0f; /* Preserve the audio input control bits */
396 dev->audio_bitrate=bitrate;
400 dev->audio_bitrate=bitrate;
403 val=tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, val);