d32bfd9eb794c42c6b620d98e4d256a64240cd34
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 ** tas2563-codec.c
15 **
16 ** Description:
17 ** ALSA SoC driver for Texas Instruments TAS2563 High Performance 4W Smart
18 ** Amplifier
19 **
20 ** =============================================================================
21 */
23 #ifdef CONFIG_TAS2563_CODEC
24 #define DEBUG
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 <linux/slab.h>
39 #include <linux/syscalls.h>
40 #include <linux/fcntl.h>
41 #include <sound/core.h>
42 #include <sound/pcm.h>
43 #include <sound/pcm_params.h>
44 #include <sound/soc.h>
45 #include <sound/initval.h>
46 #include <sound/tlv.h>
47 #include <linux/crc8.h>
49 #include "tas2563.h"
50 #include "tas2563-codec.h"
52 #define PPC_DRIVER_CRCCHK 0x00000200
53 #define PPC_DRIVER_CONFDEV 0x00000000
54 #define PPC_DRIVER_MTPLLSRC 0x00000400
55 #define PPC_DRIVER_CFGDEV_NONCRC 0x00000101
57 #define TAS2563_CAL_NAME "/data/vendor/pa_cal/tas2563_cal.bin"
58 #define RESTART_MAX 3
60 #define TAS2563_UDELAY 0xFFFFFFFE
61 #define TAS2563_MDELAY 0xFFFFFFFE
62 #define KCONTROL_CODEC
64 #define TAS2563_BLOCK_PLL 0x00
65 #define TAS2563_BLOCK_PGM_ALL 0x0d
66 #define TAS2563_BLOCK_PGM_DEV_A 0x01
67 #define TAS2563_BLOCK_PGM_DEV_B 0x08
68 #define TAS2563_BLOCK_CFG_COEFF_DEV_A 0x03
69 #define TAS2563_BLOCK_CFG_COEFF_DEV_B 0x0a
70 #define TAS2563_BLOCK_CFG_PRE_DEV_A 0x04
71 #define TAS2563_BLOCK_CFG_PRE_DEV_B 0x0b
72 #define TAS2563_BLOCK_CFG_POST 0x05
73 #define TAS2563_BLOCK_CFG_POST_POWER 0x06
75 static char pICN[] = {0x00, 0x01, 0x09, 0x45};
76 static char pICNDelay[] = {0x00, 0x01, 0x00, 0x00};
77 static char const *iv_enable_text[] = {"Off", "On"};
78 static int tas2563iv_enable;
79 static const struct soc_enum tas2563_enum[] = {
80 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(iv_enable_text), iv_enable_text),
81 };
82 static int tas2563_set_fmt(struct tas2563_priv *pTAS2563, unsigned int fmt);
83 static void tas2563_clear_firmware(struct TFirmware *pFirmware);
85 static int fw_parse(struct tas2563_priv *pTAS2563,
86 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize);
87 static bool tas2563_get_coefficient_in_block(struct tas2563_priv *pTAS2563,
88 struct TBlock *pBlock, int nReg, int *pnValue);
89 int tas2563_set_program(struct tas2563_priv *pTAS2563, unsigned int nProgram, int nConfig);
90 static int tas2563_set_calibration(struct tas2563_priv *pTAS2563, int nCalibration);
91 static int tas2563_load_configuration(struct tas2563_priv *pTAS2563,
92 unsigned int nConfiguration, bool bLoadSame);
93 static int tas2563_load_coefficient(struct tas2563_priv *pTAS2563,
94 int nPrevConfig, int nNewConfig, bool bPowerOn);
96 static unsigned int tas2563_codec_read(struct snd_soc_codec *codec,
97 unsigned int reg)
98 {
99 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
100 int nResult = 0;
101 unsigned int value = 0;
103 nResult = pTAS2563->read(pTAS2563, reg, &value);
105 if (nResult < 0)
106 dev_err(pTAS2563->dev, "%s, ERROR, reg=0x%x, E=%d\n",
107 __func__, reg, nResult);
108 else
109 dev_info(pTAS2563->dev, "%s, reg: 0x%x, value: 0x%x\n",
110 __func__, reg, value);
112 if (nResult >= 0)
113 return value;
114 else
115 return nResult;
116 }
118 static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
119 0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
120 0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
121 0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
122 0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
123 0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
124 0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
125 0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
126 0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
127 0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
128 0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
129 0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
130 0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
131 0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
132 0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
133 0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
134 0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
135 };
137 static int isInPageYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
138 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
139 {
140 int nResult = 0;
142 if (nBook == TAS2563_YRAM_BOOK1) {
143 if (nPage == TAS2563_YRAM1_PAGE) {
144 if (nReg >= TAS2563_YRAM1_START_REG) {
145 pCRCData->mnOffset = nReg;
146 pCRCData->mnLen = len;
147 nResult = 1;
148 } else if ((nReg + len) > TAS2563_YRAM1_START_REG) {
149 pCRCData->mnOffset = TAS2563_YRAM1_START_REG;
150 pCRCData->mnLen = len - (TAS2563_YRAM1_START_REG - nReg);
151 nResult = 1;
152 } else
153 nResult = 0;
154 } else if (nPage == TAS2563_YRAM3_PAGE) {
155 if (nReg > TAS2563_YRAM3_END_REG) {
156 nResult = 0;
157 } else if (nReg >= TAS2563_YRAM3_START_REG) {
158 if ((nReg + len) > TAS2563_YRAM3_END_REG) {
159 pCRCData->mnOffset = nReg;
160 pCRCData->mnLen = TAS2563_YRAM3_END_REG - nReg + 1;
161 nResult = 1;
162 } else {
163 pCRCData->mnOffset = nReg;
164 pCRCData->mnLen = len;
165 nResult = 1;
166 }
167 } else {
168 if ((nReg + (len - 1)) < TAS2563_YRAM3_START_REG)
169 nResult = 0;
170 else {
171 pCRCData->mnOffset = TAS2563_YRAM3_START_REG;
172 pCRCData->mnLen = len - (TAS2563_YRAM3_START_REG - nReg);
173 nResult = 1;
174 }
175 }
176 }
177 } else if (nBook == TAS2563_YRAM_BOOK2) {
178 if (nPage == TAS2563_YRAM5_PAGE) {
179 if (nReg > TAS2563_YRAM5_END_REG) {
180 nResult = 0;
181 } else if (nReg >= TAS2563_YRAM5_START_REG) {
182 if ((nReg + len) > TAS2563_YRAM5_END_REG) {
183 pCRCData->mnOffset = nReg;
184 pCRCData->mnLen = TAS2563_YRAM5_END_REG - nReg + 1;
185 nResult = 1;
186 } else {
187 pCRCData->mnOffset = nReg;
188 pCRCData->mnLen = len;
189 nResult = 1;
190 }
191 } else {
192 if ((nReg + (len - 1)) < TAS2563_YRAM5_START_REG)
193 nResult = 0;
194 else {
195 pCRCData->mnOffset = TAS2563_YRAM5_START_REG;
196 pCRCData->mnLen = len - (TAS2563_YRAM5_START_REG - nReg);
197 nResult = 1;
198 }
199 }
200 }
201 } else
202 nResult = 0;
204 return nResult;
205 }
207 static int isInBlockYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
208 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
209 {
210 int nResult;
212 if (nBook == TAS2563_YRAM_BOOK1) {
213 if (nPage < TAS2563_YRAM2_START_PAGE)
214 nResult = 0;
215 else if (nPage <= TAS2563_YRAM2_END_PAGE) {
216 if (nReg > TAS2563_YRAM2_END_REG)
217 nResult = 0;
218 else if (nReg >= TAS2563_YRAM2_START_REG) {
219 pCRCData->mnOffset = nReg;
220 pCRCData->mnLen = len;
221 nResult = 1;
222 } else {
223 if ((nReg + (len - 1)) < TAS2563_YRAM2_START_REG)
224 nResult = 0;
225 else {
226 pCRCData->mnOffset = TAS2563_YRAM2_START_REG;
227 pCRCData->mnLen = nReg + len - TAS2563_YRAM2_START_REG;
228 nResult = 1;
229 }
230 }
231 } else
232 nResult = 0;
233 } else if (nBook == TAS2563_YRAM_BOOK2) {
234 if (nPage < TAS2563_YRAM4_START_PAGE)
235 nResult = 0;
236 else if (nPage <= TAS2563_YRAM4_END_PAGE) {
237 if (nReg > TAS2563_YRAM2_END_REG)
238 nResult = 0;
239 else if (nReg >= TAS2563_YRAM2_START_REG) {
240 pCRCData->mnOffset = nReg;
241 pCRCData->mnLen = len;
242 nResult = 1;
243 } else {
244 if ((nReg + (len - 1)) < TAS2563_YRAM2_START_REG)
245 nResult = 0;
246 else {
247 pCRCData->mnOffset = TAS2563_YRAM2_START_REG;
248 pCRCData->mnLen = nReg + len - TAS2563_YRAM2_START_REG;
249 nResult = 1;
250 }
251 }
252 } else
253 nResult = 0;
254 } else
255 nResult = 0;
257 return nResult;
258 }
261 static int isYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
262 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
263 {
264 int nResult;
266 nResult = isInPageYRAM(pTAS2563, pCRCData, nBook, nPage, nReg, len);
268 if (nResult == 0)
269 nResult = isInBlockYRAM(pTAS2563, pCRCData, nBook, nPage, nReg, len);
271 return nResult;
272 }
274 /*
275 * crc8 - calculate a crc8 over the given input data.
276 *
277 * table: crc table used for calculation.
278 * pdata: pointer to data buffer.
279 * nbytes: number of bytes in data buffer.
280 * crc: previous returned crc8 value.
281 */
282 static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
283 {
284 /* loop over the buffer data */
285 while (nbytes-- > 0)
286 crc = table[(crc ^ *pdata++) & 0xff];
288 return crc;
289 }
291 static int doSingleRegCheckSum(struct tas2563_priv *pTAS2563,
292 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
293 {
294 int nResult = 0;
295 struct TYCRC sCRCData;
296 unsigned int nData1 = 0;
298 if ((nBook == TAS2563_BOOK_ID(TAS2563_SA_COEFF_SWAP_REG))
299 && (nPage == TAS2563_PAGE_ID(TAS2563_SA_COEFF_SWAP_REG))
300 && (nReg >= TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG))
301 && (nReg <= (TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG) + 4))) {
302 /* DSP swap command, pass */
303 nResult = 0;
304 goto end;
305 }
307 nResult = isYRAM(pTAS2563, &sCRCData, nBook, nPage, nReg, 1);
308 if (nResult == 1) {
309 nResult = pTAS2563->read(pTAS2563, TAS2563_REG(nBook, nPage, nReg), &nData1);
310 if (nResult < 0)
311 goto end;
313 if (nData1 != nValue) {
314 dev_err(pTAS2563->dev, "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
315 __LINE__, nBook, nPage, nReg, nValue, nData1);
316 nResult = -EAGAIN;
317 goto end;
318 }
320 nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0);
321 }
323 end:
325 return nResult;
326 }
328 static int doMultiRegCheckSum(struct tas2563_priv *pTAS2563,
329 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
330 {
331 int nResult = 0, i;
332 unsigned char nCRCChkSum = 0;
333 unsigned char nBuf1[128];
334 struct TYCRC TCRCData;
336 return 0;
338 if ((nReg + len-1) > 127) {
339 nResult = -EINVAL;
340 dev_err(pTAS2563->dev, "firmware error\n");
341 goto end;
342 }
344 if ((nBook == TAS2563_BOOK_ID(TAS2563_SA_COEFF_SWAP_REG))
345 && (nPage == TAS2563_PAGE_ID(TAS2563_SA_COEFF_SWAP_REG))
346 && (nReg == TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG))
347 && (len == 4)) {
348 /* DSP swap command, pass */
349 nResult = 0;
350 goto end;
351 }
353 nResult = isYRAM(pTAS2563, &TCRCData, nBook, nPage, nReg, len);
354 dev_info(pTAS2563->dev, "isYRAM: nBook 0x%x, nPage 0x%x, nReg 0x%x\n", nBook, nPage, nReg);
355 dev_info(pTAS2563->dev, "isYRAM: TCRCData.mnLen 0x%x, len 0x%x, nResult %d\n", TCRCData.mnLen, len, nResult);
356 dev_info(pTAS2563->dev, "TCRCData.mnOffset %x\n", TCRCData.mnOffset);
357 if (nResult == 1) {
358 if (len == 1) {
359 dev_err(pTAS2563->dev, "firmware error\n");
360 nResult = -EINVAL;
361 goto end;
362 } else {
363 nResult = pTAS2563->bulk_read(pTAS2563, TAS2563_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
364 if (nResult < 0)
365 goto end;
367 for (i = 0; i < TCRCData.mnLen; i++) {
368 if ((nBook == TAS2563_BOOK_ID(TAS2563_SA_COEFF_SWAP_REG))
369 && (nPage == TAS2563_PAGE_ID(TAS2563_SA_COEFF_SWAP_REG))
370 && ((i + TCRCData.mnOffset)
371 >= TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG))
372 && ((i + TCRCData.mnOffset)
373 <= (TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG) + 4))) {
374 /* DSP swap command, bypass */
375 continue;
376 } else
377 nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf1[i], 1, 0);
378 }
380 nResult = nCRCChkSum;
381 }
382 }
384 end:
386 return nResult;
387 }
390 static int tas2563_load_block(struct tas2563_priv *pTAS2563, struct TBlock *pBlock)
391 {
392 int nResult = 0;
393 unsigned int nCommand = 0;
394 unsigned char nBook;
395 unsigned char nPage;
396 unsigned char nOffset;
397 unsigned char nData;
398 unsigned int nLength;
399 unsigned int nSleep;
400 unsigned char nCRCChkSum = 0;
401 unsigned int nValue;
402 int nRetry = 6;
403 unsigned char *pData = pBlock->mpData;
405 dev_info(pTAS2563->dev, "TAS2563 load block: Type = %d, commands = %d\n",
406 pBlock->mnType, pBlock->mnCommands);
407 start:
408 if (pBlock->mbPChkSumPresent) {
409 nResult = pTAS2563->write(pTAS2563, TAS2563_I2CChecksum, 0);
410 if (nResult < 0)
411 goto end;
412 }
414 if (pBlock->mbYChkSumPresent)
415 nCRCChkSum = 0;
417 nCommand = 0;
419 while (nCommand < pBlock->mnCommands) {
420 pData = pBlock->mpData + nCommand * 4;
422 nBook = pData[0];
423 nPage = pData[1];
424 nOffset = pData[2];
425 nData = pData[3];
427 nCommand++;
429 if (nOffset <= 0x7F) {
430 nResult = pTAS2563->write(pTAS2563, TAS2563_REG(nBook, nPage, nOffset), nData);
431 if (nResult < 0)
432 goto end;
433 if (pBlock->mbYChkSumPresent) {
434 nResult = doSingleRegCheckSum(pTAS2563, nBook, nPage, nOffset, nData);
435 if (nResult < 0)
436 goto check;
437 nCRCChkSum += (unsigned char)nResult;
438 }
439 } else if (nOffset == 0x81) {
440 nSleep = (nBook << 8) + nPage;
441 msleep(nSleep);
442 } else if (nOffset == 0x85) {
443 pData += 4;
444 nLength = (nBook << 8) + nPage;
445 nBook = pData[0];
446 nPage = pData[1];
447 nOffset = pData[2];
448 if (nLength > 1) {
449 nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_REG(nBook, nPage, nOffset), pData + 3, nLength);
450 if (nResult < 0)
451 goto end;
452 if (pBlock->mbYChkSumPresent) {
453 nResult = doMultiRegCheckSum(pTAS2563, nBook, nPage, nOffset, nLength);
454 if (nResult < 0)
455 goto check;
456 nCRCChkSum += (unsigned char)nResult;
457 }
458 } else {
459 nResult = pTAS2563->write(pTAS2563, TAS2563_REG(nBook, nPage, nOffset), pData[3]);
460 if (nResult < 0)
461 goto end;
462 if (pBlock->mbYChkSumPresent) {
463 nResult = doSingleRegCheckSum(pTAS2563, nBook, nPage, nOffset, pData[3]);
464 if (nResult < 0)
465 goto check;
466 nCRCChkSum += (unsigned char)nResult;
467 }
468 }
470 nCommand++;
472 if (nLength >= 2)
473 nCommand += ((nLength - 2) / 4) + 1;
474 }
475 }
476 if (pBlock->mbPChkSumPresent) {
477 nResult = pTAS2563->read(pTAS2563, TAS2563_I2CChecksum, &nValue);
478 dev_err(pTAS2563->dev, "Block PChkSum: FW = 0x%x, Reg = 0x%x\n",
479 pBlock->mnPChkSum, (nValue&0xff));
481 if (nResult < 0)
482 goto end;
483 if ((nValue&0xff) != pBlock->mnPChkSum) {
484 dev_err(pTAS2563->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
485 pBlock->mnPChkSum, (nValue&0xff));
486 nResult = -EAGAIN;
487 pTAS2563->mnErrCode |= ERROR_PRAM_CRCCHK;
488 goto check;
489 }
491 nResult = 0;
492 pTAS2563->mnErrCode &= ~ERROR_PRAM_CRCCHK;
493 dev_info(pTAS2563->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
494 }
496 if (pBlock->mbYChkSumPresent) {
497 //TBD, open it when FW ready
498 dev_err(pTAS2563->dev, "Block YChkSum: FW = 0x%x, YCRC = 0x%x\n",
499 pBlock->mnYChkSum, nCRCChkSum);
500 /*
501 if (nCRCChkSum != pBlock->mnYChkSum) {
502 dev_err(pTAS2563->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
503 pBlock->mnYChkSum, nCRCChkSum);
504 nResult = -EAGAIN;
505 pTAS2563->mnErrCode |= ERROR_YRAM_CRCCHK;
506 goto check;
507 }
508 */
509 pTAS2563->mnErrCode &= ~ERROR_YRAM_CRCCHK;
510 nResult = 0;
511 dev_info(pTAS2563->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
512 }
514 check:
515 if (nResult == -EAGAIN) {
516 nRetry--;
517 if (nRetry > 0)
518 goto start;
519 }
521 end:
522 if (nResult < 0) {
523 dev_err(pTAS2563->dev, "Block (%d) load error\n",
524 pBlock->mnType);
525 }
526 return nResult;
527 }
530 static int tas2563_load_data(struct tas2563_priv *pTAS2563, struct TData *pData, unsigned int nType)
531 {
532 int nResult = 0;
533 unsigned int nBlock;
534 struct TBlock *pBlock;
536 dev_info(pTAS2563->dev,
537 "TAS2563 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
539 for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
540 pBlock = &(pData->mpBlocks[nBlock]);
541 if (pBlock->mnType == nType) {
542 nResult = tas2563_load_block(pTAS2563, pBlock);
543 if (nResult < 0)
544 break;
545 }
546 }
548 return nResult;
549 }
551 void tas2563_clear_firmware(struct TFirmware *pFirmware)
552 {
553 unsigned int n, nn;
555 if (!pFirmware)
556 return;
558 kfree(pFirmware->mpDescription);
560 if (pFirmware->mpPLLs != NULL) {
561 for (n = 0; n < pFirmware->mnPLLs; n++) {
562 kfree(pFirmware->mpPLLs[n].mpDescription);
563 kfree(pFirmware->mpPLLs[n].mBlock.mpData);
564 }
565 kfree(pFirmware->mpPLLs);
566 }
568 if (pFirmware->mpPrograms != NULL) {
569 for (n = 0; n < pFirmware->mnPrograms; n++) {
570 kfree(pFirmware->mpPrograms[n].mpDescription);
571 kfree(pFirmware->mpPrograms[n].mData.mpDescription);
572 for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
573 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
574 kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
575 }
576 kfree(pFirmware->mpPrograms);
577 }
579 if (pFirmware->mpConfigurations != NULL) {
580 for (n = 0; n < pFirmware->mnConfigurations; n++) {
581 kfree(pFirmware->mpConfigurations[n].mpDescription);
582 kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
583 for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
584 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
585 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
586 }
587 kfree(pFirmware->mpConfigurations);
588 }
590 if (pFirmware->mpCalibrations != NULL) {
591 for (n = 0; n < pFirmware->mnCalibrations; n++) {
592 kfree(pFirmware->mpCalibrations[n].mpDescription);
593 kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
594 for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
595 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
596 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
597 }
598 kfree(pFirmware->mpCalibrations);
599 }
601 memset(pFirmware, 0x00, sizeof(struct TFirmware));
602 }
604 static int tas2563_load_configuration(struct tas2563_priv *pTAS2563,
605 unsigned int nConfiguration, bool bLoadSame)
606 {
607 int nResult = 0;
608 struct TConfiguration *pCurrentConfiguration = NULL;
609 struct TConfiguration *pNewConfiguration = NULL;
611 dev_info(pTAS2563->dev, "%s: %d\n", __func__, nConfiguration);
613 if ((!pTAS2563->mpFirmware->mpPrograms) ||
614 (!pTAS2563->mpFirmware->mpConfigurations)) {
615 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n", __func__);
616 nResult = 0;
617 goto end;
618 }
620 if (nConfiguration >= pTAS2563->mpFirmware->mnConfigurations) {
621 dev_err(pTAS2563->dev, "Configuration %d doesn't exist\n",
622 nConfiguration);
623 nResult = 0;
624 goto end;
625 }
627 if ((!pTAS2563->mbLoadConfigurationPrePowerUp)
628 && (nConfiguration == pTAS2563->mnCurrentConfiguration)
629 && (!bLoadSame)) {
630 dev_info(pTAS2563->dev, "Configuration %d is already loaded\n",
631 nConfiguration);
632 nResult = 0;
633 goto end;
634 }
636 pCurrentConfiguration =
637 &(pTAS2563->mpFirmware->mpConfigurations[pTAS2563->mnCurrentConfiguration]);
638 pNewConfiguration =
639 &(pTAS2563->mpFirmware->mpConfigurations[nConfiguration]);
640 if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
641 dev_err(pTAS2563->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
642 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
643 nResult = 0;
644 goto end;
645 }
647 if (pTAS2563->mbPowerUp) {
648 pTAS2563->mbLoadConfigurationPrePowerUp = false;
649 nResult = tas2563_load_coefficient(pTAS2563, pTAS2563->mnCurrentConfiguration, nConfiguration, true);
650 } else {
651 dev_info(pTAS2563->dev,
652 "TAS2563 was powered down, will load coefficient when power up\n");
653 pTAS2563->mbLoadConfigurationPrePowerUp = true;
654 pTAS2563->mnNewConfiguration = nConfiguration;
655 }
657 end:
659 /* if (nResult < 0) {
660 if (pTAS2563->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
661 failsafe(pTAS2563);
662 }
663 */
664 return nResult;
665 }
667 static int tas2563_load_calibration(struct tas2563_priv *pTAS2563, char *pFileName)
668 {
669 int nResult = 0;
671 int nFile;
672 mm_segment_t fs;
673 unsigned char pBuffer[1000];
674 int nSize = 0;
676 dev_info(pTAS2563->dev, "%s:\n", __func__);
678 fs = get_fs();
679 set_fs(KERNEL_DS);
680 nFile = sys_open(pFileName, O_RDONLY, 0);
682 dev_info(pTAS2563->dev, "TAS2563 calibration file = %s, handle = %d\n",
683 pFileName, nFile);
685 if (nFile >= 0) {
686 nSize = sys_read(nFile, pBuffer, 1000);
687 sys_close(nFile);
688 } else {
689 dev_err(pTAS2563->dev, "TAS2563 cannot open calibration file: %s\n",
690 pFileName);
691 }
693 set_fs(fs);
695 if (!nSize)
696 goto end;
698 tas2563_clear_firmware(pTAS2563->mpCalFirmware);
699 dev_info(pTAS2563->dev, "TAS2563 calibration file size = %d\n", nSize);
700 nResult = fw_parse(pTAS2563, pTAS2563->mpCalFirmware, pBuffer, nSize);
702 if (nResult)
703 dev_err(pTAS2563->dev, "TAS2563 calibration file is corrupt\n");
704 else
705 dev_info(pTAS2563->dev, "TAS2563 calibration: %d calibrations\n",
706 pTAS2563->mpCalFirmware->mnCalibrations);
707 end:
709 return nResult;
710 }
713 static int tas2563iv_put(struct snd_kcontrol *kcontrol,
714 struct snd_ctl_elem_value *ucontrol)
715 {
716 #ifdef KCONTROL_CODEC
717 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
718 #else
719 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
720 #endif
722 if (codec == NULL) {
723 pr_err("%s: codec is NULL \n", __func__);
724 return 0;
725 }
727 tas2563iv_enable = ucontrol->value.integer.value[0];
729 if (tas2563iv_enable) {
730 pr_debug("%s: tas2563iv_enable \n", __func__);
731 snd_soc_update_bits(codec, TAS2563_PowerControl,
732 TAS2563_PowerControl_OperationalMode10_Mask |
733 TAS2563_PowerControl_ISNSPower_Mask |
734 TAS2563_PowerControl_VSNSPower_Mask,
735 TAS2563_PowerControl_OperationalMode10_Active |
736 TAS2563_PowerControl_VSNSPower_Active |
737 TAS2563_PowerControl_ISNSPower_Active);
738 } else {
739 pr_debug("%s: tas2563iv_disable \n", __func__);
740 snd_soc_update_bits(codec, TAS2563_PowerControl,
741 TAS2563_PowerControl_OperationalMode10_Mask |
742 TAS2563_PowerControl_ISNSPower_Mask |
743 TAS2563_PowerControl_VSNSPower_Mask,
744 TAS2563_PowerControl_OperationalMode10_Active |
745 TAS2563_PowerControl_VSNSPower_PoweredDown |
746 TAS2563_PowerControl_ISNSPower_PoweredDown);
747 }
749 pr_debug("%s: tas2563iv_enable = %d\n", __func__, tas2563iv_enable);
751 return 0;
752 }
754 static int tas2563iv_get(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
756 {
757 int value;
758 ucontrol->value.integer.value[0] = tas2563iv_enable;
759 value=gpio_get_value(37);
760 pr_debug("%s: tas2563iv_enable = %d\n", __func__, tas2563iv_enable);
761 pr_debug("%s: gpio37 value = %d\n", __func__, value);
762 return 0;
763 }
765 static const struct snd_kcontrol_new tas2563_controls[] = {
766 SOC_ENUM_EXT("TAS2563 IVSENSE ENABLE", tas2563_enum[1],
767 tas2563iv_get, tas2563iv_put),
768 };
770 static int tas2563_codec_write(struct snd_soc_codec *codec, unsigned int reg,
771 unsigned int value)
772 {
773 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
775 int nResult = 0;
777 nResult = pTAS2563->write(pTAS2563, reg, value);
778 if (nResult < 0)
779 dev_err(pTAS2563->dev, "%s, ERROR, reg=0x%x, E=%d\n",
780 __func__, reg, nResult);
781 else
782 dev_info(pTAS2563->dev, "%s, reg: 0x%x, 0x%x\n",
783 __func__, reg, value);
785 return nResult;
787 }
789 static void fw_print_header(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware)
790 {
791 dev_info(pTAS2563->dev, "FW Size = %d", pFirmware->mnFWSize);
792 dev_info(pTAS2563->dev, "Checksum = 0x%04X", pFirmware->mnChecksum);
793 dev_info(pTAS2563->dev, "PPC Version = 0x%04X", pFirmware->mnPPCVersion);
794 dev_info(pTAS2563->dev, "FW Version = 0x%04X", pFirmware->mnFWVersion);
795 dev_info(pTAS2563->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
796 dev_info(pTAS2563->dev, "Timestamp = %d", pFirmware->mnTimeStamp);
797 dev_info(pTAS2563->dev, "DDC Name = %s", pFirmware->mpDDCName);
798 dev_info(pTAS2563->dev, "Description = %s", pFirmware->mpDescription);
799 }
801 inline unsigned int fw_convert_number(unsigned char *pData)
802 {
803 return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
804 }
806 static int fw_parse_header(struct tas2563_priv *pTAS2563,
807 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
808 {
809 unsigned char *pDataStart = pData;
810 unsigned int n;
811 unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
813 if (nSize < 104) {
814 dev_err(pTAS2563->dev, "Firmware: Header too short");
815 return -EINVAL;
816 }
818 if (memcmp(pData, pMagicNumber, 4)) {
819 dev_err(pTAS2563->dev, "Firmware: Magic number doesn't match");
820 return -EINVAL;
821 }
822 pData += 4;
824 pFirmware->mnFWSize = fw_convert_number(pData);
825 pData += 4;
826 dev_info(pTAS2563->dev, "firmware size: %d", pFirmware->mnFWSize);
828 pFirmware->mnChecksum = fw_convert_number(pData);
829 pData += 4;
831 pFirmware->mnPPCVersion = fw_convert_number(pData);
832 pData += 4;
834 pFirmware->mnFWVersion = fw_convert_number(pData);
835 pData += 4;
837 pFirmware->mnDriverVersion = fw_convert_number(pData);
838 pData += 4;
840 pFirmware->mnTimeStamp = fw_convert_number(pData);
841 pData += 4;
842 dev_info(pTAS2563->dev, "FW timestamp: %d", pFirmware->mnTimeStamp);
844 memcpy(pFirmware->mpDDCName, pData, 64);
845 pData += 64;
847 n = strlen(pData);
848 pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
849 pData += n + 1;
850 if ((pData - pDataStart) >= nSize) {
851 dev_err(pTAS2563->dev, "Firmware: Header too short after DDC description");
852 return -EINVAL;
853 }
855 pFirmware->mnDeviceFamily = fw_convert_number(pData);
856 pData += 4;
857 if (pFirmware->mnDeviceFamily != 0) {
858 dev_err(pTAS2563->dev,
859 "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
860 return -EINVAL;
861 }
863 pFirmware->mnDevice = fw_convert_number(pData);
864 pData += 4;
866 if (pFirmware->mnDevice != 5) {
867 dev_err(pTAS2563->dev,
868 "device %d, not TAS2563", pFirmware->mnDevice);
869 return -EINVAL;
870 }
872 fw_print_header(pTAS2563, pFirmware);
873 return pData - pDataStart;
874 }
876 static int fw_parse_block_data(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware,
877 struct TBlock *pBlock, unsigned char *pData)
878 {
879 unsigned char *pDataStart = pData;
880 unsigned int n;
882 dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
884 pBlock->mnType = fw_convert_number(pData);
885 pData += 4;
886 dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
888 if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) {
889 pBlock->mbPChkSumPresent = pData[0];
890 pData++;
892 pBlock->mnPChkSum = pData[0];
893 pData++;
895 pBlock->mbYChkSumPresent = pData[0];
896 pData++;
898 pBlock->mnYChkSum = pData[0];
899 pData++;
900 } else {
901 pBlock->mbPChkSumPresent = 0;
902 pBlock->mbYChkSumPresent = 0;
903 }
905 pBlock->mnCommands = fw_convert_number(pData);
906 pData += 4;
908 n = pBlock->mnCommands * 4;
909 pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
910 pData += n;
911 dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
912 return pData - pDataStart;
913 }
915 static int fw_parse_data(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware,
916 struct TData *pImageData, unsigned char *pData)
917 {
918 unsigned char *pDataStart = pData;
919 unsigned int nBlock;
920 unsigned int n;
922 dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
923 memcpy(pImageData->mpName, pData, 64);
924 pData += 64;
926 n = strlen(pData);
927 pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
928 pData += n + 1;
930 pImageData->mnBlocks = (pData[0] << 8) + pData[1];
931 pData += 2;
933 pImageData->mpBlocks =
934 kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
936 for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
937 n = fw_parse_block_data(pTAS2563, pFirmware,
938 &(pImageData->mpBlocks[nBlock]), pData);
939 pData += n;
940 }
941 return pData - pDataStart;
942 }
944 static int fw_parse_program_data(struct tas2563_priv *pTAS2563,
945 struct TFirmware *pFirmware, unsigned char *pData)
946 {
947 unsigned char *pDataStart = pData;
948 unsigned int n;
949 unsigned int nProgram;
950 struct TProgram *pProgram;
952 pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
953 pData += 2;
955 if (pFirmware->mnPrograms == 0)
956 goto end;
958 pFirmware->mpPrograms =
959 kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
960 for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
961 pProgram = &(pFirmware->mpPrograms[nProgram]);
962 memcpy(pProgram->mpName, pData, 64);
963 pData += 64;
965 n = strlen(pData);
966 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
967 pData += n + 1;
969 pProgram->mnAppMode = pData[0];
970 pData++;
972 /*pProgram->mnBoost = (pData[0] << 8) + pData[1];
973 pData += 2;*/
974 pProgram->mnI2sMode = pData[0];
975 pData++;
976 dev_info(pTAS2563->dev, "FW i2sMode: %d", pProgram->mnI2sMode);
978 pProgram->mnISnsPD = pData[0];
979 pData++;
981 pProgram->mnVSnsPD = pData[0];
982 pData++;
984 pProgram->mnPowerLDG = pData[0];
985 pData++;
987 n = fw_parse_data(pTAS2563, pFirmware, &(pProgram->mData), pData);
988 pData += n;
989 dev_info(pTAS2563->dev, "program data number: %d", n);
990 }
992 end:
994 return pData - pDataStart;
995 }
997 static int fw_parse_configuration_data(struct tas2563_priv *pTAS2563,
998 struct TFirmware *pFirmware, unsigned char *pData)
999 {
1000 unsigned char *pDataStart = pData;
1001 unsigned int n;
1002 unsigned int nConfiguration;
1003 struct TConfiguration *pConfiguration;
1005 pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
1006 pData += 2;
1008 if (pFirmware->mnConfigurations == 0)
1009 goto end;
1011 pFirmware->mpConfigurations =
1012 kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
1013 GFP_KERNEL);
1014 for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
1015 nConfiguration++) {
1016 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
1017 memcpy(pConfiguration->mpName, pData, 64);
1018 pData += 64;
1020 n = strlen(pData);
1021 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1022 pData += n + 1;
1024 /*
1025 if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV)
1026 || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC)
1027 && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) {*/
1028 pConfiguration->mnDevices = (pData[0] << 8) + pData[1];
1029 pData += 2;
1030 /* } else
1031 pConfiguration->mnDevices = 1;*/
1033 pConfiguration->mnProgram = pData[0];
1034 pData++;
1035 dev_info(pTAS2563->dev, "configuration, mnProgram: %d", pConfiguration->mnProgram);
1037 pConfiguration->mnSamplingRate = fw_convert_number(pData);
1038 pData += 4;
1039 dev_info(pTAS2563->dev, "configuration samplerate: %d", pConfiguration->mnSamplingRate);
1041 //if (pFirmware->mnDriverVersion >= PPC_DRIVER_MTPLLSRC) {
1042 pConfiguration->mnPLLSrc = pData[0];
1043 pData++;
1045 pConfiguration->mnPLLSrcRate = fw_convert_number(pData);
1046 pData += 4;
1047 //}
1049 pConfiguration->mnFsRate = (pData[0] << 8) + pData[1];
1050 pData += 2;
1051 dev_info(pTAS2563->dev, "Fs rate: %d", pConfiguration->mnFsRate);
1053 n = fw_parse_data(pTAS2563, pFirmware, &(pConfiguration->mData), pData);
1054 pData += n;
1055 }
1057 end:
1059 return pData - pDataStart;
1060 }
1062 int fw_parse_calibration_data(struct tas2563_priv *pTAS2563,
1063 struct TFirmware *pFirmware, unsigned char *pData)
1064 {
1065 unsigned char *pDataStart = pData;
1066 unsigned int n;
1067 unsigned int nCalibration;
1068 struct TCalibration *pCalibration;
1070 pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
1071 pData += 2;
1073 if (pFirmware->mnCalibrations == 0)
1074 goto end;
1076 pFirmware->mpCalibrations =
1077 kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
1078 for (nCalibration = 0;
1079 nCalibration < pFirmware->mnCalibrations;
1080 nCalibration++) {
1081 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
1082 memcpy(pCalibration->mpName, pData, 64);
1083 pData += 64;
1085 n = strlen(pData);
1086 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1087 pData += n + 1;
1089 pCalibration->mnProgram = pData[0];
1090 pData++;
1092 pCalibration->mnConfiguration = pData[0];
1093 pData++;
1095 n = fw_parse_data(pTAS2563, pFirmware, &(pCalibration->mData), pData);
1096 pData += n;
1097 }
1099 end:
1101 return pData - pDataStart;
1102 }
1104 static int fw_parse(struct tas2563_priv *pTAS2563,
1105 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
1106 {
1107 int nPosition = 0;
1109 nPosition = fw_parse_header(pTAS2563, pFirmware, pData, nSize);
1110 dev_info(pTAS2563->dev, "header size: %d, line: %d\n", nPosition, __LINE__);
1111 if (nPosition < 0) {
1112 dev_err(pTAS2563->dev, "Firmware: Wrong Header");
1113 return -EINVAL;
1114 }
1116 if (nPosition >= nSize) {
1117 dev_err(pTAS2563->dev, "Firmware: Too short");
1118 return -EINVAL;
1119 }
1121 pData += nPosition;
1122 nSize -= nPosition;
1123 nPosition = 0;
1125 nPosition = fw_parse_program_data(pTAS2563, pFirmware, pData);
1126 dev_info(pTAS2563->dev, "program size: %d, line: %d\n", nPosition, __LINE__);
1128 pData += nPosition;
1129 nSize -= nPosition;
1130 nPosition = 0;
1132 nPosition = fw_parse_configuration_data(pTAS2563, pFirmware, pData);
1133 dev_info(pTAS2563->dev, "config size: %d, line: %d\n", nPosition, __LINE__);
1135 pData += nPosition;
1136 nSize -= nPosition;
1137 nPosition = 0;
1139 if (nSize > 64)
1140 nPosition = fw_parse_calibration_data(pTAS2563, pFirmware, pData);
1141 dev_info(pTAS2563->dev, "calib size: %d, line: %d\n", nPosition, __LINE__);
1142 return 0;
1143 }
1146 static int tas2563_codec_suspend(struct snd_soc_codec *codec)
1147 {
1148 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1149 int ret = 0;
1151 mutex_lock(&pTAS2563->codec_lock);
1153 dev_info(pTAS2563->dev, "%s\n", __func__);
1154 pTAS2563->runtime_suspend(pTAS2563);
1156 mutex_unlock(&pTAS2563->codec_lock);
1157 return ret;
1158 }
1160 static int tas2563_codec_resume(struct snd_soc_codec *codec)
1161 {
1162 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1163 int ret = 0;
1165 mutex_lock(&pTAS2563->codec_lock);
1167 dev_info(pTAS2563->dev, "%s\n", __func__);
1168 pTAS2563->runtime_resume(pTAS2563);
1170 mutex_unlock(&pTAS2563->codec_lock);
1171 return ret;
1172 }
1174 static const struct snd_kcontrol_new tas2563_asi_controls[] = {
1175 SOC_DAPM_SINGLE("Left", TAS2563_TDMConfigurationReg2,
1176 4, 1, 0),
1177 SOC_DAPM_SINGLE("Right", TAS2563_TDMConfigurationReg2,
1178 4, 2, 0),
1179 SOC_DAPM_SINGLE("LeftRightDiv2", TAS2563_TDMConfigurationReg2,
1180 4, 3, 0),
1181 };
1183 static int tas2563_set_power_state(struct tas2563_priv *pTAS2563, int state)
1184 {
1185 int nResult = 0;
1186 /*unsigned int nValue;*/
1187 const char *pFWName;
1188 struct TProgram *pProgram;
1190 dev_info(pTAS2563->dev, "set power state: %d\n", state);
1192 if ((pTAS2563->mpFirmware->mnPrograms == 0)
1193 || (pTAS2563->mpFirmware->mnConfigurations == 0)) {
1194 dev_err(pTAS2563->dev, "%s, firmware not loaded\n", __func__);
1195 pFWName = TAS2563_FW_NAME;
1196 nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName,
1197 pTAS2563->dev, GFP_KERNEL, pTAS2563, tas2563_fw_ready);
1199 if(nResult < 0) {
1200 dev_err(pTAS2563->dev, "%s, firmware is loaded, %d\n", __func__, nResult);
1201 goto end;
1202 }
1203 }
1204 /* check safe guard*/
1205 /* TBD, add back when FW ready
1206 nResult = pTAS2563->read(pTAS2563, TAS2563_SAFE_GUARD_REG, &nValue);
1207 if (nResult < 0)
1208 goto end;
1209 if ((nValue&0xff) != TAS2563_SAFE_GUARD_PATTERN) {
1210 dev_err(pTAS2563->dev, "ERROR safe guard failure!\n");
1211 nResult = -EPIPE;
1212 goto end;
1213 }
1214 */
1216 pProgram = &(pTAS2563->mpFirmware->mpPrograms[pTAS2563->mnCurrentProgram]);
1217 dev_info(pTAS2563->dev, "%s, state: %d, mbPowerup %d\n", __func__, state, pTAS2563->mbPowerUp);
1218 if (state != TAS2563_POWER_SHUTDOWN) {
1219 if (!pTAS2563->mbPowerUp) {
1220 if (!pTAS2563->mbCalibrationLoaded) {
1221 nResult = tas2563_set_calibration(pTAS2563, 0xFF);
1222 if((nResult > 0) || (nResult == 0))
1223 pTAS2563->mbCalibrationLoaded = true;
1224 }
1226 if (pTAS2563->mbLoadConfigurationPrePowerUp) {
1227 dev_info(pTAS2563->dev, "load coefficient before power\n");
1228 pTAS2563->mbLoadConfigurationPrePowerUp = false;
1229 nResult = tas2563_load_coefficient(pTAS2563,
1230 pTAS2563->mnCurrentConfiguration, pTAS2563->mnNewConfiguration, false);
1231 if (nResult < 0)
1232 goto end;
1233 }
1234 }
1235 }
1237 switch (state) {
1238 case TAS2563_POWER_ACTIVE:
1239 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1240 TAS2563_PowerControl_OperationalMode10_Mask |
1241 TAS2563_PowerControl_ISNSPower_Mask |
1242 TAS2563_PowerControl_VSNSPower_Mask,
1243 TAS2563_PowerControl_OperationalMode10_Active |
1244 TAS2563_PowerControl_VSNSPower_Active |
1245 TAS2563_PowerControl_ISNSPower_Active);
1246 if (nResult < 0)
1247 return nResult;
1248 pTAS2563->mbPowerUp = true;
1249 dev_info(pTAS2563->dev, "set ICN to -90dB\n");
1250 nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_ICN_REG, pICN, 4);
1251 if(nResult < 0)
1252 return nResult;
1254 dev_info(pTAS2563->dev, "set ICN delay\n");
1255 nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_ICN_DELAY, pICNDelay, 4);
1256 break;
1258 case TAS2563_POWER_MUTE:
1259 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1260 TAS2563_PowerControl_OperationalMode10_Mask |
1261 TAS2563_PowerControl_ISNSPower_Mask |
1262 TAS2563_PowerControl_VSNSPower_Mask,
1263 TAS2563_PowerControl_OperationalMode10_Mute |
1264 TAS2563_PowerControl_VSNSPower_Active |
1265 TAS2563_PowerControl_ISNSPower_Active);
1266 pTAS2563->mbPowerUp = true;
1267 break;
1269 case TAS2563_POWER_SHUTDOWN:
1270 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1271 TAS2563_PowerControl_OperationalMode10_Mask,
1272 TAS2563_PowerControl_OperationalMode10_Shutdown);
1273 pTAS2563->mbPowerUp = false;
1274 break;
1276 default:
1277 dev_err(pTAS2563->dev, "wrong power state setting %d\n", state);
1279 }
1281 end:
1282 pTAS2563->mnPowerState = state;
1283 return nResult;
1284 }
1286 static int tas2563_dac_event(struct snd_soc_dapm_widget *w,
1287 struct snd_kcontrol *kcontrol, int event)
1288 {
1289 #ifdef KCONTROL_CODEC
1290 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1291 #else
1292 struct snd_soc_codec *codec = w->codec;
1293 #endif
1294 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1296 switch (event) {
1297 case SND_SOC_DAPM_POST_PMU:
1298 tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
1299 break;
1300 case SND_SOC_DAPM_PRE_PMD:
1301 tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1302 break;
1304 }
1305 return 0;
1307 }
1309 static const struct snd_soc_dapm_widget tas2563_dapm_widgets[] = {
1310 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
1311 SND_SOC_DAPM_AIF_OUT("Voltage Sense", "ASI1 Capture", 1, TAS2563_PowerControl, 2, 1),
1312 SND_SOC_DAPM_AIF_OUT("Current Sense", "ASI1 Capture", 0, TAS2563_PowerControl, 3, 1),
1313 SND_SOC_DAPM_MIXER("ASI1 Sel",
1314 TAS2563_TDMConfigurationReg2, 4, 0,
1315 &tas2563_asi_controls[0],
1316 ARRAY_SIZE(tas2563_asi_controls)),
1317 SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2563_dac_event,
1318 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1319 SND_SOC_DAPM_OUTPUT("OUT"),
1320 SND_SOC_DAPM_SIGGEN("VMON"),
1321 SND_SOC_DAPM_SIGGEN("IMON")
1322 };
1324 static const struct snd_soc_dapm_route tas2563_audio_map[] = {
1325 {"ASI1 Sel", "Left", "ASI1"},
1326 {"ASI1 Sel", "Right", "ASI1"},
1327 {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
1328 {"DAC", NULL, "ASI1 Sel"},
1329 {"OUT", NULL, "DAC"},
1330 /*{"VMON", NULL, "Voltage Sense"},
1331 {"IMON", NULL, "Current Sense"},*/
1332 {"Voltage Sense", NULL, "VMON"},
1333 {"Current Sense", NULL, "IMON"},
1334 };
1337 static int tas2563_mute(struct snd_soc_dai *dai, int mute)
1338 {
1339 struct snd_soc_codec *codec = dai->codec;
1340 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1342 dev_info(pTAS2563->dev, "%s\n", __func__);
1343 mutex_lock(&pTAS2563->codec_lock);
1344 if (mute) {
1345 dev_info(pTAS2563->dev, "mute: %s\n", __func__);
1346 tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1347 } else {
1348 dev_info(pTAS2563->dev, "unmute: %s\n", __func__);
1349 tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
1350 }
1351 mutex_unlock(&pTAS2563->codec_lock);
1352 return 0;
1353 }
1356 static int tas2563_slot_config(struct snd_soc_codec *codec, struct tas2563_priv *pTAS2563, int blr_clk_ratio)
1357 {
1358 int ret = 0;
1359 pTAS2563->update_bits(pTAS2563,
1360 TAS2563_TDMConfigurationReg5, 0xff, 0x42);
1362 pTAS2563->update_bits(pTAS2563,
1363 TAS2563_TDMConfigurationReg6, 0xff, 0x40);
1365 return ret;
1366 }
1368 static int tas2563_set_slot(struct tas2563_priv *pTAS2563, int slot_width)
1369 {
1370 int ret = 0;
1371 dev_info(pTAS2563->dev, "%s, slot_width:%d\n", __func__, slot_width);
1373 switch (slot_width) {
1374 case 16:
1375 ret = pTAS2563->update_bits(pTAS2563,
1376 TAS2563_TDMConfigurationReg2,
1377 TAS2563_TDMConfigurationReg2_RXSLEN10_Mask,
1378 TAS2563_TDMConfigurationReg2_RXSLEN10_16Bits);
1379 break;
1381 case 24:
1382 ret = pTAS2563->update_bits(pTAS2563,
1383 TAS2563_TDMConfigurationReg2,
1384 TAS2563_TDMConfigurationReg2_RXSLEN10_Mask,
1385 TAS2563_TDMConfigurationReg2_RXSLEN10_24Bits);
1386 break;
1388 case 32:
1389 ret = pTAS2563->update_bits(pTAS2563,
1390 TAS2563_TDMConfigurationReg2,
1391 TAS2563_TDMConfigurationReg2_RXSLEN10_Mask,
1392 TAS2563_TDMConfigurationReg2_RXSLEN10_32Bits);
1393 break;
1395 case 0:
1396 /* Do not change slot width */
1397 break;
1399 default:
1400 dev_info(pTAS2563->dev, "slot width not supported");
1401 ret = -EINVAL;
1402 }
1404 if (ret >= 0)
1405 pTAS2563->mnSlot_width = slot_width;
1407 return ret;
1408 }
1410 static int tas2563_set_bitwidth(struct tas2563_priv *pTAS2563, int bitwidth)
1411 {
1412 int slot_width_tmp = 0;
1413 dev_info(pTAS2563->dev, "%s %d\n", __func__, __LINE__);
1415 switch (bitwidth) {
1416 case SNDRV_PCM_FORMAT_S16_LE:
1417 pTAS2563->update_bits(pTAS2563,
1418 TAS2563_TDMConfigurationReg2,
1419 TAS2563_TDMConfigurationReg2_RXWLEN32_Mask,
1420 TAS2563_TDMConfigurationReg2_RXWLEN32_16Bits);
1421 pTAS2563->mnCh_size = 16;
1422 if (pTAS2563->mnSlot_width == 0)
1423 slot_width_tmp = 16;
1424 break;
1425 case SNDRV_PCM_FORMAT_S24_LE:
1426 pTAS2563->update_bits(pTAS2563,
1427 TAS2563_TDMConfigurationReg2,
1428 TAS2563_TDMConfigurationReg2_RXWLEN32_Mask,
1429 TAS2563_TDMConfigurationReg2_RXWLEN32_24Bits);
1430 pTAS2563->mnCh_size = 24;
1431 if (pTAS2563->mnSlot_width == 0)
1432 slot_width_tmp = 32;
1433 break;
1434 case SNDRV_PCM_FORMAT_S32_LE:
1435 pTAS2563->update_bits(pTAS2563,
1436 TAS2563_TDMConfigurationReg2,
1437 TAS2563_TDMConfigurationReg2_RXWLEN32_Mask,
1438 TAS2563_TDMConfigurationReg2_RXWLEN32_32Bits);
1439 pTAS2563->mnCh_size = 32;
1440 if (pTAS2563->mnSlot_width == 0)
1441 slot_width_tmp = 32;
1442 break;
1444 default:
1445 dev_info(pTAS2563->dev, "Not supported params format\n");
1446 }
1448 /* If machine driver did not call set slot width */
1449 if (pTAS2563->mnSlot_width == 0)
1450 tas2563_set_slot(pTAS2563, slot_width_tmp);
1452 dev_info(pTAS2563->dev, "mnCh_size: %d\n", pTAS2563->mnCh_size);
1453 pTAS2563->mnPCMFormat = bitwidth;
1455 return 0;
1456 }
1458 static int tas2563_set_samplerate(struct tas2563_priv *pTAS2563, int samplerate)
1459 {
1460 switch (samplerate) {
1461 case 48000:
1462 pTAS2563->update_bits(pTAS2563,
1463 TAS2563_TDMConfigurationReg0,
1464 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1465 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
1466 pTAS2563->update_bits(pTAS2563,
1467 TAS2563_TDMConfigurationReg0,
1468 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1469 TAS2563_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
1470 break;
1471 case 44100:
1472 pTAS2563->update_bits(pTAS2563,
1473 TAS2563_TDMConfigurationReg0,
1474 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1475 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
1476 pTAS2563->update_bits(pTAS2563,
1477 TAS2563_TDMConfigurationReg0,
1478 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1479 TAS2563_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
1480 break;
1481 case 96000:
1482 pTAS2563->update_bits(pTAS2563,
1483 TAS2563_TDMConfigurationReg0,
1484 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1485 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
1486 pTAS2563->update_bits(pTAS2563,
1487 TAS2563_TDMConfigurationReg0,
1488 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1489 TAS2563_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
1490 break;
1491 case 88200:
1492 pTAS2563->update_bits(pTAS2563,
1493 TAS2563_TDMConfigurationReg0,
1494 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1495 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
1496 pTAS2563->update_bits(pTAS2563,
1497 TAS2563_TDMConfigurationReg0,
1498 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1499 TAS2563_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
1500 break;
1501 case 19200:
1502 pTAS2563->update_bits(pTAS2563,
1503 TAS2563_TDMConfigurationReg0,
1504 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1505 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
1506 pTAS2563->update_bits(pTAS2563,
1507 TAS2563_TDMConfigurationReg0,
1508 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1509 TAS2563_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
1510 break;
1511 case 17640:
1512 pTAS2563->update_bits(pTAS2563,
1513 TAS2563_TDMConfigurationReg0,
1514 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1515 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
1516 pTAS2563->update_bits(pTAS2563,
1517 TAS2563_TDMConfigurationReg0,
1518 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1519 TAS2563_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
1520 break;
1521 default:
1522 dev_info(pTAS2563->dev, "%s, unsupported sample rate, %d\n", __func__, samplerate);
1524 }
1526 pTAS2563->mnSamplingRate = samplerate;
1527 return 0;
1528 }
1530 int tas2563_load_default(struct tas2563_priv *pTAS2563)
1531 {
1532 int ret = 0;
1534 dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1536 ret = tas2563_set_slot(pTAS2563, pTAS2563->mnSlot_width);
1537 if (ret < 0)
1538 goto end;
1539 dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1541 /* proper TX format */
1542 ret = pTAS2563->write(pTAS2563, TAS2563_TDMConfigurationReg4, 0x01);
1543 if(ret < 0)
1544 goto end;
1546 /*if setting format was not called by asoc, then set it default*/
1547 if(pTAS2563->mnASIFormat == 0)
1548 pTAS2563->mnASIFormat = SND_SOC_DAIFMT_CBS_CFS
1549 | SND_SOC_DAIFMT_IB_NF
1550 | SND_SOC_DAIFMT_I2S;
1551 ret = tas2563_set_fmt(pTAS2563, pTAS2563->mnASIFormat);
1553 if (ret < 0)
1554 goto end;
1555 dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1557 ret = tas2563_set_bitwidth(pTAS2563, pTAS2563->mnPCMFormat);
1558 if (ret < 0)
1559 goto end;
1560 dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1562 ret = tas2563_set_samplerate(pTAS2563, pTAS2563->mnSamplingRate);
1563 if (ret < 0)
1564 goto end;
1566 end:
1567 /* power up failed, restart later */
1568 dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1569 if (ret < 0)
1570 schedule_delayed_work(&pTAS2563->irq_work,
1571 msecs_to_jiffies(1000));
1572 return ret;
1573 }
1575 #if 0
1576 static void failsafe(struct tas2563_priv *pTAS2563)
1577 {
1578 dev_err(pTAS2563->dev, "%s\n", __func__);
1579 pTAS2563->mnErrCode |= ERROR_FAILSAFE;
1580 if (hrtimer_active(&pTAS2563->mtimerwork))
1581 hrtimer_cancel(&pTAS2563->mtimerwork);
1583 if(pTAS2563->mnRestart < RESTART_MAX)
1584 {
1585 pTAS2563->mnRestart ++;
1586 msleep(100);
1587 dev_err(pTAS2563->dev, "I2C COMM error, restart SmartAmp.\n");
1588 schedule_delayed_work(&pTAS2563->irq_work, msecs_to_jiffies(100));
1589 return;
1590 }
1591 pTAS2563->enableIRQ(pTAS2563, false);
1592 tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1594 pTAS2563->mbPowerUp = false;
1595 pTAS2563->hw_reset(pTAS2563);
1596 pTAS2563->write(pTAS2563, TAS2563_SoftwareReset, TAS2563_SoftwareReset_SoftwareReset_Reset);
1597 udelay(1000);
1598 if (pTAS2563->mpFirmware != NULL)
1599 tas2563_clear_firmware(pTAS2563->mpFirmware);
1600 }
1601 #endif
1603 /*
1604 * tas2563_load_coefficient
1605 */
1606 static int tas2563_load_coefficient(struct tas2563_priv *pTAS2563,
1607 int nPrevConfig, int nNewConfig, bool bPowerOn)
1608 {
1609 int nResult = 0;
1610 // struct TPLL *pPLL;
1611 struct TProgram *pProgram;
1612 struct TConfiguration *pPrevConfiguration;
1613 struct TConfiguration *pNewConfiguration;
1614 bool bRestorePower = false;
1616 if (!pTAS2563->mpFirmware->mnConfigurations) {
1617 dev_err(pTAS2563->dev, "%s, firmware not loaded\n", __func__);
1618 goto end;
1619 }
1621 if (nNewConfig >= pTAS2563->mpFirmware->mnConfigurations) {
1622 dev_err(pTAS2563->dev, "%s, invalid configuration New=%d, total=%d\n",
1623 __func__, nNewConfig, pTAS2563->mpFirmware->mnConfigurations);
1624 goto end;
1625 }
1627 if (nPrevConfig < 0)
1628 pPrevConfiguration = NULL;
1629 else if (nPrevConfig == nNewConfig) {
1630 dev_info(pTAS2563->dev, "%s, config [%d] already loaded\n",
1631 __func__, nNewConfig);
1632 goto end;
1633 } else
1634 pPrevConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[nPrevConfig]);
1636 pNewConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[nNewConfig]);
1637 pTAS2563->mnCurrentConfiguration = nNewConfig;
1638 #if 0
1639 if (pPrevConfiguration) {
1640 if (pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL) {
1641 dev_info(pTAS2563->dev, "%s, PLL same\n", __func__);
1642 goto prog_coefficient;
1643 }
1644 }
1646 pProgram = &(pTAS2563->mpFirmware->mpPrograms[pTAS2563->mnCurrentProgram]);
1647 if (bPowerOn) {
1648 dev_info(pTAS2563->dev, "%s, power down to load new PLL\n", __func__);
1649 if (hrtimer_active(&pTAS2563->mtimerwork))
1650 hrtimer_cancel(&pTAS2563->mtimerwork);
1652 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE)
1653 pTAS2563->enableIRQ(pTAS2563, false);
1655 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1656 if (nResult < 0)
1657 goto end;
1658 bRestorePower = true;
1659 }
1661 /* load PLL */
1662 pPLL = &(pTAS2563->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
1663 dev_info(pTAS2563->dev, "load PLL: %s block for Configuration %s\n",
1664 pPLL->mpName, pNewConfiguration->mpName);
1665 nResult = tas2563_load_block(pTAS2563, &(pPLL->mBlock));
1666 if (nResult < 0)
1667 goto end;
1668 #endif
1669 pTAS2563->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
1671 dev_info(pTAS2563->dev, "load configuration %s conefficient pre block\n",
1672 pNewConfiguration->mpName);
1673 nResult = tas2563_load_data(pTAS2563, &(pNewConfiguration->mData), TAS2563_BLOCK_CFG_PRE_DEV_A);
1674 if (nResult < 0)
1675 goto end;
1677 //prog_coefficient:
1678 dev_info(pTAS2563->dev, "load new configuration: %s, coeff block data\n",
1679 pNewConfiguration->mpName);
1680 nResult = tas2563_load_data(pTAS2563, &(pNewConfiguration->mData),
1681 TAS2563_BLOCK_CFG_COEFF_DEV_A);
1682 if (nResult < 0)
1683 goto end;
1685 if (pTAS2563->mpCalFirmware->mnCalibrations) {
1686 nResult = tas2563_set_calibration(pTAS2563, pTAS2563->mnCurrentCalibration);
1687 if (nResult < 0)
1688 goto end;
1689 }
1691 if (bRestorePower) {
1692 pTAS2563->clearIRQ(pTAS2563);
1693 dev_info(pTAS2563->dev, "device powered up, load startup\n");
1694 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_MUTE);
1695 if (nResult < 0)
1696 goto end;
1698 dev_info(pTAS2563->dev,
1699 "device powered up, load unmute\n");
1700 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
1701 if (nResult < 0)
1702 goto end;
1703 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1704 pTAS2563->enableIRQ(pTAS2563, true);
1705 if (!hrtimer_active(&pTAS2563->mtimerwork)) {
1706 pTAS2563->mnDieTvReadCounter = 0;
1707 hrtimer_start(&pTAS2563->mtimerwork,
1708 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1709 }
1710 }
1711 }
1712 end:
1714 pTAS2563->mnNewConfiguration = pTAS2563->mnCurrentConfiguration;
1715 return nResult;
1716 }
1718 static bool tas2563_get_coefficient_in_data(struct tas2563_priv *pTAS2563,
1719 struct TData *pData, int blockType, int nReg, int *pnValue)
1720 {
1721 bool bFound = false;
1722 struct TBlock *pBlock;
1723 int i;
1725 for (i = 0; i < pData->mnBlocks; i++) {
1726 pBlock = &(pData->mpBlocks[i]);
1727 if (pBlock->mnType == blockType) {
1728 bFound = tas2563_get_coefficient_in_block(pTAS2563,
1729 pBlock, nReg, pnValue);
1730 if (bFound)
1731 break;
1732 }
1733 }
1735 return bFound;
1736 }
1738 static bool tas2563_find_Tmax_in_configuration(struct tas2563_priv *pTAS2563,
1739 struct TConfiguration *pConfiguration, int *pnTMax)
1740 {
1741 struct TData *pData;
1742 bool bFound = false;
1743 int nBlockType, nReg, nCoefficient;
1745 nReg = TAS2563_CALI_T_REG;
1747 nBlockType = TAS2563_BLOCK_CFG_COEFF_DEV_A;
1749 pData = &(pConfiguration->mData);
1750 bFound = tas2563_get_coefficient_in_data(pTAS2563, pData, nBlockType, nReg, &nCoefficient);
1751 if (bFound)
1752 *pnTMax = nCoefficient;
1754 return bFound;
1755 }
1757 void tas2563_fw_ready(const struct firmware *pFW, void *pContext)
1758 {
1759 struct tas2563_priv *pTAS2563 = (struct tas2563_priv *) pContext;
1760 int nResult;
1761 unsigned int nProgram = 0;
1762 unsigned int nSampleRate = 0;
1764 #ifdef CONFIG_TAS2563_CODEC
1765 mutex_lock(&pTAS2563->codec_lock);
1766 #endif
1768 #ifdef CONFIG_TAS2563_MISC
1769 mutex_lock(&pTAS2563->file_lock);
1770 #endif
1772 dev_info(pTAS2563->dev, "%s:\n", __func__);
1774 if (unlikely(!pFW) || unlikely(!pFW->data)) {
1775 dev_err(pTAS2563->dev, "%s firmware is not loaded.\n",
1776 TAS2563_FW_NAME);
1777 goto end;
1778 }
1780 if (pTAS2563->mpFirmware->mpConfigurations) {
1781 nProgram = pTAS2563->mnCurrentProgram;
1782 nSampleRate = pTAS2563->mnCurrentSampleRate;
1783 dev_info(pTAS2563->dev, "clear current firmware\n");
1784 tas2563_clear_firmware(pTAS2563->mpFirmware);
1785 }
1787 nResult = fw_parse(pTAS2563, pTAS2563->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
1788 release_firmware(pFW);
1789 if (nResult < 0) {
1790 dev_err(pTAS2563->dev, "firmware is corrupt\n");
1791 goto end;
1792 }
1794 if (!pTAS2563->mpFirmware->mnPrograms) {
1795 dev_err(pTAS2563->dev, "firmware contains no programs\n");
1796 nResult = -EINVAL;
1797 goto end;
1798 }
1800 if (!pTAS2563->mpFirmware->mnConfigurations) {
1801 dev_err(pTAS2563->dev, "firmware contains no configurations\n");
1802 nResult = -EINVAL;
1803 goto end;
1804 }
1806 if (nProgram >= pTAS2563->mpFirmware->mnPrograms) {
1807 dev_info(pTAS2563->dev,
1808 "no previous program, set to default\n");
1809 nProgram = 0;
1810 }
1812 pTAS2563->mnCurrentSampleRate = nSampleRate;
1813 nResult = tas2563_set_program(pTAS2563, nProgram, -1);
1815 end:
1817 #ifdef CONFIG_TAS2563_CODEC
1818 mutex_unlock(&pTAS2563->codec_lock);
1819 #endif
1821 #ifdef CONFIG_TAS2563_MISC
1822 mutex_unlock(&pTAS2563->file_lock);
1823 #endif
1824 }
1826 static bool tas2563_get_coefficient_in_block(struct tas2563_priv *pTAS2563,
1827 struct TBlock *pBlock, int nReg, int *pnValue)
1828 {
1829 int nCoefficient = 0;
1830 bool bFound = false;
1831 unsigned char *pCommands;
1832 int nBook, nPage, nOffset, len;
1833 int i, n;
1835 pCommands = pBlock->mpData;
1836 for (i = 0 ; i < pBlock->mnCommands;) {
1837 nBook = pCommands[4 * i + 0];
1838 nPage = pCommands[4 * i + 1];
1839 nOffset = pCommands[4 * i + 2];
1840 if ((nOffset < 0x7f) || (nOffset == 0x81))
1841 i++;
1842 else if (nOffset == 0x85) {
1843 len = ((int)nBook << 8) | nPage;
1844 nBook = pCommands[4 * i + 4];
1845 nPage = pCommands[4 * i + 5];
1846 nOffset = pCommands[4 * i + 6];
1847 n = 4 * i + 7;
1848 i += 2;
1849 i += ((len - 1) / 4);
1850 if ((len - 1) % 4)
1851 i++;
1852 if ((nBook != TAS2563_BOOK_ID(nReg))
1853 || (nPage != TAS2563_PAGE_ID(nReg)))
1854 continue;
1855 if (nOffset > TAS2563_PAGE_REG(nReg))
1856 continue;
1857 if ((len + nOffset) >= (TAS2563_PAGE_REG(nReg) + 4)) {
1858 n += (TAS2563_PAGE_REG(nReg) - nOffset);
1859 nCoefficient = ((int)pCommands[n] << 24)
1860 | ((int)pCommands[n + 1] << 16)
1861 | ((int)pCommands[n + 2] << 8)
1862 | (int)pCommands[n + 3];
1863 bFound = true;
1864 break;
1865 }
1866 } else {
1867 dev_err(pTAS2563->dev, "%s, format error %d\n", __func__, nOffset);
1868 break;
1869 }
1870 }
1872 if (bFound) {
1873 *pnValue = nCoefficient;
1874 dev_info(pTAS2563->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", __func__,
1875 TAS2563_BOOK_ID(nReg), TAS2563_PAGE_ID(nReg), TAS2563_PAGE_REG(nReg),
1876 nCoefficient);
1877 }
1879 return bFound;
1880 }
1883 int tas2563_set_program(struct tas2563_priv *pTAS2563,
1884 unsigned int nProgram, int nConfig)
1885 {
1886 struct TProgram *pProgram;
1887 unsigned int nConfiguration = 0;
1888 unsigned int nSampleRate = 0;
1889 bool bFound = false;
1890 int nResult = 0;
1892 if ((!pTAS2563->mpFirmware->mpPrograms) ||
1893 (!pTAS2563->mpFirmware->mpConfigurations)) {
1894 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n", __func__);
1895 nResult = 0;
1896 goto end;
1897 }
1899 if (nProgram >= pTAS2563->mpFirmware->mnPrograms) {
1900 dev_err(pTAS2563->dev, "TAS2563: Program %d doesn't exist\n",
1901 nProgram);
1902 nResult = 0;
1903 goto end;
1904 }
1906 if (nConfig < 0) {
1907 nConfiguration = 0;
1908 nSampleRate = pTAS2563->mnCurrentSampleRate;
1909 while (!bFound && (nConfiguration < pTAS2563->mpFirmware->mnConfigurations)) {
1910 if (pTAS2563->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
1911 if (nSampleRate == 0) {
1912 bFound = true;
1913 dev_info(pTAS2563->dev, "find default configuration %d\n", nConfiguration);
1914 } else if (nSampleRate == pTAS2563->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
1915 bFound = true;
1916 dev_info(pTAS2563->dev, "find matching configuration %d\n", nConfiguration);
1917 } else {
1918 nConfiguration++;
1919 }
1920 } else {
1921 nConfiguration++;
1922 }
1923 }
1924 if (!bFound) {
1925 dev_err(pTAS2563->dev,
1926 "Program %d, no valid configuration found for sample rate %d, ignore\n",
1927 nProgram, nSampleRate);
1928 nResult = 0;
1929 goto end;
1930 }
1931 } else {
1932 if (pTAS2563->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
1933 dev_err(pTAS2563->dev, "%s, configuration program doesn't match\n", __func__);
1934 nResult = 0;
1935 goto end;
1936 }
1937 nConfiguration = nConfig;
1938 }
1940 pProgram = &(pTAS2563->mpFirmware->mpPrograms[nProgram]);
1941 if (pTAS2563->mbPowerUp) {
1942 dev_info(pTAS2563->dev,
1943 "device powered up, power down to load program %d (%s)\n",
1944 nProgram, pProgram->mpName);
1945 if (hrtimer_active(&pTAS2563->mtimerwork))
1946 hrtimer_cancel(&pTAS2563->mtimerwork);
1948 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE)
1949 pTAS2563->enableIRQ(pTAS2563, false);
1951 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1952 if (nResult < 0)
1953 goto end;
1954 }
1956 pTAS2563->hw_reset(pTAS2563);
1957 nResult = pTAS2563->write(pTAS2563, TAS2563_SoftwareReset, 0x01);
1958 if (nResult < 0)
1959 goto end;
1960 msleep(1);
1961 nResult = tas2563_load_default(pTAS2563);
1962 if (nResult < 0)
1963 goto end;
1965 dev_info(pTAS2563->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
1966 nResult = tas2563_load_data(pTAS2563, &(pProgram->mData), TAS2563_BLOCK_PGM_DEV_A);
1967 if (nResult < 0)
1968 goto end;
1969 pTAS2563->mnCurrentProgram = nProgram;
1971 nResult = tas2563_load_coefficient(pTAS2563, -1, nConfiguration, false);
1972 if (nResult < 0)
1973 goto end;
1975 // Enable IV data
1976 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1977 TAS2563_PowerControl_OperationalMode10_Mask |
1978 TAS2563_PowerControl_ISNSPower_Mask |
1979 TAS2563_PowerControl_VSNSPower_Mask,
1980 TAS2563_PowerControl_OperationalMode10_Active |
1981 TAS2563_PowerControl_VSNSPower_Active |
1982 TAS2563_PowerControl_ISNSPower_Active);
1983 if (nResult < 0)
1984 dev_info(pTAS2563->dev, "Enable IV Data Failed: %s\n", __func__);
1986 if (pTAS2563->mbPowerUp) {
1987 // pTAS2563->clearIRQ(pTAS2563);
1988 // dev_info(pTAS2563->dev, "device powered up, load startup\n");
1989 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_MUTE);
1991 if (nResult < 0)
1992 goto end;
1993 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1994 if (nResult < 0) {
1995 tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1996 pTAS2563->mbPowerUp = false;
1997 goto end;
1998 }
1999 }
2000 dev_info(pTAS2563->dev, "device powered up, load unmute\n");
2001 tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
2002 if (nResult < 0)
2003 goto end;
2005 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
2006 pTAS2563->enableIRQ(pTAS2563, true);
2007 if (!hrtimer_active(&pTAS2563->mtimerwork)) {
2008 pTAS2563->mnDieTvReadCounter = 0;
2009 hrtimer_start(&pTAS2563->mtimerwork,
2010 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
2011 }
2012 }
2013 }
2015 end:
2017 /* if (nResult < 0) {
2018 if (pTAS2563->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
2019 failsafe(pTAS2563);
2020 }*/
2021 return nResult;
2022 }
2024 static int tas2563_set_calibration(struct tas2563_priv *pTAS2563, int nCalibration)
2025 {
2026 struct TCalibration *pCalibration = NULL;
2027 struct TConfiguration *pConfiguration;
2028 struct TProgram *pProgram;
2029 int nTmax = 0;
2030 bool bFound = false;
2031 int nResult = 0;
2033 if ((!pTAS2563->mpFirmware->mpPrograms)
2034 || (!pTAS2563->mpFirmware->mpConfigurations)) {
2035 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n\r", __func__);
2036 nResult = 0;
2037 goto end;
2038 }
2040 if (nCalibration == 0x00FF) {
2041 nResult = tas2563_load_calibration(pTAS2563, TAS2563_CAL_NAME);
2042 if (nResult < 0) {
2043 dev_info(pTAS2563->dev, "load new calibration file %s fail %d\n",
2044 TAS2563_CAL_NAME, nResult);
2045 goto end;
2046 }
2047 nCalibration = 0;
2048 }
2050 if (nCalibration >= pTAS2563->mpCalFirmware->mnCalibrations) {
2051 dev_err(pTAS2563->dev,
2052 "Calibration %d doesn't exist\n", nCalibration);
2053 nResult = 0;
2054 goto end;
2055 }
2057 pTAS2563->mnCurrentCalibration = nCalibration;
2058 if (pTAS2563->mbLoadConfigurationPrePowerUp)
2059 goto end;
2061 pCalibration = &(pTAS2563->mpCalFirmware->mpCalibrations[nCalibration]);
2062 pProgram = &(pTAS2563->mpFirmware->mpPrograms[pTAS2563->mnCurrentProgram]);
2063 pConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[pTAS2563->mnCurrentConfiguration]);
2064 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
2065 if (pTAS2563->mbBypassTMax) {
2066 bFound = tas2563_find_Tmax_in_configuration(pTAS2563, pConfiguration, &nTmax);
2067 if (bFound && (nTmax == TAS2563_COEFFICIENT_TMAX)) {
2068 dev_info(pTAS2563->dev, "%s, config[%s] bypass load calibration\n",
2069 __func__, pConfiguration->mpName);
2070 goto end;
2071 }
2072 }
2074 dev_info(pTAS2563->dev, "%s, load calibration\n", __func__);
2075 nResult = tas2563_load_data(pTAS2563, &(pCalibration->mData), TAS2563_BLOCK_CFG_COEFF_DEV_A);
2076 if (nResult < 0)
2077 goto end;
2078 }
2080 end:
2081 if (nResult < 0) {
2082 tas2563_clear_firmware(pTAS2563->mpCalFirmware);
2083 nResult = tas2563_set_program(pTAS2563, pTAS2563->mnCurrentProgram, pTAS2563->mnCurrentConfiguration);
2084 }
2086 return nResult;
2087 }
2089 bool tas2563_get_Cali_prm_r0(struct tas2563_priv *pTAS2563, int *prm_r0)
2090 {
2091 struct TCalibration *pCalibration;
2092 struct TData *pData;
2093 int nReg;
2094 int nCali_Re;
2095 bool bFound = false;
2096 int nBlockType;
2098 if (!pTAS2563->mpCalFirmware->mnCalibrations) {
2099 dev_err(pTAS2563->dev, "%s, no calibration data\n", __func__);
2100 goto end;
2101 }
2103 nReg = TAS2563_CALI_R0_REG;
2104 nBlockType = TAS2563_BLOCK_CFG_COEFF_DEV_A;
2106 pCalibration = &(pTAS2563->mpCalFirmware->mpCalibrations[pTAS2563->mnCurrentCalibration]);
2107 pData = &(pCalibration->mData);
2109 bFound = tas2563_get_coefficient_in_data(pTAS2563, pData, nBlockType, nReg, &nCali_Re);
2111 end:
2113 if (bFound)
2114 *prm_r0 = nCali_Re;
2116 return bFound;
2117 }
2119 int tas2563_set_config(struct tas2563_priv *pTAS2563, int config)
2120 {
2121 struct TConfiguration *pConfiguration;
2122 struct TProgram *pProgram;
2123 unsigned int nProgram = pTAS2563->mnCurrentProgram;
2124 unsigned int nConfiguration = config;
2125 int nResult = 0;
2127 if ((!pTAS2563->mpFirmware->mpPrograms) ||
2128 (!pTAS2563->mpFirmware->mpConfigurations)) {
2129 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n", __func__);
2130 nResult = -EINVAL;
2131 goto end;
2132 }
2134 if (nConfiguration >= pTAS2563->mpFirmware->mnConfigurations) {
2135 dev_err(pTAS2563->dev, "Configuration %d doesn't exist\n",
2136 nConfiguration);
2137 nResult = -EINVAL;
2138 goto end;
2139 }
2141 pConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[nConfiguration]);
2142 pProgram = &(pTAS2563->mpFirmware->mpPrograms[nProgram]);
2144 if (nProgram != pConfiguration->mnProgram) {
2145 dev_err(pTAS2563->dev,
2146 "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
2147 nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
2148 nProgram, pProgram->mpName);
2149 nResult = -EINVAL;
2150 goto end;
2151 }
2153 nResult = tas2563_load_configuration(pTAS2563, nConfiguration, false);
2155 end:
2157 return nResult;
2158 }
2160 static int tas2563_configuration_get(struct snd_kcontrol *pKcontrol,
2161 struct snd_ctl_elem_value *pValue)
2162 {
2163 #ifdef KCONTROL_CODEC
2164 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2165 #else
2166 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2167 #endif
2168 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2170 mutex_lock(&pTAS2563->codec_lock);
2172 pValue->value.integer.value[0] = pTAS2563->mnCurrentConfiguration;
2173 dev_info(pTAS2563->dev, "tas2563_configuration_get = %d\n",
2174 pTAS2563->mnCurrentConfiguration);
2176 mutex_unlock(&pTAS2563->codec_lock);
2177 return 0;
2178 }
2180 static int tas2563_configuration_put(struct snd_kcontrol *pKcontrol,
2181 struct snd_ctl_elem_value *pValue)
2182 {
2183 #ifdef KCONTROL_CODEC
2184 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2185 #else
2186 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2187 #endif
2188 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2189 unsigned int nConfiguration = pValue->value.integer.value[0];
2190 int ret = 0;
2192 mutex_lock(&pTAS2563->codec_lock);
2194 dev_info(pTAS2563->dev, "%s = %d\n", __func__, nConfiguration);
2195 ret = tas2563_set_config(pTAS2563, nConfiguration);
2197 mutex_unlock(&pTAS2563->codec_lock);
2198 return ret;
2199 }
2202 static int tas2563_hw_params(struct snd_pcm_substream *substream,
2203 struct snd_pcm_hw_params *params,
2204 struct snd_soc_dai *dai)
2205 {
2206 struct snd_soc_codec *codec = dai->codec;
2207 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2208 int ret = 0;
2209 int blr_clk_ratio;
2211 dev_info(pTAS2563->dev, "%s, format: %d\n", __func__,
2212 params_format(params));
2214 mutex_lock(&pTAS2563->codec_lock);
2216 ret = tas2563_set_bitwidth(pTAS2563, params_format(params));
2217 if(ret < 0)
2218 {
2219 dev_info(pTAS2563->dev, "set bitwidth failed, %d\n", ret);
2220 goto ret;
2221 }
2223 blr_clk_ratio = params_channels(params) * pTAS2563->mnCh_size;
2224 dev_info(pTAS2563->dev, "blr_clk_ratio: %d\n", blr_clk_ratio);
2225 if(blr_clk_ratio != 0)
2226 tas2563_slot_config(pTAS2563->codec, pTAS2563, blr_clk_ratio);
2228 dev_info(pTAS2563->dev, "%s, sample rate: %d\n", __func__,
2229 params_rate(params));
2231 ret = tas2563_set_samplerate(pTAS2563, params_rate(params));
2233 ret:
2234 mutex_unlock(&pTAS2563->codec_lock);
2235 return ret;
2236 }
2238 static int tas2563_set_fmt(struct tas2563_priv *pTAS2563, unsigned int fmt)
2239 {
2240 u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
2241 int ret = 0;
2243 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2244 case SND_SOC_DAIFMT_CBS_CFS:
2245 asi_cfg_1 = 0x00;
2246 break;
2247 default:
2248 dev_err(pTAS2563->dev, "ASI format master is not found\n");
2249 ret = -EINVAL;
2250 }
2252 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2253 case SND_SOC_DAIFMT_NB_NF:
2254 dev_info(pTAS2563->dev, "INV format: NBNF\n");
2255 asi_cfg_1 |= TAS2563_TDMConfigurationReg1_RXEDGE_Rising;
2256 break;
2257 case SND_SOC_DAIFMT_IB_NF:
2258 dev_info(pTAS2563->dev, "INV format: IBNF\n");
2259 asi_cfg_1 |= TAS2563_TDMConfigurationReg1_RXEDGE_Falling;
2260 break;
2261 default:
2262 dev_err(pTAS2563->dev, "ASI format Inverse is not found\n");
2263 ret = -EINVAL;
2264 }
2266 pTAS2563->update_bits(pTAS2563, TAS2563_TDMConfigurationReg1,
2267 TAS2563_TDMConfigurationReg1_RXEDGE_Mask,
2268 asi_cfg_1);
2270 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2271 case (SND_SOC_DAIFMT_I2S):
2272 tdm_rx_start_slot = 1;
2273 break;
2274 case (SND_SOC_DAIFMT_DSP_A):
2275 case (SND_SOC_DAIFMT_DSP_B):
2276 tdm_rx_start_slot = 1;
2277 break;
2278 case (SND_SOC_DAIFMT_LEFT_J):
2279 tdm_rx_start_slot = 0;
2280 break;
2281 default:
2282 dev_err(pTAS2563->dev, "DAI Format is not found, fmt=0x%x\n", fmt);
2283 ret = -EINVAL;
2284 break;
2285 }
2287 pTAS2563->update_bits(pTAS2563, TAS2563_TDMConfigurationReg1,
2288 TAS2563_TDMConfigurationReg1_RXOFFSET51_Mask,
2289 (tdm_rx_start_slot << TAS2563_TDMConfigurationReg1_RXOFFSET51_Shift));
2291 pTAS2563->mnASIFormat = fmt;
2293 return 0;
2294 }
2297 static int tas2563_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2298 {
2299 struct snd_soc_codec *codec = dai->codec;
2300 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2301 int ret = 0;
2303 dev_info(pTAS2563->dev, "%s, format=0x%x\n", __func__, fmt);
2305 mutex_lock(&pTAS2563->codec_lock);
2307 ret = tas2563_set_fmt(pTAS2563, fmt);
2309 mutex_unlock(&pTAS2563->codec_lock);
2310 return ret;
2311 }
2313 static int tas2563_set_dai_tdm_slot(struct snd_soc_dai *dai,
2314 unsigned int tx_mask, unsigned int rx_mask,
2315 int slots, int slot_width)
2316 {
2317 int ret = 0;
2318 struct snd_soc_codec *codec = dai->codec;
2319 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2321 dev_info(pTAS2563->dev, "%s, tx_mask:%d, rx_mask:%d, slots:%d, slot_width:%d",
2322 __func__, tx_mask, rx_mask, slots, slot_width);
2324 ret = tas2563_set_slot(pTAS2563, slot_width);
2326 return ret;
2327 }
2329 static int tas2563_program_get(struct snd_kcontrol *pKcontrol,
2330 struct snd_ctl_elem_value *pValue)
2331 {
2332 #ifdef KCONTROL_CODEC
2333 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2334 #else
2335 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2336 #endif
2337 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2339 mutex_lock(&pTAS2563->codec_lock);
2341 pValue->value.integer.value[0] = pTAS2563->mnCurrentProgram;
2342 dev_info(pTAS2563->dev, "tas2563_program_get = %d\n",
2343 pTAS2563->mnCurrentProgram);
2345 mutex_unlock(&pTAS2563->codec_lock);
2346 return 0;
2347 }
2349 static int tas2563_program_put(struct snd_kcontrol *pKcontrol,
2350 struct snd_ctl_elem_value *pValue)
2351 {
2352 #ifdef KCONTROL_CODEC
2353 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2354 #else
2355 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2356 #endif
2357 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2358 unsigned int nProgram = pValue->value.integer.value[0];
2359 int ret = 0, nConfiguration = -1;
2361 mutex_lock(&pTAS2563->codec_lock);
2363 if (nProgram == pTAS2563->mnCurrentProgram)
2364 nConfiguration = pTAS2563->mnCurrentConfiguration;
2365 ret = tas2563_set_program(pTAS2563, nProgram, nConfiguration);
2367 mutex_unlock(&pTAS2563->codec_lock);
2368 return ret;
2369 }
2371 static int tas2563_calibration_get(struct snd_kcontrol *pKcontrol,
2372 struct snd_ctl_elem_value *pValue)
2373 {
2374 #ifdef KCONTROL_CODEC
2375 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2376 #else
2377 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2378 #endif
2379 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2381 mutex_lock(&pTAS2563->codec_lock);
2383 pValue->value.integer.value[0] = pTAS2563->mnCurrentCalibration;
2384 dev_info(pTAS2563->dev,
2385 "tas2563_calibration_get = %d\n",
2386 pTAS2563->mnCurrentCalibration);
2388 mutex_unlock(&pTAS2563->codec_lock);
2389 return 0;
2390 }
2392 static int tas2563_calibration_put(struct snd_kcontrol *pKcontrol,
2393 struct snd_ctl_elem_value *pValue)
2394 {
2395 #ifdef KCONTROL_CODEC
2396 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2397 #else
2398 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2399 #endif
2400 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2401 unsigned int nCalibration = pValue->value.integer.value[0];
2402 int ret = 0;
2404 mutex_lock(&pTAS2563->codec_lock);
2406 ret = tas2563_set_calibration(pTAS2563, nCalibration);
2408 mutex_unlock(&pTAS2563->codec_lock);
2409 return ret;
2410 }
2412 static struct snd_soc_dai_ops tas2563_dai_ops = {
2413 .digital_mute = tas2563_mute,
2414 .hw_params = tas2563_hw_params,
2415 .set_fmt = tas2563_set_dai_fmt,
2416 .set_tdm_slot = tas2563_set_dai_tdm_slot,
2417 };
2419 #define TAS2563_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2420 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2422 #define TAS2563_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 \
2423 SNDRV_PCM_RATE_88200 |\
2424 SNDRV_PCM_RATE_96000 |\
2425 SNDRV_PCM_RATE_176400 |\
2426 SNDRV_PCM_RATE_192000\
2427 )
2429 static struct snd_soc_dai_driver tas2563_dai_driver[] = {
2430 {
2431 .name = "tas2563 ASI1",
2432 .id = 0,
2433 .playback = {
2434 .stream_name = "ASI1 Playback",
2435 .channels_min = 2,
2436 .channels_max = 2,
2437 .rates = SNDRV_PCM_RATE_8000_192000,
2438 .formats = TAS2563_FORMATS,
2439 },
2440 .capture = {
2441 .stream_name = "ASI1 Capture",
2442 .channels_min = 0,
2443 .channels_max = 2,
2444 .rates = SNDRV_PCM_RATE_8000_192000,
2445 .formats = TAS2563_FORMATS,
2446 },
2447 .ops = &tas2563_dai_ops,
2448 .symmetric_rates = 1,
2449 },
2450 };
2452 static int tas2563_codec_probe(struct snd_soc_codec *codec)
2453 {
2454 int ret;
2455 struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2457 ret = snd_soc_add_codec_controls(codec, tas2563_controls,
2458 ARRAY_SIZE(tas2563_controls));
2459 if (ret < 0) {
2460 pr_err("%s: add_codec_controls failed, err %d\n",
2461 __func__, ret);
2462 return ret;
2463 }
2464 pTAS2563->codec = codec;
2465 pTAS2563->set_calibration = tas2563_set_calibration;
2466 pTAS2563->set_config = tas2563_set_config;
2468 dev_err(pTAS2563->dev, "%s\n", __func__);
2470 return 0;
2471 }
2473 static int tas2563_codec_remove(struct snd_soc_codec *codec)
2474 {
2475 return 0;
2476 }
2478 /*static DECLARE_TLV_DB_SCALE(dac_tlv, 0, 100, 0);*/
2479 static DECLARE_TLV_DB_SCALE(tas2563_digital_tlv, 1100, 50, 0);
2481 static const struct snd_kcontrol_new tas2563_snd_controls[] = {
2482 SOC_SINGLE_TLV("Amp Output Level", TAS2563_PlaybackConfigurationReg0,
2483 0, 0x16, 0,
2484 tas2563_digital_tlv),
2485 SOC_SINGLE_EXT("Program", SND_SOC_NOPM, 0, 0x00FF, 0, tas2563_program_get,
2486 tas2563_program_put),
2487 SOC_SINGLE_EXT("Configuration", SND_SOC_NOPM, 0, 0x00FF, 0,
2488 tas2563_configuration_get, tas2563_configuration_put),
2489 SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0,
2490 tas2563_calibration_get, tas2563_calibration_put),
2491 };
2493 static struct snd_soc_codec_driver soc_codec_driver_tas2563 = {
2494 .probe = tas2563_codec_probe,
2495 .remove = tas2563_codec_remove,
2496 .read = tas2563_codec_read,
2497 .write = tas2563_codec_write,
2498 .suspend = tas2563_codec_suspend,
2499 .resume = tas2563_codec_resume,
2500 #ifdef KCONTROL_CODEC
2501 .component_driver = {
2502 #endif
2503 .controls = tas2563_snd_controls,
2504 .num_controls = ARRAY_SIZE(tas2563_snd_controls),
2505 .dapm_widgets = tas2563_dapm_widgets,
2506 .num_dapm_widgets = ARRAY_SIZE(tas2563_dapm_widgets),
2507 .dapm_routes = tas2563_audio_map,
2508 .num_dapm_routes = ARRAY_SIZE(tas2563_audio_map),
2509 #ifdef KCONTROL_CODEC
2510 },
2511 #endif
2512 };
2514 int tas2563_register_codec(struct tas2563_priv *pTAS2563)
2515 {
2516 int nResult = 0;
2518 dev_info(pTAS2563->dev, "%s, enter\n", __func__);
2519 nResult = snd_soc_register_codec(pTAS2563->dev,
2520 &soc_codec_driver_tas2563,
2521 tas2563_dai_driver, ARRAY_SIZE(tas2563_dai_driver));
2522 return nResult;
2523 }
2525 int tas2563_deregister_codec(struct tas2563_priv *pTAS2563)
2526 {
2527 snd_soc_unregister_codec(pTAS2563->dev);
2529 return 0;
2530 }
2532 MODULE_AUTHOR("Texas Instruments Inc.");
2533 MODULE_DESCRIPTION("TAS2563 ALSA SOC Smart Amplifier driver");
2534 MODULE_LICENSE("GPL v2");
2535 #endif /* CONFIG_TAS2563_CODEC */