Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=702a67624e4bc9c7056418b576af928940b7dbb9
Commit:     702a67624e4bc9c7056418b576af928940b7dbb9
Parent:     c6e62a3a398d62e8ae366ac1465911db0ac7fc0b
Author:     Chris Pascoe <[EMAIL PROTECTED]>
AuthorDate: Tue Nov 20 03:34:11 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Fri Jan 25 19:02:37 2008 -0200

    V4L/DVB (6655): Add support for MT352-based DViCO FusionHDTV DVB-T NANO 
devices
    
    There are at least three variants of the DViCO FusionHDTV DVB-T NANO that
    share the same USB device ID.  The first (ZL10353 w/ firmware in ROM) is
    already supported; the latter two both require firmware and have either
    an MT352 or ZL10353 demodulator, and have a different IR receiver from the
    first.
    
    This introduces a new identify_state that can tell the difference between a
    "warm" device which is running the embedded firmware, and a "cold" device
    that needs us to upload firmware to it before it will work.  We patch the
    uploaded device ID (like we do for other bluebird devices) to make it easy
    to identify the particular device variant when it reattaches.
    
    NB: These devices use a different firmware file from previous bluebird
        devices.  You need a new firmware file to make this work.
    
    Signed-off-by: Chris Pascoe <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 drivers/media/dvb/dvb-usb/cxusb.c       |  116 ++++++++++++++++++++++++++++---
 drivers/media/dvb/dvb-usb/dvb-usb-ids.h |    1 +
 2 files changed, 106 insertions(+), 11 deletions(-)

diff --git a/drivers/media/dvb/dvb-usb/cxusb.c 
b/drivers/media/dvb/dvb-usb/cxusb.c
index f6fa2c2..c44b979 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -440,6 +440,13 @@ static struct zl10353_config cxusb_zl10353_xc3028_config = 
{
        .parallel_ts = 1,
 };
 
+static struct mt352_config cxusb_mt352_xc3028_config = {
+       .demod_address = 0x0f,
+       .if2 = 4560,
+       .no_tuner = 1,
+       .demod_init = cxusb_mt352_demod_init,
+};
+
 /* Callbacks for DVB USB */
 static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
 {
@@ -639,30 +646,63 @@ static int cxusb_nano2_frontend_attach(struct 
dvb_usb_adapter *adap)
                                   &adap->dev->i2c_adap)) != NULL)
                return 0;
 
+       if ((adap->fe = dvb_attach(mt352_attach,
+                                  &cxusb_mt352_xc3028_config,
+                                  &adap->dev->i2c_adap)) != NULL)
+               return 0;
+
        return -EIO;
 }
 
 /*
+ * DViCO has shipped two devices with the same USB ID, but only one of them
+ * needs a firmware download.  Check the device class details to see if they
+ * have non-default values to decide whether the device is actually cold or
+ * not, and forget a match if it turns out we selected the wrong device.
+ */
+static int bluebird_fx2_identify_state(struct usb_device *udev,
+                                      struct dvb_usb_device_properties *props,
+                                      struct dvb_usb_device_description **desc,
+                                      int *cold)
+{
+       int wascold = *cold;
+
+       *cold = udev->descriptor.bDeviceClass == 0xff &&
+               udev->descriptor.bDeviceSubClass == 0xff &&
+               udev->descriptor.bDeviceProtocol == 0xff;
+
+       if (*cold && !wascold)
+               *desc = NULL;
+
+       return 0;
+}
+
+/*
  * DViCO bluebird firmware needs the "warm" product ID to be patched into the
  * firmware file before download.
  */
 
-#define BLUEBIRD_01_ID_OFFSET 6638
+static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
 static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
                                                  const struct firmware *fw)
 {
-       if (fw->size < BLUEBIRD_01_ID_OFFSET + 4)
-               return -EINVAL;
+       int pos;
+
+       for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
+               int idoff = dvico_firmware_id_offsets[pos];
 
-       if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) &&
-           fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) {
+               if (fw->size < idoff + 4)
+                       continue;
 
-               fw->data[BLUEBIRD_01_ID_OFFSET + 2] =
-                       le16_to_cpu(udev->descriptor.idProduct) + 1;
-               fw->data[BLUEBIRD_01_ID_OFFSET + 3] =
-                       le16_to_cpu(udev->descriptor.idProduct) >> 8;
+               if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
+                   fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
+                       fw->data[idoff + 2] =
+                               le16_to_cpu(udev->descriptor.idProduct) + 1;
+                       fw->data[idoff + 3] =
+                               le16_to_cpu(udev->descriptor.idProduct) >> 8;
 
-               return usb_cypress_load_firmware(udev, fw, CYPRESS_FX2);
+                       return usb_cypress_load_firmware(udev, fw, CYPRESS_FX2);
+               }
        }
 
        return -EINVAL;
@@ -676,6 +716,7 @@ static struct dvb_usb_device_properties 
cxusb_bluebird_lgz201_properties;
 static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
 static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
 static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
+static struct dvb_usb_device_properties 
cxusb_bluebird_nano2_needsfirmware_properties;
 
 static int cxusb_probe(struct usb_interface *intf,
                       const struct usb_device_id *id)
@@ -686,7 +727,8 @@ static int cxusb_probe(struct usb_interface *intf,
                
dvb_usb_device_init(intf,&cxusb_bluebird_lgz201_properties,THIS_MODULE,NULL) == 
0 ||
                
dvb_usb_device_init(intf,&cxusb_bluebird_dtt7579_properties,THIS_MODULE,NULL) 
== 0 ||
                
dvb_usb_device_init(intf,&cxusb_bluebird_dualdig4_properties,THIS_MODULE,NULL) 
== 0 ||
-               
dvb_usb_device_init(intf,&cxusb_bluebird_nano2_properties,THIS_MODULE,NULL) == 
0) {
+               
dvb_usb_device_init(intf,&cxusb_bluebird_nano2_properties,THIS_MODULE,NULL) == 
0 ||
+               
dvb_usb_device_init(intf,&cxusb_bluebird_nano2_needsfirmware_properties,THIS_MODULE,NULL)
 == 0) {
                return 0;
        }
 
@@ -709,6 +751,7 @@ static struct usb_device_id cxusb_table [] = {
        { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
        { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
        { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
+       { USB_DEVICE(USB_VID_DVICO, 
USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
        {}              /* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1018,6 +1061,7 @@ static struct dvb_usb_device_properties 
cxusb_bluebird_nano2_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl         = CYPRESS_FX2,
+       .identify_state   = bluebird_fx2_identify_state,
 
        .size_of_priv     = sizeof(struct cxusb_state),
 
@@ -1061,6 +1105,56 @@ static struct dvb_usb_device_properties 
cxusb_bluebird_nano2_properties = {
        }
 };
 
+static struct dvb_usb_device_properties 
cxusb_bluebird_nano2_needsfirmware_properties = {
+       .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+       .usb_ctrl          = DEVICE_SPECIFIC,
+       .firmware          = "dvb-usb-bluebird-02.fw",
+       .download_firmware = bluebird_patch_dvico_firmware_download,
+       .identify_state    = bluebird_fx2_identify_state,
+
+       .size_of_priv      = sizeof(struct cxusb_state),
+
+       .num_adapters = 1,
+       .adapter = {
+               {
+                       .streaming_ctrl   = cxusb_streaming_ctrl,
+                       .frontend_attach  = cxusb_nano2_frontend_attach,
+                       .tuner_attach     = cxusb_dvico_xc3028_tuner_attach,
+                       /* parameter for the MPEG2-data transfer */
+                       .stream = {
+                               .type = USB_BULK,
+                               .count = 5,
+                               .endpoint = 0x02,
+                               .u = {
+                                       .bulk = {
+                                               .buffersize = 8192,
+                                       }
+                               }
+                       },
+               },
+       },
+
+       .power_ctrl       = cxusb_nano2_power_ctrl,
+
+       .i2c_algo         = &cxusb_i2c_algo,
+
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .rc_interval      = 100,
+       .rc_key_map       = dvico_portable_rc_keys,
+       .rc_key_map_size  = ARRAY_SIZE(dvico_portable_rc_keys),
+       .rc_query         = cxusb_rc_query,
+
+       .num_device_descs = 1,
+       .devices = {
+               {   "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
+                       { &cxusb_table[14], NULL },
+                       { &cxusb_table[15], NULL },
+               },
+       }
+};
+
 static struct usb_driver cxusb_driver = {
        .name           = "dvb_usb_cxusb",
        .probe          = cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h 
b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 5349698..c94d993 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -149,6 +149,7 @@
 #define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM             0xdb59
 #define USB_PID_DVICO_BLUEBIRD_DUAL_4                  0xdb78
 #define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2            0xdb70
+#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM   0xdb71
 #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD                0xdb54
 #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM                0xdb55
 #define USB_PID_MEDION_MD95700                         0x0932
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to