root/arch/arm/mach-sa1100/simpad.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. simpad_get_cs3_ro
  2. simpad_get_cs3_shadow
  3. __simpad_write_cs3
  4. simpad_set_cs3_bit
  5. simpad_clear_cs3_bit
  6. cs3_gpio_set
  7. cs3_gpio_get
  8. cs3_gpio_direction_input
  9. cs3_gpio_direction_output
  10. simpad_uart_pm
  11. simpad_map_io
  12. simpad_power_off
  13. simpad_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * linux/arch/arm/mach-sa1100/simpad.c
   4  */
   5 
   6 #include <linux/module.h>
   7 #include <linux/gpio/machine.h>
   8 #include <linux/init.h>
   9 #include <linux/kernel.h>
  10 #include <linux/tty.h>
  11 #include <linux/proc_fs.h>
  12 #include <linux/string.h>
  13 #include <linux/pm.h>
  14 #include <linux/platform_data/sa11x0-serial.h>
  15 #include <linux/platform_device.h>
  16 #include <linux/mfd/ucb1x00.h>
  17 #include <linux/mtd/mtd.h>
  18 #include <linux/mtd/partitions.h>
  19 #include <linux/io.h>
  20 #include <linux/gpio/driver.h>
  21 
  22 #include <mach/hardware.h>
  23 #include <asm/setup.h>
  24 #include <asm/irq.h>
  25 
  26 #include <asm/mach-types.h>
  27 #include <asm/mach/arch.h>
  28 #include <asm/mach/flash.h>
  29 #include <asm/mach/map.h>
  30 #include <linux/platform_data/mfd-mcp-sa11x0.h>
  31 #include <mach/simpad.h>
  32 #include <mach/irqs.h>
  33 
  34 #include <linux/serial_core.h>
  35 #include <linux/ioport.h>
  36 #include <linux/input.h>
  37 #include <linux/gpio_keys.h>
  38 #include <linux/leds.h>
  39 #include <linux/platform_data/i2c-gpio.h>
  40 
  41 #include "generic.h"
  42 
  43 /*
  44  * CS3 support
  45  */
  46 
  47 static long cs3_shadow;
  48 static spinlock_t cs3_lock;
  49 static struct gpio_chip cs3_gpio;
  50 
  51 long simpad_get_cs3_ro(void)
  52 {
  53         return readl(CS3_BASE);
  54 }
  55 EXPORT_SYMBOL(simpad_get_cs3_ro);
  56 
  57 long simpad_get_cs3_shadow(void)
  58 {
  59         return cs3_shadow;
  60 }
  61 EXPORT_SYMBOL(simpad_get_cs3_shadow);
  62 
  63 static void __simpad_write_cs3(void)
  64 {
  65         writel(cs3_shadow, CS3_BASE);
  66 }
  67 
  68 void simpad_set_cs3_bit(int value)
  69 {
  70         unsigned long flags;
  71 
  72         spin_lock_irqsave(&cs3_lock, flags);
  73         cs3_shadow |= value;
  74         __simpad_write_cs3();
  75         spin_unlock_irqrestore(&cs3_lock, flags);
  76 }
  77 EXPORT_SYMBOL(simpad_set_cs3_bit);
  78 
  79 void simpad_clear_cs3_bit(int value)
  80 {
  81         unsigned long flags;
  82 
  83         spin_lock_irqsave(&cs3_lock, flags);
  84         cs3_shadow &= ~value;
  85         __simpad_write_cs3();
  86         spin_unlock_irqrestore(&cs3_lock, flags);
  87 }
  88 EXPORT_SYMBOL(simpad_clear_cs3_bit);
  89 
  90 static void cs3_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  91 {
  92         if (offset > 15)
  93                 return;
  94         if (value)
  95                 simpad_set_cs3_bit(1 << offset);
  96         else
  97                 simpad_clear_cs3_bit(1 << offset);
  98 };
  99 
 100 static int cs3_gpio_get(struct gpio_chip *chip, unsigned offset)
 101 {
 102         if (offset > 15)
 103                 return !!(simpad_get_cs3_ro() & (1 << (offset - 16)));
 104         return !!(simpad_get_cs3_shadow() & (1 << offset));
 105 };
 106 
 107 static int cs3_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 108 {
 109         if (offset > 15)
 110                 return 0;
 111         return -EINVAL;
 112 };
 113 
 114 static int cs3_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 115         int value)
 116 {
 117         if (offset > 15)
 118                 return -EINVAL;
 119         cs3_gpio_set(chip, offset, value);
 120         return 0;
 121 };
 122 
 123 static struct map_desc simpad_io_desc[] __initdata = {
 124         {       /* MQ200 */
 125                 .virtual        =  0xf2800000,
 126                 .pfn            = __phys_to_pfn(0x4b800000),
 127                 .length         = 0x00800000,
 128                 .type           = MT_DEVICE
 129         }, {    /* Simpad CS3 */
 130                 .virtual        = (unsigned long)CS3_BASE,
 131                 .pfn            = __phys_to_pfn(SA1100_CS3_PHYS),
 132                 .length         = 0x00100000,
 133                 .type           = MT_DEVICE
 134         },
 135 };
 136 
 137 
 138 static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 139 {
 140         if (port->mapbase == (u_int)&Ser1UTCR0) {
 141                 if (state)
 142                 {
 143                         simpad_clear_cs3_bit(RS232_ON);
 144                         simpad_clear_cs3_bit(DECT_POWER_ON);
 145                 }else
 146                 {
 147                         simpad_set_cs3_bit(RS232_ON);
 148                         simpad_set_cs3_bit(DECT_POWER_ON);
 149                 }
 150         }
 151 }
 152 
 153 static struct sa1100_port_fns simpad_port_fns __initdata = {
 154         .pm        = simpad_uart_pm,
 155 };
 156 
 157 
 158 static struct mtd_partition simpad_partitions[] = {
 159         {
 160                 .name       = "SIMpad boot firmware",
 161                 .size       = 0x00080000,
 162                 .offset     = 0,
 163                 .mask_flags = MTD_WRITEABLE,
 164         }, {
 165                 .name       = "SIMpad kernel",
 166                 .size       = 0x0010000,
 167                 .offset     = MTDPART_OFS_APPEND,
 168         }, {
 169                 .name       = "SIMpad root jffs2",
 170                 .size       = MTDPART_SIZ_FULL,
 171                 .offset     = MTDPART_OFS_APPEND,
 172         }
 173 };
 174 
 175 static struct flash_platform_data simpad_flash_data = {
 176         .map_name    = "cfi_probe",
 177         .parts       = simpad_partitions,
 178         .nr_parts    = ARRAY_SIZE(simpad_partitions),
 179 };
 180 
 181 
 182 static struct resource simpad_flash_resources [] = {
 183         DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M),
 184         DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M),
 185 };
 186 
 187 static struct ucb1x00_plat_data simpad_ucb1x00_data = {
 188         .gpio_base      = SIMPAD_UCB1X00_GPIO_BASE,
 189 };
 190 
 191 static struct mcp_plat_data simpad_mcp_data = {
 192         .mccr0          = MCCR0_ADM,
 193         .sclk_rate      = 11981000,
 194         .codec_pdata    = &simpad_ucb1x00_data,
 195 };
 196 
 197 
 198 
 199 static void __init simpad_map_io(void)
 200 {
 201         sa1100_map_io();
 202 
 203         iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
 204 
 205         /* Initialize CS3 */
 206         cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON |
 207                 RS232_ON | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
 208         __simpad_write_cs3(); /* Spinlocks not yet initialized */
 209 
 210         sa1100_register_uart_fns(&simpad_port_fns);
 211         sa1100_register_uart(0, 3);  /* serial interface */
 212         sa1100_register_uart(1, 1);  /* DECT             */
 213 
 214         // Reassign UART 1 pins
 215         GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
 216         GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
 217         GPDR &= ~GPIO_UART_RXD;
 218         PPAR |= PPAR_UPR;
 219 
 220         /*
 221          * Set up registers for sleep mode.
 222          */
 223 
 224 
 225         PWER = PWER_GPIO0| PWER_RTC;
 226         PGSR = 0x818;
 227         PCFR = 0;
 228         PSDR = 0;
 229 
 230 }
 231 
 232 static void simpad_power_off(void)
 233 {
 234         local_irq_disable();
 235         cs3_shadow = SD_MEDIAQ;
 236         __simpad_write_cs3(); /* Bypass spinlock here */
 237 
 238         /* disable internal oscillator, float CS lines */
 239         PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
 240         /* enable wake-up on GPIO0 */
 241         PWER = GFER = GRER = PWER_GPIO0;
 242         /*
 243          * set scratchpad to zero, just in case it is used as a
 244          * restart address by the bootloader.
 245          */
 246         PSPR = 0;
 247         PGSR = 0;
 248         /* enter sleep mode */
 249         PMCR = PMCR_SF;
 250         while(1);
 251 
 252         local_irq_enable(); /* we won't ever call it */
 253 
 254 
 255 }
 256 
 257 /*
 258  * gpio_keys
 259 */
 260 
 261 static struct gpio_keys_button simpad_button_table[] = {
 262         { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" },
 263 };
 264 
 265 static struct gpio_keys_platform_data simpad_keys_data = {
 266         .buttons = simpad_button_table,
 267         .nbuttons = ARRAY_SIZE(simpad_button_table),
 268 };
 269 
 270 static struct platform_device simpad_keys = {
 271         .name = "gpio-keys",
 272         .dev = {
 273                 .platform_data = &simpad_keys_data,
 274         },
 275 };
 276 
 277 static struct gpio_keys_button simpad_polled_button_table[] = {
 278         { KEY_PROG1, SIMPAD_UCB1X00_GPIO_PROG1, 1, "prog1 button" },
 279         { KEY_PROG2, SIMPAD_UCB1X00_GPIO_PROG2, 1, "prog2 button" },
 280         { KEY_UP,    SIMPAD_UCB1X00_GPIO_UP,    1, "up button" },
 281         { KEY_DOWN,  SIMPAD_UCB1X00_GPIO_DOWN,  1, "down button" },
 282         { KEY_LEFT,  SIMPAD_UCB1X00_GPIO_LEFT,  1, "left button" },
 283         { KEY_RIGHT, SIMPAD_UCB1X00_GPIO_RIGHT, 1, "right button" },
 284 };
 285 
 286 static struct gpio_keys_platform_data simpad_polled_keys_data = {
 287         .buttons = simpad_polled_button_table,
 288         .nbuttons = ARRAY_SIZE(simpad_polled_button_table),
 289         .poll_interval = 50,
 290 };
 291 
 292 static struct platform_device simpad_polled_keys = {
 293         .name = "gpio-keys-polled",
 294         .dev = {
 295                 .platform_data = &simpad_polled_keys_data,
 296         },
 297 };
 298 
 299 /*
 300  * GPIO LEDs
 301  */
 302 
 303 static struct gpio_led simpad_leds[] = {
 304         {
 305                 .name = "simpad:power",
 306                 .gpio = SIMPAD_CS3_LED2_ON,
 307                 .active_low = 0,
 308                 .default_trigger = "default-on",
 309         },
 310 };
 311 
 312 static struct gpio_led_platform_data simpad_led_data = {
 313         .num_leds = ARRAY_SIZE(simpad_leds),
 314         .leds = simpad_leds,
 315 };
 316 
 317 static struct platform_device simpad_gpio_leds = {
 318         .name = "leds-gpio",
 319         .id = 0,
 320         .dev = {
 321                 .platform_data = &simpad_led_data,
 322         },
 323 };
 324 
 325 /*
 326  * i2c
 327  */
 328 static struct gpiod_lookup_table simpad_i2c_gpiod_table = {
 329         .dev_id = "i2c-gpio.0",
 330         .table = {
 331                 GPIO_LOOKUP_IDX("gpio", 21, NULL, 0,
 332                                 GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
 333                 GPIO_LOOKUP_IDX("gpio", 25, NULL, 1,
 334                                 GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
 335         },
 336 };
 337 
 338 static struct i2c_gpio_platform_data simpad_i2c_data = {
 339         .udelay = 10,
 340         .timeout = HZ,
 341 };
 342 
 343 static struct platform_device simpad_i2c = {
 344         .name = "i2c-gpio",
 345         .id = 0,
 346         .dev = {
 347                 .platform_data = &simpad_i2c_data,
 348         },
 349 };
 350 
 351 /*
 352  * MediaQ Video Device
 353  */
 354 static struct platform_device simpad_mq200fb = {
 355         .name = "simpad-mq200",
 356         .id   = 0,
 357 };
 358 
 359 static struct platform_device *devices[] __initdata = {
 360         &simpad_keys,
 361         &simpad_polled_keys,
 362         &simpad_mq200fb,
 363         &simpad_gpio_leds,
 364         &simpad_i2c,
 365 };
 366 
 367 /* Compact Flash */
 368 static struct gpiod_lookup_table simpad_cf_gpio_table = {
 369         .dev_id = "sa11x0-pcmcia",
 370         .table = {
 371                 GPIO_LOOKUP("gpio", GPIO_CF_IRQ, "cf-ready", GPIO_ACTIVE_HIGH),
 372                 GPIO_LOOKUP("gpio", GPIO_CF_CD, "cf-detect", GPIO_ACTIVE_HIGH),
 373                 { },
 374         },
 375 };
 376 
 377 
 378 static int __init simpad_init(void)
 379 {
 380         int ret;
 381 
 382         spin_lock_init(&cs3_lock);
 383 
 384         cs3_gpio.label = "simpad_cs3";
 385         cs3_gpio.base = SIMPAD_CS3_GPIO_BASE;
 386         cs3_gpio.ngpio = 24;
 387         cs3_gpio.set = cs3_gpio_set;
 388         cs3_gpio.get = cs3_gpio_get;
 389         cs3_gpio.direction_input = cs3_gpio_direction_input;
 390         cs3_gpio.direction_output = cs3_gpio_direction_output;
 391         ret = gpiochip_add_data(&cs3_gpio, NULL);
 392         if (ret)
 393                 printk(KERN_WARNING "simpad: Unable to register cs3 GPIO device");
 394 
 395         pm_power_off = simpad_power_off;
 396 
 397         sa11x0_register_pcmcia(-1, &simpad_cf_gpio_table);
 398         sa11x0_ppc_configure_mcp();
 399         sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
 400                               ARRAY_SIZE(simpad_flash_resources));
 401         sa11x0_register_mcp(&simpad_mcp_data);
 402 
 403         gpiod_add_lookup_table(&simpad_i2c_gpiod_table);
 404         ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 405         if(ret)
 406                 printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
 407 
 408         return 0;
 409 }
 410 
 411 arch_initcall(simpad_init);
 412 
 413 
 414 MACHINE_START(SIMPAD, "Simpad")
 415         /* Maintainer: Holger Freyther */
 416         .atag_offset    = 0x100,
 417         .map_io         = simpad_map_io,
 418         .nr_irqs        = SA1100_NR_IRQS,
 419         .init_irq       = sa1100_init_irq,
 420         .init_late      = sa11x0_init_late,
 421         .init_time      = sa1100_timer_init,
 422         .restart        = sa11x0_restart,
 423 MACHINE_END

/* [<][>][^][v][top][bottom][index][help] */