/*
 *  Atheros AR71XX/AR724X/AR913X GPIO API support
 *
 *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
 *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
 *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
 *
 *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
 *
 *  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 published
 *  by the Free Software Foundation.
 */

#include <linux/gpio/driver.h>
#include <linux/platform_data/gpio-ath79.h>
#include <linux/of_device.h>

#include <asm/mach-ath79/ar71xx_regs.h>

struct ath79_gpio_ctrl {
	struct gpio_chip chip;
	void __iomem *base;
	spinlock_t lock;
};

#define to_ath79_gpio_ctrl(c) container_of(c, struct ath79_gpio_ctrl, chip)

static void ath79_gpio_set_value(struct gpio_chip *chip,
				unsigned gpio, int value)
{
	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);

	if (value)
		__raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_SET);
	else
		__raw_writel(BIT(gpio), ctrl->base + AR71XX_GPIO_REG_CLEAR);
}

static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);

	return (__raw_readl(ctrl->base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
}

static int ath79_gpio_direction_input(struct gpio_chip *chip,
				       unsigned offset)
{
	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
	unsigned long flags;

	spin_lock_irqsave(&ctrl->lock, flags);

	__raw_writel(
		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
		ctrl->base + AR71XX_GPIO_REG_OE);

	spin_unlock_irqrestore(&ctrl->lock, flags);

	return 0;
}

static int ath79_gpio_direction_output(struct gpio_chip *chip,
					unsigned offset, int value)
{
	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
	unsigned long flags;

	spin_lock_irqsave(&ctrl->lock, flags);

	if (value)
		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET);
	else
		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);

	__raw_writel(
		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset),
		ctrl->base + AR71XX_GPIO_REG_OE);

	spin_unlock_irqrestore(&ctrl->lock, flags);

	return 0;
}

static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
	unsigned long flags;

	spin_lock_irqsave(&ctrl->lock, flags);

	__raw_writel(
		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) | BIT(offset),
		ctrl->base + AR71XX_GPIO_REG_OE);

	spin_unlock_irqrestore(&ctrl->lock, flags);

	return 0;
}

static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
					int value)
{
	struct ath79_gpio_ctrl *ctrl = to_ath79_gpio_ctrl(chip);
	unsigned long flags;

	spin_lock_irqsave(&ctrl->lock, flags);

	if (value)
		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_SET);
	else
		__raw_writel(BIT(offset), ctrl->base + AR71XX_GPIO_REG_CLEAR);

	__raw_writel(
		__raw_readl(ctrl->base + AR71XX_GPIO_REG_OE) & ~BIT(offset),
		ctrl->base + AR71XX_GPIO_REG_OE);

	spin_unlock_irqrestore(&ctrl->lock, flags);

	return 0;
}

static const struct gpio_chip ath79_gpio_chip = {
	.label			= "ath79",
	.get			= ath79_gpio_get_value,
	.set			= ath79_gpio_set_value,
	.direction_input	= ath79_gpio_direction_input,
	.direction_output	= ath79_gpio_direction_output,
	.base			= 0,
};

static const struct of_device_id ath79_gpio_of_match[] = {
	{ .compatible = "qca,ar7100-gpio" },
	{ .compatible = "qca,ar9340-gpio" },
	{},
};

static int ath79_gpio_probe(struct platform_device *pdev)
{
	struct ath79_gpio_platform_data *pdata = pdev->dev.platform_data;
	struct device_node *np = pdev->dev.of_node;
	struct ath79_gpio_ctrl *ctrl;
	struct resource *res;
	u32 ath79_gpio_count;
	bool oe_inverted;
	int err;

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

	if (np) {
		err = of_property_read_u32(np, "ngpios", &ath79_gpio_count);
		if (err) {
			dev_err(&pdev->dev, "ngpios property is not valid\n");
			return err;
		}
		if (ath79_gpio_count >= 32) {
			dev_err(&pdev->dev, "ngpios must be less than 32\n");
			return -EINVAL;
		}
		oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio");
	} else if (pdata) {
		ath79_gpio_count = pdata->ngpios;
		oe_inverted = pdata->oe_inverted;
	} else {
		dev_err(&pdev->dev, "No DT node or platform data found\n");
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	ctrl->base = devm_ioremap_nocache(
		&pdev->dev, res->start, resource_size(res));
	if (!ctrl->base)
		return -ENOMEM;

	spin_lock_init(&ctrl->lock);
	memcpy(&ctrl->chip, &ath79_gpio_chip, sizeof(ctrl->chip));
	ctrl->chip.dev = &pdev->dev;
	ctrl->chip.ngpio = ath79_gpio_count;
	if (oe_inverted) {
		ctrl->chip.direction_input = ar934x_gpio_direction_input;
		ctrl->chip.direction_output = ar934x_gpio_direction_output;
	}

	err = gpiochip_add(&ctrl->chip);
	if (err) {
		dev_err(&pdev->dev,
			"cannot add AR71xx GPIO chip, error=%d", err);
		return err;
	}

	return 0;
}

static struct platform_driver ath79_gpio_driver = {
	.driver = {
		.name = "ath79-gpio",
		.of_match_table	= ath79_gpio_of_match,
	},
	.probe = ath79_gpio_probe,
};

module_platform_driver(ath79_gpio_driver);
