Staging: go7007: saa7134 updates
Pete Eberlein [Thu, 30 Oct 2008 19:56:33 +0000 (12:56 -0700)]
- 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>

drivers/staging/go7007/go7007-driver.c
drivers/staging/go7007/go7007-priv.h
drivers/staging/go7007/go7007-usb.c
drivers/staging/go7007/go7007-v4l2.c
drivers/staging/go7007/go7007.txt [new file with mode: 0644]
drivers/staging/go7007/saa7134-go7007.c
drivers/staging/go7007/wis-sony-tuner.c

index e4ead96..510c23b 100644 (file)
@@ -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);
index 005542d..f61d983 100644 (file)
@@ -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 */
index 3f5ee34..04cc144 100644 (file)
@@ -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",
                        },
                        {
index dfbc2e9..e0b17a0 100644 (file)
 #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;
 }
diff --git a/drivers/staging/go7007/go7007.txt b/drivers/staging/go7007/go7007.txt
new file mode 100644 (file)
index 0000000..9f6772b
--- /dev/null
@@ -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.
index c4a6d8e..665bbf5 100644 (file)
@@ -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 *********************/
index 5a91ee4..58fddb1 100644 (file)
@@ -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? */