V4L/DVB (4932): Usbvision_v4l2: fix norm setting problems
authorThierry MERLE <thierry.merle@free.fr>
Mon, 4 Dec 2006 11:31:30 +0000 (08:31 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Sun, 10 Dec 2006 11:05:50 +0000 (09:05 -0200)
Patch contents:
- fix i2c command broadcast (caused problems for SECAM norm setting)
- default input selection at driver open

Signed-off-by: Thierry MERLE <thierry.merle@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/usbvision/usbvision-core.c
drivers/media/video/usbvision/usbvision.h

index eb8f4ca3a15f010e0fe973eef47cf85161fccd9a..f87bd0afbbfa0b643d1884a9291ddad15ecccf09 100644 (file)
@@ -2570,58 +2570,61 @@ static int usbvision_unrequest_intra (struct usb_usbvision *usbvision)
 static void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,
                             void *arg)
 {
-
-       int i;
-
-       for (i = 0; i < USBVISION_I2C_CLIENTS_MAX; i++) {
-               if (NULL == usbvision->i2c_clients[i])
-                       continue;
-               if (NULL == usbvision->i2c_clients[i]->driver->command)
-                       continue;
-               usbvision->i2c_clients[i]->driver->command(usbvision->i2c_clients[i], cmd, arg);
-       }
+       BUG_ON(NULL == usbvision->i2c_adap.algo_data);
+       i2c_clients_command(&usbvision->i2c_adap, cmd, arg);
 }
 
 static int attach_inform(struct i2c_client *client)
 {
        struct usb_usbvision *usbvision;
-       struct tuner_setup tun_addr;
-       int i;
 
-       #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-               usbvision = (struct usb_usbvision *)client->adapter->data;
-       #else
-               usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
-       #endif
+       usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
+
+       switch (client->addr << 1) {
+               case 0x43:
+               case 0x4b:
+               {
+                       struct tuner_setup tun_setup;
 
-       for (i = 0; i < USBVISION_I2C_CLIENTS_MAX; i++) {
-               if (usbvision->i2c_clients[i] == NULL ||
-                   usbvision->i2c_clients[i]->driver->id ==
-                   client->driver->id) {
-                       usbvision->i2c_clients[i] = client;
+                       tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+                       tun_setup.type = TUNER_TDA9887;
+                       tun_setup.addr = client->addr;
+
+                       call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
                        break;
                }
-       }
-       if ((usbvision->have_tuner) && (usbvision->tuner_type != -1)) {
-               tun_addr.mode_mask = T_ANALOG_TV;
-               tun_addr.type = usbvision->tuner_type;
-               tun_addr.addr = ADDR_UNSET;
-               client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr);
-               call_i2c_clients(usbvision, VIDIOC_INT_RESET, NULL);
-               call_i2c_clients(usbvision, VIDIOC_S_INPUT, &usbvision->ctl_input);
-               call_i2c_clients(usbvision, VIDIOC_STREAMON, NULL);
-       }
-       call_i2c_clients(usbvision, VIDIOC_S_STD, &usbvision->tvnorm->id);
+               case 0x42:
+                       PDEBUG(DBG_I2C,"attach_inform: saa7114 detected.\n");
+                       break;
+               case 0x4a:
+                       PDEBUG(DBG_I2C,"attach_inform: saa7113 detected.\n");
+                       break;
+               case 0xa0:
+                       PDEBUG(DBG_I2C,"attach_inform: eeprom detected.\n");
+                       break;
 
-       PDEBUG(DBG_I2C, "usbvision[%d] attaches %s", usbvision->nr, client->name);
+               default:
+                       PDEBUG(DBG_I2C,"attach inform: detected I2C address %x\n", client->addr << 1);
+                       {
+                               struct tuner_setup tun_setup;
 
+                               usbvision->tuner_addr = client->addr;
+
+                               if ((usbvision->have_tuner) && (usbvision->tuner_type != -1)) {
+                                       tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+                                       tun_setup.type = usbvision->tuner_type;
+                                       tun_setup.addr = usbvision->tuner_addr;
+                                       call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
+                               }
+                       }
+                       break;
+       }
        return 0;
 }
 
 static int detach_inform(struct i2c_client *client)
 {
        struct usb_usbvision *usbvision;
-       int i;
 
        #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
                usbvision = (struct usb_usbvision *)client->adapter->data;
@@ -2630,14 +2633,6 @@ static int detach_inform(struct i2c_client *client)
        #endif
 
        PDEBUG(DBG_I2C, "usbvision[%d] detaches %s", usbvision->nr, client->name);
-       for (i = 0; i < USBVISION_I2C_CLIENTS_MAX; i++) {
-               if (NULL != usbvision->i2c_clients[i] &&
-                   usbvision->i2c_clients[i]->driver->id ==
-                   client->driver->id) {
-                       usbvision->i2c_clients[i] = NULL;
-                       break;
-               }
-       }
        return 0;
 }
 
@@ -2886,10 +2881,7 @@ static int usbvision_init_i2c(struct usb_usbvision *usbvision)
        }
 #endif
 
-       usbvision->i2c_ok = usbvision_i2c_usb_add_bus(&usbvision->i2c_adap);
-
-       return usbvision->i2c_ok;
-
+       return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap);
 }
 
 
@@ -3811,6 +3803,8 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file)
                if (!errCode) {
                        usbvision_begin_streaming(usbvision);
                        errCode = usbvision_init_isoc(usbvision);
+                       /* device needs to be initialized before isoc transfer */
+                       usbvision_muxsel(usbvision,0);
                        usbvision->user++;
                }
                else {
@@ -4169,7 +4163,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
                        memset(ctrl,0,sizeof(*ctrl));
                        ctrl->id=id;
 
-                       i2c_clients_command(&usbvision->i2c_adap, cmd, arg);
+                       call_i2c_clients(usbvision, cmd, arg);
 
                        if (ctrl->type)
                                return 0;
@@ -5300,19 +5294,15 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
                (usbvision->have_tuner ? V4L2_CAP_TUNER : 0);
        usbvision->vcap.version = USBVISION_DRIVER_VERSION;         /* version */
 
-
        for (i = 0; i < TVNORMS; i++)
                if (usbvision_device_data[model].VideoNorm == tvnorms[i].mode)
                        break;
        if (i == TVNORMS)
                i = 0;
-       usbvision->tvnorm = &tvnorms[i];        /* set default norm */
-       call_i2c_clients(usbvision, VIDIOC_S_STD,
-                        &usbvision->tvnorm->id);
+       usbvision->tvnorm = &tvnorms[i];        /* set default norm */
 
        usbvision->video_inputs = usbvision_device_data[model].VideoChannels;
        usbvision->ctl_input = 0;
-/*     usbvision_muxsel(usbvision, usbvision->ctl_input); */
 
        /* This should be here to make i2c clients to be able to register */
        usbvision_audio_off(usbvision); //first switch off audio
@@ -5678,6 +5668,8 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
                usbvision->tuner_type = usbvision_device_data[model].TunerType;
        }
 
+       usbvision->tuner_addr = ADDR_UNSET;
+
        usbvision->DevModel = model;
        usbvision->remove_pending = 0;
        usbvision->last_error = 0;
@@ -5689,7 +5681,6 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us
        usbvision->usb_bandwidth = 0;
        usbvision->user = 0;
        usbvision->streaming = Stream_Off;
-
        usbvision_register_video(usbvision);
        usbvision_configure_video(usbvision);
        up(&usbvision->lock);
index ef83a5c4d2fd529eff6751efd0b6dbd5d47c6cd7..f304e66b03a672b0145542d11cceefaf83652e83 100644 (file)
@@ -319,8 +319,6 @@ struct usbvision_frame {
 #define BRIDGE_NT1004  1004
 #define BRIDGE_NT1005   1005
 
-#define USBVISION_I2C_CLIENTS_MAX              8
-
 struct usbvision_device_data_st {
        int idVendor;
        int idProduct;
@@ -355,8 +353,6 @@ struct usb_usbvision {
        struct i2c_adapter i2c_adap;
        struct i2c_algo_usb_data i2c_algo;
        struct i2c_client i2c_client;
-       int i2c_state, i2c_ok;
-       struct i2c_client *i2c_clients[USBVISION_I2C_CLIENTS_MAX];
 
        struct urb *ctrlUrb;
        unsigned char ctrlUrbBuffer[8];
@@ -367,6 +363,7 @@ struct usb_usbvision {
 
        int have_tuner;
        int tuner_type;
+       int tuner_addr;
        int bridgeType;                                                 // NT1003, NT1004, NT1005
        int channel;
        int radio;