// SPDX-License-Identifier: GPL-2.0
/*
 * Support for Medifield PNW Camera Imaging ISP subsystem.
 *
 * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
 *
 * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *
 */

#include <media/v4l2-event.h>
#include <media/v4l2-mediabus.h>

#include <media/videobuf-vmalloc.h>
#include <linux/delay.h>

#include "ia_css.h"

#include "atomisp_cmd.h"
#include "atomisp_common.h"
#include "atomisp_file.h"
#include "atomisp_internal.h"
#include "atomisp_ioctl.h"

static void file_work(struct work_struct *work)
{
	struct atomisp_file_device *file_dev =
	    container_of(work, struct atomisp_file_device, work);
	struct atomisp_device *isp = file_dev->isp;
	/* only support file injection on subdev0 */
	struct atomisp_sub_device *asd = &isp->asd[0];
	struct atomisp_video_pipe *out_pipe = &asd->video_in;
	unsigned short *buf = videobuf_to_vmalloc(out_pipe->outq.bufs[0]);
	struct v4l2_mbus_framefmt isp_sink_fmt;

	if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED)
		return;

	dev_dbg(isp->dev, ">%s: ready to start streaming\n", __func__);
	isp_sink_fmt = *atomisp_subdev_get_ffmt(&asd->subdev, NULL,
						V4L2_SUBDEV_FORMAT_ACTIVE,
						ATOMISP_SUBDEV_PAD_SINK);

	while (!ia_css_isp_has_started())
		usleep_range(1000, 1500);

	ia_css_stream_send_input_frame(asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
				       buf, isp_sink_fmt.width,
				       isp_sink_fmt.height);
	dev_dbg(isp->dev, "<%s: streaming done\n", __func__);
}

static int file_input_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct atomisp_file_device *file_dev = v4l2_get_subdevdata(sd);
	struct atomisp_device *isp = file_dev->isp;
	/* only support file injection on subdev0 */
	struct atomisp_sub_device *asd = &isp->asd[0];

	dev_dbg(isp->dev, "%s: enable %d\n", __func__, enable);
	if (enable) {
		if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED)
			return 0;

		queue_work(file_dev->work_queue, &file_dev->work);
		return 0;
	}
	cancel_work_sync(&file_dev->work);
	return 0;
}

static int file_input_get_fmt(struct v4l2_subdev *sd,
			      struct v4l2_subdev_pad_config *cfg,
			      struct v4l2_subdev_format *format)
{
	struct v4l2_mbus_framefmt *fmt = &format->format;
	struct atomisp_file_device *file_dev = v4l2_get_subdevdata(sd);
	struct atomisp_device *isp = file_dev->isp;
	/* only support file injection on subdev0 */
	struct atomisp_sub_device *asd = &isp->asd[0];
	struct v4l2_mbus_framefmt *isp_sink_fmt;

	if (format->pad)
		return -EINVAL;
	isp_sink_fmt = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
					       V4L2_SUBDEV_FORMAT_ACTIVE,
					       ATOMISP_SUBDEV_PAD_SINK);

	fmt->width = isp_sink_fmt->width;
	fmt->height = isp_sink_fmt->height;
	fmt->code = isp_sink_fmt->code;

	return 0;
}

static int file_input_set_fmt(struct v4l2_subdev *sd,
			      struct v4l2_subdev_pad_config *cfg,
			      struct v4l2_subdev_format *format)
{
	struct v4l2_mbus_framefmt *fmt = &format->format;

	if (format->pad)
		return -EINVAL;
	file_input_get_fmt(sd, cfg, format);
	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
		cfg->try_fmt = *fmt;
	return 0;
}

static int file_input_log_status(struct v4l2_subdev *sd)
{
	/*to fake*/
	return 0;
}

static int file_input_s_power(struct v4l2_subdev *sd, int on)
{
	/* to fake */
	return 0;
}

static int file_input_enum_mbus_code(struct v4l2_subdev *sd,
				     struct v4l2_subdev_pad_config *cfg,
				     struct v4l2_subdev_mbus_code_enum *code)
{
	/*to fake*/
	return 0;
}

static int file_input_enum_frame_size(struct v4l2_subdev *sd,
				      struct v4l2_subdev_pad_config *cfg,
				      struct v4l2_subdev_frame_size_enum *fse)
{
	/*to fake*/
	return 0;
}

static int file_input_enum_frame_ival(struct v4l2_subdev *sd,
				      struct v4l2_subdev_pad_config *cfg,
				      struct v4l2_subdev_frame_interval_enum
				      *fie)
{
	/*to fake*/
	return 0;
}

static const struct v4l2_subdev_video_ops file_input_video_ops = {
	.s_stream = file_input_s_stream,
};

static const struct v4l2_subdev_core_ops file_input_core_ops = {
	.log_status = file_input_log_status,
	.s_power = file_input_s_power,
};

static const struct v4l2_subdev_pad_ops file_input_pad_ops = {
	.enum_mbus_code = file_input_enum_mbus_code,
	.enum_frame_size = file_input_enum_frame_size,
	.enum_frame_interval = file_input_enum_frame_ival,
	.get_fmt = file_input_get_fmt,
	.set_fmt = file_input_set_fmt,
};

static const struct v4l2_subdev_ops file_input_ops = {
	.core = &file_input_core_ops,
	.video = &file_input_video_ops,
	.pad = &file_input_pad_ops,
};

void
atomisp_file_input_unregister_entities(struct atomisp_file_device *file_dev)
{
	media_entity_cleanup(&file_dev->sd.entity);
	v4l2_device_unregister_subdev(&file_dev->sd);
}

int atomisp_file_input_register_entities(struct atomisp_file_device *file_dev,
	struct v4l2_device *vdev)
{
	/* Register the subdev and video nodes. */
	return  v4l2_device_register_subdev(vdev, &file_dev->sd);
}

void atomisp_file_input_cleanup(struct atomisp_device *isp)
{
	struct atomisp_file_device *file_dev = &isp->file_dev;

	if (file_dev->work_queue) {
		destroy_workqueue(file_dev->work_queue);
		file_dev->work_queue = NULL;
	}
}

int atomisp_file_input_init(struct atomisp_device *isp)
{
	struct atomisp_file_device *file_dev = &isp->file_dev;
	struct v4l2_subdev *sd = &file_dev->sd;
	struct media_pad *pads = file_dev->pads;
	struct media_entity *me = &sd->entity;

	file_dev->isp = isp;
	file_dev->work_queue = alloc_workqueue(isp->v4l2_dev.name, 0, 1);
	if (!file_dev->work_queue) {
		dev_err(isp->dev, "Failed to initialize file inject workq\n");
		return -ENOMEM;
	}

	INIT_WORK(&file_dev->work, file_work);

	v4l2_subdev_init(sd, &file_input_ops);
	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	strscpy(sd->name, "file_input_subdev", sizeof(sd->name));
	v4l2_set_subdevdata(sd, file_dev);

	pads[0].flags = MEDIA_PAD_FL_SINK;
	me->function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;

	return media_entity_pads_init(me, 1, pads);
}
