/*
 * 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 <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 eth_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 (!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)
	},
};

#ifdef CONFIG_LEDS_ATMEL_PWM
static struct gpio_led stk_pwm_led[] = {
	{
		.name	= "backlight",
		.gpio	= 0,		/* PWM channel 0 (LCD backlight) */
	},
};

static struct gpio_led_platform_data stk_pwm_led_data = {
	.num_leds	= ARRAY_SIZE(stk_pwm_led),
	.leds		= stk_pwm_led,
};

static struct platform_device stk_pwm_led_dev = {
	.name	= "leds-atmel-pwm",
	.id	= -1,
	.dev	= {
		.platform_data	= &stk_pwm_led_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);

#ifdef CONFIG_LEDS_ATMEL_PWM
	at32_add_device_pwm((1 << 0) | (1 << 2));
	platform_device_register(&stk_pwm_led_dev);
#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);
