aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2008-02-15 19:53:09 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-10 18:31:08 -0400
commit866b8695d67e83f47194731d3a7ba55826a7ec70 (patch)
tree946a4850d3850edeac3634e6d4dd24928779f0c5
parentc0f005888c6663898a040cd922947dd8caa55160 (diff)
Staging: add the go7007 video driver
Todo: - checkpatch.pl cleanups - sparse cleanups - lots of little modules, should be merged together and added to the build. - testing? - handle churn in v4l layer. Many thanks to Ross Cohen <rcohen@snurgle.org> for cleanup patches on this driver. Cc: Ross Cohen <rcohen@snurgle.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/go7007/Kconfig25
-rw-r--r--drivers/staging/go7007/Makefile18
-rw-r--r--drivers/staging/go7007/README11
-rw-r--r--drivers/staging/go7007/go7007-driver.c688
-rw-r--r--drivers/staging/go7007/go7007-fw.c1639
-rw-r--r--drivers/staging/go7007/go7007-i2c.c309
-rw-r--r--drivers/staging/go7007/go7007-priv.h279
-rw-r--r--drivers/staging/go7007/go7007-usb.c1229
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c1503
-rw-r--r--drivers/staging/go7007/go7007.h114
-rw-r--r--drivers/staging/go7007/saa7134-go7007.c484
-rw-r--r--drivers/staging/go7007/snd-go7007.c305
-rw-r--r--drivers/staging/go7007/wis-i2c.h55
-rw-r--r--drivers/staging/go7007/wis-ov7640.c131
-rw-r--r--drivers/staging/go7007/wis-saa7113.c363
-rw-r--r--drivers/staging/go7007/wis-saa7115.c492
-rw-r--r--drivers/staging/go7007/wis-sony-tuner.c741
-rw-r--r--drivers/staging/go7007/wis-tw2804.c381
-rw-r--r--drivers/staging/go7007/wis-tw9903.c363
-rw-r--r--drivers/staging/go7007/wis-uda1342.c136
22 files changed, 9269 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 56c73bcf477..f16bc9cdaf3 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -31,4 +31,6 @@ source "drivers/staging/sxg/Kconfig"
31 31
32source "drivers/staging/me4000/Kconfig" 32source "drivers/staging/me4000/Kconfig"
33 33
34source "drivers/staging/go7007/Kconfig"
35
34endif # STAGING 36endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 97df19be52d..aa61662e632 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_ET131X) += et131x/
4obj-$(CONFIG_SLICOSS) += slicoss/ 4obj-$(CONFIG_SLICOSS) += slicoss/
5obj-$(CONFIG_SXG) += sxg/ 5obj-$(CONFIG_SXG) += sxg/
6obj-$(CONFIG_ME4000) += me4000/ 6obj-$(CONFIG_ME4000) += me4000/
7obj-$(CONFIG_VIDEO_GO7007) += go7007/
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
new file mode 100644
index 00000000000..57a121c338c
--- /dev/null
+++ b/drivers/staging/go7007/Kconfig
@@ -0,0 +1,25 @@
1config VIDEO_GO7007
2 tristate "Go 7007 support"
3 depends on VIDEO_DEV && PCI && I2C && INPUT
4 select VIDEOBUF_DMA_SG
5 select VIDEO_IR
6 select VIDEO_TUNER
7 select VIDEO_TVEEPROM
8 select CRC32
9 default N
10 ---help---
11 This is a video4linux driver for some wierd device...
12
13 To compile this driver as a module, choose M here: the
14 module will be called go7007
15
16config VIDEO_GO7007_USB
17 tristate "Go 7007 USB support"
18 depends on VIDEO_GO7007 && USB
19 default N
20 ---help---
21 This is a video4linux driver for some wierd device...
22
23 To compile this driver as a module, choose M here: the
24 module will be called go7007-usb
25
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
new file mode 100644
index 00000000000..9b9310cae1c
--- /dev/null
+++ b/drivers/staging/go7007/Makefile
@@ -0,0 +1,18 @@
1#obj-m += go7007.o go7007-usb.o snd-go7007.o wis-saa7115.o wis-tw9903.o \
2 wis-uda1342.o wis-sony-tuner.o wis-saa7113.o wis-ov7640.o \
3 wis-tw2804.o
4
5
6obj-$(CONFIG_VIDEO_GO7007) += go7007.o
7obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
8
9go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o snd-go7007.o
10
11
12#ifneq ($(SAA7134_BUILD),)
13#obj-m += saa7134-go7007.o
14#endif
15
16EXTRA_CFLAGS += -Idrivers/staging/saa7134
17EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
18EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/staging/go7007/README b/drivers/staging/go7007/README
new file mode 100644
index 00000000000..48f44763781
--- /dev/null
+++ b/drivers/staging/go7007/README
@@ -0,0 +1,11 @@
1Todo:
2 - checkpatch.pl cleanups
3 - sparse cleanups
4 - lots of little modules, should be merged together
5 and added to the build.
6 - testing?
7 - handle churn in v4l layer.
8
9Please send patchs to Greg Kroah-Hartman <greg@kroah.com> and Cc: Ross
10Cohen <rcohen@snurgle.org> as well.
11
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
new file mode 100644
index 00000000000..5a336ff2d9b
--- /dev/null
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -0,0 +1,688 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/version.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/sched.h>
23#include <linux/spinlock.h>
24#include <linux/unistd.h>
25#include <linux/time.h>
26#include <linux/mm.h>
27#include <linux/vmalloc.h>
28#include <linux/device.h>
29#include <linux/i2c.h>
30#include <linux/firmware.h>
31#include <linux/semaphore.h>
32#include <linux/uaccess.h>
33#include <asm/system.h>
34#include <linux/videodev.h>
35#include <media/tuner.h>
36#include <media/v4l2-common.h>
37
38#include "go7007-priv.h"
39#include "wis-i2c.h"
40
41/*
42 * Wait for an interrupt to be delivered from the GO7007SB and return
43 * the associated value and data.
44 *
45 * Must be called with the hw_lock held.
46 */
47int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
48{
49 go->interrupt_available = 0;
50 go->hpi_ops->read_interrupt(go);
51 if (wait_event_timeout(go->interrupt_waitq,
52 go->interrupt_available, 5*HZ) < 0) {
53 printk(KERN_ERR "go7007: timeout waiting for read interrupt\n");
54 return -1;
55 }
56 if (!go->interrupt_available)
57 return -1;
58 go->interrupt_available = 0;
59 *value = go->interrupt_value & 0xfffe;
60 *data = go->interrupt_data;
61 return 0;
62}
63EXPORT_SYMBOL(go7007_read_interrupt);
64
65/*
66 * Read a register/address on the GO7007SB.
67 *
68 * Must be called with the hw_lock held.
69 */
70int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data)
71{
72 int count = 100;
73 u16 value;
74
75 if (go7007_write_interrupt(go, 0x0010, addr) < 0)
76 return -EIO;
77 while (count-- > 0) {
78 if (go7007_read_interrupt(go, &value, data) == 0 &&
79 value == 0xa000)
80 return 0;
81 }
82 return -EIO;
83}
84EXPORT_SYMBOL(go7007_read_addr);
85
86/*
87 * Send the boot firmware to the encoder, which just wakes it up and lets
88 * us talk to the GPIO pins and on-board I2C adapter.
89 *
90 * Must be called with the hw_lock held.
91 */
92static int go7007_load_encoder(struct go7007 *go)
93{
94 const struct firmware *fw_entry;
95 char fw_name[] = "go7007fw.bin";
96 void *bounce;
97 int fw_len, rv = 0;
98 u16 intr_val, intr_data;
99
100 if (request_firmware(&fw_entry, fw_name, go->dev)) {
101 printk(KERN_ERR
102 "go7007: unable to load firmware from file \"%s\"\n",
103 fw_name);
104 return -1;
105 }
106 if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
107 printk(KERN_ERR "go7007: file \"%s\" does not appear to be "
108 "go7007 firmware\n", fw_name);
109 release_firmware(fw_entry);
110 return -1;
111 }
112 fw_len = fw_entry->size - 16;
113 bounce = kmalloc(fw_len, GFP_KERNEL);
114 if (bounce == NULL) {
115 printk(KERN_ERR "go7007: unable to allocate %d bytes for "
116 "firmware transfer\n", fw_len);
117 release_firmware(fw_entry);
118 return -1;
119 }
120 memcpy(bounce, fw_entry->data + 16, fw_len);
121 release_firmware(fw_entry);
122 if (go7007_interface_reset(go) < 0 ||
123 go7007_send_firmware(go, bounce, fw_len) < 0 ||
124 go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
125 (intr_val & ~0x1) != 0x5a5a) {
126 printk(KERN_ERR "go7007: error transferring firmware\n");
127 rv = -1;
128 }
129 kfree(bounce);
130 return rv;
131}
132
133/*
134 * Boot the encoder and register the I2C adapter if requested. Do the
135 * minimum initialization necessary, since the board-specific code may
136 * still need to probe the board ID.
137 *
138 * Must NOT be called with the hw_lock held.
139 */
140int go7007_boot_encoder(struct go7007 *go, int init_i2c)
141{
142 int ret;
143
144 down(&go->hw_lock);
145 ret = go7007_load_encoder(go);
146 up(&go->hw_lock);
147 if (ret < 0)
148 return -1;
149 if (!init_i2c)
150 return 0;
151 if (go7007_i2c_init(go) < 0)
152 return -1;
153 go->i2c_adapter_online = 1;
154 return 0;
155}
156EXPORT_SYMBOL(go7007_boot_encoder);
157
158/*
159 * Configure any hardware-related registers in the GO7007, such as GPIO
160 * pins and bus parameters, which are board-specific. This assumes
161 * the boot firmware has already been downloaded.
162 *
163 * Must be called with the hw_lock held.
164 */
165static int go7007_init_encoder(struct go7007 *go)
166{
167 if (go->board_info->audio_flags & GO7007_AUDIO_I2S_MASTER) {
168 go7007_write_addr(go, 0x1000, 0x0811);
169 go7007_write_addr(go, 0x1000, 0x0c11);
170 }
171 if (go->board_id == GO7007_BOARDID_MATRIX_REV) {
172 /* Set GPIO pin 0 to be an output (audio clock control) */
173 go7007_write_addr(go, 0x3c82, 0x0001);
174 go7007_write_addr(go, 0x3c80, 0x00fe);
175 }
176 return 0;
177}
178
179/*
180 * Send the boot firmware to the GO7007 and configure the registers. This
181 * is the only way to stop the encoder once it has started streaming video.
182 *
183 * Must be called with the hw_lock held.
184 */
185int go7007_reset_encoder(struct go7007 *go)
186{
187 if (go7007_load_encoder(go) < 0)
188 return -1;
189 return go7007_init_encoder(go);
190}
191
192/*
193 * Attempt to instantiate an I2C client by ID, probably loading a module.
194 */
195static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr)
196{
197 char *modname;
198
199 switch (id) {
200 case I2C_DRIVERID_WIS_SAA7115:
201 modname = "wis-saa7115";
202 break;
203 case I2C_DRIVERID_WIS_SAA7113:
204 modname = "wis-saa7113";
205 break;
206 case I2C_DRIVERID_WIS_UDA1342:
207 modname = "wis-uda1342";
208 break;
209 case I2C_DRIVERID_WIS_SONY_TUNER:
210 modname = "wis-sony-tuner";
211 break;
212 case I2C_DRIVERID_WIS_TW9903:
213 modname = "wis-tw9903";
214 break;
215 case I2C_DRIVERID_WIS_TW2804:
216 modname = "wis-tw2804";
217 break;
218 case I2C_DRIVERID_WIS_OV7640:
219 modname = "wis-ov7640";
220 break;
221 default:
222 modname = NULL;
223 break;
224 }
225 if (modname != NULL)
226 request_module(modname);
227 if (wis_i2c_probe_device(adapter, id, addr) == 1)
228 return 0;
229 if (modname != NULL)
230 printk(KERN_INFO
231 "go7007: probing for module %s failed", modname);
232 else
233 printk(KERN_INFO
234 "go7007: sensor %u seems to be unsupported!\n", id);
235 return -1;
236}
237
238/*
239 * Finalize the GO7007 hardware setup, register the on-board I2C adapter
240 * (if used on this board), load the I2C client driver for the sensor
241 * (SAA7115 or whatever) and other devices, and register the ALSA and V4L2
242 * interfaces.
243 *
244 * Must NOT be called with the hw_lock held.
245 */
246int go7007_register_encoder(struct go7007 *go)
247{
248 int i, ret;
249
250 printk(KERN_INFO "go7007: registering new %s\n", go->name);
251
252 down(&go->hw_lock);
253 ret = go7007_init_encoder(go);
254 up(&go->hw_lock);
255 if (ret < 0)
256 return -1;
257
258 if (!go->i2c_adapter_online &&
259 go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
260 if (go7007_i2c_init(go) < 0)
261 return -1;
262 go->i2c_adapter_online = 1;
263 }
264 if (go->i2c_adapter_online) {
265 for (i = 0; i < go->board_info->num_i2c_devs; ++i)
266 init_i2c_module(&go->i2c_adapter,
267 go->board_info->i2c_devs[i].id,
268 go->board_info->i2c_devs[i].addr);
269#ifdef TUNER_SET_TYPE_ADDR
270 if (go->tuner_type >= 0) {
271 struct tuner_setup tun_setup = {
272 .mode_mask = T_ANALOG_TV,
273 .addr = ADDR_UNSET,
274 .type = go->tuner_type
275 };
276 i2c_clients_command(&go->i2c_adapter,
277 TUNER_SET_TYPE_ADDR, &tun_setup);
278 }
279#else
280 if (go->tuner_type >= 0)
281 i2c_clients_command(&go->i2c_adapter,
282 TUNER_SET_TYPE, &go->tuner_type);
283#endif
284 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
285 i2c_clients_command(&go->i2c_adapter,
286 DECODER_SET_CHANNEL, &go->channel_number);
287 }
288 if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
289 go->audio_enabled = 1;
290 go7007_snd_init(go);
291 }
292 return go7007_v4l2_init(go);
293}
294EXPORT_SYMBOL(go7007_register_encoder);
295
296/*
297 * Send the encode firmware to the encoder, which will cause it
298 * to immediately start delivering the video and audio streams.
299 *
300 * Must be called with the hw_lock held.
301 */
302int go7007_start_encoder(struct go7007 *go)
303{
304 u8 *fw;
305 int fw_len, rv = 0, i;
306 u16 intr_val, intr_data;
307
308 go->modet_enable = 0;
309 if (!go->dvd_mode)
310 for (i = 0; i < 4; ++i) {
311 if (go->modet[i].enable) {
312 go->modet_enable = 1;
313 continue;
314 }
315 go->modet[i].pixel_threshold = 32767;
316 go->modet[i].motion_threshold = 32767;
317 go->modet[i].mb_threshold = 32767;
318 }
319
320 if (go7007_construct_fw_image(go, &fw, &fw_len) < 0)
321 return -1;
322
323 if (go7007_send_firmware(go, fw, fw_len) < 0 ||
324 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
325 printk(KERN_ERR "go7007: error transferring firmware\n");
326 rv = -1;
327 goto start_error;
328 }
329
330 go->state = STATE_DATA;
331 go->parse_length = 0;
332 go->seen_frame = 0;
333 if (go7007_stream_start(go) < 0) {
334 printk(KERN_ERR "go7007: error starting stream transfer\n");
335 rv = -1;
336 goto start_error;
337 }
338
339start_error:
340 kfree(fw);
341 return rv;
342}
343
344/*
345 * Store a byte in the current video buffer, if there is one.
346 */
347static inline void store_byte(struct go7007_buffer *gobuf, u8 byte)
348{
349 if (gobuf != NULL && gobuf->bytesused < GO7007_BUF_SIZE) {
350 unsigned int pgidx = gobuf->offset >> PAGE_SHIFT;
351 unsigned int pgoff = gobuf->offset & ~PAGE_MASK;
352
353 *((u8 *)page_address(gobuf->pages[pgidx]) + pgoff) = byte;
354 ++gobuf->offset;
355 ++gobuf->bytesused;
356 }
357}
358
359/*
360 * Deliver the last video buffer and get a new one to start writing to.
361 */
362static void frame_boundary(struct go7007 *go)
363{
364 struct go7007_buffer *gobuf;
365 int i;
366
367 if (go->active_buf) {
368 if (go->active_buf->modet_active) {
369 if (go->active_buf->bytesused + 216 < GO7007_BUF_SIZE) {
370 for (i = 0; i < 216; ++i)
371 store_byte(go->active_buf,
372 go->active_map[i]);
373 go->active_buf->bytesused -= 216;
374 } else
375 go->active_buf->modet_active = 0;
376 }
377 go->active_buf->state = BUF_STATE_DONE;
378 wake_up_interruptible(&go->frame_waitq);
379 go->active_buf = NULL;
380 }
381 list_for_each_entry(gobuf, &go->stream, stream)
382 if (gobuf->state == BUF_STATE_QUEUED) {
383 gobuf->seq = go->next_seq;
384 do_gettimeofday(&gobuf->timestamp);
385 go->active_buf = gobuf;
386 break;
387 }
388 ++go->next_seq;
389}
390
391static void write_bitmap_word(struct go7007 *go)
392{
393 int x, y, i, stride = ((go->width >> 4) + 7) >> 3;
394
395 for (i = 0; i < 16; ++i) {
396 y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4);
397 x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4);
398 go->active_map[stride * y + (x >> 3)] |=
399 (go->modet_word & 1) << (x & 0x7);
400 go->modet_word >>= 1;
401 }
402}
403
404/*
405 * Parse a chunk of the video stream into frames. The frames are not
406 * delimited by the hardware, so we have to parse the frame boundaries
407 * based on the type of video stream we're receiving.
408 */
409void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
410{
411 int i, seq_start_code = -1, frame_start_code = -1;
412
413 spin_lock(&go->spinlock);
414
415 switch (go->format) {
416 case GO7007_FORMAT_MPEG4:
417 seq_start_code = 0xB0;
418 frame_start_code = 0xB6;
419 break;
420 case GO7007_FORMAT_MPEG1:
421 case GO7007_FORMAT_MPEG2:
422 seq_start_code = 0xB3;
423 frame_start_code = 0x00;
424 break;
425 }
426
427 for (i = 0; i < length; ++i) {
428 if (go->active_buf != NULL &&
429 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
430 printk(KERN_DEBUG "go7007: dropping oversized frame\n");
431 go->active_buf->offset -= go->active_buf->bytesused;
432 go->active_buf->bytesused = 0;
433 go->active_buf->modet_active = 0;
434 go->active_buf = NULL;
435 }
436
437 switch (go->state) {
438 case STATE_DATA:
439 switch (buf[i]) {
440 case 0x00:
441 go->state = STATE_00;
442 break;
443 case 0xFF:
444 go->state = STATE_FF;
445 break;
446 default:
447 store_byte(go->active_buf, buf[i]);
448 break;
449 }
450 break;
451 case STATE_00:
452 switch (buf[i]) {
453 case 0x00:
454 go->state = STATE_00_00;
455 break;
456 case 0xFF:
457 store_byte(go->active_buf, 0x00);
458 go->state = STATE_FF;
459 break;
460 default:
461 store_byte(go->active_buf, 0x00);
462 store_byte(go->active_buf, buf[i]);
463 go->state = STATE_DATA;
464 break;
465 }
466 break;
467 case STATE_00_00:
468 switch (buf[i]) {
469 case 0x00:
470 store_byte(go->active_buf, 0x00);
471 /* go->state remains STATE_00_00 */
472 break;
473 case 0x01:
474 go->state = STATE_00_00_01;
475 break;
476 case 0xFF:
477 store_byte(go->active_buf, 0x00);
478 store_byte(go->active_buf, 0x00);
479 go->state = STATE_FF;
480 break;
481 default:
482 store_byte(go->active_buf, 0x00);
483 store_byte(go->active_buf, 0x00);
484 store_byte(go->active_buf, buf[i]);
485 go->state = STATE_DATA;
486 break;
487 }
488 break;
489 case STATE_00_00_01:
490 /* If this is the start of a new MPEG frame,
491 * get a new buffer */
492 if ((go->format == GO7007_FORMAT_MPEG1 ||
493 go->format == GO7007_FORMAT_MPEG2 ||
494 go->format == GO7007_FORMAT_MPEG4) &&
495 (buf[i] == seq_start_code ||
496 buf[i] == 0xB8 || /* GOP code */
497 buf[i] == frame_start_code)) {
498 if (go->active_buf == NULL || go->seen_frame)
499 frame_boundary(go);
500 if (buf[i] == frame_start_code) {
501 if (go->active_buf != NULL)
502 go->active_buf->frame_offset =
503 go->active_buf->offset;
504 go->seen_frame = 1;
505 } else {
506 go->seen_frame = 0;
507 }
508 }
509 /* Handle any special chunk types, or just write the
510 * start code to the (potentially new) buffer */
511 switch (buf[i]) {
512 case 0xF5: /* timestamp */
513 go->parse_length = 12;
514 go->state = STATE_UNPARSED;
515 break;
516 case 0xF6: /* vbi */
517 go->state = STATE_VBI_LEN_A;
518 break;
519 case 0xF8: /* MD map */
520 go->parse_length = 0;
521 memset(go->active_map, 0,
522 sizeof(go->active_map));
523 go->state = STATE_MODET_MAP;
524 break;
525 case 0xFF: /* Potential JPEG start code */
526 store_byte(go->active_buf, 0x00);
527 store_byte(go->active_buf, 0x00);
528 store_byte(go->active_buf, 0x01);
529 go->state = STATE_FF;
530 break;
531 default:
532 store_byte(go->active_buf, 0x00);
533 store_byte(go->active_buf, 0x00);
534 store_byte(go->active_buf, 0x01);
535 store_byte(go->active_buf, buf[i]);
536 go->state = STATE_DATA;
537 break;
538 }
539 break;
540 case STATE_FF:
541 switch (buf[i]) {
542 case 0x00:
543 store_byte(go->active_buf, 0xFF);
544 go->state = STATE_00;
545 break;
546 case 0xFF:
547 store_byte(go->active_buf, 0xFF);
548 /* go->state remains STATE_FF */
549 break;
550 case 0xD8:
551 if (go->format == GO7007_FORMAT_MJPEG)
552 frame_boundary(go);
553 /* fall through */
554 default:
555 store_byte(go->active_buf, 0xFF);
556 store_byte(go->active_buf, buf[i]);
557 go->state = STATE_DATA;
558 break;
559 }
560 break;
561 case STATE_VBI_LEN_A:
562 go->parse_length = buf[i] << 8;
563 go->state = STATE_VBI_LEN_B;
564 break;
565 case STATE_VBI_LEN_B:
566 go->parse_length |= buf[i];
567 if (go->parse_length > 0)
568 go->state = STATE_UNPARSED;
569 else
570 go->state = STATE_DATA;
571 break;
572 case STATE_MODET_MAP:
573 if (go->parse_length < 204) {
574 if (go->parse_length & 1) {
575 go->modet_word |= buf[i];
576 write_bitmap_word(go);
577 } else
578 go->modet_word = buf[i] << 8;
579 } else if (go->parse_length == 207 && go->active_buf) {
580 go->active_buf->modet_active = buf[i];
581 }
582 if (++go->parse_length == 208)
583 go->state = STATE_DATA;
584 break;
585 case STATE_UNPARSED:
586 if (--go->parse_length == 0)
587 go->state = STATE_DATA;
588 break;
589 }
590 }
591
592 spin_unlock(&go->spinlock);
593}
594EXPORT_SYMBOL(go7007_parse_video_stream);
595
596/*
597 * Allocate a new go7007 struct. Used by the hardware-specific probe.
598 */
599struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
600{
601 struct go7007 *go;
602 int i;
603
604 go = kmalloc(sizeof(struct go7007), GFP_KERNEL);
605 if (go == NULL)
606 return NULL;
607 go->dev = dev;
608 go->board_info = board;
609 go->board_id = 0;
610 go->tuner_type = -1;
611 go->channel_number = 0;
612 go->name[0] = 0;
613 init_MUTEX(&go->hw_lock);
614 init_waitqueue_head(&go->frame_waitq);
615 spin_lock_init(&go->spinlock);
616 go->video_dev = NULL;
617 go->ref_count = 0;
618 go->status = STATUS_INIT;
619 memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
620 go->i2c_adapter_online = 0;
621 go->interrupt_available = 0;
622 init_waitqueue_head(&go->interrupt_waitq);
623 go->in_use = 0;
624 go->input = 0;
625 if (board->sensor_flags & GO7007_SENSOR_TV) {
626 go->standard = GO7007_STD_NTSC;
627 go->width = 720;
628 go->height = 480;
629 go->sensor_framerate = 30000;
630 } else {
631 go->standard = GO7007_STD_OTHER;
632 go->width = board->sensor_width;
633 go->height = board->sensor_height;
634 go->sensor_framerate = board->sensor_framerate;
635 }
636 go->encoder_v_offset = board->sensor_v_offset;
637 go->encoder_h_offset = board->sensor_h_offset;
638 go->encoder_h_halve = 0;
639 go->encoder_v_halve = 0;
640 go->encoder_subsample = 0;
641 go->streaming = 0;
642 go->format = GO7007_FORMAT_MJPEG;
643 go->bitrate = 1500000;
644 go->fps_scale = 1;
645 go->pali = 0;
646 go->aspect_ratio = GO7007_RATIO_1_1;
647 go->gop_size = 0;
648 go->ipb = 0;
649 go->closed_gop = 0;
650 go->repeat_seqhead = 0;
651 go->seq_header_enable = 0;
652 go->gop_header_enable = 0;
653 go->dvd_mode = 0;
654 go->interlace_coding = 0;
655 for (i = 0; i < 4; ++i)
656 go->modet[i].enable = 0;;
657 for (i = 0; i < 1624; ++i)
658 go->modet_map[i] = 0;
659 go->audio_deliver = NULL;
660 go->audio_enabled = 0;
661 INIT_LIST_HEAD(&go->stream);
662
663 return go;
664}
665EXPORT_SYMBOL(go7007_alloc);
666
667/*
668 * Detach and unregister the encoder. The go7007 struct won't be freed
669 * until v4l2 finishes releasing its resources and all associated fds are
670 * closed by applications.
671 */
672void go7007_remove(struct go7007 *go)
673{
674 if (go->i2c_adapter_online) {
675 if (i2c_del_adapter(&go->i2c_adapter) == 0)
676 go->i2c_adapter_online = 0;
677 else
678 printk(KERN_ERR
679 "go7007: error removing I2C adapter!\n");
680 }
681
682 if (go->audio_enabled)
683 go7007_snd_remove(go);
684 go7007_v4l2_remove(go);
685}
686EXPORT_SYMBOL(go7007_remove);
687
688MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/go7007/go7007-fw.c
new file mode 100644
index 00000000000..c2aea1020b0
--- /dev/null
+++ b/drivers/staging/go7007/go7007-fw.c
@@ -0,0 +1,1639 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18/*
19 * This file contains code to generate a firmware image for the GO7007SB
20 * encoder. Much of the firmware is read verbatim from a file, but some of
21 * it concerning bitrate control and other things that can be configured at
22 * run-time are generated dynamically. Note that the format headers
23 * generated here do not affect the functioning of the encoder; they are
24 * merely parroted back to the host at the start of each frame.
25 */
26
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/version.h>
30#include <linux/time.h>
31#include <linux/mm.h>
32#include <linux/device.h>
33#include <linux/i2c.h>
34#include <linux/firmware.h>
35#include <asm/byteorder.h>
36
37#include "go7007-priv.h"
38
39/* Constants used in the source firmware image to describe code segments */
40
41#define FLAG_MODE_MJPEG (1)
42#define FLAG_MODE_MPEG1 (1<<1)
43#define FLAG_MODE_MPEG2 (1<<2)
44#define FLAG_MODE_MPEG4 (1<<3)
45#define FLAG_MODE_H263 (1<<4)
46#define FLAG_MODE_ALL (FLAG_MODE_MJPEG | FLAG_MODE_MPEG1 | \
47 FLAG_MODE_MPEG2 | FLAG_MODE_MPEG4 | \
48 FLAG_MODE_H263)
49#define FLAG_SPECIAL (1<<8)
50
51#define SPECIAL_FRM_HEAD 0
52#define SPECIAL_BRC_CTRL 1
53#define SPECIAL_CONFIG 2
54#define SPECIAL_SEQHEAD 3
55#define SPECIAL_AV_SYNC 4
56#define SPECIAL_FINAL 5
57#define SPECIAL_AUDIO 6
58#define SPECIAL_MODET 7
59
60/* Little data class for creating MPEG headers bit-by-bit */
61
62struct code_gen {
63 unsigned char *p; /* destination */
64 u32 a; /* collects bits at the top of the variable */
65 int b; /* bit position of most recently-written bit */
66 int len; /* written out so far */
67};
68
69#define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 }
70
71#define CODE_ADD(name, val, length) do { \
72 name.b -= (length); \
73 name.a |= (val) << name.b; \
74 while (name.b <= 24) { \
75 *name.p = name.a >> 24; \
76 ++name.p; \
77 name.a <<= 8; \
78 name.b += 8; \
79 name.len += 8; \
80 } \
81} while (0)
82
83#define CODE_LENGTH(name) (name.len + (32 - name.b))
84
85/* Tables for creating the bitrate control data */
86
87static const s16 converge_speed_ip[101] = {
88 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
89 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
90 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
91 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
92 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
93 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
94 5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
95 9, 10, 10, 11, 12, 13, 14, 15, 16, 17,
96 19, 20, 22, 23, 25, 27, 30, 32, 35, 38,
97 41, 45, 49, 53, 58, 63, 69, 76, 83, 91,
98 100
99};
100
101static const s16 converge_speed_ipb[101] = {
102 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
103 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
104 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
105 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
106 6, 6, 6, 7, 7, 7, 7, 8, 8, 9,
107 9, 9, 10, 10, 11, 12, 12, 13, 14, 14,
108 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
109 28, 30, 32, 34, 37, 40, 42, 46, 49, 53,
110 57, 61, 66, 71, 77, 83, 90, 97, 106, 115,
111 125, 135, 147, 161, 175, 191, 209, 228, 249, 273,
112 300
113};
114
115static const s16 LAMBDA_table[4][101] = {
116 { 16, 16, 16, 16, 17, 17, 17, 18, 18, 18,
117 19, 19, 19, 20, 20, 20, 21, 21, 22, 22,
118 22, 23, 23, 24, 24, 25, 25, 25, 26, 26,
119 27, 27, 28, 28, 29, 29, 30, 31, 31, 32,
120 32, 33, 33, 34, 35, 35, 36, 37, 37, 38,
121 39, 39, 40, 41, 42, 42, 43, 44, 45, 46,
122 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
123 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
124 67, 68, 69, 70, 72, 73, 74, 76, 77, 78,
125 80, 81, 83, 84, 86, 87, 89, 90, 92, 94,
126 96
127 },
128 {
129 20, 20, 20, 21, 21, 21, 22, 22, 23, 23,
130 23, 24, 24, 25, 25, 26, 26, 27, 27, 28,
131 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
132 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
133 40, 41, 42, 43, 43, 44, 45, 46, 47, 48,
134 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
135 58, 59, 60, 61, 62, 64, 65, 66, 67, 68,
136 70, 71, 72, 73, 75, 76, 78, 79, 80, 82,
137 83, 85, 86, 88, 90, 91, 93, 95, 96, 98,
138 100, 102, 103, 105, 107, 109, 111, 113, 115, 117,
139 120
140 },
141 {
142 24, 24, 24, 25, 25, 26, 26, 27, 27, 28,
143 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
144 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
145 41, 41, 42, 43, 44, 44, 45, 46, 47, 48,
146 49, 50, 50, 51, 52, 53, 54, 55, 56, 57,
147 58, 59, 60, 62, 63, 64, 65, 66, 67, 69,
148 70, 71, 72, 74, 75, 76, 78, 79, 81, 82,
149 84, 85, 87, 88, 90, 92, 93, 95, 97, 98,
150 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
151 120, 122, 124, 127, 129, 131, 134, 136, 138, 141,
152 144
153 },
154 {
155 32, 32, 33, 33, 34, 34, 35, 36, 36, 37,
156 38, 38, 39, 40, 41, 41, 42, 43, 44, 44,
157 45, 46, 47, 48, 49, 50, 50, 51, 52, 53,
158 54, 55, 56, 57, 58, 59, 60, 62, 63, 64,
159 65, 66, 67, 69, 70, 71, 72, 74, 75, 76,
160 78, 79, 81, 82, 84, 85, 87, 88, 90, 92,
161 93, 95, 97, 98, 100, 102, 104, 106, 108, 110,
162 112, 114, 116, 118, 120, 122, 124, 127, 129, 131,
163 134, 136, 139, 141, 144, 146, 149, 152, 154, 157,
164 160, 163, 166, 169, 172, 175, 178, 181, 185, 188,
165 192
166 }
167};
168
169/* MPEG blank frame generation tables */
170
171enum mpeg_frame_type {
172 PFRAME,
173 BFRAME_PRE,
174 BFRAME_POST,
175 BFRAME_BIDIR,
176 BFRAME_EMPTY
177};
178
179static const u32 addrinctab[33][2] = {
180 { 0x01, 1 }, { 0x03, 3 }, { 0x02, 3 }, { 0x03, 4 },
181 { 0x02, 4 }, { 0x03, 5 }, { 0x02, 5 }, { 0x07, 7 },
182 { 0x06, 7 }, { 0x0b, 8 }, { 0x0a, 8 }, { 0x09, 8 },
183 { 0x08, 8 }, { 0x07, 8 }, { 0x06, 8 }, { 0x17, 10 },
184 { 0x16, 10 }, { 0x15, 10 }, { 0x14, 10 }, { 0x13, 10 },
185 { 0x12, 10 }, { 0x23, 11 }, { 0x22, 11 }, { 0x21, 11 },
186 { 0x20, 11 }, { 0x1f, 11 }, { 0x1e, 11 }, { 0x1d, 11 },
187 { 0x1c, 11 }, { 0x1b, 11 }, { 0x1a, 11 }, { 0x19, 11 },
188 { 0x18, 11 }
189};
190
191/* Standard JPEG tables */
192
193static const u8 default_intra_quant_table[] = {
194 8, 16, 19, 22, 26, 27, 29, 34,
195 16, 16, 22, 24, 27, 29, 34, 37,
196 19, 22, 26, 27, 29, 34, 34, 38,
197 22, 22, 26, 27, 29, 34, 37, 40,
198 22, 26, 27, 29, 32, 35, 40, 48,
199 26, 27, 29, 32, 35, 40, 48, 58,
200 26, 27, 29, 34, 38, 46, 56, 69,
201 27, 29, 35, 38, 46, 56, 69, 83
202};
203
204static const u8 bits_dc_luminance[] = {
205 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
206};
207
208static const u8 val_dc_luminance[] = {
209 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
210};
211
212static const u8 bits_dc_chrominance[] = {
213 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
214};
215
216static const u8 val_dc_chrominance[] = {
217 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
218};
219
220static const u8 bits_ac_luminance[] = {
221 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
222};
223
224static const u8 val_ac_luminance[] = {
225 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
226 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
227 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
228 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
229 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
230 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
231 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
232 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
233 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
234 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
235 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
236 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
237 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
238 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
239 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
240 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
241 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
242 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
243 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
244 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
245 0xf9, 0xfa
246};
247
248static const u8 bits_ac_chrominance[] = {
249 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
250};
251
252static const u8 val_ac_chrominance[] = {
253 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
254 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
255 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
256 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
257 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
258 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
259 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
260 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
261 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
262 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
263 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
264 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
265 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
266 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
267 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
268 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
269 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
270 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
271 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
272 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
273 0xf9, 0xfa
274};
275
276/* Zig-zag mapping for quant table
277 *
278 * OK, let's do this mapping on the actual table above so it doesn't have
279 * to be done on the fly.
280 */
281static const int zz[64] = {
282 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
283 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
284 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
285 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
286};
287
288static int copy_packages(u16 *dest, u16 *src, int pkg_cnt, int space)
289{
290 int i, cnt = pkg_cnt * 32;
291
292 if (space < cnt)
293 return -1;
294
295 for (i = 0; i < cnt; ++i)
296 dest[i] = __cpu_to_le16(src[i]);
297
298 return cnt;
299}
300
301static int mjpeg_frame_header(struct go7007 *go, unsigned char *buf, int q)
302{
303 int i, p = 0;
304
305 buf[p++] = 0xff;
306 buf[p++] = 0xd8;
307 buf[p++] = 0xff;
308 buf[p++] = 0xdb;
309 buf[p++] = 0;
310 buf[p++] = 2 + 65;
311 buf[p++] = 0;
312 buf[p++] = default_intra_quant_table[0];
313 for (i = 1; i < 64; ++i)
314 /* buf[p++] = (default_intra_quant_table[i] * q) >> 3; */
315 buf[p++] = (default_intra_quant_table[zz[i]] * q) >> 3;
316 buf[p++] = 0xff;
317 buf[p++] = 0xc0;
318 buf[p++] = 0;
319 buf[p++] = 17;
320 buf[p++] = 8;
321 buf[p++] = go->height >> 8;
322 buf[p++] = go->height & 0xff;
323 buf[p++] = go->width >> 8;
324 buf[p++] = go->width & 0xff;
325 buf[p++] = 3;
326 buf[p++] = 1;
327 buf[p++] = 0x22;
328 buf[p++] = 0;
329 buf[p++] = 2;
330 buf[p++] = 0x11;
331 buf[p++] = 0;
332 buf[p++] = 3;
333 buf[p++] = 0x11;
334 buf[p++] = 0;
335 buf[p++] = 0xff;
336 buf[p++] = 0xc4;
337 buf[p++] = 418 >> 8;
338 buf[p++] = 418 & 0xff;
339 buf[p++] = 0x00;
340 memcpy(buf + p, bits_dc_luminance + 1, 16);
341 p += 16;
342 memcpy(buf + p, val_dc_luminance, sizeof(val_dc_luminance));
343 p += sizeof(val_dc_luminance);
344 buf[p++] = 0x01;
345 memcpy(buf + p, bits_dc_chrominance + 1, 16);
346 p += 16;
347 memcpy(buf + p, val_dc_chrominance, sizeof(val_dc_chrominance));
348 p += sizeof(val_dc_chrominance);
349 buf[p++] = 0x10;
350 memcpy(buf + p, bits_ac_luminance + 1, 16);
351 p += 16;
352 memcpy(buf + p, val_ac_luminance, sizeof(val_ac_luminance));
353 p += sizeof(val_ac_luminance);
354 buf[p++] = 0x11;
355 memcpy(buf + p, bits_ac_chrominance + 1, 16);
356 p += 16;
357 memcpy(buf + p, val_ac_chrominance, sizeof(val_ac_chrominance));
358 p += sizeof(val_ac_chrominance);
359 buf[p++] = 0xff;
360 buf[p++] = 0xda;
361 buf[p++] = 0;
362 buf[p++] = 12;
363 buf[p++] = 3;
364 buf[p++] = 1;
365 buf[p++] = 0x00;
366 buf[p++] = 2;
367 buf[p++] = 0x11;
368 buf[p++] = 3;
369 buf[p++] = 0x11;
370 buf[p++] = 0;
371 buf[p++] = 63;
372 buf[p++] = 0;
373 return p;
374}
375
376static int gen_mjpeghdr_to_package(struct go7007 *go, u16 *code, int space)
377{
378 u8 *buf;
379 u16 mem = 0x3e00;
380 unsigned int addr = 0x19;
381 int size = 0, i, off = 0, chunk;
382
383 buf = kmalloc(4096, GFP_KERNEL);
384 if (buf == NULL) {
385 printk(KERN_ERR "go7007: unable to allocate 4096 bytes for "
386 "firmware construction\n");
387 return -1;
388 }
389 memset(buf, 0, 4096);
390
391 for (i = 1; i < 32; ++i) {
392 mjpeg_frame_header(go, buf + size, i);
393 size += 80;
394 }
395 chunk = mjpeg_frame_header(go, buf + size, 1);
396 memmove(buf + size, buf + size + 80, chunk - 80);
397 size += chunk - 80;
398
399 for (i = 0; i < size; i += chunk * 2) {
400 if (space - off < 32) {
401 off = -1;
402 goto done;
403 }
404
405 code[off + 1] = __cpu_to_le16(0x8000 | mem);
406
407 chunk = 28;
408 if (mem + chunk > 0x4000)
409 chunk = 0x4000 - mem;
410 if (i + 2 * chunk > size)
411 chunk = (size - i) / 2;
412
413 if (chunk < 28) {
414 code[off] = __cpu_to_le16(0x4000 | chunk);
415 code[off + 31] = __cpu_to_le16(addr++);
416 mem = 0x3e00;
417 } else {
418 code[off] = __cpu_to_le16(0x1000 | 28);
419 code[off + 31] = 0;
420 mem += 28;
421 }
422
423 memcpy(&code[off + 2], buf + i, chunk * 2);
424 off += 32;
425 }
426done:
427 kfree(buf);
428 return off;
429}
430
431static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
432 int modulo, int pict_struct, enum mpeg_frame_type frame)
433{
434 int i, j, mb_code, mb_len;
435 int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
436 CODE_GEN(c, buf + 6);
437
438 switch (frame) {
439 case PFRAME:
440 mb_code = 0x1;
441 mb_len = 3;
442 break;
443 case BFRAME_PRE:
444 mb_code = 0x2;
445 mb_len = 4;
446 break;
447 case BFRAME_POST:
448 mb_code = 0x2;
449 mb_len = 3;
450 break;
451 case BFRAME_BIDIR:
452 mb_code = 0x2;
453 mb_len = 2;
454 break;
455 default: /* keep the compiler happy */
456 mb_code = mb_len = 0;
457 break;
458 }
459
460 CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13);
461 CODE_ADD(c, 0xffff, 16);
462 CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
463 if (frame != PFRAME)
464 CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
465 else
466 CODE_ADD(c, 0, 4); /* Is this supposed to be here?? */
467 CODE_ADD(c, 0, 3); /* What is this?? */
468 /* Byte-align with zeros */
469 j = 8 - (CODE_LENGTH(c) % 8);
470 if (j != 8)
471 CODE_ADD(c, 0, j);
472
473 if (go->format == GO7007_FORMAT_MPEG2) {
474 CODE_ADD(c, 0x1, 24);
475 CODE_ADD(c, 0xb5, 8);
476 CODE_ADD(c, 0x844, 12);
477 CODE_ADD(c, frame == PFRAME ? 0xff : 0x44, 8);
478 if (go->interlace_coding) {
479 CODE_ADD(c, pict_struct, 4);
480 if (go->dvd_mode)
481 CODE_ADD(c, 0x000, 11);
482 else
483 CODE_ADD(c, 0x200, 11);
484 } else {
485 CODE_ADD(c, 0x3, 4);
486 CODE_ADD(c, 0x20c, 11);
487 }
488 /* Byte-align with zeros */
489 j = 8 - (CODE_LENGTH(c) % 8);
490 if (j != 8)
491 CODE_ADD(c, 0, j);
492 }
493
494 for (i = 0; i < rows; ++i) {
495 CODE_ADD(c, 1, 24);
496 CODE_ADD(c, i + 1, 8);
497 CODE_ADD(c, 0x2, 6);
498 CODE_ADD(c, 0x1, 1);
499 CODE_ADD(c, mb_code, mb_len);
500 if (go->interlace_coding) {
501 CODE_ADD(c, 0x1, 2);
502 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
503 }
504 if (frame == BFRAME_BIDIR) {
505 CODE_ADD(c, 0x3, 2);
506 if (go->interlace_coding)
507 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
508 }
509 CODE_ADD(c, 0x3, 2);
510 for (j = (go->width >> 4) - 2; j >= 33; j -= 33)
511 CODE_ADD(c, 0x8, 11);
512 CODE_ADD(c, addrinctab[j][0], addrinctab[j][1]);
513 CODE_ADD(c, mb_code, mb_len);
514 if (go->interlace_coding) {
515 CODE_ADD(c, 0x1, 2);
516 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
517 }
518 if (frame == BFRAME_BIDIR) {
519 CODE_ADD(c, 0x3, 2);
520 if (go->interlace_coding)
521 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
522 }
523 CODE_ADD(c, 0x3, 2);
524
525 /* Byte-align with zeros */
526 j = 8 - (CODE_LENGTH(c) % 8);
527 if (j != 8)
528 CODE_ADD(c, 0, j);
529 }
530
531 i = CODE_LENGTH(c) + 4 * 8;
532 buf[2] = 0x00;
533 buf[3] = 0x00;
534 buf[4] = 0x01;
535 buf[5] = 0x00;
536 return i;
537}
538
539static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
540{
541 int i, aspect_ratio, picture_rate;
542 CODE_GEN(c, buf + 6);
543
544 if (go->format == GO7007_FORMAT_MPEG1) {
545 switch (go->aspect_ratio) {
546 case GO7007_RATIO_4_3:
547 aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
548 break;
549 case GO7007_RATIO_16_9:
550 aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
551 break;
552 default:
553 aspect_ratio = 1;
554 break;
555 }
556 } else {
557 switch (go->aspect_ratio) {
558 case GO7007_RATIO_4_3:
559 aspect_ratio = 2;
560 break;
561 case GO7007_RATIO_16_9:
562 aspect_ratio = 3;
563 break;
564 default:
565 aspect_ratio = 1;
566 break;
567 }
568 }
569 switch (go->sensor_framerate) {
570 case 24000:
571 picture_rate = 1;
572 break;
573 case 24024:
574 picture_rate = 2;
575 break;
576 case 25025:
577 picture_rate = go->interlace_coding ? 6 : 3;
578 break;
579 case 30000:
580 picture_rate = go->interlace_coding ? 7 : 4;
581 break;
582 case 30030:
583 picture_rate = go->interlace_coding ? 8 : 5;
584 break;
585 default:
586 picture_rate = 5; /* 30 fps seems like a reasonable default */
587 break;
588 }
589
590 CODE_ADD(c, go->width, 12);
591 CODE_ADD(c, go->height, 12);
592 CODE_ADD(c, aspect_ratio, 4);
593 CODE_ADD(c, picture_rate, 4);
594 CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 20000 : 0x3ffff, 18);
595 CODE_ADD(c, 1, 1);
596 CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 112 : 20, 10);
597 CODE_ADD(c, 0, 3);
598
599 /* Byte-align with zeros */
600 i = 8 - (CODE_LENGTH(c) % 8);
601 if (i != 8)
602 CODE_ADD(c, 0, i);
603
604 if (go->format == GO7007_FORMAT_MPEG2) {
605 CODE_ADD(c, 0x1, 24);
606 CODE_ADD(c, 0xb5, 8);
607 CODE_ADD(c, 0x148, 12);
608 if (go->interlace_coding)
609 CODE_ADD(c, 0x20001, 20);
610 else
611 CODE_ADD(c, 0xa0001, 20);
612 CODE_ADD(c, 0, 16);
613
614 /* Byte-align with zeros */
615 i = 8 - (CODE_LENGTH(c) % 8);
616 if (i != 8)
617 CODE_ADD(c, 0, i);
618
619 if (ext) {
620 CODE_ADD(c, 0x1, 24);
621 CODE_ADD(c, 0xb52, 12);
622 CODE_ADD(c, go->standard == GO7007_STD_NTSC ? 2 : 1, 3);
623 CODE_ADD(c, 0x105, 9);
624 CODE_ADD(c, 0x505, 16);
625 CODE_ADD(c, go->width, 14);
626 CODE_ADD(c, 1, 1);
627 CODE_ADD(c, go->height, 14);
628
629 /* Byte-align with zeros */
630 i = 8 - (CODE_LENGTH(c) % 8);
631 if (i != 8)
632 CODE_ADD(c, 0, i);
633 }
634 }
635
636 i = CODE_LENGTH(c) + 4 * 8;
637 buf[0] = i & 0xff;
638 buf[1] = i >> 8;
639 buf[2] = 0x00;
640 buf[3] = 0x00;
641 buf[4] = 0x01;
642 buf[5] = 0xb3;
643 return i;
644}
645
646static int gen_mpeg1hdr_to_package(struct go7007 *go,
647 u16 *code, int space, int *framelen)
648{
649 u8 *buf;
650 u16 mem = 0x3e00;
651 unsigned int addr = 0x19;
652 int i, off = 0, chunk;
653
654 buf = kmalloc(5120, GFP_KERNEL);
655 if (buf == NULL) {
656 printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
657 "firmware construction\n");
658 return -1;
659 }
660 memset(buf, 0, 5120);
661 framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME);
662 if (go->interlace_coding)
663 framelen[0] += mpeg1_frame_header(go, buf + framelen[0] / 8,
664 0, 2, PFRAME);
665 buf[0] = framelen[0] & 0xff;
666 buf[1] = framelen[0] >> 8;
667 i = 368;
668 framelen[1] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_PRE);
669 if (go->interlace_coding)
670 framelen[1] += mpeg1_frame_header(go, buf + i + framelen[1] / 8,
671 0, 2, BFRAME_PRE);
672 buf[i] = framelen[1] & 0xff;
673 buf[i + 1] = framelen[1] >> 8;
674 i += 1632;
675 framelen[2] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_POST);
676 if (go->interlace_coding)
677 framelen[2] += mpeg1_frame_header(go, buf + i + framelen[2] / 8,
678 0, 2, BFRAME_POST);
679 buf[i] = framelen[2] & 0xff;
680 buf[i + 1] = framelen[2] >> 8;
681 i += 1432;
682 framelen[3] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_BIDIR);
683 if (go->interlace_coding)
684 framelen[3] += mpeg1_frame_header(go, buf + i + framelen[3] / 8,
685 0, 2, BFRAME_BIDIR);
686 buf[i] = framelen[3] & 0xff;
687 buf[i + 1] = framelen[3] >> 8;
688 i += 1632 + 16;
689 mpeg1_sequence_header(go, buf + i, 0);
690 i += 40;
691 for (i = 0; i < 5120; i += chunk * 2) {
692 if (space - off < 32) {
693 off = -1;
694 goto done;
695 }
696
697 code[off + 1] = __cpu_to_le16(0x8000 | mem);
698
699 chunk = 28;
700 if (mem + chunk > 0x4000)
701 chunk = 0x4000 - mem;
702 if (i + 2 * chunk > 5120)
703 chunk = (5120 - i) / 2;
704
705 if (chunk < 28) {
706 code[off] = __cpu_to_le16(0x4000 | chunk);
707 code[off + 31] = __cpu_to_le16(addr);
708 if (mem + chunk == 0x4000) {
709 mem = 0x3e00;
710 ++addr;
711 }
712 } else {
713 code[off] = __cpu_to_le16(0x1000 | 28);
714 code[off + 31] = 0;
715 mem += 28;
716 }
717
718 memcpy(&code[off + 2], buf + i, chunk * 2);
719 off += 32;
720 }
721done:
722 kfree(buf);
723 return off;
724}
725
726static int vti_bitlen(struct go7007 *go)
727{
728 unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
729
730 for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i);
731 return i + 1;
732}
733
734static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
735 int modulo, enum mpeg_frame_type frame)
736{
737 int i;
738 CODE_GEN(c, buf + 6);
739 int mb_count = (go->width >> 4) * (go->height >> 4);
740
741 CODE_ADD(c, frame == PFRAME ? 0x1 : 0x2, 2);
742 if (modulo)
743 CODE_ADD(c, 0x1, 1);
744 CODE_ADD(c, 0x1, 2);
745 CODE_ADD(c, 0, vti_bitlen(go));
746 CODE_ADD(c, 0x3, 2);
747 if (frame == PFRAME)
748 CODE_ADD(c, 0, 1);
749 CODE_ADD(c, 0xc, 11);
750 if (frame != PFRAME)
751 CODE_ADD(c, 0x4, 3);
752 if (frame != BFRAME_EMPTY) {
753 for (i = 0; i < mb_count; ++i) {
754 switch (frame) {
755 case PFRAME:
756 CODE_ADD(c, 0x1, 1);
757 break;
758 case BFRAME_PRE:
759 CODE_ADD(c, 0x47, 8);
760 break;
761 case BFRAME_POST:
762 CODE_ADD(c, 0x27, 7);
763 break;
764 case BFRAME_BIDIR:
765 CODE_ADD(c, 0x5f, 8);
766 break;
767 case BFRAME_EMPTY: /* keep compiler quiet */
768 break;
769 }
770 }
771 }
772
773 /* Byte-align with a zero followed by ones */
774 i = 8 - (CODE_LENGTH(c) % 8);
775 CODE_ADD(c, 0, 1);
776 CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
777
778 i = CODE_LENGTH(c) + 4 * 8;
779 buf[0] = i & 0xff;
780 buf[1] = i >> 8;
781 buf[2] = 0x00;
782 buf[3] = 0x00;
783 buf[4] = 0x01;
784 buf[5] = 0xb6;
785 return i;
786}
787
788static int mpeg4_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
789{
790 const unsigned char head[] = { 0x00, 0x00, 0x01, 0xb0, go->pali,
791 0x00, 0x00, 0x01, 0xb5, 0x09,
792 0x00, 0x00, 0x01, 0x00,
793 0x00, 0x00, 0x01, 0x20, };
794 int i, aspect_ratio;
795 int fps = go->sensor_framerate / go->fps_scale;
796 CODE_GEN(c, buf + 2 + sizeof(head));
797
798 switch (go->aspect_ratio) {
799 case GO7007_RATIO_4_3:
800 aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
801 break;
802 case GO7007_RATIO_16_9:
803 aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
804 break;
805 default:
806 aspect_ratio = 1;
807 break;
808 }
809
810 memcpy(buf + 2, head, sizeof(head));
811 CODE_ADD(c, 0x191, 17);
812 CODE_ADD(c, aspect_ratio, 4);
813 CODE_ADD(c, 0x1, 4);
814 CODE_ADD(c, fps, 16);
815 CODE_ADD(c, 0x3, 2);
816 CODE_ADD(c, 1001, vti_bitlen(go));
817 CODE_ADD(c, 1, 1);
818 CODE_ADD(c, go->width, 13);
819 CODE_ADD(c, 1, 1);
820 CODE_ADD(c, go->height, 13);
821 CODE_ADD(c, 0x2830, 14);
822
823 /* Byte-align */
824 i = 8 - (CODE_LENGTH(c) % 8);
825 CODE_ADD(c, 0, 1);
826 CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
827
828 i = CODE_LENGTH(c) + sizeof(head) * 8;
829 buf[0] = i & 0xff;
830 buf[1] = i >> 8;
831 return i;
832}
833
834static int gen_mpeg4hdr_to_package(struct go7007 *go,
835 u16 *code, int space, int *framelen)
836{
837 u8 *buf;
838 u16 mem = 0x3e00;
839 unsigned int addr = 0x19;
840 int i, off = 0, chunk;
841
842 buf = kmalloc(5120, GFP_KERNEL);
843 if (buf == NULL) {
844 printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
845 "firmware construction\n");
846 return -1;
847 }
848 memset(buf, 0, 5120);
849 framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME);
850 i = 368;
851 framelen[1] = mpeg4_frame_header(go, buf + i, 0, BFRAME_PRE);
852 i += 1632;
853 framelen[2] = mpeg4_frame_header(go, buf + i, 0, BFRAME_POST);
854 i += 1432;
855 framelen[3] = mpeg4_frame_header(go, buf + i, 0, BFRAME_BIDIR);
856 i += 1632;
857 mpeg4_frame_header(go, buf + i, 0, BFRAME_EMPTY);
858 i += 16;
859 mpeg4_sequence_header(go, buf + i, 0);
860 i += 40;
861 for (i = 0; i < 5120; i += chunk * 2) {
862 if (space - off < 32) {
863 off = -1;
864 goto done;
865 }
866
867 code[off + 1] = __cpu_to_le16(0x8000 | mem);
868
869 chunk = 28;
870 if (mem + chunk > 0x4000)
871 chunk = 0x4000 - mem;
872 if (i + 2 * chunk > 5120)
873 chunk = (5120 - i) / 2;
874
875 if (chunk < 28) {
876 code[off] = __cpu_to_le16(0x4000 | chunk);
877 code[off + 31] = __cpu_to_le16(addr);
878 if (mem + chunk == 0x4000) {
879 mem = 0x3e00;
880 ++addr;
881 }
882 } else {
883 code[off] = __cpu_to_le16(0x1000 | 28);
884 code[off + 31] = 0;
885 mem += 28;
886 }
887
888 memcpy(&code[off + 2], buf + i, chunk * 2);
889 off += 32;
890 }
891 mem = 0x3e00;
892 addr = go->ipb ? 0x14f9 : 0x0af9;
893 memset(buf, 0, 5120);
894 framelen[4] = mpeg4_frame_header(go, buf, 1, PFRAME);
895 i = 368;
896 framelen[5] = mpeg4_frame_header(go, buf + i, 1, BFRAME_PRE);
897 i += 1632;
898 framelen[6] = mpeg4_frame_header(go, buf + i, 1, BFRAME_POST);
899 i += 1432;
900 framelen[7] = mpeg4_frame_header(go, buf + i, 1, BFRAME_BIDIR);
901 i += 1632;
902 mpeg4_frame_header(go, buf + i, 1, BFRAME_EMPTY);
903 i += 16;
904 for (i = 0; i < 5120; i += chunk * 2) {
905 if (space - off < 32) {
906 off = -1;
907 goto done;
908 }
909
910 code[off + 1] = __cpu_to_le16(0x8000 | mem);
911
912 chunk = 28;
913 if (mem + chunk > 0x4000)
914 chunk = 0x4000 - mem;
915 if (i + 2 * chunk > 5120)
916 chunk = (5120 - i) / 2;
917
918 if (chunk < 28) {
919 code[off] = __cpu_to_le16(0x4000 | chunk);
920 code[off + 31] = __cpu_to_le16(addr);
921 if (mem + chunk == 0x4000) {
922 mem = 0x3e00;
923 ++addr;
924 }
925 } else {
926 code[off] = __cpu_to_le16(0x1000 | 28);
927 code[off + 31] = 0;
928 mem += 28;
929 }
930
931 memcpy(&code[off + 2], buf + i, chunk * 2);
932 off += 32;
933 }
934done:
935 kfree(buf);
936 return off;
937}
938
939static int brctrl_to_package(struct go7007 *go,
940 u16 *code, int space, int *framelen)
941{
942 int converge_speed = 0;
943 int lambda = (go->format == GO7007_FORMAT_MJPEG || go->dvd_mode) ?
944 100 : 0;
945 int peak_rate = 6 * go->bitrate / 5;
946 int vbv_buffer = go->format == GO7007_FORMAT_MJPEG ?
947 go->bitrate :
948 (go->dvd_mode ? 900000 : peak_rate);
949 int fps = go->sensor_framerate / go->fps_scale;
950 int q = 0;
951 /* Bizarre math below depends on rounding errors in division */
952 u32 sgop_expt_addr = go->bitrate / 32 * (go->ipb ? 3 : 1) * 1001 / fps;
953 u32 sgop_peak_addr = peak_rate / 32 * 1001 / fps;
954 u32 total_expt_addr = go->bitrate / 32 * 1000 / fps * (fps / 1000);
955 u32 vbv_alert_addr = vbv_buffer * 3 / (4 * 32);
956 u32 cplx[] = {
957 q > 0 ? sgop_expt_addr * q :
958 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
959 q > 0 ? sgop_expt_addr * q :
960 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
961 q > 0 ? sgop_expt_addr * q :
962 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
963 q > 0 ? sgop_expt_addr * q :
964 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
965 };
966 u32 calc_q = q > 0 ? q : cplx[0] / sgop_expt_addr;
967 u16 pack[] = {
968 0x200e, 0x0000,
969 0xBF20, go->ipb ? converge_speed_ipb[converge_speed]
970 : converge_speed_ip[converge_speed],
971 0xBF21, go->ipb ? 2 : 0,
972 0xBF22, go->ipb ? LAMBDA_table[0][lambda / 2 + 50]
973 : 32767,
974 0xBF23, go->ipb ? LAMBDA_table[1][lambda] : 32767,
975 0xBF24, 32767,
976 0xBF25, lambda > 99 ? 32767 : LAMBDA_table[3][lambda],
977 0xBF26, sgop_expt_addr & 0x0000FFFF,
978 0xBF27, sgop_expt_addr >> 16,
979 0xBF28, sgop_peak_addr & 0x0000FFFF,
980 0xBF29, sgop_peak_addr >> 16,
981 0xBF2A, vbv_alert_addr & 0x0000FFFF,
982 0xBF2B, vbv_alert_addr >> 16,
983 0xBF2C, 0,
984 0xBF2D, 0,
985 0, 0,
986
987 0x200e, 0x0000,
988 0xBF2E, vbv_alert_addr & 0x0000FFFF,
989 0xBF2F, vbv_alert_addr >> 16,
990 0xBF30, cplx[0] & 0x0000FFFF,
991 0xBF31, cplx[0] >> 16,
992 0xBF32, cplx[1] & 0x0000FFFF,
993 0xBF33, cplx[1] >> 16,
994 0xBF34, cplx[2] & 0x0000FFFF,
995 0xBF35, cplx[2] >> 16,
996 0xBF36, cplx[3] & 0x0000FFFF,
997 0xBF37, cplx[3] >> 16,
998 0xBF38, 0,
999 0xBF39, 0,
1000 0xBF3A, total_expt_addr & 0x0000FFFF,
1001 0xBF3B, total_expt_addr >> 16,
1002 0, 0,
1003
1004 0x200e, 0x0000,
1005 0xBF3C, total_expt_addr & 0x0000FFFF,
1006 0xBF3D, total_expt_addr >> 16,
1007 0xBF3E, 0,
1008 0xBF3F, 0,
1009 0xBF48, 0,
1010 0xBF49, 0,
1011 0xBF4A, calc_q < 4 ? 4 : (calc_q > 124 ? 124 : calc_q),
1012 0xBF4B, 4,
1013 0xBF4C, 0,
1014 0xBF4D, 0,
1015 0xBF4E, 0,
1016 0xBF4F, 0,
1017 0xBF50, 0,
1018 0xBF51, 0,
1019 0, 0,
1020
1021 0x200e, 0x0000,
1022 0xBF40, sgop_expt_addr & 0x0000FFFF,
1023 0xBF41, sgop_expt_addr >> 16,
1024 0xBF42, 0,
1025 0xBF43, 0,
1026 0xBF44, 0,
1027 0xBF45, 0,
1028 0xBF46, (go->width >> 4) * (go->height >> 4),
1029 0xBF47, 0,
1030 0xBF64, 0,
1031 0xBF65, 0,
1032 0xBF18, framelen[4],
1033 0xBF19, framelen[5],
1034 0xBF1A, framelen[6],
1035 0xBF1B, framelen[7],
1036 0, 0,
1037
1038#if 0 /* Remove once we don't care about matching */
1039 0x200e, 0x0000,
1040 0xBF56, 4,
1041 0xBF57, 0,
1042 0xBF58, 5,
1043 0xBF59, 0,
1044 0xBF5A, 6,
1045 0xBF5B, 0,
1046 0xBF5C, 8,
1047 0xBF5D, 0,
1048 0xBF5E, 1,
1049 0xBF5F, 0,
1050 0xBF60, 1,
1051 0xBF61, 0,
1052 0xBF62, 0,
1053 0xBF63, 0,
1054 0, 0,
1055#else
1056 0x2008, 0x0000,
1057 0xBF56, 4,
1058 0xBF57, 0,
1059 0xBF58, 5,
1060 0xBF59, 0,
1061 0xBF5A, 6,
1062 0xBF5B, 0,
1063 0xBF5C, 8,
1064 0xBF5D, 0,
1065 0, 0,
1066 0, 0,
1067 0, 0,
1068 0, 0,
1069 0, 0,
1070 0, 0,
1071 0, 0,
1072#endif
1073
1074 0x200e, 0x0000,
1075 0xBF10, 0,
1076 0xBF11, 0,
1077 0xBF12, 0,
1078 0xBF13, 0,
1079 0xBF14, 0,
1080 0xBF15, 0,
1081 0xBF16, 0,
1082 0xBF17, 0,
1083 0xBF7E, 0,
1084 0xBF7F, 1,
1085 0xBF52, framelen[0],
1086 0xBF53, framelen[1],
1087 0xBF54, framelen[2],
1088 0xBF55, framelen[3],
1089 0, 0,
1090 };
1091
1092 return copy_packages(code, pack, 6, space);
1093}
1094
1095static int config_package(struct go7007 *go, u16 *code, int space)
1096{
1097 int fps = go->sensor_framerate / go->fps_scale / 1000;
1098 int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
1099 int brc_window_size = fps;
1100 int q_min = 2, q_max = 31;
1101 int THACCoeffSet0 = 0;
1102 u16 pack[] = {
1103 0x200e, 0x0000,
1104 0xc002, 0x14b4,
1105 0xc003, 0x28b4,
1106 0xc004, 0x3c5a,
1107 0xdc05, 0x2a77,
1108 0xc6c3, go->format == GO7007_FORMAT_MPEG4 ? 0 :
1109 (go->format == GO7007_FORMAT_H263 ? 0 : 1),
1110 0xc680, go->format == GO7007_FORMAT_MPEG4 ? 0xf1 :
1111 (go->format == GO7007_FORMAT_H263 ? 0x61 :
1112 0xd3),
1113 0xc780, 0x0140,
1114 0xe009, 0x0001,
1115 0xc60f, 0x0008,
1116 0xd4ff, 0x0002,
1117 0xe403, 2340,
1118 0xe406, 75,
1119 0xd411, 0x0001,
1120 0xd410, 0xa1d6,
1121 0x0001, 0x2801,
1122
1123 0x200d, 0x0000,
1124 0xe402, 0x018b,
1125 0xe401, 0x8b01,
1126 0xd472, (go->board_info->sensor_flags &
1127 GO7007_SENSOR_TV) &&
1128 (!go->interlace_coding) ?
1129 0x01b0 : 0x0170,
1130 0xd475, (go->board_info->sensor_flags &
1131 GO7007_SENSOR_TV) &&
1132 (!go->interlace_coding) ?
1133 0x0008 : 0x0009,
1134 0xc404, go->interlace_coding ? 0x44 :
1135 (go->format == GO7007_FORMAT_MPEG4 ? 0x11 :
1136 (go->format == GO7007_FORMAT_MPEG1 ? 0x02 :
1137 (go->format == GO7007_FORMAT_MPEG2 ? 0x04 :
1138 (go->format == GO7007_FORMAT_H263 ? 0x08 :
1139 0x20)))),
1140 0xbf0a, (go->format == GO7007_FORMAT_MPEG4 ? 8 :
1141 (go->format == GO7007_FORMAT_MPEG1 ? 1 :
1142 (go->format == GO7007_FORMAT_MPEG2 ? 2 :
1143 (go->format == GO7007_FORMAT_H263 ? 4 : 16)))) |
1144 ((go->repeat_seqhead ? 1 : 0) << 6) |
1145 ((go->dvd_mode ? 1 : 0) << 9) |
1146 ((go->gop_header_enable ? 1 : 0) << 10),
1147 0xbf0b, 0,
1148 0xdd5a, go->ipb ? 0x14 : 0x0a,
1149 0xbf0c, 0,
1150 0xbf0d, 0,
1151 0xc683, THACCoeffSet0,
1152 0xc40a, (go->width << 4) | rows,
1153 0xe01a, go->board_info->hpi_buffer_cap,
1154 0, 0,
1155 0, 0,
1156
1157 0x2008, 0,
1158 0xe402, 0x88,
1159 0xe401, 0x8f01,
1160 0xbf6a, 0,
1161 0xbf6b, 0,
1162 0xbf6c, 0,
1163 0xbf6d, 0,
1164 0xbf6e, 0,
1165 0xbf6f, 0,
1166 0, 0,
1167 0, 0,
1168 0, 0,
1169 0, 0,
1170 0, 0,
1171 0, 0,
1172 0, 0,
1173
1174 0x200e, 0,
1175 0xbf66, brc_window_size,
1176 0xbf67, 0,
1177 0xbf68, q_min,
1178 0xbf69, q_max,
1179 0xbfe0, 0,
1180 0xbfe1, 0,
1181 0xbfe2, 0,
1182 0xbfe3, go->ipb ? 3 : 1,
1183 0xc031, go->board_info->sensor_flags &
1184 GO7007_SENSOR_VBI ? 1 : 0,
1185 0xc01c, 0x1f,
1186 0xdd8c, 0x15,
1187 0xdd94, 0x15,
1188 0xdd88, go->ipb ? 0x1401 : 0x0a01,
1189 0xdd90, go->ipb ? 0x1401 : 0x0a01,
1190 0, 0,
1191
1192 0x200e, 0,
1193 0xbfe4, 0,
1194 0xbfe5, 0,
1195 0xbfe6, 0,
1196 0xbfe7, fps << 8,
1197 0xbfe8, 0x3a00,
1198 0xbfe9, 0,
1199 0xbfea, 0,
1200 0xbfeb, 0,
1201 0xbfec, (go->interlace_coding ? 1 << 15 : 0) |
1202 (go->modet_enable ? 0xa : 0) |
1203 (go->board_info->sensor_flags &
1204 GO7007_SENSOR_VBI ? 1 : 0),
1205 0xbfed, 0,
1206 0xbfee, 0,
1207 0xbfef, 0,
1208 0xbff0, go->board_info->sensor_flags &
1209 GO7007_SENSOR_TV ? 0xf060 : 0xb060,
1210 0xbff1, 0,
1211 0, 0,
1212 };
1213
1214 return copy_packages(code, pack, 5, space);
1215}
1216
1217static int seqhead_to_package(struct go7007 *go, u16 *code, int space,
1218 int (*sequence_header_func)(struct go7007 *go,
1219 unsigned char *buf, int ext))
1220{
1221 int vop_time_increment_bitlength = vti_bitlen(go);
1222 int fps = go->sensor_framerate / go->fps_scale *
1223 (go->interlace_coding ? 2 : 1);
1224 unsigned char buf[40] = { };
1225 int len = sequence_header_func(go, buf, 1);
1226 u16 pack[] = {
1227 0x2006, 0,
1228 0xbf08, fps,
1229 0xbf09, 0,
1230 0xbff2, vop_time_increment_bitlength,
1231 0xbff3, (1 << vop_time_increment_bitlength) - 1,
1232 0xbfe6, 0,
1233 0xbfe7, (fps / 1000) << 8,
1234 0, 0,
1235 0, 0,
1236 0, 0,
1237 0, 0,
1238 0, 0,
1239 0, 0,
1240 0, 0,
1241 0, 0,
1242 0, 0,
1243
1244 0x2007, 0,
1245 0xc800, buf[2] << 8 | buf[3],
1246 0xc801, buf[4] << 8 | buf[5],
1247 0xc802, buf[6] << 8 | buf[7],
1248 0xc803, buf[8] << 8 | buf[9],
1249 0xc406, 64,
1250 0xc407, len - 64,
1251 0xc61b, 1,
1252 0, 0,
1253 0, 0,
1254 0, 0,
1255 0, 0,
1256 0, 0,
1257 0, 0,
1258 0, 0,
1259 0, 0,
1260
1261 0x200e, 0,
1262 0xc808, buf[10] << 8 | buf[11],
1263 0xc809, buf[12] << 8 | buf[13],
1264 0xc80a, buf[14] << 8 | buf[15],
1265 0xc80b, buf[16] << 8 | buf[17],
1266 0xc80c, buf[18] << 8 | buf[19],
1267 0xc80d, buf[20] << 8 | buf[21],
1268 0xc80e, buf[22] << 8 | buf[23],
1269 0xc80f, buf[24] << 8 | buf[25],
1270 0xc810, buf[26] << 8 | buf[27],
1271 0xc811, buf[28] << 8 | buf[29],
1272 0xc812, buf[30] << 8 | buf[31],
1273 0xc813, buf[32] << 8 | buf[33],
1274 0xc814, buf[34] << 8 | buf[35],
1275 0xc815, buf[36] << 8 | buf[37],
1276 0, 0,
1277 0, 0,
1278 0, 0,
1279 };
1280
1281 return copy_packages(code, pack, 3, space);
1282}
1283
1284static int relative_prime(int big, int little)
1285{
1286 int remainder;
1287
1288 while (little != 0) {
1289 remainder = big % little;
1290 big = little;
1291 little = remainder;
1292 }
1293 return big;
1294}
1295
1296static int avsync_to_package(struct go7007 *go, u16 *code, int space)
1297{
1298 int arate = go->board_info->audio_rate * 1001 * go->fps_scale;
1299 int ratio = arate / go->sensor_framerate;
1300 int adjratio = ratio * 215 / 100;
1301 int rprime = relative_prime(go->sensor_framerate,
1302 arate % go->sensor_framerate);
1303 int f1 = (arate % go->sensor_framerate) / rprime;
1304 int f2 = (go->sensor_framerate - arate % go->sensor_framerate) / rprime;
1305 u16 pack[] = {
1306 0x200e, 0,
1307 0xbf98, (u16)((-adjratio) & 0xffff),
1308 0xbf99, (u16)((-adjratio) >> 16),
1309 0xbf92, 0,
1310 0xbf93, 0,
1311 0xbff4, f1 > f2 ? f1 : f2,
1312 0xbff5, f1 < f2 ? f1 : f2,
1313 0xbff6, f1 < f2 ? ratio : ratio + 1,
1314 0xbff7, f1 > f2 ? ratio : ratio + 1,
1315 0xbff8, 0,
1316 0xbff9, 0,
1317 0xbffa, adjratio & 0xffff,
1318 0xbffb, adjratio >> 16,
1319 0xbf94, 0,
1320 0xbf95, 0,
1321 0, 0,
1322 };
1323
1324 return copy_packages(code, pack, 1, space);
1325}
1326
1327static int final_package(struct go7007 *go, u16 *code, int space)
1328{
1329 int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
1330 u16 pack[] = {
1331 0x8000,
1332 0,
1333 0,
1334 0,
1335 0,
1336 0,
1337 0,
1338 2,
1339 ((go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
1340 (!go->interlace_coding) ?
1341 (1 << 14) | (1 << 9) : 0) |
1342 ((go->encoder_subsample ? 1 : 0) << 8) |
1343 (go->board_info->sensor_flags &
1344 GO7007_SENSOR_CONFIG_MASK),
1345 ((go->encoder_v_halve ? 1 : 0) << 14) |
1346 (go->encoder_v_halve ? rows << 9 : rows << 8) |
1347 (go->encoder_h_halve ? 1 << 6 : 0) |
1348 (go->encoder_h_halve ? go->width >> 3 : go->width >> 4),
1349 (1 << 15) | (go->encoder_v_offset << 6) |
1350 (1 << 7) | (go->encoder_h_offset >> 2),
1351 (1 << 6),
1352 0,
1353 0,
1354 ((go->fps_scale - 1) << 8) |
1355 (go->board_info->sensor_flags & GO7007_SENSOR_TV ?
1356 (1 << 7) : 0) |
1357 0x41,
1358 go->ipb ? 0xd4c : 0x36b,
1359 (rows << 8) | (go->width >> 4),
1360 go->format == GO7007_FORMAT_MPEG4 ? 0x0404 : 0,
1361 (1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) |
1362 ((go->closed_gop ? 1 : 0) << 12) |
1363 ((go->format == GO7007_FORMAT_MPEG4 ? 1 : 0) << 11) |
1364 /* (1 << 9) | */
1365 ((go->ipb ? 3 : 0) << 7) |
1366 ((go->modet_enable ? 1 : 0) << 2) |
1367 ((go->dvd_mode ? 1 : 0) << 1) | 1,
1368 (go->format == GO7007_FORMAT_MPEG1 ? 0x89a0 :
1369 (go->format == GO7007_FORMAT_MPEG2 ? 0x89a0 :
1370 (go->format == GO7007_FORMAT_MJPEG ? 0x89a0 :
1371 (go->format == GO7007_FORMAT_MPEG4 ? 0x8920 :
1372 (go->format == GO7007_FORMAT_H263 ? 0x8920 : 0))))),
1373 go->ipb ? 0x1f15 : 0x1f0b,
1374 go->ipb ? 0x0015 : 0x000b,
1375 go->ipb ? 0xa800 : 0x5800,
1376 0xffff,
1377 0x0020 + 0x034b * 0,
1378 0x0020 + 0x034b * 1,
1379 0x0020 + 0x034b * 2,
1380 0x0020 + 0x034b * 3,
1381 0x0020 + 0x034b * 4,
1382 0x0020 + 0x034b * 5,
1383 go->ipb ? (go->gop_size / 3) : go->gop_size,
1384 (go->height >> 4) * (go->width >> 4) * 110 / 100,
1385 };
1386
1387 return copy_packages(code, pack, 1, space);
1388}
1389
1390static int audio_to_package(struct go7007 *go, u16 *code, int space)
1391{
1392 int clock_config = ((go->board_info->audio_flags &
1393 GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) |
1394 ((go->board_info->audio_flags &
1395 GO7007_AUDIO_OKI_MODE ? 1 : 0) << 8) |
1396 (((go->board_info->audio_bclk_div / 4) - 1) << 4) |
1397 (go->board_info->audio_main_div - 1);
1398 u16 pack[] = {
1399 0x200d, 0,
1400 0x9002, 0,
1401 0x9002, 0,
1402 0x9031, 0,
1403 0x9032, 0,
1404 0x9033, 0,
1405 0x9034, 0,
1406 0x9035, 0,
1407 0x9036, 0,
1408 0x9037, 0,
1409 0x9040, 0,
1410 0x9000, clock_config,
1411 0x9001, (go->board_info->audio_flags & 0xffff) |
1412 (1 << 9),
1413 0x9000, ((go->board_info->audio_flags &
1414 GO7007_AUDIO_I2S_MASTER ?
1415 1 : 0) << 10) |
1416 clock_config,
1417 0, 0,
1418 0, 0,
1419 0x2005, 0,
1420 0x9041, 0,
1421 0x9042, 256,
1422 0x9043, 0,
1423 0x9044, 16,
1424 0x9045, 16,
1425 0, 0,
1426 0, 0,
1427 0, 0,
1428 0, 0,
1429 0, 0,
1430 0, 0,
1431 0, 0,
1432 0, 0,
1433 0, 0,
1434 0, 0,
1435 };
1436
1437 return copy_packages(code, pack, 2, space);
1438}
1439
1440static int modet_to_package(struct go7007 *go, u16 *code, int space)
1441{
1442 int ret, mb, i, addr, cnt = 0;
1443 u16 pack[32];
1444 u16 thresholds[] = {
1445 0x200e, 0,
1446 0xbf82, go->modet[0].pixel_threshold,
1447 0xbf83, go->modet[1].pixel_threshold,
1448 0xbf84, go->modet[2].pixel_threshold,
1449 0xbf85, go->modet[3].pixel_threshold,
1450 0xbf86, go->modet[0].motion_threshold,
1451 0xbf87, go->modet[1].motion_threshold,
1452 0xbf88, go->modet[2].motion_threshold,
1453 0xbf89, go->modet[3].motion_threshold,
1454 0xbf8a, go->modet[0].mb_threshold,
1455 0xbf8b, go->modet[1].mb_threshold,
1456 0xbf8c, go->modet[2].mb_threshold,
1457 0xbf8d, go->modet[3].mb_threshold,
1458 0xbf8e, 0,
1459 0xbf8f, 0,
1460 0, 0,
1461 };
1462
1463 ret = copy_packages(code, thresholds, 1, space);
1464 if (ret < 0)
1465 return -1;
1466 cnt += ret;
1467
1468 addr = 0xbac0;
1469 memset(pack, 0, 64);
1470 i = 0;
1471 for (mb = 0; mb < 1624; ++mb) {
1472 pack[i * 2 + 3] <<= 2;
1473 pack[i * 2 + 3] |= go->modet_map[mb];
1474 if (mb % 8 != 7)
1475 continue;
1476 pack[i * 2 + 2] = addr++;
1477 ++i;
1478 if (i == 10 || mb == 1623) {
1479 pack[0] = 0x2000 | i;
1480 ret = copy_packages(code + cnt, pack, 1, space - cnt);
1481 if (ret < 0)
1482 return -1;
1483 cnt += ret;
1484 i = 0;
1485 memset(pack, 0, 64);
1486 }
1487 pack[i * 2 + 3] = 0;
1488 }
1489
1490 memset(pack, 0, 64);
1491 i = 0;
1492 for (addr = 0xbb90; addr < 0xbbfa; ++addr) {
1493 pack[i * 2 + 2] = addr;
1494 pack[i * 2 + 3] = 0;
1495 ++i;
1496 if (i == 10 || addr == 0xbbf9) {
1497 pack[0] = 0x2000 | i;
1498 ret = copy_packages(code + cnt, pack, 1, space - cnt);
1499 if (ret < 0)
1500 return -1;
1501 cnt += ret;
1502 i = 0;
1503 memset(pack, 0, 64);
1504 }
1505 }
1506 return cnt;
1507}
1508
1509static int do_special(struct go7007 *go, u16 type, u16 *code, int space,
1510 int *framelen)
1511{
1512 switch (type) {
1513 case SPECIAL_FRM_HEAD:
1514 switch (go->format) {
1515 case GO7007_FORMAT_MJPEG:
1516 return gen_mjpeghdr_to_package(go, code, space);
1517 case GO7007_FORMAT_MPEG1:
1518 case GO7007_FORMAT_MPEG2:
1519 return gen_mpeg1hdr_to_package(go, code, space,
1520 framelen);
1521 case GO7007_FORMAT_MPEG4:
1522 return gen_mpeg4hdr_to_package(go, code, space,
1523 framelen);
1524 }
1525 case SPECIAL_BRC_CTRL:
1526 return brctrl_to_package(go, code, space, framelen);
1527 case SPECIAL_CONFIG:
1528 return config_package(go, code, space);
1529 case SPECIAL_SEQHEAD:
1530 switch (go->format) {
1531 case GO7007_FORMAT_MPEG1:
1532 case GO7007_FORMAT_MPEG2:
1533 return seqhead_to_package(go, code, space,
1534 mpeg1_sequence_header);
1535 case GO7007_FORMAT_MPEG4:
1536 return seqhead_to_package(go, code, space,
1537 mpeg4_sequence_header);
1538 default:
1539 return 0;
1540 }
1541 case SPECIAL_AV_SYNC:
1542 return avsync_to_package(go, code, space);
1543 case SPECIAL_FINAL:
1544 return final_package(go, code, space);
1545 case SPECIAL_AUDIO:
1546 return audio_to_package(go, code, space);
1547 case SPECIAL_MODET:
1548 return modet_to_package(go, code, space);
1549 }
1550 printk(KERN_ERR
1551 "go7007: firmware file contains unsupported feature %04x\n",
1552 type);
1553 return -1;
1554}
1555
1556int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
1557{
1558 const struct firmware *fw_entry;
1559 u16 *code, *src;
1560 int framelen[8] = { }; /* holds the lengths of empty frame templates */
1561 int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags;
1562 int mode_flag;
1563 int ret;
1564
1565 switch (go->format) {
1566 case GO7007_FORMAT_MJPEG:
1567 mode_flag = FLAG_MODE_MJPEG;
1568 break;
1569 case GO7007_FORMAT_MPEG1:
1570 mode_flag = FLAG_MODE_MPEG1;
1571 break;
1572 case GO7007_FORMAT_MPEG2:
1573 mode_flag = FLAG_MODE_MPEG2;
1574 break;
1575 case GO7007_FORMAT_MPEG4:
1576 mode_flag = FLAG_MODE_MPEG4;
1577 break;
1578 default:
1579 return -1;
1580 }
1581 if (request_firmware(&fw_entry, go->board_info->firmware, go->dev)) {
1582 printk(KERN_ERR
1583 "go7007: unable to load firmware from file \"%s\"\n",
1584 go->board_info->firmware);
1585 return -1;
1586 }
1587 code = kmalloc(codespace * 2, GFP_KERNEL);
1588 if (code == NULL) {
1589 printk(KERN_ERR "go7007: unable to allocate %d bytes for "
1590 "firmware construction\n", codespace * 2);
1591 goto fw_failed;
1592 }
1593 memset(code, 0, codespace * 2);
1594 src = (u16 *)fw_entry->data;
1595 srclen = fw_entry->size / 2;
1596 while (srclen >= 2) {
1597 chunk_flags = __le16_to_cpu(src[0]);
1598 chunk_len = __le16_to_cpu(src[1]);
1599 if (chunk_len + 2 > srclen) {
1600 printk(KERN_ERR "go7007: firmware file \"%s\" "
1601 "appears to be corrupted\n",
1602 go->board_info->firmware);
1603 goto fw_failed;
1604 }
1605 if (chunk_flags & mode_flag) {
1606 if (chunk_flags & FLAG_SPECIAL) {
1607 ret = do_special(go, __le16_to_cpu(src[2]),
1608 &code[i], codespace - i, framelen);
1609 if (ret < 0) {
1610 printk(KERN_ERR "go7007: insufficient "
1611 "memory for firmware "
1612 "construction\n");
1613 goto fw_failed;
1614 }
1615 i += ret;
1616 } else {
1617 if (codespace - i < chunk_len) {
1618 printk(KERN_ERR "go7007: insufficient "
1619 "memory for firmware "
1620 "construction\n");
1621 goto fw_failed;
1622 }
1623 memcpy(&code[i], &src[2], chunk_len * 2);
1624 i += chunk_len;
1625 }
1626 }
1627 srclen -= chunk_len + 2;
1628 src += chunk_len + 2;
1629 }
1630 release_firmware(fw_entry);
1631 *fw = (u8 *)code;
1632 *fwlen = i * 2;
1633 return 0;
1634
1635fw_failed:
1636 kfree(code);
1637 release_firmware(fw_entry);
1638 return -1;
1639}
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c
new file mode 100644
index 00000000000..10baae3dade
--- /dev/null
+++ b/drivers/staging/go7007/go7007-i2c.c
@@ -0,0 +1,309 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/version.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/sched.h>
23#include <linux/list.h>
24#include <linux/unistd.h>
25#include <linux/time.h>
26#include <linux/device.h>
27#include <linux/i2c.h>
28#include <linux/semaphore.h>
29#include <linux/uaccess.h>
30#include <asm/system.h>
31
32#include "go7007-priv.h"
33#include "wis-i2c.h"
34
35/************** Registration interface for I2C client drivers **************/
36
37/* Since there's no way to auto-probe the I2C devices connected to the I2C
38 * bus on the go7007, we have this silly little registration system that
39 * client drivers can use to register their I2C driver ID and their
40 * detect_client function (the one that's normally passed to i2c_probe).
41 *
42 * When a new go7007 device is connected, we can look up in a board info
43 * table by the USB or PCI vendor/product/revision ID to determine
44 * which I2C client module to load. The client driver module will register
45 * itself here, and then we can call the registered detect_client function
46 * to force-load a new client at the address listed in the board info table.
47 *
48 * Really the I2C subsystem should have a way to force-load I2C client
49 * drivers when we have a priori knowledge of what's on the bus, especially
50 * since the existing I2C auto-probe mechanism is so hokey, but we'll use
51 * our own mechanism for the time being. */
52
53struct wis_i2c_client_driver {
54 unsigned int id;
55 found_proc found_proc;
56 struct list_head list;
57};
58
59static LIST_HEAD(i2c_client_drivers);
60static DECLARE_MUTEX(i2c_client_driver_list_lock);
61
62/* Client drivers register here by their I2C driver ID */
63int wis_i2c_add_driver(unsigned int id, found_proc found_proc)
64{
65 struct wis_i2c_client_driver *driver;
66
67 driver = kmalloc(sizeof(struct wis_i2c_client_driver), GFP_KERNEL);
68 if (driver == NULL)
69 return -ENOMEM;
70 driver->id = id;
71 driver->found_proc = found_proc;
72
73 down(&i2c_client_driver_list_lock);
74 list_add_tail(&driver->list, &i2c_client_drivers);
75 up(&i2c_client_driver_list_lock);
76
77 return 0;
78}
79EXPORT_SYMBOL(wis_i2c_add_driver);
80
81void wis_i2c_del_driver(found_proc found_proc)
82{
83 struct wis_i2c_client_driver *driver, *next;
84
85 down(&i2c_client_driver_list_lock);
86 list_for_each_entry_safe(driver, next, &i2c_client_drivers, list)
87 if (driver->found_proc == found_proc) {
88 list_del(&driver->list);
89 kfree(driver);
90 }
91 up(&i2c_client_driver_list_lock);
92}
93EXPORT_SYMBOL(wis_i2c_del_driver);
94
95/* The main go7007 driver calls this to instantiate a client by driver
96 * ID and bus address, which are both stored in the board info table */
97int wis_i2c_probe_device(struct i2c_adapter *adapter,
98 unsigned int id, int addr)
99{
100 struct wis_i2c_client_driver *driver;
101 int found = 0;
102
103 if (addr < 0 || addr > 0x7f)
104 return -1;
105 down(&i2c_client_driver_list_lock);
106 list_for_each_entry(driver, &i2c_client_drivers, list)
107 if (driver->id == id) {
108 if (driver->found_proc(adapter, addr, 0) == 0)
109 found = 1;
110 break;
111 }
112 up(&i2c_client_driver_list_lock);
113 return found;
114}
115
116/********************* Driver for on-board I2C adapter *********************/
117
118/* #define GO7007_I2C_DEBUG */
119
120#define SPI_I2C_ADDR_BASE 0x1400
121#define STATUS_REG_ADDR (SPI_I2C_ADDR_BASE + 0x2)
122#define I2C_CTRL_REG_ADDR (SPI_I2C_ADDR_BASE + 0x6)
123#define I2C_DEV_UP_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x7)
124#define I2C_LO_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x8)
125#define I2C_DATA_REG_ADDR (SPI_I2C_ADDR_BASE + 0x9)
126#define I2C_CLKFREQ_REG_ADDR (SPI_I2C_ADDR_BASE + 0xa)
127
128#define I2C_STATE_MASK 0x0007
129#define I2C_READ_READY_MASK 0x0008
130
131/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
132 * on the Adlink PCI-MPG24, so access is shared between all of them. */
133static DECLARE_MUTEX(adlink_mpg24_i2c_lock);
134
135static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
136 u16 command, int flags, u8 *data)
137{
138 int i, ret = -1;
139 u16 val;
140
141 if (go->status == STATUS_SHUTDOWN)
142 return -1;
143
144#ifdef GO7007_I2C_DEBUG
145 if (read)
146 printk(KERN_DEBUG "go7007-i2c: reading 0x%02x on 0x%02x\n",
147 command, addr);
148 else
149 printk(KERN_DEBUG
150 "go7007-i2c: writing 0x%02x to 0x%02x on 0x%02x\n",
151 *data, command, addr);
152#endif
153
154 down(&go->hw_lock);
155
156 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
157 /* Bridge the I2C port on this GO7007 to the shared bus */
158 down(&adlink_mpg24_i2c_lock);
159 go7007_write_addr(go, 0x3c82, 0x0020);
160 }
161
162 /* Wait for I2C adapter to be ready */
163 for (i = 0; i < 10; ++i) {
164 if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
165 goto i2c_done;
166 if (!(val & I2C_STATE_MASK))
167 break;
168 msleep(100);
169 }
170 if (i == 10) {
171 printk(KERN_ERR "go7007-i2c: I2C adapter is hung\n");
172 goto i2c_done;
173 }
174
175 /* Set target register (command) */
176 go7007_write_addr(go, I2C_CTRL_REG_ADDR, flags);
177 go7007_write_addr(go, I2C_LO_ADDR_REG_ADDR, command);
178
179 /* If we're writing, send the data and target address and we're done */
180 if (!read) {
181 go7007_write_addr(go, I2C_DATA_REG_ADDR, *data);
182 go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
183 (addr << 9) | (command >> 8));
184 ret = 0;
185 goto i2c_done;
186 }
187
188 /* Otherwise, we're reading. First clear i2c_rx_data_rdy. */
189 if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
190 goto i2c_done;
191
192 /* Send the target address plus read flag */
193 go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
194 (addr << 9) | 0x0100 | (command >> 8));
195
196 /* Wait for i2c_rx_data_rdy */
197 for (i = 0; i < 10; ++i) {
198 if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
199 goto i2c_done;
200 if (val & I2C_READ_READY_MASK)
201 break;
202 msleep(100);
203 }
204 if (i == 10) {
205 printk(KERN_ERR "go7007-i2c: I2C adapter is hung\n");
206 goto i2c_done;
207 }
208
209 /* Retrieve the read byte */
210 if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
211 goto i2c_done;
212 *data = val;
213 ret = 0;
214
215i2c_done:
216 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
217 /* Isolate the I2C port on this GO7007 from the shared bus */
218 go7007_write_addr(go, 0x3c82, 0x0000);
219 up(&adlink_mpg24_i2c_lock);
220 }
221 up(&go->hw_lock);
222 return ret;
223}
224
225static int go7007_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
226 unsigned short flags, char read_write,
227 u8 command, int size, union i2c_smbus_data *data)
228{
229 struct go7007 *go = i2c_get_adapdata(adapter);
230
231 if (size != I2C_SMBUS_BYTE_DATA)
232 return -1;
233 return go7007_i2c_xfer(go, addr, read_write == I2C_SMBUS_READ, command,
234 flags & I2C_CLIENT_SCCB ? 0x10 : 0x00, &data->byte);
235}
236
237/* VERY LIMITED I2C master xfer function -- only needed because the
238 * SMBus functions only support 8-bit commands and the SAA7135 uses
239 * 16-bit commands. The I2C interface on the GO7007, as limited as
240 * it is, does support this mode. */
241
242static int go7007_i2c_master_xfer(struct i2c_adapter *adapter,
243 struct i2c_msg msgs[], int num)
244{
245 struct go7007 *go = i2c_get_adapdata(adapter);
246 int i;
247
248 for (i = 0; i < num; ++i) {
249 /* We can only do two things here -- write three bytes, or
250 * write two bytes and read one byte. */
251 if (msgs[i].len == 2) {
252 if (i + 1 == num || msgs[i].addr != msgs[i + 1].addr ||
253 (msgs[i].flags & I2C_M_RD) ||
254 !(msgs[i + 1].flags & I2C_M_RD) ||
255 msgs[i + 1].len != 1)
256 return -1;
257 if (go7007_i2c_xfer(go, msgs[i].addr, 1,
258 (msgs[i].buf[0] << 8) | msgs[i].buf[1],
259 0x01, &msgs[i + 1].buf[0]) < 0)
260 return -1;
261 ++i;
262 } else if (msgs[i].len == 3) {
263 if (msgs[i].flags & I2C_M_RD)
264 return -1;
265 if (msgs[i].len != 3)
266 return -1;
267 if (go7007_i2c_xfer(go, msgs[i].addr, 0,
268 (msgs[i].buf[0] << 8) | msgs[i].buf[1],
269 0x01, &msgs[i].buf[2]) < 0)
270 return -1;
271 } else
272 return -1;
273 }
274
275 return 0;
276}
277
278static u32 go7007_functionality(struct i2c_adapter *adapter)
279{
280 return I2C_FUNC_SMBUS_BYTE_DATA;
281}
282
283static struct i2c_algorithm go7007_algo = {
284 .smbus_xfer = go7007_smbus_xfer,
285 .master_xfer = go7007_i2c_master_xfer,
286 .functionality = go7007_functionality,
287};
288
289static struct i2c_adapter go7007_adap_templ = {
290 .owner = THIS_MODULE,
291 .class = I2C_CLASS_TV_ANALOG,
292 .name = "WIS GO7007SB",
293 .id = I2C_ALGO_GO7007,
294 .algo = &go7007_algo,
295};
296
297int go7007_i2c_init(struct go7007 *go)
298{
299 memcpy(&go->i2c_adapter, &go7007_adap_templ,
300 sizeof(go7007_adap_templ));
301 go->i2c_adapter.dev.parent = go->dev;
302 i2c_set_adapdata(&go->i2c_adapter, go);
303 if (i2c_add_adapter(&go->i2c_adapter) < 0) {
304 printk(KERN_ERR
305 "go7007-i2c: error: i2c_add_adapter failed\n");
306 return -1;
307 }
308 return 0;
309}
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
new file mode 100644
index 00000000000..005542d16a5
--- /dev/null
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -0,0 +1,279 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18/*
19 * This is the private include file for the go7007 driver. It should not
20 * be included by anybody but the driver itself, and especially not by
21 * user-space applications.
22 */
23
24struct go7007;
25
26/* IDs to activate board-specific support code */
27#define GO7007_BOARDID_MATRIX_II 0
28#define GO7007_BOARDID_MATRIX_RELOAD 1
29#define GO7007_BOARDID_STAR_TREK 2
30#define GO7007_BOARDID_PCI_VOYAGER 3
31#define GO7007_BOARDID_XMEN 4
32#define GO7007_BOARDID_XMEN_II 5
33#define GO7007_BOARDID_XMEN_III 6
34#define GO7007_BOARDID_MATRIX_REV 7
35#define GO7007_BOARDID_PX_M402U 16
36#define GO7007_BOARDID_PX_TV402U_ANY 17 /* need to check tuner model */
37#define GO7007_BOARDID_PX_TV402U_NA 18 /* detected NTSC tuner */
38#define GO7007_BOARDID_PX_TV402U_EU 19 /* detected PAL tuner */
39#define GO7007_BOARDID_PX_TV402U_JP 20 /* detected NTSC-J tuner */
40#define GO7007_BOARDID_LIFEVIEW_LR192 21 /* TV Walker Ultra */
41#define GO7007_BOARDID_ENDURA 22
42#define GO7007_BOARDID_ADLINK_MPG24 23
43
44/* Various characteristics of each board */
45#define GO7007_BOARD_HAS_AUDIO (1<<0)
46#define GO7007_BOARD_USE_ONBOARD_I2C (1<<1)
47#define GO7007_BOARD_HAS_TUNER (1<<2)
48
49/* Characteristics of sensor devices */
50#define GO7007_SENSOR_VALID_POLAR (1<<0)
51#define GO7007_SENSOR_HREF_POLAR (1<<1)
52#define GO7007_SENSOR_VREF_POLAR (1<<2)
53#define GO7007_SENSOR_FIELD_ID_POLAR (1<<3)
54#define GO7007_SENSOR_BIT_WIDTH (1<<4)
55#define GO7007_SENSOR_VALID_ENABLE (1<<5)
56#define GO7007_SENSOR_656 (1<<6)
57#define GO7007_SENSOR_CONFIG_MASK 0x7f
58#define GO7007_SENSOR_TV (1<<7)
59#define GO7007_SENSOR_VBI (1<<8)
60#define GO7007_SENSOR_SCALING (1<<9)
61
62/* Characteristics of audio sensor devices */
63#define GO7007_AUDIO_I2S_MODE_1 (1)
64#define GO7007_AUDIO_I2S_MODE_2 (2)
65#define GO7007_AUDIO_I2S_MODE_3 (3)
66#define GO7007_AUDIO_BCLK_POLAR (1<<2)
67#define GO7007_AUDIO_WORD_14 (14<<4)
68#define GO7007_AUDIO_WORD_16 (16<<4)
69#define GO7007_AUDIO_ONE_CHANNEL (1<<11)
70#define GO7007_AUDIO_I2S_MASTER (1<<16)
71#define GO7007_AUDIO_OKI_MODE (1<<17)
72
73struct go7007_board_info {
74 char *firmware;
75 unsigned int flags;
76 int hpi_buffer_cap;
77 unsigned int sensor_flags;
78 int sensor_width;
79 int sensor_height;
80 int sensor_framerate;
81 int sensor_h_offset;
82 int sensor_v_offset;
83 unsigned int audio_flags;
84 int audio_rate;
85 int audio_bclk_div;
86 int audio_main_div;
87 int num_i2c_devs;
88 struct {
89 int id;
90 int addr;
91 } i2c_devs[4];
92 int num_inputs;
93 struct {
94 int video_input;
95 int audio_input;
96 char *name;
97 } inputs[4];
98};
99
100struct go7007_hpi_ops {
101 int (*interface_reset)(struct go7007 *go);
102 int (*write_interrupt)(struct go7007 *go, int addr, int data);
103 int (*read_interrupt)(struct go7007 *go);
104 int (*stream_start)(struct go7007 *go);
105 int (*stream_stop)(struct go7007 *go);
106 int (*send_firmware)(struct go7007 *go, u8 *data, int len);
107};
108
109/* The video buffer size must be a multiple of PAGE_SIZE */
110#define GO7007_BUF_PAGES (128 * 1024 / PAGE_SIZE)
111#define GO7007_BUF_SIZE (GO7007_BUF_PAGES << PAGE_SHIFT)
112
113struct go7007_buffer {
114 struct go7007 *go; /* Reverse reference for VMA ops */
115 int index; /* Reverse reference for DQBUF */
116 enum { BUF_STATE_IDLE, BUF_STATE_QUEUED, BUF_STATE_DONE } state;
117 u32 seq;
118 struct timeval timestamp;
119 struct list_head stream;
120 struct page *pages[GO7007_BUF_PAGES + 1]; /* extra for straddling */
121 unsigned long user_addr;
122 unsigned int page_count;
123 unsigned int offset;
124 unsigned int bytesused;
125 unsigned int frame_offset;
126 u32 modet_active;
127 int mapped;
128};
129
130struct go7007_file {
131 struct go7007 *go;
132 struct semaphore lock;
133 int buf_count;
134 struct go7007_buffer *bufs;
135};
136
137#define GO7007_FORMAT_MJPEG 0
138#define GO7007_FORMAT_MPEG4 1
139#define GO7007_FORMAT_MPEG1 2
140#define GO7007_FORMAT_MPEG2 3
141#define GO7007_FORMAT_H263 4
142
143#define GO7007_RATIO_1_1 0
144#define GO7007_RATIO_4_3 1
145#define GO7007_RATIO_16_9 2
146
147enum go7007_parser_state {
148 STATE_DATA,
149 STATE_00,
150 STATE_00_00,
151 STATE_00_00_01,
152 STATE_FF,
153 STATE_VBI_LEN_A,
154 STATE_VBI_LEN_B,
155 STATE_MODET_MAP,
156 STATE_UNPARSED,
157};
158
159struct go7007 {
160 struct device *dev;
161 struct go7007_board_info *board_info;
162 unsigned int board_id;
163 int tuner_type;
164 int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
165 char name[64];
166 struct video_device *video_dev;
167 int ref_count;
168 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
169 spinlock_t spinlock;
170 struct semaphore hw_lock;
171 int streaming;
172 int in_use;
173 int audio_enabled;
174
175 /* Video input */
176 int input;
177 enum { GO7007_STD_NTSC, GO7007_STD_PAL, GO7007_STD_OTHER } standard;
178 int sensor_framerate;
179 int width;
180 int height;
181 int encoder_h_offset;
182 int encoder_v_offset;
183 unsigned int encoder_h_halve:1;
184 unsigned int encoder_v_halve:1;
185 unsigned int encoder_subsample:1;
186
187 /* Encoder config */
188 int format;
189 int bitrate;
190 int fps_scale;
191 int pali;
192 int aspect_ratio;
193 int gop_size;
194 unsigned int ipb:1;
195 unsigned int closed_gop:1;
196 unsigned int repeat_seqhead:1;
197 unsigned int seq_header_enable:1;
198 unsigned int gop_header_enable:1;
199 unsigned int dvd_mode:1;
200 unsigned int interlace_coding:1;
201
202 /* Motion detection */
203 unsigned int modet_enable:1;
204 struct {
205 unsigned int enable:1;
206 int pixel_threshold;
207 int motion_threshold;
208 int mb_threshold;
209 } modet[4];
210 unsigned char modet_map[1624];
211 unsigned char active_map[216];
212
213 /* Video streaming */
214 struct go7007_buffer *active_buf;
215 enum go7007_parser_state state;
216 int parse_length;
217 u16 modet_word;
218 int seen_frame;
219 u32 next_seq;
220 struct list_head stream;
221 wait_queue_head_t frame_waitq;
222
223 /* Audio streaming */
224 void (*audio_deliver)(struct go7007 *go, u8 *buf, int length);
225 void *snd_context;
226
227 /* I2C */
228 int i2c_adapter_online;
229 struct i2c_adapter i2c_adapter;
230
231 /* HPI driver */
232 struct go7007_hpi_ops *hpi_ops;
233 void *hpi_context;
234 int interrupt_available;
235 wait_queue_head_t interrupt_waitq;
236 unsigned short interrupt_value;
237 unsigned short interrupt_data;
238};
239
240/* All of these must be called with the hpi_lock semaphore held! */
241#define go7007_interface_reset(go) \
242 ((go)->hpi_ops->interface_reset(go))
243#define go7007_write_interrupt(go, x, y) \
244 ((go)->hpi_ops->write_interrupt)((go), (x), (y))
245#define go7007_stream_start(go) \
246 ((go)->hpi_ops->stream_start(go))
247#define go7007_stream_stop(go) \
248 ((go)->hpi_ops->stream_stop(go))
249#define go7007_send_firmware(go, x, y) \
250 ((go)->hpi_ops->send_firmware)((go), (x), (y))
251#define go7007_write_addr(go, x, y) \
252 ((go)->hpi_ops->write_interrupt)((go), (x)|0x8000, (y))
253
254/* go7007-driver.c */
255int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data);
256int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data);
257int go7007_boot_encoder(struct go7007 *go, int init_i2c);
258int go7007_reset_encoder(struct go7007 *go);
259int go7007_register_encoder(struct go7007 *go);
260int go7007_start_encoder(struct go7007 *go);
261void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length);
262struct go7007 *go7007_alloc(struct go7007_board_info *board,
263 struct device *dev);
264void go7007_remove(struct go7007 *go);
265
266/* go7007-fw.c */
267int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen);
268
269/* go7007-i2c.c */
270int go7007_i2c_init(struct go7007 *go);
271int go7007_i2c_remove(struct go7007 *go);
272
273/* go7007-v4l2.c */
274int go7007_v4l2_init(struct go7007 *go);
275void go7007_v4l2_remove(struct go7007 *go);
276
277/* snd-go7007.c */
278int go7007_snd_init(struct go7007 *go);
279int go7007_snd_remove(struct go7007 *go);
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
new file mode 100644
index 00000000000..d4ed6d2b715
--- /dev/null
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -0,0 +1,1229 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/version.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/wait.h>
23#include <linux/list.h>
24#include <linux/slab.h>
25#include <linux/time.h>
26#include <linux/mm.h>
27#include <linux/usb.h>
28#include <linux/i2c.h>
29#include <asm/byteorder.h>
30#include <media/tvaudio.h>
31
32#include "go7007-priv.h"
33#include "wis-i2c.h"
34
35static unsigned int assume_endura;
36module_param(assume_endura, int, 0644);
37MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura");
38
39/* #define GO7007_USB_DEBUG */
40/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
41
42#define HPI_STATUS_ADDR 0xFFF4
43#define INT_PARAM_ADDR 0xFFF6
44#define INT_INDEX_ADDR 0xFFF8
45
46/*
47 * Pipes on EZ-USB interface:
48 * 0 snd - Control
49 * 0 rcv - Control
50 * 2 snd - Download firmware (control)
51 * 4 rcv - Read Interrupt (interrupt)
52 * 6 rcv - Read Video (bulk)
53 * 8 rcv - Read Audio (bulk)
54 */
55
56#define GO7007_USB_EZUSB (1<<0)
57#define GO7007_USB_EZUSB_I2C (1<<1)
58
59struct go7007_usb_board {
60 unsigned int flags;
61 struct go7007_board_info main_info;
62};
63
64struct go7007_usb {
65 struct go7007_usb_board *board;
66 struct semaphore i2c_lock;
67 struct usb_device *usbdev;
68 struct urb *video_urbs[8];
69 struct urb *audio_urbs[8];
70 struct urb *intr_urb;
71};
72
73/*********************** Product specification data ***********************/
74
75static struct go7007_usb_board board_matrix_ii = {
76 .flags = GO7007_USB_EZUSB,
77 .main_info = {
78 .firmware = "go7007tv.bin",
79 .flags = GO7007_BOARD_HAS_AUDIO |
80 GO7007_BOARD_USE_ONBOARD_I2C,
81 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
82 GO7007_AUDIO_WORD_16,
83 .audio_rate = 48000,
84 .audio_bclk_div = 8,
85 .audio_main_div = 2,
86 .hpi_buffer_cap = 7,
87 .sensor_flags = GO7007_SENSOR_656 |
88 GO7007_SENSOR_VALID_ENABLE |
89 GO7007_SENSOR_TV |
90 GO7007_SENSOR_VBI |
91 GO7007_SENSOR_SCALING,
92 .num_i2c_devs = 1,
93 .i2c_devs = {
94 {
95 .id = I2C_DRIVERID_WIS_SAA7115,
96 .addr = 0x20,
97 },
98 },
99 .num_inputs = 2,
100 .inputs = {
101 {
102 .video_input = 0,
103 .name = "Composite",
104 },
105 {
106 .video_input = 9,
107 .name = "S-Video",
108 },
109 },
110 },
111};
112
113static struct go7007_usb_board board_matrix_reload = {
114 .flags = GO7007_USB_EZUSB,
115 .main_info = {
116 .firmware = "go7007tv.bin",
117 .flags = GO7007_BOARD_HAS_AUDIO |
118 GO7007_BOARD_USE_ONBOARD_I2C,
119 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
120 GO7007_AUDIO_I2S_MASTER |
121 GO7007_AUDIO_WORD_16,
122 .audio_rate = 48000,
123 .audio_bclk_div = 8,
124 .audio_main_div = 2,
125 .hpi_buffer_cap = 7,
126 .sensor_flags = GO7007_SENSOR_656 |
127 GO7007_SENSOR_TV,
128 .num_i2c_devs = 1,
129 .i2c_devs = {
130 {
131 .id = I2C_DRIVERID_WIS_SAA7113,
132 .addr = 0x25,
133 },
134 },
135 .num_inputs = 2,
136 .inputs = {
137 {
138 .video_input = 0,
139 .name = "Composite",
140 },
141 {
142 .video_input = 9,
143 .name = "S-Video",
144 },
145 },
146 },
147};
148
149static struct go7007_usb_board board_star_trek = {
150 .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
151 .main_info = {
152 .firmware = "go7007tv.bin",
153 .flags = GO7007_BOARD_HAS_AUDIO, /* |
154 GO7007_BOARD_HAS_TUNER, */
155 .sensor_flags = GO7007_SENSOR_656 |
156 GO7007_SENSOR_VALID_ENABLE |
157 GO7007_SENSOR_TV |
158 GO7007_SENSOR_VBI |
159 GO7007_SENSOR_SCALING,
160 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
161 GO7007_AUDIO_WORD_16,
162 .audio_bclk_div = 8,
163 .audio_main_div = 2,
164 .hpi_buffer_cap = 7,
165 .num_i2c_devs = 1,
166 .i2c_devs = {
167 {
168 .id = I2C_DRIVERID_WIS_SAA7115,
169 .addr = 0x20,
170 },
171 },
172 .num_inputs = 2,
173 .inputs = {
174 {
175 .video_input = 1,
176 /* .audio_input = AUDIO_EXTERN, */
177 .name = "Composite",
178 },
179 {
180 .video_input = 8,
181 /* .audio_input = AUDIO_EXTERN, */
182 .name = "S-Video",
183 },
184 /* {
185 * .video_input = 3,
186 * .audio_input = AUDIO_TUNER,
187 * .name = "Tuner",
188 * },
189 */
190 },
191 },
192};
193
194static struct go7007_usb_board board_px_tv402u = {
195 .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
196 .main_info = {
197 .firmware = "go7007tv.bin",
198 .flags = GO7007_BOARD_HAS_AUDIO |
199 GO7007_BOARD_HAS_TUNER,
200 .sensor_flags = GO7007_SENSOR_656 |
201 GO7007_SENSOR_VALID_ENABLE |
202 GO7007_SENSOR_TV |
203 GO7007_SENSOR_VBI |
204 GO7007_SENSOR_SCALING,
205 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
206 GO7007_AUDIO_WORD_16,
207 .audio_bclk_div = 8,
208 .audio_main_div = 2,
209 .hpi_buffer_cap = 7,
210 .num_i2c_devs = 3,
211 .i2c_devs = {
212 {
213 .id = I2C_DRIVERID_WIS_SAA7115,
214 .addr = 0x20,
215 },
216 {
217 .id = I2C_DRIVERID_WIS_UDA1342,
218 .addr = 0x1a,
219 },
220 {
221 .id = I2C_DRIVERID_WIS_SONY_TUNER,
222 .addr = 0x60,
223 },
224 },
225 .num_inputs = 3,
226 .inputs = {
227 {
228 .video_input = 1,
229 .audio_input = TVAUDIO_INPUT_EXTERN,
230 .name = "Composite",
231 },
232 {
233 .video_input = 8,
234 .audio_input = TVAUDIO_INPUT_EXTERN,
235 .name = "S-Video",
236 },
237 {
238 .video_input = 3,
239 .audio_input = TVAUDIO_INPUT_TUNER,
240 .name = "Tuner",
241 },
242 },
243 },
244};
245
246static struct go7007_usb_board board_xmen = {
247 .flags = 0,
248 .main_info = {
249 .firmware = "go7007tv.bin",
250 .flags = GO7007_BOARD_USE_ONBOARD_I2C,
251 .hpi_buffer_cap = 0,
252 .sensor_flags = GO7007_SENSOR_VREF_POLAR,
253 .sensor_width = 320,
254 .sensor_height = 240,
255 .sensor_framerate = 30030,
256 .audio_flags = GO7007_AUDIO_ONE_CHANNEL |
257 GO7007_AUDIO_I2S_MODE_3 |
258 GO7007_AUDIO_WORD_14 |
259 GO7007_AUDIO_I2S_MASTER |
260 GO7007_AUDIO_BCLK_POLAR |
261 GO7007_AUDIO_OKI_MODE,
262 .audio_rate = 8000,
263 .audio_bclk_div = 48,
264 .audio_main_div = 1,
265 .num_i2c_devs = 1,
266 .i2c_devs = {
267 {
268 .id = I2C_DRIVERID_WIS_OV7640,
269 .addr = 0x21,
270 },
271 },
272 .num_inputs = 1,
273 .inputs = {
274 {
275 .name = "Camera",
276 },
277 },
278 },
279};
280
281static struct go7007_usb_board board_matrix_revolution = {
282 .flags = GO7007_USB_EZUSB,
283 .main_info = {
284 .firmware = "go7007tv.bin",
285 .flags = GO7007_BOARD_HAS_AUDIO |
286 GO7007_BOARD_USE_ONBOARD_I2C,
287 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
288 GO7007_AUDIO_I2S_MASTER |
289 GO7007_AUDIO_WORD_16,
290 .audio_rate = 48000,
291 .audio_bclk_div = 8,
292 .audio_main_div = 2,
293 .hpi_buffer_cap = 7,
294 .sensor_flags = GO7007_SENSOR_656 |
295 GO7007_SENSOR_TV |
296 GO7007_SENSOR_VBI,
297 .num_i2c_devs = 1,
298 .i2c_devs = {
299 {
300 .id = I2C_DRIVERID_WIS_TW9903,
301 .addr = 0x44,
302 },
303 },
304 .num_inputs = 2,
305 .inputs = {
306 {
307 .video_input = 2,
308 .name = "Composite",
309 },
310 {
311 .video_input = 8,
312 .name = "S-Video",
313 },
314 },
315 },
316};
317
318static struct go7007_usb_board board_lifeview_lr192 = {
319 .flags = GO7007_USB_EZUSB,
320 .main_info = {
321 .firmware = "go7007tv.bin",
322 .flags = GO7007_BOARD_HAS_AUDIO |
323 GO7007_BOARD_USE_ONBOARD_I2C,
324 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
325 GO7007_AUDIO_WORD_16,
326 .audio_rate = 48000,
327 .audio_bclk_div = 8,
328 .audio_main_div = 2,
329 .hpi_buffer_cap = 7,
330 .sensor_flags = GO7007_SENSOR_656 |
331 GO7007_SENSOR_VALID_ENABLE |
332 GO7007_SENSOR_TV |
333 GO7007_SENSOR_VBI |
334 GO7007_SENSOR_SCALING,
335 .num_i2c_devs = 0,
336 .num_inputs = 1,
337 .inputs = {
338 {
339 .video_input = 0,
340 .name = "Composite",
341 },
342 },
343 },
344};
345
346static struct go7007_usb_board board_endura = {
347 .flags = 0,
348 .main_info = {
349 .firmware = "go7007tv.bin",
350 .flags = 0,
351 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
352 GO7007_AUDIO_I2S_MASTER |
353 GO7007_AUDIO_WORD_16,
354 .audio_rate = 8000,
355 .audio_bclk_div = 48,
356 .audio_main_div = 8,
357 .hpi_buffer_cap = 0,
358 .sensor_flags = GO7007_SENSOR_656 |
359 GO7007_SENSOR_TV,
360 .sensor_h_offset = 8,
361 .num_i2c_devs = 0,
362 .num_inputs = 1,
363 .inputs = {
364 {
365 .name = "Camera",
366 },
367 },
368 },
369};
370
371static struct go7007_usb_board board_adlink_mpg24 = {
372 .flags = 0,
373 .main_info = {
374 .firmware = "go7007tv.bin",
375 .flags = GO7007_BOARD_USE_ONBOARD_I2C,
376 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
377 GO7007_AUDIO_I2S_MASTER |
378 GO7007_AUDIO_WORD_16,
379 .audio_rate = 48000,
380 .audio_bclk_div = 8,
381 .audio_main_div = 2,
382 .hpi_buffer_cap = 0,
383 .sensor_flags = GO7007_SENSOR_656 |
384 GO7007_SENSOR_TV |
385 GO7007_SENSOR_VBI,
386 .num_i2c_devs = 1,
387 .i2c_devs = {
388 {
389 .id = I2C_DRIVERID_WIS_TW2804,
390 .addr = 0x00, /* yes, really */
391 },
392 },
393 .num_inputs = 1,
394 .inputs = {
395 {
396 .name = "Composite",
397 },
398 },
399 },
400};
401
402static struct usb_device_id go7007_usb_id_table[] = {
403 {
404 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
405 USB_DEVICE_ID_MATCH_INT_INFO,
406 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
407 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
408 .bcdDevice_lo = 0x200, /* Revision number of XMen */
409 .bcdDevice_hi = 0x200,
410 .bInterfaceClass = 255,
411 .bInterfaceSubClass = 0,
412 .bInterfaceProtocol = 255,
413 .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN,
414 },
415 {
416 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
417 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
418 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
419 .bcdDevice_lo = 0x202, /* Revision number of Matrix II */
420 .bcdDevice_hi = 0x202,
421 .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_II,
422 },
423 {
424 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
425 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
426 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
427 .bcdDevice_lo = 0x204, /* Revision number of Matrix */
428 .bcdDevice_hi = 0x204, /* Reloaded */
429 .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_RELOAD,
430 },
431 {
432 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
433 USB_DEVICE_ID_MATCH_INT_INFO,
434 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
435 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
436 .bcdDevice_lo = 0x205, /* Revision number of XMen-II */
437 .bcdDevice_hi = 0x205,
438 .bInterfaceClass = 255,
439 .bInterfaceSubClass = 0,
440 .bInterfaceProtocol = 255,
441 .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_II,
442 },
443 {
444 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
445 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
446 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
447 .bcdDevice_lo = 0x208, /* Revision number of Star Trek */
448 .bcdDevice_hi = 0x208,
449 .driver_info = (kernel_ulong_t)GO7007_BOARDID_STAR_TREK,
450 },
451 {
452 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
453 USB_DEVICE_ID_MATCH_INT_INFO,
454 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
455 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
456 .bcdDevice_lo = 0x209, /* Revision number of XMen-III */
457 .bcdDevice_hi = 0x209,
458 .bInterfaceClass = 255,
459 .bInterfaceSubClass = 0,
460 .bInterfaceProtocol = 255,
461 .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_III,
462 },
463 {
464 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
465 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
466 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
467 .bcdDevice_lo = 0x210, /* Revision number of Matrix */
468 .bcdDevice_hi = 0x210, /* Revolution */
469 .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_REV,
470 },
471 {
472 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
473 .idVendor = 0x093b, /* Vendor ID of Plextor */
474 .idProduct = 0xa102, /* Product ID of M402U */
475 .bcdDevice_lo = 0x1, /* revision number of Blueberry */
476 .bcdDevice_hi = 0x1,
477 .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_M402U,
478 },
479 {
480 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
481 .idVendor = 0x093b, /* Vendor ID of Plextor */
482 .idProduct = 0xa104, /* Product ID of TV402U */
483 .bcdDevice_lo = 0x1,
484 .bcdDevice_hi = 0x1,
485 .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_TV402U_ANY,
486 },
487 {
488 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
489 .idVendor = 0x10fd, /* Vendor ID of Anubis Electronics */
490 .idProduct = 0xde00, /* Product ID of Lifeview LR192 */
491 .bcdDevice_lo = 0x1,
492 .bcdDevice_hi = 0x1,
493 .driver_info = (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192,
494 },
495 { } /* Terminating entry */
496};
497
498MODULE_DEVICE_TABLE(usb, go7007_usb_id_table);
499
500/********************* Driver for EZ-USB HPI interface *********************/
501
502static int go7007_usb_vendor_request(struct go7007 *go, int request,
503 int value, int index, void *transfer_buffer, int length, int in)
504{
505 struct go7007_usb *usb = go->hpi_context;
506 int timeout = 5000;
507
508 if (in) {
509 return usb_control_msg(usb->usbdev,
510 usb_rcvctrlpipe(usb->usbdev, 0), request,
511 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
512 value, index, transfer_buffer, length, timeout);
513 } else {
514 return usb_control_msg(usb->usbdev,
515 usb_sndctrlpipe(usb->usbdev, 0), request,
516 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
517 value, index, transfer_buffer, length, timeout);
518 }
519}
520
521static int go7007_usb_interface_reset(struct go7007 *go)
522{
523 struct go7007_usb *usb = go->hpi_context;
524 u16 intr_val, intr_data;
525
526 /* Reset encoder */
527 if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
528 return -1;
529 msleep(100);
530
531 if (usb->board->flags & GO7007_USB_EZUSB) {
532 /* Reset buffer in EZ-USB */
533#ifdef GO7007_USB_DEBUG
534 printk(KERN_DEBUG "go7007-usb: resetting EZ-USB buffers\n");
535#endif
536 if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
537 go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
538 return -1;
539
540 /* Reset encoder again */
541 if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
542 return -1;
543 msleep(100);
544 }
545
546 /* Wait for an interrupt to indicate successful hardware reset */
547 if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
548 (intr_val & ~0x1) != 0x55aa) {
549 printk(KERN_ERR
550 "go7007-usb: unable to reset the USB interface\n");
551 return -1;
552 }
553 return 0;
554}
555
556static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
557 int addr, int data)
558{
559 struct go7007_usb *usb = go->hpi_context;
560 int i, r;
561 u16 status_reg;
562 int timeout = 500;
563
564#ifdef GO7007_USB_DEBUG
565 printk(KERN_DEBUG
566 "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
567#endif
568
569 for (i = 0; i < 100; ++i) {
570 r = usb_control_msg(usb->usbdev,
571 usb_rcvctrlpipe(usb->usbdev, 0), 0x14,
572 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
573 0, HPI_STATUS_ADDR, &status_reg,
574 sizeof(status_reg), timeout);
575 if (r < 0)
576 goto write_int_error;
577 __le16_to_cpus(&status_reg);
578 if (!(status_reg & 0x0010))
579 break;
580 msleep(10);
581 }
582 if (i == 100) {
583 printk(KERN_ERR
584 "go7007-usb: device is hung, status reg = 0x%04x\n",
585 status_reg);
586 return -1;
587 }
588 r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
589 USB_TYPE_VENDOR | USB_RECIP_DEVICE, data,
590 INT_PARAM_ADDR, NULL, 0, timeout);
591 if (r < 0)
592 goto write_int_error;
593 r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0),
594 0x12, USB_TYPE_VENDOR | USB_RECIP_DEVICE, addr,
595 INT_INDEX_ADDR, NULL, 0, timeout);
596 if (r < 0)
597 goto write_int_error;
598 return 0;
599
600write_int_error:
601 printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
602 return r;
603}
604
605static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
606 int addr, int data)
607{
608 struct go7007_usb *usb = go->hpi_context;
609 u8 *tbuf;
610 int r;
611 int timeout = 500;
612
613#ifdef GO7007_USB_DEBUG
614 printk(KERN_DEBUG
615 "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
616#endif
617
618 tbuf = kmalloc(8, GFP_KERNEL);
619 if (tbuf == NULL)
620 return -ENOMEM;
621 memset(tbuf, 0, 8);
622 tbuf[0] = data & 0xff;
623 tbuf[1] = data >> 8;
624 tbuf[2] = addr & 0xff;
625 tbuf[3] = addr >> 8;
626 r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00,
627 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
628 0xf0f0, tbuf, 8, timeout);
629 kfree(tbuf);
630 if (r < 0) {
631 printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
632 return r;
633 }
634 return 0;
635}
636
637static void go7007_usb_readinterrupt_complete(struct urb *urb)
638{
639 struct go7007 *go = (struct go7007 *)urb->context;
640 u16 *regs = (u16 *)urb->transfer_buffer;
641
642 if (urb->status != 0) {
643 if (urb->status != -ESHUTDOWN &&
644 go->status != STATUS_SHUTDOWN) {
645 printk(KERN_ERR
646 "go7007-usb: error in read interrupt: %d\n",
647 urb->status);
648 } else {
649 wake_up(&go->interrupt_waitq);
650 return;
651 }
652 } else if (urb->actual_length != urb->transfer_buffer_length) {
653 printk(KERN_ERR "go7007-usb: short read in interrupt pipe!\n");
654 } else {
655 go->interrupt_available = 1;
656 go->interrupt_data = __le16_to_cpu(regs[0]);
657 go->interrupt_value = __le16_to_cpu(regs[1]);
658#ifdef GO7007_USB_DEBUG
659 printk(KERN_DEBUG "go7007-usb: ReadInterrupt: %04x %04x\n",
660 go->interrupt_value, go->interrupt_data);
661#endif
662 }
663
664 wake_up(&go->interrupt_waitq);
665}
666
667static int go7007_usb_read_interrupt(struct go7007 *go)
668{
669 struct go7007_usb *usb = go->hpi_context;
670 int r;
671
672 r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
673 if (r < 0) {
674 printk(KERN_ERR
675 "go7007-usb: unable to submit interrupt urb: %d\n", r);
676 return r;
677 }
678 return 0;
679}
680
681static void go7007_usb_read_video_pipe_complete(struct urb *urb)
682{
683 struct go7007 *go = (struct go7007 *)urb->context;
684 int r;
685
686 if (!go->streaming) {
687 wake_up_interruptible(&go->frame_waitq);
688 return;
689 }
690 if (urb->status != 0) {
691 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
692 urb->status);
693 return;
694 }
695 if (urb->actual_length != urb->transfer_buffer_length) {
696 printk(KERN_ERR "go7007-usb: short read in video pipe!\n");
697 return;
698 }
699 go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
700 r = usb_submit_urb(urb, GFP_ATOMIC);
701 if (r < 0)
702 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", r);
703}
704
705static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
706{
707 struct go7007 *go = (struct go7007 *)urb->context;
708 int r;
709
710 if (!go->streaming)
711 return;
712 if (urb->status != 0) {
713 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
714 urb->status);
715 return;
716 }
717 if (urb->actual_length != urb->transfer_buffer_length) {
718 printk(KERN_ERR "go7007-usb: short read in audio pipe!\n");
719 return;
720 }
721 if (go->audio_deliver != NULL)
722 go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
723 r = usb_submit_urb(urb, GFP_ATOMIC);
724 if (r < 0)
725 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", r);
726}
727
728static int go7007_usb_stream_start(struct go7007 *go)
729{
730 struct go7007_usb *usb = go->hpi_context;
731 int i, r;
732
733 for (i = 0; i < 8; ++i) {
734 r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
735 if (r < 0) {
736 printk(KERN_ERR "go7007-usb: error submitting video "
737 "urb %d: %d\n", i, r);
738 goto video_submit_failed;
739 }
740 }
741 if (!go->audio_enabled)
742 return 0;
743
744 for (i = 0; i < 8; ++i) {
745 r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
746 if (r < 0) {
747 printk(KERN_ERR "go7007-usb: error submitting audio "
748 "urb %d: %d\n", i, r);
749 goto audio_submit_failed;
750 }
751 }
752 return 0;
753
754audio_submit_failed:
755 for (i = 0; i < 8; ++i)
756 usb_kill_urb(usb->audio_urbs[i]);
757video_submit_failed:
758 for (i = 0; i < 8; ++i)
759 usb_kill_urb(usb->video_urbs[i]);
760 return -1;
761}
762
763static int go7007_usb_stream_stop(struct go7007 *go)
764{
765 struct go7007_usb *usb = go->hpi_context;
766 int i;
767
768 if (go->status == STATUS_SHUTDOWN)
769 return 0;
770 for (i = 0; i < 8; ++i)
771 usb_kill_urb(usb->video_urbs[i]);
772 if (go->audio_enabled)
773 for (i = 0; i < 8; ++i)
774 usb_kill_urb(usb->audio_urbs[i]);
775 return 0;
776}
777
778static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
779{
780 struct go7007_usb *usb = go->hpi_context;
781 int transferred, pipe;
782 int timeout = 500;
783
784#ifdef GO7007_USB_DEBUG
785 printk(KERN_DEBUG "go7007-usb: DownloadBuffer sending %d bytes\n", len);
786#endif
787
788 if (usb->board->flags & GO7007_USB_EZUSB)
789 pipe = usb_sndbulkpipe(usb->usbdev, 2);
790 else
791 pipe = usb_sndbulkpipe(usb->usbdev, 3);
792
793 return usb_bulk_msg(usb->usbdev, pipe, data, len,
794 &transferred, timeout);
795}
796
797static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
798 .interface_reset = go7007_usb_interface_reset,
799 .write_interrupt = go7007_usb_ezusb_write_interrupt,
800 .read_interrupt = go7007_usb_read_interrupt,
801 .stream_start = go7007_usb_stream_start,
802 .stream_stop = go7007_usb_stream_stop,
803 .send_firmware = go7007_usb_send_firmware,
804};
805
806static struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
807 .interface_reset = go7007_usb_interface_reset,
808 .write_interrupt = go7007_usb_onboard_write_interrupt,
809 .read_interrupt = go7007_usb_read_interrupt,
810 .stream_start = go7007_usb_stream_start,
811 .stream_stop = go7007_usb_stream_stop,
812 .send_firmware = go7007_usb_send_firmware,
813};
814
815/********************* Driver for EZ-USB I2C adapter *********************/
816
817static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
818 struct i2c_msg msgs[], int num)
819{
820 struct go7007 *go = i2c_get_adapdata(adapter);
821 struct go7007_usb *usb = go->hpi_context;
822 u8 buf[16];
823 int buf_len, i;
824 int ret = -1;
825
826 if (go->status == STATUS_SHUTDOWN)
827 return -1;
828
829 down(&usb->i2c_lock);
830
831 for (i = 0; i < num; ++i) {
832 /* The hardware command is "write some bytes then read some
833 * bytes", so we try to coalesce a write followed by a read
834 * into a single USB transaction */
835 if (i + 1 < num && msgs[i].addr == msgs[i + 1].addr &&
836 !(msgs[i].flags & I2C_M_RD) &&
837 (msgs[i + 1].flags & I2C_M_RD)) {
838#ifdef GO7007_I2C_DEBUG
839 printk(KERN_DEBUG "go7007-usb: i2c write/read %d/%d "
840 "bytes on %02x\n", msgs[i].len,
841 msgs[i + 1].len, msgs[i].addr);
842#endif
843 buf[0] = 0x01;
844 buf[1] = msgs[i].len + 1;
845 buf[2] = msgs[i].addr << 1;
846 memcpy(&buf[3], msgs[i].buf, msgs[i].len);
847 buf_len = msgs[i].len + 3;
848 buf[buf_len++] = msgs[++i].len;
849 } else if (msgs[i].flags & I2C_M_RD) {
850#ifdef GO7007_I2C_DEBUG
851 printk(KERN_DEBUG "go7007-usb: i2c read %d "
852 "bytes on %02x\n", msgs[i].len,
853 msgs[i].addr);
854#endif
855 buf[0] = 0x01;
856 buf[1] = 1;
857 buf[2] = msgs[i].addr << 1;
858 buf[3] = msgs[i].len;
859 buf_len = 4;
860 } else {
861#ifdef GO7007_I2C_DEBUG
862 printk(KERN_DEBUG "go7007-usb: i2c write %d "
863 "bytes on %02x\n", msgs[i].len,
864 msgs[i].addr);
865#endif
866 buf[0] = 0x00;
867 buf[1] = msgs[i].len + 1;
868 buf[2] = msgs[i].addr << 1;
869 memcpy(&buf[3], msgs[i].buf, msgs[i].len);
870 buf_len = msgs[i].len + 3;
871 buf[buf_len++] = 0;
872 }
873 if (go7007_usb_vendor_request(go, 0x24, 0, 0,
874 buf, buf_len, 0) < 0)
875 goto i2c_done;
876 if (msgs[i].flags & I2C_M_RD) {
877 memset(buf, 0, sizeof(buf));
878 if (go7007_usb_vendor_request(go, 0x25, 0, 0, buf,
879 msgs[i].len + 1, 1) < 0)
880 goto i2c_done;
881 memcpy(msgs[i].buf, buf + 1, msgs[i].len);
882 }
883 }
884 ret = 0;
885
886i2c_done:
887 up(&usb->i2c_lock);
888 return ret;
889}
890
891static u32 go7007_usb_functionality(struct i2c_adapter *adapter)
892{
893 /* No errors are reported by the hardware, so we don't bother
894 * supporting quick writes to avoid confusing probing */
895 return (I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK;
896}
897
898static struct i2c_algorithm go7007_usb_algo = {
899 .master_xfer = go7007_usb_i2c_master_xfer,
900 .functionality = go7007_usb_functionality,
901};
902
903static struct i2c_adapter go7007_usb_adap_templ = {
904 .owner = THIS_MODULE,
905 .class = I2C_CLASS_TV_ANALOG,
906 .name = "WIS GO7007SB EZ-USB",
907 .id = I2C_ALGO_GO7007_USB,
908 .algo = &go7007_usb_algo,
909};
910
911/********************* USB add/remove functions *********************/
912
913static int go7007_usb_probe(struct usb_interface *intf,
914 const struct usb_device_id *id)
915{
916 struct go7007 *go;
917 struct go7007_usb *usb;
918 struct go7007_usb_board *board;
919 struct usb_device *usbdev = interface_to_usbdev(intf);
920 char *name;
921 int video_pipe, i, v_urb_len;
922
923 printk(KERN_DEBUG "go7007-usb: probing new GO7007 USB board\n");
924
925 switch (id->driver_info) {
926 case GO7007_BOARDID_MATRIX_II:
927 name = "WIS Matrix II or compatible";
928 board = &board_matrix_ii;
929 break;
930 case GO7007_BOARDID_MATRIX_RELOAD:
931 name = "WIS Matrix Reloaded or compatible";
932 board = &board_matrix_reload;
933 break;
934 case GO7007_BOARDID_MATRIX_REV:
935 name = "WIS Matrix Revolution or compatible";
936 board = &board_matrix_revolution;
937 break;
938 case GO7007_BOARDID_STAR_TREK:
939 name = "WIS Star Trek or compatible";
940 board = &board_star_trek;
941 break;
942 case GO7007_BOARDID_XMEN:
943 name = "WIS XMen or compatible";
944 board = &board_xmen;
945 break;
946 case GO7007_BOARDID_XMEN_II:
947 name = "WIS XMen II or compatible";
948 board = &board_xmen;
949 break;
950 case GO7007_BOARDID_XMEN_III:
951 name = "WIS XMen III or compatible";
952 board = &board_xmen;
953 break;
954 case GO7007_BOARDID_PX_M402U:
955 name = "Plextor PX-M402U";
956 board = &board_matrix_ii;
957 break;
958 case GO7007_BOARDID_PX_TV402U_ANY:
959 name = "Plextor PX-TV402U (unknown tuner)";
960 board = &board_px_tv402u;
961 break;
962 case GO7007_BOARDID_LIFEVIEW_LR192:
963 printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
964 "is not supported. Sorry!\n");
965 return 0;
966 name = "Lifeview TV Walker Ultra";
967 board = &board_lifeview_lr192;
968 break;
969 default:
970 printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
971 (unsigned int)id->driver_info);
972 return 0;
973 }
974
975 usb = kmalloc(sizeof(struct go7007_usb), GFP_KERNEL);
976 if (usb == NULL)
977 return -ENOMEM;
978 memset(usb, 0, sizeof(struct go7007_usb));
979
980 /* Allocate the URB and buffer for receiving incoming interrupts */
981 usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
982 if (usb->intr_urb == NULL)
983 goto allocfail;
984 usb->intr_urb->transfer_buffer = kmalloc(2*sizeof(u16), GFP_KERNEL);
985 if (usb->intr_urb->transfer_buffer == NULL)
986 goto allocfail;
987
988 go = go7007_alloc(&board->main_info, &intf->dev);
989 if (go == NULL)
990 goto allocfail;
991 usb->board = board;
992 usb->usbdev = usbdev;
993 go->board_id = id->driver_info;
994 strncpy(go->name, name, sizeof(go->name));
995 if (board->flags & GO7007_USB_EZUSB)
996 go->hpi_ops = &go7007_usb_ezusb_hpi_ops;
997 else
998 go->hpi_ops = &go7007_usb_onboard_hpi_ops;
999 go->hpi_context = usb;
1000 usb_fill_int_urb(usb->intr_urb, usb->usbdev,
1001 usb_rcvintpipe(usb->usbdev, 4),
1002 usb->intr_urb->transfer_buffer, 2*sizeof(u16),
1003 go7007_usb_readinterrupt_complete, go, 8);
1004 usb_set_intfdata(intf, go);
1005
1006 /* Boot the GO7007 */
1007 if (go7007_boot_encoder(go, go->board_info->flags &
1008 GO7007_BOARD_USE_ONBOARD_I2C) < 0)
1009 goto initfail;
1010
1011 /* Register the EZ-USB I2C adapter, if we're using it */
1012 if (board->flags & GO7007_USB_EZUSB_I2C) {
1013 memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
1014 sizeof(go7007_usb_adap_templ));
1015 init_MUTEX(&usb->i2c_lock);
1016 go->i2c_adapter.dev.parent = go->dev;
1017 i2c_set_adapdata(&go->i2c_adapter, go);
1018 if (i2c_add_adapter(&go->i2c_adapter) < 0) {
1019 printk(KERN_ERR
1020 "go7007-usb: error: i2c_add_adapter failed\n");
1021 goto initfail;
1022 }
1023 go->i2c_adapter_online = 1;
1024 }
1025
1026 /* Pelco and Adlink reused the XMen and XMen-III vendor and product
1027 * IDs for their own incompatible designs. We can detect XMen boards
1028 * by probing the sensor, but there is no way to probe the sensors on
1029 * the Pelco and Adlink designs so we default to the Adlink. If it
1030 * is actually a Pelco, the user must set the assume_endura module
1031 * parameter. */
1032 if ((go->board_id == GO7007_BOARDID_XMEN ||
1033 go->board_id == GO7007_BOARDID_XMEN_III) &&
1034 go->i2c_adapter_online) {
1035 union i2c_smbus_data data;
1036
1037 /* Check to see if register 0x0A is 0x76 */
1038 i2c_smbus_xfer(&go->i2c_adapter, 0x21, I2C_CLIENT_SCCB,
1039 I2C_SMBUS_READ, 0x0A, I2C_SMBUS_BYTE_DATA, &data);
1040 if (data.byte != 0x76) {
1041 if (assume_endura) {
1042 go->board_id = GO7007_BOARDID_ENDURA;
1043 usb->board = board = &board_endura;
1044 go->board_info = &board->main_info;
1045 strncpy(go->name, "Pelco Endura",
1046 sizeof(go->name));
1047 } else {
1048 u16 channel;
1049
1050 /* set GPIO5 to be an output, currently low */
1051 go7007_write_addr(go, 0x3c82, 0x0000);
1052 go7007_write_addr(go, 0x3c80, 0x00df);
1053 /* read channel number from GPIO[1:0] */
1054 go7007_read_addr(go, 0x3c81, &channel);
1055 channel &= 0x3;
1056 go->board_id = GO7007_BOARDID_ADLINK_MPG24;
1057 usb->board = board = &board_adlink_mpg24;
1058 go->board_info = &board->main_info;
1059 go->channel_number = channel;
1060 snprintf(go->name, sizeof(go->name),
1061 "Adlink PCI-MPG24, channel #%d",
1062 channel);
1063 }
1064 }
1065 }
1066
1067 /* Probe the tuner model on the TV402U */
1068 if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) {
1069 u8 data[3];
1070
1071 /* Board strapping indicates tuner model */
1072 if (go7007_usb_vendor_request(go, 0x41, 0, 0, data, 3, 1) < 0) {
1073 printk(KERN_ERR "go7007-usb: GPIO read failed!\n");
1074 goto initfail;
1075 }
1076 switch (data[0] >> 6) {
1077 case 1:
1078 go->board_id = GO7007_BOARDID_PX_TV402U_EU;
1079 go->tuner_type = TUNER_SONY_BTF_PG472Z;
1080 strncpy(go->name, "Plextor PX-TV402U-EU",
1081 sizeof(go->name));
1082 break;
1083 case 2:
1084 go->board_id = GO7007_BOARDID_PX_TV402U_JP;
1085 go->tuner_type = TUNER_SONY_BTF_PK467Z;
1086 strncpy(go->name, "Plextor PX-TV402U-JP",
1087 sizeof(go->name));
1088 break;
1089 case 3:
1090 go->board_id = GO7007_BOARDID_PX_TV402U_NA;
1091 go->tuner_type = TUNER_SONY_BTF_PB463Z;
1092 strncpy(go->name, "Plextor PX-TV402U-NA",
1093 sizeof(go->name));
1094 break;
1095 default:
1096 printk(KERN_DEBUG "go7007-usb: unable to detect "
1097 "tuner type!\n");
1098 break;
1099 }
1100 /* Configure tuner mode selection inputs connected
1101 * to the EZ-USB GPIO output pins */
1102 if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
1103 NULL, 0, 0) < 0) {
1104 printk(KERN_ERR
1105 "go7007-usb: GPIO write failed!\n");
1106 goto initfail;
1107 }
1108 }
1109
1110 /* Print a nasty message if the user attempts to use a USB2.0 device in
1111 * a USB1.1 port. There will be silent corruption of the stream. */
1112 if ((board->flags & GO7007_USB_EZUSB) &&
1113 usbdev->speed != USB_SPEED_HIGH)
1114 printk(KERN_ERR "go7007-usb: *** WARNING *** This device "
1115 "must be connected to a USB 2.0 port! "
1116 "Attempting to capture video through a USB 1.1 "
1117 "port will result in stream corruption, even "
1118 "at low bitrates!\n");
1119
1120 /* Do any final GO7007 initialization, then register the
1121 * V4L2 and ALSA interfaces */
1122 if (go7007_register_encoder(go) < 0)
1123 goto initfail;
1124
1125 /* Allocate the URBs and buffers for receiving the video stream */
1126 if (board->flags & GO7007_USB_EZUSB) {
1127 v_urb_len = 1024;
1128 video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
1129 } else {
1130 v_urb_len = 512;
1131 video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
1132 }
1133 for (i = 0; i < 8; ++i) {
1134 usb->video_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1135 if (usb->video_urbs[i] == NULL)
1136 goto initfail;
1137 usb->video_urbs[i]->transfer_buffer =
1138 kmalloc(v_urb_len, GFP_KERNEL);
1139 if (usb->video_urbs[i]->transfer_buffer == NULL)
1140 goto initfail;
1141 usb_fill_bulk_urb(usb->video_urbs[i], usb->usbdev, video_pipe,
1142 usb->video_urbs[i]->transfer_buffer, v_urb_len,
1143 go7007_usb_read_video_pipe_complete, go);
1144 }
1145
1146 /* Allocate the URBs and buffers for receiving the audio stream */
1147 if ((board->flags & GO7007_USB_EZUSB) && go->audio_enabled)
1148 for (i = 0; i < 8; ++i) {
1149 usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1150 if (usb->audio_urbs[i] == NULL)
1151 goto initfail;
1152 usb->audio_urbs[i]->transfer_buffer = kmalloc(4096,
1153 GFP_KERNEL);
1154 if (usb->audio_urbs[i]->transfer_buffer == NULL)
1155 goto initfail;
1156 usb_fill_bulk_urb(usb->audio_urbs[i], usb->usbdev,
1157 usb_rcvbulkpipe(usb->usbdev, 8),
1158 usb->audio_urbs[i]->transfer_buffer, 4096,
1159 go7007_usb_read_audio_pipe_complete, go);
1160 }
1161
1162
1163 go->status = STATUS_ONLINE;
1164 return 0;
1165
1166initfail:
1167 go->status = STATUS_SHUTDOWN;
1168 return 0;
1169
1170allocfail:
1171 if (usb->intr_urb) {
1172 kfree(usb->intr_urb->transfer_buffer);
1173 usb_free_urb(usb->intr_urb);
1174 }
1175 kfree(usb);
1176 return -ENOMEM;
1177}
1178
1179static void go7007_usb_disconnect(struct usb_interface *intf)
1180{
1181 struct go7007 *go = usb_get_intfdata(intf);
1182 struct go7007_usb *usb = go->hpi_context;
1183 int i;
1184
1185 go->status = STATUS_SHUTDOWN;
1186 usb_kill_urb(usb->intr_urb);
1187
1188 /* Free USB-related structs */
1189 for (i = 0; i < 8; ++i) {
1190 if (usb->video_urbs[i] != NULL) {
1191 if (usb->video_urbs[i]->transfer_buffer != NULL)
1192 kfree(usb->video_urbs[i]->transfer_buffer);
1193 usb_free_urb(usb->video_urbs[i]);
1194 }
1195 if (usb->audio_urbs[i] != NULL) {
1196 if (usb->audio_urbs[i]->transfer_buffer != NULL)
1197 kfree(usb->audio_urbs[i]->transfer_buffer);
1198 usb_free_urb(usb->audio_urbs[i]);
1199 }
1200 }
1201 kfree(usb->intr_urb->transfer_buffer);
1202 usb_free_urb(usb->intr_urb);
1203
1204 kfree(go->hpi_context);
1205
1206 go7007_remove(go);
1207}
1208
1209static struct usb_driver go7007_usb_driver = {
1210 .name = "go7007",
1211 .probe = go7007_usb_probe,
1212 .disconnect = go7007_usb_disconnect,
1213 .id_table = go7007_usb_id_table,
1214};
1215
1216static int __init go7007_usb_init(void)
1217{
1218 return usb_register(&go7007_usb_driver);
1219}
1220
1221static void __exit go7007_usb_cleanup(void)
1222{
1223 usb_deregister(&go7007_usb_driver);
1224}
1225
1226module_init(go7007_usb_init);
1227module_exit(go7007_usb_cleanup);
1228
1229MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
new file mode 100644
index 00000000000..d54d0190d81
--- /dev/null
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -0,0 +1,1503 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/version.h>
21#include <linux/delay.h>
22#include <linux/sched.h>
23#include <linux/spinlock.h>
24#include <linux/fs.h>
25#include <linux/unistd.h>
26#include <linux/time.h>
27#include <linux/vmalloc.h>
28#include <linux/pagemap.h>
29#include <linux/videodev.h>
30#include <linux/video_decoder.h>
31#include <media/v4l2-common.h>
32#include <media/v4l2-ioctl.h>
33#include <linux/i2c.h>
34#include <linux/semaphore.h>
35#include <linux/uaccess.h>
36#include <asm/system.h>
37
38#include "go7007.h"
39#include "go7007-priv.h"
40#include "wis-i2c.h"
41
42static void deactivate_buffer(struct go7007_buffer *gobuf)
43{
44 int i;
45
46 if (gobuf->state != BUF_STATE_IDLE) {
47 list_del(&gobuf->stream);
48 gobuf->state = BUF_STATE_IDLE;
49 }
50 if (gobuf->page_count > 0) {
51 for (i = 0; i < gobuf->page_count; ++i)
52 page_cache_release(gobuf->pages[i]);
53 gobuf->page_count = 0;
54 }
55}
56
57static void abort_queued(struct go7007 *go)
58{
59 struct go7007_buffer *gobuf, *next;
60
61 list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
62 deactivate_buffer(gobuf);
63 }
64}
65
66static int go7007_streamoff(struct go7007 *go)
67{
68 int retval = -EINVAL;
69 unsigned long flags;
70
71 down(&go->hw_lock);
72 if (go->streaming) {
73 go->streaming = 0;
74 go7007_stream_stop(go);
75 spin_lock_irqsave(&go->spinlock, flags);
76 abort_queued(go);
77 spin_unlock_irqrestore(&go->spinlock, flags);
78 go7007_reset_encoder(go);
79 retval = 0;
80 }
81 up(&go->hw_lock);
82 return 0;
83}
84
85static int go7007_open(struct inode *inode, struct file *file)
86{
87 struct go7007 *go = video_get_drvdata(video_devdata(file));
88 struct go7007_file *gofh;
89
90 if (go->status != STATUS_ONLINE)
91 return -EBUSY;
92 gofh = kmalloc(sizeof(struct go7007_file), GFP_KERNEL);
93 if (gofh == NULL)
94 return -ENOMEM;
95 ++go->ref_count;
96 gofh->go = go;
97 init_MUTEX(&gofh->lock);
98 gofh->buf_count = 0;
99 file->private_data = gofh;
100 return 0;
101}
102
103static int go7007_release(struct inode *inode, struct file *file)
104{
105 struct go7007_file *gofh = file->private_data;
106 struct go7007 *go = gofh->go;
107
108 if (gofh->buf_count > 0) {
109 go7007_streamoff(go);
110 go->in_use = 0;
111 kfree(gofh->bufs);
112 gofh->buf_count = 0;
113 }
114 kfree(gofh);
115 if (--go->ref_count == 0)
116 kfree(go);
117 file->private_data = NULL;
118 return 0;
119}
120
121static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
122{
123 u8 *f = page_address(gobuf->pages[0]);
124
125 switch (format) {
126 case GO7007_FORMAT_MJPEG:
127 return V4L2_BUF_FLAG_KEYFRAME;
128 case GO7007_FORMAT_MPEG4:
129 switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
130 case 0:
131 return V4L2_BUF_FLAG_KEYFRAME;
132 case 1:
133 return V4L2_BUF_FLAG_PFRAME;
134 case 2:
135 return V4L2_BUF_FLAG_BFRAME;
136 default:
137 return 0;
138 }
139 case GO7007_FORMAT_MPEG1:
140 case GO7007_FORMAT_MPEG2:
141 switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
142 case 1:
143 return V4L2_BUF_FLAG_KEYFRAME;
144 case 2:
145 return V4L2_BUF_FLAG_PFRAME;
146 case 3:
147 return V4L2_BUF_FLAG_BFRAME;
148 default:
149 return 0;
150 }
151 }
152
153 return 0;
154}
155
156static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
157{
158 int sensor_height = 0, sensor_width = 0;
159 int width, height, i;
160
161 if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
162 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
163 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
164 return -EINVAL;
165
166 switch (go->standard) {
167 case GO7007_STD_NTSC:
168 sensor_width = 720;
169 sensor_height = 480;
170 break;
171 case GO7007_STD_PAL:
172 sensor_width = 720;
173 sensor_height = 576;
174 break;
175 case GO7007_STD_OTHER:
176 sensor_width = go->board_info->sensor_width;
177 sensor_height = go->board_info->sensor_height;
178 break;
179 }
180
181 if (fmt == NULL) {
182 width = sensor_width;
183 height = sensor_height;
184 } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
185 if (fmt->fmt.pix.width > sensor_width)
186 width = sensor_width;
187 else if (fmt->fmt.pix.width < 144)
188 width = 144;
189 else
190 width = fmt->fmt.pix.width & ~0x0f;
191
192 if (fmt->fmt.pix.height > sensor_height)
193 height = sensor_height;
194 else if (fmt->fmt.pix.height < 96)
195 height = 96;
196 else
197 height = fmt->fmt.pix.height & ~0x0f;
198 } else {
199 int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height;
200 int sensor_size = sensor_width * sensor_height;
201
202 if (64 * requested_size < 9 * sensor_size) {
203 width = sensor_width / 4;
204 height = sensor_height / 4;
205 } else if (64 * requested_size < 36 * sensor_size) {
206 width = sensor_width / 2;
207 height = sensor_height / 2;
208 } else {
209 width = sensor_width;
210 height = sensor_height;
211 }
212 width &= ~0xf;
213 height &= ~0xf;
214 }
215
216 if (fmt != NULL) {
217 u32 pixelformat = fmt->fmt.pix.pixelformat;
218
219 memset(fmt, 0, sizeof(*fmt));
220 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
221 fmt->fmt.pix.width = width;
222 fmt->fmt.pix.height = height;
223 fmt->fmt.pix.pixelformat = pixelformat;
224 fmt->fmt.pix.field = V4L2_FIELD_NONE;
225 fmt->fmt.pix.bytesperline = 0;
226 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
227 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
228 }
229
230 if (try)
231 return 0;
232
233 go->width = width;
234 go->height = height;
235 go->encoder_h_offset = go->board_info->sensor_h_offset;
236 go->encoder_v_offset = go->board_info->sensor_v_offset;
237 for (i = 0; i < 4; ++i)
238 go->modet[i].enable = 0;
239 for (i = 0; i < 1624; ++i)
240 go->modet_map[i] = 0;
241
242 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
243 struct video_decoder_resolution res;
244
245 res.width = width;
246 if (height > sensor_height / 2) {
247 res.height = height / 2;
248 go->encoder_v_halve = 0;
249 } else {
250 res.height = height;
251 go->encoder_v_halve = 1;
252 }
253 if (go->i2c_adapter_online)
254 i2c_clients_command(&go->i2c_adapter,
255 DECODER_SET_RESOLUTION, &res);
256 } else {
257 if (width <= sensor_width / 4) {
258 go->encoder_h_halve = 1;
259 go->encoder_v_halve = 1;
260 go->encoder_subsample = 1;
261 } else if (width <= sensor_width / 2) {
262 go->encoder_h_halve = 1;
263 go->encoder_v_halve = 1;
264 go->encoder_subsample = 0;
265 } else {
266 go->encoder_h_halve = 0;
267 go->encoder_v_halve = 0;
268 go->encoder_subsample = 0;
269 }
270 }
271
272 if (fmt == NULL)
273 return 0;
274
275 switch (fmt->fmt.pix.pixelformat) {
276 case V4L2_PIX_FMT_MPEG:
277 if (go->format == GO7007_FORMAT_MPEG1 ||
278 go->format == GO7007_FORMAT_MPEG2 ||
279 go->format == GO7007_FORMAT_MPEG4)
280 break;
281 go->format = GO7007_FORMAT_MPEG1;
282 go->pali = 0;
283 go->aspect_ratio = GO7007_RATIO_1_1;
284 go->gop_size = go->sensor_framerate / 1000;
285 go->ipb = 0;
286 go->closed_gop = 1;
287 go->repeat_seqhead = 1;
288 go->seq_header_enable = 1;
289 go->gop_header_enable = 1;
290 go->dvd_mode = 0;
291 break;
292 /* Backwards compatibility only! */
293 case V4L2_PIX_FMT_MPEG4:
294 if (go->format == GO7007_FORMAT_MPEG4)
295 break;
296 go->format = GO7007_FORMAT_MPEG4;
297 go->pali = 0xf5;
298 go->aspect_ratio = GO7007_RATIO_1_1;
299 go->gop_size = go->sensor_framerate / 1000;
300 go->ipb = 0;
301 go->closed_gop = 1;
302 go->repeat_seqhead = 1;
303 go->seq_header_enable = 1;
304 go->gop_header_enable = 1;
305 go->dvd_mode = 0;
306 break;
307 case V4L2_PIX_FMT_MJPEG:
308 go->format = GO7007_FORMAT_MJPEG;
309 go->pali = 0;
310 go->aspect_ratio = GO7007_RATIO_1_1;
311 go->gop_size = 0;
312 go->ipb = 0;
313 go->closed_gop = 0;
314 go->repeat_seqhead = 0;
315 go->seq_header_enable = 0;
316 go->gop_header_enable = 0;
317 go->dvd_mode = 0;
318 break;
319 }
320 return 0;
321}
322
323static int clip_to_modet_map(struct go7007 *go, int region,
324 struct v4l2_clip *clip_list)
325{
326 struct v4l2_clip clip, *clip_ptr;
327 int x, y, mbnum;
328
329 /* Check if coordinates are OK and if any macroblocks are already
330 * used by other regions (besides 0) */
331 clip_ptr = clip_list;
332 while (clip_ptr) {
333 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
334 return -EFAULT;
335 if (clip.c.left < 0 || (clip.c.left & 0xF) ||
336 clip.c.width <= 0 || (clip.c.width & 0xF))
337 return -EINVAL;
338 if (clip.c.left + clip.c.width > go->width)
339 return -EINVAL;
340 if (clip.c.top < 0 || (clip.c.top & 0xF) ||
341 clip.c.height <= 0 || (clip.c.height & 0xF))
342 return -EINVAL;
343 if (clip.c.top + clip.c.height > go->height)
344 return -EINVAL;
345 for (y = 0; y < clip.c.height; y += 16)
346 for (x = 0; x < clip.c.width; x += 16) {
347 mbnum = (go->width >> 4) *
348 ((clip.c.top + y) >> 4) +
349 ((clip.c.left + x) >> 4);
350 if (go->modet_map[mbnum] != 0 &&
351 go->modet_map[mbnum] != region)
352 return -EBUSY;
353 }
354 clip_ptr = clip.next;
355 }
356
357 /* Clear old region macroblocks */
358 for (mbnum = 0; mbnum < 1624; ++mbnum)
359 if (go->modet_map[mbnum] == region)
360 go->modet_map[mbnum] = 0;
361
362 /* Claim macroblocks in this list */
363 clip_ptr = clip_list;
364 while (clip_ptr) {
365 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
366 return -EFAULT;
367 for (y = 0; y < clip.c.height; y += 16)
368 for (x = 0; x < clip.c.width; x += 16) {
369 mbnum = (go->width >> 4) *
370 ((clip.c.top + y) >> 4) +
371 ((clip.c.left + x) >> 4);
372 go->modet_map[mbnum] = region;
373 }
374 clip_ptr = clip.next;
375 }
376 return 0;
377}
378
379static int go7007_do_ioctl(struct inode *inode, struct file *file,
380 unsigned int cmd, void *arg)
381{
382 struct go7007_file *gofh = file->private_data;
383 struct go7007 *go = gofh->go;
384 unsigned long flags;
385 int retval = 0;
386
387 switch (cmd) {
388 case VIDIOC_QUERYCAP:
389 {
390 struct v4l2_capability *cap = arg;
391
392 memset(cap, 0, sizeof(*cap));
393 strcpy(cap->driver, "go7007");
394 strncpy(cap->card, go->name, sizeof(cap->card));
395 cap->version = KERNEL_VERSION(0, 9, 8);
396 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
397 V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
398 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
399 cap->capabilities |= V4L2_CAP_TUNER;
400 return 0;
401 }
402 case VIDIOC_ENUM_FMT:
403 {
404 struct v4l2_fmtdesc *fmt = arg;
405 unsigned int index;
406 char *desc;
407 u32 pixelformat;
408
409 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
410 return -EINVAL;
411 switch (fmt->index) {
412 case 0:
413 pixelformat = V4L2_PIX_FMT_MJPEG;
414 desc = "Motion-JPEG";
415 break;
416 case 1:
417 pixelformat = V4L2_PIX_FMT_MPEG;
418 desc = "MPEG1/MPEG2/MPEG4";
419 break;
420 default:
421 return -EINVAL;
422 }
423 index = fmt->index;
424 memset(fmt, 0, sizeof(*fmt));
425 fmt->index = index;
426 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
427 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
428 strncpy(fmt->description, desc, sizeof(fmt->description));
429 fmt->pixelformat = pixelformat;
430
431 return 0;
432 }
433 case VIDIOC_TRY_FMT:
434 {
435 struct v4l2_format *fmt = arg;
436
437 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
438 return -EINVAL;
439 return set_capture_size(go, fmt, 1);
440 }
441 case VIDIOC_G_FMT:
442 {
443 struct v4l2_format *fmt = arg;
444
445 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
446 return -EINVAL;
447 memset(fmt, 0, sizeof(*fmt));
448 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
449 fmt->fmt.pix.width = go->width;
450 fmt->fmt.pix.height = go->height;
451 fmt->fmt.pix.pixelformat = go->format == GO7007_FORMAT_MJPEG ?
452 V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
453 fmt->fmt.pix.field = V4L2_FIELD_NONE;
454 fmt->fmt.pix.bytesperline = 0;
455 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
456 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
457 return 0;
458 }
459 case VIDIOC_S_FMT:
460 {
461 struct v4l2_format *fmt = arg;
462
463 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
464 return -EINVAL;
465 if (go->streaming)
466 return -EBUSY;
467 return set_capture_size(go, fmt, 0);
468 }
469 case VIDIOC_G_FBUF:
470 case VIDIOC_S_FBUF:
471 return -EINVAL;
472 case VIDIOC_REQBUFS:
473 {
474 struct v4l2_requestbuffers *req = arg;
475 unsigned int count, i;
476
477 if (go->streaming)
478 return -EBUSY;
479 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
480 req->memory != V4L2_MEMORY_MMAP)
481 return -EINVAL;
482
483 down(&gofh->lock);
484 retval = -EBUSY;
485 for (i = 0; i < gofh->buf_count; ++i)
486 if (gofh->bufs[i].mapped > 0)
487 goto unlock_and_return;
488 down(&go->hw_lock);
489 if (go->in_use > 0 && gofh->buf_count == 0) {
490 up(&go->hw_lock);
491 goto unlock_and_return;
492 }
493 if (gofh->buf_count > 0)
494 kfree(gofh->bufs);
495 retval = -ENOMEM;
496 count = req->count;
497 if (count > 0) {
498 if (count < 2)
499 count = 2;
500 if (count > 32)
501 count = 32;
502 gofh->bufs = kmalloc(count *
503 sizeof(struct go7007_buffer),
504 GFP_KERNEL);
505 if (gofh->bufs == NULL) {
506 up(&go->hw_lock);
507 goto unlock_and_return;
508 }
509 memset(gofh->bufs, 0,
510 count * sizeof(struct go7007_buffer));
511 for (i = 0; i < count; ++i) {
512 gofh->bufs[i].go = go;
513 gofh->bufs[i].index = i;
514 gofh->bufs[i].state = BUF_STATE_IDLE;
515 gofh->bufs[i].mapped = 0;
516 }
517 go->in_use = 1;
518 } else {
519 go->in_use = 0;
520 }
521 gofh->buf_count = count;
522 up(&go->hw_lock);
523 up(&gofh->lock);
524 memset(req, 0, sizeof(*req));
525 req->count = count;
526 req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
527 req->memory = V4L2_MEMORY_MMAP;
528 return 0;
529 }
530 case VIDIOC_QUERYBUF:
531 {
532 struct v4l2_buffer *buf = arg;
533 unsigned int index;
534
535 retval = -EINVAL;
536 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
537 return -EINVAL;
538 index = buf->index;
539 down(&gofh->lock);
540 if (index >= gofh->buf_count)
541 goto unlock_and_return;
542 memset(buf, 0, sizeof(*buf));
543 buf->index = index;
544 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
545 switch (gofh->bufs[index].state) {
546 case BUF_STATE_QUEUED:
547 buf->flags = V4L2_BUF_FLAG_QUEUED;
548 break;
549 case BUF_STATE_DONE:
550 buf->flags = V4L2_BUF_FLAG_DONE;
551 break;
552 default:
553 buf->flags = 0;
554 }
555 if (gofh->bufs[index].mapped)
556 buf->flags |= V4L2_BUF_FLAG_MAPPED;
557 buf->memory = V4L2_MEMORY_MMAP;
558 buf->m.offset = index * GO7007_BUF_SIZE;
559 buf->length = GO7007_BUF_SIZE;
560 up(&gofh->lock);
561
562 return 0;
563 }
564 case VIDIOC_QBUF:
565 {
566 struct v4l2_buffer *buf = arg;
567 struct go7007_buffer *gobuf;
568 int ret;
569
570 retval = -EINVAL;
571 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
572 buf->memory != V4L2_MEMORY_MMAP)
573 return -EINVAL;
574 down(&gofh->lock);
575 if (buf->index < 0 || buf->index >= gofh->buf_count)
576 goto unlock_and_return;
577 gobuf = &gofh->bufs[buf->index];
578 if (gobuf->mapped == 0)
579 goto unlock_and_return;
580 retval = -EBUSY;
581 if (gobuf->state != BUF_STATE_IDLE)
582 goto unlock_and_return;
583 /* offset will be 0 until we really support USERPTR streaming */
584 gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
585 gobuf->bytesused = 0;
586 gobuf->frame_offset = 0;
587 gobuf->modet_active = 0;
588 if (gobuf->offset > 0)
589 gobuf->page_count = GO7007_BUF_PAGES + 1;
590 else
591 gobuf->page_count = GO7007_BUF_PAGES;
592 retval = -ENOMEM;
593 down_read(&current->mm->mmap_sem);
594 ret = get_user_pages(current, current->mm,
595 gobuf->user_addr & PAGE_MASK, gobuf->page_count,
596 1, 1, gobuf->pages, NULL);
597 up_read(&current->mm->mmap_sem);
598 if (ret != gobuf->page_count) {
599 int i;
600 for (i = 0; i < ret; ++i)
601 page_cache_release(gobuf->pages[i]);
602 gobuf->page_count = 0;
603 goto unlock_and_return;
604 }
605 gobuf->state = BUF_STATE_QUEUED;
606 spin_lock_irqsave(&go->spinlock, flags);
607 list_add_tail(&gobuf->stream, &go->stream);
608 spin_unlock_irqrestore(&go->spinlock, flags);
609 up(&gofh->lock);
610 return 0;
611 }
612 case VIDIOC_DQBUF:
613 {
614 struct v4l2_buffer *buf = arg;
615 struct go7007_buffer *gobuf;
616 u32 frame_type_flag;
617 DEFINE_WAIT(wait);
618
619 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
620 return -EINVAL;
621 if (buf->memory != V4L2_MEMORY_MMAP)
622 return -EINVAL;
623 down(&gofh->lock);
624 retval = -EINVAL;
625 if (list_empty(&go->stream))
626 goto unlock_and_return;
627 gobuf = list_entry(go->stream.next,
628 struct go7007_buffer, stream);
629 retval = -EAGAIN;
630 if (gobuf->state != BUF_STATE_DONE &&
631 !(file->f_flags & O_NONBLOCK)) {
632 for (;;) {
633 prepare_to_wait(&go->frame_waitq, &wait,
634 TASK_INTERRUPTIBLE);
635 if (gobuf->state == BUF_STATE_DONE)
636 break;
637 if (signal_pending(current)) {
638 retval = -ERESTARTSYS;
639 break;
640 }
641 schedule();
642 }
643 finish_wait(&go->frame_waitq, &wait);
644 }
645 if (gobuf->state != BUF_STATE_DONE)
646 goto unlock_and_return;
647 spin_lock_irqsave(&go->spinlock, flags);
648 deactivate_buffer(gobuf);
649 spin_unlock_irqrestore(&go->spinlock, flags);
650 frame_type_flag = get_frame_type_flag(gobuf, go->format);
651 gobuf->state = BUF_STATE_IDLE;
652 memset(buf, 0, sizeof(*buf));
653 buf->index = gobuf->index;
654 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
655 buf->bytesused = gobuf->bytesused;
656 buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
657 buf->field = V4L2_FIELD_NONE;
658 buf->timestamp = gobuf->timestamp;
659 buf->sequence = gobuf->seq;
660 buf->memory = V4L2_MEMORY_MMAP;
661 buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
662 buf->length = GO7007_BUF_SIZE;
663 buf->reserved = gobuf->modet_active;
664 up(&gofh->lock);
665 return 0;
666 }
667 case VIDIOC_STREAMON:
668 {
669 unsigned int *type = arg;
670
671 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
672 return -EINVAL;
673 down(&gofh->lock);
674 down(&go->hw_lock);
675 if (!go->streaming) {
676 go->streaming = 1;
677 go->next_seq = 0;
678 go->active_buf = NULL;
679 if (go7007_start_encoder(go) < 0)
680 retval = -EIO;
681 else
682 retval = 0;
683 }
684 up(&go->hw_lock);
685 up(&gofh->lock);
686 return retval;
687 }
688 case VIDIOC_STREAMOFF:
689 {
690 unsigned int *type = arg;
691
692 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
693 return -EINVAL;
694 down(&gofh->lock);
695 go7007_streamoff(go);
696 up(&gofh->lock);
697 return 0;
698 }
699 case VIDIOC_QUERYCTRL:
700 {
701 struct v4l2_queryctrl *ctrl = arg;
702 u32 id;
703
704 if (!go->i2c_adapter_online)
705 return -EIO;
706 id = ctrl->id;
707 memset(ctrl, 0, sizeof(*ctrl));
708 ctrl->id = id;
709 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, arg);
710 return ctrl->name[0] == 0 ? -EINVAL : 0;
711 }
712 case VIDIOC_G_CTRL:
713 {
714 struct v4l2_control *ctrl = arg;
715 struct v4l2_queryctrl query;
716
717 if (!go->i2c_adapter_online)
718 return -EIO;
719 memset(&query, 0, sizeof(query));
720 query.id = ctrl->id;
721 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
722 if (query.name[0] == 0)
723 return -EINVAL;
724 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, arg);
725 return 0;
726 }
727 case VIDIOC_S_CTRL:
728 {
729 struct v4l2_control *ctrl = arg;
730 struct v4l2_queryctrl query;
731
732 if (!go->i2c_adapter_online)
733 return -EIO;
734 memset(&query, 0, sizeof(query));
735 query.id = ctrl->id;
736 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
737 if (query.name[0] == 0)
738 return -EINVAL;
739 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, arg);
740 return 0;
741 }
742 case VIDIOC_G_PARM:
743 {
744 struct v4l2_streamparm *parm = arg;
745 struct v4l2_fract timeperframe = {
746 .numerator = 1001 * go->fps_scale,
747 .denominator = go->sensor_framerate,
748 };
749
750 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
751 return -EINVAL;
752 memset(parm, 0, sizeof(*parm));
753 parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
754 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
755 parm->parm.capture.timeperframe = timeperframe;
756 return 0;
757 }
758 case VIDIOC_S_PARM:
759 {
760 struct v4l2_streamparm *parm = arg;
761 unsigned int n, d;
762
763 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
764 return -EINVAL;
765 if (parm->parm.capture.capturemode != 0)
766 return -EINVAL;
767 n = go->sensor_framerate *
768 parm->parm.capture.timeperframe.numerator;
769 d = 1001 * parm->parm.capture.timeperframe.denominator;
770 if (n != 0 && d != 0 && n > d)
771 go->fps_scale = (n + d/2) / d;
772 else
773 go->fps_scale = 1;
774 return 0;
775 }
776 case VIDIOC_ENUMSTD:
777 {
778 struct v4l2_standard *std = arg;
779
780 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
781 go->input == go->board_info->num_inputs - 1) {
782 if (!go->i2c_adapter_online)
783 return -EIO;
784 i2c_clients_command(&go->i2c_adapter,
785 VIDIOC_ENUMSTD, arg);
786 if (!std->id) /* hack to indicate EINVAL from tuner */
787 return -EINVAL;
788 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
789 switch (std->index) {
790 case 0:
791 v4l2_video_std_construct(std,
792 V4L2_STD_NTSC, "NTSC");
793 break;
794 case 1:
795 v4l2_video_std_construct(std,
796 V4L2_STD_PAL | V4L2_STD_SECAM,
797 "PAL/SECAM");
798 break;
799 default:
800 return -EINVAL;
801 }
802 } else {
803 if (std->index != 0)
804 return -EINVAL;
805 memset(std, 0, sizeof(*std));
806 snprintf(std->name, sizeof(std->name), "%dx%d, %dfps",
807 go->board_info->sensor_width,
808 go->board_info->sensor_height,
809 go->board_info->sensor_framerate / 1000);
810 std->frameperiod.numerator = 1001;
811 std->frameperiod.denominator =
812 go->board_info->sensor_framerate;
813 }
814 return 0;
815 }
816 case VIDIOC_G_STD:
817 {
818 v4l2_std_id *std = arg;
819
820 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
821 go->input == go->board_info->num_inputs - 1) {
822 if (!go->i2c_adapter_online)
823 return -EIO;
824 i2c_clients_command(&go->i2c_adapter,
825 VIDIOC_G_STD, arg);
826 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
827 if (go->standard == GO7007_STD_NTSC)
828 *std = V4L2_STD_NTSC;
829 else
830 *std = V4L2_STD_PAL | V4L2_STD_SECAM;
831 } else
832 *std = 0;
833 return 0;
834 }
835 case VIDIOC_S_STD:
836 {
837 v4l2_std_id *std = arg;
838 int norm;
839
840 if (go->streaming)
841 return -EBUSY;
842 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
843 *std != 0)
844 return -EINVAL;
845 if (*std == 0)
846 return -EINVAL;
847 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
848 go->input == go->board_info->num_inputs - 1) {
849 if (!go->i2c_adapter_online)
850 return -EIO;
851 i2c_clients_command(&go->i2c_adapter,
852 VIDIOC_S_STD, arg);
853 if (!*std) /* hack to indicate EINVAL from tuner */
854 return -EINVAL;
855 }
856 if (*std & V4L2_STD_NTSC) {
857 go->standard = GO7007_STD_NTSC;
858 go->sensor_framerate = 30000;
859 norm = VIDEO_MODE_NTSC;
860 } else if (*std & V4L2_STD_PAL) {
861 go->standard = GO7007_STD_PAL;
862 go->sensor_framerate = 25025;
863 norm = VIDEO_MODE_PAL;
864 } else if (*std & V4L2_STD_SECAM) {
865 go->standard = GO7007_STD_PAL;
866 go->sensor_framerate = 25025;
867 norm = VIDEO_MODE_SECAM;
868 } else
869 return -EINVAL;
870 if (go->i2c_adapter_online)
871 i2c_clients_command(&go->i2c_adapter,
872 DECODER_SET_NORM, &norm);
873 set_capture_size(go, NULL, 0);
874 return 0;
875 }
876 case VIDIOC_QUERYSTD:
877 {
878 v4l2_std_id *std = arg;
879
880 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
881 go->input == go->board_info->num_inputs - 1) {
882 if (!go->i2c_adapter_online)
883 return -EIO;
884 i2c_clients_command(&go->i2c_adapter,
885 VIDIOC_QUERYSTD, arg);
886 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
887 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
888 else
889 *std = 0;
890 return 0;
891 }
892 case VIDIOC_ENUMINPUT:
893 {
894 struct v4l2_input *inp = arg;
895 int index;
896
897 if (inp->index >= go->board_info->num_inputs)
898 return -EINVAL;
899 index = inp->index;
900 memset(inp, 0, sizeof(*inp));
901 inp->index = index;
902 strncpy(inp->name, go->board_info->inputs[index].name,
903 sizeof(inp->name));
904 /* If this board has a tuner, it will be the last input */
905 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
906 index == go->board_info->num_inputs - 1)
907 inp->type = V4L2_INPUT_TYPE_TUNER;
908 else
909 inp->type = V4L2_INPUT_TYPE_CAMERA;
910 inp->audioset = 0;
911 inp->tuner = 0;
912 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
913 inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
914 V4L2_STD_SECAM;
915 else
916 inp->std = 0;
917 return 0;
918 }
919 case VIDIOC_G_INPUT:
920 {
921 int *input = arg;
922
923 *input = go->input;
924 return 0;
925 }
926 case VIDIOC_S_INPUT:
927 {
928 int *input = arg;
929
930 if (*input >= go->board_info->num_inputs)
931 return -EINVAL;
932 if (go->streaming)
933 return -EBUSY;
934 go->input = *input;
935 if (go->i2c_adapter_online) {
936 i2c_clients_command(&go->i2c_adapter, DECODER_SET_INPUT,
937 &go->board_info->inputs[*input].video_input);
938 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO,
939 &go->board_info->inputs[*input].audio_input);
940 }
941 return 0;
942 }
943 case VIDIOC_G_TUNER:
944 {
945 struct v4l2_tuner *t = arg;
946
947 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
948 return -EINVAL;
949 if (t->index != 0)
950 return -EINVAL;
951 if (!go->i2c_adapter_online)
952 return -EIO;
953 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, arg);
954 t->index = 0;
955 return 0;
956 }
957 case VIDIOC_S_TUNER:
958 {
959 struct v4l2_tuner *t = arg;
960
961 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
962 return -EINVAL;
963 if (t->index != 0)
964 return -EINVAL;
965 if (!go->i2c_adapter_online)
966 return -EIO;
967 switch (go->board_id) {
968 case GO7007_BOARDID_PX_TV402U_NA:
969 case GO7007_BOARDID_PX_TV402U_JP:
970 /* No selectable options currently */
971 if (t->audmode != V4L2_TUNER_MODE_STEREO)
972 return -EINVAL;
973 break;
974 }
975 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, arg);
976 return 0;
977 }
978 case VIDIOC_G_FREQUENCY:
979 {
980 struct v4l2_frequency *f = arg;
981
982 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
983 return -EINVAL;
984 if (!go->i2c_adapter_online)
985 return -EIO;
986 memset(f, 0, sizeof(*f));
987 f->type = V4L2_TUNER_ANALOG_TV;
988 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, arg);
989 return 0;
990 }
991 case VIDIOC_S_FREQUENCY:
992 {
993 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
994 return -EINVAL;
995 if (!go->i2c_adapter_online)
996 return -EIO;
997 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, arg);
998 return 0;
999 }
1000 case VIDIOC_CROPCAP:
1001 {
1002 struct v4l2_cropcap *cropcap = arg;
1003
1004 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1005 return -EINVAL;
1006 memset(cropcap, 0, sizeof(*cropcap));
1007 cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1008 /* These specify the raw input of the sensor */
1009 switch (go->standard) {
1010 case GO7007_STD_NTSC:
1011 cropcap->bounds.top = 0;
1012 cropcap->bounds.left = 0;
1013 cropcap->bounds.width = 720;
1014 cropcap->bounds.height = 480;
1015 cropcap->defrect.top = 0;
1016 cropcap->defrect.left = 0;
1017 cropcap->defrect.width = 720;
1018 cropcap->defrect.height = 480;
1019 break;
1020 case GO7007_STD_PAL:
1021 cropcap->bounds.top = 0;
1022 cropcap->bounds.left = 0;
1023 cropcap->bounds.width = 720;
1024 cropcap->bounds.height = 576;
1025 cropcap->defrect.top = 0;
1026 cropcap->defrect.left = 0;
1027 cropcap->defrect.width = 720;
1028 cropcap->defrect.height = 576;
1029 break;
1030 case GO7007_STD_OTHER:
1031 cropcap->bounds.top = 0;
1032 cropcap->bounds.left = 0;
1033 cropcap->bounds.width = go->board_info->sensor_width;
1034 cropcap->bounds.height = go->board_info->sensor_height;
1035 cropcap->defrect.top = 0;
1036 cropcap->defrect.left = 0;
1037 cropcap->defrect.width = go->board_info->sensor_width;
1038 cropcap->defrect.height = go->board_info->sensor_height;
1039 break;
1040 }
1041
1042 return 0;
1043 }
1044 case VIDIOC_G_CROP:
1045 {
1046 struct v4l2_crop *crop = arg;
1047
1048 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1049 return -EINVAL;
1050 memset(crop, 0, sizeof(*crop));
1051 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1052 /* These specify the raw input of the sensor */
1053 switch (go->standard) {
1054 case GO7007_STD_NTSC:
1055 crop->c.top = 0;
1056 crop->c.left = 0;
1057 crop->c.width = 720;
1058 crop->c.height = 480;
1059 break;
1060 case GO7007_STD_PAL:
1061 crop->c.top = 0;
1062 crop->c.left = 0;
1063 crop->c.width = 720;
1064 crop->c.height = 576;
1065 break;
1066 case GO7007_STD_OTHER:
1067 crop->c.top = 0;
1068 crop->c.left = 0;
1069 crop->c.width = go->board_info->sensor_width;
1070 crop->c.height = go->board_info->sensor_height;
1071 break;
1072 }
1073
1074 return 0;
1075 }
1076 case VIDIOC_S_CROP:
1077 {
1078 struct v4l2_crop *crop = arg;
1079
1080 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1081 return -EINVAL;
1082 return 0;
1083 }
1084 case VIDIOC_G_JPEGCOMP:
1085 {
1086 struct v4l2_jpegcompression *params = arg;
1087
1088 memset(params, 0, sizeof(*params));
1089 params->quality = 50; /* ?? */
1090 params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1091 V4L2_JPEG_MARKER_DQT;
1092
1093 return 0;
1094 }
1095 case VIDIOC_S_JPEGCOMP:
1096 {
1097 struct v4l2_jpegcompression *params = arg;
1098
1099 if (params->quality != 50 ||
1100 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1101 V4L2_JPEG_MARKER_DQT))
1102 return -EINVAL;
1103 return 0;
1104 }
1105 /* Temporary ioctls for controlling compression characteristics */
1106 case GO7007IOC_S_BITRATE:
1107 {
1108 int *bitrate = arg;
1109
1110 if (go->streaming)
1111 return -EINVAL;
1112 /* Upper bound is kind of arbitrary here */
1113 if (*bitrate < 64000 || *bitrate > 10000000)
1114 return -EINVAL;
1115 go->bitrate = *bitrate;
1116 return 0;
1117 }
1118 case GO7007IOC_G_BITRATE:
1119 {
1120 int *bitrate = arg;
1121
1122 *bitrate = go->bitrate;
1123 return 0;
1124 }
1125 case GO7007IOC_S_COMP_PARAMS:
1126 {
1127 struct go7007_comp_params *comp = arg;
1128
1129 if (go->format == GO7007_FORMAT_MJPEG)
1130 return -EINVAL;
1131 if (comp->gop_size > 0)
1132 go->gop_size = comp->gop_size;
1133 else
1134 go->gop_size = go->sensor_framerate / 1000;
1135 if (go->gop_size != 15)
1136 go->dvd_mode = 0;
1137 /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
1138 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1139 switch (comp->aspect_ratio) {
1140 case GO7007_ASPECT_RATIO_4_3_NTSC:
1141 case GO7007_ASPECT_RATIO_4_3_PAL:
1142 go->aspect_ratio = GO7007_RATIO_4_3;
1143 break;
1144 case GO7007_ASPECT_RATIO_16_9_NTSC:
1145 case GO7007_ASPECT_RATIO_16_9_PAL:
1146 go->aspect_ratio = GO7007_RATIO_16_9;
1147 break;
1148 default:
1149 go->aspect_ratio = GO7007_RATIO_1_1;
1150 break;
1151 }
1152 }
1153 if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1154 go->dvd_mode = 0;
1155 go->seq_header_enable = 0;
1156 } else {
1157 go->seq_header_enable = 1;
1158 }
1159 /* fall-through */
1160 }
1161 case GO7007IOC_G_COMP_PARAMS:
1162 {
1163 struct go7007_comp_params *comp = arg;
1164
1165 if (go->format == GO7007_FORMAT_MJPEG)
1166 return -EINVAL;
1167 memset(comp, 0, sizeof(*comp));
1168 comp->gop_size = go->gop_size;
1169 comp->max_b_frames = go->ipb ? 2 : 0;
1170 switch (go->aspect_ratio) {
1171 case GO7007_RATIO_4_3:
1172 if (go->standard == GO7007_STD_NTSC)
1173 comp->aspect_ratio =
1174 GO7007_ASPECT_RATIO_4_3_NTSC;
1175 else
1176 comp->aspect_ratio =
1177 GO7007_ASPECT_RATIO_4_3_PAL;
1178 break;
1179 case GO7007_RATIO_16_9:
1180 if (go->standard == GO7007_STD_NTSC)
1181 comp->aspect_ratio =
1182 GO7007_ASPECT_RATIO_16_9_NTSC;
1183 else
1184 comp->aspect_ratio =
1185 GO7007_ASPECT_RATIO_16_9_PAL;
1186 break;
1187 default:
1188 comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1189 break;
1190 }
1191 if (go->closed_gop)
1192 comp->flags |= GO7007_COMP_CLOSED_GOP;
1193 if (!go->seq_header_enable)
1194 comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1195 return 0;
1196 }
1197 case GO7007IOC_S_MPEG_PARAMS:
1198 {
1199 struct go7007_mpeg_params *mpeg = arg;
1200
1201 if (go->format != GO7007_FORMAT_MPEG1 &&
1202 go->format != GO7007_FORMAT_MPEG2 &&
1203 go->format != GO7007_FORMAT_MPEG4)
1204 return -EINVAL;
1205
1206 if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1207 go->format = GO7007_FORMAT_MPEG2;
1208 go->bitrate = 9800000;
1209 go->gop_size = 15;
1210 go->pali = 0x48;
1211 go->closed_gop = 1;
1212 go->repeat_seqhead = 0;
1213 go->seq_header_enable = 1;
1214 go->gop_header_enable = 1;
1215 go->dvd_mode = 1;
1216 } else {
1217 switch (mpeg->mpeg_video_standard) {
1218 case GO7007_MPEG_VIDEO_MPEG1:
1219 go->format = GO7007_FORMAT_MPEG1;
1220 go->pali = 0;
1221 break;
1222 case GO7007_MPEG_VIDEO_MPEG2:
1223 go->format = GO7007_FORMAT_MPEG2;
1224 if (mpeg->pali >> 24 == 2)
1225 go->pali = mpeg->pali & 0xff;
1226 else
1227 go->pali = 0x48;
1228 break;
1229 case GO7007_MPEG_VIDEO_MPEG4:
1230 go->format = GO7007_FORMAT_MPEG4;
1231 if (mpeg->pali >> 24 == 4)
1232 go->pali = mpeg->pali & 0xff;
1233 else
1234 go->pali = 0xf5;
1235 break;
1236 default:
1237 return -EINVAL;
1238 }
1239 go->gop_header_enable =
1240 mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1241 ? 0 : 1;
1242 if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1243 go->repeat_seqhead = 1;
1244 else
1245 go->repeat_seqhead = 0;
1246 go->dvd_mode = 0;
1247 }
1248 /* fall-through */
1249 }
1250 case GO7007IOC_G_MPEG_PARAMS:
1251 {
1252 struct go7007_mpeg_params *mpeg = arg;
1253
1254 memset(mpeg, 0, sizeof(*mpeg));
1255 switch (go->format) {
1256 case GO7007_FORMAT_MPEG1:
1257 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1258 mpeg->pali = 0;
1259 break;
1260 case GO7007_FORMAT_MPEG2:
1261 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1262 mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1263 break;
1264 case GO7007_FORMAT_MPEG4:
1265 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1266 mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1267 break;
1268 default:
1269 return -EINVAL;
1270 }
1271 if (!go->gop_header_enable)
1272 mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1273 if (go->repeat_seqhead)
1274 mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1275 if (go->dvd_mode)
1276 mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1277 return 0;
1278 }
1279 case GO7007IOC_S_MD_PARAMS:
1280 {
1281 struct go7007_md_params *mdp = arg;
1282
1283 if (mdp->region > 3)
1284 return -EINVAL;
1285 if (mdp->trigger > 0) {
1286 go->modet[mdp->region].pixel_threshold =
1287 mdp->pixel_threshold >> 1;
1288 go->modet[mdp->region].motion_threshold =
1289 mdp->motion_threshold >> 1;
1290 go->modet[mdp->region].mb_threshold =
1291 mdp->trigger >> 1;
1292 go->modet[mdp->region].enable = 1;
1293 } else
1294 go->modet[mdp->region].enable = 0;
1295 /* fall-through */
1296 }
1297 case GO7007IOC_G_MD_PARAMS:
1298 {
1299 struct go7007_md_params *mdp = arg;
1300 int region = mdp->region;
1301
1302 if (mdp->region > 3)
1303 return -EINVAL;
1304 memset(mdp, 0, sizeof(struct go7007_md_params));
1305 mdp->region = region;
1306 if (!go->modet[region].enable)
1307 return 0;
1308 mdp->pixel_threshold =
1309 (go->modet[region].pixel_threshold << 1) + 1;
1310 mdp->motion_threshold =
1311 (go->modet[region].motion_threshold << 1) + 1;
1312 mdp->trigger =
1313 (go->modet[region].mb_threshold << 1) + 1;
1314 return 0;
1315 }
1316 case GO7007IOC_S_MD_REGION:
1317 {
1318 struct go7007_md_region *region = arg;
1319
1320 if (region->region < 1 || region->region > 3)
1321 return -EINVAL;
1322 return clip_to_modet_map(go, region->region, region->clips);
1323 }
1324 default:
1325 printk(KERN_DEBUG "go7007: unsupported ioctl %d\n", cmd);
1326 return -ENOIOCTLCMD;
1327 }
1328 return 0;
1329
1330unlock_and_return:
1331 up(&gofh->lock);
1332 return retval;
1333}
1334
1335static int go7007_ioctl(struct inode *inode, struct file *file,
1336 unsigned int cmd, unsigned long arg)
1337{
1338 struct go7007_file *gofh = file->private_data;
1339
1340 if (gofh->go->status != STATUS_ONLINE)
1341 return -EIO;
1342
1343 return video_usercopy(inode, file, cmd, arg, go7007_do_ioctl);
1344}
1345
1346static ssize_t go7007_read(struct file *file, char __user *data,
1347 size_t count, loff_t *ppos)
1348{
1349 return -EINVAL;
1350}
1351
1352static void go7007_vm_open(struct vm_area_struct *vma)
1353{
1354 struct go7007_buffer *gobuf = vma->vm_private_data;
1355
1356 ++gobuf->mapped;
1357}
1358
1359static void go7007_vm_close(struct vm_area_struct *vma)
1360{
1361 struct go7007_buffer *gobuf = vma->vm_private_data;
1362 unsigned long flags;
1363
1364 if (--gobuf->mapped == 0) {
1365 spin_lock_irqsave(&gobuf->go->spinlock, flags);
1366 deactivate_buffer(gobuf);
1367 spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1368 }
1369}
1370
1371/* Copied from videobuf-dma-sg.c */
1372static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1373{
1374 struct page *page;
1375
1376 page = alloc_page(GFP_USER | __GFP_DMA32);
1377 if (!page)
1378 return VM_FAULT_OOM;
1379 clear_user_page(page_address(page), (unsigned long)vmf->virtual_address,
1380 page);
1381 vmf->page = page;
1382 return 0;
1383}
1384
1385static struct vm_operations_struct go7007_vm_ops = {
1386 .open = go7007_vm_open,
1387 .close = go7007_vm_close,
1388 .fault = go7007_vm_fault,
1389};
1390
1391static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1392{
1393 struct go7007_file *gofh = file->private_data;
1394 unsigned int index;
1395
1396 if (gofh->go->status != STATUS_ONLINE)
1397 return -EIO;
1398 if (!(vma->vm_flags & VM_SHARED))
1399 return -EINVAL; /* only support VM_SHARED mapping */
1400 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1401 return -EINVAL; /* must map exactly one full buffer */
1402 down(&gofh->lock);
1403 index = vma->vm_pgoff / GO7007_BUF_PAGES;
1404 if (index >= gofh->buf_count) {
1405 up(&gofh->lock);
1406 return -EINVAL; /* trying to map beyond requested buffers */
1407 }
1408 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1409 up(&gofh->lock);
1410 return -EINVAL; /* offset is not aligned on buffer boundary */
1411 }
1412 if (gofh->bufs[index].mapped > 0) {
1413 up(&gofh->lock);
1414 return -EBUSY;
1415 }
1416 gofh->bufs[index].mapped = 1;
1417 gofh->bufs[index].user_addr = vma->vm_start;
1418 vma->vm_ops = &go7007_vm_ops;
1419 vma->vm_flags |= VM_DONTEXPAND;
1420 vma->vm_flags &= ~VM_IO;
1421 vma->vm_private_data = &gofh->bufs[index];
1422 up(&gofh->lock);
1423 return 0;
1424}
1425
1426static unsigned int go7007_poll(struct file *file, poll_table *wait)
1427{
1428 struct go7007_file *gofh = file->private_data;
1429 struct go7007_buffer *gobuf;
1430
1431 if (list_empty(&gofh->go->stream))
1432 return POLLERR;
1433 gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1434 poll_wait(file, &gofh->go->frame_waitq, wait);
1435 if (gobuf->state == BUF_STATE_DONE)
1436 return POLLIN | POLLRDNORM;
1437 return 0;
1438}
1439
1440static void go7007_vfl_release(struct video_device *vfd)
1441{
1442 struct go7007 *go = video_get_drvdata(vfd);
1443
1444 video_device_release(vfd);
1445 if (--go->ref_count == 0)
1446 kfree(go);
1447}
1448
1449static struct file_operations go7007_fops = {
1450 .owner = THIS_MODULE,
1451 .open = go7007_open,
1452 .release = go7007_release,
1453 .ioctl = go7007_ioctl,
1454 .llseek = no_llseek,
1455 .read = go7007_read,
1456 .mmap = go7007_mmap,
1457 .poll = go7007_poll,
1458};
1459
1460static struct video_device go7007_template = {
1461 .name = "go7007",
1462 .fops = &go7007_fops,
1463 .minor = -1,
1464 .release = go7007_vfl_release,
1465};
1466
1467int go7007_v4l2_init(struct go7007 *go)
1468{
1469 int rv;
1470
1471 go->video_dev = video_device_alloc();
1472 if (go->video_dev == NULL)
1473 return -ENOMEM;
1474 memcpy(go->video_dev, &go7007_template, sizeof(go7007_template));
1475 go->video_dev->parent = go->dev;
1476 rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1477 if (rv < 0) {
1478 video_device_release(go->video_dev);
1479 go->video_dev = NULL;
1480 return rv;
1481 }
1482 video_set_drvdata(go->video_dev, go);
1483 ++go->ref_count;
1484
1485 return 0;
1486}
1487
1488void go7007_v4l2_remove(struct go7007 *go)
1489{
1490 unsigned long flags;
1491
1492 down(&go->hw_lock);
1493 if (go->streaming) {
1494 go->streaming = 0;
1495 go7007_stream_stop(go);
1496 spin_lock_irqsave(&go->spinlock, flags);
1497 abort_queued(go);
1498 spin_unlock_irqrestore(&go->spinlock, flags);
1499 }
1500 up(&go->hw_lock);
1501 if (go->video_dev)
1502 video_unregister_device(go->video_dev);
1503}
diff --git a/drivers/staging/go7007/go7007.h b/drivers/staging/go7007/go7007.h
new file mode 100644
index 00000000000..7399c915a93
--- /dev/null
+++ b/drivers/staging/go7007/go7007.h
@@ -0,0 +1,114 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and the associated README documentation file (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
13 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
14 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
15 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
16 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 */
19
20/* DEPRECATED -- use V4L2_PIX_FMT_MPEG and then call GO7007IOC_S_MPEG_PARAMS
21 * to select between MPEG1, MPEG2, and MPEG4 */
22#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG4 */
23
24/* These will be replaced with a better interface
25 * soon, so don't get too attached to them */
26#define GO7007IOC_S_BITRATE _IOW('V', BASE_VIDIOC_PRIVATE + 0, int)
27#define GO7007IOC_G_BITRATE _IOR('V', BASE_VIDIOC_PRIVATE + 1, int)
28
29enum go7007_aspect_ratio {
30 GO7007_ASPECT_RATIO_1_1 = 0,
31 GO7007_ASPECT_RATIO_4_3_NTSC = 1,
32 GO7007_ASPECT_RATIO_4_3_PAL = 2,
33 GO7007_ASPECT_RATIO_16_9_NTSC = 3,
34 GO7007_ASPECT_RATIO_16_9_PAL = 4,
35};
36
37/* Used to set generic compression parameters */
38struct go7007_comp_params {
39 __u32 gop_size;
40 __u32 max_b_frames;
41 enum go7007_aspect_ratio aspect_ratio;
42 __u32 flags;
43 __u32 reserved[8];
44};
45
46#define GO7007_COMP_CLOSED_GOP 0x00000001
47#define GO7007_COMP_OMIT_SEQ_HEADER 0x00000002
48
49enum go7007_mpeg_video_standard {
50 GO7007_MPEG_VIDEO_MPEG1 = 0,
51 GO7007_MPEG_VIDEO_MPEG2 = 1,
52 GO7007_MPEG_VIDEO_MPEG4 = 2,
53};
54
55/* Used to set parameters for V4L2_PIX_FMT_MPEG format */
56struct go7007_mpeg_params {
57 enum go7007_mpeg_video_standard mpeg_video_standard;
58 __u32 flags;
59 __u32 pali;
60 __u32 reserved[8];
61};
62
63#define GO7007_MPEG_FORCE_DVD_MODE 0x00000001
64#define GO7007_MPEG_OMIT_GOP_HEADER 0x00000002
65#define GO7007_MPEG_REPEAT_SEQHEADER 0x00000004
66
67#define GO7007_MPEG_PROFILE(format, pali) (((format)<<24)|(pali))
68
69#define GO7007_MPEG2_PROFILE_MAIN_MAIN GO7007_MPEG_PROFILE(2, 0x48)
70
71#define GO7007_MPEG4_PROFILE_S_L0 GO7007_MPEG_PROFILE(4, 0x08)
72#define GO7007_MPEG4_PROFILE_S_L1 GO7007_MPEG_PROFILE(4, 0x01)
73#define GO7007_MPEG4_PROFILE_S_L2 GO7007_MPEG_PROFILE(4, 0x02)
74#define GO7007_MPEG4_PROFILE_S_L3 GO7007_MPEG_PROFILE(4, 0x03)
75#define GO7007_MPEG4_PROFILE_ARTS_L1 GO7007_MPEG_PROFILE(4, 0x91)
76#define GO7007_MPEG4_PROFILE_ARTS_L2 GO7007_MPEG_PROFILE(4, 0x92)
77#define GO7007_MPEG4_PROFILE_ARTS_L3 GO7007_MPEG_PROFILE(4, 0x93)
78#define GO7007_MPEG4_PROFILE_ARTS_L4 GO7007_MPEG_PROFILE(4, 0x94)
79#define GO7007_MPEG4_PROFILE_AS_L0 GO7007_MPEG_PROFILE(4, 0xf0)
80#define GO7007_MPEG4_PROFILE_AS_L1 GO7007_MPEG_PROFILE(4, 0xf1)
81#define GO7007_MPEG4_PROFILE_AS_L2 GO7007_MPEG_PROFILE(4, 0xf2)
82#define GO7007_MPEG4_PROFILE_AS_L3 GO7007_MPEG_PROFILE(4, 0xf3)
83#define GO7007_MPEG4_PROFILE_AS_L4 GO7007_MPEG_PROFILE(4, 0xf4)
84#define GO7007_MPEG4_PROFILE_AS_L5 GO7007_MPEG_PROFILE(4, 0xf5)
85
86struct go7007_md_params {
87 __u16 region;
88 __u16 trigger;
89 __u16 pixel_threshold;
90 __u16 motion_threshold;
91 __u32 reserved[8];
92};
93
94struct go7007_md_region {
95 __u16 region;
96 __u16 flags;
97 struct v4l2_clip *clips;
98 __u32 reserved[8];
99};
100
101#define GO7007IOC_S_MPEG_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 2, \
102 struct go7007_mpeg_params)
103#define GO7007IOC_G_MPEG_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 3, \
104 struct go7007_mpeg_params)
105#define GO7007IOC_S_COMP_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 4, \
106 struct go7007_comp_params)
107#define GO7007IOC_G_COMP_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 5, \
108 struct go7007_comp_params)
109#define GO7007IOC_S_MD_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 6, \
110 struct go7007_md_params)
111#define GO7007IOC_G_MD_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 7, \
112 struct go7007_md_params)
113#define GO7007IOC_S_MD_REGION _IOW('V', BASE_VIDIOC_PRIVATE + 8, \
114 struct go7007_md_region)
diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/go7007/saa7134-go7007.c
new file mode 100644
index 00000000000..c4a6d8ef907
--- /dev/null
+++ b/drivers/staging/go7007/saa7134-go7007.c
@@ -0,0 +1,484 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/spinlock.h>
22#include <linux/wait.h>
23#include <linux/list.h>
24#include <linux/slab.h>
25#include <linux/time.h>
26#include <linux/mm.h>
27#include <linux/usb.h>
28#include <linux/i2c.h>
29#include <asm/byteorder.h>
30#include <media/audiochip.h>
31
32#include "saa7134-reg.h"
33#include "saa7134.h"
34#include "go7007-priv.h"
35
36#define GO7007_HPI_DEBUG
37
38enum hpi_address {
39 HPI_ADDR_VIDEO_BUFFER = 0xe4,
40 HPI_ADDR_INIT_BUFFER = 0xea,
41 HPI_ADDR_INTR_RET_VALUE = 0xee,
42 HPI_ADDR_INTR_RET_DATA = 0xec,
43 HPI_ADDR_INTR_STATUS = 0xf4,
44 HPI_ADDR_INTR_WR_PARAM = 0xf6,
45 HPI_ADDR_INTR_WR_INDEX = 0xf8,
46};
47
48enum gpio_command {
49 GPIO_COMMAND_RESET = 0x00, /* 000b */
50 GPIO_COMMAND_REQ1 = 0x04, /* 001b */
51 GPIO_COMMAND_WRITE = 0x20, /* 010b */
52 GPIO_COMMAND_REQ2 = 0x24, /* 011b */
53 GPIO_COMMAND_READ = 0x80, /* 100b */
54 GPIO_COMMAND_VIDEO = 0x84, /* 101b */
55 GPIO_COMMAND_IDLE = 0xA0, /* 110b */
56 GPIO_COMMAND_ADDR = 0xA4, /* 111b */
57};
58
59struct saa7134_go7007 {
60 struct saa7134_dev *dev;
61 u8 *top;
62 u8 *bottom;
63 dma_addr_t top_dma;
64 dma_addr_t bottom_dma;
65};
66
67static struct go7007_board_info board_voyager = {
68 .firmware = "go7007tv.bin",
69 .flags = 0,
70 .sensor_flags = GO7007_SENSOR_656 |
71 GO7007_SENSOR_VALID_ENABLE |
72 GO7007_SENSOR_TV |
73 GO7007_SENSOR_VBI,
74 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
75 GO7007_AUDIO_WORD_16,
76 .audio_rate = 48000,
77 .audio_bclk_div = 8,
78 .audio_main_div = 2,
79 .hpi_buffer_cap = 7,
80 .num_inputs = 1,
81 .inputs = {
82 {
83 .name = "SAA7134",
84 },
85 },
86};
87
88/********************* Driver for GPIO HPI interface *********************/
89
90static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
91{
92 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
93
94 /* Write HPI address */
95 saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
96 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
97 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
98
99 /* Write low byte */
100 saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
101 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
102 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
103
104 /* Write high byte */
105 saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8);
106 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
107 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
108
109 return 0;
110}
111
112static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
113{
114 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
115
116 /* Write HPI address */
117 saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
118 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
119 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
120
121 saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
122
123 /* Read low byte */
124 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
125 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
126 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
127 *data = saa_readb(SAA7134_GPIO_GPSTATUS0);
128 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
129
130 /* Read high byte */
131 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
132 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
133 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
134 *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
135 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
136
137 return 0;
138}
139
140static int saa7134_go7007_interface_reset(struct go7007 *go)
141{
142 struct saa7134_go7007 *saa = go->hpi_context;
143 struct saa7134_dev *dev = saa->dev;
144 u32 status;
145 u16 intr_val, intr_data;
146 int count = 20;
147
148 saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
149 saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4);
150 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
151
152 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
153 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET);
154 msleep(1);
155 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
156 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
157 msleep(10);
158
159 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
160 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
161
162 status = saa_readb(SAA7134_GPIO_GPSTATUS2);
163 /*printk(KERN_DEBUG "status is %s\n", status & 0x40 ? "OK" : "not OK"); */
164
165 /* enter command mode...(?) */
166 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
167 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
168
169 do {
170 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
171 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
172 status = saa_readb(SAA7134_GPIO_GPSTATUS2);
173 /*printk(KERN_INFO "gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
174 } while (--count > 0);
175
176 /* Wait for an interrupt to indicate successful hardware reset */
177 if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
178 (intr_val & ~0x1) != 0x55aa) {
179 printk(KERN_ERR
180 "saa7134-go7007: unable to reset the GO7007\n");
181 return -1;
182 }
183 return 0;
184}
185
186static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
187{
188 struct saa7134_go7007 *saa = go->hpi_context;
189 struct saa7134_dev *dev = saa->dev;
190 int i;
191 u16 status_reg;
192
193#ifdef GO7007_HPI_DEBUG
194 printk(KERN_DEBUG
195 "saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
196#endif
197
198 for (i = 0; i < 100; ++i) {
199 gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
200 if (!(status_reg & 0x0010))
201 break;
202 msleep(10);
203 }
204 if (i == 100) {
205 printk(KERN_ERR
206 "saa7134-go7007: device is hung, status reg = 0x%04x\n",
207 status_reg);
208 return -1;
209 }
210 gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data);
211 gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr);
212
213 return 0;
214}
215
216static int saa7134_go7007_read_interrupt(struct go7007 *go)
217{
218 struct saa7134_go7007 *saa = go->hpi_context;
219 struct saa7134_dev *dev = saa->dev;
220
221 /* XXX we need to wait if there is no interrupt available */
222 go->interrupt_available = 1;
223 gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value);
224 gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data);
225#ifdef GO7007_HPI_DEBUG
226 printk(KERN_DEBUG "saa7134-go7007: ReadInterrupt: %04x %04x\n",
227 go->interrupt_value, go->interrupt_data);
228#endif
229 return 0;
230}
231
232static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
233 unsigned long status)
234{
235 struct go7007 *go = video_get_drvdata(dev->empress_dev);
236 struct saa7134_go7007 *saa = go->hpi_context;
237
238 if (!go->streaming)
239 return;
240 if (0 != (status & 0x000f0000))
241 printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n",
242 (status >> 16) & 0x0f);
243 if (status & 0x100000) {
244 dma_sync_single(&dev->pci->dev,
245 saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE);
246 go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE);
247 saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
248 } else {
249 dma_sync_single(&dev->pci->dev,
250 saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE);
251 go7007_parse_video_stream(go, saa->top, PAGE_SIZE);
252 saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
253 }
254}
255
256static int saa7134_go7007_stream_start(struct go7007 *go)
257{
258 struct saa7134_go7007 *saa = go->hpi_context;
259 struct saa7134_dev *dev = saa->dev;
260
261 saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
262 0, PAGE_SIZE, DMA_FROM_DEVICE);
263 if (!saa->top_dma)
264 return -ENOMEM;
265 saa->bottom_dma = dma_map_page(&dev->pci->dev,
266 virt_to_page(saa->bottom),
267 0, PAGE_SIZE, DMA_FROM_DEVICE);
268 if (!saa->bottom_dma) {
269 dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
270 DMA_FROM_DEVICE);
271 return -ENOMEM;
272 }
273
274 saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
275 saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
276
277 /* Set HPI interface for video */
278 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
279 saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER);
280 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
281 saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
282
283 /* Enable TS interface */
284 saa_writeb(SAA7134_TS_PARALLEL, 0xe6);
285
286 /* Reset TS interface */
287 saa_setb(SAA7134_TS_SERIAL1, 0x01);
288 saa_clearb(SAA7134_TS_SERIAL1, 0x01);
289
290 /* Set up transfer block size */
291 saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1);
292 saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1);
293 saa_writeb(SAA7134_TS_DMA1, 0);
294 saa_writeb(SAA7134_TS_DMA2, 0);
295
296 /* Enable video streaming mode */
297 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO);
298
299 saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
300 saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
301 saa_writel(SAA7134_RS_PITCH(5), 128);
302 saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX);
303
304 /* Enable TS FIFO */
305 saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
306
307 /* Enable DMA IRQ */
308 saa_setl(SAA7134_IRQ1,
309 SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
310
311 return 0;
312}
313
314static int saa7134_go7007_stream_stop(struct go7007 *go)
315{
316 struct saa7134_go7007 *saa = go->hpi_context;
317 struct saa7134_dev *dev = saa->dev;
318
319 /* Shut down TS FIFO */
320 saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
321
322 /* Disable DMA IRQ */
323 saa_clearl(SAA7134_IRQ1,
324 SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
325
326 /* Disable TS interface */
327 saa_clearb(SAA7134_TS_PARALLEL, 0x80);
328
329 dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
330 DMA_FROM_DEVICE);
331 dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
332 DMA_FROM_DEVICE);
333
334 return 0;
335}
336
337static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
338{
339 struct saa7134_go7007 *saa = go->hpi_context;
340 struct saa7134_dev *dev = saa->dev;
341 u16 status_reg;
342 int i;
343
344#ifdef GO7007_HPI_DEBUG
345 printk(KERN_DEBUG "saa7134-go7007: DownloadBuffer "
346 "sending %d bytes\n", len);
347#endif
348
349 while (len > 0) {
350 i = len > 64 ? 64 : len;
351 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
352 saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER);
353 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
354 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
355 while (i-- > 0) {
356 saa_writeb(SAA7134_GPIO_GPSTATUS0, *data);
357 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
358 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
359 ++data;
360 --len;
361 }
362 for (i = 0; i < 100; ++i) {
363 gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
364 if (!(status_reg & 0x0002))
365 break;
366 }
367 if (i == 100) {
368 printk(KERN_ERR "saa7134-go7007: device is hung, "
369 "status reg = 0x%04x\n", status_reg);
370 return -1;
371 }
372 }
373 return 0;
374}
375
376static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
377 .interface_reset = saa7134_go7007_interface_reset,
378 .write_interrupt = saa7134_go7007_write_interrupt,
379 .read_interrupt = saa7134_go7007_read_interrupt,
380 .stream_start = saa7134_go7007_stream_start,
381 .stream_stop = saa7134_go7007_stream_stop,
382 .send_firmware = saa7134_go7007_send_firmware,
383};
384
385/********************* Add/remove functions *********************/
386
387static int saa7134_go7007_init(struct saa7134_dev *dev)
388{
389 struct go7007 *go;
390 struct saa7134_go7007 *saa;
391
392 printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n");
393
394 saa = kmalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
395 if (saa == NULL)
396 return -ENOMEM;
397 memset(saa, 0, sizeof(struct saa7134_go7007));
398
399 /* Allocate a couple pages for receiving the compressed stream */
400 saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
401 if (!saa->top)
402 goto allocfail;
403 saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
404 if (!saa->bottom)
405 goto allocfail;
406
407 go = go7007_alloc(&board_voyager, &dev->pci->dev);
408 if (go == NULL)
409 goto allocfail;
410 go->board_id = GO7007_BOARDID_PCI_VOYAGER;
411 strncpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
412 go->hpi_ops = &saa7134_go7007_hpi_ops;
413 go->hpi_context = saa;
414 saa->dev = dev;
415
416 /* Boot the GO7007 */
417 if (go7007_boot_encoder(go, go->board_info->flags &
418 GO7007_BOARD_USE_ONBOARD_I2C) < 0)
419 goto initfail;
420
421 /* Do any final GO7007 initialization, then register the
422 * V4L2 and ALSA interfaces */
423 if (go7007_register_encoder(go) < 0)
424 goto initfail;
425 dev->empress_dev = go->video_dev;
426 video_set_drvdata(dev->empress_dev, go);
427
428 go->status = STATUS_ONLINE;
429 return 0;
430
431initfail:
432 go->status = STATUS_SHUTDOWN;
433 return 0;
434
435allocfail:
436 if (saa->top)
437 free_page((unsigned long)saa->top);
438 if (saa->bottom)
439 free_page((unsigned long)saa->bottom);
440 kfree(saa);
441 return -ENOMEM;
442}
443
444static int saa7134_go7007_fini(struct saa7134_dev *dev)
445{
446 struct go7007 *go;
447 struct saa7134_go7007 *saa;
448
449 if (NULL == dev->empress_dev)
450 return 0;
451
452 go = video_get_drvdata(dev->empress_dev);
453 saa = go->hpi_context;
454 go->status = STATUS_SHUTDOWN;
455 free_page((unsigned long)saa->top);
456 free_page((unsigned long)saa->bottom);
457 kfree(saa);
458 go7007_remove(go);
459 dev->empress_dev = NULL;
460
461 return 0;
462}
463
464static struct saa7134_mpeg_ops saa7134_go7007_ops = {
465 .type = SAA7134_MPEG_GO7007,
466 .init = saa7134_go7007_init,
467 .fini = saa7134_go7007_fini,
468 .irq_ts_done = saa7134_go7007_irq_ts_done,
469};
470
471static int __init saa7134_go7007_mod_init(void)
472{
473 return saa7134_ts_register(&saa7134_go7007_ops);
474}
475
476static void __exit saa7134_go7007_mod_cleanup(void)
477{
478 saa7134_ts_unregister(&saa7134_go7007_ops);
479}
480
481module_init(saa7134_go7007_mod_init);
482module_exit(saa7134_go7007_mod_cleanup);
483
484MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c
new file mode 100644
index 00000000000..f5cac08b07e
--- /dev/null
+++ b/drivers/staging/go7007/snd-go7007.c
@@ -0,0 +1,305 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/version.h>
21#include <linux/moduleparam.h>
22#include <linux/init.h>
23#include <linux/spinlock.h>
24#include <linux/delay.h>
25#include <linux/sched.h>
26#include <linux/vmalloc.h>
27#include <linux/time.h>
28#include <linux/mm.h>
29#include <linux/i2c.h>
30#include <linux/semaphore.h>
31#include <linux/uaccess.h>
32#include <asm/system.h>
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/initval.h>
36
37#include "go7007-priv.h"
38
39static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
40static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
41static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
42
43module_param_array(index, int, NULL, 0444);
44module_param_array(id, charp, NULL, 0444);
45module_param_array(enable, bool, NULL, 0444);
46MODULE_PARM_DESC(index, "Index value for the go7007 audio driver");
47MODULE_PARM_DESC(index, "ID string for the go7007 audio driver");
48MODULE_PARM_DESC(index, "Enable for the go7007 audio driver");
49
50struct go7007_snd {
51 struct snd_card *card;
52 struct snd_pcm *pcm;
53 struct snd_pcm_substream *substream;
54 spinlock_t lock;
55 int w_idx;
56 int hw_ptr;
57 int avail;
58 int capturing;
59};
60
61static struct snd_pcm_hardware go7007_snd_capture_hw = {
62 .info = (SNDRV_PCM_INFO_MMAP |
63 SNDRV_PCM_INFO_INTERLEAVED |
64 SNDRV_PCM_INFO_BLOCK_TRANSFER |
65 SNDRV_PCM_INFO_MMAP_VALID),
66 .formats = SNDRV_PCM_FMTBIT_S16_LE,
67 .rates = SNDRV_PCM_RATE_48000,
68 .rate_min = 48000,
69 .rate_max = 48000,
70 .channels_min = 2,
71 .channels_max = 2,
72 .buffer_bytes_max = (128*1024),
73 .period_bytes_min = 4096,
74 .period_bytes_max = (128*1024),
75 .periods_min = 1,
76 .periods_max = 32,
77};
78
79static void parse_audio_stream_data(struct go7007 *go, u8 *buf, int length)
80{
81 struct go7007_snd *gosnd = go->snd_context;
82 struct snd_pcm_runtime *runtime = gosnd->substream->runtime;
83 int frames = bytes_to_frames(runtime, length);
84
85 spin_lock(&gosnd->lock);
86 gosnd->hw_ptr += frames;
87 if (gosnd->hw_ptr >= runtime->buffer_size)
88 gosnd->hw_ptr -= runtime->buffer_size;
89 gosnd->avail += frames;
90 spin_unlock(&gosnd->lock);
91 if (gosnd->w_idx + length > runtime->dma_bytes) {
92 int cpy = runtime->dma_bytes - gosnd->w_idx;
93
94 memcpy(runtime->dma_area + gosnd->w_idx, buf, cpy);
95 length -= cpy;
96 buf += cpy;
97 gosnd->w_idx = 0;
98 }
99 memcpy(runtime->dma_area + gosnd->w_idx, buf, length);
100 gosnd->w_idx += length;
101 spin_lock(&gosnd->lock);
102 if (gosnd->avail < runtime->period_size) {
103 spin_unlock(&gosnd->lock);
104 return;
105 }
106 gosnd->avail -= runtime->period_size;
107 spin_unlock(&gosnd->lock);
108 if (gosnd->capturing)
109 snd_pcm_period_elapsed(gosnd->substream);
110}
111
112static int go7007_snd_hw_params(struct snd_pcm_substream *substream,
113 struct snd_pcm_hw_params *hw_params)
114{
115 struct go7007 *go = snd_pcm_substream_chip(substream);
116 unsigned int bytes;
117
118 bytes = params_buffer_bytes(hw_params);
119 if (substream->runtime->dma_bytes > 0)
120 vfree(substream->runtime->dma_area);
121 substream->runtime->dma_bytes = 0;
122 substream->runtime->dma_area = vmalloc(bytes);
123 if (substream->runtime->dma_area == NULL)
124 return -ENOMEM;
125 substream->runtime->dma_bytes = bytes;
126 go->audio_deliver = parse_audio_stream_data;
127 return 0;
128}
129
130static int go7007_snd_hw_free(struct snd_pcm_substream *substream)
131{
132 struct go7007 *go = snd_pcm_substream_chip(substream);
133
134 go->audio_deliver = NULL;
135 if (substream->runtime->dma_bytes > 0)
136 vfree(substream->runtime->dma_area);
137 substream->runtime->dma_bytes = 0;
138 return 0;
139}
140
141static int go7007_snd_capture_open(struct snd_pcm_substream *substream)
142{
143 struct go7007 *go = snd_pcm_substream_chip(substream);
144 struct go7007_snd *gosnd = go->snd_context;
145 unsigned long flags;
146 int r;
147
148 spin_lock_irqsave(&gosnd->lock, flags);
149 if (gosnd->substream == NULL) {
150 gosnd->substream = substream;
151 substream->runtime->hw = go7007_snd_capture_hw;
152 r = 0;
153 } else
154 r = -EBUSY;
155 spin_unlock_irqrestore(&gosnd->lock, flags);
156 return r;
157}
158
159static int go7007_snd_capture_close(struct snd_pcm_substream *substream)
160{
161 struct go7007 *go = snd_pcm_substream_chip(substream);
162 struct go7007_snd *gosnd = go->snd_context;
163
164 gosnd->substream = NULL;
165 return 0;
166}
167
168static int go7007_snd_pcm_prepare(struct snd_pcm_substream *substream)
169{
170 return 0;
171}
172
173static int go7007_snd_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
174{
175 struct go7007 *go = snd_pcm_substream_chip(substream);
176 struct go7007_snd *gosnd = go->snd_context;
177
178 switch (cmd) {
179 case SNDRV_PCM_TRIGGER_START:
180 /* Just set a flag to indicate we should signal ALSA when
181 * sound comes in */
182 gosnd->capturing = 1;
183 return 0;
184 case SNDRV_PCM_TRIGGER_STOP:
185 gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
186 gosnd->capturing = 0;
187 return 0;
188 default:
189 return -EINVAL;
190 }
191}
192
193static snd_pcm_uframes_t go7007_snd_pcm_pointer(struct snd_pcm_substream *substream)
194{
195 struct go7007 *go = snd_pcm_substream_chip(substream);
196 struct go7007_snd *gosnd = go->snd_context;
197
198 return gosnd->hw_ptr;
199}
200
201static struct page *go7007_snd_pcm_page(struct snd_pcm_substream *substream,
202 unsigned long offset)
203{
204 return vmalloc_to_page(substream->runtime->dma_area + offset);
205}
206
207static struct snd_pcm_ops go7007_snd_capture_ops = {
208 .open = go7007_snd_capture_open,
209 .close = go7007_snd_capture_close,
210 .ioctl = snd_pcm_lib_ioctl,
211 .hw_params = go7007_snd_hw_params,
212 .hw_free = go7007_snd_hw_free,
213 .prepare = go7007_snd_pcm_prepare,
214 .trigger = go7007_snd_pcm_trigger,
215 .pointer = go7007_snd_pcm_pointer,
216 .page = go7007_snd_pcm_page,
217};
218
219static int go7007_snd_free(struct snd_device *device)
220{
221 struct go7007 *go = device->device_data;
222
223 kfree(go->snd_context);
224 go->snd_context = NULL;
225 if (--go->ref_count == 0)
226 kfree(go);
227 return 0;
228}
229
230static struct snd_device_ops go7007_snd_device_ops = {
231 .dev_free = go7007_snd_free,
232};
233
234int go7007_snd_init(struct go7007 *go)
235{
236 static int dev;
237 struct go7007_snd *gosnd;
238 int ret = 0;
239
240 if (dev >= SNDRV_CARDS)
241 return -ENODEV;
242 if (!enable[dev]) {
243 dev++;
244 return -ENOENT;
245 }
246 gosnd = kmalloc(sizeof(struct go7007_snd), GFP_KERNEL);
247 if (gosnd == NULL)
248 return -ENOMEM;
249 spin_lock_init(&gosnd->lock);
250 gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
251 gosnd->capturing = 0;
252 gosnd->card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
253 if (gosnd->card == NULL) {
254 kfree(gosnd);
255 return -ENOMEM;
256 }
257 ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
258 &go7007_snd_device_ops);
259 if (ret < 0) {
260 kfree(gosnd);
261 return ret;
262 }
263 snd_card_set_dev(gosnd->card, go->dev);
264 ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
265 if (ret < 0) {
266 snd_card_free(gosnd->card);
267 kfree(gosnd);
268 return ret;
269 }
270 strncpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
271 strncpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
272 strncpy(gosnd->card->longname, gosnd->card->shortname,
273 sizeof(gosnd->card->longname));
274
275 gosnd->pcm->private_data = go;
276 snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE,
277 &go7007_snd_capture_ops);
278
279 ret = snd_card_register(gosnd->card);
280 if (ret < 0) {
281 snd_card_free(gosnd->card);
282 kfree(gosnd);
283 return ret;
284 }
285
286 gosnd->substream = NULL;
287 go->snd_context = gosnd;
288 ++dev;
289 ++go->ref_count;
290
291 return 0;
292}
293EXPORT_SYMBOL(go7007_snd_init);
294
295int go7007_snd_remove(struct go7007 *go)
296{
297 struct go7007_snd *gosnd = go->snd_context;
298
299 snd_card_disconnect(gosnd->card);
300 snd_card_free_when_closed(gosnd->card);
301 return 0;
302}
303EXPORT_SYMBOL(go7007_snd_remove);
304
305MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-i2c.h b/drivers/staging/go7007/wis-i2c.h
new file mode 100644
index 00000000000..993f658ad73
--- /dev/null
+++ b/drivers/staging/go7007/wis-i2c.h
@@ -0,0 +1,55 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18/* Temporary I2C IDs -- these need to be replaced with real registered IDs */
19#define I2C_DRIVERID_WIS_SAA7115 0xf0f0
20#define I2C_DRIVERID_WIS_UDA1342 0xf0f1
21#define I2C_DRIVERID_WIS_SONY_TUNER 0xf0f2
22#define I2C_DRIVERID_WIS_TW9903 0xf0f3
23#define I2C_DRIVERID_WIS_SAA7113 0xf0f4
24#define I2C_DRIVERID_WIS_OV7640 0xf0f5
25#define I2C_DRIVERID_WIS_TW2804 0xf0f6
26#define I2C_ALGO_GO7007 0xf00000
27#define I2C_ALGO_GO7007_USB 0xf10000
28
29/* Flag to indicate that the client needs to be accessed with SCCB semantics */
30/* We re-use the I2C_M_TEN value so the flag passes through the masks in the
31 * core I2C code. Major kludge, but the I2C layer ain't exactly flexible. */
32#define I2C_CLIENT_SCCB 0x10
33
34typedef int (*found_proc) (struct i2c_adapter *, int, int);
35int wis_i2c_add_driver(unsigned int id, found_proc found_proc);
36void wis_i2c_del_driver(found_proc found_proc);
37
38int wis_i2c_probe_device(struct i2c_adapter *adapter,
39 unsigned int id, int addr);
40
41/* Definitions for new video decoder commands */
42
43struct video_decoder_resolution {
44 unsigned int width;
45 unsigned int height;
46};
47
48#define DECODER_SET_RESOLUTION _IOW('d', 200, struct video_decoder_resolution)
49#define DECODER_SET_CHANNEL _IOW('d', 201, int)
50
51/* Sony tuner types */
52
53#define TUNER_SONY_BTF_PG472Z 200
54#define TUNER_SONY_BTF_PK467Z 201
55#define TUNER_SONY_BTF_PB463Z 202
diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/go7007/wis-ov7640.c
new file mode 100644
index 00000000000..815615a6230
--- /dev/null
+++ b/drivers/staging/go7007/wis-ov7640.c
@@ -0,0 +1,131 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/version.h>
21#include <linux/i2c.h>
22#include <linux/videodev.h>
23#include <linux/video_decoder.h>
24
25#include "wis-i2c.h"
26
27struct wis_ov7640 {
28 int brightness;
29 int contrast;
30 int saturation;
31 int hue;
32};
33
34static u8 initial_registers[] =
35{
36 0x12, 0x80,
37 0x12, 0x54,
38 0x14, 0x24,
39 0x15, 0x01,
40 0x28, 0x20,
41 0x75, 0x82,
42 0xFF, 0xFF, /* Terminator (reg 0xFF is unused) */
43};
44
45static int write_regs(struct i2c_client *client, u8 *regs)
46{
47 int i;
48
49 for (i = 0; regs[i] != 0xFF; i += 2)
50 if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
51 return -1;
52 return 0;
53}
54
55static struct i2c_driver wis_ov7640_driver;
56
57static struct i2c_client wis_ov7640_client_templ = {
58 .name = "OV7640 (WIS)",
59 .driver = &wis_ov7640_driver,
60};
61
62static int wis_ov7640_detect(struct i2c_adapter *adapter, int addr, int kind)
63{
64 struct i2c_client *client;
65
66 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
67 return 0;
68
69 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
70 if (client == NULL)
71 return -ENOMEM;
72 memcpy(client, &wis_ov7640_client_templ,
73 sizeof(wis_ov7640_client_templ));
74 client->adapter = adapter;
75 client->addr = addr;
76 client->flags = I2C_CLIENT_SCCB;
77
78 printk(KERN_DEBUG
79 "wis-ov7640: initializing OV7640 at address %d on %s\n",
80 addr, adapter->name);
81
82 if (write_regs(client, initial_registers) < 0) {
83 printk(KERN_ERR "wis-ov7640: error initializing OV7640\n");
84 kfree(client);
85 return 0;
86 }
87
88 i2c_attach_client(client);
89 return 0;
90}
91
92static int wis_ov7640_detach(struct i2c_client *client)
93{
94 int r;
95
96 r = i2c_detach_client(client);
97 if (r < 0)
98 return r;
99
100 kfree(client);
101 return 0;
102}
103
104static struct i2c_driver wis_ov7640_driver = {
105 .driver = {
106 .name = "WIS OV7640 I2C driver",
107 },
108 .id = I2C_DRIVERID_WIS_OV7640,
109 .detach_client = wis_ov7640_detach,
110};
111
112static int __init wis_ov7640_init(void)
113{
114 int r;
115
116 r = i2c_add_driver(&wis_ov7640_driver);
117 if (r < 0)
118 return r;
119 return wis_i2c_add_driver(wis_ov7640_driver.id, wis_ov7640_detect);
120}
121
122static void __exit wis_ov7640_cleanup(void)
123{
124 wis_i2c_del_driver(wis_ov7640_detect);
125 i2c_del_driver(&wis_ov7640_driver);
126}
127
128module_init(wis_ov7640_init);
129module_exit(wis_ov7640_cleanup);
130
131MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c
new file mode 100644
index 00000000000..4b14ca88b1a
--- /dev/null
+++ b/drivers/staging/go7007/wis-saa7113.c
@@ -0,0 +1,363 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/version.h>
21#include <linux/i2c.h>
22#include <linux/videodev.h>
23#include <linux/video_decoder.h>
24#include <linux/ioctl.h>
25
26#include "wis-i2c.h"
27
28struct wis_saa7113 {
29 int norm;
30 int brightness;
31 int contrast;
32 int saturation;
33 int hue;
34};
35
36static u8 initial_registers[] =
37{
38 0x01, 0x08,
39 0x02, 0xc0,
40 0x03, 0x33,
41 0x04, 0x00,
42 0x05, 0x00,
43 0x06, 0xe9,
44 0x07, 0x0d,
45 0x08, 0xd8,
46 0x09, 0x40,
47 0x0a, 0x80,
48 0x0b, 0x47,
49 0x0c, 0x40,
50 0x0d, 0x00,
51 0x0e, 0x01,
52 0x0f, 0x2a,
53 0x10, 0x40,
54 0x11, 0x0c,
55 0x12, 0xfe,
56 0x13, 0x00,
57 0x14, 0x00,
58 0x15, 0x04,
59 0x16, 0x00,
60 0x17, 0x00,
61 0x18, 0x00,
62 0x19, 0x00,
63 0x1a, 0x00,
64 0x1b, 0x00,
65 0x1c, 0x00,
66 0x1d, 0x00,
67 0x1e, 0x00,
68 0x1f, 0xc8,
69 0x40, 0x00,
70 0x41, 0xff,
71 0x42, 0xff,
72 0x43, 0xff,
73 0x44, 0xff,
74 0x45, 0xff,
75 0x46, 0xff,
76 0x47, 0xff,
77 0x48, 0xff,
78 0x49, 0xff,
79 0x4a, 0xff,
80 0x4b, 0xff,
81 0x4c, 0xff,
82 0x4d, 0xff,
83 0x4e, 0xff,
84 0x4f, 0xff,
85 0x50, 0xff,
86 0x51, 0xff,
87 0x52, 0xff,
88 0x53, 0xff,
89 0x54, 0xff,
90 0x55, 0xff,
91 0x56, 0xff,
92 0x57, 0xff,
93 0x58, 0x00,
94 0x59, 0x54,
95 0x5a, 0x07,
96 0x5b, 0x83,
97 0x5c, 0x00,
98 0x5d, 0x00,
99 0x5e, 0x00,
100 0x5f, 0x00,
101 0x60, 0x00,
102 0x61, 0x00,
103 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
104};
105
106static int write_reg(struct i2c_client *client, u8 reg, u8 value)
107{
108 return i2c_smbus_write_byte_data(client, reg, value);
109}
110
111static int write_regs(struct i2c_client *client, u8 *regs)
112{
113 int i;
114
115 for (i = 0; regs[i] != 0x00; i += 2)
116 if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
117 return -1;
118 return 0;
119}
120
121static int wis_saa7113_command(struct i2c_client *client,
122 unsigned int cmd, void *arg)
123{
124 struct wis_saa7113 *dec = i2c_get_clientdata(client);
125
126 switch (cmd) {
127 case DECODER_SET_INPUT:
128 {
129 int *input = arg;
130
131 i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
132 i2c_smbus_write_byte_data(client, 0x09,
133 *input < 6 ? 0x40 : 0x80);
134 break;
135 }
136 case DECODER_SET_NORM:
137 {
138 int *input = arg;
139 dec->norm = *input;
140 switch (dec->norm) {
141 case VIDEO_MODE_PAL:
142 write_reg(client, 0x0e, 0x01);
143 write_reg(client, 0x10, 0x48);
144 break;
145 case VIDEO_MODE_NTSC:
146 write_reg(client, 0x0e, 0x01);
147 write_reg(client, 0x10, 0x40);
148 break;
149 case VIDEO_MODE_SECAM:
150 write_reg(client, 0x0e, 0x50);
151 write_reg(client, 0x10, 0x48);
152 break;
153 }
154 break;
155 }
156 case VIDIOC_QUERYCTRL:
157 {
158 struct v4l2_queryctrl *ctrl = arg;
159
160 switch (ctrl->id) {
161 case V4L2_CID_BRIGHTNESS:
162 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
163 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
164 ctrl->minimum = 0;
165 ctrl->maximum = 255;
166 ctrl->step = 1;
167 ctrl->default_value = 128;
168 ctrl->flags = 0;
169 break;
170 case V4L2_CID_CONTRAST:
171 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
172 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
173 ctrl->minimum = 0;
174 ctrl->maximum = 127;
175 ctrl->step = 1;
176 ctrl->default_value = 71;
177 ctrl->flags = 0;
178 break;
179 case V4L2_CID_SATURATION:
180 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
181 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
182 ctrl->minimum = 0;
183 ctrl->maximum = 127;
184 ctrl->step = 1;
185 ctrl->default_value = 64;
186 ctrl->flags = 0;
187 break;
188 case V4L2_CID_HUE:
189 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
190 strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
191 ctrl->minimum = -128;
192 ctrl->maximum = 127;
193 ctrl->step = 1;
194 ctrl->default_value = 0;
195 ctrl->flags = 0;
196 break;
197 }
198 break;
199 }
200 case VIDIOC_S_CTRL:
201 {
202 struct v4l2_control *ctrl = arg;
203
204 switch (ctrl->id) {
205 case V4L2_CID_BRIGHTNESS:
206 if (ctrl->value > 255)
207 dec->brightness = 255;
208 else if (ctrl->value < 0)
209 dec->brightness = 0;
210 else
211 dec->brightness = ctrl->value;
212 write_reg(client, 0x0a, dec->brightness);
213 break;
214 case V4L2_CID_CONTRAST:
215 if (ctrl->value > 127)
216 dec->contrast = 127;
217 else if (ctrl->value < 0)
218 dec->contrast = 0;
219 else
220 dec->contrast = ctrl->value;
221 write_reg(client, 0x0b, dec->contrast);
222 break;
223 case V4L2_CID_SATURATION:
224 if (ctrl->value > 127)
225 dec->saturation = 127;
226 else if (ctrl->value < 0)
227 dec->saturation = 0;
228 else
229 dec->saturation = ctrl->value;
230 write_reg(client, 0x0c, dec->saturation);
231 break;
232 case V4L2_CID_HUE:
233 if (ctrl->value > 127)
234 dec->hue = 127;
235 else if (ctrl->value < -128)
236 dec->hue = -128;
237 else
238 dec->hue = ctrl->value;
239 write_reg(client, 0x0d, dec->hue);
240 break;
241 }
242 break;
243 }
244 case VIDIOC_G_CTRL:
245 {
246 struct v4l2_control *ctrl = arg;
247
248 switch (ctrl->id) {
249 case V4L2_CID_BRIGHTNESS:
250 ctrl->value = dec->brightness;
251 break;
252 case V4L2_CID_CONTRAST:
253 ctrl->value = dec->contrast;
254 break;
255 case V4L2_CID_SATURATION:
256 ctrl->value = dec->saturation;
257 break;
258 case V4L2_CID_HUE:
259 ctrl->value = dec->hue;
260 break;
261 }
262 break;
263 }
264 default:
265 break;
266 }
267 return 0;
268}
269
270static struct i2c_driver wis_saa7113_driver;
271
272static struct i2c_client wis_saa7113_client_templ = {
273 .name = "SAA7113 (WIS)",
274 .driver = &wis_saa7113_driver,
275};
276
277static int wis_saa7113_detect(struct i2c_adapter *adapter, int addr, int kind)
278{
279 struct i2c_client *client;
280 struct wis_saa7113 *dec;
281
282 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
283 return 0;
284
285 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
286 if (client == NULL)
287 return -ENOMEM;
288 memcpy(client, &wis_saa7113_client_templ,
289 sizeof(wis_saa7113_client_templ));
290 client->adapter = adapter;
291 client->addr = addr;
292
293 dec = kmalloc(sizeof(struct wis_saa7113), GFP_KERNEL);
294 if (dec == NULL) {
295 kfree(client);
296 return -ENOMEM;
297 }
298 dec->norm = VIDEO_MODE_NTSC;
299 dec->brightness = 128;
300 dec->contrast = 71;
301 dec->saturation = 64;
302 dec->hue = 0;
303 i2c_set_clientdata(client, dec);
304
305 printk(KERN_DEBUG
306 "wis-saa7113: initializing SAA7113 at address %d on %s\n",
307 addr, adapter->name);
308
309 if (write_regs(client, initial_registers) < 0) {
310 printk(KERN_ERR
311 "wis-saa7113: error initializing SAA7113\n");
312 kfree(client);
313 kfree(dec);
314 return 0;
315 }
316
317 i2c_attach_client(client);
318 return 0;
319}
320
321static int wis_saa7113_detach(struct i2c_client *client)
322{
323 struct wis_saa7113 *dec = i2c_get_clientdata(client);
324 int r;
325
326 r = i2c_detach_client(client);
327 if (r < 0)
328 return r;
329
330 kfree(client);
331 kfree(dec);
332 return 0;
333}
334
335static struct i2c_driver wis_saa7113_driver = {
336 .driver = {
337 .name = "WIS SAA7113 I2C driver",
338 },
339 .id = I2C_DRIVERID_WIS_SAA7113,
340 .detach_client = wis_saa7113_detach,
341 .command = wis_saa7113_command,
342};
343
344static int __init wis_saa7113_init(void)
345{
346 int r;
347
348 r = i2c_add_driver(&wis_saa7113_driver);
349 if (r < 0)
350 return r;
351 return wis_i2c_add_driver(wis_saa7113_driver.id, wis_saa7113_detect);
352}
353
354static void __exit wis_saa7113_cleanup(void)
355{
356 wis_i2c_del_driver(wis_saa7113_detect);
357 i2c_del_driver(&wis_saa7113_driver);
358}
359
360module_init(wis_saa7113_init);
361module_exit(wis_saa7113_cleanup);
362
363MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c
new file mode 100644
index 00000000000..bd40bf4be28
--- /dev/null
+++ b/drivers/staging/go7007/wis-saa7115.c
@@ -0,0 +1,492 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/version.h>
21#include <linux/i2c.h>
22#include <linux/videodev.h>
23#include <linux/video_decoder.h>
24#include <linux/ioctl.h>
25
26#include "wis-i2c.h"
27
28struct wis_saa7115 {
29 int norm;
30 int brightness;
31 int contrast;
32 int saturation;
33 int hue;
34};
35
36static u8 initial_registers[] =
37{
38 0x01, 0x08,
39 0x02, 0xc0,
40 0x03, 0x20,
41 0x04, 0x80,
42 0x05, 0x80,
43 0x06, 0xeb,
44 0x07, 0xe0,
45 0x08, 0xf0, /* always toggle FID */
46 0x09, 0x40,
47 0x0a, 0x80,
48 0x0b, 0x40,
49 0x0c, 0x40,
50 0x0d, 0x00,
51 0x0e, 0x03,
52 0x0f, 0x2a,
53 0x10, 0x0e,
54 0x11, 0x00,
55 0x12, 0x8d,
56 0x13, 0x00,
57 0x14, 0x00,
58 0x15, 0x11,
59 0x16, 0x01,
60 0x17, 0xda,
61 0x18, 0x40,
62 0x19, 0x80,
63 0x1a, 0x00,
64 0x1b, 0x42,
65 0x1c, 0xa9,
66 0x30, 0x66,
67 0x31, 0x90,
68 0x32, 0x01,
69 0x34, 0x00,
70 0x35, 0x00,
71 0x36, 0x20,
72 0x38, 0x03,
73 0x39, 0x20,
74 0x3a, 0x88,
75 0x40, 0x00,
76 0x41, 0xff,
77 0x42, 0xff,
78 0x43, 0xff,
79 0x44, 0xff,
80 0x45, 0xff,
81 0x46, 0xff,
82 0x47, 0xff,
83 0x48, 0xff,
84 0x49, 0xff,
85 0x4a, 0xff,
86 0x4b, 0xff,
87 0x4c, 0xff,
88 0x4d, 0xff,
89 0x4e, 0xff,
90 0x4f, 0xff,
91 0x50, 0xff,
92 0x51, 0xff,
93 0x52, 0xff,
94 0x53, 0xff,
95 0x54, 0xf4 /*0xff*/,
96 0x55, 0xff,
97 0x56, 0xff,
98 0x57, 0xff,
99 0x58, 0x40,
100 0x59, 0x47,
101 0x5a, 0x06 /*0x03*/,
102 0x5b, 0x83,
103 0x5d, 0x06,
104 0x5e, 0x00,
105 0x80, 0x30, /* window defined scaler operation, task A and B enabled */
106 0x81, 0x03, /* use scaler datapath generated V */
107 0x83, 0x00,
108 0x84, 0x00,
109 0x85, 0x00,
110 0x86, 0x45,
111 0x87, 0x31,
112 0x88, 0xc0,
113 0x90, 0x02, /* task A process top field */
114 0x91, 0x08,
115 0x92, 0x09,
116 0x93, 0x80,
117 0x94, 0x06,
118 0x95, 0x00,
119 0x96, 0xc0,
120 0x97, 0x02,
121 0x98, 0x12,
122 0x99, 0x00,
123 0x9a, 0xf2,
124 0x9b, 0x00,
125 0x9c, 0xd0,
126 0x9d, 0x02,
127 0x9e, 0xf2,
128 0x9f, 0x00,
129 0xa0, 0x01,
130 0xa1, 0x01,
131 0xa2, 0x01,
132 0xa4, 0x80,
133 0xa5, 0x40,
134 0xa6, 0x40,
135 0xa8, 0x00,
136 0xa9, 0x04,
137 0xaa, 0x00,
138 0xac, 0x00,
139 0xad, 0x02,
140 0xae, 0x00,
141 0xb0, 0x00,
142 0xb1, 0x04,
143 0xb2, 0x00,
144 0xb3, 0x04,
145 0xb4, 0x00,
146 0xb8, 0x00,
147 0xbc, 0x00,
148 0xc0, 0x03, /* task B process bottom field */
149 0xc1, 0x08,
150 0xc2, 0x09,
151 0xc3, 0x80,
152 0xc4, 0x06,
153 0xc5, 0x00,
154 0xc6, 0xc0,
155 0xc7, 0x02,
156 0xc8, 0x12,
157 0xc9, 0x00,
158 0xca, 0xf2,
159 0xcb, 0x00,
160 0xcc, 0xd0,
161 0xcd, 0x02,
162 0xce, 0xf2,
163 0xcf, 0x00,
164 0xd0, 0x01,
165 0xd1, 0x01,
166 0xd2, 0x01,
167 0xd4, 0x80,
168 0xd5, 0x40,
169 0xd6, 0x40,
170 0xd8, 0x00,
171 0xd9, 0x04,
172 0xda, 0x00,
173 0xdc, 0x00,
174 0xdd, 0x02,
175 0xde, 0x00,
176 0xe0, 0x00,
177 0xe1, 0x04,
178 0xe2, 0x00,
179 0xe3, 0x04,
180 0xe4, 0x00,
181 0xe8, 0x00,
182 0x88, 0xf0, /* End of original static list */
183 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
184};
185
186static int write_reg(struct i2c_client *client, u8 reg, u8 value)
187{
188 return i2c_smbus_write_byte_data(client, reg, value);
189}
190
191static int write_regs(struct i2c_client *client, u8 *regs)
192{
193 int i;
194
195 for (i = 0; regs[i] != 0x00; i += 2)
196 if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
197 return -1;
198 return 0;
199}
200
201static int wis_saa7115_command(struct i2c_client *client,
202 unsigned int cmd, void *arg)
203{
204 struct wis_saa7115 *dec = i2c_get_clientdata(client);
205
206 switch (cmd) {
207 case DECODER_SET_INPUT:
208 {
209 int *input = arg;
210
211 i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
212 i2c_smbus_write_byte_data(client, 0x09,
213 *input < 6 ? 0x40 : 0xC0);
214 break;
215 }
216 case DECODER_SET_RESOLUTION:
217 {
218 struct video_decoder_resolution *res = arg;
219 /* Course-grained scaler */
220 int h_integer_scaler = res->width < 704 ? 704 / res->width : 1;
221 /* Fine-grained scaler to take care of remainder */
222 int h_scaling_increment = (704 / h_integer_scaler) *
223 1024 / res->width;
224 /* Fine-grained scaler only */
225 int v_scaling_increment = (dec->norm == VIDEO_MODE_NTSC ?
226 240 : 288) * 1024 / res->height;
227 u8 regs[] = {
228 0x88, 0xc0,
229 0x9c, res->width & 0xff,
230 0x9d, res->width >> 8,
231 0x9e, res->height & 0xff,
232 0x9f, res->height >> 8,
233 0xa0, h_integer_scaler,
234 0xa1, 1,
235 0xa2, 1,
236 0xa8, h_scaling_increment & 0xff,
237 0xa9, h_scaling_increment >> 8,
238 0xac, (h_scaling_increment / 2) & 0xff,
239 0xad, (h_scaling_increment / 2) >> 8,
240 0xb0, v_scaling_increment & 0xff,
241 0xb1, v_scaling_increment >> 8,
242 0xb2, v_scaling_increment & 0xff,
243 0xb3, v_scaling_increment >> 8,
244 0xcc, res->width & 0xff,
245 0xcd, res->width >> 8,
246 0xce, res->height & 0xff,
247 0xcf, res->height >> 8,
248 0xd0, h_integer_scaler,
249 0xd1, 1,
250 0xd2, 1,
251 0xd8, h_scaling_increment & 0xff,
252 0xd9, h_scaling_increment >> 8,
253 0xdc, (h_scaling_increment / 2) & 0xff,
254 0xdd, (h_scaling_increment / 2) >> 8,
255 0xe0, v_scaling_increment & 0xff,
256 0xe1, v_scaling_increment >> 8,
257 0xe2, v_scaling_increment & 0xff,
258 0xe3, v_scaling_increment >> 8,
259 0x88, 0xf0,
260 0, 0,
261 };
262 write_regs(client, regs);
263 break;
264 }
265 case DECODER_SET_NORM:
266 {
267 int *input = arg;
268 u8 regs[] = {
269 0x88, 0xc0,
270 0x98, *input == VIDEO_MODE_NTSC ? 0x12 : 0x16,
271 0x9a, *input == VIDEO_MODE_NTSC ? 0xf2 : 0x20,
272 0x9b, *input == VIDEO_MODE_NTSC ? 0x00 : 0x01,
273 0xc8, *input == VIDEO_MODE_NTSC ? 0x12 : 0x16,
274 0xca, *input == VIDEO_MODE_NTSC ? 0xf2 : 0x20,
275 0xcb, *input == VIDEO_MODE_NTSC ? 0x00 : 0x01,
276 0x88, 0xf0,
277 0x30, *input == VIDEO_MODE_NTSC ? 0x66 : 0x00,
278 0x31, *input == VIDEO_MODE_NTSC ? 0x90 : 0xe0,
279 0, 0,
280 };
281 write_regs(client, regs);
282 dec->norm = *input;
283 break;
284 }
285 case VIDIOC_QUERYCTRL:
286 {
287 struct v4l2_queryctrl *ctrl = arg;
288
289 switch (ctrl->id) {
290 case V4L2_CID_BRIGHTNESS:
291 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
292 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
293 ctrl->minimum = 0;
294 ctrl->maximum = 255;
295 ctrl->step = 1;
296 ctrl->default_value = 128;
297 ctrl->flags = 0;
298 break;
299 case V4L2_CID_CONTRAST:
300 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
301 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
302 ctrl->minimum = 0;
303 ctrl->maximum = 127;
304 ctrl->step = 1;
305 ctrl->default_value = 64;
306 ctrl->flags = 0;
307 break;
308 case V4L2_CID_SATURATION:
309 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
310 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
311 ctrl->minimum = 0;
312 ctrl->maximum = 127;
313 ctrl->step = 1;
314 ctrl->default_value = 64;
315 ctrl->flags = 0;
316 break;
317 case V4L2_CID_HUE:
318 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
319 strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
320 ctrl->minimum = -128;
321 ctrl->maximum = 127;
322 ctrl->step = 1;
323 ctrl->default_value = 0;
324 ctrl->flags = 0;
325 break;
326 }
327 break;
328 }
329 case VIDIOC_S_CTRL:
330 {
331 struct v4l2_control *ctrl = arg;
332
333 switch (ctrl->id) {
334 case V4L2_CID_BRIGHTNESS:
335 if (ctrl->value > 255)
336 dec->brightness = 255;
337 else if (ctrl->value < 0)
338 dec->brightness = 0;
339 else
340 dec->brightness = ctrl->value;
341 write_reg(client, 0x0a, dec->brightness);
342 break;
343 case V4L2_CID_CONTRAST:
344 if (ctrl->value > 127)
345 dec->contrast = 127;
346 else if (ctrl->value < 0)
347 dec->contrast = 0;
348 else
349 dec->contrast = ctrl->value;
350 write_reg(client, 0x0b, dec->contrast);
351 break;
352 case V4L2_CID_SATURATION:
353 if (ctrl->value > 127)
354 dec->saturation = 127;
355 else if (ctrl->value < 0)
356 dec->saturation = 0;
357 else
358 dec->saturation = ctrl->value;
359 write_reg(client, 0x0c, dec->saturation);
360 break;
361 case V4L2_CID_HUE:
362 if (ctrl->value > 127)
363 dec->hue = 127;
364 else if (ctrl->value < -128)
365 dec->hue = -128;
366 else
367 dec->hue = ctrl->value;
368 write_reg(client, 0x0d, dec->hue);
369 break;
370 }
371 break;
372 }
373 case VIDIOC_G_CTRL:
374 {
375 struct v4l2_control *ctrl = arg;
376
377 switch (ctrl->id) {
378 case V4L2_CID_BRIGHTNESS:
379 ctrl->value = dec->brightness;
380 break;
381 case V4L2_CID_CONTRAST:
382 ctrl->value = dec->contrast;
383 break;
384 case V4L2_CID_SATURATION:
385 ctrl->value = dec->saturation;
386 break;
387 case V4L2_CID_HUE:
388 ctrl->value = dec->hue;
389 break;
390 }
391 break;
392 }
393 default:
394 break;
395 }
396 return 0;
397}
398
399static struct i2c_driver wis_saa7115_driver;
400
401static struct i2c_client wis_saa7115_client_templ = {
402 .name = "SAA7115 (WIS)",
403 .driver = &wis_saa7115_driver,
404};
405
406static int wis_saa7115_detect(struct i2c_adapter *adapter, int addr, int kind)
407{
408 struct i2c_client *client;
409 struct wis_saa7115 *dec;
410
411 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
412 return 0;
413
414 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
415 if (client == NULL)
416 return -ENOMEM;
417 memcpy(client, &wis_saa7115_client_templ,
418 sizeof(wis_saa7115_client_templ));
419 client->adapter = adapter;
420 client->addr = addr;
421
422 dec = kmalloc(sizeof(struct wis_saa7115), GFP_KERNEL);
423 if (dec == NULL) {
424 kfree(client);
425 return -ENOMEM;
426 }
427 dec->norm = VIDEO_MODE_NTSC;
428 dec->brightness = 128;
429 dec->contrast = 64;
430 dec->saturation = 64;
431 dec->hue = 0;
432 i2c_set_clientdata(client, dec);
433
434 printk(KERN_DEBUG
435 "wis-saa7115: initializing SAA7115 at address %d on %s\n",
436 addr, adapter->name);
437
438 if (write_regs(client, initial_registers) < 0) {
439 printk(KERN_ERR
440 "wis-saa7115: error initializing SAA7115\n");
441 kfree(client);
442 kfree(dec);
443 return 0;
444 }
445
446 i2c_attach_client(client);
447 return 0;
448}
449
450static int wis_saa7115_detach(struct i2c_client *client)
451{
452 struct wis_saa7115 *dec = i2c_get_clientdata(client);
453 int r;
454
455 r = i2c_detach_client(client);
456 if (r < 0)
457 return r;
458
459 kfree(client);
460 kfree(dec);
461 return 0;
462}
463
464static struct i2c_driver wis_saa7115_driver = {
465 .driver = {
466 .name = "WIS SAA7115 I2C driver",
467 },
468 .id = I2C_DRIVERID_WIS_SAA7115,
469 .detach_client = wis_saa7115_detach,
470 .command = wis_saa7115_command,
471};
472
473static int __init wis_saa7115_init(void)
474{
475 int r;
476
477 r = i2c_add_driver(&wis_saa7115_driver);
478 if (r < 0)
479 return r;
480 return wis_i2c_add_driver(wis_saa7115_driver.id, wis_saa7115_detect);
481}
482
483static void __exit wis_saa7115_cleanup(void)
484{
485 wis_i2c_del_driver(wis_saa7115_detect);
486 i2c_del_driver(&wis_saa7115_driver);
487}
488
489module_init(wis_saa7115_init);
490module_exit(wis_saa7115_cleanup);
491
492MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c
new file mode 100644
index 00000000000..82e66d65f36
--- /dev/null
+++ b/drivers/staging/go7007/wis-sony-tuner.c
@@ -0,0 +1,741 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/version.h>
21#include <linux/i2c.h>
22#include <linux/videodev.h>
23#include <media/tuner.h>
24#include <media/v4l2-common.h>
25
26#include "wis-i2c.h"
27
28/* #define MPX_DEBUG */
29
30/* AS(IF/MPX) pin: LOW HIGH/OPEN
31 * IF/MPX address: 0x42/0x40 0x43/0x44
32 */
33#define IF_I2C_ADDR 0x43
34#define MPX_I2C_ADDR 0x44
35
36static v4l2_std_id force_band;
37static char force_band_str[] = "-";
38module_param_string(force_band, force_band_str, sizeof(force_band_str), 0644);
39static int force_mpx_mode = -1;
40module_param(force_mpx_mode, int, 0644);
41
42/* Store tuner info in the same format as tuner.c, so maybe we can put the
43 * Sony tuner support in there. */
44struct sony_tunertype {
45 char *name;
46 unsigned char Vendor; /* unused here */
47 unsigned char Type; /* unused here */
48
49 unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */
50 unsigned short thresh2; /* band switch VHF_HI <=> UHF */
51 unsigned char VHF_L;
52 unsigned char VHF_H;
53 unsigned char UHF;
54 unsigned char config;
55 unsigned short IFPCoff;
56};
57
58/* This array is indexed by (tuner_type - 200) */
59static struct sony_tunertype sony_tuners[] = {
60 { "Sony PAL+SECAM (BTF-PG472Z)", 0, 0,
61 16*144.25, 16*427.25, 0x01, 0x02, 0x04, 0xc6, 623},
62 { "Sony NTSC_JP (BTF-PK467Z)", 0, 0,
63 16*220.25, 16*467.25, 0x01, 0x02, 0x04, 0xc6, 940},
64 { "Sony NTSC (BTF-PB463Z)", 0, 0,
65 16*130.25, 16*364.25, 0x01, 0x02, 0x04, 0xc6, 732},
66};
67
68struct wis_sony_tuner {
69 int type;
70 v4l2_std_id std;
71 unsigned int freq;
72 int mpxmode;
73 u32 audmode;
74};
75
76/* Basically the same as default_set_tv_freq() in tuner.c */
77static int set_freq(struct i2c_client *client, int freq)
78{
79 struct wis_sony_tuner *t = i2c_get_clientdata(client);
80 char *band_name;
81 int n;
82 int band_select;
83 struct sony_tunertype *tun;
84 u8 buffer[4];
85
86 tun = &sony_tuners[t->type - 200];
87 if (freq < tun->thresh1) {
88 band_name = "VHF_L";
89 band_select = tun->VHF_L;
90 } else if (freq < tun->thresh2) {
91 band_name = "VHF_H";
92 band_select = tun->VHF_H;
93 } else {
94 band_name = "UHF";
95 band_select = tun->UHF;
96 }
97 printk(KERN_DEBUG "wis-sony-tuner: tuning to frequency %d.%04d (%s)\n",
98 freq / 16, (freq % 16) * 625, band_name);
99 n = freq + tun->IFPCoff;
100
101 buffer[0] = n >> 8;
102 buffer[1] = n & 0xff;
103 buffer[2] = tun->config;
104 buffer[3] = band_select;
105 i2c_master_send(client, buffer, 4);
106
107 return 0;
108}
109
110static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
111{
112 u8 buffer[5];
113 struct i2c_msg msg;
114
115 buffer[0] = dev;
116 buffer[1] = addr >> 8;
117 buffer[2] = addr & 0xff;
118 buffer[3] = val >> 8;
119 buffer[4] = val & 0xff;
120 msg.addr = MPX_I2C_ADDR;
121 msg.flags = 0;
122 msg.len = 5;
123 msg.buf = buffer;
124 i2c_transfer(client->adapter, &msg, 1);
125 return 0;
126}
127
128/*
129 * MPX register values for the BTF-PG472Z:
130 *
131 * FM_ NICAM_ SCART_
132 * MODUS SOURCE ACB PRESCAL PRESCAL PRESCAL SYSTEM VOLUME
133 * 10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000
134 * ---------------------------------------------------------------
135 * Auto 1003 0020 0100 2603 5000 XXXX 0001 7500
136 *
137 * B/G
138 * Mono 1003 0020 0100 2603 5000 XXXX 0003 7500
139 * A2 1003 0020 0100 2601 5000 XXXX 0003 7500
140 * NICAM 1003 0120 0100 2603 5000 XXXX 0008 7500
141 *
142 * I
143 * Mono 1003 0020 0100 2603 7900 XXXX 000A 7500
144 * NICAM 1003 0120 0100 2603 7900 XXXX 000A 7500
145 *
146 * D/K
147 * Mono 1003 0020 0100 2603 5000 XXXX 0004 7500
148 * A2-1 1003 0020 0100 2601 5000 XXXX 0004 7500
149 * A2-2 1003 0020 0100 2601 5000 XXXX 0005 7500
150 * A2-3 1003 0020 0100 2601 5000 XXXX 0007 7500
151 * NICAM 1003 0120 0100 2603 5000 XXXX 000B 7500
152 *
153 * L/L'
154 * Mono 0003 0200 0100 7C03 5000 2200 0009 7500
155 * NICAM 0003 0120 0100 7C03 5000 XXXX 0009 7500
156 *
157 * M
158 * Mono 1003 0200 0100 2B03 5000 2B00 0002 7500
159 *
160 * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX.
161 *
162 * Bilingual selection in A2/NICAM:
163 *
164 * High byte of SOURCE Left chan Right chan
165 * 0x01 MAIN SUB
166 * 0x03 MAIN MAIN
167 * 0x04 SUB SUB
168 *
169 * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or
170 * 0x00 (all other bands). Force mono in A2 with FMONO_A2:
171 *
172 * FMONO_A2
173 * 10/0022
174 * --------
175 * Forced mono ON 07F0
176 * Forced mono OFF 0190
177 */
178
179static struct {
180 enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
181 u16 modus;
182 u16 source;
183 u16 acb;
184 u16 fm_prescale;
185 u16 nicam_prescale;
186 u16 scart_prescale;
187 u16 system;
188 u16 volume;
189} mpx_audio_modes[] = {
190 /* Auto */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
191 0x5000, 0x0000, 0x0001, 0x7500 },
192 /* B/G Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
193 0x5000, 0x0000, 0x0003, 0x7500 },
194 /* B/G A2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
195 0x5000, 0x0000, 0x0003, 0x7500 },
196 /* B/G NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
197 0x5000, 0x0000, 0x0008, 0x7500 },
198 /* I Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
199 0x7900, 0x0000, 0x000A, 0x7500 },
200 /* I NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
201 0x7900, 0x0000, 0x000A, 0x7500 },
202 /* D/K Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
203 0x5000, 0x0000, 0x0004, 0x7500 },
204 /* D/K A2-1 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
205 0x5000, 0x0000, 0x0004, 0x7500 },
206 /* D/K A2-2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
207 0x5000, 0x0000, 0x0005, 0x7500 },
208 /* D/K A2-3 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
209 0x5000, 0x0000, 0x0007, 0x7500 },
210 /* D/K NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
211 0x5000, 0x0000, 0x000B, 0x7500 },
212 /* L/L' Mono */ { AUD_MONO, 0x0003, 0x0200, 0x0100, 0x7C03,
213 0x5000, 0x2200, 0x0009, 0x7500 },
214 /* L/L' NICAM */{ AUD_NICAM_L, 0x0003, 0x0120, 0x0100, 0x7C03,
215 0x5000, 0x0000, 0x0009, 0x7500 },
216};
217
218#define MPX_NUM_MODES ARRAY_SIZE(mpx_audio_modes)
219
220static int mpx_setup(struct i2c_client *client)
221{
222 struct wis_sony_tuner *t = i2c_get_clientdata(client);
223 u16 source = 0;
224 u8 buffer[3];
225 struct i2c_msg msg;
226
227 /* reset MPX */
228 buffer[0] = 0x00;
229 buffer[1] = 0x80;
230 buffer[2] = 0x00;
231 msg.addr = MPX_I2C_ADDR;
232 msg.flags = 0;
233 msg.len = 3;
234 msg.buf = buffer;
235 i2c_transfer(client->adapter, &msg, 1);
236 buffer[1] = 0x00;
237 i2c_transfer(client->adapter, &msg, 1);
238
239 if (mpx_audio_modes[t->mpxmode].audio_mode != AUD_MONO) {
240 switch (t->audmode) {
241 case V4L2_TUNER_MODE_MONO:
242 switch (mpx_audio_modes[t->mpxmode].audio_mode) {
243 case AUD_A2:
244 source = mpx_audio_modes[t->mpxmode].source;
245 break;
246 case AUD_NICAM:
247 source = 0x0000;
248 break;
249 case AUD_NICAM_L:
250 source = 0x0200;
251 break;
252 default:
253 break;
254 }
255 break;
256 case V4L2_TUNER_MODE_STEREO:
257 source = mpx_audio_modes[t->mpxmode].source;
258 break;
259 case V4L2_TUNER_MODE_LANG1:
260 source = 0x0300;
261 break;
262 case V4L2_TUNER_MODE_LANG2:
263 source = 0x0400;
264 break;
265 }
266 source |= mpx_audio_modes[t->mpxmode].source & 0x00ff;
267 } else
268 source = mpx_audio_modes[t->mpxmode].source;
269
270 mpx_write(client, 0x10, 0x0030, mpx_audio_modes[t->mpxmode].modus);
271 mpx_write(client, 0x12, 0x0008, source);
272 mpx_write(client, 0x12, 0x0013, mpx_audio_modes[t->mpxmode].acb);
273 mpx_write(client, 0x12, 0x000e,
274 mpx_audio_modes[t->mpxmode].fm_prescale);
275 mpx_write(client, 0x12, 0x0010,
276 mpx_audio_modes[t->mpxmode].nicam_prescale);
277 mpx_write(client, 0x12, 0x000d,
278 mpx_audio_modes[t->mpxmode].scart_prescale);
279 mpx_write(client, 0x10, 0x0020, mpx_audio_modes[t->mpxmode].system);
280 mpx_write(client, 0x12, 0x0000, mpx_audio_modes[t->mpxmode].volume);
281 if (mpx_audio_modes[t->mpxmode].audio_mode == AUD_A2)
282 mpx_write(client, 0x10, 0x0022,
283 t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190);
284
285#ifdef MPX_DEBUG
286 {
287 u8 buf1[3], buf2[2];
288 struct i2c_msg msgs[2];
289
290 printk(KERN_DEBUG "wis-sony-tuner: MPX registers: %04x %04x "
291 "%04x %04x %04x %04x %04x %04x\n",
292 mpx_audio_modes[t->mpxmode].modus,
293 source,
294 mpx_audio_modes[t->mpxmode].acb,
295 mpx_audio_modes[t->mpxmode].fm_prescale,
296 mpx_audio_modes[t->mpxmode].nicam_prescale,
297 mpx_audio_modes[t->mpxmode].scart_prescale,
298 mpx_audio_modes[t->mpxmode].system,
299 mpx_audio_modes[t->mpxmode].volume);
300 buf1[0] = 0x11;
301 buf1[1] = 0x00;
302 buf1[2] = 0x7e;
303 msgs[0].addr = MPX_I2C_ADDR;
304 msgs[0].flags = 0;
305 msgs[0].len = 3;
306 msgs[0].buf = buf1;
307 msgs[1].addr = MPX_I2C_ADDR;
308 msgs[1].flags = I2C_M_RD;
309 msgs[1].len = 2;
310 msgs[1].buf = buf2;
311 i2c_transfer(client->adapter, msgs, 2);
312 printk(KERN_DEBUG "wis-sony-tuner: MPX system: %02x%02x\n",
313 buf2[0], buf2[1]);
314 buf1[0] = 0x11;
315 buf1[1] = 0x02;
316 buf1[2] = 0x00;
317 i2c_transfer(client->adapter, msgs, 2);
318 printk(KERN_DEBUG "wis-sony-tuner: MPX status: %02x%02x\n",
319 buf2[0], buf2[1]);
320 }
321#endif
322 return 0;
323}
324
325/*
326 * IF configuration values for the BTF-PG472Z:
327 *
328 * B/G: 0x94 0x70 0x49
329 * I: 0x14 0x70 0x4a
330 * D/K: 0x14 0x70 0x4b
331 * L: 0x04 0x70 0x4b
332 * L': 0x44 0x70 0x53
333 * M: 0x50 0x30 0x4c
334 */
335
336static int set_if(struct i2c_client *client)
337{
338 struct wis_sony_tuner *t = i2c_get_clientdata(client);
339 u8 buffer[4];
340 struct i2c_msg msg;
341 int default_mpx_mode = 0;
342
343 /* configure IF */
344 buffer[0] = 0;
345 if (t->std & V4L2_STD_PAL_BG) {
346 buffer[1] = 0x94;
347 buffer[2] = 0x70;
348 buffer[3] = 0x49;
349 default_mpx_mode = 1;
350 } else if (t->std & V4L2_STD_PAL_I) {
351 buffer[1] = 0x14;
352 buffer[2] = 0x70;
353 buffer[3] = 0x4a;
354 default_mpx_mode = 4;
355 } else if (t->std & V4L2_STD_PAL_DK) {
356 buffer[1] = 0x14;
357 buffer[2] = 0x70;
358 buffer[3] = 0x4b;
359 default_mpx_mode = 6;
360 } else if (t->std & V4L2_STD_SECAM_L) {
361 buffer[1] = 0x04;
362 buffer[2] = 0x70;
363 buffer[3] = 0x4b;
364 default_mpx_mode = 11;
365 }
366 msg.addr = IF_I2C_ADDR;
367 msg.flags = 0;
368 msg.len = 4;
369 msg.buf = buffer;
370 i2c_transfer(client->adapter, &msg, 1);
371
372 /* Select MPX mode if not forced by the user */
373 if (force_mpx_mode >= 0 || force_mpx_mode < MPX_NUM_MODES)
374 t->mpxmode = force_mpx_mode;
375 else
376 t->mpxmode = default_mpx_mode;
377 printk(KERN_DEBUG "wis-sony-tuner: setting MPX to mode %d\n",
378 t->mpxmode);
379 mpx_setup(client);
380
381 return 0;
382}
383
384static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
385{
386 struct wis_sony_tuner *t = i2c_get_clientdata(client);
387
388 switch (cmd) {
389#ifdef TUNER_SET_TYPE_ADDR
390 case TUNER_SET_TYPE_ADDR:
391 {
392 struct tuner_setup *tun_setup = arg;
393 int *type = &tun_setup->type;
394#else
395 case TUNER_SET_TYPE:
396 {
397 int *type = arg;
398#endif
399
400 if (t->type >= 0) {
401 if (t->type != *type)
402 printk(KERN_ERR "wis-sony-tuner: type already "
403 "set to %d, ignoring request for %d\n",
404 t->type, *type);
405 break;
406 }
407 t->type = *type;
408 switch (t->type) {
409 case TUNER_SONY_BTF_PG472Z:
410 switch (force_band_str[0]) {
411 case 'b':
412 case 'B':
413 case 'g':
414 case 'G':
415 printk(KERN_INFO "wis-sony-tuner: forcing "
416 "tuner to PAL-B/G bands\n");
417 force_band = V4L2_STD_PAL_BG;
418 break;
419 case 'i':
420 case 'I':
421 printk(KERN_INFO "wis-sony-tuner: forcing "
422 "tuner to PAL-I band\n");
423 force_band = V4L2_STD_PAL_I;
424 break;
425 case 'd':
426 case 'D':
427 case 'k':
428 case 'K':
429 printk(KERN_INFO "wis-sony-tuner: forcing "
430 "tuner to PAL-D/K bands\n");
431 force_band = V4L2_STD_PAL_I;
432 break;
433 case 'l':
434 case 'L':
435 printk(KERN_INFO "wis-sony-tuner: forcing "
436 "tuner to SECAM-L band\n");
437 force_band = V4L2_STD_SECAM_L;
438 break;
439 default:
440 force_band = 0;
441 break;
442 }
443 if (force_band)
444 t->std = force_band;
445 else
446 t->std = V4L2_STD_PAL_BG;
447 set_if(client);
448 break;
449 case TUNER_SONY_BTF_PK467Z:
450 t->std = V4L2_STD_NTSC_M_JP;
451 break;
452 case TUNER_SONY_BTF_PB463Z:
453 t->std = V4L2_STD_NTSC_M;
454 break;
455 default:
456 printk(KERN_ERR "wis-sony-tuner: tuner type %d is not "
457 "supported by this module\n", *type);
458 break;
459 }
460 if (type >= 0)
461 printk(KERN_INFO
462 "wis-sony-tuner: type set to %d (%s)\n",
463 t->type, sony_tuners[t->type - 200].name);
464 break;
465 }
466 case VIDIOC_G_FREQUENCY:
467 {
468 struct v4l2_frequency *f = arg;
469
470 f->frequency = t->freq;
471 break;
472 }
473 case VIDIOC_S_FREQUENCY:
474 {
475 struct v4l2_frequency *f = arg;
476
477 t->freq = f->frequency;
478 set_freq(client, t->freq);
479 break;
480 }
481 case VIDIOC_ENUMSTD:
482 {
483 struct v4l2_standard *std = arg;
484
485 switch (t->type) {
486 case TUNER_SONY_BTF_PG472Z:
487 switch (std->index) {
488 case 0:
489 v4l2_video_std_construct(std,
490 V4L2_STD_PAL_BG, "PAL-B/G");
491 break;
492 case 1:
493 v4l2_video_std_construct(std,
494 V4L2_STD_PAL_I, "PAL-I");
495 break;
496 case 2:
497 v4l2_video_std_construct(std,
498 V4L2_STD_PAL_DK, "PAL-D/K");
499 break;
500 case 3:
501 v4l2_video_std_construct(std,
502 V4L2_STD_SECAM_L, "SECAM-L");
503 break;
504 default:
505 std->id = 0; /* hack to indicate EINVAL */
506 break;
507 }
508 break;
509 case TUNER_SONY_BTF_PK467Z:
510 if (std->index != 0) {
511 std->id = 0; /* hack to indicate EINVAL */
512 break;
513 }
514 v4l2_video_std_construct(std,
515 V4L2_STD_NTSC_M_JP, "NTSC-J");
516 break;
517 case TUNER_SONY_BTF_PB463Z:
518 if (std->index != 0) {
519 std->id = 0; /* hack to indicate EINVAL */
520 break;
521 }
522 v4l2_video_std_construct(std, V4L2_STD_NTSC_M, "NTSC");
523 break;
524 }
525 break;
526 }
527 case VIDIOC_G_STD:
528 {
529 v4l2_std_id *std = arg;
530
531 *std = t->std;
532 break;
533 }
534 case VIDIOC_S_STD:
535 {
536 v4l2_std_id *std = arg;
537 v4l2_std_id old = t->std;
538
539 switch (t->type) {
540 case TUNER_SONY_BTF_PG472Z:
541 if (force_band && (*std & force_band) != *std &&
542 *std != V4L2_STD_PAL &&
543 *std != V4L2_STD_SECAM) {
544 printk(KERN_DEBUG "wis-sony-tuner: ignoring "
545 "requested TV standard in "
546 "favor of force_band value\n");
547 t->std = force_band;
548 } else if (*std & V4L2_STD_PAL_BG) { /* default */
549 t->std = V4L2_STD_PAL_BG;
550 } else if (*std & V4L2_STD_PAL_I) {
551 t->std = V4L2_STD_PAL_I;
552 } else if (*std & V4L2_STD_PAL_DK) {
553 t->std = V4L2_STD_PAL_DK;
554 } else if (*std & V4L2_STD_SECAM_L) {
555 t->std = V4L2_STD_SECAM_L;
556 } else {
557 printk(KERN_ERR "wis-sony-tuner: TV standard "
558 "not supported\n");
559 *std = 0; /* hack to indicate EINVAL */
560 break;
561 }
562 if (old != t->std)
563 set_if(client);
564 break;
565 case TUNER_SONY_BTF_PK467Z:
566 if (!(*std & V4L2_STD_NTSC_M_JP)) {
567 printk(KERN_ERR "wis-sony-tuner: TV standard "
568 "not supported\n");
569 *std = 0; /* hack to indicate EINVAL */
570 }
571 break;
572 case TUNER_SONY_BTF_PB463Z:
573 if (!(*std & V4L2_STD_NTSC_M)) {
574 printk(KERN_ERR "wis-sony-tuner: TV standard "
575 "not supported\n");
576 *std = 0; /* hack to indicate EINVAL */
577 }
578 break;
579 }
580 break;
581 }
582 case VIDIOC_QUERYSTD:
583 {
584 v4l2_std_id *std = arg;
585
586 switch (t->type) {
587 case TUNER_SONY_BTF_PG472Z:
588 if (force_band)
589 *std = force_band;
590 else
591 *std = V4L2_STD_PAL_BG | V4L2_STD_PAL_I |
592 V4L2_STD_PAL_DK | V4L2_STD_SECAM_L;
593 break;
594 case TUNER_SONY_BTF_PK467Z:
595 *std = V4L2_STD_NTSC_M_JP;
596 break;
597 case TUNER_SONY_BTF_PB463Z:
598 *std = V4L2_STD_NTSC_M;
599 break;
600 }
601 break;
602 }
603 case VIDIOC_G_TUNER:
604 {
605 struct v4l2_tuner *tun = arg;
606
607 memset(t, 0, sizeof(*tun));
608 strcpy(tun->name, "Television");
609 tun->type = V4L2_TUNER_ANALOG_TV;
610 tun->rangelow = 0UL; /* does anything use these? */
611 tun->rangehigh = 0xffffffffUL;
612 switch (t->type) {
613 case TUNER_SONY_BTF_PG472Z:
614 tun->capability = V4L2_TUNER_CAP_NORM |
615 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
616 V4L2_TUNER_CAP_LANG2;
617 tun->rxsubchans = V4L2_TUNER_SUB_MONO |
618 V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
619 V4L2_TUNER_SUB_LANG2;
620 break;
621 case TUNER_SONY_BTF_PK467Z:
622 case TUNER_SONY_BTF_PB463Z:
623 tun->capability = V4L2_TUNER_CAP_STEREO;
624 tun->rxsubchans = V4L2_TUNER_SUB_MONO |
625 V4L2_TUNER_SUB_STEREO;
626 break;
627 }
628 tun->audmode = t->audmode;
629 return 0;
630 }
631 case VIDIOC_S_TUNER:
632 {
633 struct v4l2_tuner *tun = arg;
634
635 switch (t->type) {
636 case TUNER_SONY_BTF_PG472Z:
637 if (tun->audmode != t->audmode) {
638 t->audmode = tun->audmode;
639 mpx_setup(client);
640 }
641 break;
642 case TUNER_SONY_BTF_PK467Z:
643 case TUNER_SONY_BTF_PB463Z:
644 break;
645 }
646 return 0;
647 }
648 default:
649 break;
650 }
651 return 0;
652}
653
654static struct i2c_driver wis_sony_tuner_driver;
655
656static struct i2c_client wis_sony_tuner_client_templ = {
657 .name = "Sony TV Tuner (WIS)",
658 .driver = &wis_sony_tuner_driver,
659};
660
661static int wis_sony_tuner_detect(struct i2c_adapter *adapter,
662 int addr, int kind)
663{
664 struct i2c_client *client;
665 struct wis_sony_tuner *t;
666
667 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
668 return 0;
669
670 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
671 if (client == NULL)
672 return -ENOMEM;
673 memcpy(client, &wis_sony_tuner_client_templ,
674 sizeof(wis_sony_tuner_client_templ));
675 client->adapter = adapter;
676 client->addr = addr;
677
678 t = kmalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL);
679 if (t == NULL) {
680 kfree(client);
681 return -ENOMEM;
682 }
683 t->type = -1;
684 t->freq = 0;
685 t->mpxmode = 0;
686 t->audmode = V4L2_TUNER_MODE_STEREO;
687 i2c_set_clientdata(client, t);
688
689 printk(KERN_DEBUG
690 "wis-sony-tuner: initializing tuner at address %d on %s\n",
691 addr, adapter->name);
692
693 i2c_attach_client(client);
694
695 return 0;
696}
697
698static int wis_sony_tuner_detach(struct i2c_client *client)
699{
700 struct wis_sony_tuner *t = i2c_get_clientdata(client);
701 int r;
702
703 r = i2c_detach_client(client);
704 if (r < 0)
705 return r;
706
707 kfree(t);
708 kfree(client);
709 return 0;
710}
711
712static struct i2c_driver wis_sony_tuner_driver = {
713 .driver = {
714 .name = "WIS Sony TV Tuner I2C driver",
715 },
716 .id = I2C_DRIVERID_WIS_SONY_TUNER,
717 .detach_client = wis_sony_tuner_detach,
718 .command = tuner_command,
719};
720
721static int __init wis_sony_tuner_init(void)
722{
723 int r;
724
725 r = i2c_add_driver(&wis_sony_tuner_driver);
726 if (r < 0)
727 return r;
728 return wis_i2c_add_driver(wis_sony_tuner_driver.id,
729 wis_sony_tuner_detect);
730}
731
732static void __exit wis_sony_tuner_cleanup(void)
733{
734 wis_i2c_del_driver(wis_sony_tuner_detect);
735 i2c_del_driver(&wis_sony_tuner_driver);
736}
737
738module_init(wis_sony_tuner_init);
739module_exit(wis_sony_tuner_cleanup);
740
741MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c
new file mode 100644
index 00000000000..69ed7bf0322
--- /dev/null
+++ b/drivers/staging/go7007/wis-tw2804.c
@@ -0,0 +1,381 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/version.h>
21#include <linux/i2c.h>
22#include <linux/videodev.h>
23#include <linux/video_decoder.h>
24#include <linux/ioctl.h>
25
26#include "wis-i2c.h"
27
28struct wis_tw2804 {
29 int channel;
30 int norm;
31 int brightness;
32 int contrast;
33 int saturation;
34 int hue;
35};
36
37static u8 global_registers[] =
38{
39 0x39, 0x00,
40 0x3a, 0xff,
41 0x3b, 0x84,
42 0x3c, 0x80,
43 0x3d, 0x80,
44 0x3e, 0x82,
45 0x3f, 0x82,
46 0xff, 0xff, /* Terminator (reg 0xff does not exist) */
47};
48
49static u8 channel_registers[] =
50{
51 0x01, 0xc4,
52 0x02, 0xa5,
53 0x03, 0x20,
54 0x04, 0xd0,
55 0x05, 0x20,
56 0x06, 0xd0,
57 0x07, 0x88,
58 0x08, 0x20,
59 0x09, 0x07,
60 0x0a, 0xf0,
61 0x0b, 0x07,
62 0x0c, 0xf0,
63 0x0d, 0x40,
64 0x0e, 0xd2,
65 0x0f, 0x80,
66 0x10, 0x80,
67 0x11, 0x80,
68 0x12, 0x80,
69 0x13, 0x1f,
70 0x14, 0x00,
71 0x15, 0x00,
72 0x16, 0x00,
73 0x17, 0x00,
74 0x18, 0xff,
75 0x19, 0xff,
76 0x1a, 0xff,
77 0x1b, 0xff,
78 0x1c, 0xff,
79 0x1d, 0xff,
80 0x1e, 0xff,
81 0x1f, 0xff,
82 0x20, 0x07,
83 0x21, 0x07,
84 0x22, 0x00,
85 0x23, 0x91,
86 0x24, 0x51,
87 0x25, 0x03,
88 0x26, 0x00,
89 0x27, 0x00,
90 0x28, 0x00,
91 0x29, 0x00,
92 0x2a, 0x00,
93 0x2b, 0x00,
94 0x2c, 0x00,
95 0x2d, 0x00,
96 0x2e, 0x00,
97 0x2f, 0x00,
98 0x30, 0x00,
99 0x31, 0x00,
100 0x32, 0x00,
101 0x33, 0x00,
102 0x34, 0x00,
103 0x35, 0x00,
104 0x36, 0x00,
105 0x37, 0x00,
106 0xff, 0xff, /* Terminator (reg 0xff does not exist) */
107};
108
109static int write_reg(struct i2c_client *client, u8 reg, u8 value, int channel)
110{
111 return i2c_smbus_write_byte_data(client, reg | (channel << 6), value);
112}
113
114static int write_regs(struct i2c_client *client, u8 *regs, int channel)
115{
116 int i;
117
118 for (i = 0; regs[i] != 0xff; i += 2)
119 if (i2c_smbus_write_byte_data(client,
120 regs[i] | (channel << 6), regs[i + 1]) < 0)
121 return -1;
122 return 0;
123}
124
125static int wis_tw2804_command(struct i2c_client *client,
126 unsigned int cmd, void *arg)
127{
128 struct wis_tw2804 *dec = i2c_get_clientdata(client);
129
130 if (cmd == DECODER_SET_CHANNEL) {
131 int *input = arg;
132
133 if (*input < 0 || *input > 3) {
134 printk(KERN_ERR "wis-tw2804: channel %d is not "
135 "between 0 and 3!\n", *input);
136 return 0;
137 }
138 dec->channel = *input;
139 printk(KERN_DEBUG "wis-tw2804: initializing TW2804 "
140 "channel %d\n", dec->channel);
141 if (dec->channel == 0 &&
142 write_regs(client, global_registers, 0) < 0) {
143 printk(KERN_ERR "wis-tw2804: error initializing "
144 "TW2804 global registers\n");
145 return 0;
146 }
147 if (write_regs(client, channel_registers, dec->channel) < 0) {
148 printk(KERN_ERR "wis-tw2804: error initializing "
149 "TW2804 channel %d\n", dec->channel);
150 return 0;
151 }
152 return 0;
153 }
154
155 if (dec->channel < 0) {
156 printk(KERN_DEBUG "wis-tw2804: ignoring command %08x until "
157 "channel number is set\n", cmd);
158 return 0;
159 }
160
161 switch (cmd) {
162 case DECODER_SET_NORM:
163 {
164 int *input = arg;
165 u8 regs[] = {
166 0x01, *input == VIDEO_MODE_NTSC ? 0xc4 : 0x84,
167 0x09, *input == VIDEO_MODE_NTSC ? 0x07 : 0x04,
168 0x0a, *input == VIDEO_MODE_NTSC ? 0xf0 : 0x20,
169 0x0b, *input == VIDEO_MODE_NTSC ? 0x07 : 0x04,
170 0x0c, *input == VIDEO_MODE_NTSC ? 0xf0 : 0x20,
171 0x0d, *input == VIDEO_MODE_NTSC ? 0x40 : 0x4a,
172 0x16, *input == VIDEO_MODE_NTSC ? 0x00 : 0x40,
173 0x17, *input == VIDEO_MODE_NTSC ? 0x00 : 0x40,
174 0x20, *input == VIDEO_MODE_NTSC ? 0x07 : 0x0f,
175 0x21, *input == VIDEO_MODE_NTSC ? 0x07 : 0x0f,
176 0xff, 0xff,
177 };
178 write_regs(client, regs, dec->channel);
179 dec->norm = *input;
180 break;
181 }
182 case VIDIOC_QUERYCTRL:
183 {
184 struct v4l2_queryctrl *ctrl = arg;
185
186 switch (ctrl->id) {
187 case V4L2_CID_BRIGHTNESS:
188 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
189 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
190 ctrl->minimum = 0;
191 ctrl->maximum = 255;
192 ctrl->step = 1;
193 ctrl->default_value = 128;
194 ctrl->flags = 0;
195 break;
196 case V4L2_CID_CONTRAST:
197 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
198 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
199 ctrl->minimum = 0;
200 ctrl->maximum = 255;
201 ctrl->step = 1;
202 ctrl->default_value = 128;
203 ctrl->flags = 0;
204 break;
205 case V4L2_CID_SATURATION:
206 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
207 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
208 ctrl->minimum = 0;
209 ctrl->maximum = 255;
210 ctrl->step = 1;
211 ctrl->default_value = 128;
212 ctrl->flags = 0;
213 break;
214 case V4L2_CID_HUE:
215 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
216 strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
217 ctrl->minimum = 0;
218 ctrl->maximum = 255;
219 ctrl->step = 1;
220 ctrl->default_value = 128;
221 ctrl->flags = 0;
222 break;
223 }
224 break;
225 }
226 case VIDIOC_S_CTRL:
227 {
228 struct v4l2_control *ctrl = arg;
229
230 switch (ctrl->id) {
231 case V4L2_CID_BRIGHTNESS:
232 if (ctrl->value > 255)
233 dec->brightness = 255;
234 else if (ctrl->value < 0)
235 dec->brightness = 0;
236 else
237 dec->brightness = ctrl->value;
238 write_reg(client, 0x12, dec->brightness, dec->channel);
239 break;
240 case V4L2_CID_CONTRAST:
241 if (ctrl->value > 255)
242 dec->contrast = 255;
243 else if (ctrl->value < 0)
244 dec->contrast = 0;
245 else
246 dec->contrast = ctrl->value;
247 write_reg(client, 0x11, dec->contrast, dec->channel);
248 break;
249 case V4L2_CID_SATURATION:
250 if (ctrl->value > 255)
251 dec->saturation = 255;
252 else if (ctrl->value < 0)
253 dec->saturation = 0;
254 else
255 dec->saturation = ctrl->value;
256 write_reg(client, 0x10, dec->saturation, dec->channel);
257 break;
258 case V4L2_CID_HUE:
259 if (ctrl->value > 255)
260 dec->hue = 255;
261 else if (ctrl->value < 0)
262 dec->hue = 0;
263 else
264 dec->hue = ctrl->value;
265 write_reg(client, 0x0f, dec->hue, dec->channel);
266 break;
267 }
268 break;
269 }
270 case VIDIOC_G_CTRL:
271 {
272 struct v4l2_control *ctrl = arg;
273
274 switch (ctrl->id) {
275 case V4L2_CID_BRIGHTNESS:
276 ctrl->value = dec->brightness;
277 break;
278 case V4L2_CID_CONTRAST:
279 ctrl->value = dec->contrast;
280 break;
281 case V4L2_CID_SATURATION:
282 ctrl->value = dec->saturation;
283 break;
284 case V4L2_CID_HUE:
285 ctrl->value = dec->hue;
286 break;
287 }
288 break;
289 }
290 default:
291 break;
292 }
293 return 0;
294}
295
296static struct i2c_driver wis_tw2804_driver;
297
298static struct i2c_client wis_tw2804_client_templ = {
299 .name = "TW2804 (WIS)",
300 .driver = &wis_tw2804_driver,
301};
302
303static int wis_tw2804_detect(struct i2c_adapter *adapter, int addr, int kind)
304{
305 struct i2c_client *client;
306 struct wis_tw2804 *dec;
307
308 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
309 return 0;
310
311 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
312 if (client == NULL)
313 return -ENOMEM;
314 memcpy(client, &wis_tw2804_client_templ,
315 sizeof(wis_tw2804_client_templ));
316 client->adapter = adapter;
317 client->addr = addr;
318
319 dec = kmalloc(sizeof(struct wis_tw2804), GFP_KERNEL);
320 if (dec == NULL) {
321 kfree(client);
322 return -ENOMEM;
323 }
324 dec->channel = -1;
325 dec->norm = VIDEO_MODE_NTSC;
326 dec->brightness = 128;
327 dec->contrast = 128;
328 dec->saturation = 128;
329 dec->hue = 128;
330 i2c_set_clientdata(client, dec);
331
332 printk(KERN_DEBUG "wis-tw2804: creating TW2804 at address %d on %s\n",
333 addr, adapter->name);
334
335 i2c_attach_client(client);
336 return 0;
337}
338
339static int wis_tw2804_detach(struct i2c_client *client)
340{
341 struct wis_tw2804 *dec = i2c_get_clientdata(client);
342 int r;
343
344 r = i2c_detach_client(client);
345 if (r < 0)
346 return r;
347
348 kfree(client);
349 kfree(dec);
350 return 0;
351}
352
353static struct i2c_driver wis_tw2804_driver = {
354 .driver = {
355 .name = "WIS TW2804 I2C driver",
356 },
357 .id = I2C_DRIVERID_WIS_TW2804,
358 .detach_client = wis_tw2804_detach,
359 .command = wis_tw2804_command,
360};
361
362static int __init wis_tw2804_init(void)
363{
364 int r;
365
366 r = i2c_add_driver(&wis_tw2804_driver);
367 if (r < 0)
368 return r;
369 return wis_i2c_add_driver(wis_tw2804_driver.id, wis_tw2804_detect);
370}
371
372static void __exit wis_tw2804_cleanup(void)
373{
374 wis_i2c_del_driver(wis_tw2804_detect);
375 i2c_del_driver(&wis_tw2804_driver);
376}
377
378module_init(wis_tw2804_init);
379module_exit(wis_tw2804_cleanup);
380
381MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
new file mode 100644
index 00000000000..1cdf01a8b33
--- /dev/null
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -0,0 +1,363 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/version.h>
21#include <linux/i2c.h>
22#include <linux/videodev.h>
23#include <linux/video_decoder.h>
24#include <linux/ioctl.h>
25
26#include "wis-i2c.h"
27
28struct wis_tw9903 {
29 int norm;
30 int brightness;
31 int contrast;
32 int hue;
33};
34
35static u8 initial_registers[] =
36{
37 0x02, 0x44, /* input 1, composite */
38 0x03, 0x92, /* correct digital format */
39 0x04, 0x00,
40 0x05, 0x80, /* or 0x00 for PAL */
41 0x06, 0x40, /* second internal current reference */
42 0x07, 0x02, /* window */
43 0x08, 0x14, /* window */
44 0x09, 0xf0, /* window */
45 0x0a, 0x81, /* window */
46 0x0b, 0xd0, /* window */
47 0x0c, 0x8c,
48 0x0d, 0x00, /* scaling */
49 0x0e, 0x11, /* scaling */
50 0x0f, 0x00, /* scaling */
51 0x10, 0x00, /* brightness */
52 0x11, 0x60, /* contrast */
53 0x12, 0x01, /* sharpness */
54 0x13, 0x7f, /* U gain */
55 0x14, 0x5a, /* V gain */
56 0x15, 0x00, /* hue */
57 0x16, 0xc3, /* sharpness */
58 0x18, 0x00,
59 0x19, 0x58, /* vbi */
60 0x1a, 0x80,
61 0x1c, 0x0f, /* video norm */
62 0x1d, 0x7f, /* video norm */
63 0x20, 0xa0, /* clamping gain (working 0x50) */
64 0x21, 0x22,
65 0x22, 0xf0,
66 0x23, 0xfe,
67 0x24, 0x3c,
68 0x25, 0x38,
69 0x26, 0x44,
70 0x27, 0x20,
71 0x28, 0x00,
72 0x29, 0x15,
73 0x2a, 0xa0,
74 0x2b, 0x44,
75 0x2c, 0x37,
76 0x2d, 0x00,
77 0x2e, 0xa5, /* burst PLL control (working: a9) */
78 0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */
79 0x31, 0x00,
80 0x33, 0x22,
81 0x34, 0x11,
82 0x35, 0x35,
83 0x3b, 0x05,
84 0x06, 0xc0, /* reset device */
85 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
86};
87
88static int write_reg(struct i2c_client *client, u8 reg, u8 value)
89{
90 return i2c_smbus_write_byte_data(client, reg, value);
91}
92
93static int write_regs(struct i2c_client *client, u8 *regs)
94{
95 int i;
96
97 for (i = 0; regs[i] != 0x00; i += 2)
98 if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
99 return -1;
100 return 0;
101}
102
103static int wis_tw9903_command(struct i2c_client *client,
104 unsigned int cmd, void *arg)
105{
106 struct wis_tw9903 *dec = i2c_get_clientdata(client);
107
108 switch (cmd) {
109 case DECODER_SET_INPUT:
110 {
111 int *input = arg;
112
113 i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
114 break;
115 }
116#if 0 /* The scaler on this thing seems to be horribly broken */
117 case DECODER_SET_RESOLUTION:
118 {
119 struct video_decoder_resolution *res = arg;
120 /*int hscale = 256 * 720 / res->width;*/
121 int hscale = 256 * 720 / (res->width - (res->width > 704 ? 0 : 8));
122 int vscale = 256 * (dec->norm == VIDEO_MODE_NTSC ? 240 : 288)
123 / res->height;
124 u8 regs[] = {
125 0x0d, vscale & 0xff,
126 0x0f, hscale & 0xff,
127 0x0e, ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8),
128 0x06, 0xc0, /* reset device */
129 0, 0,
130 };
131 printk(KERN_DEBUG "vscale is %04x, hscale is %04x\n",
132 vscale, hscale);
133 /*write_regs(client, regs);*/
134 break;
135 }
136#endif
137 case DECODER_SET_NORM:
138 {
139 int *input = arg;
140 u8 regs[] = {
141 0x05, *input == VIDEO_MODE_NTSC ? 0x80 : 0x00,
142 0x07, *input == VIDEO_MODE_NTSC ? 0x02 : 0x12,
143 0x08, *input == VIDEO_MODE_NTSC ? 0x14 : 0x18,
144 0x09, *input == VIDEO_MODE_NTSC ? 0xf0 : 0x20,
145 0, 0,
146 };
147 write_regs(client, regs);
148 dec->norm = *input;
149 break;
150 }
151 case VIDIOC_QUERYCTRL:
152 {
153 struct v4l2_queryctrl *ctrl = arg;
154
155 switch (ctrl->id) {
156 case V4L2_CID_BRIGHTNESS:
157 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
158 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
159 ctrl->minimum = -128;
160 ctrl->maximum = 127;
161 ctrl->step = 1;
162 ctrl->default_value = 0x00;
163 ctrl->flags = 0;
164 break;
165 case V4L2_CID_CONTRAST:
166 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
167 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
168 ctrl->minimum = 0;
169 ctrl->maximum = 255;
170 ctrl->step = 1;
171 ctrl->default_value = 0x60;
172 ctrl->flags = 0;
173 break;
174#if 0
175 /* I don't understand how the Chroma Gain registers work... */
176 case V4L2_CID_SATURATION:
177 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
178 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
179 ctrl->minimum = 0;
180 ctrl->maximum = 127;
181 ctrl->step = 1;
182 ctrl->default_value = 64;
183 ctrl->flags = 0;
184 break;
185#endif
186 case V4L2_CID_HUE:
187 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
188 strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
189 ctrl->minimum = -128;
190 ctrl->maximum = 127;
191 ctrl->step = 1;
192 ctrl->default_value = 0;
193 ctrl->flags = 0;
194 break;
195 }
196 break;
197 }
198 case VIDIOC_S_CTRL:
199 {
200 struct v4l2_control *ctrl = arg;
201
202 switch (ctrl->id) {
203 case V4L2_CID_BRIGHTNESS:
204 if (ctrl->value > 127)
205 dec->brightness = 127;
206 else if (ctrl->value < -128)
207 dec->brightness = -128;
208 else
209 dec->brightness = ctrl->value;
210 write_reg(client, 0x10, dec->brightness);
211 break;
212 case V4L2_CID_CONTRAST:
213 if (ctrl->value > 255)
214 dec->contrast = 255;
215 else if (ctrl->value < 0)
216 dec->contrast = 0;
217 else
218 dec->contrast = ctrl->value;
219 write_reg(client, 0x11, dec->contrast);
220 break;
221#if 0
222 case V4L2_CID_SATURATION:
223 if (ctrl->value > 127)
224 dec->saturation = 127;
225 else if (ctrl->value < 0)
226 dec->saturation = 0;
227 else
228 dec->saturation = ctrl->value;
229 /*write_reg(client, 0x0c, dec->saturation);*/
230 break;
231#endif
232 case V4L2_CID_HUE:
233 if (ctrl->value > 127)
234 dec->hue = 127;
235 else if (ctrl->value < -128)
236 dec->hue = -128;
237 else
238 dec->hue = ctrl->value;
239 write_reg(client, 0x15, dec->hue);
240 break;
241 }
242 break;
243 }
244 case VIDIOC_G_CTRL:
245 {
246 struct v4l2_control *ctrl = arg;
247
248 switch (ctrl->id) {
249 case V4L2_CID_BRIGHTNESS:
250 ctrl->value = dec->brightness;
251 break;
252 case V4L2_CID_CONTRAST:
253 ctrl->value = dec->contrast;
254 break;
255#if 0
256 case V4L2_CID_SATURATION:
257 ctrl->value = dec->saturation;
258 break;
259#endif
260 case V4L2_CID_HUE:
261 ctrl->value = dec->hue;
262 break;
263 }
264 break;
265 }
266 default:
267 break;
268 }
269 return 0;
270}
271
272static struct i2c_driver wis_tw9903_driver;
273
274static struct i2c_client wis_tw9903_client_templ = {
275 .name = "TW9903 (WIS)",
276 .driver = &wis_tw9903_driver,
277};
278
279static int wis_tw9903_detect(struct i2c_adapter *adapter, int addr, int kind)
280{
281 struct i2c_client *client;
282 struct wis_tw9903 *dec;
283
284 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
285 return 0;
286
287 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
288 if (client == NULL)
289 return -ENOMEM;
290 memcpy(client, &wis_tw9903_client_templ,
291 sizeof(wis_tw9903_client_templ));
292 client->adapter = adapter;
293 client->addr = addr;
294
295 dec = kmalloc(sizeof(struct wis_tw9903), GFP_KERNEL);
296 if (dec == NULL) {
297 kfree(client);
298 return -ENOMEM;
299 }
300 dec->norm = VIDEO_MODE_NTSC;
301 dec->brightness = 0;
302 dec->contrast = 0x60;
303 dec->hue = 0;
304 i2c_set_clientdata(client, dec);
305
306 printk(KERN_DEBUG
307 "wis-tw9903: initializing TW9903 at address %d on %s\n",
308 addr, adapter->name);
309
310 if (write_regs(client, initial_registers) < 0) {
311 printk(KERN_ERR "wis-tw9903: error initializing TW9903\n");
312 kfree(client);
313 kfree(dec);
314 return 0;
315 }
316
317 i2c_attach_client(client);
318 return 0;
319}
320
321static int wis_tw9903_detach(struct i2c_client *client)
322{
323 struct wis_tw9903 *dec = i2c_get_clientdata(client);
324 int r;
325
326 r = i2c_detach_client(client);
327 if (r < 0)
328 return r;
329
330 kfree(client);
331 kfree(dec);
332 return 0;
333}
334
335static struct i2c_driver wis_tw9903_driver = {
336 .driver = {
337 .name = "WIS TW9903 I2C driver",
338 },
339 .id = I2C_DRIVERID_WIS_TW9903,
340 .detach_client = wis_tw9903_detach,
341 .command = wis_tw9903_command,
342};
343
344static int __init wis_tw9903_init(void)
345{
346 int r;
347
348 r = i2c_add_driver(&wis_tw9903_driver);
349 if (r < 0)
350 return r;
351 return wis_i2c_add_driver(wis_tw9903_driver.id, wis_tw9903_detect);
352}
353
354static void __exit wis_tw9903_cleanup(void)
355{
356 wis_i2c_del_driver(wis_tw9903_detect);
357 i2c_del_driver(&wis_tw9903_driver);
358}
359
360module_init(wis_tw9903_init);
361module_exit(wis_tw9903_cleanup);
362
363MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/go7007/wis-uda1342.c
new file mode 100644
index 00000000000..28c10bf3a47
--- /dev/null
+++ b/drivers/staging/go7007/wis-uda1342.c
@@ -0,0 +1,136 @@
1/*
2 * Copyright (C) 2005-2006 Micronas USA Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/version.h>
21#include <linux/i2c.h>
22#include <linux/videodev.h>
23#include <media/tvaudio.h>
24#include <media/v4l2-common.h>
25
26#include "wis-i2c.h"
27
28static int write_reg(struct i2c_client *client, int reg, int value)
29{
30 /* UDA1342 wants MSB first, but SMBus sends LSB first */
31 i2c_smbus_write_word_data(client, reg, swab16(value));
32 return 0;
33}
34
35static int wis_uda1342_command(struct i2c_client *client,
36 unsigned int cmd, void *arg)
37{
38 switch (cmd) {
39 case VIDIOC_S_AUDIO:
40 {
41 int *inp = arg;
42
43 switch (*inp) {
44 case TVAUDIO_INPUT_TUNER:
45 write_reg(client, 0x00, 0x1441); /* select input 2 */
46 break;
47 case TVAUDIO_INPUT_EXTERN:
48 write_reg(client, 0x00, 0x1241); /* select input 1 */
49 break;
50 default:
51 printk(KERN_ERR "wis-uda1342: input %d not supported\n",
52 *inp);
53 break;
54 }
55 break;
56 }
57 default:
58 break;
59 }
60 return 0;
61}
62
63static struct i2c_driver wis_uda1342_driver;
64
65static struct i2c_client wis_uda1342_client_templ = {
66 .name = "UDA1342 (WIS)",
67 .driver = &wis_uda1342_driver,
68};
69
70static int wis_uda1342_detect(struct i2c_adapter *adapter, int addr, int kind)
71{
72 struct i2c_client *client;
73
74 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
75 return 0;
76
77 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
78 if (client == NULL)
79 return -ENOMEM;
80 memcpy(client, &wis_uda1342_client_templ,
81 sizeof(wis_uda1342_client_templ));
82 client->adapter = adapter;
83 client->addr = addr;
84
85 printk(KERN_DEBUG
86 "wis-uda1342: initializing UDA1342 at address %d on %s\n",
87 addr, adapter->name);
88
89 write_reg(client, 0x00, 0x8000); /* reset registers */
90 write_reg(client, 0x00, 0x1241); /* select input 1 */
91
92 i2c_attach_client(client);
93 return 0;
94}
95
96static int wis_uda1342_detach(struct i2c_client *client)
97{
98 int r;
99
100 r = i2c_detach_client(client);
101 if (r < 0)
102 return r;
103
104 kfree(client);
105 return 0;
106}
107
108static struct i2c_driver wis_uda1342_driver = {
109 .driver = {
110 .name = "WIS UDA1342 I2C driver",
111 },
112 .id = I2C_DRIVERID_WIS_UDA1342,
113 .detach_client = wis_uda1342_detach,
114 .command = wis_uda1342_command,
115};
116
117static int __init wis_uda1342_init(void)
118{
119 int r;
120
121 r = i2c_add_driver(&wis_uda1342_driver);
122 if (r < 0)
123 return r;
124 return wis_i2c_add_driver(wis_uda1342_driver.id, wis_uda1342_detect);
125}
126
127static void __exit wis_uda1342_cleanup(void)
128{
129 wis_i2c_del_driver(wis_uda1342_detect);
130 i2c_del_driver(&wis_uda1342_driver);
131}
132
133module_init(wis_uda1342_init);
134module_exit(wis_uda1342_cleanup);
135
136MODULE_LICENSE("GPL v2");