Commit | Line | Data |
---|---|---|
102c91d8 APR |
1 | /* |
2 | * Copyright (C) Arnaud Patard <arnaud.patard@rtp-net.org> | |
3 | * | |
4 | * based on code from the following | |
5 | * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved. | |
6 | * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved. | |
7 | * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved. | |
8 | * | |
9 | * The code contained herein is licensed under the GNU General Public | |
10 | * License. You may obtain a copy of the GNU General Public License | |
11 | * Version 2 or later at the following locations: | |
12 | * | |
13 | * http://www.opensource.org/licenses/gpl-license.html | |
14 | * http://www.gnu.org/copyleft/gpl.html | |
15 | */ | |
16 | ||
17 | #include <linux/init.h> | |
18 | #include <linux/platform_device.h> | |
19 | #include <linux/i2c.h> | |
20 | #include <linux/gpio.h> | |
21 | #include <linux/leds.h> | |
22 | #include <linux/input.h> | |
23 | #include <linux/delay.h> | |
24 | #include <linux/io.h> | |
102c91d8 APR |
25 | #include <linux/spi/flash.h> |
26 | #include <linux/spi/spi.h> | |
27 | #include <linux/mfd/mc13892.h> | |
28 | #include <linux/regulator/machine.h> | |
29 | #include <linux/regulator/consumer.h> | |
30 | #include <linux/usb/otg.h> | |
31 | #include <linux/usb/ulpi.h> | |
32 | #include <mach/ulpi.h> | |
33 | ||
34 | #include <mach/common.h> | |
35 | #include <mach/hardware.h> | |
36 | #include <mach/iomux-mx51.h> | |
102c91d8 APR |
37 | |
38 | #include <asm/irq.h> | |
39 | #include <asm/setup.h> | |
40 | #include <asm/mach-types.h> | |
41 | #include <asm/mach/arch.h> | |
42 | #include <asm/mach/time.h> | |
43 | ||
44 | #include "devices-imx51.h" | |
45 | #include "devices.h" | |
46 | #include "efika.h" | |
47 | ||
48 | #define EFIKASB_USBH2_STP IMX_GPIO_NR(2, 20) | |
49 | #define EFIKASB_GREEN_LED IMX_GPIO_NR(1, 3) | |
50 | #define EFIKASB_WHITE_LED IMX_GPIO_NR(2, 25) | |
51 | #define EFIKASB_PCBID0 IMX_GPIO_NR(2, 28) | |
52 | #define EFIKASB_PCBID1 IMX_GPIO_NR(2, 29) | |
53 | #define EFIKASB_PWRKEY IMX_GPIO_NR(2, 31) | |
54 | #define EFIKASB_LID IMX_GPIO_NR(3, 14) | |
55 | #define EFIKASB_POWEROFF IMX_GPIO_NR(4, 13) | |
56 | #define EFIKASB_RFKILL IMX_GPIO_NR(3, 1) | |
57 | ||
58 | #define MX51_PAD_PWRKEY IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, PAD_CTL_PUS_100K_UP | PAD_CTL_PKE) | |
59 | ||
60 | static iomux_v3_cfg_t mx51efikasb_pads[] = { | |
61 | /* USB HOST2 */ | |
62 | MX51_PAD_EIM_D16__USBH2_DATA0, | |
63 | MX51_PAD_EIM_D17__USBH2_DATA1, | |
64 | MX51_PAD_EIM_D18__USBH2_DATA2, | |
65 | MX51_PAD_EIM_D19__USBH2_DATA3, | |
66 | MX51_PAD_EIM_D20__USBH2_DATA4, | |
67 | MX51_PAD_EIM_D21__USBH2_DATA5, | |
68 | MX51_PAD_EIM_D22__USBH2_DATA6, | |
69 | MX51_PAD_EIM_D23__USBH2_DATA7, | |
70 | MX51_PAD_EIM_A24__USBH2_CLK, | |
71 | MX51_PAD_EIM_A25__USBH2_DIR, | |
72 | MX51_PAD_EIM_A26__USBH2_STP, | |
73 | MX51_PAD_EIM_A27__USBH2_NXT, | |
74 | ||
75 | /* leds */ | |
76 | MX51_PAD_EIM_CS0__GPIO2_25, | |
77 | MX51_PAD_GPIO1_3__GPIO1_3, | |
78 | ||
79 | /* pcb id */ | |
80 | MX51_PAD_EIM_CS3__GPIO2_28, | |
81 | MX51_PAD_EIM_CS4__GPIO2_29, | |
82 | ||
83 | /* lid */ | |
84 | MX51_PAD_CSI1_VSYNC__GPIO3_14, | |
85 | ||
86 | /* power key*/ | |
87 | MX51_PAD_PWRKEY, | |
88 | ||
89 | /* wifi/bt button */ | |
90 | MX51_PAD_DI1_PIN12__GPIO3_1, | |
91 | ||
92 | /* power off */ | |
93 | MX51_PAD_CSI2_VSYNC__GPIO4_13, | |
94 | ||
95 | /* wdog reset */ | |
96 | MX51_PAD_GPIO1_4__WDOG1_WDOG_B, | |
97 | ||
98 | /* BT */ | |
99 | MX51_PAD_EIM_A17__GPIO2_11, | |
100 | }; | |
101 | ||
102 | static int initialize_usbh2_port(struct platform_device *pdev) | |
103 | { | |
104 | iomux_v3_cfg_t usbh2stp = MX51_PAD_EIM_A26__USBH2_STP; | |
105 | iomux_v3_cfg_t usbh2gpio = MX51_PAD_EIM_A26__GPIO2_20; | |
106 | ||
107 | mxc_iomux_v3_setup_pad(usbh2gpio); | |
108 | gpio_request(EFIKASB_USBH2_STP, "usbh2_stp"); | |
109 | gpio_direction_output(EFIKASB_USBH2_STP, 0); | |
110 | msleep(1); | |
111 | gpio_set_value(EFIKASB_USBH2_STP, 1); | |
112 | msleep(1); | |
113 | ||
114 | gpio_free(EFIKASB_USBH2_STP); | |
115 | mxc_iomux_v3_setup_pad(usbh2stp); | |
116 | ||
117 | mdelay(10); | |
118 | ||
119 | return mx51_initialize_usb_hw(pdev->id, MXC_EHCI_ITC_NO_THRESHOLD); | |
120 | } | |
121 | ||
122 | static struct mxc_usbh_platform_data usbh2_config = { | |
123 | .init = initialize_usbh2_port, | |
124 | .portsc = MXC_EHCI_MODE_ULPI, | |
125 | }; | |
126 | ||
127 | static void __init mx51_efikasb_usb(void) | |
128 | { | |
48f6b099 SH |
129 | usbh2_config.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS | |
130 | ULPI_OTG_DRVVBUS_EXT | ULPI_OTG_EXTVBUSIND); | |
131 | if (usbh2_config.otg) | |
132 | mxc_register_device(&mxc_usbh2_device, &usbh2_config); | |
102c91d8 APR |
133 | } |
134 | ||
135 | static struct gpio_led mx51_efikasb_leds[] = { | |
136 | { | |
137 | .name = "efikasb:green", | |
138 | .default_trigger = "default-on", | |
139 | .gpio = EFIKASB_GREEN_LED, | |
140 | .active_low = 1, | |
141 | }, | |
142 | { | |
143 | .name = "efikasb:white", | |
144 | .default_trigger = "caps", | |
145 | .gpio = EFIKASB_WHITE_LED, | |
146 | }, | |
147 | }; | |
148 | ||
149 | static struct gpio_led_platform_data mx51_efikasb_leds_data = { | |
150 | .leds = mx51_efikasb_leds, | |
151 | .num_leds = ARRAY_SIZE(mx51_efikasb_leds), | |
152 | }; | |
153 | ||
154 | static struct platform_device mx51_efikasb_leds_device = { | |
155 | .name = "leds-gpio", | |
156 | .id = -1, | |
157 | .dev = { | |
158 | .platform_data = &mx51_efikasb_leds_data, | |
159 | }, | |
160 | }; | |
161 | ||
162 | static struct gpio_keys_button mx51_efikasb_keys[] = { | |
163 | { | |
164 | .code = KEY_POWER, | |
165 | .gpio = EFIKASB_PWRKEY, | |
166 | .type = EV_PWR, | |
167 | .desc = "Power Button", | |
168 | .wakeup = 1, | |
169 | .debounce_interval = 10, /* ms */ | |
170 | }, | |
171 | { | |
172 | .code = SW_LID, | |
173 | .gpio = EFIKASB_LID, | |
174 | .type = EV_SW, | |
175 | .desc = "Lid Switch", | |
176 | }, | |
177 | { | |
178 | /* SW_RFKILLALL vs KEY_RFKILL ? */ | |
179 | .code = SW_RFKILL_ALL, | |
180 | .gpio = EFIKASB_RFKILL, | |
181 | .type = EV_SW, | |
182 | .desc = "rfkill", | |
183 | }, | |
184 | }; | |
185 | ||
186 | static const struct gpio_keys_platform_data mx51_efikasb_keys_data __initconst = { | |
187 | .buttons = mx51_efikasb_keys, | |
188 | .nbuttons = ARRAY_SIZE(mx51_efikasb_keys), | |
189 | }; | |
190 | ||
191 | static struct regulator *pwgt1, *pwgt2; | |
192 | ||
193 | static void mx51_efikasb_power_off(void) | |
194 | { | |
195 | gpio_set_value(EFIKA_USB_PHY_RESET, 0); | |
196 | ||
197 | if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) { | |
198 | regulator_disable(pwgt2); | |
199 | regulator_disable(pwgt1); | |
200 | } | |
201 | gpio_direction_output(EFIKASB_POWEROFF, 1); | |
202 | } | |
203 | ||
204 | static int __init mx51_efikasb_power_init(void) | |
205 | { | |
206 | if (machine_is_mx51_efikasb()) { | |
207 | pwgt1 = regulator_get(NULL, "pwgt1"); | |
208 | pwgt2 = regulator_get(NULL, "pwgt2"); | |
209 | if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) { | |
210 | regulator_enable(pwgt1); | |
211 | regulator_enable(pwgt2); | |
212 | } | |
213 | gpio_request(EFIKASB_POWEROFF, "poweroff"); | |
214 | pm_power_off = mx51_efikasb_power_off; | |
215 | ||
216 | regulator_has_full_constraints(); | |
217 | } | |
218 | ||
219 | return 0; | |
220 | } | |
221 | late_initcall(mx51_efikasb_power_init); | |
222 | ||
223 | /* 01 R1.3 board | |
224 | 10 R2.0 board */ | |
225 | static void __init mx51_efikasb_board_id(void) | |
226 | { | |
227 | int id; | |
228 | ||
229 | gpio_request(EFIKASB_PCBID0, "pcb id0"); | |
230 | gpio_direction_input(EFIKASB_PCBID0); | |
231 | gpio_request(EFIKASB_PCBID1, "pcb id1"); | |
232 | gpio_direction_input(EFIKASB_PCBID1); | |
233 | ||
234 | id = gpio_get_value(EFIKASB_PCBID0); | |
235 | id |= gpio_get_value(EFIKASB_PCBID1) << 1; | |
236 | ||
237 | switch (id) { | |
238 | default: | |
239 | break; | |
240 | case 1: | |
241 | system_rev = 0x13; | |
242 | break; | |
243 | case 2: | |
244 | system_rev = 0x20; | |
245 | break; | |
246 | } | |
247 | } | |
248 | ||
249 | static void __init efikasb_board_init(void) | |
250 | { | |
251 | mxc_iomux_v3_setup_multiple_pads(mx51efikasb_pads, | |
252 | ARRAY_SIZE(mx51efikasb_pads)); | |
253 | efika_board_common_init(); | |
254 | ||
255 | mx51_efikasb_board_id(); | |
256 | mx51_efikasb_usb(); | |
257 | imx51_add_sdhci_esdhc_imx(1, NULL); | |
258 | ||
259 | platform_device_register(&mx51_efikasb_leds_device); | |
ba8a6c04 | 260 | imx_add_gpio_keys(&mx51_efikasb_keys_data); |
102c91d8 APR |
261 | |
262 | } | |
263 | ||
264 | static void __init mx51_efikasb_timer_init(void) | |
265 | { | |
266 | mx51_clocks_init(32768, 24000000, 22579200, 24576000); | |
267 | } | |
268 | ||
269 | static struct sys_timer mx51_efikasb_timer = { | |
270 | .init = mx51_efikasb_timer_init, | |
271 | }; | |
272 | ||
273 | MACHINE_START(MX51_EFIKASB, "Genesi Efika Smartbook") | |
274 | .boot_params = MX51_PHYS_OFFSET + 0x100, | |
275 | .map_io = mx51_map_io, | |
276 | .init_early = imx51_init_early, | |
277 | .init_irq = mx51_init_irq, | |
278 | .init_machine = efikasb_board_init, | |
279 | .timer = &mx51_efikasb_timer, | |
280 | MACHINE_END |