[media] go7007: move out of staging into drivers/media/usb.
authorHans Verkuil <hans.verkuil@cisco.com>
Tue, 22 Jul 2014 04:21:37 +0000 (06:21 +0200)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Tue, 22 Jul 2014 15:53:33 +0000 (12:53 -0300)
Now that the custom motion detection API in this driver has been
replaced with a standard API there is no reason anymore to keep it
in staging. So (finally!) move it to drivers/media/usb.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
29 files changed:
drivers/media/usb/Kconfig
drivers/media/usb/Makefile
drivers/media/usb/go7007/Kconfig [new file with mode: 0644]
drivers/media/usb/go7007/Makefile [new file with mode: 0644]
drivers/media/usb/go7007/go7007-driver.c [new file with mode: 0644]
drivers/media/usb/go7007/go7007-fw.c [new file with mode: 0644]
drivers/media/usb/go7007/go7007-i2c.c [new file with mode: 0644]
drivers/media/usb/go7007/go7007-loader.c [new file with mode: 0644]
drivers/media/usb/go7007/go7007-priv.h [new file with mode: 0644]
drivers/media/usb/go7007/go7007-usb.c [new file with mode: 0644]
drivers/media/usb/go7007/go7007-v4l2.c [new file with mode: 0644]
drivers/media/usb/go7007/s2250-board.c [new file with mode: 0644]
drivers/media/usb/go7007/snd-go7007.c [new file with mode: 0644]
drivers/staging/media/Kconfig
drivers/staging/media/Makefile
drivers/staging/media/go7007/Kconfig [deleted file]
drivers/staging/media/go7007/Makefile [deleted file]
drivers/staging/media/go7007/README [deleted file]
drivers/staging/media/go7007/go7007-driver.c [deleted file]
drivers/staging/media/go7007/go7007-fw.c [deleted file]
drivers/staging/media/go7007/go7007-i2c.c [deleted file]
drivers/staging/media/go7007/go7007-loader.c [deleted file]
drivers/staging/media/go7007/go7007-priv.h [deleted file]
drivers/staging/media/go7007/go7007-usb.c [deleted file]
drivers/staging/media/go7007/go7007-v4l2.c [deleted file]
drivers/staging/media/go7007/go7007.txt [deleted file]
drivers/staging/media/go7007/s2250-board.c [deleted file]
drivers/staging/media/go7007/saa7134-go7007.c [deleted file]
drivers/staging/media/go7007/snd-go7007.c [deleted file]

index fa67519abda2c1b781babeb7cc33db1b66ac94a7..94d51e092db34a4df56fb49570dd5e2de3af0895 100644 (file)
@@ -27,6 +27,7 @@ source "drivers/media/usb/hdpvr/Kconfig"
 source "drivers/media/usb/tlg2300/Kconfig"
 source "drivers/media/usb/usbvision/Kconfig"
 source "drivers/media/usb/stk1160/Kconfig"
+source "drivers/media/usb/go7007/Kconfig"
 endif
 
 if (MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT)
index 712a6b1e888201436247fa9b20c35ca354dc14e7..f438efffefc59e027a1241fc7a30b42774b416c8 100644 (file)
@@ -22,3 +22,4 @@ obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
 obj-$(CONFIG_VIDEO_TM6000) += tm6000/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
 obj-$(CONFIG_VIDEO_USBTV) += usbtv/
+obj-$(CONFIG_VIDEO_GO7007) += go7007/
diff --git a/drivers/media/usb/go7007/Kconfig b/drivers/media/usb/go7007/Kconfig
new file mode 100644 (file)
index 0000000..95a3af6
--- /dev/null
@@ -0,0 +1,51 @@
+config VIDEO_GO7007
+       tristate "WIS GO7007 MPEG encoder support"
+       depends on VIDEO_DEV && I2C
+       depends on SND && USB
+       select VIDEOBUF2_VMALLOC
+       select VIDEO_TUNER
+       select CYPRESS_FIRMWARE
+       select SND_PCM
+       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_TW9906 if MEDIA_SUBDRV_AUTOSELECT
+       select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT
+       select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT
+       ---help---
+         This is a video4linux driver for the WIS GO7007 MPEG
+         encoder chip.
+
+         To compile this driver as a module, choose M here: the
+         module will be called go7007.
+
+config VIDEO_GO7007_USB
+       tristate "WIS GO7007 USB support"
+       depends on VIDEO_GO7007 && USB
+       ---help---
+         This is a video4linux 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-usb.
+
+config VIDEO_GO7007_LOADER
+       tristate "WIS GO7007 Loader support"
+       depends on VIDEO_GO7007
+       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 && USB
+       ---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.
diff --git a/drivers/media/usb/go7007/Makefile b/drivers/media/usb/go7007/Makefile
new file mode 100644 (file)
index 0000000..e99287c
--- /dev/null
@@ -0,0 +1,11 @@
+obj-$(CONFIG_VIDEO_GO7007) += go7007.o
+obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.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
+
+s2250-y := s2250-board.o
+
+ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/common
diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c
new file mode 100644 (file)
index 0000000..95cffb7
--- /dev/null
@@ -0,0 +1,766 @@
+/*
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/unistd.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/firmware.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <media/tuner.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+
+#include "go7007-priv.h"
+
+/*
+ * Wait for an interrupt to be delivered from the GO7007SB and return
+ * the associated value and data.
+ *
+ * Must be called with the hw_lock held.
+ */
+int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
+{
+       go->interrupt_available = 0;
+       go->hpi_ops->read_interrupt(go);
+       if (wait_event_timeout(go->interrupt_waitq,
+                               go->interrupt_available, 5*HZ) < 0) {
+               v4l2_err(&go->v4l2_dev, "timeout waiting for read interrupt\n");
+               return -1;
+       }
+       if (!go->interrupt_available)
+               return -1;
+       go->interrupt_available = 0;
+       *value = go->interrupt_value & 0xfffe;
+       *data = go->interrupt_data;
+       return 0;
+}
+EXPORT_SYMBOL(go7007_read_interrupt);
+
+/*
+ * Read a register/address on the GO7007SB.
+ *
+ * Must be called with the hw_lock held.
+ */
+int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data)
+{
+       int count = 100;
+       u16 value;
+
+       if (go7007_write_interrupt(go, 0x0010, addr) < 0)
+               return -EIO;
+       while (count-- > 0) {
+               if (go7007_read_interrupt(go, &value, data) == 0 &&
+                               value == 0xa000)
+                       return 0;
+       }
+       return -EIO;
+}
+EXPORT_SYMBOL(go7007_read_addr);
+
+/*
+ * Send the boot firmware to the encoder, which just wakes it up and lets
+ * us talk to the GPIO pins and on-board I2C adapter.
+ *
+ * Must be called with the hw_lock held.
+ */
+static int go7007_load_encoder(struct go7007 *go)
+{
+       const struct firmware *fw_entry;
+       char fw_name[] = "go7007/go7007fw.bin";
+       void *bounce;
+       int fw_len, rv = 0;
+       u16 intr_val, intr_data;
+
+       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);
+               go->boot_fw_len = fw_len;
+               go->boot_fw = bounce;
+       }
+       if (go7007_interface_reset(go) < 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;
+       }
+       return rv;
+}
+
+MODULE_FIRMWARE("go7007/go7007fw.bin");
+
+/*
+ * Boot the encoder and register the I2C adapter if requested.  Do the
+ * minimum initialization necessary, since the board-specific code may
+ * still need to probe the board ID.
+ *
+ * Must NOT be called with the hw_lock held.
+ */
+int go7007_boot_encoder(struct go7007 *go, int init_i2c)
+{
+       int ret;
+
+       mutex_lock(&go->hw_lock);
+       ret = go7007_load_encoder(go);
+       mutex_unlock(&go->hw_lock);
+       if (ret < 0)
+               return -1;
+       if (!init_i2c)
+               return 0;
+       if (go7007_i2c_init(go) < 0)
+               return -1;
+       go->i2c_adapter_online = 1;
+       return 0;
+}
+EXPORT_SYMBOL(go7007_boot_encoder);
+
+/*
+ * Configure any hardware-related registers in the GO7007, such as GPIO
+ * pins and bus parameters, which are board-specific.  This assumes
+ * the boot firmware has already been downloaded.
+ *
+ * Must be called with the hw_lock held.
+ */
+static int go7007_init_encoder(struct go7007 *go)
+{
+       if (go->board_info->audio_flags & GO7007_AUDIO_I2S_MASTER) {
+               go7007_write_addr(go, 0x1000, 0x0811);
+               go7007_write_addr(go, 0x1000, 0x0c11);
+       }
+       switch (go->board_id) {
+       case GO7007_BOARDID_MATRIX_REV:
+               /* Set GPIO pin 0 to be an output (audio clock control) */
+               go7007_write_addr(go, 0x3c82, 0x0001);
+               go7007_write_addr(go, 0x3c80, 0x00fe);
+               break;
+       case GO7007_BOARDID_ADLINK_MPG24:
+               /* set GPIO5 to be an output, currently low */
+               go7007_write_addr(go, 0x3c82, 0x0000);
+               go7007_write_addr(go, 0x3c80, 0x00df);
+               break;
+       case GO7007_BOARDID_ADS_USBAV_709:
+               /* GPIO pin 0: audio clock control */
+               /*      pin 2: TW9906 reset */
+               /*      pin 3: capture LED */
+               go7007_write_addr(go, 0x3c82, 0x000d);
+               go7007_write_addr(go, 0x3c80, 0x00f2);
+               break;
+       }
+       return 0;
+}
+
+/*
+ * Send the boot firmware to the GO7007 and configure the registers.  This
+ * is the only way to stop the encoder once it has started streaming video.
+ *
+ * Must be called with the hw_lock held.
+ */
+int go7007_reset_encoder(struct go7007 *go)
+{
+       if (go7007_load_encoder(go) < 0)
+               return -1;
+       return go7007_init_encoder(go);
+}
+
+/*
+ * Attempt to instantiate an I2C client by ID, probably loading a module.
+ */
+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 v4l2_subdev *sd;
+       struct i2c_board_info info;
+
+       memset(&info, 0, sizeof(info));
+       strlcpy(info.type, i2c->type, sizeof(info.type));
+       info.addr = i2c->addr;
+       info.flags = i2c->flags;
+
+       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;
+       }
+
+       pr_info("go7007: probing for module i2c:%s failed\n", i2c->type);
+       return -EINVAL;
+}
+
+/*
+ * 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) {
+               i2c_del_adapter(&go->i2c_adapter);
+               go->i2c_adapter_online = 0;
+       }
+
+       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
+ * interfaces.
+ *
+ * Must NOT be called with the hw_lock held.
+ */
+int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
+{
+       int i, ret;
+
+       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 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) {
+               ret = go7007_i2c_init(go);
+               if (ret < 0)
+                       return ret;
+               go->i2c_adapter_online = 1;
+       }
+       if (go->i2c_adapter_online) {
+               if (go->board_id == GO7007_BOARDID_ADS_USBAV_709) {
+                       /* Reset the TW9906 */
+                       go7007_write_addr(go, 0x3c82, 0x0009);
+                       msleep(50);
+                       go7007_write_addr(go, 0x3c82, 0x000d);
+               }
+               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)
+                       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);
+       }
+       return 0;
+}
+EXPORT_SYMBOL(go7007_register_encoder);
+
+/*
+ * Send the encode firmware to the encoder, which will cause it
+ * to immediately start delivering the video and audio streams.
+ *
+ * Must be called with the hw_lock held.
+ */
+int go7007_start_encoder(struct go7007 *go)
+{
+       u8 *fw;
+       int fw_len, rv = 0, i, x, y;
+       u16 intr_val, intr_data;
+
+       go->modet_enable = 0;
+       for (i = 0; i < 4; i++)
+               go->modet[i].enable = 0;
+
+       switch (v4l2_ctrl_g_ctrl(go->modet_mode)) {
+       case V4L2_DETECT_MD_MODE_GLOBAL:
+               memset(go->modet_map, 0, sizeof(go->modet_map));
+               go->modet[0].enable = 1;
+               go->modet_enable = 1;
+               break;
+       case V4L2_DETECT_MD_MODE_REGION_GRID:
+               for (y = 0; y < go->height / 16; y++) {
+                       for (x = 0; x < go->width / 16; x++) {
+                               int idx = y * go->width / 16 + x;
+
+                               go->modet[go->modet_map[idx]].enable = 1;
+                       }
+               }
+               go->modet_enable = 1;
+               break;
+       }
+
+       if (go->dvd_mode)
+               go->modet_enable = 0;
+
+       if (go7007_construct_fw_image(go, &fw, &fw_len) < 0)
+               return -1;
+
+       if (go7007_send_firmware(go, fw, fw_len) < 0 ||
+                       go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
+               v4l2_err(&go->v4l2_dev, "error transferring firmware\n");
+               rv = -1;
+               goto start_error;
+       }
+
+       go->state = STATE_DATA;
+       go->parse_length = 0;
+       go->seen_frame = 0;
+       if (go7007_stream_start(go) < 0) {
+               v4l2_err(&go->v4l2_dev, "error starting stream transfer\n");
+               rv = -1;
+               goto start_error;
+       }
+
+start_error:
+       kfree(fw);
+       return rv;
+}
+
+/*
+ * Store a byte in the current video buffer, if there is one.
+ */
+static inline void store_byte(struct go7007_buffer *vb, u8 byte)
+{
+       if (vb && vb->vb.v4l2_planes[0].bytesused < GO7007_BUF_SIZE) {
+               u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
+
+               ptr[vb->vb.v4l2_planes[0].bytesused++] = byte;
+       }
+}
+
+static void go7007_set_motion_regions(struct go7007 *go, struct go7007_buffer *vb,
+               u32 motion_regions)
+{
+       if (motion_regions != go->modet_event_status) {
+               struct v4l2_event ev = {
+                       .type = V4L2_EVENT_MOTION_DET,
+                       .u.motion_det = {
+                               .flags = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ,
+                               .frame_sequence = vb->vb.v4l2_buf.sequence,
+                               .region_mask = motion_regions,
+                       },
+               };
+
+               v4l2_event_queue(&go->vdev, &ev);
+               go->modet_event_status = motion_regions;
+       }
+}
+
+/*
+ * Determine regions with motion and send a motion detection event
+ * in case of changes.
+ */
+static void go7007_motion_regions(struct go7007 *go, struct go7007_buffer *vb)
+{
+       u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused;
+       unsigned motion[4] = { 0, 0, 0, 0 };
+       u32 motion_regions = 0;
+       unsigned stride = (go->width + 7) >> 3;
+       unsigned x, y;
+       int i;
+
+       for (i = 0; i < 216; ++i)
+               store_byte(vb, go->active_map[i]);
+       for (y = 0; y < go->height / 16; y++) {
+               for (x = 0; x < go->width / 16; x++) {
+                       if (!(go->active_map[y * stride + (x >> 3)] & (1 << (x & 7))))
+                               continue;
+                       motion[go->modet_map[y * (go->width / 16) + x]]++;
+               }
+       }
+       motion_regions = ((motion[0] > 0) << 0) |
+                        ((motion[1] > 0) << 1) |
+                        ((motion[2] > 0) << 2) |
+                        ((motion[3] > 0) << 3);
+       *bytesused -= 216;
+       go7007_set_motion_regions(go, vb, motion_regions);
+}
+
+/*
+ * Deliver the last video buffer and get a new one to start writing to.
+ */
+static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buffer *vb)
+{
+       u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused;
+       struct go7007_buffer *vb_tmp = NULL;
+
+       if (vb == NULL) {
+               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;
+       }
+
+       vb->vb.v4l2_buf.sequence = go->next_seq++;
+       if (vb->modet_active && *bytesused + 216 < GO7007_BUF_SIZE)
+               go7007_motion_regions(go, vb);
+       else
+               go7007_set_motion_regions(go, vb, 0);
+
+       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;
+}
+
+static void write_bitmap_word(struct go7007 *go)
+{
+       int x, y, i, stride = ((go->width >> 4) + 7) >> 3;
+
+       for (i = 0; i < 16; ++i) {
+               y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4);
+               x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4);
+               if (stride * y + (x >> 3) < sizeof(go->active_map))
+                       go->active_map[stride * y + (x >> 3)] |=
+                                       (go->modet_word & 1) << (x & 0x7);
+               go->modet_word >>= 1;
+       }
+}
+
+/*
+ * Parse a chunk of the video stream into frames.  The frames are not
+ * delimited by the hardware, so we have to parse the frame boundaries
+ * based on the type of video stream we're receiving.
+ */
+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, gop_start_code = -1, frame_start_code = -1;
+
+       switch (go->format) {
+       case V4L2_PIX_FMT_MPEG4:
+               seq_start_code = 0xB0;
+               gop_start_code = 0xB3;
+               frame_start_code = 0xB6;
+               break;
+       case V4L2_PIX_FMT_MPEG1:
+       case V4L2_PIX_FMT_MPEG2:
+               seq_start_code = 0xB3;
+               gop_start_code = 0xB8;
+               frame_start_code = 0x00;
+               break;
+       }
+
+       for (i = 0; i < length; ++i) {
+               if (vb && vb->vb.v4l2_planes[0].bytesused >= GO7007_BUF_SIZE - 3) {
+                       v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
+                       vb->vb.v4l2_planes[0].bytesused = 0;
+                       vb->frame_offset = 0;
+                       vb->modet_active = 0;
+                       vb = go->active_buf = NULL;
+               }
+
+               switch (go->state) {
+               case STATE_DATA:
+                       switch (buf[i]) {
+                       case 0x00:
+                               go->state = STATE_00;
+                               break;
+                       case 0xFF:
+                               go->state = STATE_FF;
+                               break;
+                       default:
+                               store_byte(vb, buf[i]);
+                               break;
+                       }
+                       break;
+               case STATE_00:
+                       switch (buf[i]) {
+                       case 0x00:
+                               go->state = STATE_00_00;
+                               break;
+                       case 0xFF:
+                               store_byte(vb, 0x00);
+                               go->state = STATE_FF;
+                               break;
+                       default:
+                               store_byte(vb, 0x00);
+                               store_byte(vb, buf[i]);
+                               go->state = STATE_DATA;
+                               break;
+                       }
+                       break;
+               case STATE_00_00:
+                       switch (buf[i]) {
+                       case 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(vb, 0x00);
+                               store_byte(vb, 0x00);
+                               go->state = STATE_FF;
+                               break;
+                       default:
+                               store_byte(vb, 0x00);
+                               store_byte(vb, 0x00);
+                               store_byte(vb, buf[i]);
+                               go->state = STATE_DATA;
+                               break;
+                       }
+                       break;
+               case STATE_00_00_01:
+                       if (buf[i] == 0xF8 && go->modet_enable == 0) {
+                               /* MODET start code, but MODET not enabled */
+                               store_byte(vb, 0x00);
+                               store_byte(vb, 0x00);
+                               store_byte(vb, 0x01);
+                               store_byte(vb, 0xF8);
+                               go->state = STATE_DATA;
+                               break;
+                       }
+                       /* If this is the start of a new MPEG frame,
+                        * get a new buffer */
+                       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] == gop_start_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 */
+                       switch (buf[i]) {
+                       case 0xF5: /* timestamp */
+                               go->parse_length = 12;
+                               go->state = STATE_UNPARSED;
+                               break;
+                       case 0xF6: /* vbi */
+                               go->state = STATE_VBI_LEN_A;
+                               break;
+                       case 0xF8: /* MD map */
+                               go->parse_length = 0;
+                               memset(go->active_map, 0,
+                                               sizeof(go->active_map));
+                               go->state = STATE_MODET_MAP;
+                               break;
+                       case 0xFF: /* Potential JPEG start code */
+                               store_byte(vb, 0x00);
+                               store_byte(vb, 0x00);
+                               store_byte(vb, 0x01);
+                               go->state = STATE_FF;
+                               break;
+                       default:
+                               store_byte(vb, 0x00);
+                               store_byte(vb, 0x00);
+                               store_byte(vb, 0x01);
+                               store_byte(vb, buf[i]);
+                               go->state = STATE_DATA;
+                               break;
+                       }
+                       break;
+               case STATE_FF:
+                       switch (buf[i]) {
+                       case 0x00:
+                               store_byte(vb, 0xFF);
+                               go->state = STATE_00;
+                               break;
+                       case 0xFF:
+                               store_byte(vb, 0xFF);
+                               /* go->state remains STATE_FF */
+                               break;
+                       case 0xD8:
+                               if (go->format == V4L2_PIX_FMT_MJPEG)
+                                       vb = frame_boundary(go, vb);
+                               /* fall through */
+                       default:
+                               store_byte(vb, 0xFF);
+                               store_byte(vb, buf[i]);
+                               go->state = STATE_DATA;
+                               break;
+                       }
+                       break;
+               case STATE_VBI_LEN_A:
+                       go->parse_length = buf[i] << 8;
+                       go->state = STATE_VBI_LEN_B;
+                       break;
+               case STATE_VBI_LEN_B:
+                       go->parse_length |= buf[i];
+                       if (go->parse_length > 0)
+                               go->state = STATE_UNPARSED;
+                       else
+                               go->state = STATE_DATA;
+                       break;
+               case STATE_MODET_MAP:
+                       if (go->parse_length < 204) {
+                               if (go->parse_length & 1) {
+                                       go->modet_word |= buf[i];
+                                       write_bitmap_word(go);
+                               } else
+                                       go->modet_word = buf[i] << 8;
+                       } else if (go->parse_length == 207 && vb) {
+                               vb->modet_active = buf[i];
+                       }
+                       if (++go->parse_length == 208)
+                               go->state = STATE_DATA;
+                       break;
+               case STATE_UNPARSED:
+                       if (--go->parse_length == 0)
+                               go->state = STATE_DATA;
+                       break;
+               }
+       }
+}
+EXPORT_SYMBOL(go7007_parse_video_stream);
+
+/*
+ * Allocate a new go7007 struct.  Used by the hardware-specific probe.
+ */
+struct go7007 *go7007_alloc(const struct go7007_board_info *board,
+                                               struct device *dev)
+{
+       struct go7007 *go;
+       int i;
+
+       go = kzalloc(sizeof(struct go7007), GFP_KERNEL);
+       if (go == NULL)
+               return NULL;
+       go->dev = dev;
+       go->board_info = board;
+       go->board_id = 0;
+       go->tuner_type = -1;
+       go->channel_number = 0;
+       go->name[0] = 0;
+       mutex_init(&go->hw_lock);
+       init_waitqueue_head(&go->frame_waitq);
+       spin_lock_init(&go->spinlock);
+       go->status = STATUS_INIT;
+       memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
+       go->i2c_adapter_online = 0;
+       go->interrupt_available = 0;
+       init_waitqueue_head(&go->interrupt_waitq);
+       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->bitrate = 1500000;
+       go->fps_scale = 1;
+       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;
+       go->interlace_coding = 0;
+       for (i = 0; i < 4; ++i)
+               go->modet[i].enable = 0;
+       for (i = 0; i < 1624; ++i)
+               go->modet_map[i] = 0;
+       go->audio_deliver = NULL;
+       go->audio_enabled = 0;
+
+       return go;
+}
+EXPORT_SYMBOL(go7007_alloc);
+
+void go7007_update_board(struct go7007 *go)
+{
+       const 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/media/usb/go7007/go7007-fw.c b/drivers/media/usb/go7007/go7007-fw.c
new file mode 100644 (file)
index 0000000..5f4c9b9
--- /dev/null
@@ -0,0 +1,1628 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file contains code to generate a firmware image for the GO7007SB
+ * encoder.  Much of the firmware is read verbatim from a file, but some of
+ * it concerning bitrate control and other things that can be configured at
+ * run-time are generated dynamically.  Note that the format headers
+ * generated here do not affect the functioning of the encoder; they are
+ * merely parroted back to the host at the start of each frame.
+ */
+
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <asm/byteorder.h>
+
+#include "go7007-priv.h"
+
+#define GO7007_FW_NAME "go7007/go7007tv.bin"
+
+/* Constants used in the source firmware image to describe code segments */
+
+#define        FLAG_MODE_MJPEG         (1)
+#define        FLAG_MODE_MPEG1         (1<<1)
+#define        FLAG_MODE_MPEG2         (1<<2)
+#define        FLAG_MODE_MPEG4         (1<<3)
+#define        FLAG_MODE_H263          (1<<4)
+#define FLAG_MODE_ALL          (FLAG_MODE_MJPEG | FLAG_MODE_MPEG1 | \
+                                       FLAG_MODE_MPEG2 | FLAG_MODE_MPEG4 | \
+                                       FLAG_MODE_H263)
+#define FLAG_SPECIAL           (1<<8)
+
+#define SPECIAL_FRM_HEAD       0
+#define SPECIAL_BRC_CTRL       1
+#define SPECIAL_CONFIG         2
+#define SPECIAL_SEQHEAD                3
+#define SPECIAL_AV_SYNC                4
+#define SPECIAL_FINAL          5
+#define SPECIAL_AUDIO          6
+#define SPECIAL_MODET          7
+
+/* Little data class for creating MPEG headers bit-by-bit */
+
+struct code_gen {
+       unsigned char *p; /* destination */
+       u32 a; /* collects bits at the top of the variable */
+       int b; /* bit position of most recently-written bit */
+       int len; /* written out so far */
+};
+
+#define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 }
+
+#define CODE_ADD(name, val, length) do { \
+       name.b -= (length); \
+       name.a |= (val) << name.b; \
+       while (name.b <= 24) { \
+               *name.p = name.a >> 24; \
+               ++name.p; \
+               name.a <<= 8; \
+               name.b += 8; \
+               name.len += 8; \
+       } \
+} while (0)
+
+#define CODE_LENGTH(name) (name.len + (32 - name.b))
+
+/* Tables for creating the bitrate control data */
+
+static const s16 converge_speed_ip[101] = {
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+       1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+       2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
+       3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
+       5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
+       9, 10, 10, 11, 12, 13, 14, 15, 16, 17,
+       19, 20, 22, 23, 25, 27, 30, 32, 35, 38,
+       41, 45, 49, 53, 58, 63, 69, 76, 83, 91,
+       100
+};
+
+static const s16 converge_speed_ipb[101] = {
+       3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+       3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+       3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
+       4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
+       6, 6, 6, 7, 7, 7, 7, 8, 8, 9,
+       9, 9, 10, 10, 11, 12, 12, 13, 14, 14,
+       15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
+       28, 30, 32, 34, 37, 40, 42, 46, 49, 53,
+       57, 61, 66, 71, 77, 83, 90, 97, 106, 115,
+       125, 135, 147, 161, 175, 191, 209, 228, 249, 273,
+       300
+};
+
+static const s16 LAMBDA_table[4][101] = {
+       {       16, 16, 16, 16, 17, 17, 17, 18, 18, 18,
+               19, 19, 19, 20, 20, 20, 21, 21, 22, 22,
+               22, 23, 23, 24, 24, 25, 25, 25, 26, 26,
+               27, 27, 28, 28, 29, 29, 30, 31, 31, 32,
+               32, 33, 33, 34, 35, 35, 36, 37, 37, 38,
+               39, 39, 40, 41, 42, 42, 43, 44, 45, 46,
+               46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+               56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+               67, 68, 69, 70, 72, 73, 74, 76, 77, 78,
+               80, 81, 83, 84, 86, 87, 89, 90, 92, 94,
+               96
+       },
+       {
+               20, 20, 20, 21, 21, 21, 22, 22, 23, 23,
+               23, 24, 24, 25, 25, 26, 26, 27, 27, 28,
+               28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
+               34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
+               40, 41, 42, 43, 43, 44, 45, 46, 47, 48,
+               48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+               58, 59, 60, 61, 62, 64, 65, 66, 67, 68,
+               70, 71, 72, 73, 75, 76, 78, 79, 80, 82,
+               83, 85, 86, 88, 90, 91, 93, 95, 96, 98,
+               100, 102, 103, 105, 107, 109, 111, 113, 115, 117,
+               120
+       },
+       {
+               24, 24, 24, 25, 25, 26, 26, 27, 27, 28,
+               28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
+               34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
+               41, 41, 42, 43, 44, 44, 45, 46, 47, 48,
+               49, 50, 50, 51, 52, 53, 54, 55, 56, 57,
+               58, 59, 60, 62, 63, 64, 65, 66, 67, 69,
+               70, 71, 72, 74, 75, 76, 78, 79, 81, 82,
+               84, 85, 87, 88, 90, 92, 93, 95, 97, 98,
+               100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
+               120, 122, 124, 127, 129, 131, 134, 136, 138, 141,
+               144
+       },
+       {
+               32, 32, 33, 33, 34, 34, 35, 36, 36, 37,
+               38, 38, 39, 40, 41, 41, 42, 43, 44, 44,
+               45, 46, 47, 48, 49, 50, 50, 51, 52, 53,
+               54, 55, 56, 57, 58, 59, 60, 62, 63, 64,
+               65, 66, 67, 69, 70, 71, 72, 74, 75, 76,
+               78, 79, 81, 82, 84, 85, 87, 88, 90, 92,
+               93, 95, 97, 98, 100, 102, 104, 106, 108, 110,
+               112, 114, 116, 118, 120, 122, 124, 127, 129, 131,
+               134, 136, 139, 141, 144, 146, 149, 152, 154, 157,
+               160, 163, 166, 169, 172, 175, 178, 181, 185, 188,
+               192
+       }
+};
+
+/* MPEG blank frame generation tables */
+
+enum mpeg_frame_type {
+       PFRAME,
+       BFRAME_PRE,
+       BFRAME_POST,
+       BFRAME_BIDIR,
+       BFRAME_EMPTY
+};
+
+static const u32 addrinctab[33][2] = {
+       { 0x01, 1 },    { 0x03, 3 },    { 0x02, 3 },    { 0x03, 4 },
+       { 0x02, 4 },    { 0x03, 5 },    { 0x02, 5 },    { 0x07, 7 },
+       { 0x06, 7 },    { 0x0b, 8 },    { 0x0a, 8 },    { 0x09, 8 },
+       { 0x08, 8 },    { 0x07, 8 },    { 0x06, 8 },    { 0x17, 10 },
+       { 0x16, 10 },   { 0x15, 10 },   { 0x14, 10 },   { 0x13, 10 },
+       { 0x12, 10 },   { 0x23, 11 },   { 0x22, 11 },   { 0x21, 11 },
+       { 0x20, 11 },   { 0x1f, 11 },   { 0x1e, 11 },   { 0x1d, 11 },
+       { 0x1c, 11 },   { 0x1b, 11 },   { 0x1a, 11 },   { 0x19, 11 },
+       { 0x18, 11 }
+};
+
+/* Standard JPEG tables */
+
+static const u8 default_intra_quant_table[] = {
+        8, 16, 19, 22, 26, 27, 29, 34,
+       16, 16, 22, 24, 27, 29, 34, 37,
+       19, 22, 26, 27, 29, 34, 34, 38,
+       22, 22, 26, 27, 29, 34, 37, 40,
+       22, 26, 27, 29, 32, 35, 40, 48,
+       26, 27, 29, 32, 35, 40, 48, 58,
+       26, 27, 29, 34, 38, 46, 56, 69,
+       27, 29, 35, 38, 46, 56, 69, 83
+};
+
+static const u8 bits_dc_luminance[] = {
+       0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const u8 val_dc_luminance[] = {
+       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+
+static const u8 bits_dc_chrominance[] = {
+       0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
+};
+
+static const u8 val_dc_chrominance[] = {
+       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+
+static const u8 bits_ac_luminance[] = {
+       0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
+};
+
+static const u8 val_ac_luminance[] = {
+       0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+       0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+       0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+       0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+       0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+       0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+       0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+       0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+       0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+       0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+       0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+       0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+       0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+       0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+       0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+       0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+       0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+       0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+       0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+       0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+       0xf9, 0xfa
+};
+
+static const u8 bits_ac_chrominance[] = {
+       0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
+};
+
+static const u8 val_ac_chrominance[] = {
+       0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+       0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+       0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+       0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+       0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+       0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+       0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+       0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+       0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+       0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+       0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+       0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+       0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+       0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+       0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+       0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+       0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+       0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+       0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+       0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+       0xf9, 0xfa
+};
+
+/* Zig-zag mapping for quant table
+ *
+ * OK, let's do this mapping on the actual table above so it doesn't have
+ * to be done on the fly.
+ */
+static const int zz[64] = {
+       0,   1,  8, 16,  9,  2,  3, 10, 17, 24, 32, 25, 18, 11,  4,  5,
+       12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13,  6,  7, 14, 21, 28,
+       35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
+       58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static int copy_packages(__le16 *dest, u16 *src, int pkg_cnt, int space)
+{
+       int i, cnt = pkg_cnt * 32;
+
+       if (space < cnt)
+               return -1;
+
+       for (i = 0; i < cnt; ++i)
+               dest[i] = cpu_to_le16p(src + i);
+
+       return cnt;
+}
+
+static int mjpeg_frame_header(struct go7007 *go, unsigned char *buf, int q)
+{
+       int i, p = 0;
+
+       buf[p++] = 0xff;
+       buf[p++] = 0xd8;
+       buf[p++] = 0xff;
+       buf[p++] = 0xdb;
+       buf[p++] = 0;
+       buf[p++] = 2 + 65;
+       buf[p++] = 0;
+       buf[p++] = default_intra_quant_table[0];
+       for (i = 1; i < 64; ++i)
+               /* buf[p++] = (default_intra_quant_table[i] * q) >> 3; */
+               buf[p++] = (default_intra_quant_table[zz[i]] * q) >> 3;
+       buf[p++] = 0xff;
+       buf[p++] = 0xc0;
+       buf[p++] = 0;
+       buf[p++] = 17;
+       buf[p++] = 8;
+       buf[p++] = go->height >> 8;
+       buf[p++] = go->height & 0xff;
+       buf[p++] = go->width >> 8;
+       buf[p++] = go->width & 0xff;
+       buf[p++] = 3;
+       buf[p++] = 1;
+       buf[p++] = 0x22;
+       buf[p++] = 0;
+       buf[p++] = 2;
+       buf[p++] = 0x11;
+       buf[p++] = 0;
+       buf[p++] = 3;
+       buf[p++] = 0x11;
+       buf[p++] = 0;
+       buf[p++] = 0xff;
+       buf[p++] = 0xc4;
+       buf[p++] = 418 >> 8;
+       buf[p++] = 418 & 0xff;
+       buf[p++] = 0x00;
+       memcpy(buf + p, bits_dc_luminance + 1, 16);
+       p += 16;
+       memcpy(buf + p, val_dc_luminance, sizeof(val_dc_luminance));
+       p += sizeof(val_dc_luminance);
+       buf[p++] = 0x01;
+       memcpy(buf + p, bits_dc_chrominance + 1, 16);
+       p += 16;
+       memcpy(buf + p, val_dc_chrominance, sizeof(val_dc_chrominance));
+       p += sizeof(val_dc_chrominance);
+       buf[p++] = 0x10;
+       memcpy(buf + p, bits_ac_luminance + 1, 16);
+       p += 16;
+       memcpy(buf + p, val_ac_luminance, sizeof(val_ac_luminance));
+       p += sizeof(val_ac_luminance);
+       buf[p++] = 0x11;
+       memcpy(buf + p, bits_ac_chrominance + 1, 16);
+       p += 16;
+       memcpy(buf + p, val_ac_chrominance, sizeof(val_ac_chrominance));
+       p += sizeof(val_ac_chrominance);
+       buf[p++] = 0xff;
+       buf[p++] = 0xda;
+       buf[p++] = 0;
+       buf[p++] = 12;
+       buf[p++] = 3;
+       buf[p++] = 1;
+       buf[p++] = 0x00;
+       buf[p++] = 2;
+       buf[p++] = 0x11;
+       buf[p++] = 3;
+       buf[p++] = 0x11;
+       buf[p++] = 0;
+       buf[p++] = 63;
+       buf[p++] = 0;
+       return p;
+}
+
+static int gen_mjpeghdr_to_package(struct go7007 *go, __le16 *code, int space)
+{
+       u8 *buf;
+       u16 mem = 0x3e00;
+       unsigned int addr = 0x19;
+       int size = 0, i, off = 0, chunk;
+
+       buf = kzalloc(4096, GFP_KERNEL);
+       if (buf == NULL)
+               return -1;
+
+       for (i = 1; i < 32; ++i) {
+               mjpeg_frame_header(go, buf + size, i);
+               size += 80;
+       }
+       chunk = mjpeg_frame_header(go, buf + size, 1);
+       memmove(buf + size, buf + size + 80, chunk - 80);
+       size += chunk - 80;
+
+       for (i = 0; i < size; i += chunk * 2) {
+               if (space - off < 32) {
+                       off = -1;
+                       goto done;
+               }
+
+               code[off + 1] = __cpu_to_le16(0x8000 | mem);
+
+               chunk = 28;
+               if (mem + chunk > 0x4000)
+                       chunk = 0x4000 - mem;
+               if (i + 2 * chunk > size)
+                       chunk = (size - i) / 2;
+
+               if (chunk < 28) {
+                       code[off] = __cpu_to_le16(0x4000 | chunk);
+                       code[off + 31] = __cpu_to_le16(addr++);
+                       mem = 0x3e00;
+               } else {
+                       code[off] = __cpu_to_le16(0x1000 | 28);
+                       code[off + 31] = 0;
+                       mem += 28;
+               }
+
+               memcpy(&code[off + 2], buf + i, chunk * 2);
+               off += 32;
+       }
+done:
+       kfree(buf);
+       return off;
+}
+
+static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
+               int modulo, int pict_struct, enum mpeg_frame_type frame)
+{
+       int i, j, mb_code, mb_len;
+       int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
+       CODE_GEN(c, buf + 6);
+
+       switch (frame) {
+       case PFRAME:
+               mb_code = 0x1;
+               mb_len = 3;
+               break;
+       case BFRAME_PRE:
+               mb_code = 0x2;
+               mb_len = 4;
+               break;
+       case BFRAME_POST:
+               mb_code = 0x2;
+               mb_len = 3;
+               break;
+       case BFRAME_BIDIR:
+               mb_code = 0x2;
+               mb_len = 2;
+               break;
+       default: /* keep the compiler happy */
+               mb_code = mb_len = 0;
+               break;
+       }
+
+       CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13);
+       CODE_ADD(c, 0xffff, 16);
+       CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4);
+       if (frame != PFRAME)
+               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?? */
+       /* Byte-align with zeros */
+       j = 8 - (CODE_LENGTH(c) % 8);
+       if (j != 8)
+               CODE_ADD(c, 0, j);
+
+       if (go->format == V4L2_PIX_FMT_MPEG2) {
+               CODE_ADD(c, 0x1, 24);
+               CODE_ADD(c, 0xb5, 8);
+               CODE_ADD(c, 0x844, 12);
+               CODE_ADD(c, frame == PFRAME ? 0xff : 0x44, 8);
+               if (go->interlace_coding) {
+                       CODE_ADD(c, pict_struct, 4);
+                       if (go->dvd_mode)
+                               CODE_ADD(c, 0x000, 11);
+                       else
+                               CODE_ADD(c, 0x200, 11);
+               } else {
+                       CODE_ADD(c, 0x3, 4);
+                       CODE_ADD(c, 0x20c, 11);
+               }
+               /* Byte-align with zeros */
+               j = 8 - (CODE_LENGTH(c) % 8);
+               if (j != 8)
+                       CODE_ADD(c, 0, j);
+       }
+
+       for (i = 0; i < rows; ++i) {
+               CODE_ADD(c, 1, 24);
+               CODE_ADD(c, i + 1, 8);
+               CODE_ADD(c, 0x2, 6);
+               CODE_ADD(c, 0x1, 1);
+               CODE_ADD(c, mb_code, mb_len);
+               if (go->interlace_coding) {
+                       CODE_ADD(c, 0x1, 2);
+                       CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
+               }
+               if (frame == BFRAME_BIDIR) {
+                       CODE_ADD(c, 0x3, 2);
+                       if (go->interlace_coding)
+                               CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
+               }
+               CODE_ADD(c, 0x3, 2);
+               for (j = (go->width >> 4) - 2; j >= 33; j -= 33)
+                       CODE_ADD(c, 0x8, 11);
+               CODE_ADD(c, addrinctab[j][0], addrinctab[j][1]);
+               CODE_ADD(c, mb_code, mb_len);
+               if (go->interlace_coding) {
+                       CODE_ADD(c, 0x1, 2);
+                       CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
+               }
+               if (frame == BFRAME_BIDIR) {
+                       CODE_ADD(c, 0x3, 2);
+                       if (go->interlace_coding)
+                               CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
+               }
+               CODE_ADD(c, 0x3, 2);
+
+               /* Byte-align with zeros */
+               j = 8 - (CODE_LENGTH(c) % 8);
+               if (j != 8)
+                       CODE_ADD(c, 0, j);
+       }
+
+       i = CODE_LENGTH(c) + 4 * 8;
+       buf[2] = 0x00;
+       buf[3] = 0x00;
+       buf[4] = 0x01;
+       buf[5] = 0x00;
+       return i;
+}
+
+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 == V4L2_PIX_FMT_MPEG1) {
+               switch (go->aspect_ratio) {
+               case GO7007_RATIO_4_3:
+                       aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
+                       break;
+               case GO7007_RATIO_16_9:
+                       aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
+                       break;
+               default:
+                       aspect_ratio = 1;
+                       break;
+               }
+       } else {
+               switch (go->aspect_ratio) {
+               case GO7007_RATIO_4_3:
+                       aspect_ratio = 2;
+                       break;
+               case GO7007_RATIO_16_9:
+                       aspect_ratio = 3;
+                       break;
+               default:
+                       aspect_ratio = 1;
+                       break;
+               }
+       }
+       switch (go->sensor_framerate) {
+       case 24000:
+               picture_rate = 1;
+               break;
+       case 24024:
+               picture_rate = 2;
+               break;
+       case 25025:
+               picture_rate = go->interlace_coding ? 6 : 3;
+               break;
+       case 30000:
+               picture_rate = go->interlace_coding ? 7 : 4;
+               break;
+       case 30030:
+               picture_rate = go->interlace_coding ? 8 : 5;
+               break;
+       default:
+               picture_rate = 5; /* 30 fps seems like a reasonable default */
+               break;
+       }
+
+       CODE_ADD(c, go->width, 12);
+       CODE_ADD(c, go->height, 12);
+       CODE_ADD(c, aspect_ratio, 4);
+       CODE_ADD(c, picture_rate, 4);
+       CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 20000 : 0x3ffff, 18);
+       CODE_ADD(c, 1, 1);
+       CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 112 : 20, 10);
+       CODE_ADD(c, 0, 3);
+
+       /* Byte-align with zeros */
+       i = 8 - (CODE_LENGTH(c) % 8);
+       if (i != 8)
+               CODE_ADD(c, 0, i);
+
+       if (go->format == V4L2_PIX_FMT_MPEG2) {
+               CODE_ADD(c, 0x1, 24);
+               CODE_ADD(c, 0xb5, 8);
+               CODE_ADD(c, 0x148, 12);
+               if (go->interlace_coding)
+                       CODE_ADD(c, 0x20001, 20);
+               else
+                       CODE_ADD(c, 0xa0001, 20);
+               CODE_ADD(c, 0, 16);
+
+               /* Byte-align with zeros */
+               i = 8 - (CODE_LENGTH(c) % 8);
+               if (i != 8)
+                       CODE_ADD(c, 0, i);
+
+               if (ext) {
+                       CODE_ADD(c, 0x1, 24);
+                       CODE_ADD(c, 0xb52, 12);
+                       CODE_ADD(c, go->standard == GO7007_STD_NTSC ? 2 : 1, 3);
+                       CODE_ADD(c, 0x105, 9);
+                       CODE_ADD(c, 0x505, 16);
+                       CODE_ADD(c, go->width, 14);
+                       CODE_ADD(c, 1, 1);
+                       CODE_ADD(c, go->height, 14);
+
+                       /* Byte-align with zeros */
+                       i = 8 - (CODE_LENGTH(c) % 8);
+                       if (i != 8)
+                               CODE_ADD(c, 0, i);
+               }
+       }
+
+       i = CODE_LENGTH(c) + 4 * 8;
+       buf[0] = i & 0xff;
+       buf[1] = i >> 8;
+       buf[2] = 0x00;
+       buf[3] = 0x00;
+       buf[4] = 0x01;
+       buf[5] = 0xb3;
+       return i;
+}
+
+static int gen_mpeg1hdr_to_package(struct go7007 *go,
+                                       __le16 *code, int space, int *framelen)
+{
+       u8 *buf;
+       u16 mem = 0x3e00;
+       unsigned int addr = 0x19;
+       int i, off = 0, chunk;
+
+       buf = kzalloc(5120, GFP_KERNEL);
+       if (buf == NULL)
+               return -1;
+
+       framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME);
+       if (go->interlace_coding)
+               framelen[0] += mpeg1_frame_header(go, buf + framelen[0] / 8,
+                                                       0, 2, PFRAME);
+       buf[0] = framelen[0] & 0xff;
+       buf[1] = framelen[0] >> 8;
+       i = 368;
+       framelen[1] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_PRE);
+       if (go->interlace_coding)
+               framelen[1] += mpeg1_frame_header(go, buf + i + framelen[1] / 8,
+                                                       0, 2, BFRAME_PRE);
+       buf[i] = framelen[1] & 0xff;
+       buf[i + 1] = framelen[1] >> 8;
+       i += 1632;
+       framelen[2] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_POST);
+       if (go->interlace_coding)
+               framelen[2] += mpeg1_frame_header(go, buf + i + framelen[2] / 8,
+                                                       0, 2, BFRAME_POST);
+       buf[i] = framelen[2] & 0xff;
+       buf[i + 1] = framelen[2] >> 8;
+       i += 1432;
+       framelen[3] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_BIDIR);
+       if (go->interlace_coding)
+               framelen[3] += mpeg1_frame_header(go, buf + i + framelen[3] / 8,
+                                                       0, 2, BFRAME_BIDIR);
+       buf[i] = framelen[3] & 0xff;
+       buf[i + 1] = framelen[3] >> 8;
+       i += 1632 + 16;
+       mpeg1_sequence_header(go, buf + i, 0);
+       i += 40;
+       for (i = 0; i < 5120; i += chunk * 2) {
+               if (space - off < 32) {
+                       off = -1;
+                       goto done;
+               }
+
+               code[off + 1] = __cpu_to_le16(0x8000 | mem);
+
+               chunk = 28;
+               if (mem + chunk > 0x4000)
+                       chunk = 0x4000 - mem;
+               if (i + 2 * chunk > 5120)
+                       chunk = (5120 - i) / 2;
+
+               if (chunk < 28) {
+                       code[off] = __cpu_to_le16(0x4000 | chunk);
+                       code[off + 31] = __cpu_to_le16(addr);
+                       if (mem + chunk == 0x4000) {
+                               mem = 0x3e00;
+                               ++addr;
+                       }
+               } else {
+                       code[off] = __cpu_to_le16(0x1000 | 28);
+                       code[off + 31] = 0;
+                       mem += 28;
+               }
+
+               memcpy(&code[off + 2], buf + i, chunk * 2);
+               off += 32;
+       }
+done:
+       kfree(buf);
+       return off;
+}
+
+static int vti_bitlen(struct go7007 *go)
+{
+       unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
+
+       for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i)
+               ;
+       return i + 1;
+}
+
+static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
+               int modulo, enum mpeg_frame_type frame)
+{
+       int i;
+       CODE_GEN(c, buf + 6);
+       int mb_count = (go->width >> 4) * (go->height >> 4);
+
+       CODE_ADD(c, frame == PFRAME ? 0x1 : 0x2, 2);
+       if (modulo)
+               CODE_ADD(c, 0x1, 1);
+       CODE_ADD(c, 0x1, 2);
+       CODE_ADD(c, 0, vti_bitlen(go));
+       CODE_ADD(c, 0x3, 2);
+       if (frame == PFRAME)
+               CODE_ADD(c, 0, 1);
+       CODE_ADD(c, 0xc, 11);
+       if (frame != PFRAME)
+               CODE_ADD(c, 0x4, 3);
+       if (frame != BFRAME_EMPTY) {
+               for (i = 0; i < mb_count; ++i) {
+                       switch (frame) {
+                       case PFRAME:
+                               CODE_ADD(c, 0x1, 1);
+                               break;
+                       case BFRAME_PRE:
+                               CODE_ADD(c, 0x47, 8);
+                               break;
+                       case BFRAME_POST:
+                               CODE_ADD(c, 0x27, 7);
+                               break;
+                       case BFRAME_BIDIR:
+                               CODE_ADD(c, 0x5f, 8);
+                               break;
+                       case BFRAME_EMPTY: /* keep compiler quiet */
+                               break;
+                       }
+               }
+       }
+
+       /* Byte-align with a zero followed by ones */
+       i = 8 - (CODE_LENGTH(c) % 8);
+       CODE_ADD(c, 0, 1);
+       CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
+
+       i = CODE_LENGTH(c) + 4 * 8;
+       buf[0] = i & 0xff;
+       buf[1] = i >> 8;
+       buf[2] = 0x00;
+       buf[3] = 0x00;
+       buf[4] = 0x01;
+       buf[5] = 0xb6;
+       return i;
+}
+
+static int mpeg4_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
+{
+       const unsigned char head[] = { 0x00, 0x00, 0x01, 0xb0, go->pali,
+               0x00, 0x00, 0x01, 0xb5, 0x09,
+               0x00, 0x00, 0x01, 0x00,
+               0x00, 0x00, 0x01, 0x20, };
+       int i, aspect_ratio;
+       int fps = go->sensor_framerate / go->fps_scale;
+       CODE_GEN(c, buf + 2 + sizeof(head));
+
+       switch (go->aspect_ratio) {
+       case GO7007_RATIO_4_3:
+               aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
+               break;
+       case GO7007_RATIO_16_9:
+               aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
+               break;
+       default:
+               aspect_ratio = 1;
+               break;
+       }
+
+       memcpy(buf + 2, head, sizeof(head));
+       CODE_ADD(c, 0x191, 17);
+       CODE_ADD(c, aspect_ratio, 4);
+       CODE_ADD(c, 0x1, 4);
+       CODE_ADD(c, fps, 16);
+       CODE_ADD(c, 0x3, 2);
+       CODE_ADD(c, 1001, vti_bitlen(go));
+       CODE_ADD(c, 1, 1);
+       CODE_ADD(c, go->width, 13);
+       CODE_ADD(c, 1, 1);
+       CODE_ADD(c, go->height, 13);
+       CODE_ADD(c, 0x2830, 14);
+
+       /* Byte-align */
+       i = 8 - (CODE_LENGTH(c) % 8);
+       CODE_ADD(c, 0, 1);
+       CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
+
+       i = CODE_LENGTH(c) + sizeof(head) * 8;
+       buf[0] = i & 0xff;
+       buf[1] = i >> 8;
+       return i;
+}
+
+static int gen_mpeg4hdr_to_package(struct go7007 *go,
+                                       __le16 *code, int space, int *framelen)
+{
+       u8 *buf;
+       u16 mem = 0x3e00;
+       unsigned int addr = 0x19;
+       int i, off = 0, chunk;
+
+       buf = kzalloc(5120, GFP_KERNEL);
+       if (buf == NULL)
+               return -1;
+
+       framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME);
+       i = 368;
+       framelen[1] = mpeg4_frame_header(go, buf + i, 0, BFRAME_PRE);
+       i += 1632;
+       framelen[2] = mpeg4_frame_header(go, buf + i, 0, BFRAME_POST);
+       i += 1432;
+       framelen[3] = mpeg4_frame_header(go, buf + i, 0, BFRAME_BIDIR);
+       i += 1632;
+       mpeg4_frame_header(go, buf + i, 0, BFRAME_EMPTY);
+       i += 16;
+       mpeg4_sequence_header(go, buf + i, 0);
+       i += 40;
+       for (i = 0; i < 5120; i += chunk * 2) {
+               if (space - off < 32) {
+                       off = -1;
+                       goto done;
+               }
+
+               code[off + 1] = __cpu_to_le16(0x8000 | mem);
+
+               chunk = 28;
+               if (mem + chunk > 0x4000)
+                       chunk = 0x4000 - mem;
+               if (i + 2 * chunk > 5120)
+                       chunk = (5120 - i) / 2;
+
+               if (chunk < 28) {
+                       code[off] = __cpu_to_le16(0x4000 | chunk);
+                       code[off + 31] = __cpu_to_le16(addr);
+                       if (mem + chunk == 0x4000) {
+                               mem = 0x3e00;
+                               ++addr;
+                       }
+               } else {
+                       code[off] = __cpu_to_le16(0x1000 | 28);
+                       code[off + 31] = 0;
+                       mem += 28;
+               }
+
+               memcpy(&code[off + 2], buf + i, chunk * 2);
+               off += 32;
+       }
+       mem = 0x3e00;
+       addr = go->ipb ? 0x14f9 : 0x0af9;
+       memset(buf, 0, 5120);
+       framelen[4] = mpeg4_frame_header(go, buf, 1, PFRAME);
+       i = 368;
+       framelen[5] = mpeg4_frame_header(go, buf + i, 1, BFRAME_PRE);
+       i += 1632;
+       framelen[6] = mpeg4_frame_header(go, buf + i, 1, BFRAME_POST);
+       i += 1432;
+       framelen[7] = mpeg4_frame_header(go, buf + i, 1, BFRAME_BIDIR);
+       i += 1632;
+       mpeg4_frame_header(go, buf + i, 1, BFRAME_EMPTY);
+       i += 16;
+       for (i = 0; i < 5120; i += chunk * 2) {
+               if (space - off < 32) {
+                       off = -1;
+                       goto done;
+               }
+
+               code[off + 1] = __cpu_to_le16(0x8000 | mem);
+
+               chunk = 28;
+               if (mem + chunk > 0x4000)
+                       chunk = 0x4000 - mem;
+               if (i + 2 * chunk > 5120)
+                       chunk = (5120 - i) / 2;
+
+               if (chunk < 28) {
+                       code[off] = __cpu_to_le16(0x4000 | chunk);
+                       code[off + 31] = __cpu_to_le16(addr);
+                       if (mem + chunk == 0x4000) {
+                               mem = 0x3e00;
+                               ++addr;
+                       }
+               } else {
+                       code[off] = __cpu_to_le16(0x1000 | 28);
+                       code[off + 31] = 0;
+                       mem += 28;
+               }
+
+               memcpy(&code[off + 2], buf + i, chunk * 2);
+               off += 32;
+       }
+done:
+       kfree(buf);
+       return off;
+}
+
+static int brctrl_to_package(struct go7007 *go,
+                                       __le16 *code, int space, int *framelen)
+{
+       int converge_speed = 0;
+       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 == V4L2_PIX_FMT_MJPEG ?
+                               go->bitrate :
+                               (go->dvd_mode ? 900000 : peak_rate);
+       int fps = go->sensor_framerate / go->fps_scale;
+       int q = 0;
+       /* Bizarre math below depends on rounding errors in division */
+       u32 sgop_expt_addr = go->bitrate / 32 * (go->ipb ? 3 : 1) * 1001 / fps;
+       u32 sgop_peak_addr = peak_rate / 32 * 1001 / fps;
+       u32 total_expt_addr = go->bitrate / 32 * 1000 / fps * (fps / 1000);
+       u32 vbv_alert_addr = vbv_buffer * 3 / (4 * 32);
+       u32 cplx[] = {
+               q > 0 ? sgop_expt_addr * q :
+                       2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
+               q > 0 ? sgop_expt_addr * q :
+                       2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
+               q > 0 ? sgop_expt_addr * q :
+                       2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
+               q > 0 ? sgop_expt_addr * q :
+                       2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
+       };
+       u32 calc_q = q > 0 ? q : cplx[0] / sgop_expt_addr;
+       u16 pack[] = {
+               0x200e,         0x0000,
+               0xBF20,         go->ipb ? converge_speed_ipb[converge_speed]
+                                       : converge_speed_ip[converge_speed],
+               0xBF21,         go->ipb ? 2 : 0,
+               0xBF22,         go->ipb ? LAMBDA_table[0][lambda / 2 + 50]
+                                       : 32767,
+               0xBF23,         go->ipb ? LAMBDA_table[1][lambda] : 32767,
+               0xBF24,         32767,
+               0xBF25,         lambda > 99 ? 32767 : LAMBDA_table[3][lambda],
+               0xBF26,         sgop_expt_addr & 0x0000FFFF,
+               0xBF27,         sgop_expt_addr >> 16,
+               0xBF28,         sgop_peak_addr & 0x0000FFFF,
+               0xBF29,         sgop_peak_addr >> 16,
+               0xBF2A,         vbv_alert_addr & 0x0000FFFF,
+               0xBF2B,         vbv_alert_addr >> 16,
+               0xBF2C,         0,
+               0xBF2D,         0,
+               0,              0,
+
+               0x200e,         0x0000,
+               0xBF2E,         vbv_alert_addr & 0x0000FFFF,
+               0xBF2F,         vbv_alert_addr >> 16,
+               0xBF30,         cplx[0] & 0x0000FFFF,
+               0xBF31,         cplx[0] >> 16,
+               0xBF32,         cplx[1] & 0x0000FFFF,
+               0xBF33,         cplx[1] >> 16,
+               0xBF34,         cplx[2] & 0x0000FFFF,
+               0xBF35,         cplx[2] >> 16,
+               0xBF36,         cplx[3] & 0x0000FFFF,
+               0xBF37,         cplx[3] >> 16,
+               0xBF38,         0,
+               0xBF39,         0,
+               0xBF3A,         total_expt_addr & 0x0000FFFF,
+               0xBF3B,         total_expt_addr >> 16,
+               0,              0,
+
+               0x200e,         0x0000,
+               0xBF3C,         total_expt_addr & 0x0000FFFF,
+               0xBF3D,         total_expt_addr >> 16,
+               0xBF3E,         0,
+               0xBF3F,         0,
+               0xBF48,         0,
+               0xBF49,         0,
+               0xBF4A,         calc_q < 4 ? 4 : (calc_q > 124 ? 124 : calc_q),
+               0xBF4B,         4,
+               0xBF4C,         0,
+               0xBF4D,         0,
+               0xBF4E,         0,
+               0xBF4F,         0,
+               0xBF50,         0,
+               0xBF51,         0,
+               0,              0,
+
+               0x200e,         0x0000,
+               0xBF40,         sgop_expt_addr & 0x0000FFFF,
+               0xBF41,         sgop_expt_addr >> 16,
+               0xBF42,         0,
+               0xBF43,         0,
+               0xBF44,         0,
+               0xBF45,         0,
+               0xBF46,         (go->width >> 4) * (go->height >> 4),
+               0xBF47,         0,
+               0xBF64,         0,
+               0xBF65,         0,
+               0xBF18,         framelen[4],
+               0xBF19,         framelen[5],
+               0xBF1A,         framelen[6],
+               0xBF1B,         framelen[7],
+               0,              0,
+
+#if 0
+               /* Remove once we don't care about matching */
+               0x200e,         0x0000,
+               0xBF56,         4,
+               0xBF57,         0,
+               0xBF58,         5,
+               0xBF59,         0,
+               0xBF5A,         6,
+               0xBF5B,         0,
+               0xBF5C,         8,
+               0xBF5D,         0,
+               0xBF5E,         1,
+               0xBF5F,         0,
+               0xBF60,         1,
+               0xBF61,         0,
+               0xBF62,         0,
+               0xBF63,         0,
+               0,              0,
+#else
+               0x2008,         0x0000,
+               0xBF56,         4,
+               0xBF57,         0,
+               0xBF58,         5,
+               0xBF59,         0,
+               0xBF5A,         6,
+               0xBF5B,         0,
+               0xBF5C,         8,
+               0xBF5D,         0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+#endif
+
+               0x200e,         0x0000,
+               0xBF10,         0,
+               0xBF11,         0,
+               0xBF12,         0,
+               0xBF13,         0,
+               0xBF14,         0,
+               0xBF15,         0,
+               0xBF16,         0,
+               0xBF17,         0,
+               0xBF7E,         0,
+               0xBF7F,         1,
+               0xBF52,         framelen[0],
+               0xBF53,         framelen[1],
+               0xBF54,         framelen[2],
+               0xBF55,         framelen[3],
+               0,              0,
+       };
+
+       return copy_packages(code, pack, 6, space);
+}
+
+static int config_package(struct go7007 *go, __le16 *code, int space)
+{
+       int fps = go->sensor_framerate / go->fps_scale / 1000;
+       int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
+       int brc_window_size = fps;
+       int q_min = 2, q_max = 31;
+       int THACCoeffSet0 = 0;
+       u16 pack[] = {
+               0x200e,         0x0000,
+               0xc002,         0x14b4,
+               0xc003,         0x28b4,
+               0xc004,         0x3c5a,
+               0xdc05,         0x2a77,
+               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,
+               0xc60f,         0x0008,
+               0xd4ff,         0x0002,
+               0xe403,         2340,
+               0xe406,         75,
+               0xd411,         0x0001,
+               0xd410,         0xa1d6,
+               0x0001,         0x2801,
+
+               0x200d,         0x0000,
+               0xe402,         0x018b,
+               0xe401,         0x8b01,
+               0xd472,         (go->board_info->sensor_flags &
+                                                       GO7007_SENSOR_TV) &&
+                                               (!go->interlace_coding) ?
+                                       0x01b0 : 0x0170,
+               0xd475,         (go->board_info->sensor_flags &
+                                                       GO7007_SENSOR_TV) &&
+                                               (!go->interlace_coding) ?
+                                       0x0008 : 0x0009,
+               0xc404,         go->interlace_coding ? 0x44 :
+                               (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 == 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),
+               0xbf0b,         0,
+               0xdd5a,         go->ipb ? 0x14 : 0x0a,
+               0xbf0c,         0,
+               0xbf0d,         0,
+               0xc683,         THACCoeffSet0,
+               0xc40a,         (go->width << 4) | rows,
+               0xe01a,         go->board_info->hpi_buffer_cap,
+               0,              0,
+               0,              0,
+
+               0x2008,         0,
+               0xe402,         0x88,
+               0xe401,         0x8f01,
+               0xbf6a,         0,
+               0xbf6b,         0,
+               0xbf6c,         0,
+               0xbf6d,         0,
+               0xbf6e,         0,
+               0xbf6f,         0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+
+               0x200e,         0,
+               0xbf66,         brc_window_size,
+               0xbf67,         0,
+               0xbf68,         q_min,
+               0xbf69,         q_max,
+               0xbfe0,         0,
+               0xbfe1,         0,
+               0xbfe2,         0,
+               0xbfe3,         go->ipb ? 3 : 1,
+               0xc031,         go->board_info->sensor_flags &
+                                       GO7007_SENSOR_VBI ? 1 : 0,
+               0xc01c,         0x1f,
+               0xdd8c,         0x15,
+               0xdd94,         0x15,
+               0xdd88,         go->ipb ? 0x1401 : 0x0a01,
+               0xdd90,         go->ipb ? 0x1401 : 0x0a01,
+               0,              0,
+
+               0x200e,         0,
+               0xbfe4,         0,
+               0xbfe5,         0,
+               0xbfe6,         0,
+               0xbfe7,         fps << 8,
+               0xbfe8,         0x3a00,
+               0xbfe9,         0,
+               0xbfea,         0,
+               0xbfeb,         0,
+               0xbfec,         (go->interlace_coding ? 1 << 15 : 0) |
+                                       (go->modet_enable ? 0xa : 0) |
+                                       (go->board_info->sensor_flags &
+                                               GO7007_SENSOR_VBI ? 1 : 0),
+               0xbfed,         0,
+               0xbfee,         0,
+               0xbfef,         0,
+               0xbff0,         go->board_info->sensor_flags &
+                                       GO7007_SENSOR_TV ? 0xf060 : 0xb060,
+               0xbff1,         0,
+               0,              0,
+       };
+
+       return copy_packages(code, pack, 5, space);
+}
+
+static int seqhead_to_package(struct go7007 *go, __le16 *code, int space,
+       int (*sequence_header_func)(struct go7007 *go,
+               unsigned char *buf, int ext))
+{
+       int vop_time_increment_bitlength = vti_bitlen(go);
+       int fps = go->sensor_framerate / go->fps_scale *
+                                       (go->interlace_coding ? 2 : 1);
+       unsigned char buf[40] = { };
+       int len = sequence_header_func(go, buf, 1);
+       u16 pack[] = {
+               0x2006,         0,
+               0xbf08,         fps,
+               0xbf09,         0,
+               0xbff2,         vop_time_increment_bitlength,
+               0xbff3,         (1 << vop_time_increment_bitlength) - 1,
+               0xbfe6,         0,
+               0xbfe7,         (fps / 1000) << 8,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+
+               0x2007,         0,
+               0xc800,         buf[2] << 8 | buf[3],
+               0xc801,         buf[4] << 8 | buf[5],
+               0xc802,         buf[6] << 8 | buf[7],
+               0xc803,         buf[8] << 8 | buf[9],
+               0xc406,         64,
+               0xc407,         len - 64,
+               0xc61b,         1,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+
+               0x200e,         0,
+               0xc808,         buf[10] << 8 | buf[11],
+               0xc809,         buf[12] << 8 | buf[13],
+               0xc80a,         buf[14] << 8 | buf[15],
+               0xc80b,         buf[16] << 8 | buf[17],
+               0xc80c,         buf[18] << 8 | buf[19],
+               0xc80d,         buf[20] << 8 | buf[21],
+               0xc80e,         buf[22] << 8 | buf[23],
+               0xc80f,         buf[24] << 8 | buf[25],
+               0xc810,         buf[26] << 8 | buf[27],
+               0xc811,         buf[28] << 8 | buf[29],
+               0xc812,         buf[30] << 8 | buf[31],
+               0xc813,         buf[32] << 8 | buf[33],
+               0xc814,         buf[34] << 8 | buf[35],
+               0xc815,         buf[36] << 8 | buf[37],
+               0,              0,
+               0,              0,
+               0,              0,
+       };
+
+       return copy_packages(code, pack, 3, space);
+}
+
+static int relative_prime(int big, int little)
+{
+       int remainder;
+
+       while (little != 0) {
+               remainder = big % little;
+               big = little;
+               little = remainder;
+       }
+       return big;
+}
+
+static int avsync_to_package(struct go7007 *go, __le16 *code, int space)
+{
+       int arate = go->board_info->audio_rate * 1001 * go->fps_scale;
+       int ratio = arate / go->sensor_framerate;
+       int adjratio = ratio * 215 / 100;
+       int rprime = relative_prime(go->sensor_framerate,
+                                       arate % go->sensor_framerate);
+       int f1 = (arate % go->sensor_framerate) / rprime;
+       int f2 = (go->sensor_framerate - arate % go->sensor_framerate) / rprime;
+       u16 pack[] = {
+               0x200e,         0,
+               0xbf98,         (u16)((-adjratio) & 0xffff),
+               0xbf99,         (u16)((-adjratio) >> 16),
+               0xbf92,         0,
+               0xbf93,         0,
+               0xbff4,         f1 > f2 ? f1 : f2,
+               0xbff5,         f1 < f2 ? f1 : f2,
+               0xbff6,         f1 < f2 ? ratio : ratio + 1,
+               0xbff7,         f1 > f2 ? ratio : ratio + 1,
+               0xbff8,         0,
+               0xbff9,         0,
+               0xbffa,         adjratio & 0xffff,
+               0xbffb,         adjratio >> 16,
+               0xbf94,         0,
+               0xbf95,         0,
+               0,              0,
+       };
+
+       return copy_packages(code, pack, 1, space);
+}
+
+static int final_package(struct go7007 *go, __le16 *code, int space)
+{
+       int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
+       u16 pack[] = {
+               0x8000,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+               2,
+               ((go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
+                                               (!go->interlace_coding) ?
+                                       (1 << 14) | (1 << 9) : 0) |
+                       ((go->encoder_subsample ? 1 : 0) << 8) |
+                       (go->board_info->sensor_flags &
+                               GO7007_SENSOR_CONFIG_MASK),
+               ((go->encoder_v_halve ? 1 : 0) << 14) |
+                       (go->encoder_v_halve ? rows << 9 : rows << 8) |
+                       (go->encoder_h_halve ? 1 << 6 : 0) |
+                       (go->encoder_h_halve ? go->width >> 3 : go->width >> 4),
+               (1 << 15) | (go->encoder_v_offset << 6) |
+                       (1 << 7) | (go->encoder_h_offset >> 2),
+               (1 << 6),
+               0,
+               0,
+               ((go->fps_scale - 1) << 8) |
+                       (go->board_info->sensor_flags & GO7007_SENSOR_TV ?
+                                               (1 << 7) : 0) |
+                       0x41,
+               go->ipb ? 0xd4c : 0x36b,
+               (rows << 8) | (go->width >> 4),
+               go->format == V4L2_PIX_FMT_MPEG4 ? 0x0404 : 0,
+               (1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) |
+                       ((go->closed_gop ? 1 : 0) << 12) |
+                       ((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 == 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,
+               0xffff,
+               0x0020 + 0x034b * 0,
+               0x0020 + 0x034b * 1,
+               0x0020 + 0x034b * 2,
+               0x0020 + 0x034b * 3,
+               0x0020 + 0x034b * 4,
+               0x0020 + 0x034b * 5,
+               go->ipb ? (go->gop_size / 3) : go->gop_size,
+               (go->height >> 4) * (go->width >> 4) * 110 / 100,
+       };
+
+       return copy_packages(code, pack, 1, space);
+}
+
+static int audio_to_package(struct go7007 *go, __le16 *code, int space)
+{
+       int clock_config = ((go->board_info->audio_flags &
+                               GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) |
+                       ((go->board_info->audio_flags &
+                               GO7007_AUDIO_OKI_MODE ? 1 : 0) << 8) |
+                       (((go->board_info->audio_bclk_div / 4) - 1) << 4) |
+                       (go->board_info->audio_main_div - 1);
+       u16 pack[] = {
+               0x200d,         0,
+               0x9002,         0,
+               0x9002,         0,
+               0x9031,         0,
+               0x9032,         0,
+               0x9033,         0,
+               0x9034,         0,
+               0x9035,         0,
+               0x9036,         0,
+               0x9037,         0,
+               0x9040,         0,
+               0x9000,         clock_config,
+               0x9001,         (go->board_info->audio_flags & 0xffff) |
+                                       (1 << 9),
+               0x9000,         ((go->board_info->audio_flags &
+                                               GO7007_AUDIO_I2S_MASTER ?
+                                               1 : 0) << 10) |
+                                       clock_config,
+               0,              0,
+               0,              0,
+               0x2005,         0,
+               0x9041,         0,
+               0x9042,         256,
+               0x9043,         0,
+               0x9044,         16,
+               0x9045,         16,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+               0,              0,
+       };
+
+       return copy_packages(code, pack, 2, space);
+}
+
+static int modet_to_package(struct go7007 *go, __le16 *code, int space)
+{
+       bool has_modet0 = go->modet[0].enable;
+       bool has_modet1 = go->modet[1].enable;
+       bool has_modet2 = go->modet[2].enable;
+       bool has_modet3 = go->modet[3].enable;
+       int ret, mb, i, addr, cnt = 0;
+       u16 pack[32];
+       u16 thresholds[] = {
+               0x200e,         0,
+               0xbf82,         has_modet0 ? go->modet[0].pixel_threshold : 32767,
+               0xbf83,         has_modet1 ? go->modet[1].pixel_threshold : 32767,
+               0xbf84,         has_modet2 ? go->modet[2].pixel_threshold : 32767,
+               0xbf85,         has_modet3 ? go->modet[3].pixel_threshold : 32767,
+               0xbf86,         has_modet0 ? go->modet[0].motion_threshold : 32767,
+               0xbf87,         has_modet1 ? go->modet[1].motion_threshold : 32767,
+               0xbf88,         has_modet2 ? go->modet[2].motion_threshold : 32767,
+               0xbf89,         has_modet3 ? go->modet[3].motion_threshold : 32767,
+               0xbf8a,         has_modet0 ? go->modet[0].mb_threshold : 32767,
+               0xbf8b,         has_modet1 ? go->modet[1].mb_threshold : 32767,
+               0xbf8c,         has_modet2 ? go->modet[2].mb_threshold : 32767,
+               0xbf8d,         has_modet3 ? go->modet[3].mb_threshold : 32767,
+               0xbf8e,         0,
+               0xbf8f,         0,
+               0,              0,
+       };
+
+       ret = copy_packages(code, thresholds, 1, space);
+       if (ret < 0)
+               return -1;
+       cnt += ret;
+
+       addr = 0xbac0;
+       memset(pack, 0, 64);
+       i = 0;
+       for (mb = 0; mb < 1624; ++mb) {
+               pack[i * 2 + 3] <<= 2;
+               pack[i * 2 + 3] |= go->modet_map[mb];
+               if (mb % 8 != 7)
+                       continue;
+               pack[i * 2 + 2] = addr++;
+               ++i;
+               if (i == 10 || mb == 1623) {
+                       pack[0] = 0x2000 | i;
+                       ret = copy_packages(code + cnt, pack, 1, space - cnt);
+                       if (ret < 0)
+                               return -1;
+                       cnt += ret;
+                       i = 0;
+                       memset(pack, 0, 64);
+               }
+               pack[i * 2 + 3] = 0;
+       }
+
+       memset(pack, 0, 64);
+       i = 0;
+       for (addr = 0xbb90; addr < 0xbbfa; ++addr) {
+               pack[i * 2 + 2] = addr;
+               pack[i * 2 + 3] = 0;
+               ++i;
+               if (i == 10 || addr == 0xbbf9) {
+                       pack[0] = 0x2000 | i;
+                       ret = copy_packages(code + cnt, pack, 1, space - cnt);
+                       if (ret < 0)
+                               return -1;
+                       cnt += ret;
+                       i = 0;
+                       memset(pack, 0, 64);
+               }
+       }
+       return cnt;
+}
+
+static int do_special(struct go7007 *go, u16 type, __le16 *code, int space,
+                       int *framelen)
+{
+       switch (type) {
+       case SPECIAL_FRM_HEAD:
+               switch (go->format) {
+               case V4L2_PIX_FMT_MJPEG:
+                       return gen_mjpeghdr_to_package(go, code, space);
+               case V4L2_PIX_FMT_MPEG1:
+               case V4L2_PIX_FMT_MPEG2:
+                       return gen_mpeg1hdr_to_package(go, code, space,
+                                                               framelen);
+               case V4L2_PIX_FMT_MPEG4:
+                       return gen_mpeg4hdr_to_package(go, code, space,
+                                                               framelen);
+               }
+       case SPECIAL_BRC_CTRL:
+               return brctrl_to_package(go, code, space, framelen);
+       case SPECIAL_CONFIG:
+               return config_package(go, code, space);
+       case SPECIAL_SEQHEAD:
+               switch (go->format) {
+               case V4L2_PIX_FMT_MPEG1:
+               case V4L2_PIX_FMT_MPEG2:
+                       return seqhead_to_package(go, code, space,
+                                       mpeg1_sequence_header);
+               case V4L2_PIX_FMT_MPEG4:
+                       return seqhead_to_package(go, code, space,
+                                       mpeg4_sequence_header);
+               default:
+                       return 0;
+               }
+       case SPECIAL_AV_SYNC:
+               return avsync_to_package(go, code, space);
+       case SPECIAL_FINAL:
+               return final_package(go, code, space);
+       case SPECIAL_AUDIO:
+               return audio_to_package(go, code, space);
+       case SPECIAL_MODET:
+               return modet_to_package(go, code, space);
+       }
+       dev_err(go->dev,
+               "firmware file contains unsupported feature %04x\n", type);
+       return -1;
+}
+
+int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
+{
+       const struct firmware *fw_entry;
+       __le16 *code, *src;
+       int framelen[8] = { }; /* holds the lengths of empty frame templates */
+       int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags;
+       int mode_flag;
+       int ret;
+
+       switch (go->format) {
+       case V4L2_PIX_FMT_MJPEG:
+               mode_flag = FLAG_MODE_MJPEG;
+               break;
+       case V4L2_PIX_FMT_MPEG1:
+               mode_flag = FLAG_MODE_MPEG1;
+               break;
+       case V4L2_PIX_FMT_MPEG2:
+               mode_flag = FLAG_MODE_MPEG2;
+               break;
+       case V4L2_PIX_FMT_MPEG4:
+               mode_flag = FLAG_MODE_MPEG4;
+               break;
+       default:
+               return -1;
+       }
+       if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev)) {
+               dev_err(go->dev,
+                       "unable to load firmware from file \"%s\"\n",
+                       GO7007_FW_NAME);
+               return -1;
+       }
+       code = kzalloc(codespace * 2, GFP_KERNEL);
+       if (code == NULL)
+               goto fw_failed;
+
+       src = (__le16 *)fw_entry->data;
+       srclen = fw_entry->size / 2;
+       while (srclen >= 2) {
+               chunk_flags = __le16_to_cpu(src[0]);
+               chunk_len = __le16_to_cpu(src[1]);
+               if (chunk_len + 2 > srclen) {
+                       dev_err(go->dev,
+                               "firmware file \"%s\" appears to be corrupted\n",
+                               GO7007_FW_NAME);
+                       goto fw_failed;
+               }
+               if (chunk_flags & mode_flag) {
+                       if (chunk_flags & FLAG_SPECIAL) {
+                               ret = do_special(go, __le16_to_cpu(src[2]),
+                                       &code[i], codespace - i, framelen);
+                               if (ret < 0) {
+                                       dev_err(go->dev,
+                                               "insufficient memory for firmware construction\n");
+                                       goto fw_failed;
+                               }
+                               i += ret;
+                       } else {
+                               if (codespace - i < chunk_len) {
+                                       dev_err(go->dev,
+                                               "insufficient memory for firmware construction\n");
+                                       goto fw_failed;
+                               }
+                               memcpy(&code[i], &src[2], chunk_len * 2);
+                               i += chunk_len;
+                       }
+               }
+               srclen -= chunk_len + 2;
+               src += chunk_len + 2;
+       }
+       release_firmware(fw_entry);
+       *fw = (u8 *)code;
+       *fwlen = i * 2;
+       return 0;
+
+fw_failed:
+       kfree(code);
+       release_firmware(fw_entry);
+       return -1;
+}
+
+MODULE_FIRMWARE(GO7007_FW_NAME);
diff --git a/drivers/media/usb/go7007/go7007-i2c.c b/drivers/media/usb/go7007/go7007-i2c.c
new file mode 100644 (file)
index 0000000..55addfa
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/unistd.h>
+#include <linux/time.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+
+#include "go7007-priv.h"
+
+/********************* Driver for on-board I2C adapter *********************/
+
+/* #define GO7007_I2C_DEBUG */
+
+#define SPI_I2C_ADDR_BASE              0x1400
+#define STATUS_REG_ADDR                        (SPI_I2C_ADDR_BASE + 0x2)
+#define I2C_CTRL_REG_ADDR              (SPI_I2C_ADDR_BASE + 0x6)
+#define I2C_DEV_UP_ADDR_REG_ADDR       (SPI_I2C_ADDR_BASE + 0x7)
+#define I2C_LO_ADDR_REG_ADDR           (SPI_I2C_ADDR_BASE + 0x8)
+#define I2C_DATA_REG_ADDR              (SPI_I2C_ADDR_BASE + 0x9)
+#define I2C_CLKFREQ_REG_ADDR           (SPI_I2C_ADDR_BASE + 0xa)
+
+#define I2C_STATE_MASK                 0x0007
+#define I2C_READ_READY_MASK            0x0008
+
+/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
+ * on the Adlink PCI-MPG24, so access is shared between all of them. */
+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 = -EIO;
+       u16 val;
+
+       if (go->status == STATUS_SHUTDOWN)
+               return -ENODEV;
+
+#ifdef GO7007_I2C_DEBUG
+       if (read)
+               dev_dbg(go->dev, "go7007-i2c: reading 0x%02x on 0x%02x\n",
+                       command, addr);
+       else
+               dev_dbg(go->dev,
+                       "go7007-i2c: writing 0x%02x to 0x%02x on 0x%02x\n",
+                       *data, command, addr);
+#endif
+
+       mutex_lock(&go->hw_lock);
+
+       if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
+               /* Bridge the I2C port on this GO7007 to the shared bus */
+               mutex_lock(&adlink_mpg24_i2c_lock);
+               go7007_write_addr(go, 0x3c82, 0x0020);
+       }
+
+       /* Wait for I2C adapter to be ready */
+       for (i = 0; i < 10; ++i) {
+               if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
+                       goto i2c_done;
+               if (!(val & I2C_STATE_MASK))
+                       break;
+               msleep(100);
+       }
+       if (i == 10) {
+               dev_err(go->dev, "go7007-i2c: I2C adapter is hung\n");
+               goto i2c_done;
+       }
+
+       /* Set target register (command) */
+       go7007_write_addr(go, I2C_CTRL_REG_ADDR, flags);
+       go7007_write_addr(go, I2C_LO_ADDR_REG_ADDR, command);
+
+       /* If we're writing, send the data and target address and we're done */
+       if (!read) {
+               go7007_write_addr(go, I2C_DATA_REG_ADDR, *data);
+               go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
+                                       (addr << 9) | (command >> 8));
+               ret = 0;
+               goto i2c_done;
+       }
+
+       /* Otherwise, we're reading.  First clear i2c_rx_data_rdy. */
+       if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
+               goto i2c_done;
+
+       /* Send the target address plus read flag */
+       go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
+                       (addr << 9) | 0x0100 | (command >> 8));
+
+       /* Wait for i2c_rx_data_rdy */
+       for (i = 0; i < 10; ++i) {
+               if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
+                       goto i2c_done;
+               if (val & I2C_READ_READY_MASK)
+                       break;
+               msleep(100);
+       }
+       if (i == 10) {
+               dev_err(go->dev, "go7007-i2c: I2C adapter is hung\n");
+               goto i2c_done;
+       }
+
+       /* Retrieve the read byte */
+       if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
+               goto i2c_done;
+       *data = val;
+       ret = 0;
+
+i2c_done:
+       if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
+               /* Isolate the I2C port on this GO7007 from the shared bus */
+               go7007_write_addr(go, 0x3c82, 0x0000);
+               mutex_unlock(&adlink_mpg24_i2c_lock);
+       }
+       mutex_unlock(&go->hw_lock);
+       return ret;
+}
+
+static int go7007_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
+               unsigned short flags, char read_write,
+               u8 command, int size, union i2c_smbus_data *data)
+{
+       struct go7007 *go = i2c_get_adapdata(adapter);
+
+       if (size != I2C_SMBUS_BYTE_DATA)
+               return -EIO;
+       return go7007_i2c_xfer(go, addr, read_write == I2C_SMBUS_READ, command,
+                       flags & I2C_CLIENT_SCCB ? 0x10 : 0x00, &data->byte);
+}
+
+/* VERY LIMITED I2C master xfer function -- only needed because the
+ * SMBus functions only support 8-bit commands and the SAA7135 uses
+ * 16-bit commands.  The I2C interface on the GO7007, as limited as
+ * it is, does support this mode. */
+
+static int go7007_i2c_master_xfer(struct i2c_adapter *adapter,
+                                       struct i2c_msg msgs[], int num)
+{
+       struct go7007 *go = i2c_get_adapdata(adapter);
+       int i;
+
+       for (i = 0; i < num; ++i) {
+               /* We can only do two things here -- write three bytes, or
+                * write two bytes and read one byte. */
+               if (msgs[i].len == 2) {
+                       if (i + 1 == num || msgs[i].addr != msgs[i + 1].addr ||
+                                       (msgs[i].flags & I2C_M_RD) ||
+                                       !(msgs[i + 1].flags & I2C_M_RD) ||
+                                       msgs[i + 1].len != 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 -EIO;
+                       ++i;
+               } else if (msgs[i].len == 3) {
+                       if (msgs[i].flags & I2C_M_RD)
+                               return -EIO;
+                       if (msgs[i].len != 3)
+                               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 -EIO;
+               } else
+                       return -EIO;
+       }
+
+       return num;
+}
+
+static u32 go7007_functionality(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_SMBUS_BYTE_DATA;
+}
+
+static struct i2c_algorithm go7007_algo = {
+       .smbus_xfer     = go7007_smbus_xfer,
+       .master_xfer    = go7007_i2c_master_xfer,
+       .functionality  = go7007_functionality,
+};
+
+static struct i2c_adapter go7007_adap_templ = {
+       .owner                  = THIS_MODULE,
+       .name                   = "WIS GO7007SB",
+       .algo                   = &go7007_algo,
+};
+
+int go7007_i2c_init(struct go7007 *go)
+{
+       memcpy(&go->i2c_adapter, &go7007_adap_templ,
+                       sizeof(go7007_adap_templ));
+       go->i2c_adapter.dev.parent = go->dev;
+       i2c_set_adapdata(&go->i2c_adapter, go);
+       if (i2c_add_adapter(&go->i2c_adapter) < 0) {
+               dev_err(go->dev,
+                       "go7007-i2c: error: i2c_add_adapter failed\n");
+               return -1;
+       }
+       return 0;
+}
diff --git a/drivers/media/usb/go7007/go7007-loader.c b/drivers/media/usb/go7007/go7007-loader.c
new file mode 100644 (file)
index 0000000..042f78a
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <cypress_firmware.h>
+
+struct fw_config {
+       u16 vendor;
+       u16 product;
+       const char * const fw_name1;
+       const char * const fw_name2;
+};
+
+static 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;
+       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)
+               goto failed2;
+
+       if (usbdev->descriptor.bNumConfigurations != 1) {
+               dev_err(&interface->dev, "can't handle multiple config\n");
+               goto failed2;
+       }
+
+       vendor = le16_to_cpu(usbdev->descriptor.idVendor);
+       product = le16_to_cpu(usbdev->descriptor.idProduct);
+
+       for (i = 0; fw_configs[i].fw_name1; i++)
+               if (fw_configs[i].vendor == vendor &&
+                   fw_configs[i].product == product)
+                       break;
+
+       /* Should never happen */
+       if (fw_configs[i].fw_name1 == NULL)
+               goto failed2;
+
+       fw1 = fw_configs[i].fw_name1;
+       fw2 = fw_configs[i].fw_name2;
+
+       dev_info(&interface->dev, "loading firmware %s\n", fw1);
+
+       if (request_firmware(&fw, fw1, &usbdev->dev)) {
+               dev_err(&interface->dev,
+                       "unable to load firmware from file \"%s\"\n", fw1);
+               goto failed2;
+       }
+       ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
+       release_firmware(fw);
+       if (0 != ret) {
+               dev_err(&interface->dev, "loader download failed\n");
+               goto failed2;
+       }
+
+       if (fw2 == NULL)
+               return 0;
+
+       if (request_firmware(&fw, fw2, &usbdev->dev)) {
+               dev_err(&interface->dev,
+                       "unable to load firmware from file \"%s\"\n", fw2);
+               goto failed2;
+       }
+       ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
+       release_firmware(fw);
+       if (0 != ret) {
+               dev_err(&interface->dev, "firmware download failed\n");
+               goto failed2;
+       }
+       return 0;
+
+failed2:
+       usb_put_dev(usbdev);
+       dev_err(&interface->dev, "probe failed\n");
+       return -ENODEV;
+}
+
+static void go7007_loader_disconnect(struct usb_interface *interface)
+{
+       dev_info(&interface->dev, "disconnect\n");
+       usb_put_dev(interface_to_usbdev(interface));
+       usb_set_intfdata(interface, NULL);
+}
+
+static const struct usb_device_id go7007_loader_ids[] = {
+       { USB_DEVICE(0x1943, 0xa250) },
+       { USB_DEVICE(0x093b, 0xa002) },
+       { USB_DEVICE(0x093b, 0xa004) },
+       { USB_DEVICE(0x0eb1, 0x6666) },
+       { USB_DEVICE(0x0eb1, 0x6668) },
+       {}                          /* 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");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/usb/go7007/go7007-priv.h b/drivers/media/usb/go7007/go7007-priv.h
new file mode 100644 (file)
index 0000000..2251c3f
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * 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.
+ */
+
+/*
+ * This is the private include file for the go7007 driver.  It should not
+ * be included by anybody but the driver itself, and especially not by
+ * user-space applications.
+ */
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fh.h>
+#include <media/videobuf2-core.h>
+
+struct go7007;
+
+/* IDs to activate board-specific support code */
+#define GO7007_BOARDID_MATRIX_II       0
+#define GO7007_BOARDID_MATRIX_RELOAD   1
+#define GO7007_BOARDID_STAR_TREK       2
+#define GO7007_BOARDID_PCI_VOYAGER     3
+#define GO7007_BOARDID_XMEN            4
+#define GO7007_BOARDID_XMEN_II         5
+#define GO7007_BOARDID_XMEN_III                6
+#define GO7007_BOARDID_MATRIX_REV      7
+#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 */
+#define GO7007_BOARDID_ADS_USBAV_709    14
+
+/* Various characteristics of each board */
+#define GO7007_BOARD_HAS_AUDIO         (1<<0)
+#define GO7007_BOARD_USE_ONBOARD_I2C   (1<<1)
+#define GO7007_BOARD_HAS_TUNER         (1<<2)
+
+/* Characteristics of sensor devices */
+#define GO7007_SENSOR_VALID_POLAR      (1<<0)
+#define GO7007_SENSOR_HREF_POLAR       (1<<1)
+#define GO7007_SENSOR_VREF_POLAR       (1<<2)
+#define GO7007_SENSOR_FIELD_ID_POLAR   (1<<3)
+#define GO7007_SENSOR_BIT_WIDTH                (1<<4)
+#define GO7007_SENSOR_VALID_ENABLE     (1<<5)
+#define GO7007_SENSOR_656              (1<<6)
+#define GO7007_SENSOR_CONFIG_MASK      0x7f
+#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)
+#define GO7007_AUDIO_I2S_MODE_2                (2)
+#define GO7007_AUDIO_I2S_MODE_3                (3)
+#define GO7007_AUDIO_BCLK_POLAR                (1<<2)
+#define GO7007_AUDIO_WORD_14           (14<<4)
+#define GO7007_AUDIO_WORD_16           (16<<4)
+#define GO7007_AUDIO_ONE_CHANNEL       (1<<11)
+#define GO7007_AUDIO_I2S_MASTER                (1<<16)
+#define GO7007_AUDIO_OKI_MODE          (1<<17)
+
+#define GO7007_CID_CUSTOM_BASE         (V4L2_CID_DETECT_CLASS_BASE + 0x1000)
+#define V4L2_CID_PIXEL_THRESHOLD0      (GO7007_CID_CUSTOM_BASE+1)
+#define V4L2_CID_MOTION_THRESHOLD0     (GO7007_CID_CUSTOM_BASE+2)
+#define V4L2_CID_MB_THRESHOLD0         (GO7007_CID_CUSTOM_BASE+3)
+#define V4L2_CID_PIXEL_THRESHOLD1      (GO7007_CID_CUSTOM_BASE+4)
+#define V4L2_CID_MOTION_THRESHOLD1     (GO7007_CID_CUSTOM_BASE+5)
+#define V4L2_CID_MB_THRESHOLD1         (GO7007_CID_CUSTOM_BASE+6)
+#define V4L2_CID_PIXEL_THRESHOLD2      (GO7007_CID_CUSTOM_BASE+7)
+#define V4L2_CID_MOTION_THRESHOLD2     (GO7007_CID_CUSTOM_BASE+8)
+#define V4L2_CID_MB_THRESHOLD2         (GO7007_CID_CUSTOM_BASE+9)
+#define V4L2_CID_PIXEL_THRESHOLD3      (GO7007_CID_CUSTOM_BASE+10)
+#define V4L2_CID_MOTION_THRESHOLD3     (GO7007_CID_CUSTOM_BASE+11)
+#define V4L2_CID_MB_THRESHOLD3         (GO7007_CID_CUSTOM_BASE+12)
+
+struct go7007_board_info {
+       unsigned int flags;
+       int hpi_buffer_cap;
+       unsigned int sensor_flags;
+       int sensor_width;
+       int sensor_height;
+       int sensor_framerate;
+       int sensor_h_offset;
+       int sensor_v_offset;
+       unsigned int audio_flags;
+       int audio_rate;
+       int audio_bclk_div;
+       int audio_main_div;
+       int num_i2c_devs;
+       struct go_i2c {
+               const char *type;
+               unsigned int is_video:1;
+               unsigned int is_audio:1;
+               int addr;
+               u32 flags;
+       } i2c_devs[5];
+       int num_inputs;
+       struct {
+               int video_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 {
+       int (*interface_reset)(struct go7007 *go);
+       int (*write_interrupt)(struct go7007 *go, int addr, int data);
+       int (*read_interrupt)(struct go7007 *go);
+       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);
+       void (*release)(struct go7007 *go);
+};
+
+/* The video buffer size must be a multiple of PAGE_SIZE */
+#define        GO7007_BUF_PAGES        (128 * 1024 / PAGE_SIZE)
+#define        GO7007_BUF_SIZE         (GO7007_BUF_PAGES << PAGE_SHIFT)
+
+struct go7007_buffer {
+       struct vb2_buffer vb;
+       struct list_head list;
+       unsigned int frame_offset;
+       u32 modet_active;
+};
+
+#define GO7007_RATIO_1_1       0
+#define GO7007_RATIO_4_3       1
+#define GO7007_RATIO_16_9      2
+
+enum go7007_parser_state {
+       STATE_DATA,
+       STATE_00,
+       STATE_00_00,
+       STATE_00_00_01,
+       STATE_FF,
+       STATE_VBI_LEN_A,
+       STATE_VBI_LEN_B,
+       STATE_MODET_MAP,
+       STATE_UNPARSED,
+};
+
+struct go7007 {
+       struct device *dev;
+       u8 bus_info[32];
+       const struct go7007_board_info *board_info;
+       unsigned int board_id;
+       int tuner_type;
+       int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
+       char name[64];
+       struct video_device vdev;
+       void *boot_fw;
+       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;
+       struct v4l2_ctrl *mpeg_video_b_frames;
+       struct v4l2_ctrl *mpeg_video_rep_seqheader;
+       struct v4l2_ctrl *modet_mode;
+       enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
+       spinlock_t spinlock;
+       struct mutex hw_lock;
+       struct mutex serialize_lock;
+       int audio_enabled;
+       struct v4l2_subdev *sd_video;
+       struct v4l2_subdev *sd_audio;
+       u8 usb_buf[16];
+
+       /* Video input */
+       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;
+       int encoder_h_offset;
+       int encoder_v_offset;
+       unsigned int encoder_h_halve:1;
+       unsigned int encoder_v_halve:1;
+       unsigned int encoder_subsample:1;
+
+       /* Encoder config */
+       u32 format;
+       int bitrate;
+       int fps_scale;
+       int pali;
+       int aspect_ratio;
+       int gop_size;
+       unsigned int ipb:1;
+       unsigned int closed_gop:1;
+       unsigned int repeat_seqhead:1;
+       unsigned int seq_header_enable:1;
+       unsigned int gop_header_enable:1;
+       unsigned int dvd_mode:1;
+       unsigned int interlace_coding:1;
+
+       /* Motion detection */
+       unsigned int modet_enable:1;
+       struct {
+               unsigned int enable:1;
+               int pixel_threshold;
+               int motion_threshold;
+               int mb_threshold;
+       } modet[4];
+       unsigned char modet_map[1624];
+       unsigned char active_map[216];
+       u32 modet_event_status;
+
+       /* Video streaming */
+       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 vidq_active;
+       wait_queue_head_t frame_waitq;
+       struct go7007_buffer *active_buf;
+
+       /* Audio streaming */
+       void (*audio_deliver)(struct go7007 *go, u8 *buf, int length);
+       void *snd_context;
+
+       /* I2C */
+       int i2c_adapter_online;
+       struct i2c_adapter i2c_adapter;
+
+       /* HPI driver */
+       struct go7007_hpi_ops *hpi_ops;
+       void *hpi_context;
+       int interrupt_available;
+       wait_queue_head_t interrupt_waitq;
+       unsigned short interrupt_value;
+       unsigned short interrupt_data;
+};
+
+static inline struct go7007 *to_go7007(struct v4l2_device *v4l2_dev)
+{
+       return container_of(v4l2_dev, struct go7007, v4l2_dev);
+}
+
+/* All of these must be called with the hpi_lock mutex held! */
+#define go7007_interface_reset(go) \
+                       ((go)->hpi_ops->interface_reset(go))
+#define        go7007_write_interrupt(go, x, y) \
+                       ((go)->hpi_ops->write_interrupt)((go), (x), (y))
+#define go7007_stream_start(go) \
+                       ((go)->hpi_ops->stream_start(go))
+#define go7007_stream_stop(go) \
+                       ((go)->hpi_ops->stream_stop(go))
+#define        go7007_send_firmware(go, x, y) \
+                       ((go)->hpi_ops->send_firmware)((go), (x), (y))
+#define go7007_write_addr(go, x, y) \
+                       ((go)->hpi_ops->write_interrupt)((go), (x)|0x8000, (y))
+
+/* go7007-driver.c */
+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, 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(const 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);
+
+/* go7007-i2c.c */
+int go7007_i2c_init(struct go7007 *go);
+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 */
+int go7007_snd_init(struct go7007 *go);
+int go7007_snd_remove(struct go7007 *go);
diff --git a/drivers/media/usb/go7007/go7007-usb.c b/drivers/media/usb/go7007/go7007-usb.c
new file mode 100644 (file)
index 0000000..ece27ec
--- /dev/null
@@ -0,0 +1,1345 @@
+/*
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <asm/byteorder.h>
+#include <media/saa7115.h>
+#include <media/tuner.h>
+#include <media/uda1342.h>
+
+#include "go7007-priv.h"
+
+static unsigned int assume_endura;
+module_param(assume_endura, int, 0644);
+MODULE_PARM_DESC(assume_endura,
+                       "when probing fails, hardware is a Pelco Endura");
+
+/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
+
+#define        HPI_STATUS_ADDR 0xFFF4
+#define        INT_PARAM_ADDR  0xFFF6
+#define        INT_INDEX_ADDR  0xFFF8
+
+/*
+ * Pipes on EZ-USB interface:
+ *     0 snd - Control
+ *     0 rcv - Control
+ *     2 snd - Download firmware (control)
+ *     4 rcv - Read Interrupt (interrupt)
+ *     6 rcv - Read Video (bulk)
+ *     8 rcv - Read Audio (bulk)
+ */
+
+#define GO7007_USB_EZUSB               (1<<0)
+#define GO7007_USB_EZUSB_I2C           (1<<1)
+
+struct go7007_usb_board {
+       unsigned int flags;
+       struct go7007_board_info main_info;
+};
+
+struct go7007_usb {
+       const struct go7007_usb_board *board;
+       struct mutex i2c_lock;
+       struct usb_device *usbdev;
+       struct urb *video_urbs[8];
+       struct urb *audio_urbs[8];
+       struct urb *intr_urb;
+};
+
+/*********************** Product specification data ***********************/
+
+static const struct go7007_usb_board board_matrix_ii = {
+       .flags          = GO7007_USB_EZUSB,
+       .main_info      = {
+               .flags           = GO7007_BOARD_HAS_AUDIO |
+                                       GO7007_BOARD_USE_ONBOARD_I2C,
+               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
+                                       GO7007_AUDIO_WORD_16,
+               .audio_rate      = 48000,
+               .audio_bclk_div  = 8,
+               .audio_main_div  = 2,
+               .hpi_buffer_cap  = 7,
+               .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,
+               .i2c_devs        = {
+                       {
+                               .type   = "saa7115",
+                               .addr   = 0x20,
+                               .is_video = 1,
+                       },
+               },
+               .num_inputs      = 2,
+               .inputs          = {
+                       {
+                               .video_input    = 0,
+                               .name           = "Composite",
+                       },
+                       {
+                               .video_input    = 9,
+                               .name           = "S-Video",
+                       },
+               },
+               .video_config   = SAA7115_IDQ_IS_DEFAULT,
+       },
+};
+
+static const struct go7007_usb_board board_matrix_reload = {
+       .flags          = GO7007_USB_EZUSB,
+       .main_info      = {
+               .flags           = GO7007_BOARD_HAS_AUDIO |
+                                       GO7007_BOARD_USE_ONBOARD_I2C,
+               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
+                                       GO7007_AUDIO_I2S_MASTER |
+                                       GO7007_AUDIO_WORD_16,
+               .audio_rate      = 48000,
+               .audio_bclk_div  = 8,
+               .audio_main_div  = 2,
+               .hpi_buffer_cap  = 7,
+               .sensor_flags    = GO7007_SENSOR_656 |
+                                       GO7007_SENSOR_TV,
+               .num_i2c_devs    = 1,
+               .i2c_devs        = {
+                       {
+                               .type   = "saa7113",
+                               .addr   = 0x25,
+                               .is_video = 1,
+                       },
+               },
+               .num_inputs      = 2,
+               .inputs          = {
+                       {
+                               .video_input    = 0,
+                               .name           = "Composite",
+                       },
+                       {
+                               .video_input    = 9,
+                               .name           = "S-Video",
+                       },
+               },
+               .video_config   = SAA7115_IDQ_IS_DEFAULT,
+       },
+};
+
+static const struct go7007_usb_board board_star_trek = {
+       .flags          = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
+       .main_info      = {
+               .flags           = GO7007_BOARD_HAS_AUDIO, /* |
+                                       GO7007_BOARD_HAS_TUNER, */
+               .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 |
+                                       GO7007_AUDIO_WORD_16,
+               .audio_bclk_div  = 8,
+               .audio_main_div  = 2,
+               .hpi_buffer_cap  = 7,
+               .num_i2c_devs    = 1,
+               .i2c_devs        = {
+                       {
+                               .type   = "saa7115",
+                               .addr   = 0x20,
+                               .is_video = 1,
+                       },
+               },
+               .num_inputs      = 2,
+               .inputs          = {
+               /*      {
+                *              .video_input    = 3,
+                *              .audio_index    = AUDIO_TUNER,
+                *              .name           = "Tuner",
+                *      },
+                */
+                       {
+                               .video_input    = 1,
+                       /*      .audio_index    = AUDIO_EXTERN, */
+                               .name           = "Composite",
+                       },
+                       {
+                               .video_input    = 8,
+                       /*      .audio_index    = AUDIO_EXTERN, */
+                               .name           = "S-Video",
+                       },
+               },
+               .video_config   = SAA7115_IDQ_IS_DEFAULT,
+       },
+};
+
+static const struct go7007_usb_board board_px_tv402u = {
+       .flags          = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
+       .main_info      = {
+               .flags           = GO7007_BOARD_HAS_AUDIO |
+                                       GO7007_BOARD_HAS_TUNER,
+               .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 |
+                                       GO7007_AUDIO_WORD_16,
+               .audio_bclk_div  = 8,
+               .audio_main_div  = 2,
+               .hpi_buffer_cap  = 7,
+               .num_i2c_devs    = 5,
+               .i2c_devs        = {
+                       {
+                               .type   = "saa7115",
+                               .addr   = 0x20,
+                               .is_video = 1,
+                       },
+                       {
+                               .type   = "uda1342",
+                               .addr   = 0x1a,
+                               .is_audio = 1,
+                       },
+                       {
+                               .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_index    = 1,
+                               .name           = "Composite",
+                       },
+                       {
+                               .video_input    = 8,
+                               .audio_index    = 1,
+                               .name           = "S-Video",
+                       },
+               },
+               .video_config   = SAA7115_IDQ_IS_DEFAULT,
+               .num_aud_inputs  = 2,
+               .aud_inputs      = {
+                       {
+                               .audio_input    = UDA1342_IN2,
+                               .name           = "Tuner",
+                       },
+                       {
+                               .audio_input    = UDA1342_IN1,
+                               .name           = "Line In",
+                       },
+               },
+       },
+};
+
+static const struct go7007_usb_board board_xmen = {
+       .flags          = 0,
+       .main_info      = {
+               .flags            = GO7007_BOARD_USE_ONBOARD_I2C,
+               .hpi_buffer_cap   = 0,
+               .sensor_flags     = GO7007_SENSOR_VREF_POLAR,
+               .sensor_width     = 320,
+               .sensor_height    = 240,
+               .sensor_framerate = 30030,
+               .audio_flags      = GO7007_AUDIO_ONE_CHANNEL |
+                                       GO7007_AUDIO_I2S_MODE_3 |
+                                       GO7007_AUDIO_WORD_14 |
+                                       GO7007_AUDIO_I2S_MASTER |
+                                       GO7007_AUDIO_BCLK_POLAR |
+                                       GO7007_AUDIO_OKI_MODE,
+               .audio_rate       = 8000,
+               .audio_bclk_div   = 48,
+               .audio_main_div   = 1,
+               .num_i2c_devs     = 1,
+               .i2c_devs         = {
+                       {
+                               .type   = "ov7640",
+                               .addr   = 0x21,
+                       },
+               },
+               .num_inputs       = 1,
+               .inputs           = {
+                       {
+                               .name           = "Camera",
+                       },
+               },
+       },
+};
+
+static const struct go7007_usb_board board_matrix_revolution = {
+       .flags          = GO7007_USB_EZUSB,
+       .main_info      = {
+               .flags           = GO7007_BOARD_HAS_AUDIO |
+                                       GO7007_BOARD_USE_ONBOARD_I2C,
+               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
+                                       GO7007_AUDIO_I2S_MASTER |
+                                       GO7007_AUDIO_WORD_16,
+               .audio_rate      = 48000,
+               .audio_bclk_div  = 8,
+               .audio_main_div  = 2,
+               .hpi_buffer_cap  = 7,
+               .sensor_flags    = GO7007_SENSOR_656 |
+                                       GO7007_SENSOR_TV |
+                                       GO7007_SENSOR_VBI,
+               .num_i2c_devs    = 1,
+               .i2c_devs        = {
+                       {
+                               .type   = "tw9903",
+                               .is_video = 1,
+                               .addr   = 0x44,
+                       },
+               },
+               .num_inputs      = 2,
+               .inputs          = {
+                       {
+                               .video_input    = 2,
+                               .name           = "Composite",
+                       },
+                       {
+                               .video_input    = 8,
+                               .name           = "S-Video",
+                       },
+               },
+       },
+};
+
+static const struct go7007_usb_board board_lifeview_lr192 = {
+       .flags          = GO7007_USB_EZUSB,
+       .main_info      = {
+               .flags           = GO7007_BOARD_HAS_AUDIO |
+                                       GO7007_BOARD_USE_ONBOARD_I2C,
+               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
+                                       GO7007_AUDIO_WORD_16,
+               .audio_rate      = 48000,
+               .audio_bclk_div  = 8,
+               .audio_main_div  = 2,
+               .hpi_buffer_cap  = 7,
+               .sensor_flags    = GO7007_SENSOR_656 |
+                                       GO7007_SENSOR_VALID_ENABLE |
+                                       GO7007_SENSOR_TV |
+                                       GO7007_SENSOR_VBI |
+                                       GO7007_SENSOR_SCALING,
+               .num_i2c_devs    = 0,
+               .num_inputs      = 1,
+               .inputs          = {
+                       {
+                               .video_input    = 0,
+                               .name           = "Composite",
+                       },
+               },
+       },
+};
+
+static const struct go7007_usb_board board_endura = {
+       .flags          = 0,
+       .main_info      = {
+               .flags           = 0,
+               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
+                                       GO7007_AUDIO_I2S_MASTER |
+                                       GO7007_AUDIO_WORD_16,
+               .audio_rate      = 8000,
+               .audio_bclk_div  = 48,
+               .audio_main_div  = 8,
+               .hpi_buffer_cap  = 0,
+               .sensor_flags    = GO7007_SENSOR_656 |
+                                       GO7007_SENSOR_TV,
+               .sensor_h_offset = 8,
+               .num_i2c_devs    = 0,
+               .num_inputs      = 1,
+               .inputs          = {
+                       {
+                               .name           = "Camera",
+                       },
+               },
+       },
+};
+
+static const struct go7007_usb_board board_adlink_mpg24 = {
+       .flags          = 0,
+       .main_info      = {
+               .flags           = GO7007_BOARD_USE_ONBOARD_I2C,
+               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
+                                       GO7007_AUDIO_I2S_MASTER |
+                                       GO7007_AUDIO_WORD_16,
+               .audio_rate      = 48000,
+               .audio_bclk_div  = 8,
+               .audio_main_div  = 2,
+               .hpi_buffer_cap  = 0,
+               .sensor_flags    = GO7007_SENSOR_656 |
+                                       GO7007_SENSOR_TV |
+                                       GO7007_SENSOR_VBI,
+               .num_i2c_devs    = 1,
+               .i2c_devs        = {
+                       {
+                               .type   = "tw2804",
+                               .addr   = 0x00, /* yes, really */
+                               .flags  = I2C_CLIENT_TEN,
+                               .is_video = 1,
+                       },
+               },
+               .num_inputs      = 1,
+               .inputs          = {
+                       {
+                               .name           = "Composite",
+                       },
+               },
+       },
+};
+
+static const struct go7007_usb_board board_sensoray_2250 = {
+       .flags          = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
+       .main_info      = {
+               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
+                                       GO7007_AUDIO_I2S_MASTER |
+                                       GO7007_AUDIO_WORD_16,
+               .flags           = GO7007_BOARD_HAS_AUDIO,
+               .audio_rate      = 48000,
+               .audio_bclk_div  = 8,
+               .audio_main_div  = 2,
+               .hpi_buffer_cap  = 7,
+               .sensor_flags    = GO7007_SENSOR_656 |
+                                       GO7007_SENSOR_TV,
+               .num_i2c_devs    = 1,
+               .i2c_devs        = {
+                       {
+                               .type   = "s2250",
+                               .addr   = 0x43,
+                               .is_video = 1,
+                               .is_audio = 1,
+                       },
+               },
+               .num_inputs      = 2,
+               .inputs          = {
+                       {
+                               .video_input    = 0,
+                               .name           = "Composite",
+                       },
+                       {
+                               .video_input    = 1,
+                               .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",
+                       },
+               },
+       },
+};
+
+static const struct go7007_usb_board board_ads_usbav_709 = {
+       .flags          = GO7007_USB_EZUSB,
+       .main_info      = {
+               .flags           = GO7007_BOARD_HAS_AUDIO |
+                                       GO7007_BOARD_USE_ONBOARD_I2C,
+               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
+                                       GO7007_AUDIO_I2S_MASTER |
+                                       GO7007_AUDIO_WORD_16,
+               .audio_rate      = 48000,
+               .audio_bclk_div  = 8,
+               .audio_main_div  = 2,
+               .hpi_buffer_cap  = 7,
+               .sensor_flags    = GO7007_SENSOR_656 |
+                                       GO7007_SENSOR_TV |
+                                       GO7007_SENSOR_VBI,
+               .num_i2c_devs    = 1,
+               .i2c_devs        = {
+                       {
+                               .type   = "tw9906",
+                               .is_video = 1,
+                               .addr   = 0x44,
+                       },
+               },
+               .num_inputs      = 2,
+               .inputs          = {
+                       {
+                               .video_input    = 0,
+                               .name           = "Composite",
+                       },
+                       {
+                               .video_input    = 10,
+                               .name           = "S-Video",
+                       },
+               },
+       },
+};
+
+static const struct usb_device_id go7007_usb_id_table[] = {
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
+                                       USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
+               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
+               .bcdDevice_lo   = 0x200,   /* Revision number of XMen */
+               .bcdDevice_hi   = 0x200,
+               .bInterfaceClass        = 255,
+               .bInterfaceSubClass     = 0,
+               .bInterfaceProtocol     = 255,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
+               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
+               .bcdDevice_lo   = 0x202,   /* Revision number of Matrix II */
+               .bcdDevice_hi   = 0x202,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_MATRIX_II,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
+               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
+               .bcdDevice_lo   = 0x204,   /* Revision number of Matrix */
+               .bcdDevice_hi   = 0x204,   /*     Reloaded */
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_MATRIX_RELOAD,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
+                                       USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
+               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
+               .bcdDevice_lo   = 0x205,   /* Revision number of XMen-II */
+               .bcdDevice_hi   = 0x205,
+               .bInterfaceClass        = 255,
+               .bInterfaceSubClass     = 0,
+               .bInterfaceProtocol     = 255,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN_II,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
+               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
+               .bcdDevice_lo   = 0x208,   /* Revision number of Star Trek */
+               .bcdDevice_hi   = 0x208,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_STAR_TREK,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
+                                       USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
+               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
+               .bcdDevice_lo   = 0x209,   /* Revision number of XMen-III */
+               .bcdDevice_hi   = 0x209,
+               .bInterfaceClass        = 255,
+               .bInterfaceSubClass     = 0,
+               .bInterfaceProtocol     = 255,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN_III,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
+               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
+               .bcdDevice_lo   = 0x210,   /* Revision number of Matrix */
+               .bcdDevice_hi   = 0x210,   /*     Revolution */
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_MATRIX_REV,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+               .idVendor       = 0x093b,  /* Vendor ID of Plextor */
+               .idProduct      = 0xa102,  /* Product ID of M402U */
+               .bcdDevice_lo   = 0x1,     /* revision number of Blueberry */
+               .bcdDevice_hi   = 0x1,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_PX_M402U,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+               .idVendor       = 0x093b,  /* Vendor ID of Plextor */
+               .idProduct      = 0xa104,  /* Product ID of TV402U */
+               .bcdDevice_lo   = 0x1,
+               .bcdDevice_hi   = 0x1,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_PX_TV402U,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+               .idVendor       = 0x10fd,  /* Vendor ID of Anubis Electronics */
+               .idProduct      = 0xde00,  /* Product ID of Lifeview LR192 */
+               .bcdDevice_lo   = 0x1,
+               .bcdDevice_hi   = 0x1,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+               .idVendor       = 0x1943,  /* Vendor ID Sensoray */
+               .idProduct      = 0x2250,  /* Product ID of 2250/2251 */
+               .bcdDevice_lo   = 0x1,
+               .bcdDevice_hi   = 0x1,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_SENSORAY_2250,
+       },
+       {
+               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+               .idVendor       = 0x06e1,  /* Vendor ID of ADS Technologies */
+               .idProduct      = 0x0709,  /* Product ID of DVD Xpress DX2 */
+               .bcdDevice_lo   = 0x204,
+               .bcdDevice_hi   = 0x204,
+               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_ADS_USBAV_709,
+       },
+       { }                                     /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, go7007_usb_id_table);
+
+/********************* Driver for EZ-USB HPI interface *********************/
+
+static int go7007_usb_vendor_request(struct go7007 *go, int request,
+               int value, int index, void *transfer_buffer, int length, int in)
+{
+       struct go7007_usb *usb = go->hpi_context;
+       int timeout = 5000;
+
+       if (in) {
+               return usb_control_msg(usb->usbdev,
+                               usb_rcvctrlpipe(usb->usbdev, 0), request,
+                               USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+                               value, index, transfer_buffer, length, timeout);
+       } else {
+               return usb_control_msg(usb->usbdev,
+                               usb_sndctrlpipe(usb->usbdev, 0), request,
+                               USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               value, index, transfer_buffer, length, timeout);
+       }
+}
+
+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;
+       msleep(100);
+
+       if (usb->board->flags & GO7007_USB_EZUSB) {
+               /* Reset buffer in EZ-USB */
+               pr_debug("resetting EZ-USB buffers\n");
+               if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
+                   go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
+                       return -1;
+
+               /* Reset encoder again */
+               if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
+                       return -1;
+               msleep(100);
+       }
+
+       /* Wait for an interrupt to indicate successful hardware reset */
+       if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
+                       (intr_val & ~0x1) != 0x55aa) {
+               dev_err(go->dev, "unable to reset the USB interface\n");
+               return -1;
+       }
+       return 0;
+}
+
+static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
+                                               int addr, int data)
+{
+       struct go7007_usb *usb = go->hpi_context;
+       int i, r;
+       u16 status_reg = 0;
+       int timeout = 500;
+
+       pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
+
+       for (i = 0; i < 100; ++i) {
+               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, go->usb_buf,
+                               sizeof(status_reg), timeout);
+               if (r < 0)
+                       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) {
+               dev_err(go->dev, "device is hung, status reg = 0x%04x\n", status_reg);
+               return -1;
+       }
+       r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
+                       USB_TYPE_VENDOR | USB_RECIP_DEVICE, data,
+                       INT_PARAM_ADDR, NULL, 0, timeout);
+       if (r < 0)
+               goto write_int_error;
+       r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0),
+                       0x12, USB_TYPE_VENDOR | USB_RECIP_DEVICE, addr,
+                       INT_INDEX_ADDR, NULL, 0, timeout);
+       if (r < 0)
+               goto write_int_error;
+       return 0;
+
+write_int_error:
+       dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
+       return r;
+}
+
+static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
+                                               int addr, int data)
+{
+       struct go7007_usb *usb = go->hpi_context;
+       int r;
+       int timeout = 500;
+
+       pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
+
+       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, go->usb_buf, 8, timeout);
+       if (r < 0) {
+               dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
+               return r;
+       }
+       return 0;
+}
+
+static void go7007_usb_readinterrupt_complete(struct urb *urb)
+{
+       struct go7007 *go = (struct go7007 *)urb->context;
+       u16 *regs = (u16 *)urb->transfer_buffer;
+       int status = urb->status;
+
+       if (status) {
+               if (status != -ESHUTDOWN &&
+                               go->status != STATUS_SHUTDOWN) {
+                       dev_err(go->dev, "error in read interrupt: %d\n", urb->status);
+               } else {
+                       wake_up(&go->interrupt_waitq);
+                       return;
+               }
+       } else if (urb->actual_length != urb->transfer_buffer_length) {
+               dev_err(go->dev, "short read in interrupt pipe!\n");
+       } else {
+               go->interrupt_available = 1;
+               go->interrupt_data = __le16_to_cpu(regs[0]);
+               go->interrupt_value = __le16_to_cpu(regs[1]);
+               pr_debug("ReadInterrupt: %04x %04x\n",
+                               go->interrupt_value, go->interrupt_data);
+       }
+
+       wake_up(&go->interrupt_waitq);
+}
+
+static int go7007_usb_read_interrupt(struct go7007 *go)
+{
+       struct go7007_usb *usb = go->hpi_context;
+       int r;
+
+       r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
+       if (r < 0) {
+               dev_err(go->dev, "unable to submit interrupt urb: %d\n", r);
+               return r;
+       }
+       return 0;
+}
+
+static void go7007_usb_read_video_pipe_complete(struct urb *urb)
+{
+       struct go7007 *go = (struct go7007 *)urb->context;
+       int r, status = urb->status;
+
+       if (!vb2_is_streaming(&go->vidq)) {
+               wake_up_interruptible(&go->frame_waitq);
+               return;
+       }
+       if (status) {
+               dev_err(go->dev, "error in video pipe: %d\n", status);
+               return;
+       }
+       if (urb->actual_length != urb->transfer_buffer_length) {
+               dev_err(go->dev, "short read in video pipe!\n");
+               return;
+       }
+       go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
+       r = usb_submit_urb(urb, GFP_ATOMIC);
+       if (r < 0)
+               dev_err(go->dev, "error in video pipe: %d\n", r);
+}
+
+static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
+{
+       struct go7007 *go = (struct go7007 *)urb->context;
+       int r, status = urb->status;
+
+       if (!vb2_is_streaming(&go->vidq))
+               return;
+       if (status) {
+               dev_err(go->dev, "error in audio pipe: %d\n",
+                       status);
+               return;
+       }
+       if (urb->actual_length != urb->transfer_buffer_length) {
+               dev_err(go->dev, "short read in audio pipe!\n");
+               return;
+       }
+       if (go->audio_deliver != NULL)
+               go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
+       r = usb_submit_urb(urb, GFP_ATOMIC);
+       if (r < 0)
+               dev_err(go->dev, "error in audio pipe: %d\n", r);
+}
+
+static int go7007_usb_stream_start(struct go7007 *go)
+{
+       struct go7007_usb *usb = go->hpi_context;
+       int i, r;
+
+       for (i = 0; i < 8; ++i) {
+               r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
+               if (r < 0) {
+                       dev_err(go->dev, "error submitting video urb %d: %d\n", i, r);
+                       goto video_submit_failed;
+               }
+       }
+       if (!go->audio_enabled)
+               return 0;
+
+       for (i = 0; i < 8; ++i) {
+               r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
+               if (r < 0) {
+                       dev_err(go->dev, "error submitting audio urb %d: %d\n", i, r);
+                       goto audio_submit_failed;
+               }
+       }
+       return 0;
+
+audio_submit_failed:
+       for (i = 0; i < 7; ++i)
+               usb_kill_urb(usb->audio_urbs[i]);
+video_submit_failed:
+       for (i = 0; i < 8; ++i)
+               usb_kill_urb(usb->video_urbs[i]);
+       return -1;
+}
+
+static int go7007_usb_stream_stop(struct go7007 *go)
+{
+       struct go7007_usb *usb = go->hpi_context;
+       int i;
+
+       if (go->status == STATUS_SHUTDOWN)
+               return 0;
+       for (i = 0; i < 8; ++i)
+               usb_kill_urb(usb->video_urbs[i]);
+       if (go->audio_enabled)
+               for (i = 0; i < 8; ++i)
+                       usb_kill_urb(usb->audio_urbs[i]);
+       return 0;
+}
+
+static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
+{
+       struct go7007_usb *usb = go->hpi_context;
+       int transferred, pipe;
+       int timeout = 500;
+
+       pr_debug("DownloadBuffer sending %d bytes\n", len);
+
+       if (usb->board->flags & GO7007_USB_EZUSB)
+               pipe = usb_sndbulkpipe(usb->usbdev, 2);
+       else
+               pipe = usb_sndbulkpipe(usb->usbdev, 3);
+
+       return usb_bulk_msg(usb->usbdev, pipe, data, len,
+                                       &transferred, timeout);
+}
+
+static void go7007_usb_release(struct go7007 *go)
+{
+       struct go7007_usb *usb = go->hpi_context;
+       struct urb *vurb, *aurb;
+       int i;
+
+       if (usb->intr_urb) {
+               usb_kill_urb(usb->intr_urb);
+               kfree(usb->intr_urb->transfer_buffer);
+               usb_free_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(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,
+       .read_interrupt         = go7007_usb_read_interrupt,
+       .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 = {
+       .interface_reset        = go7007_usb_interface_reset,
+       .write_interrupt        = go7007_usb_onboard_write_interrupt,
+       .read_interrupt         = go7007_usb_read_interrupt,
+       .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 *********************/
+
+static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
+                                       struct i2c_msg msgs[], int num)
+{
+       struct go7007 *go = i2c_get_adapdata(adapter);
+       struct go7007_usb *usb = go->hpi_context;
+       u8 *buf = go->usb_buf;
+       int buf_len, i;
+       int ret = -EIO;
+
+       if (go->status == STATUS_SHUTDOWN)
+               return -ENODEV;
+
+       mutex_lock(&usb->i2c_lock);
+
+       for (i = 0; i < num; ++i) {
+               /* The hardware command is "write some bytes then read some
+                * bytes", so we try to coalesce a write followed by a read
+                * into a single USB transaction */
+               if (i + 1 < num && msgs[i].addr == msgs[i + 1].addr &&
+                               !(msgs[i].flags & I2C_M_RD) &&
+                               (msgs[i + 1].flags & I2C_M_RD)) {
+#ifdef GO7007_I2C_DEBUG
+                       pr_debug("i2c write/read %d/%d bytes on %02x\n",
+                               msgs[i].len, msgs[i + 1].len, msgs[i].addr);
+#endif
+                       buf[0] = 0x01;
+                       buf[1] = msgs[i].len + 1;
+                       buf[2] = msgs[i].addr << 1;
+                       memcpy(&buf[3], msgs[i].buf, msgs[i].len);
+                       buf_len = msgs[i].len + 3;
+                       buf[buf_len++] = msgs[++i].len;
+               } else if (msgs[i].flags & I2C_M_RD) {
+#ifdef GO7007_I2C_DEBUG
+                       pr_debug("i2c read %d bytes on %02x\n",
+                                       msgs[i].len, msgs[i].addr);
+#endif
+                       buf[0] = 0x01;
+                       buf[1] = 1;
+                       buf[2] = msgs[i].addr << 1;
+                       buf[3] = msgs[i].len;
+                       buf_len = 4;
+               } else {
+#ifdef GO7007_I2C_DEBUG
+                       pr_debug("i2c write %d bytes on %02x\n",
+                                       msgs[i].len, msgs[i].addr);
+#endif
+                       buf[0] = 0x00;
+                       buf[1] = msgs[i].len + 1;
+                       buf[2] = msgs[i].addr << 1;
+                       memcpy(&buf[3], msgs[i].buf, msgs[i].len);
+                       buf_len = msgs[i].len + 3;
+                       buf[buf_len++] = 0;
+               }
+               if (go7007_usb_vendor_request(go, 0x24, 0, 0,
+                                               buf, buf_len, 0) < 0)
+                       goto i2c_done;
+               if (msgs[i].flags & I2C_M_RD) {
+                       memset(buf, 0, msgs[i].len + 1);
+                       if (go7007_usb_vendor_request(go, 0x25, 0, 0, buf,
+                                               msgs[i].len + 1, 1) < 0)
+                               goto i2c_done;
+                       memcpy(msgs[i].buf, buf + 1, msgs[i].len);
+               }
+       }
+       ret = num;
+
+i2c_done:
+       mutex_unlock(&usb->i2c_lock);
+       return ret;
+}
+
+static u32 go7007_usb_functionality(struct i2c_adapter *adapter)
+{
+       /* No errors are reported by the hardware, so we don't bother
+        * supporting quick writes to avoid confusing probing */
+       return (I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK;
+}
+
+static struct i2c_algorithm go7007_usb_algo = {
+       .master_xfer    = go7007_usb_i2c_master_xfer,
+       .functionality  = go7007_usb_functionality,
+};
+
+static struct i2c_adapter go7007_usb_adap_templ = {
+       .owner                  = THIS_MODULE,
+       .name                   = "WIS GO7007SB EZ-USB",
+       .algo                   = &go7007_usb_algo,
+};
+
+/********************* USB add/remove functions *********************/
+
+static int go7007_usb_probe(struct usb_interface *intf,
+               const struct usb_device_id *id)
+{
+       struct go7007 *go;
+       struct go7007_usb *usb;
+       const 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;
+
+       pr_debug("probing new GO7007 USB board\n");
+
+       switch (id->driver_info) {
+       case GO7007_BOARDID_MATRIX_II:
+               name = "WIS Matrix II or compatible";
+               board = &board_matrix_ii;
+               break;
+       case GO7007_BOARDID_MATRIX_RELOAD:
+               name = "WIS Matrix Reloaded or compatible";
+               board = &board_matrix_reload;
+               break;
+       case GO7007_BOARDID_MATRIX_REV:
+               name = "WIS Matrix Revolution or compatible";
+               board = &board_matrix_revolution;
+               break;
+       case GO7007_BOARDID_STAR_TREK:
+               name = "WIS Star Trek or compatible";
+               board = &board_star_trek;
+               break;
+       case GO7007_BOARDID_XMEN:
+               name = "WIS XMen or compatible";
+               board = &board_xmen;
+               break;
+       case GO7007_BOARDID_XMEN_II:
+               name = "WIS XMen II or compatible";
+               board = &board_xmen;
+               break;
+       case GO7007_BOARDID_XMEN_III:
+               name = "WIS XMen III or compatible";
+               board = &board_xmen;
+               break;
+       case GO7007_BOARDID_PX_M402U:
+               name = "Plextor PX-M402U";
+               board = &board_matrix_ii;
+               break;
+       case GO7007_BOARDID_PX_TV402U:
+               name = "Plextor PX-TV402U (unknown tuner)";
+               board = &board_px_tv402u;
+               break;
+       case GO7007_BOARDID_LIFEVIEW_LR192:
+               dev_err(&intf->dev, "The Lifeview TV Walker Ultra is not supported. Sorry!\n");
+               return -ENODEV;
+               name = "Lifeview TV Walker Ultra";
+               board = &board_lifeview_lr192;
+               break;
+       case GO7007_BOARDID_SENSORAY_2250:
+               dev_info(&intf->dev, "Sensoray 2250 found\n");
+               name = "Sensoray 2250/2251";
+               board = &board_sensoray_2250;
+               break;
+       case GO7007_BOARDID_ADS_USBAV_709:
+               name = "ADS Tech DVD Xpress DX2";
+               board = &board_ads_usbav_709;
+               break;
+       default:
+               dev_err(&intf->dev, "unknown board ID %d!\n",
+                               (unsigned int)id->driver_info);
+               return -ENODEV;
+       }
+
+       go = go7007_alloc(&board->main_info, &intf->dev);
+       if (go == NULL)
+               return -ENOMEM;
+
+       usb = kzalloc(sizeof(struct go7007_usb), GFP_KERNEL);
+       if (usb == NULL) {
+               kfree(go);
+               return -ENOMEM;
+       }
+
+       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)
+               go->hpi_ops = &go7007_usb_ezusb_hpi_ops;
+       else
+               go->hpi_ops = &go7007_usb_onboard_hpi_ops;
+       go->hpi_context = usb;
+
+       /* Allocate the URB and buffer for receiving incoming interrupts */
+       usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (usb->intr_urb == NULL)
+               goto allocfail;
+       usb->intr_urb->transfer_buffer = kmalloc(2*sizeof(u16), GFP_KERNEL);
+       if (usb->intr_urb->transfer_buffer == NULL)
+               goto allocfail;
+
+       if (go->board_id == GO7007_BOARDID_SENSORAY_2250)
+               usb_fill_bulk_urb(usb->intr_urb, usb->usbdev,
+                       usb_rcvbulkpipe(usb->usbdev, 4),
+                       usb->intr_urb->transfer_buffer, 2*sizeof(u16),
+                       go7007_usb_readinterrupt_complete, go);
+       else
+               usb_fill_int_urb(usb->intr_urb, usb->usbdev,
+                       usb_rcvintpipe(usb->usbdev, 4),
+                       usb->intr_urb->transfer_buffer, 2*sizeof(u16),
+                       go7007_usb_readinterrupt_complete, go, 8);
+       usb_set_intfdata(intf, &go->v4l2_dev);
+
+       /* Boot the GO7007 */
+       if (go7007_boot_encoder(go, go->board_info->flags &
+                                       GO7007_BOARD_USE_ONBOARD_I2C) < 0)
+               goto allocfail;
+
+       /* Register the EZ-USB I2C adapter, if we're using it */
+       if (board->flags & GO7007_USB_EZUSB_I2C) {
+               memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
+                               sizeof(go7007_usb_adap_templ));
+               mutex_init(&usb->i2c_lock);
+               go->i2c_adapter.dev.parent = go->dev;
+               i2c_set_adapdata(&go->i2c_adapter, go);
+               if (i2c_add_adapter(&go->i2c_adapter) < 0) {
+                       dev_err(go->dev, "error: i2c_add_adapter failed\n");
+                       goto allocfail;
+               }
+               go->i2c_adapter_online = 1;
+       }
+
+       /* Pelco and Adlink reused the XMen and XMen-III vendor and product
+        * IDs for their own incompatible designs.  We can detect XMen boards
+        * by probing the sensor, but there is no way to probe the sensors on
+        * the Pelco and Adlink designs so we default to the Adlink.  If it
+        * is actually a Pelco, the user must set the assume_endura module
+        * parameter. */
+       if ((go->board_id == GO7007_BOARDID_XMEN ||
+                               go->board_id == GO7007_BOARDID_XMEN_III) &&
+                       go->i2c_adapter_online) {
+               union i2c_smbus_data data;
+
+               /* Check to see if register 0x0A is 0x76 */
+               i2c_smbus_xfer(&go->i2c_adapter, 0x21, I2C_CLIENT_SCCB,
+                       I2C_SMBUS_READ, 0x0A, I2C_SMBUS_BYTE_DATA, &data);
+               if (data.byte != 0x76) {
+                       if (assume_endura) {
+                               go->board_id = GO7007_BOARDID_ENDURA;
+                               usb->board = board = &board_endura;
+                               go->board_info = &board->main_info;
+                               strncpy(go->name, "Pelco Endura",
+                                       sizeof(go->name));
+                       } else {
+                               u16 channel;
+
+                               /* read channel number from GPIO[1:0] */
+                               go7007_read_addr(go, 0x3c81, &channel);
+                               channel &= 0x3;
+                               go->board_id = GO7007_BOARDID_ADLINK_MPG24;
+                               usb->board = board = &board_adlink_mpg24;
+                               go->board_info = &board->main_info;
+                               go->channel_number = channel;
+                               snprintf(go->name, sizeof(go->name),
+                                       "Adlink PCI-MPG24, channel #%d",
+                                       channel);
+                       }
+                       go7007_update_board(go);
+               }
+       }
+
+       num_i2c_devs = go->board_info->num_i2c_devs;
+
+       /* Probe the tuner model on the TV402U */
+       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) {
+                       dev_err(go->dev, "GPIO read failed!\n");
+                       goto allocfail;
+               }
+               switch (go->usb_buf[0] >> 6) {
+               case 1:
+                       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->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));
+                       break;
+               case 3:
+                       go->tuner_type = TUNER_SONY_BTF_PB463Z;
+                       num_i2c_devs -= 2;
+                       strncpy(go->name, "Plextor PX-TV402U-NA",
+                                       sizeof(go->name));
+                       break;
+               default:
+                       pr_debug("unable to detect tuner type!\n");
+                       break;
+               }
+               /* Configure tuner mode selection inputs connected
+                * to the EZ-USB GPIO output pins */
+               if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
+                                       NULL, 0, 0) < 0) {
+                       dev_err(go->dev, "GPIO write failed!\n");
+                       goto allocfail;
+               }
+       }
+
+       /* Print a nasty message if the user attempts to use a USB2.0 device in
+        * a USB1.1 port.  There will be silent corruption of the stream. */
+       if ((board->flags & GO7007_USB_EZUSB) &&
+                       usbdev->speed != USB_SPEED_HIGH)
+               dev_err(go->dev, "*** WARNING ***  This device must be connected to a USB 2.0 port! Attempting to capture video through a USB 1.1 port will result in stream corruption, even at low bitrates!\n");
+
+       /* Allocate the URBs and buffers for receiving the video stream */
+       if (board->flags & GO7007_USB_EZUSB) {
+               v_urb_len = 1024;
+               video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
+       } else {
+               v_urb_len = 512;
+               video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
+       }
+       for (i = 0; i < 8; ++i) {
+               usb->video_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
+               if (usb->video_urbs[i] == NULL)
+                       goto allocfail;
+               usb->video_urbs[i]->transfer_buffer =
+                                               kmalloc(v_urb_len, GFP_KERNEL);
+               if (usb->video_urbs[i]->transfer_buffer == NULL)
+                       goto allocfail;
+               usb_fill_bulk_urb(usb->video_urbs[i], usb->usbdev, video_pipe,
+                               usb->video_urbs[i]->transfer_buffer, v_urb_len,
+                               go7007_usb_read_video_pipe_complete, go);
+       }
+
+       /* Allocate the URBs and buffers for receiving the audio stream */
+       if ((board->flags & GO7007_USB_EZUSB) &&
+           (board->flags & GO7007_BOARD_HAS_AUDIO)) {
+               for (i = 0; i < 8; ++i) {
+                       usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
+                       if (usb->audio_urbs[i] == NULL)
+                               goto allocfail;
+                       usb->audio_urbs[i]->transfer_buffer = kmalloc(4096,
+                                                               GFP_KERNEL);
+                       if (usb->audio_urbs[i]->transfer_buffer == NULL)
+                               goto allocfail;
+                       usb_fill_bulk_urb(usb->audio_urbs[i], usb->usbdev,
+                               usb_rcvbulkpipe(usb->usbdev, 8),
+                               usb->audio_urbs[i]->transfer_buffer, 4096,
+                               go7007_usb_read_audio_pipe_complete, go);
+               }
+       }
+
+       /* Do any final GO7007 initialization, then register the
+        * V4L2 and ALSA interfaces */
+       if (go7007_register_encoder(go, num_i2c_devs) < 0)
+               goto allocfail;
+
+       go->status = STATUS_ONLINE;
+       return 0;
+
+allocfail:
+       go7007_usb_release(go);
+       kfree(go);
+       return -ENOMEM;
+}
+
+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->vdev);
+       mutex_unlock(&go->serialize_lock);
+       mutex_unlock(&go->queue_lock);
+
+       v4l2_device_put(&go->v4l2_dev);
+}
+
+static struct usb_driver go7007_usb_driver = {
+       .name           = "go7007",
+       .probe          = go7007_usb_probe,
+       .disconnect     = go7007_usb_disconnect,
+       .id_table       = go7007_usb_id_table,
+};
+
+module_usb_driver(go7007_usb_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c
new file mode 100644 (file)
index 0000000..ec799b4
--- /dev/null
@@ -0,0 +1,1173 @@
+/*
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/unistd.h>
+#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 <media/v4l2-event.h>
+#include <media/videobuf2-vmalloc.h>
+#include <media/saa7115.h>
+
+#include "go7007-priv.h"
+
+#define call_all(dev, o, f, args...) \
+       v4l2_device_call_until_err(dev, 0, o, f, ##args)
+
+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 *vb, int format)
+{
+       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 ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
+               case 0:
+                       return V4L2_BUF_FLAG_KEYFRAME;
+               case 1:
+                       return V4L2_BUF_FLAG_PFRAME;
+               case 2:
+                       return V4L2_BUF_FLAG_BFRAME;
+               default:
+                       return 0;
+               }
+       case V4L2_PIX_FMT_MPEG1:
+       case V4L2_PIX_FMT_MPEG2:
+               switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
+               case 1:
+                       return V4L2_BUF_FLAG_KEYFRAME;
+               case 2:
+                       return V4L2_BUF_FLAG_PFRAME;
+               case 3:
+                       return V4L2_BUF_FLAG_BFRAME;
+               default:
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+static void get_resolution(struct go7007 *go, int *width, int *height)
+{
+       switch (go->standard) {
+       case GO7007_STD_NTSC:
+               *width = 720;
+               *height = 480;
+               break;
+       case GO7007_STD_PAL:
+               *width = 720;
+               *height = 576;
+               break;
+       case GO7007_STD_OTHER:
+       default:
+               *width = go->board_info->sensor_width;
+               *height = go->board_info->sensor_height;
+               break;
+       }
+}
+
+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->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
+       go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
+       go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
+       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->ipb == 0 &&
+                       go->repeat_seqhead == 1 &&
+                       go->closed_gop;
+
+       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;
+
+       if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
+               return -EINVAL;
+
+       get_resolution(go, &sensor_width, &sensor_height);
+
+       if (fmt == NULL) {
+               width = sensor_width;
+               height = sensor_height;
+       } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
+               if (fmt->fmt.pix.width > sensor_width)
+                       width = sensor_width;
+               else if (fmt->fmt.pix.width < 144)
+                       width = 144;
+               else
+                       width = fmt->fmt.pix.width & ~0x0f;
+
+               if (fmt->fmt.pix.height > sensor_height)
+                       height = sensor_height;
+               else if (fmt->fmt.pix.height < 96)
+                       height = 96;
+               else
+                       height = fmt->fmt.pix.height & ~0x0f;
+       } else {
+               width = fmt->fmt.pix.width;
+
+               if (width <= sensor_width / 4) {
+                       width = sensor_width / 4;
+                       height = sensor_height / 4;
+               } else if (width <= sensor_width / 2) {
+                       width = sensor_width / 2;
+                       height = sensor_height / 2;
+               } else {
+                       width = sensor_width;
+                       height = sensor_height;
+               }
+               width &= ~0xf;
+               height &= ~0xf;
+       }
+
+       if (fmt != NULL) {
+               u32 pixelformat = fmt->fmt.pix.pixelformat;
+
+               memset(fmt, 0, sizeof(*fmt));
+               fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+               fmt->fmt.pix.width = width;
+               fmt->fmt.pix.height = height;
+               fmt->fmt.pix.pixelformat = pixelformat;
+               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;
+       }
+
+       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;
+       go->encoder_v_offset = go->board_info->sensor_v_offset;
+
+       if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
+               struct v4l2_mbus_framefmt mbus_fmt;
+
+               mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
+               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) {
+                       go->encoder_h_halve = 1;
+                       go->encoder_v_halve = 1;
+                       go->encoder_subsample = 1;
+               } else if (width <= sensor_width / 2) {
+                       go->encoder_h_halve = 1;
+                       go->encoder_v_halve = 1;
+                       go->encoder_subsample = 0;
+               } else {
+                       go->encoder_h_halve = 0;
+                       go->encoder_v_halve = 0;
+                       go->encoder_subsample = 0;
+               }
+       }
+       return 0;
+}
+
+static int vidioc_querycap(struct file *file, void  *priv,
+                                       struct v4l2_capability *cap)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       strlcpy(cap->driver, "go7007", sizeof(cap->driver));
+       strlcpy(cap->card, go->name, sizeof(cap->card));
+       strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
+
+       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;
+       if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
+               cap->device_caps |= V4L2_CAP_TUNER;
+       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+       return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
+                                       struct v4l2_fmtdesc *fmt)
+{
+       char *desc = NULL;
+
+       switch (fmt->index) {
+       case 0:
+               fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
+               desc = "Motion JPEG";
+               break;
+       case 1:
+               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;
+       }
+       fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
+
+       strncpy(fmt->description, desc, sizeof(fmt->description));
+
+       return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+                                       struct v4l2_format *fmt)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       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;
+       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;
+
+       return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+                       struct v4l2_format *fmt)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       return set_capture_size(go, fmt, 1);
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+                       struct v4l2_format *fmt)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       if (vb2_is_busy(&go->vidq))
+               return -EBUSY;
+
+       return set_capture_size(go, fmt, 0);
+}
+
+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[])
+{
+       sizes[0] = GO7007_BUF_SIZE;
+       *num_planes = 1;
+
+       if (*num_buffers < 2)
+               *num_buffers = 2;
+
+       return 0;
+}
+
+static void go7007_buf_queue(struct vb2_buffer *vb)
+{
+       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;
+
+       spin_lock_irqsave(&go->spinlock, flags);
+       list_add_tail(&go7007_vb->list, &go->vidq_active);
+       spin_unlock_irqrestore(&go->spinlock, flags);
+}
+
+static int go7007_buf_prepare(struct vb2_buffer *vb)
+{
+       struct go7007_buffer *go7007_vb =
+               container_of(vb, struct go7007_buffer, vb);
+
+       go7007_vb->modet_active = 0;
+       go7007_vb->frame_offset = 0;
+       vb->v4l2_planes[0].bytesused = 0;
+       return 0;
+}
+
+static void go7007_buf_finish(struct vb2_buffer *vb)
+{
+       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;
+}
+
+static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+       struct go7007 *go = vb2_get_drv_priv(q);
+       int ret;
+
+       set_formatting(go);
+       mutex_lock(&go->hw_lock);
+       go->next_seq = 0;
+       go->active_buf = NULL;
+       go->modet_event_status = 0;
+       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);
+       /* Turn on Capture LED */
+       if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
+               go7007_write_addr(go, 0x3c82, 0x0005);
+       return ret;
+}
+
+static void go7007_stop_streaming(struct vb2_queue *q)
+{
+       struct go7007 *go = vb2_get_drv_priv(q);
+       unsigned long flags;
+
+       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);
+       /* Turn on Capture LED */
+       if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
+               go7007_write_addr(go, 0x3c82, 0x000d);
+}
+
+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)
+{
+       struct go7007 *go = video_drvdata(filp);
+       struct v4l2_fract timeperframe = {
+               .numerator = 1001 *  go->fps_scale,
+               .denominator = go->sensor_framerate,
+       };
+
+       if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       parm->parm.capture.readbuffers = 2;
+       parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+       parm->parm.capture.timeperframe = timeperframe;
+
+       return 0;
+}
+
+static int vidioc_s_parm(struct file *filp, void *priv,
+               struct v4l2_streamparm *parm)
+{
+       struct go7007 *go = video_drvdata(filp);
+       unsigned int n, d;
+
+       if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       n = go->sensor_framerate *
+               parm->parm.capture.timeperframe.numerator;
+       d = 1001 * parm->parm.capture.timeperframe.denominator;
+       if (n != 0 && d != 0 && n > d)
+               go->fps_scale = (n + d/2) / d;
+       else
+               go->fps_scale = 1;
+
+       return vidioc_g_parm(filp, priv, parm);
+}
+
+/* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
+   its resolution, when the device is not connected to TV.
+   This is were an API abuse, probably used by the lack of specific IOCTL's to
+   enumerate it, by the time the driver was written.
+
+   However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
+   and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
+
+   The two functions below implement the newer ioctls
+*/
+static int vidioc_enum_framesizes(struct file *filp, void *priv,
+                                 struct v4l2_frmsizeenum *fsize)
+{
+       struct go7007 *go = video_drvdata(filp);
+       int width, height;
+
+       if (fsize->index > 2)
+               return -EINVAL;
+
+       if (!valid_pixelformat(fsize->pixel_format))
+               return -EINVAL;
+
+       get_resolution(go, &width, &height);
+       fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+       fsize->discrete.width = (width >> fsize->index) & ~0xf;
+       fsize->discrete.height = (height >> fsize->index) & ~0xf;
+       return 0;
+}
+
+static int vidioc_enum_frameintervals(struct file *filp, void *priv,
+                                     struct v4l2_frmivalenum *fival)
+{
+       struct go7007 *go = video_drvdata(filp);
+       int width, height;
+       int i;
+
+       if (fival->index > 4)
+               return -EINVAL;
+
+       if (!valid_pixelformat(fival->pixel_format))
+               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->index + 1);
+       fival->discrete.denominator = go->sensor_framerate;
+       return 0;
+}
+
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       *std = go->std;
+       return 0;
+}
+
+static int go7007_s_std(struct go7007 *go)
+{
+       if (go->std & V4L2_STD_625_50) {
+               go->standard = GO7007_STD_PAL;
+               go->sensor_framerate = 25025;
+       } else {
+               go->standard = GO7007_STD_NTSC;
+               go->sensor_framerate = 30000;
+       }
+
+       call_all(&go->v4l2_dev, video, 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 = video_drvdata(file);
+
+       if (vb2_is_busy(&go->vidq))
+               return -EBUSY;
+
+       go->std = std;
+
+       return go7007_s_std(go);
+}
+
+static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       return call_all(&go->v4l2_dev, video, querystd, std);
+}
+
+static int vidioc_enum_input(struct file *file, void *priv,
+                               struct v4l2_input *inp)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       if (inp->index >= go->board_info->num_inputs)
+               return -EINVAL;
+
+       strncpy(inp->name, go->board_info->inputs[inp->index].name,
+                       sizeof(inp->name));
+
+       /* If this board has a tuner, it will be the first input */
+       if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
+                       inp->index == 0)
+               inp->type = V4L2_INPUT_TYPE_TUNER;
+       else
+               inp->type = V4L2_INPUT_TYPE_CAMERA;
+
+       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 = video_devdata(file)->tvnorms;
+       else
+               inp->std = 0;
+
+       return 0;
+}
+
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       *input = go->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 void go7007_s_input(struct go7007 *go)
+{
+       unsigned int input = go->input;
+
+       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;
+       }
+}
+
+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 (vb2_is_busy(&go->vidq))
+               return -EBUSY;
+
+       go->input = input;
+       go7007_s_input(go);
+
+       return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+                               struct v4l2_tuner *t)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       if (t->index != 0)
+               return -EINVAL;
+
+       strlcpy(t->name, "Tuner", sizeof(t->name));
+       return call_all(&go->v4l2_dev, tuner, g_tuner, t);
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+                               const struct v4l2_tuner *t)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       if (t->index != 0)
+               return -EINVAL;
+
+       return call_all(&go->v4l2_dev, tuner, s_tuner, t);
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+                               struct v4l2_frequency *f)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       if (f->tuner)
+               return -EINVAL;
+
+       return call_all(&go->v4l2_dev, tuner, g_frequency, f);
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+                               const struct v4l2_frequency *f)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       if (f->tuner)
+               return -EINVAL;
+
+       return call_all(&go->v4l2_dev, tuner, s_frequency, f);
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+       struct go7007 *go = video_drvdata(file);
+
+       v4l2_ctrl_log_status(file, priv);
+       return call_all(&go->v4l2_dev, core, log_status);
+}
+
+static int vidioc_subscribe_event(struct v4l2_fh *fh,
+                               const struct v4l2_event_subscription *sub)
+{
+
+       switch (sub->type) {
+       case V4L2_EVENT_CTRL:
+               return v4l2_ctrl_subscribe_event(fh, sub);
+       case V4L2_EVENT_MOTION_DET:
+               /* Allow for up to 30 events (1 second for NTSC) to be
+                * stored. */
+               return v4l2_event_subscribe(fh, sub, 30, NULL);
+       }
+       return -EINVAL;
+}
+
+
+static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       struct go7007 *go =
+               container_of(ctrl->handler, struct go7007, hdl);
+       unsigned y;
+       u8 *mt;
+
+       switch (ctrl->id) {
+       case V4L2_CID_PIXEL_THRESHOLD0:
+               go->modet[0].pixel_threshold = ctrl->val;
+               break;
+       case V4L2_CID_MOTION_THRESHOLD0:
+               go->modet[0].motion_threshold = ctrl->val;
+               break;
+       case V4L2_CID_MB_THRESHOLD0:
+               go->modet[0].mb_threshold = ctrl->val;
+               break;
+       case V4L2_CID_PIXEL_THRESHOLD1:
+               go->modet[1].pixel_threshold = ctrl->val;
+               break;
+       case V4L2_CID_MOTION_THRESHOLD1:
+               go->modet[1].motion_threshold = ctrl->val;
+               break;
+       case V4L2_CID_MB_THRESHOLD1:
+               go->modet[1].mb_threshold = ctrl->val;
+               break;
+       case V4L2_CID_PIXEL_THRESHOLD2:
+               go->modet[2].pixel_threshold = ctrl->val;
+               break;
+       case V4L2_CID_MOTION_THRESHOLD2:
+               go->modet[2].motion_threshold = ctrl->val;
+               break;
+       case V4L2_CID_MB_THRESHOLD2:
+               go->modet[2].mb_threshold = ctrl->val;
+               break;
+       case V4L2_CID_PIXEL_THRESHOLD3:
+               go->modet[3].pixel_threshold = ctrl->val;
+               break;
+       case V4L2_CID_MOTION_THRESHOLD3:
+               go->modet[3].motion_threshold = ctrl->val;
+               break;
+       case V4L2_CID_MB_THRESHOLD3:
+               go->modet[3].mb_threshold = ctrl->val;
+               break;
+       case V4L2_CID_DETECT_MD_REGION_GRID:
+               mt = go->modet_map;
+               for (y = 0; y < go->height / 16; y++, mt += go->width / 16)
+                       memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static struct v4l2_file_operations go7007_fops = {
+       .owner          = THIS_MODULE,
+       .open           = v4l2_fh_open,
+       .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 = {
+       .vidioc_querycap          = vidioc_querycap,
+       .vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
+       .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           = 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,
+       .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_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,
+       .vidioc_s_frequency       = vidioc_s_frequency,
+       .vidioc_g_parm            = vidioc_g_parm,
+       .vidioc_s_parm            = vidioc_s_parm,
+       .vidioc_enum_framesizes   = vidioc_enum_framesizes,
+       .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
+       .vidioc_log_status        = vidioc_log_status,
+       .vidioc_subscribe_event   = vidioc_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static struct video_device go7007_template = {
+       .name           = "go7007",
+       .fops           = &go7007_fops,
+       .release        = video_device_release_empty,
+       .ioctl_ops      = &video_ioctl_ops,
+       .tvnorms        = V4L2_STD_ALL,
+};
+
+static const struct v4l2_ctrl_ops go7007_ctrl_ops = {
+       .s_ctrl = go7007_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_PIXEL_THRESHOLD0,
+       .name = "Pixel Threshold Region 0",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 20,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_MOTION_THRESHOLD0,
+       .name = "Motion Threshold Region 0",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 80,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_MB_THRESHOLD0,
+       .name = "MB Threshold Region 0",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 200,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_PIXEL_THRESHOLD1,
+       .name = "Pixel Threshold Region 1",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 20,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_MOTION_THRESHOLD1,
+       .name = "Motion Threshold Region 1",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 80,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_MB_THRESHOLD1,
+       .name = "MB Threshold Region 1",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 200,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_PIXEL_THRESHOLD2,
+       .name = "Pixel Threshold Region 2",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 20,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_MOTION_THRESHOLD2,
+       .name = "Motion Threshold Region 2",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 80,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_MB_THRESHOLD2,
+       .name = "MB Threshold Region 2",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 200,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_PIXEL_THRESHOLD3,
+       .name = "Pixel Threshold Region 3",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 20,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_MOTION_THRESHOLD3,
+       .name = "Motion Threshold Region 3",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 80,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_MB_THRESHOLD3,
+       .name = "MB Threshold Region 3",
+       .type = V4L2_CTRL_TYPE_INTEGER,
+       .def = 200,
+       .max = 32767,
+       .step = 1,
+};
+
+static const struct v4l2_ctrl_config go7007_mb_regions_ctrl = {
+       .ops = &go7007_ctrl_ops,
+       .id = V4L2_CID_DETECT_MD_REGION_GRID,
+       .dims = { 576 / 16, 720 / 16 },
+       .max = 3,
+       .step = 1,
+};
+
+int go7007_v4l2_ctrl_init(struct go7007 *go)
+{
+       struct v4l2_ctrl_handler *hdl = &go->hdl;
+       struct v4l2_ctrl *ctrl;
+
+       v4l2_ctrl_handler_init(hdl, 22);
+       go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
+                       V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
+       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, 9800000);
+       go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
+                       V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
+       go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
+                       V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
+
+       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);
+       if (ctrl)
+               ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+       v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold0_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold0_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold0_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold1_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold1_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold1_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold2_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold2_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold2_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold3_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold3_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold3_ctrl, NULL);
+       v4l2_ctrl_new_custom(hdl, &go7007_mb_regions_ctrl, NULL);
+       go->modet_mode = v4l2_ctrl_new_std_menu(hdl, NULL,
+                       V4L2_CID_DETECT_MD_MODE,
+                       V4L2_DETECT_MD_MODE_REGION_GRID,
+                       1 << V4L2_DETECT_MD_MODE_THRESHOLD_GRID,
+                       V4L2_DETECT_MD_MODE_DISABLED);
+       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)
+{
+       struct video_device *vdev = &go->vdev;
+       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_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       go->vidq.lock = &go->queue_lock;
+       rv = vb2_queue_init(&go->vidq);
+       if (rv)
+               return rv;
+       *vdev = go7007_template;
+       vdev->lock = &go->serialize_lock;
+       vdev->queue = &go->vidq;
+       video_set_drvdata(vdev, go);
+       vdev->v4l2_dev = &go->v4l2_dev;
+       if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
+               v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
+       if (!(go->board_info->flags & GO7007_BOARD_HAS_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,
+                       .frequency = 980,
+               };
+
+               call_all(&go->v4l2_dev, tuner, s_frequency, &f);
+       }
+       if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
+               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(vdev, VIDIOC_ENUM_FRAMESIZES);
+       if (go->board_info->num_aud_inputs == 0) {
+               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)
+               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);
+       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(vdev));
+
+       return 0;
+}
+
+void go7007_v4l2_remove(struct go7007 *go)
+{
+       v4l2_ctrl_handler_free(&go->hdl);
+}
diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c
new file mode 100644 (file)
index 0000000..bb84668
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/slab.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-subdev.h>
+#include "go7007-priv.h"
+
+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
+#define VPX322_ADDR_BRIGHTNESS1                0x0131
+#define VPX322_ADDR_CONTRAST0          0x0128
+#define VPX322_ADDR_CONTRAST1          0x0132
+#define VPX322_ADDR_HUE                        0x00dc
+#define VPX322_ADDR_SAT                        0x0030
+
+struct go7007_usb_board {
+       unsigned int flags;
+       struct go7007_board_info main_info;
+};
+
+struct go7007_usb {
+       struct go7007_usb_board *board;
+       struct mutex i2c_lock;
+       struct usb_device *usbdev;
+       struct urb *video_urbs[8];
+       struct urb *audio_urbs[8];
+       struct urb *intr_urb;
+};
+
+static unsigned char aud_regs[] = {
+       0x1e, 0x00,
+       0x00, 0x17,
+       0x02, 0x17,
+       0x04, 0xf9,
+       0x06, 0xf9,
+       0x08, 0x02,
+       0x0a, 0x00,
+       0x0c, 0x00,
+       0x0a, 0x00,
+       0x0c, 0x00,
+       0x0e, 0x02,
+       0x10, 0x00,
+       0x12, 0x01,
+       0x00, 0x00,
+};
+
+
+static unsigned char vid_regs[] = {
+       0xF2, 0x0f,
+       0xAA, 0x00,
+       0xF8, 0xff,
+       0x00, 0x00,
+};
+
+static u16 vid_regs_fp[] = {
+       0x028, 0x067,
+       0x120, 0x016,
+       0x121, 0xcF2,
+       0x122, 0x0F2,
+       0x123, 0x00c,
+       0x124, 0x2d0,
+       0x125, 0x2e0,
+       0x126, 0x004,
+       0x128, 0x1E0,
+       0x12A, 0x016,
+       0x12B, 0x0F2,
+       0x12C, 0x0F2,
+       0x12D, 0x00c,
+       0x12E, 0x2d0,
+       0x12F, 0x2e0,
+       0x130, 0x004,
+       0x132, 0x1E0,
+       0x140, 0x060,
+       0x153, 0x00C,
+       0x154, 0x200,
+       0x150, 0x801,
+       0x000, 0x000
+};
+
+/* PAL specific values */
+static u16 vid_regs_fp_pal[] = {
+       0x120, 0x017,
+       0x121, 0xd22,
+       0x122, 0x122,
+       0x12A, 0x017,
+       0x12B, 0x122,
+       0x12C, 0x122,
+       0x140, 0x060,
+       0x000, 0x000,
+};
+
+struct s2250 {
+       struct v4l2_subdev sd;
+       struct v4l2_ctrl_handler hdl;
+       v4l2_std_id std;
+       int input;
+       int brightness;
+       int contrast;
+       int saturation;
+       int hue;
+       int reg12b_val;
+       int audio_input;
+       struct i2c_client *audio;
+};
+
+static inline struct s2250 *to_state(struct v4l2_subdev *sd)
+{
+       return container_of(sd, struct s2250, sd);
+}
+
+/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
+static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
+       u16 value, u16 index, void *transfer_buffer, int length, int in)
+{
+       struct go7007_usb *usb = go->hpi_context;
+       int timeout = 5000;
+
+       if (in) {
+               return usb_control_msg(usb->usbdev,
+                               usb_rcvctrlpipe(usb->usbdev, 0), request,
+                               USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+                               value, index, transfer_buffer, length, timeout);
+       } else {
+               return usb_control_msg(usb->usbdev,
+                               usb_sndctrlpipe(usb->usbdev, 0), request,
+                               USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                               value, index, transfer_buffer, length, timeout);
+       }
+}
+/* end from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
+
+static int write_reg(struct i2c_client *client, u8 reg, u8 value)
+{
+       struct go7007 *go = i2c_get_adapdata(client->adapter);
+       struct go7007_usb *usb;
+       int rc;
+       int dev_addr = client->addr << 1;  /* firmware wants 8-bit address */
+       u8 *buf;
+
+       if (go == NULL)
+               return -ENODEV;
+
+       if (go->status == STATUS_SHUTDOWN)
+               return -EBUSY;
+
+       buf = kzalloc(16, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       usb = go->hpi_context;
+       if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
+               dev_info(&client->dev, "i2c lock failed\n");
+               kfree(buf);
+               return -EINTR;
+       }
+       rc = go7007_usb_vendor_request(go, 0x55, dev_addr,
+                                      (reg<<8 | value),
+                                      buf,
+                                      16, 1);
+
+       mutex_unlock(&usb->i2c_lock);
+       kfree(buf);
+       return rc;
+}
+
+static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
+{
+       struct go7007 *go = i2c_get_adapdata(client->adapter);
+       struct go7007_usb *usb;
+       int rc;
+       u8 *buf;
+       struct s2250 *dec = i2c_get_clientdata(client);
+
+       if (go == NULL)
+               return -ENODEV;
+
+       if (go->status == STATUS_SHUTDOWN)
+               return -EBUSY;
+
+       buf = kzalloc(16, GFP_KERNEL);
+
+       if (buf == NULL)
+               return -ENOMEM;
+
+
+
+       memset(buf, 0xcd, 6);
+
+       usb = go->hpi_context;
+       if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
+               dev_info(&client->dev, "i2c lock failed\n");
+               kfree(buf);
+               return -EINTR;
+       }
+       rc = go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1);
+       mutex_unlock(&usb->i2c_lock);
+       if (rc < 0) {
+               kfree(buf);
+               return rc;
+       }
+
+       if (buf[0] == 0) {
+               unsigned int subaddr, val_read;
+
+               subaddr = (buf[4] << 8) + buf[5];
+               val_read = (buf[2] << 8) + buf[3];
+               kfree(buf);
+               if (val_read != val) {
+                       dev_info(&client->dev, "invalid fp write %x %x\n",
+                                val_read, val);
+                       return -EFAULT;
+               }
+               if (subaddr != addr) {
+                       dev_info(&client->dev, "invalid fp write addr %x %x\n",
+                                subaddr, addr);
+                       return -EFAULT;
+               }
+       } else {
+               kfree(buf);
+               return -EFAULT;
+       }
+
+       /* save last 12b value */
+       if (addr == 0x12b)
+               dec->reg12b_val = val;
+
+       return 0;
+}
+
+static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
+{
+       struct go7007 *go = i2c_get_adapdata(client->adapter);
+       struct go7007_usb *usb;
+       int rc;
+       u8 *buf;
+
+       if (go == NULL)
+               return -ENODEV;
+
+       if (go->status == STATUS_SHUTDOWN)
+               return -EBUSY;
+
+       buf = kzalloc(16, GFP_KERNEL);
+
+       if (buf == NULL)
+               return -ENOMEM;
+
+
+
+       memset(buf, 0xcd, 6);
+       usb = go->hpi_context;
+       if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
+               dev_info(&client->dev, "i2c lock failed\n");
+               kfree(buf);
+               return -EINTR;
+       }
+       rc = go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1);
+       mutex_unlock(&usb->i2c_lock);
+       if (rc < 0) {
+               kfree(buf);
+               return rc;
+       }
+
+       *val = (buf[0] << 8) | buf[1];
+       kfree(buf);
+
+       return 0;
+}
+
+
+static int write_regs(struct i2c_client *client, u8 *regs)
+{
+       int i;
+
+       for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
+               if (write_reg(client, regs[i], regs[i+1]) < 0) {
+                       dev_info(&client->dev, "failed\n");
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+static int write_regs_fp(struct i2c_client *client, u16 *regs)
+{
+       int i;
+
+       for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
+               if (write_reg_fp(client, regs[i], regs[i+1]) < 0) {
+                       dev_info(&client->dev, "failed fp\n");
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+static int s2250_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
+                                u32 config)
+{
+       struct s2250 *state = to_state(sd);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       int vidsys;
+
+       vidsys = (state->std == V4L2_STD_NTSC) ? 0x01 : 0x00;
+       if (input == 0) {
+               /* composite */
+               write_reg_fp(client, 0x20, 0x020 | vidsys);
+               write_reg_fp(client, 0x21, 0x662);
+               write_reg_fp(client, 0x140, 0x060);
+       } else if (input == 1) {
+               /* S-Video */
+               write_reg_fp(client, 0x20, 0x040 | vidsys);
+               write_reg_fp(client, 0x21, 0x666);
+               write_reg_fp(client, 0x140, 0x060);
+       } else {
+               return -EINVAL;
+       }
+       state->input = input;
+       return 0;
+}
+
+static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+       struct s2250 *state = to_state(sd);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+       u16 vidsource;
+
+       vidsource = (state->input == 1) ? 0x040 : 0x020;
+       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);
+       } else {
+               write_regs_fp(client, vid_regs_fp);
+               write_reg_fp(client, 0x20, vidsource | 1);
+       }
+       state->std = norm;
+       return 0;
+}
+
+static int s2250_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+       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:
+               read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
+               write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
+                            ctrl->val | (oldvalue & ~0xff));
+               read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
+               write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
+                            ctrl->val | (oldvalue & ~0xff));
+               write_reg_fp(client, 0x140, 0x60);
+               break;
+       case V4L2_CID_CONTRAST:
+               read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
+               write_reg_fp(client, VPX322_ADDR_CONTRAST0,
+                            ctrl->val | (oldvalue & ~0x3f));
+               read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
+               write_reg_fp(client, VPX322_ADDR_CONTRAST1,
+                            ctrl->val | (oldvalue & ~0x3f));
+               write_reg_fp(client, 0x140, 0x60);
+               break;
+       case V4L2_CID_SATURATION:
+               write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
+               break;
+       case V4L2_CID_HUE:
+               write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int s2250_s_mbus_fmt(struct v4l2_subdev *sd,
+                       struct v4l2_mbus_framefmt *fmt)
+{
+       struct s2250 *state = to_state(sd);
+       struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+       if (fmt->height < 640) {
+               write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
+               write_reg_fp(client, 0x140, 0x060);
+       } else {
+               write_reg_fp(client, 0x12b, state->reg12b_val & ~0x400);
+               write_reg_fp(client, 0x140, 0x060);
+       }
+       return 0;
+}
+
+static int s2250_s_audio_routing(struct v4l2_subdev *sd, u32 input, u32 output,
+                                u32 config)
+{
+       struct s2250 *state = to_state(sd);
+
+       switch (input) {
+       case 0:
+               write_reg(state->audio, 0x08, 0x02); /* Line In */
+               break;
+       case 1:
+               write_reg(state->audio, 0x08, 0x04); /* Mic */
+               break;
+       case 2:
+               write_reg(state->audio, 0x08, 0x05); /* Mic Boost */
+               break;
+       default:
+               return -EINVAL;
+       }
+       state->audio_input = input;
+       return 0;
+}
+
+
+static int s2250_log_status(struct v4l2_subdev *sd)
+{
+       struct s2250 *state = to_state(sd);
+
+       v4l2_info(sd, "Standard: %s\n", state->std == V4L2_STD_NTSC ? "NTSC" :
+                                       state->std == V4L2_STD_PAL ? "PAL" :
+                                       state->std == V4L2_STD_SECAM ? "SECAM" :
+                                       "unknown");
+       v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
+                                       state->input == 1 ? "S-video" :
+                                       "error");
+       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 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,
+};
+
+static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
+       .s_routing = s2250_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops s2250_video_ops = {
+       .s_std = s2250_s_std,
+       .s_routing = s2250_s_video_routing,
+       .s_mbus_fmt = s2250_s_mbus_fmt,
+};
+
+static const struct v4l2_subdev_ops s2250_ops = {
+       .core = &s2250_core_ops,
+       .audio = &s2250_audio_ops,
+       .video = &s2250_video_ops,
+};
+
+/* --------------------------------------------------------------------------*/
+
+static int s2250_probe(struct i2c_client *client,
+                      const struct i2c_device_id *id)
+{
+       struct i2c_client *audio;
+       struct i2c_adapter *adapter = client->adapter;
+       struct s2250 *state;
+       struct v4l2_subdev *sd;
+       u8 *data;
+       struct go7007 *go = i2c_get_adapdata(adapter);
+       struct go7007_usb *usb = go->hpi_context;
+
+       audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
+       if (audio == NULL)
+               return -ENOMEM;
+
+       state = kzalloc(sizeof(struct s2250), GFP_KERNEL);
+       if (state == NULL) {
+               i2c_unregister_device(audio);
+               return -ENOMEM;
+       }
+
+       sd = &state->sd;
+       v4l2_i2c_subdev_init(sd, client, &s2250_ops);
+
+       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;
+       state->saturation = 50;
+       state->hue = 0;
+       state->audio = audio;
+
+       /* initialize the audio */
+       if (write_regs(audio, aud_regs) < 0) {
+               dev_err(&client->dev, "error initializing audio\n");
+               goto fail;
+       }
+
+       if (write_regs(client, vid_regs) < 0) {
+               dev_err(&client->dev, "error initializing decoder\n");
+               goto fail;
+       }
+       if (write_regs_fp(client, vid_regs_fp) < 0) {
+               dev_err(&client->dev, "error initializing decoder\n");
+               goto fail;
+       }
+       /* set default channel */
+       /* composite */
+       write_reg_fp(client, 0x20, 0x020 | 1);
+       write_reg_fp(client, 0x21, 0x662);
+       write_reg_fp(client, 0x140, 0x060);
+
+       /* set default audio input */
+       state->audio_input = 0;
+       write_reg(client, 0x08, 0x02); /* Line In */
+
+       if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
+               data = kzalloc(16, GFP_KERNEL);
+               if (data != NULL) {
+                       int rc = go7007_usb_vendor_request(go, 0x41, 0, 0,
+                                                      data, 16, 1);
+
+                       if (rc > 0) {
+                               u8 mask;
+
+                               data[0] = 0;
+                               mask = 1<<5;
+                               data[0] &= ~mask;
+                               data[1] |= mask;
+                               go7007_usb_vendor_request(go, 0x40, 0,
+                                                         (data[1]<<8)
+                                                         + data[1],
+                                                         data, 16, 0);
+                       }
+                       kfree(data);
+               }
+               mutex_unlock(&usb->i2c_lock);
+       }
+
+       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 s2250 *state = to_state(i2c_get_clientdata(client));
+
+       v4l2_device_unregister_subdev(&state->sd);
+       v4l2_ctrl_handler_free(&state->hdl);
+       kfree(state);
+       return 0;
+}
+
+static const struct i2c_device_id s2250_id[] = {
+       { "s2250", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, s2250_id);
+
+static struct i2c_driver s2250_driver = {
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = "s2250",
+       },
+       .probe          = s2250_probe,
+       .remove         = s2250_remove,
+       .id_table       = s2250_id,
+};
+
+module_i2c_driver(s2250_driver);
diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c
new file mode 100644 (file)
index 0000000..d22d7d5
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+
+#include "go7007-priv.h"
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+module_param_array(index, int, NULL, 0444);
+module_param_array(id, charp, NULL, 0444);
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for the go7007 audio driver");
+MODULE_PARM_DESC(id, "ID string for the go7007 audio driver");
+MODULE_PARM_DESC(enable, "Enable for the go7007 audio driver");
+
+struct go7007_snd {
+       struct snd_card *card;
+       struct snd_pcm *pcm;
+       struct snd_pcm_substream *substream;
+       spinlock_t lock;
+       int w_idx;
+       int hw_ptr;
+       int avail;
+       int capturing;
+};
+
+static struct snd_pcm_hardware go7007_snd_capture_hw = {
+       .info                   = (SNDRV_PCM_INFO_MMAP |
+                                       SNDRV_PCM_INFO_INTERLEAVED |
+                                       SNDRV_PCM_INFO_BLOCK_TRANSFER |
+                                       SNDRV_PCM_INFO_MMAP_VALID),
+       .formats                = SNDRV_PCM_FMTBIT_S16_LE,
+       .rates                  = SNDRV_PCM_RATE_48000,
+       .rate_min               = 48000,
+       .rate_max               = 48000,
+       .channels_min           = 2,
+       .channels_max           = 2,
+       .buffer_bytes_max       = (128*1024),
+       .period_bytes_min       = 4096,
+       .period_bytes_max       = (128*1024),
+       .periods_min            = 1,
+       .periods_max            = 32,
+};
+
+static void parse_audio_stream_data(struct go7007 *go, u8 *buf, int length)
+{
+       struct go7007_snd *gosnd = go->snd_context;
+       struct snd_pcm_runtime *runtime = gosnd->substream->runtime;
+       int frames = bytes_to_frames(runtime, length);
+
+       spin_lock(&gosnd->lock);
+       gosnd->hw_ptr += frames;
+       if (gosnd->hw_ptr >= runtime->buffer_size)
+               gosnd->hw_ptr -= runtime->buffer_size;
+       gosnd->avail += frames;
+       spin_unlock(&gosnd->lock);
+       if (gosnd->w_idx + length > runtime->dma_bytes) {
+               int cpy = runtime->dma_bytes - gosnd->w_idx;
+
+               memcpy(runtime->dma_area + gosnd->w_idx, buf, cpy);
+               length -= cpy;
+               buf += cpy;
+               gosnd->w_idx = 0;
+       }
+       memcpy(runtime->dma_area + gosnd->w_idx, buf, length);
+       gosnd->w_idx += length;
+       spin_lock(&gosnd->lock);
+       if (gosnd->avail < runtime->period_size) {
+               spin_unlock(&gosnd->lock);
+               return;
+       }
+       gosnd->avail -= runtime->period_size;
+       spin_unlock(&gosnd->lock);
+       if (gosnd->capturing)
+               snd_pcm_period_elapsed(gosnd->substream);
+}
+
+static int go7007_snd_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *hw_params)
+{
+       struct go7007 *go = snd_pcm_substream_chip(substream);
+       unsigned int bytes;
+
+       bytes = params_buffer_bytes(hw_params);
+       if (substream->runtime->dma_bytes > 0)
+               vfree(substream->runtime->dma_area);
+       substream->runtime->dma_bytes = 0;
+       substream->runtime->dma_area = vmalloc(bytes);
+       if (substream->runtime->dma_area == NULL)
+               return -ENOMEM;
+       substream->runtime->dma_bytes = bytes;
+       go->audio_deliver = parse_audio_stream_data;
+       return 0;
+}
+
+static int go7007_snd_hw_free(struct snd_pcm_substream *substream)
+{
+       struct go7007 *go = snd_pcm_substream_chip(substream);
+
+       go->audio_deliver = NULL;
+       if (substream->runtime->dma_bytes > 0)
+               vfree(substream->runtime->dma_area);
+       substream->runtime->dma_bytes = 0;
+       return 0;
+}
+
+static int go7007_snd_capture_open(struct snd_pcm_substream *substream)
+{
+       struct go7007 *go = snd_pcm_substream_chip(substream);
+       struct go7007_snd *gosnd = go->snd_context;
+       unsigned long flags;
+       int r;
+
+       spin_lock_irqsave(&gosnd->lock, flags);
+       if (gosnd->substream == NULL) {
+               gosnd->substream = substream;
+               substream->runtime->hw = go7007_snd_capture_hw;
+               r = 0;
+       } else
+               r = -EBUSY;
+       spin_unlock_irqrestore(&gosnd->lock, flags);
+       return r;
+}
+
+static int go7007_snd_capture_close(struct snd_pcm_substream *substream)
+{
+       struct go7007 *go = snd_pcm_substream_chip(substream);
+       struct go7007_snd *gosnd = go->snd_context;
+
+       gosnd->substream = NULL;
+       return 0;
+}
+
+static int go7007_snd_pcm_prepare(struct snd_pcm_substream *substream)
+{
+       return 0;
+}
+
+static int go7007_snd_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct go7007 *go = snd_pcm_substream_chip(substream);
+       struct go7007_snd *gosnd = go->snd_context;
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               /* Just set a flag to indicate we should signal ALSA when
+                * sound comes in */
+               gosnd->capturing = 1;
+               return 0;
+       case SNDRV_PCM_TRIGGER_STOP:
+               gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
+               gosnd->capturing = 0;
+               return 0;
+       default:
+               return -EINVAL;
+       }
+}
+
+static snd_pcm_uframes_t go7007_snd_pcm_pointer(struct snd_pcm_substream *substream)
+{
+       struct go7007 *go = snd_pcm_substream_chip(substream);
+       struct go7007_snd *gosnd = go->snd_context;
+
+       return gosnd->hw_ptr;
+}
+
+static struct page *go7007_snd_pcm_page(struct snd_pcm_substream *substream,
+                                       unsigned long offset)
+{
+       return vmalloc_to_page(substream->runtime->dma_area + offset);
+}
+
+static struct snd_pcm_ops go7007_snd_capture_ops = {
+       .open           = go7007_snd_capture_open,
+       .close          = go7007_snd_capture_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = go7007_snd_hw_params,
+       .hw_free        = go7007_snd_hw_free,
+       .prepare        = go7007_snd_pcm_prepare,
+       .trigger        = go7007_snd_pcm_trigger,
+       .pointer        = go7007_snd_pcm_pointer,
+       .page           = go7007_snd_pcm_page,
+};
+
+static int go7007_snd_free(struct snd_device *device)
+{
+       struct go7007 *go = device->device_data;
+
+       kfree(go->snd_context);
+       go->snd_context = NULL;
+       return 0;
+}
+
+static struct snd_device_ops go7007_snd_device_ops = {
+       .dev_free       = go7007_snd_free,
+};
+
+int go7007_snd_init(struct go7007 *go)
+{
+       static int dev;
+       struct go7007_snd *gosnd;
+       int ret = 0;
+
+       if (dev >= SNDRV_CARDS)
+               return -ENODEV;
+       if (!enable[dev]) {
+               dev++;
+               return -ENOENT;
+       }
+       gosnd = kmalloc(sizeof(struct go7007_snd), GFP_KERNEL);
+       if (gosnd == NULL)
+               return -ENOMEM;
+       spin_lock_init(&gosnd->lock);
+       gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
+       gosnd->capturing = 0;
+       ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0,
+                          &gosnd->card);
+       if (ret < 0) {
+               kfree(gosnd);
+               return ret;
+       }
+       ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
+                       &go7007_snd_device_ops);
+       if (ret < 0) {
+               kfree(gosnd);
+               return ret;
+       }
+       ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
+       if (ret < 0) {
+               snd_card_free(gosnd->card);
+               kfree(gosnd);
+               return ret;
+       }
+       strlcpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
+       strlcpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
+       strlcpy(gosnd->card->longname, gosnd->card->shortname,
+                       sizeof(gosnd->card->longname));
+
+       gosnd->pcm->private_data = go;
+       snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE,
+                       &go7007_snd_capture_ops);
+
+       ret = snd_card_register(gosnd->card);
+       if (ret < 0) {
+               snd_card_free(gosnd->card);
+               kfree(gosnd);
+               return ret;
+       }
+
+       gosnd->substream = NULL;
+       go->snd_context = gosnd;
+       v4l2_device_get(&go->v4l2_dev);
+       ++dev;
+
+       return 0;
+}
+EXPORT_SYMBOL(go7007_snd_init);
+
+int go7007_snd_remove(struct go7007 *go)
+{
+       struct go7007_snd *gosnd = go->snd_context;
+
+       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);
+
+MODULE_LICENSE("GPL v2");
index 3312a3bd256d5c3124e92d7d4af429980bccf272..3323eb5e77b07ea1e56367c21ff9497e2143f661 100644 (file)
@@ -29,8 +29,6 @@ source "drivers/staging/media/davinci_vpfe/Kconfig"
 
 source "drivers/staging/media/dt3155v4l/Kconfig"
 
-source "drivers/staging/media/go7007/Kconfig"
-
 source "drivers/staging/media/omap24xx/Kconfig"
 
 source "drivers/staging/media/omap4iss/Kconfig"
index 205eba283326045aab6e113e701f6d31760f5b10..7db83f373f63010c8618255415146c9a1d9dd03e 100644 (file)
@@ -3,7 +3,6 @@ obj-$(CONFIG_I2C_BCM2048)       += bcm2048/
 obj-$(CONFIG_DVB_CXD2099)      += cxd2099/
 obj-$(CONFIG_LIRC_STAGING)     += lirc/
 obj-$(CONFIG_VIDEO_DT3155)     += dt3155v4l/
-obj-$(CONFIG_VIDEO_GO7007)     += go7007/
 obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
 obj-$(CONFIG_VIDEO_OMAP4)      += omap4iss/
 obj-$(CONFIG_VIDEO_OMAP2)       += omap24xx/
diff --git a/drivers/staging/media/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig
deleted file mode 100644 (file)
index 95a3af6..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-config VIDEO_GO7007
-       tristate "WIS GO7007 MPEG encoder support"
-       depends on VIDEO_DEV && I2C
-       depends on SND && USB
-       select VIDEOBUF2_VMALLOC
-       select VIDEO_TUNER
-       select CYPRESS_FIRMWARE
-       select SND_PCM
-       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_TW9906 if MEDIA_SUBDRV_AUTOSELECT
-       select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT
-       select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT
-       ---help---
-         This is a video4linux driver for the WIS GO7007 MPEG
-         encoder chip.
-
-         To compile this driver as a module, choose M here: the
-         module will be called go7007.
-
-config VIDEO_GO7007_USB
-       tristate "WIS GO7007 USB support"
-       depends on VIDEO_GO7007 && USB
-       ---help---
-         This is a video4linux 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-usb.
-
-config VIDEO_GO7007_LOADER
-       tristate "WIS GO7007 Loader support"
-       depends on VIDEO_GO7007
-       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 && USB
-       ---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.
diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
deleted file mode 100644 (file)
index 9c6ad4a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-obj-$(CONFIG_VIDEO_GO7007) += go7007.o
-obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.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
-
-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/pci/saa7134
-
-ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/common
diff --git a/drivers/staging/media/go7007/README b/drivers/staging/media/go7007/README
deleted file mode 100644 (file)
index 34516ea..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-Todo:
-       - let s2250-board use i2c subdevs as well instead of hardcoding
-         support for the i2c devices.
-       - when the driver is moved out of staging, support for saa7134-go7007
-         should be added to the saa7134 driver. The patch for that is
-         included below.
-
-Patch for saa7134:
-
-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 62169dd..5fad39a 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 9c6ad4a..1b23689 100644
---- a/drivers/staging/media/go7007/Makefile
-+++ b/drivers/staging/media/go7007/Makefile
-@@ -8,8 +8,7 @@ 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/pci/saa7134
-+obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
-+ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/pci/saa7134
- ccflags-$(CONFIG_VIDEO_GO7007_LOADER:m=y) += -Idrivers/media/common
diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
deleted file mode 100644 (file)
index 95cffb7..0000000
+++ /dev/null
@@ -1,766 +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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/unistd.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/firmware.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-#include <media/tuner.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-event.h>
-
-#include "go7007-priv.h"
-
-/*
- * Wait for an interrupt to be delivered from the GO7007SB and return
- * the associated value and data.
- *
- * Must be called with the hw_lock held.
- */
-int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
-{
-       go->interrupt_available = 0;
-       go->hpi_ops->read_interrupt(go);
-       if (wait_event_timeout(go->interrupt_waitq,
-                               go->interrupt_available, 5*HZ) < 0) {
-               v4l2_err(&go->v4l2_dev, "timeout waiting for read interrupt\n");
-               return -1;
-       }
-       if (!go->interrupt_available)
-               return -1;
-       go->interrupt_available = 0;
-       *value = go->interrupt_value & 0xfffe;
-       *data = go->interrupt_data;
-       return 0;
-}
-EXPORT_SYMBOL(go7007_read_interrupt);
-
-/*
- * Read a register/address on the GO7007SB.
- *
- * Must be called with the hw_lock held.
- */
-int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data)
-{
-       int count = 100;
-       u16 value;
-
-       if (go7007_write_interrupt(go, 0x0010, addr) < 0)
-               return -EIO;
-       while (count-- > 0) {
-               if (go7007_read_interrupt(go, &value, data) == 0 &&
-                               value == 0xa000)
-                       return 0;
-       }
-       return -EIO;
-}
-EXPORT_SYMBOL(go7007_read_addr);
-
-/*
- * Send the boot firmware to the encoder, which just wakes it up and lets
- * us talk to the GPIO pins and on-board I2C adapter.
- *
- * Must be called with the hw_lock held.
- */
-static int go7007_load_encoder(struct go7007 *go)
-{
-       const struct firmware *fw_entry;
-       char fw_name[] = "go7007/go7007fw.bin";
-       void *bounce;
-       int fw_len, rv = 0;
-       u16 intr_val, intr_data;
-
-       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);
-               go->boot_fw_len = fw_len;
-               go->boot_fw = bounce;
-       }
-       if (go7007_interface_reset(go) < 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;
-       }
-       return rv;
-}
-
-MODULE_FIRMWARE("go7007/go7007fw.bin");
-
-/*
- * Boot the encoder and register the I2C adapter if requested.  Do the
- * minimum initialization necessary, since the board-specific code may
- * still need to probe the board ID.
- *
- * Must NOT be called with the hw_lock held.
- */
-int go7007_boot_encoder(struct go7007 *go, int init_i2c)
-{
-       int ret;
-
-       mutex_lock(&go->hw_lock);
-       ret = go7007_load_encoder(go);
-       mutex_unlock(&go->hw_lock);
-       if (ret < 0)
-               return -1;
-       if (!init_i2c)
-               return 0;
-       if (go7007_i2c_init(go) < 0)
-               return -1;
-       go->i2c_adapter_online = 1;
-       return 0;
-}
-EXPORT_SYMBOL(go7007_boot_encoder);
-
-/*
- * Configure any hardware-related registers in the GO7007, such as GPIO
- * pins and bus parameters, which are board-specific.  This assumes
- * the boot firmware has already been downloaded.
- *
- * Must be called with the hw_lock held.
- */
-static int go7007_init_encoder(struct go7007 *go)
-{
-       if (go->board_info->audio_flags & GO7007_AUDIO_I2S_MASTER) {
-               go7007_write_addr(go, 0x1000, 0x0811);
-               go7007_write_addr(go, 0x1000, 0x0c11);
-       }
-       switch (go->board_id) {
-       case GO7007_BOARDID_MATRIX_REV:
-               /* Set GPIO pin 0 to be an output (audio clock control) */
-               go7007_write_addr(go, 0x3c82, 0x0001);
-               go7007_write_addr(go, 0x3c80, 0x00fe);
-               break;
-       case GO7007_BOARDID_ADLINK_MPG24:
-               /* set GPIO5 to be an output, currently low */
-               go7007_write_addr(go, 0x3c82, 0x0000);
-               go7007_write_addr(go, 0x3c80, 0x00df);
-               break;
-       case GO7007_BOARDID_ADS_USBAV_709:
-               /* GPIO pin 0: audio clock control */
-               /*      pin 2: TW9906 reset */
-               /*      pin 3: capture LED */
-               go7007_write_addr(go, 0x3c82, 0x000d);
-               go7007_write_addr(go, 0x3c80, 0x00f2);
-               break;
-       }
-       return 0;
-}
-
-/*
- * Send the boot firmware to the GO7007 and configure the registers.  This
- * is the only way to stop the encoder once it has started streaming video.
- *
- * Must be called with the hw_lock held.
- */
-int go7007_reset_encoder(struct go7007 *go)
-{
-       if (go7007_load_encoder(go) < 0)
-               return -1;
-       return go7007_init_encoder(go);
-}
-
-/*
- * Attempt to instantiate an I2C client by ID, probably loading a module.
- */
-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 v4l2_subdev *sd;
-       struct i2c_board_info info;
-
-       memset(&info, 0, sizeof(info));
-       strlcpy(info.type, i2c->type, sizeof(info.type));
-       info.addr = i2c->addr;
-       info.flags = i2c->flags;
-
-       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;
-       }
-
-       pr_info("go7007: probing for module i2c:%s failed\n", i2c->type);
-       return -EINVAL;
-}
-
-/*
- * 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) {
-               i2c_del_adapter(&go->i2c_adapter);
-               go->i2c_adapter_online = 0;
-       }
-
-       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
- * interfaces.
- *
- * Must NOT be called with the hw_lock held.
- */
-int go7007_register_encoder(struct go7007 *go, unsigned num_i2c_devs)
-{
-       int i, ret;
-
-       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 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) {
-               ret = go7007_i2c_init(go);
-               if (ret < 0)
-                       return ret;
-               go->i2c_adapter_online = 1;
-       }
-       if (go->i2c_adapter_online) {
-               if (go->board_id == GO7007_BOARDID_ADS_USBAV_709) {
-                       /* Reset the TW9906 */
-                       go7007_write_addr(go, 0x3c82, 0x0009);
-                       msleep(50);
-                       go7007_write_addr(go, 0x3c82, 0x000d);
-               }
-               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)
-                       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);
-       }
-       return 0;
-}
-EXPORT_SYMBOL(go7007_register_encoder);
-
-/*
- * Send the encode firmware to the encoder, which will cause it
- * to immediately start delivering the video and audio streams.
- *
- * Must be called with the hw_lock held.
- */
-int go7007_start_encoder(struct go7007 *go)
-{
-       u8 *fw;
-       int fw_len, rv = 0, i, x, y;
-       u16 intr_val, intr_data;
-
-       go->modet_enable = 0;
-       for (i = 0; i < 4; i++)
-               go->modet[i].enable = 0;
-
-       switch (v4l2_ctrl_g_ctrl(go->modet_mode)) {
-       case V4L2_DETECT_MD_MODE_GLOBAL:
-               memset(go->modet_map, 0, sizeof(go->modet_map));
-               go->modet[0].enable = 1;
-               go->modet_enable = 1;
-               break;
-       case V4L2_DETECT_MD_MODE_REGION_GRID:
-               for (y = 0; y < go->height / 16; y++) {
-                       for (x = 0; x < go->width / 16; x++) {
-                               int idx = y * go->width / 16 + x;
-
-                               go->modet[go->modet_map[idx]].enable = 1;
-                       }
-               }
-               go->modet_enable = 1;
-               break;
-       }
-
-       if (go->dvd_mode)
-               go->modet_enable = 0;
-
-       if (go7007_construct_fw_image(go, &fw, &fw_len) < 0)
-               return -1;
-
-       if (go7007_send_firmware(go, fw, fw_len) < 0 ||
-                       go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
-               v4l2_err(&go->v4l2_dev, "error transferring firmware\n");
-               rv = -1;
-               goto start_error;
-       }
-
-       go->state = STATE_DATA;
-       go->parse_length = 0;
-       go->seen_frame = 0;
-       if (go7007_stream_start(go) < 0) {
-               v4l2_err(&go->v4l2_dev, "error starting stream transfer\n");
-               rv = -1;
-               goto start_error;
-       }
-
-start_error:
-       kfree(fw);
-       return rv;
-}
-
-/*
- * Store a byte in the current video buffer, if there is one.
- */
-static inline void store_byte(struct go7007_buffer *vb, u8 byte)
-{
-       if (vb && vb->vb.v4l2_planes[0].bytesused < GO7007_BUF_SIZE) {
-               u8 *ptr = vb2_plane_vaddr(&vb->vb, 0);
-
-               ptr[vb->vb.v4l2_planes[0].bytesused++] = byte;
-       }
-}
-
-static void go7007_set_motion_regions(struct go7007 *go, struct go7007_buffer *vb,
-               u32 motion_regions)
-{
-       if (motion_regions != go->modet_event_status) {
-               struct v4l2_event ev = {
-                       .type = V4L2_EVENT_MOTION_DET,
-                       .u.motion_det = {
-                               .flags = V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ,
-                               .frame_sequence = vb->vb.v4l2_buf.sequence,
-                               .region_mask = motion_regions,
-                       },
-               };
-
-               v4l2_event_queue(&go->vdev, &ev);
-               go->modet_event_status = motion_regions;
-       }
-}
-
-/*
- * Determine regions with motion and send a motion detection event
- * in case of changes.
- */
-static void go7007_motion_regions(struct go7007 *go, struct go7007_buffer *vb)
-{
-       u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused;
-       unsigned motion[4] = { 0, 0, 0, 0 };
-       u32 motion_regions = 0;
-       unsigned stride = (go->width + 7) >> 3;
-       unsigned x, y;
-       int i;
-
-       for (i = 0; i < 216; ++i)
-               store_byte(vb, go->active_map[i]);
-       for (y = 0; y < go->height / 16; y++) {
-               for (x = 0; x < go->width / 16; x++) {
-                       if (!(go->active_map[y * stride + (x >> 3)] & (1 << (x & 7))))
-                               continue;
-                       motion[go->modet_map[y * (go->width / 16) + x]]++;
-               }
-       }
-       motion_regions = ((motion[0] > 0) << 0) |
-                        ((motion[1] > 0) << 1) |
-                        ((motion[2] > 0) << 2) |
-                        ((motion[3] > 0) << 3);
-       *bytesused -= 216;
-       go7007_set_motion_regions(go, vb, motion_regions);
-}
-
-/*
- * Deliver the last video buffer and get a new one to start writing to.
- */
-static struct go7007_buffer *frame_boundary(struct go7007 *go, struct go7007_buffer *vb)
-{
-       u32 *bytesused = &vb->vb.v4l2_planes[0].bytesused;
-       struct go7007_buffer *vb_tmp = NULL;
-
-       if (vb == NULL) {
-               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;
-       }
-
-       vb->vb.v4l2_buf.sequence = go->next_seq++;
-       if (vb->modet_active && *bytesused + 216 < GO7007_BUF_SIZE)
-               go7007_motion_regions(go, vb);
-       else
-               go7007_set_motion_regions(go, vb, 0);
-
-       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;
-}
-
-static void write_bitmap_word(struct go7007 *go)
-{
-       int x, y, i, stride = ((go->width >> 4) + 7) >> 3;
-
-       for (i = 0; i < 16; ++i) {
-               y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4);
-               x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4);
-               if (stride * y + (x >> 3) < sizeof(go->active_map))
-                       go->active_map[stride * y + (x >> 3)] |=
-                                       (go->modet_word & 1) << (x & 0x7);
-               go->modet_word >>= 1;
-       }
-}
-
-/*
- * Parse a chunk of the video stream into frames.  The frames are not
- * delimited by the hardware, so we have to parse the frame boundaries
- * based on the type of video stream we're receiving.
- */
-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, gop_start_code = -1, frame_start_code = -1;
-
-       switch (go->format) {
-       case V4L2_PIX_FMT_MPEG4:
-               seq_start_code = 0xB0;
-               gop_start_code = 0xB3;
-               frame_start_code = 0xB6;
-               break;
-       case V4L2_PIX_FMT_MPEG1:
-       case V4L2_PIX_FMT_MPEG2:
-               seq_start_code = 0xB3;
-               gop_start_code = 0xB8;
-               frame_start_code = 0x00;
-               break;
-       }
-
-       for (i = 0; i < length; ++i) {
-               if (vb && vb->vb.v4l2_planes[0].bytesused >= GO7007_BUF_SIZE - 3) {
-                       v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
-                       vb->vb.v4l2_planes[0].bytesused = 0;
-                       vb->frame_offset = 0;
-                       vb->modet_active = 0;
-                       vb = go->active_buf = NULL;
-               }
-
-               switch (go->state) {
-               case STATE_DATA:
-                       switch (buf[i]) {
-                       case 0x00:
-                               go->state = STATE_00;
-                               break;
-                       case 0xFF:
-                               go->state = STATE_FF;
-                               break;
-                       default:
-                               store_byte(vb, buf[i]);
-                               break;
-                       }
-                       break;
-               case STATE_00:
-                       switch (buf[i]) {
-                       case 0x00:
-                               go->state = STATE_00_00;
-                               break;
-                       case 0xFF:
-                               store_byte(vb, 0x00);
-                               go->state = STATE_FF;
-                               break;
-                       default:
-                               store_byte(vb, 0x00);
-                               store_byte(vb, buf[i]);
-                               go->state = STATE_DATA;
-                               break;
-                       }
-                       break;
-               case STATE_00_00:
-                       switch (buf[i]) {
-                       case 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(vb, 0x00);
-                               store_byte(vb, 0x00);
-                               go->state = STATE_FF;
-                               break;
-                       default:
-                               store_byte(vb, 0x00);
-                               store_byte(vb, 0x00);
-                               store_byte(vb, buf[i]);
-                               go->state = STATE_DATA;
-                               break;
-                       }
-                       break;
-               case STATE_00_00_01:
-                       if (buf[i] == 0xF8 && go->modet_enable == 0) {
-                               /* MODET start code, but MODET not enabled */
-                               store_byte(vb, 0x00);
-                               store_byte(vb, 0x00);
-                               store_byte(vb, 0x01);
-                               store_byte(vb, 0xF8);
-                               go->state = STATE_DATA;
-                               break;
-                       }
-                       /* If this is the start of a new MPEG frame,
-                        * get a new buffer */
-                       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] == gop_start_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 */
-                       switch (buf[i]) {
-                       case 0xF5: /* timestamp */
-                               go->parse_length = 12;
-                               go->state = STATE_UNPARSED;
-                               break;
-                       case 0xF6: /* vbi */
-                               go->state = STATE_VBI_LEN_A;
-                               break;
-                       case 0xF8: /* MD map */
-                               go->parse_length = 0;
-                               memset(go->active_map, 0,
-                                               sizeof(go->active_map));
-                               go->state = STATE_MODET_MAP;
-                               break;
-                       case 0xFF: /* Potential JPEG start code */
-                               store_byte(vb, 0x00);
-                               store_byte(vb, 0x00);
-                               store_byte(vb, 0x01);
-                               go->state = STATE_FF;
-                               break;
-                       default:
-                               store_byte(vb, 0x00);
-                               store_byte(vb, 0x00);
-                               store_byte(vb, 0x01);
-                               store_byte(vb, buf[i]);
-                               go->state = STATE_DATA;
-                               break;
-                       }
-                       break;
-               case STATE_FF:
-                       switch (buf[i]) {
-                       case 0x00:
-                               store_byte(vb, 0xFF);
-                               go->state = STATE_00;
-                               break;
-                       case 0xFF:
-                               store_byte(vb, 0xFF);
-                               /* go->state remains STATE_FF */
-                               break;
-                       case 0xD8:
-                               if (go->format == V4L2_PIX_FMT_MJPEG)
-                                       vb = frame_boundary(go, vb);
-                               /* fall through */
-                       default:
-                               store_byte(vb, 0xFF);
-                               store_byte(vb, buf[i]);
-                               go->state = STATE_DATA;
-                               break;
-                       }
-                       break;
-               case STATE_VBI_LEN_A:
-                       go->parse_length = buf[i] << 8;
-                       go->state = STATE_VBI_LEN_B;
-                       break;
-               case STATE_VBI_LEN_B:
-                       go->parse_length |= buf[i];
-                       if (go->parse_length > 0)
-                               go->state = STATE_UNPARSED;
-                       else
-                               go->state = STATE_DATA;
-                       break;
-               case STATE_MODET_MAP:
-                       if (go->parse_length < 204) {
-                               if (go->parse_length & 1) {
-                                       go->modet_word |= buf[i];
-                                       write_bitmap_word(go);
-                               } else
-                                       go->modet_word = buf[i] << 8;
-                       } else if (go->parse_length == 207 && vb) {
-                               vb->modet_active = buf[i];
-                       }
-                       if (++go->parse_length == 208)
-                               go->state = STATE_DATA;
-                       break;
-               case STATE_UNPARSED:
-                       if (--go->parse_length == 0)
-                               go->state = STATE_DATA;
-                       break;
-               }
-       }
-}
-EXPORT_SYMBOL(go7007_parse_video_stream);
-
-/*
- * Allocate a new go7007 struct.  Used by the hardware-specific probe.
- */
-struct go7007 *go7007_alloc(const struct go7007_board_info *board,
-                                               struct device *dev)
-{
-       struct go7007 *go;
-       int i;
-
-       go = kzalloc(sizeof(struct go7007), GFP_KERNEL);
-       if (go == NULL)
-               return NULL;
-       go->dev = dev;
-       go->board_info = board;
-       go->board_id = 0;
-       go->tuner_type = -1;
-       go->channel_number = 0;
-       go->name[0] = 0;
-       mutex_init(&go->hw_lock);
-       init_waitqueue_head(&go->frame_waitq);
-       spin_lock_init(&go->spinlock);
-       go->status = STATUS_INIT;
-       memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
-       go->i2c_adapter_online = 0;
-       go->interrupt_available = 0;
-       init_waitqueue_head(&go->interrupt_waitq);
-       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->bitrate = 1500000;
-       go->fps_scale = 1;
-       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;
-       go->interlace_coding = 0;
-       for (i = 0; i < 4; ++i)
-               go->modet[i].enable = 0;
-       for (i = 0; i < 1624; ++i)
-               go->modet_map[i] = 0;
-       go->audio_deliver = NULL;
-       go->audio_enabled = 0;
-
-       return go;
-}
-EXPORT_SYMBOL(go7007_alloc);
-
-void go7007_update_board(struct go7007 *go)
-{
-       const 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-fw.c b/drivers/staging/media/go7007/go7007-fw.c
deleted file mode 100644 (file)
index 5f4c9b9..0000000
+++ /dev/null
@@ -1,1628 +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.
- */
-
-/*
- * This file contains code to generate a firmware image for the GO7007SB
- * encoder.  Much of the firmware is read verbatim from a file, but some of
- * it concerning bitrate control and other things that can be configured at
- * run-time are generated dynamically.  Note that the format headers
- * generated here do not affect the functioning of the encoder; they are
- * merely parroted back to the host at the start of each frame.
- */
-
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-
-#include "go7007-priv.h"
-
-#define GO7007_FW_NAME "go7007/go7007tv.bin"
-
-/* Constants used in the source firmware image to describe code segments */
-
-#define        FLAG_MODE_MJPEG         (1)
-#define        FLAG_MODE_MPEG1         (1<<1)
-#define        FLAG_MODE_MPEG2         (1<<2)
-#define        FLAG_MODE_MPEG4         (1<<3)
-#define        FLAG_MODE_H263          (1<<4)
-#define FLAG_MODE_ALL          (FLAG_MODE_MJPEG | FLAG_MODE_MPEG1 | \
-                                       FLAG_MODE_MPEG2 | FLAG_MODE_MPEG4 | \
-                                       FLAG_MODE_H263)
-#define FLAG_SPECIAL           (1<<8)
-
-#define SPECIAL_FRM_HEAD       0
-#define SPECIAL_BRC_CTRL       1
-#define SPECIAL_CONFIG         2
-#define SPECIAL_SEQHEAD                3
-#define SPECIAL_AV_SYNC                4
-#define SPECIAL_FINAL          5
-#define SPECIAL_AUDIO          6
-#define SPECIAL_MODET          7
-
-/* Little data class for creating MPEG headers bit-by-bit */
-
-struct code_gen {
-       unsigned char *p; /* destination */
-       u32 a; /* collects bits at the top of the variable */
-       int b; /* bit position of most recently-written bit */
-       int len; /* written out so far */
-};
-
-#define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 }
-
-#define CODE_ADD(name, val, length) do { \
-       name.b -= (length); \
-       name.a |= (val) << name.b; \
-       while (name.b <= 24) { \
-               *name.p = name.a >> 24; \
-               ++name.p; \
-               name.a <<= 8; \
-               name.b += 8; \
-               name.len += 8; \
-       } \
-} while (0)
-
-#define CODE_LENGTH(name) (name.len + (32 - name.b))
-
-/* Tables for creating the bitrate control data */
-
-static const s16 converge_speed_ip[101] = {
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-       1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
-       2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
-       3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
-       5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
-       9, 10, 10, 11, 12, 13, 14, 15, 16, 17,
-       19, 20, 22, 23, 25, 27, 30, 32, 35, 38,
-       41, 45, 49, 53, 58, 63, 69, 76, 83, 91,
-       100
-};
-
-static const s16 converge_speed_ipb[101] = {
-       3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-       3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-       3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
-       4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
-       6, 6, 6, 7, 7, 7, 7, 8, 8, 9,
-       9, 9, 10, 10, 11, 12, 12, 13, 14, 14,
-       15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
-       28, 30, 32, 34, 37, 40, 42, 46, 49, 53,
-       57, 61, 66, 71, 77, 83, 90, 97, 106, 115,
-       125, 135, 147, 161, 175, 191, 209, 228, 249, 273,
-       300
-};
-
-static const s16 LAMBDA_table[4][101] = {
-       {       16, 16, 16, 16, 17, 17, 17, 18, 18, 18,
-               19, 19, 19, 20, 20, 20, 21, 21, 22, 22,
-               22, 23, 23, 24, 24, 25, 25, 25, 26, 26,
-               27, 27, 28, 28, 29, 29, 30, 31, 31, 32,
-               32, 33, 33, 34, 35, 35, 36, 37, 37, 38,
-               39, 39, 40, 41, 42, 42, 43, 44, 45, 46,
-               46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
-               56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
-               67, 68, 69, 70, 72, 73, 74, 76, 77, 78,
-               80, 81, 83, 84, 86, 87, 89, 90, 92, 94,
-               96
-       },
-       {
-               20, 20, 20, 21, 21, 21, 22, 22, 23, 23,
-               23, 24, 24, 25, 25, 26, 26, 27, 27, 28,
-               28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
-               34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
-               40, 41, 42, 43, 43, 44, 45, 46, 47, 48,
-               48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
-               58, 59, 60, 61, 62, 64, 65, 66, 67, 68,
-               70, 71, 72, 73, 75, 76, 78, 79, 80, 82,
-               83, 85, 86, 88, 90, 91, 93, 95, 96, 98,
-               100, 102, 103, 105, 107, 109, 111, 113, 115, 117,
-               120
-       },
-       {
-               24, 24, 24, 25, 25, 26, 26, 27, 27, 28,
-               28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
-               34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
-               41, 41, 42, 43, 44, 44, 45, 46, 47, 48,
-               49, 50, 50, 51, 52, 53, 54, 55, 56, 57,
-               58, 59, 60, 62, 63, 64, 65, 66, 67, 69,
-               70, 71, 72, 74, 75, 76, 78, 79, 81, 82,
-               84, 85, 87, 88, 90, 92, 93, 95, 97, 98,
-               100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
-               120, 122, 124, 127, 129, 131, 134, 136, 138, 141,
-               144
-       },
-       {
-               32, 32, 33, 33, 34, 34, 35, 36, 36, 37,
-               38, 38, 39, 40, 41, 41, 42, 43, 44, 44,
-               45, 46, 47, 48, 49, 50, 50, 51, 52, 53,
-               54, 55, 56, 57, 58, 59, 60, 62, 63, 64,
-               65, 66, 67, 69, 70, 71, 72, 74, 75, 76,
-               78, 79, 81, 82, 84, 85, 87, 88, 90, 92,
-               93, 95, 97, 98, 100, 102, 104, 106, 108, 110,
-               112, 114, 116, 118, 120, 122, 124, 127, 129, 131,
-               134, 136, 139, 141, 144, 146, 149, 152, 154, 157,
-               160, 163, 166, 169, 172, 175, 178, 181, 185, 188,
-               192
-       }
-};
-
-/* MPEG blank frame generation tables */
-
-enum mpeg_frame_type {
-       PFRAME,
-       BFRAME_PRE,
-       BFRAME_POST,
-       BFRAME_BIDIR,
-       BFRAME_EMPTY
-};
-
-static const u32 addrinctab[33][2] = {
-       { 0x01, 1 },    { 0x03, 3 },    { 0x02, 3 },    { 0x03, 4 },
-       { 0x02, 4 },    { 0x03, 5 },    { 0x02, 5 },    { 0x07, 7 },
-       { 0x06, 7 },    { 0x0b, 8 },    { 0x0a, 8 },    { 0x09, 8 },
-       { 0x08, 8 },    { 0x07, 8 },    { 0x06, 8 },    { 0x17, 10 },
-       { 0x16, 10 },   { 0x15, 10 },   { 0x14, 10 },   { 0x13, 10 },
-       { 0x12, 10 },   { 0x23, 11 },   { 0x22, 11 },   { 0x21, 11 },
-       { 0x20, 11 },   { 0x1f, 11 },   { 0x1e, 11 },   { 0x1d, 11 },
-       { 0x1c, 11 },   { 0x1b, 11 },   { 0x1a, 11 },   { 0x19, 11 },
-       { 0x18, 11 }
-};
-
-/* Standard JPEG tables */
-
-static const u8 default_intra_quant_table[] = {
-        8, 16, 19, 22, 26, 27, 29, 34,
-       16, 16, 22, 24, 27, 29, 34, 37,
-       19, 22, 26, 27, 29, 34, 34, 38,
-       22, 22, 26, 27, 29, 34, 37, 40,
-       22, 26, 27, 29, 32, 35, 40, 48,
-       26, 27, 29, 32, 35, 40, 48, 58,
-       26, 27, 29, 34, 38, 46, 56, 69,
-       27, 29, 35, 38, 46, 56, 69, 83
-};
-
-static const u8 bits_dc_luminance[] = {
-       0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const u8 val_dc_luminance[] = {
-       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
-};
-
-static const u8 bits_dc_chrominance[] = {
-       0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
-};
-
-static const u8 val_dc_chrominance[] = {
-       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
-};
-
-static const u8 bits_ac_luminance[] = {
-       0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
-};
-
-static const u8 val_ac_luminance[] = {
-       0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
-       0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
-       0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
-       0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
-       0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
-       0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
-       0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-       0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
-       0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
-       0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
-       0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
-       0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
-       0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
-       0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
-       0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
-       0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
-       0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
-       0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
-       0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
-       0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
-       0xf9, 0xfa
-};
-
-static const u8 bits_ac_chrominance[] = {
-       0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
-};
-
-static const u8 val_ac_chrominance[] = {
-       0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
-       0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
-       0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
-       0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
-       0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
-       0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
-       0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
-       0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
-       0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
-       0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
-       0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-       0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-       0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
-       0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
-       0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
-       0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
-       0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
-       0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
-       0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
-       0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
-       0xf9, 0xfa
-};
-
-/* Zig-zag mapping for quant table
- *
- * OK, let's do this mapping on the actual table above so it doesn't have
- * to be done on the fly.
- */
-static const int zz[64] = {
-       0,   1,  8, 16,  9,  2,  3, 10, 17, 24, 32, 25, 18, 11,  4,  5,
-       12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13,  6,  7, 14, 21, 28,
-       35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
-       58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
-};
-
-static int copy_packages(__le16 *dest, u16 *src, int pkg_cnt, int space)
-{
-       int i, cnt = pkg_cnt * 32;
-
-       if (space < cnt)
-               return -1;
-
-       for (i = 0; i < cnt; ++i)
-               dest[i] = cpu_to_le16p(src + i);
-
-       return cnt;
-}
-
-static int mjpeg_frame_header(struct go7007 *go, unsigned char *buf, int q)
-{
-       int i, p = 0;
-
-       buf[p++] = 0xff;
-       buf[p++] = 0xd8;
-       buf[p++] = 0xff;
-       buf[p++] = 0xdb;
-       buf[p++] = 0;
-       buf[p++] = 2 + 65;
-       buf[p++] = 0;
-       buf[p++] = default_intra_quant_table[0];
-       for (i = 1; i < 64; ++i)
-               /* buf[p++] = (default_intra_quant_table[i] * q) >> 3; */
-               buf[p++] = (default_intra_quant_table[zz[i]] * q) >> 3;
-       buf[p++] = 0xff;
-       buf[p++] = 0xc0;
-       buf[p++] = 0;
-       buf[p++] = 17;
-       buf[p++] = 8;
-       buf[p++] = go->height >> 8;
-       buf[p++] = go->height & 0xff;
-       buf[p++] = go->width >> 8;
-       buf[p++] = go->width & 0xff;
-       buf[p++] = 3;
-       buf[p++] = 1;
-       buf[p++] = 0x22;
-       buf[p++] = 0;
-       buf[p++] = 2;
-       buf[p++] = 0x11;
-       buf[p++] = 0;
-       buf[p++] = 3;
-       buf[p++] = 0x11;
-       buf[p++] = 0;
-       buf[p++] = 0xff;
-       buf[p++] = 0xc4;
-       buf[p++] = 418 >> 8;
-       buf[p++] = 418 & 0xff;
-       buf[p++] = 0x00;
-       memcpy(buf + p, bits_dc_luminance + 1, 16);
-       p += 16;
-       memcpy(buf + p, val_dc_luminance, sizeof(val_dc_luminance));
-       p += sizeof(val_dc_luminance);
-       buf[p++] = 0x01;
-       memcpy(buf + p, bits_dc_chrominance + 1, 16);
-       p += 16;
-       memcpy(buf + p, val_dc_chrominance, sizeof(val_dc_chrominance));
-       p += sizeof(val_dc_chrominance);
-       buf[p++] = 0x10;
-       memcpy(buf + p, bits_ac_luminance + 1, 16);
-       p += 16;
-       memcpy(buf + p, val_ac_luminance, sizeof(val_ac_luminance));
-       p += sizeof(val_ac_luminance);
-       buf[p++] = 0x11;
-       memcpy(buf + p, bits_ac_chrominance + 1, 16);
-       p += 16;
-       memcpy(buf + p, val_ac_chrominance, sizeof(val_ac_chrominance));
-       p += sizeof(val_ac_chrominance);
-       buf[p++] = 0xff;
-       buf[p++] = 0xda;
-       buf[p++] = 0;
-       buf[p++] = 12;
-       buf[p++] = 3;
-       buf[p++] = 1;
-       buf[p++] = 0x00;
-       buf[p++] = 2;
-       buf[p++] = 0x11;
-       buf[p++] = 3;
-       buf[p++] = 0x11;
-       buf[p++] = 0;
-       buf[p++] = 63;
-       buf[p++] = 0;
-       return p;
-}
-
-static int gen_mjpeghdr_to_package(struct go7007 *go, __le16 *code, int space)
-{
-       u8 *buf;
-       u16 mem = 0x3e00;
-       unsigned int addr = 0x19;
-       int size = 0, i, off = 0, chunk;
-
-       buf = kzalloc(4096, GFP_KERNEL);
-       if (buf == NULL)
-               return -1;
-
-       for (i = 1; i < 32; ++i) {
-               mjpeg_frame_header(go, buf + size, i);
-               size += 80;
-       }
-       chunk = mjpeg_frame_header(go, buf + size, 1);
-       memmove(buf + size, buf + size + 80, chunk - 80);
-       size += chunk - 80;
-
-       for (i = 0; i < size; i += chunk * 2) {
-               if (space - off < 32) {
-                       off = -1;
-                       goto done;
-               }
-
-               code[off + 1] = __cpu_to_le16(0x8000 | mem);
-
-               chunk = 28;
-               if (mem + chunk > 0x4000)
-                       chunk = 0x4000 - mem;
-               if (i + 2 * chunk > size)
-                       chunk = (size - i) / 2;
-
-               if (chunk < 28) {
-                       code[off] = __cpu_to_le16(0x4000 | chunk);
-                       code[off + 31] = __cpu_to_le16(addr++);
-                       mem = 0x3e00;
-               } else {
-                       code[off] = __cpu_to_le16(0x1000 | 28);
-                       code[off + 31] = 0;
-                       mem += 28;
-               }
-
-               memcpy(&code[off + 2], buf + i, chunk * 2);
-               off += 32;
-       }
-done:
-       kfree(buf);
-       return off;
-}
-
-static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
-               int modulo, int pict_struct, enum mpeg_frame_type frame)
-{
-       int i, j, mb_code, mb_len;
-       int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
-       CODE_GEN(c, buf + 6);
-
-       switch (frame) {
-       case PFRAME:
-               mb_code = 0x1;
-               mb_len = 3;
-               break;
-       case BFRAME_PRE:
-               mb_code = 0x2;
-               mb_len = 4;
-               break;
-       case BFRAME_POST:
-               mb_code = 0x2;
-               mb_len = 3;
-               break;
-       case BFRAME_BIDIR:
-               mb_code = 0x2;
-               mb_len = 2;
-               break;
-       default: /* keep the compiler happy */
-               mb_code = mb_len = 0;
-               break;
-       }
-
-       CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13);
-       CODE_ADD(c, 0xffff, 16);
-       CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 0x7 : 0x4, 4);
-       if (frame != PFRAME)
-               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?? */
-       /* Byte-align with zeros */
-       j = 8 - (CODE_LENGTH(c) % 8);
-       if (j != 8)
-               CODE_ADD(c, 0, j);
-
-       if (go->format == V4L2_PIX_FMT_MPEG2) {
-               CODE_ADD(c, 0x1, 24);
-               CODE_ADD(c, 0xb5, 8);
-               CODE_ADD(c, 0x844, 12);
-               CODE_ADD(c, frame == PFRAME ? 0xff : 0x44, 8);
-               if (go->interlace_coding) {
-                       CODE_ADD(c, pict_struct, 4);
-                       if (go->dvd_mode)
-                               CODE_ADD(c, 0x000, 11);
-                       else
-                               CODE_ADD(c, 0x200, 11);
-               } else {
-                       CODE_ADD(c, 0x3, 4);
-                       CODE_ADD(c, 0x20c, 11);
-               }
-               /* Byte-align with zeros */
-               j = 8 - (CODE_LENGTH(c) % 8);
-               if (j != 8)
-                       CODE_ADD(c, 0, j);
-       }
-
-       for (i = 0; i < rows; ++i) {
-               CODE_ADD(c, 1, 24);
-               CODE_ADD(c, i + 1, 8);
-               CODE_ADD(c, 0x2, 6);
-               CODE_ADD(c, 0x1, 1);
-               CODE_ADD(c, mb_code, mb_len);
-               if (go->interlace_coding) {
-                       CODE_ADD(c, 0x1, 2);
-                       CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
-               }
-               if (frame == BFRAME_BIDIR) {
-                       CODE_ADD(c, 0x3, 2);
-                       if (go->interlace_coding)
-                               CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
-               }
-               CODE_ADD(c, 0x3, 2);
-               for (j = (go->width >> 4) - 2; j >= 33; j -= 33)
-                       CODE_ADD(c, 0x8, 11);
-               CODE_ADD(c, addrinctab[j][0], addrinctab[j][1]);
-               CODE_ADD(c, mb_code, mb_len);
-               if (go->interlace_coding) {
-                       CODE_ADD(c, 0x1, 2);
-                       CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
-               }
-               if (frame == BFRAME_BIDIR) {
-                       CODE_ADD(c, 0x3, 2);
-                       if (go->interlace_coding)
-                               CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
-               }
-               CODE_ADD(c, 0x3, 2);
-
-               /* Byte-align with zeros */
-               j = 8 - (CODE_LENGTH(c) % 8);
-               if (j != 8)
-                       CODE_ADD(c, 0, j);
-       }
-
-       i = CODE_LENGTH(c) + 4 * 8;
-       buf[2] = 0x00;
-       buf[3] = 0x00;
-       buf[4] = 0x01;
-       buf[5] = 0x00;
-       return i;
-}
-
-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 == V4L2_PIX_FMT_MPEG1) {
-               switch (go->aspect_ratio) {
-               case GO7007_RATIO_4_3:
-                       aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
-                       break;
-               case GO7007_RATIO_16_9:
-                       aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
-                       break;
-               default:
-                       aspect_ratio = 1;
-                       break;
-               }
-       } else {
-               switch (go->aspect_ratio) {
-               case GO7007_RATIO_4_3:
-                       aspect_ratio = 2;
-                       break;
-               case GO7007_RATIO_16_9:
-                       aspect_ratio = 3;
-                       break;
-               default:
-                       aspect_ratio = 1;
-                       break;
-               }
-       }
-       switch (go->sensor_framerate) {
-       case 24000:
-               picture_rate = 1;
-               break;
-       case 24024:
-               picture_rate = 2;
-               break;
-       case 25025:
-               picture_rate = go->interlace_coding ? 6 : 3;
-               break;
-       case 30000:
-               picture_rate = go->interlace_coding ? 7 : 4;
-               break;
-       case 30030:
-               picture_rate = go->interlace_coding ? 8 : 5;
-               break;
-       default:
-               picture_rate = 5; /* 30 fps seems like a reasonable default */
-               break;
-       }
-
-       CODE_ADD(c, go->width, 12);
-       CODE_ADD(c, go->height, 12);
-       CODE_ADD(c, aspect_ratio, 4);
-       CODE_ADD(c, picture_rate, 4);
-       CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 20000 : 0x3ffff, 18);
-       CODE_ADD(c, 1, 1);
-       CODE_ADD(c, go->format == V4L2_PIX_FMT_MPEG2 ? 112 : 20, 10);
-       CODE_ADD(c, 0, 3);
-
-       /* Byte-align with zeros */
-       i = 8 - (CODE_LENGTH(c) % 8);
-       if (i != 8)
-               CODE_ADD(c, 0, i);
-
-       if (go->format == V4L2_PIX_FMT_MPEG2) {
-               CODE_ADD(c, 0x1, 24);
-               CODE_ADD(c, 0xb5, 8);
-               CODE_ADD(c, 0x148, 12);
-               if (go->interlace_coding)
-                       CODE_ADD(c, 0x20001, 20);
-               else
-                       CODE_ADD(c, 0xa0001, 20);
-               CODE_ADD(c, 0, 16);
-
-               /* Byte-align with zeros */
-               i = 8 - (CODE_LENGTH(c) % 8);
-               if (i != 8)
-                       CODE_ADD(c, 0, i);
-
-               if (ext) {
-                       CODE_ADD(c, 0x1, 24);
-                       CODE_ADD(c, 0xb52, 12);
-                       CODE_ADD(c, go->standard == GO7007_STD_NTSC ? 2 : 1, 3);
-                       CODE_ADD(c, 0x105, 9);
-                       CODE_ADD(c, 0x505, 16);
-                       CODE_ADD(c, go->width, 14);
-                       CODE_ADD(c, 1, 1);
-                       CODE_ADD(c, go->height, 14);
-
-                       /* Byte-align with zeros */
-                       i = 8 - (CODE_LENGTH(c) % 8);
-                       if (i != 8)
-                               CODE_ADD(c, 0, i);
-               }
-       }
-
-       i = CODE_LENGTH(c) + 4 * 8;
-       buf[0] = i & 0xff;
-       buf[1] = i >> 8;
-       buf[2] = 0x00;
-       buf[3] = 0x00;
-       buf[4] = 0x01;
-       buf[5] = 0xb3;
-       return i;
-}
-
-static int gen_mpeg1hdr_to_package(struct go7007 *go,
-                                       __le16 *code, int space, int *framelen)
-{
-       u8 *buf;
-       u16 mem = 0x3e00;
-       unsigned int addr = 0x19;
-       int i, off = 0, chunk;
-
-       buf = kzalloc(5120, GFP_KERNEL);
-       if (buf == NULL)
-               return -1;
-
-       framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME);
-       if (go->interlace_coding)
-               framelen[0] += mpeg1_frame_header(go, buf + framelen[0] / 8,
-                                                       0, 2, PFRAME);
-       buf[0] = framelen[0] & 0xff;
-       buf[1] = framelen[0] >> 8;
-       i = 368;
-       framelen[1] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_PRE);
-       if (go->interlace_coding)
-               framelen[1] += mpeg1_frame_header(go, buf + i + framelen[1] / 8,
-                                                       0, 2, BFRAME_PRE);
-       buf[i] = framelen[1] & 0xff;
-       buf[i + 1] = framelen[1] >> 8;
-       i += 1632;
-       framelen[2] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_POST);
-       if (go->interlace_coding)
-               framelen[2] += mpeg1_frame_header(go, buf + i + framelen[2] / 8,
-                                                       0, 2, BFRAME_POST);
-       buf[i] = framelen[2] & 0xff;
-       buf[i + 1] = framelen[2] >> 8;
-       i += 1432;
-       framelen[3] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_BIDIR);
-       if (go->interlace_coding)
-               framelen[3] += mpeg1_frame_header(go, buf + i + framelen[3] / 8,
-                                                       0, 2, BFRAME_BIDIR);
-       buf[i] = framelen[3] & 0xff;
-       buf[i + 1] = framelen[3] >> 8;
-       i += 1632 + 16;
-       mpeg1_sequence_header(go, buf + i, 0);
-       i += 40;
-       for (i = 0; i < 5120; i += chunk * 2) {
-               if (space - off < 32) {
-                       off = -1;
-                       goto done;
-               }
-
-               code[off + 1] = __cpu_to_le16(0x8000 | mem);
-
-               chunk = 28;
-               if (mem + chunk > 0x4000)
-                       chunk = 0x4000 - mem;
-               if (i + 2 * chunk > 5120)
-                       chunk = (5120 - i) / 2;
-
-               if (chunk < 28) {
-                       code[off] = __cpu_to_le16(0x4000 | chunk);
-                       code[off + 31] = __cpu_to_le16(addr);
-                       if (mem + chunk == 0x4000) {
-                               mem = 0x3e00;
-                               ++addr;
-                       }
-               } else {
-                       code[off] = __cpu_to_le16(0x1000 | 28);
-                       code[off + 31] = 0;
-                       mem += 28;
-               }
-
-               memcpy(&code[off + 2], buf + i, chunk * 2);
-               off += 32;
-       }
-done:
-       kfree(buf);
-       return off;
-}
-
-static int vti_bitlen(struct go7007 *go)
-{
-       unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
-
-       for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i)
-               ;
-       return i + 1;
-}
-
-static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
-               int modulo, enum mpeg_frame_type frame)
-{
-       int i;
-       CODE_GEN(c, buf + 6);
-       int mb_count = (go->width >> 4) * (go->height >> 4);
-
-       CODE_ADD(c, frame == PFRAME ? 0x1 : 0x2, 2);
-       if (modulo)
-               CODE_ADD(c, 0x1, 1);
-       CODE_ADD(c, 0x1, 2);
-       CODE_ADD(c, 0, vti_bitlen(go));
-       CODE_ADD(c, 0x3, 2);
-       if (frame == PFRAME)
-               CODE_ADD(c, 0, 1);
-       CODE_ADD(c, 0xc, 11);
-       if (frame != PFRAME)
-               CODE_ADD(c, 0x4, 3);
-       if (frame != BFRAME_EMPTY) {
-               for (i = 0; i < mb_count; ++i) {
-                       switch (frame) {
-                       case PFRAME:
-                               CODE_ADD(c, 0x1, 1);
-                               break;
-                       case BFRAME_PRE:
-                               CODE_ADD(c, 0x47, 8);
-                               break;
-                       case BFRAME_POST:
-                               CODE_ADD(c, 0x27, 7);
-                               break;
-                       case BFRAME_BIDIR:
-                               CODE_ADD(c, 0x5f, 8);
-                               break;
-                       case BFRAME_EMPTY: /* keep compiler quiet */
-                               break;
-                       }
-               }
-       }
-
-       /* Byte-align with a zero followed by ones */
-       i = 8 - (CODE_LENGTH(c) % 8);
-       CODE_ADD(c, 0, 1);
-       CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
-
-       i = CODE_LENGTH(c) + 4 * 8;
-       buf[0] = i & 0xff;
-       buf[1] = i >> 8;
-       buf[2] = 0x00;
-       buf[3] = 0x00;
-       buf[4] = 0x01;
-       buf[5] = 0xb6;
-       return i;
-}
-
-static int mpeg4_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
-{
-       const unsigned char head[] = { 0x00, 0x00, 0x01, 0xb0, go->pali,
-               0x00, 0x00, 0x01, 0xb5, 0x09,
-               0x00, 0x00, 0x01, 0x00,
-               0x00, 0x00, 0x01, 0x20, };
-       int i, aspect_ratio;
-       int fps = go->sensor_framerate / go->fps_scale;
-       CODE_GEN(c, buf + 2 + sizeof(head));
-
-       switch (go->aspect_ratio) {
-       case GO7007_RATIO_4_3:
-               aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
-               break;
-       case GO7007_RATIO_16_9:
-               aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
-               break;
-       default:
-               aspect_ratio = 1;
-               break;
-       }
-
-       memcpy(buf + 2, head, sizeof(head));
-       CODE_ADD(c, 0x191, 17);
-       CODE_ADD(c, aspect_ratio, 4);
-       CODE_ADD(c, 0x1, 4);
-       CODE_ADD(c, fps, 16);
-       CODE_ADD(c, 0x3, 2);
-       CODE_ADD(c, 1001, vti_bitlen(go));
-       CODE_ADD(c, 1, 1);
-       CODE_ADD(c, go->width, 13);
-       CODE_ADD(c, 1, 1);
-       CODE_ADD(c, go->height, 13);
-       CODE_ADD(c, 0x2830, 14);
-
-       /* Byte-align */
-       i = 8 - (CODE_LENGTH(c) % 8);
-       CODE_ADD(c, 0, 1);
-       CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
-
-       i = CODE_LENGTH(c) + sizeof(head) * 8;
-       buf[0] = i & 0xff;
-       buf[1] = i >> 8;
-       return i;
-}
-
-static int gen_mpeg4hdr_to_package(struct go7007 *go,
-                                       __le16 *code, int space, int *framelen)
-{
-       u8 *buf;
-       u16 mem = 0x3e00;
-       unsigned int addr = 0x19;
-       int i, off = 0, chunk;
-
-       buf = kzalloc(5120, GFP_KERNEL);
-       if (buf == NULL)
-               return -1;
-
-       framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME);
-       i = 368;
-       framelen[1] = mpeg4_frame_header(go, buf + i, 0, BFRAME_PRE);
-       i += 1632;
-       framelen[2] = mpeg4_frame_header(go, buf + i, 0, BFRAME_POST);
-       i += 1432;
-       framelen[3] = mpeg4_frame_header(go, buf + i, 0, BFRAME_BIDIR);
-       i += 1632;
-       mpeg4_frame_header(go, buf + i, 0, BFRAME_EMPTY);
-       i += 16;
-       mpeg4_sequence_header(go, buf + i, 0);
-       i += 40;
-       for (i = 0; i < 5120; i += chunk * 2) {
-               if (space - off < 32) {
-                       off = -1;
-                       goto done;
-               }
-
-               code[off + 1] = __cpu_to_le16(0x8000 | mem);
-
-               chunk = 28;
-               if (mem + chunk > 0x4000)
-                       chunk = 0x4000 - mem;
-               if (i + 2 * chunk > 5120)
-                       chunk = (5120 - i) / 2;
-
-               if (chunk < 28) {
-                       code[off] = __cpu_to_le16(0x4000 | chunk);
-                       code[off + 31] = __cpu_to_le16(addr);
-                       if (mem + chunk == 0x4000) {
-                               mem = 0x3e00;
-                               ++addr;
-                       }
-               } else {
-                       code[off] = __cpu_to_le16(0x1000 | 28);
-                       code[off + 31] = 0;
-                       mem += 28;
-               }
-
-               memcpy(&code[off + 2], buf + i, chunk * 2);
-               off += 32;
-       }
-       mem = 0x3e00;
-       addr = go->ipb ? 0x14f9 : 0x0af9;
-       memset(buf, 0, 5120);
-       framelen[4] = mpeg4_frame_header(go, buf, 1, PFRAME);
-       i = 368;
-       framelen[5] = mpeg4_frame_header(go, buf + i, 1, BFRAME_PRE);
-       i += 1632;
-       framelen[6] = mpeg4_frame_header(go, buf + i, 1, BFRAME_POST);
-       i += 1432;
-       framelen[7] = mpeg4_frame_header(go, buf + i, 1, BFRAME_BIDIR);
-       i += 1632;
-       mpeg4_frame_header(go, buf + i, 1, BFRAME_EMPTY);
-       i += 16;
-       for (i = 0; i < 5120; i += chunk * 2) {
-               if (space - off < 32) {
-                       off = -1;
-                       goto done;
-               }
-
-               code[off + 1] = __cpu_to_le16(0x8000 | mem);
-
-               chunk = 28;
-               if (mem + chunk > 0x4000)
-                       chunk = 0x4000 - mem;
-               if (i + 2 * chunk > 5120)
-                       chunk = (5120 - i) / 2;
-
-               if (chunk < 28) {
-                       code[off] = __cpu_to_le16(0x4000 | chunk);
-                       code[off + 31] = __cpu_to_le16(addr);
-                       if (mem + chunk == 0x4000) {
-                               mem = 0x3e00;
-                               ++addr;
-                       }
-               } else {
-                       code[off] = __cpu_to_le16(0x1000 | 28);
-                       code[off + 31] = 0;
-                       mem += 28;
-               }
-
-               memcpy(&code[off + 2], buf + i, chunk * 2);
-               off += 32;
-       }
-done:
-       kfree(buf);
-       return off;
-}
-
-static int brctrl_to_package(struct go7007 *go,
-                                       __le16 *code, int space, int *framelen)
-{
-       int converge_speed = 0;
-       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 == V4L2_PIX_FMT_MJPEG ?
-                               go->bitrate :
-                               (go->dvd_mode ? 900000 : peak_rate);
-       int fps = go->sensor_framerate / go->fps_scale;
-       int q = 0;
-       /* Bizarre math below depends on rounding errors in division */
-       u32 sgop_expt_addr = go->bitrate / 32 * (go->ipb ? 3 : 1) * 1001 / fps;
-       u32 sgop_peak_addr = peak_rate / 32 * 1001 / fps;
-       u32 total_expt_addr = go->bitrate / 32 * 1000 / fps * (fps / 1000);
-       u32 vbv_alert_addr = vbv_buffer * 3 / (4 * 32);
-       u32 cplx[] = {
-               q > 0 ? sgop_expt_addr * q :
-                       2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
-               q > 0 ? sgop_expt_addr * q :
-                       2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
-               q > 0 ? sgop_expt_addr * q :
-                       2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
-               q > 0 ? sgop_expt_addr * q :
-                       2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
-       };
-       u32 calc_q = q > 0 ? q : cplx[0] / sgop_expt_addr;
-       u16 pack[] = {
-               0x200e,         0x0000,
-               0xBF20,         go->ipb ? converge_speed_ipb[converge_speed]
-                                       : converge_speed_ip[converge_speed],
-               0xBF21,         go->ipb ? 2 : 0,
-               0xBF22,         go->ipb ? LAMBDA_table[0][lambda / 2 + 50]
-                                       : 32767,
-               0xBF23,         go->ipb ? LAMBDA_table[1][lambda] : 32767,
-               0xBF24,         32767,
-               0xBF25,         lambda > 99 ? 32767 : LAMBDA_table[3][lambda],
-               0xBF26,         sgop_expt_addr & 0x0000FFFF,
-               0xBF27,         sgop_expt_addr >> 16,
-               0xBF28,         sgop_peak_addr & 0x0000FFFF,
-               0xBF29,         sgop_peak_addr >> 16,
-               0xBF2A,         vbv_alert_addr & 0x0000FFFF,
-               0xBF2B,         vbv_alert_addr >> 16,
-               0xBF2C,         0,
-               0xBF2D,         0,
-               0,              0,
-
-               0x200e,         0x0000,
-               0xBF2E,         vbv_alert_addr & 0x0000FFFF,
-               0xBF2F,         vbv_alert_addr >> 16,
-               0xBF30,         cplx[0] & 0x0000FFFF,
-               0xBF31,         cplx[0] >> 16,
-               0xBF32,         cplx[1] & 0x0000FFFF,
-               0xBF33,         cplx[1] >> 16,
-               0xBF34,         cplx[2] & 0x0000FFFF,
-               0xBF35,         cplx[2] >> 16,
-               0xBF36,         cplx[3] & 0x0000FFFF,
-               0xBF37,         cplx[3] >> 16,
-               0xBF38,         0,
-               0xBF39,         0,
-               0xBF3A,         total_expt_addr & 0x0000FFFF,
-               0xBF3B,         total_expt_addr >> 16,
-               0,              0,
-
-               0x200e,         0x0000,
-               0xBF3C,         total_expt_addr & 0x0000FFFF,
-               0xBF3D,         total_expt_addr >> 16,
-               0xBF3E,         0,
-               0xBF3F,         0,
-               0xBF48,         0,
-               0xBF49,         0,
-               0xBF4A,         calc_q < 4 ? 4 : (calc_q > 124 ? 124 : calc_q),
-               0xBF4B,         4,
-               0xBF4C,         0,
-               0xBF4D,         0,
-               0xBF4E,         0,
-               0xBF4F,         0,
-               0xBF50,         0,
-               0xBF51,         0,
-               0,              0,
-
-               0x200e,         0x0000,
-               0xBF40,         sgop_expt_addr & 0x0000FFFF,
-               0xBF41,         sgop_expt_addr >> 16,
-               0xBF42,         0,
-               0xBF43,         0,
-               0xBF44,         0,
-               0xBF45,         0,
-               0xBF46,         (go->width >> 4) * (go->height >> 4),
-               0xBF47,         0,
-               0xBF64,         0,
-               0xBF65,         0,
-               0xBF18,         framelen[4],
-               0xBF19,         framelen[5],
-               0xBF1A,         framelen[6],
-               0xBF1B,         framelen[7],
-               0,              0,
-
-#if 0
-               /* Remove once we don't care about matching */
-               0x200e,         0x0000,
-               0xBF56,         4,
-               0xBF57,         0,
-               0xBF58,         5,
-               0xBF59,         0,
-               0xBF5A,         6,
-               0xBF5B,         0,
-               0xBF5C,         8,
-               0xBF5D,         0,
-               0xBF5E,         1,
-               0xBF5F,         0,
-               0xBF60,         1,
-               0xBF61,         0,
-               0xBF62,         0,
-               0xBF63,         0,
-               0,              0,
-#else
-               0x2008,         0x0000,
-               0xBF56,         4,
-               0xBF57,         0,
-               0xBF58,         5,
-               0xBF59,         0,
-               0xBF5A,         6,
-               0xBF5B,         0,
-               0xBF5C,         8,
-               0xBF5D,         0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-#endif
-
-               0x200e,         0x0000,
-               0xBF10,         0,
-               0xBF11,         0,
-               0xBF12,         0,
-               0xBF13,         0,
-               0xBF14,         0,
-               0xBF15,         0,
-               0xBF16,         0,
-               0xBF17,         0,
-               0xBF7E,         0,
-               0xBF7F,         1,
-               0xBF52,         framelen[0],
-               0xBF53,         framelen[1],
-               0xBF54,         framelen[2],
-               0xBF55,         framelen[3],
-               0,              0,
-       };
-
-       return copy_packages(code, pack, 6, space);
-}
-
-static int config_package(struct go7007 *go, __le16 *code, int space)
-{
-       int fps = go->sensor_framerate / go->fps_scale / 1000;
-       int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
-       int brc_window_size = fps;
-       int q_min = 2, q_max = 31;
-       int THACCoeffSet0 = 0;
-       u16 pack[] = {
-               0x200e,         0x0000,
-               0xc002,         0x14b4,
-               0xc003,         0x28b4,
-               0xc004,         0x3c5a,
-               0xdc05,         0x2a77,
-               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,
-               0xc60f,         0x0008,
-               0xd4ff,         0x0002,
-               0xe403,         2340,
-               0xe406,         75,
-               0xd411,         0x0001,
-               0xd410,         0xa1d6,
-               0x0001,         0x2801,
-
-               0x200d,         0x0000,
-               0xe402,         0x018b,
-               0xe401,         0x8b01,
-               0xd472,         (go->board_info->sensor_flags &
-                                                       GO7007_SENSOR_TV) &&
-                                               (!go->interlace_coding) ?
-                                       0x01b0 : 0x0170,
-               0xd475,         (go->board_info->sensor_flags &
-                                                       GO7007_SENSOR_TV) &&
-                                               (!go->interlace_coding) ?
-                                       0x0008 : 0x0009,
-               0xc404,         go->interlace_coding ? 0x44 :
-                               (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 == 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),
-               0xbf0b,         0,
-               0xdd5a,         go->ipb ? 0x14 : 0x0a,
-               0xbf0c,         0,
-               0xbf0d,         0,
-               0xc683,         THACCoeffSet0,
-               0xc40a,         (go->width << 4) | rows,
-               0xe01a,         go->board_info->hpi_buffer_cap,
-               0,              0,
-               0,              0,
-
-               0x2008,         0,
-               0xe402,         0x88,
-               0xe401,         0x8f01,
-               0xbf6a,         0,
-               0xbf6b,         0,
-               0xbf6c,         0,
-               0xbf6d,         0,
-               0xbf6e,         0,
-               0xbf6f,         0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-
-               0x200e,         0,
-               0xbf66,         brc_window_size,
-               0xbf67,         0,
-               0xbf68,         q_min,
-               0xbf69,         q_max,
-               0xbfe0,         0,
-               0xbfe1,         0,
-               0xbfe2,         0,
-               0xbfe3,         go->ipb ? 3 : 1,
-               0xc031,         go->board_info->sensor_flags &
-                                       GO7007_SENSOR_VBI ? 1 : 0,
-               0xc01c,         0x1f,
-               0xdd8c,         0x15,
-               0xdd94,         0x15,
-               0xdd88,         go->ipb ? 0x1401 : 0x0a01,
-               0xdd90,         go->ipb ? 0x1401 : 0x0a01,
-               0,              0,
-
-               0x200e,         0,
-               0xbfe4,         0,
-               0xbfe5,         0,
-               0xbfe6,         0,
-               0xbfe7,         fps << 8,
-               0xbfe8,         0x3a00,
-               0xbfe9,         0,
-               0xbfea,         0,
-               0xbfeb,         0,
-               0xbfec,         (go->interlace_coding ? 1 << 15 : 0) |
-                                       (go->modet_enable ? 0xa : 0) |
-                                       (go->board_info->sensor_flags &
-                                               GO7007_SENSOR_VBI ? 1 : 0),
-               0xbfed,         0,
-               0xbfee,         0,
-               0xbfef,         0,
-               0xbff0,         go->board_info->sensor_flags &
-                                       GO7007_SENSOR_TV ? 0xf060 : 0xb060,
-               0xbff1,         0,
-               0,              0,
-       };
-
-       return copy_packages(code, pack, 5, space);
-}
-
-static int seqhead_to_package(struct go7007 *go, __le16 *code, int space,
-       int (*sequence_header_func)(struct go7007 *go,
-               unsigned char *buf, int ext))
-{
-       int vop_time_increment_bitlength = vti_bitlen(go);
-       int fps = go->sensor_framerate / go->fps_scale *
-                                       (go->interlace_coding ? 2 : 1);
-       unsigned char buf[40] = { };
-       int len = sequence_header_func(go, buf, 1);
-       u16 pack[] = {
-               0x2006,         0,
-               0xbf08,         fps,
-               0xbf09,         0,
-               0xbff2,         vop_time_increment_bitlength,
-               0xbff3,         (1 << vop_time_increment_bitlength) - 1,
-               0xbfe6,         0,
-               0xbfe7,         (fps / 1000) << 8,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-
-               0x2007,         0,
-               0xc800,         buf[2] << 8 | buf[3],
-               0xc801,         buf[4] << 8 | buf[5],
-               0xc802,         buf[6] << 8 | buf[7],
-               0xc803,         buf[8] << 8 | buf[9],
-               0xc406,         64,
-               0xc407,         len - 64,
-               0xc61b,         1,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-
-               0x200e,         0,
-               0xc808,         buf[10] << 8 | buf[11],
-               0xc809,         buf[12] << 8 | buf[13],
-               0xc80a,         buf[14] << 8 | buf[15],
-               0xc80b,         buf[16] << 8 | buf[17],
-               0xc80c,         buf[18] << 8 | buf[19],
-               0xc80d,         buf[20] << 8 | buf[21],
-               0xc80e,         buf[22] << 8 | buf[23],
-               0xc80f,         buf[24] << 8 | buf[25],
-               0xc810,         buf[26] << 8 | buf[27],
-               0xc811,         buf[28] << 8 | buf[29],
-               0xc812,         buf[30] << 8 | buf[31],
-               0xc813,         buf[32] << 8 | buf[33],
-               0xc814,         buf[34] << 8 | buf[35],
-               0xc815,         buf[36] << 8 | buf[37],
-               0,              0,
-               0,              0,
-               0,              0,
-       };
-
-       return copy_packages(code, pack, 3, space);
-}
-
-static int relative_prime(int big, int little)
-{
-       int remainder;
-
-       while (little != 0) {
-               remainder = big % little;
-               big = little;
-               little = remainder;
-       }
-       return big;
-}
-
-static int avsync_to_package(struct go7007 *go, __le16 *code, int space)
-{
-       int arate = go->board_info->audio_rate * 1001 * go->fps_scale;
-       int ratio = arate / go->sensor_framerate;
-       int adjratio = ratio * 215 / 100;
-       int rprime = relative_prime(go->sensor_framerate,
-                                       arate % go->sensor_framerate);
-       int f1 = (arate % go->sensor_framerate) / rprime;
-       int f2 = (go->sensor_framerate - arate % go->sensor_framerate) / rprime;
-       u16 pack[] = {
-               0x200e,         0,
-               0xbf98,         (u16)((-adjratio) & 0xffff),
-               0xbf99,         (u16)((-adjratio) >> 16),
-               0xbf92,         0,
-               0xbf93,         0,
-               0xbff4,         f1 > f2 ? f1 : f2,
-               0xbff5,         f1 < f2 ? f1 : f2,
-               0xbff6,         f1 < f2 ? ratio : ratio + 1,
-               0xbff7,         f1 > f2 ? ratio : ratio + 1,
-               0xbff8,         0,
-               0xbff9,         0,
-               0xbffa,         adjratio & 0xffff,
-               0xbffb,         adjratio >> 16,
-               0xbf94,         0,
-               0xbf95,         0,
-               0,              0,
-       };
-
-       return copy_packages(code, pack, 1, space);
-}
-
-static int final_package(struct go7007 *go, __le16 *code, int space)
-{
-       int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
-       u16 pack[] = {
-               0x8000,
-               0,
-               0,
-               0,
-               0,
-               0,
-               0,
-               2,
-               ((go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
-                                               (!go->interlace_coding) ?
-                                       (1 << 14) | (1 << 9) : 0) |
-                       ((go->encoder_subsample ? 1 : 0) << 8) |
-                       (go->board_info->sensor_flags &
-                               GO7007_SENSOR_CONFIG_MASK),
-               ((go->encoder_v_halve ? 1 : 0) << 14) |
-                       (go->encoder_v_halve ? rows << 9 : rows << 8) |
-                       (go->encoder_h_halve ? 1 << 6 : 0) |
-                       (go->encoder_h_halve ? go->width >> 3 : go->width >> 4),
-               (1 << 15) | (go->encoder_v_offset << 6) |
-                       (1 << 7) | (go->encoder_h_offset >> 2),
-               (1 << 6),
-               0,
-               0,
-               ((go->fps_scale - 1) << 8) |
-                       (go->board_info->sensor_flags & GO7007_SENSOR_TV ?
-                                               (1 << 7) : 0) |
-                       0x41,
-               go->ipb ? 0xd4c : 0x36b,
-               (rows << 8) | (go->width >> 4),
-               go->format == V4L2_PIX_FMT_MPEG4 ? 0x0404 : 0,
-               (1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) |
-                       ((go->closed_gop ? 1 : 0) << 12) |
-                       ((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 == 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,
-               0xffff,
-               0x0020 + 0x034b * 0,
-               0x0020 + 0x034b * 1,
-               0x0020 + 0x034b * 2,
-               0x0020 + 0x034b * 3,
-               0x0020 + 0x034b * 4,
-               0x0020 + 0x034b * 5,
-               go->ipb ? (go->gop_size / 3) : go->gop_size,
-               (go->height >> 4) * (go->width >> 4) * 110 / 100,
-       };
-
-       return copy_packages(code, pack, 1, space);
-}
-
-static int audio_to_package(struct go7007 *go, __le16 *code, int space)
-{
-       int clock_config = ((go->board_info->audio_flags &
-                               GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) |
-                       ((go->board_info->audio_flags &
-                               GO7007_AUDIO_OKI_MODE ? 1 : 0) << 8) |
-                       (((go->board_info->audio_bclk_div / 4) - 1) << 4) |
-                       (go->board_info->audio_main_div - 1);
-       u16 pack[] = {
-               0x200d,         0,
-               0x9002,         0,
-               0x9002,         0,
-               0x9031,         0,
-               0x9032,         0,
-               0x9033,         0,
-               0x9034,         0,
-               0x9035,         0,
-               0x9036,         0,
-               0x9037,         0,
-               0x9040,         0,
-               0x9000,         clock_config,
-               0x9001,         (go->board_info->audio_flags & 0xffff) |
-                                       (1 << 9),
-               0x9000,         ((go->board_info->audio_flags &
-                                               GO7007_AUDIO_I2S_MASTER ?
-                                               1 : 0) << 10) |
-                                       clock_config,
-               0,              0,
-               0,              0,
-               0x2005,         0,
-               0x9041,         0,
-               0x9042,         256,
-               0x9043,         0,
-               0x9044,         16,
-               0x9045,         16,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-               0,              0,
-       };
-
-       return copy_packages(code, pack, 2, space);
-}
-
-static int modet_to_package(struct go7007 *go, __le16 *code, int space)
-{
-       bool has_modet0 = go->modet[0].enable;
-       bool has_modet1 = go->modet[1].enable;
-       bool has_modet2 = go->modet[2].enable;
-       bool has_modet3 = go->modet[3].enable;
-       int ret, mb, i, addr, cnt = 0;
-       u16 pack[32];
-       u16 thresholds[] = {
-               0x200e,         0,
-               0xbf82,         has_modet0 ? go->modet[0].pixel_threshold : 32767,
-               0xbf83,         has_modet1 ? go->modet[1].pixel_threshold : 32767,
-               0xbf84,         has_modet2 ? go->modet[2].pixel_threshold : 32767,
-               0xbf85,         has_modet3 ? go->modet[3].pixel_threshold : 32767,
-               0xbf86,         has_modet0 ? go->modet[0].motion_threshold : 32767,
-               0xbf87,         has_modet1 ? go->modet[1].motion_threshold : 32767,
-               0xbf88,         has_modet2 ? go->modet[2].motion_threshold : 32767,
-               0xbf89,         has_modet3 ? go->modet[3].motion_threshold : 32767,
-               0xbf8a,         has_modet0 ? go->modet[0].mb_threshold : 32767,
-               0xbf8b,         has_modet1 ? go->modet[1].mb_threshold : 32767,
-               0xbf8c,         has_modet2 ? go->modet[2].mb_threshold : 32767,
-               0xbf8d,         has_modet3 ? go->modet[3].mb_threshold : 32767,
-               0xbf8e,         0,
-               0xbf8f,         0,
-               0,              0,
-       };
-
-       ret = copy_packages(code, thresholds, 1, space);
-       if (ret < 0)
-               return -1;
-       cnt += ret;
-
-       addr = 0xbac0;
-       memset(pack, 0, 64);
-       i = 0;
-       for (mb = 0; mb < 1624; ++mb) {
-               pack[i * 2 + 3] <<= 2;
-               pack[i * 2 + 3] |= go->modet_map[mb];
-               if (mb % 8 != 7)
-                       continue;
-               pack[i * 2 + 2] = addr++;
-               ++i;
-               if (i == 10 || mb == 1623) {
-                       pack[0] = 0x2000 | i;
-                       ret = copy_packages(code + cnt, pack, 1, space - cnt);
-                       if (ret < 0)
-                               return -1;
-                       cnt += ret;
-                       i = 0;
-                       memset(pack, 0, 64);
-               }
-               pack[i * 2 + 3] = 0;
-       }
-
-       memset(pack, 0, 64);
-       i = 0;
-       for (addr = 0xbb90; addr < 0xbbfa; ++addr) {
-               pack[i * 2 + 2] = addr;
-               pack[i * 2 + 3] = 0;
-               ++i;
-               if (i == 10 || addr == 0xbbf9) {
-                       pack[0] = 0x2000 | i;
-                       ret = copy_packages(code + cnt, pack, 1, space - cnt);
-                       if (ret < 0)
-                               return -1;
-                       cnt += ret;
-                       i = 0;
-                       memset(pack, 0, 64);
-               }
-       }
-       return cnt;
-}
-
-static int do_special(struct go7007 *go, u16 type, __le16 *code, int space,
-                       int *framelen)
-{
-       switch (type) {
-       case SPECIAL_FRM_HEAD:
-               switch (go->format) {
-               case V4L2_PIX_FMT_MJPEG:
-                       return gen_mjpeghdr_to_package(go, code, space);
-               case V4L2_PIX_FMT_MPEG1:
-               case V4L2_PIX_FMT_MPEG2:
-                       return gen_mpeg1hdr_to_package(go, code, space,
-                                                               framelen);
-               case V4L2_PIX_FMT_MPEG4:
-                       return gen_mpeg4hdr_to_package(go, code, space,
-                                                               framelen);
-               }
-       case SPECIAL_BRC_CTRL:
-               return brctrl_to_package(go, code, space, framelen);
-       case SPECIAL_CONFIG:
-               return config_package(go, code, space);
-       case SPECIAL_SEQHEAD:
-               switch (go->format) {
-               case V4L2_PIX_FMT_MPEG1:
-               case V4L2_PIX_FMT_MPEG2:
-                       return seqhead_to_package(go, code, space,
-                                       mpeg1_sequence_header);
-               case V4L2_PIX_FMT_MPEG4:
-                       return seqhead_to_package(go, code, space,
-                                       mpeg4_sequence_header);
-               default:
-                       return 0;
-               }
-       case SPECIAL_AV_SYNC:
-               return avsync_to_package(go, code, space);
-       case SPECIAL_FINAL:
-               return final_package(go, code, space);
-       case SPECIAL_AUDIO:
-               return audio_to_package(go, code, space);
-       case SPECIAL_MODET:
-               return modet_to_package(go, code, space);
-       }
-       dev_err(go->dev,
-               "firmware file contains unsupported feature %04x\n", type);
-       return -1;
-}
-
-int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
-{
-       const struct firmware *fw_entry;
-       __le16 *code, *src;
-       int framelen[8] = { }; /* holds the lengths of empty frame templates */
-       int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags;
-       int mode_flag;
-       int ret;
-
-       switch (go->format) {
-       case V4L2_PIX_FMT_MJPEG:
-               mode_flag = FLAG_MODE_MJPEG;
-               break;
-       case V4L2_PIX_FMT_MPEG1:
-               mode_flag = FLAG_MODE_MPEG1;
-               break;
-       case V4L2_PIX_FMT_MPEG2:
-               mode_flag = FLAG_MODE_MPEG2;
-               break;
-       case V4L2_PIX_FMT_MPEG4:
-               mode_flag = FLAG_MODE_MPEG4;
-               break;
-       default:
-               return -1;
-       }
-       if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev)) {
-               dev_err(go->dev,
-                       "unable to load firmware from file \"%s\"\n",
-                       GO7007_FW_NAME);
-               return -1;
-       }
-       code = kzalloc(codespace * 2, GFP_KERNEL);
-       if (code == NULL)
-               goto fw_failed;
-
-       src = (__le16 *)fw_entry->data;
-       srclen = fw_entry->size / 2;
-       while (srclen >= 2) {
-               chunk_flags = __le16_to_cpu(src[0]);
-               chunk_len = __le16_to_cpu(src[1]);
-               if (chunk_len + 2 > srclen) {
-                       dev_err(go->dev,
-                               "firmware file \"%s\" appears to be corrupted\n",
-                               GO7007_FW_NAME);
-                       goto fw_failed;
-               }
-               if (chunk_flags & mode_flag) {
-                       if (chunk_flags & FLAG_SPECIAL) {
-                               ret = do_special(go, __le16_to_cpu(src[2]),
-                                       &code[i], codespace - i, framelen);
-                               if (ret < 0) {
-                                       dev_err(go->dev,
-                                               "insufficient memory for firmware construction\n");
-                                       goto fw_failed;
-                               }
-                               i += ret;
-                       } else {
-                               if (codespace - i < chunk_len) {
-                                       dev_err(go->dev,
-                                               "insufficient memory for firmware construction\n");
-                                       goto fw_failed;
-                               }
-                               memcpy(&code[i], &src[2], chunk_len * 2);
-                               i += chunk_len;
-                       }
-               }
-               srclen -= chunk_len + 2;
-               src += chunk_len + 2;
-       }
-       release_firmware(fw_entry);
-       *fw = (u8 *)code;
-       *fwlen = i * 2;
-       return 0;
-
-fw_failed:
-       kfree(code);
-       release_firmware(fw_entry);
-       return -1;
-}
-
-MODULE_FIRMWARE(GO7007_FW_NAME);
diff --git a/drivers/staging/media/go7007/go7007-i2c.c b/drivers/staging/media/go7007/go7007-i2c.c
deleted file mode 100644 (file)
index 55addfa..0000000
+++ /dev/null
@@ -1,218 +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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/list.h>
-#include <linux/unistd.h>
-#include <linux/time.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-
-#include "go7007-priv.h"
-
-/********************* Driver for on-board I2C adapter *********************/
-
-/* #define GO7007_I2C_DEBUG */
-
-#define SPI_I2C_ADDR_BASE              0x1400
-#define STATUS_REG_ADDR                        (SPI_I2C_ADDR_BASE + 0x2)
-#define I2C_CTRL_REG_ADDR              (SPI_I2C_ADDR_BASE + 0x6)
-#define I2C_DEV_UP_ADDR_REG_ADDR       (SPI_I2C_ADDR_BASE + 0x7)
-#define I2C_LO_ADDR_REG_ADDR           (SPI_I2C_ADDR_BASE + 0x8)
-#define I2C_DATA_REG_ADDR              (SPI_I2C_ADDR_BASE + 0x9)
-#define I2C_CLKFREQ_REG_ADDR           (SPI_I2C_ADDR_BASE + 0xa)
-
-#define I2C_STATE_MASK                 0x0007
-#define I2C_READ_READY_MASK            0x0008
-
-/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
- * on the Adlink PCI-MPG24, so access is shared between all of them. */
-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 = -EIO;
-       u16 val;
-
-       if (go->status == STATUS_SHUTDOWN)
-               return -ENODEV;
-
-#ifdef GO7007_I2C_DEBUG
-       if (read)
-               dev_dbg(go->dev, "go7007-i2c: reading 0x%02x on 0x%02x\n",
-                       command, addr);
-       else
-               dev_dbg(go->dev,
-                       "go7007-i2c: writing 0x%02x to 0x%02x on 0x%02x\n",
-                       *data, command, addr);
-#endif
-
-       mutex_lock(&go->hw_lock);
-
-       if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
-               /* Bridge the I2C port on this GO7007 to the shared bus */
-               mutex_lock(&adlink_mpg24_i2c_lock);
-               go7007_write_addr(go, 0x3c82, 0x0020);
-       }
-
-       /* Wait for I2C adapter to be ready */
-       for (i = 0; i < 10; ++i) {
-               if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
-                       goto i2c_done;
-               if (!(val & I2C_STATE_MASK))
-                       break;
-               msleep(100);
-       }
-       if (i == 10) {
-               dev_err(go->dev, "go7007-i2c: I2C adapter is hung\n");
-               goto i2c_done;
-       }
-
-       /* Set target register (command) */
-       go7007_write_addr(go, I2C_CTRL_REG_ADDR, flags);
-       go7007_write_addr(go, I2C_LO_ADDR_REG_ADDR, command);
-
-       /* If we're writing, send the data and target address and we're done */
-       if (!read) {
-               go7007_write_addr(go, I2C_DATA_REG_ADDR, *data);
-               go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
-                                       (addr << 9) | (command >> 8));
-               ret = 0;
-               goto i2c_done;
-       }
-
-       /* Otherwise, we're reading.  First clear i2c_rx_data_rdy. */
-       if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
-               goto i2c_done;
-
-       /* Send the target address plus read flag */
-       go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
-                       (addr << 9) | 0x0100 | (command >> 8));
-
-       /* Wait for i2c_rx_data_rdy */
-       for (i = 0; i < 10; ++i) {
-               if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
-                       goto i2c_done;
-               if (val & I2C_READ_READY_MASK)
-                       break;
-               msleep(100);
-       }
-       if (i == 10) {
-               dev_err(go->dev, "go7007-i2c: I2C adapter is hung\n");
-               goto i2c_done;
-       }
-
-       /* Retrieve the read byte */
-       if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
-               goto i2c_done;
-       *data = val;
-       ret = 0;
-
-i2c_done:
-       if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
-               /* Isolate the I2C port on this GO7007 from the shared bus */
-               go7007_write_addr(go, 0x3c82, 0x0000);
-               mutex_unlock(&adlink_mpg24_i2c_lock);
-       }
-       mutex_unlock(&go->hw_lock);
-       return ret;
-}
-
-static int go7007_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
-               unsigned short flags, char read_write,
-               u8 command, int size, union i2c_smbus_data *data)
-{
-       struct go7007 *go = i2c_get_adapdata(adapter);
-
-       if (size != I2C_SMBUS_BYTE_DATA)
-               return -EIO;
-       return go7007_i2c_xfer(go, addr, read_write == I2C_SMBUS_READ, command,
-                       flags & I2C_CLIENT_SCCB ? 0x10 : 0x00, &data->byte);
-}
-
-/* VERY LIMITED I2C master xfer function -- only needed because the
- * SMBus functions only support 8-bit commands and the SAA7135 uses
- * 16-bit commands.  The I2C interface on the GO7007, as limited as
- * it is, does support this mode. */
-
-static int go7007_i2c_master_xfer(struct i2c_adapter *adapter,
-                                       struct i2c_msg msgs[], int num)
-{
-       struct go7007 *go = i2c_get_adapdata(adapter);
-       int i;
-
-       for (i = 0; i < num; ++i) {
-               /* We can only do two things here -- write three bytes, or
-                * write two bytes and read one byte. */
-               if (msgs[i].len == 2) {
-                       if (i + 1 == num || msgs[i].addr != msgs[i + 1].addr ||
-                                       (msgs[i].flags & I2C_M_RD) ||
-                                       !(msgs[i + 1].flags & I2C_M_RD) ||
-                                       msgs[i + 1].len != 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 -EIO;
-                       ++i;
-               } else if (msgs[i].len == 3) {
-                       if (msgs[i].flags & I2C_M_RD)
-                               return -EIO;
-                       if (msgs[i].len != 3)
-                               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 -EIO;
-               } else
-                       return -EIO;
-       }
-
-       return num;
-}
-
-static u32 go7007_functionality(struct i2c_adapter *adapter)
-{
-       return I2C_FUNC_SMBUS_BYTE_DATA;
-}
-
-static struct i2c_algorithm go7007_algo = {
-       .smbus_xfer     = go7007_smbus_xfer,
-       .master_xfer    = go7007_i2c_master_xfer,
-       .functionality  = go7007_functionality,
-};
-
-static struct i2c_adapter go7007_adap_templ = {
-       .owner                  = THIS_MODULE,
-       .name                   = "WIS GO7007SB",
-       .algo                   = &go7007_algo,
-};
-
-int go7007_i2c_init(struct go7007 *go)
-{
-       memcpy(&go->i2c_adapter, &go7007_adap_templ,
-                       sizeof(go7007_adap_templ));
-       go->i2c_adapter.dev.parent = go->dev;
-       i2c_set_adapdata(&go->i2c_adapter, go);
-       if (i2c_add_adapter(&go->i2c_adapter) < 0) {
-               dev_err(go->dev,
-                       "go7007-i2c: error: i2c_add_adapter failed\n");
-               return -1;
-       }
-       return 0;
-}
diff --git a/drivers/staging/media/go7007/go7007-loader.c b/drivers/staging/media/go7007/go7007-loader.c
deleted file mode 100644 (file)
index 042f78a..0000000
+++ /dev/null
@@ -1,141 +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.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <cypress_firmware.h>
-
-struct fw_config {
-       u16 vendor;
-       u16 product;
-       const char * const fw_name1;
-       const char * const fw_name2;
-};
-
-static 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;
-       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)
-               goto failed2;
-
-       if (usbdev->descriptor.bNumConfigurations != 1) {
-               dev_err(&interface->dev, "can't handle multiple config\n");
-               goto failed2;
-       }
-
-       vendor = le16_to_cpu(usbdev->descriptor.idVendor);
-       product = le16_to_cpu(usbdev->descriptor.idProduct);
-
-       for (i = 0; fw_configs[i].fw_name1; i++)
-               if (fw_configs[i].vendor == vendor &&
-                   fw_configs[i].product == product)
-                       break;
-
-       /* Should never happen */
-       if (fw_configs[i].fw_name1 == NULL)
-               goto failed2;
-
-       fw1 = fw_configs[i].fw_name1;
-       fw2 = fw_configs[i].fw_name2;
-
-       dev_info(&interface->dev, "loading firmware %s\n", fw1);
-
-       if (request_firmware(&fw, fw1, &usbdev->dev)) {
-               dev_err(&interface->dev,
-                       "unable to load firmware from file \"%s\"\n", fw1);
-               goto failed2;
-       }
-       ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
-       release_firmware(fw);
-       if (0 != ret) {
-               dev_err(&interface->dev, "loader download failed\n");
-               goto failed2;
-       }
-
-       if (fw2 == NULL)
-               return 0;
-
-       if (request_firmware(&fw, fw2, &usbdev->dev)) {
-               dev_err(&interface->dev,
-                       "unable to load firmware from file \"%s\"\n", fw2);
-               goto failed2;
-       }
-       ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
-       release_firmware(fw);
-       if (0 != ret) {
-               dev_err(&interface->dev, "firmware download failed\n");
-               goto failed2;
-       }
-       return 0;
-
-failed2:
-       usb_put_dev(usbdev);
-       dev_err(&interface->dev, "probe failed\n");
-       return -ENODEV;
-}
-
-static void go7007_loader_disconnect(struct usb_interface *interface)
-{
-       dev_info(&interface->dev, "disconnect\n");
-       usb_put_dev(interface_to_usbdev(interface));
-       usb_set_intfdata(interface, NULL);
-}
-
-static const struct usb_device_id go7007_loader_ids[] = {
-       { USB_DEVICE(0x1943, 0xa250) },
-       { USB_DEVICE(0x093b, 0xa002) },
-       { USB_DEVICE(0x093b, 0xa004) },
-       { USB_DEVICE(0x0eb1, 0x6666) },
-       { USB_DEVICE(0x0eb1, 0x6668) },
-       {}                          /* 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");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
deleted file mode 100644 (file)
index 2251c3f..0000000
+++ /dev/null
@@ -1,306 +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.
- */
-
-/*
- * This is the private include file for the go7007 driver.  It should not
- * be included by anybody but the driver itself, and especially not by
- * user-space applications.
- */
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fh.h>
-#include <media/videobuf2-core.h>
-
-struct go7007;
-
-/* IDs to activate board-specific support code */
-#define GO7007_BOARDID_MATRIX_II       0
-#define GO7007_BOARDID_MATRIX_RELOAD   1
-#define GO7007_BOARDID_STAR_TREK       2
-#define GO7007_BOARDID_PCI_VOYAGER     3
-#define GO7007_BOARDID_XMEN            4
-#define GO7007_BOARDID_XMEN_II         5
-#define GO7007_BOARDID_XMEN_III                6
-#define GO7007_BOARDID_MATRIX_REV      7
-#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 */
-#define GO7007_BOARDID_ADS_USBAV_709    14
-
-/* Various characteristics of each board */
-#define GO7007_BOARD_HAS_AUDIO         (1<<0)
-#define GO7007_BOARD_USE_ONBOARD_I2C   (1<<1)
-#define GO7007_BOARD_HAS_TUNER         (1<<2)
-
-/* Characteristics of sensor devices */
-#define GO7007_SENSOR_VALID_POLAR      (1<<0)
-#define GO7007_SENSOR_HREF_POLAR       (1<<1)
-#define GO7007_SENSOR_VREF_POLAR       (1<<2)
-#define GO7007_SENSOR_FIELD_ID_POLAR   (1<<3)
-#define GO7007_SENSOR_BIT_WIDTH                (1<<4)
-#define GO7007_SENSOR_VALID_ENABLE     (1<<5)
-#define GO7007_SENSOR_656              (1<<6)
-#define GO7007_SENSOR_CONFIG_MASK      0x7f
-#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)
-#define GO7007_AUDIO_I2S_MODE_2                (2)
-#define GO7007_AUDIO_I2S_MODE_3                (3)
-#define GO7007_AUDIO_BCLK_POLAR                (1<<2)
-#define GO7007_AUDIO_WORD_14           (14<<4)
-#define GO7007_AUDIO_WORD_16           (16<<4)
-#define GO7007_AUDIO_ONE_CHANNEL       (1<<11)
-#define GO7007_AUDIO_I2S_MASTER                (1<<16)
-#define GO7007_AUDIO_OKI_MODE          (1<<17)
-
-#define GO7007_CID_CUSTOM_BASE         (V4L2_CID_DETECT_CLASS_BASE + 0x1000)
-#define V4L2_CID_PIXEL_THRESHOLD0      (GO7007_CID_CUSTOM_BASE+1)
-#define V4L2_CID_MOTION_THRESHOLD0     (GO7007_CID_CUSTOM_BASE+2)
-#define V4L2_CID_MB_THRESHOLD0         (GO7007_CID_CUSTOM_BASE+3)
-#define V4L2_CID_PIXEL_THRESHOLD1      (GO7007_CID_CUSTOM_BASE+4)
-#define V4L2_CID_MOTION_THRESHOLD1     (GO7007_CID_CUSTOM_BASE+5)
-#define V4L2_CID_MB_THRESHOLD1         (GO7007_CID_CUSTOM_BASE+6)
-#define V4L2_CID_PIXEL_THRESHOLD2      (GO7007_CID_CUSTOM_BASE+7)
-#define V4L2_CID_MOTION_THRESHOLD2     (GO7007_CID_CUSTOM_BASE+8)
-#define V4L2_CID_MB_THRESHOLD2         (GO7007_CID_CUSTOM_BASE+9)
-#define V4L2_CID_PIXEL_THRESHOLD3      (GO7007_CID_CUSTOM_BASE+10)
-#define V4L2_CID_MOTION_THRESHOLD3     (GO7007_CID_CUSTOM_BASE+11)
-#define V4L2_CID_MB_THRESHOLD3         (GO7007_CID_CUSTOM_BASE+12)
-
-struct go7007_board_info {
-       unsigned int flags;
-       int hpi_buffer_cap;
-       unsigned int sensor_flags;
-       int sensor_width;
-       int sensor_height;
-       int sensor_framerate;
-       int sensor_h_offset;
-       int sensor_v_offset;
-       unsigned int audio_flags;
-       int audio_rate;
-       int audio_bclk_div;
-       int audio_main_div;
-       int num_i2c_devs;
-       struct go_i2c {
-               const char *type;
-               unsigned int is_video:1;
-               unsigned int is_audio:1;
-               int addr;
-               u32 flags;
-       } i2c_devs[5];
-       int num_inputs;
-       struct {
-               int video_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 {
-       int (*interface_reset)(struct go7007 *go);
-       int (*write_interrupt)(struct go7007 *go, int addr, int data);
-       int (*read_interrupt)(struct go7007 *go);
-       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);
-       void (*release)(struct go7007 *go);
-};
-
-/* The video buffer size must be a multiple of PAGE_SIZE */
-#define        GO7007_BUF_PAGES        (128 * 1024 / PAGE_SIZE)
-#define        GO7007_BUF_SIZE         (GO7007_BUF_PAGES << PAGE_SHIFT)
-
-struct go7007_buffer {
-       struct vb2_buffer vb;
-       struct list_head list;
-       unsigned int frame_offset;
-       u32 modet_active;
-};
-
-#define GO7007_RATIO_1_1       0
-#define GO7007_RATIO_4_3       1
-#define GO7007_RATIO_16_9      2
-
-enum go7007_parser_state {
-       STATE_DATA,
-       STATE_00,
-       STATE_00_00,
-       STATE_00_00_01,
-       STATE_FF,
-       STATE_VBI_LEN_A,
-       STATE_VBI_LEN_B,
-       STATE_MODET_MAP,
-       STATE_UNPARSED,
-};
-
-struct go7007 {
-       struct device *dev;
-       u8 bus_info[32];
-       const struct go7007_board_info *board_info;
-       unsigned int board_id;
-       int tuner_type;
-       int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
-       char name[64];
-       struct video_device vdev;
-       void *boot_fw;
-       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;
-       struct v4l2_ctrl *mpeg_video_b_frames;
-       struct v4l2_ctrl *mpeg_video_rep_seqheader;
-       struct v4l2_ctrl *modet_mode;
-       enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
-       spinlock_t spinlock;
-       struct mutex hw_lock;
-       struct mutex serialize_lock;
-       int audio_enabled;
-       struct v4l2_subdev *sd_video;
-       struct v4l2_subdev *sd_audio;
-       u8 usb_buf[16];
-
-       /* Video input */
-       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;
-       int encoder_h_offset;
-       int encoder_v_offset;
-       unsigned int encoder_h_halve:1;
-       unsigned int encoder_v_halve:1;
-       unsigned int encoder_subsample:1;
-
-       /* Encoder config */
-       u32 format;
-       int bitrate;
-       int fps_scale;
-       int pali;
-       int aspect_ratio;
-       int gop_size;
-       unsigned int ipb:1;
-       unsigned int closed_gop:1;
-       unsigned int repeat_seqhead:1;
-       unsigned int seq_header_enable:1;
-       unsigned int gop_header_enable:1;
-       unsigned int dvd_mode:1;
-       unsigned int interlace_coding:1;
-
-       /* Motion detection */
-       unsigned int modet_enable:1;
-       struct {
-               unsigned int enable:1;
-               int pixel_threshold;
-               int motion_threshold;
-               int mb_threshold;
-       } modet[4];
-       unsigned char modet_map[1624];
-       unsigned char active_map[216];
-       u32 modet_event_status;
-
-       /* Video streaming */
-       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 vidq_active;
-       wait_queue_head_t frame_waitq;
-       struct go7007_buffer *active_buf;
-
-       /* Audio streaming */
-       void (*audio_deliver)(struct go7007 *go, u8 *buf, int length);
-       void *snd_context;
-
-       /* I2C */
-       int i2c_adapter_online;
-       struct i2c_adapter i2c_adapter;
-
-       /* HPI driver */
-       struct go7007_hpi_ops *hpi_ops;
-       void *hpi_context;
-       int interrupt_available;
-       wait_queue_head_t interrupt_waitq;
-       unsigned short interrupt_value;
-       unsigned short interrupt_data;
-};
-
-static inline struct go7007 *to_go7007(struct v4l2_device *v4l2_dev)
-{
-       return container_of(v4l2_dev, struct go7007, v4l2_dev);
-}
-
-/* All of these must be called with the hpi_lock mutex held! */
-#define go7007_interface_reset(go) \
-                       ((go)->hpi_ops->interface_reset(go))
-#define        go7007_write_interrupt(go, x, y) \
-                       ((go)->hpi_ops->write_interrupt)((go), (x), (y))
-#define go7007_stream_start(go) \
-                       ((go)->hpi_ops->stream_start(go))
-#define go7007_stream_stop(go) \
-                       ((go)->hpi_ops->stream_stop(go))
-#define        go7007_send_firmware(go, x, y) \
-                       ((go)->hpi_ops->send_firmware)((go), (x), (y))
-#define go7007_write_addr(go, x, y) \
-                       ((go)->hpi_ops->write_interrupt)((go), (x)|0x8000, (y))
-
-/* go7007-driver.c */
-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, 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(const 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);
-
-/* go7007-i2c.c */
-int go7007_i2c_init(struct go7007 *go);
-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 */
-int go7007_snd_init(struct go7007 *go);
-int go7007_snd_remove(struct go7007 *go);
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
deleted file mode 100644 (file)
index ece27ec..0000000
+++ /dev/null
@@ -1,1345 +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.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <asm/byteorder.h>
-#include <media/saa7115.h>
-#include <media/tuner.h>
-#include <media/uda1342.h>
-
-#include "go7007-priv.h"
-
-static unsigned int assume_endura;
-module_param(assume_endura, int, 0644);
-MODULE_PARM_DESC(assume_endura,
-                       "when probing fails, hardware is a Pelco Endura");
-
-/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
-
-#define        HPI_STATUS_ADDR 0xFFF4
-#define        INT_PARAM_ADDR  0xFFF6
-#define        INT_INDEX_ADDR  0xFFF8
-
-/*
- * Pipes on EZ-USB interface:
- *     0 snd - Control
- *     0 rcv - Control
- *     2 snd - Download firmware (control)
- *     4 rcv - Read Interrupt (interrupt)
- *     6 rcv - Read Video (bulk)
- *     8 rcv - Read Audio (bulk)
- */
-
-#define GO7007_USB_EZUSB               (1<<0)
-#define GO7007_USB_EZUSB_I2C           (1<<1)
-
-struct go7007_usb_board {
-       unsigned int flags;
-       struct go7007_board_info main_info;
-};
-
-struct go7007_usb {
-       const struct go7007_usb_board *board;
-       struct mutex i2c_lock;
-       struct usb_device *usbdev;
-       struct urb *video_urbs[8];
-       struct urb *audio_urbs[8];
-       struct urb *intr_urb;
-};
-
-/*********************** Product specification data ***********************/
-
-static const struct go7007_usb_board board_matrix_ii = {
-       .flags          = GO7007_USB_EZUSB,
-       .main_info      = {
-               .flags           = GO7007_BOARD_HAS_AUDIO |
-                                       GO7007_BOARD_USE_ONBOARD_I2C,
-               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
-                                       GO7007_AUDIO_WORD_16,
-               .audio_rate      = 48000,
-               .audio_bclk_div  = 8,
-               .audio_main_div  = 2,
-               .hpi_buffer_cap  = 7,
-               .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,
-               .i2c_devs        = {
-                       {
-                               .type   = "saa7115",
-                               .addr   = 0x20,
-                               .is_video = 1,
-                       },
-               },
-               .num_inputs      = 2,
-               .inputs          = {
-                       {
-                               .video_input    = 0,
-                               .name           = "Composite",
-                       },
-                       {
-                               .video_input    = 9,
-                               .name           = "S-Video",
-                       },
-               },
-               .video_config   = SAA7115_IDQ_IS_DEFAULT,
-       },
-};
-
-static const struct go7007_usb_board board_matrix_reload = {
-       .flags          = GO7007_USB_EZUSB,
-       .main_info      = {
-               .flags           = GO7007_BOARD_HAS_AUDIO |
-                                       GO7007_BOARD_USE_ONBOARD_I2C,
-               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
-                                       GO7007_AUDIO_I2S_MASTER |
-                                       GO7007_AUDIO_WORD_16,
-               .audio_rate      = 48000,
-               .audio_bclk_div  = 8,
-               .audio_main_div  = 2,
-               .hpi_buffer_cap  = 7,
-               .sensor_flags    = GO7007_SENSOR_656 |
-                                       GO7007_SENSOR_TV,
-               .num_i2c_devs    = 1,
-               .i2c_devs        = {
-                       {
-                               .type   = "saa7113",
-                               .addr   = 0x25,
-                               .is_video = 1,
-                       },
-               },
-               .num_inputs      = 2,
-               .inputs          = {
-                       {
-                               .video_input    = 0,
-                               .name           = "Composite",
-                       },
-                       {
-                               .video_input    = 9,
-                               .name           = "S-Video",
-                       },
-               },
-               .video_config   = SAA7115_IDQ_IS_DEFAULT,
-       },
-};
-
-static const struct go7007_usb_board board_star_trek = {
-       .flags          = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
-       .main_info      = {
-               .flags           = GO7007_BOARD_HAS_AUDIO, /* |
-                                       GO7007_BOARD_HAS_TUNER, */
-               .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 |
-                                       GO7007_AUDIO_WORD_16,
-               .audio_bclk_div  = 8,
-               .audio_main_div  = 2,
-               .hpi_buffer_cap  = 7,
-               .num_i2c_devs    = 1,
-               .i2c_devs        = {
-                       {
-                               .type   = "saa7115",
-                               .addr   = 0x20,
-                               .is_video = 1,
-                       },
-               },
-               .num_inputs      = 2,
-               .inputs          = {
-               /*      {
-                *              .video_input    = 3,
-                *              .audio_index    = AUDIO_TUNER,
-                *              .name           = "Tuner",
-                *      },
-                */
-                       {
-                               .video_input    = 1,
-                       /*      .audio_index    = AUDIO_EXTERN, */
-                               .name           = "Composite",
-                       },
-                       {
-                               .video_input    = 8,
-                       /*      .audio_index    = AUDIO_EXTERN, */
-                               .name           = "S-Video",
-                       },
-               },
-               .video_config   = SAA7115_IDQ_IS_DEFAULT,
-       },
-};
-
-static const struct go7007_usb_board board_px_tv402u = {
-       .flags          = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
-       .main_info      = {
-               .flags           = GO7007_BOARD_HAS_AUDIO |
-                                       GO7007_BOARD_HAS_TUNER,
-               .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 |
-                                       GO7007_AUDIO_WORD_16,
-               .audio_bclk_div  = 8,
-               .audio_main_div  = 2,
-               .hpi_buffer_cap  = 7,
-               .num_i2c_devs    = 5,
-               .i2c_devs        = {
-                       {
-                               .type   = "saa7115",
-                               .addr   = 0x20,
-                               .is_video = 1,
-                       },
-                       {
-                               .type   = "uda1342",
-                               .addr   = 0x1a,
-                               .is_audio = 1,
-                       },
-                       {
-                               .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_index    = 1,
-                               .name           = "Composite",
-                       },
-                       {
-                               .video_input    = 8,
-                               .audio_index    = 1,
-                               .name           = "S-Video",
-                       },
-               },
-               .video_config   = SAA7115_IDQ_IS_DEFAULT,
-               .num_aud_inputs  = 2,
-               .aud_inputs      = {
-                       {
-                               .audio_input    = UDA1342_IN2,
-                               .name           = "Tuner",
-                       },
-                       {
-                               .audio_input    = UDA1342_IN1,
-                               .name           = "Line In",
-                       },
-               },
-       },
-};
-
-static const struct go7007_usb_board board_xmen = {
-       .flags          = 0,
-       .main_info      = {
-               .flags            = GO7007_BOARD_USE_ONBOARD_I2C,
-               .hpi_buffer_cap   = 0,
-               .sensor_flags     = GO7007_SENSOR_VREF_POLAR,
-               .sensor_width     = 320,
-               .sensor_height    = 240,
-               .sensor_framerate = 30030,
-               .audio_flags      = GO7007_AUDIO_ONE_CHANNEL |
-                                       GO7007_AUDIO_I2S_MODE_3 |
-                                       GO7007_AUDIO_WORD_14 |
-                                       GO7007_AUDIO_I2S_MASTER |
-                                       GO7007_AUDIO_BCLK_POLAR |
-                                       GO7007_AUDIO_OKI_MODE,
-               .audio_rate       = 8000,
-               .audio_bclk_div   = 48,
-               .audio_main_div   = 1,
-               .num_i2c_devs     = 1,
-               .i2c_devs         = {
-                       {
-                               .type   = "ov7640",
-                               .addr   = 0x21,
-                       },
-               },
-               .num_inputs       = 1,
-               .inputs           = {
-                       {
-                               .name           = "Camera",
-                       },
-               },
-       },
-};
-
-static const struct go7007_usb_board board_matrix_revolution = {
-       .flags          = GO7007_USB_EZUSB,
-       .main_info      = {
-               .flags           = GO7007_BOARD_HAS_AUDIO |
-                                       GO7007_BOARD_USE_ONBOARD_I2C,
-               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
-                                       GO7007_AUDIO_I2S_MASTER |
-                                       GO7007_AUDIO_WORD_16,
-               .audio_rate      = 48000,
-               .audio_bclk_div  = 8,
-               .audio_main_div  = 2,
-               .hpi_buffer_cap  = 7,
-               .sensor_flags    = GO7007_SENSOR_656 |
-                                       GO7007_SENSOR_TV |
-                                       GO7007_SENSOR_VBI,
-               .num_i2c_devs    = 1,
-               .i2c_devs        = {
-                       {
-                               .type   = "tw9903",
-                               .is_video = 1,
-                               .addr   = 0x44,
-                       },
-               },
-               .num_inputs      = 2,
-               .inputs          = {
-                       {
-                               .video_input    = 2,
-                               .name           = "Composite",
-                       },
-                       {
-                               .video_input    = 8,
-                               .name           = "S-Video",
-                       },
-               },
-       },
-};
-
-static const struct go7007_usb_board board_lifeview_lr192 = {
-       .flags          = GO7007_USB_EZUSB,
-       .main_info      = {
-               .flags           = GO7007_BOARD_HAS_AUDIO |
-                                       GO7007_BOARD_USE_ONBOARD_I2C,
-               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
-                                       GO7007_AUDIO_WORD_16,
-               .audio_rate      = 48000,
-               .audio_bclk_div  = 8,
-               .audio_main_div  = 2,
-               .hpi_buffer_cap  = 7,
-               .sensor_flags    = GO7007_SENSOR_656 |
-                                       GO7007_SENSOR_VALID_ENABLE |
-                                       GO7007_SENSOR_TV |
-                                       GO7007_SENSOR_VBI |
-                                       GO7007_SENSOR_SCALING,
-               .num_i2c_devs    = 0,
-               .num_inputs      = 1,
-               .inputs          = {
-                       {
-                               .video_input    = 0,
-                               .name           = "Composite",
-                       },
-               },
-       },
-};
-
-static const struct go7007_usb_board board_endura = {
-       .flags          = 0,
-       .main_info      = {
-               .flags           = 0,
-               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
-                                       GO7007_AUDIO_I2S_MASTER |
-                                       GO7007_AUDIO_WORD_16,
-               .audio_rate      = 8000,
-               .audio_bclk_div  = 48,
-               .audio_main_div  = 8,
-               .hpi_buffer_cap  = 0,
-               .sensor_flags    = GO7007_SENSOR_656 |
-                                       GO7007_SENSOR_TV,
-               .sensor_h_offset = 8,
-               .num_i2c_devs    = 0,
-               .num_inputs      = 1,
-               .inputs          = {
-                       {
-                               .name           = "Camera",
-                       },
-               },
-       },
-};
-
-static const struct go7007_usb_board board_adlink_mpg24 = {
-       .flags          = 0,
-       .main_info      = {
-               .flags           = GO7007_BOARD_USE_ONBOARD_I2C,
-               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
-                                       GO7007_AUDIO_I2S_MASTER |
-                                       GO7007_AUDIO_WORD_16,
-               .audio_rate      = 48000,
-               .audio_bclk_div  = 8,
-               .audio_main_div  = 2,
-               .hpi_buffer_cap  = 0,
-               .sensor_flags    = GO7007_SENSOR_656 |
-                                       GO7007_SENSOR_TV |
-                                       GO7007_SENSOR_VBI,
-               .num_i2c_devs    = 1,
-               .i2c_devs        = {
-                       {
-                               .type   = "tw2804",
-                               .addr   = 0x00, /* yes, really */
-                               .flags  = I2C_CLIENT_TEN,
-                               .is_video = 1,
-                       },
-               },
-               .num_inputs      = 1,
-               .inputs          = {
-                       {
-                               .name           = "Composite",
-                       },
-               },
-       },
-};
-
-static const struct go7007_usb_board board_sensoray_2250 = {
-       .flags          = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
-       .main_info      = {
-               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
-                                       GO7007_AUDIO_I2S_MASTER |
-                                       GO7007_AUDIO_WORD_16,
-               .flags           = GO7007_BOARD_HAS_AUDIO,
-               .audio_rate      = 48000,
-               .audio_bclk_div  = 8,
-               .audio_main_div  = 2,
-               .hpi_buffer_cap  = 7,
-               .sensor_flags    = GO7007_SENSOR_656 |
-                                       GO7007_SENSOR_TV,
-               .num_i2c_devs    = 1,
-               .i2c_devs        = {
-                       {
-                               .type   = "s2250",
-                               .addr   = 0x43,
-                               .is_video = 1,
-                               .is_audio = 1,
-                       },
-               },
-               .num_inputs      = 2,
-               .inputs          = {
-                       {
-                               .video_input    = 0,
-                               .name           = "Composite",
-                       },
-                       {
-                               .video_input    = 1,
-                               .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",
-                       },
-               },
-       },
-};
-
-static const struct go7007_usb_board board_ads_usbav_709 = {
-       .flags          = GO7007_USB_EZUSB,
-       .main_info      = {
-               .flags           = GO7007_BOARD_HAS_AUDIO |
-                                       GO7007_BOARD_USE_ONBOARD_I2C,
-               .audio_flags     = GO7007_AUDIO_I2S_MODE_1 |
-                                       GO7007_AUDIO_I2S_MASTER |
-                                       GO7007_AUDIO_WORD_16,
-               .audio_rate      = 48000,
-               .audio_bclk_div  = 8,
-               .audio_main_div  = 2,
-               .hpi_buffer_cap  = 7,
-               .sensor_flags    = GO7007_SENSOR_656 |
-                                       GO7007_SENSOR_TV |
-                                       GO7007_SENSOR_VBI,
-               .num_i2c_devs    = 1,
-               .i2c_devs        = {
-                       {
-                               .type   = "tw9906",
-                               .is_video = 1,
-                               .addr   = 0x44,
-                       },
-               },
-               .num_inputs      = 2,
-               .inputs          = {
-                       {
-                               .video_input    = 0,
-                               .name           = "Composite",
-                       },
-                       {
-                               .video_input    = 10,
-                               .name           = "S-Video",
-                       },
-               },
-       },
-};
-
-static const struct usb_device_id go7007_usb_id_table[] = {
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
-                                       USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
-               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
-               .bcdDevice_lo   = 0x200,   /* Revision number of XMen */
-               .bcdDevice_hi   = 0x200,
-               .bInterfaceClass        = 255,
-               .bInterfaceSubClass     = 0,
-               .bInterfaceProtocol     = 255,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
-               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
-               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
-               .bcdDevice_lo   = 0x202,   /* Revision number of Matrix II */
-               .bcdDevice_hi   = 0x202,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_MATRIX_II,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
-               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
-               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
-               .bcdDevice_lo   = 0x204,   /* Revision number of Matrix */
-               .bcdDevice_hi   = 0x204,   /*     Reloaded */
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_MATRIX_RELOAD,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
-                                       USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
-               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
-               .bcdDevice_lo   = 0x205,   /* Revision number of XMen-II */
-               .bcdDevice_hi   = 0x205,
-               .bInterfaceClass        = 255,
-               .bInterfaceSubClass     = 0,
-               .bInterfaceProtocol     = 255,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN_II,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
-               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
-               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
-               .bcdDevice_lo   = 0x208,   /* Revision number of Star Trek */
-               .bcdDevice_hi   = 0x208,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_STAR_TREK,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
-                                       USB_DEVICE_ID_MATCH_INT_INFO,
-               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
-               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
-               .bcdDevice_lo   = 0x209,   /* Revision number of XMen-III */
-               .bcdDevice_hi   = 0x209,
-               .bInterfaceClass        = 255,
-               .bInterfaceSubClass     = 0,
-               .bInterfaceProtocol     = 255,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_XMEN_III,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
-               .idVendor       = 0x0eb1,  /* Vendor ID of WIS Technologies */
-               .idProduct      = 0x7007,  /* Product ID of GO7007SB chip */
-               .bcdDevice_lo   = 0x210,   /* Revision number of Matrix */
-               .bcdDevice_hi   = 0x210,   /*     Revolution */
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_MATRIX_REV,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
-               .idVendor       = 0x093b,  /* Vendor ID of Plextor */
-               .idProduct      = 0xa102,  /* Product ID of M402U */
-               .bcdDevice_lo   = 0x1,     /* revision number of Blueberry */
-               .bcdDevice_hi   = 0x1,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_PX_M402U,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
-               .idVendor       = 0x093b,  /* Vendor ID of Plextor */
-               .idProduct      = 0xa104,  /* Product ID of TV402U */
-               .bcdDevice_lo   = 0x1,
-               .bcdDevice_hi   = 0x1,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_PX_TV402U,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
-               .idVendor       = 0x10fd,  /* Vendor ID of Anubis Electronics */
-               .idProduct      = 0xde00,  /* Product ID of Lifeview LR192 */
-               .bcdDevice_lo   = 0x1,
-               .bcdDevice_hi   = 0x1,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
-               .idVendor       = 0x1943,  /* Vendor ID Sensoray */
-               .idProduct      = 0x2250,  /* Product ID of 2250/2251 */
-               .bcdDevice_lo   = 0x1,
-               .bcdDevice_hi   = 0x1,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_SENSORAY_2250,
-       },
-       {
-               .match_flags    = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
-               .idVendor       = 0x06e1,  /* Vendor ID of ADS Technologies */
-               .idProduct      = 0x0709,  /* Product ID of DVD Xpress DX2 */
-               .bcdDevice_lo   = 0x204,
-               .bcdDevice_hi   = 0x204,
-               .driver_info    = (kernel_ulong_t)GO7007_BOARDID_ADS_USBAV_709,
-       },
-       { }                                     /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, go7007_usb_id_table);
-
-/********************* Driver for EZ-USB HPI interface *********************/
-
-static int go7007_usb_vendor_request(struct go7007 *go, int request,
-               int value, int index, void *transfer_buffer, int length, int in)
-{
-       struct go7007_usb *usb = go->hpi_context;
-       int timeout = 5000;
-
-       if (in) {
-               return usb_control_msg(usb->usbdev,
-                               usb_rcvctrlpipe(usb->usbdev, 0), request,
-                               USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                               value, index, transfer_buffer, length, timeout);
-       } else {
-               return usb_control_msg(usb->usbdev,
-                               usb_sndctrlpipe(usb->usbdev, 0), request,
-                               USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                               value, index, transfer_buffer, length, timeout);
-       }
-}
-
-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;
-       msleep(100);
-
-       if (usb->board->flags & GO7007_USB_EZUSB) {
-               /* Reset buffer in EZ-USB */
-               pr_debug("resetting EZ-USB buffers\n");
-               if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
-                   go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
-                       return -1;
-
-               /* Reset encoder again */
-               if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
-                       return -1;
-               msleep(100);
-       }
-
-       /* Wait for an interrupt to indicate successful hardware reset */
-       if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
-                       (intr_val & ~0x1) != 0x55aa) {
-               dev_err(go->dev, "unable to reset the USB interface\n");
-               return -1;
-       }
-       return 0;
-}
-
-static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
-                                               int addr, int data)
-{
-       struct go7007_usb *usb = go->hpi_context;
-       int i, r;
-       u16 status_reg = 0;
-       int timeout = 500;
-
-       pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
-
-       for (i = 0; i < 100; ++i) {
-               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, go->usb_buf,
-                               sizeof(status_reg), timeout);
-               if (r < 0)
-                       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) {
-               dev_err(go->dev, "device is hung, status reg = 0x%04x\n", status_reg);
-               return -1;
-       }
-       r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
-                       USB_TYPE_VENDOR | USB_RECIP_DEVICE, data,
-                       INT_PARAM_ADDR, NULL, 0, timeout);
-       if (r < 0)
-               goto write_int_error;
-       r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0),
-                       0x12, USB_TYPE_VENDOR | USB_RECIP_DEVICE, addr,
-                       INT_INDEX_ADDR, NULL, 0, timeout);
-       if (r < 0)
-               goto write_int_error;
-       return 0;
-
-write_int_error:
-       dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
-       return r;
-}
-
-static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
-                                               int addr, int data)
-{
-       struct go7007_usb *usb = go->hpi_context;
-       int r;
-       int timeout = 500;
-
-       pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
-
-       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, go->usb_buf, 8, timeout);
-       if (r < 0) {
-               dev_err(go->dev, "error in WriteInterrupt: %d\n", r);
-               return r;
-       }
-       return 0;
-}
-
-static void go7007_usb_readinterrupt_complete(struct urb *urb)
-{
-       struct go7007 *go = (struct go7007 *)urb->context;
-       u16 *regs = (u16 *)urb->transfer_buffer;
-       int status = urb->status;
-
-       if (status) {
-               if (status != -ESHUTDOWN &&
-                               go->status != STATUS_SHUTDOWN) {
-                       dev_err(go->dev, "error in read interrupt: %d\n", urb->status);
-               } else {
-                       wake_up(&go->interrupt_waitq);
-                       return;
-               }
-       } else if (urb->actual_length != urb->transfer_buffer_length) {
-               dev_err(go->dev, "short read in interrupt pipe!\n");
-       } else {
-               go->interrupt_available = 1;
-               go->interrupt_data = __le16_to_cpu(regs[0]);
-               go->interrupt_value = __le16_to_cpu(regs[1]);
-               pr_debug("ReadInterrupt: %04x %04x\n",
-                               go->interrupt_value, go->interrupt_data);
-       }
-
-       wake_up(&go->interrupt_waitq);
-}
-
-static int go7007_usb_read_interrupt(struct go7007 *go)
-{
-       struct go7007_usb *usb = go->hpi_context;
-       int r;
-
-       r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
-       if (r < 0) {
-               dev_err(go->dev, "unable to submit interrupt urb: %d\n", r);
-               return r;
-       }
-       return 0;
-}
-
-static void go7007_usb_read_video_pipe_complete(struct urb *urb)
-{
-       struct go7007 *go = (struct go7007 *)urb->context;
-       int r, status = urb->status;
-
-       if (!vb2_is_streaming(&go->vidq)) {
-               wake_up_interruptible(&go->frame_waitq);
-               return;
-       }
-       if (status) {
-               dev_err(go->dev, "error in video pipe: %d\n", status);
-               return;
-       }
-       if (urb->actual_length != urb->transfer_buffer_length) {
-               dev_err(go->dev, "short read in video pipe!\n");
-               return;
-       }
-       go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
-       r = usb_submit_urb(urb, GFP_ATOMIC);
-       if (r < 0)
-               dev_err(go->dev, "error in video pipe: %d\n", r);
-}
-
-static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
-{
-       struct go7007 *go = (struct go7007 *)urb->context;
-       int r, status = urb->status;
-
-       if (!vb2_is_streaming(&go->vidq))
-               return;
-       if (status) {
-               dev_err(go->dev, "error in audio pipe: %d\n",
-                       status);
-               return;
-       }
-       if (urb->actual_length != urb->transfer_buffer_length) {
-               dev_err(go->dev, "short read in audio pipe!\n");
-               return;
-       }
-       if (go->audio_deliver != NULL)
-               go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
-       r = usb_submit_urb(urb, GFP_ATOMIC);
-       if (r < 0)
-               dev_err(go->dev, "error in audio pipe: %d\n", r);
-}
-
-static int go7007_usb_stream_start(struct go7007 *go)
-{
-       struct go7007_usb *usb = go->hpi_context;
-       int i, r;
-
-       for (i = 0; i < 8; ++i) {
-               r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
-               if (r < 0) {
-                       dev_err(go->dev, "error submitting video urb %d: %d\n", i, r);
-                       goto video_submit_failed;
-               }
-       }
-       if (!go->audio_enabled)
-               return 0;
-
-       for (i = 0; i < 8; ++i) {
-               r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
-               if (r < 0) {
-                       dev_err(go->dev, "error submitting audio urb %d: %d\n", i, r);
-                       goto audio_submit_failed;
-               }
-       }
-       return 0;
-
-audio_submit_failed:
-       for (i = 0; i < 7; ++i)
-               usb_kill_urb(usb->audio_urbs[i]);
-video_submit_failed:
-       for (i = 0; i < 8; ++i)
-               usb_kill_urb(usb->video_urbs[i]);
-       return -1;
-}
-
-static int go7007_usb_stream_stop(struct go7007 *go)
-{
-       struct go7007_usb *usb = go->hpi_context;
-       int i;
-
-       if (go->status == STATUS_SHUTDOWN)
-               return 0;
-       for (i = 0; i < 8; ++i)
-               usb_kill_urb(usb->video_urbs[i]);
-       if (go->audio_enabled)
-               for (i = 0; i < 8; ++i)
-                       usb_kill_urb(usb->audio_urbs[i]);
-       return 0;
-}
-
-static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
-{
-       struct go7007_usb *usb = go->hpi_context;
-       int transferred, pipe;
-       int timeout = 500;
-
-       pr_debug("DownloadBuffer sending %d bytes\n", len);
-
-       if (usb->board->flags & GO7007_USB_EZUSB)
-               pipe = usb_sndbulkpipe(usb->usbdev, 2);
-       else
-               pipe = usb_sndbulkpipe(usb->usbdev, 3);
-
-       return usb_bulk_msg(usb->usbdev, pipe, data, len,
-                                       &transferred, timeout);
-}
-
-static void go7007_usb_release(struct go7007 *go)
-{
-       struct go7007_usb *usb = go->hpi_context;
-       struct urb *vurb, *aurb;
-       int i;
-
-       if (usb->intr_urb) {
-               usb_kill_urb(usb->intr_urb);
-               kfree(usb->intr_urb->transfer_buffer);
-               usb_free_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(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,
-       .read_interrupt         = go7007_usb_read_interrupt,
-       .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 = {
-       .interface_reset        = go7007_usb_interface_reset,
-       .write_interrupt        = go7007_usb_onboard_write_interrupt,
-       .read_interrupt         = go7007_usb_read_interrupt,
-       .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 *********************/
-
-static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
-                                       struct i2c_msg msgs[], int num)
-{
-       struct go7007 *go = i2c_get_adapdata(adapter);
-       struct go7007_usb *usb = go->hpi_context;
-       u8 *buf = go->usb_buf;
-       int buf_len, i;
-       int ret = -EIO;
-
-       if (go->status == STATUS_SHUTDOWN)
-               return -ENODEV;
-
-       mutex_lock(&usb->i2c_lock);
-
-       for (i = 0; i < num; ++i) {
-               /* The hardware command is "write some bytes then read some
-                * bytes", so we try to coalesce a write followed by a read
-                * into a single USB transaction */
-               if (i + 1 < num && msgs[i].addr == msgs[i + 1].addr &&
-                               !(msgs[i].flags & I2C_M_RD) &&
-                               (msgs[i + 1].flags & I2C_M_RD)) {
-#ifdef GO7007_I2C_DEBUG
-                       pr_debug("i2c write/read %d/%d bytes on %02x\n",
-                               msgs[i].len, msgs[i + 1].len, msgs[i].addr);
-#endif
-                       buf[0] = 0x01;
-                       buf[1] = msgs[i].len + 1;
-                       buf[2] = msgs[i].addr << 1;
-                       memcpy(&buf[3], msgs[i].buf, msgs[i].len);
-                       buf_len = msgs[i].len + 3;
-                       buf[buf_len++] = msgs[++i].len;
-               } else if (msgs[i].flags & I2C_M_RD) {
-#ifdef GO7007_I2C_DEBUG
-                       pr_debug("i2c read %d bytes on %02x\n",
-                                       msgs[i].len, msgs[i].addr);
-#endif
-                       buf[0] = 0x01;
-                       buf[1] = 1;
-                       buf[2] = msgs[i].addr << 1;
-                       buf[3] = msgs[i].len;
-                       buf_len = 4;
-               } else {
-#ifdef GO7007_I2C_DEBUG
-                       pr_debug("i2c write %d bytes on %02x\n",
-                                       msgs[i].len, msgs[i].addr);
-#endif
-                       buf[0] = 0x00;
-                       buf[1] = msgs[i].len + 1;
-                       buf[2] = msgs[i].addr << 1;
-                       memcpy(&buf[3], msgs[i].buf, msgs[i].len);
-                       buf_len = msgs[i].len + 3;
-                       buf[buf_len++] = 0;
-               }
-               if (go7007_usb_vendor_request(go, 0x24, 0, 0,
-                                               buf, buf_len, 0) < 0)
-                       goto i2c_done;
-               if (msgs[i].flags & I2C_M_RD) {
-                       memset(buf, 0, msgs[i].len + 1);
-                       if (go7007_usb_vendor_request(go, 0x25, 0, 0, buf,
-                                               msgs[i].len + 1, 1) < 0)
-                               goto i2c_done;
-                       memcpy(msgs[i].buf, buf + 1, msgs[i].len);
-               }
-       }
-       ret = num;
-
-i2c_done:
-       mutex_unlock(&usb->i2c_lock);
-       return ret;
-}
-
-static u32 go7007_usb_functionality(struct i2c_adapter *adapter)
-{
-       /* No errors are reported by the hardware, so we don't bother
-        * supporting quick writes to avoid confusing probing */
-       return (I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK;
-}
-
-static struct i2c_algorithm go7007_usb_algo = {
-       .master_xfer    = go7007_usb_i2c_master_xfer,
-       .functionality  = go7007_usb_functionality,
-};
-
-static struct i2c_adapter go7007_usb_adap_templ = {
-       .owner                  = THIS_MODULE,
-       .name                   = "WIS GO7007SB EZ-USB",
-       .algo                   = &go7007_usb_algo,
-};
-
-/********************* USB add/remove functions *********************/
-
-static int go7007_usb_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
-{
-       struct go7007 *go;
-       struct go7007_usb *usb;
-       const 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;
-
-       pr_debug("probing new GO7007 USB board\n");
-
-       switch (id->driver_info) {
-       case GO7007_BOARDID_MATRIX_II:
-               name = "WIS Matrix II or compatible";
-               board = &board_matrix_ii;
-               break;
-       case GO7007_BOARDID_MATRIX_RELOAD:
-               name = "WIS Matrix Reloaded or compatible";
-               board = &board_matrix_reload;
-               break;
-       case GO7007_BOARDID_MATRIX_REV:
-               name = "WIS Matrix Revolution or compatible";
-               board = &board_matrix_revolution;
-               break;
-       case GO7007_BOARDID_STAR_TREK:
-               name = "WIS Star Trek or compatible";
-               board = &board_star_trek;
-               break;
-       case GO7007_BOARDID_XMEN:
-               name = "WIS XMen or compatible";
-               board = &board_xmen;
-               break;
-       case GO7007_BOARDID_XMEN_II:
-               name = "WIS XMen II or compatible";
-               board = &board_xmen;
-               break;
-       case GO7007_BOARDID_XMEN_III:
-               name = "WIS XMen III or compatible";
-               board = &board_xmen;
-               break;
-       case GO7007_BOARDID_PX_M402U:
-               name = "Plextor PX-M402U";
-               board = &board_matrix_ii;
-               break;
-       case GO7007_BOARDID_PX_TV402U:
-               name = "Plextor PX-TV402U (unknown tuner)";
-               board = &board_px_tv402u;
-               break;
-       case GO7007_BOARDID_LIFEVIEW_LR192:
-               dev_err(&intf->dev, "The Lifeview TV Walker Ultra is not supported. Sorry!\n");
-               return -ENODEV;
-               name = "Lifeview TV Walker Ultra";
-               board = &board_lifeview_lr192;
-               break;
-       case GO7007_BOARDID_SENSORAY_2250:
-               dev_info(&intf->dev, "Sensoray 2250 found\n");
-               name = "Sensoray 2250/2251";
-               board = &board_sensoray_2250;
-               break;
-       case GO7007_BOARDID_ADS_USBAV_709:
-               name = "ADS Tech DVD Xpress DX2";
-               board = &board_ads_usbav_709;
-               break;
-       default:
-               dev_err(&intf->dev, "unknown board ID %d!\n",
-                               (unsigned int)id->driver_info);
-               return -ENODEV;
-       }
-
-       go = go7007_alloc(&board->main_info, &intf->dev);
-       if (go == NULL)
-               return -ENOMEM;
-
-       usb = kzalloc(sizeof(struct go7007_usb), GFP_KERNEL);
-       if (usb == NULL) {
-               kfree(go);
-               return -ENOMEM;
-       }
-
-       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)
-               go->hpi_ops = &go7007_usb_ezusb_hpi_ops;
-       else
-               go->hpi_ops = &go7007_usb_onboard_hpi_ops;
-       go->hpi_context = usb;
-
-       /* Allocate the URB and buffer for receiving incoming interrupts */
-       usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (usb->intr_urb == NULL)
-               goto allocfail;
-       usb->intr_urb->transfer_buffer = kmalloc(2*sizeof(u16), GFP_KERNEL);
-       if (usb->intr_urb->transfer_buffer == NULL)
-               goto allocfail;
-
-       if (go->board_id == GO7007_BOARDID_SENSORAY_2250)
-               usb_fill_bulk_urb(usb->intr_urb, usb->usbdev,
-                       usb_rcvbulkpipe(usb->usbdev, 4),
-                       usb->intr_urb->transfer_buffer, 2*sizeof(u16),
-                       go7007_usb_readinterrupt_complete, go);
-       else
-               usb_fill_int_urb(usb->intr_urb, usb->usbdev,
-                       usb_rcvintpipe(usb->usbdev, 4),
-                       usb->intr_urb->transfer_buffer, 2*sizeof(u16),
-                       go7007_usb_readinterrupt_complete, go, 8);
-       usb_set_intfdata(intf, &go->v4l2_dev);
-
-       /* Boot the GO7007 */
-       if (go7007_boot_encoder(go, go->board_info->flags &
-                                       GO7007_BOARD_USE_ONBOARD_I2C) < 0)
-               goto allocfail;
-
-       /* Register the EZ-USB I2C adapter, if we're using it */
-       if (board->flags & GO7007_USB_EZUSB_I2C) {
-               memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
-                               sizeof(go7007_usb_adap_templ));
-               mutex_init(&usb->i2c_lock);
-               go->i2c_adapter.dev.parent = go->dev;
-               i2c_set_adapdata(&go->i2c_adapter, go);
-               if (i2c_add_adapter(&go->i2c_adapter) < 0) {
-                       dev_err(go->dev, "error: i2c_add_adapter failed\n");
-                       goto allocfail;
-               }
-               go->i2c_adapter_online = 1;
-       }
-
-       /* Pelco and Adlink reused the XMen and XMen-III vendor and product
-        * IDs for their own incompatible designs.  We can detect XMen boards
-        * by probing the sensor, but there is no way to probe the sensors on
-        * the Pelco and Adlink designs so we default to the Adlink.  If it
-        * is actually a Pelco, the user must set the assume_endura module
-        * parameter. */
-       if ((go->board_id == GO7007_BOARDID_XMEN ||
-                               go->board_id == GO7007_BOARDID_XMEN_III) &&
-                       go->i2c_adapter_online) {
-               union i2c_smbus_data data;
-
-               /* Check to see if register 0x0A is 0x76 */
-               i2c_smbus_xfer(&go->i2c_adapter, 0x21, I2C_CLIENT_SCCB,
-                       I2C_SMBUS_READ, 0x0A, I2C_SMBUS_BYTE_DATA, &data);
-               if (data.byte != 0x76) {
-                       if (assume_endura) {
-                               go->board_id = GO7007_BOARDID_ENDURA;
-                               usb->board = board = &board_endura;
-                               go->board_info = &board->main_info;
-                               strncpy(go->name, "Pelco Endura",
-                                       sizeof(go->name));
-                       } else {
-                               u16 channel;
-
-                               /* read channel number from GPIO[1:0] */
-                               go7007_read_addr(go, 0x3c81, &channel);
-                               channel &= 0x3;
-                               go->board_id = GO7007_BOARDID_ADLINK_MPG24;
-                               usb->board = board = &board_adlink_mpg24;
-                               go->board_info = &board->main_info;
-                               go->channel_number = channel;
-                               snprintf(go->name, sizeof(go->name),
-                                       "Adlink PCI-MPG24, channel #%d",
-                                       channel);
-                       }
-                       go7007_update_board(go);
-               }
-       }
-
-       num_i2c_devs = go->board_info->num_i2c_devs;
-
-       /* Probe the tuner model on the TV402U */
-       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) {
-                       dev_err(go->dev, "GPIO read failed!\n");
-                       goto allocfail;
-               }
-               switch (go->usb_buf[0] >> 6) {
-               case 1:
-                       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->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));
-                       break;
-               case 3:
-                       go->tuner_type = TUNER_SONY_BTF_PB463Z;
-                       num_i2c_devs -= 2;
-                       strncpy(go->name, "Plextor PX-TV402U-NA",
-                                       sizeof(go->name));
-                       break;
-               default:
-                       pr_debug("unable to detect tuner type!\n");
-                       break;
-               }
-               /* Configure tuner mode selection inputs connected
-                * to the EZ-USB GPIO output pins */
-               if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
-                                       NULL, 0, 0) < 0) {
-                       dev_err(go->dev, "GPIO write failed!\n");
-                       goto allocfail;
-               }
-       }
-
-       /* Print a nasty message if the user attempts to use a USB2.0 device in
-        * a USB1.1 port.  There will be silent corruption of the stream. */
-       if ((board->flags & GO7007_USB_EZUSB) &&
-                       usbdev->speed != USB_SPEED_HIGH)
-               dev_err(go->dev, "*** WARNING ***  This device must be connected to a USB 2.0 port! Attempting to capture video through a USB 1.1 port will result in stream corruption, even at low bitrates!\n");
-
-       /* Allocate the URBs and buffers for receiving the video stream */
-       if (board->flags & GO7007_USB_EZUSB) {
-               v_urb_len = 1024;
-               video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
-       } else {
-               v_urb_len = 512;
-               video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
-       }
-       for (i = 0; i < 8; ++i) {
-               usb->video_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
-               if (usb->video_urbs[i] == NULL)
-                       goto allocfail;
-               usb->video_urbs[i]->transfer_buffer =
-                                               kmalloc(v_urb_len, GFP_KERNEL);
-               if (usb->video_urbs[i]->transfer_buffer == NULL)
-                       goto allocfail;
-               usb_fill_bulk_urb(usb->video_urbs[i], usb->usbdev, video_pipe,
-                               usb->video_urbs[i]->transfer_buffer, v_urb_len,
-                               go7007_usb_read_video_pipe_complete, go);
-       }
-
-       /* Allocate the URBs and buffers for receiving the audio stream */
-       if ((board->flags & GO7007_USB_EZUSB) &&
-           (board->flags & GO7007_BOARD_HAS_AUDIO)) {
-               for (i = 0; i < 8; ++i) {
-                       usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
-                       if (usb->audio_urbs[i] == NULL)
-                               goto allocfail;
-                       usb->audio_urbs[i]->transfer_buffer = kmalloc(4096,
-                                                               GFP_KERNEL);
-                       if (usb->audio_urbs[i]->transfer_buffer == NULL)
-                               goto allocfail;
-                       usb_fill_bulk_urb(usb->audio_urbs[i], usb->usbdev,
-                               usb_rcvbulkpipe(usb->usbdev, 8),
-                               usb->audio_urbs[i]->transfer_buffer, 4096,
-                               go7007_usb_read_audio_pipe_complete, go);
-               }
-       }
-
-       /* Do any final GO7007 initialization, then register the
-        * V4L2 and ALSA interfaces */
-       if (go7007_register_encoder(go, num_i2c_devs) < 0)
-               goto allocfail;
-
-       go->status = STATUS_ONLINE;
-       return 0;
-
-allocfail:
-       go7007_usb_release(go);
-       kfree(go);
-       return -ENOMEM;
-}
-
-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->vdev);
-       mutex_unlock(&go->serialize_lock);
-       mutex_unlock(&go->queue_lock);
-
-       v4l2_device_put(&go->v4l2_dev);
-}
-
-static struct usb_driver go7007_usb_driver = {
-       .name           = "go7007",
-       .probe          = go7007_usb_probe,
-       .disconnect     = go7007_usb_disconnect,
-       .id_table       = go7007_usb_id_table,
-};
-
-module_usb_driver(go7007_usb_driver);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
deleted file mode 100644 (file)
index ec799b4..0000000
+++ /dev/null
@@ -1,1173 +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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/unistd.h>
-#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 <media/v4l2-event.h>
-#include <media/videobuf2-vmalloc.h>
-#include <media/saa7115.h>
-
-#include "go7007-priv.h"
-
-#define call_all(dev, o, f, args...) \
-       v4l2_device_call_until_err(dev, 0, o, f, ##args)
-
-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 *vb, int format)
-{
-       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 ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
-               case 0:
-                       return V4L2_BUF_FLAG_KEYFRAME;
-               case 1:
-                       return V4L2_BUF_FLAG_PFRAME;
-               case 2:
-                       return V4L2_BUF_FLAG_BFRAME;
-               default:
-                       return 0;
-               }
-       case V4L2_PIX_FMT_MPEG1:
-       case V4L2_PIX_FMT_MPEG2:
-               switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
-               case 1:
-                       return V4L2_BUF_FLAG_KEYFRAME;
-               case 2:
-                       return V4L2_BUF_FLAG_PFRAME;
-               case 3:
-                       return V4L2_BUF_FLAG_BFRAME;
-               default:
-                       return 0;
-               }
-       }
-
-       return 0;
-}
-
-static void get_resolution(struct go7007 *go, int *width, int *height)
-{
-       switch (go->standard) {
-       case GO7007_STD_NTSC:
-               *width = 720;
-               *height = 480;
-               break;
-       case GO7007_STD_PAL:
-               *width = 720;
-               *height = 576;
-               break;
-       case GO7007_STD_OTHER:
-       default:
-               *width = go->board_info->sensor_width;
-               *height = go->board_info->sensor_height;
-               break;
-       }
-}
-
-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->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
-       go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
-       go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
-       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->ipb == 0 &&
-                       go->repeat_seqhead == 1 &&
-                       go->closed_gop;
-
-       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;
-
-       if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
-               return -EINVAL;
-
-       get_resolution(go, &sensor_width, &sensor_height);
-
-       if (fmt == NULL) {
-               width = sensor_width;
-               height = sensor_height;
-       } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
-               if (fmt->fmt.pix.width > sensor_width)
-                       width = sensor_width;
-               else if (fmt->fmt.pix.width < 144)
-                       width = 144;
-               else
-                       width = fmt->fmt.pix.width & ~0x0f;
-
-               if (fmt->fmt.pix.height > sensor_height)
-                       height = sensor_height;
-               else if (fmt->fmt.pix.height < 96)
-                       height = 96;
-               else
-                       height = fmt->fmt.pix.height & ~0x0f;
-       } else {
-               width = fmt->fmt.pix.width;
-
-               if (width <= sensor_width / 4) {
-                       width = sensor_width / 4;
-                       height = sensor_height / 4;
-               } else if (width <= sensor_width / 2) {
-                       width = sensor_width / 2;
-                       height = sensor_height / 2;
-               } else {
-                       width = sensor_width;
-                       height = sensor_height;
-               }
-               width &= ~0xf;
-               height &= ~0xf;
-       }
-
-       if (fmt != NULL) {
-               u32 pixelformat = fmt->fmt.pix.pixelformat;
-
-               memset(fmt, 0, sizeof(*fmt));
-               fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-               fmt->fmt.pix.width = width;
-               fmt->fmt.pix.height = height;
-               fmt->fmt.pix.pixelformat = pixelformat;
-               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;
-       }
-
-       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;
-       go->encoder_v_offset = go->board_info->sensor_v_offset;
-
-       if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
-               struct v4l2_mbus_framefmt mbus_fmt;
-
-               mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
-               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) {
-                       go->encoder_h_halve = 1;
-                       go->encoder_v_halve = 1;
-                       go->encoder_subsample = 1;
-               } else if (width <= sensor_width / 2) {
-                       go->encoder_h_halve = 1;
-                       go->encoder_v_halve = 1;
-                       go->encoder_subsample = 0;
-               } else {
-                       go->encoder_h_halve = 0;
-                       go->encoder_v_halve = 0;
-                       go->encoder_subsample = 0;
-               }
-       }
-       return 0;
-}
-
-static int vidioc_querycap(struct file *file, void  *priv,
-                                       struct v4l2_capability *cap)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       strlcpy(cap->driver, "go7007", sizeof(cap->driver));
-       strlcpy(cap->card, go->name, sizeof(cap->card));
-       strlcpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
-
-       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;
-       if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
-               cap->device_caps |= V4L2_CAP_TUNER;
-       cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-       return 0;
-}
-
-static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
-                                       struct v4l2_fmtdesc *fmt)
-{
-       char *desc = NULL;
-
-       switch (fmt->index) {
-       case 0:
-               fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
-               desc = "Motion JPEG";
-               break;
-       case 1:
-               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;
-       }
-       fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-       fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
-
-       strncpy(fmt->description, desc, sizeof(fmt->description));
-
-       return 0;
-}
-
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
-                                       struct v4l2_format *fmt)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       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;
-       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;
-
-       return 0;
-}
-
-static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
-                       struct v4l2_format *fmt)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       return set_capture_size(go, fmt, 1);
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
-                       struct v4l2_format *fmt)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       if (vb2_is_busy(&go->vidq))
-               return -EBUSY;
-
-       return set_capture_size(go, fmt, 0);
-}
-
-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[])
-{
-       sizes[0] = GO7007_BUF_SIZE;
-       *num_planes = 1;
-
-       if (*num_buffers < 2)
-               *num_buffers = 2;
-
-       return 0;
-}
-
-static void go7007_buf_queue(struct vb2_buffer *vb)
-{
-       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;
-
-       spin_lock_irqsave(&go->spinlock, flags);
-       list_add_tail(&go7007_vb->list, &go->vidq_active);
-       spin_unlock_irqrestore(&go->spinlock, flags);
-}
-
-static int go7007_buf_prepare(struct vb2_buffer *vb)
-{
-       struct go7007_buffer *go7007_vb =
-               container_of(vb, struct go7007_buffer, vb);
-
-       go7007_vb->modet_active = 0;
-       go7007_vb->frame_offset = 0;
-       vb->v4l2_planes[0].bytesused = 0;
-       return 0;
-}
-
-static void go7007_buf_finish(struct vb2_buffer *vb)
-{
-       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;
-}
-
-static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
-{
-       struct go7007 *go = vb2_get_drv_priv(q);
-       int ret;
-
-       set_formatting(go);
-       mutex_lock(&go->hw_lock);
-       go->next_seq = 0;
-       go->active_buf = NULL;
-       go->modet_event_status = 0;
-       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);
-       /* Turn on Capture LED */
-       if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
-               go7007_write_addr(go, 0x3c82, 0x0005);
-       return ret;
-}
-
-static void go7007_stop_streaming(struct vb2_queue *q)
-{
-       struct go7007 *go = vb2_get_drv_priv(q);
-       unsigned long flags;
-
-       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);
-       /* Turn on Capture LED */
-       if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
-               go7007_write_addr(go, 0x3c82, 0x000d);
-}
-
-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)
-{
-       struct go7007 *go = video_drvdata(filp);
-       struct v4l2_fract timeperframe = {
-               .numerator = 1001 *  go->fps_scale,
-               .denominator = go->sensor_framerate,
-       };
-
-       if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-               return -EINVAL;
-
-       parm->parm.capture.readbuffers = 2;
-       parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
-       parm->parm.capture.timeperframe = timeperframe;
-
-       return 0;
-}
-
-static int vidioc_s_parm(struct file *filp, void *priv,
-               struct v4l2_streamparm *parm)
-{
-       struct go7007 *go = video_drvdata(filp);
-       unsigned int n, d;
-
-       if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-               return -EINVAL;
-
-       n = go->sensor_framerate *
-               parm->parm.capture.timeperframe.numerator;
-       d = 1001 * parm->parm.capture.timeperframe.denominator;
-       if (n != 0 && d != 0 && n > d)
-               go->fps_scale = (n + d/2) / d;
-       else
-               go->fps_scale = 1;
-
-       return vidioc_g_parm(filp, priv, parm);
-}
-
-/* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
-   its resolution, when the device is not connected to TV.
-   This is were an API abuse, probably used by the lack of specific IOCTL's to
-   enumerate it, by the time the driver was written.
-
-   However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
-   and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
-
-   The two functions below implement the newer ioctls
-*/
-static int vidioc_enum_framesizes(struct file *filp, void *priv,
-                                 struct v4l2_frmsizeenum *fsize)
-{
-       struct go7007 *go = video_drvdata(filp);
-       int width, height;
-
-       if (fsize->index > 2)
-               return -EINVAL;
-
-       if (!valid_pixelformat(fsize->pixel_format))
-               return -EINVAL;
-
-       get_resolution(go, &width, &height);
-       fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
-       fsize->discrete.width = (width >> fsize->index) & ~0xf;
-       fsize->discrete.height = (height >> fsize->index) & ~0xf;
-       return 0;
-}
-
-static int vidioc_enum_frameintervals(struct file *filp, void *priv,
-                                     struct v4l2_frmivalenum *fival)
-{
-       struct go7007 *go = video_drvdata(filp);
-       int width, height;
-       int i;
-
-       if (fival->index > 4)
-               return -EINVAL;
-
-       if (!valid_pixelformat(fival->pixel_format))
-               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->index + 1);
-       fival->discrete.denominator = go->sensor_framerate;
-       return 0;
-}
-
-static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       *std = go->std;
-       return 0;
-}
-
-static int go7007_s_std(struct go7007 *go)
-{
-       if (go->std & V4L2_STD_625_50) {
-               go->standard = GO7007_STD_PAL;
-               go->sensor_framerate = 25025;
-       } else {
-               go->standard = GO7007_STD_NTSC;
-               go->sensor_framerate = 30000;
-       }
-
-       call_all(&go->v4l2_dev, video, 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 = video_drvdata(file);
-
-       if (vb2_is_busy(&go->vidq))
-               return -EBUSY;
-
-       go->std = std;
-
-       return go7007_s_std(go);
-}
-
-static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       return call_all(&go->v4l2_dev, video, querystd, std);
-}
-
-static int vidioc_enum_input(struct file *file, void *priv,
-                               struct v4l2_input *inp)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       if (inp->index >= go->board_info->num_inputs)
-               return -EINVAL;
-
-       strncpy(inp->name, go->board_info->inputs[inp->index].name,
-                       sizeof(inp->name));
-
-       /* If this board has a tuner, it will be the first input */
-       if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
-                       inp->index == 0)
-               inp->type = V4L2_INPUT_TYPE_TUNER;
-       else
-               inp->type = V4L2_INPUT_TYPE_CAMERA;
-
-       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 = video_devdata(file)->tvnorms;
-       else
-               inp->std = 0;
-
-       return 0;
-}
-
-
-static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       *input = go->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 void go7007_s_input(struct go7007 *go)
-{
-       unsigned int input = go->input;
-
-       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;
-       }
-}
-
-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 (vb2_is_busy(&go->vidq))
-               return -EBUSY;
-
-       go->input = input;
-       go7007_s_input(go);
-
-       return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
-                               struct v4l2_tuner *t)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       if (t->index != 0)
-               return -EINVAL;
-
-       strlcpy(t->name, "Tuner", sizeof(t->name));
-       return call_all(&go->v4l2_dev, tuner, g_tuner, t);
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
-                               const struct v4l2_tuner *t)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       if (t->index != 0)
-               return -EINVAL;
-
-       return call_all(&go->v4l2_dev, tuner, s_tuner, t);
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
-                               struct v4l2_frequency *f)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       if (f->tuner)
-               return -EINVAL;
-
-       return call_all(&go->v4l2_dev, tuner, g_frequency, f);
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
-                               const struct v4l2_frequency *f)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       if (f->tuner)
-               return -EINVAL;
-
-       return call_all(&go->v4l2_dev, tuner, s_frequency, f);
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
-       struct go7007 *go = video_drvdata(file);
-
-       v4l2_ctrl_log_status(file, priv);
-       return call_all(&go->v4l2_dev, core, log_status);
-}
-
-static int vidioc_subscribe_event(struct v4l2_fh *fh,
-                               const struct v4l2_event_subscription *sub)
-{
-
-       switch (sub->type) {
-       case V4L2_EVENT_CTRL:
-               return v4l2_ctrl_subscribe_event(fh, sub);
-       case V4L2_EVENT_MOTION_DET:
-               /* Allow for up to 30 events (1 second for NTSC) to be
-                * stored. */
-               return v4l2_event_subscribe(fh, sub, 30, NULL);
-       }
-       return -EINVAL;
-}
-
-
-static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       struct go7007 *go =
-               container_of(ctrl->handler, struct go7007, hdl);
-       unsigned y;
-       u8 *mt;
-
-       switch (ctrl->id) {
-       case V4L2_CID_PIXEL_THRESHOLD0:
-               go->modet[0].pixel_threshold = ctrl->val;
-               break;
-       case V4L2_CID_MOTION_THRESHOLD0:
-               go->modet[0].motion_threshold = ctrl->val;
-               break;
-       case V4L2_CID_MB_THRESHOLD0:
-               go->modet[0].mb_threshold = ctrl->val;
-               break;
-       case V4L2_CID_PIXEL_THRESHOLD1:
-               go->modet[1].pixel_threshold = ctrl->val;
-               break;
-       case V4L2_CID_MOTION_THRESHOLD1:
-               go->modet[1].motion_threshold = ctrl->val;
-               break;
-       case V4L2_CID_MB_THRESHOLD1:
-               go->modet[1].mb_threshold = ctrl->val;
-               break;
-       case V4L2_CID_PIXEL_THRESHOLD2:
-               go->modet[2].pixel_threshold = ctrl->val;
-               break;
-       case V4L2_CID_MOTION_THRESHOLD2:
-               go->modet[2].motion_threshold = ctrl->val;
-               break;
-       case V4L2_CID_MB_THRESHOLD2:
-               go->modet[2].mb_threshold = ctrl->val;
-               break;
-       case V4L2_CID_PIXEL_THRESHOLD3:
-               go->modet[3].pixel_threshold = ctrl->val;
-               break;
-       case V4L2_CID_MOTION_THRESHOLD3:
-               go->modet[3].motion_threshold = ctrl->val;
-               break;
-       case V4L2_CID_MB_THRESHOLD3:
-               go->modet[3].mb_threshold = ctrl->val;
-               break;
-       case V4L2_CID_DETECT_MD_REGION_GRID:
-               mt = go->modet_map;
-               for (y = 0; y < go->height / 16; y++, mt += go->width / 16)
-                       memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16);
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static struct v4l2_file_operations go7007_fops = {
-       .owner          = THIS_MODULE,
-       .open           = v4l2_fh_open,
-       .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 = {
-       .vidioc_querycap          = vidioc_querycap,
-       .vidioc_enum_fmt_vid_cap  = vidioc_enum_fmt_vid_cap,
-       .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           = 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,
-       .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_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,
-       .vidioc_s_frequency       = vidioc_s_frequency,
-       .vidioc_g_parm            = vidioc_g_parm,
-       .vidioc_s_parm            = vidioc_s_parm,
-       .vidioc_enum_framesizes   = vidioc_enum_framesizes,
-       .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
-       .vidioc_log_status        = vidioc_log_status,
-       .vidioc_subscribe_event   = vidioc_subscribe_event,
-       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-static struct video_device go7007_template = {
-       .name           = "go7007",
-       .fops           = &go7007_fops,
-       .release        = video_device_release_empty,
-       .ioctl_ops      = &video_ioctl_ops,
-       .tvnorms        = V4L2_STD_ALL,
-};
-
-static const struct v4l2_ctrl_ops go7007_ctrl_ops = {
-       .s_ctrl = go7007_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_PIXEL_THRESHOLD0,
-       .name = "Pixel Threshold Region 0",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 20,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_MOTION_THRESHOLD0,
-       .name = "Motion Threshold Region 0",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 80,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_MB_THRESHOLD0,
-       .name = "MB Threshold Region 0",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 200,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_PIXEL_THRESHOLD1,
-       .name = "Pixel Threshold Region 1",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 20,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_MOTION_THRESHOLD1,
-       .name = "Motion Threshold Region 1",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 80,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_MB_THRESHOLD1,
-       .name = "MB Threshold Region 1",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 200,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_PIXEL_THRESHOLD2,
-       .name = "Pixel Threshold Region 2",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 20,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_MOTION_THRESHOLD2,
-       .name = "Motion Threshold Region 2",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 80,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_MB_THRESHOLD2,
-       .name = "MB Threshold Region 2",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 200,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_PIXEL_THRESHOLD3,
-       .name = "Pixel Threshold Region 3",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 20,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_MOTION_THRESHOLD3,
-       .name = "Motion Threshold Region 3",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 80,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_MB_THRESHOLD3,
-       .name = "MB Threshold Region 3",
-       .type = V4L2_CTRL_TYPE_INTEGER,
-       .def = 200,
-       .max = 32767,
-       .step = 1,
-};
-
-static const struct v4l2_ctrl_config go7007_mb_regions_ctrl = {
-       .ops = &go7007_ctrl_ops,
-       .id = V4L2_CID_DETECT_MD_REGION_GRID,
-       .dims = { 576 / 16, 720 / 16 },
-       .max = 3,
-       .step = 1,
-};
-
-int go7007_v4l2_ctrl_init(struct go7007 *go)
-{
-       struct v4l2_ctrl_handler *hdl = &go->hdl;
-       struct v4l2_ctrl *ctrl;
-
-       v4l2_ctrl_handler_init(hdl, 22);
-       go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
-                       V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
-       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, 9800000);
-       go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
-                       V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
-       go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
-                       V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
-
-       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);
-       if (ctrl)
-               ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-       v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold0_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold0_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold0_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold1_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold1_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold1_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold2_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold2_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold2_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold3_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold3_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold3_ctrl, NULL);
-       v4l2_ctrl_new_custom(hdl, &go7007_mb_regions_ctrl, NULL);
-       go->modet_mode = v4l2_ctrl_new_std_menu(hdl, NULL,
-                       V4L2_CID_DETECT_MD_MODE,
-                       V4L2_DETECT_MD_MODE_REGION_GRID,
-                       1 << V4L2_DETECT_MD_MODE_THRESHOLD_GRID,
-                       V4L2_DETECT_MD_MODE_DISABLED);
-       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)
-{
-       struct video_device *vdev = &go->vdev;
-       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_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-       go->vidq.lock = &go->queue_lock;
-       rv = vb2_queue_init(&go->vidq);
-       if (rv)
-               return rv;
-       *vdev = go7007_template;
-       vdev->lock = &go->serialize_lock;
-       vdev->queue = &go->vidq;
-       video_set_drvdata(vdev, go);
-       vdev->v4l2_dev = &go->v4l2_dev;
-       if (!v4l2_device_has_op(&go->v4l2_dev, video, querystd))
-               v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
-       if (!(go->board_info->flags & GO7007_BOARD_HAS_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,
-                       .frequency = 980,
-               };
-
-               call_all(&go->v4l2_dev, tuner, s_frequency, &f);
-       }
-       if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
-               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(vdev, VIDIOC_ENUM_FRAMESIZES);
-       if (go->board_info->num_aud_inputs == 0) {
-               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)
-               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);
-       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(vdev));
-
-       return 0;
-}
-
-void go7007_v4l2_remove(struct go7007 *go)
-{
-       v4l2_ctrl_handler_free(&go->hdl);
-}
diff --git a/drivers/staging/media/go7007/go7007.txt b/drivers/staging/media/go7007/go7007.txt
deleted file mode 100644 (file)
index c8e5eb0..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-This is a driver for the WIS GO7007SB multi-format video encoder.
-
-Pete Eberlein <pete@sensoray.com>
-
-The driver was originally 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_MODULES           - Enable loadable module support
-       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_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.
diff --git a/drivers/staging/media/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c
deleted file mode 100644 (file)
index bb84668..0000000
+++ /dev/null
@@ -1,628 +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.
- */
-
-#include <linux/module.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-subdev.h>
-#include "go7007-priv.h"
-
-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
-#define VPX322_ADDR_BRIGHTNESS1                0x0131
-#define VPX322_ADDR_CONTRAST0          0x0128
-#define VPX322_ADDR_CONTRAST1          0x0132
-#define VPX322_ADDR_HUE                        0x00dc
-#define VPX322_ADDR_SAT                        0x0030
-
-struct go7007_usb_board {
-       unsigned int flags;
-       struct go7007_board_info main_info;
-};
-
-struct go7007_usb {
-       struct go7007_usb_board *board;
-       struct mutex i2c_lock;
-       struct usb_device *usbdev;
-       struct urb *video_urbs[8];
-       struct urb *audio_urbs[8];
-       struct urb *intr_urb;
-};
-
-static unsigned char aud_regs[] = {
-       0x1e, 0x00,
-       0x00, 0x17,
-       0x02, 0x17,
-       0x04, 0xf9,
-       0x06, 0xf9,
-       0x08, 0x02,
-       0x0a, 0x00,
-       0x0c, 0x00,
-       0x0a, 0x00,
-       0x0c, 0x00,
-       0x0e, 0x02,
-       0x10, 0x00,
-       0x12, 0x01,
-       0x00, 0x00,
-};
-
-
-static unsigned char vid_regs[] = {
-       0xF2, 0x0f,
-       0xAA, 0x00,
-       0xF8, 0xff,
-       0x00, 0x00,
-};
-
-static u16 vid_regs_fp[] = {
-       0x028, 0x067,
-       0x120, 0x016,
-       0x121, 0xcF2,
-       0x122, 0x0F2,
-       0x123, 0x00c,
-       0x124, 0x2d0,
-       0x125, 0x2e0,
-       0x126, 0x004,
-       0x128, 0x1E0,
-       0x12A, 0x016,
-       0x12B, 0x0F2,
-       0x12C, 0x0F2,
-       0x12D, 0x00c,
-       0x12E, 0x2d0,
-       0x12F, 0x2e0,
-       0x130, 0x004,
-       0x132, 0x1E0,
-       0x140, 0x060,
-       0x153, 0x00C,
-       0x154, 0x200,
-       0x150, 0x801,
-       0x000, 0x000
-};
-
-/* PAL specific values */
-static u16 vid_regs_fp_pal[] = {
-       0x120, 0x017,
-       0x121, 0xd22,
-       0x122, 0x122,
-       0x12A, 0x017,
-       0x12B, 0x122,
-       0x12C, 0x122,
-       0x140, 0x060,
-       0x000, 0x000,
-};
-
-struct s2250 {
-       struct v4l2_subdev sd;
-       struct v4l2_ctrl_handler hdl;
-       v4l2_std_id std;
-       int input;
-       int brightness;
-       int contrast;
-       int saturation;
-       int hue;
-       int reg12b_val;
-       int audio_input;
-       struct i2c_client *audio;
-};
-
-static inline struct s2250 *to_state(struct v4l2_subdev *sd)
-{
-       return container_of(sd, struct s2250, sd);
-}
-
-/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
-static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
-       u16 value, u16 index, void *transfer_buffer, int length, int in)
-{
-       struct go7007_usb *usb = go->hpi_context;
-       int timeout = 5000;
-
-       if (in) {
-               return usb_control_msg(usb->usbdev,
-                               usb_rcvctrlpipe(usb->usbdev, 0), request,
-                               USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-                               value, index, transfer_buffer, length, timeout);
-       } else {
-               return usb_control_msg(usb->usbdev,
-                               usb_sndctrlpipe(usb->usbdev, 0), request,
-                               USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                               value, index, transfer_buffer, length, timeout);
-       }
-}
-/* end from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
-
-static int write_reg(struct i2c_client *client, u8 reg, u8 value)
-{
-       struct go7007 *go = i2c_get_adapdata(client->adapter);
-       struct go7007_usb *usb;
-       int rc;
-       int dev_addr = client->addr << 1;  /* firmware wants 8-bit address */
-       u8 *buf;
-
-       if (go == NULL)
-               return -ENODEV;
-
-       if (go->status == STATUS_SHUTDOWN)
-               return -EBUSY;
-
-       buf = kzalloc(16, GFP_KERNEL);
-       if (buf == NULL)
-               return -ENOMEM;
-
-       usb = go->hpi_context;
-       if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
-               dev_info(&client->dev, "i2c lock failed\n");
-               kfree(buf);
-               return -EINTR;
-       }
-       rc = go7007_usb_vendor_request(go, 0x55, dev_addr,
-                                      (reg<<8 | value),
-                                      buf,
-                                      16, 1);
-
-       mutex_unlock(&usb->i2c_lock);
-       kfree(buf);
-       return rc;
-}
-
-static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
-{
-       struct go7007 *go = i2c_get_adapdata(client->adapter);
-       struct go7007_usb *usb;
-       int rc;
-       u8 *buf;
-       struct s2250 *dec = i2c_get_clientdata(client);
-
-       if (go == NULL)
-               return -ENODEV;
-
-       if (go->status == STATUS_SHUTDOWN)
-               return -EBUSY;
-
-       buf = kzalloc(16, GFP_KERNEL);
-
-       if (buf == NULL)
-               return -ENOMEM;
-
-
-
-       memset(buf, 0xcd, 6);
-
-       usb = go->hpi_context;
-       if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
-               dev_info(&client->dev, "i2c lock failed\n");
-               kfree(buf);
-               return -EINTR;
-       }
-       rc = go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1);
-       mutex_unlock(&usb->i2c_lock);
-       if (rc < 0) {
-               kfree(buf);
-               return rc;
-       }
-
-       if (buf[0] == 0) {
-               unsigned int subaddr, val_read;
-
-               subaddr = (buf[4] << 8) + buf[5];
-               val_read = (buf[2] << 8) + buf[3];
-               kfree(buf);
-               if (val_read != val) {
-                       dev_info(&client->dev, "invalid fp write %x %x\n",
-                                val_read, val);
-                       return -EFAULT;
-               }
-               if (subaddr != addr) {
-                       dev_info(&client->dev, "invalid fp write addr %x %x\n",
-                                subaddr, addr);
-                       return -EFAULT;
-               }
-       } else {
-               kfree(buf);
-               return -EFAULT;
-       }
-
-       /* save last 12b value */
-       if (addr == 0x12b)
-               dec->reg12b_val = val;
-
-       return 0;
-}
-
-static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
-{
-       struct go7007 *go = i2c_get_adapdata(client->adapter);
-       struct go7007_usb *usb;
-       int rc;
-       u8 *buf;
-
-       if (go == NULL)
-               return -ENODEV;
-
-       if (go->status == STATUS_SHUTDOWN)
-               return -EBUSY;
-
-       buf = kzalloc(16, GFP_KERNEL);
-
-       if (buf == NULL)
-               return -ENOMEM;
-
-
-
-       memset(buf, 0xcd, 6);
-       usb = go->hpi_context;
-       if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
-               dev_info(&client->dev, "i2c lock failed\n");
-               kfree(buf);
-               return -EINTR;
-       }
-       rc = go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1);
-       mutex_unlock(&usb->i2c_lock);
-       if (rc < 0) {
-               kfree(buf);
-               return rc;
-       }
-
-       *val = (buf[0] << 8) | buf[1];
-       kfree(buf);
-
-       return 0;
-}
-
-
-static int write_regs(struct i2c_client *client, u8 *regs)
-{
-       int i;
-
-       for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
-               if (write_reg(client, regs[i], regs[i+1]) < 0) {
-                       dev_info(&client->dev, "failed\n");
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static int write_regs_fp(struct i2c_client *client, u16 *regs)
-{
-       int i;
-
-       for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
-               if (write_reg_fp(client, regs[i], regs[i+1]) < 0) {
-                       dev_info(&client->dev, "failed fp\n");
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-static int s2250_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
-                                u32 config)
-{
-       struct s2250 *state = to_state(sd);
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       int vidsys;
-
-       vidsys = (state->std == V4L2_STD_NTSC) ? 0x01 : 0x00;
-       if (input == 0) {
-               /* composite */
-               write_reg_fp(client, 0x20, 0x020 | vidsys);
-               write_reg_fp(client, 0x21, 0x662);
-               write_reg_fp(client, 0x140, 0x060);
-       } else if (input == 1) {
-               /* S-Video */
-               write_reg_fp(client, 0x20, 0x040 | vidsys);
-               write_reg_fp(client, 0x21, 0x666);
-               write_reg_fp(client, 0x140, 0x060);
-       } else {
-               return -EINVAL;
-       }
-       state->input = input;
-       return 0;
-}
-
-static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
-{
-       struct s2250 *state = to_state(sd);
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-       u16 vidsource;
-
-       vidsource = (state->input == 1) ? 0x040 : 0x020;
-       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);
-       } else {
-               write_regs_fp(client, vid_regs_fp);
-               write_reg_fp(client, 0x20, vidsource | 1);
-       }
-       state->std = norm;
-       return 0;
-}
-
-static int s2250_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-       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:
-               read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
-               write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
-                            ctrl->val | (oldvalue & ~0xff));
-               read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
-               write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
-                            ctrl->val | (oldvalue & ~0xff));
-               write_reg_fp(client, 0x140, 0x60);
-               break;
-       case V4L2_CID_CONTRAST:
-               read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
-               write_reg_fp(client, VPX322_ADDR_CONTRAST0,
-                            ctrl->val | (oldvalue & ~0x3f));
-               read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
-               write_reg_fp(client, VPX322_ADDR_CONTRAST1,
-                            ctrl->val | (oldvalue & ~0x3f));
-               write_reg_fp(client, 0x140, 0x60);
-               break;
-       case V4L2_CID_SATURATION:
-               write_reg_fp(client, VPX322_ADDR_SAT, ctrl->val);
-               break;
-       case V4L2_CID_HUE:
-               write_reg_fp(client, VPX322_ADDR_HUE, ctrl->val);
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static int s2250_s_mbus_fmt(struct v4l2_subdev *sd,
-                       struct v4l2_mbus_framefmt *fmt)
-{
-       struct s2250 *state = to_state(sd);
-       struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-       if (fmt->height < 640) {
-               write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
-               write_reg_fp(client, 0x140, 0x060);
-       } else {
-               write_reg_fp(client, 0x12b, state->reg12b_val & ~0x400);
-               write_reg_fp(client, 0x140, 0x060);
-       }
-       return 0;
-}
-
-static int s2250_s_audio_routing(struct v4l2_subdev *sd, u32 input, u32 output,
-                                u32 config)
-{
-       struct s2250 *state = to_state(sd);
-
-       switch (input) {
-       case 0:
-               write_reg(state->audio, 0x08, 0x02); /* Line In */
-               break;
-       case 1:
-               write_reg(state->audio, 0x08, 0x04); /* Mic */
-               break;
-       case 2:
-               write_reg(state->audio, 0x08, 0x05); /* Mic Boost */
-               break;
-       default:
-               return -EINVAL;
-       }
-       state->audio_input = input;
-       return 0;
-}
-
-
-static int s2250_log_status(struct v4l2_subdev *sd)
-{
-       struct s2250 *state = to_state(sd);
-
-       v4l2_info(sd, "Standard: %s\n", state->std == V4L2_STD_NTSC ? "NTSC" :
-                                       state->std == V4L2_STD_PAL ? "PAL" :
-                                       state->std == V4L2_STD_SECAM ? "SECAM" :
-                                       "unknown");
-       v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
-                                       state->input == 1 ? "S-video" :
-                                       "error");
-       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 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,
-};
-
-static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
-       .s_routing = s2250_s_audio_routing,
-};
-
-static const struct v4l2_subdev_video_ops s2250_video_ops = {
-       .s_std = s2250_s_std,
-       .s_routing = s2250_s_video_routing,
-       .s_mbus_fmt = s2250_s_mbus_fmt,
-};
-
-static const struct v4l2_subdev_ops s2250_ops = {
-       .core = &s2250_core_ops,
-       .audio = &s2250_audio_ops,
-       .video = &s2250_video_ops,
-};
-
-/* --------------------------------------------------------------------------*/
-
-static int s2250_probe(struct i2c_client *client,
-                      const struct i2c_device_id *id)
-{
-       struct i2c_client *audio;
-       struct i2c_adapter *adapter = client->adapter;
-       struct s2250 *state;
-       struct v4l2_subdev *sd;
-       u8 *data;
-       struct go7007 *go = i2c_get_adapdata(adapter);
-       struct go7007_usb *usb = go->hpi_context;
-
-       audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
-       if (audio == NULL)
-               return -ENOMEM;
-
-       state = kzalloc(sizeof(struct s2250), GFP_KERNEL);
-       if (state == NULL) {
-               i2c_unregister_device(audio);
-               return -ENOMEM;
-       }
-
-       sd = &state->sd;
-       v4l2_i2c_subdev_init(sd, client, &s2250_ops);
-
-       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;
-       state->saturation = 50;
-       state->hue = 0;
-       state->audio = audio;
-
-       /* initialize the audio */
-       if (write_regs(audio, aud_regs) < 0) {
-               dev_err(&client->dev, "error initializing audio\n");
-               goto fail;
-       }
-
-       if (write_regs(client, vid_regs) < 0) {
-               dev_err(&client->dev, "error initializing decoder\n");
-               goto fail;
-       }
-       if (write_regs_fp(client, vid_regs_fp) < 0) {
-               dev_err(&client->dev, "error initializing decoder\n");
-               goto fail;
-       }
-       /* set default channel */
-       /* composite */
-       write_reg_fp(client, 0x20, 0x020 | 1);
-       write_reg_fp(client, 0x21, 0x662);
-       write_reg_fp(client, 0x140, 0x060);
-
-       /* set default audio input */
-       state->audio_input = 0;
-       write_reg(client, 0x08, 0x02); /* Line In */
-
-       if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
-               data = kzalloc(16, GFP_KERNEL);
-               if (data != NULL) {
-                       int rc = go7007_usb_vendor_request(go, 0x41, 0, 0,
-                                                      data, 16, 1);
-
-                       if (rc > 0) {
-                               u8 mask;
-
-                               data[0] = 0;
-                               mask = 1<<5;
-                               data[0] &= ~mask;
-                               data[1] |= mask;
-                               go7007_usb_vendor_request(go, 0x40, 0,
-                                                         (data[1]<<8)
-                                                         + data[1],
-                                                         data, 16, 0);
-                       }
-                       kfree(data);
-               }
-               mutex_unlock(&usb->i2c_lock);
-       }
-
-       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 s2250 *state = to_state(i2c_get_clientdata(client));
-
-       v4l2_device_unregister_subdev(&state->sd);
-       v4l2_ctrl_handler_free(&state->hdl);
-       kfree(state);
-       return 0;
-}
-
-static const struct i2c_device_id s2250_id[] = {
-       { "s2250", 0 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, s2250_id);
-
-static struct i2c_driver s2250_driver = {
-       .driver = {
-               .owner  = THIS_MODULE,
-               .name   = "s2250",
-       },
-       .probe          = s2250_probe,
-       .remove         = s2250_remove,
-       .id_table       = s2250_id,
-};
-
-module_i2c_driver(s2250_driver);
diff --git a/drivers/staging/media/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
deleted file mode 100644 (file)
index b137432..0000000
+++ /dev/null
@@ -1,560 +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.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/usb.h>
-#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.h"
-#include "saa7134-reg.h"
-#include "go7007-priv.h"
-
-/*#define GO7007_HPI_DEBUG*/
-
-enum hpi_address {
-       HPI_ADDR_VIDEO_BUFFER = 0xe4,
-       HPI_ADDR_INIT_BUFFER = 0xea,
-       HPI_ADDR_INTR_RET_VALUE = 0xee,
-       HPI_ADDR_INTR_RET_DATA = 0xec,
-       HPI_ADDR_INTR_STATUS = 0xf4,
-       HPI_ADDR_INTR_WR_PARAM = 0xf6,
-       HPI_ADDR_INTR_WR_INDEX = 0xf8,
-};
-
-enum gpio_command {
-       GPIO_COMMAND_RESET = 0x00, /* 000b */
-       GPIO_COMMAND_REQ1  = 0x04, /* 001b */
-       GPIO_COMMAND_WRITE = 0x20, /* 010b */
-       GPIO_COMMAND_REQ2  = 0x24, /* 011b */
-       GPIO_COMMAND_READ  = 0x80, /* 100b */
-       GPIO_COMMAND_VIDEO = 0x84, /* 101b */
-       GPIO_COMMAND_IDLE  = 0xA0, /* 110b */
-       GPIO_COMMAND_ADDR  = 0xA4, /* 111b */
-};
-
-struct saa7134_go7007 {
-       struct v4l2_subdev sd;
-       struct saa7134_dev *dev;
-       u8 *top;
-       u8 *bottom;
-       dma_addr_t top_dma;
-       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 const struct go7007_board_info board_voyager = {
-       .flags           = 0,
-       .sensor_flags    = GO7007_SENSOR_656 |
-                               GO7007_SENSOR_VALID_ENABLE |
-                               GO7007_SENSOR_TV |
-                               GO7007_SENSOR_VBI,
-       .audio_flags    = GO7007_AUDIO_I2S_MODE_1 |
-                               GO7007_AUDIO_WORD_16,
-       .audio_rate      = 48000,
-       .audio_bclk_div  = 8,
-       .audio_main_div  = 2,
-       .hpi_buffer_cap  = 7,
-       .num_inputs      = 1,
-       .inputs          = {
-               {
-                       .name           = "SAA7134",
-               },
-       },
-};
-
-/********************* Driver for GPIO HPI interface *********************/
-
-static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
-{
-       saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-
-       /* Write HPI address */
-       saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
-       /* Write low byte */
-       saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
-       /* Write high byte */
-       saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
-       return 0;
-}
-
-static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
-{
-       saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-
-       /* Write HPI address */
-       saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
-       saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
-
-       /* Read low byte */
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
-       saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-       saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-       *data = saa_readb(SAA7134_GPIO_GPSTATUS0);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
-       /* Read high byte */
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
-       saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-       saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-       *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-
-       return 0;
-}
-
-static int saa7134_go7007_interface_reset(struct go7007 *go)
-{
-       struct saa7134_go7007 *saa = go->hpi_context;
-       struct saa7134_dev *dev = saa->dev;
-       u32 status;
-       u16 intr_val, intr_data;
-       int count = 20;
-
-       saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
-       saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4);
-       saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET);
-       msleep(1);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
-       msleep(10);
-
-       saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-       saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-
-       status = saa_readb(SAA7134_GPIO_GPSTATUS2);
-       /*pr_debug("status is %s\n", status & 0x40 ? "OK" : "not OK"); */
-
-       /* enter command mode...(?) */
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
-
-       do {
-               saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-               saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
-               status = saa_readb(SAA7134_GPIO_GPSTATUS2);
-               /*pr_info("gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
-       } while (--count > 0);
-
-       /* Wait for an interrupt to indicate successful hardware reset */
-       if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
-                       (intr_val & ~0x1) != 0x55aa) {
-               pr_err("saa7134-go7007: unable to reset the GO7007\n");
-               return -1;
-       }
-       return 0;
-}
-
-static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
-{
-       struct saa7134_go7007 *saa = go->hpi_context;
-       struct saa7134_dev *dev = saa->dev;
-       int i;
-       u16 status_reg;
-
-#ifdef GO7007_HPI_DEBUG
-       pr_debug("saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
-#endif
-
-       for (i = 0; i < 100; ++i) {
-               gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
-               if (!(status_reg & 0x0010))
-                       break;
-               msleep(10);
-       }
-       if (i == 100) {
-               pr_err("saa7134-go7007: device is hung, status reg = 0x%04x\n",
-                       status_reg);
-               return -1;
-       }
-       gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data);
-       gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr);
-
-       return 0;
-}
-
-static int saa7134_go7007_read_interrupt(struct go7007 *go)
-{
-       struct saa7134_go7007 *saa = go->hpi_context;
-       struct saa7134_dev *dev = saa->dev;
-
-       /* XXX we need to wait if there is no interrupt available */
-       go->interrupt_available = 1;
-       gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value);
-       gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data);
-#ifdef GO7007_HPI_DEBUG
-       pr_debug("saa7134-go7007: ReadInterrupt: %04x %04x\n",
-                       go->interrupt_value, go->interrupt_data);
-#endif
-       return 0;
-}
-
-static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
-                                               unsigned long status)
-{
-       struct go7007 *go = video_get_drvdata(dev->empress_dev);
-       struct saa7134_go7007 *saa = go->hpi_context;
-
-       if (!vb2_is_streaming(&go->vidq))
-               return;
-       if (0 != (status & 0x000f0000))
-               pr_debug("saa7134-go7007: irq: lost %ld\n",
-                               (status >> 16) & 0x0f);
-       if (status & 0x100000) {
-               dma_sync_single_for_cpu(&dev->pci->dev,
-                                       saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE);
-               go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE);
-               saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
-       } else {
-               dma_sync_single_for_cpu(&dev->pci->dev,
-                                       saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE);
-               go7007_parse_video_stream(go, saa->top, PAGE_SIZE);
-               saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
-       }
-}
-
-static int saa7134_go7007_stream_start(struct go7007 *go)
-{
-       struct saa7134_go7007 *saa = go->hpi_context;
-       struct saa7134_dev *dev = saa->dev;
-
-       saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
-                       0, PAGE_SIZE, DMA_FROM_DEVICE);
-       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 (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;
-       }
-
-       saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
-       saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
-
-       /* Set HPI interface for video */
-       saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-       saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER);
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
-       saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
-
-       /* Enable TS interface */
-       saa_writeb(SAA7134_TS_PARALLEL, 0xe6);
-
-       /* Reset TS interface */
-       saa_setb(SAA7134_TS_SERIAL1, 0x01);
-       saa_clearb(SAA7134_TS_SERIAL1, 0x01);
-
-       /* Set up transfer block size */
-       saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1);
-       saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1);
-       saa_writeb(SAA7134_TS_DMA1, 0);
-       saa_writeb(SAA7134_TS_DMA2, 0);
-
-       /* Enable video streaming mode */
-       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO);
-
-       saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
-       saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
-       saa_writel(SAA7134_RS_PITCH(5), 128);
-       saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX);
-
-       /* Enable TS FIFO */
-       saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
-
-       /* Enable DMA IRQ */
-       saa_setl(SAA7134_IRQ1,
-                       SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
-
-       return 0;
-}
-
-static int saa7134_go7007_stream_stop(struct go7007 *go)
-{
-       struct saa7134_go7007 *saa = go->hpi_context;
-       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);
-
-       /* Disable DMA IRQ */
-       saa_clearl(SAA7134_IRQ1,
-                       SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
-
-       /* Disable TS interface */
-       saa_clearb(SAA7134_TS_PARALLEL, 0x80);
-
-       dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
-                       DMA_FROM_DEVICE);
-       dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
-                       DMA_FROM_DEVICE);
-
-       return 0;
-}
-
-static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
-{
-       struct saa7134_go7007 *saa = go->hpi_context;
-       struct saa7134_dev *dev = saa->dev;
-       u16 status_reg;
-       int i;
-
-#ifdef GO7007_HPI_DEBUG
-       pr_debug("saa7134-go7007: DownloadBuffer sending %d bytes\n", len);
-#endif
-
-       while (len > 0) {
-               i = len > 64 ? 64 : len;
-               saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
-               saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER);
-               saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
-               saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-               while (i-- > 0) {
-                       saa_writeb(SAA7134_GPIO_GPSTATUS0, *data);
-                       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
-                       saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
-                       ++data;
-                       --len;
-               }
-               for (i = 0; i < 100; ++i) {
-                       gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
-                       if (!(status_reg & 0x0002))
-                               break;
-               }
-               if (i == 100) {
-                       pr_err("saa7134-go7007: device is hung, status reg = 0x%04x\n",
-                                       status_reg);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
-       .interface_reset        = saa7134_go7007_interface_reset,
-       .write_interrupt        = saa7134_go7007_write_interrupt,
-       .read_interrupt         = saa7134_go7007_read_interrupt,
-       .stream_start           = saa7134_go7007_stream_start,
-       .stream_stop            = saa7134_go7007_stream_stop,
-       .send_firmware          = saa7134_go7007_send_firmware,
-};
-MODULE_FIRMWARE("go7007/go7007tv.bin");
-
-/* --------------------------------------------------------------------------*/
-
-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,
-};
-
-static const struct v4l2_subdev_video_ops saa7134_go7007_video_ops = {
-       .s_std = saa7134_go7007_s_std,
-};
-
-static const struct v4l2_subdev_ops saa7134_go7007_sd_ops = {
-       .core = &saa7134_go7007_core_ops,
-       .video = &saa7134_go7007_video_ops,
-};
-
-/* --------------------------------------------------------------------------*/
-
-
-/********************* Add/remove functions *********************/
-
-static int saa7134_go7007_init(struct saa7134_dev *dev)
-{
-       struct go7007 *go;
-       struct saa7134_go7007 *saa;
-       struct v4l2_subdev *sd;
-
-       pr_debug("saa7134-go7007: probing new SAA713X board\n");
-
-       go = go7007_alloc(&board_voyager, &dev->pci->dev);
-       if (go == NULL)
-               return -ENOMEM;
-
-       saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
-       if (saa == NULL) {
-               kfree(go);
-               return -ENOMEM;
-       }
-
-       go->board_id = GO7007_BOARDID_PCI_VOYAGER;
-       snprintf(go->bus_info, sizeof(go->bus_info), "PCI:%s", pci_name(dev->pci));
-       strlcpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
-       go->hpi_ops = &saa7134_go7007_hpi_ops;
-       go->hpi_context = saa;
-       saa->dev = dev;
-
-       /* 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)
-               goto allocfail;
-       saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
-       if (!saa->bottom)
-               goto allocfail;
-
-       /* Boot the GO7007 */
-       if (go7007_boot_encoder(go, go->board_info->flags &
-                                       GO7007_BOARD_USE_ONBOARD_I2C) < 0)
-               goto allocfail;
-
-       /* Do any final GO7007 initialization, then register the
-        * V4L2 and ALSA interfaces */
-       if (go7007_register_encoder(go, go->board_info->num_i2c_devs) < 0)
-               goto allocfail;
-
-       /* Register the subdevice interface with the go7007 device */
-       if (v4l2_device_register_subdev(&go->v4l2_dev, sd) < 0)
-               pr_info("saa7134-go7007: register subdev failed\n");
-
-       dev->empress_dev = &go->vdev;
-
-       go->status = STATUS_ONLINE;
-       return 0;
-
-allocfail:
-       if (saa->top)
-               free_page((unsigned long)saa->top);
-       if (saa->bottom)
-               free_page((unsigned long)saa->bottom);
-       kfree(saa);
-       kfree(go);
-       return -ENOMEM;
-}
-
-static int saa7134_go7007_fini(struct saa7134_dev *dev)
-{
-       struct go7007 *go;
-       struct saa7134_go7007 *saa;
-
-       if (NULL == dev->empress_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);
-       v4l2_device_unregister_subdev(&saa->sd);
-       kfree(saa);
-       video_unregister_device(&go->vdev);
-
-       v4l2_device_put(&go->v4l2_dev);
-       dev->empress_dev = NULL;
-
-       return 0;
-}
-
-static struct saa7134_mpeg_ops saa7134_go7007_ops = {
-       .type          = SAA7134_MPEG_GO7007,
-       .init          = saa7134_go7007_init,
-       .fini          = saa7134_go7007_fini,
-       .irq_ts_done   = saa7134_go7007_irq_ts_done,
-};
-
-static int __init saa7134_go7007_mod_init(void)
-{
-       return saa7134_ts_register(&saa7134_go7007_ops);
-}
-
-static void __exit saa7134_go7007_mod_cleanup(void)
-{
-       saa7134_ts_unregister(&saa7134_go7007_ops);
-}
-
-module_init(saa7134_go7007_mod_init);
-module_exit(saa7134_go7007_mod_cleanup);
-
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/media/go7007/snd-go7007.c b/drivers/staging/media/go7007/snd-go7007.c
deleted file mode 100644 (file)
index d22d7d5..0000000
+++ /dev/null
@@ -1,298 +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.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/vmalloc.h>
-#include <linux/time.h>
-#include <linux/mm.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/initval.h>
-
-#include "go7007-priv.h"
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-
-module_param_array(index, int, NULL, 0444);
-module_param_array(id, charp, NULL, 0444);
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the go7007 audio driver");
-MODULE_PARM_DESC(id, "ID string for the go7007 audio driver");
-MODULE_PARM_DESC(enable, "Enable for the go7007 audio driver");
-
-struct go7007_snd {
-       struct snd_card *card;
-       struct snd_pcm *pcm;
-       struct snd_pcm_substream *substream;
-       spinlock_t lock;
-       int w_idx;
-       int hw_ptr;
-       int avail;
-       int capturing;
-};
-
-static struct snd_pcm_hardware go7007_snd_capture_hw = {
-       .info                   = (SNDRV_PCM_INFO_MMAP |
-                                       SNDRV_PCM_INFO_INTERLEAVED |
-                                       SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                                       SNDRV_PCM_INFO_MMAP_VALID),
-       .formats                = SNDRV_PCM_FMTBIT_S16_LE,
-       .rates                  = SNDRV_PCM_RATE_48000,
-       .rate_min               = 48000,
-       .rate_max               = 48000,
-       .channels_min           = 2,
-       .channels_max           = 2,
-       .buffer_bytes_max       = (128*1024),
-       .period_bytes_min       = 4096,
-       .period_bytes_max       = (128*1024),
-       .periods_min            = 1,
-       .periods_max            = 32,
-};
-
-static void parse_audio_stream_data(struct go7007 *go, u8 *buf, int length)
-{
-       struct go7007_snd *gosnd = go->snd_context;
-       struct snd_pcm_runtime *runtime = gosnd->substream->runtime;
-       int frames = bytes_to_frames(runtime, length);
-
-       spin_lock(&gosnd->lock);
-       gosnd->hw_ptr += frames;
-       if (gosnd->hw_ptr >= runtime->buffer_size)
-               gosnd->hw_ptr -= runtime->buffer_size;
-       gosnd->avail += frames;
-       spin_unlock(&gosnd->lock);
-       if (gosnd->w_idx + length > runtime->dma_bytes) {
-               int cpy = runtime->dma_bytes - gosnd->w_idx;
-
-               memcpy(runtime->dma_area + gosnd->w_idx, buf, cpy);
-               length -= cpy;
-               buf += cpy;
-               gosnd->w_idx = 0;
-       }
-       memcpy(runtime->dma_area + gosnd->w_idx, buf, length);
-       gosnd->w_idx += length;
-       spin_lock(&gosnd->lock);
-       if (gosnd->avail < runtime->period_size) {
-               spin_unlock(&gosnd->lock);
-               return;
-       }
-       gosnd->avail -= runtime->period_size;
-       spin_unlock(&gosnd->lock);
-       if (gosnd->capturing)
-               snd_pcm_period_elapsed(gosnd->substream);
-}
-
-static int go7007_snd_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *hw_params)
-{
-       struct go7007 *go = snd_pcm_substream_chip(substream);
-       unsigned int bytes;
-
-       bytes = params_buffer_bytes(hw_params);
-       if (substream->runtime->dma_bytes > 0)
-               vfree(substream->runtime->dma_area);
-       substream->runtime->dma_bytes = 0;
-       substream->runtime->dma_area = vmalloc(bytes);
-       if (substream->runtime->dma_area == NULL)
-               return -ENOMEM;
-       substream->runtime->dma_bytes = bytes;
-       go->audio_deliver = parse_audio_stream_data;
-       return 0;
-}
-
-static int go7007_snd_hw_free(struct snd_pcm_substream *substream)
-{
-       struct go7007 *go = snd_pcm_substream_chip(substream);
-
-       go->audio_deliver = NULL;
-       if (substream->runtime->dma_bytes > 0)
-               vfree(substream->runtime->dma_area);
-       substream->runtime->dma_bytes = 0;
-       return 0;
-}
-
-static int go7007_snd_capture_open(struct snd_pcm_substream *substream)
-{
-       struct go7007 *go = snd_pcm_substream_chip(substream);
-       struct go7007_snd *gosnd = go->snd_context;
-       unsigned long flags;
-       int r;
-
-       spin_lock_irqsave(&gosnd->lock, flags);
-       if (gosnd->substream == NULL) {
-               gosnd->substream = substream;
-               substream->runtime->hw = go7007_snd_capture_hw;
-               r = 0;
-       } else
-               r = -EBUSY;
-       spin_unlock_irqrestore(&gosnd->lock, flags);
-       return r;
-}
-
-static int go7007_snd_capture_close(struct snd_pcm_substream *substream)
-{
-       struct go7007 *go = snd_pcm_substream_chip(substream);
-       struct go7007_snd *gosnd = go->snd_context;
-
-       gosnd->substream = NULL;
-       return 0;
-}
-
-static int go7007_snd_pcm_prepare(struct snd_pcm_substream *substream)
-{
-       return 0;
-}
-
-static int go7007_snd_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
-       struct go7007 *go = snd_pcm_substream_chip(substream);
-       struct go7007_snd *gosnd = go->snd_context;
-
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-               /* Just set a flag to indicate we should signal ALSA when
-                * sound comes in */
-               gosnd->capturing = 1;
-               return 0;
-       case SNDRV_PCM_TRIGGER_STOP:
-               gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
-               gosnd->capturing = 0;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static snd_pcm_uframes_t go7007_snd_pcm_pointer(struct snd_pcm_substream *substream)
-{
-       struct go7007 *go = snd_pcm_substream_chip(substream);
-       struct go7007_snd *gosnd = go->snd_context;
-
-       return gosnd->hw_ptr;
-}
-
-static struct page *go7007_snd_pcm_page(struct snd_pcm_substream *substream,
-                                       unsigned long offset)
-{
-       return vmalloc_to_page(substream->runtime->dma_area + offset);
-}
-
-static struct snd_pcm_ops go7007_snd_capture_ops = {
-       .open           = go7007_snd_capture_open,
-       .close          = go7007_snd_capture_close,
-       .ioctl          = snd_pcm_lib_ioctl,
-       .hw_params      = go7007_snd_hw_params,
-       .hw_free        = go7007_snd_hw_free,
-       .prepare        = go7007_snd_pcm_prepare,
-       .trigger        = go7007_snd_pcm_trigger,
-       .pointer        = go7007_snd_pcm_pointer,
-       .page           = go7007_snd_pcm_page,
-};
-
-static int go7007_snd_free(struct snd_device *device)
-{
-       struct go7007 *go = device->device_data;
-
-       kfree(go->snd_context);
-       go->snd_context = NULL;
-       return 0;
-}
-
-static struct snd_device_ops go7007_snd_device_ops = {
-       .dev_free       = go7007_snd_free,
-};
-
-int go7007_snd_init(struct go7007 *go)
-{
-       static int dev;
-       struct go7007_snd *gosnd;
-       int ret = 0;
-
-       if (dev >= SNDRV_CARDS)
-               return -ENODEV;
-       if (!enable[dev]) {
-               dev++;
-               return -ENOENT;
-       }
-       gosnd = kmalloc(sizeof(struct go7007_snd), GFP_KERNEL);
-       if (gosnd == NULL)
-               return -ENOMEM;
-       spin_lock_init(&gosnd->lock);
-       gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
-       gosnd->capturing = 0;
-       ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0,
-                          &gosnd->card);
-       if (ret < 0) {
-               kfree(gosnd);
-               return ret;
-       }
-       ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
-                       &go7007_snd_device_ops);
-       if (ret < 0) {
-               kfree(gosnd);
-               return ret;
-       }
-       ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
-       if (ret < 0) {
-               snd_card_free(gosnd->card);
-               kfree(gosnd);
-               return ret;
-       }
-       strlcpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
-       strlcpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
-       strlcpy(gosnd->card->longname, gosnd->card->shortname,
-                       sizeof(gosnd->card->longname));
-
-       gosnd->pcm->private_data = go;
-       snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE,
-                       &go7007_snd_capture_ops);
-
-       ret = snd_card_register(gosnd->card);
-       if (ret < 0) {
-               snd_card_free(gosnd->card);
-               kfree(gosnd);
-               return ret;
-       }
-
-       gosnd->substream = NULL;
-       go->snd_context = gosnd;
-       v4l2_device_get(&go->v4l2_dev);
-       ++dev;
-
-       return 0;
-}
-EXPORT_SYMBOL(go7007_snd_init);
-
-int go7007_snd_remove(struct go7007 *go)
-{
-       struct go7007_snd *gosnd = go->snd_context;
-
-       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);
-
-MODULE_LICENSE("GPL v2");
This page took 0.176491 seconds and 5 git commands to generate.