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 | ... | ... |