diff options
Diffstat (limited to 'sound/soc/codecs/ak4642.c')
-rw-r--r-- | sound/soc/codecs/ak4642.c | 177 |
1 files changed, 141 insertions, 36 deletions
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 729859cf6ca8..7528a54102b5 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -81,12 +81,39 @@ | |||
81 | 81 | ||
82 | #define AK4642_CACHEREGNUM 0x25 | 82 | #define AK4642_CACHEREGNUM 0x25 |
83 | 83 | ||
84 | /* PW_MGMT2 */ | ||
85 | #define HPMTN (1 << 6) | ||
86 | #define PMHPL (1 << 5) | ||
87 | #define PMHPR (1 << 4) | ||
88 | #define MS (1 << 3) /* master/slave select */ | ||
89 | #define MCKO (1 << 1) | ||
90 | #define PMPLL (1 << 0) | ||
91 | |||
92 | #define PMHP_MASK (PMHPL | PMHPR) | ||
93 | #define PMHP PMHP_MASK | ||
94 | |||
95 | /* MD_CTL1 */ | ||
96 | #define PLL3 (1 << 7) | ||
97 | #define PLL2 (1 << 6) | ||
98 | #define PLL1 (1 << 5) | ||
99 | #define PLL0 (1 << 4) | ||
100 | #define PLL_MASK (PLL3 | PLL2 | PLL1 | PLL0) | ||
101 | |||
102 | #define BCKO_MASK (1 << 3) | ||
103 | #define BCKO_64 BCKO_MASK | ||
104 | |||
105 | /* MD_CTL2 */ | ||
106 | #define FS0 (1 << 0) | ||
107 | #define FS1 (1 << 1) | ||
108 | #define FS2 (1 << 2) | ||
109 | #define FS3 (1 << 5) | ||
110 | #define FS_MASK (FS0 | FS1 | FS2 | FS3) | ||
111 | |||
84 | struct snd_soc_codec_device soc_codec_dev_ak4642; | 112 | struct snd_soc_codec_device soc_codec_dev_ak4642; |
85 | 113 | ||
86 | /* codec private data */ | 114 | /* codec private data */ |
87 | struct ak4642_priv { | 115 | struct ak4642_priv { |
88 | struct snd_soc_codec codec; | 116 | struct snd_soc_codec codec; |
89 | unsigned int sysclk; | ||
90 | }; | 117 | }; |
91 | 118 | ||
92 | static struct snd_soc_codec *ak4642_codec; | 119 | static struct snd_soc_codec *ak4642_codec; |
@@ -177,17 +204,12 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, | |||
177 | * | 204 | * |
178 | * PLL, Master Mode | 205 | * PLL, Master Mode |
179 | * Audio I/F Format :MSB justified (ADC & DAC) | 206 | * Audio I/F Format :MSB justified (ADC & DAC) |
180 | * Sampling Frequency: 44.1kHz | 207 | * Digital Volume: -8dB |
181 | * Digital Volume: −8dB | ||
182 | * Bass Boost Level : Middle | 208 | * Bass Boost Level : Middle |
183 | * | 209 | * |
184 | * This operation came from example code of | 210 | * This operation came from example code of |
185 | * "ASAHI KASEI AK4642" (japanese) manual p97. | 211 | * "ASAHI KASEI AK4642" (japanese) manual p97. |
186 | * | ||
187 | * Example code use 0x39, 0x79 value for 0x01 address, | ||
188 | * But we need MCKO (0x02) bit now | ||
189 | */ | 212 | */ |
190 | ak4642_write(codec, 0x05, 0x27); | ||
191 | ak4642_write(codec, 0x0f, 0x09); | 213 | ak4642_write(codec, 0x0f, 0x09); |
192 | ak4642_write(codec, 0x0e, 0x19); | 214 | ak4642_write(codec, 0x0e, 0x19); |
193 | ak4642_write(codec, 0x09, 0x91); | 215 | ak4642_write(codec, 0x09, 0x91); |
@@ -195,15 +217,14 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, | |||
195 | ak4642_write(codec, 0x0a, 0x28); | 217 | ak4642_write(codec, 0x0a, 0x28); |
196 | ak4642_write(codec, 0x0d, 0x28); | 218 | ak4642_write(codec, 0x0d, 0x28); |
197 | ak4642_write(codec, 0x00, 0x64); | 219 | ak4642_write(codec, 0x00, 0x64); |
198 | ak4642_write(codec, 0x01, 0x3b); /* + MCKO bit */ | 220 | snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); |
199 | ak4642_write(codec, 0x01, 0x7b); /* + MCKO bit */ | 221 | snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN); |
200 | } else { | 222 | } else { |
201 | /* | 223 | /* |
202 | * start stereo input | 224 | * start stereo input |
203 | * | 225 | * |
204 | * PLL Master Mode | 226 | * PLL Master Mode |
205 | * Audio I/F Format:MSB justified (ADC & DAC) | 227 | * Audio I/F Format:MSB justified (ADC & DAC) |
206 | * Sampling Frequency:44.1kHz | ||
207 | * Pre MIC AMP:+20dB | 228 | * Pre MIC AMP:+20dB |
208 | * MIC Power On | 229 | * MIC Power On |
209 | * ALC setting:Refer to Table 35 | 230 | * ALC setting:Refer to Table 35 |
@@ -212,7 +233,6 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, | |||
212 | * This operation came from example code of | 233 | * This operation came from example code of |
213 | * "ASAHI KASEI AK4642" (japanese) manual p94. | 234 | * "ASAHI KASEI AK4642" (japanese) manual p94. |
214 | */ | 235 | */ |
215 | ak4642_write(codec, 0x05, 0x27); | ||
216 | ak4642_write(codec, 0x02, 0x05); | 236 | ak4642_write(codec, 0x02, 0x05); |
217 | ak4642_write(codec, 0x06, 0x3c); | 237 | ak4642_write(codec, 0x06, 0x3c); |
218 | ak4642_write(codec, 0x08, 0xe1); | 238 | ak4642_write(codec, 0x08, 0xe1); |
@@ -233,8 +253,8 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream, | |||
233 | 253 | ||
234 | if (is_play) { | 254 | if (is_play) { |
235 | /* stop headphone output */ | 255 | /* stop headphone output */ |
236 | ak4642_write(codec, 0x01, 0x3b); | 256 | snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0); |
237 | ak4642_write(codec, 0x01, 0x0b); | 257 | snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0); |
238 | ak4642_write(codec, 0x00, 0x40); | 258 | ak4642_write(codec, 0x00, 0x40); |
239 | ak4642_write(codec, 0x0e, 0x11); | 259 | ak4642_write(codec, 0x0e, 0x11); |
240 | ak4642_write(codec, 0x0f, 0x08); | 260 | ak4642_write(codec, 0x0f, 0x08); |
@@ -250,9 +270,111 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai, | |||
250 | int clk_id, unsigned int freq, int dir) | 270 | int clk_id, unsigned int freq, int dir) |
251 | { | 271 | { |
252 | struct snd_soc_codec *codec = codec_dai->codec; | 272 | struct snd_soc_codec *codec = codec_dai->codec; |
253 | struct ak4642_priv *ak4642 = codec->private_data; | 273 | u8 pll; |
274 | |||
275 | switch (freq) { | ||
276 | case 11289600: | ||
277 | pll = PLL2; | ||
278 | break; | ||
279 | case 12288000: | ||
280 | pll = PLL2 | PLL0; | ||
281 | break; | ||
282 | case 12000000: | ||
283 | pll = PLL2 | PLL1; | ||
284 | break; | ||
285 | case 24000000: | ||
286 | pll = PLL2 | PLL1 | PLL0; | ||
287 | break; | ||
288 | case 13500000: | ||
289 | pll = PLL3 | PLL2; | ||
290 | break; | ||
291 | case 27000000: | ||
292 | pll = PLL3 | PLL2 | PLL0; | ||
293 | break; | ||
294 | default: | ||
295 | return -EINVAL; | ||
296 | } | ||
297 | snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll); | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
303 | { | ||
304 | struct snd_soc_codec *codec = dai->codec; | ||
305 | u8 data; | ||
306 | u8 bcko; | ||
307 | |||
308 | data = MCKO | PMPLL; /* use MCKO */ | ||
309 | bcko = 0; | ||
310 | |||
311 | /* set master/slave audio interface */ | ||
312 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
313 | case SND_SOC_DAIFMT_CBM_CFM: | ||
314 | data |= MS; | ||
315 | bcko = BCKO_64; | ||
316 | break; | ||
317 | case SND_SOC_DAIFMT_CBS_CFS: | ||
318 | break; | ||
319 | default: | ||
320 | return -EINVAL; | ||
321 | } | ||
322 | snd_soc_update_bits(codec, PW_MGMT2, MS, data); | ||
323 | snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, | ||
329 | struct snd_pcm_hw_params *params, | ||
330 | struct snd_soc_dai *dai) | ||
331 | { | ||
332 | struct snd_soc_codec *codec = dai->codec; | ||
333 | u8 rate; | ||
334 | |||
335 | switch (params_rate(params)) { | ||
336 | case 7350: | ||
337 | rate = FS2; | ||
338 | break; | ||
339 | case 8000: | ||
340 | rate = 0; | ||
341 | break; | ||
342 | case 11025: | ||
343 | rate = FS2 | FS0; | ||
344 | break; | ||
345 | case 12000: | ||
346 | rate = FS0; | ||
347 | break; | ||
348 | case 14700: | ||
349 | rate = FS2 | FS1; | ||
350 | break; | ||
351 | case 16000: | ||
352 | rate = FS1; | ||
353 | break; | ||
354 | case 22050: | ||
355 | rate = FS2 | FS1 | FS0; | ||
356 | break; | ||
357 | case 24000: | ||
358 | rate = FS1 | FS0; | ||
359 | break; | ||
360 | case 29400: | ||
361 | rate = FS3 | FS2 | FS1; | ||
362 | break; | ||
363 | case 32000: | ||
364 | rate = FS3 | FS1; | ||
365 | break; | ||
366 | case 44100: | ||
367 | rate = FS3 | FS2 | FS1 | FS0; | ||
368 | break; | ||
369 | case 48000: | ||
370 | rate = FS3 | FS1 | FS0; | ||
371 | break; | ||
372 | default: | ||
373 | return -EINVAL; | ||
374 | break; | ||
375 | } | ||
376 | snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate); | ||
254 | 377 | ||
255 | ak4642->sysclk = freq; | ||
256 | return 0; | 378 | return 0; |
257 | } | 379 | } |
258 | 380 | ||
@@ -260,6 +382,8 @@ static struct snd_soc_dai_ops ak4642_dai_ops = { | |||
260 | .startup = ak4642_dai_startup, | 382 | .startup = ak4642_dai_startup, |
261 | .shutdown = ak4642_dai_shutdown, | 383 | .shutdown = ak4642_dai_shutdown, |
262 | .set_sysclk = ak4642_dai_set_sysclk, | 384 | .set_sysclk = ak4642_dai_set_sysclk, |
385 | .set_fmt = ak4642_dai_set_fmt, | ||
386 | .hw_params = ak4642_dai_hw_params, | ||
263 | }; | 387 | }; |
264 | 388 | ||
265 | struct snd_soc_dai ak4642_dai = { | 389 | struct snd_soc_dai ak4642_dai = { |
@@ -277,6 +401,7 @@ struct snd_soc_dai ak4642_dai = { | |||
277 | .rates = SNDRV_PCM_RATE_8000_48000, | 401 | .rates = SNDRV_PCM_RATE_8000_48000, |
278 | .formats = SNDRV_PCM_FMTBIT_S16_LE }, | 402 | .formats = SNDRV_PCM_FMTBIT_S16_LE }, |
279 | .ops = &ak4642_dai_ops, | 403 | .ops = &ak4642_dai_ops, |
404 | .symmetric_rates = 1, | ||
280 | }; | 405 | }; |
281 | EXPORT_SYMBOL_GPL(ak4642_dai); | 406 | EXPORT_SYMBOL_GPL(ak4642_dai); |
282 | 407 | ||
@@ -307,7 +432,7 @@ static int ak4642_init(struct ak4642_priv *ak4642) | |||
307 | INIT_LIST_HEAD(&codec->dapm_widgets); | 432 | INIT_LIST_HEAD(&codec->dapm_widgets); |
308 | INIT_LIST_HEAD(&codec->dapm_paths); | 433 | INIT_LIST_HEAD(&codec->dapm_paths); |
309 | 434 | ||
310 | codec->private_data = ak4642; | 435 | snd_soc_codec_set_drvdata(codec, ak4642); |
311 | codec->name = "AK4642"; | 436 | codec->name = "AK4642"; |
312 | codec->owner = THIS_MODULE; | 437 | codec->owner = THIS_MODULE; |
313 | codec->read = ak4642_read_reg_cache; | 438 | codec->read = ak4642_read_reg_cache; |
@@ -338,26 +463,6 @@ static int ak4642_init(struct ak4642_priv *ak4642) | |||
338 | goto reg_cache_err; | 463 | goto reg_cache_err; |
339 | } | 464 | } |
340 | 465 | ||
341 | /* | ||
342 | * clock setting | ||
343 | * | ||
344 | * Audio I/F Format: MSB justified (ADC & DAC) | ||
345 | * BICK frequency at Master Mode: 64fs | ||
346 | * Input Master Clock Select at PLL Mode: 11.2896MHz | ||
347 | * MCKO: Enable | ||
348 | * Sampling Frequency: 44.1kHz | ||
349 | * | ||
350 | * This operation came from example code of | ||
351 | * "ASAHI KASEI AK4642" (japanese) manual p89. | ||
352 | * | ||
353 | * please fix-me | ||
354 | */ | ||
355 | ak4642_write(codec, 0x01, 0x08); | ||
356 | ak4642_write(codec, 0x04, 0x4a); | ||
357 | ak4642_write(codec, 0x05, 0x27); | ||
358 | ak4642_write(codec, 0x00, 0x40); | ||
359 | ak4642_write(codec, 0x01, 0x0b); | ||
360 | |||
361 | return ret; | 466 | return ret; |
362 | 467 | ||
363 | reg_cache_err: | 468 | reg_cache_err: |