/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 * Copyright 2017 NXP
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * 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 <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/slab.h>
#include <soc/imx8/sc/sci.h>

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

sc_ipc_t pinctrl_ipcHandle;

int imx_pmx_set_one_pin_scu(struct imx_pinctrl *ipctl, struct imx_pin *pin)
{
	return 0;
}

int imx_pmx_backend_gpio_request_enable_scu(struct pinctrl_dev *pctldev,
			struct pinctrl_gpio_range *range, unsigned offset)
{
	return -EINVAL;
}

void imx_pmx_backend_gpio_disable_free_scu(struct pinctrl_dev *pctldev,
				       struct pinctrl_gpio_range *range,
				       unsigned offset)
{
}

int imx_pmx_backend_gpio_set_direction_scu(struct pinctrl_dev *pctldev,
	   struct pinctrl_gpio_range *range, unsigned offset, bool input)
{
	return -EINVAL;
}

int imx_pinconf_backend_get_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
			    unsigned long *config)
{
	sc_err_t err = SC_ERR_NONE;
	sc_ipc_t ipc = pinctrl_ipcHandle;

	if (ipc == -1) {
		printk("IPC handle not initialized!\n");
		return -EIO;
	}

	err = sc_pad_get(ipc, pin_id, (unsigned int *)config);

	if (err != SC_ERR_NONE)
		return -EIO;

	return 0;
}

int imx_pinconf_backend_set_scu(struct pinctrl_dev *pctldev, unsigned pin_id,
			    unsigned long *configs, unsigned num_configs)
{
	sc_err_t err = SC_ERR_NONE;
	sc_ipc_t ipc = pinctrl_ipcHandle;
	struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
	const struct imx_pinctrl_soc_info *info = ipctl->info;
	/*
	 * Mux should be done in pmx set, but we do not have a good api
	 * to handle that in scfw, so config it in pad conf func
	 */
	unsigned int mux = configs[0];
	unsigned int val = configs[1];

	if (ipc == -1) {
		printk("IPC handle not initialized!\n");
		return -EIO;
	}

	if (info->flags & IMX8_ENABLE_MUX_CONFIG)
		val |= BM_IMX8_IFMUX_ENABLE;

	if (info->flags & IMX8_ENABLE_PAD_CONFIG)
		val |= BM_IMX8_GP_ENABLE;

	if (info->flags & SHARE_MUX_CONF_REG) {
		val |= (mux << 27) & (0x7 << 27);
		err = sc_pad_set(ipc, pin_id, val);
	}

	if (err != SC_ERR_NONE)
		return -EIO;

	return 0;
}

int imx_pinctrl_parse_pin_scu(struct imx_pinctrl_soc_info *info,
			  unsigned int *pin_id, struct imx_pin *pin,
			  const __be32 **list_p)
{
	struct imx_pin_scu *pin_scu = &pin->pin_conf.pin_scu;

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

	dev_dbg(info->dev, "%s: 0x%lx 0x%lx",
		 info->pins[pin->pin].name, pin_scu->mux, pin_scu->config);

	return 0;
}
