aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/pxa/raumfeld.c
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2010-01-15 11:36:49 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-01-15 12:28:41 -0500
commita421296840379aee7d00ec4a28ecfe7e697a0a44 (patch)
tree93e1b3cb7a2a343e20ea754776bf4535aa5184a3 /sound/soc/pxa/raumfeld.c
parent6aababdf20bb8892023bb8df136514d7679e4959 (diff)
ASoC: support more sample rates on raumfeld devices
Add support for sample rates other than 44100Khz on raumfeld audio devices. At startup time, call snd_soc_dai_set_sysclk() with 0 as 'freq' argument so it offers all the sample rates. Later, the function is called again to give proper constraints. Use the external audio clock generator to provide double data rate clocks as the PXA's internal baud generator does anything but what's described in the datasheets. Signed-off-by: Daniel Mack <daniel@caiaq.de> Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Timur Tabi <timur@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/pxa/raumfeld.c')
-rw-r--r--sound/soc/pxa/raumfeld.c61
1 files changed, 40 insertions, 21 deletions
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index acfce1c0f1c9..7e3f41696c41 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -41,7 +41,9 @@ static struct i2c_board_info max9486_hwmon_info = {
41}; 41};
42 42
43#define MAX9485_MCLK_FREQ_112896 0x22 43#define MAX9485_MCLK_FREQ_112896 0x22
44#define MAX9485_MCLK_FREQ_122880 0x23 44#define MAX9485_MCLK_FREQ_122880 0x23
45#define MAX9485_MCLK_FREQ_225792 0x32
46#define MAX9485_MCLK_FREQ_245760 0x33
45 47
46static void set_max9485_clk(char clk) 48static void set_max9485_clk(char clk)
47{ 49{
@@ -71,9 +73,17 @@ static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
71 struct snd_soc_pcm_runtime *rtd = substream->private_data; 73 struct snd_soc_pcm_runtime *rtd = substream->private_data;
72 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 74 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
73 75
74 set_max9485_clk(MAX9485_MCLK_FREQ_112896); 76 /* set freq to 0 to enable all possible codec sample rates */
77 return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
78}
75 79
76 return snd_soc_dai_set_sysclk(codec_dai, 0, 11289600, 0); 80static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
81{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
84
85 /* set freq to 0 to enable all possible codec sample rates */
86 snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
77} 87}
78 88
79static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream, 89static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
@@ -86,20 +96,24 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
86 int ret = 0; 96 int ret = 0;
87 97
88 switch (params_rate(params)) { 98 switch (params_rate(params)) {
89 case 8000: 99 case 44100:
90 case 16000: 100 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
101 clk = 11289600;
102 break;
91 case 48000: 103 case 48000:
92 case 96000:
93 set_max9485_clk(MAX9485_MCLK_FREQ_122880); 104 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
94 clk = 12288000; 105 clk = 12288000;
95 break; 106 break;
96 case 11025:
97 case 22050:
98 case 44100:
99 case 88200: 107 case 88200:
100 set_max9485_clk(MAX9485_MCLK_FREQ_112896); 108 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
101 clk = 11289600; 109 clk = 22579200;
102 break; 110 break;
111 case 96000:
112 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
113 clk = 24576000;
114 break;
115 default:
116 return -EINVAL;
103 } 117 }
104 118
105 fmt = SND_SOC_DAIFMT_I2S | 119 fmt = SND_SOC_DAIFMT_I2S |
@@ -128,7 +142,7 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
128 if (ret < 0) 142 if (ret < 0)
129 return ret; 143 return ret;
130 144
131 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, 0, 1); 145 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
132 if (ret < 0) 146 if (ret < 0)
133 return ret; 147 return ret;
134 148
@@ -137,6 +151,7 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
137 151
138static struct snd_soc_ops raumfeld_cs4270_ops = { 152static struct snd_soc_ops raumfeld_cs4270_ops = {
139 .startup = raumfeld_cs4270_startup, 153 .startup = raumfeld_cs4270_startup,
154 .shutdown = raumfeld_cs4270_shutdown,
140 .hw_params = raumfeld_cs4270_hw_params, 155 .hw_params = raumfeld_cs4270_hw_params,
141}; 156};
142 157
@@ -181,20 +196,24 @@ static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
181 int fmt, ret = 0, clk = 0; 196 int fmt, ret = 0, clk = 0;
182 197
183 switch (params_rate(params)) { 198 switch (params_rate(params)) {
184 case 8000: 199 case 44100:
185 case 16000: 200 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
201 clk = 11289600;
202 break;
186 case 48000: 203 case 48000:
187 case 96000:
188 set_max9485_clk(MAX9485_MCLK_FREQ_122880); 204 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
189 clk = 12288000; 205 clk = 12288000;
190 break; 206 break;
191 case 11025:
192 case 22050:
193 case 44100:
194 case 88200: 207 case 88200:
195 set_max9485_clk(MAX9485_MCLK_FREQ_112896); 208 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
196 clk = 11289600; 209 clk = 22579200;
210 break;
211 case 96000:
212 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
213 clk = 24576000;
197 break; 214 break;
215 default:
216 return -EINVAL;
198 } 217 }
199 218
200 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF; 219 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
@@ -217,7 +236,7 @@ static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
217 if (ret < 0) 236 if (ret < 0)
218 return ret; 237 return ret;
219 238
220 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, 0, 1); 239 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
221 if (ret < 0) 240 if (ret < 0)
222 return ret; 241 return ret;
223 242