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