cx231xx: Add support for PV Xcapture USB
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/5 cx231xx: Simplify interface checking logic at probe
Just a cleanup patch. Removes one indent level by moving the return -ENODEV to happen before the device register logic, if the interface is not the audio/video (int 1).
drivers/media/video/cx231xx/cx231xx-cards.c +95 -95
@@ -844,110 +844,110 @@ static int cx231xx_usb_probe(struct usb_interface *interface, udev =usb_get_dev (interface_to_usbdev (interface)); ifnum = interface->altsetting[0 ].desc.bInterfaceNumber; -if (ifnum ==1 ) { -/* -* Interface number 0 - IR interface -*/ -/* Check to see next free device and mark as used */ - nr =find_first_zero_bit (&cx231xx_devused,CX231XX_MAXBOARDS ); - cx231xx_devused |=1 << nr; +/* +* Interface number 0 - IR interface (handled by mceusb driver) +* Interface number 1 - AV interface (handled by this driver) +*/ +if (ifnum !=1 ) +return -ENODEV ; -if (nr >=CX231XX_MAXBOARDS ) { -cx231xx_err (DRIVER_NAME +/* Check to see next free device and mark as used */ + nr =find_first_zero_bit (&cx231xx_devused,CX231XX_MAXBOARDS ); + cx231xx_devused |=1 << nr; + +if (nr >=CX231XX_MAXBOARDS ) { +cx231xx_err (DRIVER_NAME ": Supports only %i cx231xx boards.\n" ,CX231XX_MAXBOARDS ); - cx231xx_devused &= ~(1 << nr); -return -ENOMEM ; - } - -/* allocate memory for our device state and initialize it */ - dev =kzalloc (sizeof (*dev),GFP_KERNEL ); -if (dev ==NULL ) { -cx231xx_err (DRIVER_NAME ": out of memory!\n" ); - cx231xx_devused &= ~(1 << nr); -return -ENOMEM ; - } - -snprintf (dev->name,29 ,"cx231xx #%d" , nr); - dev->devno = nr; - dev->model = id->driver_info; - dev->video_mode.alt =-1 ; - dev->interface_count++; - -/* reset gpio dir and value */ - dev->gpio_dir =0 ; - dev->gpio_val =0 ; - dev->xc_fw_load_done =0 ; - dev->has_alsa_audio =1 ; - dev->power_mode =-1 ; -atomic_set (&dev->devlist_count,0 ); - -/* 0 - vbi ; 1 -sliced cc mode */ - dev->vbi_or_sliced_cc_mode =0 ; - -/* get maximum no.of IAD interfaces */ - assoc_desc = udev->actconfig->intf_assoc[0 ]; - dev->max_iad_interface_count = assoc_desc->bInterfaceCount; - -/* init CIR module TBD */ - -/* store the current interface */ - lif = interface; - -/*mode_tv: digital=1 or analog=0*/ - dev->mode_tv =0 ; - - dev->USE_ISO = transfer_mode; - -switch (udev->speed) { -case USB_SPEED_LOW : - speed ="1.5" ; -break ; -case USB_SPEED_UNKNOWN : -case USB_SPEED_FULL : - speed ="12" ; -break ; -case USB_SPEED_HIGH : - speed ="480" ; -break ; -default : - speed ="unknown" ; - } - -if (udev->manufacturer) -strlcpy (descr, udev->manufacturer,sizeof (descr)); - -if (udev->product) { -if (*descr) -strlcat (descr," " ,sizeof (descr)); -strlcat (descr, udev->product,sizeof (descr)); - } + cx231xx_devused &= ~(1 << nr); +return -ENOMEM ; + } + +/* allocate memory for our device state and initialize it */ + dev =kzalloc (sizeof (*dev),GFP_KERNEL ); +if (dev ==NULL ) { +cx231xx_err (DRIVER_NAME ": out of memory!\n" ); + cx231xx_devused &= ~(1 << nr); +return -ENOMEM ; + } + +snprintf (dev->name,29 ,"cx231xx #%d" , nr); + dev->devno = nr; + dev->model = id->driver_info; + dev->video_mode.alt =-1 ; + + dev->interface_count++; +/* reset gpio dir and value */ + dev->gpio_dir =0 ; + dev->gpio_val =0 ; + dev->xc_fw_load_done =0 ; + dev->has_alsa_audio =1 ; + dev->power_mode =-1 ; +atomic_set (&dev->devlist_count,0 ); + +/* 0 - vbi ; 1 -sliced cc mode */ + dev->vbi_or_sliced_cc_mode =0 ; + +/* get maximum no.of IAD interfaces */ + assoc_desc = udev->actconfig->intf_assoc[0 ]; + dev->max_iad_interface_count = assoc_desc->bInterfaceCount; + +/* init CIR module TBD */ + +/* store the current interface */ + lif = interface; + +/*mode_tv: digital=1 or analog=0*/ + dev->mode_tv =0 ; + + dev->USE_ISO = transfer_mode; + +switch (udev->speed) { +case USB_SPEED_LOW : + speed ="1.5" ; +break ; +case USB_SPEED_UNKNOWN : +case USB_SPEED_FULL : + speed ="12" ; +break ; +case USB_SPEED_HIGH : + speed ="480" ; +break ; +default : + speed ="unknown" ; + } + +if (udev->manufacturer) +strlcpy (descr, udev->manufacturer,sizeof (descr)); + +if (udev->product) {if (*descr)strlcat (descr," " ,sizeof (descr)); +strlcat (descr, udev->product,sizeof (descr)); + } +if (*descr) +strlcat (descr," " ,sizeof (descr)); -cx231xx_info ("New device %s@ %s Mbps " -"(%04x:%04x) with %d interfaces\n" , - descr, - speed, -le16_to_cpu (udev->descriptor.idVendor), -le16_to_cpu (udev->descriptor.idProduct), - dev->max_iad_interface_count); +cx231xx_info ("New device %s@ %s Mbps " +"(%04x:%04x) with %d interfaces\n" , + descr, + speed, +le16_to_cpu (udev->descriptor.idVendor), +le16_to_cpu (udev->descriptor.idProduct), + dev->max_iad_interface_count); -/* store the interface 0 back */ - lif = udev->actconfig->interface[0 ]; +/* store the interface 0 back */ + lif = udev->actconfig->interface[0 ]; -/* increment interface count */ - dev->interface_count++; +/* increment interface count */ + dev->interface_count++; -/* get device number */ - nr = dev->devno; +/* get device number */ + nr = dev->devno; - assoc_desc = udev->actconfig->intf_assoc[0 ]; -if (assoc_desc->bFirstInterface != ifnum) { -cx231xx_err (DRIVER_NAME ": Not found " -"matching IAD interface\n" ); -return -ENODEV ; - } - }else { + assoc_desc = udev->actconfig->intf_assoc[0 ]; +if (assoc_desc->bFirstInterface != ifnum) { +cx231xx_err (DRIVER_NAME ": Not found " +"matching IAD interface\n" );return -ENODEV ; }
Signature · 1 line
1.7.1
PATCH 2/5 cx231xx: Use a generic check for TUNER_XC5000
In reply to a message not in the archiveThe check for xc5000 assumes that the tuner will always be using the same bus and will have the same address. As those are configurable via dev->board, it should use, instead, the values defined there.
Also, a similar type of test will be needed by other tuners (for example, for TUNER_XC2028)
drivers/media/video/cx231xx/cx231xx-i2c.c +20 -11
@@ -54,6 +54,21 @@ do { \ } \ }while (0 ) +static inline bool is_tuner(struct cx231xx *dev, struct cx231xx_i2c *bus, +const struct i2c_msg *msg,int tuner_type) +{ +if (bus->nr != dev->board.tuner_i2c_master) +return false; + +if (msg->addr != dev->board.tuner_addr) +return false; + +if (dev->tuner_type != tuner_type) +return false; + +return true; +} +/* * cx231xx_i2c_send_bytes() */
@@ -71,9 +86,7 @@ int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,u16 saddr =0 ;u8 need_gpio =0 ; -if ((bus->nr ==1 ) && (msg->addr ==0x61 ) - && (dev->tuner_type ==TUNER_XC5000 )) { - +if (is_tuner (dev, bus, msg,TUNER_XC5000 )) { size = msg->len;if (size ==2 ) {/* register write sub addr */
@@ -180,9 +193,7 @@ static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap,u16 saddr =0 ;u8 need_gpio =0 ; -if ((bus->nr ==1 ) && (msg->addr ==0x61 ) - && dev->tuner_type ==TUNER_XC5000 ) { - +if (is_tuner (dev, bus, msg,TUNER_XC5000 )) {if (msg->len ==2 ) saddr = msg->buf[0 ] <<8 | msg->buf[1 ];else if (msg->len ==1 )
@@ -274,9 +285,7 @@ static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap,else if (msg1->len ==1 ) saddr = msg1->buf[0 ]; -if ((bus->nr ==1 ) && (msg2->addr ==0x61 ) - && dev->tuner_type ==TUNER_XC5000 ) { - +if (is_tuner (dev, bus, msg2,TUNER_XC5000 )) {if ((msg2->len <16 )) { dprintk1(1,
@@ -454,8 +463,8 @@ static char *i2c_devs[128] = { [0x32 >> 1] = "GeminiIII", [0x02 >> 1] = "Aquarius", [0xa0 >> 1] = "eeprom", - [0xc0 >> 1] = "tuner/XC3028", - [0xc2 >> 1] = "tuner/XC5000", + [0xc0 >> 1] = "tuner", + [0xc2 >> 1] = "tuner", };/*
Signature · 1 line
1.7.1
PATCH 3/5 cx231xx: Use parameters to describe some board variants
In reply to a message not in the archiveInstead of per-model tests all over the code, use some parameters at the board entries to describe the model variants for:
- devices with 417 MPEG encoder;
- devices that use external AV;
- devices where vbi VANC endpoint doesn't work;
- devices with xc5000 that require different IF initialization (and probably will cover also xc3028).
- devices with xceive tuner that require a reset during init.
drivers/media/video/cx231xx/cx231xx-avcore.c +4 -8
@@ -759,11 +759,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,case CX231XX_VMUX_TELEVISION :case CX231XX_VMUX_CABLE :default : -switch (dev->model) { -case CX231XX_BOARD_CNXT_CARRAERA : -case CX231XX_BOARD_CNXT_RDE_250 : -case CX231XX_BOARD_CNXT_SHELBY : -case CX231XX_BOARD_CNXT_RDU_250 : +/* TODO: Test if this is also needed for xc2028/xc3028 */ +if (dev->board.tuner_type ==TUNER_XC5000 ) {/* Disable the use of DIF */ status =vid_blk_read_word (dev,AFE_CTRL , &value);
@@ -820,8 +817,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,MODE_CTRL ,FLD_INPUT_MODE ,cx231xx_set_field (FLD_INPUT_MODE , INPUT_MODE_CVBS_0)); -break ; -default : + }else {/* Enable the DIF for the tuner */ /* Reinitialize the DIF */
@@ -2550,7 +2546,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)case 4 :/* ts1 */ cx231xx_info ("%s: set ts1 registers" , __func__); -if (dev->model ==CX231XX_BOARD_CNXT_VIDEO_GRABBER ) { +if (dev->board.has_417) {cx231xx_info (" MPEG\n" ); value &=0xFFFFFFFC ; value |=0x3 ;
drivers/media/video/cx231xx/cx231xx-cards.c +6 -1
@@ -261,6 +261,9 @@ struct cx231xx_board cx231xx_boards[] = { .agc_analog_digital_select_gpio = 0x1c, .gpio_pin_status_mask = 0x4001000, .norm = V4L2_STD_PAL, + .no_alt_vanc = 1, + .external_av = 1, + .has_417 = 1, .input = {{ .type = CX231XX_VMUX_COMPOSITE1,
@@ -382,6 +385,8 @@ struct cx231xx_board cx231xx_boards[] = { .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, .norm = V4L2_STD_NTSC, + .no_alt_vanc = 1, + .external_av = 1, .input = {{ .type = CX231XX_VMUX_COMPOSITE1, .vmux = CX231XX_VIN_2_1,
@@ -772,7 +777,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,/* Reset other chips required if they are tied up with GPIO pins */ cx231xx_add_into_devlist (dev); -if (dev->model ==CX231XX_BOARD_CNXT_VIDEO_GRABBER ) { +if (dev->board.has_417) {printk (KERN_INFO "attach 417 %d\n" , dev->model);if (cx231xx_417_register (dev) <0 ) { printk(KERN_ERR
drivers/media/video/cx231xx/cx231xx-core.c +7 -9
@@ -571,6 +571,8 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) alt];break ;case INDEX_VANC : +if (dev->board.no_alt_vanc) +return 0 ; usb_interface_index = dev->current_pcb_config.hs_config_info[0 ].interface_info. vanc_index +1 ;
@@ -600,8 +602,7 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) usb_interface_index, alt);/*To workaround error number=-71 on EP0 for videograbber, need add following codes.*/ -if (dev->model !=CX231XX_BOARD_CNXT_VIDEO_GRABBER && - dev->model !=CX231XX_BOARD_HAUPPAUGE_USBLIVE2 ) +if (dev->board.no_alt_vanc)return -1 ; }
@@ -1301,8 +1302,7 @@ int cx231xx_dev_init(struct cx231xx *dev)/* init hardware */ /* Note : with out calling set power mode function, afe can not be set up correctly */ -if (dev->model ==CX231XX_BOARD_CNXT_VIDEO_GRABBER || - dev->model ==CX231XX_BOARD_HAUPPAUGE_USBLIVE2 ) { +if (dev->board.external_av) { errCode =cx231xx_set_power_mode (dev,POLARIS_AVMODE_ENXTERNAL_AV );if (errCode <0 ) {
@@ -1322,11 +1322,9 @@ int cx231xx_dev_init(struct cx231xx *dev) } } -/* reset the Tuner */ -if ((dev->model ==CX231XX_BOARD_CNXT_CARRAERA ) || - (dev->model ==CX231XX_BOARD_CNXT_RDE_250 ) || - (dev->model ==CX231XX_BOARD_CNXT_SHELBY ) || - (dev->model ==CX231XX_BOARD_CNXT_RDU_250 )) +/* reset the Tuner, if it is a Xceive tuner */ +if ((dev->board.tuner_type ==TUNER_XC5000 ) || + (dev->board.tuner_type ==TUNER_XC2028 ))cx231xx_gpio_set (dev, dev->board.tuner_gpio);/* initialize Colibri block */
drivers/media/video/cx231xx/cx231xx-video.c +10 -10
@@ -2190,8 +2190,7 @@ static int cx231xx_v4l2_open(struct file *filp) dev->height =norm_maxh (dev);/* Power up in Analog TV mode */ -if (dev->model ==CX231XX_BOARD_CNXT_VIDEO_GRABBER || - dev->model ==CX231XX_BOARD_HAUPPAUGE_USBLIVE2 ) +if (dev->board.external_av)cx231xx_set_power_mode (dev,POLARIS_AVMODE_ENXTERNAL_AV );else
@@ -2231,9 +2230,7 @@ static int cx231xx_v4l2_open(struct file *filp)if (fh->type ==V4L2_BUF_TYPE_VBI_CAPTURE ) {/* Set the required alternate setting VBI interface works in Bulk mode only */ -if (dev->model !=CX231XX_BOARD_CNXT_VIDEO_GRABBER && - dev->model !=CX231XX_BOARD_HAUPPAUGE_USBLIVE2 ) -cx231xx_set_alt_setting (dev,INDEX_VANC ,0 ); +cx231xx_set_alt_setting (dev,INDEX_VANC ,0 ); videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops, NULL, &dev->vbi_mode.slock,
@@ -2275,7 +2272,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev)cx231xx_info ("V4L2 device %s deregistered\n" ,video_device_node_name (dev->vdev)); -if (dev->model ==CX231XX_BOARD_CNXT_VIDEO_GRABBER ) +if (dev->board.has_417)cx231xx_417_unregister (dev);if (video_is_registered (dev->vdev))
@@ -2302,10 +2299,13 @@ static int cx231xx_v4l2_close(struct file *filp)if (res_check (fh))res_free (fh); -/*To workaround error number=-71 on EP0 for VideoGrabber, -need exclude following.*/ -if (dev->model !=CX231XX_BOARD_CNXT_VIDEO_GRABBER && - dev->model !=CX231XX_BOARD_HAUPPAUGE_USBLIVE2 ) +/* +* To workaround error number=-71 on EP0 for VideoGrabber, +* need exclude following. +* FIXME: It is probably safe to remove most of these, as we're +* now avoiding the alternate setting for INDEX_VANC +*/ +if (!dev->board.no_alt_vanc)if (fh->type ==V4L2_BUF_TYPE_VBI_CAPTURE ) {videobuf_stop (&fh->vb_vidq);videobuf_mmap_free (&fh->vb_vidq);
drivers/media/video/cx231xx/cx231xx.h +3 -0
@@ -353,7 +353,10 @@ struct cx231xx_board { unsigned int max_range_640_480:1; unsigned int has_dvb:1; + unsigned int has_417:1; unsigned int valid:1; + unsigned int no_alt_vanc:1; + unsigned int external_av:1;unsigned char xclk, i2c_speed;
Signature · 1 line
1.7.1
PATCH 4/5 cx231xx: Allow some boards to not use I2C port 3
In reply to a message not in the archiveSome devices don't need to use it. So allow to just disable this logic. Having it enabled on some devices cause power management to complain, generating error -71.
drivers/media/video/cx231xx/cx231xx-avcore.c +2 -0
@@ -1271,6 +1271,8 @@ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3)int status =0 ;bool current_is_port_3; +if (dev->board.dont_use_port_3) + is_port_3 = false; status =cx231xx_read_ctrl_reg (dev,VRT_GET_REGISTER ,PWR_CTL_EN , value,4 );if (status <0 )
drivers/media/video/cx231xx/cx231xx.h +1 -0
@@ -357,6 +357,7 @@ struct cx231xx_board { unsigned int valid:1; unsigned int no_alt_vanc:1; unsigned int external_av:1; + unsigned int dont_use_port_3:1;unsigned char xclk, i2c_speed;
Signature · 1 line
1.7.1
PATCH 5/5 cx231xx: Add support for PV Xcapture USB
In reply to a message not in the archiveAdds support for Pixelviex Xcapture USB grabber device. This device has one composite and one s-video entry only, plus a button.
For now, the button is not supported.
drivers/media/video/cx231xx/cx231xx-cards.c +31 -0
@@ -440,6 +440,35 @@ struct cx231xx_board cx231xx_boards[] = { .gpio = 0, } }, }, + [CX231XX_BOARD_PV_XCAPTURE_USB ] = { + .name ="Pixelview Xcapture USB" , + .tuner_type =TUNER_ABSENT , + .decoder =CX231XX_AVDECODER , + .output_mode =OUT_MODE_VIP11 , + .demod_xfer_mode =0 , + .ctl_pin_status_mask =0xFFFFFFC4 , + .agc_analog_digital_select_gpio =0x0c , + .gpio_pin_status_mask =0x4001000 , + .norm =V4L2_STD_NTSC , + .no_alt_vanc =1 , + .external_av =1 , + .dont_use_port_3 =1 , + + .input = {{ + .type =CX231XX_VMUX_COMPOSITE1 , + .vmux =CX231XX_VIN_2_1 , + .amux =CX231XX_AMUX_LINE_IN , + .gpio =NULL , + }, { + .type =CX231XX_VMUX_SVIDEO , + .vmux =CX231XX_VIN_1_1 | + (CX231XX_VIN_1_2 <<8 ) | +CX25840_SVIDEO_ON , + .amux =CX231XX_AMUX_LINE_IN , + .gpio =NULL , + } + }, + }, };const unsigned int cx231xx_bcount =ARRAY_SIZE (cx231xx_boards);
@@ -469,6 +498,8 @@ struct usb_device_id cx231xx_id_table[] = { .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2}, {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001), .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID}, + {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014), + .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, {}, };
drivers/media/video/cx231xx/cx231xx.h +1 -0
@@ -64,6 +64,7 @@#define CX231XX_BOARD_HAUPPAUGE_EXETER 8#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10 +#define CX231XX_BOARD_PV_XCAPTURE_USB 11/* Limits minimum and default number of buffers */ #define CX231XX_MIN_BUF 4
Signature · 1 line
1.7.1