// SPDX-License-Identifier: GPL-2.0
/*
 * System Control and Power Interface (SCMI) Protocol based pinctrl driver
 *
 * Copyright (C) 2024 EPAM
 * Copyright 2024 NXP
 */

#include <linux/device.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/scmi_protocol.h>
#include <linux/slab.h>
#include <linux/types.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 "pinctrl-utils.h"
#include "core.h"
#include "pinconf.h"

#define DRV_NAME "scmi-pinctrl"

/* Define num configs, if not large than 4 use stack, else use kcalloc() */
#define SCMI_NUM_CONFIGS	4

static const struct scmi_pinctrl_proto_ops *pinctrl_ops;

struct scmi_pinctrl {
	struct device *dev;
	struct scmi_protocol_handle *ph;
	struct pinctrl_dev *pctldev;
	struct pinctrl_desc pctl_desc;
	struct pinfunction *functions;
	unsigned int nr_functions;
};

static int pinctrl_scmi_get_groups_count(struct pinctrl_dev *pctldev)
{
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);

	return pinctrl_ops->count_get(pmx->ph, GROUP_TYPE);
}

static const char *pinctrl_scmi_get_group_name(struct pinctrl_dev *pctldev,
					       unsigned int selector)
{
	int ret;
	const char *name;
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);

	ret = pinctrl_ops->name_get(pmx->ph, selector, GROUP_TYPE, &name);
	if (ret) {
		dev_err(pmx->dev, "get name failed with err %d", ret);
		return NULL;
	}

	return name;
}

static int pinctrl_scmi_get_group_pins(struct pinctrl_dev *pctldev,
				       unsigned int selector,
				       const unsigned int **pins,
				       unsigned int *num_pins)
{
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);

	return pinctrl_ops->group_pins_get(pmx->ph, selector, pins, num_pins);
}

static const struct pinctrl_ops pinctrl_scmi_pinctrl_ops = {
	.get_groups_count = pinctrl_scmi_get_groups_count,
	.get_group_name = pinctrl_scmi_get_group_name,
	.get_group_pins = pinctrl_scmi_get_group_pins,
#ifdef CONFIG_OF
	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
	.dt_free_map = pinconf_generic_dt_free_map,
#endif
};

static int pinctrl_scmi_get_functions_count(struct pinctrl_dev *pctldev)
{
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);

	return pinctrl_ops->count_get(pmx->ph, FUNCTION_TYPE);
}

static const char *pinctrl_scmi_get_function_name(struct pinctrl_dev *pctldev,
						  unsigned int selector)
{
	int ret;
	const char *name;
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);

	ret = pinctrl_ops->name_get(pmx->ph, selector, FUNCTION_TYPE, &name);
	if (ret) {
		dev_err(pmx->dev, "get name failed with err %d", ret);
		return NULL;
	}

	return name;
}

static int pinctrl_scmi_get_function_groups(struct pinctrl_dev *pctldev,
					    unsigned int selector,
					    const char * const **p_groups,
					    unsigned int * const p_num_groups)
{
	struct pinfunction *func;
	const unsigned int *group_ids;
	unsigned int num_groups;
	const char **groups;
	int ret, i;
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);

	if (!p_groups || !p_num_groups)
		return -EINVAL;

	if (selector >= pmx->nr_functions)
		return -EINVAL;

	func = &pmx->functions[selector];
	if (func->ngroups)
		goto done;

	ret = pinctrl_ops->function_groups_get(pmx->ph, selector, &num_groups,
					       &group_ids);
	if (ret) {
		dev_err(pmx->dev, "Unable to get function groups, err %d", ret);
		return ret;
	}
	if (!num_groups)
		return -EINVAL;

	groups = kcalloc(num_groups, sizeof(*groups), GFP_KERNEL);
	if (!groups)
		return -ENOMEM;

	for (i = 0; i < num_groups; i++) {
		groups[i] = pinctrl_scmi_get_group_name(pctldev, group_ids[i]);
		if (!groups[i]) {
			ret = -EINVAL;
			goto err_free;
		}
	}

	func->ngroups = num_groups;
	func->groups = groups;
done:
	*p_groups = func->groups;
	*p_num_groups = func->ngroups;

	return 0;

err_free:
	kfree(groups);

	return ret;
}

static int pinctrl_scmi_func_set_mux(struct pinctrl_dev *pctldev,
				     unsigned int selector, unsigned int group)
{
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);

	return pinctrl_ops->mux_set(pmx->ph, selector, group);
}

static int pinctrl_scmi_request(struct pinctrl_dev *pctldev,
				unsigned int offset)
{
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);

	return pinctrl_ops->pin_request(pmx->ph, offset);
}

static int pinctrl_scmi_free(struct pinctrl_dev *pctldev, unsigned int offset)
{
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);

	return pinctrl_ops->pin_free(pmx->ph, offset);
}

static const struct pinmux_ops pinctrl_scmi_pinmux_ops = {
	.request = pinctrl_scmi_request,
	.free = pinctrl_scmi_free,
	.get_functions_count = pinctrl_scmi_get_functions_count,
	.get_function_name = pinctrl_scmi_get_function_name,
	.get_function_groups = pinctrl_scmi_get_function_groups,
	.set_mux = pinctrl_scmi_func_set_mux,
};

static int pinctrl_scmi_map_pinconf_type(enum pin_config_param param,
					 enum scmi_pinctrl_conf_type *type)
{
	u32 arg = param;

	switch (arg) {
	case PIN_CONFIG_BIAS_BUS_HOLD:
		*type = SCMI_PIN_BIAS_BUS_HOLD;
		break;
	case PIN_CONFIG_BIAS_DISABLE:
		*type = SCMI_PIN_BIAS_DISABLE;
		break;
	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
		*type = SCMI_PIN_BIAS_HIGH_IMPEDANCE;
		break;
	case PIN_CONFIG_BIAS_PULL_DOWN:
		*type = SCMI_PIN_BIAS_PULL_DOWN;
		break;
	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
		*type = SCMI_PIN_BIAS_PULL_DEFAULT;
		break;
	case PIN_CONFIG_BIAS_PULL_UP:
		*type = SCMI_PIN_BIAS_PULL_UP;
		break;
	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		*type = SCMI_PIN_DRIVE_OPEN_DRAIN;
		break;
	case PIN_CONFIG_DRIVE_OPEN_SOURCE:
		*type = SCMI_PIN_DRIVE_OPEN_SOURCE;
		break;
	case PIN_CONFIG_DRIVE_PUSH_PULL:
		*type = SCMI_PIN_DRIVE_PUSH_PULL;
		break;
	case PIN_CONFIG_DRIVE_STRENGTH:
		*type = SCMI_PIN_DRIVE_STRENGTH;
		break;
	case PIN_CONFIG_DRIVE_STRENGTH_UA:
		*type = SCMI_PIN_DRIVE_STRENGTH;
		break;
	case PIN_CONFIG_INPUT_DEBOUNCE:
		*type = SCMI_PIN_INPUT_DEBOUNCE;
		break;
	case PIN_CONFIG_INPUT_ENABLE:
		*type = SCMI_PIN_INPUT_MODE;
		break;
	case PIN_CONFIG_INPUT_SCHMITT:
		*type = SCMI_PIN_INPUT_SCHMITT;
		break;
	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
		*type = SCMI_PIN_INPUT_MODE;
		break;
	case PIN_CONFIG_MODE_LOW_POWER:
		*type = SCMI_PIN_LOW_POWER_MODE;
		break;
	case PIN_CONFIG_OUTPUT_ENABLE:
		*type = SCMI_PIN_OUTPUT_MODE;
		break;
	case PIN_CONFIG_POWER_SOURCE:
		*type = SCMI_PIN_POWER_SOURCE;
		break;
	case PIN_CONFIG_SLEW_RATE:
		*type = SCMI_PIN_SLEW_RATE;
		break;
	case SCMI_PIN_OEM_START ... SCMI_PIN_OEM_END:
		*type = arg;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int pinctrl_scmi_map_pinconf_type_get(enum pin_config_param param,
					     enum scmi_pinctrl_conf_type *type)
{
	if (param == PIN_CONFIG_LEVEL) {
		*type = SCMI_PIN_INPUT_VALUE;
		return 0;
	}

	return pinctrl_scmi_map_pinconf_type(param, type);
}

static int pinctrl_scmi_map_pinconf_type_set(enum pin_config_param param,
					     enum scmi_pinctrl_conf_type *type)
{
	if (param == PIN_CONFIG_LEVEL) {
		*type = SCMI_PIN_OUTPUT_VALUE;
		return 0;
	}

	return pinctrl_scmi_map_pinconf_type(param, type);
}

static int pinctrl_scmi_pinconf_get(struct pinctrl_dev *pctldev,
				    unsigned int pin, unsigned long *config)
{
	int ret;
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param config_type;
	enum scmi_pinctrl_conf_type type;
	u32 config_value;

	if (!config)
		return -EINVAL;

	config_type = pinconf_to_config_param(*config);

	ret = pinctrl_scmi_map_pinconf_type_get(config_type, &type);
	if (ret)
		return ret;

	ret = pinctrl_ops->settings_get_one(pmx->ph, pin, PIN_TYPE, type,
					    &config_value);
	/* Convert SCMI error code to PINCTRL expected error code */
	if (ret == -EOPNOTSUPP)
		return -ENOTSUPP;
	if (ret)
		return ret;

	*config = pinconf_to_config_packed(config_type, config_value);

	return 0;
}

static int
pinctrl_scmi_alloc_configs(struct pinctrl_dev *pctldev, u32 num_configs,
			   u32 **p_config_value,
			   enum scmi_pinctrl_conf_type **p_config_type)
{
	if (num_configs <= SCMI_NUM_CONFIGS)
		return 0;

	*p_config_value = kcalloc(num_configs, sizeof(**p_config_value), GFP_KERNEL);
	if (!*p_config_value)
		return -ENOMEM;

	*p_config_type = kzalloc_objs(**p_config_type, num_configs);
	if (!*p_config_type) {
		kfree(*p_config_value);
		return -ENOMEM;
	}

	return 0;
}

static void
pinctrl_scmi_free_configs(struct pinctrl_dev *pctldev, u32 num_configs,
			  u32 **p_config_value,
			  enum scmi_pinctrl_conf_type **p_config_type)
{
	if (num_configs <= SCMI_NUM_CONFIGS)
		return;

	kfree(*p_config_value);
	kfree(*p_config_type);
}

static int pinctrl_scmi_pinconf_set(struct pinctrl_dev *pctldev,
				    unsigned int pin,
				    unsigned long *configs,
				    unsigned int num_configs)
{
	int i, cnt, ret;
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
	enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS];
	u32 config_value[SCMI_NUM_CONFIGS];
	enum scmi_pinctrl_conf_type *p_config_type = config_type;
	u32 *p_config_value = config_value;
	enum pin_config_param param;

	if (!configs || !num_configs)
		return -EINVAL;

	ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type,
					 &p_config_value);
	if (ret)
		return ret;

	cnt = 0;
	for (i = 0; i < num_configs; i++) {
		param = pinconf_to_config_param(configs[i]);
		if (param == PIN_CONFIG_PERSIST_STATE)
			continue;
		ret = pinctrl_scmi_map_pinconf_type_set(param, &p_config_type[cnt]);
		if (ret) {
			dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
			goto free_config;
		}
		p_config_value[cnt] = pinconf_to_config_argument(configs[i]);
		cnt++;
	}

	ret = pinctrl_ops->settings_conf(pmx->ph, pin, PIN_TYPE, cnt,
					 p_config_type,  p_config_value);
	if (ret)
		dev_err(pmx->dev, "Error parsing config %d\n", ret);

free_config:
	pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type,
				  &p_config_value);
	return ret;
}

static int pinctrl_scmi_pinconf_group_set(struct pinctrl_dev *pctldev,
					  unsigned int group,
					  unsigned long *configs,
					  unsigned int num_configs)
{
	int i, ret;
	struct scmi_pinctrl *pmx =  pinctrl_dev_get_drvdata(pctldev);
	enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS];
	u32 config_value[SCMI_NUM_CONFIGS];
	enum scmi_pinctrl_conf_type *p_config_type = config_type;
	u32 *p_config_value = config_value;
	enum pin_config_param param;

	if (!configs || !num_configs)
		return -EINVAL;

	ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type,
					 &p_config_value);
	if (ret)
		return ret;

	for (i = 0; i < num_configs; i++) {
		param = pinconf_to_config_param(configs[i]);
		ret = pinctrl_scmi_map_pinconf_type_set(param, &p_config_type[i]);
		if (ret) {
			dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
			goto free_config;
		}

		p_config_value[i] = pinconf_to_config_argument(configs[i]);
	}

	ret = pinctrl_ops->settings_conf(pmx->ph, group, GROUP_TYPE,
					 num_configs, p_config_type,
					 p_config_value);
	if (ret)
		dev_err(pmx->dev, "Error parsing config %d", ret);

free_config:
	pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type,
				  &p_config_value);
	return ret;
};

static int pinctrl_scmi_pinconf_group_get(struct pinctrl_dev *pctldev,
					  unsigned int group,
					  unsigned long *config)
{
	int ret;
	struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param config_type;
	enum scmi_pinctrl_conf_type type;
	u32 config_value;

	if (!config)
		return -EINVAL;

	config_type = pinconf_to_config_param(*config);
	ret = pinctrl_scmi_map_pinconf_type_get(config_type, &type);
	if (ret) {
		dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
		return ret;
	}

	ret = pinctrl_ops->settings_get_one(pmx->ph, group, GROUP_TYPE, type,
					    &config_value);
	/* Convert SCMI error code to PINCTRL expected error code */
	if (ret == -EOPNOTSUPP)
		return -ENOTSUPP;
	if (ret)
		return ret;

	*config = pinconf_to_config_packed(config_type, config_value);

	return 0;
}

static const struct pinconf_ops pinctrl_scmi_pinconf_ops = {
	.is_generic = true,
	.pin_config_get = pinctrl_scmi_pinconf_get,
	.pin_config_set = pinctrl_scmi_pinconf_set,
	.pin_config_group_set = pinctrl_scmi_pinconf_group_set,
	.pin_config_group_get = pinctrl_scmi_pinconf_group_get,
	.pin_config_config_dbg_show = pinconf_generic_dump_config,
};

static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
				 struct pinctrl_desc *desc)
{
	struct pinctrl_pin_desc *pins;
	unsigned int npins;
	int ret, i;

	npins = pinctrl_ops->count_get(pmx->ph, PIN_TYPE);
	/*
	 * npins will never be zero, the scmi pinctrl driver has bailed out
	 * if npins is zero.
	 */
	pins = devm_kmalloc_array(pmx->dev, npins, sizeof(*pins), GFP_KERNEL);
	if (!pins)
		return -ENOMEM;

	for (i = 0; i < npins; i++) {
		pins[i].number = i;
		/*
		 * The memory for name is handled by the scmi firmware driver,
		 * no need free here
		 */
		ret = pinctrl_ops->name_get(pmx->ph, i, PIN_TYPE, &pins[i].name);
		if (ret)
			return dev_err_probe(pmx->dev, ret,
					     "Can't get name for pin %d", i);
	}

	desc->npins = npins;
	desc->pins = pins;
	dev_dbg(pmx->dev, "got pins %u", npins);

	return 0;
}

static const char * const scmi_pinctrl_blocklist[] = {
	"fsl,imx94",
	"fsl,imx95",
	"fsl,imx952",
	NULL
};

static int scmi_pinctrl_probe(struct scmi_device *sdev)
{
	int ret;
	struct device *dev = &sdev->dev;
	struct scmi_pinctrl *pmx;
	const struct scmi_handle *handle;
	struct scmi_protocol_handle *ph;

	if (!sdev->handle)
		return -EINVAL;

	if (of_machine_compatible_match(scmi_pinctrl_blocklist))
		return -ENODEV;

	handle = sdev->handle;

	pinctrl_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PINCTRL, &ph);
	if (IS_ERR(pinctrl_ops))
		return PTR_ERR(pinctrl_ops);

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

	pmx->ph = ph;

	pmx->dev = dev;
	pmx->pctl_desc.name = DRV_NAME;
	pmx->pctl_desc.owner = THIS_MODULE;
	pmx->pctl_desc.pctlops = &pinctrl_scmi_pinctrl_ops;
	pmx->pctl_desc.pmxops = &pinctrl_scmi_pinmux_ops;
	pmx->pctl_desc.confops = &pinctrl_scmi_pinconf_ops;

	ret = pinctrl_scmi_get_pins(pmx, &pmx->pctl_desc);
	if (ret)
		return ret;

	ret = devm_pinctrl_register_and_init(dev, &pmx->pctl_desc, pmx,
					     &pmx->pctldev);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to register pinctrl\n");

	pmx->nr_functions = pinctrl_scmi_get_functions_count(pmx->pctldev);
	pmx->functions = devm_kcalloc(dev, pmx->nr_functions,
				      sizeof(*pmx->functions), GFP_KERNEL);
	if (!pmx->functions)
		return -ENOMEM;

	return pinctrl_enable(pmx->pctldev);
}

static const struct scmi_device_id scmi_id_table[] = {
	{ SCMI_PROTOCOL_PINCTRL, "pinctrl" },
	{ }
};
MODULE_DEVICE_TABLE(scmi, scmi_id_table);

static struct scmi_driver scmi_pinctrl_driver = {
	.name = DRV_NAME,
	.probe = scmi_pinctrl_probe,
	.id_table = scmi_id_table,
};
module_scmi_driver(scmi_pinctrl_driver);

MODULE_AUTHOR("Oleksii Moisieiev <oleksii_moisieiev@epam.com>");
MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
MODULE_DESCRIPTION("ARM SCMI pin controller driver");
MODULE_LICENSE("GPL");
