diff options
Diffstat (limited to 'arch/arm/mach-omap2/board-rx51-peripherals.c')
-rw-r--r-- | arch/arm/mach-omap2/board-rx51-peripherals.c | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c new file mode 100644 index 000000000000..a7381729645c --- /dev/null +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
@@ -0,0 +1,419 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/board-rx51-flash.c | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Nokia | ||
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 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/input.h> | ||
15 | #include <linux/spi/spi.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/i2c/twl4030.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/regulator/machine.h> | ||
21 | #include <linux/gpio.h> | ||
22 | |||
23 | #include <mach/mcspi.h> | ||
24 | #include <mach/mux.h> | ||
25 | #include <mach/board.h> | ||
26 | #include <mach/common.h> | ||
27 | #include <mach/dma.h> | ||
28 | #include <mach/gpmc.h> | ||
29 | #include <mach/keypad.h> | ||
30 | |||
31 | #include "mmc-twl4030.h" | ||
32 | |||
33 | |||
34 | #define SMC91X_CS 1 | ||
35 | #define SMC91X_GPIO_IRQ 54 | ||
36 | #define SMC91X_GPIO_RESET 164 | ||
37 | #define SMC91X_GPIO_PWRDWN 86 | ||
38 | |||
39 | static struct resource rx51_smc91x_resources[] = { | ||
40 | [0] = { | ||
41 | .flags = IORESOURCE_MEM, | ||
42 | }, | ||
43 | [1] = { | ||
44 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | ||
45 | }, | ||
46 | }; | ||
47 | |||
48 | static struct platform_device rx51_smc91x_device = { | ||
49 | .name = "smc91x", | ||
50 | .id = -1, | ||
51 | .num_resources = ARRAY_SIZE(rx51_smc91x_resources), | ||
52 | .resource = rx51_smc91x_resources, | ||
53 | }; | ||
54 | |||
55 | static int rx51_keymap[] = { | ||
56 | KEY(0, 0, KEY_Q), | ||
57 | KEY(0, 1, KEY_W), | ||
58 | KEY(0, 2, KEY_E), | ||
59 | KEY(0, 3, KEY_R), | ||
60 | KEY(0, 4, KEY_T), | ||
61 | KEY(0, 5, KEY_Y), | ||
62 | KEY(0, 6, KEY_U), | ||
63 | KEY(0, 7, KEY_I), | ||
64 | KEY(1, 0, KEY_O), | ||
65 | KEY(1, 1, KEY_D), | ||
66 | KEY(1, 2, KEY_DOT), | ||
67 | KEY(1, 3, KEY_V), | ||
68 | KEY(1, 4, KEY_DOWN), | ||
69 | KEY(2, 0, KEY_P), | ||
70 | KEY(2, 1, KEY_F), | ||
71 | KEY(2, 2, KEY_UP), | ||
72 | KEY(2, 3, KEY_B), | ||
73 | KEY(2, 4, KEY_RIGHT), | ||
74 | KEY(3, 0, KEY_COMMA), | ||
75 | KEY(3, 1, KEY_G), | ||
76 | KEY(3, 2, KEY_ENTER), | ||
77 | KEY(3, 3, KEY_N), | ||
78 | KEY(4, 0, KEY_BACKSPACE), | ||
79 | KEY(4, 1, KEY_H), | ||
80 | KEY(4, 3, KEY_M), | ||
81 | KEY(4, 4, KEY_LEFTCTRL), | ||
82 | KEY(5, 1, KEY_J), | ||
83 | KEY(5, 2, KEY_Z), | ||
84 | KEY(5, 3, KEY_SPACE), | ||
85 | KEY(5, 4, KEY_LEFTSHIFT), | ||
86 | KEY(6, 0, KEY_A), | ||
87 | KEY(6, 1, KEY_K), | ||
88 | KEY(6, 2, KEY_X), | ||
89 | KEY(6, 3, KEY_SPACE), | ||
90 | KEY(6, 4, KEY_FN), | ||
91 | KEY(7, 0, KEY_S), | ||
92 | KEY(7, 1, KEY_L), | ||
93 | KEY(7, 2, KEY_C), | ||
94 | KEY(7, 3, KEY_LEFT), | ||
95 | KEY(0xff, 0, KEY_F6), | ||
96 | KEY(0xff, 1, KEY_F7), | ||
97 | KEY(0xff, 2, KEY_F8), | ||
98 | KEY(0xff, 4, KEY_F9), | ||
99 | KEY(0xff, 5, KEY_F10), | ||
100 | }; | ||
101 | |||
102 | static struct twl4030_keypad_data rx51_kp_data = { | ||
103 | .rows = 8, | ||
104 | .cols = 8, | ||
105 | .keymap = rx51_keymap, | ||
106 | .keymapsize = ARRAY_SIZE(rx51_keymap), | ||
107 | .rep = 1, | ||
108 | }; | ||
109 | |||
110 | static struct platform_device *rx51_peripherals_devices[] = { | ||
111 | &rx51_smc91x_device, | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * Timings are taken from smsc-lan91c96-ms.pdf | ||
116 | */ | ||
117 | static int smc91x_init_gpmc(int cs) | ||
118 | { | ||
119 | struct gpmc_timings t; | ||
120 | const int t2_r = 45; /* t2 in Figure 12.10 */ | ||
121 | const int t2_w = 30; /* t2 in Figure 12.11 */ | ||
122 | const int t3 = 15; /* t3 in Figure 12.10 */ | ||
123 | const int t5_r = 0; /* t5 in Figure 12.10 */ | ||
124 | const int t6_r = 45; /* t6 in Figure 12.10 */ | ||
125 | const int t6_w = 0; /* t6 in Figure 12.11 */ | ||
126 | const int t7_w = 15; /* t7 in Figure 12.11 */ | ||
127 | const int t15 = 12; /* t15 in Figure 12.2 */ | ||
128 | const int t20 = 185; /* t20 in Figure 12.2 */ | ||
129 | |||
130 | memset(&t, 0, sizeof(t)); | ||
131 | |||
132 | t.cs_on = t15; | ||
133 | t.cs_rd_off = t3 + t2_r + t5_r; /* Figure 12.10 */ | ||
134 | t.cs_wr_off = t3 + t2_w + t6_w; /* Figure 12.11 */ | ||
135 | t.adv_on = t3; /* Figure 12.10 */ | ||
136 | t.adv_rd_off = t3 + t2_r; /* Figure 12.10 */ | ||
137 | t.adv_wr_off = t3 + t2_w; /* Figure 12.11 */ | ||
138 | t.oe_off = t3 + t2_r + t5_r; /* Figure 12.10 */ | ||
139 | t.oe_on = t.oe_off - t6_r; /* Figure 12.10 */ | ||
140 | t.we_off = t3 + t2_w + t6_w; /* Figure 12.11 */ | ||
141 | t.we_on = t.we_off - t7_w; /* Figure 12.11 */ | ||
142 | t.rd_cycle = t20; /* Figure 12.2 */ | ||
143 | t.wr_cycle = t20; /* Figure 12.4 */ | ||
144 | t.access = t3 + t2_r + t5_r; /* Figure 12.10 */ | ||
145 | t.wr_access = t3 + t2_w + t6_w; /* Figure 12.11 */ | ||
146 | |||
147 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, GPMC_CONFIG1_DEVICESIZE_16); | ||
148 | |||
149 | return gpmc_cs_set_timings(cs, &t); | ||
150 | } | ||
151 | |||
152 | static void __init rx51_init_smc91x(void) | ||
153 | { | ||
154 | unsigned long cs_mem_base; | ||
155 | int ret; | ||
156 | |||
157 | omap_cfg_reg(U8_34XX_GPIO54_DOWN); | ||
158 | omap_cfg_reg(G25_34XX_GPIO86_OUT); | ||
159 | omap_cfg_reg(H19_34XX_GPIO164_OUT); | ||
160 | |||
161 | if (gpmc_cs_request(SMC91X_CS, SZ_16M, &cs_mem_base) < 0) { | ||
162 | printk(KERN_ERR "Failed to request GPMC mem for smc91x\n"); | ||
163 | return; | ||
164 | } | ||
165 | |||
166 | rx51_smc91x_resources[0].start = cs_mem_base + 0x300; | ||
167 | rx51_smc91x_resources[0].end = cs_mem_base + 0x30f; | ||
168 | |||
169 | smc91x_init_gpmc(SMC91X_CS); | ||
170 | |||
171 | if (gpio_request(SMC91X_GPIO_IRQ, "SMC91X irq") < 0) | ||
172 | goto free1; | ||
173 | |||
174 | gpio_direction_input(SMC91X_GPIO_IRQ); | ||
175 | rx51_smc91x_resources[1].start = gpio_to_irq(SMC91X_GPIO_IRQ); | ||
176 | |||
177 | ret = gpio_request(SMC91X_GPIO_PWRDWN, "SMC91X powerdown"); | ||
178 | if (ret) | ||
179 | goto free2; | ||
180 | gpio_direction_output(SMC91X_GPIO_PWRDWN, 0); | ||
181 | |||
182 | ret = gpio_request(SMC91X_GPIO_RESET, "SMC91X reset"); | ||
183 | if (ret) | ||
184 | goto free3; | ||
185 | gpio_direction_output(SMC91X_GPIO_RESET, 0); | ||
186 | gpio_set_value(SMC91X_GPIO_RESET, 1); | ||
187 | msleep(100); | ||
188 | gpio_set_value(SMC91X_GPIO_RESET, 0); | ||
189 | |||
190 | return; | ||
191 | |||
192 | free3: | ||
193 | gpio_free(SMC91X_GPIO_PWRDWN); | ||
194 | free2: | ||
195 | gpio_free(SMC91X_GPIO_IRQ); | ||
196 | free1: | ||
197 | gpmc_cs_free(SMC91X_CS); | ||
198 | |||
199 | printk(KERN_ERR "Could not initialize smc91x\n"); | ||
200 | } | ||
201 | |||
202 | static struct twl4030_madc_platform_data rx51_madc_data = { | ||
203 | .irq_line = 1, | ||
204 | }; | ||
205 | |||
206 | static struct twl4030_hsmmc_info mmc[] = { | ||
207 | { | ||
208 | .name = "external", | ||
209 | .mmc = 1, | ||
210 | .wires = 4, | ||
211 | .cover_only = true, | ||
212 | .gpio_cd = 160, | ||
213 | .gpio_wp = -EINVAL, | ||
214 | }, | ||
215 | { | ||
216 | .name = "internal", | ||
217 | .mmc = 2, | ||
218 | .wires = 8, | ||
219 | .gpio_cd = -EINVAL, | ||
220 | .gpio_wp = -EINVAL, | ||
221 | }, | ||
222 | {} /* Terminator */ | ||
223 | }; | ||
224 | |||
225 | static struct regulator_consumer_supply rx51_vmmc1_supply = { | ||
226 | .supply = "vmmc", | ||
227 | }; | ||
228 | |||
229 | static struct regulator_consumer_supply rx51_vmmc2_supply = { | ||
230 | .supply = "vmmc", | ||
231 | }; | ||
232 | |||
233 | static struct regulator_consumer_supply rx51_vsim_supply = { | ||
234 | .supply = "vmmc_aux", | ||
235 | }; | ||
236 | |||
237 | static struct regulator_init_data rx51_vaux1 = { | ||
238 | .constraints = { | ||
239 | .name = "V28", | ||
240 | .min_uV = 2800000, | ||
241 | .max_uV = 2800000, | ||
242 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
243 | | REGULATOR_MODE_STANDBY, | ||
244 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
245 | | REGULATOR_CHANGE_STATUS, | ||
246 | }, | ||
247 | }; | ||
248 | |||
249 | static struct regulator_init_data rx51_vaux2 = { | ||
250 | .constraints = { | ||
251 | .name = "VCSI", | ||
252 | .min_uV = 1800000, | ||
253 | .max_uV = 1800000, | ||
254 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
255 | | REGULATOR_MODE_STANDBY, | ||
256 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
257 | | REGULATOR_CHANGE_STATUS, | ||
258 | }, | ||
259 | }; | ||
260 | |||
261 | /* VAUX3 - adds more power to VIO_18 rail */ | ||
262 | static struct regulator_init_data rx51_vaux3 = { | ||
263 | .constraints = { | ||
264 | .name = "VCAM_DIG_18", | ||
265 | .min_uV = 1800000, | ||
266 | .max_uV = 1800000, | ||
267 | .apply_uV = true, | ||
268 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
269 | | REGULATOR_MODE_STANDBY, | ||
270 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
271 | | REGULATOR_CHANGE_STATUS, | ||
272 | }, | ||
273 | }; | ||
274 | |||
275 | static struct regulator_init_data rx51_vaux4 = { | ||
276 | .constraints = { | ||
277 | .name = "VCAM_ANA_28", | ||
278 | .min_uV = 2800000, | ||
279 | .max_uV = 2800000, | ||
280 | .apply_uV = true, | ||
281 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
282 | | REGULATOR_MODE_STANDBY, | ||
283 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
284 | | REGULATOR_CHANGE_STATUS, | ||
285 | }, | ||
286 | }; | ||
287 | |||
288 | static struct regulator_init_data rx51_vmmc1 = { | ||
289 | .constraints = { | ||
290 | .min_uV = 1850000, | ||
291 | .max_uV = 3150000, | ||
292 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
293 | | REGULATOR_MODE_STANDBY, | ||
294 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
295 | | REGULATOR_CHANGE_MODE | ||
296 | | REGULATOR_CHANGE_STATUS, | ||
297 | }, | ||
298 | .num_consumer_supplies = 1, | ||
299 | .consumer_supplies = &rx51_vmmc1_supply, | ||
300 | }; | ||
301 | |||
302 | static struct regulator_init_data rx51_vmmc2 = { | ||
303 | .constraints = { | ||
304 | .name = "VMMC2_30", | ||
305 | .min_uV = 1850000, | ||
306 | .max_uV = 3150000, | ||
307 | .apply_uV = true, | ||
308 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
309 | | REGULATOR_MODE_STANDBY, | ||
310 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
311 | | REGULATOR_CHANGE_MODE | ||
312 | | REGULATOR_CHANGE_STATUS, | ||
313 | }, | ||
314 | .num_consumer_supplies = 1, | ||
315 | .consumer_supplies = &rx51_vmmc2_supply, | ||
316 | }; | ||
317 | |||
318 | static struct regulator_init_data rx51_vsim = { | ||
319 | .constraints = { | ||
320 | .name = "VMMC2_IO_18", | ||
321 | .min_uV = 1800000, | ||
322 | .max_uV = 1800000, | ||
323 | .apply_uV = true, | ||
324 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
325 | | REGULATOR_MODE_STANDBY, | ||
326 | .valid_ops_mask = REGULATOR_CHANGE_MODE | ||
327 | | REGULATOR_CHANGE_STATUS, | ||
328 | }, | ||
329 | .num_consumer_supplies = 1, | ||
330 | .consumer_supplies = &rx51_vsim_supply, | ||
331 | }; | ||
332 | |||
333 | static struct regulator_init_data rx51_vdac = { | ||
334 | .constraints = { | ||
335 | .min_uV = 1800000, | ||
336 | .max_uV = 1800000, | ||
337 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
338 | | REGULATOR_MODE_STANDBY, | ||
339 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | ||
340 | | REGULATOR_CHANGE_MODE | ||
341 | | REGULATOR_CHANGE_STATUS, | ||
342 | }, | ||
343 | }; | ||
344 | |||
345 | static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n) | ||
346 | { | ||
347 | /* FIXME this gpio setup is just a placeholder for now */ | ||
348 | gpio_request(gpio + 6, "backlight_pwm"); | ||
349 | gpio_direction_output(gpio + 6, 0); | ||
350 | gpio_request(gpio + 7, "speaker_en"); | ||
351 | gpio_direction_output(gpio + 7, 1); | ||
352 | |||
353 | /* set up MMC adapters, linking their regulators to them */ | ||
354 | twl4030_mmc_init(mmc); | ||
355 | rx51_vmmc1_supply.dev = mmc[0].dev; | ||
356 | rx51_vmmc2_supply.dev = mmc[1].dev; | ||
357 | rx51_vsim_supply.dev = mmc[1].dev; | ||
358 | |||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static struct twl4030_gpio_platform_data rx51_gpio_data = { | ||
363 | .gpio_base = OMAP_MAX_GPIO_LINES, | ||
364 | .irq_base = TWL4030_GPIO_IRQ_BASE, | ||
365 | .irq_end = TWL4030_GPIO_IRQ_END, | ||
366 | .pulldowns = BIT(0) | BIT(1) | BIT(2) | BIT(3) | ||
367 | | BIT(4) | BIT(5) | ||
368 | | BIT(8) | BIT(9) | BIT(10) | BIT(11) | ||
369 | | BIT(12) | BIT(13) | BIT(14) | BIT(15) | ||
370 | | BIT(16) | BIT(17) , | ||
371 | .setup = rx51_twlgpio_setup, | ||
372 | }; | ||
373 | |||
374 | static struct twl4030_platform_data rx51_twldata = { | ||
375 | .irq_base = TWL4030_IRQ_BASE, | ||
376 | .irq_end = TWL4030_IRQ_END, | ||
377 | |||
378 | /* platform_data for children goes here */ | ||
379 | .gpio = &rx51_gpio_data, | ||
380 | .keypad = &rx51_kp_data, | ||
381 | .madc = &rx51_madc_data, | ||
382 | |||
383 | .vaux1 = &rx51_vaux1, | ||
384 | .vaux2 = &rx51_vaux2, | ||
385 | .vaux3 = &rx51_vaux3, | ||
386 | .vaux4 = &rx51_vaux4, | ||
387 | .vmmc1 = &rx51_vmmc1, | ||
388 | .vmmc2 = &rx51_vmmc2, | ||
389 | .vsim = &rx51_vsim, | ||
390 | .vdac = &rx51_vdac, | ||
391 | }; | ||
392 | |||
393 | static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = { | ||
394 | { | ||
395 | I2C_BOARD_INFO("twl5030", 0x48), | ||
396 | .flags = I2C_CLIENT_WAKE, | ||
397 | .irq = INT_34XX_SYS_NIRQ, | ||
398 | .platform_data = &rx51_twldata, | ||
399 | }, | ||
400 | }; | ||
401 | |||
402 | static int __init rx51_i2c_init(void) | ||
403 | { | ||
404 | omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1, | ||
405 | ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); | ||
406 | omap_register_i2c_bus(2, 100, NULL, 0); | ||
407 | omap_register_i2c_bus(3, 400, NULL, 0); | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | |||
412 | void __init rx51_peripherals_init(void) | ||
413 | { | ||
414 | platform_add_devices(rx51_peripherals_devices, | ||
415 | ARRAY_SIZE(rx51_peripherals_devices)); | ||
416 | rx51_i2c_init(); | ||
417 | rx51_init_smc91x(); | ||
418 | } | ||
419 | |||