aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/Kconfig6
-rw-r--r--drivers/media/video/Makefile1
-rw-r--r--drivers/media/video/bt866.c377
-rw-r--r--drivers/media/video/ks0127.c846
-rw-r--r--drivers/media/video/ks0127.h53
-rw-r--r--drivers/media/video/zoran.h8
-rw-r--r--drivers/media/video/zoran_card.c87
7 files changed, 1377 insertions, 1 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 6b4197018561..515e16acf0dd 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -224,6 +224,12 @@ config VIDEO_ZORAN_LML33R10
224 support for the Linux Media Labs LML33R10 MJPEG capture/playback 224 support for the Linux Media Labs LML33R10 MJPEG capture/playback
225 card. 225 card.
226 226
227config VIDEO_ZORAN_AVS6EYES
228 tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
229 depends on VIDEO_ZORAN && EXPERIMENTAL && VIDEO_V4L1
230 help
231 Support for the AverMedia 6 Eyes video surveillance card.
232
227config VIDEO_ZR36120 233config VIDEO_ZR36120
228 tristate "Zoran ZR36120/36125 Video For Linux" 234 tristate "Zoran ZR36120/36125 Video For Linux"
229 depends on PCI && I2C && VIDEO_V4L1 && BROKEN 235 depends on PCI && I2C && VIDEO_V4L1 && BROKEN
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index e5bf2687b76d..97e899074436 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_VIDEO_ZORAN_DC30) += adv7175.o vpx3220.o zr36050.o \
33 zr36016.o 33 zr36016.o
34obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o 34obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o zr36060.o
35obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o 35obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o
36obj-$(CONFIG_VIDEO_ZORAN_AVS6EYES) += bt866.o ks0127.o zr36060.o
36obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o 37obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o
37obj-$(CONFIG_VIDEO_PMS) += pms.o 38obj-$(CONFIG_VIDEO_PMS) += pms.o
38obj-$(CONFIG_VIDEO_PLANB) += planb.o 39obj-$(CONFIG_VIDEO_PLANB) += planb.o
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
new file mode 100644
index 000000000000..05e42bbcfc3d
--- /dev/null
+++ b/drivers/media/video/bt866.c
@@ -0,0 +1,377 @@
1/*
2 bt866 - BT866 Digital Video Encoder (Rockwell Part)
3
4 Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6
7 Modifications for LML33/DC10plus unified driver
8 Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9
10 This code was modify/ported from the saa7111 driver written
11 by Dave Perks.
12
13 This code was adapted for the bt866 by Christer Weinigel and ported
14 to 2.6 by Martin Samuelsson.
15
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or
19 (at your option) any later version.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29*/
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/pci.h>
41#include <linux/signal.h>
42#include <asm/io.h>
43#include <asm/pgtable.h>
44#include <asm/page.h>
45#include <linux/sched.h>
46#include <linux/types.h>
47#include <linux/i2c.h>
48
49#include <linux/videodev.h>
50#include <asm/uaccess.h>
51
52#include <linux/video_encoder.h>
53
54MODULE_LICENSE("GPL");
55
56#define BT866_DEVNAME "bt866"
57#define I2C_BT866 0x88
58
59MODULE_LICENSE("GPL");
60
61#define DEBUG(x) /* Debug driver */
62
63/* ----------------------------------------------------------------------- */
64
65struct bt866 {
66 struct i2c_client *i2c;
67 int addr;
68 unsigned char reg[128];
69
70 int norm;
71 int enable;
72 int bright;
73 int contrast;
74 int hue;
75 int sat;
76};
77
78static int bt866_write(struct bt866 *dev,
79 unsigned char subaddr, unsigned char data);
80
81static int bt866_do_command(struct bt866 *encoder,
82 unsigned int cmd, void *arg)
83{
84 switch (cmd) {
85 case ENCODER_GET_CAPABILITIES:
86 {
87 struct video_encoder_capability *cap = arg;
88
89 DEBUG(printk
90 (KERN_INFO "%s: get capabilities\n",
91 encoder->i2c->name));
92
93 cap->flags
94 = VIDEO_ENCODER_PAL
95 | VIDEO_ENCODER_NTSC
96 | VIDEO_ENCODER_CCIR;
97 cap->inputs = 2;
98 cap->outputs = 1;
99 }
100 break;
101
102 case ENCODER_SET_NORM:
103 {
104 int *iarg = arg;
105
106 DEBUG(printk(KERN_INFO "%s: set norm %d\n",
107 encoder->i2c->name, *iarg));
108
109 switch (*iarg) {
110
111 case VIDEO_MODE_NTSC:
112 break;
113
114 case VIDEO_MODE_PAL:
115 break;
116
117 default:
118 return -EINVAL;
119
120 }
121 encoder->norm = *iarg;
122 }
123 break;
124
125 case ENCODER_SET_INPUT:
126 {
127 int *iarg = arg;
128 static const __u8 init[] = {
129 0xc8, 0xcc, /* CRSCALE */
130 0xca, 0x91, /* CBSCALE */
131 0xcc, 0x24, /* YC16 | OSDNUM */
132 0xda, 0x00, /* */
133 0xdc, 0x24, /* SETMODE | PAL */
134 0xde, 0x02, /* EACTIVE */
135
136 /* overlay colors */
137 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
138 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
139 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
140 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
141 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
142 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
143 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
144 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
145
146 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
147 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
148 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
149 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
150 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
151 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
152 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
153 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
154 };
155 int i;
156 u8 val;
157
158 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
159 bt866_write(encoder, init[i], init[i+1]);
160
161 val = encoder->reg[0xdc];
162
163 if (*iarg == 0)
164 val |= 0x40; /* CBSWAP */
165 else
166 val &= ~0x40; /* !CBSWAP */
167
168 bt866_write(encoder, 0xdc, val);
169
170 val = encoder->reg[0xcc];
171 if (*iarg == 2)
172 val |= 0x01; /* OSDBAR */
173 else
174 val &= ~0x01; /* !OSDBAR */
175 bt866_write(encoder, 0xcc, val);
176
177 DEBUG(printk(KERN_INFO "%s: set input %d\n",
178 encoder->i2c->name, *iarg));
179
180 switch (*iarg) {
181 case 0:
182 break;
183 case 1:
184 break;
185 default:
186 return -EINVAL;
187
188 }
189 }
190 break;
191
192 case ENCODER_SET_OUTPUT:
193 {
194 int *iarg = arg;
195
196 DEBUG(printk(KERN_INFO "%s: set output %d\n",
197 encoder->i2c->name, *iarg));
198
199 /* not much choice of outputs */
200 if (*iarg != 0)
201 return -EINVAL;
202 }
203 break;
204
205 case ENCODER_ENABLE_OUTPUT:
206 {
207 int *iarg = arg;
208 encoder->enable = !!*iarg;
209
210 DEBUG(printk
211 (KERN_INFO "%s: enable output %d\n",
212 encoder->i2c->name, encoder->enable));
213 }
214 break;
215
216 case 4711:
217 {
218 int *iarg = arg;
219 __u8 val;
220
221 printk("bt866: square = %d\n", *iarg);
222
223 val = encoder->reg[0xdc];
224 if (*iarg)
225 val |= 1; /* SQUARE */
226 else
227 val &= ~1; /* !SQUARE */
228 bt866_write(encoder, 0xdc, val);
229 break;
230 }
231
232 default:
233 return -EINVAL;
234 }
235
236 return 0;
237}
238
239static int bt866_write(struct bt866 *encoder,
240 unsigned char subaddr, unsigned char data)
241{
242 unsigned char buffer[2];
243 int err;
244
245 buffer[0] = subaddr;
246 buffer[1] = data;
247
248 encoder->reg[subaddr] = data;
249
250 DEBUG(printk
251 ("%s: write 0x%02X = 0x%02X\n",
252 encoder->i2c->name, subaddr, data));
253
254 for (err = 0; err < 3;) {
255 if (i2c_master_send(encoder->i2c, buffer, 2) == 2)
256 break;
257 err++;
258 printk(KERN_WARNING "%s: I/O error #%d "
259 "(write 0x%02x/0x%02x)\n",
260 encoder->i2c->name, err, encoder->addr, subaddr);
261 schedule_timeout_interruptible(HZ/10);
262 }
263 if (err == 3) {
264 printk(KERN_WARNING "%s: giving up\n",
265 encoder->i2c->name);
266 return -1;
267 }
268
269 return 0;
270}
271
272static int bt866_attach(struct i2c_adapter *adapter);
273static int bt866_detach(struct i2c_client *client);
274static int bt866_command(struct i2c_client *client,
275 unsigned int cmd, void *arg);
276
277
278/* Addresses to scan */
279static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END};
280static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
281static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
282
283static struct i2c_client_address_data addr_data = {
284 normal_i2c,
285 probe,
286 ignore,
287};
288
289static struct i2c_driver i2c_driver_bt866 = {
290 .driver.name = BT866_DEVNAME,
291 .id = I2C_DRIVERID_BT866,
292 .attach_adapter = bt866_attach,
293 .detach_client = bt866_detach,
294 .command = bt866_command
295};
296
297
298static struct i2c_client bt866_client_tmpl =
299{
300 .name = "(nil)",
301 .addr = 0,
302 .adapter = NULL,
303 .driver = &i2c_driver_bt866,
304 .usage_count = 0
305};
306
307static int bt866_found_proc(struct i2c_adapter *adapter,
308 int addr, int kind)
309{
310 struct bt866 *encoder;
311 struct i2c_client *client;
312
313 client = kzalloc(sizeof(*client), GFP_KERNEL);
314 if (client == NULL)
315 return -ENOMEM;
316 memcpy(client, &bt866_client_tmpl, sizeof(*client));
317
318 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
319 if (encoder == NULL) {
320 kfree(client);
321 return -ENOMEM;
322 }
323
324 i2c_set_clientdata(client, encoder);
325 client->adapter = adapter;
326 client->addr = addr;
327 sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
328
329 encoder->i2c = client;
330 encoder->addr = addr;
331 //encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
332
333 /* initialize */
334
335 i2c_attach_client(client);
336
337 return 0;
338}
339
340static int bt866_attach(struct i2c_adapter *adapter)
341{
342 if (adapter->id == I2C_HW_B_ZR36067)
343 return i2c_probe(adapter, &addr_data, bt866_found_proc);
344 return 0;
345}
346
347static int bt866_detach(struct i2c_client *client)
348{
349 struct bt866 *encoder = i2c_get_clientdata(client);
350
351 i2c_detach_client(client);
352 kfree(encoder);
353 kfree(client);
354
355 return 0;
356}
357
358static int bt866_command(struct i2c_client *client,
359 unsigned int cmd, void *arg)
360{
361 struct bt866 *encoder = i2c_get_clientdata(client);
362 return bt866_do_command(encoder, cmd, arg);
363}
364
365static int __devinit bt866_init(void)
366{
367 i2c_add_driver(&i2c_driver_bt866);
368 return 0;
369}
370
371static void __devexit bt866_exit(void)
372{
373 i2c_del_driver(&i2c_driver_bt866);
374}
375
376module_init(bt866_init);
377module_exit(bt866_exit);
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
new file mode 100644
index 000000000000..3bf7ac4f5288
--- /dev/null
+++ b/drivers/media/video/ks0127.c
@@ -0,0 +1,846 @@
1/*
2 * Video Capture Driver (Video for Linux 1/2)
3 * for the Matrox Marvel G200,G400 and Rainbow Runner-G series
4 *
5 * This module is an interface to the KS0127 video decoder chip.
6 *
7 * Copyright (C) 1999 Ryan Drake <stiletto@mediaone.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 *****************************************************************************
24 *
25 * Modified and extended by
26 * Mike Bernson <mike@mlb.org>
27 * Gerard v.d. Horst
28 * Leon van Stuivenberg <l.vanstuivenberg@chello.nl>
29 * Gernot Ziegler <gz@lysator.liu.se>
30 *
31 * Version History:
32 * V1.0 Ryan Drake Initial version by Ryan Drake
33 * V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard
34 */
35
36#ifndef __KERNEL__
37#define __KERNEL__
38#endif
39
40#include <linux/init.h>
41#include <linux/module.h>
42#include <linux/delay.h>
43#include <linux/errno.h>
44#include <linux/kernel.h>
45#include <linux/slab.h>
46#include <linux/proc_fs.h>
47#include "ks0127.h"
48
49#include <linux/i2c.h>
50#include <linux/video_decoder.h>
51
52#define dprintk if (debug) printk
53
54/* i2c identification */
55#define I2C_KS0127_ADDON 0xD8
56#define I2C_KS0127_ONBOARD 0xDA
57
58#define KS_TYPE_UNKNOWN 0
59#define KS_TYPE_0122S 1
60#define KS_TYPE_0127 2
61#define KS_TYPE_0127B 3
62
63/* ks0127 control registers */
64#define KS_STAT 0x00
65#define KS_CMDA 0x01
66#define KS_CMDB 0x02
67#define KS_CMDC 0x03
68#define KS_CMDD 0x04
69#define KS_HAVB 0x05
70#define KS_HAVE 0x06
71#define KS_HS1B 0x07
72#define KS_HS1E 0x08
73#define KS_HS2B 0x09
74#define KS_HS2E 0x0a
75#define KS_AGC 0x0b
76#define KS_HXTRA 0x0c
77#define KS_CDEM 0x0d
78#define KS_PORTAB 0x0e
79#define KS_LUMA 0x0f
80#define KS_CON 0x10
81#define KS_BRT 0x11
82#define KS_CHROMA 0x12
83#define KS_CHROMB 0x13
84#define KS_DEMOD 0x14
85#define KS_SAT 0x15
86#define KS_HUE 0x16
87#define KS_VERTIA 0x17
88#define KS_VERTIB 0x18
89#define KS_VERTIC 0x19
90#define KS_HSCLL 0x1a
91#define KS_HSCLH 0x1b
92#define KS_VSCLL 0x1c
93#define KS_VSCLH 0x1d
94#define KS_OFMTA 0x1e
95#define KS_OFMTB 0x1f
96#define KS_VBICTL 0x20
97#define KS_CCDAT2 0x21
98#define KS_CCDAT1 0x22
99#define KS_VBIL30 0x23
100#define KS_VBIL74 0x24
101#define KS_VBIL118 0x25
102#define KS_VBIL1512 0x26
103#define KS_TTFRAM 0x27
104#define KS_TESTA 0x28
105#define KS_UVOFFH 0x29
106#define KS_UVOFFL 0x2a
107#define KS_UGAIN 0x2b
108#define KS_VGAIN 0x2c
109#define KS_VAVB 0x2d
110#define KS_VAVE 0x2e
111#define KS_CTRACK 0x2f
112#define KS_POLCTL 0x30
113#define KS_REFCOD 0x31
114#define KS_INVALY 0x32
115#define KS_INVALU 0x33
116#define KS_INVALV 0x34
117#define KS_UNUSEY 0x35
118#define KS_UNUSEU 0x36
119#define KS_UNUSEV 0x37
120#define KS_USRSAV 0x38
121#define KS_USREAV 0x39
122#define KS_SHS1A 0x3a
123#define KS_SHS1B 0x3b
124#define KS_SHS1C 0x3c
125#define KS_CMDE 0x3d
126#define KS_VSDEL 0x3e
127#define KS_CMDF 0x3f
128#define KS_GAMMA0 0x40
129#define KS_GAMMA1 0x41
130#define KS_GAMMA2 0x42
131#define KS_GAMMA3 0x43
132#define KS_GAMMA4 0x44
133#define KS_GAMMA5 0x45
134#define KS_GAMMA6 0x46
135#define KS_GAMMA7 0x47
136#define KS_GAMMA8 0x48
137#define KS_GAMMA9 0x49
138#define KS_GAMMA10 0x4a
139#define KS_GAMMA11 0x4b
140#define KS_GAMMA12 0x4c
141#define KS_GAMMA13 0x4d
142#define KS_GAMMA14 0x4e
143#define KS_GAMMA15 0x4f
144#define KS_GAMMA16 0x50
145#define KS_GAMMA17 0x51
146#define KS_GAMMA18 0x52
147#define KS_GAMMA19 0x53
148#define KS_GAMMA20 0x54
149#define KS_GAMMA21 0x55
150#define KS_GAMMA22 0x56
151#define KS_GAMMA23 0x57
152#define KS_GAMMA24 0x58
153#define KS_GAMMA25 0x59
154#define KS_GAMMA26 0x5a
155#define KS_GAMMA27 0x5b
156#define KS_GAMMA28 0x5c
157#define KS_GAMMA29 0x5d
158#define KS_GAMMA30 0x5e
159#define KS_GAMMA31 0x5f
160#define KS_GAMMAD0 0x60
161#define KS_GAMMAD1 0x61
162#define KS_GAMMAD2 0x62
163#define KS_GAMMAD3 0x63
164#define KS_GAMMAD4 0x64
165#define KS_GAMMAD5 0x65
166#define KS_GAMMAD6 0x66
167#define KS_GAMMAD7 0x67
168#define KS_GAMMAD8 0x68
169#define KS_GAMMAD9 0x69
170#define KS_GAMMAD10 0x6a
171#define KS_GAMMAD11 0x6b
172#define KS_GAMMAD12 0x6c
173#define KS_GAMMAD13 0x6d
174#define KS_GAMMAD14 0x6e
175#define KS_GAMMAD15 0x6f
176#define KS_GAMMAD16 0x70
177#define KS_GAMMAD17 0x71
178#define KS_GAMMAD18 0x72
179#define KS_GAMMAD19 0x73
180#define KS_GAMMAD20 0x74
181#define KS_GAMMAD21 0x75
182#define KS_GAMMAD22 0x76
183#define KS_GAMMAD23 0x77
184#define KS_GAMMAD24 0x78
185#define KS_GAMMAD25 0x79
186#define KS_GAMMAD26 0x7a
187#define KS_GAMMAD27 0x7b
188#define KS_GAMMAD28 0x7c
189#define KS_GAMMAD29 0x7d
190#define KS_GAMMAD30 0x7e
191#define KS_GAMMAD31 0x7f
192
193
194/****************************************************************************
195* mga_dev : represents one ks0127 chip.
196****************************************************************************/
197
198struct adjust {
199 int contrast;
200 int bright;
201 int hue;
202 int ugain;
203 int vgain;
204};
205
206struct ks0127 {
207 struct i2c_client *client;
208 unsigned char addr;
209 int format_width;
210 int format_height;
211 int cap_width;
212 int cap_height;
213 int norm;
214 int ks_type;
215 u8 regs[256];
216};
217
218
219static int debug; /* insmod parameter */
220
221module_param(debug, int, 0);
222MODULE_PARM_DESC(debug, "Debug output");
223MODULE_LICENSE("GPL");
224
225static u8 reg_defaults[64];
226
227
228
229static void init_reg_defaults(void)
230{
231 u8 *table = reg_defaults;
232
233 table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */
234 table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */
235 table[KS_CMDC] = 0x00; /* Test options */
236 /* clock & input select, write 1 to PORTA */
237 table[KS_CMDD] = 0x01;
238 table[KS_HAVB] = 0x00; /* HAV Start Control */
239 table[KS_HAVE] = 0x00; /* HAV End Control */
240 table[KS_HS1B] = 0x10; /* HS1 Start Control */
241 table[KS_HS1E] = 0x00; /* HS1 End Control */
242 table[KS_HS2B] = 0x00; /* HS2 Start Control */
243 table[KS_HS2E] = 0x00; /* HS2 End Control */
244 table[KS_AGC] = 0x53; /* Manual setting for AGC */
245 table[KS_HXTRA] = 0x00; /* Extra Bits for HAV and HS1/2 */
246 table[KS_CDEM] = 0x00; /* Chroma Demodulation Control */
247 table[KS_PORTAB] = 0x0f; /* port B is input, port A output GPPORT */
248 table[KS_LUMA] = 0x01; /* Luma control */
249 table[KS_CON] = 0x00; /* Contrast Control */
250 table[KS_BRT] = 0x00; /* Brightness Control */
251 table[KS_CHROMA] = 0x2a; /* Chroma control A */
252 table[KS_CHROMB] = 0x90; /* Chroma control B */
253 table[KS_DEMOD] = 0x00; /* Chroma Demodulation Control & Status */
254 table[KS_SAT] = 0x00; /* Color Saturation Control*/
255 table[KS_HUE] = 0x00; /* Hue Control */
256 table[KS_VERTIA] = 0x00; /* Vertical Processing Control A */
257 /* Vertical Processing Control B, luma 1 line delayed */
258 table[KS_VERTIB] = 0x12;
259 table[KS_VERTIC] = 0x0b; /* Vertical Processing Control C */
260 table[KS_HSCLL] = 0x00; /* Horizontal Scaling Ratio Low */
261 table[KS_HSCLH] = 0x00; /* Horizontal Scaling Ratio High */
262 table[KS_VSCLL] = 0x00; /* Vertical Scaling Ratio Low */
263 table[KS_VSCLH] = 0x00; /* Vertical Scaling Ratio High */
264 /* 16 bit YCbCr 4:2:2 output; I can't make the bt866 like 8 bit /Sam */
265 table[KS_OFMTA] = 0x30;
266 table[KS_OFMTB] = 0x00; /* Output Control B */
267 /* VBI Decoder Control; 4bit fmt: avoid Y overflow */
268 table[KS_VBICTL] = 0x5d;
269 table[KS_CCDAT2] = 0x00; /* Read Only register */
270 table[KS_CCDAT1] = 0x00; /* Read Only register */
271 table[KS_VBIL30] = 0xa8; /* VBI data decoding options */
272 table[KS_VBIL74] = 0xaa; /* VBI data decoding options */
273 table[KS_VBIL118] = 0x2a; /* VBI data decoding options */
274 table[KS_VBIL1512] = 0x00; /* VBI data decoding options */
275 table[KS_TTFRAM] = 0x00; /* Teletext frame alignment pattern */
276 table[KS_TESTA] = 0x00; /* test register, shouldn't be written */
277 table[KS_UVOFFH] = 0x00; /* UV Offset Adjustment High */
278 table[KS_UVOFFL] = 0x00; /* UV Offset Adjustment Low */
279 table[KS_UGAIN] = 0x00; /* U Component Gain Adjustment */
280 table[KS_VGAIN] = 0x00; /* V Component Gain Adjustment */
281 table[KS_VAVB] = 0x07; /* VAV Begin */
282 table[KS_VAVE] = 0x00; /* VAV End */
283 table[KS_CTRACK] = 0x00; /* Chroma Tracking Control */
284 table[KS_POLCTL] = 0x41; /* Timing Signal Polarity Control */
285 table[KS_REFCOD] = 0x80; /* Reference Code Insertion Control */
286 table[KS_INVALY] = 0x10; /* Invalid Y Code */
287 table[KS_INVALU] = 0x80; /* Invalid U Code */
288 table[KS_INVALV] = 0x80; /* Invalid V Code */
289 table[KS_UNUSEY] = 0x10; /* Unused Y Code */
290 table[KS_UNUSEU] = 0x80; /* Unused U Code */
291 table[KS_UNUSEV] = 0x80; /* Unused V Code */
292 table[KS_USRSAV] = 0x00; /* reserved */
293 table[KS_USREAV] = 0x00; /* reserved */
294 table[KS_SHS1A] = 0x00; /* User Defined SHS1 A */
295 /* User Defined SHS1 B, ALT656=1 on 0127B */
296 table[KS_SHS1B] = 0x80;
297 table[KS_SHS1C] = 0x00; /* User Defined SHS1 C */
298 table[KS_CMDE] = 0x00; /* Command Register E */
299 table[KS_VSDEL] = 0x00; /* VS Delay Control */
300 /* Command Register F, update -immediately- */
301 /* (there might come no vsync)*/
302 table[KS_CMDF] = 0x02;
303}
304
305
306/* We need to manually read because of a bug in the KS0127 chip.
307 *
308 * An explanation from kayork@mail.utexas.edu:
309 *
310 * During I2C reads, the KS0127 only samples for a stop condition
311 * during the place where the acknoledge bit should be. Any standard
312 * I2C implementation (correctly) throws in another clock transition
313 * at the 9th bit, and the KS0127 will not recognize the stop condition
314 * and will continue to clock out data.
315 *
316 * So we have to do the read ourself. Big deal.
317 workaround in i2c-algo-bit
318 */
319
320
321static u8 ks0127_read(struct ks0127 *ks, u8 reg)
322{
323 struct i2c_client *c = ks->client;
324 char val = 0;
325 struct i2c_msg msgs[] = {
326 {c->addr, 0, sizeof(reg), &reg},
327 {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}};
328 int ret;
329
330 ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs));
331 if (ret != ARRAY_SIZE(msgs))
332 dprintk("ks0127_write error\n");
333
334 return val;
335}
336
337
338static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val)
339{
340 char msg[] = {reg, val};
341
342 if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg))
343 dprintk("ks0127_write error\n");
344
345 ks->regs[reg] = val;
346}
347
348
349/* generic bit-twiddling */
350static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v)
351{
352 u8 val = ks->regs[reg];
353 val = (val & and_v) | or_v;
354 ks0127_write(ks, reg, val);
355}
356
357
358
359/****************************************************************************
360* ks0127 private api
361****************************************************************************/
362static void ks0127_reset(struct ks0127* ks)
363{
364 int i;
365 u8 *table = reg_defaults;
366
367 ks->ks_type = KS_TYPE_UNKNOWN;
368
369 dprintk("ks0127: reset\n");
370 msleep(1);
371
372 /* initialize all registers to known values */
373 /* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
374
375 for(i = 1; i < 33; i++)
376 ks0127_write(ks, i, table[i]);
377
378 for(i = 35; i < 40; i++)
379 ks0127_write(ks, i, table[i]);
380
381 for(i = 41; i < 56; i++)
382 ks0127_write(ks, i, table[i]);
383
384 for(i = 58; i < 64; i++)
385 ks0127_write(ks, i, table[i]);
386
387
388 if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) {
389 ks->ks_type = KS_TYPE_0122S;
390 dprintk("ks0127: ks0122s Found\n");
391 return;
392 }
393
394 switch(ks0127_read(ks, KS_CMDE) & 0x0f) {
395
396 case 0:
397 ks->ks_type = KS_TYPE_0127;
398 dprintk("ks0127: ks0127 found\n");
399 break;
400
401 case 9:
402 ks->ks_type = KS_TYPE_0127B;
403 dprintk("ks0127: ks0127B Revision A found\n");
404 break;
405
406 default:
407 dprintk("ks0127: unknown revision\n");
408 break;
409 }
410}
411
412static int ks0127_command(struct i2c_client *client,
413 unsigned int cmd, void *arg)
414{
415 struct ks0127 *ks = i2c_get_clientdata(client);
416
417 int *iarg = (int*)arg;
418
419 int status;
420
421 if (!ks)
422 return -ENODEV;
423
424 switch (cmd) {
425
426 case DECODER_INIT:
427 dprintk("ks0127: command DECODER_INIT\n");
428 ks0127_reset(ks);
429 break;
430
431 case DECODER_SET_INPUT:
432 switch(*iarg) {
433 case KS_INPUT_COMPOSITE_1:
434 case KS_INPUT_COMPOSITE_2:
435 case KS_INPUT_COMPOSITE_3:
436 case KS_INPUT_COMPOSITE_4:
437 case KS_INPUT_COMPOSITE_5:
438 case KS_INPUT_COMPOSITE_6:
439 dprintk("ks0127: command DECODER_SET_INPUT %d: "
440 "Composite\n", *iarg);
441 /* autodetect 50/60 Hz */
442 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
443 /* VSE=0 */
444 ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00);
445 /* set input line */
446 ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg);
447 /* non-freerunning mode */
448 ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a);
449 /* analog input */
450 ks0127_and_or(ks, KS_CMDD, 0x03, 0x00);
451 /* enable chroma demodulation */
452 ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
453 /* chroma trap, HYBWR=1 */
454 ks0127_and_or(ks, KS_LUMA, 0x00,
455 (reg_defaults[KS_LUMA])|0x0c);
456 /* scaler fullbw, luma comb off */
457 ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
458 /* manual chroma comb .25 .5 .25 */
459 ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90);
460
461 /* chroma path delay */
462 ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90);
463
464 ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
465 ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
466 ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
467 ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
468 break;
469
470 case KS_INPUT_SVIDEO_1:
471 case KS_INPUT_SVIDEO_2:
472 case KS_INPUT_SVIDEO_3:
473 dprintk("ks0127: command DECODER_SET_INPUT %d: "
474 "S-Video\n", *iarg);
475 /* autodetect 50/60 Hz */
476 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
477 /* VSE=0 */
478 ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00);
479 /* set input line */
480 ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg);
481 /* non-freerunning mode */
482 ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a);
483 /* analog input */
484 ks0127_and_or(ks, KS_CMDD, 0x03, 0x00);
485 /* enable chroma demodulation */
486 ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
487 ks0127_and_or(ks, KS_LUMA, 0x00,
488 reg_defaults[KS_LUMA]);
489 /* disable luma comb */
490 ks0127_and_or(ks, KS_VERTIA, 0x08,
491 (reg_defaults[KS_VERTIA]&0xf0)|0x01);
492 ks0127_and_or(ks, KS_VERTIC, 0x0f,
493 reg_defaults[KS_VERTIC]&0xf0);
494
495 ks0127_and_or(ks, KS_CHROMB, 0x0f,
496 reg_defaults[KS_CHROMB]&0xf0);
497
498 ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
499 ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
500 ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
501 ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
502 break;
503
504 case KS_INPUT_YUV656:
505 dprintk("ks0127: command DECODER_SET_INPUT 15: "
506 "YUV656\n");
507 if (ks->norm == VIDEO_MODE_NTSC ||
508 ks->norm == KS_STD_PAL_M)
509 /* force 60 Hz */
510 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03);
511 else
512 /* force 50 Hz */
513 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02);
514
515 ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */
516 /* set input line and VALIGN */
517 ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40));
518 /* freerunning mode, */
519 /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
520 ks0127_and_or(ks, KS_CMDC, 0x70, 0x87);
521 /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
522 ks0127_and_or(ks, KS_CMDD, 0x03, 0x08);
523 /* disable chroma demodulation */
524 ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30);
525 /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
526 ks0127_and_or(ks, KS_LUMA, 0x00, 0x71);
527 ks0127_and_or(ks, KS_VERTIC, 0x0f,
528 reg_defaults[KS_VERTIC]&0xf0);
529
530 /* scaler fullbw, luma comb off */
531 ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
532
533 ks0127_and_or(ks, KS_CHROMB, 0x0f,
534 reg_defaults[KS_CHROMB]&0xf0);
535
536 ks0127_and_or(ks, KS_CON, 0x00, 0x00);
537 ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */
538 /* spec: 229 (e5) */
539 ks0127_and_or(ks, KS_SAT, 0x00, 0xe8);
540 ks0127_and_or(ks, KS_HUE, 0x00, 0);
541
542 ks0127_and_or(ks, KS_UGAIN, 0x00, 238);
543 ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00);
544
545 /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
546 ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f);
547 ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00);
548 break;
549
550 default:
551 dprintk("ks0127: command DECODER_SET_INPUT: "
552 "Unknown input %d\n", *iarg);
553 break;
554 }
555
556 /* hack: CDMLPF sometimes spontaneously switches on; */
557 /* force back off */
558 ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]);
559 break;
560
561 case DECODER_SET_OUTPUT:
562 switch(*iarg) {
563 case KS_OUTPUT_YUV656E:
564 dprintk("ks0127: command DECODER_SET_OUTPUT: "
565 "OUTPUT_YUV656E (Missing)\n");
566 return -EINVAL;
567 break;
568
569 case KS_OUTPUT_EXV:
570 dprintk("ks0127: command DECODER_SET_OUTPUT: "
571 "OUTPUT_EXV\n");
572 ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09);
573 break;
574 }
575 break;
576
577 case DECODER_SET_NORM: //sam This block mixes old and new norm names...
578 /* Set to automatic SECAM/Fsc mode */
579 ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
580
581 ks->norm = *iarg;
582 switch(*iarg)
583 {
584 /* this is untested !! */
585 /* It just detects PAL_N/NTSC_M (no special frequencies) */
586 /* And you have to set the standard a second time afterwards */
587 case VIDEO_MODE_AUTO:
588 dprintk("ks0127: command DECODER_SET_NORM: AUTO\n");
589
590 /* The chip determines the format */
591 /* based on the current field rate */
592 ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
593 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
594 /* This is wrong for PAL ! As I said, */
595 /* you need to set the standard once again !! */
596 ks->format_height = 240;
597 ks->format_width = 704;
598 break;
599
600 case VIDEO_MODE_NTSC:
601 dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n");
602 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
603 ks->format_height = 240;
604 ks->format_width = 704;
605 break;
606
607 case KS_STD_NTSC_N:
608 dprintk("ks0127: command KS0127_SET_STANDARD: "
609 "NTSC_N (fixme)\n");
610 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
611 ks->format_height = 240;
612 ks->format_width = 704;
613 break;
614
615 case VIDEO_MODE_PAL:
616 dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n");
617 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
618 ks->format_height = 290;
619 ks->format_width = 704;
620 break;
621
622 case KS_STD_PAL_M:
623 dprintk("ks0127: command KS0127_SET_STANDARD: "
624 "PAL_M (fixme)\n");
625 ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
626 ks->format_height = 290;
627 ks->format_width = 704;
628 break;
629
630 case VIDEO_MODE_SECAM:
631 dprintk("ks0127: command KS0127_SET_STANDARD: "
632 "SECAM\n");
633 ks->format_height = 290;
634 ks->format_width = 704;
635
636 /* set to secam autodetection */
637 ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20);
638 ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
639 schedule_timeout_interruptible(HZ/10+1);
640
641 /* did it autodetect? */
642 if (ks0127_read(ks, KS_DEMOD) & 0x40)
643 break;
644
645 /* force to secam mode */
646 ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f);
647 break;
648
649 default:
650 dprintk("ks0127: command DECODER_SET_NORM: "
651 "Unknown norm %d\n", *iarg);
652 break;
653 }
654 break;
655
656 case DECODER_SET_PICTURE:
657 dprintk("ks0127: command DECODER_SET_PICTURE "
658 "not yet supported (fixme)\n");
659 return -EINVAL;
660
661 //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE
662 //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE
663 //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE?
664 //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE
665 //sam todo: KS0127_SET_AGC_MODE:
666 //sam todo: KS0127_SET_AGC:
667 //sam todo: KS0127_SET_CHROMA_MODE:
668 //sam todo: KS0127_SET_PIXCLK_MODE:
669 //sam todo: KS0127_SET_GAMMA_MODE:
670 //sam todo: KS0127_SET_UGAIN:
671 //sam todo: KS0127_SET_VGAIN:
672 //sam todo: KS0127_SET_INVALY:
673 //sam todo: KS0127_SET_INVALU:
674 //sam todo: KS0127_SET_INVALV:
675 //sam todo: KS0127_SET_UNUSEY:
676 //sam todo: KS0127_SET_UNUSEU:
677 //sam todo: KS0127_SET_UNUSEV:
678 //sam todo: KS0127_SET_VSALIGN_MODE:
679
680 case DECODER_ENABLE_OUTPUT:
681 {
682
683 int *iarg = arg;
684 int enable = (*iarg != 0);
685 if (enable) {
686 dprintk("ks0127: command "
687 "DECODER_ENABLE_OUTPUT on "
688 "(%d)\n", enable);
689 /* All output pins on */
690 ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30);
691 /* Obey the OEN pin */
692 ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00);
693 } else {
694 dprintk("ks0127: command "
695 "DECODER_ENABLE_OUTPUT off "
696 "(%d)\n", enable);
697 /* Video output pins off */
698 ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00);
699 /* Ignore the OEN pin */
700 ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80);
701 }
702 }
703 break;
704
705 //sam todo: KS0127_SET_OUTPUT_MODE:
706 //sam todo: KS0127_SET_WIDTH:
707 //sam todo: KS0127_SET_HEIGHT:
708 //sam todo: KS0127_SET_HSCALE:
709
710 case DECODER_GET_STATUS:
711 dprintk("ks0127: command DECODER_GET_STATUS\n");
712 *iarg = 0;
713 status = ks0127_read(ks, KS_STAT);
714 if (!(status & 0x20)) /* NOVID not set */
715 *iarg = (*iarg & DECODER_STATUS_GOOD);
716 if ((status & 0x01)) /* CLOCK set */
717 *iarg = (*iarg & DECODER_STATUS_COLOR);
718 if ((status & 0x08)) /* PALDET set */
719 *iarg = (*iarg & DECODER_STATUS_PAL);
720 else
721 *iarg = (*iarg & DECODER_STATUS_NTSC);
722 break;
723
724 //Catch any unknown command
725 default:
726 dprintk("ks0127: command unknown: %04X\n", cmd);
727 return -EINVAL;
728 }
729 return 0;
730}
731
732
733
734
735static int ks0127_probe(struct i2c_adapter *adapter);
736static int ks0127_detach(struct i2c_client *client);
737static int ks0127_command(struct i2c_client *client,
738 unsigned int cmd, void *arg);
739
740
741
742/* Addresses to scan */
743static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1,
744 I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END};
745static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
746static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
747static struct i2c_client_address_data addr_data = {
748 normal_i2c,
749 probe,
750 ignore,
751};
752
753static struct i2c_driver i2c_driver_ks0127 = {
754 .driver.name = "ks0127",
755 .id = I2C_DRIVERID_KS0127,
756 .attach_adapter = ks0127_probe,
757 .detach_client = ks0127_detach,
758 .command = ks0127_command
759};
760
761static struct i2c_client ks0127_client_tmpl =
762{
763 .name = "(ks0127 unset)",
764 .addr = 0,
765 .adapter = NULL,
766 .driver = &i2c_driver_ks0127,
767 .usage_count = 0
768};
769
770static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind)
771{
772 struct ks0127 *ks;
773 struct i2c_client *client;
774
775 client = kzalloc(sizeof(*client), GFP_KERNEL);
776 if (client == NULL)
777 return -ENOMEM;
778 memcpy(client, &ks0127_client_tmpl, sizeof(*client));
779
780 ks = kzalloc(sizeof(*ks), GFP_KERNEL);
781 if (ks == NULL) {
782 kfree(client);
783 return -ENOMEM;
784 }
785
786 i2c_set_clientdata(client, ks);
787 client->adapter = adapter;
788 client->addr = addr;
789 sprintf(client->name, "ks0127-%02x", adapter->id);
790
791 ks->client = client;
792 ks->addr = addr;
793 ks->ks_type = KS_TYPE_UNKNOWN;
794
795 /* power up */
796 ks0127_write(ks, KS_CMDA, 0x2c);
797 mdelay(10);
798
799 /* reset the device */
800 ks0127_reset(ks);
801 printk(KERN_INFO "ks0127: attach: %s video decoder\n",
802 ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board");
803
804 i2c_attach_client(client);
805 return 0;
806}
807
808
809static int ks0127_probe(struct i2c_adapter *adapter)
810{
811 if (adapter->id == I2C_HW_B_ZR36067)
812 return i2c_probe(adapter, &addr_data, ks0127_found_proc);
813 return 0;
814}
815
816static int ks0127_detach(struct i2c_client *client)
817{
818 struct ks0127 *ks = i2c_get_clientdata(client);
819
820 ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/
821 ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */
822
823 i2c_detach_client(client);
824 kfree(ks);
825 kfree(client);
826
827 dprintk("ks0127: detach\n");
828 return 0;
829}
830
831
832static int __devinit ks0127_init_module(void)
833{
834 init_reg_defaults();
835 i2c_add_driver(&i2c_driver_ks0127);
836 return 0;
837}
838
839static void __devexit ks0127_cleanup_module(void)
840{
841 i2c_del_driver(&i2c_driver_ks0127);
842}
843
844
845module_init(ks0127_init_module);
846module_exit(ks0127_cleanup_module);
diff --git a/drivers/media/video/ks0127.h b/drivers/media/video/ks0127.h
new file mode 100644
index 000000000000..1ec578833aea
--- /dev/null
+++ b/drivers/media/video/ks0127.h
@@ -0,0 +1,53 @@
1/*
2 * Video Capture Driver ( Video for Linux 1/2 )
3 * for the Matrox Marvel G200,G400 and Rainbow Runner-G series
4 *
5 * This module is an interface to the KS0127 video decoder chip.
6 *
7 * Copyright (C) 1999 Ryan Drake <stiletto@mediaone.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#ifndef KS0127_H
25#define KS0127_H
26
27#include <linux/videodev.h>
28
29/* input channels */
30#define KS_INPUT_COMPOSITE_1 0
31#define KS_INPUT_COMPOSITE_2 1
32#define KS_INPUT_COMPOSITE_3 2
33#define KS_INPUT_COMPOSITE_4 4
34#define KS_INPUT_COMPOSITE_5 5
35#define KS_INPUT_COMPOSITE_6 6
36
37#define KS_INPUT_SVIDEO_1 8
38#define KS_INPUT_SVIDEO_2 9
39#define KS_INPUT_SVIDEO_3 10
40
41#define KS_INPUT_YUV656 15
42#define KS_INPUT_COUNT 10
43
44/* output channels */
45#define KS_OUTPUT_YUV656E 0
46#define KS_OUTPUT_EXV 1
47
48/* video standards */
49#define KS_STD_NTSC_N 112 /* 50 Hz NTSC */
50#define KS_STD_PAL_M 113 /* 60 Hz PAL */
51
52#endif /* KS0127_H */
53
diff --git a/drivers/media/video/zoran.h b/drivers/media/video/zoran.h
index 0166f555a5ca..ffcda95ed9d4 100644
--- a/drivers/media/video/zoran.h
+++ b/drivers/media/video/zoran.h
@@ -159,7 +159,7 @@ Private IOCTL to set up for displaying MJPEG
159#define BUZ_MAX_FRAME 256 /* Must be a power of 2 */ 159#define BUZ_MAX_FRAME 256 /* Must be a power of 2 */
160#define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */ 160#define BUZ_MASK_FRAME 255 /* Must be BUZ_MAX_FRAME-1 */
161 161
162#define BUZ_MAX_INPUT 8 162#define BUZ_MAX_INPUT 16
163 163
164#if VIDEO_MAX_FRAME <= 32 164#if VIDEO_MAX_FRAME <= 32
165# define V4L_MAX_FRAME 32 165# define V4L_MAX_FRAME 32
@@ -191,6 +191,9 @@ enum card_type {
191 /* Iomega */ 191 /* Iomega */
192 BUZ, 192 BUZ,
193 193
194 /* AverMedia */
195 AVS6EYES,
196
194 /* total number of cards */ 197 /* total number of cards */
195 NUM_CARDS 198 NUM_CARDS
196}; 199};
@@ -379,6 +382,9 @@ struct card_info {
379 /* is the /GWS line conected? */ 382 /* is the /GWS line conected? */
380 u8 gws_not_connected; 383 u8 gws_not_connected;
381 384
385 /* avs6eyes mux setting */
386 u8 input_mux;
387
382 void (*init) (struct zoran * zr); 388 void (*init) (struct zoran * zr);
383}; 389};
384 390
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index 0a85c9e7fb48..798138599bec 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -27,6 +27,8 @@
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */ 28 */
29 29
30#include <linux/delay.h>
31
30#include <linux/config.h> 32#include <linux/config.h>
31#include <linux/types.h> 33#include <linux/types.h>
32#include <linux/kernel.h> 34#include <linux/kernel.h>
@@ -93,6 +95,11 @@ module_param(default_input, int, 0);
93MODULE_PARM_DESC(default_input, 95MODULE_PARM_DESC(default_input,
94 "Default input (0=Composite, 1=S-Video, 2=Internal)"); 96 "Default input (0=Composite, 1=S-Video, 2=Internal)");
95 97
98static int default_mux = 1; /* 6 Eyes input selection */
99module_param(default_mux, int, 0);
100MODULE_PARM_DESC(default_mux,
101 "Default 6 Eyes mux setting (Input selection)");
102
96static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */ 103static int default_norm = 0; /* 0=PAL, 1=NTSC 2=SECAM */
97module_param(default_norm, int, 0); 104module_param(default_norm, int, 0);
98MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)"); 105MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
@@ -301,6 +308,30 @@ lml33_init (struct zoran *zr)
301 GPIO(zr, 2, 1); // Set Composite input/output 308 GPIO(zr, 2, 1); // Set Composite input/output
302} 309}
303 310
311static void
312avs6eyes_init (struct zoran *zr)
313{
314 // AverMedia 6-Eyes original driver by Christer Weinigel
315
316 // Lifted straight from Christer's old driver and
317 // modified slightly by Martin Samuelsson.
318
319 int mux = default_mux; /* 1 = BT866, 7 = VID1 */
320
321 GPIO(zr, 4, 1); /* Bt866 SLEEP on */
322 udelay(2);
323
324 GPIO(zr, 0, 1); /* ZR36060 /RESET on */
325 GPIO(zr, 1, 0); /* ZR36060 /SLEEP on */
326 GPIO(zr, 2, mux & 1); /* MUX S0 */
327 GPIO(zr, 3, 0); /* /FRAME on */
328 GPIO(zr, 4, 0); /* Bt866 SLEEP off */
329 GPIO(zr, 5, mux & 2); /* MUX S1 */
330 GPIO(zr, 6, 0); /* ? */
331 GPIO(zr, 7, mux & 4); /* MUX S2 */
332
333}
334
304static char * 335static char *
305i2cid_to_modulename (u16 i2c_id) 336i2cid_to_modulename (u16 i2c_id)
306{ 337{
@@ -391,6 +422,14 @@ static struct tvnorm f60sqpixel_dc10 = { 780, 640, 0, 716, 525, 480, 12 };
391static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 }; 422static struct tvnorm f50ccir601_lm33r10 = { 864, 720, 74+54, 804, 625, 576, 18 };
392static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }; 423static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 };
393 424
425/* FIXME: The ks0127 seem incapable of swapping U and V, too, which is why I
426 * copy Maxim's left shift hack for the 6 Eyes.
427 *
428 * Christer's driver used the unshifted norms, though...
429 * /Sam */
430static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
431static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
432
394static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { 433static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
395 { 434 {
396 .type = DC10_old, 435 .type = DC10_old,
@@ -419,6 +458,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
419 .gpcs = { -1, 0 }, 458 .gpcs = { -1, 0 },
420 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, 459 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
421 .gws_not_connected = 0, 460 .gws_not_connected = 0,
461 .input_mux = 0,
422 .init = &dc10_init, 462 .init = &dc10_init,
423 }, { 463 }, {
424 .type = DC10_new, 464 .type = DC10_new,
@@ -445,6 +485,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
445 .gpcs = { -1, 1}, 485 .gpcs = { -1, 1},
446 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, 486 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
447 .gws_not_connected = 0, 487 .gws_not_connected = 0,
488 .input_mux = 0,
448 .init = &dc10plus_init, 489 .init = &dc10plus_init,
449 }, { 490 }, {
450 .type = DC10plus, 491 .type = DC10plus,
@@ -474,6 +515,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
474 .gpcs = { -1, 1 }, 515 .gpcs = { -1, 1 },
475 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 }, 516 .vfe_pol = { 1, 1, 1, 1, 0, 0, 0, 0 },
476 .gws_not_connected = 0, 517 .gws_not_connected = 0,
518 .input_mux = 0,
477 .init = &dc10plus_init, 519 .init = &dc10plus_init,
478 }, { 520 }, {
479 .type = DC30, 521 .type = DC30,
@@ -502,6 +544,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
502 .gpcs = { -1, 0 }, 544 .gpcs = { -1, 0 },
503 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, 545 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
504 .gws_not_connected = 0, 546 .gws_not_connected = 0,
547 .input_mux = 0,
505 .init = &dc10_init, 548 .init = &dc10_init,
506 }, { 549 }, {
507 .type = DC30plus, 550 .type = DC30plus,
@@ -532,6 +575,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
532 .gpcs = { -1, 0 }, 575 .gpcs = { -1, 0 },
533 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, 576 .vfe_pol = { 0, 0, 0, 0, 0, 0, 0, 0 },
534 .gws_not_connected = 0, 577 .gws_not_connected = 0,
578 .input_mux = 0,
535 .init = &dc10_init, 579 .init = &dc10_init,
536 }, { 580 }, {
537 .type = LML33, 581 .type = LML33,
@@ -558,6 +602,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
558 .gpcs = { 3, 1 }, 602 .gpcs = { 3, 1 },
559 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, 603 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
560 .gws_not_connected = 1, 604 .gws_not_connected = 1,
605 .input_mux = 0,
561 .init = &lml33_init, 606 .init = &lml33_init,
562 }, { 607 }, {
563 .type = LML33R10, 608 .type = LML33R10,
@@ -586,6 +631,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
586 .gpcs = { 3, 1 }, 631 .gpcs = { 3, 1 },
587 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, 632 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
588 .gws_not_connected = 1, 633 .gws_not_connected = 1,
634 .input_mux = 0,
589 .init = &lml33_init, 635 .init = &lml33_init,
590 }, { 636 }, {
591 .type = BUZ, 637 .type = BUZ,
@@ -614,8 +660,49 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
614 .gpcs = { 3, 1 }, 660 .gpcs = { 3, 1 },
615 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 }, 661 .vfe_pol = { 1, 1, 0, 0, 0, 1, 0, 0 },
616 .gws_not_connected = 1, 662 .gws_not_connected = 1,
663 .input_mux = 0,
617 .init = &buz_init, 664 .init = &buz_init,
665 }, {
666 .type = AVS6EYES,
667 .name = "6-Eyes",
668 /* AverMedia chose not to brand the 6-Eyes. Thus it
669 can't be autodetected, and requires card=x. */
670 .vendor_id = -1,
671 .device_id = -1,
672 .i2c_decoder = I2C_DRIVERID_KS0127,
673 .i2c_encoder = I2C_DRIVERID_BT866,
674 .video_codec = CODEC_TYPE_ZR36060,
675
676 .inputs = 10,
677 .input = {
678 { 0, "Composite 1" },
679 { 1, "Composite 2" },
680 { 2, "Composite 3" },
681 { 4, "Composite 4" },
682 { 5, "Composite 5" },
683 { 6, "Composite 6" },
684 { 8, "S-Video 1" },
685 { 9, "S-Video 2" },
686 {10, "S-Video 3" },
687 {15, "YCbCr" }
688 },
689 .norms = 2,
690 .tvn = {
691 &f50ccir601_avs6eyes,
692 &f60ccir601_avs6eyes,
693 NULL
694 },
695 .jpeg_int = ZR36057_ISR_GIRQ1,
696 .vsync_int = ZR36057_ISR_GIRQ0,
697 .gpio = { 1, 0, 3, -1, -1, -1, -1, -1 },// Validity unknown /Sam
698 .gpio_pol = { 0, 0, 0, 0, 0, 0, 0, 0 }, // Validity unknown /Sam
699 .gpcs = { 3, 1 }, // Validity unknown /Sam
700 .vfe_pol = { 1, 0, 0, 0, 0, 1, 0, 0 }, // Validity unknown /Sam
701 .gws_not_connected = 1,
702 .input_mux = 1,
703 .init = &avs6eyes_init,
618 } 704 }
705
619}; 706};
620 707
621/* 708/*