mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
HD200 - Setup codec as I2S master and enable recording
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27250 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
15d0ac0134
commit
971a6e9c94
5 changed files with 138 additions and 79 deletions
|
@ -42,6 +42,14 @@ const struct sound_settings_info audiohw_settings[] = {
|
|||
[SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
|
||||
[SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
|
||||
[SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
|
||||
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
||||
[SOUND_DEPTH_3D] = {"", 0, 1, 0, 15, 0},
|
||||
#endif
|
||||
#ifdef HAVE_RECORDING
|
||||
[SOUND_LEFT_GAIN] = {"dB", 1, 1,-172, 300, 0},
|
||||
[SOUND_RIGHT_GAIN] = {"dB", 1, 1,-172, 300, 0},
|
||||
[SOUND_MIC_GAIN] = {"dB", 1, 1,-172, 300, 0},
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Flags used in combination with settings */
|
||||
|
@ -110,7 +118,7 @@ static int recvol2hw(int value)
|
|||
/* 010111 == 0dB (0x17) */
|
||||
/* 000000 == -17.25dB */
|
||||
|
||||
return (3*(value/10 - 0x17))/4;
|
||||
return ((4*(value))/30 + 0x17);
|
||||
}
|
||||
#endif
|
||||
static void audiohw_mute(bool mute)
|
||||
|
@ -167,6 +175,14 @@ void audiohw_postinit(void)
|
|||
|
||||
/* 4. Enable line and / or headphone output buffers as required. */
|
||||
#if defined(MROBE_100) || defined(MPIO_HD200)
|
||||
/* fix for high pitch noise after power-up on HD200
|
||||
* it is *NOT* required step according to the
|
||||
* Datasheet for WM8750L but real life is different :-)
|
||||
*/
|
||||
wmcodec_write(LOUT1, LOUT1_BITS);
|
||||
wmcodec_write(ROUT1, ROUT1_BITS);
|
||||
|
||||
/* power-up output stage */
|
||||
wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
|
||||
PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
|
||||
#else
|
||||
|
@ -196,16 +212,6 @@ void audiohw_postinit(void)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MPIO_HD200
|
||||
/* Crude fix for high pitch noise at startup
|
||||
* I should find out what realy causes this
|
||||
*/
|
||||
wmcodec_write(LOUT1, LOUT1_BITS|0x7f);
|
||||
wmcodec_write(ROUT1, ROUT1_BITS|0x7f);
|
||||
wmcodec_write(LOUT1, LOUT1_BITS);
|
||||
wmcodec_write(ROUT1, ROUT1_BITS);
|
||||
#endif
|
||||
|
||||
/* lower power consumption */
|
||||
wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
|
||||
|
||||
|
@ -276,10 +282,12 @@ void audiohw_close(void)
|
|||
wmcodec_write(PWRMGMT1, 0x0);
|
||||
}
|
||||
|
||||
/* According to datasheet of WM8750
|
||||
* clocking setup is needed in both slave and master mode
|
||||
*/
|
||||
void audiohw_set_frequency(int fsel)
|
||||
{
|
||||
(void)fsel;
|
||||
#ifndef CODEC_SLAVE
|
||||
static const unsigned char srctrl_table[HW_NUM_FREQ] =
|
||||
{
|
||||
HW_HAVE_11_([HW_FREQ_11] = CODEC_SRCTRL_11025HZ,)
|
||||
|
@ -292,10 +300,23 @@ void audiohw_set_frequency(int fsel)
|
|||
fsel = HW_FREQ_DEFAULT;
|
||||
|
||||
wmcodec_write(CLOCKING, srctrl_table[fsel]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(HAVE_WM8750)
|
||||
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
||||
/* Set the depth of the 3D effect */
|
||||
void audiohw_set_depth_3d(int val)
|
||||
{
|
||||
if (val)
|
||||
wmcodec_write(ENHANCE_3D,
|
||||
ENHANCE_3D_MODE3D_PLAYBACK | ENHANCE_3D_DEPTH(val) |
|
||||
ENHANCE_3D_3DEN);
|
||||
else
|
||||
wmcodec_write(ENHANCE_3D,ENHANCE_3D_MODE3D_PLAYBACK);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RECORDING
|
||||
void audiohw_set_recsrc(int source, bool recording)
|
||||
{
|
||||
/* INPUT1 - FM radio
|
||||
|
@ -307,17 +328,30 @@ void audiohw_set_recsrc(int source, bool recording)
|
|||
* turn on output buffer(s)
|
||||
*
|
||||
* if recording == true we route input signal to PGA
|
||||
* and monitoring picks up signal after PGA in analog domain
|
||||
* and monitoring picks up signal after PGA and ADC
|
||||
* turn on ADC, PGA, DAC, output buffer(s)
|
||||
*/
|
||||
|
||||
switch(source)
|
||||
{
|
||||
case AUDIO_SRC_PLAYBACK:
|
||||
/* mute PGA, disable all audio paths but DAC and output stage*/
|
||||
wmcodec_write(LINVOL, LINVOL_LINMUTE | LINVOL_LINVOL(23)); /* 0dB */
|
||||
wmcodec_write(RINVOL, RINVOL_RINMUTE | RINVOL_RINVOL(23)); /* 0dB */
|
||||
/* turn off DAC and ADC in order to setup Enchance 3D function
|
||||
* for playback. This does not turn on enchancement but
|
||||
* the switch between playback/record has to be done with
|
||||
* DAC and ADC off
|
||||
*/
|
||||
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
||||
wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
|
||||
wmcodec_write(PWRMGMT2, 0x00);
|
||||
wmcodec_write(ENHANCE_3D, ENHANCE_3D_MODE3D_PLAYBACK);
|
||||
#endif
|
||||
/* mute PGA, disable all audio paths but DAC and output stage*/
|
||||
wmcodec_write(LINVOL, LINVOL_LINMUTE | LINVOL_LINVOL(0x17)); /* 0dB */
|
||||
wmcodec_write(RINVOL, RINVOL_RINMUTE | RINVOL_RINVOL(0x17)); /* 0dB */
|
||||
|
||||
wmcodec_write(LOUT1, LOUT1_BITS);
|
||||
wmcodec_write(ROUT1, ROUT1_BITS);
|
||||
|
||||
wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
|
||||
PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
|
||||
|
||||
|
@ -332,15 +366,26 @@ void audiohw_set_recsrc(int source, bool recording)
|
|||
case AUDIO_SRC_FMRADIO:
|
||||
if(recording)
|
||||
{
|
||||
/* Set input volume to PGA */
|
||||
wmcodec_write(LINVOL, LINVOL_LINVOL(23));
|
||||
wmcodec_write(RINVOL, RINVOL_RINVOL(23));
|
||||
/* turn off DAC and ADC in order to setup Enchance 3D function
|
||||
* for playback. This does not turn on enchancement but
|
||||
* the switch between playback/record has to be done with
|
||||
* DAC and ADC off
|
||||
*/
|
||||
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
||||
wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
|
||||
wmcodec_write(PWRMGMT2, 0x00);
|
||||
wmcodec_write(ENHANCE_3D, ENHANCE_3D_MODE3D_RECORD);
|
||||
#endif
|
||||
|
||||
/* Turn on PGA and ADC */
|
||||
wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K |
|
||||
PWRMGMT1_AINL | PWRMGMT1_AINR |
|
||||
PWRMGMT1_ADCL | PWRMGMT1_ADCR);
|
||||
|
||||
/* Set input volume to PGA 0dB*/
|
||||
wmcodec_write(LINVOL, LINVOL_LIVU|LINVOL_LINVOL(0x17));
|
||||
wmcodec_write(RINVOL, RINVOL_RIVU|RINVOL_RINVOL(0x17));
|
||||
|
||||
/* Setup input source for PGA as INPUT1
|
||||
* MICBOOST disabled
|
||||
*/
|
||||
|
@ -356,18 +401,18 @@ void audiohw_set_recsrc(int source, bool recording)
|
|||
wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
|
||||
PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
|
||||
|
||||
/* analog monitor */
|
||||
wmcodec_write(LEFTMIX1, LEFTMIX1_LMIXSEL_ADCLIN |
|
||||
LEFTMIX1_LD2LO);
|
||||
wmcodec_write(RIGHTMIX2, RIGHTMIX2_RMIXSEL_ADCRIN |
|
||||
RIGHTMIX2_RD2RO);
|
||||
/* route DAC signal to output mixer */
|
||||
wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO);
|
||||
wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* turn off ADC, PGA */
|
||||
wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
|
||||
|
||||
wmcodec_write(LOUT1, LOUT1_BITS);
|
||||
wmcodec_write(ROUT1, ROUT1_BITS);
|
||||
|
||||
/* turn on DAC and output stage */
|
||||
wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
|
||||
PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
|
||||
|
@ -377,17 +422,24 @@ void audiohw_set_recsrc(int source, bool recording)
|
|||
*/
|
||||
wmcodec_write(LEFTMIX1, LEFTMIX1_LI2LO | LEFTMIX1_LMIXSEL_LINPUT1 |
|
||||
LEFTMIX1_LI2LOVOL(0x20) | LEFTMIX1_LD2LO);
|
||||
wmcodec_write(RIGHTMIX2, RIGHTMIX2_RI2RO | RIGHTMIX2_RMIXSEL_RINPUT1 |
|
||||
wmcodec_write(RIGHTMIX1, RIGHTMIX1_RMIXSEL_RINPUT1);
|
||||
wmcodec_write(RIGHTMIX2, RIGHTMIX2_RI2RO |
|
||||
RIGHTMIX2_RI2ROVOL(0x20) | RIGHTMIX2_RD2RO);
|
||||
}
|
||||
break;
|
||||
|
||||
case AUDIO_SRC_LINEIN:
|
||||
/* Set input volume to PGA */
|
||||
wmcodec_write(LINVOL, LINVOL_LINVOL(23));
|
||||
wmcodec_write(RINVOL, RINVOL_RINVOL(23));
|
||||
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
||||
wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
|
||||
wmcodec_write(PWRMGMT2, 0x00);
|
||||
wmcodec_write(ENHANCE_3D, ENHANCE_3D_MODE3D_RECORD);
|
||||
#endif
|
||||
|
||||
/* Turn on PGA, ADC, DAC */
|
||||
/* Set input volume to PGA */
|
||||
wmcodec_write(LINVOL, LINVOL_LIVU | LINVOL_LINVOL(23));
|
||||
wmcodec_write(RINVOL, RINVOL_RIVU | RINVOL_RINVOL(23));
|
||||
|
||||
/* Turn on PGA, ADC */
|
||||
wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K |
|
||||
PWRMGMT1_AINL | PWRMGMT1_AINR |
|
||||
PWRMGMT1_ADCL | PWRMGMT1_ADCR);
|
||||
|
@ -406,18 +458,21 @@ void audiohw_set_recsrc(int source, bool recording)
|
|||
* default is LADC -> LDATA, RADC -> RDATA
|
||||
* so we don't touch this
|
||||
*/
|
||||
|
||||
/* digital monitor */
|
||||
wmcodec_write(LEFTMIX1, LEFTMIX1_LMIXSEL_ADCLIN |
|
||||
LEFTMIX1_LD2LO);
|
||||
wmcodec_write(RIGHTMIX2, RIGHTMIX2_RMIXSEL_ADCRIN |
|
||||
RIGHTMIX2_RD2RO);
|
||||
/* route DAC signal to output mixer */
|
||||
wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO);
|
||||
wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO);
|
||||
break;
|
||||
|
||||
case AUDIO_SRC_MIC:
|
||||
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
||||
wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
|
||||
wmcodec_write(PWRMGMT2, 0x00);
|
||||
wmcodec_write(ENHANCE_3D, ENHANCE_3D_MODE3D_RECORD);
|
||||
#endif
|
||||
|
||||
/* Set input volume to PGA */
|
||||
wmcodec_write(LINVOL, LINVOL_LINVOL(23));
|
||||
wmcodec_write(RINVOL, RINVOL_RINVOL(23));
|
||||
wmcodec_write(LINVOL, LINVOL_LIVU | LINVOL_LINVOL(23));
|
||||
wmcodec_write(RINVOL, RINVOL_RIVU | RINVOL_RINVOL(23));
|
||||
|
||||
/* Turn on PGA and ADC, turn off DAC */
|
||||
wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K |
|
||||
|
@ -439,21 +494,19 @@ void audiohw_set_recsrc(int source, bool recording)
|
|||
* so we don't touch this
|
||||
*/
|
||||
|
||||
/* analog monitor */
|
||||
wmcodec_write(LEFTMIX1, LEFTMIX1_LMIXSEL_ADCLIN |
|
||||
LEFTMIX1_LD2LO);
|
||||
wmcodec_write(RIGHTMIX2, RIGHTMIX2_RMIXSEL_ADCRIN |
|
||||
RIGHTMIX2_RD2RO);
|
||||
break;
|
||||
/* route DAC signal to output mixer */
|
||||
wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO);
|
||||
wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO);
|
||||
|
||||
} /* switch(source) */
|
||||
}
|
||||
|
||||
/* Setup PGA gain */
|
||||
void audiohw_set_recvol(int left, int right, int type)
|
||||
void audiohw_set_recvol(int vol_l, int vol_r, int type)
|
||||
{
|
||||
(void)type;
|
||||
wmcodec_write(LINVOL, LINVOL_LINVOL(recvol2hw(left)));
|
||||
wmcodec_write(RINVOL, RINVOL_RINVOL(recvol2hw(right)));
|
||||
wmcodec_write(LINVOL, LINVOL_LIZC|LINVOL_LINVOL(recvol2hw(vol_l)));
|
||||
wmcodec_write(RINVOL, RINVOL_RIZC|RINVOL_RIVU|RINVOL_RINVOL(recvol2hw(vol_r)));
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_RECORDING */
|
||||
#endif /* HAVE_WM8750 */
|
||||
|
|
|
@ -14,26 +14,18 @@
|
|||
#define ATA_SWAP_WORDS
|
||||
|
||||
/* define this if you have recording possibility */
|
||||
/* not implemented yet
|
||||
* #define HAVE_RECORDING
|
||||
*/
|
||||
|
||||
#define HAVE_RECORDING
|
||||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
* explicitly if different
|
||||
* not implemented yet
|
||||
*/
|
||||
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO)
|
||||
|
||||
|
||||
/* define the bitmask of hardware sample rates */
|
||||
#define HW_SAMPR_CAPS (SAMPR_CAP_88 | SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11)
|
||||
|
||||
/* define the bitmask of recording sample rates
|
||||
* not implemented yet
|
||||
*#define REC_SAMPR_CAPS (SAMPR_CAP_88 | SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11)
|
||||
*/
|
||||
/* define the bitmask of recording sample rates */
|
||||
#define REC_SAMPR_CAPS (SAMPR_CAP_88 | SAMPR_CAP_44 | SAMPR_CAP_22 | SAMPR_CAP_11)
|
||||
|
||||
/* define this if you have a bitmap LCD display */
|
||||
#define HAVE_LCD_BITMAP
|
||||
|
@ -114,9 +106,17 @@
|
|||
#define CONFIG_TUNER_XTAL 32768
|
||||
|
||||
|
||||
/* we have WM8750 codec in I2S slave mode */
|
||||
/* we have WM8750 codec in I2S master mode */
|
||||
#define HAVE_WM8750
|
||||
#define CODEC_SLAVE
|
||||
|
||||
/* clocking setup based on 11.2896 MHz master clock
|
||||
* provided to the codec by MCU
|
||||
* WM8750L Datasheet Table 40, page 46
|
||||
*/
|
||||
#define CODEC_SRCTRL_11025HZ (0x18 << 1)
|
||||
#define CODEC_SRCTRL_22050HZ (0x1A << 1)
|
||||
#define CODEC_SRCTRL_44100HZ (0x10 << 1)
|
||||
#define CODEC_SRCTRL_88200HZ (0x1E << 1)
|
||||
|
||||
#define BATTERY_CAPACITY_DEFAULT 950 /* default battery capacity */
|
||||
#define BATTERY_CAPACITY_MIN 950 /* min. capacity selectable */
|
||||
|
@ -142,12 +142,6 @@
|
|||
/* Define this if you want to use coldfire's i2c interface */
|
||||
#define CONFIG_I2C I2C_COLDFIRE
|
||||
|
||||
/* OF resets device instead of poweroff while charging
|
||||
* this triggers bootloader code which takes care of charging.
|
||||
* I have feeling that powering off while charging may cause
|
||||
* partition table corruption I am experiencing from time to time
|
||||
*/
|
||||
|
||||
/* define this if the hardware can be powered off while charging */
|
||||
/* #define HAVE_POWEROFF_WHILE_CHARGING */
|
||||
|
||||
|
|
|
@ -25,13 +25,19 @@
|
|||
#define VOLUME_MIN -730
|
||||
#define VOLUME_MAX 60
|
||||
|
||||
/* turn off 3D Enchance feature of WM8750 for now
|
||||
#if defined(HAVE_WM8750)
|
||||
#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | DEPTH_3D_CAP)
|
||||
#else
|
||||
*/
|
||||
#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP)
|
||||
/* #endif */
|
||||
|
||||
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);
|
||||
#if defined(HAVE_WM8750)
|
||||
#if defined(HAVE_WM8750) && defined(HAVE_RECORDING)
|
||||
void audiohw_set_recsrc(int source, bool recording);
|
||||
#endif
|
||||
|
||||
|
@ -222,7 +228,7 @@ void audiohw_set_recsrc(int source, bool recording);
|
|||
#define ADCL_LMICBOOST_13DB (1 << 4)
|
||||
#define ADCL_LMICBOOST_20DB (2 << 4)
|
||||
#define ADCL_LMICBOOST_29DB (3 << 4)
|
||||
#define ADCL_LMICBOOST(x) ((x) & (0x3 << 7))
|
||||
#define ADCL_LMICBOOST(x) (((x) & 0x3) << 4))
|
||||
#define ADCL_LINSEL_LINPUT1 (0 << 6)
|
||||
#define ADCL_LINSEL_LINPUT2 (1 << 6)
|
||||
#define ADCL_LINSEL_LINPUT3 (2 << 6)
|
||||
|
|
|
@ -46,6 +46,7 @@ void audio_set_output_source(int source)
|
|||
if ((unsigned)source >= AUDIO_NUM_SOURCES)
|
||||
source = AUDIO_SRC_PLAYBACK;
|
||||
|
||||
/* route incoming audio samples to DAC */
|
||||
IIS2CONFIG = (IIS2CONFIG & ~(7 << 8)) | (txsrc_select[source+1] << 8);
|
||||
|
||||
restore_irq(level);
|
||||
|
@ -89,10 +90,10 @@ void audio_input_mux(int source, unsigned flags)
|
|||
|
||||
last_recording = recording;
|
||||
|
||||
audiohw_set_recsrc(source,recording);
|
||||
/* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */
|
||||
coldfire_set_dataincontrol(recording ?
|
||||
((3 << 14) | (4 << 3)) : 0);
|
||||
audiohw_set_recsrc(source, recording);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,13 +84,18 @@ static const unsigned char pcm_freq_parms[HW_NUM_FREQ][2] =
|
|||
#endif
|
||||
|
||||
#if CONFIG_CPU == MCF5249 && defined(HAVE_WM8750)
|
||||
/* We run codec in master mode.
|
||||
* Codec can reconstruct all frequencies
|
||||
* from single 11.2896 MHz master clock
|
||||
*/
|
||||
static const unsigned char pcm_freq_parms[HW_NUM_FREQ][2] =
|
||||
{
|
||||
[HW_FREQ_88] = { 0x0c, 0x01 },
|
||||
[HW_FREQ_44] = { 0x06, 0x01 },
|
||||
[HW_FREQ_22] = { 0x04, 0x01 },
|
||||
[HW_FREQ_11] = { 0x02, 0x01 },
|
||||
[HW_FREQ_88] = { 0x00, 0x01 },
|
||||
[HW_FREQ_44] = { 0x00, 0x01 },
|
||||
[HW_FREQ_22] = { 0x00, 0x01 },
|
||||
[HW_FREQ_11] = { 0x00, 0x01 },
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if (CONFIG_CPU == MCF5250 || CONFIG_CPU == MCF5249) && defined(HAVE_TLV320)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue