1 /* 2 * TI TWL92230C energy-management companion device for the OMAP24xx. 3 * Aka. Menelaus (N4200 MENELAUS1_V2.2) 4 * 5 * Copyright (C) 2008 Nokia Corporation 6 * Written by Andrzej Zaborowski <andrew@openedhand.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 or 11 * (at your option) version 3 of the License. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include "qemu/osdep.h" 23 #include "qemu-common.h" 24 #include "qemu/timer.h" 25 #include "hw/i2c/i2c.h" 26 #include "hw/irq.h" 27 #include "migration/qemu-file-types.h" 28 #include "migration/vmstate.h" 29 #include "sysemu/sysemu.h" 30 #include "qemu/bcd.h" 31 #include "qemu/module.h" 32 #include "qom/object.h" 33 34 #define VERBOSE 1 35 36 #define TYPE_TWL92230 "twl92230" 37 typedef struct MenelausState MenelausState; 38 DECLARE_INSTANCE_CHECKER(MenelausState, TWL92230, 39 TYPE_TWL92230) 40 41 struct MenelausState { 42 I2CSlave parent_obj; 43 44 int firstbyte; 45 uint8_t reg; 46 47 uint8_t vcore[5]; 48 uint8_t dcdc[3]; 49 uint8_t ldo[8]; 50 uint8_t sleep[2]; 51 uint8_t osc; 52 uint8_t detect; 53 uint16_t mask; 54 uint16_t status; 55 uint8_t dir; 56 uint8_t inputs; 57 uint8_t outputs; 58 uint8_t bbsms; 59 uint8_t pull[4]; 60 uint8_t mmc_ctrl[3]; 61 uint8_t mmc_debounce; 62 struct { 63 uint8_t ctrl; 64 uint16_t comp; 65 QEMUTimer *hz_tm; 66 int64_t next; 67 struct tm tm; 68 struct tm new; 69 struct tm alm; 70 int sec_offset; 71 int alm_sec; 72 int next_comp; 73 } rtc; 74 uint16_t rtc_next_vmstate; 75 qemu_irq out[4]; 76 uint8_t pwrbtn_state; 77 }; 78 79 static inline void menelaus_update(MenelausState *s) 80 { 81 qemu_set_irq(s->out[3], s->status & ~s->mask); 82 } 83 84 static inline void menelaus_rtc_start(MenelausState *s) 85 { 86 s->rtc.next += qemu_clock_get_ms(rtc_clock); 87 timer_mod(s->rtc.hz_tm, s->rtc.next); 88 } 89 90 static inline void menelaus_rtc_stop(MenelausState *s) 91 { 92 timer_del(s->rtc.hz_tm); 93 s->rtc.next -= qemu_clock_get_ms(rtc_clock); 94 if (s->rtc.next < 1) 95 s->rtc.next = 1; 96 } 97 98 static void menelaus_rtc_update(MenelausState *s) 99 { 100 qemu_get_timedate(&s->rtc.tm, s->rtc.sec_offset); 101 } 102 103 static void menelaus_alm_update(MenelausState *s) 104 { 105 if ((s->rtc.ctrl & 3) == 3) 106 s->rtc.alm_sec = qemu_timedate_diff(&s->rtc.alm) - s->rtc.sec_offset; 107 } 108 109 static void menelaus_rtc_hz(void *opaque) 110 { 111 MenelausState *s = (MenelausState *) opaque; 112 113 s->rtc.next_comp --; 114 s->rtc.alm_sec --; 115 s->rtc.next += 1000; 116 timer_mod(s->rtc.hz_tm, s->rtc.next); 117 if ((s->rtc.ctrl >> 3) & 3) { /* EVERY */ 118 menelaus_rtc_update(s); 119 if (((s->rtc.ctrl >> 3) & 3) == 1 && !s->rtc.tm.tm_sec) 120 s->status |= 1 << 8; /* RTCTMR */ 121 else if (((s->rtc.ctrl >> 3) & 3) == 2 && !s->rtc.tm.tm_min) 122 s->status |= 1 << 8; /* RTCTMR */ 123 else if (!s->rtc.tm.tm_hour) 124 s->status |= 1 << 8; /* RTCTMR */ 125 } else 126 s->status |= 1 << 8; /* RTCTMR */ 127 if ((s->rtc.ctrl >> 1) & 1) { /* RTC_AL_EN */ 128 if (s->rtc.alm_sec == 0) 129 s->status |= 1 << 9; /* RTCALM */ 130 /* TODO: wake-up */ 131 } 132 if (s->rtc.next_comp <= 0) { 133 s->rtc.next -= muldiv64((int16_t) s->rtc.comp, 1000, 0x8000); 134 s->rtc.next_comp = 3600; 135 } 136 menelaus_update(s); 137 } 138 139 static void menelaus_reset(I2CSlave *i2c) 140 { 141 MenelausState *s = TWL92230(i2c); 142 143 s->reg = 0x00; 144 145 s->vcore[0] = 0x0c; /* XXX: X-loader needs 0x8c? check! */ 146 s->vcore[1] = 0x05; 147 s->vcore[2] = 0x02; 148 s->vcore[3] = 0x0c; 149 s->vcore[4] = 0x03; 150 s->dcdc[0] = 0x33; /* Depends on wiring */ 151 s->dcdc[1] = 0x03; 152 s->dcdc[2] = 0x00; 153 s->ldo[0] = 0x95; 154 s->ldo[1] = 0x7e; 155 s->ldo[2] = 0x00; 156 s->ldo[3] = 0x00; /* Depends on wiring */ 157 s->ldo[4] = 0x03; /* Depends on wiring */ 158 s->ldo[5] = 0x00; 159 s->ldo[6] = 0x00; 160 s->ldo[7] = 0x00; 161 s->sleep[0] = 0x00; 162 s->sleep[1] = 0x00; 163 s->osc = 0x01; 164 s->detect = 0x09; 165 s->mask = 0x0fff; 166 s->status = 0; 167 s->dir = 0x07; 168 s->outputs = 0x00; 169 s->bbsms = 0x00; 170 s->pull[0] = 0x00; 171 s->pull[1] = 0x00; 172 s->pull[2] = 0x00; 173 s->pull[3] = 0x00; 174 s->mmc_ctrl[0] = 0x03; 175 s->mmc_ctrl[1] = 0xc0; 176 s->mmc_ctrl[2] = 0x00; 177 s->mmc_debounce = 0x05; 178 179 if (s->rtc.ctrl & 1) 180 menelaus_rtc_stop(s); 181 s->rtc.ctrl = 0x00; 182 s->rtc.comp = 0x0000; 183 s->rtc.next = 1000; 184 s->rtc.sec_offset = 0; 185 s->rtc.next_comp = 1800; 186 s->rtc.alm_sec = 1800; 187 s->rtc.alm.tm_sec = 0x00; 188 s->rtc.alm.tm_min = 0x00; 189 s->rtc.alm.tm_hour = 0x00; 190 s->rtc.alm.tm_mday = 0x01; 191 s->rtc.alm.tm_mon = 0x00; 192 s->rtc.alm.tm_year = 2004; 193 menelaus_update(s); 194 } 195 196 static void menelaus_gpio_set(void *opaque, int line, int level) 197 { 198 MenelausState *s = (MenelausState *) opaque; 199 200 if (line < 3) { 201 /* No interrupt generated */ 202 s->inputs &= ~(1 << line); 203 s->inputs |= level << line; 204 return; 205 } 206 207 if (!s->pwrbtn_state && level) { 208 s->status |= 1 << 11; /* PSHBTN */ 209 menelaus_update(s); 210 } 211 s->pwrbtn_state = level; 212 } 213 214 #define MENELAUS_REV 0x01 215 #define MENELAUS_VCORE_CTRL1 0x02 216 #define MENELAUS_VCORE_CTRL2 0x03 217 #define MENELAUS_VCORE_CTRL3 0x04 218 #define MENELAUS_VCORE_CTRL4 0x05 219 #define MENELAUS_VCORE_CTRL5 0x06 220 #define MENELAUS_DCDC_CTRL1 0x07 221 #define MENELAUS_DCDC_CTRL2 0x08 222 #define MENELAUS_DCDC_CTRL3 0x09 223 #define MENELAUS_LDO_CTRL1 0x0a 224 #define MENELAUS_LDO_CTRL2 0x0b 225 #define MENELAUS_LDO_CTRL3 0x0c 226 #define MENELAUS_LDO_CTRL4 0x0d 227 #define MENELAUS_LDO_CTRL5 0x0e 228 #define MENELAUS_LDO_CTRL6 0x0f 229 #define MENELAUS_LDO_CTRL7 0x10 230 #define MENELAUS_LDO_CTRL8 0x11 231 #define MENELAUS_SLEEP_CTRL1 0x12 232 #define MENELAUS_SLEEP_CTRL2 0x13 233 #define MENELAUS_DEVICE_OFF 0x14 234 #define MENELAUS_OSC_CTRL 0x15 235 #define MENELAUS_DETECT_CTRL 0x16 236 #define MENELAUS_INT_MASK1 0x17 237 #define MENELAUS_INT_MASK2 0x18 238 #define MENELAUS_INT_STATUS1 0x19 239 #define MENELAUS_INT_STATUS2 0x1a 240 #define MENELAUS_INT_ACK1 0x1b 241 #define MENELAUS_INT_ACK2 0x1c 242 #define MENELAUS_GPIO_CTRL 0x1d 243 #define MENELAUS_GPIO_IN 0x1e 244 #define MENELAUS_GPIO_OUT 0x1f 245 #define MENELAUS_BBSMS 0x20 246 #define MENELAUS_RTC_CTRL 0x21 247 #define MENELAUS_RTC_UPDATE 0x22 248 #define MENELAUS_RTC_SEC 0x23 249 #define MENELAUS_RTC_MIN 0x24 250 #define MENELAUS_RTC_HR 0x25 251 #define MENELAUS_RTC_DAY 0x26 252 #define MENELAUS_RTC_MON 0x27 253 #define MENELAUS_RTC_YR 0x28 254 #define MENELAUS_RTC_WKDAY 0x29 255 #define MENELAUS_RTC_AL_SEC 0x2a 256 #define MENELAUS_RTC_AL_MIN 0x2b 257 #define MENELAUS_RTC_AL_HR 0x2c 258 #define MENELAUS_RTC_AL_DAY 0x2d 259 #define MENELAUS_RTC_AL_MON 0x2e 260 #define MENELAUS_RTC_AL_YR 0x2f 261 #define MENELAUS_RTC_COMP_MSB 0x30 262 #define MENELAUS_RTC_COMP_LSB 0x31 263 #define MENELAUS_S1_PULL_EN 0x32 264 #define MENELAUS_S1_PULL_DIR 0x33 265 #define MENELAUS_S2_PULL_EN 0x34 266 #define MENELAUS_S2_PULL_DIR 0x35 267 #define MENELAUS_MCT_CTRL1 0x36 268 #define MENELAUS_MCT_CTRL2 0x37 269 #define MENELAUS_MCT_CTRL3 0x38 270 #define MENELAUS_MCT_PIN_ST 0x39 271 #define MENELAUS_DEBOUNCE1 0x3a 272 273 static uint8_t menelaus_read(void *opaque, uint8_t addr) 274 { 275 MenelausState *s = (MenelausState *) opaque; 276 int reg = 0; 277 278 switch (addr) { 279 case MENELAUS_REV: 280 return 0x22; 281 282 case MENELAUS_VCORE_CTRL5: reg ++; 283 case MENELAUS_VCORE_CTRL4: reg ++; 284 case MENELAUS_VCORE_CTRL3: reg ++; 285 case MENELAUS_VCORE_CTRL2: reg ++; 286 case MENELAUS_VCORE_CTRL1: 287 return s->vcore[reg]; 288 289 case MENELAUS_DCDC_CTRL3: reg ++; 290 case MENELAUS_DCDC_CTRL2: reg ++; 291 case MENELAUS_DCDC_CTRL1: 292 return s->dcdc[reg]; 293 294 case MENELAUS_LDO_CTRL8: reg ++; 295 case MENELAUS_LDO_CTRL7: reg ++; 296 case MENELAUS_LDO_CTRL6: reg ++; 297 case MENELAUS_LDO_CTRL5: reg ++; 298 case MENELAUS_LDO_CTRL4: reg ++; 299 case MENELAUS_LDO_CTRL3: reg ++; 300 case MENELAUS_LDO_CTRL2: reg ++; 301 case MENELAUS_LDO_CTRL1: 302 return s->ldo[reg]; 303 304 case MENELAUS_SLEEP_CTRL2: reg ++; 305 case MENELAUS_SLEEP_CTRL1: 306 return s->sleep[reg]; 307 308 case MENELAUS_DEVICE_OFF: 309 return 0; 310 311 case MENELAUS_OSC_CTRL: 312 return s->osc | (1 << 7); /* CLK32K_GOOD */ 313 314 case MENELAUS_DETECT_CTRL: 315 return s->detect; 316 317 case MENELAUS_INT_MASK1: 318 return (s->mask >> 0) & 0xff; 319 case MENELAUS_INT_MASK2: 320 return (s->mask >> 8) & 0xff; 321 322 case MENELAUS_INT_STATUS1: 323 return (s->status >> 0) & 0xff; 324 case MENELAUS_INT_STATUS2: 325 return (s->status >> 8) & 0xff; 326 327 case MENELAUS_INT_ACK1: 328 case MENELAUS_INT_ACK2: 329 return 0; 330 331 case MENELAUS_GPIO_CTRL: 332 return s->dir; 333 case MENELAUS_GPIO_IN: 334 return s->inputs | (~s->dir & s->outputs); 335 case MENELAUS_GPIO_OUT: 336 return s->outputs; 337 338 case MENELAUS_BBSMS: 339 return s->bbsms; 340 341 case MENELAUS_RTC_CTRL: 342 return s->rtc.ctrl; 343 case MENELAUS_RTC_UPDATE: 344 return 0x00; 345 case MENELAUS_RTC_SEC: 346 menelaus_rtc_update(s); 347 return to_bcd(s->rtc.tm.tm_sec); 348 case MENELAUS_RTC_MIN: 349 menelaus_rtc_update(s); 350 return to_bcd(s->rtc.tm.tm_min); 351 case MENELAUS_RTC_HR: 352 menelaus_rtc_update(s); 353 if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */ 354 return to_bcd((s->rtc.tm.tm_hour % 12) + 1) | 355 (!!(s->rtc.tm.tm_hour >= 12) << 7); /* PM_nAM */ 356 else 357 return to_bcd(s->rtc.tm.tm_hour); 358 case MENELAUS_RTC_DAY: 359 menelaus_rtc_update(s); 360 return to_bcd(s->rtc.tm.tm_mday); 361 case MENELAUS_RTC_MON: 362 menelaus_rtc_update(s); 363 return to_bcd(s->rtc.tm.tm_mon + 1); 364 case MENELAUS_RTC_YR: 365 menelaus_rtc_update(s); 366 return to_bcd(s->rtc.tm.tm_year - 2000); 367 case MENELAUS_RTC_WKDAY: 368 menelaus_rtc_update(s); 369 return to_bcd(s->rtc.tm.tm_wday); 370 case MENELAUS_RTC_AL_SEC: 371 return to_bcd(s->rtc.alm.tm_sec); 372 case MENELAUS_RTC_AL_MIN: 373 return to_bcd(s->rtc.alm.tm_min); 374 case MENELAUS_RTC_AL_HR: 375 if ((s->rtc.ctrl >> 2) & 1) /* MODE12_n24 */ 376 return to_bcd((s->rtc.alm.tm_hour % 12) + 1) | 377 (!!(s->rtc.alm.tm_hour >= 12) << 7);/* AL_PM_nAM */ 378 else 379 return to_bcd(s->rtc.alm.tm_hour); 380 case MENELAUS_RTC_AL_DAY: 381 return to_bcd(s->rtc.alm.tm_mday); 382 case MENELAUS_RTC_AL_MON: 383 return to_bcd(s->rtc.alm.tm_mon + 1); 384 case MENELAUS_RTC_AL_YR: 385 return to_bcd(s->rtc.alm.tm_year - 2000); 386 case MENELAUS_RTC_COMP_MSB: 387 return (s->rtc.comp >> 8) & 0xff; 388 case MENELAUS_RTC_COMP_LSB: 389 return (s->rtc.comp >> 0) & 0xff; 390 391 case MENELAUS_S1_PULL_EN: 392 return s->pull[0]; 393 case MENELAUS_S1_PULL_DIR: 394 return s->pull[1]; 395 case MENELAUS_S2_PULL_EN: 396 return s->pull[2]; 397 case MENELAUS_S2_PULL_DIR: 398 return s->pull[3]; 399 400 case MENELAUS_MCT_CTRL3: reg ++; 401 case MENELAUS_MCT_CTRL2: reg ++; 402 case MENELAUS_MCT_CTRL1: 403 return s->mmc_ctrl[reg]; 404 case MENELAUS_MCT_PIN_ST: 405 /* TODO: return the real Card Detect */ 406 return 0; 407 case MENELAUS_DEBOUNCE1: 408 return s->mmc_debounce; 409 410 default: 411 #ifdef VERBOSE 412 printf("%s: unknown register %02x\n", __func__, addr); 413 #endif 414 break; 415 } 416 return 0; 417 } 418 419 static void menelaus_write(void *opaque, uint8_t addr, uint8_t value) 420 { 421 MenelausState *s = (MenelausState *) opaque; 422 int line; 423 int reg = 0; 424 struct tm tm; 425 426 switch (addr) { 427 case MENELAUS_VCORE_CTRL1: 428 s->vcore[0] = (value & 0xe) | MIN(value & 0x1f, 0x12); 429 break; 430 case MENELAUS_VCORE_CTRL2: 431 s->vcore[1] = value; 432 break; 433 case MENELAUS_VCORE_CTRL3: 434 s->vcore[2] = MIN(value & 0x1f, 0x12); 435 break; 436 case MENELAUS_VCORE_CTRL4: 437 s->vcore[3] = MIN(value & 0x1f, 0x12); 438 break; 439 case MENELAUS_VCORE_CTRL5: 440 s->vcore[4] = value & 3; 441 /* XXX 442 * auto set to 3 on M_Active, nRESWARM 443 * auto set to 0 on M_WaitOn, M_Backup 444 */ 445 break; 446 447 case MENELAUS_DCDC_CTRL1: 448 s->dcdc[0] = value & 0x3f; 449 break; 450 case MENELAUS_DCDC_CTRL2: 451 s->dcdc[1] = value & 0x07; 452 /* XXX 453 * auto set to 3 on M_Active, nRESWARM 454 * auto set to 0 on M_WaitOn, M_Backup 455 */ 456 break; 457 case MENELAUS_DCDC_CTRL3: 458 s->dcdc[2] = value & 0x07; 459 break; 460 461 case MENELAUS_LDO_CTRL1: 462 s->ldo[0] = value; 463 break; 464 case MENELAUS_LDO_CTRL2: 465 s->ldo[1] = value & 0x7f; 466 /* XXX 467 * auto set to 0x7e on M_WaitOn, M_Backup 468 */ 469 break; 470 case MENELAUS_LDO_CTRL3: 471 s->ldo[2] = value & 3; 472 /* XXX 473 * auto set to 3 on M_Active, nRESWARM 474 * auto set to 0 on M_WaitOn, M_Backup 475 */ 476 break; 477 case MENELAUS_LDO_CTRL4: 478 s->ldo[3] = value & 3; 479 /* XXX 480 * auto set to 3 on M_Active, nRESWARM 481 * auto set to 0 on M_WaitOn, M_Backup 482 */ 483 break; 484 case MENELAUS_LDO_CTRL5: 485 s->ldo[4] = value & 3; 486 /* XXX 487 * auto set to 3 on M_Active, nRESWARM 488 * auto set to 0 on M_WaitOn, M_Backup 489 */ 490 break; 491 case MENELAUS_LDO_CTRL6: 492 s->ldo[5] = value & 3; 493 break; 494 case MENELAUS_LDO_CTRL7: 495 s->ldo[6] = value & 3; 496 break; 497 case MENELAUS_LDO_CTRL8: 498 s->ldo[7] = value & 3; 499 break; 500 501 case MENELAUS_SLEEP_CTRL2: reg ++; 502 case MENELAUS_SLEEP_CTRL1: 503 s->sleep[reg] = value; 504 break; 505 506 case MENELAUS_DEVICE_OFF: 507 if (value & 1) { 508 menelaus_reset(I2C_SLAVE(s)); 509 } 510 break; 511 512 case MENELAUS_OSC_CTRL: 513 s->osc = value & 7; 514 break; 515 516 case MENELAUS_DETECT_CTRL: 517 s->detect = value & 0x7f; 518 break; 519 520 case MENELAUS_INT_MASK1: 521 s->mask &= 0xf00; 522 s->mask |= value << 0; 523 menelaus_update(s); 524 break; 525 case MENELAUS_INT_MASK2: 526 s->mask &= 0x0ff; 527 s->mask |= value << 8; 528 menelaus_update(s); 529 break; 530 531 case MENELAUS_INT_ACK1: 532 s->status &= ~(((uint16_t) value) << 0); 533 menelaus_update(s); 534 break; 535 case MENELAUS_INT_ACK2: 536 s->status &= ~(((uint16_t) value) << 8); 537 menelaus_update(s); 538 break; 539 540 case MENELAUS_GPIO_CTRL: 541 for (line = 0; line < 3; line ++) { 542 if (((s->dir ^ value) >> line) & 1) { 543 qemu_set_irq(s->out[line], 544 ((s->outputs & ~s->dir) >> line) & 1); 545 } 546 } 547 s->dir = value & 0x67; 548 break; 549 case MENELAUS_GPIO_OUT: 550 for (line = 0; line < 3; line ++) { 551 if ((((s->outputs ^ value) & ~s->dir) >> line) & 1) { 552 qemu_set_irq(s->out[line], (s->outputs >> line) & 1); 553 } 554 } 555 s->outputs = value & 0x07; 556 break; 557 558 case MENELAUS_BBSMS: 559 s->bbsms = 0x0d; 560 break; 561 562 case MENELAUS_RTC_CTRL: 563 if ((s->rtc.ctrl ^ value) & 1) { /* RTC_EN */ 564 if (value & 1) 565 menelaus_rtc_start(s); 566 else 567 menelaus_rtc_stop(s); 568 } 569 s->rtc.ctrl = value & 0x1f; 570 menelaus_alm_update(s); 571 break; 572 case MENELAUS_RTC_UPDATE: 573 menelaus_rtc_update(s); 574 memcpy(&tm, &s->rtc.tm, sizeof(tm)); 575 switch (value & 0xf) { 576 case 0: 577 break; 578 case 1: 579 tm.tm_sec = s->rtc.new.tm_sec; 580 break; 581 case 2: 582 tm.tm_min = s->rtc.new.tm_min; 583 break; 584 case 3: 585 if (s->rtc.new.tm_hour > 23) 586 goto rtc_badness; 587 tm.tm_hour = s->rtc.new.tm_hour; 588 break; 589 case 4: 590 if (s->rtc.new.tm_mday < 1) 591 goto rtc_badness; 592 /* TODO check range */ 593 tm.tm_mday = s->rtc.new.tm_mday; 594 break; 595 case 5: 596 if (s->rtc.new.tm_mon < 0 || s->rtc.new.tm_mon > 11) 597 goto rtc_badness; 598 tm.tm_mon = s->rtc.new.tm_mon; 599 break; 600 case 6: 601 tm.tm_year = s->rtc.new.tm_year; 602 break; 603 case 7: 604 /* TODO set .tm_mday instead */ 605 tm.tm_wday = s->rtc.new.tm_wday; 606 break; 607 case 8: 608 if (s->rtc.new.tm_hour > 23) 609 goto rtc_badness; 610 if (s->rtc.new.tm_mday < 1) 611 goto rtc_badness; 612 if (s->rtc.new.tm_mon < 0 || s->rtc.new.tm_mon > 11) 613 goto rtc_badness; 614 tm.tm_sec = s->rtc.new.tm_sec; 615 tm.tm_min = s->rtc.new.tm_min; 616 tm.tm_hour = s->rtc.new.tm_hour; 617 tm.tm_mday = s->rtc.new.tm_mday; 618 tm.tm_mon = s->rtc.new.tm_mon; 619 tm.tm_year = s->rtc.new.tm_year; 620 break; 621 rtc_badness: 622 default: 623 fprintf(stderr, "%s: bad RTC_UPDATE value %02x\n", 624 __func__, value); 625 s->status |= 1 << 10; /* RTCERR */ 626 menelaus_update(s); 627 } 628 s->rtc.sec_offset = qemu_timedate_diff(&tm); 629 break; 630 case MENELAUS_RTC_SEC: 631 s->rtc.tm.tm_sec = from_bcd(value & 0x7f); 632 break; 633 case MENELAUS_RTC_MIN: 634 s->rtc.tm.tm_min = from_bcd(value & 0x7f); 635 break; 636 case MENELAUS_RTC_HR: 637 s->rtc.tm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */ 638 MIN(from_bcd(value & 0x3f), 12) + ((value >> 7) ? 11 : -1) : 639 from_bcd(value & 0x3f); 640 break; 641 case MENELAUS_RTC_DAY: 642 s->rtc.tm.tm_mday = from_bcd(value); 643 break; 644 case MENELAUS_RTC_MON: 645 s->rtc.tm.tm_mon = MAX(1, from_bcd(value)) - 1; 646 break; 647 case MENELAUS_RTC_YR: 648 s->rtc.tm.tm_year = 2000 + from_bcd(value); 649 break; 650 case MENELAUS_RTC_WKDAY: 651 s->rtc.tm.tm_mday = from_bcd(value); 652 break; 653 case MENELAUS_RTC_AL_SEC: 654 s->rtc.alm.tm_sec = from_bcd(value & 0x7f); 655 menelaus_alm_update(s); 656 break; 657 case MENELAUS_RTC_AL_MIN: 658 s->rtc.alm.tm_min = from_bcd(value & 0x7f); 659 menelaus_alm_update(s); 660 break; 661 case MENELAUS_RTC_AL_HR: 662 s->rtc.alm.tm_hour = (s->rtc.ctrl & (1 << 2)) ? /* MODE12_n24 */ 663 MIN(from_bcd(value & 0x3f), 12) + ((value >> 7) ? 11 : -1) : 664 from_bcd(value & 0x3f); 665 menelaus_alm_update(s); 666 break; 667 case MENELAUS_RTC_AL_DAY: 668 s->rtc.alm.tm_mday = from_bcd(value); 669 menelaus_alm_update(s); 670 break; 671 case MENELAUS_RTC_AL_MON: 672 s->rtc.alm.tm_mon = MAX(1, from_bcd(value)) - 1; 673 menelaus_alm_update(s); 674 break; 675 case MENELAUS_RTC_AL_YR: 676 s->rtc.alm.tm_year = 2000 + from_bcd(value); 677 menelaus_alm_update(s); 678 break; 679 case MENELAUS_RTC_COMP_MSB: 680 s->rtc.comp &= 0xff; 681 s->rtc.comp |= value << 8; 682 break; 683 case MENELAUS_RTC_COMP_LSB: 684 s->rtc.comp &= 0xff << 8; 685 s->rtc.comp |= value; 686 break; 687 688 case MENELAUS_S1_PULL_EN: 689 s->pull[0] = value; 690 break; 691 case MENELAUS_S1_PULL_DIR: 692 s->pull[1] = value & 0x1f; 693 break; 694 case MENELAUS_S2_PULL_EN: 695 s->pull[2] = value; 696 break; 697 case MENELAUS_S2_PULL_DIR: 698 s->pull[3] = value & 0x1f; 699 break; 700 701 case MENELAUS_MCT_CTRL1: 702 s->mmc_ctrl[0] = value & 0x7f; 703 break; 704 case MENELAUS_MCT_CTRL2: 705 s->mmc_ctrl[1] = value; 706 /* TODO update Card Detect interrupts */ 707 break; 708 case MENELAUS_MCT_CTRL3: 709 s->mmc_ctrl[2] = value & 0xf; 710 break; 711 case MENELAUS_DEBOUNCE1: 712 s->mmc_debounce = value & 0x3f; 713 break; 714 715 default: 716 #ifdef VERBOSE 717 printf("%s: unknown register %02x\n", __func__, addr); 718 #endif 719 } 720 } 721 722 static int menelaus_event(I2CSlave *i2c, enum i2c_event event) 723 { 724 MenelausState *s = TWL92230(i2c); 725 726 if (event == I2C_START_SEND) 727 s->firstbyte = 1; 728 729 return 0; 730 } 731 732 static int menelaus_tx(I2CSlave *i2c, uint8_t data) 733 { 734 MenelausState *s = TWL92230(i2c); 735 736 /* Interpret register address byte */ 737 if (s->firstbyte) { 738 s->reg = data; 739 s->firstbyte = 0; 740 } else 741 menelaus_write(s, s->reg ++, data); 742 743 return 0; 744 } 745 746 static uint8_t menelaus_rx(I2CSlave *i2c) 747 { 748 MenelausState *s = TWL92230(i2c); 749 750 return menelaus_read(s, s->reg ++); 751 } 752 753 /* Save restore 32 bit int as uint16_t 754 This is a Big hack, but it is how the old state did it. 755 Or we broke compatibility in the state, or we can't use struct tm 756 */ 757 758 static int get_int32_as_uint16(QEMUFile *f, void *pv, size_t size, 759 const VMStateField *field) 760 { 761 int *v = pv; 762 *v = qemu_get_be16(f); 763 return 0; 764 } 765 766 static int put_int32_as_uint16(QEMUFile *f, void *pv, size_t size, 767 const VMStateField *field, QJSON *vmdesc) 768 { 769 int *v = pv; 770 qemu_put_be16(f, *v); 771 772 return 0; 773 } 774 775 static const VMStateInfo vmstate_hack_int32_as_uint16 = { 776 .name = "int32_as_uint16", 777 .get = get_int32_as_uint16, 778 .put = put_int32_as_uint16, 779 }; 780 781 #define VMSTATE_UINT16_HACK(_f, _s) \ 782 VMSTATE_SINGLE(_f, _s, 0, vmstate_hack_int32_as_uint16, int32_t) 783 784 785 static const VMStateDescription vmstate_menelaus_tm = { 786 .name = "menelaus_tm", 787 .version_id = 0, 788 .minimum_version_id = 0, 789 .fields = (VMStateField[]) { 790 VMSTATE_UINT16_HACK(tm_sec, struct tm), 791 VMSTATE_UINT16_HACK(tm_min, struct tm), 792 VMSTATE_UINT16_HACK(tm_hour, struct tm), 793 VMSTATE_UINT16_HACK(tm_mday, struct tm), 794 VMSTATE_UINT16_HACK(tm_min, struct tm), 795 VMSTATE_UINT16_HACK(tm_year, struct tm), 796 VMSTATE_END_OF_LIST() 797 } 798 }; 799 800 static int menelaus_pre_save(void *opaque) 801 { 802 MenelausState *s = opaque; 803 /* Should be <= 1000 */ 804 s->rtc_next_vmstate = s->rtc.next - qemu_clock_get_ms(rtc_clock); 805 806 return 0; 807 } 808 809 static int menelaus_post_load(void *opaque, int version_id) 810 { 811 MenelausState *s = opaque; 812 813 if (s->rtc.ctrl & 1) /* RTC_EN */ 814 menelaus_rtc_stop(s); 815 816 s->rtc.next = s->rtc_next_vmstate; 817 818 menelaus_alm_update(s); 819 menelaus_update(s); 820 if (s->rtc.ctrl & 1) /* RTC_EN */ 821 menelaus_rtc_start(s); 822 return 0; 823 } 824 825 static const VMStateDescription vmstate_menelaus = { 826 .name = "menelaus", 827 .version_id = 0, 828 .minimum_version_id = 0, 829 .pre_save = menelaus_pre_save, 830 .post_load = menelaus_post_load, 831 .fields = (VMStateField[]) { 832 VMSTATE_INT32(firstbyte, MenelausState), 833 VMSTATE_UINT8(reg, MenelausState), 834 VMSTATE_UINT8_ARRAY(vcore, MenelausState, 5), 835 VMSTATE_UINT8_ARRAY(dcdc, MenelausState, 3), 836 VMSTATE_UINT8_ARRAY(ldo, MenelausState, 8), 837 VMSTATE_UINT8_ARRAY(sleep, MenelausState, 2), 838 VMSTATE_UINT8(osc, MenelausState), 839 VMSTATE_UINT8(detect, MenelausState), 840 VMSTATE_UINT16(mask, MenelausState), 841 VMSTATE_UINT16(status, MenelausState), 842 VMSTATE_UINT8(dir, MenelausState), 843 VMSTATE_UINT8(inputs, MenelausState), 844 VMSTATE_UINT8(outputs, MenelausState), 845 VMSTATE_UINT8(bbsms, MenelausState), 846 VMSTATE_UINT8_ARRAY(pull, MenelausState, 4), 847 VMSTATE_UINT8_ARRAY(mmc_ctrl, MenelausState, 3), 848 VMSTATE_UINT8(mmc_debounce, MenelausState), 849 VMSTATE_UINT8(rtc.ctrl, MenelausState), 850 VMSTATE_UINT16(rtc.comp, MenelausState), 851 VMSTATE_UINT16(rtc_next_vmstate, MenelausState), 852 VMSTATE_STRUCT(rtc.new, MenelausState, 0, vmstate_menelaus_tm, 853 struct tm), 854 VMSTATE_STRUCT(rtc.alm, MenelausState, 0, vmstate_menelaus_tm, 855 struct tm), 856 VMSTATE_UINT8(pwrbtn_state, MenelausState), 857 VMSTATE_I2C_SLAVE(parent_obj, MenelausState), 858 VMSTATE_END_OF_LIST() 859 } 860 }; 861 862 static void twl92230_realize(DeviceState *dev, Error **errp) 863 { 864 MenelausState *s = TWL92230(dev); 865 866 s->rtc.hz_tm = timer_new_ms(rtc_clock, menelaus_rtc_hz, s); 867 /* Three output pins plus one interrupt pin. */ 868 qdev_init_gpio_out(dev, s->out, 4); 869 870 /* Three input pins plus one power-button pin. */ 871 qdev_init_gpio_in(dev, menelaus_gpio_set, 4); 872 873 menelaus_reset(I2C_SLAVE(dev)); 874 } 875 876 static void twl92230_class_init(ObjectClass *klass, void *data) 877 { 878 DeviceClass *dc = DEVICE_CLASS(klass); 879 I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass); 880 881 dc->realize = twl92230_realize; 882 sc->event = menelaus_event; 883 sc->recv = menelaus_rx; 884 sc->send = menelaus_tx; 885 dc->vmsd = &vmstate_menelaus; 886 } 887 888 static const TypeInfo twl92230_info = { 889 .name = TYPE_TWL92230, 890 .parent = TYPE_I2C_SLAVE, 891 .instance_size = sizeof(MenelausState), 892 .class_init = twl92230_class_init, 893 }; 894 895 static void twl92230_register_types(void) 896 { 897 type_register_static(&twl92230_info); 898 } 899 900 type_init(twl92230_register_types) 901