linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [REVIEW PATCH 00/42] go7007: complete overhaul
@ 2013-03-11 11:45 Hans Verkuil
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                   ` (2 more replies)
  0 siblings, 3 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein

Hi all,

This patch series updates the staging go7007 driver to the latest
V4L2 frameworks and actually makes it work reliably.

Some highlights:

- moved the custom i2c drivers to media/i2c.
- replaced the s2250-loader by a common loader for all the supported
  devices.
- replaced all MPEG-related custom ioctls by standard ioctls and FMT
  support.
- added the saa7134-go7007 combination (similar to the saa7134-empress).

In addition I've made some V4L2 core and saa7115 changes (the first 6
patches):

- eliminate false lockdep warnings when dealing with nested control
  handlers. This patch is a slightly modified version from the one Andy
  posted a long time ago.
- add support to easily test if any subdevices support a particular operation.
- fix a few bugs in the code that tests if an ioctl is available: it didn't
  take 'disabling of ioctls' into account.
- added additional configuration flags to saa7115, needed by the go7007.
- improved querystd support in saa7115.

This driver now passes all v4l2-compliance tests.

Volokh, I've merged your tw2804 v4l2 framework cleanup patches into one
with my modifications on top. I hope you don't mind.

It has been tested with:

- Plextor PX-TV402U (PAL model)
- Sensoray S2250S (generously provided by Sensoray, all audio inputs
  now work!)
- Sensoray Model 614 (saa7134+go7007 PCI board, generously provided by
  Sensoray)
- WIS X-Men II sensor board (generously provided by Sensoray)
- Adlink PCI-MPG24 surveillance board

Everything seems to work OK, but for two things:

- the WIS X-Men and tthe S2250 do not honor requested frameperiod changes
  using S_PARM. The others work fine, and I have no idea why these work
  differently.
- the bttv part of the Adlink card doesn't work for me: I just get black
  with fuzzy lines. This doesn't work in 3.8 either, so I don't know
  what's going on here. It's not related to my patch series, that's for
  sure. Volokh, can you test it as well?

What needs to be done to get this driver out of staging? The main thing
is the motion detection support. Volokh has some addition code for that,
and I want to experiment with motion detection for this card and the
solo6x10 card and see if I can come up with a nice API for that.

It would also be nice to get the s2250-board.c code make use of the already
existing i2c devices, but it is hooked up somewhat strangely, so I need to
look at that some day.

I also need to look at the firmware licensing. I think it is all OK, but
I need to check. For now all the firmwares are available here:

http://hverkuil.home.xs4all.nl/go7007-fw.tar.bz2

Just unpack in /lib/firmware.

I've moved all firmwares into a single go7007 directory. And the old .hex
files have been converted into binary format that the cypress loader expects.

Pete, can you test this for your S2251 USB device?

This week I'll also receive a Plextor PX-M402U to test with and an ADS DVD
XPress DX2 is also on its way (I did some ebay shopping!).

I plan on posting the pull request this Friday, so let me know if there are
any issues.

BTW, my git tree is available here:

http://git.linuxtv.org/hverkuil/media_tree.git/shortlog/refs/heads/go7007

Regards,

	Hans


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

* [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock
  2013-03-11 11:45 [REVIEW PATCH 00/42] go7007: complete overhaul Hans Verkuil
@ 2013-03-11 11:45 ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 02/42] v4l2-core: add code to check for specific ops Hans Verkuil
                     ` (41 more replies)
  2013-03-11 22:01 ` [REVIEW PATCH 00/42] go7007: complete overhaul Hans Verkuil
  2013-03-12 14:37 ` Darrick Burch
  2 siblings, 42 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

From: Andy Walls <awalls at>

When calling v4l2_ctrl_add_handler(), lockdep would detect a potential
recursive locking problem on a situation that is by design intended and
not a recursive lock.  This happened because all struct
v4l2_ctrl_handler.lock mutexes were created as members of the same lock
class in v4l2_ctrl_handler_init(), and v4l2_ctrl_add_handler() takes the
hdl->lock on two different v4l2_ctrl_handler instances.

This change breaks the large lockdep lock class for struct
v4l2_ctrl_handler.lock and breaks it into v4l2_ctrl_handler
instantiation specific lock classes with meaningful class names.

This will validly eliminate lockdep alarms for v4l2_ctrl_handler locking
validation, as long as the relationships between drivers adding v4l2
controls to their own handler from other v4l2 drivers' control handlers
remains straightforward.

struct v4l2_ctrl_handler.lock lock classes are created with names such
that the output of cat /proc/lockdep indicates where in the v4l2 driver
code v4l2_ctrl_handle_init() is being called on instantiations:

ffffffffa045f490 FD:   10 BD:    8 +.+...: cx2341x:1534:(hdl)->lock
ffffffffa0497d20 FD:   12 BD:    2 +.+.+.: saa7115:1581:(hdl)->lock
ffffffffa04ac660 FD:   14 BD:    2 +.+.+.: msp3400_driver:756:(hdl)->lock
ffffffffa0484b90 FD:   12 BD:    1 +.+.+.: ivtv_gpio:366:(&itv->hdl_gpio)->lock
ffffffffa04eb530 FD:   11 BD:    2 +.+.+.: cx25840_core:1982:(&state->hdl)->lock
ffffffffa04fbc80 FD:   11 BD:    3 +.+.+.: wm8775:246:(&state->hdl)->lock

Some lock chains, that were previously causing the recursion alarms, are
now visible in the output of cat /proc/lockdep_chains:

irq_context: 0
[ffffffffa0497d20] saa7115:1581:(hdl)->lock
[ffffffffa045f490] cx2341x:1534:(hdl)->lock

irq_context: 0
[ffffffffa04ac660] msp3400_driver:756:(hdl)->lock
[ffffffffa045f490] cx2341x:1534:(hdl)->lock

irq_context: 0
[ffffffffa0484b90] ivtv_gpio:366:(&itv->hdl_gpio)->lock
[ffffffffa045f490] cx2341x:1534:(hdl)->lock

irq_context: 0
[ffffffffa04eb530] cx25840_core:1982:(&state->hdl)->lock
[ffffffffa045f490] cx2341x:1534:(hdl)->lock

irq_context: 0
[ffffffffa04fbc80] wm8775:246:(&state->hdl)->lock
[ffffffffa045f490] cx2341x:1534:(hdl)->lock

Signed-off-by: Andy Walls <awalls <at> md.metrocast.net>
[hans.verkuil@cisco.com: keep mutex_init in v4l2_ctrl_handler_init_class]
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/v4l2-core/v4l2-ctrls.c |    8 +++++---
 include/media/v4l2-ctrls.h           |   29 ++++++++++++++++++++++++++---
 2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 6b28b58..b36d1ec 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1362,11 +1362,13 @@ static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
 }
 
 /* Initialize the handler */
-int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
-			   unsigned nr_of_controls_hint)
+int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
+				 unsigned nr_of_controls_hint,
+				 struct lock_class_key *key, const char *name)
 {
 	hdl->lock = &hdl->_lock;
 	mutex_init(hdl->lock);
+	lockdep_set_class_and_name(hdl->lock, key, name);
 	INIT_LIST_HEAD(&hdl->ctrls);
 	INIT_LIST_HEAD(&hdl->ctrl_refs);
 	hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
@@ -1375,7 +1377,7 @@ int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
 	hdl->error = hdl->buckets ? 0 : -ENOMEM;
 	return hdl->error;
 }
-EXPORT_SYMBOL(v4l2_ctrl_handler_init);
+EXPORT_SYMBOL(v4l2_ctrl_handler_init_class);
 
 /* Free all controls and control refs */
 void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index f00d42b..7343a27 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -259,7 +259,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 		    s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags);
 
 
-/** v4l2_ctrl_handler_init() - Initialize the control handler.
+/** v4l2_ctrl_handler_init_class() - Initialize the control handler.
   * @hdl:	The control handler.
   * @nr_of_controls_hint: A hint of how many controls this handler is
   *		expected to refer to. This is the total number, so including
@@ -268,12 +268,35 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
   *		are allocated) or the control lookup becomes slower (not enough
   *		buckets are allocated, so there are more slow list lookups).
   *		It will always work, though.
+  * @key:	Used by the lock validator if CONFIG_LOCKDEP is set.
+  * @name:	Used by the lock validator if CONFIG_LOCKDEP is set.
   *
   * Returns an error if the buckets could not be allocated. This error will
   * also be stored in @hdl->error.
+  *
+  * Never use this call directly, always use the v4l2_ctrl_handler_init
+  * macro that hides the @key and @name arguments.
   */
-int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
-			   unsigned nr_of_controls_hint);
+int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
+				 unsigned nr_of_controls_hint,
+				 struct lock_class_key *key, const char *name);
+
+#ifdef CONFIG_LOCKDEP
+#define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint)		\
+(									\
+	({								\
+		static struct lock_class_key _key;			\
+		v4l2_ctrl_handler_init_class(hdl, nr_of_controls_hint,	\
+					&_key,				\
+					KBUILD_BASENAME ":"		\
+					__stringify(__LINE__) ":"	\
+					"(" #hdl ")->_lock");		\
+	})								\
+)
+#else
+#define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint)		\
+	v4l2_ctrl_handler_init_class(hdl, nr_of_controls_hint, NULL, NULL)
+#endif
 
 /** v4l2_ctrl_handler_free() - Free all controls owned by the handler and free
   * the control list.
-- 
1.7.10.4


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

* [REVIEW PATCH 02/42] v4l2-core: add code to check for specific ops.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 03/42] v4l2-ioctl: check if an ioctl is valid Hans Verkuil
                     ` (40 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

This patch adds a v4l2_subdev_has_op() macro and a v4l2_device_has_op macro to
quickly check if a specific subdev or any subdev supports a particular subdev
operation.

This makes it easy for drivers to disable certain ioctls if none of the subdevs
supports the necessary functionality.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 include/media/v4l2-device.h |   13 +++++++++++++
 include/media/v4l2-subdev.h |    3 +++
 2 files changed, 16 insertions(+)

diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index d61febf..c9b1593 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -190,4 +190,17 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
 			##args);					\
 })
 
+#define v4l2_device_has_op(v4l2_dev, o, f)				\
+({									\
+	struct v4l2_subdev *__sd;					\
+	bool __result = false;						\
+	list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list) {		\
+		if (v4l2_subdev_has_op(__sd, o, f)) {			\
+			__result = true;				\
+			break;						\
+		}							\
+	}								\
+	__result;							\
+})
+
 #endif
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index b137a5e..0740c06 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -687,4 +687,7 @@ void v4l2_subdev_init(struct v4l2_subdev *sd,
 	((!(sd) || !(sd)->v4l2_dev || !(sd)->v4l2_dev->notify) ? -ENODEV : \
 	 (sd)->v4l2_dev->notify((sd), (notification), (arg)))
 
+#define v4l2_subdev_has_op(sd, o, f) \
+	((sd)->ops->o && (sd)->ops->o->f)
+
 #endif
-- 
1.7.10.4


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

* [REVIEW PATCH 03/42] v4l2-ioctl: check if an ioctl is valid.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 02/42] v4l2-core: add code to check for specific ops Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 04/42] saa7115: add config flag to change the IDQ polarity Hans Verkuil
                     ` (39 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Just checking if the op exists isn't correct, you should check if the ioctl
is valid (which implies that the op exists as well).

One exception is g_std: if current_norm is non-zero, then the g_std op may be
absent. This sort of weird behavior is one of the reasons why I am trying to
get rid of current_norm.

This patch fixes the case where the g/s_std op is set, but these ioctls are
disabled. This can happen in drivers supporting multiple models, some that
have TV input (and support the STD API) and some that have a sensor (and do
not support the STD API). In the latter case qv4l2 would still show the
Standards combobox.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/v4l2-core/v4l2-ioctl.c |   22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index aa6e7c7..b589c34 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -35,6 +35,8 @@
 	memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
 	0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
 
+#define is_valid_ioctl(vfd, cmd) test_bit(_IOC_NR(cmd), (vfd)->valid_ioctls)
+
 struct std_descr {
 	v4l2_std_id std;
 	const char *descr;
@@ -997,6 +999,7 @@ static int v4l_s_priority(const struct v4l2_ioctl_ops *ops,
 static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
+	struct video_device *vfd = video_devdata(file);
 	struct v4l2_input *p = arg;
 
 	/*
@@ -1005,11 +1008,11 @@ static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
 	 * driver. If the driver doesn't support these
 	 * for a specific input, it must override these flags.
 	 */
-	if (ops->vidioc_s_std)
+	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
 		p->capabilities |= V4L2_IN_CAP_STD;
-	if (ops->vidioc_s_dv_preset)
+	if (is_valid_ioctl(vfd, VIDIOC_S_DV_PRESET))
 		p->capabilities |= V4L2_IN_CAP_PRESETS;
-	if (ops->vidioc_s_dv_timings)
+	if (is_valid_ioctl(vfd, VIDIOC_S_DV_TIMINGS))
 		p->capabilities |= V4L2_IN_CAP_DV_TIMINGS;
 
 	return ops->vidioc_enum_input(file, fh, p);
@@ -1018,6 +1021,7 @@ static int v4l_enuminput(const struct v4l2_ioctl_ops *ops,
 static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
+	struct video_device *vfd = video_devdata(file);
 	struct v4l2_output *p = arg;
 
 	/*
@@ -1026,11 +1030,11 @@ static int v4l_enumoutput(const struct v4l2_ioctl_ops *ops,
 	 * driver. If the driver doesn't support these
 	 * for a specific output, it must override these flags.
 	 */
-	if (ops->vidioc_s_std)
+	if (is_valid_ioctl(vfd, VIDIOC_S_STD))
 		p->capabilities |= V4L2_OUT_CAP_STD;
-	if (ops->vidioc_s_dv_preset)
+	if (is_valid_ioctl(vfd, VIDIOC_S_DV_PRESET))
 		p->capabilities |= V4L2_OUT_CAP_PRESETS;
-	if (ops->vidioc_s_dv_timings)
+	if (is_valid_ioctl(vfd, VIDIOC_S_DV_TIMINGS))
 		p->capabilities |= V4L2_OUT_CAP_DV_TIMINGS;
 
 	return ops->vidioc_enum_output(file, fh, p);
@@ -1513,7 +1517,7 @@ static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 		return -EINVAL;
 	p->parm.capture.readbuffers = 2;
-	if (ops->vidioc_g_std)
+	if (is_valid_ioctl(vfd, VIDIOC_G_STD) && ops->vidioc_g_std)
 		ret = ops->vidioc_g_std(file, fh, &std);
 	if (ret == 0)
 		v4l2_video_std_frame_period(std,
@@ -1873,7 +1877,7 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
 		return -EINVAL;
 	if (ops->vidioc_enum_freq_bands)
 		return ops->vidioc_enum_freq_bands(file, fh, p);
-	if (ops->vidioc_g_tuner) {
+	if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) {
 		struct v4l2_tuner t = {
 			.index = p->tuner,
 			.type = type,
@@ -1891,7 +1895,7 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops,
 			V4L2_BAND_MODULATION_FM : V4L2_BAND_MODULATION_VSB;
 		return 0;
 	}
-	if (ops->vidioc_g_modulator) {
+	if (is_valid_ioctl(vfd, VIDIOC_G_MODULATOR)) {
 		struct v4l2_modulator m = {
 			.index = p->tuner,
 		};
-- 
1.7.10.4


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

* [REVIEW PATCH 04/42] saa7115: add config flag to change the IDQ polarity.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 02/42] v4l2-core: add code to check for specific ops Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 03/42] v4l2-ioctl: check if an ioctl is valid Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 05/42] saa7115: improve querystd handling for the saa7115 Hans Verkuil
                     ` (38 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Needed by the go7007 driver: it assumes a different polarity of the IDQ
signal, so we need to be able to tell the saa7115 about this.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/saa7115.c |    6 ++++++
 include/media/saa7115.h     |   31 +++++++++++++++++++++----------
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index 6b6788c..f249b20 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -1259,6 +1259,12 @@ static int saa711x_s_routing(struct v4l2_subdev *sd,
 				(saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
 				(state->output & 0x01));
 	}
+	if (state->ident > V4L2_IDENT_SAA7111A) {
+		if (config & SAA7115_IDQ_IS_DEFAULT)
+			saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x20);
+		else
+			saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x21);
+	}
 	return 0;
 }
 
diff --git a/include/media/saa7115.h b/include/media/saa7115.h
index bab2127..8b2ecc6 100644
--- a/include/media/saa7115.h
+++ b/include/media/saa7115.h
@@ -21,6 +21,8 @@
 #ifndef _SAA7115_H_
 #define _SAA7115_H_
 
+/* s_routing inputs, outputs, and config */
+
 /* SAA7111/3/4/5 HW inputs */
 #define SAA7115_COMPOSITE0 0
 #define SAA7115_COMPOSITE1 1
@@ -33,24 +35,33 @@
 #define SAA7115_SVIDEO2    8
 #define SAA7115_SVIDEO3    9
 
-/* SAA7115 v4l2_crystal_freq frequency values */
-#define SAA7115_FREQ_32_11_MHZ  32110000   /* 32.11 MHz crystal, SAA7114/5 only */
-#define SAA7115_FREQ_24_576_MHZ 24576000   /* 24.576 MHz crystal */
-
-/* SAA7115 v4l2_crystal_freq audio clock control flags */
-#define SAA7115_FREQ_FL_UCGC   (1 << 0)	   /* SA 3A[7], UCGC, SAA7115 only */
-#define SAA7115_FREQ_FL_CGCDIV (1 << 1)	   /* SA 3A[6], CGCDIV, SAA7115 only */
-#define SAA7115_FREQ_FL_APLL   (1 << 2)	   /* SA 3A[3], APLL, SAA7114/5 only */
-
+/* outputs */
 #define SAA7115_IPORT_ON    	1
 #define SAA7115_IPORT_OFF   	0
 
-/* SAA7111 specific output flags */
+/* SAA7111 specific outputs. */
 #define SAA7111_VBI_BYPASS 	2
 #define SAA7111_FMT_YUV422      0x00
 #define SAA7111_FMT_RGB 	0x40
 #define SAA7111_FMT_CCIR 	0x80
 #define SAA7111_FMT_YUV411 	0xc0
 
+/* config flags */
+/* Register 0x85 should set bit 0 to 0 (it's 1 by default). This bit
+ * controls the IDQ signal polarity which is set to 'inverted' if the bit
+ * it 1 and to 'default' if it is 0. */
+#define SAA7115_IDQ_IS_DEFAULT  (1 << 0)
+
+/* s_crystal_freq values and flags */
+
+/* SAA7115 v4l2_crystal_freq frequency values */
+#define SAA7115_FREQ_32_11_MHZ  32110000   /* 32.11 MHz crystal, SAA7114/5 only */
+#define SAA7115_FREQ_24_576_MHZ 24576000   /* 24.576 MHz crystal */
+
+/* SAA7115 v4l2_crystal_freq audio clock control flags */
+#define SAA7115_FREQ_FL_UCGC   (1 << 0)	   /* SA 3A[7], UCGC, SAA7115 only */
+#define SAA7115_FREQ_FL_CGCDIV (1 << 1)	   /* SA 3A[6], CGCDIV, SAA7115 only */
+#define SAA7115_FREQ_FL_APLL   (1 << 2)	   /* SA 3A[3], APLL, SAA7114/5 only */
+
 #endif
 
-- 
1.7.10.4


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

* [REVIEW PATCH 05/42] saa7115: improve querystd handling for the saa7115.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (2 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 04/42] saa7115: add config flag to change the IDQ polarity Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 06/42] saa7115: add support for double-rate ASCLK Hans Verkuil
                     ` (37 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

The saa7115 has better PAL/NTSC detection, so it can detect PAL even
though the chip is currently set up for NTSC.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/saa7115.c |   56 +++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index f249b20..d301442 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -1360,6 +1360,34 @@ static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
 	 */
 
 	reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
+
+	if (state->ident == V4L2_IDENT_SAA7115) {
+		reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
+
+		v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
+
+		switch (reg1e & 0x03) {
+		case 1:
+			*std &= V4L2_STD_NTSC;
+			break;
+		case 2:
+			/*
+			 * V4L2_STD_PAL just cover the european PAL standards.
+			 * This is wrong, as the device could also be using an
+			 * other PAL standard.
+			 */
+			*std &= V4L2_STD_PAL   | V4L2_STD_PAL_N  | V4L2_STD_PAL_Nc |
+				V4L2_STD_PAL_M | V4L2_STD_PAL_60;
+			break;
+		case 3:
+			*std &= V4L2_STD_SECAM;
+			break;
+		default:
+			/* Can't detect anything */
+			break;
+		}
+	}
+
 	v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f);
 
 	/* horizontal/vertical not locked */
@@ -1371,34 +1399,6 @@ static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
 	else
 		*std &= V4L2_STD_625_50;
 
-	if (state->ident != V4L2_IDENT_SAA7115)
-		goto ret;
-
-	reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
-
-	switch (reg1e & 0x03) {
-	case 1:
-		*std &= V4L2_STD_NTSC;
-		break;
-	case 2:
-		/*
-		 * V4L2_STD_PAL just cover the european PAL standards.
-		 * This is wrong, as the device could also be using an
-		 * other PAL standard.
-		 */
-		*std &= V4L2_STD_PAL   | V4L2_STD_PAL_N  | V4L2_STD_PAL_Nc |
-			V4L2_STD_PAL_M | V4L2_STD_PAL_60;
-		break;
-	case 3:
-		*std &= V4L2_STD_SECAM;
-		break;
-	default:
-		/* Can't detect anything */
-		break;
-	}
-
-	v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
-
 ret:
 	v4l2_dbg(1, debug, sd, "detected std mask = %08Lx\n", *std);
 
-- 
1.7.10.4


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

* [REVIEW PATCH 06/42] saa7115: add support for double-rate ASCLK
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (3 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 05/42] saa7115: improve querystd handling for the saa7115 Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 07/42] go7007: fix i2c_xfer return codes Hans Verkuil
                     ` (36 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Some devices expect a double rate ASCLK. Add a flag to let the driver know
through the s_crystal_freq call.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/saa7115.c |   16 +++++++++++-----
 include/media/saa7115.h     |    7 ++++---
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index d301442..9d3dbb3 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -83,9 +83,10 @@ struct saa711x_state {
 	u32 ident;
 	u32 audclk_freq;
 	u32 crystal_freq;
-	u8 ucgc;
+	bool ucgc;
 	u8 cgcdiv;
-	u8 apll;
+	bool apll;
+	bool double_asclk;
 };
 
 static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
@@ -732,8 +733,12 @@ static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
 	if (state->apll)
 		acc |= 0x08;
 
+	if (state->double_asclk) {
+		acpf <<= 1;
+		acni <<= 1;
+	}
 	saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
-	saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
+	saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10 << state->double_asclk);
 	saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
 
 	saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
@@ -1302,9 +1307,10 @@ static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, u32 freq, u32 flags)
 	if (freq != SAA7115_FREQ_32_11_MHZ && freq != SAA7115_FREQ_24_576_MHZ)
 		return -EINVAL;
 	state->crystal_freq = freq;
+	state->double_asclk = flags & SAA7115_FREQ_FL_DOUBLE_ASCLK;
 	state->cgcdiv = (flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
-	state->ucgc = (flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
-	state->apll = (flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
+	state->ucgc = flags & SAA7115_FREQ_FL_UCGC;
+	state->apll = flags & SAA7115_FREQ_FL_APLL;
 	saa711x_s_clock_freq(sd, state->audclk_freq);
 	return 0;
 }
diff --git a/include/media/saa7115.h b/include/media/saa7115.h
index 8b2ecc6..4079186 100644
--- a/include/media/saa7115.h
+++ b/include/media/saa7115.h
@@ -59,9 +59,10 @@
 #define SAA7115_FREQ_24_576_MHZ 24576000   /* 24.576 MHz crystal */
 
 /* SAA7115 v4l2_crystal_freq audio clock control flags */
-#define SAA7115_FREQ_FL_UCGC   (1 << 0)	   /* SA 3A[7], UCGC, SAA7115 only */
-#define SAA7115_FREQ_FL_CGCDIV (1 << 1)	   /* SA 3A[6], CGCDIV, SAA7115 only */
-#define SAA7115_FREQ_FL_APLL   (1 << 2)	   /* SA 3A[3], APLL, SAA7114/5 only */
+#define SAA7115_FREQ_FL_UCGC         (1 << 0) /* SA 3A[7], UCGC, SAA7115 only */
+#define SAA7115_FREQ_FL_CGCDIV       (1 << 1) /* SA 3A[6], CGCDIV, SAA7115 only */
+#define SAA7115_FREQ_FL_APLL         (1 << 2) /* SA 3A[3], APLL, SAA7114/5 only */
+#define SAA7115_FREQ_FL_DOUBLE_ASCLK (1 << 3) /* SA 39, LRDIV, SAA7114/5 only */
 
 #endif
 
-- 
1.7.10.4


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

* [REVIEW PATCH 07/42] go7007: fix i2c_xfer return codes.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (4 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 06/42] saa7115: add support for double-rate ASCLK Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 08/42] tuner: add Sony BTF tuners Hans Verkuil
                     ` (35 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

The i2c_xfer functions didn't return the proper error codes and (especially
important) on success they returned 0 instead of the number of transferred
messages.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-i2c.c |   20 ++++++++++----------
 drivers/staging/media/go7007/go7007-usb.c |    6 +++---
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-i2c.c b/drivers/staging/media/go7007/go7007-i2c.c
index 39456a3..1d0a400 100644
--- a/drivers/staging/media/go7007/go7007-i2c.c
+++ b/drivers/staging/media/go7007/go7007-i2c.c
@@ -52,11 +52,11 @@ static DEFINE_MUTEX(adlink_mpg24_i2c_lock);
 static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
 		u16 command, int flags, u8 *data)
 {
-	int i, ret = -1;
+	int i, ret = -EIO;
 	u16 val;
 
 	if (go->status == STATUS_SHUTDOWN)
-		return -1;
+		return -ENODEV;
 
 #ifdef GO7007_I2C_DEBUG
 	if (read)
@@ -146,7 +146,7 @@ static int go7007_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
 	struct go7007 *go = i2c_get_adapdata(adapter);
 
 	if (size != I2C_SMBUS_BYTE_DATA)
-		return -1;
+		return -EIO;
 	return go7007_i2c_xfer(go, addr, read_write == I2C_SMBUS_READ, command,
 			flags & I2C_CLIENT_SCCB ? 0x10 : 0x00, &data->byte);
 }
@@ -170,26 +170,26 @@ static int go7007_i2c_master_xfer(struct i2c_adapter *adapter,
 					(msgs[i].flags & I2C_M_RD) ||
 					!(msgs[i + 1].flags & I2C_M_RD) ||
 					msgs[i + 1].len != 1)
-				return -1;
+				return -EIO;
 			if (go7007_i2c_xfer(go, msgs[i].addr, 1,
 					(msgs[i].buf[0] << 8) | msgs[i].buf[1],
 					0x01, &msgs[i + 1].buf[0]) < 0)
-				return -1;
+				return -EIO;
 			++i;
 		} else if (msgs[i].len == 3) {
 			if (msgs[i].flags & I2C_M_RD)
-				return -1;
+				return -EIO;
 			if (msgs[i].len != 3)
-				return -1;
+				return -EIO;
 			if (go7007_i2c_xfer(go, msgs[i].addr, 0,
 					(msgs[i].buf[0] << 8) | msgs[i].buf[1],
 					0x01, &msgs[i].buf[2]) < 0)
-				return -1;
+				return -EIO;
 		} else
-			return -1;
+			return -EIO;
 	}
 
-	return 0;
+	return num;
 }
 
 static u32 go7007_functionality(struct i2c_adapter *adapter)
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 9dbf5ec..914b247 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -876,10 +876,10 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
 	struct go7007_usb *usb = go->hpi_context;
 	u8 buf[16];
 	int buf_len, i;
-	int ret = -1;
+	int ret = -EIO;
 
 	if (go->status == STATUS_SHUTDOWN)
-		return -1;
+		return -ENODEV;
 
 	mutex_lock(&usb->i2c_lock);
 
@@ -936,7 +936,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
 			memcpy(msgs[i].buf, buf + 1, msgs[i].len);
 		}
 	}
-	ret = 0;
+	ret = num;
 
 i2c_done:
 	mutex_unlock(&usb->i2c_lock);
-- 
1.7.10.4


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

* [REVIEW PATCH 08/42] tuner: add Sony BTF tuners
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (5 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 07/42] go7007: fix i2c_xfer return codes Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 09/42] sony-btf-mpx: the MPX driver for the sony BTF PAL/SECAM tuner Hans Verkuil
                     ` (34 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

This adds support for three Sony BTF tuners:

TUNER_SONY_BTF_PG472Z: PAL+SECAM
TUNER_SONY_BTF_PK467Z: NTSC-M-JP
TUNER_SONY_BTF_PB463Z: NTSC-M

These come from the go7007 staging driver where they were implemented in
the wis-sony-tuner i2c driver.

Adding support for these tuners to tuner-types.c is the first step towards
removing the wis-sony-tuner driver.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 Documentation/video4linux/CARDLIST.tuner   |    3 ++
 drivers/media/tuners/tuner-types.c         |   69 ++++++++++++++++++++++++++++
 drivers/staging/media/go7007/go7007-usb.c  |    1 +
 drivers/staging/media/go7007/go7007-v4l2.c |    1 +
 drivers/staging/media/go7007/wis-i2c.h     |    6 ---
 include/media/tuner.h                      |    4 ++
 6 files changed, 78 insertions(+), 6 deletions(-)

diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index c83f6e4..5b83a3f 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -86,3 +86,6 @@ tuner=85 - Philips FQ1236 MK5
 tuner=86 - Tena TNF5337 MFD
 tuner=87 - Xceive 4000 tuner
 tuner=88 - Xceive 5000C tuner
+tuner=89 - Sony PAL+SECAM (BTF-PG472Z)
+tuner=90 - Sony NTSC-M-JP (BTF-PK467Z)
+tuner=91 - Sony NTSC-M (BTF-PB463Z)
diff --git a/drivers/media/tuners/tuner-types.c b/drivers/media/tuners/tuner-types.c
index 2da4440..98bc15a 100644
--- a/drivers/media/tuners/tuner-types.c
+++ b/drivers/media/tuners/tuner-types.c
@@ -1381,6 +1381,58 @@ static struct tuner_params tuner_philips_fq1236_mk5_params[] = {
 	},
 };
 
+/* --------- Sony BTF-PG472Z PAL/SECAM ------- */
+
+static struct tuner_range tuner_sony_btf_pg472z_ranges[] = {
+	{ 16 * 144.25 /*MHz*/, 0xc6, 0x01, },
+	{ 16 * 427.25 /*MHz*/, 0xc6, 0x02, },
+	{ 16 * 999.99        , 0xc6, 0x04, },
+};
+
+static struct tuner_params tuner_sony_btf_pg472z_params[] = {
+	{
+		.type   = TUNER_PARAM_TYPE_PAL,
+		.ranges = tuner_sony_btf_pg472z_ranges,
+		.count  = ARRAY_SIZE(tuner_sony_btf_pg472z_ranges),
+		.has_tda9887 = 1,
+		.port1_active = 1,
+		.port2_invert_for_secam_lc = 1,
+	},
+};
+
+/* 90-99 */
+/* --------- Sony BTF-PG467Z NTSC-M-JP ------- */
+
+static struct tuner_range tuner_sony_btf_pg467z_ranges[] = {
+	{ 16 * 220.25 /*MHz*/, 0xc6, 0x01, },
+	{ 16 * 467.25 /*MHz*/, 0xc6, 0x02, },
+	{ 16 * 999.99        , 0xc6, 0x04, },
+};
+
+static struct tuner_params tuner_sony_btf_pg467z_params[] = {
+	{
+		.type   = TUNER_PARAM_TYPE_NTSC,
+		.ranges = tuner_sony_btf_pg467z_ranges,
+		.count  = ARRAY_SIZE(tuner_sony_btf_pg467z_ranges),
+	},
+};
+
+/* --------- Sony BTF-PG463Z NTSC-M ------- */
+
+static struct tuner_range tuner_sony_btf_pg463z_ranges[] = {
+	{ 16 * 130.25 /*MHz*/, 0xc6, 0x01, },
+	{ 16 * 364.25 /*MHz*/, 0xc6, 0x02, },
+	{ 16 * 999.99        , 0xc6, 0x04, },
+};
+
+static struct tuner_params tuner_sony_btf_pg463z_params[] = {
+	{
+		.type   = TUNER_PARAM_TYPE_NTSC,
+		.ranges = tuner_sony_btf_pg463z_ranges,
+		.count  = ARRAY_SIZE(tuner_sony_btf_pg463z_ranges),
+	},
+};
+
 /* --------------------------------------------------------------------- */
 
 struct tunertype tuners[] = {
@@ -1872,6 +1924,23 @@ struct tunertype tuners[] = {
 		.name   = "Xceive 5000C tuner",
 		/* see xc5000.c for details */
 	},
+	[TUNER_SONY_BTF_PG472Z] = {
+		.name   = "Sony BTF-PG472Z PAL/SECAM",
+		.params = tuner_sony_btf_pg472z_params,
+		.count  = ARRAY_SIZE(tuner_sony_btf_pg472z_params),
+	},
+
+	/* 90-99 */
+	[TUNER_SONY_BTF_PK467Z] = {
+		.name   = "Sony BTF-PK467Z NTSC-M-JP",
+		.params = tuner_sony_btf_pg467z_params,
+		.count  = ARRAY_SIZE(tuner_sony_btf_pg467z_params),
+	},
+	[TUNER_SONY_BTF_PB463Z] = {
+		.name   = "Sony BTF-PB463Z NTSC-M",
+		.params = tuner_sony_btf_pg463z_params,
+		.count  = ARRAY_SIZE(tuner_sony_btf_pg463z_params),
+	},
 };
 EXPORT_SYMBOL(tuners);
 
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 914b247..3333a8f 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -27,6 +27,7 @@
 #include <linux/i2c.h>
 #include <asm/byteorder.h>
 #include <media/tvaudio.h>
+#include <media/tuner.h>
 
 #include "go7007-priv.h"
 #include "wis-i2c.h"
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index cb9fe33..e115132 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -1238,6 +1238,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 	if (!go->i2c_adapter_online)
 		return -EIO;
 
+	strlcpy(t->name, "Tuner", sizeof(t->name));
 	return call_all(&go->v4l2_dev, tuner, g_tuner, t);
 }
 
diff --git a/drivers/staging/media/go7007/wis-i2c.h b/drivers/staging/media/go7007/wis-i2c.h
index 6d09c06..97763db 100644
--- a/drivers/staging/media/go7007/wis-i2c.h
+++ b/drivers/staging/media/go7007/wis-i2c.h
@@ -34,9 +34,3 @@ struct video_decoder_resolution {
 
 #define	DECODER_SET_RESOLUTION	_IOW('d', 200, struct video_decoder_resolution)
 #define	DECODER_SET_CHANNEL	_IOW('d', 201, int)
-
-/* Sony tuner types */
-
-#define TUNER_SONY_BTF_PG472Z		200
-#define TUNER_SONY_BTF_PK467Z		201
-#define TUNER_SONY_BTF_PB463Z		202
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 926aff9..24eaafe 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -138,6 +138,10 @@
 #define TUNER_XC4000			87	/* Xceive Silicon Tuner */
 #define TUNER_XC5000C			88	/* Xceive Silicon Tuner */
 
+#define TUNER_SONY_BTF_PG472Z		89	/* PAL+SECAM */
+#define TUNER_SONY_BTF_PK467Z		90	/* NTSC_JP */
+#define TUNER_SONY_BTF_PB463Z		91	/* NTSC */
+
 /* tv card specific */
 #define TDA9887_PRESENT 		(1<<0)
 #define TDA9887_PORT1_INACTIVE 		(1<<1)
-- 
1.7.10.4


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

* [REVIEW PATCH 09/42] sony-btf-mpx: the MPX driver for the sony BTF PAL/SECAM tuner
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (6 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 08/42] tuner: add Sony BTF tuners Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-24 15:21     ` Mauro Carvalho Chehab
  2013-03-11 11:45   ` [REVIEW PATCH 10/42] ov7640: add new ov7640 driver Hans Verkuil
                     ` (33 subsequent siblings)
  41 siblings, 1 reply; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

The Sony BTF PG472Z has an internal MPX to deal with mono/stereo/bilingual
audio. This is split off from the wis-sony-tuner driver that is part of
the go7007 driver as it should be a separate i2c sub-device driver.

The wis-sony-tuner is really three i2c devices: a standard tuner, a tda9887
compatible demodulator and this mpx. After this patch the wis-sony-tuner
can be replaced by this driver and the standard tuner driver.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/Kconfig        |   11 +-
 drivers/media/i2c/Makefile       |    1 +
 drivers/media/i2c/sony-btf-mpx.c |  399 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 410 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/i2c/sony-btf-mpx.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 7b771ba..70dbae2 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -133,7 +133,7 @@ config VIDEO_WM8739
 	  module will be called wm8739.
 
 config VIDEO_VP27SMPX
-	tristate "Panasonic VP27s internal MPX"
+	tristate "Panasonic VP27's internal MPX"
 	depends on VIDEO_V4L2 && I2C
 	---help---
 	  Support for the internal MPX of the Panasonic VP27s tuner.
@@ -141,6 +141,15 @@ config VIDEO_VP27SMPX
 	  To compile this driver as a module, choose M here: the
 	  module will be called vp27smpx.
 
+config VIDEO_SONY_BTF_MPX
+	tristate "Sony BTF's internal MPX"
+	depends on VIDEO_V4L2 && I2C
+	help
+	  Support for the internal MPX of the Sony BTF-PG472Z tuner.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sony-btf-mpx.
+
 comment "RDS decoders"
 
 config VIDEO_SAA6588
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index cfefd30..4c57075 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
 obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
 obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
 obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
+obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
 obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
 obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
 obj-$(CONFIG_VIDEO_OV7670) 	+= ov7670.o
diff --git a/drivers/media/i2c/sony-btf-mpx.c b/drivers/media/i2c/sony-btf-mpx.c
new file mode 100644
index 0000000..bc73e8f
--- /dev/null
+++ b/drivers/media/i2c/sony-btf-mpx.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/tuner.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <linux/slab.h>
+
+MODULE_DESCRIPTION("sony-btf-mpx driver");
+MODULE_LICENSE("GPL v2");
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on\n");
+
+/* #define MPX_DEBUG */
+
+/*
+ * Note:
+ *
+ * AS(IF/MPX) pin:      LOW      HIGH/OPEN
+ * IF/MPX address:   0x42/0x40   0x43/0x44
+ */
+
+
+static int force_mpx_mode = -1;
+module_param(force_mpx_mode, int, 0644);
+
+struct sony_btf_mpx {
+	struct v4l2_subdev sd;
+	int mpxmode;
+	u32 audmode;
+};
+
+static inline struct sony_btf_mpx *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct sony_btf_mpx, sd);
+}
+
+static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
+{
+	u8 buffer[5];
+	struct i2c_msg msg;
+
+	buffer[0] = dev;
+	buffer[1] = addr >> 8;
+	buffer[2] = addr & 0xff;
+	buffer[3] = val >> 8;
+	buffer[4] = val & 0xff;
+	msg.addr = client->addr;
+	msg.flags = 0;
+	msg.len = 5;
+	msg.buf = buffer;
+	i2c_transfer(client->adapter, &msg, 1);
+	return 0;
+}
+
+/*
+ * MPX register values for the BTF-PG472Z:
+ *
+ *                                 FM_     NICAM_  SCART_
+ *          MODUS  SOURCE    ACB   PRESCAL PRESCAL PRESCAL SYSTEM  VOLUME
+ *         10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000
+ *         ---------------------------------------------------------------
+ * Auto     1003    0020    0100    2603    5000    XXXX    0001    7500
+ *
+ * B/G
+ *  Mono    1003    0020    0100    2603    5000    XXXX    0003    7500
+ *  A2      1003    0020    0100    2601    5000    XXXX    0003    7500
+ *  NICAM   1003    0120    0100    2603    5000    XXXX    0008    7500
+ *
+ * I
+ *  Mono    1003    0020    0100    2603    7900    XXXX    000A    7500
+ *  NICAM   1003    0120    0100    2603    7900    XXXX    000A    7500
+ *
+ * D/K
+ *  Mono    1003    0020    0100    2603    5000    XXXX    0004    7500
+ *  A2-1    1003    0020    0100    2601    5000    XXXX    0004    7500
+ *  A2-2    1003    0020    0100    2601    5000    XXXX    0005    7500
+ *  A2-3    1003    0020    0100    2601    5000    XXXX    0007    7500
+ *  NICAM   1003    0120    0100    2603    5000    XXXX    000B    7500
+ *
+ * L/L'
+ *  Mono    0003    0200    0100    7C03    5000    2200    0009    7500
+ *  NICAM   0003    0120    0100    7C03    5000    XXXX    0009    7500
+ *
+ * M
+ *  Mono    1003    0200    0100    2B03    5000    2B00    0002    7500
+ *
+ * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX.
+ *
+ * Bilingual selection in A2/NICAM:
+ *
+ *         High byte of SOURCE     Left chan   Right chan
+ *                 0x01              MAIN         SUB
+ *                 0x03              MAIN         MAIN
+ *                 0x04              SUB          SUB
+ *
+ * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or
+ * 0x00 (all other bands).  Force mono in A2 with FMONO_A2:
+ *
+ *                      FMONO_A2
+ *                      10/0022
+ *                      --------
+ *     Forced mono ON     07F0
+ *     Forced mono OFF    0190
+ */
+
+static const struct {
+	enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
+	u16 modus;
+	u16 source;
+	u16 acb;
+	u16 fm_prescale;
+	u16 nicam_prescale;
+	u16 scart_prescale;
+	u16 system;
+	u16 volume;
+} mpx_audio_modes[] = {
+	/* Auto */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
+					0x5000, 0x0000, 0x0001, 0x7500 },
+	/* B/G Mono */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
+					0x5000, 0x0000, 0x0003, 0x7500 },
+	/* B/G A2 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
+					0x5000, 0x0000, 0x0003, 0x7500 },
+	/* B/G NICAM */ { AUD_NICAM,	0x1003, 0x0120, 0x0100, 0x2603,
+					0x5000, 0x0000, 0x0008, 0x7500 },
+	/* I Mono */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
+					0x7900, 0x0000, 0x000A, 0x7500 },
+	/* I NICAM */	{ AUD_NICAM,	0x1003, 0x0120, 0x0100, 0x2603,
+					0x7900, 0x0000, 0x000A, 0x7500 },
+	/* D/K Mono */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
+					0x5000, 0x0000, 0x0004, 0x7500 },
+	/* D/K A2-1 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
+					0x5000, 0x0000, 0x0004, 0x7500 },
+	/* D/K A2-2 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
+					0x5000, 0x0000, 0x0005, 0x7500 },
+	/* D/K A2-3 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
+					0x5000, 0x0000, 0x0007, 0x7500 },
+	/* D/K NICAM */	{ AUD_NICAM,	0x1003, 0x0120, 0x0100, 0x2603,
+					0x5000, 0x0000, 0x000B, 0x7500 },
+	/* L/L' Mono */	{ AUD_MONO,	0x0003, 0x0200, 0x0100, 0x7C03,
+					0x5000, 0x2200, 0x0009, 0x7500 },
+	/* L/L' NICAM */{ AUD_NICAM_L,	0x0003, 0x0120, 0x0100, 0x7C03,
+					0x5000, 0x0000, 0x0009, 0x7500 },
+};
+
+#define MPX_NUM_MODES	ARRAY_SIZE(mpx_audio_modes)
+
+static int mpx_setup(struct sony_btf_mpx *t)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+	u16 source = 0;
+	u8 buffer[3];
+	struct i2c_msg msg;
+	int mode = t->mpxmode;
+
+	/* reset MPX */
+	buffer[0] = 0x00;
+	buffer[1] = 0x80;
+	buffer[2] = 0x00;
+	msg.addr = client->addr;
+	msg.flags = 0;
+	msg.len = 3;
+	msg.buf = buffer;
+	i2c_transfer(client->adapter, &msg, 1);
+	buffer[1] = 0x00;
+	i2c_transfer(client->adapter, &msg, 1);
+
+	if (t->audmode != V4L2_TUNER_MODE_MONO)
+		mode++;
+
+	if (mpx_audio_modes[mode].audio_mode != AUD_MONO) {
+		switch (t->audmode) {
+		case V4L2_TUNER_MODE_MONO:
+			switch (mpx_audio_modes[mode].audio_mode) {
+			case AUD_A2:
+				source = mpx_audio_modes[mode].source;
+				break;
+			case AUD_NICAM:
+				source = 0x0000;
+				break;
+			case AUD_NICAM_L:
+				source = 0x0200;
+				break;
+			default:
+				break;
+			}
+			break;
+		case V4L2_TUNER_MODE_STEREO:
+			source = mpx_audio_modes[mode].source;
+			break;
+		case V4L2_TUNER_MODE_LANG1:
+			source = 0x0300;
+			break;
+		case V4L2_TUNER_MODE_LANG2:
+			source = 0x0400;
+			break;
+		}
+		source |= mpx_audio_modes[mode].source & 0x00ff;
+	} else
+		source = mpx_audio_modes[mode].source;
+
+	mpx_write(client, 0x10, 0x0030, mpx_audio_modes[mode].modus);
+	mpx_write(client, 0x12, 0x0008, source);
+	mpx_write(client, 0x12, 0x0013, mpx_audio_modes[mode].acb);
+	mpx_write(client, 0x12, 0x000e,
+			mpx_audio_modes[mode].fm_prescale);
+	mpx_write(client, 0x12, 0x0010,
+			mpx_audio_modes[mode].nicam_prescale);
+	mpx_write(client, 0x12, 0x000d,
+			mpx_audio_modes[mode].scart_prescale);
+	mpx_write(client, 0x10, 0x0020, mpx_audio_modes[mode].system);
+	mpx_write(client, 0x12, 0x0000, mpx_audio_modes[mode].volume);
+	if (mpx_audio_modes[mode].audio_mode == AUD_A2)
+		mpx_write(client, 0x10, 0x0022,
+			t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190);
+
+#ifdef MPX_DEBUG
+	{
+		u8 buf1[3], buf2[2];
+		struct i2c_msg msgs[2];
+
+		v4l2_info(client,
+			"MPX registers: %04x %04x %04x %04x %04x %04x %04x %04x\n",
+			mpx_audio_modes[mode].modus,
+			source,
+			mpx_audio_modes[mode].acb,
+			mpx_audio_modes[mode].fm_prescale,
+			mpx_audio_modes[mode].nicam_prescale,
+			mpx_audio_modes[mode].scart_prescale,
+			mpx_audio_modes[mode].system,
+			mpx_audio_modes[mode].volume);
+		buf1[0] = 0x11;
+		buf1[1] = 0x00;
+		buf1[2] = 0x7e;
+		msgs[0].addr = client->addr;
+		msgs[0].flags = 0;
+		msgs[0].len = 3;
+		msgs[0].buf = buf1;
+		msgs[1].addr = client->addr;
+		msgs[1].flags = I2C_M_RD;
+		msgs[1].len = 2;
+		msgs[1].buf = buf2;
+		i2c_transfer(client->adapter, msgs, 2);
+		v4l2_info(client, "MPX system: %02x%02x\n",
+				buf2[0], buf2[1]);
+		buf1[0] = 0x11;
+		buf1[1] = 0x02;
+		buf1[2] = 0x00;
+		i2c_transfer(client->adapter, msgs, 2);
+		v4l2_info(client, "MPX status: %02x%02x\n",
+				buf2[0], buf2[1]);
+	}
+#endif
+	return 0;
+}
+
+
+static int sony_btf_mpx_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct sony_btf_mpx *t = to_state(sd);
+	int default_mpx_mode = 0;
+
+	if (std & V4L2_STD_PAL_BG)
+		default_mpx_mode = 1;
+	else if (std & V4L2_STD_PAL_I)
+		default_mpx_mode = 4;
+	else if (std & V4L2_STD_PAL_DK)
+		default_mpx_mode = 6;
+	else if (std & V4L2_STD_SECAM_L)
+		default_mpx_mode = 11;
+
+	if (default_mpx_mode != t->mpxmode) {
+		t->mpxmode = default_mpx_mode;
+		mpx_setup(t);
+	}
+	return 0;
+}
+
+static int sony_btf_mpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+	struct sony_btf_mpx *t = to_state(sd);
+
+	vt->capability = V4L2_TUNER_CAP_NORM |
+		V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+		V4L2_TUNER_CAP_LANG2;
+	vt->rxsubchans = V4L2_TUNER_SUB_MONO |
+		V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
+		V4L2_TUNER_SUB_LANG2;
+	vt->audmode = t->audmode;
+	return 0;
+}
+
+static int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+	struct sony_btf_mpx *t = to_state(sd);
+
+	if (vt->type != V4L2_TUNER_ANALOG_TV)
+		return -EINVAL;
+
+	if (vt->audmode != t->audmode) {
+		t->audmode = vt->audmode;
+		mpx_setup(t);
+	}
+	return 0;
+}
+
+/* --------------------------------------------------------------------------*/
+
+static const struct v4l2_subdev_core_ops sony_btf_mpx_core_ops = {
+	.s_std = sony_btf_mpx_s_std,
+};
+
+static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = {
+	.s_tuner = sony_btf_mpx_s_tuner,
+	.g_tuner = sony_btf_mpx_g_tuner,
+};
+
+static const struct v4l2_subdev_ops sony_btf_mpx_ops = {
+	.core = &sony_btf_mpx_core_ops,
+	.tuner = &sony_btf_mpx_tuner_ops,
+};
+
+/* --------------------------------------------------------------------------*/
+
+static int sony_btf_mpx_probe(struct i2c_client *client,
+				const struct i2c_device_id *id)
+{
+	struct sony_btf_mpx *t;
+	struct v4l2_subdev *sd;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+		return -ENODEV;
+
+	v4l_info(client, "chip found @ 0x%x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	t = kzalloc(sizeof(struct sony_btf_mpx), GFP_KERNEL);
+	if (t == NULL)
+		return -ENOMEM;
+
+	sd = &t->sd;
+	v4l2_i2c_subdev_init(sd, client, &sony_btf_mpx_ops);
+
+	/* Initialize sony_btf_mpx */
+	t->mpxmode = 0;
+	t->audmode = V4L2_TUNER_MODE_STEREO;
+
+	return 0;
+}
+
+static int sony_btf_mpx_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct i2c_device_id sony_btf_mpx_id[] = {
+	{ "sony-btf-mpx", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, sony_btf_mpx_id);
+
+static struct i2c_driver sony_btf_mpx_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "sony-btf-mpx",
+	},
+	.probe = sony_btf_mpx_probe,
+	.remove = sony_btf_mpx_remove,
+	.id_table = sony_btf_mpx_id,
+};
+module_i2c_driver(sony_btf_mpx_driver);
-- 
1.7.10.4


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

* [REVIEW PATCH 10/42] ov7640: add new ov7640 driver
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (7 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 09/42] sony-btf-mpx: the MPX driver for the sony BTF PAL/SECAM tuner Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 11/42] uda1342: add new uda1342 audio codec driver Hans Verkuil
                     ` (32 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

This based on the wis-ov7640.c driver that's part of the go7007 driver.
It has been converted to a v4l subdev driver by Pete Eberlein, and I made
additional cleanups.

Based on work by: Pete Eberlein <pete@sensoray.com>

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Pete Eberlein <pete@sensoray.com>
---
 drivers/media/i2c/Kconfig  |   11 +++++
 drivers/media/i2c/Makefile |    3 +-
 drivers/media/i2c/ov7640.c |  106 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/i2c/ov7640.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 70dbae2..fe5f9d0 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -395,6 +395,17 @@ config VIDEO_APTINA_PLL
 config VIDEO_SMIAPP_PLL
 	tristate
 
+config VIDEO_OV7640
+	tristate "OmniVision OV7640 sensor support"
+	depends on I2C && VIDEO_V4L2
+	depends on MEDIA_CAMERA_SUPPORT
+	---help---
+	  This is a Video4Linux2 sensor-level driver for the OmniVision
+	  OV7640 camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ov7640.
+
 config VIDEO_OV7670
 	tristate "OmniVision OV7670 sensor support"
 	depends on I2C && VIDEO_V4L2
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 4c57075..adf9504 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -47,7 +47,8 @@ obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
 obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
 obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
 obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
-obj-$(CONFIG_VIDEO_OV7670) 	+= ov7670.o
+obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
+obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
 obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
 obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
 obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
diff --git a/drivers/media/i2c/ov7640.c b/drivers/media/i2c/ov7640.c
new file mode 100644
index 0000000..b0cc927
--- /dev/null
+++ b/drivers/media/i2c/ov7640.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <linux/slab.h>
+
+MODULE_DESCRIPTION("OmniVision ov7640 sensor driver");
+MODULE_LICENSE("GPL v2");
+
+static const u8 initial_registers[] = {
+	0x12, 0x80,
+	0x12, 0x54,
+	0x14, 0x24,
+	0x15, 0x01,
+	0x28, 0x20,
+	0x75, 0x82,
+	0xFF, 0xFF, /* Terminator (reg 0xFF is unused) */
+};
+
+static int write_regs(struct i2c_client *client, const u8 *regs)
+{
+	int i;
+
+	for (i = 0; regs[i] != 0xFF; i += 2)
+		if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
+			return -1;
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_ops ov7640_ops;
+
+static int ov7640_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	struct v4l2_subdev *sd;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	if (sd == NULL)
+		return -ENOMEM;
+	v4l2_i2c_subdev_init(sd, client, &ov7640_ops);
+
+	client->flags = I2C_CLIENT_SCCB;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	if (write_regs(client, initial_registers) < 0) {
+		v4l_err(client, "error initializing OV7640\n");
+		kfree(sd);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+
+static int ov7640_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 ov7640_id[] = {
+	{ "ov7640", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ov7640_id);
+
+static struct i2c_driver ov7640_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "ov7640",
+	},
+	.probe = ov7640_probe,
+	.remove = ov7640_remove,
+	.id_table = ov7640_id,
+};
+module_i2c_driver(ov7640_driver);
-- 
1.7.10.4


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

* [REVIEW PATCH 11/42] uda1342: add new uda1342 audio codec driver
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (8 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 10/42] ov7640: add new ov7640 driver Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 12/42] tw9903: add new tw9903 video decoder Hans Verkuil
                     ` (31 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

This based on the wis-uda1342.c driver that's part of the go7007 driver.
It has been converted to a v4l subdev driver by Pete Eberlein, and I made
additional cleanups.

Based on work by: Pete Eberlein <pete@sensoray.com>

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Pete Eberlein <pete@sensoray.com>
---
 drivers/media/i2c/Kconfig   |    9 ++++
 drivers/media/i2c/Makefile  |    1 +
 drivers/media/i2c/uda1342.c |  113 +++++++++++++++++++++++++++++++++++++++++++
 include/media/uda1342.h     |   29 +++++++++++
 4 files changed, 152 insertions(+)
 create mode 100644 drivers/media/i2c/uda1342.c
 create mode 100644 include/media/uda1342.h

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index fe5f9d0..8000642 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -112,6 +112,15 @@ config VIDEO_TLV320AIC23B
 	  To compile this driver as a module, choose M here: the
 	  module will be called tlv320aic23b.
 
+config VIDEO_UDA1342
+	tristate "Philips UDA1342 audio codec"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the Philips UDA1342 audio codec.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called uda1342.
+
 config VIDEO_WM8775
 	tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
 	depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index adf9504..b1775b3 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
 obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
 obj-$(CONFIG_VIDEO_M52790) += m52790.o
 obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
+obj-$(CONFIG_VIDEO_UDA1342) += uda1342.o
 obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
 obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
 obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
diff --git a/drivers/media/i2c/uda1342.c b/drivers/media/i2c/uda1342.c
new file mode 100644
index 0000000..3af4085
--- /dev/null
+++ b/drivers/media/i2c/uda1342.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/uda1342.h>
+#include <linux/slab.h>
+
+static int write_reg(struct i2c_client *client, int reg, int value)
+{
+	/* UDA1342 wants MSB first, but SMBus sends LSB first */
+	i2c_smbus_write_word_data(client, reg, swab16(value));
+	return 0;
+}
+
+static int uda1342_s_routing(struct v4l2_subdev *sd,
+		u32 input, u32 output, u32 config)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	switch (input) {
+	case UDA1342_IN1:
+		write_reg(client, 0x00, 0x1241); /* select input 1 */
+		break;
+	case UDA1342_IN2:
+		write_reg(client, 0x00, 0x1441); /* select input 2 */
+		break;
+	default:
+		v4l2_err(sd, "input %d not supported\n", input);
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_subdev_audio_ops uda1342_audio_ops = {
+	.s_routing = uda1342_s_routing,
+};
+
+static const struct v4l2_subdev_ops uda1342_ops = {
+	.audio = &uda1342_audio_ops,
+};
+
+static int uda1342_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	struct v4l2_subdev *sd;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
+		return -ENODEV;
+
+	dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n",
+		client->addr, adapter->name);
+
+	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	if (sd == NULL)
+		return -ENOMEM;
+
+	v4l2_i2c_subdev_init(sd, client, &uda1342_ops);
+
+	write_reg(client, 0x00, 0x8000); /* reset registers */
+	write_reg(client, 0x00, 0x1241); /* select input 1 */
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	return 0;
+}
+
+static int uda1342_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 uda1342_id[] = {
+	{ "uda1342", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, uda1342_id);
+
+static struct i2c_driver uda1342_driver = {
+	.driver = {
+		.name	= "uda1342",
+	},
+	.probe		= uda1342_probe,
+	.remove		= uda1342_remove,
+	.id_table	= uda1342_id,
+};
+
+module_i2c_driver(uda1342_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/include/media/uda1342.h b/include/media/uda1342.h
new file mode 100644
index 0000000..cd15640
--- /dev/null
+++ b/include/media/uda1342.h
@@ -0,0 +1,29 @@
+/*
+ * uda1342.h - definition for uda1342 inputs
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef _UDA1342_H_
+#define _UDA1342_H_
+
+/* The UDA1342 has 2 inputs */
+
+#define UDA1342_IN1 1
+#define UDA1342_IN2 2
+
+#endif
-- 
1.7.10.4


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

* [REVIEW PATCH 12/42] tw9903: add new tw9903 video decoder.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (9 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 11/42] uda1342: add new uda1342 audio codec driver Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-24 15:29     ` Mauro Carvalho Chehab
  2013-03-11 11:45   ` [REVIEW PATCH 13/42] tw2804: add support for the Techwell tw2804 Hans Verkuil
                     ` (30 subsequent siblings)
  41 siblings, 1 reply; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

This based on the wis-tw9903.c driver that's part of the go7007 driver.
It has been converted to a v4l subdev driver by Pete Eberlein, and I made
additional cleanups.

Based on work by: Pete Eberlein <pete@sensoray.com>

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Pete Eberlein <pete@sensoray.com>
---
 drivers/media/i2c/Kconfig  |   10 ++
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/tw9903.c |  274 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 285 insertions(+)
 create mode 100644 drivers/media/i2c/tw9903.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 8000642..eb9ef55 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -301,6 +301,16 @@ config VIDEO_TVP7002
 	  To compile this driver as a module, choose M here: the
 	  module will be called tvp7002.
 
+config VIDEO_TW9903
+	tristate "Techwell TW9903 video decoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the Techwell 9903 multi-standard video decoder
+	  with high quality down scaler.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called tw9903.
+
 config VIDEO_VPX3220
 	tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
 	depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index b1775b3..af8fb29 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
 obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
 obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
+obj-$(CONFIG_VIDEO_TW9903) += tw9903.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/tw9903.c b/drivers/media/i2c/tw9903.c
new file mode 100644
index 0000000..82626ea
--- /dev/null
+++ b/drivers/media/i2c/tw9903.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <linux/slab.h>
+
+MODULE_DESCRIPTION("TW9903 I2C subdev driver");
+MODULE_LICENSE("GPL v2");
+
+/*
+ * This driver is based on the wis-tw9903.c source that was in
+ * drivers/staging/media/go7007. That source had commented out code for
+ * saturation and scaling (neither seemed to work). If anyone ever gets
+ * hardware to test this driver, then that code might be useful to look at.
+ * You need to get the kernel sources of, say, kernel 3.8 where that
+ * wis-tw9903 driver is still present.
+ */
+
+struct tw9903 {
+	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler hdl;
+	v4l2_std_id norm;
+};
+
+static inline struct tw9903 *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct tw9903, sd);
+}
+
+static const u8 initial_registers[] = {
+	0x02, 0x44, /* input 1, composite */
+	0x03, 0x92, /* correct digital format */
+	0x04, 0x00,
+	0x05, 0x80, /* or 0x00 for PAL */
+	0x06, 0x40, /* second internal current reference */
+	0x07, 0x02, /* window */
+	0x08, 0x14, /* window */
+	0x09, 0xf0, /* window */
+	0x0a, 0x81, /* window */
+	0x0b, 0xd0, /* window */
+	0x0c, 0x8c,
+	0x0d, 0x00, /* scaling */
+	0x0e, 0x11, /* scaling */
+	0x0f, 0x00, /* scaling */
+	0x10, 0x00, /* brightness */
+	0x11, 0x60, /* contrast */
+	0x12, 0x01, /* sharpness */
+	0x13, 0x7f, /* U gain */
+	0x14, 0x5a, /* V gain */
+	0x15, 0x00, /* hue */
+	0x16, 0xc3, /* sharpness */
+	0x18, 0x00,
+	0x19, 0x58, /* vbi */
+	0x1a, 0x80,
+	0x1c, 0x0f, /* video norm */
+	0x1d, 0x7f, /* video norm */
+	0x20, 0xa0, /* clamping gain (working 0x50) */
+	0x21, 0x22,
+	0x22, 0xf0,
+	0x23, 0xfe,
+	0x24, 0x3c,
+	0x25, 0x38,
+	0x26, 0x44,
+	0x27, 0x20,
+	0x28, 0x00,
+	0x29, 0x15,
+	0x2a, 0xa0,
+	0x2b, 0x44,
+	0x2c, 0x37,
+	0x2d, 0x00,
+	0x2e, 0xa5, /* burst PLL control (working: a9) */
+	0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */
+	0x31, 0x00,
+	0x33, 0x22,
+	0x34, 0x11,
+	0x35, 0x35,
+	0x3b, 0x05,
+	0x06, 0xc0, /* reset device */
+	0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
+};
+
+static int write_reg(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 int write_regs(struct v4l2_subdev *sd, const u8 *regs)
+{
+	int i;
+
+	for (i = 0; regs[i] != 0x00; i += 2)
+		if (write_reg(sd, regs[i], regs[i + 1]) < 0)
+			return -1;
+	return 0;
+}
+
+static int tw9903_s_video_routing(struct v4l2_subdev *sd, u32 input,
+				      u32 output, u32 config)
+{
+	write_reg(sd, 0x02, 0x40 | (input << 1));
+	return 0;
+}
+
+static int tw9903_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+	struct tw9903 *dec = to_state(sd);
+	bool is_60hz = norm & V4L2_STD_525_60;
+	u8 regs[] = {
+		0x05, is_60hz ? 0x80 : 0x00,
+		0x07, is_60hz ? 0x02 : 0x12,
+		0x08, is_60hz ? 0x14 : 0x18,
+		0x09, is_60hz ? 0xf0 : 0x20,
+		0,    0,
+	};
+
+	write_regs(sd, regs);
+	dec->norm = norm;
+	return 0;
+}
+
+
+static int tw9903_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct tw9903 *dec = container_of(ctrl->handler, struct tw9903, hdl);
+	struct v4l2_subdev *sd = &dec->sd;
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		write_reg(sd, 0x10, ctrl->val);
+		break;
+	case V4L2_CID_CONTRAST:
+		write_reg(sd, 0x11, ctrl->val);
+		break;
+	case V4L2_CID_HUE:
+		write_reg(sd, 0x15, ctrl->val);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int tw9903_log_status(struct v4l2_subdev *sd)
+{
+	struct tw9903 *dec = to_state(sd);
+
+	v4l2_info(sd, "Standard: %s\n", dec->norm == V4L2_STD_NTSC ? "NTSC" :
+					dec->norm == V4L2_STD_PAL ? "PAL" :
+					dec->norm == V4L2_STD_SECAM ? "SECAM" :
+					"unknown");
+	v4l2_ctrl_subdev_log_status(sd);
+	return 0;
+}
+
+/* --------------------------------------------------------------------------*/
+
+static const struct v4l2_ctrl_ops tw9903_ctrl_ops = {
+	.s_ctrl = tw9903_s_ctrl,
+};
+
+static const struct v4l2_subdev_core_ops tw9903_core_ops = {
+	.log_status = tw9903_log_status,
+	.s_std = tw9903_s_std,
+};
+
+static const struct v4l2_subdev_video_ops tw9903_video_ops = {
+	.s_routing = tw9903_s_video_routing,
+};
+
+static const struct v4l2_subdev_ops tw9903_ops = {
+	.core = &tw9903_core_ops,
+	.video = &tw9903_video_ops,
+};
+
+/* --------------------------------------------------------------------------*/
+
+static int tw9903_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
+{
+	struct tw9903 *dec;
+	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *hdl;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	dec = kzalloc(sizeof(struct tw9903), GFP_KERNEL);
+	if (dec == NULL)
+		return -ENOMEM;
+	sd = &dec->sd;
+	v4l2_i2c_subdev_init(sd, client, &tw9903_ops);
+	hdl = &dec->hdl;
+	v4l2_ctrl_handler_init(hdl, 4);
+	v4l2_ctrl_new_std(hdl, &tw9903_ctrl_ops,
+		V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
+	v4l2_ctrl_new_std(hdl, &tw9903_ctrl_ops,
+		V4L2_CID_CONTRAST, 0, 255, 1, 0x60);
+	v4l2_ctrl_new_std(hdl, &tw9903_ctrl_ops,
+		V4L2_CID_HUE, -128, 127, 1, 0);
+	sd->ctrl_handler = hdl;
+	if (hdl->error) {
+		int err = hdl->error;
+
+		v4l2_ctrl_handler_free(hdl);
+		kfree(dec);
+		return err;
+	}
+
+	/* Initialize tw9903 */
+	dec->norm = V4L2_STD_NTSC;
+
+	if (write_regs(sd, initial_registers) < 0) {
+		v4l2_err(client, "error initializing TW9903\n");
+		kfree(dec);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int tw9903_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&to_state(sd)->hdl);
+	kfree(to_state(sd));
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct i2c_device_id tw9903_id[] = {
+	{ "tw9903", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tw9903_id);
+
+static struct i2c_driver tw9903_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "tw9903",
+	},
+	.probe = tw9903_probe,
+	.remove = tw9903_remove,
+	.id_table = tw9903_id,
+};
+module_i2c_driver(tw9903_driver);
-- 
1.7.10.4


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

* [REVIEW PATCH 13/42] tw2804: add support for the Techwell tw2804.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (10 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 12/42] tw9903: add new tw9903 video decoder Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 14/42] tw2804: modify ADC power control Hans Verkuil
                     ` (29 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

This is based on the wis-tw2804.c driver that's part of the go7007 driver.
It has been converted to a v4l subdev driver by Volokh Konstantin, and I
made additional cleanups.

Based on work by: Volokh Konstantin <volokh84@gmail.com>

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: Volokh Konstantin <volokh84@gmail.com>
---
 drivers/media/i2c/Kconfig  |   11 +-
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/tw2804.c |  467 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 478 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/i2c/tw2804.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index eb9ef55..4c03684 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -301,11 +301,20 @@ config VIDEO_TVP7002
 	  To compile this driver as a module, choose M here: the
 	  module will be called tvp7002.
 
+config VIDEO_TW2804
+	tristate "Techwell TW2804 multiple video decoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the Techwell tw2804 multiple video decoder.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called tw2804.
+
 config VIDEO_TW9903
 	tristate "Techwell TW9903 video decoder"
 	depends on VIDEO_V4L2 && I2C
 	---help---
-	  Support for the Techwell 9903 multi-standard video decoder
+	  Support for the Techwell tw9903 multi-standard video decoder
 	  with high quality down scaler.
 
 	  To compile this driver as a module, choose M here: the
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index af8fb29..399050a 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
 obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
 obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
+obj-$(CONFIG_VIDEO_TW2804) += tw2804.o
 obj-$(CONFIG_VIDEO_TW9903) += tw9903.o
 obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
 obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
diff --git a/drivers/media/i2c/tw2804.c b/drivers/media/i2c/tw2804.c
new file mode 100644
index 0000000..4bb5ba6
--- /dev/null
+++ b/drivers/media/i2c/tw2804.c
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/ioctl.h>
+#include <linux/slab.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ctrls.h>
+
+#define TW2804_REG_AUTOGAIN		0x02
+#define TW2804_REG_HUE			0x0f
+#define TW2804_REG_SATURATION		0x10
+#define TW2804_REG_CONTRAST		0x11
+#define TW2804_REG_BRIGHTNESS		0x12
+#define TW2804_REG_COLOR_KILLER		0x14
+#define TW2804_REG_GAIN			0x3c
+#define TW2804_REG_CHROMA_GAIN		0x3d
+#define TW2804_REG_BLUE_BALANCE		0x3e
+#define TW2804_REG_RED_BALANCE		0x3f
+
+struct tw2804 {
+	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler hdl;
+	u8 channel:2;
+	u8 input:1;
+	int norm;
+};
+
+static const u8 global_registers[] = {
+	0x39, 0x00,
+	0x3a, 0xff,
+	0x3b, 0x84,
+	0x3c, 0x80,
+	0x3d, 0x80,
+	0x3e, 0x82,
+	0x3f, 0x82,
+	0xff, 0xff, /* Terminator (reg 0xff does not exist) */
+};
+
+static const u8 channel_registers[] = {
+	0x01, 0xc4,
+	0x02, 0xa5,
+	0x03, 0x20,
+	0x04, 0xd0,
+	0x05, 0x20,
+	0x06, 0xd0,
+	0x07, 0x88,
+	0x08, 0x20,
+	0x09, 0x07,
+	0x0a, 0xf0,
+	0x0b, 0x07,
+	0x0c, 0xf0,
+	0x0d, 0x40,
+	0x0e, 0xd2,
+	0x0f, 0x80,
+	0x10, 0x80,
+	0x11, 0x80,
+	0x12, 0x80,
+	0x13, 0x1f,
+	0x14, 0x00,
+	0x15, 0x00,
+	0x16, 0x00,
+	0x17, 0x00,
+	0x18, 0xff,
+	0x19, 0xff,
+	0x1a, 0xff,
+	0x1b, 0xff,
+	0x1c, 0xff,
+	0x1d, 0xff,
+	0x1e, 0xff,
+	0x1f, 0xff,
+	0x20, 0x07,
+	0x21, 0x07,
+	0x22, 0x00,
+	0x23, 0x91,
+	0x24, 0x51,
+	0x25, 0x03,
+	0x26, 0x00,
+	0x27, 0x00,
+	0x28, 0x00,
+	0x29, 0x00,
+	0x2a, 0x00,
+	0x2b, 0x00,
+	0x2c, 0x00,
+	0x2d, 0x00,
+	0x2e, 0x00,
+	0x2f, 0x00,
+	0x30, 0x00,
+	0x31, 0x00,
+	0x32, 0x00,
+	0x33, 0x00,
+	0x34, 0x00,
+	0x35, 0x00,
+	0x36, 0x00,
+	0x37, 0x00,
+	0xff, 0xff, /* Terminator (reg 0xff does not exist) */
+};
+
+static int write_reg(struct i2c_client *client, u8 reg, u8 value, u8 channel)
+{
+	return i2c_smbus_write_byte_data(client, reg | (channel << 6), value);
+}
+
+static int write_regs(struct i2c_client *client, const u8 *regs, u8 channel)
+{
+	int ret;
+	int i;
+
+	for (i = 0; regs[i] != 0xff; i += 2) {
+		ret = i2c_smbus_write_byte_data(client,
+				regs[i] | (channel << 6), regs[i + 1]);
+		if (ret < 0)
+			return ret;
+	}
+	return 0;
+}
+
+static int read_reg(struct i2c_client *client, u8 reg, u8 channel)
+{
+	return i2c_smbus_read_byte_data(client, (reg) | (channel << 6));
+}
+
+static inline struct tw2804 *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct tw2804, sd);
+}
+
+static inline struct tw2804 *to_state_from_ctrl(struct v4l2_ctrl *ctrl)
+{
+	return container_of(ctrl->handler, struct tw2804, hdl);
+}
+
+static int tw2804_log_status(struct v4l2_subdev *sd)
+{
+	struct tw2804 *state = to_state(sd);
+
+	v4l2_info(sd, "Standard: %s\n",
+			state->norm & V4L2_STD_525_60 ? "60 Hz" : "50 Hz");
+	v4l2_info(sd, "Channel: %d\n", state->channel);
+	v4l2_info(sd, "Input: %d\n", state->input);
+	return v4l2_ctrl_subdev_log_status(sd);
+}
+
+/*
+ * These volatile controls are needed because all four channels share
+ * these controls. So a change made to them through one channel would
+ * require another channel to be updated.
+ *
+ * Normally this would have been done in a different way, but since the one
+ * board that uses this driver sees this single chip as if it was on four
+ * different i2c adapters (each adapter belonging to a separate instance of
+ * the same USB driver) there is no reliable method that I have found to let
+ * the instances know about each other.
+ *
+ * So implementing these global registers as volatile is the best we can do.
+ */
+static int tw2804_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct tw2804 *state = to_state_from_ctrl(ctrl);
+	struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
+
+	switch (ctrl->id) {
+	case V4L2_CID_GAIN:
+		ctrl->val = read_reg(client, TW2804_REG_GAIN, 0);
+		return 0;
+
+	case V4L2_CID_CHROMA_GAIN:
+		ctrl->val = read_reg(client, TW2804_REG_CHROMA_GAIN, 0);
+		return 0;
+
+	case V4L2_CID_BLUE_BALANCE:
+		ctrl->val = read_reg(client, TW2804_REG_BLUE_BALANCE, 0);
+		return 0;
+
+	case V4L2_CID_RED_BALANCE:
+		ctrl->val = read_reg(client, TW2804_REG_RED_BALANCE, 0);
+		return 0;
+	}
+	return 0;
+}
+
+static int tw2804_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct tw2804 *state = to_state_from_ctrl(ctrl);
+	struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
+	int addr;
+	int reg;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUTOGAIN:
+		addr = TW2804_REG_AUTOGAIN;
+		reg = read_reg(client, addr, state->channel);
+		if (reg < 0)
+			return reg;
+		if (ctrl->val == 0)
+			reg &= ~(1 << 7);
+		else
+			reg |= 1 << 7;
+		return write_reg(client, addr, reg, state->channel);
+
+	case V4L2_CID_COLOR_KILLER:
+		addr = TW2804_REG_COLOR_KILLER;
+		reg = read_reg(client, addr, state->channel);
+		if (reg < 0)
+			return reg;
+		reg = (reg & ~(0x03)) | (ctrl->val == 0 ? 0x02 : 0x03);
+		return write_reg(client, addr, reg, state->channel);
+
+	case V4L2_CID_GAIN:
+		return write_reg(client, TW2804_REG_GAIN, ctrl->val, 0);
+
+	case V4L2_CID_CHROMA_GAIN:
+		return write_reg(client, TW2804_REG_CHROMA_GAIN, ctrl->val, 0);
+
+	case V4L2_CID_BLUE_BALANCE:
+		return write_reg(client, TW2804_REG_BLUE_BALANCE, ctrl->val, 0);
+
+	case V4L2_CID_RED_BALANCE:
+		return write_reg(client, TW2804_REG_RED_BALANCE, ctrl->val, 0);
+
+	case V4L2_CID_BRIGHTNESS:
+		return write_reg(client, TW2804_REG_BRIGHTNESS,
+				ctrl->val, state->channel);
+
+	case V4L2_CID_CONTRAST:
+		return write_reg(client, TW2804_REG_CONTRAST,
+				ctrl->val, state->channel);
+
+	case V4L2_CID_SATURATION:
+		return write_reg(client, TW2804_REG_SATURATION,
+				ctrl->val, state->channel);
+
+	case V4L2_CID_HUE:
+		return write_reg(client, TW2804_REG_HUE,
+				ctrl->val, state->channel);
+
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+static int tw2804_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+	struct tw2804 *dec = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	bool is_60hz = norm & V4L2_STD_525_60;
+	u8 regs[] = {
+		0x01, is_60hz ? 0xc4 : 0x84,
+		0x09, is_60hz ? 0x07 : 0x04,
+		0x0a, is_60hz ? 0xf0 : 0x20,
+		0x0b, is_60hz ? 0x07 : 0x04,
+		0x0c, is_60hz ? 0xf0 : 0x20,
+		0x0d, is_60hz ? 0x40 : 0x4a,
+		0x16, is_60hz ? 0x00 : 0x40,
+		0x17, is_60hz ? 0x00 : 0x40,
+		0x20, is_60hz ? 0x07 : 0x0f,
+		0x21, is_60hz ? 0x07 : 0x0f,
+		0xff, 0xff,
+	};
+
+	write_regs(client, regs, dec->channel);
+	dec->norm = norm;
+	return 0;
+}
+
+static int tw2804_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
+	u32 config)
+{
+	struct tw2804 *dec = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int reg;
+
+	if (config && config - 1 != dec->channel) {
+		if (config > 4) {
+			dev_err(&client->dev,
+				"channel %d is not between 1 and 4!\n", config);
+			return -EINVAL;
+		}
+		dec->channel = config - 1;
+		dev_dbg(&client->dev, "initializing TW2804 channel %d\n",
+			dec->channel);
+		if (dec->channel == 0 &&
+				write_regs(client, global_registers, 0) < 0) {
+			dev_err(&client->dev,
+				"error initializing TW2804 global registers\n");
+			return -EIO;
+		}
+		if (write_regs(client, channel_registers, dec->channel) < 0) {
+			dev_err(&client->dev,
+				"error initializing TW2804 channel %d\n",
+				dec->channel);
+			return -EIO;
+		}
+	}
+
+	if (input > 1)
+		return -EINVAL;
+
+	if (input == dec->input)
+		return 0;
+
+	reg = read_reg(client, 0x22, dec->channel);
+
+	if (reg >= 0) {
+		if (input == 0)
+			reg &= ~(1 << 2);
+		else
+			reg |= 1 << 2;
+		reg = write_reg(client, 0x22, reg, dec->channel);
+	}
+
+	if (reg >= 0)
+		dec->input = input;
+	else
+		return reg;
+	return 0;
+}
+
+static int tw2804_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct tw2804 *dec = to_state(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u32 reg = read_reg(client, 0x78, 0);
+
+	if (enable == 1)
+		write_reg(client, 0x78, reg & ~(1 << dec->channel), 0);
+	else
+		write_reg(client, 0x78, reg | (1 << dec->channel), 0);
+
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops tw2804_ctrl_ops = {
+	.g_volatile_ctrl = tw2804_g_volatile_ctrl,
+	.s_ctrl = tw2804_s_ctrl,
+};
+
+static const struct v4l2_subdev_video_ops tw2804_video_ops = {
+	.s_routing = tw2804_s_video_routing,
+	.s_stream = tw2804_s_stream,
+};
+
+static const struct v4l2_subdev_core_ops tw2804_core_ops = {
+	.log_status = tw2804_log_status,
+	.s_std = tw2804_s_std,
+};
+
+static const struct v4l2_subdev_ops tw2804_ops = {
+	.core = &tw2804_core_ops,
+	.video = &tw2804_video_ops,
+};
+
+static int tw2804_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	struct tw2804 *state;
+	struct v4l2_subdev *sd;
+	struct v4l2_ctrl *ctrl;
+	int err;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	state = kzalloc(sizeof(struct tw2804), GFP_KERNEL);
+
+	if (state == NULL)
+		return -ENOMEM;
+	sd = &state->sd;
+	v4l2_i2c_subdev_init(sd, client, &tw2804_ops);
+	state->channel = -1;
+	state->norm = V4L2_STD_NTSC;
+
+	v4l2_ctrl_handler_init(&state->hdl, 10);
+	v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
+	v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_CONTRAST, 0, 255, 1, 128);
+	v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_SATURATION, 0, 255, 1, 128);
+	v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_HUE, 0, 255, 1, 128);
+	v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_COLOR_KILLER, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
+	ctrl = v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_GAIN, 0, 255, 1, 128);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	ctrl = v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_CHROMA_GAIN, 0, 255, 1, 128);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	ctrl = v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_BLUE_BALANCE, 0, 255, 1, 122);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	ctrl = v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
+				V4L2_CID_RED_BALANCE, 0, 255, 1, 122);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	sd->ctrl_handler = &state->hdl;
+	err = state->hdl.error;
+	if (err) {
+		v4l2_ctrl_handler_free(&state->hdl);
+		kfree(state);
+		return err;
+	}
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	return 0;
+}
+
+static int tw2804_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct tw2804 *state = to_state(sd);
+
+	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&state->hdl);
+	kfree(state);
+	return 0;
+}
+
+static const struct i2c_device_id tw2804_id[] = {
+	{ "tw2804", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tw2804_id);
+
+static struct i2c_driver tw2804_driver = {
+	.driver = {
+		.name	= "tw2804",
+	},
+	.probe		= tw2804_probe,
+	.remove		= tw2804_remove,
+	.id_table	= tw2804_id,
+};
+
+module_i2c_driver(tw2804_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TW2804/TW2802 V4L2 i2c driver");
+MODULE_AUTHOR("Micronas USA Inc");
-- 
1.7.10.4


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

* [REVIEW PATCH 14/42] tw2804: modify ADC power control
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (11 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 13/42] tw2804: add support for the Techwell tw2804 Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 15/42] go7007: i2c initialization changes for tw2804 Hans Verkuil
                     ` (28 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

From: Volokh Konstantin <volokh84@gmail.com>

Switch off all ADC (max 4) with first init, we control it
when starting/stopping streaming.

Signed-off-by: Volokh Konstantin <volokh84@gmail.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/i2c/tw2804.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/i2c/tw2804.c b/drivers/media/i2c/tw2804.c
index 4bb5ba6..441b766 100644
--- a/drivers/media/i2c/tw2804.c
+++ b/drivers/media/i2c/tw2804.c
@@ -53,6 +53,7 @@ static const u8 global_registers[] = {
 	0x3d, 0x80,
 	0x3e, 0x82,
 	0x3f, 0x82,
+	0x78, 0x0f,
 	0xff, 0xff, /* Terminator (reg 0xff does not exist) */
 };
 
-- 
1.7.10.4


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

* [REVIEW PATCH 15/42] go7007: i2c initialization changes for tw2804
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (12 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 14/42] tw2804: modify ADC power control Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 16/42] go7007: switch to standard tuner/i2c subdevs Hans Verkuil
                     ` (27 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

From: Volokh Konstantin <volokh84@gmail.com>

Do i2c initialization via struct item as tw2804 has a 0x00 i2c address,
so we need to use the I2C_CLIENT_TEN flag for validity.

Signed-off-by: Volokh Konstantin <volokh84@gmail.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-driver.c |   20 +++++++++++---------
 drivers/staging/media/go7007/go7007-priv.h   |    3 ++-
 drivers/staging/media/go7007/go7007-usb.c    |    1 +
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index 6695091..2e5be70 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -196,18 +196,22 @@ int go7007_reset_encoder(struct go7007 *go)
 /*
  * Attempt to instantiate an I2C client by ID, probably loading a module.
  */
-static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
-			   int addr)
+static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *const i2c)
 {
 	struct go7007 *go = i2c_get_adapdata(adapter);
 	struct v4l2_device *v4l2_dev = &go->v4l2_dev;
+	struct i2c_board_info info;
 
-	if (v4l2_i2c_new_subdev(v4l2_dev, adapter, type, addr, NULL))
+	memset(&info, 0, sizeof(info));
+	strlcpy(info.type, i2c->type, sizeof(info.type));
+	info.addr = i2c->addr;
+	info.flags = i2c->flags;
+
+	if (v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, NULL))
 		return 0;
 
-	dev_info(&adapter->dev,
-		 "go7007: probing for module i2c:%s failed\n", type);
-	return -1;
+	printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", i2c->type);
+	return -EINVAL;
 }
 
 /*
@@ -243,9 +247,7 @@ int go7007_register_encoder(struct go7007 *go)
 	}
 	if (go->i2c_adapter_online) {
 		for (i = 0; i < go->board_info->num_i2c_devs; ++i)
-			init_i2c_module(&go->i2c_adapter,
-					go->board_info->i2c_devs[i].type,
-					go->board_info->i2c_devs[i].addr);
+			init_i2c_module(&go->i2c_adapter, &go->board_info->i2c_devs[i]);
 		if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
 			i2c_clients_command(&go->i2c_adapter,
 				DECODER_SET_CHANNEL, &go->channel_number);
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index b58c394..b9ebdfb 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -88,10 +88,11 @@ struct go7007_board_info {
 	int audio_bclk_div;
 	int audio_main_div;
 	int num_i2c_devs;
-	struct {
+	struct go_i2c {
 		const char *type;
 		int id;
 		int addr;
+		u32 flags;
 	} i2c_devs[4];
 	int num_inputs;
 	struct {
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 3333a8f..b44f9b1 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -398,6 +398,7 @@ static struct go7007_usb_board board_adlink_mpg24 = {
 				.type	= "wis_tw2804",
 				.id	= I2C_DRIVERID_WIS_TW2804,
 				.addr	= 0x00, /* yes, really */
+				.flags  = I2C_CLIENT_TEN,
 			},
 		},
 		.num_inputs	 = 1,
-- 
1.7.10.4


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

* [REVIEW PATCH 16/42] go7007: switch to standard tuner/i2c subdevs.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (13 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 15/42] go7007: i2c initialization changes for tw2804 Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-24 15:35     ` Mauro Carvalho Chehab
  2013-03-11 11:45   ` [REVIEW PATCH 17/42] go7007: remove all wis* drivers Hans Verkuil
                     ` (26 subsequent siblings)
  41 siblings, 1 reply; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Instead of using the wis-* drivers we now use the standard 'proper' subdev
drivers.

The board configuration tables now also list the possible audio inputs,
this will be used later to implement audio inputs.

Special mention deserves a little change in set_capture_size() where the
height passed to s_mbus_fmt is doubled: that is because the saa7115 driver
expects to see the frame height, not the field height as the wis_saa7115
driver did.

Another change is that the tuner input is moved from last to the first
input, which is consistent with the common practice in other video drivers.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/Kconfig          |   77 ++---------------
 drivers/staging/media/go7007/Makefile         |   12 ---
 drivers/staging/media/go7007/go7007-driver.c  |   29 +++++--
 drivers/staging/media/go7007/go7007-i2c.c     |    1 -
 drivers/staging/media/go7007/go7007-priv.h    |   18 +++-
 drivers/staging/media/go7007/go7007-usb.c     |  112 +++++++++++++++++--------
 drivers/staging/media/go7007/go7007-v4l2.c    |   18 +++-
 drivers/staging/media/go7007/saa7134-go7007.c |    2 +-
 8 files changed, 135 insertions(+), 134 deletions(-)

diff --git a/drivers/staging/media/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig
index 7dfb281..da32031 100644
--- a/drivers/staging/media/go7007/Kconfig
+++ b/drivers/staging/media/go7007/Kconfig
@@ -8,6 +8,12 @@ config VIDEO_GO7007
 	select VIDEO_TVEEPROM
 	select SND_PCM
 	select CRC32
+	select VIDEO_SONY_BTF_MPX if MEDIA_SUBDRV_AUTOSELECT
+	select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
+	select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT
+	select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT
+	select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT
+	select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT
 	default N
 	---help---
 	  This is a video4linux driver for the WIS GO7007 MPEG
@@ -36,74 +42,3 @@ config VIDEO_GO7007_USB_S2250_BOARD
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called s2250
-
-config VIDEO_GO7007_OV7640
-	tristate "OV7640 subdev support"
-	depends on VIDEO_GO7007
-	default N
-	---help---
-	  This is a video4linux driver for the OV7640 sub-device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called wis-ov7640
-
-config VIDEO_GO7007_SAA7113
-	tristate "SAA7113 subdev support"
-	depends on VIDEO_GO7007
-	default N
-	---help---
-	  This is a video4linux driver for the SAA7113 sub-device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called wis-saa7113
-
-config VIDEO_GO7007_SAA7115
-	tristate "SAA7115 subdev support"
-	depends on VIDEO_GO7007
-	default N
-	---help---
-	  This is a video4linux driver for the SAA7115 sub-device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called wis-saa7115
-
-config VIDEO_GO7007_TW9903
-	tristate "TW9903 subdev support"
-	depends on VIDEO_GO7007
-	default N
-	---help---
-	  This is a video4linux driver for the TW9903 sub-device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called wis-tw9903
-
-config VIDEO_GO7007_UDA1342
-	tristate "UDA1342 subdev support"
-	depends on VIDEO_GO7007
-	default N
-	---help---
-	  This is a video4linux driver for the UDA1342 sub-device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called wis-uda1342
-
-config VIDEO_GO7007_SONY_TUNER
-	tristate "Sony tuner subdev support"
-	depends on VIDEO_GO7007
-	default N
-	---help---
-	  This is a video4linux driver for the Sony Tuner sub-device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called wis-sony-tuner
-
-config VIDEO_GO7007_TW2804
-	tristate "TW2804 subdev support"
-	depends on VIDEO_GO7007
-	default N
-	---help---
-	  This is a video4linux driver for the TW2804 sub-device.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called wis-tw2804
-
diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
index 3fdbef5..5bed78b 100644
--- a/drivers/staging/media/go7007/Makefile
+++ b/drivers/staging/media/go7007/Makefile
@@ -1,18 +1,6 @@
-#obj-m += go7007.o go7007-usb.o snd-go7007.o wis-saa7115.o wis-tw9903.o \
-		wis-uda1342.o wis-sony-tuner.o wis-saa7113.o wis-ov7640.o \
-		wis-tw2804.o
-
-
 obj-$(CONFIG_VIDEO_GO7007) += go7007.o
 obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
 obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o s2250-loader.o
-obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o
-obj-$(CONFIG_VIDEO_GO7007_OV7640) += wis-ov7640.o
-obj-$(CONFIG_VIDEO_GO7007_SAA7115) += wis-saa7115.o
-obj-$(CONFIG_VIDEO_GO7007_TW9903) += wis-tw9903.o
-obj-$(CONFIG_VIDEO_GO7007_UDA1342) += wis-uda1342.o
-obj-$(CONFIG_VIDEO_GO7007_SONY_TUNER) += wis-sony-tuner.o
-obj-$(CONFIG_VIDEO_GO7007_TW2804) += wis-tw2804.o
 
 go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
 		snd-go7007.o
diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index 2e5be70..09d0ef4 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -35,7 +35,6 @@
 #include <media/v4l2-common.h>
 
 #include "go7007-priv.h"
-#include "wis-i2c.h"
 
 /*
  * Wait for an interrupt to be delivered from the GO7007SB and return
@@ -200,6 +199,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *con
 {
 	struct go7007 *go = i2c_get_adapdata(adapter);
 	struct v4l2_device *v4l2_dev = &go->v4l2_dev;
+	struct v4l2_subdev *sd;
 	struct i2c_board_info info;
 
 	memset(&info, 0, sizeof(info));
@@ -207,8 +207,14 @@ static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *con
 	info.addr = i2c->addr;
 	info.flags = i2c->flags;
 
-	if (v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, NULL))
+	sd = v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, NULL);
+	if (sd) {
+		if (i2c->is_video)
+			go->sd_video = sd;
+		if (i2c->is_audio)
+			go->sd_audio = sd;
 		return 0;
+	}
 
 	printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", i2c->type);
 	return -EINVAL;
@@ -222,7 +228,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *con
  *
  * Must NOT be called with the hw_lock held.
  */
-int go7007_register_encoder(struct go7007 *go)
+int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
 {
 	int i, ret;
 
@@ -246,11 +252,22 @@ int go7007_register_encoder(struct go7007 *go)
 		go->i2c_adapter_online = 1;
 	}
 	if (go->i2c_adapter_online) {
-		for (i = 0; i < go->board_info->num_i2c_devs; ++i)
+		for (i = 0; i < num_i2c_devs; ++i)
 			init_i2c_module(&go->i2c_adapter, &go->board_info->i2c_devs[i]);
+
+		if (go->tuner_type >= 0) {
+			struct tuner_setup setup = {
+				.addr = ADDR_UNSET,
+				.type = go->tuner_type,
+				.mode_mask = T_ANALOG_TV,
+			};
+
+			v4l2_device_call_all(&go->v4l2_dev, 0, tuner,
+				s_type_addr, &setup);
+		}
 		if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
-			i2c_clients_command(&go->i2c_adapter,
-				DECODER_SET_CHANNEL, &go->channel_number);
+			v4l2_subdev_call(go->sd_video, video, s_routing,
+					0, 0, go->channel_number + 1);
 	}
 	if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
 		go->audio_enabled = 1;
diff --git a/drivers/staging/media/go7007/go7007-i2c.c b/drivers/staging/media/go7007/go7007-i2c.c
index 1d0a400..74f25e0 100644
--- a/drivers/staging/media/go7007/go7007-i2c.c
+++ b/drivers/staging/media/go7007/go7007-i2c.c
@@ -28,7 +28,6 @@
 #include <linux/uaccess.h>
 
 #include "go7007-priv.h"
-#include "wis-i2c.h"
 
 /********************* Driver for on-board I2C adapter *********************/
 
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index b9ebdfb..898eb5b 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -90,16 +90,23 @@ struct go7007_board_info {
 	int num_i2c_devs;
 	struct go_i2c {
 		const char *type;
-		int id;
+		int is_video:1;
+		int is_audio:1;
 		int addr;
 		u32 flags;
-	} i2c_devs[4];
+	} i2c_devs[5];
 	int num_inputs;
 	struct {
 		int video_input;
-		int audio_input;
+		int audio_index;
 		char *name;
 	} inputs[4];
+	int video_config;
+	int num_aud_inputs;
+	struct {
+		int audio_input;
+		char *name;
+	} aud_inputs[3];
 };
 
 struct go7007_hpi_ops {
@@ -178,9 +185,12 @@ struct go7007 {
 	int streaming;
 	int in_use;
 	int audio_enabled;
+	struct v4l2_subdev *sd_video;
+	struct v4l2_subdev *sd_audio;
 
 	/* Video input */
 	int input;
+	int aud_input;
 	enum { GO7007_STD_NTSC, GO7007_STD_PAL, GO7007_STD_OTHER } standard;
 	int sensor_framerate;
 	int width;
@@ -268,7 +278,7 @@ int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data);
 int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data);
 int go7007_boot_encoder(struct go7007 *go, int init_i2c);
 int go7007_reset_encoder(struct go7007 *go);
-int go7007_register_encoder(struct go7007 *go);
+int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs);
 int go7007_start_encoder(struct go7007 *go);
 void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length);
 struct go7007 *go7007_alloc(struct go7007_board_info *board,
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index b44f9b1..5e3e5a0 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -26,11 +26,11 @@
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <asm/byteorder.h>
-#include <media/tvaudio.h>
+#include <media/saa7115.h>
 #include <media/tuner.h>
+#include <media/uda1342.h>
 
 #include "go7007-priv.h"
-#include "wis-i2c.h"
 
 static unsigned int assume_endura;
 module_param(assume_endura, int, 0644);
@@ -93,9 +93,9 @@ static struct go7007_usb_board board_matrix_ii = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
-				.type	= "wis_saa7115",
-				.id	= I2C_DRIVERID_WIS_SAA7115,
+				.type	= "saa7115",
 				.addr	= 0x20,
+				.is_video = 1,
 			},
 		},
 		.num_inputs	 = 2,
@@ -109,6 +109,7 @@ static struct go7007_usb_board board_matrix_ii = {
 				.name		= "S-Video",
 			},
 		},
+		.video_config	= SAA7115_IDQ_IS_DEFAULT,
 	},
 };
 
@@ -130,9 +131,9 @@ static struct go7007_usb_board board_matrix_reload = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
-				.type	= "wis_saa7113",
-				.id	= I2C_DRIVERID_WIS_SAA7113,
+				.type	= "saa7115",
 				.addr	= 0x25,
+				.is_video = 1,
 			},
 		},
 		.num_inputs	 = 2,
@@ -146,6 +147,7 @@ static struct go7007_usb_board board_matrix_reload = {
 				.name		= "S-Video",
 			},
 		},
+		.video_config	= SAA7115_IDQ_IS_DEFAULT,
 	},
 };
 
@@ -168,30 +170,31 @@ static struct go7007_usb_board board_star_trek = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
-				.type	= "wis_saa7115",
-				.id	= I2C_DRIVERID_WIS_SAA7115,
+				.type	= "saa7115",
 				.addr	= 0x20,
+				.is_video = 1,
 			},
 		},
 		.num_inputs	 = 2,
 		.inputs		 = {
+		/*	{
+		 *		.video_input	= 3,
+		 *		.audio_index	= AUDIO_TUNER,
+		 *		.name		= "Tuner",
+		 *	},
+		 */
 			{
 				.video_input	= 1,
-			/*	.audio_input	= AUDIO_EXTERN, */
+			/*	.audio_index	= AUDIO_EXTERN, */
 				.name		= "Composite",
 			},
 			{
 				.video_input	= 8,
-			/*	.audio_input	= AUDIO_EXTERN, */
+			/*	.audio_index	= AUDIO_EXTERN, */
 				.name		= "S-Video",
 			},
-		/*	{
-		 *		.video_input	= 3,
-		 *		.audio_input	= AUDIO_TUNER,
-		 *		.name		= "Tuner",
-		 *	},
-		 */
 		},
+		.video_config	= SAA7115_IDQ_IS_DEFAULT,
 	},
 };
 
@@ -211,41 +214,60 @@ static struct go7007_usb_board board_px_tv402u = {
 		.audio_bclk_div	 = 8,
 		.audio_main_div	 = 2,
 		.hpi_buffer_cap  = 7,
-		.num_i2c_devs	 = 3,
+		.num_i2c_devs	 = 5,
 		.i2c_devs	 = {
 			{
-				.type	= "wis_saa7115",
-				.id	= I2C_DRIVERID_WIS_SAA7115,
+				.type	= "saa7115",
 				.addr	= 0x20,
+				.is_video = 1,
 			},
 			{
-				.type	= "wis_uda1342",
-				.id	= I2C_DRIVERID_WIS_UDA1342,
+				.type	= "uda1342",
 				.addr	= 0x1a,
+				.is_audio = 1,
 			},
 			{
-				.type	= "wis_sony_tuner",
-				.id	= I2C_DRIVERID_WIS_SONY_TUNER,
+				.type	= "tuner",
 				.addr	= 0x60,
 			},
+			{
+				.type	= "tuner",
+				.addr	= 0x43,
+			},
+			{
+				.type	= "sony-btf-mpx",
+				.addr	= 0x44,
+			},
 		},
 		.num_inputs	 = 3,
 		.inputs		 = {
 			{
+				.video_input	= 3,
+				.audio_index	= 0,
+				.name		= "Tuner",
+			},
+			{
 				.video_input	= 1,
-				.audio_input	= TVAUDIO_INPUT_EXTERN,
+				.audio_index	= 1,
 				.name		= "Composite",
 			},
 			{
 				.video_input	= 8,
-				.audio_input	= TVAUDIO_INPUT_EXTERN,
+				.audio_index	= 1,
 				.name		= "S-Video",
 			},
+		},
+		.video_config	= SAA7115_IDQ_IS_DEFAULT,
+		.num_aud_inputs	 = 2,
+		.aud_inputs	 = {
 			{
-				.video_input	= 3,
-				.audio_input	= TVAUDIO_INPUT_TUNER,
+				.audio_input	= UDA1342_IN2,
 				.name		= "Tuner",
 			},
+			{
+				.audio_input	= UDA1342_IN1,
+				.name		= "Line In",
+			},
 		},
 	},
 };
@@ -272,8 +294,7 @@ static struct go7007_usb_board board_xmen = {
 		.num_i2c_devs	  = 1,
 		.i2c_devs	  = {
 			{
-				.type	= "wis_ov7640",
-				.id	= I2C_DRIVERID_WIS_OV7640,
+				.type	= "ov7640",
 				.addr	= 0x21,
 			},
 		},
@@ -305,8 +326,8 @@ static struct go7007_usb_board board_matrix_revolution = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
-				.type	= "wis_tw9903",
-				.id	= I2C_DRIVERID_WIS_TW9903,
+				.type	= "tw9903",
+				.is_video = 1,
 				.addr	= 0x44,
 			},
 		},
@@ -395,10 +416,10 @@ static struct go7007_usb_board board_adlink_mpg24 = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
-				.type	= "wis_tw2804",
-				.id	= I2C_DRIVERID_WIS_TW2804,
+				.type	= "tw2804",
 				.addr	= 0x00, /* yes, really */
 				.flags  = I2C_CLIENT_TEN,
+				.is_video = 1,
 			},
 		},
 		.num_inputs	 = 1,
@@ -428,8 +449,9 @@ static struct go7007_usb_board board_sensoray_2250 = {
 		.i2c_devs	 = {
 			{
 				.type	= "s2250",
-				.id	= I2C_DRIVERID_S2250,
 				.addr	= 0x43,
+				.is_video = 1,
+				.is_audio = 1,
 			},
 		},
 		.num_inputs	 = 2,
@@ -443,6 +465,21 @@ static struct go7007_usb_board board_sensoray_2250 = {
 				.name		= "S-Video",
 			},
 		},
+		.num_aud_inputs	 = 3,
+		.aud_inputs	 = {
+			{
+				.audio_input	= 0,
+				.name		= "Line In",
+			},
+			{
+				.audio_input	= 1,
+				.name		= "Mic",
+			},
+			{
+				.audio_input	= 2,
+				.name		= "Mic Boost",
+			},
+		},
 	},
 };
 
@@ -972,6 +1009,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 	struct go7007_usb *usb;
 	struct go7007_usb_board *board;
 	struct usb_device *usbdev = interface_to_usbdev(intf);
+	unsigned num_i2c_devs;
 	char *name;
 	int video_pipe, i, v_urb_len;
 
@@ -1126,6 +1164,8 @@ static int go7007_usb_probe(struct usb_interface *intf,
 		}
 	}
 
+	num_i2c_devs = go->board_info->num_i2c_devs;
+
 	/* Probe the tuner model on the TV402U */
 	if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) {
 		u8 data[3];
@@ -1145,12 +1185,14 @@ static int go7007_usb_probe(struct usb_interface *intf,
 		case 2:
 			go->board_id = GO7007_BOARDID_PX_TV402U_JP;
 			go->tuner_type = TUNER_SONY_BTF_PK467Z;
+			num_i2c_devs -= 2;
 			strncpy(go->name, "Plextor PX-TV402U-JP",
 					sizeof(go->name));
 			break;
 		case 3:
 			go->board_id = GO7007_BOARDID_PX_TV402U_NA;
 			go->tuner_type = TUNER_SONY_BTF_PB463Z;
+			num_i2c_devs -= 2;
 			strncpy(go->name, "Plextor PX-TV402U-NA",
 					sizeof(go->name));
 			break;
@@ -1180,7 +1222,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 
 	/* Do any final GO7007 initialization, then register the
 	 * V4L2 and ALSA interfaces */
-	if (go7007_register_encoder(go) < 0)
+	if (go7007_register_encoder(go, num_i2c_devs) < 0)
 		goto initfail;
 
 	/* Allocate the URBs and buffers for receiving the video stream */
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index e115132..bab4a31 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -37,7 +37,6 @@
 
 #include "go7007.h"
 #include "go7007-priv.h"
-#include "wis-i2c.h"
 
 /* Temporary defines until accepted in v4l-dvb */
 #ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
@@ -264,6 +263,7 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
 			mbus_fmt.height = height;
 			go->encoder_v_halve = 1;
 		}
+		mbus_fmt.height *= 2;
 		call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
 	} else {
 		if (width <= sensor_width / 4) {
@@ -1184,9 +1184,9 @@ static int vidioc_enum_input(struct file *file, void *priv,
 	strncpy(inp->name, go->board_info->inputs[inp->index].name,
 			sizeof(inp->name));
 
-	/* If this board has a tuner, it will be the last input */
+	/* If this board has a tuner, it will be the first input */
 	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
-			inp->index == go->board_info->num_inputs - 1)
+			inp->index == 0)
 		inp->type = V4L2_INPUT_TYPE_TUNER;
 	else
 		inp->type = V4L2_INPUT_TYPE_CAMERA;
@@ -1223,7 +1223,17 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
 
 	go->input = input;
 
-	return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0);
+	v4l2_subdev_call(go->sd_video, video, s_routing,
+			go->board_info->inputs[input].video_input, 0,
+			go->board_info->video_config);
+	if (go->board_info->num_aud_inputs) {
+		int aud_input = go->board_info->inputs[input].audio_index;
+
+		v4l2_subdev_call(go->sd_audio, audio, s_routing,
+			go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
+		go->aud_input = aud_input;
+	}
+	return 0;
 }
 
 static int vidioc_g_tuner(struct file *file, void *priv,
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index cf7c34a..e037a39 100644
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
@@ -468,7 +468,7 @@ static int saa7134_go7007_init(struct saa7134_dev *dev)
 
 	/* Do any final GO7007 initialization, then register the
 	 * V4L2 and ALSA interfaces */
-	if (go7007_register_encoder(go) < 0)
+	if (go7007_register_encoder(go, go->board_info->num_i2c_devs) < 0)
 		goto initfail;
 	dev->empress_dev = go->video_dev;
 	video_set_drvdata(dev->empress_dev, go);
-- 
1.7.10.4


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

* [REVIEW PATCH 17/42] go7007: remove all wis* drivers.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (14 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 16/42] go7007: switch to standard tuner/i2c subdevs Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 18/42] go7007: add audio input ioctls Hans Verkuil
                     ` (25 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

These are now no longer used and so they can be removed.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/wis-i2c.h        |   36 --
 drivers/staging/media/go7007/wis-ov7640.c     |   96 ----
 drivers/staging/media/go7007/wis-saa7113.c    |  324 -----------
 drivers/staging/media/go7007/wis-saa7115.c    |  457 ----------------
 drivers/staging/media/go7007/wis-sony-tuner.c |  707 -------------------------
 drivers/staging/media/go7007/wis-tw2804.c     |  348 ------------
 drivers/staging/media/go7007/wis-tw9903.c     |  328 ------------
 drivers/staging/media/go7007/wis-uda1342.c    |  102 ----
 8 files changed, 2398 deletions(-)
 delete mode 100644 drivers/staging/media/go7007/wis-i2c.h
 delete mode 100644 drivers/staging/media/go7007/wis-ov7640.c
 delete mode 100644 drivers/staging/media/go7007/wis-saa7113.c
 delete mode 100644 drivers/staging/media/go7007/wis-saa7115.c
 delete mode 100644 drivers/staging/media/go7007/wis-sony-tuner.c
 delete mode 100644 drivers/staging/media/go7007/wis-tw2804.c
 delete mode 100644 drivers/staging/media/go7007/wis-tw9903.c
 delete mode 100644 drivers/staging/media/go7007/wis-uda1342.c

diff --git a/drivers/staging/media/go7007/wis-i2c.h b/drivers/staging/media/go7007/wis-i2c.h
deleted file mode 100644
index 97763db..0000000
--- a/drivers/staging/media/go7007/wis-i2c.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-/* Temporary I2C IDs -- these need to be replaced with real registered IDs */
-#define	I2C_DRIVERID_WIS_SAA7115	0xf0f0
-#define	I2C_DRIVERID_WIS_UDA1342	0xf0f1
-#define	I2C_DRIVERID_WIS_SONY_TUNER	0xf0f2
-#define	I2C_DRIVERID_WIS_TW9903		0xf0f3
-#define	I2C_DRIVERID_WIS_SAA7113	0xf0f4
-#define	I2C_DRIVERID_WIS_OV7640		0xf0f5
-#define	I2C_DRIVERID_WIS_TW2804		0xf0f6
-#define	I2C_DRIVERID_S2250		0xf0f7
-
-/* Definitions for new video decoder commands */
-
-struct video_decoder_resolution {
-	unsigned int width;
-	unsigned int height;
-};
-
-#define	DECODER_SET_RESOLUTION	_IOW('d', 200, struct video_decoder_resolution)
-#define	DECODER_SET_CHANNEL	_IOW('d', 201, int)
diff --git a/drivers/staging/media/go7007/wis-ov7640.c b/drivers/staging/media/go7007/wis-ov7640.c
deleted file mode 100644
index 9f01657..0000000
--- a/drivers/staging/media/go7007/wis-ov7640.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-
-#include "wis-i2c.h"
-
-struct wis_ov7640 {
-	int brightness;
-	int contrast;
-	int saturation;
-	int hue;
-};
-
-static u8 initial_registers[] = {
-	0x12, 0x80,
-	0x12, 0x54,
-	0x14, 0x24,
-	0x15, 0x01,
-	0x28, 0x20,
-	0x75, 0x82,
-	0xFF, 0xFF, /* Terminator (reg 0xFF is unused) */
-};
-
-static int write_regs(struct i2c_client *client, u8 *regs)
-{
-	int i;
-
-	for (i = 0; regs[i] != 0xFF; i += 2)
-		if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
-			return -1;
-	return 0;
-}
-
-static int wis_ov7640_probe(struct i2c_client *client,
-			    const struct i2c_device_id *id)
-{
-	struct i2c_adapter *adapter = client->adapter;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -ENODEV;
-
-	client->flags = I2C_CLIENT_SCCB;
-
-	dev_dbg(&client->dev,
-		"wis-ov7640: initializing OV7640 at address %d on %s\n",
-		client->addr, adapter->name);
-
-	if (write_regs(client, initial_registers) < 0) {
-		dev_err(&client->dev, "wis-ov7640: error initializing OV7640\n");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-static int wis_ov7640_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
-static const struct i2c_device_id wis_ov7640_id[] = {
-	{ "wis_ov7640", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, wis_ov7640_id);
-
-static struct i2c_driver wis_ov7640_driver = {
-	.driver = {
-		.name	= "WIS OV7640 I2C driver",
-	},
-	.probe		= wis_ov7640_probe,
-	.remove		= wis_ov7640_remove,
-	.id_table	= wis_ov7640_id,
-};
-
-module_i2c_driver(wis_ov7640_driver);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/wis-saa7113.c b/drivers/staging/media/go7007/wis-saa7113.c
deleted file mode 100644
index 891cde7..0000000
--- a/drivers/staging/media/go7007/wis-saa7113.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-
-#include "wis-i2c.h"
-
-struct wis_saa7113 {
-	int norm;
-	int brightness;
-	int contrast;
-	int saturation;
-	int hue;
-};
-
-static u8 initial_registers[] = {
-	0x01, 0x08,
-	0x02, 0xc0,
-	0x03, 0x33,
-	0x04, 0x00,
-	0x05, 0x00,
-	0x06, 0xe9,
-	0x07, 0x0d,
-	0x08, 0xd8,
-	0x09, 0x40,
-	0x0a, 0x80,
-	0x0b, 0x47,
-	0x0c, 0x40,
-	0x0d, 0x00,
-	0x0e, 0x01,
-	0x0f, 0x2a,
-	0x10, 0x40,
-	0x11, 0x0c,
-	0x12, 0xfe,
-	0x13, 0x00,
-	0x14, 0x00,
-	0x15, 0x04,
-	0x16, 0x00,
-	0x17, 0x00,
-	0x18, 0x00,
-	0x19, 0x00,
-	0x1a, 0x00,
-	0x1b, 0x00,
-	0x1c, 0x00,
-	0x1d, 0x00,
-	0x1e, 0x00,
-	0x1f, 0xc8,
-	0x40, 0x00,
-	0x41, 0xff,
-	0x42, 0xff,
-	0x43, 0xff,
-	0x44, 0xff,
-	0x45, 0xff,
-	0x46, 0xff,
-	0x47, 0xff,
-	0x48, 0xff,
-	0x49, 0xff,
-	0x4a, 0xff,
-	0x4b, 0xff,
-	0x4c, 0xff,
-	0x4d, 0xff,
-	0x4e, 0xff,
-	0x4f, 0xff,
-	0x50, 0xff,
-	0x51, 0xff,
-	0x52, 0xff,
-	0x53, 0xff,
-	0x54, 0xff,
-	0x55, 0xff,
-	0x56, 0xff,
-	0x57, 0xff,
-	0x58, 0x00,
-	0x59, 0x54,
-	0x5a, 0x07,
-	0x5b, 0x83,
-	0x5c, 0x00,
-	0x5d, 0x00,
-	0x5e, 0x00,
-	0x5f, 0x00,
-	0x60, 0x00,
-	0x61, 0x00,
-	0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
-};
-
-static int write_reg(struct i2c_client *client, u8 reg, u8 value)
-{
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int write_regs(struct i2c_client *client, u8 *regs)
-{
-	int i;
-
-	for (i = 0; regs[i] != 0x00; i += 2)
-		if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
-			return -1;
-	return 0;
-}
-
-static int wis_saa7113_command(struct i2c_client *client,
-				unsigned int cmd, void *arg)
-{
-	struct wis_saa7113 *dec = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case VIDIOC_S_INPUT:
-	{
-		int *input = arg;
-
-		i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
-		i2c_smbus_write_byte_data(client, 0x09,
-				*input < 6 ? 0x40 : 0x80);
-		break;
-	}
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *input = arg;
-		dec->norm = *input;
-		if (dec->norm & V4L2_STD_NTSC) {
-			write_reg(client, 0x0e, 0x01);
-			write_reg(client, 0x10, 0x40);
-		} else if (dec->norm & V4L2_STD_PAL) {
-			write_reg(client, 0x0e, 0x01);
-			write_reg(client, 0x10, 0x48);
-		} else if (dec->norm & V4L2_STD_SECAM) {
-			write_reg(client, 0x0e, 0x50);
-			write_reg(client, 0x10, 0x48);
-		}
-		break;
-	}
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 255;
-			ctrl->step = 1;
-			ctrl->default_value = 128;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 127;
-			ctrl->step = 1;
-			ctrl->default_value = 71;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_SATURATION:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 127;
-			ctrl->step = 1;
-			ctrl->default_value = 64;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_HUE:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
-			ctrl->minimum = -128;
-			ctrl->maximum = 127;
-			ctrl->step = 1;
-			ctrl->default_value = 0;
-			ctrl->flags = 0;
-			break;
-		}
-		break;
-	}
-	case VIDIOC_S_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			if (ctrl->value > 255)
-				dec->brightness = 255;
-			else if (ctrl->value < 0)
-				dec->brightness = 0;
-			else
-				dec->brightness = ctrl->value;
-			write_reg(client, 0x0a, dec->brightness);
-			break;
-		case V4L2_CID_CONTRAST:
-			if (ctrl->value > 127)
-				dec->contrast = 127;
-			else if (ctrl->value < 0)
-				dec->contrast = 0;
-			else
-				dec->contrast = ctrl->value;
-			write_reg(client, 0x0b, dec->contrast);
-			break;
-		case V4L2_CID_SATURATION:
-			if (ctrl->value > 127)
-				dec->saturation = 127;
-			else if (ctrl->value < 0)
-				dec->saturation = 0;
-			else
-				dec->saturation = ctrl->value;
-			write_reg(client, 0x0c, dec->saturation);
-			break;
-		case V4L2_CID_HUE:
-			if (ctrl->value > 127)
-				dec->hue = 127;
-			else if (ctrl->value < -128)
-				dec->hue = -128;
-			else
-				dec->hue = ctrl->value;
-			write_reg(client, 0x0d, dec->hue);
-			break;
-		}
-		break;
-	}
-	case VIDIOC_G_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->value = dec->brightness;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->value = dec->contrast;
-			break;
-		case V4L2_CID_SATURATION:
-			ctrl->value = dec->saturation;
-			break;
-		case V4L2_CID_HUE:
-			ctrl->value = dec->hue;
-			break;
-		}
-		break;
-	}
-	default:
-		break;
-	}
-	return 0;
-}
-
-static int wis_saa7113_probe(struct i2c_client *client,
-			     const struct i2c_device_id *id)
-{
-	struct i2c_adapter *adapter = client->adapter;
-	struct wis_saa7113 *dec;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -ENODEV;
-
-	dec = kmalloc(sizeof(struct wis_saa7113), GFP_KERNEL);
-	if (dec == NULL)
-		return -ENOMEM;
-
-	dec->norm = V4L2_STD_NTSC;
-	dec->brightness = 128;
-	dec->contrast = 71;
-	dec->saturation = 64;
-	dec->hue = 0;
-	i2c_set_clientdata(client, dec);
-
-	dev_dbg(&client->dev,
-		"wis-saa7113: initializing SAA7113 at address %d on %s\n",
-		client->addr, adapter->name);
-
-	if (write_regs(client, initial_registers) < 0) {
-		dev_err(&client->dev,
-			"wis-saa7113: error initializing SAA7113\n");
-		kfree(dec);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-static int wis_saa7113_remove(struct i2c_client *client)
-{
-	struct wis_saa7113 *dec = i2c_get_clientdata(client);
-
-	kfree(dec);
-	return 0;
-}
-
-static const struct i2c_device_id wis_saa7113_id[] = {
-	{ "wis_saa7113", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, wis_saa7113_id);
-
-static struct i2c_driver wis_saa7113_driver = {
-	.driver = {
-		.name	= "WIS SAA7113 I2C driver",
-	},
-	.probe		= wis_saa7113_probe,
-	.remove		= wis_saa7113_remove,
-	.command	= wis_saa7113_command,
-	.id_table	= wis_saa7113_id,
-};
-
-module_i2c_driver(wis_saa7113_driver);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/wis-saa7115.c b/drivers/staging/media/go7007/wis-saa7115.c
deleted file mode 100644
index fa86acd..0000000
--- a/drivers/staging/media/go7007/wis-saa7115.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-
-#include "wis-i2c.h"
-
-struct wis_saa7115 {
-	int norm;
-	int brightness;
-	int contrast;
-	int saturation;
-	int hue;
-};
-
-static u8 initial_registers[] = {
-	0x01, 0x08,
-	0x02, 0xc0,
-	0x03, 0x20,
-	0x04, 0x80,
-	0x05, 0x80,
-	0x06, 0xeb,
-	0x07, 0xe0,
-	0x08, 0xf0,	/* always toggle FID */
-	0x09, 0x40,
-	0x0a, 0x80,
-	0x0b, 0x40,
-	0x0c, 0x40,
-	0x0d, 0x00,
-	0x0e, 0x03,
-	0x0f, 0x2a,
-	0x10, 0x0e,
-	0x11, 0x00,
-	0x12, 0x8d,
-	0x13, 0x00,
-	0x14, 0x00,
-	0x15, 0x11,
-	0x16, 0x01,
-	0x17, 0xda,
-	0x18, 0x40,
-	0x19, 0x80,
-	0x1a, 0x00,
-	0x1b, 0x42,
-	0x1c, 0xa9,
-	0x30, 0x66,
-	0x31, 0x90,
-	0x32, 0x01,
-	0x34, 0x00,
-	0x35, 0x00,
-	0x36, 0x20,
-	0x38, 0x03,
-	0x39, 0x20,
-	0x3a, 0x88,
-	0x40, 0x00,
-	0x41, 0xff,
-	0x42, 0xff,
-	0x43, 0xff,
-	0x44, 0xff,
-	0x45, 0xff,
-	0x46, 0xff,
-	0x47, 0xff,
-	0x48, 0xff,
-	0x49, 0xff,
-	0x4a, 0xff,
-	0x4b, 0xff,
-	0x4c, 0xff,
-	0x4d, 0xff,
-	0x4e, 0xff,
-	0x4f, 0xff,
-	0x50, 0xff,
-	0x51, 0xff,
-	0x52, 0xff,
-	0x53, 0xff,
-	0x54, 0xf4 /*0xff*/,
-	0x55, 0xff,
-	0x56, 0xff,
-	0x57, 0xff,
-	0x58, 0x40,
-	0x59, 0x47,
-	0x5a, 0x06 /*0x03*/,
-	0x5b, 0x83,
-	0x5d, 0x06,
-	0x5e, 0x00,
-	0x80, 0x30, /* window defined scaler operation, task A and B enabled */
-	0x81, 0x03, /* use scaler datapath generated V */
-	0x83, 0x00,
-	0x84, 0x00,
-	0x85, 0x00,
-	0x86, 0x45,
-	0x87, 0x31,
-	0x88, 0xc0,
-	0x90, 0x02, /* task A process top field */
-	0x91, 0x08,
-	0x92, 0x09,
-	0x93, 0x80,
-	0x94, 0x06,
-	0x95, 0x00,
-	0x96, 0xc0,
-	0x97, 0x02,
-	0x98, 0x12,
-	0x99, 0x00,
-	0x9a, 0xf2,
-	0x9b, 0x00,
-	0x9c, 0xd0,
-	0x9d, 0x02,
-	0x9e, 0xf2,
-	0x9f, 0x00,
-	0xa0, 0x01,
-	0xa1, 0x01,
-	0xa2, 0x01,
-	0xa4, 0x80,
-	0xa5, 0x40,
-	0xa6, 0x40,
-	0xa8, 0x00,
-	0xa9, 0x04,
-	0xaa, 0x00,
-	0xac, 0x00,
-	0xad, 0x02,
-	0xae, 0x00,
-	0xb0, 0x00,
-	0xb1, 0x04,
-	0xb2, 0x00,
-	0xb3, 0x04,
-	0xb4, 0x00,
-	0xb8, 0x00,
-	0xbc, 0x00,
-	0xc0, 0x03,	/* task B process bottom field */
-	0xc1, 0x08,
-	0xc2, 0x09,
-	0xc3, 0x80,
-	0xc4, 0x06,
-	0xc5, 0x00,
-	0xc6, 0xc0,
-	0xc7, 0x02,
-	0xc8, 0x12,
-	0xc9, 0x00,
-	0xca, 0xf2,
-	0xcb, 0x00,
-	0xcc, 0xd0,
-	0xcd, 0x02,
-	0xce, 0xf2,
-	0xcf, 0x00,
-	0xd0, 0x01,
-	0xd1, 0x01,
-	0xd2, 0x01,
-	0xd4, 0x80,
-	0xd5, 0x40,
-	0xd6, 0x40,
-	0xd8, 0x00,
-	0xd9, 0x04,
-	0xda, 0x00,
-	0xdc, 0x00,
-	0xdd, 0x02,
-	0xde, 0x00,
-	0xe0, 0x00,
-	0xe1, 0x04,
-	0xe2, 0x00,
-	0xe3, 0x04,
-	0xe4, 0x00,
-	0xe8, 0x00,
-	0x88, 0xf0, /* End of original static list */
-	0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
-};
-
-static int write_reg(struct i2c_client *client, u8 reg, u8 value)
-{
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int write_regs(struct i2c_client *client, u8 *regs)
-{
-	int i;
-
-	for (i = 0; regs[i] != 0x00; i += 2)
-		if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
-			return -1;
-	return 0;
-}
-
-static int wis_saa7115_command(struct i2c_client *client,
-				unsigned int cmd, void *arg)
-{
-	struct wis_saa7115 *dec = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case VIDIOC_S_INPUT:
-	{
-		int *input = arg;
-
-		i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
-		i2c_smbus_write_byte_data(client, 0x09,
-				*input < 6 ? 0x40 : 0xC0);
-		break;
-	}
-	case DECODER_SET_RESOLUTION:
-	{
-		struct video_decoder_resolution *res = arg;
-		/* Course-grained scaler */
-		int h_integer_scaler = res->width < 704 ? 704 / res->width : 1;
-		/* Fine-grained scaler to take care of remainder */
-		int h_scaling_increment = (704 / h_integer_scaler) *
-					1024 / res->width;
-		/* Fine-grained scaler only */
-		int v_scaling_increment = (dec->norm & V4L2_STD_NTSC ?
-				240 : 288) * 1024 / res->height;
-		u8 regs[] = {
-			0x88,	0xc0,
-			0x9c,	res->width & 0xff,
-			0x9d,	res->width >> 8,
-			0x9e,	res->height & 0xff,
-			0x9f,	res->height >> 8,
-			0xa0,	h_integer_scaler,
-			0xa1,	1,
-			0xa2,	1,
-			0xa8,	h_scaling_increment & 0xff,
-			0xa9,	h_scaling_increment >> 8,
-			0xac,	(h_scaling_increment / 2) & 0xff,
-			0xad,	(h_scaling_increment / 2) >> 8,
-			0xb0,	v_scaling_increment & 0xff,
-			0xb1,	v_scaling_increment >> 8,
-			0xb2,	v_scaling_increment & 0xff,
-			0xb3,	v_scaling_increment >> 8,
-			0xcc,	res->width & 0xff,
-			0xcd,	res->width >> 8,
-			0xce,	res->height & 0xff,
-			0xcf,	res->height >> 8,
-			0xd0,	h_integer_scaler,
-			0xd1,	1,
-			0xd2,	1,
-			0xd8,	h_scaling_increment & 0xff,
-			0xd9,	h_scaling_increment >> 8,
-			0xdc,	(h_scaling_increment / 2) & 0xff,
-			0xdd,	(h_scaling_increment / 2) >> 8,
-			0xe0,	v_scaling_increment & 0xff,
-			0xe1,	v_scaling_increment >> 8,
-			0xe2,	v_scaling_increment & 0xff,
-			0xe3,	v_scaling_increment >> 8,
-			0x88,	0xf0,
-			0,	0,
-		};
-		write_regs(client, regs);
-		break;
-	}
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *input = arg;
-		u8 regs[] = {
-			0x88,	0xc0,
-			0x98,	*input & V4L2_STD_NTSC ? 0x12 : 0x16,
-			0x9a,	*input & V4L2_STD_NTSC ? 0xf2 : 0x20,
-			0x9b,	*input & V4L2_STD_NTSC ? 0x00 : 0x01,
-			0xc8,	*input & V4L2_STD_NTSC ? 0x12 : 0x16,
-			0xca,	*input & V4L2_STD_NTSC ? 0xf2 : 0x20,
-			0xcb,	*input & V4L2_STD_NTSC ? 0x00 : 0x01,
-			0x88,	0xf0,
-			0x30,	*input & V4L2_STD_NTSC ? 0x66 : 0x00,
-			0x31,	*input & V4L2_STD_NTSC ? 0x90 : 0xe0,
-			0,	0,
-		};
-		write_regs(client, regs);
-		dec->norm = *input;
-		break;
-	}
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 255;
-			ctrl->step = 1;
-			ctrl->default_value = 128;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 127;
-			ctrl->step = 1;
-			ctrl->default_value = 64;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_SATURATION:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 127;
-			ctrl->step = 1;
-			ctrl->default_value = 64;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_HUE:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
-			ctrl->minimum = -128;
-			ctrl->maximum = 127;
-			ctrl->step = 1;
-			ctrl->default_value = 0;
-			ctrl->flags = 0;
-			break;
-		}
-		break;
-	}
-	case VIDIOC_S_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			if (ctrl->value > 255)
-				dec->brightness = 255;
-			else if (ctrl->value < 0)
-				dec->brightness = 0;
-			else
-				dec->brightness = ctrl->value;
-			write_reg(client, 0x0a, dec->brightness);
-			break;
-		case V4L2_CID_CONTRAST:
-			if (ctrl->value > 127)
-				dec->contrast = 127;
-			else if (ctrl->value < 0)
-				dec->contrast = 0;
-			else
-				dec->contrast = ctrl->value;
-			write_reg(client, 0x0b, dec->contrast);
-			break;
-		case V4L2_CID_SATURATION:
-			if (ctrl->value > 127)
-				dec->saturation = 127;
-			else if (ctrl->value < 0)
-				dec->saturation = 0;
-			else
-				dec->saturation = ctrl->value;
-			write_reg(client, 0x0c, dec->saturation);
-			break;
-		case V4L2_CID_HUE:
-			if (ctrl->value > 127)
-				dec->hue = 127;
-			else if (ctrl->value < -128)
-				dec->hue = -128;
-			else
-				dec->hue = ctrl->value;
-			write_reg(client, 0x0d, dec->hue);
-			break;
-		}
-		break;
-	}
-	case VIDIOC_G_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->value = dec->brightness;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->value = dec->contrast;
-			break;
-		case V4L2_CID_SATURATION:
-			ctrl->value = dec->saturation;
-			break;
-		case V4L2_CID_HUE:
-			ctrl->value = dec->hue;
-			break;
-		}
-		break;
-	}
-	default:
-		break;
-	}
-	return 0;
-}
-
-static int wis_saa7115_probe(struct i2c_client *client,
-			     const struct i2c_device_id *id)
-{
-	struct i2c_adapter *adapter = client->adapter;
-	struct wis_saa7115 *dec;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -ENODEV;
-
-	dec = kmalloc(sizeof(struct wis_saa7115), GFP_KERNEL);
-	if (dec == NULL)
-		return -ENOMEM;
-
-	dec->norm = V4L2_STD_NTSC;
-	dec->brightness = 128;
-	dec->contrast = 64;
-	dec->saturation = 64;
-	dec->hue = 0;
-	i2c_set_clientdata(client, dec);
-
-	dev_dbg(&client->dev,
-		"wis-saa7115: initializing SAA7115 at address %d on %s\n",
-		client->addr, adapter->name);
-
-	if (write_regs(client, initial_registers) < 0) {
-		dev_err(&client->dev,
-			"wis-saa7115: error initializing SAA7115\n");
-		kfree(dec);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-static int wis_saa7115_remove(struct i2c_client *client)
-{
-	struct wis_saa7115 *dec = i2c_get_clientdata(client);
-
-	kfree(dec);
-	return 0;
-}
-
-static const struct i2c_device_id wis_saa7115_id[] = {
-	{ "wis_saa7115", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, wis_saa7115_id);
-
-static struct i2c_driver wis_saa7115_driver = {
-	.driver = {
-		.name	= "WIS SAA7115 I2C driver",
-	},
-	.probe		= wis_saa7115_probe,
-	.remove		= wis_saa7115_remove,
-	.command	= wis_saa7115_command,
-	.id_table	= wis_saa7115_id,
-};
-
-module_i2c_driver(wis_saa7115_driver);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/wis-sony-tuner.c b/drivers/staging/media/go7007/wis-sony-tuner.c
deleted file mode 100644
index 5d7ff8c..0000000
--- a/drivers/staging/media/go7007/wis-sony-tuner.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <media/tuner.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-
-#include "wis-i2c.h"
-
-/* #define MPX_DEBUG */
-
-/* AS(IF/MPX) pin:      LOW      HIGH/OPEN
- * IF/MPX address:   0x42/0x40   0x43/0x44
- */
-#define IF_I2C_ADDR	0x43
-#define MPX_I2C_ADDR	0x44
-
-static v4l2_std_id force_band;
-static char force_band_str[] = "-";
-module_param_string(force_band, force_band_str, sizeof(force_band_str), 0644);
-static int force_mpx_mode = -1;
-module_param(force_mpx_mode, int, 0644);
-
-/* Store tuner info in the same format as tuner.c, so maybe we can put the
- * Sony tuner support in there. */
-struct sony_tunertype {
-	char *name;
-	unsigned char Vendor; /* unused here */
-	unsigned char Type; /* unused here */
-
-	unsigned short thresh1; /*  band switch VHF_LO <=> VHF_HI */
-	unsigned short thresh2; /*  band switch VHF_HI <=> UHF */
-	unsigned char VHF_L;
-	unsigned char VHF_H;
-	unsigned char UHF;
-	unsigned char config;
-	unsigned short IFPCoff;
-};
-
-/* This array is indexed by (tuner_type - 200) */
-static struct sony_tunertype sony_tuners[] = {
-	{ "Sony PAL+SECAM (BTF-PG472Z)", 0, 0,
-	  16*144.25, 16*427.25, 0x01, 0x02, 0x04, 0xc6, 623},
-	{ "Sony NTSC_JP (BTF-PK467Z)", 0, 0,
-	  16*220.25, 16*467.25, 0x01, 0x02, 0x04, 0xc6, 940},
-	{ "Sony NTSC (BTF-PB463Z)", 0, 0,
-	  16*130.25, 16*364.25, 0x01, 0x02, 0x04, 0xc6, 732},
-};
-
-struct wis_sony_tuner {
-	int type;
-	v4l2_std_id std;
-	unsigned int freq;
-	int mpxmode;
-	u32 audmode;
-};
-
-/* Basically the same as default_set_tv_freq() in tuner.c */
-static int set_freq(struct i2c_client *client, int freq)
-{
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
-	char *band_name;
-	int n;
-	int band_select;
-	struct sony_tunertype *tun;
-	u8 buffer[4];
-
-	tun = &sony_tuners[t->type - 200];
-	if (freq < tun->thresh1) {
-		band_name = "VHF_L";
-		band_select = tun->VHF_L;
-	} else if (freq < tun->thresh2) {
-		band_name = "VHF_H";
-		band_select = tun->VHF_H;
-	} else {
-		band_name = "UHF";
-		band_select = tun->UHF;
-	}
-	dev_dbg(&client->dev, "tuning to frequency %d.%04d (%s)\n",
-		freq / 16, (freq % 16) * 625, band_name);
-	n = freq + tun->IFPCoff;
-
-	buffer[0] = n >> 8;
-	buffer[1] = n & 0xff;
-	buffer[2] = tun->config;
-	buffer[3] = band_select;
-	i2c_master_send(client, buffer, 4);
-
-	return 0;
-}
-
-static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
-{
-	u8 buffer[5];
-	struct i2c_msg msg;
-
-	buffer[0] = dev;
-	buffer[1] = addr >> 8;
-	buffer[2] = addr & 0xff;
-	buffer[3] = val >> 8;
-	buffer[4] = val & 0xff;
-	msg.addr = MPX_I2C_ADDR;
-	msg.flags = 0;
-	msg.len = 5;
-	msg.buf = buffer;
-	i2c_transfer(client->adapter, &msg, 1);
-	return 0;
-}
-
-/*
- * MPX register values for the BTF-PG472Z:
- *
- *                                 FM_     NICAM_  SCART_
- *          MODUS  SOURCE    ACB   PRESCAL PRESCAL PRESCAL SYSTEM  VOLUME
- *         10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000
- *         ---------------------------------------------------------------
- * Auto     1003    0020    0100    2603    5000    XXXX    0001    7500
- *
- * B/G
- *  Mono    1003    0020    0100    2603    5000    XXXX    0003    7500
- *  A2      1003    0020    0100    2601    5000    XXXX    0003    7500
- *  NICAM   1003    0120    0100    2603    5000    XXXX    0008    7500
- *
- * I
- *  Mono    1003    0020    0100    2603    7900    XXXX    000A    7500
- *  NICAM   1003    0120    0100    2603    7900    XXXX    000A    7500
- *
- * D/K
- *  Mono    1003    0020    0100    2603    5000    XXXX    0004    7500
- *  A2-1    1003    0020    0100    2601    5000    XXXX    0004    7500
- *  A2-2    1003    0020    0100    2601    5000    XXXX    0005    7500
- *  A2-3    1003    0020    0100    2601    5000    XXXX    0007    7500
- *  NICAM   1003    0120    0100    2603    5000    XXXX    000B    7500
- *
- * L/L'
- *  Mono    0003    0200    0100    7C03    5000    2200    0009    7500
- *  NICAM   0003    0120    0100    7C03    5000    XXXX    0009    7500
- *
- * M
- *  Mono    1003    0200    0100    2B03    5000    2B00    0002    7500
- *
- * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX.
- *
- * Bilingual selection in A2/NICAM:
- *
- *         High byte of SOURCE     Left chan   Right chan
- *                 0x01              MAIN         SUB
- *                 0x03              MAIN         MAIN
- *                 0x04              SUB          SUB
- *
- * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or
- * 0x00 (all other bands).  Force mono in A2 with FMONO_A2:
- *
- *                      FMONO_A2
- *                      10/0022
- *                      --------
- *     Forced mono ON     07F0
- *     Forced mono OFF    0190
- */
-
-static struct {
-	enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
-	u16 modus;
-	u16 source;
-	u16 acb;
-	u16 fm_prescale;
-	u16 nicam_prescale;
-	u16 scart_prescale;
-	u16 system;
-	u16 volume;
-} mpx_audio_modes[] = {
-	/* Auto */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
-					0x5000, 0x0000, 0x0001, 0x7500 },
-	/* B/G Mono */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
-					0x5000, 0x0000, 0x0003, 0x7500 },
-	/* B/G A2 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
-					0x5000, 0x0000, 0x0003, 0x7500 },
-	/* B/G NICAM */ { AUD_NICAM,	0x1003, 0x0120, 0x0100, 0x2603,
-					0x5000, 0x0000, 0x0008, 0x7500 },
-	/* I Mono */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
-					0x7900, 0x0000, 0x000A, 0x7500 },
-	/* I NICAM */	{ AUD_NICAM,	0x1003, 0x0120, 0x0100, 0x2603,
-					0x7900, 0x0000, 0x000A, 0x7500 },
-	/* D/K Mono */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
-					0x5000, 0x0000, 0x0004, 0x7500 },
-	/* D/K A2-1 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
-					0x5000, 0x0000, 0x0004, 0x7500 },
-	/* D/K A2-2 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
-					0x5000, 0x0000, 0x0005, 0x7500 },
-	/* D/K A2-3 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
-					0x5000, 0x0000, 0x0007, 0x7500 },
-	/* D/K NICAM */	{ AUD_NICAM,	0x1003, 0x0120, 0x0100, 0x2603,
-					0x5000, 0x0000, 0x000B, 0x7500 },
-	/* L/L' Mono */	{ AUD_MONO,	0x0003, 0x0200, 0x0100, 0x7C03,
-					0x5000, 0x2200, 0x0009, 0x7500 },
-	/* L/L' NICAM */{ AUD_NICAM_L,	0x0003, 0x0120, 0x0100, 0x7C03,
-					0x5000, 0x0000, 0x0009, 0x7500 },
-};
-
-#define MPX_NUM_MODES	ARRAY_SIZE(mpx_audio_modes)
-
-static int mpx_setup(struct i2c_client *client)
-{
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
-	u16 source = 0;
-	u8 buffer[3];
-	struct i2c_msg msg;
-
-	/* reset MPX */
-	buffer[0] = 0x00;
-	buffer[1] = 0x80;
-	buffer[2] = 0x00;
-	msg.addr = MPX_I2C_ADDR;
-	msg.flags = 0;
-	msg.len = 3;
-	msg.buf = buffer;
-	i2c_transfer(client->adapter, &msg, 1);
-	buffer[1] = 0x00;
-	i2c_transfer(client->adapter, &msg, 1);
-
-	if (mpx_audio_modes[t->mpxmode].audio_mode != AUD_MONO) {
-		switch (t->audmode) {
-		case V4L2_TUNER_MODE_MONO:
-			switch (mpx_audio_modes[t->mpxmode].audio_mode) {
-			case AUD_A2:
-				source = mpx_audio_modes[t->mpxmode].source;
-				break;
-			case AUD_NICAM:
-				source = 0x0000;
-				break;
-			case AUD_NICAM_L:
-				source = 0x0200;
-				break;
-			default:
-				break;
-			}
-			break;
-		case V4L2_TUNER_MODE_STEREO:
-			source = mpx_audio_modes[t->mpxmode].source;
-			break;
-		case V4L2_TUNER_MODE_LANG1:
-			source = 0x0300;
-			break;
-		case V4L2_TUNER_MODE_LANG2:
-			source = 0x0400;
-			break;
-		}
-		source |= mpx_audio_modes[t->mpxmode].source & 0x00ff;
-	} else
-		source = mpx_audio_modes[t->mpxmode].source;
-
-	mpx_write(client, 0x10, 0x0030, mpx_audio_modes[t->mpxmode].modus);
-	mpx_write(client, 0x12, 0x0008, source);
-	mpx_write(client, 0x12, 0x0013, mpx_audio_modes[t->mpxmode].acb);
-	mpx_write(client, 0x12, 0x000e,
-			mpx_audio_modes[t->mpxmode].fm_prescale);
-	mpx_write(client, 0x12, 0x0010,
-			mpx_audio_modes[t->mpxmode].nicam_prescale);
-	mpx_write(client, 0x12, 0x000d,
-			mpx_audio_modes[t->mpxmode].scart_prescale);
-	mpx_write(client, 0x10, 0x0020, mpx_audio_modes[t->mpxmode].system);
-	mpx_write(client, 0x12, 0x0000, mpx_audio_modes[t->mpxmode].volume);
-	if (mpx_audio_modes[t->mpxmode].audio_mode == AUD_A2)
-		mpx_write(client, 0x10, 0x0022,
-			t->audmode == V4L2_TUNER_MODE_MONO ?  0x07f0 : 0x0190);
-
-#ifdef MPX_DEBUG
-	{
-		u8 buf1[3], buf2[2];
-		struct i2c_msg msgs[2];
-
-		dev_dbg(&client->dev,
-			"MPX registers: %04x %04x %04x %04x %04x %04x %04x %04x\n",
-			mpx_audio_modes[t->mpxmode].modus,
-			source,
-			mpx_audio_modes[t->mpxmode].acb,
-			mpx_audio_modes[t->mpxmode].fm_prescale,
-			mpx_audio_modes[t->mpxmode].nicam_prescale,
-			mpx_audio_modes[t->mpxmode].scart_prescale,
-			mpx_audio_modes[t->mpxmode].system,
-			mpx_audio_modes[t->mpxmode].volume);
-		buf1[0] = 0x11;
-		buf1[1] = 0x00;
-		buf1[2] = 0x7e;
-		msgs[0].addr = MPX_I2C_ADDR;
-		msgs[0].flags = 0;
-		msgs[0].len = 3;
-		msgs[0].buf = buf1;
-		msgs[1].addr = MPX_I2C_ADDR;
-		msgs[1].flags = I2C_M_RD;
-		msgs[1].len = 2;
-		msgs[1].buf = buf2;
-		i2c_transfer(client->adapter, msgs, 2);
-		dev_dbg(&client->dev, "MPX system: %02x%02x\n",
-			buf2[0], buf2[1]);
-		buf1[0] = 0x11;
-		buf1[1] = 0x02;
-		buf1[2] = 0x00;
-		i2c_transfer(client->adapter, msgs, 2);
-		dev_dbg(&client->dev, "MPX status: %02x%02x\n",
-			buf2[0], buf2[1]);
-	}
-#endif
-	return 0;
-}
-
-/*
- * IF configuration values for the BTF-PG472Z:
- *
- *	B/G: 0x94 0x70 0x49
- *	I:   0x14 0x70 0x4a
- *	D/K: 0x14 0x70 0x4b
- *	L:   0x04 0x70 0x4b
- *	L':  0x44 0x70 0x53
- *	M:   0x50 0x30 0x4c
- */
-
-static int set_if(struct i2c_client *client)
-{
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
-	u8 buffer[4];
-	struct i2c_msg msg;
-	int default_mpx_mode = 0;
-
-	/* configure IF */
-	buffer[0] = 0;
-	if (t->std & V4L2_STD_PAL_BG) {
-		buffer[1] = 0x94;
-		buffer[2] = 0x70;
-		buffer[3] = 0x49;
-		default_mpx_mode = 1;
-	} else if (t->std & V4L2_STD_PAL_I) {
-		buffer[1] = 0x14;
-		buffer[2] = 0x70;
-		buffer[3] = 0x4a;
-		default_mpx_mode = 4;
-	} else if (t->std & V4L2_STD_PAL_DK) {
-		buffer[1] = 0x14;
-		buffer[2] = 0x70;
-		buffer[3] = 0x4b;
-		default_mpx_mode = 6;
-	} else if (t->std & V4L2_STD_SECAM_L) {
-		buffer[1] = 0x04;
-		buffer[2] = 0x70;
-		buffer[3] = 0x4b;
-		default_mpx_mode = 11;
-	}
-	msg.addr = IF_I2C_ADDR;
-	msg.flags = 0;
-	msg.len = 4;
-	msg.buf = buffer;
-	i2c_transfer(client->adapter, &msg, 1);
-
-	/* Select MPX mode if not forced by the user */
-	if (force_mpx_mode >= 0 && force_mpx_mode < MPX_NUM_MODES)
-		t->mpxmode = force_mpx_mode;
-	else
-		t->mpxmode = default_mpx_mode;
-	dev_dbg(&client->dev, "setting MPX to mode %d\n", t->mpxmode);
-	mpx_setup(client);
-
-	return 0;
-}
-
-static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
-
-	switch (cmd) {
-#if 0
-#ifdef TUNER_SET_TYPE_ADDR
-	case TUNER_SET_TYPE_ADDR:
-	{
-		struct tuner_setup *tun_setup = arg;
-		int *type = &tun_setup->type;
-#else
-	case TUNER_SET_TYPE:
-	{
-		int *type = arg;
-#endif
-
-		if (t->type >= 0) {
-			if (t->type != *type)
-				dev_err(&client->dev,
-					"type already set to %d, ignoring request for %d\n",
-					t->type, *type);
-			break;
-		}
-		t->type = *type;
-		switch (t->type) {
-		case TUNER_SONY_BTF_PG472Z:
-			switch (force_band_str[0]) {
-			case 'b':
-			case 'B':
-			case 'g':
-			case 'G':
-				dev_info(&client->dev,
-					 "forcing tuner to PAL-B/G bands\n");
-				force_band = V4L2_STD_PAL_BG;
-				break;
-			case 'i':
-			case 'I':
-				dev_info(&client->dev,
-					 "forcing tuner to PAL-I band\n");
-				force_band = V4L2_STD_PAL_I;
-				break;
-			case 'd':
-			case 'D':
-			case 'k':
-			case 'K':
-				dev_info(&client->dev,
-					 "forcing tuner to PAL-D/K bands\n");
-				force_band = V4L2_STD_PAL_I;
-				break;
-			case 'l':
-			case 'L':
-				dev_info(&client->dev,
-					 "forcing tuner to SECAM-L band\n");
-				force_band = V4L2_STD_SECAM_L;
-				break;
-			default:
-				force_band = 0;
-				break;
-			}
-			if (force_band)
-				t->std = force_band;
-			else
-				t->std = V4L2_STD_PAL_BG;
-			set_if(client);
-			break;
-		case TUNER_SONY_BTF_PK467Z:
-			t->std = V4L2_STD_NTSC_M_JP;
-			break;
-		case TUNER_SONY_BTF_PB463Z:
-			t->std = V4L2_STD_NTSC_M;
-			break;
-		default:
-			dev_err(&client->dev,
-				"tuner type %d is not supported by this module\n",
-				*type);
-			break;
-		}
-		if (type >= 0)
-			dev_info(&clinet->dev,
-				 "type set to %d (%s)\n",
-				 t->type, sony_tuners[t->type - 200].name);
-		break;
-	}
-#endif
-	case VIDIOC_G_FREQUENCY:
-	{
-		struct v4l2_frequency *f = arg;
-
-		f->frequency = t->freq;
-		break;
-	}
-	case VIDIOC_S_FREQUENCY:
-	{
-		struct v4l2_frequency *f = arg;
-
-		t->freq = f->frequency;
-		set_freq(client, t->freq);
-		break;
-	}
-	case VIDIOC_ENUMSTD:
-	{
-		struct v4l2_standard *std = arg;
-
-		switch (t->type) {
-		case TUNER_SONY_BTF_PG472Z:
-			switch (std->index) {
-			case 0:
-				v4l2_video_std_construct(std,
-						V4L2_STD_PAL_BG, "PAL-B/G");
-				break;
-			case 1:
-				v4l2_video_std_construct(std,
-						V4L2_STD_PAL_I, "PAL-I");
-				break;
-			case 2:
-				v4l2_video_std_construct(std,
-						V4L2_STD_PAL_DK, "PAL-D/K");
-				break;
-			case 3:
-				v4l2_video_std_construct(std,
-						V4L2_STD_SECAM_L, "SECAM-L");
-				break;
-			default:
-				std->id = 0; /* hack to indicate EINVAL */
-				break;
-			}
-			break;
-		case TUNER_SONY_BTF_PK467Z:
-			if (std->index != 0) {
-				std->id = 0; /* hack to indicate EINVAL */
-				break;
-			}
-			v4l2_video_std_construct(std,
-					V4L2_STD_NTSC_M_JP, "NTSC-J");
-			break;
-		case TUNER_SONY_BTF_PB463Z:
-			if (std->index != 0) {
-				std->id = 0; /* hack to indicate EINVAL */
-				break;
-			}
-			v4l2_video_std_construct(std, V4L2_STD_NTSC_M, "NTSC");
-			break;
-		}
-		break;
-	}
-	case VIDIOC_G_STD:
-	{
-		v4l2_std_id *std = arg;
-
-		*std = t->std;
-		break;
-	}
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *std = arg;
-		v4l2_std_id old = t->std;
-
-		switch (t->type) {
-		case TUNER_SONY_BTF_PG472Z:
-			if (force_band && (*std & force_band) != *std &&
-					*std != V4L2_STD_PAL &&
-					*std != V4L2_STD_SECAM) {
-				dev_dbg(&client->dev,
-					"ignoring requested TV standard in favor of force_band value\n");
-				t->std = force_band;
-			} else if (*std & V4L2_STD_PAL_BG) { /* default */
-				t->std = V4L2_STD_PAL_BG;
-			} else if (*std & V4L2_STD_PAL_I) {
-				t->std = V4L2_STD_PAL_I;
-			} else if (*std & V4L2_STD_PAL_DK) {
-				t->std = V4L2_STD_PAL_DK;
-			} else if (*std & V4L2_STD_SECAM_L) {
-				t->std = V4L2_STD_SECAM_L;
-			} else {
-				dev_err(&client->dev,
-					"TV standard not supported\n");
-				*std = 0; /* hack to indicate EINVAL */
-				break;
-			}
-			if (old != t->std)
-				set_if(client);
-			break;
-		case TUNER_SONY_BTF_PK467Z:
-			if (!(*std & V4L2_STD_NTSC_M_JP)) {
-				dev_err(&client->dev,
-					"TV standard not supported\n");
-				*std = 0; /* hack to indicate EINVAL */
-			}
-			break;
-		case TUNER_SONY_BTF_PB463Z:
-			if (!(*std & V4L2_STD_NTSC_M)) {
-				dev_err(&client->dev,
-					"TV standard not supported\n");
-				*std = 0; /* hack to indicate EINVAL */
-			}
-			break;
-		}
-		break;
-	}
-	case VIDIOC_QUERYSTD:
-	{
-		v4l2_std_id *std = arg;
-
-		switch (t->type) {
-		case TUNER_SONY_BTF_PG472Z:
-			if (force_band)
-				*std = force_band;
-			else
-				*std = V4L2_STD_PAL_BG | V4L2_STD_PAL_I |
-					V4L2_STD_PAL_DK | V4L2_STD_SECAM_L;
-			break;
-		case TUNER_SONY_BTF_PK467Z:
-			*std = V4L2_STD_NTSC_M_JP;
-			break;
-		case TUNER_SONY_BTF_PB463Z:
-			*std = V4L2_STD_NTSC_M;
-			break;
-		}
-		break;
-	}
-	case VIDIOC_G_TUNER:
-	{
-		struct v4l2_tuner *tun = arg;
-
-		memset(tun, 0, sizeof(*tun));
-		strcpy(tun->name, "Television");
-		tun->type = V4L2_TUNER_ANALOG_TV;
-		tun->rangelow = 0UL; /* does anything use these? */
-		tun->rangehigh = 0xffffffffUL;
-		switch (t->type) {
-		case TUNER_SONY_BTF_PG472Z:
-			tun->capability = V4L2_TUNER_CAP_NORM |
-				V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
-				V4L2_TUNER_CAP_LANG2;
-			tun->rxsubchans = V4L2_TUNER_SUB_MONO |
-				V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
-				V4L2_TUNER_SUB_LANG2;
-			break;
-		case TUNER_SONY_BTF_PK467Z:
-		case TUNER_SONY_BTF_PB463Z:
-			tun->capability = V4L2_TUNER_CAP_STEREO;
-			tun->rxsubchans = V4L2_TUNER_SUB_MONO |
-						V4L2_TUNER_SUB_STEREO;
-			break;
-		}
-		tun->audmode = t->audmode;
-		return 0;
-	}
-	case VIDIOC_S_TUNER:
-	{
-		struct v4l2_tuner *tun = arg;
-
-		switch (t->type) {
-		case TUNER_SONY_BTF_PG472Z:
-			if (tun->audmode != t->audmode) {
-				t->audmode = tun->audmode;
-				mpx_setup(client);
-			}
-			break;
-		case TUNER_SONY_BTF_PK467Z:
-		case TUNER_SONY_BTF_PB463Z:
-			break;
-		}
-		return 0;
-	}
-	default:
-		break;
-	}
-	return 0;
-}
-
-static int wis_sony_tuner_probe(struct i2c_client *client,
-				const struct i2c_device_id *id)
-{
-	struct i2c_adapter *adapter = client->adapter;
-	struct wis_sony_tuner *t;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
-		return -ENODEV;
-
-	t = kmalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL);
-	if (t == NULL)
-		return -ENOMEM;
-
-	t->type = -1;
-	t->freq = 0;
-	t->mpxmode = 0;
-	t->audmode = V4L2_TUNER_MODE_STEREO;
-	i2c_set_clientdata(client, t);
-
-	dev_dbg(&client->dev, "initializing tuner at address %d on %s\n",
-		client->addr, adapter->name);
-
-	return 0;
-}
-
-static int wis_sony_tuner_remove(struct i2c_client *client)
-{
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
-
-	kfree(t);
-	return 0;
-}
-
-static const struct i2c_device_id wis_sony_tuner_id[] = {
-	{ "wis_sony_tuner", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, wis_sony_tuner_id);
-
-static struct i2c_driver wis_sony_tuner_driver = {
-	.driver = {
-		.name	= "WIS Sony TV Tuner I2C driver",
-	},
-	.probe		= wis_sony_tuner_probe,
-	.remove		= wis_sony_tuner_remove,
-	.command	= tuner_command,
-	.id_table	= wis_sony_tuner_id,
-};
-
-module_i2c_driver(wis_sony_tuner_driver);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/wis-tw2804.c b/drivers/staging/media/go7007/wis-tw2804.c
deleted file mode 100644
index 290fd8c..0000000
--- a/drivers/staging/media/go7007/wis-tw2804.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-
-#include "wis-i2c.h"
-
-struct wis_tw2804 {
-	int channel;
-	int norm;
-	int brightness;
-	int contrast;
-	int saturation;
-	int hue;
-};
-
-static u8 global_registers[] = {
-	0x39, 0x00,
-	0x3a, 0xff,
-	0x3b, 0x84,
-	0x3c, 0x80,
-	0x3d, 0x80,
-	0x3e, 0x82,
-	0x3f, 0x82,
-	0xff, 0xff, /* Terminator (reg 0xff does not exist) */
-};
-
-static u8 channel_registers[] = {
-	0x01, 0xc4,
-	0x02, 0xa5,
-	0x03, 0x20,
-	0x04, 0xd0,
-	0x05, 0x20,
-	0x06, 0xd0,
-	0x07, 0x88,
-	0x08, 0x20,
-	0x09, 0x07,
-	0x0a, 0xf0,
-	0x0b, 0x07,
-	0x0c, 0xf0,
-	0x0d, 0x40,
-	0x0e, 0xd2,
-	0x0f, 0x80,
-	0x10, 0x80,
-	0x11, 0x80,
-	0x12, 0x80,
-	0x13, 0x1f,
-	0x14, 0x00,
-	0x15, 0x00,
-	0x16, 0x00,
-	0x17, 0x00,
-	0x18, 0xff,
-	0x19, 0xff,
-	0x1a, 0xff,
-	0x1b, 0xff,
-	0x1c, 0xff,
-	0x1d, 0xff,
-	0x1e, 0xff,
-	0x1f, 0xff,
-	0x20, 0x07,
-	0x21, 0x07,
-	0x22, 0x00,
-	0x23, 0x91,
-	0x24, 0x51,
-	0x25, 0x03,
-	0x26, 0x00,
-	0x27, 0x00,
-	0x28, 0x00,
-	0x29, 0x00,
-	0x2a, 0x00,
-	0x2b, 0x00,
-	0x2c, 0x00,
-	0x2d, 0x00,
-	0x2e, 0x00,
-	0x2f, 0x00,
-	0x30, 0x00,
-	0x31, 0x00,
-	0x32, 0x00,
-	0x33, 0x00,
-	0x34, 0x00,
-	0x35, 0x00,
-	0x36, 0x00,
-	0x37, 0x00,
-	0xff, 0xff, /* Terminator (reg 0xff does not exist) */
-};
-
-static int write_reg(struct i2c_client *client, u8 reg, u8 value, int channel)
-{
-	return i2c_smbus_write_byte_data(client, reg | (channel << 6), value);
-}
-
-static int write_regs(struct i2c_client *client, u8 *regs, int channel)
-{
-	int i;
-
-	for (i = 0; regs[i] != 0xff; i += 2)
-		if (i2c_smbus_write_byte_data(client,
-				regs[i] | (channel << 6), regs[i + 1]) < 0)
-			return -1;
-	return 0;
-}
-
-static int wis_tw2804_command(struct i2c_client *client,
-				unsigned int cmd, void *arg)
-{
-	struct wis_tw2804 *dec = i2c_get_clientdata(client);
-
-	if (cmd == DECODER_SET_CHANNEL) {
-		int *input = arg;
-
-		if (*input < 0 || *input > 3) {
-			dev_err(&client->dev,
-				"channel %d is not between 0 and 3!\n", *input);
-			return 0;
-		}
-		dec->channel = *input;
-		dev_dbg(&client->dev, "initializing TW2804 channel %d\n",
-			dec->channel);
-		if (dec->channel == 0 &&
-				write_regs(client, global_registers, 0) < 0) {
-			dev_err(&client->dev,
-				"error initializing TW2804 global registers\n");
-			return 0;
-		}
-		if (write_regs(client, channel_registers, dec->channel) < 0) {
-			dev_err(&client->dev,
-				"error initializing TW2804 channel %d\n",
-				dec->channel);
-			return 0;
-		}
-		return 0;
-	}
-
-	if (dec->channel < 0) {
-		dev_dbg(&client->dev,
-			"ignoring command %08x until channel number is set\n",
-			cmd);
-		return 0;
-	}
-
-	switch (cmd) {
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *input = arg;
-		u8 regs[] = {
-			0x01, *input & V4L2_STD_NTSC ? 0xc4 : 0x84,
-			0x09, *input & V4L2_STD_NTSC ? 0x07 : 0x04,
-			0x0a, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
-			0x0b, *input & V4L2_STD_NTSC ? 0x07 : 0x04,
-			0x0c, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
-			0x0d, *input & V4L2_STD_NTSC ? 0x40 : 0x4a,
-			0x16, *input & V4L2_STD_NTSC ? 0x00 : 0x40,
-			0x17, *input & V4L2_STD_NTSC ? 0x00 : 0x40,
-			0x20, *input & V4L2_STD_NTSC ? 0x07 : 0x0f,
-			0x21, *input & V4L2_STD_NTSC ? 0x07 : 0x0f,
-			0xff,	0xff,
-		};
-		write_regs(client, regs, dec->channel);
-		dec->norm = *input;
-		break;
-	}
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 255;
-			ctrl->step = 1;
-			ctrl->default_value = 128;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 255;
-			ctrl->step = 1;
-			ctrl->default_value = 128;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_SATURATION:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 255;
-			ctrl->step = 1;
-			ctrl->default_value = 128;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_HUE:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 255;
-			ctrl->step = 1;
-			ctrl->default_value = 128;
-			ctrl->flags = 0;
-			break;
-		}
-		break;
-	}
-	case VIDIOC_S_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			if (ctrl->value > 255)
-				dec->brightness = 255;
-			else if (ctrl->value < 0)
-				dec->brightness = 0;
-			else
-				dec->brightness = ctrl->value;
-			write_reg(client, 0x12, dec->brightness, dec->channel);
-			break;
-		case V4L2_CID_CONTRAST:
-			if (ctrl->value > 255)
-				dec->contrast = 255;
-			else if (ctrl->value < 0)
-				dec->contrast = 0;
-			else
-				dec->contrast = ctrl->value;
-			write_reg(client, 0x11, dec->contrast, dec->channel);
-			break;
-		case V4L2_CID_SATURATION:
-			if (ctrl->value > 255)
-				dec->saturation = 255;
-			else if (ctrl->value < 0)
-				dec->saturation = 0;
-			else
-				dec->saturation = ctrl->value;
-			write_reg(client, 0x10, dec->saturation, dec->channel);
-			break;
-		case V4L2_CID_HUE:
-			if (ctrl->value > 255)
-				dec->hue = 255;
-			else if (ctrl->value < 0)
-				dec->hue = 0;
-			else
-				dec->hue = ctrl->value;
-			write_reg(client, 0x0f, dec->hue, dec->channel);
-			break;
-		}
-		break;
-	}
-	case VIDIOC_G_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->value = dec->brightness;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->value = dec->contrast;
-			break;
-		case V4L2_CID_SATURATION:
-			ctrl->value = dec->saturation;
-			break;
-		case V4L2_CID_HUE:
-			ctrl->value = dec->hue;
-			break;
-		}
-		break;
-	}
-	default:
-		break;
-	}
-	return 0;
-}
-
-static int wis_tw2804_probe(struct i2c_client *client,
-			    const struct i2c_device_id *id)
-{
-	struct i2c_adapter *adapter = client->adapter;
-	struct wis_tw2804 *dec;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -ENODEV;
-
-	dec = kmalloc(sizeof(struct wis_tw2804), GFP_KERNEL);
-	if (dec == NULL)
-		return -ENOMEM;
-
-	dec->channel = -1;
-	dec->norm = V4L2_STD_NTSC;
-	dec->brightness = 128;
-	dec->contrast = 128;
-	dec->saturation = 128;
-	dec->hue = 128;
-	i2c_set_clientdata(client, dec);
-
-	dev_dbg(&client->dev, "creating TW2804 at address %d on %s\n",
-		client->addr, adapter->name);
-
-	return 0;
-}
-
-static int wis_tw2804_remove(struct i2c_client *client)
-{
-	struct wis_tw2804 *dec = i2c_get_clientdata(client);
-
-	kfree(dec);
-	return 0;
-}
-
-static const struct i2c_device_id wis_tw2804_id[] = {
-	{ "wis_tw2804", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, wis_tw2804_id);
-
-static struct i2c_driver wis_tw2804_driver = {
-	.driver = {
-		.name	= "WIS TW2804 I2C driver",
-	},
-	.probe		= wis_tw2804_probe,
-	.remove		= wis_tw2804_remove,
-	.command	= wis_tw2804_command,
-	.id_table	= wis_tw2804_id,
-};
-
-module_i2c_driver(wis_tw2804_driver);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/wis-tw9903.c b/drivers/staging/media/go7007/wis-tw9903.c
deleted file mode 100644
index 684ca37..0000000
--- a/drivers/staging/media/go7007/wis-tw9903.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/ioctl.h>
-#include <linux/slab.h>
-
-#include "wis-i2c.h"
-
-struct wis_tw9903 {
-	int norm;
-	int brightness;
-	int contrast;
-	int hue;
-};
-
-static u8 initial_registers[] = {
-	0x02, 0x44, /* input 1, composite */
-	0x03, 0x92, /* correct digital format */
-	0x04, 0x00,
-	0x05, 0x80, /* or 0x00 for PAL */
-	0x06, 0x40, /* second internal current reference */
-	0x07, 0x02, /* window */
-	0x08, 0x14, /* window */
-	0x09, 0xf0, /* window */
-	0x0a, 0x81, /* window */
-	0x0b, 0xd0, /* window */
-	0x0c, 0x8c,
-	0x0d, 0x00, /* scaling */
-	0x0e, 0x11, /* scaling */
-	0x0f, 0x00, /* scaling */
-	0x10, 0x00, /* brightness */
-	0x11, 0x60, /* contrast */
-	0x12, 0x01, /* sharpness */
-	0x13, 0x7f, /* U gain */
-	0x14, 0x5a, /* V gain */
-	0x15, 0x00, /* hue */
-	0x16, 0xc3, /* sharpness */
-	0x18, 0x00,
-	0x19, 0x58, /* vbi */
-	0x1a, 0x80,
-	0x1c, 0x0f, /* video norm */
-	0x1d, 0x7f, /* video norm */
-	0x20, 0xa0, /* clamping gain (working 0x50) */
-	0x21, 0x22,
-	0x22, 0xf0,
-	0x23, 0xfe,
-	0x24, 0x3c,
-	0x25, 0x38,
-	0x26, 0x44,
-	0x27, 0x20,
-	0x28, 0x00,
-	0x29, 0x15,
-	0x2a, 0xa0,
-	0x2b, 0x44,
-	0x2c, 0x37,
-	0x2d, 0x00,
-	0x2e, 0xa5, /* burst PLL control (working: a9) */
-	0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */
-	0x31, 0x00,
-	0x33, 0x22,
-	0x34, 0x11,
-	0x35, 0x35,
-	0x3b, 0x05,
-	0x06, 0xc0, /* reset device */
-	0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
-};
-
-static int write_reg(struct i2c_client *client, u8 reg, u8 value)
-{
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int write_regs(struct i2c_client *client, u8 *regs)
-{
-	int i;
-
-	for (i = 0; regs[i] != 0x00; i += 2)
-		if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
-			return -1;
-	return 0;
-}
-
-static int wis_tw9903_command(struct i2c_client *client,
-				unsigned int cmd, void *arg)
-{
-	struct wis_tw9903 *dec = i2c_get_clientdata(client);
-
-	switch (cmd) {
-	case VIDIOC_S_INPUT:
-	{
-		int *input = arg;
-
-		i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
-		break;
-	}
-#if 0
-	/* The scaler on this thing seems to be horribly broken */
-	case DECODER_SET_RESOLUTION:
-	{
-		struct video_decoder_resolution *res = arg;
-		/*int hscale = 256 * 720 / res->width;*/
-		int hscale = 256 * 720 / (res->width - (res->width > 704 ? 0 : 8));
-		int vscale = 256 * (dec->norm & V4L2_STD_NTSC ?  240 : 288)
-				/ res->height;
-		u8 regs[] = {
-			0x0d, vscale & 0xff,
-			0x0f, hscale & 0xff,
-			0x0e, ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8),
-			0x06, 0xc0, /* reset device */
-			0,	0,
-		};
-		dev_dbg(&client->dev, "vscale is %04x, hscale is %04x\n",
-			vscale, hscale);
-		/*write_regs(client, regs);*/
-		break;
-	}
-#endif
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *input = arg;
-		u8 regs[] = {
-			0x05, *input & V4L2_STD_NTSC ? 0x80 : 0x00,
-			0x07, *input & V4L2_STD_NTSC ? 0x02 : 0x12,
-			0x08, *input & V4L2_STD_NTSC ? 0x14 : 0x18,
-			0x09, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
-			0,	0,
-		};
-		write_regs(client, regs);
-		dec->norm = *input;
-		break;
-	}
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
-			ctrl->minimum = -128;
-			ctrl->maximum = 127;
-			ctrl->step = 1;
-			ctrl->default_value = 0x00;
-			ctrl->flags = 0;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 255;
-			ctrl->step = 1;
-			ctrl->default_value = 0x60;
-			ctrl->flags = 0;
-			break;
-#if 0
-		/* I don't understand how the Chroma Gain registers work... */
-		case V4L2_CID_SATURATION:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
-			ctrl->minimum = 0;
-			ctrl->maximum = 127;
-			ctrl->step = 1;
-			ctrl->default_value = 64;
-			ctrl->flags = 0;
-			break;
-#endif
-		case V4L2_CID_HUE:
-			ctrl->type = V4L2_CTRL_TYPE_INTEGER;
-			strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
-			ctrl->minimum = -128;
-			ctrl->maximum = 127;
-			ctrl->step = 1;
-			ctrl->default_value = 0;
-			ctrl->flags = 0;
-			break;
-		}
-		break;
-	}
-	case VIDIOC_S_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			if (ctrl->value > 127)
-				dec->brightness = 127;
-			else if (ctrl->value < -128)
-				dec->brightness = -128;
-			else
-				dec->brightness = ctrl->value;
-			write_reg(client, 0x10, dec->brightness);
-			break;
-		case V4L2_CID_CONTRAST:
-			if (ctrl->value > 255)
-				dec->contrast = 255;
-			else if (ctrl->value < 0)
-				dec->contrast = 0;
-			else
-				dec->contrast = ctrl->value;
-			write_reg(client, 0x11, dec->contrast);
-			break;
-#if 0
-		case V4L2_CID_SATURATION:
-			if (ctrl->value > 127)
-				dec->saturation = 127;
-			else if (ctrl->value < 0)
-				dec->saturation = 0;
-			else
-				dec->saturation = ctrl->value;
-			/*write_reg(client, 0x0c, dec->saturation);*/
-			break;
-#endif
-		case V4L2_CID_HUE:
-			if (ctrl->value > 127)
-				dec->hue = 127;
-			else if (ctrl->value < -128)
-				dec->hue = -128;
-			else
-				dec->hue = ctrl->value;
-			write_reg(client, 0x15, dec->hue);
-			break;
-		}
-		break;
-	}
-	case VIDIOC_G_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-
-		switch (ctrl->id) {
-		case V4L2_CID_BRIGHTNESS:
-			ctrl->value = dec->brightness;
-			break;
-		case V4L2_CID_CONTRAST:
-			ctrl->value = dec->contrast;
-			break;
-#if 0
-		case V4L2_CID_SATURATION:
-			ctrl->value = dec->saturation;
-			break;
-#endif
-		case V4L2_CID_HUE:
-			ctrl->value = dec->hue;
-			break;
-		}
-		break;
-	}
-	default:
-		break;
-	}
-	return 0;
-}
-
-static int wis_tw9903_probe(struct i2c_client *client,
-			    const struct i2c_device_id *id)
-{
-	struct i2c_adapter *adapter = client->adapter;
-	struct wis_tw9903 *dec;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -ENODEV;
-
-	dec = kmalloc(sizeof(struct wis_tw9903), GFP_KERNEL);
-	if (dec == NULL)
-		return -ENOMEM;
-
-	dec->norm = V4L2_STD_NTSC;
-	dec->brightness = 0;
-	dec->contrast = 0x60;
-	dec->hue = 0;
-	i2c_set_clientdata(client, dec);
-
-	dev_dbg(&client->dev, "initializing TW9903 at address %d on %s\n",
-		client->addr, adapter->name);
-
-	if (write_regs(client, initial_registers) < 0) {
-		dev_err(&client->dev, "error initializing TW9903\n");
-		kfree(dec);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-static int wis_tw9903_remove(struct i2c_client *client)
-{
-	struct wis_tw9903 *dec = i2c_get_clientdata(client);
-
-	kfree(dec);
-	return 0;
-}
-
-static const struct i2c_device_id wis_tw9903_id[] = {
-	{ "wis_tw9903", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, wis_tw9903_id);
-
-static struct i2c_driver wis_tw9903_driver = {
-	.driver = {
-		.name	= "WIS TW9903 I2C driver",
-	},
-	.probe		= wis_tw9903_probe,
-	.remove		= wis_tw9903_remove,
-	.command	= wis_tw9903_command,
-	.id_table	= wis_tw9903_id,
-};
-
-module_i2c_driver(wis_tw9903_driver);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/wis-uda1342.c b/drivers/staging/media/go7007/wis-uda1342.c
deleted file mode 100644
index 582ea12..0000000
--- a/drivers/staging/media/go7007/wis-uda1342.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <media/tvaudio.h>
-#include <media/v4l2-common.h>
-
-#include "wis-i2c.h"
-
-static int write_reg(struct i2c_client *client, int reg, int value)
-{
-	/* UDA1342 wants MSB first, but SMBus sends LSB first */
-	i2c_smbus_write_word_data(client, reg, swab16(value));
-	return 0;
-}
-
-static int wis_uda1342_command(struct i2c_client *client,
-				unsigned int cmd, void *arg)
-{
-	switch (cmd) {
-	case VIDIOC_S_AUDIO:
-	{
-		int *inp = arg;
-
-		switch (*inp) {
-		case TVAUDIO_INPUT_TUNER:
-			write_reg(client, 0x00, 0x1441); /* select input 2 */
-			break;
-		case TVAUDIO_INPUT_EXTERN:
-			write_reg(client, 0x00, 0x1241); /* select input 1 */
-			break;
-		default:
-			dev_err(&client->dev, "input %d not supported\n",
-				*inp);
-			break;
-		}
-		break;
-	}
-	default:
-		break;
-	}
-	return 0;
-}
-
-static int wis_uda1342_probe(struct i2c_client *client,
-			     const struct i2c_device_id *id)
-{
-	struct i2c_adapter *adapter = client->adapter;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
-		return -ENODEV;
-
-	dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n",
-		client->addr, adapter->name);
-
-	write_reg(client, 0x00, 0x8000); /* reset registers */
-	write_reg(client, 0x00, 0x1241); /* select input 1 */
-
-	return 0;
-}
-
-static int wis_uda1342_remove(struct i2c_client *client)
-{
-	return 0;
-}
-
-static const struct i2c_device_id wis_uda1342_id[] = {
-	{ "wis_uda1342", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, wis_uda1342_id);
-
-static struct i2c_driver wis_uda1342_driver = {
-	.driver = {
-		.name	= "WIS UDA1342 I2C driver",
-	},
-	.probe		= wis_uda1342_probe,
-	.remove		= wis_uda1342_remove,
-	.command	= wis_uda1342_command,
-	.id_table	= wis_uda1342_id,
-};
-
-module_i2c_driver(wis_uda1342_driver);
-
-MODULE_LICENSE("GPL v2");
-- 
1.7.10.4


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

* [REVIEW PATCH 18/42] go7007: add audio input ioctls.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (15 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 17/42] go7007: remove all wis* drivers Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 19/42] s2250-loader: use usbv2_cypress_load_firmware Hans Verkuil
                     ` (24 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Since we now know what audio inputs there are, we can also get/set and
enumerate them.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-v4l2.c |   51 ++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index bab4a31..b79cda8 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -608,9 +608,10 @@ static int vidioc_querycap(struct file *file, void  *priv,
 
 	cap->version = KERNEL_VERSION(0, 9, 8);
 
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
-			    V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 
+	if (go->board_info->num_aud_inputs)
+		cap->device_caps |= V4L2_CAP_AUDIO;
 	if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
 		cap->capabilities |= V4L2_CAP_TUNER;
 
@@ -1191,7 +1192,10 @@ static int vidioc_enum_input(struct file *file, void *priv,
 	else
 		inp->type = V4L2_INPUT_TYPE_CAMERA;
 
-	inp->audioset = 0;
+	if (go->board_info->num_aud_inputs)
+		inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
+	else
+		inp->audioset = 0;
 	inp->tuner = 0;
 	if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
 		inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
@@ -1212,6 +1216,39 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
 	return 0;
 }
 
+static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	struct go7007 *go = video_drvdata(file);
+
+	if (a->index >= go->board_info->num_aud_inputs)
+		return -EINVAL;
+	strlcpy(a->name, go->board_info->aud_inputs[a->index].name, sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
+	return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+	struct go7007 *go = video_drvdata(file);
+
+	a->index = go->aud_input;
+	strlcpy(a->name, go->board_info->aud_inputs[go->aud_input].name, sizeof(a->name));
+	a->capability = V4L2_AUDCAP_STEREO;
+	return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
+{
+	struct go7007 *go = video_drvdata(file);
+
+	if (a->index >= go->board_info->num_aud_inputs)
+		return -EINVAL;
+	go->aud_input = a->index;
+	v4l2_subdev_call(go->sd_audio, audio, s_routing,
+			go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
+	return 0;
+}
+
 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
@@ -1772,6 +1809,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_enum_input        = vidioc_enum_input,
 	.vidioc_g_input           = vidioc_g_input,
 	.vidioc_s_input           = vidioc_s_input,
+	.vidioc_enumaudio         = vidioc_enumaudio,
+	.vidioc_g_audio           = vidioc_g_audio,
+	.vidioc_s_audio           = vidioc_s_audio,
 	.vidioc_queryctrl         = vidioc_queryctrl,
 	.vidioc_g_ctrl            = vidioc_g_ctrl,
 	.vidioc_s_ctrl            = vidioc_s_ctrl,
@@ -1816,6 +1856,11 @@ int go7007_v4l2_init(struct go7007 *go)
 		go->video_dev = NULL;
 		return rv;
 	}
+	if (go->board_info->num_aud_inputs == 0) {
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_G_AUDIO);
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_AUDIO);
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_ENUMAUDIO);
+	}
 	rv = v4l2_device_register(go->dev, &go->v4l2_dev);
 	if (rv < 0) {
 		video_device_release(go->video_dev);
-- 
1.7.10.4


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

* [REVIEW PATCH 19/42] s2250-loader: use usbv2_cypress_load_firmware
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (16 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 18/42] go7007: add audio input ioctls Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-24 15:39     ` Mauro Carvalho Chehab
  2013-03-11 11:45   ` [REVIEW PATCH 20/42] go7007: go7007: add device_caps and bus_info support to querycap Hans Verkuil
                     ` (23 subsequent siblings)
  41 siblings, 1 reply; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

The v2 of this function doesn't do DMA to objects on the stack like
its predecessor does.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/Makefile       |    4 ++--
 drivers/staging/media/go7007/s2250-loader.c |    7 ++++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
index 5bed78b..f9c8e0f 100644
--- a/drivers/staging/media/go7007/Makefile
+++ b/drivers/staging/media/go7007/Makefile
@@ -11,8 +11,8 @@ s2250-y := s2250-board.o
 #obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
 #ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
 
-# S2250 needs cypress ezusb loader from dvb-usb
-ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb
+# S2250 needs cypress ezusb loader from dvb-usb-v2
+ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb-v2
 
 ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/dvb-core
diff --git a/drivers/staging/media/go7007/s2250-loader.c b/drivers/staging/media/go7007/s2250-loader.c
index 72e5175..6453ec0 100644
--- a/drivers/staging/media/go7007/s2250-loader.c
+++ b/drivers/staging/media/go7007/s2250-loader.c
@@ -19,7 +19,8 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
-#include <dvb-usb.h>
+#include <linux/firmware.h>
+#include <cypress_firmware.h>
 
 #define S2250_LOADER_FIRMWARE	"s2250_loader.fw"
 #define S2250_FIRMWARE		"s2250.fw"
@@ -104,7 +105,7 @@ static int s2250loader_probe(struct usb_interface *interface,
 			S2250_LOADER_FIRMWARE);
 		goto failed2;
 	}
-	ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
+	ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
 	release_firmware(fw);
 	if (0 != ret) {
 		dev_err(&interface->dev, "loader download failed\n");
@@ -117,7 +118,7 @@ static int s2250loader_probe(struct usb_interface *interface,
 			S2250_FIRMWARE);
 		goto failed2;
 	}
-	ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
+	ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
 	release_firmware(fw);
 	if (0 != ret) {
 		dev_err(&interface->dev, "firmware_s2250 download failed\n");
-- 
1.7.10.4


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

* [REVIEW PATCH 20/42] go7007: go7007: add device_caps and bus_info support to querycap.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (17 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 19/42] s2250-loader: use usbv2_cypress_load_firmware Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:45   ` [REVIEW PATCH 21/42] go7007: remove current_norm Hans Verkuil
                     ` (22 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

And don't set the version field, the core does that for you.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-priv.h    |    1 +
 drivers/staging/media/go7007/go7007-usb.c     |    1 +
 drivers/staging/media/go7007/go7007-v4l2.c    |   10 +++-------
 drivers/staging/media/go7007/saa7134-go7007.c |    1 +
 4 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index 898eb5b..1c4b049 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -171,6 +171,7 @@ enum go7007_parser_state {
 
 struct go7007 {
 	struct device *dev;
+	u8 bus_info[32];
 	struct go7007_board_info *board_info;
 	unsigned int board_id;
 	int tuner_type;
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 5e3e5a0..0b1af50 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -1087,6 +1087,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 		goto allocfail;
 	usb->board = board;
 	usb->usbdev = usbdev;
+	usb_make_path(usbdev, go->bus_info, sizeof(go->bus_info));
 	go->board_id = id->driver_info;
 	strncpy(go->name, name, sizeof(go->name));
 	if (board->flags & GO7007_USB_EZUSB)
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index b79cda8..6f14ac5 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -602,19 +602,15 @@ static int vidioc_querycap(struct file *file, void  *priv,
 
 	strlcpy(cap->driver, "go7007", sizeof(cap->driver));
 	strlcpy(cap->card, go->name, sizeof(cap->card));
-#if 0
-	strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
-#endif
-
-	cap->version = KERNEL_VERSION(0, 9, 8);
+	strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
 
 	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 
 	if (go->board_info->num_aud_inputs)
 		cap->device_caps |= V4L2_CAP_AUDIO;
 	if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
-		cap->capabilities |= V4L2_CAP_TUNER;
-
+		cap->device_caps |= V4L2_CAP_TUNER;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index e037a39..d65e17a 100644
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
@@ -456,6 +456,7 @@ static int saa7134_go7007_init(struct saa7134_dev *dev)
 	if (go == NULL)
 		goto allocfail;
 	go->board_id = GO7007_BOARDID_PCI_VOYAGER;
+	snprintf(go->bus_info, sizeof(go->bus_info), "PCI:%s", pci_name(dev->pci));
 	strncpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
 	go->hpi_ops = &saa7134_go7007_hpi_ops;
 	go->hpi_context = saa;
-- 
1.7.10.4


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

* [REVIEW PATCH 21/42] go7007: remove current_norm.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (18 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 20/42] go7007: go7007: add device_caps and bus_info support to querycap Hans Verkuil
@ 2013-03-11 11:45   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 22/42] go7007: fix DMA related errors Hans Verkuil
                     ` (21 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:45 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

It's deprecated and replaced by g_std. Since this driver already implements
g_std the use of current_norm can just be removed.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-v4l2.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 6f14ac5..b470306 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -1834,7 +1834,6 @@ static struct video_device go7007_template = {
 	.release	= go7007_vfl_release,
 	.ioctl_ops	= &video_ioctl_ops,
 	.tvnorms	= V4L2_STD_ALL,
-	.current_norm	= V4L2_STD_NTSC,
 };
 
 int go7007_v4l2_init(struct go7007 *go)
-- 
1.7.10.4


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

* [REVIEW PATCH 22/42] go7007: fix DMA related errors.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (19 preceding siblings ...)
  2013-03-11 11:45   ` [REVIEW PATCH 21/42] go7007: remove current_norm Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 23/42] go7007: remember boot firmware Hans Verkuil
                     ` (20 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

- Don't pass data allocated on the stack to usb_control_msg.
- Use dma_mapping_error after calling dma_map_page().

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-priv.h    |    1 +
 drivers/staging/media/go7007/go7007-usb.c     |   36 +++++++++++--------------
 drivers/staging/media/go7007/s2250-board.c    |    2 +-
 drivers/staging/media/go7007/saa7134-go7007.c |    4 +--
 4 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index 1c4b049..daae6dd 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -188,6 +188,7 @@ struct go7007 {
 	int audio_enabled;
 	struct v4l2_subdev *sd_video;
 	struct v4l2_subdev *sd_audio;
+	u8 usb_buf[16];
 
 	/* Video input */
 	int input;
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 0b1af50..f496720 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -652,7 +652,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
 {
 	struct go7007_usb *usb = go->hpi_context;
 	int i, r;
-	u16 status_reg;
+	u16 status_reg = 0;
 	int timeout = 500;
 
 #ifdef GO7007_USB_DEBUG
@@ -664,15 +664,17 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
 		r = usb_control_msg(usb->usbdev,
 				usb_rcvctrlpipe(usb->usbdev, 0), 0x14,
 				USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-				0, HPI_STATUS_ADDR, &status_reg,
+				0, HPI_STATUS_ADDR, go->usb_buf,
 				sizeof(status_reg), timeout);
 		if (r < 0)
-			goto write_int_error;
-		__le16_to_cpus(&status_reg);
+			break;
+		status_reg = le16_to_cpu(*((u16 *)go->usb_buf));
 		if (!(status_reg & 0x0010))
 			break;
 		msleep(10);
 	}
+	if (r < 0)
+		goto write_int_error;
 	if (i == 100) {
 		printk(KERN_ERR
 			"go7007-usb: device is hung, status reg = 0x%04x\n",
@@ -700,7 +702,6 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
 						int addr, int data)
 {
 	struct go7007_usb *usb = go->hpi_context;
-	u8 *tbuf;
 	int r;
 	int timeout = 500;
 
@@ -709,17 +710,14 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
 		"go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
 #endif
 
-	tbuf = kzalloc(8, GFP_KERNEL);
-	if (tbuf == NULL)
-		return -ENOMEM;
-	tbuf[0] = data & 0xff;
-	tbuf[1] = data >> 8;
-	tbuf[2] = addr & 0xff;
-	tbuf[3] = addr >> 8;
+	go->usb_buf[0] = data & 0xff;
+	go->usb_buf[1] = data >> 8;
+	go->usb_buf[2] = addr & 0xff;
+	go->usb_buf[3] = addr >> 8;
+	go->usb_buf[4] = go->usb_buf[5] = go->usb_buf[6] = go->usb_buf[7] = 0;
 	r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00,
 			USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
-			0xf0f0, tbuf, 8, timeout);
-	kfree(tbuf);
+			0xf0f0, go->usb_buf, 8, timeout);
 	if (r < 0) {
 		printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
 		return r;
@@ -913,7 +911,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
 {
 	struct go7007 *go = i2c_get_adapdata(adapter);
 	struct go7007_usb *usb = go->hpi_context;
-	u8 buf[16];
+	u8 *buf = go->usb_buf;
 	int buf_len, i;
 	int ret = -EIO;
 
@@ -1169,14 +1167,12 @@ static int go7007_usb_probe(struct usb_interface *intf,
 
 	/* Probe the tuner model on the TV402U */
 	if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) {
-		u8 data[3];
-
 		/* Board strapping indicates tuner model */
-		if (go7007_usb_vendor_request(go, 0x41, 0, 0, data, 3, 1) < 0) {
+		if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3, 1) < 0) {
 			printk(KERN_ERR "go7007-usb: GPIO read failed!\n");
 			goto initfail;
 		}
-		switch (data[0] >> 6) {
+		switch (go->usb_buf[0] >> 6) {
 		case 1:
 			go->board_id = GO7007_BOARDID_PX_TV402U_EU;
 			go->tuner_type = TUNER_SONY_BTF_PG472Z;
@@ -1309,8 +1305,8 @@ static void go7007_usb_disconnect(struct usb_interface *intf)
 
 	kfree(go->hpi_context);
 
-	go7007_remove(go);
 	go->status = STATUS_SHUTDOWN;
+	go7007_remove(go);
 }
 
 static struct usb_driver go7007_usb_driver = {
diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c
index 37400bf..2266e1b 100644
--- a/drivers/staging/media/go7007/s2250-board.c
+++ b/drivers/staging/media/go7007/s2250-board.c
@@ -584,7 +584,7 @@ static int s2250_probe(struct i2c_client *client,
 	if (audio == NULL)
 		return -ENOMEM;
 
-	state = kmalloc(sizeof(struct s2250), GFP_KERNEL);
+	state = kzalloc(sizeof(struct s2250), GFP_KERNEL);
 	if (state == NULL) {
 		i2c_unregister_device(audio);
 		return -ENOMEM;
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index d65e17a..afe21f3 100644
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
@@ -261,12 +261,12 @@ static int saa7134_go7007_stream_start(struct go7007 *go)
 
 	saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
 			0, PAGE_SIZE, DMA_FROM_DEVICE);
-	if (!saa->top_dma)
+	if (dma_mapping_error(&dev->pci->dev, saa->top_dma))
 		return -ENOMEM;
 	saa->bottom_dma = dma_map_page(&dev->pci->dev,
 			virt_to_page(saa->bottom),
 			0, PAGE_SIZE, DMA_FROM_DEVICE);
-	if (!saa->bottom_dma) {
+	if (dma_mapping_error(&dev->pci->dev, saa->bottom_dma)) {
 		dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
 				DMA_FROM_DEVICE);
 		return -ENOMEM;
-- 
1.7.10.4


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

* [REVIEW PATCH 23/42] go7007: remember boot firmware.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (20 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 22/42] go7007: fix DMA related errors Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 24/42] go7007: fix unregister/disconnect handling Hans Verkuil
                     ` (19 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Don't load it everytime you stop encoding. Instead remember it.
Another reason for not loading it every time is that this could
be called from within the release() file operation, which turns
out to be deadly.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-driver.c |   43 +++++++++++++-------------
 drivers/staging/media/go7007/go7007-priv.h   |    2 ++
 2 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index 09d0ef4..db9a4b3 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -95,34 +95,34 @@ static int go7007_load_encoder(struct go7007 *go)
 	int fw_len, rv = 0;
 	u16 intr_val, intr_data;
 
-	if (request_firmware(&fw_entry, fw_name, go->dev)) {
-		v4l2_err(go, "unable to load firmware from file "
-			"\"%s\"\n", fw_name);
-		return -1;
-	}
-	if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
-		v4l2_err(go, "file \"%s\" does not appear to be "
-				"go7007 firmware\n", fw_name);
-		release_firmware(fw_entry);
-		return -1;
-	}
-	fw_len = fw_entry->size - 16;
-	bounce = kmemdup(fw_entry->data + 16, fw_len, GFP_KERNEL);
-	if (bounce == NULL) {
-		v4l2_err(go, "unable to allocate %d bytes for "
-				"firmware transfer\n", fw_len);
+	if (go->boot_fw == NULL) {
+		if (request_firmware(&fw_entry, fw_name, go->dev)) {
+			v4l2_err(go, "unable to load firmware from file \"%s\"\n", fw_name);
+			return -1;
+		}
+		if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
+			v4l2_err(go, "file \"%s\" does not appear to be go7007 firmware\n", fw_name);
+			release_firmware(fw_entry);
+			return -1;
+		}
+		fw_len = fw_entry->size - 16;
+		bounce = kmemdup(fw_entry->data + 16, fw_len, GFP_KERNEL);
+		if (bounce == NULL) {
+			v4l2_err(go, "unable to allocate %d bytes for firmware transfer\n", fw_len);
+			release_firmware(fw_entry);
+			return -1;
+		}
 		release_firmware(fw_entry);
-		return -1;
+		go->boot_fw_len = fw_len;
+		go->boot_fw = bounce;
 	}
-	release_firmware(fw_entry);
 	if (go7007_interface_reset(go) < 0 ||
-			go7007_send_firmware(go, bounce, fw_len) < 0 ||
-			go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
+	    go7007_send_firmware(go, go->boot_fw, go->boot_fw_len) < 0 ||
+	    go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
 			(intr_val & ~0x1) != 0x5a5a) {
 		v4l2_err(go, "error transferring firmware\n");
 		rv = -1;
 	}
-	kfree(bounce);
 	return rv;
 }
 
@@ -675,6 +675,7 @@ void go7007_remove(struct go7007 *go)
 
 	if (go->audio_enabled)
 		go7007_snd_remove(go);
+	kfree(go->boot_fw);
 	go7007_v4l2_remove(go);
 }
 EXPORT_SYMBOL(go7007_remove);
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index daae6dd..d390120 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -178,6 +178,8 @@ struct go7007 {
 	int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
 	char name[64];
 	struct video_device *video_dev;
+	void *boot_fw;
+	unsigned boot_fw_len;
 	struct v4l2_device v4l2_dev;
 	int ref_count;
 	enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
-- 
1.7.10.4


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

* [REVIEW PATCH 24/42] go7007: fix unregister/disconnect handling.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (21 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 23/42] go7007: remember boot firmware Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 25/42] go7007: convert to the control framework and remove obsolete JPEGCOMP support Hans Verkuil
                     ` (18 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

- use the v4l2_device's release() callback
- remove the unnecessary ref_count
- don't free usb data structures on disconnect, only do that in the final
  release callback.

This is the correct way in order to safely handle disconnect and removal
of modules.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-driver.c  |   63 +++++++++++++-----------
 drivers/staging/media/go7007/go7007-priv.h    |    4 +-
 drivers/staging/media/go7007/go7007-usb.c     |   64 +++++++++++++++----------
 drivers/staging/media/go7007/go7007-v4l2.c    |   22 +--------
 drivers/staging/media/go7007/saa7134-go7007.c |    7 ++-
 drivers/staging/media/go7007/snd-go7007.c     |    5 +-
 6 files changed, 85 insertions(+), 80 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index db9a4b3..dca85d8 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -221,6 +221,31 @@ static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *con
 }
 
 /*
+ * Detach and unregister the encoder.  The go7007 struct won't be freed
+ * until v4l2 finishes releasing its resources and all associated fds are
+ * closed by applications.
+ */
+static void go7007_remove(struct v4l2_device *v4l2_dev)
+{
+	struct go7007 *go = container_of(v4l2_dev, struct go7007, v4l2_dev);
+
+	v4l2_device_unregister(v4l2_dev);
+	if (go->hpi_ops->release)
+		go->hpi_ops->release(go);
+	if (go->i2c_adapter_online) {
+		if (i2c_del_adapter(&go->i2c_adapter) == 0)
+			go->i2c_adapter_online = 0;
+		else
+			v4l2_err(&go->v4l2_dev,
+				"error removing I2C adapter!\n");
+	}
+
+	kfree(go->boot_fw);
+	go7007_v4l2_remove(go);
+	kfree(go);
+}
+
+/*
  * Finalize the GO7007 hardware setup, register the on-board I2C adapter
  * (if used on this board), load the I2C client driver for the sensor
  * (SAA7115 or whatever) and other devices, and register the ALSA and V4L2
@@ -234,17 +259,17 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
 
 	dev_info(go->dev, "go7007: registering new %s\n", go->name);
 
+	go->v4l2_dev.release = go7007_remove;
+	ret = v4l2_device_register(go->dev, &go->v4l2_dev);
+	if (ret < 0)
+		return ret;
+
 	mutex_lock(&go->hw_lock);
 	ret = go7007_init_encoder(go);
 	mutex_unlock(&go->hw_lock);
 	if (ret < 0)
 		return -1;
 
-	/* v4l2 init must happen before i2c subdevs */
-	ret = go7007_v4l2_init(go);
-	if (ret < 0)
-		return ret;
-
 	if (!go->i2c_adapter_online &&
 			go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
 		if (go7007_i2c_init(go) < 0)
@@ -269,6 +294,11 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
 			v4l2_subdev_call(go->sd_video, video, s_routing,
 					0, 0, go->channel_number + 1);
 	}
+
+	ret = go7007_v4l2_init(go);
+	if (ret < 0)
+		return ret;
+
 	if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
 		go->audio_enabled = 1;
 		go7007_snd_init(go);
@@ -608,7 +638,6 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 	init_waitqueue_head(&go->frame_waitq);
 	spin_lock_init(&go->spinlock);
 	go->video_dev = NULL;
-	go->ref_count = 0;
 	go->status = STATUS_INIT;
 	memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
 	go->i2c_adapter_online = 0;
@@ -658,26 +687,4 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 }
 EXPORT_SYMBOL(go7007_alloc);
 
-/*
- * Detach and unregister the encoder.  The go7007 struct won't be freed
- * until v4l2 finishes releasing its resources and all associated fds are
- * closed by applications.
- */
-void go7007_remove(struct go7007 *go)
-{
-	if (go->i2c_adapter_online) {
-		if (i2c_del_adapter(&go->i2c_adapter) == 0)
-			go->i2c_adapter_online = 0;
-		else
-			v4l2_err(&go->v4l2_dev,
-				"error removing I2C adapter!\n");
-	}
-
-	if (go->audio_enabled)
-		go7007_snd_remove(go);
-	kfree(go->boot_fw);
-	go7007_v4l2_remove(go);
-}
-EXPORT_SYMBOL(go7007_remove);
-
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index d390120..54cfc0a 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -117,6 +117,7 @@ struct go7007_hpi_ops {
 	int (*stream_stop)(struct go7007 *go);
 	int (*send_firmware)(struct go7007 *go, u8 *data, int len);
 	int (*send_command)(struct go7007 *go, unsigned int cmd, void *arg);
+	void (*release)(struct go7007 *go);
 };
 
 /* The video buffer size must be a multiple of PAGE_SIZE */
@@ -181,7 +182,6 @@ struct go7007 {
 	void *boot_fw;
 	unsigned boot_fw_len;
 	struct v4l2_device v4l2_dev;
-	int ref_count;
 	enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
 	spinlock_t spinlock;
 	struct mutex hw_lock;
@@ -287,8 +287,6 @@ int go7007_start_encoder(struct go7007 *go);
 void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length);
 struct go7007 *go7007_alloc(struct go7007_board_info *board,
 					struct device *dev);
-void go7007_remove(struct go7007 *go);
-
 /* go7007-fw.c */
 int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen);
 
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index f496720..2d349f4 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -617,6 +617,8 @@ static int go7007_usb_interface_reset(struct go7007 *go)
 	struct go7007_usb *usb = go->hpi_context;
 	u16 intr_val, intr_data;
 
+	if (go->status == STATUS_SHUTDOWN)
+		return -1;
 	/* Reset encoder */
 	if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
 		return -1;
@@ -886,6 +888,35 @@ static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
 					&transferred, timeout);
 }
 
+static void go7007_usb_release(struct go7007 *go)
+{
+	struct go7007_usb *usb = go->hpi_context;
+	struct urb *vurb, *aurb;
+	int i;
+
+	usb_kill_urb(usb->intr_urb);
+
+	/* Free USB-related structs */
+	for (i = 0; i < 8; ++i) {
+		vurb = usb->video_urbs[i];
+		if (vurb) {
+			usb_kill_urb(vurb);
+			kfree(vurb->transfer_buffer);
+			usb_free_urb(vurb);
+		}
+		aurb = usb->audio_urbs[i];
+		if (aurb) {
+			usb_kill_urb(aurb);
+			kfree(aurb->transfer_buffer);
+			usb_free_urb(aurb);
+		}
+	}
+	kfree(usb->intr_urb->transfer_buffer);
+	usb_free_urb(usb->intr_urb);
+
+	kfree(go->hpi_context);
+}
+
 static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
 	.interface_reset	= go7007_usb_interface_reset,
 	.write_interrupt	= go7007_usb_ezusb_write_interrupt,
@@ -893,6 +924,7 @@ static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
 	.stream_start		= go7007_usb_stream_start,
 	.stream_stop		= go7007_usb_stream_stop,
 	.send_firmware		= go7007_usb_send_firmware,
+	.release		= go7007_usb_release,
 };
 
 static struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
@@ -902,6 +934,7 @@ static struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
 	.stream_start		= go7007_usb_stream_start,
 	.stream_stop		= go7007_usb_stream_stop,
 	.send_firmware		= go7007_usb_send_firmware,
+	.release		= go7007_usb_release,
 };
 
 /********************* Driver for EZ-USB I2C adapter *********************/
@@ -1279,34 +1312,15 @@ allocfail:
 static void go7007_usb_disconnect(struct usb_interface *intf)
 {
 	struct go7007 *go = to_go7007(usb_get_intfdata(intf));
-	struct go7007_usb *usb = go->hpi_context;
-	struct urb *vurb, *aurb;
-	int i;
-
-	usb_kill_urb(usb->intr_urb);
-
-	/* Free USB-related structs */
-	for (i = 0; i < 8; ++i) {
-		vurb = usb->video_urbs[i];
-		if (vurb) {
-			usb_kill_urb(vurb);
-			kfree(vurb->transfer_buffer);
-			usb_free_urb(vurb);
-		}
-		aurb = usb->audio_urbs[i];
-		if (aurb) {
-			usb_kill_urb(aurb);
-			kfree(aurb->transfer_buffer);
-			usb_free_urb(aurb);
-		}
-	}
-	kfree(usb->intr_urb->transfer_buffer);
-	usb_free_urb(usb->intr_urb);
 
-	kfree(go->hpi_context);
+	if (go->audio_enabled)
+		go7007_snd_remove(go);
 
 	go->status = STATUS_SHUTDOWN;
-	go7007_remove(go);
+	v4l2_device_disconnect(&go->v4l2_dev);
+	video_unregister_device(go->video_dev);
+
+	v4l2_device_put(&go->v4l2_dev);
 }
 
 static struct usb_driver go7007_usb_driver = {
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index b470306..53d2cbc 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -100,7 +100,6 @@ static int go7007_open(struct file *file)
 	gofh = kzalloc(sizeof(struct go7007_file), GFP_KERNEL);
 	if (gofh == NULL)
 		return -ENOMEM;
-	++go->ref_count;
 	gofh->go = go;
 	mutex_init(&gofh->lock);
 	gofh->buf_count = 0;
@@ -120,8 +119,6 @@ static int go7007_release(struct file *file)
 		gofh->buf_count = 0;
 	}
 	kfree(gofh);
-	if (--go->ref_count == 0)
-		kfree(go);
 	file->private_data = NULL;
 	return 0;
 }
@@ -1772,11 +1769,7 @@ static unsigned int go7007_poll(struct file *file, poll_table *wait)
 
 static void go7007_vfl_release(struct video_device *vfd)
 {
-	struct go7007 *go = video_get_drvdata(vfd);
-
 	video_device_release(vfd);
-	if (--go->ref_count == 0)
-		kfree(go);
 }
 
 static struct v4l2_file_operations go7007_fops = {
@@ -1844,7 +1837,8 @@ int go7007_v4l2_init(struct go7007 *go)
 	if (go->video_dev == NULL)
 		return -ENOMEM;
 	*go->video_dev = go7007_template;
-	go->video_dev->parent = go->dev;
+	video_set_drvdata(go->video_dev, go);
+	go->video_dev->v4l2_dev = &go->v4l2_dev;
 	rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
 	if (rv < 0) {
 		video_device_release(go->video_dev);
@@ -1856,14 +1850,6 @@ int go7007_v4l2_init(struct go7007 *go)
 		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_AUDIO);
 		v4l2_disable_ioctl(go->video_dev, VIDIOC_ENUMAUDIO);
 	}
-	rv = v4l2_device_register(go->dev, &go->v4l2_dev);
-	if (rv < 0) {
-		video_device_release(go->video_dev);
-		go->video_dev = NULL;
-		return rv;
-	}
-	video_set_drvdata(go->video_dev, go);
-	++go->ref_count;
 	dev_info(go->dev, "registered device %s [v4l2]\n",
 		 video_device_node_name(go->video_dev));
 
@@ -1883,8 +1869,4 @@ void go7007_v4l2_remove(struct go7007 *go)
 		spin_unlock_irqrestore(&go->spinlock, flags);
 	}
 	mutex_unlock(&go->hw_lock);
-	if (go->video_dev)
-		video_unregister_device(go->video_dev);
-	if (go->status != STATUS_SHUTDOWN)
-		v4l2_device_unregister(&go->v4l2_dev);
 }
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index afe21f3..4c73945 100644
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
@@ -499,12 +499,17 @@ static int saa7134_go7007_fini(struct saa7134_dev *dev)
 		return 0;
 
 	go = video_get_drvdata(dev->empress_dev);
+	if (go->audio_enabled)
+		go7007_snd_remove(go);
+
 	saa = go->hpi_context;
 	go->status = STATUS_SHUTDOWN;
 	free_page((unsigned long)saa->top);
 	free_page((unsigned long)saa->bottom);
 	kfree(saa);
-	go7007_remove(go);
+	video_unregister_device(&go->vdev);
+
+	v4l2_device_put(&go->v4l2_dev);
 	dev->empress_dev = NULL;
 
 	return 0;
diff --git a/drivers/staging/media/go7007/snd-go7007.c b/drivers/staging/media/go7007/snd-go7007.c
index 5af29ff..0e50e22 100644
--- a/drivers/staging/media/go7007/snd-go7007.c
+++ b/drivers/staging/media/go7007/snd-go7007.c
@@ -221,8 +221,6 @@ static int go7007_snd_free(struct snd_device *device)
 
 	kfree(go->snd_context);
 	go->snd_context = NULL;
-	if (--go->ref_count == 0)
-		kfree(go);
 	return 0;
 }
 
@@ -285,8 +283,8 @@ int go7007_snd_init(struct go7007 *go)
 
 	gosnd->substream = NULL;
 	go->snd_context = gosnd;
+	v4l2_device_get(&go->v4l2_dev);
 	++dev;
-	++go->ref_count;
 
 	return 0;
 }
@@ -298,6 +296,7 @@ int go7007_snd_remove(struct go7007 *go)
 
 	snd_card_disconnect(gosnd->card);
 	snd_card_free_when_closed(gosnd->card);
+	v4l2_device_put(&go->v4l2_dev);
 	return 0;
 }
 EXPORT_SYMBOL(go7007_snd_remove);
-- 
1.7.10.4


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

* [REVIEW PATCH 25/42] go7007: convert to the control framework and remove obsolete JPEGCOMP support.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (22 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 24/42] go7007: fix unregister/disconnect handling Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 26/42] s2250: convert to the control framework Hans Verkuil
                     ` (17 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Just add a read-only V4L2_CID_JPEG_ACTIVE_MARKER control to replace
the JPEGCOMP support.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-driver.c |   11 +-
 drivers/staging/media/go7007/go7007-priv.h   |    3 +
 drivers/staging/media/go7007/go7007-v4l2.c   |  249 +++++++-------------------
 3 files changed, 71 insertions(+), 192 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index dca85d8..d689989 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -268,12 +268,17 @@ int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
 	ret = go7007_init_encoder(go);
 	mutex_unlock(&go->hw_lock);
 	if (ret < 0)
-		return -1;
+		return ret;
+
+	ret = go7007_v4l2_ctrl_init(go);
+	if (ret < 0)
+		return ret;
 
 	if (!go->i2c_adapter_online &&
 			go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
-		if (go7007_i2c_init(go) < 0)
-			return -1;
+		ret = go7007_i2c_init(go);
+		if (ret < 0)
+			return ret;
 		go->i2c_adapter_online = 1;
 	}
 	if (go->i2c_adapter_online) {
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index 54cfc0a..d127a8d 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -22,6 +22,7 @@
  */
 
 #include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
 
 struct go7007;
 
@@ -182,6 +183,7 @@ struct go7007 {
 	void *boot_fw;
 	unsigned boot_fw_len;
 	struct v4l2_device v4l2_dev;
+	struct v4l2_ctrl_handler hdl;
 	enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
 	spinlock_t spinlock;
 	struct mutex hw_lock;
@@ -296,6 +298,7 @@ int go7007_i2c_remove(struct go7007 *go);
 
 /* go7007-v4l2.c */
 int go7007_v4l2_init(struct go7007 *go);
+int go7007_v4l2_ctrl_init(struct go7007 *go);
 void go7007_v4l2_remove(struct go7007 *go);
 
 /* snd-go7007.c */
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 53d2cbc..cb89af3 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -42,9 +42,6 @@
 #ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
 #define	V4L2_MPEG_STREAM_TYPE_MPEG_ELEM   6 /* MPEG elementary stream */
 #endif
-#ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4
-#define	V4L2_MPEG_VIDEO_ENCODING_MPEG_4   3
-#endif
 
 #define call_all(dev, o, f, args...) \
 	v4l2_device_call_until_err(dev, 0, o, f, ##args)
@@ -387,67 +384,18 @@ static int clip_to_modet_map(struct go7007 *go, int region,
 }
 #endif
 
-static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl)
+static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	static const u32 mpeg_ctrls[] = {
-		V4L2_CID_MPEG_CLASS,
-		V4L2_CID_MPEG_STREAM_TYPE,
-		V4L2_CID_MPEG_VIDEO_ENCODING,
-		V4L2_CID_MPEG_VIDEO_ASPECT,
-		V4L2_CID_MPEG_VIDEO_GOP_SIZE,
-		V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
-		V4L2_CID_MPEG_VIDEO_BITRATE,
-		0
-	};
-	static const u32 *ctrl_classes[] = {
-		mpeg_ctrls,
-		NULL
-	};
-
-	ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
-
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_CLASS:
-		return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
-	case V4L2_CID_MPEG_STREAM_TYPE:
-		return v4l2_ctrl_query_fill(ctrl,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
-				V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1,
-				V4L2_MPEG_STREAM_TYPE_MPEG_ELEM);
-	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		return v4l2_ctrl_query_fill(ctrl,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
-	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		return v4l2_ctrl_query_fill(ctrl,
-				V4L2_MPEG_VIDEO_ASPECT_1x1,
-				V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
-				V4L2_MPEG_VIDEO_ASPECT_1x1);
-	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
-		return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
-	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
-		return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		return v4l2_ctrl_query_fill(ctrl,
-				64000,
-				10000000, 1,
-				1500000);
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
+	struct go7007 *go =
+		container_of(ctrl->handler, struct go7007, hdl);
 
-static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
-{
 	/* pretty sure we can't change any of these while streaming */
 	if (go->streaming)
 		return -EBUSY;
 
 	switch (ctrl->id) {
 	case V4L2_CID_MPEG_STREAM_TYPE:
-		switch (ctrl->value) {
+		switch (ctrl->val) {
 		case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD:
 			go->format = GO7007_FORMAT_MPEG2;
 			go->bitrate = 9800000;
@@ -459,15 +407,12 @@ static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
 			go->gop_header_enable = 1;
 			go->dvd_mode = 1;
 			break;
-		case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM:
-			/* todo: */
-			break;
 		default:
 			return -EINVAL;
 		}
 		break;
 	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		switch (ctrl->value) {
+		switch (ctrl->val) {
 		case V4L2_MPEG_VIDEO_ENCODING_MPEG_1:
 			go->format = GO7007_FORMAT_MPEG1;
 			go->pali = 0;
@@ -479,7 +424,7 @@ static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
 			else*/
 				go->pali = 0x48;
 			break;
-		case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
+		case V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC:
 			go->format = GO7007_FORMAT_MPEG4;
 			/*if (mpeg->pali >> 24 == 4)
 				go->pali = mpeg->pali & 0xff;
@@ -499,9 +444,10 @@ static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
 		go->dvd_mode = 0;
 		break;
 	case V4L2_CID_MPEG_VIDEO_ASPECT:
+		/* TODO: is this really the right thing to do for mjpeg? */
 		if (go->format == GO7007_FORMAT_MJPEG)
 			return -EINVAL;
-		switch (ctrl->value) {
+		switch (ctrl->val) {
 		case V4L2_MPEG_VIDEO_ASPECT_1x1:
 			go->aspect_ratio = GO7007_RATIO_1_1;
 			break;
@@ -511,80 +457,18 @@ static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
 		case V4L2_MPEG_VIDEO_ASPECT_16x9:
 			go->aspect_ratio = GO7007_RATIO_16_9;
 			break;
-		case V4L2_MPEG_VIDEO_ASPECT_221x100:
-		default:
-			return -EINVAL;
-		}
-		break;
-	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
-		if (ctrl->value < 0 || ctrl->value > 34)
-			return -EINVAL;
-		go->gop_size = ctrl->value;
-		break;
-	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
-		if (ctrl->value != 0 && ctrl->value != 1)
-			return -EINVAL;
-		go->closed_gop = ctrl->value;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		/* Upper bound is kind of arbitrary here */
-		if (ctrl->value < 64000 || ctrl->value > 10000000)
-			return -EINVAL;
-		go->bitrate = ctrl->value;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
-{
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_STREAM_TYPE:
-		if (go->dvd_mode)
-			ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
-		else
-			ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG_ELEM;
-		break;
-	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		switch (go->format) {
-		case GO7007_FORMAT_MPEG1:
-			ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
-			break;
-		case GO7007_FORMAT_MPEG2:
-			ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
-			break;
-		case GO7007_FORMAT_MPEG4:
-			ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4;
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		switch (go->aspect_ratio) {
-		case GO7007_RATIO_1_1:
-			ctrl->value = V4L2_MPEG_VIDEO_ASPECT_1x1;
-			break;
-		case GO7007_RATIO_4_3:
-			ctrl->value = V4L2_MPEG_VIDEO_ASPECT_4x3;
-			break;
-		case GO7007_RATIO_16_9:
-			ctrl->value = V4L2_MPEG_VIDEO_ASPECT_16x9;
-			break;
 		default:
 			return -EINVAL;
 		}
 		break;
 	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
-		ctrl->value = go->gop_size;
+		go->gop_size = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
-		ctrl->value = go->closed_gop;
+		go->closed_gop = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		ctrl->value = go->bitrate;
+		go->bitrate = ctrl->val;
 		break;
 	default:
 		return -EINVAL;
@@ -968,41 +852,6 @@ static int vidioc_streamoff(struct file *file, void *priv,
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-			   struct v4l2_queryctrl *query)
-{
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
-	int id = query->id;
-
-	if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
-		return 0;
-
-	query->id = id;
-	return mpeg_query_ctrl(query);
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctrl)
-{
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
-
-	if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl))
-		return 0;
-
-	return mpeg_g_ctrl(ctrl, go);
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctrl)
-{
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
-
-	if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl))
-		return 0;
-
-	return mpeg_s_ctrl(ctrl, go);
-}
-
 static int vidioc_g_parm(struct file *filp, void *priv,
 		struct v4l2_streamparm *parm)
 {
@@ -1423,28 +1272,6 @@ static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *
 	return 0;
 }
 
-static int vidioc_g_jpegcomp(struct file *file, void *priv,
-			 struct v4l2_jpegcompression *params)
-{
-	memset(params, 0, sizeof(*params));
-	params->quality = 50; /* ?? */
-	params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
-				V4L2_JPEG_MARKER_DQT;
-
-	return 0;
-}
-
-static int vidioc_s_jpegcomp(struct file *file, void *priv,
-			 const struct v4l2_jpegcompression *params)
-{
-	if (params->quality != 50 ||
-			params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
-						V4L2_JPEG_MARKER_DQT))
-		return -EINVAL;
-
-	return 0;
-}
-
 /* FIXME:
 	Those ioctls are private, and not needed, since several standard
 	extended controls already provide streaming control.
@@ -1782,6 +1609,10 @@ static struct v4l2_file_operations go7007_fops = {
 	.poll		= go7007_poll,
 };
 
+static struct v4l2_ctrl_ops go7007_ctrl_ops = {
+	.s_ctrl = go7007_s_ctrl,
+};
+
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_querycap          = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
@@ -1801,9 +1632,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_enumaudio         = vidioc_enumaudio,
 	.vidioc_g_audio           = vidioc_g_audio,
 	.vidioc_s_audio           = vidioc_s_audio,
-	.vidioc_queryctrl         = vidioc_queryctrl,
-	.vidioc_g_ctrl            = vidioc_g_ctrl,
-	.vidioc_s_ctrl            = vidioc_s_ctrl,
 	.vidioc_streamon          = vidioc_streamon,
 	.vidioc_streamoff         = vidioc_streamoff,
 	.vidioc_g_tuner           = vidioc_g_tuner,
@@ -1817,8 +1645,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_cropcap           = vidioc_cropcap,
 	.vidioc_g_crop            = vidioc_g_crop,
 	.vidioc_s_crop            = vidioc_s_crop,
-	.vidioc_g_jpegcomp        = vidioc_g_jpegcomp,
-	.vidioc_s_jpegcomp        = vidioc_s_jpegcomp,
 };
 
 static struct video_device go7007_template = {
@@ -1829,6 +1655,50 @@ static struct video_device go7007_template = {
 	.tvnorms	= V4L2_STD_ALL,
 };
 
+int go7007_v4l2_ctrl_init(struct go7007 *go)
+{
+	struct v4l2_ctrl_handler *hdl = &go->hdl;
+	struct v4l2_ctrl *ctrl;
+
+	v4l2_ctrl_handler_init(hdl, 12);
+	v4l2_ctrl_new_std_menu(hdl, &go7007_ctrl_ops,
+			V4L2_CID_MPEG_STREAM_TYPE,
+			V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
+			0x7,
+			V4L2_MPEG_STREAM_TYPE_MPEG2_DVD);
+	v4l2_ctrl_new_std_menu(hdl, &go7007_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_ENCODING,
+			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC,
+			0,
+			V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
+	v4l2_ctrl_new_std_menu(hdl, &go7007_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_ASPECT,
+			V4L2_MPEG_VIDEO_ASPECT_16x9,
+			0,
+			V4L2_MPEG_VIDEO_ASPECT_1x1);
+	v4l2_ctrl_new_std(hdl, &go7007_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
+	v4l2_ctrl_new_std(hdl, &go7007_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(hdl, &go7007_ctrl_ops,
+			V4L2_CID_MPEG_VIDEO_BITRATE,
+			64000, 10000000, 1, 1500000);
+	ctrl = v4l2_ctrl_new_std(hdl, &go7007_ctrl_ops,
+			V4L2_CID_JPEG_ACTIVE_MARKER, 0,
+			V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
+			V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+	if (hdl->error) {
+		int rv = hdl->error;
+
+		v4l2_err(&go->v4l2_dev, "Could not register controls\n");
+		return rv;
+	}
+	go->v4l2_dev.ctrl_handler = hdl;
+	return 0;
+}
+
 int go7007_v4l2_init(struct go7007 *go)
 {
 	int rv;
@@ -1869,4 +1739,5 @@ void go7007_v4l2_remove(struct go7007 *go)
 		spin_unlock_irqrestore(&go->spinlock, flags);
 	}
 	mutex_unlock(&go->hw_lock);
+	v4l2_ctrl_handler_free(&go->hdl);
 }
-- 
1.7.10.4


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

* [REVIEW PATCH 26/42] s2250: convert to the control framework.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (23 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 25/42] go7007: convert to the control framework and remove obsolete JPEGCOMP support Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 27/42] go7007: add prio and control event support Hans Verkuil
                     ` (16 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/s2250-board.c |  149 +++++++++-------------------
 1 file changed, 46 insertions(+), 103 deletions(-)

diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c
index 2266e1b..5899513 100644
--- a/drivers/staging/media/go7007/s2250-board.c
+++ b/drivers/staging/media/go7007/s2250-board.c
@@ -116,6 +116,7 @@ static u16 vid_regs_fp_pal[] = {
 
 struct s2250 {
 	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler hdl;
 	v4l2_std_id std;
 	int input;
 	int brightness;
@@ -370,110 +371,36 @@ static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
 	return 0;
 }
 
-static int s2250_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *query)
+static int s2250_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	switch (query->id) {
-	case V4L2_CID_BRIGHTNESS:
-		return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
-	case V4L2_CID_CONTRAST:
-		return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
-	case V4L2_CID_SATURATION:
-		return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
-	case V4L2_CID_HUE:
-		return v4l2_ctrl_query_fill(query, -50, 50, 1, 0);
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int s2250_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-	struct s2250 *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int value1;
+	struct s2250 *state = container_of(ctrl->handler, struct s2250, hdl);
+	struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
 	u16 oldvalue;
 
 	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
-		if (ctrl->value > 100)
-			state->brightness = 100;
-		else if (ctrl->value < 0)
-			state->brightness = 0;
-		else
-			state->brightness = ctrl->value;
-		value1 = (state->brightness - 50) * 255 / 100;
 		read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
 		write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
-			     value1 | (oldvalue & ~0xff));
+			     ctrl->val | (oldvalue & ~0xff));
 		read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
 		write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
-			     value1 | (oldvalue & ~0xff));
+			     ctrl->val | (oldvalue & ~0xff));
 		write_reg_fp(client, 0x140, 0x60);
 		break;
 	case V4L2_CID_CONTRAST:
-		if (ctrl->value > 100)
-			state->contrast = 100;
-		else if (ctrl->value < 0)
-			state->contrast = 0;
-		else
-			state->contrast = ctrl->value;
-		value1 = state->contrast * 0x40 / 100;
-		if (value1 > 0x3f)
-			value1 = 0x3f; /* max */
 		read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
 		write_reg_fp(client, VPX322_ADDR_CONTRAST0,
-			     value1 | (oldvalue & ~0x3f));
+			     ctrl->val | (oldvalue & ~0x3f));
 		read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
 		write_reg_fp(client, VPX322_ADDR_CONTRAST1,
-			     value1 | (oldvalue & ~0x3f));
+			     ctrl->val | (oldvalue & ~0x3f));
 		write_reg_fp(client, 0x140, 0x60);
 		break;
 	case V4L2_CID_SATURATION:
-		if (ctrl->value > 100)
-			state->saturation = 100;
-		else if (ctrl->value < 0)
-			state->saturation = 0;
-		else
-			state->saturation = ctrl->value;
-		value1 = state->saturation * 4140 / 100;
-		if (value1 > 4094)
-			value1 = 4094;
-		write_reg_fp(client, VPX322_ADDR_SAT, value1);
-		break;
-	case V4L2_CID_HUE:
-		if (ctrl->value > 50)
-			state->hue = 50;
-		else if (ctrl->value < -50)
-			state->hue = -50;
-		else
-			state->hue = ctrl->value;
-		/* clamp the hue range */
-		value1 = state->hue * 280 / 50;
-		write_reg_fp(client, VPX322_ADDR_HUE, value1);
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int s2250_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-	struct s2250 *state = to_state(sd);
-
-	switch (ctrl->id) {
-	case V4L2_CID_BRIGHTNESS:
-		ctrl->value = state->brightness;
-		break;
-	case V4L2_CID_CONTRAST:
-		ctrl->value = state->contrast;
-		break;
-	case V4L2_CID_SATURATION:
-		ctrl->value = state->saturation;
+		write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
 		break;
 	case V4L2_CID_HUE:
-		ctrl->value = state->hue;
+		write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
 		break;
 	default:
 		return -EINVAL;
@@ -531,24 +458,21 @@ static int s2250_log_status(struct v4l2_subdev *sd)
 	v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
 					state->input == 1 ? "S-video" :
 					"error");
-	v4l2_info(sd, "Brightness: %d\n", state->brightness);
-	v4l2_info(sd, "Contrast: %d\n", state->contrast);
-	v4l2_info(sd, "Saturation: %d\n", state->saturation);
-	v4l2_info(sd, "Hue: %d\n", state->hue);
 	v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" :
 					state->audio_input == 1 ? "Mic" :
 					state->audio_input == 2 ? "Mic Boost" :
 					"error");
-	return 0;
+	return v4l2_ctrl_subdev_log_status(sd);
 }
 
 /* --------------------------------------------------------------------------*/
 
+static const struct v4l2_ctrl_ops s2250_ctrl_ops = {
+	.s_ctrl = s2250_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops s2250_core_ops = {
 	.log_status = s2250_log_status,
-	.g_ctrl = s2250_g_ctrl,
-	.s_ctrl = s2250_s_ctrl,
-	.queryctrl = s2250_queryctrl,
 	.s_std = s2250_s_std,
 };
 
@@ -596,6 +520,24 @@ static int s2250_probe(struct i2c_client *client,
 	v4l2_info(sd, "initializing %s at address 0x%x on %s\n",
 	       "Sensoray 2250/2251", client->addr, client->adapter->name);
 
+	v4l2_ctrl_handler_init(&state->hdl, 4);
+	v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
+		V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
+	v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
+		V4L2_CID_CONTRAST, 0, 0x3f, 1, 0x32);
+	v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
+		V4L2_CID_SATURATION, 0, 4094, 1, 2070);
+	v4l2_ctrl_new_std(&state->hdl, &s2250_ctrl_ops,
+		V4L2_CID_HUE, -512, 511, 1, 0);
+	sd->ctrl_handler = &state->hdl;
+	if (state->hdl.error) {
+		int err = state->hdl.error;
+
+		v4l2_ctrl_handler_free(&state->hdl);
+		kfree(state);
+		return err;
+	}
+
 	state->std = V4L2_STD_NTSC;
 	state->brightness = 50;
 	state->contrast = 50;
@@ -606,22 +548,16 @@ static int s2250_probe(struct i2c_client *client,
 	/* initialize the audio */
 	if (write_regs(audio, aud_regs) < 0) {
 		dev_err(&client->dev, "error initializing audio\n");
-		i2c_unregister_device(audio);
-		kfree(state);
-		return 0;
+		goto fail;
 	}
 
 	if (write_regs(client, vid_regs) < 0) {
 		dev_err(&client->dev, "error initializing decoder\n");
-		i2c_unregister_device(audio);
-		kfree(state);
-		return 0;
+		goto fail;
 	}
 	if (write_regs_fp(client, vid_regs_fp) < 0) {
 		dev_err(&client->dev, "error initializing decoder\n");
-		i2c_unregister_device(audio);
-		kfree(state);
-		return 0;
+		goto fail;
 	}
 	/* set default channel */
 	/* composite */
@@ -657,14 +593,21 @@ static int s2250_probe(struct i2c_client *client,
 
 	v4l2_info(sd, "initialized successfully\n");
 	return 0;
+
+fail:
+	i2c_unregister_device(audio);
+	v4l2_ctrl_handler_free(&state->hdl);
+	kfree(state);
+	return -EIO;
 }
 
 static int s2250_remove(struct i2c_client *client)
 {
-	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct s2250 *state = to_state(i2c_get_clientdata(client));
 
-	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
+	v4l2_device_unregister_subdev(&state->sd);
+	v4l2_ctrl_handler_free(&state->hdl);
+	kfree(state);
 	return 0;
 }
 
-- 
1.7.10.4


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

* [REVIEW PATCH 27/42] go7007: add prio and control event support.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (24 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 26/42] s2250: convert to the control framework Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 28/42] go7007: add log_status support Hans Verkuil
                     ` (15 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-priv.h |    2 ++
 drivers/staging/media/go7007/go7007-v4l2.c |   23 ++++++++++++++++++-----
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index d127a8d..2321fd7 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -23,6 +23,7 @@
 
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
+#include <media/v4l2-fh.h>
 
 struct go7007;
 
@@ -143,6 +144,7 @@ struct go7007_buffer {
 };
 
 struct go7007_file {
+	struct v4l2_fh fh;
 	struct go7007 *go;
 	struct mutex lock;
 	int buf_count;
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index cb89af3..186a56b 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -27,13 +27,14 @@
 #include <linux/time.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-subdev.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
+#include <media/v4l2-event.h>
 
 #include "go7007.h"
 #include "go7007-priv.h"
@@ -101,6 +102,8 @@ static int go7007_open(struct file *file)
 	mutex_init(&gofh->lock);
 	gofh->buf_count = 0;
 	file->private_data = gofh;
+	v4l2_fh_init(&gofh->fh, video_devdata(file));
+	v4l2_fh_add(&gofh->fh);
 	return 0;
 }
 
@@ -115,6 +118,8 @@ static int go7007_release(struct file *file)
 		kfree(gofh->bufs);
 		gofh->buf_count = 0;
 	}
+	v4l2_fh_del(&gofh->fh);
+	v4l2_fh_exit(&gofh->fh);
 	kfree(gofh);
 	file->private_data = NULL;
 	return 0;
@@ -1582,16 +1587,20 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
 
 static unsigned int go7007_poll(struct file *file, poll_table *wait)
 {
+	unsigned long req_events = poll_requested_events(wait);
 	struct go7007_file *gofh = file->private_data;
 	struct go7007_buffer *gobuf;
+	unsigned int res = v4l2_ctrl_poll(file, wait);
 
+	if (!(req_events & (POLLIN | POLLRDNORM)))
+		return res;
 	if (list_empty(&gofh->go->stream))
 		return POLLERR;
 	gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
 	poll_wait(file, &gofh->go->frame_waitq, wait);
 	if (gobuf->state == BUF_STATE_DONE)
-		return POLLIN | POLLRDNORM;
-	return 0;
+		return res | POLLIN | POLLRDNORM;
+	return res;
 }
 
 static void go7007_vfl_release(struct video_device *vfd)
@@ -1645,6 +1654,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_cropcap           = vidioc_cropcap,
 	.vidioc_g_crop            = vidioc_g_crop,
 	.vidioc_s_crop            = vidioc_s_crop,
+	.vidioc_log_status        = v4l2_ctrl_log_status,
+	.vidioc_subscribe_event   = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 static struct video_device go7007_template = {
@@ -1707,6 +1719,7 @@ int go7007_v4l2_init(struct go7007 *go)
 	if (go->video_dev == NULL)
 		return -ENOMEM;
 	*go->video_dev = go7007_template;
+	set_bit(V4L2_FL_USE_FH_PRIO, &go->video_dev->flags);
 	video_set_drvdata(go->video_dev, go);
 	go->video_dev->v4l2_dev = &go->v4l2_dev;
 	rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
-- 
1.7.10.4


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

* [REVIEW PATCH 28/42] go7007: add log_status support.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (25 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 27/42] go7007: add prio and control event support Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 29/42] go7007: tuner/std related fixes Hans Verkuil
                     ` (14 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-v4l2.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 186a56b..d3eef8d 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -1188,6 +1188,14 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 	return call_all(&go->v4l2_dev, tuner, s_frequency, f);
 }
 
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
+
+	v4l2_ctrl_log_status(file, priv);
+	return call_all(&go->v4l2_dev, core, log_status);
+}
+
 static int vidioc_cropcap(struct file *file, void *priv,
 					struct v4l2_cropcap *cropcap)
 {
@@ -1654,7 +1662,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_cropcap           = vidioc_cropcap,
 	.vidioc_g_crop            = vidioc_g_crop,
 	.vidioc_s_crop            = vidioc_s_crop,
-	.vidioc_log_status        = v4l2_ctrl_log_status,
+	.vidioc_log_status        = vidioc_log_status,
 	.vidioc_subscribe_event   = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
-- 
1.7.10.4


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

* [REVIEW PATCH 29/42] go7007: tuner/std related fixes.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (26 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 28/42] go7007: add log_status support Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 30/42] go7007: standardize MPEG handling support Hans Verkuil
                     ` (13 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

- The Adlink is initially detected as a sensor board, so the driver config
  is set up as if it was a sensor. Later the driver discovers that it really
  is a video capture card and that means that the driver configuration has
  to be updated for a PAL/NTSC capture card.

- Setup the correct initial std based on the TV tuner type.

- Remember the exact std the user selected, don't map it to STD_PAL or NTSC.

- Use v4l2_disable_ioctl to disable ioctls based on the board config and
  drop a lot of checking code in each of those ioctls since that is no longer
  needed.

- enum_input should use tvnorms to fill its std field.

- configure the input, std and initial tuner frequency at driver initialization.

- fix std handling in the s2250 driver.

- the code handling scaling for devices without a scaler was broken. This is
  now fixed.

- correctly set readbuffers and capability in g/s_parm.

- remove the bogus test for capturemode in s_parm.

- correctly implement enum_framesizes/intervals.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-driver.c |   35 ++--
 drivers/staging/media/go7007/go7007-priv.h   |    3 +
 drivers/staging/media/go7007/go7007-usb.c    |    3 +
 drivers/staging/media/go7007/go7007-v4l2.c   |  255 ++++++++++++--------------
 drivers/staging/media/go7007/s2250-board.c   |   13 +-
 5 files changed, 154 insertions(+), 155 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index d689989..eac91bc 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -650,19 +650,7 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 	init_waitqueue_head(&go->interrupt_waitq);
 	go->in_use = 0;
 	go->input = 0;
-	if (board->sensor_flags & GO7007_SENSOR_TV) {
-		go->standard = GO7007_STD_NTSC;
-		go->width = 720;
-		go->height = 480;
-		go->sensor_framerate = 30000;
-	} else {
-		go->standard = GO7007_STD_OTHER;
-		go->width = board->sensor_width;
-		go->height = board->sensor_height;
-		go->sensor_framerate = board->sensor_framerate;
-	}
-	go->encoder_v_offset = board->sensor_v_offset;
-	go->encoder_h_offset = board->sensor_h_offset;
+	go7007_update_board(go);
 	go->encoder_h_halve = 0;
 	go->encoder_v_halve = 0;
 	go->encoder_subsample = 0;
@@ -692,4 +680,25 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 }
 EXPORT_SYMBOL(go7007_alloc);
 
+void go7007_update_board(struct go7007 *go)
+{
+	struct go7007_board_info *board = go->board_info;
+
+	if (board->sensor_flags & GO7007_SENSOR_TV) {
+		go->standard = GO7007_STD_NTSC;
+		go->std = V4L2_STD_NTSC_M;
+		go->width = 720;
+		go->height = 480;
+		go->sensor_framerate = 30000;
+	} else {
+		go->standard = GO7007_STD_OTHER;
+		go->width = board->sensor_width;
+		go->height = board->sensor_height;
+		go->sensor_framerate = board->sensor_framerate;
+	}
+	go->encoder_v_offset = board->sensor_v_offset;
+	go->encoder_h_offset = board->sensor_h_offset;
+}
+EXPORT_SYMBOL(go7007_update_board);
+
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index 2321fd7..bf874dd 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -200,6 +200,7 @@ struct go7007 {
 	int input;
 	int aud_input;
 	enum { GO7007_STD_NTSC, GO7007_STD_PAL, GO7007_STD_OTHER } standard;
+	v4l2_std_id std;
 	int sensor_framerate;
 	int width;
 	int height;
@@ -291,6 +292,8 @@ int go7007_start_encoder(struct go7007 *go);
 void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length);
 struct go7007 *go7007_alloc(struct go7007_board_info *board,
 					struct device *dev);
+void go7007_update_board(struct go7007 *go);
+
 /* go7007-fw.c */
 int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen);
 
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 2d349f4..14d1cda 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -1193,6 +1193,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 					"Adlink PCI-MPG24, channel #%d",
 					channel);
 			}
+			go7007_update_board(go);
 		}
 	}
 
@@ -1209,12 +1210,14 @@ static int go7007_usb_probe(struct usb_interface *intf,
 		case 1:
 			go->board_id = GO7007_BOARDID_PX_TV402U_EU;
 			go->tuner_type = TUNER_SONY_BTF_PG472Z;
+			go->std = V4L2_STD_PAL;
 			strncpy(go->name, "Plextor PX-TV402U-EU",
 					sizeof(go->name));
 			break;
 		case 2:
 			go->board_id = GO7007_BOARDID_PX_TV402U_JP;
 			go->tuner_type = TUNER_SONY_BTF_PK467Z;
+			go->std = V4L2_STD_NTSC_M_JP;
 			num_i2c_devs -= 2;
 			strncpy(go->name, "Plextor PX-TV402U-JP",
 					sizeof(go->name));
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index d3eef8d..2fa5ffc 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -160,30 +160,35 @@ static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
 	return 0;
 }
 
-static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
+static void get_resolution(struct go7007 *go, int *width, int *height)
 {
-	int sensor_height = 0, sensor_width = 0;
-	int width, height, i;
-
-	if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
-			fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
-			fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
-		return -EINVAL;
-
 	switch (go->standard) {
 	case GO7007_STD_NTSC:
-		sensor_width = 720;
-		sensor_height = 480;
+		*width = 720;
+		*height = 480;
 		break;
 	case GO7007_STD_PAL:
-		sensor_width = 720;
-		sensor_height = 576;
+		*width = 720;
+		*height = 576;
 		break;
 	case GO7007_STD_OTHER:
-		sensor_width = go->board_info->sensor_width;
-		sensor_height = go->board_info->sensor_height;
+	default:
+		*width = go->board_info->sensor_width;
+		*height = go->board_info->sensor_height;
 		break;
 	}
+}
+
+static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
+{
+	int sensor_height = 0, sensor_width = 0;
+	int width, height, i;
+
+	if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
+			fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG)
+		return -EINVAL;
+
+	get_resolution(go, &sensor_width, &sensor_height);
 
 	if (fmt == NULL) {
 		width = sensor_width;
@@ -203,13 +208,12 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
 		else
 			height = fmt->fmt.pix.height & ~0x0f;
 	} else {
-		int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height;
-		int sensor_size = sensor_width * sensor_height;
+		width = fmt->fmt.pix.width;
 
-		if (64 * requested_size < 9 * sensor_size) {
+		if (width <= sensor_width / 4) {
 			width = sensor_width / 4;
 			height = sensor_height / 4;
-		} else if (64 * requested_size < 36 * sensor_size) {
+		} else if (width <= sensor_width / 2) {
 			width = sensor_width / 2;
 			height = sensor_height / 2;
 		} else {
@@ -231,7 +235,7 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
 		fmt->fmt.pix.field = V4L2_FIELD_NONE;
 		fmt->fmt.pix.bytesperline = 0;
 		fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
-		fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
+		fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 	}
 
 	if (try)
@@ -250,19 +254,11 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
 		struct v4l2_mbus_framefmt mbus_fmt;
 
 		mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
-		if (fmt != NULL)
-			mbus_fmt.width = fmt->fmt.pix.width;
-		else
-			mbus_fmt.width = width;
-
-		if (height > sensor_height / 2) {
-			mbus_fmt.height = height / 2;
-			go->encoder_v_halve = 0;
-		} else {
-			mbus_fmt.height = height;
-			go->encoder_v_halve = 1;
-		}
-		mbus_fmt.height *= 2;
+		mbus_fmt.width = fmt ? fmt->fmt.pix.width : width;
+		mbus_fmt.height = height;
+		go->encoder_h_halve = 0;
+		go->encoder_v_halve = 0;
+		go->encoder_subsample = 0;
 		call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
 	} else {
 		if (width <= sensor_width / 4) {
@@ -869,7 +865,8 @@ static int vidioc_g_parm(struct file *filp, void *priv,
 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
-	parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
+	parm->parm.capture.readbuffers = 2;
+	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
 	parm->parm.capture.timeperframe = timeperframe;
 
 	return 0;
@@ -883,8 +880,6 @@ static int vidioc_s_parm(struct file *filp, void *priv,
 
 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
-	if (parm->parm.capture.capturemode != 0)
-		return -EINVAL;
 
 	n = go->sensor_framerate *
 		parm->parm.capture.timeperframe.numerator;
@@ -894,7 +889,7 @@ static int vidioc_s_parm(struct file *filp, void *priv,
 	else
 		go->fps_scale = 1;
 
-	return 0;
+	return vidioc_g_parm(filp, priv, parm);
 }
 
 /* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
@@ -911,19 +906,19 @@ static int vidioc_enum_framesizes(struct file *filp, void *priv,
 				  struct v4l2_frmsizeenum *fsize)
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	int width, height;
 
-	/* Return -EINVAL, if it is a TV board */
-	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
-	    (go->board_info->sensor_flags & GO7007_SENSOR_TV))
+	if (fsize->index > 2)
 		return -EINVAL;
 
-	if (fsize->index > 0)
+	if (fsize->pixel_format != V4L2_PIX_FMT_MJPEG &&
+	    fsize->pixel_format != V4L2_PIX_FMT_MPEG)
 		return -EINVAL;
 
+	get_resolution(go, &width, &height);
 	fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
-	fsize->discrete.width = go->board_info->sensor_width;
-	fsize->discrete.height = go->board_info->sensor_height;
-
+	fsize->discrete.width = (width >> fsize->index) & ~0xf;
+	fsize->discrete.height = (height >> fsize->index) & ~0xf;
 	return 0;
 }
 
@@ -931,19 +926,28 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
 				      struct v4l2_frmivalenum *fival)
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	int width, height;
+	int i;
 
-	/* Return -EINVAL, if it is a TV board */
-	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
-	    (go->board_info->sensor_flags & GO7007_SENSOR_TV))
+	if (fival->index > 4)
 		return -EINVAL;
 
-	if (fival->index > 0)
+	if (fival->pixel_format != V4L2_PIX_FMT_MJPEG &&
+	    fival->pixel_format != V4L2_PIX_FMT_MPEG)
 		return -EINVAL;
 
+	if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
+		get_resolution(go, &width, &height);
+		for (i = 0; i <= 2; i++)
+			if (fival->width == ((width >> i) & ~0xf) &&
+			    fival->height == ((height >> i) & ~0xf))
+				break;
+		if (i > 2)
+			return -EINVAL;
+	}
 	fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
-	fival->discrete.numerator = 1001;
-	fival->discrete.denominator = go->board_info->sensor_framerate;
-
+	fival->discrete.numerator = 1001 * (fival->index + 1);
+	fival->discrete.denominator = go->sensor_framerate;
 	return 0;
 }
 
@@ -951,74 +955,42 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
-	switch (go->standard) {
-	case GO7007_STD_NTSC:
-		*std = V4L2_STD_NTSC;
-		break;
-	case GO7007_STD_PAL:
-		*std = V4L2_STD_PAL;
-		break;
-	default:
-		return -EINVAL;
+	*std = go->std;
+	return 0;
+}
+
+static int go7007_s_std(struct go7007 *go)
+{
+	if (go->std & V4L2_STD_525_60) {
+		go->standard = GO7007_STD_NTSC;
+		go->sensor_framerate = 30000;
+	} else {
+		go->standard = GO7007_STD_PAL;
+		go->sensor_framerate = 25025;
 	}
 
+	call_all(&go->v4l2_dev, core, s_std, go->std);
+	set_capture_size(go, NULL, 0);
 	return 0;
 }
 
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (go->streaming)
 		return -EBUSY;
 
-	if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0)
-		return -EINVAL;
-
-	if (*std == 0)
-		return -EINVAL;
-
-	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
-			go->input == go->board_info->num_inputs - 1) {
-		if (!go->i2c_adapter_online)
-			return -EIO;
-		if (call_all(&go->v4l2_dev, core, s_std, *std) < 0)
-			return -EINVAL;
-	}
+	go->std = *std;
 
-	if (*std & V4L2_STD_NTSC) {
-		go->standard = GO7007_STD_NTSC;
-		go->sensor_framerate = 30000;
-	} else if (*std & V4L2_STD_PAL) {
-		go->standard = GO7007_STD_PAL;
-		go->sensor_framerate = 25025;
-	} else if (*std & V4L2_STD_SECAM) {
-		go->standard = GO7007_STD_PAL;
-		go->sensor_framerate = 25025;
-	} else
-		return -EINVAL;
-
-	call_all(&go->v4l2_dev, core, s_std, *std);
-	set_capture_size(go, NULL, 0);
-
-	return 0;
+	return go7007_s_std(go);
 }
 
 static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
-	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
-			go->input == go->board_info->num_inputs - 1) {
-		if (!go->i2c_adapter_online)
-			return -EIO;
-		return call_all(&go->v4l2_dev, video, querystd, std);
-	} else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
-		*std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
-	else
-		*std = 0;
-
-	return 0;
+	return call_all(&go->v4l2_dev, video, querystd, std);
 }
 
 static int vidioc_enum_input(struct file *file, void *priv,
@@ -1045,8 +1017,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
 		inp->audioset = 0;
 	inp->tuner = 0;
 	if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
-		inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
-						V4L2_STD_SECAM;
+		inp->std = video_devdata(file)->tvnorms;
 	else
 		inp->std = 0;
 
@@ -1096,16 +1067,9 @@ static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *
 	return 0;
 }
 
-static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
+static void go7007_s_input(struct go7007 *go)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
-
-	if (input >= go->board_info->num_inputs)
-		return -EINVAL;
-	if (go->streaming)
-		return -EBUSY;
-
-	go->input = input;
+	unsigned int input = go->input;
 
 	v4l2_subdev_call(go->sd_video, video, s_routing,
 			go->board_info->inputs[input].video_input, 0,
@@ -1117,6 +1081,20 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
 			go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
 		go->aud_input = aud_input;
 	}
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
+{
+	struct go7007 *go = video_drvdata(file);
+
+	if (input >= go->board_info->num_inputs)
+		return -EINVAL;
+	if (go->streaming)
+		return -EBUSY;
+
+	go->input = input;
+	go7007_s_input(go);
+
 	return 0;
 }
 
@@ -1125,12 +1103,8 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
-	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
-		return -EINVAL;
 	if (t->index != 0)
 		return -EINVAL;
-	if (!go->i2c_adapter_online)
-		return -EIO;
 
 	strlcpy(t->name, "Tuner", sizeof(t->name));
 	return call_all(&go->v4l2_dev, tuner, g_tuner, t);
@@ -1141,12 +1115,8 @@ static int vidioc_s_tuner(struct file *file, void *priv,
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
-	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
-		return -EINVAL;
 	if (t->index != 0)
 		return -EINVAL;
-	if (!go->i2c_adapter_online)
-		return -EIO;
 
 	switch (go->board_id) {
 	case GO7007_BOARDID_PX_TV402U_NA:
@@ -1165,12 +1135,8 @@ static int vidioc_g_frequency(struct file *file, void *priv,
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
-	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
+	if (f->tuner)
 		return -EINVAL;
-	if (!go->i2c_adapter_online)
-		return -EIO;
-
-	f->type = V4L2_TUNER_ANALOG_TV;
 
 	return call_all(&go->v4l2_dev, tuner, g_frequency, f);
 }
@@ -1180,10 +1146,8 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 {
 	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
-	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
+	if (f->tuner)
 		return -EINVAL;
-	if (!go->i2c_adapter_online)
-		return -EIO;
 
 	return call_all(&go->v4l2_dev, tuner, s_frequency, f);
 }
@@ -1730,17 +1694,42 @@ int go7007_v4l2_init(struct go7007 *go)
 	set_bit(V4L2_FL_USE_FH_PRIO, &go->video_dev->flags);
 	video_set_drvdata(go->video_dev, go);
 	go->video_dev->v4l2_dev = &go->v4l2_dev;
-	rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
-	if (rv < 0) {
-		video_device_release(go->video_dev);
-		go->video_dev = NULL;
-		return rv;
+	if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_QUERYSTD);
+	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_FREQUENCY);
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_G_FREQUENCY);
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_TUNER);
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_G_TUNER);
+	} else {
+		struct v4l2_frequency f = {
+			.type = V4L2_TUNER_ANALOG_TV,
+			.frequency = 980,
+		};
+
+		call_all(&go->v4l2_dev, tuner, s_frequency, &f);
+	}
+	if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_G_STD);
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_STD);
+		go->video_dev->tvnorms = 0;
 	}
+	if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
+		v4l2_disable_ioctl(go->video_dev, VIDIOC_ENUM_FRAMESIZES);
 	if (go->board_info->num_aud_inputs == 0) {
 		v4l2_disable_ioctl(go->video_dev, VIDIOC_G_AUDIO);
 		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_AUDIO);
 		v4l2_disable_ioctl(go->video_dev, VIDIOC_ENUMAUDIO);
 	}
+	go7007_s_input(go);
+	if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
+		go7007_s_std(go);
+	rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
+	if (rv < 0) {
+		video_device_release(go->video_dev);
+		go->video_dev = NULL;
+		return rv;
+	}
 	dev_info(go->dev, "registered device %s [v4l2]\n",
 		 video_device_node_name(go->video_dev));
 
diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c
index 5899513..cb36427 100644
--- a/drivers/staging/media/go7007/s2250-board.c
+++ b/drivers/staging/media/go7007/s2250-board.c
@@ -354,18 +354,13 @@ static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
 	u16 vidsource;
 
 	vidsource = (state->input == 1) ? 0x040 : 0x020;
-	switch (norm) {
-	case V4L2_STD_NTSC:
-		write_regs_fp(client, vid_regs_fp);
-		write_reg_fp(client, 0x20, vidsource | 1);
-		break;
-	case V4L2_STD_PAL:
+	if (norm & V4L2_STD_625_50) {
 		write_regs_fp(client, vid_regs_fp);
 		write_regs_fp(client, vid_regs_fp_pal);
 		write_reg_fp(client, 0x20, vidsource);
-		break;
-	default:
-		return -EINVAL;
+	} else {
+		write_regs_fp(client, vid_regs_fp);
+		write_reg_fp(client, 0x20, vidsource | 1);
 	}
 	state->std = norm;
 	return 0;
-- 
1.7.10.4


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

* [REVIEW PATCH 30/42] go7007: standardize MPEG handling support.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (27 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 29/42] go7007: tuner/std related fixes Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 31/42] go7007: simplify the PX-TV402U board ID handling Hans Verkuil
                     ` (12 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

The go7007 produces elementary streams, so we shouldn't use the STREAM_TYPE
control, since that is for multiplexed streams.

Instead use V4L2_PIX_FMT_MPEG1/2/4.

Initially set up all the values for MPEG-2 dvd-mode, and select the dvd_mode
field if those values match that setup precisely.

Clean up lots of obsolete code relating to the custom ioctls for the MPEG
support.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-driver.c |   16 +-
 drivers/staging/media/go7007/go7007-fw.c     |   78 ++--
 drivers/staging/media/go7007/go7007-priv.h   |   13 +-
 drivers/staging/media/go7007/go7007-v4l2.c   |  507 +++++++-------------------
 drivers/staging/media/go7007/go7007.h        |   74 ----
 5 files changed, 181 insertions(+), 507 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index eac91bc..732b452 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -433,12 +433,12 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 	spin_lock(&go->spinlock);
 
 	switch (go->format) {
-	case GO7007_FORMAT_MPEG4:
+	case V4L2_PIX_FMT_MPEG4:
 		seq_start_code = 0xB0;
 		frame_start_code = 0xB6;
 		break;
-	case GO7007_FORMAT_MPEG1:
-	case GO7007_FORMAT_MPEG2:
+	case V4L2_PIX_FMT_MPEG1:
+	case V4L2_PIX_FMT_MPEG2:
 		seq_start_code = 0xB3;
 		frame_start_code = 0x00;
 		break;
@@ -518,9 +518,9 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 			}
 			/* If this is the start of a new MPEG frame,
 			 * get a new buffer */
-			if ((go->format == GO7007_FORMAT_MPEG1 ||
-					go->format == GO7007_FORMAT_MPEG2 ||
-					go->format == GO7007_FORMAT_MPEG4) &&
+			if ((go->format == V4L2_PIX_FMT_MPEG1 ||
+			     go->format == V4L2_PIX_FMT_MPEG2 ||
+			     go->format == V4L2_PIX_FMT_MPEG4) &&
 					(buf[i] == seq_start_code ||
 						buf[i] == 0xB8 || /* GOP code */
 						buf[i] == frame_start_code)) {
@@ -577,7 +577,7 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 				/* go->state remains STATE_FF */
 				break;
 			case 0xD8:
-				if (go->format == GO7007_FORMAT_MJPEG)
+				if (go->format == V4L2_PIX_FMT_MJPEG)
 					frame_boundary(go);
 				/* fall through */
 			default:
@@ -654,8 +654,8 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 	go->encoder_h_halve = 0;
 	go->encoder_v_halve = 0;
 	go->encoder_subsample = 0;
+	go->format = V4L2_PIX_FMT_MJPEG;
 	go->streaming = 0;
-	go->format = GO7007_FORMAT_MJPEG;
 	go->bitrate = 1500000;
 	go->fps_scale = 1;
 	go->pali = 0;
diff --git a/drivers/staging/media/go7007/go7007-fw.c b/drivers/staging/media/go7007/go7007-fw.c
index a5ede1c..524ba48 100644
--- a/drivers/staging/media/go7007/go7007-fw.c
+++ b/drivers/staging/media/go7007/go7007-fw.c
@@ -455,9 +455,9 @@ static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
 
 	CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13);
 	CODE_ADD(c, 0xffff, 16);
-	CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
+	CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4);
 	if (frame != PFRAME)
-		CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
+		CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4);
 	else
 		CODE_ADD(c, 0, 4); /* Is this supposed to be here?? */
 	CODE_ADD(c, 0, 3); /* What is this?? */
@@ -466,7 +466,7 @@ static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
 	if (j != 8)
 		CODE_ADD(c, 0, j);
 
-	if (go->format == GO7007_FORMAT_MPEG2) {
+	if (go->format == V4L2_PIX_FMT_MPEG2) {
 		CODE_ADD(c, 0x1, 24);
 		CODE_ADD(c, 0xb5, 8);
 		CODE_ADD(c, 0x844, 12);
@@ -537,7 +537,7 @@ static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
 	int i, aspect_ratio, picture_rate;
 	CODE_GEN(c, buf + 6);
 
-	if (go->format == GO7007_FORMAT_MPEG1) {
+	if (go->format == V4L2_PIX_FMT_MPEG1) {
 		switch (go->aspect_ratio) {
 		case GO7007_RATIO_4_3:
 			aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
@@ -587,9 +587,9 @@ static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
 	CODE_ADD(c, go->height, 12);
 	CODE_ADD(c, aspect_ratio, 4);
 	CODE_ADD(c, picture_rate, 4);
-	CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 20000 : 0x3ffff, 18);
+	CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 20000 : 0x3ffff, 18);
 	CODE_ADD(c, 1, 1);
-	CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 112 : 20, 10);
+	CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 112 : 20, 10);
 	CODE_ADD(c, 0, 3);
 
 	/* Byte-align with zeros */
@@ -597,7 +597,7 @@ static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
 	if (i != 8)
 		CODE_ADD(c, 0, i);
 
-	if (go->format == GO7007_FORMAT_MPEG2) {
+	if (go->format == V4L2_PIX_FMT_MPEG2) {
 		CODE_ADD(c, 0x1, 24);
 		CODE_ADD(c, 0xb5, 8);
 		CODE_ADD(c, 0x148, 12);
@@ -930,10 +930,10 @@ static int brctrl_to_package(struct go7007 *go,
 					__le16 *code, int space, int *framelen)
 {
 	int converge_speed = 0;
-	int lambda = (go->format == GO7007_FORMAT_MJPEG || go->dvd_mode) ?
+	int lambda = (go->format == V4L2_PIX_FMT_MJPEG || go->dvd_mode) ?
 				100 : 0;
 	int peak_rate = 6 * go->bitrate / 5;
-	int vbv_buffer = go->format == GO7007_FORMAT_MJPEG ?
+	int vbv_buffer = go->format == V4L2_PIX_FMT_MJPEG ?
 				go->bitrate :
 				(go->dvd_mode ? 900000 : peak_rate);
 	int fps = go->sensor_framerate / go->fps_scale;
@@ -1096,10 +1096,10 @@ static int config_package(struct go7007 *go, __le16 *code, int space)
 		0xc003,		0x28b4,
 		0xc004,		0x3c5a,
 		0xdc05,		0x2a77,
-		0xc6c3,		go->format == GO7007_FORMAT_MPEG4 ? 0 :
-				(go->format == GO7007_FORMAT_H263 ? 0 : 1),
-		0xc680,		go->format == GO7007_FORMAT_MPEG4 ? 0xf1 :
-				(go->format == GO7007_FORMAT_H263 ? 0x61 :
+		0xc6c3,		go->format == V4L2_PIX_FMT_MPEG4 ? 0 :
+				(go->format == V4L2_PIX_FMT_H263 ? 0 : 1),
+		0xc680,		go->format == V4L2_PIX_FMT_MPEG4 ? 0xf1 :
+				(go->format == V4L2_PIX_FMT_H263 ? 0x61 :
 									0xd3),
 		0xc780,		0x0140,
 		0xe009,		0x0001,
@@ -1123,15 +1123,15 @@ static int config_package(struct go7007 *go, __le16 *code, int space)
 						(!go->interlace_coding) ?
 					0x0008 : 0x0009,
 		0xc404,		go->interlace_coding ? 0x44 :
-				(go->format == GO7007_FORMAT_MPEG4 ? 0x11 :
-				(go->format == GO7007_FORMAT_MPEG1 ? 0x02 :
-				(go->format == GO7007_FORMAT_MPEG2 ? 0x04 :
-				(go->format == GO7007_FORMAT_H263  ? 0x08 :
+				(go->format == V4L2_PIX_FMT_MPEG4 ? 0x11 :
+				(go->format == V4L2_PIX_FMT_MPEG1 ? 0x02 :
+				(go->format == V4L2_PIX_FMT_MPEG2 ? 0x04 :
+				(go->format == V4L2_PIX_FMT_H263  ? 0x08 :
 								     0x20)))),
-		0xbf0a,		(go->format == GO7007_FORMAT_MPEG4 ? 8 :
-				(go->format == GO7007_FORMAT_MPEG1 ? 1 :
-				(go->format == GO7007_FORMAT_MPEG2 ? 2 :
-				(go->format == GO7007_FORMAT_H263 ? 4 : 16)))) |
+		0xbf0a,		(go->format == V4L2_PIX_FMT_MPEG4 ? 8 :
+				(go->format == V4L2_PIX_FMT_MPEG1 ? 1 :
+				(go->format == V4L2_PIX_FMT_MPEG2 ? 2 :
+				(go->format == V4L2_PIX_FMT_H263 ? 4 : 16)))) |
 				((go->repeat_seqhead ? 1 : 0) << 6) |
 				((go->dvd_mode ? 1 : 0) << 9) |
 				((go->gop_header_enable ? 1 : 0) << 10),
@@ -1348,19 +1348,19 @@ static int final_package(struct go7007 *go, __le16 *code, int space)
 			0x41,
 		go->ipb ? 0xd4c : 0x36b,
 		(rows << 8) | (go->width >> 4),
-		go->format == GO7007_FORMAT_MPEG4 ? 0x0404 : 0,
+		go->format == V4L2_PIX_FMT_MPEG4 ? 0x0404 : 0,
 		(1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) |
 			((go->closed_gop ? 1 : 0) << 12) |
-			((go->format == GO7007_FORMAT_MPEG4 ? 1 : 0) << 11) |
+			((go->format == V4L2_PIX_FMT_MPEG4 ? 1 : 0) << 11) |
 		/*	(1 << 9) |   */
 			((go->ipb ? 3 : 0) << 7) |
 			((go->modet_enable ? 1 : 0) << 2) |
 			((go->dvd_mode ? 1 : 0) << 1) | 1,
-		(go->format == GO7007_FORMAT_MPEG1 ? 0x89a0 :
-			(go->format == GO7007_FORMAT_MPEG2 ? 0x89a0 :
-			(go->format == GO7007_FORMAT_MJPEG ? 0x89a0 :
-			(go->format == GO7007_FORMAT_MPEG4 ? 0x8920 :
-			(go->format == GO7007_FORMAT_H263 ? 0x8920 : 0))))),
+		(go->format == V4L2_PIX_FMT_MPEG1 ? 0x89a0 :
+			(go->format == V4L2_PIX_FMT_MPEG2 ? 0x89a0 :
+			(go->format == V4L2_PIX_FMT_MJPEG ? 0x89a0 :
+			(go->format == V4L2_PIX_FMT_MPEG4 ? 0x8920 :
+			(go->format == V4L2_PIX_FMT_H263 ? 0x8920 : 0))))),
 		go->ipb ? 0x1f15 : 0x1f0b,
 		go->ipb ? 0x0015 : 0x000b,
 		go->ipb ? 0xa800 : 0x5800,
@@ -1503,13 +1503,13 @@ static int do_special(struct go7007 *go, u16 type, __le16 *code, int space,
 	switch (type) {
 	case SPECIAL_FRM_HEAD:
 		switch (go->format) {
-		case GO7007_FORMAT_MJPEG:
+		case V4L2_PIX_FMT_MJPEG:
 			return gen_mjpeghdr_to_package(go, code, space);
-		case GO7007_FORMAT_MPEG1:
-		case GO7007_FORMAT_MPEG2:
+		case V4L2_PIX_FMT_MPEG1:
+		case V4L2_PIX_FMT_MPEG2:
 			return gen_mpeg1hdr_to_package(go, code, space,
 								framelen);
-		case GO7007_FORMAT_MPEG4:
+		case V4L2_PIX_FMT_MPEG4:
 			return gen_mpeg4hdr_to_package(go, code, space,
 								framelen);
 		}
@@ -1519,11 +1519,11 @@ static int do_special(struct go7007 *go, u16 type, __le16 *code, int space,
 		return config_package(go, code, space);
 	case SPECIAL_SEQHEAD:
 		switch (go->format) {
-		case GO7007_FORMAT_MPEG1:
-		case GO7007_FORMAT_MPEG2:
+		case V4L2_PIX_FMT_MPEG1:
+		case V4L2_PIX_FMT_MPEG2:
 			return seqhead_to_package(go, code, space,
 					mpeg1_sequence_header);
-		case GO7007_FORMAT_MPEG4:
+		case V4L2_PIX_FMT_MPEG4:
 			return seqhead_to_package(go, code, space,
 					mpeg4_sequence_header);
 		default:
@@ -1553,16 +1553,16 @@ int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
 	int ret;
 
 	switch (go->format) {
-	case GO7007_FORMAT_MJPEG:
+	case V4L2_PIX_FMT_MJPEG:
 		mode_flag = FLAG_MODE_MJPEG;
 		break;
-	case GO7007_FORMAT_MPEG1:
+	case V4L2_PIX_FMT_MPEG1:
 		mode_flag = FLAG_MODE_MPEG1;
 		break;
-	case GO7007_FORMAT_MPEG2:
+	case V4L2_PIX_FMT_MPEG2:
 		mode_flag = FLAG_MODE_MPEG2;
 		break;
-	case GO7007_FORMAT_MPEG4:
+	case V4L2_PIX_FMT_MPEG4:
 		mode_flag = FLAG_MODE_MPEG4;
 		break;
 	default:
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index bf874dd..c2fafb2 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -151,12 +151,6 @@ struct go7007_file {
 	struct go7007_buffer *bufs;
 };
 
-#define	GO7007_FORMAT_MJPEG	0
-#define GO7007_FORMAT_MPEG4	1
-#define GO7007_FORMAT_MPEG1	2
-#define GO7007_FORMAT_MPEG2	3
-#define GO7007_FORMAT_H263	4
-
 #define GO7007_RATIO_1_1	0
 #define GO7007_RATIO_4_3	1
 #define GO7007_RATIO_16_9	2
@@ -186,6 +180,11 @@ struct go7007 {
 	unsigned boot_fw_len;
 	struct v4l2_device v4l2_dev;
 	struct v4l2_ctrl_handler hdl;
+	struct v4l2_ctrl *mpeg_video_encoding;
+	struct v4l2_ctrl *mpeg_video_gop_size;
+	struct v4l2_ctrl *mpeg_video_gop_closure;
+	struct v4l2_ctrl *mpeg_video_bitrate;
+	struct v4l2_ctrl *mpeg_video_aspect_ratio;
 	enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
 	spinlock_t spinlock;
 	struct mutex hw_lock;
@@ -211,7 +210,7 @@ struct go7007 {
 	unsigned int encoder_subsample:1;
 
 	/* Encoder config */
-	int format;
+	u32 format;
 	int bitrate;
 	int fps_scale;
 	int pali;
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 2fa5ffc..df5296f 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -39,11 +39,6 @@
 #include "go7007.h"
 #include "go7007-priv.h"
 
-/* Temporary defines until accepted in v4l-dvb */
-#ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
-#define	V4L2_MPEG_STREAM_TYPE_MPEG_ELEM   6 /* MPEG elementary stream */
-#endif
-
 #define call_all(dev, o, f, args...) \
 	v4l2_device_call_until_err(dev, 0, o, f, ##args)
 
@@ -85,6 +80,10 @@ static int go7007_streamoff(struct go7007 *go)
 		go7007_reset_encoder(go);
 	}
 	mutex_unlock(&go->hw_lock);
+	v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
+	v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
+	v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
+	v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
 	return 0;
 }
 
@@ -125,14 +124,27 @@ static int go7007_release(struct file *file)
 	return 0;
 }
 
+static bool valid_pixelformat(u32 pixelformat)
+{
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_MJPEG:
+	case V4L2_PIX_FMT_MPEG1:
+	case V4L2_PIX_FMT_MPEG2:
+	case V4L2_PIX_FMT_MPEG4:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
 {
 	u8 *f = page_address(gobuf->pages[0]);
 
 	switch (format) {
-	case GO7007_FORMAT_MJPEG:
+	case V4L2_PIX_FMT_MJPEG:
 		return V4L2_BUF_FLAG_KEYFRAME;
-	case GO7007_FORMAT_MPEG4:
+	case V4L2_PIX_FMT_MPEG4:
 		switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
 		case 0:
 			return V4L2_BUF_FLAG_KEYFRAME;
@@ -143,8 +155,8 @@ static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
 		default:
 			return 0;
 		}
-	case GO7007_FORMAT_MPEG1:
-	case GO7007_FORMAT_MPEG2:
+	case V4L2_PIX_FMT_MPEG1:
+	case V4L2_PIX_FMT_MPEG2:
 		switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
 		case 1:
 			return V4L2_BUF_FLAG_KEYFRAME;
@@ -179,13 +191,87 @@ static void get_resolution(struct go7007 *go, int *width, int *height)
 	}
 }
 
+static void set_formatting(struct go7007 *go)
+{
+	if (go->format == V4L2_PIX_FMT_MJPEG) {
+		go->pali = 0;
+		go->aspect_ratio = GO7007_RATIO_1_1;
+		go->gop_size = 0;
+		go->ipb = 0;
+		go->closed_gop = 0;
+		go->repeat_seqhead = 0;
+		go->seq_header_enable = 0;
+		go->gop_header_enable = 0;
+		go->dvd_mode = 0;
+		return;
+	}
+
+	switch (go->format) {
+	case V4L2_PIX_FMT_MPEG1:
+		go->pali = 0;
+		break;
+	default:
+	case V4L2_PIX_FMT_MPEG2:
+		go->pali = 0x48;
+		break;
+	case V4L2_PIX_FMT_MPEG4:
+		/* For future reference: this is the list of MPEG4
+		 * profiles that are available, although they are
+		 * untested:
+		 *
+		 * Profile		pali
+		 * --------------	----
+		 * PROFILE_S_L0		0x08
+		 * PROFILE_S_L1		0x01
+		 * PROFILE_S_L2		0x02
+		 * PROFILE_S_L3		0x03
+		 * PROFILE_ARTS_L1	0x91
+		 * PROFILE_ARTS_L2	0x92
+		 * PROFILE_ARTS_L3	0x93
+		 * PROFILE_ARTS_L4	0x94
+		 * PROFILE_AS_L0	0xf0
+		 * PROFILE_AS_L1	0xf1
+		 * PROFILE_AS_L2	0xf2
+		 * PROFILE_AS_L3	0xf3
+		 * PROFILE_AS_L4	0xf4
+		 * PROFILE_AS_L5	0xf5
+		 */
+		go->pali = 0xf5;
+		break;
+	}
+	go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size);
+	go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure);
+	go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
+	go->gop_header_enable = 1;
+	go->dvd_mode = 0;
+	if (go->format == V4L2_PIX_FMT_MPEG2)
+		go->dvd_mode =
+			go->bitrate == 9800000 &&
+			go->gop_size == 15 &&
+			go->closed_gop;
+	go->repeat_seqhead = go->dvd_mode;
+	go->ipb = 0;
+
+	switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) {
+	default:
+	case V4L2_MPEG_VIDEO_ASPECT_1x1:
+		go->aspect_ratio = GO7007_RATIO_1_1;
+		break;
+	case V4L2_MPEG_VIDEO_ASPECT_4x3:
+		go->aspect_ratio = GO7007_RATIO_4_3;
+		break;
+	case V4L2_MPEG_VIDEO_ASPECT_16x9:
+		go->aspect_ratio = GO7007_RATIO_16_9;
+		break;
+	}
+}
+
 static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
 {
 	int sensor_height = 0, sensor_width = 0;
 	int width, height, i;
 
-	if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
-			fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG)
+	if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
 		return -EINVAL;
 
 	get_resolution(go, &sensor_width, &sensor_height);
@@ -241,6 +327,8 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
 	if (try)
 		return 0;
 
+	if (fmt)
+		go->format = fmt->fmt.pix.pixelformat;
 	go->width = width;
 	go->height = height;
 	go->encoder_h_offset = go->board_info->sensor_h_offset;
@@ -275,55 +363,6 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
 			go->encoder_subsample = 0;
 		}
 	}
-
-	if (fmt == NULL)
-		return 0;
-
-	switch (fmt->fmt.pix.pixelformat) {
-	case V4L2_PIX_FMT_MPEG:
-		if (go->format == GO7007_FORMAT_MPEG1 ||
-				go->format == GO7007_FORMAT_MPEG2 ||
-				go->format == GO7007_FORMAT_MPEG4)
-			break;
-		go->format = GO7007_FORMAT_MPEG1;
-		go->pali = 0;
-		go->aspect_ratio = GO7007_RATIO_1_1;
-		go->gop_size = go->sensor_framerate / 1000;
-		go->ipb = 0;
-		go->closed_gop = 1;
-		go->repeat_seqhead = 1;
-		go->seq_header_enable = 1;
-		go->gop_header_enable = 1;
-		go->dvd_mode = 0;
-		break;
-	/* Backwards compatibility only! */
-	case V4L2_PIX_FMT_MPEG4:
-		if (go->format == GO7007_FORMAT_MPEG4)
-			break;
-		go->format = GO7007_FORMAT_MPEG4;
-		go->pali = 0xf5;
-		go->aspect_ratio = GO7007_RATIO_1_1;
-		go->gop_size = go->sensor_framerate / 1000;
-		go->ipb = 0;
-		go->closed_gop = 1;
-		go->repeat_seqhead = 1;
-		go->seq_header_enable = 1;
-		go->gop_header_enable = 1;
-		go->dvd_mode = 0;
-		break;
-	case V4L2_PIX_FMT_MJPEG:
-		go->format = GO7007_FORMAT_MJPEG;
-		go->pali = 0;
-		go->aspect_ratio = GO7007_RATIO_1_1;
-		go->gop_size = 0;
-		go->ipb = 0;
-		go->closed_gop = 0;
-		go->repeat_seqhead = 0;
-		go->seq_header_enable = 0;
-		go->gop_header_enable = 0;
-		go->dvd_mode = 0;
-		break;
-	}
 	return 0;
 }
 
@@ -385,98 +424,6 @@ static int clip_to_modet_map(struct go7007 *go, int region,
 }
 #endif
 
-static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct go7007 *go =
-		container_of(ctrl->handler, struct go7007, hdl);
-
-	/* pretty sure we can't change any of these while streaming */
-	if (go->streaming)
-		return -EBUSY;
-
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_STREAM_TYPE:
-		switch (ctrl->val) {
-		case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD:
-			go->format = GO7007_FORMAT_MPEG2;
-			go->bitrate = 9800000;
-			go->gop_size = 15;
-			go->pali = 0x48;
-			go->closed_gop = 1;
-			go->repeat_seqhead = 0;
-			go->seq_header_enable = 1;
-			go->gop_header_enable = 1;
-			go->dvd_mode = 1;
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		switch (ctrl->val) {
-		case V4L2_MPEG_VIDEO_ENCODING_MPEG_1:
-			go->format = GO7007_FORMAT_MPEG1;
-			go->pali = 0;
-			break;
-		case V4L2_MPEG_VIDEO_ENCODING_MPEG_2:
-			go->format = GO7007_FORMAT_MPEG2;
-			/*if (mpeg->pali >> 24 == 2)
-				go->pali = mpeg->pali & 0xff;
-			else*/
-				go->pali = 0x48;
-			break;
-		case V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC:
-			go->format = GO7007_FORMAT_MPEG4;
-			/*if (mpeg->pali >> 24 == 4)
-				go->pali = mpeg->pali & 0xff;
-			else*/
-				go->pali = 0xf5;
-			break;
-		default:
-			return -EINVAL;
-		}
-		go->gop_header_enable =
-			/*mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
-			? 0 :*/ 1;
-		/*if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
-			go->repeat_seqhead = 1;
-		else*/
-			go->repeat_seqhead = 0;
-		go->dvd_mode = 0;
-		break;
-	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		/* TODO: is this really the right thing to do for mjpeg? */
-		if (go->format == GO7007_FORMAT_MJPEG)
-			return -EINVAL;
-		switch (ctrl->val) {
-		case V4L2_MPEG_VIDEO_ASPECT_1x1:
-			go->aspect_ratio = GO7007_RATIO_1_1;
-			break;
-		case V4L2_MPEG_VIDEO_ASPECT_4x3:
-			go->aspect_ratio = GO7007_RATIO_4_3;
-			break;
-		case V4L2_MPEG_VIDEO_ASPECT_16x9:
-			go->aspect_ratio = GO7007_RATIO_16_9;
-			break;
-		default:
-			return -EINVAL;
-		}
-		break;
-	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
-		go->gop_size = ctrl->val;
-		break;
-	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
-		go->closed_gop = ctrl->val;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		go->bitrate = ctrl->val;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *cap)
 {
@@ -504,11 +451,19 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 	switch (fmt->index) {
 	case 0:
 		fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
-		desc = "Motion-JPEG";
+		desc = "Motion JPEG";
 		break;
 	case 1:
-		fmt->pixelformat = V4L2_PIX_FMT_MPEG;
-		desc = "MPEG1/MPEG2/MPEG4";
+		fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
+		desc = "MPEG-1 ES";
+		break;
+	case 2:
+		fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
+		desc = "MPEG-2 ES";
+		break;
+	case 3:
+		fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
+		desc = "MPEG-4 ES";
 		break;
 	default:
 		return -EINVAL;
@@ -529,8 +484,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	fmt->fmt.pix.width = go->width;
 	fmt->fmt.pix.height = go->height;
-	fmt->fmt.pix.pixelformat = (go->format == GO7007_FORMAT_MJPEG) ?
-				   V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
+	fmt->fmt.pix.pixelformat = go->format;
 	fmt->fmt.pix.field = V4L2_FIELD_NONE;
 	fmt->fmt.pix.bytesperline = 0;
 	fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
@@ -578,6 +532,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 		if (gofh->bufs[i].mapped > 0)
 			goto unlock_and_return;
 
+	set_formatting(go);
 	mutex_lock(&go->hw_lock);
 	if (go->in_use > 0 && gofh->buf_count == 0) {
 		mutex_unlock(&go->hw_lock);
@@ -833,6 +788,10 @@ static int vidioc_streamon(struct file *file, void *priv,
 	mutex_unlock(&go->hw_lock);
 	mutex_unlock(&gofh->lock);
 	call_all(&go->v4l2_dev, video, s_stream, 1);
+	v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
+	v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
+	v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
+	v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
 
 	return retval;
 }
@@ -911,8 +870,7 @@ static int vidioc_enum_framesizes(struct file *filp, void *priv,
 	if (fsize->index > 2)
 		return -EINVAL;
 
-	if (fsize->pixel_format != V4L2_PIX_FMT_MJPEG &&
-	    fsize->pixel_format != V4L2_PIX_FMT_MPEG)
+	if (!valid_pixelformat(fsize->pixel_format))
 		return -EINVAL;
 
 	get_resolution(go, &width, &height);
@@ -932,8 +890,7 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
 	if (fival->index > 4)
 		return -EINVAL;
 
-	if (fival->pixel_format != V4L2_PIX_FMT_MJPEG &&
-	    fival->pixel_format != V4L2_PIX_FMT_MPEG)
+	if (!valid_pixelformat(fival->pixel_format))
 		return -EINVAL;
 
 	if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
@@ -1257,180 +1214,6 @@ static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *
  */
 
 #if 0
-	/* Temporary ioctls for controlling compression characteristics */
-	case GO7007IOC_S_BITRATE:
-	{
-		int *bitrate = arg;
-
-		if (go->streaming)
-			return -EINVAL;
-		/* Upper bound is kind of arbitrary here */
-		if (*bitrate < 64000 || *bitrate > 10000000)
-			return -EINVAL;
-		go->bitrate = *bitrate;
-		return 0;
-	}
-	case GO7007IOC_G_BITRATE:
-	{
-		int *bitrate = arg;
-
-		*bitrate = go->bitrate;
-		return 0;
-	}
-	case GO7007IOC_S_COMP_PARAMS:
-	{
-		struct go7007_comp_params *comp = arg;
-
-		if (go->format == GO7007_FORMAT_MJPEG)
-			return -EINVAL;
-		if (comp->gop_size > 0)
-			go->gop_size = comp->gop_size;
-		else
-			go->gop_size = go->sensor_framerate / 1000;
-		if (go->gop_size != 15)
-			go->dvd_mode = 0;
-		/*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
-		if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
-			switch (comp->aspect_ratio) {
-			case GO7007_ASPECT_RATIO_4_3_NTSC:
-			case GO7007_ASPECT_RATIO_4_3_PAL:
-				go->aspect_ratio = GO7007_RATIO_4_3;
-				break;
-			case GO7007_ASPECT_RATIO_16_9_NTSC:
-			case GO7007_ASPECT_RATIO_16_9_PAL:
-				go->aspect_ratio = GO7007_RATIO_16_9;
-				break;
-			default:
-				go->aspect_ratio = GO7007_RATIO_1_1;
-				break;
-			}
-		}
-		if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
-			go->dvd_mode = 0;
-			go->seq_header_enable = 0;
-		} else {
-			go->seq_header_enable = 1;
-		}
-		/* fall-through */
-	}
-	case GO7007IOC_G_COMP_PARAMS:
-	{
-		struct go7007_comp_params *comp = arg;
-
-		if (go->format == GO7007_FORMAT_MJPEG)
-			return -EINVAL;
-		memset(comp, 0, sizeof(*comp));
-		comp->gop_size = go->gop_size;
-		comp->max_b_frames = go->ipb ? 2 : 0;
-		switch (go->aspect_ratio) {
-		case GO7007_RATIO_4_3:
-			if (go->standard == GO7007_STD_NTSC)
-				comp->aspect_ratio =
-					GO7007_ASPECT_RATIO_4_3_NTSC;
-			else
-				comp->aspect_ratio =
-					GO7007_ASPECT_RATIO_4_3_PAL;
-			break;
-		case GO7007_RATIO_16_9:
-			if (go->standard == GO7007_STD_NTSC)
-				comp->aspect_ratio =
-					GO7007_ASPECT_RATIO_16_9_NTSC;
-			else
-				comp->aspect_ratio =
-					GO7007_ASPECT_RATIO_16_9_PAL;
-			break;
-		default:
-			comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
-			break;
-		}
-		if (go->closed_gop)
-			comp->flags |= GO7007_COMP_CLOSED_GOP;
-		if (!go->seq_header_enable)
-			comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
-		return 0;
-	}
-	case GO7007IOC_S_MPEG_PARAMS:
-	{
-		struct go7007_mpeg_params *mpeg = arg;
-
-		if (go->format != GO7007_FORMAT_MPEG1 &&
-				go->format != GO7007_FORMAT_MPEG2 &&
-				go->format != GO7007_FORMAT_MPEG4)
-			return -EINVAL;
-
-		if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
-			go->format = GO7007_FORMAT_MPEG2;
-			go->bitrate = 9800000;
-			go->gop_size = 15;
-			go->pali = 0x48;
-			go->closed_gop = 1;
-			go->repeat_seqhead = 0;
-			go->seq_header_enable = 1;
-			go->gop_header_enable = 1;
-			go->dvd_mode = 1;
-		} else {
-			switch (mpeg->mpeg_video_standard) {
-			case GO7007_MPEG_VIDEO_MPEG1:
-				go->format = GO7007_FORMAT_MPEG1;
-				go->pali = 0;
-				break;
-			case GO7007_MPEG_VIDEO_MPEG2:
-				go->format = GO7007_FORMAT_MPEG2;
-				if (mpeg->pali >> 24 == 2)
-					go->pali = mpeg->pali & 0xff;
-				else
-					go->pali = 0x48;
-				break;
-			case GO7007_MPEG_VIDEO_MPEG4:
-				go->format = GO7007_FORMAT_MPEG4;
-				if (mpeg->pali >> 24 == 4)
-					go->pali = mpeg->pali & 0xff;
-				else
-					go->pali = 0xf5;
-				break;
-			default:
-				return -EINVAL;
-			}
-			go->gop_header_enable =
-				mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
-				? 0 : 1;
-			if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
-				go->repeat_seqhead = 1;
-			else
-				go->repeat_seqhead = 0;
-			go->dvd_mode = 0;
-		}
-		/* fall-through */
-	}
-	case GO7007IOC_G_MPEG_PARAMS:
-	{
-		struct go7007_mpeg_params *mpeg = arg;
-
-		memset(mpeg, 0, sizeof(*mpeg));
-		switch (go->format) {
-		case GO7007_FORMAT_MPEG1:
-			mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
-			mpeg->pali = 0;
-			break;
-		case GO7007_FORMAT_MPEG2:
-			mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
-			mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
-			break;
-		case GO7007_FORMAT_MPEG4:
-			mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
-			mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
-			break;
-		default:
-			return -EINVAL;
-		}
-		if (!go->gop_header_enable)
-			mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
-		if (go->repeat_seqhead)
-			mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
-		if (go->dvd_mode)
-			mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
-		return 0;
-	}
 	case GO7007IOC_S_MD_PARAMS:
 	{
 		struct go7007_md_params *mdp = arg;
@@ -1449,25 +1232,6 @@ static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *
 			go->modet[mdp->region].enable = 0;
 		/* fall-through */
 	}
-	case GO7007IOC_G_MD_PARAMS:
-	{
-		struct go7007_md_params *mdp = arg;
-		int region = mdp->region;
-
-		if (mdp->region > 3)
-			return -EINVAL;
-		memset(mdp, 0, sizeof(struct go7007_md_params));
-		mdp->region = region;
-		if (!go->modet[region].enable)
-			return 0;
-		mdp->pixel_threshold =
-			(go->modet[region].pixel_threshold << 1) + 1;
-		mdp->motion_threshold =
-			(go->modet[region].motion_threshold << 1) + 1;
-		mdp->trigger =
-			(go->modet[region].mb_threshold << 1) + 1;
-		return 0;
-	}
 	case GO7007IOC_S_MD_REGION:
 	{
 		struct go7007_md_region *region = arg;
@@ -1590,10 +1354,6 @@ static struct v4l2_file_operations go7007_fops = {
 	.poll		= go7007_poll,
 };
 
-static struct v4l2_ctrl_ops go7007_ctrl_ops = {
-	.s_ctrl = go7007_s_ctrl,
-};
-
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_querycap          = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
@@ -1645,29 +1405,18 @@ int go7007_v4l2_ctrl_init(struct go7007 *go)
 	struct v4l2_ctrl *ctrl;
 
 	v4l2_ctrl_handler_init(hdl, 12);
-	v4l2_ctrl_new_std_menu(hdl, &go7007_ctrl_ops,
-			V4L2_CID_MPEG_STREAM_TYPE,
-			V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
-			0x7,
-			V4L2_MPEG_STREAM_TYPE_MPEG2_DVD);
-	v4l2_ctrl_new_std_menu(hdl, &go7007_ctrl_ops,
-			V4L2_CID_MPEG_VIDEO_ENCODING,
-			V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC,
-			0,
-			V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
-	v4l2_ctrl_new_std_menu(hdl, &go7007_ctrl_ops,
-			V4L2_CID_MPEG_VIDEO_ASPECT,
-			V4L2_MPEG_VIDEO_ASPECT_16x9,
-			0,
-			V4L2_MPEG_VIDEO_ASPECT_1x1);
-	v4l2_ctrl_new_std(hdl, &go7007_ctrl_ops,
+	go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
 			V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
-	v4l2_ctrl_new_std(hdl, &go7007_ctrl_ops,
-			V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 0);
-	v4l2_ctrl_new_std(hdl, &go7007_ctrl_ops,
+	go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
+			V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
+	go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
 			V4L2_CID_MPEG_VIDEO_BITRATE,
-			64000, 10000000, 1, 1500000);
-	ctrl = v4l2_ctrl_new_std(hdl, &go7007_ctrl_ops,
+			64000, 10000000, 1, 9800000);
+	go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
+			V4L2_CID_MPEG_VIDEO_ASPECT,
+			V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
+			V4L2_MPEG_VIDEO_ASPECT_1x1);
+	ctrl = v4l2_ctrl_new_std(hdl, NULL,
 			V4L2_CID_JPEG_ACTIVE_MARKER, 0,
 			V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
 			V4L2_JPEG_ACTIVE_MARKER_DQT | V4L2_JPEG_ACTIVE_MARKER_DHT);
diff --git a/drivers/staging/media/go7007/go7007.h b/drivers/staging/media/go7007/go7007.h
index 7399c91..54b9897 100644
--- a/drivers/staging/media/go7007/go7007.h
+++ b/drivers/staging/media/go7007/go7007.h
@@ -17,72 +17,6 @@
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/* DEPRECATED -- use V4L2_PIX_FMT_MPEG and then call GO7007IOC_S_MPEG_PARAMS
- * to select between MPEG1, MPEG2, and MPEG4 */
-#define V4L2_PIX_FMT_MPEG4     v4l2_fourcc('M', 'P', 'G', '4') /* MPEG4 */
-
-/* These will be replaced with a better interface
- * soon, so don't get too attached to them */
-#define	GO7007IOC_S_BITRATE	_IOW('V', BASE_VIDIOC_PRIVATE + 0, int)
-#define	GO7007IOC_G_BITRATE	_IOR('V', BASE_VIDIOC_PRIVATE + 1, int)
-
-enum go7007_aspect_ratio {
-	GO7007_ASPECT_RATIO_1_1 = 0,
-	GO7007_ASPECT_RATIO_4_3_NTSC = 1,
-	GO7007_ASPECT_RATIO_4_3_PAL = 2,
-	GO7007_ASPECT_RATIO_16_9_NTSC = 3,
-	GO7007_ASPECT_RATIO_16_9_PAL = 4,
-};
-
-/* Used to set generic compression parameters */
-struct go7007_comp_params {
-	__u32 gop_size;
-	__u32 max_b_frames;
-	enum go7007_aspect_ratio aspect_ratio;
-	__u32 flags;
-	__u32 reserved[8];
-};
-
-#define GO7007_COMP_CLOSED_GOP		0x00000001
-#define GO7007_COMP_OMIT_SEQ_HEADER	0x00000002
-
-enum go7007_mpeg_video_standard {
-	GO7007_MPEG_VIDEO_MPEG1 = 0,
-	GO7007_MPEG_VIDEO_MPEG2 = 1,
-	GO7007_MPEG_VIDEO_MPEG4 = 2,
-};
-
-/* Used to set parameters for V4L2_PIX_FMT_MPEG format */
-struct go7007_mpeg_params {
-	enum go7007_mpeg_video_standard mpeg_video_standard;
-	__u32 flags;
-	__u32 pali;
-	__u32 reserved[8];
-};
-
-#define GO7007_MPEG_FORCE_DVD_MODE	0x00000001
-#define GO7007_MPEG_OMIT_GOP_HEADER	0x00000002
-#define GO7007_MPEG_REPEAT_SEQHEADER	0x00000004
-
-#define GO7007_MPEG_PROFILE(format, pali)	(((format)<<24)|(pali))
-
-#define GO7007_MPEG2_PROFILE_MAIN_MAIN		GO7007_MPEG_PROFILE(2, 0x48)
-
-#define GO7007_MPEG4_PROFILE_S_L0		GO7007_MPEG_PROFILE(4, 0x08)
-#define GO7007_MPEG4_PROFILE_S_L1		GO7007_MPEG_PROFILE(4, 0x01)
-#define GO7007_MPEG4_PROFILE_S_L2		GO7007_MPEG_PROFILE(4, 0x02)
-#define GO7007_MPEG4_PROFILE_S_L3		GO7007_MPEG_PROFILE(4, 0x03)
-#define GO7007_MPEG4_PROFILE_ARTS_L1		GO7007_MPEG_PROFILE(4, 0x91)
-#define GO7007_MPEG4_PROFILE_ARTS_L2		GO7007_MPEG_PROFILE(4, 0x92)
-#define GO7007_MPEG4_PROFILE_ARTS_L3		GO7007_MPEG_PROFILE(4, 0x93)
-#define GO7007_MPEG4_PROFILE_ARTS_L4		GO7007_MPEG_PROFILE(4, 0x94)
-#define GO7007_MPEG4_PROFILE_AS_L0		GO7007_MPEG_PROFILE(4, 0xf0)
-#define GO7007_MPEG4_PROFILE_AS_L1		GO7007_MPEG_PROFILE(4, 0xf1)
-#define GO7007_MPEG4_PROFILE_AS_L2		GO7007_MPEG_PROFILE(4, 0xf2)
-#define GO7007_MPEG4_PROFILE_AS_L3		GO7007_MPEG_PROFILE(4, 0xf3)
-#define GO7007_MPEG4_PROFILE_AS_L4		GO7007_MPEG_PROFILE(4, 0xf4)
-#define GO7007_MPEG4_PROFILE_AS_L5		GO7007_MPEG_PROFILE(4, 0xf5)
-
 struct go7007_md_params {
 	__u16 region;
 	__u16 trigger;
@@ -98,14 +32,6 @@ struct go7007_md_region {
 	__u32 reserved[8];
 };
 
-#define	GO7007IOC_S_MPEG_PARAMS	_IOWR('V', BASE_VIDIOC_PRIVATE + 2, \
-					struct go7007_mpeg_params)
-#define	GO7007IOC_G_MPEG_PARAMS	_IOR('V', BASE_VIDIOC_PRIVATE + 3, \
-					struct go7007_mpeg_params)
-#define	GO7007IOC_S_COMP_PARAMS	_IOWR('V', BASE_VIDIOC_PRIVATE + 4, \
-					struct go7007_comp_params)
-#define	GO7007IOC_G_COMP_PARAMS	_IOR('V', BASE_VIDIOC_PRIVATE + 5, \
-					struct go7007_comp_params)
 #define	GO7007IOC_S_MD_PARAMS	_IOWR('V', BASE_VIDIOC_PRIVATE + 6, \
 					struct go7007_md_params)
 #define	GO7007IOC_G_MD_PARAMS	_IOR('V', BASE_VIDIOC_PRIVATE + 7, \
-- 
1.7.10.4


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

* [REVIEW PATCH 31/42] go7007: simplify the PX-TV402U board ID handling.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (28 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 30/42] go7007: standardize MPEG handling support Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 32/42] go7007: set up the saa7115 audio clock correctly Hans Verkuil
                     ` (11 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

There really is no need to split out the board IDs for each tuner.
That's what the tuner_type is for, after all.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-priv.h |   15 ++++++---------
 drivers/staging/media/go7007/go7007-usb.c  |    9 +++------
 drivers/staging/media/go7007/go7007-v4l2.c |    9 ---------
 3 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index c2fafb2..a6ef67b 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -36,15 +36,12 @@ struct go7007;
 #define GO7007_BOARDID_XMEN_II		5
 #define GO7007_BOARDID_XMEN_III		6
 #define GO7007_BOARDID_MATRIX_REV	7
-#define GO7007_BOARDID_PX_M402U		16
-#define GO7007_BOARDID_PX_TV402U_ANY	17 /* need to check tuner model */
-#define GO7007_BOARDID_PX_TV402U_NA	18 /* detected NTSC tuner */
-#define GO7007_BOARDID_PX_TV402U_EU	19 /* detected PAL tuner */
-#define GO7007_BOARDID_PX_TV402U_JP	20 /* detected NTSC-J tuner */
-#define GO7007_BOARDID_LIFEVIEW_LR192	21 /* TV Walker Ultra */
-#define GO7007_BOARDID_ENDURA		22
-#define GO7007_BOARDID_ADLINK_MPG24	23
-#define GO7007_BOARDID_SENSORAY_2250	24 /* Sensoray 2250/2251 */
+#define GO7007_BOARDID_PX_M402U		8
+#define GO7007_BOARDID_PX_TV402U	9
+#define GO7007_BOARDID_LIFEVIEW_LR192	10 /* TV Walker Ultra */
+#define GO7007_BOARDID_ENDURA		11
+#define GO7007_BOARDID_ADLINK_MPG24	12
+#define GO7007_BOARDID_SENSORAY_2250	13 /* Sensoray 2250/2251 */
 
 /* Various characteristics of each board */
 #define GO7007_BOARD_HAS_AUDIO		(1<<0)
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 14d1cda..53c5b16 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -568,7 +568,7 @@ static const struct usb_device_id go7007_usb_id_table[] = {
 		.idProduct	= 0xa104,  /* Product ID of TV402U */
 		.bcdDevice_lo	= 0x1,
 		.bcdDevice_hi	= 0x1,
-		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_PX_TV402U_ANY,
+		.driver_info	= (kernel_ulong_t)GO7007_BOARDID_PX_TV402U,
 	},
 	{
 		.match_flags	= USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
@@ -1079,7 +1079,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 		name = "Plextor PX-M402U";
 		board = &board_matrix_ii;
 		break;
-	case GO7007_BOARDID_PX_TV402U_ANY:
+	case GO7007_BOARDID_PX_TV402U:
 		name = "Plextor PX-TV402U (unknown tuner)";
 		board = &board_px_tv402u;
 		break;
@@ -1200,7 +1200,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 	num_i2c_devs = go->board_info->num_i2c_devs;
 
 	/* Probe the tuner model on the TV402U */
-	if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) {
+	if (go->board_id == GO7007_BOARDID_PX_TV402U) {
 		/* Board strapping indicates tuner model */
 		if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3, 1) < 0) {
 			printk(KERN_ERR "go7007-usb: GPIO read failed!\n");
@@ -1208,14 +1208,12 @@ static int go7007_usb_probe(struct usb_interface *intf,
 		}
 		switch (go->usb_buf[0] >> 6) {
 		case 1:
-			go->board_id = GO7007_BOARDID_PX_TV402U_EU;
 			go->tuner_type = TUNER_SONY_BTF_PG472Z;
 			go->std = V4L2_STD_PAL;
 			strncpy(go->name, "Plextor PX-TV402U-EU",
 					sizeof(go->name));
 			break;
 		case 2:
-			go->board_id = GO7007_BOARDID_PX_TV402U_JP;
 			go->tuner_type = TUNER_SONY_BTF_PK467Z;
 			go->std = V4L2_STD_NTSC_M_JP;
 			num_i2c_devs -= 2;
@@ -1223,7 +1221,6 @@ static int go7007_usb_probe(struct usb_interface *intf,
 					sizeof(go->name));
 			break;
 		case 3:
-			go->board_id = GO7007_BOARDID_PX_TV402U_NA;
 			go->tuner_type = TUNER_SONY_BTF_PB463Z;
 			num_i2c_devs -= 2;
 			strncpy(go->name, "Plextor PX-TV402U-NA",
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index df5296f..fd6cae0 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -1075,15 +1075,6 @@ static int vidioc_s_tuner(struct file *file, void *priv,
 	if (t->index != 0)
 		return -EINVAL;
 
-	switch (go->board_id) {
-	case GO7007_BOARDID_PX_TV402U_NA:
-	case GO7007_BOARDID_PX_TV402U_JP:
-		/* No selectable options currently */
-		if (t->audmode != V4L2_TUNER_MODE_STEREO)
-			return -EINVAL;
-		break;
-	}
-
 	return call_all(&go->v4l2_dev, tuner, s_tuner, t);
 }
 
-- 
1.7.10.4


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

* [REVIEW PATCH 32/42] go7007: set up the saa7115 audio clock correctly.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (29 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 31/42] go7007: simplify the PX-TV402U board ID handling Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 33/42] go7007: drop struct go7007_file Hans Verkuil
                     ` (10 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

The s_crystal_freq operation has to be called for the saa7115 to
set up the audio clock correctly.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-priv.h |    1 +
 drivers/staging/media/go7007/go7007-usb.c  |    5 ++++-
 drivers/staging/media/go7007/go7007-v4l2.c |    7 +++++++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index a6ef67b..7f79cc1 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -60,6 +60,7 @@ struct go7007;
 #define GO7007_SENSOR_TV		(1<<7)
 #define GO7007_SENSOR_VBI		(1<<8)
 #define GO7007_SENSOR_SCALING		(1<<9)
+#define GO7007_SENSOR_SAA7115		(1<<10)
 
 /* Characteristics of audio sensor devices */
 #define GO7007_AUDIO_I2S_MODE_1		(1)
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 53c5b16..5c7a19e6 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -88,6 +88,7 @@ static struct go7007_usb_board board_matrix_ii = {
 		.sensor_flags	 = GO7007_SENSOR_656 |
 					GO7007_SENSOR_VALID_ENABLE |
 					GO7007_SENSOR_TV |
+					GO7007_SENSOR_SAA7115 |
 					GO7007_SENSOR_VBI |
 					GO7007_SENSOR_SCALING,
 		.num_i2c_devs	 = 1,
@@ -131,7 +132,7 @@ static struct go7007_usb_board board_matrix_reload = {
 		.num_i2c_devs	 = 1,
 		.i2c_devs	 = {
 			{
-				.type	= "saa7115",
+				.type	= "saa7113",
 				.addr	= 0x25,
 				.is_video = 1,
 			},
@@ -160,6 +161,7 @@ static struct go7007_usb_board board_star_trek = {
 		.sensor_flags	 = GO7007_SENSOR_656 |
 					GO7007_SENSOR_VALID_ENABLE |
 					GO7007_SENSOR_TV |
+					GO7007_SENSOR_SAA7115 |
 					GO7007_SENSOR_VBI |
 					GO7007_SENSOR_SCALING,
 		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
@@ -207,6 +209,7 @@ static struct go7007_usb_board board_px_tv402u = {
 		.sensor_flags	 = GO7007_SENSOR_656 |
 					GO7007_SENSOR_VALID_ENABLE |
 					GO7007_SENSOR_TV |
+					GO7007_SENSOR_SAA7115 |
 					GO7007_SENSOR_VBI |
 					GO7007_SENSOR_SCALING,
 		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index fd6cae0..972f8a5 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -35,6 +35,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-event.h>
+#include <media/saa7115.h>
 
 #include "go7007.h"
 #include "go7007-priv.h"
@@ -1461,6 +1462,12 @@ int go7007_v4l2_init(struct go7007 *go)
 		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_AUDIO);
 		v4l2_disable_ioctl(go->video_dev, VIDIOC_ENUMAUDIO);
 	}
+	/* Setup correct crystal frequency on this board */
+	if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
+		v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
+				SAA7115_FREQ_24_576_MHZ,
+				SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
+				SAA7115_FREQ_FL_DOUBLE_ASCLK);
 	go7007_s_input(go);
 	if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
 		go7007_s_std(go);
-- 
1.7.10.4


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

* [REVIEW PATCH 33/42] go7007: drop struct go7007_file
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (30 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 32/42] go7007: set up the saa7115 audio clock correctly Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 34/42] go7007: convert to core locking and vb2 Hans Verkuil
                     ` (9 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Remove struct go7007_file: all fields contained in that struct are moved to
the go7007 struct since they are really global values. The lock has just
been deleted (what's the point of a per-fh lock??).

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-priv.h |   11 +-
 drivers/staging/media/go7007/go7007-v4l2.c |  177 ++++++++++------------------
 2 files changed, 67 insertions(+), 121 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index 7f79cc1..2c0afb1 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -141,14 +141,6 @@ struct go7007_buffer {
 	int mapped;
 };
 
-struct go7007_file {
-	struct v4l2_fh fh;
-	struct go7007 *go;
-	struct mutex lock;
-	int buf_count;
-	struct go7007_buffer *bufs;
-};
-
 #define GO7007_RATIO_1_1	0
 #define GO7007_RATIO_4_3	1
 #define GO7007_RATIO_16_9	2
@@ -242,6 +234,9 @@ struct go7007 {
 	u32 next_seq;
 	struct list_head stream;
 	wait_queue_head_t frame_waitq;
+	int buf_count;
+	struct go7007_buffer *bufs;
+	struct v4l2_fh *bufs_owner;
 
 	/* Audio streaming */
 	void (*audio_deliver)(struct go7007 *go, u8 *buf, int length);
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 972f8a5..191af80 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -88,41 +88,19 @@ static int go7007_streamoff(struct go7007 *go)
 	return 0;
 }
 
-static int go7007_open(struct file *file)
-{
-	struct go7007 *go = video_get_drvdata(video_devdata(file));
-	struct go7007_file *gofh;
-
-	if (go->status != STATUS_ONLINE)
-		return -EBUSY;
-	gofh = kzalloc(sizeof(struct go7007_file), GFP_KERNEL);
-	if (gofh == NULL)
-		return -ENOMEM;
-	gofh->go = go;
-	mutex_init(&gofh->lock);
-	gofh->buf_count = 0;
-	file->private_data = gofh;
-	v4l2_fh_init(&gofh->fh, video_devdata(file));
-	v4l2_fh_add(&gofh->fh);
-	return 0;
-}
-
 static int go7007_release(struct file *file)
 {
-	struct go7007_file *gofh = file->private_data;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = video_drvdata(file);
 
-	if (gofh->buf_count > 0) {
+	if (file->private_data == go->bufs_owner && go->buf_count > 0) {
 		go7007_streamoff(go);
 		go->in_use = 0;
-		kfree(gofh->bufs);
-		gofh->buf_count = 0;
+		kfree(go->bufs);
+		go->bufs = NULL;
+		go->buf_count = 0;
+		go->bufs_owner = NULL;
 	}
-	v4l2_fh_del(&gofh->fh);
-	v4l2_fh_exit(&gofh->fh);
-	kfree(gofh);
-	file->private_data = NULL;
-	return 0;
+	return v4l2_fh_release(file);
 }
 
 static bool valid_pixelformat(u32 pixelformat)
@@ -428,7 +406,7 @@ static int clip_to_modet_map(struct go7007 *go, int region,
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *cap)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	strlcpy(cap->driver, "go7007", sizeof(cap->driver));
 	strlcpy(cap->card, go->name, sizeof(cap->card));
@@ -480,7 +458,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 					struct v4l2_format *fmt)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	fmt->fmt.pix.width = go->width;
@@ -497,7 +475,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 			struct v4l2_format *fmt)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	return set_capture_size(go, fmt, 1);
 }
@@ -505,7 +483,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 			struct v4l2_format *fmt)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (go->streaming)
 		return -EBUSY;
@@ -516,8 +494,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_reqbufs(struct file *file, void *priv,
 			  struct v4l2_requestbuffers *req)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = video_drvdata(file);
 	int retval = -EBUSY;
 	unsigned int count, i;
 
@@ -528,20 +505,19 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 			req->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
 
-	mutex_lock(&gofh->lock);
-	for (i = 0; i < gofh->buf_count; ++i)
-		if (gofh->bufs[i].mapped > 0)
+	for (i = 0; i < go->buf_count; ++i)
+		if (go->bufs[i].mapped > 0)
 			goto unlock_and_return;
 
 	set_formatting(go);
 	mutex_lock(&go->hw_lock);
-	if (go->in_use > 0 && gofh->buf_count == 0) {
+	if (go->in_use > 0 && go->buf_count == 0) {
 		mutex_unlock(&go->hw_lock);
 		goto unlock_and_return;
 	}
 
-	if (gofh->buf_count > 0)
-		kfree(gofh->bufs);
+	if (go->buf_count > 0)
+		kfree(go->bufs);
 
 	retval = -ENOMEM;
 	count = req->count;
@@ -551,29 +527,30 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 		if (count > 32)
 			count = 32;
 
-		gofh->bufs = kcalloc(count, sizeof(struct go7007_buffer),
+		go->bufs = kcalloc(count, sizeof(struct go7007_buffer),
 				     GFP_KERNEL);
 
-		if (!gofh->bufs) {
+		if (!go->bufs) {
 			mutex_unlock(&go->hw_lock);
 			goto unlock_and_return;
 		}
 
 		for (i = 0; i < count; ++i) {
-			gofh->bufs[i].go = go;
-			gofh->bufs[i].index = i;
-			gofh->bufs[i].state = BUF_STATE_IDLE;
-			gofh->bufs[i].mapped = 0;
+			go->bufs[i].go = go;
+			go->bufs[i].index = i;
+			go->bufs[i].state = BUF_STATE_IDLE;
+			go->bufs[i].mapped = 0;
 		}
 
 		go->in_use = 1;
+		go->bufs_owner = file->private_data;
 	} else {
 		go->in_use = 0;
+		go->bufs_owner = NULL;
 	}
 
-	gofh->buf_count = count;
+	go->buf_count = count;
 	mutex_unlock(&go->hw_lock);
-	mutex_unlock(&gofh->lock);
 
 	memset(req, 0, sizeof(*req));
 
@@ -584,14 +561,13 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 	return 0;
 
 unlock_and_return:
-	mutex_unlock(&gofh->lock);
 	return retval;
 }
 
 static int vidioc_querybuf(struct file *file, void *priv,
 			   struct v4l2_buffer *buf)
 {
-	struct go7007_file *gofh = priv;
+	struct go7007 *go = video_drvdata(file);
 	int retval = -EINVAL;
 	unsigned int index;
 
@@ -600,15 +576,14 @@ static int vidioc_querybuf(struct file *file, void *priv,
 
 	index = buf->index;
 
-	mutex_lock(&gofh->lock);
-	if (index >= gofh->buf_count)
+	if (index >= go->buf_count)
 		goto unlock_and_return;
 
 	memset(buf, 0, sizeof(*buf));
 	buf->index = index;
 	buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
-	switch (gofh->bufs[index].state) {
+	switch (go->bufs[index].state) {
 	case BUF_STATE_QUEUED:
 		buf->flags = V4L2_BUF_FLAG_QUEUED;
 		break;
@@ -619,24 +594,21 @@ static int vidioc_querybuf(struct file *file, void *priv,
 		buf->flags = 0;
 	}
 
-	if (gofh->bufs[index].mapped)
+	if (go->bufs[index].mapped)
 		buf->flags |= V4L2_BUF_FLAG_MAPPED;
 	buf->memory = V4L2_MEMORY_MMAP;
 	buf->m.offset = index * GO7007_BUF_SIZE;
 	buf->length = GO7007_BUF_SIZE;
-	mutex_unlock(&gofh->lock);
 
 	return 0;
 
 unlock_and_return:
-	mutex_unlock(&gofh->lock);
 	return retval;
 }
 
 static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = video_drvdata(file);
 	struct go7007_buffer *gobuf;
 	unsigned long flags;
 	int retval = -EINVAL;
@@ -646,11 +618,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 			buf->memory != V4L2_MEMORY_MMAP)
 		return retval;
 
-	mutex_lock(&gofh->lock);
-	if (buf->index >= gofh->buf_count)
+	if (buf->index >= go->buf_count)
 		goto unlock_and_return;
 
-	gobuf = &gofh->bufs[buf->index];
+	gobuf = &go->bufs[buf->index];
 	if (!gobuf->mapped)
 		goto unlock_and_return;
 
@@ -687,20 +658,17 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 	spin_lock_irqsave(&go->spinlock, flags);
 	list_add_tail(&gobuf->stream, &go->stream);
 	spin_unlock_irqrestore(&go->spinlock, flags);
-	mutex_unlock(&gofh->lock);
 
 	return 0;
 
 unlock_and_return:
-	mutex_unlock(&gofh->lock);
 	return retval;
 }
 
 
 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = video_drvdata(file);
 	struct go7007_buffer *gobuf;
 	int retval = -EINVAL;
 	unsigned long flags;
@@ -712,7 +680,6 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 	if (buf->memory != V4L2_MEMORY_MMAP)
 		return retval;
 
-	mutex_lock(&gofh->lock);
 	if (list_empty(&go->stream))
 		goto unlock_and_return;
 	gobuf = list_entry(go->stream.next,
@@ -756,25 +723,21 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 	buf->length = GO7007_BUF_SIZE;
 	buf->reserved = gobuf->modet_active;
 
-	mutex_unlock(&gofh->lock);
 	return 0;
 
 unlock_and_return:
-	mutex_unlock(&gofh->lock);
 	return retval;
 }
 
 static int vidioc_streamon(struct file *file, void *priv,
 					enum v4l2_buf_type type)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = video_drvdata(file);
 	int retval = 0;
 
 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
-	mutex_lock(&gofh->lock);
 	mutex_lock(&go->hw_lock);
 
 	if (!go->streaming) {
@@ -787,7 +750,6 @@ static int vidioc_streamon(struct file *file, void *priv,
 			retval = 0;
 	}
 	mutex_unlock(&go->hw_lock);
-	mutex_unlock(&gofh->lock);
 	call_all(&go->v4l2_dev, video, s_stream, 1);
 	v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
 	v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
@@ -800,14 +762,11 @@ static int vidioc_streamon(struct file *file, void *priv,
 static int vidioc_streamoff(struct file *file, void *priv,
 					enum v4l2_buf_type type)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
-	mutex_lock(&gofh->lock);
 	go7007_streamoff(go);
-	mutex_unlock(&gofh->lock);
 	call_all(&go->v4l2_dev, video, s_stream, 0);
 
 	return 0;
@@ -816,7 +775,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
 static int vidioc_g_parm(struct file *filp, void *priv,
 		struct v4l2_streamparm *parm)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(filp);
 	struct v4l2_fract timeperframe = {
 		.numerator = 1001 *  go->fps_scale,
 		.denominator = go->sensor_framerate,
@@ -835,7 +794,7 @@ static int vidioc_g_parm(struct file *filp, void *priv,
 static int vidioc_s_parm(struct file *filp, void *priv,
 		struct v4l2_streamparm *parm)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(filp);
 	unsigned int n, d;
 
 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -865,7 +824,7 @@ static int vidioc_s_parm(struct file *filp, void *priv,
 static int vidioc_enum_framesizes(struct file *filp, void *priv,
 				  struct v4l2_frmsizeenum *fsize)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(filp);
 	int width, height;
 
 	if (fsize->index > 2)
@@ -884,7 +843,7 @@ static int vidioc_enum_framesizes(struct file *filp, void *priv,
 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
 				      struct v4l2_frmivalenum *fival)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(filp);
 	int width, height;
 	int i;
 
@@ -911,7 +870,7 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
 
 static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	*std = go->std;
 	return 0;
@@ -946,7 +905,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
 
 static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	return call_all(&go->v4l2_dev, video, querystd, std);
 }
@@ -954,7 +913,7 @@ static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
 static int vidioc_enum_input(struct file *file, void *priv,
 				struct v4l2_input *inp)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (inp->index >= go->board_info->num_inputs)
 		return -EINVAL;
@@ -985,7 +944,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
 
 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	*input = go->input;
 
@@ -1059,7 +1018,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *t)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (t->index != 0)
 		return -EINVAL;
@@ -1071,7 +1030,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 static int vidioc_s_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *t)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (t->index != 0)
 		return -EINVAL;
@@ -1082,7 +1041,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (f->tuner)
 		return -EINVAL;
@@ -1093,7 +1052,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
 static int vidioc_s_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (f->tuner)
 		return -EINVAL;
@@ -1103,7 +1062,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 
 static int vidioc_log_status(struct file *file, void *priv)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	v4l2_ctrl_log_status(file, priv);
 	return call_all(&go->v4l2_dev, core, log_status);
@@ -1112,7 +1071,7 @@ static int vidioc_log_status(struct file *file, void *priv)
 static int vidioc_cropcap(struct file *file, void *priv,
 					struct v4l2_cropcap *cropcap)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1156,7 +1115,7 @@ static int vidioc_cropcap(struct file *file, void *priv,
 
 static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
 {
-	struct go7007 *go = ((struct go7007_file *) priv)->go;
+	struct go7007 *go = video_drvdata(file);
 
 	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1280,52 +1239,44 @@ static struct vm_operations_struct go7007_vm_ops = {
 
 static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct go7007_file *gofh = file->private_data;
+	struct go7007 *go = video_drvdata(file);
 	unsigned int index;
 
-	if (gofh->go->status != STATUS_ONLINE)
+	if (go->status != STATUS_ONLINE)
 		return -EIO;
 	if (!(vma->vm_flags & VM_SHARED))
 		return -EINVAL; /* only support VM_SHARED mapping */
 	if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
 		return -EINVAL; /* must map exactly one full buffer */
-	mutex_lock(&gofh->lock);
 	index = vma->vm_pgoff / GO7007_BUF_PAGES;
-	if (index >= gofh->buf_count) {
-		mutex_unlock(&gofh->lock);
+	if (index >= go->buf_count)
 		return -EINVAL; /* trying to map beyond requested buffers */
-	}
-	if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
-		mutex_unlock(&gofh->lock);
+	if (index * GO7007_BUF_PAGES != vma->vm_pgoff)
 		return -EINVAL; /* offset is not aligned on buffer boundary */
-	}
-	if (gofh->bufs[index].mapped > 0) {
-		mutex_unlock(&gofh->lock);
+	if (go->bufs[index].mapped > 0)
 		return -EBUSY;
-	}
-	gofh->bufs[index].mapped = 1;
-	gofh->bufs[index].user_addr = vma->vm_start;
+	go->bufs[index].mapped = 1;
+	go->bufs[index].user_addr = vma->vm_start;
 	vma->vm_ops = &go7007_vm_ops;
 	vma->vm_flags |= VM_DONTEXPAND;
 	vma->vm_flags &= ~VM_IO;
-	vma->vm_private_data = &gofh->bufs[index];
-	mutex_unlock(&gofh->lock);
+	vma->vm_private_data = &go->bufs[index];
 	return 0;
 }
 
 static unsigned int go7007_poll(struct file *file, poll_table *wait)
 {
 	unsigned long req_events = poll_requested_events(wait);
-	struct go7007_file *gofh = file->private_data;
+	struct go7007 *go = video_drvdata(file);
 	struct go7007_buffer *gobuf;
 	unsigned int res = v4l2_ctrl_poll(file, wait);
 
 	if (!(req_events & (POLLIN | POLLRDNORM)))
 		return res;
-	if (list_empty(&gofh->go->stream))
+	if (list_empty(&go->stream))
 		return POLLERR;
-	gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
-	poll_wait(file, &gofh->go->frame_waitq, wait);
+	gobuf = list_entry(go->stream.next, struct go7007_buffer, stream);
+	poll_wait(file, &go->frame_waitq, wait);
 	if (gobuf->state == BUF_STATE_DONE)
 		return res | POLLIN | POLLRDNORM;
 	return res;
@@ -1338,7 +1289,7 @@ static void go7007_vfl_release(struct video_device *vfd)
 
 static struct v4l2_file_operations go7007_fops = {
 	.owner		= THIS_MODULE,
-	.open		= go7007_open,
+	.open		= v4l2_fh_open,
 	.release	= go7007_release,
 	.ioctl		= video_ioctl2,
 	.read		= go7007_read,
-- 
1.7.10.4


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

* [REVIEW PATCH 34/42] go7007: convert to core locking and vb2.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (31 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 33/42] go7007: drop struct go7007_file Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 35/42] go7007: embed struct video_device Hans Verkuil
                     ` (8 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Convert this driver to videobuf2 and core locking.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/Kconfig          |    2 +-
 drivers/staging/media/go7007/go7007-driver.c  |  156 ++++---
 drivers/staging/media/go7007/go7007-priv.h    |   27 +-
 drivers/staging/media/go7007/go7007-usb.c     |    9 +-
 drivers/staging/media/go7007/go7007-v4l2.c    |  535 ++++++-------------------
 drivers/staging/media/go7007/saa7134-go7007.c |    2 +-
 6 files changed, 205 insertions(+), 526 deletions(-)

diff --git a/drivers/staging/media/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig
index da32031..46cb7bf 100644
--- a/drivers/staging/media/go7007/Kconfig
+++ b/drivers/staging/media/go7007/Kconfig
@@ -2,7 +2,7 @@ config VIDEO_GO7007
 	tristate "WIS GO7007 MPEG encoder support"
 	depends on VIDEO_DEV && PCI && I2C
 	depends on SND
-	select VIDEOBUF_DMA_SG
+	select VIDEOBUF2_VMALLOC
 	depends on RC_CORE
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index 732b452..075de4d 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -363,48 +363,54 @@ start_error:
 /*
  * Store a byte in the current video buffer, if there is one.
  */
-static inline void store_byte(struct go7007_buffer *gobuf, u8 byte)
+static inline void store_byte(struct go7007_buffer *vb, u8 byte)
 {
-	if (gobuf != NULL && gobuf->bytesused < GO7007_BUF_SIZE) {
-		unsigned int pgidx = gobuf->offset >> PAGE_SHIFT;
-		unsigned int pgoff = gobuf->offset & ~PAGE_MASK;
+	if (vb && vb->vb.v4l2_planes[0].bytesused < GO7007_BUF_SIZE) {
+		u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
 
-		*((u8 *)page_address(gobuf->pages[pgidx]) + pgoff) = byte;
-		++gobuf->offset;
-		++gobuf->bytesused;
+		ptr[vb->vb.v4l2_planes[0].bytesused++] = byte;
 	}
 }
 
 /*
  * Deliver the last video buffer and get a new one to start writing to.
  */
-static void frame_boundary(struct go7007 *go)
+static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buffer *vb)
 {
-	struct go7007_buffer *gobuf;
+	struct go7007_buffer *vb_tmp = NULL;
+	u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused;
 	int i;
 
-	if (go->active_buf) {
-		if (go->active_buf->modet_active) {
-			if (go->active_buf->bytesused + 216 < GO7007_BUF_SIZE) {
+	if (vb) {
+		if (vb->modet_active) {
+			if (*bytesused + 216 < GO7007_BUF_SIZE) {
 				for (i = 0; i < 216; ++i)
-					store_byte(go->active_buf,
-							go->active_map[i]);
-				go->active_buf->bytesused -= 216;
+					store_byte(vb, go->active_map[i]);
+				*bytesused -= 216;
 			} else
-				go->active_buf->modet_active = 0;
+				vb->modet_active = 0;
 		}
-		go->active_buf->state = BUF_STATE_DONE;
-		wake_up_interruptible(&go->frame_waitq);
-		go->active_buf = NULL;
+		vb->vb.v4l2_buf.sequence = go->next_seq++;
+		v4l2_get_timestamp(&vb->vb.v4l2_buf.timestamp);
+		vb_tmp = vb;
+		spin_lock(&go->spinlock);
+		list_del(&vb->list);
+		if (list_empty(&go->vidq_active))
+			vb = NULL;
+		else
+			vb = list_first_entry(&go->vidq_active, struct go7007_buffer, list);
+		go->active_buf = vb;
+		spin_unlock(&go->spinlock);
+		vb2_buffer_done(&vb_tmp->vb, VB2_BUF_STATE_DONE);
+		return vb;
 	}
-	list_for_each_entry(gobuf, &go->stream, stream)
-		if (gobuf->state == BUF_STATE_QUEUED) {
-			gobuf->seq = go->next_seq;
-			do_gettimeofday(&gobuf->timestamp);
-			go->active_buf = gobuf;
-			break;
-		}
-	++go->next_seq;
+	spin_lock(&go->spinlock);
+	if (!list_empty(&go->vidq_active))
+		vb = go->active_buf =
+			list_first_entry(&go->vidq_active, struct go7007_buffer, list);
+	spin_unlock(&go->spinlock);
+	go->next_seq++;
+	return vb;
 }
 
 static void write_bitmap_word(struct go7007 *go)
@@ -428,10 +434,9 @@ static void write_bitmap_word(struct go7007 *go)
  */
 void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 {
+	struct go7007_buffer *vb = go->active_buf;
 	int i, seq_start_code = -1, frame_start_code = -1;
 
-	spin_lock(&go->spinlock);
-
 	switch (go->format) {
 	case V4L2_PIX_FMT_MPEG4:
 		seq_start_code = 0xB0;
@@ -445,13 +450,12 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 	}
 
 	for (i = 0; i < length; ++i) {
-		if (go->active_buf != NULL &&
-			    go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
+		if (vb && vb->vb.v4l2_planes[0].bytesused >= GO7007_BUF_SIZE - 3) {
 			v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
-			go->active_buf->offset -= go->active_buf->bytesused;
-			go->active_buf->bytesused = 0;
-			go->active_buf->modet_active = 0;
-			go->active_buf = NULL;
+			vb->vb.v4l2_planes[0].bytesused = 0;
+			vb->frame_offset = 0;
+			vb->modet_active = 0;
+			vb = go->active_buf = NULL;
 		}
 
 		switch (go->state) {
@@ -464,7 +468,7 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 				go->state = STATE_FF;
 				break;
 			default:
-				store_byte(go->active_buf, buf[i]);
+				store_byte(vb, buf[i]);
 				break;
 			}
 			break;
@@ -474,12 +478,12 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 				go->state = STATE_00_00;
 				break;
 			case 0xFF:
-				store_byte(go->active_buf, 0x00);
+				store_byte(vb, 0x00);
 				go->state = STATE_FF;
 				break;
 			default:
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, buf[i]);
+				store_byte(vb, 0x00);
+				store_byte(vb, buf[i]);
 				go->state = STATE_DATA;
 				break;
 			}
@@ -487,21 +491,21 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 		case STATE_00_00:
 			switch (buf[i]) {
 			case 0x00:
-				store_byte(go->active_buf, 0x00);
+				store_byte(vb, 0x00);
 				/* go->state remains STATE_00_00 */
 				break;
 			case 0x01:
 				go->state = STATE_00_00_01;
 				break;
 			case 0xFF:
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, 0x00);
+				store_byte(vb, 0x00);
+				store_byte(vb, 0x00);
 				go->state = STATE_FF;
 				break;
 			default:
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, buf[i]);
+				store_byte(vb, 0x00);
+				store_byte(vb, 0x00);
+				store_byte(vb, buf[i]);
 				go->state = STATE_DATA;
 				break;
 			}
@@ -509,10 +513,10 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 		case STATE_00_00_01:
 			if (buf[i] == 0xF8 && go->modet_enable == 0) {
 				/* MODET start code, but MODET not enabled */
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, 0x01);
-				store_byte(go->active_buf, 0xF8);
+				store_byte(vb, 0x00);
+				store_byte(vb, 0x00);
+				store_byte(vb, 0x01);
+				store_byte(vb, 0xF8);
 				go->state = STATE_DATA;
 				break;
 			}
@@ -521,19 +525,14 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 			if ((go->format == V4L2_PIX_FMT_MPEG1 ||
 			     go->format == V4L2_PIX_FMT_MPEG2 ||
 			     go->format == V4L2_PIX_FMT_MPEG4) &&
-					(buf[i] == seq_start_code ||
-						buf[i] == 0xB8 || /* GOP code */
-						buf[i] == frame_start_code)) {
-				if (go->active_buf == NULL || go->seen_frame)
-					frame_boundary(go);
-				if (buf[i] == frame_start_code) {
-					if (go->active_buf != NULL)
-						go->active_buf->frame_offset =
-							go->active_buf->offset;
-					go->seen_frame = 1;
-				} else {
-					go->seen_frame = 0;
-				}
+			    (buf[i] == seq_start_code ||
+			     buf[i] == 0xB8 || /* GOP code */
+			     buf[i] == frame_start_code)) {
+				if (vb == NULL || go->seen_frame)
+					vb = frame_boundary(go, vb);
+				go->seen_frame = buf[i] == frame_start_code;
+				if (vb && go->seen_frame)
+					vb->frame_offset = vb->vb.v4l2_planes[0].bytesused;
 			}
 			/* Handle any special chunk types, or just write the
 			 * start code to the (potentially new) buffer */
@@ -552,16 +551,16 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 				go->state = STATE_MODET_MAP;
 				break;
 			case 0xFF: /* Potential JPEG start code */
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, 0x01);
+				store_byte(vb, 0x00);
+				store_byte(vb, 0x00);
+				store_byte(vb, 0x01);
 				go->state = STATE_FF;
 				break;
 			default:
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, 0x00);
-				store_byte(go->active_buf, 0x01);
-				store_byte(go->active_buf, buf[i]);
+				store_byte(vb, 0x00);
+				store_byte(vb, 0x00);
+				store_byte(vb, 0x01);
+				store_byte(vb, buf[i]);
 				go->state = STATE_DATA;
 				break;
 			}
@@ -569,20 +568,20 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 		case STATE_FF:
 			switch (buf[i]) {
 			case 0x00:
-				store_byte(go->active_buf, 0xFF);
+				store_byte(vb, 0xFF);
 				go->state = STATE_00;
 				break;
 			case 0xFF:
-				store_byte(go->active_buf, 0xFF);
+				store_byte(vb, 0xFF);
 				/* go->state remains STATE_FF */
 				break;
 			case 0xD8:
 				if (go->format == V4L2_PIX_FMT_MJPEG)
-					frame_boundary(go);
+					vb = frame_boundary(go, vb);
 				/* fall through */
 			default:
-				store_byte(go->active_buf, 0xFF);
-				store_byte(go->active_buf, buf[i]);
+				store_byte(vb, 0xFF);
+				store_byte(vb, buf[i]);
 				go->state = STATE_DATA;
 				break;
 			}
@@ -605,8 +604,8 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 					write_bitmap_word(go);
 				} else
 					go->modet_word = buf[i] << 8;
-			} else if (go->parse_length == 207 && go->active_buf) {
-				go->active_buf->modet_active = buf[i];
+			} else if (go->parse_length == 207 && vb) {
+				vb->modet_active = buf[i];
 			}
 			if (++go->parse_length == 208)
 				go->state = STATE_DATA;
@@ -617,8 +616,6 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 			break;
 		}
 	}
-
-	spin_unlock(&go->spinlock);
 }
 EXPORT_SYMBOL(go7007_parse_video_stream);
 
@@ -648,14 +645,12 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 	go->i2c_adapter_online = 0;
 	go->interrupt_available = 0;
 	init_waitqueue_head(&go->interrupt_waitq);
-	go->in_use = 0;
 	go->input = 0;
 	go7007_update_board(go);
 	go->encoder_h_halve = 0;
 	go->encoder_v_halve = 0;
 	go->encoder_subsample = 0;
 	go->format = V4L2_PIX_FMT_MJPEG;
-	go->streaming = 0;
 	go->bitrate = 1500000;
 	go->fps_scale = 1;
 	go->pali = 0;
@@ -674,7 +669,6 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 		go->modet_map[i] = 0;
 	go->audio_deliver = NULL;
 	go->audio_enabled = 0;
-	INIT_LIST_HEAD(&go->stream);
 
 	return go;
 }
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index 2c0afb1..30148eb 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -24,6 +24,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-fh.h>
+#include <media/videobuf2-core.h>
 
 struct go7007;
 
@@ -125,20 +126,10 @@ struct go7007_hpi_ops {
 #define	GO7007_BUF_SIZE		(GO7007_BUF_PAGES << PAGE_SHIFT)
 
 struct go7007_buffer {
-	struct go7007 *go; /* Reverse reference for VMA ops */
-	int index; /* Reverse reference for DQBUF */
-	enum { BUF_STATE_IDLE, BUF_STATE_QUEUED, BUF_STATE_DONE } state;
-	u32 seq;
-	struct timeval timestamp;
-	struct list_head stream;
-	struct page *pages[GO7007_BUF_PAGES + 1]; /* extra for straddling */
-	unsigned long user_addr;
-	unsigned int page_count;
-	unsigned int offset;
-	unsigned int bytesused;
+	struct vb2_buffer vb;
+	struct list_head list;
 	unsigned int frame_offset;
 	u32 modet_active;
-	int mapped;
 };
 
 #define GO7007_RATIO_1_1	0
@@ -178,8 +169,7 @@ struct go7007 {
 	enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
 	spinlock_t spinlock;
 	struct mutex hw_lock;
-	int streaming;
-	int in_use;
+	struct mutex serialize_lock;
 	int audio_enabled;
 	struct v4l2_subdev *sd_video;
 	struct v4l2_subdev *sd_audio;
@@ -226,17 +216,16 @@ struct go7007 {
 	unsigned char active_map[216];
 
 	/* Video streaming */
-	struct go7007_buffer *active_buf;
+	struct mutex queue_lock;
+	struct vb2_queue vidq;
 	enum go7007_parser_state state;
 	int parse_length;
 	u16 modet_word;
 	int seen_frame;
 	u32 next_seq;
-	struct list_head stream;
+	struct list_head vidq_active;
 	wait_queue_head_t frame_waitq;
-	int buf_count;
-	struct go7007_buffer *bufs;
-	struct v4l2_fh *bufs_owner;
+	struct go7007_buffer *active_buf;
 
 	/* Audio streaming */
 	void (*audio_deliver)(struct go7007 *go, u8 *buf, int length);
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 5c7a19e6..c95538c 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -780,7 +780,7 @@ static void go7007_usb_read_video_pipe_complete(struct urb *urb)
 	struct go7007 *go = (struct go7007 *)urb->context;
 	int r, status = urb->status;
 
-	if (!go->streaming) {
+	if (!vb2_is_streaming(&go->vidq)) {
 		wake_up_interruptible(&go->frame_waitq);
 		return;
 	}
@@ -804,7 +804,7 @@ static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
 	struct go7007 *go = (struct go7007 *)urb->context;
 	int r, status = urb->status;
 
-	if (!go->streaming)
+	if (!vb2_is_streaming(&go->vidq))
 		return;
 	if (status) {
 		printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
@@ -1316,12 +1316,17 @@ static void go7007_usb_disconnect(struct usb_interface *intf)
 {
 	struct go7007 *go = to_go7007(usb_get_intfdata(intf));
 
+	mutex_lock(&go->queue_lock);
+	mutex_lock(&go->serialize_lock);
+
 	if (go->audio_enabled)
 		go7007_snd_remove(go);
 
 	go->status = STATUS_SHUTDOWN;
 	v4l2_device_disconnect(&go->v4l2_dev);
 	video_unregister_device(go->video_dev);
+	mutex_unlock(&go->serialize_lock);
+	mutex_unlock(&go->queue_lock);
 
 	v4l2_device_put(&go->v4l2_dev);
 }
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 191af80..46db491 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -35,6 +35,7 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-event.h>
+#include <media/videobuf2-vmalloc.h>
 #include <media/saa7115.h>
 
 #include "go7007.h"
@@ -43,66 +44,6 @@
 #define call_all(dev, o, f, args...) \
 	v4l2_device_call_until_err(dev, 0, o, f, ##args)
 
-static void deactivate_buffer(struct go7007_buffer *gobuf)
-{
-	int i;
-
-	if (gobuf->state != BUF_STATE_IDLE) {
-		list_del(&gobuf->stream);
-		gobuf->state = BUF_STATE_IDLE;
-	}
-	if (gobuf->page_count > 0) {
-		for (i = 0; i < gobuf->page_count; ++i)
-			page_cache_release(gobuf->pages[i]);
-		gobuf->page_count = 0;
-	}
-}
-
-static void abort_queued(struct go7007 *go)
-{
-	struct go7007_buffer *gobuf, *next;
-
-	list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
-		deactivate_buffer(gobuf);
-	}
-}
-
-static int go7007_streamoff(struct go7007 *go)
-{
-	unsigned long flags;
-
-	mutex_lock(&go->hw_lock);
-	if (go->streaming) {
-		go->streaming = 0;
-		go7007_stream_stop(go);
-		spin_lock_irqsave(&go->spinlock, flags);
-		abort_queued(go);
-		spin_unlock_irqrestore(&go->spinlock, flags);
-		go7007_reset_encoder(go);
-	}
-	mutex_unlock(&go->hw_lock);
-	v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
-	v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
-	v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
-	v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
-	return 0;
-}
-
-static int go7007_release(struct file *file)
-{
-	struct go7007 *go = video_drvdata(file);
-
-	if (file->private_data == go->bufs_owner && go->buf_count > 0) {
-		go7007_streamoff(go);
-		go->in_use = 0;
-		kfree(go->bufs);
-		go->bufs = NULL;
-		go->buf_count = 0;
-		go->bufs_owner = NULL;
-	}
-	return v4l2_fh_release(file);
-}
-
 static bool valid_pixelformat(u32 pixelformat)
 {
 	switch (pixelformat) {
@@ -116,15 +57,15 @@ static bool valid_pixelformat(u32 pixelformat)
 	}
 }
 
-static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
+static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
 {
-	u8 *f = page_address(gobuf->pages[0]);
+	u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
 
 	switch (format) {
 	case V4L2_PIX_FMT_MJPEG:
 		return V4L2_BUF_FLAG_KEYFRAME;
 	case V4L2_PIX_FMT_MPEG4:
-		switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
+		switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
 		case 0:
 			return V4L2_BUF_FLAG_KEYFRAME;
 		case 1:
@@ -136,7 +77,7 @@ static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
 		}
 	case V4L2_PIX_FMT_MPEG1:
 	case V4L2_PIX_FMT_MPEG2:
-		switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
+		switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
 		case 1:
 			return V4L2_BUF_FLAG_KEYFRAME;
 		case 2:
@@ -412,7 +353,8 @@ static int vidioc_querycap(struct file *file, void  *priv,
 	strlcpy(cap->card, go->name, sizeof(cap->card));
 	strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
 
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
+				V4L2_CAP_STREAMING;
 
 	if (go->board_info->num_aud_inputs)
 		cap->device_caps |= V4L2_CAP_AUDIO;
@@ -485,293 +427,125 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 {
 	struct go7007 *go = video_drvdata(file);
 
-	if (go->streaming)
+	if (vb2_is_busy(&go->vidq))
 		return -EBUSY;
 
 	return set_capture_size(go, fmt, 0);
 }
 
-static int vidioc_reqbufs(struct file *file, void *priv,
-			  struct v4l2_requestbuffers *req)
+static int go7007_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
+		unsigned int *num_buffers, unsigned int *num_planes,
+		unsigned int sizes[], void *alloc_ctxs[])
 {
-	struct go7007 *go = video_drvdata(file);
-	int retval = -EBUSY;
-	unsigned int count, i;
-
-	if (go->streaming)
-		return retval;
-
-	if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-			req->memory != V4L2_MEMORY_MMAP)
-		return -EINVAL;
-
-	for (i = 0; i < go->buf_count; ++i)
-		if (go->bufs[i].mapped > 0)
-			goto unlock_and_return;
-
-	set_formatting(go);
-	mutex_lock(&go->hw_lock);
-	if (go->in_use > 0 && go->buf_count == 0) {
-		mutex_unlock(&go->hw_lock);
-		goto unlock_and_return;
-	}
+	sizes[0] = GO7007_BUF_SIZE;
+	*num_planes = 1;
 
-	if (go->buf_count > 0)
-		kfree(go->bufs);
-
-	retval = -ENOMEM;
-	count = req->count;
-	if (count > 0) {
-		if (count < 2)
-			count = 2;
-		if (count > 32)
-			count = 32;
-
-		go->bufs = kcalloc(count, sizeof(struct go7007_buffer),
-				     GFP_KERNEL);
-
-		if (!go->bufs) {
-			mutex_unlock(&go->hw_lock);
-			goto unlock_and_return;
-		}
-
-		for (i = 0; i < count; ++i) {
-			go->bufs[i].go = go;
-			go->bufs[i].index = i;
-			go->bufs[i].state = BUF_STATE_IDLE;
-			go->bufs[i].mapped = 0;
-		}
-
-		go->in_use = 1;
-		go->bufs_owner = file->private_data;
-	} else {
-		go->in_use = 0;
-		go->bufs_owner = NULL;
-	}
-
-	go->buf_count = count;
-	mutex_unlock(&go->hw_lock);
-
-	memset(req, 0, sizeof(*req));
-
-	req->count = count;
-	req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	req->memory = V4L2_MEMORY_MMAP;
+	if (*num_buffers < 2)
+		*num_buffers = 2;
 
 	return 0;
-
-unlock_and_return:
-	return retval;
 }
 
-static int vidioc_querybuf(struct file *file, void *priv,
-			   struct v4l2_buffer *buf)
+static void go7007_buf_queue(struct vb2_buffer *vb)
 {
-	struct go7007 *go = video_drvdata(file);
-	int retval = -EINVAL;
-	unsigned int index;
-
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return retval;
-
-	index = buf->index;
-
-	if (index >= go->buf_count)
-		goto unlock_and_return;
-
-	memset(buf, 0, sizeof(*buf));
-	buf->index = index;
-	buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	switch (go->bufs[index].state) {
-	case BUF_STATE_QUEUED:
-		buf->flags = V4L2_BUF_FLAG_QUEUED;
-		break;
-	case BUF_STATE_DONE:
-		buf->flags = V4L2_BUF_FLAG_DONE;
-		break;
-	default:
-		buf->flags = 0;
-	}
-
-	if (go->bufs[index].mapped)
-		buf->flags |= V4L2_BUF_FLAG_MAPPED;
-	buf->memory = V4L2_MEMORY_MMAP;
-	buf->m.offset = index * GO7007_BUF_SIZE;
-	buf->length = GO7007_BUF_SIZE;
-
-	return 0;
-
-unlock_and_return:
-	return retval;
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-	struct go7007 *go = video_drvdata(file);
-	struct go7007_buffer *gobuf;
+	struct vb2_queue *vq = vb->vb2_queue;
+	struct go7007 *go = vb2_get_drv_priv(vq);
+	struct go7007_buffer *go7007_vb =
+		container_of(vb, struct go7007_buffer, vb);
 	unsigned long flags;
-	int retval = -EINVAL;
-	int ret;
-
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-			buf->memory != V4L2_MEMORY_MMAP)
-		return retval;
-
-	if (buf->index >= go->buf_count)
-		goto unlock_and_return;
 
-	gobuf = &go->bufs[buf->index];
-	if (!gobuf->mapped)
-		goto unlock_and_return;
-
-	retval = -EBUSY;
-	if (gobuf->state != BUF_STATE_IDLE)
-		goto unlock_and_return;
-
-	/* offset will be 0 until we really support USERPTR streaming */
-	gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
-	gobuf->bytesused = 0;
-	gobuf->frame_offset = 0;
-	gobuf->modet_active = 0;
-	if (gobuf->offset > 0)
-		gobuf->page_count = GO7007_BUF_PAGES + 1;
-	else
-		gobuf->page_count = GO7007_BUF_PAGES;
-
-	retval = -ENOMEM;
-	down_read(&current->mm->mmap_sem);
-	ret = get_user_pages(current, current->mm,
-			gobuf->user_addr & PAGE_MASK, gobuf->page_count,
-			1, 1, gobuf->pages, NULL);
-	up_read(&current->mm->mmap_sem);
-
-	if (ret != gobuf->page_count) {
-		int i;
-		for (i = 0; i < ret; ++i)
-			page_cache_release(gobuf->pages[i]);
-		gobuf->page_count = 0;
-		goto unlock_and_return;
-	}
-
-	gobuf->state = BUF_STATE_QUEUED;
 	spin_lock_irqsave(&go->spinlock, flags);
-	list_add_tail(&gobuf->stream, &go->stream);
+	list_add_tail(&go7007_vb->list, &go->vidq_active);
 	spin_unlock_irqrestore(&go->spinlock, flags);
+}
 
-	return 0;
+static int go7007_buf_prepare(struct vb2_buffer *vb)
+{
+	struct go7007_buffer *go7007_vb =
+		container_of(vb, struct go7007_buffer, vb);
 
-unlock_and_return:
-	return retval;
+	go7007_vb->modet_active = 0;
+	go7007_vb->frame_offset = 0;
+	vb->v4l2_planes[0].bytesused = 0;
+	return 0;
 }
 
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+static int go7007_buf_finish(struct vb2_buffer *vb)
 {
-	struct go7007 *go = video_drvdata(file);
-	struct go7007_buffer *gobuf;
-	int retval = -EINVAL;
-	unsigned long flags;
-	u32 frame_type_flag;
-	DEFINE_WAIT(wait);
-
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return retval;
-	if (buf->memory != V4L2_MEMORY_MMAP)
-		return retval;
-
-	if (list_empty(&go->stream))
-		goto unlock_and_return;
-	gobuf = list_entry(go->stream.next,
-			struct go7007_buffer, stream);
-
-	retval = -EAGAIN;
-	if (gobuf->state != BUF_STATE_DONE &&
-			!(file->f_flags & O_NONBLOCK)) {
-		for (;;) {
-			prepare_to_wait(&go->frame_waitq, &wait,
-					TASK_INTERRUPTIBLE);
-			if (gobuf->state == BUF_STATE_DONE)
-				break;
-			if (signal_pending(current)) {
-				retval = -ERESTARTSYS;
-				break;
-			}
-			schedule();
-		}
-		finish_wait(&go->frame_waitq, &wait);
-	}
-	if (gobuf->state != BUF_STATE_DONE)
-		goto unlock_and_return;
-
-	spin_lock_irqsave(&go->spinlock, flags);
-	deactivate_buffer(gobuf);
-	spin_unlock_irqrestore(&go->spinlock, flags);
-	frame_type_flag = get_frame_type_flag(gobuf, go->format);
-	gobuf->state = BUF_STATE_IDLE;
-
-	memset(buf, 0, sizeof(*buf));
-	buf->index = gobuf->index;
-	buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	buf->bytesused = gobuf->bytesused;
-	buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
+	struct vb2_queue *vq = vb->vb2_queue;
+	struct go7007 *go = vb2_get_drv_priv(vq);
+	struct go7007_buffer *go7007_vb =
+		container_of(vb, struct go7007_buffer, vb);
+	u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
+	struct v4l2_buffer *buf = &vb->v4l2_buf;
+
+	buf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
+			V4L2_BUF_FLAG_PFRAME);
+	buf->flags |= frame_type_flag;
 	buf->field = V4L2_FIELD_NONE;
-	buf->timestamp = gobuf->timestamp;
-	buf->sequence = gobuf->seq;
-	buf->memory = V4L2_MEMORY_MMAP;
-	buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
-	buf->length = GO7007_BUF_SIZE;
-	buf->reserved = gobuf->modet_active;
-
 	return 0;
-
-unlock_and_return:
-	return retval;
 }
 
-static int vidioc_streamon(struct file *file, void *priv,
-					enum v4l2_buf_type type)
+static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
 {
-	struct go7007 *go = video_drvdata(file);
-	int retval = 0;
-
-	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
+	struct go7007 *go = vb2_get_drv_priv(q);
+	int ret;
 
+	set_formatting(go);
 	mutex_lock(&go->hw_lock);
-
-	if (!go->streaming) {
-		go->streaming = 1;
-		go->next_seq = 0;
-		go->active_buf = NULL;
-		if (go7007_start_encoder(go) < 0)
-			retval = -EIO;
-		else
-			retval = 0;
-	}
+	go->next_seq = 0;
+	go->active_buf = NULL;
+	q->streaming = 1;
+	if (go7007_start_encoder(go) < 0)
+		ret = -EIO;
+	else
+		ret = 0;
 	mutex_unlock(&go->hw_lock);
+	if (ret) {
+		q->streaming = 0;
+		return ret;
+	}
 	call_all(&go->v4l2_dev, video, s_stream, 1);
 	v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
 	v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
 	v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
 	v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
-
-	return retval;
+	return ret;
 }
 
-static int vidioc_streamoff(struct file *file, void *priv,
-					enum v4l2_buf_type type)
+static int go7007_stop_streaming(struct vb2_queue *q)
 {
-	struct go7007 *go = video_drvdata(file);
+	struct go7007 *go = vb2_get_drv_priv(q);
+	unsigned long flags;
 
-	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-	go7007_streamoff(go);
+	q->streaming = 0;
+	go7007_stream_stop(go);
+	mutex_lock(&go->hw_lock);
+	go7007_reset_encoder(go);
+	mutex_unlock(&go->hw_lock);
 	call_all(&go->v4l2_dev, video, s_stream, 0);
 
+	spin_lock_irqsave(&go->spinlock, flags);
+	INIT_LIST_HEAD(&go->vidq_active);
+	spin_unlock_irqrestore(&go->spinlock, flags);
+	v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
+	v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
+	v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
+	v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
 	return 0;
 }
 
+static struct vb2_ops go7007_video_qops = {
+	.queue_setup    = go7007_queue_setup,
+	.buf_queue      = go7007_buf_queue,
+	.buf_prepare    = go7007_buf_prepare,
+	.buf_finish     = go7007_buf_finish,
+	.start_streaming = go7007_start_streaming,
+	.stop_streaming = go7007_stop_streaming,
+	.wait_prepare   = vb2_ops_wait_prepare,
+	.wait_finish    = vb2_ops_wait_finish,
+};
+
 static int vidioc_g_parm(struct file *filp, void *priv,
 		struct v4l2_streamparm *parm)
 {
@@ -895,7 +669,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
 {
 	struct go7007 *go = video_drvdata(file);
 
-	if (go->streaming)
+	if (vb2_is_busy(&go->vidq))
 		return -EBUSY;
 
 	go->std = *std;
@@ -1006,7 +780,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
 
 	if (input >= go->board_info->num_inputs)
 		return -EINVAL;
-	if (go->streaming)
+	if (vb2_is_busy(&go->vidq))
 		return -EBUSY;
 
 	go->input = input;
@@ -1193,95 +967,6 @@ static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *
 	}
 #endif
 
-static ssize_t go7007_read(struct file *file, char __user *data,
-		size_t count, loff_t *ppos)
-{
-	return -EINVAL;
-}
-
-static void go7007_vm_open(struct vm_area_struct *vma)
-{
-	struct go7007_buffer *gobuf = vma->vm_private_data;
-
-	++gobuf->mapped;
-}
-
-static void go7007_vm_close(struct vm_area_struct *vma)
-{
-	struct go7007_buffer *gobuf = vma->vm_private_data;
-	unsigned long flags;
-
-	if (--gobuf->mapped == 0) {
-		spin_lock_irqsave(&gobuf->go->spinlock, flags);
-		deactivate_buffer(gobuf);
-		spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
-	}
-}
-
-/* Copied from videobuf-dma-sg.c */
-static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	struct page *page;
-
-	page = alloc_page(GFP_USER | __GFP_DMA32);
-	if (!page)
-		return VM_FAULT_OOM;
-	clear_user_highpage(page, (unsigned long)vmf->virtual_address);
-	vmf->page = page;
-	return 0;
-}
-
-static struct vm_operations_struct go7007_vm_ops = {
-	.open	= go7007_vm_open,
-	.close	= go7007_vm_close,
-	.fault	= go7007_vm_fault,
-};
-
-static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct go7007 *go = video_drvdata(file);
-	unsigned int index;
-
-	if (go->status != STATUS_ONLINE)
-		return -EIO;
-	if (!(vma->vm_flags & VM_SHARED))
-		return -EINVAL; /* only support VM_SHARED mapping */
-	if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
-		return -EINVAL; /* must map exactly one full buffer */
-	index = vma->vm_pgoff / GO7007_BUF_PAGES;
-	if (index >= go->buf_count)
-		return -EINVAL; /* trying to map beyond requested buffers */
-	if (index * GO7007_BUF_PAGES != vma->vm_pgoff)
-		return -EINVAL; /* offset is not aligned on buffer boundary */
-	if (go->bufs[index].mapped > 0)
-		return -EBUSY;
-	go->bufs[index].mapped = 1;
-	go->bufs[index].user_addr = vma->vm_start;
-	vma->vm_ops = &go7007_vm_ops;
-	vma->vm_flags |= VM_DONTEXPAND;
-	vma->vm_flags &= ~VM_IO;
-	vma->vm_private_data = &go->bufs[index];
-	return 0;
-}
-
-static unsigned int go7007_poll(struct file *file, poll_table *wait)
-{
-	unsigned long req_events = poll_requested_events(wait);
-	struct go7007 *go = video_drvdata(file);
-	struct go7007_buffer *gobuf;
-	unsigned int res = v4l2_ctrl_poll(file, wait);
-
-	if (!(req_events & (POLLIN | POLLRDNORM)))
-		return res;
-	if (list_empty(&go->stream))
-		return POLLERR;
-	gobuf = list_entry(go->stream.next, struct go7007_buffer, stream);
-	poll_wait(file, &go->frame_waitq, wait);
-	if (gobuf->state == BUF_STATE_DONE)
-		return res | POLLIN | POLLRDNORM;
-	return res;
-}
-
 static void go7007_vfl_release(struct video_device *vfd)
 {
 	video_device_release(vfd);
@@ -1290,11 +975,11 @@ static void go7007_vfl_release(struct video_device *vfd)
 static struct v4l2_file_operations go7007_fops = {
 	.owner		= THIS_MODULE,
 	.open		= v4l2_fh_open,
-	.release	= go7007_release,
-	.ioctl		= video_ioctl2,
-	.read		= go7007_read,
-	.mmap		= go7007_mmap,
-	.poll		= go7007_poll,
+	.release	= vb2_fop_release,
+	.unlocked_ioctl	= video_ioctl2,
+	.read		= vb2_fop_read,
+	.mmap		= vb2_fop_mmap,
+	.poll		= vb2_fop_poll,
 };
 
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1303,10 +988,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
-	.vidioc_reqbufs           = vidioc_reqbufs,
-	.vidioc_querybuf          = vidioc_querybuf,
-	.vidioc_qbuf              = vidioc_qbuf,
-	.vidioc_dqbuf             = vidioc_dqbuf,
+	.vidioc_reqbufs           = vb2_ioctl_reqbufs,
+	.vidioc_querybuf          = vb2_ioctl_querybuf,
+	.vidioc_qbuf              = vb2_ioctl_qbuf,
+	.vidioc_dqbuf             = vb2_ioctl_dqbuf,
 	.vidioc_g_std             = vidioc_g_std,
 	.vidioc_s_std             = vidioc_s_std,
 	.vidioc_querystd          = vidioc_querystd,
@@ -1316,8 +1001,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_enumaudio         = vidioc_enumaudio,
 	.vidioc_g_audio           = vidioc_g_audio,
 	.vidioc_s_audio           = vidioc_s_audio,
-	.vidioc_streamon          = vidioc_streamon,
-	.vidioc_streamoff         = vidioc_streamoff,
+	.vidioc_streamon          = vb2_ioctl_streamon,
+	.vidioc_streamoff         = vb2_ioctl_streamoff,
 	.vidioc_g_tuner           = vidioc_g_tuner,
 	.vidioc_s_tuner           = vidioc_s_tuner,
 	.vidioc_g_frequency       = vidioc_g_frequency,
@@ -1379,10 +1064,27 @@ int go7007_v4l2_init(struct go7007 *go)
 {
 	int rv;
 
+	mutex_init(&go->serialize_lock);
+	mutex_init(&go->queue_lock);
+
+	INIT_LIST_HEAD(&go->vidq_active);
+	go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+	go->vidq.ops = &go7007_video_qops;
+	go->vidq.mem_ops = &vb2_vmalloc_memops;
+	go->vidq.drv_priv = go;
+	go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
+	go->vidq.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	go->vidq.lock = &go->queue_lock;
+	rv = vb2_queue_init(&go->vidq);
+	if (rv)
+		return rv;
 	go->video_dev = video_device_alloc();
 	if (go->video_dev == NULL)
 		return -ENOMEM;
 	*go->video_dev = go7007_template;
+	go->video_dev->lock = &go->serialize_lock;
+	go->video_dev->queue = &go->vidq;
 	set_bit(V4L2_FL_USE_FH_PRIO, &go->video_dev->flags);
 	video_set_drvdata(go->video_dev, go);
 	go->video_dev->v4l2_dev = &go->v4l2_dev;
@@ -1436,16 +1138,5 @@ int go7007_v4l2_init(struct go7007 *go)
 
 void go7007_v4l2_remove(struct go7007 *go)
 {
-	unsigned long flags;
-
-	mutex_lock(&go->hw_lock);
-	if (go->streaming) {
-		go->streaming = 0;
-		go7007_stream_stop(go);
-		spin_lock_irqsave(&go->spinlock, flags);
-		abort_queued(go);
-		spin_unlock_irqrestore(&go->spinlock, flags);
-	}
-	mutex_unlock(&go->hw_lock);
 	v4l2_ctrl_handler_free(&go->hdl);
 }
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index 4c73945..fa9de3c 100644
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
@@ -236,7 +236,7 @@ static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
 	struct go7007 *go = video_get_drvdata(dev->empress_dev);
 	struct saa7134_go7007 *saa = go->hpi_context;
 
-	if (!go->streaming)
+	if (!vb2_is_streaming(&go->vidq))
 		return;
 	if (0 != (status & 0x000f0000))
 		printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n",
-- 
1.7.10.4


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

* [REVIEW PATCH 35/42] go7007: embed struct video_device
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (32 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 34/42] go7007: convert to core locking and vb2 Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 36/42] go7007: remove cropping functions Hans Verkuil
                     ` (7 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Do not allocate it, but just embed in the go7007 struct.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-driver.c  |    1 -
 drivers/staging/media/go7007/go7007-priv.h    |    2 +-
 drivers/staging/media/go7007/go7007-usb.c     |    2 +-
 drivers/staging/media/go7007/go7007-v4l2.c    |   56 ++++++++++---------------
 drivers/staging/media/go7007/saa7134-go7007.c |    2 +-
 5 files changed, 26 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index 075de4d..0fd3f10 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -639,7 +639,6 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 	mutex_init(&go->hw_lock);
 	init_waitqueue_head(&go->frame_waitq);
 	spin_lock_init(&go->spinlock);
-	go->video_dev = NULL;
 	go->status = STATUS_INIT;
 	memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
 	go->i2c_adapter_online = 0;
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index 30148eb..0914fa3 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -156,7 +156,7 @@ struct go7007 {
 	int tuner_type;
 	int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
 	char name[64];
-	struct video_device *video_dev;
+	struct video_device vdev;
 	void *boot_fw;
 	unsigned boot_fw_len;
 	struct v4l2_device v4l2_dev;
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index c95538c..2a1cda2 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -1324,7 +1324,7 @@ static void go7007_usb_disconnect(struct usb_interface *intf)
 
 	go->status = STATUS_SHUTDOWN;
 	v4l2_device_disconnect(&go->v4l2_dev);
-	video_unregister_device(go->video_dev);
+	video_unregister_device(&go->vdev);
 	mutex_unlock(&go->serialize_lock);
 	mutex_unlock(&go->queue_lock);
 
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 46db491..2e5bc02 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -967,11 +967,6 @@ static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *
 	}
 #endif
 
-static void go7007_vfl_release(struct video_device *vfd)
-{
-	video_device_release(vfd);
-}
-
 static struct v4l2_file_operations go7007_fops = {
 	.owner		= THIS_MODULE,
 	.open		= v4l2_fh_open,
@@ -1022,7 +1017,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 static struct video_device go7007_template = {
 	.name		= "go7007",
 	.fops		= &go7007_fops,
-	.release	= go7007_vfl_release,
+	.release	= video_device_release_empty,
 	.ioctl_ops	= &video_ioctl_ops,
 	.tvnorms	= V4L2_STD_ALL,
 };
@@ -1062,6 +1057,7 @@ int go7007_v4l2_ctrl_init(struct go7007 *go)
 
 int go7007_v4l2_init(struct go7007 *go)
 {
+	struct video_device *vdev = &go->vdev;
 	int rv;
 
 	mutex_init(&go->serialize_lock);
@@ -1079,22 +1075,19 @@ int go7007_v4l2_init(struct go7007 *go)
 	rv = vb2_queue_init(&go->vidq);
 	if (rv)
 		return rv;
-	go->video_dev = video_device_alloc();
-	if (go->video_dev == NULL)
-		return -ENOMEM;
-	*go->video_dev = go7007_template;
-	go->video_dev->lock = &go->serialize_lock;
-	go->video_dev->queue = &go->vidq;
-	set_bit(V4L2_FL_USE_FH_PRIO, &go->video_dev->flags);
-	video_set_drvdata(go->video_dev, go);
-	go->video_dev->v4l2_dev = &go->v4l2_dev;
+	*vdev = go7007_template;
+	vdev->lock = &go->serialize_lock;
+	vdev->queue = &go->vidq;
+	set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags);
+	video_set_drvdata(vdev, go);
+	vdev->v4l2_dev = &go->v4l2_dev;
 	if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_QUERYSTD);
+		v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
 	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_FREQUENCY);
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_G_FREQUENCY);
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_TUNER);
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_G_TUNER);
+		v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
+		v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
+		v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
+		v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
 	} else {
 		struct v4l2_frequency f = {
 			.type = V4L2_TUNER_ANALOG_TV,
@@ -1104,16 +1097,16 @@ int go7007_v4l2_init(struct go7007 *go)
 		call_all(&go->v4l2_dev, tuner, s_frequency, &f);
 	}
 	if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_G_STD);
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_STD);
-		go->video_dev->tvnorms = 0;
+		v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
+		v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
+		vdev->tvnorms = 0;
 	}
 	if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_ENUM_FRAMESIZES);
+		v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
 	if (go->board_info->num_aud_inputs == 0) {
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_G_AUDIO);
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_S_AUDIO);
-		v4l2_disable_ioctl(go->video_dev, VIDIOC_ENUMAUDIO);
+		v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
+		v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
+		v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
 	}
 	/* Setup correct crystal frequency on this board */
 	if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
@@ -1124,14 +1117,11 @@ int go7007_v4l2_init(struct go7007 *go)
 	go7007_s_input(go);
 	if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
 		go7007_s_std(go);
-	rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
-	if (rv < 0) {
-		video_device_release(go->video_dev);
-		go->video_dev = NULL;
+	rv = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+	if (rv < 0)
 		return rv;
-	}
 	dev_info(go->dev, "registered device %s [v4l2]\n",
-		 video_device_node_name(go->video_dev));
+		 video_device_node_name(vdev));
 
 	return 0;
 }
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index fa9de3c..752f1bd 100644
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
@@ -471,7 +471,7 @@ static int saa7134_go7007_init(struct saa7134_dev *dev)
 	 * V4L2 and ALSA interfaces */
 	if (go7007_register_encoder(go, go->board_info->num_i2c_devs) < 0)
 		goto initfail;
-	dev->empress_dev = go->video_dev;
+	dev->empress_dev = &go->vdev;
 	video_set_drvdata(dev->empress_dev, go);
 
 	go->status = STATUS_ONLINE;
-- 
1.7.10.4


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

* [REVIEW PATCH 36/42] go7007: remove cropping functions
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (33 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 35/42] go7007: embed struct video_device Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 37/42] saa7134-go7007: add support for this combination Hans Verkuil
                     ` (6 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Remove these dummy cropping functions: cropping was never implemented.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-v4l2.c |   92 ----------------------------
 1 file changed, 92 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 2e5bc02..24d93b4 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -842,95 +842,6 @@ static int vidioc_log_status(struct file *file, void *priv)
 	return call_all(&go->v4l2_dev, core, log_status);
 }
 
-static int vidioc_cropcap(struct file *file, void *priv,
-					struct v4l2_cropcap *cropcap)
-{
-	struct go7007 *go = video_drvdata(file);
-
-	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	/* These specify the raw input of the sensor */
-	switch (go->standard) {
-	case GO7007_STD_NTSC:
-		cropcap->bounds.top = 0;
-		cropcap->bounds.left = 0;
-		cropcap->bounds.width = 720;
-		cropcap->bounds.height = 480;
-		cropcap->defrect.top = 0;
-		cropcap->defrect.left = 0;
-		cropcap->defrect.width = 720;
-		cropcap->defrect.height = 480;
-		break;
-	case GO7007_STD_PAL:
-		cropcap->bounds.top = 0;
-		cropcap->bounds.left = 0;
-		cropcap->bounds.width = 720;
-		cropcap->bounds.height = 576;
-		cropcap->defrect.top = 0;
-		cropcap->defrect.left = 0;
-		cropcap->defrect.width = 720;
-		cropcap->defrect.height = 576;
-		break;
-	case GO7007_STD_OTHER:
-		cropcap->bounds.top = 0;
-		cropcap->bounds.left = 0;
-		cropcap->bounds.width = go->board_info->sensor_width;
-		cropcap->bounds.height = go->board_info->sensor_height;
-		cropcap->defrect.top = 0;
-		cropcap->defrect.left = 0;
-		cropcap->defrect.width = go->board_info->sensor_width;
-		cropcap->defrect.height = go->board_info->sensor_height;
-		break;
-	}
-
-	return 0;
-}
-
-static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
-{
-	struct go7007 *go = video_drvdata(file);
-
-	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	/* These specify the raw input of the sensor */
-	switch (go->standard) {
-	case GO7007_STD_NTSC:
-		crop->c.top = 0;
-		crop->c.left = 0;
-		crop->c.width = 720;
-		crop->c.height = 480;
-		break;
-	case GO7007_STD_PAL:
-		crop->c.top = 0;
-		crop->c.left = 0;
-		crop->c.width = 720;
-		crop->c.height = 576;
-		break;
-	case GO7007_STD_OTHER:
-		crop->c.top = 0;
-		crop->c.left = 0;
-		crop->c.width = go->board_info->sensor_width;
-		crop->c.height = go->board_info->sensor_height;
-		break;
-	}
-
-	return 0;
-}
-
-/* FIXME: vidioc_s_crop is not really implemented!!!
- */
-static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop)
-{
-	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	return 0;
-}
-
 /* FIXME:
 	Those ioctls are private, and not needed, since several standard
 	extended controls already provide streaming control.
@@ -1006,9 +917,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_s_parm            = vidioc_s_parm,
 	.vidioc_enum_framesizes   = vidioc_enum_framesizes,
 	.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
-	.vidioc_cropcap           = vidioc_cropcap,
-	.vidioc_g_crop            = vidioc_g_crop,
-	.vidioc_s_crop            = vidioc_s_crop,
 	.vidioc_log_status        = vidioc_log_status,
 	.vidioc_subscribe_event   = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-- 
1.7.10.4


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

* [REVIEW PATCH 37/42] saa7134-go7007: add support for this combination.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (34 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 36/42] go7007: remove cropping functions Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 38/42] s2250: add comment describing the hardware Hans Verkuil
                     ` (5 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

From: Pete Eberlein <pete@sensoray.com>

Add support for the Sensoray model 614 board, which is a saa7134
with a go7007 MPEG encoder.

Signed-off-by: Pete Eberlein <pete@sensoray.com>
[hans.verkuil@cisco.com: updated to make it merge correctly]
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/pci/saa7134/saa7134-cards.c     |   29 ++++++
 drivers/media/pci/saa7134/saa7134-core.c      |   10 ++-
 drivers/media/pci/saa7134/saa7134.h           |    5 ++
 drivers/staging/media/go7007/Makefile         |    4 +-
 drivers/staging/media/go7007/saa7134-go7007.c |  117 +++++++++++++++----------
 5 files changed, 115 insertions(+), 50 deletions(-)

diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c
index dc68cf1..9a53794 100644
--- a/drivers/media/pci/saa7134/saa7134-cards.c
+++ b/drivers/media/pci/saa7134/saa7134-cards.c
@@ -5790,6 +5790,29 @@ struct saa7134_board saa7134_boards[] = {
 			.gpio = 0x6010000,
 		} },
 	},
+	[SAA7134_BOARD_WIS_VOYAGER] = {
+		.name           = "WIS Voyager or compatible",
+		.audio_clock    = 0x00200000,
+		.tuner_type	= TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.mpeg		= SAA7134_MPEG_GO7007,
+		.inputs		= { {
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE2,
+		}, {
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_svideo,
+			.vmux = 6,
+		.amux = LINE1,
+		} },
+	},
 
 };
 
@@ -7037,6 +7060,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.subdevice    = 0x0911,
 		.driver_data  = SAA7134_BOARD_SENSORAY811_911,
 	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x1905, /* WIS */
+		.subdevice    = 0x7007,
+		.driver_data  = SAA7134_BOARD_WIS_VOYAGER,
+	}, {
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c
index 8fd24e7..0a849ea 100644
--- a/drivers/media/pci/saa7134/saa7134-core.c
+++ b/drivers/media/pci/saa7134/saa7134-core.c
@@ -156,6 +156,8 @@ static void request_module_async(struct work_struct *work){
 		request_module("saa7134-empress");
 	if (card_is_dvb(dev))
 		request_module("saa7134-dvb");
+	if (card_is_go7007(dev))
+		request_module("saa7134-go7007");
 	if (alsa) {
 		if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130)
 			request_module("saa7134-alsa");
@@ -557,8 +559,12 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
 			saa7134_irq_vbi_done(dev,status);
 
 		if ((report & SAA7134_IRQ_REPORT_DONE_RA2) &&
-		    card_has_mpeg(dev))
-			saa7134_irq_ts_done(dev,status);
+		    card_has_mpeg(dev)) {
+			if (dev->mops->irq_ts_done != NULL)
+				dev->mops->irq_ts_done(dev, status);
+			else
+				saa7134_irq_ts_done(dev, status);
+		}
 
 		if (report & SAA7134_IRQ_REPORT_GPIO16) {
 			switch (dev->has_remote) {
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 71eefef..e337e6c 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -334,6 +334,7 @@ struct saa7134_card_ir {
 #define SAA7134_BOARD_KWORLD_PC150U         189
 #define SAA7134_BOARD_ASUSTeK_PS3_100      190
 #define SAA7134_BOARD_HAWELL_HW_9004V1      191
+#define SAA7134_BOARD_WIS_VOYAGER           192
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
@@ -364,6 +365,7 @@ enum saa7134_mpeg_type {
 	SAA7134_MPEG_UNUSED,
 	SAA7134_MPEG_EMPRESS,
 	SAA7134_MPEG_DVB,
+	SAA7134_MPEG_GO7007,
 };
 
 enum saa7134_mpeg_ts_type {
@@ -403,6 +405,7 @@ struct saa7134_board {
 #define card_has_radio(dev)   (NULL != saa7134_boards[dev->board].radio.name)
 #define card_is_empress(dev)  (SAA7134_MPEG_EMPRESS == saa7134_boards[dev->board].mpeg)
 #define card_is_dvb(dev)      (SAA7134_MPEG_DVB     == saa7134_boards[dev->board].mpeg)
+#define card_is_go7007(dev)   (SAA7134_MPEG_GO7007  == saa7134_boards[dev->board].mpeg)
 #define card_has_mpeg(dev)    (SAA7134_MPEG_UNUSED  != saa7134_boards[dev->board].mpeg)
 #define card(dev)             (saa7134_boards[dev->board])
 #define card_in(dev,n)        (saa7134_boards[dev->board].inputs[n])
@@ -535,6 +538,8 @@ struct saa7134_mpeg_ops {
 	int                        (*init)(struct saa7134_dev *dev);
 	int                        (*fini)(struct saa7134_dev *dev);
 	void                       (*signal_change)(struct saa7134_dev *dev);
+	void                       (*irq_ts_done)(struct saa7134_dev *dev,
+						  unsigned long status);
 };
 
 /* global device status */
diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
index f9c8e0f..7885c21 100644
--- a/drivers/staging/media/go7007/Makefile
+++ b/drivers/staging/media/go7007/Makefile
@@ -8,8 +8,8 @@ go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
 s2250-y := s2250-board.o
 
 # Uncomment when the saa7134 patches get into upstream
-#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
-#ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
+obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
+ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134
 
 # S2250 needs cypress ezusb loader from dvb-usb-v2
 ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb-v2
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index 752f1bd..f51f42e 100644
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
@@ -28,12 +28,15 @@
 #include <linux/i2c.h>
 #include <asm/byteorder.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
 
-#include "saa7134-reg.h"
 #include "saa7134.h"
+#include "saa7134-reg.h"
+#include "go7007.h"
 #include "go7007-priv.h"
 
-#define GO7007_HPI_DEBUG
+/*#define GO7007_HPI_DEBUG*/
 
 enum hpi_address {
 	HPI_ADDR_VIDEO_BUFFER = 0xe4,
@@ -57,6 +60,7 @@ enum gpio_command {
 };
 
 struct saa7134_go7007 {
+	struct v4l2_subdev sd;
 	struct saa7134_dev *dev;
 	u8 *top;
 	u8 *bottom;
@@ -64,6 +68,11 @@ struct saa7134_go7007 {
 	dma_addr_t bottom_dma;
 };
 
+static inline struct saa7134_go7007 *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct saa7134_go7007, sd);
+}
+
 static struct go7007_board_info board_voyager = {
 	.firmware	 = "go7007tv.bin",
 	.flags		 = 0,
@@ -84,7 +93,6 @@ static struct go7007_board_info board_voyager = {
 		},
 	},
 };
-MODULE_FIRMWARE("go7007tv.bin");
 
 /********************* Driver for GPIO HPI interface *********************/
 
@@ -380,47 +388,6 @@ static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
 	return 0;
 }
 
-static int saa7134_go7007_send_command(struct go7007 *go, unsigned int cmd,
-					void *arg)
-{
-	struct saa7134_go7007 *saa = go->hpi_context;
-	struct saa7134_dev *dev = saa->dev;
-
-	switch (cmd) {
-	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *std = arg;
-		return saa7134_s_std_internal(dev, NULL, std);
-	}
-	case VIDIOC_G_STD:
-	{
-		v4l2_std_id *std = arg;
-		*std = dev->tvnorm->id;
-		return 0;
-	}
-	case VIDIOC_QUERYCTRL:
-	{
-		struct v4l2_queryctrl *ctrl = arg;
-		if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER)
-			return saa7134_queryctrl(NULL, NULL, ctrl);
-	}
-	case VIDIOC_G_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-		if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER)
-			return saa7134_g_ctrl_internal(dev, NULL, ctrl);
-	}
-	case VIDIOC_S_CTRL:
-	{
-		struct v4l2_control *ctrl = arg;
-		if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER)
-			return saa7134_s_ctrl_internal(dev, NULL, ctrl);
-	}
-	}
-	return -EINVAL;
-
-}
-
 static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
 	.interface_reset	= saa7134_go7007_interface_reset,
 	.write_interrupt	= saa7134_go7007_write_interrupt,
@@ -428,15 +395,62 @@ static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
 	.stream_start		= saa7134_go7007_stream_start,
 	.stream_stop		= saa7134_go7007_stream_stop,
 	.send_firmware		= saa7134_go7007_send_firmware,
-	.send_command		= saa7134_go7007_send_command,
 };
 
+/* --------------------------------------------------------------------------*/
+
+static int saa7134_go7007_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+	struct saa7134_go7007 *saa = to_state(sd);
+	struct saa7134_dev *dev = saa->dev;
+
+	return saa7134_s_std_internal(dev, NULL, &norm);
+}
+
+static int saa7134_go7007_queryctrl(struct v4l2_subdev *sd,
+				    struct v4l2_queryctrl *query)
+{
+	return saa7134_queryctrl(NULL, NULL, query);
+}
+static int saa7134_go7007_s_ctrl(struct v4l2_subdev *sd,
+				 struct v4l2_control *ctrl)
+{
+	struct saa7134_go7007 *saa = to_state(sd);
+	struct saa7134_dev *dev = saa->dev;
+	return saa7134_s_ctrl_internal(dev, NULL, ctrl);
+}
+
+static int saa7134_go7007_g_ctrl(struct v4l2_subdev *sd,
+				 struct v4l2_control *ctrl)
+{
+	struct saa7134_go7007 *saa = to_state(sd);
+	struct saa7134_dev *dev = saa->dev;
+	return saa7134_g_ctrl_internal(dev, NULL, ctrl);
+}
+
+/* --------------------------------------------------------------------------*/
+
+static const struct v4l2_subdev_core_ops saa7134_go7007_core_ops = {
+	.g_ctrl = saa7134_go7007_g_ctrl,
+	.s_ctrl = saa7134_go7007_s_ctrl,
+	.queryctrl = saa7134_go7007_queryctrl,
+	.s_std = saa7134_go7007_s_std,
+};
+
+static const struct v4l2_subdev_ops saa7134_go7007_sd_ops = {
+	.core = &saa7134_go7007_core_ops,
+};
+
+/* --------------------------------------------------------------------------*/
+
+
 /********************* Add/remove functions *********************/
 
 static int saa7134_go7007_init(struct saa7134_dev *dev)
 {
 	struct go7007 *go;
 	struct saa7134_go7007 *saa;
+	struct v4l2_subdev *sd;
 
 	printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n");
 
@@ -444,6 +458,12 @@ static int saa7134_go7007_init(struct saa7134_dev *dev)
 	if (saa == NULL)
 		return -ENOMEM;
 
+	/* Init the subdevice interface */
+	sd = &saa->sd;
+	v4l2_subdev_init(sd, &saa7134_go7007_sd_ops);
+	v4l2_set_subdevdata(sd, saa);
+	strncpy(sd->name, "saa7134-go7007", sizeof(sd->name));
+
 	/* Allocate a couple pages for receiving the compressed stream */
 	saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
 	if (!saa->top)
@@ -471,8 +491,12 @@ static int saa7134_go7007_init(struct saa7134_dev *dev)
 	 * V4L2 and ALSA interfaces */
 	if (go7007_register_encoder(go, go->board_info->num_i2c_devs) < 0)
 		goto initfail;
+
+	/* Register the subdevice interface with the go7007 device */
+	if (v4l2_device_register_subdev(&go->v4l2_dev, sd) < 0)
+		printk(KERN_INFO "saa7134-go7007: register subdev failed\n");
+
 	dev->empress_dev = &go->vdev;
-	video_set_drvdata(dev->empress_dev, go);
 
 	go->status = STATUS_ONLINE;
 	return 0;
@@ -506,6 +530,7 @@ static int saa7134_go7007_fini(struct saa7134_dev *dev)
 	go->status = STATUS_SHUTDOWN;
 	free_page((unsigned long)saa->top);
 	free_page((unsigned long)saa->bottom);
+	v4l2_device_unregister_subdev(&saa->sd);
 	kfree(saa);
 	video_unregister_device(&go->vdev);
 
-- 
1.7.10.4


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

* [REVIEW PATCH 38/42] s2250: add comment describing the hardware.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (35 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 37/42] saa7134-go7007: add support for this combination Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 39/42] go7007-loader: renamed from s2250-loader Hans Verkuil
                     ` (4 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/s2250-board.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c
index cb36427..beaa98b 100644
--- a/drivers/staging/media/go7007/s2250-board.c
+++ b/drivers/staging/media/go7007/s2250-board.c
@@ -29,6 +29,13 @@
 MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
 MODULE_LICENSE("GPL v2");
 
+/*
+ * Note: this board has two i2c devices: a vpx3226f and a tlv320aic23b.
+ * Due to the unusual way these are accessed on this device we do not
+ * reuse the i2c drivers, but instead they are implemented in this
+ * driver. It would be nice to improve on this, though.
+ */
+
 #define TLV320_ADDRESS      0x34
 #define VPX322_ADDR_ANALOGCONTROL1	0x02
 #define VPX322_ADDR_BRIGHTNESS0		0x0127
-- 
1.7.10.4


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

* [REVIEW PATCH 39/42] go7007-loader: renamed from s2250-loader
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (36 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 38/42] s2250: add comment describing the hardware Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 40/42] go7007-loader: add support for the other devices and move fw files Hans Verkuil
                     ` (3 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

All s2250 names are renamed to go7007. This will be the generic go7007
firmware loader for any go7007 device, not just for the s2250/1.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/Kconfig         |   24 ++--
 drivers/staging/media/go7007/Makefile        |    7 +-
 drivers/staging/media/go7007/go7007-loader.c |  169 +++++++++++++++++++++++++
 drivers/staging/media/go7007/s2250-loader.c  |  170 --------------------------
 drivers/staging/media/go7007/s2250-loader.h  |   24 ----
 5 files changed, 189 insertions(+), 205 deletions(-)
 create mode 100644 drivers/staging/media/go7007/go7007-loader.c
 delete mode 100644 drivers/staging/media/go7007/s2250-loader.c
 delete mode 100644 drivers/staging/media/go7007/s2250-loader.h

diff --git a/drivers/staging/media/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig
index 46cb7bf..957277c 100644
--- a/drivers/staging/media/go7007/Kconfig
+++ b/drivers/staging/media/go7007/Kconfig
@@ -1,13 +1,10 @@
 config VIDEO_GO7007
 	tristate "WIS GO7007 MPEG encoder support"
-	depends on VIDEO_DEV && PCI && I2C
+	depends on VIDEO_DEV && I2C
 	depends on SND
 	select VIDEOBUF2_VMALLOC
-	depends on RC_CORE
 	select VIDEO_TUNER
-	select VIDEO_TVEEPROM
 	select SND_PCM
-	select CRC32
 	select VIDEO_SONY_BTF_MPX if MEDIA_SUBDRV_AUTOSELECT
 	select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
 	select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT
@@ -20,7 +17,7 @@ config VIDEO_GO7007
 	  encoder chip.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called go7007
+	  module will be called go7007.
 
 config VIDEO_GO7007_USB
 	tristate "WIS GO7007 USB support"
@@ -31,14 +28,25 @@ config VIDEO_GO7007_USB
 	  encoder chip over USB.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called go7007-usb
+	  module will be called go7007-usb.
+
+config VIDEO_GO7007_LOADER
+	tristate "WIS GO7007 Loader support"
+	depends on VIDEO_GO7007 && DVB_USB
+	default y
+	---help---
+	  This is a go7007 firmware loader driver for the WIS GO7007
+	  MPEG encoder chip over USB.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called go7007-loader.
 
 config VIDEO_GO7007_USB_S2250_BOARD
 	tristate "Sensoray 2250/2251 support"
-	depends on VIDEO_GO7007_USB && DVB_USB
+	depends on VIDEO_GO7007_USB && USB
 	default N
 	---help---
 	  This is a video4linux driver for the Sensoray 2250/2251 device.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called s2250
+	  module will be called s2250.
diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
index 7885c21..e94ab0d 100644
--- a/drivers/staging/media/go7007/Makefile
+++ b/drivers/staging/media/go7007/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_VIDEO_GO7007) += go7007.o
 obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
-obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o s2250-loader.o
+obj-$(CONFIG_VIDEO_GO7007_LOADER) += go7007-loader.o
+obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o
 
 go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
 		snd-go7007.o
@@ -11,8 +12,8 @@ s2250-y := s2250-board.o
 obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
 ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134
 
-# S2250 needs cypress ezusb loader from dvb-usb-v2
-ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb-v2
+# go7007-loader needs cypress ezusb loader from dvb-usb-v2
+ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/usb/dvb-usb-v2
 
 ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/dvb-core
diff --git a/drivers/staging/media/go7007/go7007-loader.c b/drivers/staging/media/go7007/go7007-loader.c
new file mode 100644
index 0000000..730a4f8
--- /dev/null
+++ b/drivers/staging/media/go7007/go7007-loader.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2008 Sensoray Company Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <cypress_firmware.h>
+
+#define S2250_LOADER_FIRMWARE	"s2250_loader.fw"
+#define S2250_FIRMWARE		"2250.fw"
+
+typedef struct device_extension_s {
+    struct kref     kref;
+    int minor;
+    struct usb_device *usbdev;
+} device_extension_t, *pdevice_extension_t;
+
+#define USB_go7007_loader_MAJOR 240
+#define USB_go7007_loader_MINOR_BASE 0
+#define MAX_DEVICES 256
+
+static pdevice_extension_t go7007_dev_table[MAX_DEVICES];
+static DEFINE_MUTEX(go7007_dev_table_mutex);
+
+#define to_go7007_loader_dev_common(d) container_of(d, device_extension_t, kref)
+static void go7007_loader_delete(struct kref *kref)
+{
+	pdevice_extension_t s = to_go7007_loader_dev_common(kref);
+	go7007_dev_table[s->minor] = NULL;
+	kfree(s);
+}
+
+static int go7007_loader_probe(struct usb_interface *interface,
+				const struct usb_device_id *id)
+{
+	struct usb_device *usbdev;
+	int minor, ret;
+	pdevice_extension_t s = NULL;
+	const struct firmware *fw;
+
+	usbdev = usb_get_dev(interface_to_usbdev(interface));
+	if (!usbdev) {
+		dev_err(&interface->dev, "Enter go7007_loader_probe failed\n");
+		return -1;
+	}
+	dev_info(&interface->dev, "vendor id 0x%x, device id 0x%x devnum:%d\n",
+		 usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
+		 usbdev->devnum);
+
+	if (usbdev->descriptor.bNumConfigurations != 1) {
+		dev_err(&interface->dev, "can't handle multiple config\n");
+		return -1;
+	}
+	mutex_lock(&go7007_dev_table_mutex);
+
+	for (minor = 0; minor < MAX_DEVICES; minor++) {
+		if (go7007_dev_table[minor] == NULL)
+			break;
+	}
+
+	if (minor < 0 || minor >= MAX_DEVICES) {
+		dev_err(&interface->dev, "Invalid minor: %d\n", minor);
+		goto failed;
+	}
+
+	/* Allocate dev data structure */
+	s = kmalloc(sizeof(device_extension_t), GFP_KERNEL);
+	if (s == NULL)
+		goto failed;
+
+	go7007_dev_table[minor] = s;
+
+	dev_info(&interface->dev,
+		 "Device %d on Bus %d Minor %d\n",
+		 usbdev->devnum, usbdev->bus->busnum, minor);
+
+	memset(s, 0, sizeof(device_extension_t));
+	s->usbdev = usbdev;
+	dev_info(&interface->dev, "loading go7007-loader\n");
+
+	kref_init(&(s->kref));
+
+	mutex_unlock(&go7007_dev_table_mutex);
+
+	if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
+		dev_err(&interface->dev,
+			"unable to load firmware from file \"%s\"\n",
+			S2250_LOADER_FIRMWARE);
+		goto failed2;
+	}
+	ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
+	release_firmware(fw);
+	if (0 != ret) {
+		dev_err(&interface->dev, "loader download failed\n");
+		goto failed2;
+	}
+
+	if (request_firmware(&fw, S2250_FIRMWARE, &usbdev->dev)) {
+		dev_err(&interface->dev,
+			"unable to load firmware from file \"%s\"\n",
+			S2250_FIRMWARE);
+		goto failed2;
+	}
+	ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
+	release_firmware(fw);
+	if (0 != ret) {
+		dev_err(&interface->dev, "firmware download failed\n");
+		goto failed2;
+	}
+
+	usb_set_intfdata(interface, s);
+	return 0;
+
+failed:
+	mutex_unlock(&go7007_dev_table_mutex);
+failed2:
+	if (s)
+		kref_put(&(s->kref), go7007_loader_delete);
+
+	dev_err(&interface->dev, "probe failed\n");
+	return -1;
+}
+
+static void go7007_loader_disconnect(struct usb_interface *interface)
+{
+	pdevice_extension_t s;
+	dev_info(&interface->dev, "disconnect\n");
+	s = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+	kref_put(&(s->kref), go7007_loader_delete);
+}
+
+static const struct usb_device_id go7007_loader_ids[] = {
+	{USB_DEVICE(0x1943, 0xa250)},
+	{}                          /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, go7007_loader_ids);
+
+static struct usb_driver go7007_loader_driver = {
+	.name		= "go7007-loader",
+	.probe		= go7007_loader_probe,
+	.disconnect	= go7007_loader_disconnect,
+	.id_table	= go7007_loader_ids,
+};
+
+module_usb_driver(go7007_loader_driver);
+
+MODULE_AUTHOR("");
+MODULE_DESCRIPTION("firmware loader for go7007 USB devices");
+MODULE_LICENSE("GPL v2");
+MODULE_FIRMWARE(S2250_LOADER_FIRMWARE);
+MODULE_FIRMWARE(S2250_FIRMWARE);
diff --git a/drivers/staging/media/go7007/s2250-loader.c b/drivers/staging/media/go7007/s2250-loader.c
deleted file mode 100644
index 6453ec0..0000000
--- a/drivers/staging/media/go7007/s2250-loader.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2008 Sensoray Company Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <cypress_firmware.h>
-
-#define S2250_LOADER_FIRMWARE	"s2250_loader.fw"
-#define S2250_FIRMWARE		"s2250.fw"
-
-typedef struct device_extension_s {
-    struct kref     kref;
-    int minor;
-    struct usb_device *usbdev;
-} device_extension_t, *pdevice_extension_t;
-
-#define USB_s2250loader_MAJOR 240
-#define USB_s2250loader_MINOR_BASE 0
-#define MAX_DEVICES 256
-
-static pdevice_extension_t s2250_dev_table[MAX_DEVICES];
-static DEFINE_MUTEX(s2250_dev_table_mutex);
-
-#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref)
-static void s2250loader_delete(struct kref *kref)
-{
-	pdevice_extension_t s = to_s2250loader_dev_common(kref);
-	s2250_dev_table[s->minor] = NULL;
-	kfree(s);
-}
-
-static int s2250loader_probe(struct usb_interface *interface,
-				const struct usb_device_id *id)
-{
-	struct usb_device *usbdev;
-	int minor, ret;
-	pdevice_extension_t s = NULL;
-	const struct firmware *fw;
-
-	usbdev = usb_get_dev(interface_to_usbdev(interface));
-	if (!usbdev) {
-		dev_err(&interface->dev, "Enter s2250loader_probe failed\n");
-		return -1;
-	}
-	dev_info(&interface->dev, "Enter s2250loader_probe 2.6 kernel\n");
-	dev_info(&interface->dev, "vendor id 0x%x, device id 0x%x devnum:%d\n",
-		 usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
-		 usbdev->devnum);
-
-	if (usbdev->descriptor.bNumConfigurations != 1) {
-		dev_err(&interface->dev, "can't handle multiple config\n");
-		return -1;
-	}
-	mutex_lock(&s2250_dev_table_mutex);
-
-	for (minor = 0; minor < MAX_DEVICES; minor++) {
-		if (s2250_dev_table[minor] == NULL)
-			break;
-	}
-
-	if (minor < 0 || minor >= MAX_DEVICES) {
-		dev_err(&interface->dev, "Invalid minor: %d\n", minor);
-		goto failed;
-	}
-
-	/* Allocate dev data structure */
-	s = kmalloc(sizeof(device_extension_t), GFP_KERNEL);
-	if (s == NULL)
-		goto failed;
-
-	s2250_dev_table[minor] = s;
-
-	dev_info(&interface->dev,
-		 "s2250loader_probe: Device %d on Bus %d Minor %d\n",
-		 usbdev->devnum, usbdev->bus->busnum, minor);
-
-	memset(s, 0, sizeof(device_extension_t));
-	s->usbdev = usbdev;
-	dev_info(&interface->dev, "loading 2250 loader\n");
-
-	kref_init(&(s->kref));
-
-	mutex_unlock(&s2250_dev_table_mutex);
-
-	if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
-		dev_err(&interface->dev,
-			"s2250: unable to load firmware from file \"%s\"\n",
-			S2250_LOADER_FIRMWARE);
-		goto failed2;
-	}
-	ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
-	release_firmware(fw);
-	if (0 != ret) {
-		dev_err(&interface->dev, "loader download failed\n");
-		goto failed2;
-	}
-
-	if (request_firmware(&fw, S2250_FIRMWARE, &usbdev->dev)) {
-		dev_err(&interface->dev,
-			"s2250: unable to load firmware from file \"%s\"\n",
-			S2250_FIRMWARE);
-		goto failed2;
-	}
-	ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
-	release_firmware(fw);
-	if (0 != ret) {
-		dev_err(&interface->dev, "firmware_s2250 download failed\n");
-		goto failed2;
-	}
-
-	usb_set_intfdata(interface, s);
-	return 0;
-
-failed:
-	mutex_unlock(&s2250_dev_table_mutex);
-failed2:
-	if (s)
-		kref_put(&(s->kref), s2250loader_delete);
-
-	dev_err(&interface->dev, "probe failed\n");
-	return -1;
-}
-
-static void s2250loader_disconnect(struct usb_interface *interface)
-{
-	pdevice_extension_t s;
-	dev_info(&interface->dev, "s2250: disconnect\n");
-	s = usb_get_intfdata(interface);
-	usb_set_intfdata(interface, NULL);
-	kref_put(&(s->kref), s2250loader_delete);
-}
-
-static const struct usb_device_id s2250loader_ids[] = {
-	{USB_DEVICE(0x1943, 0xa250)},
-	{}                          /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, s2250loader_ids);
-
-static struct usb_driver s2250loader_driver = {
-	.name		= "s2250-loader",
-	.probe		= s2250loader_probe,
-	.disconnect	= s2250loader_disconnect,
-	.id_table	= s2250loader_ids,
-};
-
-module_usb_driver(s2250loader_driver);
-
-MODULE_AUTHOR("");
-MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251");
-MODULE_LICENSE("GPL v2");
-MODULE_FIRMWARE(S2250_LOADER_FIRMWARE);
-MODULE_FIRMWARE(S2250_FIRMWARE);
diff --git a/drivers/staging/media/go7007/s2250-loader.h b/drivers/staging/media/go7007/s2250-loader.h
deleted file mode 100644
index b7c301a..0000000
--- a/drivers/staging/media/go7007/s2250-loader.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Micronas USA Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-#ifndef _S2250_LOADER_H_
-#define _S2250_LOADER_H_
-
-extern int s2250loader_init(void);
-extern void s2250loader_cleanup(void);
-
-#endif
-- 
1.7.10.4


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

* [REVIEW PATCH 40/42] go7007-loader: add support for the other devices and move fw files
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (37 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 39/42] go7007-loader: renamed from s2250-loader Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 41/42] go7007: update the README Hans Verkuil
                     ` (2 subsequent siblings)
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Add support for the other devices that need to load the boot firmware.
All firmware files are now placed in a single go7007 directory.

Also remove the device_extension_s stuff: this is clearly a left-over from
the olden days.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/go7007-driver.c  |    4 +-
 drivers/staging/media/go7007/go7007-loader.c  |  131 ++++++++++---------------
 drivers/staging/media/go7007/go7007-usb.c     |   22 ++---
 drivers/staging/media/go7007/saa7134-go7007.c |    3 +-
 4 files changed, 68 insertions(+), 92 deletions(-)

diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index 0fd3f10..4378223 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -90,7 +90,7 @@ EXPORT_SYMBOL(go7007_read_addr);
 static int go7007_load_encoder(struct go7007 *go)
 {
 	const struct firmware *fw_entry;
-	char fw_name[] = "go7007fw.bin";
+	char fw_name[] = "go7007/go7007fw.bin";
 	void *bounce;
 	int fw_len, rv = 0;
 	u16 intr_val, intr_data;
@@ -126,7 +126,7 @@ static int go7007_load_encoder(struct go7007 *go)
 	return rv;
 }
 
-MODULE_FIRMWARE("go7007fw.bin");
+MODULE_FIRMWARE("go7007/go7007fw.bin");
 
 /*
  * Boot the encoder and register the I2C adapter if requested.  Do the
diff --git a/drivers/staging/media/go7007/go7007-loader.c b/drivers/staging/media/go7007/go7007-loader.c
index 730a4f8..4ce53d6 100644
--- a/drivers/staging/media/go7007/go7007-loader.c
+++ b/drivers/staging/media/go7007/go7007-loader.c
@@ -22,86 +22,67 @@
 #include <linux/firmware.h>
 #include <cypress_firmware.h>
 
-#define S2250_LOADER_FIRMWARE	"s2250_loader.fw"
-#define S2250_FIRMWARE		"2250.fw"
-
-typedef struct device_extension_s {
-    struct kref     kref;
-    int minor;
-    struct usb_device *usbdev;
-} device_extension_t, *pdevice_extension_t;
-
-#define USB_go7007_loader_MAJOR 240
-#define USB_go7007_loader_MINOR_BASE 0
-#define MAX_DEVICES 256
-
-static pdevice_extension_t go7007_dev_table[MAX_DEVICES];
-static DEFINE_MUTEX(go7007_dev_table_mutex);
+struct fw_config {
+	u16 vendor;
+	u16 product;
+	const char * const fw_name1;
+	const char * const fw_name2;
+};
 
-#define to_go7007_loader_dev_common(d) container_of(d, device_extension_t, kref)
-static void go7007_loader_delete(struct kref *kref)
-{
-	pdevice_extension_t s = to_go7007_loader_dev_common(kref);
-	go7007_dev_table[s->minor] = NULL;
-	kfree(s);
-}
+struct fw_config fw_configs[] = {
+	{ 0x1943, 0xa250, "go7007/s2250-1.fw", "go7007/s2250-2.fw" },
+	{ 0x093b, 0xa002, "go7007/px-m402u.fw", NULL },
+	{ 0x093b, 0xa004, "go7007/px-tv402u.fw", NULL },
+	{ 0x0eb1, 0x6666, "go7007/lr192.fw", NULL },
+	{ 0x0eb1, 0x6668, "go7007/wis-startrek.fw", NULL },
+	{ 0, 0, NULL, NULL }
+};
+MODULE_FIRMWARE("go7007/s2250-1.fw");
+MODULE_FIRMWARE("go7007/s2250-2.fw");
+MODULE_FIRMWARE("go7007/px-m402u.fw");
+MODULE_FIRMWARE("go7007/px-tv402u.fw");
+MODULE_FIRMWARE("go7007/lr192.fw");
+MODULE_FIRMWARE("go7007/wis-startrek.fw");
 
 static int go7007_loader_probe(struct usb_interface *interface,
 				const struct usb_device_id *id)
 {
 	struct usb_device *usbdev;
-	int minor, ret;
-	pdevice_extension_t s = NULL;
 	const struct firmware *fw;
+	u16 vendor, product;
+	const char *fw1, *fw2;
+	int ret;
+	int i;
 
 	usbdev = usb_get_dev(interface_to_usbdev(interface));
-	if (!usbdev) {
-		dev_err(&interface->dev, "Enter go7007_loader_probe failed\n");
-		return -1;
-	}
-	dev_info(&interface->dev, "vendor id 0x%x, device id 0x%x devnum:%d\n",
-		 usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
-		 usbdev->devnum);
+	if (!usbdev)
+		goto failed2;
 
 	if (usbdev->descriptor.bNumConfigurations != 1) {
 		dev_err(&interface->dev, "can't handle multiple config\n");
-		return -1;
-	}
-	mutex_lock(&go7007_dev_table_mutex);
-
-	for (minor = 0; minor < MAX_DEVICES; minor++) {
-		if (go7007_dev_table[minor] == NULL)
-			break;
+		return -ENODEV;
 	}
 
-	if (minor < 0 || minor >= MAX_DEVICES) {
-		dev_err(&interface->dev, "Invalid minor: %d\n", minor);
-		goto failed;
-	}
-
-	/* Allocate dev data structure */
-	s = kmalloc(sizeof(device_extension_t), GFP_KERNEL);
-	if (s == NULL)
-		goto failed;
-
-	go7007_dev_table[minor] = s;
+	vendor = le16_to_cpu(usbdev->descriptor.idVendor);
+	product = le16_to_cpu(usbdev->descriptor.idProduct);
 
-	dev_info(&interface->dev,
-		 "Device %d on Bus %d Minor %d\n",
-		 usbdev->devnum, usbdev->bus->busnum, minor);
+	for (i = 0; fw_configs[i].fw_name1; i++)
+		if (fw_configs[i].vendor == vendor &&
+		    fw_configs[i].product == product)
+			break;
 
-	memset(s, 0, sizeof(device_extension_t));
-	s->usbdev = usbdev;
-	dev_info(&interface->dev, "loading go7007-loader\n");
+	/* Should never happen */
+	if (fw_configs[i].fw_name1 == NULL)
+		goto failed2;
 
-	kref_init(&(s->kref));
+	fw1 = fw_configs[i].fw_name1;
+	fw2 = fw_configs[i].fw_name2;
 
-	mutex_unlock(&go7007_dev_table_mutex);
+	dev_info(&interface->dev, "loading firmware %s\n", fw1);
 
-	if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
+	if (request_firmware(&fw, fw1, &usbdev->dev)) {
 		dev_err(&interface->dev,
-			"unable to load firmware from file \"%s\"\n",
-			S2250_LOADER_FIRMWARE);
+			"unable to load firmware from file \"%s\"\n", fw1);
 		goto failed2;
 	}
 	ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
@@ -111,10 +92,12 @@ static int go7007_loader_probe(struct usb_interface *interface,
 		goto failed2;
 	}
 
-	if (request_firmware(&fw, S2250_FIRMWARE, &usbdev->dev)) {
+	if (fw2 == NULL)
+		return 0;
+
+	if (request_firmware(&fw, fw2, &usbdev->dev)) {
 		dev_err(&interface->dev,
-			"unable to load firmware from file \"%s\"\n",
-			S2250_FIRMWARE);
+			"unable to load firmware from file \"%s\"\n", fw2);
 		goto failed2;
 	}
 	ret = usbv2_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
@@ -123,31 +106,25 @@ static int go7007_loader_probe(struct usb_interface *interface,
 		dev_err(&interface->dev, "firmware download failed\n");
 		goto failed2;
 	}
-
-	usb_set_intfdata(interface, s);
 	return 0;
 
-failed:
-	mutex_unlock(&go7007_dev_table_mutex);
 failed2:
-	if (s)
-		kref_put(&(s->kref), go7007_loader_delete);
-
 	dev_err(&interface->dev, "probe failed\n");
-	return -1;
+	return -ENODEV;
 }
 
 static void go7007_loader_disconnect(struct usb_interface *interface)
 {
-	pdevice_extension_t s;
 	dev_info(&interface->dev, "disconnect\n");
-	s = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
-	kref_put(&(s->kref), go7007_loader_delete);
 }
 
 static const struct usb_device_id go7007_loader_ids[] = {
-	{USB_DEVICE(0x1943, 0xa250)},
+	{ USB_DEVICE(0x1943, 0xa250) },
+	{ USB_DEVICE(0x093b, 0xa002) },
+	{ USB_DEVICE(0x093b, 0xa004) },
+	{ USB_DEVICE(0x0eb1, 0x6666) },
+	{ USB_DEVICE(0x0eb1, 0x6668) },
 	{}                          /* Terminating entry */
 };
 
@@ -163,7 +140,5 @@ static struct usb_driver go7007_loader_driver = {
 module_usb_driver(go7007_loader_driver);
 
 MODULE_AUTHOR("");
-MODULE_DESCRIPTION("firmware loader for go7007 USB devices");
+MODULE_DESCRIPTION("firmware loader for go7007-usb");
 MODULE_LICENSE("GPL v2");
-MODULE_FIRMWARE(S2250_LOADER_FIRMWARE);
-MODULE_FIRMWARE(S2250_FIRMWARE);
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 2a1cda2..bd23d7d 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -76,7 +76,7 @@ struct go7007_usb {
 static struct go7007_usb_board board_matrix_ii = {
 	.flags		= GO7007_USB_EZUSB,
 	.main_info	= {
-		.firmware	 = "go7007tv.bin",
+		.firmware	 = "go7007/go7007tv.bin",
 		.flags		 = GO7007_BOARD_HAS_AUDIO |
 					GO7007_BOARD_USE_ONBOARD_I2C,
 		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
@@ -117,7 +117,7 @@ static struct go7007_usb_board board_matrix_ii = {
 static struct go7007_usb_board board_matrix_reload = {
 	.flags		= GO7007_USB_EZUSB,
 	.main_info	= {
-		.firmware	 = "go7007tv.bin",
+		.firmware	 = "go7007/go7007tv.bin",
 		.flags		 = GO7007_BOARD_HAS_AUDIO |
 					GO7007_BOARD_USE_ONBOARD_I2C,
 		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
@@ -155,7 +155,7 @@ static struct go7007_usb_board board_matrix_reload = {
 static struct go7007_usb_board board_star_trek = {
 	.flags		= GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
 	.main_info	= {
-		.firmware	 = "go7007tv.bin",
+		.firmware	 = "go7007/go7007tv.bin",
 		.flags		 = GO7007_BOARD_HAS_AUDIO, /* |
 					GO7007_BOARD_HAS_TUNER, */
 		.sensor_flags	 = GO7007_SENSOR_656 |
@@ -203,7 +203,7 @@ static struct go7007_usb_board board_star_trek = {
 static struct go7007_usb_board board_px_tv402u = {
 	.flags		= GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
 	.main_info	= {
-		.firmware	 = "go7007tv.bin",
+		.firmware	 = "go7007/go7007tv.bin",
 		.flags		 = GO7007_BOARD_HAS_AUDIO |
 					GO7007_BOARD_HAS_TUNER,
 		.sensor_flags	 = GO7007_SENSOR_656 |
@@ -278,7 +278,7 @@ static struct go7007_usb_board board_px_tv402u = {
 static struct go7007_usb_board board_xmen = {
 	.flags		= 0,
 	.main_info	= {
-		.firmware	  = "go7007tv.bin",
+		.firmware	  = "go7007/go7007tv.bin",
 		.flags		  = GO7007_BOARD_USE_ONBOARD_I2C,
 		.hpi_buffer_cap   = 0,
 		.sensor_flags	  = GO7007_SENSOR_VREF_POLAR,
@@ -313,7 +313,7 @@ static struct go7007_usb_board board_xmen = {
 static struct go7007_usb_board board_matrix_revolution = {
 	.flags		= GO7007_USB_EZUSB,
 	.main_info	= {
-		.firmware	 = "go7007tv.bin",
+		.firmware	 = "go7007/go7007tv.bin",
 		.flags		 = GO7007_BOARD_HAS_AUDIO |
 					GO7007_BOARD_USE_ONBOARD_I2C,
 		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
@@ -351,7 +351,7 @@ static struct go7007_usb_board board_matrix_revolution = {
 static struct go7007_usb_board board_lifeview_lr192 = {
 	.flags		= GO7007_USB_EZUSB,
 	.main_info	= {
-		.firmware	 = "go7007tv.bin",
+		.firmware	 = "go7007/go7007tv.bin",
 		.flags		 = GO7007_BOARD_HAS_AUDIO |
 					GO7007_BOARD_USE_ONBOARD_I2C,
 		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
@@ -379,7 +379,7 @@ static struct go7007_usb_board board_lifeview_lr192 = {
 static struct go7007_usb_board board_endura = {
 	.flags		= 0,
 	.main_info	= {
-		.firmware	 = "go7007tv.bin",
+		.firmware	 = "go7007/go7007tv.bin",
 		.flags		 = 0,
 		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 					GO7007_AUDIO_I2S_MASTER |
@@ -404,7 +404,7 @@ static struct go7007_usb_board board_endura = {
 static struct go7007_usb_board board_adlink_mpg24 = {
 	.flags		= 0,
 	.main_info	= {
-		.firmware	 = "go7007tv.bin",
+		.firmware	 = "go7007/go7007tv.bin",
 		.flags		 = GO7007_BOARD_USE_ONBOARD_I2C,
 		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 					GO7007_AUDIO_I2S_MASTER |
@@ -437,7 +437,7 @@ static struct go7007_usb_board board_adlink_mpg24 = {
 static struct go7007_usb_board board_sensoray_2250 = {
 	.flags		= GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
 	.main_info	= {
-		.firmware	 = "go7007tv.bin",
+		.firmware	 = "go7007/go7007tv.bin",
 		.audio_flags	 = GO7007_AUDIO_I2S_MODE_1 |
 					GO7007_AUDIO_I2S_MASTER |
 					GO7007_AUDIO_WORD_16,
@@ -486,7 +486,7 @@ static struct go7007_usb_board board_sensoray_2250 = {
 	},
 };
 
-MODULE_FIRMWARE("go7007tv.bin");
+MODULE_FIRMWARE("go7007/go7007tv.bin");
 
 static const struct usb_device_id go7007_usb_id_table[] = {
 	{
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index f51f42e..daa8c02 100644
--- a/drivers/staging/media/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
@@ -74,7 +74,7 @@ static inline struct saa7134_go7007 *to_state(struct v4l2_subdev *sd)
 }
 
 static struct go7007_board_info board_voyager = {
-	.firmware	 = "go7007tv.bin",
+	.firmware	 = "go7007/go7007tv.bin",
 	.flags		 = 0,
 	.sensor_flags	 = GO7007_SENSOR_656 |
 				GO7007_SENSOR_VALID_ENABLE |
@@ -93,6 +93,7 @@ static struct go7007_board_info board_voyager = {
 		},
 	},
 };
+MODULE_FIRMWARE("go7007/go7007tv.bin");
 
 /********************* Driver for GPIO HPI interface *********************/
 
-- 
1.7.10.4


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

* [REVIEW PATCH 41/42] go7007: update the README
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (38 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 40/42] go7007-loader: add support for the other devices and move fw files Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:46   ` [REVIEW PATCH 42/42] MAINTAINERS: add the go7007 driver Hans Verkuil
  2013-03-11 11:50   ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/staging/media/go7007/README |   14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/go7007/README b/drivers/staging/media/go7007/README
index aeba132..779fe3f 100644
--- a/drivers/staging/media/go7007/README
+++ b/drivers/staging/media/go7007/README
@@ -1,11 +1,5 @@
 Todo:
-	- checkpatch.pl cleanups
-	- sparse cleanups
-	- lots of little modules, should be merged together
-	  and added to the build.
-	- testing?
-	- handle churn in v4l layer.
-
-Please send patches to Greg Kroah-Hartman <greg@linuxfoundation.org> and Cc: Ross
-Cohen <rcohen@snurgle.org> as well.
-
+	- create an API for motion detection
+	- figure out how to distribute the firmware files
+	- let s2250-board use i2c subdevs as well instead of hardcoding
+	  support for the i2c devices.
-- 
1.7.10.4


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

* [REVIEW PATCH 42/42] MAINTAINERS: add the go7007 driver.
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (39 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 41/42] go7007: update the README Hans Verkuil
@ 2013-03-11 11:46   ` Hans Verkuil
  2013-03-11 11:50   ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:46 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein, Hans Verkuil

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

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 MAINTAINERS |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ff2fcc9..5703edd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7550,6 +7550,11 @@ M:	David Täht <d@teklibre.com>
 S:	Odd Fixes
 F:	drivers/staging/frontier/
 
+STAGING - GO7007 MPEG CODEC
+M:	Hans Verkuil <hans.verkuil@cisco.com>
+S:	Maintained
+F:	drivers/staging/media/go7007/
+
 STAGING - INDUSTRIAL IO
 M:	Jonathan Cameron <jic23@cam.ac.uk>
 L:	linux-iio@vger.kernel.org
-- 
1.7.10.4


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

* Re: [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
                     ` (40 preceding siblings ...)
  2013-03-11 11:46   ` [REVIEW PATCH 42/42] MAINTAINERS: add the go7007 driver Hans Verkuil
@ 2013-03-11 11:50   ` Hans Verkuil
  41 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 11:50 UTC (permalink / raw)
  To: linux-media, Andy Walls; +Cc: Volokh Konstantin, Pete Eberlein

On Mon March 11 2013 12:45:39 Hans Verkuil wrote:
> From: Andy Walls <awalls at>

Oops, somehow I messed up Andy's email. I've corrected it in my git tree.

Regards,

	Hans

> 
> When calling v4l2_ctrl_add_handler(), lockdep would detect a potential
> recursive locking problem on a situation that is by design intended and
> not a recursive lock.  This happened because all struct
> v4l2_ctrl_handler.lock mutexes were created as members of the same lock
> class in v4l2_ctrl_handler_init(), and v4l2_ctrl_add_handler() takes the
> hdl->lock on two different v4l2_ctrl_handler instances.
> 
> This change breaks the large lockdep lock class for struct
> v4l2_ctrl_handler.lock and breaks it into v4l2_ctrl_handler
> instantiation specific lock classes with meaningful class names.
> 
> This will validly eliminate lockdep alarms for v4l2_ctrl_handler locking
> validation, as long as the relationships between drivers adding v4l2
> controls to their own handler from other v4l2 drivers' control handlers
> remains straightforward.
> 
> struct v4l2_ctrl_handler.lock lock classes are created with names such
> that the output of cat /proc/lockdep indicates where in the v4l2 driver
> code v4l2_ctrl_handle_init() is being called on instantiations:
> 
> ffffffffa045f490 FD:   10 BD:    8 +.+...: cx2341x:1534:(hdl)->lock
> ffffffffa0497d20 FD:   12 BD:    2 +.+.+.: saa7115:1581:(hdl)->lock
> ffffffffa04ac660 FD:   14 BD:    2 +.+.+.: msp3400_driver:756:(hdl)->lock
> ffffffffa0484b90 FD:   12 BD:    1 +.+.+.: ivtv_gpio:366:(&itv->hdl_gpio)->lock
> ffffffffa04eb530 FD:   11 BD:    2 +.+.+.: cx25840_core:1982:(&state->hdl)->lock
> ffffffffa04fbc80 FD:   11 BD:    3 +.+.+.: wm8775:246:(&state->hdl)->lock
> 
> Some lock chains, that were previously causing the recursion alarms, are
> now visible in the output of cat /proc/lockdep_chains:
> 
> irq_context: 0
> [ffffffffa0497d20] saa7115:1581:(hdl)->lock
> [ffffffffa045f490] cx2341x:1534:(hdl)->lock
> 
> irq_context: 0
> [ffffffffa04ac660] msp3400_driver:756:(hdl)->lock
> [ffffffffa045f490] cx2341x:1534:(hdl)->lock
> 
> irq_context: 0
> [ffffffffa0484b90] ivtv_gpio:366:(&itv->hdl_gpio)->lock
> [ffffffffa045f490] cx2341x:1534:(hdl)->lock
> 
> irq_context: 0
> [ffffffffa04eb530] cx25840_core:1982:(&state->hdl)->lock
> [ffffffffa045f490] cx2341x:1534:(hdl)->lock
> 
> irq_context: 0
> [ffffffffa04fbc80] wm8775:246:(&state->hdl)->lock
> [ffffffffa045f490] cx2341x:1534:(hdl)->lock
> 
> Signed-off-by: Andy Walls <awalls <at> md.metrocast.net>
> [hans.verkuil@cisco.com: keep mutex_init in v4l2_ctrl_handler_init_class]
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  drivers/media/v4l2-core/v4l2-ctrls.c |    8 +++++---
>  include/media/v4l2-ctrls.h           |   29 ++++++++++++++++++++++++++---
>  2 files changed, 31 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
> index 6b28b58..b36d1ec 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -1362,11 +1362,13 @@ static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
>  }
>  
>  /* Initialize the handler */
> -int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
> -			   unsigned nr_of_controls_hint)
> +int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
> +				 unsigned nr_of_controls_hint,
> +				 struct lock_class_key *key, const char *name)
>  {
>  	hdl->lock = &hdl->_lock;
>  	mutex_init(hdl->lock);
> +	lockdep_set_class_and_name(hdl->lock, key, name);
>  	INIT_LIST_HEAD(&hdl->ctrls);
>  	INIT_LIST_HEAD(&hdl->ctrl_refs);
>  	hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
> @@ -1375,7 +1377,7 @@ int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
>  	hdl->error = hdl->buckets ? 0 : -ENOMEM;
>  	return hdl->error;
>  }
> -EXPORT_SYMBOL(v4l2_ctrl_handler_init);
> +EXPORT_SYMBOL(v4l2_ctrl_handler_init_class);
>  
>  /* Free all controls and control refs */
>  void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
> diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
> index f00d42b..7343a27 100644
> --- a/include/media/v4l2-ctrls.h
> +++ b/include/media/v4l2-ctrls.h
> @@ -259,7 +259,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
>  		    s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags);
>  
>  
> -/** v4l2_ctrl_handler_init() - Initialize the control handler.
> +/** v4l2_ctrl_handler_init_class() - Initialize the control handler.
>    * @hdl:	The control handler.
>    * @nr_of_controls_hint: A hint of how many controls this handler is
>    *		expected to refer to. This is the total number, so including
> @@ -268,12 +268,35 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
>    *		are allocated) or the control lookup becomes slower (not enough
>    *		buckets are allocated, so there are more slow list lookups).
>    *		It will always work, though.
> +  * @key:	Used by the lock validator if CONFIG_LOCKDEP is set.
> +  * @name:	Used by the lock validator if CONFIG_LOCKDEP is set.
>    *
>    * Returns an error if the buckets could not be allocated. This error will
>    * also be stored in @hdl->error.
> +  *
> +  * Never use this call directly, always use the v4l2_ctrl_handler_init
> +  * macro that hides the @key and @name arguments.
>    */
> -int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
> -			   unsigned nr_of_controls_hint);
> +int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
> +				 unsigned nr_of_controls_hint,
> +				 struct lock_class_key *key, const char *name);
> +
> +#ifdef CONFIG_LOCKDEP
> +#define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint)		\
> +(									\
> +	({								\
> +		static struct lock_class_key _key;			\
> +		v4l2_ctrl_handler_init_class(hdl, nr_of_controls_hint,	\
> +					&_key,				\
> +					KBUILD_BASENAME ":"		\
> +					__stringify(__LINE__) ":"	\
> +					"(" #hdl ")->_lock");		\
> +	})								\
> +)
> +#else
> +#define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint)		\
> +	v4l2_ctrl_handler_init_class(hdl, nr_of_controls_hint, NULL, NULL)
> +#endif
>  
>  /** v4l2_ctrl_handler_free() - Free all controls owned by the handler and free
>    * the control list.
> 

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

* Re: [REVIEW PATCH 00/42] go7007: complete overhaul
  2013-03-11 11:45 [REVIEW PATCH 00/42] go7007: complete overhaul Hans Verkuil
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
@ 2013-03-11 22:01 ` Hans Verkuil
  2013-03-12 14:37 ` Darrick Burch
  2 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-11 22:01 UTC (permalink / raw)
  To: linux-media; +Cc: Volokh Konstantin, Pete Eberlein

On Mon March 11 2013 12:45:38 Hans Verkuil wrote:
> Hi all,
> 
> This patch series updates the staging go7007 driver to the latest
> V4L2 frameworks and actually makes it work reliably.
> 
> Some highlights:
> 
> - moved the custom i2c drivers to media/i2c.
> - replaced the s2250-loader by a common loader for all the supported
>   devices.
> - replaced all MPEG-related custom ioctls by standard ioctls and FMT
>   support.
> - added the saa7134-go7007 combination (similar to the saa7134-empress).
> 
> In addition I've made some V4L2 core and saa7115 changes (the first 6
> patches):
> 
> - eliminate false lockdep warnings when dealing with nested control
>   handlers. This patch is a slightly modified version from the one Andy
>   posted a long time ago.
> - add support to easily test if any subdevices support a particular operation.
> - fix a few bugs in the code that tests if an ioctl is available: it didn't
>   take 'disabling of ioctls' into account.
> - added additional configuration flags to saa7115, needed by the go7007.
> - improved querystd support in saa7115.
> 
> This driver now passes all v4l2-compliance tests.
> 
> Volokh, I've merged your tw2804 v4l2 framework cleanup patches into one
> with my modifications on top. I hope you don't mind.
> 
> It has been tested with:
> 
> - Plextor PX-TV402U (PAL model)
> - Sensoray S2250S (generously provided by Sensoray, all audio inputs
>   now work!)
> - Sensoray Model 614 (saa7134+go7007 PCI board, generously provided by
>   Sensoray)
> - WIS X-Men II sensor board (generously provided by Sensoray)
> - Adlink PCI-MPG24 surveillance board

and it has also been tested with:

- Plextor PX-M402U (it arrived today)

Regards,

	Hans

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

* Re: [REVIEW PATCH 00/42] go7007: complete overhaul
  2013-03-11 11:45 [REVIEW PATCH 00/42] go7007: complete overhaul Hans Verkuil
  2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
  2013-03-11 22:01 ` [REVIEW PATCH 00/42] go7007: complete overhaul Hans Verkuil
@ 2013-03-12 14:37 ` Darrick Burch
  2013-03-12 15:05   ` Hans Verkuil
  2 siblings, 1 reply; 56+ messages in thread
From: Darrick Burch @ 2013-03-12 14:37 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media

> This week I'll also receive a Plextor PX-M402U to test with and an ADS DVD
> XPress DX2 is also on its way (I did some ebay shopping!).

As it happens I've been working with the DVD Xpress DX2.  I found a patch
floating around the Internet, with the needed code to add support for it,
but I was chagrined to discover (on 3.6.28) that v4l2 subdevice support
was simply not implemented correctly and I couldn't get very far with it.

I have cloned your go7007 branch and I am in the process of trying to
apply the changes again.  My only question about this device is that it
uses a tw9906 and not a tw9903 (for which there is already an i2c module).
 Do you know much about either decoder?  The tw9906 code in the patch
looked very similar to what was in the tw9903 save for a few initial
register differences.


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

* Re: [REVIEW PATCH 00/42] go7007: complete overhaul
  2013-03-12 14:37 ` Darrick Burch
@ 2013-03-12 15:05   ` Hans Verkuil
  0 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-12 15:05 UTC (permalink / raw)
  To: Darrick Burch; +Cc: linux-media

On Tue 12 March 2013 15:37:03 Darrick Burch wrote:
> > This week I'll also receive a Plextor PX-M402U to test with and an ADS DVD
> > XPress DX2 is also on its way (I did some ebay shopping!).
> 
> As it happens I've been working with the DVD Xpress DX2.  I found a patch
> floating around the Internet, with the needed code to add support for it,
> but I was chagrined to discover (on 3.6.28) that v4l2 subdevice support
> was simply not implemented correctly and I couldn't get very far with it.
> 
> I have cloned your go7007 branch and I am in the process of trying to
> apply the changes again.  My only question about this device is that it
> uses a tw9906 and not a tw9903 (for which there is already an i2c module).
>  Do you know much about either decoder?  The tw9906 code in the patch
> looked very similar to what was in the tw9903 save for a few initial
> register differences.

I know little about those devices. But I did find datasheets for both with
some creative googling. I'll mail them to you.

Looking at the datasheets it seems to me that there are too many differences.
Especially if the drivers are going to be extended with additional features.
I would go with separate drivers for now.

Regards,

	Hans

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

* Re: [REVIEW PATCH 09/42] sony-btf-mpx: the MPX driver for the sony BTF PAL/SECAM tuner
  2013-03-11 11:45   ` [REVIEW PATCH 09/42] sony-btf-mpx: the MPX driver for the sony BTF PAL/SECAM tuner Hans Verkuil
@ 2013-03-24 15:21     ` Mauro Carvalho Chehab
  2013-03-25  8:52       ` Hans Verkuil
  0 siblings, 1 reply; 56+ messages in thread
From: Mauro Carvalho Chehab @ 2013-03-24 15:21 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, Volokh Konstantin, Pete Eberlein, Hans Verkuil

Em Mon, 11 Mar 2013 12:45:47 +0100
Hans Verkuil <hverkuil@xs4all.nl> escreveu:

> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> The Sony BTF PG472Z has an internal MPX to deal with mono/stereo/bilingual
> audio. This is split off from the wis-sony-tuner driver that is part of
> the go7007 driver as it should be a separate i2c sub-device driver.
> 
> The wis-sony-tuner is really three i2c devices: a standard tuner, a tda9887
> compatible demodulator and this mpx. After this patch the wis-sony-tuner
> can be replaced by this driver and the standard tuner driver.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  drivers/media/i2c/Kconfig        |   11 +-
>  drivers/media/i2c/Makefile       |    1 +
>  drivers/media/i2c/sony-btf-mpx.c |  399 ++++++++++++++++++++++++++++++++++++++

Not sure what happened, but sony-btf-mpx.c got missed on the version inside
the pull request.

So, I got it from this patch.

>  3 files changed, 410 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/media/i2c/sony-btf-mpx.c
> 
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 7b771ba..70dbae2 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -133,7 +133,7 @@ config VIDEO_WM8739
>  	  module will be called wm8739.
>  
>  config VIDEO_VP27SMPX
> -	tristate "Panasonic VP27s internal MPX"
> +	tristate "Panasonic VP27's internal MPX"
>  	depends on VIDEO_V4L2 && I2C
>  	---help---
>  	  Support for the internal MPX of the Panasonic VP27s tuner.
> @@ -141,6 +141,15 @@ config VIDEO_VP27SMPX
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called vp27smpx.
>  
> +config VIDEO_SONY_BTF_MPX
> +	tristate "Sony BTF's internal MPX"
> +	depends on VIDEO_V4L2 && I2C
> +	help
> +	  Support for the internal MPX of the Sony BTF-PG472Z tuner.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called sony-btf-mpx.
> +
>  comment "RDS decoders"
>  
>  config VIDEO_SAA6588
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index cfefd30..4c57075 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -44,6 +44,7 @@ obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
>  obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
>  obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
>  obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
> +obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
>  obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
>  obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
>  obj-$(CONFIG_VIDEO_OV7670) 	+= ov7670.o
> diff --git a/drivers/media/i2c/sony-btf-mpx.c b/drivers/media/i2c/sony-btf-mpx.c
> new file mode 100644
> index 0000000..bc73e8f
> --- /dev/null
> +++ b/drivers/media/i2c/sony-btf-mpx.c
> @@ -0,0 +1,399 @@
> +/*
> + * Copyright (C) 2005-2006 Micronas USA Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License (Version 2) as
> + * published by the Free Software Foundation.
> + *
> + * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/i2c.h>
> +#include <linux/videodev2.h>
> +#include <media/tuner.h>
> +#include <media/v4l2-common.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/v4l2-device.h>
> +#include <linux/slab.h>
> +
> +MODULE_DESCRIPTION("sony-btf-mpx driver");
> +MODULE_LICENSE("GPL v2");
> +
> +static int debug;
> +module_param(debug, int, 0644);
> +MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on\n");
> +
> +/* #define MPX_DEBUG */
> +
> +/*
> + * Note:
> + *
> + * AS(IF/MPX) pin:      LOW      HIGH/OPEN
> + * IF/MPX address:   0x42/0x40   0x43/0x44
> + */
> +
> +
> +static int force_mpx_mode = -1;
> +module_param(force_mpx_mode, int, 0644);
> +
> +struct sony_btf_mpx {
> +	struct v4l2_subdev sd;
> +	int mpxmode;
> +	u32 audmode;
> +};
> +
> +static inline struct sony_btf_mpx *to_state(struct v4l2_subdev *sd)
> +{
> +	return container_of(sd, struct sony_btf_mpx, sd);
> +}
> +
> +static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
> +{
> +	u8 buffer[5];
> +	struct i2c_msg msg;
> +
> +	buffer[0] = dev;
> +	buffer[1] = addr >> 8;
> +	buffer[2] = addr & 0xff;
> +	buffer[3] = val >> 8;
> +	buffer[4] = val & 0xff;
> +	msg.addr = client->addr;
> +	msg.flags = 0;
> +	msg.len = 5;
> +	msg.buf = buffer;
> +	i2c_transfer(client->adapter, &msg, 1);
> +	return 0;
> +}
> +
> +/*
> + * MPX register values for the BTF-PG472Z:
> + *
> + *                                 FM_     NICAM_  SCART_
> + *          MODUS  SOURCE    ACB   PRESCAL PRESCAL PRESCAL SYSTEM  VOLUME
> + *         10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000
> + *         ---------------------------------------------------------------
> + * Auto     1003    0020    0100    2603    5000    XXXX    0001    7500
> + *
> + * B/G
> + *  Mono    1003    0020    0100    2603    5000    XXXX    0003    7500
> + *  A2      1003    0020    0100    2601    5000    XXXX    0003    7500
> + *  NICAM   1003    0120    0100    2603    5000    XXXX    0008    7500
> + *
> + * I
> + *  Mono    1003    0020    0100    2603    7900    XXXX    000A    7500
> + *  NICAM   1003    0120    0100    2603    7900    XXXX    000A    7500
> + *
> + * D/K
> + *  Mono    1003    0020    0100    2603    5000    XXXX    0004    7500
> + *  A2-1    1003    0020    0100    2601    5000    XXXX    0004    7500
> + *  A2-2    1003    0020    0100    2601    5000    XXXX    0005    7500
> + *  A2-3    1003    0020    0100    2601    5000    XXXX    0007    7500
> + *  NICAM   1003    0120    0100    2603    5000    XXXX    000B    7500
> + *
> + * L/L'
> + *  Mono    0003    0200    0100    7C03    5000    2200    0009    7500
> + *  NICAM   0003    0120    0100    7C03    5000    XXXX    0009    7500
> + *
> + * M
> + *  Mono    1003    0200    0100    2B03    5000    2B00    0002    7500
> + *
> + * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX.
> + *
> + * Bilingual selection in A2/NICAM:
> + *
> + *         High byte of SOURCE     Left chan   Right chan
> + *                 0x01              MAIN         SUB
> + *                 0x03              MAIN         MAIN
> + *                 0x04              SUB          SUB
> + *
> + * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or
> + * 0x00 (all other bands).  Force mono in A2 with FMONO_A2:
> + *
> + *                      FMONO_A2
> + *                      10/0022
> + *                      --------
> + *     Forced mono ON     07F0
> + *     Forced mono OFF    0190
> + */
> +
> +static const struct {
> +	enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
> +	u16 modus;
> +	u16 source;
> +	u16 acb;
> +	u16 fm_prescale;
> +	u16 nicam_prescale;
> +	u16 scart_prescale;
> +	u16 system;
> +	u16 volume;
> +} mpx_audio_modes[] = {
> +	/* Auto */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
> +					0x5000, 0x0000, 0x0001, 0x7500 },
> +	/* B/G Mono */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
> +					0x5000, 0x0000, 0x0003, 0x7500 },
> +	/* B/G A2 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
> +					0x5000, 0x0000, 0x0003, 0x7500 },
> +	/* B/G NICAM */ { AUD_NICAM,	0x1003, 0x0120, 0x0100, 0x2603,
> +					0x5000, 0x0000, 0x0008, 0x7500 },
> +	/* I Mono */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
> +					0x7900, 0x0000, 0x000A, 0x7500 },
> +	/* I NICAM */	{ AUD_NICAM,	0x1003, 0x0120, 0x0100, 0x2603,
> +					0x7900, 0x0000, 0x000A, 0x7500 },
> +	/* D/K Mono */	{ AUD_MONO,	0x1003, 0x0020, 0x0100, 0x2603,
> +					0x5000, 0x0000, 0x0004, 0x7500 },
> +	/* D/K A2-1 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
> +					0x5000, 0x0000, 0x0004, 0x7500 },
> +	/* D/K A2-2 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
> +					0x5000, 0x0000, 0x0005, 0x7500 },
> +	/* D/K A2-3 */	{ AUD_A2,	0x1003, 0x0020, 0x0100, 0x2601,
> +					0x5000, 0x0000, 0x0007, 0x7500 },
> +	/* D/K NICAM */	{ AUD_NICAM,	0x1003, 0x0120, 0x0100, 0x2603,
> +					0x5000, 0x0000, 0x000B, 0x7500 },
> +	/* L/L' Mono */	{ AUD_MONO,	0x0003, 0x0200, 0x0100, 0x7C03,
> +					0x5000, 0x2200, 0x0009, 0x7500 },
> +	/* L/L' NICAM */{ AUD_NICAM_L,	0x0003, 0x0120, 0x0100, 0x7C03,
> +					0x5000, 0x0000, 0x0009, 0x7500 },
> +};
> +
> +#define MPX_NUM_MODES	ARRAY_SIZE(mpx_audio_modes)
> +
> +static int mpx_setup(struct sony_btf_mpx *t)
> +{
> +	struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
> +	u16 source = 0;
> +	u8 buffer[3];
> +	struct i2c_msg msg;
> +	int mode = t->mpxmode;
> +
> +	/* reset MPX */
> +	buffer[0] = 0x00;
> +	buffer[1] = 0x80;
> +	buffer[2] = 0x00;
> +	msg.addr = client->addr;
> +	msg.flags = 0;
> +	msg.len = 3;
> +	msg.buf = buffer;
> +	i2c_transfer(client->adapter, &msg, 1);
> +	buffer[1] = 0x00;
> +	i2c_transfer(client->adapter, &msg, 1);
> +
> +	if (t->audmode != V4L2_TUNER_MODE_MONO)
> +		mode++;
> +
> +	if (mpx_audio_modes[mode].audio_mode != AUD_MONO) {
> +		switch (t->audmode) {
> +		case V4L2_TUNER_MODE_MONO:
> +			switch (mpx_audio_modes[mode].audio_mode) {
> +			case AUD_A2:
> +				source = mpx_audio_modes[mode].source;
> +				break;
> +			case AUD_NICAM:
> +				source = 0x0000;
> +				break;
> +			case AUD_NICAM_L:
> +				source = 0x0200;
> +				break;
> +			default:
> +				break;
> +			}
> +			break;
> +		case V4L2_TUNER_MODE_STEREO:
> +			source = mpx_audio_modes[mode].source;
> +			break;
> +		case V4L2_TUNER_MODE_LANG1:
> +			source = 0x0300;
> +			break;
> +		case V4L2_TUNER_MODE_LANG2:
> +			source = 0x0400;
> +			break;
> +		}
> +		source |= mpx_audio_modes[mode].source & 0x00ff;
> +	} else
> +		source = mpx_audio_modes[mode].source;
> +
> +	mpx_write(client, 0x10, 0x0030, mpx_audio_modes[mode].modus);
> +	mpx_write(client, 0x12, 0x0008, source);
> +	mpx_write(client, 0x12, 0x0013, mpx_audio_modes[mode].acb);
> +	mpx_write(client, 0x12, 0x000e,
> +			mpx_audio_modes[mode].fm_prescale);
> +	mpx_write(client, 0x12, 0x0010,
> +			mpx_audio_modes[mode].nicam_prescale);
> +	mpx_write(client, 0x12, 0x000d,
> +			mpx_audio_modes[mode].scart_prescale);
> +	mpx_write(client, 0x10, 0x0020, mpx_audio_modes[mode].system);
> +	mpx_write(client, 0x12, 0x0000, mpx_audio_modes[mode].volume);
> +	if (mpx_audio_modes[mode].audio_mode == AUD_A2)
> +		mpx_write(client, 0x10, 0x0022,
> +			t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190);
> +
> +#ifdef MPX_DEBUG
> +	{
> +		u8 buf1[3], buf2[2];
> +		struct i2c_msg msgs[2];
> +
> +		v4l2_info(client,
> +			"MPX registers: %04x %04x %04x %04x %04x %04x %04x %04x\n",
> +			mpx_audio_modes[mode].modus,
> +			source,
> +			mpx_audio_modes[mode].acb,
> +			mpx_audio_modes[mode].fm_prescale,
> +			mpx_audio_modes[mode].nicam_prescale,
> +			mpx_audio_modes[mode].scart_prescale,
> +			mpx_audio_modes[mode].system,
> +			mpx_audio_modes[mode].volume);
> +		buf1[0] = 0x11;
> +		buf1[1] = 0x00;
> +		buf1[2] = 0x7e;
> +		msgs[0].addr = client->addr;
> +		msgs[0].flags = 0;
> +		msgs[0].len = 3;
> +		msgs[0].buf = buf1;
> +		msgs[1].addr = client->addr;
> +		msgs[1].flags = I2C_M_RD;
> +		msgs[1].len = 2;
> +		msgs[1].buf = buf2;
> +		i2c_transfer(client->adapter, msgs, 2);
> +		v4l2_info(client, "MPX system: %02x%02x\n",
> +				buf2[0], buf2[1]);
> +		buf1[0] = 0x11;
> +		buf1[1] = 0x02;
> +		buf1[2] = 0x00;
> +		i2c_transfer(client->adapter, msgs, 2);
> +		v4l2_info(client, "MPX status: %02x%02x\n",
> +				buf2[0], buf2[1]);
> +	}
> +#endif
> +	return 0;
> +}
> +
> +
> +static int sony_btf_mpx_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
> +{
> +	struct sony_btf_mpx *t = to_state(sd);
> +	int default_mpx_mode = 0;
> +
> +	if (std & V4L2_STD_PAL_BG)
> +		default_mpx_mode = 1;
> +	else if (std & V4L2_STD_PAL_I)
> +		default_mpx_mode = 4;
> +	else if (std & V4L2_STD_PAL_DK)
> +		default_mpx_mode = 6;
> +	else if (std & V4L2_STD_SECAM_L)
> +		default_mpx_mode = 11;
> +
> +	if (default_mpx_mode != t->mpxmode) {
> +		t->mpxmode = default_mpx_mode;
> +		mpx_setup(t);
> +	}
> +	return 0;
> +}
> +
> +static int sony_btf_mpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
> +{
> +	struct sony_btf_mpx *t = to_state(sd);
> +
> +	vt->capability = V4L2_TUNER_CAP_NORM |
> +		V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
> +		V4L2_TUNER_CAP_LANG2;
> +	vt->rxsubchans = V4L2_TUNER_SUB_MONO |
> +		V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
> +		V4L2_TUNER_SUB_LANG2;
> +	vt->audmode = t->audmode;
> +	return 0;
> +}
> +
> +static int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
> +{
> +	struct sony_btf_mpx *t = to_state(sd);
> +
> +	if (vt->type != V4L2_TUNER_ANALOG_TV)
> +		return -EINVAL;
> +
> +	if (vt->audmode != t->audmode) {
> +		t->audmode = vt->audmode;
> +		mpx_setup(t);
> +	}
> +	return 0;
> +}
> +
> +/* --------------------------------------------------------------------------*/
> +
> +static const struct v4l2_subdev_core_ops sony_btf_mpx_core_ops = {
> +	.s_std = sony_btf_mpx_s_std,
> +};
> +
> +static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = {
> +	.s_tuner = sony_btf_mpx_s_tuner,
> +	.g_tuner = sony_btf_mpx_g_tuner,
> +};
> +
> +static const struct v4l2_subdev_ops sony_btf_mpx_ops = {
> +	.core = &sony_btf_mpx_core_ops,
> +	.tuner = &sony_btf_mpx_tuner_ops,
> +};
> +
> +/* --------------------------------------------------------------------------*/
> +
> +static int sony_btf_mpx_probe(struct i2c_client *client,
> +				const struct i2c_device_id *id)
> +{
> +	struct sony_btf_mpx *t;
> +	struct v4l2_subdev *sd;
> +
> +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
> +		return -ENODEV;
> +
> +	v4l_info(client, "chip found @ 0x%x (%s)\n",
> +			client->addr << 1, client->adapter->name);
> +
> +	t = kzalloc(sizeof(struct sony_btf_mpx), GFP_KERNEL);
> +	if (t == NULL)
> +		return -ENOMEM;
> +
> +	sd = &t->sd;
> +	v4l2_i2c_subdev_init(sd, client, &sony_btf_mpx_ops);
> +
> +	/* Initialize sony_btf_mpx */
> +	t->mpxmode = 0;
> +	t->audmode = V4L2_TUNER_MODE_STEREO;
> +
> +	return 0;
> +}
> +
> +static int sony_btf_mpx_remove(struct i2c_client *client)
> +{
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +
> +	v4l2_device_unregister_subdev(sd);
> +	kfree(to_state(sd));
> +
> +	return 0;
> +}
> +
> +/* ----------------------------------------------------------------------- */
> +
> +static const struct i2c_device_id sony_btf_mpx_id[] = {
> +	{ "sony-btf-mpx", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, sony_btf_mpx_id);
> +
> +static struct i2c_driver sony_btf_mpx_driver = {
> +	.driver = {
> +		.owner	= THIS_MODULE,
> +		.name	= "sony-btf-mpx",
> +	},
> +	.probe = sony_btf_mpx_probe,
> +	.remove = sony_btf_mpx_remove,
> +	.id_table = sony_btf_mpx_id,
> +};
> +module_i2c_driver(sony_btf_mpx_driver);


-- 

Cheers,
Mauro

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

* Re: [REVIEW PATCH 12/42] tw9903: add new tw9903 video decoder.
  2013-03-11 11:45   ` [REVIEW PATCH 12/42] tw9903: add new tw9903 video decoder Hans Verkuil
@ 2013-03-24 15:29     ` Mauro Carvalho Chehab
  2013-03-24 16:06       ` Mauro Carvalho Chehab
  2013-03-25  8:55       ` Hans Verkuil
  0 siblings, 2 replies; 56+ messages in thread
From: Mauro Carvalho Chehab @ 2013-03-24 15:29 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, Volokh Konstantin, Pete Eberlein, Hans Verkuil

Em Mon, 11 Mar 2013 12:45:50 +0100
Hans Verkuil <hverkuil@xs4all.nl> escreveu:

> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> This based on the wis-tw9903.c driver that's part of the go7007 driver.
> It has been converted to a v4l subdev driver by Pete Eberlein, and I made
> additional cleanups.
> 
> Based on work by: Pete Eberlein <pete@sensoray.com>
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> Cc: Pete Eberlein <pete@sensoray.com>
> ---
>  drivers/media/i2c/Kconfig  |   10 ++
>  drivers/media/i2c/Makefile |    1 +
>  drivers/media/i2c/tw9903.c |  274 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 285 insertions(+)
>  create mode 100644 drivers/media/i2c/tw9903.c
> 
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 8000642..eb9ef55 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -301,6 +301,16 @@ config VIDEO_TVP7002
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called tvp7002.
>  
> +config VIDEO_TW9903
> +	tristate "Techwell TW9903 video decoder"
> +	depends on VIDEO_V4L2 && I2C
> +	---help---
> +	  Support for the Techwell 9903 multi-standard video decoder
> +	  with high quality down scaler.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called tw9903.
> +
>  config VIDEO_VPX3220
>  	tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
>  	depends on VIDEO_V4L2 && I2C
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index b1775b3..af8fb29 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
>  obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
>  obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
>  obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
> +obj-$(CONFIG_VIDEO_TW9903) += tw9903.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/tw9903.c b/drivers/media/i2c/tw9903.c
> new file mode 100644
> index 0000000..82626ea
> --- /dev/null
> +++ b/drivers/media/i2c/tw9903.c
> @@ -0,0 +1,274 @@
> +/*
> + * Copyright (C) 2005-2006 Micronas USA Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License (Version 2) as
> + * published by the Free Software Foundation.
> + *
> + * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/i2c.h>
> +#include <linux/videodev2.h>
> +#include <linux/ioctl.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-ctrls.h>
> +#include <linux/slab.h>
> +
> +MODULE_DESCRIPTION("TW9903 I2C subdev driver");
> +MODULE_LICENSE("GPL v2");
> +
> +/*
> + * This driver is based on the wis-tw9903.c source that was in
> + * drivers/staging/media/go7007. That source had commented out code for
> + * saturation and scaling (neither seemed to work). If anyone ever gets
> + * hardware to test this driver, then that code might be useful to look at.
> + * You need to get the kernel sources of, say, kernel 3.8 where that
> + * wis-tw9903 driver is still present.
> + */
> +
> +struct tw9903 {
> +	struct v4l2_subdev sd;
> +	struct v4l2_ctrl_handler hdl;
> +	v4l2_std_id norm;
> +};
> +
> +static inline struct tw9903 *to_state(struct v4l2_subdev *sd)
> +{
> +	return container_of(sd, struct tw9903, sd);
> +}
> +
> +static const u8 initial_registers[] = {
> +	0x02, 0x44, /* input 1, composite */
> +	0x03, 0x92, /* correct digital format */
> +	0x04, 0x00,
> +	0x05, 0x80, /* or 0x00 for PAL */
> +	0x06, 0x40, /* second internal current reference */
> +	0x07, 0x02, /* window */
> +	0x08, 0x14, /* window */
> +	0x09, 0xf0, /* window */
> +	0x0a, 0x81, /* window */
> +	0x0b, 0xd0, /* window */
> +	0x0c, 0x8c,
> +	0x0d, 0x00, /* scaling */
> +	0x0e, 0x11, /* scaling */
> +	0x0f, 0x00, /* scaling */
> +	0x10, 0x00, /* brightness */
> +	0x11, 0x60, /* contrast */
> +	0x12, 0x01, /* sharpness */
> +	0x13, 0x7f, /* U gain */
> +	0x14, 0x5a, /* V gain */
> +	0x15, 0x00, /* hue */
> +	0x16, 0xc3, /* sharpness */
> +	0x18, 0x00,
> +	0x19, 0x58, /* vbi */
> +	0x1a, 0x80,
> +	0x1c, 0x0f, /* video norm */
> +	0x1d, 0x7f, /* video norm */
> +	0x20, 0xa0, /* clamping gain (working 0x50) */
> +	0x21, 0x22,
> +	0x22, 0xf0,
> +	0x23, 0xfe,
> +	0x24, 0x3c,
> +	0x25, 0x38,
> +	0x26, 0x44,
> +	0x27, 0x20,
> +	0x28, 0x00,
> +	0x29, 0x15,
> +	0x2a, 0xa0,
> +	0x2b, 0x44,
> +	0x2c, 0x37,
> +	0x2d, 0x00,
> +	0x2e, 0xa5, /* burst PLL control (working: a9) */
> +	0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */
> +	0x31, 0x00,
> +	0x33, 0x22,
> +	0x34, 0x11,
> +	0x35, 0x35,
> +	0x3b, 0x05,
> +	0x06, 0xc0, /* reset device */
> +	0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
> +};
> +
> +static int write_reg(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 int write_regs(struct v4l2_subdev *sd, const u8 *regs)
> +{
> +	int i;
> +
> +	for (i = 0; regs[i] != 0x00; i += 2)
> +		if (write_reg(sd, regs[i], regs[i + 1]) < 0)
> +			return -1;
> +	return 0;
> +}
> +
> +static int tw9903_s_video_routing(struct v4l2_subdev *sd, u32 input,
> +				      u32 output, u32 config)
> +{
> +	write_reg(sd, 0x02, 0x40 | (input << 1));
> +	return 0;
> +}
> +
> +static int tw9903_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
> +{
> +	struct tw9903 *dec = to_state(sd);
> +	bool is_60hz = norm & V4L2_STD_525_60;
> +	u8 regs[] = {
> +		0x05, is_60hz ? 0x80 : 0x00,
> +		0x07, is_60hz ? 0x02 : 0x12,
> +		0x08, is_60hz ? 0x14 : 0x18,
> +		0x09, is_60hz ? 0xf0 : 0x20,
> +		0,    0,
> +	};

The above is ugly, and probably is wasting space at the code
segment.

I'll apply it for now, but the better would be to change it to
2 const tables.


Cheers,
Mauro

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

* Re: [REVIEW PATCH 16/42] go7007: switch to standard tuner/i2c subdevs.
  2013-03-11 11:45   ` [REVIEW PATCH 16/42] go7007: switch to standard tuner/i2c subdevs Hans Verkuil
@ 2013-03-24 15:35     ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 56+ messages in thread
From: Mauro Carvalho Chehab @ 2013-03-24 15:35 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, Volokh Konstantin, Pete Eberlein, Hans Verkuil

Em Mon, 11 Mar 2013 12:45:54 +0100
Hans Verkuil <hverkuil@xs4all.nl> escreveu:

> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> Instead of using the wis-* drivers we now use the standard 'proper' subdev
> drivers.
> 
> The board configuration tables now also list the possible audio inputs,
> this will be used later to implement audio inputs.
> 
> Special mention deserves a little change in set_capture_size() where the
> height passed to s_mbus_fmt is doubled: that is because the saa7115 driver
> expects to see the frame height, not the field height as the wis_saa7115
> driver did.
> 
> Another change is that the tuner input is moved from last to the first
> input, which is consistent with the common practice in other video drivers.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  drivers/staging/media/go7007/Kconfig          |   77 ++---------------
>  drivers/staging/media/go7007/Makefile         |   12 ---
>  drivers/staging/media/go7007/go7007-driver.c  |   29 +++++--
>  drivers/staging/media/go7007/go7007-i2c.c     |    1 -
>  drivers/staging/media/go7007/go7007-priv.h    |   18 +++-
>  drivers/staging/media/go7007/go7007-usb.c     |  112 +++++++++++++++++--------
>  drivers/staging/media/go7007/go7007-v4l2.c    |   18 +++-
>  drivers/staging/media/go7007/saa7134-go7007.c |    2 +-
>  8 files changed, 135 insertions(+), 134 deletions(-)

That produced the following warnings:

drivers/media/i2c/sony-btf-mpx.c:335:2: warning: initialization from incompatible pointer type [enabled by default]
drivers/media/i2c/sony-btf-mpx.c:335:2: warning: (near initialization for 'sony_btf_mpx_tuner_ops.s_tuner') [enabled by default]

Cheers,
Mauro

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

* Re: [REVIEW PATCH 19/42] s2250-loader: use usbv2_cypress_load_firmware
  2013-03-11 11:45   ` [REVIEW PATCH 19/42] s2250-loader: use usbv2_cypress_load_firmware Hans Verkuil
@ 2013-03-24 15:39     ` Mauro Carvalho Chehab
  2013-03-24 15:49       ` Antti Palosaari
  2013-03-25  8:56       ` Hans Verkuil
  0 siblings, 2 replies; 56+ messages in thread
From: Mauro Carvalho Chehab @ 2013-03-24 15:39 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: linux-media, Volokh Konstantin, Pete Eberlein, Hans Verkuil,
	Antti Palosaari

Em Mon, 11 Mar 2013 12:45:57 +0100
Hans Verkuil <hverkuil@xs4all.nl> escreveu:

> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> The v2 of this function doesn't do DMA to objects on the stack like
> its predecessor does.
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  drivers/staging/media/go7007/Makefile       |    4 ++--
>  drivers/staging/media/go7007/s2250-loader.c |    7 ++++---
>  2 files changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
> index 5bed78b..f9c8e0f 100644
> --- a/drivers/staging/media/go7007/Makefile
> +++ b/drivers/staging/media/go7007/Makefile
> @@ -11,8 +11,8 @@ s2250-y := s2250-board.o
>  #obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
>  #ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
>  
> -# S2250 needs cypress ezusb loader from dvb-usb
> -ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb
> +# S2250 needs cypress ezusb loader from dvb-usb-v2
> +ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb-v2

Please don't do it like that. Ok, for now it is in staging,
but once you move it outside it, please move the cypress load firmware
code to drivers/media/common, and do the proper changes for it to be
shared between go7007 and dvb-usb-v2.

Regards,
Mauro

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

* Re: [REVIEW PATCH 19/42] s2250-loader: use usbv2_cypress_load_firmware
  2013-03-24 15:39     ` Mauro Carvalho Chehab
@ 2013-03-24 15:49       ` Antti Palosaari
  2013-03-25  8:56       ` Hans Verkuil
  1 sibling, 0 replies; 56+ messages in thread
From: Antti Palosaari @ 2013-03-24 15:49 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Hans Verkuil, linux-media, Volokh Konstantin, Pete Eberlein,
	Hans Verkuil

On 03/24/2013 05:39 PM, Mauro Carvalho Chehab wrote:
> Em Mon, 11 Mar 2013 12:45:57 +0100
> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
>
>> From: Hans Verkuil <hans.verkuil@cisco.com>
>>
>> The v2 of this function doesn't do DMA to objects on the stack like
>> its predecessor does.
>>
>> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
>> ---
>>   drivers/staging/media/go7007/Makefile       |    4 ++--
>>   drivers/staging/media/go7007/s2250-loader.c |    7 ++++---
>>   2 files changed, 6 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
>> index 5bed78b..f9c8e0f 100644
>> --- a/drivers/staging/media/go7007/Makefile
>> +++ b/drivers/staging/media/go7007/Makefile
>> @@ -11,8 +11,8 @@ s2250-y := s2250-board.o
>>   #obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
>>   #ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
>>
>> -# S2250 needs cypress ezusb loader from dvb-usb
>> -ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb
>> +# S2250 needs cypress ezusb loader from dvb-usb-v2
>> +ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb-v2
>
> Please don't do it like that. Ok, for now it is in staging,
> but once you move it outside it, please move the cypress load firmware
> code to drivers/media/common, and do the proper changes for it to be
> shared between go7007 and dvb-usb-v2.

I agree with Mauro, you could move it to the common as it is nothing DVB 
USB only related.

Acked-by: Antti Palosaari <crope@iki.fi>

regards
Antti


-- 
http://palosaari.fi/

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

* Re: [REVIEW PATCH 12/42] tw9903: add new tw9903 video decoder.
  2013-03-24 15:29     ` Mauro Carvalho Chehab
@ 2013-03-24 16:06       ` Mauro Carvalho Chehab
  2013-03-25  8:55       ` Hans Verkuil
  1 sibling, 0 replies; 56+ messages in thread
From: Mauro Carvalho Chehab @ 2013-03-24 16:06 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Hans Verkuil, linux-media, Volokh Konstantin, Pete Eberlein,
	Hans Verkuil

Em Sun, 24 Mar 2013 12:29:32 -0300
Mauro Carvalho Chehab <mchehab@redhat.com> escreveu:

> Em Mon, 11 Mar 2013 12:45:50 +0100
> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> 
> > From: Hans Verkuil <hans.verkuil@cisco.com>
> > 
> > This based on the wis-tw9903.c driver that's part of the go7007 driver.
> > It has been converted to a v4l subdev driver by Pete Eberlein, and I made
> > additional cleanups.
> > 
> > Based on work by: Pete Eberlein <pete@sensoray.com>
> > 
> > Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> > Cc: Pete Eberlein <pete@sensoray.com>
> > ---
> >  drivers/media/i2c/Kconfig  |   10 ++
> >  drivers/media/i2c/Makefile |    1 +
> >  drivers/media/i2c/tw9903.c |  274 ++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 285 insertions(+)
> >  create mode 100644 drivers/media/i2c/tw9903.c
> > 
> > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > index 8000642..eb9ef55 100644
> > --- a/drivers/media/i2c/Kconfig
> > +++ b/drivers/media/i2c/Kconfig
> > @@ -301,6 +301,16 @@ config VIDEO_TVP7002
> >  	  To compile this driver as a module, choose M here: the
> >  	  module will be called tvp7002.
> >  
> > +config VIDEO_TW9903
> > +	tristate "Techwell TW9903 video decoder"
> > +	depends on VIDEO_V4L2 && I2C
> > +	---help---
> > +	  Support for the Techwell 9903 multi-standard video decoder
> > +	  with high quality down scaler.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  module will be called tw9903.
> > +
> >  config VIDEO_VPX3220
> >  	tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
> >  	depends on VIDEO_V4L2 && I2C
> > diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> > index b1775b3..af8fb29 100644
> > --- a/drivers/media/i2c/Makefile
> > +++ b/drivers/media/i2c/Makefile
> > @@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
> >  obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
> >  obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
> >  obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
> > +obj-$(CONFIG_VIDEO_TW9903) += tw9903.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/tw9903.c b/drivers/media/i2c/tw9903.c
> > new file mode 100644
> > index 0000000..82626ea
> > --- /dev/null
> > +++ b/drivers/media/i2c/tw9903.c
> > @@ -0,0 +1,274 @@
> > +/*
> > + * Copyright (C) 2005-2006 Micronas USA Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License (Version 2) as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/init.h>
> > +#include <linux/i2c.h>
> > +#include <linux/videodev2.h>
> > +#include <linux/ioctl.h>
> > +#include <media/v4l2-device.h>
> > +#include <media/v4l2-ctrls.h>
> > +#include <linux/slab.h>
> > +
> > +MODULE_DESCRIPTION("TW9903 I2C subdev driver");
> > +MODULE_LICENSE("GPL v2");
> > +
> > +/*
> > + * This driver is based on the wis-tw9903.c source that was in
> > + * drivers/staging/media/go7007. That source had commented out code for
> > + * saturation and scaling (neither seemed to work). If anyone ever gets
> > + * hardware to test this driver, then that code might be useful to look at.
> > + * You need to get the kernel sources of, say, kernel 3.8 where that
> > + * wis-tw9903 driver is still present.
> > + */
> > +
> > +struct tw9903 {
> > +	struct v4l2_subdev sd;
> > +	struct v4l2_ctrl_handler hdl;
> > +	v4l2_std_id norm;
> > +};
> > +
> > +static inline struct tw9903 *to_state(struct v4l2_subdev *sd)
> > +{
> > +	return container_of(sd, struct tw9903, sd);
> > +}
> > +
> > +static const u8 initial_registers[] = {
> > +	0x02, 0x44, /* input 1, composite */
> > +	0x03, 0x92, /* correct digital format */
> > +	0x04, 0x00,
> > +	0x05, 0x80, /* or 0x00 for PAL */
> > +	0x06, 0x40, /* second internal current reference */
> > +	0x07, 0x02, /* window */
> > +	0x08, 0x14, /* window */
> > +	0x09, 0xf0, /* window */
> > +	0x0a, 0x81, /* window */
> > +	0x0b, 0xd0, /* window */
> > +	0x0c, 0x8c,
> > +	0x0d, 0x00, /* scaling */
> > +	0x0e, 0x11, /* scaling */
> > +	0x0f, 0x00, /* scaling */
> > +	0x10, 0x00, /* brightness */
> > +	0x11, 0x60, /* contrast */
> > +	0x12, 0x01, /* sharpness */
> > +	0x13, 0x7f, /* U gain */
> > +	0x14, 0x5a, /* V gain */
> > +	0x15, 0x00, /* hue */
> > +	0x16, 0xc3, /* sharpness */
> > +	0x18, 0x00,
> > +	0x19, 0x58, /* vbi */
> > +	0x1a, 0x80,
> > +	0x1c, 0x0f, /* video norm */
> > +	0x1d, 0x7f, /* video norm */
> > +	0x20, 0xa0, /* clamping gain (working 0x50) */
> > +	0x21, 0x22,
> > +	0x22, 0xf0,
> > +	0x23, 0xfe,
> > +	0x24, 0x3c,
> > +	0x25, 0x38,
> > +	0x26, 0x44,
> > +	0x27, 0x20,
> > +	0x28, 0x00,
> > +	0x29, 0x15,
> > +	0x2a, 0xa0,
> > +	0x2b, 0x44,
> > +	0x2c, 0x37,
> > +	0x2d, 0x00,
> > +	0x2e, 0xa5, /* burst PLL control (working: a9) */
> > +	0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */
> > +	0x31, 0x00,
> > +	0x33, 0x22,
> > +	0x34, 0x11,
> > +	0x35, 0x35,
> > +	0x3b, 0x05,
> > +	0x06, 0xc0, /* reset device */
> > +	0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
> > +};
> > +
> > +static int write_reg(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 int write_regs(struct v4l2_subdev *sd, const u8 *regs)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; regs[i] != 0x00; i += 2)
> > +		if (write_reg(sd, regs[i], regs[i + 1]) < 0)
> > +			return -1;
> > +	return 0;
> > +}
> > +
> > +static int tw9903_s_video_routing(struct v4l2_subdev *sd, u32 input,
> > +				      u32 output, u32 config)
> > +{
> > +	write_reg(sd, 0x02, 0x40 | (input << 1));
> > +	return 0;
> > +}
> > +
> > +static int tw9903_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
> > +{
> > +	struct tw9903 *dec = to_state(sd);
> > +	bool is_60hz = norm & V4L2_STD_525_60;
> > +	u8 regs[] = {
> > +		0x05, is_60hz ? 0x80 : 0x00,
> > +		0x07, is_60hz ? 0x02 : 0x12,
> > +		0x08, is_60hz ? 0x14 : 0x18,
> > +		0x09, is_60hz ? 0xf0 : 0x20,
> > +		0,    0,
> > +	};
> 
> The above is ugly, and probably is wasting space at the code
> segment.
> 
> I'll apply it for now, but the better would be to change it to
> 2 const tables.

The very same issue is there at tw9906 patch on your git tree. I didn't
find any REVIEW email with it through.

-- 

Cheers,
Mauro

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

* Re: [REVIEW PATCH 09/42] sony-btf-mpx: the MPX driver for the sony BTF PAL/SECAM tuner
  2013-03-24 15:21     ` Mauro Carvalho Chehab
@ 2013-03-25  8:52       ` Hans Verkuil
  0 siblings, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-25  8:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: linux-media, Volokh Konstantin, Pete Eberlein, Hans Verkuil

On Sun March 24 2013 16:21:12 Mauro Carvalho Chehab wrote:
> Em Mon, 11 Mar 2013 12:45:47 +0100
> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> 
> > From: Hans Verkuil <hans.verkuil@cisco.com>
> > 
> > The Sony BTF PG472Z has an internal MPX to deal with mono/stereo/bilingual
> > audio. This is split off from the wis-sony-tuner driver that is part of
> > the go7007 driver as it should be a separate i2c sub-device driver.
> > 
> > The wis-sony-tuner is really three i2c devices: a standard tuner, a tda9887
> > compatible demodulator and this mpx. After this patch the wis-sony-tuner
> > can be replaced by this driver and the standard tuner driver.
> > 
> > Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> > ---
> >  drivers/media/i2c/Kconfig        |   11 +-
> >  drivers/media/i2c/Makefile       |    1 +
> >  drivers/media/i2c/sony-btf-mpx.c |  399 ++++++++++++++++++++++++++++++++++++++
> 
> Not sure what happened, but sony-btf-mpx.c got missed on the version inside
> the pull request.
> 
> So, I got it from this patch.

Grr. I found the same 'const' issue as you did, fixed it in my tree but forgot
to do a git add for the file :-(

Sorry.

Regards,

	Hans

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

* Re: [REVIEW PATCH 12/42] tw9903: add new tw9903 video decoder.
  2013-03-24 15:29     ` Mauro Carvalho Chehab
  2013-03-24 16:06       ` Mauro Carvalho Chehab
@ 2013-03-25  8:55       ` Hans Verkuil
  1 sibling, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-25  8:55 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: linux-media, Volokh Konstantin, Pete Eberlein, Hans Verkuil

On Sun March 24 2013 16:29:32 Mauro Carvalho Chehab wrote:
> Em Mon, 11 Mar 2013 12:45:50 +0100
> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> 
> > From: Hans Verkuil <hans.verkuil@cisco.com>
> > 
> > This based on the wis-tw9903.c driver that's part of the go7007 driver.
> > It has been converted to a v4l subdev driver by Pete Eberlein, and I made
> > additional cleanups.
> > 
> > Based on work by: Pete Eberlein <pete@sensoray.com>
> > 
> > Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> > Cc: Pete Eberlein <pete@sensoray.com>
> > ---
> >  drivers/media/i2c/Kconfig  |   10 ++
> >  drivers/media/i2c/Makefile |    1 +
> >  drivers/media/i2c/tw9903.c |  274 ++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 285 insertions(+)
> >  create mode 100644 drivers/media/i2c/tw9903.c
> > 
> > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > index 8000642..eb9ef55 100644
> > --- a/drivers/media/i2c/Kconfig
> > +++ b/drivers/media/i2c/Kconfig
> > @@ -301,6 +301,16 @@ config VIDEO_TVP7002
> >  	  To compile this driver as a module, choose M here: the
> >  	  module will be called tvp7002.
> >  
> > +config VIDEO_TW9903
> > +	tristate "Techwell TW9903 video decoder"
> > +	depends on VIDEO_V4L2 && I2C
> > +	---help---
> > +	  Support for the Techwell 9903 multi-standard video decoder
> > +	  with high quality down scaler.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  module will be called tw9903.
> > +
> >  config VIDEO_VPX3220
> >  	tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
> >  	depends on VIDEO_V4L2 && I2C
> > diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> > index b1775b3..af8fb29 100644
> > --- a/drivers/media/i2c/Makefile
> > +++ b/drivers/media/i2c/Makefile
> > @@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
> >  obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
> >  obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
> >  obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
> > +obj-$(CONFIG_VIDEO_TW9903) += tw9903.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/tw9903.c b/drivers/media/i2c/tw9903.c
> > new file mode 100644
> > index 0000000..82626ea
> > --- /dev/null
> > +++ b/drivers/media/i2c/tw9903.c
> > @@ -0,0 +1,274 @@
> > +/*
> > + * Copyright (C) 2005-2006 Micronas USA Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License (Version 2) as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/init.h>
> > +#include <linux/i2c.h>
> > +#include <linux/videodev2.h>
> > +#include <linux/ioctl.h>
> > +#include <media/v4l2-device.h>
> > +#include <media/v4l2-ctrls.h>
> > +#include <linux/slab.h>
> > +
> > +MODULE_DESCRIPTION("TW9903 I2C subdev driver");
> > +MODULE_LICENSE("GPL v2");
> > +
> > +/*
> > + * This driver is based on the wis-tw9903.c source that was in
> > + * drivers/staging/media/go7007. That source had commented out code for
> > + * saturation and scaling (neither seemed to work). If anyone ever gets
> > + * hardware to test this driver, then that code might be useful to look at.
> > + * You need to get the kernel sources of, say, kernel 3.8 where that
> > + * wis-tw9903 driver is still present.
> > + */
> > +
> > +struct tw9903 {
> > +	struct v4l2_subdev sd;
> > +	struct v4l2_ctrl_handler hdl;
> > +	v4l2_std_id norm;
> > +};
> > +
> > +static inline struct tw9903 *to_state(struct v4l2_subdev *sd)
> > +{
> > +	return container_of(sd, struct tw9903, sd);
> > +}
> > +
> > +static const u8 initial_registers[] = {
> > +	0x02, 0x44, /* input 1, composite */
> > +	0x03, 0x92, /* correct digital format */
> > +	0x04, 0x00,
> > +	0x05, 0x80, /* or 0x00 for PAL */
> > +	0x06, 0x40, /* second internal current reference */
> > +	0x07, 0x02, /* window */
> > +	0x08, 0x14, /* window */
> > +	0x09, 0xf0, /* window */
> > +	0x0a, 0x81, /* window */
> > +	0x0b, 0xd0, /* window */
> > +	0x0c, 0x8c,
> > +	0x0d, 0x00, /* scaling */
> > +	0x0e, 0x11, /* scaling */
> > +	0x0f, 0x00, /* scaling */
> > +	0x10, 0x00, /* brightness */
> > +	0x11, 0x60, /* contrast */
> > +	0x12, 0x01, /* sharpness */
> > +	0x13, 0x7f, /* U gain */
> > +	0x14, 0x5a, /* V gain */
> > +	0x15, 0x00, /* hue */
> > +	0x16, 0xc3, /* sharpness */
> > +	0x18, 0x00,
> > +	0x19, 0x58, /* vbi */
> > +	0x1a, 0x80,
> > +	0x1c, 0x0f, /* video norm */
> > +	0x1d, 0x7f, /* video norm */
> > +	0x20, 0xa0, /* clamping gain (working 0x50) */
> > +	0x21, 0x22,
> > +	0x22, 0xf0,
> > +	0x23, 0xfe,
> > +	0x24, 0x3c,
> > +	0x25, 0x38,
> > +	0x26, 0x44,
> > +	0x27, 0x20,
> > +	0x28, 0x00,
> > +	0x29, 0x15,
> > +	0x2a, 0xa0,
> > +	0x2b, 0x44,
> > +	0x2c, 0x37,
> > +	0x2d, 0x00,
> > +	0x2e, 0xa5, /* burst PLL control (working: a9) */
> > +	0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */
> > +	0x31, 0x00,
> > +	0x33, 0x22,
> > +	0x34, 0x11,
> > +	0x35, 0x35,
> > +	0x3b, 0x05,
> > +	0x06, 0xc0, /* reset device */
> > +	0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
> > +};
> > +
> > +static int write_reg(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 int write_regs(struct v4l2_subdev *sd, const u8 *regs)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; regs[i] != 0x00; i += 2)
> > +		if (write_reg(sd, regs[i], regs[i + 1]) < 0)
> > +			return -1;
> > +	return 0;
> > +}
> > +
> > +static int tw9903_s_video_routing(struct v4l2_subdev *sd, u32 input,
> > +				      u32 output, u32 config)
> > +{
> > +	write_reg(sd, 0x02, 0x40 | (input << 1));
> > +	return 0;
> > +}
> > +
> > +static int tw9903_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
> > +{
> > +	struct tw9903 *dec = to_state(sd);
> > +	bool is_60hz = norm & V4L2_STD_525_60;
> > +	u8 regs[] = {
> > +		0x05, is_60hz ? 0x80 : 0x00,
> > +		0x07, is_60hz ? 0x02 : 0x12,
> > +		0x08, is_60hz ? 0x14 : 0x18,
> > +		0x09, is_60hz ? 0xf0 : 0x20,
> > +		0,    0,
> > +	};
> 
> The above is ugly, and probably is wasting space at the code
> segment.
> 
> I'll apply it for now, but the better would be to change it to
> 2 const tables.

There are a few go7007 related patches that were posted in the last few days.
I'm going to combine them and also fix simple things like the above and
make a new pull request for you.

Regards,

	Hans

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

* Re: [REVIEW PATCH 19/42] s2250-loader: use usbv2_cypress_load_firmware
  2013-03-24 15:39     ` Mauro Carvalho Chehab
  2013-03-24 15:49       ` Antti Palosaari
@ 2013-03-25  8:56       ` Hans Verkuil
  1 sibling, 0 replies; 56+ messages in thread
From: Hans Verkuil @ 2013-03-25  8:56 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: linux-media, Volokh Konstantin, Pete Eberlein, Hans Verkuil,
	Antti Palosaari

On Sun March 24 2013 16:39:24 Mauro Carvalho Chehab wrote:
> Em Mon, 11 Mar 2013 12:45:57 +0100
> Hans Verkuil <hverkuil@xs4all.nl> escreveu:
> 
> > From: Hans Verkuil <hans.verkuil@cisco.com>
> > 
> > The v2 of this function doesn't do DMA to objects on the stack like
> > its predecessor does.
> > 
> > Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> > ---
> >  drivers/staging/media/go7007/Makefile       |    4 ++--
> >  drivers/staging/media/go7007/s2250-loader.c |    7 ++++---
> >  2 files changed, 6 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
> > index 5bed78b..f9c8e0f 100644
> > --- a/drivers/staging/media/go7007/Makefile
> > +++ b/drivers/staging/media/go7007/Makefile
> > @@ -11,8 +11,8 @@ s2250-y := s2250-board.o
> >  #obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
> >  #ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
> >  
> > -# S2250 needs cypress ezusb loader from dvb-usb
> > -ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb
> > +# S2250 needs cypress ezusb loader from dvb-usb-v2
> > +ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb-v2
> 
> Please don't do it like that. Ok, for now it is in staging,
> but once you move it outside it, please move the cypress load firmware
> code to drivers/media/common, and do the proper changes for it to be
> shared between go7007 and dvb-usb-v2.

It's a good idea to move this to common. I'll do that.

Regards,

	Hans

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

end of thread, other threads:[~2013-03-25  8:57 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-11 11:45 [REVIEW PATCH 00/42] go7007: complete overhaul Hans Verkuil
2013-03-11 11:45 ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 02/42] v4l2-core: add code to check for specific ops Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 03/42] v4l2-ioctl: check if an ioctl is valid Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 04/42] saa7115: add config flag to change the IDQ polarity Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 05/42] saa7115: improve querystd handling for the saa7115 Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 06/42] saa7115: add support for double-rate ASCLK Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 07/42] go7007: fix i2c_xfer return codes Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 08/42] tuner: add Sony BTF tuners Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 09/42] sony-btf-mpx: the MPX driver for the sony BTF PAL/SECAM tuner Hans Verkuil
2013-03-24 15:21     ` Mauro Carvalho Chehab
2013-03-25  8:52       ` Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 10/42] ov7640: add new ov7640 driver Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 11/42] uda1342: add new uda1342 audio codec driver Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 12/42] tw9903: add new tw9903 video decoder Hans Verkuil
2013-03-24 15:29     ` Mauro Carvalho Chehab
2013-03-24 16:06       ` Mauro Carvalho Chehab
2013-03-25  8:55       ` Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 13/42] tw2804: add support for the Techwell tw2804 Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 14/42] tw2804: modify ADC power control Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 15/42] go7007: i2c initialization changes for tw2804 Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 16/42] go7007: switch to standard tuner/i2c subdevs Hans Verkuil
2013-03-24 15:35     ` Mauro Carvalho Chehab
2013-03-11 11:45   ` [REVIEW PATCH 17/42] go7007: remove all wis* drivers Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 18/42] go7007: add audio input ioctls Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 19/42] s2250-loader: use usbv2_cypress_load_firmware Hans Verkuil
2013-03-24 15:39     ` Mauro Carvalho Chehab
2013-03-24 15:49       ` Antti Palosaari
2013-03-25  8:56       ` Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 20/42] go7007: go7007: add device_caps and bus_info support to querycap Hans Verkuil
2013-03-11 11:45   ` [REVIEW PATCH 21/42] go7007: remove current_norm Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 22/42] go7007: fix DMA related errors Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 23/42] go7007: remember boot firmware Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 24/42] go7007: fix unregister/disconnect handling Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 25/42] go7007: convert to the control framework and remove obsolete JPEGCOMP support Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 26/42] s2250: convert to the control framework Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 27/42] go7007: add prio and control event support Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 28/42] go7007: add log_status support Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 29/42] go7007: tuner/std related fixes Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 30/42] go7007: standardize MPEG handling support Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 31/42] go7007: simplify the PX-TV402U board ID handling Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 32/42] go7007: set up the saa7115 audio clock correctly Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 33/42] go7007: drop struct go7007_file Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 34/42] go7007: convert to core locking and vb2 Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 35/42] go7007: embed struct video_device Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 36/42] go7007: remove cropping functions Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 37/42] saa7134-go7007: add support for this combination Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 38/42] s2250: add comment describing the hardware Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 39/42] go7007-loader: renamed from s2250-loader Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 40/42] go7007-loader: add support for the other devices and move fw files Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 41/42] go7007: update the README Hans Verkuil
2013-03-11 11:46   ` [REVIEW PATCH 42/42] MAINTAINERS: add the go7007 driver Hans Verkuil
2013-03-11 11:50   ` [REVIEW PATCH 01/42] v4l2-ctrls: eliminate lockdep false alarms for struct v4l2_ctrl_handler.lock Hans Verkuil
2013-03-11 22:01 ` [REVIEW PATCH 00/42] go7007: complete overhaul Hans Verkuil
2013-03-12 14:37 ` Darrick Burch
2013-03-12 15:05   ` Hans Verkuil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).