Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * linux/arch/arm/mach-sa1100/simpad.c
0004  */
0005 
0006 #include <linux/module.h>
0007 #include <linux/gpio/machine.h>
0008 #include <linux/init.h>
0009 #include <linux/kernel.h>
0010 #include <linux/tty.h>
0011 #include <linux/proc_fs.h>
0012 #include <linux/string.h>
0013 #include <linux/pm.h>
0014 #include <linux/platform_data/sa11x0-serial.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/mfd/ucb1x00.h>
0017 #include <linux/mtd/mtd.h>
0018 #include <linux/mtd/partitions.h>
0019 #include <linux/io.h>
0020 #include <linux/gpio/driver.h>
0021 
0022 #include <mach/hardware.h>
0023 #include <asm/setup.h>
0024 #include <asm/irq.h>
0025 
0026 #include <asm/mach-types.h>
0027 #include <asm/mach/arch.h>
0028 #include <asm/mach/flash.h>
0029 #include <asm/mach/map.h>
0030 #include <linux/platform_data/mfd-mcp-sa11x0.h>
0031 #include <mach/simpad.h>
0032 #include <mach/irqs.h>
0033 
0034 #include <linux/serial_core.h>
0035 #include <linux/ioport.h>
0036 #include <linux/input.h>
0037 #include <linux/gpio_keys.h>
0038 #include <linux/leds.h>
0039 #include <linux/platform_data/i2c-gpio.h>
0040 
0041 #include "generic.h"
0042 
0043 /*
0044  * CS3 support
0045  */
0046 
0047 static long cs3_shadow;
0048 static spinlock_t cs3_lock;
0049 static struct gpio_chip cs3_gpio;
0050 
0051 long simpad_get_cs3_ro(void)
0052 {
0053     return readl(CS3_BASE);
0054 }
0055 EXPORT_SYMBOL(simpad_get_cs3_ro);
0056 
0057 long simpad_get_cs3_shadow(void)
0058 {
0059     return cs3_shadow;
0060 }
0061 EXPORT_SYMBOL(simpad_get_cs3_shadow);
0062 
0063 static void __simpad_write_cs3(void)
0064 {
0065     writel(cs3_shadow, CS3_BASE);
0066 }
0067 
0068 void simpad_set_cs3_bit(int value)
0069 {
0070     unsigned long flags;
0071 
0072     spin_lock_irqsave(&cs3_lock, flags);
0073     cs3_shadow |= value;
0074     __simpad_write_cs3();
0075     spin_unlock_irqrestore(&cs3_lock, flags);
0076 }
0077 EXPORT_SYMBOL(simpad_set_cs3_bit);
0078 
0079 void simpad_clear_cs3_bit(int value)
0080 {
0081     unsigned long flags;
0082 
0083     spin_lock_irqsave(&cs3_lock, flags);
0084     cs3_shadow &= ~value;
0085     __simpad_write_cs3();
0086     spin_unlock_irqrestore(&cs3_lock, flags);
0087 }
0088 EXPORT_SYMBOL(simpad_clear_cs3_bit);
0089 
0090 static void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
0091 {
0092     if (offset > 15)
0093         return;
0094     if (value)
0095         simpad_set_cs3_bit(1 << offset);
0096     else
0097         simpad_clear_cs3_bit(1 << offset);
0098 };
0099 
0100 static int cs3_gpio_get(struct gpio_chip *chip, unsigned offset)
0101 {
0102     if (offset > 15)
0103         return !!(simpad_get_cs3_ro() & (1 << (offset - 16)));
0104     return !!(simpad_get_cs3_shadow() & (1 << offset));
0105 };
0106 
0107 static int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
0108 {
0109     if (offset > 15)
0110         return 0;
0111     return -EINVAL;
0112 };
0113 
0114 static int cs3_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
0115     int value)
0116 {
0117     if (offset > 15)
0118         return -EINVAL;
0119     cs3_gpio_set(chip, offset, value);
0120     return 0;
0121 };
0122 
0123 static struct map_desc simpad_io_desc[] __initdata = {
0124     {   /* MQ200 */
0125         .virtual    =  0xf2800000,
0126         .pfn        = __phys_to_pfn(0x4b800000),
0127         .length     = 0x00800000,
0128         .type       = MT_DEVICE
0129     }, {    /* Simpad CS3 */
0130         .virtual    = (unsigned long)CS3_BASE,
0131         .pfn        = __phys_to_pfn(SA1100_CS3_PHYS),
0132         .length     = 0x00100000,
0133         .type       = MT_DEVICE
0134     },
0135 };
0136 
0137 
0138 static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
0139 {
0140     if (port->mapbase == (u_int)&Ser1UTCR0) {
0141         if (state)
0142         {
0143             simpad_clear_cs3_bit(RS232_ON);
0144             simpad_clear_cs3_bit(DECT_POWER_ON);
0145         }else
0146         {
0147             simpad_set_cs3_bit(RS232_ON);
0148             simpad_set_cs3_bit(DECT_POWER_ON);
0149         }
0150     }
0151 }
0152 
0153 static struct sa1100_port_fns simpad_port_fns __initdata = {
0154     .pm    = simpad_uart_pm,
0155 };
0156 
0157 
0158 static struct mtd_partition simpad_partitions[] = {
0159     {
0160         .name       = "SIMpad boot firmware",
0161         .size       = 0x00080000,
0162         .offset     = 0,
0163         .mask_flags = MTD_WRITEABLE,
0164     }, {
0165         .name       = "SIMpad kernel",
0166         .size       = 0x0010000,
0167         .offset     = MTDPART_OFS_APPEND,
0168     }, {
0169         .name       = "SIMpad root jffs2",
0170         .size       = MTDPART_SIZ_FULL,
0171         .offset     = MTDPART_OFS_APPEND,
0172     }
0173 };
0174 
0175 static struct flash_platform_data simpad_flash_data = {
0176     .map_name    = "cfi_probe",
0177     .parts       = simpad_partitions,
0178     .nr_parts    = ARRAY_SIZE(simpad_partitions),
0179 };
0180 
0181 
0182 static struct resource simpad_flash_resources [] = {
0183     DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M),
0184     DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M),
0185 };
0186 
0187 static struct ucb1x00_plat_data simpad_ucb1x00_data = {
0188     .gpio_base  = SIMPAD_UCB1X00_GPIO_BASE,
0189 };
0190 
0191 static struct mcp_plat_data simpad_mcp_data = {
0192     .mccr0      = MCCR0_ADM,
0193     .sclk_rate  = 11981000,
0194     .codec_pdata    = &simpad_ucb1x00_data,
0195 };
0196 
0197 
0198 
0199 static void __init simpad_map_io(void)
0200 {
0201     sa1100_map_io();
0202 
0203     iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
0204 
0205     /* Initialize CS3 */
0206     cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON |
0207         RS232_ON | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
0208     __simpad_write_cs3(); /* Spinlocks not yet initialized */
0209 
0210         sa1100_register_uart_fns(&simpad_port_fns);
0211     sa1100_register_uart(0, 3);  /* serial interface */
0212     sa1100_register_uart(1, 1);  /* DECT             */
0213 
0214     // Reassign UART 1 pins
0215     GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
0216     GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
0217     GPDR &= ~GPIO_UART_RXD;
0218     PPAR |= PPAR_UPR;
0219 
0220     /*
0221      * Set up registers for sleep mode.
0222      */
0223 
0224 
0225     PWER = PWER_GPIO0| PWER_RTC;
0226     PGSR = 0x818;
0227     PCFR = 0;
0228     PSDR = 0;
0229 
0230 }
0231 
0232 static void simpad_power_off(void)
0233 {
0234     local_irq_disable();
0235     cs3_shadow = SD_MEDIAQ;
0236     __simpad_write_cs3(); /* Bypass spinlock here */
0237 
0238     /* disable internal oscillator, float CS lines */
0239     PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
0240     /* enable wake-up on GPIO0 */
0241     PWER = GFER = GRER = PWER_GPIO0;
0242     /*
0243      * set scratchpad to zero, just in case it is used as a
0244      * restart address by the bootloader.
0245      */
0246     PSPR = 0;
0247     PGSR = 0;
0248     /* enter sleep mode */
0249     PMCR = PMCR_SF;
0250     while(1);
0251 
0252     local_irq_enable(); /* we won't ever call it */
0253 
0254 
0255 }
0256 
0257 /*
0258  * gpio_keys
0259 */
0260 
0261 static struct gpio_keys_button simpad_button_table[] = {
0262     { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" },
0263 };
0264 
0265 static struct gpio_keys_platform_data simpad_keys_data = {
0266     .buttons = simpad_button_table,
0267     .nbuttons = ARRAY_SIZE(simpad_button_table),
0268 };
0269 
0270 static struct platform_device simpad_keys = {
0271     .name = "gpio-keys",
0272     .dev = {
0273         .platform_data = &simpad_keys_data,
0274     },
0275 };
0276 
0277 static struct gpio_keys_button simpad_polled_button_table[] = {
0278     { KEY_PROG1, SIMPAD_UCB1X00_GPIO_PROG1, 1, "prog1 button" },
0279     { KEY_PROG2, SIMPAD_UCB1X00_GPIO_PROG2, 1, "prog2 button" },
0280     { KEY_UP,    SIMPAD_UCB1X00_GPIO_UP,    1, "up button" },
0281     { KEY_DOWN,  SIMPAD_UCB1X00_GPIO_DOWN,  1, "down button" },
0282     { KEY_LEFT,  SIMPAD_UCB1X00_GPIO_LEFT,  1, "left button" },
0283     { KEY_RIGHT, SIMPAD_UCB1X00_GPIO_RIGHT, 1, "right button" },
0284 };
0285 
0286 static struct gpio_keys_platform_data simpad_polled_keys_data = {
0287     .buttons = simpad_polled_button_table,
0288     .nbuttons = ARRAY_SIZE(simpad_polled_button_table),
0289     .poll_interval = 50,
0290 };
0291 
0292 static struct platform_device simpad_polled_keys = {
0293     .name = "gpio-keys-polled",
0294     .dev = {
0295         .platform_data = &simpad_polled_keys_data,
0296     },
0297 };
0298 
0299 /*
0300  * GPIO LEDs
0301  */
0302 
0303 static struct gpio_led simpad_leds[] = {
0304     {
0305         .name = "simpad:power",
0306         .gpio = SIMPAD_CS3_LED2_ON,
0307         .active_low = 0,
0308         .default_trigger = "default-on",
0309     },
0310 };
0311 
0312 static struct gpio_led_platform_data simpad_led_data = {
0313     .num_leds = ARRAY_SIZE(simpad_leds),
0314     .leds = simpad_leds,
0315 };
0316 
0317 static struct platform_device simpad_gpio_leds = {
0318     .name = "leds-gpio",
0319     .id = 0,
0320     .dev = {
0321         .platform_data = &simpad_led_data,
0322     },
0323 };
0324 
0325 /*
0326  * i2c
0327  */
0328 static struct gpiod_lookup_table simpad_i2c_gpiod_table = {
0329     .dev_id = "i2c-gpio.0",
0330     .table = {
0331         GPIO_LOOKUP_IDX("gpio", 21, NULL, 0,
0332                 GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
0333         GPIO_LOOKUP_IDX("gpio", 25, NULL, 1,
0334                 GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
0335     },
0336 };
0337 
0338 static struct i2c_gpio_platform_data simpad_i2c_data = {
0339     .udelay = 10,
0340     .timeout = HZ,
0341 };
0342 
0343 static struct platform_device simpad_i2c = {
0344     .name = "i2c-gpio",
0345     .id = 0,
0346     .dev = {
0347         .platform_data = &simpad_i2c_data,
0348     },
0349 };
0350 
0351 /*
0352  * MediaQ Video Device
0353  */
0354 static struct platform_device simpad_mq200fb = {
0355     .name = "simpad-mq200",
0356     .id   = 0,
0357 };
0358 
0359 static struct platform_device *devices[] __initdata = {
0360     &simpad_keys,
0361     &simpad_polled_keys,
0362     &simpad_mq200fb,
0363     &simpad_gpio_leds,
0364     &simpad_i2c,
0365 };
0366 
0367 /* Compact Flash */
0368 static struct gpiod_lookup_table simpad_cf_gpio_table = {
0369     .dev_id = "sa11x0-pcmcia",
0370     .table = {
0371         GPIO_LOOKUP("gpio", GPIO_CF_IRQ, "cf-ready", GPIO_ACTIVE_HIGH),
0372         GPIO_LOOKUP("gpio", GPIO_CF_CD, "cf-detect", GPIO_ACTIVE_HIGH),
0373         { },
0374     },
0375 };
0376 
0377 
0378 static int __init simpad_init(void)
0379 {
0380     int ret;
0381 
0382     spin_lock_init(&cs3_lock);
0383 
0384     cs3_gpio.label = "simpad_cs3";
0385     cs3_gpio.base = SIMPAD_CS3_GPIO_BASE;
0386     cs3_gpio.ngpio = 24;
0387     cs3_gpio.set = cs3_gpio_set;
0388     cs3_gpio.get = cs3_gpio_get;
0389     cs3_gpio.direction_input = cs3_gpio_direction_input;
0390     cs3_gpio.direction_output = cs3_gpio_direction_output;
0391     ret = gpiochip_add_data(&cs3_gpio, NULL);
0392     if (ret)
0393         printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device");
0394 
0395     pm_power_off = simpad_power_off;
0396 
0397     sa11x0_register_pcmcia(-1, &simpad_cf_gpio_table);
0398     sa11x0_ppc_configure_mcp();
0399     sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
0400                   ARRAY_SIZE(simpad_flash_resources));
0401     sa11x0_register_mcp(&simpad_mcp_data);
0402 
0403     gpiod_add_lookup_table(&simpad_i2c_gpiod_table);
0404     ret = platform_add_devices(devices, ARRAY_SIZE(devices));
0405     if(ret)
0406         printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
0407 
0408     return 0;
0409 }
0410 
0411 arch_initcall(simpad_init);
0412 
0413 
0414 MACHINE_START(SIMPAD, "Simpad")
0415     /* Maintainer: Holger Freyther */
0416     .atag_offset    = 0x100,
0417     .map_io     = simpad_map_io,
0418     .nr_irqs    = SA1100_NR_IRQS,
0419     .init_irq   = sa1100_init_irq,
0420     .init_late  = sa11x0_init_late,
0421     .init_time  = sa1100_timer_init,
0422     .restart    = sa11x0_restart,
0423 MACHINE_END