summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-10-17 15:37:14 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-10-17 15:37:14 +0000
commitfeddfdb2d9e56c132d91d72b6c7a595fa0b83a16 (patch)
tree52eb3cf18e5cdde0ffa1c06c85668332e9649631
parent2a478c826bff003a46a35c4cff2ca961c208c38f (diff)
downloadrockbox-feddfdb2d9e56c132d91d72b6c7a595fa0b83a16.tar.gz
rockbox-feddfdb2d9e56c132d91d72b6c7a595fa0b83a16.zip
Gigabeat S/i.MX31/wm8978: Clean up clocking information in the general wmcodec/pcm drivers and move it to the target's wmcodec/i2s files.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30771 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/audio/wm8978.c95
-rw-r--r--firmware/export/wm8978.h11
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/i2s-gigabeat-s.c93
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c96
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/wmcodec-gigabeat-s.c83
5 files changed, 190 insertions, 188 deletions
diff --git a/firmware/drivers/audio/wm8978.c b/firmware/drivers/audio/wm8978.c
index 6836d8c5e8..5bba19b996 100644
--- a/firmware/drivers/audio/wm8978.c
+++ b/firmware/drivers/audio/wm8978.c
@@ -505,88 +505,7 @@ void audiohw_close(void)
505 505
506void audiohw_set_frequency(int fsel) 506void audiohw_set_frequency(int fsel)
507{ 507{
508 /* For 16.9344MHz MCLK, codec as master. */ 508 extern const struct wmc_srctrl_entry wmc_srctrl_table[HW_NUM_FREQ];
509 static const struct
510 {
511 uint32_t plln : 8;
512 uint32_t pllk1 : 6;
513 uint32_t pllk2 : 9;
514 uint32_t pllk3 : 9;
515 unsigned char mclkdiv;
516 unsigned char filter;
517 } srctrl_table[HW_NUM_FREQ] =
518 {
519 [HW_FREQ_8] = /* PLL = 65.536MHz */
520 {
521 .plln = 7 | WMC_PLL_PRESCALE,
522 .pllk1 = 0x2f, /* 12414886 */
523 .pllk2 = 0x0b7,
524 .pllk3 = 0x1a6,
525 .mclkdiv = WMC_MCLKDIV_8, /* 2.0480 MHz */
526 .filter = WMC_SR_8KHZ,
527 },
528 [HW_FREQ_11] = /* PLL = off */
529 {
530 .mclkdiv = WMC_MCLKDIV_6, /* 2.8224 MHz */
531 .filter = WMC_SR_12KHZ,
532 },
533 [HW_FREQ_12] = /* PLL = 73.728 MHz */
534 {
535 .plln = 8 | WMC_PLL_PRESCALE,
536 .pllk1 = 0x2d, /* 11869595 */
537 .pllk2 = 0x08e,
538 .pllk3 = 0x19b,
539 .mclkdiv = WMC_MCLKDIV_6, /* 3.0720 MHz */
540 .filter = WMC_SR_12KHZ,
541 },
542 [HW_FREQ_16] = /* PLL = 65.536MHz */
543 {
544 .plln = 7 | WMC_PLL_PRESCALE,
545 .pllk1 = 0x2f, /* 12414886 */
546 .pllk2 = 0x0b7,
547 .pllk3 = 0x1a6,
548 .mclkdiv = WMC_MCLKDIV_4, /* 4.0960 MHz */
549 .filter = WMC_SR_16KHZ,
550 },
551 [HW_FREQ_22] = /* PLL = off */
552 {
553 .mclkdiv = WMC_MCLKDIV_3, /* 5.6448 MHz */
554 .filter = WMC_SR_24KHZ,
555 },
556 [HW_FREQ_24] = /* PLL = 73.728 MHz */
557 {
558 .plln = 8 | WMC_PLL_PRESCALE,
559 .pllk1 = 0x2d, /* 11869595 */
560 .pllk2 = 0x08e,
561 .pllk3 = 0x19b,
562 .mclkdiv = WMC_MCLKDIV_3, /* 6.1440 MHz */
563 .filter = WMC_SR_24KHZ,
564 },
565 [HW_FREQ_32] = /* PLL = 65.536MHz */
566 {
567 .plln = 7 | WMC_PLL_PRESCALE,
568 .pllk1 = 0x2f, /* 12414886 */
569 .pllk2 = 0x0b7,
570 .pllk3 = 0x1a6,
571 .mclkdiv = WMC_MCLKDIV_2, /* 8.1920 MHz */
572 .filter = WMC_SR_32KHZ,
573 },
574 [HW_FREQ_44] = /* PLL = off */
575 {
576 .mclkdiv = WMC_MCLKDIV_1_5, /* 11.2896 MHz */
577 .filter = WMC_SR_48KHZ,
578 },
579 [HW_FREQ_48] = /* PLL = 73.728 MHz */
580 {
581 .plln = 8 | WMC_PLL_PRESCALE,
582 .pllk1 = 0x2d, /* 11869595 */
583 .pllk2 = 0x08e,
584 .pllk3 = 0x19b,
585 .mclkdiv = WMC_MCLKDIV_1_5, /* 12.2880 MHz */
586 .filter = WMC_SR_48KHZ,
587 },
588 };
589
590 unsigned int plln; 509 unsigned int plln;
591 unsigned int mclkdiv; 510 unsigned int mclkdiv;
592 511
@@ -594,10 +513,10 @@ void audiohw_set_frequency(int fsel)
594 fsel = HW_FREQ_DEFAULT; 513 fsel = HW_FREQ_DEFAULT;
595 514
596 /* Setup filters. */ 515 /* Setup filters. */
597 wmc_write(WMC_ADDITIONAL_CTRL, srctrl_table[fsel].filter); 516 wmc_write(WMC_ADDITIONAL_CTRL, wmc_srctrl_table[fsel].filter);
598 517
599 plln = srctrl_table[fsel].plln; 518 plln = wmc_srctrl_table[fsel].plln;
600 mclkdiv = srctrl_table[fsel].mclkdiv; 519 mclkdiv = wmc_srctrl_table[fsel].mclkdiv;
601 520
602 if (plln != 0) 521 if (plln != 0)
603 { 522 {
@@ -605,9 +524,9 @@ void audiohw_set_frequency(int fsel)
605 524
606 /* Program PLL. */ 525 /* Program PLL. */
607 wmc_write(WMC_PLL_N, plln); 526 wmc_write(WMC_PLL_N, plln);
608 wmc_write(WMC_PLL_K1, srctrl_table[fsel].pllk1); 527 wmc_write(WMC_PLL_K1, wmc_srctrl_table[fsel].pllk1);
609 wmc_write(WMC_PLL_K2, srctrl_table[fsel].pllk2); 528 wmc_write(WMC_PLL_K2, wmc_srctrl_table[fsel].pllk2);
610 wmc_write(WMC_PLL_K3, srctrl_table[fsel].pllk3); 529 wmc_write(WMC_PLL_K3, wmc_srctrl_table[fsel].pllk3);
611 530
612 /* Turn on PLL. */ 531 /* Turn on PLL. */
613 wmc_set(WMC_POWER_MANAGEMENT1, WMC_PLLEN); 532 wmc_set(WMC_POWER_MANAGEMENT1, WMC_PLLEN);
diff --git a/firmware/export/wm8978.h b/firmware/export/wm8978.h
index 4081d05a89..f591c1b9fb 100644
--- a/firmware/export/wm8978.h
+++ b/firmware/export/wm8978.h
@@ -499,4 +499,15 @@ void wmc_clear(unsigned int reg, unsigned int bits);
499#define WMC_RMIX2OUT4 (1 << 1) 499#define WMC_RMIX2OUT4 (1 << 1)
500#define WMC_RDAC2OUT4 (1 << 0) 500#define WMC_RDAC2OUT4 (1 << 0)
501 501
502/* For implementing samplerate conrol */
503struct wmc_srctrl_entry
504{
505 uint32_t plln : 8;
506 uint32_t pllk1 : 6;
507 uint32_t pllk2 : 9;
508 uint32_t pllk3 : 9;
509 unsigned char mclkdiv;
510 unsigned char filter;
511};
512
502#endif /* _WM8978_H */ 513#endif /* _WM8978_H */
diff --git a/firmware/target/arm/imx31/gigabeat-s/i2s-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/i2s-gigabeat-s.c
index 6291a9cf18..723999c15e 100644
--- a/firmware/target/arm/imx31/gigabeat-s/i2s-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/i2s-gigabeat-s.c
@@ -20,6 +20,8 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "config.h" 21#include "config.h"
22#include "system.h" 22#include "system.h"
23#include "ccm-imx31.h"
24#include "sdma-imx31.h"
23#include "i2s.h" 25#include "i2s.h"
24 26
25void i2s_reset(void) 27void i2s_reset(void)
@@ -42,4 +44,95 @@ void i2s_reset(void)
42 ((64-1) << CCM_PDR1_SSI2_PODF_POS), 44 ((64-1) << CCM_PDR1_SSI2_PODF_POS),
43 CCM_PDR1_SSI1_PODF | CCM_PDR1_SSI2_PODF | 45 CCM_PDR1_SSI1_PODF | CCM_PDR1_SSI2_PODF |
44 CCM_PDR1_SSI1_PRE_PODF | CCM_PDR1_SSI2_PRE_PODF); 46 CCM_PDR1_SSI1_PRE_PODF | CCM_PDR1_SSI2_PRE_PODF);
47
48 ccm_module_clock_gating(CG_SSI1, CGM_ON_RUN_WAIT);
49 ccm_module_clock_gating(CG_SSI2, CGM_ON_RUN_WAIT);
50
51 /* Reset & disable SSIs */
52 SSI_SCR1 &= ~SSI_SCR_SSIEN;
53 SSI_SCR2 &= ~SSI_SCR_SSIEN;
54
55 SSI_SIER1 = 0;
56 SSI_SIER2 = 0;
57
58 /* Set up audio mux */
59
60 /* Port 2 (internally connected to SSI2)
61 * All clocking is output sourced from port 4 */
62 AUDMUX_PTCR2 = AUDMUX_PTCR_TFS_DIR | AUDMUX_PTCR_TFSEL_PORT4 |
63 AUDMUX_PTCR_TCLKDIR | AUDMUX_PTCR_TCSEL_PORT4 |
64 AUDMUX_PTCR_SYN;
65
66 /* Receive data from port 4 */
67 AUDMUX_PDCR2 = AUDMUX_PDCR_RXDSEL_PORT4;
68 /* All clock lines are inputs sourced from the master mode codec and
69 * sent back to SSI2 through port 2 */
70 AUDMUX_PTCR4 = AUDMUX_PTCR_SYN;
71
72 /* Receive data from port 2 */
73 AUDMUX_PDCR4 = AUDMUX_PDCR_RXDSEL_PORT2;
74
75 /* PORT1 (internally connected to SSI1) routes clocking to PORT5 to
76 * provide MCLK to the codec */
77 /* TX clocks are inputs taken from SSI2 */
78 /* RX clocks are outputs taken from PORT4 */
79 AUDMUX_PTCR1 = AUDMUX_PTCR_RFS_DIR | AUDMUX_PTCR_RFSSEL_PORT4 |
80 AUDMUX_PTCR_RCLKDIR | AUDMUX_PTCR_RCSEL_PORT4;
81 /* RX data taken from PORT4 */
82 AUDMUX_PDCR1 = AUDMUX_PDCR_RXDSEL_PORT4;
83
84 /* PORT5 outputs TCLK sourced from PORT1 (SSI1) */
85 AUDMUX_PTCR5 = AUDMUX_PTCR_TCLKDIR | AUDMUX_PTCR_TCSEL_PORT1;
86 AUDMUX_PDCR5 = 0;
87
88 /* Setup SSIs */
89
90 /* SSI2 - SoC software interface for all I2S data out */
91 SSI_SCR2 = SSI_SCR_SYN | SSI_SCR_I2S_MODE_SLAVE;
92 SSI_STCR2 = SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSI |
93 SSI_STCR_TEFS | SSI_STCR_TFEN0;
94
95 /* 16 bits per word, 2 words per frame */
96 SSI_STCCR2 = SSI_STRCCR_WL16 | ((2-1) << SSI_STRCCR_DC_POS) |
97 ((4-1) << SSI_STRCCR_PM_POS);
98
99 /* Transmit low watermark */
100 SSI_SFCSR2 = (SSI_SFCSR2 & ~SSI_SFCSR_TFWM0) |
101 ((8-SDMA_SSI_TXFIFO_WML) << SSI_SFCSR_TFWM0_POS);
102 SSI_STMSK2 = 0;
103
104 /* SSI1 - provides MCLK to codec. Receives data from codec. */
105 SSI_STCR1 = SSI_STCR_TXDIR;
106
107 /* f(INT_BIT_CLK) =
108 * f(SYS_CLK) / [(DIV2 + 1)*(7*PSR + 1)*(PM + 1)*2] =
109 * 677737600 / [(1 + 1)*(7*0 + 1)*(0 + 1)*2] =
110 * 677737600 / 4 = 169344000 Hz
111 *
112 * 45.4.2.2 DIV2, PSR, and PM Bit Description states:
113 * Bits DIV2, PSR, and PM should not be all set to zero at the same
114 * time.
115 *
116 * The hardware seems to force a divide by 4 even if all bits are
117 * zero but comply by setting DIV2 and the others to zero.
118 */
119 SSI_STCCR1 = SSI_STRCCR_DIV2 | ((1-1) << SSI_STRCCR_PM_POS);
120
121 /* SSI1 - receive - asynchronous clocks */
122 SSI_SCR1 = SSI_SCR_I2S_MODE_SLAVE;
123
124 SSI_SRCR1 = SSI_SRCR_RXBIT0 | SSI_SRCR_RSCKP | SSI_SRCR_RFSI |
125 SSI_SRCR_REFS;
126
127 /* 16 bits per word, 2 words per frame */
128 SSI_SRCCR1 = SSI_STRCCR_WL16 | ((2-1) << SSI_STRCCR_DC_POS) |
129 ((4-1) << SSI_STRCCR_PM_POS);
130
131 /* Receive high watermark */
132 SSI_SFCSR1 = (SSI_SFCSR1 & ~SSI_SFCSR_RFWM0) |
133 (SDMA_SSI_RXFIFO_WML << SSI_SFCSR_RFWM0_POS);
134 SSI_SRMSK1 = 0;
135
136 /* Enable SSI1 (codec clock) */
137 SSI_SCR1 |= SSI_SCR_SSIEN;
45} 138}
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
index 65571a4ee2..1c21415752 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
@@ -23,7 +23,7 @@
23#include "kernel.h" 23#include "kernel.h"
24#include "audio.h" 24#include "audio.h"
25#include "sound.h" 25#include "sound.h"
26#include "ccm-imx31.h" 26//#include "ccm-imx31.h"
27#include "sdma-imx31.h" 27#include "sdma-imx31.h"
28#include "mmu-imx31.h" 28#include "mmu-imx31.h"
29#include "pcm-internal.h" 29#include "pcm-internal.h"
@@ -149,101 +149,11 @@ void pcm_dma_apply_settings(void)
149 149
150void pcm_play_dma_init(void) 150void pcm_play_dma_init(void)
151{ 151{
152 /* Init channel information */ 152 /* Init DMA channel information */
153 sdma_channel_init(DMA_PLAY_CH_NUM, &dma_play_cd, &dma_play_bd); 153 sdma_channel_init(DMA_PLAY_CH_NUM, &dma_play_cd, &dma_play_bd);
154 sdma_channel_set_priority(DMA_PLAY_CH_NUM, DMA_PLAY_CH_PRIORITY); 154 sdma_channel_set_priority(DMA_PLAY_CH_NUM, DMA_PLAY_CH_PRIORITY);
155 155
156 ccm_module_clock_gating(CG_SSI1, CGM_ON_RUN_WAIT); 156 /* Init audio interfaces */
157 ccm_module_clock_gating(CG_SSI2, CGM_ON_RUN_WAIT);
158
159 /* Reset & disable SSIs */
160 SSI_SCR1 &= ~SSI_SCR_SSIEN;
161 SSI_SCR2 &= ~SSI_SCR_SSIEN;
162
163 SSI_SIER1 = 0;
164 SSI_SIER2 = 0;
165
166 /* Set up audio mux */
167
168 /* Port 2 (internally connected to SSI2)
169 * All clocking is output sourced from port 4 */
170 AUDMUX_PTCR2 = AUDMUX_PTCR_TFS_DIR | AUDMUX_PTCR_TFSEL_PORT4 |
171 AUDMUX_PTCR_TCLKDIR | AUDMUX_PTCR_TCSEL_PORT4 |
172 AUDMUX_PTCR_SYN;
173
174 /* Receive data from port 4 */
175 AUDMUX_PDCR2 = AUDMUX_PDCR_RXDSEL_PORT4;
176 /* All clock lines are inputs sourced from the master mode codec and
177 * sent back to SSI2 through port 2 */
178 AUDMUX_PTCR4 = AUDMUX_PTCR_SYN;
179
180 /* Receive data from port 2 */
181 AUDMUX_PDCR4 = AUDMUX_PDCR_RXDSEL_PORT2;
182
183 /* PORT1 (internally connected to SSI1) routes clocking to PORT5 to
184 * provide MCLK to the codec */
185 /* TX clocks are inputs taken from SSI2 */
186 /* RX clocks are outputs taken from PORT4 */
187 AUDMUX_PTCR1 = AUDMUX_PTCR_RFS_DIR | AUDMUX_PTCR_RFSSEL_PORT4 |
188 AUDMUX_PTCR_RCLKDIR | AUDMUX_PTCR_RCSEL_PORT4;
189 /* RX data taken from PORT4 */
190 AUDMUX_PDCR1 = AUDMUX_PDCR_RXDSEL_PORT4;
191
192 /* PORT5 outputs TCLK sourced from PORT1 (SSI1) */
193 AUDMUX_PTCR5 = AUDMUX_PTCR_TCLKDIR | AUDMUX_PTCR_TCSEL_PORT1;
194 AUDMUX_PDCR5 = 0;
195
196 /* Setup SSIs */
197
198 /* SSI2 - SoC software interface for all I2S data out */
199 SSI_SCR2 = SSI_SCR_SYN | SSI_SCR_I2S_MODE_SLAVE;
200 SSI_STCR2 = SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSI |
201 SSI_STCR_TEFS | SSI_STCR_TFEN0;
202
203 /* 16 bits per word, 2 words per frame */
204 SSI_STCCR2 = SSI_STRCCR_WL16 | ((2-1) << SSI_STRCCR_DC_POS) |
205 ((4-1) << SSI_STRCCR_PM_POS);
206
207 /* Transmit low watermark */
208 SSI_SFCSR2 = (SSI_SFCSR2 & ~SSI_SFCSR_TFWM0) |
209 ((8-SDMA_SSI_TXFIFO_WML) << SSI_SFCSR_TFWM0_POS);
210 SSI_STMSK2 = 0;
211
212 /* SSI1 - provides MCLK to codec. Receives data from codec. */
213 SSI_STCR1 = SSI_STCR_TXDIR;
214
215 /* f(INT_BIT_CLK) =
216 * f(SYS_CLK) / [(DIV2 + 1)*(7*PSR + 1)*(PM + 1)*2] =
217 * 677737600 / [(1 + 1)*(7*0 + 1)*(0 + 1)*2] =
218 * 677737600 / 4 = 169344000 Hz
219 *
220 * 45.4.2.2 DIV2, PSR, and PM Bit Description states:
221 * Bits DIV2, PSR, and PM should not be all set to zero at the same
222 * time.
223 *
224 * The hardware seems to force a divide by 4 even if all bits are
225 * zero but comply by setting DIV2 and the others to zero.
226 */
227 SSI_STCCR1 = SSI_STRCCR_DIV2 | ((1-1) << SSI_STRCCR_PM_POS);
228
229 /* SSI1 - receive - asynchronous clocks */
230 SSI_SCR1 = SSI_SCR_I2S_MODE_SLAVE;
231
232 SSI_SRCR1 = SSI_SRCR_RXBIT0 | SSI_SRCR_RSCKP | SSI_SRCR_RFSI |
233 SSI_SRCR_REFS;
234
235 /* 16 bits per word, 2 words per frame */
236 SSI_SRCCR1 = SSI_STRCCR_WL16 | ((2-1) << SSI_STRCCR_DC_POS) |
237 ((4-1) << SSI_STRCCR_PM_POS);
238
239 /* Receive high watermark */
240 SSI_SFCSR1 = (SSI_SFCSR1 & ~SSI_SFCSR_RFWM0) |
241 (SDMA_SSI_RXFIFO_WML << SSI_SFCSR_RFWM0_POS);
242 SSI_SRMSK1 = 0;
243
244 /* Enable SSI1 (codec clock) */
245 SSI_SCR1 |= SSI_SCR_SSIEN;
246
247 audiohw_init(); 157 audiohw_init();
248} 158}
249 159
diff --git a/firmware/target/arm/imx31/gigabeat-s/wmcodec-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/wmcodec-gigabeat-s.c
index 36ab33a5dc..ca23aa4e56 100644
--- a/firmware/target/arm/imx31/gigabeat-s/wmcodec-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/wmcodec-gigabeat-s.c
@@ -22,24 +22,93 @@
22 ****************************************************************************/ 22 ****************************************************************************/
23#include "config.h" 23#include "config.h"
24#include "system.h" 24#include "system.h"
25#include "kernel.h" 25#include "audiohw.h"
26#include "sound.h"
27#include "wmcodec.h" 26#include "wmcodec.h"
27#include "audio.h"
28#include "i2s.h" 28#include "i2s.h"
29#include "i2c-imx31.h" 29#include "i2c-imx31.h"
30 30
31/* NOTE: Some port-specific bits will have to be moved away (node and GPIO
32 * writes) for cleanest implementation. */
33
34static struct i2c_node wm8978_i2c_node = 31static struct i2c_node wm8978_i2c_node =
35{ 32{
36 .num = I2C1_NUM, 33 .num = I2C1_NUM,
37 .ifdr = I2C_IFDR_DIV192, /* 66MHz/.4MHz = 165, closest = 192 = 343750Hz */ 34 .ifdr = I2C_IFDR_DIV192, /* 66MHz/.4MHz = 165, closest = 192 = 343750Hz */
38 /* Just hard-code for now - scaling may require
39 * updating */
40 .addr = WMC_I2C_ADDR, 35 .addr = WMC_I2C_ADDR,
41}; 36};
42 37
38/* For 16.9344MHz MCLK, codec as master. */
39const struct wmc_srctrl_entry wmc_srctrl_table[HW_NUM_FREQ] =
40{
41 [HW_FREQ_8] = /* PLL = 65.536MHz */
42 {
43 .plln = 7 | WMC_PLL_PRESCALE,
44 .pllk1 = 0x2f, /* 12414886 */
45 .pllk2 = 0x0b7,
46 .pllk3 = 0x1a6,
47 .mclkdiv = WMC_MCLKDIV_8, /* 2.0480 MHz */
48 .filter = WMC_SR_8KHZ,
49 },
50 [HW_FREQ_11] = /* PLL = off */
51 {
52 .mclkdiv = WMC_MCLKDIV_6, /* 2.8224 MHz */
53 .filter = WMC_SR_12KHZ,
54 },
55 [HW_FREQ_12] = /* PLL = 73.728 MHz */
56 {
57 .plln = 8 | WMC_PLL_PRESCALE,
58 .pllk1 = 0x2d, /* 11869595 */
59 .pllk2 = 0x08e,
60 .pllk3 = 0x19b,
61 .mclkdiv = WMC_MCLKDIV_6, /* 3.0720 MHz */
62 .filter = WMC_SR_12KHZ,
63 },
64 [HW_FREQ_16] = /* PLL = 65.536MHz */
65 {
66 .plln = 7 | WMC_PLL_PRESCALE,
67 .pllk1 = 0x2f, /* 12414886 */
68 .pllk2 = 0x0b7,
69 .pllk3 = 0x1a6,
70 .mclkdiv = WMC_MCLKDIV_4, /* 4.0960 MHz */
71 .filter = WMC_SR_16KHZ,
72 },
73 [HW_FREQ_22] = /* PLL = off */
74 {
75 .mclkdiv = WMC_MCLKDIV_3, /* 5.6448 MHz */
76 .filter = WMC_SR_24KHZ,
77 },
78 [HW_FREQ_24] = /* PLL = 73.728 MHz */
79 {
80 .plln = 8 | WMC_PLL_PRESCALE,
81 .pllk1 = 0x2d, /* 11869595 */
82 .pllk2 = 0x08e,
83 .pllk3 = 0x19b,
84 .mclkdiv = WMC_MCLKDIV_3, /* 6.1440 MHz */
85 .filter = WMC_SR_24KHZ,
86 },
87 [HW_FREQ_32] = /* PLL = 65.536MHz */
88 {
89 .plln = 7 | WMC_PLL_PRESCALE,
90 .pllk1 = 0x2f, /* 12414886 */
91 .pllk2 = 0x0b7,
92 .pllk3 = 0x1a6,
93 .mclkdiv = WMC_MCLKDIV_2, /* 8.1920 MHz */
94 .filter = WMC_SR_32KHZ,
95 },
96 [HW_FREQ_44] = /* PLL = off */
97 {
98 .mclkdiv = WMC_MCLKDIV_1_5, /* 11.2896 MHz */
99 .filter = WMC_SR_48KHZ,
100 },
101 [HW_FREQ_48] = /* PLL = 73.728 MHz */
102 {
103 .plln = 8 | WMC_PLL_PRESCALE,
104 .pllk1 = 0x2d, /* 11869595 */
105 .pllk2 = 0x08e,
106 .pllk3 = 0x19b,
107 .mclkdiv = WMC_MCLKDIV_1_5, /* 12.2880 MHz */
108 .filter = WMC_SR_48KHZ,
109 },
110};
111
43void audiohw_init(void) 112void audiohw_init(void)
44{ 113{
45 i2s_reset(); 114 i2s_reset();