diff options
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/aic-x1000.h')
-rw-r--r-- | firmware/target/mips/ingenic_x1000/aic-x1000.h | 130 |
1 files changed, 114 insertions, 16 deletions
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 | * | 43 | static 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. */ | ||
50 | static 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. */ | ||
56 | static 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 */ | ||
62 | static 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). */ | ||
81 | static 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') */ | ||
96 | static 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 */ | ||
102 | static 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). */ | ||
108 | static 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 | */ | ||
130 | extern 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 | */ |
44 | extern int aic_i2s_set_mclk(x1000_clk_t clksrc, unsigned fs, unsigned mult); | 142 | extern 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__ */ |