1 /*
2 * bt819 - BT819A VideoStream Decoder (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 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
11 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
12 *
13 * This code was modify/ported from the saa7111 driver written
14 * by Dave Perks.
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
27 #include <linux/module.h>
28 #include <linux/types.h>
29 #include <linux/ioctl.h>
30 #include <linux/delay.h>
31 #include <linux/i2c.h>
32 #include <linux/videodev2.h>
33 #include <linux/slab.h>
34 #include <media/v4l2-device.h>
35 #include <media/v4l2-ctrls.h>
36 #include <media/i2c/bt819.h>
37
38 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
39 MODULE_AUTHOR("Mike Bernson & Dave Perks");
40 MODULE_LICENSE("GPL");
41
42 static int debug;
43 module_param(debug, int, 0);
44 MODULE_PARM_DESC(debug, "Debug level (0-1)");
45
46
47 /* ----------------------------------------------------------------------- */
48
49 struct bt819 {
50 struct v4l2_subdev sd;
51 struct v4l2_ctrl_handler hdl;
52 unsigned char reg[32];
53
54 v4l2_std_id norm;
55 int input;
56 int enable;
57 };
58
to_bt819(struct v4l2_subdev * sd)59 static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
60 {
61 return container_of(sd, struct bt819, sd);
62 }
63
to_sd(struct v4l2_ctrl * ctrl)64 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
65 {
66 return &container_of(ctrl->handler, struct bt819, hdl)->sd;
67 }
68
69 struct timing {
70 int hactive;
71 int hdelay;
72 int vactive;
73 int vdelay;
74 int hscale;
75 int vscale;
76 };
77
78 /* for values, see the bt819 datasheet */
79 static struct timing timing_data[] = {
80 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
81 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
82 };
83
84 /* ----------------------------------------------------------------------- */
85
bt819_write(struct bt819 * decoder,u8 reg,u8 value)86 static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
87 {
88 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
89
90 decoder->reg[reg] = value;
91 return i2c_smbus_write_byte_data(client, reg, value);
92 }
93
bt819_setbit(struct bt819 * decoder,u8 reg,u8 bit,u8 value)94 static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
95 {
96 return bt819_write(decoder, reg,
97 (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
98 }
99
bt819_write_block(struct bt819 * decoder,const u8 * data,unsigned int len)100 static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
101 {
102 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
103 int ret = -1;
104 u8 reg;
105
106 /* the bt819 has an autoincrement function, use it if
107 * the adapter understands raw I2C */
108 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
109 /* do raw I2C, not smbus compatible */
110 u8 block_data[32];
111 int block_len;
112
113 while (len >= 2) {
114 block_len = 0;
115 block_data[block_len++] = reg = data[0];
116 do {
117 block_data[block_len++] =
118 decoder->reg[reg++] = data[1];
119 len -= 2;
120 data += 2;
121 } while (len >= 2 && data[0] == reg && block_len < 32);
122 ret = i2c_master_send(client, block_data, block_len);
123 if (ret < 0)
124 break;
125 }
126 } else {
127 /* do some slow I2C emulation kind of thing */
128 while (len >= 2) {
129 reg = *data++;
130 ret = bt819_write(decoder, reg, *data++);
131 if (ret < 0)
132 break;
133 len -= 2;
134 }
135 }
136
137 return ret;
138 }
139
bt819_read(struct bt819 * decoder,u8 reg)140 static inline int bt819_read(struct bt819 *decoder, u8 reg)
141 {
142 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
143
144 return i2c_smbus_read_byte_data(client, reg);
145 }
146
bt819_init(struct v4l2_subdev * sd)147 static int bt819_init(struct v4l2_subdev *sd)
148 {
149 static unsigned char init[] = {
150 /*0x1f, 0x00,*/ /* Reset */
151 0x01, 0x59, /* 0x01 input format */
152 0x02, 0x00, /* 0x02 temporal decimation */
153 0x03, 0x12, /* 0x03 Cropping msb */
154 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
155 0x05, 0xe0, /* 0x05 Vertical Active lsb */
156 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
157 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
158 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
159 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
160 0x0a, 0x00, /* 0x0a Brightness control */
161 0x0b, 0x30, /* 0x0b Miscellaneous control */
162 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
163 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
164 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
165 0x0f, 0x00, /* 0x0f Hue control */
166 0x12, 0x04, /* 0x12 Output Format */
167 0x13, 0x20, /* 0x13 Vertial Scaling msb 0x00
168 chroma comb OFF, line drop scaling, interlace scaling
169 BUG? Why does turning the chroma comb on fuck up color?
170 Bug in the bt819 stepping on my board?
171 */
172 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
173 0x16, 0x07, /* 0x16 Video Timing Polarity
174 ACTIVE=active low
175 FIELD: high=odd,
176 vreset=active high,
177 hreset=active high */
178 0x18, 0x68, /* 0x18 AGC Delay */
179 0x19, 0x5d, /* 0x19 Burst Gate Delay */
180 0x1a, 0x80, /* 0x1a ADC Interface */
181 };
182
183 struct bt819 *decoder = to_bt819(sd);
184 struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
185
186 init[0x03 * 2 - 1] =
187 (((timing->vdelay >> 8) & 0x03) << 6) |
188 (((timing->vactive >> 8) & 0x03) << 4) |
189 (((timing->hdelay >> 8) & 0x03) << 2) |
190 ((timing->hactive >> 8) & 0x03);
191 init[0x04 * 2 - 1] = timing->vdelay & 0xff;
192 init[0x05 * 2 - 1] = timing->vactive & 0xff;
193 init[0x06 * 2 - 1] = timing->hdelay & 0xff;
194 init[0x07 * 2 - 1] = timing->hactive & 0xff;
195 init[0x08 * 2 - 1] = timing->hscale >> 8;
196 init[0x09 * 2 - 1] = timing->hscale & 0xff;
197 /* 0x15 in array is address 0x19 */
198 init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */
199 /* reset */
200 bt819_write(decoder, 0x1f, 0x00);
201 mdelay(1);
202
203 /* init */
204 return bt819_write_block(decoder, init, sizeof(init));
205 }
206
207 /* ----------------------------------------------------------------------- */
208
bt819_status(struct v4l2_subdev * sd,u32 * pstatus,v4l2_std_id * pstd)209 static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
210 {
211 struct bt819 *decoder = to_bt819(sd);
212 int status = bt819_read(decoder, 0x00);
213 int res = V4L2_IN_ST_NO_SIGNAL;
214 v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
215
216 if ((status & 0x80))
217 res = 0;
218 else
219 std = V4L2_STD_UNKNOWN;
220
221 if ((status & 0x10))
222 std &= V4L2_STD_PAL;
223 else
224 std &= V4L2_STD_NTSC;
225 if (pstd)
226 *pstd = std;
227 if (pstatus)
228 *pstatus = res;
229
230 v4l2_dbg(1, debug, sd, "get status %x\n", status);
231 return 0;
232 }
233
bt819_querystd(struct v4l2_subdev * sd,v4l2_std_id * std)234 static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
235 {
236 return bt819_status(sd, NULL, std);
237 }
238
bt819_g_input_status(struct v4l2_subdev * sd,u32 * status)239 static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
240 {
241 return bt819_status(sd, status, NULL);
242 }
243
bt819_s_std(struct v4l2_subdev * sd,v4l2_std_id std)244 static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
245 {
246 struct bt819 *decoder = to_bt819(sd);
247 struct timing *timing = NULL;
248
249 v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
250
251 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
252 v4l2_err(sd, "no notify found!\n");
253
254 if (std & V4L2_STD_NTSC) {
255 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
256 bt819_setbit(decoder, 0x01, 0, 1);
257 bt819_setbit(decoder, 0x01, 1, 0);
258 bt819_setbit(decoder, 0x01, 5, 0);
259 bt819_write(decoder, 0x18, 0x68);
260 bt819_write(decoder, 0x19, 0x5d);
261 /* bt819_setbit(decoder, 0x1a, 5, 1); */
262 timing = &timing_data[1];
263 } else if (std & V4L2_STD_PAL) {
264 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
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];
272 } else {
273 v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
274 (unsigned long long)std);
275 return -EINVAL;
276 }
277 bt819_write(decoder, 0x03,
278 (((timing->vdelay >> 8) & 0x03) << 6) |
279 (((timing->vactive >> 8) & 0x03) << 4) |
280 (((timing->hdelay >> 8) & 0x03) << 2) |
281 ((timing->hactive >> 8) & 0x03));
282 bt819_write(decoder, 0x04, timing->vdelay & 0xff);
283 bt819_write(decoder, 0x05, timing->vactive & 0xff);
284 bt819_write(decoder, 0x06, timing->hdelay & 0xff);
285 bt819_write(decoder, 0x07, timing->hactive & 0xff);
286 bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
287 bt819_write(decoder, 0x09, timing->hscale & 0xff);
288 decoder->norm = std;
289 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
290 return 0;
291 }
292
bt819_s_routing(struct v4l2_subdev * sd,u32 input,u32 output,u32 config)293 static int bt819_s_routing(struct v4l2_subdev *sd,
294 u32 input, u32 output, u32 config)
295 {
296 struct bt819 *decoder = to_bt819(sd);
297
298 v4l2_dbg(1, debug, sd, "set input %x\n", input);
299
300 if (input > 7)
301 return -EINVAL;
302
303 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
304 v4l2_err(sd, "no notify found!\n");
305
306 if (decoder->input != input) {
307 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
308 decoder->input = input;
309 /* select mode */
310 if (decoder->input == 0) {
311 bt819_setbit(decoder, 0x0b, 6, 0);
312 bt819_setbit(decoder, 0x1a, 1, 1);
313 } else {
314 bt819_setbit(decoder, 0x0b, 6, 1);
315 bt819_setbit(decoder, 0x1a, 1, 0);
316 }
317 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
318 }
319 return 0;
320 }
321
bt819_s_stream(struct v4l2_subdev * sd,int enable)322 static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
323 {
324 struct bt819 *decoder = to_bt819(sd);
325
326 v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
327
328 if (decoder->enable != enable) {
329 decoder->enable = enable;
330 bt819_setbit(decoder, 0x16, 7, !enable);
331 }
332 return 0;
333 }
334
bt819_s_ctrl(struct v4l2_ctrl * ctrl)335 static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
336 {
337 struct v4l2_subdev *sd = to_sd(ctrl);
338 struct bt819 *decoder = to_bt819(sd);
339 int temp;
340
341 switch (ctrl->id) {
342 case V4L2_CID_BRIGHTNESS:
343 bt819_write(decoder, 0x0a, ctrl->val);
344 break;
345
346 case V4L2_CID_CONTRAST:
347 bt819_write(decoder, 0x0c, ctrl->val & 0xff);
348 bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
349 break;
350
351 case V4L2_CID_SATURATION:
352 bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
353 bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
354
355 /* Ratio between U gain and V gain must stay the same as
356 the ratio between the default U and V gain values. */
357 temp = (ctrl->val * 180) / 254;
358 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
359 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
360 break;
361
362 case V4L2_CID_HUE:
363 bt819_write(decoder, 0x0f, ctrl->val);
364 break;
365
366 default:
367 return -EINVAL;
368 }
369 return 0;
370 }
371
372 /* ----------------------------------------------------------------------- */
373
374 static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
375 .s_ctrl = bt819_s_ctrl,
376 };
377
378 static const struct v4l2_subdev_video_ops bt819_video_ops = {
379 .s_std = bt819_s_std,
380 .s_routing = bt819_s_routing,
381 .s_stream = bt819_s_stream,
382 .querystd = bt819_querystd,
383 .g_input_status = bt819_g_input_status,
384 };
385
386 static const struct v4l2_subdev_ops bt819_ops = {
387 .video = &bt819_video_ops,
388 };
389
390 /* ----------------------------------------------------------------------- */
391
bt819_probe(struct i2c_client * client,const struct i2c_device_id * id)392 static int bt819_probe(struct i2c_client *client,
393 const struct i2c_device_id *id)
394 {
395 int i, ver;
396 struct bt819 *decoder;
397 struct v4l2_subdev *sd;
398 const char *name;
399
400 /* Check if the adapter supports the needed features */
401 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
402 return -ENODEV;
403
404 decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
405 if (decoder == NULL)
406 return -ENOMEM;
407 sd = &decoder->sd;
408 v4l2_i2c_subdev_init(sd, client, &bt819_ops);
409
410 ver = bt819_read(decoder, 0x17);
411 switch (ver & 0xf0) {
412 case 0x70:
413 name = "bt819a";
414 break;
415 case 0x60:
416 name = "bt817a";
417 break;
418 case 0x20:
419 name = "bt815a";
420 break;
421 default:
422 v4l2_dbg(1, debug, sd,
423 "unknown chip version 0x%02x\n", ver);
424 return -ENODEV;
425 }
426
427 v4l_info(client, "%s found @ 0x%x (%s)\n", name,
428 client->addr << 1, client->adapter->name);
429
430 decoder->norm = V4L2_STD_NTSC;
431 decoder->input = 0;
432 decoder->enable = 1;
433
434 i = bt819_init(sd);
435 if (i < 0)
436 v4l2_dbg(1, debug, sd, "init status %d\n", i);
437
438 v4l2_ctrl_handler_init(&decoder->hdl, 4);
439 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
440 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
441 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
442 V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
443 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
444 V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
445 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
446 V4L2_CID_HUE, -128, 127, 1, 0);
447 sd->ctrl_handler = &decoder->hdl;
448 if (decoder->hdl.error) {
449 int err = decoder->hdl.error;
450
451 v4l2_ctrl_handler_free(&decoder->hdl);
452 return err;
453 }
454 v4l2_ctrl_handler_setup(&decoder->hdl);
455 return 0;
456 }
457
bt819_remove(struct i2c_client * client)458 static int bt819_remove(struct i2c_client *client)
459 {
460 struct v4l2_subdev *sd = i2c_get_clientdata(client);
461 struct bt819 *decoder = to_bt819(sd);
462
463 v4l2_device_unregister_subdev(sd);
464 v4l2_ctrl_handler_free(&decoder->hdl);
465 return 0;
466 }
467
468 /* ----------------------------------------------------------------------- */
469
470 static const struct i2c_device_id bt819_id[] = {
471 { "bt819a", 0 },
472 { "bt817a", 0 },
473 { "bt815a", 0 },
474 { }
475 };
476 MODULE_DEVICE_TABLE(i2c, bt819_id);
477
478 static struct i2c_driver bt819_driver = {
479 .driver = {
480 .name = "bt819",
481 },
482 .probe = bt819_probe,
483 .remove = bt819_remove,
484 .id_table = bt819_id,
485 };
486
487 module_i2c_driver(bt819_driver);
488