// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * vimc-sensor.c Virtual Media Controller Driver
 *
 * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
 */

#include <linux/v4l2-mediabus.h>
#include <linux/vmalloc.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/v4l2-subdev.h>
#include <media/tpg/v4l2-tpg.h>

#include "vimc-common.h"

static const struct v4l2_mbus_framefmt fmt_default = {
	.width = 640,
	.height = 480,
	.code = MEDIA_BUS_FMT_RGB888_1X24,
	.field = V4L2_FIELD_NONE,
	.colorspace = V4L2_COLORSPACE_SRGB,
};

static int vimc_sensor_init_state(struct v4l2_subdev *sd,
				  struct v4l2_subdev_state *sd_state)
{
	struct vimc_sensor_device *vsensor =
		container_of(sd, struct vimc_sensor_device, sd);

	struct v4l2_mbus_framefmt *mf;

	mf = v4l2_subdev_state_get_format(sd_state, 0);
	*mf = fmt_default;
	vsensor->hw.size.width = fmt_default.width;
	vsensor->hw.size.height = fmt_default.height;

	return 0;
}

static int vimc_sensor_enum_mbus_code(struct v4l2_subdev *sd,
				      struct v4l2_subdev_state *sd_state,
				      struct v4l2_subdev_mbus_code_enum *code)
{
	u32 mbus_code = vimc_mbus_code_by_index(code->index);

	if (!mbus_code)
		return -EINVAL;

	code->code = mbus_code;

	return 0;
}

static int vimc_sensor_enum_frame_size(struct v4l2_subdev *sd,
				       struct v4l2_subdev_state *sd_state,
				       struct v4l2_subdev_frame_size_enum *fse)
{
	const struct vimc_pix_map *vpix;

	if (fse->index)
		return -EINVAL;

	/* Only accept code in the pix map table */
	vpix = vimc_pix_map_by_code(fse->code);
	if (!vpix)
		return -EINVAL;

	fse->min_width = VIMC_FRAME_MIN_WIDTH;
	fse->max_width = VIMC_FRAME_MAX_WIDTH;
	fse->min_height = VIMC_FRAME_MIN_HEIGHT;
	fse->max_height = VIMC_FRAME_MAX_HEIGHT;

	return 0;
}

static void vimc_sensor_tpg_s_format(struct vimc_sensor_device *vsensor,
				     const struct v4l2_mbus_framefmt *format)
{
	const struct vimc_pix_map *vpix = vimc_pix_map_by_code(format->code);

	tpg_reset_source(&vsensor->tpg, format->width, format->height,
			 format->field);
	tpg_s_bytesperline(&vsensor->tpg, 0, format->width * vpix->bpp);
	tpg_s_buf_height(&vsensor->tpg, format->height);
	tpg_s_fourcc(&vsensor->tpg, vpix->pixelformat);
	/* TODO: add support for V4L2_FIELD_ALTERNATE */
	tpg_s_field(&vsensor->tpg, format->field, false);
	tpg_s_colorspace(&vsensor->tpg, format->colorspace);
	tpg_s_ycbcr_enc(&vsensor->tpg, format->ycbcr_enc);
	tpg_s_quantization(&vsensor->tpg, format->quantization);
	tpg_s_xfer_func(&vsensor->tpg, format->xfer_func);
}

static int vimc_sensor_update_frame_timing(struct v4l2_subdev *sd,
					   u32 width, u32 height)
{
	struct vimc_sensor_device *vsensor =
		container_of(sd, struct vimc_sensor_device, sd);
	u64 pixel_rate = vsensor->pixel_rate->val;
	u32 hts = width + vsensor->hblank->val;
	u32 vts = height + vsensor->vblank->val;
	u64 total_pixels = (u64)hts * vts;
	u64 frame_interval_ns;

	frame_interval_ns = total_pixels * NSEC_PER_SEC;
	do_div(frame_interval_ns, pixel_rate);
	vsensor->hw.fps_jiffies = nsecs_to_jiffies(frame_interval_ns);
	if (vsensor->hw.fps_jiffies == 0)
		vsensor->hw.fps_jiffies = 1;

	return 0;
}

static void vimc_sensor_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
{
	const struct vimc_pix_map *vpix;

	/* Only accept code in the pix map table */
	vpix = vimc_pix_map_by_code(fmt->code);
	if (!vpix)
		fmt->code = fmt_default.code;

	fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
			     VIMC_FRAME_MAX_WIDTH) & ~1;
	fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
			      VIMC_FRAME_MAX_HEIGHT) & ~1;

	/* TODO: add support for V4L2_FIELD_ALTERNATE */
	if (fmt->field == V4L2_FIELD_ANY || fmt->field == V4L2_FIELD_ALTERNATE)
		fmt->field = fmt_default.field;

	vimc_colorimetry_clamp(fmt);
}

static u32 vimc_calc_vblank(u32 width, u32 height,
			    s64 pixel_rate, s32 hblank)
{
	u32 hts = width + hblank;
	u32 target_fps;
	u64 vts;

	target_fps = (width * height <= VIMC_PIXELS_THRESHOLD_30FPS) ? 30 : 10;

	vts = (u64)pixel_rate;
	do_div(vts, target_fps * hts);

	if (vts > height)
		return clamp((u32)(vts - height), VIMC_VBLANK_MIN, VIMC_VBLANK_MAX);

	return VIMC_VBLANK_MIN;
}

static int vimc_sensor_set_fmt(struct v4l2_subdev *sd,
			       struct v4l2_subdev_state *sd_state,
			       struct v4l2_subdev_format *fmt)
{
	struct vimc_sensor_device *vsensor = v4l2_get_subdevdata(sd);
	struct v4l2_mbus_framefmt *mf;

	/* Do not change the format while stream is on */
	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && vsensor->frame)
		return -EBUSY;

	mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);

	/* Set the new format */
	vimc_sensor_adjust_fmt(&fmt->format);

	dev_dbg(vsensor->ved.dev, "%s: format update: "
		"old:%dx%d (0x%x, %d, %d, %d, %d) "
		"new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsensor->sd.name,
		/* old */
		mf->width, mf->height, mf->code,
		mf->colorspace,	mf->quantization,
		mf->xfer_func, mf->ycbcr_enc,
		/* new */
		fmt->format.width, fmt->format.height, fmt->format.code,
		fmt->format.colorspace, fmt->format.quantization,
		fmt->format.xfer_func, fmt->format.ycbcr_enc);

	*mf = fmt->format;
	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
		u32 vblank_def = vimc_calc_vblank(fmt->format.width,
						  fmt->format.height,
						  vsensor->pixel_rate->val,
						  vsensor->hblank->val);
		vsensor->hw.size.width = fmt->format.width;
		vsensor->hw.size.height = fmt->format.height;
		__v4l2_ctrl_modify_range(vsensor->vblank,
					 VIMC_VBLANK_MIN,
					 VIMC_VBLANK_MAX,
					 VIMC_VBLANK_STEP,
					 vblank_def);
		__v4l2_ctrl_s_ctrl(vsensor->vblank, vblank_def);
	}

	return 0;
}

static const struct v4l2_subdev_pad_ops vimc_sensor_pad_ops = {
	.enum_mbus_code		= vimc_sensor_enum_mbus_code,
	.enum_frame_size	= vimc_sensor_enum_frame_size,
	.get_fmt		= v4l2_subdev_get_fmt,
	.set_fmt		= vimc_sensor_set_fmt,
};

static void *vimc_sensor_process_frame(struct vimc_ent_device *ved,
				       const void *sink_frame)
{
	struct vimc_sensor_device *vsensor =
		container_of(ved, struct vimc_sensor_device, ved);

	const unsigned int line_height = 16;
	u8 *basep[TPG_MAX_PLANES][2];
	unsigned int line = 1;
	char str[100];

	tpg_fill_plane_buffer(&vsensor->tpg, 0, 0, vsensor->frame);
	tpg_calc_text_basep(&vsensor->tpg, basep, 0, vsensor->frame);
	switch (vsensor->hw.osd_value) {
	case VIMC_SENSOR_OSD_SHOW_ALL: {
		const char *order = tpg_g_color_order(&vsensor->tpg);

		tpg_gen_text(&vsensor->tpg, basep, line++ * line_height,
			     16, order);
		snprintf(str, sizeof(str),
			 "brightness %3d, contrast %3d, saturation %3d, hue %d ",
			 vsensor->tpg.brightness,
			 vsensor->tpg.contrast,
			 vsensor->tpg.saturation,
			 vsensor->tpg.hue);
		tpg_gen_text(&vsensor->tpg, basep, line++ * line_height, 16, str);
		snprintf(str, sizeof(str), "sensor size: %dx%d",
			 vsensor->hw.size.width, vsensor->hw.size.height);
		tpg_gen_text(&vsensor->tpg, basep, line++ * line_height, 16, str);
		fallthrough;
	}
	case VIMC_SENSOR_OSD_SHOW_COUNTERS: {
		unsigned int ms;

		ms = div_u64(ktime_get_ns() - vsensor->hw.start_stream_ts, 1000000);
		snprintf(str, sizeof(str), "%02d:%02d:%02d:%03d",
			 (ms / (60 * 60 * 1000)) % 24,
			 (ms / (60 * 1000)) % 60,
			 (ms / 1000) % 60,
			 ms % 1000);
		tpg_gen_text(&vsensor->tpg, basep, line++ * line_height, 16, str);
		break;
	}
	case VIMC_SENSOR_OSD_SHOW_NONE:
	default:
		break;
	}

	return vsensor->frame;
}

static int vimc_sensor_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct vimc_sensor_device *vsensor =
				container_of(sd, struct vimc_sensor_device, sd);

	if (enable) {
		const struct v4l2_mbus_framefmt *format;
		struct v4l2_subdev_state *state;
		const struct vimc_pix_map *vpix;
		unsigned int frame_size;

		state = v4l2_subdev_lock_and_get_active_state(sd);
		format = v4l2_subdev_state_get_format(state, 0);

		/* Configure the test pattern generator. */
		vimc_sensor_tpg_s_format(vsensor, format);

		/* Calculate the frame size. */
		vpix = vimc_pix_map_by_code(format->code);
		frame_size = format->width * vpix->bpp * format->height;

		vsensor->hw.size.width = format->width;
		vsensor->hw.size.height = format->height;
		vimc_sensor_update_frame_timing(sd, format->width,
						format->height);

		v4l2_subdev_unlock_state(state);

		/*
		 * Allocate the frame buffer. Use vmalloc to be able to
		 * allocate a large amount of memory
		 */
		vsensor->frame = vmalloc(frame_size);
		if (!vsensor->frame)
			return -ENOMEM;

		vsensor->hw.start_stream_ts = ktime_get_ns();
	} else {

		vfree(vsensor->frame);
		vsensor->frame = NULL;
	}

	return 0;
}

static const struct v4l2_subdev_core_ops vimc_sensor_core_ops = {
	.log_status = v4l2_ctrl_subdev_log_status,
	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
};

static const struct v4l2_subdev_video_ops vimc_sensor_video_ops = {
	.s_stream = vimc_sensor_s_stream,
};

static const struct v4l2_subdev_ops vimc_sensor_ops = {
	.core = &vimc_sensor_core_ops,
	.pad = &vimc_sensor_pad_ops,
	.video = &vimc_sensor_video_ops,
};

static const struct v4l2_subdev_internal_ops vimc_sensor_internal_ops = {
	.init_state = vimc_sensor_init_state,
};

static int vimc_sensor_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct vimc_sensor_device *vsensor =
		container_of(ctrl->handler, struct vimc_sensor_device, hdl);

	switch (ctrl->id) {
	case VIMC_CID_TEST_PATTERN:
		tpg_s_pattern(&vsensor->tpg, ctrl->val);
		break;
	case V4L2_CID_HFLIP:
		tpg_s_hflip(&vsensor->tpg, ctrl->val);
		break;
	case V4L2_CID_VFLIP:
		tpg_s_vflip(&vsensor->tpg, ctrl->val);
		break;
	case V4L2_CID_BRIGHTNESS:
		tpg_s_brightness(&vsensor->tpg, ctrl->val);
		break;
	case V4L2_CID_CONTRAST:
		tpg_s_contrast(&vsensor->tpg, ctrl->val);
		break;
	case V4L2_CID_HUE:
		tpg_s_hue(&vsensor->tpg, ctrl->val);
		break;
	case V4L2_CID_SATURATION:
		tpg_s_saturation(&vsensor->tpg, ctrl->val);
		break;
	case VIMC_CID_OSD_TEXT_MODE:
		vsensor->hw.osd_value = ctrl->val;
		break;
	case V4L2_CID_PIXEL_RATE:
		break;
	case V4L2_CID_HBLANK:
		break;
	case V4L2_CID_VBLANK:
		vimc_sensor_update_frame_timing(&vsensor->sd,
						vsensor->hw.size.width,
						vsensor->hw.size.height);
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static const struct v4l2_ctrl_ops vimc_sensor_ctrl_ops = {
	.s_ctrl = vimc_sensor_s_ctrl,
};

static void vimc_sensor_release(struct vimc_ent_device *ved)
{
	struct vimc_sensor_device *vsensor =
		container_of(ved, struct vimc_sensor_device, ved);

	v4l2_ctrl_handler_free(&vsensor->hdl);
	tpg_free(&vsensor->tpg);
	v4l2_subdev_cleanup(&vsensor->sd);
	media_entity_cleanup(vsensor->ved.ent);
	kfree(vsensor);
}

/* Image Processing Controls */
static const struct v4l2_ctrl_config vimc_sensor_ctrl_class = {
	.flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
	.id = VIMC_CID_VIMC_CLASS,
	.name = "VIMC Controls",
	.type = V4L2_CTRL_TYPE_CTRL_CLASS,
};

static const struct v4l2_ctrl_config vimc_sensor_ctrl_test_pattern = {
	.ops = &vimc_sensor_ctrl_ops,
	.id = VIMC_CID_TEST_PATTERN,
	.name = "Test Pattern",
	.type = V4L2_CTRL_TYPE_MENU,
	.max = TPG_PAT_NOISE,
	.qmenu = tpg_pattern_strings,
};

static const char * const vimc_ctrl_osd_mode_strings[] = {
	"All",
	"Counters Only",
	"None",
	NULL,
};

static const struct v4l2_ctrl_config vimc_sensor_ctrl_osd_mode = {
	.ops = &vimc_sensor_ctrl_ops,
	.id = VIMC_CID_OSD_TEXT_MODE,
	.name = "Show Information",
	.type = V4L2_CTRL_TYPE_MENU,
	.max = ARRAY_SIZE(vimc_ctrl_osd_mode_strings) - 2,
	.qmenu = vimc_ctrl_osd_mode_strings,
};

static struct vimc_ent_device *vimc_sensor_add(struct vimc_device *vimc,
					       const char *vcfg_name)
{
	struct v4l2_device *v4l2_dev = &vimc->v4l2_dev;
	struct vimc_sensor_device *vsensor;
	int ret;

	/* Allocate the vsensor struct */
	vsensor = kzalloc_obj(*vsensor);
	if (!vsensor)
		return ERR_PTR(-ENOMEM);

	v4l2_ctrl_handler_init(&vsensor->hdl, 4);

	v4l2_ctrl_new_custom(&vsensor->hdl, &vimc_sensor_ctrl_class, NULL);
	v4l2_ctrl_new_custom(&vsensor->hdl, &vimc_sensor_ctrl_test_pattern, NULL);
	v4l2_ctrl_new_custom(&vsensor->hdl, &vimc_sensor_ctrl_osd_mode, NULL);
	v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,
			  V4L2_CID_VFLIP, 0, 1, 1, 0);
	v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,
			  V4L2_CID_HFLIP, 0, 1, 1, 0);
	v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,
			  V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
	v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,
			  V4L2_CID_CONTRAST, 0, 255, 1, 128);
	v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,
			  V4L2_CID_HUE, -128, 127, 1, 0);
	v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,
			  V4L2_CID_SATURATION, 0, 255, 1, 128);
	/* Timing controls for frame interval configuration */
	vsensor->pixel_rate = v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,
						V4L2_CID_PIXEL_RATE,
						VIMC_PIXEL_RATE_FIXED, VIMC_PIXEL_RATE_FIXED,
						1, VIMC_PIXEL_RATE_FIXED);
	if (vsensor->pixel_rate)
		vsensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;

	vsensor->hblank = v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,
					    V4L2_CID_HBLANK,
					    VIMC_HBLANK_FIXED, VIMC_HBLANK_FIXED,
					    1, VIMC_HBLANK_FIXED);
	if (vsensor->hblank)
		vsensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;

	vsensor->vblank = v4l2_ctrl_new_std(&vsensor->hdl, &vimc_sensor_ctrl_ops,
					    V4L2_CID_VBLANK,
					    VIMC_VBLANK_MIN, VIMC_VBLANK_MAX,
					    VIMC_VBLANK_STEP, VIMC_VBLANK_DEFAULT);

	vsensor->sd.ctrl_handler = &vsensor->hdl;
	if (vsensor->hdl.error) {
		ret = vsensor->hdl.error;
		goto err_free_vsensor;
	}

	/* Initialize the test pattern generator */
	tpg_init(&vsensor->tpg, fmt_default.width, fmt_default.height);
	ret = tpg_alloc(&vsensor->tpg, VIMC_FRAME_MAX_WIDTH);
	if (ret)
		goto err_free_hdl;

	/* Initialize ved and sd */
	vsensor->pad.flags = MEDIA_PAD_FL_SOURCE;
	ret = vimc_ent_sd_register(&vsensor->ved, &vsensor->sd, v4l2_dev,
				   vcfg_name,
				   MEDIA_ENT_F_CAM_SENSOR, 1, &vsensor->pad,
				   &vimc_sensor_internal_ops, &vimc_sensor_ops);
	if (ret)
		goto err_free_tpg;

	vsensor->ved.process_frame = vimc_sensor_process_frame;
	vsensor->ved.dev = vimc->mdev.dev;

	return &vsensor->ved;

err_free_tpg:
	tpg_free(&vsensor->tpg);
err_free_hdl:
	v4l2_ctrl_handler_free(&vsensor->hdl);
err_free_vsensor:
	kfree(vsensor);

	return ERR_PTR(ret);
}

const struct vimc_ent_type vimc_sensor_type = {
	.add = vimc_sensor_add,
	.release = vimc_sensor_release
};
