/*
 * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
 *
 * 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/can/platform/sja1000.h>

#include <asm/mach/arch.h>

#include <mach/common.h>
#include <mach/iomux-mx27.h>
#include <mach/imxfb.h>
#include <mach/hardware.h>
#include <mach/mmc.h>

#include "devices.h"

static int pcm970_pins[] = {
	/* SDHC */
	PB4_PF_SD2_D0,
	PB5_PF_SD2_D1,
	PB6_PF_SD2_D2,
	PB7_PF_SD2_D3,
	PB8_PF_SD2_CMD,
	PB9_PF_SD2_CLK,
	/* display */
	PA5_PF_LSCLK,
	PA6_PF_LD0,
	PA7_PF_LD1,
	PA8_PF_LD2,
	PA9_PF_LD3,
	PA10_PF_LD4,
	PA11_PF_LD5,
	PA12_PF_LD6,
	PA13_PF_LD7,
	PA14_PF_LD8,
	PA15_PF_LD9,
	PA16_PF_LD10,
	PA17_PF_LD11,
	PA18_PF_LD12,
	PA19_PF_LD13,
	PA20_PF_LD14,
	PA21_PF_LD15,
	PA22_PF_LD16,
	PA23_PF_LD17,
	PA24_PF_REV,
	PA25_PF_CLS,
	PA26_PF_PS,
	PA27_PF_SPL_SPR,
	PA28_PF_HSYNC,
	PA29_PF_VSYNC,
	PA30_PF_CONTRAST,
	PA31_PF_OE_ACD,
	/*
	 * it seems the data line misses a pullup, so we must enable
	 * the internal pullup as a local workaround
	 */
	PD17_PF_I2C_DATA | GPIO_PUEN,
	PD18_PF_I2C_CLK,
	/* Camera */
	PB10_PF_CSI_D0,
	PB11_PF_CSI_D1,
	PB12_PF_CSI_D2,
	PB13_PF_CSI_D3,
	PB14_PF_CSI_D4,
	PB15_PF_CSI_MCLK,
	PB16_PF_CSI_PIXCLK,
	PB17_PF_CSI_D5,
	PB18_PF_CSI_D6,
	PB19_PF_CSI_D7,
	PB20_PF_CSI_VSYNC,
	PB21_PF_CSI_HSYNC,
};

static int pcm970_sdhc2_get_ro(struct device *dev)
{
	return gpio_get_value(GPIO_PORTC + 28);
}

static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
{
	int ret;

	ret = request_irq(IRQ_GPIOC(29), detect_irq, IRQF_TRIGGER_FALLING,
				"imx-mmc-detect", data);
	if (ret)
		return ret;

	ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
	if (ret) {
		free_irq(IRQ_GPIOC(29), data);
		return ret;
	}

	gpio_direction_input(GPIO_PORTC + 28);

	return 0;
}

static void pcm970_sdhc2_exit(struct device *dev, void *data)
{
	free_irq(IRQ_GPIOC(29), data);
	gpio_free(GPIO_PORTC + 28);
}

static struct imxmmc_platform_data sdhc_pdata = {
	.get_ro = pcm970_sdhc2_get_ro,
	.init = pcm970_sdhc2_init,
	.exit = pcm970_sdhc2_exit,
};

static struct imx_fb_videomode pcm970_modes[] = {
	{
		.mode = {
			.name		= "Sharp-LQ035Q7",
			.refresh	= 60,
			.xres		= 240,
			.yres		= 320,
			.pixclock	= 188679, /* in ps (5.3MHz) */
			.hsync_len	= 7,
			.left_margin	= 5,
			.right_margin	= 16,
			.vsync_len	= 1,
			.upper_margin	= 7,
			.lower_margin	= 9,
		},
		/*
		 * - HSYNC active high
		 * - VSYNC active high
		 * - clk notenabled while idle
		 * - clock not inverted
		 * - data not inverted
		 * - data enable low active
		 * - enable sharp mode
		 */
		.pcr		= 0xF00080C0,
		.bpp		= 16,
	}, {
		.mode = {
			.name		= "TX090",
			.refresh	= 60,
			.xres		= 240,
			.yres		= 320,
			.pixclock	= 38255,
			.left_margin	= 144,
			.right_margin	= 0,
			.upper_margin	= 7,
			.lower_margin	= 40,
			.hsync_len	= 96,
			.vsync_len	= 1,
		},
		/*
		 * - HSYNC active low (1 << 22)
		 * - VSYNC active low (1 << 23)
		 * - clk notenabled while idle
		 * - clock not inverted
		 * - data not inverted
		 * - data enable low active
		 * - enable sharp mode
		 */
		.pcr = 0xF0008080 | (1<<22) | (1<<23) | (1<<19),
		.bpp = 32,
	},
};

static struct imx_fb_platform_data pcm038_fb_data = {
	.mode = pcm970_modes,
	.num_modes = ARRAY_SIZE(pcm970_modes),

	.pwmr		= 0x00A903FF,
	.lscr1		= 0x00120300,
	.dmacr		= 0x00020010,
};

static struct resource pcm970_sja1000_resources[] = {
	{
		.start   = MX27_CS4_BASE_ADDR,
		.end     = MX27_CS4_BASE_ADDR + 0x100 - 1,
		.flags   = IORESOURCE_MEM,
	}, {
		.start   = IRQ_GPIOE(19),
		.end     = IRQ_GPIOE(19),
		.flags   = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
	},
};

struct sja1000_platform_data pcm970_sja1000_platform_data = {
	.clock		= 16000000 / 2,
	.ocr		= 0x40 | 0x18,
	.cdr		= 0x40,
};

static struct platform_device pcm970_sja1000 = {
	.name = "sja1000_platform",
	.dev = {
		.platform_data = &pcm970_sja1000_platform_data,
	},
	.resource = pcm970_sja1000_resources,
	.num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
};

/*
 * system init for baseboard usage. Will be called by pcm038 init.
 *
 * Add platform devices present on this baseboard and init
 * them from CPU side as far as required to use them later on
 */
void __init pcm970_baseboard_init(void)
{
	mxc_gpio_setup_multiple_pins(pcm970_pins, ARRAY_SIZE(pcm970_pins),
			"PCM970");

	mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
	mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN);
	mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
	platform_device_register(&pcm970_sja1000);
}
