/*
 *  linux/drivers/pinctrl/pinctrl-pxa3xx.c
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  publishhed by the Free Software Foundation.
 *
 *  Copyright (C) 2011, Marvell Technology Group Ltd.
 *
 *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
 *
 */

#include <linux/module.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "pinctrl-pxa3xx.h"

static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = {
	.name		= "PXA3xx GPIO",
	.id		= 0,
	.base		= 0,
	.pin_base	= 0,
};

static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
{
	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
	if (selector >= info->num_grps)
		return -EINVAL;
	return 0;
}

static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
					 unsigned selector)
{
	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
	if (selector >= info->num_grps)
		return NULL;
	return info->grps[selector].name;
}

static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev,
				 unsigned selector,
				 const unsigned **pins,
				 unsigned *num_pins)
{
	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
	if (selector >= info->num_grps)
		return -EINVAL;
	*pins = info->grps[selector].pins;
	*num_pins = info->grps[selector].npins;
	return 0;
}

static struct pinctrl_ops pxa3xx_pctrl_ops = {
	.list_groups	= pxa3xx_list_groups,
	.get_group_name	= pxa3xx_get_group_name,
	.get_group_pins	= pxa3xx_get_group_pins,
};

static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
{
	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
	if (func >= info->num_funcs)
		return -EINVAL;
	return 0;
}

static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
					    unsigned func)
{
	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
	return info->funcs[func].name;
}

static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func,
				 const char * const **groups,
				 unsigned * const num_groups)
{
	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
	*groups = info->funcs[func].groups;
	*num_groups = info->funcs[func].num_groups;
	return 0;
}

/* Return function number. If failure, return negative value. */
static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux)
{
	int i;
	for (i = 0; i < PXA3xx_MAX_MUX; i++) {
		if (mfp->func[i] == mux)
			break;
	}
	if (i >= PXA3xx_MAX_MUX)
		return -EINVAL;
	return i;
}

/* check whether current pin configuration is valid. Negative for failure */
static int match_group_mux(struct pxa3xx_pin_group *grp,
			   struct pxa3xx_pinmux_info *info,
			   unsigned mux)
{
	int i, pin, ret = 0;
	for (i = 0; i < grp->npins; i++) {
		pin = grp->pins[i];
		ret = match_mux(&info->mfp[pin], mux);
		if (ret < 0) {
			dev_err(info->dev, "Can't find mux %d on pin%d\n",
				mux, pin);
			break;
		}
	}
	return ret;
}

static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func,
			     unsigned group)
{
	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
	struct pxa3xx_pin_group *pin_grp = &info->grps[group];
	unsigned int data;
	int i, mfpr, pin, pin_func;

	if (!pin_grp->npins ||
		(match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
		dev_err(info->dev, "Failed to set the pin group: %d\n", group);
		return -EINVAL;
	}
	for (i = 0; i < pin_grp->npins; i++) {
		pin = pin_grp->pins[i];
		pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
		mfpr = info->mfp[pin].mfpr;
		data = readl_relaxed(info->virt_base + mfpr);
		data &= ~MFPR_FUNC_MASK;
		data |= pin_func;
		writel_relaxed(data, info->virt_base + mfpr);
	}
	return 0;
}

static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func,
			       unsigned group)
{
}

static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
				   struct pinctrl_gpio_range *range,
				   unsigned pin)
{
	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
	unsigned int data;
	int pin_func, mfpr;

	pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO);
	if (pin_func < 0) {
		dev_err(info->dev, "No GPIO function on pin%d (%s)\n",
			pin, info->pads[pin].name);
		return -EINVAL;
	}
	mfpr = info->mfp[pin].mfpr;
	/* write gpio function into mfpr register */
	data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK;
	data |= pin_func;
	writel_relaxed(data, info->virt_base + mfpr);
	return 0;
}

static struct pinmux_ops pxa3xx_pmx_ops = {
	.list_functions		= pxa3xx_pmx_list_func,
	.get_function_name	= pxa3xx_pmx_get_func_name,
	.get_function_groups	= pxa3xx_pmx_get_groups,
	.enable			= pxa3xx_pmx_enable,
	.disable		= pxa3xx_pmx_disable,
	.gpio_request_enable	= pxa3xx_pmx_request_gpio,
};

int pxa3xx_pinctrl_register(struct platform_device *pdev,
			    struct pxa3xx_pinmux_info *info)
{
	struct pinctrl_desc *desc;
	struct resource *res;
	int ret = 0;

	if (!info || !info->cputype)
		return -EINVAL;
	desc = info->desc;
	desc->pins = info->pads;
	desc->npins = info->num_pads;
	desc->pctlops = &pxa3xx_pctrl_ops;
	desc->pmxops = &pxa3xx_pmx_ops;
	info->dev = &pdev->dev;
	pxa3xx_pinctrl_gpio_range.npins = info->num_gpio;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENOENT;
	info->phy_base = res->start;
	info->phy_size = resource_size(res);
	info->virt_base = ioremap(info->phy_base, info->phy_size);
	if (!info->virt_base)
		return -ENOMEM;
	info->pctrl = pinctrl_register(desc, &pdev->dev, info);
	if (!info->pctrl) {
		dev_err(&pdev->dev, "failed to register PXA pinmux driver\n");
		ret = -EINVAL;
		goto err;
	}
	pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range);
	platform_set_drvdata(pdev, info);
	return 0;
err:
	iounmap(info->virt_base);
	return ret;
}

int pxa3xx_pinctrl_unregister(struct platform_device *pdev)
{
	struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev);

	pinctrl_unregister(info->pctrl);
	iounmap(info->virt_base);
	platform_set_drvdata(pdev, NULL);
	return 0;
}

static int __init pxa3xx_pinctrl_init(void)
{
	pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n");
	return 0;
}
core_initcall_sync(pxa3xx_pinctrl_init);

static void __exit pxa3xx_pinctrl_exit(void)
{
}
module_exit(pxa3xx_pinctrl_exit);

MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_DESCRIPTION("PXA3xx pin control driver");
MODULE_LICENSE("GPL v2");
