/*
 * Favr-32 board-specific setup code.
 *
 * Copyright (C) 2008 Atmel Corporation
 *
 * 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/bootmem.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/linkage.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/atmel-mci.h>
#include <linux/atmel-pwm-bl.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>

#include <video/atmel_lcdc.h>

#include <asm/setup.h>

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

/* 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 */
};

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

struct eth_addr {
	u8 addr[6];
};
static struct eth_addr __initdata hw_addr[1];
static struct eth_platform_data __initdata eth_data[1] = {
	{
		.phy_mask	= ~(1U << 1),
	},
};

static int ads7843_get_pendown_state(void)
{
	return !gpio_get_value(GPIO_PIN_PB(3));
}

static struct ads7846_platform_data ads7843_data = {
	.model			= 7843,
	.get_pendown_state	= ads7843_get_pendown_state,
	.pressure_max		= 255,
	/*
	 * Values below are for debounce filtering, these can be experimented
	 * with further.
	 */
	.debounce_max		= 20,
	.debounce_rep		= 4,
	.debounce_tol		= 5,
};

static struct spi_board_info __initdata spi1_board_info[] = {
	{
		/* ADS7843 touch controller */
		.modalias	= "ads7846",
		.max_speed_hz	= 2000000,
		.chip_select	= 0,
		.bus_num	= 1,
		.platform_data	= &ads7843_data,
	},
};

static struct mci_platform_data __initdata mci0_data = {
	.slot[0] = {
		.bus_width	= 4,
		.detect_pin	= -ENODEV,
		.wp_pin		= -ENODEV,
	},
};

static struct fb_videomode __initdata lb104v03_modes[] = {
	{
		.name		= "640x480 @ 50",
		.refresh	= 50,
		.xres		= 640,		.yres		= 480,
		.pixclock	= KHZ2PICOS(25100),

		.left_margin	= 90,		.right_margin	= 70,
		.upper_margin	= 30,		.lower_margin	= 15,
		.hsync_len	= 12,		.vsync_len	= 2,

		.sync		= 0,
		.vmode		= FB_VMODE_NONINTERLACED,
	},
};

static struct fb_monspecs __initdata favr32_default_monspecs = {
	.manufacturer		= "LG",
	.monitor		= "LB104V03",
	.modedb			= lb104v03_modes,
	.modedb_len		= ARRAY_SIZE(lb104v03_modes),
	.hfmin			= 27273,
	.hfmax			= 31111,
	.vfmin			= 45,
	.vfmax			= 60,
	.dclkmax		= 28000000,
};

struct atmel_lcdfb_info __initdata favr32_lcdc_data = {
	.default_bpp		= 16,
	.default_dmacon		= ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
	.default_lcdcon2	= (ATMEL_LCDC_DISTYPE_TFT
				   | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
				   | ATMEL_LCDC_MEMOR_BIG),
	.default_monspecs	= &favr32_default_monspecs,
	.guard_time		= 2,
};

static struct gpio_led favr32_leds[] = {
	{
		.name		 = "green",
		.gpio		 = GPIO_PIN_PE(19),
		.default_trigger = "heartbeat",
		.active_low	 = 1,
	},
	{
		.name		 = "red",
		.gpio		 = GPIO_PIN_PE(20),
		.active_low	 = 1,
	},
};

static struct gpio_led_platform_data favr32_led_data = {
	.num_leds	= ARRAY_SIZE(favr32_leds),
	.leds		= favr32_leds,
};

static struct platform_device favr32_led_dev = {
	.name		= "leds-gpio",
	.id		= 0,
	.dev		= {
		.platform_data	= &favr32_led_data,
	},
};

/*
 * The next two functions should go away as the boot loader is
 * supposed to initialize the macb address registers with a valid
 * ethernet address. But we need to keep it around for a while until
 * we can be reasonably sure the boot loader does this.
 *
 * The phy_id is ignored as the driver will probe for it.
 */
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;

	/*
	 * Since this is board-specific code, we'll cheat and use the
	 * physical address directly as we happen to know that it's
	 * the same as the virtual address.
	 */
	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);
}

void __init favr32_setup_leds(void)
{
	unsigned i;

	for (i = 0; i < ARRAY_SIZE(favr32_leds); i++)
		at32_select_gpio(favr32_leds[i].gpio, AT32_GPIOF_OUTPUT);

	platform_device_register(&favr32_led_dev);
}

static struct atmel_pwm_bl_platform_data atmel_pwm_bl_pdata = {
	.pwm_channel		= 2,
	.pwm_frequency		= 200000,
	.pwm_compare_max	= 345,
	.pwm_duty_max		= 345,
	.pwm_duty_min		= 90,
	.pwm_active_low		= 1,
	.gpio_on		= GPIO_PIN_PA(28),
	.on_active_low		= 0,
};

static struct platform_device atmel_pwm_bl_dev = {
	.name		= "atmel-pwm-bl",
	.id		= 0,
	.dev		= {
		.platform_data = &atmel_pwm_bl_pdata,
	},
};

static void __init favr32_setup_atmel_pwm_bl(void)
{
	platform_device_register(&atmel_pwm_bl_dev);
	at32_select_gpio(atmel_pwm_bl_pdata.gpio_on, 0);
}

void __init setup_board(void)
{
	at32_map_usart(3, 0);	/* USART 3 => /dev/ttyS0 */
	at32_setup_serial_console(0);
}

static int __init set_abdac_rate(struct platform_device *pdev)
{
	int retval;
	struct clk *osc1;
	struct clk *pll1;
	struct clk *abdac;

	if (pdev == NULL)
		return -ENXIO;

	osc1 = clk_get(NULL, "osc1");
	if (IS_ERR(osc1)) {
		retval = PTR_ERR(osc1);
		goto out;
	}

	pll1 = clk_get(NULL, "pll1");
	if (IS_ERR(pll1)) {
		retval = PTR_ERR(pll1);
		goto out_osc1;
	}

	abdac = clk_get(&pdev->dev, "sample_clk");
	if (IS_ERR(abdac)) {
		retval = PTR_ERR(abdac);
		goto out_pll1;
	}

	retval = clk_set_parent(pll1, osc1);
	if (retval != 0)
		goto out_abdac;

	/*
	 * Rate is 32000 to 50000 and ABDAC oversamples 256x. Multiply, in
	 * power of 2, to a value above 80 MHz. Power of 2 so it is possible
	 * for the generic clock to divide it down again and 80 MHz is the
	 * lowest frequency for the PLL.
	 */
	retval = clk_round_rate(pll1,
			CONFIG_BOARD_FAVR32_ABDAC_RATE * 256 * 16);
	if (retval < 0)
		goto out_abdac;

	retval = clk_set_rate(pll1, retval);
	if (retval != 0)
		goto out_abdac;

	retval = clk_set_parent(abdac, pll1);
	if (retval != 0)
		goto out_abdac;

out_abdac:
	clk_put(abdac);
out_pll1:
	clk_put(pll1);
out_osc1:
	clk_put(osc1);
out:
	return retval;
}

static int __init favr32_init(void)
{
	/*
	 * Favr-32 uses 32-bit SDRAM interface. Reserve the SDRAM-specific
	 * pins so that nobody messes with them.
	 */
	at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL);

	at32_select_gpio(GPIO_PIN_PB(3), 0);	/* IRQ from ADS7843 */

	at32_add_device_usart(0);

	set_hw_addr(at32_add_device_eth(0, &eth_data[0]));

	spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3));

	set_abdac_rate(at32_add_device_abdac(0));

	at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
	at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
	at32_add_device_mci(0, &mci0_data);
	at32_add_device_usba(0, NULL);
	at32_add_device_lcdc(0, &favr32_lcdc_data, fbmem_start, fbmem_size, 0);

	favr32_setup_leds();

	favr32_setup_atmel_pwm_bl();

	return 0;
}
postcore_initcall(favr32_init);
