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