diff options
Diffstat (limited to 'drivers/media/usb')
51 files changed, 2422 insertions, 1666 deletions
diff --git a/drivers/media/usb/au0828/au0828-cards.c b/drivers/media/usb/au0828/au0828-cards.c index 9eb77ac2153b..da87f1cc31a9 100644 --- a/drivers/media/usb/au0828/au0828-cards.c +++ b/drivers/media/usb/au0828/au0828-cards.c @@ -36,6 +36,11 @@ static void hvr950q_cs5340_audio(void *priv, int enable) au0828_clear(dev, REG_000, 0x10); } +/* + * WARNING: There's a quirks table at sound/usb/quirks-table.h + * that should also be updated every time a new device with V4L2 support + * is added here. + */ struct au0828_board au0828_boards[] = { [AU0828_BOARD_UNKNOWN] = { .name = "Unknown board", diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index bc064803b6c7..082ae6ba492f 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -153,6 +153,14 @@ static void au0828_usb_disconnect(struct usb_interface *interface) dprintk(1, "%s()\n", __func__); + /* there is a small window after disconnect, before + dev->usbdev is NULL, for poll (e.g: IR) try to access + the device and fill the dmesg with error messages. + Set the status so poll routines can check and avoid + access after disconnect. + */ + dev->dev_state = DEV_DISCONNECTED; + au0828_rc_unregister(dev); /* Digital TV */ au0828_dvb_unregister(dev); diff --git a/drivers/media/usb/au0828/au0828-dvb.c b/drivers/media/usb/au0828/au0828-dvb.c index 00ab1563d142..c267d76f5b3c 100644 --- a/drivers/media/usb/au0828/au0828-dvb.c +++ b/drivers/media/usb/au0828/au0828-dvb.c @@ -88,12 +88,14 @@ static struct xc5000_config hauppauge_xc5000a_config = { .i2c_address = 0x61, .if_khz = 6000, .chip_id = XC5000A, + .output_amp = 0x8f, }; static struct xc5000_config hauppauge_xc5000c_config = { .i2c_address = 0x61, .if_khz = 6000, .chip_id = XC5000C, + .output_amp = 0x8f, }; static struct mxl5007t_config mxl5007t_hvr950q_config = { diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 63995f97dc65..b0f067971979 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -129,6 +129,10 @@ static int au0828_get_key_au8522(struct au0828_rc *ir) int prv_bit, bit, width; bool first = true; + /* do nothing if device is disconnected */ + if (ir->dev->dev_state == DEV_DISCONNECTED) + return 0; + /* Check IR int */ rc = au8522_rc_read(ir, 0xe1, -1, buf, 1); if (rc < 0 || !(buf[0] & (1 << 4))) { @@ -255,8 +259,11 @@ static void au0828_rc_stop(struct rc_dev *rc) cancel_delayed_work_sync(&ir->work); - /* Disable IR */ - au8522_rc_clear(ir, 0xe0, 1 << 4); + /* do nothing if device is disconnected */ + if (ir->dev->dev_state != DEV_DISCONNECTED) { + /* Disable IR */ + au8522_rc_clear(ir, 0xe0, 1 << 4); + } } static int au0828_probe_i2c_ir(struct au0828_dev *dev) @@ -363,8 +370,7 @@ void au0828_rc_unregister(struct au0828_dev *dev) if (!ir) return; - if (ir->rc) - rc_unregister_device(ir->rc); + rc_unregister_device(ir->rc); /* done */ kfree(ir); diff --git a/drivers/media/usb/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig index 569aa298c03f..173c0e287a08 100644 --- a/drivers/media/usb/cx231xx/Kconfig +++ b/drivers/media/usb/cx231xx/Kconfig @@ -7,6 +7,7 @@ config VIDEO_CX231XX select VIDEOBUF_VMALLOC select VIDEO_CX25840 select VIDEO_CX2341X + select I2C_MUX ---help--- This is a video4linux driver for Conexant 231xx USB based TV cards. diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 459bb0e98971..3f295b4d1a3d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -24,6 +24,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" + #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> @@ -37,9 +39,6 @@ #include <media/v4l2-event.h> #include <media/cx2341x.h> #include <media/tuner.h> -#include <linux/usb.h> - -#include "cx231xx.h" #define CX231xx_FIRM_IMAGE_SIZE 376836 #define CX231xx_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" @@ -90,10 +89,10 @@ static unsigned int v4l_debug = 1; module_param(v4l_debug, int, 0644); MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); -#define dprintk(level, fmt, arg...)\ - do { if (v4l_debug >= level) \ - pr_info("%s: " fmt, \ - (dev) ? dev->name : "cx231xx[?]", ## arg); \ +#define dprintk(level, fmt, arg...) \ + do { \ + if (v4l_debug >= level) \ + printk(KERN_DEBUG pr_fmt(fmt), ## arg); \ } while (0) static struct cx231xx_tvnorm cx231xx_tvnorms[] = { @@ -988,29 +987,34 @@ static int cx231xx_load_firmware(struct cx231xx *dev) IVTV_REG_APU, 0); if (retval != 0) { - pr_err("%s: Error with mc417_register_write\n", __func__); + dev_err(dev->dev, + "%s: Error with mc417_register_write\n", __func__); return -1; } retval = request_firmware(&firmware, CX231xx_FIRM_IMAGE_NAME, - &dev->udev->dev); + dev->dev); if (retval != 0) { - pr_err("ERROR: Hotplug firmware request failed (%s).\n", + dev_err(dev->dev, + "ERROR: Hotplug firmware request failed (%s).\n", CX231xx_FIRM_IMAGE_NAME); - pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); + dev_err(dev->dev, + "Please fix your hotplug setup, the board will not work without firmware loaded!\n"); return -1; } if (firmware->size != CX231xx_FIRM_IMAGE_SIZE) { - pr_err("ERROR: Firmware size mismatch (have %zd, expected %d)\n", + dev_err(dev->dev, + "ERROR: Firmware size mismatch (have %zd, expected %d)\n", firmware->size, CX231xx_FIRM_IMAGE_SIZE); release_firmware(firmware); return -1; } if (0 != memcmp(firmware->data, magic, 8)) { - pr_err("ERROR: Firmware magic mismatch, wrong file?\n"); + dev_err(dev->dev, + "ERROR: Firmware magic mismatch, wrong file?\n"); release_firmware(firmware); return -1; } @@ -1057,7 +1061,8 @@ static int cx231xx_load_firmware(struct cx231xx *dev) retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); if (retval < 0) { - pr_err("%s: Error with mc417_register_write\n", + dev_err(dev->dev, + "%s: Error with mc417_register_write\n", __func__); return retval; } @@ -1069,7 +1074,8 @@ static int cx231xx_load_firmware(struct cx231xx *dev) retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8); if (retval < 0) { - pr_err("%s: Error with mc417_register_write\n", + dev_err(dev->dev, + "%s: Error with mc417_register_write\n", __func__); return retval; } @@ -1114,28 +1120,31 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) cx231xx_disable656(dev); retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ if (retval < 0) { - dprintk(2, "%s() PING OK\n", __func__); + dprintk(2, "%s: PING OK\n", __func__); retval = cx231xx_load_firmware(dev); if (retval < 0) { - pr_err("%s() f/w load failed\n", __func__); + dev_err(dev->dev, + "%s: f/w load failed\n", __func__); return retval; } retval = cx231xx_find_mailbox(dev); if (retval < 0) { - pr_err("%s() mailbox < 0, error\n", + dev_err(dev->dev, "%s: mailbox < 0, error\n", __func__); return -1; } dev->cx23417_mailbox = retval; retval = cx231xx_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); if (retval < 0) { - pr_err("ERROR: cx23417 firmware ping failed!\n"); + dev_err(dev->dev, + "ERROR: cx23417 firmware ping failed!\n"); return -1; } retval = cx231xx_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, &version); if (retval < 0) { - pr_err("ERROR: cx23417 firmware get encoder: version failed!\n"); + dev_err(dev->dev, + "ERROR: cx23417 firmware get encoder: version failed!\n"); return -1; } dprintk(1, "cx23417 firmware version is 0x%08x\n", version); @@ -1416,8 +1425,9 @@ static int bb_buf_prepare(struct videobuf_queue *q, if (!dev->video_mode.bulk_ctl.num_bufs) urb_init = 1; } - /*cx231xx_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", - urb_init, dev->video_mode.max_pkt_size);*/ + dev_dbg(dev->dev, + "urb_init=%d dev->video_mode.max_pkt_size=%d\n", + urb_init, dev->video_mode.max_pkt_size); dev->mode_tv = 1; if (urb_init) { @@ -1688,7 +1698,7 @@ static int mpeg_open(struct file *file) sizeof(struct cx231xx_buffer), fh, &dev->lock); /* videobuf_queue_sg_init(&fh->vidq, &cx231xx_qops, - &dev->udev->dev, &dev->ts1.slock, + dev->dev, &dev->ts1.slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct cx231xx_buffer), @@ -1798,7 +1808,6 @@ static unsigned int mpeg_poll(struct file *file, static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) { struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; dprintk(2, "%s()\n", __func__); @@ -1878,7 +1887,7 @@ static int cx231xx_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) /* fix videodecoder resolution */ fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1); fmt.height = cxhdl->height; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; v4l2_subdev_call(dev->sd_cx25840, video, s_mbus_fmt, &fmt); return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index 9b925874d392..de4ae5eb4830 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -20,8 +20,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include <linux/kernel.h> -#include <linux/usb.h> #include <linux/init.h> #include <linux/sound.h> #include <linux/spinlock.h> @@ -37,25 +37,18 @@ #include <sound/initval.h> #include <sound/control.h> #include <media/v4l2-common.h> -#include "cx231xx.h" static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "activates debug info"); -#define dprintk(fmt, arg...) do { \ - if (debug) \ - printk(KERN_INFO "cx231xx-audio %s: " fmt, \ - __func__, ##arg); \ - } while (0) - static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static int cx231xx_isoc_audio_deinit(struct cx231xx *dev) { int i; - dprintk("Stopping isoc\n"); + dev_dbg(dev->dev, "Stopping isoc\n"); for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { if (dev->adev.urb[i]) { @@ -79,7 +72,7 @@ static int cx231xx_bulk_audio_deinit(struct cx231xx *dev) { int i; - dprintk("Stopping bulk\n"); + dev_dbg(dev->dev, "Stopping bulk\n"); for (i = 0; i < CX231XX_AUDIO_BUFS; i++) { if (dev->adev.urb[i]) { @@ -123,7 +116,8 @@ static void cx231xx_audio_isocirq(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - dprintk("urb completition error %d.\n", urb->status); + dev_dbg(dev->dev, "urb completition error %d.\n", + urb->status); break; } @@ -182,8 +176,9 @@ static void cx231xx_audio_isocirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { - cx231xx_errdev("resubmit of audio urb failed (error=%i)\n", - status); + dev_err(dev->dev, + "resubmit of audio urb failed (error=%i)\n", + status); } return; } @@ -211,7 +206,8 @@ static void cx231xx_audio_bulkirq(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - dprintk("urb completition error %d.\n", urb->status); + dev_dbg(dev->dev, "urb completition error %d.\n", + urb->status); break; } @@ -266,8 +262,9 @@ static void cx231xx_audio_bulkirq(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status < 0) { - cx231xx_errdev("resubmit of audio urb failed (error=%i)\n", - status); + dev_err(dev->dev, + "resubmit of audio urb failed (error=%i)\n", + status); } return; } @@ -277,7 +274,8 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) int i, errCode; int sb_size; - cx231xx_info("%s: Starting ISO AUDIO transfers\n", __func__); + dev_dbg(dev->dev, + "%s: Starting ISO AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) return -ENODEV; @@ -295,7 +293,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) memset(dev->adev.transfer_buffer[i], 0x80, sb_size); urb = usb_alloc_urb(CX231XX_ISO_NUM_AUDIO_PACKETS, GFP_ATOMIC); if (!urb) { - cx231xx_errdev("usb_alloc_urb failed!\n"); + dev_err(dev->dev, "usb_alloc_urb failed!\n"); for (j = 0; j < i; j++) { usb_free_urb(dev->adev.urb[j]); kfree(dev->adev.transfer_buffer[j]); @@ -338,7 +336,8 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) int i, errCode; int sb_size; - cx231xx_info("%s: Starting BULK AUDIO transfers\n", __func__); + dev_dbg(dev->dev, + "%s: Starting BULK AUDIO transfers\n", __func__); if (dev->state & DEV_DISCONNECTED) return -ENODEV; @@ -356,7 +355,7 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) memset(dev->adev.transfer_buffer[i], 0x80, sb_size); urb = usb_alloc_urb(CX231XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); if (!urb) { - cx231xx_errdev("usb_alloc_urb failed!\n"); + dev_err(dev->dev, "usb_alloc_urb failed!\n"); for (j = 0; j < i; j++) { usb_free_urb(dev->adev.urb[j]); kfree(dev->adev.transfer_buffer[j]); @@ -392,8 +391,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size) { struct snd_pcm_runtime *runtime = subs->runtime; + struct cx231xx *dev = snd_pcm_substream_chip(subs); - dprintk("Allocating vbuffer\n"); + dev_dbg(dev->dev, "Allocating vbuffer\n"); if (runtime->dma_area) { if (runtime->dma_bytes > size) return 0; @@ -436,16 +436,12 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int ret = 0; - dprintk("opening device and trying to acquire exclusive lock\n"); - - if (!dev) { - cx231xx_errdev("BUG: cx231xx can't find device struct." - " Can't proceed with open\n"); - return -ENODEV; - } + dev_dbg(dev->dev, + "opening device and trying to acquire exclusive lock\n"); if (dev->state & DEV_DISCONNECTED) { - cx231xx_errdev("Can't open. the device was removed.\n"); + dev_err(dev->dev, + "Can't open. the device was removed.\n"); return -ENODEV; } @@ -458,7 +454,8 @@ static int snd_cx231xx_capture_open(struct snd_pcm_substream *substream) ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); mutex_unlock(&dev->lock); if (ret < 0) { - cx231xx_errdev("failed to set alternate setting !\n"); + dev_err(dev->dev, + "failed to set alternate setting !\n"); return ret; } @@ -484,7 +481,7 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) int ret; struct cx231xx *dev = snd_pcm_substream_chip(substream); - dprintk("closing device\n"); + dev_dbg(dev->dev, "closing device\n"); /* inform hardware to stop streaming */ mutex_lock(&dev->lock); @@ -494,7 +491,8 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) /* 1 - 48000 samples per sec */ ret = cx231xx_set_alt_setting(dev, INDEX_AUDIO, 0); if (ret < 0) { - cx231xx_errdev("failed to set alternate setting !\n"); + dev_err(dev->dev, + "failed to set alternate setting !\n"); mutex_unlock(&dev->lock); return ret; @@ -504,10 +502,10 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) mutex_unlock(&dev->lock); if (dev->adev.users == 0 && dev->adev.shutdown == 1) { - dprintk("audio users: %d\n", dev->adev.users); - dprintk("disabling audio stream!\n"); + dev_dbg(dev->dev, "audio users: %d\n", dev->adev.users); + dev_dbg(dev->dev, "disabling audio stream!\n"); dev->adev.shutdown = 0; - dprintk("released lock\n"); + dev_dbg(dev->dev, "released lock\n"); if (atomic_read(&dev->stream_started) > 0) { atomic_set(&dev->stream_started, 0); schedule_work(&dev->wq_trigger); @@ -519,9 +517,10 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { + struct cx231xx *dev = snd_pcm_substream_chip(substream); int ret; - dprintk("Setting capture parameters\n"); + dev_dbg(dev->dev, "Setting capture parameters\n"); ret = snd_pcm_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); @@ -543,7 +542,7 @@ static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream) { struct cx231xx *dev = snd_pcm_substream_chip(substream); - dprintk("Stop capture, if needed\n"); + dev_dbg(dev->dev, "Stop capture, if needed\n"); if (atomic_read(&dev->stream_started) > 0) { atomic_set(&dev->stream_started, 0); @@ -568,7 +567,7 @@ static void audio_trigger(struct work_struct *work) struct cx231xx *dev = container_of(work, struct cx231xx, wq_trigger); if (atomic_read(&dev->stream_started)) { - dprintk("starting capture"); + dev_dbg(dev->dev, "starting capture"); if (is_fw_load(dev) == 0) cx25840_call(dev, core, load_fw); if (dev->USE_ISO) @@ -576,7 +575,7 @@ static void audio_trigger(struct work_struct *work) else cx231xx_init_audio_bulk(dev); } else { - dprintk("stopping capture"); + dev_dbg(dev->dev, "stopping capture"); cx231xx_isoc_audio_deinit(dev); } } @@ -662,10 +661,10 @@ static int cx231xx_audio_init(struct cx231xx *dev) return 0; } - cx231xx_info("cx231xx-audio.c: probing for cx231xx " - "non standard usbaudio\n"); + dev_dbg(dev->dev, + "probing for cx231xx non standard usbaudio\n"); - err = snd_card_new(&dev->udev->dev, index[devnr], "Cx231xx Audio", + err = snd_card_new(dev->dev, index[devnr], "Cx231xx Audio", THIS_MODULE, 0, &card); if (err < 0) return err; @@ -707,14 +706,13 @@ static int cx231xx_audio_init(struct cx231xx *dev) bEndpointAddress; adev->num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", - adev->end_point_addr, adev->num_alt); + dev_info(dev->dev, + "audio EndPoint Addr 0x%x, Alternate settings: %i\n", + adev->end_point_addr, adev->num_alt); adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL); - if (adev->alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); + if (adev->alt_max_pkt_size == NULL) return -ENOMEM; - } for (i = 0; i < adev->num_alt; i++) { u16 tmp = @@ -722,8 +720,9 @@ static int cx231xx_audio_init(struct cx231xx *dev) wMaxPacketSize); adev->alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, - adev->alt_max_pkt_size[i]); + dev_dbg(dev->dev, + "audio alternate setting %i, max size= %i\n", i, + adev->alt_max_pkt_size[i]); } return 0; diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 40a69879fc0a..39e887925e3d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -22,12 +22,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include <linux/init.h> #include <linux/list.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/bitmap.h> -#include <linux/usb.h> #include <linux/i2c.h> #include <linux/mm.h> #include <linux/mutex.h> @@ -36,7 +36,6 @@ #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> -#include "cx231xx.h" #include "cx231xx-dif.h" #define TUNER_MODE_FM_RADIO 0 @@ -83,10 +82,10 @@ void initGPIO(struct cx231xx *dev) cx231xx_send_gpio_cmd(dev, _gpio_direction, (u8 *)&value, 4, 0, 0); verve_read_byte(dev, 0x07, &val); - cx231xx_info(" verve_read_byte address0x07=0x%x\n", val); + dev_dbg(dev->dev, "verve_read_byte address0x07=0x%x\n", val); verve_write_byte(dev, 0x07, 0xF4); verve_read_byte(dev, 0x07, &val); - cx231xx_info(" verve_read_byte address0x07=0x%x\n", val); + dev_dbg(dev->dev, "verve_read_byte address0x07=0x%x\n", val); cx231xx_capture_start(dev, 1, Vbi); @@ -156,22 +155,25 @@ int cx231xx_afe_init_super_block(struct cx231xx *dev, u32 ref_count) while (afe_power_status != 0x18) { status = afe_write_byte(dev, SUP_BLK_PWRDN, 0x18); if (status < 0) { - cx231xx_info( - ": Init Super Block failed in send cmd\n"); + dev_dbg(dev->dev, + "%s: Init Super Block failed in send cmd\n", + __func__); break; } status = afe_read_byte(dev, SUP_BLK_PWRDN, &afe_power_status); afe_power_status &= 0xff; if (status < 0) { - cx231xx_info( - ": Init Super Block failed in receive cmd\n"); + dev_dbg(dev->dev, + "%s: Init Super Block failed in receive cmd\n", + __func__); break; } i++; if (i == 10) { - cx231xx_info( - ": Init Super Block force break in loop !!!!\n"); + dev_dbg(dev->dev, + "%s: Init Super Block force break in loop !!!!\n", + __func__); status = -1; break; } @@ -410,7 +412,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x00); } else { - cx231xx_info("Invalid AV mode input\n"); + dev_dbg(dev->dev, "Invalid AV mode input\n"); status = -1; } break; @@ -467,7 +469,7 @@ int cx231xx_afe_update_power_control(struct cx231xx *dev, status |= afe_write_byte(dev, ADC_PWRDN_CLAMP_CH3, 0x40); } else { - cx231xx_info("Invalid AV mode input\n"); + dev_dbg(dev->dev, "Invalid AV mode input\n"); status = -1; } } /* switch */ @@ -573,9 +575,9 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) status = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ENXTERNAL_AV); if (status < 0) { - cx231xx_errdev("%s: set_power_mode : Failed to" - " set Power - errCode [%d]!\n", - __func__, status); + dev_err(dev->dev, + "%s: Failed to set Power - errCode [%d]!\n", + __func__, status); return status; } } @@ -591,8 +593,8 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) status = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); if (status < 0) { - cx231xx_errdev("%s: set_power_mode:Failed" - " to set Power - errCode [%d]!\n", + dev_err(dev->dev, + "%s: Failed to set Power - errCode [%d]!\n", __func__, status); return status; } @@ -608,8 +610,8 @@ int cx231xx_set_video_input_mux(struct cx231xx *dev, u8 input) break; default: - cx231xx_errdev("%s: set_power_mode : Unknown Input %d !\n", - __func__, INPUT(input)->type); + dev_err(dev->dev, "%s: Unknown Input %d !\n", + __func__, INPUT(input)->type); break; } @@ -628,8 +630,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, if (pin_type != dev->video_input) { status = cx231xx_afe_adjust_ref_count(dev, pin_type); if (status < 0) { - cx231xx_errdev("%s: adjust_ref_count :Failed to set" - "AFE input mux - errCode [%d]!\n", + dev_err(dev->dev, + "%s: adjust_ref_count :Failed to set AFE input mux - errCode [%d]!\n", __func__, status); return status; } @@ -638,9 +640,9 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* call afe block to set video inputs */ status = cx231xx_afe_set_input_mux(dev, input); if (status < 0) { - cx231xx_errdev("%s: set_input_mux :Failed to set" - " AFE input mux - errCode [%d]!\n", - __func__, status); + dev_err(dev->dev, + "%s: set_input_mux :Failed to set AFE input mux - errCode [%d]!\n", + __func__, status); return status; } @@ -670,8 +672,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - cx231xx_errdev("%s: cx231xx_dif set to By pass" - " mode- errCode [%d]!\n", + dev_err(dev->dev, + "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; } @@ -715,8 +717,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Tell DIF object to go to baseband mode */ status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - cx231xx_errdev("%s: cx231xx_dif set to By pass" - " mode- errCode [%d]!\n", + dev_err(dev->dev, + "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", __func__, status); return status; } @@ -790,9 +792,9 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, status = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (status < 0) { - cx231xx_errdev("%s: cx231xx_dif set to By pass" - " mode- errCode [%d]!\n", - __func__, status); + dev_err(dev->dev, + "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", + __func__, status); return status; } @@ -826,9 +828,9 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev, /* Reinitialize the DIF */ status = cx231xx_dif_set_standard(dev, dev->norm); if (status < 0) { - cx231xx_errdev("%s: cx231xx_dif set to By pass" - " mode- errCode [%d]!\n", - __func__, status); + dev_err(dev->dev, + "%s: cx231xx_dif set to By pass mode- errCode [%d]!\n", + __func__, status); return status; } @@ -970,14 +972,14 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) { int status = 0; - cx231xx_info("do_mode_ctrl_overrides : 0x%x\n", - (unsigned int)dev->norm); + dev_dbg(dev->dev, "%s: 0x%x\n", + __func__, (unsigned int)dev->norm); /* Change the DFE_CTRL3 bp_percent to fix flagging */ status = vid_blk_write_word(dev, DFE_CTRL3, 0xCD3F0280); if (dev->norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) { - cx231xx_info("do_mode_ctrl_overrides NTSC\n"); + dev_dbg(dev->dev, "%s: NTSC\n", __func__); /* Move the close caption lines out of active video, adjust the active video start point */ @@ -1004,7 +1006,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) (FLD_HBLANK_CNT, 0x79)); } else if (dev->norm & V4L2_STD_SECAM) { - cx231xx_info("do_mode_ctrl_overrides SECAM\n"); + dev_dbg(dev->dev, "%s: SECAM\n", __func__); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1031,7 +1033,7 @@ int cx231xx_do_mode_ctrl_overrides(struct cx231xx *dev) cx231xx_set_field (FLD_HBLANK_CNT, 0x85)); } else { - cx231xx_info("do_mode_ctrl_overrides PAL\n"); + dev_dbg(dev->dev, "%s: PAL\n", __func__); status = cx231xx_read_modify_write_i2c_dword(dev, VID_BLK_I2C_ADDRESS, VERT_TIM_CTRL, @@ -1206,7 +1208,8 @@ int cx231xx_set_audio_decoder_input(struct cx231xx *dev, /* This is just a casual suggestion to people adding new boards in case they use a tuner type we don't currently know about */ - printk(KERN_INFO "Unknown tuner type configuring SIF"); + dev_info(dev->dev, + "Unknown tuner type configuring SIF"); break; } break; @@ -1270,8 +1273,13 @@ 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; + /* + * Should this code check dev->port_3_switch_enabled first + * to skip unnecessary reading of the register? + * If yes, the flag dev->port_3_switch_enabled must be initialized + * correctly. + */ + status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, 4); if (status < 0) @@ -1288,12 +1296,13 @@ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3) else value[0] &= ~I2C_DEMOD_EN; - cx231xx_info("Changing the i2c master port to %d\n", - is_port_3 ? 3 : 1); - status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, PWR_CTL_EN, value, 4); + /* remember status of the switch for usage in is_tuner */ + if (status >= 0) + dev->port_3_switch_enabled = is_port_3; + return status; } @@ -1325,113 +1334,131 @@ void cx231xx_dump_HH_reg(struct cx231xx *dev) for (i = 0x100; i < 0x140; i++) { vid_blk_read_word(dev, i, &value); - cx231xx_info("reg0x%x=0x%x\n", i, value); + dev_dbg(dev->dev, "reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x300; i < 0x400; i++) { vid_blk_read_word(dev, i, &value); - cx231xx_info("reg0x%x=0x%x\n", i, value); + dev_dbg(dev->dev, "reg0x%x=0x%x\n", i, value); i = i+3; } for (i = 0x400; i < 0x440; i++) { vid_blk_read_word(dev, i, &value); - cx231xx_info("reg0x%x=0x%x\n", i, value); + dev_dbg(dev->dev, "reg0x%x=0x%x\n", i, value); i = i+3; } vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + dev_dbg(dev->dev, "AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); vid_blk_write_word(dev, AFE_CTRL_C2HH_SRC_CTRL, 0x4485D390); vid_blk_read_word(dev, AFE_CTRL_C2HH_SRC_CTRL, &value); - cx231xx_info("AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); + dev_dbg(dev->dev, "AFE_CTRL_C2HH_SRC_CTRL=0x%x\n", value); } -void cx231xx_dump_SC_reg(struct cx231xx *dev) +#if 0 +static void cx231xx_dump_SC_reg(struct cx231xx *dev) { u8 value[4] = { 0, 0, 0, 0 }; - cx231xx_info("cx231xx_dump_SC_reg!\n"); + dev_dbg(dev->dev, "%s!\n", __func__); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", BOARD_CFG_STAT, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS_MODE_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS_MODE_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_CFG_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_CFG_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS1_LENGTH_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS1_LENGTH_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_CFG_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_CFG_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, TS2_LENGTH_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", TS2_LENGTH_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", EP_MODE_SET, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN1, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN1, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN2, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN2, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_PTN3, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_PTN3, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK0, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK0, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK1, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK1, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_PWR_MASK2, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_PWR_MASK2, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_GAIN, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_GAIN, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_CAR_REG, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_CAR_REG, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG1, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG1, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, CIR_OT_CFG2, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], - value[1], value[2], value[3]); + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", CIR_OT_CFG2, value[0], + value[1], value[2], value[3]); cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, PWR_CTL_EN, value, 4); - cx231xx_info("reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], - value[1], value[2], value[3]); - - + dev_dbg(dev->dev, + "reg0x%x=0x%x 0x%x 0x%x 0x%x\n", PWR_CTL_EN, value[0], + value[1], value[2], value[3]); } +#endif void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev) @@ -1497,7 +1524,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, u32 standard = 0; u8 value[4] = { 0, 0, 0, 0 }; - cx231xx_info("Enter cx231xx_set_Colibri_For_LowIF()\n"); + dev_dbg(dev->dev, "Enter cx231xx_set_Colibri_For_LowIF()\n"); value[0] = (u8) 0x6F; value[1] = (u8) 0x6F; value[2] = (u8) 0x6F; @@ -1517,7 +1544,7 @@ void cx231xx_set_Colibri_For_LowIF(struct cx231xx *dev, u32 if_freq, colibri_carrier_offset = cx231xx_Get_Colibri_CarrierOffset(mode, standard); - cx231xx_info("colibri_carrier_offset=%d, standard=0x%x\n", + dev_dbg(dev->dev, "colibri_carrier_offset=%d, standard=0x%x\n", colibri_carrier_offset, standard); /* Set the band Pass filter for DIF*/ @@ -1551,8 +1578,8 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, u64 pll_freq_u64 = 0; u32 i = 0; - cx231xx_info("if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", - if_freq, spectral_invert, mode); + dev_dbg(dev->dev, "if_freq=%d;spectral_invert=0x%x;mode=0x%x\n", + if_freq, spectral_invert, mode); if (mode == TUNER_MODE_FM_RADIO) { @@ -1595,8 +1622,7 @@ void cx231xx_set_DIF_bandpass(struct cx231xx *dev, u32 if_freq, if_freq = 16000000; } - cx231xx_info("Enter IF=%zu\n", - ARRAY_SIZE(Dif_set_array)); + dev_dbg(dev->dev, "Enter IF=%zu\n", ARRAY_SIZE(Dif_set_array)); for (i = 0; i < ARRAY_SIZE(Dif_set_array); i++) { if (Dif_set_array[i].if_freq == if_freq) { vid_blk_write_word(dev, @@ -1708,7 +1734,7 @@ int cx231xx_dif_set_standard(struct cx231xx *dev, u32 standard) u32 dif_misc_ctrl_value = 0; u32 func_mode = 0; - cx231xx_info("%s: setStandard to %x\n", __func__, standard); + dev_dbg(dev->dev, "%s: setStandard to %x\n", __func__, standard); status = vid_blk_read_word(dev, DIF_MISC_CTRL, &dif_misc_ctrl_value); if (standard != DIF_USE_BASEBAND) @@ -2111,8 +2137,8 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev) { int status = 0; u32 dwval; - cx231xx_info("cx231xx_tuner_post_channel_change dev->tuner_type =0%d\n", - dev->tuner_type); + dev_dbg(dev->dev, "%s: dev->tuner_type =0%d\n", + __func__, dev->tuner_type); /* Set the RF and IF k_agc values to 4 for PAL/NTSC and 8 for * SECAM L/B/D standards */ status = vid_blk_read_word(dev, DIF_AGC_IF_REF, &dwval); @@ -2213,8 +2239,8 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) if (dev->power_mode != mode) dev->power_mode = mode; else { - cx231xx_info(" setPowerMode::mode = %d, No Change req.\n", - mode); + dev_dbg(dev->dev, "%s: mode = %d, No Change req.\n", + __func__, mode); return 0; } @@ -2264,7 +2290,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) case POLARIS_AVMODE_ANALOGT_TV: tmp |= PWR_DEMOD_EN; - tmp |= (I2C_DEMOD_EN); value[0] = (u8) tmp; value[1] = (u8) (tmp >> 8); value[2] = (u8) (tmp >> 16); @@ -2317,9 +2342,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) } if (dev->board.tuner_type != TUNER_ABSENT) { - /* Enable tuner */ - cx231xx_enable_i2c_port_3(dev, true); - /* reset the Tuner */ if (dev->board.tuner_gpio) cx231xx_gpio_set(dev, dev->board.tuner_gpio); @@ -2363,7 +2385,7 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) } tmp &= (~PWR_AV_MODE); - tmp |= POLARIS_AVMODE_DIGITAL | I2C_DEMOD_EN; + tmp |= POLARIS_AVMODE_DIGITAL; value[0] = (u8) tmp; value[1] = (u8) (tmp >> 8); value[2] = (u8) (tmp >> 16); @@ -2384,15 +2406,6 @@ int cx231xx_set_power_mode(struct cx231xx *dev, enum AV_MODE mode) } if (dev->board.tuner_type != TUNER_ABSENT) { - /* - * Enable tuner - * Hauppauge Exeter seems to need to do something different! - */ - if (dev->model == CX231XX_BOARD_HAUPPAUGE_EXETER) - cx231xx_enable_i2c_port_3(dev, false); - else - cx231xx_enable_i2c_port_3(dev, true); - /* reset the Tuner */ if (dev->board.tuner_gpio) cx231xx_gpio_set(dev, dev->board.tuner_gpio); @@ -2466,7 +2479,7 @@ int cx231xx_start_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - cx231xx_info("cx231xx_start_stream():: ep_mask = %x\n", ep_mask); + dev_dbg(dev->dev, "%s: ep_mask = %x\n", __func__, ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2491,7 +2504,7 @@ int cx231xx_stop_stream(struct cx231xx *dev, u32 ep_mask) u32 tmp = 0; int status = 0; - cx231xx_info("cx231xx_stop_stream():: ep_mask = %x\n", ep_mask); + dev_dbg(dev->dev, "%s: ep_mask = %x\n", __func__, ep_mask); status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, EP_MODE_SET, value, 4); if (status < 0) @@ -2519,61 +2532,72 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type) if (dev->udev->speed == USB_SPEED_HIGH) { switch (media_type) { case Audio: - cx231xx_info("%s: Audio enter HANC\n", __func__); + dev_dbg(dev->dev, + "%s: Audio enter HANC\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x9300); break; case Vbi: - cx231xx_info("%s: set vanc registers\n", __func__); + dev_dbg(dev->dev, + "%s: set vanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300); break; case Sliced_cc: - cx231xx_info("%s: set hanc registers\n", __func__); + dev_dbg(dev->dev, + "%s: set hanc registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x1300); break; case Raw_Video: - cx231xx_info("%s: set video registers\n", __func__); + dev_dbg(dev->dev, + "%s: set video registers\n", __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); break; case TS1_serial_mode: - cx231xx_info("%s: set ts1 registers", __func__); - - if (dev->board.has_417) { - cx231xx_info(" MPEG\n"); - value &= 0xFFFFFFFC; - value |= 0x3; - - status = cx231xx_mode_register(dev, TS_MODE_REG, value); - - val[0] = 0x04; - val[1] = 0xA3; - val[2] = 0x3B; - val[3] = 0x00; - status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, - TS1_CFG_REG, val, 4); - - val[0] = 0x00; - val[1] = 0x08; - val[2] = 0x00; - val[3] = 0x08; - status = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER, - TS1_LENGTH_REG, val, 4); - - } else { - cx231xx_info(" BDA\n"); - status = cx231xx_mode_register(dev, TS_MODE_REG, 0x101); - status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x010); - } + dev_dbg(dev->dev, + "%s: set ts1 registers", __func__); + + if (dev->board.has_417) { + dev_dbg(dev->dev, + "%s: MPEG\n", __func__); + value &= 0xFFFFFFFC; + value |= 0x3; + + status = cx231xx_mode_register(dev, + TS_MODE_REG, value); + + val[0] = 0x04; + val[1] = 0xA3; + val[2] = 0x3B; + val[3] = 0x00; + status = cx231xx_write_ctrl_reg(dev, + VRT_SET_REGISTER, + TS1_CFG_REG, val, 4); + + val[0] = 0x00; + val[1] = 0x08; + val[2] = 0x00; + val[3] = 0x08; + status = cx231xx_write_ctrl_reg(dev, + VRT_SET_REGISTER, + TS1_LENGTH_REG, val, 4); + } else { + dev_dbg(dev->dev, "%s: BDA\n", __func__); + status = cx231xx_mode_register(dev, + TS_MODE_REG, 0x101); + status = cx231xx_mode_register(dev, + TS1_CFG_REG, 0x010); + } break; case TS1_parallel_mode: - cx231xx_info("%s: set ts1 parallel mode registers\n", - __func__); + dev_dbg(dev->dev, + "%s: set ts1 parallel mode registers\n", + __func__); status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100); status = cx231xx_mode_register(dev, TS1_CFG_REG, 0x400); break; @@ -2926,8 +2950,9 @@ int cx231xx_gpio_i2c_read_ack(struct cx231xx *dev) (nCnt > 0)); if (nCnt == 0) - cx231xx_info("No ACK after %d msec -GPIO I2C failed!", - nInit * 10); + dev_dbg(dev->dev, + "No ACK after %d msec -GPIO I2C failed!", + nInit * 10); /* * readAck diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 791f00c6276b..ae05d591f228 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -20,12 +20,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include <linux/init.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/delay.h> #include <linux/i2c.h> -#include <linux/usb.h> #include <media/tuner.h> #include <media/tveeprom.h> #include <media/v4l2-common.h> @@ -35,7 +35,6 @@ #include "xc5000.h" #include "tda18271.h" -#include "cx231xx.h" static int tuner = -1; module_param(tuner, int, 0444); @@ -104,8 +103,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, .norm = V4L2_STD_PAL, @@ -144,8 +143,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x32, .norm = V4L2_STD_NTSC, @@ -184,8 +183,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x1c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, .norm = V4L2_STD_PAL, @@ -225,8 +224,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x1c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, .norm = V4L2_STD_PAL, @@ -262,7 +261,6 @@ struct cx231xx_board cx231xx_boards[] = { .norm = V4L2_STD_PAL, .no_alt_vanc = 1, .external_av = 1, - .dont_use_port_3 = 1, /* Actually, it has a 417, but it isn't working correctly. * So set to 0 for now until someone can manage to get this * to work reliably. */ @@ -297,8 +295,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x02, .norm = V4L2_STD_PAL, @@ -325,8 +323,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x32, .norm = V4L2_STD_NTSC, @@ -353,8 +351,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1_MUX_1, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x0e, .norm = V4L2_STD_NTSC, @@ -390,7 +388,6 @@ struct cx231xx_board cx231xx_boards[] = { .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, @@ -418,9 +415,9 @@ struct cx231xx_board cx231xx_boards[] = { .tuner_scl_gpio = -1, .tuner_sda_gpio = -1, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 2, - .demod_i2c_master = 1, - .ir_i2c_master = 2, + .tuner_i2c_master = I2C_2, + .demod_i2c_master = I2C_1_MUX_3, + .ir_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x10, .norm = V4L2_STD_PAL_M, @@ -456,9 +453,9 @@ struct cx231xx_board cx231xx_boards[] = { .tuner_scl_gpio = -1, .tuner_sda_gpio = -1, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 2, - .demod_i2c_master = 1, - .ir_i2c_master = 2, + .tuner_i2c_master = I2C_2, + .demod_i2c_master = I2C_1_MUX_3, + .ir_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x10, .norm = V4L2_STD_NTSC_M, @@ -494,9 +491,9 @@ struct cx231xx_board cx231xx_boards[] = { .tuner_scl_gpio = -1, .tuner_sda_gpio = -1, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 2, - .demod_i2c_master = 1, - .ir_i2c_master = 2, + .tuner_i2c_master = I2C_2, + .demod_i2c_master = I2C_1_MUX_3, + .ir_i2c_master = I2C_2, .rc_map_name = RC_MAP_PIXELVIEW_002T, .has_dvb = 1, .demod_addr = 0x10, @@ -532,7 +529,6 @@ struct cx231xx_board cx231xx_boards[] = { .norm = V4L2_STD_NTSC, .no_alt_vanc = 1, .external_av = 1, - .dont_use_port_3 = 1, .input = {{ .type = CX231XX_VMUX_COMPOSITE1, @@ -587,7 +583,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, + .tuner_i2c_master = I2C_1_MUX_3, .norm = V4L2_STD_PAL, .input = {{ @@ -622,7 +618,7 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, + .tuner_i2c_master = I2C_1_MUX_3, .norm = V4L2_STD_NTSC, .input = {{ @@ -656,7 +652,6 @@ struct cx231xx_board cx231xx_boards[] = { .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, @@ -677,13 +672,12 @@ struct cx231xx_board cx231xx_boards[] = { .decoder = CX231XX_AVDECODER, .output_mode = OUT_MODE_VIP11, .ctl_pin_status_mask = 0xFFFFFFC4, - .agc_analog_digital_select_gpio = 0x0c, + .agc_analog_digital_select_gpio = 0x0c, /* According with PV CxPlrCAP.inf file */ .gpio_pin_status_mask = 0x4001000, .norm = V4L2_STD_NTSC, .no_alt_vanc = 1, .external_av = 1, - .dont_use_port_3 = 1, /*.has_417 = 1, */ /* This board is believed to have a hardware encoding chip * supporting mpeg1/2/4, but as the 417 is apparently not @@ -718,8 +712,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x0e, .norm = V4L2_STD_PAL, @@ -757,8 +751,8 @@ struct cx231xx_board cx231xx_boards[] = { .ctl_pin_status_mask = 0xFFFFFFC4, .agc_analog_digital_select_gpio = 0x0c, .gpio_pin_status_mask = 0x4001000, - .tuner_i2c_master = 1, - .demod_i2c_master = 2, + .tuner_i2c_master = I2C_1_MUX_3, + .demod_i2c_master = I2C_2, .has_dvb = 1, .demod_addr = 0x0e, .norm = V4L2_STD_PAL, @@ -861,9 +855,9 @@ int cx231xx_tuner_callback(void *ptr, int component, int command, int arg) if (dev->tuner_type == TUNER_XC5000) { if (command == XC5000_TUNER_RESET) { - cx231xx_info - ("Tuner CB: RESET: cmd %d : tuner type %d \n", - command, dev->tuner_type); + dev_dbg(dev->dev, + "Tuner CB: RESET: cmd %d : tuner type %d\n", + command, dev->tuner_type); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); msleep(10); @@ -921,8 +915,8 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) cx231xx_set_model(dev); - cx231xx_info("Identified as %s (card=%d)\n", - dev->board.name, dev->model); + dev_info(dev->dev, "Identified as %s (card=%d)\n", + dev->board.name, dev->model); /* set the direction for GPIO pins */ if (dev->board.tuner_gpio) { @@ -980,25 +974,22 @@ static void cx231xx_config_tuner(struct cx231xx *dev) } -static int read_eeprom(struct cx231xx *dev, u8 *eedata, int len) +static int read_eeprom(struct cx231xx *dev, struct i2c_client *client, + u8 *eedata, int len) { int ret = 0; - u8 addr = 0xa0 >> 1; u8 start_offset = 0; int len_todo = len; u8 *eedata_cur = eedata; int i; - struct i2c_msg msg_write = { .addr = addr, .flags = 0, + struct i2c_msg msg_write = { .addr = client->addr, .flags = 0, .buf = &start_offset, .len = 1 }; - struct i2c_msg msg_read = { .addr = addr, .flags = I2C_M_RD }; - - /* mutex_lock(&dev->i2c_lock); */ - cx231xx_enable_i2c_port_3(dev, false); + struct i2c_msg msg_read = { .addr = client->addr, .flags = I2C_M_RD }; /* start reading at offset 0 */ - ret = i2c_transfer(&dev->i2c_bus[1].i2c_adap, &msg_write, 1); + ret = i2c_transfer(client->adapter, &msg_write, 1); if (ret < 0) { - cx231xx_err("Can't read eeprom\n"); + dev_err(dev->dev, "Can't read eeprom\n"); return ret; } @@ -1006,20 +997,18 @@ static int read_eeprom(struct cx231xx *dev, u8 *eedata, int len) msg_read.len = (len_todo > 64) ? 64 : len_todo; msg_read.buf = eedata_cur; - ret = i2c_transfer(&dev->i2c_bus[1].i2c_adap, &msg_read, 1); + ret = i2c_transfer(client->adapter, &msg_read, 1); if (ret < 0) { - cx231xx_err("Can't read eeprom\n"); + dev_err(dev->dev, "Can't read eeprom\n"); return ret; } eedata_cur += msg_read.len; len_todo -= msg_read.len; } - cx231xx_enable_i2c_port_3(dev, true); - /* mutex_unlock(&dev->i2c_lock); */ - for (i = 0; i + 15 < len; i += 16) - cx231xx_info("i2c eeprom %02x: %*ph\n", i, 16, &eedata[i]); + dev_dbg(dev->dev, "i2c eeprom %02x: %*ph\n", + i, 16, &eedata[i]); return 0; } @@ -1036,22 +1025,26 @@ void cx231xx_card_setup(struct cx231xx *dev) /* request some modules */ if (dev->board.decoder == CX231XX_AVDECODER) { dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_bus[0].i2c_adap, + cx231xx_get_i2c_adap(dev, I2C_0), "cx25840", 0x88 >> 1, NULL); if (dev->sd_cx25840 == NULL) - cx231xx_info("cx25840 subdev registration failure\n"); + dev_err(dev->dev, + "cx25840 subdev registration failure\n"); cx25840_call(dev, core, load_fw); } /* Initialize the tuner */ if (dev->board.tuner_type != TUNER_ABSENT) { + struct i2c_adapter *tuner_i2c = cx231xx_get_i2c_adap(dev, + dev->board.tuner_i2c_master); dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, "tuner", dev->tuner_addr, NULL); if (dev->sd_tuner == NULL) - cx231xx_info("tuner subdev registration failure\n"); + dev_err(dev->dev, + "tuner subdev registration failure\n"); else cx231xx_config_tuner(dev); } @@ -1062,9 +1055,14 @@ void cx231xx_card_setup(struct cx231xx *dev) { struct tveeprom tvee; static u8 eeprom[256]; + struct i2c_client client; + + memset(&client, 0, sizeof(client)); + client.adapter = cx231xx_get_i2c_adap(dev, I2C_1_MUX_1); + client.addr = 0xa0 >> 1; - read_eeprom(dev, eeprom, sizeof(eeprom)); - tveeprom_hauppauge_analog(&dev->i2c_bus[1].i2c_client, + read_eeprom(dev, &client, eeprom, sizeof(eeprom)); + tveeprom_hauppauge_analog(&client, &tvee, eeprom + 0xc0); break; } @@ -1152,7 +1150,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, /* Query cx231xx to find what pcb config it is related to */ retval = initialize_cx231xx(dev); if (retval < 0) { - cx231xx_errdev("Failed to read PCB config\n"); + dev_err(dev->dev, "Failed to read PCB config\n"); return retval; } @@ -1168,7 +1166,7 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, retval = cx231xx_config(dev); if (retval) { - cx231xx_errdev("error configuring device\n"); + dev_err(dev->dev, "error configuring device\n"); return -ENOMEM; } @@ -1178,8 +1176,9 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, /* register i2c bus */ retval = cx231xx_dev_init(dev); if (retval) { - cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n", - __func__, retval); + dev_err(dev->dev, + "%s: cx231xx_i2c_register - errCode [%d]!\n", + __func__, retval); goto err_dev_init; } @@ -1200,8 +1199,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, retval = cx231xx_config(dev); if (retval) { - cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n", - __func__, retval); + dev_err(dev->dev, "%s: cx231xx_config - errCode [%d]!\n", + __func__, retval); goto err_dev_init; } @@ -1217,11 +1216,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, cx231xx_add_into_devlist(dev); if (dev->board.has_417) { - printk(KERN_INFO "attach 417 %d\n", dev->model); + dev_info(dev->dev, "attach 417 %d\n", dev->model); if (cx231xx_417_register(dev) < 0) { - printk(KERN_ERR + dev_err(dev->dev, "%s() Failed to register 417 on VID_B\n", - __func__); + __func__); } } @@ -1285,7 +1284,8 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, /* compute alternate max packet sizes for video */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.video_index + 1; if (idx >= dev->max_iad_interface_count) { - cx231xx_errdev("Video PCB interface #%d doesn't exist\n", idx); + dev_err(dev->dev, + "Video PCB interface #%d doesn't exist\n", idx); return -ENODEV; } @@ -1294,28 +1294,29 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, dev->video_mode.end_point_addr = uif->altsetting[0].endpoint[isoc_pipe].desc.bEndpointAddress; dev->video_mode.num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", - dev->video_mode.end_point_addr, - dev->video_mode.num_alt); + dev_info(dev->dev, + "video EndPoint Addr 0x%x, Alternate settings: %i\n", + dev->video_mode.end_point_addr, + dev->video_mode.num_alt); dev->video_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->video_mode.num_alt, GFP_KERNEL); - if (dev->video_mode.alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); + if (dev->video_mode.alt_max_pkt_size == NULL) return -ENOMEM; - } for (i = 0; i < dev->video_mode.num_alt; i++) { u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); dev->video_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, - dev->video_mode.alt_max_pkt_size[i]); + dev_dbg(dev->dev, + "Alternate setting %i, max size= %i\n", i, + dev->video_mode.alt_max_pkt_size[i]); } /* VBI Init */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.vanc_index + 1; if (idx >= dev->max_iad_interface_count) { - cx231xx_errdev("VBI PCB interface #%d doesn't exist\n", idx); + dev_err(dev->dev, + "VBI PCB interface #%d doesn't exist\n", idx); return -ENODEV; } uif = udev->actconfig->interface[idx]; @@ -1325,16 +1326,15 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->vbi_mode.num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", - dev->vbi_mode.end_point_addr, - dev->vbi_mode.num_alt); + dev_info(dev->dev, + "VBI EndPoint Addr 0x%x, Alternate settings: %i\n", + dev->vbi_mode.end_point_addr, + dev->vbi_mode.num_alt); /* compute alternate max packet sizes for vbi */ dev->vbi_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->vbi_mode.num_alt, GFP_KERNEL); - if (dev->vbi_mode.alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); + if (dev->vbi_mode.alt_max_pkt_size == NULL) return -ENOMEM; - } for (i = 0; i < dev->vbi_mode.num_alt; i++) { u16 tmp = @@ -1342,8 +1342,9 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, desc.wMaxPacketSize); dev->vbi_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, - dev->vbi_mode.alt_max_pkt_size[i]); + dev_dbg(dev->dev, + "Alternate setting %i, max size= %i\n", i, + dev->vbi_mode.alt_max_pkt_size[i]); } /* Sliced CC VBI init */ @@ -1351,7 +1352,8 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, /* compute alternate max packet sizes for sliced CC */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.hanc_index + 1; if (idx >= dev->max_iad_interface_count) { - cx231xx_errdev("Sliced CC PCB interface #%d doesn't exist\n", idx); + dev_err(dev->dev, + "Sliced CC PCB interface #%d doesn't exist\n", idx); return -ENODEV; } uif = udev->actconfig->interface[idx]; @@ -1361,23 +1363,22 @@ static int cx231xx_init_v4l2(struct cx231xx *dev, bEndpointAddress; dev->sliced_cc_mode.num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", - dev->sliced_cc_mode.end_point_addr, - dev->sliced_cc_mode.num_alt); + dev_info(dev->dev, + "sliced CC EndPoint Addr 0x%x, Alternate settings: %i\n", + dev->sliced_cc_mode.end_point_addr, + dev->sliced_cc_mode.num_alt); dev->sliced_cc_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->sliced_cc_mode.num_alt, GFP_KERNEL); - - if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); + if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) return -ENOMEM; - } for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe]. desc.wMaxPacketSize); dev->sliced_cc_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, - dev->sliced_cc_mode.alt_max_pkt_size[i]); + dev_dbg(dev->dev, + "Alternate setting %i, max size= %i\n", i, + dev->sliced_cc_mode.alt_max_pkt_size[i]); } return 0; @@ -1391,6 +1392,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct usb_device *udev; + struct device *d = &interface->dev; struct usb_interface *uif; struct cx231xx *dev = NULL; int retval = -ENODEV; @@ -1401,6 +1403,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, struct usb_interface_assoc_descriptor *assoc_desc; ifnum = interface->altsetting[0].desc.bInterfaceNumber; + udev = usb_get_dev(interface_to_usbdev(interface)); /* * Interface number 0 - IR interface (handled by mceusb driver) @@ -1414,18 +1417,16 @@ static int cx231xx_usb_probe(struct usb_interface *interface, nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); if (nr >= CX231XX_MAXBOARDS) { /* No free device slots */ - cx231xx_err(DRIVER_NAME ": Supports only %i devices.\n", - CX231XX_MAXBOARDS); + dev_err(d, + "Supports only %i devices.\n", + CX231XX_MAXBOARDS); return -ENOMEM; } } while (test_and_set_bit(nr, &cx231xx_devused)); - udev = usb_get_dev(interface_to_usbdev(interface)); - /* allocate memory for our device state and initialize it */ dev = devm_kzalloc(&udev->dev, sizeof(*dev), GFP_KERNEL); if (dev == NULL) { - cx231xx_err(DRIVER_NAME ": out of memory!\n"); clear_bit(nr, &cx231xx_devused); return -ENOMEM; } @@ -1434,6 +1435,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, dev->devno = nr; dev->model = id->driver_info; dev->video_mode.alt = -1; + dev->dev = d; dev->interface_count++; /* reset gpio dir and value */ @@ -1472,14 +1474,14 @@ static int cx231xx_usb_probe(struct usb_interface *interface, speed = "unknown"; } - cx231xx_info("New device %s %s @ %s Mbps " - "(%04x:%04x) with %d interfaces\n", - udev->manufacturer ? udev->manufacturer : "", - udev->product ? udev->product : "", - speed, - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct), - dev->max_iad_interface_count); + dev_info(d, + "New device %s %s @ %s Mbps (%04x:%04x) with %d interfaces\n", + udev->manufacturer ? udev->manufacturer : "", + udev->product ? udev->product : "", + speed, + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct), + dev->max_iad_interface_count); /* increment interface count */ dev->interface_count++; @@ -1489,13 +1491,12 @@ static int cx231xx_usb_probe(struct usb_interface *interface, assoc_desc = udev->actconfig->intf_assoc[0]; if (assoc_desc->bFirstInterface != ifnum) { - cx231xx_err(DRIVER_NAME ": Not found " - "matching IAD interface\n"); + dev_err(d, "Not found matching IAD interface\n"); retval = -ENODEV; goto err_if; } - cx231xx_info("registering interface %d\n", ifnum); + dev_dbg(d, "registering interface %d\n", ifnum); /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); @@ -1503,7 +1504,7 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* Create v4l2 device */ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); if (retval) { - cx231xx_errdev("v4l2_device_register failed\n"); + dev_err(d, "v4l2_device_register failed\n"); goto err_v4l2; } @@ -1520,7 +1521,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, /* compute alternate max packet sizes for TS1 */ idx = dev->current_pcb_config.hs_config_info[0].interface_info.ts1_index + 1; if (idx >= dev->max_iad_interface_count) { - cx231xx_errdev("TS1 PCB interface #%d doesn't exist\n", idx); + dev_err(d, "TS1 PCB interface #%d doesn't exist\n", + idx); retval = -ENODEV; goto err_video_alt; } @@ -1531,13 +1533,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface, desc.bEndpointAddress; dev->ts1_mode.num_alt = uif->num_altsetting; - cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n", - dev->ts1_mode.end_point_addr, - dev->ts1_mode.num_alt); + dev_info(d, + "TS EndPoint Addr 0x%x, Alternate settings: %i\n", + dev->ts1_mode.end_point_addr, + dev->ts1_mode.num_alt); dev->ts1_mode.alt_max_pkt_size = devm_kmalloc_array(&udev->dev, 32, dev->ts1_mode.num_alt, GFP_KERNEL); if (dev->ts1_mode.alt_max_pkt_size == NULL) { - cx231xx_errdev("out of memory!\n"); retval = -ENOMEM; goto err_video_alt; } @@ -1548,8 +1550,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, wMaxPacketSize); dev->ts1_mode.alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - cx231xx_info("Alternate setting %i, max size= %i\n", i, - dev->ts1_mode.alt_max_pkt_size[i]); + dev_dbg(d, "Alternate setting %i, max size= %i\n", + i, dev->ts1_mode.alt_max_pkt_size[i]); } } @@ -1613,10 +1615,9 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) wake_up_interruptible_all(&dev->open); if (dev->users) { - cx231xx_warn - ("device %s is open! Deregistration and memory " - "deallocation are deferred on close.\n", - video_device_node_name(dev->vdev)); + dev_warn(dev->dev, + "device %s is open! Deregistration and memory deallocation are deferred on close.\n", + video_device_node_name(dev->vdev)); /* Even having users, it is safe to remove the RC i2c driver */ cx231xx_ir_exit(dev); diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index 180103e48036..4a3f28c4e8d3 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -20,16 +20,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include <linux/init.h> #include <linux/list.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/usb.h> #include <linux/vmalloc.h> #include <media/v4l2-common.h> #include <media/tuner.h> -#include "cx231xx.h" #include "cx231xx-reg.h" /* #define ENABLE_DEBUG_ISOC_FRAMES */ @@ -99,10 +98,10 @@ int cx231xx_register_extension(struct cx231xx_ops *ops) mutex_lock(&cx231xx_devlist_mutex); list_add_tail(&ops->next, &cx231xx_extension_devlist); - list_for_each_entry(dev, &cx231xx_devlist, devlist) + list_for_each_entry(dev, &cx231xx_devlist, devlist) { ops->init(dev); - - printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name); + dev_info(dev->dev, "%s initialized\n", ops->name); + } mutex_unlock(&cx231xx_devlist_mutex); return 0; } @@ -113,11 +112,11 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops) struct cx231xx *dev = NULL; mutex_lock(&cx231xx_devlist_mutex); - list_for_each_entry(dev, &cx231xx_devlist, devlist) + list_for_each_entry(dev, &cx231xx_devlist, devlist) { ops->fini(dev); + dev_info(dev->dev, "%s removed\n", ops->name); + } - - printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name); list_del(&ops->next); mutex_unlock(&cx231xx_devlist_mutex); } @@ -227,10 +226,9 @@ int cx231xx_send_usb_command(struct cx231xx_i2c *i2c_bus, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); - if (status < 0) { - cx231xx_info - ("UsbInterface::sendCommand, failed with status -%d\n", - status); + if (status < 0 && !dev->i2c_scan_running) { + dev_err(dev->dev, "%s: failed with status -%d\n", + __func__, status); } return status; @@ -524,9 +522,9 @@ int cx231xx_set_video_alternate(struct cx231xx *dev) usb_set_interface(dev->udev, usb_interface_index, dev->video_mode.alt); if (errCode < 0) { - cx231xx_errdev - ("cannot change alt number to %d (error=%i)\n", - dev->video_mode.alt, errCode); + dev_err(dev->dev, + "cannot change alt number to %d (error=%i)\n", + dev->video_mode.alt, errCode); return errCode; } } @@ -600,9 +598,9 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) } if (alt > 0 && max_pkt_size == 0) { - cx231xx_errdev - ("can't change interface %d alt no. to %d: Max. Pkt size = 0\n", - usb_interface_index, alt); + dev_err(dev->dev, + "can't change interface %d alt no. to %d: Max. Pkt size = 0\n", + usb_interface_index, alt); /*To workaround error number=-71 on EP0 for videograbber, need add following codes.*/ if (dev->board.no_alt_vanc) @@ -616,9 +614,9 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt) if (usb_interface_index > 0) { status = usb_set_interface(dev->udev, usb_interface_index, alt); if (status < 0) { - cx231xx_errdev - ("can't change interface %d alt no. to %d (err=%i)\n", - usb_interface_index, alt, status); + dev_err(dev->dev, + "can't change interface %d alt no. to %d (err=%i)\n", + usb_interface_index, alt, status); return status; } } @@ -767,18 +765,17 @@ int cx231xx_ep5_bulkout(struct cx231xx *dev, u8 *firmware, u16 size) u32 *buffer; buffer = kzalloc(4096, GFP_KERNEL); - if (buffer == NULL) { - cx231xx_info("out of mem\n"); + if (buffer == NULL) return -ENOMEM; - } memcpy(&buffer[0], firmware, 4096); ret = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 5), buffer, 4096, &actlen, 2000); if (ret) - cx231xx_info("bulk message failed: %d (%d/%d)", ret, - size, actlen); + dev_err(dev->dev, + "bulk message failed: %d (%d/%d)", ret, + size, actlen); else { errCode = actlen != size ? -1 : 0; } @@ -987,12 +984,8 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, cx231xx_uninit_isoc(dev); dma_q->p_left_data = kzalloc(4096, GFP_KERNEL); - if (dma_q->p_left_data == NULL) { - cx231xx_info("out of mem\n"); + if (dma_q->p_left_data == NULL) return -ENOMEM; - } - - dev->video_mode.isoc_ctl.isoc_copy = isoc_copy; dev->video_mode.isoc_ctl.num_bufs = num_bufs; @@ -1018,14 +1011,16 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, dev->video_mode.isoc_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.isoc_ctl.urb) { - cx231xx_errdev("cannot alloc memory for usb buffers\n"); + dev_err(dev->dev, + "cannot alloc memory for usb buffers\n"); return -ENOMEM; } dev->video_mode.isoc_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.isoc_ctl.transfer_buffer) { - cx231xx_errdev("cannot allocate memory for usbtransfer\n"); + dev_err(dev->dev, + "cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.isoc_ctl.urb); return -ENOMEM; } @@ -1045,7 +1040,8 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->video_mode.isoc_ctl.num_bufs; i++) { urb = usb_alloc_urb(max_packets, GFP_KERNEL); if (!urb) { - cx231xx_err("cannot alloc isoc_ctl.urb %i\n", i); + dev_err(dev->dev, + "cannot alloc isoc_ctl.urb %i\n", i); cx231xx_uninit_isoc(dev); return -ENOMEM; } @@ -1055,10 +1051,10 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.isoc_ctl.transfer_buffer[i]) { - cx231xx_err("unable to allocate %i bytes for transfer" - " buffer %i%s\n", - sb_size, i, - in_interrupt() ? " while in int" : ""); + dev_err(dev->dev, + "unable to allocate %i bytes for transfer buffer %i%s\n", + sb_size, i, + in_interrupt() ? " while in int" : ""); cx231xx_uninit_isoc(dev); return -ENOMEM; } @@ -1090,8 +1086,9 @@ int cx231xx_init_isoc(struct cx231xx *dev, int max_packets, rc = usb_submit_urb(dev->video_mode.isoc_ctl.urb[i], GFP_ATOMIC); if (rc) { - cx231xx_err("submit of urb %i failed (error=%i)\n", i, - rc); + dev_err(dev->dev, + "submit of urb %i failed (error=%i)\n", i, + rc); cx231xx_uninit_isoc(dev); return rc; } @@ -1151,14 +1148,16 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, dev->video_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.bulk_ctl.urb) { - cx231xx_errdev("cannot alloc memory for usb buffers\n"); + dev_err(dev->dev, + "cannot alloc memory for usb buffers\n"); return -ENOMEM; } dev->video_mode.bulk_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->video_mode.bulk_ctl.transfer_buffer) { - cx231xx_errdev("cannot allocate memory for usbtransfer\n"); + dev_err(dev->dev, + "cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.bulk_ctl.urb); return -ENOMEM; } @@ -1178,7 +1177,8 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->video_mode.bulk_ctl.num_bufs; i++) { urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - cx231xx_err("cannot alloc bulk_ctl.urb %i\n", i); + dev_err(dev->dev, + "cannot alloc bulk_ctl.urb %i\n", i); cx231xx_uninit_bulk(dev); return -ENOMEM; } @@ -1189,10 +1189,10 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, usb_alloc_coherent(dev->udev, sb_size, GFP_KERNEL, &urb->transfer_dma); if (!dev->video_mode.bulk_ctl.transfer_buffer[i]) { - cx231xx_err("unable to allocate %i bytes for transfer" - " buffer %i%s\n", - sb_size, i, - in_interrupt() ? " while in int" : ""); + dev_err(dev->dev, + "unable to allocate %i bytes for transfer buffer %i%s\n", + sb_size, i, + in_interrupt() ? " while in int" : ""); cx231xx_uninit_bulk(dev); return -ENOMEM; } @@ -1212,8 +1212,8 @@ int cx231xx_init_bulk(struct cx231xx *dev, int max_packets, rc = usb_submit_urb(dev->video_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - cx231xx_err("submit of urb %i failed (error=%i)\n", i, - rc); + dev_err(dev->dev, + "submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_bulk(dev); return rc; } @@ -1300,6 +1300,15 @@ int cx231xx_dev_init(struct cx231xx *dev) cx231xx_i2c_register(&dev->i2c_bus[1]); cx231xx_i2c_register(&dev->i2c_bus[2]); + cx231xx_i2c_mux_register(dev, 0); + cx231xx_i2c_mux_register(dev, 1); + + /* scan the real bus segments in the order of physical port numbers */ + cx231xx_do_i2c_scan(dev, I2C_0); + cx231xx_do_i2c_scan(dev, I2C_1_MUX_1); + cx231xx_do_i2c_scan(dev, I2C_2); + cx231xx_do_i2c_scan(dev, I2C_1_MUX_3); + /* init hardware */ /* Note : with out calling set power mode function, afe can not be set up correctly */ @@ -1307,18 +1316,18 @@ int cx231xx_dev_init(struct cx231xx *dev) errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ENXTERNAL_AV); if (errCode < 0) { - cx231xx_errdev - ("%s: Failed to set Power - errCode [%d]!\n", - __func__, errCode); + dev_err(dev->dev, + "%s: Failed to set Power - errCode [%d]!\n", + __func__, errCode); return errCode; } } else { errCode = cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); if (errCode < 0) { - cx231xx_errdev - ("%s: Failed to set Power - errCode [%d]!\n", - __func__, errCode); + dev_err(dev->dev, + "%s: Failed to set Power - errCode [%d]!\n", + __func__, errCode); return errCode; } } @@ -1331,42 +1340,43 @@ int cx231xx_dev_init(struct cx231xx *dev) /* initialize Colibri block */ errCode = cx231xx_afe_init_super_block(dev, 0x23c); if (errCode < 0) { - cx231xx_errdev - ("%s: cx231xx_afe init super block - errCode [%d]!\n", - __func__, errCode); + dev_err(dev->dev, + "%s: cx231xx_afe init super block - errCode [%d]!\n", + __func__, errCode); return errCode; } errCode = cx231xx_afe_init_channels(dev); if (errCode < 0) { - cx231xx_errdev - ("%s: cx231xx_afe init channels - errCode [%d]!\n", - __func__, errCode); + dev_err(dev->dev, + "%s: cx231xx_afe init channels - errCode [%d]!\n", + __func__, errCode); return errCode; } /* Set DIF in By pass mode */ errCode = cx231xx_dif_set_standard(dev, DIF_USE_BASEBAND); if (errCode < 0) { - cx231xx_errdev - ("%s: cx231xx_dif set to By pass mode - errCode [%d]!\n", - __func__, errCode); + dev_err(dev->dev, + "%s: cx231xx_dif set to By pass mode - errCode [%d]!\n", + __func__, errCode); return errCode; } /* I2S block related functions */ errCode = cx231xx_i2s_blk_initialize(dev); if (errCode < 0) { - cx231xx_errdev - ("%s: cx231xx_i2s block initialize - errCode [%d]!\n", - __func__, errCode); + dev_err(dev->dev, + "%s: cx231xx_i2s block initialize - errCode [%d]!\n", + __func__, errCode); return errCode; } /* init control pins */ errCode = cx231xx_init_ctrl_pin_status(dev); if (errCode < 0) { - cx231xx_errdev("%s: cx231xx_init ctrl pins - errCode [%d]!\n", - __func__, errCode); + dev_err(dev->dev, + "%s: cx231xx_init ctrl pins - errCode [%d]!\n", + __func__, errCode); return errCode; } @@ -1391,9 +1401,9 @@ int cx231xx_dev_init(struct cx231xx *dev) break; } if (errCode < 0) { - cx231xx_errdev - ("%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", - __func__, errCode); + dev_err(dev->dev, + "%s: cx231xx_AGC mode to Analog - errCode [%d]!\n", + __func__, errCode); return errCode; } @@ -1404,9 +1414,7 @@ int cx231xx_dev_init(struct cx231xx *dev) if (dev->board.has_dvb) cx231xx_set_alt_setting(dev, INDEX_TS1, 0); - /* set the I2C master port to 3 on channel 1 */ - errCode = cx231xx_enable_i2c_port_3(dev, true); - + errCode = 0; return errCode; } EXPORT_SYMBOL_GPL(cx231xx_dev_init); @@ -1414,6 +1422,8 @@ EXPORT_SYMBOL_GPL(cx231xx_dev_init); void cx231xx_dev_uninit(struct cx231xx *dev) { /* Un Initialize I2C bus */ + cx231xx_i2c_mux_unregister(dev, 1); + cx231xx_i2c_mux_unregister(dev, 0); cx231xx_i2c_unregister(&dev->i2c_bus[2]); cx231xx_i2c_unregister(&dev->i2c_bus[1]); cx231xx_i2c_unregister(&dev->i2c_bus[0]); @@ -1468,9 +1478,8 @@ int cx231xx_send_gpio_cmd(struct cx231xx *dev, u32 gpio_bit, u8 *gpio_val, /* call common vendor command request */ status = cx231xx_send_vendor_cmd(dev, &ven_req); if (status < 0) { - cx231xx_info - ("UsbInterface::sendCommand, failed with status -%d\n", - status); + dev_err(dev->dev, "%s: failed with status -%d\n", + __func__, status); } return status; diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 6c7b5e250eed..dd600b994e69 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -19,11 +19,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include <linux/kernel.h> #include <linux/slab.h> -#include <linux/usb.h> -#include "cx231xx.h" #include <media/v4l2-common.h> #include <media/videobuf-vmalloc.h> @@ -46,11 +45,6 @@ MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#define dprintk(level, fmt, arg...) do { \ -if (debug >= level) \ - printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ -} while (0) - #define CX231XX_DVB_NUM_BUFS 5 #define CX231XX_DVB_MAX_PACKETSIZE 564 #define CX231XX_DVB_MAX_PACKETS 64 @@ -197,9 +191,11 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) break; } if (packet < 0) { - dprintk(1, "URB status %d [%s].\n", status, errmsg); + dev_dbg(dev->dev, + "URB status %d [%s].\n", status, errmsg); } else { - dprintk(1, "URB packet %d, status %d [%s].\n", + dev_dbg(dev->dev, + "URB packet %d, status %d [%s].\n", packet, status, errmsg); } } @@ -265,12 +261,8 @@ static int start_streaming(struct cx231xx_dvb *dvb) struct cx231xx *dev = dvb->adapter.priv; if (dev->USE_ISO) { - cx231xx_info("DVB transfer mode is ISO.\n"); - mutex_lock(&dev->i2c_lock); - cx231xx_enable_i2c_port_3(dev, false); + dev_dbg(dev->dev, "DVB transfer mode is ISO.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 4); - cx231xx_enable_i2c_port_3(dev, true); - mutex_unlock(&dev->i2c_lock); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) return rc; @@ -280,7 +272,7 @@ static int start_streaming(struct cx231xx_dvb *dvb) dev->ts1_mode.max_pkt_size, dvb_isoc_copy); } else { - cx231xx_info("DVB transfer mode is BULK.\n"); + dev_dbg(dev->dev, "DVB transfer mode is BULK.\n"); cx231xx_set_alt_setting(dev, INDEX_TS1, 0); rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); if (rc < 0) @@ -378,24 +370,24 @@ static int attach_xc5000(u8 addr, struct cx231xx *dev) struct xc5000_config cfg; memset(&cfg, 0, sizeof(cfg)); - cfg.i2c_adap = &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap; + cfg.i2c_adap = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master); cfg.i2c_addr = addr; if (!dev->dvb->frontend) { - printk(KERN_ERR "%s/2: dvb frontend not attached. " + dev_err(dev->dev, "%s/2: dvb frontend not attached. " "Can't attach xc5000\n", dev->name); return -EINVAL; } fe = dvb_attach(xc5000_attach, dev->dvb->frontend, &cfg); if (!fe) { - printk(KERN_ERR "%s/2: xc5000 attach failed\n", dev->name); + dev_err(dev->dev, "%s/2: xc5000 attach failed\n", dev->name); dvb_frontend_detach(dev->dvb->frontend); dev->dvb->frontend = NULL; return -EINVAL; } - printk(KERN_INFO "%s/2: xc5000 attached\n", dev->name); + dev_info(dev->dev, "%s/2: xc5000 attached\n", dev->name); return 0; } @@ -434,16 +426,17 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev) if (dops->init != NULL && !dev->xc_fw_load_done) { - cx231xx_info("Reloading firmware for XC5000\n"); + dev_dbg(dev->dev, + "Reloading firmware for XC5000\n"); status = dops->init(dev->dvb->frontend); if (status == 0) { dev->xc_fw_load_done = 1; - cx231xx_info - ("XC5000 firmware download completed\n"); + dev_dbg(dev->dev, + "XC5000 firmware download completed\n"); } else { dev->xc_fw_load_done = 0; - cx231xx_info - ("XC5000 firmware download failed !!!\n"); + dev_dbg(dev->dev, + "XC5000 firmware download failed !!!\n"); } } @@ -466,7 +459,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, adapter_nr); if (result < 0) { - printk(KERN_WARNING + dev_warn(dev->dev, "%s: dvb_register_adapter failed (errno = %d)\n", dev->name, result); goto fail_adapter; @@ -480,7 +473,7 @@ static int register_dvb(struct cx231xx_dvb *dvb, /* register frontend */ result = dvb_register_frontend(&dvb->adapter, dvb->frontend); if (result < 0) { - printk(KERN_WARNING + dev_warn(dev->dev, "%s: dvb_register_frontend failed (errno = %d)\n", dev->name, result); goto fail_frontend; @@ -498,7 +491,8 @@ static int register_dvb(struct cx231xx_dvb *dvb, result = dvb_dmx_init(&dvb->demux); if (result < 0) { - printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n", + dev_warn(dev->dev, + "%s: dvb_dmx_init failed (errno = %d)\n", dev->name, result); goto fail_dmx; } @@ -508,15 +502,16 @@ static int register_dvb(struct cx231xx_dvb *dvb, dvb->dmxdev.capabilities = 0; result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); if (result < 0) { - printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", - dev->name, result); + dev_warn(dev->dev, + "%s: dvb_dmxdev_init failed (errno = %d)\n", + dev->name, result); goto fail_dmxdev; } dvb->fe_hw.source = DMX_FRONTEND_0; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - printk(KERN_WARNING + dev_warn(dev->dev, "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", dev->name, result); goto fail_fe_hw; @@ -525,17 +520,17 @@ static int register_dvb(struct cx231xx_dvb *dvb, dvb->fe_mem.source = DMX_MEMORY_FE; result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); if (result < 0) { - printk(KERN_WARNING - "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", - dev->name, result); + dev_warn(dev->dev, + "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", + dev->name, result); goto fail_fe_mem; } result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); if (result < 0) { - printk(KERN_WARNING - "%s: connect_frontend failed (errno = %d)\n", dev->name, - result); + dev_warn(dev->dev, + "%s: connect_frontend failed (errno = %d)\n", + dev->name, result); goto fail_fe_conn; } @@ -583,6 +578,8 @@ static int dvb_init(struct cx231xx *dev) { int result = 0; struct cx231xx_dvb *dvb; + struct i2c_adapter *tuner_i2c; + struct i2c_adapter *demod_i2c; if (!dev->board.has_dvb) { /* This device does not support the extension */ @@ -592,13 +589,16 @@ static int dvb_init(struct cx231xx *dev) dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL); if (dvb == NULL) { - printk(KERN_INFO "cx231xx_dvb: memory allocation failed\n"); + dev_info(dev->dev, + "cx231xx_dvb: memory allocation failed\n"); return -ENOMEM; } dev->dvb = dvb; dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq; dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; + tuner_i2c = cx231xx_get_i2c_adap(dev, dev->board.tuner_i2c_master); + demod_i2c = cx231xx_get_i2c_adap(dev, dev->board.demod_i2c_master); mutex_lock(&dev->lock); cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); cx231xx_demod_reset(dev); @@ -609,11 +609,11 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(s5h1432_attach, &dvico_s5h1432_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach s5h1432 front end\n"); + dev_err(dev->dev, + "Failed to attach s5h1432 front end\n"); result = -EINVAL; goto out_free; } @@ -622,7 +622,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(xc5000_attach, dev->dvb->frontend, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, &cnxt_rde250_tunerconfig)) { result = -EINVAL; goto out_free; @@ -634,11 +634,11 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(s5h1411_attach, &xc5000_s5h1411_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach s5h1411 front end\n"); + dev_err(dev->dev, + "Failed to attach s5h1411 front end\n"); result = -EINVAL; goto out_free; } @@ -647,7 +647,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(xc5000_attach, dev->dvb->frontend, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, &cnxt_rdu250_tunerconfig)) { result = -EINVAL; goto out_free; @@ -657,11 +657,11 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(s5h1432_attach, &dvico_s5h1432_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach s5h1432 front end\n"); + dev_err(dev->dev, + "Failed to attach s5h1432 front end\n"); result = -EINVAL; goto out_free; } @@ -670,7 +670,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(tda18271_attach, dev->dvb->frontend, - 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + 0x60, tuner_i2c, &cnxt_rde253s_tunerconfig)) { result = -EINVAL; goto out_free; @@ -681,11 +681,11 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(s5h1411_attach, &tda18271_s5h1411_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach s5h1411 front end\n"); + dev_err(dev->dev, + "Failed to attach s5h1411 front end\n"); result = -EINVAL; goto out_free; } @@ -694,7 +694,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; if (!dvb_attach(tda18271_attach, dev->dvb->frontend, - 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + 0x60, tuner_i2c, &cnxt_rde253s_tunerconfig)) { result = -EINVAL; goto out_free; @@ -702,16 +702,17 @@ static int dvb_init(struct cx231xx *dev) break; case CX231XX_BOARD_HAUPPAUGE_EXETER: - printk(KERN_INFO "%s: looking for tuner / demod on i2c bus: %d\n", - __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap)); + dev_info(dev->dev, + "%s: looking for tuner / demod on i2c bus: %d\n", + __func__, i2c_adapter_id(tuner_i2c)); dev->dvb->frontend = dvb_attach(lgdt3305_attach, &hcw_lgdt3305_config, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap); + tuner_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach LG3305 front end\n"); + dev_err(dev->dev, + "Failed to attach LG3305 front end\n"); result = -EINVAL; goto out_free; } @@ -720,7 +721,7 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; dvb_attach(tda18271_attach, dev->dvb->frontend, - 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + 0x60, tuner_i2c, &hcw_tda18271_config); break; @@ -728,12 +729,12 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(si2165_attach, &hauppauge_930C_HD_1113xx_si2165_config, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap + tuner_i2c ); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach SI2165 front end\n"); + dev_err(dev->dev, + "Failed to attach SI2165 front end\n"); result = -EINVAL; goto out_free; } @@ -745,7 +746,7 @@ static int dvb_init(struct cx231xx *dev) dvb_attach(tda18271_attach, dev->dvb->frontend, 0x60, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, &hcw_tda18271_config); dev->cx231xx_reset_analog_tuner = NULL; @@ -761,12 +762,12 @@ static int dvb_init(struct cx231xx *dev) dev->dvb->frontend = dvb_attach(si2165_attach, &pctv_quatro_stick_1114xx_si2165_config, - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap + tuner_i2c ); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach SI2165 front end\n"); + dev_err(dev->dev, + "Failed to attach SI2165 front end\n"); result = -EINVAL; goto out_free; } @@ -786,7 +787,7 @@ static int dvb_init(struct cx231xx *dev) request_module("si2157"); client = i2c_new_device( - &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + tuner_i2c, &info); if (client == NULL || client->dev.driver == NULL) { dvb_frontend_detach(dev->dvb->frontend); @@ -810,16 +811,17 @@ static int dvb_init(struct cx231xx *dev) case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID: case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID: - printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n", - __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap)); + dev_info(dev->dev, + "%s: looking for demod on i2c bus: %d\n", + __func__, i2c_adapter_id(tuner_i2c)); dev->dvb->frontend = dvb_attach(mb86a20s_attach, &pv_mb86a20s_config, - &dev->i2c_bus[dev->board.demod_i2c_master].i2c_adap); + demod_i2c); if (dev->dvb->frontend == NULL) { - printk(DRIVER_NAME - ": Failed to attach mb86a20s demod\n"); + dev_err(dev->dev, + "Failed to attach mb86a20s demod\n"); result = -EINVAL; goto out_free; } @@ -828,30 +830,31 @@ static int dvb_init(struct cx231xx *dev) dvb->frontend->callback = cx231xx_tuner_callback; dvb_attach(tda18271_attach, dev->dvb->frontend, - 0x60, &dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap, + 0x60, tuner_i2c, &pv_tda18271_config); break; default: - printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" - " isn't supported yet\n", dev->name); + dev_err(dev->dev, + "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", + dev->name); break; } if (NULL == dvb->frontend) { - printk(KERN_ERR + dev_err(dev->dev, "%s/2: frontend initialization failed\n", dev->name); result = -EINVAL; goto out_free; } /* register everything */ - result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); + result = register_dvb(dvb, THIS_MODULE, dev, dev->dev); if (result < 0) goto out_free; - printk(KERN_INFO "Successfully loaded cx231xx-dvb\n"); + dev_info(dev->dev, "Successfully loaded cx231xx-dvb\n"); ret: cx231xx_set_mode(dev, CX231XX_SUSPEND); diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 7c0f797f1057..a29c345b027d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -20,14 +20,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include <linux/module.h> #include <linux/kernel.h> -#include <linux/usb.h> #include <linux/i2c.h> +#include <linux/i2c-mux.h> #include <media/v4l2-common.h> #include <media/tuner.h> -#include "cx231xx.h" /* ----------------------------------------------------------- */ @@ -54,10 +54,19 @@ do { \ } \ } while (0) +static inline int get_real_i2c_port(struct cx231xx *dev, int bus_nr) +{ + if (bus_nr == 1) + return dev->port_3_switch_enabled ? I2C_1_MUX_3 : I2C_1_MUX_1; + return bus_nr; +} + 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) + int i2c_port = get_real_i2c_port(dev, bus->nr); + + if (i2c_port != dev->board.tuner_i2c_master) return false; if (msg->addr != dev->board.tuner_addr) @@ -340,14 +349,15 @@ static int cx231xx_i2c_check_for_device(struct i2c_adapter *i2c_adap, struct cx231xx *dev = bus->dev; struct cx231xx_i2c_xfer_data req_data; int status = 0; + u8 buf[1]; /* prepare xfer_data struct */ req_data.dev_addr = msg->addr; - req_data.direction = msg->flags; + req_data.direction = I2C_M_RD; req_data.saddr_len = 0; req_data.saddr_dat = 0; - req_data.buf_size = 0; - req_data.p_buffer = NULL; + req_data.buf_size = 1; + req_data.p_buffer = buf; /* usb send command */ status = dev->cx231xx_send_usb_command(bus, &req_data); @@ -455,17 +465,14 @@ static struct i2c_adapter cx231xx_adap_template = { .algo = &cx231xx_algo, }; -static struct i2c_client cx231xx_client_template = { - .name = "cx231xx internal", -}; - /* ----------------------------------------------------------- */ /* * i2c_devs * incomplete list of known devices */ -static char *i2c_devs[128] = { +static const char *i2c_devs[128] = { + [0x20 >> 1] = "demod", [0x60 >> 1] = "colibri", [0x88 >> 1] = "hammerhead", [0x8e >> 1] = "CIR", @@ -480,22 +487,34 @@ static char *i2c_devs[128] = { * cx231xx_do_i2c_scan() * check i2c address range for devices */ -void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c) +void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port) { unsigned char buf; int i, rc; + struct i2c_client client; + + if (!i2c_scan) + return; + + /* Don't generate I2C errors during scan */ + dev->i2c_scan_running = true; + + memset(&client, 0, sizeof(client)); + client.adapter = cx231xx_get_i2c_adap(dev, i2c_port); - cx231xx_info(": Checking for I2C devices ..\n"); for (i = 0; i < 128; i++) { - c->addr = i; - rc = i2c_master_recv(c, &buf, 0); + client.addr = i; + rc = i2c_master_recv(&client, &buf, 0); if (rc < 0) continue; - cx231xx_info("%s: i2c scan: found device @ 0x%x [%s]\n", - dev->name, i << 1, - i2c_devs[i] ? i2c_devs[i] : "???"); + dev_info(dev->dev, + "i2c scan: found device @ port %d addr 0x%x [%s]\n", + i2c_port, + i << 1, + i2c_devs[i] ? i2c_devs[i] : "???"); } - cx231xx_info(": Completed Checking for I2C devices.\n"); + + dev->i2c_scan_running = false; } /* @@ -509,23 +528,17 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) BUG_ON(!dev->cx231xx_send_usb_command); bus->i2c_adap = cx231xx_adap_template; - bus->i2c_client = cx231xx_client_template; - bus->i2c_adap.dev.parent = &dev->udev->dev; + bus->i2c_adap.dev.parent = dev->dev; - strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name)); + snprintf(bus->i2c_adap.name, sizeof(bus->i2c_adap.name), "%s-%d", bus->dev->name, bus->nr); bus->i2c_adap.algo_data = bus; i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); i2c_add_adapter(&bus->i2c_adap); - bus->i2c_client.adapter = &bus->i2c_adap; - - if (0 == bus->i2c_rc) { - if (i2c_scan) - cx231xx_do_i2c_scan(dev, &bus->i2c_client); - } else - cx231xx_warn("%s: i2c bus %d register FAILED\n", - dev->name, bus->nr); + if (0 != bus->i2c_rc) + dev_warn(dev->dev, + "i2c bus %d register FAILED\n", bus->nr); return bus->i2c_rc; } @@ -539,3 +552,62 @@ int cx231xx_i2c_unregister(struct cx231xx_i2c *bus) i2c_del_adapter(&bus->i2c_adap); return 0; } + +/* + * cx231xx_i2c_mux_select() + * switch i2c master number 1 between port1 and port3 + */ +static int cx231xx_i2c_mux_select(struct i2c_adapter *adap, + void *mux_priv, u32 chan_id) +{ + struct cx231xx *dev = mux_priv; + + return cx231xx_enable_i2c_port_3(dev, chan_id); +} + +int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no) +{ + struct i2c_adapter *i2c_parent = &dev->i2c_bus[1].i2c_adap; + /* what is the correct mux_dev? */ + struct device *mux_dev = dev->dev; + + dev->i2c_mux_adap[mux_no] = i2c_add_mux_adapter(i2c_parent, + mux_dev, + dev /* mux_priv */, + 0, + mux_no /* chan_id */, + 0 /* class */, + &cx231xx_i2c_mux_select, + NULL); + + if (!dev->i2c_mux_adap[mux_no]) + dev_warn(dev->dev, + "i2c mux %d register FAILED\n", mux_no); + + return 0; +} + +void cx231xx_i2c_mux_unregister(struct cx231xx *dev, int mux_no) +{ + i2c_del_mux_adapter(dev->i2c_mux_adap[mux_no]); + dev->i2c_mux_adap[mux_no] = NULL; +} + +struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port) +{ + switch (i2c_port) { + case I2C_0: + return &dev->i2c_bus[0].i2c_adap; + case I2C_1: + return &dev->i2c_bus[1].i2c_adap; + case I2C_2: + return &dev->i2c_bus[2].i2c_adap; + case I2C_1_MUX_1: + return dev->i2c_mux_adap[0]; + case I2C_1_MUX_3: + return dev->i2c_mux_adap[1]; + default: + return NULL; + } +} +EXPORT_SYMBOL_GPL(cx231xx_get_i2c_adap); diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c index 05f0434919d4..15d8d1b5f05c 100644 --- a/drivers/media/usb/cx231xx/cx231xx-input.c +++ b/drivers/media/usb/cx231xx/cx231xx-input.c @@ -19,7 +19,6 @@ */ #include "cx231xx.h" -#include <linux/usb.h> #include <linux/slab.h> #include <linux/bitrev.h> @@ -63,7 +62,7 @@ int cx231xx_ir_init(struct cx231xx *dev) struct i2c_board_info info; u8 ir_i2c_bus; - dev_dbg(&dev->udev->dev, "%s\n", __func__); + dev_dbg(dev->dev, "%s\n", __func__); /* Only initialize if a rc keycode map is defined */ if (!cx231xx_boards[dev->model].rc_map_name) @@ -98,9 +97,10 @@ int cx231xx_ir_init(struct cx231xx *dev) /* Load and bind ir-kbd-i2c */ ir_i2c_bus = cx231xx_boards[dev->model].ir_i2c_master; - dev_dbg(&dev->udev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n", + dev_dbg(dev->dev, "Trying to bind ir at bus %d, addr 0x%02x\n", ir_i2c_bus, info.addr); - dev->ir_i2c_client = i2c_new_device(&dev->i2c_bus[ir_i2c_bus].i2c_adap, &info); + dev->ir_i2c_client = i2c_new_device( + cx231xx_get_i2c_adap(dev, ir_i2c_bus), &info); return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c index 3052c4c20229..5bc74149fcb9 100644 --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.c @@ -703,9 +703,9 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_BUSPOWER_DIF_ONLY; break; default: - cx231xx_info("bad config in buspower!!!!\n"); - cx231xx_info("config_info=%x\n", - (config_info & BUSPOWER_MASK)); + dev_err(dev->dev, + "bad config in buspower!!!!\nconfig_info=%x\n", + config_info & BUSPOWER_MASK); return 1; } } else { /* self-power */ @@ -768,9 +768,9 @@ int initialize_cx231xx(struct cx231xx *dev) _current_scenario_idx = INDEX_SELFPOWER_COMPRESSOR; break; default: - cx231xx_info("bad senario!!!!!\n"); - cx231xx_info("config_info=%x\n", - (config_info & SELFPOWER_MASK)); + dev_err(dev->dev, + "bad senario!!!!!\nconfig_info=%x\n", + config_info & SELFPOWER_MASK); return -ENODEV; } } @@ -781,18 +781,29 @@ int initialize_cx231xx(struct cx231xx *dev) sizeof(struct pcb_config)); if (pcb_debug) { - cx231xx_info("SC(0x00) register = 0x%x\n", config_info); - cx231xx_info("scenario %d\n", - (dev->current_pcb_config.index) + 1); - cx231xx_info("type=%x\n", dev->current_pcb_config.type); - cx231xx_info("mode=%x\n", dev->current_pcb_config.mode); - cx231xx_info("speed=%x\n", dev->current_pcb_config.speed); - cx231xx_info("ts1_source=%x\n", - dev->current_pcb_config.ts1_source); - cx231xx_info("ts2_source=%x\n", - dev->current_pcb_config.ts2_source); - cx231xx_info("analog_source=%x\n", - dev->current_pcb_config.analog_source); + dev_info(dev->dev, + "SC(0x00) register = 0x%x\n", config_info); + dev_info(dev->dev, + "scenario %d\n", + (dev->current_pcb_config.index) + 1); + dev_info(dev->dev, + "type=%x\n", + dev->current_pcb_config.type); + dev_info(dev->dev, + "mode=%x\n", + dev->current_pcb_config.mode); + dev_info(dev->dev, + "speed=%x\n", + dev->current_pcb_config.speed); + dev_info(dev->dev, + "ts1_source=%x\n", + dev->current_pcb_config.ts1_source); + dev_info(dev->dev, + "ts2_source=%x\n", + dev->current_pcb_config.ts2_source); + dev_info(dev->dev, + "analog_source=%x\n", + dev->current_pcb_config.analog_source); } return 0; diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index c02794274f51..80261ac40208 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -19,12 +19,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include <linux/init.h> #include <linux/list.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/bitmap.h> -#include <linux/usb.h> #include <linux/i2c.h> #include <linux/mm.h> #include <linux/mutex.h> @@ -35,7 +35,6 @@ #include <media/msp3400.h> #include <media/tuner.h> -#include "cx231xx.h" #include "cx231xx-vbi.h" static inline void print_err_status(struct cx231xx *dev, int packet, int status) @@ -69,11 +68,12 @@ static inline void print_err_status(struct cx231xx *dev, int packet, int status) break; } if (packet < 0) { - cx231xx_err("URB status %d [%s].\n", status, - errmsg); + dev_err(dev->dev, + "URB status %d [%s].\n", status, errmsg); } else { - cx231xx_err("URB packet %d, status %d [%s].\n", - packet, status, errmsg); + dev_err(dev->dev, + "URB packet %d, status %d [%s].\n", + packet, status, errmsg); } } @@ -316,8 +316,8 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) case -ESHUTDOWN: return; default: /* error */ - cx231xx_err("urb completition error %d.\n", - urb->status); + dev_err(dev->dev, + "urb completition error %d.\n", urb->status); break; } @@ -331,8 +331,8 @@ static void cx231xx_irq_vbi_callback(struct urb *urb) urb->status = usb_submit_urb(urb, GFP_ATOMIC); if (urb->status) { - cx231xx_err("urb resubmit failed (error=%i)\n", - urb->status); + dev_err(dev->dev, "urb resubmit failed (error=%i)\n", + urb->status); } } @@ -344,7 +344,7 @@ void cx231xx_uninit_vbi_isoc(struct cx231xx *dev) struct urb *urb; int i; - cx231xx_info("called cx231xx_uninit_vbi_isoc\n"); + dev_dbg(dev->dev, "called cx231xx_uninit_vbi_isoc\n"); dev->vbi_mode.bulk_ctl.nfields = -1; for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { @@ -393,7 +393,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, struct urb *urb; int rc; - cx231xx_info("called cx231xx_vbi_isoc\n"); + dev_dbg(dev->dev, "called cx231xx_vbi_isoc\n"); /* De-allocates all pending stuff */ cx231xx_uninit_vbi_isoc(dev); @@ -419,14 +419,16 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.urb = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.urb) { - cx231xx_errdev("cannot alloc memory for usb buffers\n"); + dev_err(dev->dev, + "cannot alloc memory for usb buffers\n"); return -ENOMEM; } dev->vbi_mode.bulk_ctl.transfer_buffer = kzalloc(sizeof(void *) * num_bufs, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer) { - cx231xx_errdev("cannot allocate memory for usbtransfer\n"); + dev_err(dev->dev, + "cannot allocate memory for usbtransfer\n"); kfree(dev->vbi_mode.bulk_ctl.urb); return -ENOMEM; } @@ -441,7 +443,8 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - cx231xx_err("cannot alloc bulk_ctl.urb %i\n", i); + dev_err(dev->dev, + "cannot alloc bulk_ctl.urb %i\n", i); cx231xx_uninit_vbi_isoc(dev); return -ENOMEM; } @@ -451,9 +454,10 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, dev->vbi_mode.bulk_ctl.transfer_buffer[i] = kzalloc(sb_size, GFP_KERNEL); if (!dev->vbi_mode.bulk_ctl.transfer_buffer[i]) { - cx231xx_err("unable to allocate %i bytes for transfer" - " buffer %i%s\n", sb_size, i, - in_interrupt() ? " while in int" : ""); + dev_err(dev->dev, + "unable to allocate %i bytes for transfer buffer %i%s\n", + sb_size, i, + in_interrupt() ? " while in int" : ""); cx231xx_uninit_vbi_isoc(dev); return -ENOMEM; } @@ -470,8 +474,8 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, for (i = 0; i < dev->vbi_mode.bulk_ctl.num_bufs; i++) { rc = usb_submit_urb(dev->vbi_mode.bulk_ctl.urb[i], GFP_ATOMIC); if (rc) { - cx231xx_err("submit of urb %i failed (error=%i)\n", i, - rc); + dev_err(dev->dev, + "submit of urb %i failed (error=%i)\n", i, rc); cx231xx_uninit_vbi_isoc(dev); return rc; } @@ -522,7 +526,7 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, struct cx231xx_buffer *buf) { /* Advice that buffer was filled */ - /* cx231xx_info("[%p/%d] wakeup\n", buf, buf->vb.i); */ + /* dev_dbg(dev->dev, "[%p/%d] wakeup\n", buf, buf->vb.i); */ buf->vb.state = VIDEOBUF_DONE; buf->vb.field_count++; @@ -614,7 +618,7 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, char *outp; if (list_empty(&dma_q->active)) { - cx231xx_err("No active queue to serve\n"); + dev_err(dev->dev, "No active queue to serve\n"); dev->vbi_mode.bulk_ctl.buf = NULL; *buf = NULL; return; diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index 3b3ada6562ca..53ca12c1ff69 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -22,12 +22,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "cx231xx.h" #include <linux/init.h> #include <linux/list.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/bitmap.h> -#include <linux/usb.h> #include <linux/i2c.h> #include <linux/mm.h> #include <linux/mutex.h> @@ -41,10 +41,9 @@ #include "dvb_frontend.h" -#include "cx231xx.h" #include "cx231xx-vbi.h" -#define CX231XX_VERSION "0.0.2" +#define CX231XX_VERSION "0.0.3" #define DRIVER_AUTHOR "Srinivasa Deevi <srinivasa.deevi@conexant.com>" #define DRIVER_DESC "Conexant cx231xx based USB video device driver" @@ -737,8 +736,9 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, if (!dev->video_mode.bulk_ctl.num_bufs) urb_init = 1; } - /*cx231xx_info("urb_init=%d dev->video_mode.max_pkt_size=%d\n", - urb_init, dev->video_mode.max_pkt_size);*/ + dev_dbg(dev->dev, + "urb_init=%d dev->video_mode.max_pkt_size=%d\n", + urb_init, dev->video_mode.max_pkt_size); if (urb_init) { dev->mode_tv = 0; if (dev->USE_ISO) @@ -809,7 +809,7 @@ void video_mux(struct cx231xx *dev, int index) cx231xx_set_audio_input(dev, dev->ctl_ainput); - cx231xx_info("video_mux : %d\n", index); + dev_dbg(dev->dev, "video_mux : %d\n", index); /* do mode control overrides if required */ cx231xx_do_mode_ctrl_overrides(dev); @@ -861,7 +861,7 @@ static void res_free(struct cx231xx_fh *fh) static int check_dev(struct cx231xx *dev) { if (dev->state & DEV_DISCONNECTED) { - cx231xx_errdev("v4l2 ioctl: device not present\n"); + dev_err(dev->dev, "v4l2 ioctl: device not present\n"); return -ENODEV; } return 0; @@ -953,12 +953,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; if (videobuf_queue_is_busy(&fh->vb_vidq)) { - cx231xx_errdev("%s queue busy\n", __func__); + dev_err(dev->dev, "%s: queue busy\n", __func__); return -EBUSY; } if (dev->stream_on && !fh->stream_on) { - cx231xx_errdev("%s device in use by another fh\n", __func__); + dev_err(dev->dev, + "%s: device in use by another fh\n", __func__); return -EBUSY; } @@ -967,7 +968,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, dev->height = f->fmt.pix.height; dev->format = fmt; - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); + v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); call_all(dev, video, s_mbus_fmt, &mbus_fmt); v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); @@ -1012,7 +1013,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) resolution (since a standard change effects things like the number of lines in VACT, etc) */ memset(&mbus_fmt, 0, sizeof(mbus_fmt)); - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; mbus_fmt.width = dev->width; mbus_fmt.height = dev->height; call_all(dev, video, s_mbus_fmt, &mbus_fmt); @@ -1176,9 +1177,9 @@ int cx231xx_s_frequency(struct file *file, void *priv, int rc; u32 if_frequency = 5400000; - cx231xx_info("Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", - f->frequency, f->type); - /*cx231xx_info("f->type: 1-radio 2-analogTV 3-digitalTV\n");*/ + dev_dbg(dev->dev, + "Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", + f->frequency, f->type); rc = check_dev(dev); if (rc < 0) @@ -1213,13 +1214,14 @@ int cx231xx_s_frequency(struct file *file, void *priv, else if (dev->norm & V4L2_STD_SECAM_LC) if_frequency = 1250000; /*1.25MHz */ - cx231xx_info("if_frequency is set to %d\n", if_frequency); + dev_dbg(dev->dev, + "if_frequency is set to %d\n", if_frequency); cx231xx_set_Colibri_For_LowIF(dev, if_frequency, 1, 1); update_HH_register_after_set_DIF(dev); } - cx231xx_info("Set New FREQUENCY to %d\n", f->frequency); + dev_dbg(dev->dev, "Set New FREQUENCY to %d\n", f->frequency); return rc; } @@ -1523,7 +1525,8 @@ static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, struct cx231xx *dev = fh->dev; if (dev->vbi_stream_on && !fh->stream_on) { - cx231xx_errdev("%s device in use by another fh\n", __func__); + dev_err(dev->dev, + "%s device in use by another fh\n", __func__); return -EBUSY; } return vidioc_try_fmt_vbi_cap(file, priv, f); @@ -1642,17 +1645,15 @@ static int cx231xx_v4l2_open(struct file *filp) #if 0 errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); if (errCode < 0) { - cx231xx_errdev - ("Device locked on digital mode. Can't open analog\n"); + dev_err(dev->dev, + "Device locked on digital mode. Can't open analog\n"); return -EBUSY; } #endif fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL); - if (!fh) { - cx231xx_errdev("cx231xx-video.c: Out of memory?!\n"); + if (!fh) return -ENOMEM; - } if (mutex_lock_interruptible(&dev->lock)) { kfree(fh); return -ERESTARTSYS; @@ -1736,8 +1737,8 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->radio_dev = NULL; } if (dev->vbi_dev) { - cx231xx_info("V4L2 device %s deregistered\n", - video_device_node_name(dev->vbi_dev)); + dev_info(dev->dev, "V4L2 device %s deregistered\n", + video_device_node_name(dev->vbi_dev)); if (video_is_registered(dev->vbi_dev)) video_unregister_device(dev->vbi_dev); else @@ -1745,8 +1746,8 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) dev->vbi_dev = NULL; } if (dev->vdev) { - cx231xx_info("V4L2 device %s deregistered\n", - video_device_node_name(dev->vdev)); + dev_info(dev->dev, "V4L2 device %s deregistered\n", + video_device_node_name(dev->vdev)); if (dev->board.has_417) cx231xx_417_unregister(dev); @@ -2080,8 +2081,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) { int ret; - cx231xx_info("%s: v4l2 driver version %s\n", - dev->name, CX231XX_VERSION); + dev_info(dev->dev, "v4l2 driver version %s\n", CX231XX_VERSION); /* set default norm */ dev->norm = V4L2_STD_PAL; @@ -2119,7 +2119,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) /* allocate and fill video video_device struct */ dev->vdev = cx231xx_vdev_init(dev, &cx231xx_video_template, "video"); if (!dev->vdev) { - cx231xx_errdev("cannot allocate video_device.\n"); + dev_err(dev->dev, "cannot allocate video_device.\n"); return -ENODEV; } @@ -2128,13 +2128,14 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, video_nr[dev->devno]); if (ret) { - cx231xx_errdev("unable to register video device (error=%i).\n", - ret); + dev_err(dev->dev, + "unable to register video device (error=%i).\n", + ret); return ret; } - cx231xx_info("%s/0: registered device %s [v4l2]\n", - dev->name, video_device_node_name(dev->vdev)); + dev_info(dev->dev, "Registered video device %s [v4l2]\n", + video_device_node_name(dev->vdev)); /* Initialize VBI template */ cx231xx_vbi_template = cx231xx_video_template; @@ -2144,7 +2145,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) dev->vbi_dev = cx231xx_vdev_init(dev, &cx231xx_vbi_template, "vbi"); if (!dev->vbi_dev) { - cx231xx_errdev("cannot allocate video_device.\n"); + dev_err(dev->dev, "cannot allocate video_device.\n"); return -ENODEV; } dev->vbi_dev->ctrl_handler = &dev->ctrl_handler; @@ -2152,34 +2153,32 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]); if (ret < 0) { - cx231xx_errdev("unable to register vbi device\n"); + dev_err(dev->dev, "unable to register vbi device\n"); return ret; } - cx231xx_info("%s/0: registered device %s\n", - dev->name, video_device_node_name(dev->vbi_dev)); + dev_info(dev->dev, "Registered VBI device %s\n", + video_device_node_name(dev->vbi_dev)); if (cx231xx_boards[dev->model].radio.type == CX231XX_RADIO) { dev->radio_dev = cx231xx_vdev_init(dev, &cx231xx_radio_template, "radio"); if (!dev->radio_dev) { - cx231xx_errdev("cannot allocate video_device.\n"); + dev_err(dev->dev, + "cannot allocate video_device.\n"); return -ENODEV; } dev->radio_dev->ctrl_handler = &dev->radio_ctrl_handler; ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, radio_nr[dev->devno]); if (ret < 0) { - cx231xx_errdev("can't register radio device\n"); + dev_err(dev->dev, + "can't register radio device\n"); return ret; } - cx231xx_info("Registered radio device as %s\n", - video_device_node_name(dev->radio_dev)); + dev_info(dev->dev, "Registered radio device as %s\n", + video_device_node_name(dev->radio_dev)); } - cx231xx_info("V4L2 device registered as %s and %s\n", - video_device_node_name(dev->vdev), - video_device_node_name(dev->vbi_dev)); - return 0; } diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index aeb1bf42b88d..f9e262eb0db9 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -28,6 +28,7 @@ #include <linux/i2c.h> #include <linux/workqueue.h> #include <linux/mutex.h> +#include <linux/usb.h> #include <media/cx2341x.h> @@ -322,10 +323,11 @@ enum cx231xx_decoder { }; enum CX231XX_I2C_MASTER_PORT { - I2C_0 = 0, - I2C_1 = 1, - I2C_2 = 2, - I2C_3 = 3 + I2C_0 = 0, /* master 0 - internal connection */ + I2C_1 = 1, /* master 1 - used with mux */ + I2C_2 = 2, /* master 2 */ + I2C_1_MUX_1 = 3, /* master 1 - port 1 (I2C_DEMOD_EN = 0) */ + I2C_1_MUX_3 = 4 /* master 1 - port 3 (I2C_DEMOD_EN = 1) */ }; struct cx231xx_board { @@ -367,7 +369,6 @@ 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; @@ -472,7 +473,6 @@ struct cx231xx_i2c { /* i2c i/o */ struct i2c_adapter i2c_adap; - struct i2c_client i2c_client; u32 i2c_rc; /* different settings for each bus */ @@ -597,6 +597,7 @@ struct cx231xx { char name[30]; /* name (including minor) of the device */ int model; /* index in the device_data struct */ int devno; /* marks the number of this device */ + struct device *dev; /* pointer to USB interface's dev */ struct cx231xx_board board; @@ -609,6 +610,8 @@ struct cx231xx { unsigned int has_audio_class:1; unsigned int has_alsa_audio:1; + unsigned int i2c_scan_running:1; /* true only during i2c_scan */ + struct cx231xx_fmt *format; struct v4l2_device v4l2_dev; @@ -628,7 +631,10 @@ struct cx231xx { /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ struct cx231xx_i2c i2c_bus[3]; + struct i2c_adapter *i2c_mux_adap[2]; + unsigned int xc_fw_load_done:1; + unsigned int port_3_switch_enabled:1; /* locks */ struct mutex gpio_i2c_lock; struct mutex i2c_lock; @@ -751,9 +757,12 @@ int cx231xx_set_analog_freq(struct cx231xx *dev, u32 freq); int cx231xx_reset_analog_tuner(struct cx231xx *dev); /* Provided by cx231xx-i2c.c */ -void cx231xx_do_i2c_scan(struct cx231xx *dev, struct i2c_client *c); +void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port); int cx231xx_i2c_register(struct cx231xx_i2c *bus); int cx231xx_i2c_unregister(struct cx231xx_i2c *bus); +int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no); +void cx231xx_i2c_mux_unregister(struct cx231xx *dev, int mux_no); +struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port); /* Internal block control functions */ int cx231xx_read_i2c_master(struct cx231xx *dev, u8 dev_addr, u16 saddr, @@ -802,7 +811,6 @@ void cx231xx_Setup_AFE_for_LowIF(struct cx231xx *dev); void reset_s5h1432_demod(struct cx231xx *dev); void cx231xx_dump_HH_reg(struct cx231xx *dev); void update_HH_register_after_set_DIF(struct cx231xx *dev); -void cx231xx_dump_SC_reg(struct cx231xx *dev); @@ -976,23 +984,6 @@ void cx231xx_ir_exit(struct cx231xx *dev); #define cx231xx_ir_exit(dev) (0) #endif - -/* printk macros */ - -#define cx231xx_err(fmt, arg...) do {\ - printk(KERN_ERR fmt , ##arg); } while (0) - -#define cx231xx_errdev(fmt, arg...) do {\ - printk(KERN_ERR "%s: "fmt,\ - dev->name , ##arg); } while (0) - -#define cx231xx_info(fmt, arg...) do {\ - printk(KERN_INFO "%s: "fmt,\ - dev->name , ##arg); } while (0) -#define cx231xx_warn(fmt, arg...) do {\ - printk(KERN_WARNING "%s: "fmt,\ - dev->name , ##arg); } while (0) - static inline unsigned int norm_maxw(struct cx231xx *dev) { if (dev->board.max_range_640_480) diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index 5b34323ad207..0982e734fab5 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig @@ -145,6 +145,9 @@ config DVB_USB_DVBSKY tristate "DVBSky USB support" depends on DVB_USB_V2 select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT + select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_M88TS2022 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT + select DVB_SP2 if MEDIA_SUBDRV_AUTOSELECT help Say Y here to support the USB receivers from DVBSky. diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 1896ab218b11..80a29f5377ea 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1171,6 +1171,7 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap) dev_dbg(&d->udev->dev, "adap->id=%d\n", adap->id); + memset(&si2168_config, 0, sizeof(si2168_config)); si2168_config.i2c_adapter = &adapter; si2168_config.fe = &adap->fe[0]; si2168_config.ts_mode = SI2168_TS_SERIAL; diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 34688c89df11..9b5add4499e3 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -21,10 +21,17 @@ #include "dvb_usb.h" #include "m88ds3103.h" #include "m88ts2022.h" +#include "sp2.h" +#include "si2168.h" +#include "si2157.h" #define DVBSKY_MSG_DELAY 0/*2000*/ #define DVBSKY_BUF_LEN 64 +static int dvb_usb_dvbsky_disable_rc; +module_param_named(disable_rc, dvb_usb_dvbsky_disable_rc, int, 0644); +MODULE_PARM_DESC(disable_rc, "Disable inbuilt IR receiver."); + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct dvbsky_state { @@ -32,7 +39,9 @@ struct dvbsky_state { u8 ibuf[DVBSKY_BUF_LEN]; u8 obuf[DVBSKY_BUF_LEN]; u8 last_lock; + struct i2c_client *i2c_client_demod; struct i2c_client *i2c_client_tuner; + struct i2c_client *i2c_client_ci; /* fe hook functions*/ int (*fe_set_voltage)(struct dvb_frontend *fe, @@ -96,8 +105,7 @@ static int dvbsky_gpio_ctrl(struct dvb_usb_device *d, u8 gport, u8 value) obuf[2] = value; ret = dvbsky_usb_generic_rw(d, obuf, 3, ibuf, 1); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); return ret; } @@ -114,7 +122,7 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], if (num > 2) { dev_err(&d->udev->dev, - "dvbsky_usb: too many i2c messages[%d] than 2.", num); + "too many i2c messages[%d], max 2.", num); ret = -EOPNOTSUPP; goto i2c_error; } @@ -122,7 +130,7 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], if (num == 1) { if (msg[0].len > 60) { dev_err(&d->udev->dev, - "dvbsky_usb: too many i2c bytes[%d] than 60.", + "too many i2c bytes[%d], max 60.", msg[0].len); ret = -EOPNOTSUPP; goto i2c_error; @@ -136,8 +144,7 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], ret = dvbsky_usb_generic_rw(d, obuf, 4, ibuf, msg[0].len + 1); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); if (!ret) memcpy(msg[0].buf, &ibuf[1], msg[0].len); } else { @@ -149,13 +156,12 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], ret = dvbsky_usb_generic_rw(d, obuf, msg[0].len + 3, ibuf, 1); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); } } else { if ((msg[0].len > 60) || (msg[1].len > 60)) { dev_err(&d->udev->dev, - "dvbsky_usb: too many i2c bytes[w-%d][r-%d] than 60.", + "too many i2c bytes[w-%d][r-%d], max 60.", msg[0].len, msg[1].len); ret = -EOPNOTSUPP; goto i2c_error; @@ -169,8 +175,7 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], ret = dvbsky_usb_generic_rw(d, obuf, msg[0].len + 4, ibuf, msg[1].len + 1); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); if (!ret) memcpy(msg[1].buf, &ibuf[1], msg[1].len); @@ -201,8 +206,7 @@ static int dvbsky_rc_query(struct dvb_usb_device *d) obuf[0] = 0x10; ret = dvbsky_usb_generic_rw(d, obuf, 1, ibuf, 2); if (ret) - dev_err(&d->udev->dev, "%s: %s() failed=%d\n", - KBUILD_MODNAME, __func__, ret); + dev_err(&d->udev->dev, "failed=%d\n", ret); if (ret == 0) code = (ibuf[0] << 8) | ibuf[1]; if (code != 0xffff) { @@ -218,6 +222,11 @@ static int dvbsky_rc_query(struct dvb_usb_device *d) static int dvbsky_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { + if (dvb_usb_dvbsky_disable_rc) { + rc->map_name = NULL; + return 0; + } + rc->allowed_protos = RC_BIT_RC5; rc->query = dvbsky_rc_query; rc->interval = 300; @@ -265,8 +274,6 @@ static int dvbsky_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6]) if (i2c_transfer(&d->i2c_adap, msg, 2) == 2) memcpy(mac, ibuf, 6); - dev_info(&d->udev->dev, "dvbsky_usb MAC address=%pM\n", mac); - return 0; } @@ -362,6 +369,300 @@ fail_attach: return ret; } +static int dvbsky_usb_ci_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + struct dvb_usb_device *d = fe_to_d(fe); + struct dvbsky_state *state = d_to_priv(d); + u8 value; + + if (voltage == SEC_VOLTAGE_OFF) + value = 0; + else + value = 1; + dvbsky_gpio_ctrl(d, 0x00, value); + + return state->fe_set_voltage(fe, voltage); +} + +static int dvbsky_ci_ctrl(void *priv, u8 read, int addr, + u8 data, int *mem) +{ + struct dvb_usb_device *d = priv; + int ret = 0; + u8 command[4], respond[2], command_size, respond_size; + + command[1] = (u8)((addr >> 8) & 0xff); /*high part of address*/ + command[2] = (u8)(addr & 0xff); /*low part of address*/ + if (read) { + command[0] = 0x71; + command_size = 3; + respond_size = 2; + } else { + command[0] = 0x70; + command[3] = data; + command_size = 4; + respond_size = 1; + } + ret = dvbsky_usb_generic_rw(d, command, command_size, + respond, respond_size); + if (ret) + goto err; + if (read) + *mem = respond[1]; + return ret; +err: + dev_err(&d->udev->dev, "ci control failed=%d\n", ret); + return ret; +} + +static const struct m88ds3103_config dvbsky_s960c_m88ds3103_config = { + .i2c_addr = 0x68, + .clock = 27000000, + .i2c_wr_max = 33, + .clock_out = 0, + .ts_mode = M88DS3103_TS_CI, + .ts_clk = 10000, + .ts_clk_pol = 1, + .agc = 0x99, + .lnb_hv_pol = 0, + .lnb_en_pol = 1, +}; + +static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap) +{ + struct dvbsky_state *state = adap_to_priv(adap); + struct dvb_usb_device *d = adap_to_d(adap); + int ret = 0; + /* demod I2C adapter */ + struct i2c_adapter *i2c_adapter; + struct i2c_client *client_tuner, *client_ci; + struct i2c_board_info info; + struct sp2_config sp2_config; + struct m88ts2022_config m88ts2022_config = { + .clock = 27000000, + }; + memset(&info, 0, sizeof(struct i2c_board_info)); + + /* attach demod */ + adap->fe[0] = dvb_attach(m88ds3103_attach, + &dvbsky_s960c_m88ds3103_config, + &d->i2c_adap, + &i2c_adapter); + if (!adap->fe[0]) { + dev_err(&d->udev->dev, "dvbsky_s960ci_attach fail.\n"); + ret = -ENODEV; + goto fail_attach; + } + + /* attach tuner */ + m88ts2022_config.fe = adap->fe[0]; + strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &m88ts2022_config; + request_module("m88ts2022"); + client_tuner = i2c_new_device(i2c_adapter, &info); + if (client_tuner == NULL || client_tuner->dev.driver == NULL) { + ret = -ENODEV; + goto fail_tuner_device; + } + + if (!try_module_get(client_tuner->dev.driver->owner)) { + ret = -ENODEV; + goto fail_tuner_module; + } + + /* attach ci controller */ + memset(&sp2_config, 0, sizeof(sp2_config)); + sp2_config.dvb_adap = &adap->dvb_adap; + sp2_config.priv = d; + sp2_config.ci_control = dvbsky_ci_ctrl; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "sp2", I2C_NAME_SIZE); + info.addr = 0x40; + info.platform_data = &sp2_config; + request_module("sp2"); + client_ci = i2c_new_device(&d->i2c_adap, &info); + if (client_ci == NULL || client_ci->dev.driver == NULL) { + ret = -ENODEV; + goto fail_ci_device; + } + + if (!try_module_get(client_ci->dev.driver->owner)) { + ret = -ENODEV; + goto fail_ci_module; + } + + /* delegate signal strength measurement to tuner */ + adap->fe[0]->ops.read_signal_strength = + adap->fe[0]->ops.tuner_ops.get_rf_strength; + + /* hook fe: need to resync the slave fifo when signal locks. */ + state->fe_read_status = adap->fe[0]->ops.read_status; + adap->fe[0]->ops.read_status = dvbsky_usb_read_status; + + /* hook fe: LNB off/on is control by Cypress usb chip. */ + state->fe_set_voltage = adap->fe[0]->ops.set_voltage; + adap->fe[0]->ops.set_voltage = dvbsky_usb_ci_set_voltage; + + state->i2c_client_tuner = client_tuner; + state->i2c_client_ci = client_ci; + return ret; +fail_ci_module: + i2c_unregister_device(client_ci); +fail_ci_device: + module_put(client_tuner->dev.driver->owner); +fail_tuner_module: + i2c_unregister_device(client_tuner); +fail_tuner_device: + dvb_frontend_detach(adap->fe[0]); +fail_attach: + return ret; +} + +static int dvbsky_t680c_attach(struct dvb_usb_adapter *adap) +{ + struct dvbsky_state *state = adap_to_priv(adap); + struct dvb_usb_device *d = adap_to_d(adap); + int ret = 0; + struct i2c_adapter *i2c_adapter; + struct i2c_client *client_demod, *client_tuner, *client_ci; + struct i2c_board_info info; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + struct sp2_config sp2_config; + + /* attach demod */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &i2c_adapter; + si2168_config.fe = &adap->fe[0]; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + + request_module(info.type); + client_demod = i2c_new_device(&d->i2c_adap, &info); + if (client_demod == NULL || + client_demod->dev.driver == NULL) + goto fail_demod_device; + if (!try_module_get(client_demod->dev.driver->owner)) + goto fail_demod_module; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = adap->fe[0]; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + + request_module(info.type); + client_tuner = i2c_new_device(i2c_adapter, &info); + if (client_tuner == NULL || + client_tuner->dev.driver == NULL) + goto fail_tuner_device; + if (!try_module_get(client_tuner->dev.driver->owner)) + goto fail_tuner_module; + + /* attach ci controller */ + memset(&sp2_config, 0, sizeof(sp2_config)); + sp2_config.dvb_adap = &adap->dvb_adap; + sp2_config.priv = d; + sp2_config.ci_control = dvbsky_ci_ctrl; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "sp2", I2C_NAME_SIZE); + info.addr = 0x40; + info.platform_data = &sp2_config; + + request_module(info.type); + client_ci = i2c_new_device(&d->i2c_adap, &info); + + if (client_ci == NULL || client_ci->dev.driver == NULL) + goto fail_ci_device; + + if (!try_module_get(client_ci->dev.driver->owner)) + goto fail_ci_module; + + state->i2c_client_demod = client_demod; + state->i2c_client_tuner = client_tuner; + state->i2c_client_ci = client_ci; + return ret; +fail_ci_module: + i2c_unregister_device(client_ci); +fail_ci_device: + module_put(client_tuner->dev.driver->owner); +fail_tuner_module: + i2c_unregister_device(client_tuner); +fail_tuner_device: + module_put(client_demod->dev.driver->owner); +fail_demod_module: + i2c_unregister_device(client_demod); +fail_demod_device: + ret = -ENODEV; + return ret; +} + +static int dvbsky_t330_attach(struct dvb_usb_adapter *adap) +{ + struct dvbsky_state *state = adap_to_priv(adap); + struct dvb_usb_device *d = adap_to_d(adap); + int ret = 0; + struct i2c_adapter *i2c_adapter; + struct i2c_client *client_demod, *client_tuner; + struct i2c_board_info info; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + + /* attach demod */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &i2c_adapter; + si2168_config.fe = &adap->fe[0]; + si2168_config.ts_mode = SI2168_TS_PARALLEL | 0x40; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + + request_module(info.type); + client_demod = i2c_new_device(&d->i2c_adap, &info); + if (client_demod == NULL || + client_demod->dev.driver == NULL) + goto fail_demod_device; + if (!try_module_get(client_demod->dev.driver->owner)) + goto fail_demod_module; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = adap->fe[0]; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2157", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + + request_module(info.type); + client_tuner = i2c_new_device(i2c_adapter, &info); + if (client_tuner == NULL || + client_tuner->dev.driver == NULL) + goto fail_tuner_device; + if (!try_module_get(client_tuner->dev.driver->owner)) + goto fail_tuner_module; + + state->i2c_client_demod = client_demod; + state->i2c_client_tuner = client_tuner; + return ret; +fail_tuner_module: + i2c_unregister_device(client_tuner); +fail_tuner_device: + module_put(client_demod->dev.driver->owner); +fail_demod_module: + i2c_unregister_device(client_demod); +fail_demod_device: + ret = -ENODEV; + return ret; +} + static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name) { dvbsky_gpio_ctrl(d, 0x04, 1); @@ -404,6 +705,18 @@ static void dvbsky_exit(struct dvb_usb_device *d) module_put(client->dev.driver->owner); i2c_unregister_device(client); } + client = state->i2c_client_demod; + /* remove I2C demod */ + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + client = state->i2c_client_ci; + /* remove I2C ci */ + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } } /* DVB USB Driver stuff */ @@ -434,9 +747,104 @@ static struct dvb_usb_device_properties dvbsky_s960_props = { } }; +static struct dvb_usb_device_properties dvbsky_s960c_props = { + .driver_name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .adapter_nr = adapter_nr, + .size_of_priv = sizeof(struct dvbsky_state), + + .generic_bulk_ctrl_endpoint = 0x01, + .generic_bulk_ctrl_endpoint_response = 0x81, + .generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY, + + .i2c_algo = &dvbsky_i2c_algo, + .frontend_attach = dvbsky_s960c_attach, + .init = dvbsky_init, + .get_rc_config = dvbsky_get_rc_config, + .streaming_ctrl = dvbsky_streaming_ctrl, + .identify_state = dvbsky_identify_state, + .exit = dvbsky_exit, + .read_mac_address = dvbsky_read_mac_addr, + + .num_adapters = 1, + .adapter = { + { + .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096), + } + } +}; + +static struct dvb_usb_device_properties dvbsky_t680c_props = { + .driver_name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .adapter_nr = adapter_nr, + .size_of_priv = sizeof(struct dvbsky_state), + + .generic_bulk_ctrl_endpoint = 0x01, + .generic_bulk_ctrl_endpoint_response = 0x81, + .generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY, + + .i2c_algo = &dvbsky_i2c_algo, + .frontend_attach = dvbsky_t680c_attach, + .init = dvbsky_init, + .get_rc_config = dvbsky_get_rc_config, + .streaming_ctrl = dvbsky_streaming_ctrl, + .identify_state = dvbsky_identify_state, + .exit = dvbsky_exit, + .read_mac_address = dvbsky_read_mac_addr, + + .num_adapters = 1, + .adapter = { + { + .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096), + } + } +}; + +static struct dvb_usb_device_properties dvbsky_t330_props = { + .driver_name = KBUILD_MODNAME, + .owner = THIS_MODULE, + .adapter_nr = adapter_nr, + .size_of_priv = sizeof(struct dvbsky_state), + + .generic_bulk_ctrl_endpoint = 0x01, + .generic_bulk_ctrl_endpoint_response = 0x81, + .generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY, + + .i2c_algo = &dvbsky_i2c_algo, + .frontend_attach = dvbsky_t330_attach, + .init = dvbsky_init, + .get_rc_config = dvbsky_get_rc_config, + .streaming_ctrl = dvbsky_streaming_ctrl, + .identify_state = dvbsky_identify_state, + .exit = dvbsky_exit, + .read_mac_address = dvbsky_read_mac_addr, + + .num_adapters = 1, + .adapter = { + { + .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096), + } + } +}; + static const struct usb_device_id dvbsky_id_table[] = { { DVB_USB_DEVICE(0x0572, 0x6831, &dvbsky_s960_props, "DVBSky S960/S860", RC_MAP_DVBSKY) }, + { DVB_USB_DEVICE(0x0572, 0x960c, + &dvbsky_s960c_props, "DVBSky S960CI", RC_MAP_DVBSKY) }, + { DVB_USB_DEVICE(0x0572, 0x680c, + &dvbsky_t680c_props, "DVBSky T680CI", RC_MAP_DVBSKY) }, + { DVB_USB_DEVICE(0x0572, 0x0320, + &dvbsky_t330_props, "DVBSky T330", RC_MAP_DVBSKY) }, + { DVB_USB_DEVICE(USB_VID_TECHNOTREND, + USB_PID_TECHNOTREND_TVSTICK_CT2_4400, + &dvbsky_t330_props, "TechnoTrend TVStick CT2-4400", + RC_MAP_TT_1500) }, + { DVB_USB_DEVICE(USB_VID_TECHNOTREND, + USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI, + &dvbsky_t680c_props, "TechnoTrend TT-connect CT2-4650 CI", + RC_MAP_TT_1500) }, { } }; MODULE_DEVICE_TABLE(usb, dvbsky_id_table); diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 9f2c5459b73a..994de53a574b 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -817,20 +817,22 @@ static const char *lme_firmware_switch(struct dvb_usb_device *d, int cold) case 0x1122: switch (st->dvb_usb_lme2510_firmware) { default: - st->dvb_usb_lme2510_firmware = TUNER_S0194; case TUNER_S0194: fw_lme = fw_s0194; ret = request_firmware(&fw, fw_lme, &udev->dev); if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_S0194; cold = 0; break; } - st->dvb_usb_lme2510_firmware = TUNER_LG; + /* fall through */ case TUNER_LG: fw_lme = fw_lg; ret = request_firmware(&fw, fw_lme, &udev->dev); - if (ret == 0) + if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_LG; break; + } st->dvb_usb_lme2510_firmware = TUNER_DEFAULT; break; } @@ -838,26 +840,30 @@ static const char *lme_firmware_switch(struct dvb_usb_device *d, int cold) case 0x1120: switch (st->dvb_usb_lme2510_firmware) { default: - st->dvb_usb_lme2510_firmware = TUNER_S7395; case TUNER_S7395: fw_lme = fw_c_s7395; ret = request_firmware(&fw, fw_lme, &udev->dev); if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_S7395; cold = 0; break; } - st->dvb_usb_lme2510_firmware = TUNER_LG; + /* fall through */ case TUNER_LG: fw_lme = fw_c_lg; ret = request_firmware(&fw, fw_lme, &udev->dev); - if (ret == 0) + if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_LG; break; - st->dvb_usb_lme2510_firmware = TUNER_S0194; + } + /* fall through */ case TUNER_S0194: fw_lme = fw_c_s0194; ret = request_firmware(&fw, fw_lme, &udev->dev); - if (ret == 0) + if (ret == 0) { + st->dvb_usb_lme2510_firmware = TUNER_S0194; break; + } st->dvb_usb_lme2510_firmware = TUNER_DEFAULT; cold = 0; break; diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 27b1e0397e71..896a225ee011 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -24,6 +24,9 @@ #include "rtl2830.h" #include "rtl2832.h" +#include "rtl2832_sdr.h" +#include "mn88472.h" +#include "mn88473.h" #include "qt1010.h" #include "mt2060.h" @@ -35,25 +38,6 @@ #include "tua9001.h" #include "r820t.h" -/* - * RTL2832_SDR module is in staging. That logic is added in order to avoid any - * hard dependency to drivers/staging/ directory as we want compile mainline - * driver even whole staging directory is missing. - */ -#include <media/v4l2-subdev.h> - -#if IS_ENABLED(CONFIG_DVB_RTL2832_SDR) -struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, const struct rtl2832_config *cfg, - struct v4l2_subdev *sd); -#else -static inline struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, const struct rtl2832_config *cfg, - struct v4l2_subdev *sd) -{ - return NULL; -} -#endif #ifdef CONFIG_MEDIA_ATTACH #define dvb_attach_sdr(FUNCTION, ARGS...) ({ \ @@ -420,6 +404,8 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf}; struct rtl28xxu_req req_r820t = {0x0034, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf}; + struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf}; + struct rtl28xxu_req req_mn88473 = {0xff38, CMD_I2C_RD, 1, buf}; dev_dbg(&d->udev->dev, "%s:\n", __func__); @@ -449,7 +435,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0xa1) { priv->tuner = TUNER_RTL2832_FC0012; priv->tuner_name = "FC0012"; - goto found; + goto tuner_found; } /* check FC0013 ID register; reg=00 val=a3 */ @@ -457,7 +443,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0xa3) { priv->tuner = TUNER_RTL2832_FC0013; priv->tuner_name = "FC0013"; - goto found; + goto tuner_found; } /* check MT2266 ID register; reg=00 val=85 */ @@ -465,7 +451,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x85) { priv->tuner = TUNER_RTL2832_MT2266; priv->tuner_name = "MT2266"; - goto found; + goto tuner_found; } /* check FC2580 ID register; reg=01 val=56 */ @@ -473,7 +459,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x56) { priv->tuner = TUNER_RTL2832_FC2580; priv->tuner_name = "FC2580"; - goto found; + goto tuner_found; } /* check MT2063 ID register; reg=00 val=9e || 9c */ @@ -481,7 +467,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) { priv->tuner = TUNER_RTL2832_MT2063; priv->tuner_name = "MT2063"; - goto found; + goto tuner_found; } /* check MAX3543 ID register; reg=00 val=38 */ @@ -489,7 +475,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x38) { priv->tuner = TUNER_RTL2832_MAX3543; priv->tuner_name = "MAX3543"; - goto found; + goto tuner_found; } /* check TUA9001 ID register; reg=7e val=2328 */ @@ -497,7 +483,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) { priv->tuner = TUNER_RTL2832_TUA9001; priv->tuner_name = "TUA9001"; - goto found; + goto tuner_found; } /* check MXL5007R ID register; reg=d9 val=14 */ @@ -505,7 +491,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x14) { priv->tuner = TUNER_RTL2832_MXL5007T; priv->tuner_name = "MXL5007T"; - goto found; + goto tuner_found; } /* check E4000 ID register; reg=02 val=40 */ @@ -513,7 +499,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x40) { priv->tuner = TUNER_RTL2832_E4000; priv->tuner_name = "E4000"; - goto found; + goto tuner_found; } /* check TDA18272 ID register; reg=00 val=c760 */ @@ -521,7 +507,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) { priv->tuner = TUNER_RTL2832_TDA18272; priv->tuner_name = "TDA18272"; - goto found; + goto tuner_found; } /* check R820T ID register; reg=00 val=69 */ @@ -529,7 +515,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x69) { priv->tuner = TUNER_RTL2832_R820T; priv->tuner_name = "R820T"; - goto found; + goto tuner_found; } /* check R828D ID register; reg=00 val=69 */ @@ -537,13 +523,44 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) if (ret == 0 && buf[0] == 0x69) { priv->tuner = TUNER_RTL2832_R828D; priv->tuner_name = "R828D"; - goto found; + goto tuner_found; } - -found: +tuner_found: dev_dbg(&d->udev->dev, "%s: tuner=%s\n", __func__, priv->tuner_name); + /* probe slave demod */ + if (priv->tuner == TUNER_RTL2832_R828D) { + /* power on MN88472 demod on GPIO0 */ + ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x01, 0x01); + if (ret) + goto err; + + ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01); + if (ret) + goto err; + + ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01); + if (ret) + goto err; + + /* check MN88472 answers */ + ret = rtl28xxu_ctrl_msg(d, &req_mn88472); + if (ret == 0 && buf[0] == 0x02) { + dev_dbg(&d->udev->dev, "%s: MN88472 found\n", __func__); + priv->slave_demod = SLAVE_DEMOD_MN88472; + goto demod_found; + } + + ret = rtl28xxu_ctrl_msg(d, &req_mn88473); + if (ret == 0 && buf[0] == 0x03) { + dev_dbg(&d->udev->dev, "%s: MN88473 found\n", __func__); + priv->slave_demod = SLAVE_DEMOD_MN88473; + goto demod_found; + } + } + +demod_found: /* close demod I2C gate */ ret = rtl28xxu_ctrl_msg(d, &req_gate_close); if (ret < 0) @@ -818,7 +835,66 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) /* set fe callback */ adap->fe[0]->callback = rtl2832u_frontend_callback; + if (priv->slave_demod) { + struct i2c_board_info info = {}; + struct i2c_client *client; + + /* + * We continue on reduced mode, without DVB-T2/C, using master + * demod, when slave demod fails. + */ + ret = 0; + + /* attach slave demodulator */ + if (priv->slave_demod == SLAVE_DEMOD_MN88472) { + struct mn88472_config mn88472_config = {}; + + mn88472_config.fe = &adap->fe[1]; + mn88472_config.i2c_wr_max = 22, + strlcpy(info.type, "mn88472", I2C_NAME_SIZE); + info.addr = 0x18; + info.platform_data = &mn88472_config; + request_module(info.type); + client = i2c_new_device(priv->demod_i2c_adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + priv->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + priv->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + + priv->i2c_client_slave_demod = client; + } else { + struct mn88473_config mn88473_config = {}; + + mn88473_config.fe = &adap->fe[1]; + mn88473_config.i2c_wr_max = 22, + strlcpy(info.type, "mn88473", I2C_NAME_SIZE); + info.addr = 0x18; + info.platform_data = &mn88473_config; + request_module(info.type); + client = i2c_new_device(priv->demod_i2c_adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + priv->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + priv->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + + priv->i2c_client_slave_demod = client; + } + } + return 0; +err_slave_demod_failed: err: dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); return ret; @@ -984,7 +1060,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) break; } - priv->client = client; + priv->i2c_client_tuner = client; sd = i2c_get_clientdata(client); i2c_set_adapdata(i2c_adap_internal, d); @@ -1024,32 +1100,30 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) &rtl28xxu_rtl2832_r820t_config, NULL); break; case TUNER_RTL2832_R828D: - /* power off mn88472 demod on GPIO0 */ - ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x01); - if (ret) - goto err; - - ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x01); - if (ret) - goto err; - - ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x01, 0x01); - if (ret) - goto err; - - fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap, + fe = dvb_attach(r820t_attach, adap->fe[0], + priv->demod_i2c_adapter, &rtl2832u_r828d_config); - - /* Use tuner to get the signal strength */ adap->fe[0]->ops.read_signal_strength = adap->fe[0]->ops.tuner_ops.get_rf_strength; + + if (adap->fe[1]) { + fe = dvb_attach(r820t_attach, adap->fe[1], + priv->demod_i2c_adapter, + &rtl2832u_r828d_config); + adap->fe[1]->ops.read_signal_strength = + adap->fe[1]->ops.tuner_ops.get_rf_strength; + } + + /* attach SDR */ + dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap, + &rtl28xxu_rtl2832_r820t_config, NULL); break; default: dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME, priv->tuner); } - if (fe == NULL && priv->client == NULL) { + if (fe == NULL && priv->i2c_client_tuner == NULL) { ret = -ENODEV; goto err; } @@ -1097,11 +1171,19 @@ err: static void rtl28xxu_exit(struct dvb_usb_device *d) { struct rtl28xxu_priv *priv = d->priv; - struct i2c_client *client = priv->client; + struct i2c_client *client; dev_dbg(&d->udev->dev, "%s:\n", __func__); /* remove I2C tuner */ + client = priv->i2c_client_tuner; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } + + /* remove I2C slave demod */ + client = priv->i2c_client_slave_demod; if (client) { module_put(client->dev.driver->owner); i2c_unregister_device(client); @@ -1201,13 +1283,6 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) if (ret) goto err; - mdelay(5); - - /* enable ADC */ - ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x48, 0x48); - if (ret) - goto err; - /* streaming EP: clear stall & reset */ ret = rtl28xx_wr_regs(d, USB_EPA_CTL, "\x00\x00", 2); if (ret) @@ -1222,11 +1297,6 @@ static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff) if (ret) goto err; - /* disable ADC */ - ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x48); - if (ret) - goto err; - /* disable PLL */ ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x80); if (ret) @@ -1244,6 +1314,38 @@ err: return ret; } +static int rtl2832u_frontend_ctrl(struct dvb_frontend *fe, int onoff) +{ + struct dvb_usb_device *d = fe_to_d(fe); + struct dvb_usb_adapter *adap = fe_to_adap(fe); + int ret; + u8 val; + + dev_dbg(&d->udev->dev, "%s: fe=%d onoff=%d\n", __func__, fe->id, onoff); + + /* control internal demod ADC */ + if (fe->id == 0 && onoff) + val = 0x48; /* enable ADC */ + else + val = 0x00; /* disable ADC */ + + ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, val, 0x48); + if (ret) + goto err; + + /* bypass slave demod TS through master demod */ + if (fe->id == 1 && onoff) { + ret = rtl2832_enable_external_ts_if(adap->fe[0]); + if (ret) + goto err; + } + + return 0; +err: + dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); + return ret; +} + #if IS_ENABLED(CONFIG_RC_CORE) static int rtl2831u_rc_query(struct dvb_usb_device *d) { @@ -1467,6 +1569,7 @@ static const struct dvb_usb_device_properties rtl2832u_props = { .size_of_priv = sizeof(struct rtl28xxu_priv), .power_ctrl = rtl2832u_power_ctrl, + .frontend_ctrl = rtl2832u_frontend_ctrl, .i2c_algo = &rtl28xxu_i2c_algo, .read_config = rtl2832u_read_config, .frontend_attach = rtl2832u_frontend_attach, diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h index a26cab10f382..3e3ea9d64a38 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h @@ -57,7 +57,12 @@ struct rtl28xxu_priv { u8 page; /* integrated demod active register page */ struct i2c_adapter *demod_i2c_adapter; bool rc_active; - struct i2c_client *client; + struct i2c_client *i2c_client_tuner; + struct i2c_client *i2c_client_slave_demod; + #define SLAVE_DEMOD_NONE 0 + #define SLAVE_DEMOD_MN88472 1 + #define SLAVE_DEMOD_MN88473 2 + unsigned int slave_demod:2; }; enum rtl28xxu_chip_id { diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig index 41d3eb922a00..3364200db093 100644 --- a/drivers/media/usb/dvb-usb/Kconfig +++ b/drivers/media/usb/dvb-usb/Kconfig @@ -130,7 +130,6 @@ config DVB_USB_CXUSB Medion MD95700 hybrid USB2.0 device. DViCO FusionHDTV (Bluebird) USB2.0 devices - TechnoTrend TVStick CT2-4400 and CT2-4650 CI devices config DVB_USB_M920X tristate "Uli m920x DVB-T USB2.0 support" diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c index 3f4361e48a32..efa782ed6e2d 100644 --- a/drivers/media/usb/dvb-usb/af9005.c +++ b/drivers/media/usb/dvb-usb/af9005.c @@ -1081,9 +1081,12 @@ static int __init af9005_usb_module_init(void) err("usb_register failed. (%d)", result); return result; } +#if IS_MODULE(CONFIG_DVB_USB_AF9005) || defined(CONFIG_DVB_USB_AF9005_REMOTE) + /* FIXME: convert to todays kernel IR infrastructure */ rc_decode = symbol_request(af9005_rc_decode); rc_keys = symbol_request(rc_map_af9005_table); rc_keys_size = symbol_request(rc_map_af9005_table_size); +#endif if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { err("af9005_rc_decode function not found, disabling remote"); af9005_properties.rc.legacy.rc_query = NULL; diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 356abb369c20..0f345b1f9014 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -44,7 +44,6 @@ #include "atbm8830.h" #include "si2168.h" #include "si2157.h" -#include "sp2.h" /* Max transfer size done by I2C transfer functions */ #define MAX_XFER_SIZE 80 @@ -147,22 +146,6 @@ static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d, } } -static int cxusb_tt_ct2_4400_gpio_tuner(struct dvb_usb_device *d, int onoff) -{ - u8 o[2], i; - int rc; - - o[0] = 0x83; - o[1] = onoff; - rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); - - if (rc) { - deb_info("gpio_write failed.\n"); - return -EIO; - } - return 0; -} - /* I2C */ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) @@ -524,30 +507,6 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event, return 0; } -static int cxusb_tt_ct2_4400_rc_query(struct dvb_usb_device *d) -{ - u8 i[2]; - int ret; - u32 cmd, keycode; - u8 rc5_cmd, rc5_addr, rc5_toggle; - - ret = cxusb_ctrl_msg(d, 0x10, NULL, 0, i, 2); - if (ret) - return ret; - - cmd = (i[0] << 8) | i[1]; - - if (cmd != 0xffff) { - rc5_cmd = cmd & 0x3F; /* bits 1-6 for command */ - rc5_addr = (cmd & 0x07C0) >> 6; /* bits 7-11 for address */ - rc5_toggle = (cmd & 0x0800) >> 11; /* bit 12 for toggle */ - keycode = (rc5_addr << 8) | rc5_cmd; - rc_keydown(d->rc_dev, RC_BIT_RC5, keycode, rc5_toggle); - } - - return 0; -} - static struct rc_map_table rc_map_dvico_mce_table[] = { { 0xfe02, KEY_TV }, { 0xfe0e, KEY_MP3 }, @@ -673,70 +632,6 @@ static struct rc_map_table rc_map_d680_dmb_table[] = { { 0x0025, KEY_POWER }, }; -static int cxusb_tt_ct2_4400_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -{ - u8 wbuf[2]; - u8 rbuf[6]; - int ret; - struct i2c_msg msg[] = { - { - .addr = 0x51, - .flags = 0, - .buf = wbuf, - .len = 2, - }, { - .addr = 0x51, - .flags = I2C_M_RD, - .buf = rbuf, - .len = 6, - } - }; - - wbuf[0] = 0x1e; - wbuf[1] = 0x00; - ret = cxusb_i2c_xfer(&d->i2c_adap, msg, 2); - - if (ret == 2) { - memcpy(mac, rbuf, 6); - return 0; - } else { - if (ret < 0) - return ret; - return -EIO; - } -} - -static int cxusb_tt_ct2_4650_ci_ctrl(void *priv, u8 read, int addr, - u8 data, int *mem) -{ - struct dvb_usb_device *d = priv; - u8 wbuf[3]; - u8 rbuf[2]; - int ret; - - wbuf[0] = (addr >> 8) & 0xff; - wbuf[1] = addr & 0xff; - - if (read) { - ret = cxusb_ctrl_msg(d, CMD_SP2_CI_READ, wbuf, 2, rbuf, 2); - } else { - wbuf[2] = data; - ret = cxusb_ctrl_msg(d, CMD_SP2_CI_WRITE, wbuf, 3, rbuf, 1); - } - - if (ret) - goto err; - - if (read) - *mem = rbuf[1]; - - return 0; -err: - deb_info("%s: ci usb write returned %d\n", __func__, ret); - return ret; - -} - static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) { static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; @@ -1408,36 +1303,34 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) return 0; } -static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap) +static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) { struct dvb_usb_device *d = adap->dev; struct cxusb_state *st = d->priv; struct i2c_adapter *adapter; struct i2c_client *client_demod; struct i2c_client *client_tuner; - struct i2c_client *client_ci; struct i2c_board_info info; struct si2168_config si2168_config; struct si2157_config si2157_config; - struct sp2_config sp2_config; - u8 o[2], i; - /* reset the tuner */ - if (cxusb_tt_ct2_4400_gpio_tuner(d, 0) < 0) { - err("clear tuner gpio failed"); - return -EIO; - } - msleep(100); - if (cxusb_tt_ct2_4400_gpio_tuner(d, 1) < 0) { - err("set tuner gpio failed"); - return -EIO; - } - msleep(100); + /* Select required USB configuration */ + if (usb_set_interface(d->udev, 0, 0) < 0) + err("set interface failed"); + + /* Unblock all USB pipes */ + usb_clear_halt(d->udev, + usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, + usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); + usb_clear_halt(d->udev, + usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); /* attach frontend */ si2168_config.i2c_adapter = &adapter; si2168_config.fe = &adap->fe_adap[0].fe; si2168_config.ts_mode = SI2168_TS_PARALLEL; + si2168_config.ts_clock_inv = 1; memset(&info, 0, sizeof(struct i2c_board_info)); strlcpy(info.type, "si2168", I2C_NAME_SIZE); info.addr = 0x64; @@ -1477,48 +1370,6 @@ static int cxusb_tt_ct2_4400_attach(struct dvb_usb_adapter *adap) st->i2c_client_tuner = client_tuner; - /* initialize CI */ - if (d->udev->descriptor.idProduct == - USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI) { - - memcpy(o, "\xc0\x01", 2); - cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); - msleep(100); - - memcpy(o, "\xc0\x00", 2); - cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); - msleep(100); - - memset(&sp2_config, 0, sizeof(sp2_config)); - sp2_config.dvb_adap = &adap->dvb_adap; - sp2_config.priv = d; - sp2_config.ci_control = cxusb_tt_ct2_4650_ci_ctrl; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "sp2", I2C_NAME_SIZE); - info.addr = 0x40; - info.platform_data = &sp2_config; - request_module(info.type); - client_ci = i2c_new_device(&d->i2c_adap, &info); - if (client_ci == NULL || client_ci->dev.driver == NULL) { - module_put(client_tuner->dev.driver->owner); - i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - return -ENODEV; - } - if (!try_module_get(client_ci->dev.driver->owner)) { - i2c_unregister_device(client_ci); - module_put(client_tuner->dev.driver->owner); - i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - return -ENODEV; - } - - st->i2c_client_ci = client_ci; - - } - return 0; } @@ -1603,7 +1454,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope static struct dvb_usb_device_properties cxusb_aver_a868r_properties; static struct dvb_usb_device_properties cxusb_d680_dmb_properties; static struct dvb_usb_device_properties cxusb_mygica_d689_properties; -static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties; +static struct dvb_usb_device_properties cxusb_mygica_t230_properties; static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -1634,7 +1485,7 @@ static int cxusb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_tt_ct2_4400_properties, + 0 == dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, THIS_MODULE, NULL, adapter_nr) || 0) return 0; @@ -1648,13 +1499,6 @@ static void cxusb_disconnect(struct usb_interface *intf) struct cxusb_state *st = d->priv; struct i2c_client *client; - /* remove I2C client for CI */ - client = st->i2c_client_ci; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - } - /* remove I2C client for tuner */ client = st->i2c_client_tuner; if (client) { @@ -1693,8 +1537,7 @@ static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, - { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_TVSTICK_CT2_4400) }, - { USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_CT2_4650_CI) }, + { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); @@ -2341,7 +2184,7 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { } }; -static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = { +static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = CYPRESS_FX2, @@ -2349,25 +2192,21 @@ static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = { .size_of_priv = sizeof(struct cxusb_state), .num_adapters = 1, - .read_mac_address = cxusb_tt_ct2_4400_read_mac_address, - .adapter = { { .num_frontends = 1, .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, - /* both frontend and tuner attached in the - same function */ - .frontend_attach = cxusb_tt_ct2_4400_attach, + .frontend_attach = cxusb_mygica_t230_frontend_attach, /* parameter for the MPEG2-data transfer */ .stream = { .type = USB_BULK, - .count = 8, - .endpoint = 0x82, + .count = 5, + .endpoint = 0x02, .u = { .bulk = { - .buffersize = 4096, + .buffersize = 8192, } } }, @@ -2375,28 +2214,25 @@ static struct dvb_usb_device_properties cxusb_tt_ct2_4400_properties = { }, }, - .i2c_algo = &cxusb_i2c_algo, + .power_ctrl = cxusb_d680_dmb_power_ctrl, + + .i2c_algo = &cxusb_i2c_algo, + .generic_bulk_ctrl_endpoint = 0x01, - .generic_bulk_ctrl_endpoint_response = 0x81, - .rc.core = { - .rc_codes = RC_MAP_TT_1500, - .allowed_protos = RC_BIT_RC5, - .rc_query = cxusb_tt_ct2_4400_rc_query, - .rc_interval = 150, + .rc.legacy = { + .rc_interval = 100, + .rc_map_table = rc_map_d680_dmb_table, + .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table), + .rc_query = cxusb_d680_dmb_rc_query, }, - .num_device_descs = 2, + .num_device_descs = 1, .devices = { { - "TechnoTrend TVStick CT2-4400", - { NULL }, - { &cxusb_table[20], NULL }, - }, - { - "TechnoTrend TT-connect CT2-4650 CI", + "Mygica T230 DVB-T/T2/C", { NULL }, - { &cxusb_table[21], NULL }, + { &cxusb_table[22], NULL }, }, } }; diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h index 29f3e2ea2476..527ff7905e15 100644 --- a/drivers/media/usb/dvb-usb/cxusb.h +++ b/drivers/media/usb/dvb-usb/cxusb.h @@ -28,14 +28,10 @@ #define CMD_ANALOG 0x50 #define CMD_DIGITAL 0x51 -#define CMD_SP2_CI_WRITE 0x70 -#define CMD_SP2_CI_READ 0x71 - struct cxusb_state { u8 gpio_write_state[3]; struct i2c_client *i2c_client_demod; struct i2c_client *i2c_client_tuner; - struct i2c_client *i2c_client_ci; }; #endif diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c index 6b0b8b6b9e2a..5801ae7f672a 100644 --- a/drivers/media/usb/dvb-usb/technisat-usb2.c +++ b/drivers/media/usb/dvb-usb/technisat-usb2.c @@ -449,6 +449,8 @@ static int technisat_usb2_read_mac_address(struct dvb_usb_device *d, return 0; } +static struct stv090x_config technisat_usb2_stv090x_config; + /* frontend attach */ static int technisat_usb2_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) @@ -472,7 +474,8 @@ static int technisat_usb2_set_voltage(struct dvb_frontend *fe, } for (i = 0; i < 3; i++) - if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0) + if (technisat_usb2_stv090x_config.set_gpio(fe, i+2, 0, + gpio[i], 0) != 0) return -EREMOTEIO; return 0; } diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 957c7ae30efe..44ae1e0661e6 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "activates debug info"); #define dprintk(fmt, arg...) do { \ if (debug) \ printk(KERN_INFO "em28xx-audio %s: " fmt, \ - __func__, ##arg); \ + __func__, ##arg); \ } while (0) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; @@ -232,7 +232,6 @@ static struct snd_pcm_hardware snd_em28xx_hw_capture = { .channels_max = 2, .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */ - /* * The period is 12.288 bytes. Allow a 10% of variation along its * value, in order to avoid overruns/underruns due to some clock @@ -361,7 +360,7 @@ static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, dprintk("Setting capture parameters\n"); ret = snd_pcm_alloc_vmalloc_buffer(substream, - params_buffer_bytes(hw_params)); + params_buffer_bytes(hw_params)); if (ret < 0) return ret; #if 0 @@ -478,7 +477,7 @@ static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, * AC97 volume control support */ static int em28xx_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *info) + struct snd_ctl_elem_info *info) { struct em28xx *dev = snd_kcontrol_chip(kcontrol); @@ -494,7 +493,7 @@ static int em28xx_vol_info(struct snd_kcontrol *kcontrol, } static int em28xx_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) + struct snd_ctl_elem_value *value) { struct em28xx *dev = snd_kcontrol_chip(kcontrol); struct snd_pcm_substream *substream = dev->adev.capture_pcm_substream; @@ -534,7 +533,7 @@ err: } static int em28xx_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *value) + struct snd_ctl_elem_value *value) { struct em28xx *dev = snd_kcontrol_chip(kcontrol); struct snd_pcm_substream *substream = dev->adev.capture_pcm_substream; @@ -655,7 +654,7 @@ static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev, struct snd_kcontrol *kctl; struct snd_kcontrol_new tmp; - memset (&tmp, 0, sizeof(tmp)); + memset(&tmp, 0, sizeof(tmp)); tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER, tmp.private_value = id, tmp.name = ctl_name, @@ -672,7 +671,7 @@ static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev, dprintk("Added control %s for ac97 volume control 0x%04x\n", ctl_name, id); - memset (&tmp, 0, sizeof(tmp)); + memset(&tmp, 0, sizeof(tmp)); tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER, tmp.private_value = id, tmp.name = ctl_name, @@ -731,7 +730,7 @@ static void em28xx_audio_free_urb(struct em28xx *dev) /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ static int em28xx_audio_ep_packet_size(struct usb_device *udev, - struct usb_endpoint_descriptor *e) + struct usb_endpoint_descriptor *e) { int size = le16_to_cpu(e->wMaxPacketSize); @@ -781,7 +780,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) interval = 1 << (ep->bInterval - 1); em28xx_info("Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d\n", - EM28XX_EP_AUDIO, usb_speed_string(dev->udev->speed), + EM28XX_EP_AUDIO, usb_speed_string(dev->udev->speed), dev->ifnum, alt, interval, ep_size); diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 6d2ea9afd57b..7be661f73930 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -27,7 +27,6 @@ #include "em28xx.h" - /* Possible i2c addresses of Micron sensors */ static unsigned short micron_sensor_addrs[] = { 0xb8 >> 1, /* MT9V111, MT9V403 */ @@ -43,7 +42,6 @@ static unsigned short omnivision_sensor_addrs[] = { I2C_CLIENT_END }; - static struct soc_camera_link camlink = { .bus_id = 0, .flags = 0, @@ -51,7 +49,6 @@ static struct soc_camera_link camlink = { .unbalanced_power = true, }; - /* FIXME: Should be replaced by a proper mt9m111 driver */ static int em28xx_initialize_mt9m111(struct em28xx *dev) { @@ -70,7 +67,6 @@ static int em28xx_initialize_mt9m111(struct em28xx *dev) return 0; } - /* FIXME: Should be replaced by a proper mt9m001 driver */ static int em28xx_initialize_mt9m001(struct em28xx *dev) { @@ -98,7 +94,6 @@ static int em28xx_initialize_mt9m001(struct em28xx *dev) return 0; } - /* * Probes Micron sensors with 8 bit address and 16 bit register width */ @@ -430,7 +425,7 @@ int em28xx_init_camera(struct em28xx *dev) break; } - fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; + fmt.code = MEDIA_BUS_FMT_YUYV8_2X8; fmt.width = 640; fmt.height = 480; v4l2_subdev_call(subdev, video, s_mbus_fmt, &fmt); diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 71fa51e7984e..d9704e66b8c9 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -64,7 +64,6 @@ module_param(usb_xfer_mode, int, 0444); MODULE_PARM_DESC(usb_xfer_mode, "USB transfer mode for frame data (-1 = auto, 0 = prefer isoc, 1 = prefer bulk)"); - /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */ static DECLARE_BITMAP(em28xx_devused, EM28XX_MAXBOARDS); @@ -190,8 +189,8 @@ static struct em28xx_reg_seq kworld_a340_digital[] = { }; static struct em28xx_reg_seq kworld_ub435q_v3_digital[] = { - {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100}, - {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 100}, + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 100}, + {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xbe, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xfe, 0xff, 100}, { -1, -1, -1, -1}, @@ -301,7 +300,6 @@ static struct em28xx_reg_seq dikom_dk300_digital[] = { { -1, -1, -1, -1}, }; - /* Reset for the most [digital] boards */ static struct em28xx_reg_seq leadership_digital[] = { {EM2874_R80_GPIO_P0_CTRL, 0x70, 0xff, 10}, @@ -479,6 +477,20 @@ static struct em28xx_reg_seq pctv_292e[] = { {-1, -1, -1, -1}, }; +static struct em28xx_reg_seq terratec_t2_stick_hd[] = { + {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0}, + {0x0d, 0xff, 0xff, 600}, + {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 10}, + {EM2874_R80_GPIO_P0_CTRL, 0xbc, 0xff, 100}, + {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 100}, + {EM2874_R80_GPIO_P0_CTRL, 0x00, 0xff, 300}, + {EM2874_R80_GPIO_P0_CTRL, 0xf8, 0xff, 100}, + {EM2874_R80_GPIO_P0_CTRL, 0xfc, 0xff, 300}, + {0x0d, 0x42, 0xff, 1000}, + {EM2874_R5F_TS_ENABLE, 0x85, 0xff, 0}, + {-1, -1, -1, -1}, +}; + /* * Button definitions */ @@ -548,7 +560,6 @@ static struct em28xx_led pctv_80e_leds[] = { {-1, 0, 0, 0}, }; - /* * Board definitions */ @@ -1514,7 +1525,7 @@ struct em28xx_board em28xx_boards[] = { .type = EM28XX_VMUX_TELEVISION, .vmux = SAA7115_COMPOSITE2, .amux = EM28XX_AMUX_VIDEO, - .aout = EM28XX_AOUT_MONO | /* I2S */ + .aout = EM28XX_AOUT_MONO | /* I2S */ EM28XX_AOUT_MASTER, /* Line out pin */ }, { .type = EM28XX_VMUX_COMPOSITE1, @@ -1536,7 +1547,7 @@ struct em28xx_board em28xx_boards[] = { .type = EM28XX_VMUX_TELEVISION, .vmux = SAA7115_COMPOSITE2, .amux = EM28XX_AMUX_VIDEO, - .aout = EM28XX_AOUT_MONO | /* I2S */ + .aout = EM28XX_AOUT_MONO | /* I2S */ EM28XX_AOUT_MASTER, /* Line out pin */ }, { .type = EM28XX_VMUX_COMPOSITE1, @@ -2243,6 +2254,31 @@ struct em28xx_board em28xx_boards[] = { .has_dvb = 1, .ir_codes = RC_MAP_PINNACLE_PCTV_HD, }, + [EM2861_BOARD_LEADTEK_VC100] = { + .name = "Leadtek VC100", + .tuner_type = TUNER_ABSENT, /* Capture only device */ + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, + /* eb1a:8179 Terratec Cinergy T2 Stick HD. + * Empia EM28178, Silicon Labs Si2168, Silicon Labs Si2146 */ + [EM28178_BOARD_TERRATEC_T2_STICK_HD] = { + .name = "Terratec Cinergy T2 Stick HD", + .def_i2c_bus = 1, + .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, + .tuner_type = TUNER_ABSENT, + .tuner_gpio = terratec_t2_stick_hd, + .has_dvb = 1, + .ir_codes = RC_MAP_TERRATEC_SLIM_2, + }, }; EXPORT_SYMBOL_GPL(em28xx_boards); @@ -2424,6 +2460,10 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM28178_BOARD_PCTV_461E }, { USB_DEVICE(0x2013, 0x025f), .driver_info = EM28178_BOARD_PCTV_292E }, + { USB_DEVICE(0x0413, 0x6f07), + .driver_info = EM2861_BOARD_LEADTEK_VC100 }, + { USB_DEVICE(0xeb1a, 0x8179), + .driver_info = EM28178_BOARD_TERRATEC_T2_STICK_HD }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -2453,6 +2493,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF}, {0x6b800080, EM2874_BOARD_LEADERSHIP_ISDBT, TUNER_ABSENT}, }; + /* NOTE: introduce a separate hash table for devices with 16 bit eeproms */ int em28xx_tuner_callback(void *ptr, int component, int command, int arg) @@ -2695,7 +2736,7 @@ static int em28xx_hint_board(struct em28xx *dev) " insmod option:\n"); for (i = 0; i < em28xx_bcount; i++) { em28xx_errdev(" card=%d -> %s\n", - i, em28xx_boards[i].name); + i, em28xx_boards[i].name); } return -1; } @@ -3051,6 +3092,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, if (le16_to_cpu(dev->udev->descriptor.idVendor) == 0xeb1a) { __le16 idProd = dev->udev->descriptor.idProduct; + if (le16_to_cpu(idProd) == 0x2710) chip_name = "em2710"; else if (le16_to_cpu(idProd) == 0x2820) @@ -3139,7 +3181,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { em28xx_errdev("%s: em28xx_i2c_register bus 0 - error [%d]!\n", - __func__, retval); + __func__, retval); return retval; } @@ -3147,13 +3189,13 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, if (dev->def_i2c_bus) { if (dev->is_em25xx) retval = em28xx_i2c_register(dev, 1, - EM28XX_I2C_ALGO_EM25XX_BUS_B); + EM28XX_I2C_ALGO_EM25XX_BUS_B); else retval = em28xx_i2c_register(dev, 1, - EM28XX_I2C_ALGO_EM28XX); + EM28XX_I2C_ALGO_EM28XX); if (retval < 0) { em28xx_errdev("%s: em28xx_i2c_register bus 1 - error [%d]!\n", - __func__, retval); + __func__, retval); em28xx_i2c_unregister(dev, 0); @@ -3193,7 +3235,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (nr >= EM28XX_MAXBOARDS) { /* No free device slots */ printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", - EM28XX_MAXBOARDS); + EM28XX_MAXBOARDS); retval = -ENOMEM; goto err_no_slot; } @@ -3377,6 +3419,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* Checks if audio is provided by a USB Audio Class interface */ for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { struct usb_interface *uif = udev->config->interface[i]; + if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { if (has_vendor_audio) em28xx_err("em28xx: device seems to have vendor AND usb audio class interfaces !\n" @@ -3487,7 +3530,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) } static int em28xx_usb_suspend(struct usb_interface *interface, - pm_message_t message) + pm_message_t message) { struct em28xx *dev; diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 901cf2b952d7..86461a708abe 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -75,7 +75,7 @@ MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); * reads data from the usb device specifying bRequest */ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, - char *buf, int len) + char *buf, int len) { int ret; int pipe = usb_rcvctrlpipe(dev->udev, 0); @@ -151,7 +151,7 @@ EXPORT_SYMBOL_GPL(em28xx_read_reg); * sends data to the usb device, specifying bRequest */ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, - int len) + int len) { int ret; int pipe = usb_sndctrlpipe(dev->udev, 0); @@ -213,7 +213,7 @@ EXPORT_SYMBOL_GPL(em28xx_write_reg); * the actual value */ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, - u8 bitmask) + u8 bitmask) { int oldval; u8 newval; @@ -222,7 +222,7 @@ int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, if (oldval < 0) return oldval; - newval = (((u8) oldval) & ~bitmask) | (val & bitmask); + newval = (((u8)oldval) & ~bitmask) | (val & bitmask); return em28xx_write_regs(dev, reg, &newval, 1); } @@ -314,7 +314,7 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val) if (ret < 0) return ret; - ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, (u8 *) &value, 2); + ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, (u8 *)&value, 2); if (ret < 0) return ret; @@ -361,7 +361,7 @@ static int set_ac97_input(struct em28xx *dev) if (ret < 0) em28xx_warn("couldn't setup AC97 register %d\n", - inputs[i].reg); + inputs[i].reg); } return 0; } @@ -445,7 +445,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000); if (ret < 0) em28xx_warn("couldn't setup AC97 register %d\n", - outputs[i].reg); + outputs[i].reg); } } @@ -483,7 +483,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) vol); if (ret < 0) em28xx_warn("couldn't setup AC97 register %d\n", - outputs[i].reg); + outputs[i].reg); } if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { @@ -531,7 +531,7 @@ int em28xx_audio_setup(struct em28xx *dev) } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) != EM28XX_CHIPCFG_AC97) { dev->int_audio_type = EM28XX_INT_AUDIO_I2S; if (dev->chip_id < CHIP_ID_EM2860 && - (cfg & EM28XX_CHIPCFG_AUDIOMASK) == + (cfg & EM28XX_CHIPCFG_AUDIOMASK) == EM2820_CHIPCFG_I2S_1_SAMPRATE) i2s_samplerates = 1; else if (dev->chip_id >= CHIP_ID_EM2860 && @@ -541,7 +541,7 @@ int em28xx_audio_setup(struct em28xx *dev) else i2s_samplerates = 3; em28xx_info("I2S Audio (%d sample rate(s))\n", - i2s_samplerates); + i2s_samplerates); /* Skip the code that does AC97 vendor detection */ dev->audio_mode.ac97 = EM28XX_NO_AC97; goto init_audio; @@ -614,8 +614,9 @@ const struct em28xx_led *em28xx_find_led(struct em28xx *dev, { if (dev->board.leds) { u8 k = 0; + while (dev->board.leds[k].role >= 0 && - dev->board.leds[k].role < EM28XX_NUM_LED_ROLES) { + dev->board.leds[k].role < EM28XX_NUM_LED_ROLES) { if (dev->board.leds[k].role == role) return &dev->board.leds[k]; k++; @@ -658,10 +659,12 @@ int em28xx_capture_start(struct em28xx *dev, int start) if (dev->mode == EM28XX_ANALOG_MODE) rc = em28xx_write_reg(dev, - EM28XX_R12_VINENABLE, 0x67); + EM28XX_R12_VINENABLE, + 0x67); else rc = em28xx_write_reg(dev, - EM28XX_R12_VINENABLE, 0x37); + EM28XX_R12_VINENABLE, + 0x37); if (rc < 0) return rc; @@ -815,9 +818,9 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) if (usb_bufs->transfer_buffer[i]) { usb_free_coherent(dev->udev, - urb->transfer_buffer_length, - usb_bufs->transfer_buffer[i], - urb->transfer_dma); + urb->transfer_buffer_length, + usb_bufs->transfer_buffer[i], + urb->transfer_dma); } usb_free_urb(urb); usb_bufs->urb[i] = NULL; @@ -889,7 +892,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, if ((xfer_bulk && !dev->analog_ep_bulk) || (!xfer_bulk && !dev->analog_ep_isoc)) { em28xx_errdev("no endpoint for analog mode and transfer type %d\n", - xfer_bulk > 0); + xfer_bulk > 0); return -EINVAL; } usb_bufs = &dev->usb_ctl.analog_bufs; @@ -988,9 +991,9 @@ EXPORT_SYMBOL_GPL(em28xx_alloc_urbs); * Allocate URBs and start IRQ */ int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, - int xfer_bulk, int num_bufs, int max_pkt_size, + int xfer_bulk, int num_bufs, int max_pkt_size, int packet_multiplier, - int (*urb_data_copy) (struct em28xx *dev, struct urb *urb)) + int (*urb_data_copy)(struct em28xx *dev, struct urb *urb)) { struct em28xx_dmaqueue *dma_q = &dev->vidq; struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 9682c52d67d1..9877b699c6bc 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -63,7 +63,6 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION(DRIVER_DESC " - digital TV interface"); MODULE_VERSION(EM28XX_VERSION); - static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); @@ -71,7 +70,7 @@ MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define dprintk(level, fmt, arg...) do { \ -if (debug >= level) \ +if (debug >= level) \ printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ } while (0) @@ -99,9 +98,8 @@ struct em28xx_dvb { struct i2c_client *i2c_client_tuner; }; - static inline void print_err_status(struct em28xx *dev, - int packet, int status) + int packet, int status) { char *errmsg = "Unknown"; @@ -169,7 +167,7 @@ static inline int em28xx_dvb_urb_data_copy(struct em28xx *dev, struct urb *urb) if (!urb->actual_length) continue; dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, - urb->actual_length); + urb->actual_length); } else { if (urb->iso_frame_desc[i].status < 0) { print_err_status(dev, i, @@ -280,7 +278,6 @@ static int em28xx_stop_feed(struct dvb_demux_feed *feed) } - /* ------------------------------------------------------------------ */ static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) { @@ -740,7 +737,7 @@ static int em28xx_pctv_290e_set_lna(struct dvb_frontend *fe) return ret; #else dev_warn(&dev->udev->dev, "%s: LNA control is disabled (lna=%u)\n", - KBUILD_MODNAME, c->lna); + KBUILD_MODNAME, c->lna); return 0; #endif } @@ -830,6 +827,7 @@ static struct zl10353_config em28xx_zl10353_no_i2c_gate_dev = { .no_tuner = 1, .parallel_ts = 1, }; + static struct qt1010_config em28xx_qt1010_config = { .i2c_address = 0x62 }; @@ -861,7 +859,6 @@ static const struct m88ds3103_config pctv_461e_m88ds3103_config = { .agc = 0x99, }; - static struct tda18271_std_map drx_j_std_map = { .atsc_6 = { .if_freq = 5000, .agc_mode = 3, .std = 0, .if_lvl = 1, .rfagc_top = 0x37, }, @@ -948,7 +945,7 @@ static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]); if (result < 0) { printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n", - dev->name, result); + dev->name, result); goto fail_frontend1; } } @@ -1047,7 +1044,7 @@ static void em28xx_unregister_dvb(struct em28xx_dvb *dvb) static int em28xx_dvb_init(struct em28xx *dev) { - int result = 0, mfe_shared = 0; + int result = 0; struct em28xx_dvb *dvb; if (dev->is_audio_only) { @@ -1182,7 +1179,8 @@ static int em28xx_dvb_init(struct em28xx *dev) &dev->i2c_adap[dev->def_i2c_bus]); if (dvb->fe[0] != NULL) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], - &dev->i2c_adap[dev->def_i2c_bus], 0x61, TUNER_THOMSON_DTT761X)) { + &dev->i2c_adap[dev->def_i2c_bus], + 0x61, TUNER_THOMSON_DTT761X)) { result = -EINVAL; goto out_free; } @@ -1204,7 +1202,8 @@ static int em28xx_dvb_init(struct em28xx *dev) &dev->i2c_adap[dev->def_i2c_bus], 0x48); if (dvb->fe[0]) { if (!dvb_attach(simple_tuner_attach, dvb->fe[0], - &dev->i2c_adap[dev->def_i2c_bus], 0x60, TUNER_PHILIPS_CU1216L)) { + &dev->i2c_adap[dev->def_i2c_bus], + 0x60, TUNER_PHILIPS_CU1216L)) { result = -EINVAL; goto out_free; } @@ -1219,7 +1218,7 @@ static int em28xx_dvb_init(struct em28xx *dev) goto out_free; } if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, - &dev->i2c_adap[dev->def_i2c_bus], + &dev->i2c_adap[dev->def_i2c_bus], &kworld_a340_config)) { dvb_frontend_detach(dvb->fe[0]); result = -EINVAL; @@ -1250,10 +1249,10 @@ static int em28xx_dvb_init(struct em28xx *dev) #ifdef CONFIG_GPIOLIB /* enable LNA for DVB-T, DVB-T2 and DVB-C */ result = gpio_request_one(dvb->lna_gpio, - GPIOF_OUT_INIT_LOW, NULL); + GPIOF_OUT_INIT_LOW, NULL); if (result) em28xx_errdev("gpio request failed %d\n", - result); + result); else gpio_free(dvb->lna_gpio); @@ -1266,6 +1265,7 @@ static int em28xx_dvb_init(struct em28xx *dev) case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: { struct xc5000_config cfg; + hauppauge_hvr930c_init(dev); dvb->fe[0] = dvb_attach(drxk_attach, @@ -1339,7 +1339,7 @@ static int em28xx_dvb_init(struct em28xx *dev) /* attach SEC */ if (dvb->fe[0]) dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], - &em28xx_a8293_config); + &em28xx_a8293_config); break; case EM2874_BOARD_DELOCK_61959: case EM2874_BOARD_MAXMEDIA_UB425_TC: @@ -1553,6 +1553,7 @@ static int em28xx_dvb_init(struct em28xx *dev) struct si2157_config si2157_config; /* attach demod */ + memset(&si2168_config, 0, sizeof(si2168_config)); si2168_config.i2c_adapter = &adapter; si2168_config.fe = &dvb->fe[0]; si2168_config.ts_mode = SI2168_TS_PARALLEL; @@ -1603,6 +1604,65 @@ static int em28xx_dvb_init(struct em28xx *dev) dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna; } break; + case EM28178_BOARD_TERRATEC_T2_STICK_HD: + { + struct i2c_adapter *adapter; + struct i2c_client *client; + struct i2c_board_info info; + struct si2168_config si2168_config; + struct si2157_config si2157_config; + + /* attach demod */ + memset(&si2168_config, 0, sizeof(si2168_config)); + si2168_config.i2c_adapter = &adapter; + si2168_config.fe = &dvb->fe[0]; + si2168_config.ts_mode = SI2168_TS_PARALLEL; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2168", I2C_NAME_SIZE); + info.addr = 0x64; + info.platform_data = &si2168_config; + request_module(info.type); + client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info); + if (client == NULL || client->dev.driver == NULL) { + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + result = -ENODEV; + goto out_free; + } + + dvb->i2c_client_demod = client; + + /* attach tuner */ + memset(&si2157_config, 0, sizeof(si2157_config)); + si2157_config.fe = dvb->fe[0]; + memset(&info, 0, sizeof(struct i2c_board_info)); + strlcpy(info.type, "si2146", I2C_NAME_SIZE); + info.addr = 0x60; + info.platform_data = &si2157_config; + request_module("si2157"); + client = i2c_new_device(adapter, &info); + if (client == NULL || client->dev.driver == NULL) { + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + module_put(dvb->i2c_client_demod->dev.driver->owner); + i2c_unregister_device(dvb->i2c_client_demod); + result = -ENODEV; + goto out_free; + } + + dvb->i2c_client_tuner = client; + } + break; default: em28xx_errdev("/2: The frontend of your DVB/ATSC card" " isn't supported yet\n"); @@ -1624,9 +1684,6 @@ static int em28xx_dvb_init(struct em28xx *dev) if (result < 0) goto out_free; - /* MFE lock */ - dvb->adapter.mfe_shared = mfe_shared; - em28xx_info("DVB extension successfully initialized\n"); kref_get(&dev->ref); diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index 1048c1a23fb6..a19b5c8b56ff 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -593,6 +593,7 @@ static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) unsigned long l = 0; int len = 0; unsigned char c; + do { if (len == length) { c = (char)len; @@ -877,6 +878,7 @@ static struct i2c_client em28xx_client_template = { * incomplete list of known devices */ static char *i2c_devs[128] = { + [0x1c >> 1] = "lgdt330x", [0x3e >> 1] = "remote IR sensor", [0x4a >> 1] = "saa7113h", [0x52 >> 1] = "drxk", @@ -949,7 +951,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, retval = i2c_add_adapter(&dev->i2c_adap[bus]); if (retval < 0) { em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", - __func__, retval); + __func__, retval); return retval; } @@ -961,7 +963,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus, retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); if ((retval < 0) && (retval != -ENODEV)) { em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", - __func__, retval); + __func__, retval); return retval; } diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 23f8f6afa2e0..d8dc03aadfbd 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -459,7 +459,7 @@ static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 *rc_type) return em2874_ir_change_protocol(rc_dev, rc_type); default: printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n", - dev->chip_id); + dev->chip_id); return -EINVAL; } } @@ -505,7 +505,7 @@ static void em28xx_query_buttons(struct work_struct *work) /* Check states of the buttons and act */ j = 0; while (dev->board.buttons[j].role >= 0 && - dev->board.buttons[j].role < EM28XX_NUM_BUTTON_ROLES) { + dev->board.buttons[j].role < EM28XX_NUM_BUTTON_ROLES) { struct em28xx_button *button = &dev->board.buttons[j]; /* Check if button uses the current address */ if (button->reg_r != dev->button_polling_addresses[i]) { @@ -607,7 +607,7 @@ static void em28xx_init_buttons(struct em28xx *dev) dev->button_polling_interval = EM28XX_BUTTONS_DEBOUNCED_QUERY_INTERVAL; while (dev->board.buttons[i].role >= 0 && - dev->board.buttons[i].role < EM28XX_NUM_BUTTON_ROLES) { + dev->board.buttons[i].role < EM28XX_NUM_BUTTON_ROLES) { struct em28xx_button *button = &dev->board.buttons[i]; /* Check if polling address is already on the list */ addr_new = true; @@ -653,11 +653,11 @@ next_button: /* Start polling */ if (dev->num_button_polling_addresses) { memset(dev->button_polling_last_values, 0, - EM28XX_NUM_BUTTON_ADDRESSES_MAX); + EM28XX_NUM_BUTTON_ADDRESSES_MAX); INIT_DELAYED_WORK(&dev->buttons_query_work, - em28xx_query_buttons); + em28xx_query_buttons); schedule_delayed_work(&dev->buttons_query_work, - msecs_to_jiffies(dev->button_polling_interval)); + msecs_to_jiffies(dev->button_polling_interval)); } } @@ -841,8 +841,7 @@ static int em28xx_ir_fini(struct em28xx *dev) if (!ir) goto ref_put; - if (ir->rc) - rc_unregister_device(ir->rc); + rc_unregister_device(ir->rc); kfree(ir->i2c_client); @@ -887,7 +886,7 @@ static int em28xx_ir_resume(struct em28xx *dev) schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); if (dev->num_button_polling_addresses) schedule_delayed_work(&dev->buttons_query_work, - msecs_to_jiffies(dev->button_polling_interval)); + msecs_to_jiffies(dev->button_polling_interval)); return 0; } diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h index 311fb349dafa..13cbb7f3ea10 100644 --- a/drivers/media/usb/em28xx/em28xx-reg.h +++ b/drivers/media/usb/em28xx/em28xx-reg.h @@ -49,7 +49,6 @@ #define EM28XX_CHIPCFG2_TS_PACKETSIZE_564 0x02 #define EM28XX_CHIPCFG2_TS_PACKETSIZE_752 0x03 - /* GPIO/GPO registers */ #define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ #define EM2820_R08_GPIO_CTRL 0x08 /* em2820-em2873/83 only */ @@ -68,7 +67,6 @@ #define EM28XX_I2C_FREQ_400_KHZ 0x01 #define EM28XX_I2C_FREQ_100_KHZ 0x00 - #define EM28XX_R0A_CHIPID 0x0a #define EM28XX_R0C_USBSUSP 0x0c #define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20 /* 1=button pressed, needs reset */ @@ -157,7 +155,6 @@ #define EM28XX_OUTFMT_YUV422_Y1UY0V 0x15 #define EM28XX_OUTFMT_YUV411 0x18 - #define EM28XX_R28_XMIN 0x28 #define EM28XX_R29_XMAX 0x29 #define EM28XX_R2A_YMIN 0x2a diff --git a/drivers/media/usb/em28xx/em28xx-v4l.h b/drivers/media/usb/em28xx/em28xx-v4l.h index 432862c20bbf..8dfcb56bf4b3 100644 --- a/drivers/media/usb/em28xx/em28xx-v4l.h +++ b/drivers/media/usb/em28xx/em28xx-v4l.h @@ -14,7 +14,6 @@ GNU General Public License for more details. */ - int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count); void em28xx_stop_vbi_streaming(struct vb2_queue *vq); extern struct vb2_ops em28xx_vbi_qops; diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index 34ee1e03a732..744e7ed743e1 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c @@ -92,7 +92,6 @@ vbi_buffer_queue(struct vb2_buffer *vb) spin_unlock_irqrestore(&dev->slock, flags); } - struct vb2_ops em28xx_vbi_qops = { .queue_setup = vbi_queue_setup, .buf_prepare = vbi_buffer_prepare, diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 03d5ece0319c..cf7f58b76292 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -81,7 +81,6 @@ MODULE_DESCRIPTION(DRIVER_DESC " - v4l2 interface"); MODULE_LICENSE("GPL"); MODULE_VERSION(EM28XX_VERSION); - #define EM25XX_FRMDATAHDR_BYTE1 0x02 #define EM25XX_FRMDATAHDR_BYTE2_STILL_IMAGE 0x20 #define EM25XX_FRMDATAHDR_BYTE2_FRAME_END 0x02 @@ -90,7 +89,6 @@ MODULE_VERSION(EM28XX_VERSION); EM25XX_FRMDATAHDR_BYTE2_FRAME_END | \ EM25XX_FRMDATAHDR_BYTE2_FRAME_ID) - static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U }; static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U }; static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = -1U }; @@ -194,9 +192,10 @@ static int em28xx_vbi_supported(struct em28xx *dev) static void em28xx_wake_i2c(struct em28xx *dev) { struct v4l2_device *v4l2_dev = &dev->v4l2->v4l2_dev; + v4l2_device_call_all(v4l2_dev, 0, core, reset, 0); v4l2_device_call_all(v4l2_dev, 0, video, s_routing, - INPUT(dev->ctl_input)->vmux, 0, 0); + INPUT(dev->ctl_input)->vmux, 0, 0); v4l2_device_call_all(v4l2_dev, 0, video, s_stream, 0); } @@ -275,7 +274,7 @@ static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, } static void em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, - u16 width, u16 height) + u16 width, u16 height) { u8 cwidth = width >> 2; u8 cheight = height >> 2; @@ -283,7 +282,7 @@ static void em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, /* NOTE: size limit: 2047x1023 = 2MPix */ em28xx_videodbg("capture area set to (%d,%d): %dx%d\n", - hstart, vstart, + hstart, vstart, ((overflow & 2) << 9 | cwidth << 2), ((overflow & 1) << 10 | cheight << 2)); @@ -406,13 +405,13 @@ set_alt: dev->packet_multiplier = EM28XX_BULK_PACKET_MULTIPLIER; } else { /* isoc */ em28xx_videodbg("minimum isoc packet size: %u (alt=%d)\n", - min_pkt_size, dev->alt); + min_pkt_size, dev->alt); dev->max_pkt_size = dev->alt_max_pkt_size_isoc[dev->alt]; dev->packet_multiplier = EM28XX_NUM_ISOC_PACKETS; } em28xx_videodbg("setting alternate %d with wMaxPacketSize=%u\n", - dev->alt, dev->max_pkt_size); + dev->alt, dev->max_pkt_size); errCode = usb_set_interface(dev->udev, dev->ifnum, dev->alt); if (errCode < 0) { em28xx_errdev("cannot change alternate number to %d (error=%i)\n", @@ -482,7 +481,7 @@ static void em28xx_copy_video(struct em28xx *dev, if ((char *)startwrite + lencopy > (char *)buf->vb_buf + buf->length) { em28xx_isocdbg("Overflow of %zu bytes past buffer end (1)\n", - ((char *)startwrite + lencopy) - + ((char *)startwrite + lencopy) - ((char *)buf->vb_buf + buf->length)); remain = (char *)buf->vb_buf + buf->length - (char *)startwrite; @@ -548,7 +547,7 @@ static void em28xx_copy_vbi(struct em28xx *dev, } static inline void print_err_status(struct em28xx *dev, - int packet, int status) + int packet, int status) { char *errmsg = "Unknown"; @@ -831,7 +830,6 @@ static inline int em28xx_urb_data_copy(struct em28xx *dev, struct urb *urb) return 1; } - static int get_ressource(enum v4l2_buf_type f_type) { switch (f_type) { @@ -1003,6 +1001,7 @@ static void em28xx_stop_streaming(struct vb2_queue *vq) } while (!list_empty(&vidq->active)) { struct em28xx_buffer *buf; + buf = list_entry(vidq->active.next, struct em28xx_buffer, list); list_del(&buf->list); vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); @@ -1033,6 +1032,7 @@ void em28xx_stop_vbi_streaming(struct vb2_queue *vq) } while (!list_empty(&vbiq->active)) { struct em28xx_buffer *buf; + buf = list_entry(vbiq->active.next, struct em28xx_buffer, list); list_del(&buf->list); vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); @@ -1109,6 +1109,7 @@ static int em28xx_vb2_setup(struct em28xx *dev) static void video_mux(struct em28xx *dev, int index) { struct v4l2_device *v4l2_dev = &dev->v4l2->v4l2_dev; + dev->ctl_input = index; dev->ctl_ainput = INPUT(index)->amux; dev->ctl_aoutput = INPUT(index)->aout; @@ -1117,21 +1118,22 @@ static void video_mux(struct em28xx *dev, int index) dev->ctl_aoutput = EM28XX_AOUT_MASTER; v4l2_device_call_all(v4l2_dev, 0, video, s_routing, - INPUT(index)->vmux, 0, 0); + INPUT(index)->vmux, 0, 0); if (dev->board.has_msp34xx) { if (dev->i2s_speed) { v4l2_device_call_all(v4l2_dev, 0, audio, - s_i2s_clock_freq, dev->i2s_speed); + s_i2s_clock_freq, dev->i2s_speed); } /* Note: this is msp3400 specific */ v4l2_device_call_all(v4l2_dev, 0, audio, s_routing, - dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0); + dev->ctl_ainput, + MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0); } if (dev->board.adecoder != EM28XX_NOADECODER) { v4l2_device_call_all(v4l2_dev, 0, audio, s_routing, - dev->ctl_ainput, dev->ctl_aoutput, 0); + dev->ctl_ainput, dev->ctl_aoutput, 0); } em28xx_audio_analog_set(dev); @@ -1203,7 +1205,7 @@ static const struct v4l2_ctrl_ops em28xx_ctrl_ops = { }; static void size_to_scale(struct em28xx *dev, - unsigned int width, unsigned int height, + unsigned int width, unsigned int height, unsigned int *hscale, unsigned int *vscale) { unsigned int maxw = norm_maxw(dev); @@ -1234,7 +1236,7 @@ static void scale_to_size(struct em28xx *dev, ------------------------------------------------------------------*/ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev->v4l2; @@ -1267,7 +1269,7 @@ static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc) } static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev->v4l2; @@ -1338,7 +1340,7 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, /* set new image size */ size_to_scale(dev, v4l2->width, v4l2->height, - &v4l2->hscale, &v4l2->vscale); + &v4l2->hscale, &v4l2->vscale); em28xx_resolution_set(dev); @@ -1346,7 +1348,7 @@ static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, } static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) + struct v4l2_format *f) { struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev->v4l2; @@ -1401,7 +1403,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) v4l2->width = f.fmt.pix.width; v4l2->height = f.fmt.pix.height; size_to_scale(dev, v4l2->width, v4l2->height, - &v4l2->hscale, &v4l2->vscale); + &v4l2->hscale, &v4l2->vscale); em28xx_resolution_set(dev); v4l2_device_call_all(&v4l2->v4l2_dev, 0, video, s_std, v4l2->norm); @@ -1422,7 +1424,7 @@ static int vidioc_g_parm(struct file *file, void *priv, video, g_parm, p); else v4l2_video_std_frame_period(v4l2->norm, - &p->parm.capture.timeperframe); + &p->parm.capture.timeperframe); return rc; } @@ -1450,7 +1452,7 @@ static const char *iname[] = { }; static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) + struct v4l2_input *i) { struct em28xx *dev = video_drvdata(file); unsigned int n; @@ -1467,7 +1469,7 @@ static int vidioc_enum_input(struct file *file, void *priv, strcpy(i->name, iname[INPUT(n)->type]); if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) || - (EM28XX_VMUX_CABLE == INPUT(n)->type)) + (EM28XX_VMUX_CABLE == INPUT(n)->type)) i->type = V4L2_INPUT_TYPE_TUNER; i->std = dev->v4l2->vdev->tvnorms; @@ -1558,7 +1560,7 @@ static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio } static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) + struct v4l2_tuner *t) { struct em28xx *dev = video_drvdata(file); @@ -1572,7 +1574,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, } static int vidioc_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *t) + const struct v4l2_tuner *t) { struct em28xx *dev = video_drvdata(file); @@ -1584,7 +1586,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, } static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) + struct v4l2_frequency *f) { struct em28xx *dev = video_drvdata(file); struct em28xx_v4l2 *v4l2 = dev->v4l2; @@ -1597,7 +1599,7 @@ static int vidioc_g_frequency(struct file *file, void *priv, } static int vidioc_s_frequency(struct file *file, void *priv, - const struct v4l2_frequency *f) + const struct v4l2_frequency *f) { struct v4l2_frequency new_freq = *f; struct em28xx *dev = video_drvdata(file); @@ -1615,7 +1617,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, #ifdef CONFIG_VIDEO_ADV_DEBUG static int vidioc_g_chip_info(struct file *file, void *priv, - struct v4l2_dbg_chip_info *chip) + struct v4l2_dbg_chip_info *chip) { struct em28xx *dev = video_drvdata(file); @@ -1670,6 +1672,7 @@ static int vidioc_g_register(struct file *file, void *priv, reg->val = ret; } else { __le16 val = 0; + ret = dev->em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, reg->reg, (char *)&val, 2); if (ret < 0) @@ -1700,9 +1703,8 @@ static int vidioc_s_register(struct file *file, void *priv, } #endif - static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) + struct v4l2_capability *cap) { struct video_device *vdev = video_devdata(file); struct em28xx *dev = video_drvdata(file); @@ -1736,7 +1738,7 @@ static int vidioc_querycap(struct file *file, void *priv, } static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) + struct v4l2_fmtdesc *f) { if (unlikely(f->index >= ARRAY_SIZE(format))) return -EINVAL; @@ -2177,9 +2179,10 @@ static unsigned short msp3400_addrs[] = { /******************************** usb interface ******************************/ -static struct video_device *em28xx_vdev_init(struct em28xx *dev, - const struct video_device *template, - const char *type_name) +static struct video_device +*em28xx_vdev_init(struct em28xx *dev, + const struct video_device *template, + const char *type_name) { struct video_device *vfd; @@ -2344,21 +2347,24 @@ static int em28xx_v4l2_init(struct em28xx *dev) if (dev->board.radio.type) v4l2_i2c_new_subdev(&v4l2->v4l2_dev, - &dev->i2c_adap[dev->def_i2c_bus], - "tuner", dev->board.radio_addr, NULL); + &dev->i2c_adap[dev->def_i2c_bus], + "tuner", dev->board.radio_addr, + NULL); if (has_demod) v4l2_i2c_new_subdev(&v4l2->v4l2_dev, - &dev->i2c_adap[dev->def_i2c_bus], "tuner", - 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); + &dev->i2c_adap[dev->def_i2c_bus], + "tuner", 0, + v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); if (tuner_addr == 0) { enum v4l2_i2c_tuner_type type = has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; struct v4l2_subdev *sd; sd = v4l2_i2c_new_subdev(&v4l2->v4l2_dev, - &dev->i2c_adap[dev->def_i2c_bus], "tuner", - 0, v4l2_i2c_tuner_addrs(type)); + &dev->i2c_adap[dev->def_i2c_bus], + "tuner", 0, + v4l2_i2c_tuner_addrs(type)); if (sd) tuner_addr = v4l2_i2c_subdev_addr(sd); @@ -2378,20 +2384,20 @@ static int em28xx_v4l2_init(struct em28xx *dev) ret = em28xx_audio_setup(dev); if (ret < 0) { em28xx_errdev("%s: Error while setting audio - error [%d]!\n", - __func__, ret); + __func__, ret); goto unregister_dev; } if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, - V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); + V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops, - V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f); + V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f); } else { /* install the em28xx notify callback */ v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE), - em28xx_ctrl_notify, dev); + em28xx_ctrl_notify, dev); v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME), - em28xx_ctrl_notify, dev); + em28xx_ctrl_notify, dev); } /* wake i2c devices */ @@ -2518,7 +2524,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) /* register v4l2 video video_device */ ret = video_register_device(v4l2->vdev, VFL_TYPE_GRABBER, - video_nr[dev->devno]); + video_nr[dev->devno]); if (ret) { em28xx_errdev("unable to register video device (error=%i).\n", ret); diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index a21a7463b557..9c7075344109 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -141,6 +141,8 @@ #define EM28178_BOARD_PCTV_461E 92 #define EM2874_BOARD_KWORLD_UB435Q_V3 93 #define EM28178_BOARD_PCTV_292E 94 +#define EM2861_BOARD_LEADTEK_VC100 95 +#define EM28178_BOARD_TERRATEC_T2_STICK_HD 96 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 @@ -215,7 +217,6 @@ enum em28xx_mode { EM28XX_DIGITAL_MODE, }; - struct em28xx; struct em28xx_usb_bufs { @@ -243,11 +244,11 @@ struct em28xx_usb_ctl { struct em28xx_usb_bufs digital_bufs; /* Stores already requested buffers */ - struct em28xx_buffer *vid_buf; - struct em28xx_buffer *vbi_buf; + struct em28xx_buffer *vid_buf; + struct em28xx_buffer *vbi_buf; /* copy data from URB */ - int (*urb_data_copy) (struct em28xx *dev, struct urb *urb); + int (*urb_data_copy)(struct em28xx *dev, struct urb *urb); }; @@ -695,14 +696,14 @@ struct em28xx { char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ /* helper funcs that call usb_control_msg */ - int (*em28xx_write_regs) (struct em28xx *dev, u16 reg, - char *buf, int len); - int (*em28xx_read_reg) (struct em28xx *dev, u16 reg); - int (*em28xx_read_reg_req_len) (struct em28xx *dev, u8 req, u16 reg, - char *buf, int len); - int (*em28xx_write_regs_req) (struct em28xx *dev, u8 req, u16 reg, - char *buf, int len); - int (*em28xx_read_reg_req) (struct em28xx *dev, u8 req, u16 reg); + int (*em28xx_write_regs)(struct em28xx *dev, u16 reg, + char *buf, int len); + int (*em28xx_read_reg)(struct em28xx *dev, u16 reg); + int (*em28xx_read_reg_req_len)(struct em28xx *dev, u8 req, u16 reg, + char *buf, int len); + int (*em28xx_write_regs_req)(struct em28xx *dev, u8 req, u16 reg, + char *buf, int len); + int (*em28xx_read_reg_req)(struct em28xx *dev, u8 req, u16 reg); enum em28xx_mode mode; @@ -745,7 +746,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val); int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, - u8 bitmask); + u8 bitmask); int em28xx_toggle_reg_bits(struct em28xx *dev, u16 reg, u8 bitmask); int em28xx_read_ac97(struct em28xx *dev, u8 reg); diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c index ec799b4d88be..d6bf982efa42 100644 --- a/drivers/media/usb/go7007/go7007-v4l2.c +++ b/drivers/media/usb/go7007/go7007-v4l2.c @@ -252,7 +252,7 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try) if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { struct v4l2_mbus_framefmt mbus_fmt; - mbus_fmt.code = V4L2_MBUS_FMT_FIXED; + mbus_fmt.code = MEDIA_BUS_FMT_FIXED; mbus_fmt.width = fmt ? fmt->fmt.pix.width : width; mbus_fmt.height = height; go->encoder_h_halve = 0; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c index 7c19ff72e6b3..c8761c71c9d2 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-context.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c @@ -80,7 +80,7 @@ static void pvr2_context_set_notify(struct pvr2_context *mp, int fl) static void pvr2_context_destroy(struct pvr2_context *mp) { pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (destroy)",mp); - if (mp->hdw) pvr2_hdw_destroy(mp->hdw); + pvr2_hdw_destroy(mp->hdw); pvr2_context_set_notify(mp, 0); mutex_lock(&pvr2_context_mutex); if (mp->exist_next) { diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 9623b6218214..2fd9b5e0e2a9 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2966,7 +2966,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) memset(&fmt, 0, sizeof(fmt)); fmt.width = hdw->res_hor_val; fmt.height = hdw->res_ver_val; - fmt.code = V4L2_MBUS_FMT_FIXED; + fmt.code = MEDIA_BUS_FMT_FIXED; pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)", fmt.width, fmt.height); v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_mbus_fmt, &fmt); diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index ccc00099b261..de55e96fed15 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -558,27 +558,30 @@ static void s2255_fwchunk_complete(struct urb *urb) } -static int s2255_got_frame(struct s2255_vc *vc, int jpgsize) +static void s2255_got_frame(struct s2255_vc *vc, int jpgsize) { struct s2255_buffer *buf; struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev); unsigned long flags = 0; - int rc = 0; + spin_lock_irqsave(&vc->qlock, flags); if (list_empty(&vc->buf_list)) { dprintk(dev, 1, "No active queue to serve\n"); - rc = -1; - goto unlock; + spin_unlock_irqrestore(&vc->qlock, flags); + return; } buf = list_entry(vc->buf_list.next, struct s2255_buffer, list); list_del(&buf->list); v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); + buf->vb.v4l2_buf.field = vc->field; + buf->vb.v4l2_buf.sequence = vc->frame_count; + spin_unlock_irqrestore(&vc->qlock, flags); + s2255_fillbuff(vc, buf, jpgsize); + /* tell v4l buffer was filled */ + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf); -unlock: - spin_unlock_irqrestore(&vc->qlock, flags); - return rc; } static const struct s2255_fmt *format_by_fourcc(int fourcc) @@ -632,7 +635,7 @@ static void s2255_fillbuff(struct s2255_vc *vc, break; case V4L2_PIX_FMT_JPEG: case V4L2_PIX_FMT_MJPEG: - buf->vb.v4l2_buf.length = jpgsize; + vb2_set_plane_payload(&buf->vb, 0, jpgsize); memcpy(vbuf, tmpbuf, jpgsize); break; case V4L2_PIX_FMT_YUV422P: @@ -649,11 +652,6 @@ static void s2255_fillbuff(struct s2255_vc *vc, } dprintk(dev, 2, "s2255fill at : Buffer 0x%08lx size= %d\n", (unsigned long)vbuf, pos); - /* tell v4l buffer was filled */ - buf->vb.v4l2_buf.field = vc->field; - buf->vb.v4l2_buf.sequence = vc->frame_count; - v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp); - vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); } @@ -1976,8 +1974,7 @@ static int s2255_release_sys_buffers(struct s2255_vc *vc) { unsigned long i; for (i = 0; i < SYS_FRAMES; i++) { - if (vc->buffer.frame[i].lpvbits) - vfree(vc->buffer.frame[i].lpvbits); + vfree(vc->buffer.frame[i].lpvbits); vc->buffer.frame[i].lpvbits = NULL; } return 0; diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c index 233054311a62..a47629108c1b 100644 --- a/drivers/media/usb/stk1160/stk1160-v4l.c +++ b/drivers/media/usb/stk1160/stk1160-v4l.c @@ -475,7 +475,7 @@ static int vidioc_s_register(struct file *file, void *priv, struct stk1160 *dev = video_drvdata(file); /* Match host */ - return stk1160_write_reg(dev, reg->reg, cpu_to_le16(reg->val)); + return stk1160_write_reg(dev, reg->reg, reg->val); } #endif diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index 9bfa041e3316..693d5f409138 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -509,11 +509,12 @@ static int vidioc_querycap(struct file *file, void *priv, usbvision_device_data[usbvision->dev_model].model_string, sizeof(vc->card)); usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info)); - vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | + vc->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | (usbvision->have_tuner ? V4L2_CAP_TUNER : 0); + vc->capabilities = vc->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 7c8322d4fc63..6a4b0b8cd270 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -331,6 +331,7 @@ static int uvc_parse_format(struct uvc_device *dev, struct uvc_format_desc *fmtdesc; struct uvc_frame *frame; const unsigned char *start = buffer; + unsigned int width_multiplier = 1; unsigned int interval; unsigned int i, n; __u8 ftype; @@ -366,6 +367,20 @@ static int uvc_parse_format(struct uvc_device *dev, } format->bpp = buffer[21]; + + /* Some devices report a format that doesn't match what they + * really send. + */ + if (dev->quirks & UVC_QUIRK_FORCE_Y8) { + if (format->fcc == V4L2_PIX_FMT_YUYV) { + strlcpy(format->name, "Greyscale 8-bit (Y8 )", + sizeof(format->name)); + format->fcc = V4L2_PIX_FMT_GREY; + format->bpp = 8; + width_multiplier = 2; + } + } + if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) { ftype = UVC_VS_FRAME_UNCOMPRESSED; } else { @@ -474,7 +489,8 @@ static int uvc_parse_format(struct uvc_device *dev, frame->bFrameIndex = buffer[3]; frame->bmCapabilities = buffer[4]; - frame->wWidth = get_unaligned_le16(&buffer[5]); + frame->wWidth = get_unaligned_le16(&buffer[5]) + * width_multiplier; frame->wHeight = get_unaligned_le16(&buffer[7]); frame->dwMinBitRate = get_unaligned_le32(&buffer[9]); frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]); @@ -1623,12 +1639,12 @@ static void uvc_delete(struct uvc_device *dev) { struct list_head *p, *n; - usb_put_intf(dev->intf); - usb_put_dev(dev->udev); - uvc_status_cleanup(dev); uvc_ctrl_cleanup_device(dev); + usb_put_intf(dev->intf); + usb_put_dev(dev->udev); + if (dev->vdev.dev) v4l2_device_unregister(&dev->vdev); #ifdef CONFIG_MEDIA_CONTROLLER @@ -1718,6 +1734,11 @@ static int uvc_register_video(struct uvc_device *dev, struct video_device *vdev; int ret; + /* Initialize the video buffers queue. */ + ret = uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param); + if (ret) + return ret; + /* Initialize the streaming interface with default streaming * parameters. */ @@ -1744,6 +1765,7 @@ static int uvc_register_video(struct uvc_device *dev, */ vdev->v4l2_dev = &dev->vdev; vdev->fops = &uvc_fops; + vdev->ioctl_ops = &uvc_ioctl_ops; vdev->release = uvc_release; vdev->prio = &stream->chain->prio; if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) @@ -1991,14 +2013,13 @@ static int __uvc_resume(struct usb_interface *intf, int reset) { struct uvc_device *dev = usb_get_intfdata(intf); struct uvc_streaming *stream; + int ret = 0; uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n", intf->cur_altsetting->desc.bInterfaceNumber); if (intf->cur_altsetting->desc.bInterfaceSubClass == UVC_SC_VIDEOCONTROL) { - int ret = 0; - if (reset) { ret = uvc_ctrl_restore_values(dev); if (ret < 0) @@ -2014,8 +2035,13 @@ static int __uvc_resume(struct usb_interface *intf, int reset) } list_for_each_entry(stream, &dev->streams, list) { - if (stream->intf == intf) - return uvc_video_resume(stream, reset); + if (stream->intf == intf) { + ret = uvc_video_resume(stream, reset); + if (ret < 0) + uvc_queue_streamoff(&stream->queue, + stream->queue.queue.type); + return ret; + } } uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface " @@ -2504,6 +2530,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_IGNORE_SELECTOR_UNIT }, + /* Oculus VR Positional Tracker DK2 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x2833, + .idProduct = 0x0201, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_FORCE_Y8 }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, {} diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index 6e92d2080255..cc960723b926 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -36,6 +36,34 @@ * the driver. */ +static inline struct uvc_streaming * +uvc_queue_to_stream(struct uvc_video_queue *queue) +{ + return container_of(queue, struct uvc_streaming, queue); +} + +/* + * Return all queued buffers to videobuf2 in the requested state. + * + * This function must be called with the queue spinlock held. + */ +static void uvc_queue_return_buffers(struct uvc_video_queue *queue, + enum uvc_buffer_state state) +{ + enum vb2_buffer_state vb2_state = state == UVC_BUF_STATE_ERROR + ? VB2_BUF_STATE_ERROR + : VB2_BUF_STATE_QUEUED; + + while (!list_empty(&queue->irqqueue)) { + struct uvc_buffer *buf = list_first_entry(&queue->irqqueue, + struct uvc_buffer, + queue); + list_del(&buf->queue); + buf->state = state; + vb2_buffer_done(&buf->buf, vb2_state); + } +} + /* ----------------------------------------------------------------------------- * videobuf2 queue operations */ @@ -45,8 +73,7 @@ static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int sizes[], void *alloc_ctxs[]) { struct uvc_video_queue *queue = vb2_get_drv_priv(vq); - struct uvc_streaming *stream = - container_of(queue, struct uvc_streaming, queue); + struct uvc_streaming *stream = uvc_queue_to_stream(queue); /* Make sure the image size is large enough. */ if (fmt && fmt->fmt.pix.sizeimage < stream->ctrl.dwMaxVideoFrameSize) @@ -109,8 +136,7 @@ static void uvc_buffer_queue(struct vb2_buffer *vb) static void uvc_buffer_finish(struct vb2_buffer *vb) { struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); - struct uvc_streaming *stream = - container_of(queue, struct uvc_streaming, queue); + struct uvc_streaming *stream = uvc_queue_to_stream(queue); struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); if (vb->state == VB2_BUF_STATE_DONE) @@ -131,6 +157,39 @@ static void uvc_wait_finish(struct vb2_queue *vq) mutex_lock(&queue->mutex); } +static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct uvc_video_queue *queue = vb2_get_drv_priv(vq); + struct uvc_streaming *stream = uvc_queue_to_stream(queue); + unsigned long flags; + int ret; + + queue->buf_used = 0; + + ret = uvc_video_enable(stream, 1); + if (ret == 0) + return 0; + + spin_lock_irqsave(&queue->irqlock, flags); + uvc_queue_return_buffers(queue, UVC_BUF_STATE_QUEUED); + spin_unlock_irqrestore(&queue->irqlock, flags); + + return ret; +} + +static void uvc_stop_streaming(struct vb2_queue *vq) +{ + struct uvc_video_queue *queue = vb2_get_drv_priv(vq); + struct uvc_streaming *stream = uvc_queue_to_stream(queue); + unsigned long flags; + + uvc_video_enable(stream, 0); + + spin_lock_irqsave(&queue->irqlock, flags); + uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR); + spin_unlock_irqrestore(&queue->irqlock, flags); +} + static struct vb2_ops uvc_queue_qops = { .queue_setup = uvc_queue_setup, .buf_prepare = uvc_buffer_prepare, @@ -138,6 +197,8 @@ static struct vb2_ops uvc_queue_qops = { .buf_finish = uvc_buffer_finish, .wait_prepare = uvc_wait_prepare, .wait_finish = uvc_wait_finish, + .start_streaming = uvc_start_streaming, + .stop_streaming = uvc_stop_streaming, }; int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, @@ -165,12 +226,19 @@ int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, return 0; } +void uvc_queue_release(struct uvc_video_queue *queue) +{ + mutex_lock(&queue->mutex); + vb2_queue_release(&queue->queue); + mutex_unlock(&queue->mutex); +} + /* ----------------------------------------------------------------------------- * V4L2 queue operations */ -int uvc_alloc_buffers(struct uvc_video_queue *queue, - struct v4l2_requestbuffers *rb) +int uvc_request_buffers(struct uvc_video_queue *queue, + struct v4l2_requestbuffers *rb) { int ret; @@ -181,13 +249,6 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, return ret ? ret : rb->count; } -void uvc_free_buffers(struct uvc_video_queue *queue) -{ - mutex_lock(&queue->mutex); - vb2_queue_release(&queue->queue); - mutex_unlock(&queue->mutex); -} - int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf) { int ret; @@ -234,6 +295,28 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *buf, return ret; } +int uvc_queue_streamon(struct uvc_video_queue *queue, enum v4l2_buf_type type) +{ + int ret; + + mutex_lock(&queue->mutex); + ret = vb2_streamon(&queue->queue, type); + mutex_unlock(&queue->mutex); + + return ret; +} + +int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type) +{ + int ret; + + mutex_lock(&queue->mutex); + ret = vb2_streamoff(&queue->queue, type); + mutex_unlock(&queue->mutex); + + return ret; +} + int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) { int ret; @@ -289,49 +372,6 @@ int uvc_queue_allocated(struct uvc_video_queue *queue) } /* - * Enable or disable the video buffers queue. - * - * The queue must be enabled before starting video acquisition and must be - * disabled after stopping it. This ensures that the video buffers queue - * state can be properly initialized before buffers are accessed from the - * interrupt handler. - * - * Enabling the video queue returns -EBUSY if the queue is already enabled. - * - * Disabling the video queue cancels the queue and removes all buffers from - * the main queue. - * - * This function can't be called from interrupt context. Use - * uvc_queue_cancel() instead. - */ -int uvc_queue_enable(struct uvc_video_queue *queue, int enable) -{ - unsigned long flags; - int ret; - - mutex_lock(&queue->mutex); - if (enable) { - ret = vb2_streamon(&queue->queue, queue->queue.type); - if (ret < 0) - goto done; - - queue->buf_used = 0; - } else { - ret = vb2_streamoff(&queue->queue, queue->queue.type); - if (ret < 0) - goto done; - - spin_lock_irqsave(&queue->irqlock, flags); - INIT_LIST_HEAD(&queue->irqqueue); - spin_unlock_irqrestore(&queue->irqlock, flags); - } - -done: - mutex_unlock(&queue->mutex); - return ret; -} - -/* * Cancel the video buffers queue. * * Cancelling the queue marks all buffers on the irq queue as erroneous, @@ -345,17 +385,10 @@ done: */ void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect) { - struct uvc_buffer *buf; unsigned long flags; spin_lock_irqsave(&queue->irqlock, flags); - while (!list_empty(&queue->irqqueue)) { - buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, - queue); - list_del(&buf->queue); - buf->state = UVC_BUF_STATE_ERROR; - vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); - } + uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR); /* This must be protected by the irqlock spinlock to avoid race * conditions between uvc_buffer_queue and the disconnection event that * could result in an interruptible wait in uvc_dequeue_buffer. Do not diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 378ae02e593b..9c5cbcf16529 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -530,10 +530,8 @@ static int uvc_v4l2_release(struct file *file) uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n"); /* Only free resources if this is a privileged handle. */ - if (uvc_has_privileges(handle)) { - uvc_video_enable(stream, 0); - uvc_free_buffers(&stream->queue); - } + if (uvc_has_privileges(handle)) + uvc_queue_release(&stream->queue); /* Release the file handle. */ uvc_dismiss_privileges(handle); @@ -551,553 +549,628 @@ static int uvc_v4l2_release(struct file *file) return 0; } -static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) +static int uvc_ioctl_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) { struct video_device *vdev = video_devdata(file); struct uvc_fh *handle = file->private_data; struct uvc_video_chain *chain = handle->chain; struct uvc_streaming *stream = handle->stream; - long ret = 0; - switch (cmd) { - /* Query capabilities */ - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memset(cap, 0, sizeof *cap); - strlcpy(cap->driver, "uvcvideo", sizeof cap->driver); - strlcpy(cap->card, vdev->name, sizeof cap->card); - usb_make_path(stream->dev->udev, - cap->bus_info, sizeof(cap->bus_info)); - cap->version = LINUX_VERSION_CODE; - cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING - | chain->caps; - if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE - | V4L2_CAP_STREAMING; - else - cap->device_caps = V4L2_CAP_VIDEO_OUTPUT - | V4L2_CAP_STREAMING; - break; - } + strlcpy(cap->driver, "uvcvideo", sizeof(cap->driver)); + strlcpy(cap->card, vdev->name, sizeof(cap->card)); + usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info)); + cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING + | chain->caps; + if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + else + cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; - /* Priority */ - case VIDIOC_G_PRIORITY: - *(u32 *)arg = v4l2_prio_max(vdev->prio); - break; + return 0; +} - case VIDIOC_S_PRIORITY: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; +static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream, + struct v4l2_fmtdesc *fmt) +{ + struct uvc_format *format; + enum v4l2_buf_type type = fmt->type; + __u32 index = fmt->index; - return v4l2_prio_change(vdev->prio, &handle->vfh.prio, - *(u32 *)arg); + if (fmt->type != stream->type || fmt->index >= stream->nformats) + return -EINVAL; - /* Get, Set & Query control */ - case VIDIOC_QUERYCTRL: - return uvc_query_v4l2_ctrl(chain, arg); + memset(fmt, 0, sizeof(*fmt)); + fmt->index = index; + fmt->type = type; + + format = &stream->format[fmt->index]; + fmt->flags = 0; + if (format->flags & UVC_FMT_FLAG_COMPRESSED) + fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; + strlcpy(fmt->description, format->name, sizeof(fmt->description)); + fmt->description[sizeof(fmt->description) - 1] = 0; + fmt->pixelformat = format->fcc; + return 0; +} - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - struct v4l2_ext_control xctrl; +static int uvc_ioctl_enum_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_fmtdesc *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - memset(&xctrl, 0, sizeof xctrl); - xctrl.id = ctrl->id; + return uvc_ioctl_enum_fmt(stream, fmt); +} - ret = uvc_ctrl_begin(chain); - if (ret < 0) - return ret; +static int uvc_ioctl_enum_fmt_vid_out(struct file *file, void *fh, + struct v4l2_fmtdesc *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - ret = uvc_ctrl_get(chain, &xctrl); - uvc_ctrl_rollback(handle); - if (ret >= 0) - ctrl->value = xctrl.value; - break; - } + return uvc_ioctl_enum_fmt(stream, fmt); +} - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - struct v4l2_ext_control xctrl; +static int uvc_ioctl_g_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; + return uvc_v4l2_get_format(stream, fmt); +} - memset(&xctrl, 0, sizeof xctrl); - xctrl.id = ctrl->id; - xctrl.value = ctrl->value; +static int uvc_ioctl_g_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - ret = uvc_ctrl_begin(chain); - if (ret < 0) - return ret; + return uvc_v4l2_get_format(stream, fmt); +} - ret = uvc_ctrl_set(chain, &xctrl); - if (ret < 0) { - uvc_ctrl_rollback(handle); - return ret; - } - ret = uvc_ctrl_commit(handle, &xctrl, 1); - if (ret == 0) - ctrl->value = xctrl.value; - break; - } +static int uvc_ioctl_s_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - case VIDIOC_QUERYMENU: - return uvc_query_v4l2_menu(chain, arg); + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *ctrls = arg; - struct v4l2_ext_control *ctrl = ctrls->controls; - unsigned int i; + return uvc_v4l2_set_format(stream, fmt); +} - ret = uvc_ctrl_begin(chain); - if (ret < 0) - return ret; +static int uvc_ioctl_s_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - for (i = 0; i < ctrls->count; ++ctrl, ++i) { - ret = uvc_ctrl_get(chain, ctrl); - if (ret < 0) { - uvc_ctrl_rollback(handle); - ctrls->error_idx = i; - return ret; - } - } - ctrls->error_idx = 0; - ret = uvc_ctrl_rollback(handle); - break; - } + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - case VIDIOC_S_EXT_CTRLS: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; - /* Fall through */ - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *ctrls = arg; - struct v4l2_ext_control *ctrl = ctrls->controls; - unsigned int i; - - ret = uvc_ctrl_begin(chain); - if (ret < 0) - return ret; + return uvc_v4l2_set_format(stream, fmt); +} - for (i = 0; i < ctrls->count; ++ctrl, ++i) { - ret = uvc_ctrl_set(chain, ctrl); - if (ret < 0) { - uvc_ctrl_rollback(handle); - ctrls->error_idx = cmd == VIDIOC_S_EXT_CTRLS - ? ctrls->count : i; - return ret; - } - } +static int uvc_ioctl_try_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + struct uvc_streaming_control probe; - ctrls->error_idx = 0; + return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL); +} - if (cmd == VIDIOC_S_EXT_CTRLS) - ret = uvc_ctrl_commit(handle, - ctrls->controls, ctrls->count); - else - ret = uvc_ctrl_rollback(handle); - break; - } +static int uvc_ioctl_try_fmt_vid_out(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + struct uvc_streaming_control probe; - /* Get, Set & Enum input */ - case VIDIOC_ENUMINPUT: - { - const struct uvc_entity *selector = chain->selector; - struct v4l2_input *input = arg; - struct uvc_entity *iterm = NULL; - u32 index = input->index; - int pin = 0; - - if (selector == NULL || - (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { - if (index != 0) - return -EINVAL; - list_for_each_entry(iterm, &chain->entities, chain) { - if (UVC_ENTITY_IS_ITERM(iterm)) - break; - } - pin = iterm->id; - } else if (index < selector->bNrInPins) { - pin = selector->baSourceID[index]; - list_for_each_entry(iterm, &chain->entities, chain) { - if (!UVC_ENTITY_IS_ITERM(iterm)) - continue; - if (iterm->id == pin) - break; - } - } + return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL); +} - if (iterm == NULL || iterm->id != pin) - return -EINVAL; +static int uvc_ioctl_reqbufs(struct file *file, void *fh, + struct v4l2_requestbuffers *rb) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - memset(input, 0, sizeof *input); - input->index = index; - strlcpy(input->name, iterm->name, sizeof input->name); - if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA) - input->type = V4L2_INPUT_TYPE_CAMERA; - break; - } + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - case VIDIOC_G_INPUT: - { - u8 input; + mutex_lock(&stream->mutex); + ret = uvc_request_buffers(&stream->queue, rb); + mutex_unlock(&stream->mutex); + if (ret < 0) + return ret; - if (chain->selector == NULL || - (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { - *(int *)arg = 0; - break; - } + if (ret == 0) + uvc_dismiss_privileges(handle); - ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, - chain->selector->id, chain->dev->intfnum, - UVC_SU_INPUT_SELECT_CONTROL, &input, 1); - if (ret < 0) - return ret; + return 0; +} - *(int *)arg = input - 1; - break; - } +static int uvc_ioctl_querybuf(struct file *file, void *fh, + struct v4l2_buffer *buf) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - case VIDIOC_S_INPUT: - { - u32 input = *(u32 *)arg + 1; + if (!uvc_has_privileges(handle)) + return -EBUSY; - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; + return uvc_query_buffer(&stream->queue, buf); +} - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; +static int uvc_ioctl_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - if (chain->selector == NULL || - (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { - if (input != 1) - return -EINVAL; - break; - } + if (!uvc_has_privileges(handle)) + return -EBUSY; - if (input == 0 || input > chain->selector->bNrInPins) - return -EINVAL; + return uvc_queue_buffer(&stream->queue, buf); +} - return uvc_query_ctrl(chain->dev, UVC_SET_CUR, - chain->selector->id, chain->dev->intfnum, - UVC_SU_INPUT_SELECT_CONTROL, &input, 1); - } +static int uvc_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - /* Try, Get, Set & Enum format */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmt = arg; - struct uvc_format *format; - enum v4l2_buf_type type = fmt->type; - __u32 index = fmt->index; + if (!uvc_has_privileges(handle)) + return -EBUSY; - if (fmt->type != stream->type || - fmt->index >= stream->nformats) - return -EINVAL; + return uvc_dequeue_buffer(&stream->queue, buf, + file->f_flags & O_NONBLOCK); +} - memset(fmt, 0, sizeof(*fmt)); - fmt->index = index; - fmt->type = type; - - format = &stream->format[fmt->index]; - fmt->flags = 0; - if (format->flags & UVC_FMT_FLAG_COMPRESSED) - fmt->flags |= V4L2_FMT_FLAG_COMPRESSED; - strlcpy(fmt->description, format->name, - sizeof fmt->description); - fmt->description[sizeof fmt->description - 1] = 0; - fmt->pixelformat = format->fcc; - break; - } +static int uvc_ioctl_create_bufs(struct file *file, void *fh, + struct v4l2_create_buffers *cb) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - case VIDIOC_TRY_FMT: - { - struct uvc_streaming_control probe; + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL); - } + return uvc_create_buffers(&stream->queue, cb); +} - case VIDIOC_S_FMT: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; +static int uvc_ioctl_streamon(struct file *file, void *fh, + enum v4l2_buf_type type) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; + if (!uvc_has_privileges(handle)) + return -EBUSY; - return uvc_v4l2_set_format(stream, arg); + mutex_lock(&stream->mutex); + ret = uvc_queue_streamon(&stream->queue, type); + mutex_unlock(&stream->mutex); - case VIDIOC_G_FMT: - return uvc_v4l2_get_format(stream, arg); + return ret; +} - /* Frame size enumeration */ - case VIDIOC_ENUM_FRAMESIZES: - { - struct v4l2_frmsizeenum *fsize = arg; - struct uvc_format *format = NULL; - struct uvc_frame *frame; - int i; +static int uvc_ioctl_streamoff(struct file *file, void *fh, + enum v4l2_buf_type type) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; - /* Look for the given pixel format */ - for (i = 0; i < stream->nformats; i++) { - if (stream->format[i].fcc == - fsize->pixel_format) { - format = &stream->format[i]; - break; - } - } - if (format == NULL) - return -EINVAL; + if (!uvc_has_privileges(handle)) + return -EBUSY; - if (fsize->index >= format->nframes) - return -EINVAL; + mutex_lock(&stream->mutex); + uvc_queue_streamoff(&stream->queue, type); + mutex_unlock(&stream->mutex); - frame = &format->frame[fsize->index]; - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = frame->wWidth; - fsize->discrete.height = frame->wHeight; - break; - } + return 0; +} - /* Frame interval enumeration */ - case VIDIOC_ENUM_FRAMEINTERVALS: - { - struct v4l2_frmivalenum *fival = arg; - struct uvc_format *format = NULL; - struct uvc_frame *frame = NULL; - int i; - - /* Look for the given pixel format and frame size */ - for (i = 0; i < stream->nformats; i++) { - if (stream->format[i].fcc == - fival->pixel_format) { - format = &stream->format[i]; - break; - } - } - if (format == NULL) +static int uvc_ioctl_enum_input(struct file *file, void *fh, + struct v4l2_input *input) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + const struct uvc_entity *selector = chain->selector; + struct uvc_entity *iterm = NULL; + u32 index = input->index; + int pin = 0; + + if (selector == NULL || + (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { + if (index != 0) return -EINVAL; - - for (i = 0; i < format->nframes; i++) { - if (format->frame[i].wWidth == fival->width && - format->frame[i].wHeight == fival->height) { - frame = &format->frame[i]; + list_for_each_entry(iterm, &chain->entities, chain) { + if (UVC_ENTITY_IS_ITERM(iterm)) break; - } } - if (frame == NULL) - return -EINVAL; - - if (frame->bFrameIntervalType) { - if (fival->index >= frame->bFrameIntervalType) - return -EINVAL; - - fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; - fival->discrete.numerator = - frame->dwFrameInterval[fival->index]; - fival->discrete.denominator = 10000000; - uvc_simplify_fraction(&fival->discrete.numerator, - &fival->discrete.denominator, 8, 333); - } else { - fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; - fival->stepwise.min.numerator = - frame->dwFrameInterval[0]; - fival->stepwise.min.denominator = 10000000; - fival->stepwise.max.numerator = - frame->dwFrameInterval[1]; - fival->stepwise.max.denominator = 10000000; - fival->stepwise.step.numerator = - frame->dwFrameInterval[2]; - fival->stepwise.step.denominator = 10000000; - uvc_simplify_fraction(&fival->stepwise.min.numerator, - &fival->stepwise.min.denominator, 8, 333); - uvc_simplify_fraction(&fival->stepwise.max.numerator, - &fival->stepwise.max.denominator, 8, 333); - uvc_simplify_fraction(&fival->stepwise.step.numerator, - &fival->stepwise.step.denominator, 8, 333); + pin = iterm->id; + } else if (index < selector->bNrInPins) { + pin = selector->baSourceID[index]; + list_for_each_entry(iterm, &chain->entities, chain) { + if (!UVC_ENTITY_IS_ITERM(iterm)) + continue; + if (iterm->id == pin) + break; } - break; } - /* Get & Set streaming parameters */ - case VIDIOC_G_PARM: - return uvc_v4l2_get_streamparm(stream, arg); + if (iterm == NULL || iterm->id != pin) + return -EINVAL; - case VIDIOC_S_PARM: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; + memset(input, 0, sizeof(*input)); + input->index = index; + strlcpy(input->name, iterm->name, sizeof(input->name)); + if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA) + input->type = V4L2_INPUT_TYPE_CAMERA; - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; + return 0; +} - return uvc_v4l2_set_streamparm(stream, arg); +static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + int ret; + u8 i; - /* Cropping and scaling */ - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *ccap = arg; + if (chain->selector == NULL || + (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { + *input = 0; + return 0; + } - if (ccap->type != stream->type) - return -EINVAL; + ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, chain->selector->id, + chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, + &i, 1); + if (ret < 0) + return ret; - ccap->bounds.left = 0; - ccap->bounds.top = 0; + *input = i - 1; + return 0; +} - mutex_lock(&stream->mutex); - ccap->bounds.width = stream->cur_frame->wWidth; - ccap->bounds.height = stream->cur_frame->wHeight; - mutex_unlock(&stream->mutex); +static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + int ret; + u32 i; - ccap->defrect = ccap->bounds; + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; - ccap->pixelaspect.numerator = 1; - ccap->pixelaspect.denominator = 1; - break; + if (chain->selector == NULL || + (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { + if (input) + return -EINVAL; + return 0; } - case VIDIOC_G_CROP: - case VIDIOC_S_CROP: - return -ENOTTY; + if (input >= chain->selector->bNrInPins) + return -EINVAL; - /* Buffers & streaming */ - case VIDIOC_REQBUFS: - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; + i = input + 1; + return uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id, + chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, + &i, 1); +} - if ((ret = uvc_acquire_privileges(handle)) < 0) - return ret; +static int uvc_ioctl_queryctrl(struct file *file, void *fh, + struct v4l2_queryctrl *qc) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; - mutex_lock(&stream->mutex); - ret = uvc_alloc_buffers(&stream->queue, arg); - mutex_unlock(&stream->mutex); - if (ret < 0) - return ret; + return uvc_query_v4l2_ctrl(chain, qc); +} - if (ret == 0) - uvc_dismiss_privileges(handle); +static int uvc_ioctl_g_ctrl(struct file *file, void *fh, + struct v4l2_control *ctrl) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + struct v4l2_ext_control xctrl; + int ret; - ret = 0; - break; + memset(&xctrl, 0, sizeof(xctrl)); + xctrl.id = ctrl->id; + + ret = uvc_ctrl_begin(chain); + if (ret < 0) + return ret; - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *buf = arg; + ret = uvc_ctrl_get(chain, &xctrl); + uvc_ctrl_rollback(handle); + if (ret < 0) + return ret; - if (!uvc_has_privileges(handle)) - return -EBUSY; + ctrl->value = xctrl.value; + return 0; +} - return uvc_query_buffer(&stream->queue, buf); - } +static int uvc_ioctl_s_ctrl(struct file *file, void *fh, + struct v4l2_control *ctrl) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + struct v4l2_ext_control xctrl; + int ret; - case VIDIOC_CREATE_BUFS: - { - struct v4l2_create_buffers *cb = arg; + memset(&xctrl, 0, sizeof(xctrl)); + xctrl.id = ctrl->id; + xctrl.value = ctrl->value; - ret = uvc_acquire_privileges(handle); - if (ret < 0) - return ret; + ret = uvc_ctrl_begin(chain); + if (ret < 0) + return ret; - return uvc_create_buffers(&stream->queue, cb); + ret = uvc_ctrl_set(chain, &xctrl); + if (ret < 0) { + uvc_ctrl_rollback(handle); + return ret; } - case VIDIOC_QBUF: - if (!uvc_has_privileges(handle)) - return -EBUSY; + ret = uvc_ctrl_commit(handle, &xctrl, 1); + if (ret < 0) + return ret; - return uvc_queue_buffer(&stream->queue, arg); + ctrl->value = xctrl.value; + return 0; +} + +static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *ctrls) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + struct v4l2_ext_control *ctrl = ctrls->controls; + unsigned int i; + int ret; - case VIDIOC_DQBUF: - if (!uvc_has_privileges(handle)) - return -EBUSY; + ret = uvc_ctrl_begin(chain); + if (ret < 0) + return ret; - return uvc_dequeue_buffer(&stream->queue, arg, - file->f_flags & O_NONBLOCK); + for (i = 0; i < ctrls->count; ++ctrl, ++i) { + ret = uvc_ctrl_get(chain, ctrl); + if (ret < 0) { + uvc_ctrl_rollback(handle); + ctrls->error_idx = i; + return ret; + } + } - case VIDIOC_STREAMON: - { - int *type = arg; + ctrls->error_idx = 0; - if (*type != stream->type) - return -EINVAL; + return uvc_ctrl_rollback(handle); +} - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; +static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle, + struct v4l2_ext_controls *ctrls, + bool commit) +{ + struct v4l2_ext_control *ctrl = ctrls->controls; + struct uvc_video_chain *chain = handle->chain; + unsigned int i; + int ret; - if (!uvc_has_privileges(handle)) - return -EBUSY; + ret = uvc_ctrl_begin(chain); + if (ret < 0) + return ret; - mutex_lock(&stream->mutex); - ret = uvc_video_enable(stream, 1); - mutex_unlock(&stream->mutex); - if (ret < 0) + for (i = 0; i < ctrls->count; ++ctrl, ++i) { + ret = uvc_ctrl_set(chain, ctrl); + if (ret < 0) { + uvc_ctrl_rollback(handle); + ctrls->error_idx = commit ? ctrls->count : i; return ret; - break; + } } - case VIDIOC_STREAMOFF: - { - int *type = arg; + ctrls->error_idx = 0; - if (*type != stream->type) - return -EINVAL; + if (commit) + return uvc_ctrl_commit(handle, ctrls->controls, ctrls->count); + else + return uvc_ctrl_rollback(handle); +} - ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); - if (ret < 0) - return ret; +static int uvc_ioctl_s_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *ctrls) +{ + struct uvc_fh *handle = fh; + + return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, true); +} - if (!uvc_has_privileges(handle)) - return -EBUSY; +static int uvc_ioctl_try_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *ctrls) +{ + struct uvc_fh *handle = fh; - return uvc_video_enable(stream, 0); + return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, false); +} + +static int uvc_ioctl_querymenu(struct file *file, void *fh, + struct v4l2_querymenu *qm) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + + return uvc_query_v4l2_menu(chain, qm); +} + +static int uvc_ioctl_cropcap(struct file *file, void *fh, + struct v4l2_cropcap *ccap) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + + if (ccap->type != stream->type) + return -EINVAL; + + ccap->bounds.left = 0; + ccap->bounds.top = 0; + mutex_lock(&stream->mutex); + ccap->bounds.width = stream->cur_frame->wWidth; + ccap->bounds.height = stream->cur_frame->wHeight; + mutex_unlock(&stream->mutex); + + ccap->defrect = ccap->bounds; + + ccap->pixelaspect.numerator = 1; + ccap->pixelaspect.denominator = 1; + return 0; +} + +static int uvc_ioctl_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + + return uvc_v4l2_get_streamparm(stream, parm); +} + +static int uvc_ioctl_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + int ret; + + ret = uvc_acquire_privileges(handle); + if (ret < 0) + return ret; + + return uvc_v4l2_set_streamparm(stream, parm); +} + +static int uvc_ioctl_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + struct uvc_format *format = NULL; + struct uvc_frame *frame; + int i; + + /* Look for the given pixel format */ + for (i = 0; i < stream->nformats; i++) { + if (stream->format[i].fcc == fsize->pixel_format) { + format = &stream->format[i]; + break; + } } + if (format == NULL) + return -EINVAL; - case VIDIOC_SUBSCRIBE_EVENT: - { - struct v4l2_event_subscription *sub = arg; + if (fsize->index >= format->nframes) + return -EINVAL; - switch (sub->type) { - case V4L2_EVENT_CTRL: - return v4l2_event_subscribe(&handle->vfh, sub, 0, - &uvc_ctrl_sub_ev_ops); - default: - return -EINVAL; + frame = &format->frame[fsize->index]; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = frame->wWidth; + fsize->discrete.height = frame->wHeight; + return 0; +} + +static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh, + struct v4l2_frmivalenum *fival) +{ + struct uvc_fh *handle = fh; + struct uvc_streaming *stream = handle->stream; + struct uvc_format *format = NULL; + struct uvc_frame *frame = NULL; + int i; + + /* Look for the given pixel format and frame size */ + for (i = 0; i < stream->nformats; i++) { + if (stream->format[i].fcc == fival->pixel_format) { + format = &stream->format[i]; + break; } } + if (format == NULL) + return -EINVAL; - case VIDIOC_UNSUBSCRIBE_EVENT: - return v4l2_event_unsubscribe(&handle->vfh, arg); + for (i = 0; i < format->nframes; i++) { + if (format->frame[i].wWidth == fival->width && + format->frame[i].wHeight == fival->height) { + frame = &format->frame[i]; + break; + } + } + if (frame == NULL) + return -EINVAL; - case VIDIOC_DQEVENT: - return v4l2_event_dequeue(&handle->vfh, arg, - file->f_flags & O_NONBLOCK); + if (frame->bFrameIntervalType) { + if (fival->index >= frame->bFrameIntervalType) + return -EINVAL; - /* Analog video standards make no sense for digital cameras. */ - case VIDIOC_ENUMSTD: - case VIDIOC_QUERYSTD: - case VIDIOC_G_STD: - case VIDIOC_S_STD: + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; + fival->discrete.numerator = + frame->dwFrameInterval[fival->index]; + fival->discrete.denominator = 10000000; + uvc_simplify_fraction(&fival->discrete.numerator, + &fival->discrete.denominator, 8, 333); + } else { + fival->type = V4L2_FRMIVAL_TYPE_STEPWISE; + fival->stepwise.min.numerator = frame->dwFrameInterval[0]; + fival->stepwise.min.denominator = 10000000; + fival->stepwise.max.numerator = frame->dwFrameInterval[1]; + fival->stepwise.max.denominator = 10000000; + fival->stepwise.step.numerator = frame->dwFrameInterval[2]; + fival->stepwise.step.denominator = 10000000; + uvc_simplify_fraction(&fival->stepwise.min.numerator, + &fival->stepwise.min.denominator, 8, 333); + uvc_simplify_fraction(&fival->stepwise.max.numerator, + &fival->stepwise.max.denominator, 8, 333); + uvc_simplify_fraction(&fival->stepwise.step.numerator, + &fival->stepwise.step.denominator, 8, 333); + } - case VIDIOC_OVERLAY: + return 0; +} - case VIDIOC_ENUMAUDIO: - case VIDIOC_ENUMAUDOUT: +static int uvc_ioctl_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_CTRL: + return v4l2_event_subscribe(fh, sub, 0, &uvc_ctrl_sub_ev_ops); + default: + return -EINVAL; + } +} - case VIDIOC_ENUMOUTPUT: - uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd); - return -ENOTTY; +static long uvc_ioctl_default(struct file *file, void *fh, bool valid_prio, + unsigned int cmd, void *arg) +{ + struct uvc_fh *handle = fh; + struct uvc_video_chain *chain = handle->chain; + switch (cmd) { + /* Dynamic controls. */ case UVCIOC_CTRL_MAP: return uvc_ioctl_ctrl_map(chain, arg); @@ -1105,23 +1178,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) return uvc_xu_ctrl_query(chain, arg); default: - uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd); return -ENOTTY; } - - return ret; -} - -static long uvc_v4l2_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - if (uvc_trace_param & UVC_TRACE_IOCTL) { - uvc_printk(KERN_DEBUG, "uvc_v4l2_ioctl("); - v4l_printk_ioctl(NULL, cmd); - printk(")\n"); - } - - return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl); } #ifdef CONFIG_COMPAT @@ -1304,7 +1362,7 @@ static long uvc_v4l2_compat_ioctl32(struct file *file, old_fs = get_fs(); set_fs(KERNEL_DS); - ret = uvc_v4l2_ioctl(file, cmd, (unsigned long)&karg); + ret = video_ioctl2(file, cmd, (unsigned long)&karg); set_fs(old_fs); if (ret < 0) @@ -1365,11 +1423,48 @@ static unsigned long uvc_v4l2_get_unmapped_area(struct file *file, } #endif +const struct v4l2_ioctl_ops uvc_ioctl_ops = { + .vidioc_querycap = uvc_ioctl_querycap, + .vidioc_enum_fmt_vid_cap = uvc_ioctl_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt_vid_out, + .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt_vid_cap, + .vidioc_g_fmt_vid_out = uvc_ioctl_g_fmt_vid_out, + .vidioc_s_fmt_vid_cap = uvc_ioctl_s_fmt_vid_cap, + .vidioc_s_fmt_vid_out = uvc_ioctl_s_fmt_vid_out, + .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt_vid_cap, + .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt_vid_out, + .vidioc_reqbufs = uvc_ioctl_reqbufs, + .vidioc_querybuf = uvc_ioctl_querybuf, + .vidioc_qbuf = uvc_ioctl_qbuf, + .vidioc_dqbuf = uvc_ioctl_dqbuf, + .vidioc_create_bufs = uvc_ioctl_create_bufs, + .vidioc_streamon = uvc_ioctl_streamon, + .vidioc_streamoff = uvc_ioctl_streamoff, + .vidioc_enum_input = uvc_ioctl_enum_input, + .vidioc_g_input = uvc_ioctl_g_input, + .vidioc_s_input = uvc_ioctl_s_input, + .vidioc_queryctrl = uvc_ioctl_queryctrl, + .vidioc_g_ctrl = uvc_ioctl_g_ctrl, + .vidioc_s_ctrl = uvc_ioctl_s_ctrl, + .vidioc_g_ext_ctrls = uvc_ioctl_g_ext_ctrls, + .vidioc_s_ext_ctrls = uvc_ioctl_s_ext_ctrls, + .vidioc_try_ext_ctrls = uvc_ioctl_try_ext_ctrls, + .vidioc_querymenu = uvc_ioctl_querymenu, + .vidioc_cropcap = uvc_ioctl_cropcap, + .vidioc_g_parm = uvc_ioctl_g_parm, + .vidioc_s_parm = uvc_ioctl_s_parm, + .vidioc_enum_framesizes = uvc_ioctl_enum_framesizes, + .vidioc_enum_frameintervals = uvc_ioctl_enum_frameintervals, + .vidioc_subscribe_event = uvc_ioctl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_default = uvc_ioctl_default, +}; + const struct v4l2_file_operations uvc_fops = { .owner = THIS_MODULE, .open = uvc_v4l2_open, .release = uvc_v4l2_release, - .unlocked_ioctl = uvc_v4l2_ioctl, + .unlocked_ioctl = video_ioctl2, #ifdef CONFIG_COMPAT .compat_ioctl32 = uvc_v4l2_compat_ioctl32, #endif diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index df81b9c4faf1..9637e8b86949 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1021,6 +1021,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, uvc_video_get_ts(&ts); + buf->buf.v4l2_buf.field = V4L2_FIELD_NONE; buf->buf.v4l2_buf.sequence = stream->sequence; buf->buf.v4l2_buf.timestamp.tv_sec = ts.tv_sec; buf->buf.v4l2_buf.timestamp.tv_usec = @@ -1734,19 +1735,13 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) uvc_video_clock_reset(stream); ret = uvc_commit_video(stream, &stream->ctrl); - if (ret < 0) { - uvc_queue_enable(&stream->queue, 0); + if (ret < 0) return ret; - } if (!uvc_queue_streaming(&stream->queue)) return 0; - ret = uvc_init_video(stream, GFP_NOIO); - if (ret < 0) - uvc_queue_enable(&stream->queue, 0); - - return ret; + return uvc_init_video(stream, GFP_NOIO); } /* ------------------------------------------------------------------------ @@ -1778,11 +1773,6 @@ int uvc_video_init(struct uvc_streaming *stream) atomic_set(&stream->active, 0); - /* Initialize the video buffers queue. */ - ret = uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param); - if (ret) - return ret; - /* Alternate setting 0 should be the default, yet the XBox Live Vision * Cam (and possibly other devices) crash or otherwise misbehave if * they don't receive a SET_INTERFACE request before any other video @@ -1889,7 +1879,6 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) usb_clear_halt(stream->dev->udev, pipe); } - uvc_queue_enable(&stream->queue, 0); uvc_video_clock_cleanup(stream); return 0; } @@ -1898,10 +1887,6 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) if (ret < 0) return ret; - ret = uvc_queue_enable(&stream->queue, 1); - if (ret < 0) - goto error_queue; - /* Commit the streaming parameters. */ ret = uvc_commit_video(stream, &stream->ctrl); if (ret < 0) @@ -1916,8 +1901,6 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) error_video: usb_set_interface(stream->dev->udev, stream->intfnum, 0); error_commit: - uvc_queue_enable(&stream->queue, 0); -error_queue: uvc_video_clock_cleanup(stream); return ret; diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 864ada740360..f0a04b532ede 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -148,6 +148,7 @@ #define UVC_QUIRK_PROBE_DEF 0x00000100 #define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400 +#define UVC_QUIRK_FORCE_Y8 0x00000800 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 @@ -579,7 +580,6 @@ struct uvc_driver { #define UVC_TRACE_FORMAT (1 << 3) #define UVC_TRACE_CAPTURE (1 << 4) #define UVC_TRACE_CALLS (1 << 5) -#define UVC_TRACE_IOCTL (1 << 6) #define UVC_TRACE_FRAME (1 << 7) #define UVC_TRACE_SUSPEND (1 << 8) #define UVC_TRACE_STATUS (1 << 9) @@ -623,9 +623,9 @@ extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); /* Video buffers queue management. */ extern int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, int drop_corrupted); -extern int uvc_alloc_buffers(struct uvc_video_queue *queue, +extern void uvc_queue_release(struct uvc_video_queue *queue); +extern int uvc_request_buffers(struct uvc_video_queue *queue, struct v4l2_requestbuffers *rb); -extern void uvc_free_buffers(struct uvc_video_queue *queue); extern int uvc_query_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf); extern int uvc_create_buffers(struct uvc_video_queue *queue, @@ -634,7 +634,10 @@ extern int uvc_queue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf); extern int uvc_dequeue_buffer(struct uvc_video_queue *queue, struct v4l2_buffer *v4l2_buf, int nonblocking); -extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); +extern int uvc_queue_streamon(struct uvc_video_queue *queue, + enum v4l2_buf_type type); +extern int uvc_queue_streamoff(struct uvc_video_queue *queue, + enum v4l2_buf_type type); extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf); @@ -653,6 +656,7 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue) } /* V4L2 interface */ +extern const struct v4l2_ioctl_ops uvc_ioctl_ops; extern const struct v4l2_file_operations uvc_fops; /* Media controller */ |