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.
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>
38 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
39 MODULE_AUTHOR("Mike Bernson & Dave Perks");
40 MODULE_LICENSE("GPL");
43 module_param(debug
, int, 0);
44 MODULE_PARM_DESC(debug
, "Debug level (0-1)");
47 /* ----------------------------------------------------------------------- */
50 struct v4l2_subdev sd
;
51 struct v4l2_ctrl_handler hdl
;
52 unsigned char reg
[32];
59 static inline struct bt819
*to_bt819(struct v4l2_subdev
*sd
)
61 return container_of(sd
, struct bt819
, sd
);
64 static inline struct v4l2_subdev
*to_sd(struct v4l2_ctrl
*ctrl
)
66 return &container_of(ctrl
->handler
, struct bt819
, hdl
)->sd
;
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},
84 /* ----------------------------------------------------------------------- */
86 static inline int bt819_write(struct bt819
*decoder
, u8 reg
, u8 value
)
88 struct i2c_client
*client
= v4l2_get_subdevdata(&decoder
->sd
);
90 decoder
->reg
[reg
] = value
;
91 return i2c_smbus_write_byte_data(client
, reg
, value
);
94 static inline int bt819_setbit(struct bt819
*decoder
, u8 reg
, u8 bit
, u8 value
)
96 return bt819_write(decoder
, reg
,
97 (decoder
->reg
[reg
] & ~(1 << bit
)) | (value
? (1 << bit
) : 0));
100 static int bt819_write_block(struct bt819
*decoder
, const u8
*data
, unsigned int len
)
102 struct i2c_client
*client
= v4l2_get_subdevdata(&decoder
->sd
);
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 */
115 block_data
[block_len
++] = reg
= data
[0];
117 block_data
[block_len
++] =
118 decoder
->reg
[reg
++] = data
[1];
121 } while (len
>= 2 && data
[0] == reg
&& block_len
< 32);
122 ret
= i2c_master_send(client
, block_data
, block_len
);
127 /* do some slow I2C emulation kind of thing */
130 ret
= bt819_write(decoder
, reg
, *data
++);
140 static inline int bt819_read(struct bt819
*decoder
, u8 reg
)
142 struct i2c_client
*client
= v4l2_get_subdevdata(&decoder
->sd
);
144 return i2c_smbus_read_byte_data(client
, reg
);
147 static int bt819_init(struct v4l2_subdev
*sd
)
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?
172 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
173 0x16, 0x07, /* 0x16 Video Timing Polarity
177 hreset=active high */
178 0x18, 0x68, /* 0x18 AGC Delay */
179 0x19, 0x5d, /* 0x19 Burst Gate Delay */
180 0x1a, 0x80, /* 0x1a ADC Interface */
183 struct bt819
*decoder
= to_bt819(sd
);
184 struct timing
*timing
= &timing_data
[(decoder
->norm
& V4L2_STD_525_60
) ? 1 : 0];
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 */
200 bt819_write(decoder
, 0x1f, 0x00);
204 return bt819_write_block(decoder
, init
, sizeof(init
));
207 /* ----------------------------------------------------------------------- */
209 static int bt819_status(struct v4l2_subdev
*sd
, u32
*pstatus
, v4l2_std_id
*pstd
)
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
;
219 std
= V4L2_STD_UNKNOWN
;
224 std
&= V4L2_STD_NTSC
;
230 v4l2_dbg(1, debug
, sd
, "get status %x\n", status
);
234 static int bt819_querystd(struct v4l2_subdev
*sd
, v4l2_std_id
*std
)
236 return bt819_status(sd
, NULL
, std
);
239 static int bt819_g_input_status(struct v4l2_subdev
*sd
, u32
*status
)
241 return bt819_status(sd
, status
, NULL
);
244 static int bt819_s_std(struct v4l2_subdev
*sd
, v4l2_std_id std
)
246 struct bt819
*decoder
= to_bt819(sd
);
247 struct timing
*timing
= NULL
;
249 v4l2_dbg(1, debug
, sd
, "set norm %llx\n", (unsigned long long)std
);
251 if (sd
->v4l2_dev
== NULL
|| sd
->v4l2_dev
->notify
== NULL
)
252 v4l2_err(sd
, "no notify found!\n");
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];
273 v4l2_dbg(1, debug
, sd
, "unsupported norm %llx\n",
274 (unsigned long long)std
);
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);
289 v4l2_subdev_notify(sd
, BT819_FIFO_RESET_HIGH
, NULL
);
293 static int bt819_s_routing(struct v4l2_subdev
*sd
,
294 u32 input
, u32 output
, u32 config
)
296 struct bt819
*decoder
= to_bt819(sd
);
298 v4l2_dbg(1, debug
, sd
, "set input %x\n", input
);
303 if (sd
->v4l2_dev
== NULL
|| sd
->v4l2_dev
->notify
== NULL
)
304 v4l2_err(sd
, "no notify found!\n");
306 if (decoder
->input
!= input
) {
307 v4l2_subdev_notify(sd
, BT819_FIFO_RESET_LOW
, NULL
);
308 decoder
->input
= input
;
310 if (decoder
->input
== 0) {
311 bt819_setbit(decoder
, 0x0b, 6, 0);
312 bt819_setbit(decoder
, 0x1a, 1, 1);
314 bt819_setbit(decoder
, 0x0b, 6, 1);
315 bt819_setbit(decoder
, 0x1a, 1, 0);
317 v4l2_subdev_notify(sd
, BT819_FIFO_RESET_HIGH
, NULL
);
322 static int bt819_s_stream(struct v4l2_subdev
*sd
, int enable
)
324 struct bt819
*decoder
= to_bt819(sd
);
326 v4l2_dbg(1, debug
, sd
, "enable output %x\n", enable
);
328 if (decoder
->enable
!= enable
) {
329 decoder
->enable
= enable
;
330 bt819_setbit(decoder
, 0x16, 7, !enable
);
335 static int bt819_s_ctrl(struct v4l2_ctrl
*ctrl
)
337 struct v4l2_subdev
*sd
= to_sd(ctrl
);
338 struct bt819
*decoder
= to_bt819(sd
);
342 case V4L2_CID_BRIGHTNESS
:
343 bt819_write(decoder
, 0x0a, ctrl
->val
);
346 case V4L2_CID_CONTRAST
:
347 bt819_write(decoder
, 0x0c, ctrl
->val
& 0xff);
348 bt819_setbit(decoder
, 0x0b, 2, ((ctrl
->val
>> 8) & 0x01));
351 case V4L2_CID_SATURATION
:
352 bt819_write(decoder
, 0x0d, (ctrl
->val
>> 7) & 0xff);
353 bt819_setbit(decoder
, 0x0b, 1, ((ctrl
->val
>> 15) & 0x01));
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);
363 bt819_write(decoder
, 0x0f, ctrl
->val
);
372 /* ----------------------------------------------------------------------- */
374 static const struct v4l2_ctrl_ops bt819_ctrl_ops
= {
375 .s_ctrl
= bt819_s_ctrl
,
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
,
386 static const struct v4l2_subdev_ops bt819_ops
= {
387 .video
= &bt819_video_ops
,
390 /* ----------------------------------------------------------------------- */
392 static int bt819_probe(struct i2c_client
*client
,
393 const struct i2c_device_id
*id
)
396 struct bt819
*decoder
;
397 struct v4l2_subdev
*sd
;
400 /* Check if the adapter supports the needed features */
401 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_SMBUS_BYTE_DATA
))
404 decoder
= devm_kzalloc(&client
->dev
, sizeof(*decoder
), GFP_KERNEL
);
408 v4l2_i2c_subdev_init(sd
, client
, &bt819_ops
);
410 ver
= bt819_read(decoder
, 0x17);
411 switch (ver
& 0xf0) {
422 v4l2_dbg(1, debug
, sd
,
423 "unknown chip version 0x%02x\n", ver
);
427 v4l_info(client
, "%s found @ 0x%x (%s)\n", name
,
428 client
->addr
<< 1, client
->adapter
->name
);
430 decoder
->norm
= V4L2_STD_NTSC
;
436 v4l2_dbg(1, debug
, sd
, "init status %d\n", i
);
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
;
451 v4l2_ctrl_handler_free(&decoder
->hdl
);
454 v4l2_ctrl_handler_setup(&decoder
->hdl
);
458 static int bt819_remove(struct i2c_client
*client
)
460 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
461 struct bt819
*decoder
= to_bt819(sd
);
463 v4l2_device_unregister_subdev(sd
);
464 v4l2_ctrl_handler_free(&decoder
->hdl
);
468 /* ----------------------------------------------------------------------- */
470 static const struct i2c_device_id bt819_id
[] = {
476 MODULE_DEVICE_TABLE(i2c
, bt819_id
);
478 static struct i2c_driver bt819_driver
= {
482 .probe
= bt819_probe
,
483 .remove
= bt819_remove
,
484 .id_table
= bt819_id
,
487 module_i2c_driver(bt819_driver
);