/*
 * Generic Syscon LEDs Driver
 *
 * Copyright (c) 2014, Linaro Limited
 * Author: Linus Walleij <linus.walleij@linaro.org>
 *
 * 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; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
#include <linux/io.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/leds.h>

/**
 * struct syscon_led - state container for syscon based LEDs
 * @cdev: LED class device for this LED
 * @map: regmap to access the syscon device backing this LED
 * @offset: the offset into the syscon regmap for the LED register
 * @mask: the bit in the register corresponding to the LED
 * @state: current state of the LED
 */
struct syscon_led {
	struct led_classdev cdev;
	struct regmap *map;
	u32 offset;
	u32 mask;
	bool state;
};

static void syscon_led_set(struct led_classdev *led_cdev,
	enum led_brightness value)
{
	struct syscon_led *sled =
		container_of(led_cdev, struct syscon_led, cdev);
	u32 val;
	int ret;

	if (value == LED_OFF) {
		val = 0;
		sled->state = false;
	} else {
		val = sled->mask;
		sled->state = true;
	}

	ret = regmap_update_bits(sled->map, sled->offset, sled->mask, val);
	if (ret < 0)
		dev_err(sled->cdev.dev, "error updating LED status\n");
}

static int __init syscon_leds_spawn(struct device_node *np,
				    struct device *dev,
				    struct regmap *map)
{
	struct device_node *child;
	int ret;

	for_each_available_child_of_node(np, child) {
		struct syscon_led *sled;
		const char *state;

		/* Only check for register-bit-leds */
		if (of_property_match_string(child, "compatible",
					     "register-bit-led") < 0)
			continue;

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

		sled->map = map;

		if (of_property_read_u32(child, "offset", &sled->offset))
			return -EINVAL;
		if (of_property_read_u32(child, "mask", &sled->mask))
			return -EINVAL;
		sled->cdev.name =
			of_get_property(child, "label", NULL) ? : child->name;
		sled->cdev.default_trigger =
			of_get_property(child, "linux,default-trigger", NULL);

		state = of_get_property(child, "default-state", NULL);
		if (state) {
			if (!strcmp(state, "keep")) {
				u32 val;

				ret = regmap_read(map, sled->offset, &val);
				if (ret < 0)
					return ret;
				sled->state = !!(val & sled->mask);
			} else if (!strcmp(state, "on")) {
				sled->state = true;
				ret = regmap_update_bits(map, sled->offset,
							 sled->mask,
							 sled->mask);
				if (ret < 0)
					return ret;
			} else {
				sled->state = false;
				ret = regmap_update_bits(map, sled->offset,
							 sled->mask, 0);
				if (ret < 0)
					return ret;
			}
		}
		sled->cdev.brightness_set = syscon_led_set;

		ret = led_classdev_register(dev, &sled->cdev);
		if (ret < 0)
			return ret;

		dev_info(dev, "registered LED %s\n", sled->cdev.name);
	}
	return 0;
}

static int __init syscon_leds_init(void)
{
	struct device_node *np;

	for_each_of_allnodes(np) {
		struct platform_device *pdev;
		struct regmap *map;
		int ret;

		if (!of_device_is_compatible(np, "syscon"))
			continue;

		map = syscon_node_to_regmap(np);
		if (IS_ERR(map)) {
			pr_err("error getting regmap for syscon LEDs\n");
			continue;
		}

		/*
		 * If the map is there, the device should be there, we allocate
		 * memory on the syscon device's behalf here.
		 */
		pdev = of_find_device_by_node(np);
		if (!pdev)
			return -ENODEV;
		ret = syscon_leds_spawn(np, &pdev->dev, map);
		if (ret)
			dev_err(&pdev->dev, "could not spawn syscon LEDs\n");
	}

	return 0;
}
device_initcall(syscon_leds_init);
