diff options
Diffstat (limited to 'linux/drivers/media/video/cx88/cx88-video.c')
-rw-r--r-- | linux/drivers/media/video/cx88/cx88-video.c | 84 |
1 files changed, 47 insertions, 37 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index 005a78aab..9ec7d2f57 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -31,6 +31,7 @@ #include <linux/kmod.h> #include <linux/kernel.h> #include <linux/slab.h> +#include <linux/smp_lock.h> #include <linux/interrupt.h> #include <linux/dma-mapping.h> #include <linux/delay.h> @@ -42,11 +43,6 @@ #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> -#ifdef CONFIG_VIDEO_V4L1_COMPAT -/* Include V4L1 specific functions. Should be removed soon */ -#include <linux/videodev.h> -#endif - MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); MODULE_LICENSE("GPL"); @@ -434,11 +430,8 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) routes for different inputs. HVR-1300 surely does */ if (core->board.audio_chip && core->board.audio_chip == V4L2_IDENT_WM8775) { - struct v4l2_routing route; - - route.input = INPUT(input).audioroute; - cx88_call_i2c_clients(core, - VIDIOC_INT_S_AUDIO_ROUTING, &route); + call_all(core, audio, s_routing, + INPUT(input).audioroute, 0, 0); } /* cx2388's C-ADC is connected to the tuner only. When used with S-Video, that ADC is busy dealing with @@ -1055,11 +1048,8 @@ static int video_open(struct file *file) if (core->board.radio.audioroute) { if(core->board.audio_chip && core->board.audio_chip == V4L2_IDENT_WM8775) { - struct v4l2_routing route; - - route.input = core->board.radio.audioroute; - cx88_call_i2c_clients(core, - VIDIOC_INT_S_AUDIO_ROUTING, &route); + call_all(core, audio, s_routing, + core->board.radio.audioroute, 0, 0); } /* "I2S ADC mode" */ core->tvaudio = WW_I2SADC; @@ -1070,7 +1060,7 @@ static int video_open(struct file *file) cx88_set_tvaudio(core); cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); } - cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); + call_all(core, tuner, s_radio); } unlock_kernel(); @@ -1106,6 +1096,7 @@ video_poll(struct file *file, struct poll_table_struct *wait) { struct cx8800_fh *fh = file->private_data; struct cx88_buffer *buf; + unsigned int rc = POLLERR; if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { if (!res_get(fh->dev,fh,RESOURCE_VBI)) @@ -1113,22 +1104,27 @@ video_poll(struct file *file, struct poll_table_struct *wait) return videobuf_poll_stream(file, &fh->vbiq, wait); } + mutex_lock(&fh->vidq.vb_lock); if (res_check(fh,RESOURCE_VIDEO)) { /* streaming capture */ if (list_empty(&fh->vidq.stream)) - return POLLERR; + goto done; buf = list_entry(fh->vidq.stream.next,struct cx88_buffer,vb.stream); } else { /* read() capture */ buf = (struct cx88_buffer*)fh->vidq.read_buf; if (NULL == buf) - return POLLERR; + goto done; } poll_wait(file, &buf->vb.done, wait); if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) - return POLLIN|POLLRDNORM; - return 0; + rc = POLLIN|POLLRDNORM; + else + rc = 0; +done: + mutex_unlock(&fh->vidq.vb_lock); + return rc; } static int video_release(struct file *file) @@ -1163,8 +1159,10 @@ static int video_release(struct file *file) file->private_data = NULL; kfree(fh); + mutex_lock(&dev->core->lock); if(atomic_dec_and_test(&dev->core->users)) - cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); + call_all(dev->core, tuner, s_standby); + mutex_unlock(&dev->core->lock); return 0; } @@ -1348,15 +1346,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, } f->fmt.pix.field = field; - if (f->fmt.pix.height < 32) - f->fmt.pix.height = 32; - if (f->fmt.pix.height > maxh) - f->fmt.pix.height = maxh; - if (f->fmt.pix.width < 48) - f->fmt.pix.width = 48; - if (f->fmt.pix.width > maxw) - f->fmt.pix.width = maxw; - f->fmt.pix.width &= ~0x03; + v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, + &f->fmt.pix.height, 32, maxh, 0, 0); f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = @@ -1666,7 +1657,7 @@ static int vidioc_g_frequency (struct file *file, void *priv, f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; f->frequency = core->freq; - cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f); + call_all(core, tuner, g_frequency, f); return 0; } @@ -1682,7 +1673,7 @@ int cx88_set_freq (struct cx88_core *core, mutex_lock(&core->lock); core->freq = f->frequency; cx88_newstation(core); - cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f); + call_all(core, tuner, s_frequency, f); /* When changing channels it is required to reset TVAUDIO */ msleep (10); @@ -1764,7 +1755,7 @@ static int radio_g_tuner (struct file *file, void *priv, strcpy(t->name, "Radio"); t->type = V4L2_TUNER_RADIO; - cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t); + call_all(core, tuner, g_tuner, t); return 0; } @@ -1798,7 +1789,7 @@ static int radio_s_tuner (struct file *file, void *priv, if (0 != t->index) return -EINVAL; - cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t); + call_all(core, tuner, s_tuner, t); return 0; } @@ -2113,7 +2104,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); pci_set_master(pci_dev); - if (!pci_dma_supported(pci_dev,DMA_32BIT_MASK)) { + if (!pci_dma_supported(pci_dev,DMA_BIT_MASK(32))) { printk("%s/0: Oops: no 32bit PCI DMA ???\n",core->name); err = -EIO; goto fail_core; @@ -2163,12 +2154,31 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* load and configure helper modules */ if (core->board.audio_chip == V4L2_IDENT_WM8775) - request_module("wm8775"); + v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, + "wm8775", "wm8775", 0x36 >> 1, NULL); + + if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { + /* This probes for a tda9874 as is used on some + Pixelview Ultra boards. */ + v4l2_i2c_new_subdev(&core->v4l2_dev, + &core->i2c_adap, + "tvaudio", "tvaudio", 0, I2C_ADDRS(0xb0 >> 1)); + } switch (core->boardnr) { case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: - case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: + case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + static struct i2c_board_info rtc_info = { + I2C_BOARD_INFO("isl1208", 0x6f) + }; + request_module("rtc-isl1208"); + core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info); +#else + request_module("rtc-isl1208"); +#endif + } /* break intentionally omitted */ case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: request_module("ir-kbd-i2c"); |