All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support
@ 2015-11-30 20:27 Hans Verkuil
  2015-11-30 20:27 ` [PATCH 01/11] cx23885: fix format/crop handling Hans Verkuil
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller

From: Hans Verkuil <hans.verkuil@cisco.com>

A friend asked me to help getting his ViewCast 460e to work. Little did I
know...

Kernel Labs did work on this card lots of kernel version ago, but after
integrating that work it still didn't function properly.

After digging deeper it turned out that there were a lot of register
differences between the cx23888 and the cx2388x/cx25840/cx231xx devices
that were not correctly handled. Also issues with format/cropcap/std handling
in cx25840 and cx23885 caused problems.

This patch series makes the ViewCast 460e work. Tested with a ViewCast 460e,
cx25840-based board (ivtv), cx231xx board and cx23885 board.

This patch series also adds the new cs3308 driver, used by the ViewCast
and written by Kernel Labs.

And it fixes broken pixelaspect ratio reporting by cx231xx and ivtv/cx18
which I discovered while digging into that topic for the cx23885.

Regards,

	Hans

Hans Verkuil (11):
  cx23885: fix format/crop handling
  cx231xx: fix NTSC cropcap, add missing cropcap for 417
  ivtv/cx18: fix inverted pixel aspect ratio
  cx25840: fix VBI support for cx23888
  cx25840: more cx23888 register address changes
  cx25840: relax a Vsrc check
  cx25840: fix cx25840_s_stream for cx2388x and cx231xx
  cx25840: initialize the standard to NTSC_M
  cs3308: add new 8-channel volume control driver
  cx23885: add support for ViewCast 260e and 460e.
  cx23885: video instead of vbi register used

 MAINTAINERS                               |   9 ++
 drivers/media/i2c/Kconfig                 |  10 +++
 drivers/media/i2c/Makefile                |   1 +
 drivers/media/i2c/cs3308.c                | 138 ++++++++++++++++++++++++++++++
 drivers/media/i2c/cx25840/cx25840-core.c  | 115 +++++++++++++------------
 drivers/media/i2c/cx25840/cx25840-core.h  |   1 +
 drivers/media/i2c/cx25840/cx25840-vbi.c   |  32 +++++--
 drivers/media/pci/cx18/cx18-ioctl.c       |   4 +-
 drivers/media/pci/cx23885/Kconfig         |   1 +
 drivers/media/pci/cx23885/cx23885-cards.c | 114 ++++++++++++++++++++++++
 drivers/media/pci/cx23885/cx23885-core.c  |  10 +++
 drivers/media/pci/cx23885/cx23885-i2c.c   |   2 +
 drivers/media/pci/cx23885/cx23885-vbi.c   |   3 +-
 drivers/media/pci/cx23885/cx23885-video.c |  43 +++++++++-
 drivers/media/pci/cx23885/cx23885.h       |   7 +-
 drivers/media/pci/ivtv/ivtv-ioctl.c       |   8 +-
 drivers/media/usb/cx231xx/cx231xx-417.c   |  22 +++++
 drivers/media/usb/cx231xx/cx231xx-video.c |   5 +-
 18 files changed, 444 insertions(+), 81 deletions(-)
 create mode 100644 drivers/media/i2c/cs3308.c

-- 
2.6.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 01/11] cx23885: fix format/crop handling
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 02/11] cx231xx: fix NTSC cropcap, add missing cropcap for 417 Hans Verkuil
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

While testing the cx23885 driver with various TV standards I found
a number of bugs:

1) norm_maxw() returned 768 instead of 720 for PAL formats. This should
   always be 720, so drop this inline function and just always use 720.
2) cropcap() was missing, so the pixelaspect was never known and qv4l2 would
   scale the image incorrectly. Add cropcap support.
3) cx23885_set_tvnorm() should just return 0 if the same standard was
   set again. If another standard is set, then reset the width/height and
   call set_fmt for the subdevs.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-video.c | 39 ++++++++++++++++++++++++++++++-
 drivers/media/pci/cx23885/cx23885.h       |  5 ----
 2 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index 63f302e0..ad4d7e6 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -114,11 +114,19 @@ void cx23885_video_wakeup(struct cx23885_dev *dev,
 
 int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
 {
+	struct v4l2_subdev_format format = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.format.code = MEDIA_BUS_FMT_FIXED,
+	};
+
 	dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
 		__func__,
 		(unsigned int)norm,
 		v4l2_norm_to_name(norm));
 
+	if (dev->tvnorm == norm)
+		return 0;
+
 	if (dev->tvnorm != norm) {
 		if (vb2_is_busy(&dev->vb2_vidq) || vb2_is_busy(&dev->vb2_vbiq) ||
 		    vb2_is_busy(&dev->vb2_mpegq))
@@ -126,9 +134,17 @@ int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
 	}
 
 	dev->tvnorm = norm;
+	dev->width = 720;
+	dev->height = norm_maxh(norm);
+	dev->field = V4L2_FIELD_INTERLACED;
 
 	call_all(dev, video, s_std, norm);
 
+	format.format.width = dev->width;
+	format.format.height = dev->height;
+	format.format.field = dev->field;
+	call_all(dev, pad, set_fmt, NULL, &format);
+
 	return 0;
 }
 
@@ -545,7 +561,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 		return -EINVAL;
 
 	field = f->fmt.pix.field;
-	maxw  = norm_maxw(dev->tvnorm);
+	maxw  = 720;
 	maxh  = norm_maxh(dev->tvnorm);
 
 	if (V4L2_FIELD_ANY == field) {
@@ -648,6 +664,26 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 	return 0;
 }
 
+static int vidioc_cropcap(struct file *file, void *priv,
+			  struct v4l2_cropcap *cc)
+{
+	struct cx23885_dev *dev = video_drvdata(file);
+	bool is_50hz = dev->tvnorm & V4L2_STD_625_50;
+
+	if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	cc->bounds.left = 0;
+	cc->bounds.top = 0;
+	cc->bounds.width = 720;
+	cc->bounds.height = norm_maxh(dev->tvnorm);
+	cc->defrect = cc->bounds;
+	cc->pixelaspect.numerator = is_50hz ? 54 : 11;
+	cc->pixelaspect.denominator = is_50hz ? 59 : 10;
+
+	return 0;
+}
+
 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
 {
 	struct cx23885_dev *dev = video_drvdata(file);
@@ -1082,6 +1118,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
 	.vidioc_streamon      = vb2_ioctl_streamon,
 	.vidioc_streamoff     = vb2_ioctl_streamoff,
+	.vidioc_cropcap       = vidioc_cropcap,
 	.vidioc_s_std         = vidioc_s_std,
 	.vidioc_g_std         = vidioc_g_std,
 	.vidioc_enum_input    = vidioc_enum_input,
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index f9eb57b..9a8938b 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -627,11 +627,6 @@ extern int cx23885_risc_databuffer(struct pci_dev *pci,
 /* ----------------------------------------------------------- */
 /* tv norms                                                    */
 
-static inline unsigned int norm_maxw(v4l2_std_id norm)
-{
-	return (norm & V4L2_STD_525_60) ? 720 : 768;
-}
-
 static inline unsigned int norm_maxh(v4l2_std_id norm)
 {
 	return (norm & V4L2_STD_525_60) ? 480 : 576;
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 02/11] cx231xx: fix NTSC cropcap, add missing cropcap for 417
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
  2015-11-30 20:27 ` [PATCH 01/11] cx23885: fix format/crop handling Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 03/11] ivtv/cx18: fix inverted pixel aspect ratio Hans Verkuil
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

The pixelaspect ratio was set incorrectly for 60Hz formats.
And since cropcap wasn't implemented at all for the -417 (compressed
video) the pixelaspect was unknown for compressed video.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/usb/cx231xx/cx231xx-417.c   | 22 ++++++++++++++++++++++
 drivers/media/usb/cx231xx/cx231xx-video.c |  5 +++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c
index f59a6f1..1564ade 100644
--- a/drivers/media/usb/cx231xx/cx231xx-417.c
+++ b/drivers/media/usb/cx231xx/cx231xx-417.c
@@ -1492,6 +1492,27 @@ static struct videobuf_queue_ops cx231xx_qops = {
 
 /* ------------------------------------------------------------------ */
 
+static int vidioc_cropcap(struct file *file, void *priv,
+			  struct v4l2_cropcap *cc)
+{
+	struct cx231xx_fh *fh = priv;
+	struct cx231xx *dev = fh->dev;
+	bool is_50hz = dev->encodernorm.id & V4L2_STD_625_50;
+
+	if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	cc->bounds.left = 0;
+	cc->bounds.top = 0;
+	cc->bounds.width = dev->ts1.width;
+	cc->bounds.height = dev->ts1.height;
+	cc->defrect = cc->bounds;
+	cc->pixelaspect.numerator = is_50hz ? 54 : 11;
+	cc->pixelaspect.denominator = is_50hz ? 59 : 10;
+
+	return 0;
+}
+
 static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm)
 {
 	struct cx231xx_fh  *fh  = file->private_data;
@@ -1834,6 +1855,7 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_g_input		 = cx231xx_g_input,
 	.vidioc_s_input		 = cx231xx_s_input,
 	.vidioc_s_ctrl		 = vidioc_s_ctrl,
+	.vidioc_cropcap		 = vidioc_cropcap,
 	.vidioc_querycap	 = cx231xx_querycap,
 	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap	 = vidioc_g_fmt_vid_cap,
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index 246fb2b..a70850f 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -1444,6 +1444,7 @@ static int vidioc_cropcap(struct file *file, void *priv,
 {
 	struct cx231xx_fh *fh = priv;
 	struct cx231xx *dev = fh->dev;
+	bool is_50hz = dev->norm & V4L2_STD_625_50;
 
 	if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1453,8 +1454,8 @@ static int vidioc_cropcap(struct file *file, void *priv,
 	cc->bounds.width = dev->width;
 	cc->bounds.height = dev->height;
 	cc->defrect = cc->bounds;
-	cc->pixelaspect.numerator = 54;	/* 4:3 FIXME: remove magic numbers */
-	cc->pixelaspect.denominator = 59;
+	cc->pixelaspect.numerator = is_50hz ? 54 : 11;
+	cc->pixelaspect.denominator = is_50hz ? 59 : 10;
 
 	return 0;
 }
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 03/11] ivtv/cx18: fix inverted pixel aspect ratio
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
  2015-11-30 20:27 ` [PATCH 01/11] cx23885: fix format/crop handling Hans Verkuil
  2015-11-30 20:27 ` [PATCH 02/11] cx231xx: fix NTSC cropcap, add missing cropcap for 417 Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 04/11] cx25840: fix VBI support for cx23888 Hans Verkuil
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

These two drivers reported the pixel aspect ratio the wrong way around.
This caused qv4l2 to scale the image incorrectly.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx18/cx18-ioctl.c | 4 ++--
 drivers/media/pci/ivtv/ivtv-ioctl.c | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c
index 55525af..eeb741c 100644
--- a/drivers/media/pci/cx18/cx18-ioctl.c
+++ b/drivers/media/pci/cx18/cx18-ioctl.c
@@ -453,8 +453,8 @@ static int cx18_cropcap(struct file *file, void *fh,
 
 	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
-	cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
-	cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
+	cropcap->pixelaspect.numerator = cx->is_50hz ? 54 : 11;
+	cropcap->pixelaspect.denominator = cx->is_50hz ? 59 : 10;
 	return 0;
 }
 
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index 2c54cb8..2dc4b20 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -831,11 +831,11 @@ static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropca
 	struct ivtv *itv = id->itv;
 
 	if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
-		cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
+		cropcap->pixelaspect.numerator = itv->is_50hz ? 54 : 11;
+		cropcap->pixelaspect.denominator = itv->is_50hz ? 59 : 10;
 	} else if (cropcap->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
-		cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+		cropcap->pixelaspect.numerator = itv->is_out_50hz ? 54 : 11;
+		cropcap->pixelaspect.denominator = itv->is_out_50hz ? 59 : 10;
 	} else {
 		return -EINVAL;
 	}
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 04/11] cx25840: fix VBI support for cx23888
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
                   ` (2 preceding siblings ...)
  2015-11-30 20:27 ` [PATCH 03/11] ivtv/cx18: fix inverted pixel aspect ratio Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 05/11] cx25840: more cx23888 register address changes Hans Verkuil
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

The cx23888 has the VBI registers at different addresses compared to
the other variants. In most cases it is a fixed offset, but not always.

Update the code so the right registers are written for the cx23888.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/cx25840/cx25840-core.c | 20 ++++++++++----------
 drivers/media/i2c/cx25840/cx25840-core.h |  1 +
 drivers/media/i2c/cx25840/cx25840-vbi.c  | 32 +++++++++++++++++++++++---------
 3 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index 181fdc1..ec11ba7 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -666,7 +666,7 @@ static void cx23885_initialize(struct i2c_client *client)
 	cx25840_write4(client, 0x404, 0x0010253e);
 
 	/* CC on  - Undocumented Register */
-	cx25840_write(client, 0x42f, 0x66);
+	cx25840_write(client, state->vbi_regs_offset + 0x42f, 0x66);
 
 	/* HVR-1250 / HVR1850 DIF related */
 	/* Power everything up */
@@ -1122,15 +1122,14 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
 			else
 				cx25840_write4(client, 0x420, 0x001c8282);
 
-			cx25840_write4(client, 0x42c, 0x42600000);
-			cx25840_write4(client, 0x430, 0x0000039b);
-			cx25840_write4(client, 0x438, 0x00000000);
-
-			cx25840_write4(client, 0x440, 0xF8E3E824);
-			cx25840_write4(client, 0x444, 0x401040dc);
-			cx25840_write4(client, 0x448, 0xcd3f02a0);
-			cx25840_write4(client, 0x44c, 0x161f1000);
-			cx25840_write4(client, 0x450, 0x00000802);
+			cx25840_write4(client, state->vbi_regs_offset + 0x42c, 0x42600000);
+			cx25840_write4(client, state->vbi_regs_offset + 0x430, 0x0000039b);
+			cx25840_write4(client, state->vbi_regs_offset + 0x438, 0x00000000);
+			cx25840_write4(client, state->vbi_regs_offset + 0x440, 0xF8E3E824);
+			cx25840_write4(client, state->vbi_regs_offset + 0x444, 0x401040dc);
+			cx25840_write4(client, state->vbi_regs_offset + 0x448, 0xcd3f02a0);
+			cx25840_write4(client, state->vbi_regs_offset + 0x44c, 0x161f1000);
+			cx25840_write4(client, state->vbi_regs_offset + 0x450, 0x00000802);
 
 			cx25840_write4(client, 0x91c, 0x01000000);
 			cx25840_write4(client, 0x8e0, 0x03063870);
@@ -5264,6 +5263,7 @@ static int cx25840_probe(struct i2c_client *client,
 	state->vbi_line_offset = 8;
 	state->id = id;
 	state->rev = device_id;
+	state->vbi_regs_offset = id == CX23888_AV ? 0x500 - 0x424 : 0;
 	v4l2_ctrl_handler_init(&state->hdl, 9);
 	v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
 			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
diff --git a/drivers/media/i2c/cx25840/cx25840-core.h b/drivers/media/i2c/cx25840/cx25840-core.h
index fdea48c..254ef45 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.h
+++ b/drivers/media/i2c/cx25840/cx25840-core.h
@@ -69,6 +69,7 @@ struct cx25840_state {
 	enum cx25840_model id;
 	u32 rev;
 	int is_initialized;
+	unsigned vbi_regs_offset;
 	wait_queue_head_t fw_wait;    /* wake up when the fw load is finished */
 	struct work_struct fw_work;   /* work entry for fw load */
 	struct cx25840_ir_state *ir_state;
diff --git a/drivers/media/i2c/cx25840/cx25840-vbi.c b/drivers/media/i2c/cx25840/cx25840-vbi.c
index 04034c5..0470bb6 100644
--- a/drivers/media/i2c/cx25840/cx25840-vbi.c
+++ b/drivers/media/i2c/cx25840/cx25840-vbi.c
@@ -104,7 +104,8 @@ int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
 
 	if (is_pal) {
 		for (i = 7; i <= 23; i++) {
-			u8 v = cx25840_read(client, 0x424 + i - 7);
+			u8 v = cx25840_read(client,
+				 state->vbi_regs_offset + 0x424 + i - 7);
 
 			svbi->service_lines[0][i] = lcr2vbi[v >> 4];
 			svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
@@ -113,7 +114,8 @@ int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
 		}
 	} else {
 		for (i = 10; i <= 21; i++) {
-			u8 v = cx25840_read(client, 0x424 + i - 10);
+			u8 v = cx25840_read(client,
+				state->vbi_regs_offset + 0x424 + i - 10);
 
 			svbi->service_lines[0][i] = lcr2vbi[v >> 4];
 			svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
@@ -135,7 +137,10 @@ int cx25840_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
 	cx25840_std_setup(client);
 
 	/* VBI Offset */
-	cx25840_write(client, 0x47f, vbi_offset);
+	if (is_cx23888(state))
+		cx25840_write(client, 0x54f, vbi_offset);
+	else
+		cx25840_write(client, 0x47f, vbi_offset);
 	cx25840_write(client, 0x404, 0x2e);
 	return 0;
 }
@@ -158,7 +163,10 @@ int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
 	/* Sliced VBI */
 	cx25840_write(client, 0x404, 0x32);	/* Ancillary data */
 	cx25840_write(client, 0x406, 0x13);
-	cx25840_write(client, 0x47f, vbi_offset);
+	if (is_cx23888(state))
+		cx25840_write(client, 0x54f, vbi_offset);
+	else
+		cx25840_write(client, 0x47f, vbi_offset);
 
 	if (is_pal) {
 		for (i = 0; i <= 6; i++)
@@ -194,17 +202,23 @@ int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
 	}
 
 	if (is_pal) {
-		for (x = 1, i = 0x424; i <= 0x434; i++, x++)
+		for (x = 1, i = state->vbi_regs_offset + 0x424;
+		     i <= state->vbi_regs_offset + 0x434; i++, x++)
 			cx25840_write(client, i, lcr[6 + x]);
 	} else {
-		for (x = 1, i = 0x424; i <= 0x430; i++, x++)
+		for (x = 1, i = state->vbi_regs_offset + 0x424;
+		     i <= state->vbi_regs_offset + 0x430; i++, x++)
 			cx25840_write(client, i, lcr[9 + x]);
-		for (i = 0x431; i <= 0x434; i++)
+		for (i = state->vbi_regs_offset + 0x431;
+		     i <= state->vbi_regs_offset + 0x434; i++)
 			cx25840_write(client, i, 0);
 	}
 
-	cx25840_write(client, 0x43c, 0x16);
-	cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22);
+	cx25840_write(client, state->vbi_regs_offset + 0x43c, 0x16);
+	if (is_cx23888(state))
+		cx25840_write(client, 0x428, is_pal ? 0x2a : 0x22);
+	else
+		cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22);
 	return 0;
 }
 
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 05/11] cx25840: more cx23888 register address changes
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
                   ` (3 preceding siblings ...)
  2015-11-30 20:27 ` [PATCH 04/11] cx25840: fix VBI support for cx23888 Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 06/11] cx25840: relax a Vsrc check Hans Verkuil
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

The cx23888 also moves the following registers around:

!cx23888	cx23888
--------	-------
0x418, 0x41c	0x434, 0x438
0x420		0x418 (expect for bit 29 which has a different meaning)
0x478		0x454

Also drop the set_input code where the scaler is changed: this does not
belong here, changing the input should not change the scaler.

And that's besides the fact that that code is plain wrong.

After this change the cx23888 behaves much better. In particular, calling
set_input no longer changes the saturation to 0, causing a grayscale
image.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/cx25840/cx25840-core.c | 49 +++++++++++++++-----------------
 1 file changed, 23 insertions(+), 26 deletions(-)

diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index ec11ba7..a741c30 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -559,7 +559,10 @@ static void cx23885_initialize(struct i2c_client *client)
 	cx25840_write4(client, 0x414, 0x00107d12);
 
 	/* Chroma */
-	cx25840_write4(client, 0x420, 0x3d008282);
+	if (is_cx23888(state))
+		cx25840_write4(client, 0x418, 0x1d008282);
+	else
+		cx25840_write4(client, 0x420, 0x3d008282);
 
 	/*
 	 * Aux PLL
@@ -673,7 +676,10 @@ static void cx23885_initialize(struct i2c_client *client)
 	cx25840_write4(client, 0x130, 0x0);
 
 	/* Undocumented */
-	cx25840_write4(client, 0x478, 0x6628021F);
+	if (is_cx23888(state))
+		cx25840_write4(client, 0x454, 0x6628021F);
+	else
+		cx25840_write4(client, 0x478, 0x6628021F);
 
 	/* AFE_CLK_OUT_CTRL - Select the clock output source as output */
 	cx25840_write4(client, 0x144, 0x5);
@@ -1106,25 +1112,10 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
 			cx25840_write4(client, 0x410, 0xffff0dbf);
 			cx25840_write4(client, 0x414, 0x00137d03);
 
-			/* on the 887, 0x418 is HSCALE_CTRL, on the 888 it is 
-			   CHROMA_CTRL */
-			if (is_cx23888(state))
-				cx25840_write4(client, 0x418, 0x01008080);
-			else
-				cx25840_write4(client, 0x418, 0x01000000);
-
-			cx25840_write4(client, 0x41c, 0x00000000);
-
-			/* on the 887, 0x420 is CHROMA_CTRL, on the 888 it is 
-			   CRUSH_CTRL */
-			if (is_cx23888(state))
-				cx25840_write4(client, 0x420, 0x001c3e0f);
-			else
-				cx25840_write4(client, 0x420, 0x001c8282);
-
 			cx25840_write4(client, state->vbi_regs_offset + 0x42c, 0x42600000);
 			cx25840_write4(client, state->vbi_regs_offset + 0x430, 0x0000039b);
 			cx25840_write4(client, state->vbi_regs_offset + 0x438, 0x00000000);
+
 			cx25840_write4(client, state->vbi_regs_offset + 0x440, 0xF8E3E824);
 			cx25840_write4(client, state->vbi_regs_offset + 0x444, 0x401040dc);
 			cx25840_write4(client, state->vbi_regs_offset + 0x448, 0xcd3f02a0);
@@ -1425,14 +1416,20 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd,
 			fmt->width, fmt->height, HSC, VSC);
 
 	/* HSCALE=HSC */
-	cx25840_write(client, 0x418, HSC & 0xff);
-	cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
-	cx25840_write(client, 0x41a, HSC >> 16);
-	/* VSCALE=VSC */
-	cx25840_write(client, 0x41c, VSC & 0xff);
-	cx25840_write(client, 0x41d, VSC >> 8);
-	/* VS_INTRLACE=1 VFILT=filter */
-	cx25840_write(client, 0x41e, 0x8 | filter);
+	if (is_cx23888(state)) {
+		cx25840_write4(client, 0x434, HSC | (1 << 24));
+		/* VSCALE=VSC VS_INTRLACE=1 VFILT=filter */
+		cx25840_write4(client, 0x438, VSC | (1 << 19) | (filter << 16));
+	} else {
+		cx25840_write(client, 0x418, HSC & 0xff);
+		cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
+		cx25840_write(client, 0x41a, HSC >> 16);
+		/* VSCALE=VSC */
+		cx25840_write(client, 0x41c, VSC & 0xff);
+		cx25840_write(client, 0x41d, VSC >> 8);
+		/* VS_INTRLACE=1 VFILT=filter */
+		cx25840_write(client, 0x41e, 0x8 | filter);
+	}
 	return 0;
 }
 
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 06/11] cx25840: relax a Vsrc check
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
                   ` (4 preceding siblings ...)
  2015-11-30 20:27 ` [PATCH 05/11] cx25840: more cx23888 register address changes Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 07/11] cx25840: fix cx25840_s_stream for cx2388x and cx231xx Hans Verkuil
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

The cx23888 reports a slightly different Vsrc value than the other
chip variants do. Relax the check by 1, otherwise cx25840_set_fmt()
would fail for the cx23888.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/cx25840/cx25840-core.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index a741c30..d8b5343 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -1390,8 +1390,14 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd,
 
 	Vlines = fmt->height + (is_50Hz ? 4 : 7);
 
+	/*
+	 * We keep 1 margin for the Vsrc < Vlines check since the
+	 * cx23888 reports a Vsrc of 486 instead of 487 for the NTSC
+	 * height. Without that margin the cx23885 fails in this
+	 * check.
+	 */
 	if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
-			(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
+			(Vlines * 8 < Vsrc) || (Vsrc + 1 < Vlines)) {
 		v4l_err(client, "%dx%d is not a valid size!\n",
 				fmt->width, fmt->height);
 		return -ERANGE;
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 07/11] cx25840: fix cx25840_s_stream for cx2388x and cx231xx
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
                   ` (5 preceding siblings ...)
  2015-11-30 20:27 ` [PATCH 06/11] cx25840: relax a Vsrc check Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 08/11] cx25840: initialize the standard to NTSC_M Hans Verkuil
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

For those two devices the code wrote to addresses 0x115/6, but on
those devices those addresses have nothing to do with power controls.
So clearly this never worked. Rather than writing to bogus addresses,
just do nothing for the cx2388x and cx231xx.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/cx25840/cx25840-core.c | 37 ++++++++++++++++----------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index d8b5343..a8b1a03 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -1716,26 +1716,27 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
 
 	v4l_dbg(1, cx25840_debug, client, "%s video output\n",
 			enable ? "enable" : "disable");
+
+	/*
+	 * It's not clear what should be done for these devices.
+	 * The original code used the same addresses as for the cx25840, but
+	 * those addresses do something else entirely on the cx2388x and
+	 * cx231xx. Since it never did anything in the first place, just do
+	 * nothing.
+	 */
+	if (is_cx2388x(state) || is_cx231xx(state))
+		return 0;
+
 	if (enable) {
-		if (is_cx2388x(state) || is_cx231xx(state)) {
-			v = cx25840_read(client, 0x421) | 0x0b;
-			cx25840_write(client, 0x421, v);
-		} else {
-			v = cx25840_read(client, 0x115) | 0x0c;
-			cx25840_write(client, 0x115, v);
-			v = cx25840_read(client, 0x116) | 0x04;
-			cx25840_write(client, 0x116, v);
-		}
+		v = cx25840_read(client, 0x115) | 0x0c;
+		cx25840_write(client, 0x115, v);
+		v = cx25840_read(client, 0x116) | 0x04;
+		cx25840_write(client, 0x116, v);
 	} else {
-		if (is_cx2388x(state) || is_cx231xx(state)) {
-			v = cx25840_read(client, 0x421) & ~(0x0b);
-			cx25840_write(client, 0x421, v);
-		} else {
-			v = cx25840_read(client, 0x115) & ~(0x0c);
-			cx25840_write(client, 0x115, v);
-			v = cx25840_read(client, 0x116) & ~(0x04);
-			cx25840_write(client, 0x116, v);
-		}
+		v = cx25840_read(client, 0x115) & ~(0x0c);
+		cx25840_write(client, 0x115, v);
+		v = cx25840_read(client, 0x116) & ~(0x04);
+		cx25840_write(client, 0x116, v);
 	}
 	return 0;
 }
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 08/11] cx25840: initialize the standard to NTSC_M
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
                   ` (6 preceding siblings ...)
  2015-11-30 20:27 ` [PATCH 07/11] cx25840: fix cx25840_s_stream for cx2388x and cx231xx Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 09/11] cs3308: add new 8-channel volume control driver Hans Verkuil
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

This is necessary since the *_std_setup functions rely on a valid state->std
field.

Also fix the cx23888_std_setup() to test for 60Hz instead of NTSC, just like
cx25840_std_setup() does.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/cx25840/cx25840-core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index a8b1a03..f2e2c34 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -4977,7 +4977,7 @@ static void cx23888_std_setup(struct i2c_client *client)
 	cx25840_write4(client, 0x4b4, 0x20524030);
 	cx25840_write4(client, 0x47c, 0x010a8263);
 
-	if (std & V4L2_STD_NTSC) {
+	if (std & V4L2_STD_525_60) {
 		v4l_dbg(1, cx25840_debug, client, "%s() Selecting NTSC",
 			__func__);
 
@@ -5268,6 +5268,7 @@ static int cx25840_probe(struct i2c_client *client,
 	state->id = id;
 	state->rev = device_id;
 	state->vbi_regs_offset = id == CX23888_AV ? 0x500 - 0x424 : 0;
+	state->std = V4L2_STD_NTSC_M;
 	v4l2_ctrl_handler_init(&state->hdl, 9);
 	v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
 			V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 09/11] cs3308: add new 8-channel volume control driver
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
                   ` (7 preceding siblings ...)
  2015-11-30 20:27 ` [PATCH 08/11] cx25840: initialize the standard to NTSC_M Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 10/11] cx23885: add support for ViewCast 260e and 460e Hans Verkuil
  2015-11-30 20:27 ` [PATCH 11/11] cx23885: video instead of vbi register used Hans Verkuil
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Add simple support for this 8 channel volume control driver.
Currently all it does is to unmute all 8 channels.

Based upon Devin's initial patch made for an older kernel which I
cleaned up and rebased. Thanks to Kernel Labs for that work.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 MAINTAINERS                |   9 +++
 drivers/media/i2c/Kconfig  |  10 ++++
 drivers/media/i2c/Makefile |   1 +
 drivers/media/i2c/cs3308.c | 138 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 158 insertions(+)
 create mode 100644 drivers/media/i2c/cs3308.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d6bba28..9571ad9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3094,6 +3094,15 @@ S:	Maintained
 F:	crypto/ansi_cprng.c
 F:	crypto/rng.c
 
+CS3308 MEDIA DRIVER
+M:	Hans Verkuil <hverkuil@xs4all.nl>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+W:	http://linuxtv.org
+S:	Odd Fixes
+F:	drivers/media/i2c/cs3308.c
+F:	drivers/media/i2c/cs3308.h
+
 CS5535 Audio ALSA driver
 M:	Jaya Kumar <jayakumar.alsa@gmail.com>
 S:	Maintained
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 521bbf1..993dc50 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -83,6 +83,16 @@ config VIDEO_MSP3400
 	  To compile this driver as a module, choose M here: the
 	  module will be called msp3400.
 
+config VIDEO_CS3308
+	tristate "Cirrus Logic CS3308 audio ADC"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the Cirrus Logic CS3308 High Performance 8-Channel
+	  Analog Volume Control
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cs3308.
+
 config VIDEO_CS5345
 	tristate "Cirrus Logic CS5345 audio ADC"
 	depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 07db257..94f2c99 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
 obj-$(CONFIG_VIDEO_TW2804) += tw2804.o
 obj-$(CONFIG_VIDEO_TW9903) += tw9903.o
 obj-$(CONFIG_VIDEO_TW9906) += tw9906.o
+obj-$(CONFIG_VIDEO_CS3308) += cs3308.o
 obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
 obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
 obj-$(CONFIG_VIDEO_M52790) += m52790.o
diff --git a/drivers/media/i2c/cs3308.c b/drivers/media/i2c/cs3308.c
new file mode 100644
index 0000000..d28b4f3
--- /dev/null
+++ b/drivers/media/i2c/cs3308.c
@@ -0,0 +1,138 @@
+/*
+ * Cirrus Logic cs3308 8-Channel Analog Volume Control
+ *
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
+ * Copyright (C) 2012 Steven Toth <stoth@kernellabs.com>
+ *
+ * Derived from cs5345.c Copyright (C) 2007 Hans Verkuil
+ *
+ * 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.
+ */
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+
+MODULE_DESCRIPTION("i2c device driver for cs3308 8-channel volume control");
+MODULE_AUTHOR("Devin Heitmueller");
+MODULE_LICENSE("GPL");
+
+static inline int cs3308_write(struct v4l2_subdev *sd, u8 reg, u8 value)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static inline int cs3308_read(struct v4l2_subdev *sd, u8 reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int cs3308_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
+{
+	reg->val = cs3308_read(sd, reg->reg & 0xffff);
+	reg->size = 1;
+	return 0;
+}
+
+static int cs3308_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
+{
+	cs3308_write(sd, reg->reg & 0xffff, reg->val & 0xff);
+	return 0;
+}
+#endif
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops cs3308_core_ops = {
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = cs3308_g_register,
+	.s_register = cs3308_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_ops cs3308_ops = {
+	.core = &cs3308_core_ops,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int cs3308_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct v4l2_subdev *sd;
+	unsigned i;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	if ((i2c_smbus_read_byte_data(client, 0x1c) & 0xf0) != 0xe0)
+		return -ENODEV;
+
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+		 client->addr << 1, client->adapter->name);
+
+	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	if (sd == NULL)
+		return -ENOMEM;
+
+	v4l2_i2c_subdev_init(sd, client, &cs3308_ops);
+
+	/* Set some reasonable defaults */
+	cs3308_write(sd, 0x0d, 0x00); /* Power up all channels */
+	cs3308_write(sd, 0x0e, 0x00); /* Master Power */
+	cs3308_write(sd, 0x0b, 0x00); /* Device Configuration */
+	/* Set volume for each channel */
+	for (i = 1; i <= 8; i++)
+		cs3308_write(sd, i, 0xd2);
+	cs3308_write(sd, 0x0a, 0x00); /* Unmute all channels */
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int cs3308_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(sd);
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct i2c_device_id cs3308_id[] = {
+	{ "cs3308", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, cs3308_id);
+
+static struct i2c_driver cs3308_driver = {
+	.driver = {
+		.owner  = THIS_MODULE,
+		.name   = "cs3308",
+	},
+	.probe          = cs3308_probe,
+	.remove         = cs3308_remove,
+	.id_table       = cs3308_id,
+};
+
+module_i2c_driver(cs3308_driver);
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 10/11] cx23885: add support for ViewCast 260e and 460e.
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
                   ` (8 preceding siblings ...)
  2015-11-30 20:27 ` [PATCH 09/11] cs3308: add new 8-channel volume control driver Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  2015-11-30 20:27 ` [PATCH 11/11] cx23885: video instead of vbi register used Hans Verkuil
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

Add support for these two new cards.

Based upon Devin's initial patch made for an older kernel which I
cleaned up and rebased. Thanks to Kernel Labs for that work.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/Kconfig         |   1 +
 drivers/media/pci/cx23885/cx23885-cards.c | 114 ++++++++++++++++++++++++++++++
 drivers/media/pci/cx23885/cx23885-core.c  |  10 +++
 drivers/media/pci/cx23885/cx23885-i2c.c   |   2 +
 drivers/media/pci/cx23885/cx23885-video.c |   4 +-
 drivers/media/pci/cx23885/cx23885.h       |   2 +
 6 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig
index 2e1b88c..3435bba 100644
--- a/drivers/media/pci/cx23885/Kconfig
+++ b/drivers/media/pci/cx23885/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_CX23885
 	select VIDEOBUF2_DMA_SG
 	select VIDEO_CX25840
 	select VIDEO_CX2341X
+	select VIDEO_CS3308
 	select DVB_DIB7000P if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_S5H1409 if MEDIA_SUBDRV_AUTOSELECT
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index 99ac201..310ee76 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -715,6 +715,56 @@ struct cx23885_board cx23885_boards[] = {
 		.portb		= CX23885_MPEG_DVB,
 		.portc		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_VIEWCAST_260E] = {
+		.name		= "ViewCast 260e",
+		.porta		= CX23885_ANALOG_VIDEO,
+		.force_bff	= 1,
+		.input          = {{
+			.type   = CX23885_VMUX_COMPOSITE1,
+			.vmux   = CX25840_VIN6_CH1,
+			.amux   = CX25840_AUDIO7,
+		}, {
+			.type   = CX23885_VMUX_SVIDEO,
+			.vmux   = CX25840_VIN7_CH3 |
+					CX25840_VIN5_CH1 |
+					CX25840_SVIDEO_ON,
+			.amux   = CX25840_AUDIO7,
+		}, {
+			.type   = CX23885_VMUX_COMPONENT,
+			.vmux   = CX25840_VIN7_CH3 |
+					CX25840_VIN6_CH2 |
+					CX25840_VIN5_CH1 |
+					CX25840_COMPONENT_ON,
+			.amux   = CX25840_AUDIO7,
+		} },
+	},
+	[CX23885_BOARD_VIEWCAST_460E] = {
+		.name		= "ViewCast 460e",
+		.porta		= CX23885_ANALOG_VIDEO,
+		.force_bff	= 1,
+		.input          = {{
+			.type   = CX23885_VMUX_COMPOSITE1,
+			.vmux   = CX25840_VIN4_CH1,
+			.amux   = CX25840_AUDIO7,
+		}, {
+			.type   = CX23885_VMUX_SVIDEO,
+			.vmux   = CX25840_VIN7_CH3 |
+					CX25840_VIN6_CH1 |
+					CX25840_SVIDEO_ON,
+			.amux   = CX25840_AUDIO7,
+		}, {
+			.type   = CX23885_VMUX_COMPONENT,
+			.vmux   = CX25840_VIN7_CH3 |
+					CX25840_VIN6_CH1 |
+					CX25840_VIN5_CH2 |
+					CX25840_COMPONENT_ON,
+			.amux   = CX25840_AUDIO7,
+		}, {
+			.type   = CX23885_VMUX_COMPOSITE2,
+			.vmux   = CX25840_VIN6_CH1,
+			.amux   = CX25840_AUDIO7,
+		} },
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -1002,6 +1052,14 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x0070,
 		.subdevice = 0xf038,
 		.card      = CX23885_BOARD_HAUPPAUGE_HVR5525,
+	}, {
+		.subvendor = 0x1576,
+		.subdevice = 0x0260,
+		.card      = CX23885_BOARD_VIEWCAST_260E,
+	}, {
+		.subvendor = 0x1576,
+		.subdevice = 0x0460,
+		.card      = CX23885_BOARD_VIEWCAST_460E,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -1034,6 +1092,28 @@ void cx23885_card_list(struct cx23885_dev *dev)
 		       dev->name, i, cx23885_boards[i].name);
 }
 
+static void viewcast_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
+{
+	u32 sn;
+
+	/* The serial number record begins with tag 0x59 */
+	if (*(eeprom_data + 0x00) != 0x59) {
+		pr_info("%s() eeprom records are undefined, no serial number\n",
+			__func__);
+		return;
+	}
+
+	sn =	(*(eeprom_data + 0x06) << 24) |
+		(*(eeprom_data + 0x05) << 16) |
+		(*(eeprom_data + 0x04) << 8) |
+		(*(eeprom_data + 0x03));
+
+	pr_info("%s: card '%s' sn# MM%d\n",
+		dev->name,
+		cx23885_boards[dev->board].name,
+		sn);
+}
+
 static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
 {
 	struct tveeprom tv;
@@ -1671,6 +1751,12 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		cx23885_gpio_set(dev, GPIO_8 | GPIO_9);
 		msleep(100);
 		break;
+	case CX23885_BOARD_VIEWCAST_260E:
+	case CX23885_BOARD_VIEWCAST_460E:
+		/* For documentation purposes, it's worth noting that this
+		 * card does not have any GPIO's connected to subcomponents.
+		 */
+		break;
 	}
 }
 
@@ -1917,6 +2003,14 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 		if (dev->i2c_bus[0].i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xc0);
 		break;
+	case CX23885_BOARD_VIEWCAST_260E:
+	case CX23885_BOARD_VIEWCAST_460E:
+		dev->i2c_bus[1].i2c_client.addr = 0xa0 >> 1;
+		tveeprom_read(&dev->i2c_bus[1].i2c_client,
+			      eeprom, sizeof(eeprom));
+		if (dev->i2c_bus[0].i2c_rc == 0)
+			viewcast_eeprom(dev, eeprom);
+		break;
 	}
 
 	switch (dev->board) {
@@ -2120,6 +2214,8 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_DVBSKY_S950:
 	case CX23885_BOARD_DVBSKY_S952:
 	case CX23885_BOARD_DVBSKY_T982:
+	case CX23885_BOARD_VIEWCAST_260E:
+	case CX23885_BOARD_VIEWCAST_460E:
 		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[2].i2c_adap,
 				"cx25840", 0x88 >> 1, NULL);
@@ -2130,6 +2226,24 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 		break;
 	}
 
+	switch (dev->board) {
+	case CX23885_BOARD_VIEWCAST_260E:
+		v4l2_i2c_new_subdev(&dev->v4l2_dev,
+				&dev->i2c_bus[0].i2c_adap,
+				"cs3308", 0x82 >> 1, NULL);
+		break;
+	case CX23885_BOARD_VIEWCAST_460E:
+		/* This cs3308 controls the audio from the breakout cable */
+		v4l2_i2c_new_subdev(&dev->v4l2_dev,
+				&dev->i2c_bus[0].i2c_adap,
+				"cs3308", 0x80 >> 1, NULL);
+		/* This cs3308 controls the audio from the onboard header */
+		v4l2_i2c_new_subdev(&dev->v4l2_dev,
+				&dev->i2c_bus[0].i2c_adap,
+				"cs3308", 0x82 >> 1, NULL);
+		break;
+	}
+
 	/* AUX-PLL 27MHz CLK */
 	switch (dev->board) {
 	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c
index e8f8472..722781b 100644
--- a/drivers/media/pci/cx23885/cx23885-core.c
+++ b/drivers/media/pci/cx23885/cx23885-core.c
@@ -968,6 +968,16 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 	call_all(dev, core, s_power, 0);
 	cx23885_ir_init(dev);
 
+	if (dev->board == CX23885_BOARD_VIEWCAST_460E) {
+		/*
+		 * GPIOs 9/8 are input detection bits for the breakout video
+		 * (gpio 8) and audio (gpio 9) cables. When they're attached,
+		 * this gpios are pulled high. Make sure these GPIOs are marked
+		 * as inputs.
+		 */
+		cx23885_gpio_enable(dev, 0x300, 0);
+	}
+
 	if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
 		if (cx23885_video_register(dev) < 0) {
 			printk(KERN_ERR "%s() Failed to register analog "
diff --git a/drivers/media/pci/cx23885/cx23885-i2c.c b/drivers/media/pci/cx23885/cx23885-i2c.c
index 1135ea3..ae061b3 100644
--- a/drivers/media/pci/cx23885/cx23885-i2c.c
+++ b/drivers/media/pci/cx23885/cx23885-i2c.c
@@ -279,6 +279,8 @@ static char *i2c_devs[128] = {
 	[0x10 >> 1] = "tda10048",
 	[0x12 >> 1] = "dib7000pc",
 	[0x1c >> 1] = "lgdt3303",
+	[0x80 >> 1] = "cs3308",
+	[0x82 >> 1] = "cs3308",
 	[0x86 >> 1] = "tda9887",
 	[0x32 >> 1] = "cx24227",
 	[0x88 >> 1] = "cx25837",
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index ad4d7e6..064e5fb 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -263,7 +263,9 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
 		(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) ||
 		(dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) ||
 		(dev->board == CX23885_BOARD_MYGICA_X8507) ||
-		(dev->board == CX23885_BOARD_AVERMEDIA_HC81R)) {
+		(dev->board == CX23885_BOARD_AVERMEDIA_HC81R) ||
+		(dev->board == CX23885_BOARD_VIEWCAST_260E) ||
+		(dev->board == CX23885_BOARD_VIEWCAST_460E)) {
 		/* Configure audio routing */
 		v4l2_subdev_call(dev->sd_cx25840, audio, s_routing,
 			INPUT(input)->amux, 0, 0);
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 9a8938b..b1a5409 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -101,6 +101,8 @@
 #define CX23885_BOARD_DVBSKY_T982              51
 #define CX23885_BOARD_HAUPPAUGE_HVR5525        52
 #define CX23885_BOARD_HAUPPAUGE_STARBURST      53
+#define CX23885_BOARD_VIEWCAST_260E            54
+#define CX23885_BOARD_VIEWCAST_460E            55
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 11/11] cx23885: video instead of vbi register used
  2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
                   ` (9 preceding siblings ...)
  2015-11-30 20:27 ` [PATCH 10/11] cx23885: add support for ViewCast 260e and 460e Hans Verkuil
@ 2015-11-30 20:27 ` Hans Verkuil
  10 siblings, 0 replies; 12+ messages in thread
From: Hans Verkuil @ 2015-11-30 20:27 UTC (permalink / raw)
  To: linux-media; +Cc: stoth, dheitmueller, Hans Verkuil

From: Hans Verkuil <hans.verkuil@cisco.com>

The VID_A_GPCNT register is for video, not vbi. Read from the right
register and don't write to the video register.

Based upon Devin's initial patch made for an older kernel which I
cleaned up and rebased. Thanks to Kernel Labs for that work.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/cx23885/cx23885-vbi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/media/pci/cx23885/cx23885-vbi.c b/drivers/media/pci/cx23885/cx23885-vbi.c
index cf3cb13..ab36d12 100644
--- a/drivers/media/pci/cx23885/cx23885-vbi.c
+++ b/drivers/media/pci/cx23885/cx23885-vbi.c
@@ -83,7 +83,7 @@ int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status)
 	if (status & VID_BC_MSK_VBI_RISCI1) {
 		dprintk(1, "%s() VID_BC_MSK_VBI_RISCI1\n", __func__);
 		spin_lock(&dev->slock);
-		count = cx_read(VID_A_GPCNT);
+		count = cx_read(VBI_A_GPCNT);
 		cx23885_video_wakeup(dev, &dev->vbiq, count);
 		spin_unlock(&dev->slock);
 		handled++;
@@ -103,7 +103,6 @@ static int cx23885_start_vbi_dma(struct cx23885_dev    *dev,
 				VBI_LINE_LENGTH, buf->risc.dma);
 
 	/* reset counter */
-	cx_write(VID_A_GPCNT_CTL, 3);
 	cx_write(VID_A_VBI_CTRL, 3);
 	cx_write(VBI_A_GPCNT_CTL, 3);
 	q->count = 0;
-- 
2.6.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-11-30 20:27 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-30 20:27 [PATCH 00/11] cx23885: cleanups, add ViewCast 260e/460e support Hans Verkuil
2015-11-30 20:27 ` [PATCH 01/11] cx23885: fix format/crop handling Hans Verkuil
2015-11-30 20:27 ` [PATCH 02/11] cx231xx: fix NTSC cropcap, add missing cropcap for 417 Hans Verkuil
2015-11-30 20:27 ` [PATCH 03/11] ivtv/cx18: fix inverted pixel aspect ratio Hans Verkuil
2015-11-30 20:27 ` [PATCH 04/11] cx25840: fix VBI support for cx23888 Hans Verkuil
2015-11-30 20:27 ` [PATCH 05/11] cx25840: more cx23888 register address changes Hans Verkuil
2015-11-30 20:27 ` [PATCH 06/11] cx25840: relax a Vsrc check Hans Verkuil
2015-11-30 20:27 ` [PATCH 07/11] cx25840: fix cx25840_s_stream for cx2388x and cx231xx Hans Verkuil
2015-11-30 20:27 ` [PATCH 08/11] cx25840: initialize the standard to NTSC_M Hans Verkuil
2015-11-30 20:27 ` [PATCH 09/11] cs3308: add new 8-channel volume control driver Hans Verkuil
2015-11-30 20:27 ` [PATCH 10/11] cx23885: add support for ViewCast 260e and 460e Hans Verkuil
2015-11-30 20:27 ` [PATCH 11/11] cx23885: video instead of vbi register used Hans Verkuil

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.