Revision f34c417b hw/omap.c
b/hw/omap.c | ||
---|---|---|
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 | 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 |
|
Also available in: Unified diff