2 * linux/arch/arm/mach-sa1100/simpad.c
5 #include <linux/module.h>
6 #include <linux/init.h>
7 #include <linux/kernel.h>
9 #include <linux/proc_fs.h>
10 #include <linux/string.h>
12 #include <linux/platform_device.h>
13 #include <linux/mtd/mtd.h>
14 #include <linux/mtd/partitions.h>
16 #include <linux/gpio.h>
19 #include <mach/hardware.h>
20 #include <asm/setup.h>
22 #include <asm/mach-types.h>
23 #include <asm/mach/arch.h>
24 #include <asm/mach/flash.h>
25 #include <asm/mach/map.h>
26 #include <asm/mach/serial_sa1100.h>
28 #include <mach/simpad.h>
30 #include <linux/serial_core.h>
31 #include <linux/ioport.h>
32 #include <linux/input.h>
33 #include <linux/gpio_keys.h>
34 #include <linux/leds.h>
35 #include <linux/i2c-gpio.h>
43 static long cs3_shadow
;
44 static spinlock_t cs3_lock
;
45 static struct gpio_chip cs3_gpio
;
47 long simpad_get_cs3_ro(void)
49 return readl(CS3_BASE
);
51 EXPORT_SYMBOL(simpad_get_cs3_ro
);
53 long simpad_get_cs3_shadow(void)
57 EXPORT_SYMBOL(simpad_get_cs3_shadow
);
59 static void __simpad_write_cs3(void)
61 writel(cs3_shadow
, CS3_BASE
);
64 void simpad_set_cs3_bit(int value
)
68 spin_lock_irqsave(&cs3_lock
, flags
);
71 spin_unlock_irqrestore(&cs3_lock
, flags
);
73 EXPORT_SYMBOL(simpad_set_cs3_bit
);
75 void simpad_clear_cs3_bit(int value
)
79 spin_lock_irqsave(&cs3_lock
, flags
);
82 spin_unlock_irqrestore(&cs3_lock
, flags
);
84 EXPORT_SYMBOL(simpad_clear_cs3_bit
);
86 static void cs3_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
91 simpad_set_cs3_bit(1 << offset
);
93 simpad_clear_cs3_bit(1 << offset
);
96 static int cs3_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
99 return simpad_get_cs3_ro() & (1 << (offset
- 16));
100 return simpad_get_cs3_shadow() & (1 << offset
);
103 static int cs3_gpio_direction_input(struct gpio_chip
*chip
, unsigned offset
)
110 static int cs3_gpio_direction_output(struct gpio_chip
*chip
, unsigned offset
,
115 cs3_gpio_set(chip
, offset
, value
);
119 static struct map_desc simpad_io_desc
[] __initdata
= {
121 .virtual = 0xf2800000,
122 .pfn
= __phys_to_pfn(0x4b800000),
123 .length
= 0x00800000,
125 }, { /* Simpad CS3 */
127 .pfn
= __phys_to_pfn(SA1100_CS3_PHYS
),
128 .length
= 0x00100000,
134 static void simpad_uart_pm(struct uart_port
*port
, u_int state
, u_int oldstate
)
136 if (port
->mapbase
== (u_int
)&Ser1UTCR0
) {
139 simpad_clear_cs3_bit(RS232_ON
);
140 simpad_clear_cs3_bit(DECT_POWER_ON
);
143 simpad_set_cs3_bit(RS232_ON
);
144 simpad_set_cs3_bit(DECT_POWER_ON
);
149 static struct sa1100_port_fns simpad_port_fns __initdata
= {
150 .pm
= simpad_uart_pm
,
154 static struct mtd_partition simpad_partitions
[] = {
156 .name
= "SIMpad boot firmware",
159 .mask_flags
= MTD_WRITEABLE
,
161 .name
= "SIMpad kernel",
163 .offset
= MTDPART_OFS_APPEND
,
165 .name
= "SIMpad root jffs2",
166 .size
= MTDPART_SIZ_FULL
,
167 .offset
= MTDPART_OFS_APPEND
,
171 static struct flash_platform_data simpad_flash_data
= {
172 .map_name
= "cfi_probe",
173 .parts
= simpad_partitions
,
174 .nr_parts
= ARRAY_SIZE(simpad_partitions
),
178 static struct resource simpad_flash_resources
[] = {
180 .start
= SA1100_CS0_PHYS
,
181 .end
= SA1100_CS0_PHYS
+ SZ_16M
-1,
182 .flags
= IORESOURCE_MEM
,
184 .start
= SA1100_CS1_PHYS
,
185 .end
= SA1100_CS1_PHYS
+ SZ_16M
-1,
186 .flags
= IORESOURCE_MEM
,
190 static struct mcp_plat_data simpad_mcp_data
= {
192 .sclk_rate
= 11981000,
193 .gpio_base
= SIMPAD_UCB1X00_GPIO_BASE
,
198 static void __init
simpad_map_io(void)
202 iotable_init(simpad_io_desc
, ARRAY_SIZE(simpad_io_desc
));
205 cs3_shadow
= (EN1
| EN0
| LED2_ON
| DISPLAY_ON
|
206 RS232_ON
| ENABLE_5V
| RESET_SIMCARD
| DECT_POWER_ON
);
207 __simpad_write_cs3(); /* Spinlocks not yet initialized */
209 sa1100_register_uart_fns(&simpad_port_fns
);
210 sa1100_register_uart(0, 3); /* serial interface */
211 sa1100_register_uart(1, 1); /* DECT */
213 // Reassign UART 1 pins
214 GAFR
|= GPIO_UART_TXD
| GPIO_UART_RXD
;
215 GPDR
|= GPIO_UART_TXD
| GPIO_LDD13
| GPIO_LDD15
;
216 GPDR
&= ~GPIO_UART_RXD
;
220 * Set up registers for sleep mode.
224 PWER
= PWER_GPIO0
| PWER_RTC
;
231 static void simpad_power_off(void)
234 cs3_shadow
= SD_MEDIAQ
;
235 __simpad_write_cs3(); /* Bypass spinlock here */
237 /* disable internal oscillator, float CS lines */
238 PCFR
= (PCFR_OPDE
| PCFR_FP
| PCFR_FS
);
239 /* enable wake-up on GPIO0 */
240 PWER
= GFER
= GRER
= PWER_GPIO0
;
242 * set scratchpad to zero, just in case it is used as a
243 * restart address by the bootloader.
247 /* enter sleep mode */
251 local_irq_enable(); /* we won't ever call it */
260 static struct gpio_keys_button simpad_button_table
[] = {
261 { KEY_POWER
, IRQ_GPIO_POWER_BUTTON
, 1, "power button" },
264 static struct gpio_keys_platform_data simpad_keys_data
= {
265 .buttons
= simpad_button_table
,
266 .nbuttons
= ARRAY_SIZE(simpad_button_table
),
269 static struct platform_device simpad_keys
= {
272 .platform_data
= &simpad_keys_data
,
276 static struct gpio_keys_button simpad_polled_button_table
[] = {
277 { KEY_PROG1
, SIMPAD_UCB1X00_GPIO_PROG1
, 1, "prog1 button" },
278 { KEY_PROG2
, SIMPAD_UCB1X00_GPIO_PROG2
, 1, "prog2 button" },
279 { KEY_UP
, SIMPAD_UCB1X00_GPIO_UP
, 1, "up button" },
280 { KEY_DOWN
, SIMPAD_UCB1X00_GPIO_DOWN
, 1, "down button" },
281 { KEY_LEFT
, SIMPAD_UCB1X00_GPIO_LEFT
, 1, "left button" },
282 { KEY_RIGHT
, SIMPAD_UCB1X00_GPIO_RIGHT
, 1, "right button" },
285 static struct gpio_keys_platform_data simpad_polled_keys_data
= {
286 .buttons
= simpad_polled_button_table
,
287 .nbuttons
= ARRAY_SIZE(simpad_polled_button_table
),
291 static struct platform_device simpad_polled_keys
= {
292 .name
= "gpio-keys-polled",
294 .platform_data
= &simpad_polled_keys_data
,
302 static struct gpio_led simpad_leds
[] = {
304 .name
= "simpad:power",
305 .gpio
= SIMPAD_CS3_LED2_ON
,
307 .default_trigger
= "default-on",
311 static struct gpio_led_platform_data simpad_led_data
= {
312 .num_leds
= ARRAY_SIZE(simpad_leds
),
316 static struct platform_device simpad_gpio_leds
= {
320 .platform_data
= &simpad_led_data
,
327 static struct i2c_gpio_platform_data simpad_i2c_data
= {
328 .sda_pin
= GPIO_GPIO21
,
329 .scl_pin
= GPIO_GPIO25
,
334 static struct platform_device simpad_i2c
= {
338 .platform_data
= &simpad_i2c_data
,
343 * MediaQ Video Device
345 static struct platform_device simpad_mq200fb
= {
346 .name
= "simpad-mq200",
350 static struct platform_device
*devices
[] __initdata
= {
360 static int __init
simpad_init(void)
364 spin_lock_init(&cs3_lock
);
366 cs3_gpio
.label
= "simpad_cs3";
367 cs3_gpio
.base
= SIMPAD_CS3_GPIO_BASE
;
369 cs3_gpio
.set
= cs3_gpio_set
;
370 cs3_gpio
.get
= cs3_gpio_get
;
371 cs3_gpio
.direction_input
= cs3_gpio_direction_input
;
372 cs3_gpio
.direction_output
= cs3_gpio_direction_output
;
373 ret
= gpiochip_add(&cs3_gpio
);
375 printk(KERN_WARNING
"simpad: Unable to register cs3 GPIO device");
377 pm_power_off
= simpad_power_off
;
379 sa11x0_register_mtd(&simpad_flash_data
, simpad_flash_resources
,
380 ARRAY_SIZE(simpad_flash_resources
));
381 sa11x0_register_mcp(&simpad_mcp_data
);
383 ret
= platform_add_devices(devices
, ARRAY_SIZE(devices
));
385 printk(KERN_WARNING
"simpad: Unable to register mq200 framebuffer device");
390 arch_initcall(simpad_init
);
393 MACHINE_START(SIMPAD
, "Simpad")
394 /* Maintainer: Holger Freyther */
395 .atag_offset
= 0x100,
396 .map_io
= simpad_map_io
,
397 .init_irq
= sa1100_init_irq
,
398 .timer
= &sa1100_timer
,
399 .restart
= sa11x0_restart
,