Add endianness as io mem parameter
[sdk/emulator/qemu.git] / hw / omap_gpio.c
1 /*
2  * TI OMAP processors GPIO emulation.
3  *
4  * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
5  * Copyright (C) 2007-2009 Nokia Corporation
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 or
10  * (at your option) version 3 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "hw.h"
22 #include "omap.h"
23 /* General-Purpose I/O */
24 struct omap_gpio_s {
25     qemu_irq irq;
26     qemu_irq *in;
27     qemu_irq handler[16];
28
29     uint16_t inputs;
30     uint16_t outputs;
31     uint16_t dir;
32     uint16_t edge;
33     uint16_t mask;
34     uint16_t ints;
35     uint16_t pins;
36 };
37
38 static void omap_gpio_set(void *opaque, int line, int level)
39 {
40     struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
41     uint16_t prev = s->inputs;
42
43     if (level)
44         s->inputs |= 1 << line;
45     else
46         s->inputs &= ~(1 << line);
47
48     if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
49                     (1 << line) & s->dir & ~s->mask) {
50         s->ints |= 1 << line;
51         qemu_irq_raise(s->irq);
52     }
53 }
54
55 static uint32_t omap_gpio_read(void *opaque, target_phys_addr_t addr)
56 {
57     struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
58     int offset = addr & OMAP_MPUI_REG_MASK;
59
60     switch (offset) {
61     case 0x00:  /* DATA_INPUT */
62         return s->inputs & s->pins;
63
64     case 0x04:  /* DATA_OUTPUT */
65         return s->outputs;
66
67     case 0x08:  /* DIRECTION_CONTROL */
68         return s->dir;
69
70     case 0x0c:  /* INTERRUPT_CONTROL */
71         return s->edge;
72
73     case 0x10:  /* INTERRUPT_MASK */
74         return s->mask;
75
76     case 0x14:  /* INTERRUPT_STATUS */
77         return s->ints;
78
79     case 0x18:  /* PIN_CONTROL (not in OMAP310) */
80         OMAP_BAD_REG(addr);
81         return s->pins;
82     }
83
84     OMAP_BAD_REG(addr);
85     return 0;
86 }
87
88 static void omap_gpio_write(void *opaque, target_phys_addr_t addr,
89                 uint32_t value)
90 {
91     struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
92     int offset = addr & OMAP_MPUI_REG_MASK;
93     uint16_t diff;
94     int ln;
95
96     switch (offset) {
97     case 0x00:  /* DATA_INPUT */
98         OMAP_RO_REG(addr);
99         return;
100
101     case 0x04:  /* DATA_OUTPUT */
102         diff = (s->outputs ^ value) & ~s->dir;
103         s->outputs = value;
104         while ((ln = ffs(diff))) {
105             ln --;
106             if (s->handler[ln])
107                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
108             diff &= ~(1 << ln);
109         }
110         break;
111
112     case 0x08:  /* DIRECTION_CONTROL */
113         diff = s->outputs & (s->dir ^ value);
114         s->dir = value;
115
116         value = s->outputs & ~s->dir;
117         while ((ln = ffs(diff))) {
118             ln --;
119             if (s->handler[ln])
120                 qemu_set_irq(s->handler[ln], (value >> ln) & 1);
121             diff &= ~(1 << ln);
122         }
123         break;
124
125     case 0x0c:  /* INTERRUPT_CONTROL */
126         s->edge = value;
127         break;
128
129     case 0x10:  /* INTERRUPT_MASK */
130         s->mask = value;
131         break;
132
133     case 0x14:  /* INTERRUPT_STATUS */
134         s->ints &= ~value;
135         if (!s->ints)
136             qemu_irq_lower(s->irq);
137         break;
138
139     case 0x18:  /* PIN_CONTROL (not in OMAP310 TRM) */
140         OMAP_BAD_REG(addr);
141         s->pins = value;
142         break;
143
144     default:
145         OMAP_BAD_REG(addr);
146         return;
147     }
148 }
149
150 /* *Some* sources say the memory region is 32-bit.  */
151 static CPUReadMemoryFunc * const omap_gpio_readfn[] = {
152     omap_badwidth_read16,
153     omap_gpio_read,
154     omap_badwidth_read16,
155 };
156
157 static CPUWriteMemoryFunc * const omap_gpio_writefn[] = {
158     omap_badwidth_write16,
159     omap_gpio_write,
160     omap_badwidth_write16,
161 };
162
163 void omap_gpio_reset(struct omap_gpio_s *s)
164 {
165     s->inputs = 0;
166     s->outputs = ~0;
167     s->dir = ~0;
168     s->edge = ~0;
169     s->mask = ~0;
170     s->ints = 0;
171     s->pins = ~0;
172 }
173
174 struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
175                 qemu_irq irq, omap_clk clk)
176 {
177     int iomemtype;
178     struct omap_gpio_s *s = (struct omap_gpio_s *)
179             qemu_mallocz(sizeof(struct omap_gpio_s));
180
181     s->irq = irq;
182     s->in = qemu_allocate_irqs(omap_gpio_set, s, 16);
183     omap_gpio_reset(s);
184
185     iomemtype = cpu_register_io_memory(omap_gpio_readfn,
186                     omap_gpio_writefn, s, DEVICE_NATIVE_ENDIAN);
187     cpu_register_physical_memory(base, 0x1000, iomemtype);
188
189     return s;
190 }
191
192 qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s)
193 {
194     return s->in;
195 }
196
197 void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler)
198 {
199     if (line >= 16 || line < 0)
200         hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
201     s->handler[line] = handler;
202 }
203
204 /* General-Purpose Interface of OMAP2 */
205 struct omap2_gpio_s {
206     qemu_irq irq[2];
207     qemu_irq wkup;
208     qemu_irq *in;
209     qemu_irq handler[32];
210
211     uint8_t config[2];
212     uint32_t inputs;
213     uint32_t outputs;
214     uint32_t dir;
215     uint32_t level[2];
216     uint32_t edge[2];
217     uint32_t mask[2];
218     uint32_t wumask;
219     uint32_t ints[2];
220     uint32_t debounce;
221     uint8_t delay;
222 };
223
224 static inline void omap2_gpio_module_int_update(struct omap2_gpio_s *s,
225                 int line)
226 {
227     qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
228 }
229
230 static void omap2_gpio_module_wake(struct omap2_gpio_s *s, int line)
231 {
232     if (!(s->config[0] & (1 << 2)))                     /* ENAWAKEUP */
233         return;
234     if (!(s->config[0] & (3 << 3)))                     /* Force Idle */
235         return;
236     if (!(s->wumask & (1 << line)))
237         return;
238
239     qemu_irq_raise(s->wkup);
240 }
241
242 static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s,
243                 uint32_t diff)
244 {
245     int ln;
246
247     s->outputs ^= diff;
248     diff &= ~s->dir;
249     while ((ln = ffs(diff))) {
250         ln --;
251         qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
252         diff &= ~(1 << ln);
253     }
254 }
255
256 static void omap2_gpio_module_level_update(struct omap2_gpio_s *s, int line)
257 {
258     s->ints[line] |= s->dir &
259             ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
260     omap2_gpio_module_int_update(s, line);
261 }
262
263 static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
264 {
265     s->ints[0] |= 1 << line;
266     omap2_gpio_module_int_update(s, 0);
267     s->ints[1] |= 1 << line;
268     omap2_gpio_module_int_update(s, 1);
269     omap2_gpio_module_wake(s, line);
270 }
271
272 static void omap2_gpio_module_set(void *opaque, int line, int level)
273 {
274     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
275
276     if (level) {
277         if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
278             omap2_gpio_module_int(s, line);
279         s->inputs |= 1 << line;
280     } else {
281         if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
282             omap2_gpio_module_int(s, line);
283         s->inputs &= ~(1 << line);
284     }
285 }
286
287 static void omap2_gpio_module_reset(struct omap2_gpio_s *s)
288 {
289     s->config[0] = 0;
290     s->config[1] = 2;
291     s->ints[0] = 0;
292     s->ints[1] = 0;
293     s->mask[0] = 0;
294     s->mask[1] = 0;
295     s->wumask = 0;
296     s->dir = ~0;
297     s->level[0] = 0;
298     s->level[1] = 0;
299     s->edge[0] = 0;
300     s->edge[1] = 0;
301     s->debounce = 0;
302     s->delay = 0;
303 }
304
305 static uint32_t omap2_gpio_module_read(void *opaque, target_phys_addr_t addr)
306 {
307     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
308
309     switch (addr) {
310     case 0x00:  /* GPIO_REVISION */
311         return 0x18;
312
313     case 0x10:  /* GPIO_SYSCONFIG */
314         return s->config[0];
315
316     case 0x14:  /* GPIO_SYSSTATUS */
317         return 0x01;
318
319     case 0x18:  /* GPIO_IRQSTATUS1 */
320         return s->ints[0];
321
322     case 0x1c:  /* GPIO_IRQENABLE1 */
323     case 0x60:  /* GPIO_CLEARIRQENABLE1 */
324     case 0x64:  /* GPIO_SETIRQENABLE1 */
325         return s->mask[0];
326
327     case 0x20:  /* GPIO_WAKEUPENABLE */
328     case 0x80:  /* GPIO_CLEARWKUENA */
329     case 0x84:  /* GPIO_SETWKUENA */
330         return s->wumask;
331
332     case 0x28:  /* GPIO_IRQSTATUS2 */
333         return s->ints[1];
334
335     case 0x2c:  /* GPIO_IRQENABLE2 */
336     case 0x70:  /* GPIO_CLEARIRQENABLE2 */
337     case 0x74:  /* GPIO_SETIREQNEABLE2 */
338         return s->mask[1];
339
340     case 0x30:  /* GPIO_CTRL */
341         return s->config[1];
342
343     case 0x34:  /* GPIO_OE */
344         return s->dir;
345
346     case 0x38:  /* GPIO_DATAIN */
347         return s->inputs;
348
349     case 0x3c:  /* GPIO_DATAOUT */
350     case 0x90:  /* GPIO_CLEARDATAOUT */
351     case 0x94:  /* GPIO_SETDATAOUT */
352         return s->outputs;
353
354     case 0x40:  /* GPIO_LEVELDETECT0 */
355         return s->level[0];
356
357     case 0x44:  /* GPIO_LEVELDETECT1 */
358         return s->level[1];
359
360     case 0x48:  /* GPIO_RISINGDETECT */
361         return s->edge[0];
362
363     case 0x4c:  /* GPIO_FALLINGDETECT */
364         return s->edge[1];
365
366     case 0x50:  /* GPIO_DEBOUNCENABLE */
367         return s->debounce;
368
369     case 0x54:  /* GPIO_DEBOUNCINGTIME */
370         return s->delay;
371     }
372
373     OMAP_BAD_REG(addr);
374     return 0;
375 }
376
377 static void omap2_gpio_module_write(void *opaque, target_phys_addr_t addr,
378                 uint32_t value)
379 {
380     struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
381     uint32_t diff;
382     int ln;
383
384     switch (addr) {
385     case 0x00:  /* GPIO_REVISION */
386     case 0x14:  /* GPIO_SYSSTATUS */
387     case 0x38:  /* GPIO_DATAIN */
388         OMAP_RO_REG(addr);
389         break;
390
391     case 0x10:  /* GPIO_SYSCONFIG */
392         if (((value >> 3) & 3) == 3)
393             fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
394         if (value & 2)
395             omap2_gpio_module_reset(s);
396         s->config[0] = value & 0x1d;
397         break;
398
399     case 0x18:  /* GPIO_IRQSTATUS1 */
400         if (s->ints[0] & value) {
401             s->ints[0] &= ~value;
402             omap2_gpio_module_level_update(s, 0);
403         }
404         break;
405
406     case 0x1c:  /* GPIO_IRQENABLE1 */
407         s->mask[0] = value;
408         omap2_gpio_module_int_update(s, 0);
409         break;
410
411     case 0x20:  /* GPIO_WAKEUPENABLE */
412         s->wumask = value;
413         break;
414
415     case 0x28:  /* GPIO_IRQSTATUS2 */
416         if (s->ints[1] & value) {
417             s->ints[1] &= ~value;
418             omap2_gpio_module_level_update(s, 1);
419         }
420         break;
421
422     case 0x2c:  /* GPIO_IRQENABLE2 */
423         s->mask[1] = value;
424         omap2_gpio_module_int_update(s, 1);
425         break;
426
427     case 0x30:  /* GPIO_CTRL */
428         s->config[1] = value & 7;
429         break;
430
431     case 0x34:  /* GPIO_OE */
432         diff = s->outputs & (s->dir ^ value);
433         s->dir = value;
434
435         value = s->outputs & ~s->dir;
436         while ((ln = ffs(diff))) {
437             diff &= ~(1 <<-- ln);
438             qemu_set_irq(s->handler[ln], (value >> ln) & 1);
439         }
440
441         omap2_gpio_module_level_update(s, 0);
442         omap2_gpio_module_level_update(s, 1);
443         break;
444
445     case 0x3c:  /* GPIO_DATAOUT */
446         omap2_gpio_module_out_update(s, s->outputs ^ value);
447         break;
448
449     case 0x40:  /* GPIO_LEVELDETECT0 */
450         s->level[0] = value;
451         omap2_gpio_module_level_update(s, 0);
452         omap2_gpio_module_level_update(s, 1);
453         break;
454
455     case 0x44:  /* GPIO_LEVELDETECT1 */
456         s->level[1] = value;
457         omap2_gpio_module_level_update(s, 0);
458         omap2_gpio_module_level_update(s, 1);
459         break;
460
461     case 0x48:  /* GPIO_RISINGDETECT */
462         s->edge[0] = value;
463         break;
464
465     case 0x4c:  /* GPIO_FALLINGDETECT */
466         s->edge[1] = value;
467         break;
468
469     case 0x50:  /* GPIO_DEBOUNCENABLE */
470         s->debounce = value;
471         break;
472
473     case 0x54:  /* GPIO_DEBOUNCINGTIME */
474         s->delay = value;
475         break;
476
477     case 0x60:  /* GPIO_CLEARIRQENABLE1 */
478         s->mask[0] &= ~value;
479         omap2_gpio_module_int_update(s, 0);
480         break;
481
482     case 0x64:  /* GPIO_SETIRQENABLE1 */
483         s->mask[0] |= value;
484         omap2_gpio_module_int_update(s, 0);
485         break;
486
487     case 0x70:  /* GPIO_CLEARIRQENABLE2 */
488         s->mask[1] &= ~value;
489         omap2_gpio_module_int_update(s, 1);
490         break;
491
492     case 0x74:  /* GPIO_SETIREQNEABLE2 */
493         s->mask[1] |= value;
494         omap2_gpio_module_int_update(s, 1);
495         break;
496
497     case 0x80:  /* GPIO_CLEARWKUENA */
498         s->wumask &= ~value;
499         break;
500
501     case 0x84:  /* GPIO_SETWKUENA */
502         s->wumask |= value;
503         break;
504
505     case 0x90:  /* GPIO_CLEARDATAOUT */
506         omap2_gpio_module_out_update(s, s->outputs & value);
507         break;
508
509     case 0x94:  /* GPIO_SETDATAOUT */
510         omap2_gpio_module_out_update(s, ~s->outputs & value);
511         break;
512
513     default:
514         OMAP_BAD_REG(addr);
515         return;
516     }
517 }
518
519 static uint32_t omap2_gpio_module_readp(void *opaque, target_phys_addr_t addr)
520 {
521     return omap2_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
522 }
523
524 static void omap2_gpio_module_writep(void *opaque, target_phys_addr_t addr,
525                 uint32_t value)
526 {
527     uint32_t cur = 0;
528     uint32_t mask = 0xffff;
529
530     switch (addr & ~3) {
531     case 0x00:  /* GPIO_REVISION */
532     case 0x14:  /* GPIO_SYSSTATUS */
533     case 0x38:  /* GPIO_DATAIN */
534         OMAP_RO_REG(addr);
535         break;
536
537     case 0x10:  /* GPIO_SYSCONFIG */
538     case 0x1c:  /* GPIO_IRQENABLE1 */
539     case 0x20:  /* GPIO_WAKEUPENABLE */
540     case 0x2c:  /* GPIO_IRQENABLE2 */
541     case 0x30:  /* GPIO_CTRL */
542     case 0x34:  /* GPIO_OE */
543     case 0x3c:  /* GPIO_DATAOUT */
544     case 0x40:  /* GPIO_LEVELDETECT0 */
545     case 0x44:  /* GPIO_LEVELDETECT1 */
546     case 0x48:  /* GPIO_RISINGDETECT */
547     case 0x4c:  /* GPIO_FALLINGDETECT */
548     case 0x50:  /* GPIO_DEBOUNCENABLE */
549     case 0x54:  /* GPIO_DEBOUNCINGTIME */
550         cur = omap2_gpio_module_read(opaque, addr & ~3) &
551                 ~(mask << ((addr & 3) << 3));
552
553         /* Fall through.  */
554     case 0x18:  /* GPIO_IRQSTATUS1 */
555     case 0x28:  /* GPIO_IRQSTATUS2 */
556     case 0x60:  /* GPIO_CLEARIRQENABLE1 */
557     case 0x64:  /* GPIO_SETIRQENABLE1 */
558     case 0x70:  /* GPIO_CLEARIRQENABLE2 */
559     case 0x74:  /* GPIO_SETIREQNEABLE2 */
560     case 0x80:  /* GPIO_CLEARWKUENA */
561     case 0x84:  /* GPIO_SETWKUENA */
562     case 0x90:  /* GPIO_CLEARDATAOUT */
563     case 0x94:  /* GPIO_SETDATAOUT */
564         value <<= (addr & 3) << 3;
565         omap2_gpio_module_write(opaque, addr, cur | value);
566         break;
567
568     default:
569         OMAP_BAD_REG(addr);
570         return;
571     }
572 }
573
574 static CPUReadMemoryFunc * const omap2_gpio_module_readfn[] = {
575     omap2_gpio_module_readp,
576     omap2_gpio_module_readp,
577     omap2_gpio_module_read,
578 };
579
580 static CPUWriteMemoryFunc * const omap2_gpio_module_writefn[] = {
581     omap2_gpio_module_writep,
582     omap2_gpio_module_writep,
583     omap2_gpio_module_write,
584 };
585
586 static void omap2_gpio_module_init(struct omap2_gpio_s *s,
587                 struct omap_target_agent_s *ta, int region,
588                 qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
589                 omap_clk fclk, omap_clk iclk)
590 {
591     int iomemtype;
592
593     s->irq[0] = mpu;
594     s->irq[1] = dsp;
595     s->wkup = wkup;
596     s->in = qemu_allocate_irqs(omap2_gpio_module_set, s, 32);
597
598     iomemtype = l4_register_io_memory(omap2_gpio_module_readfn,
599                     omap2_gpio_module_writefn, s);
600     omap_l4_attach(ta, region, iomemtype);
601 }
602
603 struct omap_gpif_s {
604     struct omap2_gpio_s module[5];
605     int modules;
606
607     int autoidle;
608     int gpo;
609 };
610
611 void omap_gpif_reset(struct omap_gpif_s *s)
612 {
613     int i;
614
615     for (i = 0; i < s->modules; i ++)
616         omap2_gpio_module_reset(s->module + i);
617
618     s->autoidle = 0;
619     s->gpo = 0;
620 }
621
622 static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
623 {
624     struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
625
626     switch (addr) {
627     case 0x00:  /* IPGENERICOCPSPL_REVISION */
628         return 0x18;
629
630     case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
631         return s->autoidle;
632
633     case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
634         return 0x01;
635
636     case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
637         return 0x00;
638
639     case 0x40:  /* IPGENERICOCPSPL_GPO */
640         return s->gpo;
641
642     case 0x50:  /* IPGENERICOCPSPL_GPI */
643         return 0x00;
644     }
645
646     OMAP_BAD_REG(addr);
647     return 0;
648 }
649
650 static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
651                 uint32_t value)
652 {
653     struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
654
655     switch (addr) {
656     case 0x00:  /* IPGENERICOCPSPL_REVISION */
657     case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
658     case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
659     case 0x50:  /* IPGENERICOCPSPL_GPI */
660         OMAP_RO_REG(addr);
661         break;
662
663     case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
664         if (value & (1 << 1))                                   /* SOFTRESET */
665             omap_gpif_reset(s);
666         s->autoidle = value & 1;
667         break;
668
669     case 0x40:  /* IPGENERICOCPSPL_GPO */
670         s->gpo = value & 1;
671         break;
672
673     default:
674         OMAP_BAD_REG(addr);
675         return;
676     }
677 }
678
679 static CPUReadMemoryFunc * const omap_gpif_top_readfn[] = {
680     omap_gpif_top_read,
681     omap_gpif_top_read,
682     omap_gpif_top_read,
683 };
684
685 static CPUWriteMemoryFunc * const omap_gpif_top_writefn[] = {
686     omap_gpif_top_write,
687     omap_gpif_top_write,
688     omap_gpif_top_write,
689 };
690
691 struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
692                 qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
693 {
694     int iomemtype, i;
695     struct omap_gpif_s *s = (struct omap_gpif_s *)
696             qemu_mallocz(sizeof(struct omap_gpif_s));
697     int region[4] = { 0, 2, 4, 5 };
698
699     s->modules = modules;
700     for (i = 0; i < modules; i ++)
701         omap2_gpio_module_init(s->module + i, ta, region[i],
702                               irq[i], NULL, NULL, fclk[i], iclk);
703
704     omap_gpif_reset(s);
705
706     iomemtype = l4_register_io_memory(omap_gpif_top_readfn,
707                     omap_gpif_top_writefn, s);
708     omap_l4_attach(ta, 1, iomemtype);
709
710     return s;
711 }
712
713 qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
714 {
715     if (start >= s->modules * 32 || start < 0)
716         hw_error("%s: No GPIO line %i\n", __FUNCTION__, start);
717     return s->module[start >> 5].in + (start & 31);
718 }
719
720 void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
721 {
722     if (line >= s->modules * 32 || line < 0)
723         hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
724     s->module[line >> 5].handler[line & 31] = handler;
725 }