1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * bt819 - BT819A VideoStream Decoder (Rockwell Part)
5 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
6 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
8 * Modifications for LML33/DC10plus unified driver
9 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
11 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
12 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
14 * This code was modify/ported from the saa7111 driver written
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>
29 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
30 MODULE_AUTHOR("Mike Bernson & Dave Perks");
31 MODULE_LICENSE("GPL");
34 module_param(debug, int, 0);
35 MODULE_PARM_DESC(debug, "Debug level (0-1)");
38 /* ----------------------------------------------------------------------- */
41 struct v4l2_subdev sd;
42 struct v4l2_ctrl_handler hdl;
43 unsigned char reg[32];
50 static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
52 return container_of(sd, struct bt819, sd);
55 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
57 return &container_of(ctrl->handler, struct bt819, hdl)->sd;
69 /* for values, see the bt819 datasheet */
70 static struct timing timing_data[] = {
71 {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
72 {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
75 /* ----------------------------------------------------------------------- */
77 static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
79 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
81 decoder->reg[reg] = value;
82 return i2c_smbus_write_byte_data(client, reg, value);
85 static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
87 return bt819_write(decoder, reg,
88 (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
91 static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
93 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
97 /* the bt819 has an autoincrement function, use it if
98 * the adapter understands raw I2C */
99 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
100 /* do raw I2C, not smbus compatible */
106 block_data[block_len++] = reg = data[0];
108 block_data[block_len++] =
109 decoder->reg[reg++] = data[1];
112 } while (len >= 2 && data[0] == reg && block_len < 32);
113 ret = i2c_master_send(client, block_data, block_len);
118 /* do some slow I2C emulation kind of thing */
121 ret = bt819_write(decoder, reg, *data++);
131 static inline int bt819_read(struct bt819 *decoder, u8 reg)
133 struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
135 return i2c_smbus_read_byte_data(client, reg);
138 static int bt819_init(struct v4l2_subdev *sd)
140 static unsigned char init[] = {
141 /*0x1f, 0x00,*/ /* Reset */
142 0x01, 0x59, /* 0x01 input format */
143 0x02, 0x00, /* 0x02 temporal decimation */
144 0x03, 0x12, /* 0x03 Cropping msb */
145 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
146 0x05, 0xe0, /* 0x05 Vertical Active lsb */
147 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
148 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
149 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
150 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
151 0x0a, 0x00, /* 0x0a Brightness control */
152 0x0b, 0x30, /* 0x0b Miscellaneous control */
153 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
154 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
155 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
156 0x0f, 0x00, /* 0x0f Hue control */
157 0x12, 0x04, /* 0x12 Output Format */
158 0x13, 0x20, /* 0x13 Vertical Scaling msb 0x00
159 chroma comb OFF, line drop scaling, interlace scaling
160 BUG? Why does turning the chroma comb on screw up color?
161 Bug in the bt819 stepping on my board?
163 0x14, 0x00, /* 0x14 Vertical Scaling lsb */
164 0x16, 0x07, /* 0x16 Video Timing Polarity
168 hreset=active high */
169 0x18, 0x68, /* 0x18 AGC Delay */
170 0x19, 0x5d, /* 0x19 Burst Gate Delay */
171 0x1a, 0x80, /* 0x1a ADC Interface */
174 struct bt819 *decoder = to_bt819(sd);
175 struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
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 /* 0x15 in array is address 0x19 */
189 init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */
191 bt819_write(decoder, 0x1f, 0x00);
195 return bt819_write_block(decoder, init, sizeof(init));
198 /* ----------------------------------------------------------------------- */
200 static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
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;
210 std = V4L2_STD_UNKNOWN;
215 std &= V4L2_STD_NTSC;
221 v4l2_dbg(1, debug, sd, "get status %x\n", status);
225 static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
227 return bt819_status(sd, NULL, std);
230 static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
232 return bt819_status(sd, status, NULL);
235 static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
237 struct bt819 *decoder = to_bt819(sd);
238 struct timing *timing = NULL;
240 v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
242 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
243 v4l2_err(sd, "no notify found!\n");
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 /* bt819_setbit(decoder, 0x1a, 5, 1); */
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 /* bt819_setbit(decoder, 0x1a, 5, 0); */
262 timing = &timing_data[0];
264 v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
265 (unsigned long long)std);
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);
280 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
284 static int bt819_s_routing(struct v4l2_subdev *sd,
285 u32 input, u32 output, u32 config)
287 struct bt819 *decoder = to_bt819(sd);
289 v4l2_dbg(1, debug, sd, "set input %x\n", input);
294 if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
295 v4l2_err(sd, "no notify found!\n");
297 if (decoder->input != input) {
298 v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
299 decoder->input = input;
301 if (decoder->input == 0) {
302 bt819_setbit(decoder, 0x0b, 6, 0);
303 bt819_setbit(decoder, 0x1a, 1, 1);
305 bt819_setbit(decoder, 0x0b, 6, 1);
306 bt819_setbit(decoder, 0x1a, 1, 0);
308 v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
313 static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
315 struct bt819 *decoder = to_bt819(sd);
317 v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
319 if (decoder->enable != enable) {
320 decoder->enable = enable;
321 bt819_setbit(decoder, 0x16, 7, !enable);
326 static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
328 struct v4l2_subdev *sd = to_sd(ctrl);
329 struct bt819 *decoder = to_bt819(sd);
333 case V4L2_CID_BRIGHTNESS:
334 bt819_write(decoder, 0x0a, ctrl->val);
337 case V4L2_CID_CONTRAST:
338 bt819_write(decoder, 0x0c, ctrl->val & 0xff);
339 bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
342 case V4L2_CID_SATURATION:
343 bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
344 bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
346 /* Ratio between U gain and V gain must stay the same as
347 the ratio between the default U and V gain values. */
348 temp = (ctrl->val * 180) / 254;
349 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
350 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
354 bt819_write(decoder, 0x0f, ctrl->val);
363 /* ----------------------------------------------------------------------- */
365 static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
366 .s_ctrl = bt819_s_ctrl,
369 static 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,
377 static const struct v4l2_subdev_ops bt819_ops = {
378 .video = &bt819_video_ops,
381 /* ----------------------------------------------------------------------- */
383 static int bt819_probe(struct i2c_client *client)
386 struct bt819 *decoder;
387 struct v4l2_subdev *sd;
390 /* Check if the adapter supports the needed features */
391 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
394 decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
398 v4l2_i2c_subdev_init(sd, client, &bt819_ops);
400 ver = bt819_read(decoder, 0x17);
401 switch (ver & 0xf0) {
412 v4l2_dbg(1, debug, sd,
413 "unknown chip version 0x%02x\n", ver);
417 v4l_info(client, "%s found @ 0x%x (%s)\n", name,
418 client->addr << 1, client->adapter->name);
420 decoder->norm = V4L2_STD_NTSC;
426 v4l2_dbg(1, debug, sd, "init status %d\n", i);
428 v4l2_ctrl_handler_init(&decoder->hdl, 4);
429 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
430 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
431 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
432 V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
433 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
434 V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
435 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
436 V4L2_CID_HUE, -128, 127, 1, 0);
437 sd->ctrl_handler = &decoder->hdl;
438 if (decoder->hdl.error) {
439 int err = decoder->hdl.error;
441 v4l2_ctrl_handler_free(&decoder->hdl);
444 v4l2_ctrl_handler_setup(&decoder->hdl);
448 static void bt819_remove(struct i2c_client *client)
450 struct v4l2_subdev *sd = i2c_get_clientdata(client);
451 struct bt819 *decoder = to_bt819(sd);
453 v4l2_device_unregister_subdev(sd);
454 v4l2_ctrl_handler_free(&decoder->hdl);
457 /* ----------------------------------------------------------------------- */
459 static const struct i2c_device_id bt819_id[] = {
465 MODULE_DEVICE_TABLE(i2c, bt819_id);
467 static struct i2c_driver bt819_driver = {
471 .probe = bt819_probe,
472 .remove = bt819_remove,
473 .id_table = bt819_id,
476 module_i2c_driver(bt819_driver);