// SPDX-License-Identifier: GPL-2.0
/*
 * Sophgo CV18XX SoCs pinctrl driver.
 *
 * Copyright (C) 2024 Inochi Amaoto <inochiama@outlook.com>
 *
 */

#include <linux/bitfield.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/bsearch.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>

#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>

#include <dt-bindings/pinctrl/pinctrl-cv18xx.h>

#include "../core.h"
#include "../pinctrl-utils.h"
#include "../pinconf.h"
#include "../pinmux.h"
#include "pinctrl-cv18xx.h"

struct cv1800_pinctrl {
	struct device				*dev;
	struct pinctrl_dev			*pctl_dev;
	const struct cv1800_pinctrl_data	*data;
	struct pinctrl_desc			pdesc;
	u32					*power_cfg;

	struct mutex				mutex;
	raw_spinlock_t				lock;

	void __iomem				*regs[2];
};

struct cv1800_pin_mux_config {
	struct cv1800_pin	*pin;
	u32			config;
};

static unsigned int cv1800_dt_get_pin(u32 value)
{
	return value & GENMASK(15, 0);
}

static unsigned int cv1800_dt_get_pin_mux(u32 value)
{
	return (value >> 16) & GENMASK(7, 0);
}

static unsigned int cv1800_dt_get_pin_mux2(u32 value)
{
	return (value >> 24) & GENMASK(7, 0);
}

#define cv1800_pinctrl_get_component_addr(pctrl, _comp)		\
	((pctrl)->regs[(_comp)->area] + (_comp)->offset)

static int cv1800_cmp_pin(const void *key, const void *pivot)
{
	const struct cv1800_pin *pin = pivot;
	int pin_id = (long)key;
	int pivid = pin->pin;

	return pin_id - pivid;
}

static int cv1800_set_power_cfg(struct cv1800_pinctrl *pctrl,
				u8 domain, u32 cfg)
{
	if (domain >= pctrl->data->npd)
		return -ENOTSUPP;

	if (pctrl->power_cfg[domain] && pctrl->power_cfg[domain] != cfg)
		return -EINVAL;

	pctrl->power_cfg[domain] = cfg;

	return 0;
}

static int cv1800_get_power_cfg(struct cv1800_pinctrl *pctrl,
				u8 domain)
{
	return pctrl->power_cfg[domain];
}

static struct cv1800_pin *cv1800_get_pin(struct cv1800_pinctrl *pctrl,
					 unsigned long pin)
{
	return bsearch((void *)pin, pctrl->data->pindata, pctrl->data->npins,
		       sizeof(struct cv1800_pin), cv1800_cmp_pin);
}

#define PIN_BGA_ID_OFFSET		8
#define PIN_BGA_ID_MASK			0xff

static const char *const io_type_desc[] = {
	"1V8",
	"18OD33",
	"AUDIO",
	"ETH"
};

static const char *cv1800_get_power_cfg_desc(struct cv1800_pinctrl *pctrl,
					     u8 domain)
{
	return pctrl->data->pdnames[domain];
}

static void cv1800_pctrl_dbg_show(struct pinctrl_dev *pctldev,
				  struct seq_file *seq, unsigned int pin_id)
{
	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
	struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);
	enum cv1800_pin_io_type type = cv1800_pin_io_type(pin);
	u32 value;
	void __iomem *reg;

	if (pin->pin >> PIN_BGA_ID_OFFSET)
		seq_printf(seq, "pos: %c%u ",
			   'A' + (pin->pin >> PIN_BGA_ID_OFFSET) - 1,
			   pin->pin & PIN_BGA_ID_MASK);
	else
		seq_printf(seq, "pos: %u ", pin->pin);

	seq_printf(seq, "power-domain: %s ",
		   cv1800_get_power_cfg_desc(pctrl, pin->power_domain));
	seq_printf(seq, "type: %s ", io_type_desc[type]);

	reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux);
	value = readl(reg);
	seq_printf(seq, "mux: 0x%08x ", value);

	if (pin->flags & CV1800_PIN_HAVE_MUX2) {
		reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux2);
		value = readl(reg);
		seq_printf(seq, "mux2: 0x%08x ", value);
	}

	if (type == IO_TYPE_1V8_ONLY || type == IO_TYPE_1V8_OR_3V3) {
		reg = cv1800_pinctrl_get_component_addr(pctrl, &pin->conf);
		value = readl(reg);
		seq_printf(seq, "conf: 0x%08x ", value);
	}
}

static int cv1800_verify_pinmux_config(const struct cv1800_pin_mux_config *config)
{
	unsigned int mux = cv1800_dt_get_pin_mux(config->config);
	unsigned int mux2 = cv1800_dt_get_pin_mux2(config->config);

	if (mux > config->pin->mux.max)
		return -EINVAL;

	if (config->pin->flags & CV1800_PIN_HAVE_MUX2) {
		if (mux != config->pin->mux2.pfunc)
			return -EINVAL;

		if (mux2 > config->pin->mux2.max)
			return -EINVAL;
	} else {
		if (mux2 != PIN_MUX_INVALD)
			return -ENOTSUPP;
	}

	return 0;
}

static int cv1800_verify_pin_group(const struct cv1800_pin_mux_config *mux,
				   unsigned long npins)
{
	enum cv1800_pin_io_type type;
	u8 power_domain;
	int i;

	if (npins == 1)
		return 0;

	type = cv1800_pin_io_type(mux[0].pin);
	power_domain = mux[0].pin->power_domain;

	for (i = 0; i < npins; i++) {
		if (type != cv1800_pin_io_type(mux[i].pin) ||
		    power_domain != mux[i].pin->power_domain)
			return -ENOTSUPP;
	}

	return 0;
}

static int cv1800_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
				       struct device_node *np,
				       struct pinctrl_map **maps,
				       unsigned int *num_maps)
{
	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
	struct device *dev = pctrl->dev;
	struct device_node *child;
	struct pinctrl_map *map;
	const char **grpnames;
	const char *grpname;
	int ngroups = 0;
	int nmaps = 0;
	int ret;

	for_each_available_child_of_node(np, child)
		ngroups += 1;

	grpnames = devm_kcalloc(dev, ngroups, sizeof(*grpnames), GFP_KERNEL);
	if (!grpnames)
		return -ENOMEM;

	map = devm_kcalloc(dev, ngroups * 2, sizeof(*map), GFP_KERNEL);
	if (!map)
		return -ENOMEM;

	ngroups = 0;
	mutex_lock(&pctrl->mutex);
	for_each_available_child_of_node(np, child) {
		int npins = of_property_count_u32_elems(child, "pinmux");
		unsigned int *pins;
		struct cv1800_pin_mux_config *pinmuxs;
		u32 config, power;
		int i;

		if (npins < 1) {
			dev_err(dev, "invalid pinctrl group %pOFn.%pOFn\n",
				np, child);
			ret = -EINVAL;
			goto dt_failed;
		}

		grpname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn",
					 np, child);
		if (!grpname) {
			ret = -ENOMEM;
			goto dt_failed;
		}

		grpnames[ngroups++] = grpname;

		pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
		if (!pins) {
			ret = -ENOMEM;
			goto dt_failed;
		}

		pinmuxs = devm_kcalloc(dev, npins, sizeof(*pinmuxs), GFP_KERNEL);
		if (!pinmuxs) {
			ret = -ENOMEM;
			goto dt_failed;
		}

		for (i = 0; i < npins; i++) {
			ret = of_property_read_u32_index(child, "pinmux",
							 i, &config);
			if (ret)
				goto dt_failed;

			pins[i] = cv1800_dt_get_pin(config);
			pinmuxs[i].config = config;
			pinmuxs[i].pin = cv1800_get_pin(pctrl, pins[i]);

			if (!pinmuxs[i].pin) {
				dev_err(dev, "failed to get pin %d\n", pins[i]);
				ret = -ENODEV;
				goto dt_failed;
			}

			ret = cv1800_verify_pinmux_config(&pinmuxs[i]);
			if (ret) {
				dev_err(dev, "group %s pin %d is invalid\n",
					grpname, i);
				goto dt_failed;
			}
		}

		ret = cv1800_verify_pin_group(pinmuxs, npins);
		if (ret) {
			dev_err(dev, "group %s is invalid\n", grpname);
			goto dt_failed;
		}

		ret = of_property_read_u32(child, "power-source", &power);
		if (ret)
			goto dt_failed;

		if (!(power == PIN_POWER_STATE_3V3 || power == PIN_POWER_STATE_1V8)) {
			dev_err(dev, "group %s have unsupported power: %u\n",
				grpname, power);
			ret = -ENOTSUPP;
			goto dt_failed;
		}

		ret = cv1800_set_power_cfg(pctrl, pinmuxs[0].pin->power_domain,
					   power);
		if (ret)
			goto dt_failed;

		map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
		map[nmaps].data.mux.function = np->name;
		map[nmaps].data.mux.group = grpname;
		nmaps += 1;

		ret = pinconf_generic_parse_dt_config(child, pctldev,
						      &map[nmaps].data.configs.configs,
						      &map[nmaps].data.configs.num_configs);
		if (ret) {
			dev_err(dev, "failed to parse pin config of group %s: %d\n",
				grpname, ret);
			goto dt_failed;
		}

		ret = pinctrl_generic_add_group(pctldev, grpname,
						pins, npins, pinmuxs);
		if (ret < 0) {
			dev_err(dev, "failed to add group %s: %d\n", grpname, ret);
			goto dt_failed;
		}

		/* don't create a map if there are no pinconf settings */
		if (map[nmaps].data.configs.num_configs == 0)
			continue;

		map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
		map[nmaps].data.configs.group_or_pin = grpname;
		nmaps += 1;
	}

	ret = pinmux_generic_add_function(pctldev, np->name,
					  grpnames, ngroups, NULL);
	if (ret < 0) {
		dev_err(dev, "error adding function %s: %d\n", np->name, ret);
		goto function_failed;
	}

	*maps = map;
	*num_maps = nmaps;
	mutex_unlock(&pctrl->mutex);

	return 0;

dt_failed:
	of_node_put(child);
function_failed:
	pinctrl_utils_free_map(pctldev, map, nmaps);
	mutex_unlock(&pctrl->mutex);
	return ret;
}

static const struct pinctrl_ops cv1800_pctrl_ops = {
	.get_groups_count	= pinctrl_generic_get_group_count,
	.get_group_name		= pinctrl_generic_get_group_name,
	.get_group_pins		= pinctrl_generic_get_group_pins,
	.pin_dbg_show		= cv1800_pctrl_dbg_show,
	.dt_node_to_map		= cv1800_pctrl_dt_node_to_map,
	.dt_free_map		= pinctrl_utils_free_map,
};

static int cv1800_pmx_set_mux(struct pinctrl_dev *pctldev,
			      unsigned int fsel, unsigned int gsel)
{
	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
	const struct group_desc *group;
	const struct cv1800_pin_mux_config *configs;
	unsigned int i;

	group = pinctrl_generic_get_group(pctldev, gsel);
	if (!group)
		return -EINVAL;

	configs = group->data;

	for (i = 0; i < group->grp.npins; i++) {
		const struct cv1800_pin *pin = configs[i].pin;
		u32 value = configs[i].config;
		void __iomem *reg_mux;
		void __iomem *reg_mux2;
		unsigned long flags;
		u32 mux;
		u32 mux2;

		reg_mux = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux);
		reg_mux2 = cv1800_pinctrl_get_component_addr(pctrl, &pin->mux2);
		mux = cv1800_dt_get_pin_mux(value);
		mux2 = cv1800_dt_get_pin_mux2(value);

		raw_spin_lock_irqsave(&pctrl->lock, flags);
		writel_relaxed(mux, reg_mux);
		if (mux2 != PIN_MUX_INVALD)
			writel_relaxed(mux2, reg_mux2);
		raw_spin_unlock_irqrestore(&pctrl->lock, flags);
	}

	return 0;
}

static const struct pinmux_ops cv1800_pmx_ops = {
	.get_functions_count	= pinmux_generic_get_function_count,
	.get_function_name	= pinmux_generic_get_function_name,
	.get_function_groups	= pinmux_generic_get_function_groups,
	.set_mux		= cv1800_pmx_set_mux,
	.strict			= true,
};

#define PIN_IO_PULLUP		BIT(2)
#define PIN_IO_PULLDOWN		BIT(3)
#define PIN_IO_DRIVE		GENMASK(7, 5)
#define PIN_IO_SCHMITT		GENMASK(9, 8)
#define PIN_IO_BUS_HOLD		BIT(10)
#define PIN_IO_OUT_FAST_SLEW	BIT(11)

static u32 cv1800_pull_down_typical_resistor(struct cv1800_pinctrl *pctrl,
					     struct cv1800_pin *pin)
{
	return pctrl->data->vddio_ops->get_pull_down(pin, pctrl->power_cfg);
}

static u32 cv1800_pull_up_typical_resistor(struct cv1800_pinctrl *pctrl,
					   struct cv1800_pin *pin)
{
	return pctrl->data->vddio_ops->get_pull_up(pin, pctrl->power_cfg);
}

static int cv1800_pinctrl_oc2reg(struct cv1800_pinctrl *pctrl,
				 struct cv1800_pin *pin, u32 target)
{
	const u32 *map;
	int i, len;

	len = pctrl->data->vddio_ops->get_oc_map(pin, pctrl->power_cfg, &map);
	if (len < 0)
		return len;

	for (i = 0; i < len; i++) {
		if (map[i] >= target)
			return i;
	}

	return -EINVAL;
}

static int cv1800_pinctrl_reg2oc(struct cv1800_pinctrl *pctrl,
				 struct cv1800_pin *pin, u32 reg)
{
	const u32 *map;
	int len;

	len = pctrl->data->vddio_ops->get_oc_map(pin, pctrl->power_cfg, &map);
	if (len < 0)
		return len;

	if (reg >= len)
		return -EINVAL;

	return map[reg];
}

static int cv1800_pinctrl_schmitt2reg(struct cv1800_pinctrl *pctrl,
				      struct cv1800_pin *pin, u32 target)
{
	const u32 *map;
	int i, len;

	len = pctrl->data->vddio_ops->get_schmitt_map(pin, pctrl->power_cfg,
						      &map);
	if (len < 0)
		return len;

	for (i = 0; i < len; i++) {
		if (map[i] == target)
			return i;
	}

	return -EINVAL;
}

static int cv1800_pinctrl_reg2schmitt(struct cv1800_pinctrl *pctrl,
				      struct cv1800_pin *pin, u32 reg)
{
	const u32 *map;
	int len;

	len = pctrl->data->vddio_ops->get_schmitt_map(pin, pctrl->power_cfg,
						      &map);
	if (len < 0)
		return len;

	if (reg >= len)
		return -EINVAL;

	return map[reg];
}

static int cv1800_pconf_get(struct pinctrl_dev *pctldev,
			    unsigned int pin_id, unsigned long *config)
{
	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
	int param = pinconf_to_config_param(*config);
	struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);
	enum cv1800_pin_io_type type;
	u32 value;
	u32 arg;
	bool enabled;
	int ret;

	if (!pin)
		return -EINVAL;

	type = cv1800_pin_io_type(pin);
	if (type == IO_TYPE_ETH || type == IO_TYPE_AUDIO)
		return -ENOTSUPP;

	value = readl(cv1800_pinctrl_get_component_addr(pctrl, &pin->conf));

	switch (param) {
	case PIN_CONFIG_BIAS_PULL_DOWN:
		enabled = FIELD_GET(PIN_IO_PULLDOWN, value);
		arg = cv1800_pull_down_typical_resistor(pctrl, pin);
		break;
	case PIN_CONFIG_BIAS_PULL_UP:
		enabled = FIELD_GET(PIN_IO_PULLUP, value);
		arg = cv1800_pull_up_typical_resistor(pctrl, pin);
		break;
	case PIN_CONFIG_DRIVE_STRENGTH_UA:
		enabled = true;
		arg = FIELD_GET(PIN_IO_DRIVE, value);
		ret = cv1800_pinctrl_reg2oc(pctrl, pin, arg);
		if (ret < 0)
			return ret;
		arg = ret;
		break;
	case PIN_CONFIG_INPUT_SCHMITT_UV:
		arg = FIELD_GET(PIN_IO_SCHMITT, value);
		ret = cv1800_pinctrl_reg2schmitt(pctrl, pin, arg);
		if (ret < 0)
			return ret;
		arg = ret;
		enabled = arg != 0;
		break;
	case PIN_CONFIG_POWER_SOURCE:
		enabled = true;
		arg = cv1800_get_power_cfg(pctrl, pin->power_domain);
		break;
	case PIN_CONFIG_SLEW_RATE:
		enabled = true;
		arg = FIELD_GET(PIN_IO_OUT_FAST_SLEW, value);
		break;
	case PIN_CONFIG_BIAS_BUS_HOLD:
		arg = FIELD_GET(PIN_IO_BUS_HOLD, value);
		enabled = arg != 0;
		break;
	default:
		return -ENOTSUPP;
	}

	*config = pinconf_to_config_packed(param, arg);

	return enabled ? 0 : -EINVAL;
}

static int cv1800_pinconf_compute_config(struct cv1800_pinctrl *pctrl,
					 struct cv1800_pin *pin,
					 unsigned long *configs,
					 unsigned int num_configs,
					 u32 *value)
{
	int i;
	u32 v = 0;
	enum cv1800_pin_io_type type;
	int ret;

	if (!pin)
		return -EINVAL;

	type = cv1800_pin_io_type(pin);
	if (type == IO_TYPE_ETH || type == IO_TYPE_AUDIO)
		return -ENOTSUPP;

	for (i = 0; i < num_configs; i++) {
		int param = pinconf_to_config_param(configs[i]);
		u32 arg = pinconf_to_config_argument(configs[i]);

		switch (param) {
		case PIN_CONFIG_BIAS_PULL_DOWN:
			v &= ~PIN_IO_PULLDOWN;
			v |= FIELD_PREP(PIN_IO_PULLDOWN, arg);
			break;
		case PIN_CONFIG_BIAS_PULL_UP:
			v &= ~PIN_IO_PULLUP;
			v |= FIELD_PREP(PIN_IO_PULLUP, arg);
			break;
		case PIN_CONFIG_DRIVE_STRENGTH_UA:
			ret = cv1800_pinctrl_oc2reg(pctrl, pin, arg);
			if (ret < 0)
				return ret;
			v &= ~PIN_IO_DRIVE;
			v |= FIELD_PREP(PIN_IO_DRIVE, ret);
			break;
		case PIN_CONFIG_INPUT_SCHMITT_UV:
			ret = cv1800_pinctrl_schmitt2reg(pctrl, pin, arg);
			if (ret < 0)
				return ret;
			v &= ~PIN_IO_SCHMITT;
			v |= FIELD_PREP(PIN_IO_SCHMITT, ret);
			break;
		case PIN_CONFIG_POWER_SOURCE:
			/* Ignore power source as it is always fixed */
			break;
		case PIN_CONFIG_SLEW_RATE:
			v &= ~PIN_IO_OUT_FAST_SLEW;
			v |= FIELD_PREP(PIN_IO_OUT_FAST_SLEW, arg);
			break;
		case PIN_CONFIG_BIAS_BUS_HOLD:
			v &= ~PIN_IO_BUS_HOLD;
			v |= FIELD_PREP(PIN_IO_BUS_HOLD, arg);
			break;
		default:
			return -ENOTSUPP;
		}
	}

	*value = v;

	return 0;
}

static int cv1800_pin_set_config(struct cv1800_pinctrl *pctrl,
				 unsigned int pin_id,
				 u32 value)
{
	struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);
	unsigned long flags;
	void __iomem *addr;

	if (!pin)
		return -EINVAL;

	addr = cv1800_pinctrl_get_component_addr(pctrl, &pin->conf);

	raw_spin_lock_irqsave(&pctrl->lock, flags);
	writel(value, addr);
	raw_spin_unlock_irqrestore(&pctrl->lock, flags);

	return 0;
}

static int cv1800_pconf_set(struct pinctrl_dev *pctldev,
			    unsigned int pin_id, unsigned long *configs,
			    unsigned int num_configs)
{
	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
	struct cv1800_pin *pin = cv1800_get_pin(pctrl, pin_id);
	u32 value;

	if (!pin)
		return -ENODEV;

	if (cv1800_pinconf_compute_config(pctrl, pin,
					  configs, num_configs, &value))
		return -ENOTSUPP;

	return cv1800_pin_set_config(pctrl, pin_id, value);
}

static int cv1800_pconf_group_set(struct pinctrl_dev *pctldev,
				  unsigned int gsel,
				  unsigned long *configs,
				  unsigned int num_configs)
{
	struct cv1800_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
	const struct group_desc *group;
	const struct cv1800_pin_mux_config *pinmuxs;
	u32 value;
	int i;

	group = pinctrl_generic_get_group(pctldev, gsel);
	if (!group)
		return -EINVAL;

	pinmuxs = group->data;

	if (cv1800_pinconf_compute_config(pctrl, pinmuxs[0].pin,
					  configs, num_configs, &value))
		return -ENOTSUPP;

	for (i = 0; i < group->grp.npins; i++)
		cv1800_pin_set_config(pctrl, group->grp.pins[i], value);

	return 0;
}

static const struct pinconf_ops cv1800_pconf_ops = {
	.pin_config_get			= cv1800_pconf_get,
	.pin_config_set			= cv1800_pconf_set,
	.pin_config_group_set		= cv1800_pconf_group_set,
	.is_generic			= true,
};

int cv1800_pinctrl_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct cv1800_pinctrl *pctrl;
	const struct cv1800_pinctrl_data *pctrl_data;
	int ret;

	pctrl_data = device_get_match_data(dev);
	if (!pctrl_data)
		return -ENODEV;

	if (pctrl_data->npins == 0 || pctrl_data->npd == 0)
		return dev_err_probe(dev, -EINVAL, "invalid pin data\n");

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

	pctrl->power_cfg = devm_kcalloc(dev, pctrl_data->npd,
					sizeof(u32), GFP_KERNEL);
	if (!pctrl->power_cfg)
		return -ENOMEM;

	pctrl->regs[0] = devm_platform_ioremap_resource_byname(pdev, "sys");
	if (IS_ERR(pctrl->regs[0]))
		return PTR_ERR(pctrl->regs[0]);

	pctrl->regs[1] = devm_platform_ioremap_resource_byname(pdev, "rtc");
	if (IS_ERR(pctrl->regs[1]))
		return PTR_ERR(pctrl->regs[1]);

	pctrl->pdesc.name = dev_name(dev);
	pctrl->pdesc.pins = pctrl_data->pins;
	pctrl->pdesc.npins = pctrl_data->npins;
	pctrl->pdesc.pctlops = &cv1800_pctrl_ops;
	pctrl->pdesc.pmxops = &cv1800_pmx_ops;
	pctrl->pdesc.confops = &cv1800_pconf_ops;
	pctrl->pdesc.owner = THIS_MODULE;

	pctrl->data = pctrl_data;
	pctrl->dev = dev;
	raw_spin_lock_init(&pctrl->lock);
	mutex_init(&pctrl->mutex);

	platform_set_drvdata(pdev, pctrl);

	ret = devm_pinctrl_register_and_init(dev, &pctrl->pdesc,
					     pctrl, &pctrl->pctl_dev);
	if (ret)
		return dev_err_probe(dev, ret,
				     "fail to register pinctrl driver\n");

	return pinctrl_enable(pctrl->pctl_dev);
}
EXPORT_SYMBOL_GPL(cv1800_pinctrl_probe);
