Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * linux/arch/arm/mach-sa1100/collie.c
0003  *
0004  * May be copied or modified under the terms of the GNU General Public
0005  * License.  See linux/COPYING for more information.
0006  *
0007  * This file contains all Collie-specific tweaks.
0008  *
0009  * This program is free software; you can redistribute it and/or modify
0010  * it under the terms of the GNU General Public License version 2 as
0011  * published by the Free Software Foundation.
0012  *
0013  * ChangeLog:
0014  *  2006 Pavel Machek <pavel@ucw.cz>
0015  *  03-06-2004 John Lenz <lenz@cs.wisc.edu>
0016  *  06-04-2002 Chris Larson <kergoth@digitalnemesis.net>
0017  *  04-16-2001 Lineo Japan,Inc. ...
0018  */
0019 
0020 #include <linux/init.h>
0021 #include <linux/kernel.h>
0022 #include <linux/tty.h>
0023 #include <linux/delay.h>
0024 #include <linux/platform_data/sa11x0-serial.h>
0025 #include <linux/platform_device.h>
0026 #include <linux/mfd/ucb1x00.h>
0027 #include <linux/mtd/mtd.h>
0028 #include <linux/mtd/partitions.h>
0029 #include <linux/timer.h>
0030 #include <linux/gpio_keys.h>
0031 #include <linux/input.h>
0032 #include <linux/gpio.h>
0033 #include <linux/gpio/machine.h>
0034 #include <linux/power/gpio-charger.h>
0035 
0036 #include <video/sa1100fb.h>
0037 
0038 #include <mach/hardware.h>
0039 #include <asm/mach-types.h>
0040 #include <asm/page.h>
0041 #include <asm/setup.h>
0042 #include <mach/collie.h>
0043 
0044 #include <asm/mach/arch.h>
0045 #include <asm/mach/flash.h>
0046 #include <asm/mach/map.h>
0047 #include <linux/platform_data/irda-sa11x0.h>
0048 
0049 #include <asm/hardware/scoop.h>
0050 #include <asm/mach/sharpsl_param.h>
0051 #include <asm/hardware/locomo.h>
0052 #include <linux/platform_data/mfd-mcp-sa11x0.h>
0053 #include <mach/irqs.h>
0054 
0055 #include "generic.h"
0056 
0057 static struct resource collie_scoop_resources[] = {
0058     [0] = DEFINE_RES_MEM(0x40800000, SZ_4K),
0059 };
0060 
0061 static struct scoop_config collie_scoop_setup = {
0062     .io_dir     = COLLIE_SCOOP_IO_DIR,
0063     .io_out     = COLLIE_SCOOP_IO_OUT,
0064     .gpio_base  = COLLIE_SCOOP_GPIO_BASE,
0065 };
0066 
0067 struct platform_device colliescoop_device = {
0068     .name       = "sharp-scoop",
0069     .id     = -1,
0070     .dev        = {
0071         .platform_data  = &collie_scoop_setup,
0072     },
0073     .num_resources  = ARRAY_SIZE(collie_scoop_resources),
0074     .resource   = collie_scoop_resources,
0075 };
0076 
0077 static struct scoop_pcmcia_dev collie_pcmcia_scoop[] = {
0078     {
0079     .dev        = &colliescoop_device.dev,
0080     .irq        = COLLIE_IRQ_GPIO_CF_IRQ,
0081     .cd_irq     = COLLIE_IRQ_GPIO_CF_CD,
0082     .cd_irq_str = "PCMCIA0 CD",
0083     },
0084 };
0085 
0086 static struct scoop_pcmcia_config collie_pcmcia_config = {
0087     .devs       = &collie_pcmcia_scoop[0],
0088     .num_devs   = 1,
0089 };
0090 
0091 static struct ucb1x00_plat_data collie_ucb1x00_data = {
0092     .gpio_base  = COLLIE_TC35143_GPIO_BASE,
0093 };
0094 
0095 static struct mcp_plat_data collie_mcp_data = {
0096     .mccr0      = MCCR0_ADM | MCCR0_ExtClk,
0097     .sclk_rate  = 9216000,
0098     .codec_pdata    = &collie_ucb1x00_data,
0099 };
0100 
0101 /* Battery management GPIOs */
0102 static struct gpiod_lookup_table collie_battery_gpiod_table = {
0103     /* the MCP codec mcp0 has the ucb1x00 as attached device */
0104     .dev_id = "ucb1x00",
0105     .table = {
0106         /* This is found on the main GPIO on the SA1100 */
0107         GPIO_LOOKUP("gpio", COLLIE_GPIO_CO,
0108                 "main battery full", GPIO_ACTIVE_HIGH),
0109         GPIO_LOOKUP("gpio", COLLIE_GPIO_MAIN_BAT_LOW,
0110                 "main battery low", GPIO_ACTIVE_HIGH),
0111         /*
0112          * This is GPIO 0 on the Scoop expander, which is registered
0113          * from common/scoop.c with this gpio chip label.
0114          */
0115         GPIO_LOOKUP("sharp-scoop", 0,
0116                 "main charge on", GPIO_ACTIVE_HIGH),
0117         { },
0118     },
0119 };
0120 
0121 static int collie_ir_startup(struct device *dev)
0122 {
0123     int rc = gpio_request(COLLIE_GPIO_IR_ON, "IrDA");
0124     if (rc)
0125         return rc;
0126     rc = gpio_direction_output(COLLIE_GPIO_IR_ON, 1);
0127 
0128     if (!rc)
0129         return 0;
0130 
0131     gpio_free(COLLIE_GPIO_IR_ON);
0132     return rc;
0133 }
0134 
0135 static void collie_ir_shutdown(struct device *dev)
0136 {
0137     gpio_free(COLLIE_GPIO_IR_ON);
0138 }
0139 
0140 static int collie_ir_set_power(struct device *dev, unsigned int state)
0141 {
0142     gpio_set_value(COLLIE_GPIO_IR_ON, !state);
0143     return 0;
0144 }
0145 
0146 static struct irda_platform_data collie_ir_data = {
0147     .startup = collie_ir_startup,
0148     .shutdown = collie_ir_shutdown,
0149     .set_power = collie_ir_set_power,
0150 };
0151 
0152 /*
0153  * Collie AC IN
0154  */
0155 static struct gpiod_lookup_table collie_power_gpiod_table = {
0156     .dev_id = "gpio-charger",
0157     .table = {
0158         GPIO_LOOKUP("gpio", COLLIE_GPIO_AC_IN,
0159                 NULL, GPIO_ACTIVE_HIGH),
0160         { },
0161     },
0162 };
0163 
0164 static char *collie_ac_supplied_to[] = {
0165     "main-battery",
0166     "backup-battery",
0167 };
0168 
0169 static struct gpio_charger_platform_data collie_power_data = {
0170     .name           = "charger",
0171     .type           = POWER_SUPPLY_TYPE_MAINS,
0172     .supplied_to        = collie_ac_supplied_to,
0173     .num_supplicants    = ARRAY_SIZE(collie_ac_supplied_to),
0174 };
0175 
0176 static struct platform_device collie_power_device = {
0177     .name           = "gpio-charger",
0178     .id         = -1,
0179     .dev.platform_data  = &collie_power_data,
0180 };
0181 
0182 #ifdef CONFIG_SHARP_LOCOMO
0183 /*
0184  * low-level UART features.
0185  */
0186 struct platform_device collie_locomo_device;
0187 
0188 static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
0189 {
0190     if (mctrl & TIOCM_RTS)
0191         locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0);
0192     else
0193         locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1);
0194 
0195     if (mctrl & TIOCM_DTR)
0196         locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0);
0197     else
0198         locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1);
0199 }
0200 
0201 static u_int collie_uart_get_mctrl(struct uart_port *port)
0202 {
0203     int ret = TIOCM_CD;
0204     unsigned int r;
0205 
0206     r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
0207     if (r == -ENODEV)
0208         return ret;
0209     if (r & LOCOMO_GPIO_CTS)
0210         ret |= TIOCM_CTS;
0211     if (r & LOCOMO_GPIO_DSR)
0212         ret |= TIOCM_DSR;
0213 
0214     return ret;
0215 }
0216 
0217 static struct sa1100_port_fns collie_port_fns __initdata = {
0218     .set_mctrl  = collie_uart_set_mctrl,
0219     .get_mctrl  = collie_uart_get_mctrl,
0220 };
0221 
0222 static int collie_uart_probe(struct locomo_dev *dev)
0223 {
0224     return 0;
0225 }
0226 
0227 static struct locomo_driver collie_uart_driver = {
0228     .drv = {
0229         .name = "collie_uart",
0230     },
0231     .devid  = LOCOMO_DEVID_UART,
0232     .probe  = collie_uart_probe,
0233 };
0234 
0235 static int __init collie_uart_init(void)
0236 {
0237     return locomo_driver_register(&collie_uart_driver);
0238 }
0239 device_initcall(collie_uart_init);
0240 
0241 #endif
0242 
0243 
0244 static struct resource locomo_resources[] = {
0245     [0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
0246     [1] = DEFINE_RES_IRQ(IRQ_GPIO25),
0247 };
0248 
0249 static struct locomo_platform_data locomo_info = {
0250     .irq_base   = IRQ_BOARD_START,
0251 };
0252 
0253 struct platform_device collie_locomo_device = {
0254     .name       = "locomo",
0255     .id     = 0,
0256     .dev        = {
0257         .platform_data  = &locomo_info,
0258     },
0259     .num_resources  = ARRAY_SIZE(locomo_resources),
0260     .resource   = locomo_resources,
0261 };
0262 
0263 static struct gpio_keys_button collie_gpio_keys[] = {
0264     {
0265         .type   = EV_PWR,
0266         .code   = KEY_RESERVED,
0267         .gpio   = COLLIE_GPIO_ON_KEY,
0268         .desc   = "On key",
0269         .wakeup = 1,
0270         .active_low = 1,
0271     },
0272     {
0273         .type   = EV_PWR,
0274         .code   = KEY_WAKEUP,
0275         .gpio   = COLLIE_GPIO_WAKEUP,
0276         .desc   = "Sync",
0277         .wakeup = 1,
0278         .active_low = 1,
0279     },
0280 };
0281 
0282 static struct gpio_keys_platform_data collie_gpio_keys_data = {
0283     .buttons    = collie_gpio_keys,
0284     .nbuttons   = ARRAY_SIZE(collie_gpio_keys),
0285 };
0286 
0287 static struct platform_device collie_gpio_keys_device = {
0288     .name   = "gpio-keys",
0289     .id = -1,
0290     .dev    = {
0291         .platform_data = &collie_gpio_keys_data,
0292     },
0293 };
0294 
0295 static struct platform_device *devices[] __initdata = {
0296     &collie_locomo_device,
0297     &colliescoop_device,
0298     &collie_power_device,
0299     &collie_gpio_keys_device,
0300 };
0301 
0302 static struct mtd_partition collie_partitions[] = {
0303     {
0304         .name       = "bootloader",
0305         .offset     = 0,
0306         .size       = 0x000C0000,
0307         .mask_flags = MTD_WRITEABLE
0308     }, {
0309         .name       = "kernel",
0310         .offset     = MTDPART_OFS_APPEND,
0311         .size       = 0x00100000,
0312     }, {
0313         .name       = "rootfs",
0314         .offset     = MTDPART_OFS_APPEND,
0315         .size       = 0x00e20000,
0316     }, {
0317         .name       = "bootblock",
0318         .offset     = MTDPART_OFS_APPEND,
0319         .size       = 0x00020000,
0320         .mask_flags = MTD_WRITEABLE
0321     }
0322 };
0323 
0324 static int collie_flash_init(void)
0325 {
0326     int rc = gpio_request(COLLIE_GPIO_VPEN, "flash Vpp enable");
0327     if (rc)
0328         return rc;
0329 
0330     rc = gpio_direction_output(COLLIE_GPIO_VPEN, 1);
0331     if (rc)
0332         gpio_free(COLLIE_GPIO_VPEN);
0333 
0334     return rc;
0335 }
0336 
0337 static void collie_set_vpp(int vpp)
0338 {
0339     gpio_set_value(COLLIE_GPIO_VPEN, vpp);
0340 }
0341 
0342 static void collie_flash_exit(void)
0343 {
0344     gpio_free(COLLIE_GPIO_VPEN);
0345 }
0346 
0347 static struct flash_platform_data collie_flash_data = {
0348     .map_name   = "cfi_probe",
0349     .init       = collie_flash_init,
0350     .set_vpp    = collie_set_vpp,
0351     .exit       = collie_flash_exit,
0352     .parts      = collie_partitions,
0353     .nr_parts   = ARRAY_SIZE(collie_partitions),
0354 };
0355 
0356 static struct resource collie_flash_resources[] = {
0357     DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
0358 };
0359 
0360 static struct sa1100fb_mach_info collie_lcd_info = {
0361     .pixclock   = 171521,   .bpp        = 16,
0362     .xres       = 320,      .yres       = 240,
0363 
0364     .hsync_len  = 5,        .vsync_len  = 1,
0365     .left_margin    = 11,       .upper_margin   = 2,
0366     .right_margin   = 30,       .lower_margin   = 0,
0367 
0368     .sync       = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
0369 
0370     .lccr0      = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
0371     .lccr3      = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
0372 
0373 #ifdef CONFIG_BACKLIGHT_LOCOMO
0374     .lcd_power  = locomolcd_power
0375 #endif
0376 };
0377 
0378 static void __init collie_init(void)
0379 {
0380     int ret = 0;
0381 
0382     /* cpu initialize */
0383     GAFR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK |
0384         GPIO_MCP_CLK | GPIO_32_768kHz;
0385 
0386     GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 |
0387         GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD |
0388         GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK |
0389         _COLLIE_GPIO_UCB1x00_RESET | _COLLIE_GPIO_nMIC_ON |
0390         _COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz;
0391 
0392     PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 |
0393         PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS |
0394         PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM;
0395 
0396     PWER = 0;
0397 
0398     PGSR = _COLLIE_GPIO_nREMOCON_ON;
0399 
0400     PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4;
0401 
0402     PCFR = PCFR_OPDE;
0403 
0404     GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
0405 
0406     sa11x0_ppc_configure_mcp();
0407 
0408 
0409     platform_scoop_config = &collie_pcmcia_config;
0410 
0411     gpiod_add_lookup_table(&collie_power_gpiod_table);
0412     gpiod_add_lookup_table(&collie_battery_gpiod_table);
0413 
0414     ret = platform_add_devices(devices, ARRAY_SIZE(devices));
0415     if (ret) {
0416         printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
0417     }
0418 
0419     sa11x0_register_lcd(&collie_lcd_info);
0420     sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
0421                 ARRAY_SIZE(collie_flash_resources));
0422     sa11x0_register_mcp(&collie_mcp_data);
0423     sa11x0_register_irda(&collie_ir_data);
0424 
0425     sharpsl_save_param();
0426 }
0427 
0428 static struct map_desc collie_io_desc[] __initdata = {
0429     {   /* 32M main flash (cs0) */
0430         .virtual    = 0xe8000000,
0431         .pfn        = __phys_to_pfn(0x00000000),
0432         .length     = 0x02000000,
0433         .type       = MT_DEVICE
0434     }, {    /* 32M boot flash (cs1) */
0435         .virtual    = 0xea000000,
0436         .pfn        = __phys_to_pfn(0x08000000),
0437         .length     = 0x02000000,
0438         .type       = MT_DEVICE
0439     }
0440 };
0441 
0442 static void __init collie_map_io(void)
0443 {
0444     sa1100_map_io();
0445     iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
0446 
0447 #ifdef CONFIG_SHARP_LOCOMO
0448     sa1100_register_uart_fns(&collie_port_fns);
0449 #endif
0450     sa1100_register_uart(0, 3);
0451     sa1100_register_uart(1, 1);
0452 }
0453 
0454 MACHINE_START(COLLIE, "Sharp-Collie")
0455     .map_io     = collie_map_io,
0456     .nr_irqs    = SA1100_NR_IRQS,
0457     .init_irq   = sa1100_init_irq,
0458     .init_time  = sa1100_timer_init,
0459     .init_machine   = collie_init,
0460     .init_late  = sa11x0_init_late,
0461     .restart    = sa11x0_restart,
0462 MACHINE_END