39
39
struct rb532_gpio_chip {
40
40
struct gpio_chip chip ;
41
41
void __iomem * regbase ;
42
- void (* set_int_level )(struct gpio_chip * chip , unsigned offset , int value );
43
- int (* get_int_level )(struct gpio_chip * chip , unsigned offset );
44
- void (* set_int_status )(struct gpio_chip * chip , unsigned offset , int value );
45
- int (* get_int_status )(struct gpio_chip * chip , unsigned offset );
46
42
};
47
43
48
44
struct mpmc_device dev3 ;
@@ -111,15 +107,47 @@ unsigned char get_latch_u5(void)
111
107
}
112
108
EXPORT_SYMBOL (get_latch_u5 );
113
109
110
+ /* rb532_set_bit - sanely set a bit
111
+ *
112
+ * bitval: new value for the bit
113
+ * offset: bit index in the 4 byte address range
114
+ * ioaddr: 4 byte aligned address being altered
115
+ */
116
+ static inline void rb532_set_bit (unsigned bitval ,
117
+ unsigned offset , void __iomem * ioaddr )
118
+ {
119
+ unsigned long flags ;
120
+ u32 val ;
121
+
122
+ bitval = !!bitval ; /* map parameter to {0,1} */
123
+
124
+ local_irq_save (flags );
125
+
126
+ val = readl (ioaddr );
127
+ val &= ~( ~bitval << offset ); /* unset bit if bitval == 0 */
128
+ val |= ( bitval << offset ); /* set bit if bitval == 1 */
129
+ writel (val , ioaddr );
130
+
131
+ local_irq_restore (flags );
132
+ }
133
+
134
+ /* rb532_get_bit - read a bit
135
+ *
136
+ * returns the boolean state of the bit, which may be > 1
137
+ */
138
+ static inline int rb532_get_bit (unsigned offset , void __iomem * ioaddr )
139
+ {
140
+ return (readl (ioaddr ) & (1 << offset ));
141
+ }
142
+
114
143
/*
115
144
* Return GPIO level */
116
145
static int rb532_gpio_get (struct gpio_chip * chip , unsigned offset )
117
146
{
118
- u32 mask = 1 << offset ;
119
147
struct rb532_gpio_chip * gpch ;
120
148
121
149
gpch = container_of (chip , struct rb532_gpio_chip , chip );
122
- return readl ( gpch -> regbase + GPIOD ) & mask ;
150
+ return rb532_get_bit ( offset , gpch -> regbase + GPIOD );
123
151
}
124
152
125
153
/*
@@ -128,45 +156,25 @@ static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset)
128
156
static void rb532_gpio_set (struct gpio_chip * chip ,
129
157
unsigned offset , int value )
130
158
{
131
- unsigned long flags ;
132
- u32 mask = 1 << offset ;
133
- u32 tmp ;
134
159
struct rb532_gpio_chip * gpch ;
135
- void __iomem * gpvr ;
136
160
137
161
gpch = container_of (chip , struct rb532_gpio_chip , chip );
138
- gpvr = gpch -> regbase + GPIOD ;
139
-
140
- local_irq_save (flags );
141
- tmp = readl (gpvr );
142
- if (value )
143
- tmp |= mask ;
144
- else
145
- tmp &= ~mask ;
146
- writel (tmp , gpvr );
147
- local_irq_restore (flags );
162
+ rb532_set_bit (value , offset , gpch -> regbase + GPIOD );
148
163
}
149
164
150
165
/*
151
166
* Set GPIO direction to input
152
167
*/
153
168
static int rb532_gpio_direction_input (struct gpio_chip * chip , unsigned offset )
154
169
{
155
- unsigned long flags ;
156
- u32 mask = 1 << offset ;
157
- u32 value ;
158
170
struct rb532_gpio_chip * gpch ;
159
- void __iomem * gpdr ;
160
171
161
172
gpch = container_of (chip , struct rb532_gpio_chip , chip );
162
- gpdr = gpch -> regbase + GPIOCFG ;
163
173
164
- local_irq_save (flags );
165
- value = readl (gpdr );
166
- value &= ~mask ;
167
- writel (value , gpdr );
168
- local_irq_restore (flags );
174
+ if (rb532_get_bit (offset , gpch -> regbase + GPIOFUNC ))
175
+ return 1 ; /* alternate function, GPIOCFG is ignored */
169
176
177
+ rb532_set_bit (0 , offset , gpch -> regbase + GPIOCFG );
170
178
return 0 ;
171
179
}
172
180
@@ -176,117 +184,60 @@ static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
176
184
static int rb532_gpio_direction_output (struct gpio_chip * chip ,
177
185
unsigned offset , int value )
178
186
{
179
- unsigned long flags ;
180
- u32 mask = 1 << offset ;
181
- u32 tmp ;
182
187
struct rb532_gpio_chip * gpch ;
183
- void __iomem * gpdr ;
184
188
185
189
gpch = container_of (chip , struct rb532_gpio_chip , chip );
186
- writel (mask , gpch -> regbase + GPIOD );
187
- gpdr = gpch -> regbase + GPIOCFG ;
188
190
189
- local_irq_save (flags );
190
- tmp = readl (gpdr );
191
- tmp |= mask ;
192
- writel (tmp , gpdr );
193
- local_irq_restore (flags );
191
+ if (rb532_get_bit (offset , gpch -> regbase + GPIOFUNC ))
192
+ return 1 ; /* alternate function, GPIOCFG is ignored */
194
193
194
+ /* set the initial output value */
195
+ rb532_set_bit (value , offset , gpch -> regbase + GPIOD );
196
+
197
+ rb532_set_bit (1 , offset , gpch -> regbase + GPIOCFG );
195
198
return 0 ;
196
199
}
197
200
198
- /*
199
- * Set the GPIO interrupt level
200
- */
201
- static void rb532_gpio_set_int_level (struct gpio_chip * chip ,
202
- unsigned offset , int value )
203
- {
204
- unsigned long flags ;
205
- u32 mask = 1 << offset ;
206
- u32 tmp ;
207
- struct rb532_gpio_chip * gpch ;
208
- void __iomem * gpil ;
209
-
210
- gpch = container_of (chip , struct rb532_gpio_chip , chip );
211
- gpil = gpch -> regbase + GPIOILEVEL ;
212
-
213
- local_irq_save (flags );
214
- tmp = readl (gpil );
215
- if (value )
216
- tmp |= mask ;
217
- else
218
- tmp &= ~mask ;
219
- writel (tmp , gpil );
220
- local_irq_restore (flags );
221
- }
201
+ static struct rb532_gpio_chip rb532_gpio_chip [] = {
202
+ [0 ] = {
203
+ .chip = {
204
+ .label = "gpio0" ,
205
+ .direction_input = rb532_gpio_direction_input ,
206
+ .direction_output = rb532_gpio_direction_output ,
207
+ .get = rb532_gpio_get ,
208
+ .set = rb532_gpio_set ,
209
+ .base = 0 ,
210
+ .ngpio = 32 ,
211
+ },
212
+ },
213
+ };
222
214
223
215
/*
224
- * Get the GPIO interrupt level
216
+ * Set GPIO interrupt level
225
217
*/
226
- static int rb532_gpio_get_int_level ( struct gpio_chip * chip , unsigned offset )
218
+ void rb532_gpio_set_ilevel ( int bit , unsigned gpio )
227
219
{
228
- u32 mask = 1 << offset ;
229
- struct rb532_gpio_chip * gpch ;
230
-
231
- gpch = container_of (chip , struct rb532_gpio_chip , chip );
232
- return readl (gpch -> regbase + GPIOILEVEL ) & mask ;
220
+ rb532_set_bit (bit , gpio , rb532_gpio_chip -> regbase + GPIOILEVEL );
233
221
}
222
+ EXPORT_SYMBOL (rb532_gpio_set_ilevel );
234
223
235
224
/*
236
- * Set the GPIO interrupt status
225
+ * Set GPIO interrupt status
237
226
*/
238
- static void rb532_gpio_set_int_status (struct gpio_chip * chip ,
239
- unsigned offset , int value )
227
+ void rb532_gpio_set_istat (int bit , unsigned gpio )
240
228
{
241
- unsigned long flags ;
242
- u32 mask = 1 << offset ;
243
- u32 tmp ;
244
- struct rb532_gpio_chip * gpch ;
245
- void __iomem * gpis ;
246
-
247
- gpch = container_of (chip , struct rb532_gpio_chip , chip );
248
- gpis = gpch -> regbase + GPIOISTAT ;
249
-
250
- local_irq_save (flags );
251
- tmp = readl (gpis );
252
- if (value )
253
- tmp |= mask ;
254
- else
255
- tmp &= ~mask ;
256
- writel (tmp , gpis );
257
- local_irq_restore (flags );
229
+ rb532_set_bit (bit , gpio , rb532_gpio_chip -> regbase + GPIOISTAT );
258
230
}
231
+ EXPORT_SYMBOL (rb532_gpio_set_istat );
259
232
260
233
/*
261
- * Get the GPIO interrupt status
234
+ * Configure GPIO alternate function
262
235
*/
263
- static int rb532_gpio_get_int_status ( struct gpio_chip * chip , unsigned offset )
236
+ static void rb532_gpio_set_func ( int bit , unsigned gpio )
264
237
{
265
- u32 mask = 1 << offset ;
266
- struct rb532_gpio_chip * gpch ;
267
-
268
- gpch = container_of (chip , struct rb532_gpio_chip , chip );
269
- return readl (gpch -> regbase + GPIOISTAT ) & mask ;
238
+ rb532_set_bit (bit , gpio , rb532_gpio_chip -> regbase + GPIOFUNC );
270
239
}
271
240
272
- static struct rb532_gpio_chip rb532_gpio_chip [] = {
273
- [0 ] = {
274
- .chip = {
275
- .label = "gpio0" ,
276
- .direction_input = rb532_gpio_direction_input ,
277
- .direction_output = rb532_gpio_direction_output ,
278
- .get = rb532_gpio_get ,
279
- .set = rb532_gpio_set ,
280
- .base = 0 ,
281
- .ngpio = 32 ,
282
- },
283
- .get_int_level = rb532_gpio_get_int_level ,
284
- .set_int_level = rb532_gpio_set_int_level ,
285
- .get_int_status = rb532_gpio_get_int_status ,
286
- .set_int_status = rb532_gpio_set_int_status ,
287
- },
288
- };
289
-
290
241
int __init rb532_gpio_init (void )
291
242
{
292
243
struct resource * r ;
@@ -310,9 +261,11 @@ int __init rb532_gpio_init(void)
310
261
return - ENXIO ;
311
262
}
312
263
313
- /* Set the interrupt status and level for the CF pin */
314
- rb532_gpio_set_int_level (& rb532_gpio_chip -> chip , CF_GPIO_NUM , 1 );
315
- rb532_gpio_set_int_status (& rb532_gpio_chip -> chip , CF_GPIO_NUM , 0 );
264
+ /* configure CF_GPIO_NUM as CFRDY IRQ source */
265
+ rb532_gpio_set_func (0 , CF_GPIO_NUM );
266
+ rb532_gpio_direction_input (& rb532_gpio_chip -> chip , CF_GPIO_NUM );
267
+ rb532_gpio_set_ilevel (1 , CF_GPIO_NUM );
268
+ rb532_gpio_set_istat (0 , CF_GPIO_NUM );
316
269
317
270
return 0 ;
318
271
}
0 commit comments