// SPDX-License-Identifier: GPL-2.0-only
/*
 * Pinconf driver for TI DA850/OMAP-L138/AM18XX pullup/pulldown groups
 *
 * Copyright (C) 2016  David Lechner
 */

#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>

#define DA850_PUPD_ENA		0x00
#define DA850_PUPD_SEL		0x04

struct da850_pupd_data {
	void __iomem *base;
	struct pinctrl_desc desc;
	struct pinctrl_dev *pinctrl;
};

static const char * const da850_pupd_group_names[] = {
	"cp0", "cp1", "cp2", "cp3", "cp4", "cp5", "cp6", "cp7",
	"cp8", "cp9", "cp10", "cp11", "cp12", "cp13", "cp14", "cp15",
	"cp16", "cp17", "cp18", "cp19", "cp20", "cp21", "cp22", "cp23",
	"cp24", "cp25", "cp26", "cp27", "cp28", "cp29", "cp30", "cp31",
};

static int da850_pupd_get_groups_count(struct pinctrl_dev *pctldev)
{
	return ARRAY_SIZE(da850_pupd_group_names);
}

static const char *da850_pupd_get_group_name(struct pinctrl_dev *pctldev,
					     unsigned int selector)
{
	return da850_pupd_group_names[selector];
}

static int da850_pupd_get_group_pins(struct pinctrl_dev *pctldev,
				     unsigned int selector,
				     const unsigned int **pins,
				     unsigned int *num_pins)
{
	*num_pins = 0;

	return 0;
}

static const struct pinctrl_ops da850_pupd_pctlops = {
	.get_groups_count	= da850_pupd_get_groups_count,
	.get_group_name		= da850_pupd_get_group_name,
	.get_group_pins		= da850_pupd_get_group_pins,
	.dt_node_to_map		= pinconf_generic_dt_node_to_map_group,
	.dt_free_map		= pinconf_generic_dt_free_map,
};

static int da850_pupd_pin_config_group_get(struct pinctrl_dev *pctldev,
					   unsigned int selector,
					   unsigned long *config)
{
	struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param = pinconf_to_config_param(*config);
	u32 val;
	u16 arg;

	val = readl(data->base + DA850_PUPD_ENA);
	arg = !!(~val & BIT(selector));

	switch (param) {
	case PIN_CONFIG_BIAS_DISABLE:
		break;
	case PIN_CONFIG_BIAS_PULL_UP:
	case PIN_CONFIG_BIAS_PULL_DOWN:
		if (arg) {
			/* bias is disabled */
			arg = 0;
			break;
		}
		val = readl(data->base + DA850_PUPD_SEL);
		if (param == PIN_CONFIG_BIAS_PULL_DOWN)
			val = ~val;
		arg = !!(val & BIT(selector));
		break;
	default:
		return -EINVAL;
	}

	*config = pinconf_to_config_packed(param, arg);

	return 0;
}

static int da850_pupd_pin_config_group_set(struct pinctrl_dev *pctldev,
					   unsigned int selector,
					   unsigned long *configs,
					   unsigned int num_configs)
{
	struct da850_pupd_data *data = pinctrl_dev_get_drvdata(pctldev);
	u32 ena, sel;
	enum pin_config_param param;
	int i;

	ena = readl(data->base + DA850_PUPD_ENA);
	sel = readl(data->base + DA850_PUPD_SEL);

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

		switch (param) {
		case PIN_CONFIG_BIAS_DISABLE:
			ena &= ~BIT(selector);
			break;
		case PIN_CONFIG_BIAS_PULL_UP:
			ena |= BIT(selector);
			sel |= BIT(selector);
			break;
		case PIN_CONFIG_BIAS_PULL_DOWN:
			ena |= BIT(selector);
			sel &= ~BIT(selector);
			break;
		default:
			return -EINVAL;
		}
	}

	writel(sel, data->base + DA850_PUPD_SEL);
	writel(ena, data->base + DA850_PUPD_ENA);

	return 0;
}

static const struct pinconf_ops da850_pupd_confops = {
	.is_generic		= true,
	.pin_config_group_get	= da850_pupd_pin_config_group_get,
	.pin_config_group_set	= da850_pupd_pin_config_group_set,
};

static int da850_pupd_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct da850_pupd_data *data;

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

	data->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(data->base)) {
		dev_err(dev, "Could not map resource\n");
		return PTR_ERR(data->base);
	}

	data->desc.name = dev_name(dev);
	data->desc.pctlops = &da850_pupd_pctlops;
	data->desc.confops = &da850_pupd_confops;
	data->desc.owner = THIS_MODULE;

	data->pinctrl = devm_pinctrl_register(dev, &data->desc, data);
	if (IS_ERR(data->pinctrl)) {
		dev_err(dev, "Failed to register pinctrl\n");
		return PTR_ERR(data->pinctrl);
	}

	platform_set_drvdata(pdev, data);

	return 0;
}

static int da850_pupd_remove(struct platform_device *pdev)
{
	return 0;
}

static const struct of_device_id da850_pupd_of_match[] = {
	{ .compatible = "ti,da850-pupd" },
	{ }
};
MODULE_DEVICE_TABLE(of, da850_pupd_of_match);

static struct platform_driver da850_pupd_driver = {
	.driver	= {
		.name		= "ti-da850-pupd",
		.of_match_table	= da850_pupd_of_match,
	},
	.probe	= da850_pupd_probe,
	.remove	= da850_pupd_remove,
};
module_platform_driver(da850_pupd_driver);

MODULE_AUTHOR("David Lechner <david@lechnology.com>");
MODULE_DESCRIPTION("TI DA850/OMAP-L138/AM18XX pullup/pulldown configuration");
MODULE_LICENSE("GPL");
