// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2016 National Instruments Corp.
 */

#include <linux/array_size.h>
#include <linux/bits.h>
#include <linux/container_of.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/leds.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/types.h>

#define NIC78BX_USER1_LED_MASK		0x3
#define NIC78BX_USER1_GREEN_LED		BIT(0)
#define NIC78BX_USER1_YELLOW_LED	BIT(1)

#define NIC78BX_USER2_LED_MASK		0xC
#define NIC78BX_USER2_GREEN_LED		BIT(2)
#define NIC78BX_USER2_YELLOW_LED	BIT(3)

#define NIC78BX_LOCK_REG_OFFSET		1
#define NIC78BX_LOCK_VALUE		0xA5
#define NIC78BX_UNLOCK_VALUE		0x5A

#define NIC78BX_USER_LED_IO_SIZE	2

struct nic78bx_led_data {
	u16 io_base;
	spinlock_t lock;
	struct platform_device *pdev;
};

struct nic78bx_led {
	u8 bit;
	u8 mask;
	struct nic78bx_led_data *data;
	struct led_classdev cdev;
};

static inline struct nic78bx_led *to_nic78bx_led(struct led_classdev *cdev)
{
	return container_of(cdev, struct nic78bx_led, cdev);
}

static void nic78bx_brightness_set(struct led_classdev *cdev,
				  enum led_brightness brightness)
{
	struct nic78bx_led *nled = to_nic78bx_led(cdev);
	unsigned long flags;
	u8 value;

	spin_lock_irqsave(&nled->data->lock, flags);
	value = inb(nled->data->io_base);

	if (brightness) {
		value &= ~nled->mask;
		value |= nled->bit;
	} else {
		value &= ~nled->bit;
	}

	outb(value, nled->data->io_base);
	spin_unlock_irqrestore(&nled->data->lock, flags);
}

static enum led_brightness nic78bx_brightness_get(struct led_classdev *cdev)
{
	struct nic78bx_led *nled = to_nic78bx_led(cdev);
	unsigned long flags;
	u8 value;

	spin_lock_irqsave(&nled->data->lock, flags);
	value = inb(nled->data->io_base);
	spin_unlock_irqrestore(&nled->data->lock, flags);

	return (value & nled->bit) ? 1 : LED_OFF;
}

static struct nic78bx_led nic78bx_leds[] = {
	{
		.bit = NIC78BX_USER1_GREEN_LED,
		.mask = NIC78BX_USER1_LED_MASK,
		.cdev = {
			.name = "nilrt:green:user1",
			.max_brightness = 1,
			.brightness_set = nic78bx_brightness_set,
			.brightness_get = nic78bx_brightness_get,
		}
	},
	{
		.bit = NIC78BX_USER1_YELLOW_LED,
		.mask = NIC78BX_USER1_LED_MASK,
		.cdev = {
			.name = "nilrt:yellow:user1",
			.max_brightness = 1,
			.brightness_set = nic78bx_brightness_set,
			.brightness_get = nic78bx_brightness_get,
		}
	},
	{
		.bit = NIC78BX_USER2_GREEN_LED,
		.mask = NIC78BX_USER2_LED_MASK,
		.cdev = {
			.name = "nilrt:green:user2",
			.max_brightness = 1,
			.brightness_set = nic78bx_brightness_set,
			.brightness_get = nic78bx_brightness_get,
		}
	},
	{
		.bit = NIC78BX_USER2_YELLOW_LED,
		.mask = NIC78BX_USER2_LED_MASK,
		.cdev = {
			.name = "nilrt:yellow:user2",
			.max_brightness = 1,
			.brightness_set = nic78bx_brightness_set,
			.brightness_get = nic78bx_brightness_get,
		}
	}
};

static void lock_led_reg_action(void *data)
{
	struct nic78bx_led_data *led_data = data;

	/* Lock LED register */
	outb(NIC78BX_LOCK_VALUE,
	     led_data->io_base + NIC78BX_LOCK_REG_OFFSET);
}

static int nic78bx_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct nic78bx_led_data *led_data;
	struct resource *io_rc;
	int ret, i;

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

	led_data->pdev = pdev;
	platform_set_drvdata(pdev, led_data);

	io_rc = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if (!io_rc) {
		dev_err(dev, "missing IO resources\n");
		return -EINVAL;
	}

	if (resource_size(io_rc) < NIC78BX_USER_LED_IO_SIZE) {
		dev_err(dev, "IO region too small\n");
		return -EINVAL;
	}

	if (!devm_request_region(dev, io_rc->start, resource_size(io_rc),
				 KBUILD_MODNAME)) {
		dev_err(dev, "failed to get IO region\n");
		return -EBUSY;
	}

	led_data->io_base = io_rc->start;
	spin_lock_init(&led_data->lock);

	ret = devm_add_action(dev, lock_led_reg_action, led_data);
	if (ret)
		return ret;

	for (i = 0; i < ARRAY_SIZE(nic78bx_leds); i++) {
		nic78bx_leds[i].data = led_data;

		ret = devm_led_classdev_register(dev, &nic78bx_leds[i].cdev);
		if (ret)
			return ret;
	}

	/* Unlock LED register */
	outb(NIC78BX_UNLOCK_VALUE,
	     led_data->io_base + NIC78BX_LOCK_REG_OFFSET);

	return ret;
}

static const struct acpi_device_id led_device_ids[] = {
	{ "NIC78B3" },
	{ }
};
MODULE_DEVICE_TABLE(acpi, led_device_ids);

static struct platform_driver led_driver = {
	.probe = nic78bx_probe,
	.driver = {
		.name = KBUILD_MODNAME,
		.acpi_match_table = led_device_ids,
	},
};

module_platform_driver(led_driver);

MODULE_DESCRIPTION("National Instruments PXI User LEDs driver");
MODULE_AUTHOR("Hui Chun Ong <hui.chun.ong@ni.com>");
MODULE_LICENSE("GPL");
