b150b1e1236525b8e2d0d7879b564cfe6eb26c5a
[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 /*600ms, -105dB*/
76 static char pICN[] = {0x00, 0x00, 0x2f, 0x2c};
77 static char pICNDelay[] = {0x00, 0x00, 0x70, 0x80};
78 static int tas2563_set_fmt(struct tas2563_priv *pTAS2563, unsigned int fmt);
79 static void tas2563_clear_firmware(struct TFirmware *pFirmware);
81 static int fw_parse(struct tas2563_priv *pTAS2563,
82         struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize);
83 static bool tas2563_get_coefficient_in_block(struct tas2563_priv *pTAS2563,
84         struct TBlock *pBlock, int nReg, int *pnValue);
85 int tas2563_set_program(struct tas2563_priv *pTAS2563, unsigned int nProgram, int nConfig);
86 static int tas2563_set_calibration(struct tas2563_priv *pTAS2563, int nCalibration);
87 static int tas2563_load_configuration(struct tas2563_priv *pTAS2563,
88         unsigned int nConfiguration, bool bLoadSame);
89 static int tas2563_load_coefficient(struct tas2563_priv *pTAS2563,
90         int nPrevConfig, int nNewConfig, bool bPowerOn);
92 static unsigned int tas2563_codec_read(struct snd_soc_codec *codec,
93                 unsigned int reg)
94 {
95         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
96         int nResult = 0;
97         unsigned int value = 0;
99         nResult = pTAS2563->read(pTAS2563, reg, &value);
101         if (nResult < 0)
102                 dev_err(pTAS2563->dev, "%s, ERROR, reg=0x%x, E=%d\n",
103                         __func__, reg, nResult);
104         else
105                 dev_info(pTAS2563->dev, "%s, reg: 0x%x, value: 0x%x\n",
106                                 __func__, reg, value);
108         if (nResult >= 0)
109                 return value;
110         else
111                 return nResult;
114 static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
115 0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
116 0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
117 0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
118 0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
119 0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
120 0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
121 0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
122 0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
123 0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
124 0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
125 0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
126 0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
127 0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
128 0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
129 0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
130 0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
131 };
133 static int isInPageYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
134         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
136         int nResult = 0;
138         if (nBook == TAS2563_YRAM_BOOK1) {
139                 if (nPage == TAS2563_YRAM1_PAGE) {
140                         if (nReg >= TAS2563_YRAM1_START_REG) {
141                                 pCRCData->mnOffset = nReg;
142                                 pCRCData->mnLen = len;
143                                 nResult = 1;
144                         } else if ((nReg + len) > TAS2563_YRAM1_START_REG) {
145                                 pCRCData->mnOffset = TAS2563_YRAM1_START_REG;
146                                 pCRCData->mnLen = len - (TAS2563_YRAM1_START_REG - nReg);
147                                 nResult = 1;
148                         } else
149                                 nResult = 0;
150                 } else if (nPage == TAS2563_YRAM3_PAGE) {
151                         if (nReg > TAS2563_YRAM3_END_REG) {
152                                 nResult = 0;
153                         } else if (nReg >= TAS2563_YRAM3_START_REG) {
154                                 if ((nReg + len) > TAS2563_YRAM3_END_REG) {
155                                         pCRCData->mnOffset = nReg;
156                                         pCRCData->mnLen = TAS2563_YRAM3_END_REG - nReg + 1;
157                                         nResult = 1;
158                                 } else {
159                                         pCRCData->mnOffset = nReg;
160                                         pCRCData->mnLen = len;
161                                         nResult = 1;
162                                 }
163                         } else {
164                                 if ((nReg + (len - 1)) < TAS2563_YRAM3_START_REG)
165                                         nResult = 0;
166                                 else {
167                                         pCRCData->mnOffset = TAS2563_YRAM3_START_REG;
168                                         pCRCData->mnLen = len - (TAS2563_YRAM3_START_REG - nReg);
169                                         nResult = 1;
170                                 }
171                         }
172                 }
173         } else if (nBook == TAS2563_YRAM_BOOK2) {
174                 if (nPage == TAS2563_YRAM5_PAGE) {
175                         if (nReg > TAS2563_YRAM5_END_REG) {
176                                 nResult = 0;
177                         } else if (nReg >= TAS2563_YRAM5_START_REG) {
178                                 if ((nReg + len) > TAS2563_YRAM5_END_REG) {
179                                         pCRCData->mnOffset = nReg;
180                                         pCRCData->mnLen = TAS2563_YRAM5_END_REG - nReg + 1;
181                                         nResult = 1;
182                                 } else {
183                                         pCRCData->mnOffset = nReg;
184                                         pCRCData->mnLen = len;
185                                         nResult = 1;
186                                 }
187                         } else {
188                                 if ((nReg + (len - 1)) < TAS2563_YRAM5_START_REG)
189                                         nResult = 0;
190                                 else {
191                                         pCRCData->mnOffset = TAS2563_YRAM5_START_REG;
192                                         pCRCData->mnLen = len - (TAS2563_YRAM5_START_REG - nReg);
193                                         nResult = 1;
194                                 }
195                         }
196                 }
197         } else
198                 nResult = 0;
200         return nResult;
203 static int isInBlockYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
204         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
206         int nResult;
208         if (nBook == TAS2563_YRAM_BOOK1) {
209                 if (nPage < TAS2563_YRAM2_START_PAGE)
210                         nResult = 0;
211                 else if (nPage <= TAS2563_YRAM2_END_PAGE) {
212                         if (nReg > TAS2563_YRAM2_END_REG)
213                                 nResult = 0;
214                         else if (nReg >= TAS2563_YRAM2_START_REG) {
215                                 pCRCData->mnOffset = nReg;
216                                 pCRCData->mnLen = len;
217                                 nResult = 1;
218                         } else {
219                                 if ((nReg + (len - 1)) < TAS2563_YRAM2_START_REG)
220                                         nResult = 0;
221                                 else {
222                                         pCRCData->mnOffset = TAS2563_YRAM2_START_REG;
223                                         pCRCData->mnLen = nReg + len - TAS2563_YRAM2_START_REG;
224                                         nResult = 1;
225                                 }
226                         }
227                 } else
228                         nResult = 0;
229         } else if (nBook == TAS2563_YRAM_BOOK2) {
230                 if (nPage < TAS2563_YRAM4_START_PAGE)
231                         nResult = 0;
232                 else if (nPage <= TAS2563_YRAM4_END_PAGE) {
233                         if (nReg > TAS2563_YRAM2_END_REG)
234                                 nResult = 0;
235                         else if (nReg >= TAS2563_YRAM2_START_REG) {
236                                 pCRCData->mnOffset = nReg;
237                                 pCRCData->mnLen = len;
238                                 nResult = 1;
239                         } else {
240                                 if ((nReg + (len - 1)) < TAS2563_YRAM2_START_REG)
241                                         nResult = 0;
242                                 else {
243                                         pCRCData->mnOffset = TAS2563_YRAM2_START_REG;
244                                         pCRCData->mnLen = nReg + len - TAS2563_YRAM2_START_REG;
245                                         nResult = 1;
246                                 }
247                         }
248                 } else
249                         nResult = 0;
250         } else
251                 nResult = 0;
253         return nResult;
257 static int isYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
258         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
260         int nResult;
262         nResult = isInPageYRAM(pTAS2563, pCRCData, nBook, nPage, nReg, len);
264         if (nResult == 0)
265                 nResult = isInBlockYRAM(pTAS2563, pCRCData, nBook, nPage, nReg, len);
267         return nResult;
270 /*
271  * crc8 - calculate a crc8 over the given input data.
272  *
273  * table: crc table used for calculation.
274  * pdata: pointer to data buffer.
275  * nbytes: number of bytes in data buffer.
276  * crc: previous returned crc8 value.
277  */
278 static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
280         /* loop over the buffer data */
281         while (nbytes-- > 0)
282                 crc = table[(crc ^ *pdata++) & 0xff];
284         return crc;
287 static int doSingleRegCheckSum(struct tas2563_priv *pTAS2563, 
288         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
290         int nResult = 0;
291         struct TYCRC sCRCData;
292         unsigned int nData1 = 0;
294         if ((nBook == TAS2563_BOOK_ID(TAS2563_SA_COEFF_SWAP_REG))
295                 && (nPage == TAS2563_PAGE_ID(TAS2563_SA_COEFF_SWAP_REG))
296                 && (nReg >= TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG))
297                 && (nReg <= (TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG) + 4))) {
298                 /* DSP swap command, pass */
299                 nResult = 0;
300                 goto end;
301         }
303         nResult = isYRAM(pTAS2563, &sCRCData, nBook, nPage, nReg, 1);
304         if (nResult == 1) {
305                 nResult = pTAS2563->read(pTAS2563, TAS2563_REG(nBook, nPage, nReg), &nData1);
306                 if (nResult < 0)
307                         goto end;
309                 if (nData1 != nValue) {
310                         dev_err(pTAS2563->dev, "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
311                                 __LINE__, nBook, nPage, nReg, nValue, nData1);
312                         nResult = -EAGAIN;
313                         goto end;
314                 }
316                 nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0);
317         }
319 end:
321         return nResult;
324 static int doMultiRegCheckSum(struct tas2563_priv *pTAS2563, 
325         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
327         int nResult = 0, i;
328         unsigned char nCRCChkSum = 0;
329         unsigned char nBuf1[128];
330         struct TYCRC TCRCData;
331         
332         return 0;
334         if ((nReg + len-1) > 127) {
335                 nResult = -EINVAL;
336                 dev_err(pTAS2563->dev, "firmware error\n");
337                 goto end;
338         }
340         if ((nBook == TAS2563_BOOK_ID(TAS2563_SA_COEFF_SWAP_REG))
341                 && (nPage == TAS2563_PAGE_ID(TAS2563_SA_COEFF_SWAP_REG))
342                 && (nReg == TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG))
343                 && (len == 4)) {
344                 /* DSP swap command, pass */
345                 nResult = 0;
346                 goto end;
347         }
349         nResult = isYRAM(pTAS2563, &TCRCData, nBook, nPage, nReg, len);
350         dev_info(pTAS2563->dev, "isYRAM: nBook 0x%x, nPage 0x%x, nReg 0x%x\n", nBook, nPage, nReg);
351         dev_info(pTAS2563->dev, "isYRAM: TCRCData.mnLen 0x%x, len 0x%x, nResult %d\n", TCRCData.mnLen, len, nResult);
352         dev_info(pTAS2563->dev, "TCRCData.mnOffset %x\n", TCRCData.mnOffset);
353         if (nResult == 1) {
354                 if (len == 1) {
355                         dev_err(pTAS2563->dev, "firmware error\n");
356                         nResult = -EINVAL;
357                         goto end;
358                 } else {
359                         nResult = pTAS2563->bulk_read(pTAS2563, TAS2563_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
360                         if (nResult < 0)
361                                 goto end;
363                         for (i = 0; i < TCRCData.mnLen; i++) {
364                                 if ((nBook == TAS2563_BOOK_ID(TAS2563_SA_COEFF_SWAP_REG))
365                                         && (nPage == TAS2563_PAGE_ID(TAS2563_SA_COEFF_SWAP_REG))
366                                         && ((i + TCRCData.mnOffset)
367                                                 >= TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG))
368                                         && ((i + TCRCData.mnOffset)
369                                                 <= (TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG) + 4))) {
370                                         /* DSP swap command, bypass */
371                                         continue;
372                                 } else
373                                         nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf1[i], 1, 0);
374                         }
376                         nResult = nCRCChkSum;
377                 }
378         }
380 end:
382         return nResult;
386 static int tas2563_load_block(struct tas2563_priv *pTAS2563, struct TBlock *pBlock)
388         int nResult = 0;
389         unsigned int nCommand = 0;
390         unsigned char nBook;
391         unsigned char nPage;
392         unsigned char nOffset;
393         unsigned char nData;
394         unsigned int nLength;
395         unsigned int nSleep;
396         unsigned char nCRCChkSum = 0;
397         unsigned int nValue;
398         int nRetry = 6;
399         unsigned char *pData = pBlock->mpData;
401         dev_info(pTAS2563->dev, "TAS2563 load block: Type = %d, commands = %d\n",
402                 pBlock->mnType, pBlock->mnCommands);
403 start:
404         if (pBlock->mbPChkSumPresent) {
405                 nResult = pTAS2563->write(pTAS2563, TAS2563_I2CChecksum, 0);
406                 if (nResult < 0)
407                         goto end;
408         }
410         if (pBlock->mbYChkSumPresent)
411                 nCRCChkSum = 0;
413         nCommand = 0;
415         while (nCommand < pBlock->mnCommands) {
416                 pData = pBlock->mpData + nCommand * 4;
418                 nBook = pData[0];
419                 nPage = pData[1];
420                 nOffset = pData[2];
421                 nData = pData[3];
423                 nCommand++;
425                 if (nOffset <= 0x7F) {
426                         nResult = pTAS2563->write(pTAS2563, TAS2563_REG(nBook, nPage, nOffset), nData);
427                         if (nResult < 0)
428                                 goto end;
429                         if (pBlock->mbYChkSumPresent) {
430                                 nResult = doSingleRegCheckSum(pTAS2563, nBook, nPage, nOffset, nData);
431                                 if (nResult < 0)
432                                         goto check;
433                                 nCRCChkSum += (unsigned char)nResult;
434                         }
435                 } else if (nOffset == 0x81) {
436                         nSleep = (nBook << 8) + nPage;
437                         msleep(nSleep);
438                 } else if (nOffset == 0x85) {
439                         pData += 4;
440                         nLength = (nBook << 8) + nPage;
441                         nBook = pData[0];
442                         nPage = pData[1];
443                         nOffset = pData[2];
444                         if (nLength > 1) {
445                                 nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_REG(nBook, nPage, nOffset), pData + 3, nLength);
446                                 if (nResult < 0)
447                                         goto end;
448                                 if (pBlock->mbYChkSumPresent) {
449                                         nResult = doMultiRegCheckSum(pTAS2563, nBook, nPage, nOffset, nLength);
450                                         if (nResult < 0)
451                                                 goto check;
452                                         nCRCChkSum += (unsigned char)nResult;
453                                 }
454                         } else {
455                                 nResult = pTAS2563->write(pTAS2563, TAS2563_REG(nBook, nPage, nOffset), pData[3]);
456                                 if (nResult < 0)
457                                         goto end;
458                                 if (pBlock->mbYChkSumPresent) {
459                                         nResult = doSingleRegCheckSum(pTAS2563, nBook, nPage, nOffset, pData[3]);
460                                         if (nResult < 0)
461                                                 goto check;
462                                         nCRCChkSum += (unsigned char)nResult;
463                                 }
464                         }
466                         nCommand++;
468                         if (nLength >= 2)
469                                 nCommand += ((nLength - 2) / 4) + 1;
470                 }
471         }
472         if (pBlock->mbPChkSumPresent) {
473                 nResult = pTAS2563->read(pTAS2563, TAS2563_I2CChecksum, &nValue);
474                 dev_err(pTAS2563->dev, "Block PChkSum: FW = 0x%x, Reg = 0x%x\n",
475                                 pBlock->mnPChkSum, (nValue&0xff));
477                 if (nResult < 0)
478                         goto end;
479                 if ((nValue&0xff) != pBlock->mnPChkSum) {
480                         dev_err(pTAS2563->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
481                                 pBlock->mnPChkSum, (nValue&0xff));
482                         nResult = -EAGAIN;
483                                 pTAS2563->mnErrCode |= ERROR_PRAM_CRCCHK;
484                         goto check;
485                 }
487                 nResult = 0;
488                 pTAS2563->mnErrCode &= ~ERROR_PRAM_CRCCHK;
489                 dev_info(pTAS2563->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
490         }
492         if (pBlock->mbYChkSumPresent) {
493                 //TBD, open it when FW ready
494                 dev_err(pTAS2563->dev, "Block YChkSum: FW = 0x%x, YCRC = 0x%x\n",
495                                 pBlock->mnYChkSum, nCRCChkSum);
496 /*
497                 if (nCRCChkSum != pBlock->mnYChkSum) {
498                         dev_err(pTAS2563->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
499                                 pBlock->mnYChkSum, nCRCChkSum);
500                         nResult = -EAGAIN;
501                         pTAS2563->mnErrCode |= ERROR_YRAM_CRCCHK;
502                         goto check;
503                 }
504 */
505                 pTAS2563->mnErrCode &= ~ERROR_YRAM_CRCCHK;
506                 nResult = 0;
507                 dev_info(pTAS2563->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
508         }
510 check:
511         if (nResult == -EAGAIN) {
512                 nRetry--;
513                 if (nRetry > 0)
514                         goto start;
515         }
517 end:
518         if (nResult < 0) {
519                 dev_err(pTAS2563->dev, "Block (%d) load error\n",
520                                 pBlock->mnType);
521         }
522         return nResult;
526 static int tas2563_load_data(struct tas2563_priv *pTAS2563, struct TData *pData, unsigned int nType)
528         int nResult = 0;
529         unsigned int nBlock;
530         struct TBlock *pBlock;
532         dev_info(pTAS2563->dev,
533                 "TAS2563 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
535         for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
536                 pBlock = &(pData->mpBlocks[nBlock]);
537                 if (pBlock->mnType == nType) {
538                         nResult = tas2563_load_block(pTAS2563, pBlock);
539                         if (nResult < 0)
540                                 break;
541                 }
542         }
544         return nResult;
547 void tas2563_clear_firmware(struct TFirmware *pFirmware)
549         unsigned int n, nn;
551         if (!pFirmware)
552                 return;
554         kfree(pFirmware->mpDescription);
556         if (pFirmware->mpPLLs != NULL) {
557                 for (n = 0; n < pFirmware->mnPLLs; n++) {
558                         kfree(pFirmware->mpPLLs[n].mpDescription);
559                         kfree(pFirmware->mpPLLs[n].mBlock.mpData);
560                 }
561                 kfree(pFirmware->mpPLLs);
562         }
564         if (pFirmware->mpPrograms != NULL) {
565                 for (n = 0; n < pFirmware->mnPrograms; n++) {
566                         kfree(pFirmware->mpPrograms[n].mpDescription);
567                         kfree(pFirmware->mpPrograms[n].mData.mpDescription);
568                         for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
569                                 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
570                         kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
571                 }
572                 kfree(pFirmware->mpPrograms);
573         }
575         if (pFirmware->mpConfigurations != NULL) {
576                 for (n = 0; n < pFirmware->mnConfigurations; n++) {
577                         kfree(pFirmware->mpConfigurations[n].mpDescription);
578                         kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
579                         for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
580                                 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
581                         kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
582                 }
583                 kfree(pFirmware->mpConfigurations);
584         }
586         if (pFirmware->mpCalibrations != NULL) {
587                 for (n = 0; n < pFirmware->mnCalibrations; n++) {
588                         kfree(pFirmware->mpCalibrations[n].mpDescription);
589                         kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
590                         for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
591                                 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
592                         kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
593                 }
594                 kfree(pFirmware->mpCalibrations);
595         }
597         memset(pFirmware, 0x00, sizeof(struct TFirmware));
600 static int tas2563_load_configuration(struct tas2563_priv *pTAS2563,
601         unsigned int nConfiguration, bool bLoadSame)
603         int nResult = 0;
604         struct TConfiguration *pCurrentConfiguration = NULL;
605         struct TConfiguration *pNewConfiguration = NULL;
607         dev_info(pTAS2563->dev, "%s: %d\n", __func__, nConfiguration);
609         if ((!pTAS2563->mpFirmware->mpPrograms) ||
610                 (!pTAS2563->mpFirmware->mpConfigurations)) {
611                 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n", __func__);
612                 nResult = 0;
613                 goto end;
614         }
616         if (nConfiguration >= pTAS2563->mpFirmware->mnConfigurations) {
617                 dev_err(pTAS2563->dev, "Configuration %d doesn't exist\n",
618                         nConfiguration);
619                 nResult = 0;
620                 goto end;
621         }
623         if ((!pTAS2563->mbLoadConfigurationPrePowerUp)
624                 && (nConfiguration == pTAS2563->mnCurrentConfiguration)
625                 && (!bLoadSame)) {
626                 dev_info(pTAS2563->dev, "Configuration %d is already loaded\n",
627                         nConfiguration);
628                 nResult = 0;
629                 goto end;
630         }
632         pCurrentConfiguration =
633                 &(pTAS2563->mpFirmware->mpConfigurations[pTAS2563->mnCurrentConfiguration]);
634         pNewConfiguration =
635                 &(pTAS2563->mpFirmware->mpConfigurations[nConfiguration]);
636         if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
637                 dev_err(pTAS2563->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
638                         nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
639                 nResult = 0;
640                 goto end;
641         }
643         if (pTAS2563->mbPowerUp) {
644                 pTAS2563->mbLoadConfigurationPrePowerUp = false;
645                 nResult = tas2563_load_coefficient(pTAS2563, pTAS2563->mnCurrentConfiguration, nConfiguration, true);
646         } else {
647                 dev_info(pTAS2563->dev,
648                         "TAS2563 was powered down, will load coefficient when power up\n");
649                 pTAS2563->mbLoadConfigurationPrePowerUp = true;
650                 pTAS2563->mnNewConfiguration = nConfiguration;
651         }
653 end:
655 /*      if (nResult < 0) {
656                 if (pTAS2563->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
657                         failsafe(pTAS2563);
658         }
659 */
660         return nResult;
663 static int tas2563_load_calibration(struct tas2563_priv *pTAS2563,      char *pFileName)
665         int nResult = 0;
667         int nFile;
668         mm_segment_t fs;
669         unsigned char pBuffer[1000];
670         int nSize = 0;
672         dev_info(pTAS2563->dev, "%s:\n", __func__);
674         fs = get_fs();
675         set_fs(KERNEL_DS);
676         nFile = sys_open(pFileName, O_RDONLY, 0);
678         dev_info(pTAS2563->dev, "TAS2563 calibration file = %s, handle = %d\n",
679                 pFileName, nFile);
681         if (nFile >= 0) {
682                 nSize = sys_read(nFile, pBuffer, 1000);
683                 sys_close(nFile);
684         } else {
685                 dev_err(pTAS2563->dev, "TAS2563 cannot open calibration file: %s\n",
686                         pFileName);
687         }
689         set_fs(fs);
691         if (!nSize)
692                 goto end;
694         tas2563_clear_firmware(pTAS2563->mpCalFirmware);
695         dev_info(pTAS2563->dev, "TAS2563 calibration file size = %d\n", nSize);
696         nResult = fw_parse(pTAS2563, pTAS2563->mpCalFirmware, pBuffer, nSize);
698         if (nResult)
699                 dev_err(pTAS2563->dev, "TAS2563 calibration file is corrupt\n");
700         else
701                 dev_info(pTAS2563->dev, "TAS2563 calibration: %d calibrations\n",
702                         pTAS2563->mpCalFirmware->mnCalibrations);
703 end:
705         return nResult;
708 static int tas2563_codec_write(struct snd_soc_codec *codec, unsigned int reg,
709         unsigned int value)
711         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
713         int nResult = 0;
715         nResult = pTAS2563->write(pTAS2563, reg, value);
716         if (nResult < 0)
717                 dev_err(pTAS2563->dev, "%s, ERROR, reg=0x%x, E=%d\n",
718                         __func__, reg, nResult);
719         else
720                 dev_info(pTAS2563->dev, "%s, reg: 0x%x, 0x%x\n",
721                         __func__, reg, value);
723         return nResult;
727 static void fw_print_header(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware)
729         dev_info(pTAS2563->dev, "FW Size       = %d", pFirmware->mnFWSize);
730         dev_info(pTAS2563->dev, "Checksum      = 0x%04X", pFirmware->mnChecksum);
731         dev_info(pTAS2563->dev, "PPC Version   = 0x%04X", pFirmware->mnPPCVersion);
732         dev_info(pTAS2563->dev, "FW  Version    = 0x%04X", pFirmware->mnFWVersion);
733         dev_info(pTAS2563->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
734         dev_info(pTAS2563->dev, "Timestamp     = %d", pFirmware->mnTimeStamp);
735         dev_info(pTAS2563->dev, "DDC Name      = %s", pFirmware->mpDDCName);
736         dev_info(pTAS2563->dev, "Description   = %s", pFirmware->mpDescription);
739 inline unsigned int fw_convert_number(unsigned char *pData)
741         return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
744 static int fw_parse_header(struct tas2563_priv *pTAS2563,
745         struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
747         unsigned char *pDataStart = pData;
748         unsigned int n;
749         unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
751         if (nSize < 104) {
752                 dev_err(pTAS2563->dev, "Firmware: Header too short");
753                 return -EINVAL;
754         }
756         if (memcmp(pData, pMagicNumber, 4)) {
757                 dev_err(pTAS2563->dev, "Firmware: Magic number doesn't match");
758                 return -EINVAL;
759         }
760         pData += 4;
762         pFirmware->mnFWSize = fw_convert_number(pData);
763         pData += 4;
764         dev_info(pTAS2563->dev, "firmware size: %d", pFirmware->mnFWSize);
766         pFirmware->mnChecksum = fw_convert_number(pData);
767         pData += 4;
769         pFirmware->mnPPCVersion = fw_convert_number(pData);
770         pData += 4;
772         pFirmware->mnFWVersion = fw_convert_number(pData);
773         pData += 4;
775         pFirmware->mnDriverVersion = fw_convert_number(pData);
776         pData += 4;
778         pFirmware->mnTimeStamp = fw_convert_number(pData);
779         pData += 4;
780         dev_info(pTAS2563->dev, "FW timestamp: %d", pFirmware->mnTimeStamp);
782         memcpy(pFirmware->mpDDCName, pData, 64);
783         pData += 64;
785         n = strlen(pData);
786         pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
787         pData += n + 1;
788         if ((pData - pDataStart) >= nSize) {
789                 dev_err(pTAS2563->dev, "Firmware: Header too short after DDC description");
790                 return -EINVAL;
791         }
793         pFirmware->mnDeviceFamily = fw_convert_number(pData);
794         pData += 4;
795         if (pFirmware->mnDeviceFamily != 0) {
796                 dev_err(pTAS2563->dev,
797                         "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
798                 return -EINVAL;
799         }
801         pFirmware->mnDevice = fw_convert_number(pData);
802         pData += 4;
804         if (pFirmware->mnDevice != 5) {
805                 dev_err(pTAS2563->dev,
806                         "device %d, not TAS2563", pFirmware->mnDevice);
807                 return -EINVAL;
808         }
810         fw_print_header(pTAS2563, pFirmware);
811         return pData - pDataStart;
814 static int fw_parse_block_data(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware,
815         struct TBlock *pBlock, unsigned char *pData)
817         unsigned char *pDataStart = pData;
818         unsigned int n;
820         dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
822         pBlock->mnType = fw_convert_number(pData);
823         pData += 4;
824         dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
826         if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) {
827                 pBlock->mbPChkSumPresent = pData[0];
828                 pData++;
830                 pBlock->mnPChkSum = pData[0];
831                 pData++;
833                 pBlock->mbYChkSumPresent = pData[0];
834                 pData++;
836                 pBlock->mnYChkSum = pData[0];
837                 pData++;
838         } else {
839                 pBlock->mbPChkSumPresent = 0;
840                 pBlock->mbYChkSumPresent = 0;
841         }
843         pBlock->mnCommands = fw_convert_number(pData);
844         pData += 4;
846         n = pBlock->mnCommands * 4;
847         pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
848         pData += n;
849         dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
850         return pData - pDataStart;
853 static int fw_parse_data(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware,
854         struct TData *pImageData, unsigned char *pData)
856         unsigned char *pDataStart = pData;
857         unsigned int nBlock;
858         unsigned int n;
860         dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
861         memcpy(pImageData->mpName, pData, 64);
862         pData += 64;
864         n = strlen(pData);
865         pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
866         pData += n + 1;
868         pImageData->mnBlocks = (pData[0] << 8) + pData[1];
869         pData += 2;
871         pImageData->mpBlocks =
872                 kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
874         for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
875                 n = fw_parse_block_data(pTAS2563, pFirmware,
876                         &(pImageData->mpBlocks[nBlock]), pData);
877                 pData += n;
878         }
879         return pData - pDataStart;
882 static int fw_parse_program_data(struct tas2563_priv *pTAS2563,
883         struct TFirmware *pFirmware, unsigned char *pData)
885         unsigned char *pDataStart = pData;
886         unsigned int n;
887         unsigned int nProgram;
888         struct TProgram *pProgram;
890         pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
891         pData += 2;
893         if (pFirmware->mnPrograms == 0)
894                 goto end;
896         pFirmware->mpPrograms =
897                 kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
898         for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
899                 pProgram = &(pFirmware->mpPrograms[nProgram]);
900                 memcpy(pProgram->mpName, pData, 64);
901                 pData += 64;
903                 n = strlen(pData);
904                 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
905                 pData += n + 1;
907                 pProgram->mnAppMode = pData[0];
908                 pData++;
910                 pProgram->mnI2sMode = pData[0];
911                 pData++;
912                 dev_info(pTAS2563->dev, "FW i2sMode: %d", pProgram->mnI2sMode);
914                 pProgram->mnISnsPD = pData[0];
915                 pData++;
917                 pProgram->mnVSnsPD = pData[0];
918                 pData++;
920                 pProgram->mnPowerLDG = pData[0];
921                 pData++;
923                 n = fw_parse_data(pTAS2563, pFirmware, &(pProgram->mData), pData);
924                 pData += n;
925                 dev_info(pTAS2563->dev, "program data number: %d", n);
926         }
928 end:
930         return pData - pDataStart;
933 static int fw_parse_configuration_data(struct tas2563_priv *pTAS2563,
934         struct TFirmware *pFirmware, unsigned char *pData)
936         unsigned char *pDataStart = pData;
937         unsigned int n;
938         unsigned int nConfiguration;
939         struct TConfiguration *pConfiguration;
941         pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
942         pData += 2;
944         if (pFirmware->mnConfigurations == 0)
945                 goto end;
947         pFirmware->mpConfigurations =
948                 kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
949                 GFP_KERNEL);
950         for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
951                 nConfiguration++) {
952                 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
953                 memcpy(pConfiguration->mpName, pData, 64);
954                 pData += 64;
956                 n = strlen(pData);
957                 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
958                 pData += n + 1;
960 /*
961                 if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV)
962                         || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC)
963                                 && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) {*/
964                         pConfiguration->mnDevices = (pData[0] << 8) + pData[1];
965                         pData += 2;
966 /*              } else
967                         pConfiguration->mnDevices = 1;*/
969                 pConfiguration->mnProgram = pData[0];
970                 pData++;
971                 dev_info(pTAS2563->dev, "configuration, mnProgram: %d", pConfiguration->mnProgram);
973                 pConfiguration->mnSamplingRate = fw_convert_number(pData);
974                 pData += 4;
975                 dev_info(pTAS2563->dev, "configuration samplerate: %d", pConfiguration->mnSamplingRate);
977                 //if (pFirmware->mnDriverVersion >= PPC_DRIVER_MTPLLSRC) {
978                         pConfiguration->mnPLLSrc = pData[0];
979                         pData++;
981                         pConfiguration->mnPLLSrcRate = fw_convert_number(pData);
982                         pData += 4;
983                 //}
985                 pConfiguration->mnFsRate = (pData[0] << 8) + pData[1];
986                 pData += 2;
987                 dev_info(pTAS2563->dev, "Fs rate: %d", pConfiguration->mnFsRate);
989                 n = fw_parse_data(pTAS2563, pFirmware, &(pConfiguration->mData), pData);
990                 pData += n;
991         }
993 end:
995         return pData - pDataStart;
998 int fw_parse_calibration_data(struct tas2563_priv *pTAS2563,
999         struct TFirmware *pFirmware, unsigned char *pData)
1001         unsigned char *pDataStart = pData;
1002         unsigned int n;
1003         unsigned int nCalibration;
1004         struct TCalibration *pCalibration;
1006         pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
1007         pData += 2;
1009         if (pFirmware->mnCalibrations == 0)
1010                 goto end;
1012         pFirmware->mpCalibrations =
1013                 kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
1014         for (nCalibration = 0;
1015                 nCalibration < pFirmware->mnCalibrations;
1016                 nCalibration++) {
1017                 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
1018                 memcpy(pCalibration->mpName, pData, 64);
1019                 pData += 64;
1021                 n = strlen(pData);
1022                 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1023                 pData += n + 1;
1025                 pCalibration->mnProgram = pData[0];
1026                 pData++;
1028                 pCalibration->mnConfiguration = pData[0];
1029                 pData++;
1031                 n = fw_parse_data(pTAS2563, pFirmware, &(pCalibration->mData), pData);
1032                 pData += n;
1033         }
1035 end:
1037         return pData - pDataStart;
1040 static int fw_parse(struct tas2563_priv *pTAS2563,
1041         struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
1043         int nPosition = 0;
1045         nPosition = fw_parse_header(pTAS2563, pFirmware, pData, nSize);
1046         dev_info(pTAS2563->dev, "header size: %d, line: %d\n", nPosition, __LINE__);
1047         if (nPosition < 0) {
1048                 dev_err(pTAS2563->dev, "Firmware: Wrong Header");
1049                 return -EINVAL;
1050         }
1052         if (nPosition >= nSize) {
1053                 dev_err(pTAS2563->dev, "Firmware: Too short");
1054                 return -EINVAL;
1055         }
1057         pData += nPosition;
1058         nSize -= nPosition;
1059         nPosition = 0;
1061         nPosition = fw_parse_program_data(pTAS2563, pFirmware, pData);
1062         dev_info(pTAS2563->dev, "program size: %d, line: %d\n", nPosition, __LINE__);
1064         pData += nPosition;
1065         nSize -= nPosition;
1066         nPosition = 0;
1068         nPosition = fw_parse_configuration_data(pTAS2563, pFirmware, pData);
1069         dev_info(pTAS2563->dev, "config size: %d, line: %d\n", nPosition, __LINE__);
1071         pData += nPosition;
1072         nSize -= nPosition;
1073         nPosition = 0;
1075         if (nSize > 64)
1076                 nPosition = fw_parse_calibration_data(pTAS2563, pFirmware, pData);
1077         dev_info(pTAS2563->dev, "calib size: %d, line: %d\n", nPosition, __LINE__);
1078         return 0;
1082 static int tas2563_codec_suspend(struct snd_soc_codec *codec)
1084         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1085         int ret = 0;
1087         mutex_lock(&pTAS2563->codec_lock);
1089         dev_info(pTAS2563->dev, "%s\n", __func__);
1090         pTAS2563->runtime_suspend(pTAS2563);
1092         mutex_unlock(&pTAS2563->codec_lock);
1093         return ret;
1096 static int tas2563_codec_resume(struct snd_soc_codec *codec)
1098         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1099         int ret = 0;
1101         mutex_lock(&pTAS2563->codec_lock);
1103         dev_info(pTAS2563->dev, "%s\n", __func__);
1104         pTAS2563->runtime_resume(pTAS2563);
1106         mutex_unlock(&pTAS2563->codec_lock);
1107         return ret;
1110 static int tas2563_set_power_state(struct tas2563_priv *pTAS2563, int state)
1112         int nResult = 0;
1113         /*unsigned int nValue;*/
1114         const char *pFWName;
1115         struct TProgram *pProgram;
1117         dev_info(pTAS2563->dev, "set power state: %d\n", state);
1119         if ((pTAS2563->mpFirmware->mnPrograms == 0)
1120                 || (pTAS2563->mpFirmware->mnConfigurations == 0)) {
1121                 dev_err(pTAS2563->dev, "%s, firmware not loaded\n", __func__);
1122                 pFWName = TAS2563_FW_NAME;
1123                 nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName,
1124                         pTAS2563->dev, GFP_KERNEL, pTAS2563, tas2563_fw_ready);
1126                 if(nResult < 0) {
1127                         dev_err(pTAS2563->dev, "%s, firmware is loaded, %d\n", __func__, nResult);
1128                         goto end;
1129                 }
1130         }
1131         /* check safe guard*/
1132         /* TBD, add back when FW ready
1133         nResult = pTAS2563->read(pTAS2563, TAS2563_SAFE_GUARD_REG, &nValue);
1134         if (nResult < 0)
1135                 goto end;
1136         if ((nValue&0xff) != TAS2563_SAFE_GUARD_PATTERN) {
1137                 dev_err(pTAS2563->dev, "ERROR safe guard failure!\n");
1138                 nResult = -EPIPE;
1139                 goto end;
1140         }
1141         */
1143         pProgram = &(pTAS2563->mpFirmware->mpPrograms[pTAS2563->mnCurrentProgram]);
1144         dev_info(pTAS2563->dev, "%s, state: %d, mbPowerup %d\n", __func__, state, pTAS2563->mbPowerUp);
1145         if (state != TAS2563_POWER_SHUTDOWN) {
1146                 if (!pTAS2563->mbPowerUp) {
1147                         if (!pTAS2563->mbCalibrationLoaded) {
1148                                 nResult = tas2563_set_calibration(pTAS2563, 0xFF);
1149                                 if((nResult > 0) || (nResult == 0))
1150                                         pTAS2563->mbCalibrationLoaded = true;
1151                         }
1153                         if (pTAS2563->mbLoadConfigurationPrePowerUp) {
1154                                 dev_info(pTAS2563->dev, "load coefficient before power\n");
1155                                 pTAS2563->mbLoadConfigurationPrePowerUp = false;
1156                                 nResult = tas2563_load_coefficient(pTAS2563,
1157                                         pTAS2563->mnCurrentConfiguration, pTAS2563->mnNewConfiguration, false);
1158                                 if (nResult < 0)
1159                                         goto end;
1160                         }
1161                 }
1162         }
1164         switch (state) {
1165         case TAS2563_POWER_ACTIVE:
1166                 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1167                         TAS2563_PowerControl_OperationalMode10_Mask |
1168                         TAS2563_PowerControl_ISNSPower_Mask |
1169                         TAS2563_PowerControl_VSNSPower_Mask,
1170                         TAS2563_PowerControl_OperationalMode10_Active |
1171                         TAS2563_PowerControl_VSNSPower_Active |
1172                         TAS2563_PowerControl_ISNSPower_Active);
1173                 if (nResult < 0)
1174                         return nResult;
1175                 pTAS2563->mbPowerUp = true;
1176                 dev_info(pTAS2563->dev, "set ICN to -90dB\n");
1177                 nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_ICN_REG, pICN, 4);
1178                 if(nResult < 0)
1179                         return nResult;
1181                 dev_info(pTAS2563->dev, "set ICN delay\n");
1182                 nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_ICN_DELAY, pICNDelay, 4);
1183                 break;
1185         case TAS2563_POWER_MUTE:
1186                 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1187                         TAS2563_PowerControl_OperationalMode10_Mask |
1188                         TAS2563_PowerControl_ISNSPower_Mask |
1189                         TAS2563_PowerControl_VSNSPower_Mask,
1190                         TAS2563_PowerControl_OperationalMode10_Mute |
1191                         TAS2563_PowerControl_VSNSPower_Active |
1192                         TAS2563_PowerControl_ISNSPower_Active);
1193                         pTAS2563->mbPowerUp = true;
1194                 break;
1196         case TAS2563_POWER_SHUTDOWN:
1197                 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1198                         TAS2563_PowerControl_OperationalMode10_Mask,
1199                         TAS2563_PowerControl_OperationalMode10_Shutdown);
1200                         pTAS2563->mbPowerUp = false;
1201                 break;
1203         default:
1204                 dev_err(pTAS2563->dev, "wrong power state setting %d\n", state);
1206         }
1208 end:
1209         pTAS2563->mnPowerState = state;
1210         return nResult;
1213 static int tas2563_dac_event(struct snd_soc_dapm_widget *w,
1214                         struct snd_kcontrol *kcontrol, int event)
1216 #ifdef KCONTROL_CODEC
1217         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1218 #else
1219         struct snd_soc_codec *codec = w->codec;
1220 #endif
1221         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1223         switch (event) {
1224         case SND_SOC_DAPM_POST_PMU:
1225                 dev_info(pTAS2563->dev, "SND_SOC_DAPM_POST_PMU\n");
1226                 break;
1227         case SND_SOC_DAPM_PRE_PMD:
1228                 dev_info(pTAS2563->dev, "SND_SOC_DAPM_PRE_PMD\n");
1229                 break;
1230         }
1232         return 0;
1235 static const struct snd_soc_dapm_widget tas2563_dapm_widgets[] = {
1236         SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
1237         SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2563_dac_event,
1238         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1239         SND_SOC_DAPM_OUTPUT("OUT"),
1240         SND_SOC_DAPM_SIGGEN("VMON"),
1241         SND_SOC_DAPM_SIGGEN("IMON")
1242 };
1244 static const struct snd_soc_dapm_route tas2563_audio_map[] = {
1245         {"DAC", NULL, "ASI1"},
1246         {"OUT", NULL, "DAC"},
1247 };
1249 static int tas2563_mute(struct snd_soc_dai *dai, int mute)
1251         struct snd_soc_codec *codec = dai->codec;
1252         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1254         dev_info(pTAS2563->dev, "%s\n", __func__);
1255         mutex_lock(&pTAS2563->codec_lock);
1256         if (mute) {
1257                 dev_info(pTAS2563->dev, "mute: %s\n", __func__);
1258                 tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1259         } else {
1260                 dev_info(pTAS2563->dev, "unmute: %s\n", __func__);
1261                 tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
1262         }
1263         mutex_unlock(&pTAS2563->codec_lock);
1264         return 0;
1268 static int tas2563_slot_config(struct snd_soc_codec *codec, struct tas2563_priv *pTAS2563, int blr_clk_ratio)
1270         int ret = 0;
1271         pTAS2563->update_bits(pTAS2563,
1272                         TAS2563_TDMConfigurationReg5, 0xff, 0x42);
1274         pTAS2563->update_bits(pTAS2563,
1275                         TAS2563_TDMConfigurationReg6, 0xff, 0x40);
1277         return ret;
1280 static int tas2563_set_slot(struct tas2563_priv *pTAS2563, int slot_width)
1282         int ret = 0;
1283         dev_info(pTAS2563->dev, "%s, slot_width:%d\n", __func__, slot_width);
1285         switch (slot_width) {
1286         case 16:
1287         ret = pTAS2563->update_bits(pTAS2563, 
1288                 TAS2563_TDMConfigurationReg2,
1289                 TAS2563_TDMConfigurationReg2_RXSLEN10_Mask,
1290                 TAS2563_TDMConfigurationReg2_RXSLEN10_16Bits);
1291         break;
1293         case 24:
1294         ret = pTAS2563->update_bits(pTAS2563, 
1295                 TAS2563_TDMConfigurationReg2,
1296                 TAS2563_TDMConfigurationReg2_RXSLEN10_Mask,
1297                 TAS2563_TDMConfigurationReg2_RXSLEN10_24Bits);
1298         break;
1300         case 32:
1301         ret = pTAS2563->update_bits(pTAS2563, 
1302                 TAS2563_TDMConfigurationReg2,
1303                 TAS2563_TDMConfigurationReg2_RXSLEN10_Mask,
1304                 TAS2563_TDMConfigurationReg2_RXSLEN10_32Bits);
1305         break;
1307         case 0:
1308         /* Do not change slot width */
1309         break;
1311         default:
1312                 dev_info(pTAS2563->dev, "slot width not supported");
1313                 ret = -EINVAL;
1314         }
1316         if (ret >= 0)
1317                 pTAS2563->mnSlot_width = slot_width;
1319         return ret;
1322 static int tas2563_set_bitwidth(struct tas2563_priv *pTAS2563, int bitwidth)
1324         int slot_width_tmp = 0;
1325         dev_info(pTAS2563->dev, "%s %d\n", __func__, __LINE__);
1327         switch (bitwidth) {
1328         case SNDRV_PCM_FORMAT_S16_LE:
1329                         pTAS2563->update_bits(pTAS2563, 
1330                         TAS2563_TDMConfigurationReg2,
1331                         TAS2563_TDMConfigurationReg2_RXWLEN32_Mask,
1332                         TAS2563_TDMConfigurationReg2_RXWLEN32_16Bits);
1333                         pTAS2563->mnCh_size = 16;
1334                         if (pTAS2563->mnSlot_width == 0)
1335                                 slot_width_tmp = 16;
1336                 break;
1337         case SNDRV_PCM_FORMAT_S24_LE:
1338                         pTAS2563->update_bits(pTAS2563, 
1339                         TAS2563_TDMConfigurationReg2,
1340                         TAS2563_TDMConfigurationReg2_RXWLEN32_Mask,
1341                         TAS2563_TDMConfigurationReg2_RXWLEN32_24Bits);
1342                         pTAS2563->mnCh_size = 24;
1343                         if (pTAS2563->mnSlot_width == 0)
1344                                 slot_width_tmp = 32;
1345                 break;
1346         case SNDRV_PCM_FORMAT_S32_LE:
1347                         pTAS2563->update_bits(pTAS2563,
1348                         TAS2563_TDMConfigurationReg2,
1349                         TAS2563_TDMConfigurationReg2_RXWLEN32_Mask,
1350                         TAS2563_TDMConfigurationReg2_RXWLEN32_32Bits);
1351                         pTAS2563->mnCh_size = 32;
1352                         if (pTAS2563->mnSlot_width == 0)
1353                                 slot_width_tmp = 32;
1354                 break;
1356         default:
1357                 dev_info(pTAS2563->dev, "Not supported params format\n");
1358         }
1360         /* If machine driver did not call set slot width */
1361         if (pTAS2563->mnSlot_width == 0)
1362                 tas2563_set_slot(pTAS2563, slot_width_tmp);
1364         dev_info(pTAS2563->dev, "mnCh_size: %d\n", pTAS2563->mnCh_size);
1365         pTAS2563->mnPCMFormat = bitwidth;
1367         return 0;
1370 static int tas2563_set_samplerate(struct tas2563_priv *pTAS2563, int samplerate)
1372         switch (samplerate) {
1373         case 48000:
1374                         pTAS2563->update_bits(pTAS2563,
1375                                 TAS2563_TDMConfigurationReg0,
1376                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1377                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
1378                         pTAS2563->update_bits(pTAS2563,
1379                                 TAS2563_TDMConfigurationReg0,
1380                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1381                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
1382                         break;
1383         case 44100:
1384                         pTAS2563->update_bits(pTAS2563,
1385                                 TAS2563_TDMConfigurationReg0,
1386                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1387                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
1388                         pTAS2563->update_bits(pTAS2563,
1389                                 TAS2563_TDMConfigurationReg0,
1390                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1391                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
1392                         break;
1393         case 96000:
1394                         pTAS2563->update_bits(pTAS2563,
1395                                 TAS2563_TDMConfigurationReg0,
1396                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1397                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
1398                         pTAS2563->update_bits(pTAS2563,
1399                                 TAS2563_TDMConfigurationReg0,
1400                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1401                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
1402                         break;
1403         case 88200:
1404                         pTAS2563->update_bits(pTAS2563,
1405                                 TAS2563_TDMConfigurationReg0,
1406                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1407                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
1408                         pTAS2563->update_bits(pTAS2563,
1409                                 TAS2563_TDMConfigurationReg0,
1410                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1411                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
1412                         break;
1413         case 19200:
1414                         pTAS2563->update_bits(pTAS2563,
1415                                 TAS2563_TDMConfigurationReg0,
1416                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1417                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
1418                         pTAS2563->update_bits(pTAS2563,
1419                                 TAS2563_TDMConfigurationReg0,
1420                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1421                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
1422                         break;
1423         case 17640:
1424                         pTAS2563->update_bits(pTAS2563,
1425                                 TAS2563_TDMConfigurationReg0,
1426                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1427                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
1428                         pTAS2563->update_bits(pTAS2563,
1429                                 TAS2563_TDMConfigurationReg0,
1430                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1431                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
1432                         break;
1433         default:
1434                         dev_info(pTAS2563->dev, "%s, unsupported sample rate, %d\n", __func__, samplerate);
1436         }
1438         pTAS2563->mnSamplingRate = samplerate;
1439         return 0;
1442 int tas2563_load_default(struct tas2563_priv *pTAS2563)
1444         int ret = 0;
1445         
1446         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1448         ret = tas2563_set_slot(pTAS2563, pTAS2563->mnSlot_width);
1449         if (ret < 0)
1450                 goto end;
1451         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1453         /* proper TX format */
1454         ret = pTAS2563->write(pTAS2563, TAS2563_TDMConfigurationReg4, 0x01);
1455         if(ret < 0)
1456                 goto end;
1458         /*if setting format was not called by asoc, then set it default*/
1459         if(pTAS2563->mnASIFormat == 0)
1460                 pTAS2563->mnASIFormat = SND_SOC_DAIFMT_CBS_CFS 
1461                                 | SND_SOC_DAIFMT_IB_NF 
1462                                 | SND_SOC_DAIFMT_I2S;
1463         ret = tas2563_set_fmt(pTAS2563, pTAS2563->mnASIFormat);
1465         if (ret < 0)
1466                 goto end;
1467         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1469         ret = tas2563_set_bitwidth(pTAS2563, pTAS2563->mnPCMFormat);
1470         if (ret < 0)
1471                 goto end;
1472         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1474         ret = tas2563_set_samplerate(pTAS2563, pTAS2563->mnSamplingRate);
1475         if (ret < 0)
1476                 goto end;
1478 end:
1479 /* power up failed, restart later */
1480         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1481         if (ret < 0)
1482                 schedule_delayed_work(&pTAS2563->irq_work,
1483                                 msecs_to_jiffies(1000));
1484         return ret;
1487 #if 0
1488 static void failsafe(struct tas2563_priv *pTAS2563)
1490         dev_err(pTAS2563->dev, "%s\n", __func__);
1491         pTAS2563->mnErrCode |= ERROR_FAILSAFE;
1492         if (hrtimer_active(&pTAS2563->mtimerwork))
1493                 hrtimer_cancel(&pTAS2563->mtimerwork);
1495         if(pTAS2563->mnRestart < RESTART_MAX)
1496         {
1497                 pTAS2563->mnRestart ++;
1498                 msleep(100);
1499                 dev_err(pTAS2563->dev, "I2C COMM error, restart SmartAmp.\n");
1500                 schedule_delayed_work(&pTAS2563->irq_work, msecs_to_jiffies(100));
1501                 return;
1502         }
1503         pTAS2563->enableIRQ(pTAS2563, false);
1504         tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1506         pTAS2563->mbPowerUp = false;
1507         pTAS2563->hw_reset(pTAS2563);
1508         pTAS2563->write(pTAS2563, TAS2563_SoftwareReset, TAS2563_SoftwareReset_SoftwareReset_Reset);
1509         udelay(1000);
1510         if (pTAS2563->mpFirmware != NULL)
1511                 tas2563_clear_firmware(pTAS2563->mpFirmware);
1513 #endif
1515 /*
1516 * tas2563_load_coefficient
1517 */
1518 static int tas2563_load_coefficient(struct tas2563_priv *pTAS2563,
1519         int nPrevConfig, int nNewConfig, bool bPowerOn)
1521         int nResult = 0;
1522 //      struct TPLL *pPLL;
1523         struct TProgram *pProgram;
1524         struct TConfiguration *pPrevConfiguration;
1525         struct TConfiguration *pNewConfiguration;
1526         bool bRestorePower = false;
1528         if (!pTAS2563->mpFirmware->mnConfigurations) {
1529                 dev_err(pTAS2563->dev, "%s, firmware not loaded\n", __func__);
1530                 goto end;
1531         }
1533         if (nNewConfig >= pTAS2563->mpFirmware->mnConfigurations) {
1534                 dev_err(pTAS2563->dev, "%s, invalid configuration New=%d, total=%d\n",
1535                         __func__, nNewConfig, pTAS2563->mpFirmware->mnConfigurations);
1536                 goto end;
1537         }
1539         if (nPrevConfig < 0)
1540                 pPrevConfiguration = NULL;
1541         else if (nPrevConfig == nNewConfig) {
1542                 dev_info(pTAS2563->dev, "%s, config [%d] already loaded\n",
1543                         __func__, nNewConfig);
1544                 goto end;
1545         } else
1546                 pPrevConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[nPrevConfig]);
1548         pNewConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[nNewConfig]);
1549         pTAS2563->mnCurrentConfiguration = nNewConfig;
1550         pTAS2563->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
1552         dev_info(pTAS2563->dev, "load configuration %s conefficient pre block\n",
1553                 pNewConfiguration->mpName);
1554         nResult = tas2563_load_data(pTAS2563, &(pNewConfiguration->mData), TAS2563_BLOCK_CFG_PRE_DEV_A);
1555         if (nResult < 0)
1556                 goto end;
1558 //prog_coefficient:
1559         dev_info(pTAS2563->dev, "load new configuration: %s, coeff block data\n",
1560                 pNewConfiguration->mpName);
1561         nResult = tas2563_load_data(pTAS2563, &(pNewConfiguration->mData),
1562                 TAS2563_BLOCK_CFG_COEFF_DEV_A);
1563         if (nResult < 0)
1564                 goto end;
1566         if (pTAS2563->mpCalFirmware->mnCalibrations) {
1567                 nResult = tas2563_set_calibration(pTAS2563, pTAS2563->mnCurrentCalibration);
1568                 if (nResult < 0)
1569                         goto end;
1570         }
1572         if (bRestorePower) {
1573                 pTAS2563->clearIRQ(pTAS2563);
1574                 dev_info(pTAS2563->dev, "device powered up, load startup\n");
1575                 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_MUTE);
1576                 if (nResult < 0)
1577                         goto end;
1579                 dev_info(pTAS2563->dev,
1580                         "device powered up, load unmute\n");
1581                 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
1582                 if (nResult < 0)
1583                         goto end;
1584                 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1585                         pTAS2563->enableIRQ(pTAS2563, true);
1586                         if (!hrtimer_active(&pTAS2563->mtimerwork)) {
1587                                 pTAS2563->mnDieTvReadCounter = 0;
1588                                 hrtimer_start(&pTAS2563->mtimerwork,
1589                                         ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1590                         }
1591                 }
1592         }
1593 end:
1595         pTAS2563->mnNewConfiguration = pTAS2563->mnCurrentConfiguration;
1596         return nResult;
1599 static bool tas2563_get_coefficient_in_data(struct tas2563_priv *pTAS2563,
1600         struct TData *pData, int blockType, int nReg, int *pnValue)
1602         bool bFound = false;
1603         struct TBlock *pBlock;
1604         int i;
1606         for (i = 0; i < pData->mnBlocks; i++) {
1607                 pBlock = &(pData->mpBlocks[i]);
1608                 if (pBlock->mnType == blockType) {
1609                         bFound = tas2563_get_coefficient_in_block(pTAS2563,
1610                                                 pBlock, nReg, pnValue);
1611                         if (bFound)
1612                                 break;
1613                 }
1614         }
1616         return bFound;
1619 static bool tas2563_find_Tmax_in_configuration(struct tas2563_priv *pTAS2563,
1620         struct TConfiguration *pConfiguration, int *pnTMax)
1622         struct TData *pData;
1623         bool bFound = false;
1624         int nBlockType, nReg, nCoefficient;
1626         nReg = TAS2563_CALI_T_REG;
1628         nBlockType = TAS2563_BLOCK_CFG_COEFF_DEV_A;
1630         pData = &(pConfiguration->mData);
1631         bFound = tas2563_get_coefficient_in_data(pTAS2563, pData, nBlockType, nReg, &nCoefficient);
1632         if (bFound)
1633                 *pnTMax = nCoefficient;
1635         return bFound;
1638 void tas2563_fw_ready(const struct firmware *pFW, void *pContext)
1640         struct tas2563_priv *pTAS2563 = (struct tas2563_priv *) pContext;
1641         int nResult;
1642         unsigned int nProgram = 0;
1643         unsigned int nSampleRate = 0;
1645 #ifdef CONFIG_TAS2563_CODEC
1646         mutex_lock(&pTAS2563->codec_lock);
1647 #endif
1649 #ifdef CONFIG_TAS2563_MISC
1650         mutex_lock(&pTAS2563->file_lock);
1651 #endif
1653         dev_info(pTAS2563->dev, "%s:\n", __func__);
1655         if (unlikely(!pFW) || unlikely(!pFW->data)) {
1656                 dev_err(pTAS2563->dev, "%s firmware is not loaded.\n",
1657                         TAS2563_FW_NAME);
1658                 goto end;
1659         }
1661         if (pTAS2563->mpFirmware->mpConfigurations) {
1662                 nProgram = pTAS2563->mnCurrentProgram;
1663                 nSampleRate = pTAS2563->mnCurrentSampleRate;
1664                 dev_info(pTAS2563->dev, "clear current firmware\n");
1665                 tas2563_clear_firmware(pTAS2563->mpFirmware);
1666         }
1668         nResult = fw_parse(pTAS2563, pTAS2563->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
1669         release_firmware(pFW);
1670         if (nResult < 0) {
1671                 dev_err(pTAS2563->dev, "firmware is corrupt\n");
1672                 goto end;
1673         }
1675         if (!pTAS2563->mpFirmware->mnPrograms) {
1676                 dev_err(pTAS2563->dev, "firmware contains no programs\n");
1677                 nResult = -EINVAL;
1678                 goto end;
1679         }
1681         if (!pTAS2563->mpFirmware->mnConfigurations) {
1682                 dev_err(pTAS2563->dev, "firmware contains no configurations\n");
1683                 nResult = -EINVAL;
1684                 goto end;
1685         }
1687         if (nProgram >= pTAS2563->mpFirmware->mnPrograms) {
1688                 dev_info(pTAS2563->dev,
1689                         "no previous program, set to default\n");
1690                 nProgram = 0;
1691         }
1693         pTAS2563->mnCurrentSampleRate = nSampleRate;
1694         nResult = tas2563_set_program(pTAS2563, nProgram, -1);
1696 end:
1698 #ifdef CONFIG_TAS2563_CODEC
1699         mutex_unlock(&pTAS2563->codec_lock);
1700 #endif
1702 #ifdef CONFIG_TAS2563_MISC
1703         mutex_unlock(&pTAS2563->file_lock);
1704 #endif
1707 static bool tas2563_get_coefficient_in_block(struct tas2563_priv *pTAS2563,
1708         struct TBlock *pBlock, int nReg, int *pnValue)
1710         int nCoefficient = 0;
1711         bool bFound = false;
1712         unsigned char *pCommands;
1713         int nBook, nPage, nOffset, len;
1714         int i, n;
1716         pCommands = pBlock->mpData;
1717         for (i = 0 ; i < pBlock->mnCommands;) {
1718                 nBook = pCommands[4 * i + 0];
1719                 nPage = pCommands[4 * i + 1];
1720                 nOffset = pCommands[4 * i + 2];
1721                 if ((nOffset < 0x7f) || (nOffset == 0x81))
1722                         i++;
1723                 else if (nOffset == 0x85) {
1724                         len = ((int)nBook << 8) | nPage;
1725                         nBook = pCommands[4 * i + 4];
1726                         nPage = pCommands[4 * i + 5];
1727                         nOffset = pCommands[4 * i + 6];
1728                         n = 4 * i + 7;
1729                         i += 2;
1730                         i += ((len - 1) / 4);
1731                         if ((len - 1) % 4)
1732                                 i++;
1733                         if ((nBook != TAS2563_BOOK_ID(nReg))
1734                                 || (nPage != TAS2563_PAGE_ID(nReg)))
1735                                 continue;
1736                         if (nOffset > TAS2563_PAGE_REG(nReg))
1737                                 continue;
1738                         if ((len + nOffset) >= (TAS2563_PAGE_REG(nReg) + 4)) {
1739                                 n += (TAS2563_PAGE_REG(nReg) - nOffset);
1740                                 nCoefficient = ((int)pCommands[n] << 24)
1741                                                 | ((int)pCommands[n + 1] << 16)
1742                                                 | ((int)pCommands[n + 2] << 8)
1743                                                 | (int)pCommands[n + 3];
1744                                 bFound = true;
1745                                 break;
1746                         }
1747                 } else {
1748                         dev_err(pTAS2563->dev, "%s, format error %d\n", __func__, nOffset);
1749                         break;
1750                 }
1751         }
1753         if (bFound) {
1754                 *pnValue = nCoefficient;
1755                 dev_info(pTAS2563->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", __func__,
1756                         TAS2563_BOOK_ID(nReg), TAS2563_PAGE_ID(nReg), TAS2563_PAGE_REG(nReg),
1757                         nCoefficient);
1758         }
1760         return bFound;
1764 int tas2563_set_program(struct tas2563_priv *pTAS2563,
1765         unsigned int nProgram, int nConfig)
1767         struct TProgram *pProgram;
1768         unsigned int nConfiguration = 0;
1769         unsigned int nSampleRate = 0;
1770         bool bFound = false;
1771         int nResult = 0;
1773         if ((!pTAS2563->mpFirmware->mpPrograms) ||
1774                 (!pTAS2563->mpFirmware->mpConfigurations)) {
1775                 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n", __func__);
1776                 nResult = 0;
1777                 goto end;
1778         }
1780         if (nProgram >= pTAS2563->mpFirmware->mnPrograms) {
1781                 dev_err(pTAS2563->dev, "TAS2563: Program %d doesn't exist\n",
1782                         nProgram);
1783                 nResult = 0;
1784                 goto end;
1785         }
1787         if (nConfig < 0) {
1788                 nConfiguration = 0;
1789                 nSampleRate = pTAS2563->mnCurrentSampleRate;
1790                 while (!bFound && (nConfiguration < pTAS2563->mpFirmware->mnConfigurations)) {
1791                         if (pTAS2563->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
1792                                 if (nSampleRate == 0) {
1793                                         bFound = true;
1794                                         dev_info(pTAS2563->dev, "find default configuration %d\n", nConfiguration);
1795                                 } else if (nSampleRate == pTAS2563->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
1796                                         bFound = true;
1797                                         dev_info(pTAS2563->dev, "find matching configuration %d\n", nConfiguration);
1798                                 } else {
1799                                         nConfiguration++;
1800                                 }
1801                         } else {
1802                                 nConfiguration++;
1803                         }
1804                 }
1805                 if (!bFound) {
1806                         dev_err(pTAS2563->dev,
1807                                 "Program %d, no valid configuration found for sample rate %d, ignore\n",
1808                                 nProgram, nSampleRate);
1809                         nResult = 0;
1810                         goto end;
1811                 }
1812         } else {
1813                 if (pTAS2563->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
1814                         dev_err(pTAS2563->dev, "%s, configuration program doesn't match\n", __func__);
1815                         nResult = 0;
1816                         goto end;
1817                 }
1818                 nConfiguration = nConfig;
1819         }
1821         pProgram = &(pTAS2563->mpFirmware->mpPrograms[nProgram]);
1822         if (pTAS2563->mbPowerUp) {
1823                 dev_info(pTAS2563->dev,
1824                         "device powered up, power down to load program %d (%s)\n",
1825                         nProgram, pProgram->mpName);
1826                 if (hrtimer_active(&pTAS2563->mtimerwork))
1827                         hrtimer_cancel(&pTAS2563->mtimerwork);
1829                 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE)
1830                         pTAS2563->enableIRQ(pTAS2563, false);
1832                 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1833                 if (nResult < 0)
1834                         goto end;
1835         }
1837         pTAS2563->hw_reset(pTAS2563);
1838         nResult = pTAS2563->write(pTAS2563, TAS2563_SoftwareReset, 0x01);
1839         if (nResult < 0)
1840                 goto end;
1841         msleep(1);
1842         nResult = tas2563_load_default(pTAS2563);
1843         if (nResult < 0)
1844                 goto end;
1846         dev_info(pTAS2563->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
1847         nResult = tas2563_load_data(pTAS2563, &(pProgram->mData), TAS2563_BLOCK_PGM_DEV_A);
1848         if (nResult < 0)
1849                 goto end;
1850         pTAS2563->mnCurrentProgram = nProgram;
1852         nResult = tas2563_load_coefficient(pTAS2563, -1, nConfiguration, false);
1853         if (nResult < 0)
1854                 goto end;
1856         // Enable IV data
1857         nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1858                                 TAS2563_PowerControl_ISNSPower_Mask |
1859                                 TAS2563_PowerControl_VSNSPower_Mask,
1860                                 TAS2563_PowerControl_VSNSPower_Active |
1861                                 TAS2563_PowerControl_ISNSPower_Active);
1862         if (nResult < 0)
1863                 dev_info(pTAS2563->dev, "Enable IV Data Failed: %s\n", __func__);
1865         if (pTAS2563->mbPowerUp) {
1866 //              pTAS2563->clearIRQ(pTAS2563);
1867 //              dev_info(pTAS2563->dev, "device powered up, load startup\n");
1868                 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_MUTE);
1870                 if (nResult < 0)
1871                         goto end;
1872                 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1873                         if (nResult < 0) {
1874                                 tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1875                                 pTAS2563->mbPowerUp = false;
1876                                 goto end;
1877                         }
1878                 }
1879                 dev_info(pTAS2563->dev, "device powered up, load unmute\n");
1880                 tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
1881                 if (nResult < 0)
1882                         goto end;
1884                 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1885                         pTAS2563->enableIRQ(pTAS2563, true);
1886                         if (!hrtimer_active(&pTAS2563->mtimerwork)) {
1887                                 pTAS2563->mnDieTvReadCounter = 0;
1888                                 hrtimer_start(&pTAS2563->mtimerwork,
1889                                         ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1890                         }
1891                 }
1892         }
1894 end:
1896 /*      if (nResult < 0) {
1897                 if (pTAS2563->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
1898                         failsafe(pTAS2563);
1899         }*/
1900         return nResult;
1903 static int tas2563_set_calibration(struct tas2563_priv *pTAS2563, int nCalibration)
1905         struct TCalibration *pCalibration = NULL;
1906         struct TConfiguration *pConfiguration;
1907         struct TProgram *pProgram;
1908         int nTmax = 0;
1909         bool bFound = false;
1910         int nResult = 0;
1912         if ((!pTAS2563->mpFirmware->mpPrograms)
1913                 || (!pTAS2563->mpFirmware->mpConfigurations)) {
1914                 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n\r", __func__);
1915                 nResult = 0;
1916                 goto end;
1917         }
1919         if (nCalibration == 0x00FF) {
1920                 nResult = tas2563_load_calibration(pTAS2563, TAS2563_CAL_NAME);
1921                 if (nResult < 0) {
1922                         dev_info(pTAS2563->dev, "load new calibration file %s fail %d\n",
1923                                 TAS2563_CAL_NAME, nResult);
1924                         goto end;
1925                 }
1926                 nCalibration = 0;
1927         }
1929         if (nCalibration >= pTAS2563->mpCalFirmware->mnCalibrations) {
1930                 dev_err(pTAS2563->dev,
1931                         "Calibration %d doesn't exist\n", nCalibration);
1932                 nResult = 0;
1933                 goto end;
1934         }
1936         pTAS2563->mnCurrentCalibration = nCalibration;
1937         if (pTAS2563->mbLoadConfigurationPrePowerUp)
1938                 goto end;
1940         pCalibration = &(pTAS2563->mpCalFirmware->mpCalibrations[nCalibration]);
1941         pProgram = &(pTAS2563->mpFirmware->mpPrograms[pTAS2563->mnCurrentProgram]);
1942         pConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[pTAS2563->mnCurrentConfiguration]);
1943         if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1944                 if (pTAS2563->mbBypassTMax) {
1945                         bFound = tas2563_find_Tmax_in_configuration(pTAS2563, pConfiguration, &nTmax);
1946                         if (bFound && (nTmax == TAS2563_COEFFICIENT_TMAX)) {
1947                                 dev_info(pTAS2563->dev, "%s, config[%s] bypass load calibration\n",
1948                                         __func__, pConfiguration->mpName);
1949                                 goto end;
1950                         }
1951                 }
1953                 dev_info(pTAS2563->dev, "%s, load calibration\n", __func__);
1954                 nResult = tas2563_load_data(pTAS2563, &(pCalibration->mData), TAS2563_BLOCK_CFG_COEFF_DEV_A);
1955                 if (nResult < 0)
1956                         goto end;
1957         }
1959 end:
1960         if (nResult < 0) {
1961                 tas2563_clear_firmware(pTAS2563->mpCalFirmware);
1962                 nResult = tas2563_set_program(pTAS2563, pTAS2563->mnCurrentProgram, pTAS2563->mnCurrentConfiguration);
1963         }
1965         return nResult;
1968 bool tas2563_get_Cali_prm_r0(struct tas2563_priv *pTAS2563, int *prm_r0)
1970         struct TCalibration *pCalibration;
1971         struct TData *pData;
1972         int nReg;
1973         int nCali_Re;
1974         bool bFound = false;
1975         int nBlockType;
1977         if (!pTAS2563->mpCalFirmware->mnCalibrations) {
1978                 dev_err(pTAS2563->dev, "%s, no calibration data\n", __func__);
1979                 goto end;
1980         }
1982         nReg = TAS2563_CALI_R0_REG;
1983         nBlockType = TAS2563_BLOCK_CFG_COEFF_DEV_A;
1985         pCalibration = &(pTAS2563->mpCalFirmware->mpCalibrations[pTAS2563->mnCurrentCalibration]);
1986         pData = &(pCalibration->mData);
1988         bFound = tas2563_get_coefficient_in_data(pTAS2563, pData, nBlockType, nReg, &nCali_Re);
1990 end:
1992         if (bFound)
1993                 *prm_r0 = nCali_Re;
1995         return bFound;
1998 int tas2563_set_config(struct tas2563_priv *pTAS2563, int config)
2000         struct TConfiguration *pConfiguration;
2001         struct TProgram *pProgram;
2002         unsigned int nProgram = pTAS2563->mnCurrentProgram;
2003         unsigned int nConfiguration = config;
2004         int nResult = 0;
2006         if ((!pTAS2563->mpFirmware->mpPrograms) ||
2007                 (!pTAS2563->mpFirmware->mpConfigurations)) {
2008                 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n", __func__);
2009                 nResult = -EINVAL;
2010                 goto end;
2011         }
2013         if (nConfiguration >= pTAS2563->mpFirmware->mnConfigurations) {
2014                 dev_err(pTAS2563->dev, "Configuration %d doesn't exist\n",
2015                         nConfiguration);
2016                 nResult = -EINVAL;
2017                 goto end;
2018         }
2020         pConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[nConfiguration]);
2021         pProgram = &(pTAS2563->mpFirmware->mpPrograms[nProgram]);
2023         if (nProgram != pConfiguration->mnProgram) {
2024                 dev_err(pTAS2563->dev,
2025                         "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
2026                         nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
2027                         nProgram, pProgram->mpName);
2028                 nResult = -EINVAL;
2029                 goto end;
2030         }
2032         nResult = tas2563_load_configuration(pTAS2563, nConfiguration, false);
2034 end:
2036         return nResult;
2039 static int tas2563_configuration_get(struct snd_kcontrol *pKcontrol,
2040         struct snd_ctl_elem_value *pValue)
2042 #ifdef KCONTROL_CODEC
2043         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2044 #else
2045         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2046 #endif
2047         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2049         mutex_lock(&pTAS2563->codec_lock);
2051         pValue->value.integer.value[0] = pTAS2563->mnCurrentConfiguration;
2052         dev_info(pTAS2563->dev, "tas2563_configuration_get = %d\n",
2053                 pTAS2563->mnCurrentConfiguration);
2055         mutex_unlock(&pTAS2563->codec_lock);
2056         return 0;
2059 static int tas2563_configuration_put(struct snd_kcontrol *pKcontrol,
2060         struct snd_ctl_elem_value *pValue)
2062 #ifdef KCONTROL_CODEC
2063         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2064 #else
2065         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2066 #endif
2067         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2068         unsigned int nConfiguration = pValue->value.integer.value[0];
2069         int ret = 0;
2071         mutex_lock(&pTAS2563->codec_lock);
2073         dev_info(pTAS2563->dev, "%s = %d\n", __func__, nConfiguration);
2074         ret = tas2563_set_config(pTAS2563, nConfiguration);
2076         mutex_unlock(&pTAS2563->codec_lock);
2077         return ret;
2081 static int tas2563_hw_params(struct snd_pcm_substream *substream,
2082                 struct snd_pcm_hw_params *params,
2083                 struct snd_soc_dai *dai)
2085         struct snd_soc_codec *codec = dai->codec;
2086         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2087         int ret = 0;
2088         int blr_clk_ratio;
2090         dev_info(pTAS2563->dev, "%s, format: %d\n", __func__,
2091                 params_format(params));
2093         mutex_lock(&pTAS2563->codec_lock);
2095         ret = tas2563_set_bitwidth(pTAS2563, params_format(params));
2096         if(ret < 0)
2097         {
2098                 dev_info(pTAS2563->dev, "set bitwidth failed, %d\n", ret);
2099                 goto ret;
2100         }
2102         blr_clk_ratio = params_channels(params) * pTAS2563->mnCh_size;
2103         dev_info(pTAS2563->dev, "blr_clk_ratio: %d\n", blr_clk_ratio);
2104         if(blr_clk_ratio != 0)
2105                 tas2563_slot_config(pTAS2563->codec, pTAS2563, blr_clk_ratio);
2107         dev_info(pTAS2563->dev, "%s, sample rate: %d\n", __func__,
2108                 params_rate(params));
2110         ret = tas2563_set_samplerate(pTAS2563, params_rate(params));
2112 ret:
2113         mutex_unlock(&pTAS2563->codec_lock);
2114         return ret;
2117 static int tas2563_set_fmt(struct tas2563_priv *pTAS2563, unsigned int fmt)
2119         u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
2120         int ret = 0;
2122         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2123         case SND_SOC_DAIFMT_CBS_CFS:
2124                 asi_cfg_1 = 0x00;
2125                 break;
2126         default:
2127                 dev_err(pTAS2563->dev, "ASI format master is not found\n");
2128                 ret = -EINVAL;
2129         }
2131         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2132         case SND_SOC_DAIFMT_NB_NF:
2133                 dev_info(pTAS2563->dev, "INV format: NBNF\n");
2134                 asi_cfg_1 |= TAS2563_TDMConfigurationReg1_RXEDGE_Rising;
2135                 break;
2136         case SND_SOC_DAIFMT_IB_NF:
2137                 dev_info(pTAS2563->dev, "INV format: IBNF\n");
2138                 asi_cfg_1 |= TAS2563_TDMConfigurationReg1_RXEDGE_Falling;
2139                 break;
2140         default:
2141                 dev_err(pTAS2563->dev, "ASI format Inverse is not found\n");
2142                 ret = -EINVAL;
2143         }
2145         pTAS2563->update_bits(pTAS2563, TAS2563_TDMConfigurationReg1,
2146                 TAS2563_TDMConfigurationReg1_RXEDGE_Mask,
2147                 asi_cfg_1);
2149         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2150         case (SND_SOC_DAIFMT_I2S):
2151                 tdm_rx_start_slot = 1;
2152                 break;
2153         case (SND_SOC_DAIFMT_DSP_A):
2154         case (SND_SOC_DAIFMT_DSP_B):
2155                 tdm_rx_start_slot = 1;
2156                 break;
2157         case (SND_SOC_DAIFMT_LEFT_J):
2158                 tdm_rx_start_slot = 0;
2159                 break;
2160         default:
2161         dev_err(pTAS2563->dev, "DAI Format is not found, fmt=0x%x\n", fmt);
2162         ret = -EINVAL;
2163                 break;
2164         }
2166         pTAS2563->update_bits(pTAS2563, TAS2563_TDMConfigurationReg1,
2167                 TAS2563_TDMConfigurationReg1_RXOFFSET51_Mask,
2168         (tdm_rx_start_slot << TAS2563_TDMConfigurationReg1_RXOFFSET51_Shift));
2170         pTAS2563->mnASIFormat = fmt;
2172         return 0;
2176 static int tas2563_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2178         struct snd_soc_codec *codec = dai->codec;
2179         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2180         int ret = 0;
2182         dev_info(pTAS2563->dev, "%s, format=0x%x\n", __func__, fmt);
2184         mutex_lock(&pTAS2563->codec_lock);
2186         ret = tas2563_set_fmt(pTAS2563, fmt);
2188         mutex_unlock(&pTAS2563->codec_lock);
2189         return ret;
2192 static int tas2563_set_dai_tdm_slot(struct snd_soc_dai *dai,
2193                 unsigned int tx_mask, unsigned int rx_mask,
2194                 int slots, int slot_width)
2196         int ret = 0;
2197         struct snd_soc_codec *codec = dai->codec;
2198         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2200         dev_info(pTAS2563->dev, "%s, tx_mask:%d, rx_mask:%d, slots:%d, slot_width:%d",
2201                         __func__, tx_mask, rx_mask, slots, slot_width);
2203         ret = tas2563_set_slot(pTAS2563, slot_width);
2205         return ret;
2208 static int tas2563_program_get(struct snd_kcontrol *pKcontrol,
2209         struct snd_ctl_elem_value *pValue)
2211 #ifdef KCONTROL_CODEC
2212         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2213 #else
2214         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2215 #endif
2216         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2218         mutex_lock(&pTAS2563->codec_lock);
2220         pValue->value.integer.value[0] = pTAS2563->mnCurrentProgram;
2221         dev_info(pTAS2563->dev, "tas2563_program_get = %d\n",
2222                 pTAS2563->mnCurrentProgram);
2224         mutex_unlock(&pTAS2563->codec_lock);
2225         return 0;
2228 static int tas2563_program_put(struct snd_kcontrol *pKcontrol,
2229         struct snd_ctl_elem_value *pValue)
2231 #ifdef KCONTROL_CODEC
2232         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2233 #else
2234         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2235 #endif
2236         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2237         unsigned int nProgram = pValue->value.integer.value[0];
2238         int ret = 0, nConfiguration = -1;
2240         mutex_lock(&pTAS2563->codec_lock);
2242         if (nProgram == pTAS2563->mnCurrentProgram)
2243                 nConfiguration = pTAS2563->mnCurrentConfiguration;
2244         ret = tas2563_set_program(pTAS2563, nProgram, nConfiguration);
2246         mutex_unlock(&pTAS2563->codec_lock);
2247         return ret;
2250 static int tas2563_calibration_get(struct snd_kcontrol *pKcontrol,
2251         struct snd_ctl_elem_value *pValue)
2253 #ifdef KCONTROL_CODEC
2254         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2255 #else
2256         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2257 #endif
2258         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2260         mutex_lock(&pTAS2563->codec_lock);
2262         pValue->value.integer.value[0] = pTAS2563->mnCurrentCalibration;
2263         dev_info(pTAS2563->dev,
2264                 "tas2563_calibration_get = %d\n",
2265                 pTAS2563->mnCurrentCalibration);
2267         mutex_unlock(&pTAS2563->codec_lock);
2268         return 0;
2271 static int tas2563_calibration_put(struct snd_kcontrol *pKcontrol,
2272         struct snd_ctl_elem_value *pValue)
2274 #ifdef KCONTROL_CODEC
2275         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2276 #else
2277         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2278 #endif
2279         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2280         unsigned int nCalibration = pValue->value.integer.value[0];
2281         int ret = 0;
2283         mutex_lock(&pTAS2563->codec_lock);
2285         ret = tas2563_set_calibration(pTAS2563, nCalibration);
2287         mutex_unlock(&pTAS2563->codec_lock);
2288         return ret;
2291 static struct snd_soc_dai_ops tas2563_dai_ops = {
2292         .digital_mute = tas2563_mute,
2293         .hw_params  = tas2563_hw_params,
2294         .set_fmt    = tas2563_set_dai_fmt,
2295         .set_tdm_slot = tas2563_set_dai_tdm_slot,
2296 };
2298 #define TAS2563_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2299                 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2301 #define TAS2563_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 \
2302                                                 SNDRV_PCM_RATE_88200 |\
2303                                                 SNDRV_PCM_RATE_96000 |\
2304                                                 SNDRV_PCM_RATE_176400 |\
2305                                                 SNDRV_PCM_RATE_192000\
2306                                                 )
2308 static struct snd_soc_dai_driver tas2563_dai_driver[] = {
2309         {
2310                 .name = "tas2563 ASI1",
2311                 .id = 0,
2312                 .playback = {
2313                         .stream_name    = "ASI1 Playback",
2314                         .channels_min   = 2,
2315                         .channels_max   = 2,
2316                         .rates      = SNDRV_PCM_RATE_8000_192000,
2317                         .formats    = TAS2563_FORMATS,
2318                 },
2319                 .capture = {
2320                         .stream_name    = "ASI1 Capture",
2321                         .channels_min   = 0,
2322                         .channels_max   = 2,
2323                         .rates          = SNDRV_PCM_RATE_8000_192000,
2324                         .formats    = TAS2563_FORMATS,
2325                 },
2326                 .ops = &tas2563_dai_ops,
2327                 .symmetric_rates = 1,
2328         },
2329 };
2331 static int tas2563_codec_probe(struct snd_soc_codec *codec)
2333         int ret;
2334         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2336 /*      ret = snd_soc_add_codec_controls(codec, tas2563_controls,
2337                                          ARRAY_SIZE(tas2563_controls));*/
2338         if (ret < 0) {
2339                 pr_err("%s: add_codec_controls failed, err %d\n",
2340                         __func__, ret);
2341                 return ret;
2342         }
2343         pTAS2563->codec = codec;
2344         pTAS2563->set_calibration = tas2563_set_calibration;
2345         pTAS2563->set_config = tas2563_set_config;
2347         dev_err(pTAS2563->dev, "%s\n", __func__);
2349         return 0;
2352 static int tas2563_codec_remove(struct snd_soc_codec *codec)
2354         return 0;
2357 /*static DECLARE_TLV_DB_SCALE(dac_tlv, 0, 100, 0);*/
2358 static DECLARE_TLV_DB_SCALE(tas2563_digital_tlv, 1100, 50, 0);
2360 static const struct snd_kcontrol_new tas2563_snd_controls[] = {
2361         SOC_SINGLE_TLV("Amp Output Level", TAS2563_PlaybackConfigurationReg0,
2362                 0, 0x16, 0,
2363                 tas2563_digital_tlv),
2364         SOC_SINGLE_EXT("Program", SND_SOC_NOPM, 0, 0x00FF, 0, tas2563_program_get,
2365                 tas2563_program_put),
2366         SOC_SINGLE_EXT("Configuration", SND_SOC_NOPM, 0, 0x00FF, 0,
2367                 tas2563_configuration_get, tas2563_configuration_put),
2368         SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0,
2369                 tas2563_calibration_get, tas2563_calibration_put),
2370 };
2372 static struct snd_soc_codec_driver soc_codec_driver_tas2563 = {
2373         .probe                  = tas2563_codec_probe,
2374         .remove                 = tas2563_codec_remove,
2375         .read                   = tas2563_codec_read,
2376         .write                  = tas2563_codec_write,
2377         .suspend                = tas2563_codec_suspend,
2378         .resume                 = tas2563_codec_resume,
2379 #ifdef KCONTROL_CODEC
2380         .component_driver = {
2381 #endif
2382                 .controls               = tas2563_snd_controls,
2383                 .num_controls           = ARRAY_SIZE(tas2563_snd_controls),
2384                 .dapm_widgets           = tas2563_dapm_widgets,
2385                 .num_dapm_widgets       = ARRAY_SIZE(tas2563_dapm_widgets),
2386                 .dapm_routes            = tas2563_audio_map,
2387                 .num_dapm_routes        = ARRAY_SIZE(tas2563_audio_map),
2388 #ifdef KCONTROL_CODEC
2389         },
2390 #endif
2391 };
2393 int tas2563_register_codec(struct tas2563_priv *pTAS2563)
2395         int nResult = 0;
2397         dev_info(pTAS2563->dev, "%s, enter\n", __func__);
2398         nResult = snd_soc_register_codec(pTAS2563->dev,
2399                 &soc_codec_driver_tas2563,
2400                 tas2563_dai_driver, ARRAY_SIZE(tas2563_dai_driver));
2401         return nResult;
2404 int tas2563_deregister_codec(struct tas2563_priv *pTAS2563)
2406         snd_soc_unregister_codec(pTAS2563->dev);
2408         return 0;
2411 MODULE_AUTHOR("Texas Instruments Inc.");
2412 MODULE_DESCRIPTION("TAS2563 ALSA SOC Smart Amplifier driver");
2413 MODULE_LICENSE("GPL v2");
2414 #endif /* CONFIG_TAS2563_CODEC */