summaryrefslogtreecommitdiff
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-f63edb52ef8ecf18520926b40b3c61db37081a9d.tar.gz
rockbox-f63edb52ef8ecf18520926b40b3c61db37081a9d.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 @@
31 * is complete if this value is less than "cnt", and may be incomplete if it 31 * is complete if this value is less than "cnt", and may be incomplete if it
32 * is equal to "cnt". (Note the leading zero term is not written to "buf".) 32 * is equal to "cnt". (Note the leading zero term is not written to "buf".)
33 */ 33 */
34static unsigned cf_derive(unsigned m, unsigned n, unsigned* buf, unsigned cnt) 34static uint32_t cf_derive(uint32_t m, uint32_t n, uint32_t* buf, uint32_t cnt)
35{ 35{
36 unsigned wrote = 0; 36 uint32_t wrote = 0;
37 unsigned a = m / n; 37 uint32_t a = m / n;
38 while(cnt--) { 38 while(cnt--) {
39 unsigned tmp = n; 39 uint32_t tmp = n;
40 n = m - n * a; 40 n = m - n * a;
41 if(n == 0) 41 if(n == 0)
42 break; 42 break;
@@ -54,16 +54,16 @@ static unsigned cf_derive(unsigned m, unsigned n, unsigned* buf, unsigned cnt)
54 * calculate the rational number m/n which it represents. Returns m and n. 54 * calculate the rational number m/n which it represents. Returns m and n.
55 * If count is zero, then m and n are undefined. 55 * If count is zero, then m and n are undefined.
56 */ 56 */
57static void cf_expand(const unsigned* buf, unsigned count, 57static void cf_expand(const uint32_t* buf, uint32_t count,
58 unsigned* m, unsigned* n) 58 uint32_t* m, uint32_t* n)
59{ 59{
60 if(count == 0) 60 if(count == 0)
61 return; 61 return;
62 62
63 unsigned i = count - 1; 63 uint32_t i = count - 1;
64 unsigned mx = 1, nx = buf[i]; 64 uint32_t mx = 1, nx = buf[i];
65 while(i--) { 65 while(i--) {
66 unsigned tmp = nx; 66 uint32_t tmp = nx;
67 nx = mx + buf[i] * nx; 67 nx = mx + buf[i] * nx;
68 mx = tmp; 68 mx = tmp;
69 } 69 }
@@ -72,48 +72,102 @@ static void cf_expand(const unsigned* buf, unsigned count,
72 *n = nx; 72 *n = nx;
73} 73}
74 74
75int aic_i2s_set_mclk(x1000_clk_t clksrc, unsigned fs, unsigned mult) 75static int calc_i2s_clock_params(x1000_clk_t clksrc,
76 uint32_t fs, uint32_t mult,
77 uint32_t* div_m, uint32_t* div_n,
78 uint32_t* i2sdiv)
76{ 79{
77 /* get the input clock rate */ 80 if(clksrc == X1000_CLK_EXCLK) {
78 uint32_t src_freq = clk_get(clksrc); 81 /* EXCLK mode bypasses the CPM clock so it's more limited */
82 *div_m = 0;
83 *div_n = 0;
84 *i2sdiv = X1000_EXCLK_FREQ / 64 / fs;
85
86 /* clamp to maximum value */
87 if(*i2sdiv > 0x200)
88 *i2sdiv = 0x200;
89
90 return 0;
91 }
79 92
80 /* reject invalid parameters */ 93 /* ensure a valid clock was selected */
94 if(clksrc != X1000_CLK_SCLK_A &&
95 clksrc != X1000_CLK_MPLL)
96 return -1;
97
98 /* ensure bit clock constraint is respected */
81 if(mult % 64 != 0) 99 if(mult % 64 != 0)
82 return -1; 100 return -1;
83 101
84 if(clksrc == X1000_EXCLK_FREQ) { 102 /* ensure master clock frequency is not too high */
85 if(mult != 0) 103 if(fs > UINT32_MAX/mult)
86 return -1; 104 return -1;
105
106 /* get frequencies */
107 uint32_t tgt_freq = fs * mult;
108 uint32_t src_freq = clk_get(clksrc);
109
110 /* calculate best rational approximation fitting hardware constraints */
111 uint32_t m = 0, n = 0;
112 uint32_t buf[16];
113 uint32_t cnt = cf_derive(tgt_freq, src_freq, &buf[0], 16);
114 do {
115 cf_expand(&buf[0], cnt, &m, &n);
116 cnt -= 1;
117 } while(cnt > 0 && (m > 512 || n > 8192) && (n >= 2*m));
87 118
88 jz_writef(AIC_I2SCR, STPBK(1)); 119 /* unrepresentable */
120 if(cnt == 0 || n == 0 || m == 0)
121 return -1;
122
123 *div_m = m;
124 *div_n = n;
125 *i2sdiv = mult / 64;
126 return 0;
127}
128
129uint32_t aic_calc_i2s_clock(x1000_clk_t clksrc, uint32_t fs, uint32_t mult)
130{
131 uint32_t m, n, i2sdiv;
132 if(calc_i2s_clock_params(clksrc, fs, mult, &m, &n, &i2sdiv))
133 return 0;
134
135 unsigned long long rate = clk_get(clksrc);
136 rate *= m;
137 rate /= n * i2sdiv; /* this multiply can't overflow. */
138
139 /* clamp */
140 if(rate > 0xffffffffull)
141 rate = 0xffffffff;
142
143 return rate;
144}
145
146int aic_set_i2s_clock(x1000_clk_t clksrc, uint32_t fs, uint32_t mult)
147{
148 uint32_t m, n, i2sdiv;
149 if(calc_i2s_clock_params(clksrc, fs, mult, &m, &n, &i2sdiv))
150 return -1;
151
152 /* turn off bit clock */
153 bool bitclock_en = !jz_readf(AIC_I2SCR, STPBK);
154 jz_writef(AIC_I2SCR, STPBK(1));
155
156 /* handle master clock */
157 if(clksrc == X1000_CLK_EXCLK) {
89 jz_writef(CPM_I2SCDR, CS(0), CE(0)); 158 jz_writef(CPM_I2SCDR, CS(0), CE(0));
90 REG_AIC_I2SDIV = X1000_EXCLK_FREQ / 64 / fs;
91 } else { 159 } else {
92 if(mult == 0)
93 return -1;
94 if(fs*mult > src_freq)
95 return -1;
96
97 /* calculate best rational approximation that fits our constraints */
98 unsigned m = 0, n = 0;
99 unsigned buf[16];
100 unsigned cnt = cf_derive(fs*mult, src_freq, &buf[0], 16);
101 do {
102 cf_expand(&buf[0], cnt, &m, &n);
103 cnt -= 1;
104 } while(cnt > 0 && (m > 512 || n > 8192) && (n >= 2*m));
105
106 /* wrong values */
107 if(cnt == 0 || n == 0 || m == 0)
108 return -1;
109
110 jz_writef(AIC_I2SCR, STPBK(1));
111 jz_writef(CPM_I2SCDR, PCS(clksrc == X1000_CLK_MPLL ? 1 : 0), 160 jz_writef(CPM_I2SCDR, PCS(clksrc == X1000_CLK_MPLL ? 1 : 0),
112 CS(1), CE(1), DIV_M(m), DIV_N(n)); 161 CS(1), CE(1), DIV_M(m), DIV_N(n));
113 jz_write(CPM_I2SCDR1, REG_CPM_I2SCDR1); 162 jz_write(CPM_I2SCDR1, REG_CPM_I2SCDR1);
114 REG_AIC_I2SDIV = (mult / 64) - 1;
115 } 163 }
116 164
117 jz_writef(AIC_I2SCR, STPBK(0)); 165 /* set bit clock divider */
166 REG_AIC_I2SDIV = i2sdiv - 1;
167
168 /* re-enable the bit clock */
169 if(bitclock_en)
170 jz_writef(AIC_I2SCR, STPBK(0));
171
118 return 0; 172 return 0;
119} 173}
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 @@
23#define __AIC_X1000_H__ 23#define __AIC_X1000_H__
24 24
25#include "clk-x1000.h" 25#include "clk-x1000.h"
26#include "x1000/aic.h"
26#include <stdbool.h> 27#include <stdbool.h>
28#include <stdint.h>
27 29
28/* Set frequency of I2S master clock supplied by AIC. Has no use if an 30#define AIC_I2S_MASTER_MODE 0
29 * external DAC is supplying the master clock. Must be called with the 31#define AIC_I2S_MASTER_EXCLK_MODE 1
30 * bit clock disabled. 32#define AIC_I2S_SLAVE_MODE 2
31 * 33
32 * - clksrc can be one of EXCLK, SCLK_A, MPLL. 34#define AIC_I2S_LEFT_CHANNEL_FIRST 0
33 * - This function does not modify PLL settings. It's the caller's job 35#define AIC_I2S_RIGHT_CHANNEL_FIRST 1
34 * to ensure the PLL is configured and runing. 36
35 * - fs is the audio sampling frequency (8 KHz - 192 KHz) 37/* Nb. the functions below are intended to serve as "documentation" and make
36 * - mult is multiplied by fs to get the master clock rate. 38 * target audiohw code clearer, they should normally be called with immediate
37 * - mult must be a multiple of 64 due to AIC bit clock requirements. 39 * constant arguments so they are inlined to a register read-modify-write. */
38 * - Note: EXCLK bypasses the decimal divider so it is not very flexible. 40
39 * If using EXCLK you must set mult=0. If EXCLK is not a multiple of 41/* Enable/disable some kind of big-endian mode. Presumably it refers to
40 * the bit clock (= 64*fs), then the clock rate will be inaccurate. 42 * the endianness of the samples read or written to the FIFO. */
41 * 43static inline void aic_set_big_endian_format(bool en)
42 * Returns zero on success and nonzero if the frequency is not achievable. 44{
45 jz_writef(AIC_CFG, MSB(en ? 1 : 0));
46}
47
48/* Set whether to send the last sample (true) or a zero sample (false)
49 * if the AIC FIFO underflows during playback. */
50static inline void aic_set_play_last_sample(bool en)
51{
52 jz_writef(AIC_CFG, LSMP(en ? 1 : 0));
53}
54
55/* Select the use of the internal or external codec. */
56static inline void aic_set_external_codec(bool en)
57{
58 jz_writef(AIC_CFG, ICDC(en ? 0 : 1));
59}
60
61/* Set I2S interface mode */
62static inline void aic_set_i2s_mode(int mode)
63{
64 switch(mode) {
65 default:
66 case AIC_I2S_MASTER_MODE:
67 jz_writef(AIC_CFG, BCKD(1), SYNCD(1));
68 break;
69
70 case AIC_I2S_MASTER_EXCLK_MODE:
71 jz_writef(AIC_CFG, BCKD(0), SYNCD(1));
72 break;
73
74 case AIC_I2S_SLAVE_MODE:
75 jz_writef(AIC_CFG, BCKD(0), SYNCD(0));
76 break;
77 }
78}
79
80/* Select the channel ordering on the I2S interface (playback only). */
81static inline void aic_set_i2s_channel_order(int order)
82{
83 switch(order) {
84 default:
85 case AIC_I2S_LEFT_CHANNEL_FIRST:
86 jz_writef(AIC_I2SCR, RFIRST(0));
87 break;
88
89 case AIC_I2S_RIGHT_CHANNEL_FIRST:
90 jz_writef(AIC_I2SCR, RFIRST(1));
91 break;
92 }
93}
94
95/* Enable/disable the I2S master clock (also called 'system clock') */
96static inline void aic_enable_i2s_master_clock(bool en)
97{
98 jz_writef(AIC_I2SCR, ESCLK(en ? 1 : 0));
99}
100
101/* Enable/disable the I2S bit clock */
102static inline void aic_enable_i2s_bit_clock(bool en)
103{
104 jz_writef(AIC_I2SCR, STPBK(en ? 0 : 1));
105}
106
107/* Select whether I2S mode is used (false) or MSB-justified mode (true). */
108static inline void aic_set_msb_justified_mode(bool en)
109{
110 jz_writef(AIC_I2SCR, AMSL(en ? 1 : 0));
111}
112
113/* Calculate frequency of I2S clocks.
114 *
115 * - 'clksrc' can be one of EXCLK, SCLK_A, or MPLL.
116 * - 'fs' is the audio sampling frequency in Hz, must be 8 KHz - 192 KHz.
117 * - The master clock frequency equals 'mult * fs' Hz. Due to hardware
118 * restrictions, 'mult' must be divisible by 64.
119 *
120 * - NOTE: When using EXCLK source, the master clock equals EXCLK and the
121 * 'mult' parameter is ignored.
122 *
123 * This function returns the actual bit clock rate which would be achieved.
124 * (Note the bit clock is always 64x the effective sampling rate.)
125 *
126 * If the exact rate cannot be attained, then this will return the closest
127 * possible rate to the desired rate. In case of invalid parameters, this
128 * function will return zero. That also occurs if the chosen PLL is stopped.
129 */
130extern uint32_t aic_calc_i2s_clock(x1000_clk_t clksrc,
131 uint32_t fs, uint32_t mult);
132
133/* Set the I2S clock frequency.
134 *
135 * Parameters are the same as 'aic_calc_i2s_clock()' except this function
136 * will set the clocks. If the bit clock is running, it will be automatically
137 * stopped and restarted properly.
138 *
139 * Returns zero on success. If an invalid state occurs (due to bad settings)
140 * then this function will do nothing and return a nonzero value.
43 */ 141 */
44extern int aic_i2s_set_mclk(x1000_clk_t clksrc, unsigned fs, unsigned mult); 142extern int aic_set_i2s_clock(x1000_clk_t clksrc, uint32_t fs, uint32_t mult);
45 143
46#endif /* __AIC_X1000_H__ */ 144#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 @@
43 * cannot be used safely. 43 * cannot be used safely.
44 */ 44 */
45#define DMA_CHANNEL_AUDIO 0 45#define DMA_CHANNEL_AUDIO 0
46#define DMA_CHANNEL_FBCOPY 1 46#define DMA_CHANNEL_RECORD 1
47#define DMA_NUM_USED_CHANNELS 2 47#define DMA_CHANNEL_FBCOPY 2
48#define DMA_NUM_USED_CHANNELS 3
48 49
49struct dma_desc { 50struct dma_desc {
50 uint32_t cm; /* meaning and layout same as DMA_CHN_CM */ 51 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 @@
26#include "aic-x1000.h" 26#include "aic-x1000.h"
27#include "i2c-x1000.h" 27#include "i2c-x1000.h"
28#include "gpio-x1000.h" 28#include "gpio-x1000.h"
29#include "x1000/aic.h"
30#include "x1000/cpm.h"
31 29
32void audiohw_init(void) 30void audiohw_init(void)
33{ 31{
34 /* Configure AIC for I2S operation */ 32 /* Configure AIC */
35 jz_writef(CPM_CLKGR, AIC(0)); 33 aic_set_external_codec(true);
36 gpio_config(GPIO_B, 0x1f, GPIO_DEVICE(1)); 34 aic_set_i2s_mode(AIC_I2S_MASTER_MODE);
37 jz_writef(AIC_I2SCR, STPBK(1)); 35 aic_enable_i2s_master_clock(true);
38
39 /* Operate as I2S master, use external codec */
40 jz_writef(AIC_CFG, AUSEL(1), ICDC(0), BCKD(1), SYNCD(1), LSMP(1));
41 jz_writef(AIC_I2SCR, ESCLK(1), AMSL(0));
42
43 /* Stereo audio, packed 16 bit samples */
44 jz_writef(AIC_CCR, PACK16(1), CHANNEL(1), OSS(1));
45 36
46 /* Initialize DAC */ 37 /* Initialize DAC */
47 i2c_x1000_set_freq(AK4376_BUS, I2C_FREQ_400K); 38 i2c_x1000_set_freq(AK4376_BUS, I2C_FREQ_400K);
@@ -64,18 +55,15 @@ void ak4376_set_pdn_pin(int level)
64 55
65int ak4376_set_mclk_freq(int hw_freq, bool enabled) 56int ak4376_set_mclk_freq(int hw_freq, bool enabled)
66{ 57{
67 /* Get the multiplier */
68 int freq = hw_freq_sampr[hw_freq]; 58 int freq = hw_freq_sampr[hw_freq];
69 int mult = freq >= SAMPR_176 ? 128 : 256; 59 int mult = freq >= SAMPR_176 ? 128 : 256;
70 60
71 if(enabled) { 61 if(enabled) {
72 /* Set the new frequency; clock is enabled afterward */ 62 if(aic_set_i2s_clock(X1000_CLK_SCLK_A, freq, mult)) {
73 if(aic_i2s_set_mclk(X1000_CLK_SCLK_A, freq, mult))
74 logf("WARNING: unachievable audio rate %d x %d!?", freq, mult); 63 logf("WARNING: unachievable audio rate %d x %d!?", freq, mult);
75 } else { 64 }
76 /* Shut off the clock */
77 jz_writef(AIC_I2SCR, STPBK(1));
78 } 65 }
79 66
67 aic_enable_i2s_bit_clock(enabled);
80 return mult; 68 return mult;
81} 69}
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 @@
21 21
22#include "system.h" 22#include "system.h"
23#include "kernel.h" 23#include "kernel.h"
24#include "audio.h"
24#include "audiohw.h" 25#include "audiohw.h"
25#include "pcm.h" 26#include "pcm.h"
26#include "pcm-internal.h" 27#include "pcm-internal.h"
27#include "panic.h" 28#include "panic.h"
28#include "dma-x1000.h" 29#include "dma-x1000.h"
29#include "irq-x1000.h" 30#include "irq-x1000.h"
31#include "gpio-x1000.h"
30#include "x1000/aic.h" 32#include "x1000/aic.h"
33#include "x1000/cpm.h"
31 34
32#define AIC_STATE_STOPPED 0 35#define AIC_STATE_STOPPED 0
33#define AIC_STATE_PLAYING 1 36#define AIC_STATE_PLAYING 1
@@ -41,21 +44,45 @@ static volatile int aic_dma_pending_event = DMA_EVENT_NONE;
41 44
42static dma_desc aic_dma_desc; 45static dma_desc aic_dma_desc;
43 46
44static void pcm_dma_int_cb(int event); 47static void pcm_play_dma_int_cb(int event);
48#ifdef HAVE_RECORDING
49static void pcm_rec_dma_int_cb(int event);
50#endif
45 51
46void pcm_play_dma_init(void) 52void pcm_play_dma_init(void)
47{ 53{
54 /* Ungate clock, assign pins. NB this overlaps with pins labeled "sa0-sa4"
55 * on Ingenic's datasheets but I'm not sure what they are. Probably safe to
56 * assume they are not useful to Rockbox... */
57 jz_writef(CPM_CLKGR, AIC(0));
58 gpio_config(GPIO_B, 0x1f, GPIO_DEVICE(1));
59
60 /* Configure AIC with some sane defaults */
61 jz_writef(AIC_CFG, RST(1));
62 jz_writef(AIC_I2SCR, STPBK(1));
63 jz_writef(AIC_CFG, MSB(0), LSMP(1), ICDC(0), AUSEL(1), BCKD(0), SYNCD(0));
64 jz_writef(AIC_CCR, ENDSW(0), ASVTSU(0));
65 jz_writef(AIC_I2SCR, RFIRST(0), ESCLK(0), AMSL(0));
66 jz_write(AIC_SPENA, 0);
67
48 /* Let the target initialize its hardware and setup the AIC */ 68 /* Let the target initialize its hardware and setup the AIC */
49 audiohw_init(); 69 audiohw_init();
50 70
51 /* Set DMA callback */ 71 /* Program audio format (stereo, packed 16 bit samples) */
52 dma_set_callback(DMA_CHANNEL_AUDIO, pcm_dma_int_cb); 72 jz_writef(AIC_CCR, PACK16(1), CHANNEL_V(STEREO),
73 OSS_V(16BIT), ISS_V(16BIT), M2S(0));
74 jz_writef(AIC_I2SCR, SWLH(0));
53 75
54 /* Program FIFO threshold -- DMA settings must match */ 76 /* Set DMA settings */
55 jz_writef(AIC_CFG, TFTH(16)); 77 jz_writef(AIC_CFG, TFTH(16), RFTH(16));
78 dma_set_callback(DMA_CHANNEL_AUDIO, pcm_play_dma_int_cb);
79#ifdef HAVE_RECORDING
80 dma_set_callback(DMA_CHANNEL_RECORD, pcm_rec_dma_int_cb);
81#endif
56 82
57 /* Ensure all playback is disabled */ 83 /* Mask all interrupts and disable playback/recording */
58 jz_writef(AIC_CCR, ERPL(0)); 84 jz_writef(AIC_CCR, EROR(0), ETUR(0), ERFS(0), ETFS(0),
85 ENLBF(0), ERPL(0), EREC(0));
59 86
60 /* Enable the controller */ 87 /* Enable the controller */
61 jz_writef(AIC_CFG, ENABLE(1)); 88 jz_writef(AIC_CFG, ENABLE(1));
@@ -112,7 +139,7 @@ static void pcm_dma_handle_event(int event)
112 } 139 }
113} 140}
114 141
115static void pcm_dma_int_cb(int event) 142static void pcm_play_dma_int_cb(int event)
116{ 143{
117 if(aic_lock) { 144 if(aic_lock) {
118 aic_dma_pending_event = event; 145 aic_dma_pending_event = event;
@@ -156,6 +183,63 @@ void pcm_play_unlock(void)
156 restore_irq(irq); 183 restore_irq(irq);
157} 184}
158 185
186#ifdef HAVE_RECORDING
187/*
188 * Recording
189 */
190
191/* FIXME need to implement this!! */
192
193static void pcm_rec_dma_int_cb(int event)
194{
195 (void)event;
196}
197
198void pcm_rec_dma_init(void)
199{
200}
201
202void pcm_rec_dma_close(void)
203{
204}
205
206void pcm_rec_dma_start(void* addr, size_t size)
207{
208 (void)addr;
209 (void)size;
210}
211
212void pcm_rec_dma_stop(void)
213{
214}
215
216void pcm_rec_lock(void)
217{
218
219}
220
221void pcm_rec_unlock(void)
222{
223
224}
225
226const void* pcm_rec_dma_get_peak_buffer(void)
227{
228 return NULL;
229}
230
231void audio_set_output_source(int source)
232{
233 (void)source;
234}
235
236void audio_input_mux(int source, unsigned flags)
237{
238 (void)source;
239 (void)flags;
240}
241#endif /* HAVE_RECORDING */
242
159void AIC(void) 243void AIC(void)
160{ 244{
161 if(jz_readf(AIC_SR, TUR)) { 245 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 @@
123#define JI_AIC_CCR 123#define JI_AIC_CCR
124#define BP_AIC_CCR_CHANNEL 24 124#define BP_AIC_CCR_CHANNEL 24
125#define BM_AIC_CCR_CHANNEL 0x7000000 125#define BM_AIC_CCR_CHANNEL 0x7000000
126#define BV_AIC_CCR_CHANNEL__MONO 0x0
127#define BV_AIC_CCR_CHANNEL__STEREO 0x1
126#define BF_AIC_CCR_CHANNEL(v) (((v) & 0x7) << 24) 128#define BF_AIC_CCR_CHANNEL(v) (((v) & 0x7) << 24)
127#define BFM_AIC_CCR_CHANNEL(v) BM_AIC_CCR_CHANNEL 129#define BFM_AIC_CCR_CHANNEL(v) BM_AIC_CCR_CHANNEL
128#define BF_AIC_CCR_CHANNEL_V(e) BF_AIC_CCR_CHANNEL(BV_AIC_CCR_CHANNEL__##e) 130#define BF_AIC_CCR_CHANNEL_V(e) BF_AIC_CCR_CHANNEL(BV_AIC_CCR_CHANNEL__##e)
129#define BFM_AIC_CCR_CHANNEL_V(v) BM_AIC_CCR_CHANNEL 131#define BFM_AIC_CCR_CHANNEL_V(v) BM_AIC_CCR_CHANNEL
130#define BP_AIC_CCR_OSS 19 132#define BP_AIC_CCR_OSS 19
131#define BM_AIC_CCR_OSS 0x380000 133#define BM_AIC_CCR_OSS 0x380000
134#define BV_AIC_CCR_OSS__8BIT 0x0
135#define BV_AIC_CCR_OSS__16BIT 0x1
136#define BV_AIC_CCR_OSS__18BIT 0x2
137#define BV_AIC_CCR_OSS__20BIT 0x3
138#define BV_AIC_CCR_OSS__24BIT 0x4
132#define BF_AIC_CCR_OSS(v) (((v) & 0x7) << 19) 139#define BF_AIC_CCR_OSS(v) (((v) & 0x7) << 19)
133#define BFM_AIC_CCR_OSS(v) BM_AIC_CCR_OSS 140#define BFM_AIC_CCR_OSS(v) BM_AIC_CCR_OSS
134#define BF_AIC_CCR_OSS_V(e) BF_AIC_CCR_OSS(BV_AIC_CCR_OSS__##e) 141#define BF_AIC_CCR_OSS_V(e) BF_AIC_CCR_OSS(BV_AIC_CCR_OSS__##e)
135#define BFM_AIC_CCR_OSS_V(v) BM_AIC_CCR_OSS 142#define BFM_AIC_CCR_OSS_V(v) BM_AIC_CCR_OSS
136#define BP_AIC_CCR_ISS 16 143#define BP_AIC_CCR_ISS 16
137#define BM_AIC_CCR_ISS 0x70000 144#define BM_AIC_CCR_ISS 0x70000
145#define BV_AIC_CCR_ISS__8BIT 0x0
146#define BV_AIC_CCR_ISS__16BIT 0x1
147#define BV_AIC_CCR_ISS__18BIT 0x2
148#define BV_AIC_CCR_ISS__20BIT 0x3
149#define BV_AIC_CCR_ISS__24BIT 0x4
138#define BF_AIC_CCR_ISS(v) (((v) & 0x7) << 16) 150#define BF_AIC_CCR_ISS(v) (((v) & 0x7) << 16)
139#define BFM_AIC_CCR_ISS(v) BM_AIC_CCR_ISS 151#define BFM_AIC_CCR_ISS(v) BM_AIC_CCR_ISS
140#define BF_AIC_CCR_ISS_V(e) BF_AIC_CCR_ISS(BV_AIC_CCR_ISS__##e) 152#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 {
144 144
145 reg CCR 0x04 { 145 reg CCR 0x04 {
146 bit 28 PACK16 146 bit 28 PACK16
147 fld 26 24 CHANNEL 147 fld 26 24 CHANNEL { enum MONO 0; enum STEREO 1 }
148 fld 21 19 OSS 148 fld 21 19 OSS { enum 8BIT 0; enum 16BIT 1; enum 18BIT 2; enum 20BIT 3; enum 24BIT 4 }
149 fld 18 16 ISS 149 fld 18 16 ISS { enum 8BIT 0; enum 16BIT 1; enum 18BIT 2; enum 20BIT 3; enum 24BIT 4 }
150 bit 15 RDMS 150 bit 15 RDMS
151 bit 14 TDMS 151 bit 14 TDMS
152 bit 11 M2S 152 bit 11 M2S