From a877e2771a7f74b724cc09d96decd2ff3a37f2cd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 10:53:07 -0300 Subject: [media] cx25821: do not expose broken video output streams The cx25821 driver has support for one audio output channel and two video output channels. This is implemented in a very ugly and very evil way through a custom ioctl that passes the filename of a file containing the video data, which is then read by the driver itself using vfs. There are a number of problems with this: 1) it's very ugly and very evil (I can't say that often enough). 2) V4L2 supports video output, so why not use that? 3) it's very buggy, closing the filehandle through which you passed the ioctl will oops the kernel. 4) it's a nasty security leak since this allows you to load any file in the system as a video or audio source, so in theory you can output /etc/passwd to audio or video out and record & decode it on another device. Because of all these issues we no longer register those output video nodes. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 1465591d000..6b18320ebef 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -461,7 +461,7 @@ int cx25821_video_register(struct cx25821_dev *dev) spin_lock_init(&dev->slock); - for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) { + for (i = 0; i < VID_CHANNEL_NUM; ++i) { cx25821_init_controls(dev, i); cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, -- cgit v1.2.3-70-g09d2 From 31b320739b4318a04c203918310b49a55a598bde Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 11:07:02 -0300 Subject: [media] cx25821: the audio channel was registered as a video node Skip the audio channel when registering the video nodes. This fixes a bug where that incorrectly registered 'video' node was never unregistered. Note: this bug only surfaces if the video output nodes are enabled again after the previous patch disabled them. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-core.c | 8 +++----- drivers/media/pci/cx25821/cx25821-video.c | 5 ++++- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 1884e2cc35e..1f47422d488 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -1051,11 +1051,9 @@ void cx25821_dev_unregister(struct cx25821_dev *dev) if (!atomic_dec_and_test(&dev->refcount)) return; - for (i = 0; i < VID_CHANNEL_NUM; i++) - cx25821_video_unregister(dev, i); - - for (i = VID_UPSTREAM_SRAM_CHANNEL_I; - i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) { + for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) { + if (i == SRAM_CH08) /* audio channel */ + continue; cx25821_video_unregister(dev, i); } diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 6b18320ebef..8bf9c890883 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -462,6 +462,9 @@ int cx25821_video_register(struct cx25821_dev *dev) spin_lock_init(&dev->slock); for (i = 0; i < VID_CHANNEL_NUM; ++i) { + if (i == SRAM_CH08) /* audio channel */ + continue; + cx25821_init_controls(dev, i); cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, @@ -788,7 +791,7 @@ static int video_open(struct file *file) { h = list_entry(list, struct cx25821_dev, devlist); - for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) { + for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) { if (h->channels[i].video_dev && h->channels[i].video_dev->minor == minor) { dev = h; -- cgit v1.2.3-70-g09d2 From 170bd5330383ce62127ef5b6eeeab9afebd7b838 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 05:19:41 -0300 Subject: [media] cx25821: fix compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/media/pci/cx25821/cx25821-video.c: In function ‘cx25821_video_register’: drivers/media/pci/cx25821/cx25821-video.c:518:1: warning: the frame size of 1600 bytes is larger than 1024 bytes [-Wframe-larger-than=] Fixed by just making the struct video_device template static const. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 9 ++++----- drivers/media/pci/cx25821/cx25821.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 8bf9c890883..4eaa67a0833 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -161,7 +161,7 @@ int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, struct pci_dev *pci, - struct video_device *template, + const struct video_device *template, char *type) { struct video_device *vfd; @@ -447,10 +447,7 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) int cx25821_video_register(struct cx25821_dev *dev) { - int err; - int i; - - struct video_device cx25821_video_device = { + static const struct video_device cx25821_video_device = { .name = "cx25821-video", .fops = &video_fops, .minor = -1, @@ -458,6 +455,8 @@ int cx25821_video_register(struct cx25821_dev *dev) .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, }; + int err; + int i; spin_lock_init(&dev->slock); diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 8a9c0c86941..85693cdf0ee 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -610,6 +610,6 @@ extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel, extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev); extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, struct pci_dev *pci, - struct video_device *template, + const struct video_device *template, char *type); #endif -- cgit v1.2.3-70-g09d2 From ffd3c2330473f6a07f36bf3bd64f7a1158bdd759 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 05:30:48 -0300 Subject: [media] cx25821: remove bogus radio/vbi/'video-ioctl' support This device does not support radio or vbi, so remove anything referring to that. In addition, the driver created an 'video ioctl' node, which was unused and was effectively identical to the first video node. This bogus video node is now removed, leaving us with 8 video capture nodes and 2 video output nodes. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-core.c | 13 -- drivers/media/pci/cx25821/cx25821-video.c | 201 +++++++++++++----------------- drivers/media/pci/cx25821/cx25821-video.h | 1 - drivers/media/pci/cx25821/cx25821.h | 16 --- 4 files changed, 88 insertions(+), 143 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 1f47422d488..2b38a5005d0 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -988,17 +988,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) cx25821_video_register(dev); - /* register IOCTL device */ - dev->ioctl_dev = cx25821_vdev_init(dev, dev->pci, - &cx25821_videoioctl_template, "video"); - - if (video_register_device - (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) { - cx25821_videoioctl_unregister(dev); - pr_err("%s(): Failed to register video adapter for IOCTL, so unregistering videoioctl device\n", - __func__); - } - cx25821_dev_checkrevision(dev); CX25821_INFO("setup done!\n"); @@ -1057,8 +1046,6 @@ void cx25821_dev_unregister(struct cx25821_dev *dev) cx25821_video_unregister(dev, i); } - cx25821_videoioctl_unregister(dev); - cx25821_i2c_unregister(&dev->i2c_bus[0]); cx25821_iounmap(dev); } diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 4eaa67a0833..e785bb98d53 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -33,13 +33,10 @@ MODULE_AUTHOR("Hiep Huynh "); MODULE_LICENSE("GPL"); static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET }; -static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET }; module_param_array(video_nr, int, NULL, 0444); -module_param_array(radio_nr, int, NULL, 0444); MODULE_PARM_DESC(video_nr, "video device numbers"); -MODULE_PARM_DESC(radio_nr, "radio device numbers"); static unsigned int video_debug = VIDEO_DEBUG; module_param(video_debug, int, 0644); @@ -55,9 +52,6 @@ MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num); -static const struct v4l2_file_operations video_fops; -static const struct v4l2_ioctl_ops video_ioctl_ops; - #define FORMAT_FLAGS_PACKED 0x01 struct cx25821_fmt formats[] = { @@ -411,111 +405,6 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) return handled; } -void cx25821_videoioctl_unregister(struct cx25821_dev *dev) -{ - if (dev->ioctl_dev) { - if (video_is_registered(dev->ioctl_dev)) - video_unregister_device(dev->ioctl_dev); - else - video_device_release(dev->ioctl_dev); - - dev->ioctl_dev = NULL; - } -} - -void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) -{ - cx_clear(PCI_INT_MSK, 1); - - if (dev->channels[chan_num].video_dev) { - if (video_is_registered(dev->channels[chan_num].video_dev)) - video_unregister_device( - dev->channels[chan_num].video_dev); - else - video_device_release( - dev->channels[chan_num].video_dev); - - dev->channels[chan_num].video_dev = NULL; - - btcx_riscmem_free(dev->pci, - &dev->channels[chan_num].vidq.stopper); - - pr_warn("device %d released!\n", chan_num); - } - -} - -int cx25821_video_register(struct cx25821_dev *dev) -{ - static const struct video_device cx25821_video_device = { - .name = "cx25821-video", - .fops = &video_fops, - .minor = -1, - .ioctl_ops = &video_ioctl_ops, - .tvnorms = CX25821_NORMS, - .current_norm = V4L2_STD_NTSC_M, - }; - int err; - int i; - - spin_lock_init(&dev->slock); - - for (i = 0; i < VID_CHANNEL_NUM; ++i) { - if (i == SRAM_CH08) /* audio channel */ - continue; - - cx25821_init_controls(dev, i); - - cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, - dev->channels[i].sram_channels->dma_ctl, 0x11, 0); - - dev->channels[i].sram_channels = &cx25821_sram_channels[i]; - dev->channels[i].video_dev = NULL; - dev->channels[i].resources = 0; - - cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff); - - INIT_LIST_HEAD(&dev->channels[i].vidq.active); - INIT_LIST_HEAD(&dev->channels[i].vidq.queued); - - dev->channels[i].timeout_data.dev = dev; - dev->channels[i].timeout_data.channel = - &cx25821_sram_channels[i]; - dev->channels[i].vidq.timeout.function = cx25821_vid_timeout; - dev->channels[i].vidq.timeout.data = - (unsigned long)&dev->channels[i].timeout_data; - init_timer(&dev->channels[i].vidq.timeout); - - /* register v4l devices */ - dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci, - &cx25821_video_device, "video"); - - err = video_register_device(dev->channels[i].video_dev, - VFL_TYPE_GRABBER, video_nr[dev->nr]); - - if (err < 0) - goto fail_unreg; - - } - - /* set PCI interrupt */ - cx_set(PCI_INT_MSK, 0xff); - - /* initial device configuration */ - mutex_lock(&dev->lock); -#ifdef TUNER_FLAG - dev->tvnorm = cx25821_video_device.current_norm; - cx25821_set_tvnorm(dev, dev->tvnorm); -#endif - mutex_unlock(&dev->lock); - - return 0; - -fail_unreg: - cx25821_video_unregister(dev, i); - return err; -} - int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) { @@ -1983,10 +1872,96 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { #endif }; -struct video_device cx25821_videoioctl_template = { - .name = "cx25821-videoioctl", +static const struct video_device cx25821_video_device = { + .name = "cx25821-video", .fops = &video_fops, + .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, .current_norm = V4L2_STD_NTSC_M, }; + +void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) +{ + cx_clear(PCI_INT_MSK, 1); + + if (dev->channels[chan_num].video_dev) { + if (video_is_registered(dev->channels[chan_num].video_dev)) + video_unregister_device( + dev->channels[chan_num].video_dev); + else + video_device_release( + dev->channels[chan_num].video_dev); + + dev->channels[chan_num].video_dev = NULL; + + btcx_riscmem_free(dev->pci, + &dev->channels[chan_num].vidq.stopper); + + pr_warn("device %d released!\n", chan_num); + } + +} + +int cx25821_video_register(struct cx25821_dev *dev) +{ + int err; + int i; + + spin_lock_init(&dev->slock); + + for (i = 0; i < VID_CHANNEL_NUM; ++i) { + if (i == SRAM_CH08) /* audio channel */ + continue; + + cx25821_init_controls(dev, i); + + cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, + dev->channels[i].sram_channels->dma_ctl, 0x11, 0); + + dev->channels[i].sram_channels = &cx25821_sram_channels[i]; + dev->channels[i].video_dev = NULL; + dev->channels[i].resources = 0; + + cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff); + + INIT_LIST_HEAD(&dev->channels[i].vidq.active); + INIT_LIST_HEAD(&dev->channels[i].vidq.queued); + + dev->channels[i].timeout_data.dev = dev; + dev->channels[i].timeout_data.channel = + &cx25821_sram_channels[i]; + dev->channels[i].vidq.timeout.function = cx25821_vid_timeout; + dev->channels[i].vidq.timeout.data = + (unsigned long)&dev->channels[i].timeout_data; + init_timer(&dev->channels[i].vidq.timeout); + + /* register v4l devices */ + dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci, + &cx25821_video_device, "video"); + + err = video_register_device(dev->channels[i].video_dev, + VFL_TYPE_GRABBER, video_nr[dev->nr]); + + if (err < 0) + goto fail_unreg; + + } + + /* set PCI interrupt */ + cx_set(PCI_INT_MSK, 0xff); + + /* initial device configuration */ + mutex_lock(&dev->lock); +#ifdef TUNER_FLAG + dev->tvnorm = cx25821_video_device.current_norm; + cx25821_set_tvnorm(dev, dev->tvnorm); +#endif + mutex_unlock(&dev->lock); + + return 0; + +fail_unreg: + cx25821_video_unregister(dev, i); + return err; +} diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index 11ba5eb9367..37cb0c1b2de 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h @@ -76,7 +76,6 @@ extern struct sram_channel *channel7; extern struct sram_channel *channel9; extern struct sram_channel *channel10; extern struct sram_channel *channel11; -extern struct video_device cx25821_videoioctl_template; /* extern const u32 *ctrl_classes[]; */ extern unsigned int vid_limit; diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 85693cdf0ee..04c3cb0b6f4 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -80,7 +80,6 @@ #define RESOURCE_VIDEO9 512 #define RESOURCE_VIDEO10 1024 #define RESOURCE_VIDEO11 2048 -#define RESOURCE_VIDEO_IOCTL 4096 #define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ @@ -125,7 +124,6 @@ struct cx25821_tvnorm { struct cx25821_fh { struct cx25821_dev *dev; enum v4l2_buf_type type; - int radio; u32 resources; enum v4l2_priority prio; @@ -139,10 +137,7 @@ struct cx25821_fh { struct cx25821_fmt *fmt; unsigned int width, height; int channel_id; - - /* vbi capture */ struct videobuf_queue vidq; - struct videobuf_queue vbiq; /* H264 Encoder specifics ONLY */ struct videobuf_queue mpegq; @@ -153,7 +148,6 @@ enum cx25821_itype { CX25821_VMUX_COMPOSITE = 1, CX25821_VMUX_SVIDEO, CX25821_VMUX_DEBUG, - CX25821_RADIO, }; enum cx25821_src_sel_type { @@ -191,9 +185,7 @@ struct cx25821_board { enum port portb; enum port portc; unsigned int tuner_type; - unsigned int radio_type; unsigned char tuner_addr; - unsigned char radio_addr; u32 clk_freq; struct cx25821_input input[CX25821_NR_INPUT]; @@ -295,9 +287,6 @@ struct cx25821_dev { v4l2_std_id tvnorm; unsigned int tuner_type; unsigned char tuner_addr; - unsigned int radio_type; - unsigned char radio_addr; - unsigned int has_radio; unsigned int videc_type; unsigned char videc_addr; unsigned short _max_num_decoders; @@ -326,9 +315,6 @@ struct cx25821_dev { /* V4l */ u32 freq; - struct video_device *vbi_dev; - struct video_device *radio_dev; - struct video_device *ioctl_dev; spinlock_t slock; @@ -467,7 +453,6 @@ extern struct cx25821_subid cx25821_subids[]; #define VID_UPSTREAM_SRAM_CHANNEL_I SRAM_CH09 #define VID_UPSTREAM_SRAM_CHANNEL_J SRAM_CH10 #define AUDIO_UPSTREAM_SRAM_CHANNEL_B SRAM_CH11 -#define VIDEO_IOCTL_CH 11 struct sram_channel { char *name; @@ -607,7 +592,6 @@ extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, unsigned int bpl, u32 risc); extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel, u32 format); -extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev); extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, struct pci_dev *pci, const struct video_device *template, -- cgit v1.2.3-70-g09d2 From 18c73af6961c528fe5ce95eb510ef63582d47014 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 05:50:18 -0300 Subject: [media] cx25821: remove unused fields, ioctls Do some spring cleaning: - there are no board defines with tuners, so remove bogus tuner support. - tv standard handling has nothing to do with tuners, so keep that. - replace the deprecated current_norm by g_std. - querystd isn't implemented, so remove the ioctl. - remove a bunch of unused fields in cx25821.h Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-cards.c | 1 - drivers/media/pci/cx25821/cx25821-video.c | 130 +++--------------------------- drivers/media/pci/cx25821/cx25821-video.h | 13 --- drivers/media/pci/cx25821/cx25821.h | 18 ----- 4 files changed, 10 insertions(+), 152 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-cards.c b/drivers/media/pci/cx25821/cx25821-cards.c index 99988c98809..c09ec68460e 100644 --- a/drivers/media/pci/cx25821/cx25821-cards.c +++ b/drivers/media/pci/cx25821/cx25821-cards.c @@ -30,7 +30,6 @@ #include #include "cx25821.h" -#include "tuner-xc2028.h" /* board config info */ diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index e785bb98d53..8ff8fc218f3 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -138,7 +138,6 @@ void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc); } -#ifdef TUNER_FLAG int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) { dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", @@ -151,7 +150,6 @@ int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) return 0; } -#endif struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, struct pci_dev *pci, @@ -1036,8 +1034,6 @@ int cx25821_vidioc_querycap(struct file *file, void *priv, cap->version = CX25821_VERSION_CODE; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - if (UNSET != dev->tuner_type) - cap->capabilities |= V4L2_CAP_TUNER; return 0; } @@ -1093,7 +1089,14 @@ int cx25821_vidioc_s_priority(struct file *file, void *f, prio); } -#ifdef TUNER_FLAG +int cx25821_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms) +{ + struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; + + *tvnorms = dev->tvnorm; + return 0; +} + int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) { struct cx25821_fh *fh = priv; @@ -1120,7 +1123,6 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) return 0; } -#endif int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i) { @@ -1189,57 +1191,6 @@ int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) return 0; } -#ifdef TUNER_FLAG -int cx25821_vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = fh->dev; - - f->frequency = dev->freq; - - cx25821_call_all(dev, tuner, g_frequency, f); - - return 0; -} - -int cx25821_set_freq(struct cx25821_dev *dev, const struct v4l2_frequency *f) -{ - mutex_lock(&dev->lock); - dev->freq = f->frequency; - - cx25821_call_all(dev, tuner, s_frequency, f); - - /* When changing channels it is required to reset TVAUDIO */ - msleep(10); - - mutex_unlock(&dev->lock); - - return 0; -} - -int cx25821_vidioc_s_frequency(struct file *file, void *priv, - const struct v4l2_frequency *f) -{ - struct cx25821_fh *fh = priv; - struct cx25821_dev *dev; - int err; - - if (fh) { - dev = fh->dev; - err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, - fh->prio); - if (0 != err) - return err; - } else { - pr_err("Invalid fh pointer!\n"); - return -EINVAL; - } - - return cx25821_set_freq(dev, f); -} -#endif - #ifdef CONFIG_VIDEO_ADV_DEBUG int cx25821_vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) @@ -1269,48 +1220,6 @@ int cx25821_vidioc_s_register(struct file *file, void *fh, #endif -#ifdef TUNER_FLAG -int cx25821_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) -{ - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - - strcpy(t->name, "Television"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM; - t->rangehigh = 0xffffffffUL; - - t->signal = 0xffff; /* LOCKED */ - return 0; -} - -int cx25821_vidioc_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) -{ - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - struct cx25821_fh *fh = priv; - int err; - - if (fh) { - err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, - fh->prio); - if (0 != err) - return err; - } - - dprintk(1, "%s()\n", __func__); - if (UNSET == dev->tuner_type) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - - return 0; -} - -#endif /*****************************************************************************/ static const struct v4l2_queryctrl no_ctl = { .name = "42", @@ -1523,14 +1432,6 @@ int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) return -EINVAL; } -int cx25821_vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm) -{ - /* medusa does not support video standard sensing of current input */ - *norm = CX25821_NORMS; - - return 0; -} - int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm) { if (tvnorm == V4L2_STD_PAL_BG) { @@ -1842,10 +1743,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querybuf = cx25821_vidioc_querybuf, .vidioc_qbuf = cx25821_vidioc_qbuf, .vidioc_dqbuf = vidioc_dqbuf, -#ifdef TUNER_FLAG + .vidioc_g_std = cx25821_vidioc_g_std, .vidioc_s_std = cx25821_vidioc_s_std, - .vidioc_querystd = cx25821_vidioc_querystd, -#endif .vidioc_cropcap = cx25821_vidioc_cropcap, .vidioc_s_crop = cx25821_vidioc_s_crop, .vidioc_g_crop = cx25821_vidioc_g_crop, @@ -1860,12 +1759,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_log_status = vidioc_log_status, .vidioc_g_priority = cx25821_vidioc_g_priority, .vidioc_s_priority = cx25821_vidioc_s_priority, -#ifdef TUNER_FLAG - .vidioc_g_tuner = cx25821_vidioc_g_tuner, - .vidioc_s_tuner = cx25821_vidioc_s_tuner, - .vidioc_g_frequency = cx25821_vidioc_g_frequency, - .vidioc_s_frequency = cx25821_vidioc_s_frequency, -#endif #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = cx25821_vidioc_g_register, .vidioc_s_register = cx25821_vidioc_s_register, @@ -1878,7 +1771,6 @@ static const struct video_device cx25821_video_device = { .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, - .current_norm = V4L2_STD_NTSC_M, }; void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) @@ -1953,10 +1845,8 @@ int cx25821_video_register(struct cx25821_dev *dev) /* initial device configuration */ mutex_lock(&dev->lock); -#ifdef TUNER_FLAG - dev->tvnorm = cx25821_video_device.current_norm; + dev->tvnorm = V4L2_STD_NTSC_M, cx25821_set_tvnorm(dev, dev->tvnorm); -#endif mutex_unlock(&dev->lock); return 0; diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index 37cb0c1b2de..eb12e35d6de 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h @@ -40,8 +40,6 @@ #include #include -#define TUNER_FLAG - #define VIDEO_DEBUG 0 #define dprintk(level, fmt, arg...) \ @@ -88,9 +86,7 @@ extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; extern void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, u32 count); -#ifdef TUNER_FLAG extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm); -#endif extern int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit); @@ -146,19 +142,10 @@ extern int cx25821_vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl); extern int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f); -extern int cx25821_vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f); -extern int cx25821_set_freq(struct cx25821_dev *dev, const struct v4l2_frequency *f); -extern int cx25821_vidioc_s_frequency(struct file *file, void *priv, - const struct v4l2_frequency *f); extern int cx25821_vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg); extern int cx25821_vidioc_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg); -extern int cx25821_vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t); -extern int cx25821_vidioc_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *t); extern int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm); extern int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm); diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 04c3cb0b6f4..fdeecdf09ef 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -43,7 +42,6 @@ #include "cx25821-medusa-reg.h" #include "cx25821-sram.h" #include "cx25821-audio.h" -#include "media/cx2341x.h" #include #include @@ -184,8 +182,6 @@ struct cx25821_board { enum port porta; enum port portb; enum port portc; - unsigned int tuner_type; - unsigned char tuner_addr; u32 clk_freq; struct cx25821_input input[CX25821_NR_INPUT]; @@ -283,12 +279,7 @@ struct cx25821_dev { /* Analog video */ u32 resources; unsigned int input; - u32 tvaudio; v4l2_std_id tvnorm; - unsigned int tuner_type; - unsigned char tuner_addr; - unsigned int videc_type; - unsigned char videc_addr; unsigned short _max_num_decoders; /* Analog Audio Upstream */ @@ -314,8 +305,6 @@ struct cx25821_dev { char *_audiofilename; /* V4l */ - u32 freq; - spinlock_t slock; /* Video Upstream */ @@ -363,13 +352,6 @@ struct cx25821_dev { char *_filename_ch2; char *_defaultname_ch2; - /* MPEG Encoder ONLY settings */ - u32 cx23417_mailbox; - struct cx2341x_mpeg_params mpeg_params; - struct video_device *v4l_device; - atomic_t v4l_reader_count; - struct cx25821_tvnorm encodernorm; - u32 upstream_riscbuf_size; u32 upstream_databuf_size; u32 upstream_riscbuf_size_ch2; -- cgit v1.2.3-70-g09d2 From 3dd473ca58838f1dd93e915cfa7a5c150186bb0f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 06:06:18 -0300 Subject: [media] cx25821: fix log_status, querycap log_status shouldn't print LOG STATUS lines, the core does that already. Fix querycap version number and add device_caps support. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 8ff8fc218f3..7cd888581f9 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -923,21 +923,14 @@ static int vidioc_log_status(struct file *file, void *priv) { struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; struct cx25821_fh *fh = priv; - char name[32 + 2]; - - struct sram_channel *sram_ch = dev->channels[fh->channel_id] - .sram_channels; + struct sram_channel *sram_ch = + dev->channels[fh->channel_id].sram_channels; u32 tmp = 0; - snprintf(name, sizeof(name), "%s/2", dev->name); - pr_info("%s/2: ============ START LOG STATUS ============\n", - dev->name); cx25821_call_all(dev, core, log_status); tmp = cx_read(sram_ch->dma_ctl); pr_info("Video input 0 is %s\n", (tmp & 0x11) ? "streaming" : "stopped"); - pr_info("%s/2: ============= END LOG STATUS =============\n", - dev->name); return 0; } @@ -1027,13 +1020,19 @@ int cx25821_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; + struct cx25821_fh *fh = priv; + const u32 cap_input = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; + const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT; strcpy(cap->driver, "cx25821"); strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card)); sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); - cap->version = CX25821_VERSION_CODE; - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; + if (fh->channel_id >= VID_CHANNEL_NUM) + cap->device_caps = cap_output; + else + cap->device_caps = cap_input; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } -- cgit v1.2.3-70-g09d2 From bfef0d35e57c08dff295e3203d30f9ca4077415a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 06:28:54 -0300 Subject: [media] cx25821: make cx25821_sram_channels const And get rid of the channel0-11 external pointers and two more unused fields in cx25821.h. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-alsa.c | 2 +- drivers/media/pci/cx25821/cx25821-audio-upstream.c | 22 ++++++++--------- drivers/media/pci/cx25821/cx25821-core.c | 28 +++++----------------- .../media/pci/cx25821/cx25821-video-upstream-ch2.c | 20 ++++++++-------- drivers/media/pci/cx25821/cx25821-video-upstream.c | 22 ++++++++--------- drivers/media/pci/cx25821/cx25821-video.c | 14 ++++++----- drivers/media/pci/cx25821/cx25821-video.h | 15 +----------- drivers/media/pci/cx25821/cx25821.h | 26 +++++++------------- 8 files changed, 57 insertions(+), 92 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c index 1858a45dd08..b3cac75a489 100644 --- a/drivers/media/pci/cx25821/cx25821-alsa.c +++ b/drivers/media/pci/cx25821/cx25821-alsa.c @@ -151,7 +151,7 @@ static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip) { struct cx25821_audio_buffer *buf = chip->buf; struct cx25821_dev *dev = chip->dev; - struct sram_channel *audio_ch = + const struct sram_channel *audio_ch = &cx25821_sram_channels[AUDIO_SRAM_CHANNEL]; u32 tmp = 0; diff --git a/drivers/media/pci/cx25821/cx25821-audio-upstream.c b/drivers/media/pci/cx25821/cx25821-audio-upstream.c index ea973202a66..b9be535e32b 100644 --- a/drivers/media/pci/cx25821/cx25821-audio-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-audio-upstream.c @@ -45,7 +45,7 @@ static int _intr_msk = FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC | FLD_AUD_SRC_OPC_ERR; static int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev, - struct sram_channel *ch, + const struct sram_channel *ch, unsigned int bpl, u32 risc) { unsigned int i, lines; @@ -106,7 +106,7 @@ static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev, int fifo_enable) { unsigned int line; - struct sram_channel *sram_ch = + const struct sram_channel *sram_ch = dev->channels[dev->_audio_upstream_channel].sram_channels; int offset = 0; @@ -215,7 +215,7 @@ static void cx25821_free_memory_audio(struct cx25821_dev *dev) void cx25821_stop_upstream_audio(struct cx25821_dev *dev) { - struct sram_channel *sram_ch = + const struct sram_channel *sram_ch = dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels; u32 tmp = 0; @@ -257,7 +257,7 @@ void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev) } static int cx25821_get_audio_data(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { struct file *myfile; int frame_index_temp = dev->_audioframe_index; @@ -352,7 +352,7 @@ static void cx25821_audioups_handler(struct work_struct *work) } static int cx25821_openfile_audio(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { struct file *myfile; int i = 0, j = 0; @@ -433,7 +433,7 @@ static int cx25821_openfile_audio(struct cx25821_dev *dev, } static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev, - struct sram_channel *sram_ch, + const struct sram_channel *sram_ch, int bpl) { int ret = 0; @@ -495,7 +495,7 @@ static int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num, { int i = 0; u32 int_msk_tmp; - struct sram_channel *channel = dev->channels[chan_num].sram_channels; + const struct sram_channel *channel = dev->channels[chan_num].sram_channels; dma_addr_t risc_phys_jump_addr; __le32 *rp; @@ -587,7 +587,7 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id) struct cx25821_dev *dev = dev_id; u32 audio_status; int handled = 0; - struct sram_channel *sram_ch; + const struct sram_channel *sram_ch; if (!dev) return -1; @@ -611,7 +611,7 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id) } static void cx25821_wait_fifo_enable(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { int count = 0; u32 tmp; @@ -635,7 +635,7 @@ static void cx25821_wait_fifo_enable(struct cx25821_dev *dev, } static int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { u32 tmp = 0; int err = 0; @@ -699,7 +699,7 @@ fail_irq: int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select) { - struct sram_channel *sram_ch; + const struct sram_channel *sram_ch; int err = 0; if (dev->_audio_is_running) { diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 2b38a5005d0..48faf6fc273 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -48,7 +48,7 @@ EXPORT_SYMBOL(cx25821_devlist_mutex); LIST_HEAD(cx25821_devlist); EXPORT_SYMBOL(cx25821_devlist); -struct sram_channel cx25821_sram_channels[] = { +const struct sram_channel cx25821_sram_channels[] = { [SRAM_CH00] = { .i = SRAM_CH00, .name = "VID A", @@ -317,20 +317,6 @@ struct sram_channel cx25821_sram_channels[] = { }; EXPORT_SYMBOL(cx25821_sram_channels); -struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00]; -struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01]; -struct sram_channel *channel2 = &cx25821_sram_channels[SRAM_CH02]; -struct sram_channel *channel3 = &cx25821_sram_channels[SRAM_CH03]; -struct sram_channel *channel4 = &cx25821_sram_channels[SRAM_CH04]; -struct sram_channel *channel5 = &cx25821_sram_channels[SRAM_CH05]; -struct sram_channel *channel6 = &cx25821_sram_channels[SRAM_CH06]; -struct sram_channel *channel7 = &cx25821_sram_channels[SRAM_CH07]; -struct sram_channel *channel9 = &cx25821_sram_channels[SRAM_CH09]; -struct sram_channel *channel10 = &cx25821_sram_channels[SRAM_CH10]; -struct sram_channel *channel11 = &cx25821_sram_channels[SRAM_CH11]; - -struct cx25821_dmaqueue mpegq; - static int cx25821_risc_decode(u32 risc) { static const char * const instr[16] = { @@ -457,7 +443,7 @@ static void cx25821_registers_init(struct cx25821_dev *dev) } int cx25821_sram_channel_setup(struct cx25821_dev *dev, - struct sram_channel *ch, + const struct sram_channel *ch, unsigned int bpl, u32 risc) { unsigned int i, lines; @@ -523,10 +509,9 @@ int cx25821_sram_channel_setup(struct cx25821_dev *dev, return 0; } -EXPORT_SYMBOL(cx25821_sram_channel_setup); int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, - struct sram_channel *ch, + const struct sram_channel *ch, unsigned int bpl, u32 risc) { unsigned int i, lines; @@ -592,7 +577,7 @@ int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, } EXPORT_SYMBOL(cx25821_sram_channel_setup_audio); -void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch) +void cx25821_sram_channel_dump(struct cx25821_dev *dev, const struct sram_channel *ch) { static char *name[] = { "init risc lo", @@ -652,10 +637,9 @@ void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch) pr_warn(" : cnt2_reg: 0x%08x\n", cx_read(ch->cnt2_reg)); } -EXPORT_SYMBOL(cx25821_sram_channel_dump); void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, - struct sram_channel *ch) + const struct sram_channel *ch) { static const char * const name[] = { "init risc lo", @@ -803,7 +787,7 @@ void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select, } static void cx25821_set_vip_mode(struct cx25821_dev *dev, - struct sram_channel *ch) + const struct sram_channel *ch) { cx_write(ch->pix_frmt, PIXEL_FRMT_422); cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1); diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c index cf2723c7197..2381bdce99f 100644 --- a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c +++ b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c @@ -83,7 +83,7 @@ static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, int fifo_enable, int field_type) { unsigned int line, i; - struct sram_channel *sram_ch = + const struct sram_channel *sram_ch = dev->channels[dev->_channel2_upstream_select].sram_channels; int dist_betwn_starts = bpl * 2; @@ -201,7 +201,7 @@ static int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) { - struct sram_channel *sram_ch = + const struct sram_channel *sram_ch = dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels; u32 tmp = 0; @@ -257,7 +257,7 @@ void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev) } static int cx25821_get_frame_ch2(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { struct file *myfile; int frame_index_temp = dev->_frame_index_ch2; @@ -363,7 +363,7 @@ static void cx25821_vidups_handler_ch2(struct work_struct *work) } static int cx25821_openfile_ch2(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { struct file *myfile; int i = 0, j = 0; @@ -445,7 +445,7 @@ static int cx25821_openfile_ch2(struct cx25821_dev *dev, } static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, - struct sram_channel *sram_ch, + const struct sram_channel *sram_ch, int bpl) { int ret = 0; @@ -515,7 +515,7 @@ static int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, u32 status) { u32 int_msk_tmp; - struct sram_channel *channel = dev->channels[chan_num].sram_channels; + const struct sram_channel *channel = dev->channels[chan_num].sram_channels; int singlefield_lines = NTSC_FIELD_HEIGHT; int line_size_in_bytes = Y422_LINE_SZ; int odd_risc_prog_size = 0; @@ -594,7 +594,7 @@ static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) u32 vid_status; int handled = 0; int channel_num = 0; - struct sram_channel *sram_ch; + const struct sram_channel *sram_ch; if (!dev) return -1; @@ -618,7 +618,7 @@ static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) } static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev, - struct sram_channel *ch, int pix_format) + const struct sram_channel *ch, int pix_format) { int width = WIDTH_D1; int height = dev->_lines_count_ch2; @@ -652,7 +652,7 @@ static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev, } static int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { u32 tmp = 0; int err = 0; @@ -706,7 +706,7 @@ fail_irq: int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, int pixel_format) { - struct sram_channel *sram_ch; + const struct sram_channel *sram_ch; u32 tmp; int err = 0; int data_frame_size = 0; diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c index 7fc97110d97..223aae77c7e 100644 --- a/drivers/media/pci/cx25821/cx25821-video-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c @@ -44,7 +44,7 @@ static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR; int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, - struct sram_channel *ch, + const struct sram_channel *ch, unsigned int bpl, u32 risc) { unsigned int i, lines; @@ -135,7 +135,7 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, int fifo_enable, int field_type) { unsigned int line, i; - struct sram_channel *sram_ch = + const struct sram_channel *sram_ch = dev->channels[dev->_channel_upstream_select].sram_channels; int dist_betwn_starts = bpl * 2; @@ -247,7 +247,7 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) { - struct sram_channel *sram_ch = + const struct sram_channel *sram_ch = dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; u32 tmp = 0; @@ -301,7 +301,7 @@ void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev) } static int cx25821_get_frame(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { struct file *myfile; int frame_index_temp = dev->_frame_index; @@ -407,7 +407,7 @@ static void cx25821_vidups_handler(struct work_struct *work) } static int cx25821_openfile(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { struct file *myfile; int i = 0, j = 0; @@ -489,7 +489,7 @@ static int cx25821_openfile(struct cx25821_dev *dev, } static int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, - struct sram_channel *sram_ch, + const struct sram_channel *sram_ch, int bpl) { int ret = 0; @@ -555,7 +555,7 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, u32 status) { u32 int_msk_tmp; - struct sram_channel *channel = dev->channels[chan_num].sram_channels; + const struct sram_channel *channel = dev->channels[chan_num].sram_channels; int singlefield_lines = NTSC_FIELD_HEIGHT; int line_size_in_bytes = Y422_LINE_SZ; int odd_risc_prog_size = 0; @@ -643,7 +643,7 @@ static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) u32 vid_status; int handled = 0; int channel_num = 0; - struct sram_channel *sram_ch; + const struct sram_channel *sram_ch; if (!dev) return -1; @@ -668,7 +668,7 @@ static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) } static void cx25821_set_pixelengine(struct cx25821_dev *dev, - struct sram_channel *ch, + const struct sram_channel *ch, int pix_format) { int width = WIDTH_D1; @@ -701,7 +701,7 @@ static void cx25821_set_pixelengine(struct cx25821_dev *dev, } static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, - struct sram_channel *sram_ch) + const struct sram_channel *sram_ch) { u32 tmp = 0; int err = 0; @@ -755,7 +755,7 @@ fail_irq: int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, int pixel_format) { - struct sram_channel *sram_ch; + const struct sram_channel *sram_ch; u32 tmp; int err = 0; int data_frame_size = 0; diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 7cd888581f9..c418e0d38c2 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -258,7 +258,7 @@ int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) int cx25821_start_video_dma(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, struct cx25821_buffer *buf, - struct sram_channel *channel) + const struct sram_channel *channel) { int tmp = 0; @@ -285,7 +285,7 @@ int cx25821_start_video_dma(struct cx25821_dev *dev, static int cx25821_restart_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, - struct sram_channel *channel) + const struct sram_channel *channel) { struct cx25821_buffer *buf, *prev; struct list_head *item; @@ -338,7 +338,7 @@ static void cx25821_vid_timeout(unsigned long data) { struct cx25821_data *timeout_data = (struct cx25821_data *)data; struct cx25821_dev *dev = timeout_data->dev; - struct sram_channel *channel = timeout_data->channel; + const struct sram_channel *channel = timeout_data->channel; struct cx25821_dmaqueue *q = &dev->channels[channel->i].vidq; struct cx25821_buffer *buf; unsigned long flags; @@ -365,7 +365,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) u32 count = 0; int handled = 0; u32 mask; - struct sram_channel *channel = dev->channels[chan_num].sram_channels; + const struct sram_channel *channel = dev->channels[chan_num].sram_channels; mask = cx_read(channel->int_msk); if (0 == (status & mask)) @@ -787,9 +787,11 @@ static int video_release(struct file *file) { struct cx25821_fh *fh = file->private_data; struct cx25821_dev *dev = fh->dev; + const struct sram_channel *sram_ch = + dev->channels[0].sram_channels; /* stop the risc engine and fifo */ - cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */ + cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */ /* stop video capture */ if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { @@ -923,7 +925,7 @@ static int vidioc_log_status(struct file *file, void *priv) { struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; struct cx25821_fh *fh = priv; - struct sram_channel *sram_ch = + const struct sram_channel *sram_ch = dev->channels[fh->channel_id].sram_channels; u32 tmp = 0; diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index eb12e35d6de..505b7f0b45b 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h @@ -63,19 +63,6 @@ do { \ #define MEDUSA_READ 910 #define MEDUSA_WRITE 911 -extern struct sram_channel *channel0; -extern struct sram_channel *channel1; -extern struct sram_channel *channel2; -extern struct sram_channel *channel3; -extern struct sram_channel *channel4; -extern struct sram_channel *channel5; -extern struct sram_channel *channel6; -extern struct sram_channel *channel7; -extern struct sram_channel *channel9; -extern struct sram_channel *channel10; -extern struct sram_channel *channel11; -/* extern const u32 *ctrl_classes[]; */ - extern unsigned int vid_limit; #define FORMAT_FLAGS_PACKED 0x01 @@ -98,7 +85,7 @@ extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input); extern int cx25821_start_video_dma(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, struct cx25821_buffer *buf, - struct sram_channel *channel); + const struct sram_channel *channel); extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width, unsigned int height, enum v4l2_field field); diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index fdeecdf09ef..d7e71f46def 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -126,20 +126,11 @@ struct cx25821_fh { enum v4l2_priority prio; - /* video overlay */ - struct v4l2_window win; - struct v4l2_clip *clips; - unsigned int nclips; - /* video capture */ struct cx25821_fmt *fmt; unsigned int width, height; int channel_id; struct videobuf_queue vidq; - - /* H264 Encoder specifics ONLY */ - struct videobuf_queue mpegq; - atomic_t v4l_reading; }; enum cx25821_itype { @@ -222,7 +213,7 @@ struct cx25821_dmaqueue { struct cx25821_data { struct cx25821_dev *dev; - struct sram_channel *channel; + const struct sram_channel *channel; }; struct cx25821_channel { @@ -237,7 +228,7 @@ struct cx25821_channel { struct video_device *video_dev; struct cx25821_dmaqueue vidq; - struct sram_channel *sram_channels; + const struct sram_channel *sram_channels; struct mutex lock; int resources; @@ -470,7 +461,8 @@ struct sram_channel { u32 jumponly; u32 irq_bit; }; -extern struct sram_channel cx25821_sram_channels[]; + +extern const struct sram_channel cx25821_sram_channels[]; #define STATUS_SUCCESS 0 #define STATUS_UNSUCCESSFUL -1 @@ -518,7 +510,7 @@ extern int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder); extern int cx25821_sram_channel_setup(struct cx25821_dev *dev, - struct sram_channel *ch, unsigned int bpl, + const struct sram_channel *ch, unsigned int bpl, u32 risc); extern int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, @@ -537,16 +529,16 @@ extern void cx25821_free_buffer(struct videobuf_queue *q, extern int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, u32 reg, u32 mask, u32 value); extern void cx25821_sram_channel_dump(struct cx25821_dev *dev, - struct sram_channel *ch); + const struct sram_channel *ch); extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev, - struct sram_channel *ch); + const struct sram_channel *ch); extern struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci); extern void cx25821_print_irqbits(char *name, char *tag, char **strings, int len, u32 bits, u32 mask); extern void cx25821_dev_unregister(struct cx25821_dev *dev); extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, - struct sram_channel *ch, + const struct sram_channel *ch, unsigned int bpl, u32 risc); extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, @@ -570,7 +562,7 @@ extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev); extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev); extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev); extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, - struct sram_channel *ch, + const struct sram_channel *ch, unsigned int bpl, u32 risc); extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel, u32 format); -- cgit v1.2.3-70-g09d2 From a8f35ce3d6f5b776463f03403e0319c2415401f7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 07:07:40 -0300 Subject: [media] cx25821: remove unnecessary global devlist This device list is not necessary. The kernel already has all that information, so just use that instead. Also remove a bogus refcount and some dead 'private_free' code in the alsa driver. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-alsa.c | 79 ++++++++++--------------------- drivers/media/pci/cx25821/cx25821-core.c | 21 +------- drivers/media/pci/cx25821/cx25821-video.c | 38 ++++----------- drivers/media/pci/cx25821/cx25821.h | 9 ++-- 4 files changed, 41 insertions(+), 106 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c index b3cac75a489..81361c26c54 100644 --- a/drivers/media/pci/cx25821/cx25821-alsa.c +++ b/drivers/media/pci/cx25821/cx25821-alsa.c @@ -59,7 +59,6 @@ do { \ Data type declarations - Can be moded to a header file later ****************************************************************************/ -static struct snd_card *snd_cx25821_cards[SNDRV_CARDS]; static int devno; struct cx25821_audio_buffer { @@ -626,34 +625,6 @@ static DEFINE_PCI_DEVICE_TABLE(cx25821_audio_pci_tbl) = { MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl); -/* - * Not used in the function snd_cx25821_dev_free so removing - * from the file. - */ -/* -static int snd_cx25821_free(struct cx25821_audio_dev *chip) -{ - if (chip->irq >= 0) - free_irq(chip->irq, chip); - - cx25821_dev_unregister(chip->dev); - pci_disable_device(chip->pci); - - return 0; -} -*/ - -/* - * Component Destructor - */ -static void snd_cx25821_dev_free(struct snd_card *card) -{ - struct cx25821_audio_dev *chip = card->private_data; - - /* snd_cx25821_free(chip); */ - snd_card_free(chip->card); -} - /* * Alsa Constructor - Component probe */ @@ -685,7 +656,6 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) strcpy(card->driver, "cx25821"); /* Card "creation" */ - card->private_free = snd_cx25821_dev_free; chip = card->private_data; spin_lock_init(&chip->reg_lock); @@ -729,8 +699,7 @@ static int cx25821_audio_initdev(struct cx25821_dev *dev) goto error; } - snd_cx25821_cards[devno] = card; - + dev->card = card; devno++; return 0; @@ -742,9 +711,31 @@ error: /**************************************************************************** LINUX MODULE INIT ****************************************************************************/ + +static int cx25821_alsa_exit_callback(struct device *dev, void *data) +{ + struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); + struct cx25821_dev *cxdev = get_cx25821(v4l2_dev); + + snd_card_free(cxdev->card); + return 0; +} + static void cx25821_audio_fini(void) { - snd_card_free(snd_cx25821_cards[0]); + struct device_driver *drv = driver_find("cx25821", &pci_bus_type); + int ret; + + ret = driver_for_each_device(drv, NULL, NULL, cx25821_alsa_exit_callback); +} + +static int cx25821_alsa_init_callback(struct device *dev, void *data) +{ + struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); + struct cx25821_dev *cxdev = get_cx25821(v4l2_dev); + + cx25821_audio_initdev(cxdev); + return 0; } /* @@ -756,29 +747,11 @@ static void cx25821_audio_fini(void) */ static int cx25821_alsa_init(void) { - struct cx25821_dev *dev = NULL; - struct list_head *list; + struct device_driver *drv = driver_find("cx25821", &pci_bus_type); - mutex_lock(&cx25821_devlist_mutex); - list_for_each(list, &cx25821_devlist) { - dev = list_entry(list, struct cx25821_dev, devlist); - cx25821_audio_initdev(dev); - } - mutex_unlock(&cx25821_devlist_mutex); - - if (dev == NULL) - pr_info("ERROR ALSA: no cx25821 cards found\n"); - - return 0; + return driver_for_each_device(drv, NULL, NULL, cx25821_alsa_init_callback); } late_initcall(cx25821_alsa_init); module_exit(cx25821_audio_fini); - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 48faf6fc273..6205ade04a9 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -41,13 +41,6 @@ static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET }; module_param_array(card, int, NULL, 0444); MODULE_PARM_DESC(card, "card type"); -static unsigned int cx25821_devcount; - -DEFINE_MUTEX(cx25821_devlist_mutex); -EXPORT_SYMBOL(cx25821_devlist_mutex); -LIST_HEAD(cx25821_devlist); -EXPORT_SYMBOL(cx25821_devlist); - const struct sram_channel cx25821_sram_channels[] = { [SRAM_CH00] = { .i = SRAM_CH00, @@ -871,6 +864,7 @@ static void cx25821_iounmap(struct cx25821_dev *dev) static int cx25821_dev_setup(struct cx25821_dev *dev) { + static unsigned int cx25821_devcount; int i; pr_info("\n***********************************\n"); @@ -879,15 +873,9 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) mutex_init(&dev->lock); - atomic_inc(&dev->refcount); - dev->nr = ++cx25821_devcount; sprintf(dev->name, "cx25821[%d]", dev->nr); - mutex_lock(&cx25821_devlist_mutex); - list_add_tail(&dev->devlist, &cx25821_devlist); - mutex_unlock(&cx25821_devlist_mutex); - if (dev->pci->device != 0x8210) { pr_info("%s(): Exiting. Incorrect Hardware device = 0x%02x\n", __func__, dev->pci->device); @@ -1021,9 +1009,6 @@ void cx25821_dev_unregister(struct cx25821_dev *dev) release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0)); - if (!atomic_dec_and_test(&dev->refcount)) - return; - for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) { if (i == SRAM_CH08) /* audio channel */ continue; @@ -1414,10 +1399,6 @@ static void cx25821_finidev(struct pci_dev *pci_dev) if (pci_dev->irq) free_irq(pci_dev->irq, dev); - mutex_lock(&cx25821_devlist_mutex); - list_del(&dev->devlist); - mutex_unlock(&cx25821_devlist_mutex); - cx25821_dev_unregister(dev); v4l2_device_unregister(v4l2_dev); kfree(dev); diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index c418e0d38c2..a9aa09651ca 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -654,45 +654,28 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { struct video_device *vdev = video_devdata(file); - struct cx25821_dev *h, *dev = video_drvdata(file); + struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - struct list_head *list; - int minor = video_devdata(file)->minor; enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; - int ch_id = 0; - int i; + int ch_id; dprintk(1, "open dev=%s type=%s\n", video_device_node_name(vdev), v4l2_type_names[type]); + for (ch_id = 0; ch_id < MAX_VID_CHANNEL_NUM - 1; ch_id++) + if (dev->channels[ch_id].video_dev == vdev) + break; + + /* Can't happen */ + if (ch_id >= MAX_VID_CHANNEL_NUM - 1) + return -ENODEV; + /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); if (NULL == fh) return -ENOMEM; - mutex_lock(&cx25821_devlist_mutex); - - list_for_each(list, &cx25821_devlist) - { - h = list_entry(list, struct cx25821_dev, devlist); - - for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) { - if (h->channels[i].video_dev && - h->channels[i].video_dev->minor == minor) { - dev = h; - ch_id = i; - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - } - } - } - - if (NULL == dev) { - mutex_unlock(&cx25821_devlist_mutex); - kfree(fh); - return -ENODEV; - } - file->private_data = fh; fh->dev = dev; fh->type = type; @@ -719,7 +702,6 @@ static int video_open(struct file *file) fh, NULL); dprintk(1, "post videobuf_queue_init()\n"); - mutex_unlock(&cx25821_devlist_mutex); return 0; } diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index d7e71f46def..195b00407b5 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -238,9 +238,9 @@ struct cx25821_channel { int cif_width; }; +struct snd_card; + struct cx25821_dev { - struct list_head devlist; - atomic_t refcount; struct v4l2_device v4l2_dev; /* pci stuff */ @@ -252,6 +252,8 @@ struct cx25821_dev { u8 __iomem *bmmio; int pci_irqmask; int hwrevision; + /* used by cx25821-alsa */ + struct snd_card *card; u32 clk_freq; @@ -403,9 +405,6 @@ static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) #define cx25821_call_all(dev, o, f, args...) \ v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) -extern struct list_head cx25821_devlist; -extern struct mutex cx25821_devlist_mutex; - extern struct cx25821_board cx25821_boards[]; extern struct cx25821_subid cx25821_subids[]; -- cgit v1.2.3-70-g09d2 From 6b1dce251fa21caea4e0021fd3fd0d8dcdece784 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 07:39:19 -0300 Subject: [media] cx25821: s_input didn't check for invalid input The s_input implementation allowed input 1 even if that didn't exist. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index a9aa09651ca..9ddc7ac03a7 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -1163,10 +1163,8 @@ int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) return err; } - if (i >= CX25821_NR_INPUT) { - dprintk(1, "%s(): -EINVAL\n", __func__); + if (i >= CX25821_NR_INPUT || INPUT(i)->type == 0) return -EINVAL; - } mutex_lock(&dev->lock); cx25821_video_mux(dev, i); -- cgit v1.2.3-70-g09d2 From 95c232a24b73199f464e3234510ae4729196f38d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 07:41:29 -0300 Subject: [media] cx25821: make lots of externals static A lot of functions and variables were external when they really can be declared as static. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 313 ++++++++++++++---------------- drivers/media/pci/cx25821/cx25821-video.h | 74 ------- drivers/media/pci/cx25821/cx25821.h | 9 +- 3 files changed, 153 insertions(+), 243 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 9ddc7ac03a7..9e948eff6b8 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -46,15 +46,13 @@ static unsigned int irq_debug; module_param(irq_debug, int, 0644); MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]"); -unsigned int vid_limit = 16; +static unsigned int vid_limit = 16; module_param(vid_limit, int, 0644); MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); -static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num); - #define FORMAT_FLAGS_PACKED 0x01 -struct cx25821_fmt formats[] = { +static const struct cx25821_fmt formats[] = { { .name = "8 bpp, gray", .fourcc = V4L2_PIX_FMT_GREY, @@ -83,12 +81,7 @@ struct cx25821_fmt formats[] = { }, }; -int cx25821_get_format_size(void) -{ - return ARRAY_SIZE(formats); -} - -struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc) +static const struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc) { unsigned int i; @@ -138,7 +131,7 @@ void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc); } -int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) +static int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) { dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__, (unsigned int)norm, v4l2_norm_to_name(norm)); @@ -151,7 +144,7 @@ int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) return 0; } -struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, +static struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, struct pci_dev *pci, const struct video_device *template, char *type) @@ -237,7 +230,7 @@ void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, mutex_unlock(&dev->lock); } -int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) +static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) { struct v4l2_routing route; memset(&route, 0, sizeof(route)); @@ -403,7 +396,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) return handled; } -int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, +static int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) { struct cx25821_fh *fh = q->priv_data; @@ -419,7 +412,7 @@ int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, return 0; } -int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, +static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct cx25821_fh *fh = q->priv_data; @@ -546,7 +539,7 @@ fail: return rc; } -void cx25821_buffer_release(struct videobuf_queue *q, +static void cx25821_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct cx25821_buffer *buf = @@ -555,7 +548,7 @@ void cx25821_buffer_release(struct videobuf_queue *q, cx25821_free_buffer(q, buf); } -struct videobuf_queue *get_queue(struct cx25821_fh *fh) +static struct videobuf_queue *get_queue(struct cx25821_fh *fh) { switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -566,7 +559,7 @@ struct videobuf_queue *get_queue(struct cx25821_fh *fh) } } -int cx25821_get_resource(struct cx25821_fh *fh, int resource) +static int cx25821_get_resource(struct cx25821_fh *fh, int resource) { switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: @@ -577,7 +570,7 @@ int cx25821_get_resource(struct cx25821_fh *fh, int resource) } } -int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) +static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) { struct cx25821_fh *fh = file->private_data; @@ -795,6 +788,70 @@ static int video_release(struct file *file) return 0; } +/* VIDEO IOCTLS */ +static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct cx25821_fh *fh = priv; + + f->fmt.pix.width = fh->width; + f->fmt.pix.height = fh->height; + f->fmt.pix.field = fh->vidq.field; + f->fmt.pix.pixelformat = fh->fmt->fourcc; + f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3; + f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + + return 0; +} + +static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + const struct cx25821_fmt *fmt; + enum v4l2_field field; + unsigned int maxw, maxh; + + fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); + if (NULL == fmt) + return -EINVAL; + + field = f->fmt.pix.field; + maxw = 720; + maxh = 576; + + if (V4L2_FIELD_ANY == field) { + if (f->fmt.pix.height > maxh / 2) + field = V4L2_FIELD_INTERLACED; + else + field = V4L2_FIELD_TOP; + } + + switch (field) { + case V4L2_FIELD_TOP: + case V4L2_FIELD_BOTTOM: + maxh = maxh / 2; + break; + case V4L2_FIELD_INTERLACED: + break; + default: + return -EINVAL; + } + + 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; + f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + + return 0; +} static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { struct cx25821_fh *fh = priv; @@ -832,6 +889,43 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) return 0; } +static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm) +{ + if (tvnorm == V4L2_STD_PAL_BG) { + if (width == 352 || width == 720) + return 1; + else + return 0; + } + + if (tvnorm == V4L2_STD_NTSC_M) { + if (width == 320 || width == 352 || width == 720) + return 1; + else + return 0; + } + return 0; +} + +static int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm) +{ + if (tvnorm == V4L2_STD_PAL_BG) { + if (height == 576 || height == 288) + return 1; + else + return 0; + } + + if (tvnorm == V4L2_STD_NTSC_M) { + if (height == 480 || height == 240) + return 1; + else + return 0; + } + + return 0; +} + static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { @@ -918,89 +1012,8 @@ static int vidioc_log_status(struct file *file, void *priv) return 0; } -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - int err; - - if (fh) { - err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, - fh->prio); - if (0 != err) - return err; - } - - return cx25821_set_control(dev, ctl, fh->channel_id); -} - -/* VIDEO IOCTLS */ -int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx25821_fh *fh = priv; - - f->fmt.pix.width = fh->width; - f->fmt.pix.height = fh->height; - f->fmt.pix.field = fh->vidq.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3; - f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; - - return 0; -} - -int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx25821_fmt *fmt; - enum v4l2_field field; - unsigned int maxw, maxh; - - fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); - if (NULL == fmt) - return -EINVAL; - - field = f->fmt.pix.field; - maxw = 720; - maxh = 576; - - if (V4L2_FIELD_ANY == field) { - if (f->fmt.pix.height > maxh / 2) - field = V4L2_FIELD_INTERLACED; - else - field = V4L2_FIELD_TOP; - } - - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - maxh = maxh / 2; - break; - case V4L2_FIELD_INTERLACED: - break; - default: - return -EINVAL; - } - - 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; - f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; - f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; - - return 0; -} -int cx25821_vidioc_querycap(struct file *file, void *priv, +static int cx25821_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; @@ -1020,7 +1033,7 @@ int cx25821_vidioc_querycap(struct file *file, void *priv, return 0; } -int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, +static int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (unlikely(f->index >= ARRAY_SIZE(formats))) @@ -1032,27 +1045,27 @@ int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, return 0; } -int cx25821_vidioc_reqbufs(struct file *file, void *priv, +static int cx25821_vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { struct cx25821_fh *fh = priv; return videobuf_reqbufs(get_queue(fh), p); } -int cx25821_vidioc_querybuf(struct file *file, void *priv, +static int cx25821_vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) { struct cx25821_fh *fh = priv; return videobuf_querybuf(get_queue(fh), p); } -int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) +static int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { struct cx25821_fh *fh = priv; return videobuf_qbuf(get_queue(fh), p); } -int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) +static int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) { struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev; struct cx25821_fh *fh = f; @@ -1062,7 +1075,7 @@ int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) return 0; } -int cx25821_vidioc_s_priority(struct file *file, void *f, +static int cx25821_vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio) { struct cx25821_fh *fh = f; @@ -1072,7 +1085,7 @@ int cx25821_vidioc_s_priority(struct file *file, void *f, prio); } -int cx25821_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms) +static int cx25821_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms) { struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; @@ -1107,18 +1120,20 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) return 0; } -int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i) +static int cx25821_vidioc_enum_input(struct file *file, void *priv, + struct v4l2_input *i) { static const char * const iname[] = { [CX25821_VMUX_COMPOSITE] = "Composite", [CX25821_VMUX_SVIDEO] = "S-Video", [CX25821_VMUX_DEBUG] = "for debug only", }; + struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; unsigned int n; dprintk(1, "%s()\n", __func__); n = i->index; - if (n >= 2) + if (n >= CX25821_NR_INPUT) return -EINVAL; if (0 == INPUT(n)->type) @@ -1131,15 +1146,7 @@ int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i) return 0; } -int cx25821_vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - dprintk(1, "%s()\n", __func__); - return cx25821_enum_input(dev, i); -} - -int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i) +static int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i) { struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; @@ -1148,7 +1155,7 @@ int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i) return 0; } -int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) +static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) { struct cx25821_fh *fh = priv; struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; @@ -1262,7 +1269,7 @@ static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl) return 0; } -int cx25821_vidioc_queryctrl(struct file *file, void *priv, +static int cx25821_vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *qctrl) { return cx25821_ctrl_query(qctrl); @@ -1281,7 +1288,7 @@ static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id) return NULL; } -int cx25821_vidioc_g_ctrl(struct file *file, void *priv, +static int cx25821_vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl) { struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; @@ -1310,7 +1317,7 @@ int cx25821_vidioc_g_ctrl(struct file *file, void *priv, return 0; } -int cx25821_set_control(struct cx25821_dev *dev, +static int cx25821_set_control(struct cx25821_dev *dev, struct v4l2_control *ctl, int chan_num) { int err; @@ -1360,6 +1367,23 @@ int cx25821_set_control(struct cx25821_dev *dev, return err; } +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctl) +{ + struct cx25821_fh *fh = priv; + struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; + int err; + + if (fh) { + err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, + fh->prio); + if (0 != err) + return err; + } + + return cx25821_set_control(dev, ctl, fh->channel_id); +} + static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num) { struct v4l2_control ctrl; @@ -1372,7 +1396,7 @@ static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num) } } -int cx25821_vidioc_cropcap(struct file *file, void *priv, +static int cx25821_vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap) { struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; @@ -1391,7 +1415,7 @@ int cx25821_vidioc_cropcap(struct file *file, void *priv, return 0; } -int cx25821_vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop) +static int cx25821_vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop) { struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; struct cx25821_fh *fh = priv; @@ -1407,49 +1431,12 @@ int cx25821_vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop return -EINVAL; } -int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) +static int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) { /* cx25821_vidioc_g_crop not supported */ return -EINVAL; } -int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm) -{ - if (tvnorm == V4L2_STD_PAL_BG) { - if (width == 352 || width == 720) - return 1; - else - return 0; - } - - if (tvnorm == V4L2_STD_NTSC_M) { - if (width == 320 || width == 352 || width == 720) - return 1; - else - return 0; - } - return 0; -} - -int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm) -{ - if (tvnorm == V4L2_STD_PAL_BG) { - if (height == 576 || height == 288) - return 1; - else - return 0; - } - - if (tvnorm == V4L2_STD_NTSC_M) { - if (height == 480 || height == 240) - return 1; - else - return 0; - } - - return 0; -} - static long video_ioctl_upstream9(struct file *file, unsigned int cmd, unsigned long arg) { diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index 505b7f0b45b..9d70020d925 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h @@ -63,97 +63,23 @@ do { \ #define MEDUSA_READ 910 #define MEDUSA_WRITE 911 -extern unsigned int vid_limit; - #define FORMAT_FLAGS_PACKED 0x01 -extern struct cx25821_fmt formats[]; -extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc); -extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; - extern void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, u32 count); -extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm); - extern int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit); extern int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit); extern int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit); extern void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits); -extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input); extern int cx25821_start_video_dma(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, struct cx25821_buffer *buf, const struct sram_channel *channel); -extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width, - unsigned int height, enum v4l2_field field); extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status); extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num); extern int cx25821_video_register(struct cx25821_dev *dev); -extern int cx25821_get_format_size(void); - -extern int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, - unsigned int *size); -extern int cx25821_buffer_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, - enum v4l2_field field); -extern void cx25821_buffer_release(struct videobuf_queue *q, - struct videobuf_buffer *vb); -extern struct videobuf_queue *get_queue(struct cx25821_fh *fh); -extern int cx25821_get_resource(struct cx25821_fh *fh, int resource); -extern int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma); -extern int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f); -extern int cx25821_vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap); -extern int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f); -extern int cx25821_vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p); -extern int cx25821_vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *p); -extern int cx25821_vidioc_qbuf(struct file *file, void *priv, - struct v4l2_buffer *p); -extern int cx25821_vidioc_s_std(struct file *file, void *priv, - v4l2_std_id tvnorms); -extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i); -extern int cx25821_vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i); -extern int cx25821_vidioc_g_input(struct file *file, void *priv, - unsigned int *i); -extern int cx25821_vidioc_s_input(struct file *file, void *priv, - unsigned int i); -extern int cx25821_vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl); -extern int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f); -extern int cx25821_vidioc_g_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg); -extern int cx25821_vidioc_s_register(struct file *file, void *fh, - const struct v4l2_dbg_register *reg); - -extern int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm); -extern int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm); - -extern int cx25821_vidioc_g_priority(struct file *file, void *f, - enum v4l2_priority *p); -extern int cx25821_vidioc_s_priority(struct file *file, void *f, - enum v4l2_priority prio); - -extern int cx25821_vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qctrl); -extern int cx25821_set_control(struct cx25821_dev *dev, - struct v4l2_control *ctrl, int chan_num); - -extern int cx25821_vidioc_cropcap(struct file *file, void *fh, - struct v4l2_cropcap *cropcap); -extern int cx25821_vidioc_s_crop(struct file *file, void *priv, - const struct v4l2_crop *crop); -extern int cx25821_vidioc_g_crop(struct file *file, void *priv, - struct v4l2_crop *crop); -extern int cx25821_vidioc_querystd(struct file *file, void *priv, - v4l2_std_id *norm); #endif diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 195b00407b5..033993f1fb0 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -127,7 +127,7 @@ struct cx25821_fh { enum v4l2_priority prio; /* video capture */ - struct cx25821_fmt *fmt; + const struct cx25821_fmt *fmt; unsigned int width, height; int channel_id; struct videobuf_queue vidq; @@ -152,7 +152,7 @@ struct cx25821_buffer { /* cx25821 specific */ unsigned int bpl; struct btcx_riscmem risc; - struct cx25821_fmt *fmt; + const struct cx25821_fmt *fmt; u32 count; }; @@ -565,8 +565,5 @@ extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, unsigned int bpl, u32 risc); extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel, u32 format); -extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, - struct pci_dev *pci, - const struct video_device *template, - char *type); + #endif -- cgit v1.2.3-70-g09d2 From de9ea4cf7fd875460646f97c1f8addafe0454180 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 07:47:12 -0300 Subject: [media] cx25821: remove cropping ioctls This driver does not implement cropping, so remove the cropping ioctls. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 44 ------------------------------- 1 file changed, 44 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 9e948eff6b8..9919a0e93f4 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -1396,47 +1396,6 @@ static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num) } } -static int cx25821_vidioc_cropcap(struct file *file, void *priv, - struct v4l2_cropcap *cropcap) -{ - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - cropcap->bounds.top = 0; - cropcap->bounds.left = 0; - cropcap->bounds.width = 720; - cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480; - cropcap->pixelaspect.numerator = - dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10; - cropcap->pixelaspect.denominator = - dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11; - cropcap->defrect = cropcap->bounds; - return 0; -} - -static int cx25821_vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop) -{ - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - struct cx25821_fh *fh = priv; - int err; - - if (fh) { - err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, - fh->prio); - if (0 != err) - return err; - } - /* cx25821_vidioc_s_crop not supported */ - return -EINVAL; -} - -static int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) -{ - /* cx25821_vidioc_g_crop not supported */ - return -EINVAL; -} - static long video_ioctl_upstream9(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1713,9 +1672,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_dqbuf = vidioc_dqbuf, .vidioc_g_std = cx25821_vidioc_g_std, .vidioc_s_std = cx25821_vidioc_s_std, - .vidioc_cropcap = cx25821_vidioc_cropcap, - .vidioc_s_crop = cx25821_vidioc_s_crop, - .vidioc_g_crop = cx25821_vidioc_g_crop, .vidioc_enum_input = cx25821_vidioc_enum_input, .vidioc_g_input = cx25821_vidioc_g_input, .vidioc_s_input = cx25821_vidioc_s_input, -- cgit v1.2.3-70-g09d2 From 89c21389f2a48afb2fb24fdf74433950cb9b19a2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 08:01:31 -0300 Subject: [media] cx25821: remove bogus dependencies This driver doesn't use DVB, RC, cx25840 or tveeprom. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/Kconfig | 7 +------ drivers/media/pci/cx25821/Makefile | 3 --- drivers/media/pci/cx25821/cx25821-cards.c | 21 --------------------- drivers/media/pci/cx25821/cx25821-core.c | 2 -- drivers/media/pci/cx25821/cx25821-gpio.c | 1 + drivers/media/pci/cx25821/cx25821-i2c.c | 3 ++- drivers/media/pci/cx25821/cx25821.h | 11 ----------- 7 files changed, 4 insertions(+), 44 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/Kconfig b/drivers/media/pci/cx25821/Kconfig index 4017c942034..6439a847680 100644 --- a/drivers/media/pci/cx25821/Kconfig +++ b/drivers/media/pci/cx25821/Kconfig @@ -1,14 +1,9 @@ config VIDEO_CX25821 tristate "Conexant cx25821 support" - depends on DVB_CORE && VIDEO_DEV && PCI && I2C + depends on VIDEO_DEV && PCI && I2C select I2C_ALGOBIT select VIDEO_BTCX - select VIDEO_TVEEPROM - depends on RC_CORE - select VIDEOBUF_DVB select VIDEOBUF_DMA_SG - select VIDEO_CX25840 - select VIDEO_CX2341X ---help--- This is a video4linux driver for Conexant 25821 based TV cards. diff --git a/drivers/media/pci/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile index caa32b7b51f..b54a32e88bd 100644 --- a/drivers/media/pci/cx25821/Makefile +++ b/drivers/media/pci/cx25821/Makefile @@ -9,6 +9,3 @@ obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o ccflags-y += -Idrivers/media/i2c ccflags-y += -Idrivers/media/common -ccflags-y += -Idrivers/media/tuners -ccflags-y += -Idrivers/media/dvb-core -ccflags-y += -Idrivers/media/dvb-frontends diff --git a/drivers/media/pci/cx25821/cx25821-cards.c b/drivers/media/pci/cx25821/cx25821-cards.c index c09ec68460e..2b2f1f4f87a 100644 --- a/drivers/media/pci/cx25821/cx25821-cards.c +++ b/drivers/media/pci/cx25821/cx25821-cards.c @@ -26,8 +26,6 @@ #include #include #include -#include -#include #include "cx25821.h" @@ -50,22 +48,3 @@ struct cx25821_board cx25821_boards[] = { }; const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards); - -struct cx25821_subid cx25821_subids[] = { - { - .subvendor = 0x14f1, - .subdevice = 0x0920, - .card = CX25821_BOARD, - }, -}; - -void cx25821_card_setup(struct cx25821_dev *dev) -{ - static u8 eeprom[256]; - - if (dev->i2c_bus[0].i2c_rc == 0) { - dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; - tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, - sizeof(eeprom)); - } -} diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 6205ade04a9..82c2db0944e 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -953,8 +953,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) CX25821_INFO("i2c register! bus->i2c_rc = %d\n", dev->i2c_bus[0].i2c_rc); - cx25821_card_setup(dev); - if (medusa_video_init(dev) < 0) CX25821_ERR("%s(): Failed to initialize medusa!\n", __func__); diff --git a/drivers/media/pci/cx25821/cx25821-gpio.c b/drivers/media/pci/cx25821/cx25821-gpio.c index 29e43b03c85..95e8ddf6294 100644 --- a/drivers/media/pci/cx25821/cx25821-gpio.c +++ b/drivers/media/pci/cx25821/cx25821-gpio.c @@ -20,6 +20,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include "cx25821.h" /********************* GPIO stuffs *********************/ diff --git a/drivers/media/pci/cx25821/cx25821-i2c.c b/drivers/media/pci/cx25821/cx25821-i2c.c index a8dc945bbe1..dca37c7dba7 100644 --- a/drivers/media/pci/cx25821/cx25821-i2c.c +++ b/drivers/media/pci/cx25821/cx25821-i2c.c @@ -23,8 +23,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include "cx25821.h" +#include #include +#include "cx25821.h" static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 033993f1fb0..61c6cfc02d8 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -33,9 +33,7 @@ #include #include -#include #include -#include #include "btcx-risc.h" #include "cx25821-reg.h" @@ -178,12 +176,6 @@ struct cx25821_board { struct cx25821_input input[CX25821_NR_INPUT]; }; -struct cx25821_subid { - u16 subvendor; - u16 subdevice; - u32 card; -}; - struct cx25821_i2c { struct cx25821_dev *dev; @@ -406,7 +398,6 @@ static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) extern struct cx25821_board cx25821_boards[]; -extern struct cx25821_subid cx25821_subids[]; #define SRAM_CH00 0 /* Video A */ #define SRAM_CH01 1 /* Video B */ @@ -487,8 +478,6 @@ extern const struct sram_channel cx25821_sram_channels[]; pr_info("(%d): " fmt, dev->board, ##args) extern int cx25821_i2c_register(struct cx25821_i2c *bus); -extern void cx25821_card_setup(struct cx25821_dev *dev); -extern int cx25821_ir_init(struct cx25821_dev *dev); extern int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value); extern int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value); extern int cx25821_i2c_unregister(struct cx25821_i2c *bus); -- cgit v1.2.3-70-g09d2 From 467870ca26c01cb0ac84e969a78160f8164919cc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 08:18:00 -0300 Subject: [media] cx25821: embed video_device, clean up some kernel log spam Embed the video_device struct instead of allocating it. Remove some of the annoying and ugly kernel messages shown during loading and unloading of the module. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-core.c | 15 +-------- drivers/media/pci/cx25821/cx25821-video.c | 54 ++++++++----------------------- drivers/media/pci/cx25821/cx25821.h | 2 +- 3 files changed, 16 insertions(+), 55 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 82c2db0944e..f3a48a17c4c 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -845,8 +845,7 @@ static void cx25821_dev_checkrevision(struct cx25821_dev *dev) { dev->hwrevision = cx_read(RDR_CFG2) & 0xff; - pr_info("%s(): Hardware revision = 0x%02x\n", - __func__, dev->hwrevision); + pr_info("Hardware revision = 0x%02x\n", dev->hwrevision); } static void cx25821_iounmap(struct cx25821_dev *dev) @@ -856,7 +855,6 @@ static void cx25821_iounmap(struct cx25821_dev *dev) /* Releasing IO memory */ if (dev->lmmio != NULL) { - CX25821_INFO("Releasing lmmio.\n"); iounmap(dev->lmmio); dev->lmmio = NULL; } @@ -867,10 +865,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) static unsigned int cx25821_devcount; int i; - pr_info("\n***********************************\n"); - pr_info("cx25821 set up\n"); - pr_info("***********************************\n\n"); - mutex_init(&dev->lock); dev->nr = ++cx25821_devcount; @@ -950,17 +944,12 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) /* cx25821_i2c_register(&dev->i2c_bus[1]); * cx25821_i2c_register(&dev->i2c_bus[2]); */ - CX25821_INFO("i2c register! bus->i2c_rc = %d\n", - dev->i2c_bus[0].i2c_rc); - if (medusa_video_init(dev) < 0) CX25821_ERR("%s(): Failed to initialize medusa!\n", __func__); cx25821_video_register(dev); cx25821_dev_checkrevision(dev); - CX25821_INFO("setup done!\n"); - return 0; } @@ -1337,8 +1326,6 @@ static int cx25821_initdev(struct pci_dev *pci_dev, goto fail_unregister_device; } - pr_info("Athena pci enable !\n"); - err = cx25821_dev_setup(dev); if (err) { if (err == -EBUSY) diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 9919a0e93f4..41e3475efec 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -144,26 +144,6 @@ static int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) return 0; } -static struct video_device *cx25821_vdev_init(struct cx25821_dev *dev, - struct pci_dev *pci, - const struct video_device *template, - char *type) -{ - struct video_device *vfd; - dprintk(1, "%s()\n", __func__); - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - *vfd = *template; - vfd->v4l2_dev = &dev->v4l2_dev; - vfd->release = video_device_release; - snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, - cx25821_boards[dev->board].name); - video_set_drvdata(vfd, dev); - return vfd; -} - /* static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl) { @@ -657,7 +637,7 @@ static int video_open(struct file *file) v4l2_type_names[type]); for (ch_id = 0; ch_id < MAX_VID_CHANNEL_NUM - 1; ch_id++) - if (dev->channels[ch_id].video_dev == vdev) + if (&dev->channels[ch_id].vdev == vdev) break; /* Can't happen */ @@ -1692,6 +1672,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static const struct video_device cx25821_video_device = { .name = "cx25821-video", .fops = &video_fops, + .release = video_device_release_empty, .minor = -1, .ioctl_ops = &video_ioctl_ops, .tvnorms = CX25821_NORMS, @@ -1701,22 +1682,12 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) { cx_clear(PCI_INT_MSK, 1); - if (dev->channels[chan_num].video_dev) { - if (video_is_registered(dev->channels[chan_num].video_dev)) - video_unregister_device( - dev->channels[chan_num].video_dev); - else - video_device_release( - dev->channels[chan_num].video_dev); - - dev->channels[chan_num].video_dev = NULL; + if (video_is_registered(&dev->channels[chan_num].vdev)) { + video_unregister_device(&dev->channels[chan_num].vdev); btcx_riscmem_free(dev->pci, &dev->channels[chan_num].vidq.stopper); - - pr_warn("device %d released!\n", chan_num); } - } int cx25821_video_register(struct cx25821_dev *dev) @@ -1727,6 +1698,8 @@ int cx25821_video_register(struct cx25821_dev *dev) spin_lock_init(&dev->slock); for (i = 0; i < VID_CHANNEL_NUM; ++i) { + struct video_device *vdev = &dev->channels[i].vdev; + if (i == SRAM_CH08) /* audio channel */ continue; @@ -1736,7 +1709,6 @@ int cx25821_video_register(struct cx25821_dev *dev) dev->channels[i].sram_channels->dma_ctl, 0x11, 0); dev->channels[i].sram_channels = &cx25821_sram_channels[i]; - dev->channels[i].video_dev = NULL; dev->channels[i].resources = 0; cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff); @@ -1753,15 +1725,16 @@ int cx25821_video_register(struct cx25821_dev *dev) init_timer(&dev->channels[i].vidq.timeout); /* register v4l devices */ - dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci, - &cx25821_video_device, "video"); + *vdev = cx25821_video_device; + vdev->v4l2_dev = &dev->v4l2_dev; + snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); + video_set_drvdata(vdev, dev); - err = video_register_device(dev->channels[i].video_dev, - VFL_TYPE_GRABBER, video_nr[dev->nr]); + err = video_register_device(vdev, VFL_TYPE_GRABBER, + video_nr[dev->nr]); if (err < 0) goto fail_unreg; - } /* set PCI interrupt */ @@ -1776,6 +1749,7 @@ int cx25821_video_register(struct cx25821_dev *dev) return 0; fail_unreg: - cx25821_video_unregister(dev, i); + while (i >= 0) + cx25821_video_unregister(dev, i--); return err; } diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 61c6cfc02d8..df2ea22563e 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -217,7 +217,7 @@ struct cx25821_channel { int ctl_saturation; struct cx25821_data timeout_data; - struct video_device *video_dev; + struct video_device vdev; struct cx25821_dmaqueue vidq; const struct sram_channel *sram_channels; -- cgit v1.2.3-70-g09d2 From f8d7ee70919d44ef4f01f3c9bc49af54fdc433bc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 08:38:14 -0300 Subject: [media] cx25821: convert to the control framework Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-core.c | 5 +- drivers/media/pci/cx25821/cx25821-video.c | 210 +++++------------------------- drivers/media/pci/cx25821/cx25821.h | 10 +- 3 files changed, 41 insertions(+), 184 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index f3a48a17c4c..bf6c1812dd8 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -880,8 +880,11 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) /* Apply a sensible clock frequency for the PCIe bridge */ dev->clk_freq = 28000000; - for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) + for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) { + dev->channels[i].dev = dev; + dev->channels[i].id = i; dev->channels[i].sram_channels = &cx25821_sram_channels[i]; + } if (dev->nr > 1) CX25821_INFO("dev->nr > 1!"); diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 41e3475efec..0c11f314c62 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -1188,192 +1188,29 @@ int cx25821_vidioc_s_register(struct file *file, void *fh, #endif -/*****************************************************************************/ -static const struct v4l2_queryctrl no_ctl = { - .name = "42", - .flags = V4L2_CTRL_FLAG_DISABLED, -}; - -static struct v4l2_queryctrl cx25821_ctls[] = { - /* --- video --- */ - { - .id = V4L2_CID_BRIGHTNESS, - .name = "Brightness", - .minimum = 0, - .maximum = 10000, - .step = 1, - .default_value = 6200, - .type = V4L2_CTRL_TYPE_INTEGER, - }, { - .id = V4L2_CID_CONTRAST, - .name = "Contrast", - .minimum = 0, - .maximum = 10000, - .step = 1, - .default_value = 5000, - .type = V4L2_CTRL_TYPE_INTEGER, - }, { - .id = V4L2_CID_SATURATION, - .name = "Saturation", - .minimum = 0, - .maximum = 10000, - .step = 1, - .default_value = 5000, - .type = V4L2_CTRL_TYPE_INTEGER, - }, { - .id = V4L2_CID_HUE, - .name = "Hue", - .minimum = 0, - .maximum = 10000, - .step = 1, - .default_value = 5000, - .type = V4L2_CTRL_TYPE_INTEGER, - } -}; -static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls); - -static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl) -{ - int i; - - if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1) - return -EINVAL; - for (i = 0; i < CX25821_CTLS; i++) - if (cx25821_ctls[i].id == qctrl->id) - break; - if (i == CX25821_CTLS) { - *qctrl = no_ctl; - return 0; - } - *qctrl = cx25821_ctls[i]; - return 0; -} - -static int cx25821_vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qctrl) -{ - return cx25821_ctrl_query(qctrl); -} - -/* ------------------------------------------------------------------ */ -/* VIDEO CTRL IOCTLS */ - -static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id) +static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl) { - unsigned int i; + struct cx25821_channel *chan = + container_of(ctrl->handler, struct cx25821_channel, hdl); + struct cx25821_dev *dev = chan->dev; - for (i = 0; i < CX25821_CTLS; i++) - if (cx25821_ctls[i].id == id) - return cx25821_ctls + i; - return NULL; -} - -static int cx25821_vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - struct cx25821_fh *fh = priv; - - const struct v4l2_queryctrl *ctrl; - - ctrl = ctrl_by_id(ctl->id); - - if (NULL == ctrl) - return -EINVAL; - switch (ctl->id) { + switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: - ctl->value = dev->channels[fh->channel_id].ctl_bright; + medusa_set_brightness(dev, ctrl->val, chan->id); break; case V4L2_CID_HUE: - ctl->value = dev->channels[fh->channel_id].ctl_hue; + medusa_set_hue(dev, ctrl->val, chan->id); break; case V4L2_CID_CONTRAST: - ctl->value = dev->channels[fh->channel_id].ctl_contrast; + medusa_set_contrast(dev, ctrl->val, chan->id); break; case V4L2_CID_SATURATION: - ctl->value = dev->channels[fh->channel_id].ctl_saturation; - break; - } - return 0; -} - -static int cx25821_set_control(struct cx25821_dev *dev, - struct v4l2_control *ctl, int chan_num) -{ - int err; - const struct v4l2_queryctrl *ctrl; - - err = -EINVAL; - - ctrl = ctrl_by_id(ctl->id); - - if (NULL == ctrl) - return err; - - switch (ctrl->type) { - case V4L2_CTRL_TYPE_BOOLEAN: - case V4L2_CTRL_TYPE_MENU: - case V4L2_CTRL_TYPE_INTEGER: - if (ctl->value < ctrl->minimum) - ctl->value = ctrl->minimum; - if (ctl->value > ctrl->maximum) - ctl->value = ctrl->maximum; + medusa_set_saturation(dev, ctrl->val, chan->id); break; default: - /* nothing */ ; - } - - switch (ctl->id) { - case V4L2_CID_BRIGHTNESS: - dev->channels[chan_num].ctl_bright = ctl->value; - medusa_set_brightness(dev, ctl->value, chan_num); - break; - case V4L2_CID_HUE: - dev->channels[chan_num].ctl_hue = ctl->value; - medusa_set_hue(dev, ctl->value, chan_num); - break; - case V4L2_CID_CONTRAST: - dev->channels[chan_num].ctl_contrast = ctl->value; - medusa_set_contrast(dev, ctl->value, chan_num); - break; - case V4L2_CID_SATURATION: - dev->channels[chan_num].ctl_saturation = ctl->value; - medusa_set_saturation(dev, ctl->value, chan_num); - break; - } - - err = 0; - - return err; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - int err; - - if (fh) { - err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, - fh->prio); - if (0 != err) - return err; - } - - return cx25821_set_control(dev, ctl, fh->channel_id); -} - -static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num) -{ - struct v4l2_control ctrl; - int i; - for (i = 0; i < CX25821_CTLS; i++) { - ctrl.id = cx25821_ctls[i].id; - ctrl.value = cx25821_ctls[i].default_value; - - cx25821_set_control(dev, &ctrl, chan_num); + return -EINVAL; } + return 0; } static long video_ioctl_upstream9(struct file *file, unsigned int cmd, @@ -1629,7 +1466,10 @@ static long cx25821_video_ioctl(struct file *file, return video_ioctl2(file, cmd, arg); } -/* exported stuff */ +static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { + .s_ctrl = cx25821_s_ctrl, +}; + static const struct v4l2_file_operations video_fops = { .owner = THIS_MODULE, .open = video_open, @@ -1655,9 +1495,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_enum_input = cx25821_vidioc_enum_input, .vidioc_g_input = cx25821_vidioc_g_input, .vidioc_s_input = cx25821_vidioc_s_input, - .vidioc_g_ctrl = cx25821_vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_queryctrl = cx25821_vidioc_queryctrl, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_log_status = vidioc_log_status, @@ -1684,6 +1521,7 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) if (video_is_registered(&dev->channels[chan_num].vdev)) { video_unregister_device(&dev->channels[chan_num].vdev); + v4l2_ctrl_handler_free(&dev->channels[chan_num].hdl); btcx_riscmem_free(dev->pci, &dev->channels[chan_num].vidq.stopper); @@ -1699,11 +1537,24 @@ int cx25821_video_register(struct cx25821_dev *dev) for (i = 0; i < VID_CHANNEL_NUM; ++i) { struct video_device *vdev = &dev->channels[i].vdev; + struct v4l2_ctrl_handler *hdl = &dev->channels[i].hdl; if (i == SRAM_CH08) /* audio channel */ continue; - cx25821_init_controls(dev, i); + v4l2_ctrl_handler_init(hdl, 4); + v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200); + v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, + V4L2_CID_CONTRAST, 0, 10000, 1, 5000); + v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, + V4L2_CID_SATURATION, 0, 10000, 1, 5000); + v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, + V4L2_CID_HUE, 0, 10000, 1, 5000); + if (hdl->error) { + err = hdl->error; + goto fail_unreg; + } cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, dev->channels[i].sram_channels->dma_ctl, 0x11, 0); @@ -1727,6 +1578,7 @@ int cx25821_video_register(struct cx25821_dev *dev) /* register v4l devices */ *vdev = cx25821_video_device; vdev->v4l2_dev = &dev->v4l2_dev; + vdev->ctrl_handler = hdl; snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); video_set_drvdata(vdev, dev); diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index df2ea22563e..c63f7f57161 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -33,6 +33,7 @@ #include #include +#include #include #include "btcx-risc.h" @@ -208,13 +209,14 @@ struct cx25821_data { const struct sram_channel *channel; }; +struct cx25821_dev; + struct cx25821_channel { + unsigned id; + struct cx25821_dev *dev; struct v4l2_prio_state prio; - int ctl_bright; - int ctl_contrast; - int ctl_hue; - int ctl_saturation; + struct v4l2_ctrl_handler hdl; struct cx25821_data timeout_data; struct video_device vdev; -- cgit v1.2.3-70-g09d2 From bad1f29d0f98972665e6503a286d058125212aa5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 11:13:43 -0300 Subject: [media] cx25821: remove TRUE/FALSE/STATUS_(UN)SUCCESSFUL defines Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-core.c | 2 +- drivers/media/pci/cx25821/cx25821-medusa-video.c | 2 +- drivers/media/pci/cx25821/cx25821.h | 5 ----- 3 files changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index bf6c1812dd8..ba417c97841 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -814,7 +814,7 @@ static void cx25821_initialize(struct cx25821_dev *dev) cx25821_sram_channel_setup(dev, dev->channels[i].sram_channels, 1440, 0); dev->channels[i].pixel_formats = PIXEL_FRMT_422; - dev->channels[i].use_cif_resolution = FALSE; + dev->channels[i].use_cif_resolution = 0; } /* Probably only affect Downstream */ diff --git a/drivers/media/pci/cx25821/cx25821-medusa-video.c b/drivers/media/pci/cx25821/cx25821-medusa-video.c index 6a92e5c70c2..6ab3ae08348 100644 --- a/drivers/media/pci/cx25821/cx25821-medusa-video.c +++ b/drivers/media/pci/cx25821/cx25821-medusa-video.c @@ -404,7 +404,7 @@ static int medusa_initialize_pal(struct cx25821_dev *dev) int medusa_set_videostandard(struct cx25821_dev *dev) { - int status = STATUS_SUCCESS; + int status = 0; u32 value = 0, tmp = 0; if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index c63f7f57161..95dbf70d866 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -52,8 +52,6 @@ #define CX25821_MAXBOARDS 2 -#define TRUE 1 -#define FALSE 0 #define LINE_SIZE_D1 1440 /* Number of decoders and encoders */ @@ -456,9 +454,6 @@ struct sram_channel { extern const struct sram_channel cx25821_sram_channels[]; -#define STATUS_SUCCESS 0 -#define STATUS_UNSUCCESSFUL -1 - #define cx_read(reg) readl(dev->lmmio + ((reg)>>2)) #define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2)) -- cgit v1.2.3-70-g09d2 From b6f8727e9f4cff765de2b24e82c1b2cfc1a74a86 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 08:44:56 -0300 Subject: [media] cx25821: remove unnecessary debug messages The v4l2 core already has support for debugging ioctls/file operations. No need to do that again. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 0c11f314c62..6088ee996b9 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -633,9 +633,6 @@ static int video_open(struct file *file) u32 pix_format; int ch_id; - dprintk(1, "open dev=%s type=%s\n", video_device_node_name(vdev), - v4l2_type_names[type]); - for (ch_id = 0; ch_id < MAX_VID_CHANNEL_NUM - 1; ch_id++) if (&dev->channels[ch_id].vdev == vdev) break; @@ -922,7 +919,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return err; } - dprintk(2, "%s()\n", __func__); err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f); if (0 != err) @@ -956,8 +952,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, dev->channels[fh->channel_id].cif_width = fh->width; medusa_set_resolution(dev, fh->width, SRAM_CH00); - dprintk(2, "%s(): width=%d height=%d field=%d\n", __func__, fh->width, - fh->height, fh->vidq.field); v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt); @@ -1079,8 +1073,6 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; int err; - dprintk(1, "%s()\n", __func__); - if (fh) { err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, fh->prio); @@ -1110,7 +1102,6 @@ static int cx25821_vidioc_enum_input(struct file *file, void *priv, }; struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; unsigned int n; - dprintk(1, "%s()\n", __func__); n = i->index; if (n >= CX25821_NR_INPUT) @@ -1131,7 +1122,6 @@ static int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; *i = dev->input; - dprintk(1, "%s(): returns %d\n", __func__, *i); return 0; } @@ -1141,8 +1131,6 @@ static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; int err; - dprintk(1, "%s(%d)\n", __func__, i); - if (fh) { err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, fh->prio); -- cgit v1.2.3-70-g09d2 From be178cb4f41f70e29108ce4eb5a8a77a62f1922f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 11:53:35 -0300 Subject: [media] cx25821: use core locking This allows us to replace .ioctl with .unlocked_ioctl. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-medusa-video.c | 44 --------------- drivers/media/pci/cx25821/cx25821-video.c | 72 +++++++++--------------- drivers/media/pci/cx25821/cx25821-video.h | 6 -- drivers/media/pci/cx25821/cx25821.h | 1 - 4 files changed, 27 insertions(+), 96 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-medusa-video.c b/drivers/media/pci/cx25821/cx25821-medusa-video.c index 6ab3ae08348..22fa04415cc 100644 --- a/drivers/media/pci/cx25821/cx25821-medusa-video.c +++ b/drivers/media/pci/cx25821/cx25821-medusa-video.c @@ -94,8 +94,6 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev) u32 value = 0; u32 tmp = 0; - mutex_lock(&dev->lock); - for (i = 0; i < MAX_DECODERS; i++) { /* set video format NTSC-M */ value = cx25821_i2c_read(&dev->i2c_bus[0], @@ -222,8 +220,6 @@ static int medusa_initialize_ntsc(struct cx25821_dev *dev) value |= 0x00080200; ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); - mutex_unlock(&dev->lock); - return ret_val; } @@ -265,8 +261,6 @@ static int medusa_initialize_pal(struct cx25821_dev *dev) u32 value = 0; u32 tmp = 0; - mutex_lock(&dev->lock); - for (i = 0; i < MAX_DECODERS; i++) { /* set video format PAL-BDGHI */ value = cx25821_i2c_read(&dev->i2c_bus[0], @@ -397,8 +391,6 @@ static int medusa_initialize_pal(struct cx25821_dev *dev) value &= 0xFFF7FDFF; ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); - mutex_unlock(&dev->lock); - return ret_val; } @@ -434,8 +426,6 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width, u32 vscale = 0x0; const int MAX_WIDTH = 720; - mutex_lock(&dev->lock); - /* validate the width */ if (width > MAX_WIDTH) { pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n", @@ -485,8 +475,6 @@ void medusa_set_resolution(struct cx25821_dev *dev, int width, cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL + (0x200 * decoder), vscale); } - - mutex_unlock(&dev->lock); } static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, @@ -496,11 +484,8 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, u32 tmp = 0; u32 disp_cnt_reg = DISP_AB_CNT; - mutex_lock(&dev->lock); - /* no support */ if (decoder < VDEC_A || decoder > VDEC_H) { - mutex_unlock(&dev->lock); return; } @@ -535,8 +520,6 @@ static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, } cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt); - - mutex_unlock(&dev->lock); } /* Map to Medusa register setting */ @@ -587,10 +570,8 @@ int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder) int value = 0; u32 val = 0, tmp = 0; - mutex_lock(&dev->lock); if ((brightness > VIDEO_PROCAMP_MAX) || (brightness < VIDEO_PROCAMP_MIN)) { - mutex_unlock(&dev->lock); return -1; } ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, @@ -601,7 +582,6 @@ int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder) val &= 0xFFFFFF00; ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value); - mutex_unlock(&dev->lock); return ret_val; } @@ -611,10 +591,7 @@ int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder) int value = 0; u32 val = 0, tmp = 0; - mutex_lock(&dev->lock); - if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) { - mutex_unlock(&dev->lock); return -1; } @@ -626,7 +603,6 @@ int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder) ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value); - mutex_unlock(&dev->lock); return ret_val; } @@ -636,10 +612,7 @@ int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder) int value = 0; u32 val = 0, tmp = 0; - mutex_lock(&dev->lock); - if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) { - mutex_unlock(&dev->lock); return -1; } @@ -654,7 +627,6 @@ int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder) ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_HUE_CTRL + (0x200 * decoder), val | value); - mutex_unlock(&dev->lock); return ret_val; } @@ -664,11 +636,8 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder) int value = 0; u32 val = 0, tmp = 0; - mutex_lock(&dev->lock); - if ((saturation > VIDEO_PROCAMP_MAX) || (saturation < VIDEO_PROCAMP_MIN)) { - mutex_unlock(&dev->lock); return -1; } @@ -687,7 +656,6 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder) ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value); - mutex_unlock(&dev->lock); return ret_val; } @@ -699,8 +667,6 @@ int medusa_video_init(struct cx25821_dev *dev) int ret_val = 0; int i = 0; - mutex_lock(&dev->lock); - _num_decoders = dev->_max_num_decoders; /* disable Auto source selection on all video decoders */ @@ -719,13 +685,9 @@ int medusa_video_init(struct cx25821_dev *dev) if (ret_val < 0) goto error; - mutex_unlock(&dev->lock); - for (i = 0; i < _num_decoders; i++) medusa_set_decoderduration(dev, i, _display_field_cnt[i]); - mutex_lock(&dev->lock); - /* Select monitor as DENC A input, power up the DAC */ value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp); value &= 0xFF70FF70; @@ -774,14 +736,8 @@ int medusa_video_init(struct cx25821_dev *dev) if (ret_val < 0) goto error; - - mutex_unlock(&dev->lock); - ret_val = medusa_set_videostandard(dev); - return ret_val; - error: - mutex_unlock(&dev->lock); return ret_val; } diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 6088ee996b9..ab79bd5e5f6 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -144,27 +144,8 @@ static int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) return 0; } -/* -static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl) -{ - int i; - - if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1) - return -EINVAL; - for (i = 0; i < CX25821_CTLS; i++) - if (cx25821_ctls[i].v.id == qctrl->id) - break; - if (i == CX25821_CTLS) { - *qctrl = no_ctl; - return 0; - } - *qctrl = cx25821_ctls[i].v; - return 0; -} -*/ - /* resource management */ -int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, +static int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit) { dprintk(1, "%s()\n", __func__); @@ -173,41 +154,36 @@ int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, return 1; /* is it free? */ - mutex_lock(&dev->lock); if (dev->channels[fh->channel_id].resources & bit) { /* no, someone else uses it */ - mutex_unlock(&dev->lock); return 0; } /* it's free, grab it */ fh->resources |= bit; dev->channels[fh->channel_id].resources |= bit; dprintk(1, "res: get %d\n", bit); - mutex_unlock(&dev->lock); return 1; } -int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit) +static int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit) { return fh->resources & bit; } -int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit) +static int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit) { return fh->dev->channels[fh->channel_id].resources & bit; } -void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, +static void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits) { BUG_ON((fh->resources & bits) != bits); dprintk(1, "%s()\n", __func__); - mutex_lock(&dev->lock); fh->resources &= ~bits; dev->channels[fh->channel_id].resources &= ~bits; dprintk(1, "res: put %d\n", bits); - mutex_unlock(&dev->lock); } static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) @@ -669,7 +645,7 @@ static int video_open(struct file *file) videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), - fh, NULL); + fh, &dev->lock); dprintk(1, "post videobuf_queue_init()\n"); @@ -680,19 +656,25 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count, loff_t *ppos) { struct cx25821_fh *fh = file->private_data; + struct cx25821_dev *dev = fh->dev; + int err; switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; if (cx25821_res_locked(fh, RESOURCE_VIDEO0)) - return -EBUSY; - - return videobuf_read_one(&fh->vidq, data, count, ppos, + err = -EBUSY; + else + err = videobuf_read_one(&fh->vidq, data, count, ppos, file->f_flags & O_NONBLOCK); + mutex_unlock(&dev->lock); + return err; default: - BUG(); - return 0; + return -ENODEV; } + } static unsigned int video_poll(struct file *file, @@ -742,6 +724,7 @@ static int video_release(struct file *file) const struct sram_channel *sram_ch = dev->channels[0].sram_channels; + mutex_lock(&dev->lock); /* stop the risc engine and fifo */ cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */ @@ -750,6 +733,7 @@ static int video_release(struct file *file) videobuf_queue_cancel(&fh->vidq); cx25821_res_free(dev, fh, RESOURCE_VIDEO0); } + mutex_unlock(&dev->lock); if (fh->vidq.read_buf) { cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf); @@ -1083,9 +1067,7 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) if (dev->tvnorm == tvnorms) return 0; - mutex_lock(&dev->lock); cx25821_set_tvnorm(dev, tvnorms); - mutex_unlock(&dev->lock); medusa_set_videostandard(dev); @@ -1141,9 +1123,7 @@ static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) if (i >= CX25821_NR_INPUT || INPUT(i)->type == 0) return -EINVAL; - mutex_lock(&dev->lock); cx25821_video_mux(dev, i); - mutex_unlock(&dev->lock); return 0; } @@ -1465,7 +1445,7 @@ static const struct v4l2_file_operations video_fops = { .read = video_read, .poll = video_poll, .mmap = cx25821_video_mmap, - .ioctl = cx25821_video_ioctl, + .unlocked_ioctl = cx25821_video_ioctl, }; static const struct v4l2_ioctl_ops video_ioctl_ops = { @@ -1521,6 +1501,10 @@ int cx25821_video_register(struct cx25821_dev *dev) int err; int i; + /* initial device configuration */ + dev->tvnorm = V4L2_STD_NTSC_M, + cx25821_set_tvnorm(dev, dev->tvnorm); + spin_lock_init(&dev->slock); for (i = 0; i < VID_CHANNEL_NUM; ++i) { @@ -1543,6 +1527,9 @@ int cx25821_video_register(struct cx25821_dev *dev) err = hdl->error; goto fail_unreg; } + err = v4l2_ctrl_handler_setup(hdl); + if (err) + goto fail_unreg; cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, dev->channels[i].sram_channels->dma_ctl, 0x11, 0); @@ -1567,6 +1554,7 @@ int cx25821_video_register(struct cx25821_dev *dev) *vdev = cx25821_video_device; vdev->v4l2_dev = &dev->v4l2_dev; vdev->ctrl_handler = hdl; + vdev->lock = &dev->lock; snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); video_set_drvdata(vdev, dev); @@ -1580,12 +1568,6 @@ int cx25821_video_register(struct cx25821_dev *dev) /* set PCI interrupt */ cx_set(PCI_INT_MSK, 0xff); - /* initial device configuration */ - mutex_lock(&dev->lock); - dev->tvnorm = V4L2_STD_NTSC_M, - cx25821_set_tvnorm(dev, dev->tvnorm); - mutex_unlock(&dev->lock); - return 0; fail_unreg: diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index 9d70020d925..b0f0d539549 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h @@ -67,12 +67,6 @@ do { \ extern void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, u32 count); -extern int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, - unsigned int bit); -extern int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit); -extern int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit); -extern void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, - unsigned int bits); extern int cx25821_start_video_dma(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, struct cx25821_buffer *buf, diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 95dbf70d866..ad56232154e 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -222,7 +222,6 @@ struct cx25821_channel { const struct sram_channel *sram_channels; - struct mutex lock; int resources; int pixel_formats; -- cgit v1.2.3-70-g09d2 From 11f095aa4154d27bdb15909b12a9d3922ab55cde Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 11:54:56 -0300 Subject: [media] cx25821: remove 'type' field from cx25821_fh Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 56 +++++++++---------------------- drivers/media/pci/cx25821/cx25821.h | 1 - 2 files changed, 15 insertions(+), 42 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index ab79bd5e5f6..2aba24f2a3d 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -506,24 +506,12 @@ static void cx25821_buffer_release(struct videobuf_queue *q, static struct videobuf_queue *get_queue(struct cx25821_fh *fh) { - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return &fh->vidq; - default: - BUG(); - return NULL; - } + return &fh->vidq; } static int cx25821_get_resource(struct cx25821_fh *fh, int resource) { - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return resource; - default: - BUG(); - return 0; - } + return resource; } static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) @@ -605,7 +593,6 @@ static int video_open(struct file *file) struct video_device *vdev = video_devdata(file); struct cx25821_dev *dev = video_drvdata(file); struct cx25821_fh *fh; - enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; u32 pix_format; int ch_id; @@ -624,7 +611,6 @@ static int video_open(struct file *file) file->private_data = fh; fh->dev = dev; - fh->type = type; fh->width = 720; fh->channel_id = ch_id; @@ -659,22 +645,15 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count, struct cx25821_dev *dev = fh->dev; int err; - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (mutex_lock_interruptible(&dev->lock)) - return -ERESTARTSYS; - if (cx25821_res_locked(fh, RESOURCE_VIDEO0)) - err = -EBUSY; - else - err = videobuf_read_one(&fh->vidq, data, count, ppos, - file->f_flags & O_NONBLOCK); - mutex_unlock(&dev->lock); - return err; - - default: - return -ENODEV; - } - + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; + if (cx25821_res_locked(fh, RESOURCE_VIDEO0)) + err = -EBUSY; + else + err = videobuf_read_one(&fh->vidq, data, count, ppos, + file->f_flags & O_NONBLOCK); + mutex_unlock(&dev->lock); + return err; } static unsigned int video_poll(struct file *file, @@ -818,14 +797,11 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) struct cx25821_fh *fh = priv; struct cx25821_dev *dev = fh->dev; - if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) - return -EINVAL; - - if (unlikely(i != fh->type)) + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, - RESOURCE_VIDEO0)))) + if (!cx25821_res_get(dev, fh, + cx25821_get_resource(fh, RESOURCE_VIDEO0))) return -EBUSY; return videobuf_streamon(get_queue(fh)); @@ -837,9 +813,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) struct cx25821_dev *dev = fh->dev; int err, res; - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (i != fh->type) + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; res = cx25821_get_resource(fh, RESOURCE_VIDEO0); diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index ad56232154e..d1c91c9e911 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -118,7 +118,6 @@ struct cx25821_tvnorm { struct cx25821_fh { struct cx25821_dev *dev; - enum v4l2_buf_type type; u32 resources; enum v4l2_priority prio; -- cgit v1.2.3-70-g09d2 From 2efe2cc4305ad9a8ea4db5881808c4db1c451091 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 10:00:52 -0300 Subject: [media] cx25821: move vidq from cx25821_fh to cx25821_channel This is not a per-filehandle object, it's a per-channel object. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 235 ++++++++++++++---------------- drivers/media/pci/cx25821/cx25821.h | 8 +- 2 files changed, 115 insertions(+), 128 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 2aba24f2a3d..d88316c5f5d 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -288,7 +288,7 @@ static void cx25821_vid_timeout(unsigned long data) struct cx25821_data *timeout_data = (struct cx25821_data *)data; struct cx25821_dev *dev = timeout_data->dev; const struct sram_channel *channel = timeout_data->channel; - struct cx25821_dmaqueue *q = &dev->channels[channel->i].vidq; + struct cx25821_dmaqueue *q = &dev->channels[channel->i].dma_vidq; struct cx25821_buffer *buf; unsigned long flags; @@ -334,7 +334,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) if (status & FLD_VID_DST_RISC1) { spin_lock(&dev->slock); count = cx_read(channel->gpcnt); - cx25821_video_wakeup(dev, &dev->channels[channel->i].vidq, + cx25821_video_wakeup(dev, &dev->channels[channel->i].dma_vidq, count); spin_unlock(&dev->slock); handled++; @@ -345,7 +345,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) dprintk(2, "stopper video\n"); spin_lock(&dev->slock); cx25821_restart_video_queue(dev, - &dev->channels[channel->i].vidq, channel); + &dev->channels[channel->i].dma_vidq, channel); spin_unlock(&dev->slock); handled++; } @@ -355,9 +355,9 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status) static int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) { - struct cx25821_fh *fh = q->priv_data; + struct cx25821_channel *chan = q->priv_data; - *size = fh->fmt->depth * fh->width * fh->height >> 3; + *size = chan->fmt->depth * chan->width * chan->height >> 3; if (0 == *count) *count = 32; @@ -371,32 +371,32 @@ static int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count, static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { - struct cx25821_fh *fh = q->priv_data; - struct cx25821_dev *dev = fh->dev; + struct cx25821_channel *chan = q->priv_data; + struct cx25821_dev *dev = chan->dev; struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb); int rc, init_buffer = 0; u32 line0_offset; struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); int bpl_local = LINE_SIZE_D1; - int channel_opened = fh->channel_id; + int channel_opened = chan->id; - BUG_ON(NULL == fh->fmt); - if (fh->width < 48 || fh->width > 720 || - fh->height < 32 || fh->height > 576) + BUG_ON(NULL == chan->fmt); + if (chan->width < 48 || chan->width > 720 || + chan->height < 32 || chan->height > 576) return -EINVAL; - buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; + buf->vb.size = (chan->width * chan->height * chan->fmt->depth) >> 3; if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) return -EINVAL; - if (buf->fmt != fh->fmt || - buf->vb.width != fh->width || - buf->vb.height != fh->height || buf->vb.field != field) { - buf->fmt = fh->fmt; - buf->vb.width = fh->width; - buf->vb.height = fh->height; + if (buf->fmt != chan->fmt || + buf->vb.width != chan->width || + buf->vb.height != chan->height || buf->vb.field != field) { + buf->fmt = chan->fmt; + buf->vb.width = chan->width; + buf->vb.height = chan->height; buf->vb.field = field; init_buffer = 1; } @@ -413,7 +413,6 @@ static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buff dprintk(1, "init_buffer=%d\n", init_buffer); if (init_buffer) { - channel_opened = dev->channel_opened; if (channel_opened < 0 || channel_opened > 7) channel_opened = 7; @@ -483,8 +482,8 @@ static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buff } dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", - buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth, - fh->fmt->name, (unsigned long)buf->risc.dma); + buf, buf->vb.i, chan->width, chan->height, chan->fmt->depth, + chan->fmt->name, (unsigned long)buf->risc.dma); buf->vb.state = VIDEOBUF_PREPARED; @@ -504,11 +503,6 @@ static void cx25821_buffer_release(struct videobuf_queue *q, cx25821_free_buffer(q, buf); } -static struct videobuf_queue *get_queue(struct cx25821_fh *fh) -{ - return &fh->vidq; -} - static int cx25821_get_resource(struct cx25821_fh *fh, int resource) { return resource; @@ -516,9 +510,9 @@ static int cx25821_get_resource(struct cx25821_fh *fh, int resource) static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) { - struct cx25821_fh *fh = file->private_data; + struct cx25821_channel *chan = video_drvdata(file); - return videobuf_mmap_mapper(get_queue(fh), vma); + return videobuf_mmap_mapper(&chan->vidq, vma); } @@ -527,9 +521,9 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) struct cx25821_buffer *buf = container_of(vb, struct cx25821_buffer, vb); struct cx25821_buffer *prev; - struct cx25821_fh *fh = vq->priv_data; - struct cx25821_dev *dev = fh->dev; - struct cx25821_dmaqueue *q = &dev->channels[fh->channel_id].vidq; + struct cx25821_channel *chan = vq->priv_data; + struct cx25821_dev *dev = chan->dev; + struct cx25821_dmaqueue *q = &dev->channels[chan->id].dma_vidq; /* add jump to stopper */ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); @@ -546,8 +540,7 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) } else if (list_empty(&q->active)) { list_add_tail(&buf->vb.queue, &q->active); - cx25821_start_video_dma(dev, q, buf, - dev->channels[fh->channel_id].sram_channels); + cx25821_start_video_dma(dev, q, buf, chan->sram_channels); buf->vb.state = VIDEOBUF_ACTIVE; buf->count = q->count++; mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); @@ -590,19 +583,9 @@ static struct videobuf_queue_ops cx25821_video_qops = { static int video_open(struct file *file) { - struct video_device *vdev = video_devdata(file); - struct cx25821_dev *dev = video_drvdata(file); + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; struct cx25821_fh *fh; - u32 pix_format; - int ch_id; - - for (ch_id = 0; ch_id < MAX_VID_CHANNEL_NUM - 1; ch_id++) - if (&dev->channels[ch_id].vdev == vdev) - break; - - /* Can't happen */ - if (ch_id >= MAX_VID_CHANNEL_NUM - 1) - return -ENODEV; /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); @@ -611,27 +594,11 @@ static int video_open(struct file *file) file->private_data = fh; fh->dev = dev; - fh->width = 720; - fh->channel_id = ch_id; - - if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) - fh->height = 576; - else - fh->height = 480; + fh->channel_id = chan->id; dev->channel_opened = fh->channel_id; - if (dev->channels[ch_id].pixel_formats == PIXEL_FRMT_411) - pix_format = V4L2_PIX_FMT_Y41P; - else - pix_format = V4L2_PIX_FMT_YUYV; - fh->fmt = cx25821_format_by_fourcc(pix_format); - - v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); - videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev, - &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), - fh, &dev->lock); + v4l2_prio_open(&chan->prio, &fh->prio); dprintk(1, "post videobuf_queue_init()\n"); @@ -642,6 +609,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count, loff_t *ppos) { struct cx25821_fh *fh = file->private_data; + struct cx25821_channel *chan = video_drvdata(file); struct cx25821_dev *dev = fh->dev; int err; @@ -650,7 +618,7 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count, if (cx25821_res_locked(fh, RESOURCE_VIDEO0)) err = -EBUSY; else - err = videobuf_read_one(&fh->vidq, data, count, ppos, + err = videobuf_read_one(&chan->vidq, data, count, ppos, file->f_flags & O_NONBLOCK); mutex_unlock(&dev->lock); return err; @@ -660,17 +628,18 @@ static unsigned int video_poll(struct file *file, struct poll_table_struct *wait) { struct cx25821_fh *fh = file->private_data; + struct cx25821_channel *chan = video_drvdata(file); struct cx25821_buffer *buf; if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { /* streaming capture */ - if (list_empty(&fh->vidq.stream)) + if (list_empty(&chan->vidq.stream)) return POLLERR; - buf = list_entry(fh->vidq.stream.next, + buf = list_entry(chan->vidq.stream.next, struct cx25821_buffer, vb.stream); } else { /* read() capture */ - buf = (struct cx25821_buffer *)fh->vidq.read_buf; + buf = (struct cx25821_buffer *)chan->vidq.read_buf; if (NULL == buf) return POLLERR; } @@ -680,12 +649,11 @@ static unsigned int video_poll(struct file *file, if (buf->vb.state == VIDEOBUF_DONE) { struct cx25821_dev *dev = fh->dev; - if (dev && dev->channels[fh->channel_id] - .use_cif_resolution) { + if (dev && chan->use_cif_resolution) { u8 cam_id = *((char *)buf->vb.baddr + 3); memcpy((char *)buf->vb.baddr, - (char *)buf->vb.baddr + (fh->width * 2), - (fh->width * 2)); + (char *)buf->vb.baddr + (chan->width * 2), + (chan->width * 2)); *((char *)buf->vb.baddr + 3) = cam_id; } } @@ -698,8 +666,9 @@ static unsigned int video_poll(struct file *file, static int video_release(struct file *file) { + struct cx25821_channel *chan = video_drvdata(file); struct cx25821_fh *fh = file->private_data; - struct cx25821_dev *dev = fh->dev; + struct cx25821_dev *dev = chan->dev; const struct sram_channel *sram_ch = dev->channels[0].sram_channels; @@ -709,19 +678,19 @@ static int video_release(struct file *file) /* stop video capture */ if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { - videobuf_queue_cancel(&fh->vidq); + videobuf_queue_cancel(&chan->vidq); cx25821_res_free(dev, fh, RESOURCE_VIDEO0); } mutex_unlock(&dev->lock); - if (fh->vidq.read_buf) { - cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf); - kfree(fh->vidq.read_buf); + if (chan->vidq.read_buf) { + cx25821_buffer_release(&chan->vidq, chan->vidq.read_buf); + kfree(chan->vidq.read_buf); } - videobuf_mmap_free(&fh->vidq); + videobuf_mmap_free(&chan->vidq); - v4l2_prio_close(&dev->channels[fh->channel_id].prio, fh->prio); + v4l2_prio_close(&chan->prio, fh->prio); file->private_data = NULL; kfree(fh); @@ -732,13 +701,13 @@ static int video_release(struct file *file) static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx25821_fh *fh = priv; + struct cx25821_channel *chan = video_drvdata(file); - f->fmt.pix.width = fh->width; - f->fmt.pix.height = fh->height; - f->fmt.pix.field = fh->vidq.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3; + f->fmt.pix.width = chan->width; + f->fmt.pix.height = chan->height; + f->fmt.pix.field = chan->vidq.field; + f->fmt.pix.pixelformat = chan->fmt->fourcc; + f->fmt.pix.bytesperline = (f->fmt.pix.width * chan->fmt->depth) >> 3; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; return 0; @@ -794,6 +763,7 @@ static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, } static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { + struct cx25821_channel *chan = video_drvdata(file); struct cx25821_fh *fh = priv; struct cx25821_dev *dev = fh->dev; @@ -804,11 +774,12 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) cx25821_get_resource(fh, RESOURCE_VIDEO0))) return -EBUSY; - return videobuf_streamon(get_queue(fh)); + return videobuf_streamon(&chan->vidq); } static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) { + struct cx25821_channel *chan = video_drvdata(file); struct cx25821_fh *fh = priv; struct cx25821_dev *dev = fh->dev; int err, res; @@ -817,7 +788,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) return -EINVAL; res = cx25821_get_resource(fh, RESOURCE_VIDEO0); - err = videobuf_streamoff(get_queue(fh)); + err = videobuf_streamoff(&chan->vidq); if (err < 0) return err; cx25821_res_free(dev, fh, res); @@ -865,6 +836,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx25821_fh *fh = priv; + struct cx25821_channel *chan = video_drvdata(file); struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; struct v4l2_mbus_framefmt mbus_fmt; int err; @@ -882,15 +854,15 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, if (0 != err) return err; - fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); - fh->vidq.field = f->fmt.pix.field; + chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); + chan->vidq.field = f->fmt.pix.field; /* check if width and height is valid based on set standard */ if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) - fh->width = f->fmt.pix.width; + chan->width = f->fmt.pix.width; if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) - fh->height = f->fmt.pix.height; + chan->height = f->fmt.pix.height; if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P) pix_format = PIXEL_FRMT_411; @@ -902,13 +874,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, cx25821_set_pixel_format(dev, SRAM_CH00, pix_format); /* check if cif resolution */ - if (fh->width == 320 || fh->width == 352) - dev->channels[fh->channel_id].use_cif_resolution = 1; + if (chan->width == 320 || chan->width == 352) + chan->use_cif_resolution = 1; else - dev->channels[fh->channel_id].use_cif_resolution = 0; + chan->use_cif_resolution = 0; - dev->channels[fh->channel_id].cif_width = fh->width; - medusa_set_resolution(dev, fh->width, SRAM_CH00); + chan->cif_width = chan->width; + medusa_set_resolution(dev, chan->width, SRAM_CH00); v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt); @@ -919,12 +891,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) { int ret_val = 0; - struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; + struct cx25821_channel *chan = video_drvdata(file); - ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK); - - p->sequence = dev->channels[fh->channel_id].vidq.count; + ret_val = videobuf_dqbuf(&chan->vidq, p, file->f_flags & O_NONBLOCK); + p->sequence = chan->dma_vidq.count; return ret_val; } @@ -980,21 +950,24 @@ static int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, static int cx25821_vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { - struct cx25821_fh *fh = priv; - return videobuf_reqbufs(get_queue(fh), p); + struct cx25821_channel *chan = video_drvdata(file); + + return videobuf_reqbufs(&chan->vidq, p); } static int cx25821_vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) { - struct cx25821_fh *fh = priv; - return videobuf_querybuf(get_queue(fh), p); + struct cx25821_channel *chan = video_drvdata(file); + + return videobuf_querybuf(&chan->vidq, p); } static int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { - struct cx25821_fh *fh = priv; - return videobuf_qbuf(get_queue(fh), p); + struct cx25821_channel *chan = video_drvdata(file); + + return videobuf_qbuf(&chan->vidq, p); } static int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) @@ -1466,7 +1439,7 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) v4l2_ctrl_handler_free(&dev->channels[chan_num].hdl); btcx_riscmem_free(dev->pci, - &dev->channels[chan_num].vidq.stopper); + &dev->channels[chan_num].dma_vidq.stopper); } } @@ -1482,8 +1455,9 @@ int cx25821_video_register(struct cx25821_dev *dev) spin_lock_init(&dev->slock); for (i = 0; i < VID_CHANNEL_NUM; ++i) { - struct video_device *vdev = &dev->channels[i].vdev; - struct v4l2_ctrl_handler *hdl = &dev->channels[i].hdl; + struct cx25821_channel *chan = &dev->channels[i]; + struct video_device *vdev = &chan->vdev; + struct v4l2_ctrl_handler *hdl = &chan->hdl; if (i == SRAM_CH08) /* audio channel */ continue; @@ -1505,24 +1479,37 @@ int cx25821_video_register(struct cx25821_dev *dev) if (err) goto fail_unreg; - cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper, - dev->channels[i].sram_channels->dma_ctl, 0x11, 0); + cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper, + chan->sram_channels->dma_ctl, 0x11, 0); - dev->channels[i].sram_channels = &cx25821_sram_channels[i]; - dev->channels[i].resources = 0; + chan->sram_channels = &cx25821_sram_channels[i]; + chan->resources = 0; + chan->width = 720; + if (dev->tvnorm & V4L2_STD_625_50) + chan->height = 576; + else + chan->height = 480; - cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff); + if (chan->pixel_formats == PIXEL_FRMT_411) + chan->fmt = cx25821_format_by_fourcc(V4L2_PIX_FMT_Y41P); + else + chan->fmt = cx25821_format_by_fourcc(V4L2_PIX_FMT_YUYV); - INIT_LIST_HEAD(&dev->channels[i].vidq.active); - INIT_LIST_HEAD(&dev->channels[i].vidq.queued); + cx_write(chan->sram_channels->int_stat, 0xffffffff); - dev->channels[i].timeout_data.dev = dev; - dev->channels[i].timeout_data.channel = - &cx25821_sram_channels[i]; - dev->channels[i].vidq.timeout.function = cx25821_vid_timeout; - dev->channels[i].vidq.timeout.data = - (unsigned long)&dev->channels[i].timeout_data; - init_timer(&dev->channels[i].vidq.timeout); + INIT_LIST_HEAD(&chan->dma_vidq.active); + INIT_LIST_HEAD(&chan->dma_vidq.queued); + + chan->timeout_data.dev = dev; + chan->timeout_data.channel = &cx25821_sram_channels[i]; + chan->dma_vidq.timeout.function = cx25821_vid_timeout; + chan->dma_vidq.timeout.data = (unsigned long)&chan->timeout_data; + init_timer(&chan->dma_vidq.timeout); + + videobuf_queue_sg_init(&chan->vidq, &cx25821_video_qops, &dev->pci->dev, + &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), + chan, &dev->lock); /* register v4l devices */ *vdev = cx25821_video_device; @@ -1530,7 +1517,7 @@ int cx25821_video_register(struct cx25821_dev *dev) vdev->ctrl_handler = hdl; vdev->lock = &dev->lock; snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); - video_set_drvdata(vdev, dev); + video_set_drvdata(vdev, chan); err = video_register_device(vdev, VFL_TYPE_GRABBER, video_nr[dev->nr]); diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index d1c91c9e911..06dadb5d9e5 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -123,10 +123,7 @@ struct cx25821_fh { enum v4l2_priority prio; /* video capture */ - const struct cx25821_fmt *fmt; - unsigned int width, height; int channel_id; - struct videobuf_queue vidq; }; enum cx25821_itype { @@ -217,12 +214,15 @@ struct cx25821_channel { struct cx25821_data timeout_data; struct video_device vdev; - struct cx25821_dmaqueue vidq; + struct cx25821_dmaqueue dma_vidq; + struct videobuf_queue vidq; const struct sram_channel *sram_channels; int resources; + const struct cx25821_fmt *fmt; + unsigned int width, height; int pixel_formats; int use_cif_resolution; int cif_width; -- cgit v1.2.3-70-g09d2 From 84293f0843931b13d8331093bafacd1d70dd5efb Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 11:56:39 -0300 Subject: [media] cx25821: replace resource management functions with fh ownership Just remember which filehandle is streaming instead of using complicated resource masks. After this patch we can replace cx25821_fh with v4l2_fh. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 130 ++++++++---------------------- drivers/media/pci/cx25821/cx25821.h | 5 +- 2 files changed, 35 insertions(+), 100 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index d88316c5f5d..e7a2db158a0 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -144,48 +144,6 @@ static int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) return 0; } -/* resource management */ -static int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, - unsigned int bit) -{ - dprintk(1, "%s()\n", __func__); - if (fh->resources & bit) - /* have it already allocated */ - return 1; - - /* is it free? */ - if (dev->channels[fh->channel_id].resources & bit) { - /* no, someone else uses it */ - return 0; - } - /* it's free, grab it */ - fh->resources |= bit; - dev->channels[fh->channel_id].resources |= bit; - dprintk(1, "res: get %d\n", bit); - return 1; -} - -static int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit) -{ - return fh->resources & bit; -} - -static int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit) -{ - return fh->dev->channels[fh->channel_id].resources & bit; -} - -static void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, - unsigned int bits) -{ - BUG_ON((fh->resources & bits) != bits); - dprintk(1, "%s()\n", __func__); - - fh->resources &= ~bits; - dev->channels[fh->channel_id].resources &= ~bits; - dprintk(1, "res: put %d\n", bits); -} - static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) { struct v4l2_routing route; @@ -503,11 +461,6 @@ static void cx25821_buffer_release(struct videobuf_queue *q, cx25821_free_buffer(q, buf); } -static int cx25821_get_resource(struct cx25821_fh *fh, int resource) -{ - return resource; -} - static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma) { struct cx25821_channel *chan = video_drvdata(file); @@ -611,15 +564,19 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count, struct cx25821_fh *fh = file->private_data; struct cx25821_channel *chan = video_drvdata(file); struct cx25821_dev *dev = fh->dev; - int err; + int err = 0; if (mutex_lock_interruptible(&dev->lock)) return -ERESTARTSYS; - if (cx25821_res_locked(fh, RESOURCE_VIDEO0)) + if (chan->streaming_fh && chan->streaming_fh != fh) { err = -EBUSY; - else - err = videobuf_read_one(&chan->vidq, data, count, ppos, + goto unlock; + } + chan->streaming_fh = fh; + + err = videobuf_read_one(&chan->vidq, data, count, ppos, file->f_flags & O_NONBLOCK); +unlock: mutex_unlock(&dev->lock); return err; } @@ -627,41 +584,25 @@ static ssize_t video_read(struct file *file, char __user * data, size_t count, static unsigned int video_poll(struct file *file, struct poll_table_struct *wait) { - struct cx25821_fh *fh = file->private_data; struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_buffer *buf; - if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { - /* streaming capture */ - if (list_empty(&chan->vidq.stream)) - return POLLERR; - buf = list_entry(chan->vidq.stream.next, - struct cx25821_buffer, vb.stream); - } else { - /* read() capture */ - buf = (struct cx25821_buffer *)chan->vidq.read_buf; - if (NULL == buf) - return POLLERR; - } + return videobuf_poll_stream(file, &chan->vidq, wait); - poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) { - if (buf->vb.state == VIDEOBUF_DONE) { - struct cx25821_dev *dev = fh->dev; - - if (dev && chan->use_cif_resolution) { - u8 cam_id = *((char *)buf->vb.baddr + 3); - memcpy((char *)buf->vb.baddr, - (char *)buf->vb.baddr + (chan->width * 2), - (chan->width * 2)); - *((char *)buf->vb.baddr + 3) = cam_id; - } - } + /* This doesn't belong in poll(). This can be done + * much better with vb2. We keep this code here as a + * reminder. + if ((res & POLLIN) && buf->vb.state == VIDEOBUF_DONE) { + struct cx25821_dev *dev = chan->dev; - return POLLIN | POLLRDNORM; + if (dev && chan->use_cif_resolution) { + u8 cam_id = *((char *)buf->vb.baddr + 3); + memcpy((char *)buf->vb.baddr, + (char *)buf->vb.baddr + (chan->width * 2), + (chan->width * 2)); + *((char *)buf->vb.baddr + 3) = cam_id; + } } - - return 0; + */ } static int video_release(struct file *file) @@ -677,11 +618,10 @@ static int video_release(struct file *file) cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */ /* stop video capture */ - if (cx25821_res_check(fh, RESOURCE_VIDEO0)) { + if (chan->streaming_fh == fh) { videobuf_queue_cancel(&chan->vidq); - cx25821_res_free(dev, fh, RESOURCE_VIDEO0); + chan->streaming_fh = NULL; } - mutex_unlock(&dev->lock); if (chan->vidq.read_buf) { cx25821_buffer_release(&chan->vidq, chan->vidq.read_buf); @@ -689,6 +629,7 @@ static int video_release(struct file *file) } videobuf_mmap_free(&chan->vidq); + mutex_unlock(&dev->lock); v4l2_prio_close(&chan->prio, fh->prio); file->private_data = NULL; @@ -765,14 +706,13 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { struct cx25821_channel *chan = video_drvdata(file); struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = fh->dev; if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (!cx25821_res_get(dev, fh, - cx25821_get_resource(fh, RESOURCE_VIDEO0))) + if (chan->streaming_fh && chan->streaming_fh != fh) return -EBUSY; + chan->streaming_fh = fh; return videobuf_streamon(&chan->vidq); } @@ -781,18 +721,17 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) { struct cx25821_channel *chan = video_drvdata(file); struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = fh->dev; - int err, res; if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - res = cx25821_get_resource(fh, RESOURCE_VIDEO0); - err = videobuf_streamoff(&chan->vidq); - if (err < 0) - return err; - cx25821_res_free(dev, fh, res); - return 0; + if (chan->streaming_fh && chan->streaming_fh != fh) + return -EBUSY; + if (chan->streaming_fh == NULL) + return 0; + + chan->streaming_fh = NULL; + return videobuf_streamoff(&chan->vidq); } static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm) @@ -1483,7 +1422,6 @@ int cx25821_video_register(struct cx25821_dev *dev) chan->sram_channels->dma_ctl, 0x11, 0); chan->sram_channels = &cx25821_sram_channels[i]; - chan->resources = 0; chan->width = 720; if (dev->tvnorm & V4L2_STD_625_50) chan->height = 576; diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 06dadb5d9e5..128c9f320df 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -118,7 +118,6 @@ struct cx25821_tvnorm { struct cx25821_fh { struct cx25821_dev *dev; - u32 resources; enum v4l2_priority prio; @@ -208,6 +207,7 @@ struct cx25821_dev; struct cx25821_channel { unsigned id; struct cx25821_dev *dev; + struct cx25821_fh *streaming_fh; struct v4l2_prio_state prio; struct v4l2_ctrl_handler hdl; @@ -219,8 +219,6 @@ struct cx25821_channel { const struct sram_channel *sram_channels; - int resources; - const struct cx25821_fmt *fmt; unsigned int width, height; int pixel_formats; @@ -260,7 +258,6 @@ struct cx25821_dev { char name[32]; /* Analog video */ - u32 resources; unsigned int input; v4l2_std_id tvnorm; unsigned short _max_num_decoders; -- cgit v1.2.3-70-g09d2 From 8d125c507dee259d12299c9eb6e8d32ac1f8ae6d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 11:57:18 -0300 Subject: [media] cx25821: switch to v4l2_fh, add event and prio handling It is now possible to remove cx25821_fh and replace it with v4l2_fh, which in turn makes event handling and core prio handling possible. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 193 +++++++++--------------------- drivers/media/pci/cx25821/cx25821-video.h | 1 + drivers/media/pci/cx25821/cx25821.h | 13 +- 3 files changed, 59 insertions(+), 148 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index e7a2db158a0..f82da1e69e6 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -337,7 +337,6 @@ static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buff u32 line0_offset; struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); int bpl_local = LINE_SIZE_D1; - int channel_opened = chan->id; BUG_ON(NULL == chan->fmt); if (chan->width < 48 || chan->width > 720 || @@ -371,33 +370,22 @@ static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buff dprintk(1, "init_buffer=%d\n", init_buffer); if (init_buffer) { - channel_opened = dev->channel_opened; - if (channel_opened < 0 || channel_opened > 7) - channel_opened = 7; - - if (dev->channels[channel_opened].pixel_formats == - PIXEL_FRMT_411) + if (chan->pixel_formats == PIXEL_FRMT_411) buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3; else buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width); - if (dev->channels[channel_opened].pixel_formats == - PIXEL_FRMT_411) { + if (chan->pixel_formats == PIXEL_FRMT_411) { bpl_local = buf->bpl; } else { bpl_local = buf->bpl; /* Default */ - if (channel_opened >= 0 && channel_opened <= 7) { - if (dev->channels[channel_opened] - .use_cif_resolution) { - if (dev->tvnorm & V4L2_STD_PAL_BG || - dev->tvnorm & V4L2_STD_PAL_DK) - bpl_local = 352 << 1; - else - bpl_local = dev->channels[ - channel_opened]. - cif_width << 1; - } + if (chan->use_cif_resolution) { + if (dev->tvnorm & V4L2_STD_PAL_BG || + dev->tvnorm & V4L2_STD_PAL_DK) + bpl_local = 352 << 1; + else + bpl_local = chan->cif_width << 1; } } @@ -534,36 +522,12 @@ static struct videobuf_queue_ops cx25821_video_qops = { .buf_release = cx25821_buffer_release, }; -static int video_open(struct file *file) -{ - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - struct cx25821_fh *fh; - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) - return -ENOMEM; - - file->private_data = fh; - fh->dev = dev; - fh->channel_id = chan->id; - - dev->channel_opened = fh->channel_id; - - v4l2_prio_open(&chan->prio, &fh->prio); - - dprintk(1, "post videobuf_queue_init()\n"); - - return 0; -} - static ssize_t video_read(struct file *file, char __user * data, size_t count, loff_t *ppos) { - struct cx25821_fh *fh = file->private_data; + struct v4l2_fh *fh = file->private_data; struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = fh->dev; + struct cx25821_dev *dev = chan->dev; int err = 0; if (mutex_lock_interruptible(&dev->lock)) @@ -585,8 +549,12 @@ static unsigned int video_poll(struct file *file, struct poll_table_struct *wait) { struct cx25821_channel *chan = video_drvdata(file); + unsigned long req_events = poll_requested_events(wait); + unsigned int res = v4l2_ctrl_poll(file, wait); - return videobuf_poll_stream(file, &chan->vidq, wait); + if (req_events & (POLLIN | POLLRDNORM)) + res |= videobuf_poll_stream(file, &chan->vidq, wait); + return res; /* This doesn't belong in poll(). This can be done * much better with vb2. We keep this code here as a @@ -608,7 +576,7 @@ static unsigned int video_poll(struct file *file, static int video_release(struct file *file) { struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_fh *fh = file->private_data; + struct v4l2_fh *fh = file->private_data; struct cx25821_dev *dev = chan->dev; const struct sram_channel *sram_ch = dev->channels[0].sram_channels; @@ -631,11 +599,7 @@ static int video_release(struct file *file) videobuf_mmap_free(&chan->vidq); mutex_unlock(&dev->lock); - v4l2_prio_close(&chan->prio, fh->prio); - file->private_data = NULL; - kfree(fh); - - return 0; + return v4l2_fh_release(file); } /* VIDEO IOCTLS */ @@ -705,14 +669,13 @@ static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_fh *fh = priv; if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (chan->streaming_fh && chan->streaming_fh != fh) + if (chan->streaming_fh && chan->streaming_fh != priv) return -EBUSY; - chan->streaming_fh = fh; + chan->streaming_fh = priv; return videobuf_streamon(&chan->vidq); } @@ -720,12 +683,11 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) { struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_fh *fh = priv; if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (chan->streaming_fh && chan->streaming_fh != fh) + if (chan->streaming_fh && chan->streaming_fh != priv) return -EBUSY; if (chan->streaming_fh == NULL) return 0; @@ -774,20 +736,12 @@ static int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm) static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx25821_fh *fh = priv; struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; + struct cx25821_dev *dev = chan->dev; struct v4l2_mbus_framefmt mbus_fmt; int err; int pix_format = PIXEL_FRMT_422; - if (fh) { - err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, - fh->prio); - if (0 != err) - return err; - } - err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f); if (0 != err) @@ -840,10 +794,9 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) static int vidioc_log_status(struct file *file, void *priv) { - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - struct cx25821_fh *fh = priv; - const struct sram_channel *sram_ch = - dev->channels[fh->channel_id].sram_channels; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; + const struct sram_channel *sram_ch = chan->sram_channels; u32 tmp = 0; cx25821_call_all(dev, core, log_status); @@ -857,8 +810,8 @@ static int vidioc_log_status(struct file *file, void *priv) static int cx25821_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - struct cx25821_fh *fh = priv; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; const u32 cap_input = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT; @@ -866,7 +819,7 @@ static int cx25821_vidioc_querycap(struct file *file, void *priv, strcpy(cap->driver, "cx25821"); strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card)); sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); - if (fh->channel_id >= VID_CHANNEL_NUM) + if (chan->id >= VID_CHANNEL_NUM) cap->device_caps = cap_output; else cap->device_caps = cap_input; @@ -909,46 +862,18 @@ static int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer return videobuf_qbuf(&chan->vidq, p); } -static int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p) -{ - struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev; - struct cx25821_fh *fh = f; - - *p = v4l2_prio_max(&dev->channels[fh->channel_id].prio); - - return 0; -} - -static int cx25821_vidioc_s_priority(struct file *file, void *f, - enum v4l2_priority prio) -{ - struct cx25821_fh *fh = f; - struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev; - - return v4l2_prio_change(&dev->channels[fh->channel_id].prio, &fh->prio, - prio); -} - static int cx25821_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms) { - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; + struct cx25821_channel *chan = video_drvdata(file); - *tvnorms = dev->tvnorm; + *tvnorms = chan->dev->tvnorm; return 0; } int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) { - struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - int err; - - if (fh) { - err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, - fh->prio); - if (0 != err) - return err; - } + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; if (dev->tvnorm == tvnorms) return 0; @@ -968,7 +893,8 @@ static int cx25821_vidioc_enum_input(struct file *file, void *priv, [CX25821_VMUX_SVIDEO] = "S-Video", [CX25821_VMUX_DEBUG] = "for debug only", }; - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; unsigned int n; n = i->index; @@ -987,7 +913,8 @@ static int cx25821_vidioc_enum_input(struct file *file, void *priv, static int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i) { - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; *i = dev->input; return 0; @@ -995,16 +922,8 @@ static int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) { - struct cx25821_fh *fh = priv; - struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev; - int err; - - if (fh) { - err = v4l2_prio_check(&dev->channels[fh->channel_id].prio, - fh->prio); - if (0 != err) - return err; - } + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; if (i >= CX25821_NR_INPUT || INPUT(i)->type == 0) return -EINVAL; @@ -1017,7 +936,8 @@ static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) int cx25821_vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) { - struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; if (!v4l2_chip_match_host(®->match)) return -EINVAL; @@ -1030,7 +950,8 @@ int cx25821_vidioc_g_register(struct file *file, void *fh, int cx25821_vidioc_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg) { - struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; if (!v4l2_chip_match_host(®->match)) return -EINVAL; @@ -1070,8 +991,8 @@ static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl) static long video_ioctl_upstream9(struct file *file, unsigned int cmd, unsigned long arg) { - struct cx25821_fh *fh = file->private_data; - struct cx25821_dev *dev = fh->dev; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; int command = 0; struct upstream_user_struct *data_from_user; @@ -1110,8 +1031,8 @@ static long video_ioctl_upstream9(struct file *file, unsigned int cmd, static long video_ioctl_upstream10(struct file *file, unsigned int cmd, unsigned long arg) { - struct cx25821_fh *fh = file->private_data; - struct cx25821_dev *dev = fh->dev; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; int command = 0; struct upstream_user_struct *data_from_user; @@ -1150,8 +1071,8 @@ static long video_ioctl_upstream10(struct file *file, unsigned int cmd, static long video_ioctl_upstream11(struct file *file, unsigned int cmd, unsigned long arg) { - struct cx25821_fh *fh = file->private_data; - struct cx25821_dev *dev = fh->dev; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; int command = 0; struct upstream_user_struct *data_from_user; @@ -1190,8 +1111,8 @@ static long video_ioctl_upstream11(struct file *file, unsigned int cmd, static long video_ioctl_set(struct file *file, unsigned int cmd, unsigned long arg) { - struct cx25821_fh *fh = file->private_data; - struct cx25821_dev *dev = fh->dev; + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; struct downstream_user_struct *data_from_user; int command; int width = 720; @@ -1300,18 +1221,17 @@ static long video_ioctl_set(struct file *file, unsigned int cmd, static long cx25821_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { + struct cx25821_channel *chan = video_drvdata(file); int ret = 0; - struct cx25821_fh *fh = file->private_data; - /* check to see if it's the video upstream */ - if (fh->channel_id == SRAM_CH09) { + if (chan->id == SRAM_CH09) { ret = video_ioctl_upstream9(file, cmd, arg); return ret; - } else if (fh->channel_id == SRAM_CH10) { + } else if (chan->id == SRAM_CH10) { ret = video_ioctl_upstream10(file, cmd, arg); return ret; - } else if (fh->channel_id == SRAM_CH11) { + } else if (chan->id == SRAM_CH11) { ret = video_ioctl_upstream11(file, cmd, arg); ret = video_ioctl_set(file, cmd, arg); return ret; @@ -1326,7 +1246,7 @@ static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { static const struct v4l2_file_operations video_fops = { .owner = THIS_MODULE, - .open = video_open, + .open = v4l2_fh_open, .release = video_release, .read = video_read, .poll = video_poll, @@ -1352,8 +1272,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, .vidioc_log_status = vidioc_log_status, - .vidioc_g_priority = cx25821_vidioc_g_priority, - .vidioc_s_priority = cx25821_vidioc_s_priority, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = cx25821_vidioc_g_register, .vidioc_s_register = cx25821_vidioc_s_register, @@ -1454,6 +1374,7 @@ int cx25821_video_register(struct cx25821_dev *dev) vdev->v4l2_dev = &dev->v4l2_dev; vdev->ctrl_handler = hdl; vdev->lock = &dev->lock; + set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); video_set_drvdata(vdev, chan); diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index b0f0d539549..eb54e5347cc 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h @@ -39,6 +39,7 @@ #include "cx25821.h" #include #include +#include #define VIDEO_DEBUG 0 diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 128c9f320df..40b16b01349 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -116,15 +116,6 @@ struct cx25821_tvnorm { u32 cxoformat; }; -struct cx25821_fh { - struct cx25821_dev *dev; - - enum v4l2_priority prio; - - /* video capture */ - int channel_id; -}; - enum cx25821_itype { CX25821_VMUX_COMPOSITE = 1, CX25821_VMUX_SVIDEO, @@ -207,8 +198,7 @@ struct cx25821_dev; struct cx25821_channel { unsigned id; struct cx25821_dev *dev; - struct cx25821_fh *streaming_fh; - struct v4l2_prio_state prio; + struct v4l2_fh *streaming_fh; struct v4l2_ctrl_handler hdl; struct cx25821_data timeout_data; @@ -360,7 +350,6 @@ struct cx25821_dev { int pixel_format; int channel_select; int command; - int channel_opened; }; struct upstream_user_struct { -- cgit v1.2.3-70-g09d2 From 988f7b80ab6e541aef5972d347d6cc7d905abd21 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 13:06:00 -0300 Subject: [media] cx25821: g/s/try/enum_fmt related fixes and cleanups - fill in colorspace - zero priv - delete unsupported formats - fix field handling - s_std should update width/height - proper mapping of width/height to valid resolutions Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 134 +++++++----------------------- 1 file changed, 32 insertions(+), 102 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index f82da1e69e6..aec6fdfe944 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -54,11 +54,6 @@ MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); static const struct cx25821_fmt formats[] = { { - .name = "8 bpp, gray", - .fourcc = V4L2_PIX_FMT_GREY, - .depth = 8, - .flags = FORMAT_FLAGS_PACKED, - }, { .name = "4:1:1, packed, Y41P", .fourcc = V4L2_PIX_FMT_Y41P, .depth = 12, @@ -68,16 +63,6 @@ static const struct cx25821_fmt formats[] = { .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16, .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "4:2:2, packed, UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "4:2:0, YUV", - .fourcc = V4L2_PIX_FMT_YUV420, - .depth = 12, - .flags = FORMAT_FLAGS_PACKED, }, }; @@ -85,14 +70,9 @@ static const struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc) { unsigned int i; - if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P) - return formats + 1; - for (i = 0; i < ARRAY_SIZE(formats); i++) if (formats[i].fourcc == fourcc) return formats + i; - - pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc); return NULL; } @@ -381,8 +361,7 @@ static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buff bpl_local = buf->bpl; /* Default */ if (chan->use_cif_resolution) { - if (dev->tvnorm & V4L2_STD_PAL_BG || - dev->tvnorm & V4L2_STD_PAL_DK) + if (dev->tvnorm & V4L2_STD_625_50) bpl_local = 352 << 1; else bpl_local = chan->cif_width << 1; @@ -612,8 +591,10 @@ static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.height = chan->height; f->fmt.pix.field = chan->vidq.field; f->fmt.pix.pixelformat = chan->fmt->fourcc; - f->fmt.pix.bytesperline = (f->fmt.pix.width * chan->fmt->depth) >> 3; - f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + f->fmt.pix.bytesperline = (chan->width * chan->fmt->depth) >> 3; + f->fmt.pix.sizeimage = chan->height * f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.priv = 0; return 0; } @@ -621,48 +602,39 @@ static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; const struct cx25821_fmt *fmt; - enum v4l2_field field; + enum v4l2_field field = f->fmt.pix.field; unsigned int maxw, maxh; + unsigned w; fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); if (NULL == fmt) return -EINVAL; - - field = f->fmt.pix.field; maxw = 720; - maxh = 576; - - if (V4L2_FIELD_ANY == field) { - if (f->fmt.pix.height > maxh / 2) - field = V4L2_FIELD_INTERLACED; - else - field = V4L2_FIELD_TOP; - } - - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - maxh = maxh / 2; - break; - case V4L2_FIELD_INTERLACED: - break; - default: - return -EINVAL; + maxh = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480; + + w = f->fmt.pix.width; + if (field != V4L2_FIELD_BOTTOM) + field = V4L2_FIELD_TOP; + if (w < 352) { + w = 176; + f->fmt.pix.height = maxh / 4; + } else if (w < 720) { + w = 352; + f->fmt.pix.height = maxh / 2; + } else { + w = 720; + f->fmt.pix.height = maxh; + field = V4L2_FIELD_INTERLACED; } - 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; + f->fmt.pix.width = w; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.priv = 0; return 0; } @@ -696,43 +668,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) return videobuf_streamoff(&chan->vidq); } -static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm) -{ - if (tvnorm == V4L2_STD_PAL_BG) { - if (width == 352 || width == 720) - return 1; - else - return 0; - } - - if (tvnorm == V4L2_STD_NTSC_M) { - if (width == 320 || width == 352 || width == 720) - return 1; - else - return 0; - } - return 0; -} - -static int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm) -{ - if (tvnorm == V4L2_STD_PAL_BG) { - if (height == 576 || height == 288) - return 1; - else - return 0; - } - - if (tvnorm == V4L2_STD_NTSC_M) { - if (height == 480 || height == 240) - return 1; - else - return 0; - } - - return 0; -} - static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { @@ -749,20 +684,13 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); chan->vidq.field = f->fmt.pix.field; - - /* check if width and height is valid based on set standard */ - if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) - chan->width = f->fmt.pix.width; - - if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) - chan->height = f->fmt.pix.height; + chan->width = f->fmt.pix.width; + chan->height = f->fmt.pix.height; if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P) pix_format = PIXEL_FRMT_411; - else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) - pix_format = PIXEL_FRMT_422; else - return -EINVAL; + pix_format = PIXEL_FRMT_422; cx25821_set_pixel_format(dev, SRAM_CH00, pix_format); @@ -879,6 +807,8 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) return 0; cx25821_set_tvnorm(dev, tvnorms); + chan->width = 720; + chan->height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480; medusa_set_videostandard(dev); -- cgit v1.2.3-70-g09d2 From 7704cfb9cde649d514029a180cdfb7ccf0a36032 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 13:14:06 -0300 Subject: [media] cx25821: remove custom ioctls that duplicate v4l2 ioctls No idea why these custom ioctls exist: they have perfectly normal v4l2 counterparts which are already implemented. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 128 ++---------------------------- drivers/media/pci/cx25821/cx25821-video.h | 8 -- drivers/media/pci/cx25821/cx25821.h | 13 --- 3 files changed, 6 insertions(+), 143 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index aec6fdfe944..d3aa166740c 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -1038,134 +1038,18 @@ static long video_ioctl_upstream11(struct file *file, unsigned int cmd, return 0; } -static long video_ioctl_set(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - struct downstream_user_struct *data_from_user; - int command; - int width = 720; - int selected_channel = 0; - int pix_format = 0; - int i = 0; - int cif_enable = 0; - int cif_width = 0; - - data_from_user = (struct downstream_user_struct *)arg; - - if (!data_from_user) { - pr_err("%s(): User data is INVALID. Returning\n", __func__); - return 0; - } - - command = data_from_user->command; - - if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT - && command != ENABLE_CIF_RESOLUTION && command != REG_READ - && command != REG_WRITE && command != MEDUSA_READ - && command != MEDUSA_WRITE) { - return 0; - } - - switch (command) { - case SET_VIDEO_STD: - if (!strcmp(data_from_user->vid_stdname, "PAL")) - dev->tvnorm = V4L2_STD_PAL_BG; - else - dev->tvnorm = V4L2_STD_NTSC_M; - medusa_set_videostandard(dev); - break; - - case SET_PIXEL_FORMAT: - selected_channel = data_from_user->decoder_select; - pix_format = data_from_user->pixel_format; - - if (!(selected_channel <= 7 && selected_channel >= 0)) { - selected_channel -= 4; - selected_channel = selected_channel % 8; - } - - if (selected_channel >= 0) - cx25821_set_pixel_format(dev, selected_channel, - pix_format); - - break; - - case ENABLE_CIF_RESOLUTION: - selected_channel = data_from_user->decoder_select; - cif_enable = data_from_user->cif_resolution_enable; - cif_width = data_from_user->cif_width; - - if (cif_enable) { - if (dev->tvnorm & V4L2_STD_PAL_BG - || dev->tvnorm & V4L2_STD_PAL_DK) { - width = 352; - } else { - width = cif_width; - if (cif_width != 320 && cif_width != 352) - width = 320; - } - } - - if (!(selected_channel <= 7 && selected_channel >= 0)) { - selected_channel -= 4; - selected_channel = selected_channel % 8; - } - - if (selected_channel <= 7 && selected_channel >= 0) { - dev->channels[selected_channel].use_cif_resolution = - cif_enable; - dev->channels[selected_channel].cif_width = width; - } else { - for (i = 0; i < VID_CHANNEL_NUM; i++) { - dev->channels[i].use_cif_resolution = - cif_enable; - dev->channels[i].cif_width = width; - } - } - - medusa_set_resolution(dev, width, selected_channel); - break; - case REG_READ: - data_from_user->reg_data = cx_read(data_from_user->reg_address); - break; - case REG_WRITE: - cx_write(data_from_user->reg_address, data_from_user->reg_data); - break; - case MEDUSA_READ: - cx25821_i2c_read(&dev->i2c_bus[0], - (u16) data_from_user->reg_address, - &data_from_user->reg_data); - break; - case MEDUSA_WRITE: - cx25821_i2c_write(&dev->i2c_bus[0], - (u16) data_from_user->reg_address, - data_from_user->reg_data); - break; - } - - return 0; -} - static long cx25821_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct cx25821_channel *chan = video_drvdata(file); - int ret = 0; /* check to see if it's the video upstream */ - if (chan->id == SRAM_CH09) { - ret = video_ioctl_upstream9(file, cmd, arg); - return ret; - } else if (chan->id == SRAM_CH10) { - ret = video_ioctl_upstream10(file, cmd, arg); - return ret; - } else if (chan->id == SRAM_CH11) { - ret = video_ioctl_upstream11(file, cmd, arg); - ret = video_ioctl_set(file, cmd, arg); - return ret; - } + if (chan->id == SRAM_CH09) + return video_ioctl_upstream9(file, cmd, arg); + if (chan->id == SRAM_CH10) + return video_ioctl_upstream10(file, cmd, arg); + if (chan->id == SRAM_CH11) + return video_ioctl_upstream11(file, cmd, arg); return video_ioctl2(file, cmd, arg); } diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index eb54e5347cc..8871c4e737e 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h @@ -55,14 +55,6 @@ do { \ #define UPSTREAM_START_AUDIO 702 #define UPSTREAM_STOP_AUDIO 703 #define UPSTREAM_DUMP_REGISTERS 702 -#define SET_VIDEO_STD 800 -#define SET_PIXEL_FORMAT 1000 -#define ENABLE_CIF_RESOLUTION 1001 - -#define REG_READ 900 -#define REG_WRITE 901 -#define MEDUSA_READ 910 -#define MEDUSA_WRITE 911 #define FORMAT_FLAGS_PACKED 0x01 extern void cx25821_video_wakeup(struct cx25821_dev *dev, diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 40b16b01349..cfda5ac4faa 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -360,19 +360,6 @@ struct upstream_user_struct { int command; }; -struct downstream_user_struct { - char *vid_stdname; - int pixel_format; - int cif_resolution_enable; - int cif_width; - int decoder_select; - int command; - int reg_address; - int reg_data; -}; - -extern struct upstream_user_struct *up_data; - static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) { return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev); -- cgit v1.2.3-70-g09d2 From a6aa0dc482d7aad5fc4366d4c92d07a10d712b82 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 13 Apr 2013 13:34:34 -0300 Subject: [media] cx25821: remove references to subdevices that aren't there This driver does not have subdevices, so why call subdev ops? After removing that it became apparent that only Composite is supported as input, so remove also any reference to other inputs. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-cards.c | 1 - drivers/media/pci/cx25821/cx25821-video.c | 111 ++---------------------------- drivers/media/pci/cx25821/cx25821.h | 26 ------- 3 files changed, 7 insertions(+), 131 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-cards.c b/drivers/media/pci/cx25821/cx25821-cards.c index 2b2f1f4f87a..3b409feb03d 100644 --- a/drivers/media/pci/cx25821/cx25821-cards.c +++ b/drivers/media/pci/cx25821/cx25821-cards.c @@ -42,7 +42,6 @@ struct cx25821_board cx25821_boards[] = { .name = "CX25821", .portb = CX25821_RAW, .portc = CX25821_264, - .input[0].type = CX25821_VMUX_COMPOSITE, }, }; diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index d3aa166740c..49686447cc4 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -111,37 +111,6 @@ void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc); } -static int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm) -{ - dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", - __func__, (unsigned int)norm, v4l2_norm_to_name(norm)); - - dev->tvnorm = norm; - - /* Tell the internal A/V decoder */ - cx25821_call_all(dev, core, s_std, norm); - - return 0; -} - -static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input) -{ - struct v4l2_routing route; - memset(&route, 0, sizeof(route)); - - dprintk(1, "%s(): video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", - __func__, input, INPUT(input)->vmux, INPUT(input)->gpio0, - INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3); - dev->input = input; - - route.input = INPUT(input)->vmux; - - /* Tell the internal A/V decoder */ - cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0); - - return 0; -} - int cx25821_start_video_dma(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, struct cx25821_buffer *buf, @@ -673,9 +642,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, { struct cx25821_channel *chan = video_drvdata(file); struct cx25821_dev *dev = chan->dev; - struct v4l2_mbus_framefmt mbus_fmt; - int err; int pix_format = PIXEL_FRMT_422; + int err; err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f); @@ -702,10 +670,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, chan->cif_width = chan->width; medusa_set_resolution(dev, chan->width, SRAM_CH00); - - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); - cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt); - return 0; } @@ -727,7 +691,6 @@ static int vidioc_log_status(struct file *file, void *priv) const struct sram_channel *sram_ch = chan->sram_channels; u32 tmp = 0; - cx25821_call_all(dev, core, log_status); tmp = cx_read(sram_ch->dma_ctl); pr_info("Video input 0 is %s\n", (tmp & 0x11) ? "streaming" : "stopped"); @@ -806,7 +769,7 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) if (dev->tvnorm == tvnorms) return 0; - cx25821_set_tvnorm(dev, tvnorms); + dev->tvnorm = tvnorms; chan->width = 720; chan->height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480; @@ -818,81 +781,26 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms) static int cx25821_vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i) { - static const char * const iname[] = { - [CX25821_VMUX_COMPOSITE] = "Composite", - [CX25821_VMUX_SVIDEO] = "S-Video", - [CX25821_VMUX_DEBUG] = "for debug only", - }; - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - unsigned int n; - - n = i->index; - if (n >= CX25821_NR_INPUT) - return -EINVAL; - - if (0 == INPUT(n)->type) + if (i->index) return -EINVAL; i->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(i->name, iname[INPUT(n)->type]); - i->std = CX25821_NORMS; + strcpy(i->name, "Composite"); return 0; } static int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i) { - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - - *i = dev->input; + *i = 0; return 0; } static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i) { - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - - if (i >= CX25821_NR_INPUT || INPUT(i)->type == 0) - return -EINVAL; - - cx25821_video_mux(dev, i); - return 0; + return i ? -EINVAL : 0; } -#ifdef CONFIG_VIDEO_ADV_DEBUG -int cx25821_vidioc_g_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; - - cx25821_call_all(dev, core, g_register, reg); - - return 0; -} - -int cx25821_vidioc_s_register(struct file *file, void *fh, - const struct v4l2_dbg_register *reg) -{ - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - - if (!v4l2_chip_match_host(®->match)) - return -EINVAL; - - cx25821_call_all(dev, core, s_register, reg); - - return 0; -} - -#endif - static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl) { struct cx25821_channel *chan = @@ -1088,10 +996,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_log_status = vidioc_log_status, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = cx25821_vidioc_g_register, - .vidioc_s_register = cx25821_vidioc_s_register, -#endif }; static const struct video_device cx25821_video_device = { @@ -1122,8 +1026,7 @@ int cx25821_video_register(struct cx25821_dev *dev) int i; /* initial device configuration */ - dev->tvnorm = V4L2_STD_NTSC_M, - cx25821_set_tvnorm(dev, dev->tvnorm); + dev->tvnorm = V4L2_STD_NTSC_M; spin_lock_init(&dev->slock); diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index cfda5ac4faa..67b3c550e45 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -62,7 +62,6 @@ /* Max number of inputs by card */ #define MAX_CX25821_INPUT 8 -#define INPUT(nr) (&cx25821_boards[dev->board].input[nr]) #define RESOURCE_VIDEO0 1 #define RESOURCE_VIDEO1 2 #define RESOURCE_VIDEO2 4 @@ -91,7 +90,6 @@ #define CX25821_BOARD_CONEXANT_ATHENA10 1 #define MAX_VID_CHANNEL_NUM 12 #define VID_CHANNEL_NUM 8 -#define CX25821_NR_INPUT 2 struct cx25821_fmt { char *name; @@ -101,14 +99,6 @@ struct cx25821_fmt { u32 cxformat; }; -struct cx25821_ctrl { - struct v4l2_queryctrl v; - u32 off; - u32 reg; - u32 mask; - u32 shift; -}; - struct cx25821_tvnorm { char *name; v4l2_std_id id; @@ -116,12 +106,6 @@ struct cx25821_tvnorm { u32 cxoformat; }; -enum cx25821_itype { - CX25821_VMUX_COMPOSITE = 1, - CX25821_VMUX_SVIDEO, - CX25821_VMUX_DEBUG, -}; - enum cx25821_src_sel_type { CX25821_SRC_SEL_EXT_656_VIDEO = 0, CX25821_SRC_SEL_PARALLEL_MPEG_VIDEO @@ -139,12 +123,6 @@ struct cx25821_buffer { u32 count; }; -struct cx25821_input { - enum cx25821_itype type; - unsigned int vmux; - u32 gpio0, gpio1, gpio2, gpio3; -}; - enum port { CX25821_UNDEFINED = 0, CX25821_RAW, @@ -158,7 +136,6 @@ struct cx25821_board { enum port portc; u32 clk_freq; - struct cx25821_input input[CX25821_NR_INPUT]; }; struct cx25821_i2c { @@ -365,9 +342,6 @@ static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev); } -#define cx25821_call_all(dev, o, f, args...) \ - v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) - extern struct cx25821_board cx25821_boards[]; #define SRAM_CH00 0 /* Video A */ -- cgit v1.2.3-70-g09d2 From 1f1988706d77083040113094a4bee2e9e1bdc34f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 12:07:13 -0300 Subject: [media] cx25821: setup output nodes correctly Drop the custom ioctls and enable the video output nodes again, this time using standard ioctls. The next step will be to provide a proper write() interface. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-core.c | 30 ----- drivers/media/pci/cx25821/cx25821-video.c | 214 ++++++++++-------------------- drivers/media/pci/cx25821/cx25821-video.h | 7 - drivers/media/pci/cx25821/cx25821.h | 16 --- 4 files changed, 67 insertions(+), 200 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index ba417c97841..9068d53a5b8 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -956,36 +956,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev) return 0; } -void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, - struct upstream_user_struct *up_data) -{ - dev->_isNTSC = !strcmp(dev->vid_stdname, "NTSC") ? 1 : 0; - - dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M; - medusa_set_videostandard(dev); - - cx25821_vidupstream_init_ch1(dev, dev->channel_select, - dev->pixel_format); -} - -void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, - struct upstream_user_struct *up_data) -{ - dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2, "NTSC") ? 1 : 0; - - dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M; - medusa_set_videostandard(dev); - - cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2, - dev->pixel_format_ch2); -} - -void cx25821_start_upstream_audio(struct cx25821_dev *dev, - struct upstream_user_struct *up_data) -{ - cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B); -} - void cx25821_dev_unregister(struct cx25821_dev *dev) { int i; diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 49686447cc4..8d5d13bb5f0 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -826,140 +826,27 @@ static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } -static long video_ioctl_upstream9(struct file *file, unsigned int cmd, - unsigned long arg) +static int cx25821_vidioc_enum_output(struct file *file, void *priv, + struct v4l2_output *o) { - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - int command = 0; - struct upstream_user_struct *data_from_user; - - data_from_user = (struct upstream_user_struct *)arg; - - if (!data_from_user) { - pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); - return 0; - } - - command = data_from_user->command; - - if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) - return 0; - - dev->input_filename = data_from_user->input_filename; - dev->input_audiofilename = data_from_user->input_filename; - dev->vid_stdname = data_from_user->vid_stdname; - dev->pixel_format = data_from_user->pixel_format; - dev->channel_select = data_from_user->channel_select; - dev->command = data_from_user->command; - - switch (command) { - case UPSTREAM_START_VIDEO: - cx25821_start_upstream_video_ch1(dev, data_from_user); - break; - - case UPSTREAM_STOP_VIDEO: - cx25821_stop_upstream_video_ch1(dev); - break; - } + if (o->index) + return -EINVAL; + o->type = V4L2_INPUT_TYPE_CAMERA; + o->std = CX25821_NORMS; + strcpy(o->name, "Composite"); return 0; } -static long video_ioctl_upstream10(struct file *file, unsigned int cmd, - unsigned long arg) +static int cx25821_vidioc_g_output(struct file *file, void *priv, unsigned int *o) { - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - int command = 0; - struct upstream_user_struct *data_from_user; - - data_from_user = (struct upstream_user_struct *)arg; - - if (!data_from_user) { - pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); - return 0; - } - - command = data_from_user->command; - - if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) - return 0; - - dev->input_filename_ch2 = data_from_user->input_filename; - dev->input_audiofilename = data_from_user->input_filename; - dev->vid_stdname_ch2 = data_from_user->vid_stdname; - dev->pixel_format_ch2 = data_from_user->pixel_format; - dev->channel_select_ch2 = data_from_user->channel_select; - dev->command_ch2 = data_from_user->command; - - switch (command) { - case UPSTREAM_START_VIDEO: - cx25821_start_upstream_video_ch2(dev, data_from_user); - break; - - case UPSTREAM_STOP_VIDEO: - cx25821_stop_upstream_video_ch2(dev); - break; - } - + *o = 0; return 0; } -static long video_ioctl_upstream11(struct file *file, unsigned int cmd, - unsigned long arg) +static int cx25821_vidioc_s_output(struct file *file, void *priv, unsigned int o) { - struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_dev *dev = chan->dev; - int command = 0; - struct upstream_user_struct *data_from_user; - - data_from_user = (struct upstream_user_struct *)arg; - - if (!data_from_user) { - pr_err("%s(): Upstream data is INVALID. Returning\n", __func__); - return 0; - } - - command = data_from_user->command; - - if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO) - return 0; - - dev->input_filename = data_from_user->input_filename; - dev->input_audiofilename = data_from_user->input_filename; - dev->vid_stdname = data_from_user->vid_stdname; - dev->pixel_format = data_from_user->pixel_format; - dev->channel_select = data_from_user->channel_select; - dev->command = data_from_user->command; - - switch (command) { - case UPSTREAM_START_AUDIO: - cx25821_start_upstream_audio(dev, data_from_user); - break; - - case UPSTREAM_STOP_AUDIO: - cx25821_stop_upstream_audio(dev); - break; - } - - return 0; -} - -static long cx25821_video_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct cx25821_channel *chan = video_drvdata(file); - - /* check to see if it's the video upstream */ - if (chan->id == SRAM_CH09) - return video_ioctl_upstream9(file, cmd, arg); - if (chan->id == SRAM_CH10) - return video_ioctl_upstream10(file, cmd, arg); - if (chan->id == SRAM_CH11) - return video_ioctl_upstream11(file, cmd, arg); - - return video_ioctl2(file, cmd, arg); + return o ? -EINVAL : 0; } static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { @@ -973,7 +860,7 @@ static const struct v4l2_file_operations video_fops = { .read = video_read, .poll = video_poll, .mmap = cx25821_video_mmap, - .unlocked_ioctl = cx25821_video_ioctl, + .unlocked_ioctl = video_ioctl2, }; static const struct v4l2_ioctl_ops video_ioctl_ops = { @@ -1007,6 +894,32 @@ static const struct video_device cx25821_video_device = { .tvnorms = CX25821_NORMS, }; +static const struct v4l2_file_operations video_out_fops = { + .owner = THIS_MODULE, + .open = v4l2_fh_open, + .release = v4l2_fh_release, + .unlocked_ioctl = video_ioctl2, +}; + +static const struct v4l2_ioctl_ops video_out_ioctl_ops = { + .vidioc_querycap = cx25821_vidioc_querycap, + .vidioc_g_std = cx25821_vidioc_g_std, + .vidioc_s_std = cx25821_vidioc_s_std, + .vidioc_enum_output = cx25821_vidioc_enum_output, + .vidioc_g_output = cx25821_vidioc_g_output, + .vidioc_s_output = cx25821_vidioc_s_output, + .vidioc_log_status = vidioc_log_status, +}; + +static const struct video_device cx25821_video_out_device = { + .name = "cx25821-video", + .fops = &video_out_fops, + .release = video_device_release_empty, + .minor = -1, + .ioctl_ops = &video_out_ioctl_ops, + .tvnorms = CX25821_NORMS, +}; + void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num) { cx_clear(PCI_INT_MSK, 1); @@ -1030,30 +943,33 @@ int cx25821_video_register(struct cx25821_dev *dev) spin_lock_init(&dev->slock); - for (i = 0; i < VID_CHANNEL_NUM; ++i) { + for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) { struct cx25821_channel *chan = &dev->channels[i]; struct video_device *vdev = &chan->vdev; struct v4l2_ctrl_handler *hdl = &chan->hdl; + bool is_output = i > SRAM_CH08; if (i == SRAM_CH08) /* audio channel */ continue; - v4l2_ctrl_handler_init(hdl, 4); - v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, - V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200); - v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, - V4L2_CID_CONTRAST, 0, 10000, 1, 5000); - v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, - V4L2_CID_SATURATION, 0, 10000, 1, 5000); - v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, - V4L2_CID_HUE, 0, 10000, 1, 5000); - if (hdl->error) { - err = hdl->error; - goto fail_unreg; + if (!is_output) { + v4l2_ctrl_handler_init(hdl, 4); + v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200); + v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, + V4L2_CID_CONTRAST, 0, 10000, 1, 5000); + v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, + V4L2_CID_SATURATION, 0, 10000, 1, 5000); + v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops, + V4L2_CID_HUE, 0, 10000, 1, 5000); + if (hdl->error) { + err = hdl->error; + goto fail_unreg; + } + err = v4l2_ctrl_handler_setup(hdl); + if (err) + goto fail_unreg; } - err = v4l2_ctrl_handler_setup(hdl); - if (err) - goto fail_unreg; cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper, chan->sram_channels->dma_ctl, 0x11, 0); @@ -1081,15 +997,19 @@ int cx25821_video_register(struct cx25821_dev *dev) chan->dma_vidq.timeout.data = (unsigned long)&chan->timeout_data; init_timer(&chan->dma_vidq.timeout); - videobuf_queue_sg_init(&chan->vidq, &cx25821_video_qops, &dev->pci->dev, - &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), - chan, &dev->lock); + if (!is_output) + videobuf_queue_sg_init(&chan->vidq, &cx25821_video_qops, &dev->pci->dev, + &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer), + chan, &dev->lock); /* register v4l devices */ - *vdev = cx25821_video_device; + *vdev = is_output ? cx25821_video_out_device : cx25821_video_device; vdev->v4l2_dev = &dev->v4l2_dev; - vdev->ctrl_handler = hdl; + if (!is_output) + vdev->ctrl_handler = hdl; + else + vdev->vfl_dir = VFL_DIR_TX; vdev->lock = &dev->lock; set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); diff --git a/drivers/media/pci/cx25821/cx25821-video.h b/drivers/media/pci/cx25821/cx25821-video.h index 8871c4e737e..ab63b3858ac 100644 --- a/drivers/media/pci/cx25821/cx25821-video.h +++ b/drivers/media/pci/cx25821/cx25821-video.h @@ -49,13 +49,6 @@ do { \ printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg); \ } while (0) -/* For IOCTL to identify running upstream */ -#define UPSTREAM_START_VIDEO 700 -#define UPSTREAM_STOP_VIDEO 701 -#define UPSTREAM_START_AUDIO 702 -#define UPSTREAM_STOP_AUDIO 703 -#define UPSTREAM_DUMP_REGISTERS 702 - #define FORMAT_FLAGS_PACKED 0x01 extern void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q, u32 count); diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 67b3c550e45..156ad6f2c63 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -329,14 +329,6 @@ struct cx25821_dev { int command; }; -struct upstream_user_struct { - char *input_filename; - char *vid_stdname; - int pixel_format; - int channel_select; - int command; -}; - static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) { return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev); @@ -480,14 +472,6 @@ extern int cx25821_audio_upstream_init(struct cx25821_dev *dev, extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev); extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev); extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); -extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev, - struct upstream_user_struct - *up_data); -extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev, - struct upstream_user_struct - *up_data); -extern void cx25821_start_upstream_audio(struct cx25821_dev *dev, - struct upstream_user_struct *up_data); extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev); extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev); extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev); -- cgit v1.2.3-70-g09d2 From 4c1d0f73021393dda4a226b5c4c86b2d730d656c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 07:13:02 -0300 Subject: [media] cx25821: group all fmt functions together No other changes, just function reordering. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 84 ++++++++++++++++--------------- 1 file changed, 43 insertions(+), 41 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 8d5d13bb5f0..d3cf259f19f 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -551,6 +551,19 @@ static int video_release(struct file *file) } /* VIDEO IOCTLS */ + +static int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (unlikely(f->index >= ARRAY_SIZE(formats))) + return -EINVAL; + + strlcpy(f->description, formats[f->index].name, sizeof(f->description)); + f->pixelformat = formats[f->index].fourcc; + + return 0; +} + static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { @@ -607,35 +620,6 @@ static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct cx25821_channel *chan = video_drvdata(file); - - if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (chan->streaming_fh && chan->streaming_fh != priv) - return -EBUSY; - chan->streaming_fh = priv; - - return videobuf_streamon(&chan->vidq); -} - -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct cx25821_channel *chan = video_drvdata(file); - - if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - if (chan->streaming_fh && chan->streaming_fh != priv) - return -EBUSY; - if (chan->streaming_fh == NULL) - return 0; - - chan->streaming_fh = NULL; - return videobuf_streamoff(&chan->vidq); -} static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) @@ -673,6 +657,36 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, return 0; } +static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct cx25821_channel *chan = video_drvdata(file); + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (chan->streaming_fh && chan->streaming_fh != priv) + return -EBUSY; + chan->streaming_fh = priv; + + return videobuf_streamon(&chan->vidq); +} + +static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct cx25821_channel *chan = video_drvdata(file); + + if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + if (chan->streaming_fh && chan->streaming_fh != priv) + return -EBUSY; + if (chan->streaming_fh == NULL) + return 0; + + chan->streaming_fh = NULL; + return videobuf_streamoff(&chan->vidq); +} + static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) { int ret_val = 0; @@ -718,18 +732,6 @@ static int cx25821_vidioc_querycap(struct file *file, void *priv, return 0; } -static int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (unlikely(f->index >= ARRAY_SIZE(formats))) - return -EINVAL; - - strlcpy(f->description, formats[f->index].name, sizeof(f->description)); - f->pixelformat = formats[f->index].fourcc; - - return 0; -} - static int cx25821_vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { -- cgit v1.2.3-70-g09d2 From 0df13d99f7c90e3f96408c0ba425e9fb1e48bbd3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 07:14:42 -0300 Subject: [media] cx25821: prepare querycap for output support Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index d3cf259f19f..dca33918367 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -719,7 +719,7 @@ static int cx25821_vidioc_querycap(struct file *file, void *priv, struct cx25821_dev *dev = chan->dev; const u32 cap_input = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT; + const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE; strcpy(cap->driver, "cx25821"); strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card)); @@ -728,7 +728,7 @@ static int cx25821_vidioc_querycap(struct file *file, void *priv, cap->device_caps = cap_output; else cap->device_caps = cap_input; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + cap->capabilities = cap_input | cap_output | V4L2_CAP_DEVICE_CAPS; return 0; } -- cgit v1.2.3-70-g09d2 From e90878ab151f733b67d725a1e1e5aee04f431ce5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 11:40:26 -0300 Subject: [media] cx25821: add output format ioctls Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-video.c | 46 +++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index dca33918367..70e33b12596 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -851,6 +851,48 @@ static int cx25821_vidioc_s_output(struct file *file, void *priv, unsigned int o return o ? -EINVAL : 0; } +static int cx25821_vidioc_try_fmt_vid_out(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; + const struct cx25821_fmt *fmt; + + fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); + if (NULL == fmt) + return -EINVAL; + f->fmt.pix.width = 720; + f->fmt.pix.height = (dev->tvnorm & V4L2_STD_625_50) ? 576 : 480; + f->fmt.pix.field = V4L2_FIELD_INTERLACED; + f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + f->fmt.pix.priv = 0; + return 0; +} + +static int vidioc_s_fmt_vid_out(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct cx25821_channel *chan = video_drvdata(file); + int err; + + err = cx25821_vidioc_try_fmt_vid_out(file, priv, f); + + if (0 != err) + return err; + + chan->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); + chan->vidq.field = f->fmt.pix.field; + chan->width = f->fmt.pix.width; + chan->height = f->fmt.pix.height; + if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P) + chan->pixel_formats = PIXEL_FRMT_411; + else + chan->pixel_formats = PIXEL_FRMT_422; + return 0; +} + static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { .s_ctrl = cx25821_s_ctrl, }; @@ -905,6 +947,10 @@ static const struct v4l2_file_operations video_out_fops = { static const struct v4l2_ioctl_ops video_out_ioctl_ops = { .vidioc_querycap = cx25821_vidioc_querycap, + .vidioc_enum_fmt_vid_out = cx25821_vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_out = cx25821_vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_out = cx25821_vidioc_try_fmt_vid_out, + .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, .vidioc_g_std = cx25821_vidioc_g_std, .vidioc_s_std = cx25821_vidioc_s_std, .vidioc_enum_output = cx25821_vidioc_enum_output, -- cgit v1.2.3-70-g09d2 From 7087d31b0c9dddbca71b8e33d3f0a3b719afa397 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 12:10:32 -0300 Subject: [media] cx25821: drop cx25821-video-upstream-ch2.c/h cx25821-video-upstream_ch2.c/h is practically identical to cx25821-video-upstream.c/h so add support for ch2 into cx25821-video-upstream.c instead. After this we can replace the custom ioctls with a proper write() interface. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/Makefile | 1 - drivers/media/pci/cx25821/cx25821-core.c | 4 +- .../media/pci/cx25821/cx25821-video-upstream-ch2.c | 800 --------------------- .../media/pci/cx25821/cx25821-video-upstream-ch2.h | 138 ---- drivers/media/pci/cx25821/cx25821-video-upstream.c | 349 ++++----- drivers/media/pci/cx25821/cx25821-video.c | 19 +- drivers/media/pci/cx25821/cx25821.h | 127 ++-- 7 files changed, 243 insertions(+), 1195 deletions(-) delete mode 100644 drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c delete mode 100644 drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile index b54a32e88bd..407830c89df 100644 --- a/drivers/media/pci/cx25821/Makefile +++ b/drivers/media/pci/cx25821/Makefile @@ -1,7 +1,6 @@ cx25821-y := cx25821-core.o cx25821-cards.o cx25821-i2c.o \ cx25821-gpio.o cx25821-medusa-video.o \ cx25821-video.o cx25821-video-upstream.o \ - cx25821-video-upstream-ch2.o \ cx25821-audio-upstream.o obj-$(CONFIG_VIDEO_CX25821) += cx25821.o diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 9068d53a5b8..230bd864157 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -963,8 +963,6 @@ void cx25821_dev_unregister(struct cx25821_dev *dev) if (!dev->base_io_addr) return; - cx25821_free_mem_upstream_ch1(dev); - cx25821_free_mem_upstream_ch2(dev); cx25821_free_mem_upstream_audio(dev); release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0)); @@ -972,6 +970,8 @@ void cx25821_dev_unregister(struct cx25821_dev *dev) for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) { if (i == SRAM_CH08) /* audio channel */ continue; + if (i == SRAM_CH09 || i == SRAM_CH10) + cx25821_free_mem_upstream(&dev->channels[i]); cx25821_video_unregister(dev, i); } diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c deleted file mode 100644 index 2381bdce99f..00000000000 --- a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.c +++ /dev/null @@ -1,800 +0,0 @@ -/* - * Driver for the Conexant CX25821 PCIe bridge - * - * Copyright (C) 2009 Conexant Systems Inc. - * Authors , - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "cx25821-video.h" -#include "cx25821-video-upstream-ch2.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); -MODULE_AUTHOR("Hiep Huynh "); -MODULE_LICENSE("GPL"); - -static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | - FLD_VID_SRC_OPC_ERR; - -static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev, - __le32 *rp, unsigned int offset, - unsigned int bpl, u32 sync_line, - unsigned int lines, - int fifo_enable, int field_type) -{ - unsigned int line, i; - int dist_betwn_starts = bpl * 2; - - *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); - - if (USE_RISC_NOOP_VIDEO) { - for (i = 0; i < NUM_NO_OPS; i++) - *(rp++) = cpu_to_le32(RISC_NOOP); - } - - /* scan lines */ - for (line = 0; line < lines; line++) { - *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); - *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - - if ((lines <= NTSC_FIELD_HEIGHT) || - (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { - offset += dist_betwn_starts; - } - } - - return rp; -} - -static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev, - __le32 *rp, - dma_addr_t databuf_phys_addr, - unsigned int offset, - u32 sync_line, unsigned int bpl, - unsigned int lines, - int fifo_enable, int field_type) -{ - unsigned int line, i; - const struct sram_channel *sram_ch = - dev->channels[dev->_channel2_upstream_select].sram_channels; - int dist_betwn_starts = bpl * 2; - - /* sync instruction */ - if (sync_line != NO_SYNC_LINE) - *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); - - if (USE_RISC_NOOP_VIDEO) { - for (i = 0; i < NUM_NO_OPS; i++) - *(rp++) = cpu_to_le32(RISC_NOOP); - } - - /* scan lines */ - for (line = 0; line < lines; line++) { - *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); - *(rp++) = cpu_to_le32(databuf_phys_addr + offset); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - - if ((lines <= NTSC_FIELD_HEIGHT) || - (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC_ch2)) { - offset += dist_betwn_starts; - } - - /* - check if we need to enable the FIFO after the first 4 lines - For the upstream video channel, the risc engine will enable - the FIFO. - */ - if (fifo_enable && line == 3) { - *(rp++) = RISC_WRITECR; - *(rp++) = sram_ch->dma_ctl; - *(rp++) = FLD_VID_FIFO_EN; - *(rp++) = 0x00000001; - } - } - - return rp; -} - -static int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev, - struct pci_dev *pci, - unsigned int top_offset, - unsigned int bpl, - unsigned int lines) -{ - __le32 *rp; - int fifo_enable = 0; - int singlefield_lines = lines >> 1; /*get line count for single field */ - int odd_num_lines = singlefield_lines; - int frame = 0; - int frame_size = 0; - int databuf_offset = 0; - int risc_program_size = 0; - int risc_flag = RISC_CNT_RESET; - unsigned int bottom_offset = bpl; - dma_addr_t risc_phys_jump_addr; - - if (dev->_isNTSC_ch2) { - odd_num_lines = singlefield_lines + 1; - risc_program_size = FRAME1_VID_PROG_SIZE; - if (bpl == Y411_LINE_SZ) - frame_size = FRAME_SIZE_NTSC_Y411; - else - frame_size = FRAME_SIZE_NTSC_Y422; - } else { - risc_program_size = PAL_VID_PROG_SIZE; - if (bpl == Y411_LINE_SZ) - frame_size = FRAME_SIZE_PAL_Y411; - else - frame_size = FRAME_SIZE_PAL_Y422; - } - - /* Virtual address of Risc buffer program */ - rp = dev->_dma_virt_addr_ch2; - - for (frame = 0; frame < NUM_FRAMES; frame++) { - databuf_offset = frame_size * frame; - - if (UNSET != top_offset) { - fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; - rp = cx25821_risc_field_upstream_ch2(dev, rp, - dev->_data_buf_phys_addr_ch2 + databuf_offset, - top_offset, 0, bpl, odd_num_lines, fifo_enable, - ODD_FIELD); - } - - fifo_enable = FIFO_DISABLE; - - /* Even field */ - rp = cx25821_risc_field_upstream_ch2(dev, rp, - dev->_data_buf_phys_addr_ch2 + databuf_offset, - bottom_offset, 0x200, bpl, singlefield_lines, - fifo_enable, EVEN_FIELD); - - if (frame == 0) { - risc_flag = RISC_CNT_RESET; - risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2 + - risc_program_size; - } else { - risc_flag = RISC_CNT_INC; - risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2; - } - - /* - * Loop to 2ndFrameRISC or to Start of - * Risc program & generate IRQ - */ - *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag); - *(rp++) = cpu_to_le32(risc_phys_jump_addr); - *(rp++) = cpu_to_le32(0); - } - - return 0; -} - -void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev) -{ - const struct sram_channel *sram_ch = - dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels; - u32 tmp = 0; - - if (!dev->_is_running_ch2) { - pr_info("No video file is currently running so return!\n"); - return; - } - /* Disable RISC interrupts */ - tmp = cx_read(sram_ch->int_msk); - cx_write(sram_ch->int_msk, tmp & ~_intr_msk); - - /* Turn OFF risc and fifo */ - tmp = cx_read(sram_ch->dma_ctl); - cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); - - /* Clear data buffer memory */ - if (dev->_data_buf_virt_addr_ch2) - memset(dev->_data_buf_virt_addr_ch2, 0, - dev->_data_buf_size_ch2); - - dev->_is_running_ch2 = 0; - dev->_is_first_frame_ch2 = 0; - dev->_frame_count_ch2 = 0; - dev->_file_status_ch2 = END_OF_FILE; - - kfree(dev->_irq_queues_ch2); - dev->_irq_queues_ch2 = NULL; - - kfree(dev->_filename_ch2); - - tmp = cx_read(VID_CH_MODE_SEL); - cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); -} - -void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev) -{ - if (dev->_is_running_ch2) - cx25821_stop_upstream_video_ch2(dev); - - if (dev->_dma_virt_addr_ch2) { - pci_free_consistent(dev->pci, dev->_risc_size_ch2, - dev->_dma_virt_addr_ch2, - dev->_dma_phys_addr_ch2); - dev->_dma_virt_addr_ch2 = NULL; - } - - if (dev->_data_buf_virt_addr_ch2) { - pci_free_consistent(dev->pci, dev->_data_buf_size_ch2, - dev->_data_buf_virt_addr_ch2, - dev->_data_buf_phys_addr_ch2); - dev->_data_buf_virt_addr_ch2 = NULL; - } -} - -static int cx25821_get_frame_ch2(struct cx25821_dev *dev, - const struct sram_channel *sram_ch) -{ - struct file *myfile; - int frame_index_temp = dev->_frame_index_ch2; - int i = 0; - int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? - Y411_LINE_SZ : Y422_LINE_SZ; - int frame_size = 0; - int frame_offset = 0; - ssize_t vfs_read_retval = 0; - char mybuf[line_size]; - loff_t file_offset; - loff_t pos; - mm_segment_t old_fs; - - if (dev->_file_status_ch2 == END_OF_FILE) - return 0; - - if (dev->_isNTSC_ch2) { - frame_size = (line_size == Y411_LINE_SZ) ? - FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; - } else { - frame_size = (line_size == Y411_LINE_SZ) ? - FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; - } - - frame_offset = (frame_index_temp > 0) ? frame_size : 0; - file_offset = dev->_frame_count_ch2 * frame_size; - - myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); - if (IS_ERR(myfile)) { - const int open_errno = -PTR_ERR(myfile); - pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", - __func__, dev->_filename_ch2, open_errno); - return PTR_ERR(myfile); - } else { - if (!(myfile->f_op)) { - pr_err("%s(): File has no file operations registered!\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - if (!myfile->f_op->read) { - pr_err("%s(): File has no READ operations registered!\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - pos = myfile->f_pos; - old_fs = get_fs(); - set_fs(KERNEL_DS); - - for (i = 0; i < dev->_lines_count_ch2; i++) { - pos = file_offset; - - vfs_read_retval = vfs_read(myfile, mybuf, line_size, - &pos); - - if (vfs_read_retval > 0 && vfs_read_retval == line_size - && dev->_data_buf_virt_addr_ch2 != NULL) { - memcpy((void *)(dev->_data_buf_virt_addr_ch2 + - frame_offset / 4), mybuf, - vfs_read_retval); - } - - file_offset += vfs_read_retval; - frame_offset += vfs_read_retval; - - if (vfs_read_retval < line_size) { - pr_info("Done: exit %s() since no more bytes to read from Video file\n", - __func__); - break; - } - } - - if (i > 0) - dev->_frame_count_ch2++; - - dev->_file_status_ch2 = (vfs_read_retval == line_size) ? - IN_PROGRESS : END_OF_FILE; - - set_fs(old_fs); - filp_close(myfile, NULL); - } - - return 0; -} - -static void cx25821_vidups_handler_ch2(struct work_struct *work) -{ - struct cx25821_dev *dev = container_of(work, struct cx25821_dev, - _irq_work_entry_ch2); - - if (!dev) { - pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", - __func__); - return; - } - - cx25821_get_frame_ch2(dev, dev->channels[dev-> - _channel2_upstream_select].sram_channels); -} - -static int cx25821_openfile_ch2(struct cx25821_dev *dev, - const struct sram_channel *sram_ch) -{ - struct file *myfile; - int i = 0, j = 0; - int line_size = (dev->_pixel_format_ch2 == PIXEL_FRMT_411) ? - Y411_LINE_SZ : Y422_LINE_SZ; - ssize_t vfs_read_retval = 0; - char mybuf[line_size]; - loff_t pos; - loff_t offset = (unsigned long)0; - mm_segment_t old_fs; - - myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0); - - if (IS_ERR(myfile)) { - const int open_errno = -PTR_ERR(myfile); - pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", - __func__, dev->_filename_ch2, open_errno); - return PTR_ERR(myfile); - } else { - if (!(myfile->f_op)) { - pr_err("%s(): File has no file operations registered!\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - if (!myfile->f_op->read) { - pr_err("%s(): File has no READ operations registered! Returning\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - pos = myfile->f_pos; - old_fs = get_fs(); - set_fs(KERNEL_DS); - - for (j = 0; j < NUM_FRAMES; j++) { - for (i = 0; i < dev->_lines_count_ch2; i++) { - pos = offset; - - vfs_read_retval = vfs_read(myfile, mybuf, - line_size, &pos); - - if (vfs_read_retval > 0 && - vfs_read_retval == line_size && - dev->_data_buf_virt_addr_ch2 != NULL) { - memcpy((void *)(dev-> - _data_buf_virt_addr_ch2 - + offset / 4), mybuf, - vfs_read_retval); - } - - offset += vfs_read_retval; - - if (vfs_read_retval < line_size) { - pr_info("Done: exit %s() since no more bytes to read from Video file\n", - __func__); - break; - } - } - - if (i > 0) - dev->_frame_count_ch2++; - - if (vfs_read_retval < line_size) - break; - } - - dev->_file_status_ch2 = (vfs_read_retval == line_size) ? - IN_PROGRESS : END_OF_FILE; - - set_fs(old_fs); - myfile->f_pos = 0; - filp_close(myfile, NULL); - } - - return 0; -} - -static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev, - const struct sram_channel *sram_ch, - int bpl) -{ - int ret = 0; - dma_addr_t dma_addr; - dma_addr_t data_dma_addr; - - if (dev->_dma_virt_addr_ch2 != NULL) { - pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2, - dev->_dma_virt_addr_ch2, - dev->_dma_phys_addr_ch2); - } - - dev->_dma_virt_addr_ch2 = pci_alloc_consistent(dev->pci, - dev->upstream_riscbuf_size_ch2, &dma_addr); - dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2; - dev->_dma_phys_start_addr_ch2 = dma_addr; - dev->_dma_phys_addr_ch2 = dma_addr; - dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2; - - if (!dev->_dma_virt_addr_ch2) { - pr_err("FAILED to allocate memory for Risc buffer! Returning\n"); - return -ENOMEM; - } - - /* Iniitize at this address until n bytes to 0 */ - memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2); - - if (dev->_data_buf_virt_addr_ch2 != NULL) { - pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2, - dev->_data_buf_virt_addr_ch2, - dev->_data_buf_phys_addr_ch2); - } - /* For Video Data buffer allocation */ - dev->_data_buf_virt_addr_ch2 = pci_alloc_consistent(dev->pci, - dev->upstream_databuf_size_ch2, &data_dma_addr); - dev->_data_buf_phys_addr_ch2 = data_dma_addr; - dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2; - - if (!dev->_data_buf_virt_addr_ch2) { - pr_err("FAILED to allocate memory for data buffer! Returning\n"); - return -ENOMEM; - } - - /* Initialize at this address until n bytes to 0 */ - memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2); - - ret = cx25821_openfile_ch2(dev, sram_ch); - if (ret < 0) - return ret; - - /* Creating RISC programs */ - ret = cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl, - dev->_lines_count_ch2); - if (ret < 0) { - pr_info("Failed creating Video Upstream Risc programs!\n"); - goto error; - } - - return 0; - -error: - return ret; -} - -static int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, - int chan_num, - u32 status) -{ - u32 int_msk_tmp; - const struct sram_channel *channel = dev->channels[chan_num].sram_channels; - int singlefield_lines = NTSC_FIELD_HEIGHT; - int line_size_in_bytes = Y422_LINE_SZ; - int odd_risc_prog_size = 0; - dma_addr_t risc_phys_jump_addr; - __le32 *rp; - - if (status & FLD_VID_SRC_RISC1) { - /* We should only process one program per call */ - u32 prog_cnt = cx_read(channel->gpcnt); - - /* - * Since we've identified our IRQ, clear our bits from the - * interrupt mask and interrupt status registers - */ - int_msk_tmp = cx_read(channel->int_msk); - cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); - cx_write(channel->int_stat, _intr_msk); - - spin_lock(&dev->slock); - - dev->_frame_index_ch2 = prog_cnt; - - queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2); - - if (dev->_is_first_frame_ch2) { - dev->_is_first_frame_ch2 = 0; - - if (dev->_isNTSC_ch2) { - singlefield_lines += 1; - odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; - } else { - singlefield_lines = PAL_FIELD_HEIGHT; - odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; - } - - if (dev->_dma_virt_start_addr_ch2 != NULL) { - if (dev->_pixel_format_ch2 == PIXEL_FRMT_411) - line_size_in_bytes = Y411_LINE_SZ; - else - line_size_in_bytes = Y422_LINE_SZ; - risc_phys_jump_addr = - dev->_dma_phys_start_addr_ch2 + - odd_risc_prog_size; - - rp = cx25821_update_riscprogram_ch2(dev, - dev->_dma_virt_start_addr_ch2, - TOP_OFFSET, line_size_in_bytes, - 0x0, singlefield_lines, - FIFO_DISABLE, ODD_FIELD); - - /* Jump to Even Risc program of 1st Frame */ - *(rp++) = cpu_to_le32(RISC_JUMP); - *(rp++) = cpu_to_le32(risc_phys_jump_addr); - *(rp++) = cpu_to_le32(0); - } - } - - spin_unlock(&dev->slock); - } - - if (dev->_file_status_ch2 == END_OF_FILE) { - pr_info("EOF Channel 2 Framecount = %d\n", - dev->_frame_count_ch2); - return -1; - } - /* ElSE, set the interrupt mask register, re-enable irq. */ - int_msk_tmp = cx_read(channel->int_msk); - cx_write(channel->int_msk, int_msk_tmp |= _intr_msk); - - return 0; -} - -static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id) -{ - struct cx25821_dev *dev = dev_id; - u32 vid_status; - int handled = 0; - int channel_num = 0; - const struct sram_channel *sram_ch; - - if (!dev) - return -1; - - channel_num = VID_UPSTREAM_SRAM_CHANNEL_J; - sram_ch = dev->channels[channel_num].sram_channels; - - vid_status = cx_read(sram_ch->int_stat); - - /* Only deal with our interrupt */ - if (vid_status) - handled = cx25821_video_upstream_irq_ch2(dev, channel_num, - vid_status); - - if (handled < 0) - cx25821_stop_upstream_video_ch2(dev); - else - handled += handled; - - return IRQ_RETVAL(handled); -} - -static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev, - const struct sram_channel *ch, int pix_format) -{ - int width = WIDTH_D1; - int height = dev->_lines_count_ch2; - int num_lines, odd_num_lines; - u32 value; - int vip_mode = PIXEL_ENGINE_VIP1; - - value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7); - value &= 0xFFFFFFEF; - value |= dev->_isNTSC_ch2 ? 0 : 0x10; - cx_write(ch->vid_fmt_ctl, value); - - /* - * set number of active pixels in each line. Default is 720 - * pixels in both NTSC and PAL format - */ - cx_write(ch->vid_active_ctl1, width); - - num_lines = (height / 2) & 0x3FF; - odd_num_lines = num_lines; - - if (dev->_isNTSC_ch2) - odd_num_lines += 1; - - value = (num_lines << 16) | odd_num_lines; - - /* set number of active lines in field 0 (top) and field 1 (bottom) */ - cx_write(ch->vid_active_ctl2, value); - - cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); -} - -static int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev, - const struct sram_channel *sram_ch) -{ - u32 tmp = 0; - int err = 0; - - /* - * 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface - * for channel A-C - */ - tmp = cx_read(VID_CH_MODE_SEL); - cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); - - /* - * Set the physical start address of the RISC program in the initial - * program counter(IPC) member of the cmds. - */ - cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2); - cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */ - - /* reset counter */ - cx_write(sram_ch->gpcnt_ctl, 3); - - /* Clear our bits from the interrupt status register. */ - cx_write(sram_ch->int_stat, _intr_msk); - - /* Set the interrupt mask register, enable irq. */ - cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit)); - tmp = cx_read(sram_ch->int_msk); - cx_write(sram_ch->int_msk, tmp |= _intr_msk); - - err = request_irq(dev->pci->irq, cx25821_upstream_irq_ch2, - IRQF_SHARED, dev->name, dev); - if (err < 0) { - pr_err("%s: can't get upstream IRQ %d\n", - dev->name, dev->pci->irq); - goto fail_irq; - } - /* Start the DMA engine */ - tmp = cx_read(sram_ch->dma_ctl); - cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); - - dev->_is_running_ch2 = 1; - dev->_is_first_frame_ch2 = 1; - - return 0; - -fail_irq: - cx25821_dev_unregister(dev); - return err; -} - -int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select, - int pixel_format) -{ - const struct sram_channel *sram_ch; - u32 tmp; - int err = 0; - int data_frame_size = 0; - int risc_buffer_size = 0; - - if (dev->_is_running_ch2) { - pr_info("Video Channel is still running so return!\n"); - return 0; - } - - dev->_channel2_upstream_select = channel_select; - sram_ch = dev->channels[channel_select].sram_channels; - - INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2); - dev->_irq_queues_ch2 = - create_singlethread_workqueue("cx25821_workqueue2"); - - if (!dev->_irq_queues_ch2) { - pr_err("create_singlethread_workqueue() for Video FAILED!\n"); - return -ENOMEM; - } - /* - * 656/VIP SRC Upstream Channel I & J and 7 - - * Host Bus Interface for channel A-C - */ - tmp = cx_read(VID_CH_MODE_SEL); - cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); - - dev->_is_running_ch2 = 0; - dev->_frame_count_ch2 = 0; - dev->_file_status_ch2 = RESET_STATUS; - dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576; - dev->_pixel_format_ch2 = pixel_format; - dev->_line_size_ch2 = (dev->_pixel_format_ch2 == PIXEL_FRMT_422) ? - (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; - data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; - risc_buffer_size = dev->_isNTSC_ch2 ? - NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; - - if (dev->input_filename_ch2) - dev->_filename_ch2 = kstrdup(dev->input_filename_ch2, - GFP_KERNEL); - else - dev->_filename_ch2 = kstrdup(dev->_defaultname_ch2, - GFP_KERNEL); - - if (!dev->_filename_ch2) { - err = -ENOENT; - goto error; - } - - /* Default if filename is empty string */ - if (strcmp(dev->_filename_ch2, "") == 0) { - if (dev->_isNTSC_ch2) { - dev->_filename_ch2 = (dev->_pixel_format_ch2 == - PIXEL_FRMT_411) ? "/root/vid411.yuv" : - "/root/vidtest.yuv"; - } else { - dev->_filename_ch2 = (dev->_pixel_format_ch2 == - PIXEL_FRMT_411) ? "/root/pal411.yuv" : - "/root/pal422.yuv"; - } - } - - err = cx25821_sram_channel_setup_upstream(dev, sram_ch, - dev->_line_size_ch2, 0); - - /* setup fifo + format */ - cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2); - - dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2; - dev->upstream_databuf_size_ch2 = data_frame_size * 2; - - /* Allocating buffers and prepare RISC program */ - err = cx25821_upstream_buffer_prepare_ch2(dev, sram_ch, - dev->_line_size_ch2); - if (err < 0) { - pr_err("%s: Failed to set up Video upstream buffers!\n", - dev->name); - goto error; - } - - cx25821_start_video_dma_upstream_ch2(dev, sram_ch); - - return 0; - -error: - cx25821_dev_unregister(dev); - - return err; -} diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h b/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h deleted file mode 100644 index d42dab59b66..00000000000 --- a/drivers/media/pci/cx25821/cx25821-video-upstream-ch2.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Driver for the Conexant CX25821 PCIe bridge - * - * Copyright (C) 2009 Conexant Systems Inc. - * Authors , - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - -#define OPEN_FILE_1 0 -#define NUM_PROGS 8 -#define NUM_FRAMES 2 -#define ODD_FIELD 0 -#define EVEN_FIELD 1 -#define TOP_OFFSET 0 -#define FIFO_DISABLE 0 -#define FIFO_ENABLE 1 -#define TEST_FRAMES 5 -#define END_OF_FILE 0 -#define IN_PROGRESS 1 -#define RESET_STATUS -1 -#define NUM_NO_OPS 5 - -/* PAL and NTSC line sizes and number of lines. */ -#define WIDTH_D1 720 -#define NTSC_LINES_PER_FRAME 480 -#define PAL_LINES_PER_FRAME 576 -#define PAL_LINE_SZ 1440 -#define Y422_LINE_SZ 1440 -#define Y411_LINE_SZ 1080 -#define NTSC_FIELD_HEIGHT 240 -#define NTSC_ODD_FLD_LINES 241 -#define PAL_FIELD_HEIGHT 288 - -#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ) -#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ) -#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ) -#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ) - -#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME) -#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME) - -#define RISC_WRITECR_INSTRUCTION_SIZE 16 -#define RISC_SYNC_INSTRUCTION_SIZE 4 -#define JUMP_INSTRUCTION_SIZE 12 -#define MAXSIZE_NO_OPS 36 -#define DWORD_SIZE 4 - -#define USE_RISC_NOOP_VIDEO 1 - -#ifdef USE_RISC_NOOP_VIDEO -#define PAL_US_VID_PROG_SIZE \ - (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ - RISC_WRITECR_INSTRUCTION_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \ - NUM_NO_OPS * DWORD_SIZE) - -#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE) - -#define PAL_VID_PROG_SIZE \ - ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \ - 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ - JUMP_INSTRUCTION_SIZE + 2 * NUM_NO_OPS * DWORD_SIZE) - -#define ODD_FLD_PAL_PROG_SIZE \ - (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ - RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ - NUM_NO_OPS * DWORD_SIZE) - -#define NTSC_US_VID_PROG_SIZE \ - ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \ - RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \ - NUM_NO_OPS * DWORD_SIZE) - -#define NTSC_RISC_BUF_SIZE \ - (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) - -#define FRAME1_VID_PROG_SIZE \ - ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * \ - 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE + \ - RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + \ - 2 * NUM_NO_OPS * DWORD_SIZE) - -#define ODD_FLD_NTSC_PROG_SIZE \ - (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \ - RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ - NUM_NO_OPS * DWORD_SIZE) -#endif - -#ifndef USE_RISC_NOOP_VIDEO -#define PAL_US_VID_PROG_SIZE \ - ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + \ - RISC_WRITECR_INSTRUCTION_SIZE) - -#define PAL_RISC_BUF_SIZE \ - (2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE)) - -#define PAL_VID_PROG_SIZE \ - ((PAL_FIELD_HEIGHT * 2) * 3 * DWORD_SIZE + \ - 2 * RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \ - JUMP_INSTRUCTION_SIZE) - -#define ODD_FLD_PAL_PROG_SIZE \ - (PAL_FIELD_HEIGHT * 3 * DWORD_SIZE + \ - RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) - -#define ODD_FLD_NTSC_PROG_SIZE \ - (NTSC_ODD_FLD_LINES * 3 * DWORD_SIZE + \ - RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE) - -#define NTSC_US_VID_PROG_SIZE \ - ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + \ - RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) - -#define NTSC_RISC_BUF_SIZE \ - (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE)) - -#define FRAME1_VID_PROG_SIZE \ - ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * \ - 3 * DWORD_SIZE + 2 * RISC_SYNC_INSTRUCTION_SIZE + \ - RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE) - -#endif diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c index 223aae77c7e..37cfc834e5c 100644 --- a/drivers/media/pci/cx25821/cx25821-video-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c @@ -97,12 +97,13 @@ int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, return 0; } -static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev, +static __le32 *cx25821_update_riscprogram(struct cx25821_channel *chan, __le32 *rp, unsigned int offset, unsigned int bpl, u32 sync_line, unsigned int lines, int fifo_enable, int field_type) { + struct cx25821_video_out_data *out = chan->out; unsigned int line, i; int dist_betwn_starts = bpl * 2; @@ -116,11 +117,11 @@ static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev, /* scan lines */ for (line = 0; line < lines; line++) { *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl); - *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset); + *(rp++) = cpu_to_le32(out->_data_buf_phys_addr + offset); *(rp++) = cpu_to_le32(0); /* bits 63-32 */ if ((lines <= NTSC_FIELD_HEIGHT) - || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) { + || (line < (NTSC_FIELD_HEIGHT - 1)) || !(out->is_60hz)) { offset += dist_betwn_starts; } } @@ -128,15 +129,15 @@ static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev, return rp; } -static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, +static __le32 *cx25821_risc_field_upstream(struct cx25821_channel *chan, __le32 *rp, dma_addr_t databuf_phys_addr, unsigned int offset, u32 sync_line, unsigned int bpl, unsigned int lines, int fifo_enable, int field_type) { + struct cx25821_video_out_data *out = chan->out; unsigned int line, i; - const struct sram_channel *sram_ch = - dev->channels[dev->_channel_upstream_select].sram_channels; + const struct sram_channel *sram_ch = chan->sram_channels; int dist_betwn_starts = bpl * 2; /* sync instruction */ @@ -155,7 +156,7 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, *(rp++) = cpu_to_le32(0); /* bits 63-32 */ if ((lines <= NTSC_FIELD_HEIGHT) - || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) + || (line < (NTSC_FIELD_HEIGHT - 1)) || !(out->is_60hz)) /* to skip the other field line */ offset += dist_betwn_starts; @@ -173,11 +174,12 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp, return rp; } -static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, +static int cx25821_risc_buffer_upstream(struct cx25821_channel *chan, struct pci_dev *pci, unsigned int top_offset, unsigned int bpl, unsigned int lines) { + struct cx25821_video_out_data *out = chan->out; __le32 *rp; int fifo_enable = 0; /* get line count for single field */ @@ -191,7 +193,7 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, unsigned int bottom_offset = bpl; dma_addr_t risc_phys_jump_addr; - if (dev->_isNTSC) { + if (out->is_60hz) { odd_num_lines = singlefield_lines + 1; risc_program_size = FRAME1_VID_PROG_SIZE; frame_size = (bpl == Y411_LINE_SZ) ? @@ -203,15 +205,15 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, } /* Virtual address of Risc buffer program */ - rp = dev->_dma_virt_addr; + rp = out->_dma_virt_addr; for (frame = 0; frame < NUM_FRAMES; frame++) { databuf_offset = frame_size * frame; if (UNSET != top_offset) { fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE; - rp = cx25821_risc_field_upstream(dev, rp, - dev->_data_buf_phys_addr + + rp = cx25821_risc_field_upstream(chan, rp, + out->_data_buf_phys_addr + databuf_offset, top_offset, 0, bpl, odd_num_lines, fifo_enable, ODD_FIELD); } @@ -219,18 +221,18 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, fifo_enable = FIFO_DISABLE; /* Even Field */ - rp = cx25821_risc_field_upstream(dev, rp, - dev->_data_buf_phys_addr + + rp = cx25821_risc_field_upstream(chan, rp, + out->_data_buf_phys_addr + databuf_offset, bottom_offset, 0x200, bpl, singlefield_lines, fifo_enable, EVEN_FIELD); if (frame == 0) { risc_flag = RISC_CNT_RESET; - risc_phys_jump_addr = dev->_dma_phys_start_addr + + risc_phys_jump_addr = out->_dma_phys_start_addr + risc_program_size; } else { - risc_phys_jump_addr = dev->_dma_phys_start_addr; + risc_phys_jump_addr = out->_dma_phys_start_addr; risc_flag = RISC_CNT_INC; } @@ -245,13 +247,14 @@ static int cx25821_risc_buffer_upstream(struct cx25821_dev *dev, return 0; } -void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) +void cx25821_stop_upstream_video(struct cx25821_channel *chan) { - const struct sram_channel *sram_ch = - dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels; + struct cx25821_video_out_data *out = chan->out; + struct cx25821_dev *dev = chan->dev; + const struct sram_channel *sram_ch = chan->sram_channels; u32 tmp = 0; - if (!dev->_is_running) { + if (!out->_is_running) { pr_info("No video file is currently running so return!\n"); return; } @@ -264,49 +267,53 @@ void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev) cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); /* Clear data buffer memory */ - if (dev->_data_buf_virt_addr) - memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); + if (out->_data_buf_virt_addr) + memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); - dev->_is_running = 0; - dev->_is_first_frame = 0; - dev->_frame_count = 0; - dev->_file_status = END_OF_FILE; + out->_is_running = 0; + out->_is_first_frame = 0; + out->_frame_count = 0; + out->_file_status = END_OF_FILE; - kfree(dev->_irq_queues); - dev->_irq_queues = NULL; + destroy_workqueue(out->_irq_queues); + out->_irq_queues = NULL; - kfree(dev->_filename); + kfree(out->_filename); tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); } -void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev) +void cx25821_free_mem_upstream(struct cx25821_channel *chan) { - if (dev->_is_running) - cx25821_stop_upstream_video_ch1(dev); + struct cx25821_video_out_data *out = chan->out; + struct cx25821_dev *dev = chan->dev; - if (dev->_dma_virt_addr) { - pci_free_consistent(dev->pci, dev->_risc_size, - dev->_dma_virt_addr, dev->_dma_phys_addr); - dev->_dma_virt_addr = NULL; + if (out->_is_running) + cx25821_stop_upstream_video(chan); + + if (out->_dma_virt_addr) { + pci_free_consistent(dev->pci, out->_risc_size, + out->_dma_virt_addr, out->_dma_phys_addr); + out->_dma_virt_addr = NULL; } - if (dev->_data_buf_virt_addr) { - pci_free_consistent(dev->pci, dev->_data_buf_size, - dev->_data_buf_virt_addr, - dev->_data_buf_phys_addr); - dev->_data_buf_virt_addr = NULL; + if (out->_data_buf_virt_addr) { + pci_free_consistent(dev->pci, out->_data_buf_size, + out->_data_buf_virt_addr, + out->_data_buf_phys_addr); + out->_data_buf_virt_addr = NULL; } } -static int cx25821_get_frame(struct cx25821_dev *dev, +static int cx25821_get_frame(struct cx25821_channel *chan, const struct sram_channel *sram_ch) { + struct cx25821_video_out_data *out = chan->out; struct file *myfile; - int frame_index_temp = dev->_frame_index; + int frame_index_temp = out->_frame_index; int i = 0; - int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? + int line_size = (out->_pixel_format == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; int frame_size = 0; int frame_offset = 0; @@ -316,10 +323,10 @@ static int cx25821_get_frame(struct cx25821_dev *dev, loff_t pos; mm_segment_t old_fs; - if (dev->_file_status == END_OF_FILE) + if (out->_file_status == END_OF_FILE) return 0; - if (dev->_isNTSC) + if (out->is_60hz) frame_size = (line_size == Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422; else @@ -327,14 +334,14 @@ static int cx25821_get_frame(struct cx25821_dev *dev, FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; frame_offset = (frame_index_temp > 0) ? frame_size : 0; - file_offset = dev->_frame_count * frame_size; + file_offset = out->_frame_count * frame_size; - myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0); + myfile = filp_open(out->_filename, O_RDONLY | O_LARGEFILE, 0); if (IS_ERR(myfile)) { const int open_errno = -PTR_ERR(myfile); pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", - __func__, dev->_filename, open_errno); + __func__, out->_filename, open_errno); return PTR_ERR(myfile); } else { if (!(myfile->f_op)) { @@ -355,15 +362,15 @@ static int cx25821_get_frame(struct cx25821_dev *dev, old_fs = get_fs(); set_fs(KERNEL_DS); - for (i = 0; i < dev->_lines_count; i++) { + for (i = 0; i < out->_lines_count; i++) { pos = file_offset; vfs_read_retval = vfs_read(myfile, mybuf, line_size, &pos); if (vfs_read_retval > 0 && vfs_read_retval == line_size - && dev->_data_buf_virt_addr != NULL) { - memcpy((void *)(dev->_data_buf_virt_addr + + && out->_data_buf_virt_addr != NULL) { + memcpy((void *)(out->_data_buf_virt_addr + frame_offset / 4), mybuf, vfs_read_retval); } @@ -379,9 +386,9 @@ static int cx25821_get_frame(struct cx25821_dev *dev, } if (i > 0) - dev->_frame_count++; + out->_frame_count++; - dev->_file_status = (vfs_read_retval == line_size) ? + out->_file_status = (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; set_fs(old_fs); @@ -393,25 +400,19 @@ static int cx25821_get_frame(struct cx25821_dev *dev, static void cx25821_vidups_handler(struct work_struct *work) { - struct cx25821_dev *dev = container_of(work, struct cx25821_dev, - _irq_work_entry); - - if (!dev) { - pr_err("ERROR %s(): since container_of(work_struct) FAILED!\n", - __func__); - return; - } + struct cx25821_video_out_data *out = + container_of(work, struct cx25821_video_out_data, _irq_work_entry); - cx25821_get_frame(dev, dev->channels[dev->_channel_upstream_select]. - sram_channels); + cx25821_get_frame(out->chan, out->chan->sram_channels); } -static int cx25821_openfile(struct cx25821_dev *dev, +static int cx25821_openfile(struct cx25821_channel *chan, const struct sram_channel *sram_ch) { + struct cx25821_video_out_data *out = chan->out; struct file *myfile; int i = 0, j = 0; - int line_size = (dev->_pixel_format == PIXEL_FRMT_411) ? + int line_size = (out->_pixel_format == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; ssize_t vfs_read_retval = 0; char mybuf[line_size]; @@ -419,12 +420,12 @@ static int cx25821_openfile(struct cx25821_dev *dev, loff_t offset = (unsigned long)0; mm_segment_t old_fs; - myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0); + myfile = filp_open(out->_filename, O_RDONLY | O_LARGEFILE, 0); if (IS_ERR(myfile)) { const int open_errno = -PTR_ERR(myfile); pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", - __func__, dev->_filename, open_errno); + __func__, out->_filename, open_errno); return PTR_ERR(myfile); } else { if (!(myfile->f_op)) { @@ -446,7 +447,7 @@ static int cx25821_openfile(struct cx25821_dev *dev, set_fs(KERNEL_DS); for (j = 0; j < NUM_FRAMES; j++) { - for (i = 0; i < dev->_lines_count; i++) { + for (i = 0; i < out->_lines_count; i++) { pos = offset; vfs_read_retval = vfs_read(myfile, mybuf, @@ -454,8 +455,8 @@ static int cx25821_openfile(struct cx25821_dev *dev, if (vfs_read_retval > 0 && vfs_read_retval == line_size - && dev->_data_buf_virt_addr != NULL) { - memcpy((void *)(dev-> + && out->_data_buf_virt_addr != NULL) { + memcpy((void *)(out-> _data_buf_virt_addr + offset / 4), mybuf, vfs_read_retval); @@ -471,13 +472,13 @@ static int cx25821_openfile(struct cx25821_dev *dev, } if (i > 0) - dev->_frame_count++; + out->_frame_count++; if (vfs_read_retval < line_size) break; } - dev->_file_status = (vfs_read_retval == line_size) ? + out->_file_status = (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE; set_fs(old_fs); @@ -488,58 +489,60 @@ static int cx25821_openfile(struct cx25821_dev *dev, return 0; } -static int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev, +static int cx25821_upstream_buffer_prepare(struct cx25821_channel *chan, const struct sram_channel *sram_ch, int bpl) { + struct cx25821_video_out_data *out = chan->out; + struct cx25821_dev *dev = chan->dev; int ret = 0; dma_addr_t dma_addr; dma_addr_t data_dma_addr; - if (dev->_dma_virt_addr != NULL) - pci_free_consistent(dev->pci, dev->upstream_riscbuf_size, - dev->_dma_virt_addr, dev->_dma_phys_addr); + if (out->_dma_virt_addr != NULL) + pci_free_consistent(dev->pci, out->upstream_riscbuf_size, + out->_dma_virt_addr, out->_dma_phys_addr); - dev->_dma_virt_addr = pci_alloc_consistent(dev->pci, - dev->upstream_riscbuf_size, &dma_addr); - dev->_dma_virt_start_addr = dev->_dma_virt_addr; - dev->_dma_phys_start_addr = dma_addr; - dev->_dma_phys_addr = dma_addr; - dev->_risc_size = dev->upstream_riscbuf_size; + out->_dma_virt_addr = pci_alloc_consistent(dev->pci, + out->upstream_riscbuf_size, &dma_addr); + out->_dma_virt_start_addr = out->_dma_virt_addr; + out->_dma_phys_start_addr = dma_addr; + out->_dma_phys_addr = dma_addr; + out->_risc_size = out->upstream_riscbuf_size; - if (!dev->_dma_virt_addr) { + if (!out->_dma_virt_addr) { pr_err("FAILED to allocate memory for Risc buffer! Returning\n"); return -ENOMEM; } /* Clear memory at address */ - memset(dev->_dma_virt_addr, 0, dev->_risc_size); + memset(out->_dma_virt_addr, 0, out->_risc_size); - if (dev->_data_buf_virt_addr != NULL) - pci_free_consistent(dev->pci, dev->upstream_databuf_size, - dev->_data_buf_virt_addr, - dev->_data_buf_phys_addr); + if (out->_data_buf_virt_addr != NULL) + pci_free_consistent(dev->pci, out->upstream_databuf_size, + out->_data_buf_virt_addr, + out->_data_buf_phys_addr); /* For Video Data buffer allocation */ - dev->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, - dev->upstream_databuf_size, &data_dma_addr); - dev->_data_buf_phys_addr = data_dma_addr; - dev->_data_buf_size = dev->upstream_databuf_size; + out->_data_buf_virt_addr = pci_alloc_consistent(dev->pci, + out->upstream_databuf_size, &data_dma_addr); + out->_data_buf_phys_addr = data_dma_addr; + out->_data_buf_size = out->upstream_databuf_size; - if (!dev->_data_buf_virt_addr) { + if (!out->_data_buf_virt_addr) { pr_err("FAILED to allocate memory for data buffer! Returning\n"); return -ENOMEM; } /* Clear memory at address */ - memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size); + memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); - ret = cx25821_openfile(dev, sram_ch); + ret = cx25821_openfile(chan, sram_ch); if (ret < 0) return ret; /* Create RISC programs */ - ret = cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl, - dev->_lines_count); + ret = cx25821_risc_buffer_upstream(chan, dev->pci, 0, bpl, + out->_lines_count); if (ret < 0) { pr_info("Failed creating Video Upstream Risc programs!\n"); goto error; @@ -551,11 +554,12 @@ error: return ret; } -static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, - u32 status) +static int cx25821_video_upstream_irq(struct cx25821_channel *chan, u32 status) { + struct cx25821_video_out_data *out = chan->out; + struct cx25821_dev *dev = chan->dev; u32 int_msk_tmp; - const struct sram_channel *channel = dev->channels[chan_num].sram_channels; + const struct sram_channel *channel = chan->sram_channels; int singlefield_lines = NTSC_FIELD_HEIGHT; int line_size_in_bytes = Y422_LINE_SZ; int odd_risc_prog_size = 0; @@ -574,14 +578,14 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, spin_lock(&dev->slock); - dev->_frame_index = prog_cnt; + out->_frame_index = prog_cnt; - queue_work(dev->_irq_queues, &dev->_irq_work_entry); + queue_work(out->_irq_queues, &out->_irq_work_entry); - if (dev->_is_first_frame) { - dev->_is_first_frame = 0; + if (out->_is_first_frame) { + out->_is_first_frame = 0; - if (dev->_isNTSC) { + if (out->is_60hz) { singlefield_lines += 1; odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE; } else { @@ -589,17 +593,17 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE; } - if (dev->_dma_virt_start_addr != NULL) { + if (out->_dma_virt_start_addr != NULL) { line_size_in_bytes = - (dev->_pixel_format == + (out->_pixel_format == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; risc_phys_jump_addr = - dev->_dma_phys_start_addr + + out->_dma_phys_start_addr + odd_risc_prog_size; - rp = cx25821_update_riscprogram(dev, - dev->_dma_virt_start_addr, TOP_OFFSET, + rp = cx25821_update_riscprogram(chan, + out->_dma_virt_start_addr, TOP_OFFSET, line_size_in_bytes, 0x0, singlefield_lines, FIFO_DISABLE, ODD_FIELD); @@ -626,8 +630,8 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, __func__); } - if (dev->_file_status == END_OF_FILE) { - pr_err("EOF Channel 1 Framecount = %d\n", dev->_frame_count); + if (out->_file_status == END_OF_FILE) { + pr_err("EOF Channel 1 Framecount = %d\n", out->_frame_count); return -1; } /* ElSE, set the interrupt mask register, re-enable irq. */ @@ -639,47 +643,41 @@ static int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num, static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id) { - struct cx25821_dev *dev = dev_id; + struct cx25821_channel *chan = dev_id; + struct cx25821_dev *dev = chan->dev; u32 vid_status; int handled = 0; - int channel_num = 0; const struct sram_channel *sram_ch; if (!dev) return -1; - channel_num = VID_UPSTREAM_SRAM_CHANNEL_I; - - sram_ch = dev->channels[channel_num].sram_channels; + sram_ch = chan->sram_channels; vid_status = cx_read(sram_ch->int_stat); /* Only deal with our interrupt */ if (vid_status) - handled = cx25821_video_upstream_irq(dev, channel_num, - vid_status); - - if (handled < 0) - cx25821_stop_upstream_video_ch1(dev); - else - handled += handled; + handled = cx25821_video_upstream_irq(chan, vid_status); return IRQ_RETVAL(handled); } -static void cx25821_set_pixelengine(struct cx25821_dev *dev, +static void cx25821_set_pixelengine(struct cx25821_channel *chan, const struct sram_channel *ch, int pix_format) { + struct cx25821_video_out_data *out = chan->out; + struct cx25821_dev *dev = chan->dev; int width = WIDTH_D1; - int height = dev->_lines_count; + int height = out->_lines_count; int num_lines, odd_num_lines; u32 value; int vip_mode = OUTPUT_FRMT_656; value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7); value &= 0xFFFFFFEF; - value |= dev->_isNTSC ? 0 : 0x10; + value |= out->is_60hz ? 0 : 0x10; cx_write(ch->vid_fmt_ctl, value); /* set number of active pixels in each line. @@ -689,7 +687,7 @@ static void cx25821_set_pixelengine(struct cx25821_dev *dev, num_lines = (height / 2) & 0x3FF; odd_num_lines = num_lines; - if (dev->_isNTSC) + if (out->is_60hz) odd_num_lines += 1; value = (num_lines << 16) | odd_num_lines; @@ -700,9 +698,11 @@ static void cx25821_set_pixelengine(struct cx25821_dev *dev, cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3); } -static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, +static int cx25821_start_video_dma_upstream(struct cx25821_channel *chan, const struct sram_channel *sram_ch) { + struct cx25821_video_out_data *out = chan->out; + struct cx25821_dev *dev = chan->dev; u32 tmp = 0; int err = 0; @@ -715,7 +715,7 @@ static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, /* Set the physical start address of the RISC program in the initial * program counter(IPC) member of the cmds. */ - cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr); + cx_write(sram_ch->cmds_start + 0, out->_dma_phys_addr); /* Risc IPC High 64 bits 63-32 */ cx_write(sram_ch->cmds_start + 4, 0); @@ -731,7 +731,7 @@ static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, cx_write(sram_ch->int_msk, tmp |= _intr_msk); err = request_irq(dev->pci->irq, cx25821_upstream_irq, - IRQF_SHARED, dev->name, dev); + IRQF_SHARED, dev->name, chan); if (err < 0) { pr_err("%s: can't get upstream IRQ %d\n", dev->name, dev->pci->irq); @@ -742,8 +742,8 @@ static int cx25821_start_video_dma_upstream(struct cx25821_dev *dev, tmp = cx_read(sram_ch->dma_ctl); cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN); - dev->_is_running = 1; - dev->_is_first_frame = 1; + out->_is_running = 1; + out->_is_first_frame = 1; return 0; @@ -752,9 +752,11 @@ fail_irq: return err; } -int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, +int cx25821_vidupstream_init(struct cx25821_channel *chan, int pixel_format) { + struct cx25821_video_out_data *out = chan->out; + struct cx25821_dev *dev = chan->dev; const struct sram_channel *sram_ch; u32 tmp; int err = 0; @@ -762,18 +764,17 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, int risc_buffer_size = 0; int str_length = 0; - if (dev->_is_running) { + if (out->_is_running) { pr_info("Video Channel is still running so return!\n"); return 0; } - dev->_channel_upstream_select = channel_select; - sram_ch = dev->channels[channel_select].sram_channels; + sram_ch = chan->sram_channels; - INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler); - dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue"); + INIT_WORK(&out->_irq_work_entry, cx25821_vidups_handler); + out->_irq_queues = create_singlethread_workqueue("cx25821_workqueue"); - if (!dev->_irq_queues) { + if (!out->_irq_queues) { pr_err("create_singlethread_workqueue() for Video FAILED!\n"); return -ENOMEM; } @@ -783,76 +784,76 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select, tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF); - dev->_is_running = 0; - dev->_frame_count = 0; - dev->_file_status = RESET_STATUS; - dev->_lines_count = dev->_isNTSC ? 480 : 576; - dev->_pixel_format = pixel_format; - dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? + out->_is_running = 0; + out->_frame_count = 0; + out->_file_status = RESET_STATUS; + out->_lines_count = out->is_60hz ? 480 : 576; + out->_pixel_format = pixel_format; + out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; - data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; - risc_buffer_size = dev->_isNTSC ? + data_frame_size = out->is_60hz ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ; + risc_buffer_size = out->is_60hz ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; - if (dev->input_filename) { - str_length = strlen(dev->input_filename); - dev->_filename = kmemdup(dev->input_filename, str_length + 1, + if (out->input_filename) { + str_length = strlen(out->input_filename); + out->_filename = kmemdup(out->input_filename, str_length + 1, GFP_KERNEL); - if (!dev->_filename) { + if (!out->_filename) { err = -ENOENT; goto error; } } else { - str_length = strlen(dev->_defaultname); - dev->_filename = kmemdup(dev->_defaultname, str_length + 1, + str_length = strlen(out->_defaultname); + out->_filename = kmemdup(out->_defaultname, str_length + 1, GFP_KERNEL); - if (!dev->_filename) { + if (!out->_filename) { err = -ENOENT; goto error; } } /* Default if filename is empty string */ - if (strcmp(dev->_filename, "") == 0) { - if (dev->_isNTSC) { - dev->_filename = - (dev->_pixel_format == PIXEL_FRMT_411) ? + if (strcmp(out->_filename, "") == 0) { + if (out->is_60hz) { + out->_filename = + (out->_pixel_format == PIXEL_FRMT_411) ? "/root/vid411.yuv" : "/root/vidtest.yuv"; } else { - dev->_filename = - (dev->_pixel_format == PIXEL_FRMT_411) ? + out->_filename = + (out->_pixel_format == PIXEL_FRMT_411) ? "/root/pal411.yuv" : "/root/pal422.yuv"; } } - dev->_is_running = 0; - dev->_frame_count = 0; - dev->_file_status = RESET_STATUS; - dev->_lines_count = dev->_isNTSC ? 480 : 576; - dev->_pixel_format = pixel_format; - dev->_line_size = (dev->_pixel_format == PIXEL_FRMT_422) ? + out->_is_running = 0; + out->_frame_count = 0; + out->_file_status = RESET_STATUS; + out->_lines_count = out->is_60hz ? 480 : 576; + out->_pixel_format = pixel_format; + out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; err = cx25821_sram_channel_setup_upstream(dev, sram_ch, - dev->_line_size, 0); + out->_line_size, 0); /* setup fifo + format */ - cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format); + cx25821_set_pixelengine(chan, sram_ch, out->_pixel_format); - dev->upstream_riscbuf_size = risc_buffer_size * 2; - dev->upstream_databuf_size = data_frame_size * 2; + out->upstream_riscbuf_size = risc_buffer_size * 2; + out->upstream_databuf_size = data_frame_size * 2; /* Allocating buffers and prepare RISC program */ - err = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size); + err = cx25821_upstream_buffer_prepare(chan, sram_ch, out->_line_size); if (err < 0) { pr_err("%s: Failed to set up Video upstream buffers!\n", dev->name); goto error; } - cx25821_start_video_dma_upstream(dev, sram_ch); + cx25821_start_video_dma_upstream(chan, sram_ch); return 0; diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index 70e33b12596..dde0ba3d340 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -893,6 +893,20 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv, return 0; } +static int video_out_release(struct file *file) +{ + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_video_out_data *out = chan->out; + struct cx25821_dev *dev = chan->dev; + + mutex_lock(&dev->lock); + if ((chan->id == SRAM_CH09 || chan->id == SRAM_CH10) && out->_is_running) + cx25821_stop_upstream_video(chan); + mutex_unlock(&dev->lock); + + return v4l2_fh_release(file); +} + static const struct v4l2_ctrl_ops cx25821_ctrl_ops = { .s_ctrl = cx25821_s_ctrl, }; @@ -941,7 +955,7 @@ static const struct video_device cx25821_video_device = { static const struct v4l2_file_operations video_out_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, - .release = v4l2_fh_release, + .release = video_out_release, .unlocked_ioctl = video_ioctl2, }; @@ -1017,6 +1031,9 @@ int cx25821_video_register(struct cx25821_dev *dev) err = v4l2_ctrl_handler_setup(hdl); if (err) goto fail_unreg; + } else { + chan->out = &dev->vid_out_data[i - SRAM_CH09]; + chan->out->chan = chan; } cx25821_risc_stopper(dev->pci, &chan->dma_vidq.stopper, diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index 156ad6f2c63..b0bc2e626ae 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -172,6 +172,42 @@ struct cx25821_data { struct cx25821_dev; +struct cx25821_channel; + +struct cx25821_video_out_data { + struct cx25821_channel *chan; + int _line_size; + int _prog_cnt; + int _pixel_format; + int _is_first_frame; + int _is_running; + int _file_status; + int _lines_count; + int _frame_count; + unsigned int _risc_size; + + __le32 *_dma_virt_start_addr; + __le32 *_dma_virt_addr; + dma_addr_t _dma_phys_addr; + dma_addr_t _dma_phys_start_addr; + + unsigned int _data_buf_size; + __le32 *_data_buf_virt_addr; + dma_addr_t _data_buf_phys_addr; + + u32 upstream_riscbuf_size; + u32 upstream_databuf_size; + struct workqueue_struct *_irq_queues; + struct work_struct _irq_work_entry; + int is_60hz; + int _frame_index; + char *input_filename; + char *vid_stdname; + int pixel_format; + char *_filename; + char *_defaultname; +}; + struct cx25821_channel { unsigned id; struct cx25821_dev *dev; @@ -191,6 +227,9 @@ struct cx25821_channel { int pixel_formats; int use_cif_resolution; int cif_width; + + /* video output data for the video output channel */ + struct cx25821_video_out_data *out; }; struct snd_card; @@ -250,83 +289,18 @@ struct cx25821_dev { __le32 *_audiodata_buf_virt_addr; dma_addr_t _audiodata_buf_phys_addr; char *_audiofilename; - - /* V4l */ - spinlock_t slock; - - /* Video Upstream */ - int _line_size; - int _prog_cnt; - int _pixel_format; - int _is_first_frame; - int _is_running; - int _file_status; - int _lines_count; - int _frame_count; - int _channel_upstream_select; - unsigned int _risc_size; - - __le32 *_dma_virt_start_addr; - __le32 *_dma_virt_addr; - dma_addr_t _dma_phys_addr; - dma_addr_t _dma_phys_start_addr; - - unsigned int _data_buf_size; - __le32 *_data_buf_virt_addr; - dma_addr_t _data_buf_phys_addr; - char *_filename; - char *_defaultname; - - int _line_size_ch2; - int _prog_cnt_ch2; - int _pixel_format_ch2; - int _is_first_frame_ch2; - int _is_running_ch2; - int _file_status_ch2; - int _lines_count_ch2; - int _frame_count_ch2; - int _channel2_upstream_select; - unsigned int _risc_size_ch2; - - __le32 *_dma_virt_start_addr_ch2; - __le32 *_dma_virt_addr_ch2; - dma_addr_t _dma_phys_addr_ch2; - dma_addr_t _dma_phys_start_addr_ch2; - - unsigned int _data_buf_size_ch2; - __le32 *_data_buf_virt_addr_ch2; - dma_addr_t _data_buf_phys_addr_ch2; - char *_filename_ch2; - char *_defaultname_ch2; - - u32 upstream_riscbuf_size; - u32 upstream_databuf_size; - u32 upstream_riscbuf_size_ch2; - u32 upstream_databuf_size_ch2; u32 audio_upstream_riscbuf_size; u32 audio_upstream_databuf_size; - int _isNTSC; - int _frame_index; int _audioframe_index; - struct workqueue_struct *_irq_queues; - struct work_struct _irq_work_entry; - struct workqueue_struct *_irq_queues_ch2; - struct work_struct _irq_work_entry_ch2; struct workqueue_struct *_irq_audio_queues; struct work_struct _audio_work_entry; - char *input_filename; - char *input_filename_ch2; - int _frame_index_ch2; - int _isNTSC_ch2; - char *vid_stdname_ch2; - int pixel_format_ch2; - int channel_select_ch2; - int command_ch2; char *input_audiofilename; - char *vid_stdname; - int pixel_format; - int channel_select; - int command; + + /* V4l */ + spinlock_t slock; + + /* Video Upstream */ + struct cx25821_video_out_data vid_out_data[2]; }; static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev) @@ -463,17 +437,12 @@ extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, const struct sram_channel *ch, unsigned int bpl, u32 risc); -extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, - int channel_select, int pixel_format); -extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, - int channel_select, int pixel_format); +extern int cx25821_vidupstream_init(struct cx25821_channel *chan, int pixel_format); extern int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select); -extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev); -extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev); +extern void cx25821_free_mem_upstream(struct cx25821_channel *chan); extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); -extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev); -extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev); +extern void cx25821_stop_upstream_video(struct cx25821_channel *chan); extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev); extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev, const struct sram_channel *ch, -- cgit v1.2.3-70-g09d2 From ea3f7ac6e931f9aaa45e0a8445406f14e2a62011 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 12:02:19 -0300 Subject: [media] cx25821: replace custom ioctls with write() Ideally this should be implemented with vb2, but it'll do for now. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/cx25821-core.c | 3 +- drivers/media/pci/cx25821/cx25821-video-upstream.c | 248 +++------------------ drivers/media/pci/cx25821/cx25821-video.c | 37 ++- drivers/media/pci/cx25821/cx25821.h | 12 +- 4 files changed, 72 insertions(+), 228 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 230bd864157..35bea792b5e 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -775,8 +775,8 @@ void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select, if (channel_select <= 7 && channel_select >= 0) { cx_write(dev->channels[channel_select].sram_channels->pix_frmt, format); - dev->channels[channel_select].pixel_formats = format; } + dev->channels[channel_select].pixel_formats = format; } static void cx25821_set_vip_mode(struct cx25821_dev *dev, @@ -820,6 +820,7 @@ static void cx25821_initialize(struct cx25821_dev *dev) /* Probably only affect Downstream */ for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J; i++) { + dev->channels[i].pixel_formats = PIXEL_FRMT_422; cx25821_set_vip_mode(dev, dev->channels[i].sram_channels); } diff --git a/drivers/media/pci/cx25821/cx25821-video-upstream.c b/drivers/media/pci/cx25821/cx25821-video-upstream.c index 37cfc834e5c..88ffef410c5 100644 --- a/drivers/media/pci/cx25821/cx25821-video-upstream.c +++ b/drivers/media/pci/cx25821/cx25821-video-upstream.c @@ -25,16 +25,11 @@ #include "cx25821-video.h" #include "cx25821-video-upstream.h" -#include #include #include #include #include -#include -#include -#include #include -#include MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); MODULE_AUTHOR("Hiep Huynh "); @@ -258,6 +253,10 @@ void cx25821_stop_upstream_video(struct cx25821_channel *chan) pr_info("No video file is currently running so return!\n"); return; } + + /* Set the interrupt mask register, disable irq. */ + cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) & ~(1 << sram_ch->irq_bit)); + /* Disable RISC interrupts */ tmp = cx_read(sram_ch->int_msk); cx_write(sram_ch->int_msk, tmp & ~_intr_msk); @@ -266,6 +265,8 @@ void cx25821_stop_upstream_video(struct cx25821_channel *chan) tmp = cx_read(sram_ch->dma_ctl); cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN)); + free_irq(dev->pci->irq, chan); + /* Clear data buffer memory */ if (out->_data_buf_virt_addr) memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); @@ -275,11 +276,6 @@ void cx25821_stop_upstream_video(struct cx25821_channel *chan) out->_frame_count = 0; out->_file_status = END_OF_FILE; - destroy_workqueue(out->_irq_queues); - out->_irq_queues = NULL; - - kfree(out->_filename); - tmp = cx_read(VID_CH_MODE_SEL); cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00); } @@ -306,25 +302,15 @@ void cx25821_free_mem_upstream(struct cx25821_channel *chan) } } -static int cx25821_get_frame(struct cx25821_channel *chan, - const struct sram_channel *sram_ch) +int cx25821_write_frame(struct cx25821_channel *chan, + const char __user *data, size_t count) { struct cx25821_video_out_data *out = chan->out; - struct file *myfile; - int frame_index_temp = out->_frame_index; - int i = 0; int line_size = (out->_pixel_format == PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ; int frame_size = 0; int frame_offset = 0; - ssize_t vfs_read_retval = 0; - char mybuf[line_size]; - loff_t file_offset; - loff_t pos; - mm_segment_t old_fs; - - if (out->_file_status == END_OF_FILE) - return 0; + int curpos = out->curpos; if (out->is_60hz) frame_size = (line_size == Y411_LINE_SZ) ? @@ -333,160 +319,27 @@ static int cx25821_get_frame(struct cx25821_channel *chan, frame_size = (line_size == Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422; - frame_offset = (frame_index_temp > 0) ? frame_size : 0; - file_offset = out->_frame_count * frame_size; - - myfile = filp_open(out->_filename, O_RDONLY | O_LARGEFILE, 0); - - if (IS_ERR(myfile)) { - const int open_errno = -PTR_ERR(myfile); - pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", - __func__, out->_filename, open_errno); - return PTR_ERR(myfile); - } else { - if (!(myfile->f_op)) { - pr_err("%s(): File has no file operations registered!\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - if (!myfile->f_op->read) { - pr_err("%s(): File has no READ operations registered!\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - pos = myfile->f_pos; - old_fs = get_fs(); - set_fs(KERNEL_DS); - - for (i = 0; i < out->_lines_count; i++) { - pos = file_offset; - - vfs_read_retval = vfs_read(myfile, mybuf, line_size, - &pos); - - if (vfs_read_retval > 0 && vfs_read_retval == line_size - && out->_data_buf_virt_addr != NULL) { - memcpy((void *)(out->_data_buf_virt_addr + - frame_offset / 4), mybuf, - vfs_read_retval); - } - - file_offset += vfs_read_retval; - frame_offset += vfs_read_retval; - - if (vfs_read_retval < line_size) { - pr_info("Done: exit %s() since no more bytes to read from Video file\n", - __func__); - break; - } - } - - if (i > 0) - out->_frame_count++; - - out->_file_status = (vfs_read_retval == line_size) ? - IN_PROGRESS : END_OF_FILE; - - set_fs(old_fs); - filp_close(myfile, NULL); + if (curpos == 0) { + out->cur_frame_index = out->_frame_index; + if (wait_event_interruptible(out->waitq, out->cur_frame_index != out->_frame_index)) + return -EINTR; + out->cur_frame_index = out->_frame_index; } - return 0; -} - -static void cx25821_vidups_handler(struct work_struct *work) -{ - struct cx25821_video_out_data *out = - container_of(work, struct cx25821_video_out_data, _irq_work_entry); - - cx25821_get_frame(out->chan, out->chan->sram_channels); -} + frame_offset = out->cur_frame_index ? frame_size : 0; -static int cx25821_openfile(struct cx25821_channel *chan, - const struct sram_channel *sram_ch) -{ - struct cx25821_video_out_data *out = chan->out; - struct file *myfile; - int i = 0, j = 0; - int line_size = (out->_pixel_format == PIXEL_FRMT_411) ? - Y411_LINE_SZ : Y422_LINE_SZ; - ssize_t vfs_read_retval = 0; - char mybuf[line_size]; - loff_t pos; - loff_t offset = (unsigned long)0; - mm_segment_t old_fs; - - myfile = filp_open(out->_filename, O_RDONLY | O_LARGEFILE, 0); - - if (IS_ERR(myfile)) { - const int open_errno = -PTR_ERR(myfile); - pr_err("%s(): ERROR opening file(%s) with errno = %d!\n", - __func__, out->_filename, open_errno); - return PTR_ERR(myfile); - } else { - if (!(myfile->f_op)) { - pr_err("%s(): File has no file operations registered!\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - if (!myfile->f_op->read) { - pr_err("%s(): File has no READ operations registered! Returning\n", - __func__); - filp_close(myfile, NULL); - return -EIO; - } - - pos = myfile->f_pos; - old_fs = get_fs(); - set_fs(KERNEL_DS); - - for (j = 0; j < NUM_FRAMES; j++) { - for (i = 0; i < out->_lines_count; i++) { - pos = offset; - - vfs_read_retval = vfs_read(myfile, mybuf, - line_size, &pos); - - if (vfs_read_retval > 0 - && vfs_read_retval == line_size - && out->_data_buf_virt_addr != NULL) { - memcpy((void *)(out-> - _data_buf_virt_addr + - offset / 4), mybuf, - vfs_read_retval); - } - - offset += vfs_read_retval; - - if (vfs_read_retval < line_size) { - pr_info("Done: exit %s() since no more bytes to read from Video file\n", - __func__); - break; - } - } - - if (i > 0) - out->_frame_count++; - - if (vfs_read_retval < line_size) - break; - } - - out->_file_status = (vfs_read_retval == line_size) ? - IN_PROGRESS : END_OF_FILE; - - set_fs(old_fs); - myfile->f_pos = 0; - filp_close(myfile, NULL); + if (frame_size - curpos < count) + count = frame_size - curpos; + memcpy((char *)out->_data_buf_virt_addr + frame_offset + curpos, + data, count); + curpos += count; + if (curpos == frame_size) { + out->_frame_count++; + curpos = 0; } + out->curpos = curpos; - return 0; + return count; } static int cx25821_upstream_buffer_prepare(struct cx25821_channel *chan, @@ -536,10 +389,6 @@ static int cx25821_upstream_buffer_prepare(struct cx25821_channel *chan, /* Clear memory at address */ memset(out->_data_buf_virt_addr, 0, out->_data_buf_size); - ret = cx25821_openfile(chan, sram_ch); - if (ret < 0) - return ret; - /* Create RISC programs */ ret = cx25821_risc_buffer_upstream(chan, dev->pci, 0, bpl, out->_lines_count); @@ -576,12 +425,12 @@ static int cx25821_video_upstream_irq(struct cx25821_channel *chan, u32 status) cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk); cx_write(channel->int_stat, _intr_msk); + wake_up(&out->waitq); + spin_lock(&dev->slock); out->_frame_index = prog_cnt; - queue_work(out->_irq_queues, &out->_irq_work_entry); - if (out->_is_first_frame) { out->_is_first_frame = 0; @@ -762,7 +611,6 @@ int cx25821_vidupstream_init(struct cx25821_channel *chan, int err = 0; int data_frame_size = 0; int risc_buffer_size = 0; - int str_length = 0; if (out->_is_running) { pr_info("Video Channel is still running so return!\n"); @@ -771,13 +619,8 @@ int cx25821_vidupstream_init(struct cx25821_channel *chan, sram_ch = chan->sram_channels; - INIT_WORK(&out->_irq_work_entry, cx25821_vidups_handler); - out->_irq_queues = create_singlethread_workqueue("cx25821_workqueue"); + out->is_60hz = dev->tvnorm & V4L2_STD_525_60; - if (!out->_irq_queues) { - pr_err("create_singlethread_workqueue() for Video FAILED!\n"); - return -ENOMEM; - } /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for * channel A-C */ @@ -795,39 +638,6 @@ int cx25821_vidupstream_init(struct cx25821_channel *chan, risc_buffer_size = out->is_60hz ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE; - if (out->input_filename) { - str_length = strlen(out->input_filename); - out->_filename = kmemdup(out->input_filename, str_length + 1, - GFP_KERNEL); - - if (!out->_filename) { - err = -ENOENT; - goto error; - } - } else { - str_length = strlen(out->_defaultname); - out->_filename = kmemdup(out->_defaultname, str_length + 1, - GFP_KERNEL); - - if (!out->_filename) { - err = -ENOENT; - goto error; - } - } - - /* Default if filename is empty string */ - if (strcmp(out->_filename, "") == 0) { - if (out->is_60hz) { - out->_filename = - (out->_pixel_format == PIXEL_FRMT_411) ? - "/root/vid411.yuv" : "/root/vidtest.yuv"; - } else { - out->_filename = - (out->_pixel_format == PIXEL_FRMT_411) ? - "/root/pal411.yuv" : "/root/pal422.yuv"; - } - } - out->_is_running = 0; out->_frame_count = 0; out->_file_status = RESET_STATUS; @@ -835,6 +645,8 @@ int cx25821_vidupstream_init(struct cx25821_channel *chan, out->_pixel_format = pixel_format; out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2; + out->curpos = 0; + init_waitqueue_head(&out->waitq); err = cx25821_sram_channel_setup_upstream(dev, sram_ch, out->_line_size, 0); diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c index dde0ba3d340..b194138961d 100644 --- a/drivers/media/pci/cx25821/cx25821-video.c +++ b/drivers/media/pci/cx25821/cx25821-video.c @@ -893,15 +893,47 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv, return 0; } +static ssize_t video_write(struct file *file, const char __user *data, size_t count, + loff_t *ppos) +{ + struct cx25821_channel *chan = video_drvdata(file); + struct cx25821_dev *dev = chan->dev; + struct v4l2_fh *fh = file->private_data; + int err = 0; + + if (mutex_lock_interruptible(&dev->lock)) + return -ERESTARTSYS; + if (chan->streaming_fh && chan->streaming_fh != fh) { + err = -EBUSY; + goto unlock; + } + if (!chan->streaming_fh) { + err = cx25821_vidupstream_init(chan, chan->pixel_formats); + if (err) + goto unlock; + chan->streaming_fh = fh; + } + + err = cx25821_write_frame(chan, data, count); + count -= err; + *ppos += err; + +unlock: + mutex_unlock(&dev->lock); + return err; +} + static int video_out_release(struct file *file) { struct cx25821_channel *chan = video_drvdata(file); - struct cx25821_video_out_data *out = chan->out; struct cx25821_dev *dev = chan->dev; + struct v4l2_fh *fh = file->private_data; mutex_lock(&dev->lock); - if ((chan->id == SRAM_CH09 || chan->id == SRAM_CH10) && out->_is_running) + if (chan->streaming_fh == fh) { cx25821_stop_upstream_video(chan); + chan->streaming_fh = NULL; + } mutex_unlock(&dev->lock); return v4l2_fh_release(file); @@ -955,6 +987,7 @@ static const struct video_device cx25821_video_device = { static const struct v4l2_file_operations video_out_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, + .write = video_write, .release = video_out_release, .unlocked_ioctl = video_ioctl2, }; diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h index b0bc2e626ae..90bdc196929 100644 --- a/drivers/media/pci/cx25821/cx25821.h +++ b/drivers/media/pci/cx25821/cx25821.h @@ -197,15 +197,11 @@ struct cx25821_video_out_data { u32 upstream_riscbuf_size; u32 upstream_databuf_size; - struct workqueue_struct *_irq_queues; - struct work_struct _irq_work_entry; int is_60hz; int _frame_index; - char *input_filename; - char *vid_stdname; - int pixel_format; - char *_filename; - char *_defaultname; + int cur_frame_index; + int curpos; + wait_queue_head_t waitq; }; struct cx25821_channel { @@ -440,6 +436,8 @@ extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev, extern int cx25821_vidupstream_init(struct cx25821_channel *chan, int pixel_format); extern int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select); +extern int cx25821_write_frame(struct cx25821_channel *chan, + const char __user *data, size_t count); extern void cx25821_free_mem_upstream(struct cx25821_channel *chan); extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev); extern void cx25821_stop_upstream_video(struct cx25821_channel *chan); -- cgit v1.2.3-70-g09d2 From 486a7a2813c7d6e0b864c4b51027bcae3359071e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 14 Apr 2013 12:47:57 -0300 Subject: [media] cx25821: remove cx25821-audio-upstream.c from the Makefile The audio output is currently not used as this should be rewritten as an alsa driver. For the time being remove this source from the Makefile. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx25821/Makefile | 3 +-- drivers/media/pci/cx25821/cx25821-core.c | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/media/pci') diff --git a/drivers/media/pci/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile index 407830c89df..fb76c3d3713 100644 --- a/drivers/media/pci/cx25821/Makefile +++ b/drivers/media/pci/cx25821/Makefile @@ -1,7 +1,6 @@ cx25821-y := cx25821-core.o cx25821-cards.o cx25821-i2c.o \ cx25821-gpio.o cx25821-medusa-video.o \ - cx25821-video.o cx25821-video-upstream.o \ - cx25821-audio-upstream.o + cx25821-video.o cx25821-video-upstream.o obj-$(CONFIG_VIDEO_CX25821) += cx25821.o obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 35bea792b5e..b762c5b2ca1 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -964,8 +964,6 @@ void cx25821_dev_unregister(struct cx25821_dev *dev) if (!dev->base_io_addr) return; - cx25821_free_mem_upstream_audio(dev); - release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0)); for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; i++) { -- cgit v1.2.3-70-g09d2