2 bt866 - BT866 Digital Video Encoder (Rockwell Part)
4 Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 Copyright (C) 1998 Dave Perks <dperks@ibm.net>
7 Modifications for LML33/DC10plus unified driver
8 Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
10 This code was modify/ported from the saa7111 driver written
13 This code was adapted for the bt866 by Christer Weinigel and ported
14 to 2.6 by Martin Samuelsson.
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.
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.
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.
31 #include <linux/module.h>
32 #include <linux/types.h>
33 #include <linux/ioctl.h>
34 #include <asm/uaccess.h>
35 #include <linux/i2c.h>
36 #include <linux/i2c-id.h>
37 #include <linux/videodev.h>
38 #include <linux/video_encoder.h>
39 #include <media/v4l2-common.h>
40 #include <media/v4l2-i2c-drv-legacy.h>
42 MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
43 MODULE_AUTHOR("Mike Bernson & Dave Perks");
44 MODULE_LICENSE("GPL");
47 module_param(debug
, int, 0);
48 MODULE_PARM_DESC(debug
, "Debug level (0-1)");
50 /* ----------------------------------------------------------------------- */
63 static int bt866_write(struct i2c_client
*client
, u8 subaddr
, u8 data
)
65 struct bt866
*encoder
= i2c_get_clientdata(client
);
72 encoder
->reg
[subaddr
] = data
;
74 v4l_dbg(1, debug
, client
, "write 0x%02x = 0x%02x\n", subaddr
, data
);
76 for (err
= 0; err
< 3;) {
77 if (i2c_master_send(client
, buffer
, 2) == 2)
80 v4l_warn(client
, "error #%d writing to 0x%02x\n",
82 schedule_timeout_interruptible(msecs_to_jiffies(100));
85 v4l_warn(client
, "giving up\n");
92 static int bt866_command(struct i2c_client
*client
, unsigned cmd
, void *arg
)
94 struct bt866
*encoder
= i2c_get_clientdata(client
);
97 case ENCODER_GET_CAPABILITIES
:
99 struct video_encoder_capability
*cap
= arg
;
101 v4l_dbg(1, debug
, client
, "get capabilities\n");
106 | VIDEO_ENCODER_CCIR
;
112 case ENCODER_SET_NORM
:
116 v4l_dbg(1, debug
, client
, "set norm %d\n", *iarg
);
119 case VIDEO_MODE_NTSC
:
128 encoder
->norm
= *iarg
;
132 case ENCODER_SET_INPUT
:
135 static const __u8 init
[] = {
136 0xc8, 0xcc, /* CRSCALE */
137 0xca, 0x91, /* CBSCALE */
138 0xcc, 0x24, /* YC16 | OSDNUM */
140 0xdc, 0x24, /* SETMODE | PAL */
141 0xde, 0x02, /* EACTIVE */
144 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
145 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
146 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
147 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
148 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
149 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
150 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
151 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
153 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
154 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
155 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
156 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
157 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
158 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
159 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
160 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
165 for (i
= 0; i
< ARRAY_SIZE(init
) / 2; i
+= 2)
166 bt866_write(client
, init
[i
], init
[i
+1]);
168 val
= encoder
->reg
[0xdc];
171 val
|= 0x40; /* CBSWAP */
173 val
&= ~0x40; /* !CBSWAP */
175 bt866_write(client
, 0xdc, val
);
177 val
= encoder
->reg
[0xcc];
179 val
|= 0x01; /* OSDBAR */
181 val
&= ~0x01; /* !OSDBAR */
182 bt866_write(client
, 0xcc, val
);
184 v4l_dbg(1, debug
, client
, "set input %d\n", *iarg
);
197 case ENCODER_SET_OUTPUT
:
201 v4l_dbg(1, debug
, client
, "set output %d\n", *iarg
);
203 /* not much choice of outputs */
209 case ENCODER_ENABLE_OUTPUT
:
212 encoder
->enable
= !!*iarg
;
214 v4l_dbg(1, debug
, client
, "enable output %d\n", encoder
->enable
);
223 v4l_dbg(1, debug
, client
, "square %d\n", *iarg
);
225 val
= encoder
->reg
[0xdc];
227 val
|= 1; /* SQUARE */
229 val
&= ~1; /* !SQUARE */
230 bt866_write(client
, 0xdc, val
);
241 static unsigned short normal_i2c
[] = { 0x88 >> 1, I2C_CLIENT_END
};
245 static int bt866_probe(struct i2c_client
*client
,
246 const struct i2c_device_id
*id
)
248 struct bt866
*encoder
;
250 v4l_info(client
, "chip found @ 0x%x (%s)\n",
251 client
->addr
<< 1, client
->adapter
->name
);
253 encoder
= kzalloc(sizeof(*encoder
), GFP_KERNEL
);
257 i2c_set_clientdata(client
, encoder
);
261 static int bt866_remove(struct i2c_client
*client
)
263 kfree(i2c_get_clientdata(client
));
267 static int bt866_legacy_probe(struct i2c_adapter
*adapter
)
269 return adapter
->id
== I2C_HW_B_ZR36067
;
272 static const struct i2c_device_id bt866_id
[] = {
276 MODULE_DEVICE_TABLE(i2c
, bt866_id
);
278 static struct v4l2_i2c_driver_data v4l2_i2c_data
= {
280 .driverid
= I2C_DRIVERID_BT866
,
281 .command
= bt866_command
,
282 .probe
= bt866_probe
,
283 .remove
= bt866_remove
,
284 .legacy_probe
= bt866_legacy_probe
,
285 .id_table
= bt866_id
,