Commit f34c417ba63cd379ad7e1953bc3f520454601e27
1 parent
66450b15
Add OMAP Pulse-width Tone module.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3513 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
103 additions
and
0 deletions
hw/omap.c
| ... | ... | @@ -3509,6 +3509,100 @@ static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s, |
| 3509 | 3509 | omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]); |
| 3510 | 3510 | } |
| 3511 | 3511 | |
| 3512 | +/* Pulse-Width Tone module */ | |
| 3513 | +static uint32_t omap_pwt_read(void *opaque, target_phys_addr_t addr) | |
| 3514 | +{ | |
| 3515 | + struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; | |
| 3516 | + int offset = addr - s->pwt.base; | |
| 3517 | + | |
| 3518 | + switch (offset) { | |
| 3519 | + case 0x00: /* FRC */ | |
| 3520 | + return s->pwt.frc; | |
| 3521 | + case 0x04: /* VCR */ | |
| 3522 | + return s->pwt.vrc; | |
| 3523 | + case 0x08: /* GCR */ | |
| 3524 | + return s->pwt.gcr; | |
| 3525 | + } | |
| 3526 | + OMAP_BAD_REG(addr); | |
| 3527 | + return 0; | |
| 3528 | +} | |
| 3529 | + | |
| 3530 | +static void omap_pwt_write(void *opaque, target_phys_addr_t addr, | |
| 3531 | + uint32_t value) | |
| 3532 | +{ | |
| 3533 | + struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; | |
| 3534 | + int offset = addr - s->pwt.base; | |
| 3535 | + | |
| 3536 | + switch (offset) { | |
| 3537 | + case 0x00: /* FRC */ | |
| 3538 | + s->pwt.frc = value & 0x3f; | |
| 3539 | + break; | |
| 3540 | + case 0x04: /* VRC */ | |
| 3541 | + if ((value ^ s->pwt.vrc) & 1) { | |
| 3542 | + if (value & 1) | |
| 3543 | + printf("%s: %iHz buzz on\n", __FUNCTION__, (int) | |
| 3544 | + /* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */ | |
| 3545 | + ((omap_clk_getrate(s->pwt.clk) >> 3) / | |
| 3546 | + /* Pre-multiplexer divider */ | |
| 3547 | + ((s->pwt.gcr & 2) ? 1 : 154) / | |
| 3548 | + /* Octave multiplexer */ | |
| 3549 | + (2 << (value & 3)) * | |
| 3550 | + /* 101/107 divider */ | |
| 3551 | + ((value & (1 << 2)) ? 101 : 107) * | |
| 3552 | + /* 49/55 divider */ | |
| 3553 | + ((value & (1 << 3)) ? 49 : 55) * | |
| 3554 | + /* 50/63 divider */ | |
| 3555 | + ((value & (1 << 4)) ? 50 : 63) * | |
| 3556 | + /* 80/127 divider */ | |
| 3557 | + ((value & (1 << 5)) ? 80 : 127) / | |
| 3558 | + (107 * 55 * 63 * 127))); | |
| 3559 | + else | |
| 3560 | + printf("%s: silence!\n", __FUNCTION__); | |
| 3561 | + } | |
| 3562 | + s->pwt.vrc = value & 0x7f; | |
| 3563 | + break; | |
| 3564 | + case 0x08: /* GCR */ | |
| 3565 | + s->pwt.gcr = value & 3; | |
| 3566 | + break; | |
| 3567 | + default: | |
| 3568 | + OMAP_BAD_REG(addr); | |
| 3569 | + return; | |
| 3570 | + } | |
| 3571 | +} | |
| 3572 | + | |
| 3573 | +static CPUReadMemoryFunc *omap_pwt_readfn[] = { | |
| 3574 | + omap_badwidth_read8, | |
| 3575 | + omap_badwidth_read8, | |
| 3576 | + omap_pwt_read, | |
| 3577 | +}; | |
| 3578 | + | |
| 3579 | +static CPUWriteMemoryFunc *omap_pwt_writefn[] = { | |
| 3580 | + omap_badwidth_write8, | |
| 3581 | + omap_badwidth_write8, | |
| 3582 | + omap_pwt_write, | |
| 3583 | +}; | |
| 3584 | + | |
| 3585 | +void omap_pwt_reset(struct omap_mpu_state_s *s) | |
| 3586 | +{ | |
| 3587 | + s->pwt.frc = 0; | |
| 3588 | + s->pwt.vrc = 0; | |
| 3589 | + s->pwt.gcr = 0; | |
| 3590 | +} | |
| 3591 | + | |
| 3592 | +static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s, | |
| 3593 | + omap_clk clk) | |
| 3594 | +{ | |
| 3595 | + int iomemtype; | |
| 3596 | + | |
| 3597 | + s->pwt.base = base; | |
| 3598 | + s->pwt.clk = clk; | |
| 3599 | + omap_pwt_reset(s); | |
| 3600 | + | |
| 3601 | + iomemtype = cpu_register_io_memory(0, omap_pwt_readfn, | |
| 3602 | + omap_pwt_writefn, s); | |
| 3603 | + cpu_register_physical_memory(s->pwt.base, 0x800, iomemtype); | |
| 3604 | +} | |
| 3605 | + | |
| 3512 | 3606 | /* General chip reset */ |
| 3513 | 3607 | static void omap_mpu_reset(void *opaque) |
| 3514 | 3608 | { |
| ... | ... | @@ -3662,6 +3756,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, |
| 3662 | 3756 | s->drq[OMAP_DMA_UWIRE_TX], omap_findclk(s, "mpuper_ck")); |
| 3663 | 3757 | |
| 3664 | 3758 | omap_pwl_init(0xfffb5800, s, omap_findclk(s, "clk32-kHz")); |
| 3759 | + omap_pwt_init(0xfffb6000, s, omap_findclk(s, "xtal_osc_12m")); | |
| 3665 | 3760 | |
| 3666 | 3761 | qemu_register_reset(omap_mpu_reset, s); |
| 3667 | 3762 | ... | ... |
hw/omap.h
| ... | ... | @@ -542,6 +542,14 @@ struct omap_mpu_state_s { |
| 542 | 542 | int clk; |
| 543 | 543 | } pwl; |
| 544 | 544 | |
| 545 | + struct { | |
| 546 | + target_phys_addr_t base; | |
| 547 | + uint8_t frc; | |
| 548 | + uint8_t vrc; | |
| 549 | + uint8_t gcr; | |
| 550 | + omap_clk clk; | |
| 551 | + } pwt; | |
| 552 | + | |
| 545 | 553 | /* MPU private TIPB peripherals */ |
| 546 | 554 | struct omap_intr_handler_s *ih[2]; |
| 547 | 555 | ... | ... |