106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S/*
206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * adv7343 - ADV7343 Video Encoder Driver
306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S *
406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * The encoder hardware does not support SECAM.
506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S *
606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S *
806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * This program is free software; you can redistribute it and/or
906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * modify it under the terms of the GNU General Public License as
1006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * published by the Free Software Foundation version 2.
1106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S *
1206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * This program is distributed .as is. WITHOUT ANY WARRANTY of any
1306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * kind, whether express or implied; without even the implied warranty
1406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * GNU General Public License for more details.
1606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S */
1706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
1806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <linux/kernel.h>
1906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <linux/init.h>
2006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <linux/ctype.h>
215a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
2206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <linux/i2c.h>
2306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <linux/device.h>
2406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <linux/delay.h>
2506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <linux/module.h>
2606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <linux/videodev2.h>
2706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <linux/uaccess.h>
285cc6685aca9cfb01cb6f21569502d0145fb071f0Sachin Kamat#include <linux/of.h>
29fd9fdb78a9bf85b94fb2190c82ff280c8f8375ccPhilipp Zabel#include <linux/of_graph.h>
3006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
3106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <media/adv7343.h>
326555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar#include <media/v4l2-async.h>
3306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include <media/v4l2-device.h>
34ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil#include <media/v4l2-ctrls.h>
3506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
3606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S#include "adv7343_regs.h"
3706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
3806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U SMODULE_DESCRIPTION("ADV7343 video encoder driver");
3906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U SMODULE_LICENSE("GPL");
4006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
4106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic int debug;
4206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Smodule_param(debug, int, 0644);
4306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U SMODULE_PARM_DESC(debug, "Debug level 0-1");
4406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
4506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstruct adv7343_state {
4606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct v4l2_subdev sd;
47ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	struct v4l2_ctrl_handler hdl;
480b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar	const struct adv7343_platform_data *pdata;
4906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	u8 reg00;
5006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	u8 reg01;
5106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	u8 reg02;
5206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	u8 reg35;
5306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	u8 reg80;
5406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	u8 reg82;
5506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	u32 output;
5606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	v4l2_std_id std;
5706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S};
5806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
5906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic inline struct adv7343_state *to_state(struct v4l2_subdev *sd)
6006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
6106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	return container_of(sd, struct adv7343_state, sd);
6206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
6306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
64ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuilstatic inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
65ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil{
66ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	return &container_of(ctrl->handler, struct adv7343_state, hdl)->sd;
67ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil}
68ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil
6906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value)
7006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
7106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct i2c_client *client = v4l2_get_subdevdata(sd);
7206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
7306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	return i2c_smbus_write_byte_data(client, reg, value);
7406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
7506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
7606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic const u8 adv7343_init_reg_val[] = {
7706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SOFT_RESET, ADV7343_SOFT_RESET_DEFAULT,
7806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_POWER_MODE_REG, ADV7343_POWER_MODE_REG_DEFAULT,
7906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
8006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_HD_MODE_REG1, ADV7343_HD_MODE_REG1_DEFAULT,
8106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_HD_MODE_REG2, ADV7343_HD_MODE_REG2_DEFAULT,
8206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_HD_MODE_REG3, ADV7343_HD_MODE_REG3_DEFAULT,
8306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_HD_MODE_REG4, ADV7343_HD_MODE_REG4_DEFAULT,
8406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_HD_MODE_REG5, ADV7343_HD_MODE_REG5_DEFAULT,
8506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_HD_MODE_REG6, ADV7343_HD_MODE_REG6_DEFAULT,
8606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_HD_MODE_REG7, ADV7343_HD_MODE_REG7_DEFAULT,
8706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
8806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_MODE_REG1, ADV7343_SD_MODE_REG1_DEFAULT,
8906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_MODE_REG2, ADV7343_SD_MODE_REG2_DEFAULT,
9006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_MODE_REG3, ADV7343_SD_MODE_REG3_DEFAULT,
9106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_MODE_REG4, ADV7343_SD_MODE_REG4_DEFAULT,
9206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_MODE_REG5, ADV7343_SD_MODE_REG5_DEFAULT,
9306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_MODE_REG6, ADV7343_SD_MODE_REG6_DEFAULT,
9406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_MODE_REG7, ADV7343_SD_MODE_REG7_DEFAULT,
9506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_MODE_REG8, ADV7343_SD_MODE_REG8_DEFAULT,
9606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
9706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_HUE_REG, ADV7343_SD_HUE_REG_DEFAULT,
9806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_CGMS_WSS0, ADV7343_SD_CGMS_WSS0_DEFAULT,
9906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	ADV7343_SD_BRIGHTNESS_WSS, ADV7343_SD_BRIGHTNESS_WSS_DEFAULT,
10006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S};
10106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
10206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S/*
10306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * 			    2^32
10406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S * FSC(reg) =  FSC (HZ) * --------
10506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S *			  27000000
10606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S */
10706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic const struct adv7343_std_info stdinfo[] = {
10806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	{
10906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		/* FSC(Hz) = 3,579,545.45 Hz */
11006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		SD_STD_NTSC, 569408542, V4L2_STD_NTSC,
11106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}, {
11206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		/* FSC(Hz) = 3,575,611.00 Hz */
11306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M,
11406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}, {
11506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		/* FSC(Hz) = 3,582,056.00 */
11606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc,
11706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}, {
11806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		/* FSC(Hz) = 4,433,618.75 Hz */
11906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N,
12006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}, {
12106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		/* FSC(Hz) = 4,433,618.75 Hz */
12206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL,
12306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}, {
12406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		/* FSC(Hz) = 4,433,618.75 Hz */
12506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443,
12606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}, {
12706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		/* FSC(Hz) = 4,433,618.75 Hz */
12806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60,
12906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	},
13006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S};
13106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
13206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic int adv7343_setstd(struct v4l2_subdev *sd, v4l2_std_id std)
13306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
13406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct adv7343_state *state = to_state(sd);
13506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct adv7343_std_info *std_info;
1368173090acb33500496b69ca20c7f33c3bf665958Hans Verkuil	int num_std;
13706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	char *fsc_ptr;
13806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	u8 reg, val;
13906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	int err = 0;
14006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	int i = 0;
14106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
14206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	std_info = (struct adv7343_std_info *)stdinfo;
14306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	num_std = ARRAY_SIZE(stdinfo);
14406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
14506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	for (i = 0; i < num_std; i++) {
14606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		if (std_info[i].stdid & std)
14706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S			break;
14806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}
14906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
15006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (i == num_std) {
15106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		v4l2_dbg(1, debug, sd,
15206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S				"Invalid std or std is not supported: %llx\n",
15306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S						(unsigned long long)std);
15406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		return -EINVAL;
15506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}
15606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
15706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	/* Set the standard */
15806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	val = state->reg80 & (~(SD_STD_MASK));
15906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	val |= std_info[i].standard_val3;
16006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
16106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err < 0)
16206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		goto setstd_exit;
16306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
16406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg80 = val;
16506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
16606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	/* Configure the input mode register */
16706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	val = state->reg01 & (~((u8) INPUT_MODE_MASK));
16806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	val |= SD_INPUT_MODE;
16906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_write(sd, ADV7343_MODE_SELECT_REG, val);
17006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err < 0)
17106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		goto setstd_exit;
17206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
17306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg01 = val;
17406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
17506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	/* Program the sub carrier frequency registers */
17606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	fsc_ptr = (unsigned char *)&std_info[i].fsc_val;
17706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	reg = ADV7343_FSC_REG0;
17806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	for (i = 0; i < 4; i++, reg++, fsc_ptr++) {
17906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		err = adv7343_write(sd, reg, *fsc_ptr);
18006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		if (err < 0)
18106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S			goto setstd_exit;
18206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}
18306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
18406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	val = state->reg80;
18506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
18606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	/* Filter settings */
18706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443))
18806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		val &= 0x03;
18906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	else if (std & ~V4L2_STD_SECAM)
19006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		val |= 0x04;
19106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
19206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
19306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err < 0)
19406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		goto setstd_exit;
19506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
19606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg80 = val;
19706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
19806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Ssetstd_exit:
19906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err != 0)
20006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		v4l2_err(sd, "Error setting std, write failed\n");
20106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
20206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	return err;
20306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
20406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
20506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic int adv7343_setoutput(struct v4l2_subdev *sd, u32 output_type)
20606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
20706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct adv7343_state *state = to_state(sd);
20806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	unsigned char val;
20906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	int err = 0;
21006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
21106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (output_type > ADV7343_SVIDEO_ID) {
21206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		v4l2_dbg(1, debug, sd,
21306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S			"Invalid output type or output type not supported:%d\n",
21406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S								output_type);
21506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		return -EINVAL;
21606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}
21706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
21806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	/* Enable Appropriate DAC */
21906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	val = state->reg00 & 0x03;
22006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
2210b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar	/* configure default configuration */
2220b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar	if (!state->pdata)
2230b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar		if (output_type == ADV7343_COMPOSITE_ID)
2240b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar			val |= ADV7343_COMPOSITE_POWER_VALUE;
2250b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar		else if (output_type == ADV7343_COMPONENT_ID)
2260b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar			val |= ADV7343_COMPONENT_POWER_VALUE;
2270b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar		else
2280b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar			val |= ADV7343_SVIDEO_POWER_VALUE;
22906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	else
2300b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar		val = state->pdata->mode_config.sleep_mode << 0 |
2310b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar		      state->pdata->mode_config.pll_control << 1 |
2325e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		      state->pdata->mode_config.dac[2] << 2 |
2335e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		      state->pdata->mode_config.dac[1] << 3 |
2345e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		      state->pdata->mode_config.dac[0] << 4 |
2355e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		      state->pdata->mode_config.dac[5] << 5 |
2365e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		      state->pdata->mode_config.dac[4] << 6 |
2375e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		      state->pdata->mode_config.dac[3] << 7;
23806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
23906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_write(sd, ADV7343_POWER_MODE_REG, val);
24006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err < 0)
24106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		goto setoutput_exit;
24206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
24306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg00 = val;
24406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
24506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	/* Enable YUV output */
24606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	val = state->reg02 | YUV_OUTPUT_SELECT;
24706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_write(sd, ADV7343_MODE_REG0, val);
24806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err < 0)
24906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		goto setoutput_exit;
25006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
25106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg02 = val;
25206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
25306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	/* configure SD DAC Output 2 and SD DAC Output 1 bit to zero */
25406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	val = state->reg82 & (SD_DAC_1_DI & SD_DAC_2_DI);
2550b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar
2565e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar	if (state->pdata && state->pdata->sd_config.sd_dac_out[0])
2575e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		val = val | (state->pdata->sd_config.sd_dac_out[0] << 1);
2585e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar	else if (state->pdata && !state->pdata->sd_config.sd_dac_out[0])
2595e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		val = val & ~(state->pdata->sd_config.sd_dac_out[0] << 1);
2600b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar
2615e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar	if (state->pdata && state->pdata->sd_config.sd_dac_out[1])
2625e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		val = val | (state->pdata->sd_config.sd_dac_out[1] << 2);
2635e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar	else if (state->pdata && !state->pdata->sd_config.sd_dac_out[1])
2645e95814ff3f2a6ea7d76e822bbc3b0c0b94495a4Lad, Prabhakar		val = val & ~(state->pdata->sd_config.sd_dac_out[1] << 2);
2650b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar
26606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_write(sd, ADV7343_SD_MODE_REG2, val);
26706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err < 0)
26806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		goto setoutput_exit;
26906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
27006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg82 = val;
27106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
27206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	/* configure ED/HD Color DAC Swap and ED/HD RGB Input Enable bit to
27306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	 * zero */
27406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	val = state->reg35 & (HD_RGB_INPUT_DI & HD_DAC_SWAP_DI);
27506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_write(sd, ADV7343_HD_MODE_REG6, val);
27606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err < 0)
27706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		goto setoutput_exit;
27806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
27906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg35 = val;
28006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
28106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Ssetoutput_exit:
28206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err != 0)
28306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		v4l2_err(sd, "Error setting output, write failed\n");
28406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
28506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	return err;
28606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
28706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
28806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic int adv7343_log_status(struct v4l2_subdev *sd)
28906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
29006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct adv7343_state *state = to_state(sd);
29106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
29206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std);
29306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" :
29406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S			((state->output == 1) ? "Component" : "S-Video"));
29506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	return 0;
29606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
29706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
298ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuilstatic int adv7343_s_ctrl(struct v4l2_ctrl *ctrl)
29906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
300ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	struct v4l2_subdev *sd = to_sd(ctrl);
30106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
30206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	switch (ctrl->id) {
30306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	case V4L2_CID_BRIGHTNESS:
304ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil		return adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
305ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil					ctrl->val);
30606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
30706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	case V4L2_CID_HUE:
308ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil		return adv7343_write(sd, ADV7343_SD_HUE_REG, ctrl->val);
30906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
31006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	case V4L2_CID_GAIN:
311ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil		return adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, ctrl->val);
31206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}
313ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	return -EINVAL;
31406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
31506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
316ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuilstatic const struct v4l2_ctrl_ops adv7343_ctrl_ops = {
317ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	.s_ctrl = adv7343_s_ctrl,
318ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil};
319ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil
32006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic const struct v4l2_subdev_core_ops adv7343_core_ops = {
321ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	.log_status = adv7343_log_status,
322ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
323ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
324ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
325ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	.g_ctrl = v4l2_subdev_g_ctrl,
326ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	.s_ctrl = v4l2_subdev_s_ctrl,
327ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	.queryctrl = v4l2_subdev_queryctrl,
328ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	.querymenu = v4l2_subdev_querymenu,
32906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S};
33006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
33106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
33206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
33306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct adv7343_state *state = to_state(sd);
33406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	int err = 0;
33506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
33606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (state->std == std)
33706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		return 0;
33806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
33906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_setstd(sd, std);
34006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (!err)
34106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		state->std = std;
34206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
34306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	return err;
34406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
34506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
34606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic int adv7343_s_routing(struct v4l2_subdev *sd,
34706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		u32 input, u32 output, u32 config)
34806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
34906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct adv7343_state *state = to_state(sd);
35006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	int err = 0;
35106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
35206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (state->output == output)
35306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		return 0;
35406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
35506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_setoutput(sd, output);
35606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (!err)
35706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		state->output = output;
35806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
35906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	return err;
36006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
36106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
36206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic const struct v4l2_subdev_video_ops adv7343_video_ops = {
36306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	.s_std_output	= adv7343_s_std_output,
36406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	.s_routing	= adv7343_s_routing,
36506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S};
36606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
36706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic const struct v4l2_subdev_ops adv7343_ops = {
36806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	.core	= &adv7343_core_ops,
36906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	.video	= &adv7343_video_ops,
37006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S};
37106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
37206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic int adv7343_initialize(struct v4l2_subdev *sd)
37306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
37406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct adv7343_state *state = to_state(sd);
37506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	int err = 0;
37606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	int i;
37706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
37806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	for (i = 0; i < ARRAY_SIZE(adv7343_init_reg_val); i += 2) {
37906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
38006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		err = adv7343_write(sd, adv7343_init_reg_val[i],
38106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S					adv7343_init_reg_val[i+1]);
38206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		if (err) {
38306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S			v4l2_err(sd, "Error initializing\n");
38406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S			return err;
38506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		}
38606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}
38706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
38806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	/* Configure for default video standard */
38906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_setoutput(sd, state->output);
39006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err < 0) {
39106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		v4l2_err(sd, "Error setting output during init\n");
39206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		return -EINVAL;
39306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}
39406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
39506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	err = adv7343_setstd(sd, state->std);
39606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (err < 0) {
39706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		v4l2_err(sd, "Error setting std during init\n");
39806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		return -EINVAL;
39906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	}
40006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
40106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	return err;
40206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
40306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
404187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakarstatic struct adv7343_platform_data *
405187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakaradv7343_get_pdata(struct i2c_client *client)
406187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar{
407187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	struct adv7343_platform_data *pdata;
408187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	struct device_node *np;
409187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
410187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
411187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar		return client->dev.platform_data;
412187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
413fd9fdb78a9bf85b94fb2190c82ff280c8f8375ccPhilipp Zabel	np = of_graph_get_next_endpoint(client->dev.of_node, NULL);
414187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	if (!np)
415187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar		return NULL;
416187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
417187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
418187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	if (!pdata)
419187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar		goto done;
420187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
421187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	pdata->mode_config.sleep_mode =
422187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar			of_property_read_bool(np, "adi,power-mode-sleep-mode");
423187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
424187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	pdata->mode_config.pll_control =
425187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar			of_property_read_bool(np, "adi,power-mode-pll-ctrl");
426187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
427187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	of_property_read_u32_array(np, "adi,dac-enable",
428187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar				   pdata->mode_config.dac, 6);
429187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
430187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	of_property_read_u32_array(np, "adi,sd-dac-enable",
431187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar				   pdata->sd_config.sd_dac_out, 2);
432187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
433187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakardone:
434187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	of_node_put(np);
435187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	return pdata;
436187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar}
437187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
43806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic int adv7343_probe(struct i2c_client *client,
43906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S				const struct i2c_device_id *id)
44006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
44106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct adv7343_state *state;
442ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	int err;
44306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
44406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
44506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		return -ENODEV;
44606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
44706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	v4l_info(client, "chip found @ 0x%x (%s)\n",
44806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S			client->addr << 1, client->adapter->name);
44906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
450c7a857a09f1f00e6cb04c6565c136a9f0018532dLad, Prabhakar	state = devm_kzalloc(&client->dev, sizeof(struct adv7343_state),
451c7a857a09f1f00e6cb04c6565c136a9f0018532dLad, Prabhakar			     GFP_KERNEL);
45206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	if (state == NULL)
45306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		return -ENOMEM;
45406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
4550b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar	/* Copy board specific information here */
456187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	state->pdata = adv7343_get_pdata(client);
4570b302d88534f0811c5f49bfba7aa46c4e1e032b7Lad, Prabhakar
45806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg00	= 0x80;
45906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg01	= 0x00;
46006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg02	= 0x20;
46106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg35	= 0x00;
46206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg80	= ADV7343_SD_MODE_REG1_DEFAULT;
46306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->reg82	= ADV7343_SD_MODE_REG2_DEFAULT;
46406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
46506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->output = ADV7343_COMPOSITE_ID;
46606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	state->std = V4L2_STD_NTSC;
46706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
46806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops);
469ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil
470ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	v4l2_ctrl_handler_init(&state->hdl, 2);
471ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
472ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil			V4L2_CID_BRIGHTNESS, ADV7343_BRIGHTNESS_MIN,
473ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil					     ADV7343_BRIGHTNESS_MAX, 1,
474ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil					     ADV7343_BRIGHTNESS_DEF);
475ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
476ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil			V4L2_CID_HUE, ADV7343_HUE_MIN,
477ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil				      ADV7343_HUE_MAX, 1,
478ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil				      ADV7343_HUE_DEF);
479ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
480ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil			V4L2_CID_GAIN, ADV7343_GAIN_MIN,
481ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil				       ADV7343_GAIN_MAX, 1,
482ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil				       ADV7343_GAIN_DEF);
483ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	state->sd.ctrl_handler = &state->hdl;
484ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	if (state->hdl.error) {
4856555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar		err = state->hdl.error;
4866555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar		goto done;
487ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	}
488ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	v4l2_ctrl_handler_setup(&state->hdl);
489ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil
490ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	err = adv7343_initialize(&state->sd);
491c7a857a09f1f00e6cb04c6565c136a9f0018532dLad, Prabhakar	if (err)
4926555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar		goto done;
4936555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar
4946555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar	err = v4l2_async_register_subdev(&state->sd);
4956555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar
4966555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakardone:
4976555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar	if (err < 0)
498ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil		v4l2_ctrl_handler_free(&state->hdl);
4996555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar
500ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	return err;
50106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
50206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
50306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic int adv7343_remove(struct i2c_client *client)
50406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S{
50506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	struct v4l2_subdev *sd = i2c_get_clientdata(client);
506ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	struct adv7343_state *state = to_state(sd);
50706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
5086555cfc5e7f8080a76edc2f556c709770fc1db57Lad, Prabhakar	v4l2_async_unregister_subdev(&state->sd);
50906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	v4l2_device_unregister_subdev(sd);
510ceed52d67e1cf7866fa96514525c615554a0e44eHans Verkuil	v4l2_ctrl_handler_free(&state->hdl);
51106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
51206e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	return 0;
51306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S}
51406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
51506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic const struct i2c_device_id adv7343_id[] = {
51606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	{"adv7343", 0},
51706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	{},
51806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S};
51906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
52006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U SMODULE_DEVICE_TABLE(i2c, adv7343_id);
52106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
522187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar#if IS_ENABLED(CONFIG_OF)
523187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakarstatic const struct of_device_id adv7343_of_match[] = {
524187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	{.compatible = "adi,adv7343", },
525187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar	{ /* sentinel */ },
526187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar};
527187d42d6da62aa3eb3d76866584382625f141b3cLad, PrabhakarMODULE_DEVICE_TABLE(of, adv7343_of_match);
528187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar#endif
529187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar
53006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U Sstatic struct i2c_driver adv7343_driver = {
53106e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	.driver = {
532187d42d6da62aa3eb3d76866584382625f141b3cLad, Prabhakar		.of_match_table = of_match_ptr(adv7343_of_match),
53306e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		.owner	= THIS_MODULE,
53406e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S		.name	= "adv7343",
53506e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	},
53606e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	.probe		= adv7343_probe,
53706e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	.remove		= adv7343_remove,
53806e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S	.id_table	= adv7343_id,
53906e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S};
54006e61f8d5f5df68104168ac20d0527ecee13638aChaithrika U S
541c6e8d86fffd8edf1bfccbd441b1812ee919fe3d5Axel Linmodule_i2c_driver(adv7343_driver);
542