1 /*
2 ** =============================================================================
3 ** Copyright (c) 2016 Texas Instruments Inc.
4 **
5 ** This program is free software; you can redistribute it and/or modify it under
6 ** the terms of the GNU General Public License as published by the Free Software
7 ** Foundation; version 2.
8 **
9 ** This program is distributed in the hope that it will be useful, but WITHOUT
10 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 ** FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.
12 **
13 ** File:
14 ** tas2562-codec.c
15 **
16 ** Description:
17 ** ALSA SoC driver for Texas Instruments TAS2562 High Performance 4W Smart
18 ** Amplifier
19 **
20 ** =============================================================================
21 */
23 #ifdef CONFIG_TAS2562_CODEC
24 #define DEBUG 5
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/pm.h>
30 #include <linux/i2c.h>
31 #include <linux/gpio.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/firmware.h>
34 #include <linux/regmap.h>
35 #include <linux/of.h>
36 #include <linux/of_gpio.h>
37 #include <linux/slab.h>
38 #include <sound/core.h>
39 #include <sound/pcm.h>
40 #include <sound/pcm_params.h>
41 #include <sound/soc.h>
42 #include <sound/initval.h>
43 #include <sound/tlv.h>
45 #include "tas2562.h"
47 #define TAS2562_MDELAY 0xFFFFFFFE
48 #define TAS2562_MSLEEP 0xFFFFFFFD
50 static char pICN[] = {0x00, 0x03, 0x46, 0xdc};
51 static char const *iv_enable_text[] = {"Off", "On"};
52 static int tas2562iv_enable;
53 static int mbMute;
54 static const struct soc_enum tas2562_enum[] = {
55 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(iv_enable_text), iv_enable_text),
56 };
57 static int tas2562_set_fmt(struct tas2562_priv *pTAS2562, unsigned int fmt);
59 static int tas2562_i2c_load_data(struct tas2562_priv *pTAS2562, unsigned int *pData);
60 static int tas2562_mute_ctrl_get(struct snd_kcontrol *pKcontrol,
61 struct snd_ctl_elem_value *pValue);
62 static int tas2562_mute_ctrl_put(struct snd_kcontrol *pKcontrol,
63 struct snd_ctl_elem_value *pValue);
65 static unsigned int p_tas2562_classH_D_data[] = {
66 /* reg address size values */
67 TAS2562_ClassHHeadroom, 0x4, 0x09, 0x99, 0x99, 0x9a,
68 TAS2562_ClassHHysteresis, 0x4, 0x0, 0x0, 0x0, 0x0,
69 TAS2562_ClassHMtct, 0x4, 0xb, 0x0, 0x0, 0x0,
70 TAS2562_VBatFilter, 0x1, 0x38,
71 TAS2562_ClassHReleaseTimer, 0x1, 0x3c,
72 TAS2562_BoostSlope, 0x1, 0x78,
73 TAS2562_TestPageConfiguration, 0x1, 0xd,
74 TAS2562_ClassDConfiguration3, 0x1, 0x8e,
75 TAS2562_ClassDConfiguration2, 0x1, 0x49,
76 TAS2562_ClassDConfiguration4, 0x1, 0x21,
77 TAS2562_ClassDConfiguration1, 0x1, 0x80,
78 TAS2562_EfficiencyConfiguration, 0x1, 0xc1,
79 0xFFFFFFFF, 0xFFFFFFFF
80 };
83 static unsigned int tas2562_codec_read(struct snd_soc_codec *codec,
84 unsigned int reg)
85 {
86 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
87 int nResult = 0;
88 unsigned int value = 0;
90 nResult = pTAS2562->read(pTAS2562, reg, &value);
92 if (nResult < 0)
93 dev_err(pTAS2562->dev, "%s, ERROR, reg=0x%x, E=%d\n",
94 __func__, reg, nResult);
95 else
96 dev_dbg(pTAS2562->dev, "%s, reg: 0x%x, value: 0x%x\n",
97 __func__, reg, value);
99 if (nResult >= 0)
100 return value;
101 else
102 return nResult;
103 }
105 static int tas2562_iv_enable(struct tas2562_priv *pTAS2562, int enable)
106 {
107 int nResult;
109 if (enable) {
110 pr_debug("%s: tas2562iv_enable \n", __func__);
111 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
112 TAS2562_PowerControl_ISNSPower_Mask |
113 TAS2562_PowerControl_VSNSPower_Mask,
114 TAS2562_PowerControl_VSNSPower_Active |
115 TAS2562_PowerControl_ISNSPower_Active);
116 } else {
117 pr_debug("%s: tas2562iv_disable \n", __func__);
118 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
119 TAS2562_PowerControl_ISNSPower_Mask |
120 TAS2562_PowerControl_VSNSPower_Mask,
121 TAS2562_PowerControl_VSNSPower_PoweredDown |
122 TAS2562_PowerControl_ISNSPower_PoweredDown);
123 }
124 tas2562iv_enable = enable;
126 return nResult;
127 }
129 static int tas2562iv_put(struct snd_kcontrol *kcontrol,
130 struct snd_ctl_elem_value *ucontrol)
131 {
132 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
133 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
134 int iv_enable = 0, nResult = 0;
136 if (codec == NULL) {
137 pr_err("%s: codec is NULL \n", __func__);
138 return 0;
139 }
141 iv_enable = ucontrol->value.integer.value[0];
143 nResult = tas2562_iv_enable(pTAS2562, iv_enable);
145 pr_debug("%s: tas2562iv_enable = %d\n", __func__, tas2562iv_enable);
147 return nResult;
148 }
150 static int tas2562iv_get(struct snd_kcontrol *kcontrol,
151 struct snd_ctl_elem_value *ucontrol)
152 {
153 ucontrol->value.integer.value[0] = tas2562iv_enable;
154 return 0;
155 }
157 static const struct snd_kcontrol_new tas2562_controls[] = {
158 SOC_ENUM_EXT("TAS2562 IVSENSE ENABLE", tas2562_enum[0],
159 tas2562iv_get, tas2562iv_put),
160 };
162 static int tas2562_codec_write(struct snd_soc_codec *codec, unsigned int reg,
163 unsigned int value)
164 {
165 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
167 int nResult = 0;
169 nResult = pTAS2562->write(pTAS2562, reg, value);
170 if (nResult < 0)
171 dev_err(pTAS2562->dev, "%s, ERROR, reg=0x%x, E=%d\n",
172 __func__, reg, nResult);
173 else
174 dev_dbg(pTAS2562->dev, "%s, reg: 0x%x, 0x%x\n",
175 __func__, reg, value);
177 return nResult;
179 }
180 static int tas2562_i2c_load_data(struct tas2562_priv *pTAS2562, unsigned int *pData)
181 {
182 unsigned int nRegister;
183 unsigned int *nData;
184 unsigned char Buf[128];
185 unsigned int nLength = 0;
186 unsigned int i = 0;
187 unsigned int nSize = 0;
188 int nResult = 0;
189 do {
190 nRegister = pData[nLength];
191 nSize = pData[nLength + 1];
192 nData = &pData[nLength + 2];
193 if (nRegister == TAS2562_MSLEEP) {
194 msleep(nData[0]);
195 dev_dbg(pTAS2562->dev, "%s, msleep = %d\n",
196 __func__, nData[0]);
197 } else if (nRegister == TAS2562_MDELAY) {
198 mdelay(nData[0]);
199 dev_dbg(pTAS2562->dev, "%s, mdelay = %d\n",
200 __func__, nData[0]);
201 } else {
202 if (nRegister != 0xFFFFFFFF) {
203 if (nSize > 128) {
204 dev_err(pTAS2562->dev,
205 "%s, Line=%d, invalid size, maximum is 128 bytes!\n",
206 __func__, __LINE__);
207 break;
208 }
209 if (nSize > 1) {
210 for (i = 0; i < nSize; i++)
211 Buf[i] = (unsigned char)nData[i];
212 nResult = pTAS2562->bulk_write(pTAS2562, nRegister, Buf, nSize);
213 if (nResult < 0)
214 break;
215 } else if (nSize == 1) {
216 nResult = pTAS2562->write(pTAS2562, nRegister, nData[0]);
217 if (nResult < 0)
218 break;
219 } else {
220 dev_err(pTAS2562->dev,
221 "%s, Line=%d,invalid size, minimum is 1 bytes!\n",
222 __func__, __LINE__);
223 }
224 }
225 }
226 nLength = nLength + 2 + pData[nLength + 1];
227 } while (nRegister != 0xFFFFFFFF);
228 return nResult;
229 }
230 static int tas2562_codec_suspend(struct snd_soc_codec *codec)
231 {
232 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
233 int ret = 0;
235 mutex_lock(&pTAS2562->codec_lock);
237 dev_dbg(pTAS2562->dev, "%s\n", __func__);
238 pTAS2562->runtime_suspend(pTAS2562);
240 mutex_unlock(&pTAS2562->codec_lock);
241 return ret;
242 }
244 static int tas2562_codec_resume(struct snd_soc_codec *codec)
245 {
246 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
247 int ret = 0;
249 mutex_lock(&pTAS2562->codec_lock);
251 dev_dbg(pTAS2562->dev, "%s\n", __func__);
252 pTAS2562->runtime_resume(pTAS2562);
254 mutex_unlock(&pTAS2562->codec_lock);
255 return ret;
256 }
258 static const struct snd_kcontrol_new tas2562_asi_controls[] = {
259 SOC_DAPM_SINGLE("Left", TAS2562_TDMConfigurationReg2,
260 4, 1, 0),
261 SOC_DAPM_SINGLE("Right", TAS2562_TDMConfigurationReg2,
262 4, 2, 0),
263 SOC_DAPM_SINGLE("LeftRightDiv2", TAS2562_TDMConfigurationReg2,
264 4, 3, 0),
265 };
267 static int tas2562_set_power_state(struct tas2562_priv *pTAS2562, int state)
268 {
269 int nResult = 0;
270 /*unsigned int nValue;*/
272 if ((pTAS2562->mbMute) && (state == TAS2562_POWER_ACTIVE))
273 state = TAS2562_POWER_MUTE;
274 dev_err(pTAS2562->dev, "set power state: %d\n", state);
276 switch (state) {
277 case TAS2562_POWER_ACTIVE:
278 //if set format was not called by asoc, then set it default
279 if(pTAS2562->mnASIFormat == 0)
280 pTAS2562->mnASIFormat = SND_SOC_DAIFMT_CBS_CFS
281 | SND_SOC_DAIFMT_IB_NF
282 | SND_SOC_DAIFMT_I2S;
283 nResult = tas2562_set_fmt(pTAS2562, pTAS2562->mnASIFormat);
284 if (nResult < 0)
285 return nResult;
287 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
288 TAS2562_PowerControl_OperationalMode10_Mask,
289 TAS2562_PowerControl_OperationalMode10_Active);
290 if (nResult < 0)
291 return nResult;
292 pTAS2562->mbPowerUp = true;
293 dev_info(pTAS2562->dev, "set ICN to -80dB\n");
294 nResult = pTAS2562->bulk_write(pTAS2562, TAS2562_ICN_REG, pICN, 4);
295 pTAS2562->mnPowerState = TAS2562_POWER_ACTIVE;
296 pTAS2562->enableIRQ(pTAS2562, true);
297 break;
299 case TAS2562_POWER_MUTE:
300 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
301 TAS2562_PowerControl_OperationalMode10_Mask |
302 TAS2562_PowerControl_ISNSPower_Mask |
303 TAS2562_PowerControl_VSNSPower_Mask,
304 TAS2562_PowerControl_OperationalMode10_Mute |
305 TAS2562_PowerControl_VSNSPower_Active |
306 TAS2562_PowerControl_ISNSPower_Active);
307 pTAS2562->mbPowerUp = true;
308 pTAS2562->mnPowerState = TAS2562_POWER_MUTE;
309 break;
311 case TAS2562_POWER_SHUTDOWN:
312 pTAS2562->enableIRQ(pTAS2562, false);
313 if (hrtimer_active(&pTAS2562->mtimer))
314 {
315 dev_info(pTAS2562->dev, "cancel timer\n");
316 hrtimer_cancel(&pTAS2562->mtimer);
317 }
319 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
320 TAS2562_PowerControl_OperationalMode10_Mask,
321 TAS2562_PowerControl_OperationalMode10_Shutdown);
322 pTAS2562->mbPowerUp = false;
323 pTAS2562->mnPowerState = TAS2562_POWER_SHUTDOWN;
324 msleep(20);
326 break;
328 default:
329 dev_err(pTAS2562->dev, "wrong power state setting %d\n", state);
331 }
333 return nResult;
334 }
337 static int tas2562_dac_event(struct snd_soc_dapm_widget *w,
338 struct snd_kcontrol *kcontrol, int event)
339 {
340 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
341 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
343 switch (event) {
344 case SND_SOC_DAPM_POST_PMU:
345 tas2562_set_power_state(pTAS2562, TAS2562_POWER_ACTIVE);
346 break;
347 case SND_SOC_DAPM_PRE_PMD:
348 tas2562_set_power_state(pTAS2562, TAS2562_POWER_SHUTDOWN);
349 break;
351 }
352 return 0;
354 }
356 static const struct snd_soc_dapm_widget tas2562_dapm_widgets[] = {
357 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
358 SND_SOC_DAPM_AIF_OUT("Voltage Sense", "ASI1 Capture", 1, TAS2562_PowerControl, 2, 1),
359 SND_SOC_DAPM_AIF_OUT("Current Sense", "ASI1 Capture", 0, TAS2562_PowerControl, 3, 1),
360 SND_SOC_DAPM_MIXER("ASI1 Sel",
361 TAS2562_TDMConfigurationReg2, 4, 0,
362 &tas2562_asi_controls[0],
363 ARRAY_SIZE(tas2562_asi_controls)),
364 SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2562_dac_event,
365 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
366 SND_SOC_DAPM_OUTPUT("OUT"),
367 SND_SOC_DAPM_SIGGEN("VMON"),
368 SND_SOC_DAPM_SIGGEN("IMON")
369 };
371 static const struct snd_soc_dapm_route tas2562_audio_map[] = {
372 {"ASI1 Sel", "Left", "ASI1"},
373 {"ASI1 Sel", "Right", "ASI1"},
374 {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
375 {"DAC", NULL, "ASI1 Sel"},
376 {"OUT", NULL, "DAC"},
377 /*{"VMON", NULL, "Voltage Sense"},
378 {"IMON", NULL, "Current Sense"},*/
379 {"Voltage Sense", NULL, "VMON"},
380 {"Current Sense", NULL, "IMON"},
381 };
384 static int tas2562_mute(struct snd_soc_dai *dai, int mute)
385 {
386 struct snd_soc_codec *codec = dai->codec;
387 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
389 dev_dbg(pTAS2562->dev, "%s, %d \n", __func__, mute);
391 mutex_lock(&pTAS2562->codec_lock);
392 if (mute) {
393 tas2562_set_power_state(pTAS2562, TAS2562_POWER_SHUTDOWN);
394 } else {
395 tas2562_set_power_state(pTAS2562, TAS2562_POWER_ACTIVE);
396 }
397 mutex_unlock(&pTAS2562->codec_lock);
398 return 0;
399 }
401 static int tas2562_slot_config(struct snd_soc_codec *codec, struct tas2562_priv *pTAS2562, int blr_clk_ratio)
402 {
403 int ret = 0;
404 pTAS2562->update_bits(pTAS2562,
405 TAS2562_TDMConfigurationReg5, 0xff, 0x42);
407 pTAS2562->update_bits(pTAS2562,
408 TAS2562_TDMConfigurationReg6, 0xff, 0x40);
410 return ret;
411 }
413 static int tas2562_set_slot(struct snd_soc_codec *codec, int slot_width)
414 {
415 int ret = 0;
416 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
418 switch (slot_width) {
419 case 16:
420 ret = pTAS2562->update_bits(pTAS2562,
421 TAS2562_TDMConfigurationReg2,
422 TAS2562_TDMConfigurationReg2_RXSLEN10_Mask,
423 TAS2562_TDMConfigurationReg2_RXSLEN10_16Bits);
424 break;
426 case 24:
427 ret = pTAS2562->update_bits(pTAS2562,
428 TAS2562_TDMConfigurationReg2,
429 TAS2562_TDMConfigurationReg2_RXSLEN10_Mask,
430 TAS2562_TDMConfigurationReg2_RXSLEN10_24Bits);
431 break;
433 case 32:
434 ret = pTAS2562->update_bits(pTAS2562,
435 TAS2562_TDMConfigurationReg2,
436 TAS2562_TDMConfigurationReg2_RXSLEN10_Mask,
437 TAS2562_TDMConfigurationReg2_RXSLEN10_32Bits);
438 break;
440 case 0:
441 /* Do not change slot width */
442 break;
444 default:
445 dev_err(pTAS2562->dev, "slot width not supported");
446 ret = -EINVAL;
447 }
449 if (ret >= 0)
450 pTAS2562->mnSlot_width = slot_width;
452 return ret;
453 }
455 static int tas2562_set_bitwidth(struct tas2562_priv *pTAS2562, int bitwidth)
456 {
457 int slot_width_tmp = 16;
458 dev_info(pTAS2562->dev, "%s %d\n", __func__, bitwidth);
460 switch (bitwidth) {
461 case SNDRV_PCM_FORMAT_S16_LE:
462 pTAS2562->update_bits(pTAS2562,
463 TAS2562_TDMConfigurationReg2,
464 TAS2562_TDMConfigurationReg2_RXWLEN32_Mask,
465 TAS2562_TDMConfigurationReg2_RXWLEN32_16Bits);
466 pTAS2562->mnCh_size = 16;
467 if (pTAS2562->mnSlot_width == 0)
468 slot_width_tmp = 16;
469 break;
470 case SNDRV_PCM_FORMAT_S24_LE:
471 pTAS2562->update_bits(pTAS2562,
472 TAS2562_TDMConfigurationReg2,
473 TAS2562_TDMConfigurationReg2_RXWLEN32_Mask,
474 TAS2562_TDMConfigurationReg2_RXWLEN32_24Bits);
475 pTAS2562->mnCh_size = 24;
476 if (pTAS2562->mnSlot_width == 0)
477 slot_width_tmp = 32;
478 break;
479 case SNDRV_PCM_FORMAT_S32_LE:
480 pTAS2562->update_bits(pTAS2562,
481 TAS2562_TDMConfigurationReg2,
482 TAS2562_TDMConfigurationReg2_RXWLEN32_Mask,
483 TAS2562_TDMConfigurationReg2_RXWLEN32_32Bits);
484 pTAS2562->mnCh_size = 32;
485 if (pTAS2562->mnSlot_width == 0)
486 slot_width_tmp = 32;
487 break;
489 default:
490 dev_info(pTAS2562->dev, "Not supported params format\n");
491 }
493 /* If machine driver did not call set slot width */
494 if (pTAS2562->mnSlot_width == 0)
495 tas2562_set_slot(pTAS2562->codec, slot_width_tmp);
497 dev_info(pTAS2562->dev, "mnCh_size: %d\n", pTAS2562->mnCh_size);
498 pTAS2562->mnPCMFormat = bitwidth;
500 return 0;
501 }
503 static int tas2562_set_samplerate(struct tas2562_priv *pTAS2562, int samplerate)
504 {
505 switch (samplerate) {
506 case 48000:
507 pTAS2562->update_bits(pTAS2562,
508 TAS2562_TDMConfigurationReg0,
509 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
510 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
511 pTAS2562->update_bits(pTAS2562,
512 TAS2562_TDMConfigurationReg0,
513 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
514 TAS2562_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
515 break;
516 case 44100:
517 pTAS2562->update_bits(pTAS2562,
518 TAS2562_TDMConfigurationReg0,
519 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
520 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
521 pTAS2562->update_bits(pTAS2562,
522 TAS2562_TDMConfigurationReg0,
523 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
524 TAS2562_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
525 break;
526 case 96000:
527 pTAS2562->update_bits(pTAS2562,
528 TAS2562_TDMConfigurationReg0,
529 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
530 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
531 pTAS2562->update_bits(pTAS2562,
532 TAS2562_TDMConfigurationReg0,
533 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
534 TAS2562_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
535 break;
536 case 88200:
537 pTAS2562->update_bits(pTAS2562,
538 TAS2562_TDMConfigurationReg0,
539 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
540 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
541 pTAS2562->update_bits(pTAS2562,
542 TAS2562_TDMConfigurationReg0,
543 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
544 TAS2562_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
545 break;
546 case 19200:
547 pTAS2562->update_bits(pTAS2562,
548 TAS2562_TDMConfigurationReg0,
549 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
550 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
551 pTAS2562->update_bits(pTAS2562,
552 TAS2562_TDMConfigurationReg0,
553 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
554 TAS2562_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
555 break;
556 case 17640:
557 pTAS2562->update_bits(pTAS2562,
558 TAS2562_TDMConfigurationReg0,
559 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
560 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
561 pTAS2562->update_bits(pTAS2562,
562 TAS2562_TDMConfigurationReg0,
563 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
564 TAS2562_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
565 break;
566 default:
567 dev_info(pTAS2562->dev, "%s, unsupported sample rate, %d\n", __func__, samplerate);
569 }
571 pTAS2562->mnSamplingRate = samplerate;
572 return 0;
573 }
574 static int tas2562_mute_ctrl_get(struct snd_kcontrol *pKcontrol,
575 struct snd_ctl_elem_value *pValue)
576 {
577 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
578 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
580 pValue->value.integer.value[0] = pTAS2562->mbMute;
581 dev_dbg(pTAS2562->dev, "tas2562_mute_ctrl_get = %d\n",
582 pTAS2562->mbMute);
584 return 0;
585 }
587 static int tas2562_mute_ctrl_put(struct snd_kcontrol *pKcontrol,
588 struct snd_ctl_elem_value *pValue)
589 {
590 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
591 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
593 mbMute = pValue->value.integer.value[0];
595 dev_dbg(pTAS2562->dev, "tas2562_mute_ctrl_put = %d\n", mbMute);
597 pTAS2562->mbMute = !!mbMute;
599 return 0;
600 }
602 static int tas2562_hw_params(struct snd_pcm_substream *substream,
603 struct snd_pcm_hw_params *params,
604 struct snd_soc_dai *dai)
605 {
606 struct snd_soc_codec *codec = dai->codec;
607 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
608 int blr_clk_ratio;
609 int ret = 0;
611 dev_dbg(pTAS2562->dev, "%s, format: %d\n", __func__,
612 params_format(params));
614 mutex_lock(&pTAS2562->codec_lock);
616 ret = tas2562_set_bitwidth(pTAS2562, params_format(params));
617 if(ret < 0)
618 {
619 dev_info(pTAS2562->dev, "set bitwidth failed, %d\n", ret);
620 goto ret;
621 }
623 blr_clk_ratio = params_channels(params) * pTAS2562->mnCh_size;
624 dev_info(pTAS2562->dev, "blr_clk_ratio: %d\n", blr_clk_ratio);
625 if(blr_clk_ratio != 0)
626 tas2562_slot_config(pTAS2562->codec, pTAS2562, blr_clk_ratio);
628 dev_info(pTAS2562->dev, "%s, sample rate: %d\n", __func__,
629 params_rate(params));
631 ret = tas2562_set_samplerate(pTAS2562, params_rate(params));
633 ret:
634 mutex_unlock(&pTAS2562->codec_lock);
635 return ret;
636 }
638 static int tas2562_set_fmt(struct tas2562_priv *pTAS2562, unsigned int fmt)
639 {
640 u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
641 int ret = 0;
643 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
644 case SND_SOC_DAIFMT_CBS_CFS:
645 asi_cfg_1 = 0x00;
646 break;
647 default:
648 dev_err(pTAS2562->dev, "ASI format master is not found\n");
649 ret = -EINVAL;
650 }
652 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
653 case SND_SOC_DAIFMT_NB_NF:
654 dev_info(pTAS2562->dev, "INV format: NBNF\n");
655 asi_cfg_1 |= TAS2562_TDMConfigurationReg1_RXEDGE_Rising;
656 break;
657 case SND_SOC_DAIFMT_IB_NF:
658 dev_info(pTAS2562->dev, "INV format: IBNF\n");
659 asi_cfg_1 |= TAS2562_TDMConfigurationReg1_RXEDGE_Falling;
660 break;
661 default:
662 dev_err(pTAS2562->dev, "ASI format Inverse is not found\n");
663 ret = -EINVAL;
664 }
666 pTAS2562->update_bits(pTAS2562, TAS2562_TDMConfigurationReg1,
667 TAS2562_TDMConfigurationReg1_RXEDGE_Mask,
668 asi_cfg_1);
670 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
671 case (SND_SOC_DAIFMT_I2S):
672 tdm_rx_start_slot = 1;
673 break;
674 case (SND_SOC_DAIFMT_DSP_A):
675 case (SND_SOC_DAIFMT_DSP_B):
676 tdm_rx_start_slot = 1;
677 break;
678 case (SND_SOC_DAIFMT_LEFT_J):
679 tdm_rx_start_slot = 0;
680 break;
681 default:
682 dev_err(pTAS2562->dev, "DAI Format is not found, fmt=0x%x\n", fmt);
683 ret = -EINVAL;
684 break;
685 }
687 pTAS2562->update_bits(pTAS2562, TAS2562_TDMConfigurationReg1,
688 TAS2562_TDMConfigurationReg1_RXOFFSET51_Mask,
689 (tdm_rx_start_slot << TAS2562_TDMConfigurationReg1_RXOFFSET51_Shift));
691 pTAS2562->mnASIFormat = fmt;
693 return 0;
694 }
696 static int tas2562_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
697 {
698 struct snd_soc_codec *codec = dai->codec;
699 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
700 int ret = 0;
702 dev_dbg(pTAS2562->dev, "%s, format=0x%x\n", __func__, fmt);
704 ret = tas2562_set_fmt(pTAS2562, fmt);
705 return ret;
706 }
708 static int tas2562_set_dai_tdm_slot(struct snd_soc_dai *dai,
709 unsigned int tx_mask, unsigned int rx_mask,
710 int slots, int slot_width)
711 {
712 int ret = 0;
713 struct snd_soc_codec *codec = dai->codec;
714 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
716 dev_dbg(pTAS2562->dev, "%s, tx_mask:%d, rx_mask:%d, slots:%d, slot_width:%d",
717 __func__, tx_mask, rx_mask, slots, slot_width);
719 ret = tas2562_set_slot(codec, slot_width);
721 return ret;
722 }
724 static struct snd_soc_dai_ops tas2562_dai_ops = {
725 .digital_mute = tas2562_mute,
726 .hw_params = tas2562_hw_params,
727 .set_fmt = tas2562_set_dai_fmt,
728 .set_tdm_slot = tas2562_set_dai_tdm_slot,
729 };
731 #define TAS2562_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
732 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
734 #define TAS2562_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 \
735 SNDRV_PCM_RATE_88200 |\
736 SNDRV_PCM_RATE_96000 |\
737 SNDRV_PCM_RATE_176400 |\
738 SNDRV_PCM_RATE_192000\
739 )
741 static struct snd_soc_dai_driver tas2562_dai_driver[] = {
742 {
743 .name = "tas2562 ASI1",
744 .id = 0,
745 .playback = {
746 .stream_name = "ASI1 Playback",
747 .channels_min = 2,
748 .channels_max = 2,
749 .rates = SNDRV_PCM_RATE_8000_192000,
750 .formats = TAS2562_FORMATS,
751 },
752 .capture = {
753 .stream_name = "ASI1 Capture",
754 .channels_min = 0,
755 .channels_max = 2,
756 .rates = SNDRV_PCM_RATE_8000_192000,
757 .formats = TAS2562_FORMATS,
758 },
759 .ops = &tas2562_dai_ops,
760 .symmetric_rates = 1,
761 },
762 };
764 static int tas2562_load_init(struct tas2562_priv *pTAS2562)
765 {
766 int ret;
768 ret = pTAS2562->write(pTAS2562, TAS2562_MiscConfigurationReg0, 0xcf);
769 if(ret < 0)
770 return ret;
771 ret = pTAS2562->write(pTAS2562, TAS2562_TDMConfigurationReg4, 0x01);
772 if(ret < 0)
773 return ret;
774 ret = pTAS2562->write(pTAS2562, TAS2562_ClockConfiguration, 0x0c);
775 if(ret < 0)
776 return ret;
777 ret = tas2562_i2c_load_data(pTAS2562, p_tas2562_classH_D_data);
779 return ret;
780 }
782 static int tas2562_codec_probe(struct snd_soc_codec *codec)
783 {
784 int ret;
785 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
787 ret = snd_soc_add_codec_controls(codec, tas2562_controls,
788 ARRAY_SIZE(tas2562_controls));
789 if (ret < 0) {
790 pr_err("%s: add_codec_controls failed, err %d\n",
791 __func__, ret);
792 return ret;
793 }
795 tas2562_load_init(pTAS2562);
796 tas2562_iv_enable(pTAS2562, 1);
797 pTAS2562->codec = codec;
798 dev_err(pTAS2562->dev, "%s\n", __func__);
800 return 0;
801 }
803 static int tas2562_codec_remove(struct snd_soc_codec *codec)
804 {
805 return 0;
806 }
808 static DECLARE_TLV_DB_SCALE(tas2562_digital_tlv, 1100, 50, 0);
810 static const struct snd_kcontrol_new tas2562_snd_controls[] = {
811 SOC_SINGLE_TLV("Amp Output Level", TAS2562_PlaybackConfigurationReg0,
812 0, 0x16, 0,
813 tas2562_digital_tlv),
814 SOC_SINGLE_EXT("SmartPA Mute", SND_SOC_NOPM, 0, 0x0001, 0,
815 tas2562_mute_ctrl_get, tas2562_mute_ctrl_put),
816 };
818 static struct snd_soc_codec_driver soc_codec_driver_tas2562 = {
819 .probe = tas2562_codec_probe,
820 .remove = tas2562_codec_remove,
821 .read = tas2562_codec_read,
822 .write = tas2562_codec_write,
823 .suspend = tas2562_codec_suspend,
824 .resume = tas2562_codec_resume,
825 .component_driver = {
826 .controls = tas2562_snd_controls,
827 .num_controls = ARRAY_SIZE(tas2562_snd_controls),
828 .dapm_widgets = tas2562_dapm_widgets,
829 .num_dapm_widgets = ARRAY_SIZE(tas2562_dapm_widgets),
830 .dapm_routes = tas2562_audio_map,
831 .num_dapm_routes = ARRAY_SIZE(tas2562_audio_map),
832 },
833 };
835 int tas2562_register_codec(struct tas2562_priv *pTAS2562)
836 {
837 int nResult = 0;
839 dev_info(pTAS2562->dev, "%s, enter\n", __func__);
840 nResult = snd_soc_register_codec(pTAS2562->dev,
841 &soc_codec_driver_tas2562,
842 tas2562_dai_driver, ARRAY_SIZE(tas2562_dai_driver));
843 return nResult;
844 }
846 int tas2562_deregister_codec(struct tas2562_priv *pTAS2562)
847 {
848 snd_soc_unregister_codec(pTAS2562->dev);
850 return 0;
851 }
853 void tas2562_LoadConfig(struct tas2562_priv *pTAS2562)
854 {
855 int ret = 0;
857 if (hrtimer_active(&pTAS2562->mtimer))
858 {
859 dev_info(pTAS2562->dev, "cancel timer\n");
860 hrtimer_cancel(&pTAS2562->mtimer);
861 } else
862 dev_info(pTAS2562->dev, "timer not active\n");
864 pTAS2562->hw_reset(pTAS2562);
865 msleep(2);
866 pTAS2562->write(pTAS2562, TAS2562_SoftwareReset,
867 TAS2562_SoftwareReset_SoftwareReset_Reset);
868 msleep(3);
870 tas2562_load_init(pTAS2562);
872 ret = tas2562_set_slot(pTAS2562->codec, pTAS2562->mnSlot_width);
873 if (ret < 0)
874 goto end;
876 ret = tas2562_set_fmt(pTAS2562, pTAS2562->mnASIFormat);
877 if (ret < 0)
878 goto end;
880 ret = tas2562_set_bitwidth(pTAS2562, pTAS2562->mnPCMFormat);
881 if (ret < 0)
882 goto end;
884 ret = tas2562_set_samplerate(pTAS2562, pTAS2562->mnSamplingRate);
885 if (ret < 0)
886 goto end;
888 ret = tas2562_set_power_state(pTAS2562, pTAS2562->mnPowerState);
889 if (ret < 0)
890 goto end;
892 end:
893 /* power up failed, restart later */
894 if (ret < 0)
895 schedule_delayed_work(&pTAS2562->irq_work,
896 msecs_to_jiffies(1000));
897 }
899 MODULE_AUTHOR("Texas Instruments Inc.");
900 MODULE_DESCRIPTION("TAS2562 ALSA SOC Smart Amplifier driver");
901 MODULE_LICENSE("GPL v2");
902 #endif /* CONFIG_TAS2562_CODEC */