// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for the Texas Instruments DS90UB913 video serializer
 *
 * Based on a driver from Luca Ceresoli <luca@lucaceresoli.net>
 *
 * Copyright (c) 2019 Luca Ceresoli <luca@lucaceresoli.net>
 * Copyright (c) 2023 Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
 */

#include <linux/clk-provider.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/fwnode.h>
#include <linux/gpio/driver.h>
#include <linux/i2c-atr.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regmap.h>

#include <media/i2c/ds90ub9xx.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-subdev.h>

#define UB913_PAD_SINK			0
#define UB913_PAD_SOURCE		1

/*
 * UB913 has 4 gpios, but gpios 3 and 4 are reserved for external oscillator
 * mode. Thus we only support 2 gpios for now.
 */
#define UB913_NUM_GPIOS			2

#define UB913_REG_RESET_CTL			0x01
#define UB913_REG_RESET_CTL_DIGITAL_RESET_1	BIT(1)
#define UB913_REG_RESET_CTL_DIGITAL_RESET_0	BIT(0)

#define UB913_REG_GENERAL_CFG			0x03
#define UB913_REG_GENERAL_CFG_CRC_ERR_RESET	BIT(5)
#define UB913_REG_GENERAL_CFG_PCLK_RISING	BIT(0)

#define UB913_REG_MODE_SEL			0x05
#define UB913_REG_MODE_SEL_MODE_OVERRIDE	BIT(5)
#define UB913_REG_MODE_SEL_MODE_UP_TO_DATE	BIT(4)
#define UB913_REG_MODE_SEL_MODE_MASK		GENMASK(3, 0)

#define UB913_REG_CRC_ERRORS_LSB		0x0a
#define UB913_REG_CRC_ERRORS_MSB		0x0b

#define UB913_REG_GENERAL_STATUS		0x0c

#define UB913_REG_GPIO_CFG(n)			(0x0d + (n))
#define UB913_REG_GPIO_CFG_ENABLE(n)		BIT(0 + (n) * 4)
#define UB913_REG_GPIO_CFG_DIR_INPUT(n)		BIT(1 + (n) * 4)
#define UB913_REG_GPIO_CFG_REMOTE_EN(n)		BIT(2 + (n) * 4)
#define UB913_REG_GPIO_CFG_OUT_VAL(n)		BIT(3 + (n) * 4)
#define UB913_REG_GPIO_CFG_MASK(n)		(0xf << ((n) * 4))

#define UB913_REG_SCL_HIGH_TIME			0x11
#define UB913_REG_SCL_LOW_TIME			0x12

#define UB913_REG_PLL_OVR			0x35

struct ub913_data {
	struct i2c_client	*client;
	struct regmap		*regmap;
	struct clk		*clkin;

	struct gpio_chip	gpio_chip;

	struct v4l2_subdev	sd;
	struct media_pad	pads[2];

	struct v4l2_async_notifier	notifier;

	struct v4l2_subdev	*source_sd;
	u16			source_sd_pad;

	u64			enabled_source_streams;

	struct clk_hw		*clkout_clk_hw;

	struct ds90ub9xx_platform_data *plat_data;

	bool			pclk_polarity_rising;
};

static inline struct ub913_data *sd_to_ub913(struct v4l2_subdev *sd)
{
	return container_of(sd, struct ub913_data, sd);
}

struct ub913_format_info {
	u32 incode;
	u32 outcode;
};

static const struct ub913_format_info ub913_formats[] = {
	/* Only RAW10 with 8-bit payload is supported at the moment */
	{ .incode = MEDIA_BUS_FMT_YUYV8_2X8, .outcode = MEDIA_BUS_FMT_YUYV8_1X16 },
	{ .incode = MEDIA_BUS_FMT_UYVY8_2X8, .outcode = MEDIA_BUS_FMT_UYVY8_1X16 },
	{ .incode = MEDIA_BUS_FMT_VYUY8_2X8, .outcode = MEDIA_BUS_FMT_VYUY8_1X16 },
	{ .incode = MEDIA_BUS_FMT_YVYU8_2X8, .outcode = MEDIA_BUS_FMT_YVYU8_1X16 },
};

static const struct ub913_format_info *ub913_find_format(u32 incode)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(ub913_formats); i++) {
		if (ub913_formats[i].incode == incode)
			return &ub913_formats[i];
	}

	return NULL;
}

static int ub913_read(const struct ub913_data *priv, u8 reg, u8 *val)
{
	unsigned int v;
	int ret;

	ret = regmap_read(priv->regmap, reg, &v);
	if (ret < 0) {
		dev_err(&priv->client->dev,
			"Cannot read register 0x%02x: %d!\n", reg, ret);
		return ret;
	}

	*val = v;
	return 0;
}

static int ub913_write(const struct ub913_data *priv, u8 reg, u8 val)
{
	int ret;

	ret = regmap_write(priv->regmap, reg, val);
	if (ret < 0)
		dev_err(&priv->client->dev,
			"Cannot write register 0x%02x: %d!\n", reg, ret);

	return ret;
}

/*
 * GPIO chip
 */
static int ub913_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
	return GPIO_LINE_DIRECTION_OUT;
}

static int ub913_gpio_direction_out(struct gpio_chip *gc, unsigned int offset,
				    int value)
{
	struct ub913_data *priv = gpiochip_get_data(gc);
	unsigned int reg_idx = offset / 2;
	unsigned int field_idx = offset % 2;

	return regmap_update_bits(priv->regmap, UB913_REG_GPIO_CFG(reg_idx),
				  UB913_REG_GPIO_CFG_MASK(field_idx),
				  UB913_REG_GPIO_CFG_ENABLE(field_idx) |
					  (value ? UB913_REG_GPIO_CFG_OUT_VAL(field_idx) :
						   0));
}

static void ub913_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
{
	ub913_gpio_direction_out(gc, offset, value);
}

static int ub913_gpio_of_xlate(struct gpio_chip *gc,
			       const struct of_phandle_args *gpiospec,
			       u32 *flags)
{
	if (flags)
		*flags = gpiospec->args[1];

	return gpiospec->args[0];
}

static int ub913_gpiochip_probe(struct ub913_data *priv)
{
	struct device *dev = &priv->client->dev;
	struct gpio_chip *gc = &priv->gpio_chip;
	int ret;

	/* Initialize GPIOs 0 and 1 to local control, tri-state */
	ub913_write(priv, UB913_REG_GPIO_CFG(0), 0);

	gc->label = dev_name(dev);
	gc->parent = dev;
	gc->owner = THIS_MODULE;
	gc->base = -1;
	gc->can_sleep = true;
	gc->ngpio = UB913_NUM_GPIOS;
	gc->get_direction = ub913_gpio_get_direction;
	gc->direction_output = ub913_gpio_direction_out;
	gc->set = ub913_gpio_set;
	gc->of_xlate = ub913_gpio_of_xlate;
	gc->of_gpio_n_cells = 2;

	ret = gpiochip_add_data(gc, priv);
	if (ret) {
		dev_err(dev, "Failed to add GPIOs: %d\n", ret);
		return ret;
	}

	return 0;
}

static void ub913_gpiochip_remove(struct ub913_data *priv)
{
	gpiochip_remove(&priv->gpio_chip);
}

static const struct regmap_config ub913_regmap_config = {
	.name = "ds90ub913",
	.reg_bits = 8,
	.val_bits = 8,
	.reg_format_endian = REGMAP_ENDIAN_DEFAULT,
	.val_format_endian = REGMAP_ENDIAN_DEFAULT,
};

/*
 * V4L2
 */

static int ub913_enable_streams(struct v4l2_subdev *sd,
				struct v4l2_subdev_state *state, u32 pad,
				u64 streams_mask)
{
	struct ub913_data *priv = sd_to_ub913(sd);
	u64 sink_streams;
	int ret;

	sink_streams = v4l2_subdev_state_xlate_streams(state, UB913_PAD_SOURCE,
						       UB913_PAD_SINK,
						       &streams_mask);

	ret = v4l2_subdev_enable_streams(priv->source_sd, priv->source_sd_pad,
					 sink_streams);
	if (ret)
		return ret;

	priv->enabled_source_streams |= streams_mask;

	return 0;
}

static int ub913_disable_streams(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *state, u32 pad,
				 u64 streams_mask)
{
	struct ub913_data *priv = sd_to_ub913(sd);
	u64 sink_streams;
	int ret;

	sink_streams = v4l2_subdev_state_xlate_streams(state, UB913_PAD_SOURCE,
						       UB913_PAD_SINK,
						       &streams_mask);

	ret = v4l2_subdev_disable_streams(priv->source_sd, priv->source_sd_pad,
					  sink_streams);
	if (ret)
		return ret;

	priv->enabled_source_streams &= ~streams_mask;

	return 0;
}

static int _ub913_set_routing(struct v4l2_subdev *sd,
			      struct v4l2_subdev_state *state,
			      struct v4l2_subdev_krouting *routing)
{
	static const struct v4l2_mbus_framefmt in_format = {
		.width = 640,
		.height = 480,
		.code = MEDIA_BUS_FMT_UYVY8_2X8,
		.field = V4L2_FIELD_NONE,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.ycbcr_enc = V4L2_YCBCR_ENC_601,
		.quantization = V4L2_QUANTIZATION_LIM_RANGE,
		.xfer_func = V4L2_XFER_FUNC_SRGB,
	};
	static const struct v4l2_mbus_framefmt out_format = {
		.width = 640,
		.height = 480,
		.code = MEDIA_BUS_FMT_UYVY8_1X16,
		.field = V4L2_FIELD_NONE,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.ycbcr_enc = V4L2_YCBCR_ENC_601,
		.quantization = V4L2_QUANTIZATION_LIM_RANGE,
		.xfer_func = V4L2_XFER_FUNC_SRGB,
	};
	struct v4l2_subdev_stream_configs *stream_configs;
	unsigned int i;
	int ret;

	/*
	 * Note: we can only support up to V4L2_FRAME_DESC_ENTRY_MAX, until
	 * frame desc is made dynamically allocated.
	 */

	if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
		return -EINVAL;

	ret = v4l2_subdev_routing_validate(sd, routing,
					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
	if (ret)
		return ret;

	ret = v4l2_subdev_set_routing(sd, state, routing);
	if (ret)
		return ret;

	stream_configs = &state->stream_configs;

	for (i = 0; i < stream_configs->num_configs; i++) {
		if (stream_configs->configs[i].pad == UB913_PAD_SINK)
			stream_configs->configs[i].fmt = in_format;
		else
			stream_configs->configs[i].fmt = out_format;
	}

	return 0;
}

static int ub913_set_routing(struct v4l2_subdev *sd,
			     struct v4l2_subdev_state *state,
			     enum v4l2_subdev_format_whence which,
			     struct v4l2_subdev_krouting *routing)
{
	struct ub913_data *priv = sd_to_ub913(sd);

	if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)
		return -EBUSY;

	return _ub913_set_routing(sd, state, routing);
}

static int ub913_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad,
				struct v4l2_mbus_frame_desc *fd)
{
	struct ub913_data *priv = sd_to_ub913(sd);
	const struct v4l2_subdev_krouting *routing;
	struct v4l2_mbus_frame_desc source_fd;
	struct v4l2_subdev_route *route;
	struct v4l2_subdev_state *state;
	int ret;

	if (pad != UB913_PAD_SOURCE)
		return -EINVAL;

	ret = v4l2_subdev_call(priv->source_sd, pad, get_frame_desc,
			       priv->source_sd_pad, &source_fd);
	if (ret)
		return ret;

	fd->type = V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL;

	state = v4l2_subdev_lock_and_get_active_state(sd);

	routing = &state->routing;

	for_each_active_route(routing, route) {
		unsigned int i;

		if (route->source_pad != pad)
			continue;

		for (i = 0; i < source_fd.num_entries; i++) {
			if (source_fd.entry[i].stream == route->sink_stream)
				break;
		}

		if (i == source_fd.num_entries) {
			dev_err(&priv->client->dev,
				"Failed to find stream from source frame desc\n");
			ret = -EPIPE;
			goto out_unlock;
		}

		fd->entry[fd->num_entries].stream = route->source_stream;
		fd->entry[fd->num_entries].flags = source_fd.entry[i].flags;
		fd->entry[fd->num_entries].length = source_fd.entry[i].length;
		fd->entry[fd->num_entries].pixelcode =
			source_fd.entry[i].pixelcode;

		fd->num_entries++;
	}

out_unlock:
	v4l2_subdev_unlock_state(state);

	return ret;
}

static int ub913_set_fmt(struct v4l2_subdev *sd,
			 struct v4l2_subdev_state *state,
			 struct v4l2_subdev_format *format)
{
	struct ub913_data *priv = sd_to_ub913(sd);
	struct v4l2_mbus_framefmt *fmt;
	const struct ub913_format_info *finfo;

	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
	    priv->enabled_source_streams)
		return -EBUSY;

	/* Source format is fully defined by the sink format, so not settable */
	if (format->pad == UB913_PAD_SOURCE)
		return v4l2_subdev_get_fmt(sd, state, format);

	finfo = ub913_find_format(format->format.code);
	if (!finfo) {
		finfo = &ub913_formats[0];
		format->format.code = finfo->incode;
	}

	/* Set sink format */
	fmt = v4l2_subdev_state_get_stream_format(state, format->pad,
						  format->stream);
	if (!fmt)
		return -EINVAL;

	*fmt = format->format;

	/* Propagate to source format, and adjust the mbus code */
	fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
							   format->stream);
	if (!fmt)
		return -EINVAL;

	format->format.code = finfo->outcode;

	*fmt = format->format;

	return 0;
}

static int ub913_init_cfg(struct v4l2_subdev *sd,
			  struct v4l2_subdev_state *state)
{
	struct v4l2_subdev_route routes[] = {
		{
			.sink_pad = UB913_PAD_SINK,
			.sink_stream = 0,
			.source_pad = UB913_PAD_SOURCE,
			.source_stream = 0,
			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
		},
	};

	struct v4l2_subdev_krouting routing = {
		.num_routes = ARRAY_SIZE(routes),
		.routes = routes,
	};

	return _ub913_set_routing(sd, state, &routing);
}

static int ub913_log_status(struct v4l2_subdev *sd)
{
	struct ub913_data *priv = sd_to_ub913(sd);
	struct device *dev = &priv->client->dev;
	u8 v = 0, v1 = 0, v2 = 0;

	ub913_read(priv, UB913_REG_MODE_SEL, &v);
	dev_info(dev, "MODE_SEL %#02x\n", v);

	ub913_read(priv, UB913_REG_CRC_ERRORS_LSB, &v1);
	ub913_read(priv, UB913_REG_CRC_ERRORS_MSB, &v2);
	dev_info(dev, "CRC errors %u\n", v1 | (v2 << 8));

	/* clear CRC errors */
	ub913_read(priv, UB913_REG_GENERAL_CFG, &v);
	ub913_write(priv, UB913_REG_GENERAL_CFG,
		    v | UB913_REG_GENERAL_CFG_CRC_ERR_RESET);
	ub913_write(priv, UB913_REG_GENERAL_CFG, v);

	ub913_read(priv, UB913_REG_GENERAL_STATUS, &v);
	dev_info(dev, "GENERAL_STATUS %#02x\n", v);

	ub913_read(priv, UB913_REG_PLL_OVR, &v);
	dev_info(dev, "PLL_OVR %#02x\n", v);

	return 0;
}

static const struct v4l2_subdev_core_ops ub913_subdev_core_ops = {
	.log_status = ub913_log_status,
};

static const struct v4l2_subdev_pad_ops ub913_pad_ops = {
	.enable_streams = ub913_enable_streams,
	.disable_streams = ub913_disable_streams,
	.set_routing = ub913_set_routing,
	.get_frame_desc = ub913_get_frame_desc,
	.get_fmt = v4l2_subdev_get_fmt,
	.set_fmt = ub913_set_fmt,
	.init_cfg = ub913_init_cfg,
};

static const struct v4l2_subdev_ops ub913_subdev_ops = {
	.core = &ub913_subdev_core_ops,
	.pad = &ub913_pad_ops,
};

static const struct media_entity_operations ub913_entity_ops = {
	.link_validate = v4l2_subdev_link_validate,
};

static int ub913_notify_bound(struct v4l2_async_notifier *notifier,
			      struct v4l2_subdev *source_subdev,
			      struct v4l2_async_connection *asd)
{
	struct ub913_data *priv = sd_to_ub913(notifier->sd);
	struct device *dev = &priv->client->dev;
	int ret;

	ret = media_entity_get_fwnode_pad(&source_subdev->entity,
					  source_subdev->fwnode,
					  MEDIA_PAD_FL_SOURCE);
	if (ret < 0) {
		dev_err(dev, "Failed to find pad for %s\n",
			source_subdev->name);
		return ret;
	}

	priv->source_sd = source_subdev;
	priv->source_sd_pad = ret;

	ret = media_create_pad_link(&source_subdev->entity, priv->source_sd_pad,
				    &priv->sd.entity, UB913_PAD_SINK,
				    MEDIA_LNK_FL_ENABLED |
					    MEDIA_LNK_FL_IMMUTABLE);
	if (ret) {
		dev_err(dev, "Unable to link %s:%u -> %s:0\n",
			source_subdev->name, priv->source_sd_pad,
			priv->sd.name);
		return ret;
	}

	return 0;
}

static const struct v4l2_async_notifier_operations ub913_notify_ops = {
	.bound = ub913_notify_bound,
};

static int ub913_v4l2_notifier_register(struct ub913_data *priv)
{
	struct device *dev = &priv->client->dev;
	struct v4l2_async_connection *asd;
	struct fwnode_handle *ep_fwnode;
	int ret;

	ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
						    UB913_PAD_SINK, 0, 0);
	if (!ep_fwnode) {
		dev_err(dev, "No graph endpoint\n");
		return -ENODEV;
	}

	v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);

	asd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep_fwnode,
					      struct v4l2_async_connection);

	fwnode_handle_put(ep_fwnode);

	if (IS_ERR(asd)) {
		dev_err(dev, "Failed to add subdev: %ld", PTR_ERR(asd));
		v4l2_async_nf_cleanup(&priv->notifier);
		return PTR_ERR(asd);
	}

	priv->notifier.ops = &ub913_notify_ops;

	ret = v4l2_async_nf_register(&priv->notifier);
	if (ret) {
		dev_err(dev, "Failed to register subdev_notifier");
		v4l2_async_nf_cleanup(&priv->notifier);
		return ret;
	}

	return 0;
}

static void ub913_v4l2_nf_unregister(struct ub913_data *priv)
{
	v4l2_async_nf_unregister(&priv->notifier);
	v4l2_async_nf_cleanup(&priv->notifier);
}

static int ub913_register_clkout(struct ub913_data *priv)
{
	struct device *dev = &priv->client->dev;
	const char *name;
	int ret;

	name = kasprintf(GFP_KERNEL, "ds90ub913.%s.clk_out", dev_name(dev));
	if (!name)
		return -ENOMEM;

	priv->clkout_clk_hw = devm_clk_hw_register_fixed_factor(dev, name,
		__clk_get_name(priv->clkin), 0, 1, 2);

	kfree(name);

	if (IS_ERR(priv->clkout_clk_hw))
		return dev_err_probe(dev, PTR_ERR(priv->clkout_clk_hw),
				     "Cannot register clkout hw\n");

	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
					  priv->clkout_clk_hw);
	if (ret)
		return dev_err_probe(dev, ret,
				     "Cannot add OF clock provider\n");

	return 0;
}

static int ub913_i2c_master_init(struct ub913_data *priv)
{
	/* i2c fast mode */
	u32 scl_high = 600 + 300; /* high period + rise time, ns */
	u32 scl_low = 1300 + 300; /* low period + fall time, ns */
	unsigned long ref;
	int ret;

	ref = clk_get_rate(priv->clkin) / 2;

	scl_high = div64_u64((u64)scl_high * ref, 1000000000);
	scl_low = div64_u64((u64)scl_low * ref, 1000000000);

	ret = ub913_write(priv, UB913_REG_SCL_HIGH_TIME, scl_high);
	if (ret)
		return ret;

	ret = ub913_write(priv, UB913_REG_SCL_LOW_TIME, scl_low);
	if (ret)
		return ret;

	return 0;
}

static int ub913_add_i2c_adapter(struct ub913_data *priv)
{
	struct device *dev = &priv->client->dev;
	struct fwnode_handle *i2c_handle;
	int ret;

	i2c_handle = device_get_named_child_node(dev, "i2c");
	if (!i2c_handle)
		return 0;

	ret = i2c_atr_add_adapter(priv->plat_data->atr, priv->plat_data->port,
				  dev, i2c_handle);

	fwnode_handle_put(i2c_handle);

	if (ret)
		return ret;

	return 0;
}

static int ub913_parse_dt(struct ub913_data *priv)
{
	struct device *dev = &priv->client->dev;
	struct v4l2_fwnode_endpoint vep = {
		.bus_type = V4L2_MBUS_PARALLEL,
	};
	struct fwnode_handle *ep_fwnode;
	int ret;

	ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
						    UB913_PAD_SINK, 0, 0);
	if (!ep_fwnode)
		return dev_err_probe(dev, -ENOENT, "No sink endpoint\n");

	ret = v4l2_fwnode_endpoint_parse(ep_fwnode, &vep);

	fwnode_handle_put(ep_fwnode);

	if (ret)
		return dev_err_probe(dev, ret,
				     "failed to parse sink endpoint data\n");

	if (vep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
		priv->pclk_polarity_rising = true;
	else if (vep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
		priv->pclk_polarity_rising = false;
	else
		return dev_err_probe(dev, -EINVAL,
				     "bad value for 'pclk-sample'\n");

	return 0;
}

static int ub913_hw_init(struct ub913_data *priv)
{
	struct device *dev = &priv->client->dev;
	bool mode_override;
	u8 mode;
	int ret;
	u8 v;

	ret = ub913_read(priv, UB913_REG_MODE_SEL, &v);
	if (ret)
		return ret;

	if (!(v & UB913_REG_MODE_SEL_MODE_UP_TO_DATE))
		return dev_err_probe(dev, -ENODEV,
				     "Mode value not stabilized\n");

	mode_override = v & UB913_REG_MODE_SEL_MODE_OVERRIDE;
	mode = v & UB913_REG_MODE_SEL_MODE_MASK;

	dev_dbg(dev, "mode from %s: %#x\n",
		mode_override ? "reg" : "deserializer", mode);

	ret = ub913_i2c_master_init(priv);
	if (ret)
		return dev_err_probe(dev, ret, "i2c master init failed\n");

	ub913_read(priv, UB913_REG_GENERAL_CFG, &v);
	v &= ~UB913_REG_GENERAL_CFG_PCLK_RISING;
	v |= priv->pclk_polarity_rising ? UB913_REG_GENERAL_CFG_PCLK_RISING : 0;
	ub913_write(priv, UB913_REG_GENERAL_CFG, v);

	return 0;
}

static int ub913_subdev_init(struct ub913_data *priv)
{
	struct device *dev = &priv->client->dev;
	int ret;

	v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub913_subdev_ops);
	priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
	priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
	priv->sd.entity.ops = &ub913_entity_ops;

	priv->pads[0].flags = MEDIA_PAD_FL_SINK;
	priv->pads[1].flags = MEDIA_PAD_FL_SOURCE;

	ret = media_entity_pads_init(&priv->sd.entity, 2, priv->pads);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to init pads\n");

	ret = v4l2_subdev_init_finalize(&priv->sd);
	if (ret)
		goto err_entity_cleanup;

	ret = ub913_v4l2_notifier_register(priv);
	if (ret) {
		dev_err_probe(dev, ret,
			      "v4l2 subdev notifier register failed\n");
		goto err_subdev_cleanup;
	}

	ret = v4l2_async_register_subdev(&priv->sd);
	if (ret) {
		dev_err_probe(dev, ret, "v4l2_async_register_subdev error\n");
		goto err_unreg_notif;
	}

	return 0;

err_unreg_notif:
	ub913_v4l2_nf_unregister(priv);
err_subdev_cleanup:
	v4l2_subdev_cleanup(&priv->sd);
err_entity_cleanup:
	media_entity_cleanup(&priv->sd.entity);

	return ret;
}

static void ub913_subdev_uninit(struct ub913_data *priv)
{
	v4l2_async_unregister_subdev(&priv->sd);
	ub913_v4l2_nf_unregister(priv);
	v4l2_subdev_cleanup(&priv->sd);
	fwnode_handle_put(priv->sd.fwnode);
	media_entity_cleanup(&priv->sd.entity);
}

static int ub913_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct ub913_data *priv;
	int ret;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->client = client;

	priv->plat_data = dev_get_platdata(&client->dev);
	if (!priv->plat_data)
		return dev_err_probe(dev, -ENODEV, "Platform data missing\n");

	priv->regmap = devm_regmap_init_i2c(client, &ub913_regmap_config);
	if (IS_ERR(priv->regmap))
		return dev_err_probe(dev, PTR_ERR(priv->regmap),
				     "Failed to init regmap\n");

	/*
	 * ub913 can also work without ext clock, but that is not supported by
	 * the driver yet.
	 */
	priv->clkin = devm_clk_get(dev, "clkin");
	if (IS_ERR(priv->clkin))
		return dev_err_probe(dev, PTR_ERR(priv->clkin),
				     "Cannot get CLKIN\n");

	ret = ub913_parse_dt(priv);
	if (ret)
		return ret;

	ret = ub913_hw_init(priv);
	if (ret)
		return ret;

	ret = ub913_gpiochip_probe(priv);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to init gpiochip\n");

	ret = ub913_register_clkout(priv);
	if (ret) {
		dev_err_probe(dev, ret, "Failed to register clkout\n");
		goto err_gpiochip_remove;
	}

	ret = ub913_subdev_init(priv);
	if (ret)
		goto err_gpiochip_remove;

	ret = ub913_add_i2c_adapter(priv);
	if (ret) {
		dev_err_probe(dev, ret, "failed to add remote i2c adapter\n");
		goto err_subdev_uninit;
	}

	return 0;

err_subdev_uninit:
	ub913_subdev_uninit(priv);
err_gpiochip_remove:
	ub913_gpiochip_remove(priv);

	return ret;
}

static void ub913_remove(struct i2c_client *client)
{
	struct v4l2_subdev *sd = i2c_get_clientdata(client);
	struct ub913_data *priv = sd_to_ub913(sd);

	i2c_atr_del_adapter(priv->plat_data->atr, priv->plat_data->port);

	ub913_subdev_uninit(priv);

	ub913_gpiochip_remove(priv);
}

static const struct i2c_device_id ub913_id[] = { { "ds90ub913a-q1", 0 }, {} };
MODULE_DEVICE_TABLE(i2c, ub913_id);

static const struct of_device_id ub913_dt_ids[] = {
	{ .compatible = "ti,ds90ub913a-q1" },
	{}
};
MODULE_DEVICE_TABLE(of, ub913_dt_ids);

static struct i2c_driver ds90ub913_driver = {
	.probe		= ub913_probe,
	.remove		= ub913_remove,
	.id_table	= ub913_id,
	.driver = {
		.name	= "ds90ub913a",
		.of_match_table = ub913_dt_ids,
	},
};
module_i2c_driver(ds90ub913_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Texas Instruments DS90UB913 FPD-Link III Serializer Driver");
MODULE_AUTHOR("Luca Ceresoli <luca@lucaceresoli.net>");
MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>");
MODULE_IMPORT_NS(I2C_ATR);
