2 * bt819 - BT819A VideoStream Decoder (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 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
13 * This code was modify/ported from the saa7111 driver written
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 <linux/delay.h>
35 #include <asm/uaccess.h>
36 #include <linux/i2c.h>
37 #include <linux/i2c-id.h>
38 #include <linux/videodev2.h>
39 #include <media/v4l2-device.h>
40 #include <media/v4l2-chip-ident.h>
41 #include <media/v4l2-i2c-drv-legacy.h>
43 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
44 MODULE_AUTHOR("Mike Bernson & Dave Perks");
45 MODULE_LICENSE("GPL");
48 module_param(debug, int, 0);
49 MODULE_PARM_DESC(debug, "Debug level (0-1)");
51 static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END };
55 /* ----------------------------------------------------------------------- */
58 struct v4l2_subdev sd;
59 unsigned char reg[32];
71 static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
73 return container_of(sd, struct bt819, sd);
85 /* for values, see the bt819 datasheet */
86 static struct timing timing_data[] = {
87 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
88 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
91 /* ----------------------------------------------------------------------- */
93 static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
95 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
97 decoder->reg[reg] = value;
98 return i2c_smbus_write_byte_data(client, reg, value);
101 static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
103 return bt819_write(decoder, reg,
104 (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
107 static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
109 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
113 /* the bt819 has an autoincrement function, use it if
114 * the adapter understands raw I2C */
115 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
116 /* do raw I2C, not smbus compatible */
122 block_data[block_len++] = reg = data[0];
124 block_data[block_len++] =
125 decoder->reg[reg++] = data[1];
128 } while (len >= 2 && data[0] == reg && block_len < 32);
129 ret = i2c_master_send(client, block_data, block_len);
134 /* do some slow I2C emulation kind of thing */
137 ret = bt819_write(decoder, reg, *data++);
147 static inline int bt819_read(struct bt819 *decoder, u8 reg)
149 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
151 return i2c_smbus_read_byte_data(client, reg);
154 static int bt819_init(struct v4l2_subdev *sd)
156 static unsigned char init[] = {
157 /*0x1f, 0x00,*/ /* Reset */
158 0x01, 0x59, /* 0x01 input format */
159 0x02, 0x00, /* 0x02 temporal decimation */
160 0x03, 0x12, /* 0x03 Cropping msb */
161 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
162 0x05, 0xe0, /* 0x05 Vertical Active lsb */
163 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
164 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
165 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
166 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
167 0x0a, 0x00, /* 0x0a Brightness control */
168 0x0b, 0x30, /* 0x0b Miscellaneous control */
169 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
170 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
171 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
172 0x0f, 0x00, /* 0x0f Hue control */
173 0x12, 0x04, /* 0x12 Output Format */
174 0x13, 0x20, /* 0x13 Vertial Scaling msb 0x00
175 chroma comb OFF, line drop scaling, interlace scaling
176 BUG? Why does turning the chroma comb on fuck up color?
177 Bug in the bt819 stepping on my board?
179 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
180 0x16, 0x07, /* 0x16 Video Timing Polarity
184 hreset=active high */
185 0x18, 0x68, /* 0x18 AGC Delay */
186 0x19, 0x5d, /* 0x19 Burst Gate Delay */
187 0x1a, 0x80, /* 0x1a ADC Interface */
190 struct bt819 *decoder = to_bt819(sd);
191 struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
194 (((timing->vdelay >> 8) & 0x03) << 6) |
195 (((timing->vactive >> 8) & 0x03) << 4) |
196 (((timing->hdelay >> 8) & 0x03) << 2) |
197 ((timing->hactive >> 8) & 0x03);
198 init[0x04 * 2 - 1] = timing->vdelay & 0xff;
199 init[0x05 * 2 - 1] = timing->vactive & 0xff;
200 init[0x06 * 2 - 1] = timing->hdelay & 0xff;
201 init[0x07 * 2 - 1] = timing->hactive & 0xff;
202 init[0x08 * 2 - 1] = timing->hscale >> 8;
203 init[0x09 * 2 - 1] = timing->hscale & 0xff;
204 /* 0x15 in array is address 0x19 */
205 init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */
207 bt819_write(decoder, 0x1f, 0x00);
211 return bt819_write_block(decoder, init, sizeof(init));
214 /* ----------------------------------------------------------------------- */
216 static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
218 struct bt819 *decoder = to_bt819(sd);
219 int status = bt819_read(decoder, 0x00);
220 int res = V4L2_IN_ST_NO_SIGNAL;
235 v4l2_dbg(1, debug, sd, "get status %x\n", status);
239 static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
241 return bt819_status(sd, NULL, std);
244 static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
246 return bt819_status(sd, status, NULL);
249 static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
251 struct bt819 *decoder = to_bt819(sd);
252 struct timing *timing = NULL;
254 v4l2_dbg(1, debug, sd, "set norm %llx\n", std);
256 if (std & V4L2_STD_NTSC) {
257 bt819_setbit(decoder, 0x01, 0, 1);
258 bt819_setbit(decoder, 0x01, 1, 0);
259 bt819_setbit(decoder, 0x01, 5, 0);
260 bt819_write(decoder, 0x18, 0x68);
261 bt819_write(decoder, 0x19, 0x5d);
262 /* bt819_setbit(decoder, 0x1a, 5, 1); */
263 timing = &timing_data[1];
264 } else if (std & V4L2_STD_PAL) {
265 bt819_setbit(decoder, 0x01, 0, 1);
266 bt819_setbit(decoder, 0x01, 1, 1);
267 bt819_setbit(decoder, 0x01, 5, 1);
268 bt819_write(decoder, 0x18, 0x7f);
269 bt819_write(decoder, 0x19, 0x72);
270 /* bt819_setbit(decoder, 0x1a, 5, 0); */
271 timing = &timing_data[0];
273 v4l2_dbg(1, debug, sd, "unsupported norm %llx\n", std);
276 bt819_write(decoder, 0x03,
277 (((timing->vdelay >> 8) & 0x03) << 6) |
278 (((timing->vactive >> 8) & 0x03) << 4) |
279 (((timing->hdelay >> 8) & 0x03) << 2) |
280 ((timing->hactive >> 8) & 0x03));
281 bt819_write(decoder, 0x04, timing->vdelay & 0xff);
282 bt819_write(decoder, 0x05, timing->vactive & 0xff);
283 bt819_write(decoder, 0x06, timing->hdelay & 0xff);
284 bt819_write(decoder, 0x07, timing->hactive & 0xff);
285 bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
286 bt819_write(decoder, 0x09, timing->hscale & 0xff);
291 static int bt819_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
293 struct bt819 *decoder = to_bt819(sd);
295 v4l2_dbg(1, debug, sd, "set input %x\n", route->input);
297 if (route->input < 0 || route->input > 7)
300 if (decoder->input != route->input) {
301 decoder->input = route->input;
303 if (decoder->input == 0) {
304 bt819_setbit(decoder, 0x0b, 6, 0);
305 bt819_setbit(decoder, 0x1a, 1, 1);
307 bt819_setbit(decoder, 0x0b, 6, 1);
308 bt819_setbit(decoder, 0x1a, 1, 0);
314 static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
316 struct bt819 *decoder = to_bt819(sd);
318 v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
320 if (decoder->enable != enable) {
321 decoder->enable = enable;
322 bt819_setbit(decoder, 0x16, 7, !enable);
327 static int bt819_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
330 case V4L2_CID_BRIGHTNESS:
331 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
334 case V4L2_CID_CONTRAST:
335 v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
338 case V4L2_CID_SATURATION:
339 v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
343 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
352 static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
354 struct bt819 *decoder = to_bt819(sd);
358 case V4L2_CID_BRIGHTNESS:
359 if (decoder->bright == ctrl->value)
361 decoder->bright = ctrl->value;
362 bt819_write(decoder, 0x0a, decoder->bright);
365 case V4L2_CID_CONTRAST:
366 if (decoder->contrast == ctrl->value)
368 decoder->contrast = ctrl->value;
369 bt819_write(decoder, 0x0c, decoder->contrast & 0xff);
370 bt819_setbit(decoder, 0x0b, 2, ((decoder->contrast >> 8) & 0x01));
373 case V4L2_CID_SATURATION:
374 if (decoder->sat == ctrl->value)
376 decoder->sat = ctrl->value;
377 bt819_write(decoder, 0x0d, (decoder->sat >> 7) & 0xff);
378 bt819_setbit(decoder, 0x0b, 1, ((decoder->sat >> 15) & 0x01));
380 /* Ratio between U gain and V gain must stay the same as
381 the ratio between the default U and V gain values. */
382 temp = (decoder->sat * 180) / 254;
383 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
384 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
388 if (decoder->hue == ctrl->value)
390 decoder->hue = ctrl->value;
391 bt819_write(decoder, 0x0f, decoder->hue);
400 static int bt819_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
402 struct bt819 *decoder = to_bt819(sd);
405 case V4L2_CID_BRIGHTNESS:
406 ctrl->value = decoder->bright;
408 case V4L2_CID_CONTRAST:
409 ctrl->value = decoder->contrast;
411 case V4L2_CID_SATURATION:
412 ctrl->value = decoder->sat;
415 ctrl->value = decoder->hue;
423 static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
425 struct bt819 *decoder = to_bt819(sd);
426 struct i2c_client *client = v4l2_get_subdevdata(sd);
428 return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
431 static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
433 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
436 /* ----------------------------------------------------------------------- */
438 static const struct v4l2_subdev_core_ops bt819_core_ops = {
439 .g_chip_ident = bt819_g_chip_ident,
440 .g_ctrl = bt819_g_ctrl,
441 .s_ctrl = bt819_s_ctrl,
442 .queryctrl = bt819_queryctrl,
445 static const struct v4l2_subdev_tuner_ops bt819_tuner_ops = {
446 .s_std = bt819_s_std,
449 static const struct v4l2_subdev_video_ops bt819_video_ops = {
450 .s_routing = bt819_s_routing,
451 .s_stream = bt819_s_stream,
452 .querystd = bt819_querystd,
453 .g_input_status = bt819_g_input_status,
456 static const struct v4l2_subdev_ops bt819_ops = {
457 .core = &bt819_core_ops,
458 .tuner = &bt819_tuner_ops,
459 .video = &bt819_video_ops,
462 /* ----------------------------------------------------------------------- */
464 static int bt819_probe(struct i2c_client *client,
465 const struct i2c_device_id *id)
468 struct bt819 *decoder;
469 struct v4l2_subdev *sd;
472 /* Check if the adapter supports the needed features */
473 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
476 decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
480 v4l2_i2c_subdev_init(sd, client, &bt819_ops);
482 ver = bt819_read(decoder, 0x17);
483 switch (ver & 0xf0) {
486 decoder->ident = V4L2_IDENT_BT819A;
490 decoder->ident = V4L2_IDENT_BT817A;
494 decoder->ident = V4L2_IDENT_BT815A;
497 v4l2_dbg(1, debug, sd,
498 "unknown chip version 0x%02x\n", ver);
502 v4l_info(client, "%s found @ 0x%x (%s)\n", name,
503 client->addr << 1, client->adapter->name);
505 decoder->norm = V4L2_STD_NTSC;
509 decoder->contrast = 0xd8; /* 100% of original signal */
511 decoder->sat = 0xfe; /* 100% of original signal */
515 v4l2_dbg(1, debug, sd, "init status %d\n", i);
519 static int bt819_remove(struct i2c_client *client)
521 struct v4l2_subdev *sd = i2c_get_clientdata(client);
523 v4l2_device_unregister_subdev(sd);
528 /* ----------------------------------------------------------------------- */
530 static const struct i2c_device_id bt819_id[] = {
536 MODULE_DEVICE_TABLE(i2c, bt819_id);
538 static struct v4l2_i2c_driver_data v4l2_i2c_data = {
540 .driverid = I2C_DRIVERID_BT819,
541 .command = bt819_command,
542 .probe = bt819_probe,
543 .remove = bt819_remove,
544 .id_table = bt819_id,