/*
 *  linux/arch/arm/mach-pxa/idp.c
 *
 *  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.
 *
 *  Copyright (c) 2001 Cliff Brake, Accelent Systems Inc.
 *
 *  2001-09-13: Cliff Brake <cbrake@accelent.com>
 *              Initial code
 *
 *  2005-02-15: Cliff Brake <cliff.brake@gmail.com>
 *  		<http://www.vibren.com> <http://bec-systems.com>
 *              Updated for 2.6 kernel
 *
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/fb.h>

#include <asm/setup.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/irq.h>

#include <asm/mach/arch.h>
#include <asm/mach/map.h>

#include <mach/pxa25x.h>
#include <mach/idp.h>
#include <linux/platform_data/video-pxafb.h>
#include <mach/bitfield.h>
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/smc91x.h>

#include "generic.h"
#include "devices.h"

/* TODO:
 * - add pxa2xx_audio_ops_t device structure
 * - Ethernet interrupt
 */

static unsigned long idp_pin_config[] __initdata = {
	/* LCD */
	GPIOxx_LCD_DSTN_16BPP,

	/* BTUART */
	GPIO42_BTUART_RXD,
	GPIO43_BTUART_TXD,
	GPIO44_BTUART_CTS,
	GPIO45_BTUART_RTS,

	/* STUART */
	GPIO46_STUART_RXD,
	GPIO47_STUART_TXD,

	/* MMC */
	GPIO6_MMC_CLK,
	GPIO8_MMC_CS0,

	/* Ethernet */
	GPIO33_nCS_5,	/* Ethernet CS */
	GPIO4_GPIO,	/* Ethernet IRQ */
};

static struct resource smc91x_resources[] = {
	[0] = {
		.start	= (IDP_ETH_PHYS + 0x300),
		.end	= (IDP_ETH_PHYS + 0xfffff),
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.start	= PXA_GPIO_TO_IRQ(4),
		.end	= PXA_GPIO_TO_IRQ(4),
		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
	}
};

static struct smc91x_platdata smc91x_platdata = {
	.flags = SMC91X_USE_32BIT | SMC91X_USE_DMA | SMC91X_NOWAIT,
};

static struct platform_device smc91x_device = {
	.name		= "smc91x",
	.id		= 0,
	.num_resources	= ARRAY_SIZE(smc91x_resources),
	.resource	= smc91x_resources,
	.dev.platform_data = &smc91x_platdata,
};

static void idp_backlight_power(int on)
{
	if (on) {
		IDP_CPLD_LCD |= (1<<1);
	} else {
		IDP_CPLD_LCD &= ~(1<<1);
	}
}

static void idp_vlcd(int on)
{
	if (on) {
		IDP_CPLD_LCD |= (1<<2);
	} else {
		IDP_CPLD_LCD &= ~(1<<2);
	}
}

static void idp_lcd_power(int on, struct fb_var_screeninfo *var)
{
	if (on) {
		IDP_CPLD_LCD |= (1<<0);
	} else {
		IDP_CPLD_LCD &= ~(1<<0);
	}

	/* call idp_vlcd for now as core driver does not support
	 * both power and vlcd hooks.  Note, this is not technically
	 * the correct sequence, but seems to work.  Disclaimer:
	 * this may eventually damage the display.
	 */

	idp_vlcd(on);
}

static struct pxafb_mode_info sharp_lm8v31_mode = {
	.pixclock	= 270000,
	.xres		= 640,
	.yres		= 480,
	.bpp		= 16,
	.hsync_len	= 1,
	.left_margin	= 3,
	.right_margin	= 3,
	.vsync_len	= 1,
	.upper_margin	= 0,
	.lower_margin	= 0,
	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
	.cmap_greyscale	= 0,
};

static struct pxafb_mach_info sharp_lm8v31 = {
	.modes          = &sharp_lm8v31_mode,
	.num_modes      = 1,
	.cmap_inverse	= 0,
	.cmap_static	= 0,
	.lcd_conn	= LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL |
			  LCD_AC_BIAS_FREQ(255),
	.pxafb_backlight_power = &idp_backlight_power,
	.pxafb_lcd_power = &idp_lcd_power
};

static struct pxamci_platform_data idp_mci_platform_data = {
	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
	.gpio_card_detect	= -1,
	.gpio_card_ro		= -1,
	.gpio_power		= -1,
};

static void __init idp_init(void)
{
	printk("idp_init()\n");

	pxa2xx_mfp_config(ARRAY_AND_SIZE(idp_pin_config));
	pxa_set_ffuart_info(NULL);
	pxa_set_btuart_info(NULL);
	pxa_set_stuart_info(NULL);

	platform_device_register(&smc91x_device);
	//platform_device_register(&mst_audio_device);
	pxa_set_fb_info(NULL, &sharp_lm8v31);
	pxa_set_mci_info(&idp_mci_platform_data);
}

static struct map_desc idp_io_desc[] __initdata = {
  	{
		.virtual	=  IDP_COREVOLT_VIRT,
		.pfn		= __phys_to_pfn(IDP_COREVOLT_PHYS),
		.length		= IDP_COREVOLT_SIZE,
		.type		= MT_DEVICE
	}, {
		.virtual	=  IDP_CPLD_VIRT,
		.pfn		= __phys_to_pfn(IDP_CPLD_PHYS),
		.length		= IDP_CPLD_SIZE,
		.type		= MT_DEVICE
	}
};

static void __init idp_map_io(void)
{
	pxa25x_map_io();
	iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc));
}

/* LEDs */
#if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
struct idp_led {
	struct led_classdev     cdev;
	u8                      mask;
};

/*
 * The triggers lines up below will only be used if the
 * LED triggers are compiled in.
 */
static const struct {
	const char *name;
	const char *trigger;
} idp_leds[] = {
	{ "idp:green", "heartbeat", },
	{ "idp:red", "cpu0", },
};

static void idp_led_set(struct led_classdev *cdev,
		enum led_brightness b)
{
	struct idp_led *led = container_of(cdev,
			struct idp_led, cdev);
	u32 reg = IDP_CPLD_LED_CONTROL;

	if (b != LED_OFF)
		reg &= ~led->mask;
	else
		reg |= led->mask;

	IDP_CPLD_LED_CONTROL = reg;
}

static enum led_brightness idp_led_get(struct led_classdev *cdev)
{
	struct idp_led *led = container_of(cdev,
			struct idp_led, cdev);

	return (IDP_CPLD_LED_CONTROL & led->mask) ? LED_OFF : LED_FULL;
}

static int __init idp_leds_init(void)
{
	int i;

	if (!machine_is_pxa_idp())
		return -ENODEV;

	for (i = 0; i < ARRAY_SIZE(idp_leds); i++) {
		struct idp_led *led;

		led = kzalloc(sizeof(*led), GFP_KERNEL);
		if (!led)
			break;

		led->cdev.name = idp_leds[i].name;
		led->cdev.brightness_set = idp_led_set;
		led->cdev.brightness_get = idp_led_get;
		led->cdev.default_trigger = idp_leds[i].trigger;

		if (i == 0)
			led->mask = IDP_HB_LED;
		else
			led->mask = IDP_BUSY_LED;

		if (led_classdev_register(NULL, &led->cdev) < 0) {
			kfree(led);
			break;
		}
	}

	return 0;
}

/*
 * Since we may have triggers on any subsystem, defer registration
 * until after subsystem_init.
 */
fs_initcall(idp_leds_init);
#endif

MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
	/* Maintainer: Vibren Technologies */
	.map_io		= idp_map_io,
	.nr_irqs	= PXA_NR_IRQS,
	.init_irq	= pxa25x_init_irq,
	.handle_irq	= pxa25x_handle_irq,
	.init_time	= pxa_timer_init,
	.init_machine	= idp_init,
	.restart	= pxa_restart,
MACHINE_END
