Commit 957883d0 authored by Thierry MERLE's avatar Thierry MERLE Committed by Mauro Carvalho Chehab

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