Re: [PATCH] - tm6000 DVB support

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

 



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@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.
>   
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@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.
>
>   
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, &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.
>   
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@xxxxxxxx>

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