diff options
author | Thierry MERLE <thierry.merle@free.fr> | 2006-12-04 06:31:30 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-12-10 06:05:50 -0500 |
commit | 957883d0b56a649389d0652a727324dd8ba2e83c (patch) | |
tree | 25343acf88ebfe78803d8802ecb967d40899f315 /drivers/media/video | |
parent | ee5407c5019eb720872abea2e0a1376c35e2304a (diff) |
V4L/DVB (4932): Usbvision_v4l2: fix norm setting problems
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>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/usbvision/usbvision-core.c | 99 | ||||
-rw-r--r-- | drivers/media/video/usbvision/usbvision.h | 5 |
2 files changed, 46 insertions, 58 deletions
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index eb8f4ca3a15f..f87bd0afbbfa 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -2570,58 +2570,61 @@ static int usbvision_unrequest_intra (struct usb_usbvision *usbvision) | |||
2570 | static void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd, | 2570 | static void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd, |
2571 | void *arg) | 2571 | void *arg) |
2572 | { | 2572 | { |
2573 | 2573 | BUG_ON(NULL == usbvision->i2c_adap.algo_data); | |
2574 | int i; | 2574 | i2c_clients_command(&usbvision->i2c_adap, cmd, arg); |
2575 | |||
2576 | for (i = 0; i < USBVISION_I2C_CLIENTS_MAX; i++) { | ||
2577 | if (NULL == usbvision->i2c_clients[i]) | ||
2578 | continue; | ||
2579 | if (NULL == usbvision->i2c_clients[i]->driver->command) | ||
2580 | continue; | ||
2581 | usbvision->i2c_clients[i]->driver->command(usbvision->i2c_clients[i], cmd, arg); | ||
2582 | } | ||
2583 | } | 2575 | } |
2584 | 2576 | ||
2585 | static int attach_inform(struct i2c_client *client) | 2577 | static int attach_inform(struct i2c_client *client) |
2586 | { | 2578 | { |
2587 | struct usb_usbvision *usbvision; | 2579 | struct usb_usbvision *usbvision; |
2588 | struct tuner_setup tun_addr; | ||
2589 | int i; | ||
2590 | 2580 | ||
2591 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | 2581 | usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter); |
2592 | usbvision = (struct usb_usbvision *)client->adapter->data; | 2582 | |
2593 | #else | 2583 | switch (client->addr << 1) { |
2594 | usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter); | 2584 | case 0x43: |
2595 | #endif | 2585 | case 0x4b: |
2586 | { | ||
2587 | struct tuner_setup tun_setup; | ||
2596 | 2588 | ||
2597 | for (i = 0; i < USBVISION_I2C_CLIENTS_MAX; i++) { | 2589 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; |
2598 | if (usbvision->i2c_clients[i] == NULL || | 2590 | tun_setup.type = TUNER_TDA9887; |
2599 | usbvision->i2c_clients[i]->driver->id == | 2591 | tun_setup.addr = client->addr; |
2600 | client->driver->id) { | 2592 | |
2601 | usbvision->i2c_clients[i] = client; | 2593 | call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup); |
2602 | break; | 2594 | break; |
2603 | } | 2595 | } |
2604 | } | 2596 | case 0x42: |
2605 | if ((usbvision->have_tuner) && (usbvision->tuner_type != -1)) { | 2597 | PDEBUG(DBG_I2C,"attach_inform: saa7114 detected.\n"); |
2606 | tun_addr.mode_mask = T_ANALOG_TV; | 2598 | break; |
2607 | tun_addr.type = usbvision->tuner_type; | 2599 | case 0x4a: |
2608 | tun_addr.addr = ADDR_UNSET; | 2600 | PDEBUG(DBG_I2C,"attach_inform: saa7113 detected.\n"); |
2609 | client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr); | 2601 | break; |
2610 | call_i2c_clients(usbvision, VIDIOC_INT_RESET, NULL); | 2602 | case 0xa0: |
2611 | call_i2c_clients(usbvision, VIDIOC_S_INPUT, &usbvision->ctl_input); | 2603 | PDEBUG(DBG_I2C,"attach_inform: eeprom detected.\n"); |
2612 | call_i2c_clients(usbvision, VIDIOC_STREAMON, NULL); | 2604 | break; |
2613 | } | ||
2614 | call_i2c_clients(usbvision, VIDIOC_S_STD, &usbvision->tvnorm->id); | ||
2615 | 2605 | ||
2616 | PDEBUG(DBG_I2C, "usbvision[%d] attaches %s", usbvision->nr, client->name); | 2606 | default: |
2607 | PDEBUG(DBG_I2C,"attach inform: detected I2C address %x\n", client->addr << 1); | ||
2608 | { | ||
2609 | struct tuner_setup tun_setup; | ||
2617 | 2610 | ||
2611 | usbvision->tuner_addr = client->addr; | ||
2612 | |||
2613 | if ((usbvision->have_tuner) && (usbvision->tuner_type != -1)) { | ||
2614 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; | ||
2615 | tun_setup.type = usbvision->tuner_type; | ||
2616 | tun_setup.addr = usbvision->tuner_addr; | ||
2617 | call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup); | ||
2618 | } | ||
2619 | } | ||
2620 | break; | ||
2621 | } | ||
2618 | return 0; | 2622 | return 0; |
2619 | } | 2623 | } |
2620 | 2624 | ||
2621 | static int detach_inform(struct i2c_client *client) | 2625 | static int detach_inform(struct i2c_client *client) |
2622 | { | 2626 | { |
2623 | struct usb_usbvision *usbvision; | 2627 | struct usb_usbvision *usbvision; |
2624 | int i; | ||
2625 | 2628 | ||
2626 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | 2629 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) |
2627 | usbvision = (struct usb_usbvision *)client->adapter->data; | 2630 | usbvision = (struct usb_usbvision *)client->adapter->data; |
@@ -2630,14 +2633,6 @@ static int detach_inform(struct i2c_client *client) | |||
2630 | #endif | 2633 | #endif |
2631 | 2634 | ||
2632 | PDEBUG(DBG_I2C, "usbvision[%d] detaches %s", usbvision->nr, client->name); | 2635 | PDEBUG(DBG_I2C, "usbvision[%d] detaches %s", usbvision->nr, client->name); |
2633 | for (i = 0; i < USBVISION_I2C_CLIENTS_MAX; i++) { | ||
2634 | if (NULL != usbvision->i2c_clients[i] && | ||
2635 | usbvision->i2c_clients[i]->driver->id == | ||
2636 | client->driver->id) { | ||
2637 | usbvision->i2c_clients[i] = NULL; | ||
2638 | break; | ||
2639 | } | ||
2640 | } | ||
2641 | return 0; | 2636 | return 0; |
2642 | } | 2637 | } |
2643 | 2638 | ||
@@ -2886,10 +2881,7 @@ static int usbvision_init_i2c(struct usb_usbvision *usbvision) | |||
2886 | } | 2881 | } |
2887 | #endif | 2882 | #endif |
2888 | 2883 | ||
2889 | usbvision->i2c_ok = usbvision_i2c_usb_add_bus(&usbvision->i2c_adap); | 2884 | return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap); |
2890 | |||
2891 | return usbvision->i2c_ok; | ||
2892 | |||
2893 | } | 2885 | } |
2894 | 2886 | ||
2895 | 2887 | ||
@@ -3811,6 +3803,8 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) | |||
3811 | if (!errCode) { | 3803 | if (!errCode) { |
3812 | usbvision_begin_streaming(usbvision); | 3804 | usbvision_begin_streaming(usbvision); |
3813 | errCode = usbvision_init_isoc(usbvision); | 3805 | errCode = usbvision_init_isoc(usbvision); |
3806 | /* device needs to be initialized before isoc transfer */ | ||
3807 | usbvision_muxsel(usbvision,0); | ||
3814 | usbvision->user++; | 3808 | usbvision->user++; |
3815 | } | 3809 | } |
3816 | else { | 3810 | else { |
@@ -4169,7 +4163,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
4169 | memset(ctrl,0,sizeof(*ctrl)); | 4163 | memset(ctrl,0,sizeof(*ctrl)); |
4170 | ctrl->id=id; | 4164 | ctrl->id=id; |
4171 | 4165 | ||
4172 | i2c_clients_command(&usbvision->i2c_adap, cmd, arg); | 4166 | call_i2c_clients(usbvision, cmd, arg); |
4173 | 4167 | ||
4174 | if (ctrl->type) | 4168 | if (ctrl->type) |
4175 | return 0; | 4169 | return 0; |
@@ -5300,19 +5294,15 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision) | |||
5300 | (usbvision->have_tuner ? V4L2_CAP_TUNER : 0); | 5294 | (usbvision->have_tuner ? V4L2_CAP_TUNER : 0); |
5301 | usbvision->vcap.version = USBVISION_DRIVER_VERSION; /* version */ | 5295 | usbvision->vcap.version = USBVISION_DRIVER_VERSION; /* version */ |
5302 | 5296 | ||
5303 | |||
5304 | for (i = 0; i < TVNORMS; i++) | 5297 | for (i = 0; i < TVNORMS; i++) |
5305 | if (usbvision_device_data[model].VideoNorm == tvnorms[i].mode) | 5298 | if (usbvision_device_data[model].VideoNorm == tvnorms[i].mode) |
5306 | break; | 5299 | break; |
5307 | if (i == TVNORMS) | 5300 | if (i == TVNORMS) |
5308 | i = 0; | 5301 | i = 0; |
5309 | usbvision->tvnorm = &tvnorms[i]; /* set default norm */ | 5302 | usbvision->tvnorm = &tvnorms[i]; /* set default norm */ |
5310 | call_i2c_clients(usbvision, VIDIOC_S_STD, | ||
5311 | &usbvision->tvnorm->id); | ||
5312 | 5303 | ||
5313 | usbvision->video_inputs = usbvision_device_data[model].VideoChannels; | 5304 | usbvision->video_inputs = usbvision_device_data[model].VideoChannels; |
5314 | usbvision->ctl_input = 0; | 5305 | usbvision->ctl_input = 0; |
5315 | /* usbvision_muxsel(usbvision, usbvision->ctl_input); */ | ||
5316 | 5306 | ||
5317 | /* This should be here to make i2c clients to be able to register */ | 5307 | /* This should be here to make i2c clients to be able to register */ |
5318 | usbvision_audio_off(usbvision); //first switch off audio | 5308 | usbvision_audio_off(usbvision); //first switch off audio |
@@ -5678,6 +5668,8 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us | |||
5678 | usbvision->tuner_type = usbvision_device_data[model].TunerType; | 5668 | usbvision->tuner_type = usbvision_device_data[model].TunerType; |
5679 | } | 5669 | } |
5680 | 5670 | ||
5671 | usbvision->tuner_addr = ADDR_UNSET; | ||
5672 | |||
5681 | usbvision->DevModel = model; | 5673 | usbvision->DevModel = model; |
5682 | usbvision->remove_pending = 0; | 5674 | usbvision->remove_pending = 0; |
5683 | usbvision->last_error = 0; | 5675 | usbvision->last_error = 0; |
@@ -5689,7 +5681,6 @@ static int __devinit usbvision_probe(struct usb_interface *intf, const struct us | |||
5689 | usbvision->usb_bandwidth = 0; | 5681 | usbvision->usb_bandwidth = 0; |
5690 | usbvision->user = 0; | 5682 | usbvision->user = 0; |
5691 | usbvision->streaming = Stream_Off; | 5683 | usbvision->streaming = Stream_Off; |
5692 | |||
5693 | usbvision_register_video(usbvision); | 5684 | usbvision_register_video(usbvision); |
5694 | usbvision_configure_video(usbvision); | 5685 | usbvision_configure_video(usbvision); |
5695 | up(&usbvision->lock); | 5686 | up(&usbvision->lock); |
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h index ef83a5c4d2fd..f304e66b03a6 100644 --- a/drivers/media/video/usbvision/usbvision.h +++ b/drivers/media/video/usbvision/usbvision.h | |||
@@ -319,8 +319,6 @@ struct usbvision_frame { | |||
319 | #define BRIDGE_NT1004 1004 | 319 | #define BRIDGE_NT1004 1004 |
320 | #define BRIDGE_NT1005 1005 | 320 | #define BRIDGE_NT1005 1005 |
321 | 321 | ||
322 | #define USBVISION_I2C_CLIENTS_MAX 8 | ||
323 | |||
324 | struct usbvision_device_data_st { | 322 | struct usbvision_device_data_st { |
325 | int idVendor; | 323 | int idVendor; |
326 | int idProduct; | 324 | int idProduct; |
@@ -355,8 +353,6 @@ struct usb_usbvision { | |||
355 | struct i2c_adapter i2c_adap; | 353 | struct i2c_adapter i2c_adap; |
356 | struct i2c_algo_usb_data i2c_algo; | 354 | struct i2c_algo_usb_data i2c_algo; |
357 | struct i2c_client i2c_client; | 355 | struct i2c_client i2c_client; |
358 | int i2c_state, i2c_ok; | ||
359 | struct i2c_client *i2c_clients[USBVISION_I2C_CLIENTS_MAX]; | ||
360 | 356 | ||
361 | struct urb *ctrlUrb; | 357 | struct urb *ctrlUrb; |
362 | unsigned char ctrlUrbBuffer[8]; | 358 | unsigned char ctrlUrbBuffer[8]; |
@@ -367,6 +363,7 @@ struct usb_usbvision { | |||
367 | 363 | ||
368 | int have_tuner; | 364 | int have_tuner; |
369 | int tuner_type; | 365 | int tuner_type; |
366 | int tuner_addr; | ||
370 | int bridgeType; // NT1003, NT1004, NT1005 | 367 | int bridgeType; // NT1003, NT1004, NT1005 |
371 | int channel; | 368 | int channel; |
372 | int radio; | 369 | int radio; |