aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/go7007
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/go7007')
-rw-r--r--drivers/staging/go7007/Kconfig109
-rw-r--r--drivers/staging/go7007/Makefile34
-rw-r--r--drivers/staging/go7007/README11
-rw-r--r--drivers/staging/go7007/go7007-driver.c659
-rw-r--r--drivers/staging/go7007/go7007-fw.c1636
-rw-r--r--drivers/staging/go7007/go7007-i2c.c225
-rw-r--r--drivers/staging/go7007/go7007-priv.h290
-rw-r--r--drivers/staging/go7007/go7007-usb.c1288
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c1839
-rw-r--r--drivers/staging/go7007/go7007.h114
-rw-r--r--drivers/staging/go7007/go7007.txt481
-rw-r--r--drivers/staging/go7007/s2250-board.c698
-rw-r--r--drivers/staging/go7007/s2250-loader.c191
-rw-r--r--drivers/staging/go7007/s2250-loader.h24
-rw-r--r--drivers/staging/go7007/saa7134-go7007.c532
-rw-r--r--drivers/staging/go7007/snd-go7007.c306
-rw-r--r--drivers/staging/go7007/wis-i2c.h47
-rw-r--r--drivers/staging/go7007/wis-ov7640.c108
-rw-r--r--drivers/staging/go7007/wis-saa7113.c336
-rw-r--r--drivers/staging/go7007/wis-saa7115.c469
-rw-r--r--drivers/staging/go7007/wis-sony-tuner.c720
-rw-r--r--drivers/staging/go7007/wis-tw2804.c359
-rw-r--r--drivers/staging/go7007/wis-tw9903.c341
-rw-r--r--drivers/staging/go7007/wis-uda1342.c114
24 files changed, 10931 insertions, 0 deletions
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
new file mode 100644
index 00000000000..7dfb2815b9e
--- /dev/null
+++ b/drivers/staging/go7007/Kconfig
@@ -0,0 +1,109 @@
1config VIDEO_GO7007
2 tristate "WIS GO7007 MPEG encoder support"
3 depends on VIDEO_DEV && PCI && I2C
4 depends on SND
5 select VIDEOBUF_DMA_SG
6 depends on RC_CORE
7 select VIDEO_TUNER
8 select VIDEO_TVEEPROM
9 select SND_PCM
10 select CRC32
11 default N
12 ---help---
13 This is a video4linux driver for the WIS GO7007 MPEG
14 encoder chip.
15
16 To compile this driver as a module, choose M here: the
17 module will be called go7007
18
19config VIDEO_GO7007_USB
20 tristate "WIS GO7007 USB support"
21 depends on VIDEO_GO7007 && USB
22 default N
23 ---help---
24 This is a video4linux driver for the WIS GO7007 MPEG
25 encoder chip over USB.
26
27 To compile this driver as a module, choose M here: the
28 module will be called go7007-usb
29
30config VIDEO_GO7007_USB_S2250_BOARD
31 tristate "Sensoray 2250/2251 support"
32 depends on VIDEO_GO7007_USB && DVB_USB
33 default N
34 ---help---
35 This is a video4linux driver for the Sensoray 2250/2251 device.
36
37 To compile this driver as a module, choose M here: the
38 module will be called s2250
39
40config VIDEO_GO7007_OV7640
41 tristate "OV7640 subdev support"
42 depends on VIDEO_GO7007
43 default N
44 ---help---
45 This is a video4linux driver for the OV7640 sub-device.
46
47 To compile this driver as a module, choose M here: the
48 module will be called wis-ov7640
49
50config VIDEO_GO7007_SAA7113
51 tristate "SAA7113 subdev support"
52 depends on VIDEO_GO7007
53 default N
54 ---help---
55 This is a video4linux driver for the SAA7113 sub-device.
56
57 To compile this driver as a module, choose M here: the
58 module will be called wis-saa7113
59
60config VIDEO_GO7007_SAA7115
61 tristate "SAA7115 subdev support"
62 depends on VIDEO_GO7007
63 default N
64 ---help---
65 This is a video4linux driver for the SAA7115 sub-device.
66
67 To compile this driver as a module, choose M here: the
68 module will be called wis-saa7115
69
70config VIDEO_GO7007_TW9903
71 tristate "TW9903 subdev support"
72 depends on VIDEO_GO7007
73 default N
74 ---help---
75 This is a video4linux driver for the TW9903 sub-device.
76
77 To compile this driver as a module, choose M here: the
78 module will be called wis-tw9903
79
80config VIDEO_GO7007_UDA1342
81 tristate "UDA1342 subdev support"
82 depends on VIDEO_GO7007
83 default N
84 ---help---
85 This is a video4linux driver for the UDA1342 sub-device.
86
87 To compile this driver as a module, choose M here: the
88 module will be called wis-uda1342
89
90config VIDEO_GO7007_SONY_TUNER
91 tristate "Sony tuner subdev support"
92 depends on VIDEO_GO7007
93 default N
94 ---help---
95 This is a video4linux driver for the Sony Tuner sub-device.
96
97 To compile this driver as a module, choose M here: the
98 module will be called wis-sony-tuner
99
100config VIDEO_GO7007_TW2804
101 tristate "TW2804 subdev support"
102 depends on VIDEO_GO7007
103 default N
104 ---help---
105 This is a video4linux driver for the TW2804 sub-device.
106
107 To compile this driver as a module, choose M here: the
108 module will be called wis-tw2804
109
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
new file mode 100644
index 00000000000..60a91853570
--- /dev/null
+++ b/drivers/staging/go7007/Makefile
@@ -0,0 +1,34 @@
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
8obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o s2250-loader.o
9obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o
10obj-$(CONFIG_VIDEO_GO7007_OV7640) += wis-ov7640.o
11obj-$(CONFIG_VIDEO_GO7007_SAA7115) += wis-saa7115.o
12obj-$(CONFIG_VIDEO_GO7007_TW9903) += wis-tw9903.o
13obj-$(CONFIG_VIDEO_GO7007_UDA1342) += wis-uda1342.o
14obj-$(CONFIG_VIDEO_GO7007_SONY_TUNER) += wis-sony-tuner.o
15obj-$(CONFIG_VIDEO_GO7007_TW2804) += wis-tw2804.o
16
17go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
18 snd-go7007.o
19
20s2250-y := s2250-board.o
21
22# Uncomment when the saa7134 patches get into upstream
23#ifneq ($(CONFIG_VIDEO_SAA7134),)
24#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
25#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
26#endif
27
28# S2250 needs cypress ezusb loader from dvb-usb
29ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),)
30ccflags-y := -Idrivers/media/dvb/dvb-usb
31endif
32
33ccflags-y += -Idrivers/media/dvb/frontends
34ccflags-y += -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..6c9279a6d60
--- /dev/null
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -0,0 +1,659 @@
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/delay.h>
21#include <linux/sched.h>
22#include <linux/spinlock.h>
23#include <linux/unistd.h>
24#include <linux/time.h>
25#include <linux/mm.h>
26#include <linux/vmalloc.h>
27#include <linux/device.h>
28#include <linux/i2c.h>
29#include <linux/firmware.h>
30#include <linux/mutex.h>
31#include <linux/uaccess.h>
32#include <linux/slab.h>
33#include <asm/system.h>
34#include <linux/videodev2.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 v4l2_err(&go->v4l2_dev, "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 v4l2_err(go, "unable to load firmware from file "
102 "\"%s\"\n", fw_name);
103 return -1;
104 }
105 if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
106 v4l2_err(go, "file \"%s\" does not appear to be "
107 "go7007 firmware\n", fw_name);
108 release_firmware(fw_entry);
109 return -1;
110 }
111 fw_len = fw_entry->size - 16;
112 bounce = kmalloc(fw_len, GFP_KERNEL);
113 if (bounce == NULL) {
114 v4l2_err(go, "unable to allocate %d bytes for "
115 "firmware transfer\n", fw_len);
116 release_firmware(fw_entry);
117 return -1;
118 }
119 memcpy(bounce, fw_entry->data + 16, fw_len);
120 release_firmware(fw_entry);
121 if (go7007_interface_reset(go) < 0 ||
122 go7007_send_firmware(go, bounce, fw_len) < 0 ||
123 go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
124 (intr_val & ~0x1) != 0x5a5a) {
125 v4l2_err(go, "error transferring firmware\n");
126 rv = -1;
127 }
128 kfree(bounce);
129 return rv;
130}
131
132MODULE_FIRMWARE("go7007fw.bin");
133
134/*
135 * Boot the encoder and register the I2C adapter if requested. Do the
136 * minimum initialization necessary, since the board-specific code may
137 * still need to probe the board ID.
138 *
139 * Must NOT be called with the hw_lock held.
140 */
141int go7007_boot_encoder(struct go7007 *go, int init_i2c)
142{
143 int ret;
144
145 mutex_lock(&go->hw_lock);
146 ret = go7007_load_encoder(go);
147 mutex_unlock(&go->hw_lock);
148 if (ret < 0)
149 return -1;
150 if (!init_i2c)
151 return 0;
152 if (go7007_i2c_init(go) < 0)
153 return -1;
154 go->i2c_adapter_online = 1;
155 return 0;
156}
157EXPORT_SYMBOL(go7007_boot_encoder);
158
159/*
160 * Configure any hardware-related registers in the GO7007, such as GPIO
161 * pins and bus parameters, which are board-specific. This assumes
162 * the boot firmware has already been downloaded.
163 *
164 * Must be called with the hw_lock held.
165 */
166static int go7007_init_encoder(struct go7007 *go)
167{
168 if (go->board_info->audio_flags & GO7007_AUDIO_I2S_MASTER) {
169 go7007_write_addr(go, 0x1000, 0x0811);
170 go7007_write_addr(go, 0x1000, 0x0c11);
171 }
172 if (go->board_id == GO7007_BOARDID_MATRIX_REV) {
173 /* Set GPIO pin 0 to be an output (audio clock control) */
174 go7007_write_addr(go, 0x3c82, 0x0001);
175 go7007_write_addr(go, 0x3c80, 0x00fe);
176 }
177 return 0;
178}
179
180/*
181 * Send the boot firmware to the GO7007 and configure the registers. This
182 * is the only way to stop the encoder once it has started streaming video.
183 *
184 * Must be called with the hw_lock held.
185 */
186int go7007_reset_encoder(struct go7007 *go)
187{
188 if (go7007_load_encoder(go) < 0)
189 return -1;
190 return go7007_init_encoder(go);
191}
192
193/*
194 * Attempt to instantiate an I2C client by ID, probably loading a module.
195 */
196static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
197 int addr)
198{
199 struct go7007 *go = i2c_get_adapdata(adapter);
200 struct v4l2_device *v4l2_dev = &go->v4l2_dev;
201
202 if (v4l2_i2c_new_subdev(v4l2_dev, adapter, type, addr, NULL))
203 return 0;
204
205 printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", type);
206 return -1;
207}
208
209/*
210 * Finalize the GO7007 hardware setup, register the on-board I2C adapter
211 * (if used on this board), load the I2C client driver for the sensor
212 * (SAA7115 or whatever) and other devices, and register the ALSA and V4L2
213 * interfaces.
214 *
215 * Must NOT be called with the hw_lock held.
216 */
217int go7007_register_encoder(struct go7007 *go)
218{
219 int i, ret;
220
221 printk(KERN_INFO "go7007: registering new %s\n", go->name);
222
223 mutex_lock(&go->hw_lock);
224 ret = go7007_init_encoder(go);
225 mutex_unlock(&go->hw_lock);
226 if (ret < 0)
227 return -1;
228
229 /* v4l2 init must happen before i2c subdevs */
230 ret = go7007_v4l2_init(go);
231 if (ret < 0)
232 return ret;
233
234 if (!go->i2c_adapter_online &&
235 go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
236 if (go7007_i2c_init(go) < 0)
237 return -1;
238 go->i2c_adapter_online = 1;
239 }
240 if (go->i2c_adapter_online) {
241 for (i = 0; i < go->board_info->num_i2c_devs; ++i)
242 init_i2c_module(&go->i2c_adapter,
243 go->board_info->i2c_devs[i].type,
244 go->board_info->i2c_devs[i].addr);
245 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
246 i2c_clients_command(&go->i2c_adapter,
247 DECODER_SET_CHANNEL, &go->channel_number);
248 }
249 if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
250 go->audio_enabled = 1;
251 go7007_snd_init(go);
252 }
253 return 0;
254}
255EXPORT_SYMBOL(go7007_register_encoder);
256
257/*
258 * Send the encode firmware to the encoder, which will cause it
259 * to immediately start delivering the video and audio streams.
260 *
261 * Must be called with the hw_lock held.
262 */
263int go7007_start_encoder(struct go7007 *go)
264{
265 u8 *fw;
266 int fw_len, rv = 0, i;
267 u16 intr_val, intr_data;
268
269 go->modet_enable = 0;
270 if (!go->dvd_mode)
271 for (i = 0; i < 4; ++i) {
272 if (go->modet[i].enable) {
273 go->modet_enable = 1;
274 continue;
275 }
276 go->modet[i].pixel_threshold = 32767;
277 go->modet[i].motion_threshold = 32767;
278 go->modet[i].mb_threshold = 32767;
279 }
280
281 if (go7007_construct_fw_image(go, &fw, &fw_len) < 0)
282 return -1;
283
284 if (go7007_send_firmware(go, fw, fw_len) < 0 ||
285 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
286 v4l2_err(&go->v4l2_dev, "error transferring firmware\n");
287 rv = -1;
288 goto start_error;
289 }
290
291 go->state = STATE_DATA;
292 go->parse_length = 0;
293 go->seen_frame = 0;
294 if (go7007_stream_start(go) < 0) {
295 v4l2_err(&go->v4l2_dev, "error starting stream transfer\n");
296 rv = -1;
297 goto start_error;
298 }
299
300start_error:
301 kfree(fw);
302 return rv;
303}
304
305/*
306 * Store a byte in the current video buffer, if there is one.
307 */
308static inline void store_byte(struct go7007_buffer *gobuf, u8 byte)
309{
310 if (gobuf != NULL && gobuf->bytesused < GO7007_BUF_SIZE) {
311 unsigned int pgidx = gobuf->offset >> PAGE_SHIFT;
312 unsigned int pgoff = gobuf->offset & ~PAGE_MASK;
313
314 *((u8 *)page_address(gobuf->pages[pgidx]) + pgoff) = byte;
315 ++gobuf->offset;
316 ++gobuf->bytesused;
317 }
318}
319
320/*
321 * Deliver the last video buffer and get a new one to start writing to.
322 */
323static void frame_boundary(struct go7007 *go)
324{
325 struct go7007_buffer *gobuf;
326 int i;
327
328 if (go->active_buf) {
329 if (go->active_buf->modet_active) {
330 if (go->active_buf->bytesused + 216 < GO7007_BUF_SIZE) {
331 for (i = 0; i < 216; ++i)
332 store_byte(go->active_buf,
333 go->active_map[i]);
334 go->active_buf->bytesused -= 216;
335 } else
336 go->active_buf->modet_active = 0;
337 }
338 go->active_buf->state = BUF_STATE_DONE;
339 wake_up_interruptible(&go->frame_waitq);
340 go->active_buf = NULL;
341 }
342 list_for_each_entry(gobuf, &go->stream, stream)
343 if (gobuf->state == BUF_STATE_QUEUED) {
344 gobuf->seq = go->next_seq;
345 do_gettimeofday(&gobuf->timestamp);
346 go->active_buf = gobuf;
347 break;
348 }
349 ++go->next_seq;
350}
351
352static void write_bitmap_word(struct go7007 *go)
353{
354 int x, y, i, stride = ((go->width >> 4) + 7) >> 3;
355
356 for (i = 0; i < 16; ++i) {
357 y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4);
358 x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4);
359 if (stride * y + (x >> 3) < sizeof(go->active_map))
360 go->active_map[stride * y + (x >> 3)] |=
361 (go->modet_word & 1) << (x & 0x7);
362 go->modet_word >>= 1;
363 }
364}
365
366/*
367 * Parse a chunk of the video stream into frames. The frames are not
368 * delimited by the hardware, so we have to parse the frame boundaries
369 * based on the type of video stream we're receiving.
370 */
371void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
372{
373 int i, seq_start_code = -1, frame_start_code = -1;
374
375 spin_lock(&go->spinlock);
376
377 switch (go->format) {
378 case GO7007_FORMAT_MPEG4:
379 seq_start_code = 0xB0;
380 frame_start_code = 0xB6;
381 break;
382 case GO7007_FORMAT_MPEG1:
383 case GO7007_FORMAT_MPEG2:
384 seq_start_code = 0xB3;
385 frame_start_code = 0x00;
386 break;
387 }
388
389 for (i = 0; i < length; ++i) {
390 if (go->active_buf != NULL &&
391 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
392 v4l2_info(&go->v4l2_dev, "dropping oversized frame\n");
393 go->active_buf->offset -= go->active_buf->bytesused;
394 go->active_buf->bytesused = 0;
395 go->active_buf->modet_active = 0;
396 go->active_buf = NULL;
397 }
398
399 switch (go->state) {
400 case STATE_DATA:
401 switch (buf[i]) {
402 case 0x00:
403 go->state = STATE_00;
404 break;
405 case 0xFF:
406 go->state = STATE_FF;
407 break;
408 default:
409 store_byte(go->active_buf, buf[i]);
410 break;
411 }
412 break;
413 case STATE_00:
414 switch (buf[i]) {
415 case 0x00:
416 go->state = STATE_00_00;
417 break;
418 case 0xFF:
419 store_byte(go->active_buf, 0x00);
420 go->state = STATE_FF;
421 break;
422 default:
423 store_byte(go->active_buf, 0x00);
424 store_byte(go->active_buf, buf[i]);
425 go->state = STATE_DATA;
426 break;
427 }
428 break;
429 case STATE_00_00:
430 switch (buf[i]) {
431 case 0x00:
432 store_byte(go->active_buf, 0x00);
433 /* go->state remains STATE_00_00 */
434 break;
435 case 0x01:
436 go->state = STATE_00_00_01;
437 break;
438 case 0xFF:
439 store_byte(go->active_buf, 0x00);
440 store_byte(go->active_buf, 0x00);
441 go->state = STATE_FF;
442 break;
443 default:
444 store_byte(go->active_buf, 0x00);
445 store_byte(go->active_buf, 0x00);
446 store_byte(go->active_buf, buf[i]);
447 go->state = STATE_DATA;
448 break;
449 }
450 break;
451 case STATE_00_00_01:
452 if (buf[i] == 0xF8 && go->modet_enable == 0) {
453 /* MODET start code, but MODET not enabled */
454 store_byte(go->active_buf, 0x00);
455 store_byte(go->active_buf, 0x00);
456 store_byte(go->active_buf, 0x01);
457 store_byte(go->active_buf, 0xF8);
458 go->state = STATE_DATA;
459 break;
460 }
461 /* If this is the start of a new MPEG frame,
462 * get a new buffer */
463 if ((go->format == GO7007_FORMAT_MPEG1 ||
464 go->format == GO7007_FORMAT_MPEG2 ||
465 go->format == GO7007_FORMAT_MPEG4) &&
466 (buf[i] == seq_start_code ||
467 buf[i] == 0xB8 || /* GOP code */
468 buf[i] == frame_start_code)) {
469 if (go->active_buf == NULL || go->seen_frame)
470 frame_boundary(go);
471 if (buf[i] == frame_start_code) {
472 if (go->active_buf != NULL)
473 go->active_buf->frame_offset =
474 go->active_buf->offset;
475 go->seen_frame = 1;
476 } else {
477 go->seen_frame = 0;
478 }
479 }
480 /* Handle any special chunk types, or just write the
481 * start code to the (potentially new) buffer */
482 switch (buf[i]) {
483 case 0xF5: /* timestamp */
484 go->parse_length = 12;
485 go->state = STATE_UNPARSED;
486 break;
487 case 0xF6: /* vbi */
488 go->state = STATE_VBI_LEN_A;
489 break;
490 case 0xF8: /* MD map */
491 go->parse_length = 0;
492 memset(go->active_map, 0,
493 sizeof(go->active_map));
494 go->state = STATE_MODET_MAP;
495 break;
496 case 0xFF: /* Potential JPEG start code */
497 store_byte(go->active_buf, 0x00);
498 store_byte(go->active_buf, 0x00);
499 store_byte(go->active_buf, 0x01);
500 go->state = STATE_FF;
501 break;
502 default:
503 store_byte(go->active_buf, 0x00);
504 store_byte(go->active_buf, 0x00);
505 store_byte(go->active_buf, 0x01);
506 store_byte(go->active_buf, buf[i]);
507 go->state = STATE_DATA;
508 break;
509 }
510 break;
511 case STATE_FF:
512 switch (buf[i]) {
513 case 0x00:
514 store_byte(go->active_buf, 0xFF);
515 go->state = STATE_00;
516 break;
517 case 0xFF:
518 store_byte(go->active_buf, 0xFF);
519 /* go->state remains STATE_FF */
520 break;
521 case 0xD8:
522 if (go->format == GO7007_FORMAT_MJPEG)
523 frame_boundary(go);
524 /* fall through */
525 default:
526 store_byte(go->active_buf, 0xFF);
527 store_byte(go->active_buf, buf[i]);
528 go->state = STATE_DATA;
529 break;
530 }
531 break;
532 case STATE_VBI_LEN_A:
533 go->parse_length = buf[i] << 8;
534 go->state = STATE_VBI_LEN_B;
535 break;
536 case STATE_VBI_LEN_B:
537 go->parse_length |= buf[i];
538 if (go->parse_length > 0)
539 go->state = STATE_UNPARSED;
540 else
541 go->state = STATE_DATA;
542 break;
543 case STATE_MODET_MAP:
544 if (go->parse_length < 204) {
545 if (go->parse_length & 1) {
546 go->modet_word |= buf[i];
547 write_bitmap_word(go);
548 } else
549 go->modet_word = buf[i] << 8;
550 } else if (go->parse_length == 207 && go->active_buf) {
551 go->active_buf->modet_active = buf[i];
552 }
553 if (++go->parse_length == 208)
554 go->state = STATE_DATA;
555 break;
556 case STATE_UNPARSED:
557 if (--go->parse_length == 0)
558 go->state = STATE_DATA;
559 break;
560 }
561 }
562
563 spin_unlock(&go->spinlock);
564}
565EXPORT_SYMBOL(go7007_parse_video_stream);
566
567/*
568 * Allocate a new go7007 struct. Used by the hardware-specific probe.
569 */
570struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
571{
572 struct go7007 *go;
573 int i;
574
575 go = kmalloc(sizeof(struct go7007), GFP_KERNEL);
576 if (go == NULL)
577 return NULL;
578 go->dev = dev;
579 go->board_info = board;
580 go->board_id = 0;
581 go->tuner_type = -1;
582 go->channel_number = 0;
583 go->name[0] = 0;
584 mutex_init(&go->hw_lock);
585 init_waitqueue_head(&go->frame_waitq);
586 spin_lock_init(&go->spinlock);
587 go->video_dev = NULL;
588 go->ref_count = 0;
589 go->status = STATUS_INIT;
590 memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
591 go->i2c_adapter_online = 0;
592 go->interrupt_available = 0;
593 init_waitqueue_head(&go->interrupt_waitq);
594 go->in_use = 0;
595 go->input = 0;
596 if (board->sensor_flags & GO7007_SENSOR_TV) {
597 go->standard = GO7007_STD_NTSC;
598 go->width = 720;
599 go->height = 480;
600 go->sensor_framerate = 30000;
601 } else {
602 go->standard = GO7007_STD_OTHER;
603 go->width = board->sensor_width;
604 go->height = board->sensor_height;
605 go->sensor_framerate = board->sensor_framerate;
606 }
607 go->encoder_v_offset = board->sensor_v_offset;
608 go->encoder_h_offset = board->sensor_h_offset;
609 go->encoder_h_halve = 0;
610 go->encoder_v_halve = 0;
611 go->encoder_subsample = 0;
612 go->streaming = 0;
613 go->format = GO7007_FORMAT_MJPEG;
614 go->bitrate = 1500000;
615 go->fps_scale = 1;
616 go->pali = 0;
617 go->aspect_ratio = GO7007_RATIO_1_1;
618 go->gop_size = 0;
619 go->ipb = 0;
620 go->closed_gop = 0;
621 go->repeat_seqhead = 0;
622 go->seq_header_enable = 0;
623 go->gop_header_enable = 0;
624 go->dvd_mode = 0;
625 go->interlace_coding = 0;
626 for (i = 0; i < 4; ++i)
627 go->modet[i].enable = 0;
628 for (i = 0; i < 1624; ++i)
629 go->modet_map[i] = 0;
630 go->audio_deliver = NULL;
631 go->audio_enabled = 0;
632 INIT_LIST_HEAD(&go->stream);
633
634 return go;
635}
636EXPORT_SYMBOL(go7007_alloc);
637
638/*
639 * Detach and unregister the encoder. The go7007 struct won't be freed
640 * until v4l2 finishes releasing its resources and all associated fds are
641 * closed by applications.
642 */
643void go7007_remove(struct go7007 *go)
644{
645 if (go->i2c_adapter_online) {
646 if (i2c_del_adapter(&go->i2c_adapter) == 0)
647 go->i2c_adapter_online = 0;
648 else
649 v4l2_err(&go->v4l2_dev,
650 "error removing I2C adapter!\n");
651 }
652
653 if (go->audio_enabled)
654 go7007_snd_remove(go);
655 go7007_v4l2_remove(go);
656}
657EXPORT_SYMBOL(go7007_remove);
658
659MODULE_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..c9a6409edfe
--- /dev/null
+++ b/drivers/staging/go7007/go7007-fw.c
@@ -0,0 +1,1636 @@
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/time.h>
30#include <linux/mm.h>
31#include <linux/device.h>
32#include <linux/i2c.h>
33#include <linux/firmware.h>
34#include <linux/slab.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(__le16 *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_le16p(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, __le16 *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 = kzalloc(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
390 for (i = 1; i < 32; ++i) {
391 mjpeg_frame_header(go, buf + size, i);
392 size += 80;
393 }
394 chunk = mjpeg_frame_header(go, buf + size, 1);
395 memmove(buf + size, buf + size + 80, chunk - 80);
396 size += chunk - 80;
397
398 for (i = 0; i < size; i += chunk * 2) {
399 if (space - off < 32) {
400 off = -1;
401 goto done;
402 }
403
404 code[off + 1] = __cpu_to_le16(0x8000 | mem);
405
406 chunk = 28;
407 if (mem + chunk > 0x4000)
408 chunk = 0x4000 - mem;
409 if (i + 2 * chunk > size)
410 chunk = (size - i) / 2;
411
412 if (chunk < 28) {
413 code[off] = __cpu_to_le16(0x4000 | chunk);
414 code[off + 31] = __cpu_to_le16(addr++);
415 mem = 0x3e00;
416 } else {
417 code[off] = __cpu_to_le16(0x1000 | 28);
418 code[off + 31] = 0;
419 mem += 28;
420 }
421
422 memcpy(&code[off + 2], buf + i, chunk * 2);
423 off += 32;
424 }
425done:
426 kfree(buf);
427 return off;
428}
429
430static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
431 int modulo, int pict_struct, enum mpeg_frame_type frame)
432{
433 int i, j, mb_code, mb_len;
434 int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
435 CODE_GEN(c, buf + 6);
436
437 switch (frame) {
438 case PFRAME:
439 mb_code = 0x1;
440 mb_len = 3;
441 break;
442 case BFRAME_PRE:
443 mb_code = 0x2;
444 mb_len = 4;
445 break;
446 case BFRAME_POST:
447 mb_code = 0x2;
448 mb_len = 3;
449 break;
450 case BFRAME_BIDIR:
451 mb_code = 0x2;
452 mb_len = 2;
453 break;
454 default: /* keep the compiler happy */
455 mb_code = mb_len = 0;
456 break;
457 }
458
459 CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13);
460 CODE_ADD(c, 0xffff, 16);
461 CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
462 if (frame != PFRAME)
463 CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
464 else
465 CODE_ADD(c, 0, 4); /* Is this supposed to be here?? */
466 CODE_ADD(c, 0, 3); /* What is this?? */
467 /* Byte-align with zeros */
468 j = 8 - (CODE_LENGTH(c) % 8);
469 if (j != 8)
470 CODE_ADD(c, 0, j);
471
472 if (go->format == GO7007_FORMAT_MPEG2) {
473 CODE_ADD(c, 0x1, 24);
474 CODE_ADD(c, 0xb5, 8);
475 CODE_ADD(c, 0x844, 12);
476 CODE_ADD(c, frame == PFRAME ? 0xff : 0x44, 8);
477 if (go->interlace_coding) {
478 CODE_ADD(c, pict_struct, 4);
479 if (go->dvd_mode)
480 CODE_ADD(c, 0x000, 11);
481 else
482 CODE_ADD(c, 0x200, 11);
483 } else {
484 CODE_ADD(c, 0x3, 4);
485 CODE_ADD(c, 0x20c, 11);
486 }
487 /* Byte-align with zeros */
488 j = 8 - (CODE_LENGTH(c) % 8);
489 if (j != 8)
490 CODE_ADD(c, 0, j);
491 }
492
493 for (i = 0; i < rows; ++i) {
494 CODE_ADD(c, 1, 24);
495 CODE_ADD(c, i + 1, 8);
496 CODE_ADD(c, 0x2, 6);
497 CODE_ADD(c, 0x1, 1);
498 CODE_ADD(c, mb_code, mb_len);
499 if (go->interlace_coding) {
500 CODE_ADD(c, 0x1, 2);
501 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
502 }
503 if (frame == BFRAME_BIDIR) {
504 CODE_ADD(c, 0x3, 2);
505 if (go->interlace_coding)
506 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
507 }
508 CODE_ADD(c, 0x3, 2);
509 for (j = (go->width >> 4) - 2; j >= 33; j -= 33)
510 CODE_ADD(c, 0x8, 11);
511 CODE_ADD(c, addrinctab[j][0], addrinctab[j][1]);
512 CODE_ADD(c, mb_code, mb_len);
513 if (go->interlace_coding) {
514 CODE_ADD(c, 0x1, 2);
515 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
516 }
517 if (frame == BFRAME_BIDIR) {
518 CODE_ADD(c, 0x3, 2);
519 if (go->interlace_coding)
520 CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
521 }
522 CODE_ADD(c, 0x3, 2);
523
524 /* Byte-align with zeros */
525 j = 8 - (CODE_LENGTH(c) % 8);
526 if (j != 8)
527 CODE_ADD(c, 0, j);
528 }
529
530 i = CODE_LENGTH(c) + 4 * 8;
531 buf[2] = 0x00;
532 buf[3] = 0x00;
533 buf[4] = 0x01;
534 buf[5] = 0x00;
535 return i;
536}
537
538static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
539{
540 int i, aspect_ratio, picture_rate;
541 CODE_GEN(c, buf + 6);
542
543 if (go->format == GO7007_FORMAT_MPEG1) {
544 switch (go->aspect_ratio) {
545 case GO7007_RATIO_4_3:
546 aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
547 break;
548 case GO7007_RATIO_16_9:
549 aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
550 break;
551 default:
552 aspect_ratio = 1;
553 break;
554 }
555 } else {
556 switch (go->aspect_ratio) {
557 case GO7007_RATIO_4_3:
558 aspect_ratio = 2;
559 break;
560 case GO7007_RATIO_16_9:
561 aspect_ratio = 3;
562 break;
563 default:
564 aspect_ratio = 1;
565 break;
566 }
567 }
568 switch (go->sensor_framerate) {
569 case 24000:
570 picture_rate = 1;
571 break;
572 case 24024:
573 picture_rate = 2;
574 break;
575 case 25025:
576 picture_rate = go->interlace_coding ? 6 : 3;
577 break;
578 case 30000:
579 picture_rate = go->interlace_coding ? 7 : 4;
580 break;
581 case 30030:
582 picture_rate = go->interlace_coding ? 8 : 5;
583 break;
584 default:
585 picture_rate = 5; /* 30 fps seems like a reasonable default */
586 break;
587 }
588
589 CODE_ADD(c, go->width, 12);
590 CODE_ADD(c, go->height, 12);
591 CODE_ADD(c, aspect_ratio, 4);
592 CODE_ADD(c, picture_rate, 4);
593 CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 20000 : 0x3ffff, 18);
594 CODE_ADD(c, 1, 1);
595 CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 112 : 20, 10);
596 CODE_ADD(c, 0, 3);
597
598 /* Byte-align with zeros */
599 i = 8 - (CODE_LENGTH(c) % 8);
600 if (i != 8)
601 CODE_ADD(c, 0, i);
602
603 if (go->format == GO7007_FORMAT_MPEG2) {
604 CODE_ADD(c, 0x1, 24);
605 CODE_ADD(c, 0xb5, 8);
606 CODE_ADD(c, 0x148, 12);
607 if (go->interlace_coding)
608 CODE_ADD(c, 0x20001, 20);
609 else
610 CODE_ADD(c, 0xa0001, 20);
611 CODE_ADD(c, 0, 16);
612
613 /* Byte-align with zeros */
614 i = 8 - (CODE_LENGTH(c) % 8);
615 if (i != 8)
616 CODE_ADD(c, 0, i);
617
618 if (ext) {
619 CODE_ADD(c, 0x1, 24);
620 CODE_ADD(c, 0xb52, 12);
621 CODE_ADD(c, go->standard == GO7007_STD_NTSC ? 2 : 1, 3);
622 CODE_ADD(c, 0x105, 9);
623 CODE_ADD(c, 0x505, 16);
624 CODE_ADD(c, go->width, 14);
625 CODE_ADD(c, 1, 1);
626 CODE_ADD(c, go->height, 14);
627
628 /* Byte-align with zeros */
629 i = 8 - (CODE_LENGTH(c) % 8);
630 if (i != 8)
631 CODE_ADD(c, 0, i);
632 }
633 }
634
635 i = CODE_LENGTH(c) + 4 * 8;
636 buf[0] = i & 0xff;
637 buf[1] = i >> 8;
638 buf[2] = 0x00;
639 buf[3] = 0x00;
640 buf[4] = 0x01;
641 buf[5] = 0xb3;
642 return i;
643}
644
645static int gen_mpeg1hdr_to_package(struct go7007 *go,
646 __le16 *code, int space, int *framelen)
647{
648 u8 *buf;
649 u16 mem = 0x3e00;
650 unsigned int addr = 0x19;
651 int i, off = 0, chunk;
652
653 buf = kzalloc(5120, GFP_KERNEL);
654 if (buf == NULL) {
655 printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
656 "firmware construction\n");
657 return -1;
658 }
659 framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME);
660 if (go->interlace_coding)
661 framelen[0] += mpeg1_frame_header(go, buf + framelen[0] / 8,
662 0, 2, PFRAME);
663 buf[0] = framelen[0] & 0xff;
664 buf[1] = framelen[0] >> 8;
665 i = 368;
666 framelen[1] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_PRE);
667 if (go->interlace_coding)
668 framelen[1] += mpeg1_frame_header(go, buf + i + framelen[1] / 8,
669 0, 2, BFRAME_PRE);
670 buf[i] = framelen[1] & 0xff;
671 buf[i + 1] = framelen[1] >> 8;
672 i += 1632;
673 framelen[2] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_POST);
674 if (go->interlace_coding)
675 framelen[2] += mpeg1_frame_header(go, buf + i + framelen[2] / 8,
676 0, 2, BFRAME_POST);
677 buf[i] = framelen[2] & 0xff;
678 buf[i + 1] = framelen[2] >> 8;
679 i += 1432;
680 framelen[3] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_BIDIR);
681 if (go->interlace_coding)
682 framelen[3] += mpeg1_frame_header(go, buf + i + framelen[3] / 8,
683 0, 2, BFRAME_BIDIR);
684 buf[i] = framelen[3] & 0xff;
685 buf[i + 1] = framelen[3] >> 8;
686 i += 1632 + 16;
687 mpeg1_sequence_header(go, buf + i, 0);
688 i += 40;
689 for (i = 0; i < 5120; i += chunk * 2) {
690 if (space - off < 32) {
691 off = -1;
692 goto done;
693 }
694
695 code[off + 1] = __cpu_to_le16(0x8000 | mem);
696
697 chunk = 28;
698 if (mem + chunk > 0x4000)
699 chunk = 0x4000 - mem;
700 if (i + 2 * chunk > 5120)
701 chunk = (5120 - i) / 2;
702
703 if (chunk < 28) {
704 code[off] = __cpu_to_le16(0x4000 | chunk);
705 code[off + 31] = __cpu_to_le16(addr);
706 if (mem + chunk == 0x4000) {
707 mem = 0x3e00;
708 ++addr;
709 }
710 } else {
711 code[off] = __cpu_to_le16(0x1000 | 28);
712 code[off + 31] = 0;
713 mem += 28;
714 }
715
716 memcpy(&code[off + 2], buf + i, chunk * 2);
717 off += 32;
718 }
719done:
720 kfree(buf);
721 return off;
722}
723
724static int vti_bitlen(struct go7007 *go)
725{
726 unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
727
728 for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i);
729 return i + 1;
730}
731
732static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
733 int modulo, enum mpeg_frame_type frame)
734{
735 int i;
736 CODE_GEN(c, buf + 6);
737 int mb_count = (go->width >> 4) * (go->height >> 4);
738
739 CODE_ADD(c, frame == PFRAME ? 0x1 : 0x2, 2);
740 if (modulo)
741 CODE_ADD(c, 0x1, 1);
742 CODE_ADD(c, 0x1, 2);
743 CODE_ADD(c, 0, vti_bitlen(go));
744 CODE_ADD(c, 0x3, 2);
745 if (frame == PFRAME)
746 CODE_ADD(c, 0, 1);
747 CODE_ADD(c, 0xc, 11);
748 if (frame != PFRAME)
749 CODE_ADD(c, 0x4, 3);
750 if (frame != BFRAME_EMPTY) {
751 for (i = 0; i < mb_count; ++i) {
752 switch (frame) {
753 case PFRAME:
754 CODE_ADD(c, 0x1, 1);
755 break;
756 case BFRAME_PRE:
757 CODE_ADD(c, 0x47, 8);
758 break;
759 case BFRAME_POST:
760 CODE_ADD(c, 0x27, 7);
761 break;
762 case BFRAME_BIDIR:
763 CODE_ADD(c, 0x5f, 8);
764 break;
765 case BFRAME_EMPTY: /* keep compiler quiet */
766 break;
767 }
768 }
769 }
770
771 /* Byte-align with a zero followed by ones */
772 i = 8 - (CODE_LENGTH(c) % 8);
773 CODE_ADD(c, 0, 1);
774 CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
775
776 i = CODE_LENGTH(c) + 4 * 8;
777 buf[0] = i & 0xff;
778 buf[1] = i >> 8;
779 buf[2] = 0x00;
780 buf[3] = 0x00;
781 buf[4] = 0x01;
782 buf[5] = 0xb6;
783 return i;
784}
785
786static int mpeg4_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
787{
788 const unsigned char head[] = { 0x00, 0x00, 0x01, 0xb0, go->pali,
789 0x00, 0x00, 0x01, 0xb5, 0x09,
790 0x00, 0x00, 0x01, 0x00,
791 0x00, 0x00, 0x01, 0x20, };
792 int i, aspect_ratio;
793 int fps = go->sensor_framerate / go->fps_scale;
794 CODE_GEN(c, buf + 2 + sizeof(head));
795
796 switch (go->aspect_ratio) {
797 case GO7007_RATIO_4_3:
798 aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
799 break;
800 case GO7007_RATIO_16_9:
801 aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
802 break;
803 default:
804 aspect_ratio = 1;
805 break;
806 }
807
808 memcpy(buf + 2, head, sizeof(head));
809 CODE_ADD(c, 0x191, 17);
810 CODE_ADD(c, aspect_ratio, 4);
811 CODE_ADD(c, 0x1, 4);
812 CODE_ADD(c, fps, 16);
813 CODE_ADD(c, 0x3, 2);
814 CODE_ADD(c, 1001, vti_bitlen(go));
815 CODE_ADD(c, 1, 1);
816 CODE_ADD(c, go->width, 13);
817 CODE_ADD(c, 1, 1);
818 CODE_ADD(c, go->height, 13);
819 CODE_ADD(c, 0x2830, 14);
820
821 /* Byte-align */
822 i = 8 - (CODE_LENGTH(c) % 8);
823 CODE_ADD(c, 0, 1);
824 CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
825
826 i = CODE_LENGTH(c) + sizeof(head) * 8;
827 buf[0] = i & 0xff;
828 buf[1] = i >> 8;
829 return i;
830}
831
832static int gen_mpeg4hdr_to_package(struct go7007 *go,
833 __le16 *code, int space, int *framelen)
834{
835 u8 *buf;
836 u16 mem = 0x3e00;
837 unsigned int addr = 0x19;
838 int i, off = 0, chunk;
839
840 buf = kzalloc(5120, GFP_KERNEL);
841 if (buf == NULL) {
842 printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
843 "firmware construction\n");
844 return -1;
845 }
846 framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME);
847 i = 368;
848 framelen[1] = mpeg4_frame_header(go, buf + i, 0, BFRAME_PRE);
849 i += 1632;
850 framelen[2] = mpeg4_frame_header(go, buf + i, 0, BFRAME_POST);
851 i += 1432;
852 framelen[3] = mpeg4_frame_header(go, buf + i, 0, BFRAME_BIDIR);
853 i += 1632;
854 mpeg4_frame_header(go, buf + i, 0, BFRAME_EMPTY);
855 i += 16;
856 mpeg4_sequence_header(go, buf + i, 0);
857 i += 40;
858 for (i = 0; i < 5120; i += chunk * 2) {
859 if (space - off < 32) {
860 off = -1;
861 goto done;
862 }
863
864 code[off + 1] = __cpu_to_le16(0x8000 | mem);
865
866 chunk = 28;
867 if (mem + chunk > 0x4000)
868 chunk = 0x4000 - mem;
869 if (i + 2 * chunk > 5120)
870 chunk = (5120 - i) / 2;
871
872 if (chunk < 28) {
873 code[off] = __cpu_to_le16(0x4000 | chunk);
874 code[off + 31] = __cpu_to_le16(addr);
875 if (mem + chunk == 0x4000) {
876 mem = 0x3e00;
877 ++addr;
878 }
879 } else {
880 code[off] = __cpu_to_le16(0x1000 | 28);
881 code[off + 31] = 0;
882 mem += 28;
883 }
884
885 memcpy(&code[off + 2], buf + i, chunk * 2);
886 off += 32;
887 }
888 mem = 0x3e00;
889 addr = go->ipb ? 0x14f9 : 0x0af9;
890 memset(buf, 0, 5120);
891 framelen[4] = mpeg4_frame_header(go, buf, 1, PFRAME);
892 i = 368;
893 framelen[5] = mpeg4_frame_header(go, buf + i, 1, BFRAME_PRE);
894 i += 1632;
895 framelen[6] = mpeg4_frame_header(go, buf + i, 1, BFRAME_POST);
896 i += 1432;
897 framelen[7] = mpeg4_frame_header(go, buf + i, 1, BFRAME_BIDIR);
898 i += 1632;
899 mpeg4_frame_header(go, buf + i, 1, BFRAME_EMPTY);
900 i += 16;
901 for (i = 0; i < 5120; i += chunk * 2) {
902 if (space - off < 32) {
903 off = -1;
904 goto done;
905 }
906
907 code[off + 1] = __cpu_to_le16(0x8000 | mem);
908
909 chunk = 28;
910 if (mem + chunk > 0x4000)
911 chunk = 0x4000 - mem;
912 if (i + 2 * chunk > 5120)
913 chunk = (5120 - i) / 2;
914
915 if (chunk < 28) {
916 code[off] = __cpu_to_le16(0x4000 | chunk);
917 code[off + 31] = __cpu_to_le16(addr);
918 if (mem + chunk == 0x4000) {
919 mem = 0x3e00;
920 ++addr;
921 }
922 } else {
923 code[off] = __cpu_to_le16(0x1000 | 28);
924 code[off + 31] = 0;
925 mem += 28;
926 }
927
928 memcpy(&code[off + 2], buf + i, chunk * 2);
929 off += 32;
930 }
931done:
932 kfree(buf);
933 return off;
934}
935
936static int brctrl_to_package(struct go7007 *go,
937 __le16 *code, int space, int *framelen)
938{
939 int converge_speed = 0;
940 int lambda = (go->format == GO7007_FORMAT_MJPEG || go->dvd_mode) ?
941 100 : 0;
942 int peak_rate = 6 * go->bitrate / 5;
943 int vbv_buffer = go->format == GO7007_FORMAT_MJPEG ?
944 go->bitrate :
945 (go->dvd_mode ? 900000 : peak_rate);
946 int fps = go->sensor_framerate / go->fps_scale;
947 int q = 0;
948 /* Bizarre math below depends on rounding errors in division */
949 u32 sgop_expt_addr = go->bitrate / 32 * (go->ipb ? 3 : 1) * 1001 / fps;
950 u32 sgop_peak_addr = peak_rate / 32 * 1001 / fps;
951 u32 total_expt_addr = go->bitrate / 32 * 1000 / fps * (fps / 1000);
952 u32 vbv_alert_addr = vbv_buffer * 3 / (4 * 32);
953 u32 cplx[] = {
954 q > 0 ? sgop_expt_addr * q :
955 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
956 q > 0 ? sgop_expt_addr * q :
957 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
958 q > 0 ? sgop_expt_addr * q :
959 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
960 q > 0 ? sgop_expt_addr * q :
961 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
962 };
963 u32 calc_q = q > 0 ? q : cplx[0] / sgop_expt_addr;
964 u16 pack[] = {
965 0x200e, 0x0000,
966 0xBF20, go->ipb ? converge_speed_ipb[converge_speed]
967 : converge_speed_ip[converge_speed],
968 0xBF21, go->ipb ? 2 : 0,
969 0xBF22, go->ipb ? LAMBDA_table[0][lambda / 2 + 50]
970 : 32767,
971 0xBF23, go->ipb ? LAMBDA_table[1][lambda] : 32767,
972 0xBF24, 32767,
973 0xBF25, lambda > 99 ? 32767 : LAMBDA_table[3][lambda],
974 0xBF26, sgop_expt_addr & 0x0000FFFF,
975 0xBF27, sgop_expt_addr >> 16,
976 0xBF28, sgop_peak_addr & 0x0000FFFF,
977 0xBF29, sgop_peak_addr >> 16,
978 0xBF2A, vbv_alert_addr & 0x0000FFFF,
979 0xBF2B, vbv_alert_addr >> 16,
980 0xBF2C, 0,
981 0xBF2D, 0,
982 0, 0,
983
984 0x200e, 0x0000,
985 0xBF2E, vbv_alert_addr & 0x0000FFFF,
986 0xBF2F, vbv_alert_addr >> 16,
987 0xBF30, cplx[0] & 0x0000FFFF,
988 0xBF31, cplx[0] >> 16,
989 0xBF32, cplx[1] & 0x0000FFFF,
990 0xBF33, cplx[1] >> 16,
991 0xBF34, cplx[2] & 0x0000FFFF,
992 0xBF35, cplx[2] >> 16,
993 0xBF36, cplx[3] & 0x0000FFFF,
994 0xBF37, cplx[3] >> 16,
995 0xBF38, 0,
996 0xBF39, 0,
997 0xBF3A, total_expt_addr & 0x0000FFFF,
998 0xBF3B, total_expt_addr >> 16,
999 0, 0,
1000
1001 0x200e, 0x0000,
1002 0xBF3C, total_expt_addr & 0x0000FFFF,
1003 0xBF3D, total_expt_addr >> 16,
1004 0xBF3E, 0,
1005 0xBF3F, 0,
1006 0xBF48, 0,
1007 0xBF49, 0,
1008 0xBF4A, calc_q < 4 ? 4 : (calc_q > 124 ? 124 : calc_q),
1009 0xBF4B, 4,
1010 0xBF4C, 0,
1011 0xBF4D, 0,
1012 0xBF4E, 0,
1013 0xBF4F, 0,
1014 0xBF50, 0,
1015 0xBF51, 0,
1016 0, 0,
1017
1018 0x200e, 0x0000,
1019 0xBF40, sgop_expt_addr & 0x0000FFFF,
1020 0xBF41, sgop_expt_addr >> 16,
1021 0xBF42, 0,
1022 0xBF43, 0,
1023 0xBF44, 0,
1024 0xBF45, 0,
1025 0xBF46, (go->width >> 4) * (go->height >> 4),
1026 0xBF47, 0,
1027 0xBF64, 0,
1028 0xBF65, 0,
1029 0xBF18, framelen[4],
1030 0xBF19, framelen[5],
1031 0xBF1A, framelen[6],
1032 0xBF1B, framelen[7],
1033 0, 0,
1034
1035#if 0
1036 /* Remove once we don't care about matching */
1037 0x200e, 0x0000,
1038 0xBF56, 4,
1039 0xBF57, 0,
1040 0xBF58, 5,
1041 0xBF59, 0,
1042 0xBF5A, 6,
1043 0xBF5B, 0,
1044 0xBF5C, 8,
1045 0xBF5D, 0,
1046 0xBF5E, 1,
1047 0xBF5F, 0,
1048 0xBF60, 1,
1049 0xBF61, 0,
1050 0xBF62, 0,
1051 0xBF63, 0,
1052 0, 0,
1053#else
1054 0x2008, 0x0000,
1055 0xBF56, 4,
1056 0xBF57, 0,
1057 0xBF58, 5,
1058 0xBF59, 0,
1059 0xBF5A, 6,
1060 0xBF5B, 0,
1061 0xBF5C, 8,
1062 0xBF5D, 0,
1063 0, 0,
1064 0, 0,
1065 0, 0,
1066 0, 0,
1067 0, 0,
1068 0, 0,
1069 0, 0,
1070#endif
1071
1072 0x200e, 0x0000,
1073 0xBF10, 0,
1074 0xBF11, 0,
1075 0xBF12, 0,
1076 0xBF13, 0,
1077 0xBF14, 0,
1078 0xBF15, 0,
1079 0xBF16, 0,
1080 0xBF17, 0,
1081 0xBF7E, 0,
1082 0xBF7F, 1,
1083 0xBF52, framelen[0],
1084 0xBF53, framelen[1],
1085 0xBF54, framelen[2],
1086 0xBF55, framelen[3],
1087 0, 0,
1088 };
1089
1090 return copy_packages(code, pack, 6, space);
1091}
1092
1093static int config_package(struct go7007 *go, __le16 *code, int space)
1094{
1095 int fps = go->sensor_framerate / go->fps_scale / 1000;
1096 int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
1097 int brc_window_size = fps;
1098 int q_min = 2, q_max = 31;
1099 int THACCoeffSet0 = 0;
1100 u16 pack[] = {
1101 0x200e, 0x0000,
1102 0xc002, 0x14b4,
1103 0xc003, 0x28b4,
1104 0xc004, 0x3c5a,
1105 0xdc05, 0x2a77,
1106 0xc6c3, go->format == GO7007_FORMAT_MPEG4 ? 0 :
1107 (go->format == GO7007_FORMAT_H263 ? 0 : 1),
1108 0xc680, go->format == GO7007_FORMAT_MPEG4 ? 0xf1 :
1109 (go->format == GO7007_FORMAT_H263 ? 0x61 :
1110 0xd3),
1111 0xc780, 0x0140,
1112 0xe009, 0x0001,
1113 0xc60f, 0x0008,
1114 0xd4ff, 0x0002,
1115 0xe403, 2340,
1116 0xe406, 75,
1117 0xd411, 0x0001,
1118 0xd410, 0xa1d6,
1119 0x0001, 0x2801,
1120
1121 0x200d, 0x0000,
1122 0xe402, 0x018b,
1123 0xe401, 0x8b01,
1124 0xd472, (go->board_info->sensor_flags &
1125 GO7007_SENSOR_TV) &&
1126 (!go->interlace_coding) ?
1127 0x01b0 : 0x0170,
1128 0xd475, (go->board_info->sensor_flags &
1129 GO7007_SENSOR_TV) &&
1130 (!go->interlace_coding) ?
1131 0x0008 : 0x0009,
1132 0xc404, go->interlace_coding ? 0x44 :
1133 (go->format == GO7007_FORMAT_MPEG4 ? 0x11 :
1134 (go->format == GO7007_FORMAT_MPEG1 ? 0x02 :
1135 (go->format == GO7007_FORMAT_MPEG2 ? 0x04 :
1136 (go->format == GO7007_FORMAT_H263 ? 0x08 :
1137 0x20)))),
1138 0xbf0a, (go->format == GO7007_FORMAT_MPEG4 ? 8 :
1139 (go->format == GO7007_FORMAT_MPEG1 ? 1 :
1140 (go->format == GO7007_FORMAT_MPEG2 ? 2 :
1141 (go->format == GO7007_FORMAT_H263 ? 4 : 16)))) |
1142 ((go->repeat_seqhead ? 1 : 0) << 6) |
1143 ((go->dvd_mode ? 1 : 0) << 9) |
1144 ((go->gop_header_enable ? 1 : 0) << 10),
1145 0xbf0b, 0,
1146 0xdd5a, go->ipb ? 0x14 : 0x0a,
1147 0xbf0c, 0,
1148 0xbf0d, 0,
1149 0xc683, THACCoeffSet0,
1150 0xc40a, (go->width << 4) | rows,
1151 0xe01a, go->board_info->hpi_buffer_cap,
1152 0, 0,
1153 0, 0,
1154
1155 0x2008, 0,
1156 0xe402, 0x88,
1157 0xe401, 0x8f01,
1158 0xbf6a, 0,
1159 0xbf6b, 0,
1160 0xbf6c, 0,
1161 0xbf6d, 0,
1162 0xbf6e, 0,
1163 0xbf6f, 0,
1164 0, 0,
1165 0, 0,
1166 0, 0,
1167 0, 0,
1168 0, 0,
1169 0, 0,
1170 0, 0,
1171
1172 0x200e, 0,
1173 0xbf66, brc_window_size,
1174 0xbf67, 0,
1175 0xbf68, q_min,
1176 0xbf69, q_max,
1177 0xbfe0, 0,
1178 0xbfe1, 0,
1179 0xbfe2, 0,
1180 0xbfe3, go->ipb ? 3 : 1,
1181 0xc031, go->board_info->sensor_flags &
1182 GO7007_SENSOR_VBI ? 1 : 0,
1183 0xc01c, 0x1f,
1184 0xdd8c, 0x15,
1185 0xdd94, 0x15,
1186 0xdd88, go->ipb ? 0x1401 : 0x0a01,
1187 0xdd90, go->ipb ? 0x1401 : 0x0a01,
1188 0, 0,
1189
1190 0x200e, 0,
1191 0xbfe4, 0,
1192 0xbfe5, 0,
1193 0xbfe6, 0,
1194 0xbfe7, fps << 8,
1195 0xbfe8, 0x3a00,
1196 0xbfe9, 0,
1197 0xbfea, 0,
1198 0xbfeb, 0,
1199 0xbfec, (go->interlace_coding ? 1 << 15 : 0) |
1200 (go->modet_enable ? 0xa : 0) |
1201 (go->board_info->sensor_flags &
1202 GO7007_SENSOR_VBI ? 1 : 0),
1203 0xbfed, 0,
1204 0xbfee, 0,
1205 0xbfef, 0,
1206 0xbff0, go->board_info->sensor_flags &
1207 GO7007_SENSOR_TV ? 0xf060 : 0xb060,
1208 0xbff1, 0,
1209 0, 0,
1210 };
1211
1212 return copy_packages(code, pack, 5, space);
1213}
1214
1215static int seqhead_to_package(struct go7007 *go, __le16 *code, int space,
1216 int (*sequence_header_func)(struct go7007 *go,
1217 unsigned char *buf, int ext))
1218{
1219 int vop_time_increment_bitlength = vti_bitlen(go);
1220 int fps = go->sensor_framerate / go->fps_scale *
1221 (go->interlace_coding ? 2 : 1);
1222 unsigned char buf[40] = { };
1223 int len = sequence_header_func(go, buf, 1);
1224 u16 pack[] = {
1225 0x2006, 0,
1226 0xbf08, fps,
1227 0xbf09, 0,
1228 0xbff2, vop_time_increment_bitlength,
1229 0xbff3, (1 << vop_time_increment_bitlength) - 1,
1230 0xbfe6, 0,
1231 0xbfe7, (fps / 1000) << 8,
1232 0, 0,
1233 0, 0,
1234 0, 0,
1235 0, 0,
1236 0, 0,
1237 0, 0,
1238 0, 0,
1239 0, 0,
1240 0, 0,
1241
1242 0x2007, 0,
1243 0xc800, buf[2] << 8 | buf[3],
1244 0xc801, buf[4] << 8 | buf[5],
1245 0xc802, buf[6] << 8 | buf[7],
1246 0xc803, buf[8] << 8 | buf[9],
1247 0xc406, 64,
1248 0xc407, len - 64,
1249 0xc61b, 1,
1250 0, 0,
1251 0, 0,
1252 0, 0,
1253 0, 0,
1254 0, 0,
1255 0, 0,
1256 0, 0,
1257 0, 0,
1258
1259 0x200e, 0,
1260 0xc808, buf[10] << 8 | buf[11],
1261 0xc809, buf[12] << 8 | buf[13],
1262 0xc80a, buf[14] << 8 | buf[15],
1263 0xc80b, buf[16] << 8 | buf[17],
1264 0xc80c, buf[18] << 8 | buf[19],
1265 0xc80d, buf[20] << 8 | buf[21],
1266 0xc80e, buf[22] << 8 | buf[23],
1267 0xc80f, buf[24] << 8 | buf[25],
1268 0xc810, buf[26] << 8 | buf[27],
1269 0xc811, buf[28] << 8 | buf[29],
1270 0xc812, buf[30] << 8 | buf[31],
1271 0xc813, buf[32] << 8 | buf[33],
1272 0xc814, buf[34] << 8 | buf[35],
1273 0xc815, buf[36] << 8 | buf[37],
1274 0, 0,
1275 0, 0,
1276 0, 0,
1277 };
1278
1279 return copy_packages(code, pack, 3, space);
1280}
1281
1282static int relative_prime(int big, int little)
1283{
1284 int remainder;
1285
1286 while (little != 0) {
1287 remainder = big % little;
1288 big = little;
1289 little = remainder;
1290 }
1291 return big;
1292}
1293
1294static int avsync_to_package(struct go7007 *go, __le16 *code, int space)
1295{
1296 int arate = go->board_info->audio_rate * 1001 * go->fps_scale;
1297 int ratio = arate / go->sensor_framerate;
1298 int adjratio = ratio * 215 / 100;
1299 int rprime = relative_prime(go->sensor_framerate,
1300 arate % go->sensor_framerate);
1301 int f1 = (arate % go->sensor_framerate) / rprime;
1302 int f2 = (go->sensor_framerate - arate % go->sensor_framerate) / rprime;
1303 u16 pack[] = {
1304 0x200e, 0,
1305 0xbf98, (u16)((-adjratio) & 0xffff),
1306 0xbf99, (u16)((-adjratio) >> 16),
1307 0xbf92, 0,
1308 0xbf93, 0,
1309 0xbff4, f1 > f2 ? f1 : f2,
1310 0xbff5, f1 < f2 ? f1 : f2,
1311 0xbff6, f1 < f2 ? ratio : ratio + 1,
1312 0xbff7, f1 > f2 ? ratio : ratio + 1,
1313 0xbff8, 0,
1314 0xbff9, 0,
1315 0xbffa, adjratio & 0xffff,
1316 0xbffb, adjratio >> 16,
1317 0xbf94, 0,
1318 0xbf95, 0,
1319 0, 0,
1320 };
1321
1322 return copy_packages(code, pack, 1, space);
1323}
1324
1325static int final_package(struct go7007 *go, __le16 *code, int space)
1326{
1327 int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
1328 u16 pack[] = {
1329 0x8000,
1330 0,
1331 0,
1332 0,
1333 0,
1334 0,
1335 0,
1336 2,
1337 ((go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
1338 (!go->interlace_coding) ?
1339 (1 << 14) | (1 << 9) : 0) |
1340 ((go->encoder_subsample ? 1 : 0) << 8) |
1341 (go->board_info->sensor_flags &
1342 GO7007_SENSOR_CONFIG_MASK),
1343 ((go->encoder_v_halve ? 1 : 0) << 14) |
1344 (go->encoder_v_halve ? rows << 9 : rows << 8) |
1345 (go->encoder_h_halve ? 1 << 6 : 0) |
1346 (go->encoder_h_halve ? go->width >> 3 : go->width >> 4),
1347 (1 << 15) | (go->encoder_v_offset << 6) |
1348 (1 << 7) | (go->encoder_h_offset >> 2),
1349 (1 << 6),
1350 0,
1351 0,
1352 ((go->fps_scale - 1) << 8) |
1353 (go->board_info->sensor_flags & GO7007_SENSOR_TV ?
1354 (1 << 7) : 0) |
1355 0x41,
1356 go->ipb ? 0xd4c : 0x36b,
1357 (rows << 8) | (go->width >> 4),
1358 go->format == GO7007_FORMAT_MPEG4 ? 0x0404 : 0,
1359 (1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) |
1360 ((go->closed_gop ? 1 : 0) << 12) |
1361 ((go->format == GO7007_FORMAT_MPEG4 ? 1 : 0) << 11) |
1362 /* (1 << 9) | */
1363 ((go->ipb ? 3 : 0) << 7) |
1364 ((go->modet_enable ? 1 : 0) << 2) |
1365 ((go->dvd_mode ? 1 : 0) << 1) | 1,
1366 (go->format == GO7007_FORMAT_MPEG1 ? 0x89a0 :
1367 (go->format == GO7007_FORMAT_MPEG2 ? 0x89a0 :
1368 (go->format == GO7007_FORMAT_MJPEG ? 0x89a0 :
1369 (go->format == GO7007_FORMAT_MPEG4 ? 0x8920 :
1370 (go->format == GO7007_FORMAT_H263 ? 0x8920 : 0))))),
1371 go->ipb ? 0x1f15 : 0x1f0b,
1372 go->ipb ? 0x0015 : 0x000b,
1373 go->ipb ? 0xa800 : 0x5800,
1374 0xffff,
1375 0x0020 + 0x034b * 0,
1376 0x0020 + 0x034b * 1,
1377 0x0020 + 0x034b * 2,
1378 0x0020 + 0x034b * 3,
1379 0x0020 + 0x034b * 4,
1380 0x0020 + 0x034b * 5,
1381 go->ipb ? (go->gop_size / 3) : go->gop_size,
1382 (go->height >> 4) * (go->width >> 4) * 110 / 100,
1383 };
1384
1385 return copy_packages(code, pack, 1, space);
1386}
1387
1388static int audio_to_package(struct go7007 *go, __le16 *code, int space)
1389{
1390 int clock_config = ((go->board_info->audio_flags &
1391 GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) |
1392 ((go->board_info->audio_flags &
1393 GO7007_AUDIO_OKI_MODE ? 1 : 0) << 8) |
1394 (((go->board_info->audio_bclk_div / 4) - 1) << 4) |
1395 (go->board_info->audio_main_div - 1);
1396 u16 pack[] = {
1397 0x200d, 0,
1398 0x9002, 0,
1399 0x9002, 0,
1400 0x9031, 0,
1401 0x9032, 0,
1402 0x9033, 0,
1403 0x9034, 0,
1404 0x9035, 0,
1405 0x9036, 0,
1406 0x9037, 0,
1407 0x9040, 0,
1408 0x9000, clock_config,
1409 0x9001, (go->board_info->audio_flags & 0xffff) |
1410 (1 << 9),
1411 0x9000, ((go->board_info->audio_flags &
1412 GO7007_AUDIO_I2S_MASTER ?
1413 1 : 0) << 10) |
1414 clock_config,
1415 0, 0,
1416 0, 0,
1417 0x2005, 0,
1418 0x9041, 0,
1419 0x9042, 256,
1420 0x9043, 0,
1421 0x9044, 16,
1422 0x9045, 16,
1423 0, 0,
1424 0, 0,
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 };
1434
1435 return copy_packages(code, pack, 2, space);
1436}
1437
1438static int modet_to_package(struct go7007 *go, __le16 *code, int space)
1439{
1440 int ret, mb, i, addr, cnt = 0;
1441 u16 pack[32];
1442 u16 thresholds[] = {
1443 0x200e, 0,
1444 0xbf82, go->modet[0].pixel_threshold,
1445 0xbf83, go->modet[1].pixel_threshold,
1446 0xbf84, go->modet[2].pixel_threshold,
1447 0xbf85, go->modet[3].pixel_threshold,
1448 0xbf86, go->modet[0].motion_threshold,
1449 0xbf87, go->modet[1].motion_threshold,
1450 0xbf88, go->modet[2].motion_threshold,
1451 0xbf89, go->modet[3].motion_threshold,
1452 0xbf8a, go->modet[0].mb_threshold,
1453 0xbf8b, go->modet[1].mb_threshold,
1454 0xbf8c, go->modet[2].mb_threshold,
1455 0xbf8d, go->modet[3].mb_threshold,
1456 0xbf8e, 0,
1457 0xbf8f, 0,
1458 0, 0,
1459 };
1460
1461 ret = copy_packages(code, thresholds, 1, space);
1462 if (ret < 0)
1463 return -1;
1464 cnt += ret;
1465
1466 addr = 0xbac0;
1467 memset(pack, 0, 64);
1468 i = 0;
1469 for (mb = 0; mb < 1624; ++mb) {
1470 pack[i * 2 + 3] <<= 2;
1471 pack[i * 2 + 3] |= go->modet_map[mb];
1472 if (mb % 8 != 7)
1473 continue;
1474 pack[i * 2 + 2] = addr++;
1475 ++i;
1476 if (i == 10 || mb == 1623) {
1477 pack[0] = 0x2000 | i;
1478 ret = copy_packages(code + cnt, pack, 1, space - cnt);
1479 if (ret < 0)
1480 return -1;
1481 cnt += ret;
1482 i = 0;
1483 memset(pack, 0, 64);
1484 }
1485 pack[i * 2 + 3] = 0;
1486 }
1487
1488 memset(pack, 0, 64);
1489 i = 0;
1490 for (addr = 0xbb90; addr < 0xbbfa; ++addr) {
1491 pack[i * 2 + 2] = addr;
1492 pack[i * 2 + 3] = 0;
1493 ++i;
1494 if (i == 10 || addr == 0xbbf9) {
1495 pack[0] = 0x2000 | i;
1496 ret = copy_packages(code + cnt, pack, 1, space - cnt);
1497 if (ret < 0)
1498 return -1;
1499 cnt += ret;
1500 i = 0;
1501 memset(pack, 0, 64);
1502 }
1503 }
1504 return cnt;
1505}
1506
1507static int do_special(struct go7007 *go, u16 type, __le16 *code, int space,
1508 int *framelen)
1509{
1510 switch (type) {
1511 case SPECIAL_FRM_HEAD:
1512 switch (go->format) {
1513 case GO7007_FORMAT_MJPEG:
1514 return gen_mjpeghdr_to_package(go, code, space);
1515 case GO7007_FORMAT_MPEG1:
1516 case GO7007_FORMAT_MPEG2:
1517 return gen_mpeg1hdr_to_package(go, code, space,
1518 framelen);
1519 case GO7007_FORMAT_MPEG4:
1520 return gen_mpeg4hdr_to_package(go, code, space,
1521 framelen);
1522 }
1523 case SPECIAL_BRC_CTRL:
1524 return brctrl_to_package(go, code, space, framelen);
1525 case SPECIAL_CONFIG:
1526 return config_package(go, code, space);
1527 case SPECIAL_SEQHEAD:
1528 switch (go->format) {
1529 case GO7007_FORMAT_MPEG1:
1530 case GO7007_FORMAT_MPEG2:
1531 return seqhead_to_package(go, code, space,
1532 mpeg1_sequence_header);
1533 case GO7007_FORMAT_MPEG4:
1534 return seqhead_to_package(go, code, space,
1535 mpeg4_sequence_header);
1536 default:
1537 return 0;
1538 }
1539 case SPECIAL_AV_SYNC:
1540 return avsync_to_package(go, code, space);
1541 case SPECIAL_FINAL:
1542 return final_package(go, code, space);
1543 case SPECIAL_AUDIO:
1544 return audio_to_package(go, code, space);
1545 case SPECIAL_MODET:
1546 return modet_to_package(go, code, space);
1547 }
1548 printk(KERN_ERR
1549 "go7007: firmware file contains unsupported feature %04x\n",
1550 type);
1551 return -1;
1552}
1553
1554int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
1555{
1556 const struct firmware *fw_entry;
1557 __le16 *code, *src;
1558 int framelen[8] = { }; /* holds the lengths of empty frame templates */
1559 int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags;
1560 int mode_flag;
1561 int ret;
1562
1563 switch (go->format) {
1564 case GO7007_FORMAT_MJPEG:
1565 mode_flag = FLAG_MODE_MJPEG;
1566 break;
1567 case GO7007_FORMAT_MPEG1:
1568 mode_flag = FLAG_MODE_MPEG1;
1569 break;
1570 case GO7007_FORMAT_MPEG2:
1571 mode_flag = FLAG_MODE_MPEG2;
1572 break;
1573 case GO7007_FORMAT_MPEG4:
1574 mode_flag = FLAG_MODE_MPEG4;
1575 break;
1576 default:
1577 return -1;
1578 }
1579 if (request_firmware(&fw_entry, go->board_info->firmware, go->dev)) {
1580 printk(KERN_ERR
1581 "go7007: unable to load firmware from file \"%s\"\n",
1582 go->board_info->firmware);
1583 return -1;
1584 }
1585 code = kzalloc(codespace * 2, GFP_KERNEL);
1586 if (code == NULL) {
1587 printk(KERN_ERR "go7007: unable to allocate %d bytes for "
1588 "firmware construction\n", codespace * 2);
1589 goto fw_failed;
1590 }
1591 src = (__le16 *)fw_entry->data;
1592 srclen = fw_entry->size / 2;
1593 while (srclen >= 2) {
1594 chunk_flags = __le16_to_cpu(src[0]);
1595 chunk_len = __le16_to_cpu(src[1]);
1596 if (chunk_len + 2 > srclen) {
1597 printk(KERN_ERR "go7007: firmware file \"%s\" "
1598 "appears to be corrupted\n",
1599 go->board_info->firmware);
1600 goto fw_failed;
1601 }
1602 if (chunk_flags & mode_flag) {
1603 if (chunk_flags & FLAG_SPECIAL) {
1604 ret = do_special(go, __le16_to_cpu(src[2]),
1605 &code[i], codespace - i, framelen);
1606 if (ret < 0) {
1607 printk(KERN_ERR "go7007: insufficient "
1608 "memory for firmware "
1609 "construction\n");
1610 goto fw_failed;
1611 }
1612 i += ret;
1613 } else {
1614 if (codespace - i < chunk_len) {
1615 printk(KERN_ERR "go7007: insufficient "
1616 "memory for firmware "
1617 "construction\n");
1618 goto fw_failed;
1619 }
1620 memcpy(&code[i], &src[2], chunk_len * 2);
1621 i += chunk_len;
1622 }
1623 }
1624 srclen -= chunk_len + 2;
1625 src += chunk_len + 2;
1626 }
1627 release_firmware(fw_entry);
1628 *fw = (u8 *)code;
1629 *fwlen = i * 2;
1630 return 0;
1631
1632fw_failed:
1633 kfree(code);
1634 release_firmware(fw_entry);
1635 return -1;
1636}
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c
new file mode 100644
index 00000000000..b8cfa1a6eae
--- /dev/null
+++ b/drivers/staging/go7007/go7007-i2c.c
@@ -0,0 +1,225 @@
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/delay.h>
21#include <linux/sched.h>
22#include <linux/list.h>
23#include <linux/unistd.h>
24#include <linux/time.h>
25#include <linux/device.h>
26#include <linux/i2c.h>
27#include <linux/mutex.h>
28#include <linux/uaccess.h>
29#include <asm/system.h>
30
31#include "go7007-priv.h"
32#include "wis-i2c.h"
33
34/********************* Driver for on-board I2C adapter *********************/
35
36/* #define GO7007_I2C_DEBUG */
37
38#define SPI_I2C_ADDR_BASE 0x1400
39#define STATUS_REG_ADDR (SPI_I2C_ADDR_BASE + 0x2)
40#define I2C_CTRL_REG_ADDR (SPI_I2C_ADDR_BASE + 0x6)
41#define I2C_DEV_UP_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x7)
42#define I2C_LO_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x8)
43#define I2C_DATA_REG_ADDR (SPI_I2C_ADDR_BASE + 0x9)
44#define I2C_CLKFREQ_REG_ADDR (SPI_I2C_ADDR_BASE + 0xa)
45
46#define I2C_STATE_MASK 0x0007
47#define I2C_READ_READY_MASK 0x0008
48
49/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
50 * on the Adlink PCI-MPG24, so access is shared between all of them. */
51static DEFINE_MUTEX(adlink_mpg24_i2c_lock);
52
53static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
54 u16 command, int flags, u8 *data)
55{
56 int i, ret = -1;
57 u16 val;
58
59 if (go->status == STATUS_SHUTDOWN)
60 return -1;
61
62#ifdef GO7007_I2C_DEBUG
63 if (read)
64 printk(KERN_DEBUG "go7007-i2c: reading 0x%02x on 0x%02x\n",
65 command, addr);
66 else
67 printk(KERN_DEBUG
68 "go7007-i2c: writing 0x%02x to 0x%02x on 0x%02x\n",
69 *data, command, addr);
70#endif
71
72 mutex_lock(&go->hw_lock);
73
74 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
75 /* Bridge the I2C port on this GO7007 to the shared bus */
76 mutex_lock(&adlink_mpg24_i2c_lock);
77 go7007_write_addr(go, 0x3c82, 0x0020);
78 }
79
80 /* Wait for I2C adapter to be ready */
81 for (i = 0; i < 10; ++i) {
82 if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
83 goto i2c_done;
84 if (!(val & I2C_STATE_MASK))
85 break;
86 msleep(100);
87 }
88 if (i == 10) {
89 printk(KERN_ERR "go7007-i2c: I2C adapter is hung\n");
90 goto i2c_done;
91 }
92
93 /* Set target register (command) */
94 go7007_write_addr(go, I2C_CTRL_REG_ADDR, flags);
95 go7007_write_addr(go, I2C_LO_ADDR_REG_ADDR, command);
96
97 /* If we're writing, send the data and target address and we're done */
98 if (!read) {
99 go7007_write_addr(go, I2C_DATA_REG_ADDR, *data);
100 go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
101 (addr << 9) | (command >> 8));
102 ret = 0;
103 goto i2c_done;
104 }
105
106 /* Otherwise, we're reading. First clear i2c_rx_data_rdy. */
107 if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
108 goto i2c_done;
109
110 /* Send the target address plus read flag */
111 go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
112 (addr << 9) | 0x0100 | (command >> 8));
113
114 /* Wait for i2c_rx_data_rdy */
115 for (i = 0; i < 10; ++i) {
116 if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
117 goto i2c_done;
118 if (val & I2C_READ_READY_MASK)
119 break;
120 msleep(100);
121 }
122 if (i == 10) {
123 printk(KERN_ERR "go7007-i2c: I2C adapter is hung\n");
124 goto i2c_done;
125 }
126
127 /* Retrieve the read byte */
128 if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
129 goto i2c_done;
130 *data = val;
131 ret = 0;
132
133i2c_done:
134 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
135 /* Isolate the I2C port on this GO7007 from the shared bus */
136 go7007_write_addr(go, 0x3c82, 0x0000);
137 mutex_unlock(&adlink_mpg24_i2c_lock);
138 }
139 mutex_unlock(&go->hw_lock);
140 return ret;
141}
142
143static int go7007_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
144 unsigned short flags, char read_write,
145 u8 command, int size, union i2c_smbus_data *data)
146{
147 struct go7007 *go = i2c_get_adapdata(adapter);
148
149 if (size != I2C_SMBUS_BYTE_DATA)
150 return -1;
151 return go7007_i2c_xfer(go, addr, read_write == I2C_SMBUS_READ, command,
152 flags & I2C_CLIENT_SCCB ? 0x10 : 0x00, &data->byte);
153}
154
155/* VERY LIMITED I2C master xfer function -- only needed because the
156 * SMBus functions only support 8-bit commands and the SAA7135 uses
157 * 16-bit commands. The I2C interface on the GO7007, as limited as
158 * it is, does support this mode. */
159
160static int go7007_i2c_master_xfer(struct i2c_adapter *adapter,
161 struct i2c_msg msgs[], int num)
162{
163 struct go7007 *go = i2c_get_adapdata(adapter);
164 int i;
165
166 for (i = 0; i < num; ++i) {
167 /* We can only do two things here -- write three bytes, or
168 * write two bytes and read one byte. */
169 if (msgs[i].len == 2) {
170 if (i + 1 == num || msgs[i].addr != msgs[i + 1].addr ||
171 (msgs[i].flags & I2C_M_RD) ||
172 !(msgs[i + 1].flags & I2C_M_RD) ||
173 msgs[i + 1].len != 1)
174 return -1;
175 if (go7007_i2c_xfer(go, msgs[i].addr, 1,
176 (msgs[i].buf[0] << 8) | msgs[i].buf[1],
177 0x01, &msgs[i + 1].buf[0]) < 0)
178 return -1;
179 ++i;
180 } else if (msgs[i].len == 3) {
181 if (msgs[i].flags & I2C_M_RD)
182 return -1;
183 if (msgs[i].len != 3)
184 return -1;
185 if (go7007_i2c_xfer(go, msgs[i].addr, 0,
186 (msgs[i].buf[0] << 8) | msgs[i].buf[1],
187 0x01, &msgs[i].buf[2]) < 0)
188 return -1;
189 } else
190 return -1;
191 }
192
193 return 0;
194}
195
196static u32 go7007_functionality(struct i2c_adapter *adapter)
197{
198 return I2C_FUNC_SMBUS_BYTE_DATA;
199}
200
201static struct i2c_algorithm go7007_algo = {
202 .smbus_xfer = go7007_smbus_xfer,
203 .master_xfer = go7007_i2c_master_xfer,
204 .functionality = go7007_functionality,
205};
206
207static struct i2c_adapter go7007_adap_templ = {
208 .owner = THIS_MODULE,
209 .name = "WIS GO7007SB",
210 .algo = &go7007_algo,
211};
212
213int go7007_i2c_init(struct go7007 *go)
214{
215 memcpy(&go->i2c_adapter, &go7007_adap_templ,
216 sizeof(go7007_adap_templ));
217 go->i2c_adapter.dev.parent = go->dev;
218 i2c_set_adapdata(&go->i2c_adapter, go);
219 if (i2c_add_adapter(&go->i2c_adapter) < 0) {
220 printk(KERN_ERR
221 "go7007-i2c: error: i2c_add_adapter failed\n");
222 return -1;
223 }
224 return 0;
225}
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
new file mode 100644
index 00000000000..b58c394c655
--- /dev/null
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -0,0 +1,290 @@
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
24#include <media/v4l2-device.h>
25
26struct go7007;
27
28/* IDs to activate board-specific support code */
29#define GO7007_BOARDID_MATRIX_II 0
30#define GO7007_BOARDID_MATRIX_RELOAD 1
31#define GO7007_BOARDID_STAR_TREK 2
32#define GO7007_BOARDID_PCI_VOYAGER 3
33#define GO7007_BOARDID_XMEN 4
34#define GO7007_BOARDID_XMEN_II 5
35#define GO7007_BOARDID_XMEN_III 6
36#define GO7007_BOARDID_MATRIX_REV 7
37#define GO7007_BOARDID_PX_M402U 16
38#define GO7007_BOARDID_PX_TV402U_ANY 17 /* need to check tuner model */
39#define GO7007_BOARDID_PX_TV402U_NA 18 /* detected NTSC tuner */
40#define GO7007_BOARDID_PX_TV402U_EU 19 /* detected PAL tuner */
41#define GO7007_BOARDID_PX_TV402U_JP 20 /* detected NTSC-J tuner */
42#define GO7007_BOARDID_LIFEVIEW_LR192 21 /* TV Walker Ultra */
43#define GO7007_BOARDID_ENDURA 22
44#define GO7007_BOARDID_ADLINK_MPG24 23
45#define GO7007_BOARDID_SENSORAY_2250 24 /* Sensoray 2250/2251 */
46
47/* Various characteristics of each board */
48#define GO7007_BOARD_HAS_AUDIO (1<<0)
49#define GO7007_BOARD_USE_ONBOARD_I2C (1<<1)
50#define GO7007_BOARD_HAS_TUNER (1<<2)
51
52/* Characteristics of sensor devices */
53#define GO7007_SENSOR_VALID_POLAR (1<<0)
54#define GO7007_SENSOR_HREF_POLAR (1<<1)
55#define GO7007_SENSOR_VREF_POLAR (1<<2)
56#define GO7007_SENSOR_FIELD_ID_POLAR (1<<3)
57#define GO7007_SENSOR_BIT_WIDTH (1<<4)
58#define GO7007_SENSOR_VALID_ENABLE (1<<5)
59#define GO7007_SENSOR_656 (1<<6)
60#define GO7007_SENSOR_CONFIG_MASK 0x7f
61#define GO7007_SENSOR_TV (1<<7)
62#define GO7007_SENSOR_VBI (1<<8)
63#define GO7007_SENSOR_SCALING (1<<9)
64
65/* Characteristics of audio sensor devices */
66#define GO7007_AUDIO_I2S_MODE_1 (1)
67#define GO7007_AUDIO_I2S_MODE_2 (2)
68#define GO7007_AUDIO_I2S_MODE_3 (3)
69#define GO7007_AUDIO_BCLK_POLAR (1<<2)
70#define GO7007_AUDIO_WORD_14 (14<<4)
71#define GO7007_AUDIO_WORD_16 (16<<4)
72#define GO7007_AUDIO_ONE_CHANNEL (1<<11)
73#define GO7007_AUDIO_I2S_MASTER (1<<16)
74#define GO7007_AUDIO_OKI_MODE (1<<17)
75
76struct go7007_board_info {
77 char *firmware;
78 unsigned int flags;
79 int hpi_buffer_cap;
80 unsigned int sensor_flags;
81 int sensor_width;
82 int sensor_height;
83 int sensor_framerate;
84 int sensor_h_offset;
85 int sensor_v_offset;
86 unsigned int audio_flags;
87 int audio_rate;
88 int audio_bclk_div;
89 int audio_main_div;
90 int num_i2c_devs;
91 struct {
92 const char *type;
93 int id;
94 int addr;
95 } i2c_devs[4];
96 int num_inputs;
97 struct {
98 int video_input;
99 int audio_input;
100 char *name;
101 } inputs[4];
102};
103
104struct go7007_hpi_ops {
105 int (*interface_reset)(struct go7007 *go);
106 int (*write_interrupt)(struct go7007 *go, int addr, int data);
107 int (*read_interrupt)(struct go7007 *go);
108 int (*stream_start)(struct go7007 *go);
109 int (*stream_stop)(struct go7007 *go);
110 int (*send_firmware)(struct go7007 *go, u8 *data, int len);
111 int (*send_command)(struct go7007 *go, unsigned int cmd, void *arg);
112};
113
114/* The video buffer size must be a multiple of PAGE_SIZE */
115#define GO7007_BUF_PAGES (128 * 1024 / PAGE_SIZE)
116#define GO7007_BUF_SIZE (GO7007_BUF_PAGES << PAGE_SHIFT)
117
118struct go7007_buffer {
119 struct go7007 *go; /* Reverse reference for VMA ops */
120 int index; /* Reverse reference for DQBUF */
121 enum { BUF_STATE_IDLE, BUF_STATE_QUEUED, BUF_STATE_DONE } state;
122 u32 seq;
123 struct timeval timestamp;
124 struct list_head stream;
125 struct page *pages[GO7007_BUF_PAGES + 1]; /* extra for straddling */
126 unsigned long user_addr;
127 unsigned int page_count;
128 unsigned int offset;
129 unsigned int bytesused;
130 unsigned int frame_offset;
131 u32 modet_active;
132 int mapped;
133};
134
135struct go7007_file {
136 struct go7007 *go;
137 struct mutex lock;
138 int buf_count;
139 struct go7007_buffer *bufs;
140};
141
142#define GO7007_FORMAT_MJPEG 0
143#define GO7007_FORMAT_MPEG4 1
144#define GO7007_FORMAT_MPEG1 2
145#define GO7007_FORMAT_MPEG2 3
146#define GO7007_FORMAT_H263 4
147
148#define GO7007_RATIO_1_1 0
149#define GO7007_RATIO_4_3 1
150#define GO7007_RATIO_16_9 2
151
152enum go7007_parser_state {
153 STATE_DATA,
154 STATE_00,
155 STATE_00_00,
156 STATE_00_00_01,
157 STATE_FF,
158 STATE_VBI_LEN_A,
159 STATE_VBI_LEN_B,
160 STATE_MODET_MAP,
161 STATE_UNPARSED,
162};
163
164struct go7007 {
165 struct device *dev;
166 struct go7007_board_info *board_info;
167 unsigned int board_id;
168 int tuner_type;
169 int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
170 char name[64];
171 struct video_device *video_dev;
172 struct v4l2_device v4l2_dev;
173 int ref_count;
174 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
175 spinlock_t spinlock;
176 struct mutex hw_lock;
177 int streaming;
178 int in_use;
179 int audio_enabled;
180
181 /* Video input */
182 int input;
183 enum { GO7007_STD_NTSC, GO7007_STD_PAL, GO7007_STD_OTHER } standard;
184 int sensor_framerate;
185 int width;
186 int height;
187 int encoder_h_offset;
188 int encoder_v_offset;
189 unsigned int encoder_h_halve:1;
190 unsigned int encoder_v_halve:1;
191 unsigned int encoder_subsample:1;
192
193 /* Encoder config */
194 int format;
195 int bitrate;
196 int fps_scale;
197 int pali;
198 int aspect_ratio;
199 int gop_size;
200 unsigned int ipb:1;
201 unsigned int closed_gop:1;
202 unsigned int repeat_seqhead:1;
203 unsigned int seq_header_enable:1;
204 unsigned int gop_header_enable:1;
205 unsigned int dvd_mode:1;
206 unsigned int interlace_coding:1;
207
208 /* Motion detection */
209 unsigned int modet_enable:1;
210 struct {
211 unsigned int enable:1;
212 int pixel_threshold;
213 int motion_threshold;
214 int mb_threshold;
215 } modet[4];
216 unsigned char modet_map[1624];
217 unsigned char active_map[216];
218
219 /* Video streaming */
220 struct go7007_buffer *active_buf;
221 enum go7007_parser_state state;
222 int parse_length;
223 u16 modet_word;
224 int seen_frame;
225 u32 next_seq;
226 struct list_head stream;
227 wait_queue_head_t frame_waitq;
228
229 /* Audio streaming */
230 void (*audio_deliver)(struct go7007 *go, u8 *buf, int length);
231 void *snd_context;
232
233 /* I2C */
234 int i2c_adapter_online;
235 struct i2c_adapter i2c_adapter;
236
237 /* HPI driver */
238 struct go7007_hpi_ops *hpi_ops;
239 void *hpi_context;
240 int interrupt_available;
241 wait_queue_head_t interrupt_waitq;
242 unsigned short interrupt_value;
243 unsigned short interrupt_data;
244};
245
246static inline struct go7007 *to_go7007(struct v4l2_device *v4l2_dev)
247{
248 return container_of(v4l2_dev, struct go7007, v4l2_dev);
249}
250
251/* All of these must be called with the hpi_lock mutex held! */
252#define go7007_interface_reset(go) \
253 ((go)->hpi_ops->interface_reset(go))
254#define go7007_write_interrupt(go, x, y) \
255 ((go)->hpi_ops->write_interrupt)((go), (x), (y))
256#define go7007_stream_start(go) \
257 ((go)->hpi_ops->stream_start(go))
258#define go7007_stream_stop(go) \
259 ((go)->hpi_ops->stream_stop(go))
260#define go7007_send_firmware(go, x, y) \
261 ((go)->hpi_ops->send_firmware)((go), (x), (y))
262#define go7007_write_addr(go, x, y) \
263 ((go)->hpi_ops->write_interrupt)((go), (x)|0x8000, (y))
264
265/* go7007-driver.c */
266int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data);
267int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data);
268int go7007_boot_encoder(struct go7007 *go, int init_i2c);
269int go7007_reset_encoder(struct go7007 *go);
270int go7007_register_encoder(struct go7007 *go);
271int go7007_start_encoder(struct go7007 *go);
272void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length);
273struct go7007 *go7007_alloc(struct go7007_board_info *board,
274 struct device *dev);
275void go7007_remove(struct go7007 *go);
276
277/* go7007-fw.c */
278int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen);
279
280/* go7007-i2c.c */
281int go7007_i2c_init(struct go7007 *go);
282int go7007_i2c_remove(struct go7007 *go);
283
284/* go7007-v4l2.c */
285int go7007_v4l2_init(struct go7007 *go);
286void go7007_v4l2_remove(struct go7007 *go);
287
288/* snd-go7007.c */
289int go7007_snd_init(struct go7007 *go);
290int 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..3db3b0a91cc
--- /dev/null
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -0,0 +1,1288 @@
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/wait.h>
22#include <linux/list.h>
23#include <linux/slab.h>
24#include <linux/time.h>
25#include <linux/mm.h>
26#include <linux/usb.h>
27#include <linux/i2c.h>
28#include <asm/byteorder.h>
29#include <media/tvaudio.h>
30
31#include "go7007-priv.h"
32#include "wis-i2c.h"
33
34static unsigned int assume_endura;
35module_param(assume_endura, int, 0644);
36MODULE_PARM_DESC(assume_endura, "when probing fails, "
37 "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 mutex 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 .type = "wis_saa7115",
96 .id = I2C_DRIVERID_WIS_SAA7115,
97 .addr = 0x20,
98 },
99 },
100 .num_inputs = 2,
101 .inputs = {
102 {
103 .video_input = 0,
104 .name = "Composite",
105 },
106 {
107 .video_input = 9,
108 .name = "S-Video",
109 },
110 },
111 },
112};
113
114static struct go7007_usb_board board_matrix_reload = {
115 .flags = GO7007_USB_EZUSB,
116 .main_info = {
117 .firmware = "go7007tv.bin",
118 .flags = GO7007_BOARD_HAS_AUDIO |
119 GO7007_BOARD_USE_ONBOARD_I2C,
120 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
121 GO7007_AUDIO_I2S_MASTER |
122 GO7007_AUDIO_WORD_16,
123 .audio_rate = 48000,
124 .audio_bclk_div = 8,
125 .audio_main_div = 2,
126 .hpi_buffer_cap = 7,
127 .sensor_flags = GO7007_SENSOR_656 |
128 GO7007_SENSOR_TV,
129 .num_i2c_devs = 1,
130 .i2c_devs = {
131 {
132 .type = "wis_saa7113",
133 .id = I2C_DRIVERID_WIS_SAA7113,
134 .addr = 0x25,
135 },
136 },
137 .num_inputs = 2,
138 .inputs = {
139 {
140 .video_input = 0,
141 .name = "Composite",
142 },
143 {
144 .video_input = 9,
145 .name = "S-Video",
146 },
147 },
148 },
149};
150
151static struct go7007_usb_board board_star_trek = {
152 .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
153 .main_info = {
154 .firmware = "go7007tv.bin",
155 .flags = GO7007_BOARD_HAS_AUDIO, /* |
156 GO7007_BOARD_HAS_TUNER, */
157 .sensor_flags = GO7007_SENSOR_656 |
158 GO7007_SENSOR_VALID_ENABLE |
159 GO7007_SENSOR_TV |
160 GO7007_SENSOR_VBI |
161 GO7007_SENSOR_SCALING,
162 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
163 GO7007_AUDIO_WORD_16,
164 .audio_bclk_div = 8,
165 .audio_main_div = 2,
166 .hpi_buffer_cap = 7,
167 .num_i2c_devs = 1,
168 .i2c_devs = {
169 {
170 .type = "wis_saa7115",
171 .id = I2C_DRIVERID_WIS_SAA7115,
172 .addr = 0x20,
173 },
174 },
175 .num_inputs = 2,
176 .inputs = {
177 {
178 .video_input = 1,
179 /* .audio_input = AUDIO_EXTERN, */
180 .name = "Composite",
181 },
182 {
183 .video_input = 8,
184 /* .audio_input = AUDIO_EXTERN, */
185 .name = "S-Video",
186 },
187 /* {
188 * .video_input = 3,
189 * .audio_input = AUDIO_TUNER,
190 * .name = "Tuner",
191 * },
192 */
193 },
194 },
195};
196
197static struct go7007_usb_board board_px_tv402u = {
198 .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
199 .main_info = {
200 .firmware = "go7007tv.bin",
201 .flags = GO7007_BOARD_HAS_AUDIO |
202 GO7007_BOARD_HAS_TUNER,
203 .sensor_flags = GO7007_SENSOR_656 |
204 GO7007_SENSOR_VALID_ENABLE |
205 GO7007_SENSOR_TV |
206 GO7007_SENSOR_VBI |
207 GO7007_SENSOR_SCALING,
208 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
209 GO7007_AUDIO_WORD_16,
210 .audio_bclk_div = 8,
211 .audio_main_div = 2,
212 .hpi_buffer_cap = 7,
213 .num_i2c_devs = 3,
214 .i2c_devs = {
215 {
216 .type = "wis_saa7115",
217 .id = I2C_DRIVERID_WIS_SAA7115,
218 .addr = 0x20,
219 },
220 {
221 .type = "wis_uda1342",
222 .id = I2C_DRIVERID_WIS_UDA1342,
223 .addr = 0x1a,
224 },
225 {
226 .type = "wis_sony_tuner",
227 .id = I2C_DRIVERID_WIS_SONY_TUNER,
228 .addr = 0x60,
229 },
230 },
231 .num_inputs = 3,
232 .inputs = {
233 {
234 .video_input = 1,
235 .audio_input = TVAUDIO_INPUT_EXTERN,
236 .name = "Composite",
237 },
238 {
239 .video_input = 8,
240 .audio_input = TVAUDIO_INPUT_EXTERN,
241 .name = "S-Video",
242 },
243 {
244 .video_input = 3,
245 .audio_input = TVAUDIO_INPUT_TUNER,
246 .name = "Tuner",
247 },
248 },
249 },
250};
251
252static struct go7007_usb_board board_xmen = {
253 .flags = 0,
254 .main_info = {
255 .firmware = "go7007tv.bin",
256 .flags = GO7007_BOARD_USE_ONBOARD_I2C,
257 .hpi_buffer_cap = 0,
258 .sensor_flags = GO7007_SENSOR_VREF_POLAR,
259 .sensor_width = 320,
260 .sensor_height = 240,
261 .sensor_framerate = 30030,
262 .audio_flags = GO7007_AUDIO_ONE_CHANNEL |
263 GO7007_AUDIO_I2S_MODE_3 |
264 GO7007_AUDIO_WORD_14 |
265 GO7007_AUDIO_I2S_MASTER |
266 GO7007_AUDIO_BCLK_POLAR |
267 GO7007_AUDIO_OKI_MODE,
268 .audio_rate = 8000,
269 .audio_bclk_div = 48,
270 .audio_main_div = 1,
271 .num_i2c_devs = 1,
272 .i2c_devs = {
273 {
274 .type = "wis_ov7640",
275 .id = I2C_DRIVERID_WIS_OV7640,
276 .addr = 0x21,
277 },
278 },
279 .num_inputs = 1,
280 .inputs = {
281 {
282 .name = "Camera",
283 },
284 },
285 },
286};
287
288static struct go7007_usb_board board_matrix_revolution = {
289 .flags = GO7007_USB_EZUSB,
290 .main_info = {
291 .firmware = "go7007tv.bin",
292 .flags = GO7007_BOARD_HAS_AUDIO |
293 GO7007_BOARD_USE_ONBOARD_I2C,
294 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
295 GO7007_AUDIO_I2S_MASTER |
296 GO7007_AUDIO_WORD_16,
297 .audio_rate = 48000,
298 .audio_bclk_div = 8,
299 .audio_main_div = 2,
300 .hpi_buffer_cap = 7,
301 .sensor_flags = GO7007_SENSOR_656 |
302 GO7007_SENSOR_TV |
303 GO7007_SENSOR_VBI,
304 .num_i2c_devs = 1,
305 .i2c_devs = {
306 {
307 .type = "wis_tw9903",
308 .id = I2C_DRIVERID_WIS_TW9903,
309 .addr = 0x44,
310 },
311 },
312 .num_inputs = 2,
313 .inputs = {
314 {
315 .video_input = 2,
316 .name = "Composite",
317 },
318 {
319 .video_input = 8,
320 .name = "S-Video",
321 },
322 },
323 },
324};
325
326static struct go7007_usb_board board_lifeview_lr192 = {
327 .flags = GO7007_USB_EZUSB,
328 .main_info = {
329 .firmware = "go7007tv.bin",
330 .flags = GO7007_BOARD_HAS_AUDIO |
331 GO7007_BOARD_USE_ONBOARD_I2C,
332 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
333 GO7007_AUDIO_WORD_16,
334 .audio_rate = 48000,
335 .audio_bclk_div = 8,
336 .audio_main_div = 2,
337 .hpi_buffer_cap = 7,
338 .sensor_flags = GO7007_SENSOR_656 |
339 GO7007_SENSOR_VALID_ENABLE |
340 GO7007_SENSOR_TV |
341 GO7007_SENSOR_VBI |
342 GO7007_SENSOR_SCALING,
343 .num_i2c_devs = 0,
344 .num_inputs = 1,
345 .inputs = {
346 {
347 .video_input = 0,
348 .name = "Composite",
349 },
350 },
351 },
352};
353
354static struct go7007_usb_board board_endura = {
355 .flags = 0,
356 .main_info = {
357 .firmware = "go7007tv.bin",
358 .flags = 0,
359 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
360 GO7007_AUDIO_I2S_MASTER |
361 GO7007_AUDIO_WORD_16,
362 .audio_rate = 8000,
363 .audio_bclk_div = 48,
364 .audio_main_div = 8,
365 .hpi_buffer_cap = 0,
366 .sensor_flags = GO7007_SENSOR_656 |
367 GO7007_SENSOR_TV,
368 .sensor_h_offset = 8,
369 .num_i2c_devs = 0,
370 .num_inputs = 1,
371 .inputs = {
372 {
373 .name = "Camera",
374 },
375 },
376 },
377};
378
379static struct go7007_usb_board board_adlink_mpg24 = {
380 .flags = 0,
381 .main_info = {
382 .firmware = "go7007tv.bin",
383 .flags = GO7007_BOARD_USE_ONBOARD_I2C,
384 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
385 GO7007_AUDIO_I2S_MASTER |
386 GO7007_AUDIO_WORD_16,
387 .audio_rate = 48000,
388 .audio_bclk_div = 8,
389 .audio_main_div = 2,
390 .hpi_buffer_cap = 0,
391 .sensor_flags = GO7007_SENSOR_656 |
392 GO7007_SENSOR_TV |
393 GO7007_SENSOR_VBI,
394 .num_i2c_devs = 1,
395 .i2c_devs = {
396 {
397 .type = "wis_tw2804",
398 .id = I2C_DRIVERID_WIS_TW2804,
399 .addr = 0x00, /* yes, really */
400 },
401 },
402 .num_inputs = 1,
403 .inputs = {
404 {
405 .name = "Composite",
406 },
407 },
408 },
409};
410
411static struct go7007_usb_board board_sensoray_2250 = {
412 .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
413 .main_info = {
414 .firmware = "go7007tv.bin",
415 .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
416 GO7007_AUDIO_I2S_MASTER |
417 GO7007_AUDIO_WORD_16,
418 .flags = GO7007_BOARD_HAS_AUDIO,
419 .audio_rate = 48000,
420 .audio_bclk_div = 8,
421 .audio_main_div = 2,
422 .hpi_buffer_cap = 7,
423 .sensor_flags = GO7007_SENSOR_656 |
424 GO7007_SENSOR_TV,
425 .num_i2c_devs = 1,
426 .i2c_devs = {
427 {
428 .type = "s2250",
429 .id = I2C_DRIVERID_S2250,
430 .addr = 0x43,
431 },
432 },
433 .num_inputs = 2,
434 .inputs = {
435 {
436 .video_input = 0,
437 .name = "Composite",
438 },
439 {
440 .video_input = 1,
441 .name = "S-Video",
442 },
443 },
444 },
445};
446
447MODULE_FIRMWARE("go7007tv.bin");
448
449static const struct usb_device_id go7007_usb_id_table[] = {
450 {
451 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
452 USB_DEVICE_ID_MATCH_INT_INFO,
453 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
454 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
455 .bcdDevice_lo = 0x200, /* Revision number of XMen */
456 .bcdDevice_hi = 0x200,
457 .bInterfaceClass = 255,
458 .bInterfaceSubClass = 0,
459 .bInterfaceProtocol = 255,
460 .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN,
461 },
462 {
463 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
464 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
465 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
466 .bcdDevice_lo = 0x202, /* Revision number of Matrix II */
467 .bcdDevice_hi = 0x202,
468 .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_II,
469 },
470 {
471 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
472 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
473 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
474 .bcdDevice_lo = 0x204, /* Revision number of Matrix */
475 .bcdDevice_hi = 0x204, /* Reloaded */
476 .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_RELOAD,
477 },
478 {
479 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
480 USB_DEVICE_ID_MATCH_INT_INFO,
481 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
482 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
483 .bcdDevice_lo = 0x205, /* Revision number of XMen-II */
484 .bcdDevice_hi = 0x205,
485 .bInterfaceClass = 255,
486 .bInterfaceSubClass = 0,
487 .bInterfaceProtocol = 255,
488 .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_II,
489 },
490 {
491 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
492 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
493 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
494 .bcdDevice_lo = 0x208, /* Revision number of Star Trek */
495 .bcdDevice_hi = 0x208,
496 .driver_info = (kernel_ulong_t)GO7007_BOARDID_STAR_TREK,
497 },
498 {
499 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
500 USB_DEVICE_ID_MATCH_INT_INFO,
501 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
502 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
503 .bcdDevice_lo = 0x209, /* Revision number of XMen-III */
504 .bcdDevice_hi = 0x209,
505 .bInterfaceClass = 255,
506 .bInterfaceSubClass = 0,
507 .bInterfaceProtocol = 255,
508 .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_III,
509 },
510 {
511 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
512 .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
513 .idProduct = 0x7007, /* Product ID of GO7007SB chip */
514 .bcdDevice_lo = 0x210, /* Revision number of Matrix */
515 .bcdDevice_hi = 0x210, /* Revolution */
516 .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_REV,
517 },
518 {
519 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
520 .idVendor = 0x093b, /* Vendor ID of Plextor */
521 .idProduct = 0xa102, /* Product ID of M402U */
522 .bcdDevice_lo = 0x1, /* revision number of Blueberry */
523 .bcdDevice_hi = 0x1,
524 .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_M402U,
525 },
526 {
527 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
528 .idVendor = 0x093b, /* Vendor ID of Plextor */
529 .idProduct = 0xa104, /* Product ID of TV402U */
530 .bcdDevice_lo = 0x1,
531 .bcdDevice_hi = 0x1,
532 .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_TV402U_ANY,
533 },
534 {
535 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
536 .idVendor = 0x10fd, /* Vendor ID of Anubis Electronics */
537 .idProduct = 0xde00, /* Product ID of Lifeview LR192 */
538 .bcdDevice_lo = 0x1,
539 .bcdDevice_hi = 0x1,
540 .driver_info = (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192,
541 },
542 {
543 .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
544 .idVendor = 0x1943, /* Vendor ID Sensoray */
545 .idProduct = 0x2250, /* Product ID of 2250/2251 */
546 .bcdDevice_lo = 0x1,
547 .bcdDevice_hi = 0x1,
548 .driver_info = (kernel_ulong_t)GO7007_BOARDID_SENSORAY_2250,
549 },
550 { } /* Terminating entry */
551};
552
553MODULE_DEVICE_TABLE(usb, go7007_usb_id_table);
554
555/********************* Driver for EZ-USB HPI interface *********************/
556
557static int go7007_usb_vendor_request(struct go7007 *go, int request,
558 int value, int index, void *transfer_buffer, int length, int in)
559{
560 struct go7007_usb *usb = go->hpi_context;
561 int timeout = 5000;
562
563 if (in) {
564 return usb_control_msg(usb->usbdev,
565 usb_rcvctrlpipe(usb->usbdev, 0), request,
566 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
567 value, index, transfer_buffer, length, timeout);
568 } else {
569 return usb_control_msg(usb->usbdev,
570 usb_sndctrlpipe(usb->usbdev, 0), request,
571 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
572 value, index, transfer_buffer, length, timeout);
573 }
574}
575
576static int go7007_usb_interface_reset(struct go7007 *go)
577{
578 struct go7007_usb *usb = go->hpi_context;
579 u16 intr_val, intr_data;
580
581 /* Reset encoder */
582 if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
583 return -1;
584 msleep(100);
585
586 if (usb->board->flags & GO7007_USB_EZUSB) {
587 /* Reset buffer in EZ-USB */
588#ifdef GO7007_USB_DEBUG
589 printk(KERN_DEBUG "go7007-usb: resetting EZ-USB buffers\n");
590#endif
591 if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
592 go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
593 return -1;
594
595 /* Reset encoder again */
596 if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
597 return -1;
598 msleep(100);
599 }
600
601 /* Wait for an interrupt to indicate successful hardware reset */
602 if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
603 (intr_val & ~0x1) != 0x55aa) {
604 printk(KERN_ERR
605 "go7007-usb: unable to reset the USB interface\n");
606 return -1;
607 }
608 return 0;
609}
610
611static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
612 int addr, int data)
613{
614 struct go7007_usb *usb = go->hpi_context;
615 int i, r;
616 u16 status_reg;
617 int timeout = 500;
618
619#ifdef GO7007_USB_DEBUG
620 printk(KERN_DEBUG
621 "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
622#endif
623
624 for (i = 0; i < 100; ++i) {
625 r = usb_control_msg(usb->usbdev,
626 usb_rcvctrlpipe(usb->usbdev, 0), 0x14,
627 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
628 0, HPI_STATUS_ADDR, &status_reg,
629 sizeof(status_reg), timeout);
630 if (r < 0)
631 goto write_int_error;
632 __le16_to_cpus(&status_reg);
633 if (!(status_reg & 0x0010))
634 break;
635 msleep(10);
636 }
637 if (i == 100) {
638 printk(KERN_ERR
639 "go7007-usb: device is hung, status reg = 0x%04x\n",
640 status_reg);
641 return -1;
642 }
643 r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
644 USB_TYPE_VENDOR | USB_RECIP_DEVICE, data,
645 INT_PARAM_ADDR, NULL, 0, timeout);
646 if (r < 0)
647 goto write_int_error;
648 r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0),
649 0x12, USB_TYPE_VENDOR | USB_RECIP_DEVICE, addr,
650 INT_INDEX_ADDR, NULL, 0, timeout);
651 if (r < 0)
652 goto write_int_error;
653 return 0;
654
655write_int_error:
656 printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
657 return r;
658}
659
660static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
661 int addr, int data)
662{
663 struct go7007_usb *usb = go->hpi_context;
664 u8 *tbuf;
665 int r;
666 int timeout = 500;
667
668#ifdef GO7007_USB_DEBUG
669 printk(KERN_DEBUG
670 "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
671#endif
672
673 tbuf = kzalloc(8, GFP_KERNEL);
674 if (tbuf == NULL)
675 return -ENOMEM;
676 tbuf[0] = data & 0xff;
677 tbuf[1] = data >> 8;
678 tbuf[2] = addr & 0xff;
679 tbuf[3] = addr >> 8;
680 r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00,
681 USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
682 0xf0f0, tbuf, 8, timeout);
683 kfree(tbuf);
684 if (r < 0) {
685 printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
686 return r;
687 }
688 return 0;
689}
690
691static void go7007_usb_readinterrupt_complete(struct urb *urb)
692{
693 struct go7007 *go = (struct go7007 *)urb->context;
694 u16 *regs = (u16 *)urb->transfer_buffer;
695 int status = urb->status;
696
697 if (status) {
698 if (status != -ESHUTDOWN &&
699 go->status != STATUS_SHUTDOWN) {
700 printk(KERN_ERR
701 "go7007-usb: error in read interrupt: %d\n",
702 urb->status);
703 } else {
704 wake_up(&go->interrupt_waitq);
705 return;
706 }
707 } else if (urb->actual_length != urb->transfer_buffer_length) {
708 printk(KERN_ERR "go7007-usb: short read in interrupt pipe!\n");
709 } else {
710 go->interrupt_available = 1;
711 go->interrupt_data = __le16_to_cpu(regs[0]);
712 go->interrupt_value = __le16_to_cpu(regs[1]);
713#ifdef GO7007_USB_DEBUG
714 printk(KERN_DEBUG "go7007-usb: ReadInterrupt: %04x %04x\n",
715 go->interrupt_value, go->interrupt_data);
716#endif
717 }
718
719 wake_up(&go->interrupt_waitq);
720}
721
722static int go7007_usb_read_interrupt(struct go7007 *go)
723{
724 struct go7007_usb *usb = go->hpi_context;
725 int r;
726
727 r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
728 if (r < 0) {
729 printk(KERN_ERR
730 "go7007-usb: unable to submit interrupt urb: %d\n", r);
731 return r;
732 }
733 return 0;
734}
735
736static void go7007_usb_read_video_pipe_complete(struct urb *urb)
737{
738 struct go7007 *go = (struct go7007 *)urb->context;
739 int r, status = urb->status;
740
741 if (!go->streaming) {
742 wake_up_interruptible(&go->frame_waitq);
743 return;
744 }
745 if (status) {
746 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
747 status);
748 return;
749 }
750 if (urb->actual_length != urb->transfer_buffer_length) {
751 printk(KERN_ERR "go7007-usb: short read in video pipe!\n");
752 return;
753 }
754 go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
755 r = usb_submit_urb(urb, GFP_ATOMIC);
756 if (r < 0)
757 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", r);
758}
759
760static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
761{
762 struct go7007 *go = (struct go7007 *)urb->context;
763 int r, status = urb->status;
764
765 if (!go->streaming)
766 return;
767 if (status) {
768 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
769 status);
770 return;
771 }
772 if (urb->actual_length != urb->transfer_buffer_length) {
773 printk(KERN_ERR "go7007-usb: short read in audio pipe!\n");
774 return;
775 }
776 if (go->audio_deliver != NULL)
777 go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
778 r = usb_submit_urb(urb, GFP_ATOMIC);
779 if (r < 0)
780 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", r);
781}
782
783static int go7007_usb_stream_start(struct go7007 *go)
784{
785 struct go7007_usb *usb = go->hpi_context;
786 int i, r;
787
788 for (i = 0; i < 8; ++i) {
789 r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
790 if (r < 0) {
791 printk(KERN_ERR "go7007-usb: error submitting video "
792 "urb %d: %d\n", i, r);
793 goto video_submit_failed;
794 }
795 }
796 if (!go->audio_enabled)
797 return 0;
798
799 for (i = 0; i < 8; ++i) {
800 r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
801 if (r < 0) {
802 printk(KERN_ERR "go7007-usb: error submitting audio "
803 "urb %d: %d\n", i, r);
804 goto audio_submit_failed;
805 }
806 }
807 return 0;
808
809audio_submit_failed:
810 for (i = 0; i < 7; ++i)
811 usb_kill_urb(usb->audio_urbs[i]);
812video_submit_failed:
813 for (i = 0; i < 8; ++i)
814 usb_kill_urb(usb->video_urbs[i]);
815 return -1;
816}
817
818static int go7007_usb_stream_stop(struct go7007 *go)
819{
820 struct go7007_usb *usb = go->hpi_context;
821 int i;
822
823 if (go->status == STATUS_SHUTDOWN)
824 return 0;
825 for (i = 0; i < 8; ++i)
826 usb_kill_urb(usb->video_urbs[i]);
827 if (go->audio_enabled)
828 for (i = 0; i < 8; ++i)
829 usb_kill_urb(usb->audio_urbs[i]);
830 return 0;
831}
832
833static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
834{
835 struct go7007_usb *usb = go->hpi_context;
836 int transferred, pipe;
837 int timeout = 500;
838
839#ifdef GO7007_USB_DEBUG
840 printk(KERN_DEBUG "go7007-usb: DownloadBuffer sending %d bytes\n", len);
841#endif
842
843 if (usb->board->flags & GO7007_USB_EZUSB)
844 pipe = usb_sndbulkpipe(usb->usbdev, 2);
845 else
846 pipe = usb_sndbulkpipe(usb->usbdev, 3);
847
848 return usb_bulk_msg(usb->usbdev, pipe, data, len,
849 &transferred, timeout);
850}
851
852static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
853 .interface_reset = go7007_usb_interface_reset,
854 .write_interrupt = go7007_usb_ezusb_write_interrupt,
855 .read_interrupt = go7007_usb_read_interrupt,
856 .stream_start = go7007_usb_stream_start,
857 .stream_stop = go7007_usb_stream_stop,
858 .send_firmware = go7007_usb_send_firmware,
859};
860
861static struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
862 .interface_reset = go7007_usb_interface_reset,
863 .write_interrupt = go7007_usb_onboard_write_interrupt,
864 .read_interrupt = go7007_usb_read_interrupt,
865 .stream_start = go7007_usb_stream_start,
866 .stream_stop = go7007_usb_stream_stop,
867 .send_firmware = go7007_usb_send_firmware,
868};
869
870/********************* Driver for EZ-USB I2C adapter *********************/
871
872static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
873 struct i2c_msg msgs[], int num)
874{
875 struct go7007 *go = i2c_get_adapdata(adapter);
876 struct go7007_usb *usb = go->hpi_context;
877 u8 buf[16];
878 int buf_len, i;
879 int ret = -1;
880
881 if (go->status == STATUS_SHUTDOWN)
882 return -1;
883
884 mutex_lock(&usb->i2c_lock);
885
886 for (i = 0; i < num; ++i) {
887 /* The hardware command is "write some bytes then read some
888 * bytes", so we try to coalesce a write followed by a read
889 * into a single USB transaction */
890 if (i + 1 < num && msgs[i].addr == msgs[i + 1].addr &&
891 !(msgs[i].flags & I2C_M_RD) &&
892 (msgs[i + 1].flags & I2C_M_RD)) {
893#ifdef GO7007_I2C_DEBUG
894 printk(KERN_DEBUG "go7007-usb: i2c write/read %d/%d "
895 "bytes on %02x\n", msgs[i].len,
896 msgs[i + 1].len, msgs[i].addr);
897#endif
898 buf[0] = 0x01;
899 buf[1] = msgs[i].len + 1;
900 buf[2] = msgs[i].addr << 1;
901 memcpy(&buf[3], msgs[i].buf, msgs[i].len);
902 buf_len = msgs[i].len + 3;
903 buf[buf_len++] = msgs[++i].len;
904 } else if (msgs[i].flags & I2C_M_RD) {
905#ifdef GO7007_I2C_DEBUG
906 printk(KERN_DEBUG "go7007-usb: i2c read %d "
907 "bytes on %02x\n", msgs[i].len,
908 msgs[i].addr);
909#endif
910 buf[0] = 0x01;
911 buf[1] = 1;
912 buf[2] = msgs[i].addr << 1;
913 buf[3] = msgs[i].len;
914 buf_len = 4;
915 } else {
916#ifdef GO7007_I2C_DEBUG
917 printk(KERN_DEBUG "go7007-usb: i2c write %d "
918 "bytes on %02x\n", msgs[i].len,
919 msgs[i].addr);
920#endif
921 buf[0] = 0x00;
922 buf[1] = msgs[i].len + 1;
923 buf[2] = msgs[i].addr << 1;
924 memcpy(&buf[3], msgs[i].buf, msgs[i].len);
925 buf_len = msgs[i].len + 3;
926 buf[buf_len++] = 0;
927 }
928 if (go7007_usb_vendor_request(go, 0x24, 0, 0,
929 buf, buf_len, 0) < 0)
930 goto i2c_done;
931 if (msgs[i].flags & I2C_M_RD) {
932 memset(buf, 0, sizeof(buf));
933 if (go7007_usb_vendor_request(go, 0x25, 0, 0, buf,
934 msgs[i].len + 1, 1) < 0)
935 goto i2c_done;
936 memcpy(msgs[i].buf, buf + 1, msgs[i].len);
937 }
938 }
939 ret = 0;
940
941i2c_done:
942 mutex_unlock(&usb->i2c_lock);
943 return ret;
944}
945
946static u32 go7007_usb_functionality(struct i2c_adapter *adapter)
947{
948 /* No errors are reported by the hardware, so we don't bother
949 * supporting quick writes to avoid confusing probing */
950 return (I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK;
951}
952
953static struct i2c_algorithm go7007_usb_algo = {
954 .master_xfer = go7007_usb_i2c_master_xfer,
955 .functionality = go7007_usb_functionality,
956};
957
958static struct i2c_adapter go7007_usb_adap_templ = {
959 .owner = THIS_MODULE,
960 .name = "WIS GO7007SB EZ-USB",
961 .algo = &go7007_usb_algo,
962};
963
964/********************* USB add/remove functions *********************/
965
966static int go7007_usb_probe(struct usb_interface *intf,
967 const struct usb_device_id *id)
968{
969 struct go7007 *go;
970 struct go7007_usb *usb;
971 struct go7007_usb_board *board;
972 struct usb_device *usbdev = interface_to_usbdev(intf);
973 char *name;
974 int video_pipe, i, v_urb_len;
975
976 printk(KERN_DEBUG "go7007-usb: probing new GO7007 USB board\n");
977
978 switch (id->driver_info) {
979 case GO7007_BOARDID_MATRIX_II:
980 name = "WIS Matrix II or compatible";
981 board = &board_matrix_ii;
982 break;
983 case GO7007_BOARDID_MATRIX_RELOAD:
984 name = "WIS Matrix Reloaded or compatible";
985 board = &board_matrix_reload;
986 break;
987 case GO7007_BOARDID_MATRIX_REV:
988 name = "WIS Matrix Revolution or compatible";
989 board = &board_matrix_revolution;
990 break;
991 case GO7007_BOARDID_STAR_TREK:
992 name = "WIS Star Trek or compatible";
993 board = &board_star_trek;
994 break;
995 case GO7007_BOARDID_XMEN:
996 name = "WIS XMen or compatible";
997 board = &board_xmen;
998 break;
999 case GO7007_BOARDID_XMEN_II:
1000 name = "WIS XMen II or compatible";
1001 board = &board_xmen;
1002 break;
1003 case GO7007_BOARDID_XMEN_III:
1004 name = "WIS XMen III or compatible";
1005 board = &board_xmen;
1006 break;
1007 case GO7007_BOARDID_PX_M402U:
1008 name = "Plextor PX-M402U";
1009 board = &board_matrix_ii;
1010 break;
1011 case GO7007_BOARDID_PX_TV402U_ANY:
1012 name = "Plextor PX-TV402U (unknown tuner)";
1013 board = &board_px_tv402u;
1014 break;
1015 case GO7007_BOARDID_LIFEVIEW_LR192:
1016 printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
1017 "is not supported. Sorry!\n");
1018 return 0;
1019 name = "Lifeview TV Walker Ultra";
1020 board = &board_lifeview_lr192;
1021 break;
1022 case GO7007_BOARDID_SENSORAY_2250:
1023 printk(KERN_INFO "Sensoray 2250 found\n");
1024 name = "Sensoray 2250/2251";
1025 board = &board_sensoray_2250;
1026 break;
1027 default:
1028 printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
1029 (unsigned int)id->driver_info);
1030 return 0;
1031 }
1032
1033 usb = kzalloc(sizeof(struct go7007_usb), GFP_KERNEL);
1034 if (usb == NULL)
1035 return -ENOMEM;
1036
1037 /* Allocate the URB and buffer for receiving incoming interrupts */
1038 usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
1039 if (usb->intr_urb == NULL)
1040 goto allocfail;
1041 usb->intr_urb->transfer_buffer = kmalloc(2*sizeof(u16), GFP_KERNEL);
1042 if (usb->intr_urb->transfer_buffer == NULL)
1043 goto allocfail;
1044
1045 go = go7007_alloc(&board->main_info, &intf->dev);
1046 if (go == NULL)
1047 goto allocfail;
1048 usb->board = board;
1049 usb->usbdev = usbdev;
1050 go->board_id = id->driver_info;
1051 strncpy(go->name, name, sizeof(go->name));
1052 if (board->flags & GO7007_USB_EZUSB)
1053 go->hpi_ops = &go7007_usb_ezusb_hpi_ops;
1054 else
1055 go->hpi_ops = &go7007_usb_onboard_hpi_ops;
1056 go->hpi_context = usb;
1057 usb_fill_int_urb(usb->intr_urb, usb->usbdev,
1058 usb_rcvintpipe(usb->usbdev, 4),
1059 usb->intr_urb->transfer_buffer, 2*sizeof(u16),
1060 go7007_usb_readinterrupt_complete, go, 8);
1061 usb_set_intfdata(intf, &go->v4l2_dev);
1062
1063 /* Boot the GO7007 */
1064 if (go7007_boot_encoder(go, go->board_info->flags &
1065 GO7007_BOARD_USE_ONBOARD_I2C) < 0)
1066 goto initfail;
1067
1068 /* Register the EZ-USB I2C adapter, if we're using it */
1069 if (board->flags & GO7007_USB_EZUSB_I2C) {
1070 memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
1071 sizeof(go7007_usb_adap_templ));
1072 mutex_init(&usb->i2c_lock);
1073 go->i2c_adapter.dev.parent = go->dev;
1074 i2c_set_adapdata(&go->i2c_adapter, go);
1075 if (i2c_add_adapter(&go->i2c_adapter) < 0) {
1076 printk(KERN_ERR
1077 "go7007-usb: error: i2c_add_adapter failed\n");
1078 goto initfail;
1079 }
1080 go->i2c_adapter_online = 1;
1081 }
1082
1083 /* Pelco and Adlink reused the XMen and XMen-III vendor and product
1084 * IDs for their own incompatible designs. We can detect XMen boards
1085 * by probing the sensor, but there is no way to probe the sensors on
1086 * the Pelco and Adlink designs so we default to the Adlink. If it
1087 * is actually a Pelco, the user must set the assume_endura module
1088 * parameter. */
1089 if ((go->board_id == GO7007_BOARDID_XMEN ||
1090 go->board_id == GO7007_BOARDID_XMEN_III) &&
1091 go->i2c_adapter_online) {
1092 union i2c_smbus_data data;
1093
1094 /* Check to see if register 0x0A is 0x76 */
1095 i2c_smbus_xfer(&go->i2c_adapter, 0x21, I2C_CLIENT_SCCB,
1096 I2C_SMBUS_READ, 0x0A, I2C_SMBUS_BYTE_DATA, &data);
1097 if (data.byte != 0x76) {
1098 if (assume_endura) {
1099 go->board_id = GO7007_BOARDID_ENDURA;
1100 usb->board = board = &board_endura;
1101 go->board_info = &board->main_info;
1102 strncpy(go->name, "Pelco Endura",
1103 sizeof(go->name));
1104 } else {
1105 u16 channel;
1106
1107 /* set GPIO5 to be an output, currently low */
1108 go7007_write_addr(go, 0x3c82, 0x0000);
1109 go7007_write_addr(go, 0x3c80, 0x00df);
1110 /* read channel number from GPIO[1:0] */
1111 go7007_read_addr(go, 0x3c81, &channel);
1112 channel &= 0x3;
1113 go->board_id = GO7007_BOARDID_ADLINK_MPG24;
1114 usb->board = board = &board_adlink_mpg24;
1115 go->board_info = &board->main_info;
1116 go->channel_number = channel;
1117 snprintf(go->name, sizeof(go->name),
1118 "Adlink PCI-MPG24, channel #%d",
1119 channel);
1120 }
1121 }
1122 }
1123
1124 /* Probe the tuner model on the TV402U */
1125 if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) {
1126 u8 data[3];
1127
1128 /* Board strapping indicates tuner model */
1129 if (go7007_usb_vendor_request(go, 0x41, 0, 0, data, 3, 1) < 0) {
1130 printk(KERN_ERR "go7007-usb: GPIO read failed!\n");
1131 goto initfail;
1132 }
1133 switch (data[0] >> 6) {
1134 case 1:
1135 go->board_id = GO7007_BOARDID_PX_TV402U_EU;
1136 go->tuner_type = TUNER_SONY_BTF_PG472Z;
1137 strncpy(go->name, "Plextor PX-TV402U-EU",
1138 sizeof(go->name));
1139 break;
1140 case 2:
1141 go->board_id = GO7007_BOARDID_PX_TV402U_JP;
1142 go->tuner_type = TUNER_SONY_BTF_PK467Z;
1143 strncpy(go->name, "Plextor PX-TV402U-JP",
1144 sizeof(go->name));
1145 break;
1146 case 3:
1147 go->board_id = GO7007_BOARDID_PX_TV402U_NA;
1148 go->tuner_type = TUNER_SONY_BTF_PB463Z;
1149 strncpy(go->name, "Plextor PX-TV402U-NA",
1150 sizeof(go->name));
1151 break;
1152 default:
1153 printk(KERN_DEBUG "go7007-usb: unable to detect "
1154 "tuner type!\n");
1155 break;
1156 }
1157 /* Configure tuner mode selection inputs connected
1158 * to the EZ-USB GPIO output pins */
1159 if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
1160 NULL, 0, 0) < 0) {
1161 printk(KERN_ERR "go7007-usb: GPIO write failed!\n");
1162 goto initfail;
1163 }
1164 }
1165
1166 /* Print a nasty message if the user attempts to use a USB2.0 device in
1167 * a USB1.1 port. There will be silent corruption of the stream. */
1168 if ((board->flags & GO7007_USB_EZUSB) &&
1169 usbdev->speed != USB_SPEED_HIGH)
1170 printk(KERN_ERR "go7007-usb: *** WARNING *** This device "
1171 "must be connected to a USB 2.0 port! "
1172 "Attempting to capture video through a USB 1.1 "
1173 "port will result in stream corruption, even "
1174 "at low bitrates!\n");
1175
1176 /* Do any final GO7007 initialization, then register the
1177 * V4L2 and ALSA interfaces */
1178 if (go7007_register_encoder(go) < 0)
1179 goto initfail;
1180
1181 /* Allocate the URBs and buffers for receiving the video stream */
1182 if (board->flags & GO7007_USB_EZUSB) {
1183 v_urb_len = 1024;
1184 video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
1185 } else {
1186 v_urb_len = 512;
1187 video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
1188 }
1189 for (i = 0; i < 8; ++i) {
1190 usb->video_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1191 if (usb->video_urbs[i] == NULL)
1192 goto initfail;
1193 usb->video_urbs[i]->transfer_buffer =
1194 kmalloc(v_urb_len, GFP_KERNEL);
1195 if (usb->video_urbs[i]->transfer_buffer == NULL)
1196 goto initfail;
1197 usb_fill_bulk_urb(usb->video_urbs[i], usb->usbdev, video_pipe,
1198 usb->video_urbs[i]->transfer_buffer, v_urb_len,
1199 go7007_usb_read_video_pipe_complete, go);
1200 }
1201
1202 /* Allocate the URBs and buffers for receiving the audio stream */
1203 if ((board->flags & GO7007_USB_EZUSB) && go->audio_enabled)
1204 for (i = 0; i < 8; ++i) {
1205 usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
1206 if (usb->audio_urbs[i] == NULL)
1207 goto initfail;
1208 usb->audio_urbs[i]->transfer_buffer = kmalloc(4096,
1209 GFP_KERNEL);
1210 if (usb->audio_urbs[i]->transfer_buffer == NULL)
1211 goto initfail;
1212 usb_fill_bulk_urb(usb->audio_urbs[i], usb->usbdev,
1213 usb_rcvbulkpipe(usb->usbdev, 8),
1214 usb->audio_urbs[i]->transfer_buffer, 4096,
1215 go7007_usb_read_audio_pipe_complete, go);
1216 }
1217
1218
1219 go->status = STATUS_ONLINE;
1220 return 0;
1221
1222initfail:
1223 go->status = STATUS_SHUTDOWN;
1224 return 0;
1225
1226allocfail:
1227 if (usb->intr_urb) {
1228 kfree(usb->intr_urb->transfer_buffer);
1229 usb_free_urb(usb->intr_urb);
1230 }
1231 kfree(usb);
1232 return -ENOMEM;
1233}
1234
1235static void go7007_usb_disconnect(struct usb_interface *intf)
1236{
1237 struct go7007 *go = to_go7007(usb_get_intfdata(intf));
1238 struct go7007_usb *usb = go->hpi_context;
1239 struct urb *vurb, *aurb;
1240 int i;
1241
1242 go->status = STATUS_SHUTDOWN;
1243 usb_kill_urb(usb->intr_urb);
1244
1245 /* Free USB-related structs */
1246 for (i = 0; i < 8; ++i) {
1247 vurb = usb->video_urbs[i];
1248 if (vurb) {
1249 usb_kill_urb(vurb);
1250 kfree(vurb->transfer_buffer);
1251 usb_free_urb(vurb);
1252 }
1253 aurb = usb->audio_urbs[i];
1254 if (aurb) {
1255 usb_kill_urb(aurb);
1256 kfree(aurb->transfer_buffer);
1257 usb_free_urb(aurb);
1258 }
1259 }
1260 kfree(usb->intr_urb->transfer_buffer);
1261 usb_free_urb(usb->intr_urb);
1262
1263 kfree(go->hpi_context);
1264
1265 go7007_remove(go);
1266}
1267
1268static struct usb_driver go7007_usb_driver = {
1269 .name = "go7007",
1270 .probe = go7007_usb_probe,
1271 .disconnect = go7007_usb_disconnect,
1272 .id_table = go7007_usb_id_table,
1273};
1274
1275static int __init go7007_usb_init(void)
1276{
1277 return usb_register(&go7007_usb_driver);
1278}
1279
1280static void __exit go7007_usb_cleanup(void)
1281{
1282 usb_deregister(&go7007_usb_driver);
1283}
1284
1285module_init(go7007_usb_init);
1286module_exit(go7007_usb_cleanup);
1287
1288MODULE_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..2b27d8da70a
--- /dev/null
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -0,0 +1,1839 @@
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/slab.h>
25#include <linux/fs.h>
26#include <linux/unistd.h>
27#include <linux/time.h>
28#include <linux/vmalloc.h>
29#include <linux/pagemap.h>
30#include <linux/videodev2.h>
31#include <media/v4l2-common.h>
32#include <media/v4l2-ioctl.h>
33#include <media/v4l2-subdev.h>
34#include <linux/i2c.h>
35#include <linux/mutex.h>
36#include <linux/uaccess.h>
37#include <asm/system.h>
38
39#include "go7007.h"
40#include "go7007-priv.h"
41#include "wis-i2c.h"
42
43/* Temporary defines until accepted in v4l-dvb */
44#ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
45#define V4L2_MPEG_STREAM_TYPE_MPEG_ELEM 6 /* MPEG elementary stream */
46#endif
47#ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4
48#define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3
49#endif
50
51#define call_all(dev, o, f, args...) \
52 v4l2_device_call_until_err(dev, 0, o, f, ##args)
53
54static void deactivate_buffer(struct go7007_buffer *gobuf)
55{
56 int i;
57
58 if (gobuf->state != BUF_STATE_IDLE) {
59 list_del(&gobuf->stream);
60 gobuf->state = BUF_STATE_IDLE;
61 }
62 if (gobuf->page_count > 0) {
63 for (i = 0; i < gobuf->page_count; ++i)
64 page_cache_release(gobuf->pages[i]);
65 gobuf->page_count = 0;
66 }
67}
68
69static void abort_queued(struct go7007 *go)
70{
71 struct go7007_buffer *gobuf, *next;
72
73 list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
74 deactivate_buffer(gobuf);
75 }
76}
77
78static int go7007_streamoff(struct go7007 *go)
79{
80 int retval = -EINVAL;
81 unsigned long flags;
82
83 mutex_lock(&go->hw_lock);
84 if (go->streaming) {
85 go->streaming = 0;
86 go7007_stream_stop(go);
87 spin_lock_irqsave(&go->spinlock, flags);
88 abort_queued(go);
89 spin_unlock_irqrestore(&go->spinlock, flags);
90 go7007_reset_encoder(go);
91 retval = 0;
92 }
93 mutex_unlock(&go->hw_lock);
94 return 0;
95}
96
97static int go7007_open(struct file *file)
98{
99 struct go7007 *go = video_get_drvdata(video_devdata(file));
100 struct go7007_file *gofh;
101
102 if (go->status != STATUS_ONLINE)
103 return -EBUSY;
104 gofh = kmalloc(sizeof(struct go7007_file), GFP_KERNEL);
105 if (gofh == NULL)
106 return -ENOMEM;
107 ++go->ref_count;
108 gofh->go = go;
109 mutex_init(&gofh->lock);
110 gofh->buf_count = 0;
111 file->private_data = gofh;
112 return 0;
113}
114
115static int go7007_release(struct file *file)
116{
117 struct go7007_file *gofh = file->private_data;
118 struct go7007 *go = gofh->go;
119
120 if (gofh->buf_count > 0) {
121 go7007_streamoff(go);
122 go->in_use = 0;
123 kfree(gofh->bufs);
124 gofh->buf_count = 0;
125 }
126 kfree(gofh);
127 if (--go->ref_count == 0)
128 kfree(go);
129 file->private_data = NULL;
130 return 0;
131}
132
133static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
134{
135 u8 *f = page_address(gobuf->pages[0]);
136
137 switch (format) {
138 case GO7007_FORMAT_MJPEG:
139 return V4L2_BUF_FLAG_KEYFRAME;
140 case GO7007_FORMAT_MPEG4:
141 switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
142 case 0:
143 return V4L2_BUF_FLAG_KEYFRAME;
144 case 1:
145 return V4L2_BUF_FLAG_PFRAME;
146 case 2:
147 return V4L2_BUF_FLAG_BFRAME;
148 default:
149 return 0;
150 }
151 case GO7007_FORMAT_MPEG1:
152 case GO7007_FORMAT_MPEG2:
153 switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
154 case 1:
155 return V4L2_BUF_FLAG_KEYFRAME;
156 case 2:
157 return V4L2_BUF_FLAG_PFRAME;
158 case 3:
159 return V4L2_BUF_FLAG_BFRAME;
160 default:
161 return 0;
162 }
163 }
164
165 return 0;
166}
167
168static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
169{
170 int sensor_height = 0, sensor_width = 0;
171 int width, height, i;
172
173 if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
174 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
175 fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
176 return -EINVAL;
177
178 switch (go->standard) {
179 case GO7007_STD_NTSC:
180 sensor_width = 720;
181 sensor_height = 480;
182 break;
183 case GO7007_STD_PAL:
184 sensor_width = 720;
185 sensor_height = 576;
186 break;
187 case GO7007_STD_OTHER:
188 sensor_width = go->board_info->sensor_width;
189 sensor_height = go->board_info->sensor_height;
190 break;
191 }
192
193 if (fmt == NULL) {
194 width = sensor_width;
195 height = sensor_height;
196 } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
197 if (fmt->fmt.pix.width > sensor_width)
198 width = sensor_width;
199 else if (fmt->fmt.pix.width < 144)
200 width = 144;
201 else
202 width = fmt->fmt.pix.width & ~0x0f;
203
204 if (fmt->fmt.pix.height > sensor_height)
205 height = sensor_height;
206 else if (fmt->fmt.pix.height < 96)
207 height = 96;
208 else
209 height = fmt->fmt.pix.height & ~0x0f;
210 } else {
211 int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height;
212 int sensor_size = sensor_width * sensor_height;
213
214 if (64 * requested_size < 9 * sensor_size) {
215 width = sensor_width / 4;
216 height = sensor_height / 4;
217 } else if (64 * requested_size < 36 * sensor_size) {
218 width = sensor_width / 2;
219 height = sensor_height / 2;
220 } else {
221 width = sensor_width;
222 height = sensor_height;
223 }
224 width &= ~0xf;
225 height &= ~0xf;
226 }
227
228 if (fmt != NULL) {
229 u32 pixelformat = fmt->fmt.pix.pixelformat;
230
231 memset(fmt, 0, sizeof(*fmt));
232 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
233 fmt->fmt.pix.width = width;
234 fmt->fmt.pix.height = height;
235 fmt->fmt.pix.pixelformat = pixelformat;
236 fmt->fmt.pix.field = V4L2_FIELD_NONE;
237 fmt->fmt.pix.bytesperline = 0;
238 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
239 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
240 }
241
242 if (try)
243 return 0;
244
245 go->width = width;
246 go->height = height;
247 go->encoder_h_offset = go->board_info->sensor_h_offset;
248 go->encoder_v_offset = go->board_info->sensor_v_offset;
249 for (i = 0; i < 4; ++i)
250 go->modet[i].enable = 0;
251 for (i = 0; i < 1624; ++i)
252 go->modet_map[i] = 0;
253
254 if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
255 struct v4l2_mbus_framefmt mbus_fmt;
256
257 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
258 if (fmt != NULL)
259 mbus_fmt.width = fmt->fmt.pix.width;
260 else
261 mbus_fmt.width = width;
262
263 if (height > sensor_height / 2) {
264 mbus_fmt.height = height / 2;
265 go->encoder_v_halve = 0;
266 } else {
267 mbus_fmt.height = height;
268 go->encoder_v_halve = 1;
269 }
270 call_all(&go->v4l2_dev, video, s_mbus_fmt, &mbus_fmt);
271 } else {
272 if (width <= sensor_width / 4) {
273 go->encoder_h_halve = 1;
274 go->encoder_v_halve = 1;
275 go->encoder_subsample = 1;
276 } else if (width <= sensor_width / 2) {
277 go->encoder_h_halve = 1;
278 go->encoder_v_halve = 1;
279 go->encoder_subsample = 0;
280 } else {
281 go->encoder_h_halve = 0;
282 go->encoder_v_halve = 0;
283 go->encoder_subsample = 0;
284 }
285 }
286
287 if (fmt == NULL)
288 return 0;
289
290 switch (fmt->fmt.pix.pixelformat) {
291 case V4L2_PIX_FMT_MPEG:
292 if (go->format == GO7007_FORMAT_MPEG1 ||
293 go->format == GO7007_FORMAT_MPEG2 ||
294 go->format == GO7007_FORMAT_MPEG4)
295 break;
296 go->format = GO7007_FORMAT_MPEG1;
297 go->pali = 0;
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 /* Backwards compatibility only! */
308 case V4L2_PIX_FMT_MPEG4:
309 if (go->format == GO7007_FORMAT_MPEG4)
310 break;
311 go->format = GO7007_FORMAT_MPEG4;
312 go->pali = 0xf5;
313 go->aspect_ratio = GO7007_RATIO_1_1;
314 go->gop_size = go->sensor_framerate / 1000;
315 go->ipb = 0;
316 go->closed_gop = 1;
317 go->repeat_seqhead = 1;
318 go->seq_header_enable = 1;
319 go->gop_header_enable = 1;
320 go->dvd_mode = 0;
321 break;
322 case V4L2_PIX_FMT_MJPEG:
323 go->format = GO7007_FORMAT_MJPEG;
324 go->pali = 0;
325 go->aspect_ratio = GO7007_RATIO_1_1;
326 go->gop_size = 0;
327 go->ipb = 0;
328 go->closed_gop = 0;
329 go->repeat_seqhead = 0;
330 go->seq_header_enable = 0;
331 go->gop_header_enable = 0;
332 go->dvd_mode = 0;
333 break;
334 }
335 return 0;
336}
337
338#if 0
339static int clip_to_modet_map(struct go7007 *go, int region,
340 struct v4l2_clip *clip_list)
341{
342 struct v4l2_clip clip, *clip_ptr;
343 int x, y, mbnum;
344
345 /* Check if coordinates are OK and if any macroblocks are already
346 * used by other regions (besides 0) */
347 clip_ptr = clip_list;
348 while (clip_ptr) {
349 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
350 return -EFAULT;
351 if (clip.c.left < 0 || (clip.c.left & 0xF) ||
352 clip.c.width <= 0 || (clip.c.width & 0xF))
353 return -EINVAL;
354 if (clip.c.left + clip.c.width > go->width)
355 return -EINVAL;
356 if (clip.c.top < 0 || (clip.c.top & 0xF) ||
357 clip.c.height <= 0 || (clip.c.height & 0xF))
358 return -EINVAL;
359 if (clip.c.top + clip.c.height > go->height)
360 return -EINVAL;
361 for (y = 0; y < clip.c.height; y += 16)
362 for (x = 0; x < clip.c.width; x += 16) {
363 mbnum = (go->width >> 4) *
364 ((clip.c.top + y) >> 4) +
365 ((clip.c.left + x) >> 4);
366 if (go->modet_map[mbnum] != 0 &&
367 go->modet_map[mbnum] != region)
368 return -EBUSY;
369 }
370 clip_ptr = clip.next;
371 }
372
373 /* Clear old region macroblocks */
374 for (mbnum = 0; mbnum < 1624; ++mbnum)
375 if (go->modet_map[mbnum] == region)
376 go->modet_map[mbnum] = 0;
377
378 /* Claim macroblocks in this list */
379 clip_ptr = clip_list;
380 while (clip_ptr) {
381 if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
382 return -EFAULT;
383 for (y = 0; y < clip.c.height; y += 16)
384 for (x = 0; x < clip.c.width; x += 16) {
385 mbnum = (go->width >> 4) *
386 ((clip.c.top + y) >> 4) +
387 ((clip.c.left + x) >> 4);
388 go->modet_map[mbnum] = region;
389 }
390 clip_ptr = clip.next;
391 }
392 return 0;
393}
394#endif
395
396static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl)
397{
398 static const u32 mpeg_ctrls[] = {
399 V4L2_CID_MPEG_CLASS,
400 V4L2_CID_MPEG_STREAM_TYPE,
401 V4L2_CID_MPEG_VIDEO_ENCODING,
402 V4L2_CID_MPEG_VIDEO_ASPECT,
403 V4L2_CID_MPEG_VIDEO_GOP_SIZE,
404 V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
405 V4L2_CID_MPEG_VIDEO_BITRATE,
406 0
407 };
408 static const u32 *ctrl_classes[] = {
409 mpeg_ctrls,
410 NULL
411 };
412
413 ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
414
415 switch (ctrl->id) {
416 case V4L2_CID_MPEG_CLASS:
417 return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
418 case V4L2_CID_MPEG_STREAM_TYPE:
419 return v4l2_ctrl_query_fill(ctrl,
420 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
421 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1,
422 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM);
423 case V4L2_CID_MPEG_VIDEO_ENCODING:
424 return v4l2_ctrl_query_fill(ctrl,
425 V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
426 V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1,
427 V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
428 case V4L2_CID_MPEG_VIDEO_ASPECT:
429 return v4l2_ctrl_query_fill(ctrl,
430 V4L2_MPEG_VIDEO_ASPECT_1x1,
431 V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
432 V4L2_MPEG_VIDEO_ASPECT_1x1);
433 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
434 return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
435 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
436 return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
437 case V4L2_CID_MPEG_VIDEO_BITRATE:
438 return v4l2_ctrl_query_fill(ctrl,
439 64000,
440 10000000, 1,
441 1500000);
442 default:
443 return -EINVAL;
444 }
445 return 0;
446}
447
448static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
449{
450 /* pretty sure we can't change any of these while streaming */
451 if (go->streaming)
452 return -EBUSY;
453
454 switch (ctrl->id) {
455 case V4L2_CID_MPEG_STREAM_TYPE:
456 switch (ctrl->value) {
457 case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD:
458 go->format = GO7007_FORMAT_MPEG2;
459 go->bitrate = 9800000;
460 go->gop_size = 15;
461 go->pali = 0x48;
462 go->closed_gop = 1;
463 go->repeat_seqhead = 0;
464 go->seq_header_enable = 1;
465 go->gop_header_enable = 1;
466 go->dvd_mode = 1;
467 break;
468 case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM:
469 /* todo: */
470 break;
471 default:
472 return -EINVAL;
473 }
474 break;
475 case V4L2_CID_MPEG_VIDEO_ENCODING:
476 switch (ctrl->value) {
477 case V4L2_MPEG_VIDEO_ENCODING_MPEG_1:
478 go->format = GO7007_FORMAT_MPEG1;
479 go->pali = 0;
480 break;
481 case V4L2_MPEG_VIDEO_ENCODING_MPEG_2:
482 go->format = GO7007_FORMAT_MPEG2;
483 /*if (mpeg->pali >> 24 == 2)
484 go->pali = mpeg->pali & 0xff;
485 else*/
486 go->pali = 0x48;
487 break;
488 case V4L2_MPEG_VIDEO_ENCODING_MPEG_4:
489 go->format = GO7007_FORMAT_MPEG4;
490 /*if (mpeg->pali >> 24 == 4)
491 go->pali = mpeg->pali & 0xff;
492 else*/
493 go->pali = 0xf5;
494 break;
495 default:
496 return -EINVAL;
497 }
498 go->gop_header_enable =
499 /*mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
500 ? 0 :*/ 1;
501 /*if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
502 go->repeat_seqhead = 1;
503 else*/
504 go->repeat_seqhead = 0;
505 go->dvd_mode = 0;
506 break;
507 case V4L2_CID_MPEG_VIDEO_ASPECT:
508 if (go->format == GO7007_FORMAT_MJPEG)
509 return -EINVAL;
510 switch (ctrl->value) {
511 case V4L2_MPEG_VIDEO_ASPECT_1x1:
512 go->aspect_ratio = GO7007_RATIO_1_1;
513 break;
514 case V4L2_MPEG_VIDEO_ASPECT_4x3:
515 go->aspect_ratio = GO7007_RATIO_4_3;
516 break;
517 case V4L2_MPEG_VIDEO_ASPECT_16x9:
518 go->aspect_ratio = GO7007_RATIO_16_9;
519 break;
520 case V4L2_MPEG_VIDEO_ASPECT_221x100:
521 default:
522 return -EINVAL;
523 }
524 break;
525 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
526 if (ctrl->value < 0 || ctrl->value > 34)
527 return -EINVAL;
528 go->gop_size = ctrl->value;
529 break;
530 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
531 if (ctrl->value != 0 && ctrl->value != 1)
532 return -EINVAL;
533 go->closed_gop = ctrl->value;
534 break;
535 case V4L2_CID_MPEG_VIDEO_BITRATE:
536 /* Upper bound is kind of arbitrary here */
537 if (ctrl->value < 64000 || ctrl->value > 10000000)
538 return -EINVAL;
539 go->bitrate = ctrl->value;
540 break;
541 default:
542 return -EINVAL;
543 }
544 return 0;
545}
546
547static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
548{
549 switch (ctrl->id) {
550 case V4L2_CID_MPEG_STREAM_TYPE:
551 if (go->dvd_mode)
552 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
553 else
554 ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG_ELEM;
555 break;
556 case V4L2_CID_MPEG_VIDEO_ENCODING:
557 switch (go->format) {
558 case GO7007_FORMAT_MPEG1:
559 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
560 break;
561 case GO7007_FORMAT_MPEG2:
562 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
563 break;
564 case GO7007_FORMAT_MPEG4:
565 ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4;
566 break;
567 default:
568 return -EINVAL;
569 }
570 break;
571 case V4L2_CID_MPEG_VIDEO_ASPECT:
572 switch (go->aspect_ratio) {
573 case GO7007_RATIO_1_1:
574 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_1x1;
575 break;
576 case GO7007_RATIO_4_3:
577 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_4x3;
578 break;
579 case GO7007_RATIO_16_9:
580 ctrl->value = V4L2_MPEG_VIDEO_ASPECT_16x9;
581 break;
582 default:
583 return -EINVAL;
584 }
585 break;
586 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
587 ctrl->value = go->gop_size;
588 break;
589 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
590 ctrl->value = go->closed_gop;
591 break;
592 case V4L2_CID_MPEG_VIDEO_BITRATE:
593 ctrl->value = go->bitrate;
594 break;
595 default:
596 return -EINVAL;
597 }
598 return 0;
599}
600
601static int vidioc_querycap(struct file *file, void *priv,
602 struct v4l2_capability *cap)
603{
604 struct go7007 *go = ((struct go7007_file *) priv)->go;
605
606 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
607 strlcpy(cap->card, go->name, sizeof(cap->card));
608#if 0
609 strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
610#endif
611
612 cap->version = KERNEL_VERSION(0, 9, 8);
613
614 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
615 V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
616
617 if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
618 cap->capabilities |= V4L2_CAP_TUNER;
619
620 return 0;
621}
622
623static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
624 struct v4l2_fmtdesc *fmt)
625{
626 char *desc = NULL;
627
628 switch (fmt->index) {
629 case 0:
630 fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
631 desc = "Motion-JPEG";
632 break;
633 case 1:
634 fmt->pixelformat = V4L2_PIX_FMT_MPEG;
635 desc = "MPEG1/MPEG2/MPEG4";
636 break;
637 default:
638 return -EINVAL;
639 }
640 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
641 fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
642
643 strncpy(fmt->description, desc, sizeof(fmt->description));
644
645 return 0;
646}
647
648static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
649 struct v4l2_format *fmt)
650{
651 struct go7007 *go = ((struct go7007_file *) priv)->go;
652
653 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
654 fmt->fmt.pix.width = go->width;
655 fmt->fmt.pix.height = go->height;
656 fmt->fmt.pix.pixelformat = (go->format == GO7007_FORMAT_MJPEG) ?
657 V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
658 fmt->fmt.pix.field = V4L2_FIELD_NONE;
659 fmt->fmt.pix.bytesperline = 0;
660 fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
661 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
662
663 return 0;
664}
665
666static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
667 struct v4l2_format *fmt)
668{
669 struct go7007 *go = ((struct go7007_file *) priv)->go;
670
671 return set_capture_size(go, fmt, 1);
672}
673
674static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
675 struct v4l2_format *fmt)
676{
677 struct go7007 *go = ((struct go7007_file *) priv)->go;
678
679 if (go->streaming)
680 return -EBUSY;
681
682 return set_capture_size(go, fmt, 0);
683}
684
685static int vidioc_reqbufs(struct file *file, void *priv,
686 struct v4l2_requestbuffers *req)
687{
688 struct go7007_file *gofh = priv;
689 struct go7007 *go = gofh->go;
690 int retval = -EBUSY;
691 unsigned int count, i;
692
693 if (go->streaming)
694 return retval;
695
696 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
697 req->memory != V4L2_MEMORY_MMAP)
698 return -EINVAL;
699
700 mutex_lock(&gofh->lock);
701 for (i = 0; i < gofh->buf_count; ++i)
702 if (gofh->bufs[i].mapped > 0)
703 goto unlock_and_return;
704
705 mutex_lock(&go->hw_lock);
706 if (go->in_use > 0 && gofh->buf_count == 0) {
707 mutex_unlock(&go->hw_lock);
708 goto unlock_and_return;
709 }
710
711 if (gofh->buf_count > 0)
712 kfree(gofh->bufs);
713
714 retval = -ENOMEM;
715 count = req->count;
716 if (count > 0) {
717 if (count < 2)
718 count = 2;
719 if (count > 32)
720 count = 32;
721
722 gofh->bufs = kcalloc(count, sizeof(struct go7007_buffer),
723 GFP_KERNEL);
724
725 if (!gofh->bufs) {
726 mutex_unlock(&go->hw_lock);
727 goto unlock_and_return;
728 }
729
730 for (i = 0; i < count; ++i) {
731 gofh->bufs[i].go = go;
732 gofh->bufs[i].index = i;
733 gofh->bufs[i].state = BUF_STATE_IDLE;
734 gofh->bufs[i].mapped = 0;
735 }
736
737 go->in_use = 1;
738 } else {
739 go->in_use = 0;
740 }
741
742 gofh->buf_count = count;
743 mutex_unlock(&go->hw_lock);
744 mutex_unlock(&gofh->lock);
745
746 memset(req, 0, sizeof(*req));
747
748 req->count = count;
749 req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
750 req->memory = V4L2_MEMORY_MMAP;
751
752 return 0;
753
754unlock_and_return:
755 mutex_unlock(&gofh->lock);
756 return retval;
757}
758
759static int vidioc_querybuf(struct file *file, void *priv,
760 struct v4l2_buffer *buf)
761{
762 struct go7007_file *gofh = priv;
763 int retval = -EINVAL;
764 unsigned int index;
765
766 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
767 return retval;
768
769 index = buf->index;
770
771 mutex_lock(&gofh->lock);
772 if (index >= gofh->buf_count)
773 goto unlock_and_return;
774
775 memset(buf, 0, sizeof(*buf));
776 buf->index = index;
777 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
778
779 switch (gofh->bufs[index].state) {
780 case BUF_STATE_QUEUED:
781 buf->flags = V4L2_BUF_FLAG_QUEUED;
782 break;
783 case BUF_STATE_DONE:
784 buf->flags = V4L2_BUF_FLAG_DONE;
785 break;
786 default:
787 buf->flags = 0;
788 }
789
790 if (gofh->bufs[index].mapped)
791 buf->flags |= V4L2_BUF_FLAG_MAPPED;
792 buf->memory = V4L2_MEMORY_MMAP;
793 buf->m.offset = index * GO7007_BUF_SIZE;
794 buf->length = GO7007_BUF_SIZE;
795 mutex_unlock(&gofh->lock);
796
797 return 0;
798
799unlock_and_return:
800 mutex_unlock(&gofh->lock);
801 return retval;
802}
803
804static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
805{
806 struct go7007_file *gofh = priv;
807 struct go7007 *go = gofh->go;
808 struct go7007_buffer *gobuf;
809 unsigned long flags;
810 int retval = -EINVAL;
811 int ret;
812
813 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
814 buf->memory != V4L2_MEMORY_MMAP)
815 return retval;
816
817 mutex_lock(&gofh->lock);
818 if (buf->index < 0 || buf->index >= gofh->buf_count)
819 goto unlock_and_return;
820
821 gobuf = &gofh->bufs[buf->index];
822 if (!gobuf->mapped)
823 goto unlock_and_return;
824
825 retval = -EBUSY;
826 if (gobuf->state != BUF_STATE_IDLE)
827 goto unlock_and_return;
828
829 /* offset will be 0 until we really support USERPTR streaming */
830 gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
831 gobuf->bytesused = 0;
832 gobuf->frame_offset = 0;
833 gobuf->modet_active = 0;
834 if (gobuf->offset > 0)
835 gobuf->page_count = GO7007_BUF_PAGES + 1;
836 else
837 gobuf->page_count = GO7007_BUF_PAGES;
838
839 retval = -ENOMEM;
840 down_read(&current->mm->mmap_sem);
841 ret = get_user_pages(current, current->mm,
842 gobuf->user_addr & PAGE_MASK, gobuf->page_count,
843 1, 1, gobuf->pages, NULL);
844 up_read(&current->mm->mmap_sem);
845
846 if (ret != gobuf->page_count) {
847 int i;
848 for (i = 0; i < ret; ++i)
849 page_cache_release(gobuf->pages[i]);
850 gobuf->page_count = 0;
851 goto unlock_and_return;
852 }
853
854 gobuf->state = BUF_STATE_QUEUED;
855 spin_lock_irqsave(&go->spinlock, flags);
856 list_add_tail(&gobuf->stream, &go->stream);
857 spin_unlock_irqrestore(&go->spinlock, flags);
858 mutex_unlock(&gofh->lock);
859
860 return 0;
861
862unlock_and_return:
863 mutex_unlock(&gofh->lock);
864 return retval;
865}
866
867
868static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
869{
870 struct go7007_file *gofh = priv;
871 struct go7007 *go = gofh->go;
872 struct go7007_buffer *gobuf;
873 int retval = -EINVAL;
874 unsigned long flags;
875 u32 frame_type_flag;
876 DEFINE_WAIT(wait);
877
878 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
879 return retval;
880 if (buf->memory != V4L2_MEMORY_MMAP)
881 return retval;
882
883 mutex_lock(&gofh->lock);
884 if (list_empty(&go->stream))
885 goto unlock_and_return;
886 gobuf = list_entry(go->stream.next,
887 struct go7007_buffer, stream);
888
889 retval = -EAGAIN;
890 if (gobuf->state != BUF_STATE_DONE &&
891 !(file->f_flags & O_NONBLOCK)) {
892 for (;;) {
893 prepare_to_wait(&go->frame_waitq, &wait,
894 TASK_INTERRUPTIBLE);
895 if (gobuf->state == BUF_STATE_DONE)
896 break;
897 if (signal_pending(current)) {
898 retval = -ERESTARTSYS;
899 break;
900 }
901 schedule();
902 }
903 finish_wait(&go->frame_waitq, &wait);
904 }
905 if (gobuf->state != BUF_STATE_DONE)
906 goto unlock_and_return;
907
908 spin_lock_irqsave(&go->spinlock, flags);
909 deactivate_buffer(gobuf);
910 spin_unlock_irqrestore(&go->spinlock, flags);
911 frame_type_flag = get_frame_type_flag(gobuf, go->format);
912 gobuf->state = BUF_STATE_IDLE;
913
914 memset(buf, 0, sizeof(*buf));
915 buf->index = gobuf->index;
916 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
917 buf->bytesused = gobuf->bytesused;
918 buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
919 buf->field = V4L2_FIELD_NONE;
920 buf->timestamp = gobuf->timestamp;
921 buf->sequence = gobuf->seq;
922 buf->memory = V4L2_MEMORY_MMAP;
923 buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
924 buf->length = GO7007_BUF_SIZE;
925 buf->reserved = gobuf->modet_active;
926
927 mutex_unlock(&gofh->lock);
928 return 0;
929
930unlock_and_return:
931 mutex_unlock(&gofh->lock);
932 return retval;
933}
934
935static int vidioc_streamon(struct file *file, void *priv,
936 enum v4l2_buf_type type)
937{
938 struct go7007_file *gofh = priv;
939 struct go7007 *go = gofh->go;
940 int retval = 0;
941
942 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
943 return -EINVAL;
944
945 mutex_lock(&gofh->lock);
946 mutex_lock(&go->hw_lock);
947
948 if (!go->streaming) {
949 go->streaming = 1;
950 go->next_seq = 0;
951 go->active_buf = NULL;
952 if (go7007_start_encoder(go) < 0)
953 retval = -EIO;
954 else
955 retval = 0;
956 }
957 mutex_unlock(&go->hw_lock);
958 mutex_unlock(&gofh->lock);
959
960 return retval;
961}
962
963static int vidioc_streamoff(struct file *file, void *priv,
964 enum v4l2_buf_type type)
965{
966 struct go7007_file *gofh = priv;
967 struct go7007 *go = gofh->go;
968
969 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
970 return -EINVAL;
971 mutex_lock(&gofh->lock);
972 go7007_streamoff(go);
973 mutex_unlock(&gofh->lock);
974
975 return 0;
976}
977
978static int vidioc_queryctrl(struct file *file, void *priv,
979 struct v4l2_queryctrl *query)
980{
981 struct go7007 *go = ((struct go7007_file *) priv)->go;
982 int id = query->id;
983
984 if (0 == call_all(&go->v4l2_dev, core, queryctrl, query))
985 return 0;
986
987 query->id = id;
988 return mpeg_query_ctrl(query);
989}
990
991static int vidioc_g_ctrl(struct file *file, void *priv,
992 struct v4l2_control *ctrl)
993{
994 struct go7007 *go = ((struct go7007_file *) priv)->go;
995
996 if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl))
997 return 0;
998
999 return mpeg_g_ctrl(ctrl, go);
1000}
1001
1002static int vidioc_s_ctrl(struct file *file, void *priv,
1003 struct v4l2_control *ctrl)
1004{
1005 struct go7007 *go = ((struct go7007_file *) priv)->go;
1006
1007 if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl))
1008 return 0;
1009
1010 return mpeg_s_ctrl(ctrl, go);
1011}
1012
1013static int vidioc_g_parm(struct file *filp, void *priv,
1014 struct v4l2_streamparm *parm)
1015{
1016 struct go7007 *go = ((struct go7007_file *) priv)->go;
1017 struct v4l2_fract timeperframe = {
1018 .numerator = 1001 * go->fps_scale,
1019 .denominator = go->sensor_framerate,
1020 };
1021
1022 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1023 return -EINVAL;
1024
1025 parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
1026 parm->parm.capture.timeperframe = timeperframe;
1027
1028 return 0;
1029}
1030
1031static int vidioc_s_parm(struct file *filp, void *priv,
1032 struct v4l2_streamparm *parm)
1033{
1034 struct go7007 *go = ((struct go7007_file *) priv)->go;
1035 unsigned int n, d;
1036
1037 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1038 return -EINVAL;
1039 if (parm->parm.capture.capturemode != 0)
1040 return -EINVAL;
1041
1042 n = go->sensor_framerate *
1043 parm->parm.capture.timeperframe.numerator;
1044 d = 1001 * parm->parm.capture.timeperframe.denominator;
1045 if (n != 0 && d != 0 && n > d)
1046 go->fps_scale = (n + d/2) / d;
1047 else
1048 go->fps_scale = 1;
1049
1050 return 0;
1051}
1052
1053/* VIDIOC_ENUMSTD on go7007 were used for enumberating the supported fps and
1054 its resolution, when the device is not connected to TV.
1055 This were an API abuse, probably used by the lack of specific IOCTL's to
1056 enumberate it, by the time the driver were written.
1057
1058 However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
1059 and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
1060
1061 The two functions bellow implements the newer ioctls
1062*/
1063static int vidioc_enum_framesizes(struct file *filp, void *priv,
1064 struct v4l2_frmsizeenum *fsize)
1065{
1066 struct go7007 *go = ((struct go7007_file *) priv)->go;
1067
1068 /* Return -EINVAL, if it is a TV board */
1069 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1070 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1071 return -EINVAL;
1072
1073 if (fsize->index > 0)
1074 return -EINVAL;
1075
1076 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1077 fsize->discrete.width = go->board_info->sensor_width;
1078 fsize->discrete.height = go->board_info->sensor_height;
1079
1080 return 0;
1081}
1082
1083static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1084 struct v4l2_frmivalenum *fival)
1085{
1086 struct go7007 *go = ((struct go7007_file *) priv)->go;
1087
1088 /* Return -EINVAL, if it is a TV board */
1089 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
1090 (go->board_info->sensor_flags & GO7007_SENSOR_TV))
1091 return -EINVAL;
1092
1093 if (fival->index > 0)
1094 return -EINVAL;
1095
1096 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1097 fival->discrete.numerator = 1001;
1098 fival->discrete.denominator = go->board_info->sensor_framerate;
1099
1100 return 0;
1101}
1102
1103static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1104{
1105 struct go7007 *go = ((struct go7007_file *) priv)->go;
1106
1107 switch (go->standard) {
1108 case GO7007_STD_NTSC:
1109 *std = V4L2_STD_NTSC;
1110 break;
1111 case GO7007_STD_PAL:
1112 *std = V4L2_STD_PAL;
1113 break;
1114 default:
1115 return -EINVAL;
1116 }
1117
1118 return 0;
1119}
1120
1121static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1122{
1123 struct go7007 *go = ((struct go7007_file *) priv)->go;
1124
1125 if (go->streaming)
1126 return -EBUSY;
1127
1128 if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0)
1129 return -EINVAL;
1130
1131 if (*std == 0)
1132 return -EINVAL;
1133
1134 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1135 go->input == go->board_info->num_inputs - 1) {
1136 if (!go->i2c_adapter_online)
1137 return -EIO;
1138 if (call_all(&go->v4l2_dev, core, s_std, *std) < 0)
1139 return -EINVAL;
1140 }
1141
1142 if (*std & V4L2_STD_NTSC) {
1143 go->standard = GO7007_STD_NTSC;
1144 go->sensor_framerate = 30000;
1145 } else if (*std & V4L2_STD_PAL) {
1146 go->standard = GO7007_STD_PAL;
1147 go->sensor_framerate = 25025;
1148 } else if (*std & V4L2_STD_SECAM) {
1149 go->standard = GO7007_STD_PAL;
1150 go->sensor_framerate = 25025;
1151 } else
1152 return -EINVAL;
1153
1154 call_all(&go->v4l2_dev, core, s_std, *std);
1155 set_capture_size(go, NULL, 0);
1156
1157 return 0;
1158}
1159
1160static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1161{
1162 struct go7007 *go = ((struct go7007_file *) priv)->go;
1163
1164 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1165 go->input == go->board_info->num_inputs - 1) {
1166 if (!go->i2c_adapter_online)
1167 return -EIO;
1168 return call_all(&go->v4l2_dev, video, querystd, std);
1169 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1170 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1171 else
1172 *std = 0;
1173
1174 return 0;
1175}
1176
1177static int vidioc_enum_input(struct file *file, void *priv,
1178 struct v4l2_input *inp)
1179{
1180 struct go7007 *go = ((struct go7007_file *) priv)->go;
1181
1182 if (inp->index >= go->board_info->num_inputs)
1183 return -EINVAL;
1184
1185 strncpy(inp->name, go->board_info->inputs[inp->index].name,
1186 sizeof(inp->name));
1187
1188 /* If this board has a tuner, it will be the last input */
1189 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1190 inp->index == go->board_info->num_inputs - 1)
1191 inp->type = V4L2_INPUT_TYPE_TUNER;
1192 else
1193 inp->type = V4L2_INPUT_TYPE_CAMERA;
1194
1195 inp->audioset = 0;
1196 inp->tuner = 0;
1197 if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1198 inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
1199 V4L2_STD_SECAM;
1200 else
1201 inp->std = 0;
1202
1203 return 0;
1204}
1205
1206
1207static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1208{
1209 struct go7007 *go = ((struct go7007_file *) priv)->go;
1210
1211 *input = go->input;
1212
1213 return 0;
1214}
1215
1216static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1217{
1218 struct go7007 *go = ((struct go7007_file *) priv)->go;
1219
1220 if (input >= go->board_info->num_inputs)
1221 return -EINVAL;
1222 if (go->streaming)
1223 return -EBUSY;
1224
1225 go->input = input;
1226
1227 return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0);
1228}
1229
1230static int vidioc_g_tuner(struct file *file, void *priv,
1231 struct v4l2_tuner *t)
1232{
1233 struct go7007 *go = ((struct go7007_file *) priv)->go;
1234
1235 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1236 return -EINVAL;
1237 if (t->index != 0)
1238 return -EINVAL;
1239 if (!go->i2c_adapter_online)
1240 return -EIO;
1241
1242 return call_all(&go->v4l2_dev, tuner, g_tuner, t);
1243}
1244
1245static int vidioc_s_tuner(struct file *file, void *priv,
1246 struct v4l2_tuner *t)
1247{
1248 struct go7007 *go = ((struct go7007_file *) priv)->go;
1249
1250 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1251 return -EINVAL;
1252 if (t->index != 0)
1253 return -EINVAL;
1254 if (!go->i2c_adapter_online)
1255 return -EIO;
1256
1257 switch (go->board_id) {
1258 case GO7007_BOARDID_PX_TV402U_NA:
1259 case GO7007_BOARDID_PX_TV402U_JP:
1260 /* No selectable options currently */
1261 if (t->audmode != V4L2_TUNER_MODE_STEREO)
1262 return -EINVAL;
1263 break;
1264 }
1265
1266 return call_all(&go->v4l2_dev, tuner, s_tuner, t);
1267}
1268
1269static int vidioc_g_frequency(struct file *file, void *priv,
1270 struct v4l2_frequency *f)
1271{
1272 struct go7007 *go = ((struct go7007_file *) priv)->go;
1273
1274 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1275 return -EINVAL;
1276 if (!go->i2c_adapter_online)
1277 return -EIO;
1278
1279 f->type = V4L2_TUNER_ANALOG_TV;
1280
1281 return call_all(&go->v4l2_dev, tuner, g_frequency, f);
1282}
1283
1284static int vidioc_s_frequency(struct file *file, void *priv,
1285 struct v4l2_frequency *f)
1286{
1287 struct go7007 *go = ((struct go7007_file *) priv)->go;
1288
1289 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1290 return -EINVAL;
1291 if (!go->i2c_adapter_online)
1292 return -EIO;
1293
1294 return call_all(&go->v4l2_dev, tuner, s_frequency, f);
1295}
1296
1297static int vidioc_cropcap(struct file *file, void *priv,
1298 struct v4l2_cropcap *cropcap)
1299{
1300 struct go7007 *go = ((struct go7007_file *) priv)->go;
1301
1302 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1303 return -EINVAL;
1304
1305 /* These specify the raw input of the sensor */
1306 switch (go->standard) {
1307 case GO7007_STD_NTSC:
1308 cropcap->bounds.top = 0;
1309 cropcap->bounds.left = 0;
1310 cropcap->bounds.width = 720;
1311 cropcap->bounds.height = 480;
1312 cropcap->defrect.top = 0;
1313 cropcap->defrect.left = 0;
1314 cropcap->defrect.width = 720;
1315 cropcap->defrect.height = 480;
1316 break;
1317 case GO7007_STD_PAL:
1318 cropcap->bounds.top = 0;
1319 cropcap->bounds.left = 0;
1320 cropcap->bounds.width = 720;
1321 cropcap->bounds.height = 576;
1322 cropcap->defrect.top = 0;
1323 cropcap->defrect.left = 0;
1324 cropcap->defrect.width = 720;
1325 cropcap->defrect.height = 576;
1326 break;
1327 case GO7007_STD_OTHER:
1328 cropcap->bounds.top = 0;
1329 cropcap->bounds.left = 0;
1330 cropcap->bounds.width = go->board_info->sensor_width;
1331 cropcap->bounds.height = go->board_info->sensor_height;
1332 cropcap->defrect.top = 0;
1333 cropcap->defrect.left = 0;
1334 cropcap->defrect.width = go->board_info->sensor_width;
1335 cropcap->defrect.height = go->board_info->sensor_height;
1336 break;
1337 }
1338
1339 return 0;
1340}
1341
1342static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1343{
1344 struct go7007 *go = ((struct go7007_file *) priv)->go;
1345
1346 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1347 return -EINVAL;
1348
1349 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1350
1351 /* These specify the raw input of the sensor */
1352 switch (go->standard) {
1353 case GO7007_STD_NTSC:
1354 crop->c.top = 0;
1355 crop->c.left = 0;
1356 crop->c.width = 720;
1357 crop->c.height = 480;
1358 break;
1359 case GO7007_STD_PAL:
1360 crop->c.top = 0;
1361 crop->c.left = 0;
1362 crop->c.width = 720;
1363 crop->c.height = 576;
1364 break;
1365 case GO7007_STD_OTHER:
1366 crop->c.top = 0;
1367 crop->c.left = 0;
1368 crop->c.width = go->board_info->sensor_width;
1369 crop->c.height = go->board_info->sensor_height;
1370 break;
1371 }
1372
1373 return 0;
1374}
1375
1376/* FIXME: vidioc_s_crop is not really implemented!!!
1377 */
1378static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1379{
1380 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1381 return -EINVAL;
1382
1383 return 0;
1384}
1385
1386static int vidioc_g_jpegcomp(struct file *file, void *priv,
1387 struct v4l2_jpegcompression *params)
1388{
1389 memset(params, 0, sizeof(*params));
1390 params->quality = 50; /* ?? */
1391 params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
1392 V4L2_JPEG_MARKER_DQT;
1393
1394 return 0;
1395}
1396
1397static int vidioc_s_jpegcomp(struct file *file, void *priv,
1398 struct v4l2_jpegcompression *params)
1399{
1400 if (params->quality != 50 ||
1401 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
1402 V4L2_JPEG_MARKER_DQT))
1403 return -EINVAL;
1404
1405 return 0;
1406}
1407
1408/* FIXME:
1409 Those ioctls are private, and not needed, since several standard
1410 extended controls already provide streaming control.
1411 So, those ioctls should be converted into vidioc_g_ext_ctrls()
1412 and vidioc_s_ext_ctrls()
1413 */
1414
1415#if 0
1416 /* Temporary ioctls for controlling compression characteristics */
1417 case GO7007IOC_S_BITRATE:
1418 {
1419 int *bitrate = arg;
1420
1421 if (go->streaming)
1422 return -EINVAL;
1423 /* Upper bound is kind of arbitrary here */
1424 if (*bitrate < 64000 || *bitrate > 10000000)
1425 return -EINVAL;
1426 go->bitrate = *bitrate;
1427 return 0;
1428 }
1429 case GO7007IOC_G_BITRATE:
1430 {
1431 int *bitrate = arg;
1432
1433 *bitrate = go->bitrate;
1434 return 0;
1435 }
1436 case GO7007IOC_S_COMP_PARAMS:
1437 {
1438 struct go7007_comp_params *comp = arg;
1439
1440 if (go->format == GO7007_FORMAT_MJPEG)
1441 return -EINVAL;
1442 if (comp->gop_size > 0)
1443 go->gop_size = comp->gop_size;
1444 else
1445 go->gop_size = go->sensor_framerate / 1000;
1446 if (go->gop_size != 15)
1447 go->dvd_mode = 0;
1448 /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
1449 if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
1450 switch (comp->aspect_ratio) {
1451 case GO7007_ASPECT_RATIO_4_3_NTSC:
1452 case GO7007_ASPECT_RATIO_4_3_PAL:
1453 go->aspect_ratio = GO7007_RATIO_4_3;
1454 break;
1455 case GO7007_ASPECT_RATIO_16_9_NTSC:
1456 case GO7007_ASPECT_RATIO_16_9_PAL:
1457 go->aspect_ratio = GO7007_RATIO_16_9;
1458 break;
1459 default:
1460 go->aspect_ratio = GO7007_RATIO_1_1;
1461 break;
1462 }
1463 }
1464 if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
1465 go->dvd_mode = 0;
1466 go->seq_header_enable = 0;
1467 } else {
1468 go->seq_header_enable = 1;
1469 }
1470 /* fall-through */
1471 }
1472 case GO7007IOC_G_COMP_PARAMS:
1473 {
1474 struct go7007_comp_params *comp = arg;
1475
1476 if (go->format == GO7007_FORMAT_MJPEG)
1477 return -EINVAL;
1478 memset(comp, 0, sizeof(*comp));
1479 comp->gop_size = go->gop_size;
1480 comp->max_b_frames = go->ipb ? 2 : 0;
1481 switch (go->aspect_ratio) {
1482 case GO7007_RATIO_4_3:
1483 if (go->standard == GO7007_STD_NTSC)
1484 comp->aspect_ratio =
1485 GO7007_ASPECT_RATIO_4_3_NTSC;
1486 else
1487 comp->aspect_ratio =
1488 GO7007_ASPECT_RATIO_4_3_PAL;
1489 break;
1490 case GO7007_RATIO_16_9:
1491 if (go->standard == GO7007_STD_NTSC)
1492 comp->aspect_ratio =
1493 GO7007_ASPECT_RATIO_16_9_NTSC;
1494 else
1495 comp->aspect_ratio =
1496 GO7007_ASPECT_RATIO_16_9_PAL;
1497 break;
1498 default:
1499 comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
1500 break;
1501 }
1502 if (go->closed_gop)
1503 comp->flags |= GO7007_COMP_CLOSED_GOP;
1504 if (!go->seq_header_enable)
1505 comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
1506 return 0;
1507 }
1508 case GO7007IOC_S_MPEG_PARAMS:
1509 {
1510 struct go7007_mpeg_params *mpeg = arg;
1511
1512 if (go->format != GO7007_FORMAT_MPEG1 &&
1513 go->format != GO7007_FORMAT_MPEG2 &&
1514 go->format != GO7007_FORMAT_MPEG4)
1515 return -EINVAL;
1516
1517 if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
1518 go->format = GO7007_FORMAT_MPEG2;
1519 go->bitrate = 9800000;
1520 go->gop_size = 15;
1521 go->pali = 0x48;
1522 go->closed_gop = 1;
1523 go->repeat_seqhead = 0;
1524 go->seq_header_enable = 1;
1525 go->gop_header_enable = 1;
1526 go->dvd_mode = 1;
1527 } else {
1528 switch (mpeg->mpeg_video_standard) {
1529 case GO7007_MPEG_VIDEO_MPEG1:
1530 go->format = GO7007_FORMAT_MPEG1;
1531 go->pali = 0;
1532 break;
1533 case GO7007_MPEG_VIDEO_MPEG2:
1534 go->format = GO7007_FORMAT_MPEG2;
1535 if (mpeg->pali >> 24 == 2)
1536 go->pali = mpeg->pali & 0xff;
1537 else
1538 go->pali = 0x48;
1539 break;
1540 case GO7007_MPEG_VIDEO_MPEG4:
1541 go->format = GO7007_FORMAT_MPEG4;
1542 if (mpeg->pali >> 24 == 4)
1543 go->pali = mpeg->pali & 0xff;
1544 else
1545 go->pali = 0xf5;
1546 break;
1547 default:
1548 return -EINVAL;
1549 }
1550 go->gop_header_enable =
1551 mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
1552 ? 0 : 1;
1553 if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
1554 go->repeat_seqhead = 1;
1555 else
1556 go->repeat_seqhead = 0;
1557 go->dvd_mode = 0;
1558 }
1559 /* fall-through */
1560 }
1561 case GO7007IOC_G_MPEG_PARAMS:
1562 {
1563 struct go7007_mpeg_params *mpeg = arg;
1564
1565 memset(mpeg, 0, sizeof(*mpeg));
1566 switch (go->format) {
1567 case GO7007_FORMAT_MPEG1:
1568 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
1569 mpeg->pali = 0;
1570 break;
1571 case GO7007_FORMAT_MPEG2:
1572 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
1573 mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
1574 break;
1575 case GO7007_FORMAT_MPEG4:
1576 mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
1577 mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
1578 break;
1579 default:
1580 return -EINVAL;
1581 }
1582 if (!go->gop_header_enable)
1583 mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
1584 if (go->repeat_seqhead)
1585 mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
1586 if (go->dvd_mode)
1587 mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
1588 return 0;
1589 }
1590 case GO7007IOC_S_MD_PARAMS:
1591 {
1592 struct go7007_md_params *mdp = arg;
1593
1594 if (mdp->region > 3)
1595 return -EINVAL;
1596 if (mdp->trigger > 0) {
1597 go->modet[mdp->region].pixel_threshold =
1598 mdp->pixel_threshold >> 1;
1599 go->modet[mdp->region].motion_threshold =
1600 mdp->motion_threshold >> 1;
1601 go->modet[mdp->region].mb_threshold =
1602 mdp->trigger >> 1;
1603 go->modet[mdp->region].enable = 1;
1604 } else
1605 go->modet[mdp->region].enable = 0;
1606 /* fall-through */
1607 }
1608 case GO7007IOC_G_MD_PARAMS:
1609 {
1610 struct go7007_md_params *mdp = arg;
1611 int region = mdp->region;
1612
1613 if (mdp->region > 3)
1614 return -EINVAL;
1615 memset(mdp, 0, sizeof(struct go7007_md_params));
1616 mdp->region = region;
1617 if (!go->modet[region].enable)
1618 return 0;
1619 mdp->pixel_threshold =
1620 (go->modet[region].pixel_threshold << 1) + 1;
1621 mdp->motion_threshold =
1622 (go->modet[region].motion_threshold << 1) + 1;
1623 mdp->trigger =
1624 (go->modet[region].mb_threshold << 1) + 1;
1625 return 0;
1626 }
1627 case GO7007IOC_S_MD_REGION:
1628 {
1629 struct go7007_md_region *region = arg;
1630
1631 if (region->region < 1 || region->region > 3)
1632 return -EINVAL;
1633 return clip_to_modet_map(go, region->region, region->clips);
1634 }
1635#endif
1636
1637static ssize_t go7007_read(struct file *file, char __user *data,
1638 size_t count, loff_t *ppos)
1639{
1640 return -EINVAL;
1641}
1642
1643static void go7007_vm_open(struct vm_area_struct *vma)
1644{
1645 struct go7007_buffer *gobuf = vma->vm_private_data;
1646
1647 ++gobuf->mapped;
1648}
1649
1650static void go7007_vm_close(struct vm_area_struct *vma)
1651{
1652 struct go7007_buffer *gobuf = vma->vm_private_data;
1653 unsigned long flags;
1654
1655 if (--gobuf->mapped == 0) {
1656 spin_lock_irqsave(&gobuf->go->spinlock, flags);
1657 deactivate_buffer(gobuf);
1658 spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
1659 }
1660}
1661
1662/* Copied from videobuf-dma-sg.c */
1663static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1664{
1665 struct page *page;
1666
1667 page = alloc_page(GFP_USER | __GFP_DMA32);
1668 if (!page)
1669 return VM_FAULT_OOM;
1670 clear_user_highpage(page, (unsigned long)vmf->virtual_address);
1671 vmf->page = page;
1672 return 0;
1673}
1674
1675static struct vm_operations_struct go7007_vm_ops = {
1676 .open = go7007_vm_open,
1677 .close = go7007_vm_close,
1678 .fault = go7007_vm_fault,
1679};
1680
1681static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1682{
1683 struct go7007_file *gofh = file->private_data;
1684 unsigned int index;
1685
1686 if (gofh->go->status != STATUS_ONLINE)
1687 return -EIO;
1688 if (!(vma->vm_flags & VM_SHARED))
1689 return -EINVAL; /* only support VM_SHARED mapping */
1690 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1691 return -EINVAL; /* must map exactly one full buffer */
1692 mutex_lock(&gofh->lock);
1693 index = vma->vm_pgoff / GO7007_BUF_PAGES;
1694 if (index >= gofh->buf_count) {
1695 mutex_unlock(&gofh->lock);
1696 return -EINVAL; /* trying to map beyond requested buffers */
1697 }
1698 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1699 mutex_unlock(&gofh->lock);
1700 return -EINVAL; /* offset is not aligned on buffer boundary */
1701 }
1702 if (gofh->bufs[index].mapped > 0) {
1703 mutex_unlock(&gofh->lock);
1704 return -EBUSY;
1705 }
1706 gofh->bufs[index].mapped = 1;
1707 gofh->bufs[index].user_addr = vma->vm_start;
1708 vma->vm_ops = &go7007_vm_ops;
1709 vma->vm_flags |= VM_DONTEXPAND;
1710 vma->vm_flags &= ~VM_IO;
1711 vma->vm_private_data = &gofh->bufs[index];
1712 mutex_unlock(&gofh->lock);
1713 return 0;
1714}
1715
1716static unsigned int go7007_poll(struct file *file, poll_table *wait)
1717{
1718 struct go7007_file *gofh = file->private_data;
1719 struct go7007_buffer *gobuf;
1720
1721 if (list_empty(&gofh->go->stream))
1722 return POLLERR;
1723 gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
1724 poll_wait(file, &gofh->go->frame_waitq, wait);
1725 if (gobuf->state == BUF_STATE_DONE)
1726 return POLLIN | POLLRDNORM;
1727 return 0;
1728}
1729
1730static void go7007_vfl_release(struct video_device *vfd)
1731{
1732 struct go7007 *go = video_get_drvdata(vfd);
1733
1734 video_device_release(vfd);
1735 if (--go->ref_count == 0)
1736 kfree(go);
1737}
1738
1739static struct v4l2_file_operations go7007_fops = {
1740 .owner = THIS_MODULE,
1741 .open = go7007_open,
1742 .release = go7007_release,
1743 .ioctl = video_ioctl2,
1744 .read = go7007_read,
1745 .mmap = go7007_mmap,
1746 .poll = go7007_poll,
1747};
1748
1749static const struct v4l2_ioctl_ops video_ioctl_ops = {
1750 .vidioc_querycap = vidioc_querycap,
1751 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1752 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1753 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1754 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1755 .vidioc_reqbufs = vidioc_reqbufs,
1756 .vidioc_querybuf = vidioc_querybuf,
1757 .vidioc_qbuf = vidioc_qbuf,
1758 .vidioc_dqbuf = vidioc_dqbuf,
1759 .vidioc_g_std = vidioc_g_std,
1760 .vidioc_s_std = vidioc_s_std,
1761 .vidioc_querystd = vidioc_querystd,
1762 .vidioc_enum_input = vidioc_enum_input,
1763 .vidioc_g_input = vidioc_g_input,
1764 .vidioc_s_input = vidioc_s_input,
1765 .vidioc_queryctrl = vidioc_queryctrl,
1766 .vidioc_g_ctrl = vidioc_g_ctrl,
1767 .vidioc_s_ctrl = vidioc_s_ctrl,
1768 .vidioc_streamon = vidioc_streamon,
1769 .vidioc_streamoff = vidioc_streamoff,
1770 .vidioc_g_tuner = vidioc_g_tuner,
1771 .vidioc_s_tuner = vidioc_s_tuner,
1772 .vidioc_g_frequency = vidioc_g_frequency,
1773 .vidioc_s_frequency = vidioc_s_frequency,
1774 .vidioc_g_parm = vidioc_g_parm,
1775 .vidioc_s_parm = vidioc_s_parm,
1776 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1777 .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1778 .vidioc_cropcap = vidioc_cropcap,
1779 .vidioc_g_crop = vidioc_g_crop,
1780 .vidioc_s_crop = vidioc_s_crop,
1781 .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
1782 .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
1783};
1784
1785static struct video_device go7007_template = {
1786 .name = "go7007",
1787 .fops = &go7007_fops,
1788 .release = go7007_vfl_release,
1789 .ioctl_ops = &video_ioctl_ops,
1790 .tvnorms = V4L2_STD_ALL,
1791 .current_norm = V4L2_STD_NTSC,
1792};
1793
1794int go7007_v4l2_init(struct go7007 *go)
1795{
1796 int rv;
1797
1798 go->video_dev = video_device_alloc();
1799 if (go->video_dev == NULL)
1800 return -ENOMEM;
1801 *go->video_dev = go7007_template;
1802 go->video_dev->parent = go->dev;
1803 rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
1804 if (rv < 0) {
1805 video_device_release(go->video_dev);
1806 go->video_dev = NULL;
1807 return rv;
1808 }
1809 rv = v4l2_device_register(go->dev, &go->v4l2_dev);
1810 if (rv < 0) {
1811 video_device_release(go->video_dev);
1812 go->video_dev = NULL;
1813 return rv;
1814 }
1815 video_set_drvdata(go->video_dev, go);
1816 ++go->ref_count;
1817 printk(KERN_INFO "%s: registered device %s [v4l2]\n",
1818 go->video_dev->name, video_device_node_name(go->video_dev));
1819
1820 return 0;
1821}
1822
1823void go7007_v4l2_remove(struct go7007 *go)
1824{
1825 unsigned long flags;
1826
1827 mutex_lock(&go->hw_lock);
1828 if (go->streaming) {
1829 go->streaming = 0;
1830 go7007_stream_stop(go);
1831 spin_lock_irqsave(&go->spinlock, flags);
1832 abort_queued(go);
1833 spin_unlock_irqrestore(&go->spinlock, flags);
1834 }
1835 mutex_unlock(&go->hw_lock);
1836 if (go->video_dev)
1837 video_unregister_device(go->video_dev);
1838 v4l2_device_unregister(&go->v4l2_dev);
1839}
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/go7007.txt b/drivers/staging/go7007/go7007.txt
new file mode 100644
index 00000000000..9db1f3952fd
--- /dev/null
+++ b/drivers/staging/go7007/go7007.txt
@@ -0,0 +1,481 @@
1This is a driver for the WIS GO7007SB multi-format video encoder.
2
3Pete Eberlein <pete@sensoray.com>
4
5The driver was originally released under the GPL and is currently hosted at:
6http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver
7The go7007 firmware can be acquired from the package on the site above.
8
9I've modified the driver to support the following Video4Linux2 MPEG
10controls, with acceptable values:
11
12V4L2_CID_MPEG_STREAM_TYPE V4L2_MPEG_STREAM_TYPE_MPEG2_DVD
13 V4L2_MPEG_STREAM_TYPE_MPEG_ELEM
14V4L2_CID_MPEG_VIDEO_ENCODING V4L2_MPEG_VIDEO_ENCODING_MPEG_1
15 V4L2_MPEG_VIDEO_ENCODING_MPEG_2
16 V4L2_MPEG_VIDEO_ENCODING_MPEG_4
17V4L2_CID_MPEG_VIDEO_ASPECT V4L2_MPEG_VIDEO_ASPECT_1x1
18 V4L2_MPEG_VIDEO_ASPECT_4x3
19 V4L2_MPEG_VIDEO_ASPECT_16x9
20V4L2_CID_MPEG_VIDEO_GOP_SIZE integer
21V4L2_CID_MPEG_VIDEO_BITRATE 64000 .. 10000000
22
23These should be used instead of the non-standard GO7007 ioctls described
24below.
25
26
27The README files from the orignal package appear below:
28
29---------------------------------------------------------------------------
30 WIS GO7007SB Public Linux Driver
31---------------------------------------------------------------------------
32
33
34*** Please see the file RELEASE-NOTES for important last-minute updates ***
35
36
37 0. OVERVIEW AND LICENSING/DISCLAIMER
38
39
40This driver kit contains Linux drivers for the WIS GO7007SB multi-format
41video encoder. Only kernel version 2.6.x is supported. The video stream
42is available through the Video4Linux2 API and the audio stream is available
43through the ALSA API (or the OSS emulation layer of the ALSA system).
44
45The files in kernel/ and hotplug/ are licensed under the GNU General Public
46License Version 2 from the Free Software Foundation. A copy of the license
47is included in the file COPYING.
48
49The example applications in apps/ and C header files in include/ are
50licensed under a permissive license included in the source files which
51allows copying, modification and redistribution for any purpose without
52attribution.
53
54The firmware files included in the firmware/ directory may be freely
55redistributed only in conjunction with this document; but modification,
56tampering and reverse engineering are prohibited.
57
58MICRONAS USA, INC., MAKES NO WARRANTIES TO ANY PERSON OR ENTITY WITH
59RESPECT TO THE SOFTWARE OR ANY DERIVATIVES THEREOF OR ANY SERVICES OR
60LICENSES AND DISCLAIMS ALL IMPLIED WARRANTIES, INCLUDING WITHOUT LIMITATION
61WARRANTIES OF MERCHANTABILITY, SUPPORT, AND FITNESS FOR A PARTICULAR
62PURPOSE AND NON-INFRINGEMENT.
63
64
65 1. SYSTEM REQUIREMENTS
66
67
68This driver requires Linux kernel 2.6. Kernel 2.4 is not supported. Using
69kernel 2.6.10 or later is recommended, as earlier kernels are known to have
70unstable USB 2.0 support.
71
72A fully built kernel source tree must be available. Typically this will be
73linked from "/lib/modules/<KERNEL VERSION>/build" for convenience. If this
74link does not exist, an extra parameter will need to be passed to the
75`make` command.
76
77All vendor-built kernels should already be configured properly. However,
78for custom-built kernels, the following options need to be enabled in the
79kernel as built-in or modules:
80
81 CONFIG_HOTPLUG - Support for hot-pluggable devices
82 CONFIG_MODULES - Enable loadable module support
83 CONFIG_KMOD - Automatic kernel module loading
84 CONFIG_FW_LOADER - Hotplug firmware loading support
85 CONFIG_I2C - I2C support
86 CONFIG_VIDEO_DEV - Video For Linux
87 CONFIG_SOUND - Sound card support
88 CONFIG_SND - Advanced Linux Sound Architecture
89 CONFIG_USB - Support for Host-side USB
90 CONFIG_USB_DEVICEFS - USB device filesystem
91 CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support
92
93Additionally, to use the example application, the following options need to
94be enabled in the ALSA section:
95
96 CONFIG_SND_MIXER_OSS - OSS Mixer API
97 CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API
98
99The hotplug scripts, along with the fxload utility, must also be installed.
100These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>.
101Hotplugging is used for loading firmware into the Cypruss EZ-USB chip using
102fxload and for loading firmware into the driver using the firmware agent.
103
104
105 2. COMPILING AND INSTALLING THE DRIVER
106
107
108Most users should be able to compile the driver by simply running:
109
110 $ make
111
112in the top-level directory of the driver kit. First the kernel modules
113will be built, followed by the example applications.
114
115If the build system is unable to locate the kernel source tree for the
116currently-running kernel, or if the module should be built for a kernel
117other than the currently-running kernel, an additional parameter will need
118to be passed to make to specify the appropriate kernel source directory:
119
120 $ make KERNELSRC=/usr/src/linux-2.6.10-custom3
121
122Once the compile completes, the driver and firmware files should be
123installed by running:
124
125 $ make install
126
127The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra"
128and the firmware files will be placed in the appropriate hotplug firmware
129directory, usually /lib/firmware. In addition, USB maps and scripts will
130be placed in /etc/hotplug/usb to enable fxload to initialize the EZ-USB
131control chip when the device is connected.
132
133
134 3. PAL/SECAM TUNER CONFIGURATION (TV402U-EU only)
135
136
137The PAL model of the Plextor ConvertX TV402U may require additional
138configuration to correctly select the appropriate TV frequency band and
139audio subchannel.
140
141Users with a device other than the Plextor ConvertX TV402U-EU should skip
142this section.
143
144The wide variety of PAL TV systems used in Europe requires that additional
145information about the local TV standards be passed to the driver in order
146to properly tune TV channels. The two necessary parameters are (a) the PAL
147TV band, and (b) the audio subchannel format in use.
148
149In many cases, the appropriate TV band selection is passed to the driver
150from applications. However, in some cases, the application only specifies
151that the driver should use PAL but not the specific information about the
152appropriate TV band. To work around this issue, the correct TV band may be
153specified in the "force_band" parameter to the wis-sony-tuner module:
154
155 TV band force_band
156 ------- ----------
157 PAL B/G B
158 PAL I I
159 PAL D/K D
160 SECAM L L
161
162If the "force_band" parameter is specified, the driver will ignore any TV
163band specified by applications and will always use the band provided in the
164module parameter.
165
166The other parameter that can be specified is the audio subchannel format.
167There are several stereo audio carrier systems in use, including NICAM and
168three varieties of A2. To receive audio broadcast on one of these stereo
169carriers, the "force_mpx_mode" parameter must be specified to the
170wis-sony-tuner module.
171
172 TV band Audio subcarrier force_mpx_mode
173 ------- ---------------- --------------
174 PAL B/G Mono (default) 1
175 PAL B/G A2 2
176 PAL B/G NICAM 3
177 PAL I Mono (default) 4
178 PAL I NICAM 5
179 PAL D/K Mono (default) 6
180 PAL D/K A2 (1) 7
181 PAL D/K A2 (2) 8
182 PAL D/K A2 (3) 9
183 PAL D/K NICAM 10
184 SECAM L Mono (default) 11
185 SECAM L NICAM 12
186
187If the "force_mpx_mode" parameter is not specified, the correct mono-only
188mode will be chosen based on the TV band. However, the tuner will not
189receive stereo audio or bilingual broadcasts correctly.
190
191To pass the "force_band" or "force_mpx_mode" parameters to the
192wis-sony-tuner module, the following line must be added to the modprobe
193configuration file, which varies from one Linux distribution to another.
194
195 options wis-sony-tuner force_band=B force_mpx_mode=2
196
197The above example would force the tuner to the PAL B/G TV band and receive
198stereo audio broadcasts on the A2 carrier.
199
200To verify that the configuration has been placed in the correct location,
201execute:
202
203 $ modprobe -c | grep wis-sony-tuner
204
205If the configuration line appears, then modprobe will pass the parameters
206correctly the next time the wis-sony-tuner module is loaded into the
207kernel.
208
209
210 4. TESTING THE DRIVER
211
212
213Because few Linux applications are able to correctly capture from
214Video4Linux2 devices with only compressed formats supported, the new driver
215should be tested with the "gorecord" application in the apps/ directory.
216
217First connect a video source to the device, such as a DVD player or VCR.
218This will be captured to a file for testing the driver. If an input source
219is unavailable, a test file can still be captured, but the video will be
220black and the audio will be silent.
221
222This application will auto-detect the V4L2 and ALSA/OSS device names of the
223hardware and will record video and audio to an AVI file for a specified
224number of seconds. For example:
225
226 $ apps/gorecord -duration 60 capture.avi
227
228If this application does not successfully record an AVI file, the error
229messages produced by gorecord and recorded in the system log (usually in
230/var/log/messages) should provide information to help resolve the problem.
231
232Supplying no parameters to gorecord will cause it to probe the available
233devices and exit. Use the -help flag for usage information.
234
235
236 5. USING THE DRIVER
237
238
239The V4L2 device implemented by the driver provides a standard compressed
240format API, within the following criteria:
241
242 * Applications that only support the original Video4Linux1 API will not
243 be able to communicate with this driver at all.
244
245 * No raw video modes are supported, so applications like xawtv that
246 expect only uncompressed video will not function.
247
248 * Supported compression formats are: Motion-JPEG, MPEG1, MPEG2 and MPEG4.
249
250 * MPEG video formats are delivered as Video Elementary Streams only.
251 Program Stream (PS), Transport Stream (TS) and Packetized Elementary
252 Stream (PES) formats are not supported.
253
254 * Video parameters such as format and input port may not be changed while
255 the encoder is active.
256
257 * The audio capture device only functions when the video encoder is
258 actively capturing video. Attempts to read from the audio device when
259 the encoder is inactive will result in an I/O error.
260
261 * The native format of the audio device is 48Khz 2-channel 16-bit
262 little-endian PCM, delivered through the ALSA system. No audio
263 compression is implemented in the hardware. ALSA may convert to other
264 uncompressed formats on the fly.
265
266The include/ directory contains a C header file describing non-standard
267features of the GO7007SB encoder, which are described below:
268
269
270 GO7007IOC_S_COMP_PARAMS, GO7007IOC_G_COMP_PARAMS
271
272 These ioctls are used to negotiate general compression parameters.
273
274 To query the current parameters, call the GO7007IOC_G_COMP_PARAMS ioctl
275 with a pointer to a struct go7007_comp_params. If the driver is not
276 set to MPEG format, the EINVAL error code will be returned.
277
278 To change the current parameters, initialize all fields of a struct
279 go7007_comp_params and call the GO7007_IOC_S_COMP_PARAMS ioctl with a
280 pointer to this structure. The driver will return the current
281 parameters with any necessary changes to conform to the limitations of
282 the hardware or current compression mode. Any or all fields can be set
283 to zero to request a reasonable default value. If the driver is not
284 set to MPEG format, the EINVAL error code will be returned. When I/O
285 is in progress, the EBUSY error code will be returned.
286
287 Fields in struct go7007_comp_params:
288
289 __u32 The maximum number of frames in each
290 gop_size Group Of Pictures; i.e. the maximum
291 number of frames minus one between
292 each key frame.
293
294 __u32 The maximum number of sequential
295 max_b_frames bidirectionally-predicted frames.
296 (B-frames are not yet supported.)
297
298 enum go7007_aspect_ratio The aspect ratio to be encoded in the
299 aspect_ratio meta-data of the compressed format.
300
301 Choices are:
302 GO7007_ASPECT_RATIO_1_1
303 GO7007_ASPECT_RATIO_4_3_NTSC
304 GO7007_ASPECT_RATIO_4_3_PAL
305 GO7007_ASPECT_RATIO_16_9_NTSC
306 GO7007_ASPECT_RATIO_16_9_PAL
307
308 __u32 Bit-wise OR of control flags (below)
309 flags
310
311 Flags in struct go7007_comp_params:
312
313 GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used
314 to produce streams appropriate for
315 random seeking.
316
317 GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header.
318
319
320 GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS
321
322 These ioctls are used to negotiate MPEG-specific stream parameters when
323 the pixelformat has been set to V4L2_PIX_FMT_MPEG.
324
325 To query the current parameters, call the GO7007IOC_G_MPEG_PARAMS ioctl
326 with a pointer to a struct go7007_mpeg_params. If the driver is not
327 set to MPEG format, the EINVAL error code will be returned.
328
329 To change the current parameters, initialize all fields of a struct
330 go7007_mpeg_params and call the GO7007_IOC_S_MPEG_PARAMS ioctl with a
331 pointer to this structure. The driver will return the current
332 parameters with any necessary changes to conform to the limitations of
333 the hardware or selected MPEG mode. Any or all fields can be set to
334 zero to request a reasonable default value. If the driver is not set
335 to MPEG format, the EINVAL error code will be returned. When I/O is in
336 progress, the EBUSY error code will be returned.
337
338 Fields in struct go7007_mpeg_params:
339
340 enum go7007_mpeg_video_standard
341 mpeg_video_standard The MPEG video standard in which to
342 compress the video.
343
344 Choices are:
345 GO7007_MPEG_VIDEO_MPEG1
346 GO7007_MPEG_VIDEO_MPEG2
347 GO7007_MPEG_VIDEO_MPEG4
348
349 __u32 Bit-wise OR of control flags (below)
350 flags
351
352 __u32 The profile and level indication to be
353 pali stored in the sequence header. This
354 is only used as an indicator to the
355 decoder, and does not affect the MPEG
356 features used in the video stream.
357 Not valid for MPEG1.
358
359 Choices for MPEG2 are:
360 GO7007_MPEG2_PROFILE_MAIN_MAIN
361
362 Choices for MPEG4 are:
363 GO7007_MPEG4_PROFILE_S_L0
364 GO7007_MPEG4_PROFILE_S_L1
365 GO7007_MPEG4_PROFILE_S_L2
366 GO7007_MPEG4_PROFILE_S_L3
367 GO7007_MPEG4_PROFILE_ARTS_L1
368 GO7007_MPEG4_PROFILE_ARTS_L2
369 GO7007_MPEG4_PROFILE_ARTS_L3
370 GO7007_MPEG4_PROFILE_ARTS_L4
371 GO7007_MPEG4_PROFILE_AS_L0
372 GO7007_MPEG4_PROFILE_AS_L1
373 GO7007_MPEG4_PROFILE_AS_L2
374 GO7007_MPEG4_PROFILE_AS_L3
375 GO7007_MPEG4_PROFILE_AS_L4
376 GO7007_MPEG4_PROFILE_AS_L5
377
378 Flags in struct go7007_mpeg_params:
379
380 GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and
381 bitrate control settings to comply
382 with DVD MPEG2 stream requirements.
383 This overrides most compression and
384 bitrate settings!
385
386 GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header.
387
388 GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at
389 the start of each GOP.
390
391
392 GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE
393
394 These ioctls are used to set and query the target bitrate value for the
395 compressed video stream. The bitrate may be selected by storing the
396 target bits per second in an int and calling GO7007IOC_S_BITRATE with a
397 pointer to the int. The bitrate may be queried by calling
398 GO7007IOC_G_BITRATE with a pointer to an int where the current bitrate
399 will be stored.
400
401 Note that this is the primary means of controlling the video quality
402 for all compression modes, including V4L2_PIX_FMT_MJPEG. The
403 VIDIOC_S_JPEGCOMP ioctl is not supported.
404
405
406----------------------------------------------------------------------------
407 Installing the WIS PCI Voyager Driver
408---------------------------------------------------------------------------
409
410The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x
411kernel source tree before compiling the driver. These patches update the
412in-kernel SAA7134 driver to the newest development version and patch bugs
413in the TDA8290/TDA8275 tuner driver.
414
415The following patches must be downloaded from Gerd Knorr's website and
416applied in the order listed:
417
418 http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner
419 http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner2
420 http://dl.bytesex.org/patches/2.6.11-2/v4l2-api-mpeg
421 http://dl.bytesex.org/patches/2.6.11-2/saa7134-update
422
423The following patches are included with this SDK and can be applied in any
424order:
425
426 patches/2.6.11/saa7134-voyager.diff
427 patches/2.6.11/tda8275-newaddr.diff
428 patches/2.6.11/tda8290-ntsc.diff
429
430Check to make sure the CONFIG_VIDEO_SAA7134 option is enabled in the kernel
431configuration, and build and install the kernel.
432
433After rebooting into the new kernel, the GO7007 driver can be compiled and
434installed:
435
436 $ make SAA7134_BUILD=y
437 $ make install
438 $ modprobe saa7134-go7007
439
440There will be two V4L video devices associated with the PCI Voyager. The
441first device (most likely /dev/video0) provides access to the raw video
442capture mode of the SAA7133 device and is used to configure the source
443video parameters and tune the TV tuner. This device can be used with xawtv
444or other V4L(2) video software as a standard uncompressed device.
445
446The second device (most likely /dev/video1) provides access to the
447compression functions of the GO7007. It can be tested using the gorecord
448application in the apps/ directory of this SDK:
449
450 $ apps/gorecord -vdevice /dev/video1 -noaudio test.avi
451
452Currently the frame resolution is fixed at 720x480 (NTSC) or 720x576 (PAL),
453and the video standard must be specified to both the raw and the compressed
454video devices (xawtv and gorecord, for example).
455
456
457--------------------------------------------------------------------------
458RELEASE NOTES FOR WIS GO7007SB LINUX DRIVER
459---------------------------------------------------------------------------
460
461Last updated: 5 November 2005
462
463 - Release 0.9.7 includes new support for using udev to run fxload. The
464 install script should automatically detect whether the old hotplug
465 scripts or the new udev rules should be used. To force the use of
466 hotplug, run "make install USE_UDEV=n". To force the use of udev, run
467 "make install USE_UDEV=y".
468
469 - Motion detection is supported but undocumented. Try the `modet` app
470 for a demonstration of how to use the facility.
471
472 - Using USB2.0 devices such as the TV402U with USB1.1 HCDs or hubs can
473 cause buffer overruns and frame drops, even at low framerates, due to
474 inconsistency in the bitrate control mechanism.
475
476 - On devices with an SAA7115, including the Plextor ConvertX, video height
477 values of 96, 128, 160, 192, 256, 320, and 384 do not work in NTSC mode.
478 All valid heights up to 512 work correctly in PAL mode.
479
480 - The WIS Star Trek and PCI Voyager boards have no support yet for audio
481 or the TV tuner.
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
new file mode 100644
index 00000000000..e7736a91553
--- /dev/null
+++ b/drivers/staging/go7007/s2250-board.c
@@ -0,0 +1,698 @@
1/*
2 * Copyright (C) 2008 Sensoray Company 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/usb.h>
21#include <linux/i2c.h>
22#include <linux/videodev2.h>
23#include <linux/slab.h>
24#include <media/v4l2-device.h>
25#include <media/v4l2-common.h>
26#include <media/v4l2-subdev.h>
27#include "go7007-priv.h"
28
29MODULE_DESCRIPTION("Sensoray 2250/2251 i2c v4l2 subdev driver");
30MODULE_LICENSE("GPL v2");
31
32#define TLV320_ADDRESS 0x34
33#define VPX322_ADDR_ANALOGCONTROL1 0x02
34#define VPX322_ADDR_BRIGHTNESS0 0x0127
35#define VPX322_ADDR_BRIGHTNESS1 0x0131
36#define VPX322_ADDR_CONTRAST0 0x0128
37#define VPX322_ADDR_CONTRAST1 0x0132
38#define VPX322_ADDR_HUE 0x00dc
39#define VPX322_ADDR_SAT 0x0030
40
41struct go7007_usb_board {
42 unsigned int flags;
43 struct go7007_board_info main_info;
44};
45
46struct go7007_usb {
47 struct go7007_usb_board *board;
48 struct mutex i2c_lock;
49 struct usb_device *usbdev;
50 struct urb *video_urbs[8];
51 struct urb *audio_urbs[8];
52 struct urb *intr_urb;
53};
54
55static unsigned char aud_regs[] = {
56 0x1e, 0x00,
57 0x00, 0x17,
58 0x02, 0x17,
59 0x04, 0xf9,
60 0x06, 0xf9,
61 0x08, 0x02,
62 0x0a, 0x00,
63 0x0c, 0x00,
64 0x0a, 0x00,
65 0x0c, 0x00,
66 0x0e, 0x02,
67 0x10, 0x00,
68 0x12, 0x01,
69 0x00, 0x00,
70};
71
72
73static unsigned char vid_regs[] = {
74 0xF2, 0x0f,
75 0xAA, 0x00,
76 0xF8, 0xff,
77 0x00, 0x00,
78};
79
80static u16 vid_regs_fp[] = {
81 0x028, 0x067,
82 0x120, 0x016,
83 0x121, 0xcF2,
84 0x122, 0x0F2,
85 0x123, 0x00c,
86 0x124, 0x2d0,
87 0x125, 0x2e0,
88 0x126, 0x004,
89 0x128, 0x1E0,
90 0x12A, 0x016,
91 0x12B, 0x0F2,
92 0x12C, 0x0F2,
93 0x12D, 0x00c,
94 0x12E, 0x2d0,
95 0x12F, 0x2e0,
96 0x130, 0x004,
97 0x132, 0x1E0,
98 0x140, 0x060,
99 0x153, 0x00C,
100 0x154, 0x200,
101 0x150, 0x801,
102 0x000, 0x000
103};
104
105/* PAL specific values */
106static u16 vid_regs_fp_pal[] =
107{
108 0x120, 0x017,
109 0x121, 0xd22,
110 0x122, 0x122,
111 0x12A, 0x017,
112 0x12B, 0x122,
113 0x12C, 0x122,
114 0x140, 0x060,
115 0x000, 0x000,
116};
117
118struct s2250 {
119 struct v4l2_subdev sd;
120 v4l2_std_id std;
121 int input;
122 int brightness;
123 int contrast;
124 int saturation;
125 int hue;
126 int reg12b_val;
127 int audio_input;
128 struct i2c_client *audio;
129};
130
131static inline struct s2250 *to_state(struct v4l2_subdev *sd)
132{
133 return container_of(sd, struct s2250, sd);
134}
135
136/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
137static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
138 u16 value, u16 index, void *transfer_buffer, int length, int in)
139{
140 struct go7007_usb *usb = go->hpi_context;
141 int timeout = 5000;
142
143 if (in) {
144 return usb_control_msg(usb->usbdev,
145 usb_rcvctrlpipe(usb->usbdev, 0), request,
146 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
147 value, index, transfer_buffer, length, timeout);
148 } else {
149 return usb_control_msg(usb->usbdev,
150 usb_sndctrlpipe(usb->usbdev, 0), request,
151 USB_TYPE_VENDOR | USB_RECIP_DEVICE,
152 value, index, transfer_buffer, length, timeout);
153 }
154}
155/* end from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
156
157static int write_reg(struct i2c_client *client, u8 reg, u8 value)
158{
159 struct go7007 *go = i2c_get_adapdata(client->adapter);
160 struct go7007_usb *usb;
161 int rc;
162 int dev_addr = client->addr << 1; /* firmware wants 8-bit address */
163 u8 *buf;
164
165 if (go == NULL)
166 return -ENODEV;
167
168 if (go->status == STATUS_SHUTDOWN)
169 return -EBUSY;
170
171 buf = kzalloc(16, GFP_KERNEL);
172 if (buf == NULL)
173 return -ENOMEM;
174
175 usb = go->hpi_context;
176 if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
177 printk(KERN_INFO "i2c lock failed\n");
178 kfree(buf);
179 return -EINTR;
180 }
181 rc = go7007_usb_vendor_request(go, 0x55, dev_addr,
182 (reg<<8 | value),
183 buf,
184 16, 1);
185
186 mutex_unlock(&usb->i2c_lock);
187 kfree(buf);
188 return rc;
189}
190
191static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
192{
193 struct go7007 *go = i2c_get_adapdata(client->adapter);
194 struct go7007_usb *usb;
195 u8 *buf;
196 struct s2250 *dec = i2c_get_clientdata(client);
197
198 if (go == NULL)
199 return -ENODEV;
200
201 if (go->status == STATUS_SHUTDOWN)
202 return -EBUSY;
203
204 buf = kzalloc(16, GFP_KERNEL);
205
206 if (buf == NULL)
207 return -ENOMEM;
208
209
210
211 memset(buf, 0xcd, 6);
212
213 usb = go->hpi_context;
214 if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
215 printk(KERN_INFO "i2c lock failed\n");
216 kfree(buf);
217 return -EINTR;
218 }
219 if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) {
220 kfree(buf);
221 return -EFAULT;
222 }
223
224 mutex_unlock(&usb->i2c_lock);
225 if (buf[0] == 0) {
226 unsigned int subaddr, val_read;
227
228 subaddr = (buf[4] << 8) + buf[5];
229 val_read = (buf[2] << 8) + buf[3];
230 kfree(buf);
231 if (val_read != val) {
232 printk(KERN_INFO "invalid fp write %x %x\n",
233 val_read, val);
234 return -EFAULT;
235 }
236 if (subaddr != addr) {
237 printk(KERN_INFO "invalid fp write addr %x %x\n",
238 subaddr, addr);
239 return -EFAULT;
240 }
241 } else {
242 kfree(buf);
243 return -EFAULT;
244 }
245
246 /* save last 12b value */
247 if (addr == 0x12b)
248 dec->reg12b_val = val;
249
250 return 0;
251}
252
253static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
254{
255 struct go7007 *go = i2c_get_adapdata(client->adapter);
256 struct go7007_usb *usb;
257 u8 *buf;
258
259 if (go == NULL)
260 return -ENODEV;
261
262 if (go->status == STATUS_SHUTDOWN)
263 return -EBUSY;
264
265 buf = kzalloc(16, GFP_KERNEL);
266
267 if (buf == NULL)
268 return -ENOMEM;
269
270
271
272 memset(buf, 0xcd, 6);
273 usb = go->hpi_context;
274 if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
275 printk(KERN_INFO "i2c lock failed\n");
276 kfree(buf);
277 return -EINTR;
278 }
279 if (go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1) < 0) {
280 kfree(buf);
281 return -EFAULT;
282 }
283 mutex_unlock(&usb->i2c_lock);
284
285 *val = (buf[0] << 8) | buf[1];
286 kfree(buf);
287
288 return 0;
289}
290
291
292static int write_regs(struct i2c_client *client, u8 *regs)
293{
294 int i;
295
296 for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
297 if (write_reg(client, regs[i], regs[i+1]) < 0) {
298 printk(KERN_INFO "s2250: failed\n");
299 return -1;
300 }
301 }
302 return 0;
303}
304
305static int write_regs_fp(struct i2c_client *client, u16 *regs)
306{
307 int i;
308
309 for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) {
310 if (write_reg_fp(client, regs[i], regs[i+1]) < 0) {
311 printk(KERN_INFO "s2250: failed fp\n");
312 return -1;
313 }
314 }
315 return 0;
316}
317
318
319/* ------------------------------------------------------------------------- */
320
321static int s2250_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
322 u32 config)
323{
324 struct s2250 *state = to_state(sd);
325 struct i2c_client *client = v4l2_get_subdevdata(sd);
326 int vidsys;
327
328 vidsys = (state->std == V4L2_STD_NTSC) ? 0x01 : 0x00;
329 if (input == 0) {
330 /* composite */
331 write_reg_fp(client, 0x20, 0x020 | vidsys);
332 write_reg_fp(client, 0x21, 0x662);
333 write_reg_fp(client, 0x140, 0x060);
334 } else if (input == 1) {
335 /* S-Video */
336 write_reg_fp(client, 0x20, 0x040 | vidsys);
337 write_reg_fp(client, 0x21, 0x666);
338 write_reg_fp(client, 0x140, 0x060);
339 } else {
340 return -EINVAL;
341 }
342 state->input = input;
343 return 0;
344}
345
346static int s2250_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
347{
348 struct s2250 *state = to_state(sd);
349 struct i2c_client *client = v4l2_get_subdevdata(sd);
350 u16 vidsource;
351
352 vidsource = (state->input == 1) ? 0x040 : 0x020;
353 switch (norm) {
354 case V4L2_STD_NTSC:
355 write_regs_fp(client, vid_regs_fp);
356 write_reg_fp(client, 0x20, vidsource | 1);
357 break;
358 case V4L2_STD_PAL:
359 write_regs_fp(client, vid_regs_fp);
360 write_regs_fp(client, vid_regs_fp_pal);
361 write_reg_fp(client, 0x20, vidsource);
362 break;
363 default:
364 return -EINVAL;
365 }
366 state->std = norm;
367 return 0;
368}
369
370static int s2250_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *query)
371{
372 switch (query->id) {
373 case V4L2_CID_BRIGHTNESS:
374 return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
375 case V4L2_CID_CONTRAST:
376 return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
377 case V4L2_CID_SATURATION:
378 return v4l2_ctrl_query_fill(query, 0, 100, 1, 50);
379 case V4L2_CID_HUE:
380 return v4l2_ctrl_query_fill(query, -50, 50, 1, 0);
381 default:
382 return -EINVAL;
383 }
384 return 0;
385}
386
387static int s2250_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
388{
389 struct s2250 *state = to_state(sd);
390 struct i2c_client *client = v4l2_get_subdevdata(sd);
391 int value1;
392 u16 oldvalue;
393
394 switch (ctrl->id) {
395 case V4L2_CID_BRIGHTNESS:
396 if (ctrl->value > 100)
397 state->brightness = 100;
398 else if (ctrl->value < 0)
399 state->brightness = 0;
400 else
401 state->brightness = ctrl->value;
402 value1 = (state->brightness - 50) * 255 / 100;
403 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
404 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
405 value1 | (oldvalue & ~0xff));
406 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
407 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
408 value1 | (oldvalue & ~0xff));
409 write_reg_fp(client, 0x140, 0x60);
410 break;
411 case V4L2_CID_CONTRAST:
412 if (ctrl->value > 100)
413 state->contrast = 100;
414 else if (ctrl->value < 0)
415 state->contrast = 0;
416 else
417 state->contrast = ctrl->value;
418 value1 = state->contrast * 0x40 / 100;
419 if (value1 > 0x3f)
420 value1 = 0x3f; /* max */
421 read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
422 write_reg_fp(client, VPX322_ADDR_CONTRAST0,
423 value1 | (oldvalue & ~0x3f));
424 read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
425 write_reg_fp(client, VPX322_ADDR_CONTRAST1,
426 value1 | (oldvalue & ~0x3f));
427 write_reg_fp(client, 0x140, 0x60);
428 break;
429 case V4L2_CID_SATURATION:
430 if (ctrl->value > 100)
431 state->saturation = 100;
432 else if (ctrl->value < 0)
433 state->saturation = 0;
434 else
435 state->saturation = ctrl->value;
436 value1 = state->saturation * 4140 / 100;
437 if (value1 > 4094)
438 value1 = 4094;
439 write_reg_fp(client, VPX322_ADDR_SAT, value1);
440 break;
441 case V4L2_CID_HUE:
442 if (ctrl->value > 50)
443 state->hue = 50;
444 else if (ctrl->value < -50)
445 state->hue = -50;
446 else
447 state->hue = ctrl->value;
448 /* clamp the hue range */
449 value1 = state->hue * 280 / 50;
450 write_reg_fp(client, VPX322_ADDR_HUE, value1);
451 break;
452 default:
453 return -EINVAL;
454 }
455 return 0;
456}
457
458static int s2250_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
459{
460 struct s2250 *state = to_state(sd);
461
462 switch (ctrl->id) {
463 case V4L2_CID_BRIGHTNESS:
464 ctrl->value = state->brightness;
465 break;
466 case V4L2_CID_CONTRAST:
467 ctrl->value = state->contrast;
468 break;
469 case V4L2_CID_SATURATION:
470 ctrl->value = state->saturation;
471 break;
472 case V4L2_CID_HUE:
473 ctrl->value = state->hue;
474 break;
475 default:
476 return -EINVAL;
477 }
478 return 0;
479}
480
481static int s2250_s_mbus_fmt(struct v4l2_subdev *sd,
482 struct v4l2_mbus_framefmt *fmt)
483{
484 struct s2250 *state = to_state(sd);
485 struct i2c_client *client = v4l2_get_subdevdata(sd);
486
487 if (fmt->height < 640) {
488 write_reg_fp(client, 0x12b, state->reg12b_val | 0x400);
489 write_reg_fp(client, 0x140, 0x060);
490 } else {
491 write_reg_fp(client, 0x12b, state->reg12b_val & ~0x400);
492 write_reg_fp(client, 0x140, 0x060);
493 }
494 return 0;
495}
496
497static int s2250_s_audio_routing(struct v4l2_subdev *sd, u32 input, u32 output,
498 u32 config)
499{
500 struct s2250 *state = to_state(sd);
501
502 switch (input) {
503 case 0:
504 write_reg(state->audio, 0x08, 0x02); /* Line In */
505 break;
506 case 1:
507 write_reg(state->audio, 0x08, 0x04); /* Mic */
508 break;
509 case 2:
510 write_reg(state->audio, 0x08, 0x05); /* Mic Boost */
511 break;
512 default:
513 return -EINVAL;
514 }
515 state->audio_input = input;
516 return 0;
517}
518
519
520static int s2250_log_status(struct v4l2_subdev *sd)
521{
522 struct s2250 *state = to_state(sd);
523
524 v4l2_info(sd, "Standard: %s\n", state->std == V4L2_STD_NTSC ? "NTSC" :
525 state->std == V4L2_STD_PAL ? "PAL" :
526 state->std == V4L2_STD_SECAM ? "SECAM" :
527 "unknown");
528 v4l2_info(sd, "Input: %s\n", state->input == 0 ? "Composite" :
529 state->input == 1 ? "S-video" :
530 "error");
531 v4l2_info(sd, "Brightness: %d\n", state->brightness);
532 v4l2_info(sd, "Contrast: %d\n", state->contrast);
533 v4l2_info(sd, "Saturation: %d\n", state->saturation);
534 v4l2_info(sd, "Hue: %d\n", state->hue); return 0;
535 v4l2_info(sd, "Audio input: %s\n", state->audio_input == 0 ? "Line In" :
536 state->audio_input == 1 ? "Mic" :
537 state->audio_input == 2 ? "Mic Boost" :
538 "error");
539 return 0;
540}
541
542/* --------------------------------------------------------------------------*/
543
544static const struct v4l2_subdev_core_ops s2250_core_ops = {
545 .log_status = s2250_log_status,
546 .g_ctrl = s2250_g_ctrl,
547 .s_ctrl = s2250_s_ctrl,
548 .queryctrl = s2250_queryctrl,
549 .s_std = s2250_s_std,
550};
551
552static const struct v4l2_subdev_audio_ops s2250_audio_ops = {
553 .s_routing = s2250_s_audio_routing,
554};
555
556static const struct v4l2_subdev_video_ops s2250_video_ops = {
557 .s_routing = s2250_s_video_routing,
558 .s_mbus_fmt = s2250_s_mbus_fmt,
559};
560
561static const struct v4l2_subdev_ops s2250_ops = {
562 .core = &s2250_core_ops,
563 .audio = &s2250_audio_ops,
564 .video = &s2250_video_ops,
565};
566
567/* --------------------------------------------------------------------------*/
568
569static int s2250_probe(struct i2c_client *client,
570 const struct i2c_device_id *id)
571{
572 struct i2c_client *audio;
573 struct i2c_adapter *adapter = client->adapter;
574 struct s2250 *state;
575 struct v4l2_subdev *sd;
576 u8 *data;
577 struct go7007 *go = i2c_get_adapdata(adapter);
578 struct go7007_usb *usb = go->hpi_context;
579
580 audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
581 if (audio == NULL)
582 return -ENOMEM;
583
584 state = kmalloc(sizeof(struct s2250), GFP_KERNEL);
585 if (state == NULL) {
586 i2c_unregister_device(audio);
587 return -ENOMEM;
588 }
589
590 sd = &state->sd;
591 v4l2_i2c_subdev_init(sd, client, &s2250_ops);
592
593 v4l2_info(sd, "initializing %s at address 0x%x on %s\n",
594 "Sensoray 2250/2251", client->addr, client->adapter->name);
595
596 state->std = V4L2_STD_NTSC;
597 state->brightness = 50;
598 state->contrast = 50;
599 state->saturation = 50;
600 state->hue = 0;
601 state->audio = audio;
602
603 /* initialize the audio */
604 if (write_regs(audio, aud_regs) < 0) {
605 printk(KERN_ERR
606 "s2250: error initializing audio\n");
607 i2c_unregister_device(audio);
608 kfree(state);
609 return 0;
610 }
611
612 if (write_regs(client, vid_regs) < 0) {
613 printk(KERN_ERR
614 "s2250: error initializing decoder\n");
615 i2c_unregister_device(audio);
616 kfree(state);
617 return 0;
618 }
619 if (write_regs_fp(client, vid_regs_fp) < 0) {
620 printk(KERN_ERR
621 "s2250: error initializing decoder\n");
622 i2c_unregister_device(audio);
623 kfree(state);
624 return 0;
625 }
626 /* set default channel */
627 /* composite */
628 write_reg_fp(client, 0x20, 0x020 | 1);
629 write_reg_fp(client, 0x21, 0x662);
630 write_reg_fp(client, 0x140, 0x060);
631
632 /* set default audio input */
633 state->audio_input = 0;
634 write_reg(client, 0x08, 0x02); /* Line In */
635
636 if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
637 data = kzalloc(16, GFP_KERNEL);
638 if (data != NULL) {
639 int rc;
640 rc = go7007_usb_vendor_request(go, 0x41, 0, 0,
641 data, 16, 1);
642 if (rc > 0) {
643 u8 mask;
644 data[0] = 0;
645 mask = 1<<5;
646 data[0] &= ~mask;
647 data[1] |= mask;
648 go7007_usb_vendor_request(go, 0x40, 0,
649 (data[1]<<8)
650 + data[1],
651 data, 16, 0);
652 }
653 kfree(data);
654 }
655 mutex_unlock(&usb->i2c_lock);
656 }
657
658 v4l2_info(sd, "initialized successfully\n");
659 return 0;
660}
661
662static int s2250_remove(struct i2c_client *client)
663{
664 struct v4l2_subdev *sd = i2c_get_clientdata(client);
665
666 v4l2_device_unregister_subdev(sd);
667 kfree(to_state(sd));
668 return 0;
669}
670
671static const struct i2c_device_id s2250_id[] = {
672 { "s2250", 0 },
673 { }
674};
675MODULE_DEVICE_TABLE(i2c, s2250_id);
676
677static struct i2c_driver s2250_driver = {
678 .driver = {
679 .owner = THIS_MODULE,
680 .name = "s2250",
681 },
682 .probe = s2250_probe,
683 .remove = s2250_remove,
684 .id_table = s2250_id,
685};
686
687static __init int init_s2250(void)
688{
689 return i2c_add_driver(&s2250_driver);
690}
691
692static __exit void exit_s2250(void)
693{
694 i2c_del_driver(&s2250_driver);
695}
696
697module_init(init_s2250);
698module_exit(exit_s2250);
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c
new file mode 100644
index 00000000000..4e132519e25
--- /dev/null
+++ b/drivers/staging/go7007/s2250-loader.c
@@ -0,0 +1,191 @@
1/*
2 * Copyright (C) 2008 Sensoray Company 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/slab.h>
21#include <linux/usb.h>
22#include <dvb-usb.h>
23
24#define S2250_LOADER_FIRMWARE "s2250_loader.fw"
25#define S2250_FIRMWARE "s2250.fw"
26
27typedef struct device_extension_s {
28 struct kref kref;
29 int minor;
30 struct usb_device *usbdev;
31} device_extension_t, *pdevice_extension_t;
32
33#define USB_s2250loader_MAJOR 240
34#define USB_s2250loader_MINOR_BASE 0
35#define MAX_DEVICES 256
36
37static pdevice_extension_t s2250_dev_table[MAX_DEVICES];
38static DEFINE_MUTEX(s2250_dev_table_mutex);
39
40#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref)
41static void s2250loader_delete(struct kref *kref)
42{
43 pdevice_extension_t s = to_s2250loader_dev_common(kref);
44 s2250_dev_table[s->minor] = NULL;
45 kfree(s);
46}
47
48static int s2250loader_probe(struct usb_interface *interface,
49 const struct usb_device_id *id)
50{
51 struct usb_device *usbdev;
52 int minor, ret;
53 pdevice_extension_t s = NULL;
54 const struct firmware *fw;
55
56 usbdev = usb_get_dev(interface_to_usbdev(interface));
57 if (!usbdev) {
58 printk(KERN_ERR "Enter s2250loader_probe failed\n");
59 return -1;
60 }
61 printk(KERN_INFO "Enter s2250loader_probe 2.6 kernel\n");
62 printk(KERN_INFO "vendor id 0x%x, device id 0x%x devnum:%d\n",
63 usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
64 usbdev->devnum);
65
66 if (usbdev->descriptor.bNumConfigurations != 1) {
67 printk(KERN_ERR "can't handle multiple config\n");
68 return -1;
69 }
70 mutex_lock(&s2250_dev_table_mutex);
71
72 for (minor = 0; minor < MAX_DEVICES; minor++) {
73 if (s2250_dev_table[minor] == NULL)
74 break;
75 }
76
77 if (minor < 0 || minor >= MAX_DEVICES) {
78 printk(KERN_ERR "Invalid minor: %d\n", minor);
79 goto failed;
80 }
81
82 /* Allocate dev data structure */
83 s = kmalloc(sizeof(device_extension_t), GFP_KERNEL);
84 if (s == NULL) {
85 printk(KERN_ERR "Out of memory\n");
86 goto failed;
87 }
88 s2250_dev_table[minor] = s;
89
90 printk(KERN_INFO "s2250loader_probe: Device %d on Bus %d Minor %d\n",
91 usbdev->devnum, usbdev->bus->busnum, minor);
92
93 memset(s, 0, sizeof(device_extension_t));
94 s->usbdev = usbdev;
95 printk(KERN_INFO "loading 2250 loader\n");
96
97 kref_init(&(s->kref));
98
99 mutex_unlock(&s2250_dev_table_mutex);
100
101 if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
102 printk(KERN_ERR
103 "s2250: unable to load firmware from file \"%s\"\n",
104 S2250_LOADER_FIRMWARE);
105 goto failed2;
106 }
107 ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
108 release_firmware(fw);
109 if (0 != ret) {
110 printk(KERN_ERR "loader download failed\n");
111 goto failed2;
112 }
113
114 if (request_firmware(&fw, S2250_FIRMWARE, &usbdev->dev)) {
115 printk(KERN_ERR
116 "s2250: unable to load firmware from file \"%s\"\n",
117 S2250_FIRMWARE);
118 goto failed2;
119 }
120 ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
121 release_firmware(fw);
122 if (0 != ret) {
123 printk(KERN_ERR "firmware_s2250 download failed\n");
124 goto failed2;
125 }
126
127 usb_set_intfdata(interface, s);
128 return 0;
129
130failed:
131 mutex_unlock(&s2250_dev_table_mutex);
132failed2:
133 if (s)
134 kref_put(&(s->kref), s2250loader_delete);
135
136 printk(KERN_ERR "probe failed\n");
137 return -1;
138}
139
140static void s2250loader_disconnect(struct usb_interface *interface)
141{
142 pdevice_extension_t s;
143 printk(KERN_INFO "s2250: disconnect\n");
144 s = usb_get_intfdata(interface);
145 usb_set_intfdata(interface, NULL);
146 kref_put(&(s->kref), s2250loader_delete);
147}
148
149static const struct usb_device_id s2250loader_ids[] = {
150 {USB_DEVICE(0x1943, 0xa250)},
151 {} /* Terminating entry */
152};
153
154MODULE_DEVICE_TABLE(usb, s2250loader_ids);
155
156static struct usb_driver s2250loader_driver = {
157 .name = "s2250-loader",
158 .probe = s2250loader_probe,
159 .disconnect = s2250loader_disconnect,
160 .id_table = s2250loader_ids,
161};
162
163static int __init s2250loader_init(void)
164{
165 int r;
166 unsigned i = 0;
167
168 for (i = 0; i < MAX_DEVICES; i++)
169 s2250_dev_table[i] = NULL;
170
171 r = usb_register(&s2250loader_driver);
172 if (r) {
173 printk(KERN_ERR "usb_register failed. Error number %d\n", r);
174 return -1;
175 }
176
177 printk(KERN_INFO "s2250loader_init: driver registered\n");
178 return 0;
179}
180module_init(s2250loader_init);
181
182static void __exit s2250loader_cleanup(void)
183{
184 printk(KERN_INFO "s2250loader_cleanup\n");
185 usb_deregister(&s2250loader_driver);
186}
187module_exit(s2250loader_cleanup);
188
189MODULE_AUTHOR("");
190MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251");
191MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/s2250-loader.h b/drivers/staging/go7007/s2250-loader.h
new file mode 100644
index 00000000000..b7c301af16c
--- /dev/null
+++ b/drivers/staging/go7007/s2250-loader.h
@@ -0,0 +1,24 @@
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#ifndef _S2250_LOADER_H_
19#define _S2250_LOADER_H_
20
21extern int s2250loader_init(void);
22extern void s2250loader_cleanup(void);
23
24#endif
diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/go7007/saa7134-go7007.c
new file mode 100644
index 00000000000..cf7c34a9945
--- /dev/null
+++ b/drivers/staging/go7007/saa7134-go7007.c
@@ -0,0 +1,532 @@
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/v4l2-common.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};
87MODULE_FIRMWARE("go7007tv.bin");
88
89/********************* Driver for GPIO HPI interface *********************/
90
91static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
92{
93 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
94
95 /* Write HPI address */
96 saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
97 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
98 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
99
100 /* Write low byte */
101 saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
102 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
103 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
104
105 /* Write high byte */
106 saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8);
107 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
108 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
109
110 return 0;
111}
112
113static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
114{
115 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
116
117 /* Write HPI address */
118 saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
119 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
120 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
121
122 saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
123
124 /* Read low byte */
125 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
126 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
127 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
128 *data = saa_readb(SAA7134_GPIO_GPSTATUS0);
129 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
130
131 /* Read high byte */
132 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
133 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
134 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
135 *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
136 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
137
138 return 0;
139}
140
141static int saa7134_go7007_interface_reset(struct go7007 *go)
142{
143 struct saa7134_go7007 *saa = go->hpi_context;
144 struct saa7134_dev *dev = saa->dev;
145 u32 status;
146 u16 intr_val, intr_data;
147 int count = 20;
148
149 saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
150 saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4);
151 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
152
153 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
154 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET);
155 msleep(1);
156 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
157 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
158 msleep(10);
159
160 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
161 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
162
163 status = saa_readb(SAA7134_GPIO_GPSTATUS2);
164 /*printk(KERN_DEBUG "status is %s\n", status & 0x40 ? "OK" : "not OK"); */
165
166 /* enter command mode...(?) */
167 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
168 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
169
170 do {
171 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
172 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
173 status = saa_readb(SAA7134_GPIO_GPSTATUS2);
174 /*printk(KERN_INFO "gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
175 } while (--count > 0);
176
177 /* Wait for an interrupt to indicate successful hardware reset */
178 if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
179 (intr_val & ~0x1) != 0x55aa) {
180 printk(KERN_ERR
181 "saa7134-go7007: unable to reset the GO7007\n");
182 return -1;
183 }
184 return 0;
185}
186
187static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
188{
189 struct saa7134_go7007 *saa = go->hpi_context;
190 struct saa7134_dev *dev = saa->dev;
191 int i;
192 u16 status_reg;
193
194#ifdef GO7007_HPI_DEBUG
195 printk(KERN_DEBUG
196 "saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
197#endif
198
199 for (i = 0; i < 100; ++i) {
200 gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
201 if (!(status_reg & 0x0010))
202 break;
203 msleep(10);
204 }
205 if (i == 100) {
206 printk(KERN_ERR
207 "saa7134-go7007: device is hung, status reg = 0x%04x\n",
208 status_reg);
209 return -1;
210 }
211 gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data);
212 gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr);
213
214 return 0;
215}
216
217static int saa7134_go7007_read_interrupt(struct go7007 *go)
218{
219 struct saa7134_go7007 *saa = go->hpi_context;
220 struct saa7134_dev *dev = saa->dev;
221
222 /* XXX we need to wait if there is no interrupt available */
223 go->interrupt_available = 1;
224 gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value);
225 gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data);
226#ifdef GO7007_HPI_DEBUG
227 printk(KERN_DEBUG "saa7134-go7007: ReadInterrupt: %04x %04x\n",
228 go->interrupt_value, go->interrupt_data);
229#endif
230 return 0;
231}
232
233static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
234 unsigned long status)
235{
236 struct go7007 *go = video_get_drvdata(dev->empress_dev);
237 struct saa7134_go7007 *saa = go->hpi_context;
238
239 if (!go->streaming)
240 return;
241 if (0 != (status & 0x000f0000))
242 printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n",
243 (status >> 16) & 0x0f);
244 if (status & 0x100000) {
245 dma_sync_single_for_cpu(&dev->pci->dev,
246 saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE);
247 go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE);
248 saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
249 } else {
250 dma_sync_single_for_cpu(&dev->pci->dev,
251 saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE);
252 go7007_parse_video_stream(go, saa->top, PAGE_SIZE);
253 saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
254 }
255}
256
257static int saa7134_go7007_stream_start(struct go7007 *go)
258{
259 struct saa7134_go7007 *saa = go->hpi_context;
260 struct saa7134_dev *dev = saa->dev;
261
262 saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
263 0, PAGE_SIZE, DMA_FROM_DEVICE);
264 if (!saa->top_dma)
265 return -ENOMEM;
266 saa->bottom_dma = dma_map_page(&dev->pci->dev,
267 virt_to_page(saa->bottom),
268 0, PAGE_SIZE, DMA_FROM_DEVICE);
269 if (!saa->bottom_dma) {
270 dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
271 DMA_FROM_DEVICE);
272 return -ENOMEM;
273 }
274
275 saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
276 saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
277
278 /* Set HPI interface for video */
279 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
280 saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER);
281 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
282 saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
283
284 /* Enable TS interface */
285 saa_writeb(SAA7134_TS_PARALLEL, 0xe6);
286
287 /* Reset TS interface */
288 saa_setb(SAA7134_TS_SERIAL1, 0x01);
289 saa_clearb(SAA7134_TS_SERIAL1, 0x01);
290
291 /* Set up transfer block size */
292 saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1);
293 saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1);
294 saa_writeb(SAA7134_TS_DMA1, 0);
295 saa_writeb(SAA7134_TS_DMA2, 0);
296
297 /* Enable video streaming mode */
298 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO);
299
300 saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
301 saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
302 saa_writel(SAA7134_RS_PITCH(5), 128);
303 saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX);
304
305 /* Enable TS FIFO */
306 saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
307
308 /* Enable DMA IRQ */
309 saa_setl(SAA7134_IRQ1,
310 SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
311
312 return 0;
313}
314
315static int saa7134_go7007_stream_stop(struct go7007 *go)
316{
317 struct saa7134_go7007 *saa = go->hpi_context;
318 struct saa7134_dev *dev;
319
320 if (!saa)
321 return -EINVAL;
322 dev = saa->dev;
323 if (!dev)
324 return -EINVAL;
325
326 /* Shut down TS FIFO */
327 saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
328
329 /* Disable DMA IRQ */
330 saa_clearl(SAA7134_IRQ1,
331 SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
332
333 /* Disable TS interface */
334 saa_clearb(SAA7134_TS_PARALLEL, 0x80);
335
336 dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
337 DMA_FROM_DEVICE);
338 dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
339 DMA_FROM_DEVICE);
340
341 return 0;
342}
343
344static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
345{
346 struct saa7134_go7007 *saa = go->hpi_context;
347 struct saa7134_dev *dev = saa->dev;
348 u16 status_reg;
349 int i;
350
351#ifdef GO7007_HPI_DEBUG
352 printk(KERN_DEBUG "saa7134-go7007: DownloadBuffer "
353 "sending %d bytes\n", len);
354#endif
355
356 while (len > 0) {
357 i = len > 64 ? 64 : len;
358 saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
359 saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER);
360 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
361 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
362 while (i-- > 0) {
363 saa_writeb(SAA7134_GPIO_GPSTATUS0, *data);
364 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
365 saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
366 ++data;
367 --len;
368 }
369 for (i = 0; i < 100; ++i) {
370 gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
371 if (!(status_reg & 0x0002))
372 break;
373 }
374 if (i == 100) {
375 printk(KERN_ERR "saa7134-go7007: device is hung, "
376 "status reg = 0x%04x\n", status_reg);
377 return -1;
378 }
379 }
380 return 0;
381}
382
383static int saa7134_go7007_send_command(struct go7007 *go, unsigned int cmd,
384 void *arg)
385{
386 struct saa7134_go7007 *saa = go->hpi_context;
387 struct saa7134_dev *dev = saa->dev;
388
389 switch (cmd) {
390 case VIDIOC_S_STD:
391 {
392 v4l2_std_id *std = arg;
393 return saa7134_s_std_internal(dev, NULL, std);
394 }
395 case VIDIOC_G_STD:
396 {
397 v4l2_std_id *std = arg;
398 *std = dev->tvnorm->id;
399 return 0;
400 }
401 case VIDIOC_QUERYCTRL:
402 {
403 struct v4l2_queryctrl *ctrl = arg;
404 if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER)
405 return saa7134_queryctrl(NULL, NULL, ctrl);
406 }
407 case VIDIOC_G_CTRL:
408 {
409 struct v4l2_control *ctrl = arg;
410 if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER)
411 return saa7134_g_ctrl_internal(dev, NULL, ctrl);
412 }
413 case VIDIOC_S_CTRL:
414 {
415 struct v4l2_control *ctrl = arg;
416 if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER)
417 return saa7134_s_ctrl_internal(dev, NULL, ctrl);
418 }
419 }
420 return -EINVAL;
421
422}
423
424static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
425 .interface_reset = saa7134_go7007_interface_reset,
426 .write_interrupt = saa7134_go7007_write_interrupt,
427 .read_interrupt = saa7134_go7007_read_interrupt,
428 .stream_start = saa7134_go7007_stream_start,
429 .stream_stop = saa7134_go7007_stream_stop,
430 .send_firmware = saa7134_go7007_send_firmware,
431 .send_command = saa7134_go7007_send_command,
432};
433
434/********************* Add/remove functions *********************/
435
436static int saa7134_go7007_init(struct saa7134_dev *dev)
437{
438 struct go7007 *go;
439 struct saa7134_go7007 *saa;
440
441 printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n");
442
443 saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
444 if (saa == NULL)
445 return -ENOMEM;
446
447 /* Allocate a couple pages for receiving the compressed stream */
448 saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
449 if (!saa->top)
450 goto allocfail;
451 saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
452 if (!saa->bottom)
453 goto allocfail;
454
455 go = go7007_alloc(&board_voyager, &dev->pci->dev);
456 if (go == NULL)
457 goto allocfail;
458 go->board_id = GO7007_BOARDID_PCI_VOYAGER;
459 strncpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
460 go->hpi_ops = &saa7134_go7007_hpi_ops;
461 go->hpi_context = saa;
462 saa->dev = dev;
463
464 /* Boot the GO7007 */
465 if (go7007_boot_encoder(go, go->board_info->flags &
466 GO7007_BOARD_USE_ONBOARD_I2C) < 0)
467 goto initfail;
468
469 /* Do any final GO7007 initialization, then register the
470 * V4L2 and ALSA interfaces */
471 if (go7007_register_encoder(go) < 0)
472 goto initfail;
473 dev->empress_dev = go->video_dev;
474 video_set_drvdata(dev->empress_dev, go);
475
476 go->status = STATUS_ONLINE;
477 return 0;
478
479initfail:
480 go->status = STATUS_SHUTDOWN;
481 return 0;
482
483allocfail:
484 if (saa->top)
485 free_page((unsigned long)saa->top);
486 if (saa->bottom)
487 free_page((unsigned long)saa->bottom);
488 kfree(saa);
489 return -ENOMEM;
490}
491
492static int saa7134_go7007_fini(struct saa7134_dev *dev)
493{
494 struct go7007 *go;
495 struct saa7134_go7007 *saa;
496
497 if (NULL == dev->empress_dev)
498 return 0;
499
500 go = video_get_drvdata(dev->empress_dev);
501 saa = go->hpi_context;
502 go->status = STATUS_SHUTDOWN;
503 free_page((unsigned long)saa->top);
504 free_page((unsigned long)saa->bottom);
505 kfree(saa);
506 go7007_remove(go);
507 dev->empress_dev = NULL;
508
509 return 0;
510}
511
512static struct saa7134_mpeg_ops saa7134_go7007_ops = {
513 .type = SAA7134_MPEG_GO7007,
514 .init = saa7134_go7007_init,
515 .fini = saa7134_go7007_fini,
516 .irq_ts_done = saa7134_go7007_irq_ts_done,
517};
518
519static int __init saa7134_go7007_mod_init(void)
520{
521 return saa7134_ts_register(&saa7134_go7007_ops);
522}
523
524static void __exit saa7134_go7007_mod_cleanup(void)
525{
526 saa7134_ts_unregister(&saa7134_go7007_ops);
527}
528
529module_init(saa7134_go7007_mod_init);
530module_exit(saa7134_go7007_mod_cleanup);
531
532MODULE_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..deac938d850
--- /dev/null
+++ b/drivers/staging/go7007/snd-go7007.c
@@ -0,0 +1,306 @@
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/moduleparam.h>
21#include <linux/init.h>
22#include <linux/spinlock.h>
23#include <linux/delay.h>
24#include <linux/sched.h>
25#include <linux/vmalloc.h>
26#include <linux/time.h>
27#include <linux/mm.h>
28#include <linux/i2c.h>
29#include <linux/mutex.h>
30#include <linux/uaccess.h>
31#include <linux/slab.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(id, "ID string for the go7007 audio driver");
48MODULE_PARM_DESC(enable, "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 ret = snd_card_create(index[dev], id[dev], THIS_MODULE, 0,
253 &gosnd->card);
254 if (ret < 0) {
255 kfree(gosnd);
256 return ret;
257 }
258 ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
259 &go7007_snd_device_ops);
260 if (ret < 0) {
261 kfree(gosnd);
262 return ret;
263 }
264 snd_card_set_dev(gosnd->card, go->dev);
265 ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
266 if (ret < 0) {
267 snd_card_free(gosnd->card);
268 kfree(gosnd);
269 return ret;
270 }
271 strncpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
272 strncpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
273 strncpy(gosnd->card->longname, gosnd->card->shortname,
274 sizeof(gosnd->card->longname));
275
276 gosnd->pcm->private_data = go;
277 snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE,
278 &go7007_snd_capture_ops);
279
280 ret = snd_card_register(gosnd->card);
281 if (ret < 0) {
282 snd_card_free(gosnd->card);
283 kfree(gosnd);
284 return ret;
285 }
286
287 gosnd->substream = NULL;
288 go->snd_context = gosnd;
289 ++dev;
290 ++go->ref_count;
291
292 return 0;
293}
294EXPORT_SYMBOL(go7007_snd_init);
295
296int go7007_snd_remove(struct go7007 *go)
297{
298 struct go7007_snd *gosnd = go->snd_context;
299
300 snd_card_disconnect(gosnd->card);
301 snd_card_free_when_closed(gosnd->card);
302 return 0;
303}
304EXPORT_SYMBOL(go7007_snd_remove);
305
306MODULE_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..3c2b9be455d
--- /dev/null
+++ b/drivers/staging/go7007/wis-i2c.h
@@ -0,0 +1,47 @@
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_DRIVERID_S2250 0xf0f7
27
28/* Flag to indicate that the client needs to be accessed with SCCB semantics */
29/* We re-use the I2C_M_TEN value so the flag passes through the masks in the
30 * core I2C code. Major kludge, but the I2C layer ain't exactly flexible. */
31#define I2C_CLIENT_SCCB 0x10
32
33/* Definitions for new video decoder commands */
34
35struct video_decoder_resolution {
36 unsigned int width;
37 unsigned int height;
38};
39
40#define DECODER_SET_RESOLUTION _IOW('d', 200, struct video_decoder_resolution)
41#define DECODER_SET_CHANNEL _IOW('d', 201, int)
42
43/* Sony tuner types */
44
45#define TUNER_SONY_BTF_PG472Z 200
46#define TUNER_SONY_BTF_PK467Z 201
47#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..6bc9470fecb
--- /dev/null
+++ b/drivers/staging/go7007/wis-ov7640.c
@@ -0,0 +1,108 @@
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/i2c.h>
21#include <linux/videodev2.h>
22
23#include "wis-i2c.h"
24
25struct wis_ov7640 {
26 int brightness;
27 int contrast;
28 int saturation;
29 int hue;
30};
31
32static u8 initial_registers[] =
33{
34 0x12, 0x80,
35 0x12, 0x54,
36 0x14, 0x24,
37 0x15, 0x01,
38 0x28, 0x20,
39 0x75, 0x82,
40 0xFF, 0xFF, /* Terminator (reg 0xFF is unused) */
41};
42
43static int write_regs(struct i2c_client *client, u8 *regs)
44{
45 int i;
46
47 for (i = 0; regs[i] != 0xFF; i += 2)
48 if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
49 return -1;
50 return 0;
51}
52
53static int wis_ov7640_probe(struct i2c_client *client,
54 const struct i2c_device_id *id)
55{
56 struct i2c_adapter *adapter = client->adapter;
57
58 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
59 return -ENODEV;
60
61 client->flags = I2C_CLIENT_SCCB;
62
63 printk(KERN_DEBUG
64 "wis-ov7640: initializing OV7640 at address %d on %s\n",
65 client->addr, adapter->name);
66
67 if (write_regs(client, initial_registers) < 0) {
68 printk(KERN_ERR "wis-ov7640: error initializing OV7640\n");
69 return -ENODEV;
70 }
71
72 return 0;
73}
74
75static int wis_ov7640_remove(struct i2c_client *client)
76{
77 return 0;
78}
79
80static const struct i2c_device_id wis_ov7640_id[] = {
81 { "wis_ov7640", 0 },
82 { }
83};
84MODULE_DEVICE_TABLE(i2c, wis_ov7640_id);
85
86static struct i2c_driver wis_ov7640_driver = {
87 .driver = {
88 .name = "WIS OV7640 I2C driver",
89 },
90 .probe = wis_ov7640_probe,
91 .remove = wis_ov7640_remove,
92 .id_table = wis_ov7640_id,
93};
94
95static int __init wis_ov7640_init(void)
96{
97 return i2c_add_driver(&wis_ov7640_driver);
98}
99
100static void __exit wis_ov7640_cleanup(void)
101{
102 i2c_del_driver(&wis_ov7640_driver);
103}
104
105module_init(wis_ov7640_init);
106module_exit(wis_ov7640_cleanup);
107
108MODULE_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..05e0e108386
--- /dev/null
+++ b/drivers/staging/go7007/wis-saa7113.c
@@ -0,0 +1,336 @@
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/i2c.h>
21#include <linux/videodev2.h>
22#include <linux/ioctl.h>
23#include <linux/slab.h>
24
25#include "wis-i2c.h"
26
27struct wis_saa7113 {
28 int norm;
29 int brightness;
30 int contrast;
31 int saturation;
32 int hue;
33};
34
35static u8 initial_registers[] =
36{
37 0x01, 0x08,
38 0x02, 0xc0,
39 0x03, 0x33,
40 0x04, 0x00,
41 0x05, 0x00,
42 0x06, 0xe9,
43 0x07, 0x0d,
44 0x08, 0xd8,
45 0x09, 0x40,
46 0x0a, 0x80,
47 0x0b, 0x47,
48 0x0c, 0x40,
49 0x0d, 0x00,
50 0x0e, 0x01,
51 0x0f, 0x2a,
52 0x10, 0x40,
53 0x11, 0x0c,
54 0x12, 0xfe,
55 0x13, 0x00,
56 0x14, 0x00,
57 0x15, 0x04,
58 0x16, 0x00,
59 0x17, 0x00,
60 0x18, 0x00,
61 0x19, 0x00,
62 0x1a, 0x00,
63 0x1b, 0x00,
64 0x1c, 0x00,
65 0x1d, 0x00,
66 0x1e, 0x00,
67 0x1f, 0xc8,
68 0x40, 0x00,
69 0x41, 0xff,
70 0x42, 0xff,
71 0x43, 0xff,
72 0x44, 0xff,
73 0x45, 0xff,
74 0x46, 0xff,
75 0x47, 0xff,
76 0x48, 0xff,
77 0x49, 0xff,
78 0x4a, 0xff,
79 0x4b, 0xff,
80 0x4c, 0xff,
81 0x4d, 0xff,
82 0x4e, 0xff,
83 0x4f, 0xff,
84 0x50, 0xff,
85 0x51, 0xff,
86 0x52, 0xff,
87 0x53, 0xff,
88 0x54, 0xff,
89 0x55, 0xff,
90 0x56, 0xff,
91 0x57, 0xff,
92 0x58, 0x00,
93 0x59, 0x54,
94 0x5a, 0x07,
95 0x5b, 0x83,
96 0x5c, 0x00,
97 0x5d, 0x00,
98 0x5e, 0x00,
99 0x5f, 0x00,
100 0x60, 0x00,
101 0x61, 0x00,
102 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
103};
104
105static int write_reg(struct i2c_client *client, u8 reg, u8 value)
106{
107 return i2c_smbus_write_byte_data(client, reg, value);
108}
109
110static int write_regs(struct i2c_client *client, u8 *regs)
111{
112 int i;
113
114 for (i = 0; regs[i] != 0x00; i += 2)
115 if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
116 return -1;
117 return 0;
118}
119
120static int wis_saa7113_command(struct i2c_client *client,
121 unsigned int cmd, void *arg)
122{
123 struct wis_saa7113 *dec = i2c_get_clientdata(client);
124
125 switch (cmd) {
126 case VIDIOC_S_INPUT:
127 {
128 int *input = arg;
129
130 i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
131 i2c_smbus_write_byte_data(client, 0x09,
132 *input < 6 ? 0x40 : 0x80);
133 break;
134 }
135 case VIDIOC_S_STD:
136 {
137 v4l2_std_id *input = arg;
138 dec->norm = *input;
139 if (dec->norm & V4L2_STD_NTSC) {
140 write_reg(client, 0x0e, 0x01);
141 write_reg(client, 0x10, 0x40);
142 } else if (dec->norm & V4L2_STD_PAL) {
143 write_reg(client, 0x0e, 0x01);
144 write_reg(client, 0x10, 0x48);
145 } else if (dec->norm * V4L2_STD_SECAM) {
146 write_reg(client, 0x0e, 0x50);
147 write_reg(client, 0x10, 0x48);
148 }
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 = 0;
160 ctrl->maximum = 255;
161 ctrl->step = 1;
162 ctrl->default_value = 128;
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 = 127;
170 ctrl->step = 1;
171 ctrl->default_value = 71;
172 ctrl->flags = 0;
173 break;
174 case V4L2_CID_SATURATION:
175 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
176 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
177 ctrl->minimum = 0;
178 ctrl->maximum = 127;
179 ctrl->step = 1;
180 ctrl->default_value = 64;
181 ctrl->flags = 0;
182 break;
183 case V4L2_CID_HUE:
184 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
185 strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
186 ctrl->minimum = -128;
187 ctrl->maximum = 127;
188 ctrl->step = 1;
189 ctrl->default_value = 0;
190 ctrl->flags = 0;
191 break;
192 }
193 break;
194 }
195 case VIDIOC_S_CTRL:
196 {
197 struct v4l2_control *ctrl = arg;
198
199 switch (ctrl->id) {
200 case V4L2_CID_BRIGHTNESS:
201 if (ctrl->value > 255)
202 dec->brightness = 255;
203 else if (ctrl->value < 0)
204 dec->brightness = 0;
205 else
206 dec->brightness = ctrl->value;
207 write_reg(client, 0x0a, dec->brightness);
208 break;
209 case V4L2_CID_CONTRAST:
210 if (ctrl->value > 127)
211 dec->contrast = 127;
212 else if (ctrl->value < 0)
213 dec->contrast = 0;
214 else
215 dec->contrast = ctrl->value;
216 write_reg(client, 0x0b, dec->contrast);
217 break;
218 case V4L2_CID_SATURATION:
219 if (ctrl->value > 127)
220 dec->saturation = 127;
221 else if (ctrl->value < 0)
222 dec->saturation = 0;
223 else
224 dec->saturation = ctrl->value;
225 write_reg(client, 0x0c, dec->saturation);
226 break;
227 case V4L2_CID_HUE:
228 if (ctrl->value > 127)
229 dec->hue = 127;
230 else if (ctrl->value < -128)
231 dec->hue = -128;
232 else
233 dec->hue = ctrl->value;
234 write_reg(client, 0x0d, dec->hue);
235 break;
236 }
237 break;
238 }
239 case VIDIOC_G_CTRL:
240 {
241 struct v4l2_control *ctrl = arg;
242
243 switch (ctrl->id) {
244 case V4L2_CID_BRIGHTNESS:
245 ctrl->value = dec->brightness;
246 break;
247 case V4L2_CID_CONTRAST:
248 ctrl->value = dec->contrast;
249 break;
250 case V4L2_CID_SATURATION:
251 ctrl->value = dec->saturation;
252 break;
253 case V4L2_CID_HUE:
254 ctrl->value = dec->hue;
255 break;
256 }
257 break;
258 }
259 default:
260 break;
261 }
262 return 0;
263}
264
265static int wis_saa7113_probe(struct i2c_client *client,
266 const struct i2c_device_id *id)
267{
268 struct i2c_adapter *adapter = client->adapter;
269 struct wis_saa7113 *dec;
270
271 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
272 return -ENODEV;
273
274 dec = kmalloc(sizeof(struct wis_saa7113), GFP_KERNEL);
275 if (dec == NULL)
276 return -ENOMEM;
277
278 dec->norm = V4L2_STD_NTSC;
279 dec->brightness = 128;
280 dec->contrast = 71;
281 dec->saturation = 64;
282 dec->hue = 0;
283 i2c_set_clientdata(client, dec);
284
285 printk(KERN_DEBUG
286 "wis-saa7113: initializing SAA7113 at address %d on %s\n",
287 client->addr, adapter->name);
288
289 if (write_regs(client, initial_registers) < 0) {
290 printk(KERN_ERR
291 "wis-saa7113: error initializing SAA7113\n");
292 kfree(dec);
293 return -ENODEV;
294 }
295
296 return 0;
297}
298
299static int wis_saa7113_remove(struct i2c_client *client)
300{
301 struct wis_saa7113 *dec = i2c_get_clientdata(client);
302
303 kfree(dec);
304 return 0;
305}
306
307static const struct i2c_device_id wis_saa7113_id[] = {
308 { "wis_saa7113", 0 },
309 { }
310};
311MODULE_DEVICE_TABLE(i2c, wis_saa7113_id);
312
313static struct i2c_driver wis_saa7113_driver = {
314 .driver = {
315 .name = "WIS SAA7113 I2C driver",
316 },
317 .probe = wis_saa7113_probe,
318 .remove = wis_saa7113_remove,
319 .command = wis_saa7113_command,
320 .id_table = wis_saa7113_id,
321};
322
323static int __init wis_saa7113_init(void)
324{
325 return i2c_add_driver(&wis_saa7113_driver);
326}
327
328static void __exit wis_saa7113_cleanup(void)
329{
330 i2c_del_driver(&wis_saa7113_driver);
331}
332
333module_init(wis_saa7113_init);
334module_exit(wis_saa7113_cleanup);
335
336MODULE_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..46cff59e28b
--- /dev/null
+++ b/drivers/staging/go7007/wis-saa7115.c
@@ -0,0 +1,469 @@
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/i2c.h>
21#include <linux/videodev2.h>
22#include <linux/ioctl.h>
23#include <linux/slab.h>
24
25#include "wis-i2c.h"
26
27struct wis_saa7115 {
28 int norm;
29 int brightness;
30 int contrast;
31 int saturation;
32 int hue;
33};
34
35static u8 initial_registers[] =
36{
37 0x01, 0x08,
38 0x02, 0xc0,
39 0x03, 0x20,
40 0x04, 0x80,
41 0x05, 0x80,
42 0x06, 0xeb,
43 0x07, 0xe0,
44 0x08, 0xf0, /* always toggle FID */
45 0x09, 0x40,
46 0x0a, 0x80,
47 0x0b, 0x40,
48 0x0c, 0x40,
49 0x0d, 0x00,
50 0x0e, 0x03,
51 0x0f, 0x2a,
52 0x10, 0x0e,
53 0x11, 0x00,
54 0x12, 0x8d,
55 0x13, 0x00,
56 0x14, 0x00,
57 0x15, 0x11,
58 0x16, 0x01,
59 0x17, 0xda,
60 0x18, 0x40,
61 0x19, 0x80,
62 0x1a, 0x00,
63 0x1b, 0x42,
64 0x1c, 0xa9,
65 0x30, 0x66,
66 0x31, 0x90,
67 0x32, 0x01,
68 0x34, 0x00,
69 0x35, 0x00,
70 0x36, 0x20,
71 0x38, 0x03,
72 0x39, 0x20,
73 0x3a, 0x88,
74 0x40, 0x00,
75 0x41, 0xff,
76 0x42, 0xff,
77 0x43, 0xff,
78 0x44, 0xff,
79 0x45, 0xff,
80 0x46, 0xff,
81 0x47, 0xff,
82 0x48, 0xff,
83 0x49, 0xff,
84 0x4a, 0xff,
85 0x4b, 0xff,
86 0x4c, 0xff,
87 0x4d, 0xff,
88 0x4e, 0xff,
89 0x4f, 0xff,
90 0x50, 0xff,
91 0x51, 0xff,
92 0x52, 0xff,
93 0x53, 0xff,
94 0x54, 0xf4 /*0xff*/,
95 0x55, 0xff,
96 0x56, 0xff,
97 0x57, 0xff,
98 0x58, 0x40,
99 0x59, 0x47,
100 0x5a, 0x06 /*0x03*/,
101 0x5b, 0x83,
102 0x5d, 0x06,
103 0x5e, 0x00,
104 0x80, 0x30, /* window defined scaler operation, task A and B enabled */
105 0x81, 0x03, /* use scaler datapath generated V */
106 0x83, 0x00,
107 0x84, 0x00,
108 0x85, 0x00,
109 0x86, 0x45,
110 0x87, 0x31,
111 0x88, 0xc0,
112 0x90, 0x02, /* task A process top field */
113 0x91, 0x08,
114 0x92, 0x09,
115 0x93, 0x80,
116 0x94, 0x06,
117 0x95, 0x00,
118 0x96, 0xc0,
119 0x97, 0x02,
120 0x98, 0x12,
121 0x99, 0x00,
122 0x9a, 0xf2,
123 0x9b, 0x00,
124 0x9c, 0xd0,
125 0x9d, 0x02,
126 0x9e, 0xf2,
127 0x9f, 0x00,
128 0xa0, 0x01,
129 0xa1, 0x01,
130 0xa2, 0x01,
131 0xa4, 0x80,
132 0xa5, 0x40,
133 0xa6, 0x40,
134 0xa8, 0x00,
135 0xa9, 0x04,
136 0xaa, 0x00,
137 0xac, 0x00,
138 0xad, 0x02,
139 0xae, 0x00,
140 0xb0, 0x00,
141 0xb1, 0x04,
142 0xb2, 0x00,
143 0xb3, 0x04,
144 0xb4, 0x00,
145 0xb8, 0x00,
146 0xbc, 0x00,
147 0xc0, 0x03, /* task B process bottom field */
148 0xc1, 0x08,
149 0xc2, 0x09,
150 0xc3, 0x80,
151 0xc4, 0x06,
152 0xc5, 0x00,
153 0xc6, 0xc0,
154 0xc7, 0x02,
155 0xc8, 0x12,
156 0xc9, 0x00,
157 0xca, 0xf2,
158 0xcb, 0x00,
159 0xcc, 0xd0,
160 0xcd, 0x02,
161 0xce, 0xf2,
162 0xcf, 0x00,
163 0xd0, 0x01,
164 0xd1, 0x01,
165 0xd2, 0x01,
166 0xd4, 0x80,
167 0xd5, 0x40,
168 0xd6, 0x40,
169 0xd8, 0x00,
170 0xd9, 0x04,
171 0xda, 0x00,
172 0xdc, 0x00,
173 0xdd, 0x02,
174 0xde, 0x00,
175 0xe0, 0x00,
176 0xe1, 0x04,
177 0xe2, 0x00,
178 0xe3, 0x04,
179 0xe4, 0x00,
180 0xe8, 0x00,
181 0x88, 0xf0, /* End of original static list */
182 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
183};
184
185static int write_reg(struct i2c_client *client, u8 reg, u8 value)
186{
187 return i2c_smbus_write_byte_data(client, reg, value);
188}
189
190static int write_regs(struct i2c_client *client, u8 *regs)
191{
192 int i;
193
194 for (i = 0; regs[i] != 0x00; i += 2)
195 if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
196 return -1;
197 return 0;
198}
199
200static int wis_saa7115_command(struct i2c_client *client,
201 unsigned int cmd, void *arg)
202{
203 struct wis_saa7115 *dec = i2c_get_clientdata(client);
204
205 switch (cmd) {
206 case VIDIOC_S_INPUT:
207 {
208 int *input = arg;
209
210 i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
211 i2c_smbus_write_byte_data(client, 0x09,
212 *input < 6 ? 0x40 : 0xC0);
213 break;
214 }
215 case DECODER_SET_RESOLUTION:
216 {
217 struct video_decoder_resolution *res = arg;
218 /* Course-grained scaler */
219 int h_integer_scaler = res->width < 704 ? 704 / res->width : 1;
220 /* Fine-grained scaler to take care of remainder */
221 int h_scaling_increment = (704 / h_integer_scaler) *
222 1024 / res->width;
223 /* Fine-grained scaler only */
224 int v_scaling_increment = (dec->norm & V4L2_STD_NTSC ?
225 240 : 288) * 1024 / res->height;
226 u8 regs[] = {
227 0x88, 0xc0,
228 0x9c, res->width & 0xff,
229 0x9d, res->width >> 8,
230 0x9e, res->height & 0xff,
231 0x9f, res->height >> 8,
232 0xa0, h_integer_scaler,
233 0xa1, 1,
234 0xa2, 1,
235 0xa8, h_scaling_increment & 0xff,
236 0xa9, h_scaling_increment >> 8,
237 0xac, (h_scaling_increment / 2) & 0xff,
238 0xad, (h_scaling_increment / 2) >> 8,
239 0xb0, v_scaling_increment & 0xff,
240 0xb1, v_scaling_increment >> 8,
241 0xb2, v_scaling_increment & 0xff,
242 0xb3, v_scaling_increment >> 8,
243 0xcc, res->width & 0xff,
244 0xcd, res->width >> 8,
245 0xce, res->height & 0xff,
246 0xcf, res->height >> 8,
247 0xd0, h_integer_scaler,
248 0xd1, 1,
249 0xd2, 1,
250 0xd8, h_scaling_increment & 0xff,
251 0xd9, h_scaling_increment >> 8,
252 0xdc, (h_scaling_increment / 2) & 0xff,
253 0xdd, (h_scaling_increment / 2) >> 8,
254 0xe0, v_scaling_increment & 0xff,
255 0xe1, v_scaling_increment >> 8,
256 0xe2, v_scaling_increment & 0xff,
257 0xe3, v_scaling_increment >> 8,
258 0x88, 0xf0,
259 0, 0,
260 };
261 write_regs(client, regs);
262 break;
263 }
264 case VIDIOC_S_STD:
265 {
266 v4l2_std_id *input = arg;
267 u8 regs[] = {
268 0x88, 0xc0,
269 0x98, *input & V4L2_STD_NTSC ? 0x12 : 0x16,
270 0x9a, *input & V4L2_STD_NTSC ? 0xf2 : 0x20,
271 0x9b, *input & V4L2_STD_NTSC ? 0x00 : 0x01,
272 0xc8, *input & V4L2_STD_NTSC ? 0x12 : 0x16,
273 0xca, *input & V4L2_STD_NTSC ? 0xf2 : 0x20,
274 0xcb, *input & V4L2_STD_NTSC ? 0x00 : 0x01,
275 0x88, 0xf0,
276 0x30, *input & V4L2_STD_NTSC ? 0x66 : 0x00,
277 0x31, *input & V4L2_STD_NTSC ? 0x90 : 0xe0,
278 0, 0,
279 };
280 write_regs(client, regs);
281 dec->norm = *input;
282 break;
283 }
284 case VIDIOC_QUERYCTRL:
285 {
286 struct v4l2_queryctrl *ctrl = arg;
287
288 switch (ctrl->id) {
289 case V4L2_CID_BRIGHTNESS:
290 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
291 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
292 ctrl->minimum = 0;
293 ctrl->maximum = 255;
294 ctrl->step = 1;
295 ctrl->default_value = 128;
296 ctrl->flags = 0;
297 break;
298 case V4L2_CID_CONTRAST:
299 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
300 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
301 ctrl->minimum = 0;
302 ctrl->maximum = 127;
303 ctrl->step = 1;
304 ctrl->default_value = 64;
305 ctrl->flags = 0;
306 break;
307 case V4L2_CID_SATURATION:
308 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
309 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
310 ctrl->minimum = 0;
311 ctrl->maximum = 127;
312 ctrl->step = 1;
313 ctrl->default_value = 64;
314 ctrl->flags = 0;
315 break;
316 case V4L2_CID_HUE:
317 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
318 strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
319 ctrl->minimum = -128;
320 ctrl->maximum = 127;
321 ctrl->step = 1;
322 ctrl->default_value = 0;
323 ctrl->flags = 0;
324 break;
325 }
326 break;
327 }
328 case VIDIOC_S_CTRL:
329 {
330 struct v4l2_control *ctrl = arg;
331
332 switch (ctrl->id) {
333 case V4L2_CID_BRIGHTNESS:
334 if (ctrl->value > 255)
335 dec->brightness = 255;
336 else if (ctrl->value < 0)
337 dec->brightness = 0;
338 else
339 dec->brightness = ctrl->value;
340 write_reg(client, 0x0a, dec->brightness);
341 break;
342 case V4L2_CID_CONTRAST:
343 if (ctrl->value > 127)
344 dec->contrast = 127;
345 else if (ctrl->value < 0)
346 dec->contrast = 0;
347 else
348 dec->contrast = ctrl->value;
349 write_reg(client, 0x0b, dec->contrast);
350 break;
351 case V4L2_CID_SATURATION:
352 if (ctrl->value > 127)
353 dec->saturation = 127;
354 else if (ctrl->value < 0)
355 dec->saturation = 0;
356 else
357 dec->saturation = ctrl->value;
358 write_reg(client, 0x0c, dec->saturation);
359 break;
360 case V4L2_CID_HUE:
361 if (ctrl->value > 127)
362 dec->hue = 127;
363 else if (ctrl->value < -128)
364 dec->hue = -128;
365 else
366 dec->hue = ctrl->value;
367 write_reg(client, 0x0d, dec->hue);
368 break;
369 }
370 break;
371 }
372 case VIDIOC_G_CTRL:
373 {
374 struct v4l2_control *ctrl = arg;
375
376 switch (ctrl->id) {
377 case V4L2_CID_BRIGHTNESS:
378 ctrl->value = dec->brightness;
379 break;
380 case V4L2_CID_CONTRAST:
381 ctrl->value = dec->contrast;
382 break;
383 case V4L2_CID_SATURATION:
384 ctrl->value = dec->saturation;
385 break;
386 case V4L2_CID_HUE:
387 ctrl->value = dec->hue;
388 break;
389 }
390 break;
391 }
392 default:
393 break;
394 }
395 return 0;
396}
397
398static int wis_saa7115_probe(struct i2c_client *client,
399 const struct i2c_device_id *id)
400{
401 struct i2c_adapter *adapter = client->adapter;
402 struct wis_saa7115 *dec;
403
404 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
405 return -ENODEV;
406
407 dec = kmalloc(sizeof(struct wis_saa7115), GFP_KERNEL);
408 if (dec == NULL)
409 return -ENOMEM;
410
411 dec->norm = V4L2_STD_NTSC;
412 dec->brightness = 128;
413 dec->contrast = 64;
414 dec->saturation = 64;
415 dec->hue = 0;
416 i2c_set_clientdata(client, dec);
417
418 printk(KERN_DEBUG
419 "wis-saa7115: initializing SAA7115 at address %d on %s\n",
420 client->addr, adapter->name);
421
422 if (write_regs(client, initial_registers) < 0) {
423 printk(KERN_ERR
424 "wis-saa7115: error initializing SAA7115\n");
425 kfree(dec);
426 return -ENODEV;
427 }
428
429 return 0;
430}
431
432static int wis_saa7115_remove(struct i2c_client *client)
433{
434 struct wis_saa7115 *dec = i2c_get_clientdata(client);
435
436 kfree(dec);
437 return 0;
438}
439
440static const struct i2c_device_id wis_saa7115_id[] = {
441 { "wis_saa7115", 0 },
442 { }
443};
444MODULE_DEVICE_TABLE(i2c, wis_saa7115_id);
445
446static struct i2c_driver wis_saa7115_driver = {
447 .driver = {
448 .name = "WIS SAA7115 I2C driver",
449 },
450 .probe = wis_saa7115_probe,
451 .remove = wis_saa7115_remove,
452 .command = wis_saa7115_command,
453 .id_table = wis_saa7115_id,
454};
455
456static int __init wis_saa7115_init(void)
457{
458 return i2c_add_driver(&wis_saa7115_driver);
459}
460
461static void __exit wis_saa7115_cleanup(void)
462{
463 i2c_del_driver(&wis_saa7115_driver);
464}
465
466module_init(wis_saa7115_init);
467module_exit(wis_saa7115_cleanup);
468
469MODULE_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..8f1b7d4f6a2
--- /dev/null
+++ b/drivers/staging/go7007/wis-sony-tuner.c
@@ -0,0 +1,720 @@
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/i2c.h>
21#include <linux/videodev2.h>
22#include <linux/slab.h>
23#include <media/tuner.h>
24#include <media/v4l2-common.h>
25#include <media/v4l2-ioctl.h>
26
27#include "wis-i2c.h"
28
29/* #define MPX_DEBUG */
30
31/* AS(IF/MPX) pin: LOW HIGH/OPEN
32 * IF/MPX address: 0x42/0x40 0x43/0x44
33 */
34#define IF_I2C_ADDR 0x43
35#define MPX_I2C_ADDR 0x44
36
37static v4l2_std_id force_band;
38static char force_band_str[] = "-";
39module_param_string(force_band, force_band_str, sizeof(force_band_str), 0644);
40static int force_mpx_mode = -1;
41module_param(force_mpx_mode, int, 0644);
42
43/* Store tuner info in the same format as tuner.c, so maybe we can put the
44 * Sony tuner support in there. */
45struct sony_tunertype {
46 char *name;
47 unsigned char Vendor; /* unused here */
48 unsigned char Type; /* unused here */
49
50 unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */
51 unsigned short thresh2; /* band switch VHF_HI <=> UHF */
52 unsigned char VHF_L;
53 unsigned char VHF_H;
54 unsigned char UHF;
55 unsigned char config;
56 unsigned short IFPCoff;
57};
58
59/* This array is indexed by (tuner_type - 200) */
60static struct sony_tunertype sony_tuners[] = {
61 { "Sony PAL+SECAM (BTF-PG472Z)", 0, 0,
62 16*144.25, 16*427.25, 0x01, 0x02, 0x04, 0xc6, 623},
63 { "Sony NTSC_JP (BTF-PK467Z)", 0, 0,
64 16*220.25, 16*467.25, 0x01, 0x02, 0x04, 0xc6, 940},
65 { "Sony NTSC (BTF-PB463Z)", 0, 0,
66 16*130.25, 16*364.25, 0x01, 0x02, 0x04, 0xc6, 732},
67};
68
69struct wis_sony_tuner {
70 int type;
71 v4l2_std_id std;
72 unsigned int freq;
73 int mpxmode;
74 u32 audmode;
75};
76
77/* Basically the same as default_set_tv_freq() in tuner.c */
78static int set_freq(struct i2c_client *client, int freq)
79{
80 struct wis_sony_tuner *t = i2c_get_clientdata(client);
81 char *band_name;
82 int n;
83 int band_select;
84 struct sony_tunertype *tun;
85 u8 buffer[4];
86
87 tun = &sony_tuners[t->type - 200];
88 if (freq < tun->thresh1) {
89 band_name = "VHF_L";
90 band_select = tun->VHF_L;
91 } else if (freq < tun->thresh2) {
92 band_name = "VHF_H";
93 band_select = tun->VHF_H;
94 } else {
95 band_name = "UHF";
96 band_select = tun->UHF;
97 }
98 printk(KERN_DEBUG "wis-sony-tuner: tuning to frequency %d.%04d (%s)\n",
99 freq / 16, (freq % 16) * 625, band_name);
100 n = freq + tun->IFPCoff;
101
102 buffer[0] = n >> 8;
103 buffer[1] = n & 0xff;
104 buffer[2] = tun->config;
105 buffer[3] = band_select;
106 i2c_master_send(client, buffer, 4);
107
108 return 0;
109}
110
111static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
112{
113 u8 buffer[5];
114 struct i2c_msg msg;
115
116 buffer[0] = dev;
117 buffer[1] = addr >> 8;
118 buffer[2] = addr & 0xff;
119 buffer[3] = val >> 8;
120 buffer[4] = val & 0xff;
121 msg.addr = MPX_I2C_ADDR;
122 msg.flags = 0;
123 msg.len = 5;
124 msg.buf = buffer;
125 i2c_transfer(client->adapter, &msg, 1);
126 return 0;
127}
128
129/*
130 * MPX register values for the BTF-PG472Z:
131 *
132 * FM_ NICAM_ SCART_
133 * MODUS SOURCE ACB PRESCAL PRESCAL PRESCAL SYSTEM VOLUME
134 * 10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000
135 * ---------------------------------------------------------------
136 * Auto 1003 0020 0100 2603 5000 XXXX 0001 7500
137 *
138 * B/G
139 * Mono 1003 0020 0100 2603 5000 XXXX 0003 7500
140 * A2 1003 0020 0100 2601 5000 XXXX 0003 7500
141 * NICAM 1003 0120 0100 2603 5000 XXXX 0008 7500
142 *
143 * I
144 * Mono 1003 0020 0100 2603 7900 XXXX 000A 7500
145 * NICAM 1003 0120 0100 2603 7900 XXXX 000A 7500
146 *
147 * D/K
148 * Mono 1003 0020 0100 2603 5000 XXXX 0004 7500
149 * A2-1 1003 0020 0100 2601 5000 XXXX 0004 7500
150 * A2-2 1003 0020 0100 2601 5000 XXXX 0005 7500
151 * A2-3 1003 0020 0100 2601 5000 XXXX 0007 7500
152 * NICAM 1003 0120 0100 2603 5000 XXXX 000B 7500
153 *
154 * L/L'
155 * Mono 0003 0200 0100 7C03 5000 2200 0009 7500
156 * NICAM 0003 0120 0100 7C03 5000 XXXX 0009 7500
157 *
158 * M
159 * Mono 1003 0200 0100 2B03 5000 2B00 0002 7500
160 *
161 * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX.
162 *
163 * Bilingual selection in A2/NICAM:
164 *
165 * High byte of SOURCE Left chan Right chan
166 * 0x01 MAIN SUB
167 * 0x03 MAIN MAIN
168 * 0x04 SUB SUB
169 *
170 * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or
171 * 0x00 (all other bands). Force mono in A2 with FMONO_A2:
172 *
173 * FMONO_A2
174 * 10/0022
175 * --------
176 * Forced mono ON 07F0
177 * Forced mono OFF 0190
178 */
179
180static struct {
181 enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
182 u16 modus;
183 u16 source;
184 u16 acb;
185 u16 fm_prescale;
186 u16 nicam_prescale;
187 u16 scart_prescale;
188 u16 system;
189 u16 volume;
190} mpx_audio_modes[] = {
191 /* Auto */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
192 0x5000, 0x0000, 0x0001, 0x7500 },
193 /* B/G Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
194 0x5000, 0x0000, 0x0003, 0x7500 },
195 /* B/G A2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
196 0x5000, 0x0000, 0x0003, 0x7500 },
197 /* B/G NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
198 0x5000, 0x0000, 0x0008, 0x7500 },
199 /* I Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
200 0x7900, 0x0000, 0x000A, 0x7500 },
201 /* I NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
202 0x7900, 0x0000, 0x000A, 0x7500 },
203 /* D/K Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
204 0x5000, 0x0000, 0x0004, 0x7500 },
205 /* D/K A2-1 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
206 0x5000, 0x0000, 0x0004, 0x7500 },
207 /* D/K A2-2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
208 0x5000, 0x0000, 0x0005, 0x7500 },
209 /* D/K A2-3 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
210 0x5000, 0x0000, 0x0007, 0x7500 },
211 /* D/K NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
212 0x5000, 0x0000, 0x000B, 0x7500 },
213 /* L/L' Mono */ { AUD_MONO, 0x0003, 0x0200, 0x0100, 0x7C03,
214 0x5000, 0x2200, 0x0009, 0x7500 },
215 /* L/L' NICAM */{ AUD_NICAM_L, 0x0003, 0x0120, 0x0100, 0x7C03,
216 0x5000, 0x0000, 0x0009, 0x7500 },
217};
218
219#define MPX_NUM_MODES ARRAY_SIZE(mpx_audio_modes)
220
221static int mpx_setup(struct i2c_client *client)
222{
223 struct wis_sony_tuner *t = i2c_get_clientdata(client);
224 u16 source = 0;
225 u8 buffer[3];
226 struct i2c_msg msg;
227
228 /* reset MPX */
229 buffer[0] = 0x00;
230 buffer[1] = 0x80;
231 buffer[2] = 0x00;
232 msg.addr = MPX_I2C_ADDR;
233 msg.flags = 0;
234 msg.len = 3;
235 msg.buf = buffer;
236 i2c_transfer(client->adapter, &msg, 1);
237 buffer[1] = 0x00;
238 i2c_transfer(client->adapter, &msg, 1);
239
240 if (mpx_audio_modes[t->mpxmode].audio_mode != AUD_MONO) {
241 switch (t->audmode) {
242 case V4L2_TUNER_MODE_MONO:
243 switch (mpx_audio_modes[t->mpxmode].audio_mode) {
244 case AUD_A2:
245 source = mpx_audio_modes[t->mpxmode].source;
246 break;
247 case AUD_NICAM:
248 source = 0x0000;
249 break;
250 case AUD_NICAM_L:
251 source = 0x0200;
252 break;
253 default:
254 break;
255 }
256 break;
257 case V4L2_TUNER_MODE_STEREO:
258 source = mpx_audio_modes[t->mpxmode].source;
259 break;
260 case V4L2_TUNER_MODE_LANG1:
261 source = 0x0300;
262 break;
263 case V4L2_TUNER_MODE_LANG2:
264 source = 0x0400;
265 break;
266 }
267 source |= mpx_audio_modes[t->mpxmode].source & 0x00ff;
268 } else
269 source = mpx_audio_modes[t->mpxmode].source;
270
271 mpx_write(client, 0x10, 0x0030, mpx_audio_modes[t->mpxmode].modus);
272 mpx_write(client, 0x12, 0x0008, source);
273 mpx_write(client, 0x12, 0x0013, mpx_audio_modes[t->mpxmode].acb);
274 mpx_write(client, 0x12, 0x000e,
275 mpx_audio_modes[t->mpxmode].fm_prescale);
276 mpx_write(client, 0x12, 0x0010,
277 mpx_audio_modes[t->mpxmode].nicam_prescale);
278 mpx_write(client, 0x12, 0x000d,
279 mpx_audio_modes[t->mpxmode].scart_prescale);
280 mpx_write(client, 0x10, 0x0020, mpx_audio_modes[t->mpxmode].system);
281 mpx_write(client, 0x12, 0x0000, mpx_audio_modes[t->mpxmode].volume);
282 if (mpx_audio_modes[t->mpxmode].audio_mode == AUD_A2)
283 mpx_write(client, 0x10, 0x0022,
284 t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190);
285
286#ifdef MPX_DEBUG
287 {
288 u8 buf1[3], buf2[2];
289 struct i2c_msg msgs[2];
290
291 printk(KERN_DEBUG "wis-sony-tuner: MPX registers: %04x %04x "
292 "%04x %04x %04x %04x %04x %04x\n",
293 mpx_audio_modes[t->mpxmode].modus,
294 source,
295 mpx_audio_modes[t->mpxmode].acb,
296 mpx_audio_modes[t->mpxmode].fm_prescale,
297 mpx_audio_modes[t->mpxmode].nicam_prescale,
298 mpx_audio_modes[t->mpxmode].scart_prescale,
299 mpx_audio_modes[t->mpxmode].system,
300 mpx_audio_modes[t->mpxmode].volume);
301 buf1[0] = 0x11;
302 buf1[1] = 0x00;
303 buf1[2] = 0x7e;
304 msgs[0].addr = MPX_I2C_ADDR;
305 msgs[0].flags = 0;
306 msgs[0].len = 3;
307 msgs[0].buf = buf1;
308 msgs[1].addr = MPX_I2C_ADDR;
309 msgs[1].flags = I2C_M_RD;
310 msgs[1].len = 2;
311 msgs[1].buf = buf2;
312 i2c_transfer(client->adapter, msgs, 2);
313 printk(KERN_DEBUG "wis-sony-tuner: MPX system: %02x%02x\n",
314 buf2[0], buf2[1]);
315 buf1[0] = 0x11;
316 buf1[1] = 0x02;
317 buf1[2] = 0x00;
318 i2c_transfer(client->adapter, msgs, 2);
319 printk(KERN_DEBUG "wis-sony-tuner: MPX status: %02x%02x\n",
320 buf2[0], buf2[1]);
321 }
322#endif
323 return 0;
324}
325
326/*
327 * IF configuration values for the BTF-PG472Z:
328 *
329 * B/G: 0x94 0x70 0x49
330 * I: 0x14 0x70 0x4a
331 * D/K: 0x14 0x70 0x4b
332 * L: 0x04 0x70 0x4b
333 * L': 0x44 0x70 0x53
334 * M: 0x50 0x30 0x4c
335 */
336
337static int set_if(struct i2c_client *client)
338{
339 struct wis_sony_tuner *t = i2c_get_clientdata(client);
340 u8 buffer[4];
341 struct i2c_msg msg;
342 int default_mpx_mode = 0;
343
344 /* configure IF */
345 buffer[0] = 0;
346 if (t->std & V4L2_STD_PAL_BG) {
347 buffer[1] = 0x94;
348 buffer[2] = 0x70;
349 buffer[3] = 0x49;
350 default_mpx_mode = 1;
351 } else if (t->std & V4L2_STD_PAL_I) {
352 buffer[1] = 0x14;
353 buffer[2] = 0x70;
354 buffer[3] = 0x4a;
355 default_mpx_mode = 4;
356 } else if (t->std & V4L2_STD_PAL_DK) {
357 buffer[1] = 0x14;
358 buffer[2] = 0x70;
359 buffer[3] = 0x4b;
360 default_mpx_mode = 6;
361 } else if (t->std & V4L2_STD_SECAM_L) {
362 buffer[1] = 0x04;
363 buffer[2] = 0x70;
364 buffer[3] = 0x4b;
365 default_mpx_mode = 11;
366 }
367 msg.addr = IF_I2C_ADDR;
368 msg.flags = 0;
369 msg.len = 4;
370 msg.buf = buffer;
371 i2c_transfer(client->adapter, &msg, 1);
372
373 /* Select MPX mode if not forced by the user */
374 if (force_mpx_mode >= 0 && force_mpx_mode < MPX_NUM_MODES)
375 t->mpxmode = force_mpx_mode;
376 else
377 t->mpxmode = default_mpx_mode;
378 printk(KERN_DEBUG "wis-sony-tuner: setting MPX to mode %d\n",
379 t->mpxmode);
380 mpx_setup(client);
381
382 return 0;
383}
384
385static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
386{
387 struct wis_sony_tuner *t = i2c_get_clientdata(client);
388
389 switch (cmd) {
390#if 0
391#ifdef TUNER_SET_TYPE_ADDR
392 case TUNER_SET_TYPE_ADDR:
393 {
394 struct tuner_setup *tun_setup = arg;
395 int *type = &tun_setup->type;
396#else
397 case TUNER_SET_TYPE:
398 {
399 int *type = arg;
400#endif
401
402 if (t->type >= 0) {
403 if (t->type != *type)
404 printk(KERN_ERR "wis-sony-tuner: type already "
405 "set to %d, ignoring request for %d\n",
406 t->type, *type);
407 break;
408 }
409 t->type = *type;
410 switch (t->type) {
411 case TUNER_SONY_BTF_PG472Z:
412 switch (force_band_str[0]) {
413 case 'b':
414 case 'B':
415 case 'g':
416 case 'G':
417 printk(KERN_INFO "wis-sony-tuner: forcing "
418 "tuner to PAL-B/G bands\n");
419 force_band = V4L2_STD_PAL_BG;
420 break;
421 case 'i':
422 case 'I':
423 printk(KERN_INFO "wis-sony-tuner: forcing "
424 "tuner to PAL-I band\n");
425 force_band = V4L2_STD_PAL_I;
426 break;
427 case 'd':
428 case 'D':
429 case 'k':
430 case 'K':
431 printk(KERN_INFO "wis-sony-tuner: forcing "
432 "tuner to PAL-D/K bands\n");
433 force_band = V4L2_STD_PAL_I;
434 break;
435 case 'l':
436 case 'L':
437 printk(KERN_INFO "wis-sony-tuner: forcing "
438 "tuner to SECAM-L band\n");
439 force_band = V4L2_STD_SECAM_L;
440 break;
441 default:
442 force_band = 0;
443 break;
444 }
445 if (force_band)
446 t->std = force_band;
447 else
448 t->std = V4L2_STD_PAL_BG;
449 set_if(client);
450 break;
451 case TUNER_SONY_BTF_PK467Z:
452 t->std = V4L2_STD_NTSC_M_JP;
453 break;
454 case TUNER_SONY_BTF_PB463Z:
455 t->std = V4L2_STD_NTSC_M;
456 break;
457 default:
458 printk(KERN_ERR "wis-sony-tuner: tuner type %d is not "
459 "supported by this module\n", *type);
460 break;
461 }
462 if (type >= 0)
463 printk(KERN_INFO
464 "wis-sony-tuner: type set to %d (%s)\n",
465 t->type, sony_tuners[t->type - 200].name);
466 break;
467 }
468#endif
469 case VIDIOC_G_FREQUENCY:
470 {
471 struct v4l2_frequency *f = arg;
472
473 f->frequency = t->freq;
474 break;
475 }
476 case VIDIOC_S_FREQUENCY:
477 {
478 struct v4l2_frequency *f = arg;
479
480 t->freq = f->frequency;
481 set_freq(client, t->freq);
482 break;
483 }
484 case VIDIOC_ENUMSTD:
485 {
486 struct v4l2_standard *std = arg;
487
488 switch (t->type) {
489 case TUNER_SONY_BTF_PG472Z:
490 switch (std->index) {
491 case 0:
492 v4l2_video_std_construct(std,
493 V4L2_STD_PAL_BG, "PAL-B/G");
494 break;
495 case 1:
496 v4l2_video_std_construct(std,
497 V4L2_STD_PAL_I, "PAL-I");
498 break;
499 case 2:
500 v4l2_video_std_construct(std,
501 V4L2_STD_PAL_DK, "PAL-D/K");
502 break;
503 case 3:
504 v4l2_video_std_construct(std,
505 V4L2_STD_SECAM_L, "SECAM-L");
506 break;
507 default:
508 std->id = 0; /* hack to indicate EINVAL */
509 break;
510 }
511 break;
512 case TUNER_SONY_BTF_PK467Z:
513 if (std->index != 0) {
514 std->id = 0; /* hack to indicate EINVAL */
515 break;
516 }
517 v4l2_video_std_construct(std,
518 V4L2_STD_NTSC_M_JP, "NTSC-J");
519 break;
520 case TUNER_SONY_BTF_PB463Z:
521 if (std->index != 0) {
522 std->id = 0; /* hack to indicate EINVAL */
523 break;
524 }
525 v4l2_video_std_construct(std, V4L2_STD_NTSC_M, "NTSC");
526 break;
527 }
528 break;
529 }
530 case VIDIOC_G_STD:
531 {
532 v4l2_std_id *std = arg;
533
534 *std = t->std;
535 break;
536 }
537 case VIDIOC_S_STD:
538 {
539 v4l2_std_id *std = arg;
540 v4l2_std_id old = t->std;
541
542 switch (t->type) {
543 case TUNER_SONY_BTF_PG472Z:
544 if (force_band && (*std & force_band) != *std &&
545 *std != V4L2_STD_PAL &&
546 *std != V4L2_STD_SECAM) {
547 printk(KERN_DEBUG "wis-sony-tuner: ignoring "
548 "requested TV standard in "
549 "favor of force_band value\n");
550 t->std = force_band;
551 } else if (*std & V4L2_STD_PAL_BG) { /* default */
552 t->std = V4L2_STD_PAL_BG;
553 } else if (*std & V4L2_STD_PAL_I) {
554 t->std = V4L2_STD_PAL_I;
555 } else if (*std & V4L2_STD_PAL_DK) {
556 t->std = V4L2_STD_PAL_DK;
557 } else if (*std & V4L2_STD_SECAM_L) {
558 t->std = V4L2_STD_SECAM_L;
559 } else {
560 printk(KERN_ERR "wis-sony-tuner: TV standard "
561 "not supported\n");
562 *std = 0; /* hack to indicate EINVAL */
563 break;
564 }
565 if (old != t->std)
566 set_if(client);
567 break;
568 case TUNER_SONY_BTF_PK467Z:
569 if (!(*std & V4L2_STD_NTSC_M_JP)) {
570 printk(KERN_ERR "wis-sony-tuner: TV standard "
571 "not supported\n");
572 *std = 0; /* hack to indicate EINVAL */
573 }
574 break;
575 case TUNER_SONY_BTF_PB463Z:
576 if (!(*std & V4L2_STD_NTSC_M)) {
577 printk(KERN_ERR "wis-sony-tuner: TV standard "
578 "not supported\n");
579 *std = 0; /* hack to indicate EINVAL */
580 }
581 break;
582 }
583 break;
584 }
585 case VIDIOC_QUERYSTD:
586 {
587 v4l2_std_id *std = arg;
588
589 switch (t->type) {
590 case TUNER_SONY_BTF_PG472Z:
591 if (force_band)
592 *std = force_band;
593 else
594 *std = V4L2_STD_PAL_BG | V4L2_STD_PAL_I |
595 V4L2_STD_PAL_DK | V4L2_STD_SECAM_L;
596 break;
597 case TUNER_SONY_BTF_PK467Z:
598 *std = V4L2_STD_NTSC_M_JP;
599 break;
600 case TUNER_SONY_BTF_PB463Z:
601 *std = V4L2_STD_NTSC_M;
602 break;
603 }
604 break;
605 }
606 case VIDIOC_G_TUNER:
607 {
608 struct v4l2_tuner *tun = arg;
609
610 memset(tun, 0, sizeof(*tun));
611 strcpy(tun->name, "Television");
612 tun->type = V4L2_TUNER_ANALOG_TV;
613 tun->rangelow = 0UL; /* does anything use these? */
614 tun->rangehigh = 0xffffffffUL;
615 switch (t->type) {
616 case TUNER_SONY_BTF_PG472Z:
617 tun->capability = V4L2_TUNER_CAP_NORM |
618 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
619 V4L2_TUNER_CAP_LANG2;
620 tun->rxsubchans = V4L2_TUNER_SUB_MONO |
621 V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
622 V4L2_TUNER_SUB_LANG2;
623 break;
624 case TUNER_SONY_BTF_PK467Z:
625 case TUNER_SONY_BTF_PB463Z:
626 tun->capability = V4L2_TUNER_CAP_STEREO;
627 tun->rxsubchans = V4L2_TUNER_SUB_MONO |
628 V4L2_TUNER_SUB_STEREO;
629 break;
630 }
631 tun->audmode = t->audmode;
632 return 0;
633 }
634 case VIDIOC_S_TUNER:
635 {
636 struct v4l2_tuner *tun = arg;
637
638 switch (t->type) {
639 case TUNER_SONY_BTF_PG472Z:
640 if (tun->audmode != t->audmode) {
641 t->audmode = tun->audmode;
642 mpx_setup(client);
643 }
644 break;
645 case TUNER_SONY_BTF_PK467Z:
646 case TUNER_SONY_BTF_PB463Z:
647 break;
648 }
649 return 0;
650 }
651 default:
652 break;
653 }
654 return 0;
655}
656
657static int wis_sony_tuner_probe(struct i2c_client *client,
658 const struct i2c_device_id *id)
659{
660 struct i2c_adapter *adapter = client->adapter;
661 struct wis_sony_tuner *t;
662
663 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
664 return -ENODEV;
665
666 t = kmalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL);
667 if (t == NULL)
668 return -ENOMEM;
669
670 t->type = -1;
671 t->freq = 0;
672 t->mpxmode = 0;
673 t->audmode = V4L2_TUNER_MODE_STEREO;
674 i2c_set_clientdata(client, t);
675
676 printk(KERN_DEBUG
677 "wis-sony-tuner: initializing tuner at address %d on %s\n",
678 client->addr, adapter->name);
679
680 return 0;
681}
682
683static int wis_sony_tuner_remove(struct i2c_client *client)
684{
685 struct wis_sony_tuner *t = i2c_get_clientdata(client);
686
687 kfree(t);
688 return 0;
689}
690
691static const struct i2c_device_id wis_sony_tuner_id[] = {
692 { "wis_sony_tuner", 0 },
693 { }
694};
695MODULE_DEVICE_TABLE(i2c, wis_sony_tuner_id);
696
697static struct i2c_driver wis_sony_tuner_driver = {
698 .driver = {
699 .name = "WIS Sony TV Tuner I2C driver",
700 },
701 .probe = wis_sony_tuner_probe,
702 .remove = wis_sony_tuner_remove,
703 .command = tuner_command,
704 .id_table = wis_sony_tuner_id,
705};
706
707static int __init wis_sony_tuner_init(void)
708{
709 return i2c_add_driver(&wis_sony_tuner_driver);
710}
711
712static void __exit wis_sony_tuner_cleanup(void)
713{
714 i2c_del_driver(&wis_sony_tuner_driver);
715}
716
717module_init(wis_sony_tuner_init);
718module_exit(wis_sony_tuner_cleanup);
719
720MODULE_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..5b218c55842
--- /dev/null
+++ b/drivers/staging/go7007/wis-tw2804.c
@@ -0,0 +1,359 @@
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/i2c.h>
21#include <linux/videodev2.h>
22#include <linux/ioctl.h>
23#include <linux/slab.h>
24
25#include "wis-i2c.h"
26
27struct wis_tw2804 {
28 int channel;
29 int norm;
30 int brightness;
31 int contrast;
32 int saturation;
33 int hue;
34};
35
36static u8 global_registers[] =
37{
38 0x39, 0x00,
39 0x3a, 0xff,
40 0x3b, 0x84,
41 0x3c, 0x80,
42 0x3d, 0x80,
43 0x3e, 0x82,
44 0x3f, 0x82,
45 0xff, 0xff, /* Terminator (reg 0xff does not exist) */
46};
47
48static u8 channel_registers[] =
49{
50 0x01, 0xc4,
51 0x02, 0xa5,
52 0x03, 0x20,
53 0x04, 0xd0,
54 0x05, 0x20,
55 0x06, 0xd0,
56 0x07, 0x88,
57 0x08, 0x20,
58 0x09, 0x07,
59 0x0a, 0xf0,
60 0x0b, 0x07,
61 0x0c, 0xf0,
62 0x0d, 0x40,
63 0x0e, 0xd2,
64 0x0f, 0x80,
65 0x10, 0x80,
66 0x11, 0x80,
67 0x12, 0x80,
68 0x13, 0x1f,
69 0x14, 0x00,
70 0x15, 0x00,
71 0x16, 0x00,
72 0x17, 0x00,
73 0x18, 0xff,
74 0x19, 0xff,
75 0x1a, 0xff,
76 0x1b, 0xff,
77 0x1c, 0xff,
78 0x1d, 0xff,
79 0x1e, 0xff,
80 0x1f, 0xff,
81 0x20, 0x07,
82 0x21, 0x07,
83 0x22, 0x00,
84 0x23, 0x91,
85 0x24, 0x51,
86 0x25, 0x03,
87 0x26, 0x00,
88 0x27, 0x00,
89 0x28, 0x00,
90 0x29, 0x00,
91 0x2a, 0x00,
92 0x2b, 0x00,
93 0x2c, 0x00,
94 0x2d, 0x00,
95 0x2e, 0x00,
96 0x2f, 0x00,
97 0x30, 0x00,
98 0x31, 0x00,
99 0x32, 0x00,
100 0x33, 0x00,
101 0x34, 0x00,
102 0x35, 0x00,
103 0x36, 0x00,
104 0x37, 0x00,
105 0xff, 0xff, /* Terminator (reg 0xff does not exist) */
106};
107
108static int write_reg(struct i2c_client *client, u8 reg, u8 value, int channel)
109{
110 return i2c_smbus_write_byte_data(client, reg | (channel << 6), value);
111}
112
113static int write_regs(struct i2c_client *client, u8 *regs, int channel)
114{
115 int i;
116
117 for (i = 0; regs[i] != 0xff; i += 2)
118 if (i2c_smbus_write_byte_data(client,
119 regs[i] | (channel << 6), regs[i + 1]) < 0)
120 return -1;
121 return 0;
122}
123
124static int wis_tw2804_command(struct i2c_client *client,
125 unsigned int cmd, void *arg)
126{
127 struct wis_tw2804 *dec = i2c_get_clientdata(client);
128
129 if (cmd == DECODER_SET_CHANNEL) {
130 int *input = arg;
131
132 if (*input < 0 || *input > 3) {
133 printk(KERN_ERR "wis-tw2804: channel %d is not "
134 "between 0 and 3!\n", *input);
135 return 0;
136 }
137 dec->channel = *input;
138 printk(KERN_DEBUG "wis-tw2804: initializing TW2804 "
139 "channel %d\n", dec->channel);
140 if (dec->channel == 0 &&
141 write_regs(client, global_registers, 0) < 0) {
142 printk(KERN_ERR "wis-tw2804: error initializing "
143 "TW2804 global registers\n");
144 return 0;
145 }
146 if (write_regs(client, channel_registers, dec->channel) < 0) {
147 printk(KERN_ERR "wis-tw2804: error initializing "
148 "TW2804 channel %d\n", dec->channel);
149 return 0;
150 }
151 return 0;
152 }
153
154 if (dec->channel < 0) {
155 printk(KERN_DEBUG "wis-tw2804: ignoring command %08x until "
156 "channel number is set\n", cmd);
157 return 0;
158 }
159
160 switch (cmd) {
161 case VIDIOC_S_STD:
162 {
163 v4l2_std_id *input = arg;
164 u8 regs[] = {
165 0x01, *input & V4L2_STD_NTSC ? 0xc4 : 0x84,
166 0x09, *input & V4L2_STD_NTSC ? 0x07 : 0x04,
167 0x0a, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
168 0x0b, *input & V4L2_STD_NTSC ? 0x07 : 0x04,
169 0x0c, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
170 0x0d, *input & V4L2_STD_NTSC ? 0x40 : 0x4a,
171 0x16, *input & V4L2_STD_NTSC ? 0x00 : 0x40,
172 0x17, *input & V4L2_STD_NTSC ? 0x00 : 0x40,
173 0x20, *input & V4L2_STD_NTSC ? 0x07 : 0x0f,
174 0x21, *input & V4L2_STD_NTSC ? 0x07 : 0x0f,
175 0xff, 0xff,
176 };
177 write_regs(client, regs, dec->channel);
178 dec->norm = *input;
179 break;
180 }
181 case VIDIOC_QUERYCTRL:
182 {
183 struct v4l2_queryctrl *ctrl = arg;
184
185 switch (ctrl->id) {
186 case V4L2_CID_BRIGHTNESS:
187 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
188 strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
189 ctrl->minimum = 0;
190 ctrl->maximum = 255;
191 ctrl->step = 1;
192 ctrl->default_value = 128;
193 ctrl->flags = 0;
194 break;
195 case V4L2_CID_CONTRAST:
196 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
197 strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
198 ctrl->minimum = 0;
199 ctrl->maximum = 255;
200 ctrl->step = 1;
201 ctrl->default_value = 128;
202 ctrl->flags = 0;
203 break;
204 case V4L2_CID_SATURATION:
205 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
206 strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
207 ctrl->minimum = 0;
208 ctrl->maximum = 255;
209 ctrl->step = 1;
210 ctrl->default_value = 128;
211 ctrl->flags = 0;
212 break;
213 case V4L2_CID_HUE:
214 ctrl->type = V4L2_CTRL_TYPE_INTEGER;
215 strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
216 ctrl->minimum = 0;
217 ctrl->maximum = 255;
218 ctrl->step = 1;
219 ctrl->default_value = 128;
220 ctrl->flags = 0;
221 break;
222 }
223 break;
224 }
225 case VIDIOC_S_CTRL:
226 {
227 struct v4l2_control *ctrl = arg;
228
229 switch (ctrl->id) {
230 case V4L2_CID_BRIGHTNESS:
231 if (ctrl->value > 255)
232 dec->brightness = 255;
233 else if (ctrl->value < 0)
234 dec->brightness = 0;
235 else
236 dec->brightness = ctrl->value;
237 write_reg(client, 0x12, dec->brightness, dec->channel);
238 break;
239 case V4L2_CID_CONTRAST:
240 if (ctrl->value > 255)
241 dec->contrast = 255;
242 else if (ctrl->value < 0)
243 dec->contrast = 0;
244 else
245 dec->contrast = ctrl->value;
246 write_reg(client, 0x11, dec->contrast, dec->channel);
247 break;
248 case V4L2_CID_SATURATION:
249 if (ctrl->value > 255)
250 dec->saturation = 255;
251 else if (ctrl->value < 0)
252 dec->saturation = 0;
253 else
254 dec->saturation = ctrl->value;
255 write_reg(client, 0x10, dec->saturation, dec->channel);
256 break;
257 case V4L2_CID_HUE:
258 if (ctrl->value > 255)
259 dec->hue = 255;
260 else if (ctrl->value < 0)
261 dec->hue = 0;
262 else
263 dec->hue = ctrl->value;
264 write_reg(client, 0x0f, dec->hue, dec->channel);
265 break;
266 }
267 break;
268 }
269 case VIDIOC_G_CTRL:
270 {
271 struct v4l2_control *ctrl = arg;
272
273 switch (ctrl->id) {
274 case V4L2_CID_BRIGHTNESS:
275 ctrl->value = dec->brightness;
276 break;
277 case V4L2_CID_CONTRAST:
278 ctrl->value = dec->contrast;
279 break;
280 case V4L2_CID_SATURATION:
281 ctrl->value = dec->saturation;
282 break;
283 case V4L2_CID_HUE:
284 ctrl->value = dec->hue;
285 break;
286 }
287 break;
288 }
289 default:
290 break;
291 }
292 return 0;
293}
294
295static int wis_tw2804_probe(struct i2c_client *client,
296 const struct i2c_device_id *id)
297{
298 struct i2c_adapter *adapter = client->adapter;
299 struct wis_tw2804 *dec;
300
301 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
302 return -ENODEV;
303
304 dec = kmalloc(sizeof(struct wis_tw2804), GFP_KERNEL);
305 if (dec == NULL)
306 return -ENOMEM;
307
308 dec->channel = -1;
309 dec->norm = V4L2_STD_NTSC;
310 dec->brightness = 128;
311 dec->contrast = 128;
312 dec->saturation = 128;
313 dec->hue = 128;
314 i2c_set_clientdata(client, dec);
315
316 printk(KERN_DEBUG "wis-tw2804: creating TW2804 at address %d on %s\n",
317 client->addr, adapter->name);
318
319 return 0;
320}
321
322static int wis_tw2804_remove(struct i2c_client *client)
323{
324 struct wis_tw2804 *dec = i2c_get_clientdata(client);
325
326 kfree(dec);
327 return 0;
328}
329
330static const struct i2c_device_id wis_tw2804_id[] = {
331 { "wis_tw2804", 0 },
332 { }
333};
334MODULE_DEVICE_TABLE(i2c, wis_tw2804_id);
335
336static struct i2c_driver wis_tw2804_driver = {
337 .driver = {
338 .name = "WIS TW2804 I2C driver",
339 },
340 .probe = wis_tw2804_probe,
341 .remove = wis_tw2804_remove,
342 .command = wis_tw2804_command,
343 .id_table = wis_tw2804_id,
344};
345
346static int __init wis_tw2804_init(void)
347{
348 return i2c_add_driver(&wis_tw2804_driver);
349}
350
351static void __exit wis_tw2804_cleanup(void)
352{
353 i2c_del_driver(&wis_tw2804_driver);
354}
355
356module_init(wis_tw2804_init);
357module_exit(wis_tw2804_cleanup);
358
359MODULE_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..9230f4a8052
--- /dev/null
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -0,0 +1,341 @@
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/i2c.h>
21#include <linux/videodev2.h>
22#include <linux/ioctl.h>
23#include <linux/slab.h>
24
25#include "wis-i2c.h"
26
27struct wis_tw9903 {
28 int norm;
29 int brightness;
30 int contrast;
31 int hue;
32};
33
34static u8 initial_registers[] =
35{
36 0x02, 0x44, /* input 1, composite */
37 0x03, 0x92, /* correct digital format */
38 0x04, 0x00,
39 0x05, 0x80, /* or 0x00 for PAL */
40 0x06, 0x40, /* second internal current reference */
41 0x07, 0x02, /* window */
42 0x08, 0x14, /* window */
43 0x09, 0xf0, /* window */
44 0x0a, 0x81, /* window */
45 0x0b, 0xd0, /* window */
46 0x0c, 0x8c,
47 0x0d, 0x00, /* scaling */
48 0x0e, 0x11, /* scaling */
49 0x0f, 0x00, /* scaling */
50 0x10, 0x00, /* brightness */
51 0x11, 0x60, /* contrast */
52 0x12, 0x01, /* sharpness */
53 0x13, 0x7f, /* U gain */
54 0x14, 0x5a, /* V gain */
55 0x15, 0x00, /* hue */
56 0x16, 0xc3, /* sharpness */
57 0x18, 0x00,
58 0x19, 0x58, /* vbi */
59 0x1a, 0x80,
60 0x1c, 0x0f, /* video norm */
61 0x1d, 0x7f, /* video norm */
62 0x20, 0xa0, /* clamping gain (working 0x50) */
63 0x21, 0x22,
64 0x22, 0xf0,
65 0x23, 0xfe,
66 0x24, 0x3c,
67 0x25, 0x38,
68 0x26, 0x44,
69 0x27, 0x20,
70 0x28, 0x00,
71 0x29, 0x15,
72 0x2a, 0xa0,
73 0x2b, 0x44,
74 0x2c, 0x37,
75 0x2d, 0x00,
76 0x2e, 0xa5, /* burst PLL control (working: a9) */
77 0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */
78 0x31, 0x00,
79 0x33, 0x22,
80 0x34, 0x11,
81 0x35, 0x35,
82 0x3b, 0x05,
83 0x06, 0xc0, /* reset device */
84 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
85};
86
87static int write_reg(struct i2c_client *client, u8 reg, u8 value)
88{
89 return i2c_smbus_write_byte_data(client, reg, value);
90}
91
92static int write_regs(struct i2c_client *client, u8 *regs)
93{
94 int i;
95
96 for (i = 0; regs[i] != 0x00; i += 2)
97 if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
98 return -1;
99 return 0;
100}
101
102static int wis_tw9903_command(struct i2c_client *client,
103 unsigned int cmd, void *arg)
104{
105 struct wis_tw9903 *dec = i2c_get_clientdata(client);
106
107 switch (cmd) {
108 case VIDIOC_S_INPUT:
109 {
110 int *input = arg;
111
112 i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
113 break;
114 }
115#if 0
116 /* 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 & V4L2_STD_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 VIDIOC_S_STD:
138 {
139 v4l2_std_id *input = arg;
140 u8 regs[] = {
141 0x05, *input & V4L2_STD_NTSC ? 0x80 : 0x00,
142 0x07, *input & V4L2_STD_NTSC ? 0x02 : 0x12,
143 0x08, *input & V4L2_STD_NTSC ? 0x14 : 0x18,
144 0x09, *input & V4L2_STD_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 int wis_tw9903_probe(struct i2c_client *client,
273 const struct i2c_device_id *id)
274{
275 struct i2c_adapter *adapter = client->adapter;
276 struct wis_tw9903 *dec;
277
278 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
279 return -ENODEV;
280
281 dec = kmalloc(sizeof(struct wis_tw9903), GFP_KERNEL);
282 if (dec == NULL)
283 return -ENOMEM;
284
285 dec->norm = V4L2_STD_NTSC;
286 dec->brightness = 0;
287 dec->contrast = 0x60;
288 dec->hue = 0;
289 i2c_set_clientdata(client, dec);
290
291 printk(KERN_DEBUG
292 "wis-tw9903: initializing TW9903 at address %d on %s\n",
293 client->addr, adapter->name);
294
295 if (write_regs(client, initial_registers) < 0) {
296 printk(KERN_ERR "wis-tw9903: error initializing TW9903\n");
297 kfree(dec);
298 return -ENODEV;
299 }
300
301 return 0;
302}
303
304static int wis_tw9903_remove(struct i2c_client *client)
305{
306 struct wis_tw9903 *dec = i2c_get_clientdata(client);
307
308 kfree(dec);
309 return 0;
310}
311
312static const struct i2c_device_id wis_tw9903_id[] = {
313 { "wis_tw9903", 0 },
314 { }
315};
316MODULE_DEVICE_TABLE(i2c, wis_tw9903_id);
317
318static struct i2c_driver wis_tw9903_driver = {
319 .driver = {
320 .name = "WIS TW9903 I2C driver",
321 },
322 .probe = wis_tw9903_probe,
323 .remove = wis_tw9903_remove,
324 .command = wis_tw9903_command,
325 .id_table = wis_tw9903_id,
326};
327
328static int __init wis_tw9903_init(void)
329{
330 return i2c_add_driver(&wis_tw9903_driver);
331}
332
333static void __exit wis_tw9903_cleanup(void)
334{
335 i2c_del_driver(&wis_tw9903_driver);
336}
337
338module_init(wis_tw9903_init);
339module_exit(wis_tw9903_cleanup);
340
341MODULE_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..0127be2f3be
--- /dev/null
+++ b/drivers/staging/go7007/wis-uda1342.c
@@ -0,0 +1,114 @@
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/i2c.h>
21#include <linux/videodev2.h>
22#include <media/tvaudio.h>
23#include <media/v4l2-common.h>
24
25#include "wis-i2c.h"
26
27static int write_reg(struct i2c_client *client, int reg, int value)
28{
29 /* UDA1342 wants MSB first, but SMBus sends LSB first */
30 i2c_smbus_write_word_data(client, reg, swab16(value));
31 return 0;
32}
33
34static int wis_uda1342_command(struct i2c_client *client,
35 unsigned int cmd, void *arg)
36{
37 switch (cmd) {
38 case VIDIOC_S_AUDIO:
39 {
40 int *inp = arg;
41
42 switch (*inp) {
43 case TVAUDIO_INPUT_TUNER:
44 write_reg(client, 0x00, 0x1441); /* select input 2 */
45 break;
46 case TVAUDIO_INPUT_EXTERN:
47 write_reg(client, 0x00, 0x1241); /* select input 1 */
48 break;
49 default:
50 printk(KERN_ERR "wis-uda1342: input %d not supported\n",
51 *inp);
52 break;
53 }
54 break;
55 }
56 default:
57 break;
58 }
59 return 0;
60}
61
62static int wis_uda1342_probe(struct i2c_client *client,
63 const struct i2c_device_id *id)
64{
65 struct i2c_adapter *adapter = client->adapter;
66
67 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
68 return -ENODEV;
69
70 printk(KERN_DEBUG
71 "wis-uda1342: initializing UDA1342 at address %d on %s\n",
72 client->addr, adapter->name);
73
74 write_reg(client, 0x00, 0x8000); /* reset registers */
75 write_reg(client, 0x00, 0x1241); /* select input 1 */
76
77 return 0;
78}
79
80static int wis_uda1342_remove(struct i2c_client *client)
81{
82 return 0;
83}
84
85static const struct i2c_device_id wis_uda1342_id[] = {
86 { "wis_uda1342", 0 },
87 { }
88};
89MODULE_DEVICE_TABLE(i2c, wis_uda1342_id);
90
91static struct i2c_driver wis_uda1342_driver = {
92 .driver = {
93 .name = "WIS UDA1342 I2C driver",
94 },
95 .probe = wis_uda1342_probe,
96 .remove = wis_uda1342_remove,
97 .command = wis_uda1342_command,
98 .id_table = wis_uda1342_id,
99};
100
101static int __init wis_uda1342_init(void)
102{
103 return i2c_add_driver(&wis_uda1342_driver);
104}
105
106static void __exit wis_uda1342_cleanup(void)
107{
108 i2c_del_driver(&wis_uda1342_driver);
109}
110
111module_init(wis_uda1342_init);
112module_exit(wis_uda1342_cleanup);
113
114MODULE_LICENSE("GPL v2");