diff options
author | Tony Lindgren <tony@atomide.com> | 2009-05-28 16:23:52 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2009-05-28 16:23:52 -0400 |
commit | 1a48e1575188d4023b3428b623caeefe8c599e79 (patch) | |
tree | 50bdac2821ab3c9f769c204cd15bc303f08d6670 /arch/arm/mach-omap2/board-rx51-peripherals.c | |
parent | aa62e90fe0700c037675926fff9f75b0b1c00d78 (diff) |
ARM: OMAP2/3: Add generic smc91x support when connected to GPMC
Convert the board-rx51 smc91x code to be generic and make
the boards to use it. This allows future recalculation of the
timings when the source clock gets scaled.
Also correct the rx51 interrupt to be IORESOURCE_IRQ_HIGHLEVEL.
Thanks to Paul Walmsley <paul@pwsan.com> for better GPMC timing
calculations.
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/board-rx51-peripherals.c')
-rw-r--r-- | arch/arm/mach-omap2/board-rx51-peripherals.c | 146 |
1 files changed, 29 insertions, 117 deletions
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index ca18ae94185a..233c7454d84f 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
@@ -28,31 +28,10 @@ | |||
28 | #include <mach/gpmc.h> | 28 | #include <mach/gpmc.h> |
29 | #include <mach/keypad.h> | 29 | #include <mach/keypad.h> |
30 | #include <mach/onenand.h> | 30 | #include <mach/onenand.h> |
31 | #include <mach/gpmc-smc91x.h> | ||
31 | 32 | ||
32 | #include "mmc-twl4030.h" | 33 | #include "mmc-twl4030.h" |
33 | 34 | ||
34 | |||
35 | #define SMC91X_CS 1 | ||
36 | #define SMC91X_GPIO_IRQ 54 | ||
37 | #define SMC91X_GPIO_RESET 164 | ||
38 | #define SMC91X_GPIO_PWRDWN 86 | ||
39 | |||
40 | static struct resource rx51_smc91x_resources[] = { | ||
41 | [0] = { | ||
42 | .flags = IORESOURCE_MEM, | ||
43 | }, | ||
44 | [1] = { | ||
45 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | static struct platform_device rx51_smc91x_device = { | ||
50 | .name = "smc91x", | ||
51 | .id = -1, | ||
52 | .num_resources = ARRAY_SIZE(rx51_smc91x_resources), | ||
53 | .resource = rx51_smc91x_resources, | ||
54 | }; | ||
55 | |||
56 | static int rx51_keymap[] = { | 35 | static int rx51_keymap[] = { |
57 | KEY(0, 0, KEY_Q), | 36 | KEY(0, 0, KEY_Q), |
58 | KEY(0, 1, KEY_W), | 37 | KEY(0, 1, KEY_W), |
@@ -108,98 +87,6 @@ static struct twl4030_keypad_data rx51_kp_data = { | |||
108 | .rep = 1, | 87 | .rep = 1, |
109 | }; | 88 | }; |
110 | 89 | ||
111 | static struct platform_device *rx51_peripherals_devices[] = { | ||
112 | &rx51_smc91x_device, | ||
113 | }; | ||
114 | |||
115 | /* | ||
116 | * Timings are taken from smsc-lan91c96-ms.pdf | ||
117 | */ | ||
118 | static int smc91x_init_gpmc(int cs) | ||
119 | { | ||
120 | struct gpmc_timings t; | ||
121 | const int t2_r = 45; /* t2 in Figure 12.10 */ | ||
122 | const int t2_w = 30; /* t2 in Figure 12.11 */ | ||
123 | const int t3 = 15; /* t3 in Figure 12.10 */ | ||
124 | const int t5_r = 0; /* t5 in Figure 12.10 */ | ||
125 | const int t6_r = 45; /* t6 in Figure 12.10 */ | ||
126 | const int t6_w = 0; /* t6 in Figure 12.11 */ | ||
127 | const int t7_w = 15; /* t7 in Figure 12.11 */ | ||
128 | const int t15 = 12; /* t15 in Figure 12.2 */ | ||
129 | const int t20 = 185; /* t20 in Figure 12.2 */ | ||
130 | |||
131 | memset(&t, 0, sizeof(t)); | ||
132 | |||
133 | t.cs_on = t15; | ||
134 | t.cs_rd_off = t3 + t2_r + t5_r; /* Figure 12.10 */ | ||
135 | t.cs_wr_off = t3 + t2_w + t6_w; /* Figure 12.11 */ | ||
136 | t.adv_on = t3; /* Figure 12.10 */ | ||
137 | t.adv_rd_off = t3 + t2_r; /* Figure 12.10 */ | ||
138 | t.adv_wr_off = t3 + t2_w; /* Figure 12.11 */ | ||
139 | t.oe_off = t3 + t2_r + t5_r; /* Figure 12.10 */ | ||
140 | t.oe_on = t.oe_off - t6_r; /* Figure 12.10 */ | ||
141 | t.we_off = t3 + t2_w + t6_w; /* Figure 12.11 */ | ||
142 | t.we_on = t.we_off - t7_w; /* Figure 12.11 */ | ||
143 | t.rd_cycle = t20; /* Figure 12.2 */ | ||
144 | t.wr_cycle = t20; /* Figure 12.4 */ | ||
145 | t.access = t3 + t2_r + t5_r; /* Figure 12.10 */ | ||
146 | t.wr_access = t3 + t2_w + t6_w; /* Figure 12.11 */ | ||
147 | |||
148 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, GPMC_CONFIG1_DEVICESIZE_16); | ||
149 | |||
150 | return gpmc_cs_set_timings(cs, &t); | ||
151 | } | ||
152 | |||
153 | static void __init rx51_init_smc91x(void) | ||
154 | { | ||
155 | unsigned long cs_mem_base; | ||
156 | int ret; | ||
157 | |||
158 | omap_cfg_reg(U8_34XX_GPIO54_DOWN); | ||
159 | omap_cfg_reg(G25_34XX_GPIO86_OUT); | ||
160 | omap_cfg_reg(H19_34XX_GPIO164_OUT); | ||
161 | |||
162 | if (gpmc_cs_request(SMC91X_CS, SZ_16M, &cs_mem_base) < 0) { | ||
163 | printk(KERN_ERR "Failed to request GPMC mem for smc91x\n"); | ||
164 | return; | ||
165 | } | ||
166 | |||
167 | rx51_smc91x_resources[0].start = cs_mem_base + 0x300; | ||
168 | rx51_smc91x_resources[0].end = cs_mem_base + 0x30f; | ||
169 | |||
170 | smc91x_init_gpmc(SMC91X_CS); | ||
171 | |||
172 | if (gpio_request(SMC91X_GPIO_IRQ, "SMC91X irq") < 0) | ||
173 | goto free1; | ||
174 | |||
175 | gpio_direction_input(SMC91X_GPIO_IRQ); | ||
176 | rx51_smc91x_resources[1].start = gpio_to_irq(SMC91X_GPIO_IRQ); | ||
177 | |||
178 | ret = gpio_request(SMC91X_GPIO_PWRDWN, "SMC91X powerdown"); | ||
179 | if (ret) | ||
180 | goto free2; | ||
181 | gpio_direction_output(SMC91X_GPIO_PWRDWN, 0); | ||
182 | |||
183 | ret = gpio_request(SMC91X_GPIO_RESET, "SMC91X reset"); | ||
184 | if (ret) | ||
185 | goto free3; | ||
186 | gpio_direction_output(SMC91X_GPIO_RESET, 0); | ||
187 | gpio_set_value(SMC91X_GPIO_RESET, 1); | ||
188 | msleep(100); | ||
189 | gpio_set_value(SMC91X_GPIO_RESET, 0); | ||
190 | |||
191 | return; | ||
192 | |||
193 | free3: | ||
194 | gpio_free(SMC91X_GPIO_PWRDWN); | ||
195 | free2: | ||
196 | gpio_free(SMC91X_GPIO_IRQ); | ||
197 | free1: | ||
198 | gpmc_cs_free(SMC91X_CS); | ||
199 | |||
200 | printk(KERN_ERR "Could not initialize smc91x\n"); | ||
201 | } | ||
202 | |||
203 | static struct twl4030_madc_platform_data rx51_madc_data = { | 90 | static struct twl4030_madc_platform_data rx51_madc_data = { |
204 | .irq_line = 1, | 91 | .irq_line = 1, |
205 | }; | 92 | }; |
@@ -466,12 +353,37 @@ static inline void board_onenand_init(void) | |||
466 | 353 | ||
467 | #endif | 354 | #endif |
468 | 355 | ||
356 | #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) | ||
357 | |||
358 | static struct omap_smc91x_platform_data board_smc91x_data = { | ||
359 | .cs = 1, | ||
360 | .gpio_irq = 54, | ||
361 | .gpio_pwrdwn = 86, | ||
362 | .gpio_reset = 164, | ||
363 | .flags = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHLEVEL, | ||
364 | }; | ||
365 | |||
366 | static void __init board_smc91x_init(void) | ||
367 | { | ||
368 | omap_cfg_reg(U8_34XX_GPIO54_DOWN); | ||
369 | omap_cfg_reg(G25_34XX_GPIO86_OUT); | ||
370 | omap_cfg_reg(H19_34XX_GPIO164_OUT); | ||
371 | |||
372 | gpmc_smc91x_init(&board_smc91x_data); | ||
373 | } | ||
374 | |||
375 | #else | ||
376 | |||
377 | static inline void board_smc91x_init(void) | ||
378 | { | ||
379 | } | ||
380 | |||
381 | #endif | ||
382 | |||
469 | void __init rx51_peripherals_init(void) | 383 | void __init rx51_peripherals_init(void) |
470 | { | 384 | { |
471 | platform_add_devices(rx51_peripherals_devices, | ||
472 | ARRAY_SIZE(rx51_peripherals_devices)); | ||
473 | rx51_i2c_init(); | 385 | rx51_i2c_init(); |
474 | rx51_init_smc91x(); | ||
475 | board_onenand_init(); | 386 | board_onenand_init(); |
387 | board_smc91x_init(); | ||
476 | } | 388 | } |
477 | 389 | ||