/*
 * Technologic Systems TS-5500 Single Board Computer support
 *
 * Copyright (C) 2013-2014 Savoir-faire Linux Inc.
 *	Vivien Didelot <vivien.didelot@savoirfairelinux.com>
 *
 * 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 driver registers the Technologic Systems TS-5500 Single Board Computer
 * (SBC) and its devices, and exposes information to userspace such as jumpers'
 * state or available options. For further information about sysfs entries, see
 * Documentation/ABI/testing/sysfs-platform-ts5500.
 *
 * This code may be extended to support similar x86-based platforms.
 * Actually, the TS-5500 and TS-5400 are supported.
 */

#include <linux/delay.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/platform_data/gpio-ts5500.h>
#include <linux/platform_data/max197.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

/* Product code register */
#define TS5500_PRODUCT_CODE_ADDR	0x74
#define TS5500_PRODUCT_CODE		0x60	/* TS-5500 product code */
#define TS5400_PRODUCT_CODE		0x40	/* TS-5400 product code */

/* SRAM/RS-485/ADC options, and RS-485 RTS/Automatic RS-485 flags register */
#define TS5500_SRAM_RS485_ADC_ADDR	0x75
#define TS5500_SRAM			BIT(0)	/* SRAM option */
#define TS5500_RS485			BIT(1)	/* RS-485 option */
#define TS5500_ADC			BIT(2)	/* A/D converter option */
#define TS5500_RS485_RTS		BIT(6)	/* RTS for RS-485 */
#define TS5500_RS485_AUTO		BIT(7)	/* Automatic RS-485 */

/* External Reset/Industrial Temperature Range options register */
#define TS5500_ERESET_ITR_ADDR		0x76
#define TS5500_ERESET			BIT(0)	/* External Reset option */
#define TS5500_ITR			BIT(1)	/* Indust. Temp. Range option */

/* LED/Jumpers register */
#define TS5500_LED_JP_ADDR		0x77
#define TS5500_LED			BIT(0)	/* LED flag */
#define TS5500_JP1			BIT(1)	/* Automatic CMOS */
#define TS5500_JP2			BIT(2)	/* Enable Serial Console */
#define TS5500_JP3			BIT(3)	/* Write Enable Drive A */
#define TS5500_JP4			BIT(4)	/* Fast Console (115K baud) */
#define TS5500_JP5			BIT(5)	/* User Jumper */
#define TS5500_JP6			BIT(6)	/* Console on COM1 (req. JP2) */
#define TS5500_JP7			BIT(7)	/* Undocumented (Unused) */

/* A/D Converter registers */
#define TS5500_ADC_CONV_BUSY_ADDR	0x195	/* Conversion state register */
#define TS5500_ADC_CONV_BUSY		BIT(0)
#define TS5500_ADC_CONV_INIT_LSB_ADDR	0x196	/* Start conv. / LSB register */
#define TS5500_ADC_CONV_MSB_ADDR	0x197	/* MSB register */
#define TS5500_ADC_CONV_DELAY		12	/* usec */

/**
 * struct ts5500_sbc - TS-5500 board description
 * @name:	Board model name.
 * @id:		Board product ID.
 * @sram:	Flag for SRAM option.
 * @rs485:	Flag for RS-485 option.
 * @adc:	Flag for Analog/Digital converter option.
 * @ereset:	Flag for External Reset option.
 * @itr:	Flag for Industrial Temperature Range option.
 * @jumpers:	Bitfield for jumpers' state.
 */
struct ts5500_sbc {
	const char *name;
	int	id;
	bool	sram;
	bool	rs485;
	bool	adc;
	bool	ereset;
	bool	itr;
	u8	jumpers;
};

/* Board signatures in BIOS shadow RAM */
static const struct {
	const char * const string;
	const ssize_t offset;
} ts5500_signatures[] __initconst = {
	{ "TS-5x00 AMD Elan", 0xb14 },
};

static int __init ts5500_check_signature(void)
{
	void __iomem *bios;
	int i, ret = -ENODEV;

	bios = ioremap(0xf0000, 0x10000);
	if (!bios)
		return -ENOMEM;

	for (i = 0; i < ARRAY_SIZE(ts5500_signatures); i++) {
		if (check_signature(bios + ts5500_signatures[i].offset,
				    ts5500_signatures[i].string,
				    strlen(ts5500_signatures[i].string))) {
			ret = 0;
			break;
		}
	}

	iounmap(bios);
	return ret;
}

static int __init ts5500_detect_config(struct ts5500_sbc *sbc)
{
	u8 tmp;
	int ret = 0;

	if (!request_region(TS5500_PRODUCT_CODE_ADDR, 4, "ts5500"))
		return -EBUSY;

	sbc->id = inb(TS5500_PRODUCT_CODE_ADDR);
	if (sbc->id == TS5500_PRODUCT_CODE) {
		sbc->name = "TS-5500";
	} else if (sbc->id == TS5400_PRODUCT_CODE) {
		sbc->name = "TS-5400";
	} else {
		pr_err("ts5500: unknown product code 0x%x\n", sbc->id);
		ret = -ENODEV;
		goto cleanup;
	}

	tmp = inb(TS5500_SRAM_RS485_ADC_ADDR);
	sbc->sram = tmp & TS5500_SRAM;
	sbc->rs485 = tmp & TS5500_RS485;
	sbc->adc = tmp & TS5500_ADC;

	tmp = inb(TS5500_ERESET_ITR_ADDR);
	sbc->ereset = tmp & TS5500_ERESET;
	sbc->itr = tmp & TS5500_ITR;

	tmp = inb(TS5500_LED_JP_ADDR);
	sbc->jumpers = tmp & ~TS5500_LED;

cleanup:
	release_region(TS5500_PRODUCT_CODE_ADDR, 4);
	return ret;
}

static ssize_t name_show(struct device *dev, struct device_attribute *attr,
		char *buf)
{
	struct ts5500_sbc *sbc = dev_get_drvdata(dev);

	return sprintf(buf, "%s\n", sbc->name);
}
static DEVICE_ATTR_RO(name);

static ssize_t id_show(struct device *dev, struct device_attribute *attr,
		char *buf)
{
	struct ts5500_sbc *sbc = dev_get_drvdata(dev);

	return sprintf(buf, "0x%.2x\n", sbc->id);
}
static DEVICE_ATTR_RO(id);

static ssize_t jumpers_show(struct device *dev, struct device_attribute *attr,
		char *buf)
{
	struct ts5500_sbc *sbc = dev_get_drvdata(dev);

	return sprintf(buf, "0x%.2x\n", sbc->jumpers >> 1);
}
static DEVICE_ATTR_RO(jumpers);

#define TS5500_ATTR_BOOL(_field)					\
	static ssize_t _field##_show(struct device *dev,		\
			struct device_attribute *attr, char *buf)	\
	{								\
		struct ts5500_sbc *sbc = dev_get_drvdata(dev);		\
									\
		return sprintf(buf, "%d\n", sbc->_field);		\
	}								\
	static DEVICE_ATTR_RO(_field)

TS5500_ATTR_BOOL(sram);
TS5500_ATTR_BOOL(rs485);
TS5500_ATTR_BOOL(adc);
TS5500_ATTR_BOOL(ereset);
TS5500_ATTR_BOOL(itr);

static struct attribute *ts5500_attributes[] = {
	&dev_attr_id.attr,
	&dev_attr_name.attr,
	&dev_attr_jumpers.attr,
	&dev_attr_sram.attr,
	&dev_attr_rs485.attr,
	&dev_attr_adc.attr,
	&dev_attr_ereset.attr,
	&dev_attr_itr.attr,
	NULL
};

static const struct attribute_group ts5500_attr_group = {
	.attrs = ts5500_attributes,
};

static struct resource ts5500_dio1_resource[] = {
	DEFINE_RES_IRQ_NAMED(7, "DIO1 interrupt"),
};

static struct platform_device ts5500_dio1_pdev = {
	.name = "ts5500-dio1",
	.id = -1,
	.resource = ts5500_dio1_resource,
	.num_resources = 1,
};

static struct resource ts5500_dio2_resource[] = {
	DEFINE_RES_IRQ_NAMED(6, "DIO2 interrupt"),
};

static struct platform_device ts5500_dio2_pdev = {
	.name = "ts5500-dio2",
	.id = -1,
	.resource = ts5500_dio2_resource,
	.num_resources = 1,
};

static void ts5500_led_set(struct led_classdev *led_cdev,
			   enum led_brightness brightness)
{
	outb(!!brightness, TS5500_LED_JP_ADDR);
}

static enum led_brightness ts5500_led_get(struct led_classdev *led_cdev)
{
	return (inb(TS5500_LED_JP_ADDR) & TS5500_LED) ? LED_FULL : LED_OFF;
}

static struct led_classdev ts5500_led_cdev = {
	.name = "ts5500:green:",
	.brightness_set = ts5500_led_set,
	.brightness_get = ts5500_led_get,
};

static int ts5500_adc_convert(u8 ctrl)
{
	u8 lsb, msb;

	/* Start conversion (ensure the 3 MSB are set to 0) */
	outb(ctrl & 0x1f, TS5500_ADC_CONV_INIT_LSB_ADDR);

	/*
	 * The platform has CPLD logic driving the A/D converter.
	 * The conversion must complete within 11 microseconds,
	 * otherwise we have to re-initiate a conversion.
	 */
	udelay(TS5500_ADC_CONV_DELAY);
	if (inb(TS5500_ADC_CONV_BUSY_ADDR) & TS5500_ADC_CONV_BUSY)
		return -EBUSY;

	/* Read the raw data */
	lsb = inb(TS5500_ADC_CONV_INIT_LSB_ADDR);
	msb = inb(TS5500_ADC_CONV_MSB_ADDR);

	return (msb << 8) | lsb;
}

static struct max197_platform_data ts5500_adc_pdata = {
	.convert = ts5500_adc_convert,
};

static struct platform_device ts5500_adc_pdev = {
	.name = "max197",
	.id = -1,
	.dev = {
		.platform_data = &ts5500_adc_pdata,
	},
};

static int __init ts5500_init(void)
{
	struct platform_device *pdev;
	struct ts5500_sbc *sbc;
	int err;

	/*
	 * There is no DMI available or PCI bridge subvendor info,
	 * only the BIOS provides a 16-bit identification call.
	 * It is safer to find a signature in the BIOS shadow RAM.
	 */
	err = ts5500_check_signature();
	if (err)
		return err;

	pdev = platform_device_register_simple("ts5500", -1, NULL, 0);
	if (IS_ERR(pdev))
		return PTR_ERR(pdev);

	sbc = devm_kzalloc(&pdev->dev, sizeof(struct ts5500_sbc), GFP_KERNEL);
	if (!sbc) {
		err = -ENOMEM;
		goto error;
	}

	err = ts5500_detect_config(sbc);
	if (err)
		goto error;

	platform_set_drvdata(pdev, sbc);

	err = sysfs_create_group(&pdev->dev.kobj, &ts5500_attr_group);
	if (err)
		goto error;

	if (sbc->id == TS5500_PRODUCT_CODE) {
		ts5500_dio1_pdev.dev.parent = &pdev->dev;
		if (platform_device_register(&ts5500_dio1_pdev))
			dev_warn(&pdev->dev, "DIO1 block registration failed\n");
		ts5500_dio2_pdev.dev.parent = &pdev->dev;
		if (platform_device_register(&ts5500_dio2_pdev))
			dev_warn(&pdev->dev, "DIO2 block registration failed\n");
	}

	if (led_classdev_register(&pdev->dev, &ts5500_led_cdev))
		dev_warn(&pdev->dev, "LED registration failed\n");

	if (sbc->adc) {
		ts5500_adc_pdev.dev.parent = &pdev->dev;
		if (platform_device_register(&ts5500_adc_pdev))
			dev_warn(&pdev->dev, "ADC registration failed\n");
	}

	return 0;
error:
	platform_device_unregister(pdev);
	return err;
}
device_initcall(ts5500_init);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>");
MODULE_DESCRIPTION("Technologic Systems TS-5500 platform driver");
