// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * dm355evm_msp.c - driver for MSP430 firmware on DM355EVM board
 *
 * Copyright (C) 2008 David Brownell
 */

#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/leds.h>
#include <linux/i2c.h>
#include <linux/mfd/dm355evm_msp.h>


/*
 * The DM355 is a DaVinci chip with video support but no C64+ DSP.  Its
 * EVM board has an MSP430 programmed with firmware for various board
 * support functions.  This driver exposes some of them directly, and
 * supports other drivers (e.g. RTC, input) for more complex access.
 *
 * Because this firmware is entirely board-specific, this file embeds
 * knowledge that would be passed as platform_data in a generic driver.
 *
 * This driver was tested with firmware revision A4.
 */

#if IS_ENABLED(CONFIG_INPUT_DM355EVM)
#define msp_has_keyboard()	true
#else
#define msp_has_keyboard()	false
#endif

#if IS_ENABLED(CONFIG_LEDS_GPIO)
#define msp_has_leds()		true
#else
#define msp_has_leds()		false
#endif

#if IS_ENABLED(CONFIG_RTC_DRV_DM355EVM)
#define msp_has_rtc()		true
#else
#define msp_has_rtc()		false
#endif

#if IS_ENABLED(CONFIG_VIDEO_TVP514X)
#define msp_has_tvp()		true
#else
#define msp_has_tvp()		false
#endif


/*----------------------------------------------------------------------*/

/* REVISIT for paranoia's sake, retry reads/writes on error */

static struct i2c_client *msp430;

/**
 * dm355evm_msp_write - Writes a register in dm355evm_msp
 * @value: the value to be written
 * @reg: register address
 *
 * Returns result of operation - 0 is success, else negative errno
 */
int dm355evm_msp_write(u8 value, u8 reg)
{
	return i2c_smbus_write_byte_data(msp430, reg, value);
}
EXPORT_SYMBOL(dm355evm_msp_write);

/**
 * dm355evm_msp_read - Reads a register from dm355evm_msp
 * @reg: register address
 *
 * Returns result of operation - value, or negative errno
 */
int dm355evm_msp_read(u8 reg)
{
	return i2c_smbus_read_byte_data(msp430, reg);
}
EXPORT_SYMBOL(dm355evm_msp_read);

/*----------------------------------------------------------------------*/

/*
 * Many of the msp430 pins are just used as fixed-direction GPIOs.
 * We could export a few more of them this way, if we wanted.
 */
#define MSP_GPIO(bit, reg)	((DM355EVM_MSP_ ## reg) << 3 | (bit))

static const u8 msp_gpios[] = {
	/* eight leds */
	MSP_GPIO(0, LED), MSP_GPIO(1, LED),
	MSP_GPIO(2, LED), MSP_GPIO(3, LED),
	MSP_GPIO(4, LED), MSP_GPIO(5, LED),
	MSP_GPIO(6, LED), MSP_GPIO(7, LED),
	/* SW6 and the NTSC/nPAL jumper */
	MSP_GPIO(0, SWITCH1), MSP_GPIO(1, SWITCH1),
	MSP_GPIO(2, SWITCH1), MSP_GPIO(3, SWITCH1),
	MSP_GPIO(4, SWITCH1),
	/* switches on MMC/SD sockets */
	/*
	 * Note: EVMDM355_ECP_VA4.pdf suggests that Bit 2 and 4 should be
	 * checked for card detection. However on the EVM bit 1 and 3 gives
	 * this status, for 0 and 1 instance respectively. The pdf also
	 * suggests that Bit 1 and 3 should be checked for write protection.
	 * However on the EVM bit 2 and 4 gives this status,for 0 and 1
	 * instance respectively.
	 */
	MSP_GPIO(2, SDMMC), MSP_GPIO(1, SDMMC),	/* mmc0 WP, nCD */
	MSP_GPIO(4, SDMMC), MSP_GPIO(3, SDMMC),	/* mmc1 WP, nCD */
};

static struct gpio_led evm_leds[] = {
	{ .name = "dm355evm::ds14",
	  .default_trigger = "heartbeat", },
	{ .name = "dm355evm::ds15",
	  .default_trigger = "mmc0", },
	{ .name = "dm355evm::ds16",
	  /* could also be a CE-ATA drive */
	  .default_trigger = "mmc1", },
	{ .name = "dm355evm::ds17",
	  .default_trigger = "nand-disk", },
	{ .name = "dm355evm::ds18", },
	{ .name = "dm355evm::ds19", },
	{ .name = "dm355evm::ds20", },
	{ .name = "dm355evm::ds21", },
};

static struct gpio_led_platform_data evm_led_data = {
	.num_leds	= ARRAY_SIZE(evm_leds),
	.leds		= evm_leds,
};

static struct gpiod_lookup_table evm_leds_gpio_table = {
	.dev_id = "leds-gpio",
	.table = {
		/*
		 * These GPIOs are on the dm355evm_msp
		 * GPIO chip at index 0..7
		 */
		GPIO_LOOKUP_IDX("dm355evm_msp", 0, NULL,
				0, GPIO_ACTIVE_LOW),
		GPIO_LOOKUP_IDX("dm355evm_msp", 1, NULL,
				1, GPIO_ACTIVE_LOW),
		GPIO_LOOKUP_IDX("dm355evm_msp", 2, NULL,
				2, GPIO_ACTIVE_LOW),
		GPIO_LOOKUP_IDX("dm355evm_msp", 3, NULL,
				3, GPIO_ACTIVE_LOW),
		GPIO_LOOKUP_IDX("dm355evm_msp", 4, NULL,
				4, GPIO_ACTIVE_LOW),
		GPIO_LOOKUP_IDX("dm355evm_msp", 5, NULL,
				5, GPIO_ACTIVE_LOW),
		GPIO_LOOKUP_IDX("dm355evm_msp", 6, NULL,
				6, GPIO_ACTIVE_LOW),
		GPIO_LOOKUP_IDX("dm355evm_msp", 7, NULL,
				7, GPIO_ACTIVE_LOW),
		{ },
	},
};

#define MSP_GPIO_REG(offset)	(msp_gpios[(offset)] >> 3)
#define MSP_GPIO_MASK(offset)	BIT(msp_gpios[(offset)] & 0x07)

static int msp_gpio_in(struct gpio_chip *chip, unsigned offset)
{
	switch (MSP_GPIO_REG(offset)) {
	case DM355EVM_MSP_SWITCH1:
	case DM355EVM_MSP_SWITCH2:
	case DM355EVM_MSP_SDMMC:
		return 0;
	default:
		return -EINVAL;
	}
}

static u8 msp_led_cache;

static int msp_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	int reg, status;

	reg = MSP_GPIO_REG(offset);
	status = dm355evm_msp_read(reg);
	if (status < 0)
		return status;
	if (reg == DM355EVM_MSP_LED)
		msp_led_cache = status;
	return !!(status & MSP_GPIO_MASK(offset));
}

static int msp_gpio_out(struct gpio_chip *chip, unsigned offset, int value)
{
	int mask, bits;

	/* NOTE:  there are some other signals that could be
	 * packaged as output GPIOs, but they aren't as useful
	 * as the LEDs ... so for now we don't.
	 */
	if (MSP_GPIO_REG(offset) != DM355EVM_MSP_LED)
		return -EINVAL;

	mask = MSP_GPIO_MASK(offset);
	bits = msp_led_cache;

	bits &= ~mask;
	if (value)
		bits |= mask;
	msp_led_cache = bits;

	return dm355evm_msp_write(bits, DM355EVM_MSP_LED);
}

static void msp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	msp_gpio_out(chip, offset, value);
}

static struct gpio_chip dm355evm_msp_gpio = {
	.label			= "dm355evm_msp",
	.owner			= THIS_MODULE,
	.direction_input	= msp_gpio_in,
	.get			= msp_gpio_get,
	.direction_output	= msp_gpio_out,
	.set			= msp_gpio_set,
	.base			= -EINVAL,		/* dynamic assignment */
	.ngpio			= ARRAY_SIZE(msp_gpios),
	.can_sleep		= true,
};

/*----------------------------------------------------------------------*/

static struct device *add_child(struct i2c_client *client, const char *name,
		void *pdata, unsigned pdata_len,
		bool can_wakeup, int irq)
{
	struct platform_device	*pdev;
	int			status;

	pdev = platform_device_alloc(name, -1);
	if (!pdev)
		return ERR_PTR(-ENOMEM);

	device_init_wakeup(&pdev->dev, can_wakeup);
	pdev->dev.parent = &client->dev;

	if (pdata) {
		status = platform_device_add_data(pdev, pdata, pdata_len);
		if (status < 0) {
			dev_dbg(&pdev->dev, "can't add platform_data\n");
			goto put_device;
		}
	}

	if (irq) {
		struct resource r = {
			.start = irq,
			.flags = IORESOURCE_IRQ,
		};

		status = platform_device_add_resources(pdev, &r, 1);
		if (status < 0) {
			dev_dbg(&pdev->dev, "can't add irq\n");
			goto put_device;
		}
	}

	status = platform_device_add(pdev);
	if (status)
		goto put_device;

	return &pdev->dev;

put_device:
	platform_device_put(pdev);
	dev_err(&client->dev, "failed to add device %s\n", name);
	return ERR_PTR(status);
}

static int add_children(struct i2c_client *client)
{
	static const struct {
		int offset;
		char *label;
	} config_inputs[] = {
		/* 8 == right after the LEDs */
		{ 8 + 0, "sw6_1", },
		{ 8 + 1, "sw6_2", },
		{ 8 + 2, "sw6_3", },
		{ 8 + 3, "sw6_4", },
		{ 8 + 4, "NTSC/nPAL", },
	};

	struct device	*child;
	int		status;
	int		i;

	/* GPIO-ish stuff */
	dm355evm_msp_gpio.parent = &client->dev;
	status = gpiochip_add_data(&dm355evm_msp_gpio, NULL);
	if (status < 0)
		return status;

	/* LED output */
	if (msp_has_leds()) {
		gpiod_add_lookup_table(&evm_leds_gpio_table);
		/* NOTE:  these are the only fully programmable LEDs
		 * on the board, since GPIO-61/ds22 (and many signals
		 * going to DC7) must be used for AEMIF address lines
		 * unless the top 1 GB of NAND is unused...
		 */
		child = add_child(client, "leds-gpio",
				&evm_led_data, sizeof(evm_led_data),
				false, 0);
		if (IS_ERR(child))
			return PTR_ERR(child);
	}

	/* configuration inputs */
	for (i = 0; i < ARRAY_SIZE(config_inputs); i++) {
		int gpio = dm355evm_msp_gpio.base + config_inputs[i].offset;

		gpio_request_one(gpio, GPIOF_IN, config_inputs[i].label);

		/* make it easy for userspace to see these */
		gpio_export(gpio, false);
	}

	/* MMC/SD inputs -- right after the last config input */
	if (dev_get_platdata(&client->dev)) {
		void (*mmcsd_setup)(unsigned) = dev_get_platdata(&client->dev);

		mmcsd_setup(dm355evm_msp_gpio.base + 8 + 5);
	}

	/* RTC is a 32 bit counter, no alarm */
	if (msp_has_rtc()) {
		child = add_child(client, "rtc-dm355evm",
				NULL, 0, false, 0);
		if (IS_ERR(child))
			return PTR_ERR(child);
	}

	/* input from buttons and IR remote (uses the IRQ) */
	if (msp_has_keyboard()) {
		child = add_child(client, "dm355evm_keys",
				NULL, 0, true, client->irq);
		if (IS_ERR(child))
			return PTR_ERR(child);
	}

	return 0;
}

/*----------------------------------------------------------------------*/

static void dm355evm_command(unsigned command)
{
	int status;

	status = dm355evm_msp_write(command, DM355EVM_MSP_COMMAND);
	if (status < 0)
		dev_err(&msp430->dev, "command %d failure %d\n",
				command, status);
}

static void dm355evm_power_off(void)
{
	dm355evm_command(MSP_COMMAND_POWEROFF);
}

static void dm355evm_msp_remove(struct i2c_client *client)
{
	pm_power_off = NULL;
	msp430 = NULL;
}

static int
dm355evm_msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int		status;
	const char	*video = msp_has_tvp() ? "TVP5146" : "imager";

	if (msp430)
		return -EBUSY;
	msp430 = client;

	/* display revision status; doubles as sanity check */
	status = dm355evm_msp_read(DM355EVM_MSP_FIRMREV);
	if (status < 0)
		goto fail;
	dev_info(&client->dev, "firmware v.%02X, %s as video-in\n",
			status, video);

	/* mux video input:  either tvp5146 or some external imager */
	status = dm355evm_msp_write(msp_has_tvp() ? 0 : MSP_VIDEO_IMAGER,
			DM355EVM_MSP_VIDEO_IN);
	if (status < 0)
		dev_warn(&client->dev, "error %d muxing %s as video-in\n",
			status, video);

	/* init LED cache, and turn off the LEDs */
	msp_led_cache = 0xff;
	dm355evm_msp_write(msp_led_cache, DM355EVM_MSP_LED);

	/* export capabilities we support */
	status = add_children(client);
	if (status < 0)
		goto fail;

	/* PM hookup */
	pm_power_off = dm355evm_power_off;

	return 0;

fail:
	/* FIXME remove children ... */
	dm355evm_msp_remove(client);
	return status;
}

static const struct i2c_device_id dm355evm_msp_ids[] = {
	{ "dm355evm_msp", 0 },
	{ /* end of list */ },
};
MODULE_DEVICE_TABLE(i2c, dm355evm_msp_ids);

static struct i2c_driver dm355evm_msp_driver = {
	.driver.name	= "dm355evm_msp",
	.id_table	= dm355evm_msp_ids,
	.probe		= dm355evm_msp_probe,
	.remove		= dm355evm_msp_remove,
};

static int __init dm355evm_msp_init(void)
{
	return i2c_add_driver(&dm355evm_msp_driver);
}
subsys_initcall(dm355evm_msp_init);

static void __exit dm355evm_msp_exit(void)
{
	i2c_del_driver(&dm355evm_msp_driver);
}
module_exit(dm355evm_msp_exit);

MODULE_DESCRIPTION("Interface to MSP430 firmware on DM355EVM");
MODULE_LICENSE("GPL");
