From: Hans Verkuil <hverkuil@xs4all.nl>
To: Antti Palosaari <crope@iki.fi>
Cc: linux-media@vger.kernel.org,
Mauro Carvalho Chehab <m.chehab@samsung.com>
Subject: Re: [PATCH RFC v3 6/7] rtl2832_sdr: convert to SDR API
Date: Tue, 17 Dec 2013 08:45:45 +0100 [thread overview]
Message-ID: <52B00129.30501@xs4all.nl> (raw)
In-Reply-To: <1387231688-8647-7-git-send-email-crope@iki.fi>
On 12/16/2013 11:08 PM, Antti Palosaari wrote:
> It was abusing video device API. Use SDR API instead.
>
> Signed-off-by: Antti Palosaari <crope@iki.fi>
> ---
> drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 291 ++++++++++++++++++-----
> 1 file changed, 227 insertions(+), 64 deletions(-)
>
> diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
> index 4b8c016..f0965ea 100644
> --- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
> +++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
> @@ -20,12 +20,6 @@
> * GNU Radio plugin "gr-kernel" for device usage will be on:
> * http://git.linuxtv.org/anttip/gr-kernel.git
> *
> - * TODO:
> - * Help is very highly welcome for these + all the others you could imagine:
> - * - move controls to V4L2 API
> - * - use libv4l2 for stream format conversions
> - * - gr-kernel: switch to v4l2_mmap (current read eats a lot of cpu)
> - * - SDRSharp support
> */
>
> #include "dvb_frontend.h"
> @@ -38,6 +32,7 @@
> #include <media/v4l2-event.h>
> #include <media/videobuf2-vmalloc.h>
>
> +#include <linux/jiffies.h>
> #include <linux/math64.h>
>
> /* TODO: These should be moved to V4L2 API */
> @@ -49,11 +44,68 @@
> #define RTL2832_SDR_CID_TUNER_IF ((V4L2_CID_USER_BASE | 0xf000) + 12)
> #define RTL2832_SDR_CID_TUNER_GAIN ((V4L2_CID_USER_BASE | 0xf000) + 13)
>
> -#define V4L2_PIX_FMT_SDR_U8 v4l2_fourcc('D', 'U', '0', '8') /* unsigned 8-bit */
> +#define V4L2_PIX_FMT_SDR_U8 v4l2_fourcc('D', 'U', '0', '8')
> +#define V4L2_PIX_FMT_SDR_U16LE v4l2_fourcc('D', 'U', '1', '6')
>
> #define MAX_BULK_BUFS (10)
> #define BULK_BUFFER_SIZE (128 * 512)
>
> +static const struct v4l2_frequency_band bands_adc[] = {
> + {
> + .tuner = 0,
> + .type = V4L2_TUNER_ADC,
> + .index = 0,
> + .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
> + .rangelow = 300000,
> + .rangehigh = 300000,
> + },
> + {
> + .tuner = 0,
> + .type = V4L2_TUNER_ADC,
> + .index = 1,
> + .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
> + .rangelow = 900001,
> + .rangehigh = 2800000,
> + },
> + {
> + .tuner = 0,
> + .type = V4L2_TUNER_ADC,
> + .index = 2,
> + .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
> + .rangelow = 3200000,
> + .rangehigh = 3200000,
> + },
> +};
> +
> +static const struct v4l2_frequency_band bands_fm[] = {
> + {
> + .tuner = 1,
> + .type = V4L2_TUNER_RF,
> + .index = 0,
> + .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
> + .rangelow = 50000000 / 62.5,
> + .rangehigh = 2000000000 / 62.5,
> + },
> +};
> +
> +/* stream formats */
> +struct rtl2832_sdr_format {
> + char *name;
> + u32 pixelformat;
> +};
> +
> +static struct rtl2832_sdr_format formats[] = {
> + {
> + .name = "I/Q 8-bit unsigned",
> + .pixelformat = V4L2_PIX_FMT_SDR_U8,
> + }, {
> + .name = "I/Q 16-bit unsigned little endian",
> + .pixelformat = V4L2_PIX_FMT_SDR_U16LE,
> + },
> +};
> +
> +static const int NUM_FORMATS = sizeof(formats) / sizeof(struct rtl2832_sdr_format);
> +
> /* intermediate buffers with raw data from the USB device */
> struct rtl2832_sdr_frame_buf {
> struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
> @@ -96,6 +148,9 @@ struct rtl2832_sdr_state {
> int urbs_initialized;
> int urbs_submitted;
>
> + unsigned int f_adc, f_tuner;
> + u32 pixelformat;
> +
> /* Controls */
> struct v4l2_ctrl_handler ctrl_handler;
> struct v4l2_ctrl *ctrl_sampling_rate;
> @@ -107,7 +162,7 @@ struct rtl2832_sdr_state {
> /* for sample rate calc */
> unsigned int sample;
> unsigned int sample_measured;
> - unsigned long jiffies;
> + unsigned long jiffies_next;
> };
>
> /* write multiple hardware registers */
> @@ -292,27 +347,41 @@ leave:
> }
>
> static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
> - u8 *dst, const u8 *src, unsigned int src_len)
> + void *dst, const u8 *src, unsigned int src_len)
> {
> - memcpy(dst, src, src_len);
> + unsigned int dst_len;
> +
> + if (s->pixelformat == V4L2_PIX_FMT_SDR_U8) {
> + /* native stream, no need to convert */
> + memcpy(dst, src, src_len);
> + dst_len = src_len;
> + } else if (s->pixelformat == V4L2_PIX_FMT_SDR_U16LE) {
> + /* convert u8 to u16 */
> + unsigned int i;
> + u16 *u16dst = dst;
> + for (i = 0; i < src_len; i++)
> + *u16dst++ = (src[i] << 8) | (src[i] >> 0);
> + dst_len = 2 * src_len;
> + } else {
> + dst_len = 0;
> + }
>
> /* calculate samping rate and output it in 10 seconds intervals */
> - if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
> - unsigned long jiffies_now = jiffies;
> - unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
> + if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
> +#define MSECS 10000UL
> unsigned int samples = s->sample - s->sample_measured;
> - s->jiffies = jiffies_now;
> + s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
> s->sample_measured = s->sample;
> dev_dbg(&s->udev->dev,
> "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
> - src_len, samples, msecs,
> - samples * 1000UL / msecs);
> + src_len, samples, MSECS,
> + samples * 1000UL / MSECS);
> }
>
> /* total number of I+Q pairs */
> s->sample += src_len / 2;
>
> - return src_len;
> + return dst_len;
> }
>
> /*
> @@ -343,12 +412,12 @@ static void rtl2832_sdr_urb_complete(struct urb *urb)
> break;
> }
>
> - if (urb->actual_length > 0) {
> + if (likely(urb->actual_length > 0)) {
> void *ptr;
> unsigned int len;
> /* get free framebuffer */
> fbuf = rtl2832_sdr_get_next_fill_buf(s);
> - if (fbuf == NULL) {
> + if (unlikely(fbuf == NULL)) {
> s->vb_full++;
> dev_notice_ratelimited(&s->udev->dev,
> "videobuf is full, %d packets dropped\n",
> @@ -544,7 +613,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
> strlcpy(cap->card, s->vdev.name, sizeof(cap->card));
> usb_make_path(s->udev, cap->bus_info, sizeof(cap->bus_info));
> cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
> - V4L2_CAP_READWRITE;
> + V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
Shouldn't we have a V4L2_CAP_SDR_CAPTURE? I think that would make a lot of sense.
> cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
> return 0;
> }
> @@ -560,7 +629,8 @@ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
> /* Absolute min and max number of buffers available for mmap() */
> *nbuffers = 32;
> *nplanes = 1;
> - sizes[0] = PAGE_ALIGN(BULK_BUFFER_SIZE * 4); /* 8 * 512 * 4 = 16384 */
> + /* 2 = max 16-bit sample returned */
> + sizes[0] = PAGE_ALIGN(BULK_BUFFER_SIZE * 2);
> dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
> __func__, *nbuffers, sizes[0]);
> return 0;
> @@ -913,13 +983,14 @@ static struct vb2_ops rtl2832_sdr_vb2_ops = {
> .wait_finish = vb2_ops_wait_finish,
> };
>
> -static int rtl2832_sdr_enum_input(struct file *file, void *fh, struct v4l2_input *i)
> +static int rtl2832_sdr_enum_input(struct file *file, void *fh,
> + struct v4l2_input *i)
> {
> - if (i->index != 0)
> + if (i->index > 0)
> return -EINVAL;
>
> - strlcpy(i->name, "SDR data", sizeof(i->name));
> - i->type = V4L2_INPUT_TYPE_CAMERA;
> + strlcpy(i->name, "Antenna #0", sizeof(i->name));
> + i->type = V4L2_INPUT_TYPE_TUNER;
>
> return 0;
> }
> @@ -933,10 +1004,39 @@ static int rtl2832_sdr_g_input(struct file *file, void *fh, unsigned int *i)
>
> static int rtl2832_sdr_s_input(struct file *file, void *fh, unsigned int i)
> {
> - return i ? -EINVAL : 0;
> + if (i > 0)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
> + struct v4l2_tuner *v)
> +{
> + struct rtl2832_sdr_state *s = video_drvdata(file);
> + dev_dbg(&s->udev->dev, "%s: index=%d type=%d\n",
> + __func__, v->index, v->type);
> +
> + if (v->index == 0) {
> + strlcpy(v->name, "ADC: Realtek RTL2832", sizeof(v->name));
> + v->type = V4L2_TUNER_ADC;
> + v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
> + v->rangelow = 300000;
> + v->rangehigh = 3200000;
> + } else if (v->index == 1) {
> + strlcpy(v->name, "RF: <unknown>", sizeof(v->name));
> + v->type = V4L2_TUNER_RF;
> + v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS;
> + v->rangelow = 50000000 / 62.5;
> + v->rangehigh = 2000000000 / 62.5;
> + } else {
> + return -EINVAL;
> + }
> +
> + return 0;
> }
>
> -static int vidioc_s_tuner(struct file *file, void *priv,
> +static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
> const struct v4l2_tuner *v)
> {
> struct rtl2832_sdr_state *s = video_drvdata(file);
> @@ -945,91 +1045,149 @@ static int vidioc_s_tuner(struct file *file, void *priv,
> return 0;
> }
>
> -static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
> +static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv,
> + struct v4l2_frequency_band *band)
> {
> struct rtl2832_sdr_state *s = video_drvdata(file);
> - dev_dbg(&s->udev->dev, "%s:\n", __func__);
> + dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d index=%d\n",
> + __func__, band->tuner, band->type, band->index);
> +
> + if (band->tuner == 0) {
> + if (band->index >= ARRAY_SIZE(bands_adc))
> + return -EINVAL;
>
> - strcpy(v->name, "SDR RX");
> - v->capability = V4L2_TUNER_CAP_LOW;
> + *band = bands_adc[band->index];
> + } else if (band->tuner == 1) {
> + if (band->index >= ARRAY_SIZE(bands_fm))
> + return -EINVAL;
> +
> + *band = bands_fm[band->index];
> + } else {
> + return -EINVAL;
> + }
>
> return 0;
> }
>
> -static int vidioc_s_frequency(struct file *file, void *priv,
> +static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
> + struct v4l2_frequency *f)
> +{
> + struct rtl2832_sdr_state *s = video_drvdata(file);
> + int ret = 0;
> + dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d\n",
> + __func__, f->tuner, f->type);
> +
> + if (f->tuner == 0)
> + f->frequency = s->f_adc;
> + else if (f->tuner == 1)
> + f->frequency = s->f_tuner;
> + else
> + return -EINVAL;
> +
> + return ret;
> +}
> +
> +static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
> const struct v4l2_frequency *f)
> {
> struct rtl2832_sdr_state *s = video_drvdata(file);
> - dev_dbg(&s->udev->dev, "%s: frequency=%lu Hz (%u)\n",
> - __func__, f->frequency * 625UL / 10UL, f->frequency);
> + int ret;
> + dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
> + __func__, f->tuner, f->type, f->frequency);
> +
> + if (f->tuner == 0) {
> + dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
> + __func__, f->frequency);
> + s->f_adc = f->frequency;
> + ret = v4l2_ctrl_s_ctrl_int64(s->ctrl_sampling_rate,
> + f->frequency);
> + } else if (f->tuner == 1) {
> + dev_dbg(&s->udev->dev, "%s: RF frequency=%lu Hz\n",
> + __func__, f->frequency * 625UL / 10UL);
> + s->f_tuner = f->frequency;
> + ret = v4l2_ctrl_s_ctrl_int64(s->ctrl_tuner_rf,
> + f->frequency * 625UL / 10UL);
> + } else {
> + return -EINVAL;
> + }
>
> - return v4l2_ctrl_s_ctrl_int64(s->ctrl_tuner_rf,
> - f->frequency * 625UL / 10UL);
> + return ret;
> }
>
> -static int rtl2832_sdr_enum_fmt_vid_cap(struct file *file, void *priv,
> +static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
> struct v4l2_fmtdesc *f)
> {
> struct rtl2832_sdr_state *s = video_drvdata(file);
> dev_dbg(&s->udev->dev, "%s:\n", __func__);
>
> - if (f->index > 0)
> + if (f->index >= NUM_FORMATS)
> return -EINVAL;
>
> - f->flags = 0;
> - strcpy(f->description, "I/Q 8-bit unsigned");
> - f->pixelformat = V4L2_PIX_FMT_SDR_U8;
> + strlcpy(f->description, formats[f->index].name, sizeof(f->description));
> + f->pixelformat = formats[f->index].pixelformat;
>
> return 0;
> }
>
> -static int rtl2832_sdr_g_fmt_vid_cap(struct file *file, void *priv,
> +static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
> struct v4l2_format *f)
> {
> struct rtl2832_sdr_state *s = video_drvdata(file);
> dev_dbg(&s->udev->dev, "%s:\n", __func__);
>
> - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> + if (f->type != V4L2_BUF_TYPE_SDR_CAPTURE)
> return -EINVAL;
No need anymore for this test. The core tests that already. Ditto for the
other s/try functions.
>
> - memset(&f->fmt.pix, 0, sizeof(f->fmt.pix));
> - f->fmt.pix.pixelformat = V4L2_PIX_FMT_SDR_U8;
> + f->fmt.sdr.pixelformat = s->pixelformat;
>
> return 0;
> }
>
> -static int rtl2832_sdr_s_fmt_vid_cap(struct file *file, void *priv,
> +static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
> struct v4l2_format *f)
> {
> struct rtl2832_sdr_state *s = video_drvdata(file);
> struct vb2_queue *q = &s->vb_queue;
> + int i;
> dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
> - (char *)&f->fmt.pix.pixelformat);
> + (char *)&f->fmt.sdr.pixelformat);
>
> - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> + if (f->type != V4L2_BUF_TYPE_SDR_CAPTURE)
> return -EINVAL;
>
> if (vb2_is_busy(q))
> return -EBUSY;
>
> - memset(&f->fmt.pix, 0, sizeof(f->fmt.pix));
> - f->fmt.pix.pixelformat = V4L2_PIX_FMT_SDR_U8;
> + for (i = 0; i < NUM_FORMATS; i++) {
> + if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
> + s->pixelformat = f->fmt.sdr.pixelformat;
> + return 0;
> + }
> + }
> +
> + f->fmt.sdr.pixelformat = formats[0].pixelformat;
> + s->pixelformat = formats[0].pixelformat;
>
> return 0;
> }
>
> -static int rtl2832_sdr_try_fmt_vid_cap(struct file *file, void *priv,
> +static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
> struct v4l2_format *f)
> {
> struct rtl2832_sdr_state *s = video_drvdata(file);
> + int i;
> dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
> - (char *)&f->fmt.pix.pixelformat);
> + (char *)&f->fmt.sdr.pixelformat);
>
> - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> + if (f->type != V4L2_BUF_TYPE_SDR_CAPTURE)
> return -EINVAL;
>
> - memset(&f->fmt.pix, 0, sizeof(f->fmt.pix));
> - f->fmt.pix.pixelformat = V4L2_PIX_FMT_SDR_U8;
> + for (i = 0; i < NUM_FORMATS; i++) {
> + if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
> + return 0;
> + }
> +
> + f->fmt.sdr.pixelformat = formats[0].pixelformat;
>
> return 0;
> }
> @@ -1037,10 +1195,10 @@ static int rtl2832_sdr_try_fmt_vid_cap(struct file *file, void *priv,
> static const struct v4l2_ioctl_ops rtl2832_sdr_ioctl_ops = {
> .vidioc_querycap = rtl2832_sdr_querycap,
>
> - .vidioc_enum_fmt_vid_cap = rtl2832_sdr_enum_fmt_vid_cap,
> - .vidioc_g_fmt_vid_cap = rtl2832_sdr_g_fmt_vid_cap,
> - .vidioc_s_fmt_vid_cap = rtl2832_sdr_s_fmt_vid_cap,
> - .vidioc_try_fmt_vid_cap = rtl2832_sdr_try_fmt_vid_cap,
> + .vidioc_enum_fmt_sdr_cap = rtl2832_sdr_enum_fmt_sdr_cap,
> + .vidioc_g_fmt_sdr_cap = rtl2832_sdr_g_fmt_sdr_cap,
> + .vidioc_s_fmt_sdr_cap = rtl2832_sdr_s_fmt_sdr_cap,
> + .vidioc_try_fmt_sdr_cap = rtl2832_sdr_try_fmt_sdr_cap,
>
> .vidioc_enum_input = rtl2832_sdr_enum_input,
> .vidioc_g_input = rtl2832_sdr_g_input,
I see no reason why sdr should support these input ioctls.
> @@ -1056,9 +1214,12 @@ static const struct v4l2_ioctl_ops rtl2832_sdr_ioctl_ops = {
> .vidioc_streamon = vb2_ioctl_streamon,
> .vidioc_streamoff = vb2_ioctl_streamoff,
>
> - .vidioc_g_tuner = vidioc_g_tuner,
> - .vidioc_s_tuner = vidioc_s_tuner,
> - .vidioc_s_frequency = vidioc_s_frequency,
> + .vidioc_g_tuner = rtl2832_sdr_g_tuner,
> + .vidioc_s_tuner = rtl2832_sdr_s_tuner,
> +
> + .vidioc_enum_freq_bands = rtl2832_sdr_enum_freq_bands,
> + .vidioc_g_frequency = rtl2832_sdr_g_frequency,
> + .vidioc_s_frequency = rtl2832_sdr_s_frequency,
>
> .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
> .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
> @@ -1080,6 +1241,7 @@ static struct video_device rtl2832_sdr_template = {
> .release = video_device_release_empty,
> .fops = &rtl2832_sdr_fops,
> .ioctl_ops = &rtl2832_sdr_ioctl_ops,
> + .debug = 0,
Please drop this. You probably used it for debugging.
You can enable this dynamically using:
echo 1 >/sys/class/video4linux/radio0/debug
> };
>
> static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
> @@ -1227,7 +1389,7 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
> INIT_LIST_HEAD(&s->queued_bufs);
>
> /* Init videobuf2 queue structure */
> - s->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> + s->vb_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE;
> s->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
> s->vb_queue.drv_priv = s;
> s->vb_queue.buf_struct_size = sizeof(struct rtl2832_sdr_frame_buf);
> @@ -1274,8 +1436,9 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
> s->v4l2_dev.ctrl_handler = &s->ctrl_handler;
> s->vdev.v4l2_dev = &s->v4l2_dev;
> s->vdev.lock = &s->v4l2_lock;
> + s->vdev.vfl_dir = VFL_DIR_RX;
>
> - ret = video_register_device(&s->vdev, VFL_TYPE_GRABBER, -1);
> + ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
> if (ret < 0) {
> dev_err(&s->udev->dev,
> "Failed to register as video device (%d)\n",
>
Regards,
Hans
next prev parent reply other threads:[~2013-12-17 7:46 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-16 22:08 [PATCH RFC v3 0/7] SDR API Antti Palosaari
2013-12-16 22:08 ` [PATCH RFC v3 1/7] v4l: add new tuner types for SDR Antti Palosaari
2013-12-17 7:31 ` Hans Verkuil
2013-12-16 22:08 ` [PATCH RFC v3 2/7] v4l: 1 Hz resolution flag for tuners Antti Palosaari
2013-12-17 7:31 ` Hans Verkuil
2013-12-16 22:08 ` [PATCH RFC v3 3/7] v4l: add stream format for SDR receiver Antti Palosaari
2013-12-17 7:32 ` Hans Verkuil
2013-12-16 22:08 ` [PATCH RFC v3 4/7] v4l: define own IOCTL ops for SDR FMT Antti Palosaari
2013-12-17 7:32 ` Hans Verkuil
2013-12-16 22:08 ` [PATCH RFC v3 5/7] v4l: enable some IOCTLs for SDR receiver Antti Palosaari
2013-12-17 7:34 ` Hans Verkuil
2013-12-17 16:40 ` Antti Palosaari
2013-12-18 7:32 ` Hans Verkuil
2013-12-16 22:08 ` [PATCH RFC v3 6/7] rtl2832_sdr: convert to SDR API Antti Palosaari
2013-12-17 7:45 ` Hans Verkuil [this message]
2013-12-19 9:21 ` Hans Verkuil
2013-12-19 16:50 ` Antti Palosaari
2013-12-19 16:59 ` Devin Heitmueller
2013-12-19 18:38 ` Antti Palosaari
2013-12-19 19:12 ` Devin Heitmueller
2013-12-16 22:08 ` [PATCH RFC v3 7/7] msi3101: " Antti Palosaari
2013-12-17 7:36 ` [PATCH RFC v3 0/7] " Hans Verkuil
2013-12-17 16:46 ` Antti Palosaari
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52B00129.30501@xs4all.nl \
--to=hverkuil@xs4all.nl \
--cc=crope@iki.fi \
--cc=linux-media@vger.kernel.org \
--cc=m.chehab@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.