[ARM] pxa: Add multi-io support for e-series

This patchset provides support for the TMIO based IO controller used in the
    Toshiba e-series PDAs.

    Signed-off-by: Ian Molton <spyro@f2s.com>
    Acked-by: Samuel Ortiz <sameo@openedhand.com>
    Acked-by: Eric Miao <eric.y.miao@gmail.com>
This commit is contained in:
Ian Molton 2008-09-26 13:38:59 +01:00
parent f4ad9a9624
commit b1ae1b7b27
9 changed files with 320 additions and 8 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Hardware definitions for the Toshiba eseries PDAs * Hardware definitions for the Toshiba e330 PDAs
* *
* Copyright (c) 2003 Ian Molton <spyro@f2s.com> * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
* *
@ -12,6 +12,9 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/mfd/tc6387xb.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
@ -19,13 +22,44 @@
#include <mach/mfp-pxa25x.h> #include <mach/mfp-pxa25x.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/pxa-regs.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h> #include <mach/udc.h>
#include "generic.h" #include "generic.h"
#include "eseries.h" #include "eseries.h"
#include "clock.h"
/* -------------------- e330 tc6387xb parameters -------------------- */
static struct tc6387xb_platform_data e330_tc6387xb_info = {
.enable = &eseries_tmio_enable,
.disable = &eseries_tmio_disable,
.suspend = &eseries_tmio_suspend,
.resume = &eseries_tmio_resume,
};
static struct platform_device e330_tc6387xb_device = {
.name = "tc6387xb",
.id = -1,
.dev = {
.platform_data = &e330_tc6387xb_info,
},
.num_resources = 2,
.resource = eseries_tmio_resources,
};
/* --------------------------------------------------------------- */
static struct platform_device *devices[] __initdata = {
&e330_tc6387xb_device,
};
static void __init e330_init(void) static void __init e330_init(void)
{ {
eseries_register_clks();
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_udc_info(&e7xx_udc_mach_info); pxa_set_udc_info(&e7xx_udc_mach_info);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Hardware definitions for the Toshiba eseries PDAs * Hardware definitions for the Toshiba e350 PDAs
* *
* Copyright (c) 2003 Ian Molton <spyro@f2s.com> * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
* *
@ -12,20 +12,54 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/mfd/t7l66xb.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/mfp-pxa25x.h> #include <mach/mfp-pxa25x.h>
#include <mach/pxa-regs.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h> #include <mach/udc.h>
#include "generic.h" #include "generic.h"
#include "eseries.h" #include "eseries.h"
#include "clock.h"
/* -------------------- e350 t7l66xb parameters -------------------- */
static struct t7l66xb_platform_data e350_t7l66xb_info = {
.irq_base = IRQ_BOARD_START,
.enable = &eseries_tmio_enable,
.suspend = &eseries_tmio_suspend,
.resume = &eseries_tmio_resume,
};
static struct platform_device e350_t7l66xb_device = {
.name = "t7l66xb",
.id = -1,
.dev = {
.platform_data = &e350_t7l66xb_info,
},
.num_resources = 2,
.resource = eseries_tmio_resources,
};
/* ---------------------------------------------------------- */
static struct platform_device *devices[] __initdata = {
&e350_t7l66xb_device,
};
static void __init e350_init(void) static void __init e350_init(void)
{ {
eseries_register_clks();
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_udc_info(&e7xx_udc_mach_info); pxa_set_udc_info(&e7xx_udc_mach_info);
} }

View File

@ -12,20 +12,26 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/mfd/t7l66xb.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/pxa-regs.h>
#include <mach/mfp-pxa25x.h> #include <mach/mfp-pxa25x.h>
#include <mach/pxa-regs.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/eseries-gpio.h>
#include <mach/pxafb.h> #include <mach/pxafb.h>
#include <mach/udc.h> #include <mach/udc.h>
#include "generic.h" #include "generic.h"
#include "eseries.h" #include "eseries.h"
#include "clock.h"
/* ------------------------ E400 LCD definitions ------------------------ */ /* ------------------------ E400 LCD definitions ------------------------ */
@ -65,7 +71,10 @@ static unsigned long e400_pin_config[] __initdata = {
GPIO42_BTUART_RXD, GPIO42_BTUART_RXD,
GPIO43_BTUART_TXD, GPIO43_BTUART_TXD,
GPIO44_BTUART_CTS, GPIO44_BTUART_CTS,
GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
/* TMIO controller */
GPIO19_GPIO, /* t7l66xb #PCLR */
GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */
/* wakeup */ /* wakeup */
GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
@ -73,10 +82,60 @@ static unsigned long e400_pin_config[] __initdata = {
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
static struct mtd_partition partition_a = {
.name = "Internal NAND flash",
.offset = 0,
.size = MTDPART_SIZ_FULL,
};
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
static struct nand_bbt_descr e400_t7l66xb_nand_bbt = {
.options = 0,
.offs = 4,
.len = 2,
.pattern = scan_ff_pattern
};
static struct tmio_nand_data e400_t7l66xb_nand_config = {
.num_partitions = 1,
.partition = &partition_a,
.badblock_pattern = &e400_t7l66xb_nand_bbt,
};
static struct t7l66xb_platform_data e400_t7l66xb_info = {
.irq_base = IRQ_BOARD_START,
.enable = &eseries_tmio_enable,
.suspend = &eseries_tmio_suspend,
.resume = &eseries_tmio_resume,
.nand_data = &e400_t7l66xb_nand_config,
};
static struct platform_device e400_t7l66xb_device = {
.name = "t7l66xb",
.id = -1,
.dev = {
.platform_data = &e400_t7l66xb_info,
},
.num_resources = 2,
.resource = eseries_tmio_resources,
};
/* ---------------------------------------------------------- */
static struct platform_device *devices[] __initdata = {
&e400_t7l66xb_device,
};
static void __init e400_init(void) static void __init e400_init(void)
{ {
pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config)); pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config));
/* Fixme - e400 may have a switched clock */
eseries_register_clks();
eseries_get_tmio_gpios();
set_pxa_fb_info(&e400_pxafb_mach_info); set_pxa_fb_info(&e400_pxafb_mach_info);
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_udc_info(&e7xx_udc_mach_info); pxa_set_udc_info(&e7xx_udc_mach_info);
} }

View File

@ -15,6 +15,8 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/clk.h>
#include <linux/mfd/t7l66xb.h>
#include <video/w100fb.h> #include <video/w100fb.h>
@ -23,13 +25,16 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/mfp-pxa25x.h> #include <mach/mfp-pxa25x.h>
#include <mach/pxa-regs.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h> #include <mach/udc.h>
#include <mach/irda.h> #include <mach/irda.h>
#include "generic.h" #include "generic.h"
#include "eseries.h" #include "eseries.h"
#include "clock.h"
#include "devices.h"
/* ------------------------ e740 video support --------------------------- */ /* ------------------------ e740 video support --------------------------- */
@ -117,7 +122,10 @@ static unsigned long e740_pin_config[] __initdata = {
GPIO42_BTUART_RXD, GPIO42_BTUART_RXD,
GPIO43_BTUART_TXD, GPIO43_BTUART_TXD,
GPIO44_BTUART_CTS, GPIO44_BTUART_CTS,
GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
/* TMIO controller */
GPIO19_GPIO, /* t7l66xb #PCLR */
GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */
/* UDC */ /* UDC */
GPIO13_GPIO, GPIO13_GPIO,
@ -150,15 +158,39 @@ static unsigned long e740_pin_config[] __initdata = {
GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
}; };
/* -------------------- e740 t7l66xb parameters -------------------- */
static struct t7l66xb_platform_data e740_t7l66xb_info = {
.irq_base = IRQ_BOARD_START,
.enable = &eseries_tmio_enable,
.suspend = &eseries_tmio_suspend,
.resume = &eseries_tmio_resume,
};
static struct platform_device e740_t7l66xb_device = {
.name = "t7l66xb",
.id = -1,
.dev = {
.platform_data = &e740_t7l66xb_info,
},
.num_resources = 2,
.resource = eseries_tmio_resources,
};
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&e740_fb_device, &e740_fb_device,
&e740_t7l66xb_device,
}; };
static void __init e740_init(void) static void __init e740_init(void)
{ {
pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config)); pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
eseries_register_clks();
clk_add_alias("CLK_CK48M", &e740_t7l66xb_device.dev,
"UDCCLK", &pxa25x_device_udc.dev),
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices)); platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_udc_info(&e7xx_udc_mach_info); pxa_set_udc_info(&e7xx_udc_mach_info);
e7xx_irda_init(); e7xx_irda_init();

View File

@ -15,6 +15,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/mfd/tc6393xb.h>
#include <video/w100fb.h> #include <video/w100fb.h>
@ -23,12 +24,15 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/mfp-pxa25x.h> #include <mach/mfp-pxa25x.h>
#include <mach/pxa-regs.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h> #include <mach/udc.h>
#include <mach/irda.h> #include <mach/irda.h>
#include "generic.h" #include "generic.h"
#include "eseries.h" #include "eseries.h"
#include "clock.h"
/* ---------------------- E750 LCD definitions -------------------- */ /* ---------------------- E750 LCD definitions -------------------- */
@ -101,14 +105,41 @@ static struct platform_device e750_fb_device = {
.resource = e750_fb_resources, .resource = e750_fb_resources,
}; };
/* ----------------------------------------------------------------------- */ /* ----------------- e750 tc6393xb parameters ------------------ */
static struct tc6393xb_platform_data e750_tc6393xb_info = {
.irq_base = IRQ_BOARD_START,
.scr_pll2cr = 0x0cc1,
.scr_gper = 0,
.gpio_base = -1,
.suspend = &eseries_tmio_suspend,
.resume = &eseries_tmio_resume,
.enable = &eseries_tmio_enable,
.disable = &eseries_tmio_disable,
};
static struct platform_device e750_tc6393xb_device = {
.name = "tc6393xb",
.id = -1,
.dev = {
.platform_data = &e750_tc6393xb_info,
},
.num_resources = 2,
.resource = eseries_tmio_resources,
};
/* ------------------------------------------------------------- */
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&e750_fb_device, &e750_fb_device,
&e750_tc6393xb_device,
}; };
static void __init e750_init(void) static void __init e750_init(void)
{ {
clk_add_alias("CLK_CK3P6MI", &e750_tc6393xb_device.dev,
"GPIO11_CLK", NULL),
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices)); platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_udc_info(&e7xx_udc_mach_info); pxa_set_udc_info(&e7xx_udc_mach_info);
e7xx_irda_init(); e7xx_irda_init();

View File

@ -15,6 +15,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/mfd/tc6393xb.h>
#include <video/w100fb.h> #include <video/w100fb.h>
@ -23,12 +24,14 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/mfp-pxa25x.h> #include <mach/mfp-pxa25x.h>
#include <mach/pxa-regs.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/eseries-gpio.h> #include <mach/eseries-gpio.h>
#include <mach/udc.h> #include <mach/udc.h>
#include "generic.h" #include "generic.h"
#include "eseries.h" #include "eseries.h"
#include "clock.h"
/* ------------------------ e800 LCD definitions ------------------------- */ /* ------------------------ e800 LCD definitions ------------------------- */
@ -160,14 +163,41 @@ static struct pxa2xx_udc_mach_info e800_udc_mach_info = {
.gpio_pullup_inverted = 1 .gpio_pullup_inverted = 1
}; };
/* ----------------- e800 tc6393xb parameters ------------------ */
static struct tc6393xb_platform_data e800_tc6393xb_info = {
.irq_base = IRQ_BOARD_START,
.scr_pll2cr = 0x0cc1,
.scr_gper = 0,
.gpio_base = -1,
.suspend = &eseries_tmio_suspend,
.resume = &eseries_tmio_resume,
.enable = &eseries_tmio_enable,
.disable = &eseries_tmio_disable,
};
static struct platform_device e800_tc6393xb_device = {
.name = "tc6393xb",
.id = -1,
.dev = {
.platform_data = &e800_tc6393xb_info,
},
.num_resources = 2,
.resource = eseries_tmio_resources,
};
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&e800_fb_device, &e800_fb_device,
&e800_tc6393xb_device,
}; };
static void __init e800_init(void) static void __init e800_init(void)
{ {
clk_add_alias("CLK_CK3P6MI", &e800_tc6393xb_device.dev,
"GPIO11_CLK", NULL),
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices)); platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_udc_info(&e800_udc_mach_info); pxa_set_udc_info(&e800_udc_mach_info);
} }

View File

@ -13,6 +13,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <asm/setup.h> #include <asm/setup.h>
@ -26,6 +27,7 @@
#include <mach/irda.h> #include <mach/irda.h>
#include "generic.h" #include "generic.h"
#include "clock.h"
/* Only e800 has 128MB RAM */ /* Only e800 has 128MB RAM */
void __init eseries_fixup(struct machine_desc *desc, void __init eseries_fixup(struct machine_desc *desc,
@ -86,3 +88,82 @@ struct pxaficp_platform_data e7xx_ficp_platform_data = {
.shutdown = e7xx_irda_shutdown, .shutdown = e7xx_irda_shutdown,
}; };
int eseries_tmio_enable(struct platform_device *dev)
{
/* Reset - bring SUSPEND high before PCLR */
gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0);
gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 0);
msleep(1);
gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 1);
msleep(1);
gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 1);
msleep(1);
return 0;
}
int eseries_tmio_disable(struct platform_device *dev)
{
gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0);
gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 0);
return 0;
}
int eseries_tmio_suspend(struct platform_device *dev)
{
gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0);
return 0;
}
int eseries_tmio_resume(struct platform_device *dev)
{
gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 1);
msleep(1);
return 0;
}
void eseries_get_tmio_gpios(void)
{
gpio_request(GPIO_ESERIES_TMIO_SUSPEND, NULL);
gpio_request(GPIO_ESERIES_TMIO_PCLR, NULL);
gpio_direction_output(GPIO_ESERIES_TMIO_SUSPEND, 0);
gpio_direction_output(GPIO_ESERIES_TMIO_PCLR, 0);
}
/* TMIO controller uses the same resources on all e-series machines. */
struct resource eseries_tmio_resources[] = {
[0] = {
.start = PXA_CS4_PHYS,
.end = PXA_CS4_PHYS + 0x1fffff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_GPIO(GPIO_ESERIES_TMIO_IRQ),
.end = IRQ_GPIO(GPIO_ESERIES_TMIO_IRQ),
.flags = IORESOURCE_IRQ,
},
};
/* Some e-series hardware cannot control the 32K clock */
static void clk_32k_dummy(struct clk *clk)
{
}
static const struct clkops clk_32k_dummy_ops = {
.enable = clk_32k_dummy,
.disable = clk_32k_dummy,
};
static struct clk tmio_dummy_clk = {
.ops = &clk_32k_dummy_ops,
.rate = 32768,
};
static struct clk_lookup eseries_clkregs[] = {
INIT_CLKREG(&tmio_dummy_clk, NULL, "CLK_CK32K"),
};
void eseries_register_clks(void)
{
clks_register(eseries_clkregs, ARRAY_SIZE(eseries_clkregs));
}

View File

@ -5,3 +5,12 @@ extern struct pxa2xx_udc_mach_info e7xx_udc_mach_info;
extern struct pxaficp_platform_data e7xx_ficp_platform_data; extern struct pxaficp_platform_data e7xx_ficp_platform_data;
extern int e7xx_irda_init(void); extern int e7xx_irda_init(void);
extern int eseries_tmio_enable(struct platform_device *dev);
extern int eseries_tmio_disable(struct platform_device *dev);
extern int eseries_tmio_suspend(struct platform_device *dev);
extern int eseries_tmio_resume(struct platform_device *dev);
extern void eseries_get_tmio_gpios(void);
extern struct resource eseries_tmio_resources[];
extern struct platform_device e300_tc6387xb_device;
extern void eseries_register_clks(void);

View File

@ -47,4 +47,6 @@
/* ASIC related GPIOs */ /* ASIC related GPIOs */
#define GPIO_ESERIES_TMIO_IRQ 5 #define GPIO_ESERIES_TMIO_IRQ 5
#define GPIO_ESERIES_TMIO_PCLR 19
#define GPIO_ESERIES_TMIO_SUSPEND 45
#define GPIO_E800_ANGELX_IRQ 8 #define GPIO_E800_ANGELX_IRQ 8