aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ak4642.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ak4642.c')
-rw-r--r--sound/soc/codecs/ak4642.c177
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
84struct snd_soc_codec_device soc_codec_dev_ak4642; 112struct snd_soc_codec_device soc_codec_dev_ak4642;
85 113
86/* codec private data */ 114/* codec private data */
87struct ak4642_priv { 115struct ak4642_priv {
88 struct snd_soc_codec codec; 116 struct snd_soc_codec codec;
89 unsigned int sysclk;
90}; 117};
91 118
92static struct snd_soc_codec *ak4642_codec; 119static 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
302static 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
328static 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
265struct snd_soc_dai ak4642_dai = { 389struct 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};
281EXPORT_SYMBOL_GPL(ak4642_dai); 406EXPORT_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
363reg_cache_err: 468reg_cache_err: