From e69d567d9ebf7d236ff9663b11ac396cc71dcd75 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Fri, 12 Dec 2008 11:01:07 +0000 Subject: [PATCH] Bring consistency to pcm implementation and samplerate handling. Less low-level duplication. A small test_sampr fix so it works on coldfire again. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19400 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/test_sampr.c | 2 +- firmware/drivers/audio/as3514.c | 4 +- firmware/drivers/audio/tlv320.c | 16 +-- firmware/drivers/audio/tsc2100.c | 6 +- firmware/drivers/audio/uda1380.c | 35 ++++-- firmware/drivers/audio/wm8731.c | 39 +++---- firmware/drivers/audio/wm8751.c | 14 ++- firmware/drivers/audio/wm8758.c | 6 +- firmware/drivers/audio/wm8975.c | 6 +- firmware/drivers/audio/wm8978.c | 24 ++--- firmware/drivers/audio/wm8985.c | 6 +- firmware/export/as3514.h | 2 +- firmware/export/config-gigabeat.h | 6 ++ firmware/export/config-mrobe100.h | 1 + firmware/export/pcm.h | 6 +- firmware/export/pp5002.h | 58 ++++++++-- firmware/export/pp5020.h | 3 + firmware/export/tlv320.h | 2 +- firmware/export/uda1380.h | 4 +- firmware/export/wm8731.h | 2 +- firmware/export/wm8758.h | 2 +- firmware/export/wm8975.h | 2 +- firmware/export/wm8978.h | 2 +- firmware/pcm.c | 68 ++++++++++-- firmware/target/arm/as3525/pcm-as3525.c | 11 +- firmware/target/arm/audio-pp.c | 18 +++- firmware/target/arm/i2s-pp.c | 14 +-- .../target/arm/imx31/gigabeat-s/pcm-imx31.c | 75 +------------ firmware/target/arm/pcm-pp.c | 56 +--------- firmware/target/arm/pcm-telechips.c | 13 +-- firmware/target/arm/pnx0101/pcm-pnx0101.c | 13 +-- .../arm/s3c2440/gigabeat-fx/pcm-meg-fx.c | 59 ++-------- .../creative-zvm/pcm-creativezvm.c | 33 ++---- .../arm/tms320dm320/mrobe-500/pcm-mr500.c | 8 +- firmware/target/coldfire/pcm-coldfire.c | 101 +++++++----------- .../target/mips/ingenic_jz47xx/pcm-jz4740.c | 7 +- uisimulator/sdl/sound.c | 41 ++----- 37 files changed, 316 insertions(+), 449 deletions(-) mode change 100755 => 100644 firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c diff --git a/apps/plugins/test_sampr.c b/apps/plugins/test_sampr.c index 1131a7a989..a23b907048 100644 --- a/apps/plugins/test_sampr.c +++ b/apps/plugins/test_sampr.c @@ -46,7 +46,7 @@ static unsigned int gen_thread_id; #define OUTPUT_CHUNK_SAMPLES 1152 #define OUTPUT_CHUNK_SIZE (OUTPUT_CHUNK_SAMPLES*sizeof(int16_t)*2) static uint16_t output_buf[OUTPUT_CHUNK_COUNT][OUTPUT_CHUNK_SAMPLES*2] - IBSS_ATTR __attribute__((aligned(4))); + __attribute__((aligned(4))); static int output_head IBSS_ATTR; static int output_tail IBSS_ATTR; static int output_step IBSS_ATTR; diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c index 825cf51655..551a9df9b7 100644 --- a/firmware/drivers/audio/as3514.c +++ b/firmware/drivers/audio/as3514.c @@ -290,9 +290,9 @@ void audiohw_close(void) sleep(HZ/4); } -void audiohw_set_sample_rate(int sampling_control) +void audiohw_set_frequency(int fsel) { - (void)sampling_control; + (void)fsel; } #if defined(HAVE_RECORDING) diff --git a/firmware/drivers/audio/tlv320.c b/firmware/drivers/audio/tlv320.c index b2c5be8e61..c85627e683 100644 --- a/firmware/drivers/audio/tlv320.c +++ b/firmware/drivers/audio/tlv320.c @@ -152,21 +152,21 @@ void audiohw_postinit(void) * 44100: 1 = MCLK MCLK SCLK, LRCK: Audio Clk / 4 (default) * 88200: 2 = MCLK*2 MCLK SCLK, LRCK: Audio Clk / 2 */ -void audiohw_set_frequency(unsigned fsel) +void audiohw_set_frequency(int fsel) { /* All rates available for 11.2896MHz besides 8.021 */ - unsigned char values_src[3] = + static const unsigned char values_src[HW_NUM_FREQ] = { - /* Fs: */ - (0x8 << 2) | SRC_CLKIN, /* 11025, 22050 */ - (0x8 << 2), /* 44100 */ - (0xf << 2), /* 88200 */ + [HW_FREQ_11] = (0x8 << 2) | SRC_CLKIN, + [HW_FREQ_22] = (0x8 << 2) | SRC_CLKIN, + [HW_FREQ_44] = (0x8 << 2), + [HW_FREQ_88] = (0xf << 2), }; unsigned value_dap, value_pc; - if (fsel >= ARRAYLEN(values_src)) - fsel = 1; + if ((unsigned)fsel >= HW_NUM_FREQ) + fsel = HW_FREQ_DEFAULT; /* Temporarily turn off the DAC and ADC before switching sample rates or they don't choose their filters correctly */ diff --git a/firmware/drivers/audio/tsc2100.c b/firmware/drivers/audio/tsc2100.c index e0e2c53e69..11f30a8560 100644 --- a/firmware/drivers/audio/tsc2100.c +++ b/firmware/drivers/audio/tsc2100.c @@ -130,7 +130,7 @@ void audiohw_close(void) } -void audiohw_set_sample_rate(int sampling_control) -{ - (void)sampling_control; +void audiohw_set_frequency(int fsel) + + (void)fsel; } diff --git a/firmware/drivers/audio/uda1380.c b/firmware/drivers/audio/uda1380.c index a0e7ef56d8..efe02caca8 100644 --- a/firmware/drivers/audio/uda1380.c +++ b/firmware/drivers/audio/uda1380.c @@ -218,23 +218,38 @@ static void reset(void) * 11025: 0 = 6.25 to 12.5 MCLK/2 SCLK, LRCK: Audio Clk / 16 * 22050: 1 = 12.5 to 25 MCLK/2 SCLK, LRCK: Audio Clk / 8 * 44100: 2 = 25 to 50 MCLK SCLK, LRCK: Audio Clk / 4 (default) - * 88200: 3 = 50 to 100 MCLK SCLK, LRCK: Audio Clk / 2 <= TODO: Needs WSPLL + * 88200: 3 = 50 to 100 MCLK SCLK, LRCK: Audio Clk / 2 */ -void audiohw_set_frequency(unsigned fsel) +void audiohw_set_frequency(int fsel) { - static const unsigned short values_reg[4][2] = + static const unsigned short values_reg[HW_NUM_FREQ][2] = { - /* Fs: */ - { 0, WSPLL_625_125 | SYSCLK_512FS }, /* 11025 */ - { 0, WSPLL_125_25 | SYSCLK_256FS }, /* 22050 */ - { MIX_CTL_SEL_NS, WSPLL_25_50 | SYSCLK_256FS }, /* 44100 */ - { MIX_CTL_SEL_NS, WSPLL_50_100 | SYSCLK_256FS }, /* 88200 */ + [HW_FREQ_11] = /* Fs: */ + { + 0, + WSPLL_625_125 | SYSCLK_512FS + }, + [HW_FREQ_22] = + { + 0, + WSPLL_125_25 | SYSCLK_256FS + }, + [HW_FREQ_44] = + { + MIX_CTL_SEL_NS, + WSPLL_25_50 | SYSCLK_256FS + }, + [HW_FREQ_88] = + { + MIX_CTL_SEL_NS, + WSPLL_50_100 | SYSCLK_256FS + }, }; const unsigned short *ent; - if (fsel >= ARRAYLEN(values_reg)) - fsel = 2; + if ((unsigned)fsel >= HW_NUM_FREQ) + fsel = HW_FREQ_DEFAULT; ent = values_reg[fsel]; diff --git a/firmware/drivers/audio/wm8731.c b/firmware/drivers/audio/wm8731.c index c065de620a..2b74d718b0 100644 --- a/firmware/drivers/audio/wm8731.c +++ b/firmware/drivers/audio/wm8731.c @@ -224,35 +224,24 @@ void audiohw_close(void) /* 2) Remove the WM codec supplies. */ } -void audiohw_set_sample_rate(int sampling_control) +void audiohw_set_frequency(int fsel) { - int rate; - - switch(sampling_control) + /* For 24MHz MCLK */ + static const unsigned char srctrl_table[HW_NUM_FREQ] = { - case SAMPR_96: - rate = WMC_USB24_96000HZ; - break; - case SAMPR_88: - rate = WMC_USB24_88200HZ; - break; - case SAMPR_48: - rate = WMC_USB24_48000HZ; - break; - default: - case SAMPR_44: - rate = WMC_USB24_44100HZ; - break; - case SAMPR_32: - rate = WMC_USB24_32000HZ; - break; - case SAMPR_8: - rate = WMC_USB24_8000HZ; - break; - } + [HW_FREQ_8] = WMC_USB24_8000HZ, + [HW_FREQ_32] = WMC_USB24_32000HZ, + [HW_FREQ_44] = WMC_USB24_44100HZ, + [HW_FREQ_48] = WMC_USB24_48000HZ, + [HW_FREQ_88] = WMC_USB24_88200HZ, + [HW_FREQ_96] = WMC_USB24_96000HZ, + }; + + if ((unsigned)fsel >= HW_NUM_FREQ) + fsel = HW_FREQ_DEFAULT; codec_set_active(false); - wmc_write(SAMPCTRL, rate); + wmc_write(SAMPCTRL, srctrl_table[fsel]); codec_set_active(true); } diff --git a/firmware/drivers/audio/wm8751.c b/firmware/drivers/audio/wm8751.c index 2e0eb06dbf..79c7396629 100644 --- a/firmware/drivers/audio/wm8751.c +++ b/firmware/drivers/audio/wm8751.c @@ -229,8 +229,18 @@ void audiohw_close(void) wmcodec_write(PWRMGMT1, 0x0); } -/* Note: Disable output before calling this function */ void audiohw_set_frequency(int fsel) { - wmcodec_write(CLOCKING, fsel); + static const unsigned char srctrl_table[HW_NUM_FREQ] = + { + HW_HAVE_11_([HW_FREQ_11] = CODEC_SRCTRL_11025HZ,) + HW_HAVE_22_([HW_FREQ_22] = CODEC_SRCTRL_22050HZ,) + HW_HAVE_44_([HW_FREQ_44] = CODEC_SRCTRL_44100HZ,) + HW_HAVE_88_([HW_FREQ_88] = CODEC_SRCTRL_88200HZ,) + }; + + if ((unsigned)fsel >= HW_NUM_FREQ) + fsel = HW_FREQ_DEFAULT; + + wmcodec_write(CLOCKING, srctrl_table[fsel]); } diff --git a/firmware/drivers/audio/wm8758.c b/firmware/drivers/audio/wm8758.c index 8ebfbe8e26..defc415f98 100644 --- a/firmware/drivers/audio/wm8758.c +++ b/firmware/drivers/audio/wm8758.c @@ -107,7 +107,7 @@ void audiohw_preinit(void) wmcodec_write(OUTCTRL, OUTCTRL_VROI); wmcodec_write(CLKCTRL, CLKCTRL_MS); /* WM8758 is clock master */ - audiohw_set_sample_rate(WM8758_44100HZ); + audiohw_set_sample_rate(HW_FREQ_44); wmcodec_write(LOUTMIX, LOUTMIX_DACL2LMIX); wmcodec_write(ROUTMIX, ROUTMIX_DACR2RMIX); @@ -170,10 +170,10 @@ void audiohw_close(void) } /* Note: Disable output before calling this function */ -void audiohw_set_sample_rate(int sampling_control) +void audiohw_set_frequency(int fsel) { /**** We force 44.1KHz for now. ****/ - (void)sampling_control; + (void)fsel; /* setup PLL for MHZ=11.2896 */ wmcodec_write(PLLN, PLLN_PLLPRESCALE | 0x7); diff --git a/firmware/drivers/audio/wm8975.c b/firmware/drivers/audio/wm8975.c index aa519e8819..f14890db74 100644 --- a/firmware/drivers/audio/wm8975.c +++ b/firmware/drivers/audio/wm8975.c @@ -145,7 +145,7 @@ void audiohw_preinit(void) wm8975_write(DAPCTRL, wm8975_regs[DAPCTRL] ); - audiohw_set_sample_rate(WM8975_44100HZ); + wmcodec_write(SAMPCTRL, WM8975_44100HZ); /* set the volume to -6dB */ wmcodec_write(LOUT1VOL, LOUT1VOL_LO1ZC | IPOD_PCM_LEVEL); @@ -224,9 +224,9 @@ void audiohw_close(void) } /* Note: Disable output before calling this function */ -void audiohw_set_sample_rate(int sampling_control) +void audiohw_set_frequency(int fsel) { - wmcodec_write(SAMPCTRL, sampling_control); + (void)fsel; } #ifdef HAVE_RECORDING diff --git a/firmware/drivers/audio/wm8978.c b/firmware/drivers/audio/wm8978.c index 6a7c974f43..d8bf05063f 100644 --- a/firmware/drivers/audio/wm8978.c +++ b/firmware/drivers/audio/wm8978.c @@ -363,9 +363,9 @@ void audiohw_mute(bool mute) } } -void audiohw_set_frequency(int sampling_control) +void audiohw_set_frequency(int fsel) { - /* For 16.9344MHz MCLK */ + /* For 16.9344MHz MCLK, codec as master. */ static const struct { uint32_t plln : 8; @@ -374,7 +374,7 @@ void audiohw_set_frequency(int sampling_control) uint32_t pllk3 : 9; unsigned char mclkdiv; unsigned char filter; - } sctrl_table[HW_NUM_FREQ] = + } srctrl_table[HW_NUM_FREQ] = { [HW_FREQ_8] = /* PLL = 65.536MHz */ { @@ -450,16 +450,14 @@ void audiohw_set_frequency(int sampling_control) unsigned int plln; unsigned int mclkdiv; - if ((unsigned)sampling_control >= ARRAYLEN(sctrl_table)) - sampling_control = HW_FREQ_DEFAULT; - + if ((unsigned)fsel >= HW_NUM_FREQ) + fsel = HW_FREQ_DEFAULT; /* Setup filters. */ - wmc_write(WMC_ADDITIONAL_CTRL, - sctrl_table[sampling_control].filter); + wmc_write(WMC_ADDITIONAL_CTRL, srctrl_table[fsel].filter); - plln = sctrl_table[sampling_control].plln; - mclkdiv = sctrl_table[sampling_control].mclkdiv; + plln = srctrl_table[fsel].plln; + mclkdiv = srctrl_table[fsel].mclkdiv; if (plln != 0) { @@ -467,9 +465,9 @@ void audiohw_set_frequency(int sampling_control) /* Program PLL. */ wmc_write(WMC_PLL_N, plln); - wmc_write(WMC_PLL_K1, sctrl_table[sampling_control].pllk1); - wmc_write(WMC_PLL_K2, sctrl_table[sampling_control].pllk2); - wmc_write(WMC_PLL_K3, sctrl_table[sampling_control].pllk3); + wmc_write(WMC_PLL_K1, srctrl_table[fsel].pllk1); + wmc_write(WMC_PLL_K2, srctrl_table[fsel].pllk2); + wmc_write(WMC_PLL_K3, srctrl_table[fsel].pllk3); /* Turn on PLL. */ wmc_set(WMC_POWER_MANAGEMENT1, WMC_PLLEN); diff --git a/firmware/drivers/audio/wm8985.c b/firmware/drivers/audio/wm8985.c index 0467e3718a..f7b2e510ae 100644 --- a/firmware/drivers/audio/wm8985.c +++ b/firmware/drivers/audio/wm8985.c @@ -235,12 +235,12 @@ void audiohw_close(void) } /* Note: Disable output before calling this function */ -void audiohw_set_sample_rate(int sampling_control) +void audiohw_set_sample_rate(int fsel) { /* Currently the WM8985 acts as slave to the SoC I2S controller, so no setup is needed here. This seems to be in contrast to every other WM driver in Rockbox, so this may need to change in the future. */ - (void)sampling_control; + (void)fsel; } #ifdef HAVE_RECORDING @@ -261,7 +261,7 @@ void audiohw_enable_recording(bool source_mic) /* The iPod can handle multiple frequencies, but fix at 44.1KHz for now */ - audiohw_set_sample_rate(WM8985_44100HZ); + audiohw_set_frequency(HW_FREQ_DEFAULT); wmcodec_write(INCTRL,0x44); /* Connect L2 and R2 inputs */ diff --git a/firmware/export/as3514.h b/firmware/export/as3514.h index af4615a15e..07aa0ebfe2 100644 --- a/firmware/export/as3514.h +++ b/firmware/export/as3514.h @@ -26,7 +26,7 @@ extern int tenthdb2master(int db); extern void audiohw_set_master_vol(int vol_l, int vol_r); extern void audiohw_set_lineout_vol(int vol_l, int vol_r); -extern void audiohw_set_sample_rate(int sampling_control); +extern void audiohw_set_frequency(int fsel); /* Register Descriptions */ #define AS3514_LINE_OUT_R 0x00 diff --git a/firmware/export/config-gigabeat.h b/firmware/export/config-gigabeat.h index 664befd54e..708c17fd8a 100644 --- a/firmware/export/config-gigabeat.h +++ b/firmware/export/config-gigabeat.h @@ -105,6 +105,12 @@ #define HW_SAMPR_CAPS (SAMPR_CAP_88 | SAMPR_CAP_44 | SAMPR_CAP_22 | \ SAMPR_CAP_11) +/* All exact rates for 16.9344MHz clock */ +#define CODEC_SRCTRL_11025HZ (0x19 << 1) +#define CODEC_SRCTRL_22050HZ (0x1b << 1) +#define CODEC_SRCTRL_44100HZ (0x11 << 1) +#define CODEC_SRCTRL_88200HZ (0x1f << 1) + #define HAVE_HEADPHONE_DETECTION #define BATTERY_CAPACITY_DEFAULT 2000 /* default battery capacity */ diff --git a/firmware/export/config-mrobe100.h b/firmware/export/config-mrobe100.h index 051f15824f..4ade179c04 100644 --- a/firmware/export/config-mrobe100.h +++ b/firmware/export/config-mrobe100.h @@ -58,6 +58,7 @@ /* Wolfsom audio codec */ #define HAVE_WM8751 +#define CODEC_SRCTRL_44100HZ (0x40|(0x11 << 1)|1) #define AB_REPEAT_ENABLE 1 diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h index 1660f0670d..ac8ddb1b3c 100644 --- a/firmware/export/pcm.h +++ b/firmware/export/pcm.h @@ -57,7 +57,7 @@ typedef int (*pcm_more_callback_type2)(int status); /* set the pcm frequency - use values in hw_sampr_list * use -1 for the default frequency */ -void pcm_set_frequency(unsigned int frequency); +void pcm_set_frequency(unsigned int samplerate); /* apply settings to hardware immediately */ void pcm_apply_settings(void); @@ -87,6 +87,8 @@ bool pcm_is_playing(void); specific portion **/ extern unsigned long pcm_curr_sampr; +extern unsigned long pcm_sampr; +extern int pcm_fsel; /* the registered callback function to ask for more mp3 data */ extern volatile pcm_more_callback_type pcm_callback_for_more; @@ -102,6 +104,8 @@ void pcm_play_dma_pause(bool pause); void pcm_play_dma_stopped_callback(void); const void * pcm_play_dma_get_peak_buffer(int *count); +void pcm_dma_apply_settings(void); + #ifdef HAVE_RECORDING /** RAW PCM recording routines **/ diff --git a/firmware/export/pp5002.h b/firmware/export/pp5002.h index b235a2154b..9fab86bf21 100644 --- a/firmware/export/pp5002.h +++ b/firmware/export/pp5002.h @@ -34,19 +34,64 @@ #define LCD1_BUSY_MASK 0x8000 /* I2S controller */ + +/* FIFO slot bits 7-0 are not implemented and so use of packed samples + * appears to be impossible. */ #define IISCONFIG (*(volatile unsigned long *)(0xc0002500)) #define IISFIFO_CFG (*(volatile unsigned long *)(0xc000251c)) #define IISFIFO_WR (*(volatile unsigned long *)(0xc0002540)) #define IISFIFO_RD (*(volatile unsigned long *)(0xc0002580)) -/* IISCONFIG bits: */ +/** + * IISCONFIG bits: + * | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | + * | | | | | | | | | + * | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | + * | | | | | | | | | + * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | + * | | | | | | | | | + * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * | rw | rw | rw | MS | rw |TXFENB# | rw | ENB | + * + * # No effect observed on iPod 3g + */ +#define IIS_ENABLE (1 << 0) #define IIS_TXFIFOEN (1 << 2) -#define IIS_TX_FREE_MASK (0xf << 23) -#define IIS_TX_FREE_COUNT ((IISFIFO_CFG & IIS_TX_FREE_MASK) >> 23) +#define IIS_MASTER (1 << 4) -/* IISFIFO_CFG bits: */ -#define IIS_IRQTX_REG IISFIFO_CFG -#define IIS_IRQTX (1 << 9) +/** + * IISFIFO_CFG bits: + * | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | + * | | RXFull[3:0]$ | TXFree[3:1] > + * | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | + * >TXFre[0]| | | | | | RXCLR | TXCLR | + * | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | + * | rw | rw | rw | rw | rw | rw | IRQTX | rw | + * | 7* | 6* | 5* | 4* | 3 | 2 | 1 | 0 | + * |RXEMPTY | RXSAFE | RXDNGR | RXFULL | TXFULL | TXSAFE | TXDNGR |TXEMPTY | + * + * $Could be RXFree + * *Meaning isn't certain yet. + * More concerted recording work will reveal. + */ +#define IIS_IRQTX_REG IISFIFO_CFG +#define IIS_IRQRX_REG IISFIFO_CFG + +#define IIS_RX_FULL_MASK (0xf << 27) +#define IIS_RX_FULL_COUNT ((IISFIFO_CFG & IIS_RX_FULL_MASK) >> 27) +#define IIS_TX_FREE_MASK (0xf << 23) /* 0xf = 16 or 15 free */ +#define IIS_TX_FREE_COUNT ((IISFIFO_CFG & IIS_TX_FREE_MASK) >> 23) +#define IIS_TX_IS_EMPTY ((IISFIFO_CFG & IIS_TXEMPTY) != 0) + +#define IIS_RXCLR (1 << 17) /* Resets *could* be reversed */ +#define IIS_TXCLR (1 << 16) +#define IIS_IRQTX (1 << 9) +#define IIS_TXFULL (1 << 3) /* All slots occupied */ +#define IIS_TXSAFE (1 << 2) /* FIFO >= 3/4 full */ +#define IIS_TXDANGER (1 << 1) /* FIFO <= 1/4 full */ +#define IIS_TXEMPTY (1 << 0) /* No samples in FIFO */ + +#define IIS_RXEMPTY (1 << 4) /* FIFO is empty */ #define IDE_BASE 0xc0003000 @@ -184,6 +229,7 @@ #define DEV_RS (*(volatile unsigned long *)(0xcf005030)) #define DEV_I2C (1<<8) +#define DEV_I2S (1<<7) #define DEV_USB 0x400000 #define CLOCK_ENABLE (*(volatile unsigned long *)(0xcf005008)) diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h index 908fed0087..b4919a219e 100644 --- a/firmware/export/pp5020.h +++ b/firmware/export/pp5020.h @@ -431,6 +431,9 @@ #define IIS_TX_FREE_COUNT \ ((IISFIFO_CFG & IIS_TX_FREE_MASK) >> 16) +#define IIS_TX_IS_EMPTY \ + ((IISFIFO_CFG & IIS_TX_FREE_MASK) >= (16 << 16)) + #define IIS_RXCLR (1 << 12) #define IIS_TXCLR (1 << 8) /* Number of slots */ diff --git a/firmware/export/tlv320.h b/firmware/export/tlv320.h index 91c4a67623..171223f5bb 100644 --- a/firmware/export/tlv320.h +++ b/firmware/export/tlv320.h @@ -38,7 +38,7 @@ extern int tenthdb2master(int db); * 44100: 1 = MCLK MCLK SCLK, LRCK: Audio Clk / 4 (default) * 88200: 2 = MCLK*2 MCLK SCLK, LRCK: Audio Clk / 2 */ -extern void audiohw_set_frequency(unsigned fsel); +extern void audiohw_set_frequency(int fsel); extern void audiohw_set_headphone_vol(int vol_l, int vol_r); #define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */ diff --git a/firmware/export/uda1380.h b/firmware/export/uda1380.h index 26b13a968f..af2b579a60 100644 --- a/firmware/export/uda1380.h +++ b/firmware/export/uda1380.h @@ -36,6 +36,8 @@ extern void audiohw_set_mixer_vol(int channel1, int channel2); /** * Sets frequency settings for DAC and ADC relative to MCLK + * For Coldfire IIS dividers, 11.2896MHz, codec as slave with + * PLL enabled. * * Selection for frequency ranges: * Fs: range: with: @@ -44,7 +46,7 @@ extern void audiohw_set_mixer_vol(int channel1, int channel2); * 44100: 2 = 25 to 50 SCLK, LRCK: Audio Clk / 4 (default) * 88200: 3 = 50 to 100 SCLK, LRCK: Audio Clk / 2 */ -extern void audiohw_set_frequency(unsigned fsel); +extern void audiohw_set_frequency(int fsel); #define UDA1380_ADDR 0x30 diff --git a/firmware/export/wm8731.h b/firmware/export/wm8731.h index 9d5b61833f..512ef9ff3f 100644 --- a/firmware/export/wm8731.h +++ b/firmware/export/wm8731.h @@ -31,7 +31,7 @@ extern int tenthdb2master(int db); extern void audiohw_set_master_vol(int vol_l, int vol_r); -extern void audiohw_set_sample_rate(int sampling_control); +extern void audiohw_set_frequency(int fsel); /* Common register bits */ #ifdef HAVE_WM8731 diff --git a/firmware/export/wm8758.h b/firmware/export/wm8758.h index c094b1296a..493d18b753 100644 --- a/firmware/export/wm8758.h +++ b/firmware/export/wm8758.h @@ -34,7 +34,7 @@ extern int tenthdb2mixer(int db); extern void audiohw_set_master_vol(int vol_l, int vol_r); extern void audiohw_set_lineout_vol(int vol_l, int vol_r); extern void audiohw_set_mixer_vol(int channel1, int channel2); -extern void audiohw_set_sample_rate(int sampling_control); +extern void audiohw_set_frequency(int fsel); #define RESET 0x00 #define RESET_RESET 0x0 diff --git a/firmware/export/wm8975.h b/firmware/export/wm8975.h index e2e443213a..aeec33e3d8 100644 --- a/firmware/export/wm8975.h +++ b/firmware/export/wm8975.h @@ -32,7 +32,7 @@ extern int tenthdb2master(int db); extern void audiohw_set_master_vol(int vol_l, int vol_r); extern void audiohw_set_lineout_vol(int vol_l, int vol_r); -extern void audiohw_set_sample_rate(int sampling_control); +extern void audiohw_set_frequency(int fsel); /* Register addresses and bits */ diff --git a/firmware/export/wm8978.h b/firmware/export/wm8978.h index 9c54ae354d..f444c96a29 100644 --- a/firmware/export/wm8978.h +++ b/firmware/export/wm8978.h @@ -28,7 +28,7 @@ int tenthdb2master(int db); void audiohw_set_headphone_vol(int vol_l, int vol_r); -void audiohw_set_frequency(int sampling_control); +void audiohw_set_frequency(int fsel); void wmc_set(unsigned int reg, unsigned int bits); void wmc_clear(unsigned int reg, unsigned int bits); diff --git a/firmware/pcm.c b/firmware/pcm.c index ddf5095725..ea451a0b9f 100644 --- a/firmware/pcm.c +++ b/firmware/pcm.c @@ -24,6 +24,7 @@ #include "logf.h" #include "audio.h" #include "sound.h" +#include "general.h" /** * Aspects implemented in the target-specific portion: @@ -42,11 +43,17 @@ * pcm_play_dma_pause * pcm_play_dma_get_peak_buffer * Data Read/Written within TSP - - * pcm_curr_sampr (RW) + * pcm_sampr (R) + * pcm_fsel (R) + * pcm_curr_sampr (R) * pcm_callback_for_more (R) * pcm_playing (R) * pcm_paused (R) * + * ==Playback/Recording== + * Semi-private - + * pcm_dma_apply_settings + * * ==Recording== * Public - * pcm_rec_lock @@ -76,6 +83,10 @@ volatile bool pcm_playing SHAREDBSS_ATTR = false; volatile bool pcm_paused SHAREDBSS_ATTR = false; /* samplerate of currently playing audio - undefined if stopped */ unsigned long pcm_curr_sampr SHAREDBSS_ATTR = 0; +/* samplerate waiting to be set */ +unsigned long pcm_sampr SHAREDBSS_ATTR = HW_SAMPR_DEFAULT; +/* samplerate frequency selection index */ +int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT; /** * Do peak calculation using distance squared from axis and save a lot @@ -179,6 +190,8 @@ void pcm_init(void) pcm_play_dma_stopped_callback(); + pcm_set_frequency(HW_SAMPR_DEFAULT); + logf(" pcm_play_dma_init"); pcm_play_dma_init(); } @@ -221,6 +234,8 @@ void pcm_play_data(pcm_more_callback_type get_more, pcm_callback_for_more = get_more; + pcm_apply_settings(); + logf(" pcm_play_data_start"); pcm_play_data_start(start, size); @@ -241,16 +256,21 @@ void pcm_play_pause(bool play) pcm_play_dma_pause(true); pcm_paused = true; } - else if (pcm_get_bytes_waiting() > 0) - { - logf(" pcm_play_dma_pause"); - pcm_play_dma_pause(false); - pcm_paused = false; - } else { - logf(" pcm_play_dma_start: no data"); - pcm_play_data_start(NULL, 0); + pcm_apply_settings(); + + if (pcm_get_bytes_waiting() > 0) + { + logf(" pcm_play_dma_pause"); + pcm_play_dma_pause(false); + pcm_paused = false; + } + else + { + logf(" pcm_play_dma_start: no data"); + pcm_play_data_start(NULL, 0); + } } } else @@ -290,6 +310,35 @@ void pcm_play_dma_stopped_callback(void) /**/ +/* set frequency next frequency used by the audio hardware - + * what pcm_apply_settings will set */ +void pcm_set_frequency(unsigned int samplerate) +{ + logf("pcm_set_frequency"); + + int index = round_value_to_list32(samplerate, hw_freq_sampr, + HW_NUM_FREQ, false); + + if (samplerate != hw_freq_sampr[index]) + index = HW_FREQ_DEFAULT; /* Invalid = default */ + + pcm_sampr = hw_freq_sampr[index]; + pcm_fsel = index; +} + +/* apply pcm settings to the hardware */ +void pcm_apply_settings(void) +{ + logf("pcm_apply_settings"); + + if (pcm_sampr != pcm_curr_sampr) + { + logf(" pcm_dma_apply_settings"); + pcm_dma_apply_settings(); + pcm_curr_sampr = pcm_sampr; + } +} + bool pcm_is_playing(void) { return pcm_playing; @@ -411,6 +460,7 @@ void pcm_record_data(pcm_more_callback_type2 more_ready, pcm_callback_more_ready = more_ready; logf(" pcm_rec_dma_start"); + pcm_apply_settings(); pcm_rec_dma_start(start, size); pcm_recording = true; diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c index d47f80ae77..fe694e0967 100644 --- a/firmware/target/arm/as3525/pcm-as3525.c +++ b/firmware/target/arm/as3525/pcm-as3525.c @@ -138,8 +138,10 @@ void pcm_postinit(void) pcm_apply_settings(); } -void pcm_set_frequency(unsigned int frequency) +void pcm_dma_apply_settings(void) { + unsigned long frequency = pcm_sampr; + const int divider = (((AS3525_PLLA_FREQ/128) + (frequency/2)) / frequency) - 1; if(divider < 0 || divider > 511) panicf("unsupported frequency %d", frequency); @@ -147,13 +149,6 @@ void pcm_set_frequency(unsigned int frequency) CGU_AUDIO &= ~(((511 ^ divider) << 2) /* I2SOUT */ /*| ((511 ^ divider) << 14) */ /* I2SIN */ ); - - pcm_curr_sampr = frequency; -} - -void pcm_apply_settings(void) -{ - pcm_set_frequency(HW_SAMPR_DEFAULT); } size_t pcm_get_bytes_waiting(void) diff --git a/firmware/target/arm/audio-pp.c b/firmware/target/arm/audio-pp.c index ba52118e0f..b170518af4 100644 --- a/firmware/target/arm/audio-pp.c +++ b/firmware/target/arm/audio-pp.c @@ -40,6 +40,23 @@ void audio_input_mux(int source, unsigned flags) static bool last_recording = false; #endif +#if defined(IPOD_COLOR) || defined (IPOD_4G) + /* The usual magic from IPL - I'm guessing this configures the headphone + socket to be input or output. */ + if (recording && source != AUDIO_SRC_PLAYBACK) + { + /* input */ + GPIO_CLEAR_BITWISE(GPIOI_OUTPUT_VAL, 0x40); + GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_VAL, 0x04); + } + else + { + /* output */ + GPIO_SET_BITWISE(GPIOI_OUTPUT_VAL, 0x40); + GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x04); + } +#endif /* IPOD_COLOR || IPOD_4G */ + switch (source) { default: /* playback - no recording */ @@ -109,4 +126,3 @@ void audio_input_mux(int source, unsigned flags) last_source = source; } /* audio_input_mux */ #endif /* INPUT_SRC_CAPS != 0 */ - diff --git a/firmware/target/arm/i2s-pp.c b/firmware/target/arm/i2s-pp.c index c96a559a8a..81c1fa1265 100644 --- a/firmware/target/arm/i2s-pp.c +++ b/firmware/target/arm/i2s-pp.c @@ -25,28 +25,22 @@ * KIND, either express or implied. * ****************************************************************************/ - #include "system.h" #include "cpu.h" #include "i2s.h" -/* TODO: Add in PP5002 defs */ #if CONFIG_CPU == PP5002 void i2s_reset(void) { /* I2S device reset */ - DEV_RS |= 0x80; - DEV_RS &= ~0x80; + DEV_RS |= DEV_I2S; + DEV_RS &= ~DEV_I2S; /* I2S controller enable */ - IISCONFIG |= 1; - - /* BIT.FORMAT [11:10] = I2S (default) */ - /* BIT.SIZE [9:8] = 24bit */ - /* FIFO.FORMAT = 24 bit LSB */ + IISCONFIG |= IIS_ENABLE; /* reset DAC and ADC fifo */ - IISFIFO_CFG |= 0x30000; + IISFIFO_CFG |= IIS_RXCLR | IIS_TXCLR; } #else /* PP502X */ diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c index 99aa66a781..48f7f608d9 100644 --- a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c @@ -37,9 +37,6 @@ struct dma_data int state; }; -static unsigned long pcm_freq; /* 44.1 is default */ -static int sr_ctrl; - static struct dma_data dma_play_data = { /* Initialize to a locked, stopped state */ @@ -67,15 +64,6 @@ void pcm_play_unlock(void) } } -static void _pcm_apply_settings(void) -{ - if (pcm_freq != pcm_curr_sampr) - { - pcm_curr_sampr = pcm_freq; - audiohw_set_frequency(sr_ctrl); - } -} - static void __attribute__((interrupt("IRQ"))) SSI1_HANDLER(void) { register pcm_more_callback_type get_more; @@ -109,19 +97,9 @@ static void __attribute__((interrupt("IRQ"))) SSI1_HANDLER(void) pcm_play_dma_stopped_callback(); } -void pcm_apply_settings(void) +void pcm_dma_apply_settings(void) { - pcm_play_lock(); -#ifdef HAVE_RECORDING - pcm_rec_lock(); -#endif - - _pcm_apply_settings(); - -#ifdef HAVE_RECORDING - pcm_rec_unlock(); -#endif - pcm_play_unlock(); + audiohw_set_frequency(pcm_fsel); } void pcm_play_dma_init(void) @@ -214,7 +192,6 @@ void pcm_play_dma_init(void) /* Enable SSI2 (codec clock) */ SSI_SCR2 |= SSI_SCR_SSIEN; - pcm_set_frequency(HW_SAMPR_DEFAULT); audiohw_init(); } @@ -230,7 +207,7 @@ static void play_start_pcm(void) SSI_SCR1 &= ~SSI_SCR_TE; /* Apply new settings */ - _pcm_apply_settings(); + pcm_apply_settings(); /* Enable interrupt on unlock */ dma_play_data.state = 1; @@ -296,52 +273,6 @@ void pcm_play_dma_pause(bool pause) } } -/* Set the pcm frequency hardware will use when play is next started or - when pcm_apply_settings is called. Do not apply the setting to the - hardware here but simply cache it. */ -void pcm_set_frequency(unsigned int frequency) -{ - int index; - - switch (frequency) - { - case SAMPR_48: - index = HW_FREQ_48; - break; - case SAMPR_44: - index = HW_FREQ_44; - break; - case SAMPR_32: - index = HW_FREQ_32; - break; - case SAMPR_24: - index = HW_FREQ_24; - break; - case SAMPR_22: - index = HW_FREQ_22; - break; - case SAMPR_16: - index = HW_FREQ_16; - break; - case SAMPR_12: - index = HW_FREQ_12; - break; - case SAMPR_11: - index = HW_FREQ_11; - break; - case SAMPR_8: - index = HW_FREQ_8; - break; - default: - /* Invalid = default */ - frequency = HW_SAMPR_DEFAULT; - index = HW_FREQ_DEFAULT; - } - - pcm_freq = frequency; - sr_ctrl = index; -} - /* Return the number of bytes waiting - full L-R sample pairs only */ size_t pcm_get_bytes_waiting(void) { diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c index deaa20b6be..e00b1d7e75 100644 --- a/firmware/target/arm/pcm-pp.c +++ b/firmware/target/arm/pcm-pp.c @@ -25,10 +25,7 @@ #include "audio.h" #include "sound.h" #include "pcm.h" - -#ifdef HAVE_WM8751 -#define MROBE100_44100HZ (0x40|(0x11 << 1)|1) -#endif +#include "pcm_sampr.h" /** DMA **/ @@ -87,36 +84,9 @@ static struct dma_data dma_play_data SHAREDBSS_ATTR = .state = 0 }; -static unsigned long pcm_freq SHAREDDATA_ATTR = HW_SAMPR_DEFAULT; /* 44.1 is default */ -#ifdef HAVE_WM8751 -/* Samplerate control for audio codec */ -static int sr_ctrl = MROBE100_44100HZ; -#endif - -void pcm_set_frequency(unsigned int frequency) +void pcm_dma_apply_settings(void) { -#if defined(HAVE_WM8731) || defined(HAVE_WM8721) - pcm_freq = frequency; -#else - (void)frequency; - pcm_freq = HW_SAMPR_DEFAULT; -#endif -#ifdef HAVE_WM8751 - sr_ctrl = MROBE100_44100HZ; -#endif -} - -void pcm_apply_settings(void) -{ -#ifdef HAVE_WM8751 - audiohw_set_frequency(sr_ctrl); -#endif - -#if defined(HAVE_WM8711) || defined(HAVE_WM8721) \ - || defined(HAVE_WM8731) - audiohw_set_sample_rate(pcm_freq); -#endif - pcm_curr_sampr = pcm_freq; + audiohw_set_frequency(pcm_fsel); } /* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by @@ -330,9 +300,7 @@ static void play_stop_pcm(void) IIS_IRQTX_REG &= ~IIS_IRQTX; /* Wait for FIFO to empty */ -#ifdef CPU_PP502x - while (IIS_TX_FREE_COUNT < 16); -#endif + while (!IIS_TX_IS_EMPTY); dma_play_data.state = 0; } @@ -397,8 +365,6 @@ void pcm_play_dma_init(void) : [iiscfg]"r"(iiscfg), [dmapd]"r"(dmapd) : "r2"); - pcm_set_frequency(SAMPR_44); - /* Initialize default register values. */ audiohw_init(); @@ -620,24 +586,10 @@ void pcm_rec_dma_start(void *addr, size_t size) void pcm_rec_dma_close(void) { pcm_rec_dma_stop(); - -#if defined(IPOD_COLOR) || defined (IPOD_4G) - /* The usual magic from IPL - I'm guessing this configures the headphone - socket to be input or output - in this case, output. */ - GPIO_SET_BITWISE(GPIOI_OUTPUT_VAL, 0x40); - GPIO_SET_BITWISE(GPIOA_OUTPUT_VAL, 0x04); -#endif } /* pcm_close_recording */ void pcm_rec_dma_init(void) { -#if defined(IPOD_COLOR) || defined (IPOD_4G) - /* The usual magic from IPL - I'm guessing this configures the headphone - socket to be input or output - in this case, input. */ - GPIO_CLEAR_BITWISE(GPIOI_OUTPUT_VAL, 0x40); - GPIO_CLEAR_BITWISE(GPIOA_OUTPUT_VAL, 0x04); -#endif - pcm_rec_dma_stop(); } /* pcm_init */ diff --git a/firmware/target/arm/pcm-telechips.c b/firmware/target/arm/pcm-telechips.c index affad01c76..a4dc63fc56 100644 --- a/firmware/target/arm/pcm-telechips.c +++ b/firmware/target/arm/pcm-telechips.c @@ -58,7 +58,7 @@ struct dma_data dma_play_data SHAREDBSS_ATTR = .state = 0 }; -static unsigned long pcm_freq SHAREDDATA_ATTR = HW_SAMPR_DEFAULT; /* 44.1 is default */ +static unsigned long pcm_sampr SHAREDDATA_ATTR = HW_SAMPR_DEFAULT; /* 44.1 is default */ void pcm_postinit(void) { @@ -102,8 +102,6 @@ void pcm_play_dma_init(void) /* Set DAI interrupts as FIQs */ IRQSEL = ~(DAI_RX_IRQ_MASK | DAI_TX_IRQ_MASK); - pcm_set_frequency(SAMPR_44); - /* Initialize default register values. */ audiohw_init(); @@ -113,15 +111,8 @@ void pcm_play_dma_init(void) #endif } -void pcm_apply_settings(void) +void pcm_dma_apply_settings(void) { - pcm_curr_sampr = pcm_freq; -} - -void pcm_set_frequency(unsigned int frequency) -{ - (void) frequency; - pcm_freq = HW_SAMPR_DEFAULT; } static void play_start_pcm(void) diff --git a/firmware/target/arm/pnx0101/pcm-pnx0101.c b/firmware/target/arm/pnx0101/pcm-pnx0101.c index 4f90c5f829..20fca48039 100644 --- a/firmware/target/arm/pnx0101/pcm-pnx0101.c +++ b/firmware/target/arm/pnx0101/pcm-pnx0101.c @@ -27,7 +27,7 @@ short __attribute__((section(".dmabuf"))) dma_buf_left[DMA_BUF_SAMPLES]; short __attribute__((section(".dmabuf"))) dma_buf_right[DMA_BUF_SAMPLES]; -static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ +static int pcm_sampr = HW_SAMPR_DEFAULT; /* 44.1 is default */ unsigned short* p IBSS_ATTR; size_t p_size IBSS_ATTR; @@ -147,8 +147,6 @@ void pcm_init(void) { int i; - pcm_set_frequency(HW_SAMPR_DEFAULT); - memset(dma_buf_left, 0, sizeof(dma_buf_left)); memset(dma_buf_right, 0, sizeof(dma_buf_right)); @@ -193,15 +191,8 @@ void pcm_postinit(void) pcm_apply_settings(); } -void pcm_set_frequency(unsigned int frequency) +void pcm_dma_apply_settings(void) { - (void)frequency; - pcm_freq = HW_SAMPR_DEFAULT; -} - -void pcm_apply_settings(void) -{ - pcm_curr_sampr = pcm_freq; } size_t pcm_get_bytes_waiting(void) diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c index 14fbcd5cfe..315fc3bf0f 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c @@ -26,12 +26,6 @@ #include "sound.h" #include "file.h" -/* All exact rates for 16.9344MHz clock */ -#define GIGABEAT_11025HZ (0x19 << 1) -#define GIGABEAT_22050HZ (0x1b << 1) -#define GIGABEAT_44100HZ (0x11 << 1) -#define GIGABEAT_88200HZ (0x1f << 1) - /* PCM interrupt routine lockout */ static struct { @@ -43,11 +37,6 @@ static struct .state = 0, }; -/* Last samplerate set by pcm_set_frequency */ -static unsigned long pcm_freq = 0; /* 44.1 is default */ -/* Samplerate control for audio codec */ -static int sr_ctrl = 0; - #define FIFO_COUNT ((IISFCON >> 6) & 0x3F) /* Setup for the DMA controller */ @@ -57,22 +46,6 @@ static int sr_ctrl = 0; /* Get more data from the callback and top off the FIFO */ void fiq_handler(void) __attribute__((interrupt ("FIQ"))); -static void _pcm_apply_settings(void) -{ - if (pcm_freq != pcm_curr_sampr) - { - pcm_curr_sampr = pcm_freq; - audiohw_set_frequency(sr_ctrl); - } -} - -void pcm_apply_settings(void) -{ - int status = disable_fiq_save(); - _pcm_apply_settings(); - restore_fiq(status); -} - /* Mask the DMA interrupt */ void pcm_play_lock(void) { @@ -89,8 +62,6 @@ void pcm_play_unlock(void) void pcm_play_dma_init(void) { - pcm_set_frequency(SAMPR_44); - /* There seem to be problems when changing the IIS interface configuration * when a clock is not present. */ @@ -128,13 +99,18 @@ void pcm_postinit(void) pcm_apply_settings(); } +void pcm_dma_apply_settings(void) +{ + audiohw_set_frequency(pcm_fsel); +} + /* Connect the DMA and start filling the FIFO */ static void play_start_pcm(void) { /* clear pending DMA interrupt */ SRCPND = DMA2_MASK; - _pcm_apply_settings(); + pcm_apply_settings(); /* Flush any pending writes */ clean_dcache_range((void*)DISRC2, (DCON2 & 0xFFFFF) * 2); @@ -272,29 +248,6 @@ void fiq_handler(void) } } -void pcm_set_frequency(unsigned int frequency) -{ - switch(frequency) - { - case SAMPR_11: - sr_ctrl = GIGABEAT_11025HZ; - break; - case SAMPR_22: - sr_ctrl = GIGABEAT_22050HZ; - break; - default: - frequency = SAMPR_44; - case SAMPR_44: - sr_ctrl = GIGABEAT_44100HZ; - break; - case SAMPR_88: - sr_ctrl = GIGABEAT_88200HZ; - break; - } - - pcm_freq = frequency; -} - size_t pcm_get_bytes_waiting(void) { /* lie a little and only return full pairs */ diff --git a/firmware/target/arm/tms320dm320/creative-zvm/pcm-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/pcm-creativezvm.c index 34425fa63d..d8c953bbce 100644 --- a/firmware/target/arm/tms320dm320/creative-zvm/pcm-creativezvm.c +++ b/firmware/target/arm/tms320dm320/creative-zvm/pcm-creativezvm.c @@ -28,6 +28,8 @@ #include "audiohw.h" #include "dsp-target.h" +static int pcm_fsel = HW_FREQ_DEFAULT; + void pcm_play_dma_init(void) { IO_CLK_O1DIV = 3; @@ -37,7 +39,7 @@ void pcm_play_dma_init(void) audiohw_init(); - audiohw_set_frequency(1); + audiohw_set_frequency(HW_FREQ_DEFAULT); /* init DSP */ dsp_init(); @@ -46,42 +48,21 @@ void pcm_play_dma_init(void) void pcm_postinit(void) { audiohw_postinit(); + pcm_apply_settings(); + /* wake DSP */ dsp_wake(); } -/* set frequency used by the audio hardware */ -void pcm_set_frequency(unsigned int frequency) -{ - int index; - - switch(frequency) - { - case SAMPR_11: - case SAMPR_22: - index = 0; - break; - default: - case SAMPR_44: - index = 1; - break; - case SAMPR_88: - index = 2; - break; - } - - audiohw_set_frequency(index); -} /* pcm_set_frequency */ - const void * pcm_play_dma_get_peak_buffer(int *count) { (void) count; return 0; } -void pcm_apply_settings(void) +void pcm_dma_apply_settings(void) { - + audiohw_set_frequency(pcm_fsel); } void pcm_play_dma_start(const void *addr, size_t size) diff --git a/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c old mode 100755 new mode 100644 index 2f0e40757b..4c9cc337a5 --- a/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c +++ b/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c @@ -41,14 +41,8 @@ void pcm_play_dma_init(void) } -void pcm_apply_settings(void) +void pcm_dma_apply_settings(void) { - -} - -void pcm_set_frequency(unsigned int frequency) -{ - (void) frequency; } void pcm_play_dma_start(const void *addr, size_t size) diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c index 35b3ecae9c..914947a98e 100644 --- a/firmware/target/coldfire/pcm-coldfire.c +++ b/firmware/target/coldfire/pcm-coldfire.c @@ -69,66 +69,43 @@ static void iis_play_reset_if_playback(bool if_playback) /** Sample rates **/ #define FPARM_CLOCKSEL 0 #define FPARM_CLSEL 1 -#define FPARM_FSEL 2 #if CONFIG_CPU == MCF5249 && defined(HAVE_UDA1380) -static const unsigned char pcm_freq_parms[HW_NUM_FREQ][3] = +static const unsigned char pcm_freq_parms[HW_NUM_FREQ][2] = { - [HW_FREQ_88] = { 0x0c, 0x01, 0x03 }, - [HW_FREQ_44] = { 0x06, 0x01, 0x02 }, - [HW_FREQ_22] = { 0x04, 0x02, 0x01 }, - [HW_FREQ_11] = { 0x02, 0x02, 0x00 }, + [HW_FREQ_88] = { 0x0c, 0x01 }, + [HW_FREQ_44] = { 0x06, 0x01 }, + [HW_FREQ_22] = { 0x04, 0x02 }, + [HW_FREQ_11] = { 0x02, 0x02 }, }; #endif #if (CONFIG_CPU == MCF5250 || CONFIG_CPU == MCF5249) && defined(HAVE_TLV320) -static const unsigned char pcm_freq_parms[HW_NUM_FREQ][3] = +static const unsigned char pcm_freq_parms[HW_NUM_FREQ][2] = { - [HW_FREQ_88] = { 0x0c, 0x01, 0x02 }, - [HW_FREQ_44] = { 0x06, 0x01, 0x01 }, - [HW_FREQ_22] = { 0x04, 0x01, 0x00 }, - [HW_FREQ_11] = { 0x02, 0x02, 0x00 }, + [HW_FREQ_88] = { 0x0c, 0x01 }, + [HW_FREQ_44] = { 0x06, 0x01 }, + [HW_FREQ_22] = { 0x04, 0x01 }, + [HW_FREQ_11] = { 0x02, 0x02 }, }; #endif -static unsigned long pcm_freq = 0; /* 44.1 is default */ -static const unsigned char *freq_ent = pcm_freq_parms[HW_FREQ_DEFAULT]; - -/* set frequency used by the audio hardware */ -void pcm_set_frequency(unsigned int frequency) -{ - int index; - - switch(frequency) - { - case SAMPR_11: - index = HW_FREQ_11; - break; - case SAMPR_22: - index = HW_FREQ_22; - break; - default: - case SAMPR_44: - index = HW_FREQ_44; - break; - case SAMPR_88: - index = HW_FREQ_88; - break; - } - - /* remember table entry and rate */ - freq_ent = pcm_freq_parms[index]; - pcm_freq = hw_freq_sampr[index]; -} /* pcm_set_frequency */ +static const unsigned char *freq_ent; /* apply audio settings */ -static bool _pcm_apply_settings(bool clear_reset) +static bool _pcm_dma_apply_settings(bool clear_reset) { bool did_reset = false; - unsigned long iis_play_defparm = IIS_PLAY_DEFPARM; + unsigned long iis_play_defparm; + + int level = set_irq_level(DMA_IRQ_LEVEL); + + /* remember table entry */ + freq_ent = pcm_freq_parms[pcm_fsel]; - if (pcm_freq != pcm_curr_sampr) + iis_play_defparm = IIS_PLAY_DEFPARM; + + if (pcm_sampr != pcm_curr_sampr) { - pcm_curr_sampr = pcm_freq; /* Reprogramming bits 15-12 requires FIFO to be in a reset condition - Users Manual 17-8, Note 11 */ or_l(IIS_FIFO_RESET, &IIS_PLAY); @@ -136,8 +113,8 @@ static bool _pcm_apply_settings(bool clear_reset) or starting recording will sound absolutely awful once in awhile - audiohw_set_frequency then coldfire_set_pllcr_audio_bits */ - SET_IIS_PLAY(iis_play_defparm | IIS_FIFO_RESET); - audiohw_set_frequency(freq_ent[FPARM_FSEL]); + SET_IIS_PLAY(IIS_PLAY_DEFPARM | IIS_FIFO_RESET); + audiohw_set_frequency(pcm_fsel); coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); did_reset = true; } @@ -147,26 +124,21 @@ static bool _pcm_apply_settings(bool clear_reset) be cleared. If the frequency didn't change, it was never altered and the reset flag can just be removed or no action taken. */ if (clear_reset) - SET_IIS_PLAY(iis_play_defparm & ~IIS_FIFO_RESET); + SET_IIS_PLAY(IIS_PLAY_DEFPARM & ~IIS_FIFO_RESET); + + restore_irq(level); + #if 0 logf("IISPLAY: %08X", IIS_PLAY); #endif return did_reset; -} /* _pcm_apply_settings */ - -/* apply audio setting with all DMA interrupts disabled */ -static void _pcm_apply_settings_irq_lock(bool clear_reset) -{ - int level = set_irq_level(DMA_IRQ_LEVEL); - _pcm_apply_settings(clear_reset); - restore_irq(level); -} +} /* _pcm_dma_apply_settings */ /* This clears the reset bit to enable monitoring immediately if monitoring recording sources or always if playback is in progress - we might be switching samplerates on the fly */ -void pcm_apply_settings(void) +void pcm_dma_apply_settings(void) { int level = set_irq_level(DMA_IRQ_LEVEL); bool pbm = is_playback_monitoring(); @@ -174,14 +146,16 @@ void pcm_apply_settings(void) /* Clear reset if not playback monitoring or peripheral request is active and playback monitoring */ - if (_pcm_apply_settings(!pbm || kick) && kick) + if (_pcm_dma_apply_settings(!pbm || kick) && kick) PDOR3 = 0; /* Kick FIFO out of reset by writing to it */ restore_irq(level); -} /* pcm_apply_settings */ +} /* pcm_dma_apply_settings */ void pcm_play_dma_init(void) { + freq_ent = pcm_freq_parms[pcm_fsel]; + AUDIOGLOB = (1 << 8) /* IIS1 fifo auto sync */ | (1 << 7) /* PDIR2 fifo auto sync */ #ifdef HAVE_SPDIF_OUT @@ -200,7 +174,6 @@ void pcm_play_dma_init(void) other settings. */ or_l(IIS_FIFO_RESET, &IIS_PLAY); SET_IIS_PLAY(IIS_PLAY_DEFPARM | IIS_FIFO_RESET); - pcm_set_frequency(HW_FREQ_DEFAULT); audio_set_output_source(AUDIO_SRC_PLAYBACK); /* Initialize default register values. */ @@ -208,7 +181,7 @@ void pcm_play_dma_init(void) audio_input_mux(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); - audiohw_set_frequency(freq_ent[FPARM_FSEL]); + audiohw_set_frequency(pcm_fsel); coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); #if defined(HAVE_SPDIF_REC) || defined(HAVE_SPDIF_OUT) @@ -264,7 +237,7 @@ void pcm_play_dma_start(const void *addr, size_t size) BCR0 = (unsigned long)size; /* Bytes to transfer */ /* Enable the FIFO and force one write to it */ - _pcm_apply_settings_irq_lock(is_playback_monitoring()); + _pcm_dma_apply_settings(is_playback_monitoring()); DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE) | DMA_START; @@ -299,7 +272,7 @@ void pcm_play_dma_pause(bool pause) { /* restart playback on current buffer */ /* Enable the FIFO and force one write to it */ - _pcm_apply_settings_irq_lock(is_playback_monitoring()); + _pcm_dma_apply_settings(is_playback_monitoring()); or_l(DMA_EEXT | DMA_START, &DCR0); dma_play_lock.state = (1 << 14); } @@ -403,7 +376,7 @@ void pcm_rec_dma_start(void *addr, size_t size) and_l(~PDIR2_FIFO_RESET, &DATAINCONTROL); /* Clear TX FIFO reset bit if the source is not set to monitor playback otherwise maintain independence between playback and recording. */ - _pcm_apply_settings_irq_lock(!is_playback_monitoring()); + _pcm_dma_apply_settings(!is_playback_monitoring()); /* Start the DMA transfer.. */ #ifdef HAVE_SPDIF_REC diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c index e4d9127c21..2d3aa45d08 100644 --- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c @@ -58,14 +58,13 @@ void pcm_play_dma_init(void) audiohw_init(); } -void pcm_set_frequency(unsigned int frequency) +void pcm_dma_apply_settings(void) { - (void) frequency; /* TODO */ /* - __i2s_set_oss_sample_size(frequency); - i2s_codec_set_samplerate(frequency); + __i2s_set_oss_sample_size(pcm_sampr); + i2s_codec_set_samplerate(pcm_sampr); */ } diff --git a/uisimulator/sdl/sound.c b/uisimulator/sdl/sound.c index 5f061695a8..39abc85aca 100644 --- a/uisimulator/sdl/sound.c +++ b/uisimulator/sdl/sound.c @@ -33,7 +33,6 @@ #include "SDL.h" static int cvt_status = -1; -static unsigned long pcm_frequency = SAMPR_44; static Uint8* pcm_data; static size_t pcm_data_size; @@ -67,28 +66,26 @@ void pcm_play_unlock(void) SDL_UnlockAudio(); } -static void pcm_apply_settings_nolock(void) +static void pcm_dma_apply_settings_nolock(void) { - cvt_status = SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, pcm_frequency, + cvt_status = SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, pcm_sampr, obtained.format, obtained.channels, obtained.freq); - pcm_curr_sampr = pcm_frequency; - if (cvt_status < 0) { - cvt.len_ratio = (double)obtained.freq / (double)pcm_curr_sampr; + cvt.len_ratio = (double)obtained.freq / (double)pcm_sampr; } } -void pcm_apply_settings(void) +void pcm_dma_apply_settings(void) { pcm_play_lock(); - pcm_apply_settings_nolock(); + pcm_dma_apply_settings_nolock(); pcm_play_unlock(); } void pcm_play_dma_start(const void *addr, size_t size) { - pcm_apply_settings_nolock(); + pcm_dma_apply_settings_nolock(); pcm_data = (Uint8 *) addr; pcm_data_size = size; @@ -114,30 +111,6 @@ size_t pcm_get_bytes_waiting(void) return pcm_data_size; } -void pcm_set_frequency(unsigned int frequency) -{ - switch (frequency) - { - HW_HAVE_8_( case SAMPR_8:) - HW_HAVE_11_(case SAMPR_11:) - HW_HAVE_12_(case SAMPR_12:) - HW_HAVE_16_(case SAMPR_16:) - HW_HAVE_22_(case SAMPR_22:) - HW_HAVE_24_(case SAMPR_24:) - HW_HAVE_32_(case SAMPR_32:) - HW_HAVE_44_(case SAMPR_44:) - HW_HAVE_48_(case SAMPR_48:) - HW_HAVE_64_(case SAMPR_64:) - HW_HAVE_88_(case SAMPR_88:) - HW_HAVE_96_(case SAMPR_96:) - break; - default: - frequency = SAMPR_44; - } - - pcm_frequency = frequency; -} - extern int sim_volume; /* in firmware/sound.c */ void write_to_soundcard(struct pcm_udata *udata) { if (cvt.needed) { @@ -357,7 +330,7 @@ void pcm_play_dma_init(void) pcm_sample_bytes = obtained.channels * pcm_channel_bytes; - pcm_apply_settings_nolock(); + pcm_dma_apply_settings_nolock(); } void pcm_postinit(void)