// SPDX-License-Identifier: GPL-2.0
/*
 * stf_camss.c
 *
 * Starfive Camera Subsystem driver
 *
 * Copyright (C) 2021-2023 StarFive Technology Co., Ltd.
 *
 * Author: Jack Zhu <jack.zhu@starfivetech.com>
 * Author: Changhuang Liang <changhuang.liang@starfivetech.com>
 *
 */
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/videodev2.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mc.h>

#include "stf-camss.h"

static const char * const stfcamss_clocks[] = {
	"wrapper_clk_c",
	"ispcore_2x",
	"isp_axi",
};

static const char * const stfcamss_resets[] = {
	"wrapper_p",
	"wrapper_c",
	"axiwr",
	"isp_top_n",
	"isp_top_axi",
};

static const struct stf_isr_data stf_isrs[] = {
	{"wr_irq", stf_wr_irq_handler},
	{"isp_irq", stf_isp_irq_handler},
	{"line_irq", stf_line_irq_handler},
};

static int stfcamss_get_mem_res(struct stfcamss *stfcamss)
{
	struct platform_device *pdev = to_platform_device(stfcamss->dev);

	stfcamss->syscon_base =
		devm_platform_ioremap_resource_byname(pdev, "syscon");
	if (IS_ERR(stfcamss->syscon_base))
		return PTR_ERR(stfcamss->syscon_base);

	stfcamss->isp_base = devm_platform_ioremap_resource_byname(pdev, "isp");
	if (IS_ERR(stfcamss->isp_base))
		return PTR_ERR(stfcamss->isp_base);

	return 0;
}

/*
 * stfcamss_of_parse_endpoint_node - Parse port endpoint node
 * @dev: Device
 * @node: Device node to be parsed
 * @csd: Parsed data from port endpoint node
 *
 * Return 0 on success or a negative error code on failure
 */
static int stfcamss_of_parse_endpoint_node(struct stfcamss *stfcamss,
					   struct device_node *node,
					   struct stfcamss_async_subdev *csd)
{
	struct v4l2_fwnode_endpoint vep = { { 0 } };
	int ret;

	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
	if (ret) {
		dev_err(stfcamss->dev, "endpoint not defined at %pOF\n", node);
		return ret;
	}

	csd->port = vep.base.port;

	return 0;
}

/*
 * stfcamss_of_parse_ports - Parse ports node
 * @stfcamss: STFCAMSS device
 *
 * Return number of "port" nodes found in "ports" node
 */
static int stfcamss_of_parse_ports(struct stfcamss *stfcamss)
{
	struct device_node *node = NULL;
	int ret, num_subdevs = 0;

	for_each_endpoint_of_node(stfcamss->dev->of_node, node) {
		struct stfcamss_async_subdev *csd;

		if (!of_device_is_available(node))
			continue;

		csd = v4l2_async_nf_add_fwnode_remote(&stfcamss->notifier,
						      of_fwnode_handle(node),
						      struct stfcamss_async_subdev);
		if (IS_ERR(csd)) {
			ret = PTR_ERR(csd);
			dev_err(stfcamss->dev, "failed to add async notifier\n");
			goto err_cleanup;
		}

		ret = stfcamss_of_parse_endpoint_node(stfcamss, node, csd);
		if (ret)
			goto err_cleanup;

		num_subdevs++;
	}

	return num_subdevs;

err_cleanup:
	of_node_put(node);
	return ret;
}

static int stfcamss_register_devs(struct stfcamss *stfcamss)
{
	struct stf_capture *cap_yuv = &stfcamss->captures[STF_CAPTURE_YUV];
	struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
	int ret;

	ret = stf_isp_register(isp_dev, &stfcamss->v4l2_dev);
	if (ret < 0) {
		dev_err(stfcamss->dev,
			"failed to register stf isp%d entity: %d\n", 0, ret);
		return ret;
	}

	ret = stf_capture_register(stfcamss, &stfcamss->v4l2_dev);
	if (ret < 0) {
		dev_err(stfcamss->dev,
			"failed to register capture: %d\n", ret);
		goto err_isp_unregister;
	}

	ret = media_create_pad_link(&isp_dev->subdev.entity, STF_ISP_PAD_SRC,
				    &cap_yuv->video.vdev.entity, 0, 0);
	if (ret)
		goto err_cap_unregister;

	cap_yuv->video.source_subdev = &isp_dev->subdev;

	return ret;

err_cap_unregister:
	stf_capture_unregister(stfcamss);
err_isp_unregister:
	stf_isp_unregister(&stfcamss->isp_dev);

	return ret;
}

static void stfcamss_unregister_devs(struct stfcamss *stfcamss)
{
	stf_isp_unregister(&stfcamss->isp_dev);
	stf_capture_unregister(stfcamss);
}

static int stfcamss_subdev_notifier_bound(struct v4l2_async_notifier *async,
					  struct v4l2_subdev *subdev,
					  struct v4l2_async_connection *asc)
{
	struct stfcamss *stfcamss =
		container_of(async, struct stfcamss, notifier);
	struct stfcamss_async_subdev *csd =
		container_of(asc, struct stfcamss_async_subdev, asd);
	enum stf_port_num port = csd->port;
	struct stf_isp_dev *isp_dev = &stfcamss->isp_dev;
	struct stf_capture *cap_raw = &stfcamss->captures[STF_CAPTURE_RAW];
	struct media_pad *pad;
	int ret;

	if (port == STF_PORT_CSI2RX) {
		pad = &isp_dev->pads[STF_ISP_PAD_SINK];
	} else {
		dev_err(stfcamss->dev, "not support port %d\n", port);
		return -EPERM;
	}

	ret = v4l2_create_fwnode_links_to_pad(subdev, pad, 0);
	if (ret)
		return ret;

	ret = media_create_pad_link(&subdev->entity, 1,
				    &cap_raw->video.vdev.entity, 0, 0);
	if (ret)
		return ret;

	isp_dev->source_subdev = subdev;
	cap_raw->video.source_subdev = subdev;

	return 0;
}

static int stfcamss_subdev_notifier_complete(struct v4l2_async_notifier *ntf)
{
	struct stfcamss *stfcamss =
		container_of(ntf, struct stfcamss, notifier);

	return v4l2_device_register_subdev_nodes(&stfcamss->v4l2_dev);
}

static const struct v4l2_async_notifier_operations
stfcamss_subdev_notifier_ops = {
	.bound = stfcamss_subdev_notifier_bound,
	.complete = stfcamss_subdev_notifier_complete,
};

static void stfcamss_mc_init(struct platform_device *pdev,
			     struct stfcamss *stfcamss)
{
	stfcamss->media_dev.dev = stfcamss->dev;
	strscpy(stfcamss->media_dev.model, "Starfive Camera Subsystem",
		sizeof(stfcamss->media_dev.model));
	media_device_init(&stfcamss->media_dev);

	stfcamss->v4l2_dev.mdev = &stfcamss->media_dev;
}

/*
 * stfcamss_probe - Probe STFCAMSS platform device
 * @pdev: Pointer to STFCAMSS platform device
 *
 * Return 0 on success or a negative error code on failure
 */
static int stfcamss_probe(struct platform_device *pdev)
{
	struct stfcamss *stfcamss;
	struct device *dev = &pdev->dev;
	int ret, num_subdevs;
	unsigned int i;

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

	stfcamss->dev = dev;

	for (i = 0; i < ARRAY_SIZE(stf_isrs); ++i) {
		int irq;

		irq = platform_get_irq(pdev, i);
		if (irq < 0)
			return irq;

		ret = devm_request_irq(stfcamss->dev, irq, stf_isrs[i].isr, 0,
				       stf_isrs[i].name, stfcamss);
		if (ret) {
			dev_err(dev, "request irq failed: %d\n", ret);
			return ret;
		}
	}

	stfcamss->nclks = ARRAY_SIZE(stfcamss->sys_clk);
	for (i = 0; i < stfcamss->nclks; ++i)
		stfcamss->sys_clk[i].id = stfcamss_clocks[i];
	ret = devm_clk_bulk_get(dev, stfcamss->nclks, stfcamss->sys_clk);
	if (ret) {
		dev_err(dev, "Failed to get clk controls\n");
		return ret;
	}

	stfcamss->nrsts = ARRAY_SIZE(stfcamss->sys_rst);
	for (i = 0; i < stfcamss->nrsts; ++i)
		stfcamss->sys_rst[i].id = stfcamss_resets[i];
	ret = devm_reset_control_bulk_get_shared(dev, stfcamss->nrsts,
						 stfcamss->sys_rst);
	if (ret) {
		dev_err(dev, "Failed to get reset controls\n");
		return ret;
	}

	ret = stfcamss_get_mem_res(stfcamss);
	if (ret) {
		dev_err(dev, "Could not map registers\n");
		return ret;
	}

	platform_set_drvdata(pdev, stfcamss);

	v4l2_async_nf_init(&stfcamss->notifier, &stfcamss->v4l2_dev);

	num_subdevs = stfcamss_of_parse_ports(stfcamss);
	if (num_subdevs < 0) {
		ret = -ENODEV;
		dev_err(dev, "Failed to get sub devices: %d\n", ret);
		goto err_cleanup_notifier;
	}

	ret = stf_isp_init(stfcamss);
	if (ret < 0) {
		dev_err(dev, "Failed to init isp: %d\n", ret);
		goto err_cleanup_notifier;
	}

	stfcamss_mc_init(pdev, stfcamss);

	ret = v4l2_device_register(stfcamss->dev, &stfcamss->v4l2_dev);
	if (ret < 0) {
		dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
		goto err_cleanup_media_device;
	}

	ret = media_device_register(&stfcamss->media_dev);
	if (ret) {
		dev_err(dev, "Failed to register media device: %d\n", ret);
		goto err_unregister_device;
	}

	ret = stfcamss_register_devs(stfcamss);
	if (ret < 0) {
		dev_err(dev, "Failed to register subdevice: %d\n", ret);
		goto err_unregister_media_dev;
	}

	pm_runtime_enable(dev);

	stfcamss->notifier.ops = &stfcamss_subdev_notifier_ops;
	ret = v4l2_async_nf_register(&stfcamss->notifier);
	if (ret) {
		dev_err(dev, "Failed to register async subdev nodes: %d\n",
			ret);
		pm_runtime_disable(dev);
		goto err_unregister_subdevs;
	}

	return 0;

err_unregister_subdevs:
	stfcamss_unregister_devs(stfcamss);
err_unregister_media_dev:
	media_device_unregister(&stfcamss->media_dev);
err_unregister_device:
	v4l2_device_unregister(&stfcamss->v4l2_dev);
err_cleanup_media_device:
	media_device_cleanup(&stfcamss->media_dev);
err_cleanup_notifier:
	v4l2_async_nf_cleanup(&stfcamss->notifier);
	return ret;
}

/*
 * stfcamss_remove - Remove STFCAMSS platform device
 * @pdev: Pointer to STFCAMSS platform device
 *
 * Always returns 0.
 */
static int stfcamss_remove(struct platform_device *pdev)
{
	struct stfcamss *stfcamss = platform_get_drvdata(pdev);

	stfcamss_unregister_devs(stfcamss);
	v4l2_device_unregister(&stfcamss->v4l2_dev);
	media_device_cleanup(&stfcamss->media_dev);
	v4l2_async_nf_cleanup(&stfcamss->notifier);
	pm_runtime_disable(&pdev->dev);

	return 0;
}

static const struct of_device_id stfcamss_of_match[] = {
	{ .compatible = "starfive,jh7110-camss" },
	{ /* sentinel */ },
};

MODULE_DEVICE_TABLE(of, stfcamss_of_match);

static int __maybe_unused stfcamss_runtime_suspend(struct device *dev)
{
	struct stfcamss *stfcamss = dev_get_drvdata(dev);
	int ret;

	ret = reset_control_bulk_assert(stfcamss->nrsts, stfcamss->sys_rst);
	if (ret) {
		dev_err(dev, "reset assert failed\n");
		return ret;
	}

	clk_bulk_disable_unprepare(stfcamss->nclks, stfcamss->sys_clk);

	return 0;
}

static int __maybe_unused stfcamss_runtime_resume(struct device *dev)
{
	struct stfcamss *stfcamss = dev_get_drvdata(dev);
	int ret;

	ret = clk_bulk_prepare_enable(stfcamss->nclks, stfcamss->sys_clk);
	if (ret) {
		dev_err(dev, "clock prepare enable failed\n");
		return ret;
	}

	ret = reset_control_bulk_deassert(stfcamss->nrsts, stfcamss->sys_rst);
	if (ret < 0) {
		dev_err(dev, "cannot deassert resets\n");
		clk_bulk_disable_unprepare(stfcamss->nclks, stfcamss->sys_clk);
		return ret;
	}

	return 0;
}

static const struct dev_pm_ops stfcamss_pm_ops = {
	SET_RUNTIME_PM_OPS(stfcamss_runtime_suspend,
			   stfcamss_runtime_resume,
			   NULL)
};

static struct platform_driver stfcamss_driver = {
	.probe = stfcamss_probe,
	.remove = stfcamss_remove,
	.driver = {
		.name = "starfive-camss",
		.pm = &stfcamss_pm_ops,
		.of_match_table = stfcamss_of_match,
	},
};

module_platform_driver(stfcamss_driver);

MODULE_AUTHOR("Jack Zhu <jack.zhu@starfivetech.com>");
MODULE_AUTHOR("Changhuang Liang <changhuang.liang@starfivetech.com>");
MODULE_DESCRIPTION("StarFive Camera Subsystem driver");
MODULE_LICENSE("GPL");
