/*
 * Copyright (C) 2014 Nest Labs
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_gpio.h>

struct nl_gpio_exporter_dev {
	struct device *device;
};

/* Helper functions to leverage devres infrastructure */
static void devm_gpio_export_release(struct device *dev, void *res)
{
	unsigned *gpio = res;

	gpio_unexport(*gpio);
}

static int devm_gpio_export(struct device *dev, unsigned gpio, bool direction_may_change)
{
	unsigned *dr;
	int rc;

	dr = devres_alloc(devm_gpio_export_release, sizeof(unsigned), GFP_KERNEL);
	if (!dr)
		return -ENOMEM;

	rc = gpio_export(gpio, direction_may_change);
	if (rc) {
		devres_free(dr);
		return rc;
	}

	*dr = gpio;
	devres_add(dev, dr);

	return 0;
}

/* Scan through the DT and export GPIOs found using the provided flags */
static int nl_gpio_exporter_parse_dt(struct nl_gpio_exporter_dev *dev,
					 const char *names_string,
					 const char *gpios_string,
					 int flags)
{
	struct property *prop;
	const char *string;
	int gpio, index = 0;

	of_property_for_each_string(dev->device->of_node, names_string, prop, string) {
		gpio = of_get_named_gpio(dev->device->of_node, gpios_string, index);
		if (!gpio_is_valid(gpio)) {
			dev_err(dev->device, "Couldn't get GPIO (%s)\n", string);
			return -ENODEV;
		}

		if (devm_gpio_request_one(dev->device, gpio, flags, string)) {
			dev_err(dev->device, "Couldn't request GPIO %d (%s)\n", gpio, string);
			return -ENODEV;
		}

		if (devm_gpio_export(dev->device, gpio, 1)) {
			dev_err(dev->device, "Couldn't export GPIO %d (%s)\n", gpio, string);
			return -ENODEV;
		}

		if (gpio_export_link(dev->device, string, gpio)) {
			dev_err(dev->device, "Couldn't create link for GPIO %d (%s)\n", gpio, string);
			return -ENODEV;
		}

		dev_info(dev->device, "successfully exported %s as GPIO %d\n", string, gpio);

		index++;
	}

	return 0;
}

static int nl_gpio_exporter_probe(struct platform_device *pdev)
{
	struct nl_gpio_exporter_dev *dev;
	int ret;

	/* Allocate memory for private data structure */
	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	platform_set_drvdata(pdev, dev);
	dev->device = &pdev->dev;

	/* Make sure there is a DT node */
	if (!dev->device->of_node)
		return -ENODEV;

	/* Read Device Tree and export intput GPIOs */
	ret = nl_gpio_exporter_parse_dt(dev, "input-names", "input-gpios", GPIOF_DIR_IN);
	if (ret)
		return ret;

	/* Read Device Tree and export output GPIOs */
	return nl_gpio_exporter_parse_dt(dev, "output-names", "output-gpios", GPIOF_DIR_OUT);
}

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

static const struct of_device_id nl_gpio_exporter_of_match[] = {
	{.compatible = "nestlabs,gpio-exporter",},
	{},
};
MODULE_DEVICE_TABLE(of, nl_gpio_exporter_of_match);

static struct platform_driver nl_gpio_exporter_driver = {
	.driver = {
		   .name = "nl-gpio-exporter",
		   .owner = THIS_MODULE,
		   .of_match_table = nl_gpio_exporter_of_match,
		   },
	.probe = nl_gpio_exporter_probe,
	.remove = nl_gpio_exporter_remove,
};
module_platform_driver(nl_gpio_exporter_driver);

MODULE_DESCRIPTION("Nestlabs GPIO Exporter");
MODULE_LICENSE("GPL v2");
