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_data/sa11x0-serial.h>
13 #include <linux/platform_device.h>
14 #include <linux/mfd/ucb1x00.h>
15 #include <linux/mtd/mtd.h>
16 #include <linux/mtd/partitions.h>
18 #include <linux/gpio.h>
20 #include <mach/hardware.h>
21 #include <asm/setup.h>
23 #include <asm/mach-types.h>
24 #include <asm/mach/arch.h>
25 #include <asm/mach/flash.h>
26 #include <asm/mach/map.h>
27 #include <linux/platform_data/mfd-mcp-sa11x0.h>
28 #include <mach/simpad.h>
29 #include <mach/irqs.h>
31 #include <linux/serial_core.h>
32 #include <linux/ioport.h>
33 #include <linux/input.h>
34 #include <linux/gpio_keys.h>
35 #include <linux/leds.h>
36 #include <linux/i2c-gpio.h>
44 static long cs3_shadow
;
45 static spinlock_t cs3_lock
;
46 static struct gpio_chip cs3_gpio
;
48 long simpad_get_cs3_ro(void)
50 return readl(CS3_BASE
);
52 EXPORT_SYMBOL(simpad_get_cs3_ro
);
54 long simpad_get_cs3_shadow(void)
58 EXPORT_SYMBOL(simpad_get_cs3_shadow
);
60 static void __simpad_write_cs3(void)
62 writel(cs3_shadow
, CS3_BASE
);
65 void simpad_set_cs3_bit(int value
)
69 spin_lock_irqsave(&cs3_lock
, flags
);
72 spin_unlock_irqrestore(&cs3_lock
, flags
);
74 EXPORT_SYMBOL(simpad_set_cs3_bit
);
76 void simpad_clear_cs3_bit(int value
)
80 spin_lock_irqsave(&cs3_lock
, flags
);
83 spin_unlock_irqrestore(&cs3_lock
, flags
);
85 EXPORT_SYMBOL(simpad_clear_cs3_bit
);
87 static void cs3_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
92 simpad_set_cs3_bit(1 << offset
);
94 simpad_clear_cs3_bit(1 << offset
);
97 static int cs3_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
100 return simpad_get_cs3_ro() & (1 << (offset
- 16));
101 return simpad_get_cs3_shadow() & (1 << offset
);
104 static int cs3_gpio_direction_input(struct gpio_chip
*chip
, unsigned offset
)
111 static int cs3_gpio_direction_output(struct gpio_chip
*chip
, unsigned offset
,
116 cs3_gpio_set(chip
, offset
, value
);
120 static struct map_desc simpad_io_desc
[] __initdata
= {
122 .virtual = 0xf2800000,
123 .pfn
= __phys_to_pfn(0x4b800000),
124 .length
= 0x00800000,
126 }, { /* Simpad CS3 */
127 .virtual = (unsigned long)CS3_BASE
,
128 .pfn
= __phys_to_pfn(SA1100_CS3_PHYS
),
129 .length
= 0x00100000,
135 static void simpad_uart_pm(struct uart_port
*port
, u_int state
, u_int oldstate
)
137 if (port
->mapbase
== (u_int
)&Ser1UTCR0
) {
140 simpad_clear_cs3_bit(RS232_ON
);
141 simpad_clear_cs3_bit(DECT_POWER_ON
);
144 simpad_set_cs3_bit(RS232_ON
);
145 simpad_set_cs3_bit(DECT_POWER_ON
);
150 static struct sa1100_port_fns simpad_port_fns __initdata
= {
151 .pm
= simpad_uart_pm
,
155 static struct mtd_partition simpad_partitions
[] = {
157 .name
= "SIMpad boot firmware",
160 .mask_flags
= MTD_WRITEABLE
,
162 .name
= "SIMpad kernel",
164 .offset
= MTDPART_OFS_APPEND
,
166 .name
= "SIMpad root jffs2",
167 .size
= MTDPART_SIZ_FULL
,
168 .offset
= MTDPART_OFS_APPEND
,
172 static struct flash_platform_data simpad_flash_data
= {
173 .map_name
= "cfi_probe",
174 .parts
= simpad_partitions
,
175 .nr_parts
= ARRAY_SIZE(simpad_partitions
),
179 static struct resource simpad_flash_resources
[] = {
180 DEFINE_RES_MEM(SA1100_CS0_PHYS
, SZ_16M
),
181 DEFINE_RES_MEM(SA1100_CS1_PHYS
, SZ_16M
),
184 static struct ucb1x00_plat_data simpad_ucb1x00_data
= {
185 .gpio_base
= SIMPAD_UCB1X00_GPIO_BASE
,
188 static struct mcp_plat_data simpad_mcp_data
= {
190 .sclk_rate
= 11981000,
191 .codec_pdata
= &simpad_ucb1x00_data
,
196 static void __init
simpad_map_io(void)
200 iotable_init(simpad_io_desc
, ARRAY_SIZE(simpad_io_desc
));
203 cs3_shadow
= (EN1
| EN0
| LED2_ON
| DISPLAY_ON
|
204 RS232_ON
| ENABLE_5V
| RESET_SIMCARD
| DECT_POWER_ON
);
205 __simpad_write_cs3(); /* Spinlocks not yet initialized */
207 sa1100_register_uart_fns(&simpad_port_fns
);
208 sa1100_register_uart(0, 3); /* serial interface */
209 sa1100_register_uart(1, 1); /* DECT */
211 // Reassign UART 1 pins
212 GAFR
|= GPIO_UART_TXD
| GPIO_UART_RXD
;
213 GPDR
|= GPIO_UART_TXD
| GPIO_LDD13
| GPIO_LDD15
;
214 GPDR
&= ~GPIO_UART_RXD
;
218 * Set up registers for sleep mode.
222 PWER
= PWER_GPIO0
| PWER_RTC
;
229 static void simpad_power_off(void)
232 cs3_shadow
= SD_MEDIAQ
;
233 __simpad_write_cs3(); /* Bypass spinlock here */
235 /* disable internal oscillator, float CS lines */
236 PCFR
= (PCFR_OPDE
| PCFR_FP
| PCFR_FS
);
237 /* enable wake-up on GPIO0 */
238 PWER
= GFER
= GRER
= PWER_GPIO0
;
240 * set scratchpad to zero, just in case it is used as a
241 * restart address by the bootloader.
245 /* enter sleep mode */
249 local_irq_enable(); /* we won't ever call it */
258 static struct gpio_keys_button simpad_button_table
[] = {
259 { KEY_POWER
, IRQ_GPIO_POWER_BUTTON
, 1, "power button" },
262 static struct gpio_keys_platform_data simpad_keys_data
= {
263 .buttons
= simpad_button_table
,
264 .nbuttons
= ARRAY_SIZE(simpad_button_table
),
267 static struct platform_device simpad_keys
= {
270 .platform_data
= &simpad_keys_data
,
274 static struct gpio_keys_button simpad_polled_button_table
[] = {
275 { KEY_PROG1
, SIMPAD_UCB1X00_GPIO_PROG1
, 1, "prog1 button" },
276 { KEY_PROG2
, SIMPAD_UCB1X00_GPIO_PROG2
, 1, "prog2 button" },
277 { KEY_UP
, SIMPAD_UCB1X00_GPIO_UP
, 1, "up button" },
278 { KEY_DOWN
, SIMPAD_UCB1X00_GPIO_DOWN
, 1, "down button" },
279 { KEY_LEFT
, SIMPAD_UCB1X00_GPIO_LEFT
, 1, "left button" },
280 { KEY_RIGHT
, SIMPAD_UCB1X00_GPIO_RIGHT
, 1, "right button" },
283 static struct gpio_keys_platform_data simpad_polled_keys_data
= {
284 .buttons
= simpad_polled_button_table
,
285 .nbuttons
= ARRAY_SIZE(simpad_polled_button_table
),
289 static struct platform_device simpad_polled_keys
= {
290 .name
= "gpio-keys-polled",
292 .platform_data
= &simpad_polled_keys_data
,
300 static struct gpio_led simpad_leds
[] = {
302 .name
= "simpad:power",
303 .gpio
= SIMPAD_CS3_LED2_ON
,
305 .default_trigger
= "default-on",
309 static struct gpio_led_platform_data simpad_led_data
= {
310 .num_leds
= ARRAY_SIZE(simpad_leds
),
314 static struct platform_device simpad_gpio_leds
= {
318 .platform_data
= &simpad_led_data
,
325 static struct i2c_gpio_platform_data simpad_i2c_data
= {
326 .sda_pin
= GPIO_GPIO21
,
327 .scl_pin
= GPIO_GPIO25
,
332 static struct platform_device simpad_i2c
= {
336 .platform_data
= &simpad_i2c_data
,
341 * MediaQ Video Device
343 static struct platform_device simpad_mq200fb
= {
344 .name
= "simpad-mq200",
348 static struct platform_device
*devices
[] __initdata
= {
358 static int __init
simpad_init(void)
362 spin_lock_init(&cs3_lock
);
364 cs3_gpio
.label
= "simpad_cs3";
365 cs3_gpio
.base
= SIMPAD_CS3_GPIO_BASE
;
367 cs3_gpio
.set
= cs3_gpio_set
;
368 cs3_gpio
.get
= cs3_gpio_get
;
369 cs3_gpio
.direction_input
= cs3_gpio_direction_input
;
370 cs3_gpio
.direction_output
= cs3_gpio_direction_output
;
371 ret
= gpiochip_add(&cs3_gpio
);
373 printk(KERN_WARNING
"simpad: Unable to register cs3 GPIO device");
375 pm_power_off
= simpad_power_off
;
377 sa11x0_ppc_configure_mcp();
378 sa11x0_register_mtd(&simpad_flash_data
, simpad_flash_resources
,
379 ARRAY_SIZE(simpad_flash_resources
));
380 sa11x0_register_mcp(&simpad_mcp_data
);
382 ret
= platform_add_devices(devices
, ARRAY_SIZE(devices
));
384 printk(KERN_WARNING
"simpad: Unable to register mq200 framebuffer device");
389 arch_initcall(simpad_init
);
392 MACHINE_START(SIMPAD
, "Simpad")
393 /* Maintainer: Holger Freyther */
394 .atag_offset
= 0x100,
395 .map_io
= simpad_map_io
,
396 .nr_irqs
= SA1100_NR_IRQS
,
397 .init_irq
= sa1100_init_irq
,
398 .init_late
= sa11x0_init_late
,
399 .init_time
= sa1100_timer_init
,
400 .restart
= sa11x0_restart
,