xref: /linux/drivers/media/i2c/tw9910.c (revision c297aa7d3fb6755890b78b483e82c9cf07370d50)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * tw9910 Video Driver
4  *
5  * Copyright (C) 2017 Jacopo Mondi <jacopo+renesas@jmondi.org>
6  *
7  * Copyright (C) 2008 Renesas Solutions Corp.
8  * Kuninori Morimoto <morimoto.kuninori@renesas.com>
9  *
10  * Based on ov772x driver,
11  *
12  * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
13  * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
14  * Copyright (C) 2008 Magnus Damm
15  * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
16  */
17 
18 #include <linux/clk.h>
19 #include <linux/delay.h>
20 #include <linux/gpio/consumer.h>
21 #include <linux/i2c.h>
22 #include <linux/init.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/slab.h>
26 #include <linux/v4l2-mediabus.h>
27 #include <linux/videodev2.h>
28 
29 #include <media/i2c/tw9910.h>
30 #include <media/v4l2-subdev.h>
31 
32 #define GET_ID(val)  ((val & 0xF8) >> 3)
33 #define GET_REV(val) (val & 0x07)
34 
35 /*
36  * register offset
37  */
38 #define ID		0x00 /* Product ID Code Register */
39 #define STATUS1		0x01 /* Chip Status Register I */
40 #define INFORM		0x02 /* Input Format */
41 #define OPFORM		0x03 /* Output Format Control Register */
42 #define DLYCTR		0x04 /* Hysteresis and HSYNC Delay Control */
43 #define OUTCTR1		0x05 /* Output Control I */
44 #define ACNTL1		0x06 /* Analog Control Register 1 */
45 #define CROP_HI		0x07 /* Cropping Register, High */
46 #define VDELAY_LO	0x08 /* Vertical Delay Register, Low */
47 #define VACTIVE_LO	0x09 /* Vertical Active Register, Low */
48 #define HDELAY_LO	0x0A /* Horizontal Delay Register, Low */
49 #define HACTIVE_LO	0x0B /* Horizontal Active Register, Low */
50 #define CNTRL1		0x0C /* Control Register I */
51 #define VSCALE_LO	0x0D /* Vertical Scaling Register, Low */
52 #define SCALE_HI	0x0E /* Scaling Register, High */
53 #define HSCALE_LO	0x0F /* Horizontal Scaling Register, Low */
54 #define BRIGHT		0x10 /* BRIGHTNESS Control Register */
55 #define CONTRAST	0x11 /* CONTRAST Control Register */
56 #define SHARPNESS	0x12 /* SHARPNESS Control Register I */
57 #define SAT_U		0x13 /* Chroma (U) Gain Register */
58 #define SAT_V		0x14 /* Chroma (V) Gain Register */
59 #define HUE		0x15 /* Hue Control Register */
60 #define CORING1		0x17
61 #define CORING2		0x18 /* Coring and IF compensation */
62 #define VBICNTL		0x19 /* VBI Control Register */
63 #define ACNTL2		0x1A /* Analog Control 2 */
64 #define OUTCTR2		0x1B /* Output Control 2 */
65 #define SDT		0x1C /* Standard Selection */
66 #define SDTR		0x1D /* Standard Recognition */
67 #define TEST		0x1F /* Test Control Register */
68 #define CLMPG		0x20 /* Clamping Gain */
69 #define IAGC		0x21 /* Individual AGC Gain */
70 #define AGCGAIN		0x22 /* AGC Gain */
71 #define PEAKWT		0x23 /* White Peak Threshold */
72 #define CLMPL		0x24 /* Clamp level */
73 #define SYNCT		0x25 /* Sync Amplitude */
74 #define MISSCNT		0x26 /* Sync Miss Count Register */
75 #define PCLAMP		0x27 /* Clamp Position Register */
76 #define VCNTL1		0x28 /* Vertical Control I */
77 #define VCNTL2		0x29 /* Vertical Control II */
78 #define CKILL		0x2A /* Color Killer Level Control */
79 #define COMB		0x2B /* Comb Filter Control */
80 #define LDLY		0x2C /* Luma Delay and H Filter Control */
81 #define MISC1		0x2D /* Miscellaneous Control I */
82 #define LOOP		0x2E /* LOOP Control Register */
83 #define MISC2		0x2F /* Miscellaneous Control II */
84 #define MVSN		0x30 /* Macrovision Detection */
85 #define STATUS2		0x31 /* Chip STATUS II */
86 #define HFREF		0x32 /* H monitor */
87 #define CLMD		0x33 /* CLAMP MODE */
88 #define IDCNTL		0x34 /* ID Detection Control */
89 #define CLCNTL1		0x35 /* Clamp Control I */
90 #define ANAPLLCTL	0x4C
91 #define VBIMIN		0x4D
92 #define HSLOWCTL	0x4E
93 #define WSS3		0x4F
94 #define FILLDATA	0x50
95 #define SDID		0x51
96 #define DID		0x52
97 #define WSS1		0x53
98 #define WSS2		0x54
99 #define VVBI		0x55
100 #define LCTL6		0x56
101 #define LCTL7		0x57
102 #define LCTL8		0x58
103 #define LCTL9		0x59
104 #define LCTL10		0x5A
105 #define LCTL11		0x5B
106 #define LCTL12		0x5C
107 #define LCTL13		0x5D
108 #define LCTL14		0x5E
109 #define LCTL15		0x5F
110 #define LCTL16		0x60
111 #define LCTL17		0x61
112 #define LCTL18		0x62
113 #define LCTL19		0x63
114 #define LCTL20		0x64
115 #define LCTL21		0x65
116 #define LCTL22		0x66
117 #define LCTL23		0x67
118 #define LCTL24		0x68
119 #define LCTL25		0x69
120 #define LCTL26		0x6A
121 #define HSBEGIN		0x6B
122 #define HSEND		0x6C
123 #define OVSDLY		0x6D
124 #define OVSEND		0x6E
125 #define VBIDELAY	0x6F
126 
127 /*
128  * register detail
129  */
130 
131 /* INFORM */
132 #define FC27_ON     0x40 /* 1 : Input crystal clock frequency is 27MHz */
133 #define FC27_FF     0x00 /* 0 : Square pixel mode. */
134 			 /*     Must use 24.54MHz for 60Hz field rate */
135 			 /*     source or 29.5MHz for 50Hz field rate */
136 #define IFSEL_S     0x10 /* 01 : S-video decoding */
137 #define IFSEL_C     0x00 /* 00 : Composite video decoding */
138 			 /* Y input video selection */
139 #define YSEL_M0     0x00 /*  00 : Mux0 selected */
140 #define YSEL_M1     0x04 /*  01 : Mux1 selected */
141 #define YSEL_M2     0x08 /*  10 : Mux2 selected */
142 #define YSEL_M3     0x10 /*  11 : Mux3 selected */
143 
144 /* OPFORM */
145 #define MODE        0x80 /* 0 : CCIR601 compatible YCrCb 4:2:2 format */
146 			 /* 1 : ITU-R-656 compatible data sequence format */
147 #define LEN         0x40 /* 0 : 8-bit YCrCb 4:2:2 output format */
148 			 /* 1 : 16-bit YCrCb 4:2:2 output format.*/
149 #define LLCMODE     0x20 /* 1 : LLC output mode. */
150 			 /* 0 : free-run output mode */
151 #define AINC        0x10 /* Serial interface auto-indexing control */
152 			 /* 0 : auto-increment */
153 			 /* 1 : non-auto */
154 #define VSCTL       0x08 /* 1 : Vertical out ctrl by DVALID */
155 			 /* 0 : Vertical out ctrl by HACTIVE and DVALID */
156 #define OEN_TRI_SEL_MASK	0x07
157 #define OEN_TRI_SEL_ALL_ON	0x00 /* Enable output for Rev0/Rev1 */
158 #define OEN_TRI_SEL_ALL_OFF_r0	0x06 /* All tri-stated for Rev0 */
159 #define OEN_TRI_SEL_ALL_OFF_r1	0x07 /* All tri-stated for Rev1 */
160 
161 /* OUTCTR1 */
162 #define VSP_LO      0x00 /* 0 : VS pin output polarity is active low */
163 #define VSP_HI      0x80 /* 1 : VS pin output polarity is active high. */
164 			 /* VS pin output control */
165 #define VSSL_VSYNC  0x00 /*   0 : VSYNC  */
166 #define VSSL_VACT   0x10 /*   1 : VACT   */
167 #define VSSL_FIELD  0x20 /*   2 : FIELD  */
168 #define VSSL_VVALID 0x30 /*   3 : VVALID */
169 #define VSSL_ZERO   0x70 /*   7 : 0      */
170 #define HSP_LOW     0x00 /* 0 : HS pin output polarity is active low */
171 #define HSP_HI      0x08 /* 1 : HS pin output polarity is active high.*/
172 			 /* HS pin output control */
173 #define HSSL_HACT   0x00 /*   0 : HACT   */
174 #define HSSL_HSYNC  0x01 /*   1 : HSYNC  */
175 #define HSSL_DVALID 0x02 /*   2 : DVALID */
176 #define HSSL_HLOCK  0x03 /*   3 : HLOCK  */
177 #define HSSL_ASYNCW 0x04 /*   4 : ASYNCW */
178 #define HSSL_ZERO   0x07 /*   7 : 0      */
179 
180 /* ACNTL1 */
181 #define SRESET      0x80 /* resets the device to its default state
182 			  * but all register content remain unchanged.
183 			  * This bit is self-resetting.
184 			  */
185 #define ACNTL1_PDN_MASK	0x0e
186 #define CLK_PDN		0x08 /* system clock power down */
187 #define Y_PDN		0x04 /* Luma ADC power down */
188 #define C_PDN		0x02 /* Chroma ADC power down */
189 
190 /* ACNTL2 */
191 #define ACNTL2_PDN_MASK	0x40
192 #define PLL_PDN		0x40 /* PLL power down */
193 
194 /* VBICNTL */
195 
196 /* RTSEL : control the real time signal output from the MPOUT pin */
197 #define RTSEL_MASK  0x07
198 #define RTSEL_VLOSS 0x00 /* 0000 = Video loss */
199 #define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
200 #define RTSEL_SLOCK 0x02 /* 0010 = S-lock */
201 #define RTSEL_VLOCK 0x03 /* 0011 = V-lock */
202 #define RTSEL_MONO  0x04 /* 0100 = MONO */
203 #define RTSEL_DET50 0x05 /* 0101 = DET50 */
204 #define RTSEL_FIELD 0x06 /* 0110 = FIELD */
205 #define RTSEL_RTCO  0x07 /* 0111 = RTCO ( Real Time Control ) */
206 
207 /* HSYNC start and end are constant for now */
208 #define HSYNC_START	0x0260
209 #define HSYNC_END	0x0300
210 
211 /*
212  * structure
213  */
214 
215 struct tw9910_scale_ctrl {
216 	char           *name;
217 	unsigned short  width;
218 	unsigned short  height;
219 	u16             hscale;
220 	u16             vscale;
221 };
222 
223 struct tw9910_priv {
224 	struct v4l2_subdev		subdev;
225 	struct clk			*clk;
226 	struct tw9910_video_info	*info;
227 	struct gpio_desc		*pdn_gpio;
228 	struct gpio_desc		*rstb_gpio;
229 	const struct tw9910_scale_ctrl	*scale;
230 	v4l2_std_id			norm;
231 	u32				revision;
232 };
233 
234 static const struct tw9910_scale_ctrl tw9910_ntsc_scales[] = {
235 	{
236 		.name   = "NTSC SQ",
237 		.width  = 640,
238 		.height = 480,
239 		.hscale = 0x0100,
240 		.vscale = 0x0100,
241 	},
242 	{
243 		.name   = "NTSC CCIR601",
244 		.width  = 720,
245 		.height = 480,
246 		.hscale = 0x0100,
247 		.vscale = 0x0100,
248 	},
249 	{
250 		.name   = "NTSC SQ (CIF)",
251 		.width  = 320,
252 		.height = 240,
253 		.hscale = 0x0200,
254 		.vscale = 0x0200,
255 	},
256 	{
257 		.name   = "NTSC CCIR601 (CIF)",
258 		.width  = 360,
259 		.height = 240,
260 		.hscale = 0x0200,
261 		.vscale = 0x0200,
262 	},
263 	{
264 		.name   = "NTSC SQ (QCIF)",
265 		.width  = 160,
266 		.height = 120,
267 		.hscale = 0x0400,
268 		.vscale = 0x0400,
269 	},
270 	{
271 		.name   = "NTSC CCIR601 (QCIF)",
272 		.width  = 180,
273 		.height = 120,
274 		.hscale = 0x0400,
275 		.vscale = 0x0400,
276 	},
277 };
278 
279 static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
280 	{
281 		.name   = "PAL SQ",
282 		.width  = 768,
283 		.height = 576,
284 		.hscale = 0x0100,
285 		.vscale = 0x0100,
286 	},
287 	{
288 		.name   = "PAL CCIR601",
289 		.width  = 720,
290 		.height = 576,
291 		.hscale = 0x0100,
292 		.vscale = 0x0100,
293 	},
294 	{
295 		.name   = "PAL SQ (CIF)",
296 		.width  = 384,
297 		.height = 288,
298 		.hscale = 0x0200,
299 		.vscale = 0x0200,
300 	},
301 	{
302 		.name   = "PAL CCIR601 (CIF)",
303 		.width  = 360,
304 		.height = 288,
305 		.hscale = 0x0200,
306 		.vscale = 0x0200,
307 	},
308 	{
309 		.name   = "PAL SQ (QCIF)",
310 		.width  = 192,
311 		.height = 144,
312 		.hscale = 0x0400,
313 		.vscale = 0x0400,
314 	},
315 	{
316 		.name   = "PAL CCIR601 (QCIF)",
317 		.width  = 180,
318 		.height = 144,
319 		.hscale = 0x0400,
320 		.vscale = 0x0400,
321 	},
322 };
323 
324 /*
325  * general function
326  */
327 static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
328 {
329 	return container_of(i2c_get_clientdata(client), struct tw9910_priv,
330 			    subdev);
331 }
332 
333 static int tw9910_mask_set(struct i2c_client *client, u8 command,
334 			   u8 mask, u8 set)
335 {
336 	s32 val = i2c_smbus_read_byte_data(client, command);
337 
338 	if (val < 0)
339 		return val;
340 
341 	val &= ~mask;
342 	val |= set & mask;
343 
344 	return i2c_smbus_write_byte_data(client, command, val);
345 }
346 
347 static int tw9910_set_scale(struct i2c_client *client,
348 			    const struct tw9910_scale_ctrl *scale)
349 {
350 	int ret;
351 
352 	ret = i2c_smbus_write_byte_data(client, SCALE_HI,
353 					(scale->vscale & 0x0F00) >> 4 |
354 					(scale->hscale & 0x0F00) >> 8);
355 	if (ret < 0)
356 		return ret;
357 
358 	ret = i2c_smbus_write_byte_data(client, HSCALE_LO,
359 					scale->hscale & 0x00FF);
360 	if (ret < 0)
361 		return ret;
362 
363 	ret = i2c_smbus_write_byte_data(client, VSCALE_LO,
364 					scale->vscale & 0x00FF);
365 
366 	return ret;
367 }
368 
369 static int tw9910_set_hsync(struct i2c_client *client)
370 {
371 	struct tw9910_priv *priv = to_tw9910(client);
372 	int ret;
373 
374 	/* bit 10 - 3 */
375 	ret = i2c_smbus_write_byte_data(client, HSBEGIN,
376 					(HSYNC_START & 0x07F8) >> 3);
377 	if (ret < 0)
378 		return ret;
379 
380 	/* bit 10 - 3 */
381 	ret = i2c_smbus_write_byte_data(client, HSEND,
382 					(HSYNC_END & 0x07F8) >> 3);
383 	if (ret < 0)
384 		return ret;
385 
386 	/* So far only revisions 0 and 1 have been seen. */
387 	/* bit 2 - 0 */
388 	if (priv->revision == 1)
389 		ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
390 				      (HSYNC_START & 0x0007) << 4 |
391 				      (HSYNC_END   & 0x0007));
392 
393 	return ret;
394 }
395 
396 static void tw9910_reset(struct i2c_client *client)
397 {
398 	tw9910_mask_set(client, ACNTL1, SRESET, SRESET);
399 	usleep_range(1000, 5000);
400 }
401 
402 static int tw9910_power(struct i2c_client *client, int enable)
403 {
404 	int ret;
405 	u8 acntl1;
406 	u8 acntl2;
407 
408 	if (enable) {
409 		acntl1 = 0;
410 		acntl2 = 0;
411 	} else {
412 		acntl1 = CLK_PDN | Y_PDN | C_PDN;
413 		acntl2 = PLL_PDN;
414 	}
415 
416 	ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1);
417 	if (ret < 0)
418 		return ret;
419 
420 	return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
421 }
422 
423 static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm,
424 							  u32 width, u32 height)
425 {
426 	const struct tw9910_scale_ctrl *scale;
427 	const struct tw9910_scale_ctrl *ret = NULL;
428 	__u32 diff = 0xffffffff, tmp;
429 	int size, i;
430 
431 	if (norm & V4L2_STD_NTSC) {
432 		scale = tw9910_ntsc_scales;
433 		size = ARRAY_SIZE(tw9910_ntsc_scales);
434 	} else if (norm & V4L2_STD_PAL) {
435 		scale = tw9910_pal_scales;
436 		size = ARRAY_SIZE(tw9910_pal_scales);
437 	} else {
438 		return NULL;
439 	}
440 
441 	for (i = 0; i < size; i++) {
442 		tmp = abs(width - scale[i].width) +
443 		      abs(height - scale[i].height);
444 		if (tmp < diff) {
445 			diff = tmp;
446 			ret = scale + i;
447 		}
448 	}
449 
450 	return ret;
451 }
452 
453 /*
454  * subdevice operations
455  */
456 static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
457 {
458 	struct i2c_client *client = v4l2_get_subdevdata(sd);
459 	struct tw9910_priv *priv = to_tw9910(client);
460 	u8 val;
461 	int ret;
462 
463 	if (!enable) {
464 		switch (priv->revision) {
465 		case 0:
466 			val = OEN_TRI_SEL_ALL_OFF_r0;
467 			break;
468 		case 1:
469 			val = OEN_TRI_SEL_ALL_OFF_r1;
470 			break;
471 		default:
472 			dev_err(&client->dev, "un-supported revision\n");
473 			return -EINVAL;
474 		}
475 	} else {
476 		val = OEN_TRI_SEL_ALL_ON;
477 
478 		if (!priv->scale) {
479 			dev_err(&client->dev, "norm select error\n");
480 			return -EPERM;
481 		}
482 
483 		dev_dbg(&client->dev, "%s %dx%d\n",
484 			priv->scale->name,
485 			priv->scale->width,
486 			priv->scale->height);
487 	}
488 
489 	ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val);
490 	if (ret < 0)
491 		return ret;
492 
493 	return tw9910_power(client, enable);
494 }
495 
496 static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
497 {
498 	struct i2c_client *client = v4l2_get_subdevdata(sd);
499 	struct tw9910_priv *priv = to_tw9910(client);
500 
501 	*norm = priv->norm;
502 
503 	return 0;
504 }
505 
506 static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
507 {
508 	struct i2c_client *client = v4l2_get_subdevdata(sd);
509 	struct tw9910_priv *priv = to_tw9910(client);
510 	const unsigned int hact = 720;
511 	const unsigned int hdelay = 15;
512 	unsigned int vact;
513 	unsigned int vdelay;
514 	int ret;
515 
516 	if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
517 		return -EINVAL;
518 
519 	priv->norm = norm;
520 	if (norm & V4L2_STD_525_60) {
521 		vact = 240;
522 		vdelay = 18;
523 		ret = tw9910_mask_set(client, VVBI, 0x10, 0x10);
524 	} else {
525 		vact = 288;
526 		vdelay = 24;
527 		ret = tw9910_mask_set(client, VVBI, 0x10, 0x00);
528 	}
529 	if (!ret)
530 		ret = i2c_smbus_write_byte_data(client, CROP_HI,
531 						((vdelay >> 2) & 0xc0)	|
532 						((vact >> 4) & 0x30)	|
533 						((hdelay >> 6) & 0x0c)	|
534 						((hact >> 8) & 0x03));
535 	if (!ret)
536 		ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
537 						vdelay & 0xff);
538 	if (!ret)
539 		ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
540 						vact & 0xff);
541 
542 	return ret;
543 }
544 
545 #ifdef CONFIG_VIDEO_ADV_DEBUG
546 static int tw9910_g_register(struct v4l2_subdev *sd,
547 			     struct v4l2_dbg_register *reg)
548 {
549 	struct i2c_client *client = v4l2_get_subdevdata(sd);
550 	int ret;
551 
552 	if (reg->reg > 0xff)
553 		return -EINVAL;
554 
555 	reg->size = 1;
556 	ret = i2c_smbus_read_byte_data(client, reg->reg);
557 	if (ret < 0)
558 		return ret;
559 
560 	/*
561 	 * ret      = int
562 	 * reg->val = __u64
563 	 */
564 	reg->val = (__u64)ret;
565 
566 	return 0;
567 }
568 
569 static int tw9910_s_register(struct v4l2_subdev *sd,
570 			     const struct v4l2_dbg_register *reg)
571 {
572 	struct i2c_client *client = v4l2_get_subdevdata(sd);
573 
574 	if (reg->reg > 0xff ||
575 	    reg->val > 0xff)
576 		return -EINVAL;
577 
578 	return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
579 }
580 #endif
581 
582 static void tw9910_set_gpio_value(struct gpio_desc *desc, int value)
583 {
584 	if (desc) {
585 		gpiod_set_value(desc, value);
586 		usleep_range(500, 1000);
587 	}
588 }
589 
590 static int tw9910_power_on(struct tw9910_priv *priv)
591 {
592 	struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
593 	int ret;
594 
595 	if (priv->clk) {
596 		ret = clk_prepare_enable(priv->clk);
597 		if (ret)
598 			return ret;
599 	}
600 
601 	tw9910_set_gpio_value(priv->pdn_gpio, 0);
602 
603 	/*
604 	 * FIXME: The reset signal is connected to a shared GPIO on some
605 	 * platforms (namely the SuperH Migo-R). Until a framework becomes
606 	 * available to handle this cleanly, request the GPIO temporarily
607 	 * to avoid conflicts.
608 	 */
609 	priv->rstb_gpio = gpiod_get_optional(&client->dev, "rstb",
610 					     GPIOD_OUT_LOW);
611 	if (IS_ERR(priv->rstb_gpio)) {
612 		dev_info(&client->dev, "Unable to get GPIO \"rstb\"");
613 		clk_disable_unprepare(priv->clk);
614 		tw9910_set_gpio_value(priv->pdn_gpio, 1);
615 		return PTR_ERR(priv->rstb_gpio);
616 	}
617 
618 	if (priv->rstb_gpio) {
619 		tw9910_set_gpio_value(priv->rstb_gpio, 1);
620 		tw9910_set_gpio_value(priv->rstb_gpio, 0);
621 
622 		gpiod_put(priv->rstb_gpio);
623 	}
624 
625 	return 0;
626 }
627 
628 static int tw9910_power_off(struct tw9910_priv *priv)
629 {
630 	clk_disable_unprepare(priv->clk);
631 	tw9910_set_gpio_value(priv->pdn_gpio, 1);
632 
633 	return 0;
634 }
635 
636 static int tw9910_s_power(struct v4l2_subdev *sd, int on)
637 {
638 	struct i2c_client *client = v4l2_get_subdevdata(sd);
639 	struct tw9910_priv *priv = to_tw9910(client);
640 
641 	return on ? tw9910_power_on(priv) : tw9910_power_off(priv);
642 }
643 
644 static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
645 {
646 	struct i2c_client *client = v4l2_get_subdevdata(sd);
647 	struct tw9910_priv *priv = to_tw9910(client);
648 	int ret = -EINVAL;
649 	u8 val;
650 
651 	/* Select suitable norm. */
652 	priv->scale = tw9910_select_norm(priv->norm, *width, *height);
653 	if (!priv->scale)
654 		goto tw9910_set_fmt_error;
655 
656 	/* Reset hardware. */
657 	tw9910_reset(client);
658 
659 	/* Set bus width. */
660 	val = 0x00;
661 	if (priv->info->buswidth == 16)
662 		val = LEN;
663 
664 	ret = tw9910_mask_set(client, OPFORM, LEN, val);
665 	if (ret < 0)
666 		goto tw9910_set_fmt_error;
667 
668 	/* Select MPOUT behavior. */
669 	switch (priv->info->mpout) {
670 	case TW9910_MPO_VLOSS:
671 		val = RTSEL_VLOSS; break;
672 	case TW9910_MPO_HLOCK:
673 		val = RTSEL_HLOCK; break;
674 	case TW9910_MPO_SLOCK:
675 		val = RTSEL_SLOCK; break;
676 	case TW9910_MPO_VLOCK:
677 		val = RTSEL_VLOCK; break;
678 	case TW9910_MPO_MONO:
679 		val = RTSEL_MONO;  break;
680 	case TW9910_MPO_DET50:
681 		val = RTSEL_DET50; break;
682 	case TW9910_MPO_FIELD:
683 		val = RTSEL_FIELD; break;
684 	case TW9910_MPO_RTCO:
685 		val = RTSEL_RTCO;  break;
686 	default:
687 		val = 0;
688 	}
689 
690 	ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
691 	if (ret < 0)
692 		goto tw9910_set_fmt_error;
693 
694 	/* Set scale. */
695 	ret = tw9910_set_scale(client, priv->scale);
696 	if (ret < 0)
697 		goto tw9910_set_fmt_error;
698 
699 	/* Set hsync. */
700 	ret = tw9910_set_hsync(client);
701 	if (ret < 0)
702 		goto tw9910_set_fmt_error;
703 
704 	*width = priv->scale->width;
705 	*height = priv->scale->height;
706 
707 	return ret;
708 
709 tw9910_set_fmt_error:
710 
711 	tw9910_reset(client);
712 	priv->scale = NULL;
713 
714 	return ret;
715 }
716 
717 static int tw9910_get_selection(struct v4l2_subdev *sd,
718 				struct v4l2_subdev_state *sd_state,
719 				struct v4l2_subdev_selection *sel)
720 {
721 	struct i2c_client *client = v4l2_get_subdevdata(sd);
722 	struct tw9910_priv *priv = to_tw9910(client);
723 
724 	if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
725 		return -EINVAL;
726 	/* Only CROP, CROP_DEFAULT and CROP_BOUNDS are supported. */
727 	if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS)
728 		return -EINVAL;
729 
730 	sel->r.left	= 0;
731 	sel->r.top	= 0;
732 	if (priv->norm & V4L2_STD_NTSC) {
733 		sel->r.width	= 640;
734 		sel->r.height	= 480;
735 	} else {
736 		sel->r.width	= 768;
737 		sel->r.height	= 576;
738 	}
739 
740 	return 0;
741 }
742 
743 static int tw9910_get_fmt(struct v4l2_subdev *sd,
744 			  struct v4l2_subdev_state *sd_state,
745 			  struct v4l2_subdev_format *format)
746 {
747 	struct v4l2_mbus_framefmt *mf = &format->format;
748 	struct i2c_client *client = v4l2_get_subdevdata(sd);
749 	struct tw9910_priv *priv = to_tw9910(client);
750 
751 	if (format->pad)
752 		return -EINVAL;
753 
754 	if (!priv->scale) {
755 		priv->scale = tw9910_select_norm(priv->norm, 640, 480);
756 		if (!priv->scale)
757 			return -EINVAL;
758 	}
759 
760 	mf->width	= priv->scale->width;
761 	mf->height	= priv->scale->height;
762 	mf->code	= MEDIA_BUS_FMT_UYVY8_2X8;
763 	mf->colorspace	= V4L2_COLORSPACE_SMPTE170M;
764 	mf->field	= V4L2_FIELD_INTERLACED_BT;
765 
766 	return 0;
767 }
768 
769 static int tw9910_s_fmt(struct v4l2_subdev *sd,
770 			struct v4l2_mbus_framefmt *mf)
771 {
772 	u32 width = mf->width, height = mf->height;
773 	int ret;
774 
775 	WARN_ON(mf->field != V4L2_FIELD_ANY &&
776 		mf->field != V4L2_FIELD_INTERLACED_BT);
777 
778 	/* Check color format. */
779 	if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8)
780 		return -EINVAL;
781 
782 	mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
783 
784 	ret = tw9910_set_frame(sd, &width, &height);
785 	if (ret)
786 		return ret;
787 
788 	mf->width	= width;
789 	mf->height	= height;
790 
791 	return 0;
792 }
793 
794 static int tw9910_set_fmt(struct v4l2_subdev *sd,
795 			  struct v4l2_subdev_state *sd_state,
796 			  struct v4l2_subdev_format *format)
797 {
798 	struct v4l2_mbus_framefmt *mf = &format->format;
799 	struct i2c_client *client = v4l2_get_subdevdata(sd);
800 	struct tw9910_priv *priv = to_tw9910(client);
801 	const struct tw9910_scale_ctrl *scale;
802 
803 	if (format->pad)
804 		return -EINVAL;
805 
806 	if (mf->field == V4L2_FIELD_ANY) {
807 		mf->field = V4L2_FIELD_INTERLACED_BT;
808 	} else if (mf->field != V4L2_FIELD_INTERLACED_BT) {
809 		dev_err(&client->dev, "Field type %d invalid\n", mf->field);
810 		return -EINVAL;
811 	}
812 
813 	mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
814 	mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
815 
816 	/* Select suitable norm. */
817 	scale = tw9910_select_norm(priv->norm, mf->width, mf->height);
818 	if (!scale)
819 		return -EINVAL;
820 
821 	mf->width	= scale->width;
822 	mf->height	= scale->height;
823 
824 	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
825 		return tw9910_s_fmt(sd, mf);
826 
827 	return 0;
828 }
829 
830 static int tw9910_video_probe(struct i2c_client *client)
831 {
832 	struct tw9910_priv *priv = to_tw9910(client);
833 	s32 id;
834 	int ret;
835 
836 	/* TW9910 only use 8 or 16 bit bus width. */
837 	if (priv->info->buswidth != 16 && priv->info->buswidth != 8) {
838 		dev_err(&client->dev, "bus width error\n");
839 		return -ENODEV;
840 	}
841 
842 	ret = tw9910_s_power(&priv->subdev, 1);
843 	if (ret < 0)
844 		return ret;
845 
846 	/*
847 	 * Check and show Product ID.
848 	 * So far only revisions 0 and 1 have been seen.
849 	 */
850 	id = i2c_smbus_read_byte_data(client, ID);
851 	priv->revision = GET_REV(id);
852 	id = GET_ID(id);
853 
854 	if (id != 0x0b || priv->revision > 0x01) {
855 		dev_err(&client->dev, "Product ID error %x:%x\n",
856 			id, priv->revision);
857 		ret = -ENODEV;
858 		goto done;
859 	}
860 
861 	dev_info(&client->dev, "tw9910 Product ID %0x:%0x\n",
862 		 id, priv->revision);
863 
864 	priv->norm = V4L2_STD_NTSC;
865 	priv->scale = &tw9910_ntsc_scales[0];
866 
867 done:
868 	tw9910_s_power(&priv->subdev, 0);
869 
870 	return ret;
871 }
872 
873 static const struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
874 #ifdef CONFIG_VIDEO_ADV_DEBUG
875 	.g_register	= tw9910_g_register,
876 	.s_register	= tw9910_s_register,
877 #endif
878 	.s_power	= tw9910_s_power,
879 };
880 
881 static int tw9910_enum_mbus_code(struct v4l2_subdev *sd,
882 				 struct v4l2_subdev_state *sd_state,
883 				 struct v4l2_subdev_mbus_code_enum *code)
884 {
885 	if (code->pad || code->index)
886 		return -EINVAL;
887 
888 	code->code = MEDIA_BUS_FMT_UYVY8_2X8;
889 
890 	return 0;
891 }
892 
893 static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm)
894 {
895 	*norm = V4L2_STD_NTSC | V4L2_STD_PAL;
896 
897 	return 0;
898 }
899 
900 static const struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
901 	.s_std		= tw9910_s_std,
902 	.g_std		= tw9910_g_std,
903 	.s_stream	= tw9910_s_stream,
904 	.g_tvnorms	= tw9910_g_tvnorms,
905 };
906 
907 static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = {
908 	.enum_mbus_code = tw9910_enum_mbus_code,
909 	.get_selection	= tw9910_get_selection,
910 	.get_fmt	= tw9910_get_fmt,
911 	.set_fmt	= tw9910_set_fmt,
912 };
913 
914 static const struct v4l2_subdev_ops tw9910_subdev_ops = {
915 	.core	= &tw9910_subdev_core_ops,
916 	.video	= &tw9910_subdev_video_ops,
917 	.pad	= &tw9910_subdev_pad_ops,
918 };
919 
920 /*
921  * i2c_driver function
922  */
923 
924 static int tw9910_probe(struct i2c_client *client)
925 
926 {
927 	struct tw9910_priv		*priv;
928 	struct tw9910_video_info	*info;
929 	struct i2c_adapter		*adapter = client->adapter;
930 	int ret;
931 
932 	if (!client->dev.platform_data) {
933 		dev_err(&client->dev, "TW9910: missing platform data!\n");
934 		return -EINVAL;
935 	}
936 
937 	info = client->dev.platform_data;
938 
939 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
940 		dev_err(&client->dev,
941 			"I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n");
942 		return -EIO;
943 	}
944 
945 	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
946 	if (!priv)
947 		return -ENOMEM;
948 
949 	priv->info = info;
950 
951 	v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
952 
953 	priv->clk = clk_get(&client->dev, "xti");
954 	if (PTR_ERR(priv->clk) == -ENOENT) {
955 		priv->clk = NULL;
956 	} else if (IS_ERR(priv->clk)) {
957 		dev_err(&client->dev, "Unable to get xti clock\n");
958 		return PTR_ERR(priv->clk);
959 	}
960 
961 	priv->pdn_gpio = gpiod_get_optional(&client->dev, "pdn",
962 					    GPIOD_OUT_HIGH);
963 	if (IS_ERR(priv->pdn_gpio)) {
964 		dev_info(&client->dev, "Unable to get GPIO \"pdn\"");
965 		ret = PTR_ERR(priv->pdn_gpio);
966 		goto error_clk_put;
967 	}
968 
969 	ret = tw9910_video_probe(client);
970 	if (ret < 0)
971 		goto error_gpio_put;
972 
973 	ret = v4l2_async_register_subdev(&priv->subdev);
974 	if (ret)
975 		goto error_gpio_put;
976 
977 	return ret;
978 
979 error_gpio_put:
980 	if (priv->pdn_gpio)
981 		gpiod_put(priv->pdn_gpio);
982 error_clk_put:
983 	clk_put(priv->clk);
984 
985 	return ret;
986 }
987 
988 static void tw9910_remove(struct i2c_client *client)
989 {
990 	struct tw9910_priv *priv = to_tw9910(client);
991 
992 	if (priv->pdn_gpio)
993 		gpiod_put(priv->pdn_gpio);
994 	clk_put(priv->clk);
995 	v4l2_async_unregister_subdev(&priv->subdev);
996 }
997 
998 static const struct i2c_device_id tw9910_id[] = {
999 	{ "tw9910" },
1000 	{ }
1001 };
1002 MODULE_DEVICE_TABLE(i2c, tw9910_id);
1003 
1004 static struct i2c_driver tw9910_i2c_driver = {
1005 	.driver = {
1006 		.name = "tw9910",
1007 	},
1008 	.probe    = tw9910_probe,
1009 	.remove   = tw9910_remove,
1010 	.id_table = tw9910_id,
1011 };
1012 
1013 module_i2c_driver(tw9910_i2c_driver);
1014 
1015 MODULE_DESCRIPTION("V4L2 driver for TW9910 video decoder");
1016 MODULE_AUTHOR("Kuninori Morimoto");
1017 MODULE_LICENSE("GPL v2");
1018