void xenon_sound_init(void) { // reset DAC (init from scratch) xenon_gpio_control(5,0x1000,0x1000); xenon_gpio_control(0,0x1000,0x1000); xenon_gpio_control(4,0x1000,0x1000); if(xenos_is_hdmi){ // HDMI audio enable xenon_smc_i2c_write(0x0214, 0x11); xenon_smc_i2c_write(0x0202, 0x03); xenon_smc_i2c_write(0x0203, 0x00); xenon_smc_i2c_write(0x0204, 0x18); xenon_smc_i2c_write(0x0205, 0x00); xenon_smc_i2c_write(0x021d, 0x40); xenon_smc_i2c_write(0x0221, 0x02); xenon_smc_i2c_write(0x0222, 0x2b); xenon_smc_i2c_write(0x022f,0x01); xenon_smc_i2c_write(0x023e,0x3f); xenon_smc_i2c_write(0x02df,0x10);// Av mute ? } static unsigned char smc_snd[32] = {0x8d, 1, 1}; xenon_smc_send_message(smc_snd); uint32_t *descr = memalign(256, 0x20 * 8); int descr_base = ((int)descr) & 0x1FFFFFFF; buffer_len = 64*1024; buffer = memalign(256, buffer_len); memset(buffer, 0, buffer_len); memdcbst(buffer, buffer_len); int buffer_base = ((int)buffer) & 0x1fffffff; int i; for (i = 0; i < 0x20; ++i) { descr[i * 2] = __builtin_bswap32(buffer_base + (buffer_len/0x20) * i); descr[i * 2 + 1] = __builtin_bswap32(0x80000000 | (buffer_len/0x20)); } memdcbst(descr, 0x20 * 2 * 4); write32(snd_base + 8, 0); write32(snd_base + 8, 0x2000000); write32(snd_base + 0, descr_base); write32(snd_base + 8, 0x1d08001c); write32(snd_base + 0xC, 0x1c); // write32(snd_base + 8, read32(snd_base) | 0x1000000); wptr = 0; }
void xenon_sound_submit(void *data, int len) { int i = 0; while (len) { int av = buffer_len - wptr; if (av > len) av = len; memcpy(buffer + wptr, data + i, av); memdcbst(buffer + wptr, av); i += av; wptr += av; len -= av; if (wptr == buffer_len) wptr = 0; } int cur_descr = (wptr / (buffer_len/0x20) -1) & 0x1f; write32(snd_base + 4, cur_descr << 8); write32(snd_base + 8, read32(snd_base) | 0x1000000); }
static int xenon_ata_dma_read(struct xenon_ata_device *dev, char *buf, int size) { assert(!((uint32_t) buf & 3)); uint32_t i, b; int s, ss; if (xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 1) return xenon_ata_regget(dev, XENON_ATA_REG_ERROR); // printf("ATA DMA %p %d\n",buf,size); /* build PRDs */ i = 0; s = size; b = ((uint32_t) buf)&0x7fffffff; while (s > 0) { dev->prds[i].address = __builtin_bswap32(b); ss = MIN(s, 0x10000 - (b & 0xffff)); // a PRD buffer mustn't cross a 64k boundary s -= ss; b += ss; dev->prds[i].size_flags = __builtin_bswap32((ss & 0xffff) | (s > 0 ? 0 : 0x80000000)); // printf("PRD %08x %d\n",b,ss); ++i; if (i >= MAX_PRDS && s > 0) { printf("ATA DMA transfer too big\n"); return -1; } } memdcbst(dev->prds, MAX_PRDS * sizeof (struct xenon_ata_dma_prd)); /* setup DMA regs */ xenon_ata_write_data2(dev, XENON_ATA_DMA_TABLE_OFS, __builtin_bswap32((uint32_t) dev->prds & 0x7fffffff)); xenon_ata_regset2(dev, XENON_ATA_DMA_CMD, XENON_ATA_DMA_WR); xenon_ata_regset2(dev, XENON_ATA_DMA_STATUS, 0); /* flush buffer from cache */ memdcbf(buf, size); /* start DMA */ xenon_ata_regset2(dev, XENON_ATA_DMA_CMD, XENON_ATA_DMA_WR | XENON_ATA_DMA_START); /* wait for DMA end */ while (xenon_ata_regget2(dev, XENON_ATA_DMA_STATUS) & XENON_ATA_DMA_ACTIVE); /* stop DMA ctrlr */ xenon_ata_regset2(dev, XENON_ATA_DMA_CMD, 0); if (xenon_ata_regget2(dev, XENON_ATA_DMA_STATUS) & XENON_ATA_DMA_ERR) { printf("ATA DMA transfer error\n"); return -1; } if (xenon_ata_regget(dev, XENON_ATA_REG_STATUS) & 1) return xenon_ata_regget(dev, XENON_ATA_REG_ERROR); /* reload buffer into cache */ memdcbt(buf, size); return 0; };