summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-05-30 19:56:44 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-05-30 19:17:50 +0000
commitf63edb52ef8ecf18520926b40b3c61db37081a9d (patch)
tree29c36d3f247d7bab2f547d76655ac81fa8a71946
parentc78ba1aa689b178ebb73b2730bc1b13697371fbf (diff)
downloadrockbox-f63edb52ef.tar.gz
rockbox-f63edb52ef.zip
x1000: refactor AIC initialization
Have pcm-x1000 handle most work, so target's audiohw code touches only the relevant settings. Change-Id: Icf3d1b7ca428ac50a5a16ecec39ed8186ac5ae13
-rw-r--r--firmware/target/mips/ingenic_x1000/aic-x1000.c132
-rw-r--r--firmware/target/mips/ingenic_x1000/aic-x1000.h130
-rw-r--r--firmware/target/mips/ingenic_x1000/dma-x1000.h5
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c26
-rw-r--r--firmware/target/mips/ingenic_x1000/pcm-x1000.c100
-rw-r--r--firmware/target/mips/ingenic_x1000/x1000/aic.h12
-rw-r--r--utils/reggen-ng/x1000.reggen6
7 files changed, 324 insertions, 87 deletions
diff --git a/firmware/target/mips/ingenic_x1000/aic-x1000.c b/firmware/target/mips/ingenic_x1000/aic-x1000.c
index a0e509d3b6..1d1768d4f9 100644
--- a/firmware/target/mips/ingenic_x1000/aic-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/aic-x1000.c
@@ -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;
+
+ /* clamp to maximum value */
+ if(*i2sdiv > 0x200)
+ *i2sdiv = 0x200;
+
+ return 0;
+ }
- /* reject invalid parameters */
+ /* 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;
+
+ /* 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));
- jz_writef(AIC_I2SCR, STPBK(1));
+ /* 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;
}
diff --git a/firmware/target/mips/ingenic_x1000/aic-x1000.h b/firmware/target/mips/ingenic_x1000/aic-x1000.h
index eda0f80f04..f272655b9c 100644
--- a/firmware/target/mips/ingenic_x1000/aic-x1000.h
+++ b/firmware/target/mips/ingenic_x1000/aic-x1000.h
@@ -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.
- *
- * - 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.
- *
- * Returns zero on success and nonzero if the frequency is not achievable.
+#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, 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.
+ *
+ * - 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 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_i2s_set_mclk(x1000_clk_t clksrc, unsigned fs, unsigned mult);
+extern int aic_set_i2s_clock(x1000_clk_t clksrc, uint32_t fs, uint32_t mult);
#endif /* __AIC_X1000_H__ */
diff --git a/firmware/target/mips/ingenic_x1000/dma-x1000.h b/firmware/target/mips/ingenic_x1000/dma-x1000.h
index d836a0cf54..8bb5f1ddaa 100644
--- a/firmware/target/mips/ingenic_x1000/dma-x1000.h
+++ b/firmware/target/mips/ingenic_x1000/dma-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 */
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c
index 2f43809523..d1c4d67d33 100644
--- a/firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c
@@ -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;
}
diff --git a/firmware/target/mips/ingenic_x1000/pcm-x1000.c b/firmware/target/mips/ingenic_x1000/pcm-x1000.c
index 9ae6f5a956..fd5e9d20c8 100644
--- a/firmware/target/mips/ingenic_x1000/pcm-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/pcm-x1000.c
@@ -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)) {
diff --git a/firmware/target/mips/ingenic_x1000/x1000/aic.h b/firmware/target/mips/ingenic_x1000/x1000/aic.h
index d212ddc4e1..5f5e771c2c 100644
--- a/firmware/target/mips/ingenic_x1000/x1000/aic.h
+++ b/firmware/target/mips/ingenic_x1000/x1000/aic.h
@@ -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)
diff --git a/utils/reggen-ng/x1000.reggen b/utils/reggen-ng/x1000.reggen
index 4620378c19..f77f55b8b9 100644
--- a/utils/reggen-ng/x1000.reggen
+++ b/utils/reggen-ng/x1000.reggen
@@ -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