Improve OMAP3 MMC emulation and merge with OMAP3 upstream
authorJuha Riihimäki <juhriihi@esdhcp035236.research.nokia.com>
Thu, 5 Feb 2009 11:21:07 +0000 (13:21 +0200)
committerJuha Riihimäki <juhriihi@esdhcp035236.research.nokia.com>
Thu, 5 Feb 2009 11:21:07 +0000 (13:21 +0200)
Merged changes from OMAP3 upstream rev94 with development branch. Improved OMAP3 MMC emulation to be able to provide enough functionality for X-Loader. The Beagle board emulation is now able to read X-Loader from SD card and the X-Loader is able to read OS Boot loader (U-Boot) from the SD card.

Makefile
Makefile.target
hw/beagle.c
hw/i2c.h
hw/omap.h
hw/omap3.c
hw/omap3_mmc.c
hw/omap_dss.c
hw/twl4030.c

index f05d6e0..8cbdcda 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -73,7 +73,7 @@ OBJS+=readline.o console.o
 
 OBJS+=irq.o
 OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o
-OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o twl4030.o
+OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o
 OBJS+=tmp105.o lm832x.o
 OBJS+=scsi-disk.o cdrom.o
 OBJS+=scsi-generic.o
index 41ae403..5525d1b 100644 (file)
@@ -709,9 +709,9 @@ OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
 OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
 OBJS+= pflash_cfi01.o gumstix.o
 OBJS+= zaurus.o ide.o serial.o nand.o nand_bpage.o ecc.o spitz.o tosa.o tc6393xb.o
-OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap3_mmc.o omap_i2c.o
+OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap3_mmc.o omap_i2c.o omap3_i2c.o
 OBJS+= omap2.o omap_dss.o soc_dma.o
-OBJS+= omap3.o beagle.o
+OBJS+= omap3.o beagle.o twl4030.o
 OBJS+= omap_sx1.o palm.o tsc210x.o
 OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o
 OBJS+= tsc2005.o bt-hci-csr.o
index aa8c0ae..e2b5079 100644 (file)
@@ -33,7 +33,6 @@
 #include "block.h"\r
 \r
 #define BEAGLE_NAND_CS                 0\r
-#define BEAGLE_TWL4030_ADDR            0x4b    /* Power management */\r
 \r
 #define GPMC_NOR             0\r
 #define GPMC_NAND           1\r
@@ -63,6 +62,7 @@ struct beagle_s {
     struct nand_bflash_s *nand;\r
     struct omap3_lcd_panel_s *lcd_panel;\r
     i2c_bus *i2c;\r
+    struct twl4030_s *twl4030;\r
 };\r
 \r
 \r
@@ -387,15 +387,10 @@ static void beagle_mmc_cs_cb(void *opaque, int line, int level)
 \r
 static void beagle_i2c_setup(struct beagle_s *s)\r
 {\r
-\r
     /* Attach the CPU on one end of our I2C bus.  */\r
-    s->i2c = omap_i2c_bus(s->cpu->i2c[0]);\r
+    s->i2c = omap3_i2c_bus(s->cpu->omap3_i2c[0]);\r
 \r
-    /* Attach a menelaus PM chip */\r
-    i2c_set_slave_address(\r
-                    twl4030_init(s->i2c,\r
-                            s->cpu->irq[0][OMAP_INT_35XX_SYS_NIRQ]),\r
-                    BEAGLE_TWL4030_ADDR);\r
+    s->twl4030 = twl4030_init(s->i2c, s->cpu->irq[0][OMAP_INT_35XX_SYS_NIRQ]);\r
 }\r
 \r
 \r
index f9ff23b..058b402 100644 (file)
--- a/hw/i2c.h
+++ b/hw/i2c.h
@@ -88,6 +88,7 @@ struct i2c_slave *lm8323_init(i2c_bus *bus, qemu_irq nirq);
 void lm832x_key_event(struct i2c_slave *i2c, int key, int state);
 
 /* twl4030.c */
-i2c_slave *twl4030_init(i2c_bus *bus, qemu_irq irq);
+struct twl4030_s;
+struct twl4030_s *twl4030_init(i2c_bus *bus, qemu_irq irq);
 
 #endif
index e1e049a..f7aa3e5 100644 (file)
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -974,6 +974,12 @@ struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
 void omap_i2c_reset(struct omap_i2c_s *s);
 i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
 
+/* omap3_i2c.c */
+struct omap3_i2c_s *omap3_i2c_init(struct omap_target_agent_s *ta,
+                qemu_irq irq, qemu_irq *dma, omap_clk fclk, omap_clk iclk);
+i2c_bus *omap3_i2c_bus(struct omap3_i2c_s *s);
+
+
 # define cpu_is_omap310(cpu)           (cpu->mpu_model == omap310)
 # define cpu_is_omap1510(cpu)          (cpu->mpu_model == omap1510)
 # define cpu_is_omap1610(cpu)          (cpu->mpu_model == omap1610)
@@ -1152,6 +1158,8 @@ struct omap_mpu_state_s {
     struct omap3_scm_s *omap3_scm;
     struct omap3_pm_s *omap3_pm;
     struct omap3_sms_s *omap3_sms;
+    struct omap3_i2c_s *omap3_i2c[3];
+    struct omap3_mmc_s *omap3_mmc;
 };
 
 struct omap_target_agent_s {
index e9bb477..14f5a69 100644 (file)
@@ -1525,10 +1525,8 @@ static inline void omap3_cm_dpll4_update(struct omap3_cm_s *s)
         OMAP3_DEBUG(("omap3_48m_fclk %lld \n",omap_clk_getrate(omap_findclk(s->mpu, "omap3_48m_fclk"))));\r
         OMAP3_DEBUG(("omap3_12m_fclk %lld \n",omap_clk_getrate(omap_findclk(s->mpu, "omap3_12m_fclk"))));\r
 \r
-                       printf("omap3_cm_dpll4_update \n");\r
-\r
+                       //printf("omap3_cm_dpll4_update \n");\r
     }\r
-\r
 }\r
 \r
 static inline void omap3_cm_dpll5_update(struct omap3_cm_s *s)\r
@@ -3947,7 +3945,6 @@ struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
     s->sram_size = OMAP3530_SRAM_SIZE;\r
 \r
     sdindex = drive_get_index(IF_SD, 0, 0);\r
-    //printf("sdindex %d \n",sdindex);\r
     if (sdindex == -1) {\r
         fprintf(stderr, "qemu: missing SecureDigital device\n");\r
         exit(1);\r
@@ -4131,22 +4128,22 @@ struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size,
 \r
      omap_tap_init(omap3_l4ta_get(s->l4, 28), s);\r
 \r
-    s->mmc = omap3_mmc_init(omap3_l4ta_get(s->l4, 29), drives_table[sdindex].bdrv,\r
+    s->omap3_mmc = omap3_mmc_init(omap3_l4ta_get(s->l4, 29), drives_table[sdindex].bdrv,\r
                     s->irq[0][OMAP_INT_35XX_MMC1_IRQ],\r
                     &s->drq[OMAP35XX_DMA_MMC1_TX],\r
                     omap_findclk(s, "omap3_mmc1_fclk"), omap_findclk(s, "omap3_mmc1_iclk"));\r
 \r
-    s->i2c[0] = omap2_i2c_init(omap3_l4ta_get(s->l4, 32),\r
+    s->omap3_i2c[0] = omap3_i2c_init(omap3_l4ta_get(s->l4, 32),\r
                     s->irq[0][OMAP_INT_35XX_I2C1_IRQ],\r
                     &s->drq[OMAP35XX_DMA_I2C1_TX],\r
                     omap_findclk(s, "omap3_i2c1_fclk"),\r
                     omap_findclk(s, "omap3_i2c1_iclk"));\r
-    s->i2c[1] = omap2_i2c_init(omap3_l4ta_get(s->l4, 33),\r
+    s->omap3_i2c[1] = omap3_i2c_init(omap3_l4ta_get(s->l4, 33),\r
                     s->irq[0][OMAP_INT_35XX_I2C2_IRQ],\r
                     &s->drq[OMAP35XX_DMA_I2C2_TX],\r
                     omap_findclk(s, "omap3_i2c2_fclk"),\r
                     omap_findclk(s, "omap3_i2c2_iclk"));\r
-    s->i2c[2] = omap2_i2c_init(omap3_l4ta_get(s->l4, 34),\r
+    s->omap3_i2c[2] = omap3_i2c_init(omap3_l4ta_get(s->l4, 34),\r
                     s->irq[0][OMAP_INT_35XX_I2C3_IRQ],\r
                     &s->drq[OMAP35XX_DMA_I2C3_TX],\r
                     omap_findclk(s, "omap3_i2c3_fclk"),\r
index 5af3137..a7d23d0 100644 (file)
@@ -46,10 +46,10 @@ struct omap3_mmc_s
     uint32_t blk;               /*0x104 */\r
     uint32_t arg;               /*0x108 */\r
     uint32_t cmd;               /*0x10c */\r
-    uint32_t psp10;             /*0x110 */\r
-    uint32_t psp32;             /*0x114 */\r
-    uint32_t psp54;             /*0x118 */\r
-    uint32_t psp76;             /*0x11c */\r
+    uint32_t rsp10;             /*0x110 */\r
+    uint32_t rsp32;             /*0x114 */\r
+    uint32_t rsp54;             /*0x118 */\r
+    uint32_t rsp76;             /*0x11c */\r
     uint32_t data;              /*0x120 */\r
     uint32_t pstate;            /*0x124 */\r
     uint32_t hctl;              /*0x128 */\r
@@ -72,8 +72,8 @@ struct omap3_mmc_s
 \r
     int ddir;\r
     int transfer;\r
-\r
-\r
+    \r
+    uint32_t stat_pending;\r
 };\r
 \r
 \r
@@ -88,7 +88,7 @@ typedef enum
 int test=1;\r
 static void omap3_mmc_interrupts_update(struct omap3_mmc_s *s)\r
 {\r
-    qemu_set_irq(s->irq, !!(s->stat & s->ise & s->ie));\r
+    qemu_set_irq(s->irq, !!((s->stat | s->stat_pending) & s->ise & s->ie));\r
 }\r
 \r
 static void omap3_mmc_fifolevel_update(struct omap3_mmc_s *host,int de)\r
@@ -177,7 +177,7 @@ static void omap3_mmc_transfer(struct omap3_mmc_s *host, int msbs, int ace,
                 {\r
                     host->nblk_counter = (host->blk >> 16) & 0xffff;\r
                     host->transfer = 0;\r
-                    host->stat |= 0x2;        /*tc */\r
+                    host->stat_pending |= 0x2;        /*tc */\r
                     break;\r
                 }\r
             }\r
@@ -185,7 +185,7 @@ static void omap3_mmc_transfer(struct omap3_mmc_s *host, int msbs, int ace,
             {\r
                  /*single block transfer*/\r
                 host->transfer = 0;\r
-                host->stat |= 0x2;    /*tc */\r
+                host->stat_pending |= 0x2;    /*tc */\r
                 break;\r
             }\r
         }\r
@@ -207,6 +207,7 @@ static void omap3_mmc_transfer(struct omap3_mmc_s *host, int msbs, int ace,
        }\r
        /*clear BRR BWR*/\r
        host->stat &= ~0x30;\r
+        host->stat_pending &= ~0x30;\r
     }\r
    else\r
     {\r
@@ -215,15 +216,17 @@ static void omap3_mmc_transfer(struct omap3_mmc_s *host, int msbs, int ace,
        {\r
                host->pstate |= 0x800;  /*BRE*/\r
                host->pstate &= ~0x400;  /*BWE*/  /*can not write*/\r
-               host ->stat |= 0x20;  /*BRR*/\r
-               host ->stat &= ~0x10; /*BWR*/\r
+               host->stat_pending |= 0x20;  /*BRR*/\r
+               host->stat &= ~0x10; /*BWR*/\r
+            host->stat_pending &= ~0x10;\r
        }\r
        else\r
        {\r
                host->pstate &= ~0x800;  /*BRE*/\r
                host->pstate |= 0x400;  /*BWE*/\r
-               host ->stat |= 0x10;  /*BWR*/\r
-               host ->stat &= ~0x20; /*BRR*/\r
+               host->stat_pending |= 0x10;  /*BWR*/\r
+               host->stat &= ~0x20; /*BRR*/\r
+            host->stat_pending &= ~0x20;\r
        }\r
                \r
     }\r
@@ -243,9 +246,9 @@ static void omap3_mmc_command(struct omap3_mmc_s *host, int indx, int dp,
 \r
     //printf("CMD %d host->arg %x \n",indx,host->arg);\r
 \r
-    if ((host->con & 0x2) && (indx == 0))\r
+    if ((host->con & 2) && !indx) /* INIT and CMD0 */\r
     {\r
-        host->stat |= 0x1;\r
+        host->stat_pending |= 0x1;\r
         host->pstate &= 0xfffffffe;\r
         return;\r
     }\r
@@ -282,13 +285,13 @@ static void omap3_mmc_command(struct omap3_mmc_s *host, int indx, int dp,
             break;\r
         }\r
         rsplen = 16;\r
-        host->psp76 = (response[0] << 24) | (response[1] << 16) |\r
+        host->rsp76 = (response[0] << 24) | (response[1] << 16) |\r
             (response[2] << 8) | (response[3] << 0);\r
-        host->psp54 = (response[4] << 24) | (response[5] << 16) |\r
+        host->rsp54 = (response[4] << 24) | (response[5] << 16) |\r
             (response[6] << 8) | (response[7] << 0);\r
-        host->psp32 = (response[8] << 24) | (response[9] << 16) |\r
+        host->rsp32 = (response[8] << 24) | (response[9] << 16) |\r
             (response[10] << 8) | (response[11] << 0);\r
-        host->psp10 = (response[12] << 24) | (response[13] << 16) |\r
+        host->rsp10 = (response[12] << 24) | (response[13] << 16) |\r
             (response[14] << 8) | (response[15] << 0);\r
         break;\r
     case sd_48_bits:\r
@@ -299,7 +302,7 @@ static void omap3_mmc_command(struct omap3_mmc_s *host, int indx, int dp,
             break;\r
         }\r
         rsplen = 4;\r
-        host->psp10 = (response[0] << 24) | (response[1] << 16) |\r
+        host->rsp10 = (response[0] << 24) | (response[1] << 16) |\r
             (response[2] << 8) | (response[3] << 0);\r
         switch (indx)\r
         {\r
@@ -323,36 +326,34 @@ static void omap3_mmc_command(struct omap3_mmc_s *host, int indx, int dp,
     }\r
 \r
     if (rspstatus & mask & host->csre)\r
-        host->stat |= 0x10000000;\r
-    else\r
+        host->stat_pending |= 0x10000000;\r
+    else {\r
         host->stat &= ~0x10000000;\r
+        host->stat_pending &= ~0x10000000;\r
+    }\r
 \r
     if (timeout)\r
-        host->stat |= 0x10000;\r
+        host->stat_pending |= 0x10000;\r
     else\r
-        host->stat |= 0x1;\r
+        host->stat_pending |= 0x1;\r
 \r
     /*do we allow to set the stat bit? */\r
-    host->stat &= host->ie;\r
-\r
-    if (host->stat & 0xffff0000)\r
-        host->stat |= 0x8000;\r
-\r
-       //printf("after command host->stat %x \n",host->stat);\r
-       test = 2;\r
+    host->stat_pending &= host->ie;\r
 \r
+    if (host->stat_pending & 0xffff0000)\r
+        host->stat_pending |= 0x8000;\r
 }\r
 \r
 static void omap3_mmc_reset(struct omap3_mmc_s *s)\r
 {\r
-    s->sysconfig = 0x15;\r
-    s->con = 0x500;\r
-    s->capa = 0xe10080;\r
-    s->rev = 0x26000000;\r
+    s->sysconfig = 0x00000015;\r
+    s->con       = 0x00000500;\r
+    s->pstate    = 0x00040000;\r
+    s->capa      = 0x00e10080;\r
+    s->rev       = 0x26000000;\r
+\r
     s->fifo_start =0;\r
     s->fifo_len =0;\r
-\r
-\r
 }\r
 \r
 static uint32_t omap3_mmc_read(void *opaque, target_phys_addr_t addr)\r
@@ -360,7 +361,7 @@ static uint32_t omap3_mmc_read(void *opaque, target_phys_addr_t addr)
     struct omap3_mmc_s *s = (struct omap3_mmc_s *) opaque;\r
     uint32_t i ;\r
    //if ((offset!=0x12c)&&(offset!=0x120))\r
-   //printf("omap3_mmc_read %x pc %x \n",offset,cpu_single_env->regs[15] );\r
+   //fprintf(stderr, "%s: addr %03x pc %08x \n", __FUNCTION__, addr, cpu_single_env->regs[15]);\r
     switch (addr)\r
     {\r
     case 0x10:\r
@@ -371,24 +372,24 @@ static uint32_t omap3_mmc_read(void *opaque, target_phys_addr_t addr)
         return s->csre;\r
     case 0x28:\r
         return s->systest;\r
-    case 0x2c:\r
+    case 0x2c: /* MMCHS_CON */\r
         return s->con;\r
     case 0x30:\r
         return s->pwcnt;\r
-    case 0x104:\r
+    case 0x104: /* MMCHS_BLK */\r
         return s->blk;\r
-    case 0x108:\r
+    case 0x108: /* MMCHS_ARG */\r
         return s->arg;\r
     case 0x10c:\r
         return s->cmd;\r
     case 0x110:\r
-        return s->psp10;\r
+        return s->rsp10;\r
     case 0x114:\r
-        return s->psp32;\r
+        return s->rsp32;\r
     case 0x118:\r
-        return s->psp54;\r
+        return s->rsp54;\r
     case 0x11c:\r
-        return s->psp76;\r
+        return s->rsp76;\r
     case 0x120:\r
         /*Read Data */\r
         i = s->fifo[s->fifo_start];\r
@@ -401,25 +402,21 @@ static uint32_t omap3_mmc_read(void *opaque, target_phys_addr_t addr)
         s->fifo_start ++;\r
         s->fifo_len --;\r
         s->fifo_start &= 255;\r
-         omap3_mmc_transfer(s,(s->cmd>>5)&1,(s->cmd>>2)&1,(s->cmd>>1)&1,(s->cmd)&1);\r
-        omap3_mmc_fifolevel_update(s,s->cmd*0x1);\r
+        omap3_mmc_transfer(s,(s->cmd>>5)&1,(s->cmd>>2)&1,(s->cmd>>1)&1,(s->cmd)&1);\r
+        omap3_mmc_fifolevel_update(s,s->cmd&1);\r
         omap3_mmc_interrupts_update(s);\r
         return i;\r
 \r
-    case 0x124:\r
+    case 0x124: /* MMCHS_PSTATE */\r
         return s->pstate;\r
     case 0x128:\r
         return s->hctl;\r
-    case 0x12c:\r
-       //printf("s->sysctl | 0x1 %x \n",s->sysctl | 0x1);\r
-        return (s->sysctl | 0x2); /*ICS is alway ready*/\r
-    case 0x130:\r
-       if (test==2)\r
-               {\r
-                       test=3;\r
-                       //printf("s->stat %x \n",s->stat);\r
-               }\r
-        \r
+    case 0x12c: /* MMCHS_SYSCTL */\r
+        return s->sysctl;\r
+    case 0x130: /* MMCHS_STAT */\r
+        s->stat |= s->stat_pending;\r
+        s->stat_pending = 0;\r
+        //fprintf(stderr, "%s: MMCHS_STAT = %08x\n", __FUNCTION__, s->stat);\r
         return s->stat;\r
     case 0x134:\r
         return s->ie;\r
@@ -427,7 +424,7 @@ static uint32_t omap3_mmc_read(void *opaque, target_phys_addr_t addr)
         return s->ise;\r
     case 0x13c:\r
         return s->ac12;\r
-    case 0x140:\r
+    case 0x140: /* MMCHS_CAPA */\r
         return s->capa;\r
     case 0x148:\r
         return s->cur_capa;\r
@@ -445,7 +442,7 @@ static void omap3_mmc_write(void *opaque, target_phys_addr_t addr,
                             uint32_t value)\r
 {\r
     struct omap3_mmc_s *s = (struct omap3_mmc_s *) opaque;\r
-       //printf("omap3_mmc_write %x value %x \n",offset,value);\r
+       //fprintf(stderr, "%s: addr %x value %08x \n", __FUNCTION__, addr, value);\r
     switch (addr)\r
     {\r
     case 0x14:\r
@@ -459,7 +456,8 @@ static void omap3_mmc_write(void *opaque, target_phys_addr_t addr,
         OMAP_RO_REG(addr);\r
         exit(-1);\r
     case 0x10:\r
-        s->sysconfig = value & 0x30f;\r
+        if (value & 2) omap3_mmc_reset(s);\r
+        s->sysconfig = value & 0x31d;\r
         break;\r
     case 0x24:\r
         s->csre = value;\r
@@ -467,38 +465,34 @@ static void omap3_mmc_write(void *opaque, target_phys_addr_t addr,
     case 0x28:\r
         s->systest = value;\r
         break;\r
-    case 0x2c:\r
-        s->con = value & 0x1ffff;\r
-        if (s->con & 0x10)\r
-        {\r
-            fprintf(stderr, "mode =1 is not supported \n");\r
+    case 0x2c: /* MMCHS_CON */\r
+        if (value & 0x10) {\r
+            fprintf(stderr, "%s: SYSTEST mode is not supported\n", __FUNCTION__);\r
             exit(-1);\r
         }\r
-        if (s->con & 0x20)\r
-        {\r
-            fprintf(stderr, "DW8 =1 is not supported \n");\r
+        if (value & 0x20) {\r
+            fprintf(stderr, "%s: 8-bit data width is not supported\n", __FUNCTION__);\r
             exit(-1);\r
         }\r
+        s->con = value & 0x1ffff;\r
         break;\r
     case 0x30:\r
         s->pwcnt = value;\r
         break;\r
-    case 0x104:\r
-        s->blk = value;\r
+    case 0x104: /* MMCHS_BLK */\r
+        s->blk = value & 0xffff07ff;\r
         s->blen_counter = value & 0x7ff;\r
         s->nblk_counter = (value & 0xffff) >> 16;\r
         break;\r
-    case 0x108:\r
+    case 0x108: /* MMCHS_ARG */\r
         s->arg = value;\r
         break;\r
-    case 0x10c:\r
-        /*command */\r
-        s->cmd = value;\r
-        omap3_mmc_command(s, (value >> 24) & 63, (value >> 21) & 1,\r
+    case 0x10c: /* MMCHS_CMD */\r
+        s->cmd = value & 0x3ffb0037;\r
+        omap3_mmc_command(s, (value >> 24) & 0x3f, (value >> 21) & 1,\r
                           (value >> 16) & 3, (value >> 4) & 1);\r
-\r
         omap3_mmc_transfer(s,(s->cmd>>5)&1,(s->cmd>>2)&1,(s->cmd>>1)&1,(s->cmd)&1);\r
-        omap3_mmc_fifolevel_update(s,s->cmd*0x1);\r
+        omap3_mmc_fifolevel_update(s,s->cmd&0x1);\r
         omap3_mmc_interrupts_update(s);\r
         break;\r
     case 0x120:\r
@@ -508,52 +502,57 @@ static void omap3_mmc_write(void *opaque, target_phys_addr_t addr,
         s->fifo[(s->fifo_start + s->fifo_len) & 255] = value;\r
         s->fifo_len ++;\r
         omap3_mmc_transfer(s,(s->cmd>>5)&1,(s->cmd>>2)&1,(s->cmd>>1)&1,(s->cmd)&1);\r
-        omap3_mmc_fifolevel_update(s,s->cmd*0x1);\r
+        omap3_mmc_fifolevel_update(s,s->cmd&0x1);\r
         omap3_mmc_interrupts_update(s);\r
         break;\r
 \r
-    case 0x128:\r
+    case 0x128: /* MMCHS_HCTL */\r
         s->hctl = value & 0xf0f0f02;\r
         break;\r
-    case 0x12c:\r
-        //printf("write value %x\n",value);\r
-        s->sysctl = value & 0x70fffc7;\r
-        //printf("s->sysctl  %x\n",s->sysctl );\r
-        if (value & 0x04000000)\r
-        {\r
-               /*SRD*/\r
-               s->fifo_start =0;\r
-               s->fifo_len =0;\r
-               printf("sizeof(s->fifo) %ld \n",sizeof(s->fifo));\r
-               s->pstate &= ~0xf06;\r
-               s->hctl &= ~0x3000;\r
-               s->stat &= ~0x30;\r
-        }\r
-        if (value & (0x1<<24))\r
-        {\r
-          //printf("hehe \n");\r
-               omap3_mmc_reset(s);\r
-               s->sysctl &= ~(0x1<<24);\r
-        }\r
-        //printf("s->sysctl1  %x\n",s->sysctl );\r
-               \r
+    case 0x12c: /* MMCHS_SYSCTL */\r
+        if (value & 0x04000000) { /* SRD */\r
+            s->data    = 0;\r
+               s->pstate &= ~0x00000f06; /* BRE, BWE, RTA, WTA, DLA, DATI */\r
+               s->hctl   &= ~0x00030000; /* SGBR, CR */\r
+               s->stat   &= ~0x00000034; /* BRR, BWR, BGE */\r
+            s->stat_pending &= ~0x00000034;\r
+               s->fifo_start = 0;\r
+               s->fifo_len = 0;\r
+        }\r
+        if (value & 0x02000000) { /* SRC */\r
+            s->pstate &= ~0x00000001; /* CMDI */\r
+        }\r
+        if (value & 0x01000000) { /* SRA */\r
+            uint32_t capa = s->capa;\r
+            uint32_t cur_capa = s->cur_capa;\r
+            omap3_mmc_reset(s);\r
+            s->capa = capa;\r
+            s->cur_capa = cur_capa;\r
+        }\r
+        value = (value & ~2) | ((value & 1) << 1); /* copy ICE directly to ICS */\r
+        s->sysctl = value & 0x000fffc7;\r
         break;\r
     case 0x130:\r
         value = value & 0X317f0237;\r
         s->stat &= ~value;\r
+        /* stat_pending is NOT cleared */\r
         break;\r
-    case 0x134:\r
+    case 0x134: /* MMCHS_IE */\r
+        if (!(s->con & 0x4000)) /* if CON:OBIE is clear, ignore write to OBI_ENABLE */\r
+            value = (value & ~0x200) | (s->ie & 0x200);\r
         s->ie = value & 0x317f0337;\r
-        if (!(s->ie & 0x100))\r
+        if (!(s->ie & 0x100)) {\r
             s->stat &= ~0x100;\r
+            s->stat_pending &= ~0x100;\r
+        }\r
         omap3_mmc_interrupts_update(s);\r
         break;\r
     case 0x138:\r
         s->ise = value & 0x317f0337;\r
         omap3_mmc_interrupts_update(s);\r
         break;\r
-    case 0x140:\r
-        s->capa = value & 0x7000000;\r
+    case 0x140: /* MMCHS_CAPA */\r
+        s->capa = value & 0x07000000;\r
         break;\r
     case 0x148:\r
         s->cur_capa = value & 0xffffff;\r
index 093a6ae..58283e5 100644 (file)
@@ -34,6 +34,7 @@ struct omap_dss_s {
 
     int autoidle;
     int control;
+    uint32_t sdi_control;
     int enable;
 
     struct omap_dss_panel_s {
@@ -99,6 +100,10 @@ struct omap_dss_s {
         uint16_t hsync;
         struct rfbi_chip_s *chip[2];
     } rfbi;
+    
+    struct {
+        uint32_t irqst;
+    } dsi;
 };
 
 static void omap_dispc_interrupt_update(struct omap_dss_s *s)
@@ -134,6 +139,7 @@ void omap_dss_reset(struct omap_dss_s *s)
 {
     s->autoidle = 0;
     s->control = 0;
+    s->sdi_control = 0;
     s->enable = 0;
 
     s->dig.enable = 0;
@@ -175,6 +181,8 @@ void omap_dss_reset(struct omap_dss_s *s)
     s->dispc.l[0].colinc = 1;
     s->dispc.l[0].wininc = 0;
 
+    s->dsi.irqst = 0;
+    
     omap_rfbi_reset(s);
     omap_dispc_interrupt_update(s);
 }
@@ -192,10 +200,17 @@ static uint32_t omap_diss_read(void *opaque, target_phys_addr_t addr)
 
     case 0x14: /* DSS_SYSSTATUS */
         return 1;                                              /* RESETDONE */
+            
+    case 0x18:  /* DSS_IRQSTATUS */
+        return ((s->dispc.irqst & s->dispc.irqen) ? 0x1 : 0x0)
+            | ((s->dsi.irqst) ? 0x2 : 0x0);
 
     case 0x40: /* DSS_CONTROL */
         return s->control;
 
+    case 0x44:  /* DSS_SDI_CONTROL */
+        return s->sdi_control;
+
     case 0x50: /* DSS_PSA_LCD_REG_1 */
     case 0x54: /* DSS_PSA_LCD_REG_2 */
     case 0x58: /* DSS_PSA_VIDEO_REG */
@@ -237,6 +252,10 @@ static void omap_diss_write(void *opaque, target_phys_addr_t addr,
         s->control = value & 0x3dd;
         break;
 
+    case 0x44: /* DSS_SDI_CONTROL */
+        s->sdi_control = value & 0x000ff80f;
+        break;
+    
     default:
         OMAP_BAD_REGV(addr, value);
         break;
@@ -261,7 +280,7 @@ static uint32_t omap_disc_read(void *opaque, target_phys_addr_t addr)
 
     switch (addr) {
     case 0x000:        /* DISPC_REVISION */
-        return 0x20;
+        return 0x20; // 0x30 in OMAP3
 
     case 0x010:        /* DISPC_SYSCONFIG */
         return s->dispc.idlemode;
@@ -1049,10 +1068,10 @@ static CPUWriteMemoryFunc *omap_im3_writefn[] = {
 };
 
 struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
-                target_phys_addr_t l3_base, DisplayState *ds,
-                qemu_irq irq, qemu_irq drq,
-                omap_clk fck1, omap_clk fck2, omap_clk ck54m,
-                omap_clk ick1, omap_clk ick2)
+                                 target_phys_addr_t l3_base, DisplayState *ds,
+                                 qemu_irq irq, qemu_irq drq,
+                                 omap_clk fck1, omap_clk fck2, omap_clk ck54m,
+                                 omap_clk ick1, omap_clk ick2)
 {
     int iomemtype[5];
     struct omap_dss_s *s = (struct omap_dss_s *)
@@ -1063,22 +1082,21 @@ struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
     s->state = ds;
     omap_dss_reset(s);
 
-    iomemtype[0] = l4_register_io_memory(0, omap_diss1_readfn,
-                    omap_diss1_writefn, s);
-    iomemtype[1] = l4_register_io_memory(0, omap_disc1_readfn,
-                    omap_disc1_writefn, s);
-    iomemtype[2] = l4_register_io_memory(0, omap_rfbi1_readfn,
-                    omap_rfbi1_writefn, s);
-    iomemtype[3] = l4_register_io_memory(0, omap_venc1_readfn,
-                    omap_venc1_writefn, s);
-    iomemtype[4] = cpu_register_io_memory(0, omap_im3_readfn,
-                    omap_im3_writefn, s);
-    omap_l4_attach(ta, 0, iomemtype[0]);
-    omap_l4_attach(ta, 1, iomemtype[1]);
-    omap_l4_attach(ta, 2, iomemtype[2]);
-    omap_l4_attach(ta, 3, iomemtype[3]);
-    cpu_register_physical_memory(l3_base, 0x1000, iomemtype[4]);
-
+        iomemtype[0] = l4_register_io_memory(0, omap_diss1_readfn,
+                                             omap_diss1_writefn, s);
+        iomemtype[1] = l4_register_io_memory(0, omap_disc1_readfn,
+                                             omap_disc1_writefn, s);
+        iomemtype[2] = l4_register_io_memory(0, omap_rfbi1_readfn,
+                                             omap_rfbi1_writefn, s);
+        iomemtype[3] = l4_register_io_memory(0, omap_venc1_readfn,
+                                             omap_venc1_writefn, s);
+        iomemtype[4] = cpu_register_io_memory(0, omap_im3_readfn,
+                                              omap_im3_writefn, s);
+        omap_l4_attach(ta, 0, iomemtype[0]);
+        omap_l4_attach(ta, 1, iomemtype[1]);
+        omap_l4_attach(ta, 2, iomemtype[2]);
+        omap_l4_attach(ta, 3, iomemtype[3]);
+        cpu_register_physical_memory(l3_base, 0x1000, iomemtype[4]);
 #if 0
     if (ds)
         graphic_console_init(ds, omap_update_display,
index b13dce1..aab3a08 100644 (file)
 #include "i2c.h"\r
 #include "sysemu.h"\r
 #include "console.h"\r
+#include "cpu-all.h"\r
 \r
 #define VERBOSE 1\r
 \r
-struct twl4030_s {\r
-    i2c_slave i2c;\r
-    qemu_irq irq;\r
+extern CPUState *cpu_single_env;\r
 \r
+struct twl4030_i2c_s {\r
+    i2c_slave i2c;\r
     int firstbyte;\r
     uint8_t reg;\r
+    qemu_irq irq;\r
+    uint8 reg_data[256];\r
+    struct twl4030_s *twl4030;\r
+};\r
 \r
+struct twl4030_s {\r
+    struct twl4030_i2c_s *i2c[5];\r
 };\r
+\r
+\r
+static uint8_t twl4030_48_read(void *opaque, uint8_t addr)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+    int reg = 0;\r
+       \r
+    printf("twl4030_48_read addr %x\n",addr);\r
+       \r
+    switch (addr)\r
+    {\r
+        default:\r
+#ifdef VERBOSE\r
+            printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
+               //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+#endif\r
+            exit(-1);\r
+            break;\r
+    }\r
+}\r
+\r
+static void twl4030_48_write(void *opaque, uint8_t addr, uint8_t value)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+    int line;\r
+    int reg = 0;\r
+    struct tm tm;\r
+       \r
+    printf("twl4030_48_write addr %x value %x \n",addr,value);\r
+    \r
+    switch (addr)\r
+    {\r
+        default:\r
+#ifdef VERBOSE\r
+            printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
+            //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+#endif\r
+                       exit(-1);\r
+                       break;\r
+    }\r
+}\r
+\r
+static int twl4030_48_tx(i2c_slave *i2c, uint8_t data)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+    /* Interpret register address byte */\r
+    if (s->firstbyte) {\r
+        s->reg = data;\r
+        s->firstbyte = 0;\r
+    } else\r
+        twl4030_48_write(s, s->reg ++, data);\r
+       \r
+    return 0;\r
+}\r
+\r
+static int twl4030_48_rx(i2c_slave *i2c)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+       \r
+    return twl4030_48_read(s, s->reg ++);\r
+}\r
+\r
+static void twl4030_48_reset(i2c_slave *i2c)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+    s->reg = 0x00;\r
+}\r
+\r
+static void twl4030_48_event(i2c_slave *i2c, enum i2c_event event)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+    \r
+    if (event == I2C_START_SEND)\r
+        s->firstbyte = 1;\r
+}\r
+\r
+static uint8_t twl4030_49_read(void *opaque, uint8_t addr)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+    int reg = 0;\r
+       \r
+    printf("twl4030_49_read addr %x\n",addr);\r
+       \r
+    switch (addr)\r
+    {\r
+        default:\r
+#ifdef VERBOSE\r
+            printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
+            //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+#endif\r
+                       exit(-1);\r
+                       break;\r
+    }\r
+}\r
+\r
+static void twl4030_49_write(void *opaque, uint8_t addr, uint8_t value)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+    int line;\r
+    int reg = 0;\r
+    struct tm tm;\r
+       \r
+    //printf("twl4030_49_write addr %x value %x \n", addr, value);\r
+       \r
+    switch (addr)\r
+    {\r
+           case 0xb4:  /*GPIO IMR*/\r
+           case 0xb5:\r
+           case 0xb6:\r
+           case 0xb7:\r
+           case 0xb8:\r
+           case 0xb9:\r
+           case 0xba:\r
+           case 0xbb:\r
+           case 0xbc:\r
+           case 0xc5:\r
+               s->reg_data[addr] = value;\r
+               break;\r
+        default:\r
+#ifdef VERBOSE\r
+            printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,\r
+                   cpu_single_env->regs[15]);\r
+            //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+#endif\r
+            exit(-1);\r
+            break;\r
+    }\r
+}\r
+\r
+\r
+static int twl4030_49_tx(i2c_slave *i2c, uint8_t data)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+    /* Interpret register address byte */\r
+    if (s->firstbyte) {\r
+        s->reg = data;\r
+        s->firstbyte = 0;\r
+    } else\r
+        twl4030_49_write(s, s->reg ++, data);\r
+       \r
+    return 0;\r
+}\r
+\r
+static int twl4030_49_rx(i2c_slave *i2c)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+       \r
+    return twl4030_49_read(s, s->reg ++);\r
+}\r
+\r
+static void twl4030_49_reset(i2c_slave *i2c)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+    s->reg = 0x00;\r
+}\r
+\r
+static void twl4030_49_event(i2c_slave *i2c, enum i2c_event event)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+       \r
+    if (event == I2C_START_SEND)\r
+        s->firstbyte = 1;\r
+}\r
+\r
+static uint8_t twl4030_4a_read(void *opaque, uint8_t addr)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+    int reg = 0;\r
+       \r
+    printf("twl4030_4a_read addr %x\n",addr);\r
+       \r
+    switch (addr)\r
+    {\r
+        default:\r
+#ifdef VERBOSE\r
+               printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
+            //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+#endif\r
+            exit(-1);\r
+            break;\r
+    }\r
+}\r
+\r
+static void twl4030_4a_write(void *opaque, uint8_t addr, uint8_t value)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+    int line;\r
+    int reg = 0;\r
+    struct tm tm;\r
+       \r
+    printf("twl4030_4a_write addr %x value %x \n",addr,value);\r
+       \r
+    switch (addr)\r
+    {\r
+        case 0xee:  /*LED EN*/\r
+        case 0xe4:\r
+        case 0xe9:\r
+        case 0xbb:\r
+        case 0xbc:\r
+        case 0x62:\r
+            s->reg_data[addr] = value;\r
+            break;\r
+        default:\r
+#ifdef VERBOSE\r
+               printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
+               //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+#endif\r
+            exit(-1);\r
+            break;\r
+    }\r
+}\r
+\r
+static int twl4030_4a_tx(i2c_slave *i2c, uint8_t data)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+    /* Interpret register address byte */\r
+    if (s->firstbyte) {\r
+        s->reg = data;\r
+        s->firstbyte = 0;\r
+    } else\r
+        twl4030_4a_write(s, s->reg ++, data);\r
+       \r
+    return 0;\r
+}\r
+\r
+static int twl4030_4a_rx(i2c_slave *i2c)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+       \r
+    return twl4030_4a_read(s, s->reg ++);\r
+}\r
+\r
+static void twl4030_4a_reset(i2c_slave *i2c)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+    s->reg = 0x00;\r
+}\r
+\r
+static void twl4030_4a_event(i2c_slave *i2c, enum i2c_event event)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+       \r
+    if (event == I2C_START_SEND)\r
+        s->firstbyte = 1;\r
+}\r
+\r
+static uint8_t twl4030_4b_read(void *opaque, uint8_t addr)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+    int reg = 0;\r
+       \r
+    printf("twl4030_4b_read addr %x\n",addr);\r
+       \r
+    switch (addr)\r
+    {\r
+        default:\r
+#ifdef VERBOSE\r
+               printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
+               //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+#endif\r
+            exit(-1);\r
+            break;\r
+    }\r
+}\r
+\r
+static void twl4030_4b_write(void *opaque, uint8_t addr, uint8_t value)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) opaque;\r
+       \r
+    printf("twl4030_4b_write addr %x value %x \n",addr,value);\r
+       \r
+    switch (addr)\r
+    {\r
+        case 0x2f:\r
+        case 0x35:\r
+        case 0x3b:\r
+        case 0x44:\r
+        case 0x82:\r
+        case 0x85:\r
+        case 0x7a:\r
+        case 0x7d:\r
+        case 0x8e:\r
+        case 0x91:\r
+        case 0x96:\r
+        case 0x99:\r
+            s->reg_data[addr] = value;\r
+            break;\r
+        default:\r
+#ifdef VERBOSE\r
+               printf("%s: unknown register %02x pc %x \n", __FUNCTION__, addr,cpu_single_env->regs[15] );\r
+               //printf("%s: unknown register %02x \n", __FUNCTION__, addr);\r
+#endif\r
+            exit(-1);\r
+            break;\r
+    }\r
+}\r
+\r
+static int twl4030_4b_tx(i2c_slave *i2c, uint8_t data)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+    /* Interpret register address byte */\r
+    if (s->firstbyte) {\r
+        s->reg = data;\r
+        s->firstbyte = 0;\r
+    } else\r
+        twl4030_4b_write(s, s->reg ++, data);\r
+       \r
+    return 1;\r
+}\r
+\r
+static int twl4030_4b_rx(i2c_slave *i2c)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+       \r
+    return twl4030_4b_read(s, s->reg ++);\r
+}\r
+\r
+static void twl4030_4b_reset(i2c_slave *i2c)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+    s->reg = 0x00;\r
+}\r
+\r
+static void twl4030_4b_event(i2c_slave *i2c, enum i2c_event event)\r
+{\r
+    struct twl4030_i2c_s *s = (struct twl4030_i2c_s *) i2c;\r
+       \r
+    if (event == I2C_START_SEND)\r
+        s->firstbyte = 1;\r
+}\r
+\r
+struct twl4030_s *twl4030_init(i2c_bus *bus, qemu_irq irq)\r
+{\r
+    int i;\r
+       \r
+    struct twl4030_s *s = (struct twl4030_s *) qemu_mallocz(sizeof(*s));\r
+       \r
+    if (!s)\r
+    {\r
+        fprintf(stderr,"can not alloc memory space for twl4030_s \n");\r
+        exit(-1);\r
+    }\r
+    for (i=0;i<5;i++)\r
+    {\r
+        s->i2c[i]=(struct twl4030_i2c_s *)i2c_slave_init(bus, 0, sizeof(struct twl4030_i2c_s));\r
+        s->i2c[i]->irq = irq;\r
+        s->i2c[i]->twl4030 = s;\r
+    }\r
+    s->i2c[0]->i2c.event = twl4030_48_event;\r
+    s->i2c[0]->i2c.recv = twl4030_48_rx;\r
+    s->i2c[0]->i2c.send = twl4030_48_tx;\r
+    twl4030_48_reset(&s->i2c[0]->i2c);\r
+    i2c_set_slave_address((i2c_slave *)&s->i2c[0]->i2c,0x48);\r
+       \r
+    s->i2c[1]->i2c.event = twl4030_49_event;\r
+    s->i2c[1]->i2c.recv = twl4030_49_rx;\r
+    s->i2c[1]->i2c.send = twl4030_49_tx;\r
+    twl4030_49_reset(&s->i2c[1]->i2c);\r
+    i2c_set_slave_address((i2c_slave *)&s->i2c[1]->i2c,0x49);\r
+       \r
+    s->i2c[2]->i2c.event = twl4030_4a_event;\r
+    s->i2c[2]->i2c.recv = twl4030_4a_rx;\r
+    s->i2c[2]->i2c.send = twl4030_4a_tx;\r
+    twl4030_4a_reset(&s->i2c[2]->i2c);\r
+    i2c_set_slave_address((i2c_slave *)&s->i2c[2]->i2c,0x4a);\r
+       \r
+    s->i2c[3]->i2c.event = twl4030_4b_event;\r
+    s->i2c[3]->i2c.recv = twl4030_4b_rx;\r
+    s->i2c[3]->i2c.send = twl4030_4b_tx;\r
+    twl4030_4b_reset(&s->i2c[3]->i2c);\r
+    i2c_set_slave_address((i2c_slave *)&s->i2c[3]->i2c,0x4b);\r
+    /*TODO:other group*/\r
+       \r
+       \r
+    //register_savevm("menelaus", -1, 0, menelaus_save, menelaus_load, s);\r
+    return s;\r
+}\r
+\r
+#if 0\r
 static uint8_t twl4030_read(void *opaque, uint8_t addr)\r
 {\r
 //    struct twl4030_s *s = (struct twl4030_s *) opaque;\r
@@ -133,6 +519,6 @@ i2c_slave *twl4030_init(i2c_bus *bus, qemu_irq irq)
 \r
     return &s->i2c;\r
 }\r
-\r
+#endif\r
  \r
 \r