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 const *iv_enable_text[] = {"Off", "On"};
51 static int tas2562iv_enable = 1;
52 static int mbMute;
53 static const struct soc_enum tas2562_enum[] = {
54 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(iv_enable_text), iv_enable_text),
55 };
56 static int tas2562_set_fmt(struct tas2562_priv *pTAS2562, unsigned int fmt);
58 static int tas2562_i2c_load_data(struct tas2562_priv *pTAS2562, unsigned int *pData);
59 static int tas2562_mute_ctrl_get(struct snd_kcontrol *pKcontrol,
60 struct snd_ctl_elem_value *pValue);
61 static int tas2562_mute_ctrl_put(struct snd_kcontrol *pKcontrol,
62 struct snd_ctl_elem_value *pValue);
64 static unsigned int p_tas2562_classH_D_data[] = {
65 /* reg address size values */
66 TAS2562_ClassHHeadroom, 0x4, 0x09, 0x99, 0x99, 0x9a,
67 TAS2562_ClassHHysteresis, 0x4, 0x0, 0x0, 0x0, 0x0,
68 TAS2562_ClassHMtct, 0x4, 0xb, 0x0, 0x0, 0x0,
69 TAS2562_VBatFilter, 0x1, 0x38,
70 TAS2562_ClassHReleaseTimer, 0x1, 0x3c,
71 TAS2562_BoostSlope, 0x1, 0x78,
72 TAS2562_TestPageConfiguration, 0x1, 0xd,
73 TAS2562_ClassDConfiguration3, 0x1, 0x8e,
74 TAS2562_ClassDConfiguration2, 0x1, 0x49,
75 TAS2562_ClassDConfiguration4, 0x1, 0x21,
76 TAS2562_ClassDConfiguration1, 0x1, 0x80,
77 TAS2562_EfficiencyConfiguration, 0x1, 0xc1,
78 0xFFFFFFFF, 0xFFFFFFFF
79 };
82 static unsigned int tas2562_codec_read(struct snd_soc_codec *codec,
83 unsigned int reg)
84 {
85 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
86 int nResult = 0;
87 unsigned int value = 0;
89 nResult = pTAS2562->read(pTAS2562, reg, &value);
91 if (nResult < 0)
92 dev_err(pTAS2562->dev, "%s, ERROR, reg=0x%x, E=%d\n",
93 __func__, reg, nResult);
94 else
95 dev_dbg(pTAS2562->dev, "%s, reg: 0x%x, value: 0x%x\n",
96 __func__, reg, value);
98 if (nResult >= 0)
99 return value;
100 else
101 return nResult;
102 }
104 static int tas2562_iv_enable(struct tas2562_priv *pTAS2562, int enable)
105 {
106 int nResult;
108 if (enable) {
109 pr_debug("%s: tas2562iv_enable \n", __func__);
110 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
111 TAS2562_PowerControl_ISNSPower_Mask |
112 TAS2562_PowerControl_VSNSPower_Mask,
113 TAS2562_PowerControl_VSNSPower_Active |
114 TAS2562_PowerControl_ISNSPower_Active);
115 } else {
116 pr_debug("%s: tas2562iv_disable \n", __func__);
117 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
118 TAS2562_PowerControl_ISNSPower_Mask |
119 TAS2562_PowerControl_VSNSPower_Mask,
120 TAS2562_PowerControl_VSNSPower_PoweredDown |
121 TAS2562_PowerControl_ISNSPower_PoweredDown);
122 }
123 tas2562iv_enable = enable;
125 return nResult;
126 }
128 static int tas2562iv_put(struct snd_kcontrol *kcontrol,
129 struct snd_ctl_elem_value *ucontrol)
130 {
131 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
132 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
133 int iv_enable = 0, nResult = 0;
135 if (codec == NULL) {
136 pr_err("%s: codec is NULL \n", __func__);
137 return 0;
138 }
140 iv_enable = ucontrol->value.integer.value[0];
142 nResult = tas2562_iv_enable(pTAS2562, iv_enable);
144 pr_debug("%s: tas2562iv_enable = %d\n", __func__, tas2562iv_enable);
146 return nResult;
147 }
149 static int tas2562iv_get(struct snd_kcontrol *kcontrol,
150 struct snd_ctl_elem_value *ucontrol)
151 {
152 ucontrol->value.integer.value[0] = tas2562iv_enable;
153 return 0;
154 }
156 static const struct snd_kcontrol_new tas2562_controls[] = {
157 SOC_ENUM_EXT("TAS2562 IVSENSE ENABLE", tas2562_enum[0],
158 tas2562iv_get, tas2562iv_put),
159 };
161 static int tas2562_codec_write(struct snd_soc_codec *codec, unsigned int reg,
162 unsigned int value)
163 {
164 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
166 int nResult = 0;
168 nResult = pTAS2562->write(pTAS2562, reg, value);
169 if (nResult < 0)
170 dev_err(pTAS2562->dev, "%s, ERROR, reg=0x%x, E=%d\n",
171 __func__, reg, nResult);
172 else
173 dev_dbg(pTAS2562->dev, "%s, reg: 0x%x, 0x%x\n",
174 __func__, reg, value);
176 return nResult;
178 }
179 static int tas2562_i2c_load_data(struct tas2562_priv *pTAS2562, unsigned int *pData)
180 {
181 unsigned int nRegister;
182 unsigned int *nData;
183 unsigned char Buf[128];
184 unsigned int nLength = 0;
185 unsigned int i = 0;
186 unsigned int nSize = 0;
187 int nResult = 0;
188 do {
189 nRegister = pData[nLength];
190 nSize = pData[nLength + 1];
191 nData = &pData[nLength + 2];
192 if (nRegister == TAS2562_MSLEEP) {
193 msleep(nData[0]);
194 dev_dbg(pTAS2562->dev, "%s, msleep = %d\n",
195 __func__, nData[0]);
196 } else if (nRegister == TAS2562_MDELAY) {
197 mdelay(nData[0]);
198 dev_dbg(pTAS2562->dev, "%s, mdelay = %d\n",
199 __func__, nData[0]);
200 } else {
201 if (nRegister != 0xFFFFFFFF) {
202 if (nSize > 128) {
203 dev_err(pTAS2562->dev,
204 "%s, Line=%d, invalid size, maximum is 128 bytes!\n",
205 __func__, __LINE__);
206 break;
207 }
208 if (nSize > 1) {
209 for (i = 0; i < nSize; i++)
210 Buf[i] = (unsigned char)nData[i];
211 nResult = pTAS2562->bulk_write(pTAS2562, nRegister, Buf, nSize);
212 if (nResult < 0)
213 break;
214 } else if (nSize == 1) {
215 nResult = pTAS2562->write(pTAS2562, nRegister, nData[0]);
216 if (nResult < 0)
217 break;
218 } else {
219 dev_err(pTAS2562->dev,
220 "%s, Line=%d,invalid size, minimum is 1 bytes!\n",
221 __func__, __LINE__);
222 }
223 }
224 }
225 nLength = nLength + 2 + pData[nLength + 1];
226 } while (nRegister != 0xFFFFFFFF);
227 return nResult;
228 }
229 static int tas2562_codec_suspend(struct snd_soc_codec *codec)
230 {
231 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
232 int ret = 0;
234 mutex_lock(&pTAS2562->codec_lock);
236 dev_dbg(pTAS2562->dev, "%s\n", __func__);
237 pTAS2562->runtime_suspend(pTAS2562);
239 mutex_unlock(&pTAS2562->codec_lock);
240 return ret;
241 }
243 static int tas2562_codec_resume(struct snd_soc_codec *codec)
244 {
245 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
246 int ret = 0;
248 mutex_lock(&pTAS2562->codec_lock);
250 dev_dbg(pTAS2562->dev, "%s\n", __func__);
251 pTAS2562->runtime_resume(pTAS2562);
253 mutex_unlock(&pTAS2562->codec_lock);
254 return ret;
255 }
257 static const struct snd_kcontrol_new tas2562_asi_controls[] = {
258 SOC_DAPM_SINGLE("Left", TAS2562_TDMConfigurationReg2,
259 4, 1, 0),
260 SOC_DAPM_SINGLE("Right", TAS2562_TDMConfigurationReg2,
261 4, 2, 0),
262 SOC_DAPM_SINGLE("LeftRightDiv2", TAS2562_TDMConfigurationReg2,
263 4, 3, 0),
264 };
266 static int tas2562_set_power_state(struct tas2562_priv *pTAS2562, int state)
267 {
268 int nResult = 0;
269 /*unsigned int nValue;*/
270 int irqreg;
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 //Clear latched IRQ before power on
289 pTAS2562->update_bits(pTAS2562, TAS2562_InterruptConfiguration,
290 TAS2562_InterruptConfiguration_LTCHINTClear_Mask,
291 TAS2562_InterruptConfiguration_LTCHINTClear);
293 pTAS2562->read(pTAS2562, TAS2562_LatchedInterruptReg0, &irqreg);
294 dev_info(pTAS2562->dev, "IRQ reg is: %s %d, %d\n", __func__, irqreg, __LINE__);
296 pTAS2562->mbPowerUp = true;
297 pTAS2562->mnPowerState = TAS2562_POWER_ACTIVE;
298 schedule_delayed_work(&pTAS2562->irq_work, msecs_to_jiffies(10));
299 break;
301 case TAS2562_POWER_MUTE:
302 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
303 TAS2562_PowerControl_OperationalMode10_Mask |
304 TAS2562_PowerControl_ISNSPower_Mask |
305 TAS2562_PowerControl_VSNSPower_Mask,
306 TAS2562_PowerControl_OperationalMode10_Mute |
307 TAS2562_PowerControl_VSNSPower_Active |
308 TAS2562_PowerControl_ISNSPower_Active);
309 pTAS2562->mbPowerUp = true;
310 pTAS2562->mnPowerState = TAS2562_POWER_MUTE;
311 break;
313 case TAS2562_POWER_SHUTDOWN:
314 pTAS2562->enableIRQ(pTAS2562, false);
315 if (hrtimer_active(&pTAS2562->mtimer))
316 {
317 dev_info(pTAS2562->dev, "cancel timer\n");
318 hrtimer_cancel(&pTAS2562->mtimer);
319 }
321 nResult = pTAS2562->update_bits(pTAS2562, TAS2562_PowerControl,
322 TAS2562_PowerControl_OperationalMode10_Mask,
323 TAS2562_PowerControl_OperationalMode10_Shutdown);
324 pTAS2562->mbPowerUp = false;
325 pTAS2562->mnPowerState = TAS2562_POWER_SHUTDOWN;
326 msleep(20);
328 break;
330 default:
331 dev_err(pTAS2562->dev, "wrong power state setting %d\n", state);
333 }
335 return nResult;
336 }
339 static int tas2562_dac_event(struct snd_soc_dapm_widget *w,
340 struct snd_kcontrol *kcontrol, int event)
341 {
342 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
343 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
345 switch (event) {
346 case SND_SOC_DAPM_POST_PMU:
347 tas2562_set_power_state(pTAS2562, TAS2562_POWER_ACTIVE);
348 break;
349 case SND_SOC_DAPM_PRE_PMD:
350 tas2562_set_power_state(pTAS2562, TAS2562_POWER_SHUTDOWN);
351 break;
353 }
354 return 0;
356 }
358 static const struct snd_soc_dapm_widget tas2562_dapm_widgets[] = {
359 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
360 SND_SOC_DAPM_AIF_OUT("Voltage Sense", "ASI1 Capture", 1, TAS2562_PowerControl, 2, 1),
361 SND_SOC_DAPM_AIF_OUT("Current Sense", "ASI1 Capture", 0, TAS2562_PowerControl, 3, 1),
362 SND_SOC_DAPM_MIXER("ASI1 Sel",
363 TAS2562_TDMConfigurationReg2, 4, 0,
364 &tas2562_asi_controls[0],
365 ARRAY_SIZE(tas2562_asi_controls)),
366 SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2562_dac_event,
367 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
368 SND_SOC_DAPM_OUTPUT("OUT"),
369 SND_SOC_DAPM_SIGGEN("VMON"),
370 SND_SOC_DAPM_SIGGEN("IMON")
371 };
373 static const struct snd_soc_dapm_route tas2562_audio_map[] = {
374 {"ASI1 Sel", "Left", "ASI1"},
375 {"ASI1 Sel", "Right", "ASI1"},
376 {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
377 {"DAC", NULL, "ASI1 Sel"},
378 {"OUT", NULL, "DAC"},
379 /*{"VMON", NULL, "Voltage Sense"},
380 {"IMON", NULL, "Current Sense"},*/
381 {"Voltage Sense", NULL, "VMON"},
382 {"Current Sense", NULL, "IMON"},
383 };
386 static int tas2562_mute(struct snd_soc_dai *dai, int mute)
387 {
388 struct snd_soc_codec *codec = dai->codec;
389 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
391 dev_dbg(pTAS2562->dev, "%s, %d \n", __func__, mute);
393 mutex_lock(&pTAS2562->codec_lock);
394 if (mute) {
395 tas2562_set_power_state(pTAS2562, TAS2562_POWER_SHUTDOWN);
396 } else {
397 tas2562_set_power_state(pTAS2562, TAS2562_POWER_ACTIVE);
398 }
399 mutex_unlock(&pTAS2562->codec_lock);
400 return 0;
401 }
403 static int tas2562_slot_config(struct snd_soc_codec *codec, struct tas2562_priv *pTAS2562, int blr_clk_ratio)
404 {
405 int ret = 0;
406 pTAS2562->update_bits(pTAS2562,
407 TAS2562_TDMConfigurationReg5, 0xff, 0x42);
409 pTAS2562->update_bits(pTAS2562,
410 TAS2562_TDMConfigurationReg6, 0xff, 0x40);
412 return ret;
413 }
415 static int tas2562_set_slot(struct snd_soc_codec *codec, int slot_width)
416 {
417 int ret = 0;
418 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
420 switch (slot_width) {
421 case 16:
422 ret = pTAS2562->update_bits(pTAS2562,
423 TAS2562_TDMConfigurationReg2,
424 TAS2562_TDMConfigurationReg2_RXSLEN10_Mask,
425 TAS2562_TDMConfigurationReg2_RXSLEN10_16Bits);
426 break;
428 case 24:
429 ret = pTAS2562->update_bits(pTAS2562,
430 TAS2562_TDMConfigurationReg2,
431 TAS2562_TDMConfigurationReg2_RXSLEN10_Mask,
432 TAS2562_TDMConfigurationReg2_RXSLEN10_24Bits);
433 break;
435 case 32:
436 ret = pTAS2562->update_bits(pTAS2562,
437 TAS2562_TDMConfigurationReg2,
438 TAS2562_TDMConfigurationReg2_RXSLEN10_Mask,
439 TAS2562_TDMConfigurationReg2_RXSLEN10_32Bits);
440 break;
442 case 0:
443 /* Do not change slot width */
444 break;
446 default:
447 dev_err(pTAS2562->dev, "slot width not supported");
448 ret = -EINVAL;
449 }
451 if (ret >= 0)
452 pTAS2562->mnSlot_width = slot_width;
454 return ret;
455 }
457 static int tas2562_set_bitwidth(struct tas2562_priv *pTAS2562, int bitwidth)
458 {
459 int slot_width_tmp = 16;
460 dev_info(pTAS2562->dev, "%s %d\n", __func__, bitwidth);
462 switch (bitwidth) {
463 case SNDRV_PCM_FORMAT_S16_LE:
464 pTAS2562->update_bits(pTAS2562,
465 TAS2562_TDMConfigurationReg2,
466 TAS2562_TDMConfigurationReg2_RXWLEN32_Mask,
467 TAS2562_TDMConfigurationReg2_RXWLEN32_16Bits);
468 pTAS2562->mnCh_size = 16;
469 if (pTAS2562->mnSlot_width == 0)
470 slot_width_tmp = 16;
471 break;
472 case SNDRV_PCM_FORMAT_S24_LE:
473 pTAS2562->update_bits(pTAS2562,
474 TAS2562_TDMConfigurationReg2,
475 TAS2562_TDMConfigurationReg2_RXWLEN32_Mask,
476 TAS2562_TDMConfigurationReg2_RXWLEN32_24Bits);
477 pTAS2562->mnCh_size = 24;
478 if (pTAS2562->mnSlot_width == 0)
479 slot_width_tmp = 32;
480 break;
481 case SNDRV_PCM_FORMAT_S32_LE:
482 pTAS2562->update_bits(pTAS2562,
483 TAS2562_TDMConfigurationReg2,
484 TAS2562_TDMConfigurationReg2_RXWLEN32_Mask,
485 TAS2562_TDMConfigurationReg2_RXWLEN32_32Bits);
486 pTAS2562->mnCh_size = 32;
487 if (pTAS2562->mnSlot_width == 0)
488 slot_width_tmp = 32;
489 break;
491 default:
492 dev_info(pTAS2562->dev, "Not supported params format\n");
493 }
495 /* If machine driver did not call set slot width */
496 if (pTAS2562->mnSlot_width == 0)
497 tas2562_set_slot(pTAS2562->codec, slot_width_tmp);
499 dev_info(pTAS2562->dev, "mnCh_size: %d\n", pTAS2562->mnCh_size);
500 pTAS2562->mnPCMFormat = bitwidth;
502 return 0;
503 }
505 static int tas2562_set_samplerate(struct tas2562_priv *pTAS2562, int samplerate)
506 {
507 switch (samplerate) {
508 case 48000:
509 pTAS2562->update_bits(pTAS2562,
510 TAS2562_TDMConfigurationReg0,
511 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
512 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
513 pTAS2562->update_bits(pTAS2562,
514 TAS2562_TDMConfigurationReg0,
515 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
516 TAS2562_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
517 break;
518 case 44100:
519 pTAS2562->update_bits(pTAS2562,
520 TAS2562_TDMConfigurationReg0,
521 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
522 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
523 pTAS2562->update_bits(pTAS2562,
524 TAS2562_TDMConfigurationReg0,
525 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
526 TAS2562_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
527 break;
528 case 96000:
529 pTAS2562->update_bits(pTAS2562,
530 TAS2562_TDMConfigurationReg0,
531 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
532 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
533 pTAS2562->update_bits(pTAS2562,
534 TAS2562_TDMConfigurationReg0,
535 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
536 TAS2562_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
537 break;
538 case 88200:
539 pTAS2562->update_bits(pTAS2562,
540 TAS2562_TDMConfigurationReg0,
541 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
542 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
543 pTAS2562->update_bits(pTAS2562,
544 TAS2562_TDMConfigurationReg0,
545 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
546 TAS2562_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
547 break;
548 case 19200:
549 pTAS2562->update_bits(pTAS2562,
550 TAS2562_TDMConfigurationReg0,
551 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
552 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
553 pTAS2562->update_bits(pTAS2562,
554 TAS2562_TDMConfigurationReg0,
555 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
556 TAS2562_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
557 break;
558 case 17640:
559 pTAS2562->update_bits(pTAS2562,
560 TAS2562_TDMConfigurationReg0,
561 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_Mask,
562 TAS2562_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
563 pTAS2562->update_bits(pTAS2562,
564 TAS2562_TDMConfigurationReg0,
565 TAS2562_TDMConfigurationReg0_SAMPRATE31_Mask,
566 TAS2562_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
567 break;
568 default:
569 dev_info(pTAS2562->dev, "%s, unsupported sample rate, %d\n", __func__, samplerate);
571 }
573 pTAS2562->mnSamplingRate = samplerate;
574 return 0;
575 }
576 static int tas2562_mute_ctrl_get(struct snd_kcontrol *pKcontrol,
577 struct snd_ctl_elem_value *pValue)
578 {
579 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
580 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
582 pValue->value.integer.value[0] = pTAS2562->mbMute;
583 dev_dbg(pTAS2562->dev, "tas2562_mute_ctrl_get = %d\n",
584 pTAS2562->mbMute);
586 return 0;
587 }
589 static int tas2562_mute_ctrl_put(struct snd_kcontrol *pKcontrol,
590 struct snd_ctl_elem_value *pValue)
591 {
592 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
593 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
595 mbMute = pValue->value.integer.value[0];
597 dev_dbg(pTAS2562->dev, "tas2562_mute_ctrl_put = %d\n", mbMute);
599 pTAS2562->mbMute = !!mbMute;
601 return 0;
602 }
604 static int tas2562_hw_params(struct snd_pcm_substream *substream,
605 struct snd_pcm_hw_params *params,
606 struct snd_soc_dai *dai)
607 {
608 struct snd_soc_codec *codec = dai->codec;
609 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
610 int blr_clk_ratio;
611 int ret = 0;
613 dev_dbg(pTAS2562->dev, "%s, format: %d\n", __func__,
614 params_format(params));
616 mutex_lock(&pTAS2562->codec_lock);
618 ret = tas2562_set_bitwidth(pTAS2562, params_format(params));
619 if(ret < 0)
620 {
621 dev_info(pTAS2562->dev, "set bitwidth failed, %d\n", ret);
622 goto ret;
623 }
625 blr_clk_ratio = params_channels(params) * pTAS2562->mnCh_size;
626 dev_info(pTAS2562->dev, "blr_clk_ratio: %d\n", blr_clk_ratio);
627 if(blr_clk_ratio != 0)
628 tas2562_slot_config(pTAS2562->codec, pTAS2562, blr_clk_ratio);
630 dev_info(pTAS2562->dev, "%s, sample rate: %d\n", __func__,
631 params_rate(params));
633 ret = tas2562_set_samplerate(pTAS2562, params_rate(params));
635 ret:
636 mutex_unlock(&pTAS2562->codec_lock);
637 return ret;
638 }
640 static int tas2562_set_fmt(struct tas2562_priv *pTAS2562, unsigned int fmt)
641 {
642 u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
643 int ret = 0;
645 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
646 case SND_SOC_DAIFMT_CBS_CFS:
647 asi_cfg_1 = 0x00;
648 break;
649 default:
650 dev_err(pTAS2562->dev, "ASI format master is not found\n");
651 ret = -EINVAL;
652 }
654 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
655 case SND_SOC_DAIFMT_NB_NF:
656 dev_info(pTAS2562->dev, "INV format: NBNF\n");
657 asi_cfg_1 |= TAS2562_TDMConfigurationReg1_RXEDGE_Rising;
658 break;
659 case SND_SOC_DAIFMT_IB_NF:
660 dev_info(pTAS2562->dev, "INV format: IBNF\n");
661 asi_cfg_1 |= TAS2562_TDMConfigurationReg1_RXEDGE_Falling;
662 break;
663 default:
664 dev_err(pTAS2562->dev, "ASI format Inverse is not found\n");
665 ret = -EINVAL;
666 }
668 pTAS2562->update_bits(pTAS2562, TAS2562_TDMConfigurationReg1,
669 TAS2562_TDMConfigurationReg1_RXEDGE_Mask,
670 asi_cfg_1);
672 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
673 case (SND_SOC_DAIFMT_I2S):
674 tdm_rx_start_slot = 1;
675 break;
676 case (SND_SOC_DAIFMT_DSP_A):
677 case (SND_SOC_DAIFMT_DSP_B):
678 tdm_rx_start_slot = 1;
679 break;
680 case (SND_SOC_DAIFMT_LEFT_J):
681 tdm_rx_start_slot = 0;
682 break;
683 default:
684 dev_err(pTAS2562->dev, "DAI Format is not found, fmt=0x%x\n", fmt);
685 ret = -EINVAL;
686 break;
687 }
689 pTAS2562->update_bits(pTAS2562, TAS2562_TDMConfigurationReg1,
690 TAS2562_TDMConfigurationReg1_RXOFFSET51_Mask,
691 (tdm_rx_start_slot << TAS2562_TDMConfigurationReg1_RXOFFSET51_Shift));
693 pTAS2562->mnASIFormat = fmt;
695 return 0;
696 }
698 static int tas2562_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
699 {
700 struct snd_soc_codec *codec = dai->codec;
701 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
702 int ret = 0;
704 dev_dbg(pTAS2562->dev, "%s, format=0x%x\n", __func__, fmt);
706 ret = tas2562_set_fmt(pTAS2562, fmt);
707 return ret;
708 }
710 static int tas2562_set_dai_tdm_slot(struct snd_soc_dai *dai,
711 unsigned int tx_mask, unsigned int rx_mask,
712 int slots, int slot_width)
713 {
714 int ret = 0;
715 struct snd_soc_codec *codec = dai->codec;
716 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
718 dev_dbg(pTAS2562->dev, "%s, tx_mask:%d, rx_mask:%d, slots:%d, slot_width:%d",
719 __func__, tx_mask, rx_mask, slots, slot_width);
721 ret = tas2562_set_slot(codec, slot_width);
723 return ret;
724 }
726 static struct snd_soc_dai_ops tas2562_dai_ops = {
727 .digital_mute = tas2562_mute,
728 .hw_params = tas2562_hw_params,
729 .set_fmt = tas2562_set_dai_fmt,
730 .set_tdm_slot = tas2562_set_dai_tdm_slot,
731 };
733 #define TAS2562_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
734 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
736 #define TAS2562_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 \
737 SNDRV_PCM_RATE_88200 |\
738 SNDRV_PCM_RATE_96000 |\
739 SNDRV_PCM_RATE_176400 |\
740 SNDRV_PCM_RATE_192000\
741 )
743 static struct snd_soc_dai_driver tas2562_dai_driver[] = {
744 {
745 .name = "tas2562 ASI1",
746 .id = 0,
747 .playback = {
748 .stream_name = "ASI1 Playback",
749 .channels_min = 2,
750 .channels_max = 2,
751 .rates = SNDRV_PCM_RATE_8000_192000,
752 .formats = TAS2562_FORMATS,
753 },
754 .capture = {
755 .stream_name = "ASI1 Capture",
756 .channels_min = 0,
757 .channels_max = 2,
758 .rates = SNDRV_PCM_RATE_8000_192000,
759 .formats = TAS2562_FORMATS,
760 },
761 .ops = &tas2562_dai_ops,
762 .symmetric_rates = 1,
763 },
764 };
766 static int tas2562_load_init(struct tas2562_priv *pTAS2562)
767 {
768 int ret;
770 #ifdef TAS2558_CODEC
771 /* Max voltage to 9V */
772 ret = pTAS2562->update_bits(pTAS2562, TAS2562_BoostConfiguration2,
773 TAS2562_BoostConfiguration2_BoostMaxVoltage_Mask,
774 0x7);
775 if(ret < 0)
776 return ret;
778 ret = pTAS2562->update_bits(pTAS2562, TAS2562_PlaybackConfigurationReg0,
779 TAS2562_PlaybackConfigurationReg0_AmplifierLevel51_Mask,
780 0xd << 1);
781 if(ret < 0)
782 return ret;
784 #endif
786 ret = pTAS2562->write(pTAS2562, TAS2562_MiscConfigurationReg0, 0xcf);
787 if(ret < 0)
788 return ret;
789 ret = pTAS2562->write(pTAS2562, TAS2562_TDMConfigurationReg4, 0x01);
790 if(ret < 0)
791 return ret;
792 ret = pTAS2562->write(pTAS2562, TAS2562_ClockConfiguration, 0x0c);
793 if(ret < 0)
794 return ret;
795 ret = tas2562_i2c_load_data(pTAS2562, p_tas2562_classH_D_data);
797 return ret;
798 }
800 static int tas2562_codec_probe(struct snd_soc_codec *codec)
801 {
802 int ret;
803 struct tas2562_priv *pTAS2562 = snd_soc_codec_get_drvdata(codec);
805 ret = snd_soc_add_codec_controls(codec, tas2562_controls,
806 ARRAY_SIZE(tas2562_controls));
807 if (ret < 0) {
808 pr_err("%s: add_codec_controls failed, err %d\n",
809 __func__, ret);
810 return ret;
811 }
813 tas2562_load_init(pTAS2562);
814 tas2562_iv_enable(pTAS2562, 1);
815 pTAS2562->codec = codec;
816 dev_err(pTAS2562->dev, "%s\n", __func__);
818 return 0;
819 }
821 static int tas2562_codec_remove(struct snd_soc_codec *codec)
822 {
823 return 0;
824 }
826 static DECLARE_TLV_DB_SCALE(tas2562_digital_tlv, 1100, 50, 0);
828 static const struct snd_kcontrol_new tas2562_snd_controls[] = {
829 SOC_SINGLE_TLV("Amp Output Level", TAS2562_PlaybackConfigurationReg0,
830 0, 0x16, 0,
831 tas2562_digital_tlv),
832 SOC_SINGLE_EXT("SmartPA Mute", SND_SOC_NOPM, 0, 0x0001, 0,
833 tas2562_mute_ctrl_get, tas2562_mute_ctrl_put),
834 };
836 static struct snd_soc_codec_driver soc_codec_driver_tas2562 = {
837 .probe = tas2562_codec_probe,
838 .remove = tas2562_codec_remove,
839 .read = tas2562_codec_read,
840 .write = tas2562_codec_write,
841 .suspend = tas2562_codec_suspend,
842 .resume = tas2562_codec_resume,
843 .component_driver = {
844 .controls = tas2562_snd_controls,
845 .num_controls = ARRAY_SIZE(tas2562_snd_controls),
846 .dapm_widgets = tas2562_dapm_widgets,
847 .num_dapm_widgets = ARRAY_SIZE(tas2562_dapm_widgets),
848 .dapm_routes = tas2562_audio_map,
849 .num_dapm_routes = ARRAY_SIZE(tas2562_audio_map),
850 },
851 };
853 int tas2562_register_codec(struct tas2562_priv *pTAS2562)
854 {
855 int nResult = 0;
857 dev_info(pTAS2562->dev, "%s, enter\n", __func__);
858 nResult = snd_soc_register_codec(pTAS2562->dev,
859 &soc_codec_driver_tas2562,
860 tas2562_dai_driver, ARRAY_SIZE(tas2562_dai_driver));
861 return nResult;
862 }
864 int tas2562_deregister_codec(struct tas2562_priv *pTAS2562)
865 {
866 snd_soc_unregister_codec(pTAS2562->dev);
868 return 0;
869 }
871 void tas2562_LoadConfig(struct tas2562_priv *pTAS2562)
872 {
873 int ret = 0;
875 if (hrtimer_active(&pTAS2562->mtimer))
876 {
877 dev_info(pTAS2562->dev, "cancel timer\n");
878 hrtimer_cancel(&pTAS2562->mtimer);
879 } else
880 dev_info(pTAS2562->dev, "timer not active\n");
882 pTAS2562->hw_reset(pTAS2562);
883 msleep(2);
884 pTAS2562->write(pTAS2562, TAS2562_SoftwareReset,
885 TAS2562_SoftwareReset_SoftwareReset_Reset);
886 msleep(3);
888 tas2562_load_init(pTAS2562);
889 tas2562_iv_enable(pTAS2562, tas2562iv_enable);
891 ret = tas2562_set_slot(pTAS2562->codec, pTAS2562->mnSlot_width);
892 if (ret < 0)
893 goto end;
895 ret = tas2562_set_fmt(pTAS2562, pTAS2562->mnASIFormat);
896 if (ret < 0)
897 goto end;
899 ret = tas2562_set_bitwidth(pTAS2562, pTAS2562->mnPCMFormat);
900 if (ret < 0)
901 goto end;
903 ret = tas2562_set_samplerate(pTAS2562, pTAS2562->mnSamplingRate);
904 if (ret < 0)
905 goto end;
907 ret = tas2562_set_power_state(pTAS2562, pTAS2562->mnPowerState);
908 if (ret < 0)
909 goto end;
911 end:
912 /* power up failed, restart later */
913 if (ret < 0)
914 schedule_delayed_work(&pTAS2562->irq_work,
915 msecs_to_jiffies(1000));
916 }
918 MODULE_AUTHOR("Texas Instruments Inc.");
919 MODULE_DESCRIPTION("TAS2562 ALSA SOC Smart Amplifier driver");
920 MODULE_LICENSE("GPL v2");
921 #endif /* CONFIG_TAS2562_CODEC */