diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-07-12 16:43:01 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-07-12 16:43:01 -0400 |
commit | 7fecc34e07e02b4d9dab1a1f4bf7fdac0a656b9b (patch) | |
tree | 110d24e6394dbd98cb33d80a5587cd18c8315e0b /arch/arm/mach-pxa | |
parent | a9da4f7ed6a702996ac9d1bbaf1a3969a4c092b3 (diff) | |
parent | 938870491f0cad030b358af47e28d124b72702d1 (diff) |
Merge branch 'pxa-tosa' into pxa
Conflicts:
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/spitz.c
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r-- | arch/arm/mach-pxa/Kconfig | 9 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-pxa/reset.c | 96 | ||||
-rw-r--r-- | arch/arm/mach-pxa/spitz.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-pxa/tosa-bt.c | 150 | ||||
-rw-r--r-- | arch/arm/mach-pxa/tosa.c | 390 |
6 files changed, 604 insertions, 53 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 1a7ceb8866f9..7f9664dee670 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -310,4 +310,13 @@ config PXA_PWM | |||
310 | default BACKLIGHT_PWM | 310 | default BACKLIGHT_PWM |
311 | help | 311 | help |
312 | Enable support for PXA2xx/PXA3xx PWM controllers | 312 | Enable support for PXA2xx/PXA3xx PWM controllers |
313 | |||
314 | config TOSA_BT | ||
315 | tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" | ||
316 | depends on MACH_TOSA | ||
317 | select RFKILL | ||
318 | help | ||
319 | This is a simple driver that is able to control | ||
320 | the state of built in bluetooth chip on tosa. | ||
321 | |||
313 | endif | 322 | endif |
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 0865236513c7..b282412a01f5 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | # Common support (must be linked before board specific support) | 5 | # Common support (must be linked before board specific support) |
6 | obj-y += clock.o devices.o generic.o irq.o dma.o \ | 6 | obj-y += clock.o devices.o generic.o irq.o dma.o \ |
7 | time.o gpio.o | 7 | time.o gpio.o reset.o |
8 | obj-$(CONFIG_PM) += pm.o sleep.o standby.o | 8 | obj-$(CONFIG_PM) += pm.o sleep.o standby.o |
9 | obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o | 9 | obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o |
10 | 10 | ||
@@ -61,3 +61,5 @@ obj-$(CONFIG_LEDS) += $(led-y) | |||
61 | ifeq ($(CONFIG_PCI),y) | 61 | ifeq ($(CONFIG_PCI),y) |
62 | obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o | 62 | obj-$(CONFIG_MACH_ARMCORE) += cm-x270-pci.o |
63 | endif | 63 | endif |
64 | |||
65 | obj-$(CONFIG_TOSA_BT) += tosa-bt.o | ||
diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c new file mode 100644 index 000000000000..9d39dea57ce2 --- /dev/null +++ b/arch/arm/mach-pxa/reset.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | */ | ||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/gpio.h> | ||
10 | #include <asm/io.h> | ||
11 | #include <asm/proc-fns.h> | ||
12 | |||
13 | #include <asm/arch/pxa-regs.h> | ||
14 | #include <asm/arch/pxa2xx-regs.h> | ||
15 | |||
16 | static void do_hw_reset(void); | ||
17 | |||
18 | static int reset_gpio = -1; | ||
19 | |||
20 | int init_gpio_reset(int gpio) | ||
21 | { | ||
22 | int rc; | ||
23 | |||
24 | rc = gpio_request(gpio, "reset generator"); | ||
25 | if (rc) { | ||
26 | printk(KERN_ERR "Can't request reset_gpio\n"); | ||
27 | goto out; | ||
28 | } | ||
29 | |||
30 | rc = gpio_direction_input(gpio); | ||
31 | if (rc) { | ||
32 | printk(KERN_ERR "Can't configure reset_gpio for input\n"); | ||
33 | gpio_free(gpio); | ||
34 | goto out; | ||
35 | } | ||
36 | |||
37 | out: | ||
38 | if (!rc) | ||
39 | reset_gpio = gpio; | ||
40 | |||
41 | return rc; | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * Trigger GPIO reset. | ||
46 | * This covers various types of logic connecting gpio pin | ||
47 | * to RESET pins (nRESET or GPIO_RESET): | ||
48 | */ | ||
49 | static void do_gpio_reset(void) | ||
50 | { | ||
51 | BUG_ON(reset_gpio == -1); | ||
52 | |||
53 | /* drive it low */ | ||
54 | gpio_direction_output(reset_gpio, 0); | ||
55 | mdelay(2); | ||
56 | /* rising edge or drive high */ | ||
57 | gpio_set_value(reset_gpio, 1); | ||
58 | mdelay(2); | ||
59 | /* falling edge */ | ||
60 | gpio_set_value(reset_gpio, 0); | ||
61 | |||
62 | /* give it some time */ | ||
63 | mdelay(10); | ||
64 | |||
65 | WARN_ON(1); | ||
66 | /* fallback */ | ||
67 | do_hw_reset(); | ||
68 | } | ||
69 | |||
70 | static void do_hw_reset(void) | ||
71 | { | ||
72 | /* Initialize the watchdog and let it fire */ | ||
73 | OWER = OWER_WME; | ||
74 | OSSR = OSSR_M3; | ||
75 | OSMR3 = OSCR + 368640; /* ... in 100 ms */ | ||
76 | } | ||
77 | |||
78 | void arch_reset(char mode) | ||
79 | { | ||
80 | if (cpu_is_pxa2xx()) | ||
81 | RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; | ||
82 | |||
83 | switch (mode) { | ||
84 | case 's': | ||
85 | /* Jump into ROM at address 0 */ | ||
86 | cpu_reset(0); | ||
87 | break; | ||
88 | case 'h': | ||
89 | do_hw_reset(); | ||
90 | break; | ||
91 | case 'g': | ||
92 | do_gpio_reset(); | ||
93 | break; | ||
94 | } | ||
95 | } | ||
96 | |||
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index e7d0fcd9b43f..d58c3e906a93 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/arch/pxa-regs.h> | 38 | #include <asm/arch/pxa-regs.h> |
39 | #include <asm/arch/pxa2xx-regs.h> | 39 | #include <asm/arch/pxa2xx-regs.h> |
40 | #include <asm/arch/pxa2xx-gpio.h> | 40 | #include <asm/arch/pxa2xx-gpio.h> |
41 | #include <asm/arch/pxa27x-udc.h> | ||
41 | #include <asm/arch/irda.h> | 42 | #include <asm/arch/irda.h> |
42 | #include <asm/arch/mmc.h> | 43 | #include <asm/arch/mmc.h> |
43 | #include <asm/arch/ohci.h> | 44 | #include <asm/arch/ohci.h> |
@@ -529,11 +530,7 @@ static struct platform_device *devices[] __initdata = { | |||
529 | 530 | ||
530 | static void spitz_poweroff(void) | 531 | static void spitz_poweroff(void) |
531 | { | 532 | { |
532 | pxa_gpio_mode(SPITZ_GPIO_ON_RESET | GPIO_OUT); | 533 | arm_machine_restart('g'); |
533 | GPSR(SPITZ_GPIO_ON_RESET) = GPIO_bit(SPITZ_GPIO_ON_RESET); | ||
534 | |||
535 | mdelay(1000); | ||
536 | arm_machine_restart('h'); | ||
537 | } | 534 | } |
538 | 535 | ||
539 | static void spitz_restart(char mode) | 536 | static void spitz_restart(char mode) |
@@ -547,6 +544,7 @@ static void spitz_restart(char mode) | |||
547 | 544 | ||
548 | static void __init common_init(void) | 545 | static void __init common_init(void) |
549 | { | 546 | { |
547 | init_gpio_reset(SPITZ_GPIO_ON_RESET); | ||
550 | pm_power_off = spitz_poweroff; | 548 | pm_power_off = spitz_poweroff; |
551 | arm_pm_restart = spitz_restart; | 549 | arm_pm_restart = spitz_restart; |
552 | 550 | ||
diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c new file mode 100644 index 000000000000..7d8505466e54 --- /dev/null +++ b/arch/arm/mach-pxa/tosa-bt.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * Bluetooth built-in chip control | ||
3 | * | ||
4 | * Copyright (c) 2008 Dmitry Baryshkov | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/rfkill.h> | ||
18 | |||
19 | #include <asm/arch/tosa_bt.h> | ||
20 | |||
21 | static void tosa_bt_on(struct tosa_bt_data *data) | ||
22 | { | ||
23 | gpio_set_value(data->gpio_reset, 0); | ||
24 | gpio_set_value(data->gpio_pwr, 1); | ||
25 | gpio_set_value(data->gpio_reset, 1); | ||
26 | mdelay(20); | ||
27 | gpio_set_value(data->gpio_reset, 0); | ||
28 | } | ||
29 | |||
30 | static void tosa_bt_off(struct tosa_bt_data *data) | ||
31 | { | ||
32 | gpio_set_value(data->gpio_reset, 1); | ||
33 | mdelay(10); | ||
34 | gpio_set_value(data->gpio_pwr, 0); | ||
35 | gpio_set_value(data->gpio_reset, 0); | ||
36 | } | ||
37 | |||
38 | static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) | ||
39 | { | ||
40 | pr_info("BT_RADIO going: %s\n", | ||
41 | state == RFKILL_STATE_ON ? "on" : "off"); | ||
42 | |||
43 | if (state == RFKILL_STATE_ON) { | ||
44 | pr_info("TOSA_BT: going ON\n"); | ||
45 | tosa_bt_on(data); | ||
46 | } else { | ||
47 | pr_info("TOSA_BT: going OFF\n"); | ||
48 | tosa_bt_off(data); | ||
49 | } | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | static int tosa_bt_probe(struct platform_device *dev) | ||
54 | { | ||
55 | int rc; | ||
56 | struct rfkill *rfk; | ||
57 | |||
58 | struct tosa_bt_data *data = dev->dev.platform_data; | ||
59 | |||
60 | rc = gpio_request(data->gpio_reset, "Bluetooth reset"); | ||
61 | if (rc) | ||
62 | goto err_reset; | ||
63 | rc = gpio_direction_output(data->gpio_reset, 0); | ||
64 | if (rc) | ||
65 | goto err_reset_dir; | ||
66 | rc = gpio_request(data->gpio_pwr, "Bluetooth power"); | ||
67 | if (rc) | ||
68 | goto err_pwr; | ||
69 | rc = gpio_direction_output(data->gpio_pwr, 0); | ||
70 | if (rc) | ||
71 | goto err_pwr_dir; | ||
72 | |||
73 | rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH); | ||
74 | if (!rfk) { | ||
75 | rc = -ENOMEM; | ||
76 | goto err_rfk_alloc; | ||
77 | } | ||
78 | |||
79 | rfk->name = "tosa-bt"; | ||
80 | rfk->toggle_radio = tosa_bt_toggle_radio; | ||
81 | rfk->data = data; | ||
82 | #ifdef CONFIG_RFKILL_LEDS | ||
83 | rfk->led_trigger.name = "tosa-bt"; | ||
84 | #endif | ||
85 | |||
86 | rc = rfkill_register(rfk); | ||
87 | if (rc) | ||
88 | goto err_rfkill; | ||
89 | |||
90 | platform_set_drvdata(dev, rfk); | ||
91 | |||
92 | return 0; | ||
93 | |||
94 | err_rfkill: | ||
95 | if (rfk) | ||
96 | rfkill_free(rfk); | ||
97 | rfk = NULL; | ||
98 | err_rfk_alloc: | ||
99 | tosa_bt_off(data); | ||
100 | err_pwr_dir: | ||
101 | gpio_free(data->gpio_pwr); | ||
102 | err_pwr: | ||
103 | err_reset_dir: | ||
104 | gpio_free(data->gpio_reset); | ||
105 | err_reset: | ||
106 | return rc; | ||
107 | } | ||
108 | |||
109 | static int __devexit tosa_bt_remove(struct platform_device *dev) | ||
110 | { | ||
111 | struct tosa_bt_data *data = dev->dev.platform_data; | ||
112 | struct rfkill *rfk = platform_get_drvdata(dev); | ||
113 | |||
114 | platform_set_drvdata(dev, NULL); | ||
115 | |||
116 | if (rfk) | ||
117 | rfkill_unregister(rfk); | ||
118 | rfk = NULL; | ||
119 | |||
120 | tosa_bt_off(data); | ||
121 | |||
122 | gpio_free(data->gpio_pwr); | ||
123 | gpio_free(data->gpio_reset); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static struct platform_driver tosa_bt_driver = { | ||
129 | .probe = tosa_bt_probe, | ||
130 | .remove = __devexit_p(tosa_bt_remove), | ||
131 | |||
132 | .driver = { | ||
133 | .name = "tosa-bt", | ||
134 | .owner = THIS_MODULE, | ||
135 | }, | ||
136 | }; | ||
137 | |||
138 | |||
139 | static int __init tosa_bt_init(void) | ||
140 | { | ||
141 | return platform_driver_register(&tosa_bt_driver); | ||
142 | } | ||
143 | |||
144 | static void __exit tosa_bt_exit(void) | ||
145 | { | ||
146 | platform_driver_unregister(&tosa_bt_driver); | ||
147 | } | ||
148 | |||
149 | module_init(tosa_bt_init); | ||
150 | module_exit(tosa_bt_exit); | ||
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index ab4a9f579913..2d49de572ba1 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c | |||
@@ -18,30 +18,31 @@ | |||
18 | #include <linux/major.h> | 18 | #include <linux/major.h> |
19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/delay.h> | ||
22 | #include <linux/fb.h> | ||
21 | #include <linux/mmc/host.h> | 23 | #include <linux/mmc/host.h> |
24 | #include <linux/mfd/tc6393xb.h> | ||
25 | #include <linux/mfd/tmio.h> | ||
26 | #include <linux/mtd/nand.h> | ||
27 | #include <linux/mtd/partitions.h> | ||
22 | #include <linux/pm.h> | 28 | #include <linux/pm.h> |
23 | #include <linux/delay.h> | ||
24 | #include <linux/gpio_keys.h> | 29 | #include <linux/gpio_keys.h> |
25 | #include <linux/input.h> | 30 | #include <linux/input.h> |
26 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
32 | #include <linux/pda_power.h> | ||
33 | #include <linux/rfkill.h> | ||
27 | 34 | ||
28 | #include <asm/setup.h> | 35 | #include <asm/setup.h> |
29 | #include <asm/memory.h> | ||
30 | #include <asm/mach-types.h> | 36 | #include <asm/mach-types.h> |
31 | #include <asm/hardware.h> | ||
32 | #include <asm/irq.h> | ||
33 | #include <asm/system.h> | ||
34 | #include <asm/arch/pxa-regs.h> | ||
35 | #include <asm/arch/pxa2xx-regs.h> | 37 | #include <asm/arch/pxa2xx-regs.h> |
36 | #include <asm/arch/mfp-pxa25x.h> | 38 | #include <asm/arch/mfp-pxa25x.h> |
37 | #include <asm/arch/irda.h> | 39 | #include <asm/arch/irda.h> |
38 | #include <asm/arch/i2c.h> | 40 | #include <asm/arch/i2c.h> |
39 | #include <asm/arch/mmc.h> | 41 | #include <asm/arch/mmc.h> |
40 | #include <asm/arch/udc.h> | 42 | #include <asm/arch/udc.h> |
43 | #include <asm/arch/tosa_bt.h> | ||
41 | 44 | ||
42 | #include <asm/mach/arch.h> | 45 | #include <asm/mach/arch.h> |
43 | #include <asm/mach/map.h> | ||
44 | #include <asm/mach/irq.h> | ||
45 | #include <asm/arch/tosa.h> | 46 | #include <asm/arch/tosa.h> |
46 | 47 | ||
47 | #include <asm/hardware/scoop.h> | 48 | #include <asm/hardware/scoop.h> |
@@ -86,7 +87,7 @@ static unsigned long tosa_pin_config[] = { | |||
86 | GPIO6_MMC_CLK, | 87 | GPIO6_MMC_CLK, |
87 | GPIO8_MMC_CS0, | 88 | GPIO8_MMC_CS0, |
88 | GPIO9_GPIO, /* Detect */ | 89 | GPIO9_GPIO, /* Detect */ |
89 | // GPIO10 nSD_INT | 90 | GPIO10_GPIO, /* nSD_INT */ |
90 | 91 | ||
91 | /* CF */ | 92 | /* CF */ |
92 | GPIO13_GPIO, /* CD_IRQ */ | 93 | GPIO13_GPIO, /* CD_IRQ */ |
@@ -124,29 +125,25 @@ static unsigned long tosa_pin_config[] = { | |||
124 | GPIO44_BTUART_CTS, | 125 | GPIO44_BTUART_CTS, |
125 | GPIO45_BTUART_RTS, | 126 | GPIO45_BTUART_RTS, |
126 | 127 | ||
127 | /* IrDA */ | ||
128 | GPIO46_STUART_RXD, | ||
129 | GPIO47_STUART_TXD, | ||
130 | |||
131 | /* Keybd */ | 128 | /* Keybd */ |
132 | GPIO58_GPIO, | 129 | GPIO58_GPIO | MFP_LPM_DRIVE_LOW, |
133 | GPIO59_GPIO, | 130 | GPIO59_GPIO | MFP_LPM_DRIVE_LOW, |
134 | GPIO60_GPIO, | 131 | GPIO60_GPIO | MFP_LPM_DRIVE_LOW, |
135 | GPIO61_GPIO, | 132 | GPIO61_GPIO | MFP_LPM_DRIVE_LOW, |
136 | GPIO62_GPIO, | 133 | GPIO62_GPIO | MFP_LPM_DRIVE_LOW, |
137 | GPIO63_GPIO, | 134 | GPIO63_GPIO | MFP_LPM_DRIVE_LOW, |
138 | GPIO64_GPIO, | 135 | GPIO64_GPIO | MFP_LPM_DRIVE_LOW, |
139 | GPIO65_GPIO, | 136 | GPIO65_GPIO | MFP_LPM_DRIVE_LOW, |
140 | GPIO66_GPIO, | 137 | GPIO66_GPIO | MFP_LPM_DRIVE_LOW, |
141 | GPIO67_GPIO, | 138 | GPIO67_GPIO | MFP_LPM_DRIVE_LOW, |
142 | GPIO68_GPIO, | 139 | GPIO68_GPIO | MFP_LPM_DRIVE_LOW, |
143 | GPIO69_GPIO, | 140 | GPIO69_GPIO | MFP_LPM_DRIVE_LOW, |
144 | GPIO70_GPIO, | 141 | GPIO70_GPIO | MFP_LPM_DRIVE_LOW, |
145 | GPIO71_GPIO, | 142 | GPIO71_GPIO | MFP_LPM_DRIVE_LOW, |
146 | GPIO72_GPIO, | 143 | GPIO72_GPIO | MFP_LPM_DRIVE_LOW, |
147 | GPIO73_GPIO, | 144 | GPIO73_GPIO | MFP_LPM_DRIVE_LOW, |
148 | GPIO74_GPIO, | 145 | GPIO74_GPIO | MFP_LPM_DRIVE_LOW, |
149 | GPIO75_GPIO, | 146 | GPIO75_GPIO | MFP_LPM_DRIVE_LOW, |
150 | 147 | ||
151 | /* SPI */ | 148 | /* SPI */ |
152 | GPIO81_SSP2_CLK_OUT, | 149 | GPIO81_SSP2_CLK_OUT, |
@@ -154,6 +151,17 @@ static unsigned long tosa_pin_config[] = { | |||
154 | GPIO83_SSP2_TXD, | 151 | GPIO83_SSP2_TXD, |
155 | }; | 152 | }; |
156 | 153 | ||
154 | static unsigned long tosa_pin_irda_off[] = { | ||
155 | GPIO46_STUART_RXD, | ||
156 | GPIO47_GPIO | MFP_LPM_DRIVE_LOW, | ||
157 | }; | ||
158 | |||
159 | static unsigned long tosa_pin_irda_on[] = { | ||
160 | GPIO46_STUART_RXD, | ||
161 | GPIO47_STUART_TXD, | ||
162 | }; | ||
163 | |||
164 | |||
157 | /* | 165 | /* |
158 | * SCOOP Device | 166 | * SCOOP Device |
159 | */ | 167 | */ |
@@ -249,6 +257,15 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void | |||
249 | 257 | ||
250 | tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); | 258 | tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); |
251 | 259 | ||
260 | err = gpio_request(TOSA_GPIO_nSD_DETECT, "MMC/SD card detect"); | ||
261 | if (err) { | ||
262 | printk(KERN_ERR "tosa_mci_init: can't request nSD_DETECT gpio\n"); | ||
263 | goto err_gpio_detect; | ||
264 | } | ||
265 | err = gpio_direction_input(TOSA_GPIO_nSD_DETECT); | ||
266 | if (err) | ||
267 | goto err_gpio_detect_dir; | ||
268 | |||
252 | err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, | 269 | err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, |
253 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 270 | IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
254 | "MMC/SD card detect", data); | 271 | "MMC/SD card detect", data); |
@@ -257,7 +274,7 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void | |||
257 | goto err_irq; | 274 | goto err_irq; |
258 | } | 275 | } |
259 | 276 | ||
260 | err = gpio_request(TOSA_GPIO_SD_WP, "sd_wp"); | 277 | err = gpio_request(TOSA_GPIO_SD_WP, "SD Write Protect"); |
261 | if (err) { | 278 | if (err) { |
262 | printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n"); | 279 | printk(KERN_ERR "tosa_mci_init: can't request SD_WP gpio\n"); |
263 | goto err_gpio_wp; | 280 | goto err_gpio_wp; |
@@ -266,7 +283,7 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void | |||
266 | if (err) | 283 | if (err) |
267 | goto err_gpio_wp_dir; | 284 | goto err_gpio_wp_dir; |
268 | 285 | ||
269 | err = gpio_request(TOSA_GPIO_PWR_ON, "sd_pwr"); | 286 | err = gpio_request(TOSA_GPIO_PWR_ON, "SD Power"); |
270 | if (err) { | 287 | if (err) { |
271 | printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); | 288 | printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); |
272 | goto err_gpio_pwr; | 289 | goto err_gpio_pwr; |
@@ -275,8 +292,20 @@ static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void | |||
275 | if (err) | 292 | if (err) |
276 | goto err_gpio_pwr_dir; | 293 | goto err_gpio_pwr_dir; |
277 | 294 | ||
295 | err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int"); | ||
296 | if (err) { | ||
297 | printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n"); | ||
298 | goto err_gpio_int; | ||
299 | } | ||
300 | err = gpio_direction_input(TOSA_GPIO_nSD_INT); | ||
301 | if (err) | ||
302 | goto err_gpio_int_dir; | ||
303 | |||
278 | return 0; | 304 | return 0; |
279 | 305 | ||
306 | err_gpio_int_dir: | ||
307 | gpio_free(TOSA_GPIO_nSD_INT); | ||
308 | err_gpio_int: | ||
280 | err_gpio_pwr_dir: | 309 | err_gpio_pwr_dir: |
281 | gpio_free(TOSA_GPIO_PWR_ON); | 310 | gpio_free(TOSA_GPIO_PWR_ON); |
282 | err_gpio_pwr: | 311 | err_gpio_pwr: |
@@ -285,6 +314,9 @@ err_gpio_wp_dir: | |||
285 | err_gpio_wp: | 314 | err_gpio_wp: |
286 | free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); | 315 | free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); |
287 | err_irq: | 316 | err_irq: |
317 | err_gpio_detect_dir: | ||
318 | gpio_free(TOSA_GPIO_nSD_DETECT); | ||
319 | err_gpio_detect: | ||
288 | return err; | 320 | return err; |
289 | } | 321 | } |
290 | 322 | ||
@@ -306,9 +338,11 @@ static int tosa_mci_get_ro(struct device *dev) | |||
306 | 338 | ||
307 | static void tosa_mci_exit(struct device *dev, void *data) | 339 | static void tosa_mci_exit(struct device *dev, void *data) |
308 | { | 340 | { |
341 | gpio_free(TOSA_GPIO_nSD_INT); | ||
309 | gpio_free(TOSA_GPIO_PWR_ON); | 342 | gpio_free(TOSA_GPIO_PWR_ON); |
310 | gpio_free(TOSA_GPIO_SD_WP); | 343 | gpio_free(TOSA_GPIO_SD_WP); |
311 | free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); | 344 | free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); |
345 | gpio_free(TOSA_GPIO_nSD_DETECT); | ||
312 | } | 346 | } |
313 | 347 | ||
314 | static struct pxamci_platform_data tosa_mci_platform_data = { | 348 | static struct pxamci_platform_data tosa_mci_platform_data = { |
@@ -322,29 +356,55 @@ static struct pxamci_platform_data tosa_mci_platform_data = { | |||
322 | /* | 356 | /* |
323 | * Irda | 357 | * Irda |
324 | */ | 358 | */ |
359 | static void tosa_irda_transceiver_mode(struct device *dev, int mode) | ||
360 | { | ||
361 | if (mode & IR_OFF) { | ||
362 | gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0); | ||
363 | pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off)); | ||
364 | gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); | ||
365 | } else { | ||
366 | pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_on)); | ||
367 | gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1); | ||
368 | } | ||
369 | } | ||
370 | |||
325 | static int tosa_irda_startup(struct device *dev) | 371 | static int tosa_irda_startup(struct device *dev) |
326 | { | 372 | { |
327 | int ret; | 373 | int ret; |
328 | 374 | ||
375 | ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX"); | ||
376 | if (ret) | ||
377 | goto err_tx; | ||
378 | ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0); | ||
379 | if (ret) | ||
380 | goto err_tx_dir; | ||
381 | |||
329 | ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown"); | 382 | ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown"); |
330 | if (ret) | 383 | if (ret) |
331 | return ret; | 384 | goto err_pwr; |
332 | 385 | ||
333 | ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0); | 386 | ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0); |
334 | if (ret) | 387 | if (ret) |
335 | gpio_free(TOSA_GPIO_IR_POWERDWN); | 388 | goto err_pwr_dir; |
336 | 389 | ||
337 | return ret; | 390 | tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); |
338 | } | ||
339 | 391 | ||
340 | static void tosa_irda_shutdown(struct device *dev) | 392 | return 0; |
341 | { | 393 | |
394 | err_pwr_dir: | ||
342 | gpio_free(TOSA_GPIO_IR_POWERDWN); | 395 | gpio_free(TOSA_GPIO_IR_POWERDWN); |
396 | err_pwr: | ||
397 | err_tx_dir: | ||
398 | gpio_free(TOSA_GPIO_IRDA_TX); | ||
399 | err_tx: | ||
400 | return ret; | ||
343 | } | 401 | } |
344 | 402 | ||
345 | static void tosa_irda_transceiver_mode(struct device *dev, int mode) | 403 | static void tosa_irda_shutdown(struct device *dev) |
346 | { | 404 | { |
347 | gpio_set_value(TOSA_GPIO_IR_POWERDWN, !(mode & IR_OFF)); | 405 | tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF); |
406 | gpio_free(TOSA_GPIO_IR_POWERDWN); | ||
407 | gpio_free(TOSA_GPIO_IRDA_TX); | ||
348 | } | 408 | } |
349 | 409 | ||
350 | static struct pxaficp_platform_data tosa_ficp_platform_data = { | 410 | static struct pxaficp_platform_data tosa_ficp_platform_data = { |
@@ -355,6 +415,70 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = { | |||
355 | }; | 415 | }; |
356 | 416 | ||
357 | /* | 417 | /* |
418 | * Tosa AC IN | ||
419 | */ | ||
420 | static int tosa_power_init(struct device *dev) | ||
421 | { | ||
422 | int ret = gpio_request(TOSA_GPIO_AC_IN, "ac in"); | ||
423 | if (ret) | ||
424 | goto err_gpio_req; | ||
425 | |||
426 | ret = gpio_direction_input(TOSA_GPIO_AC_IN); | ||
427 | if (ret) | ||
428 | goto err_gpio_in; | ||
429 | |||
430 | return 0; | ||
431 | |||
432 | err_gpio_in: | ||
433 | gpio_free(TOSA_GPIO_AC_IN); | ||
434 | err_gpio_req: | ||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | static void tosa_power_exit(struct device *dev) | ||
439 | { | ||
440 | gpio_free(TOSA_GPIO_AC_IN); | ||
441 | } | ||
442 | |||
443 | static int tosa_power_ac_online(void) | ||
444 | { | ||
445 | return gpio_get_value(TOSA_GPIO_AC_IN) == 0; | ||
446 | } | ||
447 | |||
448 | static char *tosa_ac_supplied_to[] = { | ||
449 | "main-battery", | ||
450 | "backup-battery", | ||
451 | "jacket-battery", | ||
452 | }; | ||
453 | |||
454 | static struct pda_power_pdata tosa_power_data = { | ||
455 | .init = tosa_power_init, | ||
456 | .is_ac_online = tosa_power_ac_online, | ||
457 | .exit = tosa_power_exit, | ||
458 | .supplied_to = tosa_ac_supplied_to, | ||
459 | .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), | ||
460 | }; | ||
461 | |||
462 | static struct resource tosa_power_resource[] = { | ||
463 | { | ||
464 | .name = "ac", | ||
465 | .start = gpio_to_irq(TOSA_GPIO_AC_IN), | ||
466 | .end = gpio_to_irq(TOSA_GPIO_AC_IN), | ||
467 | .flags = IORESOURCE_IRQ | | ||
468 | IORESOURCE_IRQ_HIGHEDGE | | ||
469 | IORESOURCE_IRQ_LOWEDGE, | ||
470 | }, | ||
471 | }; | ||
472 | |||
473 | static struct platform_device tosa_power_device = { | ||
474 | .name = "pda-power", | ||
475 | .id = -1, | ||
476 | .dev.platform_data = &tosa_power_data, | ||
477 | .resource = tosa_power_resource, | ||
478 | .num_resources = ARRAY_SIZE(tosa_power_resource), | ||
479 | }; | ||
480 | |||
481 | /* | ||
358 | * Tosa Keyboard | 482 | * Tosa Keyboard |
359 | */ | 483 | */ |
360 | static struct platform_device tosakbd_device = { | 484 | static struct platform_device tosakbd_device = { |
@@ -439,7 +563,7 @@ static struct gpio_led tosa_gpio_leds[] = { | |||
439 | }, | 563 | }, |
440 | { | 564 | { |
441 | .name = "tosa:blue:bluetooth", | 565 | .name = "tosa:blue:bluetooth", |
442 | .default_trigger = "none", | 566 | .default_trigger = "tosa-bt", |
443 | .gpio = TOSA_GPIO_BT_LED, | 567 | .gpio = TOSA_GPIO_BT_LED, |
444 | }, | 568 | }, |
445 | }; | 569 | }; |
@@ -457,21 +581,184 @@ static struct platform_device tosaled_device = { | |||
457 | }, | 581 | }, |
458 | }; | 582 | }; |
459 | 583 | ||
584 | /* | ||
585 | * Toshiba Mobile IO Controller | ||
586 | */ | ||
587 | static struct resource tc6393xb_resources[] = { | ||
588 | [0] = { | ||
589 | .start = TOSA_LCDC_PHYS, | ||
590 | .end = TOSA_LCDC_PHYS + 0x3ffffff, | ||
591 | .flags = IORESOURCE_MEM, | ||
592 | }, | ||
593 | |||
594 | [1] = { | ||
595 | .start = TOSA_IRQ_GPIO_TC6393XB_INT, | ||
596 | .end = TOSA_IRQ_GPIO_TC6393XB_INT, | ||
597 | .flags = IORESOURCE_IRQ, | ||
598 | }, | ||
599 | }; | ||
600 | |||
601 | |||
602 | static int tosa_tc6393xb_enable(struct platform_device *dev) | ||
603 | { | ||
604 | int rc; | ||
605 | |||
606 | rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr"); | ||
607 | if (rc) | ||
608 | goto err_req_pclr; | ||
609 | rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend"); | ||
610 | if (rc) | ||
611 | goto err_req_suspend; | ||
612 | rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v"); | ||
613 | if (rc) | ||
614 | goto err_req_l3v; | ||
615 | rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0); | ||
616 | if (rc) | ||
617 | goto err_dir_l3v; | ||
618 | rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0); | ||
619 | if (rc) | ||
620 | goto err_dir_suspend; | ||
621 | rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0); | ||
622 | if (rc) | ||
623 | goto err_dir_pclr; | ||
624 | |||
625 | mdelay(1); | ||
626 | |||
627 | gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); | ||
628 | |||
629 | mdelay(10); | ||
630 | |||
631 | gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1); | ||
632 | gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); | ||
633 | |||
634 | return 0; | ||
635 | err_dir_pclr: | ||
636 | err_dir_suspend: | ||
637 | err_dir_l3v: | ||
638 | gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); | ||
639 | err_req_l3v: | ||
640 | gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); | ||
641 | err_req_suspend: | ||
642 | gpio_free(TOSA_GPIO_TC6393XB_REST_IN); | ||
643 | err_req_pclr: | ||
644 | return rc; | ||
645 | } | ||
646 | |||
647 | static int tosa_tc6393xb_disable(struct platform_device *dev) | ||
648 | { | ||
649 | gpio_free(TOSA_GPIO_TC6393XB_L3V_ON); | ||
650 | gpio_free(TOSA_GPIO_TC6393XB_SUSPEND); | ||
651 | gpio_free(TOSA_GPIO_TC6393XB_REST_IN); | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | static int tosa_tc6393xb_resume(struct platform_device *dev) | ||
657 | { | ||
658 | gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1); | ||
659 | mdelay(10); | ||
660 | gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1); | ||
661 | mdelay(10); | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static int tosa_tc6393xb_suspend(struct platform_device *dev) | ||
667 | { | ||
668 | gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0); | ||
669 | gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0); | ||
670 | return 0; | ||
671 | } | ||
672 | |||
673 | static struct mtd_partition tosa_nand_partition[] = { | ||
674 | { | ||
675 | .name = "smf", | ||
676 | .offset = 0, | ||
677 | .size = 7 * 1024 * 1024, | ||
678 | }, | ||
679 | { | ||
680 | .name = "root", | ||
681 | .offset = MTDPART_OFS_APPEND, | ||
682 | .size = 28 * 1024 * 1024, | ||
683 | }, | ||
684 | { | ||
685 | .name = "home", | ||
686 | .offset = MTDPART_OFS_APPEND, | ||
687 | .size = MTDPART_SIZ_FULL, | ||
688 | }, | ||
689 | }; | ||
690 | |||
691 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; | ||
692 | |||
693 | static struct nand_bbt_descr tosa_tc6393xb_nand_bbt = { | ||
694 | .options = 0, | ||
695 | .offs = 4, | ||
696 | .len = 2, | ||
697 | .pattern = scan_ff_pattern | ||
698 | }; | ||
699 | |||
700 | static struct tmio_nand_data tosa_tc6393xb_nand_config = { | ||
701 | .num_partitions = ARRAY_SIZE(tosa_nand_partition), | ||
702 | .partition = tosa_nand_partition, | ||
703 | .badblock_pattern = &tosa_tc6393xb_nand_bbt, | ||
704 | }; | ||
705 | |||
706 | static struct tc6393xb_platform_data tosa_tc6393xb_setup = { | ||
707 | .scr_pll2cr = 0x0cc1, | ||
708 | .scr_gper = 0x3300, | ||
709 | .scr_gpo_dsr = | ||
710 | TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), | ||
711 | .scr_gpo_doecr = | ||
712 | TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON), | ||
713 | |||
714 | .irq_base = IRQ_BOARD_START, | ||
715 | .gpio_base = TOSA_TC6393XB_GPIO_BASE, | ||
716 | |||
717 | .enable = tosa_tc6393xb_enable, | ||
718 | .disable = tosa_tc6393xb_disable, | ||
719 | .suspend = tosa_tc6393xb_suspend, | ||
720 | .resume = tosa_tc6393xb_resume, | ||
721 | |||
722 | .nand_data = &tosa_tc6393xb_nand_config, | ||
723 | }; | ||
724 | |||
725 | |||
726 | static struct platform_device tc6393xb_device = { | ||
727 | .name = "tc6393xb", | ||
728 | .id = -1, | ||
729 | .dev = { | ||
730 | .platform_data = &tosa_tc6393xb_setup, | ||
731 | }, | ||
732 | .num_resources = ARRAY_SIZE(tc6393xb_resources), | ||
733 | .resource = tc6393xb_resources, | ||
734 | }; | ||
735 | |||
736 | static struct tosa_bt_data tosa_bt_data = { | ||
737 | .gpio_pwr = TOSA_GPIO_BT_PWR_EN, | ||
738 | .gpio_reset = TOSA_GPIO_BT_RESET, | ||
739 | }; | ||
740 | |||
741 | static struct platform_device tosa_bt_device = { | ||
742 | .name = "tosa-bt", | ||
743 | .id = -1, | ||
744 | .dev.platform_data = &tosa_bt_data, | ||
745 | }; | ||
746 | |||
747 | |||
460 | static struct platform_device *devices[] __initdata = { | 748 | static struct platform_device *devices[] __initdata = { |
461 | &tosascoop_device, | 749 | &tosascoop_device, |
462 | &tosascoop_jc_device, | 750 | &tosascoop_jc_device, |
751 | &tc6393xb_device, | ||
752 | &tosa_power_device, | ||
463 | &tosakbd_device, | 753 | &tosakbd_device, |
464 | &tosa_gpio_keys_device, | 754 | &tosa_gpio_keys_device, |
465 | &tosaled_device, | 755 | &tosaled_device, |
756 | &tosa_bt_device, | ||
466 | }; | 757 | }; |
467 | 758 | ||
468 | static void tosa_poweroff(void) | 759 | static void tosa_poweroff(void) |
469 | { | 760 | { |
470 | gpio_direction_output(TOSA_GPIO_ON_RESET, 0); | 761 | arm_machine_restart('g'); |
471 | gpio_set_value(TOSA_GPIO_ON_RESET, 1); | ||
472 | |||
473 | mdelay(1000); | ||
474 | arm_machine_restart('h'); | ||
475 | } | 762 | } |
476 | 763 | ||
477 | static void tosa_restart(char mode) | 764 | static void tosa_restart(char mode) |
@@ -485,10 +772,15 @@ static void tosa_restart(char mode) | |||
485 | 772 | ||
486 | static void __init tosa_init(void) | 773 | static void __init tosa_init(void) |
487 | { | 774 | { |
775 | int dummy; | ||
776 | |||
488 | pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); | 777 | pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config)); |
778 | pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_irda_off)); | ||
489 | gpio_set_wake(MFP_PIN_GPIO1, 1); | 779 | gpio_set_wake(MFP_PIN_GPIO1, 1); |
490 | /* We can't pass to gpio-keys since it will drop the Reset altfunc */ | 780 | /* We can't pass to gpio-keys since it will drop the Reset altfunc */ |
491 | 781 | ||
782 | init_gpio_reset(TOSA_GPIO_ON_RESET); | ||
783 | |||
492 | pm_power_off = tosa_poweroff; | 784 | pm_power_off = tosa_poweroff; |
493 | arm_pm_restart = tosa_restart; | 785 | arm_pm_restart = tosa_restart; |
494 | 786 | ||
@@ -497,6 +789,10 @@ static void __init tosa_init(void) | |||
497 | /* enable batt_fault */ | 789 | /* enable batt_fault */ |
498 | PMCR = 0x01; | 790 | PMCR = 0x01; |
499 | 791 | ||
792 | dummy = gpiochip_reserve(TOSA_SCOOP_GPIO_BASE, 12); | ||
793 | dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12); | ||
794 | dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16); | ||
795 | |||
500 | pxa_set_mci_info(&tosa_mci_platform_data); | 796 | pxa_set_mci_info(&tosa_mci_platform_data); |
501 | pxa_set_udc_info(&udc_info); | 797 | pxa_set_udc_info(&udc_info); |
502 | pxa_set_ficp_info(&tosa_ficp_platform_data); | 798 | pxa_set_ficp_info(&tosa_ficp_platform_data); |