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/videodev2.h>
38 #include <media/v4l2-device.h>
39 #include <media/v4l2-chip-ident.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 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
54 /* ----------------------------------------------------------------------- */
57 struct v4l2_subdev sd;
61 static inline struct bt866 *to_bt866(struct v4l2_subdev *sd)
63 return container_of(sd, struct bt866, sd);
66 static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data)
68 struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
75 encoder->reg[subaddr] = data;
77 v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);
79 for (err = 0; err < 3;) {
80 if (i2c_master_send(client, buffer, 2) == 2)
83 v4l_warn(client, "error #%d writing to 0x%02x\n",
85 schedule_timeout_interruptible(msecs_to_jiffies(100));
88 v4l_warn(client, "giving up\n");
95 static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
97 v4l2_dbg(1, debug, sd, "set norm %llx\n", std);
99 /* Only PAL supported by this driver at the moment! */
100 if (!(std & V4L2_STD_NTSC))
105 static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
107 static const __u8 init[] = {
108 0xc8, 0xcc, /* CRSCALE */
109 0xca, 0x91, /* CBSCALE */
110 0xcc, 0x24, /* YC16 | OSDNUM */
112 0xdc, 0x24, /* SETMODE | PAL */
113 0xde, 0x02, /* EACTIVE */
116 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
117 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
118 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
119 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
120 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
121 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
122 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
123 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
125 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
126 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
127 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
128 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
129 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
130 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
131 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
132 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
134 struct bt866 *encoder = to_bt866(sd);
138 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
139 bt866_write(encoder, init[i], init[i+1]);
141 val = encoder->reg[0xdc];
143 if (route->input == 0)
144 val |= 0x40; /* CBSWAP */
146 val &= ~0x40; /* !CBSWAP */
148 bt866_write(encoder, 0xdc, val);
150 val = encoder->reg[0xcc];
151 if (route->input == 2)
152 val |= 0x01; /* OSDBAR */
154 val &= ~0x01; /* !OSDBAR */
155 bt866_write(encoder, 0xcc, val);
157 v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
159 switch (route->input) {
171 /* Code to setup square pixels, might be of some use in the future,
172 but is currently unused. */
173 val = encoder->reg[0xdc];
175 val |= 1; /* SQUARE */
177 val &= ~1; /* !SQUARE */
178 bt866_write(client, 0xdc, val);
181 static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
183 struct i2c_client *client = v4l2_get_subdevdata(sd);
185 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
188 static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
190 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
193 /* ----------------------------------------------------------------------- */
195 static const struct v4l2_subdev_core_ops bt866_core_ops = {
196 .g_chip_ident = bt866_g_chip_ident,
199 static const struct v4l2_subdev_video_ops bt866_video_ops = {
200 .s_std_output = bt866_s_std_output,
201 .s_routing = bt866_s_routing,
204 static const struct v4l2_subdev_ops bt866_ops = {
205 .core = &bt866_core_ops,
206 .video = &bt866_video_ops,
209 static int bt866_probe(struct i2c_client *client,
210 const struct i2c_device_id *id)
212 struct bt866 *encoder;
213 struct v4l2_subdev *sd;
215 v4l_info(client, "chip found @ 0x%x (%s)\n",
216 client->addr << 1, client->adapter->name);
218 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
222 v4l2_i2c_subdev_init(sd, client, &bt866_ops);
226 static int bt866_remove(struct i2c_client *client)
228 struct v4l2_subdev *sd = i2c_get_clientdata(client);
230 v4l2_device_unregister_subdev(sd);
235 static int bt866_legacy_probe(struct i2c_adapter *adapter)
237 return adapter->id == I2C_HW_B_ZR36067;
240 static const struct i2c_device_id bt866_id[] = {
244 MODULE_DEVICE_TABLE(i2c, bt866_id);
246 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
248 .driverid = I2C_DRIVERID_BT866,
249 .command = bt866_command,
250 .probe = bt866_probe,
251 .remove = bt866_remove,
252 .legacy_probe = bt866_legacy_probe,
253 .id_table = bt866_id,