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 /* ----------------------------------------------------------------------- */
62 static int bt866_write(struct i2c_client
*client
, u8 subaddr
, u8 data
)
64 struct bt866
*encoder
= i2c_get_clientdata(client
);
71 encoder
->reg
[subaddr
] = data
;
73 v4l_dbg(1, debug
, client
, "write 0x%02x = 0x%02x\n", subaddr
, data
);
75 for (err
= 0; err
< 3;) {
76 if (i2c_master_send(client
, buffer
, 2) == 2)
79 v4l_warn(client
, "error #%d writing to 0x%02x\n",
81 schedule_timeout_interruptible(msecs_to_jiffies(100));
84 v4l_warn(client
, "giving up\n");
91 static int bt866_command(struct i2c_client
*client
, unsigned cmd
, void *arg
)
93 struct bt866
*encoder
= i2c_get_clientdata(client
);
96 case VIDIOC_INT_S_STD_OUTPUT
:
98 v4l2_std_id
*iarg
= arg
;
100 v4l_dbg(1, debug
, client
, "set norm %llx\n", *iarg
);
102 if (!(*iarg
& (V4L2_STD_NTSC
| V4L2_STD_PAL
)))
104 encoder
->norm
= *iarg
;
108 case VIDIOC_INT_S_VIDEO_ROUTING
:
110 struct v4l2_routing
*route
= arg
;
111 static const __u8 init
[] = {
112 0xc8, 0xcc, /* CRSCALE */
113 0xca, 0x91, /* CBSCALE */
114 0xcc, 0x24, /* YC16 | OSDNUM */
116 0xdc, 0x24, /* SETMODE | PAL */
117 0xde, 0x02, /* EACTIVE */
120 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
121 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
122 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
123 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
124 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
125 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
126 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
127 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
129 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
130 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
131 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
132 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
133 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
134 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
135 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
136 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
141 for (i
= 0; i
< ARRAY_SIZE(init
) / 2; i
+= 2)
142 bt866_write(client
, init
[i
], init
[i
+1]);
144 val
= encoder
->reg
[0xdc];
146 if (route
->input
== 0)
147 val
|= 0x40; /* CBSWAP */
149 val
&= ~0x40; /* !CBSWAP */
151 bt866_write(client
, 0xdc, val
);
153 val
= encoder
->reg
[0xcc];
154 if (route
->input
== 2)
155 val
|= 0x01; /* OSDBAR */
157 val
&= ~0x01; /* !OSDBAR */
158 bt866_write(client
, 0xcc, val
);
160 v4l_dbg(1, debug
, client
, "set input %d\n", route
->input
);
162 switch (route
->input
) {
178 v4l_dbg(1, debug
, client
, "square %d\n", *iarg
);
180 val
= encoder
->reg
[0xdc];
182 val
|= 1; /* SQUARE */
184 val
&= ~1; /* !SQUARE */
185 bt866_write(client
, 0xdc, val
);
196 static unsigned short normal_i2c
[] = { 0x88 >> 1, I2C_CLIENT_END
};
200 static int bt866_probe(struct i2c_client
*client
,
201 const struct i2c_device_id
*id
)
203 struct bt866
*encoder
;
205 v4l_info(client
, "chip found @ 0x%x (%s)\n",
206 client
->addr
<< 1, client
->adapter
->name
);
208 encoder
= kzalloc(sizeof(*encoder
), GFP_KERNEL
);
212 i2c_set_clientdata(client
, encoder
);
216 static int bt866_remove(struct i2c_client
*client
)
218 kfree(i2c_get_clientdata(client
));
222 static int bt866_legacy_probe(struct i2c_adapter
*adapter
)
224 return adapter
->id
== I2C_HW_B_ZR36067
;
227 static const struct i2c_device_id bt866_id
[] = {
231 MODULE_DEVICE_TABLE(i2c
, bt866_id
);
233 static struct v4l2_i2c_driver_data v4l2_i2c_data
= {
235 .driverid
= I2C_DRIVERID_BT866
,
236 .command
= bt866_command
,
237 .probe
= bt866_probe
,
238 .remove
= bt866_remove
,
239 .legacy_probe
= bt866_legacy_probe
,
240 .id_table
= bt866_id
,