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>
24 #include <asm/mach-types.h>
25 #include <asm/mach/arch.h>
26 #include <asm/mach/flash.h>
27 #include <asm/mach/map.h>
28 #include <linux/platform_data/mfd-mcp-sa11x0.h>
29 #include <mach/simpad.h>
30 #include <mach/irqs.h>
32 #include <linux/serial_core.h>
33 #include <linux/ioport.h>
34 #include <linux/input.h>
35 #include <linux/gpio_keys.h>
36 #include <linux/leds.h>
37 #include <linux/i2c-gpio.h>
45 static long cs3_shadow
;
46 static spinlock_t cs3_lock
;
47 static struct gpio_chip cs3_gpio
;
49 long simpad_get_cs3_ro(void)
51 return readl(CS3_BASE
);
53 EXPORT_SYMBOL(simpad_get_cs3_ro
);
55 long simpad_get_cs3_shadow(void)
59 EXPORT_SYMBOL(simpad_get_cs3_shadow
);
61 static void __simpad_write_cs3(void)
63 writel(cs3_shadow
, CS3_BASE
);
66 void simpad_set_cs3_bit(int value
)
70 spin_lock_irqsave(&cs3_lock
, flags
);
73 spin_unlock_irqrestore(&cs3_lock
, flags
);
75 EXPORT_SYMBOL(simpad_set_cs3_bit
);
77 void simpad_clear_cs3_bit(int value
)
81 spin_lock_irqsave(&cs3_lock
, flags
);
84 spin_unlock_irqrestore(&cs3_lock
, flags
);
86 EXPORT_SYMBOL(simpad_clear_cs3_bit
);
88 static void cs3_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
93 simpad_set_cs3_bit(1 << offset
);
95 simpad_clear_cs3_bit(1 << offset
);
98 static int cs3_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
101 return simpad_get_cs3_ro() & (1 << (offset
- 16));
102 return simpad_get_cs3_shadow() & (1 << offset
);
105 static int cs3_gpio_direction_input(struct gpio_chip
*chip
, unsigned offset
)
112 static int cs3_gpio_direction_output(struct gpio_chip
*chip
, unsigned offset
,
117 cs3_gpio_set(chip
, offset
, value
);
121 static struct map_desc simpad_io_desc
[] __initdata
= {
123 .virtual = 0xf2800000,
124 .pfn
= __phys_to_pfn(0x4b800000),
125 .length
= 0x00800000,
127 }, { /* Simpad CS3 */
128 .virtual = (unsigned long)CS3_BASE
,
129 .pfn
= __phys_to_pfn(SA1100_CS3_PHYS
),
130 .length
= 0x00100000,
136 static void simpad_uart_pm(struct uart_port
*port
, u_int state
, u_int oldstate
)
138 if (port
->mapbase
== (u_int
)&Ser1UTCR0
) {
141 simpad_clear_cs3_bit(RS232_ON
);
142 simpad_clear_cs3_bit(DECT_POWER_ON
);
145 simpad_set_cs3_bit(RS232_ON
);
146 simpad_set_cs3_bit(DECT_POWER_ON
);
151 static struct sa1100_port_fns simpad_port_fns __initdata
= {
152 .pm
= simpad_uart_pm
,
156 static struct mtd_partition simpad_partitions
[] = {
158 .name
= "SIMpad boot firmware",
161 .mask_flags
= MTD_WRITEABLE
,
163 .name
= "SIMpad kernel",
165 .offset
= MTDPART_OFS_APPEND
,
167 .name
= "SIMpad root jffs2",
168 .size
= MTDPART_SIZ_FULL
,
169 .offset
= MTDPART_OFS_APPEND
,
173 static struct flash_platform_data simpad_flash_data
= {
174 .map_name
= "cfi_probe",
175 .parts
= simpad_partitions
,
176 .nr_parts
= ARRAY_SIZE(simpad_partitions
),
180 static struct resource simpad_flash_resources
[] = {
181 DEFINE_RES_MEM(SA1100_CS0_PHYS
, SZ_16M
),
182 DEFINE_RES_MEM(SA1100_CS1_PHYS
, SZ_16M
),
185 static struct ucb1x00_plat_data simpad_ucb1x00_data
= {
186 .gpio_base
= SIMPAD_UCB1X00_GPIO_BASE
,
189 static struct mcp_plat_data simpad_mcp_data
= {
191 .sclk_rate
= 11981000,
192 .codec_pdata
= &simpad_ucb1x00_data
,
197 static void __init
simpad_map_io(void)
201 iotable_init(simpad_io_desc
, ARRAY_SIZE(simpad_io_desc
));
204 cs3_shadow
= (EN1
| EN0
| LED2_ON
| DISPLAY_ON
|
205 RS232_ON
| ENABLE_5V
| RESET_SIMCARD
| DECT_POWER_ON
);
206 __simpad_write_cs3(); /* Spinlocks not yet initialized */
208 sa1100_register_uart_fns(&simpad_port_fns
);
209 sa1100_register_uart(0, 3); /* serial interface */
210 sa1100_register_uart(1, 1); /* DECT */
212 // Reassign UART 1 pins
213 GAFR
|= GPIO_UART_TXD
| GPIO_UART_RXD
;
214 GPDR
|= GPIO_UART_TXD
| GPIO_LDD13
| GPIO_LDD15
;
215 GPDR
&= ~GPIO_UART_RXD
;
219 * Set up registers for sleep mode.
223 PWER
= PWER_GPIO0
| PWER_RTC
;
230 static void simpad_power_off(void)
233 cs3_shadow
= SD_MEDIAQ
;
234 __simpad_write_cs3(); /* Bypass spinlock here */
236 /* disable internal oscillator, float CS lines */
237 PCFR
= (PCFR_OPDE
| PCFR_FP
| PCFR_FS
);
238 /* enable wake-up on GPIO0 */
239 PWER
= GFER
= GRER
= PWER_GPIO0
;
241 * set scratchpad to zero, just in case it is used as a
242 * restart address by the bootloader.
246 /* enter sleep mode */
250 local_irq_enable(); /* we won't ever call it */
259 static struct gpio_keys_button simpad_button_table
[] = {
260 { KEY_POWER
, IRQ_GPIO_POWER_BUTTON
, 1, "power button" },
263 static struct gpio_keys_platform_data simpad_keys_data
= {
264 .buttons
= simpad_button_table
,
265 .nbuttons
= ARRAY_SIZE(simpad_button_table
),
268 static struct platform_device simpad_keys
= {
271 .platform_data
= &simpad_keys_data
,
275 static struct gpio_keys_button simpad_polled_button_table
[] = {
276 { KEY_PROG1
, SIMPAD_UCB1X00_GPIO_PROG1
, 1, "prog1 button" },
277 { KEY_PROG2
, SIMPAD_UCB1X00_GPIO_PROG2
, 1, "prog2 button" },
278 { KEY_UP
, SIMPAD_UCB1X00_GPIO_UP
, 1, "up button" },
279 { KEY_DOWN
, SIMPAD_UCB1X00_GPIO_DOWN
, 1, "down button" },
280 { KEY_LEFT
, SIMPAD_UCB1X00_GPIO_LEFT
, 1, "left button" },
281 { KEY_RIGHT
, SIMPAD_UCB1X00_GPIO_RIGHT
, 1, "right button" },
284 static struct gpio_keys_platform_data simpad_polled_keys_data
= {
285 .buttons
= simpad_polled_button_table
,
286 .nbuttons
= ARRAY_SIZE(simpad_polled_button_table
),
290 static struct platform_device simpad_polled_keys
= {
291 .name
= "gpio-keys-polled",
293 .platform_data
= &simpad_polled_keys_data
,
301 static struct gpio_led simpad_leds
[] = {
303 .name
= "simpad:power",
304 .gpio
= SIMPAD_CS3_LED2_ON
,
306 .default_trigger
= "default-on",
310 static struct gpio_led_platform_data simpad_led_data
= {
311 .num_leds
= ARRAY_SIZE(simpad_leds
),
315 static struct platform_device simpad_gpio_leds
= {
319 .platform_data
= &simpad_led_data
,
326 static struct i2c_gpio_platform_data simpad_i2c_data
= {
327 .sda_pin
= GPIO_GPIO21
,
328 .scl_pin
= GPIO_GPIO25
,
333 static struct platform_device simpad_i2c
= {
337 .platform_data
= &simpad_i2c_data
,
342 * MediaQ Video Device
344 static struct platform_device simpad_mq200fb
= {
345 .name
= "simpad-mq200",
349 static struct platform_device
*devices
[] __initdata
= {
359 static int __init
simpad_init(void)
363 spin_lock_init(&cs3_lock
);
365 cs3_gpio
.label
= "simpad_cs3";
366 cs3_gpio
.base
= SIMPAD_CS3_GPIO_BASE
;
368 cs3_gpio
.set
= cs3_gpio_set
;
369 cs3_gpio
.get
= cs3_gpio_get
;
370 cs3_gpio
.direction_input
= cs3_gpio_direction_input
;
371 cs3_gpio
.direction_output
= cs3_gpio_direction_output
;
372 ret
= gpiochip_add(&cs3_gpio
);
374 printk(KERN_WARNING
"simpad: Unable to register cs3 GPIO device");
376 pm_power_off
= simpad_power_off
;
378 sa11x0_ppc_configure_mcp();
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 .nr_irqs
= SA1100_NR_IRQS
,
398 .init_irq
= sa1100_init_irq
,
399 .init_late
= sa11x0_init_late
,
400 .init_time
= sa1100_timer_init
,
401 .restart
= sa11x0_restart
,