qemu/hw/gpio/omap_gpio.c
<<
>>
Prefs
   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/hw.h"
  22#include "hw/arm/omap.h"
  23#include "hw/sysbus.h"
  24
  25struct omap_gpio_s {
  26    qemu_irq irq;
  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#define TYPE_OMAP1_GPIO "omap-gpio"
  39#define OMAP1_GPIO(obj) \
  40    OBJECT_CHECK(struct omap_gpif_s, (obj), TYPE_OMAP1_GPIO)
  41
  42struct omap_gpif_s {
  43    SysBusDevice parent_obj;
  44
  45    MemoryRegion iomem;
  46    int mpu_model;
  47    void *clk;
  48    struct omap_gpio_s omap1;
  49};
  50
  51/* General-Purpose I/O of OMAP1 */
  52static void omap_gpio_set(void *opaque, int line, int level)
  53{
  54    struct omap_gpio_s *s = &((struct omap_gpif_s *) opaque)->omap1;
  55    uint16_t prev = s->inputs;
  56
  57    if (level)
  58        s->inputs |= 1 << line;
  59    else
  60        s->inputs &= ~(1 << line);
  61
  62    if (((s->edge & s->inputs & ~prev) | (~s->edge & ~s->inputs & prev)) &
  63                    (1 << line) & s->dir & ~s->mask) {
  64        s->ints |= 1 << line;
  65        qemu_irq_raise(s->irq);
  66    }
  67}
  68
  69static uint64_t omap_gpio_read(void *opaque, hwaddr addr,
  70                               unsigned size)
  71{
  72    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
  73    int offset = addr & OMAP_MPUI_REG_MASK;
  74
  75    if (size != 2) {
  76        return omap_badwidth_read16(opaque, addr);
  77    }
  78
  79    switch (offset) {
  80    case 0x00:  /* DATA_INPUT */
  81        return s->inputs & s->pins;
  82
  83    case 0x04:  /* DATA_OUTPUT */
  84        return s->outputs;
  85
  86    case 0x08:  /* DIRECTION_CONTROL */
  87        return s->dir;
  88
  89    case 0x0c:  /* INTERRUPT_CONTROL */
  90        return s->edge;
  91
  92    case 0x10:  /* INTERRUPT_MASK */
  93        return s->mask;
  94
  95    case 0x14:  /* INTERRUPT_STATUS */
  96        return s->ints;
  97
  98    case 0x18:  /* PIN_CONTROL (not in OMAP310) */
  99        OMAP_BAD_REG(addr);
 100        return s->pins;
 101    }
 102
 103    OMAP_BAD_REG(addr);
 104    return 0;
 105}
 106
 107static void omap_gpio_write(void *opaque, hwaddr addr,
 108                            uint64_t value, unsigned size)
 109{
 110    struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
 111    int offset = addr & OMAP_MPUI_REG_MASK;
 112    uint16_t diff;
 113    int ln;
 114
 115    if (size != 2) {
 116        omap_badwidth_write16(opaque, addr, value);
 117        return;
 118    }
 119
 120    switch (offset) {
 121    case 0x00:  /* DATA_INPUT */
 122        OMAP_RO_REG(addr);
 123        return;
 124
 125    case 0x04:  /* DATA_OUTPUT */
 126        diff = (s->outputs ^ value) & ~s->dir;
 127        s->outputs = value;
 128        while ((ln = ctz32(diff)) != 32) {
 129            if (s->handler[ln])
 130                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
 131            diff &= ~(1 << ln);
 132        }
 133        break;
 134
 135    case 0x08:  /* DIRECTION_CONTROL */
 136        diff = s->outputs & (s->dir ^ value);
 137        s->dir = value;
 138
 139        value = s->outputs & ~s->dir;
 140        while ((ln = ctz32(diff)) != 32) {
 141            if (s->handler[ln])
 142                qemu_set_irq(s->handler[ln], (value >> ln) & 1);
 143            diff &= ~(1 << ln);
 144        }
 145        break;
 146
 147    case 0x0c:  /* INTERRUPT_CONTROL */
 148        s->edge = value;
 149        break;
 150
 151    case 0x10:  /* INTERRUPT_MASK */
 152        s->mask = value;
 153        break;
 154
 155    case 0x14:  /* INTERRUPT_STATUS */
 156        s->ints &= ~value;
 157        if (!s->ints)
 158            qemu_irq_lower(s->irq);
 159        break;
 160
 161    case 0x18:  /* PIN_CONTROL (not in OMAP310 TRM) */
 162        OMAP_BAD_REG(addr);
 163        s->pins = value;
 164        break;
 165
 166    default:
 167        OMAP_BAD_REG(addr);
 168        return;
 169    }
 170}
 171
 172/* *Some* sources say the memory region is 32-bit.  */
 173static const MemoryRegionOps omap_gpio_ops = {
 174    .read = omap_gpio_read,
 175    .write = omap_gpio_write,
 176    .endianness = DEVICE_NATIVE_ENDIAN,
 177};
 178
 179static void omap_gpio_reset(struct omap_gpio_s *s)
 180{
 181    s->inputs = 0;
 182    s->outputs = ~0;
 183    s->dir = ~0;
 184    s->edge = ~0;
 185    s->mask = ~0;
 186    s->ints = 0;
 187    s->pins = ~0;
 188}
 189
 190struct omap2_gpio_s {
 191    qemu_irq irq[2];
 192    qemu_irq wkup;
 193    qemu_irq *handler;
 194    MemoryRegion iomem;
 195
 196    uint8_t revision;
 197    uint8_t config[2];
 198    uint32_t inputs;
 199    uint32_t outputs;
 200    uint32_t dir;
 201    uint32_t level[2];
 202    uint32_t edge[2];
 203    uint32_t mask[2];
 204    uint32_t wumask;
 205    uint32_t ints[2];
 206    uint32_t debounce;
 207    uint8_t delay;
 208};
 209
 210#define TYPE_OMAP2_GPIO "omap2-gpio"
 211#define OMAP2_GPIO(obj) \
 212    OBJECT_CHECK(struct omap2_gpif_s, (obj), TYPE_OMAP2_GPIO)
 213
 214struct omap2_gpif_s {
 215    SysBusDevice parent_obj;
 216
 217    MemoryRegion iomem;
 218    int mpu_model;
 219    void *iclk;
 220    void *fclk[6];
 221    int modulecount;
 222    struct omap2_gpio_s *modules;
 223    qemu_irq *handler;
 224    int autoidle;
 225    int gpo;
 226};
 227
 228/* General-Purpose Interface of OMAP2/3 */
 229static inline void omap2_gpio_module_int_update(struct omap2_gpio_s *s,
 230                                                int line)
 231{
 232    qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
 233}
 234
 235static void omap2_gpio_module_wake(struct omap2_gpio_s *s, int line)
 236{
 237    if (!(s->config[0] & (1 << 2)))                     /* ENAWAKEUP */
 238        return;
 239    if (!(s->config[0] & (3 << 3)))                     /* Force Idle */
 240        return;
 241    if (!(s->wumask & (1 << line)))
 242        return;
 243
 244    qemu_irq_raise(s->wkup);
 245}
 246
 247static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s,
 248                uint32_t diff)
 249{
 250    int ln;
 251
 252    s->outputs ^= diff;
 253    diff &= ~s->dir;
 254    while ((ln = ctz32(diff)) != 32) {
 255        qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
 256        diff &= ~(1 << ln);
 257    }
 258}
 259
 260static void omap2_gpio_module_level_update(struct omap2_gpio_s *s, int line)
 261{
 262    s->ints[line] |= s->dir &
 263            ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
 264    omap2_gpio_module_int_update(s, line);
 265}
 266
 267static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
 268{
 269    s->ints[0] |= 1 << line;
 270    omap2_gpio_module_int_update(s, 0);
 271    s->ints[1] |= 1 << line;
 272    omap2_gpio_module_int_update(s, 1);
 273    omap2_gpio_module_wake(s, line);
 274}
 275
 276static void omap2_gpio_set(void *opaque, int line, int level)
 277{
 278    struct omap2_gpif_s *p = opaque;
 279    struct omap2_gpio_s *s = &p->modules[line >> 5];
 280
 281    line &= 31;
 282    if (level) {
 283        if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
 284            omap2_gpio_module_int(s, line);
 285        s->inputs |= 1 << line;
 286    } else {
 287        if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
 288            omap2_gpio_module_int(s, line);
 289        s->inputs &= ~(1 << line);
 290    }
 291}
 292
 293static void omap2_gpio_module_reset(struct omap2_gpio_s *s)
 294{
 295    s->config[0] = 0;
 296    s->config[1] = 2;
 297    s->ints[0] = 0;
 298    s->ints[1] = 0;
 299    s->mask[0] = 0;
 300    s->mask[1] = 0;
 301    s->wumask = 0;
 302    s->dir = ~0;
 303    s->level[0] = 0;
 304    s->level[1] = 0;
 305    s->edge[0] = 0;
 306    s->edge[1] = 0;
 307    s->debounce = 0;
 308    s->delay = 0;
 309}
 310
 311static uint32_t omap2_gpio_module_read(void *opaque, hwaddr addr)
 312{
 313    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
 314
 315    switch (addr) {
 316    case 0x00:  /* GPIO_REVISION */
 317        return s->revision;
 318
 319    case 0x10:  /* GPIO_SYSCONFIG */
 320        return s->config[0];
 321
 322    case 0x14:  /* GPIO_SYSSTATUS */
 323        return 0x01;
 324
 325    case 0x18:  /* GPIO_IRQSTATUS1 */
 326        return s->ints[0];
 327
 328    case 0x1c:  /* GPIO_IRQENABLE1 */
 329    case 0x60:  /* GPIO_CLEARIRQENABLE1 */
 330    case 0x64:  /* GPIO_SETIRQENABLE1 */
 331        return s->mask[0];
 332
 333    case 0x20:  /* GPIO_WAKEUPENABLE */
 334    case 0x80:  /* GPIO_CLEARWKUENA */
 335    case 0x84:  /* GPIO_SETWKUENA */
 336        return s->wumask;
 337
 338    case 0x28:  /* GPIO_IRQSTATUS2 */
 339        return s->ints[1];
 340
 341    case 0x2c:  /* GPIO_IRQENABLE2 */
 342    case 0x70:  /* GPIO_CLEARIRQENABLE2 */
 343    case 0x74:  /* GPIO_SETIREQNEABLE2 */
 344        return s->mask[1];
 345
 346    case 0x30:  /* GPIO_CTRL */
 347        return s->config[1];
 348
 349    case 0x34:  /* GPIO_OE */
 350        return s->dir;
 351
 352    case 0x38:  /* GPIO_DATAIN */
 353        return s->inputs;
 354
 355    case 0x3c:  /* GPIO_DATAOUT */
 356    case 0x90:  /* GPIO_CLEARDATAOUT */
 357    case 0x94:  /* GPIO_SETDATAOUT */
 358        return s->outputs;
 359
 360    case 0x40:  /* GPIO_LEVELDETECT0 */
 361        return s->level[0];
 362
 363    case 0x44:  /* GPIO_LEVELDETECT1 */
 364        return s->level[1];
 365
 366    case 0x48:  /* GPIO_RISINGDETECT */
 367        return s->edge[0];
 368
 369    case 0x4c:  /* GPIO_FALLINGDETECT */
 370        return s->edge[1];
 371
 372    case 0x50:  /* GPIO_DEBOUNCENABLE */
 373        return s->debounce;
 374
 375    case 0x54:  /* GPIO_DEBOUNCINGTIME */
 376        return s->delay;
 377    }
 378
 379    OMAP_BAD_REG(addr);
 380    return 0;
 381}
 382
 383static void omap2_gpio_module_write(void *opaque, hwaddr addr,
 384                uint32_t value)
 385{
 386    struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
 387    uint32_t diff;
 388    int ln;
 389
 390    switch (addr) {
 391    case 0x00:  /* GPIO_REVISION */
 392    case 0x14:  /* GPIO_SYSSTATUS */
 393    case 0x38:  /* GPIO_DATAIN */
 394        OMAP_RO_REG(addr);
 395        break;
 396
 397    case 0x10:  /* GPIO_SYSCONFIG */
 398        if (((value >> 3) & 3) == 3)
 399            fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
 400        if (value & 2)
 401            omap2_gpio_module_reset(s);
 402        s->config[0] = value & 0x1d;
 403        break;
 404
 405    case 0x18:  /* GPIO_IRQSTATUS1 */
 406        if (s->ints[0] & value) {
 407            s->ints[0] &= ~value;
 408            omap2_gpio_module_level_update(s, 0);
 409        }
 410        break;
 411
 412    case 0x1c:  /* GPIO_IRQENABLE1 */
 413        s->mask[0] = value;
 414        omap2_gpio_module_int_update(s, 0);
 415        break;
 416
 417    case 0x20:  /* GPIO_WAKEUPENABLE */
 418        s->wumask = value;
 419        break;
 420
 421    case 0x28:  /* GPIO_IRQSTATUS2 */
 422        if (s->ints[1] & value) {
 423            s->ints[1] &= ~value;
 424            omap2_gpio_module_level_update(s, 1);
 425        }
 426        break;
 427
 428    case 0x2c:  /* GPIO_IRQENABLE2 */
 429        s->mask[1] = value;
 430        omap2_gpio_module_int_update(s, 1);
 431        break;
 432
 433    case 0x30:  /* GPIO_CTRL */
 434        s->config[1] = value & 7;
 435        break;
 436
 437    case 0x34:  /* GPIO_OE */
 438        diff = s->outputs & (s->dir ^ value);
 439        s->dir = value;
 440
 441        value = s->outputs & ~s->dir;
 442        while ((ln = ctz32(diff)) != 32) {
 443            diff &= ~(1 << ln);
 444            qemu_set_irq(s->handler[ln], (value >> ln) & 1);
 445        }
 446
 447        omap2_gpio_module_level_update(s, 0);
 448        omap2_gpio_module_level_update(s, 1);
 449        break;
 450
 451    case 0x3c:  /* GPIO_DATAOUT */
 452        omap2_gpio_module_out_update(s, s->outputs ^ value);
 453        break;
 454
 455    case 0x40:  /* GPIO_LEVELDETECT0 */
 456        s->level[0] = value;
 457        omap2_gpio_module_level_update(s, 0);
 458        omap2_gpio_module_level_update(s, 1);
 459        break;
 460
 461    case 0x44:  /* GPIO_LEVELDETECT1 */
 462        s->level[1] = value;
 463        omap2_gpio_module_level_update(s, 0);
 464        omap2_gpio_module_level_update(s, 1);
 465        break;
 466
 467    case 0x48:  /* GPIO_RISINGDETECT */
 468        s->edge[0] = value;
 469        break;
 470
 471    case 0x4c:  /* GPIO_FALLINGDETECT */
 472        s->edge[1] = value;
 473        break;
 474
 475    case 0x50:  /* GPIO_DEBOUNCENABLE */
 476        s->debounce = value;
 477        break;
 478
 479    case 0x54:  /* GPIO_DEBOUNCINGTIME */
 480        s->delay = value;
 481        break;
 482
 483    case 0x60:  /* GPIO_CLEARIRQENABLE1 */
 484        s->mask[0] &= ~value;
 485        omap2_gpio_module_int_update(s, 0);
 486        break;
 487
 488    case 0x64:  /* GPIO_SETIRQENABLE1 */
 489        s->mask[0] |= value;
 490        omap2_gpio_module_int_update(s, 0);
 491        break;
 492
 493    case 0x70:  /* GPIO_CLEARIRQENABLE2 */
 494        s->mask[1] &= ~value;
 495        omap2_gpio_module_int_update(s, 1);
 496        break;
 497
 498    case 0x74:  /* GPIO_SETIREQNEABLE2 */
 499        s->mask[1] |= value;
 500        omap2_gpio_module_int_update(s, 1);
 501        break;
 502
 503    case 0x80:  /* GPIO_CLEARWKUENA */
 504        s->wumask &= ~value;
 505        break;
 506
 507    case 0x84:  /* GPIO_SETWKUENA */
 508        s->wumask |= value;
 509        break;
 510
 511    case 0x90:  /* GPIO_CLEARDATAOUT */
 512        omap2_gpio_module_out_update(s, s->outputs & value);
 513        break;
 514
 515    case 0x94:  /* GPIO_SETDATAOUT */
 516        omap2_gpio_module_out_update(s, ~s->outputs & value);
 517        break;
 518
 519    default:
 520        OMAP_BAD_REG(addr);
 521        return;
 522    }
 523}
 524
 525static uint32_t omap2_gpio_module_readp(void *opaque, hwaddr addr)
 526{
 527    return omap2_gpio_module_read(opaque, addr & ~3) >> ((addr & 3) << 3);
 528}
 529
 530static void omap2_gpio_module_writep(void *opaque, hwaddr addr,
 531                uint32_t value)
 532{
 533    uint32_t cur = 0;
 534    uint32_t mask = 0xffff;
 535
 536    switch (addr & ~3) {
 537    case 0x00:  /* GPIO_REVISION */
 538    case 0x14:  /* GPIO_SYSSTATUS */
 539    case 0x38:  /* GPIO_DATAIN */
 540        OMAP_RO_REG(addr);
 541        break;
 542
 543    case 0x10:  /* GPIO_SYSCONFIG */
 544    case 0x1c:  /* GPIO_IRQENABLE1 */
 545    case 0x20:  /* GPIO_WAKEUPENABLE */
 546    case 0x2c:  /* GPIO_IRQENABLE2 */
 547    case 0x30:  /* GPIO_CTRL */
 548    case 0x34:  /* GPIO_OE */
 549    case 0x3c:  /* GPIO_DATAOUT */
 550    case 0x40:  /* GPIO_LEVELDETECT0 */
 551    case 0x44:  /* GPIO_LEVELDETECT1 */
 552    case 0x48:  /* GPIO_RISINGDETECT */
 553    case 0x4c:  /* GPIO_FALLINGDETECT */
 554    case 0x50:  /* GPIO_DEBOUNCENABLE */
 555    case 0x54:  /* GPIO_DEBOUNCINGTIME */
 556        cur = omap2_gpio_module_read(opaque, addr & ~3) &
 557                ~(mask << ((addr & 3) << 3));
 558
 559        /* Fall through.  */
 560    case 0x18:  /* GPIO_IRQSTATUS1 */
 561    case 0x28:  /* GPIO_IRQSTATUS2 */
 562    case 0x60:  /* GPIO_CLEARIRQENABLE1 */
 563    case 0x64:  /* GPIO_SETIRQENABLE1 */
 564    case 0x70:  /* GPIO_CLEARIRQENABLE2 */
 565    case 0x74:  /* GPIO_SETIREQNEABLE2 */
 566    case 0x80:  /* GPIO_CLEARWKUENA */
 567    case 0x84:  /* GPIO_SETWKUENA */
 568    case 0x90:  /* GPIO_CLEARDATAOUT */
 569    case 0x94:  /* GPIO_SETDATAOUT */
 570        value <<= (addr & 3) << 3;
 571        omap2_gpio_module_write(opaque, addr, cur | value);
 572        break;
 573
 574    default:
 575        OMAP_BAD_REG(addr);
 576        return;
 577    }
 578}
 579
 580static const MemoryRegionOps omap2_gpio_module_ops = {
 581    .old_mmio = {
 582        .read = {
 583            omap2_gpio_module_readp,
 584            omap2_gpio_module_readp,
 585            omap2_gpio_module_read,
 586        },
 587        .write = {
 588            omap2_gpio_module_writep,
 589            omap2_gpio_module_writep,
 590            omap2_gpio_module_write,
 591        },
 592    },
 593    .endianness = DEVICE_NATIVE_ENDIAN,
 594};
 595
 596static void omap_gpif_reset(DeviceState *dev)
 597{
 598    struct omap_gpif_s *s = OMAP1_GPIO(dev);
 599
 600    omap_gpio_reset(&s->omap1);
 601}
 602
 603static void omap2_gpif_reset(DeviceState *dev)
 604{
 605    struct omap2_gpif_s *s = OMAP2_GPIO(dev);
 606    int i;
 607
 608    for (i = 0; i < s->modulecount; i++) {
 609        omap2_gpio_module_reset(&s->modules[i]);
 610    }
 611    s->autoidle = 0;
 612    s->gpo = 0;
 613}
 614
 615static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr,
 616                                    unsigned size)
 617{
 618    struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
 619
 620    switch (addr) {
 621    case 0x00:  /* IPGENERICOCPSPL_REVISION */
 622        return 0x18;
 623
 624    case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
 625        return s->autoidle;
 626
 627    case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
 628        return 0x01;
 629
 630    case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
 631        return 0x00;
 632
 633    case 0x40:  /* IPGENERICOCPSPL_GPO */
 634        return s->gpo;
 635
 636    case 0x50:  /* IPGENERICOCPSPL_GPI */
 637        return 0x00;
 638    }
 639
 640    OMAP_BAD_REG(addr);
 641    return 0;
 642}
 643
 644static void omap2_gpif_top_write(void *opaque, hwaddr addr,
 645                                 uint64_t value, unsigned size)
 646{
 647    struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
 648
 649    switch (addr) {
 650    case 0x00:  /* IPGENERICOCPSPL_REVISION */
 651    case 0x14:  /* IPGENERICOCPSPL_SYSSTATUS */
 652    case 0x18:  /* IPGENERICOCPSPL_IRQSTATUS */
 653    case 0x50:  /* IPGENERICOCPSPL_GPI */
 654        OMAP_RO_REG(addr);
 655        break;
 656
 657    case 0x10:  /* IPGENERICOCPSPL_SYSCONFIG */
 658        if (value & (1 << 1))                                   /* SOFTRESET */
 659            omap2_gpif_reset(DEVICE(s));
 660        s->autoidle = value & 1;
 661        break;
 662
 663    case 0x40:  /* IPGENERICOCPSPL_GPO */
 664        s->gpo = value & 1;
 665        break;
 666
 667    default:
 668        OMAP_BAD_REG(addr);
 669        return;
 670    }
 671}
 672
 673static const MemoryRegionOps omap2_gpif_top_ops = {
 674    .read = omap2_gpif_top_read,
 675    .write = omap2_gpif_top_write,
 676    .endianness = DEVICE_NATIVE_ENDIAN,
 677};
 678
 679static int omap_gpio_init(SysBusDevice *sbd)
 680{
 681    DeviceState *dev = DEVICE(sbd);
 682    struct omap_gpif_s *s = OMAP1_GPIO(dev);
 683
 684    if (!s->clk) {
 685        hw_error("omap-gpio: clk not connected\n");
 686    }
 687    qdev_init_gpio_in(dev, omap_gpio_set, 16);
 688    qdev_init_gpio_out(dev, s->omap1.handler, 16);
 689    sysbus_init_irq(sbd, &s->omap1.irq);
 690    memory_region_init_io(&s->iomem, OBJECT(s), &omap_gpio_ops, &s->omap1,
 691                          "omap.gpio", 0x1000);
 692    sysbus_init_mmio(sbd, &s->iomem);
 693    return 0;
 694}
 695
 696static int omap2_gpio_init(SysBusDevice *sbd)
 697{
 698    DeviceState *dev = DEVICE(sbd);
 699    struct omap2_gpif_s *s = OMAP2_GPIO(dev);
 700    int i;
 701
 702    if (!s->iclk) {
 703        hw_error("omap2-gpio: iclk not connected\n");
 704    }
 705    if (s->mpu_model < omap3430) {
 706        s->modulecount = (s->mpu_model < omap2430) ? 4 : 5;
 707        memory_region_init_io(&s->iomem, OBJECT(s), &omap2_gpif_top_ops, s,
 708                              "omap2.gpio", 0x1000);
 709        sysbus_init_mmio(sbd, &s->iomem);
 710    } else {
 711        s->modulecount = 6;
 712    }
 713    s->modules = g_new0(struct omap2_gpio_s, s->modulecount);
 714    s->handler = g_new0(qemu_irq, s->modulecount * 32);
 715    qdev_init_gpio_in(dev, omap2_gpio_set, s->modulecount * 32);
 716    qdev_init_gpio_out(dev, s->handler, s->modulecount * 32);
 717    for (i = 0; i < s->modulecount; i++) {
 718        struct omap2_gpio_s *m = &s->modules[i];
 719        if (!s->fclk[i]) {
 720            hw_error("omap2-gpio: fclk%d not connected\n", i);
 721        }
 722        m->revision = (s->mpu_model < omap3430) ? 0x18 : 0x25;
 723        m->handler = &s->handler[i * 32];
 724        sysbus_init_irq(sbd, &m->irq[0]); /* mpu irq */
 725        sysbus_init_irq(sbd, &m->irq[1]); /* dsp irq */
 726        sysbus_init_irq(sbd, &m->wkup);
 727        memory_region_init_io(&m->iomem, OBJECT(s), &omap2_gpio_module_ops, m,
 728                              "omap.gpio-module", 0x1000);
 729        sysbus_init_mmio(sbd, &m->iomem);
 730    }
 731    return 0;
 732}
 733
 734/* Using qdev pointer properties for the clocks is not ideal.
 735 * qdev should support a generic means of defining a 'port' with
 736 * an arbitrary interface for connecting two devices. Then we
 737 * could reframe the omap clock API in terms of clock ports,
 738 * and get some type safety. For now the best qdev provides is
 739 * passing an arbitrary pointer.
 740 * (It's not possible to pass in the string which is the clock
 741 * name, because this device does not have the necessary information
 742 * (ie the struct omap_mpu_state_s*) to do the clockname to pointer
 743 * translation.)
 744 */
 745
 746static Property omap_gpio_properties[] = {
 747    DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
 748    DEFINE_PROP_PTR("clk", struct omap_gpif_s, clk),
 749    DEFINE_PROP_END_OF_LIST(),
 750};
 751
 752static void omap_gpio_class_init(ObjectClass *klass, void *data)
 753{
 754    DeviceClass *dc = DEVICE_CLASS(klass);
 755    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 756
 757    k->init = omap_gpio_init;
 758    dc->reset = omap_gpif_reset;
 759    dc->props = omap_gpio_properties;
 760    /* Reason: pointer property "clk" */
 761    dc->cannot_instantiate_with_device_add_yet = true;
 762}
 763
 764static const TypeInfo omap_gpio_info = {
 765    .name          = TYPE_OMAP1_GPIO,
 766    .parent        = TYPE_SYS_BUS_DEVICE,
 767    .instance_size = sizeof(struct omap_gpif_s),
 768    .class_init    = omap_gpio_class_init,
 769};
 770
 771static Property omap2_gpio_properties[] = {
 772    DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
 773    DEFINE_PROP_PTR("iclk", struct omap2_gpif_s, iclk),
 774    DEFINE_PROP_PTR("fclk0", struct omap2_gpif_s, fclk[0]),
 775    DEFINE_PROP_PTR("fclk1", struct omap2_gpif_s, fclk[1]),
 776    DEFINE_PROP_PTR("fclk2", struct omap2_gpif_s, fclk[2]),
 777    DEFINE_PROP_PTR("fclk3", struct omap2_gpif_s, fclk[3]),
 778    DEFINE_PROP_PTR("fclk4", struct omap2_gpif_s, fclk[4]),
 779    DEFINE_PROP_PTR("fclk5", struct omap2_gpif_s, fclk[5]),
 780    DEFINE_PROP_END_OF_LIST(),
 781};
 782
 783static void omap2_gpio_class_init(ObjectClass *klass, void *data)
 784{
 785    DeviceClass *dc = DEVICE_CLASS(klass);
 786    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 787
 788    k->init = omap2_gpio_init;
 789    dc->reset = omap2_gpif_reset;
 790    dc->props = omap2_gpio_properties;
 791    /* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */
 792    dc->cannot_instantiate_with_device_add_yet = true;
 793}
 794
 795static const TypeInfo omap2_gpio_info = {
 796    .name          = TYPE_OMAP2_GPIO,
 797    .parent        = TYPE_SYS_BUS_DEVICE,
 798    .instance_size = sizeof(struct omap2_gpif_s),
 799    .class_init    = omap2_gpio_class_init,
 800};
 801
 802static void omap_gpio_register_types(void)
 803{
 804    type_register_static(&omap_gpio_info);
 805    type_register_static(&omap2_gpio_info);
 806}
 807
 808type_init(omap_gpio_register_types)
 809