]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/0010-Staging-add-the-go7007-video-driver.patch
Revert "Move xen patchset to new version's subdir."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / 0010-Staging-add-the-go7007-video-driver.patch
CommitLineData
00e5a55c
BS
1From 866b8695d67e83f47194731d3a7ba55826a7ec70 Mon Sep 17 00:00:00 2001
2From: Greg Kroah-Hartman <gregkh@suse.de>
3Date: Fri, 15 Feb 2008 16:53:09 -0800
4Subject: [PATCH 10/23] Staging: add the go7007 video driver
5Patch-mainline: 2.6.28
6
7Todo:
8 - checkpatch.pl cleanups
9 - sparse cleanups
10 - lots of little modules, should be merged together
11 and added to the build.
12 - testing?
13 - handle churn in v4l layer.
14
15Many thanks to Ross Cohen <rcohen@snurgle.org> for cleanup patches on
16this driver.
17
18Cc: Ross Cohen <rcohen@snurgle.org>
19Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
20---
21 drivers/staging/Kconfig | 2 +
22 drivers/staging/Makefile | 1 +
23 drivers/staging/go7007/Kconfig | 25 +
24 drivers/staging/go7007/Makefile | 18 +
25 drivers/staging/go7007/README | 11 +
26 drivers/staging/go7007/go7007-driver.c | 688 +++++++++++++
27 drivers/staging/go7007/go7007-fw.c | 1639 +++++++++++++++++++++++++++++++
28 drivers/staging/go7007/go7007-i2c.c | 309 ++++++
29 drivers/staging/go7007/go7007-priv.h | 279 ++++++
30 drivers/staging/go7007/go7007-usb.c | 1229 +++++++++++++++++++++++
31 drivers/staging/go7007/go7007-v4l2.c | 1503 ++++++++++++++++++++++++++++
32 drivers/staging/go7007/go7007.h | 114 +++
33 drivers/staging/go7007/saa7134-go7007.c | 484 +++++++++
34 drivers/staging/go7007/snd-go7007.c | 305 ++++++
35 drivers/staging/go7007/wis-i2c.h | 55 +
36 drivers/staging/go7007/wis-ov7640.c | 131 +++
37 drivers/staging/go7007/wis-saa7113.c | 363 +++++++
38 drivers/staging/go7007/wis-saa7115.c | 492 +++++++++
39 drivers/staging/go7007/wis-sony-tuner.c | 741 ++++++++++++++
40 drivers/staging/go7007/wis-tw2804.c | 381 +++++++
41 drivers/staging/go7007/wis-tw9903.c | 363 +++++++
42 drivers/staging/go7007/wis-uda1342.c | 136 +++
43 22 files changed, 9269 insertions(+), 0 deletions(-)
44 create mode 100644 drivers/staging/go7007/Kconfig
45 create mode 100644 drivers/staging/go7007/Makefile
46 create mode 100644 drivers/staging/go7007/README
47 create mode 100644 drivers/staging/go7007/go7007-driver.c
48 create mode 100644 drivers/staging/go7007/go7007-fw.c
49 create mode 100644 drivers/staging/go7007/go7007-i2c.c
50 create mode 100644 drivers/staging/go7007/go7007-priv.h
51 create mode 100644 drivers/staging/go7007/go7007-usb.c
52 create mode 100644 drivers/staging/go7007/go7007-v4l2.c
53 create mode 100644 drivers/staging/go7007/go7007.h
54 create mode 100644 drivers/staging/go7007/saa7134-go7007.c
55 create mode 100644 drivers/staging/go7007/snd-go7007.c
56 create mode 100644 drivers/staging/go7007/wis-i2c.h
57 create mode 100644 drivers/staging/go7007/wis-ov7640.c
58 create mode 100644 drivers/staging/go7007/wis-saa7113.c
59 create mode 100644 drivers/staging/go7007/wis-saa7115.c
60 create mode 100644 drivers/staging/go7007/wis-sony-tuner.c
61 create mode 100644 drivers/staging/go7007/wis-tw2804.c
62 create mode 100644 drivers/staging/go7007/wis-tw9903.c
63 create mode 100644 drivers/staging/go7007/wis-uda1342.c
64
65diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
66index 56c73bc..f16bc9c 100644
67--- a/drivers/staging/Kconfig
68+++ b/drivers/staging/Kconfig
69@@ -31,4 +31,6 @@ source "drivers/staging/sxg/Kconfig"
70
71 source "drivers/staging/me4000/Kconfig"
72
73+source "drivers/staging/go7007/Kconfig"
74+
75 endif # STAGING
76diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
77index 97df19b..aa61662 100644
78--- a/drivers/staging/Makefile
79+++ b/drivers/staging/Makefile
80@@ -4,3 +4,4 @@ obj-$(CONFIG_ET131X) += et131x/
81 obj-$(CONFIG_SLICOSS) += slicoss/
82 obj-$(CONFIG_SXG) += sxg/
83 obj-$(CONFIG_ME4000) += me4000/
84+obj-$(CONFIG_VIDEO_GO7007) += go7007/
85diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
86new file mode 100644
87index 0000000..57a121c
88--- /dev/null
89+++ b/drivers/staging/go7007/Kconfig
90@@ -0,0 +1,25 @@
91+config VIDEO_GO7007
92+ tristate "Go 7007 support"
93+ depends on VIDEO_DEV && PCI && I2C && INPUT
94+ select VIDEOBUF_DMA_SG
95+ select VIDEO_IR
96+ select VIDEO_TUNER
97+ select VIDEO_TVEEPROM
98+ select CRC32
99+ default N
100+ ---help---
101+ This is a video4linux driver for some wierd device...
102+
103+ To compile this driver as a module, choose M here: the
104+ module will be called go7007
105+
106+config VIDEO_GO7007_USB
107+ tristate "Go 7007 USB support"
108+ depends on VIDEO_GO7007 && USB
109+ default N
110+ ---help---
111+ This is a video4linux driver for some wierd device...
112+
113+ To compile this driver as a module, choose M here: the
114+ module will be called go7007-usb
115+
116diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
117new file mode 100644
118index 0000000..9b9310c
119--- /dev/null
120+++ b/drivers/staging/go7007/Makefile
121@@ -0,0 +1,18 @@
122+#obj-m += go7007.o go7007-usb.o snd-go7007.o wis-saa7115.o wis-tw9903.o \
123+ wis-uda1342.o wis-sony-tuner.o wis-saa7113.o wis-ov7640.o \
124+ wis-tw2804.o
125+
126+
127+obj-$(CONFIG_VIDEO_GO7007) += go7007.o
128+obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
129+
130+go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o snd-go7007.o
131+
132+
133+#ifneq ($(SAA7134_BUILD),)
134+#obj-m += saa7134-go7007.o
135+#endif
136+
137+EXTRA_CFLAGS += -Idrivers/staging/saa7134
138+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
139+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
140diff --git a/drivers/staging/go7007/README b/drivers/staging/go7007/README
141new file mode 100644
142index 0000000..48f4476
143--- /dev/null
144+++ b/drivers/staging/go7007/README
145@@ -0,0 +1,11 @@
146+Todo:
147+ - checkpatch.pl cleanups
148+ - sparse cleanups
149+ - lots of little modules, should be merged together
150+ and added to the build.
151+ - testing?
152+ - handle churn in v4l layer.
153+
154+Please send patchs to Greg Kroah-Hartman <greg@kroah.com> and Cc: Ross
155+Cohen <rcohen@snurgle.org> as well.
156+
157diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
158new file mode 100644
159index 0000000..5a336ff
160--- /dev/null
161+++ b/drivers/staging/go7007/go7007-driver.c
162@@ -0,0 +1,688 @@
163+/*
164+ * Copyright (C) 2005-2006 Micronas USA Inc.
165+ *
166+ * This program is free software; you can redistribute it and/or modify
167+ * it under the terms of the GNU General Public License (Version 2) as
168+ * published by the Free Software Foundation.
169+ *
170+ * This program is distributed in the hope that it will be useful,
171+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
172+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
173+ * GNU General Public License for more details.
174+ *
175+ * You should have received a copy of the GNU General Public License
176+ * along with this program; if not, write to the Free Software Foundation,
177+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
178+ */
179+
180+#include <linux/module.h>
181+#include <linux/version.h>
182+#include <linux/init.h>
183+#include <linux/delay.h>
184+#include <linux/sched.h>
185+#include <linux/spinlock.h>
186+#include <linux/unistd.h>
187+#include <linux/time.h>
188+#include <linux/mm.h>
189+#include <linux/vmalloc.h>
190+#include <linux/device.h>
191+#include <linux/i2c.h>
192+#include <linux/firmware.h>
193+#include <linux/semaphore.h>
194+#include <linux/uaccess.h>
195+#include <asm/system.h>
196+#include <linux/videodev.h>
197+#include <media/tuner.h>
198+#include <media/v4l2-common.h>
199+
200+#include "go7007-priv.h"
201+#include "wis-i2c.h"
202+
203+/*
204+ * Wait for an interrupt to be delivered from the GO7007SB and return
205+ * the associated value and data.
206+ *
207+ * Must be called with the hw_lock held.
208+ */
209+int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
210+{
211+ go->interrupt_available = 0;
212+ go->hpi_ops->read_interrupt(go);
213+ if (wait_event_timeout(go->interrupt_waitq,
214+ go->interrupt_available, 5*HZ) < 0) {
215+ printk(KERN_ERR "go7007: timeout waiting for read interrupt\n");
216+ return -1;
217+ }
218+ if (!go->interrupt_available)
219+ return -1;
220+ go->interrupt_available = 0;
221+ *value = go->interrupt_value & 0xfffe;
222+ *data = go->interrupt_data;
223+ return 0;
224+}
225+EXPORT_SYMBOL(go7007_read_interrupt);
226+
227+/*
228+ * Read a register/address on the GO7007SB.
229+ *
230+ * Must be called with the hw_lock held.
231+ */
232+int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data)
233+{
234+ int count = 100;
235+ u16 value;
236+
237+ if (go7007_write_interrupt(go, 0x0010, addr) < 0)
238+ return -EIO;
239+ while (count-- > 0) {
240+ if (go7007_read_interrupt(go, &value, data) == 0 &&
241+ value == 0xa000)
242+ return 0;
243+ }
244+ return -EIO;
245+}
246+EXPORT_SYMBOL(go7007_read_addr);
247+
248+/*
249+ * Send the boot firmware to the encoder, which just wakes it up and lets
250+ * us talk to the GPIO pins and on-board I2C adapter.
251+ *
252+ * Must be called with the hw_lock held.
253+ */
254+static int go7007_load_encoder(struct go7007 *go)
255+{
256+ const struct firmware *fw_entry;
257+ char fw_name[] = "go7007fw.bin";
258+ void *bounce;
259+ int fw_len, rv = 0;
260+ u16 intr_val, intr_data;
261+
262+ if (request_firmware(&fw_entry, fw_name, go->dev)) {
263+ printk(KERN_ERR
264+ "go7007: unable to load firmware from file \"%s\"\n",
265+ fw_name);
266+ return -1;
267+ }
268+ if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
269+ printk(KERN_ERR "go7007: file \"%s\" does not appear to be "
270+ "go7007 firmware\n", fw_name);
271+ release_firmware(fw_entry);
272+ return -1;
273+ }
274+ fw_len = fw_entry->size - 16;
275+ bounce = kmalloc(fw_len, GFP_KERNEL);
276+ if (bounce == NULL) {
277+ printk(KERN_ERR "go7007: unable to allocate %d bytes for "
278+ "firmware transfer\n", fw_len);
279+ release_firmware(fw_entry);
280+ return -1;
281+ }
282+ memcpy(bounce, fw_entry->data + 16, fw_len);
283+ release_firmware(fw_entry);
284+ if (go7007_interface_reset(go) < 0 ||
285+ go7007_send_firmware(go, bounce, fw_len) < 0 ||
286+ go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
287+ (intr_val & ~0x1) != 0x5a5a) {
288+ printk(KERN_ERR "go7007: error transferring firmware\n");
289+ rv = -1;
290+ }
291+ kfree(bounce);
292+ return rv;
293+}
294+
295+/*
296+ * Boot the encoder and register the I2C adapter if requested. Do the
297+ * minimum initialization necessary, since the board-specific code may
298+ * still need to probe the board ID.
299+ *
300+ * Must NOT be called with the hw_lock held.
301+ */
302+int go7007_boot_encoder(struct go7007 *go, int init_i2c)
303+{
304+ int ret;
305+
306+ down(&go->hw_lock);
307+ ret = go7007_load_encoder(go);
308+ up(&go->hw_lock);
309+ if (ret < 0)
310+ return -1;
311+ if (!init_i2c)
312+ return 0;
313+ if (go7007_i2c_init(go) < 0)
314+ return -1;
315+ go->i2c_adapter_online = 1;
316+ return 0;
317+}
318+EXPORT_SYMBOL(go7007_boot_encoder);
319+
320+/*
321+ * Configure any hardware-related registers in the GO7007, such as GPIO
322+ * pins and bus parameters, which are board-specific. This assumes
323+ * the boot firmware has already been downloaded.
324+ *
325+ * Must be called with the hw_lock held.
326+ */
327+static int go7007_init_encoder(struct go7007 *go)
328+{
329+ if (go->board_info->audio_flags & GO7007_AUDIO_I2S_MASTER) {
330+ go7007_write_addr(go, 0x1000, 0x0811);
331+ go7007_write_addr(go, 0x1000, 0x0c11);
332+ }
333+ if (go->board_id == GO7007_BOARDID_MATRIX_REV) {
334+ /* Set GPIO pin 0 to be an output (audio clock control) */
335+ go7007_write_addr(go, 0x3c82, 0x0001);
336+ go7007_write_addr(go, 0x3c80, 0x00fe);
337+ }
338+ return 0;
339+}
340+
341+/*
342+ * Send the boot firmware to the GO7007 and configure the registers. This
343+ * is the only way to stop the encoder once it has started streaming video.
344+ *
345+ * Must be called with the hw_lock held.
346+ */
347+int go7007_reset_encoder(struct go7007 *go)
348+{
349+ if (go7007_load_encoder(go) < 0)
350+ return -1;
351+ return go7007_init_encoder(go);
352+}
353+
354+/*
355+ * Attempt to instantiate an I2C client by ID, probably loading a module.
356+ */
357+static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr)
358+{
359+ char *modname;
360+
361+ switch (id) {
362+ case I2C_DRIVERID_WIS_SAA7115:
363+ modname = "wis-saa7115";
364+ break;
365+ case I2C_DRIVERID_WIS_SAA7113:
366+ modname = "wis-saa7113";
367+ break;
368+ case I2C_DRIVERID_WIS_UDA1342:
369+ modname = "wis-uda1342";
370+ break;
371+ case I2C_DRIVERID_WIS_SONY_TUNER:
372+ modname = "wis-sony-tuner";
373+ break;
374+ case I2C_DRIVERID_WIS_TW9903:
375+ modname = "wis-tw9903";
376+ break;
377+ case I2C_DRIVERID_WIS_TW2804:
378+ modname = "wis-tw2804";
379+ break;
380+ case I2C_DRIVERID_WIS_OV7640:
381+ modname = "wis-ov7640";
382+ break;
383+ default:
384+ modname = NULL;
385+ break;
386+ }
387+ if (modname != NULL)
388+ request_module(modname);
389+ if (wis_i2c_probe_device(adapter, id, addr) == 1)
390+ return 0;
391+ if (modname != NULL)
392+ printk(KERN_INFO
393+ "go7007: probing for module %s failed", modname);
394+ else
395+ printk(KERN_INFO
396+ "go7007: sensor %u seems to be unsupported!\n", id);
397+ return -1;
398+}
399+
400+/*
401+ * Finalize the GO7007 hardware setup, register the on-board I2C adapter
402+ * (if used on this board), load the I2C client driver for the sensor
403+ * (SAA7115 or whatever) and other devices, and register the ALSA and V4L2
404+ * interfaces.
405+ *
406+ * Must NOT be called with the hw_lock held.
407+ */
408+int go7007_register_encoder(struct go7007 *go)
409+{
410+ int i, ret;
411+
412+ printk(KERN_INFO "go7007: registering new %s\n", go->name);
413+
414+ down(&go->hw_lock);
415+ ret = go7007_init_encoder(go);
416+ up(&go->hw_lock);
417+ if (ret < 0)
418+ return -1;
419+
420+ if (!go->i2c_adapter_online &&
421+ go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
422+ if (go7007_i2c_init(go) < 0)
423+ return -1;
424+ go->i2c_adapter_online = 1;
425+ }
426+ if (go->i2c_adapter_online) {
427+ for (i = 0; i < go->board_info->num_i2c_devs; ++i)
428+ init_i2c_module(&go->i2c_adapter,
429+ go->board_info->i2c_devs[i].id,
430+ go->board_info->i2c_devs[i].addr);
431+#ifdef TUNER_SET_TYPE_ADDR
432+ if (go->tuner_type >= 0) {
433+ struct tuner_setup tun_setup = {
434+ .mode_mask = T_ANALOG_TV,
435+ .addr = ADDR_UNSET,
436+ .type = go->tuner_type
437+ };
438+ i2c_clients_command(&go->i2c_adapter,
439+ TUNER_SET_TYPE_ADDR, &tun_setup);
440+ }
441+#else
442+ if (go->tuner_type >= 0)
443+ i2c_clients_command(&go->i2c_adapter,
444+ TUNER_SET_TYPE, &go->tuner_type);
445+#endif
446+ if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
447+ i2c_clients_command(&go->i2c_adapter,
448+ DECODER_SET_CHANNEL, &go->channel_number);
449+ }
450+ if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
451+ go->audio_enabled = 1;
452+ go7007_snd_init(go);
453+ }
454+ return go7007_v4l2_init(go);
455+}
456+EXPORT_SYMBOL(go7007_register_encoder);
457+
458+/*
459+ * Send the encode firmware to the encoder, which will cause it
460+ * to immediately start delivering the video and audio streams.
461+ *
462+ * Must be called with the hw_lock held.
463+ */
464+int go7007_start_encoder(struct go7007 *go)
465+{
466+ u8 *fw;
467+ int fw_len, rv = 0, i;
468+ u16 intr_val, intr_data;
469+
470+ go->modet_enable = 0;
471+ if (!go->dvd_mode)
472+ for (i = 0; i < 4; ++i) {
473+ if (go->modet[i].enable) {
474+ go->modet_enable = 1;
475+ continue;
476+ }
477+ go->modet[i].pixel_threshold = 32767;
478+ go->modet[i].motion_threshold = 32767;
479+ go->modet[i].mb_threshold = 32767;
480+ }
481+
482+ if (go7007_construct_fw_image(go, &fw, &fw_len) < 0)
483+ return -1;
484+
485+ if (go7007_send_firmware(go, fw, fw_len) < 0 ||
486+ go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
487+ printk(KERN_ERR "go7007: error transferring firmware\n");
488+ rv = -1;
489+ goto start_error;
490+ }
491+
492+ go->state = STATE_DATA;
493+ go->parse_length = 0;
494+ go->seen_frame = 0;
495+ if (go7007_stream_start(go) < 0) {
496+ printk(KERN_ERR "go7007: error starting stream transfer\n");
497+ rv = -1;
498+ goto start_error;
499+ }
500+
501+start_error:
502+ kfree(fw);
503+ return rv;
504+}
505+
506+/*
507+ * Store a byte in the current video buffer, if there is one.
508+ */
509+static inline void store_byte(struct go7007_buffer *gobuf, u8 byte)
510+{
511+ if (gobuf != NULL && gobuf->bytesused < GO7007_BUF_SIZE) {
512+ unsigned int pgidx = gobuf->offset >> PAGE_SHIFT;
513+ unsigned int pgoff = gobuf->offset & ~PAGE_MASK;
514+
515+ *((u8 *)page_address(gobuf->pages[pgidx]) + pgoff) = byte;
516+ ++gobuf->offset;
517+ ++gobuf->bytesused;
518+ }
519+}
520+
521+/*
522+ * Deliver the last video buffer and get a new one to start writing to.
523+ */
524+static void frame_boundary(struct go7007 *go)
525+{
526+ struct go7007_buffer *gobuf;
527+ int i;
528+
529+ if (go->active_buf) {
530+ if (go->active_buf->modet_active) {
531+ if (go->active_buf->bytesused + 216 < GO7007_BUF_SIZE) {
532+ for (i = 0; i < 216; ++i)
533+ store_byte(go->active_buf,
534+ go->active_map[i]);
535+ go->active_buf->bytesused -= 216;
536+ } else
537+ go->active_buf->modet_active = 0;
538+ }
539+ go->active_buf->state = BUF_STATE_DONE;
540+ wake_up_interruptible(&go->frame_waitq);
541+ go->active_buf = NULL;
542+ }
543+ list_for_each_entry(gobuf, &go->stream, stream)
544+ if (gobuf->state == BUF_STATE_QUEUED) {
545+ gobuf->seq = go->next_seq;
546+ do_gettimeofday(&gobuf->timestamp);
547+ go->active_buf = gobuf;
548+ break;
549+ }
550+ ++go->next_seq;
551+}
552+
553+static void write_bitmap_word(struct go7007 *go)
554+{
555+ int x, y, i, stride = ((go->width >> 4) + 7) >> 3;
556+
557+ for (i = 0; i < 16; ++i) {
558+ y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4);
559+ x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4);
560+ go->active_map[stride * y + (x >> 3)] |=
561+ (go->modet_word & 1) << (x & 0x7);
562+ go->modet_word >>= 1;
563+ }
564+}
565+
566+/*
567+ * Parse a chunk of the video stream into frames. The frames are not
568+ * delimited by the hardware, so we have to parse the frame boundaries
569+ * based on the type of video stream we're receiving.
570+ */
571+void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
572+{
573+ int i, seq_start_code = -1, frame_start_code = -1;
574+
575+ spin_lock(&go->spinlock);
576+
577+ switch (go->format) {
578+ case GO7007_FORMAT_MPEG4:
579+ seq_start_code = 0xB0;
580+ frame_start_code = 0xB6;
581+ break;
582+ case GO7007_FORMAT_MPEG1:
583+ case GO7007_FORMAT_MPEG2:
584+ seq_start_code = 0xB3;
585+ frame_start_code = 0x00;
586+ break;
587+ }
588+
589+ for (i = 0; i < length; ++i) {
590+ if (go->active_buf != NULL &&
591+ go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
592+ printk(KERN_DEBUG "go7007: dropping oversized frame\n");
593+ go->active_buf->offset -= go->active_buf->bytesused;
594+ go->active_buf->bytesused = 0;
595+ go->active_buf->modet_active = 0;
596+ go->active_buf = NULL;
597+ }
598+
599+ switch (go->state) {
600+ case STATE_DATA:
601+ switch (buf[i]) {
602+ case 0x00:
603+ go->state = STATE_00;
604+ break;
605+ case 0xFF:
606+ go->state = STATE_FF;
607+ break;
608+ default:
609+ store_byte(go->active_buf, buf[i]);
610+ break;
611+ }
612+ break;
613+ case STATE_00:
614+ switch (buf[i]) {
615+ case 0x00:
616+ go->state = STATE_00_00;
617+ break;
618+ case 0xFF:
619+ store_byte(go->active_buf, 0x00);
620+ go->state = STATE_FF;
621+ break;
622+ default:
623+ store_byte(go->active_buf, 0x00);
624+ store_byte(go->active_buf, buf[i]);
625+ go->state = STATE_DATA;
626+ break;
627+ }
628+ break;
629+ case STATE_00_00:
630+ switch (buf[i]) {
631+ case 0x00:
632+ store_byte(go->active_buf, 0x00);
633+ /* go->state remains STATE_00_00 */
634+ break;
635+ case 0x01:
636+ go->state = STATE_00_00_01;
637+ break;
638+ case 0xFF:
639+ store_byte(go->active_buf, 0x00);
640+ store_byte(go->active_buf, 0x00);
641+ go->state = STATE_FF;
642+ break;
643+ default:
644+ store_byte(go->active_buf, 0x00);
645+ store_byte(go->active_buf, 0x00);
646+ store_byte(go->active_buf, buf[i]);
647+ go->state = STATE_DATA;
648+ break;
649+ }
650+ break;
651+ case STATE_00_00_01:
652+ /* If this is the start of a new MPEG frame,
653+ * get a new buffer */
654+ if ((go->format == GO7007_FORMAT_MPEG1 ||
655+ go->format == GO7007_FORMAT_MPEG2 ||
656+ go->format == GO7007_FORMAT_MPEG4) &&
657+ (buf[i] == seq_start_code ||
658+ buf[i] == 0xB8 || /* GOP code */
659+ buf[i] == frame_start_code)) {
660+ if (go->active_buf == NULL || go->seen_frame)
661+ frame_boundary(go);
662+ if (buf[i] == frame_start_code) {
663+ if (go->active_buf != NULL)
664+ go->active_buf->frame_offset =
665+ go->active_buf->offset;
666+ go->seen_frame = 1;
667+ } else {
668+ go->seen_frame = 0;
669+ }
670+ }
671+ /* Handle any special chunk types, or just write the
672+ * start code to the (potentially new) buffer */
673+ switch (buf[i]) {
674+ case 0xF5: /* timestamp */
675+ go->parse_length = 12;
676+ go->state = STATE_UNPARSED;
677+ break;
678+ case 0xF6: /* vbi */
679+ go->state = STATE_VBI_LEN_A;
680+ break;
681+ case 0xF8: /* MD map */
682+ go->parse_length = 0;
683+ memset(go->active_map, 0,
684+ sizeof(go->active_map));
685+ go->state = STATE_MODET_MAP;
686+ break;
687+ case 0xFF: /* Potential JPEG start code */
688+ store_byte(go->active_buf, 0x00);
689+ store_byte(go->active_buf, 0x00);
690+ store_byte(go->active_buf, 0x01);
691+ go->state = STATE_FF;
692+ break;
693+ default:
694+ store_byte(go->active_buf, 0x00);
695+ store_byte(go->active_buf, 0x00);
696+ store_byte(go->active_buf, 0x01);
697+ store_byte(go->active_buf, buf[i]);
698+ go->state = STATE_DATA;
699+ break;
700+ }
701+ break;
702+ case STATE_FF:
703+ switch (buf[i]) {
704+ case 0x00:
705+ store_byte(go->active_buf, 0xFF);
706+ go->state = STATE_00;
707+ break;
708+ case 0xFF:
709+ store_byte(go->active_buf, 0xFF);
710+ /* go->state remains STATE_FF */
711+ break;
712+ case 0xD8:
713+ if (go->format == GO7007_FORMAT_MJPEG)
714+ frame_boundary(go);
715+ /* fall through */
716+ default:
717+ store_byte(go->active_buf, 0xFF);
718+ store_byte(go->active_buf, buf[i]);
719+ go->state = STATE_DATA;
720+ break;
721+ }
722+ break;
723+ case STATE_VBI_LEN_A:
724+ go->parse_length = buf[i] << 8;
725+ go->state = STATE_VBI_LEN_B;
726+ break;
727+ case STATE_VBI_LEN_B:
728+ go->parse_length |= buf[i];
729+ if (go->parse_length > 0)
730+ go->state = STATE_UNPARSED;
731+ else
732+ go->state = STATE_DATA;
733+ break;
734+ case STATE_MODET_MAP:
735+ if (go->parse_length < 204) {
736+ if (go->parse_length & 1) {
737+ go->modet_word |= buf[i];
738+ write_bitmap_word(go);
739+ } else
740+ go->modet_word = buf[i] << 8;
741+ } else if (go->parse_length == 207 && go->active_buf) {
742+ go->active_buf->modet_active = buf[i];
743+ }
744+ if (++go->parse_length == 208)
745+ go->state = STATE_DATA;
746+ break;
747+ case STATE_UNPARSED:
748+ if (--go->parse_length == 0)
749+ go->state = STATE_DATA;
750+ break;
751+ }
752+ }
753+
754+ spin_unlock(&go->spinlock);
755+}
756+EXPORT_SYMBOL(go7007_parse_video_stream);
757+
758+/*
759+ * Allocate a new go7007 struct. Used by the hardware-specific probe.
760+ */
761+struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
762+{
763+ struct go7007 *go;
764+ int i;
765+
766+ go = kmalloc(sizeof(struct go7007), GFP_KERNEL);
767+ if (go == NULL)
768+ return NULL;
769+ go->dev = dev;
770+ go->board_info = board;
771+ go->board_id = 0;
772+ go->tuner_type = -1;
773+ go->channel_number = 0;
774+ go->name[0] = 0;
775+ init_MUTEX(&go->hw_lock);
776+ init_waitqueue_head(&go->frame_waitq);
777+ spin_lock_init(&go->spinlock);
778+ go->video_dev = NULL;
779+ go->ref_count = 0;
780+ go->status = STATUS_INIT;
781+ memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
782+ go->i2c_adapter_online = 0;
783+ go->interrupt_available = 0;
784+ init_waitqueue_head(&go->interrupt_waitq);
785+ go->in_use = 0;
786+ go->input = 0;
787+ if (board->sensor_flags & GO7007_SENSOR_TV) {
788+ go->standard = GO7007_STD_NTSC;
789+ go->width = 720;
790+ go->height = 480;
791+ go->sensor_framerate = 30000;
792+ } else {
793+ go->standard = GO7007_STD_OTHER;
794+ go->width = board->sensor_width;
795+ go->height = board->sensor_height;
796+ go->sensor_framerate = board->sensor_framerate;
797+ }
798+ go->encoder_v_offset = board->sensor_v_offset;
799+ go->encoder_h_offset = board->sensor_h_offset;
800+ go->encoder_h_halve = 0;
801+ go->encoder_v_halve = 0;
802+ go->encoder_subsample = 0;
803+ go->streaming = 0;
804+ go->format = GO7007_FORMAT_MJPEG;
805+ go->bitrate = 1500000;
806+ go->fps_scale = 1;
807+ go->pali = 0;
808+ go->aspect_ratio = GO7007_RATIO_1_1;
809+ go->gop_size = 0;
810+ go->ipb = 0;
811+ go->closed_gop = 0;
812+ go->repeat_seqhead = 0;
813+ go->seq_header_enable = 0;
814+ go->gop_header_enable = 0;
815+ go->dvd_mode = 0;
816+ go->interlace_coding = 0;
817+ for (i = 0; i < 4; ++i)
818+ go->modet[i].enable = 0;;
819+ for (i = 0; i < 1624; ++i)
820+ go->modet_map[i] = 0;
821+ go->audio_deliver = NULL;
822+ go->audio_enabled = 0;
823+ INIT_LIST_HEAD(&go->stream);
824+
825+ return go;
826+}
827+EXPORT_SYMBOL(go7007_alloc);
828+
829+/*
830+ * Detach and unregister the encoder. The go7007 struct won't be freed
831+ * until v4l2 finishes releasing its resources and all associated fds are
832+ * closed by applications.
833+ */
834+void go7007_remove(struct go7007 *go)
835+{
836+ if (go->i2c_adapter_online) {
837+ if (i2c_del_adapter(&go->i2c_adapter) == 0)
838+ go->i2c_adapter_online = 0;
839+ else
840+ printk(KERN_ERR
841+ "go7007: error removing I2C adapter!\n");
842+ }
843+
844+ if (go->audio_enabled)
845+ go7007_snd_remove(go);
846+ go7007_v4l2_remove(go);
847+}
848+EXPORT_SYMBOL(go7007_remove);
849+
850+MODULE_LICENSE("GPL v2");
851diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/go7007/go7007-fw.c
852new file mode 100644
853index 0000000..c2aea10
854--- /dev/null
855+++ b/drivers/staging/go7007/go7007-fw.c
856@@ -0,0 +1,1639 @@
857+/*
858+ * Copyright (C) 2005-2006 Micronas USA Inc.
859+ *
860+ * This program is free software; you can redistribute it and/or modify
861+ * it under the terms of the GNU General Public License (Version 2) as
862+ * published by the Free Software Foundation.
863+ *
864+ * This program is distributed in the hope that it will be useful,
865+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
866+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
867+ * GNU General Public License for more details.
868+ *
869+ * You should have received a copy of the GNU General Public License
870+ * along with this program; if not, write to the Free Software Foundation,
871+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
872+ */
873+
874+/*
875+ * This file contains code to generate a firmware image for the GO7007SB
876+ * encoder. Much of the firmware is read verbatim from a file, but some of
877+ * it concerning bitrate control and other things that can be configured at
878+ * run-time are generated dynamically. Note that the format headers
879+ * generated here do not affect the functioning of the encoder; they are
880+ * merely parroted back to the host at the start of each frame.
881+ */
882+
883+#include <linux/module.h>
884+#include <linux/init.h>
885+#include <linux/version.h>
886+#include <linux/time.h>
887+#include <linux/mm.h>
888+#include <linux/device.h>
889+#include <linux/i2c.h>
890+#include <linux/firmware.h>
891+#include <asm/byteorder.h>
892+
893+#include "go7007-priv.h"
894+
895+/* Constants used in the source firmware image to describe code segments */
896+
897+#define FLAG_MODE_MJPEG (1)
898+#define FLAG_MODE_MPEG1 (1<<1)
899+#define FLAG_MODE_MPEG2 (1<<2)
900+#define FLAG_MODE_MPEG4 (1<<3)
901+#define FLAG_MODE_H263 (1<<4)
902+#define FLAG_MODE_ALL (FLAG_MODE_MJPEG | FLAG_MODE_MPEG1 | \
903+ FLAG_MODE_MPEG2 | FLAG_MODE_MPEG4 | \
904+ FLAG_MODE_H263)
905+#define FLAG_SPECIAL (1<<8)
906+
907+#define SPECIAL_FRM_HEAD 0
908+#define SPECIAL_BRC_CTRL 1
909+#define SPECIAL_CONFIG 2
910+#define SPECIAL_SEQHEAD 3
911+#define SPECIAL_AV_SYNC 4
912+#define SPECIAL_FINAL 5
913+#define SPECIAL_AUDIO 6
914+#define SPECIAL_MODET 7
915+
916+/* Little data class for creating MPEG headers bit-by-bit */
917+
918+struct code_gen {
919+ unsigned char *p; /* destination */
920+ u32 a; /* collects bits at the top of the variable */
921+ int b; /* bit position of most recently-written bit */
922+ int len; /* written out so far */
923+};
924+
925+#define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 }
926+
927+#define CODE_ADD(name, val, length) do { \
928+ name.b -= (length); \
929+ name.a |= (val) << name.b; \
930+ while (name.b <= 24) { \
931+ *name.p = name.a >> 24; \
932+ ++name.p; \
933+ name.a <<= 8; \
934+ name.b += 8; \
935+ name.len += 8; \
936+ } \
937+} while (0)
938+
939+#define CODE_LENGTH(name) (name.len + (32 - name.b))
940+
941+/* Tables for creating the bitrate control data */
942+
943+static const s16 converge_speed_ip[101] = {
944+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
945+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
946+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
947+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
948+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
949+ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
950+ 5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
951+ 9, 10, 10, 11, 12, 13, 14, 15, 16, 17,
952+ 19, 20, 22, 23, 25, 27, 30, 32, 35, 38,
953+ 41, 45, 49, 53, 58, 63, 69, 76, 83, 91,
954+ 100
955+};
956+
957+static const s16 converge_speed_ipb[101] = {
958+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
959+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
960+ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
961+ 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
962+ 6, 6, 6, 7, 7, 7, 7, 8, 8, 9,
963+ 9, 9, 10, 10, 11, 12, 12, 13, 14, 14,
964+ 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
965+ 28, 30, 32, 34, 37, 40, 42, 46, 49, 53,
966+ 57, 61, 66, 71, 77, 83, 90, 97, 106, 115,
967+ 125, 135, 147, 161, 175, 191, 209, 228, 249, 273,
968+ 300
969+};
970+
971+static const s16 LAMBDA_table[4][101] = {
972+ { 16, 16, 16, 16, 17, 17, 17, 18, 18, 18,
973+ 19, 19, 19, 20, 20, 20, 21, 21, 22, 22,
974+ 22, 23, 23, 24, 24, 25, 25, 25, 26, 26,
975+ 27, 27, 28, 28, 29, 29, 30, 31, 31, 32,
976+ 32, 33, 33, 34, 35, 35, 36, 37, 37, 38,
977+ 39, 39, 40, 41, 42, 42, 43, 44, 45, 46,
978+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
979+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
980+ 67, 68, 69, 70, 72, 73, 74, 76, 77, 78,
981+ 80, 81, 83, 84, 86, 87, 89, 90, 92, 94,
982+ 96
983+ },
984+ {
985+ 20, 20, 20, 21, 21, 21, 22, 22, 23, 23,
986+ 23, 24, 24, 25, 25, 26, 26, 27, 27, 28,
987+ 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
988+ 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
989+ 40, 41, 42, 43, 43, 44, 45, 46, 47, 48,
990+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
991+ 58, 59, 60, 61, 62, 64, 65, 66, 67, 68,
992+ 70, 71, 72, 73, 75, 76, 78, 79, 80, 82,
993+ 83, 85, 86, 88, 90, 91, 93, 95, 96, 98,
994+ 100, 102, 103, 105, 107, 109, 111, 113, 115, 117,
995+ 120
996+ },
997+ {
998+ 24, 24, 24, 25, 25, 26, 26, 27, 27, 28,
999+ 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
1000+ 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
1001+ 41, 41, 42, 43, 44, 44, 45, 46, 47, 48,
1002+ 49, 50, 50, 51, 52, 53, 54, 55, 56, 57,
1003+ 58, 59, 60, 62, 63, 64, 65, 66, 67, 69,
1004+ 70, 71, 72, 74, 75, 76, 78, 79, 81, 82,
1005+ 84, 85, 87, 88, 90, 92, 93, 95, 97, 98,
1006+ 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
1007+ 120, 122, 124, 127, 129, 131, 134, 136, 138, 141,
1008+ 144
1009+ },
1010+ {
1011+ 32, 32, 33, 33, 34, 34, 35, 36, 36, 37,
1012+ 38, 38, 39, 40, 41, 41, 42, 43, 44, 44,
1013+ 45, 46, 47, 48, 49, 50, 50, 51, 52, 53,
1014+ 54, 55, 56, 57, 58, 59, 60, 62, 63, 64,
1015+ 65, 66, 67, 69, 70, 71, 72, 74, 75, 76,
1016+ 78, 79, 81, 82, 84, 85, 87, 88, 90, 92,
1017+ 93, 95, 97, 98, 100, 102, 104, 106, 108, 110,
1018+ 112, 114, 116, 118, 120, 122, 124, 127, 129, 131,
1019+ 134, 136, 139, 141, 144, 146, 149, 152, 154, 157,
1020+ 160, 163, 166, 169, 172, 175, 178, 181, 185, 188,
1021+ 192
1022+ }
1023+};
1024+
1025+/* MPEG blank frame generation tables */
1026+
1027+enum mpeg_frame_type {
1028+ PFRAME,
1029+ BFRAME_PRE,
1030+ BFRAME_POST,
1031+ BFRAME_BIDIR,
1032+ BFRAME_EMPTY
1033+};
1034+
1035+static const u32 addrinctab[33][2] = {
1036+ { 0x01, 1 }, { 0x03, 3 }, { 0x02, 3 }, { 0x03, 4 },
1037+ { 0x02, 4 }, { 0x03, 5 }, { 0x02, 5 }, { 0x07, 7 },
1038+ { 0x06, 7 }, { 0x0b, 8 }, { 0x0a, 8 }, { 0x09, 8 },
1039+ { 0x08, 8 }, { 0x07, 8 }, { 0x06, 8 }, { 0x17, 10 },
1040+ { 0x16, 10 }, { 0x15, 10 }, { 0x14, 10 }, { 0x13, 10 },
1041+ { 0x12, 10 }, { 0x23, 11 }, { 0x22, 11 }, { 0x21, 11 },
1042+ { 0x20, 11 }, { 0x1f, 11 }, { 0x1e, 11 }, { 0x1d, 11 },
1043+ { 0x1c, 11 }, { 0x1b, 11 }, { 0x1a, 11 }, { 0x19, 11 },
1044+ { 0x18, 11 }
1045+};
1046+
1047+/* Standard JPEG tables */
1048+
1049+static const u8 default_intra_quant_table[] = {
1050+ 8, 16, 19, 22, 26, 27, 29, 34,
1051+ 16, 16, 22, 24, 27, 29, 34, 37,
1052+ 19, 22, 26, 27, 29, 34, 34, 38,
1053+ 22, 22, 26, 27, 29, 34, 37, 40,
1054+ 22, 26, 27, 29, 32, 35, 40, 48,
1055+ 26, 27, 29, 32, 35, 40, 48, 58,
1056+ 26, 27, 29, 34, 38, 46, 56, 69,
1057+ 27, 29, 35, 38, 46, 56, 69, 83
1058+};
1059+
1060+static const u8 bits_dc_luminance[] = {
1061+ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
1062+};
1063+
1064+static const u8 val_dc_luminance[] = {
1065+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
1066+};
1067+
1068+static const u8 bits_dc_chrominance[] = {
1069+ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
1070+};
1071+
1072+static const u8 val_dc_chrominance[] = {
1073+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
1074+};
1075+
1076+static const u8 bits_ac_luminance[] = {
1077+ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
1078+};
1079+
1080+static const u8 val_ac_luminance[] = {
1081+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
1082+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
1083+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
1084+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
1085+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
1086+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
1087+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
1088+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
1089+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
1090+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
1091+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
1092+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
1093+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
1094+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
1095+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
1096+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
1097+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
1098+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
1099+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
1100+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
1101+ 0xf9, 0xfa
1102+};
1103+
1104+static const u8 bits_ac_chrominance[] = {
1105+ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
1106+};
1107+
1108+static const u8 val_ac_chrominance[] = {
1109+ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
1110+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
1111+ 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
1112+ 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
1113+ 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
1114+ 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
1115+ 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
1116+ 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
1117+ 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
1118+ 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
1119+ 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
1120+ 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
1121+ 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
1122+ 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
1123+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
1124+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
1125+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
1126+ 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
1127+ 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
1128+ 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
1129+ 0xf9, 0xfa
1130+};
1131+
1132+/* Zig-zag mapping for quant table
1133+ *
1134+ * OK, let's do this mapping on the actual table above so it doesn't have
1135+ * to be done on the fly.
1136+ */
1137+static const int zz[64] = {
1138+ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
1139+ 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
1140+ 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
1141+ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
1142+};
1143+
1144+static int copy_packages(u16 *dest, u16 *src, int pkg_cnt, int space)
1145+{
1146+ int i, cnt = pkg_cnt * 32;
1147+
1148+ if (space < cnt)
1149+ return -1;
1150+
1151+ for (i = 0; i < cnt; ++i)
1152+ dest[i] = __cpu_to_le16(src[i]);
1153+
1154+ return cnt;
1155+}
1156+
1157+static int mjpeg_frame_header(struct go7007 *go, unsigned char *buf, int q)
1158+{
1159+ int i, p = 0;
1160+
1161+ buf[p++] = 0xff;
1162+ buf[p++] = 0xd8;
1163+ buf[p++] = 0xff;
1164+ buf[p++] = 0xdb;
1165+ buf[p++] = 0;
1166+ buf[p++] = 2 + 65;
1167+ buf[p++] = 0;
1168+ buf[p++] = default_intra_quant_table[0];
1169+ for (i = 1; i < 64; ++i)
1170+ /* buf[p++] = (default_intra_quant_table[i] * q) >> 3; */
1171+ buf[p++] = (default_intra_quant_table[zz[i]] * q) >> 3;
1172+ buf[p++] = 0xff;
1173+ buf[p++] = 0xc0;
1174+ buf[p++] = 0;
1175+ buf[p++] = 17;
1176+ buf[p++] = 8;
1177+ buf[p++] = go->height >> 8;
1178+ buf[p++] = go->height & 0xff;
1179+ buf[p++] = go->width >> 8;
1180+ buf[p++] = go->width & 0xff;
1181+ buf[p++] = 3;
1182+ buf[p++] = 1;
1183+ buf[p++] = 0x22;
1184+ buf[p++] = 0;
1185+ buf[p++] = 2;
1186+ buf[p++] = 0x11;
1187+ buf[p++] = 0;
1188+ buf[p++] = 3;
1189+ buf[p++] = 0x11;
1190+ buf[p++] = 0;
1191+ buf[p++] = 0xff;
1192+ buf[p++] = 0xc4;
1193+ buf[p++] = 418 >> 8;
1194+ buf[p++] = 418 & 0xff;
1195+ buf[p++] = 0x00;
1196+ memcpy(buf + p, bits_dc_luminance + 1, 16);
1197+ p += 16;
1198+ memcpy(buf + p, val_dc_luminance, sizeof(val_dc_luminance));
1199+ p += sizeof(val_dc_luminance);
1200+ buf[p++] = 0x01;
1201+ memcpy(buf + p, bits_dc_chrominance + 1, 16);
1202+ p += 16;
1203+ memcpy(buf + p, val_dc_chrominance, sizeof(val_dc_chrominance));
1204+ p += sizeof(val_dc_chrominance);
1205+ buf[p++] = 0x10;
1206+ memcpy(buf + p, bits_ac_luminance + 1, 16);
1207+ p += 16;
1208+ memcpy(buf + p, val_ac_luminance, sizeof(val_ac_luminance));
1209+ p += sizeof(val_ac_luminance);
1210+ buf[p++] = 0x11;
1211+ memcpy(buf + p, bits_ac_chrominance + 1, 16);
1212+ p += 16;
1213+ memcpy(buf + p, val_ac_chrominance, sizeof(val_ac_chrominance));
1214+ p += sizeof(val_ac_chrominance);
1215+ buf[p++] = 0xff;
1216+ buf[p++] = 0xda;
1217+ buf[p++] = 0;
1218+ buf[p++] = 12;
1219+ buf[p++] = 3;
1220+ buf[p++] = 1;
1221+ buf[p++] = 0x00;
1222+ buf[p++] = 2;
1223+ buf[p++] = 0x11;
1224+ buf[p++] = 3;
1225+ buf[p++] = 0x11;
1226+ buf[p++] = 0;
1227+ buf[p++] = 63;
1228+ buf[p++] = 0;
1229+ return p;
1230+}
1231+
1232+static int gen_mjpeghdr_to_package(struct go7007 *go, u16 *code, int space)
1233+{
1234+ u8 *buf;
1235+ u16 mem = 0x3e00;
1236+ unsigned int addr = 0x19;
1237+ int size = 0, i, off = 0, chunk;
1238+
1239+ buf = kmalloc(4096, GFP_KERNEL);
1240+ if (buf == NULL) {
1241+ printk(KERN_ERR "go7007: unable to allocate 4096 bytes for "
1242+ "firmware construction\n");
1243+ return -1;
1244+ }
1245+ memset(buf, 0, 4096);
1246+
1247+ for (i = 1; i < 32; ++i) {
1248+ mjpeg_frame_header(go, buf + size, i);
1249+ size += 80;
1250+ }
1251+ chunk = mjpeg_frame_header(go, buf + size, 1);
1252+ memmove(buf + size, buf + size + 80, chunk - 80);
1253+ size += chunk - 80;
1254+
1255+ for (i = 0; i < size; i += chunk * 2) {
1256+ if (space - off < 32) {
1257+ off = -1;
1258+ goto done;
1259+ }
1260+
1261+ code[off + 1] = __cpu_to_le16(0x8000 | mem);
1262+
1263+ chunk = 28;
1264+ if (mem + chunk > 0x4000)
1265+ chunk = 0x4000 - mem;
1266+ if (i + 2 * chunk > size)
1267+ chunk = (size - i) / 2;
1268+
1269+ if (chunk < 28) {
1270+ code[off] = __cpu_to_le16(0x4000 | chunk);
1271+ code[off + 31] = __cpu_to_le16(addr++);
1272+ mem = 0x3e00;
1273+ } else {
1274+ code[off] = __cpu_to_le16(0x1000 | 28);
1275+ code[off + 31] = 0;
1276+ mem += 28;
1277+ }
1278+
1279+ memcpy(&code[off + 2], buf + i, chunk * 2);
1280+ off += 32;
1281+ }
1282+done:
1283+ kfree(buf);
1284+ return off;
1285+}
1286+
1287+static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
1288+ int modulo, int pict_struct, enum mpeg_frame_type frame)
1289+{
1290+ int i, j, mb_code, mb_len;
1291+ int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
1292+ CODE_GEN(c, buf + 6);
1293+
1294+ switch (frame) {
1295+ case PFRAME:
1296+ mb_code = 0x1;
1297+ mb_len = 3;
1298+ break;
1299+ case BFRAME_PRE:
1300+ mb_code = 0x2;
1301+ mb_len = 4;
1302+ break;
1303+ case BFRAME_POST:
1304+ mb_code = 0x2;
1305+ mb_len = 3;
1306+ break;
1307+ case BFRAME_BIDIR:
1308+ mb_code = 0x2;
1309+ mb_len = 2;
1310+ break;
1311+ default: /* keep the compiler happy */
1312+ mb_code = mb_len = 0;
1313+ break;
1314+ }
1315+
1316+ CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13);
1317+ CODE_ADD(c, 0xffff, 16);
1318+ CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
1319+ if (frame != PFRAME)
1320+ CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
1321+ else
1322+ CODE_ADD(c, 0, 4); /* Is this supposed to be here?? */
1323+ CODE_ADD(c, 0, 3); /* What is this?? */
1324+ /* Byte-align with zeros */
1325+ j = 8 - (CODE_LENGTH(c) % 8);
1326+ if (j != 8)
1327+ CODE_ADD(c, 0, j);
1328+
1329+ if (go->format == GO7007_FORMAT_MPEG2) {
1330+ CODE_ADD(c, 0x1, 24);
1331+ CODE_ADD(c, 0xb5, 8);
1332+ CODE_ADD(c, 0x844, 12);
1333+ CODE_ADD(c, frame == PFRAME ? 0xff : 0x44, 8);
1334+ if (go->interlace_coding) {
1335+ CODE_ADD(c, pict_struct, 4);
1336+ if (go->dvd_mode)
1337+ CODE_ADD(c, 0x000, 11);
1338+ else
1339+ CODE_ADD(c, 0x200, 11);
1340+ } else {
1341+ CODE_ADD(c, 0x3, 4);
1342+ CODE_ADD(c, 0x20c, 11);
1343+ }
1344+ /* Byte-align with zeros */
1345+ j = 8 - (CODE_LENGTH(c) % 8);
1346+ if (j != 8)
1347+ CODE_ADD(c, 0, j);
1348+ }
1349+
1350+ for (i = 0; i < rows; ++i) {
1351+ CODE_ADD(c, 1, 24);
1352+ CODE_ADD(c, i + 1, 8);
1353+ CODE_ADD(c, 0x2, 6);
1354+ CODE_ADD(c, 0x1, 1);
1355+ CODE_ADD(c, mb_code, mb_len);
1356+ if (go->interlace_coding) {
1357+ CODE_ADD(c, 0x1, 2);
1358+ CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
1359+ }
1360+ if (frame == BFRAME_BIDIR) {
1361+ CODE_ADD(c, 0x3, 2);
1362+ if (go->interlace_coding)
1363+ CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
1364+ }
1365+ CODE_ADD(c, 0x3, 2);
1366+ for (j = (go->width >> 4) - 2; j >= 33; j -= 33)
1367+ CODE_ADD(c, 0x8, 11);
1368+ CODE_ADD(c, addrinctab[j][0], addrinctab[j][1]);
1369+ CODE_ADD(c, mb_code, mb_len);
1370+ if (go->interlace_coding) {
1371+ CODE_ADD(c, 0x1, 2);
1372+ CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
1373+ }
1374+ if (frame == BFRAME_BIDIR) {
1375+ CODE_ADD(c, 0x3, 2);
1376+ if (go->interlace_coding)
1377+ CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
1378+ }
1379+ CODE_ADD(c, 0x3, 2);
1380+
1381+ /* Byte-align with zeros */
1382+ j = 8 - (CODE_LENGTH(c) % 8);
1383+ if (j != 8)
1384+ CODE_ADD(c, 0, j);
1385+ }
1386+
1387+ i = CODE_LENGTH(c) + 4 * 8;
1388+ buf[2] = 0x00;
1389+ buf[3] = 0x00;
1390+ buf[4] = 0x01;
1391+ buf[5] = 0x00;
1392+ return i;
1393+}
1394+
1395+static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
1396+{
1397+ int i, aspect_ratio, picture_rate;
1398+ CODE_GEN(c, buf + 6);
1399+
1400+ if (go->format == GO7007_FORMAT_MPEG1) {
1401+ switch (go->aspect_ratio) {
1402+ case GO7007_RATIO_4_3:
1403+ aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
1404+ break;
1405+ case GO7007_RATIO_16_9:
1406+ aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
1407+ break;
1408+ default:
1409+ aspect_ratio = 1;
1410+ break;
1411+ }
1412+ } else {
1413+ switch (go->aspect_ratio) {
1414+ case GO7007_RATIO_4_3:
1415+ aspect_ratio = 2;
1416+ break;
1417+ case GO7007_RATIO_16_9:
1418+ aspect_ratio = 3;
1419+ break;
1420+ default:
1421+ aspect_ratio = 1;
1422+ break;
1423+ }
1424+ }
1425+ switch (go->sensor_framerate) {
1426+ case 24000:
1427+ picture_rate = 1;
1428+ break;
1429+ case 24024:
1430+ picture_rate = 2;
1431+ break;
1432+ case 25025:
1433+ picture_rate = go->interlace_coding ? 6 : 3;
1434+ break;
1435+ case 30000:
1436+ picture_rate = go->interlace_coding ? 7 : 4;
1437+ break;
1438+ case 30030:
1439+ picture_rate = go->interlace_coding ? 8 : 5;
1440+ break;
1441+ default:
1442+ picture_rate = 5; /* 30 fps seems like a reasonable default */
1443+ break;
1444+ }
1445+
1446+ CODE_ADD(c, go->width, 12);
1447+ CODE_ADD(c, go->height, 12);
1448+ CODE_ADD(c, aspect_ratio, 4);
1449+ CODE_ADD(c, picture_rate, 4);
1450+ CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 20000 : 0x3ffff, 18);
1451+ CODE_ADD(c, 1, 1);
1452+ CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 112 : 20, 10);
1453+ CODE_ADD(c, 0, 3);
1454+
1455+ /* Byte-align with zeros */
1456+ i = 8 - (CODE_LENGTH(c) % 8);
1457+ if (i != 8)
1458+ CODE_ADD(c, 0, i);
1459+
1460+ if (go->format == GO7007_FORMAT_MPEG2) {
1461+ CODE_ADD(c, 0x1, 24);
1462+ CODE_ADD(c, 0xb5, 8);
1463+ CODE_ADD(c, 0x148, 12);
1464+ if (go->interlace_coding)
1465+ CODE_ADD(c, 0x20001, 20);
1466+ else
1467+ CODE_ADD(c, 0xa0001, 20);
1468+ CODE_ADD(c, 0, 16);
1469+
1470+ /* Byte-align with zeros */
1471+ i = 8 - (CODE_LENGTH(c) % 8);
1472+ if (i != 8)
1473+ CODE_ADD(c, 0, i);
1474+
1475+ if (ext) {
1476+ CODE_ADD(c, 0x1, 24);
1477+ CODE_ADD(c, 0xb52, 12);
1478+ CODE_ADD(c, go->standard == GO7007_STD_NTSC ? 2 : 1, 3);
1479+ CODE_ADD(c, 0x105, 9);
1480+ CODE_ADD(c, 0x505, 16);
1481+ CODE_ADD(c, go->width, 14);
1482+ CODE_ADD(c, 1, 1);
1483+ CODE_ADD(c, go->height, 14);
1484+
1485+ /* Byte-align with zeros */
1486+ i = 8 - (CODE_LENGTH(c) % 8);
1487+ if (i != 8)
1488+ CODE_ADD(c, 0, i);
1489+ }
1490+ }
1491+
1492+ i = CODE_LENGTH(c) + 4 * 8;
1493+ buf[0] = i & 0xff;
1494+ buf[1] = i >> 8;
1495+ buf[2] = 0x00;
1496+ buf[3] = 0x00;
1497+ buf[4] = 0x01;
1498+ buf[5] = 0xb3;
1499+ return i;
1500+}
1501+
1502+static int gen_mpeg1hdr_to_package(struct go7007 *go,
1503+ u16 *code, int space, int *framelen)
1504+{
1505+ u8 *buf;
1506+ u16 mem = 0x3e00;
1507+ unsigned int addr = 0x19;
1508+ int i, off = 0, chunk;
1509+
1510+ buf = kmalloc(5120, GFP_KERNEL);
1511+ if (buf == NULL) {
1512+ printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
1513+ "firmware construction\n");
1514+ return -1;
1515+ }
1516+ memset(buf, 0, 5120);
1517+ framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME);
1518+ if (go->interlace_coding)
1519+ framelen[0] += mpeg1_frame_header(go, buf + framelen[0] / 8,
1520+ 0, 2, PFRAME);
1521+ buf[0] = framelen[0] & 0xff;
1522+ buf[1] = framelen[0] >> 8;
1523+ i = 368;
1524+ framelen[1] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_PRE);
1525+ if (go->interlace_coding)
1526+ framelen[1] += mpeg1_frame_header(go, buf + i + framelen[1] / 8,
1527+ 0, 2, BFRAME_PRE);
1528+ buf[i] = framelen[1] & 0xff;
1529+ buf[i + 1] = framelen[1] >> 8;
1530+ i += 1632;
1531+ framelen[2] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_POST);
1532+ if (go->interlace_coding)
1533+ framelen[2] += mpeg1_frame_header(go, buf + i + framelen[2] / 8,
1534+ 0, 2, BFRAME_POST);
1535+ buf[i] = framelen[2] & 0xff;
1536+ buf[i + 1] = framelen[2] >> 8;
1537+ i += 1432;
1538+ framelen[3] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_BIDIR);
1539+ if (go->interlace_coding)
1540+ framelen[3] += mpeg1_frame_header(go, buf + i + framelen[3] / 8,
1541+ 0, 2, BFRAME_BIDIR);
1542+ buf[i] = framelen[3] & 0xff;
1543+ buf[i + 1] = framelen[3] >> 8;
1544+ i += 1632 + 16;
1545+ mpeg1_sequence_header(go, buf + i, 0);
1546+ i += 40;
1547+ for (i = 0; i < 5120; i += chunk * 2) {
1548+ if (space - off < 32) {
1549+ off = -1;
1550+ goto done;
1551+ }
1552+
1553+ code[off + 1] = __cpu_to_le16(0x8000 | mem);
1554+
1555+ chunk = 28;
1556+ if (mem + chunk > 0x4000)
1557+ chunk = 0x4000 - mem;
1558+ if (i + 2 * chunk > 5120)
1559+ chunk = (5120 - i) / 2;
1560+
1561+ if (chunk < 28) {
1562+ code[off] = __cpu_to_le16(0x4000 | chunk);
1563+ code[off + 31] = __cpu_to_le16(addr);
1564+ if (mem + chunk == 0x4000) {
1565+ mem = 0x3e00;
1566+ ++addr;
1567+ }
1568+ } else {
1569+ code[off] = __cpu_to_le16(0x1000 | 28);
1570+ code[off + 31] = 0;
1571+ mem += 28;
1572+ }
1573+
1574+ memcpy(&code[off + 2], buf + i, chunk * 2);
1575+ off += 32;
1576+ }
1577+done:
1578+ kfree(buf);
1579+ return off;
1580+}
1581+
1582+static int vti_bitlen(struct go7007 *go)
1583+{
1584+ unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
1585+
1586+ for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i);
1587+ return i + 1;
1588+}
1589+
1590+static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
1591+ int modulo, enum mpeg_frame_type frame)
1592+{
1593+ int i;
1594+ CODE_GEN(c, buf + 6);
1595+ int mb_count = (go->width >> 4) * (go->height >> 4);
1596+
1597+ CODE_ADD(c, frame == PFRAME ? 0x1 : 0x2, 2);
1598+ if (modulo)
1599+ CODE_ADD(c, 0x1, 1);
1600+ CODE_ADD(c, 0x1, 2);
1601+ CODE_ADD(c, 0, vti_bitlen(go));
1602+ CODE_ADD(c, 0x3, 2);
1603+ if (frame == PFRAME)
1604+ CODE_ADD(c, 0, 1);
1605+ CODE_ADD(c, 0xc, 11);
1606+ if (frame != PFRAME)
1607+ CODE_ADD(c, 0x4, 3);
1608+ if (frame != BFRAME_EMPTY) {
1609+ for (i = 0; i < mb_count; ++i) {
1610+ switch (frame) {
1611+ case PFRAME:
1612+ CODE_ADD(c, 0x1, 1);
1613+ break;
1614+ case BFRAME_PRE:
1615+ CODE_ADD(c, 0x47, 8);
1616+ break;
1617+ case BFRAME_POST:
1618+ CODE_ADD(c, 0x27, 7);
1619+ break;
1620+ case BFRAME_BIDIR:
1621+ CODE_ADD(c, 0x5f, 8);
1622+ break;
1623+ case BFRAME_EMPTY: /* keep compiler quiet */
1624+ break;
1625+ }
1626+ }
1627+ }
1628+
1629+ /* Byte-align with a zero followed by ones */
1630+ i = 8 - (CODE_LENGTH(c) % 8);
1631+ CODE_ADD(c, 0, 1);
1632+ CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
1633+
1634+ i = CODE_LENGTH(c) + 4 * 8;
1635+ buf[0] = i & 0xff;
1636+ buf[1] = i >> 8;
1637+ buf[2] = 0x00;
1638+ buf[3] = 0x00;
1639+ buf[4] = 0x01;
1640+ buf[5] = 0xb6;
1641+ return i;
1642+}
1643+
1644+static int mpeg4_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
1645+{
1646+ const unsigned char head[] = { 0x00, 0x00, 0x01, 0xb0, go->pali,
1647+ 0x00, 0x00, 0x01, 0xb5, 0x09,
1648+ 0x00, 0x00, 0x01, 0x00,
1649+ 0x00, 0x00, 0x01, 0x20, };
1650+ int i, aspect_ratio;
1651+ int fps = go->sensor_framerate / go->fps_scale;
1652+ CODE_GEN(c, buf + 2 + sizeof(head));
1653+
1654+ switch (go->aspect_ratio) {
1655+ case GO7007_RATIO_4_3:
1656+ aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
1657+ break;
1658+ case GO7007_RATIO_16_9:
1659+ aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
1660+ break;
1661+ default:
1662+ aspect_ratio = 1;
1663+ break;
1664+ }
1665+
1666+ memcpy(buf + 2, head, sizeof(head));
1667+ CODE_ADD(c, 0x191, 17);
1668+ CODE_ADD(c, aspect_ratio, 4);
1669+ CODE_ADD(c, 0x1, 4);
1670+ CODE_ADD(c, fps, 16);
1671+ CODE_ADD(c, 0x3, 2);
1672+ CODE_ADD(c, 1001, vti_bitlen(go));
1673+ CODE_ADD(c, 1, 1);
1674+ CODE_ADD(c, go->width, 13);
1675+ CODE_ADD(c, 1, 1);
1676+ CODE_ADD(c, go->height, 13);
1677+ CODE_ADD(c, 0x2830, 14);
1678+
1679+ /* Byte-align */
1680+ i = 8 - (CODE_LENGTH(c) % 8);
1681+ CODE_ADD(c, 0, 1);
1682+ CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
1683+
1684+ i = CODE_LENGTH(c) + sizeof(head) * 8;
1685+ buf[0] = i & 0xff;
1686+ buf[1] = i >> 8;
1687+ return i;
1688+}
1689+
1690+static int gen_mpeg4hdr_to_package(struct go7007 *go,
1691+ u16 *code, int space, int *framelen)
1692+{
1693+ u8 *buf;
1694+ u16 mem = 0x3e00;
1695+ unsigned int addr = 0x19;
1696+ int i, off = 0, chunk;
1697+
1698+ buf = kmalloc(5120, GFP_KERNEL);
1699+ if (buf == NULL) {
1700+ printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
1701+ "firmware construction\n");
1702+ return -1;
1703+ }
1704+ memset(buf, 0, 5120);
1705+ framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME);
1706+ i = 368;
1707+ framelen[1] = mpeg4_frame_header(go, buf + i, 0, BFRAME_PRE);
1708+ i += 1632;
1709+ framelen[2] = mpeg4_frame_header(go, buf + i, 0, BFRAME_POST);
1710+ i += 1432;
1711+ framelen[3] = mpeg4_frame_header(go, buf + i, 0, BFRAME_BIDIR);
1712+ i += 1632;
1713+ mpeg4_frame_header(go, buf + i, 0, BFRAME_EMPTY);
1714+ i += 16;
1715+ mpeg4_sequence_header(go, buf + i, 0);
1716+ i += 40;
1717+ for (i = 0; i < 5120; i += chunk * 2) {
1718+ if (space - off < 32) {
1719+ off = -1;
1720+ goto done;
1721+ }
1722+
1723+ code[off + 1] = __cpu_to_le16(0x8000 | mem);
1724+
1725+ chunk = 28;
1726+ if (mem + chunk > 0x4000)
1727+ chunk = 0x4000 - mem;
1728+ if (i + 2 * chunk > 5120)
1729+ chunk = (5120 - i) / 2;
1730+
1731+ if (chunk < 28) {
1732+ code[off] = __cpu_to_le16(0x4000 | chunk);
1733+ code[off + 31] = __cpu_to_le16(addr);
1734+ if (mem + chunk == 0x4000) {
1735+ mem = 0x3e00;
1736+ ++addr;
1737+ }
1738+ } else {
1739+ code[off] = __cpu_to_le16(0x1000 | 28);
1740+ code[off + 31] = 0;
1741+ mem += 28;
1742+ }
1743+
1744+ memcpy(&code[off + 2], buf + i, chunk * 2);
1745+ off += 32;
1746+ }
1747+ mem = 0x3e00;
1748+ addr = go->ipb ? 0x14f9 : 0x0af9;
1749+ memset(buf, 0, 5120);
1750+ framelen[4] = mpeg4_frame_header(go, buf, 1, PFRAME);
1751+ i = 368;
1752+ framelen[5] = mpeg4_frame_header(go, buf + i, 1, BFRAME_PRE);
1753+ i += 1632;
1754+ framelen[6] = mpeg4_frame_header(go, buf + i, 1, BFRAME_POST);
1755+ i += 1432;
1756+ framelen[7] = mpeg4_frame_header(go, buf + i, 1, BFRAME_BIDIR);
1757+ i += 1632;
1758+ mpeg4_frame_header(go, buf + i, 1, BFRAME_EMPTY);
1759+ i += 16;
1760+ for (i = 0; i < 5120; i += chunk * 2) {
1761+ if (space - off < 32) {
1762+ off = -1;
1763+ goto done;
1764+ }
1765+
1766+ code[off + 1] = __cpu_to_le16(0x8000 | mem);
1767+
1768+ chunk = 28;
1769+ if (mem + chunk > 0x4000)
1770+ chunk = 0x4000 - mem;
1771+ if (i + 2 * chunk > 5120)
1772+ chunk = (5120 - i) / 2;
1773+
1774+ if (chunk < 28) {
1775+ code[off] = __cpu_to_le16(0x4000 | chunk);
1776+ code[off + 31] = __cpu_to_le16(addr);
1777+ if (mem + chunk == 0x4000) {
1778+ mem = 0x3e00;
1779+ ++addr;
1780+ }
1781+ } else {
1782+ code[off] = __cpu_to_le16(0x1000 | 28);
1783+ code[off + 31] = 0;
1784+ mem += 28;
1785+ }
1786+
1787+ memcpy(&code[off + 2], buf + i, chunk * 2);
1788+ off += 32;
1789+ }
1790+done:
1791+ kfree(buf);
1792+ return off;
1793+}
1794+
1795+static int brctrl_to_package(struct go7007 *go,
1796+ u16 *code, int space, int *framelen)
1797+{
1798+ int converge_speed = 0;
1799+ int lambda = (go->format == GO7007_FORMAT_MJPEG || go->dvd_mode) ?
1800+ 100 : 0;
1801+ int peak_rate = 6 * go->bitrate / 5;
1802+ int vbv_buffer = go->format == GO7007_FORMAT_MJPEG ?
1803+ go->bitrate :
1804+ (go->dvd_mode ? 900000 : peak_rate);
1805+ int fps = go->sensor_framerate / go->fps_scale;
1806+ int q = 0;
1807+ /* Bizarre math below depends on rounding errors in division */
1808+ u32 sgop_expt_addr = go->bitrate / 32 * (go->ipb ? 3 : 1) * 1001 / fps;
1809+ u32 sgop_peak_addr = peak_rate / 32 * 1001 / fps;
1810+ u32 total_expt_addr = go->bitrate / 32 * 1000 / fps * (fps / 1000);
1811+ u32 vbv_alert_addr = vbv_buffer * 3 / (4 * 32);
1812+ u32 cplx[] = {
1813+ q > 0 ? sgop_expt_addr * q :
1814+ 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
1815+ q > 0 ? sgop_expt_addr * q :
1816+ 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
1817+ q > 0 ? sgop_expt_addr * q :
1818+ 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
1819+ q > 0 ? sgop_expt_addr * q :
1820+ 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
1821+ };
1822+ u32 calc_q = q > 0 ? q : cplx[0] / sgop_expt_addr;
1823+ u16 pack[] = {
1824+ 0x200e, 0x0000,
1825+ 0xBF20, go->ipb ? converge_speed_ipb[converge_speed]
1826+ : converge_speed_ip[converge_speed],
1827+ 0xBF21, go->ipb ? 2 : 0,
1828+ 0xBF22, go->ipb ? LAMBDA_table[0][lambda / 2 + 50]
1829+ : 32767,
1830+ 0xBF23, go->ipb ? LAMBDA_table[1][lambda] : 32767,
1831+ 0xBF24, 32767,
1832+ 0xBF25, lambda > 99 ? 32767 : LAMBDA_table[3][lambda],
1833+ 0xBF26, sgop_expt_addr & 0x0000FFFF,
1834+ 0xBF27, sgop_expt_addr >> 16,
1835+ 0xBF28, sgop_peak_addr & 0x0000FFFF,
1836+ 0xBF29, sgop_peak_addr >> 16,
1837+ 0xBF2A, vbv_alert_addr & 0x0000FFFF,
1838+ 0xBF2B, vbv_alert_addr >> 16,
1839+ 0xBF2C, 0,
1840+ 0xBF2D, 0,
1841+ 0, 0,
1842+
1843+ 0x200e, 0x0000,
1844+ 0xBF2E, vbv_alert_addr & 0x0000FFFF,
1845+ 0xBF2F, vbv_alert_addr >> 16,
1846+ 0xBF30, cplx[0] & 0x0000FFFF,
1847+ 0xBF31, cplx[0] >> 16,
1848+ 0xBF32, cplx[1] & 0x0000FFFF,
1849+ 0xBF33, cplx[1] >> 16,
1850+ 0xBF34, cplx[2] & 0x0000FFFF,
1851+ 0xBF35, cplx[2] >> 16,
1852+ 0xBF36, cplx[3] & 0x0000FFFF,
1853+ 0xBF37, cplx[3] >> 16,
1854+ 0xBF38, 0,
1855+ 0xBF39, 0,
1856+ 0xBF3A, total_expt_addr & 0x0000FFFF,
1857+ 0xBF3B, total_expt_addr >> 16,
1858+ 0, 0,
1859+
1860+ 0x200e, 0x0000,
1861+ 0xBF3C, total_expt_addr & 0x0000FFFF,
1862+ 0xBF3D, total_expt_addr >> 16,
1863+ 0xBF3E, 0,
1864+ 0xBF3F, 0,
1865+ 0xBF48, 0,
1866+ 0xBF49, 0,
1867+ 0xBF4A, calc_q < 4 ? 4 : (calc_q > 124 ? 124 : calc_q),
1868+ 0xBF4B, 4,
1869+ 0xBF4C, 0,
1870+ 0xBF4D, 0,
1871+ 0xBF4E, 0,
1872+ 0xBF4F, 0,
1873+ 0xBF50, 0,
1874+ 0xBF51, 0,
1875+ 0, 0,
1876+
1877+ 0x200e, 0x0000,
1878+ 0xBF40, sgop_expt_addr & 0x0000FFFF,
1879+ 0xBF41, sgop_expt_addr >> 16,
1880+ 0xBF42, 0,
1881+ 0xBF43, 0,
1882+ 0xBF44, 0,
1883+ 0xBF45, 0,
1884+ 0xBF46, (go->width >> 4) * (go->height >> 4),
1885+ 0xBF47, 0,
1886+ 0xBF64, 0,
1887+ 0xBF65, 0,
1888+ 0xBF18, framelen[4],
1889+ 0xBF19, framelen[5],
1890+ 0xBF1A, framelen[6],
1891+ 0xBF1B, framelen[7],
1892+ 0, 0,
1893+
1894+#if 0 /* Remove once we don't care about matching */
1895+ 0x200e, 0x0000,
1896+ 0xBF56, 4,
1897+ 0xBF57, 0,
1898+ 0xBF58, 5,
1899+ 0xBF59, 0,
1900+ 0xBF5A, 6,
1901+ 0xBF5B, 0,
1902+ 0xBF5C, 8,
1903+ 0xBF5D, 0,
1904+ 0xBF5E, 1,
1905+ 0xBF5F, 0,
1906+ 0xBF60, 1,
1907+ 0xBF61, 0,
1908+ 0xBF62, 0,
1909+ 0xBF63, 0,
1910+ 0, 0,
1911+#else
1912+ 0x2008, 0x0000,
1913+ 0xBF56, 4,
1914+ 0xBF57, 0,
1915+ 0xBF58, 5,
1916+ 0xBF59, 0,
1917+ 0xBF5A, 6,
1918+ 0xBF5B, 0,
1919+ 0xBF5C, 8,
1920+ 0xBF5D, 0,
1921+ 0, 0,
1922+ 0, 0,
1923+ 0, 0,
1924+ 0, 0,
1925+ 0, 0,
1926+ 0, 0,
1927+ 0, 0,
1928+#endif
1929+
1930+ 0x200e, 0x0000,
1931+ 0xBF10, 0,
1932+ 0xBF11, 0,
1933+ 0xBF12, 0,
1934+ 0xBF13, 0,
1935+ 0xBF14, 0,
1936+ 0xBF15, 0,
1937+ 0xBF16, 0,
1938+ 0xBF17, 0,
1939+ 0xBF7E, 0,
1940+ 0xBF7F, 1,
1941+ 0xBF52, framelen[0],
1942+ 0xBF53, framelen[1],
1943+ 0xBF54, framelen[2],
1944+ 0xBF55, framelen[3],
1945+ 0, 0,
1946+ };
1947+
1948+ return copy_packages(code, pack, 6, space);
1949+}
1950+
1951+static int config_package(struct go7007 *go, u16 *code, int space)
1952+{
1953+ int fps = go->sensor_framerate / go->fps_scale / 1000;
1954+ int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
1955+ int brc_window_size = fps;
1956+ int q_min = 2, q_max = 31;
1957+ int THACCoeffSet0 = 0;
1958+ u16 pack[] = {
1959+ 0x200e, 0x0000,
1960+ 0xc002, 0x14b4,
1961+ 0xc003, 0x28b4,
1962+ 0xc004, 0x3c5a,
1963+ 0xdc05, 0x2a77,
1964+ 0xc6c3, go->format == GO7007_FORMAT_MPEG4 ? 0 :
1965+ (go->format == GO7007_FORMAT_H263 ? 0 : 1),
1966+ 0xc680, go->format == GO7007_FORMAT_MPEG4 ? 0xf1 :
1967+ (go->format == GO7007_FORMAT_H263 ? 0x61 :
1968+ 0xd3),
1969+ 0xc780, 0x0140,
1970+ 0xe009, 0x0001,
1971+ 0xc60f, 0x0008,
1972+ 0xd4ff, 0x0002,
1973+ 0xe403, 2340,
1974+ 0xe406, 75,
1975+ 0xd411, 0x0001,
1976+ 0xd410, 0xa1d6,
1977+ 0x0001, 0x2801,
1978+
1979+ 0x200d, 0x0000,
1980+ 0xe402, 0x018b,
1981+ 0xe401, 0x8b01,
1982+ 0xd472, (go->board_info->sensor_flags &
1983+ GO7007_SENSOR_TV) &&
1984+ (!go->interlace_coding) ?
1985+ 0x01b0 : 0x0170,
1986+ 0xd475, (go->board_info->sensor_flags &
1987+ GO7007_SENSOR_TV) &&
1988+ (!go->interlace_coding) ?
1989+ 0x0008 : 0x0009,
1990+ 0xc404, go->interlace_coding ? 0x44 :
1991+ (go->format == GO7007_FORMAT_MPEG4 ? 0x11 :
1992+ (go->format == GO7007_FORMAT_MPEG1 ? 0x02 :
1993+ (go->format == GO7007_FORMAT_MPEG2 ? 0x04 :
1994+ (go->format == GO7007_FORMAT_H263 ? 0x08 :
1995+ 0x20)))),
1996+ 0xbf0a, (go->format == GO7007_FORMAT_MPEG4 ? 8 :
1997+ (go->format == GO7007_FORMAT_MPEG1 ? 1 :
1998+ (go->format == GO7007_FORMAT_MPEG2 ? 2 :
1999+ (go->format == GO7007_FORMAT_H263 ? 4 : 16)))) |
2000+ ((go->repeat_seqhead ? 1 : 0) << 6) |
2001+ ((go->dvd_mode ? 1 : 0) << 9) |
2002+ ((go->gop_header_enable ? 1 : 0) << 10),
2003+ 0xbf0b, 0,
2004+ 0xdd5a, go->ipb ? 0x14 : 0x0a,
2005+ 0xbf0c, 0,
2006+ 0xbf0d, 0,
2007+ 0xc683, THACCoeffSet0,
2008+ 0xc40a, (go->width << 4) | rows,
2009+ 0xe01a, go->board_info->hpi_buffer_cap,
2010+ 0, 0,
2011+ 0, 0,
2012+
2013+ 0x2008, 0,
2014+ 0xe402, 0x88,
2015+ 0xe401, 0x8f01,
2016+ 0xbf6a, 0,
2017+ 0xbf6b, 0,
2018+ 0xbf6c, 0,
2019+ 0xbf6d, 0,
2020+ 0xbf6e, 0,
2021+ 0xbf6f, 0,
2022+ 0, 0,
2023+ 0, 0,
2024+ 0, 0,
2025+ 0, 0,
2026+ 0, 0,
2027+ 0, 0,
2028+ 0, 0,
2029+
2030+ 0x200e, 0,
2031+ 0xbf66, brc_window_size,
2032+ 0xbf67, 0,
2033+ 0xbf68, q_min,
2034+ 0xbf69, q_max,
2035+ 0xbfe0, 0,
2036+ 0xbfe1, 0,
2037+ 0xbfe2, 0,
2038+ 0xbfe3, go->ipb ? 3 : 1,
2039+ 0xc031, go->board_info->sensor_flags &
2040+ GO7007_SENSOR_VBI ? 1 : 0,
2041+ 0xc01c, 0x1f,
2042+ 0xdd8c, 0x15,
2043+ 0xdd94, 0x15,
2044+ 0xdd88, go->ipb ? 0x1401 : 0x0a01,
2045+ 0xdd90, go->ipb ? 0x1401 : 0x0a01,
2046+ 0, 0,
2047+
2048+ 0x200e, 0,
2049+ 0xbfe4, 0,
2050+ 0xbfe5, 0,
2051+ 0xbfe6, 0,
2052+ 0xbfe7, fps << 8,
2053+ 0xbfe8, 0x3a00,
2054+ 0xbfe9, 0,
2055+ 0xbfea, 0,
2056+ 0xbfeb, 0,
2057+ 0xbfec, (go->interlace_coding ? 1 << 15 : 0) |
2058+ (go->modet_enable ? 0xa : 0) |
2059+ (go->board_info->sensor_flags &
2060+ GO7007_SENSOR_VBI ? 1 : 0),
2061+ 0xbfed, 0,
2062+ 0xbfee, 0,
2063+ 0xbfef, 0,
2064+ 0xbff0, go->board_info->sensor_flags &
2065+ GO7007_SENSOR_TV ? 0xf060 : 0xb060,
2066+ 0xbff1, 0,
2067+ 0, 0,
2068+ };
2069+
2070+ return copy_packages(code, pack, 5, space);
2071+}
2072+
2073+static int seqhead_to_package(struct go7007 *go, u16 *code, int space,
2074+ int (*sequence_header_func)(struct go7007 *go,
2075+ unsigned char *buf, int ext))
2076+{
2077+ int vop_time_increment_bitlength = vti_bitlen(go);
2078+ int fps = go->sensor_framerate / go->fps_scale *
2079+ (go->interlace_coding ? 2 : 1);
2080+ unsigned char buf[40] = { };
2081+ int len = sequence_header_func(go, buf, 1);
2082+ u16 pack[] = {
2083+ 0x2006, 0,
2084+ 0xbf08, fps,
2085+ 0xbf09, 0,
2086+ 0xbff2, vop_time_increment_bitlength,
2087+ 0xbff3, (1 << vop_time_increment_bitlength) - 1,
2088+ 0xbfe6, 0,
2089+ 0xbfe7, (fps / 1000) << 8,
2090+ 0, 0,
2091+ 0, 0,
2092+ 0, 0,
2093+ 0, 0,
2094+ 0, 0,
2095+ 0, 0,
2096+ 0, 0,
2097+ 0, 0,
2098+ 0, 0,
2099+
2100+ 0x2007, 0,
2101+ 0xc800, buf[2] << 8 | buf[3],
2102+ 0xc801, buf[4] << 8 | buf[5],
2103+ 0xc802, buf[6] << 8 | buf[7],
2104+ 0xc803, buf[8] << 8 | buf[9],
2105+ 0xc406, 64,
2106+ 0xc407, len - 64,
2107+ 0xc61b, 1,
2108+ 0, 0,
2109+ 0, 0,
2110+ 0, 0,
2111+ 0, 0,
2112+ 0, 0,
2113+ 0, 0,
2114+ 0, 0,
2115+ 0, 0,
2116+
2117+ 0x200e, 0,
2118+ 0xc808, buf[10] << 8 | buf[11],
2119+ 0xc809, buf[12] << 8 | buf[13],
2120+ 0xc80a, buf[14] << 8 | buf[15],
2121+ 0xc80b, buf[16] << 8 | buf[17],
2122+ 0xc80c, buf[18] << 8 | buf[19],
2123+ 0xc80d, buf[20] << 8 | buf[21],
2124+ 0xc80e, buf[22] << 8 | buf[23],
2125+ 0xc80f, buf[24] << 8 | buf[25],
2126+ 0xc810, buf[26] << 8 | buf[27],
2127+ 0xc811, buf[28] << 8 | buf[29],
2128+ 0xc812, buf[30] << 8 | buf[31],
2129+ 0xc813, buf[32] << 8 | buf[33],
2130+ 0xc814, buf[34] << 8 | buf[35],
2131+ 0xc815, buf[36] << 8 | buf[37],
2132+ 0, 0,
2133+ 0, 0,
2134+ 0, 0,
2135+ };
2136+
2137+ return copy_packages(code, pack, 3, space);
2138+}
2139+
2140+static int relative_prime(int big, int little)
2141+{
2142+ int remainder;
2143+
2144+ while (little != 0) {
2145+ remainder = big % little;
2146+ big = little;
2147+ little = remainder;
2148+ }
2149+ return big;
2150+}
2151+
2152+static int avsync_to_package(struct go7007 *go, u16 *code, int space)
2153+{
2154+ int arate = go->board_info->audio_rate * 1001 * go->fps_scale;
2155+ int ratio = arate / go->sensor_framerate;
2156+ int adjratio = ratio * 215 / 100;
2157+ int rprime = relative_prime(go->sensor_framerate,
2158+ arate % go->sensor_framerate);
2159+ int f1 = (arate % go->sensor_framerate) / rprime;
2160+ int f2 = (go->sensor_framerate - arate % go->sensor_framerate) / rprime;
2161+ u16 pack[] = {
2162+ 0x200e, 0,
2163+ 0xbf98, (u16)((-adjratio) & 0xffff),
2164+ 0xbf99, (u16)((-adjratio) >> 16),
2165+ 0xbf92, 0,
2166+ 0xbf93, 0,
2167+ 0xbff4, f1 > f2 ? f1 : f2,
2168+ 0xbff5, f1 < f2 ? f1 : f2,
2169+ 0xbff6, f1 < f2 ? ratio : ratio + 1,
2170+ 0xbff7, f1 > f2 ? ratio : ratio + 1,
2171+ 0xbff8, 0,
2172+ 0xbff9, 0,
2173+ 0xbffa, adjratio & 0xffff,
2174+ 0xbffb, adjratio >> 16,
2175+ 0xbf94, 0,
2176+ 0xbf95, 0,
2177+ 0, 0,
2178+ };
2179+
2180+ return copy_packages(code, pack, 1, space);
2181+}
2182+
2183+static int final_package(struct go7007 *go, u16 *code, int space)
2184+{
2185+ int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
2186+ u16 pack[] = {
2187+ 0x8000,
2188+ 0,
2189+ 0,
2190+ 0,
2191+ 0,
2192+ 0,
2193+ 0,
2194+ 2,
2195+ ((go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
2196+ (!go->interlace_coding) ?
2197+ (1 << 14) | (1 << 9) : 0) |
2198+ ((go->encoder_subsample ? 1 : 0) << 8) |
2199+ (go->board_info->sensor_flags &
2200+ GO7007_SENSOR_CONFIG_MASK),
2201+ ((go->encoder_v_halve ? 1 : 0) << 14) |
2202+ (go->encoder_v_halve ? rows << 9 : rows << 8) |
2203+ (go->encoder_h_halve ? 1 << 6 : 0) |
2204+ (go->encoder_h_halve ? go->width >> 3 : go->width >> 4),
2205+ (1 << 15) | (go->encoder_v_offset << 6) |
2206+ (1 << 7) | (go->encoder_h_offset >> 2),
2207+ (1 << 6),
2208+ 0,
2209+ 0,
2210+ ((go->fps_scale - 1) << 8) |
2211+ (go->board_info->sensor_flags & GO7007_SENSOR_TV ?
2212+ (1 << 7) : 0) |
2213+ 0x41,
2214+ go->ipb ? 0xd4c : 0x36b,
2215+ (rows << 8) | (go->width >> 4),
2216+ go->format == GO7007_FORMAT_MPEG4 ? 0x0404 : 0,
2217+ (1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) |
2218+ ((go->closed_gop ? 1 : 0) << 12) |
2219+ ((go->format == GO7007_FORMAT_MPEG4 ? 1 : 0) << 11) |
2220+ /* (1 << 9) | */
2221+ ((go->ipb ? 3 : 0) << 7) |
2222+ ((go->modet_enable ? 1 : 0) << 2) |
2223+ ((go->dvd_mode ? 1 : 0) << 1) | 1,
2224+ (go->format == GO7007_FORMAT_MPEG1 ? 0x89a0 :
2225+ (go->format == GO7007_FORMAT_MPEG2 ? 0x89a0 :
2226+ (go->format == GO7007_FORMAT_MJPEG ? 0x89a0 :
2227+ (go->format == GO7007_FORMAT_MPEG4 ? 0x8920 :
2228+ (go->format == GO7007_FORMAT_H263 ? 0x8920 : 0))))),
2229+ go->ipb ? 0x1f15 : 0x1f0b,
2230+ go->ipb ? 0x0015 : 0x000b,
2231+ go->ipb ? 0xa800 : 0x5800,
2232+ 0xffff,
2233+ 0x0020 + 0x034b * 0,
2234+ 0x0020 + 0x034b * 1,
2235+ 0x0020 + 0x034b * 2,
2236+ 0x0020 + 0x034b * 3,
2237+ 0x0020 + 0x034b * 4,
2238+ 0x0020 + 0x034b * 5,
2239+ go->ipb ? (go->gop_size / 3) : go->gop_size,
2240+ (go->height >> 4) * (go->width >> 4) * 110 / 100,
2241+ };
2242+
2243+ return copy_packages(code, pack, 1, space);
2244+}
2245+
2246+static int audio_to_package(struct go7007 *go, u16 *code, int space)
2247+{
2248+ int clock_config = ((go->board_info->audio_flags &
2249+ GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) |
2250+ ((go->board_info->audio_flags &
2251+ GO7007_AUDIO_OKI_MODE ? 1 : 0) << 8) |
2252+ (((go->board_info->audio_bclk_div / 4) - 1) << 4) |
2253+ (go->board_info->audio_main_div - 1);
2254+ u16 pack[] = {
2255+ 0x200d, 0,
2256+ 0x9002, 0,
2257+ 0x9002, 0,
2258+ 0x9031, 0,
2259+ 0x9032, 0,
2260+ 0x9033, 0,
2261+ 0x9034, 0,
2262+ 0x9035, 0,
2263+ 0x9036, 0,
2264+ 0x9037, 0,
2265+ 0x9040, 0,
2266+ 0x9000, clock_config,
2267+ 0x9001, (go->board_info->audio_flags & 0xffff) |
2268+ (1 << 9),
2269+ 0x9000, ((go->board_info->audio_flags &
2270+ GO7007_AUDIO_I2S_MASTER ?
2271+ 1 : 0) << 10) |
2272+ clock_config,
2273+ 0, 0,
2274+ 0, 0,
2275+ 0x2005, 0,
2276+ 0x9041, 0,
2277+ 0x9042, 256,
2278+ 0x9043, 0,
2279+ 0x9044, 16,
2280+ 0x9045, 16,
2281+ 0, 0,
2282+ 0, 0,
2283+ 0, 0,
2284+ 0, 0,
2285+ 0, 0,
2286+ 0, 0,
2287+ 0, 0,
2288+ 0, 0,
2289+ 0, 0,
2290+ 0, 0,
2291+ };
2292+
2293+ return copy_packages(code, pack, 2, space);
2294+}
2295+
2296+static int modet_to_package(struct go7007 *go, u16 *code, int space)
2297+{
2298+ int ret, mb, i, addr, cnt = 0;
2299+ u16 pack[32];
2300+ u16 thresholds[] = {
2301+ 0x200e, 0,
2302+ 0xbf82, go->modet[0].pixel_threshold,
2303+ 0xbf83, go->modet[1].pixel_threshold,
2304+ 0xbf84, go->modet[2].pixel_threshold,
2305+ 0xbf85, go->modet[3].pixel_threshold,
2306+ 0xbf86, go->modet[0].motion_threshold,
2307+ 0xbf87, go->modet[1].motion_threshold,
2308+ 0xbf88, go->modet[2].motion_threshold,
2309+ 0xbf89, go->modet[3].motion_threshold,
2310+ 0xbf8a, go->modet[0].mb_threshold,
2311+ 0xbf8b, go->modet[1].mb_threshold,
2312+ 0xbf8c, go->modet[2].mb_threshold,
2313+ 0xbf8d, go->modet[3].mb_threshold,
2314+ 0xbf8e, 0,
2315+ 0xbf8f, 0,
2316+ 0, 0,
2317+ };
2318+
2319+ ret = copy_packages(code, thresholds, 1, space);
2320+ if (ret < 0)
2321+ return -1;
2322+ cnt += ret;
2323+
2324+ addr = 0xbac0;
2325+ memset(pack, 0, 64);
2326+ i = 0;
2327+ for (mb = 0; mb < 1624; ++mb) {
2328+ pack[i * 2 + 3] <<= 2;
2329+ pack[i * 2 + 3] |= go->modet_map[mb];
2330+ if (mb % 8 != 7)
2331+ continue;
2332+ pack[i * 2 + 2] = addr++;
2333+ ++i;
2334+ if (i == 10 || mb == 1623) {
2335+ pack[0] = 0x2000 | i;
2336+ ret = copy_packages(code + cnt, pack, 1, space - cnt);
2337+ if (ret < 0)
2338+ return -1;
2339+ cnt += ret;
2340+ i = 0;
2341+ memset(pack, 0, 64);
2342+ }
2343+ pack[i * 2 + 3] = 0;
2344+ }
2345+
2346+ memset(pack, 0, 64);
2347+ i = 0;
2348+ for (addr = 0xbb90; addr < 0xbbfa; ++addr) {
2349+ pack[i * 2 + 2] = addr;
2350+ pack[i * 2 + 3] = 0;
2351+ ++i;
2352+ if (i == 10 || addr == 0xbbf9) {
2353+ pack[0] = 0x2000 | i;
2354+ ret = copy_packages(code + cnt, pack, 1, space - cnt);
2355+ if (ret < 0)
2356+ return -1;
2357+ cnt += ret;
2358+ i = 0;
2359+ memset(pack, 0, 64);
2360+ }
2361+ }
2362+ return cnt;
2363+}
2364+
2365+static int do_special(struct go7007 *go, u16 type, u16 *code, int space,
2366+ int *framelen)
2367+{
2368+ switch (type) {
2369+ case SPECIAL_FRM_HEAD:
2370+ switch (go->format) {
2371+ case GO7007_FORMAT_MJPEG:
2372+ return gen_mjpeghdr_to_package(go, code, space);
2373+ case GO7007_FORMAT_MPEG1:
2374+ case GO7007_FORMAT_MPEG2:
2375+ return gen_mpeg1hdr_to_package(go, code, space,
2376+ framelen);
2377+ case GO7007_FORMAT_MPEG4:
2378+ return gen_mpeg4hdr_to_package(go, code, space,
2379+ framelen);
2380+ }
2381+ case SPECIAL_BRC_CTRL:
2382+ return brctrl_to_package(go, code, space, framelen);
2383+ case SPECIAL_CONFIG:
2384+ return config_package(go, code, space);
2385+ case SPECIAL_SEQHEAD:
2386+ switch (go->format) {
2387+ case GO7007_FORMAT_MPEG1:
2388+ case GO7007_FORMAT_MPEG2:
2389+ return seqhead_to_package(go, code, space,
2390+ mpeg1_sequence_header);
2391+ case GO7007_FORMAT_MPEG4:
2392+ return seqhead_to_package(go, code, space,
2393+ mpeg4_sequence_header);
2394+ default:
2395+ return 0;
2396+ }
2397+ case SPECIAL_AV_SYNC:
2398+ return avsync_to_package(go, code, space);
2399+ case SPECIAL_FINAL:
2400+ return final_package(go, code, space);
2401+ case SPECIAL_AUDIO:
2402+ return audio_to_package(go, code, space);
2403+ case SPECIAL_MODET:
2404+ return modet_to_package(go, code, space);
2405+ }
2406+ printk(KERN_ERR
2407+ "go7007: firmware file contains unsupported feature %04x\n",
2408+ type);
2409+ return -1;
2410+}
2411+
2412+int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
2413+{
2414+ const struct firmware *fw_entry;
2415+ u16 *code, *src;
2416+ int framelen[8] = { }; /* holds the lengths of empty frame templates */
2417+ int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags;
2418+ int mode_flag;
2419+ int ret;
2420+
2421+ switch (go->format) {
2422+ case GO7007_FORMAT_MJPEG:
2423+ mode_flag = FLAG_MODE_MJPEG;
2424+ break;
2425+ case GO7007_FORMAT_MPEG1:
2426+ mode_flag = FLAG_MODE_MPEG1;
2427+ break;
2428+ case GO7007_FORMAT_MPEG2:
2429+ mode_flag = FLAG_MODE_MPEG2;
2430+ break;
2431+ case GO7007_FORMAT_MPEG4:
2432+ mode_flag = FLAG_MODE_MPEG4;
2433+ break;
2434+ default:
2435+ return -1;
2436+ }
2437+ if (request_firmware(&fw_entry, go->board_info->firmware, go->dev)) {
2438+ printk(KERN_ERR
2439+ "go7007: unable to load firmware from file \"%s\"\n",
2440+ go->board_info->firmware);
2441+ return -1;
2442+ }
2443+ code = kmalloc(codespace * 2, GFP_KERNEL);
2444+ if (code == NULL) {
2445+ printk(KERN_ERR "go7007: unable to allocate %d bytes for "
2446+ "firmware construction\n", codespace * 2);
2447+ goto fw_failed;
2448+ }
2449+ memset(code, 0, codespace * 2);
2450+ src = (u16 *)fw_entry->data;
2451+ srclen = fw_entry->size / 2;
2452+ while (srclen >= 2) {
2453+ chunk_flags = __le16_to_cpu(src[0]);
2454+ chunk_len = __le16_to_cpu(src[1]);
2455+ if (chunk_len + 2 > srclen) {
2456+ printk(KERN_ERR "go7007: firmware file \"%s\" "
2457+ "appears to be corrupted\n",
2458+ go->board_info->firmware);
2459+ goto fw_failed;
2460+ }
2461+ if (chunk_flags & mode_flag) {
2462+ if (chunk_flags & FLAG_SPECIAL) {
2463+ ret = do_special(go, __le16_to_cpu(src[2]),
2464+ &code[i], codespace - i, framelen);
2465+ if (ret < 0) {
2466+ printk(KERN_ERR "go7007: insufficient "
2467+ "memory for firmware "
2468+ "construction\n");
2469+ goto fw_failed;
2470+ }
2471+ i += ret;
2472+ } else {
2473+ if (codespace - i < chunk_len) {
2474+ printk(KERN_ERR "go7007: insufficient "
2475+ "memory for firmware "
2476+ "construction\n");
2477+ goto fw_failed;
2478+ }
2479+ memcpy(&code[i], &src[2], chunk_len * 2);
2480+ i += chunk_len;
2481+ }
2482+ }
2483+ srclen -= chunk_len + 2;
2484+ src += chunk_len + 2;
2485+ }
2486+ release_firmware(fw_entry);
2487+ *fw = (u8 *)code;
2488+ *fwlen = i * 2;
2489+ return 0;
2490+
2491+fw_failed:
2492+ kfree(code);
2493+ release_firmware(fw_entry);
2494+ return -1;
2495+}
2496diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c
2497new file mode 100644
2498index 0000000..10baae3
2499--- /dev/null
2500+++ b/drivers/staging/go7007/go7007-i2c.c
2501@@ -0,0 +1,309 @@
2502+/*
2503+ * Copyright (C) 2005-2006 Micronas USA Inc.
2504+ *
2505+ * This program is free software; you can redistribute it and/or modify
2506+ * it under the terms of the GNU General Public License (Version 2) as
2507+ * published by the Free Software Foundation.
2508+ *
2509+ * This program is distributed in the hope that it will be useful,
2510+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2511+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2512+ * GNU General Public License for more details.
2513+ *
2514+ * You should have received a copy of the GNU General Public License
2515+ * along with this program; if not, write to the Free Software Foundation,
2516+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
2517+ */
2518+
2519+#include <linux/version.h>
2520+#include <linux/module.h>
2521+#include <linux/init.h>
2522+#include <linux/delay.h>
2523+#include <linux/sched.h>
2524+#include <linux/list.h>
2525+#include <linux/unistd.h>
2526+#include <linux/time.h>
2527+#include <linux/device.h>
2528+#include <linux/i2c.h>
2529+#include <linux/semaphore.h>
2530+#include <linux/uaccess.h>
2531+#include <asm/system.h>
2532+
2533+#include "go7007-priv.h"
2534+#include "wis-i2c.h"
2535+
2536+/************** Registration interface for I2C client drivers **************/
2537+
2538+/* Since there's no way to auto-probe the I2C devices connected to the I2C
2539+ * bus on the go7007, we have this silly little registration system that
2540+ * client drivers can use to register their I2C driver ID and their
2541+ * detect_client function (the one that's normally passed to i2c_probe).
2542+ *
2543+ * When a new go7007 device is connected, we can look up in a board info
2544+ * table by the USB or PCI vendor/product/revision ID to determine
2545+ * which I2C client module to load. The client driver module will register
2546+ * itself here, and then we can call the registered detect_client function
2547+ * to force-load a new client at the address listed in the board info table.
2548+ *
2549+ * Really the I2C subsystem should have a way to force-load I2C client
2550+ * drivers when we have a priori knowledge of what's on the bus, especially
2551+ * since the existing I2C auto-probe mechanism is so hokey, but we'll use
2552+ * our own mechanism for the time being. */
2553+
2554+struct wis_i2c_client_driver {
2555+ unsigned int id;
2556+ found_proc found_proc;
2557+ struct list_head list;
2558+};
2559+
2560+static LIST_HEAD(i2c_client_drivers);
2561+static DECLARE_MUTEX(i2c_client_driver_list_lock);
2562+
2563+/* Client drivers register here by their I2C driver ID */
2564+int wis_i2c_add_driver(unsigned int id, found_proc found_proc)
2565+{
2566+ struct wis_i2c_client_driver *driver;
2567+
2568+ driver = kmalloc(sizeof(struct wis_i2c_client_driver), GFP_KERNEL);
2569+ if (driver == NULL)
2570+ return -ENOMEM;
2571+ driver->id = id;
2572+ driver->found_proc = found_proc;
2573+
2574+ down(&i2c_client_driver_list_lock);
2575+ list_add_tail(&driver->list, &i2c_client_drivers);
2576+ up(&i2c_client_driver_list_lock);
2577+
2578+ return 0;
2579+}
2580+EXPORT_SYMBOL(wis_i2c_add_driver);
2581+
2582+void wis_i2c_del_driver(found_proc found_proc)
2583+{
2584+ struct wis_i2c_client_driver *driver, *next;
2585+
2586+ down(&i2c_client_driver_list_lock);
2587+ list_for_each_entry_safe(driver, next, &i2c_client_drivers, list)
2588+ if (driver->found_proc == found_proc) {
2589+ list_del(&driver->list);
2590+ kfree(driver);
2591+ }
2592+ up(&i2c_client_driver_list_lock);
2593+}
2594+EXPORT_SYMBOL(wis_i2c_del_driver);
2595+
2596+/* The main go7007 driver calls this to instantiate a client by driver
2597+ * ID and bus address, which are both stored in the board info table */
2598+int wis_i2c_probe_device(struct i2c_adapter *adapter,
2599+ unsigned int id, int addr)
2600+{
2601+ struct wis_i2c_client_driver *driver;
2602+ int found = 0;
2603+
2604+ if (addr < 0 || addr > 0x7f)
2605+ return -1;
2606+ down(&i2c_client_driver_list_lock);
2607+ list_for_each_entry(driver, &i2c_client_drivers, list)
2608+ if (driver->id == id) {
2609+ if (driver->found_proc(adapter, addr, 0) == 0)
2610+ found = 1;
2611+ break;
2612+ }
2613+ up(&i2c_client_driver_list_lock);
2614+ return found;
2615+}
2616+
2617+/********************* Driver for on-board I2C adapter *********************/
2618+
2619+/* #define GO7007_I2C_DEBUG */
2620+
2621+#define SPI_I2C_ADDR_BASE 0x1400
2622+#define STATUS_REG_ADDR (SPI_I2C_ADDR_BASE + 0x2)
2623+#define I2C_CTRL_REG_ADDR (SPI_I2C_ADDR_BASE + 0x6)
2624+#define I2C_DEV_UP_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x7)
2625+#define I2C_LO_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x8)
2626+#define I2C_DATA_REG_ADDR (SPI_I2C_ADDR_BASE + 0x9)
2627+#define I2C_CLKFREQ_REG_ADDR (SPI_I2C_ADDR_BASE + 0xa)
2628+
2629+#define I2C_STATE_MASK 0x0007
2630+#define I2C_READ_READY_MASK 0x0008
2631+
2632+/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
2633+ * on the Adlink PCI-MPG24, so access is shared between all of them. */
2634+static DECLARE_MUTEX(adlink_mpg24_i2c_lock);
2635+
2636+static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
2637+ u16 command, int flags, u8 *data)
2638+{
2639+ int i, ret = -1;
2640+ u16 val;
2641+
2642+ if (go->status == STATUS_SHUTDOWN)
2643+ return -1;
2644+
2645+#ifdef GO7007_I2C_DEBUG
2646+ if (read)
2647+ printk(KERN_DEBUG "go7007-i2c: reading 0x%02x on 0x%02x\n",
2648+ command, addr);
2649+ else
2650+ printk(KERN_DEBUG
2651+ "go7007-i2c: writing 0x%02x to 0x%02x on 0x%02x\n",
2652+ *data, command, addr);
2653+#endif
2654+
2655+ down(&go->hw_lock);
2656+
2657+ if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
2658+ /* Bridge the I2C port on this GO7007 to the shared bus */
2659+ down(&adlink_mpg24_i2c_lock);
2660+ go7007_write_addr(go, 0x3c82, 0x0020);
2661+ }
2662+
2663+ /* Wait for I2C adapter to be ready */
2664+ for (i = 0; i < 10; ++i) {
2665+ if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
2666+ goto i2c_done;
2667+ if (!(val & I2C_STATE_MASK))
2668+ break;
2669+ msleep(100);
2670+ }
2671+ if (i == 10) {
2672+ printk(KERN_ERR "go7007-i2c: I2C adapter is hung\n");
2673+ goto i2c_done;
2674+ }
2675+
2676+ /* Set target register (command) */
2677+ go7007_write_addr(go, I2C_CTRL_REG_ADDR, flags);
2678+ go7007_write_addr(go, I2C_LO_ADDR_REG_ADDR, command);
2679+
2680+ /* If we're writing, send the data and target address and we're done */
2681+ if (!read) {
2682+ go7007_write_addr(go, I2C_DATA_REG_ADDR, *data);
2683+ go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
2684+ (addr << 9) | (command >> 8));
2685+ ret = 0;
2686+ goto i2c_done;
2687+ }
2688+
2689+ /* Otherwise, we're reading. First clear i2c_rx_data_rdy. */
2690+ if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
2691+ goto i2c_done;
2692+
2693+ /* Send the target address plus read flag */
2694+ go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
2695+ (addr << 9) | 0x0100 | (command >> 8));
2696+
2697+ /* Wait for i2c_rx_data_rdy */
2698+ for (i = 0; i < 10; ++i) {
2699+ if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
2700+ goto i2c_done;
2701+ if (val & I2C_READ_READY_MASK)
2702+ break;
2703+ msleep(100);
2704+ }
2705+ if (i == 10) {
2706+ printk(KERN_ERR "go7007-i2c: I2C adapter is hung\n");
2707+ goto i2c_done;
2708+ }
2709+
2710+ /* Retrieve the read byte */
2711+ if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
2712+ goto i2c_done;
2713+ *data = val;
2714+ ret = 0;
2715+
2716+i2c_done:
2717+ if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
2718+ /* Isolate the I2C port on this GO7007 from the shared bus */
2719+ go7007_write_addr(go, 0x3c82, 0x0000);
2720+ up(&adlink_mpg24_i2c_lock);
2721+ }
2722+ up(&go->hw_lock);
2723+ return ret;
2724+}
2725+
2726+static int go7007_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
2727+ unsigned short flags, char read_write,
2728+ u8 command, int size, union i2c_smbus_data *data)
2729+{
2730+ struct go7007 *go = i2c_get_adapdata(adapter);
2731+
2732+ if (size != I2C_SMBUS_BYTE_DATA)
2733+ return -1;
2734+ return go7007_i2c_xfer(go, addr, read_write == I2C_SMBUS_READ, command,
2735+ flags & I2C_CLIENT_SCCB ? 0x10 : 0x00, &data->byte);
2736+}
2737+
2738+/* VERY LIMITED I2C master xfer function -- only needed because the
2739+ * SMBus functions only support 8-bit commands and the SAA7135 uses
2740+ * 16-bit commands. The I2C interface on the GO7007, as limited as
2741+ * it is, does support this mode. */
2742+
2743+static int go7007_i2c_master_xfer(struct i2c_adapter *adapter,
2744+ struct i2c_msg msgs[], int num)
2745+{
2746+ struct go7007 *go = i2c_get_adapdata(adapter);
2747+ int i;
2748+
2749+ for (i = 0; i < num; ++i) {
2750+ /* We can only do two things here -- write three bytes, or
2751+ * write two bytes and read one byte. */
2752+ if (msgs[i].len == 2) {
2753+ if (i + 1 == num || msgs[i].addr != msgs[i + 1].addr ||
2754+ (msgs[i].flags & I2C_M_RD) ||
2755+ !(msgs[i + 1].flags & I2C_M_RD) ||
2756+ msgs[i + 1].len != 1)
2757+ return -1;
2758+ if (go7007_i2c_xfer(go, msgs[i].addr, 1,
2759+ (msgs[i].buf[0] << 8) | msgs[i].buf[1],
2760+ 0x01, &msgs[i + 1].buf[0]) < 0)
2761+ return -1;
2762+ ++i;
2763+ } else if (msgs[i].len == 3) {
2764+ if (msgs[i].flags & I2C_M_RD)
2765+ return -1;
2766+ if (msgs[i].len != 3)
2767+ return -1;
2768+ if (go7007_i2c_xfer(go, msgs[i].addr, 0,
2769+ (msgs[i].buf[0] << 8) | msgs[i].buf[1],
2770+ 0x01, &msgs[i].buf[2]) < 0)
2771+ return -1;
2772+ } else
2773+ return -1;
2774+ }
2775+
2776+ return 0;
2777+}
2778+
2779+static u32 go7007_functionality(struct i2c_adapter *adapter)
2780+{
2781+ return I2C_FUNC_SMBUS_BYTE_DATA;
2782+}
2783+
2784+static struct i2c_algorithm go7007_algo = {
2785+ .smbus_xfer = go7007_smbus_xfer,
2786+ .master_xfer = go7007_i2c_master_xfer,
2787+ .functionality = go7007_functionality,
2788+};
2789+
2790+static struct i2c_adapter go7007_adap_templ = {
2791+ .owner = THIS_MODULE,
2792+ .class = I2C_CLASS_TV_ANALOG,
2793+ .name = "WIS GO7007SB",
2794+ .id = I2C_ALGO_GO7007,
2795+ .algo = &go7007_algo,
2796+};
2797+
2798+int go7007_i2c_init(struct go7007 *go)
2799+{
2800+ memcpy(&go->i2c_adapter, &go7007_adap_templ,
2801+ sizeof(go7007_adap_templ));
2802+ go->i2c_adapter.dev.parent = go->dev;
2803+ i2c_set_adapdata(&go->i2c_adapter, go);
2804+ if (i2c_add_adapter(&go->i2c_adapter) < 0) {
2805+ printk(KERN_ERR
2806+ "go7007-i2c: error: i2c_add_adapter failed\n");
2807+ return -1;
2808+ }
2809+ return 0;
2810+}
2811diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
2812new file mode 100644
2813index 0000000..005542d
2814--- /dev/null
2815+++ b/drivers/staging/go7007/go7007-priv.h
2816@@ -0,0 +1,279 @@
2817+/*
2818+ * Copyright (C) 2005-2006 Micronas USA Inc.
2819+ *
2820+ * This program is free software; you can redistribute it and/or modify
2821+ * it under the terms of the GNU General Public License (Version 2) as
2822+ * published by the Free Software Foundation.
2823+ *
2824+ * This program is distributed in the hope that it will be useful,
2825+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2826+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2827+ * GNU General Public License for more details.
2828+ *
2829+ * You should have received a copy of the GNU General Public License
2830+ * along with this program; if not, write to the Free Software Foundation,
2831+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
2832+ */
2833+
2834+/*
2835+ * This is the private include file for the go7007 driver. It should not
2836+ * be included by anybody but the driver itself, and especially not by
2837+ * user-space applications.
2838+ */
2839+
2840+struct go7007;
2841+
2842+/* IDs to activate board-specific support code */
2843+#define GO7007_BOARDID_MATRIX_II 0
2844+#define GO7007_BOARDID_MATRIX_RELOAD 1
2845+#define GO7007_BOARDID_STAR_TREK 2
2846+#define GO7007_BOARDID_PCI_VOYAGER 3
2847+#define GO7007_BOARDID_XMEN 4
2848+#define GO7007_BOARDID_XMEN_II 5
2849+#define GO7007_BOARDID_XMEN_III 6
2850+#define GO7007_BOARDID_MATRIX_REV 7
2851+#define GO7007_BOARDID_PX_M402U 16
2852+#define GO7007_BOARDID_PX_TV402U_ANY 17 /* need to check tuner model */
2853+#define GO7007_BOARDID_PX_TV402U_NA 18 /* detected NTSC tuner */
2854+#define GO7007_BOARDID_PX_TV402U_EU 19 /* detected PAL tuner */
2855+#define GO7007_BOARDID_PX_TV402U_JP 20 /* detected NTSC-J tuner */
2856+#define GO7007_BOARDID_LIFEVIEW_LR192 21 /* TV Walker Ultra */
2857+#define GO7007_BOARDID_ENDURA 22
2858+#define GO7007_BOARDID_ADLINK_MPG24 23
2859+
2860+/* Various characteristics of each board */
2861+#define GO7007_BOARD_HAS_AUDIO (1<<0)
2862+#define GO7007_BOARD_USE_ONBOARD_I2C (1<<1)
2863+#define GO7007_BOARD_HAS_TUNER (1<<2)
2864+
2865+/* Characteristics of sensor devices */
2866+#define GO7007_SENSOR_VALID_POLAR (1<<0)
2867+#define GO7007_SENSOR_HREF_POLAR (1<<1)
2868+#define GO7007_SENSOR_VREF_POLAR (1<<2)
2869+#define GO7007_SENSOR_FIELD_ID_POLAR (1<<3)
2870+#define GO7007_SENSOR_BIT_WIDTH (1<<4)
2871+#define GO7007_SENSOR_VALID_ENABLE (1<<5)
2872+#define GO7007_SENSOR_656 (1<<6)
2873+#define GO7007_SENSOR_CONFIG_MASK 0x7f
2874+#define GO7007_SENSOR_TV (1<<7)
2875+#define GO7007_SENSOR_VBI (1<<8)
2876+#define GO7007_SENSOR_SCALING (1<<9)
2877+
2878+/* Characteristics of audio sensor devices */
2879+#define GO7007_AUDIO_I2S_MODE_1 (1)
2880+#define GO7007_AUDIO_I2S_MODE_2 (2)
2881+#define GO7007_AUDIO_I2S_MODE_3 (3)
2882+#define GO7007_AUDIO_BCLK_POLAR (1<<2)
2883+#define GO7007_AUDIO_WORD_14 (14<<4)
2884+#define GO7007_AUDIO_WORD_16 (16<<4)
2885+#define GO7007_AUDIO_ONE_CHANNEL (1<<11)
2886+#define GO7007_AUDIO_I2S_MASTER (1<<16)
2887+#define GO7007_AUDIO_OKI_MODE (1<<17)
2888+
2889+struct go7007_board_info {
2890+ char *firmware;
2891+ unsigned int flags;
2892+ int hpi_buffer_cap;
2893+ unsigned int sensor_flags;
2894+ int sensor_width;
2895+ int sensor_height;
2896+ int sensor_framerate;
2897+ int sensor_h_offset;
2898+ int sensor_v_offset;
2899+ unsigned int audio_flags;
2900+ int audio_rate;
2901+ int audio_bclk_div;
2902+ int audio_main_div;
2903+ int num_i2c_devs;
2904+ struct {
2905+ int id;
2906+ int addr;
2907+ } i2c_devs[4];
2908+ int num_inputs;
2909+ struct {
2910+ int video_input;
2911+ int audio_input;
2912+ char *name;
2913+ } inputs[4];
2914+};
2915+
2916+struct go7007_hpi_ops {
2917+ int (*interface_reset)(struct go7007 *go);
2918+ int (*write_interrupt)(struct go7007 *go, int addr, int data);
2919+ int (*read_interrupt)(struct go7007 *go);
2920+ int (*stream_start)(struct go7007 *go);
2921+ int (*stream_stop)(struct go7007 *go);
2922+ int (*send_firmware)(struct go7007 *go, u8 *data, int len);
2923+};
2924+
2925+/* The video buffer size must be a multiple of PAGE_SIZE */
2926+#define GO7007_BUF_PAGES (128 * 1024 / PAGE_SIZE)
2927+#define GO7007_BUF_SIZE (GO7007_BUF_PAGES << PAGE_SHIFT)
2928+
2929+struct go7007_buffer {
2930+ struct go7007 *go; /* Reverse reference for VMA ops */
2931+ int index; /* Reverse reference for DQBUF */
2932+ enum { BUF_STATE_IDLE, BUF_STATE_QUEUED, BUF_STATE_DONE } state;
2933+ u32 seq;
2934+ struct timeval timestamp;
2935+ struct list_head stream;
2936+ struct page *pages[GO7007_BUF_PAGES + 1]; /* extra for straddling */
2937+ unsigned long user_addr;
2938+ unsigned int page_count;
2939+ unsigned int offset;
2940+ unsigned int bytesused;
2941+ unsigned int frame_offset;
2942+ u32 modet_active;
2943+ int mapped;
2944+};
2945+
2946+struct go7007_file {
2947+ struct go7007 *go;
2948+ struct semaphore lock;
2949+ int buf_count;
2950+ struct go7007_buffer *bufs;
2951+};
2952+
2953+#define GO7007_FORMAT_MJPEG 0
2954+#define GO7007_FORMAT_MPEG4 1
2955+#define GO7007_FORMAT_MPEG1 2
2956+#define GO7007_FORMAT_MPEG2 3
2957+#define GO7007_FORMAT_H263 4
2958+
2959+#define GO7007_RATIO_1_1 0
2960+#define GO7007_RATIO_4_3 1
2961+#define GO7007_RATIO_16_9 2
2962+
2963+enum go7007_parser_state {
2964+ STATE_DATA,
2965+ STATE_00,
2966+ STATE_00_00,
2967+ STATE_00_00_01,
2968+ STATE_FF,
2969+ STATE_VBI_LEN_A,
2970+ STATE_VBI_LEN_B,
2971+ STATE_MODET_MAP,
2972+ STATE_UNPARSED,
2973+};
2974+
2975+struct go7007 {
2976+ struct device *dev;
2977+ struct go7007_board_info *board_info;
2978+ unsigned int board_id;
2979+ int tuner_type;
2980+ int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
2981+ char name[64];
2982+ struct video_device *video_dev;
2983+ int ref_count;
2984+ enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
2985+ spinlock_t spinlock;
2986+ struct semaphore hw_lock;
2987+ int streaming;
2988+ int in_use;
2989+ int audio_enabled;
2990+
2991+ /* Video input */
2992+ int input;
2993+ enum { GO7007_STD_NTSC, GO7007_STD_PAL, GO7007_STD_OTHER } standard;
2994+ int sensor_framerate;
2995+ int width;
2996+ int height;
2997+ int encoder_h_offset;
2998+ int encoder_v_offset;
2999+ unsigned int encoder_h_halve:1;
3000+ unsigned int encoder_v_halve:1;
3001+ unsigned int encoder_subsample:1;
3002+
3003+ /* Encoder config */
3004+ int format;
3005+ int bitrate;
3006+ int fps_scale;
3007+ int pali;
3008+ int aspect_ratio;
3009+ int gop_size;
3010+ unsigned int ipb:1;
3011+ unsigned int closed_gop:1;
3012+ unsigned int repeat_seqhead:1;
3013+ unsigned int seq_header_enable:1;
3014+ unsigned int gop_header_enable:1;
3015+ unsigned int dvd_mode:1;
3016+ unsigned int interlace_coding:1;
3017+
3018+ /* Motion detection */
3019+ unsigned int modet_enable:1;
3020+ struct {
3021+ unsigned int enable:1;
3022+ int pixel_threshold;
3023+ int motion_threshold;
3024+ int mb_threshold;
3025+ } modet[4];
3026+ unsigned char modet_map[1624];
3027+ unsigned char active_map[216];
3028+
3029+ /* Video streaming */
3030+ struct go7007_buffer *active_buf;
3031+ enum go7007_parser_state state;
3032+ int parse_length;
3033+ u16 modet_word;
3034+ int seen_frame;
3035+ u32 next_seq;
3036+ struct list_head stream;
3037+ wait_queue_head_t frame_waitq;
3038+
3039+ /* Audio streaming */
3040+ void (*audio_deliver)(struct go7007 *go, u8 *buf, int length);
3041+ void *snd_context;
3042+
3043+ /* I2C */
3044+ int i2c_adapter_online;
3045+ struct i2c_adapter i2c_adapter;
3046+
3047+ /* HPI driver */
3048+ struct go7007_hpi_ops *hpi_ops;
3049+ void *hpi_context;
3050+ int interrupt_available;
3051+ wait_queue_head_t interrupt_waitq;
3052+ unsigned short interrupt_value;
3053+ unsigned short interrupt_data;
3054+};
3055+
3056+/* All of these must be called with the hpi_lock semaphore held! */
3057+#define go7007_interface_reset(go) \
3058+ ((go)->hpi_ops->interface_reset(go))
3059+#define go7007_write_interrupt(go, x, y) \
3060+ ((go)->hpi_ops->write_interrupt)((go), (x), (y))
3061+#define go7007_stream_start(go) \
3062+ ((go)->hpi_ops->stream_start(go))
3063+#define go7007_stream_stop(go) \
3064+ ((go)->hpi_ops->stream_stop(go))
3065+#define go7007_send_firmware(go, x, y) \
3066+ ((go)->hpi_ops->send_firmware)((go), (x), (y))
3067+#define go7007_write_addr(go, x, y) \
3068+ ((go)->hpi_ops->write_interrupt)((go), (x)|0x8000, (y))
3069+
3070+/* go7007-driver.c */
3071+int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data);
3072+int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data);
3073+int go7007_boot_encoder(struct go7007 *go, int init_i2c);
3074+int go7007_reset_encoder(struct go7007 *go);
3075+int go7007_register_encoder(struct go7007 *go);
3076+int go7007_start_encoder(struct go7007 *go);
3077+void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length);
3078+struct go7007 *go7007_alloc(struct go7007_board_info *board,
3079+ struct device *dev);
3080+void go7007_remove(struct go7007 *go);
3081+
3082+/* go7007-fw.c */
3083+int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen);
3084+
3085+/* go7007-i2c.c */
3086+int go7007_i2c_init(struct go7007 *go);
3087+int go7007_i2c_remove(struct go7007 *go);
3088+
3089+/* go7007-v4l2.c */
3090+int go7007_v4l2_init(struct go7007 *go);
3091+void go7007_v4l2_remove(struct go7007 *go);
3092+
3093+/* snd-go7007.c */
3094+int go7007_snd_init(struct go7007 *go);
3095+int go7007_snd_remove(struct go7007 *go);
3096diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
3097new file mode 100644
3098index 0000000..d4ed6d2
3099--- /dev/null
3100+++ b/drivers/staging/go7007/go7007-usb.c
3101@@ -0,0 +1,1229 @@
3102+/*
3103+ * Copyright (C) 2005-2006 Micronas USA Inc.
3104+ *
3105+ * This program is free software; you can redistribute it and/or modify
3106+ * it under the terms of the GNU General Public License (Version 2) as
3107+ * published by the Free Software Foundation.
3108+ *
3109+ * This program is distributed in the hope that it will be useful,
3110+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3111+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3112+ * GNU General Public License for more details.
3113+ *
3114+ * You should have received a copy of the GNU General Public License
3115+ * along with this program; if not, write to the Free Software Foundation,
3116+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
3117+ */
3118+
3119+#include <linux/module.h>
3120+#include <linux/version.h>
3121+#include <linux/kernel.h>
3122+#include <linux/init.h>
3123+#include <linux/wait.h>
3124+#include <linux/list.h>
3125+#include <linux/slab.h>
3126+#include <linux/time.h>
3127+#include <linux/mm.h>
3128+#include <linux/usb.h>
3129+#include <linux/i2c.h>
3130+#include <asm/byteorder.h>
3131+#include <media/tvaudio.h>
3132+
3133+#include "go7007-priv.h"
3134+#include "wis-i2c.h"
3135+
3136+static unsigned int assume_endura;
3137+module_param(assume_endura, int, 0644);
3138+MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura");
3139+
3140+/* #define GO7007_USB_DEBUG */
3141+/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
3142+
3143+#define HPI_STATUS_ADDR 0xFFF4
3144+#define INT_PARAM_ADDR 0xFFF6
3145+#define INT_INDEX_ADDR 0xFFF8
3146+
3147+/*
3148+ * Pipes on EZ-USB interface:
3149+ * 0 snd - Control
3150+ * 0 rcv - Control
3151+ * 2 snd - Download firmware (control)
3152+ * 4 rcv - Read Interrupt (interrupt)
3153+ * 6 rcv - Read Video (bulk)
3154+ * 8 rcv - Read Audio (bulk)
3155+ */
3156+
3157+#define GO7007_USB_EZUSB (1<<0)
3158+#define GO7007_USB_EZUSB_I2C (1<<1)
3159+
3160+struct go7007_usb_board {
3161+ unsigned int flags;
3162+ struct go7007_board_info main_info;
3163+};
3164+
3165+struct go7007_usb {
3166+ struct go7007_usb_board *board;
3167+ struct semaphore i2c_lock;
3168+ struct usb_device *usbdev;
3169+ struct urb *video_urbs[8];
3170+ struct urb *audio_urbs[8];
3171+ struct urb *intr_urb;
3172+};
3173+
3174+/*********************** Product specification data ***********************/
3175+
3176+static struct go7007_usb_board board_matrix_ii = {
3177+ .flags = GO7007_USB_EZUSB,
3178+ .main_info = {
3179+ .firmware = "go7007tv.bin",
3180+ .flags = GO7007_BOARD_HAS_AUDIO |
3181+ GO7007_BOARD_USE_ONBOARD_I2C,
3182+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
3183+ GO7007_AUDIO_WORD_16,
3184+ .audio_rate = 48000,
3185+ .audio_bclk_div = 8,
3186+ .audio_main_div = 2,
3187+ .hpi_buffer_cap = 7,
3188+ .sensor_flags = GO7007_SENSOR_656 |
3189+ GO7007_SENSOR_VALID_ENABLE |
3190+ GO7007_SENSOR_TV |
3191+ GO7007_SENSOR_VBI |
3192+ GO7007_SENSOR_SCALING,
3193+ .num_i2c_devs = 1,
3194+ .i2c_devs = {
3195+ {
3196+ .id = I2C_DRIVERID_WIS_SAA7115,
3197+ .addr = 0x20,
3198+ },
3199+ },
3200+ .num_inputs = 2,
3201+ .inputs = {
3202+ {
3203+ .video_input = 0,
3204+ .name = "Composite",
3205+ },
3206+ {
3207+ .video_input = 9,
3208+ .name = "S-Video",
3209+ },
3210+ },
3211+ },
3212+};
3213+
3214+static struct go7007_usb_board board_matrix_reload = {
3215+ .flags = GO7007_USB_EZUSB,
3216+ .main_info = {
3217+ .firmware = "go7007tv.bin",
3218+ .flags = GO7007_BOARD_HAS_AUDIO |
3219+ GO7007_BOARD_USE_ONBOARD_I2C,
3220+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
3221+ GO7007_AUDIO_I2S_MASTER |
3222+ GO7007_AUDIO_WORD_16,
3223+ .audio_rate = 48000,
3224+ .audio_bclk_div = 8,
3225+ .audio_main_div = 2,
3226+ .hpi_buffer_cap = 7,
3227+ .sensor_flags = GO7007_SENSOR_656 |
3228+ GO7007_SENSOR_TV,
3229+ .num_i2c_devs = 1,
3230+ .i2c_devs = {
3231+ {
3232+ .id = I2C_DRIVERID_WIS_SAA7113,
3233+ .addr = 0x25,
3234+ },
3235+ },
3236+ .num_inputs = 2,
3237+ .inputs = {
3238+ {
3239+ .video_input = 0,
3240+ .name = "Composite",
3241+ },
3242+ {
3243+ .video_input = 9,
3244+ .name = "S-Video",
3245+ },
3246+ },
3247+ },
3248+};
3249+
3250+static struct go7007_usb_board board_star_trek = {
3251+ .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
3252+ .main_info = {
3253+ .firmware = "go7007tv.bin",
3254+ .flags = GO7007_BOARD_HAS_AUDIO, /* |
3255+ GO7007_BOARD_HAS_TUNER, */
3256+ .sensor_flags = GO7007_SENSOR_656 |
3257+ GO7007_SENSOR_VALID_ENABLE |
3258+ GO7007_SENSOR_TV |
3259+ GO7007_SENSOR_VBI |
3260+ GO7007_SENSOR_SCALING,
3261+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
3262+ GO7007_AUDIO_WORD_16,
3263+ .audio_bclk_div = 8,
3264+ .audio_main_div = 2,
3265+ .hpi_buffer_cap = 7,
3266+ .num_i2c_devs = 1,
3267+ .i2c_devs = {
3268+ {
3269+ .id = I2C_DRIVERID_WIS_SAA7115,
3270+ .addr = 0x20,
3271+ },
3272+ },
3273+ .num_inputs = 2,
3274+ .inputs = {
3275+ {
3276+ .video_input = 1,
3277+ /* .audio_input = AUDIO_EXTERN, */
3278+ .name = "Composite",
3279+ },
3280+ {
3281+ .video_input = 8,
3282+ /* .audio_input = AUDIO_EXTERN, */
3283+ .name = "S-Video",
3284+ },
3285+ /* {
3286+ * .video_input = 3,
3287+ * .audio_input = AUDIO_TUNER,
3288+ * .name = "Tuner",
3289+ * },
3290+ */
3291+ },
3292+ },
3293+};
3294+
3295+static struct go7007_usb_board board_px_tv402u = {
3296+ .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
3297+ .main_info = {
3298+ .firmware = "go7007tv.bin",
3299+ .flags = GO7007_BOARD_HAS_AUDIO |
3300+ GO7007_BOARD_HAS_TUNER,
3301+ .sensor_flags = GO7007_SENSOR_656 |
3302+ GO7007_SENSOR_VALID_ENABLE |
3303+ GO7007_SENSOR_TV |
3304+ GO7007_SENSOR_VBI |
3305+ GO7007_SENSOR_SCALING,
3306+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
3307+ GO7007_AUDIO_WORD_16,
3308+ .audio_bclk_div = 8,
3309+ .audio_main_div = 2,
3310+ .hpi_buffer_cap = 7,
3311+ .num_i2c_devs = 3,
3312+ .i2c_devs = {
3313+ {
3314+ .id = I2C_DRIVERID_WIS_SAA7115,
3315+ .addr = 0x20,
3316+ },
3317+ {
3318+ .id = I2C_DRIVERID_WIS_UDA1342,
3319+ .addr = 0x1a,
3320+ },
3321+ {
3322+ .id = I2C_DRIVERID_WIS_SONY_TUNER,
3323+ .addr = 0x60,
3324+ },
3325+ },
3326+ .num_inputs = 3,
3327+ .inputs = {
3328+ {
3329+ .video_input = 1,
3330+ .audio_input = TVAUDIO_INPUT_EXTERN,
3331+ .name = "Composite",
3332+ },
3333+ {
3334+ .video_input = 8,
3335+ .audio_input = TVAUDIO_INPUT_EXTERN,
3336+ .name = "S-Video",
3337+ },
3338+ {
3339+ .video_input = 3,
3340+ .audio_input = TVAUDIO_INPUT_TUNER,
3341+ .name = "Tuner",
3342+ },
3343+ },
3344+ },
3345+};
3346+
3347+static struct go7007_usb_board board_xmen = {
3348+ .flags = 0,
3349+ .main_info = {
3350+ .firmware = "go7007tv.bin",
3351+ .flags = GO7007_BOARD_USE_ONBOARD_I2C,
3352+ .hpi_buffer_cap = 0,
3353+ .sensor_flags = GO7007_SENSOR_VREF_POLAR,
3354+ .sensor_width = 320,
3355+ .sensor_height = 240,
3356+ .sensor_framerate = 30030,
3357+ .audio_flags = GO7007_AUDIO_ONE_CHANNEL |
3358+ GO7007_AUDIO_I2S_MODE_3 |
3359+ GO7007_AUDIO_WORD_14 |
3360+ GO7007_AUDIO_I2S_MASTER |
3361+ GO7007_AUDIO_BCLK_POLAR |
3362+ GO7007_AUDIO_OKI_MODE,
3363+ .audio_rate = 8000,
3364+ .audio_bclk_div = 48,
3365+ .audio_main_div = 1,
3366+ .num_i2c_devs = 1,
3367+ .i2c_devs = {
3368+ {
3369+ .id = I2C_DRIVERID_WIS_OV7640,
3370+ .addr = 0x21,
3371+ },
3372+ },
3373+ .num_inputs = 1,
3374+ .inputs = {
3375+ {
3376+ .name = "Camera",
3377+ },
3378+ },
3379+ },
3380+};
3381+
3382+static struct go7007_usb_board board_matrix_revolution = {
3383+ .flags = GO7007_USB_EZUSB,
3384+ .main_info = {
3385+ .firmware = "go7007tv.bin",
3386+ .flags = GO7007_BOARD_HAS_AUDIO |
3387+ GO7007_BOARD_USE_ONBOARD_I2C,
3388+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
3389+ GO7007_AUDIO_I2S_MASTER |
3390+ GO7007_AUDIO_WORD_16,
3391+ .audio_rate = 48000,
3392+ .audio_bclk_div = 8,
3393+ .audio_main_div = 2,
3394+ .hpi_buffer_cap = 7,
3395+ .sensor_flags = GO7007_SENSOR_656 |
3396+ GO7007_SENSOR_TV |
3397+ GO7007_SENSOR_VBI,
3398+ .num_i2c_devs = 1,
3399+ .i2c_devs = {
3400+ {
3401+ .id = I2C_DRIVERID_WIS_TW9903,
3402+ .addr = 0x44,
3403+ },
3404+ },
3405+ .num_inputs = 2,
3406+ .inputs = {
3407+ {
3408+ .video_input = 2,
3409+ .name = "Composite",
3410+ },
3411+ {
3412+ .video_input = 8,
3413+ .name = "S-Video",
3414+ },
3415+ },
3416+ },
3417+};
3418+
3419+static struct go7007_usb_board board_lifeview_lr192 = {
3420+ .flags = GO7007_USB_EZUSB,
3421+ .main_info = {
3422+ .firmware = "go7007tv.bin",
3423+ .flags = GO7007_BOARD_HAS_AUDIO |
3424+ GO7007_BOARD_USE_ONBOARD_I2C,
3425+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
3426+ GO7007_AUDIO_WORD_16,
3427+ .audio_rate = 48000,
3428+ .audio_bclk_div = 8,
3429+ .audio_main_div = 2,
3430+ .hpi_buffer_cap = 7,
3431+ .sensor_flags = GO7007_SENSOR_656 |
3432+ GO7007_SENSOR_VALID_ENABLE |
3433+ GO7007_SENSOR_TV |
3434+ GO7007_SENSOR_VBI |
3435+ GO7007_SENSOR_SCALING,
3436+ .num_i2c_devs = 0,
3437+ .num_inputs = 1,
3438+ .inputs = {
3439+ {
3440+ .video_input = 0,
3441+ .name = "Composite",
3442+ },
3443+ },
3444+ },
3445+};
3446+
3447+static struct go7007_usb_board board_endura = {
3448+ .flags = 0,
3449+ .main_info = {
3450+ .firmware = "go7007tv.bin",
3451+ .flags = 0,
3452+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
3453+ GO7007_AUDIO_I2S_MASTER |
3454+ GO7007_AUDIO_WORD_16,
3455+ .audio_rate = 8000,
3456+ .audio_bclk_div = 48,
3457+ .audio_main_div = 8,
3458+ .hpi_buffer_cap = 0,
3459+ .sensor_flags = GO7007_SENSOR_656 |
3460+ GO7007_SENSOR_TV,
3461+ .sensor_h_offset = 8,
3462+ .num_i2c_devs = 0,
3463+ .num_inputs = 1,
3464+ .inputs = {
3465+ {
3466+ .name = "Camera",
3467+ },
3468+ },
3469+ },
3470+};
3471+
3472+static struct go7007_usb_board board_adlink_mpg24 = {
3473+ .flags = 0,
3474+ .main_info = {
3475+ .firmware = "go7007tv.bin",
3476+ .flags = GO7007_BOARD_USE_ONBOARD_I2C,
3477+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
3478+ GO7007_AUDIO_I2S_MASTER |
3479+ GO7007_AUDIO_WORD_16,
3480+ .audio_rate = 48000,
3481+ .audio_bclk_div = 8,
3482+ .audio_main_div = 2,
3483+ .hpi_buffer_cap = 0,
3484+ .sensor_flags = GO7007_SENSOR_656 |
3485+ GO7007_SENSOR_TV |
3486+ GO7007_SENSOR_VBI,
3487+ .num_i2c_devs = 1,
3488+ .i2c_devs = {
3489+ {
3490+ .id = I2C_DRIVERID_WIS_TW2804,
3491+ .addr = 0x00, /* yes, really */
3492+ },
3493+ },
3494+ .num_inputs = 1,
3495+ .inputs = {
3496+ {
3497+ .name = "Composite",
3498+ },
3499+ },
3500+ },
3501+};
3502+
3503+static struct usb_device_id go7007_usb_id_table[] = {
3504+ {
3505+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
3506+ USB_DEVICE_ID_MATCH_INT_INFO,
3507+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
3508+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
3509+ .bcdDevice_lo = 0x200, /* Revision number of XMen */
3510+ .bcdDevice_hi = 0x200,
3511+ .bInterfaceClass = 255,
3512+ .bInterfaceSubClass = 0,
3513+ .bInterfaceProtocol = 255,
3514+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN,
3515+ },
3516+ {
3517+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
3518+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
3519+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
3520+ .bcdDevice_lo = 0x202, /* Revision number of Matrix II */
3521+ .bcdDevice_hi = 0x202,
3522+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_II,
3523+ },
3524+ {
3525+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
3526+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
3527+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
3528+ .bcdDevice_lo = 0x204, /* Revision number of Matrix */
3529+ .bcdDevice_hi = 0x204, /* Reloaded */
3530+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_RELOAD,
3531+ },
3532+ {
3533+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
3534+ USB_DEVICE_ID_MATCH_INT_INFO,
3535+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
3536+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
3537+ .bcdDevice_lo = 0x205, /* Revision number of XMen-II */
3538+ .bcdDevice_hi = 0x205,
3539+ .bInterfaceClass = 255,
3540+ .bInterfaceSubClass = 0,
3541+ .bInterfaceProtocol = 255,
3542+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_II,
3543+ },
3544+ {
3545+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
3546+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
3547+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
3548+ .bcdDevice_lo = 0x208, /* Revision number of Star Trek */
3549+ .bcdDevice_hi = 0x208,
3550+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_STAR_TREK,
3551+ },
3552+ {
3553+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
3554+ USB_DEVICE_ID_MATCH_INT_INFO,
3555+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
3556+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
3557+ .bcdDevice_lo = 0x209, /* Revision number of XMen-III */
3558+ .bcdDevice_hi = 0x209,
3559+ .bInterfaceClass = 255,
3560+ .bInterfaceSubClass = 0,
3561+ .bInterfaceProtocol = 255,
3562+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_III,
3563+ },
3564+ {
3565+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
3566+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
3567+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
3568+ .bcdDevice_lo = 0x210, /* Revision number of Matrix */
3569+ .bcdDevice_hi = 0x210, /* Revolution */
3570+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_REV,
3571+ },
3572+ {
3573+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
3574+ .idVendor = 0x093b, /* Vendor ID of Plextor */
3575+ .idProduct = 0xa102, /* Product ID of M402U */
3576+ .bcdDevice_lo = 0x1, /* revision number of Blueberry */
3577+ .bcdDevice_hi = 0x1,
3578+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_M402U,
3579+ },
3580+ {
3581+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
3582+ .idVendor = 0x093b, /* Vendor ID of Plextor */
3583+ .idProduct = 0xa104, /* Product ID of TV402U */
3584+ .bcdDevice_lo = 0x1,
3585+ .bcdDevice_hi = 0x1,
3586+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_TV402U_ANY,
3587+ },
3588+ {
3589+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
3590+ .idVendor = 0x10fd, /* Vendor ID of Anubis Electronics */
3591+ .idProduct = 0xde00, /* Product ID of Lifeview LR192 */
3592+ .bcdDevice_lo = 0x1,
3593+ .bcdDevice_hi = 0x1,
3594+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192,
3595+ },
3596+ { } /* Terminating entry */
3597+};
3598+
3599+MODULE_DEVICE_TABLE(usb, go7007_usb_id_table);
3600+
3601+/********************* Driver for EZ-USB HPI interface *********************/
3602+
3603+static int go7007_usb_vendor_request(struct go7007 *go, int request,
3604+ int value, int index, void *transfer_buffer, int length, int in)
3605+{
3606+ struct go7007_usb *usb = go->hpi_context;
3607+ int timeout = 5000;
3608+
3609+ if (in) {
3610+ return usb_control_msg(usb->usbdev,
3611+ usb_rcvctrlpipe(usb->usbdev, 0), request,
3612+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
3613+ value, index, transfer_buffer, length, timeout);
3614+ } else {
3615+ return usb_control_msg(usb->usbdev,
3616+ usb_sndctrlpipe(usb->usbdev, 0), request,
3617+ USB_TYPE_VENDOR | USB_RECIP_DEVICE,
3618+ value, index, transfer_buffer, length, timeout);
3619+ }
3620+}
3621+
3622+static int go7007_usb_interface_reset(struct go7007 *go)
3623+{
3624+ struct go7007_usb *usb = go->hpi_context;
3625+ u16 intr_val, intr_data;
3626+
3627+ /* Reset encoder */
3628+ if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
3629+ return -1;
3630+ msleep(100);
3631+
3632+ if (usb->board->flags & GO7007_USB_EZUSB) {
3633+ /* Reset buffer in EZ-USB */
3634+#ifdef GO7007_USB_DEBUG
3635+ printk(KERN_DEBUG "go7007-usb: resetting EZ-USB buffers\n");
3636+#endif
3637+ if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
3638+ go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
3639+ return -1;
3640+
3641+ /* Reset encoder again */
3642+ if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
3643+ return -1;
3644+ msleep(100);
3645+ }
3646+
3647+ /* Wait for an interrupt to indicate successful hardware reset */
3648+ if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
3649+ (intr_val & ~0x1) != 0x55aa) {
3650+ printk(KERN_ERR
3651+ "go7007-usb: unable to reset the USB interface\n");
3652+ return -1;
3653+ }
3654+ return 0;
3655+}
3656+
3657+static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
3658+ int addr, int data)
3659+{
3660+ struct go7007_usb *usb = go->hpi_context;
3661+ int i, r;
3662+ u16 status_reg;
3663+ int timeout = 500;
3664+
3665+#ifdef GO7007_USB_DEBUG
3666+ printk(KERN_DEBUG
3667+ "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
3668+#endif
3669+
3670+ for (i = 0; i < 100; ++i) {
3671+ r = usb_control_msg(usb->usbdev,
3672+ usb_rcvctrlpipe(usb->usbdev, 0), 0x14,
3673+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
3674+ 0, HPI_STATUS_ADDR, &status_reg,
3675+ sizeof(status_reg), timeout);
3676+ if (r < 0)
3677+ goto write_int_error;
3678+ __le16_to_cpus(&status_reg);
3679+ if (!(status_reg & 0x0010))
3680+ break;
3681+ msleep(10);
3682+ }
3683+ if (i == 100) {
3684+ printk(KERN_ERR
3685+ "go7007-usb: device is hung, status reg = 0x%04x\n",
3686+ status_reg);
3687+ return -1;
3688+ }
3689+ r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
3690+ USB_TYPE_VENDOR | USB_RECIP_DEVICE, data,
3691+ INT_PARAM_ADDR, NULL, 0, timeout);
3692+ if (r < 0)
3693+ goto write_int_error;
3694+ r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0),
3695+ 0x12, USB_TYPE_VENDOR | USB_RECIP_DEVICE, addr,
3696+ INT_INDEX_ADDR, NULL, 0, timeout);
3697+ if (r < 0)
3698+ goto write_int_error;
3699+ return 0;
3700+
3701+write_int_error:
3702+ printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
3703+ return r;
3704+}
3705+
3706+static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
3707+ int addr, int data)
3708+{
3709+ struct go7007_usb *usb = go->hpi_context;
3710+ u8 *tbuf;
3711+ int r;
3712+ int timeout = 500;
3713+
3714+#ifdef GO7007_USB_DEBUG
3715+ printk(KERN_DEBUG
3716+ "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
3717+#endif
3718+
3719+ tbuf = kmalloc(8, GFP_KERNEL);
3720+ if (tbuf == NULL)
3721+ return -ENOMEM;
3722+ memset(tbuf, 0, 8);
3723+ tbuf[0] = data & 0xff;
3724+ tbuf[1] = data >> 8;
3725+ tbuf[2] = addr & 0xff;
3726+ tbuf[3] = addr >> 8;
3727+ r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00,
3728+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
3729+ 0xf0f0, tbuf, 8, timeout);
3730+ kfree(tbuf);
3731+ if (r < 0) {
3732+ printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
3733+ return r;
3734+ }
3735+ return 0;
3736+}
3737+
3738+static void go7007_usb_readinterrupt_complete(struct urb *urb)
3739+{
3740+ struct go7007 *go = (struct go7007 *)urb->context;
3741+ u16 *regs = (u16 *)urb->transfer_buffer;
3742+
3743+ if (urb->status != 0) {
3744+ if (urb->status != -ESHUTDOWN &&
3745+ go->status != STATUS_SHUTDOWN) {
3746+ printk(KERN_ERR
3747+ "go7007-usb: error in read interrupt: %d\n",
3748+ urb->status);
3749+ } else {
3750+ wake_up(&go->interrupt_waitq);
3751+ return;
3752+ }
3753+ } else if (urb->actual_length != urb->transfer_buffer_length) {
3754+ printk(KERN_ERR "go7007-usb: short read in interrupt pipe!\n");
3755+ } else {
3756+ go->interrupt_available = 1;
3757+ go->interrupt_data = __le16_to_cpu(regs[0]);
3758+ go->interrupt_value = __le16_to_cpu(regs[1]);
3759+#ifdef GO7007_USB_DEBUG
3760+ printk(KERN_DEBUG "go7007-usb: ReadInterrupt: %04x %04x\n",
3761+ go->interrupt_value, go->interrupt_data);
3762+#endif
3763+ }
3764+
3765+ wake_up(&go->interrupt_waitq);
3766+}
3767+
3768+static int go7007_usb_read_interrupt(struct go7007 *go)
3769+{
3770+ struct go7007_usb *usb = go->hpi_context;
3771+ int r;
3772+
3773+ r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
3774+ if (r < 0) {
3775+ printk(KERN_ERR
3776+ "go7007-usb: unable to submit interrupt urb: %d\n", r);
3777+ return r;
3778+ }
3779+ return 0;
3780+}
3781+
3782+static void go7007_usb_read_video_pipe_complete(struct urb *urb)
3783+{
3784+ struct go7007 *go = (struct go7007 *)urb->context;
3785+ int r;
3786+
3787+ if (!go->streaming) {
3788+ wake_up_interruptible(&go->frame_waitq);
3789+ return;
3790+ }
3791+ if (urb->status != 0) {
3792+ printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
3793+ urb->status);
3794+ return;
3795+ }
3796+ if (urb->actual_length != urb->transfer_buffer_length) {
3797+ printk(KERN_ERR "go7007-usb: short read in video pipe!\n");
3798+ return;
3799+ }
3800+ go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
3801+ r = usb_submit_urb(urb, GFP_ATOMIC);
3802+ if (r < 0)
3803+ printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", r);
3804+}
3805+
3806+static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
3807+{
3808+ struct go7007 *go = (struct go7007 *)urb->context;
3809+ int r;
3810+
3811+ if (!go->streaming)
3812+ return;
3813+ if (urb->status != 0) {
3814+ printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
3815+ urb->status);
3816+ return;
3817+ }
3818+ if (urb->actual_length != urb->transfer_buffer_length) {
3819+ printk(KERN_ERR "go7007-usb: short read in audio pipe!\n");
3820+ return;
3821+ }
3822+ if (go->audio_deliver != NULL)
3823+ go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
3824+ r = usb_submit_urb(urb, GFP_ATOMIC);
3825+ if (r < 0)
3826+ printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", r);
3827+}
3828+
3829+static int go7007_usb_stream_start(struct go7007 *go)
3830+{
3831+ struct go7007_usb *usb = go->hpi_context;
3832+ int i, r;
3833+
3834+ for (i = 0; i < 8; ++i) {
3835+ r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
3836+ if (r < 0) {
3837+ printk(KERN_ERR "go7007-usb: error submitting video "
3838+ "urb %d: %d\n", i, r);
3839+ goto video_submit_failed;
3840+ }
3841+ }
3842+ if (!go->audio_enabled)
3843+ return 0;
3844+
3845+ for (i = 0; i < 8; ++i) {
3846+ r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
3847+ if (r < 0) {
3848+ printk(KERN_ERR "go7007-usb: error submitting audio "
3849+ "urb %d: %d\n", i, r);
3850+ goto audio_submit_failed;
3851+ }
3852+ }
3853+ return 0;
3854+
3855+audio_submit_failed:
3856+ for (i = 0; i < 8; ++i)
3857+ usb_kill_urb(usb->audio_urbs[i]);
3858+video_submit_failed:
3859+ for (i = 0; i < 8; ++i)
3860+ usb_kill_urb(usb->video_urbs[i]);
3861+ return -1;
3862+}
3863+
3864+static int go7007_usb_stream_stop(struct go7007 *go)
3865+{
3866+ struct go7007_usb *usb = go->hpi_context;
3867+ int i;
3868+
3869+ if (go->status == STATUS_SHUTDOWN)
3870+ return 0;
3871+ for (i = 0; i < 8; ++i)
3872+ usb_kill_urb(usb->video_urbs[i]);
3873+ if (go->audio_enabled)
3874+ for (i = 0; i < 8; ++i)
3875+ usb_kill_urb(usb->audio_urbs[i]);
3876+ return 0;
3877+}
3878+
3879+static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
3880+{
3881+ struct go7007_usb *usb = go->hpi_context;
3882+ int transferred, pipe;
3883+ int timeout = 500;
3884+
3885+#ifdef GO7007_USB_DEBUG
3886+ printk(KERN_DEBUG "go7007-usb: DownloadBuffer sending %d bytes\n", len);
3887+#endif
3888+
3889+ if (usb->board->flags & GO7007_USB_EZUSB)
3890+ pipe = usb_sndbulkpipe(usb->usbdev, 2);
3891+ else
3892+ pipe = usb_sndbulkpipe(usb->usbdev, 3);
3893+
3894+ return usb_bulk_msg(usb->usbdev, pipe, data, len,
3895+ &transferred, timeout);
3896+}
3897+
3898+static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
3899+ .interface_reset = go7007_usb_interface_reset,
3900+ .write_interrupt = go7007_usb_ezusb_write_interrupt,
3901+ .read_interrupt = go7007_usb_read_interrupt,
3902+ .stream_start = go7007_usb_stream_start,
3903+ .stream_stop = go7007_usb_stream_stop,
3904+ .send_firmware = go7007_usb_send_firmware,
3905+};
3906+
3907+static struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
3908+ .interface_reset = go7007_usb_interface_reset,
3909+ .write_interrupt = go7007_usb_onboard_write_interrupt,
3910+ .read_interrupt = go7007_usb_read_interrupt,
3911+ .stream_start = go7007_usb_stream_start,
3912+ .stream_stop = go7007_usb_stream_stop,
3913+ .send_firmware = go7007_usb_send_firmware,
3914+};
3915+
3916+/********************* Driver for EZ-USB I2C adapter *********************/
3917+
3918+static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
3919+ struct i2c_msg msgs[], int num)
3920+{
3921+ struct go7007 *go = i2c_get_adapdata(adapter);
3922+ struct go7007_usb *usb = go->hpi_context;
3923+ u8 buf[16];
3924+ int buf_len, i;
3925+ int ret = -1;
3926+
3927+ if (go->status == STATUS_SHUTDOWN)
3928+ return -1;
3929+
3930+ down(&usb->i2c_lock);
3931+
3932+ for (i = 0; i < num; ++i) {
3933+ /* The hardware command is "write some bytes then read some
3934+ * bytes", so we try to coalesce a write followed by a read
3935+ * into a single USB transaction */
3936+ if (i + 1 < num && msgs[i].addr == msgs[i + 1].addr &&
3937+ !(msgs[i].flags & I2C_M_RD) &&
3938+ (msgs[i + 1].flags & I2C_M_RD)) {
3939+#ifdef GO7007_I2C_DEBUG
3940+ printk(KERN_DEBUG "go7007-usb: i2c write/read %d/%d "
3941+ "bytes on %02x\n", msgs[i].len,
3942+ msgs[i + 1].len, msgs[i].addr);
3943+#endif
3944+ buf[0] = 0x01;
3945+ buf[1] = msgs[i].len + 1;
3946+ buf[2] = msgs[i].addr << 1;
3947+ memcpy(&buf[3], msgs[i].buf, msgs[i].len);
3948+ buf_len = msgs[i].len + 3;
3949+ buf[buf_len++] = msgs[++i].len;
3950+ } else if (msgs[i].flags & I2C_M_RD) {
3951+#ifdef GO7007_I2C_DEBUG
3952+ printk(KERN_DEBUG "go7007-usb: i2c read %d "
3953+ "bytes on %02x\n", msgs[i].len,
3954+ msgs[i].addr);
3955+#endif
3956+ buf[0] = 0x01;
3957+ buf[1] = 1;
3958+ buf[2] = msgs[i].addr << 1;
3959+ buf[3] = msgs[i].len;
3960+ buf_len = 4;
3961+ } else {
3962+#ifdef GO7007_I2C_DEBUG
3963+ printk(KERN_DEBUG "go7007-usb: i2c write %d "
3964+ "bytes on %02x\n", msgs[i].len,
3965+ msgs[i].addr);
3966+#endif
3967+ buf[0] = 0x00;
3968+ buf[1] = msgs[i].len + 1;
3969+ buf[2] = msgs[i].addr << 1;
3970+ memcpy(&buf[3], msgs[i].buf, msgs[i].len);
3971+ buf_len = msgs[i].len + 3;
3972+ buf[buf_len++] = 0;
3973+ }
3974+ if (go7007_usb_vendor_request(go, 0x24, 0, 0,
3975+ buf, buf_len, 0) < 0)
3976+ goto i2c_done;
3977+ if (msgs[i].flags & I2C_M_RD) {
3978+ memset(buf, 0, sizeof(buf));
3979+ if (go7007_usb_vendor_request(go, 0x25, 0, 0, buf,
3980+ msgs[i].len + 1, 1) < 0)
3981+ goto i2c_done;
3982+ memcpy(msgs[i].buf, buf + 1, msgs[i].len);
3983+ }
3984+ }
3985+ ret = 0;
3986+
3987+i2c_done:
3988+ up(&usb->i2c_lock);
3989+ return ret;
3990+}
3991+
3992+static u32 go7007_usb_functionality(struct i2c_adapter *adapter)
3993+{
3994+ /* No errors are reported by the hardware, so we don't bother
3995+ * supporting quick writes to avoid confusing probing */
3996+ return (I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK;
3997+}
3998+
3999+static struct i2c_algorithm go7007_usb_algo = {
4000+ .master_xfer = go7007_usb_i2c_master_xfer,
4001+ .functionality = go7007_usb_functionality,
4002+};
4003+
4004+static struct i2c_adapter go7007_usb_adap_templ = {
4005+ .owner = THIS_MODULE,
4006+ .class = I2C_CLASS_TV_ANALOG,
4007+ .name = "WIS GO7007SB EZ-USB",
4008+ .id = I2C_ALGO_GO7007_USB,
4009+ .algo = &go7007_usb_algo,
4010+};
4011+
4012+/********************* USB add/remove functions *********************/
4013+
4014+static int go7007_usb_probe(struct usb_interface *intf,
4015+ const struct usb_device_id *id)
4016+{
4017+ struct go7007 *go;
4018+ struct go7007_usb *usb;
4019+ struct go7007_usb_board *board;
4020+ struct usb_device *usbdev = interface_to_usbdev(intf);
4021+ char *name;
4022+ int video_pipe, i, v_urb_len;
4023+
4024+ printk(KERN_DEBUG "go7007-usb: probing new GO7007 USB board\n");
4025+
4026+ switch (id->driver_info) {
4027+ case GO7007_BOARDID_MATRIX_II:
4028+ name = "WIS Matrix II or compatible";
4029+ board = &board_matrix_ii;
4030+ break;
4031+ case GO7007_BOARDID_MATRIX_RELOAD:
4032+ name = "WIS Matrix Reloaded or compatible";
4033+ board = &board_matrix_reload;
4034+ break;
4035+ case GO7007_BOARDID_MATRIX_REV:
4036+ name = "WIS Matrix Revolution or compatible";
4037+ board = &board_matrix_revolution;
4038+ break;
4039+ case GO7007_BOARDID_STAR_TREK:
4040+ name = "WIS Star Trek or compatible";
4041+ board = &board_star_trek;
4042+ break;
4043+ case GO7007_BOARDID_XMEN:
4044+ name = "WIS XMen or compatible";
4045+ board = &board_xmen;
4046+ break;
4047+ case GO7007_BOARDID_XMEN_II:
4048+ name = "WIS XMen II or compatible";
4049+ board = &board_xmen;
4050+ break;
4051+ case GO7007_BOARDID_XMEN_III:
4052+ name = "WIS XMen III or compatible";
4053+ board = &board_xmen;
4054+ break;
4055+ case GO7007_BOARDID_PX_M402U:
4056+ name = "Plextor PX-M402U";
4057+ board = &board_matrix_ii;
4058+ break;
4059+ case GO7007_BOARDID_PX_TV402U_ANY:
4060+ name = "Plextor PX-TV402U (unknown tuner)";
4061+ board = &board_px_tv402u;
4062+ break;
4063+ case GO7007_BOARDID_LIFEVIEW_LR192:
4064+ printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
4065+ "is not supported. Sorry!\n");
4066+ return 0;
4067+ name = "Lifeview TV Walker Ultra";
4068+ board = &board_lifeview_lr192;
4069+ break;
4070+ default:
4071+ printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
4072+ (unsigned int)id->driver_info);
4073+ return 0;
4074+ }
4075+
4076+ usb = kmalloc(sizeof(struct go7007_usb), GFP_KERNEL);
4077+ if (usb == NULL)
4078+ return -ENOMEM;
4079+ memset(usb, 0, sizeof(struct go7007_usb));
4080+
4081+ /* Allocate the URB and buffer for receiving incoming interrupts */
4082+ usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
4083+ if (usb->intr_urb == NULL)
4084+ goto allocfail;
4085+ usb->intr_urb->transfer_buffer = kmalloc(2*sizeof(u16), GFP_KERNEL);
4086+ if (usb->intr_urb->transfer_buffer == NULL)
4087+ goto allocfail;
4088+
4089+ go = go7007_alloc(&board->main_info, &intf->dev);
4090+ if (go == NULL)
4091+ goto allocfail;
4092+ usb->board = board;
4093+ usb->usbdev = usbdev;
4094+ go->board_id = id->driver_info;
4095+ strncpy(go->name, name, sizeof(go->name));
4096+ if (board->flags & GO7007_USB_EZUSB)
4097+ go->hpi_ops = &go7007_usb_ezusb_hpi_ops;
4098+ else
4099+ go->hpi_ops = &go7007_usb_onboard_hpi_ops;
4100+ go->hpi_context = usb;
4101+ usb_fill_int_urb(usb->intr_urb, usb->usbdev,
4102+ usb_rcvintpipe(usb->usbdev, 4),
4103+ usb->intr_urb->transfer_buffer, 2*sizeof(u16),
4104+ go7007_usb_readinterrupt_complete, go, 8);
4105+ usb_set_intfdata(intf, go);
4106+
4107+ /* Boot the GO7007 */
4108+ if (go7007_boot_encoder(go, go->board_info->flags &
4109+ GO7007_BOARD_USE_ONBOARD_I2C) < 0)
4110+ goto initfail;
4111+
4112+ /* Register the EZ-USB I2C adapter, if we're using it */
4113+ if (board->flags & GO7007_USB_EZUSB_I2C) {
4114+ memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
4115+ sizeof(go7007_usb_adap_templ));
4116+ init_MUTEX(&usb->i2c_lock);
4117+ go->i2c_adapter.dev.parent = go->dev;
4118+ i2c_set_adapdata(&go->i2c_adapter, go);
4119+ if (i2c_add_adapter(&go->i2c_adapter) < 0) {
4120+ printk(KERN_ERR
4121+ "go7007-usb: error: i2c_add_adapter failed\n");
4122+ goto initfail;
4123+ }
4124+ go->i2c_adapter_online = 1;
4125+ }
4126+
4127+ /* Pelco and Adlink reused the XMen and XMen-III vendor and product
4128+ * IDs for their own incompatible designs. We can detect XMen boards
4129+ * by probing the sensor, but there is no way to probe the sensors on
4130+ * the Pelco and Adlink designs so we default to the Adlink. If it
4131+ * is actually a Pelco, the user must set the assume_endura module
4132+ * parameter. */
4133+ if ((go->board_id == GO7007_BOARDID_XMEN ||
4134+ go->board_id == GO7007_BOARDID_XMEN_III) &&
4135+ go->i2c_adapter_online) {
4136+ union i2c_smbus_data data;
4137+
4138+ /* Check to see if register 0x0A is 0x76 */
4139+ i2c_smbus_xfer(&go->i2c_adapter, 0x21, I2C_CLIENT_SCCB,
4140+ I2C_SMBUS_READ, 0x0A, I2C_SMBUS_BYTE_DATA, &data);
4141+ if (data.byte != 0x76) {
4142+ if (assume_endura) {
4143+ go->board_id = GO7007_BOARDID_ENDURA;
4144+ usb->board = board = &board_endura;
4145+ go->board_info = &board->main_info;
4146+ strncpy(go->name, "Pelco Endura",
4147+ sizeof(go->name));
4148+ } else {
4149+ u16 channel;
4150+
4151+ /* set GPIO5 to be an output, currently low */
4152+ go7007_write_addr(go, 0x3c82, 0x0000);
4153+ go7007_write_addr(go, 0x3c80, 0x00df);
4154+ /* read channel number from GPIO[1:0] */
4155+ go7007_read_addr(go, 0x3c81, &channel);
4156+ channel &= 0x3;
4157+ go->board_id = GO7007_BOARDID_ADLINK_MPG24;
4158+ usb->board = board = &board_adlink_mpg24;
4159+ go->board_info = &board->main_info;
4160+ go->channel_number = channel;
4161+ snprintf(go->name, sizeof(go->name),
4162+ "Adlink PCI-MPG24, channel #%d",
4163+ channel);
4164+ }
4165+ }
4166+ }
4167+
4168+ /* Probe the tuner model on the TV402U */
4169+ if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) {
4170+ u8 data[3];
4171+
4172+ /* Board strapping indicates tuner model */
4173+ if (go7007_usb_vendor_request(go, 0x41, 0, 0, data, 3, 1) < 0) {
4174+ printk(KERN_ERR "go7007-usb: GPIO read failed!\n");
4175+ goto initfail;
4176+ }
4177+ switch (data[0] >> 6) {
4178+ case 1:
4179+ go->board_id = GO7007_BOARDID_PX_TV402U_EU;
4180+ go->tuner_type = TUNER_SONY_BTF_PG472Z;
4181+ strncpy(go->name, "Plextor PX-TV402U-EU",
4182+ sizeof(go->name));
4183+ break;
4184+ case 2:
4185+ go->board_id = GO7007_BOARDID_PX_TV402U_JP;
4186+ go->tuner_type = TUNER_SONY_BTF_PK467Z;
4187+ strncpy(go->name, "Plextor PX-TV402U-JP",
4188+ sizeof(go->name));
4189+ break;
4190+ case 3:
4191+ go->board_id = GO7007_BOARDID_PX_TV402U_NA;
4192+ go->tuner_type = TUNER_SONY_BTF_PB463Z;
4193+ strncpy(go->name, "Plextor PX-TV402U-NA",
4194+ sizeof(go->name));
4195+ break;
4196+ default:
4197+ printk(KERN_DEBUG "go7007-usb: unable to detect "
4198+ "tuner type!\n");
4199+ break;
4200+ }
4201+ /* Configure tuner mode selection inputs connected
4202+ * to the EZ-USB GPIO output pins */
4203+ if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
4204+ NULL, 0, 0) < 0) {
4205+ printk(KERN_ERR
4206+ "go7007-usb: GPIO write failed!\n");
4207+ goto initfail;
4208+ }
4209+ }
4210+
4211+ /* Print a nasty message if the user attempts to use a USB2.0 device in
4212+ * a USB1.1 port. There will be silent corruption of the stream. */
4213+ if ((board->flags & GO7007_USB_EZUSB) &&
4214+ usbdev->speed != USB_SPEED_HIGH)
4215+ printk(KERN_ERR "go7007-usb: *** WARNING *** This device "
4216+ "must be connected to a USB 2.0 port! "
4217+ "Attempting to capture video through a USB 1.1 "
4218+ "port will result in stream corruption, even "
4219+ "at low bitrates!\n");
4220+
4221+ /* Do any final GO7007 initialization, then register the
4222+ * V4L2 and ALSA interfaces */
4223+ if (go7007_register_encoder(go) < 0)
4224+ goto initfail;
4225+
4226+ /* Allocate the URBs and buffers for receiving the video stream */
4227+ if (board->flags & GO7007_USB_EZUSB) {
4228+ v_urb_len = 1024;
4229+ video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
4230+ } else {
4231+ v_urb_len = 512;
4232+ video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
4233+ }
4234+ for (i = 0; i < 8; ++i) {
4235+ usb->video_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
4236+ if (usb->video_urbs[i] == NULL)
4237+ goto initfail;
4238+ usb->video_urbs[i]->transfer_buffer =
4239+ kmalloc(v_urb_len, GFP_KERNEL);
4240+ if (usb->video_urbs[i]->transfer_buffer == NULL)
4241+ goto initfail;
4242+ usb_fill_bulk_urb(usb->video_urbs[i], usb->usbdev, video_pipe,
4243+ usb->video_urbs[i]->transfer_buffer, v_urb_len,
4244+ go7007_usb_read_video_pipe_complete, go);
4245+ }
4246+
4247+ /* Allocate the URBs and buffers for receiving the audio stream */
4248+ if ((board->flags & GO7007_USB_EZUSB) && go->audio_enabled)
4249+ for (i = 0; i < 8; ++i) {
4250+ usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
4251+ if (usb->audio_urbs[i] == NULL)
4252+ goto initfail;
4253+ usb->audio_urbs[i]->transfer_buffer = kmalloc(4096,
4254+ GFP_KERNEL);
4255+ if (usb->audio_urbs[i]->transfer_buffer == NULL)
4256+ goto initfail;
4257+ usb_fill_bulk_urb(usb->audio_urbs[i], usb->usbdev,
4258+ usb_rcvbulkpipe(usb->usbdev, 8),
4259+ usb->audio_urbs[i]->transfer_buffer, 4096,
4260+ go7007_usb_read_audio_pipe_complete, go);
4261+ }
4262+
4263+
4264+ go->status = STATUS_ONLINE;
4265+ return 0;
4266+
4267+initfail:
4268+ go->status = STATUS_SHUTDOWN;
4269+ return 0;
4270+
4271+allocfail:
4272+ if (usb->intr_urb) {
4273+ kfree(usb->intr_urb->transfer_buffer);
4274+ usb_free_urb(usb->intr_urb);
4275+ }
4276+ kfree(usb);
4277+ return -ENOMEM;
4278+}
4279+
4280+static void go7007_usb_disconnect(struct usb_interface *intf)
4281+{
4282+ struct go7007 *go = usb_get_intfdata(intf);
4283+ struct go7007_usb *usb = go->hpi_context;
4284+ int i;
4285+
4286+ go->status = STATUS_SHUTDOWN;
4287+ usb_kill_urb(usb->intr_urb);
4288+
4289+ /* Free USB-related structs */
4290+ for (i = 0; i < 8; ++i) {
4291+ if (usb->video_urbs[i] != NULL) {
4292+ if (usb->video_urbs[i]->transfer_buffer != NULL)
4293+ kfree(usb->video_urbs[i]->transfer_buffer);
4294+ usb_free_urb(usb->video_urbs[i]);
4295+ }
4296+ if (usb->audio_urbs[i] != NULL) {
4297+ if (usb->audio_urbs[i]->transfer_buffer != NULL)
4298+ kfree(usb->audio_urbs[i]->transfer_buffer);
4299+ usb_free_urb(usb->audio_urbs[i]);
4300+ }
4301+ }
4302+ kfree(usb->intr_urb->transfer_buffer);
4303+ usb_free_urb(usb->intr_urb);
4304+
4305+ kfree(go->hpi_context);
4306+
4307+ go7007_remove(go);
4308+}
4309+
4310+static struct usb_driver go7007_usb_driver = {
4311+ .name = "go7007",
4312+ .probe = go7007_usb_probe,
4313+ .disconnect = go7007_usb_disconnect,
4314+ .id_table = go7007_usb_id_table,
4315+};
4316+
4317+static int __init go7007_usb_init(void)
4318+{
4319+ return usb_register(&go7007_usb_driver);
4320+}
4321+
4322+static void __exit go7007_usb_cleanup(void)
4323+{
4324+ usb_deregister(&go7007_usb_driver);
4325+}
4326+
4327+module_init(go7007_usb_init);
4328+module_exit(go7007_usb_cleanup);
4329+
4330+MODULE_LICENSE("GPL v2");
4331diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
4332new file mode 100644
4333index 0000000..d54d019
4334--- /dev/null
4335+++ b/drivers/staging/go7007/go7007-v4l2.c
4336@@ -0,0 +1,1503 @@
4337+/*
4338+ * Copyright (C) 2005-2006 Micronas USA Inc.
4339+ *
4340+ * This program is free software; you can redistribute it and/or modify
4341+ * it under the terms of the GNU General Public License (Version 2) as
4342+ * published by the Free Software Foundation.
4343+ *
4344+ * This program is distributed in the hope that it will be useful,
4345+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4346+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4347+ * GNU General Public License for more details.
4348+ *
4349+ * You should have received a copy of the GNU General Public License
4350+ * along with this program; if not, write to the Free Software Foundation,
4351+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
4352+ */
4353+
4354+#include <linux/module.h>
4355+#include <linux/init.h>
4356+#include <linux/version.h>
4357+#include <linux/delay.h>
4358+#include <linux/sched.h>
4359+#include <linux/spinlock.h>
4360+#include <linux/fs.h>
4361+#include <linux/unistd.h>
4362+#include <linux/time.h>
4363+#include <linux/vmalloc.h>
4364+#include <linux/pagemap.h>
4365+#include <linux/videodev.h>
4366+#include <linux/video_decoder.h>
4367+#include <media/v4l2-common.h>
4368+#include <media/v4l2-ioctl.h>
4369+#include <linux/i2c.h>
4370+#include <linux/semaphore.h>
4371+#include <linux/uaccess.h>
4372+#include <asm/system.h>
4373+
4374+#include "go7007.h"
4375+#include "go7007-priv.h"
4376+#include "wis-i2c.h"
4377+
4378+static void deactivate_buffer(struct go7007_buffer *gobuf)
4379+{
4380+ int i;
4381+
4382+ if (gobuf->state != BUF_STATE_IDLE) {
4383+ list_del(&gobuf->stream);
4384+ gobuf->state = BUF_STATE_IDLE;
4385+ }
4386+ if (gobuf->page_count > 0) {
4387+ for (i = 0; i < gobuf->page_count; ++i)
4388+ page_cache_release(gobuf->pages[i]);
4389+ gobuf->page_count = 0;
4390+ }
4391+}
4392+
4393+static void abort_queued(struct go7007 *go)
4394+{
4395+ struct go7007_buffer *gobuf, *next;
4396+
4397+ list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
4398+ deactivate_buffer(gobuf);
4399+ }
4400+}
4401+
4402+static int go7007_streamoff(struct go7007 *go)
4403+{
4404+ int retval = -EINVAL;
4405+ unsigned long flags;
4406+
4407+ down(&go->hw_lock);
4408+ if (go->streaming) {
4409+ go->streaming = 0;
4410+ go7007_stream_stop(go);
4411+ spin_lock_irqsave(&go->spinlock, flags);
4412+ abort_queued(go);
4413+ spin_unlock_irqrestore(&go->spinlock, flags);
4414+ go7007_reset_encoder(go);
4415+ retval = 0;
4416+ }
4417+ up(&go->hw_lock);
4418+ return 0;
4419+}
4420+
4421+static int go7007_open(struct inode *inode, struct file *file)
4422+{
4423+ struct go7007 *go = video_get_drvdata(video_devdata(file));
4424+ struct go7007_file *gofh;
4425+
4426+ if (go->status != STATUS_ONLINE)
4427+ return -EBUSY;
4428+ gofh = kmalloc(sizeof(struct go7007_file), GFP_KERNEL);
4429+ if (gofh == NULL)
4430+ return -ENOMEM;
4431+ ++go->ref_count;
4432+ gofh->go = go;
4433+ init_MUTEX(&gofh->lock);
4434+ gofh->buf_count = 0;
4435+ file->private_data = gofh;
4436+ return 0;
4437+}
4438+
4439+static int go7007_release(struct inode *inode, struct file *file)
4440+{
4441+ struct go7007_file *gofh = file->private_data;
4442+ struct go7007 *go = gofh->go;
4443+
4444+ if (gofh->buf_count > 0) {
4445+ go7007_streamoff(go);
4446+ go->in_use = 0;
4447+ kfree(gofh->bufs);
4448+ gofh->buf_count = 0;
4449+ }
4450+ kfree(gofh);
4451+ if (--go->ref_count == 0)
4452+ kfree(go);
4453+ file->private_data = NULL;
4454+ return 0;
4455+}
4456+
4457+static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
4458+{
4459+ u8 *f = page_address(gobuf->pages[0]);
4460+
4461+ switch (format) {
4462+ case GO7007_FORMAT_MJPEG:
4463+ return V4L2_BUF_FLAG_KEYFRAME;
4464+ case GO7007_FORMAT_MPEG4:
4465+ switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
4466+ case 0:
4467+ return V4L2_BUF_FLAG_KEYFRAME;
4468+ case 1:
4469+ return V4L2_BUF_FLAG_PFRAME;
4470+ case 2:
4471+ return V4L2_BUF_FLAG_BFRAME;
4472+ default:
4473+ return 0;
4474+ }
4475+ case GO7007_FORMAT_MPEG1:
4476+ case GO7007_FORMAT_MPEG2:
4477+ switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
4478+ case 1:
4479+ return V4L2_BUF_FLAG_KEYFRAME;
4480+ case 2:
4481+ return V4L2_BUF_FLAG_PFRAME;
4482+ case 3:
4483+ return V4L2_BUF_FLAG_BFRAME;
4484+ default:
4485+ return 0;
4486+ }
4487+ }
4488+
4489+ return 0;
4490+}
4491+
4492+static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
4493+{
4494+ int sensor_height = 0, sensor_width = 0;
4495+ int width, height, i;
4496+
4497+ if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
4498+ fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
4499+ fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
4500+ return -EINVAL;
4501+
4502+ switch (go->standard) {
4503+ case GO7007_STD_NTSC:
4504+ sensor_width = 720;
4505+ sensor_height = 480;
4506+ break;
4507+ case GO7007_STD_PAL:
4508+ sensor_width = 720;
4509+ sensor_height = 576;
4510+ break;
4511+ case GO7007_STD_OTHER:
4512+ sensor_width = go->board_info->sensor_width;
4513+ sensor_height = go->board_info->sensor_height;
4514+ break;
4515+ }
4516+
4517+ if (fmt == NULL) {
4518+ width = sensor_width;
4519+ height = sensor_height;
4520+ } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
4521+ if (fmt->fmt.pix.width > sensor_width)
4522+ width = sensor_width;
4523+ else if (fmt->fmt.pix.width < 144)
4524+ width = 144;
4525+ else
4526+ width = fmt->fmt.pix.width & ~0x0f;
4527+
4528+ if (fmt->fmt.pix.height > sensor_height)
4529+ height = sensor_height;
4530+ else if (fmt->fmt.pix.height < 96)
4531+ height = 96;
4532+ else
4533+ height = fmt->fmt.pix.height & ~0x0f;
4534+ } else {
4535+ int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height;
4536+ int sensor_size = sensor_width * sensor_height;
4537+
4538+ if (64 * requested_size < 9 * sensor_size) {
4539+ width = sensor_width / 4;
4540+ height = sensor_height / 4;
4541+ } else if (64 * requested_size < 36 * sensor_size) {
4542+ width = sensor_width / 2;
4543+ height = sensor_height / 2;
4544+ } else {
4545+ width = sensor_width;
4546+ height = sensor_height;
4547+ }
4548+ width &= ~0xf;
4549+ height &= ~0xf;
4550+ }
4551+
4552+ if (fmt != NULL) {
4553+ u32 pixelformat = fmt->fmt.pix.pixelformat;
4554+
4555+ memset(fmt, 0, sizeof(*fmt));
4556+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4557+ fmt->fmt.pix.width = width;
4558+ fmt->fmt.pix.height = height;
4559+ fmt->fmt.pix.pixelformat = pixelformat;
4560+ fmt->fmt.pix.field = V4L2_FIELD_NONE;
4561+ fmt->fmt.pix.bytesperline = 0;
4562+ fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
4563+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
4564+ }
4565+
4566+ if (try)
4567+ return 0;
4568+
4569+ go->width = width;
4570+ go->height = height;
4571+ go->encoder_h_offset = go->board_info->sensor_h_offset;
4572+ go->encoder_v_offset = go->board_info->sensor_v_offset;
4573+ for (i = 0; i < 4; ++i)
4574+ go->modet[i].enable = 0;
4575+ for (i = 0; i < 1624; ++i)
4576+ go->modet_map[i] = 0;
4577+
4578+ if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
4579+ struct video_decoder_resolution res;
4580+
4581+ res.width = width;
4582+ if (height > sensor_height / 2) {
4583+ res.height = height / 2;
4584+ go->encoder_v_halve = 0;
4585+ } else {
4586+ res.height = height;
4587+ go->encoder_v_halve = 1;
4588+ }
4589+ if (go->i2c_adapter_online)
4590+ i2c_clients_command(&go->i2c_adapter,
4591+ DECODER_SET_RESOLUTION, &res);
4592+ } else {
4593+ if (width <= sensor_width / 4) {
4594+ go->encoder_h_halve = 1;
4595+ go->encoder_v_halve = 1;
4596+ go->encoder_subsample = 1;
4597+ } else if (width <= sensor_width / 2) {
4598+ go->encoder_h_halve = 1;
4599+ go->encoder_v_halve = 1;
4600+ go->encoder_subsample = 0;
4601+ } else {
4602+ go->encoder_h_halve = 0;
4603+ go->encoder_v_halve = 0;
4604+ go->encoder_subsample = 0;
4605+ }
4606+ }
4607+
4608+ if (fmt == NULL)
4609+ return 0;
4610+
4611+ switch (fmt->fmt.pix.pixelformat) {
4612+ case V4L2_PIX_FMT_MPEG:
4613+ if (go->format == GO7007_FORMAT_MPEG1 ||
4614+ go->format == GO7007_FORMAT_MPEG2 ||
4615+ go->format == GO7007_FORMAT_MPEG4)
4616+ break;
4617+ go->format = GO7007_FORMAT_MPEG1;
4618+ go->pali = 0;
4619+ go->aspect_ratio = GO7007_RATIO_1_1;
4620+ go->gop_size = go->sensor_framerate / 1000;
4621+ go->ipb = 0;
4622+ go->closed_gop = 1;
4623+ go->repeat_seqhead = 1;
4624+ go->seq_header_enable = 1;
4625+ go->gop_header_enable = 1;
4626+ go->dvd_mode = 0;
4627+ break;
4628+ /* Backwards compatibility only! */
4629+ case V4L2_PIX_FMT_MPEG4:
4630+ if (go->format == GO7007_FORMAT_MPEG4)
4631+ break;
4632+ go->format = GO7007_FORMAT_MPEG4;
4633+ go->pali = 0xf5;
4634+ go->aspect_ratio = GO7007_RATIO_1_1;
4635+ go->gop_size = go->sensor_framerate / 1000;
4636+ go->ipb = 0;
4637+ go->closed_gop = 1;
4638+ go->repeat_seqhead = 1;
4639+ go->seq_header_enable = 1;
4640+ go->gop_header_enable = 1;
4641+ go->dvd_mode = 0;
4642+ break;
4643+ case V4L2_PIX_FMT_MJPEG:
4644+ go->format = GO7007_FORMAT_MJPEG;
4645+ go->pali = 0;
4646+ go->aspect_ratio = GO7007_RATIO_1_1;
4647+ go->gop_size = 0;
4648+ go->ipb = 0;
4649+ go->closed_gop = 0;
4650+ go->repeat_seqhead = 0;
4651+ go->seq_header_enable = 0;
4652+ go->gop_header_enable = 0;
4653+ go->dvd_mode = 0;
4654+ break;
4655+ }
4656+ return 0;
4657+}
4658+
4659+static int clip_to_modet_map(struct go7007 *go, int region,
4660+ struct v4l2_clip *clip_list)
4661+{
4662+ struct v4l2_clip clip, *clip_ptr;
4663+ int x, y, mbnum;
4664+
4665+ /* Check if coordinates are OK and if any macroblocks are already
4666+ * used by other regions (besides 0) */
4667+ clip_ptr = clip_list;
4668+ while (clip_ptr) {
4669+ if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
4670+ return -EFAULT;
4671+ if (clip.c.left < 0 || (clip.c.left & 0xF) ||
4672+ clip.c.width <= 0 || (clip.c.width & 0xF))
4673+ return -EINVAL;
4674+ if (clip.c.left + clip.c.width > go->width)
4675+ return -EINVAL;
4676+ if (clip.c.top < 0 || (clip.c.top & 0xF) ||
4677+ clip.c.height <= 0 || (clip.c.height & 0xF))
4678+ return -EINVAL;
4679+ if (clip.c.top + clip.c.height > go->height)
4680+ return -EINVAL;
4681+ for (y = 0; y < clip.c.height; y += 16)
4682+ for (x = 0; x < clip.c.width; x += 16) {
4683+ mbnum = (go->width >> 4) *
4684+ ((clip.c.top + y) >> 4) +
4685+ ((clip.c.left + x) >> 4);
4686+ if (go->modet_map[mbnum] != 0 &&
4687+ go->modet_map[mbnum] != region)
4688+ return -EBUSY;
4689+ }
4690+ clip_ptr = clip.next;
4691+ }
4692+
4693+ /* Clear old region macroblocks */
4694+ for (mbnum = 0; mbnum < 1624; ++mbnum)
4695+ if (go->modet_map[mbnum] == region)
4696+ go->modet_map[mbnum] = 0;
4697+
4698+ /* Claim macroblocks in this list */
4699+ clip_ptr = clip_list;
4700+ while (clip_ptr) {
4701+ if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
4702+ return -EFAULT;
4703+ for (y = 0; y < clip.c.height; y += 16)
4704+ for (x = 0; x < clip.c.width; x += 16) {
4705+ mbnum = (go->width >> 4) *
4706+ ((clip.c.top + y) >> 4) +
4707+ ((clip.c.left + x) >> 4);
4708+ go->modet_map[mbnum] = region;
4709+ }
4710+ clip_ptr = clip.next;
4711+ }
4712+ return 0;
4713+}
4714+
4715+static int go7007_do_ioctl(struct inode *inode, struct file *file,
4716+ unsigned int cmd, void *arg)
4717+{
4718+ struct go7007_file *gofh = file->private_data;
4719+ struct go7007 *go = gofh->go;
4720+ unsigned long flags;
4721+ int retval = 0;
4722+
4723+ switch (cmd) {
4724+ case VIDIOC_QUERYCAP:
4725+ {
4726+ struct v4l2_capability *cap = arg;
4727+
4728+ memset(cap, 0, sizeof(*cap));
4729+ strcpy(cap->driver, "go7007");
4730+ strncpy(cap->card, go->name, sizeof(cap->card));
4731+ cap->version = KERNEL_VERSION(0, 9, 8);
4732+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
4733+ V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
4734+ if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
4735+ cap->capabilities |= V4L2_CAP_TUNER;
4736+ return 0;
4737+ }
4738+ case VIDIOC_ENUM_FMT:
4739+ {
4740+ struct v4l2_fmtdesc *fmt = arg;
4741+ unsigned int index;
4742+ char *desc;
4743+ u32 pixelformat;
4744+
4745+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
4746+ return -EINVAL;
4747+ switch (fmt->index) {
4748+ case 0:
4749+ pixelformat = V4L2_PIX_FMT_MJPEG;
4750+ desc = "Motion-JPEG";
4751+ break;
4752+ case 1:
4753+ pixelformat = V4L2_PIX_FMT_MPEG;
4754+ desc = "MPEG1/MPEG2/MPEG4";
4755+ break;
4756+ default:
4757+ return -EINVAL;
4758+ }
4759+ index = fmt->index;
4760+ memset(fmt, 0, sizeof(*fmt));
4761+ fmt->index = index;
4762+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4763+ fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
4764+ strncpy(fmt->description, desc, sizeof(fmt->description));
4765+ fmt->pixelformat = pixelformat;
4766+
4767+ return 0;
4768+ }
4769+ case VIDIOC_TRY_FMT:
4770+ {
4771+ struct v4l2_format *fmt = arg;
4772+
4773+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
4774+ return -EINVAL;
4775+ return set_capture_size(go, fmt, 1);
4776+ }
4777+ case VIDIOC_G_FMT:
4778+ {
4779+ struct v4l2_format *fmt = arg;
4780+
4781+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
4782+ return -EINVAL;
4783+ memset(fmt, 0, sizeof(*fmt));
4784+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4785+ fmt->fmt.pix.width = go->width;
4786+ fmt->fmt.pix.height = go->height;
4787+ fmt->fmt.pix.pixelformat = go->format == GO7007_FORMAT_MJPEG ?
4788+ V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
4789+ fmt->fmt.pix.field = V4L2_FIELD_NONE;
4790+ fmt->fmt.pix.bytesperline = 0;
4791+ fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
4792+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
4793+ return 0;
4794+ }
4795+ case VIDIOC_S_FMT:
4796+ {
4797+ struct v4l2_format *fmt = arg;
4798+
4799+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
4800+ return -EINVAL;
4801+ if (go->streaming)
4802+ return -EBUSY;
4803+ return set_capture_size(go, fmt, 0);
4804+ }
4805+ case VIDIOC_G_FBUF:
4806+ case VIDIOC_S_FBUF:
4807+ return -EINVAL;
4808+ case VIDIOC_REQBUFS:
4809+ {
4810+ struct v4l2_requestbuffers *req = arg;
4811+ unsigned int count, i;
4812+
4813+ if (go->streaming)
4814+ return -EBUSY;
4815+ if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4816+ req->memory != V4L2_MEMORY_MMAP)
4817+ return -EINVAL;
4818+
4819+ down(&gofh->lock);
4820+ retval = -EBUSY;
4821+ for (i = 0; i < gofh->buf_count; ++i)
4822+ if (gofh->bufs[i].mapped > 0)
4823+ goto unlock_and_return;
4824+ down(&go->hw_lock);
4825+ if (go->in_use > 0 && gofh->buf_count == 0) {
4826+ up(&go->hw_lock);
4827+ goto unlock_and_return;
4828+ }
4829+ if (gofh->buf_count > 0)
4830+ kfree(gofh->bufs);
4831+ retval = -ENOMEM;
4832+ count = req->count;
4833+ if (count > 0) {
4834+ if (count < 2)
4835+ count = 2;
4836+ if (count > 32)
4837+ count = 32;
4838+ gofh->bufs = kmalloc(count *
4839+ sizeof(struct go7007_buffer),
4840+ GFP_KERNEL);
4841+ if (gofh->bufs == NULL) {
4842+ up(&go->hw_lock);
4843+ goto unlock_and_return;
4844+ }
4845+ memset(gofh->bufs, 0,
4846+ count * sizeof(struct go7007_buffer));
4847+ for (i = 0; i < count; ++i) {
4848+ gofh->bufs[i].go = go;
4849+ gofh->bufs[i].index = i;
4850+ gofh->bufs[i].state = BUF_STATE_IDLE;
4851+ gofh->bufs[i].mapped = 0;
4852+ }
4853+ go->in_use = 1;
4854+ } else {
4855+ go->in_use = 0;
4856+ }
4857+ gofh->buf_count = count;
4858+ up(&go->hw_lock);
4859+ up(&gofh->lock);
4860+ memset(req, 0, sizeof(*req));
4861+ req->count = count;
4862+ req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4863+ req->memory = V4L2_MEMORY_MMAP;
4864+ return 0;
4865+ }
4866+ case VIDIOC_QUERYBUF:
4867+ {
4868+ struct v4l2_buffer *buf = arg;
4869+ unsigned int index;
4870+
4871+ retval = -EINVAL;
4872+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
4873+ return -EINVAL;
4874+ index = buf->index;
4875+ down(&gofh->lock);
4876+ if (index >= gofh->buf_count)
4877+ goto unlock_and_return;
4878+ memset(buf, 0, sizeof(*buf));
4879+ buf->index = index;
4880+ buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4881+ switch (gofh->bufs[index].state) {
4882+ case BUF_STATE_QUEUED:
4883+ buf->flags = V4L2_BUF_FLAG_QUEUED;
4884+ break;
4885+ case BUF_STATE_DONE:
4886+ buf->flags = V4L2_BUF_FLAG_DONE;
4887+ break;
4888+ default:
4889+ buf->flags = 0;
4890+ }
4891+ if (gofh->bufs[index].mapped)
4892+ buf->flags |= V4L2_BUF_FLAG_MAPPED;
4893+ buf->memory = V4L2_MEMORY_MMAP;
4894+ buf->m.offset = index * GO7007_BUF_SIZE;
4895+ buf->length = GO7007_BUF_SIZE;
4896+ up(&gofh->lock);
4897+
4898+ return 0;
4899+ }
4900+ case VIDIOC_QBUF:
4901+ {
4902+ struct v4l2_buffer *buf = arg;
4903+ struct go7007_buffer *gobuf;
4904+ int ret;
4905+
4906+ retval = -EINVAL;
4907+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
4908+ buf->memory != V4L2_MEMORY_MMAP)
4909+ return -EINVAL;
4910+ down(&gofh->lock);
4911+ if (buf->index < 0 || buf->index >= gofh->buf_count)
4912+ goto unlock_and_return;
4913+ gobuf = &gofh->bufs[buf->index];
4914+ if (gobuf->mapped == 0)
4915+ goto unlock_and_return;
4916+ retval = -EBUSY;
4917+ if (gobuf->state != BUF_STATE_IDLE)
4918+ goto unlock_and_return;
4919+ /* offset will be 0 until we really support USERPTR streaming */
4920+ gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
4921+ gobuf->bytesused = 0;
4922+ gobuf->frame_offset = 0;
4923+ gobuf->modet_active = 0;
4924+ if (gobuf->offset > 0)
4925+ gobuf->page_count = GO7007_BUF_PAGES + 1;
4926+ else
4927+ gobuf->page_count = GO7007_BUF_PAGES;
4928+ retval = -ENOMEM;
4929+ down_read(&current->mm->mmap_sem);
4930+ ret = get_user_pages(current, current->mm,
4931+ gobuf->user_addr & PAGE_MASK, gobuf->page_count,
4932+ 1, 1, gobuf->pages, NULL);
4933+ up_read(&current->mm->mmap_sem);
4934+ if (ret != gobuf->page_count) {
4935+ int i;
4936+ for (i = 0; i < ret; ++i)
4937+ page_cache_release(gobuf->pages[i]);
4938+ gobuf->page_count = 0;
4939+ goto unlock_and_return;
4940+ }
4941+ gobuf->state = BUF_STATE_QUEUED;
4942+ spin_lock_irqsave(&go->spinlock, flags);
4943+ list_add_tail(&gobuf->stream, &go->stream);
4944+ spin_unlock_irqrestore(&go->spinlock, flags);
4945+ up(&gofh->lock);
4946+ return 0;
4947+ }
4948+ case VIDIOC_DQBUF:
4949+ {
4950+ struct v4l2_buffer *buf = arg;
4951+ struct go7007_buffer *gobuf;
4952+ u32 frame_type_flag;
4953+ DEFINE_WAIT(wait);
4954+
4955+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
4956+ return -EINVAL;
4957+ if (buf->memory != V4L2_MEMORY_MMAP)
4958+ return -EINVAL;
4959+ down(&gofh->lock);
4960+ retval = -EINVAL;
4961+ if (list_empty(&go->stream))
4962+ goto unlock_and_return;
4963+ gobuf = list_entry(go->stream.next,
4964+ struct go7007_buffer, stream);
4965+ retval = -EAGAIN;
4966+ if (gobuf->state != BUF_STATE_DONE &&
4967+ !(file->f_flags & O_NONBLOCK)) {
4968+ for (;;) {
4969+ prepare_to_wait(&go->frame_waitq, &wait,
4970+ TASK_INTERRUPTIBLE);
4971+ if (gobuf->state == BUF_STATE_DONE)
4972+ break;
4973+ if (signal_pending(current)) {
4974+ retval = -ERESTARTSYS;
4975+ break;
4976+ }
4977+ schedule();
4978+ }
4979+ finish_wait(&go->frame_waitq, &wait);
4980+ }
4981+ if (gobuf->state != BUF_STATE_DONE)
4982+ goto unlock_and_return;
4983+ spin_lock_irqsave(&go->spinlock, flags);
4984+ deactivate_buffer(gobuf);
4985+ spin_unlock_irqrestore(&go->spinlock, flags);
4986+ frame_type_flag = get_frame_type_flag(gobuf, go->format);
4987+ gobuf->state = BUF_STATE_IDLE;
4988+ memset(buf, 0, sizeof(*buf));
4989+ buf->index = gobuf->index;
4990+ buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4991+ buf->bytesused = gobuf->bytesused;
4992+ buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
4993+ buf->field = V4L2_FIELD_NONE;
4994+ buf->timestamp = gobuf->timestamp;
4995+ buf->sequence = gobuf->seq;
4996+ buf->memory = V4L2_MEMORY_MMAP;
4997+ buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
4998+ buf->length = GO7007_BUF_SIZE;
4999+ buf->reserved = gobuf->modet_active;
5000+ up(&gofh->lock);
5001+ return 0;
5002+ }
5003+ case VIDIOC_STREAMON:
5004+ {
5005+ unsigned int *type = arg;
5006+
5007+ if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
5008+ return -EINVAL;
5009+ down(&gofh->lock);
5010+ down(&go->hw_lock);
5011+ if (!go->streaming) {
5012+ go->streaming = 1;
5013+ go->next_seq = 0;
5014+ go->active_buf = NULL;
5015+ if (go7007_start_encoder(go) < 0)
5016+ retval = -EIO;
5017+ else
5018+ retval = 0;
5019+ }
5020+ up(&go->hw_lock);
5021+ up(&gofh->lock);
5022+ return retval;
5023+ }
5024+ case VIDIOC_STREAMOFF:
5025+ {
5026+ unsigned int *type = arg;
5027+
5028+ if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
5029+ return -EINVAL;
5030+ down(&gofh->lock);
5031+ go7007_streamoff(go);
5032+ up(&gofh->lock);
5033+ return 0;
5034+ }
5035+ case VIDIOC_QUERYCTRL:
5036+ {
5037+ struct v4l2_queryctrl *ctrl = arg;
5038+ u32 id;
5039+
5040+ if (!go->i2c_adapter_online)
5041+ return -EIO;
5042+ id = ctrl->id;
5043+ memset(ctrl, 0, sizeof(*ctrl));
5044+ ctrl->id = id;
5045+ i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, arg);
5046+ return ctrl->name[0] == 0 ? -EINVAL : 0;
5047+ }
5048+ case VIDIOC_G_CTRL:
5049+ {
5050+ struct v4l2_control *ctrl = arg;
5051+ struct v4l2_queryctrl query;
5052+
5053+ if (!go->i2c_adapter_online)
5054+ return -EIO;
5055+ memset(&query, 0, sizeof(query));
5056+ query.id = ctrl->id;
5057+ i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
5058+ if (query.name[0] == 0)
5059+ return -EINVAL;
5060+ i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, arg);
5061+ return 0;
5062+ }
5063+ case VIDIOC_S_CTRL:
5064+ {
5065+ struct v4l2_control *ctrl = arg;
5066+ struct v4l2_queryctrl query;
5067+
5068+ if (!go->i2c_adapter_online)
5069+ return -EIO;
5070+ memset(&query, 0, sizeof(query));
5071+ query.id = ctrl->id;
5072+ i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
5073+ if (query.name[0] == 0)
5074+ return -EINVAL;
5075+ i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, arg);
5076+ return 0;
5077+ }
5078+ case VIDIOC_G_PARM:
5079+ {
5080+ struct v4l2_streamparm *parm = arg;
5081+ struct v4l2_fract timeperframe = {
5082+ .numerator = 1001 * go->fps_scale,
5083+ .denominator = go->sensor_framerate,
5084+ };
5085+
5086+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
5087+ return -EINVAL;
5088+ memset(parm, 0, sizeof(*parm));
5089+ parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
5090+ parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
5091+ parm->parm.capture.timeperframe = timeperframe;
5092+ return 0;
5093+ }
5094+ case VIDIOC_S_PARM:
5095+ {
5096+ struct v4l2_streamparm *parm = arg;
5097+ unsigned int n, d;
5098+
5099+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
5100+ return -EINVAL;
5101+ if (parm->parm.capture.capturemode != 0)
5102+ return -EINVAL;
5103+ n = go->sensor_framerate *
5104+ parm->parm.capture.timeperframe.numerator;
5105+ d = 1001 * parm->parm.capture.timeperframe.denominator;
5106+ if (n != 0 && d != 0 && n > d)
5107+ go->fps_scale = (n + d/2) / d;
5108+ else
5109+ go->fps_scale = 1;
5110+ return 0;
5111+ }
5112+ case VIDIOC_ENUMSTD:
5113+ {
5114+ struct v4l2_standard *std = arg;
5115+
5116+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
5117+ go->input == go->board_info->num_inputs - 1) {
5118+ if (!go->i2c_adapter_online)
5119+ return -EIO;
5120+ i2c_clients_command(&go->i2c_adapter,
5121+ VIDIOC_ENUMSTD, arg);
5122+ if (!std->id) /* hack to indicate EINVAL from tuner */
5123+ return -EINVAL;
5124+ } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
5125+ switch (std->index) {
5126+ case 0:
5127+ v4l2_video_std_construct(std,
5128+ V4L2_STD_NTSC, "NTSC");
5129+ break;
5130+ case 1:
5131+ v4l2_video_std_construct(std,
5132+ V4L2_STD_PAL | V4L2_STD_SECAM,
5133+ "PAL/SECAM");
5134+ break;
5135+ default:
5136+ return -EINVAL;
5137+ }
5138+ } else {
5139+ if (std->index != 0)
5140+ return -EINVAL;
5141+ memset(std, 0, sizeof(*std));
5142+ snprintf(std->name, sizeof(std->name), "%dx%d, %dfps",
5143+ go->board_info->sensor_width,
5144+ go->board_info->sensor_height,
5145+ go->board_info->sensor_framerate / 1000);
5146+ std->frameperiod.numerator = 1001;
5147+ std->frameperiod.denominator =
5148+ go->board_info->sensor_framerate;
5149+ }
5150+ return 0;
5151+ }
5152+ case VIDIOC_G_STD:
5153+ {
5154+ v4l2_std_id *std = arg;
5155+
5156+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
5157+ go->input == go->board_info->num_inputs - 1) {
5158+ if (!go->i2c_adapter_online)
5159+ return -EIO;
5160+ i2c_clients_command(&go->i2c_adapter,
5161+ VIDIOC_G_STD, arg);
5162+ } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
5163+ if (go->standard == GO7007_STD_NTSC)
5164+ *std = V4L2_STD_NTSC;
5165+ else
5166+ *std = V4L2_STD_PAL | V4L2_STD_SECAM;
5167+ } else
5168+ *std = 0;
5169+ return 0;
5170+ }
5171+ case VIDIOC_S_STD:
5172+ {
5173+ v4l2_std_id *std = arg;
5174+ int norm;
5175+
5176+ if (go->streaming)
5177+ return -EBUSY;
5178+ if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
5179+ *std != 0)
5180+ return -EINVAL;
5181+ if (*std == 0)
5182+ return -EINVAL;
5183+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
5184+ go->input == go->board_info->num_inputs - 1) {
5185+ if (!go->i2c_adapter_online)
5186+ return -EIO;
5187+ i2c_clients_command(&go->i2c_adapter,
5188+ VIDIOC_S_STD, arg);
5189+ if (!*std) /* hack to indicate EINVAL from tuner */
5190+ return -EINVAL;
5191+ }
5192+ if (*std & V4L2_STD_NTSC) {
5193+ go->standard = GO7007_STD_NTSC;
5194+ go->sensor_framerate = 30000;
5195+ norm = VIDEO_MODE_NTSC;
5196+ } else if (*std & V4L2_STD_PAL) {
5197+ go->standard = GO7007_STD_PAL;
5198+ go->sensor_framerate = 25025;
5199+ norm = VIDEO_MODE_PAL;
5200+ } else if (*std & V4L2_STD_SECAM) {
5201+ go->standard = GO7007_STD_PAL;
5202+ go->sensor_framerate = 25025;
5203+ norm = VIDEO_MODE_SECAM;
5204+ } else
5205+ return -EINVAL;
5206+ if (go->i2c_adapter_online)
5207+ i2c_clients_command(&go->i2c_adapter,
5208+ DECODER_SET_NORM, &norm);
5209+ set_capture_size(go, NULL, 0);
5210+ return 0;
5211+ }
5212+ case VIDIOC_QUERYSTD:
5213+ {
5214+ v4l2_std_id *std = arg;
5215+
5216+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
5217+ go->input == go->board_info->num_inputs - 1) {
5218+ if (!go->i2c_adapter_online)
5219+ return -EIO;
5220+ i2c_clients_command(&go->i2c_adapter,
5221+ VIDIOC_QUERYSTD, arg);
5222+ } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
5223+ *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
5224+ else
5225+ *std = 0;
5226+ return 0;
5227+ }
5228+ case VIDIOC_ENUMINPUT:
5229+ {
5230+ struct v4l2_input *inp = arg;
5231+ int index;
5232+
5233+ if (inp->index >= go->board_info->num_inputs)
5234+ return -EINVAL;
5235+ index = inp->index;
5236+ memset(inp, 0, sizeof(*inp));
5237+ inp->index = index;
5238+ strncpy(inp->name, go->board_info->inputs[index].name,
5239+ sizeof(inp->name));
5240+ /* If this board has a tuner, it will be the last input */
5241+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
5242+ index == go->board_info->num_inputs - 1)
5243+ inp->type = V4L2_INPUT_TYPE_TUNER;
5244+ else
5245+ inp->type = V4L2_INPUT_TYPE_CAMERA;
5246+ inp->audioset = 0;
5247+ inp->tuner = 0;
5248+ if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
5249+ inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
5250+ V4L2_STD_SECAM;
5251+ else
5252+ inp->std = 0;
5253+ return 0;
5254+ }
5255+ case VIDIOC_G_INPUT:
5256+ {
5257+ int *input = arg;
5258+
5259+ *input = go->input;
5260+ return 0;
5261+ }
5262+ case VIDIOC_S_INPUT:
5263+ {
5264+ int *input = arg;
5265+
5266+ if (*input >= go->board_info->num_inputs)
5267+ return -EINVAL;
5268+ if (go->streaming)
5269+ return -EBUSY;
5270+ go->input = *input;
5271+ if (go->i2c_adapter_online) {
5272+ i2c_clients_command(&go->i2c_adapter, DECODER_SET_INPUT,
5273+ &go->board_info->inputs[*input].video_input);
5274+ i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO,
5275+ &go->board_info->inputs[*input].audio_input);
5276+ }
5277+ return 0;
5278+ }
5279+ case VIDIOC_G_TUNER:
5280+ {
5281+ struct v4l2_tuner *t = arg;
5282+
5283+ if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
5284+ return -EINVAL;
5285+ if (t->index != 0)
5286+ return -EINVAL;
5287+ if (!go->i2c_adapter_online)
5288+ return -EIO;
5289+ i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, arg);
5290+ t->index = 0;
5291+ return 0;
5292+ }
5293+ case VIDIOC_S_TUNER:
5294+ {
5295+ struct v4l2_tuner *t = arg;
5296+
5297+ if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
5298+ return -EINVAL;
5299+ if (t->index != 0)
5300+ return -EINVAL;
5301+ if (!go->i2c_adapter_online)
5302+ return -EIO;
5303+ switch (go->board_id) {
5304+ case GO7007_BOARDID_PX_TV402U_NA:
5305+ case GO7007_BOARDID_PX_TV402U_JP:
5306+ /* No selectable options currently */
5307+ if (t->audmode != V4L2_TUNER_MODE_STEREO)
5308+ return -EINVAL;
5309+ break;
5310+ }
5311+ i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, arg);
5312+ return 0;
5313+ }
5314+ case VIDIOC_G_FREQUENCY:
5315+ {
5316+ struct v4l2_frequency *f = arg;
5317+
5318+ if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
5319+ return -EINVAL;
5320+ if (!go->i2c_adapter_online)
5321+ return -EIO;
5322+ memset(f, 0, sizeof(*f));
5323+ f->type = V4L2_TUNER_ANALOG_TV;
5324+ i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, arg);
5325+ return 0;
5326+ }
5327+ case VIDIOC_S_FREQUENCY:
5328+ {
5329+ if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
5330+ return -EINVAL;
5331+ if (!go->i2c_adapter_online)
5332+ return -EIO;
5333+ i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, arg);
5334+ return 0;
5335+ }
5336+ case VIDIOC_CROPCAP:
5337+ {
5338+ struct v4l2_cropcap *cropcap = arg;
5339+
5340+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
5341+ return -EINVAL;
5342+ memset(cropcap, 0, sizeof(*cropcap));
5343+ cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
5344+ /* These specify the raw input of the sensor */
5345+ switch (go->standard) {
5346+ case GO7007_STD_NTSC:
5347+ cropcap->bounds.top = 0;
5348+ cropcap->bounds.left = 0;
5349+ cropcap->bounds.width = 720;
5350+ cropcap->bounds.height = 480;
5351+ cropcap->defrect.top = 0;
5352+ cropcap->defrect.left = 0;
5353+ cropcap->defrect.width = 720;
5354+ cropcap->defrect.height = 480;
5355+ break;
5356+ case GO7007_STD_PAL:
5357+ cropcap->bounds.top = 0;
5358+ cropcap->bounds.left = 0;
5359+ cropcap->bounds.width = 720;
5360+ cropcap->bounds.height = 576;
5361+ cropcap->defrect.top = 0;
5362+ cropcap->defrect.left = 0;
5363+ cropcap->defrect.width = 720;
5364+ cropcap->defrect.height = 576;
5365+ break;
5366+ case GO7007_STD_OTHER:
5367+ cropcap->bounds.top = 0;
5368+ cropcap->bounds.left = 0;
5369+ cropcap->bounds.width = go->board_info->sensor_width;
5370+ cropcap->bounds.height = go->board_info->sensor_height;
5371+ cropcap->defrect.top = 0;
5372+ cropcap->defrect.left = 0;
5373+ cropcap->defrect.width = go->board_info->sensor_width;
5374+ cropcap->defrect.height = go->board_info->sensor_height;
5375+ break;
5376+ }
5377+
5378+ return 0;
5379+ }
5380+ case VIDIOC_G_CROP:
5381+ {
5382+ struct v4l2_crop *crop = arg;
5383+
5384+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
5385+ return -EINVAL;
5386+ memset(crop, 0, sizeof(*crop));
5387+ crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
5388+ /* These specify the raw input of the sensor */
5389+ switch (go->standard) {
5390+ case GO7007_STD_NTSC:
5391+ crop->c.top = 0;
5392+ crop->c.left = 0;
5393+ crop->c.width = 720;
5394+ crop->c.height = 480;
5395+ break;
5396+ case GO7007_STD_PAL:
5397+ crop->c.top = 0;
5398+ crop->c.left = 0;
5399+ crop->c.width = 720;
5400+ crop->c.height = 576;
5401+ break;
5402+ case GO7007_STD_OTHER:
5403+ crop->c.top = 0;
5404+ crop->c.left = 0;
5405+ crop->c.width = go->board_info->sensor_width;
5406+ crop->c.height = go->board_info->sensor_height;
5407+ break;
5408+ }
5409+
5410+ return 0;
5411+ }
5412+ case VIDIOC_S_CROP:
5413+ {
5414+ struct v4l2_crop *crop = arg;
5415+
5416+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
5417+ return -EINVAL;
5418+ return 0;
5419+ }
5420+ case VIDIOC_G_JPEGCOMP:
5421+ {
5422+ struct v4l2_jpegcompression *params = arg;
5423+
5424+ memset(params, 0, sizeof(*params));
5425+ params->quality = 50; /* ?? */
5426+ params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
5427+ V4L2_JPEG_MARKER_DQT;
5428+
5429+ return 0;
5430+ }
5431+ case VIDIOC_S_JPEGCOMP:
5432+ {
5433+ struct v4l2_jpegcompression *params = arg;
5434+
5435+ if (params->quality != 50 ||
5436+ params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
5437+ V4L2_JPEG_MARKER_DQT))
5438+ return -EINVAL;
5439+ return 0;
5440+ }
5441+ /* Temporary ioctls for controlling compression characteristics */
5442+ case GO7007IOC_S_BITRATE:
5443+ {
5444+ int *bitrate = arg;
5445+
5446+ if (go->streaming)
5447+ return -EINVAL;
5448+ /* Upper bound is kind of arbitrary here */
5449+ if (*bitrate < 64000 || *bitrate > 10000000)
5450+ return -EINVAL;
5451+ go->bitrate = *bitrate;
5452+ return 0;
5453+ }
5454+ case GO7007IOC_G_BITRATE:
5455+ {
5456+ int *bitrate = arg;
5457+
5458+ *bitrate = go->bitrate;
5459+ return 0;
5460+ }
5461+ case GO7007IOC_S_COMP_PARAMS:
5462+ {
5463+ struct go7007_comp_params *comp = arg;
5464+
5465+ if (go->format == GO7007_FORMAT_MJPEG)
5466+ return -EINVAL;
5467+ if (comp->gop_size > 0)
5468+ go->gop_size = comp->gop_size;
5469+ else
5470+ go->gop_size = go->sensor_framerate / 1000;
5471+ if (go->gop_size != 15)
5472+ go->dvd_mode = 0;
5473+ /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
5474+ if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
5475+ switch (comp->aspect_ratio) {
5476+ case GO7007_ASPECT_RATIO_4_3_NTSC:
5477+ case GO7007_ASPECT_RATIO_4_3_PAL:
5478+ go->aspect_ratio = GO7007_RATIO_4_3;
5479+ break;
5480+ case GO7007_ASPECT_RATIO_16_9_NTSC:
5481+ case GO7007_ASPECT_RATIO_16_9_PAL:
5482+ go->aspect_ratio = GO7007_RATIO_16_9;
5483+ break;
5484+ default:
5485+ go->aspect_ratio = GO7007_RATIO_1_1;
5486+ break;
5487+ }
5488+ }
5489+ if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
5490+ go->dvd_mode = 0;
5491+ go->seq_header_enable = 0;
5492+ } else {
5493+ go->seq_header_enable = 1;
5494+ }
5495+ /* fall-through */
5496+ }
5497+ case GO7007IOC_G_COMP_PARAMS:
5498+ {
5499+ struct go7007_comp_params *comp = arg;
5500+
5501+ if (go->format == GO7007_FORMAT_MJPEG)
5502+ return -EINVAL;
5503+ memset(comp, 0, sizeof(*comp));
5504+ comp->gop_size = go->gop_size;
5505+ comp->max_b_frames = go->ipb ? 2 : 0;
5506+ switch (go->aspect_ratio) {
5507+ case GO7007_RATIO_4_3:
5508+ if (go->standard == GO7007_STD_NTSC)
5509+ comp->aspect_ratio =
5510+ GO7007_ASPECT_RATIO_4_3_NTSC;
5511+ else
5512+ comp->aspect_ratio =
5513+ GO7007_ASPECT_RATIO_4_3_PAL;
5514+ break;
5515+ case GO7007_RATIO_16_9:
5516+ if (go->standard == GO7007_STD_NTSC)
5517+ comp->aspect_ratio =
5518+ GO7007_ASPECT_RATIO_16_9_NTSC;
5519+ else
5520+ comp->aspect_ratio =
5521+ GO7007_ASPECT_RATIO_16_9_PAL;
5522+ break;
5523+ default:
5524+ comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
5525+ break;
5526+ }
5527+ if (go->closed_gop)
5528+ comp->flags |= GO7007_COMP_CLOSED_GOP;
5529+ if (!go->seq_header_enable)
5530+ comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
5531+ return 0;
5532+ }
5533+ case GO7007IOC_S_MPEG_PARAMS:
5534+ {
5535+ struct go7007_mpeg_params *mpeg = arg;
5536+
5537+ if (go->format != GO7007_FORMAT_MPEG1 &&
5538+ go->format != GO7007_FORMAT_MPEG2 &&
5539+ go->format != GO7007_FORMAT_MPEG4)
5540+ return -EINVAL;
5541+
5542+ if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
5543+ go->format = GO7007_FORMAT_MPEG2;
5544+ go->bitrate = 9800000;
5545+ go->gop_size = 15;
5546+ go->pali = 0x48;
5547+ go->closed_gop = 1;
5548+ go->repeat_seqhead = 0;
5549+ go->seq_header_enable = 1;
5550+ go->gop_header_enable = 1;
5551+ go->dvd_mode = 1;
5552+ } else {
5553+ switch (mpeg->mpeg_video_standard) {
5554+ case GO7007_MPEG_VIDEO_MPEG1:
5555+ go->format = GO7007_FORMAT_MPEG1;
5556+ go->pali = 0;
5557+ break;
5558+ case GO7007_MPEG_VIDEO_MPEG2:
5559+ go->format = GO7007_FORMAT_MPEG2;
5560+ if (mpeg->pali >> 24 == 2)
5561+ go->pali = mpeg->pali & 0xff;
5562+ else
5563+ go->pali = 0x48;
5564+ break;
5565+ case GO7007_MPEG_VIDEO_MPEG4:
5566+ go->format = GO7007_FORMAT_MPEG4;
5567+ if (mpeg->pali >> 24 == 4)
5568+ go->pali = mpeg->pali & 0xff;
5569+ else
5570+ go->pali = 0xf5;
5571+ break;
5572+ default:
5573+ return -EINVAL;
5574+ }
5575+ go->gop_header_enable =
5576+ mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
5577+ ? 0 : 1;
5578+ if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
5579+ go->repeat_seqhead = 1;
5580+ else
5581+ go->repeat_seqhead = 0;
5582+ go->dvd_mode = 0;
5583+ }
5584+ /* fall-through */
5585+ }
5586+ case GO7007IOC_G_MPEG_PARAMS:
5587+ {
5588+ struct go7007_mpeg_params *mpeg = arg;
5589+
5590+ memset(mpeg, 0, sizeof(*mpeg));
5591+ switch (go->format) {
5592+ case GO7007_FORMAT_MPEG1:
5593+ mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
5594+ mpeg->pali = 0;
5595+ break;
5596+ case GO7007_FORMAT_MPEG2:
5597+ mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
5598+ mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
5599+ break;
5600+ case GO7007_FORMAT_MPEG4:
5601+ mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
5602+ mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
5603+ break;
5604+ default:
5605+ return -EINVAL;
5606+ }
5607+ if (!go->gop_header_enable)
5608+ mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
5609+ if (go->repeat_seqhead)
5610+ mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
5611+ if (go->dvd_mode)
5612+ mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
5613+ return 0;
5614+ }
5615+ case GO7007IOC_S_MD_PARAMS:
5616+ {
5617+ struct go7007_md_params *mdp = arg;
5618+
5619+ if (mdp->region > 3)
5620+ return -EINVAL;
5621+ if (mdp->trigger > 0) {
5622+ go->modet[mdp->region].pixel_threshold =
5623+ mdp->pixel_threshold >> 1;
5624+ go->modet[mdp->region].motion_threshold =
5625+ mdp->motion_threshold >> 1;
5626+ go->modet[mdp->region].mb_threshold =
5627+ mdp->trigger >> 1;
5628+ go->modet[mdp->region].enable = 1;
5629+ } else
5630+ go->modet[mdp->region].enable = 0;
5631+ /* fall-through */
5632+ }
5633+ case GO7007IOC_G_MD_PARAMS:
5634+ {
5635+ struct go7007_md_params *mdp = arg;
5636+ int region = mdp->region;
5637+
5638+ if (mdp->region > 3)
5639+ return -EINVAL;
5640+ memset(mdp, 0, sizeof(struct go7007_md_params));
5641+ mdp->region = region;
5642+ if (!go->modet[region].enable)
5643+ return 0;
5644+ mdp->pixel_threshold =
5645+ (go->modet[region].pixel_threshold << 1) + 1;
5646+ mdp->motion_threshold =
5647+ (go->modet[region].motion_threshold << 1) + 1;
5648+ mdp->trigger =
5649+ (go->modet[region].mb_threshold << 1) + 1;
5650+ return 0;
5651+ }
5652+ case GO7007IOC_S_MD_REGION:
5653+ {
5654+ struct go7007_md_region *region = arg;
5655+
5656+ if (region->region < 1 || region->region > 3)
5657+ return -EINVAL;
5658+ return clip_to_modet_map(go, region->region, region->clips);
5659+ }
5660+ default:
5661+ printk(KERN_DEBUG "go7007: unsupported ioctl %d\n", cmd);
5662+ return -ENOIOCTLCMD;
5663+ }
5664+ return 0;
5665+
5666+unlock_and_return:
5667+ up(&gofh->lock);
5668+ return retval;
5669+}
5670+
5671+static int go7007_ioctl(struct inode *inode, struct file *file,
5672+ unsigned int cmd, unsigned long arg)
5673+{
5674+ struct go7007_file *gofh = file->private_data;
5675+
5676+ if (gofh->go->status != STATUS_ONLINE)
5677+ return -EIO;
5678+
5679+ return video_usercopy(inode, file, cmd, arg, go7007_do_ioctl);
5680+}
5681+
5682+static ssize_t go7007_read(struct file *file, char __user *data,
5683+ size_t count, loff_t *ppos)
5684+{
5685+ return -EINVAL;
5686+}
5687+
5688+static void go7007_vm_open(struct vm_area_struct *vma)
5689+{
5690+ struct go7007_buffer *gobuf = vma->vm_private_data;
5691+
5692+ ++gobuf->mapped;
5693+}
5694+
5695+static void go7007_vm_close(struct vm_area_struct *vma)
5696+{
5697+ struct go7007_buffer *gobuf = vma->vm_private_data;
5698+ unsigned long flags;
5699+
5700+ if (--gobuf->mapped == 0) {
5701+ spin_lock_irqsave(&gobuf->go->spinlock, flags);
5702+ deactivate_buffer(gobuf);
5703+ spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
5704+ }
5705+}
5706+
5707+/* Copied from videobuf-dma-sg.c */
5708+static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
5709+{
5710+ struct page *page;
5711+
5712+ page = alloc_page(GFP_USER | __GFP_DMA32);
5713+ if (!page)
5714+ return VM_FAULT_OOM;
5715+ clear_user_page(page_address(page), (unsigned long)vmf->virtual_address,
5716+ page);
5717+ vmf->page = page;
5718+ return 0;
5719+}
5720+
5721+static struct vm_operations_struct go7007_vm_ops = {
5722+ .open = go7007_vm_open,
5723+ .close = go7007_vm_close,
5724+ .fault = go7007_vm_fault,
5725+};
5726+
5727+static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
5728+{
5729+ struct go7007_file *gofh = file->private_data;
5730+ unsigned int index;
5731+
5732+ if (gofh->go->status != STATUS_ONLINE)
5733+ return -EIO;
5734+ if (!(vma->vm_flags & VM_SHARED))
5735+ return -EINVAL; /* only support VM_SHARED mapping */
5736+ if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
5737+ return -EINVAL; /* must map exactly one full buffer */
5738+ down(&gofh->lock);
5739+ index = vma->vm_pgoff / GO7007_BUF_PAGES;
5740+ if (index >= gofh->buf_count) {
5741+ up(&gofh->lock);
5742+ return -EINVAL; /* trying to map beyond requested buffers */
5743+ }
5744+ if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
5745+ up(&gofh->lock);
5746+ return -EINVAL; /* offset is not aligned on buffer boundary */
5747+ }
5748+ if (gofh->bufs[index].mapped > 0) {
5749+ up(&gofh->lock);
5750+ return -EBUSY;
5751+ }
5752+ gofh->bufs[index].mapped = 1;
5753+ gofh->bufs[index].user_addr = vma->vm_start;
5754+ vma->vm_ops = &go7007_vm_ops;
5755+ vma->vm_flags |= VM_DONTEXPAND;
5756+ vma->vm_flags &= ~VM_IO;
5757+ vma->vm_private_data = &gofh->bufs[index];
5758+ up(&gofh->lock);
5759+ return 0;
5760+}
5761+
5762+static unsigned int go7007_poll(struct file *file, poll_table *wait)
5763+{
5764+ struct go7007_file *gofh = file->private_data;
5765+ struct go7007_buffer *gobuf;
5766+
5767+ if (list_empty(&gofh->go->stream))
5768+ return POLLERR;
5769+ gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
5770+ poll_wait(file, &gofh->go->frame_waitq, wait);
5771+ if (gobuf->state == BUF_STATE_DONE)
5772+ return POLLIN | POLLRDNORM;
5773+ return 0;
5774+}
5775+
5776+static void go7007_vfl_release(struct video_device *vfd)
5777+{
5778+ struct go7007 *go = video_get_drvdata(vfd);
5779+
5780+ video_device_release(vfd);
5781+ if (--go->ref_count == 0)
5782+ kfree(go);
5783+}
5784+
5785+static struct file_operations go7007_fops = {
5786+ .owner = THIS_MODULE,
5787+ .open = go7007_open,
5788+ .release = go7007_release,
5789+ .ioctl = go7007_ioctl,
5790+ .llseek = no_llseek,
5791+ .read = go7007_read,
5792+ .mmap = go7007_mmap,
5793+ .poll = go7007_poll,
5794+};
5795+
5796+static struct video_device go7007_template = {
5797+ .name = "go7007",
5798+ .fops = &go7007_fops,
5799+ .minor = -1,
5800+ .release = go7007_vfl_release,
5801+};
5802+
5803+int go7007_v4l2_init(struct go7007 *go)
5804+{
5805+ int rv;
5806+
5807+ go->video_dev = video_device_alloc();
5808+ if (go->video_dev == NULL)
5809+ return -ENOMEM;
5810+ memcpy(go->video_dev, &go7007_template, sizeof(go7007_template));
5811+ go->video_dev->parent = go->dev;
5812+ rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
5813+ if (rv < 0) {
5814+ video_device_release(go->video_dev);
5815+ go->video_dev = NULL;
5816+ return rv;
5817+ }
5818+ video_set_drvdata(go->video_dev, go);
5819+ ++go->ref_count;
5820+
5821+ return 0;
5822+}
5823+
5824+void go7007_v4l2_remove(struct go7007 *go)
5825+{
5826+ unsigned long flags;
5827+
5828+ down(&go->hw_lock);
5829+ if (go->streaming) {
5830+ go->streaming = 0;
5831+ go7007_stream_stop(go);
5832+ spin_lock_irqsave(&go->spinlock, flags);
5833+ abort_queued(go);
5834+ spin_unlock_irqrestore(&go->spinlock, flags);
5835+ }
5836+ up(&go->hw_lock);
5837+ if (go->video_dev)
5838+ video_unregister_device(go->video_dev);
5839+}
5840diff --git a/drivers/staging/go7007/go7007.h b/drivers/staging/go7007/go7007.h
5841new file mode 100644
5842index 0000000..7399c91
5843--- /dev/null
5844+++ b/drivers/staging/go7007/go7007.h
5845@@ -0,0 +1,114 @@
5846+/*
5847+ * Copyright (C) 2005-2006 Micronas USA Inc.
5848+ *
5849+ * Permission is hereby granted, free of charge, to any person obtaining a
5850+ * copy of this software and the associated README documentation file (the
5851+ * "Software"), to deal in the Software without restriction, including
5852+ * without limitation the rights to use, copy, modify, merge, publish,
5853+ * distribute, sublicense, and/or sell copies of the Software, and to
5854+ * permit persons to whom the Software is furnished to do so.
5855+ *
5856+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
5857+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
5858+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
5859+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
5860+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
5861+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
5862+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5863+ */
5864+
5865+/* DEPRECATED -- use V4L2_PIX_FMT_MPEG and then call GO7007IOC_S_MPEG_PARAMS
5866+ * to select between MPEG1, MPEG2, and MPEG4 */
5867+#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG4 */
5868+
5869+/* These will be replaced with a better interface
5870+ * soon, so don't get too attached to them */
5871+#define GO7007IOC_S_BITRATE _IOW('V', BASE_VIDIOC_PRIVATE + 0, int)
5872+#define GO7007IOC_G_BITRATE _IOR('V', BASE_VIDIOC_PRIVATE + 1, int)
5873+
5874+enum go7007_aspect_ratio {
5875+ GO7007_ASPECT_RATIO_1_1 = 0,
5876+ GO7007_ASPECT_RATIO_4_3_NTSC = 1,
5877+ GO7007_ASPECT_RATIO_4_3_PAL = 2,
5878+ GO7007_ASPECT_RATIO_16_9_NTSC = 3,
5879+ GO7007_ASPECT_RATIO_16_9_PAL = 4,
5880+};
5881+
5882+/* Used to set generic compression parameters */
5883+struct go7007_comp_params {
5884+ __u32 gop_size;
5885+ __u32 max_b_frames;
5886+ enum go7007_aspect_ratio aspect_ratio;
5887+ __u32 flags;
5888+ __u32 reserved[8];
5889+};
5890+
5891+#define GO7007_COMP_CLOSED_GOP 0x00000001
5892+#define GO7007_COMP_OMIT_SEQ_HEADER 0x00000002
5893+
5894+enum go7007_mpeg_video_standard {
5895+ GO7007_MPEG_VIDEO_MPEG1 = 0,
5896+ GO7007_MPEG_VIDEO_MPEG2 = 1,
5897+ GO7007_MPEG_VIDEO_MPEG4 = 2,
5898+};
5899+
5900+/* Used to set parameters for V4L2_PIX_FMT_MPEG format */
5901+struct go7007_mpeg_params {
5902+ enum go7007_mpeg_video_standard mpeg_video_standard;
5903+ __u32 flags;
5904+ __u32 pali;
5905+ __u32 reserved[8];
5906+};
5907+
5908+#define GO7007_MPEG_FORCE_DVD_MODE 0x00000001
5909+#define GO7007_MPEG_OMIT_GOP_HEADER 0x00000002
5910+#define GO7007_MPEG_REPEAT_SEQHEADER 0x00000004
5911+
5912+#define GO7007_MPEG_PROFILE(format, pali) (((format)<<24)|(pali))
5913+
5914+#define GO7007_MPEG2_PROFILE_MAIN_MAIN GO7007_MPEG_PROFILE(2, 0x48)
5915+
5916+#define GO7007_MPEG4_PROFILE_S_L0 GO7007_MPEG_PROFILE(4, 0x08)
5917+#define GO7007_MPEG4_PROFILE_S_L1 GO7007_MPEG_PROFILE(4, 0x01)
5918+#define GO7007_MPEG4_PROFILE_S_L2 GO7007_MPEG_PROFILE(4, 0x02)
5919+#define GO7007_MPEG4_PROFILE_S_L3 GO7007_MPEG_PROFILE(4, 0x03)
5920+#define GO7007_MPEG4_PROFILE_ARTS_L1 GO7007_MPEG_PROFILE(4, 0x91)
5921+#define GO7007_MPEG4_PROFILE_ARTS_L2 GO7007_MPEG_PROFILE(4, 0x92)
5922+#define GO7007_MPEG4_PROFILE_ARTS_L3 GO7007_MPEG_PROFILE(4, 0x93)
5923+#define GO7007_MPEG4_PROFILE_ARTS_L4 GO7007_MPEG_PROFILE(4, 0x94)
5924+#define GO7007_MPEG4_PROFILE_AS_L0 GO7007_MPEG_PROFILE(4, 0xf0)
5925+#define GO7007_MPEG4_PROFILE_AS_L1 GO7007_MPEG_PROFILE(4, 0xf1)
5926+#define GO7007_MPEG4_PROFILE_AS_L2 GO7007_MPEG_PROFILE(4, 0xf2)
5927+#define GO7007_MPEG4_PROFILE_AS_L3 GO7007_MPEG_PROFILE(4, 0xf3)
5928+#define GO7007_MPEG4_PROFILE_AS_L4 GO7007_MPEG_PROFILE(4, 0xf4)
5929+#define GO7007_MPEG4_PROFILE_AS_L5 GO7007_MPEG_PROFILE(4, 0xf5)
5930+
5931+struct go7007_md_params {
5932+ __u16 region;
5933+ __u16 trigger;
5934+ __u16 pixel_threshold;
5935+ __u16 motion_threshold;
5936+ __u32 reserved[8];
5937+};
5938+
5939+struct go7007_md_region {
5940+ __u16 region;
5941+ __u16 flags;
5942+ struct v4l2_clip *clips;
5943+ __u32 reserved[8];
5944+};
5945+
5946+#define GO7007IOC_S_MPEG_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 2, \
5947+ struct go7007_mpeg_params)
5948+#define GO7007IOC_G_MPEG_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 3, \
5949+ struct go7007_mpeg_params)
5950+#define GO7007IOC_S_COMP_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 4, \
5951+ struct go7007_comp_params)
5952+#define GO7007IOC_G_COMP_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 5, \
5953+ struct go7007_comp_params)
5954+#define GO7007IOC_S_MD_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 6, \
5955+ struct go7007_md_params)
5956+#define GO7007IOC_G_MD_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 7, \
5957+ struct go7007_md_params)
5958+#define GO7007IOC_S_MD_REGION _IOW('V', BASE_VIDIOC_PRIVATE + 8, \
5959+ struct go7007_md_region)
5960diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/go7007/saa7134-go7007.c
5961new file mode 100644
5962index 0000000..c4a6d8e
5963--- /dev/null
5964+++ b/drivers/staging/go7007/saa7134-go7007.c
5965@@ -0,0 +1,484 @@
5966+/*
5967+ * Copyright (C) 2005-2006 Micronas USA Inc.
5968+ *
5969+ * This program is free software; you can redistribute it and/or modify
5970+ * it under the terms of the GNU General Public License (Version 2) as
5971+ * published by the Free Software Foundation.
5972+ *
5973+ * This program is distributed in the hope that it will be useful,
5974+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5975+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5976+ * GNU General Public License for more details.
5977+ *
5978+ * You should have received a copy of the GNU General Public License
5979+ * along with this program; if not, write to the Free Software Foundation,
5980+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
5981+ */
5982+
5983+#include <linux/module.h>
5984+#include <linux/kernel.h>
5985+#include <linux/init.h>
5986+#include <linux/spinlock.h>
5987+#include <linux/wait.h>
5988+#include <linux/list.h>
5989+#include <linux/slab.h>
5990+#include <linux/time.h>
5991+#include <linux/mm.h>
5992+#include <linux/usb.h>
5993+#include <linux/i2c.h>
5994+#include <asm/byteorder.h>
5995+#include <media/audiochip.h>
5996+
5997+#include "saa7134-reg.h"
5998+#include "saa7134.h"
5999+#include "go7007-priv.h"
6000+
6001+#define GO7007_HPI_DEBUG
6002+
6003+enum hpi_address {
6004+ HPI_ADDR_VIDEO_BUFFER = 0xe4,
6005+ HPI_ADDR_INIT_BUFFER = 0xea,
6006+ HPI_ADDR_INTR_RET_VALUE = 0xee,
6007+ HPI_ADDR_INTR_RET_DATA = 0xec,
6008+ HPI_ADDR_INTR_STATUS = 0xf4,
6009+ HPI_ADDR_INTR_WR_PARAM = 0xf6,
6010+ HPI_ADDR_INTR_WR_INDEX = 0xf8,
6011+};
6012+
6013+enum gpio_command {
6014+ GPIO_COMMAND_RESET = 0x00, /* 000b */
6015+ GPIO_COMMAND_REQ1 = 0x04, /* 001b */
6016+ GPIO_COMMAND_WRITE = 0x20, /* 010b */
6017+ GPIO_COMMAND_REQ2 = 0x24, /* 011b */
6018+ GPIO_COMMAND_READ = 0x80, /* 100b */
6019+ GPIO_COMMAND_VIDEO = 0x84, /* 101b */
6020+ GPIO_COMMAND_IDLE = 0xA0, /* 110b */
6021+ GPIO_COMMAND_ADDR = 0xA4, /* 111b */
6022+};
6023+
6024+struct saa7134_go7007 {
6025+ struct saa7134_dev *dev;
6026+ u8 *top;
6027+ u8 *bottom;
6028+ dma_addr_t top_dma;
6029+ dma_addr_t bottom_dma;
6030+};
6031+
6032+static struct go7007_board_info board_voyager = {
6033+ .firmware = "go7007tv.bin",
6034+ .flags = 0,
6035+ .sensor_flags = GO7007_SENSOR_656 |
6036+ GO7007_SENSOR_VALID_ENABLE |
6037+ GO7007_SENSOR_TV |
6038+ GO7007_SENSOR_VBI,
6039+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
6040+ GO7007_AUDIO_WORD_16,
6041+ .audio_rate = 48000,
6042+ .audio_bclk_div = 8,
6043+ .audio_main_div = 2,
6044+ .hpi_buffer_cap = 7,
6045+ .num_inputs = 1,
6046+ .inputs = {
6047+ {
6048+ .name = "SAA7134",
6049+ },
6050+ },
6051+};
6052+
6053+/********************* Driver for GPIO HPI interface *********************/
6054+
6055+static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
6056+{
6057+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
6058+
6059+ /* Write HPI address */
6060+ saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
6061+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
6062+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
6063+
6064+ /* Write low byte */
6065+ saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
6066+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
6067+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
6068+
6069+ /* Write high byte */
6070+ saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8);
6071+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
6072+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
6073+
6074+ return 0;
6075+}
6076+
6077+static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
6078+{
6079+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
6080+
6081+ /* Write HPI address */
6082+ saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
6083+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
6084+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
6085+
6086+ saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
6087+
6088+ /* Read low byte */
6089+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
6090+ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
6091+ saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
6092+ *data = saa_readb(SAA7134_GPIO_GPSTATUS0);
6093+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
6094+
6095+ /* Read high byte */
6096+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
6097+ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
6098+ saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
6099+ *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
6100+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
6101+
6102+ return 0;
6103+}
6104+
6105+static int saa7134_go7007_interface_reset(struct go7007 *go)
6106+{
6107+ struct saa7134_go7007 *saa = go->hpi_context;
6108+ struct saa7134_dev *dev = saa->dev;
6109+ u32 status;
6110+ u16 intr_val, intr_data;
6111+ int count = 20;
6112+
6113+ saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
6114+ saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4);
6115+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
6116+
6117+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
6118+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET);
6119+ msleep(1);
6120+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
6121+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
6122+ msleep(10);
6123+
6124+ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
6125+ saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
6126+
6127+ status = saa_readb(SAA7134_GPIO_GPSTATUS2);
6128+ /*printk(KERN_DEBUG "status is %s\n", status & 0x40 ? "OK" : "not OK"); */
6129+
6130+ /* enter command mode...(?) */
6131+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
6132+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
6133+
6134+ do {
6135+ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
6136+ saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
6137+ status = saa_readb(SAA7134_GPIO_GPSTATUS2);
6138+ /*printk(KERN_INFO "gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
6139+ } while (--count > 0);
6140+
6141+ /* Wait for an interrupt to indicate successful hardware reset */
6142+ if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
6143+ (intr_val & ~0x1) != 0x55aa) {
6144+ printk(KERN_ERR
6145+ "saa7134-go7007: unable to reset the GO7007\n");
6146+ return -1;
6147+ }
6148+ return 0;
6149+}
6150+
6151+static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
6152+{
6153+ struct saa7134_go7007 *saa = go->hpi_context;
6154+ struct saa7134_dev *dev = saa->dev;
6155+ int i;
6156+ u16 status_reg;
6157+
6158+#ifdef GO7007_HPI_DEBUG
6159+ printk(KERN_DEBUG
6160+ "saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
6161+#endif
6162+
6163+ for (i = 0; i < 100; ++i) {
6164+ gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
6165+ if (!(status_reg & 0x0010))
6166+ break;
6167+ msleep(10);
6168+ }
6169+ if (i == 100) {
6170+ printk(KERN_ERR
6171+ "saa7134-go7007: device is hung, status reg = 0x%04x\n",
6172+ status_reg);
6173+ return -1;
6174+ }
6175+ gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data);
6176+ gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr);
6177+
6178+ return 0;
6179+}
6180+
6181+static int saa7134_go7007_read_interrupt(struct go7007 *go)
6182+{
6183+ struct saa7134_go7007 *saa = go->hpi_context;
6184+ struct saa7134_dev *dev = saa->dev;
6185+
6186+ /* XXX we need to wait if there is no interrupt available */
6187+ go->interrupt_available = 1;
6188+ gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value);
6189+ gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data);
6190+#ifdef GO7007_HPI_DEBUG
6191+ printk(KERN_DEBUG "saa7134-go7007: ReadInterrupt: %04x %04x\n",
6192+ go->interrupt_value, go->interrupt_data);
6193+#endif
6194+ return 0;
6195+}
6196+
6197+static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
6198+ unsigned long status)
6199+{
6200+ struct go7007 *go = video_get_drvdata(dev->empress_dev);
6201+ struct saa7134_go7007 *saa = go->hpi_context;
6202+
6203+ if (!go->streaming)
6204+ return;
6205+ if (0 != (status & 0x000f0000))
6206+ printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n",
6207+ (status >> 16) & 0x0f);
6208+ if (status & 0x100000) {
6209+ dma_sync_single(&dev->pci->dev,
6210+ saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE);
6211+ go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE);
6212+ saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
6213+ } else {
6214+ dma_sync_single(&dev->pci->dev,
6215+ saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE);
6216+ go7007_parse_video_stream(go, saa->top, PAGE_SIZE);
6217+ saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
6218+ }
6219+}
6220+
6221+static int saa7134_go7007_stream_start(struct go7007 *go)
6222+{
6223+ struct saa7134_go7007 *saa = go->hpi_context;
6224+ struct saa7134_dev *dev = saa->dev;
6225+
6226+ saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
6227+ 0, PAGE_SIZE, DMA_FROM_DEVICE);
6228+ if (!saa->top_dma)
6229+ return -ENOMEM;
6230+ saa->bottom_dma = dma_map_page(&dev->pci->dev,
6231+ virt_to_page(saa->bottom),
6232+ 0, PAGE_SIZE, DMA_FROM_DEVICE);
6233+ if (!saa->bottom_dma) {
6234+ dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
6235+ DMA_FROM_DEVICE);
6236+ return -ENOMEM;
6237+ }
6238+
6239+ saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
6240+ saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
6241+
6242+ /* Set HPI interface for video */
6243+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
6244+ saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER);
6245+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
6246+ saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
6247+
6248+ /* Enable TS interface */
6249+ saa_writeb(SAA7134_TS_PARALLEL, 0xe6);
6250+
6251+ /* Reset TS interface */
6252+ saa_setb(SAA7134_TS_SERIAL1, 0x01);
6253+ saa_clearb(SAA7134_TS_SERIAL1, 0x01);
6254+
6255+ /* Set up transfer block size */
6256+ saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1);
6257+ saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1);
6258+ saa_writeb(SAA7134_TS_DMA1, 0);
6259+ saa_writeb(SAA7134_TS_DMA2, 0);
6260+
6261+ /* Enable video streaming mode */
6262+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO);
6263+
6264+ saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
6265+ saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
6266+ saa_writel(SAA7134_RS_PITCH(5), 128);
6267+ saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX);
6268+
6269+ /* Enable TS FIFO */
6270+ saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
6271+
6272+ /* Enable DMA IRQ */
6273+ saa_setl(SAA7134_IRQ1,
6274+ SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
6275+
6276+ return 0;
6277+}
6278+
6279+static int saa7134_go7007_stream_stop(struct go7007 *go)
6280+{
6281+ struct saa7134_go7007 *saa = go->hpi_context;
6282+ struct saa7134_dev *dev = saa->dev;
6283+
6284+ /* Shut down TS FIFO */
6285+ saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
6286+
6287+ /* Disable DMA IRQ */
6288+ saa_clearl(SAA7134_IRQ1,
6289+ SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
6290+
6291+ /* Disable TS interface */
6292+ saa_clearb(SAA7134_TS_PARALLEL, 0x80);
6293+
6294+ dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
6295+ DMA_FROM_DEVICE);
6296+ dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
6297+ DMA_FROM_DEVICE);
6298+
6299+ return 0;
6300+}
6301+
6302+static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
6303+{
6304+ struct saa7134_go7007 *saa = go->hpi_context;
6305+ struct saa7134_dev *dev = saa->dev;
6306+ u16 status_reg;
6307+ int i;
6308+
6309+#ifdef GO7007_HPI_DEBUG
6310+ printk(KERN_DEBUG "saa7134-go7007: DownloadBuffer "
6311+ "sending %d bytes\n", len);
6312+#endif
6313+
6314+ while (len > 0) {
6315+ i = len > 64 ? 64 : len;
6316+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
6317+ saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER);
6318+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
6319+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
6320+ while (i-- > 0) {
6321+ saa_writeb(SAA7134_GPIO_GPSTATUS0, *data);
6322+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
6323+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
6324+ ++data;
6325+ --len;
6326+ }
6327+ for (i = 0; i < 100; ++i) {
6328+ gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
6329+ if (!(status_reg & 0x0002))
6330+ break;
6331+ }
6332+ if (i == 100) {
6333+ printk(KERN_ERR "saa7134-go7007: device is hung, "
6334+ "status reg = 0x%04x\n", status_reg);
6335+ return -1;
6336+ }
6337+ }
6338+ return 0;
6339+}
6340+
6341+static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
6342+ .interface_reset = saa7134_go7007_interface_reset,
6343+ .write_interrupt = saa7134_go7007_write_interrupt,
6344+ .read_interrupt = saa7134_go7007_read_interrupt,
6345+ .stream_start = saa7134_go7007_stream_start,
6346+ .stream_stop = saa7134_go7007_stream_stop,
6347+ .send_firmware = saa7134_go7007_send_firmware,
6348+};
6349+
6350+/********************* Add/remove functions *********************/
6351+
6352+static int saa7134_go7007_init(struct saa7134_dev *dev)
6353+{
6354+ struct go7007 *go;
6355+ struct saa7134_go7007 *saa;
6356+
6357+ printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n");
6358+
6359+ saa = kmalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
6360+ if (saa == NULL)
6361+ return -ENOMEM;
6362+ memset(saa, 0, sizeof(struct saa7134_go7007));
6363+
6364+ /* Allocate a couple pages for receiving the compressed stream */
6365+ saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
6366+ if (!saa->top)
6367+ goto allocfail;
6368+ saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
6369+ if (!saa->bottom)
6370+ goto allocfail;
6371+
6372+ go = go7007_alloc(&board_voyager, &dev->pci->dev);
6373+ if (go == NULL)
6374+ goto allocfail;
6375+ go->board_id = GO7007_BOARDID_PCI_VOYAGER;
6376+ strncpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
6377+ go->hpi_ops = &saa7134_go7007_hpi_ops;
6378+ go->hpi_context = saa;
6379+ saa->dev = dev;
6380+
6381+ /* Boot the GO7007 */
6382+ if (go7007_boot_encoder(go, go->board_info->flags &
6383+ GO7007_BOARD_USE_ONBOARD_I2C) < 0)
6384+ goto initfail;
6385+
6386+ /* Do any final GO7007 initialization, then register the
6387+ * V4L2 and ALSA interfaces */
6388+ if (go7007_register_encoder(go) < 0)
6389+ goto initfail;
6390+ dev->empress_dev = go->video_dev;
6391+ video_set_drvdata(dev->empress_dev, go);
6392+
6393+ go->status = STATUS_ONLINE;
6394+ return 0;
6395+
6396+initfail:
6397+ go->status = STATUS_SHUTDOWN;
6398+ return 0;
6399+
6400+allocfail:
6401+ if (saa->top)
6402+ free_page((unsigned long)saa->top);
6403+ if (saa->bottom)
6404+ free_page((unsigned long)saa->bottom);
6405+ kfree(saa);
6406+ return -ENOMEM;
6407+}
6408+
6409+static int saa7134_go7007_fini(struct saa7134_dev *dev)
6410+{
6411+ struct go7007 *go;
6412+ struct saa7134_go7007 *saa;
6413+
6414+ if (NULL == dev->empress_dev)
6415+ return 0;
6416+
6417+ go = video_get_drvdata(dev->empress_dev);
6418+ saa = go->hpi_context;
6419+ go->status = STATUS_SHUTDOWN;
6420+ free_page((unsigned long)saa->top);
6421+ free_page((unsigned long)saa->bottom);
6422+ kfree(saa);
6423+ go7007_remove(go);
6424+ dev->empress_dev = NULL;
6425+
6426+ return 0;
6427+}
6428+
6429+static struct saa7134_mpeg_ops saa7134_go7007_ops = {
6430+ .type = SAA7134_MPEG_GO7007,
6431+ .init = saa7134_go7007_init,
6432+ .fini = saa7134_go7007_fini,
6433+ .irq_ts_done = saa7134_go7007_irq_ts_done,
6434+};
6435+
6436+static int __init saa7134_go7007_mod_init(void)
6437+{
6438+ return saa7134_ts_register(&saa7134_go7007_ops);
6439+}
6440+
6441+static void __exit saa7134_go7007_mod_cleanup(void)
6442+{
6443+ saa7134_ts_unregister(&saa7134_go7007_ops);
6444+}
6445+
6446+module_init(saa7134_go7007_mod_init);
6447+module_exit(saa7134_go7007_mod_cleanup);
6448+
6449+MODULE_LICENSE("GPL v2");
6450diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c
6451new file mode 100644
6452index 0000000..f5cac08
6453--- /dev/null
6454+++ b/drivers/staging/go7007/snd-go7007.c
6455@@ -0,0 +1,305 @@
6456+/*
6457+ * Copyright (C) 2005-2006 Micronas USA Inc.
6458+ *
6459+ * This program is free software; you can redistribute it and/or modify
6460+ * it under the terms of the GNU General Public License (Version 2) as
6461+ * published by the Free Software Foundation.
6462+ *
6463+ * This program is distributed in the hope that it will be useful,
6464+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6465+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6466+ * GNU General Public License for more details.
6467+ *
6468+ * You should have received a copy of the GNU General Public License
6469+ * along with this program; if not, write to the Free Software Foundation,
6470+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
6471+ */
6472+
6473+#include <linux/kernel.h>
6474+#include <linux/module.h>
6475+#include <linux/version.h>
6476+#include <linux/moduleparam.h>
6477+#include <linux/init.h>
6478+#include <linux/spinlock.h>
6479+#include <linux/delay.h>
6480+#include <linux/sched.h>
6481+#include <linux/vmalloc.h>
6482+#include <linux/time.h>
6483+#include <linux/mm.h>
6484+#include <linux/i2c.h>
6485+#include <linux/semaphore.h>
6486+#include <linux/uaccess.h>
6487+#include <asm/system.h>
6488+#include <sound/core.h>
6489+#include <sound/pcm.h>
6490+#include <sound/initval.h>
6491+
6492+#include "go7007-priv.h"
6493+
6494+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
6495+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
6496+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
6497+
6498+module_param_array(index, int, NULL, 0444);
6499+module_param_array(id, charp, NULL, 0444);
6500+module_param_array(enable, bool, NULL, 0444);
6501+MODULE_PARM_DESC(index, "Index value for the go7007 audio driver");
6502+MODULE_PARM_DESC(index, "ID string for the go7007 audio driver");
6503+MODULE_PARM_DESC(index, "Enable for the go7007 audio driver");
6504+
6505+struct go7007_snd {
6506+ struct snd_card *card;
6507+ struct snd_pcm *pcm;
6508+ struct snd_pcm_substream *substream;
6509+ spinlock_t lock;
6510+ int w_idx;
6511+ int hw_ptr;
6512+ int avail;
6513+ int capturing;
6514+};
6515+
6516+static struct snd_pcm_hardware go7007_snd_capture_hw = {
6517+ .info = (SNDRV_PCM_INFO_MMAP |
6518+ SNDRV_PCM_INFO_INTERLEAVED |
6519+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
6520+ SNDRV_PCM_INFO_MMAP_VALID),
6521+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
6522+ .rates = SNDRV_PCM_RATE_48000,
6523+ .rate_min = 48000,
6524+ .rate_max = 48000,
6525+ .channels_min = 2,
6526+ .channels_max = 2,
6527+ .buffer_bytes_max = (128*1024),
6528+ .period_bytes_min = 4096,
6529+ .period_bytes_max = (128*1024),
6530+ .periods_min = 1,
6531+ .periods_max = 32,
6532+};
6533+
6534+static void parse_audio_stream_data(struct go7007 *go, u8 *buf, int length)
6535+{
6536+ struct go7007_snd *gosnd = go->snd_context;
6537+ struct snd_pcm_runtime *runtime = gosnd->substream->runtime;
6538+ int frames = bytes_to_frames(runtime, length);
6539+
6540+ spin_lock(&gosnd->lock);
6541+ gosnd->hw_ptr += frames;
6542+ if (gosnd->hw_ptr >= runtime->buffer_size)
6543+ gosnd->hw_ptr -= runtime->buffer_size;
6544+ gosnd->avail += frames;
6545+ spin_unlock(&gosnd->lock);
6546+ if (gosnd->w_idx + length > runtime->dma_bytes) {
6547+ int cpy = runtime->dma_bytes - gosnd->w_idx;
6548+
6549+ memcpy(runtime->dma_area + gosnd->w_idx, buf, cpy);
6550+ length -= cpy;
6551+ buf += cpy;
6552+ gosnd->w_idx = 0;
6553+ }
6554+ memcpy(runtime->dma_area + gosnd->w_idx, buf, length);
6555+ gosnd->w_idx += length;
6556+ spin_lock(&gosnd->lock);
6557+ if (gosnd->avail < runtime->period_size) {
6558+ spin_unlock(&gosnd->lock);
6559+ return;
6560+ }
6561+ gosnd->avail -= runtime->period_size;
6562+ spin_unlock(&gosnd->lock);
6563+ if (gosnd->capturing)
6564+ snd_pcm_period_elapsed(gosnd->substream);
6565+}
6566+
6567+static int go7007_snd_hw_params(struct snd_pcm_substream *substream,
6568+ struct snd_pcm_hw_params *hw_params)
6569+{
6570+ struct go7007 *go = snd_pcm_substream_chip(substream);
6571+ unsigned int bytes;
6572+
6573+ bytes = params_buffer_bytes(hw_params);
6574+ if (substream->runtime->dma_bytes > 0)
6575+ vfree(substream->runtime->dma_area);
6576+ substream->runtime->dma_bytes = 0;
6577+ substream->runtime->dma_area = vmalloc(bytes);
6578+ if (substream->runtime->dma_area == NULL)
6579+ return -ENOMEM;
6580+ substream->runtime->dma_bytes = bytes;
6581+ go->audio_deliver = parse_audio_stream_data;
6582+ return 0;
6583+}
6584+
6585+static int go7007_snd_hw_free(struct snd_pcm_substream *substream)
6586+{
6587+ struct go7007 *go = snd_pcm_substream_chip(substream);
6588+
6589+ go->audio_deliver = NULL;
6590+ if (substream->runtime->dma_bytes > 0)
6591+ vfree(substream->runtime->dma_area);
6592+ substream->runtime->dma_bytes = 0;
6593+ return 0;
6594+}
6595+
6596+static int go7007_snd_capture_open(struct snd_pcm_substream *substream)
6597+{
6598+ struct go7007 *go = snd_pcm_substream_chip(substream);
6599+ struct go7007_snd *gosnd = go->snd_context;
6600+ unsigned long flags;
6601+ int r;
6602+
6603+ spin_lock_irqsave(&gosnd->lock, flags);
6604+ if (gosnd->substream == NULL) {
6605+ gosnd->substream = substream;
6606+ substream->runtime->hw = go7007_snd_capture_hw;
6607+ r = 0;
6608+ } else
6609+ r = -EBUSY;
6610+ spin_unlock_irqrestore(&gosnd->lock, flags);
6611+ return r;
6612+}
6613+
6614+static int go7007_snd_capture_close(struct snd_pcm_substream *substream)
6615+{
6616+ struct go7007 *go = snd_pcm_substream_chip(substream);
6617+ struct go7007_snd *gosnd = go->snd_context;
6618+
6619+ gosnd->substream = NULL;
6620+ return 0;
6621+}
6622+
6623+static int go7007_snd_pcm_prepare(struct snd_pcm_substream *substream)
6624+{
6625+ return 0;
6626+}
6627+
6628+static int go7007_snd_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
6629+{
6630+ struct go7007 *go = snd_pcm_substream_chip(substream);
6631+ struct go7007_snd *gosnd = go->snd_context;
6632+
6633+ switch (cmd) {
6634+ case SNDRV_PCM_TRIGGER_START:
6635+ /* Just set a flag to indicate we should signal ALSA when
6636+ * sound comes in */
6637+ gosnd->capturing = 1;
6638+ return 0;
6639+ case SNDRV_PCM_TRIGGER_STOP:
6640+ gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
6641+ gosnd->capturing = 0;
6642+ return 0;
6643+ default:
6644+ return -EINVAL;
6645+ }
6646+}
6647+
6648+static snd_pcm_uframes_t go7007_snd_pcm_pointer(struct snd_pcm_substream *substream)
6649+{
6650+ struct go7007 *go = snd_pcm_substream_chip(substream);
6651+ struct go7007_snd *gosnd = go->snd_context;
6652+
6653+ return gosnd->hw_ptr;
6654+}
6655+
6656+static struct page *go7007_snd_pcm_page(struct snd_pcm_substream *substream,
6657+ unsigned long offset)
6658+{
6659+ return vmalloc_to_page(substream->runtime->dma_area + offset);
6660+}
6661+
6662+static struct snd_pcm_ops go7007_snd_capture_ops = {
6663+ .open = go7007_snd_capture_open,
6664+ .close = go7007_snd_capture_close,
6665+ .ioctl = snd_pcm_lib_ioctl,
6666+ .hw_params = go7007_snd_hw_params,
6667+ .hw_free = go7007_snd_hw_free,
6668+ .prepare = go7007_snd_pcm_prepare,
6669+ .trigger = go7007_snd_pcm_trigger,
6670+ .pointer = go7007_snd_pcm_pointer,
6671+ .page = go7007_snd_pcm_page,
6672+};
6673+
6674+static int go7007_snd_free(struct snd_device *device)
6675+{
6676+ struct go7007 *go = device->device_data;
6677+
6678+ kfree(go->snd_context);
6679+ go->snd_context = NULL;
6680+ if (--go->ref_count == 0)
6681+ kfree(go);
6682+ return 0;
6683+}
6684+
6685+static struct snd_device_ops go7007_snd_device_ops = {
6686+ .dev_free = go7007_snd_free,
6687+};
6688+
6689+int go7007_snd_init(struct go7007 *go)
6690+{
6691+ static int dev;
6692+ struct go7007_snd *gosnd;
6693+ int ret = 0;
6694+
6695+ if (dev >= SNDRV_CARDS)
6696+ return -ENODEV;
6697+ if (!enable[dev]) {
6698+ dev++;
6699+ return -ENOENT;
6700+ }
6701+ gosnd = kmalloc(sizeof(struct go7007_snd), GFP_KERNEL);
6702+ if (gosnd == NULL)
6703+ return -ENOMEM;
6704+ spin_lock_init(&gosnd->lock);
6705+ gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
6706+ gosnd->capturing = 0;
6707+ gosnd->card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
6708+ if (gosnd->card == NULL) {
6709+ kfree(gosnd);
6710+ return -ENOMEM;
6711+ }
6712+ ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
6713+ &go7007_snd_device_ops);
6714+ if (ret < 0) {
6715+ kfree(gosnd);
6716+ return ret;
6717+ }
6718+ snd_card_set_dev(gosnd->card, go->dev);
6719+ ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
6720+ if (ret < 0) {
6721+ snd_card_free(gosnd->card);
6722+ kfree(gosnd);
6723+ return ret;
6724+ }
6725+ strncpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
6726+ strncpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
6727+ strncpy(gosnd->card->longname, gosnd->card->shortname,
6728+ sizeof(gosnd->card->longname));
6729+
6730+ gosnd->pcm->private_data = go;
6731+ snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE,
6732+ &go7007_snd_capture_ops);
6733+
6734+ ret = snd_card_register(gosnd->card);
6735+ if (ret < 0) {
6736+ snd_card_free(gosnd->card);
6737+ kfree(gosnd);
6738+ return ret;
6739+ }
6740+
6741+ gosnd->substream = NULL;
6742+ go->snd_context = gosnd;
6743+ ++dev;
6744+ ++go->ref_count;
6745+
6746+ return 0;
6747+}
6748+EXPORT_SYMBOL(go7007_snd_init);
6749+
6750+int go7007_snd_remove(struct go7007 *go)
6751+{
6752+ struct go7007_snd *gosnd = go->snd_context;
6753+
6754+ snd_card_disconnect(gosnd->card);
6755+ snd_card_free_when_closed(gosnd->card);
6756+ return 0;
6757+}
6758+EXPORT_SYMBOL(go7007_snd_remove);
6759+
6760+MODULE_LICENSE("GPL v2");
6761diff --git a/drivers/staging/go7007/wis-i2c.h b/drivers/staging/go7007/wis-i2c.h
6762new file mode 100644
6763index 0000000..993f658
6764--- /dev/null
6765+++ b/drivers/staging/go7007/wis-i2c.h
6766@@ -0,0 +1,55 @@
6767+/*
6768+ * Copyright (C) 2005-2006 Micronas USA Inc.
6769+ *
6770+ * This program is free software; you can redistribute it and/or modify
6771+ * it under the terms of the GNU General Public License (Version 2) as
6772+ * published by the Free Software Foundation.
6773+ *
6774+ * This program is distributed in the hope that it will be useful,
6775+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6776+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6777+ * GNU General Public License for more details.
6778+ *
6779+ * You should have received a copy of the GNU General Public License
6780+ * along with this program; if not, write to the Free Software Foundation,
6781+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
6782+ */
6783+
6784+/* Temporary I2C IDs -- these need to be replaced with real registered IDs */
6785+#define I2C_DRIVERID_WIS_SAA7115 0xf0f0
6786+#define I2C_DRIVERID_WIS_UDA1342 0xf0f1
6787+#define I2C_DRIVERID_WIS_SONY_TUNER 0xf0f2
6788+#define I2C_DRIVERID_WIS_TW9903 0xf0f3
6789+#define I2C_DRIVERID_WIS_SAA7113 0xf0f4
6790+#define I2C_DRIVERID_WIS_OV7640 0xf0f5
6791+#define I2C_DRIVERID_WIS_TW2804 0xf0f6
6792+#define I2C_ALGO_GO7007 0xf00000
6793+#define I2C_ALGO_GO7007_USB 0xf10000
6794+
6795+/* Flag to indicate that the client needs to be accessed with SCCB semantics */
6796+/* We re-use the I2C_M_TEN value so the flag passes through the masks in the
6797+ * core I2C code. Major kludge, but the I2C layer ain't exactly flexible. */
6798+#define I2C_CLIENT_SCCB 0x10
6799+
6800+typedef int (*found_proc) (struct i2c_adapter *, int, int);
6801+int wis_i2c_add_driver(unsigned int id, found_proc found_proc);
6802+void wis_i2c_del_driver(found_proc found_proc);
6803+
6804+int wis_i2c_probe_device(struct i2c_adapter *adapter,
6805+ unsigned int id, int addr);
6806+
6807+/* Definitions for new video decoder commands */
6808+
6809+struct video_decoder_resolution {
6810+ unsigned int width;
6811+ unsigned int height;
6812+};
6813+
6814+#define DECODER_SET_RESOLUTION _IOW('d', 200, struct video_decoder_resolution)
6815+#define DECODER_SET_CHANNEL _IOW('d', 201, int)
6816+
6817+/* Sony tuner types */
6818+
6819+#define TUNER_SONY_BTF_PG472Z 200
6820+#define TUNER_SONY_BTF_PK467Z 201
6821+#define TUNER_SONY_BTF_PB463Z 202
6822diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/go7007/wis-ov7640.c
6823new file mode 100644
6824index 0000000..815615a
6825--- /dev/null
6826+++ b/drivers/staging/go7007/wis-ov7640.c
6827@@ -0,0 +1,131 @@
6828+/*
6829+ * Copyright (C) 2005-2006 Micronas USA Inc.
6830+ *
6831+ * This program is free software; you can redistribute it and/or modify
6832+ * it under the terms of the GNU General Public License (Version 2) as
6833+ * published by the Free Software Foundation.
6834+ *
6835+ * This program is distributed in the hope that it will be useful,
6836+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6837+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6838+ * GNU General Public License for more details.
6839+ *
6840+ * You should have received a copy of the GNU General Public License
6841+ * along with this program; if not, write to the Free Software Foundation,
6842+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
6843+ */
6844+
6845+#include <linux/module.h>
6846+#include <linux/init.h>
6847+#include <linux/version.h>
6848+#include <linux/i2c.h>
6849+#include <linux/videodev.h>
6850+#include <linux/video_decoder.h>
6851+
6852+#include "wis-i2c.h"
6853+
6854+struct wis_ov7640 {
6855+ int brightness;
6856+ int contrast;
6857+ int saturation;
6858+ int hue;
6859+};
6860+
6861+static u8 initial_registers[] =
6862+{
6863+ 0x12, 0x80,
6864+ 0x12, 0x54,
6865+ 0x14, 0x24,
6866+ 0x15, 0x01,
6867+ 0x28, 0x20,
6868+ 0x75, 0x82,
6869+ 0xFF, 0xFF, /* Terminator (reg 0xFF is unused) */
6870+};
6871+
6872+static int write_regs(struct i2c_client *client, u8 *regs)
6873+{
6874+ int i;
6875+
6876+ for (i = 0; regs[i] != 0xFF; i += 2)
6877+ if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
6878+ return -1;
6879+ return 0;
6880+}
6881+
6882+static struct i2c_driver wis_ov7640_driver;
6883+
6884+static struct i2c_client wis_ov7640_client_templ = {
6885+ .name = "OV7640 (WIS)",
6886+ .driver = &wis_ov7640_driver,
6887+};
6888+
6889+static int wis_ov7640_detect(struct i2c_adapter *adapter, int addr, int kind)
6890+{
6891+ struct i2c_client *client;
6892+
6893+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
6894+ return 0;
6895+
6896+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
6897+ if (client == NULL)
6898+ return -ENOMEM;
6899+ memcpy(client, &wis_ov7640_client_templ,
6900+ sizeof(wis_ov7640_client_templ));
6901+ client->adapter = adapter;
6902+ client->addr = addr;
6903+ client->flags = I2C_CLIENT_SCCB;
6904+
6905+ printk(KERN_DEBUG
6906+ "wis-ov7640: initializing OV7640 at address %d on %s\n",
6907+ addr, adapter->name);
6908+
6909+ if (write_regs(client, initial_registers) < 0) {
6910+ printk(KERN_ERR "wis-ov7640: error initializing OV7640\n");
6911+ kfree(client);
6912+ return 0;
6913+ }
6914+
6915+ i2c_attach_client(client);
6916+ return 0;
6917+}
6918+
6919+static int wis_ov7640_detach(struct i2c_client *client)
6920+{
6921+ int r;
6922+
6923+ r = i2c_detach_client(client);
6924+ if (r < 0)
6925+ return r;
6926+
6927+ kfree(client);
6928+ return 0;
6929+}
6930+
6931+static struct i2c_driver wis_ov7640_driver = {
6932+ .driver = {
6933+ .name = "WIS OV7640 I2C driver",
6934+ },
6935+ .id = I2C_DRIVERID_WIS_OV7640,
6936+ .detach_client = wis_ov7640_detach,
6937+};
6938+
6939+static int __init wis_ov7640_init(void)
6940+{
6941+ int r;
6942+
6943+ r = i2c_add_driver(&wis_ov7640_driver);
6944+ if (r < 0)
6945+ return r;
6946+ return wis_i2c_add_driver(wis_ov7640_driver.id, wis_ov7640_detect);
6947+}
6948+
6949+static void __exit wis_ov7640_cleanup(void)
6950+{
6951+ wis_i2c_del_driver(wis_ov7640_detect);
6952+ i2c_del_driver(&wis_ov7640_driver);
6953+}
6954+
6955+module_init(wis_ov7640_init);
6956+module_exit(wis_ov7640_cleanup);
6957+
6958+MODULE_LICENSE("GPL v2");
6959diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c
6960new file mode 100644
6961index 0000000..4b14ca8
6962--- /dev/null
6963+++ b/drivers/staging/go7007/wis-saa7113.c
6964@@ -0,0 +1,363 @@
6965+/*
6966+ * Copyright (C) 2005-2006 Micronas USA Inc.
6967+ *
6968+ * This program is free software; you can redistribute it and/or modify
6969+ * it under the terms of the GNU General Public License (Version 2) as
6970+ * published by the Free Software Foundation.
6971+ *
6972+ * This program is distributed in the hope that it will be useful,
6973+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6974+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6975+ * GNU General Public License for more details.
6976+ *
6977+ * You should have received a copy of the GNU General Public License
6978+ * along with this program; if not, write to the Free Software Foundation,
6979+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
6980+ */
6981+
6982+#include <linux/module.h>
6983+#include <linux/init.h>
6984+#include <linux/version.h>
6985+#include <linux/i2c.h>
6986+#include <linux/videodev.h>
6987+#include <linux/video_decoder.h>
6988+#include <linux/ioctl.h>
6989+
6990+#include "wis-i2c.h"
6991+
6992+struct wis_saa7113 {
6993+ int norm;
6994+ int brightness;
6995+ int contrast;
6996+ int saturation;
6997+ int hue;
6998+};
6999+
7000+static u8 initial_registers[] =
7001+{
7002+ 0x01, 0x08,
7003+ 0x02, 0xc0,
7004+ 0x03, 0x33,
7005+ 0x04, 0x00,
7006+ 0x05, 0x00,
7007+ 0x06, 0xe9,
7008+ 0x07, 0x0d,
7009+ 0x08, 0xd8,
7010+ 0x09, 0x40,
7011+ 0x0a, 0x80,
7012+ 0x0b, 0x47,
7013+ 0x0c, 0x40,
7014+ 0x0d, 0x00,
7015+ 0x0e, 0x01,
7016+ 0x0f, 0x2a,
7017+ 0x10, 0x40,
7018+ 0x11, 0x0c,
7019+ 0x12, 0xfe,
7020+ 0x13, 0x00,
7021+ 0x14, 0x00,
7022+ 0x15, 0x04,
7023+ 0x16, 0x00,
7024+ 0x17, 0x00,
7025+ 0x18, 0x00,
7026+ 0x19, 0x00,
7027+ 0x1a, 0x00,
7028+ 0x1b, 0x00,
7029+ 0x1c, 0x00,
7030+ 0x1d, 0x00,
7031+ 0x1e, 0x00,
7032+ 0x1f, 0xc8,
7033+ 0x40, 0x00,
7034+ 0x41, 0xff,
7035+ 0x42, 0xff,
7036+ 0x43, 0xff,
7037+ 0x44, 0xff,
7038+ 0x45, 0xff,
7039+ 0x46, 0xff,
7040+ 0x47, 0xff,
7041+ 0x48, 0xff,
7042+ 0x49, 0xff,
7043+ 0x4a, 0xff,
7044+ 0x4b, 0xff,
7045+ 0x4c, 0xff,
7046+ 0x4d, 0xff,
7047+ 0x4e, 0xff,
7048+ 0x4f, 0xff,
7049+ 0x50, 0xff,
7050+ 0x51, 0xff,
7051+ 0x52, 0xff,
7052+ 0x53, 0xff,
7053+ 0x54, 0xff,
7054+ 0x55, 0xff,
7055+ 0x56, 0xff,
7056+ 0x57, 0xff,
7057+ 0x58, 0x00,
7058+ 0x59, 0x54,
7059+ 0x5a, 0x07,
7060+ 0x5b, 0x83,
7061+ 0x5c, 0x00,
7062+ 0x5d, 0x00,
7063+ 0x5e, 0x00,
7064+ 0x5f, 0x00,
7065+ 0x60, 0x00,
7066+ 0x61, 0x00,
7067+ 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
7068+};
7069+
7070+static int write_reg(struct i2c_client *client, u8 reg, u8 value)
7071+{
7072+ return i2c_smbus_write_byte_data(client, reg, value);
7073+}
7074+
7075+static int write_regs(struct i2c_client *client, u8 *regs)
7076+{
7077+ int i;
7078+
7079+ for (i = 0; regs[i] != 0x00; i += 2)
7080+ if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
7081+ return -1;
7082+ return 0;
7083+}
7084+
7085+static int wis_saa7113_command(struct i2c_client *client,
7086+ unsigned int cmd, void *arg)
7087+{
7088+ struct wis_saa7113 *dec = i2c_get_clientdata(client);
7089+
7090+ switch (cmd) {
7091+ case DECODER_SET_INPUT:
7092+ {
7093+ int *input = arg;
7094+
7095+ i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
7096+ i2c_smbus_write_byte_data(client, 0x09,
7097+ *input < 6 ? 0x40 : 0x80);
7098+ break;
7099+ }
7100+ case DECODER_SET_NORM:
7101+ {
7102+ int *input = arg;
7103+ dec->norm = *input;
7104+ switch (dec->norm) {
7105+ case VIDEO_MODE_PAL:
7106+ write_reg(client, 0x0e, 0x01);
7107+ write_reg(client, 0x10, 0x48);
7108+ break;
7109+ case VIDEO_MODE_NTSC:
7110+ write_reg(client, 0x0e, 0x01);
7111+ write_reg(client, 0x10, 0x40);
7112+ break;
7113+ case VIDEO_MODE_SECAM:
7114+ write_reg(client, 0x0e, 0x50);
7115+ write_reg(client, 0x10, 0x48);
7116+ break;
7117+ }
7118+ break;
7119+ }
7120+ case VIDIOC_QUERYCTRL:
7121+ {
7122+ struct v4l2_queryctrl *ctrl = arg;
7123+
7124+ switch (ctrl->id) {
7125+ case V4L2_CID_BRIGHTNESS:
7126+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
7127+ strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
7128+ ctrl->minimum = 0;
7129+ ctrl->maximum = 255;
7130+ ctrl->step = 1;
7131+ ctrl->default_value = 128;
7132+ ctrl->flags = 0;
7133+ break;
7134+ case V4L2_CID_CONTRAST:
7135+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
7136+ strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
7137+ ctrl->minimum = 0;
7138+ ctrl->maximum = 127;
7139+ ctrl->step = 1;
7140+ ctrl->default_value = 71;
7141+ ctrl->flags = 0;
7142+ break;
7143+ case V4L2_CID_SATURATION:
7144+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
7145+ strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
7146+ ctrl->minimum = 0;
7147+ ctrl->maximum = 127;
7148+ ctrl->step = 1;
7149+ ctrl->default_value = 64;
7150+ ctrl->flags = 0;
7151+ break;
7152+ case V4L2_CID_HUE:
7153+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
7154+ strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
7155+ ctrl->minimum = -128;
7156+ ctrl->maximum = 127;
7157+ ctrl->step = 1;
7158+ ctrl->default_value = 0;
7159+ ctrl->flags = 0;
7160+ break;
7161+ }
7162+ break;
7163+ }
7164+ case VIDIOC_S_CTRL:
7165+ {
7166+ struct v4l2_control *ctrl = arg;
7167+
7168+ switch (ctrl->id) {
7169+ case V4L2_CID_BRIGHTNESS:
7170+ if (ctrl->value > 255)
7171+ dec->brightness = 255;
7172+ else if (ctrl->value < 0)
7173+ dec->brightness = 0;
7174+ else
7175+ dec->brightness = ctrl->value;
7176+ write_reg(client, 0x0a, dec->brightness);
7177+ break;
7178+ case V4L2_CID_CONTRAST:
7179+ if (ctrl->value > 127)
7180+ dec->contrast = 127;
7181+ else if (ctrl->value < 0)
7182+ dec->contrast = 0;
7183+ else
7184+ dec->contrast = ctrl->value;
7185+ write_reg(client, 0x0b, dec->contrast);
7186+ break;
7187+ case V4L2_CID_SATURATION:
7188+ if (ctrl->value > 127)
7189+ dec->saturation = 127;
7190+ else if (ctrl->value < 0)
7191+ dec->saturation = 0;
7192+ else
7193+ dec->saturation = ctrl->value;
7194+ write_reg(client, 0x0c, dec->saturation);
7195+ break;
7196+ case V4L2_CID_HUE:
7197+ if (ctrl->value > 127)
7198+ dec->hue = 127;
7199+ else if (ctrl->value < -128)
7200+ dec->hue = -128;
7201+ else
7202+ dec->hue = ctrl->value;
7203+ write_reg(client, 0x0d, dec->hue);
7204+ break;
7205+ }
7206+ break;
7207+ }
7208+ case VIDIOC_G_CTRL:
7209+ {
7210+ struct v4l2_control *ctrl = arg;
7211+
7212+ switch (ctrl->id) {
7213+ case V4L2_CID_BRIGHTNESS:
7214+ ctrl->value = dec->brightness;
7215+ break;
7216+ case V4L2_CID_CONTRAST:
7217+ ctrl->value = dec->contrast;
7218+ break;
7219+ case V4L2_CID_SATURATION:
7220+ ctrl->value = dec->saturation;
7221+ break;
7222+ case V4L2_CID_HUE:
7223+ ctrl->value = dec->hue;
7224+ break;
7225+ }
7226+ break;
7227+ }
7228+ default:
7229+ break;
7230+ }
7231+ return 0;
7232+}
7233+
7234+static struct i2c_driver wis_saa7113_driver;
7235+
7236+static struct i2c_client wis_saa7113_client_templ = {
7237+ .name = "SAA7113 (WIS)",
7238+ .driver = &wis_saa7113_driver,
7239+};
7240+
7241+static int wis_saa7113_detect(struct i2c_adapter *adapter, int addr, int kind)
7242+{
7243+ struct i2c_client *client;
7244+ struct wis_saa7113 *dec;
7245+
7246+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
7247+ return 0;
7248+
7249+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
7250+ if (client == NULL)
7251+ return -ENOMEM;
7252+ memcpy(client, &wis_saa7113_client_templ,
7253+ sizeof(wis_saa7113_client_templ));
7254+ client->adapter = adapter;
7255+ client->addr = addr;
7256+
7257+ dec = kmalloc(sizeof(struct wis_saa7113), GFP_KERNEL);
7258+ if (dec == NULL) {
7259+ kfree(client);
7260+ return -ENOMEM;
7261+ }
7262+ dec->norm = VIDEO_MODE_NTSC;
7263+ dec->brightness = 128;
7264+ dec->contrast = 71;
7265+ dec->saturation = 64;
7266+ dec->hue = 0;
7267+ i2c_set_clientdata(client, dec);
7268+
7269+ printk(KERN_DEBUG
7270+ "wis-saa7113: initializing SAA7113 at address %d on %s\n",
7271+ addr, adapter->name);
7272+
7273+ if (write_regs(client, initial_registers) < 0) {
7274+ printk(KERN_ERR
7275+ "wis-saa7113: error initializing SAA7113\n");
7276+ kfree(client);
7277+ kfree(dec);
7278+ return 0;
7279+ }
7280+
7281+ i2c_attach_client(client);
7282+ return 0;
7283+}
7284+
7285+static int wis_saa7113_detach(struct i2c_client *client)
7286+{
7287+ struct wis_saa7113 *dec = i2c_get_clientdata(client);
7288+ int r;
7289+
7290+ r = i2c_detach_client(client);
7291+ if (r < 0)
7292+ return r;
7293+
7294+ kfree(client);
7295+ kfree(dec);
7296+ return 0;
7297+}
7298+
7299+static struct i2c_driver wis_saa7113_driver = {
7300+ .driver = {
7301+ .name = "WIS SAA7113 I2C driver",
7302+ },
7303+ .id = I2C_DRIVERID_WIS_SAA7113,
7304+ .detach_client = wis_saa7113_detach,
7305+ .command = wis_saa7113_command,
7306+};
7307+
7308+static int __init wis_saa7113_init(void)
7309+{
7310+ int r;
7311+
7312+ r = i2c_add_driver(&wis_saa7113_driver);
7313+ if (r < 0)
7314+ return r;
7315+ return wis_i2c_add_driver(wis_saa7113_driver.id, wis_saa7113_detect);
7316+}
7317+
7318+static void __exit wis_saa7113_cleanup(void)
7319+{
7320+ wis_i2c_del_driver(wis_saa7113_detect);
7321+ i2c_del_driver(&wis_saa7113_driver);
7322+}
7323+
7324+module_init(wis_saa7113_init);
7325+module_exit(wis_saa7113_cleanup);
7326+
7327+MODULE_LICENSE("GPL v2");
7328diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c
7329new file mode 100644
7330index 0000000..bd40bf4
7331--- /dev/null
7332+++ b/drivers/staging/go7007/wis-saa7115.c
7333@@ -0,0 +1,492 @@
7334+/*
7335+ * Copyright (C) 2005-2006 Micronas USA Inc.
7336+ *
7337+ * This program is free software; you can redistribute it and/or modify
7338+ * it under the terms of the GNU General Public License (Version 2) as
7339+ * published by the Free Software Foundation.
7340+ *
7341+ * This program is distributed in the hope that it will be useful,
7342+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7343+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7344+ * GNU General Public License for more details.
7345+ *
7346+ * You should have received a copy of the GNU General Public License
7347+ * along with this program; if not, write to the Free Software Foundation,
7348+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
7349+ */
7350+
7351+#include <linux/module.h>
7352+#include <linux/init.h>
7353+#include <linux/version.h>
7354+#include <linux/i2c.h>
7355+#include <linux/videodev.h>
7356+#include <linux/video_decoder.h>
7357+#include <linux/ioctl.h>
7358+
7359+#include "wis-i2c.h"
7360+
7361+struct wis_saa7115 {
7362+ int norm;
7363+ int brightness;
7364+ int contrast;
7365+ int saturation;
7366+ int hue;
7367+};
7368+
7369+static u8 initial_registers[] =
7370+{
7371+ 0x01, 0x08,
7372+ 0x02, 0xc0,
7373+ 0x03, 0x20,
7374+ 0x04, 0x80,
7375+ 0x05, 0x80,
7376+ 0x06, 0xeb,
7377+ 0x07, 0xe0,
7378+ 0x08, 0xf0, /* always toggle FID */
7379+ 0x09, 0x40,
7380+ 0x0a, 0x80,
7381+ 0x0b, 0x40,
7382+ 0x0c, 0x40,
7383+ 0x0d, 0x00,
7384+ 0x0e, 0x03,
7385+ 0x0f, 0x2a,
7386+ 0x10, 0x0e,
7387+ 0x11, 0x00,
7388+ 0x12, 0x8d,
7389+ 0x13, 0x00,
7390+ 0x14, 0x00,
7391+ 0x15, 0x11,
7392+ 0x16, 0x01,
7393+ 0x17, 0xda,
7394+ 0x18, 0x40,
7395+ 0x19, 0x80,
7396+ 0x1a, 0x00,
7397+ 0x1b, 0x42,
7398+ 0x1c, 0xa9,
7399+ 0x30, 0x66,
7400+ 0x31, 0x90,
7401+ 0x32, 0x01,
7402+ 0x34, 0x00,
7403+ 0x35, 0x00,
7404+ 0x36, 0x20,
7405+ 0x38, 0x03,
7406+ 0x39, 0x20,
7407+ 0x3a, 0x88,
7408+ 0x40, 0x00,
7409+ 0x41, 0xff,
7410+ 0x42, 0xff,
7411+ 0x43, 0xff,
7412+ 0x44, 0xff,
7413+ 0x45, 0xff,
7414+ 0x46, 0xff,
7415+ 0x47, 0xff,
7416+ 0x48, 0xff,
7417+ 0x49, 0xff,
7418+ 0x4a, 0xff,
7419+ 0x4b, 0xff,
7420+ 0x4c, 0xff,
7421+ 0x4d, 0xff,
7422+ 0x4e, 0xff,
7423+ 0x4f, 0xff,
7424+ 0x50, 0xff,
7425+ 0x51, 0xff,
7426+ 0x52, 0xff,
7427+ 0x53, 0xff,
7428+ 0x54, 0xf4 /*0xff*/,
7429+ 0x55, 0xff,
7430+ 0x56, 0xff,
7431+ 0x57, 0xff,
7432+ 0x58, 0x40,
7433+ 0x59, 0x47,
7434+ 0x5a, 0x06 /*0x03*/,
7435+ 0x5b, 0x83,
7436+ 0x5d, 0x06,
7437+ 0x5e, 0x00,
7438+ 0x80, 0x30, /* window defined scaler operation, task A and B enabled */
7439+ 0x81, 0x03, /* use scaler datapath generated V */
7440+ 0x83, 0x00,
7441+ 0x84, 0x00,
7442+ 0x85, 0x00,
7443+ 0x86, 0x45,
7444+ 0x87, 0x31,
7445+ 0x88, 0xc0,
7446+ 0x90, 0x02, /* task A process top field */
7447+ 0x91, 0x08,
7448+ 0x92, 0x09,
7449+ 0x93, 0x80,
7450+ 0x94, 0x06,
7451+ 0x95, 0x00,
7452+ 0x96, 0xc0,
7453+ 0x97, 0x02,
7454+ 0x98, 0x12,
7455+ 0x99, 0x00,
7456+ 0x9a, 0xf2,
7457+ 0x9b, 0x00,
7458+ 0x9c, 0xd0,
7459+ 0x9d, 0x02,
7460+ 0x9e, 0xf2,
7461+ 0x9f, 0x00,
7462+ 0xa0, 0x01,
7463+ 0xa1, 0x01,
7464+ 0xa2, 0x01,
7465+ 0xa4, 0x80,
7466+ 0xa5, 0x40,
7467+ 0xa6, 0x40,
7468+ 0xa8, 0x00,
7469+ 0xa9, 0x04,
7470+ 0xaa, 0x00,
7471+ 0xac, 0x00,
7472+ 0xad, 0x02,
7473+ 0xae, 0x00,
7474+ 0xb0, 0x00,
7475+ 0xb1, 0x04,
7476+ 0xb2, 0x00,
7477+ 0xb3, 0x04,
7478+ 0xb4, 0x00,
7479+ 0xb8, 0x00,
7480+ 0xbc, 0x00,
7481+ 0xc0, 0x03, /* task B process bottom field */
7482+ 0xc1, 0x08,
7483+ 0xc2, 0x09,
7484+ 0xc3, 0x80,
7485+ 0xc4, 0x06,
7486+ 0xc5, 0x00,
7487+ 0xc6, 0xc0,
7488+ 0xc7, 0x02,
7489+ 0xc8, 0x12,
7490+ 0xc9, 0x00,
7491+ 0xca, 0xf2,
7492+ 0xcb, 0x00,
7493+ 0xcc, 0xd0,
7494+ 0xcd, 0x02,
7495+ 0xce, 0xf2,
7496+ 0xcf, 0x00,
7497+ 0xd0, 0x01,
7498+ 0xd1, 0x01,
7499+ 0xd2, 0x01,
7500+ 0xd4, 0x80,
7501+ 0xd5, 0x40,
7502+ 0xd6, 0x40,
7503+ 0xd8, 0x00,
7504+ 0xd9, 0x04,
7505+ 0xda, 0x00,
7506+ 0xdc, 0x00,
7507+ 0xdd, 0x02,
7508+ 0xde, 0x00,
7509+ 0xe0, 0x00,
7510+ 0xe1, 0x04,
7511+ 0xe2, 0x00,
7512+ 0xe3, 0x04,
7513+ 0xe4, 0x00,
7514+ 0xe8, 0x00,
7515+ 0x88, 0xf0, /* End of original static list */
7516+ 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
7517+};
7518+
7519+static int write_reg(struct i2c_client *client, u8 reg, u8 value)
7520+{
7521+ return i2c_smbus_write_byte_data(client, reg, value);
7522+}
7523+
7524+static int write_regs(struct i2c_client *client, u8 *regs)
7525+{
7526+ int i;
7527+
7528+ for (i = 0; regs[i] != 0x00; i += 2)
7529+ if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
7530+ return -1;
7531+ return 0;
7532+}
7533+
7534+static int wis_saa7115_command(struct i2c_client *client,
7535+ unsigned int cmd, void *arg)
7536+{
7537+ struct wis_saa7115 *dec = i2c_get_clientdata(client);
7538+
7539+ switch (cmd) {
7540+ case DECODER_SET_INPUT:
7541+ {
7542+ int *input = arg;
7543+
7544+ i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
7545+ i2c_smbus_write_byte_data(client, 0x09,
7546+ *input < 6 ? 0x40 : 0xC0);
7547+ break;
7548+ }
7549+ case DECODER_SET_RESOLUTION:
7550+ {
7551+ struct video_decoder_resolution *res = arg;
7552+ /* Course-grained scaler */
7553+ int h_integer_scaler = res->width < 704 ? 704 / res->width : 1;
7554+ /* Fine-grained scaler to take care of remainder */
7555+ int h_scaling_increment = (704 / h_integer_scaler) *
7556+ 1024 / res->width;
7557+ /* Fine-grained scaler only */
7558+ int v_scaling_increment = (dec->norm == VIDEO_MODE_NTSC ?
7559+ 240 : 288) * 1024 / res->height;
7560+ u8 regs[] = {
7561+ 0x88, 0xc0,
7562+ 0x9c, res->width & 0xff,
7563+ 0x9d, res->width >> 8,
7564+ 0x9e, res->height & 0xff,
7565+ 0x9f, res->height >> 8,
7566+ 0xa0, h_integer_scaler,
7567+ 0xa1, 1,
7568+ 0xa2, 1,
7569+ 0xa8, h_scaling_increment & 0xff,
7570+ 0xa9, h_scaling_increment >> 8,
7571+ 0xac, (h_scaling_increment / 2) & 0xff,
7572+ 0xad, (h_scaling_increment / 2) >> 8,
7573+ 0xb0, v_scaling_increment & 0xff,
7574+ 0xb1, v_scaling_increment >> 8,
7575+ 0xb2, v_scaling_increment & 0xff,
7576+ 0xb3, v_scaling_increment >> 8,
7577+ 0xcc, res->width & 0xff,
7578+ 0xcd, res->width >> 8,
7579+ 0xce, res->height & 0xff,
7580+ 0xcf, res->height >> 8,
7581+ 0xd0, h_integer_scaler,
7582+ 0xd1, 1,
7583+ 0xd2, 1,
7584+ 0xd8, h_scaling_increment & 0xff,
7585+ 0xd9, h_scaling_increment >> 8,
7586+ 0xdc, (h_scaling_increment / 2) & 0xff,
7587+ 0xdd, (h_scaling_increment / 2) >> 8,
7588+ 0xe0, v_scaling_increment & 0xff,
7589+ 0xe1, v_scaling_increment >> 8,
7590+ 0xe2, v_scaling_increment & 0xff,
7591+ 0xe3, v_scaling_increment >> 8,
7592+ 0x88, 0xf0,
7593+ 0, 0,
7594+ };
7595+ write_regs(client, regs);
7596+ break;
7597+ }
7598+ case DECODER_SET_NORM:
7599+ {
7600+ int *input = arg;
7601+ u8 regs[] = {
7602+ 0x88, 0xc0,
7603+ 0x98, *input == VIDEO_MODE_NTSC ? 0x12 : 0x16,
7604+ 0x9a, *input == VIDEO_MODE_NTSC ? 0xf2 : 0x20,
7605+ 0x9b, *input == VIDEO_MODE_NTSC ? 0x00 : 0x01,
7606+ 0xc8, *input == VIDEO_MODE_NTSC ? 0x12 : 0x16,
7607+ 0xca, *input == VIDEO_MODE_NTSC ? 0xf2 : 0x20,
7608+ 0xcb, *input == VIDEO_MODE_NTSC ? 0x00 : 0x01,
7609+ 0x88, 0xf0,
7610+ 0x30, *input == VIDEO_MODE_NTSC ? 0x66 : 0x00,
7611+ 0x31, *input == VIDEO_MODE_NTSC ? 0x90 : 0xe0,
7612+ 0, 0,
7613+ };
7614+ write_regs(client, regs);
7615+ dec->norm = *input;
7616+ break;
7617+ }
7618+ case VIDIOC_QUERYCTRL:
7619+ {
7620+ struct v4l2_queryctrl *ctrl = arg;
7621+
7622+ switch (ctrl->id) {
7623+ case V4L2_CID_BRIGHTNESS:
7624+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
7625+ strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
7626+ ctrl->minimum = 0;
7627+ ctrl->maximum = 255;
7628+ ctrl->step = 1;
7629+ ctrl->default_value = 128;
7630+ ctrl->flags = 0;
7631+ break;
7632+ case V4L2_CID_CONTRAST:
7633+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
7634+ strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
7635+ ctrl->minimum = 0;
7636+ ctrl->maximum = 127;
7637+ ctrl->step = 1;
7638+ ctrl->default_value = 64;
7639+ ctrl->flags = 0;
7640+ break;
7641+ case V4L2_CID_SATURATION:
7642+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
7643+ strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
7644+ ctrl->minimum = 0;
7645+ ctrl->maximum = 127;
7646+ ctrl->step = 1;
7647+ ctrl->default_value = 64;
7648+ ctrl->flags = 0;
7649+ break;
7650+ case V4L2_CID_HUE:
7651+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
7652+ strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
7653+ ctrl->minimum = -128;
7654+ ctrl->maximum = 127;
7655+ ctrl->step = 1;
7656+ ctrl->default_value = 0;
7657+ ctrl->flags = 0;
7658+ break;
7659+ }
7660+ break;
7661+ }
7662+ case VIDIOC_S_CTRL:
7663+ {
7664+ struct v4l2_control *ctrl = arg;
7665+
7666+ switch (ctrl->id) {
7667+ case V4L2_CID_BRIGHTNESS:
7668+ if (ctrl->value > 255)
7669+ dec->brightness = 255;
7670+ else if (ctrl->value < 0)
7671+ dec->brightness = 0;
7672+ else
7673+ dec->brightness = ctrl->value;
7674+ write_reg(client, 0x0a, dec->brightness);
7675+ break;
7676+ case V4L2_CID_CONTRAST:
7677+ if (ctrl->value > 127)
7678+ dec->contrast = 127;
7679+ else if (ctrl->value < 0)
7680+ dec->contrast = 0;
7681+ else
7682+ dec->contrast = ctrl->value;
7683+ write_reg(client, 0x0b, dec->contrast);
7684+ break;
7685+ case V4L2_CID_SATURATION:
7686+ if (ctrl->value > 127)
7687+ dec->saturation = 127;
7688+ else if (ctrl->value < 0)
7689+ dec->saturation = 0;
7690+ else
7691+ dec->saturation = ctrl->value;
7692+ write_reg(client, 0x0c, dec->saturation);
7693+ break;
7694+ case V4L2_CID_HUE:
7695+ if (ctrl->value > 127)
7696+ dec->hue = 127;
7697+ else if (ctrl->value < -128)
7698+ dec->hue = -128;
7699+ else
7700+ dec->hue = ctrl->value;
7701+ write_reg(client, 0x0d, dec->hue);
7702+ break;
7703+ }
7704+ break;
7705+ }
7706+ case VIDIOC_G_CTRL:
7707+ {
7708+ struct v4l2_control *ctrl = arg;
7709+
7710+ switch (ctrl->id) {
7711+ case V4L2_CID_BRIGHTNESS:
7712+ ctrl->value = dec->brightness;
7713+ break;
7714+ case V4L2_CID_CONTRAST:
7715+ ctrl->value = dec->contrast;
7716+ break;
7717+ case V4L2_CID_SATURATION:
7718+ ctrl->value = dec->saturation;
7719+ break;
7720+ case V4L2_CID_HUE:
7721+ ctrl->value = dec->hue;
7722+ break;
7723+ }
7724+ break;
7725+ }
7726+ default:
7727+ break;
7728+ }
7729+ return 0;
7730+}
7731+
7732+static struct i2c_driver wis_saa7115_driver;
7733+
7734+static struct i2c_client wis_saa7115_client_templ = {
7735+ .name = "SAA7115 (WIS)",
7736+ .driver = &wis_saa7115_driver,
7737+};
7738+
7739+static int wis_saa7115_detect(struct i2c_adapter *adapter, int addr, int kind)
7740+{
7741+ struct i2c_client *client;
7742+ struct wis_saa7115 *dec;
7743+
7744+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
7745+ return 0;
7746+
7747+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
7748+ if (client == NULL)
7749+ return -ENOMEM;
7750+ memcpy(client, &wis_saa7115_client_templ,
7751+ sizeof(wis_saa7115_client_templ));
7752+ client->adapter = adapter;
7753+ client->addr = addr;
7754+
7755+ dec = kmalloc(sizeof(struct wis_saa7115), GFP_KERNEL);
7756+ if (dec == NULL) {
7757+ kfree(client);
7758+ return -ENOMEM;
7759+ }
7760+ dec->norm = VIDEO_MODE_NTSC;
7761+ dec->brightness = 128;
7762+ dec->contrast = 64;
7763+ dec->saturation = 64;
7764+ dec->hue = 0;
7765+ i2c_set_clientdata(client, dec);
7766+
7767+ printk(KERN_DEBUG
7768+ "wis-saa7115: initializing SAA7115 at address %d on %s\n",
7769+ addr, adapter->name);
7770+
7771+ if (write_regs(client, initial_registers) < 0) {
7772+ printk(KERN_ERR
7773+ "wis-saa7115: error initializing SAA7115\n");
7774+ kfree(client);
7775+ kfree(dec);
7776+ return 0;
7777+ }
7778+
7779+ i2c_attach_client(client);
7780+ return 0;
7781+}
7782+
7783+static int wis_saa7115_detach(struct i2c_client *client)
7784+{
7785+ struct wis_saa7115 *dec = i2c_get_clientdata(client);
7786+ int r;
7787+
7788+ r = i2c_detach_client(client);
7789+ if (r < 0)
7790+ return r;
7791+
7792+ kfree(client);
7793+ kfree(dec);
7794+ return 0;
7795+}
7796+
7797+static struct i2c_driver wis_saa7115_driver = {
7798+ .driver = {
7799+ .name = "WIS SAA7115 I2C driver",
7800+ },
7801+ .id = I2C_DRIVERID_WIS_SAA7115,
7802+ .detach_client = wis_saa7115_detach,
7803+ .command = wis_saa7115_command,
7804+};
7805+
7806+static int __init wis_saa7115_init(void)
7807+{
7808+ int r;
7809+
7810+ r = i2c_add_driver(&wis_saa7115_driver);
7811+ if (r < 0)
7812+ return r;
7813+ return wis_i2c_add_driver(wis_saa7115_driver.id, wis_saa7115_detect);
7814+}
7815+
7816+static void __exit wis_saa7115_cleanup(void)
7817+{
7818+ wis_i2c_del_driver(wis_saa7115_detect);
7819+ i2c_del_driver(&wis_saa7115_driver);
7820+}
7821+
7822+module_init(wis_saa7115_init);
7823+module_exit(wis_saa7115_cleanup);
7824+
7825+MODULE_LICENSE("GPL v2");
7826diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c
7827new file mode 100644
7828index 0000000..82e66d6
7829--- /dev/null
7830+++ b/drivers/staging/go7007/wis-sony-tuner.c
7831@@ -0,0 +1,741 @@
7832+/*
7833+ * Copyright (C) 2005-2006 Micronas USA Inc.
7834+ *
7835+ * This program is free software; you can redistribute it and/or modify
7836+ * it under the terms of the GNU General Public License (Version 2) as
7837+ * published by the Free Software Foundation.
7838+ *
7839+ * This program is distributed in the hope that it will be useful,
7840+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7841+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7842+ * GNU General Public License for more details.
7843+ *
7844+ * You should have received a copy of the GNU General Public License
7845+ * along with this program; if not, write to the Free Software Foundation,
7846+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
7847+ */
7848+
7849+#include <linux/module.h>
7850+#include <linux/init.h>
7851+#include <linux/version.h>
7852+#include <linux/i2c.h>
7853+#include <linux/videodev.h>
7854+#include <media/tuner.h>
7855+#include <media/v4l2-common.h>
7856+
7857+#include "wis-i2c.h"
7858+
7859+/* #define MPX_DEBUG */
7860+
7861+/* AS(IF/MPX) pin: LOW HIGH/OPEN
7862+ * IF/MPX address: 0x42/0x40 0x43/0x44
7863+ */
7864+#define IF_I2C_ADDR 0x43
7865+#define MPX_I2C_ADDR 0x44
7866+
7867+static v4l2_std_id force_band;
7868+static char force_band_str[] = "-";
7869+module_param_string(force_band, force_band_str, sizeof(force_band_str), 0644);
7870+static int force_mpx_mode = -1;
7871+module_param(force_mpx_mode, int, 0644);
7872+
7873+/* Store tuner info in the same format as tuner.c, so maybe we can put the
7874+ * Sony tuner support in there. */
7875+struct sony_tunertype {
7876+ char *name;
7877+ unsigned char Vendor; /* unused here */
7878+ unsigned char Type; /* unused here */
7879+
7880+ unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */
7881+ unsigned short thresh2; /* band switch VHF_HI <=> UHF */
7882+ unsigned char VHF_L;
7883+ unsigned char VHF_H;
7884+ unsigned char UHF;
7885+ unsigned char config;
7886+ unsigned short IFPCoff;
7887+};
7888+
7889+/* This array is indexed by (tuner_type - 200) */
7890+static struct sony_tunertype sony_tuners[] = {
7891+ { "Sony PAL+SECAM (BTF-PG472Z)", 0, 0,
7892+ 16*144.25, 16*427.25, 0x01, 0x02, 0x04, 0xc6, 623},
7893+ { "Sony NTSC_JP (BTF-PK467Z)", 0, 0,
7894+ 16*220.25, 16*467.25, 0x01, 0x02, 0x04, 0xc6, 940},
7895+ { "Sony NTSC (BTF-PB463Z)", 0, 0,
7896+ 16*130.25, 16*364.25, 0x01, 0x02, 0x04, 0xc6, 732},
7897+};
7898+
7899+struct wis_sony_tuner {
7900+ int type;
7901+ v4l2_std_id std;
7902+ unsigned int freq;
7903+ int mpxmode;
7904+ u32 audmode;
7905+};
7906+
7907+/* Basically the same as default_set_tv_freq() in tuner.c */
7908+static int set_freq(struct i2c_client *client, int freq)
7909+{
7910+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
7911+ char *band_name;
7912+ int n;
7913+ int band_select;
7914+ struct sony_tunertype *tun;
7915+ u8 buffer[4];
7916+
7917+ tun = &sony_tuners[t->type - 200];
7918+ if (freq < tun->thresh1) {
7919+ band_name = "VHF_L";
7920+ band_select = tun->VHF_L;
7921+ } else if (freq < tun->thresh2) {
7922+ band_name = "VHF_H";
7923+ band_select = tun->VHF_H;
7924+ } else {
7925+ band_name = "UHF";
7926+ band_select = tun->UHF;
7927+ }
7928+ printk(KERN_DEBUG "wis-sony-tuner: tuning to frequency %d.%04d (%s)\n",
7929+ freq / 16, (freq % 16) * 625, band_name);
7930+ n = freq + tun->IFPCoff;
7931+
7932+ buffer[0] = n >> 8;
7933+ buffer[1] = n & 0xff;
7934+ buffer[2] = tun->config;
7935+ buffer[3] = band_select;
7936+ i2c_master_send(client, buffer, 4);
7937+
7938+ return 0;
7939+}
7940+
7941+static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
7942+{
7943+ u8 buffer[5];
7944+ struct i2c_msg msg;
7945+
7946+ buffer[0] = dev;
7947+ buffer[1] = addr >> 8;
7948+ buffer[2] = addr & 0xff;
7949+ buffer[3] = val >> 8;
7950+ buffer[4] = val & 0xff;
7951+ msg.addr = MPX_I2C_ADDR;
7952+ msg.flags = 0;
7953+ msg.len = 5;
7954+ msg.buf = buffer;
7955+ i2c_transfer(client->adapter, &msg, 1);
7956+ return 0;
7957+}
7958+
7959+/*
7960+ * MPX register values for the BTF-PG472Z:
7961+ *
7962+ * FM_ NICAM_ SCART_
7963+ * MODUS SOURCE ACB PRESCAL PRESCAL PRESCAL SYSTEM VOLUME
7964+ * 10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000
7965+ * ---------------------------------------------------------------
7966+ * Auto 1003 0020 0100 2603 5000 XXXX 0001 7500
7967+ *
7968+ * B/G
7969+ * Mono 1003 0020 0100 2603 5000 XXXX 0003 7500
7970+ * A2 1003 0020 0100 2601 5000 XXXX 0003 7500
7971+ * NICAM 1003 0120 0100 2603 5000 XXXX 0008 7500
7972+ *
7973+ * I
7974+ * Mono 1003 0020 0100 2603 7900 XXXX 000A 7500
7975+ * NICAM 1003 0120 0100 2603 7900 XXXX 000A 7500
7976+ *
7977+ * D/K
7978+ * Mono 1003 0020 0100 2603 5000 XXXX 0004 7500
7979+ * A2-1 1003 0020 0100 2601 5000 XXXX 0004 7500
7980+ * A2-2 1003 0020 0100 2601 5000 XXXX 0005 7500
7981+ * A2-3 1003 0020 0100 2601 5000 XXXX 0007 7500
7982+ * NICAM 1003 0120 0100 2603 5000 XXXX 000B 7500
7983+ *
7984+ * L/L'
7985+ * Mono 0003 0200 0100 7C03 5000 2200 0009 7500
7986+ * NICAM 0003 0120 0100 7C03 5000 XXXX 0009 7500
7987+ *
7988+ * M
7989+ * Mono 1003 0200 0100 2B03 5000 2B00 0002 7500
7990+ *
7991+ * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX.
7992+ *
7993+ * Bilingual selection in A2/NICAM:
7994+ *
7995+ * High byte of SOURCE Left chan Right chan
7996+ * 0x01 MAIN SUB
7997+ * 0x03 MAIN MAIN
7998+ * 0x04 SUB SUB
7999+ *
8000+ * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or
8001+ * 0x00 (all other bands). Force mono in A2 with FMONO_A2:
8002+ *
8003+ * FMONO_A2
8004+ * 10/0022
8005+ * --------
8006+ * Forced mono ON 07F0
8007+ * Forced mono OFF 0190
8008+ */
8009+
8010+static struct {
8011+ enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
8012+ u16 modus;
8013+ u16 source;
8014+ u16 acb;
8015+ u16 fm_prescale;
8016+ u16 nicam_prescale;
8017+ u16 scart_prescale;
8018+ u16 system;
8019+ u16 volume;
8020+} mpx_audio_modes[] = {
8021+ /* Auto */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
8022+ 0x5000, 0x0000, 0x0001, 0x7500 },
8023+ /* B/G Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
8024+ 0x5000, 0x0000, 0x0003, 0x7500 },
8025+ /* B/G A2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
8026+ 0x5000, 0x0000, 0x0003, 0x7500 },
8027+ /* B/G NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
8028+ 0x5000, 0x0000, 0x0008, 0x7500 },
8029+ /* I Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
8030+ 0x7900, 0x0000, 0x000A, 0x7500 },
8031+ /* I NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
8032+ 0x7900, 0x0000, 0x000A, 0x7500 },
8033+ /* D/K Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
8034+ 0x5000, 0x0000, 0x0004, 0x7500 },
8035+ /* D/K A2-1 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
8036+ 0x5000, 0x0000, 0x0004, 0x7500 },
8037+ /* D/K A2-2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
8038+ 0x5000, 0x0000, 0x0005, 0x7500 },
8039+ /* D/K A2-3 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
8040+ 0x5000, 0x0000, 0x0007, 0x7500 },
8041+ /* D/K NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
8042+ 0x5000, 0x0000, 0x000B, 0x7500 },
8043+ /* L/L' Mono */ { AUD_MONO, 0x0003, 0x0200, 0x0100, 0x7C03,
8044+ 0x5000, 0x2200, 0x0009, 0x7500 },
8045+ /* L/L' NICAM */{ AUD_NICAM_L, 0x0003, 0x0120, 0x0100, 0x7C03,
8046+ 0x5000, 0x0000, 0x0009, 0x7500 },
8047+};
8048+
8049+#define MPX_NUM_MODES ARRAY_SIZE(mpx_audio_modes)
8050+
8051+static int mpx_setup(struct i2c_client *client)
8052+{
8053+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
8054+ u16 source = 0;
8055+ u8 buffer[3];
8056+ struct i2c_msg msg;
8057+
8058+ /* reset MPX */
8059+ buffer[0] = 0x00;
8060+ buffer[1] = 0x80;
8061+ buffer[2] = 0x00;
8062+ msg.addr = MPX_I2C_ADDR;
8063+ msg.flags = 0;
8064+ msg.len = 3;
8065+ msg.buf = buffer;
8066+ i2c_transfer(client->adapter, &msg, 1);
8067+ buffer[1] = 0x00;
8068+ i2c_transfer(client->adapter, &msg, 1);
8069+
8070+ if (mpx_audio_modes[t->mpxmode].audio_mode != AUD_MONO) {
8071+ switch (t->audmode) {
8072+ case V4L2_TUNER_MODE_MONO:
8073+ switch (mpx_audio_modes[t->mpxmode].audio_mode) {
8074+ case AUD_A2:
8075+ source = mpx_audio_modes[t->mpxmode].source;
8076+ break;
8077+ case AUD_NICAM:
8078+ source = 0x0000;
8079+ break;
8080+ case AUD_NICAM_L:
8081+ source = 0x0200;
8082+ break;
8083+ default:
8084+ break;
8085+ }
8086+ break;
8087+ case V4L2_TUNER_MODE_STEREO:
8088+ source = mpx_audio_modes[t->mpxmode].source;
8089+ break;
8090+ case V4L2_TUNER_MODE_LANG1:
8091+ source = 0x0300;
8092+ break;
8093+ case V4L2_TUNER_MODE_LANG2:
8094+ source = 0x0400;
8095+ break;
8096+ }
8097+ source |= mpx_audio_modes[t->mpxmode].source & 0x00ff;
8098+ } else
8099+ source = mpx_audio_modes[t->mpxmode].source;
8100+
8101+ mpx_write(client, 0x10, 0x0030, mpx_audio_modes[t->mpxmode].modus);
8102+ mpx_write(client, 0x12, 0x0008, source);
8103+ mpx_write(client, 0x12, 0x0013, mpx_audio_modes[t->mpxmode].acb);
8104+ mpx_write(client, 0x12, 0x000e,
8105+ mpx_audio_modes[t->mpxmode].fm_prescale);
8106+ mpx_write(client, 0x12, 0x0010,
8107+ mpx_audio_modes[t->mpxmode].nicam_prescale);
8108+ mpx_write(client, 0x12, 0x000d,
8109+ mpx_audio_modes[t->mpxmode].scart_prescale);
8110+ mpx_write(client, 0x10, 0x0020, mpx_audio_modes[t->mpxmode].system);
8111+ mpx_write(client, 0x12, 0x0000, mpx_audio_modes[t->mpxmode].volume);
8112+ if (mpx_audio_modes[t->mpxmode].audio_mode == AUD_A2)
8113+ mpx_write(client, 0x10, 0x0022,
8114+ t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190);
8115+
8116+#ifdef MPX_DEBUG
8117+ {
8118+ u8 buf1[3], buf2[2];
8119+ struct i2c_msg msgs[2];
8120+
8121+ printk(KERN_DEBUG "wis-sony-tuner: MPX registers: %04x %04x "
8122+ "%04x %04x %04x %04x %04x %04x\n",
8123+ mpx_audio_modes[t->mpxmode].modus,
8124+ source,
8125+ mpx_audio_modes[t->mpxmode].acb,
8126+ mpx_audio_modes[t->mpxmode].fm_prescale,
8127+ mpx_audio_modes[t->mpxmode].nicam_prescale,
8128+ mpx_audio_modes[t->mpxmode].scart_prescale,
8129+ mpx_audio_modes[t->mpxmode].system,
8130+ mpx_audio_modes[t->mpxmode].volume);
8131+ buf1[0] = 0x11;
8132+ buf1[1] = 0x00;
8133+ buf1[2] = 0x7e;
8134+ msgs[0].addr = MPX_I2C_ADDR;
8135+ msgs[0].flags = 0;
8136+ msgs[0].len = 3;
8137+ msgs[0].buf = buf1;
8138+ msgs[1].addr = MPX_I2C_ADDR;
8139+ msgs[1].flags = I2C_M_RD;
8140+ msgs[1].len = 2;
8141+ msgs[1].buf = buf2;
8142+ i2c_transfer(client->adapter, msgs, 2);
8143+ printk(KERN_DEBUG "wis-sony-tuner: MPX system: %02x%02x\n",
8144+ buf2[0], buf2[1]);
8145+ buf1[0] = 0x11;
8146+ buf1[1] = 0x02;
8147+ buf1[2] = 0x00;
8148+ i2c_transfer(client->adapter, msgs, 2);
8149+ printk(KERN_DEBUG "wis-sony-tuner: MPX status: %02x%02x\n",
8150+ buf2[0], buf2[1]);
8151+ }
8152+#endif
8153+ return 0;
8154+}
8155+
8156+/*
8157+ * IF configuration values for the BTF-PG472Z:
8158+ *
8159+ * B/G: 0x94 0x70 0x49
8160+ * I: 0x14 0x70 0x4a
8161+ * D/K: 0x14 0x70 0x4b
8162+ * L: 0x04 0x70 0x4b
8163+ * L': 0x44 0x70 0x53
8164+ * M: 0x50 0x30 0x4c
8165+ */
8166+
8167+static int set_if(struct i2c_client *client)
8168+{
8169+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
8170+ u8 buffer[4];
8171+ struct i2c_msg msg;
8172+ int default_mpx_mode = 0;
8173+
8174+ /* configure IF */
8175+ buffer[0] = 0;
8176+ if (t->std & V4L2_STD_PAL_BG) {
8177+ buffer[1] = 0x94;
8178+ buffer[2] = 0x70;
8179+ buffer[3] = 0x49;
8180+ default_mpx_mode = 1;
8181+ } else if (t->std & V4L2_STD_PAL_I) {
8182+ buffer[1] = 0x14;
8183+ buffer[2] = 0x70;
8184+ buffer[3] = 0x4a;
8185+ default_mpx_mode = 4;
8186+ } else if (t->std & V4L2_STD_PAL_DK) {
8187+ buffer[1] = 0x14;
8188+ buffer[2] = 0x70;
8189+ buffer[3] = 0x4b;
8190+ default_mpx_mode = 6;
8191+ } else if (t->std & V4L2_STD_SECAM_L) {
8192+ buffer[1] = 0x04;
8193+ buffer[2] = 0x70;
8194+ buffer[3] = 0x4b;
8195+ default_mpx_mode = 11;
8196+ }
8197+ msg.addr = IF_I2C_ADDR;
8198+ msg.flags = 0;
8199+ msg.len = 4;
8200+ msg.buf = buffer;
8201+ i2c_transfer(client->adapter, &msg, 1);
8202+
8203+ /* Select MPX mode if not forced by the user */
8204+ if (force_mpx_mode >= 0 || force_mpx_mode < MPX_NUM_MODES)
8205+ t->mpxmode = force_mpx_mode;
8206+ else
8207+ t->mpxmode = default_mpx_mode;
8208+ printk(KERN_DEBUG "wis-sony-tuner: setting MPX to mode %d\n",
8209+ t->mpxmode);
8210+ mpx_setup(client);
8211+
8212+ return 0;
8213+}
8214+
8215+static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
8216+{
8217+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
8218+
8219+ switch (cmd) {
8220+#ifdef TUNER_SET_TYPE_ADDR
8221+ case TUNER_SET_TYPE_ADDR:
8222+ {
8223+ struct tuner_setup *tun_setup = arg;
8224+ int *type = &tun_setup->type;
8225+#else
8226+ case TUNER_SET_TYPE:
8227+ {
8228+ int *type = arg;
8229+#endif
8230+
8231+ if (t->type >= 0) {
8232+ if (t->type != *type)
8233+ printk(KERN_ERR "wis-sony-tuner: type already "
8234+ "set to %d, ignoring request for %d\n",
8235+ t->type, *type);
8236+ break;
8237+ }
8238+ t->type = *type;
8239+ switch (t->type) {
8240+ case TUNER_SONY_BTF_PG472Z:
8241+ switch (force_band_str[0]) {
8242+ case 'b':
8243+ case 'B':
8244+ case 'g':
8245+ case 'G':
8246+ printk(KERN_INFO "wis-sony-tuner: forcing "
8247+ "tuner to PAL-B/G bands\n");
8248+ force_band = V4L2_STD_PAL_BG;
8249+ break;
8250+ case 'i':
8251+ case 'I':
8252+ printk(KERN_INFO "wis-sony-tuner: forcing "
8253+ "tuner to PAL-I band\n");
8254+ force_band = V4L2_STD_PAL_I;
8255+ break;
8256+ case 'd':
8257+ case 'D':
8258+ case 'k':
8259+ case 'K':
8260+ printk(KERN_INFO "wis-sony-tuner: forcing "
8261+ "tuner to PAL-D/K bands\n");
8262+ force_band = V4L2_STD_PAL_I;
8263+ break;
8264+ case 'l':
8265+ case 'L':
8266+ printk(KERN_INFO "wis-sony-tuner: forcing "
8267+ "tuner to SECAM-L band\n");
8268+ force_band = V4L2_STD_SECAM_L;
8269+ break;
8270+ default:
8271+ force_band = 0;
8272+ break;
8273+ }
8274+ if (force_band)
8275+ t->std = force_band;
8276+ else
8277+ t->std = V4L2_STD_PAL_BG;
8278+ set_if(client);
8279+ break;
8280+ case TUNER_SONY_BTF_PK467Z:
8281+ t->std = V4L2_STD_NTSC_M_JP;
8282+ break;
8283+ case TUNER_SONY_BTF_PB463Z:
8284+ t->std = V4L2_STD_NTSC_M;
8285+ break;
8286+ default:
8287+ printk(KERN_ERR "wis-sony-tuner: tuner type %d is not "
8288+ "supported by this module\n", *type);
8289+ break;
8290+ }
8291+ if (type >= 0)
8292+ printk(KERN_INFO
8293+ "wis-sony-tuner: type set to %d (%s)\n",
8294+ t->type, sony_tuners[t->type - 200].name);
8295+ break;
8296+ }
8297+ case VIDIOC_G_FREQUENCY:
8298+ {
8299+ struct v4l2_frequency *f = arg;
8300+
8301+ f->frequency = t->freq;
8302+ break;
8303+ }
8304+ case VIDIOC_S_FREQUENCY:
8305+ {
8306+ struct v4l2_frequency *f = arg;
8307+
8308+ t->freq = f->frequency;
8309+ set_freq(client, t->freq);
8310+ break;
8311+ }
8312+ case VIDIOC_ENUMSTD:
8313+ {
8314+ struct v4l2_standard *std = arg;
8315+
8316+ switch (t->type) {
8317+ case TUNER_SONY_BTF_PG472Z:
8318+ switch (std->index) {
8319+ case 0:
8320+ v4l2_video_std_construct(std,
8321+ V4L2_STD_PAL_BG, "PAL-B/G");
8322+ break;
8323+ case 1:
8324+ v4l2_video_std_construct(std,
8325+ V4L2_STD_PAL_I, "PAL-I");
8326+ break;
8327+ case 2:
8328+ v4l2_video_std_construct(std,
8329+ V4L2_STD_PAL_DK, "PAL-D/K");
8330+ break;
8331+ case 3:
8332+ v4l2_video_std_construct(std,
8333+ V4L2_STD_SECAM_L, "SECAM-L");
8334+ break;
8335+ default:
8336+ std->id = 0; /* hack to indicate EINVAL */
8337+ break;
8338+ }
8339+ break;
8340+ case TUNER_SONY_BTF_PK467Z:
8341+ if (std->index != 0) {
8342+ std->id = 0; /* hack to indicate EINVAL */
8343+ break;
8344+ }
8345+ v4l2_video_std_construct(std,
8346+ V4L2_STD_NTSC_M_JP, "NTSC-J");
8347+ break;
8348+ case TUNER_SONY_BTF_PB463Z:
8349+ if (std->index != 0) {
8350+ std->id = 0; /* hack to indicate EINVAL */
8351+ break;
8352+ }
8353+ v4l2_video_std_construct(std, V4L2_STD_NTSC_M, "NTSC");
8354+ break;
8355+ }
8356+ break;
8357+ }
8358+ case VIDIOC_G_STD:
8359+ {
8360+ v4l2_std_id *std = arg;
8361+
8362+ *std = t->std;
8363+ break;
8364+ }
8365+ case VIDIOC_S_STD:
8366+ {
8367+ v4l2_std_id *std = arg;
8368+ v4l2_std_id old = t->std;
8369+
8370+ switch (t->type) {
8371+ case TUNER_SONY_BTF_PG472Z:
8372+ if (force_band && (*std & force_band) != *std &&
8373+ *std != V4L2_STD_PAL &&
8374+ *std != V4L2_STD_SECAM) {
8375+ printk(KERN_DEBUG "wis-sony-tuner: ignoring "
8376+ "requested TV standard in "
8377+ "favor of force_band value\n");
8378+ t->std = force_band;
8379+ } else if (*std & V4L2_STD_PAL_BG) { /* default */
8380+ t->std = V4L2_STD_PAL_BG;
8381+ } else if (*std & V4L2_STD_PAL_I) {
8382+ t->std = V4L2_STD_PAL_I;
8383+ } else if (*std & V4L2_STD_PAL_DK) {
8384+ t->std = V4L2_STD_PAL_DK;
8385+ } else if (*std & V4L2_STD_SECAM_L) {
8386+ t->std = V4L2_STD_SECAM_L;
8387+ } else {
8388+ printk(KERN_ERR "wis-sony-tuner: TV standard "
8389+ "not supported\n");
8390+ *std = 0; /* hack to indicate EINVAL */
8391+ break;
8392+ }
8393+ if (old != t->std)
8394+ set_if(client);
8395+ break;
8396+ case TUNER_SONY_BTF_PK467Z:
8397+ if (!(*std & V4L2_STD_NTSC_M_JP)) {
8398+ printk(KERN_ERR "wis-sony-tuner: TV standard "
8399+ "not supported\n");
8400+ *std = 0; /* hack to indicate EINVAL */
8401+ }
8402+ break;
8403+ case TUNER_SONY_BTF_PB463Z:
8404+ if (!(*std & V4L2_STD_NTSC_M)) {
8405+ printk(KERN_ERR "wis-sony-tuner: TV standard "
8406+ "not supported\n");
8407+ *std = 0; /* hack to indicate EINVAL */
8408+ }
8409+ break;
8410+ }
8411+ break;
8412+ }
8413+ case VIDIOC_QUERYSTD:
8414+ {
8415+ v4l2_std_id *std = arg;
8416+
8417+ switch (t->type) {
8418+ case TUNER_SONY_BTF_PG472Z:
8419+ if (force_band)
8420+ *std = force_band;
8421+ else
8422+ *std = V4L2_STD_PAL_BG | V4L2_STD_PAL_I |
8423+ V4L2_STD_PAL_DK | V4L2_STD_SECAM_L;
8424+ break;
8425+ case TUNER_SONY_BTF_PK467Z:
8426+ *std = V4L2_STD_NTSC_M_JP;
8427+ break;
8428+ case TUNER_SONY_BTF_PB463Z:
8429+ *std = V4L2_STD_NTSC_M;
8430+ break;
8431+ }
8432+ break;
8433+ }
8434+ case VIDIOC_G_TUNER:
8435+ {
8436+ struct v4l2_tuner *tun = arg;
8437+
8438+ memset(t, 0, sizeof(*tun));
8439+ strcpy(tun->name, "Television");
8440+ tun->type = V4L2_TUNER_ANALOG_TV;
8441+ tun->rangelow = 0UL; /* does anything use these? */
8442+ tun->rangehigh = 0xffffffffUL;
8443+ switch (t->type) {
8444+ case TUNER_SONY_BTF_PG472Z:
8445+ tun->capability = V4L2_TUNER_CAP_NORM |
8446+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
8447+ V4L2_TUNER_CAP_LANG2;
8448+ tun->rxsubchans = V4L2_TUNER_SUB_MONO |
8449+ V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
8450+ V4L2_TUNER_SUB_LANG2;
8451+ break;
8452+ case TUNER_SONY_BTF_PK467Z:
8453+ case TUNER_SONY_BTF_PB463Z:
8454+ tun->capability = V4L2_TUNER_CAP_STEREO;
8455+ tun->rxsubchans = V4L2_TUNER_SUB_MONO |
8456+ V4L2_TUNER_SUB_STEREO;
8457+ break;
8458+ }
8459+ tun->audmode = t->audmode;
8460+ return 0;
8461+ }
8462+ case VIDIOC_S_TUNER:
8463+ {
8464+ struct v4l2_tuner *tun = arg;
8465+
8466+ switch (t->type) {
8467+ case TUNER_SONY_BTF_PG472Z:
8468+ if (tun->audmode != t->audmode) {
8469+ t->audmode = tun->audmode;
8470+ mpx_setup(client);
8471+ }
8472+ break;
8473+ case TUNER_SONY_BTF_PK467Z:
8474+ case TUNER_SONY_BTF_PB463Z:
8475+ break;
8476+ }
8477+ return 0;
8478+ }
8479+ default:
8480+ break;
8481+ }
8482+ return 0;
8483+}
8484+
8485+static struct i2c_driver wis_sony_tuner_driver;
8486+
8487+static struct i2c_client wis_sony_tuner_client_templ = {
8488+ .name = "Sony TV Tuner (WIS)",
8489+ .driver = &wis_sony_tuner_driver,
8490+};
8491+
8492+static int wis_sony_tuner_detect(struct i2c_adapter *adapter,
8493+ int addr, int kind)
8494+{
8495+ struct i2c_client *client;
8496+ struct wis_sony_tuner *t;
8497+
8498+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
8499+ return 0;
8500+
8501+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
8502+ if (client == NULL)
8503+ return -ENOMEM;
8504+ memcpy(client, &wis_sony_tuner_client_templ,
8505+ sizeof(wis_sony_tuner_client_templ));
8506+ client->adapter = adapter;
8507+ client->addr = addr;
8508+
8509+ t = kmalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL);
8510+ if (t == NULL) {
8511+ kfree(client);
8512+ return -ENOMEM;
8513+ }
8514+ t->type = -1;
8515+ t->freq = 0;
8516+ t->mpxmode = 0;
8517+ t->audmode = V4L2_TUNER_MODE_STEREO;
8518+ i2c_set_clientdata(client, t);
8519+
8520+ printk(KERN_DEBUG
8521+ "wis-sony-tuner: initializing tuner at address %d on %s\n",
8522+ addr, adapter->name);
8523+
8524+ i2c_attach_client(client);
8525+
8526+ return 0;
8527+}
8528+
8529+static int wis_sony_tuner_detach(struct i2c_client *client)
8530+{
8531+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
8532+ int r;
8533+
8534+ r = i2c_detach_client(client);
8535+ if (r < 0)
8536+ return r;
8537+
8538+ kfree(t);
8539+ kfree(client);
8540+ return 0;
8541+}
8542+
8543+static struct i2c_driver wis_sony_tuner_driver = {
8544+ .driver = {
8545+ .name = "WIS Sony TV Tuner I2C driver",
8546+ },
8547+ .id = I2C_DRIVERID_WIS_SONY_TUNER,
8548+ .detach_client = wis_sony_tuner_detach,
8549+ .command = tuner_command,
8550+};
8551+
8552+static int __init wis_sony_tuner_init(void)
8553+{
8554+ int r;
8555+
8556+ r = i2c_add_driver(&wis_sony_tuner_driver);
8557+ if (r < 0)
8558+ return r;
8559+ return wis_i2c_add_driver(wis_sony_tuner_driver.id,
8560+ wis_sony_tuner_detect);
8561+}
8562+
8563+static void __exit wis_sony_tuner_cleanup(void)
8564+{
8565+ wis_i2c_del_driver(wis_sony_tuner_detect);
8566+ i2c_del_driver(&wis_sony_tuner_driver);
8567+}
8568+
8569+module_init(wis_sony_tuner_init);
8570+module_exit(wis_sony_tuner_cleanup);
8571+
8572+MODULE_LICENSE("GPL v2");
8573diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c
8574new file mode 100644
8575index 0000000..69ed7bf
8576--- /dev/null
8577+++ b/drivers/staging/go7007/wis-tw2804.c
8578@@ -0,0 +1,381 @@
8579+/*
8580+ * Copyright (C) 2005-2006 Micronas USA Inc.
8581+ *
8582+ * This program is free software; you can redistribute it and/or modify
8583+ * it under the terms of the GNU General Public License (Version 2) as
8584+ * published by the Free Software Foundation.
8585+ *
8586+ * This program is distributed in the hope that it will be useful,
8587+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8588+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8589+ * GNU General Public License for more details.
8590+ *
8591+ * You should have received a copy of the GNU General Public License
8592+ * along with this program; if not, write to the Free Software Foundation,
8593+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
8594+ */
8595+
8596+#include <linux/module.h>
8597+#include <linux/init.h>
8598+#include <linux/version.h>
8599+#include <linux/i2c.h>
8600+#include <linux/videodev.h>
8601+#include <linux/video_decoder.h>
8602+#include <linux/ioctl.h>
8603+
8604+#include "wis-i2c.h"
8605+
8606+struct wis_tw2804 {
8607+ int channel;
8608+ int norm;
8609+ int brightness;
8610+ int contrast;
8611+ int saturation;
8612+ int hue;
8613+};
8614+
8615+static u8 global_registers[] =
8616+{
8617+ 0x39, 0x00,
8618+ 0x3a, 0xff,
8619+ 0x3b, 0x84,
8620+ 0x3c, 0x80,
8621+ 0x3d, 0x80,
8622+ 0x3e, 0x82,
8623+ 0x3f, 0x82,
8624+ 0xff, 0xff, /* Terminator (reg 0xff does not exist) */
8625+};
8626+
8627+static u8 channel_registers[] =
8628+{
8629+ 0x01, 0xc4,
8630+ 0x02, 0xa5,
8631+ 0x03, 0x20,
8632+ 0x04, 0xd0,
8633+ 0x05, 0x20,
8634+ 0x06, 0xd0,
8635+ 0x07, 0x88,
8636+ 0x08, 0x20,
8637+ 0x09, 0x07,
8638+ 0x0a, 0xf0,
8639+ 0x0b, 0x07,
8640+ 0x0c, 0xf0,
8641+ 0x0d, 0x40,
8642+ 0x0e, 0xd2,
8643+ 0x0f, 0x80,
8644+ 0x10, 0x80,
8645+ 0x11, 0x80,
8646+ 0x12, 0x80,
8647+ 0x13, 0x1f,
8648+ 0x14, 0x00,
8649+ 0x15, 0x00,
8650+ 0x16, 0x00,
8651+ 0x17, 0x00,
8652+ 0x18, 0xff,
8653+ 0x19, 0xff,
8654+ 0x1a, 0xff,
8655+ 0x1b, 0xff,
8656+ 0x1c, 0xff,
8657+ 0x1d, 0xff,
8658+ 0x1e, 0xff,
8659+ 0x1f, 0xff,
8660+ 0x20, 0x07,
8661+ 0x21, 0x07,
8662+ 0x22, 0x00,
8663+ 0x23, 0x91,
8664+ 0x24, 0x51,
8665+ 0x25, 0x03,
8666+ 0x26, 0x00,
8667+ 0x27, 0x00,
8668+ 0x28, 0x00,
8669+ 0x29, 0x00,
8670+ 0x2a, 0x00,
8671+ 0x2b, 0x00,
8672+ 0x2c, 0x00,
8673+ 0x2d, 0x00,
8674+ 0x2e, 0x00,
8675+ 0x2f, 0x00,
8676+ 0x30, 0x00,
8677+ 0x31, 0x00,
8678+ 0x32, 0x00,
8679+ 0x33, 0x00,
8680+ 0x34, 0x00,
8681+ 0x35, 0x00,
8682+ 0x36, 0x00,
8683+ 0x37, 0x00,
8684+ 0xff, 0xff, /* Terminator (reg 0xff does not exist) */
8685+};
8686+
8687+static int write_reg(struct i2c_client *client, u8 reg, u8 value, int channel)
8688+{
8689+ return i2c_smbus_write_byte_data(client, reg | (channel << 6), value);
8690+}
8691+
8692+static int write_regs(struct i2c_client *client, u8 *regs, int channel)
8693+{
8694+ int i;
8695+
8696+ for (i = 0; regs[i] != 0xff; i += 2)
8697+ if (i2c_smbus_write_byte_data(client,
8698+ regs[i] | (channel << 6), regs[i + 1]) < 0)
8699+ return -1;
8700+ return 0;
8701+}
8702+
8703+static int wis_tw2804_command(struct i2c_client *client,
8704+ unsigned int cmd, void *arg)
8705+{
8706+ struct wis_tw2804 *dec = i2c_get_clientdata(client);
8707+
8708+ if (cmd == DECODER_SET_CHANNEL) {
8709+ int *input = arg;
8710+
8711+ if (*input < 0 || *input > 3) {
8712+ printk(KERN_ERR "wis-tw2804: channel %d is not "
8713+ "between 0 and 3!\n", *input);
8714+ return 0;
8715+ }
8716+ dec->channel = *input;
8717+ printk(KERN_DEBUG "wis-tw2804: initializing TW2804 "
8718+ "channel %d\n", dec->channel);
8719+ if (dec->channel == 0 &&
8720+ write_regs(client, global_registers, 0) < 0) {
8721+ printk(KERN_ERR "wis-tw2804: error initializing "
8722+ "TW2804 global registers\n");
8723+ return 0;
8724+ }
8725+ if (write_regs(client, channel_registers, dec->channel) < 0) {
8726+ printk(KERN_ERR "wis-tw2804: error initializing "
8727+ "TW2804 channel %d\n", dec->channel);
8728+ return 0;
8729+ }
8730+ return 0;
8731+ }
8732+
8733+ if (dec->channel < 0) {
8734+ printk(KERN_DEBUG "wis-tw2804: ignoring command %08x until "
8735+ "channel number is set\n", cmd);
8736+ return 0;
8737+ }
8738+
8739+ switch (cmd) {
8740+ case DECODER_SET_NORM:
8741+ {
8742+ int *input = arg;
8743+ u8 regs[] = {
8744+ 0x01, *input == VIDEO_MODE_NTSC ? 0xc4 : 0x84,
8745+ 0x09, *input == VIDEO_MODE_NTSC ? 0x07 : 0x04,
8746+ 0x0a, *input == VIDEO_MODE_NTSC ? 0xf0 : 0x20,
8747+ 0x0b, *input == VIDEO_MODE_NTSC ? 0x07 : 0x04,
8748+ 0x0c, *input == VIDEO_MODE_NTSC ? 0xf0 : 0x20,
8749+ 0x0d, *input == VIDEO_MODE_NTSC ? 0x40 : 0x4a,
8750+ 0x16, *input == VIDEO_MODE_NTSC ? 0x00 : 0x40,
8751+ 0x17, *input == VIDEO_MODE_NTSC ? 0x00 : 0x40,
8752+ 0x20, *input == VIDEO_MODE_NTSC ? 0x07 : 0x0f,
8753+ 0x21, *input == VIDEO_MODE_NTSC ? 0x07 : 0x0f,
8754+ 0xff, 0xff,
8755+ };
8756+ write_regs(client, regs, dec->channel);
8757+ dec->norm = *input;
8758+ break;
8759+ }
8760+ case VIDIOC_QUERYCTRL:
8761+ {
8762+ struct v4l2_queryctrl *ctrl = arg;
8763+
8764+ switch (ctrl->id) {
8765+ case V4L2_CID_BRIGHTNESS:
8766+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
8767+ strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
8768+ ctrl->minimum = 0;
8769+ ctrl->maximum = 255;
8770+ ctrl->step = 1;
8771+ ctrl->default_value = 128;
8772+ ctrl->flags = 0;
8773+ break;
8774+ case V4L2_CID_CONTRAST:
8775+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
8776+ strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
8777+ ctrl->minimum = 0;
8778+ ctrl->maximum = 255;
8779+ ctrl->step = 1;
8780+ ctrl->default_value = 128;
8781+ ctrl->flags = 0;
8782+ break;
8783+ case V4L2_CID_SATURATION:
8784+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
8785+ strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
8786+ ctrl->minimum = 0;
8787+ ctrl->maximum = 255;
8788+ ctrl->step = 1;
8789+ ctrl->default_value = 128;
8790+ ctrl->flags = 0;
8791+ break;
8792+ case V4L2_CID_HUE:
8793+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
8794+ strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
8795+ ctrl->minimum = 0;
8796+ ctrl->maximum = 255;
8797+ ctrl->step = 1;
8798+ ctrl->default_value = 128;
8799+ ctrl->flags = 0;
8800+ break;
8801+ }
8802+ break;
8803+ }
8804+ case VIDIOC_S_CTRL:
8805+ {
8806+ struct v4l2_control *ctrl = arg;
8807+
8808+ switch (ctrl->id) {
8809+ case V4L2_CID_BRIGHTNESS:
8810+ if (ctrl->value > 255)
8811+ dec->brightness = 255;
8812+ else if (ctrl->value < 0)
8813+ dec->brightness = 0;
8814+ else
8815+ dec->brightness = ctrl->value;
8816+ write_reg(client, 0x12, dec->brightness, dec->channel);
8817+ break;
8818+ case V4L2_CID_CONTRAST:
8819+ if (ctrl->value > 255)
8820+ dec->contrast = 255;
8821+ else if (ctrl->value < 0)
8822+ dec->contrast = 0;
8823+ else
8824+ dec->contrast = ctrl->value;
8825+ write_reg(client, 0x11, dec->contrast, dec->channel);
8826+ break;
8827+ case V4L2_CID_SATURATION:
8828+ if (ctrl->value > 255)
8829+ dec->saturation = 255;
8830+ else if (ctrl->value < 0)
8831+ dec->saturation = 0;
8832+ else
8833+ dec->saturation = ctrl->value;
8834+ write_reg(client, 0x10, dec->saturation, dec->channel);
8835+ break;
8836+ case V4L2_CID_HUE:
8837+ if (ctrl->value > 255)
8838+ dec->hue = 255;
8839+ else if (ctrl->value < 0)
8840+ dec->hue = 0;
8841+ else
8842+ dec->hue = ctrl->value;
8843+ write_reg(client, 0x0f, dec->hue, dec->channel);
8844+ break;
8845+ }
8846+ break;
8847+ }
8848+ case VIDIOC_G_CTRL:
8849+ {
8850+ struct v4l2_control *ctrl = arg;
8851+
8852+ switch (ctrl->id) {
8853+ case V4L2_CID_BRIGHTNESS:
8854+ ctrl->value = dec->brightness;
8855+ break;
8856+ case V4L2_CID_CONTRAST:
8857+ ctrl->value = dec->contrast;
8858+ break;
8859+ case V4L2_CID_SATURATION:
8860+ ctrl->value = dec->saturation;
8861+ break;
8862+ case V4L2_CID_HUE:
8863+ ctrl->value = dec->hue;
8864+ break;
8865+ }
8866+ break;
8867+ }
8868+ default:
8869+ break;
8870+ }
8871+ return 0;
8872+}
8873+
8874+static struct i2c_driver wis_tw2804_driver;
8875+
8876+static struct i2c_client wis_tw2804_client_templ = {
8877+ .name = "TW2804 (WIS)",
8878+ .driver = &wis_tw2804_driver,
8879+};
8880+
8881+static int wis_tw2804_detect(struct i2c_adapter *adapter, int addr, int kind)
8882+{
8883+ struct i2c_client *client;
8884+ struct wis_tw2804 *dec;
8885+
8886+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
8887+ return 0;
8888+
8889+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
8890+ if (client == NULL)
8891+ return -ENOMEM;
8892+ memcpy(client, &wis_tw2804_client_templ,
8893+ sizeof(wis_tw2804_client_templ));
8894+ client->adapter = adapter;
8895+ client->addr = addr;
8896+
8897+ dec = kmalloc(sizeof(struct wis_tw2804), GFP_KERNEL);
8898+ if (dec == NULL) {
8899+ kfree(client);
8900+ return -ENOMEM;
8901+ }
8902+ dec->channel = -1;
8903+ dec->norm = VIDEO_MODE_NTSC;
8904+ dec->brightness = 128;
8905+ dec->contrast = 128;
8906+ dec->saturation = 128;
8907+ dec->hue = 128;
8908+ i2c_set_clientdata(client, dec);
8909+
8910+ printk(KERN_DEBUG "wis-tw2804: creating TW2804 at address %d on %s\n",
8911+ addr, adapter->name);
8912+
8913+ i2c_attach_client(client);
8914+ return 0;
8915+}
8916+
8917+static int wis_tw2804_detach(struct i2c_client *client)
8918+{
8919+ struct wis_tw2804 *dec = i2c_get_clientdata(client);
8920+ int r;
8921+
8922+ r = i2c_detach_client(client);
8923+ if (r < 0)
8924+ return r;
8925+
8926+ kfree(client);
8927+ kfree(dec);
8928+ return 0;
8929+}
8930+
8931+static struct i2c_driver wis_tw2804_driver = {
8932+ .driver = {
8933+ .name = "WIS TW2804 I2C driver",
8934+ },
8935+ .id = I2C_DRIVERID_WIS_TW2804,
8936+ .detach_client = wis_tw2804_detach,
8937+ .command = wis_tw2804_command,
8938+};
8939+
8940+static int __init wis_tw2804_init(void)
8941+{
8942+ int r;
8943+
8944+ r = i2c_add_driver(&wis_tw2804_driver);
8945+ if (r < 0)
8946+ return r;
8947+ return wis_i2c_add_driver(wis_tw2804_driver.id, wis_tw2804_detect);
8948+}
8949+
8950+static void __exit wis_tw2804_cleanup(void)
8951+{
8952+ wis_i2c_del_driver(wis_tw2804_detect);
8953+ i2c_del_driver(&wis_tw2804_driver);
8954+}
8955+
8956+module_init(wis_tw2804_init);
8957+module_exit(wis_tw2804_cleanup);
8958+
8959+MODULE_LICENSE("GPL v2");
8960diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
8961new file mode 100644
8962index 0000000..1cdf01a
8963--- /dev/null
8964+++ b/drivers/staging/go7007/wis-tw9903.c
8965@@ -0,0 +1,363 @@
8966+/*
8967+ * Copyright (C) 2005-2006 Micronas USA Inc.
8968+ *
8969+ * This program is free software; you can redistribute it and/or modify
8970+ * it under the terms of the GNU General Public License (Version 2) as
8971+ * published by the Free Software Foundation.
8972+ *
8973+ * This program is distributed in the hope that it will be useful,
8974+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8975+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8976+ * GNU General Public License for more details.
8977+ *
8978+ * You should have received a copy of the GNU General Public License
8979+ * along with this program; if not, write to the Free Software Foundation,
8980+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
8981+ */
8982+
8983+#include <linux/module.h>
8984+#include <linux/init.h>
8985+#include <linux/version.h>
8986+#include <linux/i2c.h>
8987+#include <linux/videodev.h>
8988+#include <linux/video_decoder.h>
8989+#include <linux/ioctl.h>
8990+
8991+#include "wis-i2c.h"
8992+
8993+struct wis_tw9903 {
8994+ int norm;
8995+ int brightness;
8996+ int contrast;
8997+ int hue;
8998+};
8999+
9000+static u8 initial_registers[] =
9001+{
9002+ 0x02, 0x44, /* input 1, composite */
9003+ 0x03, 0x92, /* correct digital format */
9004+ 0x04, 0x00,
9005+ 0x05, 0x80, /* or 0x00 for PAL */
9006+ 0x06, 0x40, /* second internal current reference */
9007+ 0x07, 0x02, /* window */
9008+ 0x08, 0x14, /* window */
9009+ 0x09, 0xf0, /* window */
9010+ 0x0a, 0x81, /* window */
9011+ 0x0b, 0xd0, /* window */
9012+ 0x0c, 0x8c,
9013+ 0x0d, 0x00, /* scaling */
9014+ 0x0e, 0x11, /* scaling */
9015+ 0x0f, 0x00, /* scaling */
9016+ 0x10, 0x00, /* brightness */
9017+ 0x11, 0x60, /* contrast */
9018+ 0x12, 0x01, /* sharpness */
9019+ 0x13, 0x7f, /* U gain */
9020+ 0x14, 0x5a, /* V gain */
9021+ 0x15, 0x00, /* hue */
9022+ 0x16, 0xc3, /* sharpness */
9023+ 0x18, 0x00,
9024+ 0x19, 0x58, /* vbi */
9025+ 0x1a, 0x80,
9026+ 0x1c, 0x0f, /* video norm */
9027+ 0x1d, 0x7f, /* video norm */
9028+ 0x20, 0xa0, /* clamping gain (working 0x50) */
9029+ 0x21, 0x22,
9030+ 0x22, 0xf0,
9031+ 0x23, 0xfe,
9032+ 0x24, 0x3c,
9033+ 0x25, 0x38,
9034+ 0x26, 0x44,
9035+ 0x27, 0x20,
9036+ 0x28, 0x00,
9037+ 0x29, 0x15,
9038+ 0x2a, 0xa0,
9039+ 0x2b, 0x44,
9040+ 0x2c, 0x37,
9041+ 0x2d, 0x00,
9042+ 0x2e, 0xa5, /* burst PLL control (working: a9) */
9043+ 0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */
9044+ 0x31, 0x00,
9045+ 0x33, 0x22,
9046+ 0x34, 0x11,
9047+ 0x35, 0x35,
9048+ 0x3b, 0x05,
9049+ 0x06, 0xc0, /* reset device */
9050+ 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
9051+};
9052+
9053+static int write_reg(struct i2c_client *client, u8 reg, u8 value)
9054+{
9055+ return i2c_smbus_write_byte_data(client, reg, value);
9056+}
9057+
9058+static int write_regs(struct i2c_client *client, u8 *regs)
9059+{
9060+ int i;
9061+
9062+ for (i = 0; regs[i] != 0x00; i += 2)
9063+ if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
9064+ return -1;
9065+ return 0;
9066+}
9067+
9068+static int wis_tw9903_command(struct i2c_client *client,
9069+ unsigned int cmd, void *arg)
9070+{
9071+ struct wis_tw9903 *dec = i2c_get_clientdata(client);
9072+
9073+ switch (cmd) {
9074+ case DECODER_SET_INPUT:
9075+ {
9076+ int *input = arg;
9077+
9078+ i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
9079+ break;
9080+ }
9081+#if 0 /* The scaler on this thing seems to be horribly broken */
9082+ case DECODER_SET_RESOLUTION:
9083+ {
9084+ struct video_decoder_resolution *res = arg;
9085+ /*int hscale = 256 * 720 / res->width;*/
9086+ int hscale = 256 * 720 / (res->width - (res->width > 704 ? 0 : 8));
9087+ int vscale = 256 * (dec->norm == VIDEO_MODE_NTSC ? 240 : 288)
9088+ / res->height;
9089+ u8 regs[] = {
9090+ 0x0d, vscale & 0xff,
9091+ 0x0f, hscale & 0xff,
9092+ 0x0e, ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8),
9093+ 0x06, 0xc0, /* reset device */
9094+ 0, 0,
9095+ };
9096+ printk(KERN_DEBUG "vscale is %04x, hscale is %04x\n",
9097+ vscale, hscale);
9098+ /*write_regs(client, regs);*/
9099+ break;
9100+ }
9101+#endif
9102+ case DECODER_SET_NORM:
9103+ {
9104+ int *input = arg;
9105+ u8 regs[] = {
9106+ 0x05, *input == VIDEO_MODE_NTSC ? 0x80 : 0x00,
9107+ 0x07, *input == VIDEO_MODE_NTSC ? 0x02 : 0x12,
9108+ 0x08, *input == VIDEO_MODE_NTSC ? 0x14 : 0x18,
9109+ 0x09, *input == VIDEO_MODE_NTSC ? 0xf0 : 0x20,
9110+ 0, 0,
9111+ };
9112+ write_regs(client, regs);
9113+ dec->norm = *input;
9114+ break;
9115+ }
9116+ case VIDIOC_QUERYCTRL:
9117+ {
9118+ struct v4l2_queryctrl *ctrl = arg;
9119+
9120+ switch (ctrl->id) {
9121+ case V4L2_CID_BRIGHTNESS:
9122+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
9123+ strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
9124+ ctrl->minimum = -128;
9125+ ctrl->maximum = 127;
9126+ ctrl->step = 1;
9127+ ctrl->default_value = 0x00;
9128+ ctrl->flags = 0;
9129+ break;
9130+ case V4L2_CID_CONTRAST:
9131+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
9132+ strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
9133+ ctrl->minimum = 0;
9134+ ctrl->maximum = 255;
9135+ ctrl->step = 1;
9136+ ctrl->default_value = 0x60;
9137+ ctrl->flags = 0;
9138+ break;
9139+#if 0
9140+ /* I don't understand how the Chroma Gain registers work... */
9141+ case V4L2_CID_SATURATION:
9142+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
9143+ strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
9144+ ctrl->minimum = 0;
9145+ ctrl->maximum = 127;
9146+ ctrl->step = 1;
9147+ ctrl->default_value = 64;
9148+ ctrl->flags = 0;
9149+ break;
9150+#endif
9151+ case V4L2_CID_HUE:
9152+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
9153+ strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
9154+ ctrl->minimum = -128;
9155+ ctrl->maximum = 127;
9156+ ctrl->step = 1;
9157+ ctrl->default_value = 0;
9158+ ctrl->flags = 0;
9159+ break;
9160+ }
9161+ break;
9162+ }
9163+ case VIDIOC_S_CTRL:
9164+ {
9165+ struct v4l2_control *ctrl = arg;
9166+
9167+ switch (ctrl->id) {
9168+ case V4L2_CID_BRIGHTNESS:
9169+ if (ctrl->value > 127)
9170+ dec->brightness = 127;
9171+ else if (ctrl->value < -128)
9172+ dec->brightness = -128;
9173+ else
9174+ dec->brightness = ctrl->value;
9175+ write_reg(client, 0x10, dec->brightness);
9176+ break;
9177+ case V4L2_CID_CONTRAST:
9178+ if (ctrl->value > 255)
9179+ dec->contrast = 255;
9180+ else if (ctrl->value < 0)
9181+ dec->contrast = 0;
9182+ else
9183+ dec->contrast = ctrl->value;
9184+ write_reg(client, 0x11, dec->contrast);
9185+ break;
9186+#if 0
9187+ case V4L2_CID_SATURATION:
9188+ if (ctrl->value > 127)
9189+ dec->saturation = 127;
9190+ else if (ctrl->value < 0)
9191+ dec->saturation = 0;
9192+ else
9193+ dec->saturation = ctrl->value;
9194+ /*write_reg(client, 0x0c, dec->saturation);*/
9195+ break;
9196+#endif
9197+ case V4L2_CID_HUE:
9198+ if (ctrl->value > 127)
9199+ dec->hue = 127;
9200+ else if (ctrl->value < -128)
9201+ dec->hue = -128;
9202+ else
9203+ dec->hue = ctrl->value;
9204+ write_reg(client, 0x15, dec->hue);
9205+ break;
9206+ }
9207+ break;
9208+ }
9209+ case VIDIOC_G_CTRL:
9210+ {
9211+ struct v4l2_control *ctrl = arg;
9212+
9213+ switch (ctrl->id) {
9214+ case V4L2_CID_BRIGHTNESS:
9215+ ctrl->value = dec->brightness;
9216+ break;
9217+ case V4L2_CID_CONTRAST:
9218+ ctrl->value = dec->contrast;
9219+ break;
9220+#if 0
9221+ case V4L2_CID_SATURATION:
9222+ ctrl->value = dec->saturation;
9223+ break;
9224+#endif
9225+ case V4L2_CID_HUE:
9226+ ctrl->value = dec->hue;
9227+ break;
9228+ }
9229+ break;
9230+ }
9231+ default:
9232+ break;
9233+ }
9234+ return 0;
9235+}
9236+
9237+static struct i2c_driver wis_tw9903_driver;
9238+
9239+static struct i2c_client wis_tw9903_client_templ = {
9240+ .name = "TW9903 (WIS)",
9241+ .driver = &wis_tw9903_driver,
9242+};
9243+
9244+static int wis_tw9903_detect(struct i2c_adapter *adapter, int addr, int kind)
9245+{
9246+ struct i2c_client *client;
9247+ struct wis_tw9903 *dec;
9248+
9249+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
9250+ return 0;
9251+
9252+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
9253+ if (client == NULL)
9254+ return -ENOMEM;
9255+ memcpy(client, &wis_tw9903_client_templ,
9256+ sizeof(wis_tw9903_client_templ));
9257+ client->adapter = adapter;
9258+ client->addr = addr;
9259+
9260+ dec = kmalloc(sizeof(struct wis_tw9903), GFP_KERNEL);
9261+ if (dec == NULL) {
9262+ kfree(client);
9263+ return -ENOMEM;
9264+ }
9265+ dec->norm = VIDEO_MODE_NTSC;
9266+ dec->brightness = 0;
9267+ dec->contrast = 0x60;
9268+ dec->hue = 0;
9269+ i2c_set_clientdata(client, dec);
9270+
9271+ printk(KERN_DEBUG
9272+ "wis-tw9903: initializing TW9903 at address %d on %s\n",
9273+ addr, adapter->name);
9274+
9275+ if (write_regs(client, initial_registers) < 0) {
9276+ printk(KERN_ERR "wis-tw9903: error initializing TW9903\n");
9277+ kfree(client);
9278+ kfree(dec);
9279+ return 0;
9280+ }
9281+
9282+ i2c_attach_client(client);
9283+ return 0;
9284+}
9285+
9286+static int wis_tw9903_detach(struct i2c_client *client)
9287+{
9288+ struct wis_tw9903 *dec = i2c_get_clientdata(client);
9289+ int r;
9290+
9291+ r = i2c_detach_client(client);
9292+ if (r < 0)
9293+ return r;
9294+
9295+ kfree(client);
9296+ kfree(dec);
9297+ return 0;
9298+}
9299+
9300+static struct i2c_driver wis_tw9903_driver = {
9301+ .driver = {
9302+ .name = "WIS TW9903 I2C driver",
9303+ },
9304+ .id = I2C_DRIVERID_WIS_TW9903,
9305+ .detach_client = wis_tw9903_detach,
9306+ .command = wis_tw9903_command,
9307+};
9308+
9309+static int __init wis_tw9903_init(void)
9310+{
9311+ int r;
9312+
9313+ r = i2c_add_driver(&wis_tw9903_driver);
9314+ if (r < 0)
9315+ return r;
9316+ return wis_i2c_add_driver(wis_tw9903_driver.id, wis_tw9903_detect);
9317+}
9318+
9319+static void __exit wis_tw9903_cleanup(void)
9320+{
9321+ wis_i2c_del_driver(wis_tw9903_detect);
9322+ i2c_del_driver(&wis_tw9903_driver);
9323+}
9324+
9325+module_init(wis_tw9903_init);
9326+module_exit(wis_tw9903_cleanup);
9327+
9328+MODULE_LICENSE("GPL v2");
9329diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/go7007/wis-uda1342.c
9330new file mode 100644
9331index 0000000..28c10bf
9332--- /dev/null
9333+++ b/drivers/staging/go7007/wis-uda1342.c
9334@@ -0,0 +1,136 @@
9335+/*
9336+ * Copyright (C) 2005-2006 Micronas USA Inc.
9337+ *
9338+ * This program is free software; you can redistribute it and/or modify
9339+ * it under the terms of the GNU General Public License (Version 2) as
9340+ * published by the Free Software Foundation.
9341+ *
9342+ * This program is distributed in the hope that it will be useful,
9343+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9344+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9345+ * GNU General Public License for more details.
9346+ *
9347+ * You should have received a copy of the GNU General Public License
9348+ * along with this program; if not, write to the Free Software Foundation,
9349+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
9350+ */
9351+
9352+#include <linux/module.h>
9353+#include <linux/init.h>
9354+#include <linux/version.h>
9355+#include <linux/i2c.h>
9356+#include <linux/videodev.h>
9357+#include <media/tvaudio.h>
9358+#include <media/v4l2-common.h>
9359+
9360+#include "wis-i2c.h"
9361+
9362+static int write_reg(struct i2c_client *client, int reg, int value)
9363+{
9364+ /* UDA1342 wants MSB first, but SMBus sends LSB first */
9365+ i2c_smbus_write_word_data(client, reg, swab16(value));
9366+ return 0;
9367+}
9368+
9369+static int wis_uda1342_command(struct i2c_client *client,
9370+ unsigned int cmd, void *arg)
9371+{
9372+ switch (cmd) {
9373+ case VIDIOC_S_AUDIO:
9374+ {
9375+ int *inp = arg;
9376+
9377+ switch (*inp) {
9378+ case TVAUDIO_INPUT_TUNER:
9379+ write_reg(client, 0x00, 0x1441); /* select input 2 */
9380+ break;
9381+ case TVAUDIO_INPUT_EXTERN:
9382+ write_reg(client, 0x00, 0x1241); /* select input 1 */
9383+ break;
9384+ default:
9385+ printk(KERN_ERR "wis-uda1342: input %d not supported\n",
9386+ *inp);
9387+ break;
9388+ }
9389+ break;
9390+ }
9391+ default:
9392+ break;
9393+ }
9394+ return 0;
9395+}
9396+
9397+static struct i2c_driver wis_uda1342_driver;
9398+
9399+static struct i2c_client wis_uda1342_client_templ = {
9400+ .name = "UDA1342 (WIS)",
9401+ .driver = &wis_uda1342_driver,
9402+};
9403+
9404+static int wis_uda1342_detect(struct i2c_adapter *adapter, int addr, int kind)
9405+{
9406+ struct i2c_client *client;
9407+
9408+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
9409+ return 0;
9410+
9411+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
9412+ if (client == NULL)
9413+ return -ENOMEM;
9414+ memcpy(client, &wis_uda1342_client_templ,
9415+ sizeof(wis_uda1342_client_templ));
9416+ client->adapter = adapter;
9417+ client->addr = addr;
9418+
9419+ printk(KERN_DEBUG
9420+ "wis-uda1342: initializing UDA1342 at address %d on %s\n",
9421+ addr, adapter->name);
9422+
9423+ write_reg(client, 0x00, 0x8000); /* reset registers */
9424+ write_reg(client, 0x00, 0x1241); /* select input 1 */
9425+
9426+ i2c_attach_client(client);
9427+ return 0;
9428+}
9429+
9430+static int wis_uda1342_detach(struct i2c_client *client)
9431+{
9432+ int r;
9433+
9434+ r = i2c_detach_client(client);
9435+ if (r < 0)
9436+ return r;
9437+
9438+ kfree(client);
9439+ return 0;
9440+}
9441+
9442+static struct i2c_driver wis_uda1342_driver = {
9443+ .driver = {
9444+ .name = "WIS UDA1342 I2C driver",
9445+ },
9446+ .id = I2C_DRIVERID_WIS_UDA1342,
9447+ .detach_client = wis_uda1342_detach,
9448+ .command = wis_uda1342_command,
9449+};
9450+
9451+static int __init wis_uda1342_init(void)
9452+{
9453+ int r;
9454+
9455+ r = i2c_add_driver(&wis_uda1342_driver);
9456+ if (r < 0)
9457+ return r;
9458+ return wis_i2c_add_driver(wis_uda1342_driver.id, wis_uda1342_detect);
9459+}
9460+
9461+static void __exit wis_uda1342_cleanup(void)
9462+{
9463+ wis_i2c_del_driver(wis_uda1342_detect);
9464+ i2c_del_driver(&wis_uda1342_driver);
9465+}
9466+
9467+module_init(wis_uda1342_init);
9468+module_exit(wis_uda1342_cleanup);
9469+
9470+MODULE_LICENSE("GPL v2");
9471--
94721.6.0.2
9473