// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Realtek DHC pin controller driver
 *
 * Copyright (c) 2023 Realtek Semiconductor Corp.
 */

#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/platform_device.h>
#include <linux/seq_file.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include "../core.h"
#include "../pinctrl-utils.h"
#include "pinctrl-rtd.h"

struct rtd_pinctrl {
	struct device *dev;
	struct pinctrl_dev *pcdev;
	void __iomem *base;
	struct pinctrl_desc desc;
	const struct rtd_pinctrl_desc *info;
	struct regmap *regmap_pinctrl;
	u32 **saved_regs;
};

/* custom pinconf parameters */
#define RTD_DRIVE_STRENGTH_P (PIN_CONFIG_END + 1)
#define RTD_DRIVE_STRENGTH_N (PIN_CONFIG_END + 2)
#define RTD_DUTY_CYCLE (PIN_CONFIG_END + 3)
#define RTD_HIGH_VIL (PIN_CONFIG_END + 4)

static const struct pinconf_generic_params rtd_custom_bindings[] = {
	{"realtek,drive-strength-p", RTD_DRIVE_STRENGTH_P, 0},
	{"realtek,drive-strength-n", RTD_DRIVE_STRENGTH_N, 0},
	{"realtek,duty-cycle", RTD_DUTY_CYCLE, 0},
	{"realtek,high-vil-microvolt", RTD_HIGH_VIL, 0},
};

static int rtd_pinctrl_get_groups_count(struct pinctrl_dev *pcdev)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);

	return data->info->num_groups;
}

static const char *rtd_pinctrl_get_group_name(struct pinctrl_dev *pcdev,
					      unsigned int selector)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);

	return data->info->groups[selector].name;
}

static int rtd_pinctrl_get_group_pins(struct pinctrl_dev *pcdev,
				      unsigned int selector,
				      const unsigned int **pins,
				      unsigned int *num_pins)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);

	*pins = data->info->groups[selector].pins;
	*num_pins = data->info->groups[selector].num_pins;

	return 0;
}

static void rtd_pinctrl_dbg_show(struct pinctrl_dev *pcdev,
				 struct seq_file *s,
				 unsigned int offset)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);
	const struct rtd_pin_desc *mux = &data->info->muxes[offset];
	const struct rtd_pin_mux_desc *func;
	u32 val;
	u32 mask;
	u32 pin_val;
	int is_map;

	if (!mux->name) {
		seq_puts(s, "[not defined]");
		return;
	}
	val = readl_relaxed(data->base + mux->mux_offset);
	mask = mux->mux_mask;
	pin_val = val & mask;

	is_map = 0;
	func = &mux->functions[0];
	seq_puts(s, "function: ");
	while (func->name) {
		if (func->mux_value == pin_val) {
			is_map = 1;
			seq_printf(s, "[%s] ", func->name);
		} else {
			seq_printf(s, "%s ", func->name);
		}
		func++;
	}
	if (!is_map)
		seq_puts(s, "[not defined]");
}

static const struct pinctrl_ops rtd_pinctrl_ops = {
	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
	.dt_free_map = pinctrl_utils_free_map,
	.get_groups_count = rtd_pinctrl_get_groups_count,
	.get_group_name = rtd_pinctrl_get_group_name,
	.get_group_pins = rtd_pinctrl_get_group_pins,
	.pin_dbg_show = rtd_pinctrl_dbg_show,
};

static int rtd_pinctrl_get_functions_count(struct pinctrl_dev *pcdev)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);

	return data->info->num_functions;
}

static const char *rtd_pinctrl_get_function_name(struct pinctrl_dev *pcdev,
						 unsigned int selector)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);

	return data->info->functions[selector].name;
}

static int rtd_pinctrl_get_function_groups(struct pinctrl_dev *pcdev,
					   unsigned int selector,
					   const char * const **groups,
					   unsigned int * const num_groups)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);

	*groups = data->info->functions[selector].groups;
	*num_groups = data->info->functions[selector].num_groups;

	return 0;
}

static const struct rtd_pin_desc *rtd_pinctrl_find_mux(struct rtd_pinctrl *data, unsigned int pin)
{
	if (data->info->muxes[pin].name)
		return &data->info->muxes[pin];

	return NULL;
}

static int rtd_pinctrl_set_one_mux(struct pinctrl_dev *pcdev,
				   unsigned int pin, const char *func_name)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);
	const struct rtd_pin_desc *mux;
	int ret = 0;
	int i;

	mux = rtd_pinctrl_find_mux(data, pin);
	if (!mux)
		return 0;

	if (!mux->functions) {
		if (!mux->name)
			dev_err(pcdev->dev, "NULL pin has no functions\n");
		else
			dev_err(pcdev->dev, "No functions available for pin %s\n", mux->name);
		return -ENOTSUPP;
	}

	for (i = 0; mux->functions[i].name; i++) {
		if (strcmp(mux->functions[i].name, func_name) != 0)
			continue;
		ret = regmap_update_bits(data->regmap_pinctrl, mux->mux_offset, mux->mux_mask,
					mux->functions[i].mux_value);
		return ret;
	}

	if (!mux->name) {
		dev_err(pcdev->dev, "NULL pin provided for function %s\n", func_name);
		return -EINVAL;
	}

	dev_err(pcdev->dev, "No function %s available for pin %s\n", func_name, mux->name);

	return -EINVAL;
}

static int rtd_pinctrl_set_mux(struct pinctrl_dev *pcdev,
			       unsigned int function, unsigned int group)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);
	const unsigned int *pins;
	unsigned int num_pins;
	const char *func_name;
	const char *group_name;
	int i, ret;

	func_name = data->info->functions[function].name;
	group_name = data->info->groups[group].name;

	ret = rtd_pinctrl_get_group_pins(pcdev, group, &pins, &num_pins);
	if (ret) {
		dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name);
		return ret;
	}

	for (i = 0; i < num_pins; i++) {
		ret = rtd_pinctrl_set_one_mux(pcdev, pins[i], func_name);
		if (ret)
			return ret;
	}

	return 0;
}

static int rtd_pinctrl_gpio_request_enable(struct pinctrl_dev *pcdev,
					   struct pinctrl_gpio_range *range,
					   unsigned int offset)
{
	return rtd_pinctrl_set_one_mux(pcdev, offset, "gpio");
}

static const struct pinmux_ops rtd_pinmux_ops = {
	.get_functions_count = rtd_pinctrl_get_functions_count,
	.get_function_name = rtd_pinctrl_get_function_name,
	.get_function_groups = rtd_pinctrl_get_function_groups,
	.set_mux = rtd_pinctrl_set_mux,
	.gpio_request_enable = rtd_pinctrl_gpio_request_enable,
};

static const struct pinctrl_pin_desc
	*rtd_pinctrl_get_pin_by_number(struct rtd_pinctrl *data, int number)
{
	int i;

	for (i = 0; i < data->info->num_pins; i++) {
		if (data->info->pins[i].number == number)
			return &data->info->pins[i];
	}

	return NULL;
}

static const struct rtd_pin_config_desc
	*rtd_pinctrl_find_config(struct rtd_pinctrl *data, unsigned int pin)
{
	if (data->info->configs[pin].name)
		return &data->info->configs[pin];

	return NULL;
}

static const struct rtd_pin_sconfig_desc *rtd_pinctrl_find_sconfig(struct rtd_pinctrl *data,
								   unsigned int pin)
{
	int i;
	const struct pinctrl_pin_desc *pin_desc;
	const char *pin_name;

	pin_desc = rtd_pinctrl_get_pin_by_number(data, pin);
	if (!pin_desc)
		return NULL;

	pin_name = pin_desc->name;

	for (i = 0; i < data->info->num_sconfigs; i++) {
		if (strcmp(data->info->sconfigs[i].name, pin_name) == 0)
			return &data->info->sconfigs[i];
	}

	return NULL;
}

static int rtd_pconf_parse_conf(struct rtd_pinctrl *data,
				unsigned int pinnr,
				enum pin_config_param param,
				unsigned int arg)
{
	const struct rtd_pin_config_desc *config_desc;
	const struct rtd_pin_sconfig_desc *sconfig_desc;
	u8 set_val = 0;
	u16 strength;
	u32 val;
	u32 mask;
	u32 pulsel_off, pulen_off, smt_off, curr_off, pow_off, reg_off, p_off, n_off,
	    input_volt_off, sr_off, hvil_off;
	const char *name = data->info->pins[pinnr].name;
	int ret = 0;

	config_desc = rtd_pinctrl_find_config(data, pinnr);
	if (!config_desc) {
		dev_err(data->dev, "Pin config unsupported for pin: %s\n", name);
		return -ENOTSUPP;
	}
	switch ((u32)param) {
	case PIN_CONFIG_INPUT_SCHMITT:
	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
		if (config_desc->smt_offset == NA) {
			dev_err(data->dev, "Input schmitt unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		}
		smt_off = config_desc->base_bit + config_desc->smt_offset;
		reg_off = config_desc->reg_offset;
		set_val = arg;

		mask = BIT(smt_off);
		val = set_val ? BIT(smt_off) : 0;
		break;

	case PIN_CONFIG_DRIVE_PUSH_PULL:
		if (config_desc->pud_en_offset == NA) {
			dev_err(data->dev, "Push pull unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		}
		pulen_off = config_desc->base_bit + config_desc->pud_en_offset;
		reg_off = config_desc->reg_offset;

		mask =  BIT(pulen_off);
		val = 0;
		break;

	case PIN_CONFIG_BIAS_DISABLE:
		if (config_desc->pud_en_offset == NA) {
			dev_err(data->dev, "Bias disable unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		}
		pulen_off = config_desc->base_bit + config_desc->pud_en_offset;
		reg_off = config_desc->reg_offset;

		mask =  BIT(pulen_off);
		val = 0;
		break;

	case PIN_CONFIG_BIAS_PULL_UP:
		if (config_desc->pud_en_offset == NA) {
			dev_err(data->dev, "Bias pull up unsupported for pin:%s\n", name);
			return -ENOTSUPP;
		}
		pulen_off = config_desc->base_bit + config_desc->pud_en_offset;
		pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset;
		reg_off = config_desc->reg_offset;

		mask = BIT(pulen_off) | BIT(pulsel_off);
		val = mask;
		break;

	case PIN_CONFIG_BIAS_PULL_DOWN:
		if (config_desc->pud_en_offset == NA) {
			dev_err(data->dev, "Bias pull down unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		}
		pulen_off = config_desc->base_bit + config_desc->pud_en_offset;
		pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset;
		reg_off = config_desc->reg_offset;

		mask = BIT(pulen_off) | BIT(pulsel_off);
		val = BIT(pulen_off);
		break;

	case PIN_CONFIG_DRIVE_STRENGTH:
		curr_off = config_desc->base_bit + config_desc->curr_offset;
		reg_off = config_desc->reg_offset;
		strength = arg;
		val = 0;
		switch (config_desc->curr_type) {
		case PADDRI_4_8:
			if (strength == 4)
				val = 0;
			else if (strength == 8)
				val = BIT(curr_off);
			else
				return -EINVAL;
			break;
		case PADDRI_2_4:
			if (strength == 2)
				val = 0;
			else if (strength == 4)
				val = BIT(curr_off);
			else
				return -EINVAL;
			break;
		case NA:
			dev_err(data->dev, "Drive strength unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		default:
			return -EINVAL;
		}
		mask = BIT(curr_off);
		break;

	case PIN_CONFIG_POWER_SOURCE:
		if (config_desc->power_offset == NA) {
			dev_err(data->dev, "Power source unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		}
		reg_off = config_desc->reg_offset;
		pow_off = config_desc->base_bit + config_desc->power_offset;
		if (pow_off >= 32) {
			reg_off += 0x4;
			pow_off -= 32;
		}
		set_val = arg;
		mask = BIT(pow_off);
		val = set_val ? mask : 0;
		break;

	case PIN_CONFIG_SLEW_RATE:
		if (config_desc->slew_rate_offset == NA) {
			dev_err(data->dev, "Slew rate setting unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		}

		switch (arg) {
		case 1:
			set_val = 0;
			break;
		case 10:
			set_val = 1;
			break;
		case 20:
			set_val = 2;
			break;
		case 30:
			set_val = 3;
			break;
		default:
			return -EINVAL;
		}

		sr_off = config_desc->base_bit + config_desc->slew_rate_offset;
		reg_off = config_desc->reg_offset;
		mask = 0x3 << sr_off;
		val = arg << sr_off;
		break;

	case PIN_CONFIG_INPUT_VOLTAGE_UV:
		if (config_desc->input_volt_offset == NA) {
			dev_err(data->dev, "Input voltage level setting unsupported for pin:%s\n",
				name);
			return -ENOTSUPP;
		}

		if (arg == 3300000)
			set_val = 1;
		else if (arg == 1800000)
			set_val = 0;
		else
			return -EINVAL;

		input_volt_off = config_desc->base_bit + config_desc->input_volt_offset;
		reg_off = config_desc->reg_offset;

		mask = BIT(input_volt_off);
		val = set_val ? BIT(input_volt_off) : 0;
		break;

	case RTD_HIGH_VIL:
		if (config_desc->hvil_offset == NA) {
			dev_err(data->dev, "High vil setting unsupported for pin:%s\n", name);
			return -ENOTSUPP;
		}
		hvil_off = config_desc->base_bit + config_desc->hvil_offset;
		reg_off = config_desc->reg_offset;
		mask = BIT(hvil_off);
		val = 1;
		break;

	case RTD_DRIVE_STRENGTH_P:
		sconfig_desc = rtd_pinctrl_find_sconfig(data, pinnr);
		if (!sconfig_desc) {
			dev_err(data->dev, "P driving unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		}
		set_val = arg;
		reg_off = sconfig_desc->reg_offset;
		p_off = sconfig_desc->pdrive_offset;
		if (p_off >= 32) {
			reg_off += 0x4;
			p_off -= 32;
		}
		mask = GENMASK(p_off + sconfig_desc->pdrive_maskbits - 1, p_off);
		val = set_val << p_off;
		break;

	case RTD_DRIVE_STRENGTH_N:
		sconfig_desc = rtd_pinctrl_find_sconfig(data, pinnr);
		if (!sconfig_desc) {
			dev_err(data->dev, "N driving unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		}
		set_val = arg;
		reg_off = sconfig_desc->reg_offset;
		n_off = sconfig_desc->ndrive_offset;
		if (n_off >= 32) {
			reg_off += 0x4;
			n_off -= 32;
		}
		mask = GENMASK(n_off + sconfig_desc->ndrive_maskbits - 1, n_off);
		val = set_val << n_off;
		break;

	case RTD_DUTY_CYCLE:
		sconfig_desc = rtd_pinctrl_find_sconfig(data, pinnr);
		if (!sconfig_desc || sconfig_desc->dcycle_offset == NA) {
			dev_err(data->dev, "Duty cycle unsupported for pin: %s\n", name);
			return -ENOTSUPP;
		}
		set_val = arg;
		reg_off = config_desc->reg_offset;
		mask = GENMASK(sconfig_desc->dcycle_offset +
		sconfig_desc->dcycle_maskbits - 1, sconfig_desc->dcycle_offset);
		val = set_val << sconfig_desc->dcycle_offset;
		break;

	default:
		dev_dbg(data->dev, "unsupported pinconf: %d\n", (u32)param);
		return -ENOTSUPP;
	}

	ret = regmap_update_bits(data->regmap_pinctrl, reg_off, mask, val);
	if (ret)
		dev_err(data->dev, "could not update pinconf(%d) for pin(%s)\n", (u32)param, name);

	return ret;
}

static int rtd_pin_config_get(struct pinctrl_dev *pcdev, unsigned int pinnr,
			      unsigned long *config)
{
	unsigned int param = pinconf_to_config_param(*config);
	unsigned int arg = 0;

	switch (param) {
	default:
		return -ENOTSUPP;
	}

	*config = pinconf_to_config_packed(param, arg);
	return 0;
}

static int rtd_pin_config_set(struct pinctrl_dev *pcdev, unsigned int pinnr,
			      unsigned long *configs, unsigned int num_configs)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);
	int i;
	int ret = 0;

	for (i = 0; i < num_configs; i++) {
		ret = rtd_pconf_parse_conf(data, pinnr,
					   pinconf_to_config_param(configs[i]),
					   pinconf_to_config_argument(configs[i]));
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int rtd_pin_config_group_set(struct pinctrl_dev *pcdev, unsigned int group,
				    unsigned long *configs, unsigned int num_configs)
{
	struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);
	const unsigned int *pins;
	unsigned int num_pins;
	const char *group_name;
	int i, ret;

	group_name = data->info->groups[group].name;

	ret = rtd_pinctrl_get_group_pins(pcdev, group, &pins, &num_pins);
	if (ret) {
		dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name);
		return ret;
	}

	for (i = 0; i < num_pins; i++) {
		ret = rtd_pin_config_set(pcdev, pins[i], configs, num_configs);
		if (ret)
			return ret;
	}

	return 0;
}

static const struct pinconf_ops rtd_pinconf_ops = {
	.is_generic = true,
	.pin_config_get = rtd_pin_config_get,
	.pin_config_set = rtd_pin_config_set,
	.pin_config_group_set = rtd_pin_config_group_set,
};

static const struct regmap_config rtd_pinctrl_regmap_config = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
	.use_relaxed_mmio = true,
};

static int rtd_pinctrl_init_pm(struct rtd_pinctrl *data)
{
	const struct rtd_pin_range *pin_range = data->info->pin_range;
	struct device *dev = data->pcdev->dev;
	const struct rtd_reg_range *range;
	size_t num_entries;
	int i;

	data->saved_regs = devm_kcalloc(dev, pin_range->num_ranges, sizeof(u32 *), GFP_KERNEL);
	if (!data->saved_regs)
		return -ENOMEM;

	for (i = 0; i < pin_range->num_ranges; i++) {
		range = &pin_range->ranges[i];
		num_entries = range->len / 4;

		data->saved_regs[i] = devm_kzalloc(dev, num_entries * sizeof(u32), GFP_KERNEL);
		if (!data->saved_regs[i])
			return -ENOMEM;
	}

	return 0;
}

int rtd_pinctrl_probe(struct platform_device *pdev, const struct rtd_pinctrl_desc *desc)
{
	struct rtd_pinctrl *data;

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(data->base))
		return dev_err_probe(&pdev->dev, PTR_ERR(data->base),
				     "Failed to ioremap resource\n");

	data->dev = &pdev->dev;
	data->info = desc;
	data->desc.name = dev_name(&pdev->dev);
	data->desc.pins = data->info->pins;
	data->desc.npins = data->info->num_pins;
	data->desc.pctlops = &rtd_pinctrl_ops;
	data->desc.pmxops = &rtd_pinmux_ops;
	data->desc.confops = &rtd_pinconf_ops;
	data->desc.custom_params = rtd_custom_bindings;
	data->desc.num_custom_params = ARRAY_SIZE(rtd_custom_bindings);
	data->desc.owner = THIS_MODULE;
	data->regmap_pinctrl = devm_regmap_init_mmio(data->dev, data->base,
						     &rtd_pinctrl_regmap_config);

	if (IS_ERR(data->regmap_pinctrl))
		return dev_err_probe(data->dev, PTR_ERR(data->regmap_pinctrl),
				     "Failed to init regmap\n");

	data->pcdev = devm_pinctrl_register(&pdev->dev, &data->desc, data);
	if (IS_ERR(data->pcdev))
		return dev_err_probe(data->dev, PTR_ERR(data->pcdev),
				     "Failed to register pinctrl\n");

	platform_set_drvdata(pdev, data);

	dev_dbg(&pdev->dev, "probed\n");

	if (data->info->pin_range) {
		if (rtd_pinctrl_init_pm(data))
			return -ENOMEM;
	}

	return 0;
}
EXPORT_SYMBOL(rtd_pinctrl_probe);

static int realtek_pinctrl_suspend(struct device *dev)
{
	struct rtd_pinctrl *data = dev_get_drvdata(dev);
	const struct rtd_pin_range *pin_range = data->info->pin_range;
	const struct rtd_reg_range *range;
	u32 *range_regs;
	int count;
	int i, j;
	int ret;

	if (!data->saved_regs)
		return 0;

	for (i = 0; i < pin_range->num_ranges; i++) {
		range = &pin_range->ranges[i];
		range_regs = data->saved_regs[i];
		count = range->len / 4;

		for (j = 0; j < count; j++) {
			ret = regmap_read(data->regmap_pinctrl, range->offset + (j * 4),
					  &range_regs[j]);
			if (ret) {
				dev_err(dev, "failed to store register 0x%x: %d\n",
					range->offset + (j * 4), ret);
				return ret;
			}
		}
	}

	return 0;
}

static int realtek_pinctrl_resume(struct device *dev)
{
	struct rtd_pinctrl *data = dev_get_drvdata(dev);
	const struct rtd_pin_range *pin_range = data->info->pin_range;
	const struct rtd_reg_range *range;
	u32 *range_regs;
	int count;
	int i, j;
	int ret;

	if (!data->saved_regs)
		return 0;

	for (i = 0; i < pin_range->num_ranges; i++) {
		range = &pin_range->ranges[i];
		range_regs = data->saved_regs[i];
		count = range->len / 4;

		for (j = 0; j < count; j++) {
			ret = regmap_write(data->regmap_pinctrl, range->offset + (j * 4),
					   range_regs[j]);
			if (ret) {
				dev_err(dev, "failed to restore register 0x%x: %d\n",
					range->offset + (j * 4), ret);
				return ret;
			}
		}
	}
	return 0;
}

const struct dev_pm_ops realtek_pinctrl_pm_ops = {
	NOIRQ_SYSTEM_SLEEP_PM_OPS(realtek_pinctrl_suspend, realtek_pinctrl_resume)
};
EXPORT_SYMBOL_GPL(realtek_pinctrl_pm_ops);

MODULE_DESCRIPTION("Realtek DHC SoC pinctrl driver");
MODULE_LICENSE("GPL");
