/*
 * ths8200 - Texas Instruments THS8200 video encoder driver
 *
 * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
 *
 * This program is free software; you may redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/v4l2-dv-timings.h>

#include <media/v4l2-dv-timings.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>

#include "ths8200_regs.h"

static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "debug level (0-2)");

MODULE_DESCRIPTION("Texas Instruments THS8200 video encoder driver");
MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>");
MODULE_AUTHOR("Martin Bugge <martin.bugge@cisco.com>");
MODULE_LICENSE("GPL v2");

struct ths8200_state {
	struct v4l2_subdev sd;
	uint8_t chip_version;
	/* Is the ths8200 powered on? */
	bool power_on;
	struct v4l2_dv_timings dv_timings;
};

static const struct v4l2_dv_timings_cap ths8200_timings_cap = {
	.type = V4L2_DV_BT_656_1120,
	/* keep this initialization for compatibility with GCC < 4.4.6 */
	.reserved = { 0 },
	V4L2_INIT_BT_TIMINGS(0, 1920, 0, 1080, 25000000, 148500000,
		V4L2_DV_BT_STD_CEA861, V4L2_DV_BT_CAP_PROGRESSIVE)
};

static inline struct ths8200_state *to_state(struct v4l2_subdev *sd)
{
	return container_of(sd, struct ths8200_state, sd);
}

static inline unsigned hblanking(const struct v4l2_bt_timings *t)
{
	return V4L2_DV_BT_BLANKING_WIDTH(t);
}

static inline unsigned htotal(const struct v4l2_bt_timings *t)
{
	return V4L2_DV_BT_FRAME_WIDTH(t);
}

static inline unsigned vblanking(const struct v4l2_bt_timings *t)
{
	return V4L2_DV_BT_BLANKING_HEIGHT(t);
}

static inline unsigned vtotal(const struct v4l2_bt_timings *t)
{
	return V4L2_DV_BT_FRAME_HEIGHT(t);
}

static int ths8200_read(struct v4l2_subdev *sd, u8 reg)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	return i2c_smbus_read_byte_data(client, reg);
}

static int ths8200_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	int ret;
	int i;

	for (i = 0; i < 3; i++) {
		ret = i2c_smbus_write_byte_data(client, reg, val);
		if (ret == 0)
			return 0;
	}
	v4l2_err(sd, "I2C Write Problem\n");
	return ret;
}

/* To set specific bits in the register, a clear-mask is given (to be AND-ed),
 * and then the value-mask (to be OR-ed).
 */
static inline void
ths8200_write_and_or(struct v4l2_subdev *sd, u8 reg,
		     uint8_t clr_mask, uint8_t val_mask)
{
	ths8200_write(sd, reg, (ths8200_read(sd, reg) & clr_mask) | val_mask);
}

#ifdef CONFIG_VIDEO_ADV_DEBUG

static int ths8200_g_register(struct v4l2_subdev *sd,
			      struct v4l2_dbg_register *reg)
{
	reg->val = ths8200_read(sd, reg->reg & 0xff);
	reg->size = 1;

	return 0;
}

static int ths8200_s_register(struct v4l2_subdev *sd,
			      const struct v4l2_dbg_register *reg)
{
	ths8200_write(sd, reg->reg & 0xff, reg->val & 0xff);

	return 0;
}
#endif

static int ths8200_log_status(struct v4l2_subdev *sd)
{
	struct ths8200_state *state = to_state(sd);
	uint8_t reg_03 = ths8200_read(sd, THS8200_CHIP_CTL);

	v4l2_info(sd, "----- Chip status -----\n");
	v4l2_info(sd, "version: %u\n", state->chip_version);
	v4l2_info(sd, "power: %s\n", (reg_03 & 0x0c) ? "off" : "on");
	v4l2_info(sd, "reset: %s\n", (reg_03 & 0x01) ? "off" : "on");
	v4l2_info(sd, "test pattern: %s\n",
		  (reg_03 & 0x20) ? "enabled" : "disabled");
	v4l2_info(sd, "format: %ux%u\n",
		  ths8200_read(sd, THS8200_DTG2_PIXEL_CNT_MSB) * 256 +
		  ths8200_read(sd, THS8200_DTG2_PIXEL_CNT_LSB),
		  (ths8200_read(sd, THS8200_DTG2_LINE_CNT_MSB) & 0x07) * 256 +
		  ths8200_read(sd, THS8200_DTG2_LINE_CNT_LSB));
	v4l2_print_dv_timings(sd->name, "Configured format:",
			      &state->dv_timings, true);
	return 0;
}

/* Power up/down ths8200 */
static int ths8200_s_power(struct v4l2_subdev *sd, int on)
{
	struct ths8200_state *state = to_state(sd);

	v4l2_dbg(1, debug, sd, "%s: power %s\n", __func__, on ? "on" : "off");

	state->power_on = on;

	/* Power up/down - leave in reset state until input video is present */
	ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0xf2, (on ? 0x00 : 0x0c));

	return 0;
}

static const struct v4l2_subdev_core_ops ths8200_core_ops = {
	.log_status = ths8200_log_status,
	.s_power = ths8200_s_power,
#ifdef CONFIG_VIDEO_ADV_DEBUG
	.g_register = ths8200_g_register,
	.s_register = ths8200_s_register,
#endif
};

/* -----------------------------------------------------------------------------
 * V4L2 subdev video operations
 */

static int ths8200_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct ths8200_state *state = to_state(sd);

	if (enable && !state->power_on)
		ths8200_s_power(sd, true);

	ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0xfe,
			     (enable ? 0x01 : 0x00));

	v4l2_dbg(1, debug, sd, "%s: %sable\n",
		 __func__, (enable ? "en" : "dis"));

	return 0;
}

static void ths8200_core_init(struct v4l2_subdev *sd)
{
	/* setup clocks */
	ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0x3f, 0xc0);

	/**** Data path control (DATA) ****/
	/* Set FSADJ 700 mV,
	 * bypass 422-444 interpolation,
	 * input format 30 bit RGB444
	 */
	ths8200_write(sd, THS8200_DATA_CNTL, 0x70);

	/* DTG Mode (Video blocked during blanking
	 * VESA slave
	 */
	ths8200_write(sd, THS8200_DTG1_MODE, 0x87);

	/**** Display Timing Generator Control, Part 1 (DTG1). ****/

	/* Disable embedded syncs on the output by setting
	 * the amplitude to zero for all channels.
	 */
	ths8200_write(sd, THS8200_DTG1_Y_SYNC_MSB, 0x2a);
	ths8200_write(sd, THS8200_DTG1_CBCR_SYNC_MSB, 0x2a);
}

static void ths8200_setup(struct v4l2_subdev *sd, struct v4l2_bt_timings *bt)
{
	uint8_t polarity = 0;
	uint16_t line_start_active_video = (bt->vsync + bt->vbackporch);
	uint16_t line_start_front_porch  = (vtotal(bt) - bt->vfrontporch);

	/*** System ****/
	/* Set chip in reset while it is configured */
	ths8200_s_stream(sd, false);

	/* configure video output timings */
	ths8200_write(sd, THS8200_DTG1_SPEC_A, bt->hsync);
	ths8200_write(sd, THS8200_DTG1_SPEC_B, bt->hfrontporch);

	/* Zero for progressive scan formats.*/
	if (!bt->interlaced)
		ths8200_write(sd, THS8200_DTG1_SPEC_C, 0x00);

	/* Distance from leading edge of h sync to start of active video.
	 * MSB in 0x2b
	 */
	ths8200_write(sd, THS8200_DTG1_SPEC_D_LSB,
		      (bt->hbackporch + bt->hsync) & 0xff);
	/* Zero for SDTV-mode. MSB in 0x2b */
	ths8200_write(sd, THS8200_DTG1_SPEC_E_LSB, 0x00);
	/*
	 * MSB for dtg1_spec(d/e/h). See comment for
	 * corresponding LSB registers.
	 */
	ths8200_write(sd, THS8200_DTG1_SPEC_DEH_MSB,
		      ((bt->hbackporch + bt->hsync) & 0x100) >> 1);

	/* h front porch */
	ths8200_write(sd, THS8200_DTG1_SPEC_K_LSB, (bt->hfrontporch) & 0xff);
	ths8200_write(sd, THS8200_DTG1_SPEC_K_MSB,
		      ((bt->hfrontporch) & 0x700) >> 8);

	/* Half the line length. Used to calculate SDTV line types. */
	ths8200_write(sd, THS8200_DTG1_SPEC_G_LSB, (htotal(bt)/2) & 0xff);
	ths8200_write(sd, THS8200_DTG1_SPEC_G_MSB,
		      ((htotal(bt)/2) >> 8) & 0x0f);

	/* Total pixels per line (ex. 720p: 1650) */
	ths8200_write(sd, THS8200_DTG1_TOT_PIXELS_MSB, htotal(bt) >> 8);
	ths8200_write(sd, THS8200_DTG1_TOT_PIXELS_LSB, htotal(bt) & 0xff);

	/* Frame height and field height */
	/* Field height should be programmed higher than frame_size for
	 * progressive scan formats
	 */
	ths8200_write(sd, THS8200_DTG1_FRAME_FIELD_SZ_MSB,
		      ((vtotal(bt) >> 4) & 0xf0) + 0x7);
	ths8200_write(sd, THS8200_DTG1_FRAME_SZ_LSB, vtotal(bt) & 0xff);

	/* Should be programmed higher than frame_size
	 * for progressive formats
	 */
	if (!bt->interlaced)
		ths8200_write(sd, THS8200_DTG1_FIELD_SZ_LSB, 0xff);

	/**** Display Timing Generator Control, Part 2 (DTG2). ****/
	/* Set breakpoint line numbers and types
	 * THS8200 generates line types with different properties. A line type
	 * that sets all the RGB-outputs to zero is used in the blanking areas,
	 * while a line type that enable the RGB-outputs is used in active video
	 * area. The line numbers for start of active video, start of front
	 * porch and after the last line in the frame must be set with the
	 * corresponding line types.
	 *
	 * Line types:
	 * 0x9 - Full normal sync pulse: Blocks data when dtg1_pass is off.
	 *       Used in blanking area.
	 * 0x0 - Active video: Video data is always passed. Used in active
	 *       video area.
	 */
	ths8200_write_and_or(sd, THS8200_DTG2_BP1_2_MSB, 0x88,
			     ((line_start_active_video >> 4) & 0x70) +
			     ((line_start_front_porch >> 8) & 0x07));
	ths8200_write(sd, THS8200_DTG2_BP3_4_MSB, ((vtotal(bt)) >> 4) & 0x70);
	ths8200_write(sd, THS8200_DTG2_BP1_LSB, line_start_active_video & 0xff);
	ths8200_write(sd, THS8200_DTG2_BP2_LSB, line_start_front_porch & 0xff);
	ths8200_write(sd, THS8200_DTG2_BP3_LSB, (vtotal(bt)) & 0xff);

	/* line types */
	ths8200_write(sd, THS8200_DTG2_LINETYPE1, 0x90);
	ths8200_write(sd, THS8200_DTG2_LINETYPE2, 0x90);

	/* h sync width transmitted */
	ths8200_write(sd, THS8200_DTG2_HLENGTH_LSB, bt->hsync & 0xff);
	ths8200_write_and_or(sd, THS8200_DTG2_HLENGTH_LSB_HDLY_MSB, 0x3f,
			     (bt->hsync >> 2) & 0xc0);

	/* The pixel value h sync is asserted on */
	ths8200_write_and_or(sd, THS8200_DTG2_HLENGTH_LSB_HDLY_MSB, 0xe0,
			     (htotal(bt) >> 8) & 0x1f);
	ths8200_write(sd, THS8200_DTG2_HLENGTH_HDLY_LSB, htotal(bt));

	/* v sync width transmitted */
	ths8200_write(sd, THS8200_DTG2_VLENGTH1_LSB, (bt->vsync) & 0xff);
	ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0x3f,
			     ((bt->vsync) >> 2) & 0xc0);

	/* The pixel value v sync is asserted on */
	ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0xf8,
			     (vtotal(bt)>>8) & 0x7);
	ths8200_write(sd, THS8200_DTG2_VDLY1_LSB, vtotal(bt));

	/* For progressive video vlength2 must be set to all 0 and vdly2 must
	 * be set to all 1.
	 */
	ths8200_write(sd, THS8200_DTG2_VLENGTH2_LSB, 0x00);
	ths8200_write(sd, THS8200_DTG2_VLENGTH2_MSB_VDLY2_MSB, 0x07);
	ths8200_write(sd, THS8200_DTG2_VDLY2_LSB, 0xff);

	/* Internal delay factors to synchronize the sync pulses and the data */
	/* Experimental values delays (hor 4, ver 1) */
	ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_MSB, (htotal(bt)>>8) & 0x1f);
	ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_LSB, (htotal(bt) - 4) & 0xff);
	ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_MSB, 0);
	ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_LSB, 1);

	/* Polarity of received and transmitted sync signals */
	if (bt->polarities & V4L2_DV_HSYNC_POS_POL) {
		polarity |= 0x01; /* HS_IN */
		polarity |= 0x08; /* HS_OUT */
	}
	if (bt->polarities & V4L2_DV_VSYNC_POS_POL) {
		polarity |= 0x02; /* VS_IN */
		polarity |= 0x10; /* VS_OUT */
	}

	/* RGB mode, no embedded timings */
	/* Timing of video input bus is derived from HS, VS, and FID dedicated
	 * inputs
	 */
	ths8200_write(sd, THS8200_DTG2_CNTL, 0x47 | polarity);

	/* leave reset */
	ths8200_s_stream(sd, true);

	v4l2_dbg(1, debug, sd, "%s: frame %dx%d, polarity %d\n"
		 "horizontal: front porch %d, back porch %d, sync %d\n"
		 "vertical: sync %d\n", __func__, htotal(bt), vtotal(bt),
		 polarity, bt->hfrontporch, bt->hbackporch,
		 bt->hsync, bt->vsync);
}

static int ths8200_s_dv_timings(struct v4l2_subdev *sd,
				struct v4l2_dv_timings *timings)
{
	struct ths8200_state *state = to_state(sd);

	v4l2_dbg(1, debug, sd, "%s:\n", __func__);

	if (!v4l2_valid_dv_timings(timings, &ths8200_timings_cap,
				NULL, NULL))
		return -EINVAL;

	if (!v4l2_find_dv_timings_cap(timings, &ths8200_timings_cap, 10,
				NULL, NULL)) {
		v4l2_dbg(1, debug, sd, "Unsupported format\n");
		return -EINVAL;
	}

	timings->bt.flags &= ~V4L2_DV_FL_REDUCED_FPS;

	/* save timings */
	state->dv_timings = *timings;

	ths8200_setup(sd, &timings->bt);

	return 0;
}

static int ths8200_g_dv_timings(struct v4l2_subdev *sd,
				struct v4l2_dv_timings *timings)
{
	struct ths8200_state *state = to_state(sd);

	v4l2_dbg(1, debug, sd, "%s:\n", __func__);

	*timings = state->dv_timings;

	return 0;
}

static int ths8200_enum_dv_timings(struct v4l2_subdev *sd,
				   struct v4l2_enum_dv_timings *timings)
{
	return v4l2_enum_dv_timings_cap(timings, &ths8200_timings_cap,
			NULL, NULL);
}

static int ths8200_dv_timings_cap(struct v4l2_subdev *sd,
				  struct v4l2_dv_timings_cap *cap)
{
	*cap = ths8200_timings_cap;
	return 0;
}

/* Specific video subsystem operation handlers */
static const struct v4l2_subdev_video_ops ths8200_video_ops = {
	.s_stream = ths8200_s_stream,
	.s_dv_timings = ths8200_s_dv_timings,
	.g_dv_timings = ths8200_g_dv_timings,
	.enum_dv_timings = ths8200_enum_dv_timings,
	.dv_timings_cap = ths8200_dv_timings_cap,
};

/* V4L2 top level operation handlers */
static const struct v4l2_subdev_ops ths8200_ops = {
	.core  = &ths8200_core_ops,
	.video = &ths8200_video_ops,
};

static int ths8200_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct ths8200_state *state;
	struct v4l2_subdev *sd;
	int error;

	/* Check if the adapter supports the needed features */
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EIO;

	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
	if (!state)
		return -ENOMEM;

	sd = &state->sd;
	v4l2_i2c_subdev_init(sd, client, &ths8200_ops);

	state->chip_version = ths8200_read(sd, THS8200_VERSION);
	v4l2_dbg(1, debug, sd, "chip version 0x%x\n", state->chip_version);

	ths8200_core_init(sd);

	error = v4l2_async_register_subdev(&state->sd);
	if (error)
		return error;

	v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
		  client->addr << 1, client->adapter->name);

	return 0;
}

static int ths8200_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd = i2c_get_clientdata(client);
	struct ths8200_state *decoder = to_state(sd);

	v4l2_dbg(1, debug, sd, "%s removed @ 0x%x (%s)\n", client->name,
		 client->addr << 1, client->adapter->name);

	ths8200_s_power(sd, false);
	v4l2_async_unregister_subdev(&decoder->sd);
	v4l2_device_unregister_subdev(sd);

	return 0;
}

static struct i2c_device_id ths8200_id[] = {
	{ "ths8200", 0 },
	{},
};
MODULE_DEVICE_TABLE(i2c, ths8200_id);

#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id ths8200_of_match[] = {
	{ .compatible = "ti,ths8200", },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, ths8200_of_match);
#endif

static struct i2c_driver ths8200_driver = {
	.driver = {
		.owner = THIS_MODULE,
		.name = "ths8200",
		.of_match_table = of_match_ptr(ths8200_of_match),
	},
	.probe = ths8200_probe,
	.remove = ths8200_remove,
	.id_table = ths8200_id,
};

module_i2c_driver(ths8200_driver);
