V4L/DVB (10714): zoran et al: convert zoran i2c modules to V4L2.
[deliverable/linux.git] / drivers / media / video / bt866.c
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/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>
41
42 MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
43 MODULE_AUTHOR("Mike Bernson & Dave Perks");
44 MODULE_LICENSE("GPL");
45
46 static int debug;
47 module_param(debug, int, 0);
48 MODULE_PARM_DESC(debug, "Debug level (0-1)");
49
50 /* ----------------------------------------------------------------------- */
51
52 struct bt866 {
53 u8 reg[256];
54
55 v4l2_std_id norm;
56 int bright;
57 int contrast;
58 int hue;
59 int sat;
60 };
61
62 static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
63 {
64 struct bt866 *encoder = i2c_get_clientdata(client);
65 u8 buffer[2];
66 int err;
67
68 buffer[0] = subaddr;
69 buffer[1] = data;
70
71 encoder->reg[subaddr] = data;
72
73 v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);
74
75 for (err = 0; err < 3;) {
76 if (i2c_master_send(client, buffer, 2) == 2)
77 break;
78 err++;
79 v4l_warn(client, "error #%d writing to 0x%02x\n",
80 err, subaddr);
81 schedule_timeout_interruptible(msecs_to_jiffies(100));
82 }
83 if (err == 3) {
84 v4l_warn(client, "giving up\n");
85 return -1;
86 }
87
88 return 0;
89 }
90
91 static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
92 {
93 struct bt866 *encoder = i2c_get_clientdata(client);
94
95 switch (cmd) {
96 case VIDIOC_INT_S_STD_OUTPUT:
97 {
98 v4l2_std_id *iarg = arg;
99
100 v4l_dbg(1, debug, client, "set norm %llx\n", *iarg);
101
102 if (!(*iarg & (V4L2_STD_NTSC | V4L2_STD_PAL)))
103 return -EINVAL;
104 encoder->norm = *iarg;
105 break;
106 }
107
108 case VIDIOC_INT_S_VIDEO_ROUTING:
109 {
110 struct v4l2_routing *route = arg;
111 static const __u8 init[] = {
112 0xc8, 0xcc, /* CRSCALE */
113 0xca, 0x91, /* CBSCALE */
114 0xcc, 0x24, /* YC16 | OSDNUM */
115 0xda, 0x00, /* */
116 0xdc, 0x24, /* SETMODE | PAL */
117 0xde, 0x02, /* EACTIVE */
118
119 /* overlay colors */
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 */
128
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 */
137 };
138 int i;
139 u8 val;
140
141 for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
142 bt866_write(client, init[i], init[i+1]);
143
144 val = encoder->reg[0xdc];
145
146 if (route->input == 0)
147 val |= 0x40; /* CBSWAP */
148 else
149 val &= ~0x40; /* !CBSWAP */
150
151 bt866_write(client, 0xdc, val);
152
153 val = encoder->reg[0xcc];
154 if (route->input == 2)
155 val |= 0x01; /* OSDBAR */
156 else
157 val &= ~0x01; /* !OSDBAR */
158 bt866_write(client, 0xcc, val);
159
160 v4l_dbg(1, debug, client, "set input %d\n", route->input);
161
162 switch (route->input) {
163 case 0:
164 break;
165 case 1:
166 break;
167 default:
168 return -EINVAL;
169 }
170 break;
171 }
172
173 case 4711:
174 {
175 int *iarg = arg;
176 __u8 val;
177
178 v4l_dbg(1, debug, client, "square %d\n", *iarg);
179
180 val = encoder->reg[0xdc];
181 if (*iarg)
182 val |= 1; /* SQUARE */
183 else
184 val &= ~1; /* !SQUARE */
185 bt866_write(client, 0xdc, val);
186 break;
187 }
188
189 default:
190 return -EINVAL;
191 }
192
193 return 0;
194 }
195
196 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
197
198 I2C_CLIENT_INSMOD;
199
200 static int bt866_probe(struct i2c_client *client,
201 const struct i2c_device_id *id)
202 {
203 struct bt866 *encoder;
204
205 v4l_info(client, "chip found @ 0x%x (%s)\n",
206 client->addr << 1, client->adapter->name);
207
208 encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
209 if (encoder == NULL)
210 return -ENOMEM;
211
212 i2c_set_clientdata(client, encoder);
213 return 0;
214 }
215
216 static int bt866_remove(struct i2c_client *client)
217 {
218 kfree(i2c_get_clientdata(client));
219 return 0;
220 }
221
222 static int bt866_legacy_probe(struct i2c_adapter *adapter)
223 {
224 return adapter->id == I2C_HW_B_ZR36067;
225 }
226
227 static const struct i2c_device_id bt866_id[] = {
228 { "bt866", 0 },
229 { }
230 };
231 MODULE_DEVICE_TABLE(i2c, bt866_id);
232
233 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
234 .name = "bt866",
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,
241 };
This page took 0.037139 seconds and 6 git commands to generate.