/*
 * Board-specific setup code for the Merisc
 *
 * Copyright (C) 2008 Martinsson Elektronik AB
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/clk.h>
#include <linux/etherdevice.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/leds.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/irq.h>
#include <linux/fb.h>
#include <linux/atmel-mci.h>
#include <linux/pwm.h>
#include <linux/leds_pwm.h>

#include <asm/io.h>
#include <asm/setup.h>
#include <asm/gpio.h>

#include <mach/at32ap700x.h>
#include <mach/board.h>
#include <mach/init.h>
#include <mach/portmux.h>

#include "merisc.h"

/* Holds the autodetected board model and revision */
static int merisc_board_id;

/* Initialized by bootloader-specific startup code. */
struct tag *bootloader_tags __initdata;

/* Oscillator frequencies. These are board specific */
unsigned long at32_board_osc_rates[3] = {
	[0]	= 32768,	/* 32.768 kHz on RTC osc */
	[1]	= 20000000,	/* 20 MHz on osc0 */
	[2]	= 12000000,	/* 12 MHz on osc1 */
};

struct eth_addr {
	u8 addr[6];
};

static struct eth_addr __initdata hw_addr[2];
static struct macb_platform_data __initdata eth_data[2];

static int ads7846_get_pendown_state_PB26(void)
{
	return !gpio_get_value(GPIO_PIN_PB(26));
}

static int ads7846_get_pendown_state_PB28(void)
{
	return !gpio_get_value(GPIO_PIN_PB(28));
}

static struct ads7846_platform_data __initdata ads7846_data = {
	.model				= 7846,
	.vref_delay_usecs		= 100,
	.vref_mv			= 0,
	.keep_vref_on			= 0,
	.settle_delay_usecs		= 150,
	.penirq_recheck_delay_usecs	= 1,
	.x_plate_ohms			= 800,
	.debounce_rep			= 4,
	.debounce_max			= 10,
	.debounce_tol			= 50,
	.get_pendown_state		= ads7846_get_pendown_state_PB26,
	.filter_init			= NULL,
	.filter				= NULL,
	.filter_cleanup			= NULL,
};

static struct spi_board_info __initdata spi0_board_info[] = {
	{
		.modalias	= "ads7846",
		.max_speed_hz	= 3250000,
		.chip_select	= 0,
		.bus_num	= 0,
		.platform_data	= &ads7846_data,
		.mode		= SPI_MODE_0,
	},
};

static struct mci_platform_data __initdata mci0_data = {
	.slot[0] = {
		.bus_width		= 4,
		.detect_pin		= GPIO_PIN_PE(19),
		.wp_pin			= GPIO_PIN_PE(20),
		.detect_is_active_high	= true,
	},
};

static int __init parse_tag_ethernet(struct tag *tag)
{
	int i;

	i = tag->u.ethernet.mac_index;
	if (i < ARRAY_SIZE(hw_addr)) {
		memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
		       sizeof(hw_addr[i].addr));
	}

	return 0;
}
__tagtable(ATAG_ETHERNET, parse_tag_ethernet);

static void __init set_hw_addr(struct platform_device *pdev)
{
	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	const u8 *addr;
	void __iomem *regs;
	struct clk *pclk;

	if (!res)
		return;

	if (pdev->id >= ARRAY_SIZE(hw_addr))
		return;

	addr = hw_addr[pdev->id].addr;
	if (!is_valid_ether_addr(addr))
		return;

	regs = (void __iomem __force *)res->start;
	pclk = clk_get(&pdev->dev, "pclk");
	if (IS_ERR(pclk))
		return;

	clk_enable(pclk);
	__raw_writel((addr[3] << 24) | (addr[2] << 16)
		     | (addr[1] << 8) | addr[0], regs + 0x98);
	__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
	clk_disable(pclk);
	clk_put(pclk);
}

static struct i2c_gpio_platform_data i2c_gpio_data = {
	.sda_pin		= GPIO_PIN_PA(6),
	.scl_pin		= GPIO_PIN_PA(7),
	.sda_is_open_drain	= 1,
	.scl_is_open_drain	= 1,
	.udelay			= 2,
};

static struct platform_device i2c_gpio_device = {
	.name	= "i2c-gpio",
	.id	= 0,
	.dev	= {
		.platform_data	= &i2c_gpio_data,
	},
};

static struct i2c_board_info __initdata i2c_info[] = {
	{
		I2C_BOARD_INFO("pcf8563", 0x51)
	},
};

#if IS_ENABLED(CONFIG_LEDS_PWM)
static struct pwm_lookup pwm_lookup[] = {
	PWM_LOOKUP("at91sam9rl-pwm", 0, "leds_pwm", "backlight",
		   5000, PWM_POLARITY_NORMAL),
};

static struct led_pwm pwm_leds[] = {
	{
		.name	= "backlight",
		.max_brightness = 255,
	},
};

static struct led_pwm_platform_data pwm_data = {
	.num_leds       = ARRAY_SIZE(pwm_leds),
	.leds           = pwm_leds,
};

static struct platform_device leds_pwm = {
	.name   = "leds_pwm",
	.id     = -1,
	.dev    = {
		.platform_data = &pwm_data,
	},
};
#endif

const char *merisc_model(void)
{
	switch (merisc_board_id) {
	case 0:
	case 1:
		return "500-01";
	case 2:
		return "BT";
	default:
		return "Unknown";
	}
}

const char *merisc_revision(void)
{
	switch (merisc_board_id) {
	case 0:
		return "B";
	case 1:
		return "D";
	case 2:
		return "A";
	default:
		return "Unknown";
	}
}

static void detect_merisc_board_id(void)
{
	/* Board ID pins MUST be set as input or the board may be damaged */
	at32_select_gpio(GPIO_PIN_PA(24), AT32_GPIOF_PULLUP);
	at32_select_gpio(GPIO_PIN_PA(25), AT32_GPIOF_PULLUP);
	at32_select_gpio(GPIO_PIN_PA(26), AT32_GPIOF_PULLUP);
	at32_select_gpio(GPIO_PIN_PA(27), AT32_GPIOF_PULLUP);

	merisc_board_id = !gpio_get_value(GPIO_PIN_PA(24)) +
		!gpio_get_value(GPIO_PIN_PA(25)) * 2 +
		!gpio_get_value(GPIO_PIN_PA(26)) * 4 +
		!gpio_get_value(GPIO_PIN_PA(27)) * 8;
}

void __init setup_board(void)
{
	at32_map_usart(0, 0, 0);
	at32_map_usart(1, 1, 0);
	at32_map_usart(3, 3, 0);
	at32_setup_serial_console(1);
}

static int __init merisc_init(void)
{
	detect_merisc_board_id();

	printk(KERN_NOTICE "BOARD: Merisc %s revision %s\n", merisc_model(),
	       merisc_revision());

	/* Reserve pins for SDRAM */
	at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL | (1 << 26));

	if (merisc_board_id >= 1)
		at32_map_usart(2, 2, 0);

	at32_add_device_usart(0);
	at32_add_device_usart(1);
	if (merisc_board_id >= 1)
		at32_add_device_usart(2);
	at32_add_device_usart(3);
	set_hw_addr(at32_add_device_eth(0, &eth_data[0]));

	/* ADS7846 PENIRQ */
	if (merisc_board_id == 0) {
		ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB26;
		at32_select_periph(GPIO_PIOB_BASE, 1 << 26,
				   GPIO_PERIPH_A, AT32_GPIOF_PULLUP);
		spi0_board_info[0].irq = AT32_EXTINT(1);
	} else {
		ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB28;
		at32_select_periph(GPIO_PIOB_BASE, 1 << 28, GPIO_PERIPH_A,
				   AT32_GPIOF_PULLUP);
		spi0_board_info[0].irq = AT32_EXTINT(3);
	}

	/* ADS7846 busy pin */
	at32_select_gpio(GPIO_PIN_PA(4), AT32_GPIOF_PULLUP);

	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));

	at32_add_device_mci(0, &mci0_data);

#if IS_ENABLED(CONFIG_LEDS_PWM)
	pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
	at32_add_device_pwm((1 << 0) | (1 << 2));
	platform_device_register(&leds_pwm);
#else
	at32_add_device_pwm((1 << 2));
#endif

	at32_select_gpio(i2c_gpio_data.sda_pin,
		AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
	at32_select_gpio(i2c_gpio_data.scl_pin,
		AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
	platform_device_register(&i2c_gpio_device);

	i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));

	return 0;
}
postcore_initcall(merisc_init);
