* [PATCH] - tm6000 DVB support
@ 2010-02-01 20:20 Stefan Ringel
2010-02-01 20:35 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-01 20:20 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Devin Heitmueller
[-- Attachment #1: Type: text/plain, Size: 45 bytes --]
--
Stefan Ringel <stefan.ringel@arcor.de>
[-- Attachment #2: tm6000.patch --]
[-- Type: text/x-patch, Size: 35947 bytes --]
add Terratec Cinergy Hybrid XE
bugfix i2c transfer
add frontend callback
add init for tm6010
add digital-init for tm6010
add callback for analog/digital switch
bugfix usb transfer in DVB-mode
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index ed50168..2297c00 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <media/tuner.h>
#include <linux/mutex.h>
+#include "compat.h"
#include <asm/unaligned.h>
#include "tuner-i2c.h"
#include "tuner-xc2028.h"
@@ -994,6 +995,13 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
buf[0], buf[1], buf[2], buf[3],
freq / 1000000, (freq % 1000000) / 1000);
+ if (priv->ctrl.switch_mode) {
+ if (new_mode == T_ANALOG_TV)
+ do_tuner_callback(fe, SWITCH_TV_MODE, 0);
+ if (new_mode == T_DIGITAL_TV)
+ do_tuner_callback(fe, SWITCH_TV_MODE, 1);
+ }
+
rc = 0;
ret:
@@ -1114,7 +1122,11 @@ static int xc2028_set_params(struct dvb_frontend *fe,
/* All S-code tables need a 200kHz shift */
if (priv->ctrl.demod) {
- demod = priv->ctrl.demod + 200;
+ if (priv->ctrl.fname == "xc3028L-v36.fw") {
+ demod = priv->ctrl.demod;
+ } else {
+ demod = priv->ctrl.demod + 200;
+ }
/*
* The DTV7 S-code table needs a 700 kHz shift.
* Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
@@ -1123,8 +1135,8 @@ static int xc2028_set_params(struct dvb_frontend *fe,
* use this firmware after initialization, but a tune to a UHF
* channel should then cause DTV78 to be used.
*/
- if (type & DTV7)
- demod += 500;
+ if (type & DTV7)
+ demod += 500;
}
return generic_set_freq(fe, p->frequency,
@@ -1240,6 +1252,10 @@ static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
.get_rf_strength = xc2028_signal,
.set_params = xc2028_set_params,
.sleep = xc2028_sleep,
+#if 0
+ int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
+ int (*get_status)(struct dvb_frontend *fe, u32 *status);
+#endif
};
struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/common/tuners/tuner-xc2028.h b/drivers/media/common/tuners/tuner-xc2028.h
index 9778c96..c9a4fb4 100644
--- a/drivers/media/common/tuners/tuner-xc2028.h
+++ b/drivers/media/common/tuners/tuner-xc2028.h
@@ -42,6 +42,7 @@ struct xc2028_ctrl {
unsigned int disable_power_mgmt:1;
unsigned int read_not_reliable:1;
unsigned int demod;
+ unsigned int switch_mode:1;
enum firmware_type type:2;
};
@@ -54,6 +55,7 @@ struct xc2028_config {
/* xc2028 commands for callback */
#define XC2028_TUNER_RESET 0
#define XC2028_RESET_CLK 1
+#define SWITCH_TV_MODE 2
#if defined(CONFIG_MEDIA_TUNER_XC2028) || (defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
index 6e3ca9e..015bc36 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -45,6 +45,8 @@ struct zl10353_config
/* clock control registers (0x51-0x54) */
u8 clock_ctl_1; /* default: 0x46 */
u8 pll_0; /* default: 0x15 */
+
+ int tm6000:1;
};
#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
diff --git a/drivers/staging/tm6000/hack.c b/drivers/staging/tm6000/hack.c
index f181fce..c1e1880 100644
--- a/drivers/staging/tm6000/hack.c
+++ b/drivers/staging/tm6000/hack.c
@@ -37,7 +37,6 @@ static inline int tm6000_snd_control_msg(struct tm6000_core *dev, __u8 request,
static int pseudo_zl10353_pll(struct tm6000_core *tm6000_dev, struct dvb_frontend_parameters *p)
{
- int ret;
u8 *data = kzalloc(50*sizeof(u8), GFP_KERNEL);
printk(KERN_ALERT "should set frequency %u\n", p->frequency);
@@ -51,7 +50,7 @@ printk(KERN_ALERT "and bandwith %u\n", p->u.ofdm.bandwidth);
}
// init ZL10353
- data[0] = 0x0b;
+/* data[0] = 0x0b;
ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x501e, 0x00, data, 0x1);
msleep(15);
data[0] = 0x80;
@@ -159,7 +158,7 @@ printk(KERN_ALERT "and bandwith %u\n", p->u.ofdm.bandwidth);
msleep(15);
data[0] = 0x5a;
ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x651e, 0x00, data, 0x1);
- msleep(15);
+ msleep(15)
data[0] = 0xe9;
ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x661e, 0x00, data, 0x1);
msleep(15);
@@ -189,7 +188,162 @@ printk(KERN_ALERT "and bandwith %u\n", p->u.ofdm.bandwidth);
msleep(15);
break;
}
-
+*/
+ switch(p->u.ofdm.bandwidth) {
+ case BANDWIDTH_8_MHZ:
+ data[0] = 0x03;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
+ msleep(40);
+ data[0] = 0x44;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x46;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
+ msleep(40);
+ data[0] = 0x15;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
+ msleep(40);
+ data[0] = 0x0f;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
+ msleep(40);
+ data[0] = 0x80;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x00;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x8b;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
+ msleep(40);
+ data[0] = 0x75;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
+ msleep(40);
+ data[0] = 0xe6; //0x19;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x09; //0xf7;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
+ msleep(40);
+ data[0] = 0x67;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
+ msleep(40);
+ data[0] = 0xe5;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
+ msleep(40);
+ data[0] = 0x75;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x17;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
+ msleep(40);
+ break;
+ case BANDWIDTH_7_MHZ:
+ data[0] = 0x03;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
+ msleep(40);
+ data[0] = 0x44;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x46;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
+ msleep(40);
+ data[0] = 0x15;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
+ msleep(40);
+ data[0] = 0x0f;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
+ msleep(40);
+ data[0] = 0x80;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x00;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x83;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
+ msleep(40);
+ data[0] = 0xa3;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
+ msleep(40);
+ data[0] = 0xe6; //0x19;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x09; //0xf7;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
+ msleep(40);
+ data[0] = 0x5a;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
+ msleep(40);
+ data[0] = 0xe9;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
+ msleep(40);
+ data[0] = 0x86;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x17;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
+ msleep(40);
+ break;
+ default:
+ printk(KERN_ALERT "tm6000: bandwidth not supported\n");
+ }
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0f1f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x091f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0b1f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
kfree(data);
return 0;
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 59fb505..652a54a 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -32,7 +32,7 @@
#include "tm6000.h"
#include "tm6000-regs.h"
#include "tuner-xc2028.h"
-#include "tuner-xc5000.h"
+#include "xc5000.h"
#define TM6000_BOARD_UNKNOWN 0
#define TM5600_BOARD_GENERIC 1
@@ -44,6 +44,10 @@
#define TM6000_BOARD_FREECOM_AND_SIMILAR 7
#define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
#define TM6010_BOARD_HAUPPAUGE_900H 9
+#define TM6010_BOARD_BEHOLD_WANDER 10
+#define TM6010_BOARD_BEHOLD_VOYAGER 11
+#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
+
#define TM6000_MAXBOARDS 16
static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
@@ -208,7 +212,21 @@ struct tm6000_board tm6000_boards[] = {
},
.gpio_addr_tun_reset = TM6000_GPIO_2,
},
-
+ [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
+ .name = "Terratec Cinergy Hybrid XE",
+ .tuner_type = TUNER_XC2028, /* has a XC3028 */
+ .tuner_addr = 0xc2 >> 1,
+ .demod_addr = 0x1e >> 1,
+ .type = TM6010,
+ .caps = {
+ .has_tuner = 1,
+ .has_dvb = 1,
+ .has_zl10353 = 1,
+ .has_eeprom = 1,
+ .has_remote = 1,
+ },
+ .gpio_addr_tun_reset = TM6010_GPIO_2,
+ }
};
/* table of devices that work with this driver */
@@ -221,12 +239,13 @@ struct usb_device_id tm6000_id_table [] = {
{ USB_DEVICE(0x2040, 0x6600), .driver_info = TM6010_BOARD_HAUPPAUGE_900H },
{ USB_DEVICE(0x6000, 0xdec0), .driver_info = TM6010_BOARD_BEHOLD_WANDER },
{ USB_DEVICE(0x6000, 0xdec1), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER },
+ { USB_DEVICE(0x0ccd, 0x0086), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
{ },
};
/* Tuner callback to provide the proper gpio changes needed for xc2028 */
-static int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
+int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
{
int rc=0;
struct tm6000_core *dev = ptr;
@@ -252,11 +271,14 @@ static int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
switch (arg) {
case 0:
tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ dev->tuner_reset_gpio, 0x01);
+ msleep(60);
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
dev->tuner_reset_gpio, 0x00);
- msleep(130);
+ msleep(75);
tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
dev->tuner_reset_gpio, 0x01);
- msleep(130);
+ msleep(60);
break;
case 1:
tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT,
@@ -269,13 +291,33 @@ static int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
TM6000_GPIO_CLK, 0);
if (rc<0)
return rc;
- msleep(100);
+ msleep(10);
rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
TM6000_GPIO_CLK, 1);
- msleep(100);
+ msleep(10);
+ break;
+ }
+ break;
+
+ case SWITCH_TV_MODE:
+ /* switch between analog and digital */
+ switch (arg) {
+ case 0:
+ printk(KERN_INFO "switch to analog");
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 1);
+ printk(KERN_INFO "analog");
+ break;
+ case 1:
+ printk(KERN_INFO "switch to digital");
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 0);
+ printk(KERN_INFO "digital");
break;
}
+ break;
}
+
return (rc);
}
@@ -290,7 +332,7 @@ static void tm6000_config_tuner (struct tm6000_core *dev)
memset(&tun_setup, 0, sizeof(tun_setup));
tun_setup.type = dev->tuner_type;
tun_setup.addr = dev->tuner_addr;
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+ tun_setup.mode_mask = T_ANALOG_TV | T_RADIO | T_DIGITAL_TV;
tun_setup.tuner_callback = tm6000_tuner_callback;
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
@@ -302,15 +344,19 @@ static void tm6000_config_tuner (struct tm6000_core *dev)
memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
memset (&ctl,0,sizeof(ctl));
- ctl.mts = 1;
- ctl.read_not_reliable = 1;
+ ctl.input1 = 1;
+ ctl.read_not_reliable = 0;
ctl.msleep = 10;
-
+ ctl.demod = XC3028_FE_ZARLINK456;
+ ctl.vhfbw7 = 1;
+ ctl.uhfbw8 = 1;
+ ctl.switch_mode = 1;
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
switch(dev->model) {
case TM6010_BOARD_HAUPPAUGE_900H:
+ case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
ctl.fname = "xc3028L-v36.fw";
break;
default:
@@ -402,6 +448,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
}
#endif
}
+ return 0;
err2:
v4l2_device_unregister(&dev->v4l2_dev);
@@ -459,13 +506,13 @@ static int tm6000_usb_probe(struct usb_interface *interface,
/* Check to see next free device and mark as used */
nr=find_first_zero_bit(&tm6000_devused,TM6000_MAXBOARDS);
if (nr >= TM6000_MAXBOARDS) {
- printk ("tm6000: Supports only %i em28xx boards.\n",TM6000_MAXBOARDS);
+ printk ("tm6000: Supports only %i tm60xx boards.\n",TM6000_MAXBOARDS);
usb_put_dev(usbdev);
return -ENOMEM;
}
/* Create and initialize dev struct */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*(dev)), GFP_KERNEL);
if (dev == NULL) {
printk ("tm6000" ": out of memory!\n");
usb_put_dev(usbdev);
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index d41af1d..33bbbd3 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -219,33 +219,53 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
int tm6000_init_digital_mode (struct tm6000_core *dev)
{
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
-
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
- msleep(50);
-
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
- msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
- msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
- msleep(100);
-
+ if (dev->dev_type == TM6010) {
+ int val;
+ u8 buf[2];
+
+ /* digital init */
+ val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, 0);
+ val &= ~0x60;
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, val);
+ val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, 0);
+ val |= 0x40;
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, val);
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xfe, 0x28);
+ tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe2, 0xfc);
+ tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe6, 0xff);
+ tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xf1, 0xfe);
+ tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
+ printk (KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
+
+
+ } else {
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
+
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
+ msleep(50);
+
+ tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ msleep(50);
+ tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
+ msleep(50);
+ tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ msleep(100);
+ }
return 0;
}
@@ -394,7 +414,15 @@ struct reg_init tm6010_init_tab[] = {
{ REQ_07_SET_GET_AVREG, 0x3f, 0x00 },
{ REQ_05_SET_GET_USBREG, 0x18, 0x00 },
-
+
+ /* additional from Terratec Cinergy Hybrid XE */
+ { REQ_07_SET_GET_AVREG, 0xdc, 0xaa },
+ { REQ_07_SET_GET_AVREG, 0xdd, 0x30 },
+ { REQ_07_SET_GET_AVREG, 0xde, 0x20 },
+ { REQ_07_SET_GET_AVREG, 0xdf, 0xd0 },
+ { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 },
+ { REQ_07_SET_GET_AVREG, 0xd8, 0x2f },
+
/* set remote wakeup key:any key wakeup */
{ REQ_07_SET_GET_AVREG, 0xe5, 0xfe },
{ REQ_07_SET_GET_AVREG, 0xda, 0xff },
@@ -404,6 +432,7 @@ int tm6000_init (struct tm6000_core *dev)
{
int board, rc=0, i, size;
struct reg_init *tab;
+ u8 buf[40];
if (dev->dev_type == TM6010) {
tab = tm6010_init_tab;
@@ -424,61 +453,129 @@ int tm6000_init (struct tm6000_core *dev)
}
}
- msleep(5); /* Just to be conservative */
-
- /* Check board version - maybe 10Moons specific */
- board=tm6000_get_reg16 (dev, 0x40, 0, 0);
- if (board >=0) {
- printk (KERN_INFO "Board version = 0x%04x\n",board);
- } else {
- printk (KERN_ERR "Error %i while retrieving board version\n",board);
- }
-
+ /* hack */
if (dev->dev_type == TM6010) {
- /* Turn xceive 3028 on */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6010_GPIO_3, 0x01);
- msleep(11);
- }
-
- /* Reset GPIO1 and GPIO4. */
- for (i=0; i< 2; i++) {
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->tuner_reset_gpio, 0x00);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
- return rc;
- }
-
- msleep(10); /* Just to be conservative */
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->tuner_reset_gpio, 0x01);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
- return rc;
- }
-
- msleep(10);
- rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 0);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
- return rc;
- }
-
- msleep(10);
- rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 1);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
- return rc;
- }
-
- if (!i) {
- rc=tm6000_get_reg16(dev, 0x40,0,0);
- if (rc>=0) {
- printk ("board=%d\n", rc);
+
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_4, 0);
+ msleep(15);
+
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 0);
+
+ msleep(50);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 1);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x0010, 0x4400, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
+
+ msleep(15);
+ buf[0] = 0x12;
+ buf[1] = 0x34;
+ tm6000_read_write_usb (dev, 0x40, 0x10, 0xf432, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0x0032, 0x0000, buf, 2);
+
+ msleep(15);
+ buf[0] = 0x00;
+ buf[1] = 0x01;
+ tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0x00c0, 0x0000, buf, 39);
+
+ msleep(15);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0x7f1f, 0x0000, buf, 2);
+// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf [1]);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_4, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_0, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_7, 0);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 1);
+
+ msleep(15);
+
+ for (i=0; i< size; i++) {
+ rc= tm6000_set_reg (dev, tab[i].req, tab[i].reg, tab[i].val);
+ if (rc<0) {
+ printk (KERN_ERR "Error %i while setting req %d, "
+ "reg %d to value %d\n", rc,
+ tab[i].req,tab[i].reg, tab[i].val);
+ return rc;
}
}
+
+ msleep(15);
+
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_4, 0);
+ msleep(15);
+
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 0);
+
+ msleep(50);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 1);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
+// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 0);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 0);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
}
+ /* hack end */
+
+ msleep(5); /* Just to be conservative */
+ /* Check board version - maybe 10Moons specific */
+ if (dev->dev_type == TM5600) {
+ board=tm6000_get_reg16 (dev, 0x40, 0, 0);
+ if (board >=0) {
+ printk (KERN_INFO "Board version = 0x%04x\n",board);
+ } else {
+ printk (KERN_ERR "Error %i while retrieving board version\n",board);
+ }
+ }
+
msleep(50);
return 0;
diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c
index e900d6d..31458d3 100644
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -17,7 +17,9 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/kernel.h>
#include <linux/usb.h>
+#include <compat.h>
#include "tm6000.h"
#include "tm6000-regs.h"
@@ -30,17 +32,61 @@
#include "tuner-xc2028.h"
+static void inline print_err_status (struct tm6000_core *dev,
+ int packet, int status)
+{
+ char *errmsg = "Unknown";
+
+ switch(status) {
+ case -ENOENT:
+ errmsg = "unlinked synchronuously";
+ break;
+ case -ECONNRESET:
+ errmsg = "unlinked asynchronuously";
+ break;
+ case -ENOSR:
+ errmsg = "Buffer error (overrun)";
+ break;
+ case -EPIPE:
+ errmsg = "Stalled (device not responding)";
+ break;
+ case -EOVERFLOW:
+ errmsg = "Babble (bad cable?)";
+ break;
+ case -EPROTO:
+ errmsg = "Bit-stuff error (bad cable?)";
+ break;
+ case -EILSEQ:
+ errmsg = "CRC/Timeout (could be anything)";
+ break;
+ case -ETIME:
+ errmsg = "Device does not respond";
+ break;
+ }
+ if (packet<0) {
+ dprintk(dev, 1, "URB status %d [%s].\n",
+ status, errmsg);
+ } else {
+ dprintk(dev, 1, "URB packet %d, status %d [%s].\n",
+ packet, status, errmsg);
+ }
+}
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+static void tm6000_urb_received(struct urb *urb, struct pt_regs *ptregs)
+#else
static void tm6000_urb_received(struct urb *urb)
+#endif
{
int ret;
struct tm6000_core* dev = urb->context;
- if(urb->status != 0){
- printk(KERN_ERR "tm6000: status != 0\n");
+ if(urb->status != 0) {
+ print_err_status (dev,0,urb->status);
}
else if(urb->actual_length>0){
- dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
- urb->actual_length);
+ dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, urb->actual_length);
}
if(dev->dvb->streams > 0) {
@@ -56,49 +102,37 @@ static void tm6000_urb_received(struct urb *urb)
int tm6000_start_stream(struct tm6000_core *dev)
{
int ret;
- unsigned int pipe, maxPaketSize;
+ unsigned int pipe, size;
struct tm6000_dvb *dvb = dev->dvb;
printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
tm6000_init_digital_mode(dev);
-/*
- ret = tm6000_set_led_status(tm6000_dev, 0x1);
- if(ret < 0) {
- return -1;
- }
-*/
-
dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
if(dvb->bulk_urb == NULL) {
printk(KERN_ERR "tm6000: couldn't allocate urb\n");
return -ENOMEM;
}
- maxPaketSize = dev->bulk_in->desc.wMaxPacketSize;
+ pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
+ & USB_ENDPOINT_NUMBER_MASK);
+
+ size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
+ size = size * 15; // 512 x 8 or 12 or 15
- dvb->bulk_urb->transfer_buffer = kzalloc(maxPaketSize, GFP_KERNEL);
+ dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
if(dvb->bulk_urb->transfer_buffer == NULL) {
usb_free_urb(dvb->bulk_urb);
printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
return -ENOMEM;
}
-
- pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
- & USB_ENDPOINT_NUMBER_MASK);
-
+
usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
dvb->bulk_urb->transfer_buffer,
- maxPaketSize,
+ size,
tm6000_urb_received, dev);
- ret = usb_set_interface(dev->udev, 0, 1);
- if(ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during set interface\n", ret, __FUNCTION__);
- return ret;
- }
-
ret = usb_clear_halt(dev->udev, pipe);
if(ret < 0) {
printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",ret,__FUNCTION__);
@@ -107,15 +141,14 @@ int tm6000_start_stream(struct tm6000_core *dev)
else {
printk(KERN_ERR "tm6000: pipe resetted\n");
}
-
-// mutex_lock(&tm6000_driver.open_close_mutex);
+
+// mutex_lock(&tm6000_driver.open_close_mutex);
ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
-
-// mutex_unlock(&tm6000_driver.open_close_mutex);
+// mutex_unlock(&tm6000_driver.open_close_mutex);
if (ret) {
printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",ret);
-
+
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
return ret;
@@ -126,18 +159,12 @@ int tm6000_start_stream(struct tm6000_core *dev)
void tm6000_stop_stream(struct tm6000_core *dev)
{
- int ret;
struct tm6000_dvb *dvb = dev->dvb;
-// tm6000_set_led_status(tm6000_dev, 0x0);
-
- ret = usb_set_interface(dev->udev, 0, 0);
- if(ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during set interface\n",ret,__FUNCTION__);
- }
-
if(dvb->bulk_urb) {
+ printk (KERN_INFO "urb killing\n");
usb_kill_urb(dvb->bulk_urb);
+ printk (KERN_INFO "urb buffer free\n");
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
dvb->bulk_urb = NULL;
@@ -154,7 +181,7 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
mutex_lock(&dvb->mutex);
if(dvb->streams == 0) {
dvb->streams = 1;
-// mutex_init(&tm6000_dev->streaming_mutex);
+// mutex_init(&tm6000_dev->streming_mutex);
tm6000_start_stream(dev);
}
else {
@@ -173,14 +200,17 @@ int tm6000_stop_feed(struct dvb_demux_feed *feed) {
printk(KERN_INFO "tm6000: got stop feed request %s\n",__FUNCTION__);
mutex_lock(&dvb->mutex);
- --dvb->streams;
- if(0 == dvb->streams) {
+ printk (KERN_INFO "stream %#x\n", dvb->streams);
+ --(dvb->streams);
+ if(dvb->streams == 0) {
+ printk (KERN_INFO "stop stream\n");
tm6000_stop_stream(dev);
-// mutex_destroy(&tm6000_dev->streaming_mutex);
+// mutex_destroy(&tm6000_dev->streaming_mutex);
}
+
mutex_unlock(&dvb->mutex);
-// mutex_destroy(&tm6000_dev->streaming_mutex);
+// mutex_destroy(&tm6000_dev->streaming_mutex);
return 0;
}
@@ -191,13 +221,16 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
if(dev->caps.has_zl10353) {
struct zl10353_config config =
- {.demod_address = dev->demod_addr >> 1,
+ {.demod_address = dev->demod_addr,
.no_tuner = 1,
-// .input_frequency = 0x19e9,
-// .r56_agc_targets = 0x1c,
+ .parallel_ts = 1,
+ .if2 = 45700,
+ .disable_i2c_gate_ctrl = 1,
+ .tm6000 = 1,
};
dvb->frontend = pseudo_zl10353_attach(dev, &config,
+// dvb->frontend = dvb_attach (zl10353_attach, &config,
&dev->i2c_adap);
}
else {
@@ -235,7 +268,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
.i2c_adap = &dev->i2c_adap,
.i2c_addr = dev->tuner_addr,
};
-
+
+ dvb->frontend->callback = tm6000_tuner_callback;
ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
if (ret < 0) {
printk(KERN_ERR
@@ -258,8 +292,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
| DMX_MEMORY_BASED_FILTERING;
dvb->demux.priv = dev;
- dvb->demux.filternum = 256;
- dvb->demux.feednum = 256;
+ dvb->demux.filternum = 5; //256;
+ dvb->demux.feednum = 5; //256;
dvb->demux.start_feed = tm6000_start_feed;
dvb->demux.stop_feed = tm6000_stop_feed;
dvb->demux.write_to_decoder = NULL;
@@ -307,7 +341,7 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
usb_free_urb(bulk_urb);
}
-// mutex_lock(&tm6000_driver.open_close_mutex);
+// mutex_lock(&tm6000_driver.open_close_mutex);
if(dvb->frontend) {
dvb_frontend_detach(dvb->frontend);
dvb_unregister_frontend(dvb->frontend);
@@ -317,6 +351,6 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
dvb_dmx_release(&dvb->demux);
dvb_unregister_adapter(&dvb->adapter);
mutex_destroy(&dvb->mutex);
-// mutex_unlock(&tm6000_driver.open_close_mutex);
+// mutex_unlock(&tm6000_driver.open_close_mutex);
}
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
index 4da10f5..3e43ad7 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -86,6 +86,11 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
msgs[i].len == 1 ? 0 : msgs[i].buf[1],
msgs[i + 1].buf, msgs[i + 1].len);
i++;
+
+ if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
+ tm6000_set_reg(dev, 0x32, 0,0);
+ tm6000_set_reg(dev, 0x33, 0,0);
+ }
if (i2c_debug >= 2)
for (byte = 0; byte < msgs[i].len; byte++)
printk(" %02x", msgs[i].buf[byte]);
@@ -99,6 +104,12 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
REQ_16_SET_GET_I2C_WR1_RDN,
addr | msgs[i].buf[0] << 8, 0,
msgs[i].buf + 1, msgs[i].len - 1);
+
+
+ if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
+ tm6000_set_reg(dev, 0x32, 0,0);
+ tm6000_set_reg(dev, 0x33, 0,0);
+ }
}
if (i2c_debug >= 2)
printk("\n");
@@ -198,7 +209,7 @@ static struct i2c_algorithm tm6000_algo = {
static struct i2c_adapter tm6000_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
+ .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
.name = "tm6000",
.id = I2C_HW_B_TM6000,
.algo = &tm6000_algo,
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 877cbf6..e403ca0 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -23,12 +23,15 @@
// Use the tm6000-hack, instead of the proper initialization code
//#define HACK 1
+#include "compat.h"
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/videobuf-vmalloc.h>
#include "tm6000-usb-isoc.h"
#include <linux/i2c.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
#include <linux/mutex.h>
+#endif
#include <media/v4l2-device.h>
@@ -78,6 +81,10 @@ struct tm6000_dmaqueue {
/* thread for generating video stream*/
struct task_struct *kthread;
wait_queue_head_t wq;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ struct semaphore *notify;
+ int rmmod:1;
+#endif
/* Counters to control fps rate */
int frame;
int ini_jiffies;
@@ -90,12 +97,14 @@ enum tm6000_core_state {
DEV_MISCONFIGURED = 0x04,
};
+#if 1
/* io methods */
enum tm6000_io_method {
IO_NONE,
IO_READ,
IO_MMAP,
};
+#endif
enum tm6000_mode {
TM6000_MODE_UNKNOWN=0,
@@ -202,6 +211,9 @@ struct tm6000_fh {
V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM
+/* In tm6000-cards.c */
+
+int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
/* In tm6000-core.c */
int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
@@ -209,7 +221,6 @@ int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_init (struct tm6000_core *dev);
-int tm6000_init_after_firmware (struct tm6000_core *dev);
int tm6000_init_analog_mode (struct tm6000_core *dev);
int tm6000_init_digital_mode (struct tm6000_core *dev);
@@ -231,7 +242,12 @@ int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm);
int tm6000_i2c_register(struct tm6000_core *dev);
int tm6000_i2c_unregister(struct tm6000_core *dev);
+#if 1
/* In tm6000-queue.c */
+#if 0
+int tm6000_init_isoc(struct tm6000_core *dev, int max_packets);
+void tm6000_uninit_isoc(struct tm6000_core *dev);
+#endif
int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -276,3 +292,4 @@ extern int tm6000_debug;
__FUNCTION__ , ##arg); } while (0)
+#endif
^ permalink raw reply related [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-01 20:20 [PATCH] - tm6000 DVB support Stefan Ringel
@ 2010-02-01 20:35 ` Stefan Ringel
2010-02-01 20:52 ` Devin Heitmueller
2010-02-01 22:52 ` Mauro Carvalho Chehab
0 siblings, 2 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-01 20:35 UTC (permalink / raw)
To: linux-media; +Cc: Mauro Carvalho Chehab, Devin Heitmueller
add Terratec Cinergy Hybrid XE
bugfix i2c transfer
add frontend callback
add init for tm6010
add digital-init for tm6010
add callback for analog/digital switch
bugfix usb transfer in DVB-mode
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
diff --git a/drivers/media/common/tuners/tuner-xc2028.c
b/drivers/media/common/tuners/tuner-xc2028.c
index ed50168..2297c00 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <media/tuner.h>
#include <linux/mutex.h>
+#include "compat.h"
#include <asm/unaligned.h>
#include "tuner-i2c.h"
#include "tuner-xc2028.h"
@@ -994,6 +995,13 @@ static int generic_set_freq(struct dvb_frontend
*fe, u32 freq /* in HZ */,
buf[0], buf[1], buf[2], buf[3],
freq / 1000000, (freq % 1000000) / 1000);
+ if (priv->ctrl.switch_mode) {
+ if (new_mode == T_ANALOG_TV)
+ do_tuner_callback(fe, SWITCH_TV_MODE, 0);
+ if (new_mode == T_DIGITAL_TV)
+ do_tuner_callback(fe, SWITCH_TV_MODE, 1);
+ }
+
rc = 0;
ret:
@@ -1114,7 +1122,11 @@ static int xc2028_set_params(struct dvb_frontend *fe,
/* All S-code tables need a 200kHz shift */
if (priv->ctrl.demod) {
- demod = priv->ctrl.demod + 200;
+ if (priv->ctrl.fname == "xc3028L-v36.fw") {
+ demod = priv->ctrl.demod;
+ } else {
+ demod = priv->ctrl.demod + 200;
+ }
/*
* The DTV7 S-code table needs a 700 kHz shift.
* Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
@@ -1123,8 +1135,8 @@ static int xc2028_set_params(struct dvb_frontend *fe,
* use this firmware after initialization, but a tune to a UHF
* channel should then cause DTV78 to be used.
*/
- if (type & DTV7)
- demod += 500;
+ if (type & DTV7)
+ demod += 500;
}
return generic_set_freq(fe, p->frequency,
@@ -1240,6 +1252,10 @@ static const struct dvb_tuner_ops
xc2028_dvb_tuner_ops = {
.get_rf_strength = xc2028_signal,
.set_params = xc2028_set_params,
.sleep = xc2028_sleep,
+#if 0
+ int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
+ int (*get_status)(struct dvb_frontend *fe, u32 *status);
+#endif
};
struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/common/tuners/tuner-xc2028.h
b/drivers/media/common/tuners/tuner-xc2028.h
index 9778c96..c9a4fb4 100644
--- a/drivers/media/common/tuners/tuner-xc2028.h
+++ b/drivers/media/common/tuners/tuner-xc2028.h
@@ -42,6 +42,7 @@ struct xc2028_ctrl {
unsigned int disable_power_mgmt:1;
unsigned int read_not_reliable:1;
unsigned int demod;
+ unsigned int switch_mode:1;
enum firmware_type type:2;
};
@@ -54,6 +55,7 @@ struct xc2028_config {
/* xc2028 commands for callback */
#define XC2028_TUNER_RESET 0
#define XC2028_RESET_CLK 1
+#define SWITCH_TV_MODE 2
#if defined(CONFIG_MEDIA_TUNER_XC2028) ||
(defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/dvb/frontends/zl10353.h
b/drivers/media/dvb/frontends/zl10353.h
index 6e3ca9e..015bc36 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -45,6 +45,8 @@ struct zl10353_config
/* clock control registers (0x51-0x54) */
u8 clock_ctl_1; /* default: 0x46 */
u8 pll_0; /* default: 0x15 */
+
+ int tm6000:1;
};
#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE)
&& defined(MODULE))
diff --git a/drivers/staging/tm6000/hack.c b/drivers/staging/tm6000/hack.c
index f181fce..c1e1880 100644
--- a/drivers/staging/tm6000/hack.c
+++ b/drivers/staging/tm6000/hack.c
@@ -37,7 +37,6 @@ static inline int tm6000_snd_control_msg(struct
tm6000_core *dev, __u8 request,
static int pseudo_zl10353_pll(struct tm6000_core *tm6000_dev, struct
dvb_frontend_parameters *p)
{
- int ret;
u8 *data = kzalloc(50*sizeof(u8), GFP_KERNEL);
printk(KERN_ALERT "should set frequency %u\n", p->frequency);
@@ -51,7 +50,7 @@ printk(KERN_ALERT "and bandwith %u\n",
p->u.ofdm.bandwidth);
}
// init ZL10353
- data[0] = 0x0b;
+/* data[0] = 0x0b;
ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x501e, 0x00, data,
0x1);
msleep(15);
data[0] = 0x80;
@@ -159,7 +158,7 @@ printk(KERN_ALERT "and bandwith %u\n",
p->u.ofdm.bandwidth);
msleep(15);
data[0] = 0x5a;
ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x651e,
0x00, data, 0x1);
- msleep(15);
+ msleep(15)
data[0] = 0xe9;
ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x661e,
0x00, data, 0x1);
msleep(15);
@@ -189,7 +188,162 @@ printk(KERN_ALERT "and bandwith %u\n",
p->u.ofdm.bandwidth);
msleep(15);
break;
}
-
+*/
+ switch(p->u.ofdm.bandwidth) {
+ case BANDWIDTH_8_MHZ:
+ data[0] = 0x03;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
+ msleep(40);
+ data[0] = 0x44;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x46;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
+ msleep(40);
+ data[0] = 0x15;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
+ msleep(40);
+ data[0] = 0x0f;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
+ msleep(40);
+ data[0] = 0x80;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x00;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x8b;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
+ msleep(40);
+ data[0] = 0x75;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
+ msleep(40);
+ data[0] = 0xe6; //0x19;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x09; //0xf7;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
+ msleep(40);
+ data[0] = 0x67;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
+ msleep(40);
+ data[0] = 0xe5;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
+ msleep(40);
+ data[0] = 0x75;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x17;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
+ msleep(40);
+ break;
+ case BANDWIDTH_7_MHZ:
+ data[0] = 0x03;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
+ msleep(40);
+ data[0] = 0x44;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x46;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
+ msleep(40);
+ data[0] = 0x15;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
+ msleep(40);
+ data[0] = 0x0f;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
+ msleep(40);
+ data[0] = 0x80;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x00;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x83;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
+ msleep(40);
+ data[0] = 0xa3;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
+ msleep(40);
+ data[0] = 0xe6; //0x19;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x09; //0xf7;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
+ msleep(40);
+ data[0] = 0x5a;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
+ msleep(40);
+ data[0] = 0xe9;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
+ msleep(40);
+ data[0] = 0x86;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x17;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
+ msleep(40);
+ break;
+ default:
+ printk(KERN_ALERT "tm6000: bandwidth not supported\n");
+ }
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0f1f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x091f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0b1f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
kfree(data);
return 0;
diff --git a/drivers/staging/tm6000/tm6000-cards.c
b/drivers/staging/tm6000/tm6000-cards.c
index 59fb505..652a54a 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -32,7 +32,7 @@
#include "tm6000.h"
#include "tm6000-regs.h"
#include "tuner-xc2028.h"
-#include "tuner-xc5000.h"
+#include "xc5000.h"
#define TM6000_BOARD_UNKNOWN 0
#define TM5600_BOARD_GENERIC 1
@@ -44,6 +44,10 @@
#define TM6000_BOARD_FREECOM_AND_SIMILAR 7
#define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
#define TM6010_BOARD_HAUPPAUGE_900H 9
+#define TM6010_BOARD_BEHOLD_WANDER 10
+#define TM6010_BOARD_BEHOLD_VOYAGER 11
+#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
+
#define TM6000_MAXBOARDS 16
static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
@@ -208,7 +212,21 @@ struct tm6000_board tm6000_boards[] = {
},
.gpio_addr_tun_reset = TM6000_GPIO_2,
},
-
+ [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
+ .name = "Terratec Cinergy Hybrid XE",
+ .tuner_type = TUNER_XC2028, /* has a XC3028 */
+ .tuner_addr = 0xc2 >> 1,
+ .demod_addr = 0x1e >> 1,
+ .type = TM6010,
+ .caps = {
+ .has_tuner = 1,
+ .has_dvb = 1,
+ .has_zl10353 = 1,
+ .has_eeprom = 1,
+ .has_remote = 1,
+ },
+ .gpio_addr_tun_reset = TM6010_GPIO_2,
+ }
};
/* table of devices that work with this driver */
@@ -221,12 +239,13 @@ struct usb_device_id tm6000_id_table [] = {
{ USB_DEVICE(0x2040, 0x6600), .driver_info =
TM6010_BOARD_HAUPPAUGE_900H },
{ USB_DEVICE(0x6000, 0xdec0), .driver_info =
TM6010_BOARD_BEHOLD_WANDER },
{ USB_DEVICE(0x6000, 0xdec1), .driver_info =
TM6010_BOARD_BEHOLD_VOYAGER },
+ { USB_DEVICE(0x0ccd, 0x0086), .driver_info =
TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
{ },
};
/* Tuner callback to provide the proper gpio changes needed for xc2028 */
-static int tm6000_tuner_callback(void *ptr, int component, int command,
int arg)
+int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
{
int rc=0;
struct tm6000_core *dev = ptr;
@@ -252,11 +271,14 @@ static int tm6000_tuner_callback(void *ptr, int
component, int command, int arg)
switch (arg) {
case 0:
tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ dev->tuner_reset_gpio, 0x01);
+ msleep(60);
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
dev->tuner_reset_gpio, 0x00);
- msleep(130);
+ msleep(75);
tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
dev->tuner_reset_gpio, 0x01);
- msleep(130);
+ msleep(60);
break;
case 1:
tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT,
@@ -269,13 +291,33 @@ static int tm6000_tuner_callback(void *ptr, int
component, int command, int arg)
TM6000_GPIO_CLK, 0);
if (rc<0)
return rc;
- msleep(100);
+ msleep(10);
rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
TM6000_GPIO_CLK, 1);
- msleep(100);
+ msleep(10);
+ break;
+ }
+ break;
+
+ case SWITCH_TV_MODE:
+ /* switch between analog and digital */
+ switch (arg) {
+ case 0:
+ printk(KERN_INFO "switch to analog");
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 1);
+ printk(KERN_INFO "analog");
+ break;
+ case 1:
+ printk(KERN_INFO "switch to digital");
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 0);
+ printk(KERN_INFO "digital");
break;
}
+ break;
}
+
return (rc);
}
@@ -290,7 +332,7 @@ static void tm6000_config_tuner (struct tm6000_core
*dev)
memset(&tun_setup, 0, sizeof(tun_setup));
tun_setup.type = dev->tuner_type;
tun_setup.addr = dev->tuner_addr;
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+ tun_setup.mode_mask = T_ANALOG_TV | T_RADIO | T_DIGITAL_TV;
tun_setup.tuner_callback = tm6000_tuner_callback;
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr,
&tun_setup);
@@ -302,15 +344,19 @@ static void tm6000_config_tuner (struct
tm6000_core *dev)
memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
memset (&ctl,0,sizeof(ctl));
- ctl.mts = 1;
- ctl.read_not_reliable = 1;
+ ctl.input1 = 1;
+ ctl.read_not_reliable = 0;
ctl.msleep = 10;
-
+ ctl.demod = XC3028_FE_ZARLINK456;
+ ctl.vhfbw7 = 1;
+ ctl.uhfbw8 = 1;
+ ctl.switch_mode = 1;
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
switch(dev->model) {
case TM6010_BOARD_HAUPPAUGE_900H:
+ case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
ctl.fname = "xc3028L-v36.fw";
break;
default:
@@ -402,6 +448,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
}
#endif
}
+ return 0;
err2:
v4l2_device_unregister(&dev->v4l2_dev);
@@ -459,13 +506,13 @@ static int tm6000_usb_probe(struct usb_interface
*interface,
/* Check to see next free device and mark as used */
nr=find_first_zero_bit(&tm6000_devused,TM6000_MAXBOARDS);
if (nr >= TM6000_MAXBOARDS) {
- printk ("tm6000: Supports only %i em28xx
boards.\n",TM6000_MAXBOARDS);
+ printk ("tm6000: Supports only %i tm60xx
boards.\n",TM6000_MAXBOARDS);
usb_put_dev(usbdev);
return -ENOMEM;
}
/* Create and initialize dev struct */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*(dev)), GFP_KERNEL);
if (dev == NULL) {
printk ("tm6000" ": out of memory!\n");
usb_put_dev(usbdev);
diff --git a/drivers/staging/tm6000/tm6000-core.c
b/drivers/staging/tm6000/tm6000-core.c
index d41af1d..33bbbd3 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -219,33 +219,53 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
int tm6000_init_digital_mode (struct tm6000_core *dev)
{
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
-
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
- msleep(50);
-
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
- msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
- msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
- msleep(100);
-
+ if (dev->dev_type == TM6010) {
+ int val;
+ u8 buf[2];
+
+ /* digital init */
+ val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, 0);
+ val &= ~0x60;
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, val);
+ val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, 0);
+ val |= 0x40;
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, val);
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xfe, 0x28);
+ tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe2, 0xfc);
+ tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe6, 0xff);
+ tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xf1, 0xfe);
+ tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
+ printk (KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
+
+
+ } else {
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
+
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
+ msleep(50);
+
+ tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ msleep(50);
+ tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
+ msleep(50);
+ tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ msleep(100);
+ }
return 0;
}
@@ -394,7 +414,15 @@ struct reg_init tm6010_init_tab[] = {
{ REQ_07_SET_GET_AVREG, 0x3f, 0x00 },
{ REQ_05_SET_GET_USBREG, 0x18, 0x00 },
-
+
+ /* additional from Terratec Cinergy Hybrid XE */
+ { REQ_07_SET_GET_AVREG, 0xdc, 0xaa },
+ { REQ_07_SET_GET_AVREG, 0xdd, 0x30 },
+ { REQ_07_SET_GET_AVREG, 0xde, 0x20 },
+ { REQ_07_SET_GET_AVREG, 0xdf, 0xd0 },
+ { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 },
+ { REQ_07_SET_GET_AVREG, 0xd8, 0x2f },
+
/* set remote wakeup key:any key wakeup */
{ REQ_07_SET_GET_AVREG, 0xe5, 0xfe },
{ REQ_07_SET_GET_AVREG, 0xda, 0xff },
@@ -404,6 +432,7 @@ int tm6000_init (struct tm6000_core *dev)
{
int board, rc=0, i, size;
struct reg_init *tab;
+ u8 buf[40];
if (dev->dev_type == TM6010) {
tab = tm6010_init_tab;
@@ -424,61 +453,129 @@ int tm6000_init (struct tm6000_core *dev)
}
}
- msleep(5); /* Just to be conservative */
-
- /* Check board version - maybe 10Moons specific */
- board=tm6000_get_reg16 (dev, 0x40, 0, 0);
- if (board >=0) {
- printk (KERN_INFO "Board version = 0x%04x\n",board);
- } else {
- printk (KERN_ERR "Error %i while retrieving board
version\n",board);
- }
-
+ /* hack */
if (dev->dev_type == TM6010) {
- /* Turn xceive 3028 on */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6010_GPIO_3, 0x01);
- msleep(11);
- }
-
- /* Reset GPIO1 and GPIO4. */
- for (i=0; i< 2; i++) {
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->tuner_reset_gpio, 0x00);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
- return rc;
- }
-
- msleep(10); /* Just to be conservative */
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->tuner_reset_gpio, 0x01);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
- return rc;
- }
-
- msleep(10);
- rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 0);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
- return rc;
- }
-
- msleep(10);
- rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 1);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
- return rc;
- }
-
- if (!i) {
- rc=tm6000_get_reg16(dev, 0x40,0,0);
- if (rc>=0) {
- printk ("board=%d\n", rc);
+
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_4, 0);
+ msleep(15);
+
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 0);
+
+ msleep(50);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 1);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x0010, 0x4400, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
+
+ msleep(15);
+ buf[0] = 0x12;
+ buf[1] = 0x34;
+ tm6000_read_write_usb (dev, 0x40, 0x10, 0xf432, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0x0032, 0x0000, buf, 2);
+
+ msleep(15);
+ buf[0] = 0x00;
+ buf[1] = 0x01;
+ tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0x00c0, 0x0000, buf, 39);
+
+ msleep(15);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0x7f1f, 0x0000, buf, 2);
+// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf [1]);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_4, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_0, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_7, 0);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 1);
+
+ msleep(15);
+
+ for (i=0; i< size; i++) {
+ rc= tm6000_set_reg (dev, tab[i].req, tab[i].reg, tab[i].val);
+ if (rc<0) {
+ printk (KERN_ERR "Error %i while setting req %d, "
+ "reg %d to value %d\n", rc,
+ tab[i].req,tab[i].reg, tab[i].val);
+ return rc;
}
}
+
+ msleep(15);
+
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_4, 0);
+ msleep(15);
+
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 0);
+
+ msleep(50);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 1);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
+// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 0);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 0);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
}
+ /* hack end */
+
+ msleep(5); /* Just to be conservative */
+ /* Check board version - maybe 10Moons specific */
+ if (dev->dev_type == TM5600) {
+ board=tm6000_get_reg16 (dev, 0x40, 0, 0);
+ if (board >=0) {
+ printk (KERN_INFO "Board version = 0x%04x\n",board);
+ } else {
+ printk (KERN_ERR "Error %i while retrieving board
version\n",board);
+ }
+ }
+
msleep(50);
return 0;
diff --git a/drivers/staging/tm6000/tm6000-dvb.c
b/drivers/staging/tm6000/tm6000-dvb.c
index e900d6d..31458d3 100644
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -17,7 +17,9 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/kernel.h>
#include <linux/usb.h>
+#include <compat.h>
#include "tm6000.h"
#include "tm6000-regs.h"
@@ -30,17 +32,61 @@
#include "tuner-xc2028.h"
+static void inline print_err_status (struct tm6000_core *dev,
+ int packet, int status)
+{
+ char *errmsg = "Unknown";
+
+ switch(status) {
+ case -ENOENT:
+ errmsg = "unlinked synchronuously";
+ break;
+ case -ECONNRESET:
+ errmsg = "unlinked asynchronuously";
+ break;
+ case -ENOSR:
+ errmsg = "Buffer error (overrun)";
+ break;
+ case -EPIPE:
+ errmsg = "Stalled (device not responding)";
+ break;
+ case -EOVERFLOW:
+ errmsg = "Babble (bad cable?)";
+ break;
+ case -EPROTO:
+ errmsg = "Bit-stuff error (bad cable?)";
+ break;
+ case -EILSEQ:
+ errmsg = "CRC/Timeout (could be anything)";
+ break;
+ case -ETIME:
+ errmsg = "Device does not respond";
+ break;
+ }
+ if (packet<0) {
+ dprintk(dev, 1, "URB status %d [%s].\n",
+ status, errmsg);
+ } else {
+ dprintk(dev, 1, "URB packet %d, status %d [%s].\n",
+ packet, status, errmsg);
+ }
+}
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+static void tm6000_urb_received(struct urb *urb, struct pt_regs *ptregs)
+#else
static void tm6000_urb_received(struct urb *urb)
+#endif
{
int ret;
struct tm6000_core* dev = urb->context;
- if(urb->status != 0){
- printk(KERN_ERR "tm6000: status != 0\n");
+ if(urb->status != 0) {
+ print_err_status (dev,0,urb->status);
}
else if(urb->actual_length>0){
- dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
- urb->actual_length);
+ dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
urb->actual_length);
}
if(dev->dvb->streams > 0) {
@@ -56,49 +102,37 @@ static void tm6000_urb_received(struct urb *urb)
int tm6000_start_stream(struct tm6000_core *dev)
{
int ret;
- unsigned int pipe, maxPaketSize;
+ unsigned int pipe, size;
struct tm6000_dvb *dvb = dev->dvb;
printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
tm6000_init_digital_mode(dev);
-/*
- ret = tm6000_set_led_status(tm6000_dev, 0x1);
- if(ret < 0) {
- return -1;
- }
-*/
-
dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
if(dvb->bulk_urb == NULL) {
printk(KERN_ERR "tm6000: couldn't allocate urb\n");
return -ENOMEM;
}
- maxPaketSize = dev->bulk_in->desc.wMaxPacketSize;
+ pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
+ & USB_ENDPOINT_NUMBER_MASK);
+
+ size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
+ size = size * 15; // 512 x 8 or 12 or 15
- dvb->bulk_urb->transfer_buffer = kzalloc(maxPaketSize, GFP_KERNEL);
+ dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
if(dvb->bulk_urb->transfer_buffer == NULL) {
usb_free_urb(dvb->bulk_urb);
printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
return -ENOMEM;
}
-
- pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
- & USB_ENDPOINT_NUMBER_MASK);
-
+
usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
dvb->bulk_urb->transfer_buffer,
- maxPaketSize,
+ size,
tm6000_urb_received, dev);
- ret = usb_set_interface(dev->udev, 0, 1);
- if(ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during set
interface\n", ret, __FUNCTION__);
- return ret;
- }
-
ret = usb_clear_halt(dev->udev, pipe);
if(ret < 0) {
printk(KERN_ERR "tm6000: error %i in %s during pipe
reset\n",ret,__FUNCTION__);
@@ -107,15 +141,14 @@ int tm6000_start_stream(struct tm6000_core *dev)
else {
printk(KERN_ERR "tm6000: pipe resetted\n");
}
-
-// mutex_lock(&tm6000_driver.open_close_mutex);
+
+// mutex_lock(&tm6000_driver.open_close_mutex);
ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
-
-// mutex_unlock(&tm6000_driver.open_close_mutex);
+// mutex_unlock(&tm6000_driver.open_close_mutex);
if (ret) {
printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",ret);
-
+
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
return ret;
@@ -126,18 +159,12 @@ int tm6000_start_stream(struct tm6000_core *dev)
void tm6000_stop_stream(struct tm6000_core *dev)
{
- int ret;
struct tm6000_dvb *dvb = dev->dvb;
-// tm6000_set_led_status(tm6000_dev, 0x0);
-
- ret = usb_set_interface(dev->udev, 0, 0);
- if(ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during set
interface\n",ret,__FUNCTION__);
- }
-
if(dvb->bulk_urb) {
+ printk (KERN_INFO "urb killing\n");
usb_kill_urb(dvb->bulk_urb);
+ printk (KERN_INFO "urb buffer free\n");
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
dvb->bulk_urb = NULL;
@@ -154,7 +181,7 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
mutex_lock(&dvb->mutex);
if(dvb->streams == 0) {
dvb->streams = 1;
-// mutex_init(&tm6000_dev->streaming_mutex);
+// mutex_init(&tm6000_dev->streming_mutex);
tm6000_start_stream(dev);
}
else {
@@ -173,14 +200,17 @@ int tm6000_stop_feed(struct dvb_demux_feed *feed) {
printk(KERN_INFO "tm6000: got stop feed request %s\n",__FUNCTION__);
mutex_lock(&dvb->mutex);
- --dvb->streams;
- if(0 == dvb->streams) {
+ printk (KERN_INFO "stream %#x\n", dvb->streams);
+ --(dvb->streams);
+ if(dvb->streams == 0) {
+ printk (KERN_INFO "stop stream\n");
tm6000_stop_stream(dev);
-// mutex_destroy(&tm6000_dev->streaming_mutex);
+// mutex_destroy(&tm6000_dev->streaming_mutex);
}
+
mutex_unlock(&dvb->mutex);
-// mutex_destroy(&tm6000_dev->streaming_mutex);
+// mutex_destroy(&tm6000_dev->streaming_mutex);
return 0;
}
@@ -191,13 +221,16 @@ int tm6000_dvb_attach_frontend(struct tm6000_core
*dev)
if(dev->caps.has_zl10353) {
struct zl10353_config config =
- {.demod_address = dev->demod_addr >> 1,
+ {.demod_address = dev->demod_addr,
.no_tuner = 1,
-// .input_frequency = 0x19e9,
-// .r56_agc_targets = 0x1c,
+ .parallel_ts = 1,
+ .if2 = 45700,
+ .disable_i2c_gate_ctrl = 1,
+ .tm6000 = 1,
};
dvb->frontend = pseudo_zl10353_attach(dev, &config,
+// dvb->frontend = dvb_attach (zl10353_attach, &config,
&dev->i2c_adap);
}
else {
@@ -235,7 +268,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
.i2c_adap = &dev->i2c_adap,
.i2c_addr = dev->tuner_addr,
};
-
+
+ dvb->frontend->callback = tm6000_tuner_callback;
ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
if (ret < 0) {
printk(KERN_ERR
@@ -258,8 +292,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
| DMX_MEMORY_BASED_FILTERING;
dvb->demux.priv = dev;
- dvb->demux.filternum = 256;
- dvb->demux.feednum = 256;
+ dvb->demux.filternum = 5; //256;
+ dvb->demux.feednum = 5; //256;
dvb->demux.start_feed = tm6000_start_feed;
dvb->demux.stop_feed = tm6000_stop_feed;
dvb->demux.write_to_decoder = NULL;
@@ -307,7 +341,7 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
usb_free_urb(bulk_urb);
}
-// mutex_lock(&tm6000_driver.open_close_mutex);
+// mutex_lock(&tm6000_driver.open_close_mutex);
if(dvb->frontend) {
dvb_frontend_detach(dvb->frontend);
dvb_unregister_frontend(dvb->frontend);
@@ -317,6 +351,6 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
dvb_dmx_release(&dvb->demux);
dvb_unregister_adapter(&dvb->adapter);
mutex_destroy(&dvb->mutex);
-// mutex_unlock(&tm6000_driver.open_close_mutex);
+// mutex_unlock(&tm6000_driver.open_close_mutex);
}
diff --git a/drivers/staging/tm6000/tm6000-i2c.c
b/drivers/staging/tm6000/tm6000-i2c.c
index 4da10f5..3e43ad7 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -86,6 +86,11 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
msgs[i].len == 1 ? 0 : msgs[i].buf[1],
msgs[i + 1].buf, msgs[i + 1].len);
i++;
+
+ if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
+ tm6000_set_reg(dev, 0x32, 0,0);
+ tm6000_set_reg(dev, 0x33, 0,0);
+ }
if (i2c_debug >= 2)
for (byte = 0; byte < msgs[i].len; byte++)
printk(" %02x", msgs[i].buf[byte]);
@@ -99,6 +104,12 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
REQ_16_SET_GET_I2C_WR1_RDN,
addr | msgs[i].buf[0] << 8, 0,
msgs[i].buf + 1, msgs[i].len - 1);
+
+
+ if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
+ tm6000_set_reg(dev, 0x32, 0,0);
+ tm6000_set_reg(dev, 0x33, 0,0);
+ }
}
if (i2c_debug >= 2)
printk("\n");
@@ -198,7 +209,7 @@ static struct i2c_algorithm tm6000_algo = {
static struct i2c_adapter tm6000_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
+ .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
.name = "tm6000",
.id = I2C_HW_B_TM6000,
.algo = &tm6000_algo,
diff --git a/drivers/staging/tm6000/tm6000.h
b/drivers/staging/tm6000/tm6000.h
index 877cbf6..e403ca0 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -23,12 +23,15 @@
// Use the tm6000-hack, instead of the proper initialization code
//#define HACK 1
+#include "compat.h"
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/videobuf-vmalloc.h>
#include "tm6000-usb-isoc.h"
#include <linux/i2c.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
#include <linux/mutex.h>
+#endif
#include <media/v4l2-device.h>
@@ -78,6 +81,10 @@ struct tm6000_dmaqueue {
/* thread for generating video stream*/
struct task_struct *kthread;
wait_queue_head_t wq;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ struct semaphore *notify;
+ int rmmod:1;
+#endif
/* Counters to control fps rate */
int frame;
int ini_jiffies;
@@ -90,12 +97,14 @@ enum tm6000_core_state {
DEV_MISCONFIGURED = 0x04,
};
+#if 1
/* io methods */
enum tm6000_io_method {
IO_NONE,
IO_READ,
IO_MMAP,
};
+#endif
enum tm6000_mode {
TM6000_MODE_UNKNOWN=0,
@@ -202,6 +211,9 @@ struct tm6000_fh {
V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM
+/* In tm6000-cards.c */
+
+int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
/* In tm6000-core.c */
int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
@@ -209,7 +221,6 @@ int tm6000_read_write_usb (struct tm6000_core *dev,
u8 reqtype, u8 req,
int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_init (struct tm6000_core *dev);
-int tm6000_init_after_firmware (struct tm6000_core *dev);
int tm6000_init_analog_mode (struct tm6000_core *dev);
int tm6000_init_digital_mode (struct tm6000_core *dev);
@@ -231,7 +242,12 @@ int tm6000_set_standard (struct tm6000_core *dev,
v4l2_std_id *norm);
int tm6000_i2c_register(struct tm6000_core *dev);
int tm6000_i2c_unregister(struct tm6000_core *dev);
+#if 1
/* In tm6000-queue.c */
+#if 0
+int tm6000_init_isoc(struct tm6000_core *dev, int max_packets);
+void tm6000_uninit_isoc(struct tm6000_core *dev);
+#endif
int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -276,3 +292,4 @@ extern int tm6000_debug;
__FUNCTION__ , ##arg); } while (0)
+#endif
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply related [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-01 20:35 ` Stefan Ringel
@ 2010-02-01 20:52 ` Devin Heitmueller
2010-02-01 21:23 ` Stefan Ringel
2010-02-01 22:52 ` Mauro Carvalho Chehab
1 sibling, 1 reply; 55+ messages in thread
From: Devin Heitmueller @ 2010-02-01 20:52 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Mauro Carvalho Chehab
On Mon, Feb 1, 2010 at 3:35 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
> add Terratec Cinergy Hybrid XE
> bugfix i2c transfer
> add frontend callback
> add init for tm6010
> add digital-init for tm6010
> add callback for analog/digital switch
> bugfix usb transfer in DVB-mode
>
> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
Hi Stefan,
It's good to see you're making progress. However, this is going to
need *alot* of work before it will be able to be accepted upstream.
You should start by breaking it down into a patch series, so that the
incremental changes can be reviewed. That will allow you to explain
in the patch descriptions why all the individual changes you have made
are required.
However, I will try to put some of my thoughts down based on the quick
glance I took at the patch.
Why did you define a new callback for changing the tuner mode? We
have successfully provided infrastructure on other bridges to toggle
GPIOs when changing modes. For example, the em28xx has fields in the
board profile that allow you to toggle GPIOs when going back and forth
between digital and analog mode.
You've got a bunch of changes in the xc3028 tuner that will
*definitely* need close inspection and would need to be validated on a
variety of products using the xc3028 before they could be accepted
upstream. While you have done what you felt was necessary to make it
work for your board, this cannot be at the cost of possible
regressions to other products that are already supported.
You really should look into fixing whatever is screwed up in the
tm6000 i2c implementation so that the read support works, rather than
relying on nothing ever having to perform a read operation.
What function does the "tm6000" member in the zl10353 config do? It
doesn't seem to be used anywhere.
There are a bunch of codingstyle issues which will need to be fixed.
My foremost concerns are obviously the things that touch other
drivers, since your work could cause regressions/breakage for other
boards, which is actually much worse than your board not being
supported.
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-01 20:52 ` Devin Heitmueller
@ 2010-02-01 21:23 ` Stefan Ringel
2010-02-01 21:44 ` Devin Heitmueller
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-01 21:23 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
Am 01.02.2010 21:52, schrieb Devin Heitmueller:
> On Mon, Feb 1, 2010 at 3:35 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>
>> add Terratec Cinergy Hybrid XE
>> bugfix i2c transfer
>> add frontend callback
>> add init for tm6010
>> add digital-init for tm6010
>> add callback for analog/digital switch
>> bugfix usb transfer in DVB-mode
>>
>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>
> Hi Stefan,
>
> It's good to see you're making progress. However, this is going to
> need *alot* of work before it will be able to be accepted upstream.
>
> You should start by breaking it down into a patch series, so that the
> incremental changes can be reviewed. That will allow you to explain
> in the patch descriptions why all the individual changes you have made
> are required.
>
>
how can I generate it?
> However, I will try to put some of my thoughts down based on the quick
> glance I took at the patch.
>
> Why did you define a new callback for changing the tuner mode? We
> have successfully provided infrastructure on other bridges to toggle
> GPIOs when changing modes. For example, the em28xx has fields in the
> board profile that allow you to toggle GPIOs when going back and forth
> between digital and analog mode.
>
>
I don't know, how you mean it. I'm amateur programmer.
> You've got a bunch of changes in the xc3028 tuner that will
> *definitely* need close inspection and would need to be validated on a
> variety of products using the xc3028 before they could be accepted
> upstream. While you have done what you felt was necessary to make it
> work for your board, this cannot be at the cost of possible
> regressions to other products that are already supported.
>
> You really should look into fixing whatever is screwed up in the
> tm6000 i2c implementation so that the read support works, rather than
> relying on nothing ever having to perform a read operation.
>
> What function does the "tm6000" member in the zl10353 config do? It
> doesn't seem to be used anywhere.
>
>
I'll switch it next week to demodulator module.
> There are a bunch of codingstyle issues which will need to be fixed.
>
> My foremost concerns are obviously the things that touch other
> drivers, since your work could cause regressions/breakage for other
> boards, which is actually much worse than your board not being
> supported.
>
>
Cheers
Stefan Ringel
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-01 21:23 ` Stefan Ringel
@ 2010-02-01 21:44 ` Devin Heitmueller
2010-02-01 22:00 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Devin Heitmueller @ 2010-02-01 21:44 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Mauro Carvalho Chehab
On Mon, Feb 1, 2010 at 4:23 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>> You should start by breaking it down into a patch series, so that the
>> incremental changes can be reviewed. That will allow you to explain
>> in the patch descriptions why all the individual changes you have made
>> are required.
>>
>>
> how can I generate it?
You can use quilt to break it up into a patch series, or create a
local hg clone of v4l-dvb.
>> Why did you define a new callback for changing the tuner mode? We
>> have successfully provided infrastructure on other bridges to toggle
>> GPIOs when changing modes. For example, the em28xx has fields in the
>> board profile that allow you to toggle GPIOs when going back and forth
>> between digital and analog mode.
>>
>>
> I don't know, how you mean it. I'm amateur programmer.
Look at how the ".dvb_gpio" and ".gpio" fields are used in the board
profiles in em28xx-cards.c. We toggle the GPIOs when switching the
from analog to digital mode, without the tuner having to do any sort
of callback.
>> What function does the "tm6000" member in the zl10353 config do? It
>> doesn't seem to be used anywhere.
>>
>>
> I'll switch it next week to demodulator module.
Are you saying the zl10353 isn't working right now in your patch? I'm
a bit confused. If it doesn't work, then your patch title is a bit
misleading since it suggests that your patch provides DVB support for
the tm6000. If it does work, then the tm6000 member shouldn't be
needed at all in the zl10353 config.
Cheers,
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-01 21:44 ` Devin Heitmueller
@ 2010-02-01 22:00 ` Stefan Ringel
2010-02-01 23:05 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-01 22:00 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: linux-media, Mauro Carvalho Chehab
Am 01.02.2010 22:44, schrieb Devin Heitmueller:
> On Mon, Feb 1, 2010 at 4:23 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>
>>> You should start by breaking it down into a patch series, so that the
>>> incremental changes can be reviewed. That will allow you to explain
>>> in the patch descriptions why all the individual changes you have made
>>> are required.
>>>
>>>
>>>
>> how can I generate it?
>>
> You can use quilt to break it up into a patch series, or create a
> local hg clone of v4l-dvb.
>
>
>>> Why did you define a new callback for changing the tuner mode? We
>>> have successfully provided infrastructure on other bridges to toggle
>>> GPIOs when changing modes. For example, the em28xx has fields in the
>>> board profile that allow you to toggle GPIOs when going back and forth
>>> between digital and analog mode.
>>>
>>>
>>>
>> I don't know, how you mean it. I'm amateur programmer.
>>
> Look at how the ".dvb_gpio" and ".gpio" fields are used in the board
> profiles in em28xx-cards.c. We toggle the GPIOs when switching the
> from analog to digital mode, without the tuner having to do any sort
> of callback.
>
>
It's a bad example. em28xx use a reg-set, but tm6000 not !! It use a
gpio usb request.
tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6010_GPIO_5, 1);
I don't know, that it with the ".gpio" fields works. And when it switch
from analog to digital, I don't see the way.
>>> What function does the "tm6000" member in the zl10353 config do? It
>>> doesn't seem to be used anywhere.
>>>
>>>
>>>
>> I'll switch it next week to demodulator module.
>>
> Are you saying the zl10353 isn't working right now in your patch? I'm
> a bit confused. If it doesn't work, then your patch title is a bit
> misleading since it suggests that your patch provides DVB support for
> the tm6000. If it does work, then the tm6000 member shouldn't be
> needed at all in the zl10353 config.
>
>
I'm emulating it in hack.c and the zl10353 module doesn't work, if I
switch to it.
> Cheers,
>
> Devin
>
>
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-01 20:35 ` Stefan Ringel
2010-02-01 20:52 ` Devin Heitmueller
@ 2010-02-01 22:52 ` Mauro Carvalho Chehab
2010-02-02 17:24 ` Stefan Ringel
1 sibling, 1 reply; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-01 22:52 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
Stefan Ringel wrote:
> add Terratec Cinergy Hybrid XE
> bugfix i2c transfer
> add frontend callback
> add init for tm6010
> add digital-init for tm6010
> add callback for analog/digital switch
> bugfix usb transfer in DVB-mode
>
> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
Devin is right with respect to the changes: you should break into small
patches for us to better understand what you're doing.
In particular, some parts of the changes (like tuner-xc2028) are known
to be working fine with other drivers, so any change there should be done
with the enough care to not break other drivers.
>
> diff --git a/drivers/media/common/tuners/tuner-xc2028.c
> b/drivers/media/common/tuners/tuner-xc2028.c
> index ed50168..2297c00 100644
> --- a/drivers/media/common/tuners/tuner-xc2028.c
> +++ b/drivers/media/common/tuners/tuner-xc2028.c
> @@ -15,6 +15,7 @@
> #include <linux/delay.h>
> #include <media/tuner.h>
> #include <linux/mutex.h>
> +#include "compat.h"
> #include <asm/unaligned.h>
> #include "tuner-i2c.h"
> #include "tuner-xc2028.h"
> @@ -994,6 +995,13 @@ static int generic_set_freq(struct dvb_frontend
> *fe, u32 freq /* in HZ */,
> buf[0], buf[1], buf[2], buf[3],
> freq / 1000000, (freq % 1000000) / 1000);
>
> + if (priv->ctrl.switch_mode) {
> + if (new_mode == T_ANALOG_TV)
> + do_tuner_callback(fe, SWITCH_TV_MODE, 0);
> + if (new_mode == T_DIGITAL_TV)
> + do_tuner_callback(fe, SWITCH_TV_MODE, 1);
> + }
> +
> rc = 0;
The decision taken at the driver were the opposite: the bridge driver should
have the logic to reset the tuner. This works perfectly on em28xx and other
drivers that use xc3028.
I don't see a good reason to revert the logic here. Also, such change should
be done on all drivers that use xc3028 and xc5000.
>
> ret:
> @@ -1114,7 +1122,11 @@ static int xc2028_set_params(struct dvb_frontend *fe,
>
> /* All S-code tables need a 200kHz shift */
> if (priv->ctrl.demod) {
> - demod = priv->ctrl.demod + 200;
> + if (priv->ctrl.fname == "xc3028L-v36.fw") {
> + demod = priv->ctrl.demod;
> + } else {
> + demod = priv->ctrl.demod + 200;
> + }
Instead, you should be using the firmware version.
As the firmware version is written at the firmware file, it is easy to do the tests
based on the firmware version, even on devices like tm6000 where the version read
method may fail.
Yet, I suspect that the currently available v36 firmwares already take this into
consideration (or the drivers that use those firmwares do the offset internally).
So, this change needs to be checked against the existing drivers.
> /*
> * The DTV7 S-code table needs a 700 kHz shift.
> * Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
> @@ -1123,8 +1135,8 @@ static int xc2028_set_params(struct dvb_frontend *fe,
> * use this firmware after initialization, but a tune to a UHF
> * channel should then cause DTV78 to be used.
> */
> - if (type & DTV7)
> - demod += 500;
> + if (type & DTV7)
> + demod += 500;
This hunk is wrong.
> }
>
> return generic_set_freq(fe, p->frequency,
> @@ -1240,6 +1252,10 @@ static const struct dvb_tuner_ops
> xc2028_dvb_tuner_ops = {
> .get_rf_strength = xc2028_signal,
> .set_params = xc2028_set_params,
> .sleep = xc2028_sleep,
> +#if 0
> + int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
> + int (*get_status)(struct dvb_frontend *fe, u32 *status);
> +#endif
> };
>
> struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
> diff --git a/drivers/media/common/tuners/tuner-xc2028.h
> b/drivers/media/common/tuners/tuner-xc2028.h
> index 9778c96..c9a4fb4 100644
> --- a/drivers/media/common/tuners/tuner-xc2028.h
> +++ b/drivers/media/common/tuners/tuner-xc2028.h
> @@ -42,6 +42,7 @@ struct xc2028_ctrl {
> unsigned int disable_power_mgmt:1;
> unsigned int read_not_reliable:1;
> unsigned int demod;
> + unsigned int switch_mode:1;
This struct is meant to pass static parameters to the driver. the analog/digital
mode is dynamic, so, this is not the right place for doing it.
> enum firmware_type type:2;
> };
>
> @@ -54,6 +55,7 @@ struct xc2028_config {
> /* xc2028 commands for callback */
> #define XC2028_TUNER_RESET 0
> #define XC2028_RESET_CLK 1
> +#define SWITCH_TV_MODE 2
>
> #if defined(CONFIG_MEDIA_TUNER_XC2028) ||
> (defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
> extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
> diff --git a/drivers/media/dvb/frontends/zl10353.h
> b/drivers/media/dvb/frontends/zl10353.h
> index 6e3ca9e..015bc36 100644
> --- a/drivers/media/dvb/frontends/zl10353.h
> +++ b/drivers/media/dvb/frontends/zl10353.h
> @@ -45,6 +45,8 @@ struct zl10353_config
> /* clock control registers (0x51-0x54) */
> u8 clock_ctl_1; /* default: 0x46 */
> u8 pll_0; /* default: 0x15 */
> +
> + int tm6000:1;
This doesn't make sense. The zl10353 doesn't need to know if the device is
a tm6000 or not. If the tm6000 driver needs something special, then we need
to discover what he is doing and name the zl10353 feature accordingly.
> };
>
> #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE)
> && defined(MODULE))
> diff --git a/drivers/staging/tm6000/hack.c b/drivers/staging/tm6000/hack.c
> index f181fce..c1e1880 100644
> --- a/drivers/staging/tm6000/hack.c
> +++ b/drivers/staging/tm6000/hack.c
> @@ -37,7 +37,6 @@ static inline int tm6000_snd_control_msg(struct
> tm6000_core *dev, __u8 request,
This "hack" file is a good candidate to be removed ;) It is, in fact a zl10353
code with the tm6000 initialization, made by cloning the zl10353 parameters
that the original driver does.
>
> static int pseudo_zl10353_pll(struct tm6000_core *tm6000_dev, struct
> dvb_frontend_parameters *p)
> {
> - int ret;
> u8 *data = kzalloc(50*sizeof(u8), GFP_KERNEL);
>
> printk(KERN_ALERT "should set frequency %u\n", p->frequency);
> @@ -51,7 +50,7 @@ printk(KERN_ALERT "and bandwith %u\n",
> p->u.ofdm.bandwidth);
> }
>
> // init ZL10353
> - data[0] = 0x0b;
> +/* data[0] = 0x0b;
> ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x501e, 0x00, data,
> 0x1);
> msleep(15);
> data[0] = 0x80;
> @@ -159,7 +158,7 @@ printk(KERN_ALERT "and bandwith %u\n",
> p->u.ofdm.bandwidth);
> msleep(15);
> data[0] = 0x5a;
> ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x651e,
> 0x00, data, 0x1);
> - msleep(15);
> + msleep(15)
> data[0] = 0xe9;
> ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x661e,
> 0x00, data, 0x1);
> msleep(15);
> @@ -189,7 +188,162 @@ printk(KERN_ALERT "and bandwith %u\n",
> p->u.ofdm.bandwidth);
> msleep(15);
> break;
> }
> -
> +*/
Please use #if 0 to temporarily remove a code that it is not needed. Yet, maybe
removing this code will break tm6000 devices. tm6010 has some differences
when compared with tm6000. So, if your device is tm6010, the better is to
run the above code if is not a tm6010.
> + switch(p->u.ofdm.bandwidth) {
> + case BANDWIDTH_8_MHZ:
> + data[0] = 0x03;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
> + msleep(40);
> + data[0] = 0x44;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
> + msleep(40);
> + data[0] = 0x40;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
> + msleep(40);
> + data[0] = 0x46;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
> + msleep(40);
> + data[0] = 0x15;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
> + msleep(40);
> + data[0] = 0x0f;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
> + msleep(40);
> + data[0] = 0x80;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
> + msleep(40);
> + data[0] = 0x01;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
> + msleep(40);
> + data[0] = 0x00;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
> + msleep(40);
> + data[0] = 0x8b;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
> + msleep(40);
> + data[0] = 0x75;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
> + msleep(40);
> + data[0] = 0xe6; //0x19;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
> + msleep(40);
> + data[0] = 0x09; //0xf7;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
> + msleep(40);
> + data[0] = 0x67;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
> + msleep(40);
> + data[0] = 0xe5;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
> + msleep(40);
> + data[0] = 0x75;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
> + msleep(40);
> + data[0] = 0x17;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
> + msleep(40);
> + data[0] = 0x40;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
> + msleep(40);
> + data[0] = 0x01;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
> + msleep(40);
> + break;
> + case BANDWIDTH_7_MHZ:
> + data[0] = 0x03;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
> + msleep(40);
> + data[0] = 0x44;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
> + msleep(40);
> + data[0] = 0x40;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
> + msleep(40);
> + data[0] = 0x46;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
> + msleep(40);
> + data[0] = 0x15;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
> + msleep(40);
> + data[0] = 0x0f;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
> + msleep(40);
> + data[0] = 0x80;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
> + msleep(40);
> + data[0] = 0x01;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
> + msleep(40);
> + data[0] = 0x00;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
> + msleep(40);
> + data[0] = 0x83;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
> + msleep(40);
> + data[0] = 0xa3;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
> + msleep(40);
> + data[0] = 0xe6; //0x19;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
> + msleep(40);
> + data[0] = 0x09; //0xf7;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
> + msleep(40);
> + data[0] = 0x5a;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
> + msleep(40);
> + data[0] = 0xe9;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
> + msleep(40);
> + data[0] = 0x86;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
> + msleep(40);
> + data[0] = 0x17;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
> + msleep(40);
> + data[0] = 0x40;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
> + msleep(40);
> + data[0] = 0x01;
> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
> + msleep(40);
> + break;
> + default:
> + printk(KERN_ALERT "tm6000: bandwidth not supported\n");
> + }
> +
> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
> + msleep(40);
> +
> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
> + msleep(40);
> +
> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
> + msleep(40);
> +
> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
> + msleep(40);
> +
> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
> + msleep(40);
> +
> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0f1f,0,data,2);
> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
> + msleep(40);
> +
> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x091f,0,data,2);
> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
> + msleep(40);
> +
> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0b1f,0,data,2);
> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
> + msleep(40);
The same comment here: maybe the above code only applies to tm6010.
> +
> kfree(data);
>
> return 0;
> diff --git a/drivers/staging/tm6000/tm6000-cards.c
> b/drivers/staging/tm6000/tm6000-cards.c
> index 59fb505..652a54a 100644
> --- a/drivers/staging/tm6000/tm6000-cards.c
> +++ b/drivers/staging/tm6000/tm6000-cards.c
> @@ -32,7 +32,7 @@
> #include "tm6000.h"
> #include "tm6000-regs.h"
> #include "tuner-xc2028.h"
> -#include "tuner-xc5000.h"
> +#include "xc5000.h"
Please send this hunk on a separate patch. Since it fixes compilation, I'll
need to apply it before the Kconfig changes, when tm6000 upstream.
>
> #define TM6000_BOARD_UNKNOWN 0
> #define TM5600_BOARD_GENERIC 1
> @@ -44,6 +44,10 @@
> #define TM6000_BOARD_FREECOM_AND_SIMILAR 7
> #define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
> #define TM6010_BOARD_HAUPPAUGE_900H 9
> +#define TM6010_BOARD_BEHOLD_WANDER 10
> +#define TM6010_BOARD_BEHOLD_VOYAGER 11
> +#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
> +
>
> #define TM6000_MAXBOARDS 16
> static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
> @@ -208,7 +212,21 @@ struct tm6000_board tm6000_boards[] = {
> },
> .gpio_addr_tun_reset = TM6000_GPIO_2,
> },
> -
> + [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
> + .name = "Terratec Cinergy Hybrid XE",
> + .tuner_type = TUNER_XC2028, /* has a XC3028 */
> + .tuner_addr = 0xc2 >> 1,
> + .demod_addr = 0x1e >> 1,
> + .type = TM6010,
> + .caps = {
> + .has_tuner = 1,
> + .has_dvb = 1,
> + .has_zl10353 = 1,
> + .has_eeprom = 1,
> + .has_remote = 1,
> + },
> + .gpio_addr_tun_reset = TM6010_GPIO_2,
> + }
> };
>
> /* table of devices that work with this driver */
> @@ -221,12 +239,13 @@ struct usb_device_id tm6000_id_table [] = {
> { USB_DEVICE(0x2040, 0x6600), .driver_info =
> TM6010_BOARD_HAUPPAUGE_900H },
> { USB_DEVICE(0x6000, 0xdec0), .driver_info =
> TM6010_BOARD_BEHOLD_WANDER },
> { USB_DEVICE(0x6000, 0xdec1), .driver_info =
> TM6010_BOARD_BEHOLD_VOYAGER },
> + { USB_DEVICE(0x0ccd, 0x0086), .driver_info =
> TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
> { },
> };
New board definition: please send this as a separate patch.
>
> /* Tuner callback to provide the proper gpio changes needed for xc2028 */
>
> -static int tm6000_tuner_callback(void *ptr, int component, int command,
> int arg)
> +int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
> {
> int rc=0;
> struct tm6000_core *dev = ptr;
> @@ -252,11 +271,14 @@ static int tm6000_tuner_callback(void *ptr, int
> component, int command, int arg)
> switch (arg) {
> case 0:
> tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
> + dev->tuner_reset_gpio, 0x01);
> + msleep(60);
> + tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
> dev->tuner_reset_gpio, 0x00);
> - msleep(130);
> + msleep(75);
> tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
> dev->tuner_reset_gpio, 0x01);
> - msleep(130);
> + msleep(60);
> break;
> case 1:
> tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT,
> @@ -269,13 +291,33 @@ static int tm6000_tuner_callback(void *ptr, int
> component, int command, int arg)
> TM6000_GPIO_CLK, 0);
> if (rc<0)
> return rc;
> - msleep(100);
> + msleep(10);
> rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
> TM6000_GPIO_CLK, 1);
> - msleep(100);
> + msleep(10);
> + break;
> + }
> + break;
> +
> + case SWITCH_TV_MODE:
> + /* switch between analog and digital */
> + switch (arg) {
> + case 0:
> + printk(KERN_INFO "switch to analog");
> + tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_5, 1);
> + printk(KERN_INFO "analog");
> + break;
> + case 1:
> + printk(KERN_INFO "switch to digital");
> + tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_5, 0);
> + printk(KERN_INFO "digital");
> break;
> }
> + break;
> }
Those tuner callback initializations are board-specific. So, it is better to test
for your board model, if you need something different than what's currently done.
> +
> return (rc);
> }
>
> @@ -290,7 +332,7 @@ static void tm6000_config_tuner (struct tm6000_core
> *dev)
> memset(&tun_setup, 0, sizeof(tun_setup));
> tun_setup.type = dev->tuner_type;
> tun_setup.addr = dev->tuner_addr;
> - tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
> + tun_setup.mode_mask = T_ANALOG_TV | T_RADIO | T_DIGITAL_TV;
> tun_setup.tuner_callback = tm6000_tuner_callback;
>
> v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr,
> &tun_setup);
> @@ -302,15 +344,19 @@ static void tm6000_config_tuner (struct
> tm6000_core *dev)
> memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
> memset (&ctl,0,sizeof(ctl));
>
> - ctl.mts = 1;
> - ctl.read_not_reliable = 1;
> + ctl.input1 = 1;
> + ctl.read_not_reliable = 0;
> ctl.msleep = 10;
> -
> + ctl.demod = XC3028_FE_ZARLINK456;
> + ctl.vhfbw7 = 1;
> + ctl.uhfbw8 = 1;
> + ctl.switch_mode = 1;
> xc2028_cfg.tuner = TUNER_XC2028;
> xc2028_cfg.priv = &ctl;
>
> switch(dev->model) {
> case TM6010_BOARD_HAUPPAUGE_900H:
> + case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
> ctl.fname = "xc3028L-v36.fw";
> break;
> default:
> @@ -402,6 +448,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
> }
> #endif
> }
> + return 0;
>
> err2:
> v4l2_device_unregister(&dev->v4l2_dev);
This hunk also looks a bug fix. If so, please submit as a separate patch.
> @@ -459,13 +506,13 @@ static int tm6000_usb_probe(struct usb_interface
> *interface,
> /* Check to see next free device and mark as used */
> nr=find_first_zero_bit(&tm6000_devused,TM6000_MAXBOARDS);
> if (nr >= TM6000_MAXBOARDS) {
> - printk ("tm6000: Supports only %i em28xx
> boards.\n",TM6000_MAXBOARDS);
> + printk ("tm6000: Supports only %i tm60xx
> boards.\n",TM6000_MAXBOARDS);
> usb_put_dev(usbdev);
> return -ENOMEM;
> }
Also a typo bug fix. I don't really mind if you fold this with another patch,
but the better would be to have a separate patch for it.
>
> /* Create and initialize dev struct */
> - dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> + dev = kzalloc(sizeof(*(dev)), GFP_KERNEL);
The extra parenthesis is uneeded here.
> if (dev == NULL) {
> printk ("tm6000" ": out of memory!\n");
> usb_put_dev(usbdev);
> diff --git a/drivers/staging/tm6000/tm6000-core.c
> b/drivers/staging/tm6000/tm6000-core.c
> index d41af1d..33bbbd3 100644
> --- a/drivers/staging/tm6000/tm6000-core.c
> +++ b/drivers/staging/tm6000/tm6000-core.c
> @@ -219,33 +219,53 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
>
> int tm6000_init_digital_mode (struct tm6000_core *dev)
> {
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
> -
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
> - msleep(50);
> -
> - tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
> - msleep(50);
> - tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
> - msleep(50);
> - tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
> - msleep(100);
> -
> + if (dev->dev_type == TM6010) {
> + int val;
> + u8 buf[2];
> +
> + /* digital init */
> + val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, 0);
> + val &= ~0x60;
> + tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, val);
> + val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, 0);
> + val |= 0x40;
> + tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, val);
> + tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xfe, 0x28);
> + tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe2, 0xfc);
> + tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe6, 0xff);
> + tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xf1, 0xfe);
> + tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
> + printk (KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
> +
> +
> + } else {
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
> +
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
> + msleep(50);
> +
> + tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
> + msleep(50);
> + tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
> + msleep(50);
> + tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
> + msleep(100);
> + }
> return 0;
> }
>
> @@ -394,7 +414,15 @@ struct reg_init tm6010_init_tab[] = {
> { REQ_07_SET_GET_AVREG, 0x3f, 0x00 },
>
> { REQ_05_SET_GET_USBREG, 0x18, 0x00 },
> -
> +
> + /* additional from Terratec Cinergy Hybrid XE */
> + { REQ_07_SET_GET_AVREG, 0xdc, 0xaa },
> + { REQ_07_SET_GET_AVREG, 0xdd, 0x30 },
> + { REQ_07_SET_GET_AVREG, 0xde, 0x20 },
> + { REQ_07_SET_GET_AVREG, 0xdf, 0xd0 },
> + { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 },
> + { REQ_07_SET_GET_AVREG, 0xd8, 0x2f },
> +
> /* set remote wakeup key:any key wakeup */
> { REQ_07_SET_GET_AVREG, 0xe5, 0xfe },
> { REQ_07_SET_GET_AVREG, 0xda, 0xff },
> @@ -404,6 +432,7 @@ int tm6000_init (struct tm6000_core *dev)
> {
> int board, rc=0, i, size;
> struct reg_init *tab;
> + u8 buf[40];
Why "40" ? Please avoid using magic numbers here, especially if you're
not checking at the logic if you're writing outside the buffer.
> if (dev->dev_type == TM6010) {
> tab = tm6010_init_tab;
> @@ -424,61 +453,129 @@ int tm6000_init (struct tm6000_core *dev)
> }
> }
>
> - msleep(5); /* Just to be conservative */
> -
> - /* Check board version - maybe 10Moons specific */
> - board=tm6000_get_reg16 (dev, 0x40, 0, 0);
> - if (board >=0) {
> - printk (KERN_INFO "Board version = 0x%04x\n",board);
> - } else {
> - printk (KERN_ERR "Error %i while retrieving board
> version\n",board);
> - }
> -
> + /* hack */
> if (dev->dev_type == TM6010) {
> - /* Turn xceive 3028 on */
> - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6010_GPIO_3, 0x01);
> - msleep(11);
> - }
> -
> - /* Reset GPIO1 and GPIO4. */
> - for (i=0; i< 2; i++) {
> - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> - dev->tuner_reset_gpio, 0x00);
> - if (rc<0) {
> - printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
> - return rc;
> - }
> -
> - msleep(10); /* Just to be conservative */
> - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> - dev->tuner_reset_gpio, 0x01);
> - if (rc<0) {
> - printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
> - return rc;
> - }
> -
> - msleep(10);
> - rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 0);
> - if (rc<0) {
> - printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
> - return rc;
> - }
> -
> - msleep(10);
> - rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 1);
> - if (rc<0) {
> - printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
> - return rc;
> - }
> -
> - if (!i) {
> - rc=tm6000_get_reg16(dev, 0x40,0,0);
> - if (rc>=0) {
> - printk ("board=%d\n", rc);
> +
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_4, 0);
> + msleep(15);
> +
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_1, 0);
> +
> + msleep(50);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_1, 1);
> +
> + msleep(15);
The reset code are device dependent. Please don't remove the previous code, or you'll
break the init for the other devices. Instead, add a switch above, checking for your
specific model. The better is to have all those device-specific initializations inside
tm6000-cards. Please take a look on how this is solved on em28xx driver.
> + tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x0010, 0x4400, buf, 2);
> +
> + msleep(15);
> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
> +
> + msleep(15);
> + buf[0] = 0x12;
> + buf[1] = 0x34;
> + tm6000_read_write_usb (dev, 0x40, 0x10, 0xf432, 0x0000, buf, 2);
> +
> + msleep(15);
> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
> +
> + msleep(15);
> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0x0032, 0x0000, buf, 2);
> +
> + msleep(15);
> + buf[0] = 0x00;
> + buf[1] = 0x01;
> + tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
> +
> + msleep(15);
> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0x00c0, 0x0000, buf, 39);
> +
> + msleep(15);
> + buf[0] = 0x00;
> + buf[1] = 0x00;
> + tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
> +
> + msleep(15);
> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0x7f1f, 0x0000, buf, 2);
> +// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf [1]);
> + msleep(15);
Insead, use tm6000_get_reg() or tm6000_set_reg(). Passing the USB direction as
0x40/0xc0 is very ugly, and makes the code harder to understand.
Also,
req=0x0e corresponds to REQ_14_SET_GET_I2C_WR2_RDN
req=0x10 corresponds to REQ_16_SET_GET_I2C_WR1_RDN
So, the above code is just reading/writing some data via I2C. It should be replaced
by some changes at the corresponding i2c driver for the devices that the above
code is controlling.
As a temporary hack, you might do some initialization by calling i2c_master_send/
i2c_master_recv. For example, em28xx driver has this hack:
/* FIXME: Should be replaced by a proper mt9m001 driver */
static int em28xx_initialize_mt9m001(struct em28xx *dev)
{
int i;
unsigned char regs[][3] = {
{ 0x0d, 0x00, 0x01, },
{ 0x0d, 0x00, 0x00, },
{ 0x04, 0x05, 0x00, }, /* hres = 1280 */
{ 0x03, 0x04, 0x00, }, /* vres = 1024 */
{ 0x20, 0x11, 0x00, },
{ 0x06, 0x00, 0x10, },
{ 0x2b, 0x00, 0x24, },
{ 0x2e, 0x00, 0x24, },
{ 0x35, 0x00, 0x24, },
{ 0x2d, 0x00, 0x20, },
{ 0x2c, 0x00, 0x20, },
{ 0x09, 0x0a, 0xd4, },
{ 0x35, 0x00, 0x57, },
};
for (i = 0; i < ARRAY_SIZE(regs); i++)
i2c_master_send(&dev->i2c_client, ®s[i][0], 3);
return 0;
}
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_4, 1);
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_0, 1);
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_7, 0);
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_5, 1);
> +
> + msleep(15);
Also, this is device-specific.
> +
> + for (i=0; i< size; i++) {
> + rc= tm6000_set_reg (dev, tab[i].req, tab[i].reg, tab[i].val);
> + if (rc<0) {
> + printk (KERN_ERR "Error %i while setting req %d, "
> + "reg %d to value %d\n", rc,
> + tab[i].req,tab[i].reg, tab[i].val);
> + return rc;
> }
> }
> +
> + msleep(15);
> +
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_4, 0);
> + msleep(15);
> +
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_1, 0);
> +
> + msleep(50);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_1, 1);
> +
> + msleep(15);
> + tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
> +// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_2, 1);
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_2, 0);
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_2, 1);
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_2, 1);
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_2, 0);
> + msleep(15);
> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
> + TM6010_GPIO_2, 1);
> + msleep(15);
> }
> + /* hack end */
Idem. All GPIO's are device-specific.
> +
> + msleep(5); /* Just to be conservative */
>
> + /* Check board version - maybe 10Moons specific */
> + if (dev->dev_type == TM5600) {
> + board=tm6000_get_reg16 (dev, 0x40, 0, 0);
> + if (board >=0) {
> + printk (KERN_INFO "Board version = 0x%04x\n",board);
> + } else {
> + printk (KERN_ERR "Error %i while retrieving board
> version\n",board);
> + }
> + }
> +
> msleep(50);
>
> return 0;
> diff --git a/drivers/staging/tm6000/tm6000-dvb.c
> b/drivers/staging/tm6000/tm6000-dvb.c
> index e900d6d..31458d3 100644
> --- a/drivers/staging/tm6000/tm6000-dvb.c
> +++ b/drivers/staging/tm6000/tm6000-dvb.c
> @@ -17,7 +17,9 @@
> Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> */
>
> +#include <linux/kernel.h>
> #include <linux/usb.h>
> +#include <compat.h>
>
> #include "tm6000.h"
> #include "tm6000-regs.h"
> @@ -30,17 +32,61 @@
>
> #include "tuner-xc2028.h"
>
> +static void inline print_err_status (struct tm6000_core *dev,
> + int packet, int status)
> +{
> + char *errmsg = "Unknown";
> +
> + switch(status) {
> + case -ENOENT:
> + errmsg = "unlinked synchronuously";
> + break;
> + case -ECONNRESET:
> + errmsg = "unlinked asynchronuously";
> + break;
> + case -ENOSR:
> + errmsg = "Buffer error (overrun)";
> + break;
> + case -EPIPE:
> + errmsg = "Stalled (device not responding)";
> + break;
> + case -EOVERFLOW:
> + errmsg = "Babble (bad cable?)";
> + break;
> + case -EPROTO:
> + errmsg = "Bit-stuff error (bad cable?)";
> + break;
> + case -EILSEQ:
> + errmsg = "CRC/Timeout (could be anything)";
> + break;
> + case -ETIME:
> + errmsg = "Device does not respond";
> + break;
> + }
> + if (packet<0) {
> + dprintk(dev, 1, "URB status %d [%s].\n",
> + status, errmsg);
> + } else {
> + dprintk(dev, 1, "URB packet %d, status %d [%s].\n",
> + packet, status, errmsg);
> + }
> +}
> +
> +
> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
> +static void tm6000_urb_received(struct urb *urb, struct pt_regs *ptregs)
> +#else
> static void tm6000_urb_received(struct urb *urb)
> +#endif
> {
> int ret;
> struct tm6000_core* dev = urb->context;
>
> - if(urb->status != 0){
> - printk(KERN_ERR "tm6000: status != 0\n");
> + if(urb->status != 0) {
> + print_err_status (dev,0,urb->status);
> }
> else if(urb->actual_length>0){
> - dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
> - urb->actual_length);
> + dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
> urb->actual_length);
> }
>
> if(dev->dvb->streams > 0) {
> @@ -56,49 +102,37 @@ static void tm6000_urb_received(struct urb *urb)
> int tm6000_start_stream(struct tm6000_core *dev)
> {
> int ret;
> - unsigned int pipe, maxPaketSize;
> + unsigned int pipe, size;
> struct tm6000_dvb *dvb = dev->dvb;
>
> printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
>
> tm6000_init_digital_mode(dev);
>
> -/*
> - ret = tm6000_set_led_status(tm6000_dev, 0x1);
> - if(ret < 0) {
> - return -1;
> - }
> -*/
> -
> dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
> if(dvb->bulk_urb == NULL) {
> printk(KERN_ERR "tm6000: couldn't allocate urb\n");
> return -ENOMEM;
> }
>
> - maxPaketSize = dev->bulk_in->desc.wMaxPacketSize;
> + pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
> + & USB_ENDPOINT_NUMBER_MASK);
> +
> + size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
> + size = size * 15; // 512 x 8 or 12 or 15
>
> - dvb->bulk_urb->transfer_buffer = kzalloc(maxPaketSize, GFP_KERNEL);
> + dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
> if(dvb->bulk_urb->transfer_buffer == NULL) {
> usb_free_urb(dvb->bulk_urb);
> printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
> return -ENOMEM;
> }
> -
> - pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
> - & USB_ENDPOINT_NUMBER_MASK);
> -
> +
> usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
> dvb->bulk_urb->transfer_buffer,
> - maxPaketSize,
> + size,
> tm6000_urb_received, dev);
>
> - ret = usb_set_interface(dev->udev, 0, 1);
> - if(ret < 0) {
> - printk(KERN_ERR "tm6000: error %i in %s during set
> interface\n", ret, __FUNCTION__);
> - return ret;
> - }
> -
> ret = usb_clear_halt(dev->udev, pipe);
> if(ret < 0) {
> printk(KERN_ERR "tm6000: error %i in %s during pipe
> reset\n",ret,__FUNCTION__);
> @@ -107,15 +141,14 @@ int tm6000_start_stream(struct tm6000_core *dev)
> else {
> printk(KERN_ERR "tm6000: pipe resetted\n");
> }
> -
> -// mutex_lock(&tm6000_driver.open_close_mutex);
> +
> +// mutex_lock(&tm6000_driver.open_close_mutex);
> ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
>
> -
> -// mutex_unlock(&tm6000_driver.open_close_mutex);
> +// mutex_unlock(&tm6000_driver.open_close_mutex);
> if (ret) {
> printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",ret);
> -
> +
> kfree(dvb->bulk_urb->transfer_buffer);
> usb_free_urb(dvb->bulk_urb);
> return ret;
> @@ -126,18 +159,12 @@ int tm6000_start_stream(struct tm6000_core *dev)
>
> void tm6000_stop_stream(struct tm6000_core *dev)
> {
> - int ret;
> struct tm6000_dvb *dvb = dev->dvb;
>
> -// tm6000_set_led_status(tm6000_dev, 0x0);
> -
> - ret = usb_set_interface(dev->udev, 0, 0);
> - if(ret < 0) {
> - printk(KERN_ERR "tm6000: error %i in %s during set
> interface\n",ret,__FUNCTION__);
> - }
> -
> if(dvb->bulk_urb) {
> + printk (KERN_INFO "urb killing\n");
> usb_kill_urb(dvb->bulk_urb);
> + printk (KERN_INFO "urb buffer free\n");
> kfree(dvb->bulk_urb->transfer_buffer);
> usb_free_urb(dvb->bulk_urb);
> dvb->bulk_urb = NULL;
> @@ -154,7 +181,7 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
> mutex_lock(&dvb->mutex);
> if(dvb->streams == 0) {
> dvb->streams = 1;
> -// mutex_init(&tm6000_dev->streaming_mutex);
> +// mutex_init(&tm6000_dev->streming_mutex);
> tm6000_start_stream(dev);
> }
> else {
> @@ -173,14 +200,17 @@ int tm6000_stop_feed(struct dvb_demux_feed *feed) {
> printk(KERN_INFO "tm6000: got stop feed request %s\n",__FUNCTION__);
>
> mutex_lock(&dvb->mutex);
> - --dvb->streams;
>
> - if(0 == dvb->streams) {
> + printk (KERN_INFO "stream %#x\n", dvb->streams);
> + --(dvb->streams);
> + if(dvb->streams == 0) {
> + printk (KERN_INFO "stop stream\n");
> tm6000_stop_stream(dev);
> -// mutex_destroy(&tm6000_dev->streaming_mutex);
> +// mutex_destroy(&tm6000_dev->streaming_mutex);
> }
> +
> mutex_unlock(&dvb->mutex);
> -// mutex_destroy(&tm6000_dev->streaming_mutex);
> +// mutex_destroy(&tm6000_dev->streaming_mutex);
>
> return 0;
> }
> @@ -191,13 +221,16 @@ int tm6000_dvb_attach_frontend(struct tm6000_core
> *dev)
>
> if(dev->caps.has_zl10353) {
> struct zl10353_config config =
> - {.demod_address = dev->demod_addr >> 1,
> + {.demod_address = dev->demod_addr,
> .no_tuner = 1,
> -// .input_frequency = 0x19e9,
> -// .r56_agc_targets = 0x1c,
> + .parallel_ts = 1,
> + .if2 = 45700,
> + .disable_i2c_gate_ctrl = 1,
> + .tm6000 = 1,
> };
>
> dvb->frontend = pseudo_zl10353_attach(dev, &config,
> +// dvb->frontend = dvb_attach (zl10353_attach, &config,
Don't use C99 comments. Always comment with /* */
> &dev->i2c_adap);
> }
> else {
> @@ -235,7 +268,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
> .i2c_adap = &dev->i2c_adap,
> .i2c_addr = dev->tuner_addr,
> };
> -
> +
> + dvb->frontend->callback = tm6000_tuner_callback;
> ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
> if (ret < 0) {
> printk(KERN_ERR
> @@ -258,8 +292,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
> dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
> | DMX_MEMORY_BASED_FILTERING;
> dvb->demux.priv = dev;
> - dvb->demux.filternum = 256;
> - dvb->demux.feednum = 256;
> + dvb->demux.filternum = 5; //256;
> + dvb->demux.feednum = 5; //256;
Don't use C99 comments. Always comment with /* */
> dvb->demux.start_feed = tm6000_start_feed;
> dvb->demux.stop_feed = tm6000_stop_feed;
> dvb->demux.write_to_decoder = NULL;
> @@ -307,7 +341,7 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
> usb_free_urb(bulk_urb);
> }
>
> -// mutex_lock(&tm6000_driver.open_close_mutex);
> +// mutex_lock(&tm6000_driver.open_close_mutex);
> if(dvb->frontend) {
> dvb_frontend_detach(dvb->frontend);
> dvb_unregister_frontend(dvb->frontend);
> @@ -317,6 +351,6 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
> dvb_dmx_release(&dvb->demux);
> dvb_unregister_adapter(&dvb->adapter);
> mutex_destroy(&dvb->mutex);
> -// mutex_unlock(&tm6000_driver.open_close_mutex);
> +// mutex_unlock(&tm6000_driver.open_close_mutex);
>
> }
Please send a separate patch for the dvb fixes.
> diff --git a/drivers/staging/tm6000/tm6000-i2c.c
> b/drivers/staging/tm6000/tm6000-i2c.c
> index 4da10f5..3e43ad7 100644
> --- a/drivers/staging/tm6000/tm6000-i2c.c
> +++ b/drivers/staging/tm6000/tm6000-i2c.c
> @@ -86,6 +86,11 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
> msgs[i].len == 1 ? 0 : msgs[i].buf[1],
> msgs[i + 1].buf, msgs[i + 1].len);
> i++;
> +
> + if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
> + tm6000_set_reg(dev, 0x32, 0,0);
> + tm6000_set_reg(dev, 0x33, 0,0);
> + }
> if (i2c_debug >= 2)
> for (byte = 0; byte < msgs[i].len; byte++)
> printk(" %02x", msgs[i].buf[byte]);
> @@ -99,6 +104,12 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
> REQ_16_SET_GET_I2C_WR1_RDN,
> addr | msgs[i].buf[0] << 8, 0,
> msgs[i].buf + 1, msgs[i].len - 1);
> +
> +
> + if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
> + tm6000_set_reg(dev, 0x32, 0,0);
> + tm6000_set_reg(dev, 0x33, 0,0);
> + }
> }
Please send a separate patch for the i2c fixes.
On both logic, don't check for 0xc2, but for the i2c address of the tuner. I
have here one device with a tm6000. After having this patch applied,
I'll test with it, and see if setting those two register values to 0 also fixes
for tm6000.
> if (i2c_debug >= 2)
> printk("\n");
> @@ -198,7 +209,7 @@ static struct i2c_algorithm tm6000_algo = {
>
> static struct i2c_adapter tm6000_adap_template = {
> .owner = THIS_MODULE,
> - .class = I2C_CLASS_TV_ANALOG,
> + .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
> .name = "tm6000",
> .id = I2C_HW_B_TM6000,
> .algo = &tm6000_algo,
> diff --git a/drivers/staging/tm6000/tm6000.h
> b/drivers/staging/tm6000/tm6000.h
> index 877cbf6..e403ca0 100644
> --- a/drivers/staging/tm6000/tm6000.h
> +++ b/drivers/staging/tm6000/tm6000.h
> @@ -23,12 +23,15 @@
> // Use the tm6000-hack, instead of the proper initialization code
> //#define HACK 1
>
> +#include "compat.h"
> #include <linux/videodev2.h>
> #include <media/v4l2-common.h>
> #include <media/videobuf-vmalloc.h>
> #include "tm6000-usb-isoc.h"
> #include <linux/i2c.h>
> +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
> #include <linux/mutex.h>
> +#endif
> #include <media/v4l2-device.h>
>
>
> @@ -78,6 +81,10 @@ struct tm6000_dmaqueue {
> /* thread for generating video stream*/
> struct task_struct *kthread;
> wait_queue_head_t wq;
> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
> + struct semaphore *notify;
> + int rmmod:1;
> +#endif
You may just drop the code for kernels < 2.6 (on a separate patch). The current
backport starts with 2.6.16.
> /* Counters to control fps rate */
> int frame;
> int ini_jiffies;
> @@ -90,12 +97,14 @@ enum tm6000_core_state {
> DEV_MISCONFIGURED = 0x04,
> };
>
> +#if 1
> /* io methods */
> enum tm6000_io_method {
> IO_NONE,
> IO_READ,
> IO_MMAP,
> };
> +#endif
>
> enum tm6000_mode {
> TM6000_MODE_UNKNOWN=0,
> @@ -202,6 +211,9 @@ struct tm6000_fh {
> V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
> V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM
>
> +/* In tm6000-cards.c */
> +
> +int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
> /* In tm6000-core.c */
>
> int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
> @@ -209,7 +221,6 @@ int tm6000_read_write_usb (struct tm6000_core *dev,
> u8 reqtype, u8 req,
> int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
> int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
> int tm6000_init (struct tm6000_core *dev);
> -int tm6000_init_after_firmware (struct tm6000_core *dev);
>
> int tm6000_init_analog_mode (struct tm6000_core *dev);
> int tm6000_init_digital_mode (struct tm6000_core *dev);
> @@ -231,7 +242,12 @@ int tm6000_set_standard (struct tm6000_core *dev,
> v4l2_std_id *norm);
> int tm6000_i2c_register(struct tm6000_core *dev);
> int tm6000_i2c_unregister(struct tm6000_core *dev);
>
> +#if 1
> /* In tm6000-queue.c */
> +#if 0
> +int tm6000_init_isoc(struct tm6000_core *dev, int max_packets);
> +void tm6000_uninit_isoc(struct tm6000_core *dev);
> +#endif
>
> int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
>
> @@ -276,3 +292,4 @@ extern int tm6000_debug;
> __FUNCTION__ , ##arg); } while (0)
>
>
> +#endif
>
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-01 22:00 ` Stefan Ringel
@ 2010-02-01 23:05 ` Mauro Carvalho Chehab
2010-02-02 16:14 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-01 23:05 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Devin Heitmueller, linux-media
Stefan Ringel wrote:
> Am 01.02.2010 22:44, schrieb Devin Heitmueller:
>> On Mon, Feb 1, 2010 at 4:23 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>>
>>>> You should start by breaking it down into a patch series, so that the
>>>> incremental changes can be reviewed. That will allow you to explain
>>>> in the patch descriptions why all the individual changes you have made
>>>> are required.
>>>>
>>>>
>>>>
>>> how can I generate it?
>>>
>> You can use quilt to break it up into a patch series, or create a
>> local hg clone of v4l-dvb.
>>
>>
>>>> Why did you define a new callback for changing the tuner mode? We
>>>> have successfully provided infrastructure on other bridges to toggle
>>>> GPIOs when changing modes. For example, the em28xx has fields in the
>>>> board profile that allow you to toggle GPIOs when going back and forth
>>>> between digital and analog mode.
>>>>
>>>>
>>>>
>>> I don't know, how you mean it. I'm amateur programmer.
>>>
>> Look at how the ".dvb_gpio" and ".gpio" fields are used in the board
>> profiles in em28xx-cards.c. We toggle the GPIOs when switching the
>> from analog to digital mode, without the tuner having to do any sort
>> of callback.
>>
>>
> It's a bad example. em28xx use a reg-set, but tm6000 not !! It use a
> gpio usb request.
>
> tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6010_GPIO_5, 1);
>
>
> I don't know, that it with the ".gpio" fields works. And when it switch
> from analog to digital, I don't see the way.
All devices with Xceive tuners need to reset the chip via GPIO, in order to load
the firmware. On em28xx, I wrote a patch that moved all specific init code to
a struct (basically used by gpio's), and a generic code to do the reset. It basically
contains what GPIO pins are used, and how many time it should wait.
For example:
/* Board Hauppauge WinTV HVR 900 digital */
static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
{EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
{EM2880_R04_GPO, 0x04, 0x0f, 10},
{EM2880_R04_GPO, 0x0c, 0x0f, 10},
{ -1, -1, -1, -1},
};
The first line of the above code will execute this logic:
a = read(EM28XXR08_GPIO) & ~0x2e;
write (a & ~EM_GPIO_4);
msleep(10);
So, it will basically preserve bits 8,7,6,4 and 1 of register 8,
and will clear bit 4 (EM_GPIO_4 is 1 << 4 - e. g. bit 4).
After that, it will sleep for 10 miliseconds, and will then do a
reset on bit 3 of Register 4 (writing 0, then 1 to the bit).
>
>>>> What function does the "tm6000" member in the zl10353 config do? It
>>>> doesn't seem to be used anywhere.
>>>>
>>>>
>>>>
>>> I'll switch it next week to demodulator module.
>>>
>> Are you saying the zl10353 isn't working right now in your patch? I'm
>> a bit confused. If it doesn't work, then your patch title is a bit
>> misleading since it suggests that your patch provides DVB support for
>> the tm6000. If it does work, then the tm6000 member shouldn't be
>> needed at all in the zl10353 config.
>>
>>
> I'm emulating it in hack.c and the zl10353 module doesn't work, if I
> switch to it.
the hack.c needs to be validated against the zl10353, in order to identify
what are the exact needs for tm6000. Some devices require serial mode, while
others require parallel mode.
I bet that playing with zl10353_config, we'll find the proper init values
required by tm6000.
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-01 23:05 ` Mauro Carvalho Chehab
@ 2010-02-02 16:14 ` Stefan Ringel
2010-02-02 16:44 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-02 16:14 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: Devin Heitmueller, linux-media
Am 02.02.2010 00:05, schrieb Mauro Carvalho Chehab:
> Stefan Ringel wrote:
>
>> Am 01.02.2010 22:44, schrieb Devin Heitmueller:
>>
>>> On Mon, Feb 1, 2010 at 4:23 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>>>
>>>
>>>>> You should start by breaking it down into a patch series, so that the
>>>>> incremental changes can be reviewed. That will allow you to explain
>>>>> in the patch descriptions why all the individual changes you have made
>>>>> are required.
>>>>>
>>>>>
>>>>>
>>>>>
>>>> how can I generate it?
>>>>
>>>>
>>> You can use quilt to break it up into a patch series, or create a
>>> local hg clone of v4l-dvb.
>>>
>>>
>>>
>>>>> Why did you define a new callback for changing the tuner mode? We
>>>>> have successfully provided infrastructure on other bridges to toggle
>>>>> GPIOs when changing modes. For example, the em28xx has fields in the
>>>>> board profile that allow you to toggle GPIOs when going back and forth
>>>>> between digital and analog mode.
>>>>>
>>>>>
>>>>>
>>>>>
>>>> I don't know, how you mean it. I'm amateur programmer.
>>>>
>>>>
>>> Look at how the ".dvb_gpio" and ".gpio" fields are used in the board
>>> profiles in em28xx-cards.c. We toggle the GPIOs when switching the
>>> from analog to digital mode, without the tuner having to do any sort
>>> of callback.
>>>
>>>
>>>
>> It's a bad example. em28xx use a reg-set, but tm6000 not !! It use a
>> gpio usb request.
>>
>> tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6010_GPIO_5, 1);
>>
>>
>> I don't know, that it with the ".gpio" fields works. And when it switch
>> from analog to digital, I don't see the way.
>>
> All devices with Xceive tuners need to reset the chip via GPIO, in order to load
> the firmware. On em28xx, I wrote a patch that moved all specific init code to
> a struct (basically used by gpio's), and a generic code to do the reset. It basically
> contains what GPIO pins are used, and how many time it should wait.
>
> For example:
>
> /* Board Hauppauge WinTV HVR 900 digital */
> static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
> {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10},
> {EM2880_R04_GPO, 0x04, 0x0f, 10},
> {EM2880_R04_GPO, 0x0c, 0x0f, 10},
> { -1, -1, -1, -1},
> };
>
> The first line of the above code will execute this logic:
> a = read(EM28XXR08_GPIO) & ~0x2e;
> write (a & ~EM_GPIO_4);
> msleep(10);
>
>
> So, it will basically preserve bits 8,7,6,4 and 1 of register 8,
> and will clear bit 4 (EM_GPIO_4 is 1 << 4 - e. g. bit 4).
> After that, it will sleep for 10 miliseconds, and will then do a
> reset on bit 3 of Register 4 (writing 0, then 1 to the bit).
>
reset example :
static struct tm6010_seq terratec[] = {
{TM6010_GPIO_2, 1, 60}, /* GPIO 2 going to high */
{TM6010_GPIO_2, 0, 75}, /* GPIO 2 going to lo */
{TM6010_GPIO_2, 1, 60}, /* GPIO 2 going to high */
{ -1 , -1, -1},
}
Is that correct?
>>
>>>>> What function does the "tm6000" member in the zl10353 config do? It
>>>>> doesn't seem to be used anywhere.
>>>>>
>>>>>
>>>>>
>>>>>
>>>> I'll switch it next week to demodulator module.
>>>>
>>>>
>>> Are you saying the zl10353 isn't working right now in your patch? I'm
>>> a bit confused. If it doesn't work, then your patch title is a bit
>>> misleading since it suggests that your patch provides DVB support for
>>> the tm6000. If it does work, then the tm6000 member shouldn't be
>>> needed at all in the zl10353 config.
>>>
>>>
>>>
>> I'm emulating it in hack.c and the zl10353 module doesn't work, if I
>> switch to it.
>>
> the hack.c needs to be validated against the zl10353, in order to identify
> what are the exact needs for tm6000. Some devices require serial mode, while
> others require parallel mode.
>
> I bet that playing with zl10353_config, we'll find the proper init values
> required by tm6000.
>
>
I have separately write in the hack.c the value from terratec hybrid
stick. The older value I haven't clean.
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-02 16:14 ` Stefan Ringel
@ 2010-02-02 16:44 ` Mauro Carvalho Chehab
2010-02-02 17:38 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-02 16:44 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Devin Heitmueller, linux-media
Stefan Ringel wrote:
>> So, it will basically preserve bits 8,7,6,4 and 1 of register 8,
>> and will clear bit 4 (EM_GPIO_4 is 1 << 4 - e. g. bit 4).
>> After that, it will sleep for 10 miliseconds, and will then do a
>> reset on bit 3 of Register 4 (writing 0, then 1 to the bit).
>>
>
> reset example :
>
> static struct tm6010_seq terratec[] = {
> {TM6010_GPIO_2, 1, 60}, /* GPIO 2 going to high */
> {TM6010_GPIO_2, 0, 75}, /* GPIO 2 going to lo */
> {TM6010_GPIO_2, 1, 60}, /* GPIO 2 going to high */
> { -1 , -1, -1},
> }
>
> Is that correct?
Yes. In the case of tm6010, it has separate registers for each GPIO, so, you
don't need a bitmask.
>> the hack.c needs to be validated against the zl10353, in order to identify
>> what are the exact needs for tm6000. Some devices require serial mode, while
>> others require parallel mode.
>>
>> I bet that playing with zl10353_config, we'll find the proper init values
>> required by tm6000.
>>
>>
>
> I have separately write in the hack.c the value from terratec hybrid
> stick. The older value I haven't clean.
Ok, but maybe you missed my point: at the long term, we should get rid of hack.c, and
be sure that all needed initializations are done by zl10353 driver or by tm6010-dvb.
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-01 22:52 ` Mauro Carvalho Chehab
@ 2010-02-02 17:24 ` Stefan Ringel
2010-02-02 20:03 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-02 17:24 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
Am 01.02.2010 23:52, schrieb Mauro Carvalho Chehab:
> Stefan Ringel wrote:
>
>> add Terratec Cinergy Hybrid XE
>> bugfix i2c transfer
>> add frontend callback
>> add init for tm6010
>> add digital-init for tm6010
>> add callback for analog/digital switch
>> bugfix usb transfer in DVB-mode
>>
>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>
> Devin is right with respect to the changes: you should break into small
> patches for us to better understand what you're doing.
>
> In particular, some parts of the changes (like tuner-xc2028) are known
> to be working fine with other drivers, so any change there should be done
> with the enough care to not break other drivers.
>
>
>> diff --git a/drivers/media/common/tuners/tuner-xc2028.c
>> b/drivers/media/common/tuners/tuner-xc2028.c
>> index ed50168..2297c00 100644
>> --- a/drivers/media/common/tuners/tuner-xc2028.c
>> +++ b/drivers/media/common/tuners/tuner-xc2028.c
>> @@ -15,6 +15,7 @@
>> #include <linux/delay.h>
>> #include <media/tuner.h>
>> #include <linux/mutex.h>
>> +#include "compat.h"
>> #include <asm/unaligned.h>
>> #include "tuner-i2c.h"
>> #include "tuner-xc2028.h"
>> @@ -994,6 +995,13 @@ static int generic_set_freq(struct dvb_frontend
>> *fe, u32 freq /* in HZ */,
>> buf[0], buf[1], buf[2], buf[3],
>> freq / 1000000, (freq % 1000000) / 1000);
>>
>> + if (priv->ctrl.switch_mode) {
>> + if (new_mode == T_ANALOG_TV)
>> + do_tuner_callback(fe, SWITCH_TV_MODE, 0);
>> + if (new_mode == T_DIGITAL_TV)
>> + do_tuner_callback(fe, SWITCH_TV_MODE, 1);
>> + }
>> +
>> rc = 0;
>>
> The decision taken at the driver were the opposite: the bridge driver should
> have the logic to reset the tuner. This works perfectly on em28xx and other
> drivers that use xc3028.
>
> I don't see a good reason to revert the logic here. Also, such change should
> be done on all drivers that use xc3028 and xc5000.
>
>
>>
>> ret:
>> @@ -1114,7 +1122,11 @@ static int xc2028_set_params(struct dvb_frontend *fe,
>>
>> /* All S-code tables need a 200kHz shift */
>> if (priv->ctrl.demod) {
>> - demod = priv->ctrl.demod + 200;
>> + if (priv->ctrl.fname == "xc3028L-v36.fw") {
>> + demod = priv->ctrl.demod;
>> + } else {
>> + demod = priv->ctrl.demod + 200;
>> + }
>>
> Instead, you should be using the firmware version.
>
> As the firmware version is written at the firmware file, it is easy to do the tests
> based on the firmware version, even on devices like tm6000 where the version read
> method may fail.
>
Not with the i2c patch, see down.
>
> Yet, I suspect that the currently available v36 firmwares already take this into
> consideration (or the drivers that use those firmwares do the offset internally).
>
> So, this change needs to be checked against the existing drivers.
>
>
>> /*
>> * The DTV7 S-code table needs a 700 kHz shift.
>> * Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
>> @@ -1123,8 +1135,8 @@ static int xc2028_set_params(struct dvb_frontend *fe,
>> * use this firmware after initialization, but a tune to a UHF
>> * channel should then cause DTV78 to be used.
>> */
>> - if (type & DTV7)
>> - demod += 500;
>> + if (type & DTV7)
>> + demod += 500;
>>
> This hunk is wrong.
>
>
Why that generated the git diff, I cannot say. It must be the older once.
>> }
>>
>> return generic_set_freq(fe, p->frequency,
>> @@ -1240,6 +1252,10 @@ static const struct dvb_tuner_ops
>> xc2028_dvb_tuner_ops = {
>> .get_rf_strength = xc2028_signal,
>> .set_params = xc2028_set_params,
>> .sleep = xc2028_sleep,
>> +#if 0
>> + int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
>> + int (*get_status)(struct dvb_frontend *fe, u32 *status);
>> +#endif
>> };
>>
>> struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
>> diff --git a/drivers/media/common/tuners/tuner-xc2028.h
>> b/drivers/media/common/tuners/tuner-xc2028.h
>> index 9778c96..c9a4fb4 100644
>> --- a/drivers/media/common/tuners/tuner-xc2028.h
>> +++ b/drivers/media/common/tuners/tuner-xc2028.h
>> @@ -42,6 +42,7 @@ struct xc2028_ctrl {
>> unsigned int disable_power_mgmt:1;
>> unsigned int read_not_reliable:1;
>> unsigned int demod;
>> + unsigned int switch_mode:1;
>>
> This struct is meant to pass static parameters to the driver. the analog/digital
> mode is dynamic, so, this is not the right place for doing it.
>
>
Can you tell me how that work? Where would call it? Switch it after read
demodulator status or before? This switch switches the tuner output to
the demodulator or adc input and if it read status before it switch
thoughts the apps "no digital found".
>> enum firmware_type type:2;
>> };
>>
>> @@ -54,6 +55,7 @@ struct xc2028_config {
>> /* xc2028 commands for callback */
>> #define XC2028_TUNER_RESET 0
>> #define XC2028_RESET_CLK 1
>> +#define SWITCH_TV_MODE 2
>>
>> #if defined(CONFIG_MEDIA_TUNER_XC2028) ||
>> (defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
>> extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
>> diff --git a/drivers/media/dvb/frontends/zl10353.h
>> b/drivers/media/dvb/frontends/zl10353.h
>> index 6e3ca9e..015bc36 100644
>> --- a/drivers/media/dvb/frontends/zl10353.h
>> +++ b/drivers/media/dvb/frontends/zl10353.h
>> @@ -45,6 +45,8 @@ struct zl10353_config
>> /* clock control registers (0x51-0x54) */
>> u8 clock_ctl_1; /* default: 0x46 */
>> u8 pll_0; /* default: 0x15 */
>> +
>> + int tm6000:1;
>>
> This doesn't make sense. The zl10353 doesn't need to know if the device is
> a tm6000 or not. If the tm6000 driver needs something special, then we need
> to discover what he is doing and name the zl10353 feature accordingly.
>
>
>
that is for todo in next week, when I switch from hack.c to zl10353
kernel module, but it can remove if it don't use.
>> };
>>
>> #if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE)
>> && defined(MODULE))
>> diff --git a/drivers/staging/tm6000/hack.c b/drivers/staging/tm6000/hack.c
>> index f181fce..c1e1880 100644
>> --- a/drivers/staging/tm6000/hack.c
>> +++ b/drivers/staging/tm6000/hack.c
>> @@ -37,7 +37,6 @@ static inline int tm6000_snd_control_msg(struct
>> tm6000_core *dev, __u8 request,
>>
> This "hack" file is a good candidate to be removed ;) It is, in fact a zl10353
> code with the tm6000 initialization, made by cloning the zl10353 parameters
> that the original driver does.
>
>
>>
>> static int pseudo_zl10353_pll(struct tm6000_core *tm6000_dev, struct
>> dvb_frontend_parameters *p)
>> {
>> - int ret;
>> u8 *data = kzalloc(50*sizeof(u8), GFP_KERNEL);
>>
>> printk(KERN_ALERT "should set frequency %u\n", p->frequency);
>> @@ -51,7 +50,7 @@ printk(KERN_ALERT "and bandwith %u\n",
>> p->u.ofdm.bandwidth);
>> }
>>
>> // init ZL10353
>> - data[0] = 0x0b;
>> +/* data[0] = 0x0b;
>> ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x501e, 0x00, data,
>> 0x1);
>> msleep(15);
>> data[0] = 0x80;
>> @@ -159,7 +158,7 @@ printk(KERN_ALERT "and bandwith %u\n",
>> p->u.ofdm.bandwidth);
>> msleep(15);
>> data[0] = 0x5a;
>> ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x651e,
>> 0x00, data, 0x1);
>> - msleep(15);
>> + msleep(15)
>> data[0] = 0xe9;
>> ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x661e,
>> 0x00, data, 0x1);
>> msleep(15);
>> @@ -189,7 +188,162 @@ printk(KERN_ALERT "and bandwith %u\n",
>> p->u.ofdm.bandwidth);
>> msleep(15);
>> break;
>> }
>> -
>> +*/
>>
> Please use #if 0 to temporarily remove a code that it is not needed. Yet, maybe
> removing this code will break tm6000 devices. tm6010 has some differences
> when compared with tm6000. So, if your device is tm6010, the better is to
> run the above code if is not a tm6010.
>
>
o. k.
>> + switch(p->u.ofdm.bandwidth) {
>> + case BANDWIDTH_8_MHZ:
>> + data[0] = 0x03;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x44;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x40;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x46;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x15;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x0f;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x80;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x01;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x00;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x8b;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x75;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0xe6; //0x19;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x09; //0xf7;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x67;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
>> + msleep(40);
>> + data[0] = 0xe5;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x75;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x17;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x40;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x01;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
>> + msleep(40);
>> + break;
>> + case BANDWIDTH_7_MHZ:
>> + data[0] = 0x03;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x44;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x40;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x46;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x15;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x0f;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x80;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x01;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x00;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x83;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
>> + msleep(40);
>> + data[0] = 0xa3;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0xe6; //0x19;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x09; //0xf7;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x5a;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
>> + msleep(40);
>> + data[0] = 0xe9;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x86;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x17;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x40;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
>> + msleep(40);
>> + data[0] = 0x01;
>> + tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
>> + msleep(40);
>> + break;
>> + default:
>> + printk(KERN_ALERT "tm6000: bandwidth not supported\n");
>> + }
>> +
>> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
>> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
>> + msleep(40);
>> +
>> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
>> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
>> + msleep(40);
>> +
>> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
>> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
>> + msleep(40);
>> +
>> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
>> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
>> + msleep(40);
>> +
>> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
>> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
>> + msleep(40);
>> +
>> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0f1f,0,data,2);
>> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
>> + msleep(40);
>> +
>> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x091f,0,data,2);
>> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
>> + msleep(40);
>> +
>> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0b1f,0,data,2);
>> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
>> + msleep(40);
>>
> The same comment here: maybe the above code only applies to tm6010.
>
>
It little different to the other hack code. The lastest lines are
reading demod status.
>> +
>> kfree(data);
>>
>> return 0;
>> diff --git a/drivers/staging/tm6000/tm6000-cards.c
>> b/drivers/staging/tm6000/tm6000-cards.c
>> index 59fb505..652a54a 100644
>> --- a/drivers/staging/tm6000/tm6000-cards.c
>> +++ b/drivers/staging/tm6000/tm6000-cards.c
>> @@ -32,7 +32,7 @@
>> #include "tm6000.h"
>> #include "tm6000-regs.h"
>> #include "tuner-xc2028.h"
>> -#include "tuner-xc5000.h"
>> +#include "xc5000.h"
>>
> Please send this hunk on a separate patch. Since it fixes compilation, I'll
> need to apply it before the Kconfig changes, when tm6000 upstream.
>
>
o.k. but I cannot know how. I have no idea with diff or something.
>>
>> #define TM6000_BOARD_UNKNOWN 0
>> #define TM5600_BOARD_GENERIC 1
>> @@ -44,6 +44,10 @@
>> #define TM6000_BOARD_FREECOM_AND_SIMILAR 7
>> #define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
>> #define TM6010_BOARD_HAUPPAUGE_900H 9
>> +#define TM6010_BOARD_BEHOLD_WANDER 10
>> +#define TM6010_BOARD_BEHOLD_VOYAGER 11
>> +#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
>> +
>>
>> #define TM6000_MAXBOARDS 16
>> static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
>> @@ -208,7 +212,21 @@ struct tm6000_board tm6000_boards[] = {
>> },
>> .gpio_addr_tun_reset = TM6000_GPIO_2,
>> },
>> -
>> + [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
>> + .name = "Terratec Cinergy Hybrid XE",
>> + .tuner_type = TUNER_XC2028, /* has a XC3028 */
>> + .tuner_addr = 0xc2 >> 1,
>> + .demod_addr = 0x1e >> 1,
>> + .type = TM6010,
>> + .caps = {
>> + .has_tuner = 1,
>> + .has_dvb = 1,
>> + .has_zl10353 = 1,
>> + .has_eeprom = 1,
>> + .has_remote = 1,
>> + },
>> + .gpio_addr_tun_reset = TM6010_GPIO_2,
>> + }
>> };
>>
>> /* table of devices that work with this driver */
>> @@ -221,12 +239,13 @@ struct usb_device_id tm6000_id_table [] = {
>> { USB_DEVICE(0x2040, 0x6600), .driver_info =
>> TM6010_BOARD_HAUPPAUGE_900H },
>> { USB_DEVICE(0x6000, 0xdec0), .driver_info =
>> TM6010_BOARD_BEHOLD_WANDER },
>> { USB_DEVICE(0x6000, 0xdec1), .driver_info =
>> TM6010_BOARD_BEHOLD_VOYAGER },
>> + { USB_DEVICE(0x0ccd, 0x0086), .driver_info =
>> TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
>> { },
>> };
>>
> New board definition: please send this as a separate patch.
>
>
>>
>> /* Tuner callback to provide the proper gpio changes needed for xc2028 */
>>
>> -static int tm6000_tuner_callback(void *ptr, int component, int command,
>> int arg)
>> +int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
>> {
>> int rc=0;
>> struct tm6000_core *dev = ptr;
>> @@ -252,11 +271,14 @@ static int tm6000_tuner_callback(void *ptr, int
>> component, int command, int arg)
>> switch (arg) {
>> case 0:
>> tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
>> + dev->tuner_reset_gpio, 0x01);
>> + msleep(60);
>> + tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
>> dev->tuner_reset_gpio, 0x00);
>> - msleep(130);
>> + msleep(75);
>> tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
>> dev->tuner_reset_gpio, 0x01);
>> - msleep(130);
>> + msleep(60);
>> break;
>> case 1:
>> tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT,
>> @@ -269,13 +291,33 @@ static int tm6000_tuner_callback(void *ptr, int
>> component, int command, int arg)
>> TM6000_GPIO_CLK, 0);
>> if (rc<0)
>> return rc;
>> - msleep(100);
>> + msleep(10);
>> rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
>> TM6000_GPIO_CLK, 1);
>> - msleep(100);
>> + msleep(10);
>> + break;
>> + }
>> + break;
>> +
>> + case SWITCH_TV_MODE:
>> + /* switch between analog and digital */
>> + switch (arg) {
>> + case 0:
>> + printk(KERN_INFO "switch to analog");
>> + tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_5, 1);
>> + printk(KERN_INFO "analog");
>> + break;
>> + case 1:
>> + printk(KERN_INFO "switch to digital");
>> + tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_5, 0);
>> + printk(KERN_INFO "digital");
>> break;
>> }
>> + break;
>> }
>>
> Those tuner callback initializations are board-specific. So, it is better to test
> for your board model, if you need something different than what's currently done.
>
>
This tuner reset works with my stick, but I think that can test with
other tm6000 based sticks and if it not works then I can say this as a
board-specific.
>> +
>> return (rc);
>> }
>>
>> @@ -290,7 +332,7 @@ static void tm6000_config_tuner (struct tm6000_core
>> *dev)
>> memset(&tun_setup, 0, sizeof(tun_setup));
>> tun_setup.type = dev->tuner_type;
>> tun_setup.addr = dev->tuner_addr;
>> - tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
>> + tun_setup.mode_mask = T_ANALOG_TV | T_RADIO | T_DIGITAL_TV;
>> tun_setup.tuner_callback = tm6000_tuner_callback;
>>
>> v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr,
>> &tun_setup);
>> @@ -302,15 +344,19 @@ static void tm6000_config_tuner (struct
>> tm6000_core *dev)
>> memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
>> memset (&ctl,0,sizeof(ctl));
>>
>> - ctl.mts = 1;
>> - ctl.read_not_reliable = 1;
>> + ctl.input1 = 1;
>> + ctl.read_not_reliable = 0;
>> ctl.msleep = 10;
>> -
>> + ctl.demod = XC3028_FE_ZARLINK456;
>> + ctl.vhfbw7 = 1;
>> + ctl.uhfbw8 = 1;
>> + ctl.switch_mode = 1;
>> xc2028_cfg.tuner = TUNER_XC2028;
>> xc2028_cfg.priv = &ctl;
>>
>> switch(dev->model) {
>> case TM6010_BOARD_HAUPPAUGE_900H:
>> + case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
>> ctl.fname = "xc3028L-v36.fw";
>> break;
>> default:
>>
>
>> @@ -402,6 +448,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
>> }
>> #endif
>> }
>> + return 0;
>>
>> err2:
>> v4l2_device_unregister(&dev->v4l2_dev);
>>
> This hunk also looks a bug fix. If so, please submit as a separate patch.
>
>
o. k.
>> @@ -459,13 +506,13 @@ static int tm6000_usb_probe(struct usb_interface
>> *interface,
>> /* Check to see next free device and mark as used */
>> nr=find_first_zero_bit(&tm6000_devused,TM6000_MAXBOARDS);
>> if (nr >= TM6000_MAXBOARDS) {
>> - printk ("tm6000: Supports only %i em28xx
>> boards.\n",TM6000_MAXBOARDS);
>> + printk ("tm6000: Supports only %i tm60xx
>> boards.\n",TM6000_MAXBOARDS);
>> usb_put_dev(usbdev);
>> return -ENOMEM;
>> }
>>
> Also a typo bug fix. I don't really mind if you fold this with another patch,
> but the better would be to have a separate patch for it.
>
>
o.k.
>>
>> /* Create and initialize dev struct */
>> - dev = kzalloc(sizeof(*dev), GFP_KERNEL);
>> + dev = kzalloc(sizeof(*(dev)), GFP_KERNEL);
>>
> The extra parenthesis is uneeded here.
>
>
o.k. I switch it to older once.
>> if (dev == NULL) {
>> printk ("tm6000" ": out of memory!\n");
>> usb_put_dev(usbdev);
>> diff --git a/drivers/staging/tm6000/tm6000-core.c
>> b/drivers/staging/tm6000/tm6000-core.c
>> index d41af1d..33bbbd3 100644
>> --- a/drivers/staging/tm6000/tm6000-core.c
>> +++ b/drivers/staging/tm6000/tm6000-core.c
>> @@ -219,33 +219,53 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
>>
>> int tm6000_init_digital_mode (struct tm6000_core *dev)
>> {
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
>> -
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
>> - tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
>> - msleep(50);
>> -
>> - tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
>> - msleep(50);
>> - tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
>> - msleep(50);
>> - tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
>> - msleep(100);
>> -
>> + if (dev->dev_type == TM6010) {
>> + int val;
>> + u8 buf[2];
>> +
>> + /* digital init */
>> + val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, 0);
>> + val &= ~0x60;
>> + tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, val);
>> + val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, 0);
>> + val |= 0x40;
>> + tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, val);
>> + tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xfe, 0x28);
>> + tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe2, 0xfc);
>> + tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe6, 0xff);
>> + tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xf1, 0xfe);
>> + tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
>> + printk (KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
>> +
>> +
>> + } else {
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
>> +
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
>> + tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
>> + msleep(50);
>> +
>> + tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
>> + msleep(50);
>> + tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
>> + msleep(50);
>> + tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
>> + msleep(100);
>> + }
>> return 0;
>> }
>>
>> @@ -394,7 +414,15 @@ struct reg_init tm6010_init_tab[] = {
>> { REQ_07_SET_GET_AVREG, 0x3f, 0x00 },
>>
>> { REQ_05_SET_GET_USBREG, 0x18, 0x00 },
>> -
>> +
>> + /* additional from Terratec Cinergy Hybrid XE */
>> + { REQ_07_SET_GET_AVREG, 0xdc, 0xaa },
>> + { REQ_07_SET_GET_AVREG, 0xdd, 0x30 },
>> + { REQ_07_SET_GET_AVREG, 0xde, 0x20 },
>> + { REQ_07_SET_GET_AVREG, 0xdf, 0xd0 },
>> + { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 },
>> + { REQ_07_SET_GET_AVREG, 0xd8, 0x2f },
>> +
>> /* set remote wakeup key:any key wakeup */
>> { REQ_07_SET_GET_AVREG, 0xe5, 0xfe },
>> { REQ_07_SET_GET_AVREG, 0xda, 0xff },
>> @@ -404,6 +432,7 @@ int tm6000_init (struct tm6000_core *dev)
>> {
>> int board, rc=0, i, size;
>> struct reg_init *tab;
>> + u8 buf[40];
>>
> Why "40" ? Please avoid using magic numbers here, especially if you're
> not checking at the logic if you're writing outside the buffer.
>
>
It important for tm6010 init sequence to enable the demodulator, because
the demodulator haven't found after init tuner.
>> if (dev->dev_type == TM6010) {
>> tab = tm6010_init_tab;
>> @@ -424,61 +453,129 @@ int tm6000_init (struct tm6000_core *dev)
>> }
>> }
>>
>> - msleep(5); /* Just to be conservative */
>> -
>> - /* Check board version - maybe 10Moons specific */
>> - board=tm6000_get_reg16 (dev, 0x40, 0, 0);
>> - if (board >=0) {
>> - printk (KERN_INFO "Board version = 0x%04x\n",board);
>> - } else {
>> - printk (KERN_ERR "Error %i while retrieving board
>> version\n",board);
>> - }
>> -
>> + /* hack */
>> if (dev->dev_type == TM6010) {
>> - /* Turn xceive 3028 on */
>> - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6010_GPIO_3, 0x01);
>> - msleep(11);
>> - }
>> -
>> - /* Reset GPIO1 and GPIO4. */
>> - for (i=0; i< 2; i++) {
>> - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> - dev->tuner_reset_gpio, 0x00);
>> - if (rc<0) {
>> - printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
>> - return rc;
>> - }
>> -
>> - msleep(10); /* Just to be conservative */
>> - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> - dev->tuner_reset_gpio, 0x01);
>> - if (rc<0) {
>> - printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
>> - return rc;
>> - }
>> -
>> - msleep(10);
>> - rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 0);
>> - if (rc<0) {
>> - printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
>> - return rc;
>> - }
>> -
>> - msleep(10);
>> - rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 1);
>> - if (rc<0) {
>> - printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
>> - return rc;
>> - }
>> -
>> - if (!i) {
>> - rc=tm6000_get_reg16(dev, 0x40,0,0);
>> - if (rc>=0) {
>> - printk ("board=%d\n", rc);
>> +
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_4, 0);
>> + msleep(15);
>> +
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_1, 0);
>> +
>> + msleep(50);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_1, 1);
>> +
>> + msleep(15);
>>
>
> The reset code are device dependent. Please don't remove the previous code, or you'll
> break the init for the other devices. Instead, add a switch above, checking for your
> specific model. The better is to have all those device-specific initializations inside
> tm6000-cards. Please take a look on how this is solved on em28xx driver.
>
>
GPIO 1 is the demodulator reset and gpio 4 is lo when tm6010 initialize.
>> + tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x0010, 0x4400, buf, 2);
>> +
>> + msleep(15);
>> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
>> +
>> + msleep(15);
>> + buf[0] = 0x12;
>> + buf[1] = 0x34;
>> + tm6000_read_write_usb (dev, 0x40, 0x10, 0xf432, 0x0000, buf, 2);
>> +
>> + msleep(15);
>> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
>> +
>> + msleep(15);
>> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0x0032, 0x0000, buf, 2);
>> +
>> + msleep(15);
>> + buf[0] = 0x00;
>> + buf[1] = 0x01;
>> + tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
>> +
>> + msleep(15);
>> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0x00c0, 0x0000, buf, 39);
>> +
>> + msleep(15);
>> + buf[0] = 0x00;
>> + buf[1] = 0x00;
>> + tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
>> +
>> + msleep(15);
>> + tm6000_read_write_usb (dev, 0xc0, 0x10, 0x7f1f, 0x0000, buf, 2);
>> +// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf [1]);
>> + msleep(15);
>>
>
> Insead, use tm6000_get_reg() or tm6000_set_reg(). Passing the USB direction as
> 0x40/0xc0 is very ugly, and makes the code harder to understand.
>
>
I cannot use it, because it is a i2c transfer! The reading or writing
data is in buf. (reading can it)
> Also,
> req=0x0e corresponds to REQ_14_SET_GET_I2C_WR2_RDN
> req=0x10 corresponds to REQ_16_SET_GET_I2C_WR1_RDN
>
> So, the above code is just reading/writing some data via I2C. It should be replaced
> by some changes at the corresponding i2c driver for the devices that the above
> code is controlling.
>
> As a temporary hack, you might do some initialization by calling i2c_master_send/
> i2c_master_recv. For example, em28xx driver has this hack:
>
> /* FIXME: Should be replaced by a proper mt9m001 driver */
> static int em28xx_initialize_mt9m001(struct em28xx *dev)
> {
> int i;
> unsigned char regs[][3] = {
> { 0x0d, 0x00, 0x01, },
> { 0x0d, 0x00, 0x00, },
> { 0x04, 0x05, 0x00, }, /* hres = 1280 */
> { 0x03, 0x04, 0x00, }, /* vres = 1024 */
> { 0x20, 0x11, 0x00, },
> { 0x06, 0x00, 0x10, },
> { 0x2b, 0x00, 0x24, },
> { 0x2e, 0x00, 0x24, },
> { 0x35, 0x00, 0x24, },
> { 0x2d, 0x00, 0x20, },
> { 0x2c, 0x00, 0x20, },
> { 0x09, 0x0a, 0xd4, },
> { 0x35, 0x00, 0x57, },
> };
>
> for (i = 0; i < ARRAY_SIZE(regs); i++)
> i2c_master_send(&dev->i2c_client, ®s[i][0], 3);
>
> return 0;
> }
>
>
>
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_4, 1);
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_0, 1);
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_7, 0);
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_5, 1);
>> +
>> + msleep(15);
>>
> Also, this is device-specific.
>
after tm6000 initialize gpio 4 go to high (GPIO 4 is lo if it
initialze). I think when it device-specific is then for all tm6010!!
GPIO 0 and 7 ?? GPIO 5 a/d switch (from tuner to demodulator or adc).
>
>> +
>> + for (i=0; i< size; i++) {
>> + rc= tm6000_set_reg (dev, tab[i].req, tab[i].reg, tab[i].val);
>> + if (rc<0) {
>> + printk (KERN_ERR "Error %i while setting req %d, "
>> + "reg %d to value %d\n", rc,
>> + tab[i].req,tab[i].reg, tab[i].val);
>> + return rc;
>> }
>> }
>> +
>> + msleep(15);
>>
>
>
>> +
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_4, 0);
>> + msleep(15);
>> +
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_1, 0);
>> +
>> + msleep(50);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_1, 1);
>> +
>> + msleep(15);
>> + tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
>> +// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_2, 1);
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_2, 0);
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_2, 1);
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_2, 1);
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_2, 0);
>> + msleep(15);
>> + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
>> + TM6010_GPIO_2, 1);
>> + msleep(15);
>> }
>> + /* hack end */
>>
> Idem. All GPIO's are device-specific.
>
>
GPIO 2 is tuner reset and can remove, I think.
>> +
>> + msleep(5); /* Just to be conservative */
>>
>> + /* Check board version - maybe 10Moons specific */
>> + if (dev->dev_type == TM5600) {
>> + board=tm6000_get_reg16 (dev, 0x40, 0, 0);
>> + if (board >=0) {
>> + printk (KERN_INFO "Board version = 0x%04x\n",board);
>> + } else {
>> + printk (KERN_ERR "Error %i while retrieving board
>> version\n",board);
>> + }
>> + }
>> +
>> msleep(50);
>>
>> return 0;
>> diff --git a/drivers/staging/tm6000/tm6000-dvb.c
>> b/drivers/staging/tm6000/tm6000-dvb.c
>> index e900d6d..31458d3 100644
>> --- a/drivers/staging/tm6000/tm6000-dvb.c
>> +++ b/drivers/staging/tm6000/tm6000-dvb.c
>> @@ -17,7 +17,9 @@
>> Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>> */
>>
>> +#include <linux/kernel.h>
>> #include <linux/usb.h>
>> +#include <compat.h>
>>
>> #include "tm6000.h"
>> #include "tm6000-regs.h"
>> @@ -30,17 +32,61 @@
>>
>> #include "tuner-xc2028.h"
>>
>> +static void inline print_err_status (struct tm6000_core *dev,
>> + int packet, int status)
>> +{
>> + char *errmsg = "Unknown";
>> +
>> + switch(status) {
>> + case -ENOENT:
>> + errmsg = "unlinked synchronuously";
>> + break;
>> + case -ECONNRESET:
>> + errmsg = "unlinked asynchronuously";
>> + break;
>> + case -ENOSR:
>> + errmsg = "Buffer error (overrun)";
>> + break;
>> + case -EPIPE:
>> + errmsg = "Stalled (device not responding)";
>> + break;
>> + case -EOVERFLOW:
>> + errmsg = "Babble (bad cable?)";
>> + break;
>> + case -EPROTO:
>> + errmsg = "Bit-stuff error (bad cable?)";
>> + break;
>> + case -EILSEQ:
>> + errmsg = "CRC/Timeout (could be anything)";
>> + break;
>> + case -ETIME:
>> + errmsg = "Device does not respond";
>> + break;
>> + }
>> + if (packet<0) {
>> + dprintk(dev, 1, "URB status %d [%s].\n",
>> + status, errmsg);
>> + } else {
>> + dprintk(dev, 1, "URB packet %d, status %d [%s].\n",
>> + packet, status, errmsg);
>> + }
>> +}
>> +
>> +
>> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
>> +static void tm6000_urb_received(struct urb *urb, struct pt_regs *ptregs)
>> +#else
>> static void tm6000_urb_received(struct urb *urb)
>> +#endif
>> {
>> int ret;
>> struct tm6000_core* dev = urb->context;
>>
>> - if(urb->status != 0){
>> - printk(KERN_ERR "tm6000: status != 0\n");
>> + if(urb->status != 0) {
>> + print_err_status (dev,0,urb->status);
>> }
>> else if(urb->actual_length>0){
>> - dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
>> - urb->actual_length);
>> + dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
>> urb->actual_length);
>> }
>>
>> if(dev->dvb->streams > 0) {
>> @@ -56,49 +102,37 @@ static void tm6000_urb_received(struct urb *urb)
>> int tm6000_start_stream(struct tm6000_core *dev)
>> {
>> int ret;
>> - unsigned int pipe, maxPaketSize;
>> + unsigned int pipe, size;
>> struct tm6000_dvb *dvb = dev->dvb;
>>
>> printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
>>
>> tm6000_init_digital_mode(dev);
>>
>> -/*
>> - ret = tm6000_set_led_status(tm6000_dev, 0x1);
>> - if(ret < 0) {
>> - return -1;
>> - }
>> -*/
>> -
>> dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
>> if(dvb->bulk_urb == NULL) {
>> printk(KERN_ERR "tm6000: couldn't allocate urb\n");
>> return -ENOMEM;
>> }
>>
>> - maxPaketSize = dev->bulk_in->desc.wMaxPacketSize;
>> + pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
>> + & USB_ENDPOINT_NUMBER_MASK);
>> +
>> + size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
>> + size = size * 15; // 512 x 8 or 12 or 15
>>
>> - dvb->bulk_urb->transfer_buffer = kzalloc(maxPaketSize, GFP_KERNEL);
>> + dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
>> if(dvb->bulk_urb->transfer_buffer == NULL) {
>> usb_free_urb(dvb->bulk_urb);
>> printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
>> return -ENOMEM;
>> }
>> -
>> - pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
>> - & USB_ENDPOINT_NUMBER_MASK);
>> -
>> +
>> usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
>> dvb->bulk_urb->transfer_buffer,
>> - maxPaketSize,
>> + size,
>> tm6000_urb_received, dev);
>>
>> - ret = usb_set_interface(dev->udev, 0, 1);
>> - if(ret < 0) {
>> - printk(KERN_ERR "tm6000: error %i in %s during set
>> interface\n", ret, __FUNCTION__);
>> - return ret;
>> - }
>> -
>> ret = usb_clear_halt(dev->udev, pipe);
>> if(ret < 0) {
>> printk(KERN_ERR "tm6000: error %i in %s during pipe
>> reset\n",ret,__FUNCTION__);
>> @@ -107,15 +141,14 @@ int tm6000_start_stream(struct tm6000_core *dev)
>> else {
>> printk(KERN_ERR "tm6000: pipe resetted\n");
>> }
>> -
>> -// mutex_lock(&tm6000_driver.open_close_mutex);
>> +
>> +// mutex_lock(&tm6000_driver.open_close_mutex);
>> ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
>>
>> -
>> -// mutex_unlock(&tm6000_driver.open_close_mutex);
>> +// mutex_unlock(&tm6000_driver.open_close_mutex);
>> if (ret) {
>> printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",ret);
>> -
>> +
>> kfree(dvb->bulk_urb->transfer_buffer);
>> usb_free_urb(dvb->bulk_urb);
>> return ret;
>> @@ -126,18 +159,12 @@ int tm6000_start_stream(struct tm6000_core *dev)
>>
>> void tm6000_stop_stream(struct tm6000_core *dev)
>> {
>> - int ret;
>> struct tm6000_dvb *dvb = dev->dvb;
>>
>> -// tm6000_set_led_status(tm6000_dev, 0x0);
>> -
>> - ret = usb_set_interface(dev->udev, 0, 0);
>> - if(ret < 0) {
>> - printk(KERN_ERR "tm6000: error %i in %s during set
>> interface\n",ret,__FUNCTION__);
>> - }
>> -
>> if(dvb->bulk_urb) {
>> + printk (KERN_INFO "urb killing\n");
>> usb_kill_urb(dvb->bulk_urb);
>> + printk (KERN_INFO "urb buffer free\n");
>> kfree(dvb->bulk_urb->transfer_buffer);
>> usb_free_urb(dvb->bulk_urb);
>> dvb->bulk_urb = NULL;
>> @@ -154,7 +181,7 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
>> mutex_lock(&dvb->mutex);
>> if(dvb->streams == 0) {
>> dvb->streams = 1;
>> -// mutex_init(&tm6000_dev->streaming_mutex);
>> +// mutex_init(&tm6000_dev->streming_mutex);
>> tm6000_start_stream(dev);
>> }
>> else {
>> @@ -173,14 +200,17 @@ int tm6000_stop_feed(struct dvb_demux_feed *feed) {
>> printk(KERN_INFO "tm6000: got stop feed request %s\n",__FUNCTION__);
>>
>> mutex_lock(&dvb->mutex);
>> - --dvb->streams;
>>
>> - if(0 == dvb->streams) {
>> + printk (KERN_INFO "stream %#x\n", dvb->streams);
>> + --(dvb->streams);
>> + if(dvb->streams == 0) {
>> + printk (KERN_INFO "stop stream\n");
>> tm6000_stop_stream(dev);
>> -// mutex_destroy(&tm6000_dev->streaming_mutex);
>> +// mutex_destroy(&tm6000_dev->streaming_mutex);
>> }
>> +
>> mutex_unlock(&dvb->mutex);
>> -// mutex_destroy(&tm6000_dev->streaming_mutex);
>> +// mutex_destroy(&tm6000_dev->streaming_mutex);
>>
>> return 0;
>> }
>> @@ -191,13 +221,16 @@ int tm6000_dvb_attach_frontend(struct tm6000_core
>> *dev)
>>
>> if(dev->caps.has_zl10353) {
>> struct zl10353_config config =
>> - {.demod_address = dev->demod_addr >> 1,
>> + {.demod_address = dev->demod_addr,
>> .no_tuner = 1,
>> -// .input_frequency = 0x19e9,
>> -// .r56_agc_targets = 0x1c,
>> + .parallel_ts = 1,
>> + .if2 = 45700,
>> + .disable_i2c_gate_ctrl = 1,
>> + .tm6000 = 1,
>> };
>>
>> dvb->frontend = pseudo_zl10353_attach(dev, &config,
>> +// dvb->frontend = dvb_attach (zl10353_attach, &config,
>>
> Don't use C99 comments. Always comment with /* */
>
>
all comments except frontend attach is don't from me, but I can convert it.
>
>> &dev->i2c_adap);
>> }
>> else {
>> @@ -235,7 +268,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
>> .i2c_adap = &dev->i2c_adap,
>> .i2c_addr = dev->tuner_addr,
>> };
>> -
>> +
>> + dvb->frontend->callback = tm6000_tuner_callback;
>> ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
>> if (ret < 0) {
>> printk(KERN_ERR
>> @@ -258,8 +292,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
>> dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
>> | DMX_MEMORY_BASED_FILTERING;
>> dvb->demux.priv = dev;
>> - dvb->demux.filternum = 256;
>> - dvb->demux.feednum = 256;
>> + dvb->demux.filternum = 5; //256;
>> + dvb->demux.feednum = 5; //256;
>>
> Don't use C99 comments. Always comment with /* */
>
>
all comments except frontend attach is don't from me, but I can convert it.
>> dvb->demux.start_feed = tm6000_start_feed;
>> dvb->demux.stop_feed = tm6000_stop_feed;
>> dvb->demux.write_to_decoder = NULL;
>> @@ -307,7 +341,7 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
>> usb_free_urb(bulk_urb);
>> }
>>
>> -// mutex_lock(&tm6000_driver.open_close_mutex);
>> +// mutex_lock(&tm6000_driver.open_close_mutex);
>> if(dvb->frontend) {
>> dvb_frontend_detach(dvb->frontend);
>> dvb_unregister_frontend(dvb->frontend);
>> @@ -317,6 +351,6 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
>> dvb_dmx_release(&dvb->demux);
>> dvb_unregister_adapter(&dvb->adapter);
>> mutex_destroy(&dvb->mutex);
>> -// mutex_unlock(&tm6000_driver.open_close_mutex);
>> +// mutex_unlock(&tm6000_driver.open_close_mutex);
>>
>> }
>>
> Please send a separate patch for the dvb fixes.
>
>
o.k.
>> diff --git a/drivers/staging/tm6000/tm6000-i2c.c
>> b/drivers/staging/tm6000/tm6000-i2c.c
>> index 4da10f5..3e43ad7 100644
>> --- a/drivers/staging/tm6000/tm6000-i2c.c
>> +++ b/drivers/staging/tm6000/tm6000-i2c.c
>> @@ -86,6 +86,11 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
>> msgs[i].len == 1 ? 0 : msgs[i].buf[1],
>> msgs[i + 1].buf, msgs[i + 1].len);
>> i++;
>> +
>> + if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
>> + tm6000_set_reg(dev, 0x32, 0,0);
>> + tm6000_set_reg(dev, 0x33, 0,0);
>> + }
>> if (i2c_debug >= 2)
>> for (byte = 0; byte < msgs[i].len; byte++)
>> printk(" %02x", msgs[i].buf[byte]);
>> @@ -99,6 +104,12 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
>> REQ_16_SET_GET_I2C_WR1_RDN,
>> addr | msgs[i].buf[0] << 8, 0,
>> msgs[i].buf + 1, msgs[i].len - 1);
>> +
>> +
>> + if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
>> + tm6000_set_reg(dev, 0x32, 0,0);
>> + tm6000_set_reg(dev, 0x33, 0,0);
>> + }
>> }
>>
> Please send a separate patch for the i2c fixes.
>
> On both logic, don't check for 0xc2, but for the i2c address of the tuner. I
> have here one device with a tm6000. After having this patch applied,
> I'll test with it, and see if setting those two register values to 0 also fixes
> for tm6000.
>
>
o.k.
can I use for the tuner address "dev->tuner_addr"? So it cannot use 0xc2.
>> if (i2c_debug >= 2)
>> printk("\n");
>> @@ -198,7 +209,7 @@ static struct i2c_algorithm tm6000_algo = {
>>
>> static struct i2c_adapter tm6000_adap_template = {
>> .owner = THIS_MODULE,
>> - .class = I2C_CLASS_TV_ANALOG,
>> + .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
>> .name = "tm6000",
>> .id = I2C_HW_B_TM6000,
>> .algo = &tm6000_algo,
>> diff --git a/drivers/staging/tm6000/tm6000.h
>> b/drivers/staging/tm6000/tm6000.h
>> index 877cbf6..e403ca0 100644
>> --- a/drivers/staging/tm6000/tm6000.h
>> +++ b/drivers/staging/tm6000/tm6000.h
>> @@ -23,12 +23,15 @@
>> // Use the tm6000-hack, instead of the proper initialization code
>> //#define HACK 1
>>
>> +#include "compat.h"
>> #include <linux/videodev2.h>
>> #include <media/v4l2-common.h>
>> #include <media/videobuf-vmalloc.h>
>> #include "tm6000-usb-isoc.h"
>> #include <linux/i2c.h>
>> +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
>> #include <linux/mutex.h>
>> +#endif
>> #include <media/v4l2-device.h>
>>
>>
>> @@ -78,6 +81,10 @@ struct tm6000_dmaqueue {
>> /* thread for generating video stream*/
>> struct task_struct *kthread;
>> wait_queue_head_t wq;
>> +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
>> + struct semaphore *notify;
>> + int rmmod:1;
>> +#endif
>>
> You may just drop the code for kernels < 2.6 (on a separate patch). The current
> backport starts with 2.6.16.
>
>
What you mean. Should I send a patch?
>> /* Counters to control fps rate */
>> int frame;
>> int ini_jiffies;
>> @@ -90,12 +97,14 @@ enum tm6000_core_state {
>> DEV_MISCONFIGURED = 0x04,
>> };
>>
>> +#if 1
>> /* io methods */
>> enum tm6000_io_method {
>> IO_NONE,
>> IO_READ,
>> IO_MMAP,
>> };
>> +#endif
>>
>> enum tm6000_mode {
>> TM6000_MODE_UNKNOWN=0,
>> @@ -202,6 +211,9 @@ struct tm6000_fh {
>> V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
>> V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM
>>
>> +/* In tm6000-cards.c */
>> +
>> +int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
>> /* In tm6000-core.c */
>>
>> int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
>> @@ -209,7 +221,6 @@ int tm6000_read_write_usb (struct tm6000_core *dev,
>> u8 reqtype, u8 req,
>> int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
>> int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
>> int tm6000_init (struct tm6000_core *dev);
>> -int tm6000_init_after_firmware (struct tm6000_core *dev);
>>
>> int tm6000_init_analog_mode (struct tm6000_core *dev);
>> int tm6000_init_digital_mode (struct tm6000_core *dev);
>> @@ -231,7 +242,12 @@ int tm6000_set_standard (struct tm6000_core *dev,
>> v4l2_std_id *norm);
>> int tm6000_i2c_register(struct tm6000_core *dev);
>> int tm6000_i2c_unregister(struct tm6000_core *dev);
>>
>> +#if 1
>> /* In tm6000-queue.c */
>> +#if 0
>> +int tm6000_init_isoc(struct tm6000_core *dev, int max_packets);
>> +void tm6000_uninit_isoc(struct tm6000_core *dev);
>> +#endif
>>
>> int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
>>
>> @@ -276,3 +292,4 @@ extern int tm6000_debug;
>> __FUNCTION__ , ##arg); } while (0)
>>
>>
>> +#endif
>>
>>
>
>
Can you tell me how I generate a patch set (detailed once).
Cheers
Stefan Ringel
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-02 16:44 ` Mauro Carvalho Chehab
@ 2010-02-02 17:38 ` Stefan Ringel
2010-02-02 20:05 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-02 17:38 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: Devin Heitmueller, linux-media
Am 02.02.2010 17:44, schrieb Mauro Carvalho Chehab:
> Stefan Ringel wrote:
>
>
>>> So, it will basically preserve bits 8,7,6,4 and 1 of register 8,
>>> and will clear bit 4 (EM_GPIO_4 is 1 << 4 - e. g. bit 4).
>>> After that, it will sleep for 10 miliseconds, and will then do a
>>> reset on bit 3 of Register 4 (writing 0, then 1 to the bit).
>>>
>>>
>> reset example :
>>
>> static struct tm6010_seq terratec[] = {
>> {TM6010_GPIO_2, 1, 60}, /* GPIO 2 going to high */
>> {TM6010_GPIO_2, 0, 75}, /* GPIO 2 going to lo */
>> {TM6010_GPIO_2, 1, 60}, /* GPIO 2 going to high */
>> { -1 , -1, -1},
>> }
>>
>> Is that correct?
>>
> Yes. In the case of tm6010, it has separate registers for each GPIO, so, you
> don't need a bitmask.
>
>
>>> the hack.c needs to be validated against the zl10353, in order to identify
>>> what are the exact needs for tm6000. Some devices require serial mode, while
>>> others require parallel mode.
>>>
>>> I bet that playing with zl10353_config, we'll find the proper init values
>>> required by tm6000.
>>>
>>>
>>>
>> I have separately write in the hack.c the value from terratec hybrid
>> stick. The older value I haven't clean.
>>
> Ok, but maybe you missed my point: at the long term, we should get rid of hack.c, and
> be sure that all needed initializations are done by zl10353 driver or by tm6010-dvb.
>
I think I all are done by zl10353 driver.
I thinbk all config param is usefull and ".tm6000" for tm6000 specific
once. For what is ".parallel_ts" ?
int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
if(dev->caps.has_zl10353) {
struct zl10353_config config =
{.demod_address = dev->demod_addr,
.no_tuner = 1,
.parallel_ts = 1,
.if2 = 45700,
.disable_i2c_gate_ctrl = 1,
.tm6000 = 1,
};
dvb->frontend = pseudo_zl10353_attach(dev, &config,
// dvb->frontend = dvb_attach (zl10353_attach, &config,
&dev->i2c_adap);
}
else {
printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
return -1;
}
return (!dvb->frontend) ? -1 : 0;
}
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-02 17:24 ` Stefan Ringel
@ 2010-02-02 20:03 ` Mauro Carvalho Chehab
2010-02-02 20:19 ` Stefan Ringel
2010-02-02 20:42 ` Stefan Ringel
0 siblings, 2 replies; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-02 20:03 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
Stefan Ringel wrote:
> Am 01.02.2010 23:52, schrieb Mauro Carvalho Chehab:
>> This struct is meant to pass static parameters to the driver. the analog/digital
>> mode is dynamic, so, this is not the right place for doing it.
>>
>>
> Can you tell me how that work? Where would call it? Switch it after read
> demodulator status or before? This switch switches the tuner output to
> the demodulator or adc input and if it read status before it switch
> thoughts the apps "no digital found".
Basically, this is done by check_firmware. It is called by
xc2028_set_analog_freq()
or
xc2028_set_params()
So, when the frontend (digital) or the tuner (analog) is called to set an analog frequency
or to set DVB parameters.
All that it is needed for this to work is that both analog and DVB part should call
xc2028_attach() with the proper parameters.
For the analog side, you need a code like that (modified from em28xx-cards.c):
if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
tun_setup.type = TUNER_XC2028;
tun_setup.addr = dev->tuner_addr;
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
}
With this code, tuner-core set_type() will register the analog side of the driver.
For the digital part, you need to call xc2028_attach() manually (from em28xx-dvb):
fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg);
When the driver wants to switch to an specific mode, all it needs is to set an analog or
digital frequency. The frontend or tuner driver will do the rest.
>>> @@ -45,6 +45,8 @@ struct zl10353_config
>>> /* clock control registers (0x51-0x54) */
>>> u8 clock_ctl_1; /* default: 0x46 */
>>> u8 pll_0; /* default: 0x15 */
>>> +
>>> + int tm6000:1;
>>>
>> This doesn't make sense. The zl10353 doesn't need to know if the device is
>> a tm6000 or not. If the tm6000 driver needs something special, then we need
>> to discover what he is doing and name the zl10353 feature accordingly.
>>
>>
>>
> that is for todo in next week, when I switch from hack.c to zl10353
> kernel module, but it can remove if it don't use.
OK.
>>> + tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0b1f,0,data,2);
>>> + printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
>>> + msleep(40);
>>>
>> The same comment here: maybe the above code only applies to tm6010.
>>
>>
> It little different to the other hack code. The lastest lines are
> reading demod status.
If you're reading the demod status, the proper way is to call the corresponding
code at the tm6000-dvb part and use the standard i2c way of doing it.
The demod status depends on what demod you have, so the code there should be
board dependent. While currently only one demod is supported, there are devices
like Nova-S USB that have different demods (the Nova-S is DVB-S).
>>> --- a/drivers/staging/tm6000/tm6000-cards.c
>>> +++ b/drivers/staging/tm6000/tm6000-cards.c
>>> @@ -32,7 +32,7 @@
>>> #include "tm6000.h"
>>> #include "tm6000-regs.h"
>>> #include "tuner-xc2028.h"
>>> -#include "tuner-xc5000.h"
>>> +#include "xc5000.h"
>>>
>> Please send this hunk on a separate patch. Since it fixes compilation, I'll
>> need to apply it before the Kconfig changes, when tm6000 upstream.
>>
>>
> o.k. but I cannot know how. I have no idea with diff or something.
The better way is to clone a tree and write your patches there, committing every
patch.
If you want to break an already existing diff into small diffs, you may copy it
by hand and remove the uneeded hunks.
For example, if you just save this into a file:
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -32,7 +32,7 @@
#include "tm6000.h"
#include "tm6000-regs.h"
#include "tuner-xc2028.h"
-#include "tuner-xc5000.h"
+#include "xc5000.h"
#define TM6000_BOARD_UNKNOWN 0
#define TM5600_BOARD_GENERIC 1
and apply to your new tree, you'll have just one change there.
A hunk starts with @@. the numbers after "-" are the line number and the number of lines
of the original code. The numbers after "+" are the line number/line count after the patch.
For example, on this hunk:
@@ -402,6 +448,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
}
#endif
}
+ return 0;
err2:
v4l2_device_unregister(&dev->v4l2_dev);
It is changing the content of line number 402 of the source code. The original code has 6 lines
(the 3 lines before and the 3 lines after the insertion). It is adding one line (the line with "+").
The resulting code will be at line #448 and will have 7 lines.
If you copy the above, plus the name of the file to patch (the lines with --- and +++):
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -402,6 +448,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
}
#endif
}
+ return 0;
err2:
v4l2_device_unregister(&dev->v4l2_dev);
You'll have a patch that just adds return 0.
On some cases like the above, it is just easier to edit the line and let the
mercurial to generate the diff for you.
>> Those tuner callback initializations are board-specific. So, it is better to test
>> for your board model, if you need something different than what's currently done.
>>
>>
> This tuner reset works with my stick, but I think that can test with
> other tm6000 based sticks and if it not works then I can say this as a
> board-specific.
It won't work on my boards. The GPIO pin used by each board is different.
>>> @@ -404,6 +432,7 @@ int tm6000_init (struct tm6000_core *dev)
>>> {
>>> int board, rc=0, i, size;
>>> struct reg_init *tab;
>>> + u8 buf[40];
>>>
>> Why "40" ? Please avoid using magic numbers here, especially if you're
>> not checking at the logic if you're writing outside the buffer.
>>
>>
> It important for tm6010 init sequence to enable the demodulator, because
> the demodulator haven't found after init tuner.
Probably, there is some i2c gate to enable/disable the i2c access to the
demodulator. The better way is to add a call to the tm6000-dvb and let it
init the demodulator.
Also, since there's a gate for the demodulator, the proper way is to add
a callback to control it. Please take a look at saa7134 and seek for i2c_gate_ctrl
to see how such logic works.
>> The reset code are device dependent. Please don't remove the previous code, or you'll
>> break the init for the other devices. Instead, add a switch above, checking for your
>> specific model. The better is to have all those device-specific initializations inside
>> tm6000-cards. Please take a look on how this is solved on em28xx driver.
>>
>>
> GPIO 1 is the demodulator reset and gpio 4 is lo when tm6010 initialize.
This depends on the device. The GPIO are just a few pins that the board designer may do
whatever they want to control other devices. So, it is up to each vendor do decide to use
GPIO 1 or GPIO 7 or GPIO 5, or... for xc3028 reset. They decide it in order to simplify
the design of the wire tracks at the board layout. So, this changes from project to project.
>>>
>> Insead, use tm6000_get_reg() or tm6000_set_reg(). Passing the USB direction as
>> 0x40/0xc0 is very ugly, and makes the code harder to understand.
>>
>>
> I cannot use it, because it is a i2c transfer! The reading or writing
> data is in buf. (reading can it)
So, you should use i2c_master_recv/i2c_master_send. Or even better, this code should be
on an specific i2c driver for the component that it is being controlled.
>>>
>> Also, this is device-specific.
>>
> after tm6000 initialize gpio 4 go to high (GPIO 4 is lo if it
> initialze). I think when it device-specific is then for all tm6010!!
> GPIO 0 and 7 ?? GPIO 5 a/d switch (from tuner to demodulator or adc).
GPIO 4 is device specific. In a matter of fact, you'll likely find several
designs that will use the same GPIO's found at their reference design (simply
because there are several boards that use exactly the same layout). But this
shouldn't be a rule.
>>>
>> Idem. All GPIO's are device-specific.
>>
>>
> GPIO 2 is tuner reset and can remove, I think.
Let the tuner-xc3028 driver control the tuner reset. It will call it at the
right time.
>>>
>>> dvb->frontend = pseudo_zl10353_attach(dev, &config,
>>> +// dvb->frontend = dvb_attach (zl10353_attach, &config,
>>>
>> Don't use C99 comments. Always comment with /* */
>>
>>
>
> all comments except frontend attach is don't from me, but I can convert it.
Yeah, this driver has still lots of coding style problems. You may do a latter
patch just fixing coding style. Yet, when you're adding new lines of code, the
better is to avoid increading the mess.
make checkpatch is your friend: it runs a script that checks if the current changes
aren't violating coding style.
Yet, don't bother so much with this right now. The code is already messed. At the end,
we can do a big cleanup patch.
> Can you tell me how I generate a patch set (detailed once).
README.patches contains some good explanations. I submitted yesterday an update to the
mailing list.
Basically, the better is to use git or mercurial (hg) for doing your development.
Git is a some years-light ahead Mercurial in terms of functionality, so I recommend you
to use it. Git were made by Linus Torvalds to be used on kernel development, so, it has all
kind of fancy features that every Kernel developer needs, and it is very fast. The downside
is that our -git tree has about 300GB (as it contains the entire kernel since version 2.6.12),
while the -hg has 48MB. So, the download time for -git is higher. However, after downloading, it
is faster than mercurial.
At the new README.patches, I've added a few examples on how to generate patches and to generate
emails with them using git.
A similar procedure can be done with mercurial, but exporting the patches to a series of
emails is more complicated, as it doesn't have anything equivalent to "git format-patch" (at least,
I don't know any similar feature). So, with -hg, you'll have to use some tricks to get a patch
series.
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-02 17:38 ` Stefan Ringel
@ 2010-02-02 20:05 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-02 20:05 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Devin Heitmueller, linux-media
Stefan Ringel wrote:
>> Ok, but maybe you missed my point: at the long term, we should get rid of hack.c, and
>> be sure that all needed initializations are done by zl10353 driver or by tm6010-dvb.
>>
> I think I all are done by zl10353 driver.
>
> I thinbk all config param is usefull and ".tm6000" for tm6000 specific
> once. For what is ".parallel_ts" ?
zl10353 may be connected via a serial or via a parallel interface to the chip.
So, it basically depends on how the wiring between zl10353 and the bridge is done.
>
> int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
> {
> struct tm6000_dvb *dvb = dev->dvb;
>
> if(dev->caps.has_zl10353) {
> struct zl10353_config config =
> {.demod_address = dev->demod_addr,
> .no_tuner = 1,
> .parallel_ts = 1,
> .if2 = 45700,
> .disable_i2c_gate_ctrl = 1,
> .tm6000 = 1,
> };
>
> dvb->frontend = pseudo_zl10353_attach(dev, &config,
> // dvb->frontend = dvb_attach (zl10353_attach, &config,
> &dev->i2c_adap);
> }
> else {
> printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
> return -1;
> }
>
> return (!dvb->frontend) ? -1 : 0;
> }
>
>
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-02 20:03 ` Mauro Carvalho Chehab
@ 2010-02-02 20:19 ` Stefan Ringel
2010-02-02 20:30 ` Mauro Carvalho Chehab
2010-02-02 20:42 ` Stefan Ringel
1 sibling, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-02 20:19 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
Am 02.02.2010 21:03, schrieb Mauro Carvalho Chehab:
>
>>> Those tuner callback initializations are board-specific. So, it is better to test
>>> for your board model, if you need something different than what's currently done.
>>>
>>>
>>>
>> This tuner reset works with my stick, but I think that can test with
>> other tm6000 based sticks and if it not works then I can say this as a
>> board-specific.
>>
> It won't work on my boards. The GPIO pin used by each board is different.
>
>
Have you the right gpio pin in the card struct. I have the
".gpio_addr_tun_reset" the correct gpio pin
[TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
+ .name = "Terratec Cinergy Hybrid XE",
+ .tuner_type = TUNER_XC2028, /* has a XC3028 */
+ .tuner_addr = 0xc2 >> 1,
+ .demod_addr = 0x1e >> 1,
+ .type = TM6010,
+ .caps = {
+ .has_tuner = 1,
+ .has_dvb = 1,
+ .has_zl10353 = 1,
+ .has_eeprom = 1,
+ .has_remote = 1,
+ },
+ .gpio_addr_tun_reset = TM6010_GPIO_2, /* here */
+ }
};
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-02 20:19 ` Stefan Ringel
@ 2010-02-02 20:30 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-02 20:30 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
Stefan Ringel wrote:
> Am 02.02.2010 21:03, schrieb Mauro Carvalho Chehab:
>>>> Those tuner callback initializations are board-specific. So, it is better to test
>>>> for your board model, if you need something different than what's currently done.
>>>>
>>>>
>>>>
>>> This tuner reset works with my stick, but I think that can test with
>>> other tm6000 based sticks and if it not works then I can say this as a
>>> board-specific.
>>>
>> It won't work on my boards. The GPIO pin used by each board is different.
>>
>>
> Have you the right gpio pin in the card struct. I have the
> ".gpio_addr_tun_reset" the correct gpio pin
>
> [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
> + .name = "Terratec Cinergy Hybrid XE",
> + .tuner_type = TUNER_XC2028, /* has a XC3028 */
> + .tuner_addr = 0xc2 >> 1,
> + .demod_addr = 0x1e >> 1,
> + .type = TM6010,
> + .caps = {
> + .has_tuner = 1,
> + .has_dvb = 1,
> + .has_zl10353 = 1,
> + .has_eeprom = 1,
> + .has_remote = 1,
> + },
> + .gpio_addr_tun_reset = TM6010_GPIO_2, /* here */
> + }
> };
>
Ok, this works :) All needed pins should be customized there, either individually
or via an struct similar to the one done at em28xx driver. Both ways have advantages
and disadvantages.
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-02 20:03 ` Mauro Carvalho Chehab
2010-02-02 20:19 ` Stefan Ringel
@ 2010-02-02 20:42 ` Stefan Ringel
2010-02-02 20:52 ` Mauro Carvalho Chehab
1 sibling, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-02 20:42 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
Am 02.02.2010 21:03, schrieb Mauro Carvalho Chehab:
>
>>>> @@ -404,6 +432,7 @@ int tm6000_init (struct tm6000_core *dev)
>>>> {
>>>> int board, rc=0, i, size;
>>>> struct reg_init *tab;
>>>> + u8 buf[40];
>>>>
>>>>
>>> Why "40" ? Please avoid using magic numbers here, especially if you're
>>> not checking at the logic if you're writing outside the buffer.
>>>
>>>
>>>
>> It important for tm6010 init sequence to enable the demodulator, because
>> the demodulator haven't found after init tuner.
>>
> Probably, there is some i2c gate to enable/disable the i2c access to the
> demodulator. The better way is to add a call to the tm6000-dvb and let it
> init the demodulator.
>
> Also, since there's a gate for the demodulator, the proper way is to add
> a callback to control it. Please take a look at saa7134 and seek for i2c_gate_ctrl
> to see how such logic works.
>
>
It has followed structure schema without the GPIOs:
1. tm6010 init
2. enable zl10353
3. tm6010 re-init
If it board specific then it's better when board number definition
switch from tm6000-card.c to tm6000.h . We can use in all tm6000*.c
files the board definition .
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-02 20:42 ` Stefan Ringel
@ 2010-02-02 20:52 ` Mauro Carvalho Chehab
2010-02-02 21:11 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-02 20:52 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
Stefan Ringel wrote:
> Am 02.02.2010 21:03, schrieb Mauro Carvalho Chehab:
>>>>> @@ -404,6 +432,7 @@ int tm6000_init (struct tm6000_core *dev)
>>>>> {
>>>>> int board, rc=0, i, size;
>>>>> struct reg_init *tab;
>>>>> + u8 buf[40];
>>>>>
>>>>>
>>>> Why "40" ? Please avoid using magic numbers here, especially if you're
>>>> not checking at the logic if you're writing outside the buffer.
>>>>
>>>>
>>>>
>>> It important for tm6010 init sequence to enable the demodulator, because
>>> the demodulator haven't found after init tuner.
>>>
>> Probably, there is some i2c gate to enable/disable the i2c access to the
>> demodulator. The better way is to add a call to the tm6000-dvb and let it
>> init the demodulator.
>>
>> Also, since there's a gate for the demodulator, the proper way is to add
>> a callback to control it. Please take a look at saa7134 and seek for i2c_gate_ctrl
>> to see how such logic works.
>>
>>
> It has followed structure schema without the GPIOs:
> 1. tm6010 init
> 2. enable zl10353
> 3. tm6010 re-init
>
> If it board specific then it's better when board number definition
> switch from tm6000-card.c to tm6000.h . We can use in all tm6000*.c
> files the board definition .
What's board specific: all stuff that has GPIO, and the demod/frontend enable code.
In order to have a better structure, the demod/frontend enable code should be at the tm6000-dvb,
just like the other drivers. There, you'll have a switch for those devices that have DVB
(Among others, I have here one 10moons device that is analog-only, with a tm5600 - a stripped
down version of tm6000, without the DVB part).
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH] - tm6000 DVB support
2010-02-02 20:52 ` Mauro Carvalho Chehab
@ 2010-02-02 21:11 ` Stefan Ringel
2010-02-03 20:10 ` [PATCH 1/15] - tm6000 build hunk Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-02 21:11 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
Am 02.02.2010 21:52, schrieb Mauro Carvalho Chehab:
> Stefan Ringel wrote:
>
>> Am 02.02.2010 21:03, schrieb Mauro Carvalho Chehab:
>>
>>>>>> @@ -404,6 +432,7 @@ int tm6000_init (struct tm6000_core *dev)
>>>>>> {
>>>>>> int board, rc=0, i, size;
>>>>>> struct reg_init *tab;
>>>>>> + u8 buf[40];
>>>>>>
>>>>>>
>>>>>>
>>>>> Why "40" ? Please avoid using magic numbers here, especially if you're
>>>>> not checking at the logic if you're writing outside the buffer.
>>>>>
>>>>>
>>>>>
>>>>>
>>>> It important for tm6010 init sequence to enable the demodulator, because
>>>> the demodulator haven't found after init tuner.
>>>>
>>>>
>>> Probably, there is some i2c gate to enable/disable the i2c access to the
>>> demodulator. The better way is to add a call to the tm6000-dvb and let it
>>> init the demodulator.
>>>
>>> Also, since there's a gate for the demodulator, the proper way is to add
>>> a callback to control it. Please take a look at saa7134 and seek for i2c_gate_ctrl
>>> to see how such logic works.
>>>
>>>
>>>
>> It has followed structure schema without the GPIOs:
>> 1. tm6010 init
>> 2. enable zl10353
>> 3. tm6010 re-init
>>
>> If it board specific then it's better when board number definition
>> switch from tm6000-card.c to tm6000.h . We can use in all tm6000*.c
>> files the board definition .
>>
> What's board specific: all stuff that has GPIO, and the demod/frontend enable code.
> In order to have a better structure, the demod/frontend enable code should be at the tm6000-dvb,
> just like the other drivers. There, you'll have a switch for those devices that have DVB
> (Among others, I have here one 10moons device that is analog-only, with a tm5600 - a stripped
> down version of tm6000, without the DVB part).
>
>
I have additional information to enable demodulator, it must enable
before firmware load after that it cannot find zl10353, I think. Should
I test it!
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/15] - tm6000 build hunk
2010-02-02 21:11 ` Stefan Ringel
@ 2010-02-03 20:10 ` Stefan Ringel
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (3 more replies)
0 siblings, 4 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:10 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -32,7 +32,7 @@
#include "tm6000.h"
#include "tm6000-regs.h"
#include "tuner-xc2028.h"
-#include "tuner-xc5000.h"
+#include "xc5000.h"
#define TM6000_BOARD_UNKNOWN 0
#define TM5600_BOARD_GENERIC 1
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE
2010-02-03 20:10 ` [PATCH 1/15] - tm6000 build hunk Stefan Ringel
@ 2010-02-03 20:13 ` Stefan Ringel
2010-02-03 20:15 ` [PATCH 3/15] - tm6000 bugfix hunk in init_dev Stefan Ringel
` (13 more replies)
2010-02-03 20:16 ` [PATCH 1/15] - tm6000 build hunk Mauro Carvalho Chehab
` (2 subsequent siblings)
3 siblings, 14 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:13 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -44,6 +44,10 @@
#define TM6000_BOARD_FREECOM_AND_SIMILAR 7
#define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
#define TM6010_BOARD_HAUPPAUGE_900H 9
+#define TM6010_BOARD_BEHOLD_WANDER 10
+#define TM6010_BOARD_BEHOLD_VOYAGER 11
+#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
+
#define TM6000_MAXBOARDS 16
static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
@@ -208,7 +212,21 @@ struct tm6000_board tm6000_boards[] = {
},
.gpio_addr_tun_reset = TM6000_GPIO_2,
},
-
+ [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
+ .name = "Terratec Cinergy Hybrid XE",
+ .tuner_type = TUNER_XC2028, /* has a XC3028 */
+ .tuner_addr = 0xc2 >> 1,
+ .demod_addr = 0x1e >> 1,
+ .type = TM6010,
+ .caps = {
+ .has_tuner = 1,
+ .has_dvb = 1,
+ .has_zl10353 = 1,
+ .has_eeprom = 1,
+ .has_remote = 1,
+ },
+ .gpio_addr_tun_reset = TM6010_GPIO_2,
+ }
};
/* table of devices that work with this driver */
@@ -221,12 +239,13 @@ struct usb_device_id tm6000_id_table [] = {
{ USB_DEVICE(0x2040, 0x6600), .driver_info =
TM6010_BOARD_HAUPPAUGE_900H },
{ USB_DEVICE(0x6000, 0xdec0), .driver_info =
TM6010_BOARD_BEHOLD_WANDER },
{ USB_DEVICE(0x6000, 0xdec1), .driver_info =
TM6010_BOARD_BEHOLD_VOYAGER },
+ { USB_DEVICE(0x0ccd, 0x0086), .driver_info =
TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
{ },
};
@@ -302,15 +344,19 @@ static void tm6000_config_tuner (struct
tm6000_core *dev)
memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
memset (&ctl,0,sizeof(ctl));
- ctl.mts = 1;
- ctl.read_not_reliable = 1;
+ ctl.input1 = 1;
+ ctl.read_not_reliable = 0;
ctl.msleep = 10;
-
+ ctl.demod = XC3028_FE_ZARLINK456;
+ ctl.vhfbw7 = 1;
+ ctl.uhfbw8 = 1;
+ ctl.switch_mode = 1;
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
switch(dev->model) {
case TM6010_BOARD_HAUPPAUGE_900H:
+ case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
ctl.fname = "xc3028L-v36.fw";
break;
default:
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 3/15] - tm6000 bugfix hunk in init_dev
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
@ 2010-02-03 20:15 ` Stefan Ringel
2010-02-03 20:22 ` Mauro Carvalho Chehab
2010-02-03 20:16 ` [PATCH 4/15] - tm6000.h Stefan Ringel
` (12 subsequent siblings)
13 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:15 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -402,6 +448,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
}
#endif
}
+ return 0;
err2:
v4l2_device_unregister(&dev->v4l2_dev);
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 4/15] - tm6000.h
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
2010-02-03 20:15 ` [PATCH 3/15] - tm6000 bugfix hunk in init_dev Stefan Ringel
@ 2010-02-03 20:16 ` Stefan Ringel
2010-02-03 20:25 ` Mauro Carvalho Chehab
2010-02-03 20:18 ` [PATCH 5/15] - tm6000 bugfix i2c transfer Stefan Ringel
` (11 subsequent siblings)
13 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:16 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -90,12 +97,14 @@ enum tm6000_core_state {
DEV_MISCONFIGURED = 0x04,
};
+#if 1
/* io methods */
enum tm6000_io_method {
IO_NONE,
IO_READ,
IO_MMAP,
};
+#endif
enum tm6000_mode {
TM6000_MODE_UNKNOWN=0,
@@ -202,6 +211,9 @@ struct tm6000_fh {
V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM
+/* In tm6000-cards.c */
+
+int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
/* In tm6000-core.c */
int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
@@ -209,7 +221,6 @@ int tm6000_read_write_usb (struct tm6000_core *dev,
u8 reqtype, u8 req,
int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_init (struct tm6000_core *dev);
-int tm6000_init_after_firmware (struct tm6000_core *dev);
int tm6000_init_analog_mode (struct tm6000_core *dev);
int tm6000_init_digital_mode (struct tm6000_core *dev);
@@ -231,7 +242,12 @@ int tm6000_set_standard (struct tm6000_core *dev,
v4l2_std_id *norm);
int tm6000_i2c_register(struct tm6000_core *dev);
int tm6000_i2c_unregister(struct tm6000_core *dev);
+#if 1
/* In tm6000-queue.c */
+#if 0
+int tm6000_init_isoc(struct tm6000_core *dev, int max_packets);
+void tm6000_uninit_isoc(struct tm6000_core *dev);
+#endif
int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -276,3 +292,4 @@ extern int tm6000_debug;
__FUNCTION__ , ##arg); } while (0)
+#endif
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/15] - tm6000 build hunk
2010-02-03 20:10 ` [PATCH 1/15] - tm6000 build hunk Stefan Ringel
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
@ 2010-02-03 20:16 ` Mauro Carvalho Chehab
2010-02-03 20:17 ` Devin Heitmueller
2010-02-03 21:48 ` Stefan Ringel
3 siblings, 0 replies; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-03 20:16 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
Stefan Ringel wrote:
OK, patch is correct, but you should:
- Use the email subject to summarize what the patch does
- Add more detailed patch description;
- Add your Signed-off-by.
In this specific case, you could have:
Subject: Fix compilation breakage
Signed-off-by: your name <your@email>
(this is a really trivial patch - so, you don't need a detailed description)
> --- a/drivers/staging/tm6000/tm6000-cards.c
> +++ b/drivers/staging/tm6000/tm6000-cards.c
> @@ -32,7 +32,7 @@
> #include "tm6000.h"
> #include "tm6000-regs.h"
> #include "tuner-xc2028.h"
> -#include "tuner-xc5000.h"
> +#include "xc5000.h"
>
> #define TM6000_BOARD_UNKNOWN 0
> #define TM5600_BOARD_GENERIC 1
>
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/15] - tm6000 build hunk
2010-02-03 20:10 ` [PATCH 1/15] - tm6000 build hunk Stefan Ringel
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
2010-02-03 20:16 ` [PATCH 1/15] - tm6000 build hunk Mauro Carvalho Chehab
@ 2010-02-03 20:17 ` Devin Heitmueller
2010-02-03 21:48 ` Stefan Ringel
3 siblings, 0 replies; 55+ messages in thread
From: Devin Heitmueller @ 2010-02-03 20:17 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Mauro Carvalho Chehab, linux-media
On Wed, Feb 3, 2010 at 3:10 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
> --- a/drivers/staging/tm6000/tm6000-cards.c
> +++ b/drivers/staging/tm6000/tm6000-cards.c
Before you send too many of these, I should point out that there is a
well-defined format expected for patches. Look here:
http://linuxtv.org/wiki/index.php/Development:_How_to_submit_patches
And you can see an example here:
http://kernellabs.com/hg/~dheitmueller/em28xx-test/rev/42272c1dd883
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 5/15] - tm6000 bugfix i2c transfer
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
2010-02-03 20:15 ` [PATCH 3/15] - tm6000 bugfix hunk in init_dev Stefan Ringel
2010-02-03 20:16 ` [PATCH 4/15] - tm6000.h Stefan Ringel
@ 2010-02-03 20:18 ` Stefan Ringel
2010-02-03 20:18 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Mauro Carvalho Chehab
` (10 subsequent siblings)
13 siblings, 0 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:18 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -86,6 +86,11 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
msgs[i].len == 1 ? 0 : msgs[i].buf[1],
msgs[i + 1].buf, msgs[i + 1].len);
i++;
+
+ if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
+ tm6000_set_reg(dev, 0x32, 0,0);
+ tm6000_set_reg(dev, 0x33, 0,0);
+ }
if (i2c_debug >= 2)
for (byte = 0; byte < msgs[i].len; byte++)
printk(" %02x", msgs[i].buf[byte]);
@@ -99,6 +104,12 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
REQ_16_SET_GET_I2C_WR1_RDN,
addr | msgs[i].buf[0] << 8, 0,
msgs[i].buf + 1, msgs[i].len - 1);
+
+
+ if ((dev->dev_type == TM6010) && (addr == 0xc2)) {
+ tm6000_set_reg(dev, 0x32, 0,0);
+ tm6000_set_reg(dev, 0x33, 0,0);
+ }
}
if (i2c_debug >= 2)
printk("\n");
@@ -198,7 +209,7 @@ static struct i2c_algorithm tm6000_algo = {
static struct i2c_adapter tm6000_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
+ .class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
.name = "tm6000",
.id = I2C_HW_B_TM6000,
.algo = &tm6000_algo
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (2 preceding siblings ...)
2010-02-03 20:18 ` [PATCH 5/15] - tm6000 bugfix i2c transfer Stefan Ringel
@ 2010-02-03 20:18 ` Mauro Carvalho Chehab
2010-02-03 20:20 ` [PATCH 6/15] - tm6000 bugfix usb transfer in DVB mode Stefan Ringel
` (9 subsequent siblings)
13 siblings, 0 replies; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-03 20:18 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
Stefan Ringel wrote:
> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
Signed-off-by:
(first letter is on upper case)
The patch looks ok to my eyes.
>
> --- a/drivers/staging/tm6000/tm6000-cards.c
> +++ b/drivers/staging/tm6000/tm6000-cards.c
> @@ -44,6 +44,10 @@
> #define TM6000_BOARD_FREECOM_AND_SIMILAR 7
> #define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8
> #define TM6010_BOARD_HAUPPAUGE_900H 9
> +#define TM6010_BOARD_BEHOLD_WANDER 10
> +#define TM6010_BOARD_BEHOLD_VOYAGER 11
> +#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
> +
>
> #define TM6000_MAXBOARDS 16
> static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
> @@ -208,7 +212,21 @@ struct tm6000_board tm6000_boards[] = {
> },
> .gpio_addr_tun_reset = TM6000_GPIO_2,
> },
> -
> + [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
> + .name = "Terratec Cinergy Hybrid XE",
> + .tuner_type = TUNER_XC2028, /* has a XC3028 */
> + .tuner_addr = 0xc2 >> 1,
> + .demod_addr = 0x1e >> 1,
> + .type = TM6010,
> + .caps = {
> + .has_tuner = 1,
> + .has_dvb = 1,
> + .has_zl10353 = 1,
> + .has_eeprom = 1,
> + .has_remote = 1,
> + },
> + .gpio_addr_tun_reset = TM6010_GPIO_2,
> + }
> };
>
> /* table of devices that work with this driver */
> @@ -221,12 +239,13 @@ struct usb_device_id tm6000_id_table [] = {
> { USB_DEVICE(0x2040, 0x6600), .driver_info =
> TM6010_BOARD_HAUPPAUGE_900H },
> { USB_DEVICE(0x6000, 0xdec0), .driver_info =
> TM6010_BOARD_BEHOLD_WANDER },
> { USB_DEVICE(0x6000, 0xdec1), .driver_info =
> TM6010_BOARD_BEHOLD_VOYAGER },
> + { USB_DEVICE(0x0ccd, 0x0086), .driver_info =
> TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
> { },
> };
>
> @@ -302,15 +344,19 @@ static void tm6000_config_tuner (struct
> tm6000_core *dev)
> memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
> memset (&ctl,0,sizeof(ctl));
>
> - ctl.mts = 1;
> - ctl.read_not_reliable = 1;
> + ctl.input1 = 1;
> + ctl.read_not_reliable = 0;
> ctl.msleep = 10;
> -
> + ctl.demod = XC3028_FE_ZARLINK456;
> + ctl.vhfbw7 = 1;
> + ctl.uhfbw8 = 1;
> + ctl.switch_mode = 1;
> xc2028_cfg.tuner = TUNER_XC2028;
> xc2028_cfg.priv = &ctl;
>
> switch(dev->model) {
> case TM6010_BOARD_HAUPPAUGE_900H:
> + case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
> ctl.fname = "xc3028L-v36.fw";
> break;
> default:
>
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 6/15] - tm6000 bugfix usb transfer in DVB mode
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (3 preceding siblings ...)
2010-02-03 20:18 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Mauro Carvalho Chehab
@ 2010-02-03 20:20 ` Stefan Ringel
2010-02-03 20:22 ` [PATCH 7/15] - tm6000 Stefan Ringel
` (8 subsequent siblings)
13 siblings, 0 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:20 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -17,7 +17,9 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include <linux/kernel.h>
#include <linux/usb.h>
+#include <compat.h>
#include "tm6000.h"
#include "tm6000-regs.h"
@@ -30,17 +32,61 @@
#include "tuner-xc2028.h"
+static void inline print_err_status (struct tm6000_core *dev,
+ int packet, int status)
+{
+ char *errmsg = "Unknown";
+
+ switch(status) {
+ case -ENOENT:
+ errmsg = "unlinked synchronuously";
+ break;
+ case -ECONNRESET:
+ errmsg = "unlinked asynchronuously";
+ break;
+ case -ENOSR:
+ errmsg = "Buffer error (overrun)";
+ break;
+ case -EPIPE:
+ errmsg = "Stalled (device not responding)";
+ break;
+ case -EOVERFLOW:
+ errmsg = "Babble (bad cable?)";
+ break;
+ case -EPROTO:
+ errmsg = "Bit-stuff error (bad cable?)";
+ break;
+ case -EILSEQ:
+ errmsg = "CRC/Timeout (could be anything)";
+ break;
+ case -ETIME:
+ errmsg = "Device does not respond";
+ break;
+ }
+ if (packet<0) {
+ dprintk(dev, 1, "URB status %d [%s].\n",
+ status, errmsg);
+ } else {
+ dprintk(dev, 1, "URB packet %d, status %d [%s].\n",
+ packet, status, errmsg);
+ }
+}
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+static void tm6000_urb_received(struct urb *urb, struct pt_regs *ptregs)
+#else
static void tm6000_urb_received(struct urb *urb)
+#endif
{
int ret;
struct tm6000_core* dev = urb->context;
- if(urb->status != 0){
- printk(KERN_ERR "tm6000: status != 0\n");
+ if(urb->status != 0) {
+ print_err_status (dev,0,urb->status);
}
else if(urb->actual_length>0){
- dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
- urb->actual_length);
+ dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
urb->actual_length);
}
if(dev->dvb->streams > 0) {
@@ -56,49 +102,37 @@ static void tm6000_urb_received(struct urb *urb)
int tm6000_start_stream(struct tm6000_core *dev)
{
int ret;
- unsigned int pipe, maxPaketSize;
+ unsigned int pipe, size;
struct tm6000_dvb *dvb = dev->dvb;
printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
tm6000_init_digital_mode(dev);
-/*
- ret = tm6000_set_led_status(tm6000_dev, 0x1);
- if(ret < 0) {
- return -1;
- }
-*/
-
dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
if(dvb->bulk_urb == NULL) {
printk(KERN_ERR "tm6000: couldn't allocate urb\n");
return -ENOMEM;
}
- maxPaketSize = dev->bulk_in->desc.wMaxPacketSize;
+ pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
+ & USB_ENDPOINT_NUMBER_MASK);
+
+ size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
+ size = size * 15; // 512 x 8 or 12 or 15
- dvb->bulk_urb->transfer_buffer = kzalloc(maxPaketSize, GFP_KERNEL);
+ dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
if(dvb->bulk_urb->transfer_buffer == NULL) {
usb_free_urb(dvb->bulk_urb);
printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
return -ENOMEM;
}
-
- pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in->desc.bEndpointAddress
- & USB_ENDPOINT_NUMBER_MASK);
-
+
usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe,
dvb->bulk_urb->transfer_buffer,
- maxPaketSize,
+ size,
tm6000_urb_received, dev);
- ret = usb_set_interface(dev->udev, 0, 1);
- if(ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during set
interface\n", ret, __FUNCTION__);
- return ret;
- }
-
ret = usb_clear_halt(dev->udev, pipe);
if(ret < 0) {
printk(KERN_ERR "tm6000: error %i in %s during pipe
reset\n",ret,__FUNCTION__);
@@ -107,15 +141,14 @@ int tm6000_start_stream(struct tm6000_core *dev)
else {
printk(KERN_ERR "tm6000: pipe resetted\n");
}
-
-// mutex_lock(&tm6000_driver.open_close_mutex);
+
+/* mutex_lock(&tm6000_driver.open_close_mutex); */
ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
-
-// mutex_unlock(&tm6000_driver.open_close_mutex);
+/* mutex_unlock(&tm6000_driver.open_close_mutex); */
if (ret) {
printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",ret);
-
+
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
return ret;
@@ -126,18 +159,12 @@ int tm6000_start_stream(struct tm6000_core *dev)
void tm6000_stop_stream(struct tm6000_core *dev)
{
- int ret;
struct tm6000_dvb *dvb = dev->dvb;
-// tm6000_set_led_status(tm6000_dev, 0x0);
-
- ret = usb_set_interface(dev->udev, 0, 0);
- if(ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during set
interface\n",ret,__FUNCTION__);
- }
-
if(dvb->bulk_urb) {
+ printk (KERN_INFO "urb killing\n");
usb_kill_urb(dvb->bulk_urb);
+ printk (KERN_INFO "urb buffer free\n");
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
dvb->bulk_urb = NULL;
@@ -154,7 +181,7 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
mutex_lock(&dvb->mutex);
if(dvb->streams == 0) {
dvb->streams = 1;
-// mutex_init(&tm6000_dev->streaming_mutex);
+/* mutex_init(&tm6000_dev->streaming_mutex); */
tm6000_start_stream(dev);
}
else {
@@ -173,14 +200,17 @@ int tm6000_stop_feed(struct dvb_demux_feed *feed) {
printk(KERN_INFO "tm6000: got stop feed request %s\n",__FUNCTION__);
mutex_lock(&dvb->mutex);
- --dvb->streams;
- if(0 == dvb->streams) {
+ printk (KERN_INFO "stream %#x\n", dvb->streams);
+ --(dvb->streams);
+ if(dvb->streams == 0) {
+ printk (KERN_INFO "stop stream\n");
tm6000_stop_stream(dev);
-// mutex_destroy(&tm6000_dev->streaming_mutex);
+/* mutex_destroy(&tm6000_dev->streaming_mutex); */
}
+
mutex_unlock(&dvb->mutex);
-// mutex_destroy(&tm6000_dev->streaming_mutex);
+/* mutex_destroy(&tm6000_dev->streaming_mutex); */
return 0;
}
@@ -191,13 +221,16 @@ int tm6000_dvb_attach_frontend(struct tm6000_core
*dev)
if(dev->caps.has_zl10353) {
struct zl10353_config config =
- {.demod_address = dev->demod_addr >> 1,
+ {.demod_address = dev->demod_addr,
.no_tuner = 1,
-// .input_frequency = 0x19e9,
-// .r56_agc_targets = 0x1c,
+ .parallel_ts = 1,
+ .if2 = 45700,
+ .disable_i2c_gate_ctrl = 1,
+ .tm6000 = 1,
};
dvb->frontend = pseudo_zl10353_attach(dev, &config,
+/* dvb->frontend = dvb_attach (zl10353_attach, &config, */
&dev->i2c_adap);
}
else {
@@ -258,8 +292,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
| DMX_MEMORY_BASED_FILTERING;
dvb->demux.priv = dev;
- dvb->demux.filternum = 256;
- dvb->demux.feednum = 256;
+ dvb->demux.filternum = 5; /* 256; */
+ dvb->demux.feednum = 5; /* 256; */
dvb->demux.start_feed = tm6000_start_feed;
dvb->demux.stop_feed = tm6000_stop_feed;
dvb->demux.write_to_decoder = NULL;
@@ -307,7 +341,7 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
usb_free_urb(bulk_urb);
}
-// mutex_lock(&tm6000_driver.open_close_mutex);
+/* mutex_lock(&tm6000_driver.open_close_mutex); */
if(dvb->frontend) {
dvb_frontend_detach(dvb->frontend);
dvb_unregister_frontend(dvb->frontend);
@@ -317,6 +351,6 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
dvb_dmx_release(&dvb->demux);
dvb_unregister_adapter(&dvb->adapter);
mutex_destroy(&dvb->mutex);
-// mutex_unlock(&tm6000_driver.open_close_mutex);
+/* mutex_unlock(&tm6000_driver.open_close_mutex); */
}
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 7/15] - tm6000
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (4 preceding siblings ...)
2010-02-03 20:20 ` [PATCH 6/15] - tm6000 bugfix usb transfer in DVB mode Stefan Ringel
@ 2010-02-03 20:22 ` Stefan Ringel
2010-02-03 20:23 ` [PATCH 2/15] - tm6000 bugfix Stefan Ringel
` (7 subsequent siblings)
13 siblings, 0 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:22 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -23,12 +23,15 @@
// Use the tm6000-hack, instead of the proper initialization code
//#define HACK 1
+#include "compat.h"
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/videobuf-vmalloc.h>
#include "tm6000-usb-isoc.h"
#include <linux/i2c.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
#include <linux/mutex.h>
+#endif
#include <media/v4l2-device.h>
@@ -78,6 +81,10 @@ struct tm6000_dmaqueue {
/* thread for generating video stream*/
struct task_struct *kthread;
wait_queue_head_t wq;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ struct semaphore *notify;
+ int rmmod:1;
+#endif
/* Counters to control fps rate */
int frame;
int ini_jiffies;
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 3/15] - tm6000 bugfix hunk in init_dev
2010-02-03 20:15 ` [PATCH 3/15] - tm6000 bugfix hunk in init_dev Stefan Ringel
@ 2010-02-03 20:22 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-03 20:22 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
This is too generic:
tm6000 bugfix hunk in init_dev
A better subject would be:
[PATCH 3/15] tm6000: avoid unregister the driver after success at tm6000_init_dev
PS.: don't mind to re-submit those patches where just the subject has troubles.
I'll fix it locally. I'm pointing the issues to save me some time on your next
patcheset submission ;)
For the patchsets that you forgot to sign (1/15 for example), just reply your own
email with Signed-off-by:.
Cheers,
Mauro
Stefan Ringel wrote:
> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>
> --- a/drivers/staging/tm6000/tm6000-cards.c
> +++ b/drivers/staging/tm6000/tm6000-cards.c
> @@ -402,6 +448,7 @@ static int tm6000_init_dev(struct tm6000_core *dev)
> }
> #endif
> }
> + return 0;
>
> err2:
> v4l2_device_unregister(&dev->v4l2_dev);
>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 2/15] - tm6000 bugfix
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (5 preceding siblings ...)
2010-02-03 20:22 ` [PATCH 7/15] - tm6000 Stefan Ringel
@ 2010-02-03 20:23 ` Stefan Ringel
2010-02-03 20:25 ` [PATCH 9/15] - tm6000 analog digital switch Stefan Ringel
` (6 subsequent siblings)
13 siblings, 0 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:23 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -459,13 +506,13 @@ static int tm6000_usb_probe(struct usb_interface
*interface,
/* Check to see next free device and mark as used */
nr=find_first_zero_bit(&tm6000_devused,TM6000_MAXBOARDS);
if (nr >= TM6000_MAXBOARDS) {
- printk ("tm6000: Supports only %i em28xx
boards.\n",TM6000_MAXBOARDS);
+ printk ("tm6000: Supports only %i tm60xx
boards.\n",TM6000_MAXBOARDS);
usb_put_dev(usbdev);
return -ENOMEM;
}
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 4/15] - tm6000.h
2010-02-03 20:16 ` [PATCH 4/15] - tm6000.h Stefan Ringel
@ 2010-02-03 20:25 ` Mauro Carvalho Chehab
2010-02-03 20:50 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-03 20:25 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
This one is a very obscure patch. What are you doing this patch and why?
Stefan Ringel wrote:
> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>
> --- a/drivers/staging/tm6000/tm6000.h
> +++ b/drivers/staging/tm6000/tm6000.h
> @@ -90,12 +97,14 @@ enum tm6000_core_state {
> DEV_MISCONFIGURED = 0x04,
> };
>
> +#if 1
> /* io methods */
> enum tm6000_io_method {
> IO_NONE,
> IO_READ,
> IO_MMAP,
> };
> +#endif
>
> enum tm6000_mode {
> TM6000_MODE_UNKNOWN=0,
> @@ -202,6 +211,9 @@ struct tm6000_fh {
> V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
> V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM
>
> +/* In tm6000-cards.c */
> +
> +int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
> /* In tm6000-core.c */
>
> int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
> @@ -209,7 +221,6 @@ int tm6000_read_write_usb (struct tm6000_core *dev,
> u8 reqtype, u8 req,
> int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
> int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
> int tm6000_init (struct tm6000_core *dev);
> -int tm6000_init_after_firmware (struct tm6000_core *dev);
>
> int tm6000_init_analog_mode (struct tm6000_core *dev);
> int tm6000_init_digital_mode (struct tm6000_core *dev);
> @@ -231,7 +242,12 @@ int tm6000_set_standard (struct tm6000_core *dev,
> v4l2_std_id *norm);
> int tm6000_i2c_register(struct tm6000_core *dev);
> int tm6000_i2c_unregister(struct tm6000_core *dev);
>
> +#if 1
> /* In tm6000-queue.c */
> +#if 0
> +int tm6000_init_isoc(struct tm6000_core *dev, int max_packets);
> +void tm6000_uninit_isoc(struct tm6000_core *dev);
> +#endif
>
> int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
>
> @@ -276,3 +292,4 @@ extern int tm6000_debug;
> __FUNCTION__ , ##arg); } while (0)
>
>
> +#endif
>
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 9/15] - tm6000 analog digital switch
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (6 preceding siblings ...)
2010-02-03 20:23 ` [PATCH 2/15] - tm6000 bugfix Stefan Ringel
@ 2010-02-03 20:25 ` Stefan Ringel
2010-02-03 20:40 ` Mauro Carvalho Chehab
2010-02-03 20:27 ` [PATCH 2/15] - tm6000 add digital init for tm6010 Stefan Ringel
` (5 subsequent siblings)
13 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:25 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <media/tuner.h>
#include <linux/mutex.h>
+#include "compat.h"
#include <asm/unaligned.h>
#include "tuner-i2c.h"
#include "tuner-xc2028.h"
@@ -994,6 +995,13 @@ static int generic_set_freq(struct dvb_frontend
*fe, u32 freq /* in HZ */,
buf[0], buf[1], buf[2], buf[3],
freq / 1000000, (freq % 1000000) / 1000);
+ if (priv->ctrl.switch_mode) {
+ if (new_mode == T_ANALOG_TV)
+ do_tuner_callback(fe, SWITCH_TV_MODE, 0);
+ if (new_mode == T_DIGITAL_TV)
+ do_tuner_callback(fe, SWITCH_TV_MODE, 1);
+ }
+
rc = 0;
ret:
--- a/drivers/media/common/tuners/tuner-xc2028.h
+++ b/drivers/media/common/tuners/tuner-xc2028.h
@@ -42,6 +42,7 @@ struct xc2028_ctrl {
unsigned int disable_power_mgmt:1;
unsigned int read_not_reliable:1;
unsigned int demod;
+ unsigned int switch_mode:1;
enum firmware_type type:2;
};
@@ -54,6 +55,7 @@ struct xc2028_config {
/* xc2028 commands for callback */
#define XC2028_TUNER_RESET 0
#define XC2028_RESET_CLK 1
+#define SWITCH_TV_MODE 2
#if defined(CONFIG_MEDIA_TUNER_XC2028) ||
(defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -269,13 +291,33 @@ static int tm6000_tuner_callback(void *ptr, int
component, int command, int arg)
TM6000_GPIO_CLK, 0);
if (rc<0)
return rc;
- msleep(100);
+ msleep(10);
rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
TM6000_GPIO_CLK, 1);
- msleep(100);
+ msleep(10);
+ break;
+ }
+ break;
+
+ case SWITCH_TV_MODE:
+ /* switch between analog and digital */
+ switch (arg) {
+ case 0:
+ printk(KERN_INFO "switch to analog");
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 1);
+ printk(KERN_INFO "analog");
+ break;
+ case 1:
+ printk(KERN_INFO "switch to digital");
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 0);
+ printk(KERN_INFO "digital");
break;
}
+ break;
}
+
return (rc);
}
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -235,7 +268,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
.i2c_adap = &dev->i2c_adap,
.i2c_addr = dev->tuner_addr,
};
-
+
+ dvb->frontend->callback = tm6000_tuner_callback;
ret = dvb_register_frontend(&dvb->adapter, dvb->frontend);
if (ret < 0) {
printk(KERN_ERR
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -269,13 +291,33 @@ static int tm6000_tuner_callback(void *ptr, int
component, int command, int arg)
TM6000_GPIO_CLK, 0);
if (rc<0)
return rc;
- msleep(100);
+ msleep(10);
rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
TM6000_GPIO_CLK, 1);
- msleep(100);
+ msleep(10);
+ break;
+ }
+ break;
+
+ case SWITCH_TV_MODE:
+ /* switch between analog and digital */
+ switch (arg) {
+ case 0:
+ printk(KERN_INFO "switch to analog");
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 1);
+ printk(KERN_INFO "analog");
+ break;
+ case 1:
+ printk(KERN_INFO "switch to digital");
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 0);
+ printk(KERN_INFO "digital");
break;
}
+ break;
}
+
return (rc);
}
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 2/15] - tm6000 add digital init for tm6010
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (7 preceding siblings ...)
2010-02-03 20:25 ` [PATCH 9/15] - tm6000 analog digital switch Stefan Ringel
@ 2010-02-03 20:27 ` Stefan Ringel
2010-02-03 20:29 ` [PATCH 11/15] - tm6000 add " Stefan Ringel
` (4 subsequent siblings)
13 siblings, 0 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:27 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -219,33 +219,53 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
int tm6000_init_digital_mode (struct tm6000_core *dev)
{
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
-
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
- msleep(50);
-
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
- msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
- msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
- msleep(100);
-
+ if (dev->dev_type == TM6010) {
+ int val;
+ u8 buf[2];
+
+ /* digital init */
+ val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, 0);
+ val &= ~0x60;
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xcc, val);
+ val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, 0);
+ val |= 0x40;
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xc0, val);
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xfe, 0x28);
+ tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe2, 0xfc);
+ tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xe6, 0xff);
+ tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0xf1, 0xfe);
+ tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
+ printk (KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
+
+
+ } else {
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x08);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00ff, 0x00);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x003f, 0x01);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00df, 0x08);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c0, 0x40);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c1, 0xd0);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00c3, 0x09);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00da, 0x37);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d1, 0xd8);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d2, 0xc0);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00d6, 0x60);
+
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e2, 0x0c);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00e8, 0xff);
+ tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
+ msleep(50);
+
+ tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ msleep(50);
+ tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
+ msleep(50);
+ tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ msleep(100);
+ }
return 0;
}
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 11/15] - tm6000 add init for tm6010
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (8 preceding siblings ...)
2010-02-03 20:27 ` [PATCH 2/15] - tm6000 add digital init for tm6010 Stefan Ringel
@ 2010-02-03 20:29 ` Stefan Ringel
2010-02-03 20:31 ` [PATCH 12/15] - tm6000 bugfix tuner reset time and tuner param Stefan Ringel
` (3 subsequent siblings)
13 siblings, 0 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:29 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -394,7 +414,15 @@ struct reg_init tm6010_init_tab[] = {
{ REQ_07_SET_GET_AVREG, 0x3f, 0x00 },
{ REQ_05_SET_GET_USBREG, 0x18, 0x00 },
-
+
+ /* additional from Terratec Cinergy Hybrid XE */
+ { REQ_07_SET_GET_AVREG, 0xdc, 0xaa },
+ { REQ_07_SET_GET_AVREG, 0xdd, 0x30 },
+ { REQ_07_SET_GET_AVREG, 0xde, 0x20 },
+ { REQ_07_SET_GET_AVREG, 0xdf, 0xd0 },
+ { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 },
+ { REQ_07_SET_GET_AVREG, 0xd8, 0x2f },
+
/* set remote wakeup key:any key wakeup */
{ REQ_07_SET_GET_AVREG, 0xe5, 0xfe },
{ REQ_07_SET_GET_AVREG, 0xda, 0xff },
@@ -404,6 +432,7 @@ int tm6000_init (struct tm6000_core *dev)
{
int board, rc=0, i, size;
struct reg_init *tab;
+ u8 buf[40];
if (dev->dev_type == TM6010) {
tab = tm6010_init_tab;
@@ -424,61 +453,129 @@ int tm6000_init (struct tm6000_core *dev)
}
}
- msleep(5); /* Just to be conservative */
-
- /* Check board version - maybe 10Moons specific */
- board=tm6000_get_reg16 (dev, 0x40, 0, 0);
- if (board >=0) {
- printk (KERN_INFO "Board version = 0x%04x\n",board);
- } else {
- printk (KERN_ERR "Error %i while retrieving board
version\n",board);
- }
-
+ /* hack */
if (dev->dev_type == TM6010) {
- /* Turn xceive 3028 on */
- tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6010_GPIO_3, 0x01);
- msleep(11);
- }
-
- /* Reset GPIO1 and GPIO4. */
- for (i=0; i< 2; i++) {
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->tuner_reset_gpio, 0x00);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
- return rc;
- }
-
- msleep(10); /* Just to be conservative */
- rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
- dev->tuner_reset_gpio, 0x01);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO1 reset\n",rc);
- return rc;
- }
-
- msleep(10);
- rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 0);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
- return rc;
- }
-
- msleep(10);
- rc=tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_4, 1);
- if (rc<0) {
- printk (KERN_ERR "Error %i doing GPIO4 reset\n",rc);
- return rc;
- }
-
- if (!i) {
- rc=tm6000_get_reg16(dev, 0x40,0,0);
- if (rc>=0) {
- printk ("board=%d\n", rc);
+
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_4, 0);
+ msleep(15);
+
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 0);
+
+ msleep(50);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 1);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x0010, 0x4400, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
+
+ msleep(15);
+ buf[0] = 0x12;
+ buf[1] = 0x34;
+ tm6000_read_write_usb (dev, 0x40, 0x10, 0xf432, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0xf432, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0x0032, 0x0000, buf, 2);
+
+ msleep(15);
+ buf[0] = 0x00;
+ buf[1] = 0x01;
+ tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0x00c0, 0x0000, buf, 39);
+
+ msleep(15);
+ buf[0] = 0x00;
+ buf[1] = 0x00;
+ tm6000_read_write_usb (dev, 0x40, 0x10, 0xf332, 0x0000, buf, 2);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x10, 0x7f1f, 0x0000, buf, 2);
+// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf [1]);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_4, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_0, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_7, 0);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_5, 1);
+
+ msleep(15);
+
+ for (i=0; i< size; i++) {
+ rc= tm6000_set_reg (dev, tab[i].req, tab[i].reg, tab[i].val);
+ if (rc<0) {
+ printk (KERN_ERR "Error %i while setting req %d, "
+ "reg %d to value %d\n", rc,
+ tab[i].req,tab[i].reg, tab[i].val);
+ return rc;
}
}
+
+ msleep(15);
+
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_4, 0);
+ msleep(15);
+
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 0);
+
+ msleep(50);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_1, 1);
+
+ msleep(15);
+ tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
+// printk(KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 0);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 0);
+ msleep(15);
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ TM6010_GPIO_2, 1);
+ msleep(15);
}
+ /* hack end */
+
+ msleep(5); /* Just to be conservative */
+ /* Check board version - maybe 10Moons specific */
+ if (dev->dev_type == TM5600) {
+ board=tm6000_get_reg16 (dev, 0x40, 0, 0);
+ if (board >=0) {
+ printk (KERN_INFO "Board version = 0x%04x\n",board);
+ } else {
+ printk (KERN_ERR "Error %i while retrieving board
version\n",board);
+ }
+ }
+
msleep(50);
return 0;
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 12/15] - tm6000 bugfix tuner reset time and tuner param
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (9 preceding siblings ...)
2010-02-03 20:29 ` [PATCH 11/15] - tm6000 add " Stefan Ringel
@ 2010-02-03 20:31 ` Stefan Ringel
2010-02-03 20:52 ` Devin Heitmueller
2010-02-03 20:36 ` [PATCH 13/15] - xc2028 bugfix for firmware 3.6 -> Zarlink use without shift in DTV8 or DTV78 Stefan Ringel
` (2 subsequent siblings)
13 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:31 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -221,12 +239,13 @@ struct usb_device_id tm6000_id_table [] = {
{ USB_DEVICE(0x2040, 0x6600), .driver_info =
TM6010_BOARD_HAUPPAUGE_900H },
{ USB_DEVICE(0x6000, 0xdec0), .driver_info =
TM6010_BOARD_BEHOLD_WANDER },
{ USB_DEVICE(0x6000, 0xdec1), .driver_info =
TM6010_BOARD_BEHOLD_VOYAGER },
{ USB_DEVICE(0x0ccd, 0x0086), .driver_info =
TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
{ },
};
/* Tuner callback to provide the proper gpio changes needed for xc2028 */
-static int tm6000_tuner_callback(void *ptr, int component, int command,
int arg)
+int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
{
int rc=0;
struct tm6000_core *dev = ptr;
@@ -252,11 +271,14 @@ static int tm6000_tuner_callback(void *ptr, int
component, int command, int arg)
switch (arg) {
case 0:
tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
+ dev->tuner_reset_gpio, 0x01);
+ msleep(60);
+ tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
dev->tuner_reset_gpio, 0x00);
- msleep(130);
+ msleep(75);
tm6000_set_reg (dev, REQ_03_SET_GET_MCU_PIN,
dev->tuner_reset_gpio, 0x01);
- msleep(130);
+ msleep(60);
break;
case 1:
tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT,
@@ -290,7 +332,7 @@ static void tm6000_config_tuner (struct tm6000_core
*dev)
memset(&tun_setup, 0, sizeof(tun_setup));
tun_setup.type = dev->tuner_type;
tun_setup.addr = dev->tuner_addr;
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+ tun_setup.mode_mask = T_ANALOG_TV | T_RADIO | T_DIGITAL_TV;
tun_setup.tuner_callback = tm6000_tuner_callback;
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr,
&tun_setup);
@@ -302,15 +344,19 @@ static void tm6000_config_tuner (struct
tm6000_core *dev)
memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
memset (&ctl,0,sizeof(ctl));
- ctl.mts = 1;
- ctl.read_not_reliable = 1;
+ ctl.input1 = 1;
+ ctl.read_not_reliable = 0;
ctl.msleep = 10;
-
+ ctl.demod = XC3028_FE_ZARLINK456;
+ ctl.vhfbw7 = 1;
+ ctl.uhfbw8 = 1;
+ ctl.switch_mode = 1;
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
switch(dev->model) {
case TM6010_BOARD_HAUPPAUGE_900H:
+ case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE:
ctl.fname = "xc3028L-v36.fw";
break;
default:
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 13/15] - xc2028 bugfix for firmware 3.6 -> Zarlink use without shift in DTV8 or DTV78
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (10 preceding siblings ...)
2010-02-03 20:31 ` [PATCH 12/15] - tm6000 bugfix tuner reset time and tuner param Stefan Ringel
@ 2010-02-03 20:36 ` Stefan Ringel
2010-02-03 20:45 ` Devin Heitmueller
2010-02-03 20:38 ` [PATCH 14/15] - zl10353 Stefan Ringel
2010-02-03 20:40 ` [PATCH 15/15] - tm6000 hack with different demodulator parameter Stefan Ringel
13 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:36 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -1114,7 +1122,11 @@ static int xc2028_set_params(struct dvb_frontend *fe,
/* All S-code tables need a 200kHz shift */
if (priv->ctrl.demod) {
- demod = priv->ctrl.demod + 200;
+ if ((priv->ctrl.fname == "xc3028L-v36.fw") && (priv->ctrl.demod
== XC3028_FE_ZARLINK456) && ((type & DTV78) | (type & DTV8)) ) {
+ demod = priv->ctrl.demod;
+ } else {
+ demod = priv->ctrl.demod + 200;
+ }
/*
* The DTV7 S-code table needs a 700 kHz shift.
* Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
@@ -1123,8 +1135,8 @@ static int xc2028_set_params(struct dvb_frontend *fe,
* use this firmware after initialization, but a tune to a UHF
* channel should then cause DTV78 to be used.
*/
- if (type & DTV7)
- demod += 500;
+ if (type & DTV7)
+ demod += 500;
}
return generic_set_freq(fe, p->frequency,
@@ -1240,6 +1252,10 @@ static const struct dvb_tuner_ops
xc2028_dvb_tuner_ops = {
.get_rf_strength = xc2028_signal,
.set_params = xc2028_set_params,
.sleep = xc2028_sleep,
+#if 0
+ int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
+ int (*get_status)(struct dvb_frontend *fe, u32 *status);
+#endif
};
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 14/15] - zl10353
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (11 preceding siblings ...)
2010-02-03 20:36 ` [PATCH 13/15] - xc2028 bugfix for firmware 3.6 -> Zarlink use without shift in DTV8 or DTV78 Stefan Ringel
@ 2010-02-03 20:38 ` Stefan Ringel
2010-02-03 20:49 ` Devin Heitmueller
2010-02-03 20:40 ` [PATCH 15/15] - tm6000 hack with different demodulator parameter Stefan Ringel
13 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:38 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -45,6 +45,8 @@ struct zl10353_config
/* clock control registers (0x51-0x54) */
u8 clock_ctl_1; /* default: 0x46 */
u8 pll_0; /* default: 0x15 */
+
+ int tm6000:1;
};
#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 9/15] - tm6000 analog digital switch
2010-02-03 20:25 ` [PATCH 9/15] - tm6000 analog digital switch Stefan Ringel
@ 2010-02-03 20:40 ` Mauro Carvalho Chehab
2010-02-03 20:55 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-03 20:40 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
Stefan Ringel wrote:
> @@ -994,6 +995,13 @@ static int generic_set_freq(struct dvb_frontend
> *fe, u32 freq /* in HZ */,
Your emailer is damaging the patches. The above should be in the same line,
otherwise the patch won't apply.
It seems that you're using Thunderbird, right?
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.1.5) Gecko/20091130 SUSE/3.0.0-1.1.1 Thunderbird/3.0
You should really read the README.patches (http://linuxtv.org/hg/v4l-dvb/raw-file/tip/README.patches)
before submitting your work. In particular, at the end of Part II, there are the procedures for
submissions via email. It ends with:
" BE CAREFUL: several emailers including Thunderdird breaks long lines, causing
patch corruption.
In the specific case of Thunderbird, an extension is needed to send the
patches, called Asalted Patches:
https://hg.mozilla.org/users/clarkbw_gnome.org/asalted-patches/"
So, please get the asalted-patches extension, apply it on your Thunderbird, review your patch
series based on the contents of README.patches and re-submit.
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* [PATCH 15/15] - tm6000 hack with different demodulator parameter
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
` (12 preceding siblings ...)
2010-02-03 20:38 ` [PATCH 14/15] - zl10353 Stefan Ringel
@ 2010-02-03 20:40 ` Stefan Ringel
2010-02-03 20:47 ` Devin Heitmueller
13 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:40 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/hack.c
+++ b/drivers/staging/tm6000/hack.c
@@ -37,7 +37,6 @@ static inline int tm6000_snd_control_msg(struct
tm6000_core *dev, __u8 request,
static int pseudo_zl10353_pll(struct tm6000_core *tm6000_dev, struct
dvb_frontend_parameters *p)
{
- int ret;
u8 *data = kzalloc(50*sizeof(u8), GFP_KERNEL);
printk(KERN_ALERT "should set frequency %u\n", p->frequency);
@@ -51,7 +50,7 @@ printk(KERN_ALERT "and bandwith %u\n",
p->u.ofdm.bandwidth);
}
// init ZL10353
- data[0] = 0x0b;
+/* data[0] = 0x0b;
ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x501e, 0x00, data,
0x1);
msleep(15);
data[0] = 0x80;
@@ -159,7 +158,7 @@ printk(KERN_ALERT "and bandwith %u\n",
p->u.ofdm.bandwidth);
msleep(15);
data[0] = 0x5a;
ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x651e,
0x00, data, 0x1);
- msleep(15);
+ msleep(15)
data[0] = 0xe9;
ret = tm6000_snd_control_msg(tm6000_dev, 0x10, 0x661e,
0x00, data, 0x1);
msleep(15);
@@ -189,7 +188,162 @@ printk(KERN_ALERT "and bandwith %u\n",
p->u.ofdm.bandwidth);
msleep(15);
break;
}
-
+*/
+ switch(p->u.ofdm.bandwidth) {
+ case BANDWIDTH_8_MHZ:
+ data[0] = 0x03;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
+ msleep(40);
+ data[0] = 0x44;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x46;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
+ msleep(40);
+ data[0] = 0x15;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
+ msleep(40);
+ data[0] = 0x0f;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
+ msleep(40);
+ data[0] = 0x80;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x00;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x8b;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
+ msleep(40);
+ data[0] = 0x75;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
+ msleep(40);
+ data[0] = 0xe6; //0x19;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x09; //0xf7;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
+ msleep(40);
+ data[0] = 0x67;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
+ msleep(40);
+ data[0] = 0xe5;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
+ msleep(40);
+ data[0] = 0x75;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x17;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
+ msleep(40);
+ break;
+ case BANDWIDTH_7_MHZ:
+ data[0] = 0x03;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x501e,0,data,1);
+ msleep(40);
+ data[0] = 0x44;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x511e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x46;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x521e,0,data,1);
+ msleep(40);
+ data[0] = 0x15;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x531e,0,data,1);
+ msleep(40);
+ data[0] = 0x0f;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x541e,0,data,1);
+ msleep(40);
+ data[0] = 0x80;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x551e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x00;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xea1e,0,data,1);
+ msleep(40);
+ data[0] = 0x83;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x631e,0,data,1);
+ msleep(40);
+ data[0] = 0xa3;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0xcc1e,0,data,1);
+ msleep(40);
+ data[0] = 0xe6; //0x19;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x09; //0xf7;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x6d1e,0,data,1);
+ msleep(40);
+ data[0] = 0x5a;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x651e,0,data,1);
+ msleep(40);
+ data[0] = 0xe9;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x661e,0,data,1);
+ msleep(40);
+ data[0] = 0x86;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5c1e,0,data,1);
+ msleep(40);
+ data[0] = 0x17;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5f1e,0,data,1);
+ msleep(40);
+ data[0] = 0x40;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x5e1e,0,data,1);
+ msleep(40);
+ data[0] = 0x01;
+ tm6000_read_write_usb(tm6000_dev,0x40,0x10,0x701e,0,data,1);
+ msleep(40);
+ break;
+ default:
+ printk(KERN_ALERT "tm6000: bandwidth not supported\n");
+ }
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x051f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0f1f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x091f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
+ tm6000_read_write_usb(tm6000_dev,0xc0,0x10,0x0b1f,0,data,2);
+ printk(KERN_INFO "buf %#x %#x \n", data[0], data[1]);
+ msleep(40);
+
kfree(data);
return 0;
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 13/15] - xc2028 bugfix for firmware 3.6 -> Zarlink use without shift in DTV8 or DTV78
2010-02-03 20:36 ` [PATCH 13/15] - xc2028 bugfix for firmware 3.6 -> Zarlink use without shift in DTV8 or DTV78 Stefan Ringel
@ 2010-02-03 20:45 ` Devin Heitmueller
0 siblings, 0 replies; 55+ messages in thread
From: Devin Heitmueller @ 2010-02-03 20:45 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Mauro Carvalho Chehab, linux-media
On Wed, Feb 3, 2010 at 3:36 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
> --- a/drivers/media/common/tuners/tuner-xc2028.c
> +++ b/drivers/media/common/tuners/tuner-xc2028.c
> @@ -1114,7 +1122,11 @@ static int xc2028_set_params(struct dvb_frontend *fe,
>
> /* All S-code tables need a 200kHz shift */
> if (priv->ctrl.demod) {
> - demod = priv->ctrl.demod + 200;
> + if ((priv->ctrl.fname == "xc3028L-v36.fw") && (priv->ctrl.demod
> == XC3028_FE_ZARLINK456) && ((type & DTV78) | (type & DTV8)) ) {
> + demod = priv->ctrl.demod;
> + } else {
> + demod = priv->ctrl.demod + 200;
> + }
> /*
> * The DTV7 S-code table needs a 700 kHz shift.
> * Thanks to Terry Wu <terrywu2009@gmail.com> for reporting this
> @@ -1123,8 +1135,8 @@ static int xc2028_set_params(struct dvb_frontend *fe,
> * use this firmware after initialization, but a tune to a UHF
> * channel should then cause DTV78 to be used.
> */
> - if (type & DTV7)
> - demod += 500;
> + if (type & DTV7)
> + demod += 500;
> }
Independent of the validity of this patch, you should not be
submitting patches that have a mix of whitespace changes and actual
changes. In the above case (the if type & DTV7 part), it looks like
these shouldn't have been included at all since it makes no functional
change.
It sounds like a nit-pick, but the reality is that its inclusion had
me staring at it for 30 seconds trying to figure out whether there was
an *actual* difference there or if it was purely whitespace.
>
> return generic_set_freq(fe, p->frequency,
> @@ -1240,6 +1252,10 @@ static const struct dvb_tuner_ops
> xc2028_dvb_tuner_ops = {
> .get_rf_strength = xc2028_signal,
> .set_params = xc2028_set_params,
> .sleep = xc2028_sleep,
> +#if 0
> + int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
> + int (*get_status)(struct dvb_frontend *fe, u32 *status);
> +#endif
> };
Likewise, you should not be including unrelated changes in patches -
the above "#if 0" section not only is never compiled in to the code
(presumably it is debug code), but it has nothing to do with the fix
this patch is claiming to address.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 15/15] - tm6000 hack with different demodulator parameter
2010-02-03 20:40 ` [PATCH 15/15] - tm6000 hack with different demodulator parameter Stefan Ringel
@ 2010-02-03 20:47 ` Devin Heitmueller
0 siblings, 0 replies; 55+ messages in thread
From: Devin Heitmueller @ 2010-02-03 20:47 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Mauro Carvalho Chehab, linux-media
On Wed, Feb 3, 2010 at 3:40 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>
> --- a/drivers/staging/tm6000/hack.c
> +++ b/drivers/staging/tm6000/hack.c
<snip>
This patch shouldn't be merged at all. You should figure out the
correct zl10353_config that is required, and hold off on submission
until you have the correct fix.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 14/15] - zl10353
2010-02-03 20:38 ` [PATCH 14/15] - zl10353 Stefan Ringel
@ 2010-02-03 20:49 ` Devin Heitmueller
2010-02-03 21:07 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Devin Heitmueller @ 2010-02-03 20:49 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Mauro Carvalho Chehab, linux-media
On Wed, Feb 3, 2010 at 3:38 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>
> --- a/drivers/media/dvb/frontends/zl10353.h
> +++ b/drivers/media/dvb/frontends/zl10353.h
> @@ -45,6 +45,8 @@ struct zl10353_config
> /* clock control registers (0x51-0x54) */
> u8 clock_ctl_1; /* default: 0x46 */
> u8 pll_0; /* default: 0x15 */
> +
> + int tm6000:1;
> };
Why is this being submitted as its own patch? It is code that is not
used by *anything*. If you really did require a new field in the
zl10353 config, that field should be added in the same patch as
whatever requires it.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 4/15] - tm6000.h
2010-02-03 20:25 ` Mauro Carvalho Chehab
@ 2010-02-03 20:50 ` Stefan Ringel
2010-02-03 20:58 ` Devin Heitmueller
2010-02-03 21:31 ` Mauro Carvalho Chehab
0 siblings, 2 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:50 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
Am 03.02.2010 21:25, schrieb Mauro Carvalho Chehab:
> This one is a very obscure patch. What are you doing this patch and why?
>
> Stefan Ringel wrote:
>
>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>
>> --- a/drivers/staging/tm6000/tm6000.h
>> +++ b/drivers/staging/tm6000/tm6000.h
>> @@ -90,12 +97,14 @@ enum tm6000_core_state {
>> DEV_MISCONFIGURED = 0x04,
>> };
>>
>> +#if 1
>> /* io methods */
>> enum tm6000_io_method {
>> IO_NONE,
>> IO_READ,
>> IO_MMAP,
>> };
>> +#endif
>>
>>
? different between git and hg ? not mine
>> enum tm6000_mode {
>> TM6000_MODE_UNKNOWN=0,
>> @@ -202,6 +211,9 @@ struct tm6000_fh {
>> V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
>> V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM
>>
>> +/* In tm6000-cards.c */
>> +
>> +int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
>> /* In tm6000-core.c */
>>
>>
I use that for tuner callback in tm6000-dvb --> frontend structure
>> int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
>> @@ -209,7 +221,6 @@ int tm6000_read_write_usb (struct tm6000_core *dev,
>> u8 reqtype, u8 req,
>> int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
>> int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
>> int tm6000_init (struct tm6000_core *dev);
>> -int tm6000_init_after_firmware (struct tm6000_core *dev);
>>
>> int tm6000_init_analog_mode (struct tm6000_core *dev);
>> int tm6000_init_digital_mode (struct tm6000_core *dev);
>> @@ -231,7 +242,12 @@ int tm6000_set_standard (struct tm6000_core *dev,
>> v4l2_std_id *norm);
>> int tm6000_i2c_register(struct tm6000_core *dev);
>> int tm6000_i2c_unregister(struct tm6000_core *dev);
>>
>> +#if 1
>> /* In tm6000-queue.c */
>> +#if 0
>> +int tm6000_init_isoc(struct tm6000_core *dev, int max_packets);
>> +void tm6000_uninit_isoc(struct tm6000_core *dev);
>> +#endif
>>
>>
? different between git and hg ? not mine
>> int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
>>
>> @@ -276,3 +292,4 @@ extern int tm6000_debug;
>> __FUNCTION__ , ##arg); } while (0)
>>
>>
>> +#endif
>>
>>
>
>
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 12/15] - tm6000 bugfix tuner reset time and tuner param
2010-02-03 20:31 ` [PATCH 12/15] - tm6000 bugfix tuner reset time and tuner param Stefan Ringel
@ 2010-02-03 20:52 ` Devin Heitmueller
2010-02-03 21:15 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Devin Heitmueller @ 2010-02-03 20:52 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Mauro Carvalho Chehab, linux-media
On Wed, Feb 3, 2010 at 3:31 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>
> --- a/drivers/staging/tm6000/tm6000-cards.c
> +++ b/drivers/staging/tm6000/tm6000-cards.c
> @@ -221,12 +239,13 @@ struct usb_device_id tm6000_id_table [] = {
> { USB_DEVICE(0x2040, 0x6600), .driver_info =
> TM6010_BOARD_HAUPPAUGE_900H },
> { USB_DEVICE(0x6000, 0xdec0), .driver_info =
> TM6010_BOARD_BEHOLD_WANDER },
> { USB_DEVICE(0x6000, 0xdec1), .driver_info =
> TM6010_BOARD_BEHOLD_VOYAGER },
> { USB_DEVICE(0x0ccd, 0x0086), .driver_info =
> TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
> { },
> };
>
> /* Tuner callback to provide the proper gpio changes needed for xc2028 */
>
> -static int tm6000_tuner_callback(void *ptr, int component, int command,
> int arg)
> +int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
> {
Why was the static removed from this declaration? What could possibly
be calling this from outside the module? And if there were something
that needed it, the declaration would have to be moved to a header
file so it could be included elsewhere (which should be in this same
patch).
Just to be clear, the fact that I am going through these patches
should not be taken personally - I'm just trying to give you some
advice on what you need to do to ensure the patches can be accepted
upstream and be reviewed with minimal cost to the other developers.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 9/15] - tm6000 analog digital switch
2010-02-03 20:40 ` Mauro Carvalho Chehab
@ 2010-02-03 20:55 ` Stefan Ringel
2010-02-03 21:21 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 20:55 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
Am 03.02.2010 21:40, schrieb Mauro Carvalho Chehab:
> Stefan Ringel wrote:
>
>
>> @@ -994,6 +995,13 @@ static int generic_set_freq(struct dvb_frontend
>> *fe, u32 freq /* in HZ */,
>>
> Your emailer is damaging the patches. The above should be in the same line,
> otherwise the patch won't apply.
>
> It seems that you're using Thunderbird, right?
>
> User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.1.5) Gecko/20091130 SUSE/3.0.0-1.1.1 Thunderbird/3.0
>
> You should really read the README.patches (http://linuxtv.org/hg/v4l-dvb/raw-file/tip/README.patches)
> before submitting your work. In particular, at the end of Part II, there are the procedures for
> submissions via email. It ends with:
>
> " BE CAREFUL: several emailers including Thunderdird breaks long lines, causing
> patch corruption.
> In the specific case of Thunderbird, an extension is needed to send the
> patches, called Asalted Patches:
> https://hg.mozilla.org/users/clarkbw_gnome.org/asalted-patches/"
>
> So, please get the asalted-patches extension, apply it on your Thunderbird, review your patch
> series based on the contents of README.patches and re-submit.
>
>
I use thunderbird 3, but the patch is for 2. It that compatible ?
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 4/15] - tm6000.h
2010-02-03 20:50 ` Stefan Ringel
@ 2010-02-03 20:58 ` Devin Heitmueller
2010-02-03 21:31 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 55+ messages in thread
From: Devin Heitmueller @ 2010-02-03 20:58 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Mauro Carvalho Chehab, linux-media
On Wed, Feb 3, 2010 at 3:50 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
> Am 03.02.2010 21:25, schrieb Mauro Carvalho Chehab:
>> This one is a very obscure patch. What are you doing this patch and why?
>>
>> Stefan Ringel wrote:
>>
>>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>>
>>> --- a/drivers/staging/tm6000/tm6000.h
>>> +++ b/drivers/staging/tm6000/tm6000.h
>>> @@ -90,12 +97,14 @@ enum tm6000_core_state {
>>> DEV_MISCONFIGURED = 0x04,
>>> };
>>>
>>> +#if 1
>>> /* io methods */
>>> enum tm6000_io_method {
>>> IO_NONE,
>>> IO_READ,
>>> IO_MMAP,
>>> };
>>> +#endif
>>>
>>>
> ? different between git and hg ? not mine
Stefan,
The patches *you submitted* included this "#if 1". Regardless of
whether it's differences between git and hg or some other weird merge
bug, you are responsible for the patches you submit. You should be
reviewing each patch before sending it, and if it contains things you
do not understand why they are there, then you need to resolve those
inconsistencies before submitting the patch.
Reviewing each patch individually before sending also helps avoid
avoid things like submitting patches which make arbitrary/unnecessary
whitespace changes.
Devin
--
Devin J. Heitmueller - Kernel Labs
http://www.kernellabs.com
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 14/15] - zl10353
2010-02-03 20:49 ` Devin Heitmueller
@ 2010-02-03 21:07 ` Stefan Ringel
2010-02-04 2:43 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 21:07 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: Mauro Carvalho Chehab, linux-media
Am 03.02.2010 21:49, schrieb Devin Heitmueller:
> On Wed, Feb 3, 2010 at 3:38 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>
>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>
>> --- a/drivers/media/dvb/frontends/zl10353.h
>> +++ b/drivers/media/dvb/frontends/zl10353.h
>> @@ -45,6 +45,8 @@ struct zl10353_config
>> /* clock control registers (0x51-0x54) */
>> u8 clock_ctl_1; /* default: 0x46 */
>> u8 pll_0; /* default: 0x15 */
>> +
>> + int tm6000:1;
>> };
>>
> Why is this being submitted as its own patch? It is code that is not
> used by *anything*. If you really did require a new field in the
> zl10353 config, that field should be added in the same patch as
> whatever requires it.
>
> Devin
>
>
Actually doesn't work zl10353 with tm6010, it have a little different
between a few registers, so I think that I use it.
for example:
zl10353 use 0x64 , but not mine (0x63)
register 0x5f is 0x17 not 0x13
register 0x5e is 0x40 not 0x00 for auto
and tuner go is 0x70 not 0x71
the other register are ok. I have no idea how I can set it.
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 12/15] - tm6000 bugfix tuner reset time and tuner param
2010-02-03 20:52 ` Devin Heitmueller
@ 2010-02-03 21:15 ` Stefan Ringel
0 siblings, 0 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 21:15 UTC (permalink / raw)
To: Devin Heitmueller; +Cc: Mauro Carvalho Chehab, linux-media
Am 03.02.2010 21:52, schrieb Devin Heitmueller:
> On Wed, Feb 3, 2010 at 3:31 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>
>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>
>> --- a/drivers/staging/tm6000/tm6000-cards.c
>> +++ b/drivers/staging/tm6000/tm6000-cards.c
>> @@ -221,12 +239,13 @@ struct usb_device_id tm6000_id_table [] = {
>> { USB_DEVICE(0x2040, 0x6600), .driver_info =
>> TM6010_BOARD_HAUPPAUGE_900H },
>> { USB_DEVICE(0x6000, 0xdec0), .driver_info =
>> TM6010_BOARD_BEHOLD_WANDER },
>> { USB_DEVICE(0x6000, 0xdec1), .driver_info =
>> TM6010_BOARD_BEHOLD_VOYAGER },
>> { USB_DEVICE(0x0ccd, 0x0086), .driver_info =
>> TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
>> { },
>> };
>>
>> /* Tuner callback to provide the proper gpio changes needed for xc2028 */
>>
>> -static int tm6000_tuner_callback(void *ptr, int component, int command,
>> int arg)
>> +int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
>> {
>>
> Why was the static removed from this declaration? What could possibly
> be calling this from outside the module? And if there were something
> that needed it, the declaration would have to be moved to a header
> file so it could be included elsewhere (which should be in this same
> patch).
>
> Just to be clear, the fact that I am going through these patches
> should not be taken personally - I'm just trying to give you some
> advice on what you need to do to ensure the patches can be accepted
> upstream and be reviewed with minimal cost to the other developers.
>
> Devin
>
>
1. It broke by building.
2. callback for dvb frontend (tm6000-dvb.c) so can the tuner a reset
send if it goes in DVB mode (it must reload the firmware)
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 9/15] - tm6000 analog digital switch
2010-02-03 20:55 ` Stefan Ringel
@ 2010-02-03 21:21 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-03 21:21 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
Stefan Ringel wrote:
> Am 03.02.2010 21:40, schrieb Mauro Carvalho Chehab:
>> So, please get the asalted-patches extension, apply it on your Thunderbird, review your patch
>> series based on the contents of README.patches and re-submit.
>>
>>
> I use thunderbird 3, but the patch is for 2. It that compatible ?
Yes. I have it applied to Fedora 12 thunderbird 3, and to RHEL5 thunderbird 2. It works
fine on both.
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 4/15] - tm6000.h
2010-02-03 20:50 ` Stefan Ringel
2010-02-03 20:58 ` Devin Heitmueller
@ 2010-02-03 21:31 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-03 21:31 UTC (permalink / raw)
To: Stefan Ringel; +Cc: linux-media, Devin Heitmueller
Stefan Ringel wrote:
> Am 03.02.2010 21:25, schrieb Mauro Carvalho Chehab:
>> This one is a very obscure patch. What are you doing this patch and why?
>>
>> Stefan Ringel wrote:
>>
>>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>>
>>> --- a/drivers/staging/tm6000/tm6000.h
>>> +++ b/drivers/staging/tm6000/tm6000.h
>>> @@ -90,12 +97,14 @@ enum tm6000_core_state {
>>> DEV_MISCONFIGURED = 0x04,
>>> };
>>>
>>> +#if 1
>>> /* io methods */
>>> enum tm6000_io_method {
>>> IO_NONE,
>>> IO_READ,
>>> IO_MMAP,
>>> };
>>> +#endif
>>>
>>>
> ? different between git and hg ? not mine
On git, all #if 0/#if 1 are stripped (except if an explicit comment /* keep */
is added). We do this way to avoid polluting upstream kernel code with temporary
developers only code.
>>> enum tm6000_mode {
>>> TM6000_MODE_UNKNOWN=0,
>>> @@ -202,6 +211,9 @@ struct tm6000_fh {
>>> V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \
>>> V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM
>>>
>>> +/* In tm6000-cards.c */
>>> +
>>> +int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
>>> /* In tm6000-core.c */
>>>
>>>
> I use that for tuner callback in tm6000-dvb --> frontend structure
>>> int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
>>> @@ -209,7 +221,6 @@ int tm6000_read_write_usb (struct tm6000_core *dev,
>>> u8 reqtype, u8 req,
>>> int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
>>> int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
>>> int tm6000_init (struct tm6000_core *dev);
>>> -int tm6000_init_after_firmware (struct tm6000_core *dev);
>>>
>>> int tm6000_init_analog_mode (struct tm6000_core *dev);
>>> int tm6000_init_digital_mode (struct tm6000_core *dev);
>>> @@ -231,7 +242,12 @@ int tm6000_set_standard (struct tm6000_core *dev,
>>> v4l2_std_id *norm);
>>> int tm6000_i2c_register(struct tm6000_core *dev);
>>> int tm6000_i2c_unregister(struct tm6000_core *dev);
>>>
>>> +#if 1
>>> /* In tm6000-queue.c */
>>> +#if 0
>>> +int tm6000_init_isoc(struct tm6000_core *dev, int max_packets);
>>> +void tm6000_uninit_isoc(struct tm6000_core *dev);
>>> +#endif
>>>
>>>
> ? different between git and hg ? not mine
>>> int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma);
>>>
>>> @@ -276,3 +292,4 @@ extern int tm6000_debug;
>>> __FUNCTION__ , ##arg); } while (0)
>>>
>>>
>>> +#endif
>>>
>>>
>>
>
>
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 1/15] - tm6000 build hunk
2010-02-03 20:10 ` [PATCH 1/15] - tm6000 build hunk Stefan Ringel
` (2 preceding siblings ...)
2010-02-03 20:17 ` Devin Heitmueller
@ 2010-02-03 21:48 ` Stefan Ringel
3 siblings, 0 replies; 55+ messages in thread
From: Stefan Ringel @ 2010-02-03 21:48 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: linux-media, Devin Heitmueller
Signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -32,7 +32,7 @@
#include "tm6000.h"
#include "tm6000-regs.h"
#include "tuner-xc2028.h"
-#include "tuner-xc5000.h"
+#include "xc5000.h"
#define TM6000_BOARD_UNKNOWN 0
#define TM5600_BOARD_GENERIC 1
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 14/15] - zl10353
2010-02-03 21:07 ` Stefan Ringel
@ 2010-02-04 2:43 ` Mauro Carvalho Chehab
2010-02-04 21:12 ` Stefan Ringel
0 siblings, 1 reply; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-04 2:43 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Devin Heitmueller, linux-media
Stefan Ringel wrote:
> Am 03.02.2010 21:49, schrieb Devin Heitmueller:
>> On Wed, Feb 3, 2010 at 3:38 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>>
>>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>>
>>> --- a/drivers/media/dvb/frontends/zl10353.h
>>> +++ b/drivers/media/dvb/frontends/zl10353.h
>>> @@ -45,6 +45,8 @@ struct zl10353_config
>>> /* clock control registers (0x51-0x54) */
>>> u8 clock_ctl_1; /* default: 0x46 */
>>> u8 pll_0; /* default: 0x15 */
>>> +
>>> + int tm6000:1;
>>> };
>>>
>> Why is this being submitted as its own patch? It is code that is not
>> used by *anything*. If you really did require a new field in the
>> zl10353 config, that field should be added in the same patch as
>> whatever requires it.
>>
>> Devin
>>
>>
Hi Stefan,
Due to the problem with your emailer, most of the patches failed:
2/15 3/15 4/15 5/15 6/15 7/15 2/15 (the second one 8th in the sequence)
9/15 11/15 12/15 13/15 and 15/15.
In brief, only two patches applied: the 1/15 and a patch also called 2/15
(I suspect it is the 10th patch).
So, after reading our comments, reading README.patches and applying the
Asaulted-patches extension to your thunderbird, please resubmit the patches.
> Actually doesn't work zl10353 with tm6010, it have a little different
> between a few registers, so I think that I use it.
>
> for example:
> zl10353 use 0x64 , but not mine (0x63)
> register 0x5f is 0x17 not 0x13
> register 0x5e is 0x40 not 0x00 for auto
> and tuner go is 0x70 not 0x71
>
> the other register are ok. I have no idea how I can set it.
I agree with Devin that the patch 14/15 shouldn't be applied as-is.
I have no idea why zl10353 needs a different setup, but you don't need
to add an extra parameter to identify the bridge driver. There's a field
at struct i2c_client that can be used: i2c_adapter->id.
This is already initialized with I2C_HW_B_TM6000 (although it currently
uses a fake value).
It is still ugly to do some specific initialization like this, but, when
we have no other glue, due to the lack of datasheets, this is a better
alternative than adding an extra fake parameter at the config struct.
All you need is some code like:
diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c
--- a/linux/drivers/media/dvb/frontends/zl10353.c
+++ b/linux/drivers/media/dvb/frontends/zl10353.c
@@ -597,6 +597,10 @@ static int zl10353_init(struct dvb_front
zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) {
rc = zl10353_write(fe, zl10353_reset_attach,
sizeof(zl10353_reset_attach));
+
+ if (state->i2c->id == I2C_HW_B_TM6000) {
+ /* Do special init needed by tm6000 driver */
+ }
#if 1
if (debug_regs)
zl10353_dump_regs(fe);
diff --git a/linux/drivers/staging/tm6000/tm6000-i2c.c b/linux/drivers/staging/tm6000/tm6000-i2c.c
--- a/linux/drivers/staging/tm6000/tm6000-i2c.c
+++ b/linux/drivers/staging/tm6000/tm6000-i2c.c
@@ -33,8 +33,6 @@
#include "tuner-xc2028.h"
-/*FIXME: Hack to avoid needing to patch i2c-id.h */
-#define I2C_HW_B_TM6000 I2C_HW_B_EM28XX
/* ----------------------------------------------------------- */
static unsigned int i2c_debug = 0;
diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h
--- a/linux/include/linux/i2c-id.h
+++ b/linux/include/linux/i2c-id.h
@@ -42,6 +42,7 @@
#define I2C_HW_B_AU0828 0x010023 /* auvitek au0828 usb bridge */
#define I2C_HW_B_CX231XX 0x010024 /* Conexant CX231XX USB based cards */
#define I2C_HW_B_HDPVR 0x010025 /* Hauppauge HD PVR */
+#define I2C_HW_B_TM6000 0x010026 /* TM5600/6000/6010 video bridge */
/* --- SGI adapters */
#define I2C_HW_SGI_VINO 0x160000
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 14/15] - zl10353
2010-02-04 2:43 ` Mauro Carvalho Chehab
@ 2010-02-04 21:12 ` Stefan Ringel
2010-02-05 0:06 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 55+ messages in thread
From: Stefan Ringel @ 2010-02-04 21:12 UTC (permalink / raw)
To: Mauro Carvalho Chehab; +Cc: Devin Heitmueller, linux-media
Am 04.02.2010 03:43, schrieb Mauro Carvalho Chehab:
> Stefan Ringel wrote:
>
>> Am 03.02.2010 21:49, schrieb Devin Heitmueller:
>>
>>> On Wed, Feb 3, 2010 at 3:38 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>>>
>>>
>>>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>>>
>>>> --- a/drivers/media/dvb/frontends/zl10353.h
>>>> +++ b/drivers/media/dvb/frontends/zl10353.h
>>>> @@ -45,6 +45,8 @@ struct zl10353_config
>>>> /* clock control registers (0x51-0x54) */
>>>> u8 clock_ctl_1; /* default: 0x46 */
>>>> u8 pll_0; /* default: 0x15 */
>>>> +
>>>> + int tm6000:1;
>>>> };
>>>>
>>>>
>>> Why is this being submitted as its own patch? It is code that is not
>>> used by *anything*. If you really did require a new field in the
>>> zl10353 config, that field should be added in the same patch as
>>> whatever requires it.
>>>
>>> Devin
>>>
>>>
>>>
> Hi Stefan,
>
> Due to the problem with your emailer, most of the patches failed:
>
> 2/15 3/15 4/15 5/15 6/15 7/15 2/15 (the second one 8th in the sequence)
> 9/15 11/15 12/15 13/15 and 15/15.
>
> In brief, only two patches applied: the 1/15 and a patch also called 2/15
> (I suspect it is the 10th patch).
>
> So, after reading our comments, reading README.patches and applying the
> Asaulted-patches extension to your thunderbird, please resubmit the patches.
>
>
>> Actually doesn't work zl10353 with tm6010, it have a little different
>> between a few registers, so I think that I use it.
>>
>> for example:
>> zl10353 use 0x64 , but not mine (0x63)
>> register 0x5f is 0x17 not 0x13
>> register 0x5e is 0x40 not 0x00 for auto
>> and tuner go is 0x70 not 0x71
>>
>> the other register are ok. I have no idea how I can set it.
>>
> I agree with Devin that the patch 14/15 shouldn't be applied as-is.
>
> I have no idea why zl10353 needs a different setup, but you don't need
> to add an extra parameter to identify the bridge driver. There's a field
> at struct i2c_client that can be used: i2c_adapter->id.
>
> This is already initialized with I2C_HW_B_TM6000 (although it currently
> uses a fake value).
>
> It is still ugly to do some specific initialization like this, but, when
> we have no other glue, due to the lack of datasheets, this is a better
> alternative than adding an extra fake parameter at the config struct.
>
> All you need is some code like:
>
>
> diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c
> --- a/linux/drivers/media/dvb/frontends/zl10353.c
> +++ b/linux/drivers/media/dvb/frontends/zl10353.c
> @@ -597,6 +597,10 @@ static int zl10353_init(struct dvb_front
> zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) {
> rc = zl10353_write(fe, zl10353_reset_attach,
> sizeof(zl10353_reset_attach));
> +
> + if (state->i2c->id == I2C_HW_B_TM6000) {
> + /* Do special init needed by tm6000 driver */
> + }
> #if 1
> if (debug_regs)
> zl10353_dump_regs(fe);
> diff --git a/linux/drivers/staging/tm6000/tm6000-i2c.c b/linux/drivers/staging/tm6000/tm6000-i2c.c
> --- a/linux/drivers/staging/tm6000/tm6000-i2c.c
> +++ b/linux/drivers/staging/tm6000/tm6000-i2c.c
> @@ -33,8 +33,6 @@
> #include "tuner-xc2028.h"
>
>
> -/*FIXME: Hack to avoid needing to patch i2c-id.h */
> -#define I2C_HW_B_TM6000 I2C_HW_B_EM28XX
> /* ----------------------------------------------------------- */
>
> static unsigned int i2c_debug = 0;
> diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h
> --- a/linux/include/linux/i2c-id.h
> +++ b/linux/include/linux/i2c-id.h
> @@ -42,6 +42,7 @@
> #define I2C_HW_B_AU0828 0x010023 /* auvitek au0828 usb bridge */
> #define I2C_HW_B_CX231XX 0x010024 /* Conexant CX231XX USB based cards */
> #define I2C_HW_B_HDPVR 0x010025 /* Hauppauge HD PVR */
> +#define I2C_HW_B_TM6000 0x010026 /* TM5600/6000/6010 video bridge */
>
> /* --- SGI adapters */
> #define I2C_HW_SGI_VINO 0x160000
>
init is ok, but it has only one additional register 0x55 (value 0x40)
reset after second. I think it can work without this additional once.
The different is in function "set_parameters".
--
Stefan Ringel <stefan.ringel@arcor.de>
^ permalink raw reply [flat|nested] 55+ messages in thread
* Re: [PATCH 14/15] - zl10353
2010-02-04 21:12 ` Stefan Ringel
@ 2010-02-05 0:06 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 55+ messages in thread
From: Mauro Carvalho Chehab @ 2010-02-05 0:06 UTC (permalink / raw)
To: Stefan Ringel; +Cc: Devin Heitmueller, linux-media
Stefan Ringel wrote:
> Am 04.02.2010 03:43, schrieb Mauro Carvalho Chehab:
>> Stefan Ringel wrote:
>>
>>> Am 03.02.2010 21:49, schrieb Devin Heitmueller:
>>>
>>>> On Wed, Feb 3, 2010 at 3:38 PM, Stefan Ringel <stefan.ringel@arcor.de> wrote:
>>>>
>>>>
>>>>> signed-off-by: Stefan Ringel <stefan.ringel@arcor.de>
>>>>>
>>>>> --- a/drivers/media/dvb/frontends/zl10353.h
>>>>> +++ b/drivers/media/dvb/frontends/zl10353.h
>>>>> @@ -45,6 +45,8 @@ struct zl10353_config
>>>>> /* clock control registers (0x51-0x54) */
>>>>> u8 clock_ctl_1; /* default: 0x46 */
>>>>> u8 pll_0; /* default: 0x15 */
>>>>> +
>>>>> + int tm6000:1;
>>>>> };
>>>>>
>>>>>
>>>> Why is this being submitted as its own patch? It is code that is not
>>>> used by *anything*. If you really did require a new field in the
>>>> zl10353 config, that field should be added in the same patch as
>>>> whatever requires it.
>>>>
>>>> Devin
>>>>
>>>>
>>>>
>> Hi Stefan,
>>
>> Due to the problem with your emailer, most of the patches failed:
>>
>> 2/15 3/15 4/15 5/15 6/15 7/15 2/15 (the second one 8th in the sequence)
>> 9/15 11/15 12/15 13/15 and 15/15.
>>
>> In brief, only two patches applied: the 1/15 and a patch also called 2/15
>> (I suspect it is the 10th patch).
>>
>> So, after reading our comments, reading README.patches and applying the
>> Asaulted-patches extension to your thunderbird, please resubmit the patches.
>>
>>
>>> Actually doesn't work zl10353 with tm6010, it have a little different
>>> between a few registers, so I think that I use it.
>>>
>>> for example:
>>> zl10353 use 0x64 , but not mine (0x63)
>>> register 0x5f is 0x17 not 0x13
>>> register 0x5e is 0x40 not 0x00 for auto
>>> and tuner go is 0x70 not 0x71
>>>
>>> the other register are ok. I have no idea how I can set it.
>>>
>> I agree with Devin that the patch 14/15 shouldn't be applied as-is.
>>
>> I have no idea why zl10353 needs a different setup, but you don't need
>> to add an extra parameter to identify the bridge driver. There's a field
>> at struct i2c_client that can be used: i2c_adapter->id.
>>
>> This is already initialized with I2C_HW_B_TM6000 (although it currently
>> uses a fake value).
>>
>> It is still ugly to do some specific initialization like this, but, when
>> we have no other glue, due to the lack of datasheets, this is a better
>> alternative than adding an extra fake parameter at the config struct.
>>
>> All you need is some code like:
>>
>>
>> diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c
>> --- a/linux/drivers/media/dvb/frontends/zl10353.c
>> +++ b/linux/drivers/media/dvb/frontends/zl10353.c
>> @@ -597,6 +597,10 @@ static int zl10353_init(struct dvb_front
>> zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) {
>> rc = zl10353_write(fe, zl10353_reset_attach,
>> sizeof(zl10353_reset_attach));
>> +
>> + if (state->i2c->id == I2C_HW_B_TM6000) {
>> + /* Do special init needed by tm6000 driver */
>> + }
>> #if 1
>> if (debug_regs)
>> zl10353_dump_regs(fe);
>> diff --git a/linux/drivers/staging/tm6000/tm6000-i2c.c b/linux/drivers/staging/tm6000/tm6000-i2c.c
>> --- a/linux/drivers/staging/tm6000/tm6000-i2c.c
>> +++ b/linux/drivers/staging/tm6000/tm6000-i2c.c
>> @@ -33,8 +33,6 @@
>> #include "tuner-xc2028.h"
>>
>>
>> -/*FIXME: Hack to avoid needing to patch i2c-id.h */
>> -#define I2C_HW_B_TM6000 I2C_HW_B_EM28XX
>> /* ----------------------------------------------------------- */
>>
>> static unsigned int i2c_debug = 0;
>> diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h
>> --- a/linux/include/linux/i2c-id.h
>> +++ b/linux/include/linux/i2c-id.h
>> @@ -42,6 +42,7 @@
>> #define I2C_HW_B_AU0828 0x010023 /* auvitek au0828 usb bridge */
>> #define I2C_HW_B_CX231XX 0x010024 /* Conexant CX231XX USB based cards */
>> #define I2C_HW_B_HDPVR 0x010025 /* Hauppauge HD PVR */
>> +#define I2C_HW_B_TM6000 0x010026 /* TM5600/6000/6010 video bridge */
>>
>> /* --- SGI adapters */
>> #define I2C_HW_SGI_VINO 0x160000
>>
> init is ok, but it has only one additional register 0x55 (value 0x40)
> reset after second. I think it can work without this additional once.
> The different is in function "set_parameters".
Ok. Well, just add the logic to check for the bridge at the place it is needed, and
only if it won't work otherwise. I would love to have the datasheet to check for
the values, but unfortunately I don't have it. Anyway, after having it working, someone
may help to figure out why the changes are needed and provide a better approach.
-
A side note:
due to the backport code that you've added on your patches, I suspect that you just
copied the files from the -hg to -git. You shouldn't do it, since we remove all backport
stuff at -git, by running the gentree.pl script, found at v4l/scripts/gentree.pl.
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 55+ messages in thread
end of thread, other threads:[~2010-02-05 0:07 UTC | newest]
Thread overview: 55+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-01 20:20 [PATCH] - tm6000 DVB support Stefan Ringel
2010-02-01 20:35 ` Stefan Ringel
2010-02-01 20:52 ` Devin Heitmueller
2010-02-01 21:23 ` Stefan Ringel
2010-02-01 21:44 ` Devin Heitmueller
2010-02-01 22:00 ` Stefan Ringel
2010-02-01 23:05 ` Mauro Carvalho Chehab
2010-02-02 16:14 ` Stefan Ringel
2010-02-02 16:44 ` Mauro Carvalho Chehab
2010-02-02 17:38 ` Stefan Ringel
2010-02-02 20:05 ` Mauro Carvalho Chehab
2010-02-01 22:52 ` Mauro Carvalho Chehab
2010-02-02 17:24 ` Stefan Ringel
2010-02-02 20:03 ` Mauro Carvalho Chehab
2010-02-02 20:19 ` Stefan Ringel
2010-02-02 20:30 ` Mauro Carvalho Chehab
2010-02-02 20:42 ` Stefan Ringel
2010-02-02 20:52 ` Mauro Carvalho Chehab
2010-02-02 21:11 ` Stefan Ringel
2010-02-03 20:10 ` [PATCH 1/15] - tm6000 build hunk Stefan Ringel
2010-02-03 20:13 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Stefan Ringel
2010-02-03 20:15 ` [PATCH 3/15] - tm6000 bugfix hunk in init_dev Stefan Ringel
2010-02-03 20:22 ` Mauro Carvalho Chehab
2010-02-03 20:16 ` [PATCH 4/15] - tm6000.h Stefan Ringel
2010-02-03 20:25 ` Mauro Carvalho Chehab
2010-02-03 20:50 ` Stefan Ringel
2010-02-03 20:58 ` Devin Heitmueller
2010-02-03 21:31 ` Mauro Carvalho Chehab
2010-02-03 20:18 ` [PATCH 5/15] - tm6000 bugfix i2c transfer Stefan Ringel
2010-02-03 20:18 ` [PATCH 2/15] - tm6000 add Terratec Cinergy Hybrid XE Mauro Carvalho Chehab
2010-02-03 20:20 ` [PATCH 6/15] - tm6000 bugfix usb transfer in DVB mode Stefan Ringel
2010-02-03 20:22 ` [PATCH 7/15] - tm6000 Stefan Ringel
2010-02-03 20:23 ` [PATCH 2/15] - tm6000 bugfix Stefan Ringel
2010-02-03 20:25 ` [PATCH 9/15] - tm6000 analog digital switch Stefan Ringel
2010-02-03 20:40 ` Mauro Carvalho Chehab
2010-02-03 20:55 ` Stefan Ringel
2010-02-03 21:21 ` Mauro Carvalho Chehab
2010-02-03 20:27 ` [PATCH 2/15] - tm6000 add digital init for tm6010 Stefan Ringel
2010-02-03 20:29 ` [PATCH 11/15] - tm6000 add " Stefan Ringel
2010-02-03 20:31 ` [PATCH 12/15] - tm6000 bugfix tuner reset time and tuner param Stefan Ringel
2010-02-03 20:52 ` Devin Heitmueller
2010-02-03 21:15 ` Stefan Ringel
2010-02-03 20:36 ` [PATCH 13/15] - xc2028 bugfix for firmware 3.6 -> Zarlink use without shift in DTV8 or DTV78 Stefan Ringel
2010-02-03 20:45 ` Devin Heitmueller
2010-02-03 20:38 ` [PATCH 14/15] - zl10353 Stefan Ringel
2010-02-03 20:49 ` Devin Heitmueller
2010-02-03 21:07 ` Stefan Ringel
2010-02-04 2:43 ` Mauro Carvalho Chehab
2010-02-04 21:12 ` Stefan Ringel
2010-02-05 0:06 ` Mauro Carvalho Chehab
2010-02-03 20:40 ` [PATCH 15/15] - tm6000 hack with different demodulator parameter Stefan Ringel
2010-02-03 20:47 ` Devin Heitmueller
2010-02-03 20:16 ` [PATCH 1/15] - tm6000 build hunk Mauro Carvalho Chehab
2010-02-03 20:17 ` Devin Heitmueller
2010-02-03 21:48 ` Stefan Ringel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox