/*
 * dm355evm_msp.c - driver for MSP430 firmware on DM355EVM board
 *
 * Copyright (C) 2008 David Brownell
 *
 * 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.
 */

#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/leds.h>
#include <linux/i2c.h>
#include <linux/i2c/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 */
};

#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) {
		dev_dbg(&client->dev, "can't alloc dev\n");
		status = -ENOMEM;
		goto err;
	}

	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 err;
		}
	}

	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 err;
		}
	}

	status = platform_device_add(pdev);

err:
	if (status < 0) {
		platform_device_put(pdev);
		dev_err(&client->dev, "can't add %s dev\n", name);
		return ERR_PTR(status);
	}
	return &pdev->dev;
}

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()) {
#define GPIO_LED(l)	.name = l, .active_low = true
		static struct gpio_led evm_leds[] = {
			{ GPIO_LED("dm355evm::ds14"),
				.default_trigger = "heartbeat", },
			{ GPIO_LED("dm355evm::ds15"),
				.default_trigger = "mmc0", },
			{ GPIO_LED("dm355evm::ds16"),
				/* could also be a CE-ATA drive */
				.default_trigger = "mmc1", },
			{ GPIO_LED("dm355evm::ds17"),
				.default_trigger = "nand-disk", },
			{ GPIO_LED("dm355evm::ds18"), },
			{ GPIO_LED("dm355evm::ds19"), },
			{ GPIO_LED("dm355evm::ds20"), },
			{ GPIO_LED("dm355evm::ds21"), },
		};
#undef GPIO_LED

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

		for (i = 0; i < ARRAY_SIZE(evm_leds); i++)
			evm_leds[i].gpio = i + dm355evm_msp_gpio.base;

		/* 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 int dm355evm_msp_remove(struct i2c_client *client)
{
	pm_power_off = NULL;
	msp430 = NULL;
	return 0;
}

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");
