Re: [PATCH] - tm6000 DVB support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxx>

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@xxxxxxxxx> 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, &regs[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
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux