diff mbox

[REVIEW,13/86] rtl2832_sdr: implement FMT IOCTLs

Message ID 1391935771-18670-14-git-send-email-crope@iki.fi (mailing list archive)
State New, archived
Headers show

Commit Message

Antti Palosaari Feb. 9, 2014, 8:48 a.m. UTC
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 mbox

Patch

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,