]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/i2c/bt819.c
Merge branches 'for-4.11/upstream-fixes', 'for-4.12/accutouch', 'for-4.12/cp2112...
[mirror_ubuntu-artful-kernel.git] / drivers / media / i2c / bt819.c
CommitLineData
d56410e0 1/*
1da177e4
LT
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>
d56410e0 9 *
1da177e4
LT
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.
1da177e4
LT
25 */
26
27#include <linux/module.h>
18f3fa1e 28#include <linux/types.h>
7fd011fb 29#include <linux/ioctl.h>
2883913c 30#include <linux/delay.h>
7fd011fb 31#include <linux/i2c.h>
c2179ad8 32#include <linux/videodev2.h>
5a0e3ad6 33#include <linux/slab.h>
c2179ad8 34#include <media/v4l2-device.h>
bd84a65a 35#include <media/v4l2-ctrls.h>
b5dcee22 36#include <media/i2c/bt819.h>
1da177e4
LT
37
38MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
39MODULE_AUTHOR("Mike Bernson & Dave Perks");
40MODULE_LICENSE("GPL");
41
ff699e6b 42static int debug;
1da177e4
LT
43module_param(debug, int, 0);
44MODULE_PARM_DESC(debug, "Debug level (0-1)");
45
c2179ad8 46
1da177e4
LT
47/* ----------------------------------------------------------------------- */
48
49struct bt819 {
c2179ad8 50 struct v4l2_subdev sd;
bd84a65a 51 struct v4l2_ctrl_handler hdl;
1da177e4
LT
52 unsigned char reg[32];
53
107063c6 54 v4l2_std_id norm;
1da177e4
LT
55 int input;
56 int enable;
1da177e4
LT
57};
58
c2179ad8
HV
59static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
60{
61 return container_of(sd, struct bt819, sd);
62}
63
bd84a65a
HV
64static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
65{
66 return &container_of(ctrl->handler, struct bt819, hdl)->sd;
67}
68
1da177e4
LT
69struct 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 */
79static struct timing timing_data[] = {
80 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
81 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
82};
83
1da177e4
LT
84/* ----------------------------------------------------------------------- */
85
c2179ad8 86static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
1da177e4 87{
c2179ad8 88 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
1da177e4
LT
89
90 decoder->reg[reg] = value;
91 return i2c_smbus_write_byte_data(client, reg, value);
92}
93
c2179ad8 94static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
1da177e4 95{
c2179ad8 96 return bt819_write(decoder, reg,
7fd011fb 97 (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
1da177e4
LT
98}
99
c2179ad8 100static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
1da177e4 101{
c2179ad8 102 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
1da177e4
LT
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 */
1da177e4 110 u8 block_data[32];
9aa45e34 111 int block_len;
1da177e4 112
1da177e4 113 while (len >= 2) {
9aa45e34
JD
114 block_len = 0;
115 block_data[block_len++] = reg = data[0];
1da177e4 116 do {
9aa45e34 117 block_data[block_len++] =
1da177e4
LT
118 decoder->reg[reg++] = data[1];
119 len -= 2;
120 data += 2;
7fd011fb
HV
121 } while (len >= 2 && data[0] == reg && block_len < 32);
122 ret = i2c_master_send(client, block_data, block_len);
123 if (ret < 0)
1da177e4
LT
124 break;
125 }
126 } else {
127 /* do some slow I2C emulation kind of thing */
128 while (len >= 2) {
129 reg = *data++;
c2179ad8
HV
130 ret = bt819_write(decoder, reg, *data++);
131 if (ret < 0)
1da177e4
LT
132 break;
133 len -= 2;
134 }
135 }
136
137 return ret;
138}
139
c2179ad8 140static inline int bt819_read(struct bt819 *decoder, u8 reg)
1da177e4 141{
c2179ad8
HV
142 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
143
1da177e4
LT
144 return i2c_smbus_read_byte_data(client, reg);
145}
146
c2179ad8 147static int bt819_init(struct v4l2_subdev *sd)
1da177e4 148{
1da177e4 149 static unsigned char init[] = {
7fd011fb 150 /*0x1f, 0x00,*/ /* Reset */
1da177e4
LT
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 */
d56410e0 173 0x16, 0x07, /* 0x16 Video Timing Polarity
1da177e4 174 ACTIVE=active low
d56410e0 175 FIELD: high=odd,
1da177e4
LT
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
c2179ad8 183 struct bt819 *decoder = to_bt819(sd);
107063c6 184 struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
1da177e4
LT
185
186 init[0x03 * 2 - 1] =
7fd011fb
HV
187 (((timing->vdelay >> 8) & 0x03) << 6) |
188 (((timing->vactive >> 8) & 0x03) << 4) |
189 (((timing->hdelay >> 8) & 0x03) << 2) |
190 ((timing->hactive >> 8) & 0x03);
1da177e4
LT
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 */
107063c6 198 init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */
1da177e4 199 /* reset */
c2179ad8 200 bt819_write(decoder, 0x1f, 0x00);
1da177e4
LT
201 mdelay(1);
202
203 /* init */
c2179ad8 204 return bt819_write_block(decoder, init, sizeof(init));
1da177e4
LT
205}
206
207/* ----------------------------------------------------------------------- */
208
c2179ad8 209static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
1da177e4 210{
c2179ad8
HV
211 struct bt819 *decoder = to_bt819(sd);
212 int status = bt819_read(decoder, 0x00);
213 int res = V4L2_IN_ST_NO_SIGNAL;
ddc7f72a 214 v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
c2179ad8
HV
215
216 if ((status & 0x80))
217 res = 0;
ddc7f72a
HV
218 else
219 std = V4L2_STD_UNKNOWN;
c2179ad8
HV
220
221 if ((status & 0x10))
ddc7f72a 222 std &= V4L2_STD_PAL;
c2179ad8 223 else
ddc7f72a 224 std &= V4L2_STD_NTSC;
c2179ad8
HV
225 if (pstd)
226 *pstd = std;
227 if (pstatus)
ba08831b 228 *pstatus = res;
c2179ad8
HV
229
230 v4l2_dbg(1, debug, sd, "get status %x\n", status);
231 return 0;
232}
1da177e4 233
c2179ad8
HV
234static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
235{
236 return bt819_status(sd, NULL, std);
237}
1da177e4 238
c2179ad8
HV
239static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
240{
241 return bt819_status(sd, status, NULL);
242}
243
244static 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
cc5cef8e 249 v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
c2179ad8 250
1cd3c0fa
HV
251 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
252 v4l2_err(sd, "no notify found!\n");
253
c2179ad8 254 if (std & V4L2_STD_NTSC) {
b9fb9b79 255 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
c2179ad8
HV
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) {
b9fb9b79 264 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
c2179ad8
HV
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 {
cc5cef8e
HV
273 v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
274 (unsigned long long)std);
c2179ad8 275 return -EINVAL;
1da177e4 276 }
c2179ad8
HV
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;
b9fb9b79 289 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
c2179ad8
HV
290 return 0;
291}
1da177e4 292
5325b427
HV
293static int bt819_s_routing(struct v4l2_subdev *sd,
294 u32 input, u32 output, u32 config)
c2179ad8
HV
295{
296 struct bt819 *decoder = to_bt819(sd);
1da177e4 297
5325b427 298 v4l2_dbg(1, debug, sd, "set input %x\n", input);
1da177e4 299
f14a2972 300 if (input > 7)
c2179ad8 301 return -EINVAL;
1da177e4 302
1cd3c0fa
HV
303 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
304 v4l2_err(sd, "no notify found!\n");
305
5325b427 306 if (decoder->input != input) {
b9fb9b79 307 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
5325b427 308 decoder->input = input;
c2179ad8
HV
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);
1da177e4 316 }
b9fb9b79 317 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
7fd011fb 318 }
c2179ad8
HV
319 return 0;
320}
1da177e4 321
c2179ad8
HV
322static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
323{
324 struct bt819 *decoder = to_bt819(sd);
1da177e4 325
c2179ad8 326 v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
1da177e4 327
c2179ad8
HV
328 if (decoder->enable != enable) {
329 decoder->enable = enable;
330 bt819_setbit(decoder, 0x16, 7, !enable);
7fd011fb 331 }
c2179ad8
HV
332 return 0;
333}
1da177e4 334
bd84a65a 335static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
c2179ad8 336{
bd84a65a 337 struct v4l2_subdev *sd = to_sd(ctrl);
c2179ad8
HV
338 struct bt819 *decoder = to_bt819(sd);
339 int temp;
1da177e4 340
c2179ad8
HV
341 switch (ctrl->id) {
342 case V4L2_CID_BRIGHTNESS:
bd84a65a 343 bt819_write(decoder, 0x0a, ctrl->val);
c2179ad8 344 break;
1da177e4 345
c2179ad8 346 case V4L2_CID_CONTRAST:
bd84a65a
HV
347 bt819_write(decoder, 0x0c, ctrl->val & 0xff);
348 bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
c2179ad8 349 break;
1da177e4 350
c2179ad8 351 case V4L2_CID_SATURATION:
bd84a65a
HV
352 bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
353 bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
c2179ad8
HV
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. */
bd84a65a 357 temp = (ctrl->val * 180) / 254;
c2179ad8
HV
358 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
359 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
360 break;
1da177e4 361
c2179ad8 362 case V4L2_CID_HUE:
bd84a65a 363 bt819_write(decoder, 0x0f, ctrl->val);
107063c6 364 break;
c2179ad8
HV
365
366 default:
367 return -EINVAL;
107063c6 368 }
c2179ad8
HV
369 return 0;
370}
1da177e4 371
1da177e4
LT
372/* ----------------------------------------------------------------------- */
373
bd84a65a
HV
374static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
375 .s_ctrl = bt819_s_ctrl,
376};
377
c2179ad8 378static const struct v4l2_subdev_video_ops bt819_video_ops = {
8774bed9 379 .s_std = bt819_s_std,
c2179ad8
HV
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
386static const struct v4l2_subdev_ops bt819_ops = {
c2179ad8
HV
387 .video = &bt819_video_ops,
388};
389
390/* ----------------------------------------------------------------------- */
1da177e4 391
7fd011fb
HV
392static int bt819_probe(struct i2c_client *client,
393 const struct i2c_device_id *id)
1da177e4 394{
7fd011fb 395 int i, ver;
1da177e4 396 struct bt819 *decoder;
c2179ad8 397 struct v4l2_subdev *sd;
7fd011fb 398 const char *name;
1da177e4
LT
399
400 /* Check if the adapter supports the needed features */
7fd011fb
HV
401 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
402 return -ENODEV;
1da177e4 403
c02b211d 404 decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
c2179ad8
HV
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);
7fd011fb
HV
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:
c2179ad8 422 v4l2_dbg(1, debug, sd,
7fd011fb
HV
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);
1da177e4 429
107063c6 430 decoder->norm = V4L2_STD_NTSC;
1da177e4
LT
431 decoder->input = 0;
432 decoder->enable = 1;
1da177e4 433
c2179ad8 434 i = bt819_init(sd);
7fd011fb 435 if (i < 0)
c2179ad8 436 v4l2_dbg(1, debug, sd, "init status %d\n", i);
bd84a65a
HV
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);
bd84a65a
HV
452 return err;
453 }
454 v4l2_ctrl_handler_setup(&decoder->hdl);
1da177e4
LT
455 return 0;
456}
457
7fd011fb 458static int bt819_remove(struct i2c_client *client)
1da177e4 459{
c2179ad8 460 struct v4l2_subdev *sd = i2c_get_clientdata(client);
bd84a65a 461 struct bt819 *decoder = to_bt819(sd);
c2179ad8
HV
462
463 v4l2_device_unregister_subdev(sd);
bd84a65a 464 v4l2_ctrl_handler_free(&decoder->hdl);
1da177e4
LT
465 return 0;
466}
467
468/* ----------------------------------------------------------------------- */
469
7fd011fb
HV
470static const struct i2c_device_id bt819_id[] = {
471 { "bt819a", 0 },
472 { "bt817a", 0 },
473 { "bt815a", 0 },
474 { }
475};
476MODULE_DEVICE_TABLE(i2c, bt819_id);
1da177e4 477
00cc8db8
HV
478static struct i2c_driver bt819_driver = {
479 .driver = {
00cc8db8
HV
480 .name = "bt819",
481 },
482 .probe = bt819_probe,
483 .remove = bt819_remove,
484 .id_table = bt819_id,
1da177e4 485};
00cc8db8 486
c6e8d86f 487module_i2c_driver(bt819_driver);