/*
 * drivers/leds/leds-apu.c
 * Copyright (C) 2017 Alan Mizrahi, alan at mizrahi dot com dot ve
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the names of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/dmi.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#define APU1_FCH_ACPI_MMIO_BASE 0xFED80000
#define APU1_FCH_GPIO_BASE      (APU1_FCH_ACPI_MMIO_BASE + 0x01BD)
#define APU1_LEDON              0x08
#define APU1_LEDOFF             0xC8
#define APU1_NUM_GPIO           3
#define APU1_IOSIZE             sizeof(u8)

/* LED access parameters */
struct apu_param {
	void __iomem *addr; /* for ioread/iowrite */
};

/* LED private data */
struct apu_led_priv {
	struct led_classdev cdev;
	struct apu_param param;
};
#define cdev_to_priv(c) container_of(c, struct apu_led_priv, cdev)

/* LED profile */
struct apu_led_profile {
	const char *name;
	enum led_brightness brightness;
	unsigned long offset; /* for devm_ioremap */
};

struct apu_led_pdata {
	struct platform_device *pdev;
	struct apu_led_priv *pled;
	spinlock_t lock;
};

static struct apu_led_pdata *apu_led;

static const struct apu_led_profile apu1_led_profile[] = {
	{ "apu:green:1", LED_ON,  APU1_FCH_GPIO_BASE + 0 * APU1_IOSIZE },
	{ "apu:green:2", LED_OFF, APU1_FCH_GPIO_BASE + 1 * APU1_IOSIZE },
	{ "apu:green:3", LED_OFF, APU1_FCH_GPIO_BASE + 2 * APU1_IOSIZE },
};

static const struct dmi_system_id apu_led_dmi_table[] __initconst = {
	/* PC Engines APU with factory bios "SageBios_PCEngines_APU-45" */
	{
		.ident = "apu",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"),
			DMI_MATCH(DMI_PRODUCT_NAME, "APU")
		}
	},
	/* PC Engines APU with "Mainline" bios >= 4.6.8 */
	{
		.ident = "apu",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"),
			DMI_MATCH(DMI_PRODUCT_NAME, "apu1")
		}
	},
	{}
};
MODULE_DEVICE_TABLE(dmi, apu_led_dmi_table);

static void apu1_led_brightness_set(struct led_classdev *led, enum led_brightness value)
{
	struct apu_led_priv *pled = cdev_to_priv(led);

	spin_lock(&apu_led->lock);
	iowrite8(value ? APU1_LEDON : APU1_LEDOFF, pled->param.addr);
	spin_unlock(&apu_led->lock);
}

static int apu_led_config(struct device *dev, struct apu_led_pdata *apuld)
{
	int i;
	int err;

	apu_led->pled = devm_kcalloc(dev,
		ARRAY_SIZE(apu1_led_profile), sizeof(struct apu_led_priv),
		GFP_KERNEL);

	if (!apu_led->pled)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(apu1_led_profile); i++) {
		struct apu_led_priv *pled = &apu_led->pled[i];
		struct led_classdev *led_cdev = &pled->cdev;

		led_cdev->name = apu1_led_profile[i].name;
		led_cdev->brightness = apu1_led_profile[i].brightness;
		led_cdev->max_brightness = 1;
		led_cdev->flags = LED_CORE_SUSPENDRESUME;
		led_cdev->brightness_set = apu1_led_brightness_set;

		pled->param.addr = devm_ioremap(dev,
				apu1_led_profile[i].offset, APU1_IOSIZE);
		if (!pled->param.addr) {
			err = -ENOMEM;
			goto error;
		}

		err = led_classdev_register(dev, led_cdev);
		if (err)
			goto error;

		apu1_led_brightness_set(led_cdev, apu1_led_profile[i].brightness);
	}

	return 0;

error:
	while (i-- > 0)
		led_classdev_unregister(&apu_led->pled[i].cdev);

	return err;
}

static int __init apu_led_probe(struct platform_device *pdev)
{
	apu_led = devm_kzalloc(&pdev->dev, sizeof(*apu_led), GFP_KERNEL);

	if (!apu_led)
		return -ENOMEM;

	apu_led->pdev = pdev;

	spin_lock_init(&apu_led->lock);
	return apu_led_config(&pdev->dev, apu_led);
}

static struct platform_driver apu_led_driver = {
	.driver = {
		.name = KBUILD_MODNAME,
	},
};

static int __init apu_led_init(void)
{
	struct platform_device *pdev;
	int err;

	if (!dmi_check_system(apu_led_dmi_table)) {
		pr_err("No PC Engines APUv1 board detected. For APUv2,3 support, enable CONFIG_PCENGINES_APU2\n");
		return -ENODEV;
	}

	pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0);
	if (IS_ERR(pdev)) {
		pr_err("Device allocation failed\n");
		return PTR_ERR(pdev);
	}

	err = platform_driver_probe(&apu_led_driver, apu_led_probe);
	if (err) {
		pr_err("Probe platform driver failed\n");
		platform_device_unregister(pdev);
	}

	return err;
}

static void __exit apu_led_exit(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(apu1_led_profile); i++)
		led_classdev_unregister(&apu_led->pled[i].cdev);

	platform_device_unregister(apu_led->pdev);
	platform_driver_unregister(&apu_led_driver);
}

module_init(apu_led_init);
module_exit(apu_led_exit);

MODULE_AUTHOR("Alan Mizrahi");
MODULE_DESCRIPTION("PC Engines APU1 front LED driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:leds_apu");
