2 #include <minix/syslib.h>
3 #include <minix/drvlib.h>
5 #include <minix/mmio.h>
6 #include <minix/gpio.h>
10 #include <sys/types.h>
24 /* used for logging */
25 static struct log log
= {
27 .log_level
= LEVEL_INFO
,
28 .log_func
= default_log
33 /* request access to a gpio */
34 int (*claim
) (char *owner
, int nr
, struct gpio
** gpio
);
36 /* Configure the GPIO for a certain purpose */
37 int (*pin_mode
) (struct gpio
* gpio
, int mode
);
39 /* Set the value for a GPIO */
40 int (*set
) (struct gpio
* gpio
, int value
);
42 /* Read the current value of the GPIO */
43 int (*read
) (struct gpio
* gpio
, int *value
);
45 /* Read and clear the value interrupt value of the GPIO */
46 int (*intr_read
) (struct gpio
* gpio
, int *value
);
49 int (*message_hook
) (message
* m
);
52 static struct gpio_driver drv
;
57 uint32_t register_address
;
58 uint32_t irq_nr
; /* irq number */
59 uint32_t base_address
;
61 int irq_id
; /* orignhal hook id??? */
62 int irq_hook_id
; /* hook id */
63 uint32_t inter_values
; /* values when the interrupt was called */
66 #define GPIO1_BASE (0x48310000)
67 #define GPIO2_BASE (0x49050000)
68 #define GPIO3_BASE (0x49052000)
69 #define GPIO4_BASE (0x49054000)
70 #define GPIO5_BASE (0x49056000)
71 #define GPIO6_BASE (0x49058000)
72 #define GPIO1_IRQ 29 /* GPIO module 1 */
73 #define GPIO2_IRQ 30 /* GPIO module 2 */
74 #define GPIO3_IRQ 31 /* GPIO module 3 */
75 #define GPIO4_IRQ 32 /* GPIO module 4 */
76 #define GPIO5_IRQ 33 /* GPIO module 5 */
77 #define GPIO6_IRQ 34 /* GPIO module 6 */
78 #define GPIO1_IRQ_HOOK_ID 0
79 #define GPIO2_IRQ_HOOK_ID 1
80 #define GPIO3_IRQ_HOOK_ID 2
81 #define GPIO4_IRQ_HOOK_ID 3
82 #define GPIO5_IRQ_HOOK_ID 4
83 #define GPIO6_IRQ_HOOK_ID 5
85 #define GPIO_IRQSTATUS1 (0x18)
86 #define GPIO_IRQENABLE1 (0x01C)
87 #define GPIO_DATAOUT (0x3c)
88 #define GPIO_DATAIN (0x38)
89 #define GPIO_OE (0x34) /* Output Data Enable */
90 #define GPIO_RISINGDETECT1 (0x048)
91 #define GPIO_FALLINGDETECT1 (0x04c)
92 #define GPIO_CLEARDATAOUT (0x90)
93 #define GPIO_SETDATAOUT (0x94)
95 static struct omap_gpio_bank omap_gpio_banks
[] = {
98 .register_address
= GPIO1_BASE
,
102 .irq_id
= GPIO1_IRQ_HOOK_ID
,
103 .irq_hook_id
= GPIO1_IRQ_HOOK_ID
,
107 .register_address
= GPIO2_BASE
,
111 .irq_id
= GPIO2_IRQ_HOOK_ID
,
112 .irq_hook_id
= GPIO2_IRQ_HOOK_ID
,
116 .register_address
= GPIO3_BASE
,
120 .irq_id
= GPIO3_IRQ_HOOK_ID
,
121 .irq_hook_id
= GPIO3_IRQ_HOOK_ID
,
125 .register_address
= GPIO4_BASE
,
129 .irq_id
= GPIO4_IRQ_HOOK_ID
,
130 .irq_hook_id
= GPIO4_IRQ_HOOK_ID
,
134 .register_address
= GPIO5_BASE
,
138 .irq_id
= GPIO5_IRQ_HOOK_ID
,
139 .irq_hook_id
= GPIO5_IRQ_HOOK_ID
,
143 .register_address
= GPIO6_BASE
,
147 .irq_id
= GPIO6_IRQ_HOOK_ID
,
148 .irq_hook_id
= GPIO6_IRQ_HOOK_ID
,
153 #define GPIO_REVISION 0x00
154 #define GPIO_REVISION_MAJOR(X) ((X & 0xF0) >> 4)
155 #define GPIO_REVISION_MINOR(X) (X & 0XF)
157 struct omap_gpio_bank
*
158 omap_gpio_bank_get(int gpio_nr
)
160 struct omap_gpio_bank
*bank
;
161 assert(gpio_nr
>= 0 && gpio_nr
<= 32 * 6);
162 bank
= &omap_gpio_banks
[gpio_nr
/ 32];
167 omap_gpio_claim(char *owner
, int nr
, struct gpio
**gpio
)
169 log_trace(&log
, "%s s claiming %d\n", owner
, nr
);
171 if (nr
< 0 && nr
>= 32 * 6) {
172 log_warn(&log
, "%s is claiming unknown GPIO number %d\n",
177 if (omap_gpio_bank_get(nr
)->disabled
== 1) {
178 log_warn(&log
, "%s is claiming GPIO %d from disabled bank\n",
183 struct gpio
*tmp
= malloc(sizeof(struct gpio
));
184 memset(tmp
, 0, sizeof(*tmp
));
192 omap_gpio_pin_mode(struct gpio
*gpio
, int mode
)
194 struct omap_gpio_bank
*bank
;
195 assert(gpio
!= NULL
);
198 bank
= omap_gpio_bank_get(gpio
->nr
);
200 "pin mode bank %s, base address 0x%x -> register address (0x%x,0x%x,0x%x)\n",
201 bank
->name
, bank
->base_address
, bank
->register_address
, GPIO_OE
,
202 bank
->register_address
+ GPIO_OE
);
204 if (mode
== GPIO_MODE_OUTPUT
) {
205 set32(bank
->base_address
+ GPIO_OE
, BIT(gpio
->nr
% 32), 0);
207 set32(bank
->base_address
+ GPIO_FALLINGDETECT1
,
208 BIT(gpio
->nr
% 32), 0xffffffff);
209 set32(bank
->base_address
+ GPIO_IRQENABLE1
, BIT(gpio
->nr
% 32),
211 set32(bank
->base_address
+ GPIO_OE
, BIT(gpio
->nr
% 32),
218 omap_gpio_set(struct gpio
*gpio
, int value
)
220 struct omap_gpio_bank
*bank
;
221 assert(gpio
!= NULL
);
222 assert(gpio
->nr
>= 0 && gpio
->nr
<= 32 * 6);
224 bank
= omap_gpio_bank_get(gpio
->nr
);
226 write32(bank
->base_address
+ GPIO_SETDATAOUT
,
229 write32(bank
->base_address
+ GPIO_CLEARDATAOUT
,
236 omap_gpio_read(struct gpio
*gpio
, int *value
)
238 struct omap_gpio_bank
*bank
;
239 assert(gpio
!= NULL
);
240 assert(gpio
->nr
>= 0 && gpio
->nr
<= 32 * 6);
242 bank
= omap_gpio_bank_get(gpio
->nr
);
243 log_trace(&log
, "mode=%d OU/IN 0x%08x 0x%08x\n", gpio
->mode
,
244 read32(bank
->base_address
+ GPIO_DATAIN
),
245 read32(bank
->base_address
+ GPIO_DATAOUT
));
247 if (gpio
->mode
== GPIO_MODE_INPUT
) {
249 (read32(bank
->base_address
+
250 GPIO_DATAIN
) >> (gpio
->nr
% 32)) & 0x1;
253 (read32(bank
->base_address
+
254 GPIO_DATAOUT
) >> (gpio
->nr
% 32)) & 0x1;
261 omap_gpio_intr_read(struct gpio
*gpio
, int *value
)
263 struct omap_gpio_bank
*bank
;
264 assert(gpio
!= NULL
);
265 assert(gpio
->nr
>= 0 && gpio
->nr
<= 32 * 6);
267 bank
= omap_gpio_bank_get(gpio
->nr
);
268 /* TODO: check if interrupt where enabled?? */
270 *value
= (bank
->inter_values
>> (gpio
->nr
% 32)) & 0x1;
272 bank
->inter_values
&= ~(1 << (gpio
->nr
% 32));
278 omap_message_hook(message
* m
)
280 unsigned long irq_set
, i
;
281 struct omap_gpio_bank
*bank
;
283 switch (_ENDPOINT_P(m
->m_source
)) {
285 /* Hardware interrupt return a "set" if pending interrupts */
286 irq_set
= m
->NOTIFY_ARG
;
287 log_debug(&log
, "HW message 0X%08x\n", m
->NOTIFY_ARG
);
288 bank
= &omap_gpio_banks
[0];
289 for (i
= 0; omap_gpio_banks
[i
].name
!= NULL
; i
++) {
290 bank
= &omap_gpio_banks
[i
];
292 if (irq_set
& (1 << (bank
->irq_id
))) {
293 log_trace(&log
, "Interrupt for bank %s\n",
295 bank
->inter_values
|=
296 read32(bank
->base_address
+
298 /* clear the interrupts */
299 write32(bank
->base_address
+ GPIO_IRQSTATUS1
,
301 if (sys_irqenable(&bank
->irq_hook_id
) != OK
) {
303 "Failed to enable irq for bank %s\n",
310 log_warn(&log
, "Unknown message\n");
317 omap_gpio_init(struct gpio_driver
*drv
)
321 struct minix_mem_range mr
;
322 struct omap_gpio_bank
*bank
;
324 bank
= &omap_gpio_banks
[0];
325 for (i
= 0; omap_gpio_banks
[i
].name
!= NULL
; i
++) {
326 bank
= &omap_gpio_banks
[i
];
327 mr
.mr_base
= bank
->register_address
;
328 mr
.mr_limit
= bank
->register_address
+ 0x400;
330 if (sys_privctl(SELF
, SYS_PRIV_ADD_MEM
, &mr
) != 0) {
332 "Unable to request permission to map memory\n");
333 return EPERM
; /* fixme */
336 /* Set the base address to use */
338 (uint32_t) vm_map_phys(SELF
,
339 (void *) bank
->register_address
, 0x400);
341 if (bank
->base_address
== (uint32_t) MAP_FAILED
) {
342 log_warn(&log
, "Unable to map GPIO memory\n");
343 return EPERM
; /* fixme */
347 revision
= read32(bank
->base_address
+ GPIO_REVISION
);
348 /* test if we can access it */
349 if (GPIO_REVISION_MAJOR(revision
) != 2
350 || GPIO_REVISION_MINOR(revision
) != 5) {
352 "Failed to read the revision of GPIO bank %s.. disabling\n",
358 if (sys_irqsetpolicy(bank
->irq_nr
, 0,
359 &bank
->irq_hook_id
) != OK
) {
361 "GPIO: couldn't set IRQ policy for bank %s\n",
365 if (bank
->irq_id
!= bank
->irq_hook_id
) {
366 log_debug(&log
, "requested id %d but got id %d\n",
367 bank
->irq_id
, bank
->irq_hook_id
);
369 if (sys_irqenable(&bank
->irq_hook_id
) != OK
) {
371 "GPIO: couldn't enable interrupt for %s\n",
374 log_trace(&log
, "bank %s mapped on 0x%x with irq hook id %d\n",
375 bank
->name
, bank
->base_address
, bank
->irq_hook_id
);
380 /* enable the interface and functional clock on GPIO bank 1 */
381 clkconf_set(CM_FCLKEN_WKUP
, BIT(3), 0xffffffff);
382 clkconf_set(CM_ICLKEN_WKUP
, BIT(3), 0xffffffff);
386 drv
->claim
= omap_gpio_claim
;
387 drv
->pin_mode
= omap_gpio_pin_mode
;
388 drv
->set
= omap_gpio_set
;
389 drv
->read
= omap_gpio_read
;
390 drv
->intr_read
= omap_gpio_intr_read
;
391 drv
->message_hook
= omap_message_hook
;
398 return omap_gpio_init(&drv
);
401 /* request access to a gpio */
403 gpio_claim(char *owner
, int nr
, struct gpio
**gpio
)
405 return drv
.claim(owner
, nr
, gpio
);
408 /* Configure the GPIO for a certain purpose */
410 gpio_pin_mode(struct gpio
*gpio
, int mode
)
412 return drv
.pin_mode(gpio
, mode
);
415 /* Set the value for a GPIO */
417 gpio_set(struct gpio
*gpio
, int value
)
419 return drv
.set(gpio
, value
);
422 /* Read the current value of the GPIO */
424 gpio_read(struct gpio
*gpio
, int *value
)
426 return drv
.read(gpio
, value
);
429 /* Read and clear the value interrupt value of the GPIO */
431 gpio_intr_read(struct gpio
*gpio
, int *value
)
433 return drv
.intr_read(gpio
, value
);
438 gpio_intr_message(message
* m
)
440 return drv
.message_hook(m
);