// SPDX-License-Identifier: GPL-2.0+
/*
 * vsp1_hsit.c  --  R-Car VSP1 Hue Saturation value (Inverse) Transform
 *
 * Copyright (C) 2013 Renesas Corporation
 *
 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
 */

#include <linux/device.h>
#include <linux/gfp.h>

#include <media/v4l2-subdev.h>

#include "vsp1.h"
#include "vsp1_dl.h"
#include "vsp1_hsit.h"

#define HSIT_MIN_SIZE				4U
#define HSIT_MAX_SIZE				8190U

/* -----------------------------------------------------------------------------
 * Device Access
 */

static inline void vsp1_hsit_write(struct vsp1_hsit *hsit,
				   struct vsp1_dl_body *dlb, u32 reg, u32 data)
{
	vsp1_dl_body_write(dlb, reg, data);
}

/* -----------------------------------------------------------------------------
 * V4L2 Subdevice Operations
 */

static int hsit_enum_mbus_code(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_state *sd_state,
			       struct v4l2_subdev_mbus_code_enum *code)
{
	struct vsp1_hsit *hsit = to_hsit(subdev);

	if (code->index > 0)
		return -EINVAL;

	if ((code->pad == HSIT_PAD_SINK && !hsit->inverse) |
	    (code->pad == HSIT_PAD_SOURCE && hsit->inverse))
		code->code = MEDIA_BUS_FMT_ARGB8888_1X32;
	else
		code->code = MEDIA_BUS_FMT_AHSV8888_1X32;

	return 0;
}

static int hsit_enum_frame_size(struct v4l2_subdev *subdev,
				struct v4l2_subdev_state *sd_state,
				struct v4l2_subdev_frame_size_enum *fse)
{
	return vsp1_subdev_enum_frame_size(subdev, sd_state, fse,
					   HSIT_MIN_SIZE,
					   HSIT_MIN_SIZE, HSIT_MAX_SIZE,
					   HSIT_MAX_SIZE);
}

static int hsit_set_format(struct v4l2_subdev *subdev,
			   struct v4l2_subdev_state *sd_state,
			   struct v4l2_subdev_format *fmt)
{
	struct vsp1_hsit *hsit = to_hsit(subdev);
	struct v4l2_subdev_state *config;
	struct v4l2_mbus_framefmt *format;
	int ret = 0;

	mutex_lock(&hsit->entity.lock);

	config = vsp1_entity_get_pad_config(&hsit->entity, sd_state,
					    fmt->which);
	if (!config) {
		ret = -EINVAL;
		goto done;
	}

	format = vsp1_entity_get_pad_format(&hsit->entity, config, fmt->pad);

	if (fmt->pad == HSIT_PAD_SOURCE) {
		/*
		 * The HST and HSI output format code and resolution can't be
		 * modified.
		 */
		fmt->format = *format;
		goto done;
	}

	format->code = hsit->inverse ? MEDIA_BUS_FMT_AHSV8888_1X32
		     : MEDIA_BUS_FMT_ARGB8888_1X32;
	format->width = clamp_t(unsigned int, fmt->format.width,
				HSIT_MIN_SIZE, HSIT_MAX_SIZE);
	format->height = clamp_t(unsigned int, fmt->format.height,
				 HSIT_MIN_SIZE, HSIT_MAX_SIZE);
	format->field = V4L2_FIELD_NONE;
	format->colorspace = V4L2_COLORSPACE_SRGB;

	fmt->format = *format;

	/* Propagate the format to the source pad. */
	format = vsp1_entity_get_pad_format(&hsit->entity, config,
					    HSIT_PAD_SOURCE);
	*format = fmt->format;
	format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32
		     : MEDIA_BUS_FMT_AHSV8888_1X32;

done:
	mutex_unlock(&hsit->entity.lock);
	return ret;
}

static const struct v4l2_subdev_pad_ops hsit_pad_ops = {
	.init_cfg = vsp1_entity_init_cfg,
	.enum_mbus_code = hsit_enum_mbus_code,
	.enum_frame_size = hsit_enum_frame_size,
	.get_fmt = vsp1_subdev_get_pad_format,
	.set_fmt = hsit_set_format,
};

static const struct v4l2_subdev_ops hsit_ops = {
	.pad    = &hsit_pad_ops,
};

/* -----------------------------------------------------------------------------
 * VSP1 Entity Operations
 */

static void hsit_configure_stream(struct vsp1_entity *entity,
				  struct vsp1_pipeline *pipe,
				  struct vsp1_dl_list *dl,
				  struct vsp1_dl_body *dlb)
{
	struct vsp1_hsit *hsit = to_hsit(&entity->subdev);

	if (hsit->inverse)
		vsp1_hsit_write(hsit, dlb, VI6_HSI_CTRL, VI6_HSI_CTRL_EN);
	else
		vsp1_hsit_write(hsit, dlb, VI6_HST_CTRL, VI6_HST_CTRL_EN);
}

static const struct vsp1_entity_operations hsit_entity_ops = {
	.configure_stream = hsit_configure_stream,
};

/* -----------------------------------------------------------------------------
 * Initialization and Cleanup
 */

struct vsp1_hsit *vsp1_hsit_create(struct vsp1_device *vsp1, bool inverse)
{
	struct vsp1_hsit *hsit;
	int ret;

	hsit = devm_kzalloc(vsp1->dev, sizeof(*hsit), GFP_KERNEL);
	if (hsit == NULL)
		return ERR_PTR(-ENOMEM);

	hsit->inverse = inverse;

	hsit->entity.ops = &hsit_entity_ops;

	if (inverse)
		hsit->entity.type = VSP1_ENTITY_HSI;
	else
		hsit->entity.type = VSP1_ENTITY_HST;

	ret = vsp1_entity_init(vsp1, &hsit->entity, inverse ? "hsi" : "hst",
			       2, &hsit_ops,
			       MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV);
	if (ret < 0)
		return ERR_PTR(ret);

	return hsit;
}
