1
2
3
4
5
6
7
8
9
10
11
12#include <linux/kernel.h>
13#include <linux/platform_device.h>
14#include <linux/gpio.h>
15#include <linux/delay.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18#include <linux/smc91x.h>
19
20#include <mach/board.h>
21#include <mach/gpmc.h>
22#include <mach/gpmc-smc91x.h>
23
24static struct omap_smc91x_platform_data *gpmc_cfg;
25
26static struct resource gpmc_smc91x_resources[] = {
27 [0] = {
28 .flags = IORESOURCE_MEM,
29 },
30 [1] = {
31 .flags = IORESOURCE_IRQ,
32 },
33};
34
35static struct smc91x_platdata gpmc_smc91x_info = {
36 .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_0,
37};
38
39static struct platform_device gpmc_smc91x_device = {
40 .name = "smc91x",
41 .id = -1,
42 .num_resources = ARRAY_SIZE(gpmc_smc91x_resources),
43 .resource = gpmc_smc91x_resources,
44 .dev = {
45 .platform_data = &gpmc_smc91x_info,
46 },
47};
48
49
50
51
52
53
54
55static int smc91c96_gpmc_retime(void)
56{
57 struct gpmc_timings t;
58 const int t3 = 10;
59 const int t4_r = 20;
60 const int t4_w = 5;
61 const int t5 = 25;
62 const int t6 = 15;
63 const int t7 = 5;
64 const int t8 = 5;
65 const int t20 = 185;
66 u32 l;
67
68 memset(&t, 0, sizeof(t));
69
70
71 t.cs_on = 0;
72 t.adv_on = t.cs_on;
73 t.oe_on = t.adv_on + t3;
74 t.access = t.oe_on + t5;
75 t.oe_off = t.access;
76 t.adv_rd_off = t.oe_off + max(t4_r, t6);
77 t.cs_rd_off = t.oe_off;
78 t.rd_cycle = t20 - t.oe_on;
79
80
81 t.we_on = t.adv_on + t3;
82
83 if (cpu_is_omap34xx() && (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)) {
84 t.wr_data_mux_bus = t.we_on;
85 t.we_off = t.wr_data_mux_bus + t7;
86 } else
87 t.we_off = t.we_on + t7;
88 if (cpu_is_omap34xx())
89 t.wr_access = t.we_off;
90 t.adv_wr_off = t.we_off + max(t4_w, t8);
91 t.cs_wr_off = t.we_off + t4_w;
92 t.wr_cycle = t20 - t.we_on;
93
94 l = GPMC_CONFIG1_DEVICESIZE_16;
95 if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
96 l |= GPMC_CONFIG1_MUXADDDATA;
97 if (gpmc_cfg->flags & GPMC_READ_MON)
98 l |= GPMC_CONFIG1_WAIT_READ_MON;
99 if (gpmc_cfg->flags & GPMC_WRITE_MON)
100 l |= GPMC_CONFIG1_WAIT_WRITE_MON;
101 if (gpmc_cfg->wait_pin)
102 l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg->wait_pin);
103 gpmc_cs_write_reg(gpmc_cfg->cs, GPMC_CS_CONFIG1, l);
104
105
106
107
108
109
110
111
112 if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
113 return 0;
114
115 return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
116}
117
118
119
120
121
122
123void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data)
124{
125 unsigned long cs_mem_base;
126 int ret;
127
128 gpmc_cfg = board_data;
129
130 if (gpmc_cfg->flags & GPMC_TIMINGS_SMC91C96)
131 gpmc_cfg->retime = smc91c96_gpmc_retime;
132
133 if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
134 printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
135 return;
136 }
137
138 gpmc_smc91x_resources[0].start = cs_mem_base + 0x300;
139 gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f;
140 gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK);
141
142 if (gpmc_cfg->retime) {
143 ret = gpmc_cfg->retime();
144 if (ret != 0)
145 goto free1;
146 }
147
148 if (gpio_request(gpmc_cfg->gpio_irq, "SMC91X irq") < 0)
149 goto free1;
150
151 gpio_direction_input(gpmc_cfg->gpio_irq);
152 gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
153
154 if (gpmc_cfg->gpio_pwrdwn) {
155 ret = gpio_request(gpmc_cfg->gpio_pwrdwn, "SMC91X powerdown");
156 if (ret)
157 goto free2;
158 gpio_direction_output(gpmc_cfg->gpio_pwrdwn, 0);
159 }
160
161 if (gpmc_cfg->gpio_reset) {
162 ret = gpio_request(gpmc_cfg->gpio_reset, "SMC91X reset");
163 if (ret)
164 goto free3;
165
166 gpio_direction_output(gpmc_cfg->gpio_reset, 0);
167 gpio_set_value(gpmc_cfg->gpio_reset, 1);
168 msleep(100);
169 gpio_set_value(gpmc_cfg->gpio_reset, 0);
170 }
171
172 if (platform_device_register(&gpmc_smc91x_device) < 0) {
173 printk(KERN_ERR "Unable to register smc91x device\n");
174 gpio_free(gpmc_cfg->gpio_reset);
175 goto free3;
176 }
177
178 return;
179
180free3:
181 if (gpmc_cfg->gpio_pwrdwn)
182 gpio_free(gpmc_cfg->gpio_pwrdwn);
183free2:
184 gpio_free(gpmc_cfg->gpio_irq);
185free1:
186 gpmc_cs_free(gpmc_cfg->cs);
187
188 printk(KERN_ERR "Could not initialize smc91x\n");
189}
190