// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 * Copyright 2017-2018 NXP
 *	Dong Aisheng <aisheng.dong@nxp.com>
 */

#include <linux/err.h>
#include <linux/firmware/imx/sci.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>

#include "../core.h"
#include "pinctrl-imx.h"

#define IMX_SC_PAD_FUNC_GET_WAKEUP	9
#define IMX_SC_PAD_FUNC_SET_WAKEUP	4
#define IMX_SC_IRQ_GROUP_WAKE           3   /* Wakeup interrupts */
#define IMX_SC_IRQ_PAD			2   /* Pad wakeup */

enum pad_func_e {
	IMX_SC_PAD_FUNC_SET = 15,
	IMX_SC_PAD_FUNC_GET = 16,
};

struct imx_sc_msg_req_pad_set {
	struct imx_sc_rpc_msg hdr;
	u32 val;
	u16 pad;
} __packed __aligned(4);

struct imx_sc_msg_req_pad_get {
	struct imx_sc_rpc_msg hdr;
	u16 pad;
} __packed __aligned(4);

struct imx_sc_msg_resp_pad_get {
	struct imx_sc_rpc_msg hdr;
	u32 val;
} __packed;

struct imx_sc_msg_gpio_set_pad_wakeup {
	struct imx_sc_rpc_msg hdr;
	u16 pad;
	u8 wakeup;
} __packed __aligned(4);

static struct imx_sc_ipc *pinctrl_ipc_handle;

int imx_pinctrl_sc_ipc_init(struct platform_device *pdev)
{
	imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_WAKE,
					 IMX_SC_IRQ_PAD, true);
	return imx_scu_get_handle(&pinctrl_ipc_handle);
}
EXPORT_SYMBOL_GPL(imx_pinctrl_sc_ipc_init);

int imx_pinconf_get_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
			unsigned long *config)
{
	struct imx_sc_msg_req_pad_get msg;
	struct imx_sc_msg_resp_pad_get *resp;
	struct imx_sc_rpc_msg *hdr = &msg.hdr;
	int ret;

	hdr->ver = IMX_SC_RPC_VERSION;
	hdr->svc = IMX_SC_RPC_SVC_PAD;
	hdr->func = IMX_SC_PAD_FUNC_GET;
	hdr->size = 2;

	msg.pad = pin_id;

	ret = imx_scu_call_rpc(pinctrl_ipc_handle, &msg, true);
	if (ret)
		return ret;

	resp = (struct imx_sc_msg_resp_pad_get *)&msg;
	*config = resp->val;

	return 0;
}
EXPORT_SYMBOL_GPL(imx_pinconf_get_scu);

int imx_pinconf_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
			unsigned long *configs, unsigned num_configs)
{
	struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
	struct imx_sc_msg_req_pad_set msg;
	struct imx_sc_rpc_msg *hdr = &msg.hdr;
	unsigned int mux = configs[0];
	unsigned int conf;
	unsigned int val;
	int ret;

	if (num_configs == 1) {
		struct imx_sc_msg_gpio_set_pad_wakeup wmsg;

		hdr = &wmsg.hdr;
		hdr->ver = IMX_SC_RPC_VERSION;
		hdr->svc = IMX_SC_RPC_SVC_PAD;
		hdr->func = IMX_SC_PAD_FUNC_SET_WAKEUP;
		hdr->size = 2;
		wmsg.pad = pin_id;
		wmsg.wakeup = *configs;
		ret = imx_scu_call_rpc(pinctrl_ipc_handle, &wmsg, true);

		dev_dbg(ipctl->dev, "wakeup pin_id: %d type: %ld\n",
				pin_id, *configs);
		return ret;
	}

	/*
	 * Set mux and conf together in one IPC call
	 */
	WARN_ON(num_configs != 2);
	conf = configs[1];

	val = conf | BM_PAD_CTL_IFMUX_ENABLE | BM_PAD_CTL_GP_ENABLE;
	val |= mux << BP_PAD_CTL_IFMUX;

	hdr->ver = IMX_SC_RPC_VERSION;
	hdr->svc = IMX_SC_RPC_SVC_PAD;
	hdr->func = IMX_SC_PAD_FUNC_SET;
	hdr->size = 3;

	msg.pad = pin_id;
	msg.val = val;

	ret = imx_scu_call_rpc(pinctrl_ipc_handle, &msg, true);

	dev_dbg(ipctl->dev, "write: pin_id %u config 0x%x val 0x%x\n",
		pin_id, conf, val);

	return ret;
}
EXPORT_SYMBOL_GPL(imx_pinconf_set_scu);

void imx_pinctrl_parse_pin_scu(struct imx_pinctrl *ipctl,
			       unsigned int *pin_id, struct imx_pin *pin,
			       const __be32 **list_p)
{
	const struct imx_pinctrl_soc_info *info = ipctl->info;
	struct imx_pin_scu *pin_scu = &pin->conf.scu;
	const __be32 *list = *list_p;

	pin->pin = be32_to_cpu(*list++);
	*pin_id = pin->pin;
	pin_scu->mux_mode = be32_to_cpu(*list++);
	pin_scu->config = be32_to_cpu(*list++);
	*list_p = list;

	dev_dbg(ipctl->dev, "%s: 0x%x 0x%08lx", info->pins[pin->pin].name,
		pin_scu->mux_mode, pin_scu->config);
}
EXPORT_SYMBOL_GPL(imx_pinctrl_parse_pin_scu);

MODULE_AUTHOR("Dong Aisheng <aisheng.dong@nxp.com>");
MODULE_DESCRIPTION("NXP i.MX SCU common pinctrl driver");
MODULE_LICENSE("GPL v2");
