From 31a62d415726d94bae5caf5f2e50232aa06babf6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 18 May 2012 09:36:17 -0300 Subject: [media] snd_tea575x: Add write_/read_val operations Some devices which use the tea575x tuner chip don't allow bit banging the lines, instead they offer a method to directly set / get the contents of the 25 bit shift-register in the chip. Notably the Griffin radioSHARK USB radio receiver does this. Signed-off-by: Hans de Goede CC: Ondrej Zary Signed-off-by: Mauro Carvalho Chehab --- include/sound/tea575x-tuner.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h index 0c3c2fb0f939..7bd6f6145a38 100644 --- a/include/sound/tea575x-tuner.h +++ b/include/sound/tea575x-tuner.h @@ -37,6 +37,10 @@ struct snd_tea575x; struct snd_tea575x_ops { + /* Drivers using snd_tea575x must either define read_ and write_val */ + void (*write_val)(struct snd_tea575x *tea, u32 val); + u32 (*read_val)(struct snd_tea575x *tea); + /* Or define the 3 pin functions */ void (*set_pins)(struct snd_tea575x *tea, u8 pins); u8 (*get_pins)(struct snd_tea575x *tea); void (*set_direction)(struct snd_tea575x *tea, bool output); -- cgit v1.2.3 From 3d0fe51cfa3d07751224c034f8226136a7dd05f2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 18 May 2012 12:21:57 -0300 Subject: [media] snd_tea575x: Add a cannot_mute flag Some devices which use the tea575x tuner chip don't allow direct control over the IO pins, and thus cannot mute the audio output. Signed-off-by: Hans de Goede CC: Ondrej Zary Signed-off-by: Mauro Carvalho Chehab --- include/sound/tea575x-tuner.h | 1 + sound/i2c/other/tea575x-tuner.c | 35 +++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h index 7bd6f6145a38..fe8590cac5c2 100644 --- a/include/sound/tea575x-tuner.h +++ b/include/sound/tea575x-tuner.h @@ -53,6 +53,7 @@ struct snd_tea575x { int radio_nr; /* radio_nr */ bool tea5759; /* 5759 chip is present */ bool cannot_read_data; /* Device cannot read the data pin */ + bool cannot_mute; /* Device cannot mute */ bool mute; /* Device is muted? */ bool stereo; /* receiving stereo */ bool tuned; /* tuned to a station */ diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 080aae9d1198..d14edb7d6484 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -385,7 +385,6 @@ int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner) strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name)); tea->vd.lock = &tea->mutex; tea->vd.v4l2_dev = tea->v4l2_dev; - tea->vd.ctrl_handler = &tea->ctrl_handler; tea->fops = tea575x_fops; tea->fops.owner = owner; tea->vd.fops = &tea->fops; @@ -394,29 +393,33 @@ int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner) if (tea->cannot_read_data) v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK); - v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); - v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); - retval = tea->ctrl_handler.error; - if (retval) { - v4l2_err(tea->v4l2_dev, "can't initialize controls\n"); - v4l2_ctrl_handler_free(&tea->ctrl_handler); - return retval; - } - - if (tea->ext_init) { - retval = tea->ext_init(tea); + if (!tea->cannot_mute) { + tea->vd.ctrl_handler = &tea->ctrl_handler; + v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); + v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, + V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); + retval = tea->ctrl_handler.error; if (retval) { + v4l2_err(tea->v4l2_dev, "can't initialize controls\n"); v4l2_ctrl_handler_free(&tea->ctrl_handler); return retval; } - } - v4l2_ctrl_handler_setup(&tea->ctrl_handler); + if (tea->ext_init) { + retval = tea->ext_init(tea); + if (retval) { + v4l2_ctrl_handler_free(&tea->ctrl_handler); + return retval; + } + } + + v4l2_ctrl_handler_setup(&tea->ctrl_handler); + } retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr); if (retval) { v4l2_err(tea->v4l2_dev, "can't register video device!\n"); - v4l2_ctrl_handler_free(&tea->ctrl_handler); + v4l2_ctrl_handler_free(tea->vd.ctrl_handler); return retval; } @@ -426,7 +429,7 @@ int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner) void snd_tea575x_exit(struct snd_tea575x *tea) { video_unregister_device(&tea->vd); - v4l2_ctrl_handler_free(&tea->ctrl_handler); + v4l2_ctrl_handler_free(tea->vd.ctrl_handler); } static int __init alsa_tea575x_module_init(void) -- cgit v1.2.3 From 6964b1036388fee258c48a911ac4a3ff4e55b62d Mon Sep 17 00:00:00 2001 From: Manjunath Hadli Date: Fri, 29 Jun 2012 03:20:12 -0300 Subject: [media] davinci: vpif: add support for clipping on output data add hardware clipping support for VPIF output data. This is needed as it is possible that the external encoder might get confused between the FF or 00 which are a part of the data and that of the SAV or EAV codes. Signed-off-by: Manjunath Hadli Signed-off-by: Lad, Prabhakar Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/davinci/vpif.h | 30 ++++++++++++++++++++++++++++++ drivers/media/video/davinci/vpif_display.c | 10 ++++++++++ include/media/davinci/vpif_types.h | 2 ++ 3 files changed, 42 insertions(+) (limited to 'include') diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h index a4d2141d1ef3..c2ce4d97c279 100644 --- a/drivers/media/video/davinci/vpif.h +++ b/drivers/media/video/davinci/vpif.h @@ -211,6 +211,12 @@ static inline void vpif_clr_bit(u32 reg, u32 bit) #define VPIF_CH3_INT_CTRL_SHIFT (6) #define VPIF_CH_INT_CTRL_SHIFT (6) +#define VPIF_CH2_CLIP_ANC_EN 14 +#define VPIF_CH2_CLIP_ACTIVE_EN 13 + +#define VPIF_CH3_CLIP_ANC_EN 14 +#define VPIF_CH3_CLIP_ACTIVE_EN 13 + /* enabled interrupt on both the fields on vpid_ch0_ctrl register */ #define channel0_intr_assert() (regw((regr(VPIF_CH0_CTRL)|\ (VPIF_INT_BOTH << VPIF_CH0_INT_CTRL_SHIFT)), VPIF_CH0_CTRL)) @@ -515,6 +521,30 @@ static inline void channel3_raw_enable(int enable, u8 index) vpif_clr_bit(VPIF_CH3_CTRL, mask); } +/* function to enable clipping (for both active and blanking regions) on ch 2 */ +static inline void channel2_clipping_enable(int enable) +{ + if (enable) { + vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN); + vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN); + } else { + vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN); + vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN); + } +} + +/* function to enable clipping (for both active and blanking regions) on ch 2 */ +static inline void channel3_clipping_enable(int enable) +{ + if (enable) { + vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN); + vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN); + } else { + vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN); + vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN); + } +} + /* inline function to set buffer addresses in case of Y/C non mux mode */ static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma, unsigned long btm_strt_luma, diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index 787245923a20..c3e2c193dda1 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c @@ -306,6 +306,8 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) channel2_intr_assert(); channel2_intr_enable(1); enable_channel2(1); + if (vpif_config_data->ch2_clip_en) + channel2_clipping_enable(1); } if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) @@ -313,6 +315,8 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) channel3_intr_assert(); channel3_intr_enable(1); enable_channel3(1); + if (vpif_config_data->ch3_clip_en) + channel3_clipping_enable(1); } channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1; @@ -1140,6 +1144,8 @@ static int vpif_streamoff(struct file *file, void *priv, struct vpif_fh *fh = priv; struct channel_obj *ch = fh->channel; struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; + struct vpif_display_config *vpif_config_data = + vpif_dev->platform_data; if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) { vpif_err("buffer type not supported\n"); @@ -1159,11 +1165,15 @@ static int vpif_streamoff(struct file *file, void *priv, if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) { /* disable channel */ if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { + if (vpif_config_data->ch2_clip_en) + channel2_clipping_enable(0); enable_channel2(0); channel2_intr_enable(0); } if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) || (2 == common->started)) { + if (vpif_config_data->ch3_clip_en) + channel3_clipping_enable(0); enable_channel3(0); channel3_intr_enable(0); } diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h index bd8217c2577c..d8f6ab1943e4 100644 --- a/include/media/davinci/vpif_types.h +++ b/include/media/davinci/vpif_types.h @@ -50,6 +50,8 @@ struct vpif_display_config { const char **output; int output_count; const char *card_name; + bool ch2_clip_en; + bool ch3_clip_en; }; struct vpif_input { -- cgit v1.2.3 From f0476a83d61a8004eb535a0b65721ca405421fe8 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 26 Jul 2012 09:30:00 -0300 Subject: [media] V4L: Add capability flags for memory-to-memory devices This patch adds new V4L2_CAP_VIDEO_M2M and V4L2_CAP_VIDEO_M2M_MPLANE capability flags that are intended to be used for memory-to-memory (M2M) devices, instead of ORed V4L2_CAP_VIDEO_CAPTURE and V4L2_CAP_VIDEO_OUTPUT. V4L2_CAP_VIDEO_M2M flag is added at the drivers, CAPTURE and OUTPUT capability flags are left untouched and will be removed in future, after a transition period required for existing applications to be adapted to check only for V4L2_CAP_VIDEO_M2M. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Acked-by: Kamil Debski Acked-by: Andrzej Pietrasiewicz Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/compat.xml | 9 +++++++++ Documentation/DocBook/media/v4l/vidioc-querycap.xml | 13 +++++++++++++ drivers/media/video/mem2mem_testdev.c | 3 +-- drivers/media/video/mx2_emmaprp.c | 10 +++++++--- drivers/media/video/s5p-fimc/fimc-m2m.c | 7 ++++++- drivers/media/video/s5p-g2d/g2d.c | 9 +++++++-- drivers/media/video/s5p-jpeg/jpeg-core.c | 10 +++++++--- drivers/media/video/s5p-mfc/s5p_mfc_dec.c | 10 ++++++++-- drivers/media/video/s5p-mfc/s5p_mfc_enc.c | 11 ++++++++--- include/linux/videodev2.h | 4 ++++ 10 files changed, 70 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml index 97b895151bb0..4559a6f8a5f0 100644 --- a/Documentation/DocBook/media/v4l/compat.xml +++ b/Documentation/DocBook/media/v4l/compat.xml @@ -2471,6 +2471,15 @@ that used it. It was originally scheduled for removal in 2.6.35. +
+ V4L2 in Linux 3.6 + + + Added V4L2_CAP_VIDEO_M2M and V4L2_CAP_VIDEO_M2M_MPLANE capabilities. + + +
+
Relation of V4L2 to other Linux multimedia APIs diff --git a/Documentation/DocBook/media/v4l/vidioc-querycap.xml b/Documentation/DocBook/media/v4l/vidioc-querycap.xml index 4643505cd4ca..f33dd746b66b 100644 --- a/Documentation/DocBook/media/v4l/vidioc-querycap.xml +++ b/Documentation/DocBook/media/v4l/vidioc-querycap.xml @@ -191,6 +191,19 @@ linkend="output">Video Output interface. multi-planar API through the Video Output interface. + + V4L2_CAP_VIDEO_M2M + 0x00004000 + The device supports the single-planar API through the + Video Memory-To-Memory interface. + + + V4L2_CAP_VIDEO_M2M_MPLANE + 0x00008000 + The device supports the + multi-planar API through the + Video Memory-To-Memory interface. + V4L2_CAP_VIDEO_OVERLAY 0x00000004 diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index 7fdee8fcf3f7..7efe9ad7acc7 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -431,8 +431,7 @@ static int vidioc_querycap(struct file *file, void *priv, strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info)); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT - | V4L2_CAP_STREAMING; + cap->capabilities = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } diff --git a/drivers/media/video/mx2_emmaprp.c b/drivers/media/video/mx2_emmaprp.c index 0bd5815de369..5f8a6f5b98f9 100644 --- a/drivers/media/video/mx2_emmaprp.c +++ b/drivers/media/video/mx2_emmaprp.c @@ -396,9 +396,13 @@ static int vidioc_querycap(struct file *file, void *priv, { strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT - | V4L2_CAP_STREAMING; - + /* + * This is only a mem-to-mem video device. The capture and output + * device capability flags are left only for backward compatibility + * and are scheduled for removal. + */ + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | + V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; return 0; } diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/video/s5p-fimc/fimc-m2m.c index 41eda2e27488..c587011d80ef 100644 --- a/drivers/media/video/s5p-fimc/fimc-m2m.c +++ b/drivers/media/video/s5p-fimc/fimc-m2m.c @@ -259,7 +259,12 @@ static int fimc_m2m_querycap(struct file *file, void *fh, strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1); strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1); cap->bus_info[0] = 0; - cap->capabilities = V4L2_CAP_STREAMING | + /* + * This is only a mem-to-mem video device. The capture and output + * device capability flags are left only for backward compatibility + * and are scheduled for removal. + */ + cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE; return 0; diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c index 7c98ee7377ee..7c2200435206 100644 --- a/drivers/media/video/s5p-g2d/g2d.c +++ b/drivers/media/video/s5p-g2d/g2d.c @@ -290,8 +290,13 @@ static int vidioc_querycap(struct file *file, void *priv, strncpy(cap->card, G2D_NAME, sizeof(cap->card) - 1); cap->bus_info[0] = 0; cap->version = KERNEL_VERSION(1, 0, 0); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT - | V4L2_CAP_STREAMING; + /* + * This is only a mem-to-mem video device. The capture and output + * device capability flags are left only for backward compatibility + * and are scheduled for removal. + */ + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | + V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; return 0; } diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.c b/drivers/media/video/s5p-jpeg/jpeg-core.c index 95f23024b17d..813b801238d1 100644 --- a/drivers/media/video/s5p-jpeg/jpeg-core.c +++ b/drivers/media/video/s5p-jpeg/jpeg-core.c @@ -489,9 +489,13 @@ static int s5p_jpeg_querycap(struct file *file, void *priv, sizeof(cap->card)); } cap->bus_info[0] = 0; - cap->capabilities = V4L2_CAP_STREAMING | - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VIDEO_OUTPUT; + /* + * This is only a mem-to-mem video device. The capture and output + * device capability flags are left only for backward compatibility + * and are scheduled for removal. + */ + cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M | + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT; return 0; } diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index feea867f318c..c5d567f87d77 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c @@ -220,8 +220,14 @@ static int vidioc_querycap(struct file *file, void *priv, strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); cap->bus_info[0] = 0; cap->version = KERNEL_VERSION(1, 0, 0); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE | - V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING; + /* + * This is only a mem-to-mem video device. The capture and output + * device capability flags are left only for backward compatibility + * and are scheduled for removal. + */ + cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING | + V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT_MPLANE; return 0; } diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index 158b78989b89..aa1c244cf66e 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -779,9 +779,14 @@ static int vidioc_querycap(struct file *file, void *priv, strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); cap->bus_info[0] = 0; cap->version = KERNEL_VERSION(1, 0, 0); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE - | V4L2_CAP_VIDEO_OUTPUT_MPLANE - | V4L2_CAP_STREAMING; + /* + * This is only a mem-to-mem video device. The capture and output + * device capability flags are left only for backward compatibility + * and are scheduled for removal. + */ + cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING | + V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT_MPLANE; return 0; } diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 5d78910f926c..4cf766e6f120 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -274,6 +274,10 @@ struct v4l2_capability { #define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000 /* Is a video output device that supports multiplanar formats */ #define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000 +/* Is a video mem-to-mem device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_M2M_MPLANE 0x00004000 +/* Is a video mem-to-mem device */ +#define V4L2_CAP_VIDEO_M2M 0x00008000 #define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ #define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ -- cgit v1.2.3 From 3d687b49ff085b325488e7aeb2ee4df99dd7ca6e Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Jul 2012 06:04:04 -0300 Subject: [media] videodev2.h: add VIDIOC_ENUM_FREQ_BANDS Add a new ioctl to enumerate the supported frequency bands of a tuner. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 4cf766e6f120..63c950f6fcc2 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -2032,6 +2032,7 @@ struct v4l2_modulator { #define V4L2_TUNER_CAP_RDS 0x0080 #define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 #define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 +#define V4L2_TUNER_CAP_FREQ_BANDS 0x0400 /* Flags for the 'rxsubchans' field */ #define V4L2_TUNER_SUB_MONO 0x0001 @@ -2050,19 +2051,34 @@ struct v4l2_modulator { #define V4L2_TUNER_MODE_LANG1_LANG2 0x0004 struct v4l2_frequency { - __u32 tuner; - __u32 type; /* enum v4l2_tuner_type */ - __u32 frequency; - __u32 reserved[8]; + __u32 tuner; + __u32 type; /* enum v4l2_tuner_type */ + __u32 frequency; + __u32 reserved[8]; +}; + +#define V4L2_BAND_MODULATION_VSB (1 << 1) +#define V4L2_BAND_MODULATION_FM (1 << 2) +#define V4L2_BAND_MODULATION_AM (1 << 3) + +struct v4l2_frequency_band { + __u32 tuner; + __u32 type; /* enum v4l2_tuner_type */ + __u32 index; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 modulation; + __u32 reserved[9]; }; struct v4l2_hw_freq_seek { - __u32 tuner; - __u32 type; /* enum v4l2_tuner_type */ - __u32 seek_upward; - __u32 wrap_around; - __u32 spacing; - __u32 reserved[7]; + __u32 tuner; + __u32 type; /* enum v4l2_tuner_type */ + __u32 seek_upward; + __u32 wrap_around; + __u32 spacing; + __u32 reserved[7]; }; /* @@ -2630,6 +2646,10 @@ struct v4l2_create_buffers { #define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings) #define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap) +/* Experimental, this ioctl may change over the next couple of kernel + versions. */ +#define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band) + /* Reminder: when adding new ioctls please add support for them to drivers/media/video/v4l2-compat-ioctl32.c as well! */ -- cgit v1.2.3 From 82b655bfc32b793344ef0ddd46df8af8b98b55c7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 5 Jul 2012 06:37:08 -0300 Subject: [media] v4l2: add core support for the new VIDIOC_ENUM_FREQ_BANDS ioctl This adds the usual core support code for this new ioctl. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-compat-ioctl32.c | 1 + drivers/media/video/v4l2-dev.c | 2 + drivers/media/video/v4l2-ioctl.c | 83 ++++++++++++++++++++++++++++++- include/media/v4l2-ioctl.h | 2 + 4 files changed, 86 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index ac365cfb3706..9ebd5c540d10 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c @@ -1025,6 +1025,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_ENUM_DV_TIMINGS: case VIDIOC_QUERY_DV_TIMINGS: case VIDIOC_DV_TIMINGS_CAP: + case VIDIOC_ENUM_FREQ_BANDS: ret = do_video_ioctl(file, cmd, arg); break; diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 1b2f1c52e6c3..625248585c85 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -730,6 +730,8 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_UNSUBSCRIBE_EVENT, vidioc_unsubscribe_event); SET_VALID_IOCTL(ops, VIDIOC_CREATE_BUFS, vidioc_create_bufs); SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf); + if (ops->vidioc_enum_freq_bands || ops->vidioc_g_tuner || ops->vidioc_g_modulator) + set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls); bitmap_andnot(vdev->valid_ioctls, valid_ioctls, vdev->valid_ioctls, BASE_VIDIOC_PRIVATE); } diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 3e4db2c1c3d6..0f54f8efe66b 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -825,6 +825,17 @@ static void v4l_print_sliced_vbi_cap(const void *arg, bool write_only) p->service_lines[1][i]); } +static void v4l_print_freq_band(const void *arg, bool write_only) +{ + const struct v4l2_frequency_band *p = arg; + + pr_cont("tuner=%u, type=%u, index=%u, capability=0x%x, " + "rangelow=%u, rangehigh=%u, modulation=0x%x\n", + p->tuner, p->type, p->index, + p->capability, p->rangelow, + p->rangehigh, p->modulation); +} + static void v4l_print_u32(const void *arg, bool write_only) { pr_cont("value=%u\n", *(const u32 *)arg); @@ -1245,10 +1256,14 @@ static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops, { struct video_device *vfd = video_devdata(file); struct v4l2_tuner *p = arg; + int err; p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - return ops->vidioc_g_tuner(file, fh, p); + err = ops->vidioc_g_tuner(file, fh, p); + if (!err) + p->capability |= V4L2_TUNER_CAP_FREQ_BANDS; + return err; } static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops, @@ -1262,6 +1277,18 @@ static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops, return ops->vidioc_s_tuner(file, fh, p); } +static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops, + struct file *file, void *fh, void *arg) +{ + struct v4l2_modulator *p = arg; + int err; + + err = ops->vidioc_g_modulator(file, fh, p); + if (!err) + p->capability |= V4L2_TUNER_CAP_FREQ_BANDS; + return err; +} + static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { @@ -1805,6 +1832,57 @@ static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops, return ops->vidioc_g_sliced_vbi_cap(file, fh, p); } +static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, + struct file *file, void *fh, void *arg) +{ + struct video_device *vfd = video_devdata(file); + struct v4l2_frequency_band *p = arg; + enum v4l2_tuner_type type; + int err; + + type = (vfd->vfl_type == VFL_TYPE_RADIO) ? + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + + if (type != p->type) + return -EINVAL; + if (ops->vidioc_enum_freq_bands) + return ops->vidioc_enum_freq_bands(file, fh, p); + if (ops->vidioc_g_tuner) { + struct v4l2_tuner t = { + .index = p->tuner, + .type = type, + }; + + err = ops->vidioc_g_tuner(file, fh, &t); + if (err) + return err; + p->capability = t.capability | V4L2_TUNER_CAP_FREQ_BANDS; + p->rangelow = t.rangelow; + p->rangehigh = t.rangehigh; + p->modulation = (type == V4L2_TUNER_RADIO) ? + V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB; + return 0; + } + if (ops->vidioc_g_modulator) { + struct v4l2_modulator m = { + .index = p->tuner, + }; + + if (type != V4L2_TUNER_RADIO) + return -EINVAL; + err = ops->vidioc_g_modulator(file, fh, &m); + if (err) + return err; + p->capability = m.capability | V4L2_TUNER_CAP_FREQ_BANDS; + p->rangelow = m.rangelow; + p->rangehigh = m.rangehigh; + p->modulation = (type == V4L2_TUNER_RADIO) ? + V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB; + return 0; + } + return -ENOTTY; +} + struct v4l2_ioctl_info { unsigned int ioctl; u32 flags; @@ -1886,7 +1964,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0), IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO), - IOCTL_INFO_STD(VIDIOC_G_MODULATOR, vidioc_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)), + IOCTL_INFO_FNC(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)), IOCTL_INFO_STD(VIDIOC_S_MODULATOR, vidioc_s_modulator, v4l_print_modulator, INFO_FL_PRIO), IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)), IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO), @@ -1933,6 +2011,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { IOCTL_INFO_STD(VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings, v4l_print_enum_dv_timings, 0), IOCTL_INFO_STD(VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings, v4l_print_dv_timings, 0), IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, type)), + IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), }; #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 19e93523c2d8..e614c9c15e56 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -230,6 +230,8 @@ struct v4l2_ioctl_ops { struct v4l2_frequency *a); int (*vidioc_s_frequency) (struct file *file, void *fh, struct v4l2_frequency *a); + int (*vidioc_enum_freq_bands) (struct file *file, void *fh, + struct v4l2_frequency_band *band); /* Sliced VBI cap */ int (*vidioc_g_sliced_vbi_cap) (struct file *file, void *fh, -- cgit v1.2.3 From e0a9b1770bac048171961625875aaf15118a7ae9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 12 Jul 2012 16:55:45 -0300 Subject: [media] v4l2: Add rangelow and rangehigh fields to the v4l2_hw_freq_seek struct To allow apps to limit a hw-freq-seek to a specific band, for further info see the documentation this patch adds for these new fields. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- .../DocBook/media/v4l/vidioc-s-hw-freq-seek.xml | 50 ++++++++++++++++++---- include/linux/videodev2.h | 5 ++- 2 files changed, 46 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml index f4db44d0d95a..3dd1bec6d3c7 100644 --- a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml +++ b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml @@ -52,11 +52,23 @@ Start a hardware frequency seek from the current frequency. To do this applications initialize the tuner, type, seek_upward, -spacing and -wrap_around fields, and zero out the -reserved array of a &v4l2-hw-freq-seek; and -call the VIDIOC_S_HW_FREQ_SEEK ioctl with a pointer -to this structure. +wrap_around, spacing, +rangelow and rangehigh +fields, and zero out the reserved array of a +&v4l2-hw-freq-seek; and call the VIDIOC_S_HW_FREQ_SEEK +ioctl with a pointer to this structure. + + The rangelow and +rangehigh fields can be set to a non-zero value to +tell the driver to search a specific band. If the &v4l2-tuner; +capability field has the +V4L2_TUNER_CAP_HWSEEK_PROG_LIM flag set, these values +must fall within one of the bands returned by &VIDIOC-ENUM-FREQ-BANDS;. If +the V4L2_TUNER_CAP_HWSEEK_PROG_LIM flag is not set, +then these values must exactly match those of one of the bands returned by +&VIDIOC-ENUM-FREQ-BANDS;. If the current frequency of the tuner does not fall +within the selected band it will be clamped to fit in the band before the +seek is started. If an error is returned, then the original frequency will be restored. @@ -102,7 +114,27 @@ field and the &v4l2-tuner; index field. __u32 - reserved[7] + rangelow + If non-zero, the lowest tunable frequency of the band to +search in units of 62.5 kHz, or if the &v4l2-tuner; +capability field has the +V4L2_TUNER_CAP_LOW flag set, in units of 62.5 Hz. +If rangelow is zero a reasonable default value +is used. + + + __u32 + rangehigh + If non-zero, the highest tunable frequency of the band to +search in units of 62.5 kHz, or if the &v4l2-tuner; +capability field has the +V4L2_TUNER_CAP_LOW flag set, in units of 62.5 Hz. +If rangehigh is zero a reasonable default value +is used. + + + __u32 + reserved[5] Reserved for future extensions. Applications must set the array to zero. @@ -119,8 +151,10 @@ field and the &v4l2-tuner; index field. EINVAL The tuner index is out of -bounds, the wrap_around value is not supported or the value in the type field is -wrong. +bounds, the wrap_around value is not supported or +one of the values in the type, +rangelow or rangehigh +fields is wrong. diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 63c950f6fcc2..7a147c8299ab 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -2033,6 +2033,7 @@ struct v4l2_modulator { #define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 #define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 #define V4L2_TUNER_CAP_FREQ_BANDS 0x0400 +#define V4L2_TUNER_CAP_HWSEEK_PROG_LIM 0x0800 /* Flags for the 'rxsubchans' field */ #define V4L2_TUNER_SUB_MONO 0x0001 @@ -2078,7 +2079,9 @@ struct v4l2_hw_freq_seek { __u32 seek_upward; __u32 wrap_around; __u32 spacing; - __u32 reserved[7]; + __u32 rangelow; + __u32 rangehigh; + __u32 reserved[5]; }; /* -- cgit v1.2.3