1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 *  bt819 - BT819A VideoStream Decoder (Rockwell Part)
4 *
5 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
6 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
7 *
8 * Modifications for LML33/DC10plus unified driver
9 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
10 *
11 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
12 *    - moved over to linux>=2.4.x i2c protocol (9/9/2002)
13 *
14 * This code was modify/ported from the saa7111 driver written
15 * by Dave Perks.
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/* for values, see the bt819 datasheet */
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	/* 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 */
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		/* do some slow I2C emulation kind of thing */
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		/*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?
162					*/
163		0x14, 0x00,	/* 0x14 Vertical Scaling lsb */
164		0x16, 0x07,	/* 0x16 Video Timing Polarity
165					   ACTIVE=active low
166					   FIELD: high=odd,
167					   vreset=active high,
168					   hreset=active high */
169		0x18, 0x68,	/* 0x18 AGC Delay */
170		0x19, 0x5d,	/* 0x19 Burst Gate Delay */
171		0x1a, 0x80,	/* 0x1a ADC Interface */
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	/* 0x15 in array is address 0x19 */
189	init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93;	/* Chroma burst delay */
190	/* reset */
191	bt819_write(decoder, 0x1f, 0x00);
192	mdelay(1);
193
194	/* init */
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		/* 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];
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		/* select mode */
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		/* 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);
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{
385	int i, ver;
386	struct bt819 *decoder;
387	struct v4l2_subdev *sd;
388	const char *name;
389
390	/* Check if the adapter supports the needed features */
391	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
392		return -ENODEV;
393
394	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
395	if (decoder == NULL)
396		return -ENOMEM;
397	sd = &decoder->sd;
398	v4l2_i2c_subdev_init(sd, client, &bt819_ops);
399
400	ver = bt819_read(decoder, 0x17);
401	switch (ver & 0xf0) {
402	case 0x70:
403		name = "bt819a";
404		break;
405	case 0x60:
406		name = "bt817a";
407		break;
408	case 0x20:
409		name = "bt815a";
410		break;
411	default:
412		v4l2_dbg(1, debug, sd,
413			"unknown chip version 0x%02x\n", ver);
414		return -ENODEV;
415	}
416
417	v4l_info(client, "%s found @ 0x%x (%s)\n", name,
418			client->addr << 1, client->adapter->name);
419
420	decoder->norm = V4L2_STD_NTSC;
421	decoder->input = 0;
422	decoder->enable = 1;
423
424	i = bt819_init(sd);
425	if (i < 0)
426		v4l2_dbg(1, debug, sd, "init status %d\n", i);
427
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;
440
441		v4l2_ctrl_handler_free(&decoder->hdl);
442		return err;
443	}
444	v4l2_ctrl_handler_setup(&decoder->hdl);
445	return 0;
446}
447
448static void bt819_remove(struct i2c_client *client)
449{
450	struct v4l2_subdev *sd = i2c_get_clientdata(client);
451	struct bt819 *decoder = to_bt819(sd);
452
453	v4l2_device_unregister_subdev(sd);
454	v4l2_ctrl_handler_free(&decoder->hdl);
455}
456
457/* ----------------------------------------------------------------------- */
458
459static const struct i2c_device_id bt819_id[] = {
460	{ "bt819a", 0 },
461	{ "bt817a", 0 },
462	{ "bt815a", 0 },
463	{ }
464};
465MODULE_DEVICE_TABLE(i2c, bt819_id);
466
467static struct i2c_driver bt819_driver = {
468	.driver = {
469		.name	= "bt819",
470	},
471	.probe		= bt819_probe,
472	.remove		= bt819_remove,
473	.id_table	= bt819_id,
474};
475
476module_i2c_driver(bt819_driver);
477