Fix the bug of not unlock before return
[tas256xsw-android/tas2563-android-driver.git] / tas2563-codec.c
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;
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)
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;
207 static int isInBlockYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
208         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
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;
261 static int isYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
262         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
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;
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)
284         /* loop over the buffer data */
285         while (nbytes-- > 0)
286                 crc = table[(crc ^ *pdata++) & 0xff];
288         return crc;
291 static int doSingleRegCheckSum(struct tas2563_priv *pTAS2563, 
292         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
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;
328 static int doMultiRegCheckSum(struct tas2563_priv *pTAS2563, 
329         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
331         int nResult = 0, i;
332         unsigned char nCRCChkSum = 0;
333         unsigned char nBuf1[128];
334         struct TYCRC TCRCData;
335         
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;
390 static int tas2563_load_block(struct tas2563_priv *pTAS2563, struct TBlock *pBlock)
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;
530 static int tas2563_load_data(struct tas2563_priv *pTAS2563, struct TData *pData, unsigned int nType)
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;
551 void tas2563_clear_firmware(struct TFirmware *pFirmware)
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));
604 static int tas2563_load_configuration(struct tas2563_priv *pTAS2563,
605         unsigned int nConfiguration, bool bLoadSame)
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;
667 static int tas2563_load_calibration(struct tas2563_priv *pTAS2563,      char *pFileName)
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;
713 static int tas2563iv_put(struct snd_kcontrol *kcontrol,
714                                    struct snd_ctl_elem_value *ucontrol)
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;
754 static int tas2563iv_get(struct snd_kcontrol *kcontrol,
755                                   struct snd_ctl_elem_value *ucontrol)
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;
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)
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;
789 static void fw_print_header(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware)
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);
801 inline unsigned int fw_convert_number(unsigned char *pData)
803         return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
806 static int fw_parse_header(struct tas2563_priv *pTAS2563,
807         struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
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;
876 static int fw_parse_block_data(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware,
877         struct TBlock *pBlock, unsigned char *pData)
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;
915 static int fw_parse_data(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware,
916         struct TData *pImageData, unsigned char *pData)
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;
944 static int fw_parse_program_data(struct tas2563_priv *pTAS2563,
945         struct TFirmware *pFirmware, unsigned char *pData)
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;
997 static int fw_parse_configuration_data(struct tas2563_priv *pTAS2563,
998         struct TFirmware *pFirmware, unsigned char *pData)
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;
1062 int fw_parse_calibration_data(struct tas2563_priv *pTAS2563,
1063         struct TFirmware *pFirmware, unsigned char *pData)
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;
1104 static int fw_parse(struct tas2563_priv *pTAS2563,
1105         struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
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;
1146 static int tas2563_codec_suspend(struct snd_soc_codec *codec)
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;
1160 static int tas2563_codec_resume(struct snd_soc_codec *codec)
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;
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)
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         */
1215         
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;
1286 static int tas2563_dac_event(struct snd_soc_dapm_widget *w,
1287                         struct snd_kcontrol *kcontrol, int event)
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;
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)
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;
1356 static int tas2563_slot_config(struct snd_soc_codec *codec, struct tas2563_priv *pTAS2563, int blr_clk_ratio)
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;
1368 static int tas2563_set_slot(struct tas2563_priv *pTAS2563, int slot_width)
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;
1410 static int tas2563_set_bitwidth(struct tas2563_priv *pTAS2563, int bitwidth)
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;
1458 static int tas2563_set_samplerate(struct tas2563_priv *pTAS2563, int samplerate)
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;
1530 int tas2563_load_default(struct tas2563_priv *pTAS2563)
1532         int ret = 0;
1533         
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;
1575 #if 0
1576 static void failsafe(struct tas2563_priv *pTAS2563)
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);
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)
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;
1718 static bool tas2563_get_coefficient_in_data(struct tas2563_priv *pTAS2563,
1719         struct TData *pData, int blockType, int nReg, int *pnValue)
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;
1738 static bool tas2563_find_Tmax_in_configuration(struct tas2563_priv *pTAS2563,
1739         struct TConfiguration *pConfiguration, int *pnTMax)
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;
1757 void tas2563_fw_ready(const struct firmware *pFW, void *pContext)
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
1826 static bool tas2563_get_coefficient_in_block(struct tas2563_priv *pTAS2563,
1827         struct TBlock *pBlock, int nReg, int *pnValue)
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;
1883 int tas2563_set_program(struct tas2563_priv *pTAS2563,
1884         unsigned int nProgram, int nConfig)
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;
2024 static int tas2563_set_calibration(struct tas2563_priv *pTAS2563, int nCalibration)
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;
2089 bool tas2563_get_Cali_prm_r0(struct tas2563_priv *pTAS2563, int *prm_r0)
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;
2119 int tas2563_set_config(struct tas2563_priv *pTAS2563, int config)
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;
2160 static int tas2563_configuration_get(struct snd_kcontrol *pKcontrol,
2161         struct snd_ctl_elem_value *pValue)
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;
2180 static int tas2563_configuration_put(struct snd_kcontrol *pKcontrol,
2181         struct snd_ctl_elem_value *pValue)
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;
2202 static int tas2563_hw_params(struct snd_pcm_substream *substream,
2203                 struct snd_pcm_hw_params *params,
2204                 struct snd_soc_dai *dai)
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;
2238 static int tas2563_set_fmt(struct tas2563_priv *pTAS2563, unsigned int fmt)
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;
2297 static int tas2563_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
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;
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)
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;
2329 static int tas2563_program_get(struct snd_kcontrol *pKcontrol,
2330         struct snd_ctl_elem_value *pValue)
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;
2349 static int tas2563_program_put(struct snd_kcontrol *pKcontrol,
2350         struct snd_ctl_elem_value *pValue)
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;
2371 static int tas2563_calibration_get(struct snd_kcontrol *pKcontrol,
2372         struct snd_ctl_elem_value *pValue)
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;
2392 static int tas2563_calibration_put(struct snd_kcontrol *pKcontrol,
2393         struct snd_ctl_elem_value *pValue)
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;
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)
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;
2473 static int tas2563_codec_remove(struct snd_soc_codec *codec)
2475         return 0;
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)
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;
2525 int tas2563_deregister_codec(struct tas2563_priv *pTAS2563)
2527         snd_soc_unregister_codec(pTAS2563->dev);
2529         return 0;
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 */