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
This commit is contained in:
Michael Sevakis 2008-12-12 11:01:07 +00:00
parent 0ad97d13fc
commit e69d567d9e
37 changed files with 316 additions and 449 deletions

View file

@ -46,7 +46,7 @@ static unsigned int gen_thread_id;
#define OUTPUT_CHUNK_SAMPLES 1152 #define OUTPUT_CHUNK_SAMPLES 1152
#define OUTPUT_CHUNK_SIZE (OUTPUT_CHUNK_SAMPLES*sizeof(int16_t)*2) #define OUTPUT_CHUNK_SIZE (OUTPUT_CHUNK_SAMPLES*sizeof(int16_t)*2)
static uint16_t output_buf[OUTPUT_CHUNK_COUNT][OUTPUT_CHUNK_SAMPLES*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_head IBSS_ATTR;
static int output_tail IBSS_ATTR; static int output_tail IBSS_ATTR;
static int output_step IBSS_ATTR; static int output_step IBSS_ATTR;

View file

@ -290,9 +290,9 @@ void audiohw_close(void)
sleep(HZ/4); 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) #if defined(HAVE_RECORDING)

View file

@ -152,21 +152,21 @@ void audiohw_postinit(void)
* 44100: 1 = MCLK MCLK SCLK, LRCK: Audio Clk / 4 (default) * 44100: 1 = MCLK MCLK SCLK, LRCK: Audio Clk / 4 (default)
* 88200: 2 = MCLK*2 MCLK SCLK, LRCK: Audio Clk / 2 * 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 */ /* All rates available for 11.2896MHz besides 8.021 */
unsigned char values_src[3] = static const unsigned char values_src[HW_NUM_FREQ] =
{ {
/* Fs: */ [HW_FREQ_11] = (0x8 << 2) | SRC_CLKIN,
(0x8 << 2) | SRC_CLKIN, /* 11025, 22050 */ [HW_FREQ_22] = (0x8 << 2) | SRC_CLKIN,
(0x8 << 2), /* 44100 */ [HW_FREQ_44] = (0x8 << 2),
(0xf << 2), /* 88200 */ [HW_FREQ_88] = (0xf << 2),
}; };
unsigned value_dap, value_pc; unsigned value_dap, value_pc;
if (fsel >= ARRAYLEN(values_src)) if ((unsigned)fsel >= HW_NUM_FREQ)
fsel = 1; fsel = HW_FREQ_DEFAULT;
/* Temporarily turn off the DAC and ADC before switching sample /* Temporarily turn off the DAC and ADC before switching sample
rates or they don't choose their filters correctly */ rates or they don't choose their filters correctly */

View file

@ -130,7 +130,7 @@ void audiohw_close(void)
} }
void audiohw_set_sample_rate(int sampling_control) void audiohw_set_frequency(int fsel)
{
(void)sampling_control; (void)fsel;
} }

View file

@ -218,23 +218,38 @@ static void reset(void)
* 11025: 0 = 6.25 to 12.5 MCLK/2 SCLK, LRCK: Audio Clk / 16 * 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 * 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) * 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: */ [HW_FREQ_11] = /* Fs: */
{ 0, WSPLL_625_125 | SYSCLK_512FS }, /* 11025 */ {
{ 0, WSPLL_125_25 | SYSCLK_256FS }, /* 22050 */ 0,
{ MIX_CTL_SEL_NS, WSPLL_25_50 | SYSCLK_256FS }, /* 44100 */ WSPLL_625_125 | SYSCLK_512FS
{ MIX_CTL_SEL_NS, WSPLL_50_100 | SYSCLK_256FS }, /* 88200 */ },
[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; const unsigned short *ent;
if (fsel >= ARRAYLEN(values_reg)) if ((unsigned)fsel >= HW_NUM_FREQ)
fsel = 2; fsel = HW_FREQ_DEFAULT;
ent = values_reg[fsel]; ent = values_reg[fsel];

View file

@ -224,35 +224,24 @@ void audiohw_close(void)
/* 2) Remove the WM codec supplies. */ /* 2) Remove the WM codec supplies. */
} }
void audiohw_set_sample_rate(int sampling_control) void audiohw_set_frequency(int fsel)
{ {
int rate; /* For 24MHz MCLK */
static const unsigned char srctrl_table[HW_NUM_FREQ] =
switch(sampling_control)
{ {
case SAMPR_96: [HW_FREQ_8] = WMC_USB24_8000HZ,
rate = WMC_USB24_96000HZ; [HW_FREQ_32] = WMC_USB24_32000HZ,
break; [HW_FREQ_44] = WMC_USB24_44100HZ,
case SAMPR_88: [HW_FREQ_48] = WMC_USB24_48000HZ,
rate = WMC_USB24_88200HZ; [HW_FREQ_88] = WMC_USB24_88200HZ,
break; [HW_FREQ_96] = WMC_USB24_96000HZ,
case SAMPR_48: };
rate = WMC_USB24_48000HZ;
break; if ((unsigned)fsel >= HW_NUM_FREQ)
default: fsel = HW_FREQ_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;
}
codec_set_active(false); codec_set_active(false);
wmc_write(SAMPCTRL, rate); wmc_write(SAMPCTRL, srctrl_table[fsel]);
codec_set_active(true); codec_set_active(true);
} }

View file

@ -229,8 +229,18 @@ void audiohw_close(void)
wmcodec_write(PWRMGMT1, 0x0); wmcodec_write(PWRMGMT1, 0x0);
} }
/* Note: Disable output before calling this function */
void audiohw_set_frequency(int fsel) 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]);
} }

View file

@ -107,7 +107,7 @@ void audiohw_preinit(void)
wmcodec_write(OUTCTRL, OUTCTRL_VROI); wmcodec_write(OUTCTRL, OUTCTRL_VROI);
wmcodec_write(CLKCTRL, CLKCTRL_MS); /* WM8758 is clock master */ 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(LOUTMIX, LOUTMIX_DACL2LMIX);
wmcodec_write(ROUTMIX, ROUTMIX_DACR2RMIX); wmcodec_write(ROUTMIX, ROUTMIX_DACR2RMIX);
@ -170,10 +170,10 @@ void audiohw_close(void)
} }
/* Note: Disable output before calling this function */ /* 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. ****/ /**** We force 44.1KHz for now. ****/
(void)sampling_control; (void)fsel;
/* setup PLL for MHZ=11.2896 */ /* setup PLL for MHZ=11.2896 */
wmcodec_write(PLLN, PLLN_PLLPRESCALE | 0x7); wmcodec_write(PLLN, PLLN_PLLPRESCALE | 0x7);

View file

@ -145,7 +145,7 @@ void audiohw_preinit(void)
wm8975_write(DAPCTRL, wm8975_regs[DAPCTRL] ); wm8975_write(DAPCTRL, wm8975_regs[DAPCTRL] );
audiohw_set_sample_rate(WM8975_44100HZ); wmcodec_write(SAMPCTRL, WM8975_44100HZ);
/* set the volume to -6dB */ /* set the volume to -6dB */
wmcodec_write(LOUT1VOL, LOUT1VOL_LO1ZC | IPOD_PCM_LEVEL); wmcodec_write(LOUT1VOL, LOUT1VOL_LO1ZC | IPOD_PCM_LEVEL);
@ -224,9 +224,9 @@ void audiohw_close(void)
} }
/* Note: Disable output before calling this function */ /* 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 #ifdef HAVE_RECORDING

View file

@ -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 static const struct
{ {
uint32_t plln : 8; uint32_t plln : 8;
@ -374,7 +374,7 @@ void audiohw_set_frequency(int sampling_control)
uint32_t pllk3 : 9; uint32_t pllk3 : 9;
unsigned char mclkdiv; unsigned char mclkdiv;
unsigned char filter; unsigned char filter;
} sctrl_table[HW_NUM_FREQ] = } srctrl_table[HW_NUM_FREQ] =
{ {
[HW_FREQ_8] = /* PLL = 65.536MHz */ [HW_FREQ_8] = /* PLL = 65.536MHz */
{ {
@ -450,16 +450,14 @@ void audiohw_set_frequency(int sampling_control)
unsigned int plln; unsigned int plln;
unsigned int mclkdiv; unsigned int mclkdiv;
if ((unsigned)sampling_control >= ARRAYLEN(sctrl_table)) if ((unsigned)fsel >= HW_NUM_FREQ)
sampling_control = HW_FREQ_DEFAULT; fsel = HW_FREQ_DEFAULT;
/* Setup filters. */ /* Setup filters. */
wmc_write(WMC_ADDITIONAL_CTRL, wmc_write(WMC_ADDITIONAL_CTRL, srctrl_table[fsel].filter);
sctrl_table[sampling_control].filter);
plln = sctrl_table[sampling_control].plln; plln = srctrl_table[fsel].plln;
mclkdiv = sctrl_table[sampling_control].mclkdiv; mclkdiv = srctrl_table[fsel].mclkdiv;
if (plln != 0) if (plln != 0)
{ {
@ -467,9 +465,9 @@ void audiohw_set_frequency(int sampling_control)
/* Program PLL. */ /* Program PLL. */
wmc_write(WMC_PLL_N, plln); wmc_write(WMC_PLL_N, plln);
wmc_write(WMC_PLL_K1, sctrl_table[sampling_control].pllk1); wmc_write(WMC_PLL_K1, srctrl_table[fsel].pllk1);
wmc_write(WMC_PLL_K2, sctrl_table[sampling_control].pllk2); wmc_write(WMC_PLL_K2, srctrl_table[fsel].pllk2);
wmc_write(WMC_PLL_K3, sctrl_table[sampling_control].pllk3); wmc_write(WMC_PLL_K3, srctrl_table[fsel].pllk3);
/* Turn on PLL. */ /* Turn on PLL. */
wmc_set(WMC_POWER_MANAGEMENT1, WMC_PLLEN); wmc_set(WMC_POWER_MANAGEMENT1, WMC_PLLEN);

View file

@ -235,12 +235,12 @@ void audiohw_close(void)
} }
/* Note: Disable output before calling this function */ /* 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 /* 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 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. */ driver in Rockbox, so this may need to change in the future. */
(void)sampling_control; (void)fsel;
} }
#ifdef HAVE_RECORDING #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 /* The iPod can handle multiple frequencies, but fix at 44.1KHz
for now */ for now */
audiohw_set_sample_rate(WM8985_44100HZ); audiohw_set_frequency(HW_FREQ_DEFAULT);
wmcodec_write(INCTRL,0x44); /* Connect L2 and R2 inputs */ wmcodec_write(INCTRL,0x44); /* Connect L2 and R2 inputs */

View file

@ -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_master_vol(int vol_l, int vol_r);
extern void audiohw_set_lineout_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 */ /* Register Descriptions */
#define AS3514_LINE_OUT_R 0x00 #define AS3514_LINE_OUT_R 0x00

View file

@ -105,6 +105,12 @@
#define HW_SAMPR_CAPS (SAMPR_CAP_88 | SAMPR_CAP_44 | SAMPR_CAP_22 | \ #define HW_SAMPR_CAPS (SAMPR_CAP_88 | SAMPR_CAP_44 | SAMPR_CAP_22 | \
SAMPR_CAP_11) 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 HAVE_HEADPHONE_DETECTION
#define BATTERY_CAPACITY_DEFAULT 2000 /* default battery capacity */ #define BATTERY_CAPACITY_DEFAULT 2000 /* default battery capacity */

View file

@ -58,6 +58,7 @@
/* Wolfsom audio codec */ /* Wolfsom audio codec */
#define HAVE_WM8751 #define HAVE_WM8751
#define CODEC_SRCTRL_44100HZ (0x40|(0x11 << 1)|1)
#define AB_REPEAT_ENABLE 1 #define AB_REPEAT_ENABLE 1

View file

@ -57,7 +57,7 @@ typedef int (*pcm_more_callback_type2)(int status);
/* set the pcm frequency - use values in hw_sampr_list /* set the pcm frequency - use values in hw_sampr_list
* use -1 for the default frequency * 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 */ /* apply settings to hardware immediately */
void pcm_apply_settings(void); void pcm_apply_settings(void);
@ -87,6 +87,8 @@ bool pcm_is_playing(void);
specific portion **/ specific portion **/
extern unsigned long pcm_curr_sampr; 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 */ /* the registered callback function to ask for more mp3 data */
extern volatile pcm_more_callback_type pcm_callback_for_more; 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); void pcm_play_dma_stopped_callback(void);
const void * pcm_play_dma_get_peak_buffer(int *count); const void * pcm_play_dma_get_peak_buffer(int *count);
void pcm_dma_apply_settings(void);
#ifdef HAVE_RECORDING #ifdef HAVE_RECORDING
/** RAW PCM recording routines **/ /** RAW PCM recording routines **/

View file

@ -34,19 +34,64 @@
#define LCD1_BUSY_MASK 0x8000 #define LCD1_BUSY_MASK 0x8000
/* I2S controller */ /* 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 IISCONFIG (*(volatile unsigned long *)(0xc0002500))
#define IISFIFO_CFG (*(volatile unsigned long *)(0xc000251c)) #define IISFIFO_CFG (*(volatile unsigned long *)(0xc000251c))
#define IISFIFO_WR (*(volatile unsigned long *)(0xc0002540)) #define IISFIFO_WR (*(volatile unsigned long *)(0xc0002540))
#define IISFIFO_RD (*(volatile unsigned long *)(0xc0002580)) #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_TXFIFOEN (1 << 2)
#define IIS_TX_FREE_MASK (0xf << 23) #define IIS_MASTER (1 << 4)
#define IIS_TX_FREE_COUNT ((IISFIFO_CFG & IIS_TX_FREE_MASK) >> 23)
/* IISFIFO_CFG bits: */ /**
* 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_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_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 #define IDE_BASE 0xc0003000
@ -184,6 +229,7 @@
#define DEV_RS (*(volatile unsigned long *)(0xcf005030)) #define DEV_RS (*(volatile unsigned long *)(0xcf005030))
#define DEV_I2C (1<<8) #define DEV_I2C (1<<8)
#define DEV_I2S (1<<7)
#define DEV_USB 0x400000 #define DEV_USB 0x400000
#define CLOCK_ENABLE (*(volatile unsigned long *)(0xcf005008)) #define CLOCK_ENABLE (*(volatile unsigned long *)(0xcf005008))

View file

@ -431,6 +431,9 @@
#define IIS_TX_FREE_COUNT \ #define IIS_TX_FREE_COUNT \
((IISFIFO_CFG & IIS_TX_FREE_MASK) >> 16) ((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_RXCLR (1 << 12)
#define IIS_TXCLR (1 << 8) #define IIS_TXCLR (1 << 8)
/* Number of slots */ /* Number of slots */

View file

@ -38,7 +38,7 @@ extern int tenthdb2master(int db);
* 44100: 1 = MCLK MCLK SCLK, LRCK: Audio Clk / 4 (default) * 44100: 1 = MCLK MCLK SCLK, LRCK: Audio Clk / 4 (default)
* 88200: 2 = MCLK*2 MCLK SCLK, LRCK: Audio Clk / 2 * 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); extern void audiohw_set_headphone_vol(int vol_l, int vol_r);
#define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */ #define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */

View file

@ -36,6 +36,8 @@ extern void audiohw_set_mixer_vol(int channel1, int channel2);
/** /**
* Sets frequency settings for DAC and ADC relative to MCLK * 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: * Selection for frequency ranges:
* Fs: range: with: * 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) * 44100: 2 = 25 to 50 SCLK, LRCK: Audio Clk / 4 (default)
* 88200: 3 = 50 to 100 SCLK, LRCK: Audio Clk / 2 * 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 #define UDA1380_ADDR 0x30

View file

@ -31,7 +31,7 @@
extern int tenthdb2master(int db); extern int tenthdb2master(int db);
extern void audiohw_set_master_vol(int vol_l, int vol_r); 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 */ /* Common register bits */
#ifdef HAVE_WM8731 #ifdef HAVE_WM8731

View file

@ -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_master_vol(int vol_l, int vol_r);
extern void audiohw_set_lineout_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_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 0x00
#define RESET_RESET 0x0 #define RESET_RESET 0x0

View file

@ -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_master_vol(int vol_l, int vol_r);
extern void audiohw_set_lineout_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 */ /* Register addresses and bits */

View file

@ -28,7 +28,7 @@
int tenthdb2master(int db); int tenthdb2master(int db);
void audiohw_set_headphone_vol(int vol_l, int vol_r); 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_set(unsigned int reg, unsigned int bits);
void wmc_clear(unsigned int reg, unsigned int bits); void wmc_clear(unsigned int reg, unsigned int bits);

View file

@ -24,6 +24,7 @@
#include "logf.h" #include "logf.h"
#include "audio.h" #include "audio.h"
#include "sound.h" #include "sound.h"
#include "general.h"
/** /**
* Aspects implemented in the target-specific portion: * Aspects implemented in the target-specific portion:
@ -42,11 +43,17 @@
* pcm_play_dma_pause * pcm_play_dma_pause
* pcm_play_dma_get_peak_buffer * pcm_play_dma_get_peak_buffer
* Data Read/Written within TSP - * 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_callback_for_more (R)
* pcm_playing (R) * pcm_playing (R)
* pcm_paused (R) * pcm_paused (R)
* *
* ==Playback/Recording==
* Semi-private -
* pcm_dma_apply_settings
*
* ==Recording== * ==Recording==
* Public - * Public -
* pcm_rec_lock * pcm_rec_lock
@ -76,6 +83,10 @@ volatile bool pcm_playing SHAREDBSS_ATTR = false;
volatile bool pcm_paused SHAREDBSS_ATTR = false; volatile bool pcm_paused SHAREDBSS_ATTR = false;
/* samplerate of currently playing audio - undefined if stopped */ /* samplerate of currently playing audio - undefined if stopped */
unsigned long pcm_curr_sampr SHAREDBSS_ATTR = 0; 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 * 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_play_dma_stopped_callback();
pcm_set_frequency(HW_SAMPR_DEFAULT);
logf(" pcm_play_dma_init"); logf(" pcm_play_dma_init");
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_callback_for_more = get_more;
pcm_apply_settings();
logf(" pcm_play_data_start"); logf(" pcm_play_data_start");
pcm_play_data_start(start, size); pcm_play_data_start(start, size);
@ -241,7 +256,11 @@ void pcm_play_pause(bool play)
pcm_play_dma_pause(true); pcm_play_dma_pause(true);
pcm_paused = true; pcm_paused = true;
} }
else if (pcm_get_bytes_waiting() > 0) else
{
pcm_apply_settings();
if (pcm_get_bytes_waiting() > 0)
{ {
logf(" pcm_play_dma_pause"); logf(" pcm_play_dma_pause");
pcm_play_dma_pause(false); pcm_play_dma_pause(false);
@ -253,6 +272,7 @@ void pcm_play_pause(bool play)
pcm_play_data_start(NULL, 0); pcm_play_data_start(NULL, 0);
} }
} }
}
else else
{ {
logf(" no change"); logf(" no change");
@ -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) bool pcm_is_playing(void)
{ {
return pcm_playing; return pcm_playing;
@ -411,6 +460,7 @@ void pcm_record_data(pcm_more_callback_type2 more_ready,
pcm_callback_more_ready = more_ready; pcm_callback_more_ready = more_ready;
logf(" pcm_rec_dma_start"); logf(" pcm_rec_dma_start");
pcm_apply_settings();
pcm_rec_dma_start(start, size); pcm_rec_dma_start(start, size);
pcm_recording = true; pcm_recording = true;

View file

@ -138,8 +138,10 @@ void pcm_postinit(void)
pcm_apply_settings(); 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; const int divider = (((AS3525_PLLA_FREQ/128) + (frequency/2)) / frequency) - 1;
if(divider < 0 || divider > 511) if(divider < 0 || divider > 511)
panicf("unsupported frequency %d", frequency); panicf("unsupported frequency %d", frequency);
@ -147,13 +149,6 @@ void pcm_set_frequency(unsigned int frequency)
CGU_AUDIO &= ~(((511 ^ divider) << 2) /* I2SOUT */ CGU_AUDIO &= ~(((511 ^ divider) << 2) /* I2SOUT */
/*| ((511 ^ divider) << 14) */ /* I2SIN */ /*| ((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) size_t pcm_get_bytes_waiting(void)

View file

@ -40,6 +40,23 @@ void audio_input_mux(int source, unsigned flags)
static bool last_recording = false; static bool last_recording = false;
#endif #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) switch (source)
{ {
default: /* playback - no recording */ default: /* playback - no recording */
@ -109,4 +126,3 @@ void audio_input_mux(int source, unsigned flags)
last_source = source; last_source = source;
} /* audio_input_mux */ } /* audio_input_mux */
#endif /* INPUT_SRC_CAPS != 0 */ #endif /* INPUT_SRC_CAPS != 0 */

View file

@ -25,28 +25,22 @@
* KIND, either express or implied. * KIND, either express or implied.
* *
****************************************************************************/ ****************************************************************************/
#include "system.h" #include "system.h"
#include "cpu.h" #include "cpu.h"
#include "i2s.h" #include "i2s.h"
/* TODO: Add in PP5002 defs */
#if CONFIG_CPU == PP5002 #if CONFIG_CPU == PP5002
void i2s_reset(void) void i2s_reset(void)
{ {
/* I2S device reset */ /* I2S device reset */
DEV_RS |= 0x80; DEV_RS |= DEV_I2S;
DEV_RS &= ~0x80; DEV_RS &= ~DEV_I2S;
/* I2S controller enable */ /* I2S controller enable */
IISCONFIG |= 1; IISCONFIG |= IIS_ENABLE;
/* BIT.FORMAT [11:10] = I2S (default) */
/* BIT.SIZE [9:8] = 24bit */
/* FIFO.FORMAT = 24 bit LSB */
/* reset DAC and ADC fifo */ /* reset DAC and ADC fifo */
IISFIFO_CFG |= 0x30000; IISFIFO_CFG |= IIS_RXCLR | IIS_TXCLR;
} }
#else /* PP502X */ #else /* PP502X */

View file

@ -37,9 +37,6 @@ struct dma_data
int state; int state;
}; };
static unsigned long pcm_freq; /* 44.1 is default */
static int sr_ctrl;
static struct dma_data dma_play_data = static struct dma_data dma_play_data =
{ {
/* Initialize to a locked, stopped state */ /* 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) static void __attribute__((interrupt("IRQ"))) SSI1_HANDLER(void)
{ {
register pcm_more_callback_type get_more; register pcm_more_callback_type get_more;
@ -109,19 +97,9 @@ static void __attribute__((interrupt("IRQ"))) SSI1_HANDLER(void)
pcm_play_dma_stopped_callback(); pcm_play_dma_stopped_callback();
} }
void pcm_apply_settings(void) void pcm_dma_apply_settings(void)
{ {
pcm_play_lock(); audiohw_set_frequency(pcm_fsel);
#ifdef HAVE_RECORDING
pcm_rec_lock();
#endif
_pcm_apply_settings();
#ifdef HAVE_RECORDING
pcm_rec_unlock();
#endif
pcm_play_unlock();
} }
void pcm_play_dma_init(void) void pcm_play_dma_init(void)
@ -214,7 +192,6 @@ void pcm_play_dma_init(void)
/* Enable SSI2 (codec clock) */ /* Enable SSI2 (codec clock) */
SSI_SCR2 |= SSI_SCR_SSIEN; SSI_SCR2 |= SSI_SCR_SSIEN;
pcm_set_frequency(HW_SAMPR_DEFAULT);
audiohw_init(); audiohw_init();
} }
@ -230,7 +207,7 @@ static void play_start_pcm(void)
SSI_SCR1 &= ~SSI_SCR_TE; SSI_SCR1 &= ~SSI_SCR_TE;
/* Apply new settings */ /* Apply new settings */
_pcm_apply_settings(); pcm_apply_settings();
/* Enable interrupt on unlock */ /* Enable interrupt on unlock */
dma_play_data.state = 1; 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 */ /* Return the number of bytes waiting - full L-R sample pairs only */
size_t pcm_get_bytes_waiting(void) size_t pcm_get_bytes_waiting(void)
{ {

View file

@ -25,10 +25,7 @@
#include "audio.h" #include "audio.h"
#include "sound.h" #include "sound.h"
#include "pcm.h" #include "pcm.h"
#include "pcm_sampr.h"
#ifdef HAVE_WM8751
#define MROBE100_44100HZ (0x40|(0x11 << 1)|1)
#endif
/** DMA **/ /** DMA **/
@ -87,36 +84,9 @@ static struct dma_data dma_play_data SHAREDBSS_ATTR =
.state = 0 .state = 0
}; };
static unsigned long pcm_freq SHAREDDATA_ATTR = HW_SAMPR_DEFAULT; /* 44.1 is default */ void pcm_dma_apply_settings(void)
#ifdef HAVE_WM8751
/* Samplerate control for audio codec */
static int sr_ctrl = MROBE100_44100HZ;
#endif
void pcm_set_frequency(unsigned int frequency)
{ {
#if defined(HAVE_WM8731) || defined(HAVE_WM8721) audiohw_set_frequency(pcm_fsel);
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;
} }
/* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by /* 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; IIS_IRQTX_REG &= ~IIS_IRQTX;
/* Wait for FIFO to empty */ /* Wait for FIFO to empty */
#ifdef CPU_PP502x while (!IIS_TX_IS_EMPTY);
while (IIS_TX_FREE_COUNT < 16);
#endif
dma_play_data.state = 0; dma_play_data.state = 0;
} }
@ -397,8 +365,6 @@ void pcm_play_dma_init(void)
: [iiscfg]"r"(iiscfg), [dmapd]"r"(dmapd) : [iiscfg]"r"(iiscfg), [dmapd]"r"(dmapd)
: "r2"); : "r2");
pcm_set_frequency(SAMPR_44);
/* Initialize default register values. */ /* Initialize default register values. */
audiohw_init(); audiohw_init();
@ -620,24 +586,10 @@ void pcm_rec_dma_start(void *addr, size_t size)
void pcm_rec_dma_close(void) void pcm_rec_dma_close(void)
{ {
pcm_rec_dma_stop(); 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 */ } /* pcm_close_recording */
void pcm_rec_dma_init(void) 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_rec_dma_stop();
} /* pcm_init */ } /* pcm_init */

View file

@ -58,7 +58,7 @@ struct dma_data dma_play_data SHAREDBSS_ATTR =
.state = 0 .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) void pcm_postinit(void)
{ {
@ -102,8 +102,6 @@ void pcm_play_dma_init(void)
/* Set DAI interrupts as FIQs */ /* Set DAI interrupts as FIQs */
IRQSEL = ~(DAI_RX_IRQ_MASK | DAI_TX_IRQ_MASK); IRQSEL = ~(DAI_RX_IRQ_MASK | DAI_TX_IRQ_MASK);
pcm_set_frequency(SAMPR_44);
/* Initialize default register values. */ /* Initialize default register values. */
audiohw_init(); audiohw_init();
@ -113,15 +111,8 @@ void pcm_play_dma_init(void)
#endif #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) static void play_start_pcm(void)

View file

@ -27,7 +27,7 @@
short __attribute__((section(".dmabuf"))) dma_buf_left[DMA_BUF_SAMPLES]; short __attribute__((section(".dmabuf"))) dma_buf_left[DMA_BUF_SAMPLES];
short __attribute__((section(".dmabuf"))) dma_buf_right[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; unsigned short* p IBSS_ATTR;
size_t p_size IBSS_ATTR; size_t p_size IBSS_ATTR;
@ -147,8 +147,6 @@ void pcm_init(void)
{ {
int i; int i;
pcm_set_frequency(HW_SAMPR_DEFAULT);
memset(dma_buf_left, 0, sizeof(dma_buf_left)); memset(dma_buf_left, 0, sizeof(dma_buf_left));
memset(dma_buf_right, 0, sizeof(dma_buf_right)); memset(dma_buf_right, 0, sizeof(dma_buf_right));
@ -193,15 +191,8 @@ void pcm_postinit(void)
pcm_apply_settings(); 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) size_t pcm_get_bytes_waiting(void)

View file

@ -26,12 +26,6 @@
#include "sound.h" #include "sound.h"
#include "file.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 */ /* PCM interrupt routine lockout */
static struct static struct
{ {
@ -43,11 +37,6 @@ static struct
.state = 0, .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) #define FIFO_COUNT ((IISFCON >> 6) & 0x3F)
/* Setup for the DMA controller */ /* 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 */ /* Get more data from the callback and top off the FIFO */
void fiq_handler(void) __attribute__((interrupt ("FIQ"))); 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 */ /* Mask the DMA interrupt */
void pcm_play_lock(void) void pcm_play_lock(void)
{ {
@ -89,8 +62,6 @@ void pcm_play_unlock(void)
void pcm_play_dma_init(void) void pcm_play_dma_init(void)
{ {
pcm_set_frequency(SAMPR_44);
/* There seem to be problems when changing the IIS interface configuration /* There seem to be problems when changing the IIS interface configuration
* when a clock is not present. * when a clock is not present.
*/ */
@ -128,13 +99,18 @@ void pcm_postinit(void)
pcm_apply_settings(); pcm_apply_settings();
} }
void pcm_dma_apply_settings(void)
{
audiohw_set_frequency(pcm_fsel);
}
/* Connect the DMA and start filling the FIFO */ /* Connect the DMA and start filling the FIFO */
static void play_start_pcm(void) static void play_start_pcm(void)
{ {
/* clear pending DMA interrupt */ /* clear pending DMA interrupt */
SRCPND = DMA2_MASK; SRCPND = DMA2_MASK;
_pcm_apply_settings(); pcm_apply_settings();
/* Flush any pending writes */ /* Flush any pending writes */
clean_dcache_range((void*)DISRC2, (DCON2 & 0xFFFFF) * 2); 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) size_t pcm_get_bytes_waiting(void)
{ {
/* lie a little and only return full pairs */ /* lie a little and only return full pairs */

View file

@ -28,6 +28,8 @@
#include "audiohw.h" #include "audiohw.h"
#include "dsp-target.h" #include "dsp-target.h"
static int pcm_fsel = HW_FREQ_DEFAULT;
void pcm_play_dma_init(void) void pcm_play_dma_init(void)
{ {
IO_CLK_O1DIV = 3; IO_CLK_O1DIV = 3;
@ -37,7 +39,7 @@ void pcm_play_dma_init(void)
audiohw_init(); audiohw_init();
audiohw_set_frequency(1); audiohw_set_frequency(HW_FREQ_DEFAULT);
/* init DSP */ /* init DSP */
dsp_init(); dsp_init();
@ -46,42 +48,21 @@ void pcm_play_dma_init(void)
void pcm_postinit(void) void pcm_postinit(void)
{ {
audiohw_postinit(); audiohw_postinit();
pcm_apply_settings();
/* wake DSP */ /* wake DSP */
dsp_wake(); 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) const void * pcm_play_dma_get_peak_buffer(int *count)
{ {
(void) count; (void) count;
return 0; 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) void pcm_play_dma_start(const void *addr, size_t size)

8
firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c Executable file → Normal file
View file

@ -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) void pcm_play_dma_start(const void *addr, size_t size)

View file

@ -69,66 +69,43 @@ static void iis_play_reset_if_playback(bool if_playback)
/** Sample rates **/ /** Sample rates **/
#define FPARM_CLOCKSEL 0 #define FPARM_CLOCKSEL 0
#define FPARM_CLSEL 1 #define FPARM_CLSEL 1
#define FPARM_FSEL 2
#if CONFIG_CPU == MCF5249 && defined(HAVE_UDA1380) #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_88] = { 0x0c, 0x01 },
[HW_FREQ_44] = { 0x06, 0x01, 0x02 }, [HW_FREQ_44] = { 0x06, 0x01 },
[HW_FREQ_22] = { 0x04, 0x02, 0x01 }, [HW_FREQ_22] = { 0x04, 0x02 },
[HW_FREQ_11] = { 0x02, 0x02, 0x00 }, [HW_FREQ_11] = { 0x02, 0x02 },
}; };
#endif #endif
#if (CONFIG_CPU == MCF5250 || CONFIG_CPU == MCF5249) && defined(HAVE_TLV320) #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_88] = { 0x0c, 0x01 },
[HW_FREQ_44] = { 0x06, 0x01, 0x01 }, [HW_FREQ_44] = { 0x06, 0x01 },
[HW_FREQ_22] = { 0x04, 0x01, 0x00 }, [HW_FREQ_22] = { 0x04, 0x01 },
[HW_FREQ_11] = { 0x02, 0x02, 0x00 }, [HW_FREQ_11] = { 0x02, 0x02 },
}; };
#endif #endif
static unsigned long pcm_freq = 0; /* 44.1 is default */ static const unsigned char *freq_ent;
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 */
/* apply audio settings */ /* apply audio settings */
static bool _pcm_apply_settings(bool clear_reset) static bool _pcm_dma_apply_settings(bool clear_reset)
{ {
bool did_reset = false; bool did_reset = false;
unsigned long iis_play_defparm = IIS_PLAY_DEFPARM; unsigned long iis_play_defparm;
if (pcm_freq != pcm_curr_sampr) int level = set_irq_level(DMA_IRQ_LEVEL);
/* remember table entry */
freq_ent = pcm_freq_parms[pcm_fsel];
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 /* Reprogramming bits 15-12 requires FIFO to be in a reset
condition - Users Manual 17-8, Note 11 */ condition - Users Manual 17-8, Note 11 */
or_l(IIS_FIFO_RESET, &IIS_PLAY); 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 or starting recording will sound absolutely awful once in
awhile - audiohw_set_frequency then coldfire_set_pllcr_audio_bits awhile - audiohw_set_frequency then coldfire_set_pllcr_audio_bits
*/ */
SET_IIS_PLAY(iis_play_defparm | IIS_FIFO_RESET); SET_IIS_PLAY(IIS_PLAY_DEFPARM | IIS_FIFO_RESET);
audiohw_set_frequency(freq_ent[FPARM_FSEL]); audiohw_set_frequency(pcm_fsel);
coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM);
did_reset = true; 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 be cleared. If the frequency didn't change, it was never altered and
the reset flag can just be removed or no action taken. */ the reset flag can just be removed or no action taken. */
if (clear_reset) 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 #if 0
logf("IISPLAY: %08X", IIS_PLAY); logf("IISPLAY: %08X", IIS_PLAY);
#endif #endif
return did_reset; return did_reset;
} /* _pcm_apply_settings */ } /* _pcm_dma_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);
}
/* This clears the reset bit to enable monitoring immediately if monitoring /* This clears the reset bit to enable monitoring immediately if monitoring
recording sources or always if playback is in progress - we might be recording sources or always if playback is in progress - we might be
switching samplerates on the fly */ switching samplerates on the fly */
void pcm_apply_settings(void) void pcm_dma_apply_settings(void)
{ {
int level = set_irq_level(DMA_IRQ_LEVEL); int level = set_irq_level(DMA_IRQ_LEVEL);
bool pbm = is_playback_monitoring(); bool pbm = is_playback_monitoring();
@ -174,14 +146,16 @@ void pcm_apply_settings(void)
/* Clear reset if not playback monitoring or peripheral request is /* Clear reset if not playback monitoring or peripheral request is
active and playback monitoring */ 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 */ PDOR3 = 0; /* Kick FIFO out of reset by writing to it */
restore_irq(level); restore_irq(level);
} /* pcm_apply_settings */ } /* pcm_dma_apply_settings */
void pcm_play_dma_init(void) void pcm_play_dma_init(void)
{ {
freq_ent = pcm_freq_parms[pcm_fsel];
AUDIOGLOB = (1 << 8) /* IIS1 fifo auto sync */ AUDIOGLOB = (1 << 8) /* IIS1 fifo auto sync */
| (1 << 7) /* PDIR2 fifo auto sync */ | (1 << 7) /* PDIR2 fifo auto sync */
#ifdef HAVE_SPDIF_OUT #ifdef HAVE_SPDIF_OUT
@ -200,7 +174,6 @@ void pcm_play_dma_init(void)
other settings. */ other settings. */
or_l(IIS_FIFO_RESET, &IIS_PLAY); or_l(IIS_FIFO_RESET, &IIS_PLAY);
SET_IIS_PLAY(IIS_PLAY_DEFPARM | IIS_FIFO_RESET); SET_IIS_PLAY(IIS_PLAY_DEFPARM | IIS_FIFO_RESET);
pcm_set_frequency(HW_FREQ_DEFAULT);
audio_set_output_source(AUDIO_SRC_PLAYBACK); audio_set_output_source(AUDIO_SRC_PLAYBACK);
/* Initialize default register values. */ /* Initialize default register values. */
@ -208,7 +181,7 @@ void pcm_play_dma_init(void)
audio_input_mux(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); 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); coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM);
#if defined(HAVE_SPDIF_REC) || defined(HAVE_SPDIF_OUT) #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 */ BCR0 = (unsigned long)size; /* Bytes to transfer */
/* Enable the FIFO and force one write to it */ /* 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 | DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA |
DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE) | DMA_START; 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 */ /* restart playback on current buffer */
/* Enable the FIFO and force one write to it */ /* 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); or_l(DMA_EEXT | DMA_START, &DCR0);
dma_play_lock.state = (1 << 14); 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); and_l(~PDIR2_FIFO_RESET, &DATAINCONTROL);
/* Clear TX FIFO reset bit if the source is not set to monitor playback /* Clear TX FIFO reset bit if the source is not set to monitor playback
otherwise maintain independence between playback and recording. */ 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.. */ /* Start the DMA transfer.. */
#ifdef HAVE_SPDIF_REC #ifdef HAVE_SPDIF_REC

View file

@ -58,14 +58,13 @@ void pcm_play_dma_init(void)
audiohw_init(); audiohw_init();
} }
void pcm_set_frequency(unsigned int frequency) void pcm_dma_apply_settings(void)
{ {
(void) frequency;
/* TODO */ /* TODO */
/* /*
__i2s_set_oss_sample_size(frequency); __i2s_set_oss_sample_size(pcm_sampr);
i2s_codec_set_samplerate(frequency); i2s_codec_set_samplerate(pcm_sampr);
*/ */
} }

View file

@ -33,7 +33,6 @@
#include "SDL.h" #include "SDL.h"
static int cvt_status = -1; static int cvt_status = -1;
static unsigned long pcm_frequency = SAMPR_44;
static Uint8* pcm_data; static Uint8* pcm_data;
static size_t pcm_data_size; static size_t pcm_data_size;
@ -67,28 +66,26 @@ void pcm_play_unlock(void)
SDL_UnlockAudio(); 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); obtained.format, obtained.channels, obtained.freq);
pcm_curr_sampr = pcm_frequency;
if (cvt_status < 0) { 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_play_lock();
pcm_apply_settings_nolock(); pcm_dma_apply_settings_nolock();
pcm_play_unlock(); pcm_play_unlock();
} }
void pcm_play_dma_start(const void *addr, size_t size) 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 = (Uint8 *) addr;
pcm_data_size = size; pcm_data_size = size;
@ -114,30 +111,6 @@ size_t pcm_get_bytes_waiting(void)
return pcm_data_size; 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 */ extern int sim_volume; /* in firmware/sound.c */
void write_to_soundcard(struct pcm_udata *udata) { void write_to_soundcard(struct pcm_udata *udata) {
if (cvt.needed) { if (cvt.needed) {
@ -357,7 +330,7 @@ void pcm_play_dma_init(void)
pcm_sample_bytes = obtained.channels * pcm_channel_bytes; pcm_sample_bytes = obtained.channels * pcm_channel_bytes;
pcm_apply_settings_nolock(); pcm_dma_apply_settings_nolock();
} }
void pcm_postinit(void) void pcm_postinit(void)