浏览代码

Staging: go7007: saa7134 updates

- Added documentation including README files from the original go7007
  driver package.
- Added Video4Linux2 MPEG controls.
- Added Video4Linux2 audio ioctls, which pass thru to the i2c driver.
- Improved saa7134 interface, to pass thru controls and video settings.
- Fixed a bug in sony tuner, as reported by Bifferos on the Go7007 wiki.


Signed-off-by: Pete Eberlein <pete@sensoray.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Pete Eberlein 16 年之前
父节点
当前提交
d73f822ce7

+ 1 - 1
drivers/staging/go7007/go7007-driver.c

@@ -227,7 +227,7 @@ static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr)
 		return 0;
 	if (modname != NULL)
 		printk(KERN_INFO
-			"go7007: probing for module %s failed", modname);
+			"go7007: probing for module %s failed\n", modname);
 	else
 		printk(KERN_INFO
 			"go7007: sensor %u seems to be unsupported!\n", id);

+ 1 - 0
drivers/staging/go7007/go7007-priv.h

@@ -104,6 +104,7 @@ struct go7007_hpi_ops {
 	int (*stream_start)(struct go7007 *go);
 	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);
 };
 
 /* The video buffer size must be a multiple of PAGE_SIZE */

+ 1 - 1
drivers/staging/go7007/go7007-usb.c

@@ -225,7 +225,7 @@ static struct go7007_usb_board board_px_tv402u = {
 		.inputs 	 = {
 			{
 				.video_input	= 1,
-		.audio_input	 = TVAUDIO_INPUT_EXTERN,
+				.audio_input	= TVAUDIO_INPUT_EXTERN,
 				.name		= "Composite",
 			},
 			{

+ 268 - 13
drivers/staging/go7007/go7007-v4l2.c

@@ -38,6 +38,14 @@
 #include "go7007-priv.h"
 #include "wis-i2c.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
+#ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4
+#define	V4L2_MPEG_VIDEO_ENCODING_MPEG_4   3
+#endif
+
 static void deactivate_buffer(struct go7007_buffer *gobuf)
 {
 	int i;
@@ -375,6 +383,223 @@ static int clip_to_modet_map(struct go7007 *go, int region,
 	return 0;
 }
 
+static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
+{
+	static const u32 user_ctrls[] = {
+		V4L2_CID_USER_CLASS,
+		0
+	};
+	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[] = {
+		user_ctrls,
+		mpeg_ctrls,
+		NULL
+	};
+
+	/* The ctrl may already contain the queried i2c controls,
+	 * query the mpeg controls if the existing ctrl id is
+	 * greater than the next mpeg ctrl id.
+	 */
+	id = v4l2_ctrl_next(ctrl_classes, id);
+	if (id >= ctrl->id && ctrl->name[0])
+		return 0;
+
+	memset(ctrl, 0, sizeof(*ctrl));
+	ctrl->id = id;
+
+	switch (ctrl->id) {
+	case V4L2_CID_USER_CLASS:
+	case V4L2_CID_MPEG_CLASS:
+		return v4l2_ctrl_query_fill_std(ctrl);
+	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:
+	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+		return v4l2_ctrl_query_fill_std(ctrl);
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		return v4l2_ctrl_query_fill(ctrl,
+				64000,
+				10000000, 1,
+				9800000);
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+static int mpeg_s_control(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) {
+		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;
+		case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM:
+			/* todo: */
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		switch (ctrl->value) {
+		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:
+			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:
+		if (go->format == GO7007_FORMAT_MJPEG)
+			return -EINVAL;
+		switch (ctrl->value) {
+		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;
+		case V4L2_MPEG_VIDEO_ASPECT_221x100:
+		default:
+			return -EINVAL;
+		}
+		break;
+	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		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_control(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;
+		break;
+	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+		ctrl->value = go->closed_gop;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		ctrl->value = go->bitrate;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 {
 	struct go7007_file *gofh = file->private_data;
@@ -392,7 +617,7 @@ static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		strncpy(cap->card, go->name, sizeof(cap->card));
 		cap->version = KERNEL_VERSION(0, 9, 8);
 		cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
-				V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
+				V4L2_CAP_STREAMING | V4L2_CAP_AUDIO;
 		if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
 			cap->capabilities |= V4L2_CAP_TUNER;
 		return 0;
@@ -464,6 +689,19 @@ static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 			return -EBUSY;
 		return set_capture_size(go, fmt, 0);
 	}
+	case VIDIOC_ENUMAUDIO:
+	case VIDIOC_G_AUDIO:
+	case VIDIOC_S_AUDIO:
+	{
+		struct v4l2_audio *audio = arg;
+
+		if (!go->i2c_adapter_online)
+			return -EIO;
+		i2c_clients_command(&go->i2c_adapter, cmd, arg);
+		if (cmd == VIDIOC_ENUMAUDIO && !audio->name[0])
+			return -EINVAL;
+		return 0;
+	}
 	case VIDIOC_G_FBUF:
 	case VIDIOC_S_FBUF:
 		return -EINVAL;
@@ -699,12 +937,16 @@ static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		struct v4l2_queryctrl *ctrl = arg;
 		u32 id;
 
-		if (!go->i2c_adapter_online)
-			return -EIO;
 		id = ctrl->id;
 		memset(ctrl, 0, sizeof(*ctrl));
 		ctrl->id = id;
-		i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, arg);
+		if (go->i2c_adapter_online)
+			i2c_clients_command(&go->i2c_adapter,
+						VIDIOC_QUERYCTRL, arg);
+		else if (go->hpi_ops && go->hpi_ops->send_command)
+			go->hpi_ops->send_command(go, cmd, arg);
+		if (id & V4L2_CTRL_FLAG_NEXT_CTRL || ctrl->name[0] == 0)
+			return mpeg_queryctrl(id, ctrl);
 		return ctrl->name[0] == 0 ? -EINVAL : 0;
 	}
 	case VIDIOC_G_CTRL:
@@ -712,13 +954,16 @@ static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		struct v4l2_control *ctrl = arg;
 		struct v4l2_queryctrl query;
 
-		if (!go->i2c_adapter_online)
-			return -EIO;
 		memset(&query, 0, sizeof(query));
 		query.id = ctrl->id;
-		i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
+		if (go->i2c_adapter_online)
+			i2c_clients_command(&go->i2c_adapter,
+						VIDIOC_QUERYCTRL, &query);
+		else if (go->hpi_ops && go->hpi_ops->send_command)
+			if (0 == go->hpi_ops->send_command(go, cmd, arg))
+				return 0;
 		if (query.name[0] == 0)
-			return -EINVAL;
+			return mpeg_g_control(ctrl, go);
 		i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, arg);
 		return 0;
 	}
@@ -727,13 +972,16 @@ static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		struct v4l2_control *ctrl = arg;
 		struct v4l2_queryctrl query;
 
-		if (!go->i2c_adapter_online)
-			return -EIO;
 		memset(&query, 0, sizeof(query));
 		query.id = ctrl->id;
-		i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
+		if (go->i2c_adapter_online)
+			i2c_clients_command(&go->i2c_adapter,
+						VIDIOC_QUERYCTRL, &query);
+		else if (go->hpi_ops && go->hpi_ops->send_command)
+			if (0 == go->hpi_ops->send_command(go, cmd, arg))
+				return 0;
 		if (query.name[0] == 0)
-			return -EINVAL;
+			return mpeg_s_control(ctrl, go);
 		i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, arg);
 		return 0;
 	}
@@ -826,6 +1074,8 @@ static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 				*std = V4L2_STD_NTSC;
 			else
 				*std = V4L2_STD_PAL | V4L2_STD_SECAM;
+		} else if (go->hpi_ops && go->hpi_ops->send_command) {
+			go->hpi_ops->send_command(go, cmd, arg);
 		} else
 			*std = 0;
 		return 0;
@@ -864,6 +1114,9 @@ static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		if (go->i2c_adapter_online)
 			i2c_clients_command(&go->i2c_adapter,
 					    VIDIOC_S_STD, std);
+		if (go->hpi_ops && go->hpi_ops->send_command)
+			go->hpi_ops->send_command(go, cmd, arg);
+
 		set_capture_size(go, NULL, 0);
 		return 0;
 	}
@@ -1316,7 +1569,7 @@ static long go7007_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		return clip_to_modet_map(go, region->region, region->clips);
 	}
 	default:
-		printk(KERN_DEBUG "go7007: unsupported ioctl %d\n", cmd);
+		printk(KERN_INFO "go7007-v4l2: unsupported ioctl %d\n", cmd);
 		return -ENOIOCTLCMD;
 	}
 	return 0;
@@ -1474,6 +1727,8 @@ int go7007_v4l2_init(struct go7007 *go)
 	}
 	video_set_drvdata(go->video_dev, go);
 	++go->ref_count;
+	printk(KERN_INFO "%s: registered device video%d [v4l2]\n",
+	       go->video_dev->name, go->video_dev->num);
 
 	return 0;
 }

+ 481 - 0
drivers/staging/go7007/go7007.txt

@@ -0,0 +1,481 @@
+This is a driver for the WIS GO7007SB multi-format video encoder.
+
+Pete Eberlein <pete@sensoray.com>
+
+The driver was orignally released under the GPL and is currently hosted at:
+http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver
+The go7007 firmware can be acquired from the package on the site above.
+
+I've modified the driver to support the following Video4Linux2 MPEG
+controls, with acceptable values:
+
+V4L2_CID_MPEG_STREAM_TYPE	V4L2_MPEG_STREAM_TYPE_MPEG2_DVD
+				V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
+V4L2_CID_MPEG_VIDEO_ENCODING	V4L2_MPEG_VIDEO_ENCODING_MPEG_1
+				V4L2_MPEG_VIDEO_ENCODING_MPEG_2
+				V4L2_MPEG_VIDEO_ENCODING_MPEG_4
+V4L2_CID_MPEG_VIDEO_ASPECT	V4L2_MPEG_VIDEO_ASPECT_1x1
+				V4L2_MPEG_VIDEO_ASPECT_4x3
+				V4L2_MPEG_VIDEO_ASPECT_16x9
+V4L2_CID_MPEG_VIDEO_GOP_SIZE	integer
+V4L2_CID_MPEG_VIDEO_BITRATE	64000 .. 10000000
+
+These should be used instead of the non-standard GO7007 ioctls described
+below.
+
+
+The README files from the orignal package appear below:
+
+---------------------------------------------------------------------------
+                     WIS GO7007SB Public Linux Driver
+---------------------------------------------------------------------------
+
+
+*** Please see the file RELEASE-NOTES for important last-minute updates ***
+
+
+  0. OVERVIEW AND LICENSING/DISCLAIMER
+
+
+This driver kit contains Linux drivers for the WIS GO7007SB multi-format
+video encoder.  Only kernel version 2.6.x is supported.  The video stream
+is available through the Video4Linux2 API and the audio stream is available
+through the ALSA API (or the OSS emulation layer of the ALSA system).
+
+The files in kernel/ and hotplug/ are licensed under the GNU General Public
+License Version 2 from the Free Software Foundation.  A copy of the license
+is included in the file COPYING.
+
+The example applications in apps/ and C header files in include/ are
+licensed under a permissive license included in the source files which
+allows copying, modification and redistribution for any purpose without
+attribution.
+
+The firmware files included in the firmware/ directory may be freely
+redistributed only in conjunction with this document; but modification,
+tampering and reverse engineering are prohibited.
+
+MICRONAS USA, INC., MAKES NO WARRANTIES TO ANY PERSON OR ENTITY WITH
+RESPECT TO THE SOFTWARE OR ANY DERIVATIVES THEREOF OR ANY SERVICES OR
+LICENSES AND DISCLAIMS ALL IMPLIED WARRANTIES, INCLUDING WITHOUT LIMITATION
+WARRANTIES OF MERCHANTABILITY, SUPPORT, AND FITNESS FOR A PARTICULAR
+PURPOSE AND NON-INFRINGEMENT.
+
+
+  1. SYSTEM REQUIREMENTS
+
+
+This driver requires Linux kernel 2.6.  Kernel 2.4 is not supported.  Using
+kernel 2.6.10 or later is recommended, as earlier kernels are known to have
+unstable USB 2.0 support.
+
+A fully built kernel source tree must be available.  Typically this will be
+linked from "/lib/modules/<KERNEL VERSION>/build" for convenience.  If this
+link does not exist, an extra parameter will need to be passed to the
+`make` command.
+
+All vendor-built kernels should already be configured properly.  However,
+for custom-built kernels, the following options need to be enabled in the
+kernel as built-in or modules:
+
+        CONFIG_HOTPLUG           - Support for hot-pluggable devices
+        CONFIG_MODULES           - Enable loadable module support
+        CONFIG_KMOD              - Automatic kernel module loading
+        CONFIG_FW_LOADER         - Hotplug firmware loading support
+        CONFIG_I2C               - I2C support
+        CONFIG_VIDEO_DEV         - Video For Linux
+        CONFIG_SOUND             - Sound card support
+        CONFIG_SND               - Advanced Linux Sound Architecture
+        CONFIG_USB               - Support for Host-side USB
+        CONFIG_USB_DEVICEFS      - USB device filesystem
+        CONFIG_USB_EHCI_HCD      - EHCI HCD (USB 2.0) support
+
+Additionally, to use the example application, the following options need to
+be enabled in the ALSA section:
+
+        CONFIG_SND_MIXER_OSS     - OSS Mixer API
+        CONFIG_SND_PCM_OSS       - OSS PCM (digital audio) API
+
+The hotplug scripts, along with the fxload utility, must also be installed.
+These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>.
+Hotplugging is used for loading firmware into the Cypruss EZ-USB chip using
+fxload and for loading firmware into the driver using the firmware agent.
+
+
+  2. COMPILING AND INSTALLING THE DRIVER
+
+
+Most users should be able to compile the driver by simply running:
+
+        $ make
+
+in the top-level directory of the driver kit.  First the kernel modules
+will be built, followed by the example applications.
+
+If the build system is unable to locate the kernel source tree for the
+currently-running kernel, or if the module should be built for a kernel
+other than the currently-running kernel, an additional parameter will need
+to be passed to make to specify the appropriate kernel source directory:
+
+        $ make KERNELSRC=/usr/src/linux-2.6.10-custom3
+
+Once the compile completes, the driver and firmware files should be
+installed by running:
+
+        $ make install
+
+The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra"
+and the firmware files will be placed in the appropriate hotplug firmware
+directory, usually /lib/firmware.  In addition, USB maps and scripts will
+be placed in /etc/hotplug/usb to enable fxload to initialize the EZ-USB
+control chip when the device is connected.
+
+
+  3. PAL/SECAM TUNER CONFIGURATION (TV402U-EU only)
+
+
+The PAL model of the Plextor ConvertX TV402U may require additional
+configuration to correctly select the appropriate TV frequency band and
+audio subchannel.
+
+Users with a device other than the Plextor ConvertX TV402U-EU should skip
+this section.
+
+The wide variety of PAL TV systems used in Europe requires that additional
+information about the local TV standards be passed to the driver in order
+to properly tune TV channels.  The two necessary parameters are (a) the PAL
+TV band, and (b) the audio subchannel format in use.
+
+In many cases, the appropriate TV band selection is passed to the driver
+from applications.  However, in some cases, the application only specifies
+that the driver should use PAL but not the specific information about the
+appropriate TV band.  To work around this issue, the correct TV band may be
+specified in the "force_band" parameter to the wis-sony-tuner module:
+
+     TV band           force_band
+     -------           ----------
+     PAL B/G                B
+     PAL I                  I
+     PAL D/K                D
+     SECAM L                L
+
+If the "force_band" parameter is specified, the driver will ignore any TV
+band specified by applications and will always use the band provided in the
+module parameter.
+
+The other parameter that can be specified is the audio subchannel format.
+There are several stereo audio carrier systems in use, including NICAM and
+three varieties of A2.  To receive audio broadcast on one of these stereo
+carriers, the "force_mpx_mode" parameter must be specified to the
+wis-sony-tuner module.
+
+     TV band           Audio subcarrier       force_mpx_mode
+     -------           ----------------       --------------
+     PAL B/G            Mono (default)               1
+     PAL B/G                  A2                     2
+     PAL B/G                 NICAM                   3
+     PAL I              Mono (default)               4
+     PAL I                   NICAM                   5
+     PAL D/K            Mono (default)               6
+     PAL D/K                 A2 (1)                  7
+     PAL D/K                 A2 (2)                  8
+     PAL D/K                 A2 (3)                  9
+     PAL D/K                 NICAM                  10
+     SECAM L            Mono (default)              11
+     SECAM L                 NICAM                  12
+
+If the "force_mpx_mode" parameter is not specified, the correct mono-only
+mode will be chosen based on the TV band.  However, the tuner will not
+receive stereo audio or bilingual broadcasts correctly.
+
+To pass the "force_band" or "force_mpx_mode" parameters to the
+wis-sony-tuner module, the following line must be added to the modprobe
+configuration file, which varies from one Linux distribution to another.
+
+     options wis-sony-tuner force_band=B force_mpx_mode=2
+
+The above example would force the tuner to the PAL B/G TV band and receive
+stereo audio broadcasts on the A2 carrier.
+
+To verify that the configuration has been placed in the correct location,
+execute:
+
+        $ modprobe -c | grep wis-sony-tuner
+
+If the configuration line appears, then modprobe will pass the parameters
+correctly the next time the wis-sony-tuner module is loaded into the
+kernel.
+
+
+  4. TESTING THE DRIVER
+
+
+Because few Linux applications are able to correctly capture from
+Video4Linux2 devices with only compressed formats supported, the new driver
+should be tested with the "gorecord" application in the apps/ directory.
+
+First connect a video source to the device, such as a DVD player or VCR.
+This will be captured to a file for testing the driver.  If an input source
+is unavailable, a test file can still be captured, but the video will be
+black and the audio will be silent.
+
+This application will auto-detect the V4L2 and ALSA/OSS device names of the
+hardware and will record video and audio to an AVI file for a specified
+number of seconds.  For example:
+
+        $ apps/gorecord -duration 60 capture.avi
+
+If this application does not successfully record an AVI file, the error
+messages produced by gorecord and recorded in the system log (usually in
+/var/log/messages) should provide information to help resolve the problem.
+
+Supplying no parameters to gorecord will cause it to probe the available
+devices and exit.  Use the -help flag for usage information.
+
+
+  5. USING THE DRIVER
+
+
+The V4L2 device implemented by the driver provides a standard compressed
+format API, within the following criteria:
+
+  * Applications that only support the original Video4Linux1 API will not
+    be able to communicate with this driver at all.
+
+  * No raw video modes are supported, so applications like xawtv that
+    expect only uncompressed video will not function.
+
+  * Supported compression formats are: Motion-JPEG, MPEG1, MPEG2 and MPEG4.
+
+  * MPEG video formats are delivered as Video Elementary Streams only.
+    Program Stream (PS), Transport Stream (TS) and Packetized Elementary
+    Stream (PES) formats are not supported.
+
+  * Video parameters such as format and input port may not be changed while
+    the encoder is active.
+
+  * The audio capture device only functions when the video encoder is
+    actively capturing video.  Attempts to read from the audio device when
+    the encoder is inactive will result in an I/O error.
+
+  * The native format of the audio device is 48Khz 2-channel 16-bit
+    little-endian PCM, delivered through the ALSA system.  No audio
+    compression is implemented in the hardware.  ALSA may convert to other
+    uncompressed formats on the fly.
+
+The include/ directory contains a C header file describing non-standard
+features of the GO7007SB encoder, which are described below:
+
+
+  GO7007IOC_S_COMP_PARAMS, GO7007IOC_G_COMP_PARAMS
+
+    These ioctls are used to negotiate general compression parameters.
+
+    To query the current parameters, call the GO7007IOC_G_COMP_PARAMS ioctl
+    with a pointer to a struct go7007_comp_params.  If the driver is not
+    set to MPEG format, the EINVAL error code will be returned.
+
+    To change the current parameters, initialize all fields of a struct
+    go7007_comp_params and call the GO7007_IOC_S_COMP_PARAMS ioctl with a
+    pointer to this structure.  The driver will return the current
+    parameters with any necessary changes to conform to the limitations of
+    the hardware or current compression mode.  Any or all fields can be set
+    to zero to request a reasonable default value.  If the driver is not
+    set to MPEG format, the EINVAL error code will be returned.  When I/O
+    is in progress, the EBUSY error code will be returned.
+
+    Fields in struct go7007_comp_params:
+
+        __u32                        The maximum number of frames in each
+          gop_size                   Group Of Pictures; i.e. the maximum
+                                     number of frames minus one between
+                                     each key frame.
+
+        __u32                        The maximum number of sequential
+          max_b_frames               bidirectionally-predicted frames.
+                                     (B-frames are not yet supported.)
+
+        enum go7007_aspect_ratio     The aspect ratio to be encoded in the
+          aspect_ratio               meta-data of the compressed format.
+
+                                     Choices are:
+                                        GO7007_ASPECT_RATIO_1_1
+                                        GO7007_ASPECT_RATIO_4_3_NTSC
+                                        GO7007_ASPECT_RATIO_4_3_PAL
+                                        GO7007_ASPECT_RATIO_16_9_NTSC
+                                        GO7007_ASPECT_RATIO_16_9_PAL
+
+        __u32                        Bit-wise OR of control flags (below)
+          flags
+
+    Flags in struct go7007_comp_params:
+
+        GO7007_COMP_CLOSED_GOP       Only produce self-contained GOPs, used
+                                     to produce streams appropriate for
+                                     random seeking.
+
+        GO7007_COMP_OMIT_SEQ_HEADER  Omit the stream sequence header.
+
+
+  GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS
+
+    These ioctls are used to negotiate MPEG-specific stream parameters when
+    the pixelformat has been set to V4L2_PIX_FMT_MPEG.
+
+    To query the current parameters, call the GO7007IOC_G_MPEG_PARAMS ioctl
+    with a pointer to a struct go7007_mpeg_params.  If the driver is not
+    set to MPEG format, the EINVAL error code will be returned.
+
+    To change the current parameters, initialize all fields of a struct
+    go7007_mpeg_params and call the GO7007_IOC_S_MPEG_PARAMS ioctl with a
+    pointer to this structure.  The driver will return the current
+    parameters with any necessary changes to conform to the limitations of
+    the hardware or selected MPEG mode.  Any or all fields can be set to
+    zero to request a reasonable default value.  If the driver is not set
+    to MPEG format, the EINVAL error code will be returned.  When I/O is in
+    progress, the EBUSY error code will be returned.
+
+    Fields in struct go7007_mpeg_params:
+
+        enum go7007_mpeg_video_standard
+          mpeg_video_standard        The MPEG video standard in which to
+                                     compress the video.
+
+                                     Choices are:
+                                        GO7007_MPEG_VIDEO_MPEG1
+                                        GO7007_MPEG_VIDEO_MPEG2
+                                        GO7007_MPEG_VIDEO_MPEG4
+
+        __u32                        Bit-wise OR of control flags (below)
+          flags
+
+        __u32                        The profile and level indication to be
+          pali                       stored in the sequence header.  This
+                                     is only used as an indicator to the
+                                     decoder, and does not affect the MPEG
+                                     features used in the video stream.
+                                     Not valid for MPEG1.
+
+                                     Choices for MPEG2 are:
+                                        GO7007_MPEG2_PROFILE_MAIN_MAIN
+
+                                     Choices for MPEG4 are:
+                                        GO7007_MPEG4_PROFILE_S_L0
+                                        GO7007_MPEG4_PROFILE_S_L1
+                                        GO7007_MPEG4_PROFILE_S_L2
+                                        GO7007_MPEG4_PROFILE_S_L3
+                                        GO7007_MPEG4_PROFILE_ARTS_L1
+                                        GO7007_MPEG4_PROFILE_ARTS_L2
+                                        GO7007_MPEG4_PROFILE_ARTS_L3
+                                        GO7007_MPEG4_PROFILE_ARTS_L4
+                                        GO7007_MPEG4_PROFILE_AS_L0
+                                        GO7007_MPEG4_PROFILE_AS_L1
+                                        GO7007_MPEG4_PROFILE_AS_L2
+                                        GO7007_MPEG4_PROFILE_AS_L3
+                                        GO7007_MPEG4_PROFILE_AS_L4
+                                        GO7007_MPEG4_PROFILE_AS_L5
+
+    Flags in struct go7007_mpeg_params:
+
+        GO7007_MPEG_FORCE_DVD_MODE   Force all compression parameters and
+                                     bitrate control settings to comply
+                                     with DVD MPEG2 stream requirements.
+                                     This overrides most compression and
+                                     bitrate settings!
+
+        GO7007_MPEG_OMIT_GOP_HEADER  Omit the GOP header.
+
+        GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at
+                                     the start of each GOP.
+
+
+  GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE
+
+    These ioctls are used to set and query the target bitrate value for the
+    compressed video stream.  The bitrate may be selected by storing the
+    target bits per second in an int and calling GO7007IOC_S_BITRATE with a
+    pointer to the int.  The bitrate may be queried by calling
+    GO7007IOC_G_BITRATE with a pointer to an int where the current bitrate
+    will be stored.
+
+    Note that this is the primary means of controlling the video quality
+    for all compression modes, including V4L2_PIX_FMT_MJPEG.  The
+    VIDIOC_S_JPEGCOMP ioctl is not supported.
+
+
+----------------------------------------------------------------------------
+                   Installing the WIS PCI Voyager Driver
+---------------------------------------------------------------------------
+
+The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x
+kernel source tree before compiling the driver.  These patches update the
+in-kernel SAA7134 driver to the newest development version and patch bugs
+in the TDA8290/TDA8275 tuner driver.
+
+The following patches must be downloaded from Gerd Knorr's website and
+applied in the order listed:
+
+	http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner
+	http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner2
+	http://dl.bytesex.org/patches/2.6.11-2/v4l2-api-mpeg
+	http://dl.bytesex.org/patches/2.6.11-2/saa7134-update
+
+The following patches are included with this SDK and can be applied in any
+order:
+
+	patches/2.6.11/saa7134-voyager.diff
+	patches/2.6.11/tda8275-newaddr.diff
+	patches/2.6.11/tda8290-ntsc.diff
+
+Check to make sure the CONFIG_VIDEO_SAA7134 option is enabled in the kernel
+configuration, and build and install the kernel.
+
+After rebooting into the new kernel, the GO7007 driver can be compiled and
+installed:
+
+	$ make SAA7134_BUILD=y
+	$ make install
+	$ modprobe saa7134-go7007
+
+There will be two V4L video devices associated with the PCI Voyager.  The
+first device (most likely /dev/video0) provides access to the raw video
+capture mode of the SAA7133 device and is used to configure the source
+video parameters and tune the TV tuner.  This device can be used with xawtv
+or other V4L(2) video software as a standard uncompressed device.
+
+The second device (most likely /dev/video1) provides access to the
+compression functions of the GO7007.  It can be tested using the gorecord
+application in the apps/ directory of this SDK:
+
+	$ apps/gorecord -vdevice /dev/video1 -noaudio test.avi
+
+Currently the frame resolution is fixed at 720x480 (NTSC) or 720x576 (PAL),
+and the video standard must be specified to both the raw and the compressed
+video devices (xawtv and gorecord, for example).
+
+
+--------------------------------------------------------------------------
+RELEASE NOTES FOR WIS GO7007SB LINUX DRIVER
+---------------------------------------------------------------------------
+
+Last updated: 5 November 2005
+
+ - Release 0.9.7 includes new support for using udev to run fxload.  The
+   install script should automatically detect whether the old hotplug
+   scripts or the new udev rules should be used.  To force the use of
+   hotplug, run "make install USE_UDEV=n".  To force the use of udev, run
+   "make install USE_UDEV=y".
+
+ - Motion detection is supported but undocumented.  Try the `modet` app
+   for a demonstration of how to use the facility.
+
+ - Using USB2.0 devices such as the TV402U with USB1.1 HCDs or hubs can
+   cause buffer overruns and frame drops, even at low framerates, due to
+   inconsistency in the bitrate control mechanism.
+
+ - On devices with an SAA7115, including the Plextor ConvertX, video height
+   values of 96, 128, 160, 192, 256, 320, and 384 do not work in NTSC mode.
+   All valid heights up to 512 work correctly in PAL mode.
+
+ - The WIS Star Trek and PCI Voyager boards have no support yet for audio
+   or the TV tuner.

+ 50 - 2
drivers/staging/go7007/saa7134-go7007.c

@@ -27,7 +27,7 @@
 #include <linux/usb.h>
 #include <linux/i2c.h>
 #include <asm/byteorder.h>
-#include <media/audiochip.h>
+#include <media/v4l2-common.h>
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
@@ -314,7 +314,13 @@ static int saa7134_go7007_stream_start(struct go7007 *go)
 static int saa7134_go7007_stream_stop(struct go7007 *go)
 {
 	struct saa7134_go7007 *saa = go->hpi_context;
-	struct saa7134_dev *dev = saa->dev;
+	struct saa7134_dev *dev;
+
+	if (!saa)
+		return -EINVAL;
+	dev = saa->dev;
+	if (!dev)
+		return -EINVAL;
 
 	/* Shut down TS FIFO */
 	saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
@@ -373,6 +379,47 @@ 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,
@@ -380,6 +427,7 @@ 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,
 };
 
 /********************* Add/remove functions *********************/

+ 1 - 1
drivers/staging/go7007/wis-sony-tuner.c

@@ -604,7 +604,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 	{
 		struct v4l2_tuner *tun = arg;
 
-		memset(t, 0, sizeof(*tun));
+		memset(tun, 0, sizeof(*tun));
 		strcpy(tun->name, "Television");
 		tun->type = V4L2_TUNER_ANALOG_TV;
 		tun->rangelow = 0UL; /* does anything use these? */