x1000: refactor AIC initialization
Have pcm-x1000 handle most work, so target's audiohw code touches only the relevant settings. Change-Id: Icf3d1b7ca428ac50a5a16ecec39ed8186ac5ae13
This commit is contained in:
parent
c78ba1aa68
commit
f63edb52ef
7 changed files with 322 additions and 85 deletions
|
@ -31,12 +31,12 @@
|
|||
* is complete if this value is less than "cnt", and may be incomplete if it
|
||||
* is equal to "cnt". (Note the leading zero term is not written to "buf".)
|
||||
*/
|
||||
static unsigned cf_derive(unsigned m, unsigned n, unsigned* buf, unsigned cnt)
|
||||
static uint32_t cf_derive(uint32_t m, uint32_t n, uint32_t* buf, uint32_t cnt)
|
||||
{
|
||||
unsigned wrote = 0;
|
||||
unsigned a = m / n;
|
||||
uint32_t wrote = 0;
|
||||
uint32_t a = m / n;
|
||||
while(cnt--) {
|
||||
unsigned tmp = n;
|
||||
uint32_t tmp = n;
|
||||
n = m - n * a;
|
||||
if(n == 0)
|
||||
break;
|
||||
|
@ -54,16 +54,16 @@ static unsigned cf_derive(unsigned m, unsigned n, unsigned* buf, unsigned cnt)
|
|||
* calculate the rational number m/n which it represents. Returns m and n.
|
||||
* If count is zero, then m and n are undefined.
|
||||
*/
|
||||
static void cf_expand(const unsigned* buf, unsigned count,
|
||||
unsigned* m, unsigned* n)
|
||||
static void cf_expand(const uint32_t* buf, uint32_t count,
|
||||
uint32_t* m, uint32_t* n)
|
||||
{
|
||||
if(count == 0)
|
||||
return;
|
||||
|
||||
unsigned i = count - 1;
|
||||
unsigned mx = 1, nx = buf[i];
|
||||
uint32_t i = count - 1;
|
||||
uint32_t mx = 1, nx = buf[i];
|
||||
while(i--) {
|
||||
unsigned tmp = nx;
|
||||
uint32_t tmp = nx;
|
||||
nx = mx + buf[i] * nx;
|
||||
mx = tmp;
|
||||
}
|
||||
|
@ -72,48 +72,102 @@ static void cf_expand(const unsigned* buf, unsigned count,
|
|||
*n = nx;
|
||||
}
|
||||
|
||||
int aic_i2s_set_mclk(x1000_clk_t clksrc, unsigned fs, unsigned mult)
|
||||
static int calc_i2s_clock_params(x1000_clk_t clksrc,
|
||||
uint32_t fs, uint32_t mult,
|
||||
uint32_t* div_m, uint32_t* div_n,
|
||||
uint32_t* i2sdiv)
|
||||
{
|
||||
/* get the input clock rate */
|
||||
uint32_t src_freq = clk_get(clksrc);
|
||||
if(clksrc == X1000_CLK_EXCLK) {
|
||||
/* EXCLK mode bypasses the CPM clock so it's more limited */
|
||||
*div_m = 0;
|
||||
*div_n = 0;
|
||||
*i2sdiv = X1000_EXCLK_FREQ / 64 / fs;
|
||||
|
||||
/* reject invalid parameters */
|
||||
/* clamp to maximum value */
|
||||
if(*i2sdiv > 0x200)
|
||||
*i2sdiv = 0x200;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ensure a valid clock was selected */
|
||||
if(clksrc != X1000_CLK_SCLK_A &&
|
||||
clksrc != X1000_CLK_MPLL)
|
||||
return -1;
|
||||
|
||||
/* ensure bit clock constraint is respected */
|
||||
if(mult % 64 != 0)
|
||||
return -1;
|
||||
|
||||
if(clksrc == X1000_EXCLK_FREQ) {
|
||||
if(mult != 0)
|
||||
return -1;
|
||||
/* ensure master clock frequency is not too high */
|
||||
if(fs > UINT32_MAX/mult)
|
||||
return -1;
|
||||
|
||||
jz_writef(AIC_I2SCR, STPBK(1));
|
||||
/* get frequencies */
|
||||
uint32_t tgt_freq = fs * mult;
|
||||
uint32_t src_freq = clk_get(clksrc);
|
||||
|
||||
/* calculate best rational approximation fitting hardware constraints */
|
||||
uint32_t m = 0, n = 0;
|
||||
uint32_t buf[16];
|
||||
uint32_t cnt = cf_derive(tgt_freq, src_freq, &buf[0], 16);
|
||||
do {
|
||||
cf_expand(&buf[0], cnt, &m, &n);
|
||||
cnt -= 1;
|
||||
} while(cnt > 0 && (m > 512 || n > 8192) && (n >= 2*m));
|
||||
|
||||
/* unrepresentable */
|
||||
if(cnt == 0 || n == 0 || m == 0)
|
||||
return -1;
|
||||
|
||||
*div_m = m;
|
||||
*div_n = n;
|
||||
*i2sdiv = mult / 64;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t aic_calc_i2s_clock(x1000_clk_t clksrc, uint32_t fs, uint32_t mult)
|
||||
{
|
||||
uint32_t m, n, i2sdiv;
|
||||
if(calc_i2s_clock_params(clksrc, fs, mult, &m, &n, &i2sdiv))
|
||||
return 0;
|
||||
|
||||
unsigned long long rate = clk_get(clksrc);
|
||||
rate *= m;
|
||||
rate /= n * i2sdiv; /* this multiply can't overflow. */
|
||||
|
||||
/* clamp */
|
||||
if(rate > 0xffffffffull)
|
||||
rate = 0xffffffff;
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
int aic_set_i2s_clock(x1000_clk_t clksrc, uint32_t fs, uint32_t mult)
|
||||
{
|
||||
uint32_t m, n, i2sdiv;
|
||||
if(calc_i2s_clock_params(clksrc, fs, mult, &m, &n, &i2sdiv))
|
||||
return -1;
|
||||
|
||||
/* turn off bit clock */
|
||||
bool bitclock_en = !jz_readf(AIC_I2SCR, STPBK);
|
||||
jz_writef(AIC_I2SCR, STPBK(1));
|
||||
|
||||
/* handle master clock */
|
||||
if(clksrc == X1000_CLK_EXCLK) {
|
||||
jz_writef(CPM_I2SCDR, CS(0), CE(0));
|
||||
REG_AIC_I2SDIV = X1000_EXCLK_FREQ / 64 / fs;
|
||||
} else {
|
||||
if(mult == 0)
|
||||
return -1;
|
||||
if(fs*mult > src_freq)
|
||||
return -1;
|
||||
|
||||
/* calculate best rational approximation that fits our constraints */
|
||||
unsigned m = 0, n = 0;
|
||||
unsigned buf[16];
|
||||
unsigned cnt = cf_derive(fs*mult, src_freq, &buf[0], 16);
|
||||
do {
|
||||
cf_expand(&buf[0], cnt, &m, &n);
|
||||
cnt -= 1;
|
||||
} while(cnt > 0 && (m > 512 || n > 8192) && (n >= 2*m));
|
||||
|
||||
/* wrong values */
|
||||
if(cnt == 0 || n == 0 || m == 0)
|
||||
return -1;
|
||||
|
||||
jz_writef(AIC_I2SCR, STPBK(1));
|
||||
jz_writef(CPM_I2SCDR, PCS(clksrc == X1000_CLK_MPLL ? 1 : 0),
|
||||
CS(1), CE(1), DIV_M(m), DIV_N(n));
|
||||
jz_write(CPM_I2SCDR1, REG_CPM_I2SCDR1);
|
||||
REG_AIC_I2SDIV = (mult / 64) - 1;
|
||||
}
|
||||
|
||||
jz_writef(AIC_I2SCR, STPBK(0));
|
||||
/* set bit clock divider */
|
||||
REG_AIC_I2SDIV = i2sdiv - 1;
|
||||
|
||||
/* re-enable the bit clock */
|
||||
if(bitclock_en)
|
||||
jz_writef(AIC_I2SCR, STPBK(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,24 +23,122 @@
|
|||
#define __AIC_X1000_H__
|
||||
|
||||
#include "clk-x1000.h"
|
||||
#include "x1000/aic.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Set frequency of I2S master clock supplied by AIC. Has no use if an
|
||||
* external DAC is supplying the master clock. Must be called with the
|
||||
* bit clock disabled.
|
||||
#define AIC_I2S_MASTER_MODE 0
|
||||
#define AIC_I2S_MASTER_EXCLK_MODE 1
|
||||
#define AIC_I2S_SLAVE_MODE 2
|
||||
|
||||
#define AIC_I2S_LEFT_CHANNEL_FIRST 0
|
||||
#define AIC_I2S_RIGHT_CHANNEL_FIRST 1
|
||||
|
||||
/* Nb. the functions below are intended to serve as "documentation" and make
|
||||
* target audiohw code clearer, they should normally be called with immediate
|
||||
* constant arguments so they are inlined to a register read-modify-write. */
|
||||
|
||||
/* Enable/disable some kind of big-endian mode. Presumably it refers to
|
||||
* the endianness of the samples read or written to the FIFO. */
|
||||
static inline void aic_set_big_endian_format(bool en)
|
||||
{
|
||||
jz_writef(AIC_CFG, MSB(en ? 1 : 0));
|
||||
}
|
||||
|
||||
/* Set whether to send the last sample (true) or a zero sample (false)
|
||||
* if the AIC FIFO underflows during playback. */
|
||||
static inline void aic_set_play_last_sample(bool en)
|
||||
{
|
||||
jz_writef(AIC_CFG, LSMP(en ? 1 : 0));
|
||||
}
|
||||
|
||||
/* Select the use of the internal or external codec. */
|
||||
static inline void aic_set_external_codec(bool en)
|
||||
{
|
||||
jz_writef(AIC_CFG, ICDC(en ? 0 : 1));
|
||||
}
|
||||
|
||||
/* Set I2S interface mode */
|
||||
static inline void aic_set_i2s_mode(int mode)
|
||||
{
|
||||
switch(mode) {
|
||||
default:
|
||||
case AIC_I2S_MASTER_MODE:
|
||||
jz_writef(AIC_CFG, BCKD(1), SYNCD(1));
|
||||
break;
|
||||
|
||||
case AIC_I2S_MASTER_EXCLK_MODE:
|
||||
jz_writef(AIC_CFG, BCKD(0), SYNCD(1));
|
||||
break;
|
||||
|
||||
case AIC_I2S_SLAVE_MODE:
|
||||
jz_writef(AIC_CFG, BCKD(0), SYNCD(0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select the channel ordering on the I2S interface (playback only). */
|
||||
static inline void aic_set_i2s_channel_order(int order)
|
||||
{
|
||||
switch(order) {
|
||||
default:
|
||||
case AIC_I2S_LEFT_CHANNEL_FIRST:
|
||||
jz_writef(AIC_I2SCR, RFIRST(0));
|
||||
break;
|
||||
|
||||
case AIC_I2S_RIGHT_CHANNEL_FIRST:
|
||||
jz_writef(AIC_I2SCR, RFIRST(1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable/disable the I2S master clock (also called 'system clock') */
|
||||
static inline void aic_enable_i2s_master_clock(bool en)
|
||||
{
|
||||
jz_writef(AIC_I2SCR, ESCLK(en ? 1 : 0));
|
||||
}
|
||||
|
||||
/* Enable/disable the I2S bit clock */
|
||||
static inline void aic_enable_i2s_bit_clock(bool en)
|
||||
{
|
||||
jz_writef(AIC_I2SCR, STPBK(en ? 0 : 1));
|
||||
}
|
||||
|
||||
/* Select whether I2S mode is used (false) or MSB-justified mode (true). */
|
||||
static inline void aic_set_msb_justified_mode(bool en)
|
||||
{
|
||||
jz_writef(AIC_I2SCR, AMSL(en ? 1 : 0));
|
||||
}
|
||||
|
||||
/* Calculate frequency of I2S clocks.
|
||||
*
|
||||
* - clksrc can be one of EXCLK, SCLK_A, MPLL.
|
||||
* - This function does not modify PLL settings. It's the caller's job
|
||||
* to ensure the PLL is configured and runing.
|
||||
* - fs is the audio sampling frequency (8 KHz - 192 KHz)
|
||||
* - mult is multiplied by fs to get the master clock rate.
|
||||
* - mult must be a multiple of 64 due to AIC bit clock requirements.
|
||||
* - Note: EXCLK bypasses the decimal divider so it is not very flexible.
|
||||
* If using EXCLK you must set mult=0. If EXCLK is not a multiple of
|
||||
* the bit clock (= 64*fs), then the clock rate will be inaccurate.
|
||||
* - 'clksrc' can be one of EXCLK, SCLK_A, or MPLL.
|
||||
* - 'fs' is the audio sampling frequency in Hz, must be 8 KHz - 192 KHz.
|
||||
* - The master clock frequency equals 'mult * fs' Hz. Due to hardware
|
||||
* restrictions, 'mult' must be divisible by 64.
|
||||
*
|
||||
* Returns zero on success and nonzero if the frequency is not achievable.
|
||||
* - NOTE: When using EXCLK source, the master clock equals EXCLK and the
|
||||
* 'mult' parameter is ignored.
|
||||
*
|
||||
* This function returns the actual bit clock rate which would be achieved.
|
||||
* (Note the bit clock is always 64x the effective sampling rate.)
|
||||
*
|
||||
* If the exact rate cannot be attained, then this will return the closest
|
||||
* possible rate to the desired rate. In case of invalid parameters, this
|
||||
* function will return zero. That also occurs if the chosen PLL is stopped.
|
||||
*/
|
||||
extern int aic_i2s_set_mclk(x1000_clk_t clksrc, unsigned fs, unsigned mult);
|
||||
extern uint32_t aic_calc_i2s_clock(x1000_clk_t clksrc,
|
||||
uint32_t fs, uint32_t mult);
|
||||
|
||||
/* Set the I2S clock frequency.
|
||||
*
|
||||
* Parameters are the same as 'aic_calc_i2s_clock()' except this function
|
||||
* will set the clocks. If the bit clock is running, it will be automatically
|
||||
* stopped and restarted properly.
|
||||
*
|
||||
* Returns zero on success. If an invalid state occurs (due to bad settings)
|
||||
* then this function will do nothing and return a nonzero value.
|
||||
*/
|
||||
extern int aic_set_i2s_clock(x1000_clk_t clksrc, uint32_t fs, uint32_t mult);
|
||||
|
||||
#endif /* __AIC_X1000_H__ */
|
||||
|
|
|
@ -43,8 +43,9 @@
|
|||
* cannot be used safely.
|
||||
*/
|
||||
#define DMA_CHANNEL_AUDIO 0
|
||||
#define DMA_CHANNEL_FBCOPY 1
|
||||
#define DMA_NUM_USED_CHANNELS 2
|
||||
#define DMA_CHANNEL_RECORD 1
|
||||
#define DMA_CHANNEL_FBCOPY 2
|
||||
#define DMA_NUM_USED_CHANNELS 3
|
||||
|
||||
struct dma_desc {
|
||||
uint32_t cm; /* meaning and layout same as DMA_CHN_CM */
|
||||
|
|
|
@ -26,22 +26,13 @@
|
|||
#include "aic-x1000.h"
|
||||
#include "i2c-x1000.h"
|
||||
#include "gpio-x1000.h"
|
||||
#include "x1000/aic.h"
|
||||
#include "x1000/cpm.h"
|
||||
|
||||
void audiohw_init(void)
|
||||
{
|
||||
/* Configure AIC for I2S operation */
|
||||
jz_writef(CPM_CLKGR, AIC(0));
|
||||
gpio_config(GPIO_B, 0x1f, GPIO_DEVICE(1));
|
||||
jz_writef(AIC_I2SCR, STPBK(1));
|
||||
|
||||
/* Operate as I2S master, use external codec */
|
||||
jz_writef(AIC_CFG, AUSEL(1), ICDC(0), BCKD(1), SYNCD(1), LSMP(1));
|
||||
jz_writef(AIC_I2SCR, ESCLK(1), AMSL(0));
|
||||
|
||||
/* Stereo audio, packed 16 bit samples */
|
||||
jz_writef(AIC_CCR, PACK16(1), CHANNEL(1), OSS(1));
|
||||
/* Configure AIC */
|
||||
aic_set_external_codec(true);
|
||||
aic_set_i2s_mode(AIC_I2S_MASTER_MODE);
|
||||
aic_enable_i2s_master_clock(true);
|
||||
|
||||
/* Initialize DAC */
|
||||
i2c_x1000_set_freq(AK4376_BUS, I2C_FREQ_400K);
|
||||
|
@ -64,18 +55,15 @@ void ak4376_set_pdn_pin(int level)
|
|||
|
||||
int ak4376_set_mclk_freq(int hw_freq, bool enabled)
|
||||
{
|
||||
/* Get the multiplier */
|
||||
int freq = hw_freq_sampr[hw_freq];
|
||||
int mult = freq >= SAMPR_176 ? 128 : 256;
|
||||
|
||||
if(enabled) {
|
||||
/* Set the new frequency; clock is enabled afterward */
|
||||
if(aic_i2s_set_mclk(X1000_CLK_SCLK_A, freq, mult))
|
||||
if(aic_set_i2s_clock(X1000_CLK_SCLK_A, freq, mult)) {
|
||||
logf("WARNING: unachievable audio rate %d x %d!?", freq, mult);
|
||||
} else {
|
||||
/* Shut off the clock */
|
||||
jz_writef(AIC_I2SCR, STPBK(1));
|
||||
}
|
||||
}
|
||||
|
||||
aic_enable_i2s_bit_clock(enabled);
|
||||
return mult;
|
||||
}
|
||||
|
|
|
@ -21,13 +21,16 @@
|
|||
|
||||
#include "system.h"
|
||||
#include "kernel.h"
|
||||
#include "audio.h"
|
||||
#include "audiohw.h"
|
||||
#include "pcm.h"
|
||||
#include "pcm-internal.h"
|
||||
#include "panic.h"
|
||||
#include "dma-x1000.h"
|
||||
#include "irq-x1000.h"
|
||||
#include "gpio-x1000.h"
|
||||
#include "x1000/aic.h"
|
||||
#include "x1000/cpm.h"
|
||||
|
||||
#define AIC_STATE_STOPPED 0
|
||||
#define AIC_STATE_PLAYING 1
|
||||
|
@ -41,21 +44,45 @@ static volatile int aic_dma_pending_event = DMA_EVENT_NONE;
|
|||
|
||||
static dma_desc aic_dma_desc;
|
||||
|
||||
static void pcm_dma_int_cb(int event);
|
||||
static void pcm_play_dma_int_cb(int event);
|
||||
#ifdef HAVE_RECORDING
|
||||
static void pcm_rec_dma_int_cb(int event);
|
||||
#endif
|
||||
|
||||
void pcm_play_dma_init(void)
|
||||
{
|
||||
/* Ungate clock, assign pins. NB this overlaps with pins labeled "sa0-sa4"
|
||||
* on Ingenic's datasheets but I'm not sure what they are. Probably safe to
|
||||
* assume they are not useful to Rockbox... */
|
||||
jz_writef(CPM_CLKGR, AIC(0));
|
||||
gpio_config(GPIO_B, 0x1f, GPIO_DEVICE(1));
|
||||
|
||||
/* Configure AIC with some sane defaults */
|
||||
jz_writef(AIC_CFG, RST(1));
|
||||
jz_writef(AIC_I2SCR, STPBK(1));
|
||||
jz_writef(AIC_CFG, MSB(0), LSMP(1), ICDC(0), AUSEL(1), BCKD(0), SYNCD(0));
|
||||
jz_writef(AIC_CCR, ENDSW(0), ASVTSU(0));
|
||||
jz_writef(AIC_I2SCR, RFIRST(0), ESCLK(0), AMSL(0));
|
||||
jz_write(AIC_SPENA, 0);
|
||||
|
||||
/* Let the target initialize its hardware and setup the AIC */
|
||||
audiohw_init();
|
||||
|
||||
/* Set DMA callback */
|
||||
dma_set_callback(DMA_CHANNEL_AUDIO, pcm_dma_int_cb);
|
||||
/* Program audio format (stereo, packed 16 bit samples) */
|
||||
jz_writef(AIC_CCR, PACK16(1), CHANNEL_V(STEREO),
|
||||
OSS_V(16BIT), ISS_V(16BIT), M2S(0));
|
||||
jz_writef(AIC_I2SCR, SWLH(0));
|
||||
|
||||
/* Program FIFO threshold -- DMA settings must match */
|
||||
jz_writef(AIC_CFG, TFTH(16));
|
||||
/* Set DMA settings */
|
||||
jz_writef(AIC_CFG, TFTH(16), RFTH(16));
|
||||
dma_set_callback(DMA_CHANNEL_AUDIO, pcm_play_dma_int_cb);
|
||||
#ifdef HAVE_RECORDING
|
||||
dma_set_callback(DMA_CHANNEL_RECORD, pcm_rec_dma_int_cb);
|
||||
#endif
|
||||
|
||||
/* Ensure all playback is disabled */
|
||||
jz_writef(AIC_CCR, ERPL(0));
|
||||
/* Mask all interrupts and disable playback/recording */
|
||||
jz_writef(AIC_CCR, EROR(0), ETUR(0), ERFS(0), ETFS(0),
|
||||
ENLBF(0), ERPL(0), EREC(0));
|
||||
|
||||
/* Enable the controller */
|
||||
jz_writef(AIC_CFG, ENABLE(1));
|
||||
|
@ -112,7 +139,7 @@ static void pcm_dma_handle_event(int event)
|
|||
}
|
||||
}
|
||||
|
||||
static void pcm_dma_int_cb(int event)
|
||||
static void pcm_play_dma_int_cb(int event)
|
||||
{
|
||||
if(aic_lock) {
|
||||
aic_dma_pending_event = event;
|
||||
|
@ -156,6 +183,63 @@ void pcm_play_unlock(void)
|
|||
restore_irq(irq);
|
||||
}
|
||||
|
||||
#ifdef HAVE_RECORDING
|
||||
/*
|
||||
* Recording
|
||||
*/
|
||||
|
||||
/* FIXME need to implement this!! */
|
||||
|
||||
static void pcm_rec_dma_int_cb(int event)
|
||||
{
|
||||
(void)event;
|
||||
}
|
||||
|
||||
void pcm_rec_dma_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pcm_rec_dma_close(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pcm_rec_dma_start(void* addr, size_t size)
|
||||
{
|
||||
(void)addr;
|
||||
(void)size;
|
||||
}
|
||||
|
||||
void pcm_rec_dma_stop(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pcm_rec_lock(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void pcm_rec_unlock(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const void* pcm_rec_dma_get_peak_buffer(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void audio_set_output_source(int source)
|
||||
{
|
||||
(void)source;
|
||||
}
|
||||
|
||||
void audio_input_mux(int source, unsigned flags)
|
||||
{
|
||||
(void)source;
|
||||
(void)flags;
|
||||
}
|
||||
#endif /* HAVE_RECORDING */
|
||||
|
||||
void AIC(void)
|
||||
{
|
||||
if(jz_readf(AIC_SR, TUR)) {
|
||||
|
|
|
@ -123,18 +123,30 @@
|
|||
#define JI_AIC_CCR
|
||||
#define BP_AIC_CCR_CHANNEL 24
|
||||
#define BM_AIC_CCR_CHANNEL 0x7000000
|
||||
#define BV_AIC_CCR_CHANNEL__MONO 0x0
|
||||
#define BV_AIC_CCR_CHANNEL__STEREO 0x1
|
||||
#define BF_AIC_CCR_CHANNEL(v) (((v) & 0x7) << 24)
|
||||
#define BFM_AIC_CCR_CHANNEL(v) BM_AIC_CCR_CHANNEL
|
||||
#define BF_AIC_CCR_CHANNEL_V(e) BF_AIC_CCR_CHANNEL(BV_AIC_CCR_CHANNEL__##e)
|
||||
#define BFM_AIC_CCR_CHANNEL_V(v) BM_AIC_CCR_CHANNEL
|
||||
#define BP_AIC_CCR_OSS 19
|
||||
#define BM_AIC_CCR_OSS 0x380000
|
||||
#define BV_AIC_CCR_OSS__8BIT 0x0
|
||||
#define BV_AIC_CCR_OSS__16BIT 0x1
|
||||
#define BV_AIC_CCR_OSS__18BIT 0x2
|
||||
#define BV_AIC_CCR_OSS__20BIT 0x3
|
||||
#define BV_AIC_CCR_OSS__24BIT 0x4
|
||||
#define BF_AIC_CCR_OSS(v) (((v) & 0x7) << 19)
|
||||
#define BFM_AIC_CCR_OSS(v) BM_AIC_CCR_OSS
|
||||
#define BF_AIC_CCR_OSS_V(e) BF_AIC_CCR_OSS(BV_AIC_CCR_OSS__##e)
|
||||
#define BFM_AIC_CCR_OSS_V(v) BM_AIC_CCR_OSS
|
||||
#define BP_AIC_CCR_ISS 16
|
||||
#define BM_AIC_CCR_ISS 0x70000
|
||||
#define BV_AIC_CCR_ISS__8BIT 0x0
|
||||
#define BV_AIC_CCR_ISS__16BIT 0x1
|
||||
#define BV_AIC_CCR_ISS__18BIT 0x2
|
||||
#define BV_AIC_CCR_ISS__20BIT 0x3
|
||||
#define BV_AIC_CCR_ISS__24BIT 0x4
|
||||
#define BF_AIC_CCR_ISS(v) (((v) & 0x7) << 16)
|
||||
#define BFM_AIC_CCR_ISS(v) BM_AIC_CCR_ISS
|
||||
#define BF_AIC_CCR_ISS_V(e) BF_AIC_CCR_ISS(BV_AIC_CCR_ISS__##e)
|
||||
|
|
|
@ -144,9 +144,9 @@ node AIC {
|
|||
|
||||
reg CCR 0x04 {
|
||||
bit 28 PACK16
|
||||
fld 26 24 CHANNEL
|
||||
fld 21 19 OSS
|
||||
fld 18 16 ISS
|
||||
fld 26 24 CHANNEL { enum MONO 0; enum STEREO 1 }
|
||||
fld 21 19 OSS { enum 8BIT 0; enum 16BIT 1; enum 18BIT 2; enum 20BIT 3; enum 24BIT 4 }
|
||||
fld 18 16 ISS { enum 8BIT 0; enum 16BIT 1; enum 18BIT 2; enum 20BIT 3; enum 24BIT 4 }
|
||||
bit 15 RDMS
|
||||
bit 14 TDMS
|
||||
bit 11 M2S
|
||||
|
|
Loading…
Reference in a new issue