* [PATCH 00/52] SDR devel tree
@ 2014-01-25 17:09 Antti Palosaari
2014-01-25 17:09 ` [PATCH 01/52] rtl2832_sdr: Realtek RTL2832 SDR driver module Antti Palosaari
` (51 more replies)
0 siblings, 52 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:09 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Snapshot from my SDR devel tree.
Here is same kernel tree available via git:
http://git.linuxtv.org/anttip/media_tree.git/shortlog/refs/heads/sdr
I uploaded some tools to use that API to GitHub:
https://github.com/palosaari
regards
Antti
Antti Palosaari (51):
rtl2832_sdr: Realtek RTL2832 SDR driver module
rtl28xxu: attach SDR extension module
rtl2832_sdr: use config struct from rtl2832 module
rtl2832_sdr: initial support for R820T tuner
rtl2832_sdr: use get_if_frequency()
rtl2832_sdr: implement sampling rate
rtl2832_sdr: initial support for FC0012 tuner
rtl2832_sdr: initial support for FC0013 tuner
rtl28xxu: constify demod config structs
rtl2832: remove unused if_dvbt config parameter
rtl2832: style changes and minor cleanup
rtl2832_sdr: pixel format for SDR
rtl2832_sdr: implement FMT IOCTLs
msi3101: add signed 8-bit pixel format for SDR
msi3101: implement FMT IOCTLs
msi3101: move format 384 conversion to libv4lconvert
msi3101: move format 336 conversion to libv4lconvert
msi3101: move format 252 conversion to libv4lconvert
rtl28xxu: add module parameter to disable IR
rtl2832_sdr: increase USB buffers
DocBook: fix wait.c location
v4l: add device type for Software Defined Radio
v4l: add new tuner types for SDR
v4l: 1 Hz resolution flag for tuners
v4l: add stream format for SDR receiver
v4l: define own IOCTL ops for SDR FMT
v4l: enable some IOCTLs for SDR receiver
v4l: add device capability flag for SDR receiver
DocBook: document 1 Hz flag
DocBook: Software Defined Radio Interface
DocBook: mark SDR API as Experimental
v4l2-framework.txt: add SDR device type
devices.txt: add video4linux device for Software Defined Radio
rtl2832_sdr: convert to SDR API
msi3101: convert to SDR API
msi3101: add u8 sample format
msi3101: add u16 LE sample format
msi3101: tons of small changes
v4l: disable lockdep on vb2_fop_mmap()
rtl2832_sdr: return NULL on rtl2832_sdr_attach failure
rtl2832_sdr: calculate bandwidth if not set by user
rtl2832_sdr: clamp ADC frequency to valid range always
rtl2832_sdr: improve ADC device programming logic
rtl2832_sdr: remove FMT buffer type checks
rtl2832_sdr: switch FM to DAB mode
msi3101: calculate tuner filters
msi3101: remove FMT buffer type checks
msi3101: improve ADC config stream format selection
msi3101: clamp ADC and RF to valid range
msi3101: disable all but u8 and u16le formats
v4l: add RF tuner gain controls
Hans Verkuil (1):
v4l: do not allow modulator ioctls for non-radio devices
Documentation/DocBook/device-drivers.tmpl | 2 +-
Documentation/DocBook/media/v4l/compat.xml | 13 +
Documentation/DocBook/media/v4l/dev-sdr.xml | 110 ++
Documentation/DocBook/media/v4l/io.xml | 6 +
Documentation/DocBook/media/v4l/pixfmt.xml | 8 +
Documentation/DocBook/media/v4l/v4l2.xml | 1 +
.../DocBook/media/v4l/vidioc-enum-freq-bands.xml | 8 +-
Documentation/DocBook/media/v4l/vidioc-g-fmt.xml | 7 +
.../DocBook/media/v4l/vidioc-g-frequency.xml | 5 +-
.../DocBook/media/v4l/vidioc-g-modulator.xml | 6 +-
Documentation/DocBook/media/v4l/vidioc-g-tuner.xml | 15 +-
.../DocBook/media/v4l/vidioc-querycap.xml | 6 +
.../DocBook/media/v4l/vidioc-s-hw-freq-seek.xml | 8 +-
Documentation/devices.txt | 7 +
Documentation/video4linux/v4l2-framework.txt | 1 +
drivers/media/dvb-frontends/rtl2832.c | 32 +-
drivers/media/dvb-frontends/rtl2832.h | 9 +-
drivers/media/dvb-frontends/rtl2832_priv.h | 50 +-
drivers/media/usb/dvb-usb-v2/Makefile | 1 +
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 34 +-
drivers/media/v4l2-core/v4l2-ctrls.c | 15 +
drivers/media/v4l2-core/v4l2-dev.c | 30 +-
drivers/media/v4l2-core/v4l2-ioctl.c | 75 +-
drivers/media/v4l2-core/videobuf2-core.c | 14 +-
drivers/staging/media/Kconfig | 2 +
drivers/staging/media/Makefile | 2 +
drivers/staging/media/msi3101/sdr-msi3101.c | 887 ++++++------
drivers/staging/media/rtl2832u_sdr/Kconfig | 6 +
drivers/staging/media/rtl2832u_sdr/Makefile | 5 +
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 1448 ++++++++++++++++++++
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h | 51 +
include/media/v4l2-dev.h | 3 +-
include/media/v4l2-ioctl.h | 8 +
include/trace/events/v4l2.h | 1 +
include/uapi/linux/v4l2-controls.h | 11 +
include/uapi/linux/videodev2.h | 16 +
36 files changed, 2420 insertions(+), 483 deletions(-)
create mode 100644 Documentation/DocBook/media/v4l/dev-sdr.xml
create mode 100644 drivers/staging/media/rtl2832u_sdr/Kconfig
create mode 100644 drivers/staging/media/rtl2832u_sdr/Makefile
create mode 100644 drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
create mode 100644 drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
--
1.8.5.3
^ permalink raw reply [flat|nested] 54+ messages in thread
* [PATCH 01/52] rtl2832_sdr: Realtek RTL2832 SDR driver module
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
@ 2014-01-25 17:09 ` Antti Palosaari
2014-01-25 17:09 ` [PATCH 02/52] rtl28xxu: attach SDR extension module Antti Palosaari
` (50 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:09 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Implement SDR driver for Realtek RTL2832U chip as a DVB extension
module. SDR module is attached by DVB USB RTL28XXU driver as a DVB
SEC (satellite equipment controller) module. Abusing unused SEC here
has no harm as that is DVB-T only frontend.
SDR functionality is provided by RTL2832 DVB-T demodulator. I suspect
it is originally planned for DAB and FM, but it could be abused general
SDR, due to modern silicon tuners that has wide frequency range and a
lot of configurable parameters (filters, gains, ...).
http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/44461
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/Kconfig | 2 +
drivers/staging/media/Makefile | 2 +
drivers/staging/media/rtl2832u_sdr/Kconfig | 6 +
drivers/staging/media/rtl2832u_sdr/Makefile | 4 +
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 1184 ++++++++++++++++++++++
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h | 52 +
6 files changed, 1250 insertions(+)
create mode 100644 drivers/staging/media/rtl2832u_sdr/Kconfig
create mode 100644 drivers/staging/media/rtl2832u_sdr/Makefile
create mode 100644 drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
create mode 100644 drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 22b0c9d..a9f2e63 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -41,6 +41,8 @@ source "drivers/staging/media/solo6x10/Kconfig"
source "drivers/staging/media/omap4iss/Kconfig"
+source "drivers/staging/media/rtl2832u_sdr/Kconfig"
+
# Keep LIRC at the end, as it has sub-menus
source "drivers/staging/media/lirc/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index bedc62a..8e2c5d2 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -11,3 +11,5 @@ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
obj-$(CONFIG_USB_SN9C102) += sn9c102/
obj-$(CONFIG_VIDEO_OMAP2) += omap24xx/
obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/
+obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832u_sdr/
+
diff --git a/drivers/staging/media/rtl2832u_sdr/Kconfig b/drivers/staging/media/rtl2832u_sdr/Kconfig
new file mode 100644
index 0000000..3e07f23
--- /dev/null
+++ b/drivers/staging/media/rtl2832u_sdr/Kconfig
@@ -0,0 +1,6 @@
+config DVB_RTL2832_SDR
+ tristate "Realtek RTL2832 SDR"
+ depends on USB && DVB_CORE && I2C && VIDEO_DEV
+ select VIDEOBUF2_VMALLOC
+ default m if !MEDIA_SUBDRV_AUTOSELECT
+
diff --git a/drivers/staging/media/rtl2832u_sdr/Makefile b/drivers/staging/media/rtl2832u_sdr/Makefile
new file mode 100644
index 0000000..684546776
--- /dev/null
+++ b/drivers/staging/media/rtl2832u_sdr/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/usb/dvb-usb-v2
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
new file mode 100644
index 0000000..0b110a3
--- /dev/null
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -0,0 +1,1184 @@
+/*
+ * Realtek RTL2832U SDR driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 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"
+#include "rtl2832_sdr.h"
+#include "dvb_usb.h"
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-vmalloc.h>
+
+/* TODO: These should be moved to V4L2 API */
+#define RTL2832_SDR_CID_SAMPLING_MODE ((V4L2_CID_USER_BASE | 0xf000) + 0)
+#define RTL2832_SDR_CID_SAMPLING_RATE ((V4L2_CID_USER_BASE | 0xf000) + 1)
+#define RTL2832_SDR_CID_SAMPLING_RESOLUTION ((V4L2_CID_USER_BASE | 0xf000) + 2)
+#define RTL2832_SDR_CID_TUNER_RF ((V4L2_CID_USER_BASE | 0xf000) + 10)
+#define RTL2832_SDR_CID_TUNER_BW ((V4L2_CID_USER_BASE | 0xf000) + 11)
+#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 MAX_BULK_BUFS (8)
+#define BULK_BUFFER_SIZE (8 * 512)
+
+/* 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 */
+ struct list_head list;
+};
+
+struct rtl2832_sdr_state {
+#define POWER_ON (1 << 1)
+#define URB_BUF (1 << 2)
+ unsigned long flags;
+
+ const struct rtl2832_sdr_config *cfg;
+ struct dvb_frontend *fe;
+ struct dvb_usb_device *d;
+ struct i2c_adapter *i2c;
+ u8 bank;
+
+ struct video_device vdev;
+ struct v4l2_device v4l2_dev;
+
+ /* videobuf2 queue and queued buffers list */
+ struct vb2_queue vb_queue;
+ struct list_head queued_bufs;
+ spinlock_t queued_bufs_lock; /* Protects queued_bufs */
+
+ /* Note if taking both locks v4l2_lock must always be locked first! */
+ struct mutex v4l2_lock; /* Protects everything else */
+ struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
+
+ /* Pointer to our usb_device, will be NULL after unplug */
+ struct usb_device *udev; /* Both mutexes most be hold when setting! */
+
+ unsigned int vb_full; /* vb is full and packets dropped */
+
+ struct urb *urb_list[MAX_BULK_BUFS];
+ int buf_num;
+ unsigned long buf_size;
+ u8 *buf_list[MAX_BULK_BUFS];
+ dma_addr_t dma_addr[MAX_BULK_BUFS];
+ int urbs_initialized;
+ int urbs_submitted;
+
+ /* Controls */
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct v4l2_ctrl *ctrl_sampling_rate;
+ struct v4l2_ctrl *ctrl_tuner_rf;
+ struct v4l2_ctrl *ctrl_tuner_bw;
+ struct v4l2_ctrl *ctrl_tuner_if;
+ struct v4l2_ctrl *ctrl_tuner_gain;
+
+ /* for sample rate calc */
+ unsigned int sample;
+ unsigned int sample_measured;
+ unsigned long jiffies;
+};
+
+/* write multiple hardware registers */
+static int rtl2832_sdr_wr(struct rtl2832_sdr_state *s, u8 reg, const u8 *val,
+ int len)
+{
+ int ret;
+ u8 buf[1 + len];
+ struct i2c_msg msg[1] = {
+ {
+ .addr = s->cfg->i2c_addr,
+ .flags = 0,
+ .len = 1 + len,
+ .buf = buf,
+ }
+ };
+
+ buf[0] = reg;
+ memcpy(&buf[1], val, len);
+
+ ret = i2c_transfer(s->i2c, msg, 1);
+ if (ret == 1) {
+ ret = 0;
+ } else {
+ dev_err(&s->i2c->dev,
+ "%s: I2C wr failed=%d reg=%02x len=%d\n",
+ KBUILD_MODNAME, ret, reg, len);
+ ret = -EREMOTEIO;
+ }
+ return ret;
+}
+
+#if 0
+/* read multiple hardware registers */
+static int rtl2832_sdr_rd(struct rtl2832_sdr_state *s, u8 reg, u8 *val, int len)
+{
+ int ret;
+ struct i2c_msg msg[2] = {
+ {
+ .addr = s->cfg->i2c_addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®,
+ }, {
+ .addr = s->cfg->i2c_addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = val,
+ }
+ };
+
+ ret = i2c_transfer(s->i2c, msg, 2);
+ if (ret == 2) {
+ ret = 0;
+ } else {
+ dev_err(&s->i2c->dev,
+ "%s: I2C rd failed=%d reg=%02x len=%d\n",
+ KBUILD_MODNAME, ret, reg, len);
+ ret = -EREMOTEIO;
+ }
+ return ret;
+}
+#endif
+
+/* write multiple registers */
+static int rtl2832_sdr_wr_regs(struct rtl2832_sdr_state *s, u16 reg,
+ const u8 *val, int len)
+{
+ int ret;
+ u8 reg2 = (reg >> 0) & 0xff;
+ u8 bank = (reg >> 8) & 0xff;
+
+ /* switch bank if needed */
+ if (bank != s->bank) {
+ ret = rtl2832_sdr_wr(s, 0x00, &bank, 1);
+ if (ret)
+ return ret;
+
+ s->bank = bank;
+ }
+
+ return rtl2832_sdr_wr(s, reg2, val, len);
+}
+
+#if 0
+/* read multiple registers */
+static int rtl2832_sdr_rd_regs(struct rtl2832_sdr_state *s, u16 reg, u8 *val,
+ int len)
+{
+ int ret;
+ u8 reg2 = (reg >> 0) & 0xff;
+ u8 bank = (reg >> 8) & 0xff;
+
+ /* switch bank if needed */
+ if (bank != s->bank) {
+ ret = rtl2832_sdr_wr(s, 0x00, &bank, 1);
+ if (ret)
+ return ret;
+
+ s->bank = bank;
+ }
+
+ return rtl2832_sdr_rd(s, reg2, val, len);
+}
+
+/* read single register */
+static int rtl2832_sdr_rd_reg(struct rtl2832_sdr_state *s, u16 reg, u8 *val)
+{
+ return rtl2832_sdr_rd_regs(s, reg, val, 1);
+}
+
+/* write single register with mask */
+static int rtl2832_sdr_wr_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
+ u8 val, u8 mask)
+{
+ int ret;
+ u8 tmp;
+
+ /* no need for read if whole reg is written */
+ if (mask != 0xff) {
+ ret = rtl2832_sdr_rd_regs(s, reg, &tmp, 1);
+ if (ret)
+ return ret;
+
+ val &= mask;
+ tmp &= ~mask;
+ val |= tmp;
+ }
+
+ return rtl2832_sdr_wr_regs(s, reg, &val, 1);
+}
+
+/* read single register with mask */
+static int rtl2832_sdr_rd_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
+ u8 *val, u8 mask)
+{
+ int ret, i;
+ u8 tmp;
+
+ ret = rtl2832_sdr_rd_regs(s, reg, &tmp, 1);
+ if (ret)
+ return ret;
+
+ tmp &= mask;
+
+ /* find position of the first bit */
+ for (i = 0; i < 8; i++) {
+ if ((mask >> i) & 0x01)
+ break;
+ }
+ *val = tmp >> i;
+
+ return 0;
+}
+#endif
+
+/* Private functions */
+static struct rtl2832_sdr_frame_buf *rtl2832_sdr_get_next_fill_buf(
+ struct rtl2832_sdr_state *s)
+{
+ unsigned long flags = 0;
+ struct rtl2832_sdr_frame_buf *buf = NULL;
+
+ spin_lock_irqsave(&s->queued_bufs_lock, flags);
+ if (list_empty(&s->queued_bufs))
+ goto leave;
+
+ buf = list_entry(s->queued_bufs.next,
+ struct rtl2832_sdr_frame_buf, list);
+ list_del(&buf->list);
+leave:
+ spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
+ return buf;
+}
+
+/*
+ * Integer to 32-bit IEEE floating point representation routine is taken
+ * from Radeon R600 driver (drivers/gpu/drm/radeon/r600_blit_kms.c).
+ *
+ * TODO: Currently we do conversion here in Kernel, but in future that will
+ * be moved to the libv4l2 library as video format conversions are.
+ */
+#define I2F_FRAC_BITS 23
+#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
+
+/*
+ * Converts signed 8-bit integer into 32-bit IEEE floating point
+ * representation.
+ */
+static u32 rtl2832_sdr_convert_sample(struct rtl2832_sdr_state *s, u16 x)
+{
+ u32 msb, exponent, fraction, sign;
+
+ /* Zero is special */
+ if (!x)
+ return 0;
+
+ /* Negative / positive value */
+ if (x & (1 << 7)) {
+ x = -x;
+ x &= 0x7f; /* result is 7 bit ... + sign */
+ sign = 1 << 31;
+ } else {
+ sign = 0 << 31;
+ }
+
+ /* Get location of the most significant bit */
+ msb = __fls(x);
+
+ fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
+ exponent = (127 + msb) << I2F_FRAC_BITS;
+
+ return (fraction + exponent) | sign;
+}
+
+static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
+ u32 *dst, const u8 *src, unsigned int src_len)
+{
+ unsigned int i, dst_len = 0;
+
+ for (i = 0; i < src_len; i++)
+ *dst++ = rtl2832_sdr_convert_sample(s, src[i]);
+
+ /* 8-bit to 32-bit IEEE floating point */
+ dst_len = src_len * 4;
+
+ /* 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);
+ unsigned int samples = s->sample - s->sample_measured;
+ s->jiffies = jiffies_now;
+ 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);
+ }
+
+ /* total number of I+Q pairs */
+ s->sample += src_len / 2;
+
+ return dst_len;
+}
+
+/*
+ * This gets called for the bulk stream pipe. This is done in interrupt
+ * time, so it has to be fast, not crash, and not stall. Neat.
+ */
+static void rtl2832_sdr_urb_complete(struct urb *urb)
+{
+ struct rtl2832_sdr_state *s = urb->context;
+ struct rtl2832_sdr_frame_buf *fbuf;
+
+ dev_dbg_ratelimited(&s->udev->dev,
+ "%s: status=%d length=%d/%d errors=%d\n",
+ __func__, urb->status, urb->actual_length,
+ urb->transfer_buffer_length, urb->error_count);
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ dev_err_ratelimited(&s->udev->dev, "urb failed=%d\n",
+ urb->status);
+ break;
+ }
+
+ if (urb->actual_length > 0) {
+ void *ptr;
+ unsigned int len;
+ /* get free framebuffer */
+ fbuf = rtl2832_sdr_get_next_fill_buf(s);
+ if (fbuf == NULL) {
+ s->vb_full++;
+ dev_notice_ratelimited(&s->udev->dev,
+ "videobuf is full, %d packets dropped\n",
+ s->vb_full);
+ goto skip;
+ }
+
+ /* fill framebuffer */
+ ptr = vb2_plane_vaddr(&fbuf->vb, 0);
+ len = rtl2832_sdr_convert_stream(s, ptr, urb->transfer_buffer,
+ urb->actual_length);
+ vb2_set_plane_payload(&fbuf->vb, 0, len);
+ vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
+ }
+skip:
+ usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static int rtl2832_sdr_kill_urbs(struct rtl2832_sdr_state *s)
+{
+ int i;
+
+ for (i = s->urbs_submitted - 1; i >= 0; i--) {
+ dev_dbg(&s->udev->dev, "%s: kill urb=%d\n", __func__, i);
+ /* stop the URB */
+ usb_kill_urb(s->urb_list[i]);
+ }
+ s->urbs_submitted = 0;
+
+ return 0;
+}
+
+static int rtl2832_sdr_submit_urbs(struct rtl2832_sdr_state *s)
+{
+ int i, ret;
+
+ for (i = 0; i < s->urbs_initialized; i++) {
+ dev_dbg(&s->udev->dev, "%s: submit urb=%d\n", __func__, i);
+ ret = usb_submit_urb(s->urb_list[i], GFP_ATOMIC);
+ if (ret) {
+ dev_err(&s->udev->dev,
+ "Could not submit urb no. %d - get them all back\n",
+ i);
+ rtl2832_sdr_kill_urbs(s);
+ return ret;
+ }
+ s->urbs_submitted++;
+ }
+
+ return 0;
+}
+
+static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_state *s)
+{
+ if (s->flags & USB_STATE_URB_BUF) {
+ while (s->buf_num) {
+ s->buf_num--;
+ dev_dbg(&s->udev->dev, "%s: free buf=%d\n",
+ __func__, s->buf_num);
+ usb_free_coherent(s->udev, s->buf_size,
+ s->buf_list[s->buf_num],
+ s->dma_addr[s->buf_num]);
+ }
+ }
+ s->flags &= ~USB_STATE_URB_BUF;
+
+ return 0;
+}
+
+static int rtl2832_sdr_alloc_stream_bufs(struct rtl2832_sdr_state *s)
+{
+ s->buf_num = 0;
+ s->buf_size = BULK_BUFFER_SIZE;
+
+ dev_dbg(&s->udev->dev,
+ "%s: all in all I will use %u bytes for streaming\n",
+ __func__, MAX_BULK_BUFS * BULK_BUFFER_SIZE);
+
+ for (s->buf_num = 0; s->buf_num < MAX_BULK_BUFS; s->buf_num++) {
+ s->buf_list[s->buf_num] = usb_alloc_coherent(s->udev,
+ BULK_BUFFER_SIZE, GFP_ATOMIC,
+ &s->dma_addr[s->buf_num]);
+ if (!s->buf_list[s->buf_num]) {
+ dev_dbg(&s->udev->dev, "%s: alloc buf=%d failed\n",
+ __func__, s->buf_num);
+ rtl2832_sdr_free_stream_bufs(s);
+ return -ENOMEM;
+ }
+
+ dev_dbg(&s->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
+ __func__, s->buf_num,
+ s->buf_list[s->buf_num],
+ (long long)s->dma_addr[s->buf_num]);
+ s->flags |= USB_STATE_URB_BUF;
+ }
+
+ return 0;
+}
+
+static int rtl2832_sdr_free_urbs(struct rtl2832_sdr_state *s)
+{
+ int i;
+
+ rtl2832_sdr_kill_urbs(s);
+
+ for (i = s->urbs_initialized - 1; i >= 0; i--) {
+ if (s->urb_list[i]) {
+ dev_dbg(&s->udev->dev, "%s: free urb=%d\n",
+ __func__, i);
+ /* free the URBs */
+ usb_free_urb(s->urb_list[i]);
+ }
+ }
+ s->urbs_initialized = 0;
+
+ return 0;
+}
+
+static int rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_state *s)
+{
+ int i, j;
+
+ /* allocate the URBs */
+ for (i = 0; i < MAX_BULK_BUFS; i++) {
+ dev_dbg(&s->udev->dev, "%s: alloc urb=%d\n", __func__, i);
+ s->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!s->urb_list[i]) {
+ dev_dbg(&s->udev->dev, "%s: failed\n", __func__);
+ for (j = 0; j < i; j++)
+ usb_free_urb(s->urb_list[j]);
+ return -ENOMEM;
+ }
+ usb_fill_bulk_urb(s->urb_list[i],
+ s->udev,
+ usb_rcvbulkpipe(s->udev, 0x81),
+ s->buf_list[i],
+ BULK_BUFFER_SIZE,
+ rtl2832_sdr_urb_complete, s);
+
+ s->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+ s->urb_list[i]->transfer_dma = s->dma_addr[i];
+ s->urbs_initialized++;
+ }
+
+ return 0;
+}
+
+/* Must be called with vb_queue_lock hold */
+static void rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_state *s)
+{
+ unsigned long flags = 0;
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ spin_lock_irqsave(&s->queued_bufs_lock, flags);
+ while (!list_empty(&s->queued_bufs)) {
+ struct rtl2832_sdr_frame_buf *buf;
+ buf = list_entry(s->queued_bufs.next,
+ struct rtl2832_sdr_frame_buf, list);
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ }
+ spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
+}
+
+/* The user yanked out the cable... */
+static void rtl2832_sdr_release_sec(struct dvb_frontend *fe)
+{
+ struct rtl2832_sdr_state *s = fe->sec_priv;
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ mutex_lock(&s->vb_queue_lock);
+ mutex_lock(&s->v4l2_lock);
+ /* No need to keep the urbs around after disconnection */
+ s->udev = NULL;
+
+ v4l2_device_disconnect(&s->v4l2_dev);
+ video_unregister_device(&s->vdev);
+ mutex_unlock(&s->v4l2_lock);
+ mutex_unlock(&s->vb_queue_lock);
+
+ v4l2_device_put(&s->v4l2_dev);
+
+ fe->sec_priv = NULL;
+}
+
+static int rtl2832_sdr_querycap(struct file *file, void *fh,
+ struct v4l2_capability *cap)
+{
+ struct rtl2832_sdr_state *s = video_drvdata(file);
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+ 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;
+ cap->device_caps = V4L2_CAP_TUNER;
+ cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+ return 0;
+}
+
+/* Videobuf2 operations */
+static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
+ const struct v4l2_format *fmt, unsigned int *nbuffers,
+ unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
+{
+ struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
+ dev_dbg(&s->udev->dev, "%s: *nbuffers=%d\n", __func__, *nbuffers);
+
+ /* 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 */
+ dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
+ __func__, *nbuffers, sizes[0]);
+ return 0;
+}
+
+static int rtl2832_sdr_buf_prepare(struct vb2_buffer *vb)
+{
+ struct rtl2832_sdr_state *s = vb2_get_drv_priv(vb->vb2_queue);
+
+ /* Don't allow queing new buffers after device disconnection */
+ if (!s->udev)
+ return -ENODEV;
+
+ return 0;
+}
+
+static void rtl2832_sdr_buf_queue(struct vb2_buffer *vb)
+{
+ struct rtl2832_sdr_state *s = vb2_get_drv_priv(vb->vb2_queue);
+ struct rtl2832_sdr_frame_buf *buf =
+ container_of(vb, struct rtl2832_sdr_frame_buf, vb);
+ unsigned long flags = 0;
+
+ /* Check the device has not disconnected between prep and queuing */
+ if (!s->udev) {
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ return;
+ }
+
+ spin_lock_irqsave(&s->queued_bufs_lock, flags);
+ list_add_tail(&buf->list, &s->queued_bufs);
+ spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
+}
+
+static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
+{
+ int ret;
+ unsigned int f_sr;
+
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ if (!test_bit(POWER_ON, &s->flags))
+ return 0;
+
+ f_sr = s->ctrl_sampling_rate->val64;
+
+ ret = rtl2832_sdr_wr_regs(s, 0x13e, "\x00\x00", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x115, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\x00", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x118, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x119, "\x00\x00", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x11b, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x19f, "\x03\x84", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x1a1, "\x00\x00", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x11c, "\xca", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x11d, "\xdc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x11e, "\xd7", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x11f, "\xd8", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x120, "\xe0", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x121, "\xf2", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x122, "\x0e", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x123, "\x35", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x124, "\x06", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x125, "\x50", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x126, "\x9c", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x127, "\x0d", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x128, "\x71", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x129, "\x11", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x12a, "\x14", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x12b, "\x71", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x12c, "\x74", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x12d, "\x19", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x12e, "\x41", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x12f, "\xa5", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x017, "\x11", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x018, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x019, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x01f, "\xff", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x01e, "\x01", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x01d, "\x06", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x01c, "\x0d", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x01b, "\x16", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x01a, "\x1b", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x192, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x193, "\xf0", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x194, "\x0f", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x061, "\x60", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x006, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x30", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x104, "\xd0", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x18", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x011, "\xd4", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x14", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xec", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x83", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x010, "\x49", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x87", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x85", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x013, "\x02", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x008, "\xcd", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1b1, "\x01", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x019, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10c, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\xe3", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x118, "\x8e", 1);
+
+ return ret;
+};
+
+static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
+{
+ struct dvb_frontend *fe = s->fe;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ unsigned int f_rf = s->ctrl_tuner_rf->val64;
+
+ /*
+ * bandwidth (Hz)
+ */
+ unsigned int bandwidth = s->ctrl_tuner_bw->val;
+
+ /*
+ * intermediate frequency (Hz)
+ */
+ unsigned int f_if = s->ctrl_tuner_if->val;
+
+ /*
+ * gain (dB)
+ */
+ int gain = s->ctrl_tuner_gain->val;
+
+ dev_dbg(&s->udev->dev,
+ "%s: f_rf=%u bandwidth=%d f_if=%u gain=%d\n",
+ __func__, f_rf, bandwidth, f_if, gain);
+
+ if (!test_bit(POWER_ON, &s->flags))
+ return 0;
+
+ if (fe->ops.tuner_ops.init)
+ fe->ops.tuner_ops.init(fe);
+
+ c->bandwidth_hz = bandwidth;
+ c->frequency = f_rf;
+
+ if (fe->ops.tuner_ops.set_params)
+ fe->ops.tuner_ops.set_params(fe);
+
+ return 0;
+};
+
+static void rtl2832_sdr_unset_tuner(struct rtl2832_sdr_state *s)
+{
+ struct dvb_frontend *fe = s->fe;
+
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ if (fe->ops.tuner_ops.sleep)
+ fe->ops.tuner_ops.sleep(fe);
+
+ return;
+};
+
+static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+ struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
+ int ret;
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ if (!s->udev)
+ return -ENODEV;
+
+ if (mutex_lock_interruptible(&s->v4l2_lock))
+ return -ERESTARTSYS;
+
+ if (s->d->props->power_ctrl)
+ s->d->props->power_ctrl(s->d, 1);
+
+ set_bit(POWER_ON, &s->flags);
+
+ ret = rtl2832_sdr_set_tuner(s);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_set_adc(s);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_alloc_stream_bufs(s);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_alloc_urbs(s);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_submit_urbs(s);
+ if (ret)
+ goto err;
+
+err:
+ mutex_unlock(&s->v4l2_lock);
+
+ return ret;
+}
+
+static int rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
+{
+ struct rtl2832_sdr_state *s = vb2_get_drv_priv(vq);
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ if (mutex_lock_interruptible(&s->v4l2_lock))
+ return -ERESTARTSYS;
+
+ rtl2832_sdr_kill_urbs(s);
+ rtl2832_sdr_free_urbs(s);
+ rtl2832_sdr_free_stream_bufs(s);
+ rtl2832_sdr_cleanup_queued_bufs(s);
+ rtl2832_sdr_unset_tuner(s);
+
+ clear_bit(POWER_ON, &s->flags);
+
+ if (s->d->props->power_ctrl)
+ s->d->props->power_ctrl(s->d, 0);
+
+ mutex_unlock(&s->v4l2_lock);
+
+ return 0;
+}
+
+static struct vb2_ops rtl2832_sdr_vb2_ops = {
+ .queue_setup = rtl2832_sdr_queue_setup,
+ .buf_prepare = rtl2832_sdr_buf_prepare,
+ .buf_queue = rtl2832_sdr_buf_queue,
+ .start_streaming = rtl2832_sdr_start_streaming,
+ .stop_streaming = rtl2832_sdr_stop_streaming,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+};
+
+static int rtl2832_sdr_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ if (i->index != 0)
+ return -EINVAL;
+
+ strlcpy(i->name, "SDR data", sizeof(i->name));
+ i->type = V4L2_INPUT_TYPE_CAMERA;
+
+ return 0;
+}
+
+static int rtl2832_sdr_g_input(struct file *file, void *fh, unsigned int *i)
+{
+ *i = 0;
+
+ return 0;
+}
+
+static int rtl2832_sdr_s_input(struct file *file, void *fh, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ const struct v4l2_tuner *v)
+{
+ struct rtl2832_sdr_state *s = video_drvdata(file);
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ return 0;
+}
+
+static int vidioc_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:\n", __func__);
+
+ strcpy(v->name, "SDR RX");
+ v->capability = V4L2_TUNER_CAP_LOW;
+
+ return 0;
+}
+
+static int vidioc_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);
+
+ return v4l2_ctrl_s_ctrl_int64(s->ctrl_tuner_rf,
+ f->frequency * 625UL / 10UL);
+}
+
+static const struct v4l2_ioctl_ops rtl2832_sdr_ioctl_ops = {
+ .vidioc_querycap = rtl2832_sdr_querycap,
+
+ .vidioc_enum_input = rtl2832_sdr_enum_input,
+ .vidioc_g_input = rtl2832_sdr_g_input,
+ .vidioc_s_input = rtl2832_sdr_s_input,
+
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+
+ .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_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+};
+
+static const struct v4l2_file_operations rtl2832_sdr_fops = {
+ .owner = THIS_MODULE,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .read = vb2_fop_read,
+ .poll = vb2_fop_poll,
+ .mmap = vb2_fop_mmap,
+ .unlocked_ioctl = video_ioctl2,
+};
+
+static struct video_device rtl2832_sdr_template = {
+ .name = "Realtek RTL2832U SDR",
+ .release = video_device_release_empty,
+ .fops = &rtl2832_sdr_fops,
+ .ioctl_ops = &rtl2832_sdr_ioctl_ops,
+};
+
+static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct rtl2832_sdr_state *s =
+ container_of(ctrl->handler, struct rtl2832_sdr_state,
+ ctrl_handler);
+ int ret;
+ dev_dbg(&s->udev->dev,
+ "%s: id=%d name=%s val=%d min=%d max=%d step=%d\n",
+ __func__, ctrl->id, ctrl->name, ctrl->val,
+ ctrl->minimum, ctrl->maximum, ctrl->step);
+
+ switch (ctrl->id) {
+ case RTL2832_SDR_CID_SAMPLING_MODE:
+ case RTL2832_SDR_CID_SAMPLING_RATE:
+ case RTL2832_SDR_CID_SAMPLING_RESOLUTION:
+ ret = rtl2832_sdr_set_adc(s);
+ break;
+ case RTL2832_SDR_CID_TUNER_RF:
+ case RTL2832_SDR_CID_TUNER_BW:
+ case RTL2832_SDR_CID_TUNER_IF:
+ case RTL2832_SDR_CID_TUNER_GAIN:
+ ret = rtl2832_sdr_set_tuner(s);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops rtl2832_sdr_ctrl_ops = {
+ .s_ctrl = rtl2832_sdr_s_ctrl,
+};
+
+static void rtl2832_sdr_video_release(struct v4l2_device *v)
+{
+ struct rtl2832_sdr_state *s =
+ container_of(v, struct rtl2832_sdr_state, v4l2_dev);
+
+ v4l2_ctrl_handler_free(&s->ctrl_handler);
+ v4l2_device_unregister(&s->v4l2_dev);
+ kfree(s);
+}
+
+struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct rtl2832_sdr_config *cfg)
+{
+ int ret;
+ struct rtl2832_sdr_state *s;
+ struct dvb_usb_device *d = i2c_get_adapdata(i2c);
+ static const char * const ctrl_sampling_mode_qmenu_strings[] = {
+ "Quadrature Sampling",
+ NULL,
+ };
+ static const struct v4l2_ctrl_config ctrl_sampling_mode = {
+ .ops = &rtl2832_sdr_ctrl_ops,
+ .id = RTL2832_SDR_CID_SAMPLING_MODE,
+ .type = V4L2_CTRL_TYPE_MENU,
+ .flags = V4L2_CTRL_FLAG_INACTIVE,
+ .name = "Sampling Mode",
+ .qmenu = ctrl_sampling_mode_qmenu_strings,
+ };
+ static const struct v4l2_ctrl_config ctrl_sampling_rate = {
+ .ops = &rtl2832_sdr_ctrl_ops,
+ .id = RTL2832_SDR_CID_SAMPLING_RATE,
+ .type = V4L2_CTRL_TYPE_INTEGER64,
+ .name = "Sampling Rate",
+ .min = 500000,
+ .max = 4000000,
+ .def = 2048000,
+ .step = 1,
+ };
+ static const struct v4l2_ctrl_config ctrl_sampling_resolution = {
+ .ops = &rtl2832_sdr_ctrl_ops,
+ .id = RTL2832_SDR_CID_SAMPLING_RESOLUTION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_INACTIVE,
+ .name = "Sampling Resolution",
+ .min = 8,
+ .max = 8,
+ .def = 8,
+ .step = 1,
+ };
+ static const struct v4l2_ctrl_config ctrl_tuner_rf = {
+ .ops = &rtl2832_sdr_ctrl_ops,
+ .id = RTL2832_SDR_CID_TUNER_RF,
+ .type = V4L2_CTRL_TYPE_INTEGER64,
+ .name = "Tuner RF",
+ .min = 40000000,
+ .max = 2000000000,
+ .def = 100000000,
+ .step = 1,
+ };
+ static const struct v4l2_ctrl_config ctrl_tuner_bw = {
+ .ops = &rtl2832_sdr_ctrl_ops,
+ .id = RTL2832_SDR_CID_TUNER_BW,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Tuner BW",
+ .min = 200000,
+ .max = 8000000,
+ .def = 600000,
+ .step = 1,
+ };
+ static const struct v4l2_ctrl_config ctrl_tuner_if = {
+ .ops = &rtl2832_sdr_ctrl_ops,
+ .id = RTL2832_SDR_CID_TUNER_IF,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_INACTIVE,
+ .name = "Tuner IF",
+ .min = 0,
+ .max = 10,
+ .def = 0,
+ .step = 1,
+ };
+ static const struct v4l2_ctrl_config ctrl_tuner_gain = {
+ .ops = &rtl2832_sdr_ctrl_ops,
+ .id = RTL2832_SDR_CID_TUNER_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Tuner Gain",
+ .min = 0,
+ .max = 102,
+ .def = 0,
+ .step = 1,
+ };
+
+ s = kzalloc(sizeof(struct rtl2832_sdr_state), GFP_KERNEL);
+ if (s == NULL) {
+ dev_err(&d->udev->dev,
+ "Could not allocate memory for rtl2832_sdr_state\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* setup the state */
+ s->fe = fe;
+ s->d = d;
+ s->udev = d->udev;
+ s->i2c = i2c;
+ s->cfg = cfg;
+
+ mutex_init(&s->v4l2_lock);
+ mutex_init(&s->vb_queue_lock);
+ spin_lock_init(&s->queued_bufs_lock);
+ INIT_LIST_HEAD(&s->queued_bufs);
+
+ /* Init videobuf2 queue structure */
+ s->vb_queue.type = V4L2_BUF_TYPE_VIDEO_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);
+ s->vb_queue.ops = &rtl2832_sdr_vb2_ops;
+ s->vb_queue.mem_ops = &vb2_vmalloc_memops;
+ s->vb_queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ ret = vb2_queue_init(&s->vb_queue);
+ if (ret < 0) {
+ dev_err(&s->udev->dev, "Could not initialize vb2 queue\n");
+ goto err_free_mem;
+ }
+
+ /* Init video_device structure */
+ s->vdev = rtl2832_sdr_template;
+ s->vdev.queue = &s->vb_queue;
+ s->vdev.queue->lock = &s->vb_queue_lock;
+ set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
+ video_set_drvdata(&s->vdev, s);
+
+ /* Register controls */
+ v4l2_ctrl_handler_init(&s->ctrl_handler, 7);
+ v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_mode, NULL);
+ s->ctrl_sampling_rate = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_rate, NULL);
+ v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_resolution, NULL);
+ s->ctrl_tuner_rf = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_rf, NULL);
+ s->ctrl_tuner_bw = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_bw, NULL);
+ s->ctrl_tuner_if = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_if, NULL);
+ s->ctrl_tuner_gain = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_gain, NULL);
+ if (s->ctrl_handler.error) {
+ ret = s->ctrl_handler.error;
+ dev_err(&s->udev->dev, "Could not initialize controls\n");
+ goto err_free_controls;
+ }
+
+ /* Register the v4l2_device structure */
+ s->v4l2_dev.release = rtl2832_sdr_video_release;
+ ret = v4l2_device_register(&s->udev->dev, &s->v4l2_dev);
+ if (ret) {
+ dev_err(&s->udev->dev,
+ "Failed to register v4l2-device (%d)\n", ret);
+ goto err_free_controls;
+ }
+
+ s->v4l2_dev.ctrl_handler = &s->ctrl_handler;
+ s->vdev.v4l2_dev = &s->v4l2_dev;
+ s->vdev.lock = &s->v4l2_lock;
+
+ ret = video_register_device(&s->vdev, VFL_TYPE_GRABBER, -1);
+ if (ret < 0) {
+ dev_err(&s->udev->dev,
+ "Failed to register as video device (%d)\n",
+ ret);
+ goto err_unregister_v4l2_dev;
+ }
+ dev_info(&s->udev->dev, "Registered as %s\n",
+ video_device_node_name(&s->vdev));
+
+ fe->sec_priv = s;
+ fe->ops.release_sec = rtl2832_sdr_release_sec;
+
+ dev_info(&s->i2c->dev, "%s: Realtek RTL2832 SDR attached\n",
+ KBUILD_MODNAME);
+ return fe;
+
+err_unregister_v4l2_dev:
+ v4l2_device_unregister(&s->v4l2_dev);
+err_free_controls:
+ v4l2_ctrl_handler_free(&s->ctrl_handler);
+err_free_mem:
+ kfree(s);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(rtl2832_sdr_attach);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Realtek RTL2832 SDR driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
new file mode 100644
index 0000000..69d97c1
--- /dev/null
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
@@ -0,0 +1,52 @@
+/*
+ * Realtek RTL2832U SDR driver
+ *
+ * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 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
+ */
+
+#ifndef RTL2832_SDR_H
+#define RTL2832_SDR_H
+
+#include <linux/kconfig.h>
+
+struct rtl2832_sdr_config {
+ u8 i2c_addr;
+};
+
+#if IS_ENABLED(CONFIG_DVB_RTL2832_SDR)
+extern struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct rtl2832_sdr_config *cfg);
+#else
+static inline struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, const struct rtl2832_sdr_config *cfg)
+{
+ dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* RTL2832_SDR_H */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 02/52] rtl28xxu: attach SDR extension module
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
2014-01-25 17:09 ` [PATCH 01/52] rtl2832_sdr: Realtek RTL2832 SDR driver module Antti Palosaari
@ 2014-01-25 17:09 ` Antti Palosaari
2014-01-25 17:09 ` [PATCH 03/52] rtl2832_sdr: use config struct from rtl2832 module Antti Palosaari
` (49 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:09 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
With that extension module it supports SDR.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/usb/dvb-usb-v2/Makefile | 1 +
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 8 ++++++++
2 files changed, 9 insertions(+)
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
index 2c06714..bfe67f9 100644
--- a/drivers/media/usb/dvb-usb-v2/Makefile
+++ b/drivers/media/usb/dvb-usb-v2/Makefile
@@ -44,3 +44,4 @@ ccflags-y += -I$(srctree)/drivers/media/dvb-core
ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
ccflags-y += -I$(srctree)/drivers/media/tuners
ccflags-y += -I$(srctree)/drivers/media/common
+ccflags-y += -I$(srctree)/drivers/staging/media/rtl2832u_sdr
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index fda5c64..b398ebf 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -24,6 +24,7 @@
#include "rtl2830.h"
#include "rtl2832.h"
+#include "rtl2832_sdr.h"
#include "qt1010.h"
#include "mt2060.h"
@@ -734,6 +735,9 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
struct dvb_usb_device *d = adap_to_d(adap);
struct rtl28xxu_priv *priv = d_to_priv(d);
struct rtl2832_config *rtl2832_config;
+ static const struct rtl2832_sdr_config rtl2832_sdr_config = {
+ .i2c_addr = 0x10,
+ };
dev_dbg(&d->udev->dev, "%s:\n", __func__);
@@ -775,6 +779,10 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
/* set fe callback */
adap->fe[0]->callback = rtl2832u_frontend_callback;
+ /* attach SDR */
+ dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
+ &rtl2832_sdr_config);
+
return 0;
err:
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 03/52] rtl2832_sdr: use config struct from rtl2832 module
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
2014-01-25 17:09 ` [PATCH 01/52] rtl2832_sdr: Realtek RTL2832 SDR driver module Antti Palosaari
2014-01-25 17:09 ` [PATCH 02/52] rtl28xxu: attach SDR extension module Antti Palosaari
@ 2014-01-25 17:09 ` Antti Palosaari
2014-01-25 17:09 ` [PATCH 04/52] rtl2832_sdr: initial support for R820T tuner Antti Palosaari
` (48 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:09 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
There is absolutely no need to define own configuration struct as
same params are used demod main module. So use existing config.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 5 +----
drivers/staging/media/rtl2832u_sdr/Makefile | 1 +
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 4 ++--
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h | 9 ++++-----
4 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index b398ebf..ec6ab0f 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -735,9 +735,6 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
struct dvb_usb_device *d = adap_to_d(adap);
struct rtl28xxu_priv *priv = d_to_priv(d);
struct rtl2832_config *rtl2832_config;
- static const struct rtl2832_sdr_config rtl2832_sdr_config = {
- .i2c_addr = 0x10,
- };
dev_dbg(&d->udev->dev, "%s:\n", __func__);
@@ -781,7 +778,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
/* attach SDR */
dvb_attach(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
- &rtl2832_sdr_config);
+ rtl2832_config);
return 0;
err:
diff --git a/drivers/staging/media/rtl2832u_sdr/Makefile b/drivers/staging/media/rtl2832u_sdr/Makefile
index 684546776..1009276 100644
--- a/drivers/staging/media/rtl2832u_sdr/Makefile
+++ b/drivers/staging/media/rtl2832u_sdr/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
ccflags-y += -Idrivers/media/usb/dvb-usb-v2
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 0b110a3..208520e 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -61,7 +61,7 @@ struct rtl2832_sdr_state {
#define URB_BUF (1 << 2)
unsigned long flags;
- const struct rtl2832_sdr_config *cfg;
+ const struct rtl2832_config *cfg;
struct dvb_frontend *fe;
struct dvb_usb_device *d;
struct i2c_adapter *i2c;
@@ -1004,7 +1004,7 @@ static void rtl2832_sdr_video_release(struct v4l2_device *v)
}
struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c, const struct rtl2832_sdr_config *cfg)
+ struct i2c_adapter *i2c, const struct rtl2832_config *cfg)
{
int ret;
struct rtl2832_sdr_state *s;
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
index 69d97c1..0803e45 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.h
@@ -33,16 +33,15 @@
#include <linux/kconfig.h>
-struct rtl2832_sdr_config {
- u8 i2c_addr;
-};
+/* for config struct */
+#include "rtl2832.h"
#if IS_ENABLED(CONFIG_DVB_RTL2832_SDR)
extern struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c, const struct rtl2832_sdr_config *cfg);
+ struct i2c_adapter *i2c, const struct rtl2832_config *cfg);
#else
static inline struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c, const struct rtl2832_sdr_config *cfg)
+ struct i2c_adapter *i2c, const struct rtl2832_config *cfg)
{
dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
return NULL;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 04/52] rtl2832_sdr: initial support for R820T tuner
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (2 preceding siblings ...)
2014-01-25 17:09 ` [PATCH 03/52] rtl2832_sdr: use config struct from rtl2832 module Antti Palosaari
@ 2014-01-25 17:09 ` Antti Palosaari
2014-01-25 17:09 ` [PATCH 05/52] rtl2832_sdr: use get_if_frequency() Antti Palosaari
` (47 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:09 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Use tuner via internal DVB API.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 84 +++++++++++++++---------
1 file changed, 53 insertions(+), 31 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 208520e..513da22 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -646,8 +646,16 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x115, "\x00", 1);
ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\x00", 2);
ret = rtl2832_sdr_wr_regs(s, 0x118, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x119, "\x00\x00", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x11b, "\x00", 1);
+
+ if (s->cfg->tuner == RTL2832_TUNER_R820T) {
+ ret = rtl2832_sdr_wr_regs(s, 0x119, "\x38\x11", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x11b, "\x12", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x115, "\x01", 1);
+ } else {
+ ret = rtl2832_sdr_wr_regs(s, 0x119, "\x00\x00", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x11b, "\x00", 1);
+ }
+
ret = rtl2832_sdr_wr_regs(s, 0x19f, "\x03\x84", 2);
ret = rtl2832_sdr_wr_regs(s, 0x1a1, "\x00\x00", 2);
ret = rtl2832_sdr_wr_regs(s, 0x11c, "\xca", 1);
@@ -686,11 +694,21 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x006, "\x80", 1);
ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x30", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x104, "\xd0", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x18", 1);
+
+ if (s->cfg->tuner == RTL2832_TUNER_R820T) {
+ ret = rtl2832_sdr_wr_regs(s, 0x103, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x24", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x14", 1);
+ } else {
+ ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x30", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x104, "\xd0", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x18", 1);
+ }
+
ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
@@ -704,30 +722,34 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x011, "\xd4", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x14", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xec", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x83", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x010, "\x49", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x87", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x85", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x013, "\x02", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x008, "\xcd", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1b1, "\x01", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x019, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10c, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\xe3", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x118, "\x8e", 1);
+
+ if (s->cfg->tuner == RTL2832_TUNER_R820T) {
+ ret = rtl2832_sdr_wr_regs(s, 0x011, "\xf4", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x019, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\x00", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x118, "\x00", 1);
+ } else {
+ ret = rtl2832_sdr_wr_regs(s, 0x011, "\xd4", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x14", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xec", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x83", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x010, "\x49", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x87", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x85", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x013, "\x02", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x008, "\xcd", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10c, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
+ }
return ret;
};
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 05/52] rtl2832_sdr: use get_if_frequency()
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (3 preceding siblings ...)
2014-01-25 17:09 ` [PATCH 04/52] rtl2832_sdr: initial support for R820T tuner Antti Palosaari
@ 2014-01-25 17:09 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 06/52] rtl2832_sdr: implement sampling rate Antti Palosaari
` (46 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:09 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Get IF from tuner and use it.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 60 ++++++++++++++++++++----
1 file changed, 51 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 513da22..c4b72c1 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -208,7 +208,15 @@ static int rtl2832_sdr_rd_regs(struct rtl2832_sdr_state *s, u16 reg, u8 *val,
return rtl2832_sdr_rd(s, reg2, val, len);
}
+#endif
+/* write single register */
+static int rtl2832_sdr_wr_reg(struct rtl2832_sdr_state *s, u16 reg, u8 val)
+{
+ return rtl2832_sdr_wr_regs(s, reg, &val, 1);
+}
+
+#if 0
/* read single register */
static int rtl2832_sdr_rd_reg(struct rtl2832_sdr_state *s, u16 reg, u8 *val)
{
@@ -632,8 +640,12 @@ static void rtl2832_sdr_buf_queue(struct vb2_buffer *vb)
static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
{
+ struct dvb_frontend *fe = s->fe;
int ret;
- unsigned int f_sr;
+ unsigned int f_sr, f_if;
+ u8 buf[3], tmp;
+ u64 u64tmp;
+ u32 u32tmp;
dev_dbg(&s->udev->dev, "%s:\n", __func__);
@@ -647,14 +659,42 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\x00", 2);
ret = rtl2832_sdr_wr_regs(s, 0x118, "\x00", 1);
- if (s->cfg->tuner == RTL2832_TUNER_R820T) {
- ret = rtl2832_sdr_wr_regs(s, 0x119, "\x38\x11", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x11b, "\x12", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x115, "\x01", 1);
- } else {
- ret = rtl2832_sdr_wr_regs(s, 0x119, "\x00\x00", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x11b, "\x00", 1);
- }
+ /* get IF from tuner */
+ if (fe->ops.tuner_ops.get_if_frequency)
+ ret = fe->ops.tuner_ops.get_if_frequency(fe, &f_if);
+ else
+ ret = -EINVAL;
+
+ if (ret)
+ goto err;
+
+ /* program IF */
+ u64tmp = f_if % s->cfg->xtal;
+ u64tmp *= 0x400000;
+ u64tmp = div_u64(u64tmp, s->cfg->xtal);
+ u64tmp = -u64tmp;
+ u32tmp = u64tmp & 0x3fffff;
+
+ dev_dbg(&s->udev->dev, "%s: f_if=%u if_ctl=%08x\n",
+ __func__, f_if, u32tmp);
+
+ buf[0] = (u32tmp >> 16) & 0xff;
+ buf[1] = (u32tmp >> 8) & 0xff;
+ buf[2] = (u32tmp >> 0) & 0xff;
+
+ ret = rtl2832_sdr_wr_regs(s, 0x119, buf, 3);
+ if (ret)
+ goto err;
+
+ /* program BB / IF mode */
+ if (f_if)
+ tmp = 0x00;
+ else
+ tmp = 0x01;
+
+ ret = rtl2832_sdr_wr_reg(s, 0x1b1, tmp);
+ if (ret)
+ goto err;
ret = rtl2832_sdr_wr_regs(s, 0x19f, "\x03\x84", 2);
ret = rtl2832_sdr_wr_regs(s, 0x1a1, "\x00\x00", 2);
@@ -696,6 +736,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
if (s->cfg->tuner == RTL2832_TUNER_R820T) {
+ ret = rtl2832_sdr_wr_regs(s, 0x115, "\x01", 1);
ret = rtl2832_sdr_wr_regs(s, 0x103, "\x80", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x24", 1);
ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
@@ -751,6 +792,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
}
+err:
return ret;
};
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 06/52] rtl2832_sdr: implement sampling rate
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (4 preceding siblings ...)
2014-01-25 17:09 ` [PATCH 05/52] rtl2832_sdr: use get_if_frequency() Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 07/52] rtl2832_sdr: initial support for FC0012 tuner Antti Palosaari
` (45 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Now it is possible to set desired sampling rate via v4l2 controls.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index c4b72c1..0e12e1a 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -38,6 +38,8 @@
#include <media/v4l2-event.h>
#include <media/videobuf2-vmalloc.h>
+#include <linux/math64.h>
+
/* TODO: These should be moved to V4L2 API */
#define RTL2832_SDR_CID_SAMPLING_MODE ((V4L2_CID_USER_BASE | 0xf000) + 0)
#define RTL2832_SDR_CID_SAMPLING_RATE ((V4L2_CID_USER_BASE | 0xf000) + 1)
@@ -643,7 +645,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
struct dvb_frontend *fe = s->fe;
int ret;
unsigned int f_sr, f_if;
- u8 buf[3], tmp;
+ u8 buf[4], tmp;
u64 u64tmp;
u32 u32tmp;
@@ -696,8 +698,17 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
if (ret)
goto err;
- ret = rtl2832_sdr_wr_regs(s, 0x19f, "\x03\x84", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x1a1, "\x00\x00", 2);
+ /* program sampling rate (resampling down) */
+ u32tmp = div_u64(s->cfg->xtal * 0x400000ULL, f_sr * 4U);
+ u32tmp <<= 2;
+ buf[0] = (u32tmp >> 24) & 0xff;
+ buf[1] = (u32tmp >> 16) & 0xff;
+ buf[2] = (u32tmp >> 8) & 0xff;
+ buf[3] = (u32tmp >> 0) & 0xff;
+ ret = rtl2832_sdr_wr_regs(s, 0x19f, buf, 4);
+ if (ret)
+ goto err;
+
ret = rtl2832_sdr_wr_regs(s, 0x11c, "\xca", 1);
ret = rtl2832_sdr_wr_regs(s, 0x11d, "\xdc", 1);
ret = rtl2832_sdr_wr_regs(s, 0x11e, "\xd7", 1);
@@ -1090,8 +1101,8 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
.id = RTL2832_SDR_CID_SAMPLING_RATE,
.type = V4L2_CTRL_TYPE_INTEGER64,
.name = "Sampling Rate",
- .min = 500000,
- .max = 4000000,
+ .min = 900001,
+ .max = 2800000,
.def = 2048000,
.step = 1,
};
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 07/52] rtl2832_sdr: initial support for FC0012 tuner
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (5 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 06/52] rtl2832_sdr: implement sampling rate Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 08/52] rtl2832_sdr: initial support for FC0013 tuner Antti Palosaari
` (44 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Use tuner via internal DVB API.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 0e12e1a..c088957 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -753,6 +753,12 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x14", 1);
+ } else if (s->cfg->tuner == RTL2832_TUNER_FC0012) {
+ ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x2c", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x16", 1);
} else {
ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x30", 1);
@@ -782,6 +788,19 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x019, "\x21", 1);
ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\x00", 2);
ret = rtl2832_sdr_wr_regs(s, 0x118, "\x00", 1);
+ } else if (s->cfg->tuner == RTL2832_TUNER_FC0012) {
+ ret = rtl2832_sdr_wr_regs(s, 0x011, "\xe9\xbf", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x11", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xef", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x008, "\xcd", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
} else {
ret = rtl2832_sdr_wr_regs(s, 0x011, "\xd4", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 08/52] rtl2832_sdr: initial support for FC0013 tuner
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (6 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 07/52] rtl2832_sdr: initial support for FC0012 tuner Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 09/52] rtl28xxu: constify demod config structs Antti Palosaari
` (43 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Use tuner via internal DVB API.
It is about same tuner than FC0012 and uses just same settings.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index c088957..2c84654 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -753,7 +753,8 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x14", 1);
- } else if (s->cfg->tuner == RTL2832_TUNER_FC0012) {
+ } else if (s->cfg->tuner == RTL2832_TUNER_FC0012 ||
+ s->cfg->tuner == RTL2832_TUNER_FC0013) {
ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x2c", 1);
ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
@@ -788,7 +789,8 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x019, "\x21", 1);
ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\x00", 2);
ret = rtl2832_sdr_wr_regs(s, 0x118, "\x00", 1);
- } else if (s->cfg->tuner == RTL2832_TUNER_FC0012) {
+ } else if (s->cfg->tuner == RTL2832_TUNER_FC0012 ||
+ s->cfg->tuner == RTL2832_TUNER_FC0013) {
ret = rtl2832_sdr_wr_regs(s, 0x011, "\xe9\xbf", 2);
ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 09/52] rtl28xxu: constify demod config structs
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (7 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 08/52] rtl2832_sdr: initial support for FC0013 tuner Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 10/52] rtl2832: remove unused if_dvbt config parameter Antti Palosaari
` (42 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Optimize a little bit from data to text.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index ec6ab0f..c0e651a 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -514,7 +514,7 @@ err:
return ret;
}
-static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
+static const struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
.i2c_addr = 0x10, /* 0x20 */
.xtal = 28800000,
.ts_mode = 0,
@@ -525,7 +525,7 @@ static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
};
-static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
+static const struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
.i2c_addr = 0x10, /* 0x20 */
.xtal = 28800000,
.ts_mode = 0,
@@ -535,7 +535,7 @@ static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
.agc_targ_val = 0x2d,
};
-static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
+static const struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
.i2c_addr = 0x10, /* 0x20 */
.xtal = 28800000,
.ts_mode = 0,
@@ -549,7 +549,7 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
{
struct dvb_usb_device *d = adap_to_d(adap);
struct rtl28xxu_priv *priv = d_to_priv(d);
- struct rtl2830_config *rtl2830_config;
+ const struct rtl2830_config *rtl2830_config;
int ret;
dev_dbg(&d->udev->dev, "%s:\n", __func__);
@@ -584,33 +584,33 @@ err:
return ret;
}
-static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
.i2c_addr = 0x10, /* 0x20 */
.xtal = 28800000,
.if_dvbt = 0,
.tuner = TUNER_RTL2832_FC0012
};
-static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
.i2c_addr = 0x10, /* 0x20 */
.xtal = 28800000,
.if_dvbt = 0,
.tuner = TUNER_RTL2832_FC0013
};
-static struct rtl2832_config rtl28xxu_rtl2832_tua9001_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_tua9001_config = {
.i2c_addr = 0x10, /* 0x20 */
.xtal = 28800000,
.tuner = TUNER_RTL2832_TUA9001,
};
-static struct rtl2832_config rtl28xxu_rtl2832_e4000_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_e4000_config = {
.i2c_addr = 0x10, /* 0x20 */
.xtal = 28800000,
.tuner = TUNER_RTL2832_E4000,
};
-static struct rtl2832_config rtl28xxu_rtl2832_r820t_config = {
+static const struct rtl2832_config rtl28xxu_rtl2832_r820t_config = {
.i2c_addr = 0x10,
.xtal = 28800000,
.tuner = TUNER_RTL2832_R820T,
@@ -734,7 +734,7 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
int ret;
struct dvb_usb_device *d = adap_to_d(adap);
struct rtl28xxu_priv *priv = d_to_priv(d);
- struct rtl2832_config *rtl2832_config;
+ const struct rtl2832_config *rtl2832_config;
dev_dbg(&d->udev->dev, "%s:\n", __func__);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 10/52] rtl2832: remove unused if_dvbt config parameter
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (8 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 09/52] rtl28xxu: constify demod config structs Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 11/52] rtl2832: style changes and minor cleanup Antti Palosaari
` (41 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
All used tuners has get_if_frequency() callback and that parameter
is not needed and will not needed as all upcoming tuner drivers
should implement get_if_frequency().
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/rtl2832.c | 6 ------
drivers/media/dvb-frontends/rtl2832.h | 7 -------
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 2 --
3 files changed, 15 deletions(-)
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
index ff73da9..61d4ecb 100644
--- a/drivers/media/dvb-frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -514,12 +514,6 @@ static int rtl2832_init(struct dvb_frontend *fe)
goto err;
}
- if (!fe->ops.tuner_ops.get_if_frequency) {
- ret = rtl2832_set_if(fe, priv->cfg.if_dvbt);
- if (ret)
- goto err;
- }
-
/*
* r820t NIM code does a software reset here at the demod -
* may not be needed, as there's already a software reset at set_params()
diff --git a/drivers/media/dvb-frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h
index 2cfbb6a..e543081 100644
--- a/drivers/media/dvb-frontends/rtl2832.h
+++ b/drivers/media/dvb-frontends/rtl2832.h
@@ -38,13 +38,6 @@ struct rtl2832_config {
u32 xtal;
/*
- * IFs for all used modes.
- * Hz
- * 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
- */
- u32 if_dvbt;
-
- /*
* tuner
* XXX: This must be keep sync with dvb_usb_rtl28xxu demod driver.
*/
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index c0e651a..6a5eb0f 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -587,14 +587,12 @@ err:
static const struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
.i2c_addr = 0x10, /* 0x20 */
.xtal = 28800000,
- .if_dvbt = 0,
.tuner = TUNER_RTL2832_FC0012
};
static const struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
.i2c_addr = 0x10, /* 0x20 */
.xtal = 28800000,
- .if_dvbt = 0,
.tuner = TUNER_RTL2832_FC0013
};
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 11/52] rtl2832: style changes and minor cleanup
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (9 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 10/52] rtl2832: remove unused if_dvbt config parameter Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 12/52] rtl2832_sdr: pixel format for SDR Antti Palosaari
` (40 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Most of those were reported by checkpatch.pl...
debug module parameter is not used anywhere so remove it.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/dvb-frontends/rtl2832.c | 26 +++++++---------
drivers/media/dvb-frontends/rtl2832.h | 2 +-
drivers/media/dvb-frontends/rtl2832_priv.h | 50 +++++++++++++++---------------
3 files changed, 38 insertions(+), 40 deletions(-)
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
index 61d4ecb..00e63b9 100644
--- a/drivers/media/dvb-frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -24,11 +24,6 @@
/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE 64
-
-int rtl2832_debug;
-module_param_named(debug, rtl2832_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
#define REG_MASK(b) (BIT(b + 1) - 1)
static const struct rtl2832_reg_entry registers[] = {
@@ -189,8 +184,9 @@ static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
if (ret == 1) {
ret = 0;
} else {
- dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
- "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+ dev_warn(&priv->i2c->dev,
+ "%s: i2c wr failed=%d reg=%02x len=%d\n",
+ KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
@@ -218,8 +214,9 @@ static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
if (ret == 2) {
ret = 0;
} else {
- dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
- "len=%d\n", KBUILD_MODNAME, ret, reg, len);
+ dev_warn(&priv->i2c->dev,
+ "%s: i2c rd failed=%d reg=%02x len=%d\n",
+ KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
}
return ret;
@@ -417,7 +414,7 @@ static int rtl2832_set_if(struct dvb_frontend *fe, u32 if_freq)
ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
- return (ret);
+ return ret;
}
static int rtl2832_init(struct dvb_frontend *fe)
@@ -516,7 +513,8 @@ static int rtl2832_init(struct dvb_frontend *fe)
/*
* r820t NIM code does a software reset here at the demod -
- * may not be needed, as there's already a software reset at set_params()
+ * may not be needed, as there's already a software reset at
+ * set_params()
*/
#if 1
/* soft reset */
@@ -593,9 +591,9 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
};
- dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d " \
- "inversion=%d\n", __func__, c->frequency,
- c->bandwidth_hz, c->inversion);
+ dev_dbg(&priv->i2c->dev,
+ "%s: frequency=%d bandwidth_hz=%d inversion=%d\n",
+ __func__, c->frequency, c->bandwidth_hz, c->inversion);
/* program tuner */
if (fe->ops.tuner_ops.set_params)
diff --git a/drivers/media/dvb-frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h
index e543081..fa4e5f6 100644
--- a/drivers/media/dvb-frontends/rtl2832.h
+++ b/drivers/media/dvb-frontends/rtl2832.h
@@ -51,7 +51,7 @@ struct rtl2832_config {
};
#if IS_ENABLED(CONFIG_DVB_RTL2832)
-extern struct dvb_frontend *rtl2832_attach(
+struct dvb_frontend *rtl2832_attach(
const struct rtl2832_config *cfg,
struct i2c_adapter *i2c
);
diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h
index b5f2b80..4c845af 100644
--- a/drivers/media/dvb-frontends/rtl2832_priv.h
+++ b/drivers/media/dvb-frontends/rtl2832_priv.h
@@ -267,7 +267,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_tua9001[] = {
{DVBT_OPT_ADC_IQ, 0x1},
{DVBT_AD_AVI, 0x0},
{DVBT_AD_AVQ, 0x0},
- {DVBT_SPEC_INV, 0x0},
+ {DVBT_SPEC_INV, 0x0},
};
static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
@@ -301,7 +301,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
{DVBT_GI_PGA_STATE, 0x0},
{DVBT_EN_AGC_PGA, 0x1},
{DVBT_IF_AGC_MAN, 0x0},
- {DVBT_SPEC_INV, 0x0},
+ {DVBT_SPEC_INV, 0x0},
};
static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
@@ -339,32 +339,32 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
{DVBT_REG_MONSEL, 0x1},
{DVBT_REG_MON, 0x1},
{DVBT_REG_4MSEL, 0x0},
- {DVBT_SPEC_INV, 0x0},
+ {DVBT_SPEC_INV, 0x0},
};
static const struct rtl2832_reg_value rtl2832_tuner_init_r820t[] = {
- {DVBT_DAGC_TRG_VAL, 0x39},
- {DVBT_AGC_TARG_VAL_0, 0x0},
- {DVBT_AGC_TARG_VAL_8_1, 0x40},
- {DVBT_AAGC_LOOP_GAIN, 0x16},
- {DVBT_LOOP_GAIN2_3_0, 0x8},
- {DVBT_LOOP_GAIN2_4, 0x1},
- {DVBT_LOOP_GAIN3, 0x18},
- {DVBT_VTOP1, 0x35},
- {DVBT_VTOP2, 0x21},
- {DVBT_VTOP3, 0x21},
- {DVBT_KRF1, 0x0},
- {DVBT_KRF2, 0x40},
- {DVBT_KRF3, 0x10},
- {DVBT_KRF4, 0x10},
- {DVBT_IF_AGC_MIN, 0x80},
- {DVBT_IF_AGC_MAX, 0x7f},
- {DVBT_RF_AGC_MIN, 0x80},
- {DVBT_RF_AGC_MAX, 0x7f},
- {DVBT_POLAR_RF_AGC, 0x0},
- {DVBT_POLAR_IF_AGC, 0x0},
- {DVBT_AD7_SETTING, 0xe9f4},
- {DVBT_SPEC_INV, 0x1},
+ {DVBT_DAGC_TRG_VAL, 0x39},
+ {DVBT_AGC_TARG_VAL_0, 0x0},
+ {DVBT_AGC_TARG_VAL_8_1, 0x40},
+ {DVBT_AAGC_LOOP_GAIN, 0x16},
+ {DVBT_LOOP_GAIN2_3_0, 0x8},
+ {DVBT_LOOP_GAIN2_4, 0x1},
+ {DVBT_LOOP_GAIN3, 0x18},
+ {DVBT_VTOP1, 0x35},
+ {DVBT_VTOP2, 0x21},
+ {DVBT_VTOP3, 0x21},
+ {DVBT_KRF1, 0x0},
+ {DVBT_KRF2, 0x40},
+ {DVBT_KRF3, 0x10},
+ {DVBT_KRF4, 0x10},
+ {DVBT_IF_AGC_MIN, 0x80},
+ {DVBT_IF_AGC_MAX, 0x7f},
+ {DVBT_RF_AGC_MIN, 0x80},
+ {DVBT_RF_AGC_MAX, 0x7f},
+ {DVBT_POLAR_RF_AGC, 0x0},
+ {DVBT_POLAR_IF_AGC, 0x0},
+ {DVBT_AD7_SETTING, 0xe9f4},
+ {DVBT_SPEC_INV, 0x1},
};
#endif /* RTL2832_PRIV_H */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 12/52] rtl2832_sdr: pixel format for SDR
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (10 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 11/52] rtl2832: style changes and minor cleanup Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 13/52] rtl2832_sdr: implement FMT IOCTLs Antti Palosaari
` (39 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
These are used for converting / streaming I/Q data from SDR.
* unsigned 8-bit
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 2c84654..d3db859 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -49,6 +49,8 @@
#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 MAX_BULK_BUFS (8)
#define BULK_BUFFER_SIZE (8 * 512)
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 13/52] rtl2832_sdr: implement FMT IOCTLs
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (11 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 12/52] rtl2832_sdr: pixel format for SDR Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 14/52] msi3101: add signed 8-bit pixel format for SDR Antti Palosaari
` (38 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
VIDIOC_ENUM_FMT, VIDIOC_G_FMT, VIDIOC_S_FMT and VIDIOC_TRY_FMT.
Return stream according to FMT.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 125 ++++++++++++++---------
1 file changed, 75 insertions(+), 50 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index d3db859..348df05 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -291,56 +291,10 @@ leave:
return buf;
}
-/*
- * Integer to 32-bit IEEE floating point representation routine is taken
- * from Radeon R600 driver (drivers/gpu/drm/radeon/r600_blit_kms.c).
- *
- * TODO: Currently we do conversion here in Kernel, but in future that will
- * be moved to the libv4l2 library as video format conversions are.
- */
-#define I2F_FRAC_BITS 23
-#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
-
-/*
- * Converts signed 8-bit integer into 32-bit IEEE floating point
- * representation.
- */
-static u32 rtl2832_sdr_convert_sample(struct rtl2832_sdr_state *s, u16 x)
-{
- u32 msb, exponent, fraction, sign;
-
- /* Zero is special */
- if (!x)
- return 0;
-
- /* Negative / positive value */
- if (x & (1 << 7)) {
- x = -x;
- x &= 0x7f; /* result is 7 bit ... + sign */
- sign = 1 << 31;
- } else {
- sign = 0 << 31;
- }
-
- /* Get location of the most significant bit */
- msb = __fls(x);
-
- fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
- exponent = (127 + msb) << I2F_FRAC_BITS;
-
- return (fraction + exponent) | sign;
-}
-
static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
- u32 *dst, const u8 *src, unsigned int src_len)
+ u8 *dst, const u8 *src, unsigned int src_len)
{
- unsigned int i, dst_len = 0;
-
- for (i = 0; i < src_len; i++)
- *dst++ = rtl2832_sdr_convert_sample(s, src[i]);
-
- /* 8-bit to 32-bit IEEE floating point */
- dst_len = src_len * 4;
+ memcpy(dst, src, src_len);
/* calculate samping rate and output it in 10 seconds intervals */
if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
@@ -358,7 +312,7 @@ static unsigned int rtl2832_sdr_convert_stream(struct rtl2832_sdr_state *s,
/* total number of I+Q pairs */
s->sample += src_len / 2;
- return dst_len;
+ return src_len;
}
/*
@@ -591,7 +545,6 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
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;
- cap->device_caps = V4L2_CAP_TUNER;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -1014,9 +967,81 @@ static int vidioc_s_frequency(struct file *file, void *priv,
f->frequency * 625UL / 10UL);
}
+static int rtl2832_sdr_enum_fmt_vid_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)
+ return -EINVAL;
+
+ f->flags = 0;
+ strcpy(f->description, "I/Q 8-bit unsigned");
+ f->pixelformat = V4L2_PIX_FMT_SDR_U8;
+
+ return 0;
+}
+
+static int rtl2832_sdr_g_fmt_vid_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)
+ return -EINVAL;
+
+ memset(&f->fmt.pix, 0, sizeof(f->fmt.pix));
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_SDR_U8;
+
+ return 0;
+}
+
+static int rtl2832_sdr_s_fmt_vid_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;
+ dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+ (char *)&f->fmt.pix.pixelformat);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_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;
+
+ return 0;
+}
+
+static int rtl2832_sdr_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct rtl2832_sdr_state *s = video_drvdata(file);
+ dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+ (char *)&f->fmt.pix.pixelformat);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ memset(&f->fmt.pix, 0, sizeof(f->fmt.pix));
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_SDR_U8;
+
+ return 0;
+}
+
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_input = rtl2832_sdr_enum_input,
.vidioc_g_input = rtl2832_sdr_g_input,
.vidioc_s_input = rtl2832_sdr_s_input,
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 14/52] msi3101: add signed 8-bit pixel format for SDR
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (12 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 13/52] rtl2832_sdr: implement FMT IOCTLs Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 15/52] msi3101: implement FMT IOCTLs Antti Palosaari
` (37 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
It is 8-bit unsigned data, byte after byte. Used for streaming SDR
I/Q data from ADC.
V4L2_PIX_FMT_SDR_S8, v4l fourcc "DS08".
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 4c3bf77..e208b57 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -385,6 +385,8 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
#define MSI3101_CID_TUNER_IF ((V4L2_CID_USER_BASE | 0xf000) + 12)
#define MSI3101_CID_TUNER_GAIN ((V4L2_CID_USER_BASE | 0xf000) + 13)
+#define V4L2_PIX_FMT_SDR_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
+
/* intermediate buffers with raw data from the USB device */
struct msi3101_frame_buf {
struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 15/52] msi3101: implement FMT IOCTLs
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (13 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 14/52] msi3101: add signed 8-bit pixel format for SDR Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 16/52] msi3101: move format 384 conversion to libv4lconvert Antti Palosaari
` (36 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
VIDIOC_ENUM_FMT, VIDIOC_G_FMT, VIDIOC_S_FMT and VIDIOC_TRY_FMT.
Implement 8-bit signed stream (type '504' samples per USB packet)
using FMT.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 165 +++++++++++++++++++++-------
1 file changed, 123 insertions(+), 42 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index e208b57..ba68ea9 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -387,6 +387,22 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
#define V4L2_PIX_FMT_SDR_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
+/* stream formats */
+struct msi3101_format {
+ char *name;
+ u32 pixelformat;
+};
+
+/* format descriptions for capture and preview */
+static struct msi3101_format formats[] = {
+ {
+ .name = "I/Q 8-bit signed",
+ .pixelformat = V4L2_PIX_FMT_SDR_S8,
+ },
+};
+
+static const int NUM_FORMATS = sizeof(formats) / sizeof(struct msi3101_format);
+
/* intermediate buffers with raw data from the USB device */
struct msi3101_frame_buf {
struct vb2_buffer vb; /* common v4l buffer stuff -- must be first */
@@ -409,6 +425,8 @@ struct msi3101_state {
/* Pointer to our usb_device, will be NULL after unplug */
struct usb_device *udev; /* Both mutexes most be hold when setting! */
+ u32 pixelformat;
+
unsigned int isoc_errors; /* number of contiguous ISOC errors */
unsigned int vb_full; /* vb is full and packets dropped */
@@ -447,7 +465,6 @@ leave:
spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
return buf;
}
-
/*
* +===========================================================================
* | 00-1023 | USB packet type '384'
@@ -504,40 +521,22 @@ leave:
#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
/*
- * Converts signed 8-bit integer into 32-bit IEEE floating point
- * representation.
+ * +===========================================================================
+ * | 00-1023 | USB packet type '504'
+ * +===========================================================================
+ * | 00- 03 | sequence number of first sample in that USB packet
+ * +---------------------------------------------------------------------------
+ * | 04- 15 | garbage
+ * +---------------------------------------------------------------------------
+ * | 16-1023 | samples
+ * +---------------------------------------------------------------------------
+ * signed 8-bit sample
+ * 504 * 2 = 1008 samples
*/
-static u32 msi3101_convert_sample_504(struct msi3101_state *s, u16 x)
-{
- u32 msb, exponent, fraction, sign;
-
- /* Zero is special */
- if (!x)
- return 0;
-
- /* Negative / positive value */
- if (x & (1 << 7)) {
- x = -x;
- x &= 0x7f; /* result is 7 bit ... + sign */
- sign = 1 << 31;
- } else {
- sign = 0 << 31;
- }
-
- /* Get location of the most significant bit */
- msb = __fls(x);
-
- fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
- exponent = (127 + msb) << I2F_FRAC_BITS;
-
- return (fraction + exponent) | sign;
-}
-
-static int msi3101_convert_stream_504(struct msi3101_state *s, u32 *dst,
+static int msi3101_convert_stream_504(struct msi3101_state *s, u8 *dst,
u8 *src, unsigned int src_len)
{
- int i, j, i_max, dst_len = 0;
- u16 sample[2];
+ int i, i_max, dst_len = 0;
u32 sample_num[3];
/* There could be 1-3 1024 bytes URB frames */
@@ -558,17 +557,12 @@ static int msi3101_convert_stream_504(struct msi3101_state *s, u32 *dst,
*/
dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
+ /* 504 x I+Q samples */
src += 16;
- for (j = 0; j < 1008; j += 2) {
- sample[0] = src[j + 0];
- sample[1] = src[j + 1];
-
- *dst++ = msi3101_convert_sample_504(s, sample[0]);
- *dst++ = msi3101_convert_sample_504(s, sample[1]);
- }
- /* 504 x I+Q 32bit float samples */
- dst_len += 504 * 2 * 4;
+ memcpy(dst, src, 1008);
src += 1008;
+ dst += 1008;
+ dst_len += 1008;
}
/* calculate samping rate and output it in 10 seconds intervals */
@@ -1116,7 +1110,6 @@ static int msi3101_querycap(struct file *file, void *fh,
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;
- cap->device_caps = V4L2_CAP_TUNER;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -1240,6 +1233,11 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
reg7 = 0x000c9407;
}
+ if (s->pixelformat == V4L2_PIX_FMT_SDR_S8) {
+ s->convert_stream = msi3101_convert_stream_504;
+ reg7 = 0x000c9407;
+ }
+
/*
* Synthesizer config is just a educated guess...
*
@@ -1634,6 +1632,84 @@ static int msi3101_s_input(struct file *file, void *fh, unsigned int i)
return i ? -EINVAL : 0;
}
+static int msi3101_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct msi3101_state *s = video_drvdata(file);
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ if (f->index >= NUM_FORMATS)
+ return -EINVAL;
+
+ strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+ f->pixelformat = formats[f->index].pixelformat;
+
+ return 0;
+}
+
+static int msi3101_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct msi3101_state *s = video_drvdata(file);
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ f->fmt.pix.pixelformat = s->pixelformat;
+
+ return 0;
+}
+
+static int msi3101_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct msi3101_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);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ if (vb2_is_busy(q))
+ return -EBUSY;
+
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (formats[i].pixelformat == f->fmt.pix.pixelformat) {
+ s->pixelformat = f->fmt.pix.pixelformat;
+ return 0;
+ }
+ }
+
+ f->fmt.pix.pixelformat = formats[0].pixelformat;
+ s->pixelformat = formats[0].pixelformat;
+
+ return 0;
+}
+
+static int msi3101_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct msi3101_state *s = video_drvdata(file);
+ int i;
+ dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
+ (char *)&f->fmt.pix.pixelformat);
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (formats[i].pixelformat == f->fmt.pix.pixelformat)
+ return 0;
+ }
+
+ f->fmt.pix.pixelformat = formats[0].pixelformat;
+
+ return 0;
+}
+
static int vidioc_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *v)
{
@@ -1668,6 +1744,11 @@ static int vidioc_s_frequency(struct file *file, void *priv,
static const struct v4l2_ioctl_ops msi3101_ioctl_ops = {
.vidioc_querycap = msi3101_querycap,
+ .vidioc_enum_fmt_vid_cap = msi3101_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = msi3101_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = msi3101_s_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = msi3101_try_fmt_vid_cap,
+
.vidioc_enum_input = msi3101_enum_input,
.vidioc_g_input = msi3101_g_input,
.vidioc_s_input = msi3101_s_input,
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 16/52] msi3101: move format 384 conversion to libv4lconvert
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (14 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 15/52] msi3101: implement FMT IOCTLs Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 17/52] msi3101: move format 336 " Antti Palosaari
` (35 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Move format 384 conversion to libv4lconvert as a fourcc "M384".
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 163 ++++++++++------------------
1 file changed, 57 insertions(+), 106 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index ba68ea9..37fea45 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -386,6 +386,7 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
#define MSI3101_CID_TUNER_GAIN ((V4L2_CID_USER_BASE | 0xf000) + 13)
#define V4L2_PIX_FMT_SDR_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
+#define V4L2_PIX_FMT_SDR_MSI2500_384 v4l2_fourcc('M', '3', '8', '4') /* Mirics MSi2500 format 384 */
/* stream formats */
struct msi3101_format {
@@ -399,6 +400,10 @@ static struct msi3101_format formats[] = {
.name = "I/Q 8-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S8,
},
+ {
+ .name = "I/Q 10+2-bit signed",
+ .pixelformat = V4L2_PIX_FMT_SDR_MSI2500_384,
+ },
};
static const int NUM_FORMATS = sizeof(formats) / sizeof(struct msi3101_format);
@@ -465,50 +470,6 @@ leave:
spin_unlock_irqrestore(&s->queued_bufs_lock, flags);
return buf;
}
-/*
- * +===========================================================================
- * | 00-1023 | USB packet type '384'
- * +===========================================================================
- * | 00- 03 | sequence number of first sample in that USB packet
- * +---------------------------------------------------------------------------
- * | 04- 15 | garbage
- * +---------------------------------------------------------------------------
- * | 16- 175 | samples
- * +---------------------------------------------------------------------------
- * | 176- 179 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 180- 339 | samples
- * +---------------------------------------------------------------------------
- * | 340- 343 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 344- 503 | samples
- * +---------------------------------------------------------------------------
- * | 504- 507 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 508- 667 | samples
- * +---------------------------------------------------------------------------
- * | 668- 671 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 672- 831 | samples
- * +---------------------------------------------------------------------------
- * | 832- 835 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 836- 995 | samples
- * +---------------------------------------------------------------------------
- * | 996- 999 | control bits for previous samples
- * +---------------------------------------------------------------------------
- * | 1000-1023 | garbage
- * +---------------------------------------------------------------------------
- *
- * Bytes 4 - 7 could have some meaning?
- *
- * Control bits for previous samples is 32-bit field, containing 16 x 2-bit
- * numbers. This results one 2-bit number for 8 samples. It is likely used for
- * for bit shifting sample by given bits, increasing actual sampling resolution.
- * Number 2 (0b10) was never seen.
- *
- * 6 * 16 * 2 * 4 = 768 samples. 768 * 4 = 3072 bytes
- */
/*
* Integer to 32-bit IEEE floating point representation routine is taken
@@ -585,48 +546,53 @@ static int msi3101_convert_stream_504(struct msi3101_state *s, u8 *dst,
}
/*
- * Converts signed ~10+2-bit integer into 32-bit IEEE floating point
- * representation.
+ * +===========================================================================
+ * | 00-1023 | USB packet type '384'
+ * +===========================================================================
+ * | 00- 03 | sequence number of first sample in that USB packet
+ * +---------------------------------------------------------------------------
+ * | 04- 15 | garbage
+ * +---------------------------------------------------------------------------
+ * | 16- 175 | samples
+ * +---------------------------------------------------------------------------
+ * | 176- 179 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * | 180- 339 | samples
+ * +---------------------------------------------------------------------------
+ * | 340- 343 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * | 344- 503 | samples
+ * +---------------------------------------------------------------------------
+ * | 504- 507 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * | 508- 667 | samples
+ * +---------------------------------------------------------------------------
+ * | 668- 671 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * | 672- 831 | samples
+ * +---------------------------------------------------------------------------
+ * | 832- 835 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * | 836- 995 | samples
+ * +---------------------------------------------------------------------------
+ * | 996- 999 | control bits for previous samples
+ * +---------------------------------------------------------------------------
+ * | 1000-1023 | garbage
+ * +---------------------------------------------------------------------------
+ *
+ * Bytes 4 - 7 could have some meaning?
+ *
+ * Control bits for previous samples is 32-bit field, containing 16 x 2-bit
+ * numbers. This results one 2-bit number for 8 samples. It is likely used for
+ * for bit shifting sample by given bits, increasing actual sampling resolution.
+ * Number 2 (0b10) was never seen.
+ *
+ * 6 * 16 * 2 * 4 = 768 samples. 768 * 4 = 3072 bytes
*/
-static u32 msi3101_convert_sample_384(struct msi3101_state *s, u16 x, int shift)
-{
- u32 msb, exponent, fraction, sign;
- s->sample_ctrl_bit[shift]++;
-
- /* Zero is special */
- if (!x)
- return 0;
-
- if (shift == 3)
- shift = 2;
-
- /* Convert 10-bit two's complement to 12-bit */
- if (x & (1 << 9)) {
- x |= ~0U << 10; /* set all the rest bits to one */
- x <<= shift;
- x = -x;
- x &= 0x7ff; /* result is 11 bit ... + sign */
- sign = 1 << 31;
- } else {
- x <<= shift;
- sign = 0 << 31;
- }
-
- /* Get location of the most significant bit */
- msb = __fls(x);
-
- fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
- exponent = (127 + msb) << I2F_FRAC_BITS;
-
- return (fraction + exponent) | sign;
-}
-
-static int msi3101_convert_stream_384(struct msi3101_state *s, u32 *dst,
+static int msi3101_convert_stream_384(struct msi3101_state *s, u8 *dst,
u8 *src, unsigned int src_len)
{
- int i, j, k, l, i_max, dst_len = 0;
- u16 sample[4];
- u32 bits;
+ int i, i_max, dst_len = 0;
u32 sample_num[3];
/* There could be 1-3 1024 bytes URB frames */
@@ -647,30 +613,12 @@ static int msi3101_convert_stream_384(struct msi3101_state *s, u32 *dst,
dev_dbg_ratelimited(&s->udev->dev,
"%*ph %*ph\n", 12, &src[4], 24, &src[1000]);
+ /* 384 x I+Q samples */
src += 16;
- for (j = 0; j < 6; j++) {
- bits = src[160 + 3] << 24 | src[160 + 2] << 16 | src[160 + 1] << 8 | src[160 + 0] << 0;
- for (k = 0; k < 16; k++) {
- for (l = 0; l < 10; l += 5) {
- sample[0] = (src[l + 0] & 0xff) >> 0 | (src[l + 1] & 0x03) << 8;
- sample[1] = (src[l + 1] & 0xfc) >> 2 | (src[l + 2] & 0x0f) << 6;
- sample[2] = (src[l + 2] & 0xf0) >> 4 | (src[l + 3] & 0x3f) << 4;
- sample[3] = (src[l + 3] & 0xc0) >> 6 | (src[l + 4] & 0xff) << 2;
-
- *dst++ = msi3101_convert_sample_384(s, sample[0], (bits >> (2 * k)) & 0x3);
- *dst++ = msi3101_convert_sample_384(s, sample[1], (bits >> (2 * k)) & 0x3);
- *dst++ = msi3101_convert_sample_384(s, sample[2], (bits >> (2 * k)) & 0x3);
- *dst++ = msi3101_convert_sample_384(s, sample[3], (bits >> (2 * k)) & 0x3);
- }
- src += 10;
- }
- dev_dbg_ratelimited(&s->udev->dev,
- "sample control bits %08x\n", bits);
- src += 4;
- }
- /* 384 x I+Q 32bit float samples */
- dst_len += 384 * 2 * 4;
- src += 24;
+ memcpy(dst, src, 984);
+ src += 984 + 24;
+ dst += 984;
+ dst_len += 984;
}
/* calculate samping rate and output it in 10 seconds intervals */
@@ -1236,6 +1184,9 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
if (s->pixelformat == V4L2_PIX_FMT_SDR_S8) {
s->convert_stream = msi3101_convert_stream_504;
reg7 = 0x000c9407;
+ } else if (s->pixelformat == V4L2_PIX_FMT_SDR_MSI2500_384) {
+ s->convert_stream = msi3101_convert_stream_384;
+ reg7 = 0x0000a507;
}
/*
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 17/52] msi3101: move format 336 conversion to libv4lconvert
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (15 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 16/52] msi3101: move format 384 conversion to libv4lconvert Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 18/52] msi3101: move format 252 " Antti Palosaari
` (34 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Move format 384 conversion to libv4lconvert as a fourcc "DS12".
It is 12-bit sample pairs packed to 3 bytes.
msi3101: move format 336 conversion 336 to libv4l
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 66 +++++++++++------------------
1 file changed, 24 insertions(+), 42 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 37fea45..7c1dc43 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -386,6 +386,7 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
#define MSI3101_CID_TUNER_GAIN ((V4L2_CID_USER_BASE | 0xf000) + 13)
#define V4L2_PIX_FMT_SDR_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
+#define V4L2_PIX_FMT_SDR_S12 v4l2_fourcc('D', 'S', '1', '2') /* signed 12-bit */
#define V4L2_PIX_FMT_SDR_MSI2500_384 v4l2_fourcc('M', '3', '8', '4') /* Mirics MSi2500 format 384 */
/* stream formats */
@@ -399,10 +400,12 @@ static struct msi3101_format formats[] = {
{
.name = "I/Q 8-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S8,
- },
- {
+ }, {
.name = "I/Q 10+2-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_MSI2500_384,
+ }, {
+ .name = "I/Q 12-bit signed",
+ .pixelformat = V4L2_PIX_FMT_SDR_S12,
},
};
@@ -643,40 +646,21 @@ static int msi3101_convert_stream_384(struct msi3101_state *s, u8 *dst,
}
/*
- * Converts signed 12-bit integer into 32-bit IEEE floating point
- * representation.
+ * +===========================================================================
+ * | 00-1023 | USB packet type '336'
+ * +===========================================================================
+ * | 00- 03 | sequence number of first sample in that USB packet
+ * +---------------------------------------------------------------------------
+ * | 04- 15 | garbage
+ * +---------------------------------------------------------------------------
+ * | 16-1023 | samples
+ * +---------------------------------------------------------------------------
+ * signed 12-bit sample
*/
-static u32 msi3101_convert_sample_336(struct msi3101_state *s, u16 x)
-{
- u32 msb, exponent, fraction, sign;
-
- /* Zero is special */
- if (!x)
- return 0;
-
- /* Negative / positive value */
- if (x & (1 << 11)) {
- x = -x;
- x &= 0x7ff; /* result is 11 bit ... + sign */
- sign = 1 << 31;
- } else {
- sign = 0 << 31;
- }
-
- /* Get location of the most significant bit */
- msb = __fls(x);
-
- fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
- exponent = (127 + msb) << I2F_FRAC_BITS;
-
- return (fraction + exponent) | sign;
-}
-
-static int msi3101_convert_stream_336(struct msi3101_state *s, u32 *dst,
+static int msi3101_convert_stream_336(struct msi3101_state *s, u8 *dst,
u8 *src, unsigned int src_len)
{
- int i, j, i_max, dst_len = 0;
- u16 sample[2];
+ int i, i_max, dst_len = 0;
u32 sample_num[3];
/* There could be 1-3 1024 bytes URB frames */
@@ -697,17 +681,12 @@ static int msi3101_convert_stream_336(struct msi3101_state *s, u32 *dst,
*/
dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
+ /* 336 x I+Q samples */
src += 16;
- for (j = 0; j < 1008; j += 3) {
- sample[0] = (src[j + 0] & 0xff) >> 0 | (src[j + 1] & 0x0f) << 8;
- sample[1] = (src[j + 1] & 0xf0) >> 4 | (src[j + 2] & 0xff) << 4;
-
- *dst++ = msi3101_convert_sample_336(s, sample[0]);
- *dst++ = msi3101_convert_sample_336(s, sample[1]);
- }
- /* 336 x I+Q 32bit float samples */
- dst_len += 336 * 2 * 4;
+ memcpy(dst, src, 1008);
src += 1008;
+ dst += 1008;
+ dst_len += 1008;
}
/* calculate samping rate and output it in 10 seconds intervals */
@@ -1187,6 +1166,9 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
} else if (s->pixelformat == V4L2_PIX_FMT_SDR_MSI2500_384) {
s->convert_stream = msi3101_convert_stream_384;
reg7 = 0x0000a507;
+ } else if (s->pixelformat == V4L2_PIX_FMT_SDR_S12) {
+ s->convert_stream = msi3101_convert_stream_336;
+ reg7 = 0x00008507;
}
/*
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 18/52] msi3101: move format 252 conversion to libv4lconvert
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (16 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 17/52] msi3101: move format 336 " Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 19/52] rtl28xxu: add module parameter to disable IR Antti Palosaari
` (33 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Move format 252 conversion to libv4lconvert as a fourcc "DS14".
It is 14-bit sample pairs packed to 4 bytes.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 65 +++++++++++------------------
1 file changed, 24 insertions(+), 41 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 7c1dc43..16ce417 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -387,6 +387,7 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
#define V4L2_PIX_FMT_SDR_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
#define V4L2_PIX_FMT_SDR_S12 v4l2_fourcc('D', 'S', '1', '2') /* signed 12-bit */
+#define V4L2_PIX_FMT_SDR_S14 v4l2_fourcc('D', 'S', '1', '4') /* signed 14-bit */
#define V4L2_PIX_FMT_SDR_MSI2500_384 v4l2_fourcc('M', '3', '8', '4') /* Mirics MSi2500 format 384 */
/* stream formats */
@@ -406,6 +407,9 @@ static struct msi3101_format formats[] = {
}, {
.name = "I/Q 12-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S12,
+ }, {
+ .name = "I/Q 14-bit signed",
+ .pixelformat = V4L2_PIX_FMT_SDR_S14,
},
};
@@ -439,7 +443,7 @@ struct msi3101_state {
unsigned int vb_full; /* vb is full and packets dropped */
struct urb *urbs[MAX_ISO_BUFS];
- int (*convert_stream) (struct msi3101_state *s, u32 *dst, u8 *src,
+ int (*convert_stream) (struct msi3101_state *s, u8 *dst, u8 *src,
unsigned int src_len);
/* Controls */
@@ -709,40 +713,21 @@ static int msi3101_convert_stream_336(struct msi3101_state *s, u8 *dst,
}
/*
- * Converts signed 14-bit integer into 32-bit IEEE floating point
- * representation.
+ * +===========================================================================
+ * | 00-1023 | USB packet type '252'
+ * +===========================================================================
+ * | 00- 03 | sequence number of first sample in that USB packet
+ * +---------------------------------------------------------------------------
+ * | 04- 15 | garbage
+ * +---------------------------------------------------------------------------
+ * | 16-1023 | samples
+ * +---------------------------------------------------------------------------
+ * signed 14-bit sample
*/
-static u32 msi3101_convert_sample_252(struct msi3101_state *s, u16 x)
-{
- u32 msb, exponent, fraction, sign;
-
- /* Zero is special */
- if (!x)
- return 0;
-
- /* Negative / positive value */
- if (x & (1 << 13)) {
- x = -x;
- x &= 0x1fff; /* result is 13 bit ... + sign */
- sign = 1 << 31;
- } else {
- sign = 0 << 31;
- }
-
- /* Get location of the most significant bit */
- msb = __fls(x);
-
- fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
- exponent = (127 + msb) << I2F_FRAC_BITS;
-
- return (fraction + exponent) | sign;
-}
-
-static int msi3101_convert_stream_252(struct msi3101_state *s, u32 *dst,
+static int msi3101_convert_stream_252(struct msi3101_state *s, u8 *dst,
u8 *src, unsigned int src_len)
{
- int i, j, i_max, dst_len = 0;
- u16 sample[2];
+ int i, i_max, dst_len = 0;
u32 sample_num[3];
/* There could be 1-3 1024 bytes URB frames */
@@ -763,17 +748,12 @@ static int msi3101_convert_stream_252(struct msi3101_state *s, u32 *dst,
*/
dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
+ /* 252 x I+Q samples */
src += 16;
- for (j = 0; j < 1008; j += 4) {
- sample[0] = src[j + 0] >> 0 | src[j + 1] << 8;
- sample[1] = src[j + 2] >> 0 | src[j + 3] << 8;
-
- *dst++ = msi3101_convert_sample_252(s, sample[0]);
- *dst++ = msi3101_convert_sample_252(s, sample[1]);
- }
- /* 252 x I+Q 32bit float samples */
- dst_len += 252 * 2 * 4;
+ memcpy(dst, src, 1008);
src += 1008;
+ dst += 1008;
+ dst_len += 1008;
}
/* calculate samping rate and output it in 10 seconds intervals */
@@ -1169,6 +1149,9 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
} else if (s->pixelformat == V4L2_PIX_FMT_SDR_S12) {
s->convert_stream = msi3101_convert_stream_336;
reg7 = 0x00008507;
+ } else if (s->pixelformat == V4L2_PIX_FMT_SDR_S14) {
+ s->convert_stream = msi3101_convert_stream_252;
+ reg7 = 0x00009407;
}
/*
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 19/52] rtl28xxu: add module parameter to disable IR
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (17 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 18/52] msi3101: move format 252 " Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 20/52] rtl2832_sdr: increase USB buffers Antti Palosaari
` (32 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Disable IR interrupts in order to avoid SDR sample loss.
IR interrupts causes some extra load for device and it seems
be one reason to loss samples when sampling rate is high.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 6a5eb0f..77f1fc9 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -36,6 +36,9 @@
#include "tua9001.h"
#include "r820t.h"
+static int rtl28xxu_disable_rc;
+module_param_named(disable_rc, rtl28xxu_disable_rc, int, 0644);
+MODULE_PARM_DESC(disable_rc, "disable RTL2832U remote controller");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
@@ -1325,6 +1328,10 @@ err:
static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
struct dvb_usb_rc *rc)
{
+ /* disable IR interrupts in order to avoid SDR sample loss */
+ if (rtl28xxu_disable_rc)
+ return rtl28xx_wr_reg(d, IR_RX_IE, 0x00);
+
/* load empty to enable rc */
if (!rc->map_name)
rc->map_name = RC_MAP_EMPTY;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 20/52] rtl2832_sdr: increase USB buffers
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (18 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 19/52] rtl28xxu: add module parameter to disable IR Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 21/52] DocBook: fix wait.c location Antti Palosaari
` (31 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Increase USB xfer buffers heavily in order handle wider data stream.
Stream is quite heavy, over 50Mbit/sec, when sampling rates are
increased up to 3.2Msps. With remote controller interrupts disabled
and huge USB buffers it seems to perform even 3.2Msps rather well.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 348df05..4b8c016 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -51,8 +51,8 @@
#define V4L2_PIX_FMT_SDR_U8 v4l2_fourcc('D', 'U', '0', '8') /* unsigned 8-bit */
-#define MAX_BULK_BUFS (8)
-#define BULK_BUFFER_SIZE (8 * 512)
+#define MAX_BULK_BUFS (10)
+#define BULK_BUFFER_SIZE (128 * 512)
/* intermediate buffers with raw data from the USB device */
struct rtl2832_sdr_frame_buf {
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 21/52] DocBook: fix wait.c location
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (19 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 20/52] rtl2832_sdr: increase USB buffers Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 22/52] v4l: add device type for Software Defined Radio Antti Palosaari
` (30 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Documentation did not compile as wait.c location was wrong.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
Documentation/DocBook/device-drivers.tmpl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index 6c9d9d3..f517008 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -58,7 +58,7 @@
</sect1>
<sect1><title>Wait queues and Wake events</title>
!Iinclude/linux/wait.h
-!Ekernel/wait.c
+!Ekernel/sched/wait.c
</sect1>
<sect1><title>High-resolution timers</title>
!Iinclude/linux/ktime.h
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 22/52] v4l: add device type for Software Defined Radio
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (20 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 21/52] DocBook: fix wait.c location Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 23/52] v4l: add new tuner types for SDR Antti Palosaari
` (29 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Add new V4L device type VFL_TYPE_SDR for Software Defined Radio.
It is registered as /dev/swradio0 (/dev/sdr0 was already reserved).
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/media/v4l2-core/v4l2-dev.c | 6 ++++++
include/media/v4l2-dev.h | 3 ++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index b5aaaac..2ccacf2 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -758,6 +758,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
* %VFL_TYPE_RADIO - A radio card
*
* %VFL_TYPE_SUBDEV - A subdevice
+ *
+ * %VFL_TYPE_SDR - Software Defined Radio
*/
int __video_register_device(struct video_device *vdev, int type, int nr,
int warn_if_nr_in_use, struct module *owner)
@@ -797,6 +799,10 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
case VFL_TYPE_SUBDEV:
name_base = "v4l-subdev";
break;
+ case VFL_TYPE_SDR:
+ /* Use device name 'swradio' because 'sdr' was already taken. */
+ name_base = "swradio";
+ break;
default:
printk(KERN_ERR "%s called with unknown type: %d\n",
__func__, type);
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index c768c9f..eec6e46 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -24,7 +24,8 @@
#define VFL_TYPE_VBI 1
#define VFL_TYPE_RADIO 2
#define VFL_TYPE_SUBDEV 3
-#define VFL_TYPE_MAX 4
+#define VFL_TYPE_SDR 4
+#define VFL_TYPE_MAX 5
/* Is this a receiver, transmitter or mem-to-mem? */
/* Ignored for VFL_TYPE_SUBDEV. */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 23/52] v4l: add new tuner types for SDR
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (21 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 22/52] v4l: add device type for Software Defined Radio Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-02-07 14:03 ` Mauro Carvalho Chehab
2014-01-25 17:10 ` [PATCH 24/52] v4l: 1 Hz resolution flag for tuners Antti Palosaari
` (28 subsequent siblings)
51 siblings, 1 reply; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Define tuner types V4L2_TUNER_ADC and V4L2_TUNER_RF for SDR usage.
ADC is used for setting sampling rate (sampling frequency) to SDR
device.
Another tuner type, named as V4L2_TUNER_RF, is possible RF tuner.
Is is used to down-convert RF frequency to range ADC could sample.
Having RF tuner is optional, whilst in practice it is almost always
there.
Also add checks to VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY and
VIDIOC_ENUM_FREQ_BANDS only allow these two tuner types when device
type is SDR (VFL_TYPE_SDR). For VIDIOC_G_FREQUENCY we do not check
tuner type, instead override type with V4L2_TUNER_ADC in every
case (requested by Hans in order to keep functionality in line with
existing tuners and existing API does not specify it).
Prohibit VIDIOC_S_HW_FREQ_SEEK explicitly when device type is SDR,
as device cannot do hardware seek without a hardware demodulator.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/media/v4l2-core/v4l2-ioctl.c | 39 ++++++++++++++++++++++++++----------
include/uapi/linux/videodev2.h | 2 ++
2 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 707aef7..15ab349 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1291,8 +1291,11 @@ static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
struct video_device *vfd = video_devdata(file);
struct v4l2_frequency *p = arg;
- p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ if (vfd->vfl_type == VFL_TYPE_SDR)
+ p->type = V4L2_TUNER_ADC;
+ else
+ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
return ops->vidioc_g_frequency(file, fh, p);
}
@@ -1303,10 +1306,15 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
const struct v4l2_frequency *p = arg;
enum v4l2_tuner_type type;
- type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
- V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- if (p->type != type)
- return -EINVAL;
+ if (vfd->vfl_type == VFL_TYPE_SDR) {
+ if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
+ return -EINVAL;
+ } else {
+ type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ if (type != p->type)
+ return -EINVAL;
+ }
return ops->vidioc_s_frequency(file, fh, p);
}
@@ -1386,6 +1394,10 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
struct v4l2_hw_freq_seek *p = arg;
enum v4l2_tuner_type type;
+ /* s_hw_freq_seek is not supported for SDR for now */
+ if (vfd->vfl_type == VFL_TYPE_SDR)
+ return -EINVAL;
+
type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
if (p->type != type)
@@ -1885,11 +1897,16 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
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 (vfd->vfl_type == VFL_TYPE_SDR) {
+ if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
+ return -EINVAL;
+ type = p->type;
+ } else {
+ 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 (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 6ae7bbe..9dc79d1 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -159,6 +159,8 @@ enum v4l2_tuner_type {
V4L2_TUNER_RADIO = 1,
V4L2_TUNER_ANALOG_TV = 2,
V4L2_TUNER_DIGITAL_TV = 3,
+ V4L2_TUNER_ADC = 4,
+ V4L2_TUNER_RF = 5,
};
enum v4l2_memory {
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 24/52] v4l: 1 Hz resolution flag for tuners
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (22 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 23/52] v4l: add new tuner types for SDR Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 25/52] v4l: add stream format for SDR receiver Antti Palosaari
` (27 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Add V4L2_TUNER_CAP_1HZ for 1 Hz resolution.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
include/uapi/linux/videodev2.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 9dc79d1..1cf2076 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1341,6 +1341,7 @@ struct v4l2_modulator {
#define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200
#define V4L2_TUNER_CAP_FREQ_BANDS 0x0400
#define V4L2_TUNER_CAP_HWSEEK_PROG_LIM 0x0800
+#define V4L2_TUNER_CAP_1HZ 0x1000
/* Flags for the 'rxsubchans' field */
#define V4L2_TUNER_SUB_MONO 0x0001
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 25/52] v4l: add stream format for SDR receiver
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (23 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 24/52] v4l: 1 Hz resolution flag for tuners Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 26/52] v4l: define own IOCTL ops for SDR FMT Antti Palosaari
` (26 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Add new V4L2 stream format definition, V4L2_BUF_TYPE_SDR_CAPTURE,
for SDR receiver.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/media/v4l2-core/v4l2-ioctl.c | 1 +
include/trace/events/v4l2.h | 1 +
include/uapi/linux/videodev2.h | 11 +++++++++++
3 files changed, 13 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 15ab349..9a2acaf 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -152,6 +152,7 @@ const char *v4l2_type_names[] = {
[V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
[V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
[V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
+ [V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap",
};
EXPORT_SYMBOL(v4l2_type_names);
diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h
index ef94eca..b9bb1f2 100644
--- a/include/trace/events/v4l2.h
+++ b/include/trace/events/v4l2.h
@@ -18,6 +18,7 @@
{ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY, "VIDEO_OUTPUT_OVERLAY" },\
{ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, "VIDEO_CAPTURE_MPLANE" },\
{ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, "VIDEO_OUTPUT_MPLANE" }, \
+ { V4L2_BUF_TYPE_SDR_CAPTURE, "SDR_CAPTURE" }, \
{ V4L2_BUF_TYPE_PRIVATE, "PRIVATE" })
#define show_field(field) \
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 1cf2076..27bed7c 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -139,6 +139,7 @@ enum v4l2_buf_type {
#endif
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
+ V4L2_BUF_TYPE_SDR_CAPTURE = 11,
/* Deprecated, do not use */
V4L2_BUF_TYPE_PRIVATE = 0x80,
};
@@ -1695,6 +1696,15 @@ struct v4l2_pix_format_mplane {
} __attribute__ ((packed));
/**
+ * struct v4l2_format_sdr - SDR format definition
+ * @pixelformat: little endian four character code (fourcc)
+ */
+struct v4l2_format_sdr {
+ __u32 pixelformat;
+ __u8 reserved[28];
+} __attribute__ ((packed));
+
+/**
* struct v4l2_format - stream data format
* @type: enum v4l2_buf_type; type of the data stream
* @pix: definition of an image format
@@ -1712,6 +1722,7 @@ struct v4l2_format {
struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
+ struct v4l2_format_sdr sdr; /* V4L2_BUF_TYPE_SDR_CAPTURE */
__u8 raw_data[200]; /* user-defined */
} fmt;
};
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 26/52] v4l: define own IOCTL ops for SDR FMT
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (24 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 25/52] v4l: add stream format for SDR receiver Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 27/52] v4l: enable some IOCTLs for SDR receiver Antti Palosaari
` (25 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Use own format ops for SDR data:
vidioc_enum_fmt_sdr_cap
vidioc_g_fmt_sdr_cap
vidioc_s_fmt_sdr_cap
vidioc_try_fmt_sdr_cap
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
include/media/v4l2-ioctl.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index e0b74a4..8be32f5 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -40,6 +40,8 @@ struct v4l2_ioctl_ops {
struct v4l2_fmtdesc *f);
int (*vidioc_enum_fmt_vid_out_mplane)(struct file *file, void *fh,
struct v4l2_fmtdesc *f);
+ int (*vidioc_enum_fmt_sdr_cap) (struct file *file, void *fh,
+ struct v4l2_fmtdesc *f);
/* VIDIOC_G_FMT handlers */
int (*vidioc_g_fmt_vid_cap) (struct file *file, void *fh,
@@ -62,6 +64,8 @@ struct v4l2_ioctl_ops {
struct v4l2_format *f);
int (*vidioc_g_fmt_vid_out_mplane)(struct file *file, void *fh,
struct v4l2_format *f);
+ int (*vidioc_g_fmt_sdr_cap) (struct file *file, void *fh,
+ struct v4l2_format *f);
/* VIDIOC_S_FMT handlers */
int (*vidioc_s_fmt_vid_cap) (struct file *file, void *fh,
@@ -84,6 +88,8 @@ struct v4l2_ioctl_ops {
struct v4l2_format *f);
int (*vidioc_s_fmt_vid_out_mplane)(struct file *file, void *fh,
struct v4l2_format *f);
+ int (*vidioc_s_fmt_sdr_cap) (struct file *file, void *fh,
+ struct v4l2_format *f);
/* VIDIOC_TRY_FMT handlers */
int (*vidioc_try_fmt_vid_cap) (struct file *file, void *fh,
@@ -106,6 +112,8 @@ struct v4l2_ioctl_ops {
struct v4l2_format *f);
int (*vidioc_try_fmt_vid_out_mplane)(struct file *file, void *fh,
struct v4l2_format *f);
+ int (*vidioc_try_fmt_sdr_cap) (struct file *file, void *fh,
+ struct v4l2_format *f);
/* Buffer handlers */
int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 27/52] v4l: enable some IOCTLs for SDR receiver
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (25 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 26/52] v4l: define own IOCTL ops for SDR FMT Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 28/52] v4l: add device capability flag " Antti Palosaari
` (24 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Enable stream format (FMT) IOCTLs for SDR use. These are used for negotiate
used data stream format.
Reorganise some some IOCTL selection logic.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
---
drivers/media/v4l2-core/v4l2-dev.c | 21 ++++++++++++++++++---
drivers/media/v4l2-core/v4l2-ioctl.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 2ccacf2..6308a19 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -553,7 +553,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER;
bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
- bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
+ bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
@@ -662,9 +662,20 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_try_fmt_sliced_vbi_out)))
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap);
+ } else if (is_sdr) {
+ /* SDR specific ioctls */
+ if (ops->vidioc_enum_fmt_sdr_cap)
+ set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
+ if (ops->vidioc_g_fmt_sdr_cap)
+ set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
+ if (ops->vidioc_s_fmt_sdr_cap)
+ set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
+ if (ops->vidioc_try_fmt_sdr_cap)
+ set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
}
- if (!is_radio) {
- /* ioctls valid for video or vbi */
+
+ if (is_vid || is_vbi || is_sdr) {
+ /* ioctls valid for video, vbi or sdr */
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
@@ -672,6 +683,10 @@ static void determine_valid_ioctls(struct video_device *vdev)
SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
SET_VALID_IOCTL(ops, VIDIOC_CREATE_BUFS, vidioc_create_bufs);
SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
+ }
+
+ if (is_vid || is_vbi) {
+ /* ioctls valid for video or vbi */
if (ops->vidioc_s_std)
set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 9a2acaf..95dd4f1 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -246,6 +246,7 @@ static void v4l_print_format(const void *arg, bool write_only)
const struct v4l2_vbi_format *vbi;
const struct v4l2_sliced_vbi_format *sliced;
const struct v4l2_window *win;
+ const struct v4l2_format_sdr *sdr;
unsigned i;
pr_cont("type=%s", prt_names(p->type, v4l2_type_names));
@@ -319,6 +320,14 @@ static void v4l_print_format(const void *arg, bool write_only)
sliced->service_lines[0][i],
sliced->service_lines[1][i]);
break;
+ case V4L2_BUF_TYPE_SDR_CAPTURE:
+ sdr = &p->fmt.sdr;
+ pr_cont(", pixelformat=%c%c%c%c\n",
+ (sdr->pixelformat >> 0) & 0xff,
+ (sdr->pixelformat >> 8) & 0xff,
+ (sdr->pixelformat >> 16) & 0xff,
+ (sdr->pixelformat >> 24) & 0xff);
+ break;
}
}
@@ -882,6 +891,7 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
+ bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
@@ -931,6 +941,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out)
return 0;
break;
+ case V4L2_BUF_TYPE_SDR_CAPTURE:
+ if (is_sdr && is_rx && ops->vidioc_g_fmt_sdr_cap)
+ return 0;
+ break;
default:
break;
}
@@ -1050,6 +1064,10 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out_mplane))
break;
return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_CAPTURE:
+ if (unlikely(!is_rx || !ops->vidioc_enum_fmt_sdr_cap))
+ break;
+ return ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
}
return -EINVAL;
}
@@ -1060,6 +1078,7 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
struct v4l2_format *p = arg;
struct video_device *vfd = video_devdata(file);
bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+ bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
@@ -1104,6 +1123,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out))
break;
return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_CAPTURE:
+ if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
+ break;
+ return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
}
return -EINVAL;
}
@@ -1114,6 +1137,7 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
struct v4l2_format *p = arg;
struct video_device *vfd = video_devdata(file);
bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+ bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
@@ -1168,6 +1192,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.sliced);
return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_CAPTURE:
+ if (unlikely(!is_rx || !is_sdr || !ops->vidioc_s_fmt_sdr_cap))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.sdr);
+ return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
}
return -EINVAL;
}
@@ -1178,6 +1207,7 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
struct v4l2_format *p = arg;
struct video_device *vfd = video_devdata(file);
bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
+ bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
@@ -1232,6 +1262,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.sliced);
return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
+ case V4L2_BUF_TYPE_SDR_CAPTURE:
+ if (unlikely(!is_rx || !is_sdr || !ops->vidioc_try_fmt_sdr_cap))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.sdr);
+ return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
}
return -EINVAL;
}
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 28/52] v4l: add device capability flag for SDR receiver
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (26 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 27/52] v4l: enable some IOCTLs for SDR receiver Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 29/52] v4l: do not allow modulator ioctls for non-radio devices Antti Palosaari
` (23 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
VIDIOC_QUERYCAP IOCTL is used to query device capabilities. Add new
capability flag to inform given device supports SDR capture.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hverkuil@xs4all.nl>
---
include/uapi/linux/videodev2.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 27bed7c..27fedfe 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -267,6 +267,8 @@ struct v4l2_capability {
#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */
+#define V4L2_CAP_SDR_CAPTURE 0x00100000 /* Is a SDR capture device */
+
#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 29/52] v4l: do not allow modulator ioctls for non-radio devices
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (27 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 28/52] v4l: add device capability flag " Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 30/52] DocBook: document 1 Hz flag Antti Palosaari
` (22 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Hans Verkuil, Hans Verkuil, Antti Palosaari
From: Hans Verkuil <hverkuil@xs4all.nl>
Modulator ioctls could be enabled mistakenly for non-radio devices.
Currently those ioctls are only valid for radio. Fix it.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/v4l2-core/v4l2-dev.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 6308a19..9adde0f 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -553,6 +553,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER;
bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI;
+ bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO;
bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR;
bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
@@ -726,8 +727,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings);
SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap);
}
- if (is_tx) {
- /* transmitter only ioctls */
+ if (is_tx && (is_radio || is_sdr)) {
+ /* radio transmitter only ioctls */
SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator);
SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator);
}
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 30/52] DocBook: document 1 Hz flag
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (28 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 29/52] v4l: do not allow modulator ioctls for non-radio devices Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 31/52] DocBook: Software Defined Radio Interface Antti Palosaari
` (21 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Update documentation to reflect 1 Hz frequency step flag.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
.../DocBook/media/v4l/vidioc-enum-freq-bands.xml | 8 +++++---
Documentation/DocBook/media/v4l/vidioc-g-frequency.xml | 5 +++--
Documentation/DocBook/media/v4l/vidioc-g-modulator.xml | 6 ++++--
Documentation/DocBook/media/v4l/vidioc-g-tuner.xml | 15 ++++++++++++---
Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml | 8 ++++++--
5 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/vidioc-enum-freq-bands.xml b/Documentation/DocBook/media/v4l/vidioc-enum-freq-bands.xml
index 6541ba0..4e8ea65 100644
--- a/Documentation/DocBook/media/v4l/vidioc-enum-freq-bands.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-enum-freq-bands.xml
@@ -100,7 +100,7 @@ See <xref linkend="v4l2-tuner-type" /></entry>
<entry><structfield>capability</structfield></entry>
<entry spanname="hspan">The tuner/modulator capability flags for
this frequency band, see <xref linkend="tuner-capability" />. The <constant>V4L2_TUNER_CAP_LOW</constant>
-capability must be the same for all frequency bands of the selected tuner/modulator.
+or <constant>V4L2_TUNER_CAP_1HZ</constant> capability must be the same for all frequency bands of the selected tuner/modulator.
So either all bands have that capability set, or none of them have that capability.</entry>
</row>
<row>
@@ -109,7 +109,8 @@ So either all bands have that capability set, or none of them have that capabili
<entry spanname="hspan">The lowest tunable frequency in
units of 62.5 kHz, or if the <structfield>capability</structfield>
flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz, for this frequency band.</entry>
+Hz, for this frequency band. A 1 Hz unit is used when the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set.</entry>
</row>
<row>
<entry>__u32</entry>
@@ -117,7 +118,8 @@ Hz, for this frequency band.</entry>
<entry spanname="hspan">The highest tunable frequency in
units of 62.5 kHz, or if the <structfield>capability</structfield>
flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz, for this frequency band.</entry>
+Hz, for this frequency band. A 1 Hz unit is used when the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set.</entry>
</row>
<row>
<entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
index c7a1c46..d1034fb 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-frequency.xml
@@ -109,9 +109,10 @@ See <xref linkend="v4l2-tuner-type" /></entry>
<entry>__u32</entry>
<entry><structfield>frequency</structfield></entry>
<entry>Tuning frequency in units of 62.5 kHz, or if the
-&v4l2-tuner; or &v4l2-modulator; <structfield>capabilities</structfield> flag
+&v4l2-tuner; or &v4l2-modulator; <structfield>capability</structfield> flag
<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz.</entry>
+Hz. A 1 Hz unit is used when the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set.</entry>
</row>
<row>
<entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml b/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml
index 7f4ac7e..7068b59 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-modulator.xml
@@ -113,7 +113,8 @@ change for example with the current video standard.</entry>
<entry>The lowest tunable frequency in units of 62.5
KHz, or if the <structfield>capability</structfield> flag
<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz.</entry>
+Hz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.</entry>
</row>
<row>
<entry>__u32</entry>
@@ -121,7 +122,8 @@ Hz.</entry>
<entry>The highest tunable frequency in units of 62.5
KHz, or if the <structfield>capability</structfield> flag
<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz.</entry>
+Hz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.</entry>
</row>
<row>
<entry>__u32</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
index 6cc8201..b0d8659 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml
@@ -134,7 +134,9 @@ the structure refers to a radio tuner the
<entry spanname="hspan">The lowest tunable frequency in
units of 62.5 kHz, or if the <structfield>capability</structfield>
flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz. If multiple frequency bands are supported, then
+Hz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.
+If multiple frequency bands are supported, then
<structfield>rangelow</structfield> is the lowest frequency
of all the frequency bands.</entry>
</row>
@@ -144,7 +146,9 @@ of all the frequency bands.</entry>
<entry spanname="hspan">The highest tunable frequency in
units of 62.5 kHz, or if the <structfield>capability</structfield>
flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
-Hz. If multiple frequency bands are supported, then
+Hz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_1HZ</constant> is set, in units of 1 Hz.
+If multiple frequency bands are supported, then
<structfield>rangehigh</structfield> is the highest frequency
of all the frequency bands.</entry>
</row>
@@ -270,7 +274,7 @@ applications must set the array to zero.</entry>
<entry><constant>V4L2_TUNER_CAP_LOW</constant></entry>
<entry>0x0001</entry>
<entry>When set, tuning frequencies are expressed in units of
-62.5 Hz, otherwise in units of 62.5 kHz.</entry>
+62.5 Hz instead of 62.5 kHz.</entry>
</row>
<row>
<entry><constant>V4L2_TUNER_CAP_NORM</constant></entry>
@@ -360,6 +364,11 @@ radio tuners.</entry>
<entry>The range to search when using the hardware seek functionality
is programmable, see &VIDIOC-S-HW-FREQ-SEEK; for details.</entry>
</row>
+ <row>
+ <entry><constant>V4L2_TUNER_CAP_1HZ</constant></entry>
+ <entry>0x1000</entry>
+ <entry>When set, tuning frequencies are expressed in units of 1 Hz instead of 62.5 kHz.</entry>
+ </row>
</tbody>
</tgroup>
</table>
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 5b379e7..a5fc4c4 100644
--- a/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-s-hw-freq-seek.xml
@@ -121,7 +121,9 @@ field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
<entry>If non-zero, the lowest tunable frequency of the band to
search in units of 62.5 kHz, or if the &v4l2-tuner;
<structfield>capability</structfield> field has the
-<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz.
+<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz or if the &v4l2-tuner;
+<structfield>capability</structfield> field has the
+<constant>V4L2_TUNER_CAP_1HZ</constant> flag set, in units of 1 Hz.
If <structfield>rangelow</structfield> is zero a reasonable default value
is used.</entry>
</row>
@@ -131,7 +133,9 @@ is used.</entry>
<entry>If non-zero, the highest tunable frequency of the band to
search in units of 62.5 kHz, or if the &v4l2-tuner;
<structfield>capability</structfield> field has the
-<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz.
+<constant>V4L2_TUNER_CAP_LOW</constant> flag set, in units of 62.5 Hz or if the &v4l2-tuner;
+<structfield>capability</structfield> field has the
+<constant>V4L2_TUNER_CAP_1HZ</constant> flag set, in units of 1 Hz.
If <structfield>rangehigh</structfield> is zero a reasonable default value
is used.</entry>
</row>
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 31/52] DocBook: Software Defined Radio Interface
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (29 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 30/52] DocBook: document 1 Hz flag Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 32/52] DocBook: mark SDR API as Experimental Antti Palosaari
` (20 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Document V4L2 SDR interface.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
Documentation/DocBook/media/v4l/compat.xml | 10 ++
Documentation/DocBook/media/v4l/dev-sdr.xml | 104 +++++++++++++++++++++
Documentation/DocBook/media/v4l/io.xml | 6 ++
Documentation/DocBook/media/v4l/pixfmt.xml | 8 ++
Documentation/DocBook/media/v4l/v4l2.xml | 1 +
Documentation/DocBook/media/v4l/vidioc-g-fmt.xml | 7 ++
.../DocBook/media/v4l/vidioc-querycap.xml | 6 ++
7 files changed, 142 insertions(+)
create mode 100644 Documentation/DocBook/media/v4l/dev-sdr.xml
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index c4cac6d..0b4db0e 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2535,6 +2535,16 @@ fields changed from _s32 to _u32.
</orderedlist>
</section>
+ <section>
+ <title>V4L2 in Linux 3.15</title>
+ <orderedlist>
+ <listitem>
+ <para>Added Software Defined Radio (SDR) Interface.
+ </para>
+ </listitem>
+ </orderedlist>
+ </section>
+
<section id="other">
<title>Relation of V4L2 to other Linux multimedia APIs</title>
diff --git a/Documentation/DocBook/media/v4l/dev-sdr.xml b/Documentation/DocBook/media/v4l/dev-sdr.xml
new file mode 100644
index 0000000..332b87f
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/dev-sdr.xml
@@ -0,0 +1,104 @@
+ <title>Software Defined Radio Interface (SDR)</title>
+
+ <para>
+SDR is an abbreviation of Software Defined Radio, the radio device
+which uses application software for modulation or demodulation. This interface
+is intended for controlling and data streaming of such devices.
+ </para>
+
+ <para>
+SDR devices are accessed through character device special files named
+<filename>/dev/swradio0</filename> to <filename>/dev/swradio255</filename>
+with major number 81 and dynamically allocated minor numbers 0 to 255.
+ </para>
+
+ <section>
+ <title>Querying Capabilities</title>
+
+ <para>
+Devices supporting the SDR receiver interface set the
+<constant>V4L2_CAP_SDR_CAPTURE</constant> and
+<constant>V4L2_CAP_TUNER</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. That flag means the device has an
+Analog to Digital Converter (ADC), which is a mandatory element for the SDR receiver.
+At least one of the read/write, streaming or asynchronous I/O methods must
+be supported.
+ </para>
+ </section>
+
+ <section>
+ <title>Supplemental Functions</title>
+
+ <para>
+SDR devices can support <link linkend="control">controls</link>, and must
+support the <link linkend="tuner">tuner</link> ioctls. Tuner ioctls are used
+for setting the ADC sampling rate (sampling frequency) and the possible RF tuner
+frequency.
+ </para>
+
+ <para>
+The <constant>V4L2_TUNER_ADC</constant> tuner type is used for ADC tuners, and
+the <constant>V4L2_TUNER_RF</constant> tuner type is used for RF tuners. The
+tuner index of the RF tuner (if any) must always follow the ADC tuner index.
+Normally the ADC tuner is #0 and the RF tuner is #1.
+ </para>
+
+ <para>
+The &VIDIOC-S-HW-FREQ-SEEK; ioctl is not supported.
+ </para>
+ </section>
+
+ <section>
+ <title>Data Format Negotiation</title>
+
+ <para>
+The SDR capture device uses the <link linkend="format">format</link> ioctls to
+select the capture format. Both the sampling resolution and the data streaming
+format are bound to that selectable format. In addition to the basic
+<link linkend="format">format</link> ioctls, the &VIDIOC-ENUM-FMT; ioctl
+must be supported as well.
+ </para>
+
+ <para>
+To use the <link linkend="format">format</link> ioctls applications set the
+<structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_SDR_CAPTURE</constant> and use the &v4l2-format-sdr;
+<structfield>sdr</structfield> member of the <structfield>fmt</structfield>
+union as needed per the desired operation.
+Currently only the <structfield>pixelformat</structfield> field of
+&v4l2-format-sdr; is used. The content of that field is the V4L2 fourcc code
+of the data format.
+ </para>
+
+ <table pgwide="1" frame="none" id="v4l2-format-sdr">
+ <title>struct <structname>v4l2_format_sdr</structname></title>
+ <tgroup cols="3">
+ &cs-str;
+ <tbody valign="top">
+ <row>
+ <entry>__u32</entry>
+ <entry><structfield>pixelformat</structfield></entry>
+ <entry>
+The data format or type of compression, set by the application. This is a
+little endian <link linkend="v4l2-fourcc">four character code</link>.
+V4L2 defines SDR formats in <xref linkend="sdr-formats" />.
+ </entry>
+ </row>
+ <row>
+ <entry>__u8</entry>
+ <entry><structfield>reserved[28]</structfield></entry>
+ <entry>This array is reserved for future extensions.
+Drivers and applications must set it to zero.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+An SDR device may support <link linkend="rw">read/write</link>
+and/or streaming (<link linkend="mmap">memory mapping</link>
+or <link linkend="userp">user pointer</link>) I/O.
+ </para>
+
+ </section>
diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml
index 2c4c068..1fb11e8 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -1005,6 +1005,12 @@ should set this to 0.</entry>
<entry>Buffer for video output overlay (OSD), see <xref
linkend="osd" />.</entry>
</row>
+ <row>
+ <entry><constant>V4L2_BUF_TYPE_SDR_CAPTURE</constant></entry>
+ <entry>11</entry>
+ <entry>Buffer for Software Defined Radio (SDR), see <xref
+ linkend="sdr" />.</entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml
index 72d72bd..f586d34 100644
--- a/Documentation/DocBook/media/v4l/pixfmt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt.xml
@@ -811,6 +811,14 @@ extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
</table>
</section>
+ <section id="sdr-formats">
+ <title>SDR Formats</title>
+
+ <para>These formats are used for <link linkend="sdr">SDR Capture</link>
+interface only.</para>
+
+ </section>
+
<section id="pixfmt-reserved">
<title>Reserved Format Identifiers</title>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index 74b7f27..6dd899c 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -537,6 +537,7 @@ and discussions on the V4L mailing list.</revremark>
<section id="ttx"> &sub-dev-teletext; </section>
<section id="radio"> &sub-dev-radio; </section>
<section id="rds"> &sub-dev-rds; </section>
+ <section id="sdr"> &sub-dev-sdr; </section>
<section id="event"> &sub-dev-event; </section>
<section id="subdev"> &sub-dev-subdev; </section>
</chapter>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml b/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
index ee8f56e..f43f1a9 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-fmt.xml
@@ -172,6 +172,13 @@ capture and output devices.</entry>
</row>
<row>
<entry></entry>
+ <entry>&v4l2-format-sdr;</entry>
+ <entry><structfield>sdr</structfield></entry>
+ <entry>Definition of a data format, see
+<xref linkend="pixfmt" />, used by SDR capture devices.</entry>
+ </row>
+ <row>
+ <entry></entry>
<entry>__u8</entry>
<entry><structfield>raw_data</structfield>[200]</entry>
<entry>Place holder for future extensions.</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-querycap.xml b/Documentation/DocBook/media/v4l/vidioc-querycap.xml
index d5a3c97..370d49d 100644
--- a/Documentation/DocBook/media/v4l/vidioc-querycap.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-querycap.xml
@@ -296,6 +296,12 @@ modulator programming see
<xref linkend="tuner" />.</entry>
</row>
<row>
+ <entry><constant>V4L2_CAP_SDR_CAPTURE</constant></entry>
+ <entry>0x00100000</entry>
+ <entry>The device supports the
+<link linkend="sdr">SDR Capture</link> interface.</entry>
+ </row>
+ <row>
<entry><constant>V4L2_CAP_READWRITE</constant></entry>
<entry>0x01000000</entry>
<entry>The device supports the <link
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 32/52] DocBook: mark SDR API as Experimental
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (30 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 31/52] DocBook: Software Defined Radio Interface Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 33/52] v4l2-framework.txt: add SDR device type Antti Palosaari
` (19 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Let it be experimental still as all SDR drivers are in staging.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
Documentation/DocBook/media/v4l/compat.xml | 3 +++
Documentation/DocBook/media/v4l/dev-sdr.xml | 6 ++++++
2 files changed, 9 insertions(+)
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index 0b4db0e..e72eaab 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2661,6 +2661,9 @@ ioctls.</para>
<listitem>
<para>Exporting DMABUF files using &VIDIOC-EXPBUF; ioctl.</para>
</listitem>
+ <listitem>
+ <para>Software Defined Radio (SDR) Interface, <xref linkend="sdr" />.</para>
+ </listitem>
</itemizedlist>
</section>
diff --git a/Documentation/DocBook/media/v4l/dev-sdr.xml b/Documentation/DocBook/media/v4l/dev-sdr.xml
index 332b87f..ac9f1af 100644
--- a/Documentation/DocBook/media/v4l/dev-sdr.xml
+++ b/Documentation/DocBook/media/v4l/dev-sdr.xml
@@ -1,5 +1,11 @@
<title>Software Defined Radio Interface (SDR)</title>
+ <note>
+ <title>Experimental</title>
+ <para>This is an <link linkend="experimental"> experimental </link>
+ interface and may change in the future.</para>
+ </note>
+
<para>
SDR is an abbreviation of Software Defined Radio, the radio device
which uses application software for modulation or demodulation. This interface
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 33/52] v4l2-framework.txt: add SDR device type
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (31 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 32/52] DocBook: mark SDR API as Experimental Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 34/52] devices.txt: add video4linux device for Software Defined Radio Antti Palosaari
` (18 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Add SDR device type to v4l2-framework.txt document.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
Documentation/video4linux/v4l2-framework.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 6c4866b..ae3a2cc 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -768,6 +768,7 @@ types exist:
VFL_TYPE_GRABBER: videoX for video input/output devices
VFL_TYPE_VBI: vbiX for vertical blank data (i.e. closed captions, teletext)
VFL_TYPE_RADIO: radioX for radio tuners
+VFL_TYPE_SDR: swradioX for Software Defined Radio tuners
The last argument gives you a certain amount of control over the device
device node number used (i.e. the X in videoX). Normally you will pass -1
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 34/52] devices.txt: add video4linux device for Software Defined Radio
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (32 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 33/52] v4l2-framework.txt: add SDR device type Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 35/52] rtl2832_sdr: convert to SDR API Antti Palosaari
` (17 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari, Hans Verkuil
Add new video4linux device named /dev/swradio for Software Defined
Radio use. V4L device minor numbers are allocated dynamically
nowadays, but there is still configuration option for old fixed style.
Add note to mention that configuration option too.
Cc: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
Documentation/devices.txt | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index 80b7241..e852855 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -1490,10 +1490,17 @@ Your cooperation is appreciated.
64 = /dev/radio0 Radio device
...
127 = /dev/radio63 Radio device
+ 128 = /dev/swradio0 Software Defined Radio device
+ ...
+ 191 = /dev/swradio63 Software Defined Radio device
224 = /dev/vbi0 Vertical blank interrupt
...
255 = /dev/vbi31 Vertical blank interrupt
+ Minor numbers are allocated dynamically unless
+ CONFIG_VIDEO_FIXED_MINOR_RANGES (default n)
+ configuration option is set.
+
81 block I2O hard disk
0 = /dev/i2o/hdq 17th I2O hard disk, whole disk
16 = /dev/i2o/hdr 18th I2O hard disk, whole disk
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 35/52] rtl2832_sdr: convert to SDR API
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (33 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 34/52] devices.txt: add video4linux device for Software Defined Radio Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 36/52] msi3101: " Antti Palosaari
` (16 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
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 | 387 +++++++++++++----------
1 file changed, 223 insertions(+), 164 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 4b8c016..a26125c 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,22 +32,75 @@
#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 */
-#define RTL2832_SDR_CID_SAMPLING_MODE ((V4L2_CID_USER_BASE | 0xf000) + 0)
-#define RTL2832_SDR_CID_SAMPLING_RATE ((V4L2_CID_USER_BASE | 0xf000) + 1)
-#define RTL2832_SDR_CID_SAMPLING_RESOLUTION ((V4L2_CID_USER_BASE | 0xf000) + 2)
-#define RTL2832_SDR_CID_TUNER_RF ((V4L2_CID_USER_BASE | 0xf000) + 10)
#define RTL2832_SDR_CID_TUNER_BW ((V4L2_CID_USER_BASE | 0xf000) + 11)
-#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_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 50000000,
+ .rangehigh = 2000000000,
+ },
+};
+
+/* stream formats */
+struct rtl2832_sdr_format {
+ char *name;
+ u32 pixelformat;
+};
+
+static struct rtl2832_sdr_format formats[] = {
+ {
+ .name = "8-bit unsigned",
+ .pixelformat = V4L2_PIX_FMT_SDR_U8,
+ }, {
+ .name = "16-bit unsigned little endian",
+ .pixelformat = V4L2_PIX_FMT_SDR_U16LE,
+ },
+};
+
+static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
+
/* 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,18 +143,18 @@ 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;
- struct v4l2_ctrl *ctrl_tuner_rf;
struct v4l2_ctrl *ctrl_tuner_bw;
- struct v4l2_ctrl *ctrl_tuner_if;
struct v4l2_ctrl *ctrl_tuner_gain;
/* for sample rate calc */
unsigned int sample;
unsigned int sample_measured;
- unsigned long jiffies;
+ unsigned long jiffies_next;
};
/* write multiple hardware registers */
@@ -292,27 +339,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 +404,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 +605,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;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
@@ -560,7 +621,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;
@@ -609,7 +671,10 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
if (!test_bit(POWER_ON, &s->flags))
return 0;
- f_sr = s->ctrl_sampling_rate->val64;
+ if (s->f_adc == 0)
+ return 0;
+
+ f_sr = s->f_adc;
ret = rtl2832_sdr_wr_regs(s, 0x13e, "\x00\x00", 2);
ret = rtl2832_sdr_wr_regs(s, 0x115, "\x00", 1);
@@ -788,17 +853,15 @@ static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
struct dvb_frontend *fe = s->fe;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- unsigned int f_rf = s->ctrl_tuner_rf->val64;
-
/*
- * bandwidth (Hz)
+ * tuner RF (Hz)
*/
- unsigned int bandwidth = s->ctrl_tuner_bw->val;
+ unsigned int f_rf = s->f_tuner;
/*
- * intermediate frequency (Hz)
+ * bandwidth (Hz)
*/
- unsigned int f_if = s->ctrl_tuner_if->val;
+ unsigned int bandwidth = s->ctrl_tuner_bw->val;
/*
* gain (dB)
@@ -806,8 +869,11 @@ static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
int gain = s->ctrl_tuner_gain->val;
dev_dbg(&s->udev->dev,
- "%s: f_rf=%u bandwidth=%d f_if=%u gain=%d\n",
- __func__, f_rf, bandwidth, f_if, gain);
+ "%s: f_rf=%u bandwidth=%d gain=%d\n",
+ __func__, f_rf, bandwidth, gain);
+
+ if (f_rf == 0)
+ return 0;
if (!test_bit(POWER_ON, &s->flags))
return 0;
@@ -913,123 +979,182 @@ 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_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
{
- if (i->index != 0)
+ 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_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+ v->rangelow = 50000000;
+ v->rangehigh = 2000000000;
+ } else {
return -EINVAL;
-
- strlcpy(i->name, "SDR data", sizeof(i->name));
- i->type = V4L2_INPUT_TYPE_CAMERA;
+ }
return 0;
}
-static int rtl2832_sdr_g_input(struct file *file, void *fh, unsigned int *i)
+static int rtl2832_sdr_s_tuner(struct file *file, void *priv,
+ const struct v4l2_tuner *v)
{
- *i = 0;
+ struct rtl2832_sdr_state *s = video_drvdata(file);
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
return 0;
}
-static int rtl2832_sdr_s_input(struct file *file, void *fh, unsigned int i)
-{
- return i ? -EINVAL : 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
- const 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;
+
+ *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_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
+static int rtl2832_sdr_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
-
- strcpy(v->name, "SDR RX");
- v->capability = V4L2_TUNER_CAP_LOW;
+ 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 0;
+ return ret;
}
-static int vidioc_s_frequency(struct file *file, void *priv,
+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);
- return v4l2_ctrl_s_ctrl_int64(s->ctrl_tuner_rf,
- f->frequency * 625UL / 10UL);
+ if (f->tuner == 0) {
+ s->f_adc = f->frequency;
+ dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
+ __func__, s->f_adc);
+ ret = rtl2832_sdr_set_adc(s);
+ } else if (f->tuner == 1) {
+ s->f_tuner = f->frequency;
+ dev_dbg(&s->udev->dev, "%s: RF frequency=%u Hz\n",
+ __func__, f->frequency);
+ ret = rtl2832_sdr_set_tuner(s);
+ } else {
+ return -EINVAL;
+ }
+
+ 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;
- 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,14 +1162,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_input = rtl2832_sdr_enum_input,
- .vidioc_g_input = rtl2832_sdr_g_input,
- .vidioc_s_input = rtl2832_sdr_s_input,
+ .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_reqbufs = vb2_ioctl_reqbufs,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
@@ -1056,9 +1177,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,
@@ -1076,7 +1200,7 @@ static const struct v4l2_file_operations rtl2832_sdr_fops = {
};
static struct video_device rtl2832_sdr_template = {
- .name = "Realtek RTL2832U SDR",
+ .name = "Realtek RTL2832 SDR",
.release = video_device_release_empty,
.fops = &rtl2832_sdr_fops,
.ioctl_ops = &rtl2832_sdr_ioctl_ops,
@@ -1094,14 +1218,7 @@ static int rtl2832_sdr_s_ctrl(struct v4l2_ctrl *ctrl)
ctrl->minimum, ctrl->maximum, ctrl->step);
switch (ctrl->id) {
- case RTL2832_SDR_CID_SAMPLING_MODE:
- case RTL2832_SDR_CID_SAMPLING_RATE:
- case RTL2832_SDR_CID_SAMPLING_RESOLUTION:
- ret = rtl2832_sdr_set_adc(s);
- break;
- case RTL2832_SDR_CID_TUNER_RF:
case RTL2832_SDR_CID_TUNER_BW:
- case RTL2832_SDR_CID_TUNER_IF:
case RTL2832_SDR_CID_TUNER_GAIN:
ret = rtl2832_sdr_set_tuner(s);
break;
@@ -1132,49 +1249,6 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
int ret;
struct rtl2832_sdr_state *s;
struct dvb_usb_device *d = i2c_get_adapdata(i2c);
- static const char * const ctrl_sampling_mode_qmenu_strings[] = {
- "Quadrature Sampling",
- NULL,
- };
- static const struct v4l2_ctrl_config ctrl_sampling_mode = {
- .ops = &rtl2832_sdr_ctrl_ops,
- .id = RTL2832_SDR_CID_SAMPLING_MODE,
- .type = V4L2_CTRL_TYPE_MENU,
- .flags = V4L2_CTRL_FLAG_INACTIVE,
- .name = "Sampling Mode",
- .qmenu = ctrl_sampling_mode_qmenu_strings,
- };
- static const struct v4l2_ctrl_config ctrl_sampling_rate = {
- .ops = &rtl2832_sdr_ctrl_ops,
- .id = RTL2832_SDR_CID_SAMPLING_RATE,
- .type = V4L2_CTRL_TYPE_INTEGER64,
- .name = "Sampling Rate",
- .min = 900001,
- .max = 2800000,
- .def = 2048000,
- .step = 1,
- };
- static const struct v4l2_ctrl_config ctrl_sampling_resolution = {
- .ops = &rtl2832_sdr_ctrl_ops,
- .id = RTL2832_SDR_CID_SAMPLING_RESOLUTION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .flags = V4L2_CTRL_FLAG_INACTIVE,
- .name = "Sampling Resolution",
- .min = 8,
- .max = 8,
- .def = 8,
- .step = 1,
- };
- static const struct v4l2_ctrl_config ctrl_tuner_rf = {
- .ops = &rtl2832_sdr_ctrl_ops,
- .id = RTL2832_SDR_CID_TUNER_RF,
- .type = V4L2_CTRL_TYPE_INTEGER64,
- .name = "Tuner RF",
- .min = 40000000,
- .max = 2000000000,
- .def = 100000000,
- .step = 1,
- };
static const struct v4l2_ctrl_config ctrl_tuner_bw = {
.ops = &rtl2832_sdr_ctrl_ops,
.id = RTL2832_SDR_CID_TUNER_BW,
@@ -1185,17 +1259,6 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
.def = 600000,
.step = 1,
};
- static const struct v4l2_ctrl_config ctrl_tuner_if = {
- .ops = &rtl2832_sdr_ctrl_ops,
- .id = RTL2832_SDR_CID_TUNER_IF,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .flags = V4L2_CTRL_FLAG_INACTIVE,
- .name = "Tuner IF",
- .min = 0,
- .max = 10,
- .def = 0,
- .step = 1,
- };
static const struct v4l2_ctrl_config ctrl_tuner_gain = {
.ops = &rtl2832_sdr_ctrl_ops,
.id = RTL2832_SDR_CID_TUNER_GAIN,
@@ -1227,7 +1290,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);
@@ -1248,13 +1311,8 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
video_set_drvdata(&s->vdev, s);
/* Register controls */
- v4l2_ctrl_handler_init(&s->ctrl_handler, 7);
- v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_mode, NULL);
- s->ctrl_sampling_rate = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_rate, NULL);
- v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_resolution, NULL);
- s->ctrl_tuner_rf = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_rf, NULL);
+ v4l2_ctrl_handler_init(&s->ctrl_handler, 2);
s->ctrl_tuner_bw = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_bw, NULL);
- s->ctrl_tuner_if = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_if, NULL);
s->ctrl_tuner_gain = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_gain, NULL);
if (s->ctrl_handler.error) {
ret = s->ctrl_handler.error;
@@ -1274,8 +1332,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",
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 36/52] msi3101: convert to SDR API
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (34 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 35/52] rtl2832_sdr: convert to SDR API Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 37/52] msi3101: add u8 sample format Antti Palosaari
` (15 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Convert to SDR API.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 218 ++++++++++++++++++----------
1 file changed, 142 insertions(+), 76 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 16ce417..502d35d 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -386,10 +386,39 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
#define MSI3101_CID_TUNER_GAIN ((V4L2_CID_USER_BASE | 0xf000) + 13)
#define V4L2_PIX_FMT_SDR_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
-#define V4L2_PIX_FMT_SDR_S12 v4l2_fourcc('D', 'S', '1', '2') /* signed 12-bit */
-#define V4L2_PIX_FMT_SDR_S14 v4l2_fourcc('D', 'S', '1', '4') /* signed 14-bit */
+#define V4L2_PIX_FMT_SDR_S12 v4l2_fourcc('D', 'S', '1', '2') /* signed 12-bit */
+#define V4L2_PIX_FMT_SDR_S14 v4l2_fourcc('D', 'S', '1', '4') /* signed 14-bit */
#define V4L2_PIX_FMT_SDR_MSI2500_384 v4l2_fourcc('M', '3', '8', '4') /* Mirics MSi2500 format 384 */
+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 = 1200000,
+ .rangehigh = 15000000,
+ },
+};
+
+static const struct v4l2_frequency_band bands_rf[] = {
+ {
+ .tuner = 1,
+ .type = V4L2_TUNER_RF,
+ .index = 0,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 49000000 / 62.5,
+ .rangehigh = 263000000 / 62.5,
+ }, {
+ .tuner = 1,
+ .type = V4L2_TUNER_RF,
+ .index = 1,
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 390000000 / 62.5,
+ .rangehigh = 960000000 / 62.5,
+ },
+};
+
/* stream formats */
struct msi3101_format {
char *name;
@@ -437,6 +466,7 @@ struct msi3101_state {
/* Pointer to our usb_device, will be NULL after unplug */
struct usb_device *udev; /* Both mutexes most be hold when setting! */
+ unsigned int f_adc, f_tuner;
u32 pixelformat;
unsigned int isoc_errors; /* number of contiguous ISOC errors */
@@ -479,16 +509,6 @@ leave:
}
/*
- * Integer to 32-bit IEEE floating point representation routine is taken
- * from Radeon R600 driver (drivers/gpu/drm/radeon/r600_blit_kms.c).
- *
- * TODO: Currently we do conversion here in Kernel, but in future that will
- * be moved to the libv4l2 library as video format conversions are.
- */
-#define I2F_FRAC_BITS 23
-#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
-
-/*
* +===========================================================================
* | 00-1023 | USB packet type '504'
* +===========================================================================
@@ -1016,12 +1036,11 @@ static int msi3101_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;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
-
/* Videobuf2 operations */
static int msi3101_queue_setup(struct vb2_queue *vq,
const struct v4l2_format *fmt, unsigned int *nbuffers,
@@ -1037,9 +1056,9 @@ static int msi3101_queue_setup(struct vb2_queue *vq,
* 3, wMaxPacketSize 3x 1024 bytes
* 504, max IQ sample pairs per 1024 frame
* 2, two samples, I and Q
- * 4, 32-bit float
+ * 2, 16-bit is enough for single sample
*/
- sizes[0] = PAGE_ALIGN(3 * 504 * 2 * 4); /* = 12096 */
+ sizes[0] = PAGE_ALIGN(3 * 504 * 2 * 2);
dev_dbg(&s->udev->dev, "%s: nbuffers=%d sizes[0]=%d\n",
__func__, *nbuffers, sizes[0]);
return 0;
@@ -1525,30 +1544,7 @@ static struct vb2_ops msi3101_vb2_ops = {
.wait_finish = vb2_ops_wait_finish,
};
-static int msi3101_enum_input(struct file *file, void *fh, struct v4l2_input *i)
-{
- if (i->index != 0)
- return -EINVAL;
-
- strlcpy(i->name, "SDR data", sizeof(i->name));
- i->type = V4L2_INPUT_TYPE_CAMERA;
-
- return 0;
-}
-
-static int msi3101_g_input(struct file *file, void *fh, unsigned int *i)
-{
- *i = 0;
-
- return 0;
-}
-
-static int msi3101_s_input(struct file *file, void *fh, unsigned int i)
-{
- return i ? -EINVAL : 0;
-}
-
-static int msi3101_enum_fmt_vid_cap(struct file *file, void *priv,
+static int msi3101_enum_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
struct msi3101_state *s = video_drvdata(file);
@@ -1563,70 +1559,70 @@ static int msi3101_enum_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-static int msi3101_g_fmt_vid_cap(struct file *file, void *priv,
+static int msi3101_g_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct msi3101_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;
- f->fmt.pix.pixelformat = s->pixelformat;
+ f->fmt.sdr.pixelformat = s->pixelformat;
return 0;
}
-static int msi3101_s_fmt_vid_cap(struct file *file, void *priv,
+static int msi3101_s_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct msi3101_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;
for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].pixelformat == f->fmt.pix.pixelformat) {
- s->pixelformat = f->fmt.pix.pixelformat;
+ if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
+ s->pixelformat = f->fmt.sdr.pixelformat;
return 0;
}
}
- f->fmt.pix.pixelformat = formats[0].pixelformat;
+ f->fmt.sdr.pixelformat = formats[0].pixelformat;
s->pixelformat = formats[0].pixelformat;
return 0;
}
-static int msi3101_try_fmt_vid_cap(struct file *file, void *priv,
+static int msi3101_try_fmt_sdr_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct msi3101_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;
for (i = 0; i < NUM_FORMATS; i++) {
- if (formats[i].pixelformat == f->fmt.pix.pixelformat)
+ if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
return 0;
}
- f->fmt.pix.pixelformat = formats[0].pixelformat;
+ f->fmt.sdr.pixelformat = formats[0].pixelformat;
return 0;
}
-static int vidioc_s_tuner(struct file *file, void *priv,
+static int msi3101_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *v)
{
struct msi3101_state *s = video_drvdata(file);
@@ -1635,39 +1631,106 @@ 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 msi3101_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
{
struct msi3101_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
- strcpy(v->name, "SDR RX");
- v->capability = V4L2_TUNER_CAP_LOW;
+ if (v->index == 0) {
+ strlcpy(v->name, "ADC: Mirics MSi2500", sizeof(v->name));
+ v->type = V4L2_TUNER_ADC;
+ v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+ v->rangelow = 1200000;
+ v->rangehigh = 15000000;
+ } else if (v->index == 1) {
+ strlcpy(v->name, "RF: Mirics MSi001", sizeof(v->name));
+ v->type = V4L2_TUNER_RF;
+ v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS;
+ v->rangelow = 49000000 / 62.5;
+ v->rangehigh = 960000000 / 62.5;
+ } else {
+ return -EINVAL;
+ }
return 0;
}
-static int vidioc_s_frequency(struct file *file, void *priv,
+static int msi3101_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct msi3101_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 msi3101_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
struct msi3101_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 msi3101_enum_freq_bands(struct file *file, void *priv,
+ struct v4l2_frequency_band *band)
+{
+ struct msi3101_state *s = video_drvdata(file);
+ 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;
+
+ *band = bands_adc[band->index];
+ } else if (band->tuner == 1) {
+ if (band->index >= ARRAY_SIZE(bands_rf))
+ return -EINVAL;
+
+ *band = bands_rf[band->index];
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
}
static const struct v4l2_ioctl_ops msi3101_ioctl_ops = {
.vidioc_querycap = msi3101_querycap,
- .vidioc_enum_fmt_vid_cap = msi3101_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = msi3101_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = msi3101_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = msi3101_try_fmt_vid_cap,
-
- .vidioc_enum_input = msi3101_enum_input,
- .vidioc_g_input = msi3101_g_input,
- .vidioc_s_input = msi3101_s_input,
+ .vidioc_enum_fmt_sdr_cap = msi3101_enum_fmt_sdr_cap,
+ .vidioc_g_fmt_sdr_cap = msi3101_g_fmt_sdr_cap,
+ .vidioc_s_fmt_sdr_cap = msi3101_s_fmt_sdr_cap,
+ .vidioc_try_fmt_sdr_cap = msi3101_try_fmt_sdr_cap,
.vidioc_reqbufs = vb2_ioctl_reqbufs,
.vidioc_create_bufs = vb2_ioctl_create_bufs,
@@ -1679,9 +1742,12 @@ static const struct v4l2_ioctl_ops msi3101_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 = msi3101_g_tuner,
+ .vidioc_s_tuner = msi3101_s_tuner,
+
+ .vidioc_g_frequency = msi3101_g_frequency,
+ .vidioc_s_frequency = msi3101_s_frequency,
+ .vidioc_enum_freq_bands = msi3101_enum_freq_bands,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
@@ -1844,7 +1910,7 @@ static int msi3101_probe(struct usb_interface *intf,
s->udev = udev;
/* 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 msi3101_frame_buf);
@@ -1892,7 +1958,7 @@ static int msi3101_probe(struct usb_interface *intf,
s->vdev.v4l2_dev = &s->v4l2_dev;
s->vdev.lock = &s->v4l2_lock;
- 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",
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 37/52] msi3101: add u8 sample format
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (35 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 36/52] msi3101: " Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 38/52] msi3101: add u16 LE " Antti Palosaari
` (14 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Add unsigned 8-bit sample format. Format is got directly from
hardware, but it is converted from signed to unsigned. It is worst
known sampling resolution hardware offer.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 67 ++++++++++++++++++++++++++++-
1 file changed, 66 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 502d35d..c50402d 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -385,6 +385,7 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
#define MSI3101_CID_TUNER_IF ((V4L2_CID_USER_BASE | 0xf000) + 12)
#define MSI3101_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_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
#define V4L2_PIX_FMT_SDR_S12 v4l2_fourcc('D', 'S', '1', '2') /* signed 12-bit */
#define V4L2_PIX_FMT_SDR_S14 v4l2_fourcc('D', 'S', '1', '4') /* signed 14-bit */
@@ -428,6 +429,9 @@ struct msi3101_format {
/* format descriptions for capture and preview */
static struct msi3101_format formats[] = {
{
+ .name = "I/Q 8-bit unsigned",
+ .pixelformat = V4L2_PIX_FMT_SDR_U8,
+ }, {
.name = "I/Q 8-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S8,
}, {
@@ -487,6 +491,7 @@ struct msi3101_state {
u32 next_sample; /* for track lost packets */
u32 sample; /* for sample rate calc */
unsigned long jiffies;
+ unsigned long jiffies_next;
unsigned int sample_ctrl_bit[4];
};
@@ -572,6 +577,63 @@ static int msi3101_convert_stream_504(struct msi3101_state *s, u8 *dst,
return dst_len;
}
+static int msi3101_convert_stream_504_u8(struct msi3101_state *s, u8 *dst,
+ u8 *src, unsigned int src_len)
+{
+ int i, j, i_max, dst_len = 0;
+ u32 sample_num[3];
+ s8 *s8src;
+ u8 *u8dst;
+
+ /* There could be 1-3 1024 bytes URB frames */
+ i_max = src_len / 1024;
+ u8dst = (u8 *) dst;
+
+ for (i = 0; i < i_max; i++) {
+ sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
+ if (i == 0 && s->next_sample != sample_num[0]) {
+ dev_dbg_ratelimited(&s->udev->dev,
+ "%d samples lost, %d %08x:%08x\n",
+ sample_num[0] - s->next_sample,
+ src_len, s->next_sample, sample_num[0]);
+ }
+
+ /*
+ * Dump all unknown 'garbage' data - maybe we will discover
+ * someday if there is something rational...
+ */
+ dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
+
+ /* 504 x I+Q samples */
+ src += 16;
+
+ s8src = (s8 *) src;
+ for (j = 0; j < 1008; j++)
+ *u8dst++ = *s8src++ + 128;
+
+ src += 1008;
+ dst += 1008;
+ dst_len += 1008;
+ }
+
+ /* calculate samping rate and output it in 10 seconds intervals */
+ if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
+#define MSECS 10000UL
+ unsigned int samples = sample_num[i_max - 1] - s->sample;
+ s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
+ s->sample = sample_num[i_max - 1];
+ dev_dbg(&s->udev->dev,
+ "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
+ src_len, samples, MSECS,
+ samples * 1000UL / MSECS);
+ }
+
+ /* next sample (sample = sample + i * 504) */
+ s->next_sample = sample_num[i_max - 1] + 504;
+
+ return dst_len;
+}
+
/*
* +===========================================================================
* | 00-1023 | USB packet type '384'
@@ -1159,7 +1221,10 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
reg7 = 0x000c9407;
}
- if (s->pixelformat == V4L2_PIX_FMT_SDR_S8) {
+ if (s->pixelformat == V4L2_PIX_FMT_SDR_U8) {
+ s->convert_stream = msi3101_convert_stream_504_u8;
+ reg7 = 0x000c9407;
+ } else if (s->pixelformat == V4L2_PIX_FMT_SDR_S8) {
s->convert_stream = msi3101_convert_stream_504;
reg7 = 0x000c9407;
} else if (s->pixelformat == V4L2_PIX_FMT_SDR_MSI2500_384) {
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 38/52] msi3101: add u16 LE sample format
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (36 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 37/52] msi3101: add u8 sample format Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 39/52] msi3101: tons of small changes Antti Palosaari
` (13 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Add unsigned 16-bit little endian sample format. That stream
format is scaled from hardware 14-bit signed value. That is best
known sampling resolution that MSi2500 ADC provides.
It is not guaranteed to be little endian, but host endian which is
usually little endian - room for improvement.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 79 +++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index c50402d..7a64f18 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -386,6 +386,7 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
#define MSI3101_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_U16LE v4l2_fourcc('D', 'U', '1', '6') /* unsigned 16-bit LE */
#define V4L2_PIX_FMT_SDR_S8 v4l2_fourcc('D', 'S', '0', '8') /* signed 8-bit */
#define V4L2_PIX_FMT_SDR_S12 v4l2_fourcc('D', 'S', '1', '2') /* signed 12-bit */
#define V4L2_PIX_FMT_SDR_S14 v4l2_fourcc('D', 'S', '1', '4') /* signed 14-bit */
@@ -432,6 +433,9 @@ static struct msi3101_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,
+ }, {
.name = "I/Q 8-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S8,
}, {
@@ -857,6 +861,78 @@ static int msi3101_convert_stream_252(struct msi3101_state *s, u8 *dst,
return dst_len;
}
+static int msi3101_convert_stream_252_u16(struct msi3101_state *s, u8 *dst,
+ u8 *src, unsigned int src_len)
+{
+ int i, j, i_max, dst_len = 0;
+ u32 sample_num[3];
+ u16 *u16dst = (u16 *) dst;
+ struct {signed int x:14;} se;
+
+ /* There could be 1-3 1024 bytes URB frames */
+ i_max = src_len / 1024;
+
+ for (i = 0; i < i_max; i++) {
+ sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
+ if (i == 0 && s->next_sample != sample_num[0]) {
+ dev_dbg_ratelimited(&s->udev->dev,
+ "%d samples lost, %d %08x:%08x\n",
+ sample_num[0] - s->next_sample,
+ src_len, s->next_sample, sample_num[0]);
+ }
+
+ /*
+ * Dump all unknown 'garbage' data - maybe we will discover
+ * someday if there is something rational...
+ */
+ dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
+
+ /* 252 x I+Q samples */
+ src += 16;
+
+ for (j = 0; j < 1008; j += 4) {
+ unsigned int usample[2];
+ int ssample[2];
+
+ usample[0] = src[j + 0] >> 0 | src[j + 1] << 8;
+ usample[1] = src[j + 2] >> 0 | src[j + 3] << 8;
+
+ /* sign extension from 14-bit to signed int */
+ ssample[0] = se.x = usample[0];
+ ssample[1] = se.x = usample[1];
+
+ /* from signed to unsigned */
+ usample[0] = ssample[0] + 8192;
+ usample[1] = ssample[1] + 8192;
+
+ /* from 14-bit to 16-bit */
+ *u16dst++ = (usample[0] << 2) | (usample[0] >> 12);
+ *u16dst++ = (usample[1] << 2) | (usample[1] >> 12);
+ }
+
+ src += 1008;
+ dst += 1008;
+ dst_len += 1008;
+ }
+
+ /* calculate samping rate and output it in 10 seconds intervals */
+ if (unlikely(time_is_before_jiffies(s->jiffies_next))) {
+#define MSECS 10000UL
+ unsigned int samples = sample_num[i_max - 1] - s->sample;
+ s->jiffies_next = jiffies + msecs_to_jiffies(MSECS);
+ s->sample = sample_num[i_max - 1];
+ dev_dbg(&s->udev->dev,
+ "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
+ src_len, samples, MSECS,
+ samples * 1000UL / MSECS);
+ }
+
+ /* next sample (sample = sample + i * 252) */
+ s->next_sample = sample_num[i_max - 1] + 252;
+
+ return dst_len;
+}
+
/*
* This gets called for the Isochronous pipe (stream). This is done in interrupt
* time, so it has to be fast, not crash, and not stall. Neat.
@@ -1224,6 +1300,9 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
if (s->pixelformat == V4L2_PIX_FMT_SDR_U8) {
s->convert_stream = msi3101_convert_stream_504_u8;
reg7 = 0x000c9407;
+ } else if (s->pixelformat == V4L2_PIX_FMT_SDR_U16LE) {
+ s->convert_stream = msi3101_convert_stream_252_u16;
+ reg7 = 0x00009407;
} else if (s->pixelformat == V4L2_PIX_FMT_SDR_S8) {
s->convert_stream = msi3101_convert_stream_504;
reg7 = 0x000c9407;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 39/52] msi3101: tons of small changes
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (37 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 38/52] msi3101: add u16 LE " Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 40/52] v4l: disable lockdep on vb2_fop_mmap() Antti Palosaari
` (12 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
* remove unneeded controls
* rename things
* remove unneeded callbacks
* use likely/unlikely on hot paths
* use 1Hz resolution for tuner RF frequency
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 214 +++++++---------------------
1 file changed, 55 insertions(+), 159 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 7a64f18..cb66f81 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -21,20 +21,6 @@
* (C) 1999-2004 Nemosoft Unv.
* (C) 2004-2006 Luc Saillard (luc@saillard.org)
* (C) 2011 Hans de Goede <hdegoede@redhat.com>
- *
- * Development tree of that driver will be on:
- * http://git.linuxtv.org/anttip/media_tree.git/shortlog/refs/heads/mirics
- *
- * 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:
- * - split USB ADC interface and RF tuner to own drivers (msi2500 and msi001)
- * - 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 <linux/module.h>
@@ -377,12 +363,7 @@ static const struct msi3101_gain msi3101_gain_lut_1000[] = {
#define MAX_ISOC_ERRORS 20
/* TODO: These should be moved to V4L2 API */
-#define MSI3101_CID_SAMPLING_MODE ((V4L2_CID_USER_BASE | 0xf000) + 0)
-#define MSI3101_CID_SAMPLING_RATE ((V4L2_CID_USER_BASE | 0xf000) + 1)
-#define MSI3101_CID_SAMPLING_RESOLUTION ((V4L2_CID_USER_BASE | 0xf000) + 2)
-#define MSI3101_CID_TUNER_RF ((V4L2_CID_USER_BASE | 0xf000) + 10)
#define MSI3101_CID_TUNER_BW ((V4L2_CID_USER_BASE | 0xf000) + 11)
-#define MSI3101_CID_TUNER_IF ((V4L2_CID_USER_BASE | 0xf000) + 12)
#define MSI3101_CID_TUNER_GAIN ((V4L2_CID_USER_BASE | 0xf000) + 13)
#define V4L2_PIX_FMT_SDR_U8 v4l2_fourcc('D', 'U', '0', '8') /* unsigned 8-bit */
@@ -408,16 +389,16 @@ static const struct v4l2_frequency_band bands_rf[] = {
.tuner = 1,
.type = V4L2_TUNER_RF,
.index = 0,
- .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 49000000 / 62.5,
- .rangehigh = 263000000 / 62.5,
+ .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 49000000,
+ .rangehigh = 263000000,
}, {
.tuner = 1,
.type = V4L2_TUNER_RF,
.index = 1,
- .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
- .rangelow = 390000000 / 62.5,
- .rangehigh = 960000000 / 62.5,
+ .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = 390000000,
+ .rangehigh = 960000000,
},
};
@@ -430,27 +411,27 @@ struct msi3101_format {
/* format descriptions for capture and preview */
static struct msi3101_format formats[] = {
{
- .name = "I/Q 8-bit unsigned",
+ .name = "8-bit unsigned",
.pixelformat = V4L2_PIX_FMT_SDR_U8,
}, {
- .name = "I/Q 16-bit unsigned little endian",
+ .name = "16-bit unsigned little endian",
.pixelformat = V4L2_PIX_FMT_SDR_U16LE,
}, {
- .name = "I/Q 8-bit signed",
+ .name = "8-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S8,
}, {
- .name = "I/Q 10+2-bit signed",
+ .name = "10+2-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_MSI2500_384,
}, {
- .name = "I/Q 12-bit signed",
+ .name = "12-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S12,
}, {
- .name = "I/Q 14-bit signed",
+ .name = "14-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S14,
},
};
-static const int NUM_FORMATS = sizeof(formats) / sizeof(struct msi3101_format);
+static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
/* intermediate buffers with raw data from the USB device */
struct msi3101_frame_buf {
@@ -486,15 +467,11 @@ struct msi3101_state {
/* Controls */
struct v4l2_ctrl_handler ctrl_handler;
- struct v4l2_ctrl *ctrl_sampling_rate;
- struct v4l2_ctrl *ctrl_tuner_rf;
struct v4l2_ctrl *ctrl_tuner_bw;
- struct v4l2_ctrl *ctrl_tuner_if;
struct v4l2_ctrl *ctrl_tuner_gain;
u32 next_sample; /* for track lost packets */
u32 sample; /* for sample rate calc */
- unsigned long jiffies;
unsigned long jiffies_next;
unsigned int sample_ctrl_bit[4];
};
@@ -563,11 +540,11 @@ static int msi3101_convert_stream_504(struct msi3101_state *s, u8 *dst,
}
/* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
+ if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
+ unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies = jiffies_now;
+ s->jiffies_next = jiffies_now;
s->sample = sample_num[i_max - 1];
dev_dbg(&s->udev->dev,
"slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
@@ -715,11 +692,11 @@ static int msi3101_convert_stream_384(struct msi3101_state *s, u8 *dst,
}
/* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
+ if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
+ unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies = jiffies_now;
+ s->jiffies_next = jiffies_now;
s->sample = sample_num[i_max - 1];
dev_dbg(&s->udev->dev,
"slen=%d samples=%u msecs=%lu sampling rate=%lu bits=%d.%d.%d.%d\n",
@@ -780,11 +757,11 @@ static int msi3101_convert_stream_336(struct msi3101_state *s, u8 *dst,
}
/* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
+ if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
+ unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies = jiffies_now;
+ s->jiffies_next = jiffies_now;
s->sample = sample_num[i_max - 1];
dev_dbg(&s->udev->dev,
"slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
@@ -843,11 +820,11 @@ static int msi3101_convert_stream_252(struct msi3101_state *s, u8 *dst,
}
/* calculate samping rate and output it in 10 seconds intervals */
- if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
+ if ((s->jiffies_next + msecs_to_jiffies(10000)) <= jiffies) {
unsigned long jiffies_now = jiffies;
- unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
+ unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies_next);
unsigned int samples = sample_num[i_max - 1] - s->sample;
- s->jiffies = jiffies_now;
+ s->jiffies_next = jiffies_now;
s->sample = sample_num[i_max - 1];
dev_dbg(&s->udev->dev,
"slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
@@ -944,14 +921,14 @@ static void msi3101_isoc_handler(struct urb *urb)
unsigned char *iso_buf = NULL;
struct msi3101_frame_buf *fbuf;
- if (urb->status == -ENOENT || urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN) {
+ if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN)) {
dev_dbg(&s->udev->dev, "URB (%p) unlinked %ssynchronuously\n",
urb, urb->status == -ENOENT ? "" : "a");
return;
}
- if (urb->status != 0) {
+ if (unlikely(urb->status != 0)) {
dev_dbg(&s->udev->dev,
"msi3101_isoc_handler() called with status %d\n",
urb->status);
@@ -971,28 +948,28 @@ static void msi3101_isoc_handler(struct urb *urb)
/* Check frame error */
fstatus = urb->iso_frame_desc[i].status;
- if (fstatus) {
+ if (unlikely(fstatus)) {
dev_dbg_ratelimited(&s->udev->dev,
"frame=%d/%d has error %d skipping\n",
i, urb->number_of_packets, fstatus);
- goto skip;
+ continue;
}
/* Check if that frame contains data */
flen = urb->iso_frame_desc[i].actual_length;
- if (flen == 0)
- goto skip;
+ if (unlikely(flen == 0))
+ continue;
iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
/* Get free framebuffer */
fbuf = msi3101_get_next_fill_buf(s);
- if (fbuf == NULL) {
+ if (unlikely(fbuf == NULL)) {
s->vb_full++;
dev_dbg_ratelimited(&s->udev->dev,
"videobuf is full, %d packets dropped\n",
s->vb_full);
- goto skip;
+ continue;
}
/* fill framebuffer */
@@ -1000,13 +977,11 @@ static void msi3101_isoc_handler(struct urb *urb)
flen = s->convert_stream(s, ptr, iso_buf, flen);
vb2_set_plane_payload(&fbuf->vb, 0, flen);
vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);
-skip:
- ;
}
handler_end:
i = usb_submit_urb(urb, GFP_ATOMIC);
- if (i != 0)
+ if (unlikely(i != 0))
dev_dbg(&s->udev->dev,
"Error (%d) re-submitting urb in msi3101_isoc_handler\n",
i);
@@ -1069,7 +1044,7 @@ static int msi3101_isoc_init(struct msi3101_state *s)
udev = s->udev;
ret = usb_set_interface(s->udev, 0, 1);
- if (ret < 0)
+ if (ret)
return ret;
/* Allocate and init Isochronuous urbs */
@@ -1202,17 +1177,6 @@ static int msi3101_queue_setup(struct vb2_queue *vq,
return 0;
}
-static int msi3101_buf_prepare(struct vb2_buffer *vb)
-{
- struct msi3101_state *s = vb2_get_drv_priv(vb->vb2_queue);
-
- /* Don't allow queing new buffers after device disconnection */
- if (!s->udev)
- return -ENODEV;
-
- return 0;
-}
-
static void msi3101_buf_queue(struct vb2_buffer *vb)
{
struct msi3101_state *s = vb2_get_drv_priv(vb->vb2_queue);
@@ -1221,7 +1185,7 @@ static void msi3101_buf_queue(struct vb2_buffer *vb)
unsigned long flags = 0;
/* Check the device has not disconnected between prep and queuing */
- if (!s->udev) {
+ if (unlikely(!s->udev)) {
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
return;
}
@@ -1280,7 +1244,7 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
int ret, div_n, div_m, div_r_out, f_sr, f_vco, fract;
u32 reg3, reg4, reg7;
- f_sr = s->ctrl_sampling_rate->val64;
+ f_sr = s->f_adc;
/* select stream format */
if (f_sr < 6000000) {
@@ -1455,7 +1419,7 @@ static int msi3101_set_tuner(struct msi3101_state *s)
{8000000, 0x07}, /* 8 MHz */
};
- unsigned int f_rf = s->ctrl_tuner_rf->val64;
+ unsigned int f_rf = s->f_tuner;
/*
* bandwidth (Hz)
@@ -1467,7 +1431,7 @@ static int msi3101_set_tuner(struct msi3101_state *s)
* intermediate frequency (Hz)
* 0, 450000, 1620000, 2048000
*/
- unsigned int f_if = s->ctrl_tuner_if->val;
+ unsigned int f_if = 0;
/*
* gain reduction (dB)
@@ -1680,7 +1644,6 @@ static int msi3101_stop_streaming(struct vb2_queue *vq)
static struct vb2_ops msi3101_vb2_ops = {
.queue_setup = msi3101_queue_setup,
- .buf_prepare = msi3101_buf_prepare,
.buf_queue = msi3101_buf_queue,
.start_streaming = msi3101_start_streaming,
.stop_streaming = msi3101_stop_streaming,
@@ -1789,9 +1752,9 @@ static int msi3101_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
} else if (v->index == 1) {
strlcpy(v->name, "RF: Mirics MSi001", sizeof(v->name));
v->type = V4L2_TUNER_RF;
- v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS;
- v->rangelow = 49000000 / 62.5;
- v->rangehigh = 960000000 / 62.5;
+ v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
+ v->rangelow = 49000000;
+ v->rangehigh = 960000000;
} else {
return -EINVAL;
}
@@ -1826,17 +1789,15 @@ static int msi3101_s_frequency(struct file *file, void *priv,
__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);
+ dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
+ __func__, s->f_adc);
+ ret = msi3101_set_usb_adc(s);
} 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);
+ dev_dbg(&s->udev->dev, "%s: RF frequency=%u Hz\n",
+ __func__, f->frequency);
+ ret = msi3101_set_tuner(s);
} else {
return -EINVAL;
}
@@ -1913,6 +1874,7 @@ static struct video_device msi3101_template = {
.release = video_device_release_empty,
.fops = &msi3101_fops,
.ioctl_ops = &msi3101_ioctl_ops,
+ .debug = 0,
};
static int msi3101_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -1927,14 +1889,7 @@ static int msi3101_s_ctrl(struct v4l2_ctrl *ctrl)
ctrl->minimum, ctrl->maximum, ctrl->step);
switch (ctrl->id) {
- case MSI3101_CID_SAMPLING_MODE:
- case MSI3101_CID_SAMPLING_RATE:
- case MSI3101_CID_SAMPLING_RESOLUTION:
- ret = 0;
- break;
- case MSI3101_CID_TUNER_RF:
case MSI3101_CID_TUNER_BW:
- case MSI3101_CID_TUNER_IF:
case MSI3101_CID_TUNER_GAIN:
ret = msi3101_set_tuner(s);
break;
@@ -1965,70 +1920,16 @@ static int msi3101_probe(struct usb_interface *intf,
struct usb_device *udev = interface_to_usbdev(intf);
struct msi3101_state *s = NULL;
int ret;
- static const char * const ctrl_sampling_mode_qmenu_strings[] = {
- "Quadrature Sampling",
- NULL,
- };
- static const struct v4l2_ctrl_config ctrl_sampling_mode = {
- .ops = &msi3101_ctrl_ops,
- .id = MSI3101_CID_SAMPLING_MODE,
- .type = V4L2_CTRL_TYPE_MENU,
- .flags = V4L2_CTRL_FLAG_INACTIVE,
- .name = "Sampling Mode",
- .qmenu = ctrl_sampling_mode_qmenu_strings,
- };
- static const struct v4l2_ctrl_config ctrl_sampling_rate = {
- .ops = &msi3101_ctrl_ops,
- .id = MSI3101_CID_SAMPLING_RATE,
- .type = V4L2_CTRL_TYPE_INTEGER64,
- .name = "Sampling Rate",
- .min = 500000,
- .max = 12000000,
- .def = 2048000,
- .step = 1,
- };
- static const struct v4l2_ctrl_config ctrl_sampling_resolution = {
- .ops = &msi3101_ctrl_ops,
- .id = MSI3101_CID_SAMPLING_RESOLUTION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .flags = V4L2_CTRL_FLAG_INACTIVE,
- .name = "Sampling Resolution",
- .min = 10,
- .max = 10,
- .def = 10,
- .step = 1,
- };
- static const struct v4l2_ctrl_config ctrl_tuner_rf = {
- .ops = &msi3101_ctrl_ops,
- .id = MSI3101_CID_TUNER_RF,
- .type = V4L2_CTRL_TYPE_INTEGER64,
- .name = "Tuner RF",
- .min = 40000000,
- .max = 2000000000,
- .def = 100000000,
- .step = 1,
- };
static const struct v4l2_ctrl_config ctrl_tuner_bw = {
.ops = &msi3101_ctrl_ops,
.id = MSI3101_CID_TUNER_BW,
.type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Tuner BW",
+ .name = "Tuner Bandwidth",
.min = 200000,
.max = 8000000,
.def = 600000,
.step = 1,
};
- static const struct v4l2_ctrl_config ctrl_tuner_if = {
- .ops = &msi3101_ctrl_ops,
- .id = MSI3101_CID_TUNER_IF,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .flags = V4L2_CTRL_FLAG_INACTIVE,
- .name = "Tuner IF",
- .min = 0,
- .max = 2048000,
- .def = 0,
- .step = 1,
- };
static const struct v4l2_ctrl_config ctrl_tuner_gain = {
.ops = &msi3101_ctrl_ops,
.id = MSI3101_CID_TUNER_GAIN,
@@ -2036,7 +1937,7 @@ static int msi3101_probe(struct usb_interface *intf,
.name = "Tuner Gain",
.min = 0,
.max = 102,
- .def = 0,
+ .def = 50,
.step = 1,
};
@@ -2062,7 +1963,7 @@ static int msi3101_probe(struct usb_interface *intf,
s->vb_queue.mem_ops = &vb2_vmalloc_memops;
s->vb_queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
ret = vb2_queue_init(&s->vb_queue);
- if (ret < 0) {
+ if (ret) {
dev_err(&s->udev->dev, "Could not initialize vb2 queue\n");
goto err_free_mem;
}
@@ -2075,13 +1976,8 @@ static int msi3101_probe(struct usb_interface *intf,
video_set_drvdata(&s->vdev, s);
/* Register controls */
- v4l2_ctrl_handler_init(&s->ctrl_handler, 7);
- v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_mode, NULL);
- s->ctrl_sampling_rate = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_rate, NULL);
- v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_sampling_resolution, NULL);
- s->ctrl_tuner_rf = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_rf, NULL);
+ v4l2_ctrl_handler_init(&s->ctrl_handler, 2);
s->ctrl_tuner_bw = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_bw, NULL);
- s->ctrl_tuner_if = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_if, NULL);
s->ctrl_tuner_gain = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_gain, NULL);
if (s->ctrl_handler.error) {
ret = s->ctrl_handler.error;
@@ -2103,7 +1999,7 @@ static int msi3101_probe(struct usb_interface *intf,
s->vdev.lock = &s->v4l2_lock;
ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
- if (ret < 0) {
+ if (ret) {
dev_err(&s->udev->dev,
"Failed to register as video device (%d)\n",
ret);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 40/52] v4l: disable lockdep on vb2_fop_mmap()
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (38 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 39/52] msi3101: tons of small changes Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 41/52] rtl2832_sdr: return NULL on rtl2832_sdr_attach failure Antti Palosaari
` (11 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Avoid that lockdep warning:
[ INFO: possible circular locking dependency detected ]
3.13.0-rc1+ #77 Tainted: G C O
-------------------------------------------------------
video_source:sr/32072 is trying to acquire lock:
(&dev->mutex#2){+.+.+.}, at: [<ffffffffa073fde3>] vb2_fop_mmap+0x33/0x90 [videobuf2_core]
but task is already holding lock:
(&mm->mmap_sem){++++++}, at: [<ffffffff8117825f>] vm_mmap_pgoff+0x6f/0xc0
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&mm->mmap_sem);
lock(&dev->mutex#2);
lock(&mm->mmap_sem);
lock(&dev->mutex#2);
*** DEADLOCK ***
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/v4l2-core/videobuf2-core.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index 5a5fb7f..48e7432 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2686,12 +2686,24 @@ int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
struct video_device *vdev = video_devdata(file);
struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock;
int err;
+ /*
+ * FIXME: Ugly hack. Disable possible lockdep as it detects possible
+ * deadlock. "INFO: possible circular locking dependency detected"
+ */
+ lockdep_off();
- if (lock && mutex_lock_interruptible(lock))
+ if (lock && mutex_lock_interruptible(lock)) {
+ lockdep_on();
return -ERESTARTSYS;
+ }
+
err = vb2_mmap(vdev->queue, vma);
+
if (lock)
mutex_unlock(lock);
+
+ lockdep_on();
+
return err;
}
EXPORT_SYMBOL_GPL(vb2_fop_mmap);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 41/52] rtl2832_sdr: return NULL on rtl2832_sdr_attach failure
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (39 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 40/52] v4l: disable lockdep on vb2_fop_mmap() Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 42/52] rtl2832_sdr: calculate bandwidth if not set by user Antti Palosaari
` (10 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
dvb_attach() expects NULL on attach failure.
Do some style changes also while we are here.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 50 ++++++++++++------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index a26125c..1cc7bf7 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -1250,31 +1250,31 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
struct rtl2832_sdr_state *s;
struct dvb_usb_device *d = i2c_get_adapdata(i2c);
static const struct v4l2_ctrl_config ctrl_tuner_bw = {
- .ops = &rtl2832_sdr_ctrl_ops,
- .id = RTL2832_SDR_CID_TUNER_BW,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Tuner BW",
- .min = 200000,
- .max = 8000000,
+ .ops = &rtl2832_sdr_ctrl_ops,
+ .id = RTL2832_SDR_CID_TUNER_BW,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Tuner BW",
+ .min = 200000,
+ .max = 8000000,
.def = 600000,
- .step = 1,
+ .step = 1,
};
static const struct v4l2_ctrl_config ctrl_tuner_gain = {
- .ops = &rtl2832_sdr_ctrl_ops,
- .id = RTL2832_SDR_CID_TUNER_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Tuner Gain",
- .min = 0,
- .max = 102,
+ .ops = &rtl2832_sdr_ctrl_ops,
+ .id = RTL2832_SDR_CID_TUNER_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Tuner Gain",
+ .min = 0,
+ .max = 102,
.def = 0,
- .step = 1,
+ .step = 1,
};
s = kzalloc(sizeof(struct rtl2832_sdr_state), GFP_KERNEL);
if (s == NULL) {
dev_err(&d->udev->dev,
"Could not allocate memory for rtl2832_sdr_state\n");
- return ERR_PTR(-ENOMEM);
+ return NULL;
}
/* setup the state */
@@ -1298,18 +1298,11 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->vb_queue.mem_ops = &vb2_vmalloc_memops;
s->vb_queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
ret = vb2_queue_init(&s->vb_queue);
- if (ret < 0) {
+ if (ret) {
dev_err(&s->udev->dev, "Could not initialize vb2 queue\n");
goto err_free_mem;
}
- /* Init video_device structure */
- s->vdev = rtl2832_sdr_template;
- s->vdev.queue = &s->vb_queue;
- s->vdev.queue->lock = &s->vb_queue_lock;
- set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
- video_set_drvdata(&s->vdev, s);
-
/* Register controls */
v4l2_ctrl_handler_init(&s->ctrl_handler, 2);
s->ctrl_tuner_bw = v4l2_ctrl_new_custom(&s->ctrl_handler, &ctrl_tuner_bw, NULL);
@@ -1320,6 +1313,13 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
goto err_free_controls;
}
+ /* Init video_device structure */
+ s->vdev = rtl2832_sdr_template;
+ s->vdev.queue = &s->vb_queue;
+ s->vdev.queue->lock = &s->vb_queue_lock;
+ set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev.flags);
+ video_set_drvdata(&s->vdev, s);
+
/* Register the v4l2_device structure */
s->v4l2_dev.release = rtl2832_sdr_video_release;
ret = v4l2_device_register(&s->udev->dev, &s->v4l2_dev);
@@ -1335,7 +1335,7 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->vdev.vfl_dir = VFL_DIR_RX;
ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1);
- if (ret < 0) {
+ if (ret) {
dev_err(&s->udev->dev,
"Failed to register as video device (%d)\n",
ret);
@@ -1357,7 +1357,7 @@ err_free_controls:
v4l2_ctrl_handler_free(&s->ctrl_handler);
err_free_mem:
kfree(s);
- return ERR_PTR(ret);
+ return NULL;
}
EXPORT_SYMBOL(rtl2832_sdr_attach);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 42/52] rtl2832_sdr: calculate bandwidth if not set by user
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (40 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 41/52] rtl2832_sdr: return NULL on rtl2832_sdr_attach failure Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 43/52] rtl2832_sdr: clamp ADC frequency to valid range always Antti Palosaari
` (9 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Calculate bandwidth from sampling rate if it is not set by user.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 1cc7bf7..2c9b703 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -881,6 +881,10 @@ static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
if (fe->ops.tuner_ops.init)
fe->ops.tuner_ops.init(fe);
+ /* user has not requested bandwidth so calculate automatically */
+ if (bandwidth == 0)
+ bandwidth = s->f_adc;
+
c->bandwidth_hz = bandwidth;
c->frequency = f_rf;
@@ -1254,9 +1258,9 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
.id = RTL2832_SDR_CID_TUNER_BW,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Tuner BW",
- .min = 200000,
- .max = 8000000,
- .def = 600000,
+ .min = 0,
+ .max = INT_MAX,
+ .def = 0,
.step = 1,
};
static const struct v4l2_ctrl_config ctrl_tuner_gain = {
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 43/52] rtl2832_sdr: clamp ADC frequency to valid range always
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (41 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 42/52] rtl2832_sdr: calculate bandwidth if not set by user Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 44/52] rtl2832_sdr: improve ADC device programming logic Antti Palosaari
` (8 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
V4L2 tuner API says incorrect value should be round to nearest
legal value. Implement it for ADC frequency setting.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 2c9b703..ddacfd2 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -666,7 +666,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
u64 u64tmp;
u32 u32tmp;
- dev_dbg(&s->udev->dev, "%s:\n", __func__);
+ dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
if (!test_bit(POWER_ON, &s->flags))
return 0;
@@ -1064,12 +1064,26 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
struct rtl2832_sdr_state *s = video_drvdata(file);
- int ret;
+ int ret, band;
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
__func__, f->tuner, f->type, f->frequency);
- if (f->tuner == 0) {
- s->f_adc = f->frequency;
+ /* ADC band midpoints */
+ #define BAND_ADC_0 ((bands_adc[0].rangehigh + bands_adc[1].rangelow) / 2)
+ #define BAND_ADC_1 ((bands_adc[1].rangehigh + bands_adc[2].rangelow) / 2)
+
+ if (f->tuner == 0 && f->type == V4L2_TUNER_ADC) {
+ if (f->frequency < BAND_ADC_0)
+ band = 0;
+ else if (f->frequency < BAND_ADC_1)
+ band = 1;
+ else
+ band = 2;
+
+ s->f_adc = clamp_t(unsigned int, f->frequency,
+ bands_adc[band].rangelow,
+ bands_adc[band].rangehigh);
+
dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
__func__, s->f_adc);
ret = rtl2832_sdr_set_adc(s);
@@ -1287,6 +1301,8 @@ struct dvb_frontend *rtl2832_sdr_attach(struct dvb_frontend *fe,
s->udev = d->udev;
s->i2c = i2c;
s->cfg = cfg;
+ s->f_adc = bands_adc[0].rangelow;
+ s->pixelformat = V4L2_PIX_FMT_SDR_U8;
mutex_init(&s->v4l2_lock);
mutex_init(&s->vb_queue_lock);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 44/52] rtl2832_sdr: improve ADC device programming logic
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (42 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 43/52] rtl2832_sdr: clamp ADC frequency to valid range always Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 45/52] rtl2832_sdr: remove FMT buffer type checks Antti Palosaari
` (7 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Refactor and implement properly RTL2832 programming logic. Implement
some things more correctly. Restore some critical registers to POR
default state, making it possible to use it as a DVB-T device without
resetting or replugging.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 283 ++++++++++++++---------
1 file changed, 177 insertions(+), 106 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index ddacfd2..0bc417d 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -187,7 +187,6 @@ static int rtl2832_sdr_wr(struct rtl2832_sdr_state *s, u8 reg, const u8 *val,
return ret;
}
-#if 0
/* read multiple hardware registers */
static int rtl2832_sdr_rd(struct rtl2832_sdr_state *s, u8 reg, u8 *val, int len)
{
@@ -217,7 +216,6 @@ static int rtl2832_sdr_rd(struct rtl2832_sdr_state *s, u8 reg, u8 *val, int len)
}
return ret;
}
-#endif
/* write multiple registers */
static int rtl2832_sdr_wr_regs(struct rtl2832_sdr_state *s, u16 reg,
@@ -239,7 +237,6 @@ static int rtl2832_sdr_wr_regs(struct rtl2832_sdr_state *s, u16 reg,
return rtl2832_sdr_wr(s, reg2, val, len);
}
-#if 0
/* read multiple registers */
static int rtl2832_sdr_rd_regs(struct rtl2832_sdr_state *s, u16 reg, u8 *val,
int len)
@@ -259,7 +256,6 @@ static int rtl2832_sdr_rd_regs(struct rtl2832_sdr_state *s, u16 reg, u8 *val,
return rtl2832_sdr_rd(s, reg2, val, len);
}
-#endif
/* write single register */
static int rtl2832_sdr_wr_reg(struct rtl2832_sdr_state *s, u16 reg, u8 val)
@@ -273,6 +269,7 @@ static int rtl2832_sdr_rd_reg(struct rtl2832_sdr_state *s, u16 reg, u8 *val)
{
return rtl2832_sdr_rd_regs(s, reg, val, 1);
}
+#endif
/* write single register with mask */
static int rtl2832_sdr_wr_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
@@ -295,6 +292,7 @@ static int rtl2832_sdr_wr_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
return rtl2832_sdr_wr_regs(s, reg, &val, 1);
}
+#if 0
/* read single register with mask */
static int rtl2832_sdr_rd_reg_mask(struct rtl2832_sdr_state *s, u16 reg,
u8 *val, u8 mask)
@@ -662,10 +660,9 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
struct dvb_frontend *fe = s->fe;
int ret;
unsigned int f_sr, f_if;
- u8 buf[4], tmp;
+ u8 buf[4], u8tmp1, u8tmp2;
u64 u64tmp;
u32 u32tmp;
-
dev_dbg(&s->udev->dev, "%s: f_adc=%u\n", __func__, s->f_adc);
if (!test_bit(POWER_ON, &s->flags))
@@ -677,9 +674,12 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
f_sr = s->f_adc;
ret = rtl2832_sdr_wr_regs(s, 0x13e, "\x00\x00", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x115, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\x00", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x118, "\x00", 1);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_wr_regs(s, 0x115, "\x00\x00\x00\x00", 4);
+ if (ret)
+ goto err;
/* get IF from tuner */
if (fe->ops.tuner_ops.get_if_frequency)
@@ -708,13 +708,25 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
if (ret)
goto err;
- /* program BB / IF mode */
- if (f_if)
- tmp = 0x00;
- else
- tmp = 0x01;
+ /* BB / IF mode */
+ /* POR: 0x1b1=0x1f, 0x008=0x0d, 0x006=0x80 */
+ if (f_if) {
+ u8tmp1 = 0x1a; /* disable Zero-IF */
+ u8tmp2 = 0x8d; /* enable ADC I */
+ } else {
+ u8tmp1 = 0x1b; /* enable Zero-IF, DC, IQ */
+ u8tmp2 = 0xcd; /* enable ADC I, ADC Q */
+ }
- ret = rtl2832_sdr_wr_reg(s, 0x1b1, tmp);
+ ret = rtl2832_sdr_wr_reg(s, 0x1b1, u8tmp1);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_wr_reg(s, 0x008, u8tmp2);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_wr_reg(s, 0x006, 0x80);
if (ret)
goto err;
@@ -729,101 +741,59 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
if (ret)
goto err;
- ret = rtl2832_sdr_wr_regs(s, 0x11c, "\xca", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x11d, "\xdc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x11e, "\xd7", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x11f, "\xd8", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x120, "\xe0", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x121, "\xf2", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x122, "\x0e", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x123, "\x35", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x124, "\x06", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x125, "\x50", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x126, "\x9c", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x127, "\x0d", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x128, "\x71", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x129, "\x11", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x12a, "\x14", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x12b, "\x71", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x12c, "\x74", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x12d, "\x19", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x12e, "\x41", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x12f, "\xa5", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x017, "\x11", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x018, "\x10", 1);
+ /* low-pass filter */
+ ret = rtl2832_sdr_wr_regs(s, 0x11c,
+ "\xca\xdc\xd7\xd8\xe0\xf2\x0e\x35\x06\x50\x9c\x0d\x71\x11\x14\x71\x74\x19\x41\xa5",
+ 20);
+ if (ret)
+ goto err;
+
+ /* mode */
+ ret = rtl2832_sdr_wr_regs(s, 0x017, "\x11\x10", 2);
+ if (ret)
+ goto err;
+
ret = rtl2832_sdr_wr_regs(s, 0x019, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x01f, "\xff", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x01e, "\x01", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x01d, "\x06", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x01c, "\x0d", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x01b, "\x16", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x01a, "\x1b", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x192, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x193, "\xf0", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x194, "\x0f", 1);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_wr_regs(s, 0x01a, "\x1b\x16\x0d\x06\x01\xff", 6);
+ if (ret)
+ goto err;
+
+ /* FSM */
+ ret = rtl2832_sdr_wr_regs(s, 0x192, "\x00\xf0\x0f", 3);
+ if (ret)
+ goto err;
+
+ /* PID filter */
ret = rtl2832_sdr_wr_regs(s, 0x061, "\x60", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x006, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
+ if (ret)
+ goto err;
- if (s->cfg->tuner == RTL2832_TUNER_R820T) {
- ret = rtl2832_sdr_wr_regs(s, 0x115, "\x01", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x103, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x24", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x14", 1);
- } else if (s->cfg->tuner == RTL2832_TUNER_FC0012 ||
- s->cfg->tuner == RTL2832_TUNER_FC0013) {
- ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x2c", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x16", 1);
- } else {
+ /* used RF tuner based settings */
+ switch (s->cfg->tuner) {
+ case RTL2832_TUNER_E4000:
+ ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x30", 1);
ret = rtl2832_sdr_wr_regs(s, 0x104, "\xd0", 1);
ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x18", 1);
- }
-
- ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
-
- if (s->cfg->tuner == RTL2832_TUNER_R820T) {
- ret = rtl2832_sdr_wr_regs(s, 0x011, "\xf4", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x019, "\x21", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x116, "\x00\x00", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x118, "\x00", 1);
- } else if (s->cfg->tuner == RTL2832_TUNER_FC0012 ||
- s->cfg->tuner == RTL2832_TUNER_FC0013) {
- ret = rtl2832_sdr_wr_regs(s, 0x011, "\xe9\xbf", 2);
- ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x11", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xef", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x008, "\xcd", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
- } else {
+ ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
ret = rtl2832_sdr_wr_regs(s, 0x011, "\xd4", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
@@ -838,16 +808,115 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x87", 1);
ret = rtl2832_sdr_wr_regs(s, 0x00d, "\x85", 1);
ret = rtl2832_sdr_wr_regs(s, 0x013, "\x02", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x008, "\xcd", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x10c, "\x00", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x14", 1);
- ret = rtl2832_sdr_wr_regs(s, 0x101, "\x10", 1);
+ break;
+ case RTL2832_TUNER_FC0012:
+ case RTL2832_TUNER_FC0013:
+ ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x103, "\x5a", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x2c", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x16", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x011, "\xe9\xbf", 2);
+ ret = rtl2832_sdr_wr_regs(s, 0x1e5, "\xf0", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d9, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1db, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1dd, "\x11", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1de, "\xef", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d8, "\x0c", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1e6, "\x02", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1d7, "\x09", 1);
+ break;
+ case RTL2832_TUNER_R820T:
+ ret = rtl2832_sdr_wr_regs(s, 0x112, "\x5a", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x102, "\x40", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x115, "\x01", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x103, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c7, "\x24", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x104, "\xcc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x105, "\xbe", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c8, "\x14", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x106, "\x35", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1c9, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1ca, "\x21", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1cb, "\x00", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x107, "\x40", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1cd, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x1ce, "\x10", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x108, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x109, "\x7f", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10a, "\x80", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x10b, "\x7f", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x00e, "\xfc", 1);
+ ret = rtl2832_sdr_wr_regs(s, 0x011, "\xf4", 1);
+ break;
+ default:
+ dev_notice(&s->udev->dev, "Unsupported tuner\n");
}
+ /* software reset */
+ ret = rtl2832_sdr_wr_reg_mask(s, 0x101, 0x04, 0x04);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_wr_reg_mask(s, 0x101, 0x00, 0x04);
+ if (ret)
+ goto err;
err:
return ret;
};
+static void rtl2832_sdr_unset_adc(struct rtl2832_sdr_state *s)
+{
+ int ret;
+
+ dev_dbg(&s->udev->dev, "%s:\n", __func__);
+
+ /* PID filter */
+ ret = rtl2832_sdr_wr_regs(s, 0x061, "\xe0", 1);
+ if (ret)
+ goto err;
+
+ /* mode */
+ ret = rtl2832_sdr_wr_regs(s, 0x019, "\x20", 1);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_wr_regs(s, 0x017, "\x11\x10", 2);
+ if (ret)
+ goto err;
+
+ /* FSM */
+ ret = rtl2832_sdr_wr_regs(s, 0x192, "\x00\x0f\xff", 3);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_wr_regs(s, 0x13e, "\x40\x00", 2);
+ if (ret)
+ goto err;
+
+ ret = rtl2832_sdr_wr_regs(s, 0x115, "\x06\x3f\xce\xcc", 4);
+ if (ret)
+ goto err;
+err:
+ return;
+};
+
static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
{
struct dvb_frontend *fe = s->fe;
@@ -887,6 +956,7 @@ static int rtl2832_sdr_set_tuner(struct rtl2832_sdr_state *s)
c->bandwidth_hz = bandwidth;
c->frequency = f_rf;
+ c->delivery_system = SYS_DVBT;
if (fe->ops.tuner_ops.set_params)
fe->ops.tuner_ops.set_params(fe);
@@ -961,6 +1031,7 @@ static int rtl2832_sdr_stop_streaming(struct vb2_queue *vq)
rtl2832_sdr_free_urbs(s);
rtl2832_sdr_free_stream_bufs(s);
rtl2832_sdr_cleanup_queued_bufs(s);
+ rtl2832_sdr_unset_adc(s);
rtl2832_sdr_unset_tuner(s);
clear_bit(POWER_ON, &s->flags);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 45/52] rtl2832_sdr: remove FMT buffer type checks
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (43 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 44/52] rtl2832_sdr: improve ADC device programming logic Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 46/52] rtl2832_sdr: switch FM to DAB mode Antti Palosaari
` (6 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Remove unneeded buffer type checks from FMT IOTCL handlers. Checks
are already done by V4L core.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index 0bc417d..d101409 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -1191,9 +1191,6 @@ static int rtl2832_sdr_g_fmt_sdr_cap(struct file *file, void *priv,
struct rtl2832_sdr_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
- if (f->type != V4L2_BUF_TYPE_SDR_CAPTURE)
- return -EINVAL;
-
f->fmt.sdr.pixelformat = s->pixelformat;
return 0;
@@ -1208,9 +1205,6 @@ static int rtl2832_sdr_s_fmt_sdr_cap(struct file *file, void *priv,
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
- if (f->type != V4L2_BUF_TYPE_SDR_CAPTURE)
- return -EINVAL;
-
if (vb2_is_busy(q))
return -EBUSY;
@@ -1235,9 +1229,6 @@ static int rtl2832_sdr_try_fmt_sdr_cap(struct file *file, void *priv,
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
- if (f->type != V4L2_BUF_TYPE_SDR_CAPTURE)
- return -EINVAL;
-
for (i = 0; i < NUM_FORMATS; i++) {
if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
return 0;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 46/52] rtl2832_sdr: switch FM to DAB mode
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (44 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 45/52] rtl2832_sdr: remove FMT buffer type checks Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 47/52] msi3101: calculate tuner filters Antti Palosaari
` (5 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
It seems to perform a little bit better on weak signals when mode
is DAB. It looks like weak signals are faded out by squelch(?) in
FM mode as voice was silenced under one sec when tuned to weak FM
station.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
index d101409..fccb16f 100644
--- a/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
+++ b/drivers/staging/media/rtl2832u_sdr/rtl2832_sdr.c
@@ -748,12 +748,12 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_state *s)
if (ret)
goto err;
- /* mode */
ret = rtl2832_sdr_wr_regs(s, 0x017, "\x11\x10", 2);
if (ret)
goto err;
- ret = rtl2832_sdr_wr_regs(s, 0x019, "\x21", 1);
+ /* mode */
+ ret = rtl2832_sdr_wr_regs(s, 0x019, "\x05", 1);
if (ret)
goto err;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 47/52] msi3101: calculate tuner filters
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (45 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 46/52] rtl2832_sdr: switch FM to DAB mode Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 48/52] msi3101: remove FMT buffer type checks Antti Palosaari
` (4 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Calculate tuner filters from sampling rate and use it if not
defined manually.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index cb66f81..02960c7 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -1416,7 +1416,7 @@ static int msi3101_set_tuner(struct msi3101_state *s)
{5000000, 0x04}, /* 5 MHz */
{6000000, 0x05}, /* 6 MHz */
{7000000, 0x06}, /* 7 MHz */
- {8000000, 0x07}, /* 8 MHz */
+ { ~0U, 0x07}, /* 8 MHz */
};
unsigned int f_rf = s->f_tuner;
@@ -1473,8 +1473,12 @@ static int msi3101_set_tuner(struct msi3101_state *s)
if (i == ARRAY_SIZE(if_freq_lut))
goto err;
+ /* user has not requested bandwidth, set some reasonable */
+ if (bandwidth == 0)
+ bandwidth = s->f_adc;
+
for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {
- if (bandwidth == bandwidth_lut[i].freq) {
+ if (bandwidth <= bandwidth_lut[i].freq) {
bandwidth = bandwidth_lut[i].val;
break;
}
@@ -1483,6 +1487,9 @@ static int msi3101_set_tuner(struct msi3101_state *s)
if (i == ARRAY_SIZE(bandwidth_lut))
goto err;
+ dev_dbg(&s->udev->dev, "%s: bandwidth selected=%d\n",
+ __func__, bandwidth_lut[i].freq);
+
#define F_OUT_STEP 1
#define R_REF 4
f_vco = (f_rf + f_if + f_if1) * lo_div;
@@ -1925,9 +1932,9 @@ static int msi3101_probe(struct usb_interface *intf,
.id = MSI3101_CID_TUNER_BW,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Tuner Bandwidth",
- .min = 200000,
+ .min = 0,
.max = 8000000,
- .def = 600000,
+ .def = 0,
.step = 1,
};
static const struct v4l2_ctrl_config ctrl_tuner_gain = {
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 48/52] msi3101: remove FMT buffer type checks
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (46 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 47/52] msi3101: calculate tuner filters Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 49/52] msi3101: improve ADC config stream format selection Antti Palosaari
` (3 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Remove unneeded buffer type checks from FMT IOTCL handlers. Checks
are already done by V4L core.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 02960c7..6b9f0da 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -1679,9 +1679,6 @@ static int msi3101_g_fmt_sdr_cap(struct file *file, void *priv,
struct msi3101_state *s = video_drvdata(file);
dev_dbg(&s->udev->dev, "%s:\n", __func__);
- if (f->type != V4L2_BUF_TYPE_SDR_CAPTURE)
- return -EINVAL;
-
f->fmt.sdr.pixelformat = s->pixelformat;
return 0;
@@ -1696,9 +1693,6 @@ static int msi3101_s_fmt_sdr_cap(struct file *file, void *priv,
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
- if (f->type != V4L2_BUF_TYPE_SDR_CAPTURE)
- return -EINVAL;
-
if (vb2_is_busy(q))
return -EBUSY;
@@ -1723,9 +1717,6 @@ static int msi3101_try_fmt_sdr_cap(struct file *file, void *priv,
dev_dbg(&s->udev->dev, "%s: pixelformat fourcc %4.4s\n", __func__,
(char *)&f->fmt.sdr.pixelformat);
- if (f->type != V4L2_BUF_TYPE_SDR_CAPTURE)
- return -EINVAL;
-
for (i = 0; i < NUM_FORMATS; i++) {
if (formats[i].pixelformat == f->fmt.sdr.pixelformat)
return 0;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 49/52] msi3101: improve ADC config stream format selection
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (47 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 48/52] msi3101: remove FMT buffer type checks Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 50/52] msi3101: clamp ADC and RF to valid range Antti Palosaari
` (2 subsequent siblings)
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Improve ADC config stream format selection. No functional changes.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 37 +++++++++++++----------------
1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 6b9f0da..ba37fce 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -1247,38 +1247,35 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
f_sr = s->f_adc;
/* select stream format */
- if (f_sr < 6000000) {
- s->convert_stream = msi3101_convert_stream_252;
- reg7 = 0x00009407;
- } else if (f_sr < 8000000) {
- s->convert_stream = msi3101_convert_stream_336;
- reg7 = 0x00008507;
- } else if (f_sr < 9000000) {
- s->convert_stream = msi3101_convert_stream_384;
- reg7 = 0x0000a507;
- } else {
- s->convert_stream = msi3101_convert_stream_504;
- reg7 = 0x000c9407;
- }
-
- if (s->pixelformat == V4L2_PIX_FMT_SDR_U8) {
+ switch (s->pixelformat) {
+ case V4L2_PIX_FMT_SDR_U8:
s->convert_stream = msi3101_convert_stream_504_u8;
reg7 = 0x000c9407;
- } else if (s->pixelformat == V4L2_PIX_FMT_SDR_U16LE) {
+ break;
+ case V4L2_PIX_FMT_SDR_U16LE:
s->convert_stream = msi3101_convert_stream_252_u16;
reg7 = 0x00009407;
- } else if (s->pixelformat == V4L2_PIX_FMT_SDR_S8) {
+ break;
+ case V4L2_PIX_FMT_SDR_S8:
s->convert_stream = msi3101_convert_stream_504;
reg7 = 0x000c9407;
- } else if (s->pixelformat == V4L2_PIX_FMT_SDR_MSI2500_384) {
+ break;
+ case V4L2_PIX_FMT_SDR_MSI2500_384:
s->convert_stream = msi3101_convert_stream_384;
reg7 = 0x0000a507;
- } else if (s->pixelformat == V4L2_PIX_FMT_SDR_S12) {
+ break;
+ case V4L2_PIX_FMT_SDR_S12:
s->convert_stream = msi3101_convert_stream_336;
reg7 = 0x00008507;
- } else if (s->pixelformat == V4L2_PIX_FMT_SDR_S14) {
+ break;
+ case V4L2_PIX_FMT_SDR_S14:
s->convert_stream = msi3101_convert_stream_252;
reg7 = 0x00009407;
+ break;
+ default:
+ s->convert_stream = msi3101_convert_stream_504_u8;
+ reg7 = 0x000c9407;
+ break;
}
/*
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 50/52] msi3101: clamp ADC and RF to valid range
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (48 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 49/52] msi3101: improve ADC config stream format selection Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 51/52] msi3101: disable all but u8 and u16le formats Antti Palosaari
2014-01-25 17:10 ` [PATCH 52/52] v4l: add RF tuner gain controls Antti Palosaari
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Clamp both sampling frequency and RF frequency to valid range to
meet V4L2 API spec. It is caller responsibility to check valid ranges
using VIDIOC_ENUM_FREQ_BANDS IOCTL.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index ba37fce..2b812fe 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -1779,17 +1779,26 @@ static int msi3101_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
struct msi3101_state *s = video_drvdata(file);
- int ret;
+ int ret, band;
dev_dbg(&s->udev->dev, "%s: tuner=%d type=%d frequency=%u\n",
__func__, f->tuner, f->type, f->frequency);
if (f->tuner == 0) {
- s->f_adc = f->frequency;
+ s->f_adc = clamp_t(unsigned int, f->frequency,
+ bands_adc[0].rangelow,
+ bands_adc[0].rangehigh);
dev_dbg(&s->udev->dev, "%s: ADC frequency=%u Hz\n",
__func__, s->f_adc);
ret = msi3101_set_usb_adc(s);
} else if (f->tuner == 1) {
- s->f_tuner = f->frequency;
+ #define BAND_RF_0 ((bands_rf[0].rangehigh + bands_rf[1].rangelow) / 2)
+ if (f->frequency < BAND_RF_0)
+ band = 0;
+ else
+ band = 1;
+ s->f_tuner = clamp_t(unsigned int, f->frequency,
+ bands_rf[band].rangelow,
+ bands_rf[band].rangehigh);
dev_dbg(&s->udev->dev, "%s: RF frequency=%u Hz\n",
__func__, f->frequency);
ret = msi3101_set_tuner(s);
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 51/52] msi3101: disable all but u8 and u16le formats
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (49 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 50/52] msi3101: clamp ADC and RF to valid range Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
2014-01-25 17:10 ` [PATCH 52/52] v4l: add RF tuner gain controls Antti Palosaari
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
As for now, better to support only two general stream formats.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/staging/media/msi3101/sdr-msi3101.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 2b812fe..e6b7cba 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -416,6 +416,7 @@ static struct msi3101_format formats[] = {
}, {
.name = "16-bit unsigned little endian",
.pixelformat = V4L2_PIX_FMT_SDR_U16LE,
+#if 0
}, {
.name = "8-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S8,
@@ -428,6 +429,7 @@ static struct msi3101_format formats[] = {
}, {
.name = "14-bit signed",
.pixelformat = V4L2_PIX_FMT_SDR_S14,
+#endif
},
};
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* [PATCH 52/52] v4l: add RF tuner gain controls
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
` (50 preceding siblings ...)
2014-01-25 17:10 ` [PATCH 51/52] msi3101: disable all but u8 and u16le formats Antti Palosaari
@ 2014-01-25 17:10 ` Antti Palosaari
51 siblings, 0 replies; 54+ messages in thread
From: Antti Palosaari @ 2014-01-25 17:10 UTC (permalink / raw)
To: linux-media; +Cc: Antti Palosaari
Modern silicon RF tuners used nowadays has many controllable gain
stages on signal path. Usually, but not always, there is at least
3 gain stages. Also on some cases there could be multiple gain
stages within the ones specified here. However, I think that having
these three controllable gain stages offers enough fine-tuning for
real use cases.
1) LNA gain. That is first gain just after antenna input.
2) Mixer gain. It is located quite middle of the signal path, where
RF signal is down-converted to IF/BB.
3) IF gain. That is last gain in order to adjust output signal level
to optimal level for receiving party (usually demodulator ADC).
Each gain stage could be set rather often both manual or automatic
(AGC) mode. Due to that add separate controls for controlling
operation mode.
Signed-off-by: Antti Palosaari <crope@iki.fi>
---
drivers/media/v4l2-core/v4l2-ctrls.c | 15 +++++++++++++++
include/uapi/linux/v4l2-controls.h | 11 +++++++++++
2 files changed, 26 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 6ff002b..d201f61 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -857,6 +857,14 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_FM_RX_CLASS: return "FM Radio Receiver Controls";
case V4L2_CID_TUNE_DEEMPHASIS: return "De-Emphasis";
case V4L2_CID_RDS_RECEPTION: return "RDS Reception";
+
+ case V4L2_CID_RF_TUNER_CLASS: return "RF Tuner Controls";
+ case V4L2_CID_LNA_GAIN_AUTO: return "LNA Gain, Auto";
+ case V4L2_CID_LNA_GAIN: return "LNA Gain";
+ case V4L2_CID_MIXER_GAIN_AUTO: return "Mixer Gain, Auto";
+ case V4L2_CID_MIXER_GAIN: return "Mixer Gain";
+ case V4L2_CID_IF_GAIN_AUTO: return "IF Gain, Auto";
+ case V4L2_CID_IF_GAIN: return "IF Gain";
default:
return NULL;
}
@@ -906,6 +914,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_WIDE_DYNAMIC_RANGE:
case V4L2_CID_IMAGE_STABILIZATION:
case V4L2_CID_RDS_RECEPTION:
+ case V4L2_CID_LNA_GAIN_AUTO:
+ case V4L2_CID_MIXER_GAIN_AUTO:
+ case V4L2_CID_IF_GAIN_AUTO:
*type = V4L2_CTRL_TYPE_BOOLEAN;
*min = 0;
*max = *step = 1;
@@ -991,6 +1002,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_IMAGE_PROC_CLASS:
case V4L2_CID_DV_CLASS:
case V4L2_CID_FM_RX_CLASS:
+ case V4L2_CID_RF_TUNER_CLASS:
*type = V4L2_CTRL_TYPE_CTRL_CLASS;
/* You can neither read not write these */
*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
@@ -1063,6 +1075,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_PILOT_TONE_FREQUENCY:
case V4L2_CID_TUNE_POWER_LEVEL:
case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+ case V4L2_CID_LNA_GAIN:
+ case V4L2_CID_MIXER_GAIN:
+ case V4L2_CID_IF_GAIN:
*flags |= V4L2_CTRL_FLAG_SLIDER;
break;
case V4L2_CID_PAN_RELATIVE:
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 2cbe605..076fa34 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -60,6 +60,7 @@
#define V4L2_CTRL_CLASS_IMAGE_PROC 0x009f0000 /* Image processing controls */
#define V4L2_CTRL_CLASS_DV 0x00a00000 /* Digital Video controls */
#define V4L2_CTRL_CLASS_FM_RX 0x00a10000 /* FM Receiver controls */
+#define V4L2_CTRL_CLASS_RF_TUNER 0x00a20000 /* RF tuner controls */
/* User-class control IDs */
@@ -895,4 +896,14 @@ enum v4l2_deemphasis {
#define V4L2_CID_RDS_RECEPTION (V4L2_CID_FM_RX_CLASS_BASE + 2)
+#define V4L2_CID_RF_TUNER_CLASS_BASE (V4L2_CTRL_CLASS_RF_TUNER | 0x900)
+#define V4L2_CID_RF_TUNER_CLASS (V4L2_CTRL_CLASS_RF_TUNER | 1)
+
+#define V4L2_CID_LNA_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 1)
+#define V4L2_CID_LNA_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 2)
+#define V4L2_CID_MIXER_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 3)
+#define V4L2_CID_MIXER_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 4)
+#define V4L2_CID_IF_GAIN_AUTO (V4L2_CID_RF_TUNER_CLASS_BASE + 5)
+#define V4L2_CID_IF_GAIN (V4L2_CID_RF_TUNER_CLASS_BASE + 6)
+
#endif
--
1.8.5.3
^ permalink raw reply related [flat|nested] 54+ messages in thread
* Re: [PATCH 23/52] v4l: add new tuner types for SDR
2014-01-25 17:10 ` [PATCH 23/52] v4l: add new tuner types for SDR Antti Palosaari
@ 2014-02-07 14:03 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 54+ messages in thread
From: Mauro Carvalho Chehab @ 2014-02-07 14:03 UTC (permalink / raw)
To: Antti Palosaari; +Cc: linux-media, Hans Verkuil
Em Sat, 25 Jan 2014 19:10:17 +0200
Antti Palosaari <crope@iki.fi> escreveu:
> Define tuner types V4L2_TUNER_ADC and V4L2_TUNER_RF for SDR usage.
>
> ADC is used for setting sampling rate (sampling frequency) to SDR
> device.
>
> Another tuner type, named as V4L2_TUNER_RF, is possible RF tuner.
> Is is used to down-convert RF frequency to range ADC could sample.
> Having RF tuner is optional, whilst in practice it is almost always
> there.
>
> Also add checks to VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY and
> VIDIOC_ENUM_FREQ_BANDS only allow these two tuner types when device
> type is SDR (VFL_TYPE_SDR). For VIDIOC_G_FREQUENCY we do not check
> tuner type, instead override type with V4L2_TUNER_ADC in every
> case (requested by Hans in order to keep functionality in line with
> existing tuners and existing API does not specify it).
>
> Prohibit VIDIOC_S_HW_FREQ_SEEK explicitly when device type is SDR,
> as device cannot do hardware seek without a hardware demodulator.
>
> Cc: Hans Verkuil <hverkuil@xs4all.nl>
> Signed-off-by: Antti Palosaari <crope@iki.fi>
> Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
> drivers/media/v4l2-core/v4l2-ioctl.c | 39 ++++++++++++++++++++++++++----------
> include/uapi/linux/videodev2.h | 2 ++
> 2 files changed, 30 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> index 707aef7..15ab349 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1291,8 +1291,11 @@ static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
> struct video_device *vfd = video_devdata(file);
> struct v4l2_frequency *p = arg;
>
> - p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
> - V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
> + if (vfd->vfl_type == VFL_TYPE_SDR)
> + p->type = V4L2_TUNER_ADC;
> + else
> + p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
> + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
> return ops->vidioc_g_frequency(file, fh, p);
> }
>
> @@ -1303,10 +1306,15 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
> const struct v4l2_frequency *p = arg;
> enum v4l2_tuner_type type;
>
> - type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
> - V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
> - if (p->type != type)
> - return -EINVAL;
> + if (vfd->vfl_type == VFL_TYPE_SDR) {
> + if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
> + return -EINVAL;
> + } else {
> + type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
> + V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
> + if (type != p->type)
> + return -EINVAL;
> + }
> return ops->vidioc_s_frequency(file, fh, p);
> }
>
> @@ -1386,6 +1394,10 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
> struct v4l2_hw_freq_seek *p = arg;
> enum v4l2_tuner_type type;
>
> + /* s_hw_freq_seek is not supported for SDR for now */
> + if (vfd->vfl_type == VFL_TYPE_SDR)
> + return -EINVAL;
A minor issue: return code here is IMHO wrong. It should be -ENOTTY.
It makes sense to add a printk_once() to warn about it, as, if we ever
need it for SDR, people could lose hours debugging why this is not work
until finally discovering that the Kernel is blocking such call.
In any case, I'll apply this patch. Please send a fix on a next series.
> +
> type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
> V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
> if (p->type != type)
> @@ -1885,11 +1897,16 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
> 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 (vfd->vfl_type == VFL_TYPE_SDR) {
> + if (p->type != V4L2_TUNER_ADC && p->type != V4L2_TUNER_RF)
> + return -EINVAL;
> + type = p->type;
> + } else {
> + 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 (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 6ae7bbe..9dc79d1 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -159,6 +159,8 @@ enum v4l2_tuner_type {
> V4L2_TUNER_RADIO = 1,
> V4L2_TUNER_ANALOG_TV = 2,
> V4L2_TUNER_DIGITAL_TV = 3,
> + V4L2_TUNER_ADC = 4,
> + V4L2_TUNER_RF = 5,
> };
>
> enum v4l2_memory {
--
Cheers,
Mauro
^ permalink raw reply [flat|nested] 54+ messages in thread
end of thread, other threads:[~2014-02-07 14:03 UTC | newest]
Thread overview: 54+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-25 17:09 [PATCH 00/52] SDR devel tree Antti Palosaari
2014-01-25 17:09 ` [PATCH 01/52] rtl2832_sdr: Realtek RTL2832 SDR driver module Antti Palosaari
2014-01-25 17:09 ` [PATCH 02/52] rtl28xxu: attach SDR extension module Antti Palosaari
2014-01-25 17:09 ` [PATCH 03/52] rtl2832_sdr: use config struct from rtl2832 module Antti Palosaari
2014-01-25 17:09 ` [PATCH 04/52] rtl2832_sdr: initial support for R820T tuner Antti Palosaari
2014-01-25 17:09 ` [PATCH 05/52] rtl2832_sdr: use get_if_frequency() Antti Palosaari
2014-01-25 17:10 ` [PATCH 06/52] rtl2832_sdr: implement sampling rate Antti Palosaari
2014-01-25 17:10 ` [PATCH 07/52] rtl2832_sdr: initial support for FC0012 tuner Antti Palosaari
2014-01-25 17:10 ` [PATCH 08/52] rtl2832_sdr: initial support for FC0013 tuner Antti Palosaari
2014-01-25 17:10 ` [PATCH 09/52] rtl28xxu: constify demod config structs Antti Palosaari
2014-01-25 17:10 ` [PATCH 10/52] rtl2832: remove unused if_dvbt config parameter Antti Palosaari
2014-01-25 17:10 ` [PATCH 11/52] rtl2832: style changes and minor cleanup Antti Palosaari
2014-01-25 17:10 ` [PATCH 12/52] rtl2832_sdr: pixel format for SDR Antti Palosaari
2014-01-25 17:10 ` [PATCH 13/52] rtl2832_sdr: implement FMT IOCTLs Antti Palosaari
2014-01-25 17:10 ` [PATCH 14/52] msi3101: add signed 8-bit pixel format for SDR Antti Palosaari
2014-01-25 17:10 ` [PATCH 15/52] msi3101: implement FMT IOCTLs Antti Palosaari
2014-01-25 17:10 ` [PATCH 16/52] msi3101: move format 384 conversion to libv4lconvert Antti Palosaari
2014-01-25 17:10 ` [PATCH 17/52] msi3101: move format 336 " Antti Palosaari
2014-01-25 17:10 ` [PATCH 18/52] msi3101: move format 252 " Antti Palosaari
2014-01-25 17:10 ` [PATCH 19/52] rtl28xxu: add module parameter to disable IR Antti Palosaari
2014-01-25 17:10 ` [PATCH 20/52] rtl2832_sdr: increase USB buffers Antti Palosaari
2014-01-25 17:10 ` [PATCH 21/52] DocBook: fix wait.c location Antti Palosaari
2014-01-25 17:10 ` [PATCH 22/52] v4l: add device type for Software Defined Radio Antti Palosaari
2014-01-25 17:10 ` [PATCH 23/52] v4l: add new tuner types for SDR Antti Palosaari
2014-02-07 14:03 ` Mauro Carvalho Chehab
2014-01-25 17:10 ` [PATCH 24/52] v4l: 1 Hz resolution flag for tuners Antti Palosaari
2014-01-25 17:10 ` [PATCH 25/52] v4l: add stream format for SDR receiver Antti Palosaari
2014-01-25 17:10 ` [PATCH 26/52] v4l: define own IOCTL ops for SDR FMT Antti Palosaari
2014-01-25 17:10 ` [PATCH 27/52] v4l: enable some IOCTLs for SDR receiver Antti Palosaari
2014-01-25 17:10 ` [PATCH 28/52] v4l: add device capability flag " Antti Palosaari
2014-01-25 17:10 ` [PATCH 29/52] v4l: do not allow modulator ioctls for non-radio devices Antti Palosaari
2014-01-25 17:10 ` [PATCH 30/52] DocBook: document 1 Hz flag Antti Palosaari
2014-01-25 17:10 ` [PATCH 31/52] DocBook: Software Defined Radio Interface Antti Palosaari
2014-01-25 17:10 ` [PATCH 32/52] DocBook: mark SDR API as Experimental Antti Palosaari
2014-01-25 17:10 ` [PATCH 33/52] v4l2-framework.txt: add SDR device type Antti Palosaari
2014-01-25 17:10 ` [PATCH 34/52] devices.txt: add video4linux device for Software Defined Radio Antti Palosaari
2014-01-25 17:10 ` [PATCH 35/52] rtl2832_sdr: convert to SDR API Antti Palosaari
2014-01-25 17:10 ` [PATCH 36/52] msi3101: " Antti Palosaari
2014-01-25 17:10 ` [PATCH 37/52] msi3101: add u8 sample format Antti Palosaari
2014-01-25 17:10 ` [PATCH 38/52] msi3101: add u16 LE " Antti Palosaari
2014-01-25 17:10 ` [PATCH 39/52] msi3101: tons of small changes Antti Palosaari
2014-01-25 17:10 ` [PATCH 40/52] v4l: disable lockdep on vb2_fop_mmap() Antti Palosaari
2014-01-25 17:10 ` [PATCH 41/52] rtl2832_sdr: return NULL on rtl2832_sdr_attach failure Antti Palosaari
2014-01-25 17:10 ` [PATCH 42/52] rtl2832_sdr: calculate bandwidth if not set by user Antti Palosaari
2014-01-25 17:10 ` [PATCH 43/52] rtl2832_sdr: clamp ADC frequency to valid range always Antti Palosaari
2014-01-25 17:10 ` [PATCH 44/52] rtl2832_sdr: improve ADC device programming logic Antti Palosaari
2014-01-25 17:10 ` [PATCH 45/52] rtl2832_sdr: remove FMT buffer type checks Antti Palosaari
2014-01-25 17:10 ` [PATCH 46/52] rtl2832_sdr: switch FM to DAB mode Antti Palosaari
2014-01-25 17:10 ` [PATCH 47/52] msi3101: calculate tuner filters Antti Palosaari
2014-01-25 17:10 ` [PATCH 48/52] msi3101: remove FMT buffer type checks Antti Palosaari
2014-01-25 17:10 ` [PATCH 49/52] msi3101: improve ADC config stream format selection Antti Palosaari
2014-01-25 17:10 ` [PATCH 50/52] msi3101: clamp ADC and RF to valid range Antti Palosaari
2014-01-25 17:10 ` [PATCH 51/52] msi3101: disable all but u8 and u16le formats Antti Palosaari
2014-01-25 17:10 ` [PATCH 52/52] v4l: add RF tuner gain controls Antti Palosaari
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox