Sound for Sansa E200 - based on work by myself, Rene Peinthor, Barry Wardell and Christian Gmeiner from the AS3514 datasheet.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12727 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
e21d217205
commit
dfad406aa1
7 changed files with 362 additions and 56 deletions
|
@ -205,6 +205,8 @@ drivers/wm8975.c
|
|||
drivers/wm8758.c
|
||||
#elif defined(HAVE_WM8731) || defined(HAVE_WM8721)
|
||||
drivers/wm8731l.c
|
||||
#elif defined(HAVE_AS3514)
|
||||
drivers/as3514.c
|
||||
#elif defined(HAVE_TLV320)
|
||||
drivers/tlv320.c
|
||||
#endif /* defined(HAVE_*) */
|
||||
|
|
229
firmware/drivers/as3514.c
Normal file
229
firmware/drivers/as3514.c
Normal file
|
@ -0,0 +1,229 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Driver for AS3514 audio codec
|
||||
*
|
||||
* Copyright (c) 2007 Daniel Ankers
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "lcd.h"
|
||||
#include "cpu.h"
|
||||
#include "kernel.h"
|
||||
#include "thread.h"
|
||||
#include "power.h"
|
||||
#include "debug.h"
|
||||
#include "system.h"
|
||||
#include "sprintf.h"
|
||||
#include "button.h"
|
||||
#include "string.h"
|
||||
#include "file.h"
|
||||
#include "buffer.h"
|
||||
#include "audio.h"
|
||||
#include "backlight.h"
|
||||
|
||||
#include "as3514.h"
|
||||
#include "i2s.h"
|
||||
#include "i2c-pp.h"
|
||||
|
||||
/* convert tenth of dB volume to master volume register value */
|
||||
int tenthdb2master(int db)
|
||||
{
|
||||
/* +1..07 to -45.43dB in 1.5dB steps == 32 levels = 5 bits */
|
||||
/* 11111 == +1.07dB (0x1f) = 31) */
|
||||
/* 11110 == -0.43dB (0x1e) = 30) */
|
||||
/* 00001 == -43.93dB (0x01) */
|
||||
/* 00000 == -45.43dB (0x00) */
|
||||
|
||||
if (db < VOLUME_MIN) {
|
||||
return 0x0;
|
||||
} else if (db >= VOLUME_MAX) {
|
||||
return 0x1f;
|
||||
} else {
|
||||
return((db-VOLUME_MIN)/15); /* VOLUME_MIN is negative */
|
||||
}
|
||||
}
|
||||
|
||||
/* convert tenth of dB volume (-405..60) to mixer volume register value */
|
||||
int tenthdb2mixer(int db)
|
||||
{
|
||||
/* FIXME: Make this sensible */
|
||||
if (db < -405) {
|
||||
return 0x0;
|
||||
} else if (db >= 60) {
|
||||
return 0x1f;
|
||||
} else {
|
||||
return((db+405)/15);
|
||||
}
|
||||
}
|
||||
|
||||
void audiohw_reset(void);
|
||||
|
||||
/*
|
||||
* Initialise the PP I2C and I2S.
|
||||
*/
|
||||
int audiohw_init(void) {
|
||||
/* reset I2C */
|
||||
i2c_init();
|
||||
|
||||
/* normal outputs for CDI and I2S pin groups */
|
||||
DEV_INIT &= ~0x300;
|
||||
|
||||
/*mini2?*/
|
||||
outl(inl(0x70000010) & ~0x3000000, 0x70000010);
|
||||
/*mini2?*/
|
||||
|
||||
/* device reset */
|
||||
DEV_RS |= 0x800;
|
||||
DEV_RS &=~0x800;
|
||||
|
||||
/* device enable */
|
||||
DEV_EN |= 0x807;
|
||||
|
||||
/* enable external dev clock clocks */
|
||||
DEV_EN |= 0x2;
|
||||
|
||||
/* external dev clock to 24MHz */
|
||||
outl(inl(0x70000018) & ~0xc, 0x70000018);
|
||||
|
||||
i2s_reset();
|
||||
|
||||
/* Set ADC off, mixer on, DAC on, line out off, line in off, mic off */
|
||||
pp_i2c_send(AS3514_I2C_ADDR, AUDIOSET1, 0x60); /* Turn on DAC and mixer */
|
||||
pp_i2c_send(AS3514_I2C_ADDR, PLLMODE, 0x04);
|
||||
pp_i2c_send(AS3514_I2C_ADDR, DAC_L, 0x50); /* DAC mute off, -16.5dB gain */
|
||||
pp_i2c_send(AS3514_I2C_ADDR, DAC_R, 0x10); /* DAC -16.5dB gain to prevent overloading
|
||||
the headphone amp */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void audiohw_postinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* Silently enable / disable audio output */
|
||||
void audiohw_enable_output(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
/* reset the I2S controller into known state */
|
||||
i2s_reset();
|
||||
|
||||
pp_i2c_send(AS3514_I2C_ADDR, HPH_OUT_L, 0xc0); /* Mute on, power on */
|
||||
audiohw_mute(0);
|
||||
} else {
|
||||
audiohw_mute(1);
|
||||
pp_i2c_send(AS3514_I2C_ADDR, HPH_OUT_L, 0x80); /* Mute on, power off */
|
||||
}
|
||||
}
|
||||
|
||||
int audiohw_set_master_vol(int vol_l, int vol_r)
|
||||
{
|
||||
vol_l &= 0x1f;
|
||||
vol_r &= 0x1f;
|
||||
pp_i2c_send(AS3514_I2C_ADDR, HPH_OUT_R, 0x40 | vol_r);
|
||||
pp_i2c_send(AS3514_I2C_ADDR, HPH_OUT_L, 0x40 | vol_l);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audiohw_set_lineout_vol(int vol_l, int vol_r)
|
||||
{
|
||||
pp_i2c_send(AS3514_I2C_ADDR, LINE_OUT_R, 0x40 | vol_r);
|
||||
pp_i2c_send(AS3514_I2C_ADDR, LINE_OUT_L, 0x40 | vol_l);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audiohw_set_mixer_vol(int channel1, int channel2)
|
||||
{
|
||||
(void)channel1;
|
||||
(void)channel2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We are using Linear bass control */
|
||||
void audiohw_set_bass(int value)
|
||||
{
|
||||
(void)value;
|
||||
}
|
||||
|
||||
void audiohw_set_treble(int value)
|
||||
{
|
||||
(void)value;
|
||||
}
|
||||
|
||||
int audiohw_mute(int mute)
|
||||
{
|
||||
int curr;
|
||||
|
||||
curr = i2c_readbyte(AS3514_I2C_ADDR, HPH_OUT_L);
|
||||
if (mute)
|
||||
{
|
||||
pp_i2c_send(AS3514_I2C_ADDR, HPH_OUT_L, curr | 0x80);
|
||||
} else {
|
||||
pp_i2c_send(AS3514_I2C_ADDR, HPH_OUT_L, curr & ~(0x80));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Nice shutdown of WM8758 codec */
|
||||
void audiohw_close(void)
|
||||
{
|
||||
audiohw_mute(1);
|
||||
}
|
||||
|
||||
/* Change the order of the noise shaper, 5th order is recommended above 32kHz */
|
||||
void audiohw_set_nsorder(int order)
|
||||
{
|
||||
(void)order;
|
||||
}
|
||||
|
||||
void audiohw_set_sample_rate(int sampling_control)
|
||||
{
|
||||
(void)sampling_control;
|
||||
/* TODO: Implement this by adjusting the I2S Master clock */
|
||||
}
|
||||
|
||||
void audiohw_enable_recording(bool source_mic)
|
||||
{
|
||||
(void)source_mic;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void audiohw_disable_recording(void) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void audiohw_set_recvol(int left, int right, int type) {
|
||||
|
||||
(void)left;
|
||||
(void)right;
|
||||
(void)type;
|
||||
}
|
||||
|
||||
void audiohw_set_monitor(int enable) {
|
||||
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
void audiohw_set_equalizer_band(int band, int freq, int bw, int gain)
|
||||
{
|
||||
(void)band;
|
||||
(void)freq;
|
||||
(void)bw;
|
||||
(void)gain;
|
||||
}
|
78
firmware/export/as3514.h
Normal file
78
firmware/export/as3514.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 by Daniel Ankers
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _AS3514_H
|
||||
#define _AS3514_H
|
||||
|
||||
extern int tenthdb2master(int db);
|
||||
extern int tenthdb2mixer(int db);
|
||||
|
||||
extern void audiohw_reset(void);
|
||||
extern int audiohw_init(void);
|
||||
extern void audiohw_enable_output(bool enable);
|
||||
extern int audiohw_set_master_vol(int vol_l, int vol_r);
|
||||
extern int audiohw_set_lineout_vol(int vol_l, int vol_r);
|
||||
extern int audiohw_set_mixer_vol(int channel1, int channel2);
|
||||
extern void audiohw_set_bass(int value);
|
||||
extern void audiohw_set_treble(int value);
|
||||
extern int audiohw_mute(int mute);
|
||||
extern void audiohw_close(void);
|
||||
extern void audiohw_set_nsorder(int order);
|
||||
extern void audiohw_set_sample_rate(int sampling_control);
|
||||
|
||||
extern void audiohw_enable_recording(bool source_mic);
|
||||
extern void audiohw_disable_recording(void);
|
||||
extern void audiohw_set_recvol(int left, int right, int type);
|
||||
extern void audiohw_set_monitor(int enable);
|
||||
|
||||
extern void audiohw_set_equalizer_band(int band, int freq, int bw, int gain);
|
||||
|
||||
/* Register Descriptions */
|
||||
#define LINE_OUT_R 0x00
|
||||
#define LINE_OUT_L 0x01
|
||||
#define HPH_OUT_R 0x02
|
||||
#define HPH_OUT_L 0x03
|
||||
#define LSP_OUT_R 0x04
|
||||
#define LSP_OUT_L 0x05
|
||||
#define MIC1_R 0x06
|
||||
#define MIC1_L 0x07
|
||||
#define MIC2_R 0x08
|
||||
#define MIC2_L 0x09
|
||||
#define LINE_IN1_R 0x0a
|
||||
#define LINE_IN1_L 0x0b
|
||||
#define LINE_IN2_R 0x0c
|
||||
#define LINE_IN2_L 0x0d
|
||||
#define DAC_R 0x0e
|
||||
#define DAC_L 0x0f
|
||||
#define ADC_R 0x10
|
||||
#define ADC_L 0x11
|
||||
#define AUDIOSET1 0x14
|
||||
#define AUDIOSET2 0x15
|
||||
#define AUDIOSET3 0x16
|
||||
#define PLLMODE 0x1d
|
||||
|
||||
/* Headphone volume goes from -45.43 - 1.07dB */
|
||||
#define VOLUME_MIN -454
|
||||
#define VOLUME_MAX 10
|
||||
|
||||
#ifdef SANSA_E200
|
||||
#define AS3514_I2C_ADDR 0x46
|
||||
#endif
|
||||
|
||||
#endif /* _AS3514_H */
|
|
@ -40,6 +40,10 @@
|
|||
|
||||
/* Define this if you do software codec */
|
||||
#define CONFIG_CODEC SWCODEC
|
||||
/* There is no hardware tone control */
|
||||
#define HAVE_SW_TONE_CONTROLS
|
||||
/* The PP5024 has a built-in AustriaMicrosystems AS3514 */
|
||||
#define HAVE_AS3514
|
||||
|
||||
/* define this if you have a real-time clock */
|
||||
#ifndef BOOTLOADER
|
||||
|
@ -58,9 +62,6 @@
|
|||
/* The number of bytes reserved for loadable plugins */
|
||||
#define PLUGIN_BUFFER_SIZE 0x80000
|
||||
|
||||
/* Use the built-in DAC on the PP5024 */
|
||||
#define HAVE_PP5024_CODEC
|
||||
|
||||
#define AB_REPEAT_ENABLE 1
|
||||
|
||||
/* FM Tuner */
|
||||
|
|
|
@ -77,9 +77,8 @@ static const struct sound_settings_info sound_settings_table[] = {
|
|||
[SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25, sound_set_volume},
|
||||
#elif (CONFIG_CPU == PNX0101)
|
||||
[SOUND_VOLUME] = {"dB", 0, 1, -48, 15, 0, sound_set_volume},
|
||||
#elif defined(HAVE_PP5024_CODEC)
|
||||
/* TODO: Make this correct */
|
||||
[SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25, sound_set_volume},
|
||||
#elif defined(HAVE_AS3514)
|
||||
[SOUND_VOLUME] = {"dB", 0, 1, -45, 1, -25, sound_set_volume},
|
||||
#else /* MAS3507D */
|
||||
[SOUND_VOLUME] = {"dB", 0, 1, -78, 18, -18, sound_set_volume},
|
||||
[SOUND_BASS] = {"dB", 0, 1, -15, 15, 7, sound_set_bass},
|
||||
|
@ -292,17 +291,10 @@ static int tenthdb2reg(int db)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PP5024_CODEC)
|
||||
/* TODO: Work out volume/balance/treble/bass interdependency */
|
||||
#define VOLUME_MIN 0
|
||||
#define VOLUME_MAX 1
|
||||
|
||||
#endif
|
||||
|
||||
#if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
|
||||
|| defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_WM8731) \
|
||||
|| defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
|
||||
|| defined(HAVE_PP5024_CODEC)
|
||||
|| defined(HAVE_AS3514)
|
||||
/* volume/balance/treble/bass interdependency main part */
|
||||
#define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
|
||||
|
||||
|
@ -363,7 +355,8 @@ static void set_prescaled_volume(void)
|
|||
#if CONFIG_CODEC == MAS3507D
|
||||
dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
|
||||
#elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
|
||||
|| defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751)
|
||||
|| defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
|
||||
|| defined(HAVE_AS3514)
|
||||
audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
|
||||
#if defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8751)
|
||||
audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
|
||||
|
@ -479,7 +472,7 @@ void sound_set_volume(int value)
|
|||
#elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
|
||||
|| defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
|
||||
|| defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
|
||||
|| defined(HAVE_PP5024_CODEC)
|
||||
|| defined(HAVE_AS3514)
|
||||
current_volume = value * 10; /* tenth of dB */
|
||||
set_prescaled_volume();
|
||||
#elif CONFIG_CPU == PNX0101
|
||||
|
@ -500,7 +493,7 @@ void sound_set_balance(int value)
|
|||
|| defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751)
|
||||
current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
|
||||
set_prescaled_volume();
|
||||
#elif CONFIG_CPU == PNX0101 || defined(HAVE_PP5024_CODEC)
|
||||
#elif CONFIG_CPU == PNX0101 || defined(HAVE_AS3514)
|
||||
/* TODO: implement for iFP and Sansa */
|
||||
(void)value;
|
||||
#endif
|
||||
|
@ -530,8 +523,8 @@ void sound_set_bass(int value)
|
|||
current_bass = value * 10;
|
||||
audiohw_set_bass(value);
|
||||
set_prescaled_volume();
|
||||
#elif CONFIG_CPU == PNX0101 || defined(HAVE_PP5024_CODEC)
|
||||
/* TODO: implement for iFP and Sansa */
|
||||
#elif CONFIG_CPU == PNX0101
|
||||
/* TODO: implement for iFP */
|
||||
(void)value;
|
||||
#endif
|
||||
}
|
||||
|
@ -560,8 +553,8 @@ void sound_set_treble(int value)
|
|||
audiohw_set_treble(value);
|
||||
current_treble = value * 10;
|
||||
set_prescaled_volume();
|
||||
#elif CONFIG_CPU == PNX0101 || defined(HAVE_PP5024_CODEC)
|
||||
/* TODO: implement for iFP and Sansa */
|
||||
#elif CONFIG_CPU == PNX0101
|
||||
/* TODO: implement for iFP */
|
||||
(void)value;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -84,6 +84,12 @@ void i2s_reset(void)
|
|||
/* FIFO.FORMAT */
|
||||
/* If BIT.SIZE < FIFO.FORMAT low bits will be 0 */
|
||||
IISCONFIG = ((IISCONFIG & ~FIFO_FORMAT_MASK) | FIFO_FORMAT_32LSB);
|
||||
#ifdef HAVE_AS3514
|
||||
/* AS3514 can only operate as I2S Slave */
|
||||
IISCONFIG |= I2S_MASTER;
|
||||
/* Set I2S to 44.1kHz */
|
||||
outl((inl(0x70002808) & ~(0x1ff)) | 271, 0x70002808);
|
||||
#endif
|
||||
|
||||
/* RX_ATN_LVL=1 == when 12 slots full */
|
||||
/* TX_ATN_LVL=1 == when 12 slots empty */
|
||||
|
|
|
@ -30,12 +30,10 @@ static int rec_peak_left, rec_peak_right;
|
|||
#endif
|
||||
|
||||
/** DMA **/
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
#define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f000000) >> 24)
|
||||
#elif CONFIG_CPU == PP5002
|
||||
#define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x7800000) >> 23)
|
||||
#elif CONFIG_CPU == PP5024
|
||||
#define FIFO_FREE_COUNT 4 /* TODO: make this sensible */
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -54,7 +52,7 @@ size_t p_size IBSS_ATTR;
|
|||
actually needs to do so when calling pcm_callback_for_more. C version is
|
||||
still included below for reference.
|
||||
*/
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5002
|
||||
#ifdef CPU_PP
|
||||
void fiq(void) ICODE_ATTR __attribute__((naked));
|
||||
void fiq(void)
|
||||
{
|
||||
|
@ -94,10 +92,20 @@ void fiq(void)
|
|||
#endif
|
||||
"bls .fifo_full \n\t" /* FIFO full, exit */
|
||||
"ldr r10, [r9], #4 \n\t" /* load two samples */
|
||||
#ifdef HAVE_AS3514
|
||||
/* The AS3514 reads 3 bytes at a time, it seems, ignoring the lowest.
|
||||
This code seems to work well, but we may have to mask off the extra
|
||||
bits - at the expense of a few extra cycles in the FIQ */
|
||||
"mov r10, r10, ror #2\n\t" /* put left sample at the top bits */
|
||||
"str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */
|
||||
"mov r10, r10, ror #16\n\t" /* put left sample at the top bits */
|
||||
"str r10, [r12, #0x40]\n\t" /* then write it */
|
||||
#else
|
||||
"mov r10, r10, ror #16\n\t" /* put left sample at the top bits */
|
||||
"str r10, [r12, #0x40]\n\t" /* write top sample, lower sample ignored */
|
||||
"mov r10, r10, lsl #16\n\t" /* shift lower sample up */
|
||||
"str r10, [r12, #0x40]\n\t" /* then write it */
|
||||
#endif
|
||||
"subs r8, r8, #4 \n\t" /* check if we have more samples */
|
||||
"bne .fifo_loop \n\t" /* yes, continue */
|
||||
".more_data: \n\t"
|
||||
|
@ -155,7 +163,7 @@ void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ")));
|
|||
void fiq(void)
|
||||
{
|
||||
/* Clear interrupt */
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
IISCONFIG &= ~0x2;
|
||||
#elif CONFIG_CPU == PP5002
|
||||
inl(0xcf001040);
|
||||
|
@ -166,7 +174,7 @@ void fiq(void)
|
|||
while (p_size) {
|
||||
if (FIFO_FREE_COUNT < 2) {
|
||||
/* Enable interrupt */
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
IISCONFIG |= 0x2;
|
||||
#elif CONFIG_CPU == PP5002
|
||||
IISFIFO_CFG |= (1<<9);
|
||||
|
@ -197,10 +205,9 @@ void pcm_play_dma_start(const void *addr, size_t size)
|
|||
|
||||
pcm_playing = true;
|
||||
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
CPU_INT_PRIORITY |= I2S_MASK; /* FIQ priority for I2S */
|
||||
CPU_INT_EN = I2S_MASK; /* Enable I2S interrupt */
|
||||
#elif CONFIG_CPU == PP5024
|
||||
#else
|
||||
/* setup I2S interrupt for FIQ */
|
||||
outl(inl(0xcf00102c) | DMA_OUT_MASK, 0xcf00102c);
|
||||
|
@ -212,7 +219,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
|
|||
enable_fiq();
|
||||
|
||||
/* Enable playback FIFO */
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
IISCONFIG |= 0x20000000;
|
||||
#elif CONFIG_CPU == PP5002
|
||||
IISCONFIG |= 0x4;
|
||||
|
@ -223,7 +230,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
|
|||
while (p_size > 0) {
|
||||
if (FIFO_FREE_COUNT < 2) {
|
||||
/* Enable interrupt */
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
IISCONFIG |= 0x2;
|
||||
#elif CONFIG_CPU == PP5002
|
||||
IISFIFO_CFG |= (1<<9);
|
||||
|
@ -242,7 +249,7 @@ void pcm_play_dma_stop(void)
|
|||
{
|
||||
pcm_playing = false;
|
||||
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
|
||||
/* Disable playback FIFO */
|
||||
IISCONFIG &= ~0x20000000;
|
||||
|
@ -264,7 +271,7 @@ void pcm_play_dma_stop(void)
|
|||
|
||||
void pcm_play_pause_pause(void)
|
||||
{
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
/* Disable the interrupt */
|
||||
IISCONFIG &= ~0x2;
|
||||
/* Disable playback FIFO */
|
||||
|
@ -286,7 +293,7 @@ void pcm_play_pause_unpause(void)
|
|||
enable_fiq();
|
||||
|
||||
/* Enable playback FIFO */
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
IISCONFIG |= 0x20000000;
|
||||
#elif CONFIG_CPU == PP5002
|
||||
IISCONFIG |= 0x4;
|
||||
|
@ -297,7 +304,7 @@ void pcm_play_pause_unpause(void)
|
|||
while (p_size > 0) {
|
||||
if (FIFO_FREE_COUNT < 2) {
|
||||
/* Enable interrupt */
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
IISCONFIG |= 0x2;
|
||||
#elif CONFIG_CPU == PP5002
|
||||
IISFIFO_CFG |= (1<<9);
|
||||
|
@ -322,14 +329,6 @@ size_t pcm_get_bytes_waiting(void)
|
|||
return p_size;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PP5024_CODEC
|
||||
void pcm_init(void)
|
||||
{
|
||||
}
|
||||
void pcm_postinit(void)
|
||||
{
|
||||
}
|
||||
#else
|
||||
void pcm_init(void)
|
||||
{
|
||||
pcm_playing = false;
|
||||
|
@ -338,7 +337,7 @@ void pcm_init(void)
|
|||
|
||||
/* Initialize default register values. */
|
||||
audiohw_init();
|
||||
|
||||
|
||||
/* Power on */
|
||||
audiohw_enable_output(true);
|
||||
|
||||
|
@ -353,8 +352,6 @@ void pcm_postinit(void)
|
|||
{
|
||||
audiohw_postinit();
|
||||
}
|
||||
#endif /* HAVE_PP5024_CODEC */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Recording DMA transfer
|
||||
|
@ -370,7 +367,7 @@ void fiq_record(void)
|
|||
int status = 0;
|
||||
|
||||
/* Clear interrupt */
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
IISCONFIG &= ~0x01;
|
||||
#elif CONFIG_CPU == PP5002
|
||||
/* TODO */
|
||||
|
@ -379,7 +376,7 @@ void fiq_record(void)
|
|||
while (p_size > 0) {
|
||||
if (FIFO_FREE_COUNT < 2) {
|
||||
/* enable interrupt */
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
IISCONFIG |= 0x01;
|
||||
#elif CONFIG_CPU == PP5002
|
||||
/* TODO */
|
||||
|
@ -405,7 +402,7 @@ void fiq_record(void)
|
|||
peak_l = peak_r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
more_ready = pcm_callback_more_ready;
|
||||
|
||||
if (more_ready != NULL && more_ready(status) >= 0)
|
||||
|
@ -421,7 +418,7 @@ void pcm_record_more(void *start, size_t size)
|
|||
rec_peak_addr = (unsigned long *)start; /* Start peaking at dest */
|
||||
p = start;
|
||||
p_size = size; /* Bytes to transfer */
|
||||
#if CONFIG_CPU == PP5020
|
||||
#if CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024
|
||||
IISCONFIG |= 0x01;
|
||||
#elif CONFIG_CPU == PP5002
|
||||
/* TODO */
|
||||
|
@ -431,12 +428,12 @@ void pcm_record_more(void *start, size_t size)
|
|||
void pcm_rec_dma_stop(void)
|
||||
{
|
||||
logf("pcm_rec_dma_stop");
|
||||
|
||||
|
||||
/* disable fifo */
|
||||
IISCONFIG &= ~0x10000000;
|
||||
|
||||
disable_fiq();
|
||||
|
||||
|
||||
pcm_recording = false;
|
||||
}
|
||||
|
||||
|
@ -445,11 +442,11 @@ void pcm_rec_dma_start(void *addr, size_t size)
|
|||
logf("pcm_rec_dma_start");
|
||||
|
||||
pcm_recording = true;
|
||||
|
||||
|
||||
peak_l = peak_r = 0;
|
||||
p_size = size;
|
||||
p = addr;
|
||||
|
||||
|
||||
/* setup FIQ */
|
||||
CPU_INT_PRIORITY |= I2S_MASK;
|
||||
CPU_INT_EN = I2S_MASK;
|
||||
|
@ -470,7 +467,7 @@ void pcm_close_recording(void)
|
|||
|
||||
pcm_rec_dma_stop();
|
||||
|
||||
#if (CONFIG_CPU == PP5020)
|
||||
#if (CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024)
|
||||
disable_fiq();
|
||||
|
||||
/* disable fifo */
|
||||
|
@ -488,7 +485,7 @@ void pcm_init_recording(void)
|
|||
pcm_recording = false;
|
||||
pcm_callback_more_ready = NULL;
|
||||
|
||||
#if (CONFIG_CPU == PP5020)
|
||||
#if (CONFIG_CPU == PP5020 || CONFIG_CPU == PP5024)
|
||||
#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. */
|
||||
|
|
Loading…
Reference in a new issue