return back the modification
[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    "/mnt/vendor/persist/audio/tas2563_cal.bin"
58 #define RESTART_MAX 3
60 #define TAS2563_UDELAY 0xFFFFFFFE
61 #define TAS2563_MDELAY 0xFFFFFFFE
62 #define KCONTROL_CODEC
64 #define TAS2563_BLOCK_PLL                               0x00
65 #define TAS2563_BLOCK_PGM_ALL                   0x0d
66 #define TAS2563_BLOCK_PGM_DEV_A                 0x01
67 #define TAS2563_BLOCK_PGM_DEV_B                 0x08
68 #define TAS2563_BLOCK_CFG_COEFF_DEV_A   0x03
69 #define TAS2563_BLOCK_CFG_COEFF_DEV_B   0x0a
70 #define TAS2563_BLOCK_CFG_PRE_DEV_A             0x04
71 #define TAS2563_BLOCK_CFG_PRE_DEV_B             0x0b
72 #define TAS2563_BLOCK_CFG_POST                  0x05
73 #define TAS2563_BLOCK_CFG_POST_POWER    0x06
75 static int tas2563_set_fmt(struct tas2563_priv *pTAS2563, unsigned int fmt);
76 static void tas2563_clear_firmware(struct TFirmware *pFirmware);
78 static int fw_parse(struct tas2563_priv *pTAS2563,
79         struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize);
80 static bool tas2563_get_coefficient_in_block(struct tas2563_priv *pTAS2563,
81         struct TBlock *pBlock, int nReg, int *pnValue);
82 int tas2563_set_program(struct tas2563_priv *pTAS2563, unsigned int nProgram, int nConfig);
83 static int tas2563_set_calibration(struct tas2563_priv *pTAS2563, int nCalibration);
84 static int tas2563_load_configuration(struct tas2563_priv *pTAS2563,
85         unsigned int nConfiguration, bool bLoadSame);
86 static int tas2563_load_coefficient(struct tas2563_priv *pTAS2563,
87         int nPrevConfig, int nNewConfig, bool bPowerOn);
89 static unsigned int tas2563_codec_read(struct snd_soc_codec *codec,
90                 unsigned int reg)
91 {
92         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
93         int nResult = 0;
94         unsigned int value = 0;
96         nResult = pTAS2563->read(pTAS2563, reg, &value);
98         if (nResult < 0)
99                 dev_err(pTAS2563->dev, "%s, ERROR, reg=0x%x, E=%d\n",
100                         __func__, reg, nResult);
101         else
102                 dev_info(pTAS2563->dev, "%s, reg: 0x%x, value: 0x%x\n",
103                                 __func__, reg, value);
105         if (nResult >= 0)
106                 return value;
107         else
108                 return nResult;
111 static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
112 0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
113 0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
114 0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
115 0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
116 0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
117 0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
118 0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
119 0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
120 0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
121 0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
122 0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
123 0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
124 0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
125 0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
126 0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
127 0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
128 };
130 static int isInPageYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
131         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
133         int nResult = 0;
135         if (nBook == TAS2563_YRAM_BOOK1) {
136                 if (nPage == TAS2563_YRAM1_PAGE) {
137                         if (nReg >= TAS2563_YRAM1_START_REG) {
138                                 pCRCData->mnOffset = nReg;
139                                 pCRCData->mnLen = len;
140                                 nResult = 1;
141                         } else if ((nReg + len) > TAS2563_YRAM1_START_REG) {
142                                 pCRCData->mnOffset = TAS2563_YRAM1_START_REG;
143                                 pCRCData->mnLen = len - (TAS2563_YRAM1_START_REG - nReg);
144                                 nResult = 1;
145                         } else
146                                 nResult = 0;
147                 } else if (nPage == TAS2563_YRAM3_PAGE) {
148                         if (nReg > TAS2563_YRAM3_END_REG) {
149                                 nResult = 0;
150                         } else if (nReg >= TAS2563_YRAM3_START_REG) {
151                                 if ((nReg + len) > TAS2563_YRAM3_END_REG) {
152                                         pCRCData->mnOffset = nReg;
153                                         pCRCData->mnLen = TAS2563_YRAM3_END_REG - nReg + 1;
154                                         nResult = 1;
155                                 } else {
156                                         pCRCData->mnOffset = nReg;
157                                         pCRCData->mnLen = len;
158                                         nResult = 1;
159                                 }
160                         } else {
161                                 if ((nReg + (len - 1)) < TAS2563_YRAM3_START_REG)
162                                         nResult = 0;
163                                 else {
164                                         pCRCData->mnOffset = TAS2563_YRAM3_START_REG;
165                                         pCRCData->mnLen = len - (TAS2563_YRAM3_START_REG - nReg);
166                                         nResult = 1;
167                                 }
168                         }
169                 }
170         } else if (nBook == TAS2563_YRAM_BOOK2) {
171                 if (nPage == TAS2563_YRAM5_PAGE) {
172                         if (nReg > TAS2563_YRAM5_END_REG) {
173                                 nResult = 0;
174                         } else if (nReg >= TAS2563_YRAM5_START_REG) {
175                                 if ((nReg + len) > TAS2563_YRAM5_END_REG) {
176                                         pCRCData->mnOffset = nReg;
177                                         pCRCData->mnLen = TAS2563_YRAM5_END_REG - nReg + 1;
178                                         nResult = 1;
179                                 } else {
180                                         pCRCData->mnOffset = nReg;
181                                         pCRCData->mnLen = len;
182                                         nResult = 1;
183                                 }
184                         } else {
185                                 if ((nReg + (len - 1)) < TAS2563_YRAM5_START_REG)
186                                         nResult = 0;
187                                 else {
188                                         pCRCData->mnOffset = TAS2563_YRAM5_START_REG;
189                                         pCRCData->mnLen = len - (TAS2563_YRAM5_START_REG - nReg);
190                                         nResult = 1;
191                                 }
192                         }
193                 }
194         } else
195                 nResult = 0;
197         return nResult;
200 static int isInBlockYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
201         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
203         int nResult;
205         if (nBook == TAS2563_YRAM_BOOK1) {
206                 if (nPage < TAS2563_YRAM2_START_PAGE)
207                         nResult = 0;
208                 else if (nPage <= TAS2563_YRAM2_END_PAGE) {
209                         if (nReg > TAS2563_YRAM2_END_REG)
210                                 nResult = 0;
211                         else if (nReg >= TAS2563_YRAM2_START_REG) {
212                                 pCRCData->mnOffset = nReg;
213                                 pCRCData->mnLen = len;
214                                 nResult = 1;
215                         } else {
216                                 if ((nReg + (len - 1)) < TAS2563_YRAM2_START_REG)
217                                         nResult = 0;
218                                 else {
219                                         pCRCData->mnOffset = TAS2563_YRAM2_START_REG;
220                                         pCRCData->mnLen = nReg + len - TAS2563_YRAM2_START_REG;
221                                         nResult = 1;
222                                 }
223                         }
224                 } else
225                         nResult = 0;
226         } else if (nBook == TAS2563_YRAM_BOOK2) {
227                 if (nPage < TAS2563_YRAM4_START_PAGE)
228                         nResult = 0;
229                 else if (nPage <= TAS2563_YRAM4_END_PAGE) {
230                         if (nReg > TAS2563_YRAM2_END_REG)
231                                 nResult = 0;
232                         else if (nReg >= TAS2563_YRAM2_START_REG) {
233                                 pCRCData->mnOffset = nReg;
234                                 pCRCData->mnLen = len;
235                                 nResult = 1;
236                         } else {
237                                 if ((nReg + (len - 1)) < TAS2563_YRAM2_START_REG)
238                                         nResult = 0;
239                                 else {
240                                         pCRCData->mnOffset = TAS2563_YRAM2_START_REG;
241                                         pCRCData->mnLen = nReg + len - TAS2563_YRAM2_START_REG;
242                                         nResult = 1;
243                                 }
244                         }
245                 } else
246                         nResult = 0;
247         } else
248                 nResult = 0;
250         return nResult;
254 static int isYRAM(struct tas2563_priv *pTAS2563, struct TYCRC *pCRCData,
255         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
257         int nResult;
259         nResult = isInPageYRAM(pTAS2563, pCRCData, nBook, nPage, nReg, len);
261         if (nResult == 0)
262                 nResult = isInBlockYRAM(pTAS2563, pCRCData, nBook, nPage, nReg, len);
264         return nResult;
267 /*
268  * crc8 - calculate a crc8 over the given input data.
269  *
270  * table: crc table used for calculation.
271  * pdata: pointer to data buffer.
272  * nbytes: number of bytes in data buffer.
273  * crc: previous returned crc8 value.
274  */
275 static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
277         /* loop over the buffer data */
278         while (nbytes-- > 0)
279                 crc = table[(crc ^ *pdata++) & 0xff];
281         return crc;
284 static int doSingleRegCheckSum(struct tas2563_priv *pTAS2563, 
285         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
287         int nResult = 0;
288         struct TYCRC sCRCData;
289         unsigned int nData1 = 0;
291         if ((nBook == TAS2563_BOOK_ID(TAS2563_SA_COEFF_SWAP_REG))
292                 && (nPage == TAS2563_PAGE_ID(TAS2563_SA_COEFF_SWAP_REG))
293                 && (nReg >= TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG))
294                 && (nReg <= (TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG) + 4))) {
295                 /* DSP swap command, pass */
296                 nResult = 0;
297                 goto end;
298         }
300         nResult = isYRAM(pTAS2563, &sCRCData, nBook, nPage, nReg, 1);
301         if (nResult == 1) {
302                 nResult = pTAS2563->read(pTAS2563, TAS2563_REG(nBook, nPage, nReg), &nData1);
303                 if (nResult < 0)
304                         goto end;
306                 if (nData1 != nValue) {
307                         dev_err(pTAS2563->dev, "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
308                                 __LINE__, nBook, nPage, nReg, nValue, nData1);
309                         nResult = -EAGAIN;
310                         goto end;
311                 }
313                 nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0);
314         }
316 end:
318         return nResult;
321 static int doMultiRegCheckSum(struct tas2563_priv *pTAS2563, 
322         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
324         int nResult = 0, i;
325         unsigned char nCRCChkSum = 0;
326         unsigned char nBuf1[128];
327         struct TYCRC TCRCData;
328         
329         return 0;
331         if ((nReg + len-1) > 127) {
332                 nResult = -EINVAL;
333                 dev_err(pTAS2563->dev, "firmware error\n");
334                 goto end;
335         }
337         if ((nBook == TAS2563_BOOK_ID(TAS2563_SA_COEFF_SWAP_REG))
338                 && (nPage == TAS2563_PAGE_ID(TAS2563_SA_COEFF_SWAP_REG))
339                 && (nReg == TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG))
340                 && (len == 4)) {
341                 /* DSP swap command, pass */
342                 nResult = 0;
343                 goto end;
344         }
346         nResult = isYRAM(pTAS2563, &TCRCData, nBook, nPage, nReg, len);
347         dev_info(pTAS2563->dev, "isYRAM: nBook 0x%x, nPage 0x%x, nReg 0x%x\n", nBook, nPage, nReg);
348         dev_info(pTAS2563->dev, "isYRAM: TCRCData.mnLen 0x%x, len 0x%x, nResult %d\n", TCRCData.mnLen, len, nResult);
349         dev_info(pTAS2563->dev, "TCRCData.mnOffset %x\n", TCRCData.mnOffset);
350         if (nResult == 1) {
351                 if (len == 1) {
352                         dev_err(pTAS2563->dev, "firmware error\n");
353                         nResult = -EINVAL;
354                         goto end;
355                 } else {
356                         nResult = pTAS2563->bulk_read(pTAS2563, TAS2563_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
357                         if (nResult < 0)
358                                 goto end;
360                         for (i = 0; i < TCRCData.mnLen; i++) {
361                                 if ((nBook == TAS2563_BOOK_ID(TAS2563_SA_COEFF_SWAP_REG))
362                                         && (nPage == TAS2563_PAGE_ID(TAS2563_SA_COEFF_SWAP_REG))
363                                         && ((i + TCRCData.mnOffset)
364                                                 >= TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG))
365                                         && ((i + TCRCData.mnOffset)
366                                                 <= (TAS2563_PAGE_REG(TAS2563_SA_COEFF_SWAP_REG) + 4))) {
367                                         /* DSP swap command, bypass */
368                                         continue;
369                                 } else
370                                         nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf1[i], 1, 0);
371                         }
373                         nResult = nCRCChkSum;
374                 }
375         }
377 end:
379         return nResult;
383 static int tas2563_load_block(struct tas2563_priv *pTAS2563, struct TBlock *pBlock)
385         int nResult = 0;
386         unsigned int nCommand = 0;
387         unsigned char nBook;
388         unsigned char nPage;
389         unsigned char nOffset;
390         unsigned char nData;
391         unsigned int nLength;
392         unsigned int nSleep;
393         unsigned char nCRCChkSum = 0;
394         unsigned int nValue;
395         int nRetry = 6;
396         unsigned char *pData = pBlock->mpData;
398         dev_info(pTAS2563->dev, "TAS2563 load block: Type = %d, commands = %d\n",
399                 pBlock->mnType, pBlock->mnCommands);
400 start:
401         if (pBlock->mbPChkSumPresent) {
402                 nResult = pTAS2563->write(pTAS2563, TAS2563_I2CChecksum, 0);
403                 if (nResult < 0)
404                         goto end;
405         }
407         if (pBlock->mbYChkSumPresent)
408                 nCRCChkSum = 0;
410         nCommand = 0;
412         while (nCommand < pBlock->mnCommands) {
413                 pData = pBlock->mpData + nCommand * 4;
415                 nBook = pData[0];
416                 nPage = pData[1];
417                 nOffset = pData[2];
418                 nData = pData[3];
420                 nCommand++;
422                 if (nOffset <= 0x7F) {
423                         nResult = pTAS2563->write(pTAS2563, TAS2563_REG(nBook, nPage, nOffset), nData);
424                         if (nResult < 0)
425                                 goto end;
426                         if (pBlock->mbYChkSumPresent) {
427                                 nResult = doSingleRegCheckSum(pTAS2563, nBook, nPage, nOffset, nData);
428                                 if (nResult < 0)
429                                         goto check;
430                                 nCRCChkSum += (unsigned char)nResult;
431                         }
432                 } else if (nOffset == 0x81) {
433                         nSleep = (nBook << 8) + nPage;
434                         msleep(nSleep);
435                 } else if (nOffset == 0x85) {
436                         pData += 4;
437                         nLength = (nBook << 8) + nPage;
438                         nBook = pData[0];
439                         nPage = pData[1];
440                         nOffset = pData[2];
441                         if (nLength > 1) {
442                                 nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_REG(nBook, nPage, nOffset), pData + 3, nLength);
443                                 if (nResult < 0)
444                                         goto end;
445                                 if (pBlock->mbYChkSumPresent) {
446                                         nResult = doMultiRegCheckSum(pTAS2563, nBook, nPage, nOffset, nLength);
447                                         if (nResult < 0)
448                                                 goto check;
449                                         nCRCChkSum += (unsigned char)nResult;
450                                 }
451                         } else {
452                                 nResult = pTAS2563->write(pTAS2563, TAS2563_REG(nBook, nPage, nOffset), pData[3]);
453                                 if (nResult < 0)
454                                         goto end;
455                                 if (pBlock->mbYChkSumPresent) {
456                                         nResult = doSingleRegCheckSum(pTAS2563, nBook, nPage, nOffset, pData[3]);
457                                         if (nResult < 0)
458                                                 goto check;
459                                         nCRCChkSum += (unsigned char)nResult;
460                                 }
461                         }
463                         nCommand++;
465                         if (nLength >= 2)
466                                 nCommand += ((nLength - 2) / 4) + 1;
467                 }
468         }
469         if (pBlock->mbPChkSumPresent) {
470                 nResult = pTAS2563->read(pTAS2563, TAS2563_I2CChecksum, &nValue);
471                 dev_err(pTAS2563->dev, "Block PChkSum: FW = 0x%x, Reg = 0x%x\n",
472                                 pBlock->mnPChkSum, (nValue&0xff));
474                 if (nResult < 0)
475                         goto end;
476                 if ((nValue&0xff) != pBlock->mnPChkSum) {
477                         dev_err(pTAS2563->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
478                                 pBlock->mnPChkSum, (nValue&0xff));
479                         nResult = -EAGAIN;
480                                 pTAS2563->mnErrCode |= ERROR_PRAM_CRCCHK;
481                         goto check;
482                 }
484                 nResult = 0;
485                 pTAS2563->mnErrCode &= ~ERROR_PRAM_CRCCHK;
486                 dev_info(pTAS2563->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
487         }
489         if (pBlock->mbYChkSumPresent) {
490                 //TBD, open it when FW ready
491                 dev_err(pTAS2563->dev, "Block YChkSum: FW = 0x%x, YCRC = 0x%x\n",
492                                 pBlock->mnYChkSum, nCRCChkSum);
493 /*
494                 if (nCRCChkSum != pBlock->mnYChkSum) {
495                         dev_err(pTAS2563->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
496                                 pBlock->mnYChkSum, nCRCChkSum);
497                         nResult = -EAGAIN;
498                         pTAS2563->mnErrCode |= ERROR_YRAM_CRCCHK;
499                         goto check;
500                 }
501 */
502                 pTAS2563->mnErrCode &= ~ERROR_YRAM_CRCCHK;
503                 nResult = 0;
504                 dev_info(pTAS2563->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
505         }
507 check:
508         if (nResult == -EAGAIN) {
509                 nRetry--;
510                 if (nRetry > 0)
511                         goto start;
512         }
514 end:
515         if (nResult < 0) {
516                 dev_err(pTAS2563->dev, "Block (%d) load error\n",
517                                 pBlock->mnType);
518         }
519         return nResult;
523 static int tas2563_load_data(struct tas2563_priv *pTAS2563, struct TData *pData, unsigned int nType)
525         int nResult = 0;
526         unsigned int nBlock;
527         struct TBlock *pBlock;
529         dev_info(pTAS2563->dev,
530                 "TAS2563 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
532         for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
533                 pBlock = &(pData->mpBlocks[nBlock]);
534                 if (pBlock->mnType == nType) {
535                         nResult = tas2563_load_block(pTAS2563, pBlock);
536                         if (nResult < 0)
537                                 break;
538                 }
539         }
541         return nResult;
544 void tas2563_clear_firmware(struct TFirmware *pFirmware)
546         unsigned int n, nn;
548         if (!pFirmware)
549                 return;
551         kfree(pFirmware->mpDescription);
553         if (pFirmware->mpPLLs != NULL) {
554                 for (n = 0; n < pFirmware->mnPLLs; n++) {
555                         kfree(pFirmware->mpPLLs[n].mpDescription);
556                         kfree(pFirmware->mpPLLs[n].mBlock.mpData);
557                 }
558                 kfree(pFirmware->mpPLLs);
559         }
561         if (pFirmware->mpPrograms != NULL) {
562                 for (n = 0; n < pFirmware->mnPrograms; n++) {
563                         kfree(pFirmware->mpPrograms[n].mpDescription);
564                         kfree(pFirmware->mpPrograms[n].mData.mpDescription);
565                         for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
566                                 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
567                         kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
568                 }
569                 kfree(pFirmware->mpPrograms);
570         }
572         if (pFirmware->mpConfigurations != NULL) {
573                 for (n = 0; n < pFirmware->mnConfigurations; n++) {
574                         kfree(pFirmware->mpConfigurations[n].mpDescription);
575                         kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
576                         for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
577                                 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
578                         kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
579                 }
580                 kfree(pFirmware->mpConfigurations);
581         }
583         if (pFirmware->mpCalibrations != NULL) {
584                 for (n = 0; n < pFirmware->mnCalibrations; n++) {
585                         kfree(pFirmware->mpCalibrations[n].mpDescription);
586                         kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
587                         for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
588                                 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
589                         kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
590                 }
591                 kfree(pFirmware->mpCalibrations);
592         }
594         memset(pFirmware, 0x00, sizeof(struct TFirmware));
597 static int tas2563_load_configuration(struct tas2563_priv *pTAS2563,
598         unsigned int nConfiguration, bool bLoadSame)
600         int nResult = 0;
601         struct TConfiguration *pCurrentConfiguration = NULL;
602         struct TConfiguration *pNewConfiguration = NULL;
604         dev_info(pTAS2563->dev, "%s: %d\n", __func__, nConfiguration);
606         if ((!pTAS2563->mpFirmware->mpPrograms) ||
607                 (!pTAS2563->mpFirmware->mpConfigurations)) {
608                 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n", __func__);
609                 nResult = 0;
610                 goto end;
611         }
613         if (nConfiguration >= pTAS2563->mpFirmware->mnConfigurations) {
614                 dev_err(pTAS2563->dev, "Configuration %d doesn't exist\n",
615                         nConfiguration);
616                 nResult = 0;
617                 goto end;
618         }
620         if ((!pTAS2563->mbLoadConfigurationPrePowerUp)
621                 && (nConfiguration == pTAS2563->mnCurrentConfiguration)
622                 && (!bLoadSame)) {
623                 dev_info(pTAS2563->dev, "Configuration %d is already loaded\n",
624                         nConfiguration);
625                 nResult = 0;
626                 goto end;
627         }
629         pCurrentConfiguration =
630                 &(pTAS2563->mpFirmware->mpConfigurations[pTAS2563->mnCurrentConfiguration]);
631         pNewConfiguration =
632                 &(pTAS2563->mpFirmware->mpConfigurations[nConfiguration]);
633         if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
634                 dev_err(pTAS2563->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
635                         nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
636                 nResult = 0;
637                 goto end;
638         }
640         if (pTAS2563->mbPowerUp) {
641                 pTAS2563->mbLoadConfigurationPrePowerUp = false;
642                 nResult = tas2563_load_coefficient(pTAS2563, pTAS2563->mnCurrentConfiguration, nConfiguration, true);
643         } else {
644                 dev_info(pTAS2563->dev,
645                         "TAS2563 was powered down, will load coefficient when power up\n");
646                 pTAS2563->mbLoadConfigurationPrePowerUp = true;
647                 pTAS2563->mnNewConfiguration = nConfiguration;
648         }
650 end:
652 /*      if (nResult < 0) {
653                 if (pTAS2563->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
654                         failsafe(pTAS2563);
655         }
656 */
657         return nResult;
660 static int tas2563_load_calibration(struct tas2563_priv *pTAS2563,      char *pFileName)
662         int nResult = 0;
664         int nFile;
665         mm_segment_t fs;
666         unsigned char pBuffer[1000];
667         int nSize = 0;
669         dev_info(pTAS2563->dev, "%s:\n", __func__);
671         fs = get_fs();
672         set_fs(KERNEL_DS);
673         nFile = sys_open(pFileName, O_RDONLY, 0);
675         dev_info(pTAS2563->dev, "TAS2563 calibration file = %s, handle = %d\n",
676                 pFileName, nFile);
678         if (nFile >= 0) {
679                 nSize = sys_read(nFile, pBuffer, 1000);
680                 sys_close(nFile);
681         } else {
682                 dev_err(pTAS2563->dev, "TAS2563 cannot open calibration file: %s\n",
683                         pFileName);
684         }
686         set_fs(fs);
688         if (!nSize)
689                 goto end;
691         tas2563_clear_firmware(pTAS2563->mpCalFirmware);
692         dev_info(pTAS2563->dev, "TAS2563 calibration file size = %d\n", nSize);
693         nResult = fw_parse(pTAS2563, pTAS2563->mpCalFirmware, pBuffer, nSize);
695         if (nResult)
696                 dev_err(pTAS2563->dev, "TAS2563 calibration file is corrupt\n");
697         else
698                 dev_info(pTAS2563->dev, "TAS2563 calibration: %d calibrations\n",
699                         pTAS2563->mpCalFirmware->mnCalibrations);
700 end:
702         return nResult;
705 static int tas2563_codec_write(struct snd_soc_codec *codec, unsigned int reg,
706         unsigned int value)
708         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
710         int nResult = 0;
712         nResult = pTAS2563->write(pTAS2563, reg, value);
713         if (nResult < 0)
714                 dev_err(pTAS2563->dev, "%s, ERROR, reg=0x%x, E=%d\n",
715                         __func__, reg, nResult);
716         else
717                 dev_info(pTAS2563->dev, "%s, reg: 0x%x, 0x%x\n",
718                         __func__, reg, value);
720         return nResult;
724 static void fw_print_header(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware)
726         dev_info(pTAS2563->dev, "FW Size       = %d", pFirmware->mnFWSize);
727         dev_info(pTAS2563->dev, "Checksum      = 0x%04X", pFirmware->mnChecksum);
728         dev_info(pTAS2563->dev, "PPC Version   = 0x%04X", pFirmware->mnPPCVersion);
729         dev_info(pTAS2563->dev, "FW  Version    = 0x%04X", pFirmware->mnFWVersion);
730         dev_info(pTAS2563->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
731         dev_info(pTAS2563->dev, "Timestamp     = %d", pFirmware->mnTimeStamp);
732         dev_info(pTAS2563->dev, "DDC Name      = %s", pFirmware->mpDDCName);
733         dev_info(pTAS2563->dev, "Description   = %s", pFirmware->mpDescription);
736 inline unsigned int fw_convert_number(unsigned char *pData)
738         return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
741 static int fw_parse_header(struct tas2563_priv *pTAS2563,
742         struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
744         unsigned char *pDataStart = pData;
745         unsigned int n;
746         unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
748         if (nSize < 104) {
749                 dev_err(pTAS2563->dev, "Firmware: Header too short");
750                 return -EINVAL;
751         }
753         if (memcmp(pData, pMagicNumber, 4)) {
754                 dev_err(pTAS2563->dev, "Firmware: Magic number doesn't match");
755                 return -EINVAL;
756         }
757         pData += 4;
759         pFirmware->mnFWSize = fw_convert_number(pData);
760         pData += 4;
761         dev_info(pTAS2563->dev, "firmware size: %d", pFirmware->mnFWSize);
763         pFirmware->mnChecksum = fw_convert_number(pData);
764         pData += 4;
766         pFirmware->mnPPCVersion = fw_convert_number(pData);
767         pData += 4;
769         pFirmware->mnFWVersion = fw_convert_number(pData);
770         pData += 4;
772         pFirmware->mnDriverVersion = fw_convert_number(pData);
773         pData += 4;
775         pFirmware->mnTimeStamp = fw_convert_number(pData);
776         pData += 4;
777         dev_info(pTAS2563->dev, "FW timestamp: %d", pFirmware->mnTimeStamp);
779         memcpy(pFirmware->mpDDCName, pData, 64);
780         pData += 64;
782         n = strlen(pData);
783         pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
784         pData += n + 1;
785         if ((pData - pDataStart) >= nSize) {
786                 dev_err(pTAS2563->dev, "Firmware: Header too short after DDC description");
787                 return -EINVAL;
788         }
790         pFirmware->mnDeviceFamily = fw_convert_number(pData);
791         pData += 4;
792         if (pFirmware->mnDeviceFamily != 0) {
793                 dev_err(pTAS2563->dev,
794                         "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
795                 return -EINVAL;
796         }
798         pFirmware->mnDevice = fw_convert_number(pData);
799         pData += 4;
801         if (pFirmware->mnDevice != 5) {
802                 dev_err(pTAS2563->dev,
803                         "device %d, not TAS2563", pFirmware->mnDevice);
804                 return -EINVAL;
805         }
807         fw_print_header(pTAS2563, pFirmware);
808         return pData - pDataStart;
811 static int fw_parse_block_data(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware,
812         struct TBlock *pBlock, unsigned char *pData)
814         unsigned char *pDataStart = pData;
815         unsigned int n;
817         dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
819         pBlock->mnType = fw_convert_number(pData);
820         pData += 4;
821         dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
823         if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) {
824                 pBlock->mbPChkSumPresent = pData[0];
825                 pData++;
827                 pBlock->mnPChkSum = pData[0];
828                 pData++;
830                 pBlock->mbYChkSumPresent = pData[0];
831                 pData++;
833                 pBlock->mnYChkSum = pData[0];
834                 pData++;
835         } else {
836                 pBlock->mbPChkSumPresent = 0;
837                 pBlock->mbYChkSumPresent = 0;
838         }
840         pBlock->mnCommands = fw_convert_number(pData);
841         pData += 4;
843         n = pBlock->mnCommands * 4;
844         pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
845         pData += n;
846         dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
847         return pData - pDataStart;
850 static int fw_parse_data(struct tas2563_priv *pTAS2563, struct TFirmware *pFirmware,
851         struct TData *pImageData, unsigned char *pData)
853         unsigned char *pDataStart = pData;
854         unsigned int nBlock;
855         unsigned int n;
857         dev_info(pTAS2563->dev, "%s, %d", __func__, __LINE__);
858         memcpy(pImageData->mpName, pData, 64);
859         pData += 64;
861         n = strlen(pData);
862         pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
863         pData += n + 1;
865         pImageData->mnBlocks = (pData[0] << 8) + pData[1];
866         pData += 2;
868         pImageData->mpBlocks =
869                 kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
871         for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
872                 n = fw_parse_block_data(pTAS2563, pFirmware,
873                         &(pImageData->mpBlocks[nBlock]), pData);
874                 pData += n;
875         }
876         return pData - pDataStart;
879 static int fw_parse_program_data(struct tas2563_priv *pTAS2563,
880         struct TFirmware *pFirmware, unsigned char *pData)
882         unsigned char *pDataStart = pData;
883         unsigned int n;
884         unsigned int nProgram;
885         struct TProgram *pProgram;
887         pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
888         pData += 2;
890         if (pFirmware->mnPrograms == 0)
891                 goto end;
893         pFirmware->mpPrograms =
894                 kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
895         for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
896                 pProgram = &(pFirmware->mpPrograms[nProgram]);
897                 memcpy(pProgram->mpName, pData, 64);
898                 pData += 64;
900                 n = strlen(pData);
901                 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
902                 pData += n + 1;
904                 pProgram->mnAppMode = pData[0];
905                 pData++;
907                 pProgram->mnI2sMode = pData[0];
908                 pData++;
909                 dev_info(pTAS2563->dev, "FW i2sMode: %d", pProgram->mnI2sMode);
911                 pProgram->mnISnsPD = pData[0];
912                 pData++;
914                 pProgram->mnVSnsPD = pData[0];
915                 pData++;
917                 pProgram->mnPowerLDG = pData[0];
918                 pData++;
920                 n = fw_parse_data(pTAS2563, pFirmware, &(pProgram->mData), pData);
921                 pData += n;
922                 dev_info(pTAS2563->dev, "program data number: %d", n);
923         }
925 end:
927         return pData - pDataStart;
930 static int fw_parse_configuration_data(struct tas2563_priv *pTAS2563,
931         struct TFirmware *pFirmware, unsigned char *pData)
933         unsigned char *pDataStart = pData;
934         unsigned int n;
935         unsigned int nConfiguration;
936         struct TConfiguration *pConfiguration;
938         pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
939         pData += 2;
941         if (pFirmware->mnConfigurations == 0)
942                 goto end;
944         pFirmware->mpConfigurations =
945                 kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
946                 GFP_KERNEL);
947         for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
948                 nConfiguration++) {
949                 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
950                 memcpy(pConfiguration->mpName, pData, 64);
951                 pData += 64;
953                 n = strlen(pData);
954                 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
955                 pData += n + 1;
957 /*
958                 if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV)
959                         || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC)
960                                 && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) {*/
961                         pConfiguration->mnDevices = (pData[0] << 8) + pData[1];
962                         pData += 2;
963 /*              } else
964                         pConfiguration->mnDevices = 1;*/
966                 pConfiguration->mnProgram = pData[0];
967                 pData++;
968                 dev_info(pTAS2563->dev, "configuration, mnProgram: %d", pConfiguration->mnProgram);
970                 pConfiguration->mnSamplingRate = fw_convert_number(pData);
971                 pData += 4;
972                 dev_info(pTAS2563->dev, "configuration samplerate: %d", pConfiguration->mnSamplingRate);
974                 //if (pFirmware->mnDriverVersion >= PPC_DRIVER_MTPLLSRC) {
975                         pConfiguration->mnPLLSrc = pData[0];
976                         pData++;
978                         pConfiguration->mnPLLSrcRate = fw_convert_number(pData);
979                         pData += 4;
980                 //}
982                 pConfiguration->mnFsRate = (pData[0] << 8) + pData[1];
983                 pData += 2;
984                 dev_info(pTAS2563->dev, "Fs rate: %d", pConfiguration->mnFsRate);
986                 n = fw_parse_data(pTAS2563, pFirmware, &(pConfiguration->mData), pData);
987                 pData += n;
988         }
990 end:
992         return pData - pDataStart;
995 int fw_parse_calibration_data(struct tas2563_priv *pTAS2563,
996         struct TFirmware *pFirmware, unsigned char *pData)
998         unsigned char *pDataStart = pData;
999         unsigned int n;
1000         unsigned int nCalibration;
1001         struct TCalibration *pCalibration;
1003         pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
1004         pData += 2;
1006         if (pFirmware->mnCalibrations == 0)
1007                 goto end;
1009         pFirmware->mpCalibrations =
1010                 kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
1011         for (nCalibration = 0;
1012                 nCalibration < pFirmware->mnCalibrations;
1013                 nCalibration++) {
1014                 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
1015                 memcpy(pCalibration->mpName, pData, 64);
1016                 pData += 64;
1018                 n = strlen(pData);
1019                 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1020                 pData += n + 1;
1022                 pCalibration->mnProgram = pData[0];
1023                 pData++;
1025                 pCalibration->mnConfiguration = pData[0];
1026                 pData++;
1028                 n = fw_parse_data(pTAS2563, pFirmware, &(pCalibration->mData), pData);
1029                 pData += n;
1030         }
1032 end:
1034         return pData - pDataStart;
1037 static int fw_parse(struct tas2563_priv *pTAS2563,
1038         struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
1040         int nPosition = 0;
1042         nPosition = fw_parse_header(pTAS2563, pFirmware, pData, nSize);
1043         dev_info(pTAS2563->dev, "header size: %d, line: %d\n", nPosition, __LINE__);
1044         if (nPosition < 0) {
1045                 dev_err(pTAS2563->dev, "Firmware: Wrong Header");
1046                 return -EINVAL;
1047         }
1049         if (nPosition >= nSize) {
1050                 dev_err(pTAS2563->dev, "Firmware: Too short");
1051                 return -EINVAL;
1052         }
1054         pData += nPosition;
1055         nSize -= nPosition;
1056         nPosition = 0;
1058         nPosition = fw_parse_program_data(pTAS2563, pFirmware, pData);
1059         dev_info(pTAS2563->dev, "program size: %d, line: %d\n", nPosition, __LINE__);
1061         pData += nPosition;
1062         nSize -= nPosition;
1063         nPosition = 0;
1065         nPosition = fw_parse_configuration_data(pTAS2563, pFirmware, pData);
1066         dev_info(pTAS2563->dev, "config size: %d, line: %d\n", nPosition, __LINE__);
1068         pData += nPosition;
1069         nSize -= nPosition;
1070         nPosition = 0;
1072         if (nSize > 64)
1073                 nPosition = fw_parse_calibration_data(pTAS2563, pFirmware, pData);
1074         dev_info(pTAS2563->dev, "calib size: %d, line: %d\n", nPosition, __LINE__);
1075         return 0;
1079 static int tas2563_codec_suspend(struct snd_soc_codec *codec)
1081         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1082         int ret = 0;
1084         mutex_lock(&pTAS2563->codec_lock);
1086         dev_info(pTAS2563->dev, "%s\n", __func__);
1087         pTAS2563->runtime_suspend(pTAS2563);
1089         mutex_unlock(&pTAS2563->codec_lock);
1090         return ret;
1093 static int tas2563_codec_resume(struct snd_soc_codec *codec)
1095         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1096         int ret = 0;
1098         mutex_lock(&pTAS2563->codec_lock);
1100         dev_info(pTAS2563->dev, "%s\n", __func__);
1101         pTAS2563->runtime_resume(pTAS2563);
1103         mutex_unlock(&pTAS2563->codec_lock);
1104         return ret;
1107 static int tas2563_set_power_state(struct tas2563_priv *pTAS2563, int state)
1109         int nResult = 0, irqreg;
1110         /*unsigned int nValue;*/
1111         const char *pFWName;
1112         struct TProgram *pProgram;
1114         dev_info(pTAS2563->dev, "set power state: %d\n", state);
1116         if ((pTAS2563->mpFirmware->mnPrograms == 0)
1117                 || (pTAS2563->mpFirmware->mnConfigurations == 0)) {
1118                 dev_err(pTAS2563->dev, "%s, firmware not loaded\n", __func__);
1119                 pFWName = TAS2563_FW_NAME;
1120                 nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName,
1121                         pTAS2563->dev, GFP_KERNEL, pTAS2563, tas2563_fw_ready);
1123                 if(nResult < 0) {
1124                         dev_err(pTAS2563->dev, "%s, firmware is not loaded, return %d\n",
1125                                         __func__, nResult);
1126                         goto end;
1127                 }
1128         }
1129         /* check safe guard*/
1130         /* TBD, add back when FW ready
1131         nResult = pTAS2563->read(pTAS2563, TAS2563_SAFE_GUARD_REG, &nValue);
1132         if (nResult < 0)
1133                 goto end;
1134         if ((nValue&0xff) != TAS2563_SAFE_GUARD_PATTERN) {
1135                 dev_err(pTAS2563->dev, "ERROR safe guard failure!\n");
1136                 nResult = -EPIPE;
1137                 goto end;
1138         }
1139         */
1141         pProgram = &(pTAS2563->mpFirmware->mpPrograms[pTAS2563->mnCurrentProgram]);
1142         dev_info(pTAS2563->dev, "%s, state: %d, mbPowerup %d\n", __func__, state, pTAS2563->mbPowerUp);
1143         if (state != TAS2563_POWER_SHUTDOWN) {
1144                 if (!pTAS2563->mbPowerUp) {
1145                         if (!pTAS2563->mbCalibrationLoaded) {
1146                                 nResult = tas2563_set_calibration(pTAS2563, 0xFF);
1147                                 if((nResult > 0) || (nResult == 0))
1148                                         pTAS2563->mbCalibrationLoaded = true;
1149                         }
1151                         if (pTAS2563->mbLoadConfigurationPrePowerUp) {
1152                                 dev_info(pTAS2563->dev, "load coefficient before power\n");
1153                                 pTAS2563->mbLoadConfigurationPrePowerUp = false;
1154                                 nResult = tas2563_load_coefficient(pTAS2563,
1155                                         pTAS2563->mnCurrentConfiguration, pTAS2563->mnNewConfiguration, false);
1156                                 if (nResult < 0)
1157                                         goto end;
1158                         }
1159                 }
1160         }
1162         switch (state) {
1163         case TAS2563_POWER_ACTIVE:
1164 /*
1165                 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1166                         TAS2563_PowerControl_OperationalMode10_Mask |
1167                         TAS2563_PowerControl_ISNSPower_Mask |
1168                         TAS2563_PowerControl_VSNSPower_Mask,
1169                         TAS2563_PowerControl_OperationalMode10_Active |
1170                         TAS2563_PowerControl_VSNSPower_Active |
1171                         TAS2563_PowerControl_ISNSPower_Active);
1172                 if (nResult < 0)
1173                         return nResult;
1174 */
1176 //Clear latched IRQ before power on
1177                 pTAS2563->update_bits(pTAS2563, TAS2563_InterruptConfiguration,
1178                                         TAS2563_InterruptConfiguration_CLEARLATINT_Mask,
1179                                         TAS2563_InterruptConfiguration_CLEARLATINT_CLEAR);
1180                 pTAS2563->mbPowerUp = true;
1182                 pTAS2563->read(pTAS2563, TAS2563_LatchedInterruptReg0, &irqreg);
1183                 dev_info(pTAS2563->dev, "IRQ reg is: %d, %d\n", irqreg, __LINE__);
1185 //              pTAS2563->enableIRQ(pTAS2563, true);
1186                 schedule_delayed_work(&pTAS2563->irq_work, msecs_to_jiffies(100));
1188                 break;
1190         case TAS2563_POWER_MUTE:
1191                 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1192                         TAS2563_PowerControl_OperationalMode10_Mask |
1193                         TAS2563_PowerControl_ISNSPower_Mask |
1194                         TAS2563_PowerControl_VSNSPower_Mask,
1195                         TAS2563_PowerControl_OperationalMode10_Mute |
1196                         TAS2563_PowerControl_VSNSPower_Active |
1197                         TAS2563_PowerControl_ISNSPower_Active);
1198                         pTAS2563->mbPowerUp = true;
1199                 break;
1201         case TAS2563_POWER_SHUTDOWN:
1202                 nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1203                         TAS2563_PowerControl_OperationalMode10_Mask,
1204                         TAS2563_PowerControl_OperationalMode10_Shutdown);
1205                         pTAS2563->mbPowerUp = false;
1206                         pTAS2563->enableIRQ(pTAS2563, false);
1207                 break;
1209         default:
1210                 dev_err(pTAS2563->dev, "wrong power state setting %d\n", state);
1212         }
1214 end:
1215         pTAS2563->mnPowerState = state;
1216         return nResult;
1219 static int tas2563_dac_event(struct snd_soc_dapm_widget *w,
1220                         struct snd_kcontrol *kcontrol, int event)
1222 #ifdef KCONTROL_CODEC
1223         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
1224 #else
1225         struct snd_soc_codec *codec = w->codec;
1226 #endif
1227         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1229         switch (event) {
1230         case SND_SOC_DAPM_POST_PMU:
1231                 dev_info(pTAS2563->dev, "SND_SOC_DAPM_POST_PMU\n");
1232                 break;
1233         case SND_SOC_DAPM_PRE_PMD:
1234                 dev_info(pTAS2563->dev, "SND_SOC_DAPM_PRE_PMD\n");
1235                 break;
1236         }
1238         return 0;
1241 static const struct snd_soc_dapm_widget tas2563_dapm_widgets[] = {
1242         SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
1243         SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2563_dac_event,
1244         SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1245         SND_SOC_DAPM_OUTPUT("OUT"),
1246         SND_SOC_DAPM_SIGGEN("VMON"),
1247         SND_SOC_DAPM_SIGGEN("IMON")
1248 };
1250 static const struct snd_soc_dapm_route tas2563_audio_map[] = {
1251         {"DAC", NULL, "ASI1"},
1252         {"OUT", NULL, "DAC"},
1253 };
1255 static int tas2563_mute(struct snd_soc_dai *dai, int mute)
1257         struct snd_soc_codec *codec = dai->codec;
1258         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
1260         dev_info(pTAS2563->dev, "%s\n", __func__);
1261         mutex_lock(&pTAS2563->codec_lock);
1262         if (mute) {
1263                 dev_info(pTAS2563->dev, "mute: %s\n", __func__);
1264                 tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1265         } else {
1266                 dev_info(pTAS2563->dev, "unmute: %s\n", __func__);
1267                 tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
1268         }
1269         mutex_unlock(&pTAS2563->codec_lock);
1270         return 0;
1274 static int tas2563_slot_config(struct snd_soc_codec *codec, struct tas2563_priv *pTAS2563, int blr_clk_ratio)
1276         int ret = 0;
1277         ret = pTAS2563->update_bits(pTAS2563,
1278                         TAS2563_TDMConfigurationReg5, 0xff, 0x42);
1279         if(ret < 0)
1280                 return ret;
1282         ret = pTAS2563->update_bits(pTAS2563,
1283                         TAS2563_TDMConfigurationReg6, 0xff, 0x40);
1285         return ret;
1288 static int tas2563_set_slot(struct tas2563_priv *pTAS2563, int slot_width)
1290         int ret = 0;
1291         dev_info(pTAS2563->dev, "%s, slot_width:%d\n", __func__, slot_width);
1293         switch (slot_width) {
1294         case 16:
1295         ret = pTAS2563->update_bits(pTAS2563, 
1296                 TAS2563_TDMConfigurationReg2,
1297                 TAS2563_TDMConfigurationReg2_RXSLEN10_Mask,
1298                 TAS2563_TDMConfigurationReg2_RXSLEN10_16Bits);
1299         break;
1301         case 24:
1302         ret = pTAS2563->update_bits(pTAS2563, 
1303                 TAS2563_TDMConfigurationReg2,
1304                 TAS2563_TDMConfigurationReg2_RXSLEN10_Mask,
1305                 TAS2563_TDMConfigurationReg2_RXSLEN10_24Bits);
1306         break;
1308         case 32:
1309         ret = pTAS2563->update_bits(pTAS2563, 
1310                 TAS2563_TDMConfigurationReg2,
1311                 TAS2563_TDMConfigurationReg2_RXSLEN10_Mask,
1312                 TAS2563_TDMConfigurationReg2_RXSLEN10_32Bits);
1313         break;
1315         case 0:
1316         /* Do not change slot width */
1317         break;
1319         default:
1320                 dev_info(pTAS2563->dev, "slot width not supported");
1321                 ret = -EINVAL;
1322         }
1324         if (ret >= 0)
1325                 pTAS2563->mnSlot_width = slot_width;
1327         return ret;
1330 static int tas2563_set_bitwidth(struct tas2563_priv *pTAS2563, int bitwidth)
1332         int slot_width_tmp = 0;
1333         dev_info(pTAS2563->dev, "%s %d\n", __func__, __LINE__);
1335         switch (bitwidth) {
1336         case SNDRV_PCM_FORMAT_S16_LE:
1337                         pTAS2563->update_bits(pTAS2563, 
1338                         TAS2563_TDMConfigurationReg2,
1339                         TAS2563_TDMConfigurationReg2_RXWLEN32_Mask,
1340                         TAS2563_TDMConfigurationReg2_RXWLEN32_16Bits);
1341                         pTAS2563->mnCh_size = 16;
1342                         if (pTAS2563->mnSlot_width == 0)
1343                                 slot_width_tmp = 16;
1344                 break;
1345         case SNDRV_PCM_FORMAT_S24_LE:
1346                         pTAS2563->update_bits(pTAS2563, 
1347                         TAS2563_TDMConfigurationReg2,
1348                         TAS2563_TDMConfigurationReg2_RXWLEN32_Mask,
1349                         TAS2563_TDMConfigurationReg2_RXWLEN32_24Bits);
1350                         pTAS2563->mnCh_size = 24;
1351                         if (pTAS2563->mnSlot_width == 0)
1352                                 slot_width_tmp = 32;
1353                 break;
1354         case SNDRV_PCM_FORMAT_S32_LE:
1355                         pTAS2563->update_bits(pTAS2563,
1356                         TAS2563_TDMConfigurationReg2,
1357                         TAS2563_TDMConfigurationReg2_RXWLEN32_Mask,
1358                         TAS2563_TDMConfigurationReg2_RXWLEN32_32Bits);
1359                         pTAS2563->mnCh_size = 32;
1360                         if (pTAS2563->mnSlot_width == 0)
1361                                 slot_width_tmp = 32;
1362                 break;
1364         default:
1365                 dev_info(pTAS2563->dev, "Not supported params format\n");
1366         }
1368         /* If machine driver did not call set slot width */
1369         if (pTAS2563->mnSlot_width == 0)
1370                 tas2563_set_slot(pTAS2563, slot_width_tmp);
1372         dev_info(pTAS2563->dev, "mnCh_size: %d\n", pTAS2563->mnCh_size);
1373         pTAS2563->mnPCMFormat = bitwidth;
1375         return 0;
1378 static int tas2563_set_samplerate(struct tas2563_priv *pTAS2563, int samplerate)
1380         switch (samplerate) {
1381         case 48000:
1382                         pTAS2563->update_bits(pTAS2563,
1383                                 TAS2563_TDMConfigurationReg0,
1384                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1385                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
1386                         pTAS2563->update_bits(pTAS2563,
1387                                 TAS2563_TDMConfigurationReg0,
1388                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1389                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
1390                         break;
1391         case 44100:
1392                         pTAS2563->update_bits(pTAS2563,
1393                                 TAS2563_TDMConfigurationReg0,
1394                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1395                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
1396                         pTAS2563->update_bits(pTAS2563,
1397                                 TAS2563_TDMConfigurationReg0,
1398                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1399                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_44_1_48kHz);
1400                         break;
1401         case 96000:
1402                         pTAS2563->update_bits(pTAS2563,
1403                                 TAS2563_TDMConfigurationReg0,
1404                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1405                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
1406                         pTAS2563->update_bits(pTAS2563,
1407                                 TAS2563_TDMConfigurationReg0,
1408                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1409                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
1410                         break;
1411         case 88200:
1412                         pTAS2563->update_bits(pTAS2563,
1413                                 TAS2563_TDMConfigurationReg0,
1414                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1415                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
1416                         pTAS2563->update_bits(pTAS2563,
1417                                 TAS2563_TDMConfigurationReg0,
1418                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1419                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_88_2_96kHz);
1420                         break;
1421         case 19200:
1422                         pTAS2563->update_bits(pTAS2563,
1423                                 TAS2563_TDMConfigurationReg0,
1424                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1425                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_48KHz);
1426                         pTAS2563->update_bits(pTAS2563,
1427                                 TAS2563_TDMConfigurationReg0,
1428                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1429                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
1430                         break;
1431         case 17640:
1432                         pTAS2563->update_bits(pTAS2563,
1433                                 TAS2563_TDMConfigurationReg0,
1434                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_Mask,
1435                                 TAS2563_TDMConfigurationReg0_SAMPRATERAMP_44_1KHz);
1436                         pTAS2563->update_bits(pTAS2563,
1437                                 TAS2563_TDMConfigurationReg0,
1438                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_Mask,
1439                                 TAS2563_TDMConfigurationReg0_SAMPRATE31_176_4_192kHz);
1440                         break;
1441         default:
1442                         dev_info(pTAS2563->dev, "%s, unsupported sample rate, %d\n", __func__, samplerate);
1444         }
1446         pTAS2563->mnSamplingRate = samplerate;
1447         return 0;
1450 int tas2563_load_default(struct tas2563_priv *pTAS2563)
1452         int ret = 0;
1453         
1454         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1456         ret = tas2563_set_slot(pTAS2563, pTAS2563->mnSlot_width);
1457         if (ret < 0)
1458                 goto end;
1459         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1461         /* proper TX format */
1462         ret = pTAS2563->write(pTAS2563, TAS2563_TDMConfigurationReg4, 0x01);
1463         if(ret < 0)
1464                 goto end;
1466         /*if setting format was not called by asoc, then set it default*/
1467         if(pTAS2563->mnASIFormat == 0)
1468                 pTAS2563->mnASIFormat = SND_SOC_DAIFMT_CBS_CFS 
1469                                 | SND_SOC_DAIFMT_IB_NF 
1470                                 | SND_SOC_DAIFMT_I2S;
1471         ret = tas2563_set_fmt(pTAS2563, pTAS2563->mnASIFormat);
1473         if (ret < 0)
1474                 goto end;
1475         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1477         ret = tas2563_set_bitwidth(pTAS2563, pTAS2563->mnPCMFormat);
1478         if (ret < 0)
1479                 goto end;
1480         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1482         ret = tas2563_set_samplerate(pTAS2563, pTAS2563->mnSamplingRate);
1483         if (ret < 0)
1484                 goto end;
1486 /*Enable TDM IRQ */
1487         ret = pTAS2563->update_bits(pTAS2563, TAS2563_InterruptMaskReg0,
1488                         TAS2563_InterruptMaskReg0_TDMClockErrorINTMASK_Mask,
1489                         TAS2563_InterruptMaskReg0_TDMClockErrorINTMASK_Unmask);
1490 /* disable the DMA5 deglitch filter and halt timer */
1491         ret = pTAS2563->update_bits(pTAS2563, TAS2563_CLKERR_Config,
1492                         TAS2563_CLKERR_Config_DMA5FILTER_Mask,
1493                         TAS2563_CLKERR_Config_DMA5FILTER_Disable);
1494 /* disable clk halt timer */
1495         ret = pTAS2563->update_bits(pTAS2563, TAS2563_InterruptConfiguration,
1496                         TAS2563_InterruptConfiguration_CLKHALT_Mask,
1497                         TAS2563_InterruptConfiguration_CLKHALT_Disable);
1499 end:
1500 /* Load default failed, restart later */
1501         dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
1502         if (ret < 0)
1503                 schedule_delayed_work(&pTAS2563->irq_work,
1504                                 msecs_to_jiffies(1000));
1505         return ret;
1508 #if 0
1509 static void failsafe(struct tas2563_priv *pTAS2563)
1511         dev_err(pTAS2563->dev, "%s\n", __func__);
1512         pTAS2563->mnErrCode |= ERROR_FAILSAFE;
1513         if (hrtimer_active(&pTAS2563->mtimerwork))
1514                 hrtimer_cancel(&pTAS2563->mtimerwork);
1516         if(pTAS2563->mnRestart < RESTART_MAX)
1517         {
1518                 pTAS2563->mnRestart ++;
1519                 msleep(100);
1520                 dev_err(pTAS2563->dev, "I2C COMM error, restart SmartAmp.\n");
1521                 schedule_delayed_work(&pTAS2563->irq_work, msecs_to_jiffies(100));
1522                 return;
1523         }
1524         pTAS2563->enableIRQ(pTAS2563, false);
1525         tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1527         pTAS2563->mbPowerUp = false;
1528         pTAS2563->hw_reset(pTAS2563);
1529         pTAS2563->write(pTAS2563, TAS2563_SoftwareReset, TAS2563_SoftwareReset_SoftwareReset_Reset);
1530         udelay(1000);
1531         if (pTAS2563->mpFirmware != NULL)
1532                 tas2563_clear_firmware(pTAS2563->mpFirmware);
1534 #endif
1536 /*
1537 * tas2563_load_coefficient
1538 */
1539 static int tas2563_load_coefficient(struct tas2563_priv *pTAS2563,
1540         int nPrevConfig, int nNewConfig, bool bPowerOn)
1542         int nResult = 0;
1543 //      struct TPLL *pPLL;
1544         struct TProgram *pProgram;
1545         struct TConfiguration *pPrevConfiguration;
1546         struct TConfiguration *pNewConfiguration;
1547         bool bRestorePower = false;
1549         if (!pTAS2563->mpFirmware->mnConfigurations) {
1550                 dev_err(pTAS2563->dev, "%s, firmware not loaded\n", __func__);
1551                 goto end;
1552         }
1554         if (nNewConfig >= pTAS2563->mpFirmware->mnConfigurations) {
1555                 dev_err(pTAS2563->dev, "%s, invalid configuration New=%d, total=%d\n",
1556                         __func__, nNewConfig, pTAS2563->mpFirmware->mnConfigurations);
1557                 goto end;
1558         }
1560         if (nPrevConfig < 0)
1561                 pPrevConfiguration = NULL;
1562         else if (nPrevConfig == nNewConfig) {
1563                 dev_info(pTAS2563->dev, "%s, config [%d] already loaded\n",
1564                         __func__, nNewConfig);
1565                 goto end;
1566         } else
1567                 pPrevConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[nPrevConfig]);
1569         pNewConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[nNewConfig]);
1570         pTAS2563->mnCurrentConfiguration = nNewConfig;
1571         pTAS2563->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
1573         dev_info(pTAS2563->dev, "load configuration %s conefficient pre block\n",
1574                 pNewConfiguration->mpName);
1575         nResult = tas2563_load_data(pTAS2563, &(pNewConfiguration->mData), TAS2563_BLOCK_CFG_PRE_DEV_A);
1576         if (nResult < 0)
1577                 goto end;
1579 //prog_coefficient:
1580         dev_info(pTAS2563->dev, "load new configuration: %s, coeff block data\n",
1581                 pNewConfiguration->mpName);
1582         nResult = tas2563_load_data(pTAS2563, &(pNewConfiguration->mData),
1583                 TAS2563_BLOCK_CFG_COEFF_DEV_A);
1584         if (nResult < 0)
1585                 goto end;
1587         if (pTAS2563->mpCalFirmware->mnCalibrations) {
1588                 nResult = tas2563_set_calibration(pTAS2563, pTAS2563->mnCurrentCalibration);
1589                 if (nResult < 0)
1590                         goto end;
1591         }
1593         if (bRestorePower) {
1594                 pTAS2563->clearIRQ(pTAS2563);
1595                 dev_info(pTAS2563->dev, "device powered up, load startup\n");
1596                 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_MUTE);
1597                 if (nResult < 0)
1598                         goto end;
1600                 dev_info(pTAS2563->dev,
1601                         "device powered up, load unmute\n");
1602                 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
1603                 if (nResult < 0)
1604                         goto end;
1605                 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1606                         pTAS2563->enableIRQ(pTAS2563, true);
1607                         if (!hrtimer_active(&pTAS2563->mtimerwork)) {
1608                                 pTAS2563->mnDieTvReadCounter = 0;
1609                                 hrtimer_start(&pTAS2563->mtimerwork,
1610                                         ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1611                         }
1612                 }
1613         }
1614 end:
1616         pTAS2563->mnNewConfiguration = pTAS2563->mnCurrentConfiguration;
1617         return nResult;
1620 static bool tas2563_get_coefficient_in_data(struct tas2563_priv *pTAS2563,
1621         struct TData *pData, int blockType, int nReg, int *pnValue)
1623         bool bFound = false;
1624         struct TBlock *pBlock;
1625         int i;
1627         for (i = 0; i < pData->mnBlocks; i++) {
1628                 pBlock = &(pData->mpBlocks[i]);
1629                 if (pBlock->mnType == blockType) {
1630                         bFound = tas2563_get_coefficient_in_block(pTAS2563,
1631                                                 pBlock, nReg, pnValue);
1632                         if (bFound)
1633                                 break;
1634                 }
1635         }
1637         return bFound;
1640 static bool tas2563_find_Tmax_in_configuration(struct tas2563_priv *pTAS2563,
1641         struct TConfiguration *pConfiguration, int *pnTMax)
1643         struct TData *pData;
1644         bool bFound = false;
1645         int nBlockType, nReg, nCoefficient;
1647         nReg = TAS2563_CALI_T_REG;
1649         nBlockType = TAS2563_BLOCK_CFG_COEFF_DEV_A;
1651         pData = &(pConfiguration->mData);
1652         bFound = tas2563_get_coefficient_in_data(pTAS2563, pData, nBlockType, nReg, &nCoefficient);
1653         if (bFound)
1654                 *pnTMax = nCoefficient;
1656         return bFound;
1659 void tas2563_fw_ready(const struct firmware *pFW, void *pContext)
1661         struct tas2563_priv *pTAS2563 = (struct tas2563_priv *) pContext;
1662         int nResult;
1663         unsigned int nProgram = 0;
1664         unsigned int nSampleRate = 0;
1666 #ifdef CONFIG_TAS2563_CODEC
1667         mutex_lock(&pTAS2563->codec_lock);
1668 #endif
1670 #ifdef CONFIG_TAS2563_MISC
1671         mutex_lock(&pTAS2563->file_lock);
1672 #endif
1674         dev_info(pTAS2563->dev, "%s:\n", __func__);
1676         if (unlikely(!pFW) || unlikely(!pFW->data)) {
1677                 dev_err(pTAS2563->dev, "%s firmware is not loaded.\n",
1678                         TAS2563_FW_NAME);
1679                 goto end;
1680         }
1682         if (pTAS2563->mpFirmware->mpConfigurations) {
1683                 nProgram = pTAS2563->mnCurrentProgram;
1684                 nSampleRate = pTAS2563->mnCurrentSampleRate;
1685                 dev_info(pTAS2563->dev, "clear current firmware\n");
1686                 tas2563_clear_firmware(pTAS2563->mpFirmware);
1687         }
1689         nResult = fw_parse(pTAS2563, pTAS2563->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
1690         release_firmware(pFW);
1691         if (nResult < 0) {
1692                 dev_err(pTAS2563->dev, "firmware is corrupt\n");
1693                 goto end;
1694         }
1696         if (!pTAS2563->mpFirmware->mnPrograms) {
1697                 dev_err(pTAS2563->dev, "firmware contains no programs\n");
1698                 nResult = -EINVAL;
1699                 goto end;
1700         }
1702         if (!pTAS2563->mpFirmware->mnConfigurations) {
1703                 dev_err(pTAS2563->dev, "firmware contains no configurations\n");
1704                 nResult = -EINVAL;
1705                 goto end;
1706         }
1708         if (nProgram >= pTAS2563->mpFirmware->mnPrograms) {
1709                 dev_info(pTAS2563->dev,
1710                         "no previous program, set to default\n");
1711                 nProgram = 0;
1712         }
1714         pTAS2563->mnCurrentSampleRate = nSampleRate;
1715         nResult = tas2563_set_program(pTAS2563, nProgram, -1);
1717 end:
1719 #ifdef CONFIG_TAS2563_CODEC
1720         mutex_unlock(&pTAS2563->codec_lock);
1721 #endif
1723 #ifdef CONFIG_TAS2563_MISC
1724         mutex_unlock(&pTAS2563->file_lock);
1725 #endif
1728 static bool tas2563_get_coefficient_in_block(struct tas2563_priv *pTAS2563,
1729         struct TBlock *pBlock, int nReg, int *pnValue)
1731         int nCoefficient = 0;
1732         bool bFound = false;
1733         unsigned char *pCommands;
1734         int nBook, nPage, nOffset, len;
1735         int i, n;
1737         pCommands = pBlock->mpData;
1738         for (i = 0 ; i < pBlock->mnCommands;) {
1739                 nBook = pCommands[4 * i + 0];
1740                 nPage = pCommands[4 * i + 1];
1741                 nOffset = pCommands[4 * i + 2];
1742                 if ((nOffset < 0x7f) || (nOffset == 0x81))
1743                         i++;
1744                 else if (nOffset == 0x85) {
1745                         len = ((int)nBook << 8) | nPage;
1746                         nBook = pCommands[4 * i + 4];
1747                         nPage = pCommands[4 * i + 5];
1748                         nOffset = pCommands[4 * i + 6];
1749                         n = 4 * i + 7;
1750                         i += 2;
1751                         i += ((len - 1) / 4);
1752                         if ((len - 1) % 4)
1753                                 i++;
1754                         if ((nBook != TAS2563_BOOK_ID(nReg))
1755                                 || (nPage != TAS2563_PAGE_ID(nReg)))
1756                                 continue;
1757                         if (nOffset > TAS2563_PAGE_REG(nReg))
1758                                 continue;
1759                         if ((len + nOffset) >= (TAS2563_PAGE_REG(nReg) + 4)) {
1760                                 n += (TAS2563_PAGE_REG(nReg) - nOffset);
1761                                 nCoefficient = ((int)pCommands[n] << 24)
1762                                                 | ((int)pCommands[n + 1] << 16)
1763                                                 | ((int)pCommands[n + 2] << 8)
1764                                                 | (int)pCommands[n + 3];
1765                                 bFound = true;
1766                                 break;
1767                         }
1768                 } else {
1769                         dev_err(pTAS2563->dev, "%s, format error %d\n", __func__, nOffset);
1770                         break;
1771                 }
1772         }
1774         if (bFound) {
1775                 *pnValue = nCoefficient;
1776                 dev_info(pTAS2563->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", __func__,
1777                         TAS2563_BOOK_ID(nReg), TAS2563_PAGE_ID(nReg), TAS2563_PAGE_REG(nReg),
1778                         nCoefficient);
1779         }
1781         return bFound;
1785 int tas2563_set_program(struct tas2563_priv *pTAS2563,
1786         unsigned int nProgram, int nConfig)
1788         struct TProgram *pProgram;
1789         unsigned int nConfiguration = 0;
1790         unsigned int nSampleRate = 0;
1791         bool bFound = false;
1792         int nResult = 0;
1794         if ((!pTAS2563->mpFirmware->mpPrograms) ||
1795                 (!pTAS2563->mpFirmware->mpConfigurations)) {
1796                 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n", __func__);
1797                 nResult = 0;
1798                 goto end;
1799         }
1801         if (nProgram >= pTAS2563->mpFirmware->mnPrograms) {
1802                 dev_err(pTAS2563->dev, "TAS2563: Program %d doesn't exist\n",
1803                         nProgram);
1804                 nResult = 0;
1805                 goto end;
1806         }
1808         if (nConfig < 0) {
1809                 nConfiguration = 0;
1810                 nSampleRate = pTAS2563->mnCurrentSampleRate;
1811                 while (!bFound && (nConfiguration < pTAS2563->mpFirmware->mnConfigurations)) {
1812                         if (pTAS2563->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
1813                                 if (nSampleRate == 0) {
1814                                         bFound = true;
1815                                         dev_info(pTAS2563->dev, "find default configuration %d\n", nConfiguration);
1816                                 } else if (nSampleRate == pTAS2563->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
1817                                         bFound = true;
1818                                         dev_info(pTAS2563->dev, "find matching configuration %d\n", nConfiguration);
1819                                 } else {
1820                                         nConfiguration++;
1821                                 }
1822                         } else {
1823                                 nConfiguration++;
1824                         }
1825                 }
1826                 if (!bFound) {
1827                         dev_err(pTAS2563->dev,
1828                                 "Program %d, no valid configuration found for sample rate %d, ignore\n",
1829                                 nProgram, nSampleRate);
1830                         nResult = 0;
1831                         goto end;
1832                 }
1833         } else {
1834                 if (pTAS2563->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
1835                         dev_err(pTAS2563->dev, "%s, configuration program doesn't match\n", __func__);
1836                         nResult = 0;
1837                         goto end;
1838                 }
1839                 nConfiguration = nConfig;
1840         }
1842         pProgram = &(pTAS2563->mpFirmware->mpPrograms[nProgram]);
1843         if (pTAS2563->mbPowerUp) {
1844                 dev_info(pTAS2563->dev,
1845                         "device powered up, power down to load program %d (%s)\n",
1846                         nProgram, pProgram->mpName);
1847                 if (hrtimer_active(&pTAS2563->mtimerwork))
1848                         hrtimer_cancel(&pTAS2563->mtimerwork);
1850                 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE)
1851                         pTAS2563->enableIRQ(pTAS2563, false);
1853                 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1854                 if (nResult < 0)
1855                         goto end;
1856         }
1858         pTAS2563->hw_reset(pTAS2563);
1859         nResult = pTAS2563->write(pTAS2563, TAS2563_SoftwareReset, 0x01);
1860         if (nResult < 0)
1861                 goto end;
1862         msleep(1);
1864         dev_info(pTAS2563->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
1865         nResult = tas2563_load_data(pTAS2563, &(pProgram->mData), TAS2563_BLOCK_PGM_DEV_A);
1866         if (nResult < 0)
1867                 goto end;
1868         pTAS2563->mnCurrentProgram = nProgram;
1870         nResult = tas2563_load_coefficient(pTAS2563, -1, nConfiguration, false);
1871         if (nResult < 0)
1872                 goto end;
1874         nResult = tas2563_load_default(pTAS2563);
1875         if (nResult < 0)
1876                 goto end;
1878         // Enable IV data
1879         nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
1880                                 TAS2563_PowerControl_ISNSPower_Mask |
1881                                 TAS2563_PowerControl_VSNSPower_Mask,
1882                                 TAS2563_PowerControl_VSNSPower_Active |
1883                                 TAS2563_PowerControl_ISNSPower_Active);
1884         if (nResult < 0)
1885                 dev_info(pTAS2563->dev, "Enable IV Data Failed: %s\n", __func__);
1887         if (pTAS2563->mbPowerUp) {
1888 //              pTAS2563->clearIRQ(pTAS2563);
1889                 dev_info(pTAS2563->dev, "device powered up, load startup\n");
1890                 nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_MUTE);
1892                 if (nResult < 0)
1893                         goto end;
1894                 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1895                         if (nResult < 0) {
1896                                 tas2563_set_power_state(pTAS2563, TAS2563_POWER_SHUTDOWN);
1897                                 pTAS2563->mbPowerUp = false;
1898                                 goto end;
1899                         }
1900                 }
1901                 dev_info(pTAS2563->dev, "device powered up, load unmute\n");
1902                 tas2563_set_power_state(pTAS2563, TAS2563_POWER_ACTIVE);
1903                 if (nResult < 0)
1904                         goto end;
1906                 if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1907                         pTAS2563->enableIRQ(pTAS2563, true);
1908                         if (!hrtimer_active(&pTAS2563->mtimerwork)) {
1909                                 pTAS2563->mnDieTvReadCounter = 0;
1910                                 hrtimer_start(&pTAS2563->mtimerwork,
1911                                         ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1912                         }
1913                 }
1914         }
1916 end:
1918 /*      if (nResult < 0) {
1919                 if (pTAS2563->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
1920                         failsafe(pTAS2563);
1921         }*/
1922         return nResult;
1925 static int tas2563_set_calibration(struct tas2563_priv *pTAS2563, int nCalibration)
1927         struct TCalibration *pCalibration = NULL;
1928         struct TConfiguration *pConfiguration;
1929         struct TProgram *pProgram;
1930         int nTmax = 0;
1931         bool bFound = false;
1932         int nResult = 0;
1934         if ((!pTAS2563->mpFirmware->mpPrograms)
1935                 || (!pTAS2563->mpFirmware->mpConfigurations)) {
1936                 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n\r", __func__);
1937                 nResult = 0;
1938                 goto end;
1939         }
1941         if (nCalibration == 0x00FF) {
1942                 nResult = tas2563_load_calibration(pTAS2563, TAS2563_CAL_NAME);
1943                 if (nResult < 0) {
1944                         dev_info(pTAS2563->dev, "load new calibration file %s fail %d\n",
1945                                 TAS2563_CAL_NAME, nResult);
1946                         goto end;
1947                 }
1948                 nCalibration = 0;
1949         }
1951         if (nCalibration >= pTAS2563->mpCalFirmware->mnCalibrations) {
1952                 dev_err(pTAS2563->dev,
1953                         "Calibration %d doesn't exist\n", nCalibration);
1954                 nResult = 0;
1955                 goto end;
1956         }
1958         pTAS2563->mnCurrentCalibration = nCalibration;
1959         if (pTAS2563->mbLoadConfigurationPrePowerUp)
1960                 goto end;
1962         pCalibration = &(pTAS2563->mpCalFirmware->mpCalibrations[nCalibration]);
1963         pProgram = &(pTAS2563->mpFirmware->mpPrograms[pTAS2563->mnCurrentProgram]);
1964         pConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[pTAS2563->mnCurrentConfiguration]);
1965         if (pProgram->mnAppMode == TAS2563_APP_TUNINGMODE) {
1966                 if (pTAS2563->mbBypassTMax) {
1967                         bFound = tas2563_find_Tmax_in_configuration(pTAS2563, pConfiguration, &nTmax);
1968                         if (bFound && (nTmax == TAS2563_COEFFICIENT_TMAX)) {
1969                                 dev_info(pTAS2563->dev, "%s, config[%s] bypass load calibration\n",
1970                                         __func__, pConfiguration->mpName);
1971                                 goto end;
1972                         }
1973                 }
1975                 dev_info(pTAS2563->dev, "%s, load calibration\n", __func__);
1976                 nResult = tas2563_load_data(pTAS2563, &(pCalibration->mData), TAS2563_BLOCK_CFG_COEFF_DEV_A);
1977                 if (nResult < 0)
1978                         goto end;
1979         }
1981 end:
1982         if (nResult < 0) {
1983                 tas2563_clear_firmware(pTAS2563->mpCalFirmware);
1984                 nResult = tas2563_set_program(pTAS2563, pTAS2563->mnCurrentProgram, pTAS2563->mnCurrentConfiguration);
1985         }
1987         return nResult;
1990 bool tas2563_get_Cali_prm_r0(struct tas2563_priv *pTAS2563, int *prm_r0)
1992         struct TCalibration *pCalibration;
1993         struct TData *pData;
1994         int nReg;
1995         int nCali_Re;
1996         bool bFound = false;
1997         int nBlockType;
1999         if (!pTAS2563->mpCalFirmware->mnCalibrations) {
2000                 dev_err(pTAS2563->dev, "%s, no calibration data\n", __func__);
2001                 goto end;
2002         }
2004         nReg = TAS2563_CALI_R0_REG;
2005         nBlockType = TAS2563_BLOCK_CFG_COEFF_DEV_A;
2007         pCalibration = &(pTAS2563->mpCalFirmware->mpCalibrations[pTAS2563->mnCurrentCalibration]);
2008         pData = &(pCalibration->mData);
2010         bFound = tas2563_get_coefficient_in_data(pTAS2563, pData, nBlockType, nReg, &nCali_Re);
2012 end:
2014         if (bFound)
2015                 *prm_r0 = nCali_Re;
2017         return bFound;
2020 int tas2563_set_config(struct tas2563_priv *pTAS2563, int config)
2022         struct TConfiguration *pConfiguration;
2023         struct TProgram *pProgram;
2024         unsigned int nProgram = pTAS2563->mnCurrentProgram;
2025         unsigned int nConfiguration = config;
2026         int nResult = 0;
2028         if ((!pTAS2563->mpFirmware->mpPrograms) ||
2029                 (!pTAS2563->mpFirmware->mpConfigurations)) {
2030                 dev_err(pTAS2563->dev, "%s, Firmware not loaded\n", __func__);
2031                 nResult = -EINVAL;
2032                 goto end;
2033         }
2035         if (nConfiguration >= pTAS2563->mpFirmware->mnConfigurations) {
2036                 dev_err(pTAS2563->dev, "Configuration %d doesn't exist\n",
2037                         nConfiguration);
2038                 nResult = -EINVAL;
2039                 goto end;
2040         }
2042         pConfiguration = &(pTAS2563->mpFirmware->mpConfigurations[nConfiguration]);
2043         pProgram = &(pTAS2563->mpFirmware->mpPrograms[nProgram]);
2045         if (nProgram != pConfiguration->mnProgram) {
2046                 dev_err(pTAS2563->dev,
2047                         "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
2048                         nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
2049                         nProgram, pProgram->mpName);
2050                 nResult = -EINVAL;
2051                 goto end;
2052         }
2054         nResult = tas2563_load_configuration(pTAS2563, nConfiguration, false);
2056 end:
2058         return nResult;
2061 static int tas2563_configuration_get(struct snd_kcontrol *pKcontrol,
2062         struct snd_ctl_elem_value *pValue)
2064 #ifdef KCONTROL_CODEC
2065         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2066 #else
2067         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2068 #endif
2069         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2071         mutex_lock(&pTAS2563->codec_lock);
2073         pValue->value.integer.value[0] = pTAS2563->mnCurrentConfiguration;
2074         dev_info(pTAS2563->dev, "tas2563_configuration_get = %d\n",
2075                 pTAS2563->mnCurrentConfiguration);
2077         mutex_unlock(&pTAS2563->codec_lock);
2078         return 0;
2081 static int tas2563_configuration_put(struct snd_kcontrol *pKcontrol,
2082         struct snd_ctl_elem_value *pValue)
2084 #ifdef KCONTROL_CODEC
2085         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2086 #else
2087         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2088 #endif
2089         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2090         unsigned int nConfiguration = pValue->value.integer.value[0];
2091         int ret = 0;
2093         mutex_lock(&pTAS2563->codec_lock);
2095         dev_info(pTAS2563->dev, "%s = %d\n", __func__, nConfiguration);
2096         ret = tas2563_set_config(pTAS2563, nConfiguration);
2098         mutex_unlock(&pTAS2563->codec_lock);
2099         return ret;
2103 static int tas2563_hw_params(struct snd_pcm_substream *substream,
2104                 struct snd_pcm_hw_params *params,
2105                 struct snd_soc_dai *dai)
2107         struct snd_soc_codec *codec = dai->codec;
2108         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2109         int nResult = 0;
2110         int blr_clk_ratio;
2112         dev_info(pTAS2563->dev, "%s, format: %d\n", __func__,
2113                 params_format(params));
2115         mutex_lock(&pTAS2563->codec_lock);
2117         nResult = tas2563_set_bitwidth(pTAS2563, params_format(params));
2118         if(nResult < 0)
2119         {
2120                 dev_info(pTAS2563->dev, "set bitwidth failed, %d\n", nResult);
2121                 goto ret;
2122         }
2124         blr_clk_ratio = params_channels(params) * pTAS2563->mnCh_size;
2125         dev_info(pTAS2563->dev, "blr_clk_ratio: %d\n", blr_clk_ratio);
2126         if(blr_clk_ratio != 0)
2127                 tas2563_slot_config(pTAS2563->codec, pTAS2563, blr_clk_ratio);
2129         dev_info(pTAS2563->dev, "%s, sample rate: %d\n", __func__,
2130                 params_rate(params));
2132         nResult = tas2563_set_samplerate(pTAS2563, params_rate(params));
2134 ret:
2135         mutex_unlock(&pTAS2563->codec_lock);
2136         return nResult;
2139 static int tas2563_set_fmt(struct tas2563_priv *pTAS2563, unsigned int fmt)
2141         u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
2142         int ret = 0;
2144         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2145         case SND_SOC_DAIFMT_CBS_CFS:
2146                 asi_cfg_1 = 0x00;
2147                 break;
2148         default:
2149                 dev_err(pTAS2563->dev, "ASI format master is not found\n");
2150                 ret = -EINVAL;
2151         }
2153         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2154         case SND_SOC_DAIFMT_NB_NF:
2155                 dev_info(pTAS2563->dev, "INV format: NBNF\n");
2156                 asi_cfg_1 |= TAS2563_TDMConfigurationReg1_RXEDGE_Rising;
2157                 break;
2158         case SND_SOC_DAIFMT_IB_NF:
2159                 dev_info(pTAS2563->dev, "INV format: IBNF\n");
2160                 asi_cfg_1 |= TAS2563_TDMConfigurationReg1_RXEDGE_Falling;
2161                 break;
2162         default:
2163                 dev_err(pTAS2563->dev, "ASI format Inverse is not found\n");
2164                 ret = -EINVAL;
2165         }
2167         pTAS2563->update_bits(pTAS2563, TAS2563_TDMConfigurationReg1,
2168                 TAS2563_TDMConfigurationReg1_RXEDGE_Mask,
2169                 asi_cfg_1);
2171         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2172         case (SND_SOC_DAIFMT_I2S):
2173                 tdm_rx_start_slot = 1;
2174                 break;
2175         case (SND_SOC_DAIFMT_DSP_A):
2176         case (SND_SOC_DAIFMT_DSP_B):
2177                 tdm_rx_start_slot = 1;
2178                 break;
2179         case (SND_SOC_DAIFMT_LEFT_J):
2180                 tdm_rx_start_slot = 0;
2181                 break;
2182         default:
2183         dev_err(pTAS2563->dev, "DAI Format is not found, fmt=0x%x\n", fmt);
2184         ret = -EINVAL;
2185                 break;
2186         }
2188         pTAS2563->update_bits(pTAS2563, TAS2563_TDMConfigurationReg1,
2189                 TAS2563_TDMConfigurationReg1_RXOFFSET51_Mask,
2190         (tdm_rx_start_slot << TAS2563_TDMConfigurationReg1_RXOFFSET51_Shift));
2192         pTAS2563->mnASIFormat = fmt;
2194         return 0;
2198 static int tas2563_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2200         struct snd_soc_codec *codec = dai->codec;
2201         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2202         int ret = 0;
2204         dev_info(pTAS2563->dev, "%s, format=0x%x\n", __func__, fmt);
2206         mutex_lock(&pTAS2563->codec_lock);
2208         ret = tas2563_set_fmt(pTAS2563, fmt);
2210         mutex_unlock(&pTAS2563->codec_lock);
2211         return ret;
2214 static int tas2563_set_dai_tdm_slot(struct snd_soc_dai *dai,
2215                 unsigned int tx_mask, unsigned int rx_mask,
2216                 int slots, int slot_width)
2218         int ret = 0;
2219         struct snd_soc_codec *codec = dai->codec;
2220         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2222         dev_info(pTAS2563->dev, "%s, tx_mask:%d, rx_mask:%d, slots:%d, slot_width:%d",
2223                         __func__, tx_mask, rx_mask, slots, slot_width);
2225         ret = tas2563_set_slot(pTAS2563, slot_width);
2227         return ret;
2230 static int tas2563_program_get(struct snd_kcontrol *pKcontrol,
2231         struct snd_ctl_elem_value *pValue)
2233 #ifdef KCONTROL_CODEC
2234         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2235 #else
2236         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2237 #endif
2238         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2240         mutex_lock(&pTAS2563->codec_lock);
2242         pValue->value.integer.value[0] = pTAS2563->mnCurrentProgram;
2243         dev_info(pTAS2563->dev, "tas2563_program_get = %d\n",
2244                 pTAS2563->mnCurrentProgram);
2246         mutex_unlock(&pTAS2563->codec_lock);
2247         return 0;
2250 static int tas2563_program_put(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);
2259         unsigned int nProgram = pValue->value.integer.value[0];
2260         int ret = 0, nConfiguration = -1;
2262         mutex_lock(&pTAS2563->codec_lock);
2264         if (nProgram == pTAS2563->mnCurrentProgram)
2265                 nConfiguration = pTAS2563->mnCurrentConfiguration;
2266         ret = tas2563_set_program(pTAS2563, nProgram, nConfiguration);
2268         mutex_unlock(&pTAS2563->codec_lock);
2269         return ret;
2272 static int tas2563_calibration_get(struct snd_kcontrol *pKcontrol,
2273         struct snd_ctl_elem_value *pValue)
2275 #ifdef KCONTROL_CODEC
2276         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2277 #else
2278         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2279 #endif
2280         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2282         mutex_lock(&pTAS2563->codec_lock);
2284         pValue->value.integer.value[0] = pTAS2563->mnCurrentCalibration;
2285         dev_info(pTAS2563->dev,
2286                 "tas2563_calibration_get = %d\n",
2287                 pTAS2563->mnCurrentCalibration);
2289         mutex_unlock(&pTAS2563->codec_lock);
2290         return 0;
2293 static int tas2563_calibration_put(struct snd_kcontrol *pKcontrol,
2294         struct snd_ctl_elem_value *pValue)
2296 #ifdef KCONTROL_CODEC
2297         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2298 #else
2299         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2300 #endif
2301         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2302         unsigned int nCalibration = pValue->value.integer.value[0];
2303         int ret = 0;
2305         mutex_lock(&pTAS2563->codec_lock);
2307         ret = tas2563_set_calibration(pTAS2563, nCalibration);
2309         mutex_unlock(&pTAS2563->codec_lock);
2310         return ret;
2313 static struct snd_soc_dai_ops tas2563_dai_ops = {
2314         .digital_mute = tas2563_mute,
2315         .hw_params  = tas2563_hw_params,
2316         .set_fmt    = tas2563_set_dai_fmt,
2317         .set_tdm_slot = tas2563_set_dai_tdm_slot,
2318 };
2320 #define TAS2563_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2321                 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2323 #define TAS2563_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 \
2324                                                 SNDRV_PCM_RATE_88200 |\
2325                                                 SNDRV_PCM_RATE_96000 |\
2326                                                 SNDRV_PCM_RATE_176400 |\
2327                                                 SNDRV_PCM_RATE_192000\
2328                                                 )
2330 static struct snd_soc_dai_driver tas2563_dai_driver[] = {
2331         {
2332                 .name = "tas2563 ASI1",
2333                 .id = 0,
2334                 .playback = {
2335                         .stream_name    = "ASI1 Playback",
2336                         .channels_min   = 2,
2337                         .channels_max   = 2,
2338                         .rates      = SNDRV_PCM_RATE_8000_192000,
2339                         .formats    = TAS2563_FORMATS,
2340                 },
2341                 .capture = {
2342                         .stream_name    = "ASI1 Capture",
2343                         .channels_min   = 0,
2344                         .channels_max   = 2,
2345                         .rates          = SNDRV_PCM_RATE_8000_192000,
2346                         .formats    = TAS2563_FORMATS,
2347                 },
2348                 .ops = &tas2563_dai_ops,
2349                 .symmetric_rates = 1,
2350         },
2351 };
2353 static int tas2563_codec_probe(struct snd_soc_codec *codec)
2355         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2357         pTAS2563->codec = codec;
2358         pTAS2563->set_calibration = tas2563_set_calibration;
2359         pTAS2563->set_config = tas2563_set_config;
2361         dev_err(pTAS2563->dev, "%s\n", __func__);
2363         return 0;
2366 static int tas2563_codec_remove(struct snd_soc_codec *codec)
2368         return 0;
2371 /*static DECLARE_TLV_DB_SCALE(dac_tlv, 0, 100, 0);*/
2372 static DECLARE_TLV_DB_SCALE(tas2563_digital_tlv, 1100, 50, 0);
2374 static const char * const vboost_ctl_text[] = {
2375         "default",
2376         "Device(s) AlwaysOn"
2377 };
2379 static const struct soc_enum vboost_ctl_enum[] = {
2380         SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(vboost_ctl_text), vboost_ctl_text),
2381 };
2383 static int tas2563_vboost_ctl_get(struct snd_kcontrol *pKcontrol,
2384                         struct snd_ctl_elem_value *pValue)
2386 #ifdef KCONTROL_CODEC
2387         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2388 #else
2389         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2390 #endif
2391         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2392         //int nResult = 0, nVBoost = 0;
2394         mutex_lock(&pTAS2563->codec_lock);
2396         pValue->value.integer.value[0] = pTAS2563->mnVBoostState;
2398         mutex_unlock(&pTAS2563->codec_lock);
2399         return 0;
2402 static int tas2563_vboost_ctl_put(struct snd_kcontrol *pKcontrol,
2403                         struct snd_ctl_elem_value *pValue)
2405 #ifdef KCONTROL_CODEC
2406         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
2407 #else
2408         struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
2409 #endif
2410         struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
2411         int vboost_state = pValue->value.integer.value[0];
2413         mutex_lock(&pTAS2563->codec_lock);
2415         if(vboost_state)
2416                 pTAS2563->update_bits(pTAS2563, TAS2563_BoostConfiguration,
2417                         TAS2563_BoostConfiguration_BoostMode_Mask,
2418                         TAS2563_BoostConfiguration_BoostMode_AlwaysOn);
2419         else
2420                 pTAS2563->update_bits(pTAS2563, TAS2563_BoostConfiguration,
2421                         TAS2563_BoostConfiguration_BoostMode_Mask,
2422                         TAS2563_BoostConfiguration_BoostMode_ClassH);
2424         pTAS2563->mnVBoostState = vboost_state;
2425         mutex_unlock(&pTAS2563->codec_lock);
2427         return 0;
2430 static const struct snd_kcontrol_new tas2563_snd_controls[] = {
2431         SOC_SINGLE_TLV("Amp Output Level", TAS2563_PlaybackConfigurationReg0,
2432                 0, 0x16, 0,
2433                 tas2563_digital_tlv),
2434         SOC_SINGLE_EXT("Program", SND_SOC_NOPM, 0, 0x00FF, 0, tas2563_program_get,
2435                 tas2563_program_put),
2436         SOC_SINGLE_EXT("Configuration", SND_SOC_NOPM, 0, 0x00FF, 0,
2437                 tas2563_configuration_get, tas2563_configuration_put),
2438         SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0,
2439                 tas2563_calibration_get, tas2563_calibration_put),
2440         SOC_ENUM_EXT("VBoost Ctrl", vboost_ctl_enum[0],
2441                 tas2563_vboost_ctl_get, tas2563_vboost_ctl_put),
2442 };
2444 static struct snd_soc_codec_driver soc_codec_driver_tas2563 = {
2445         .probe                  = tas2563_codec_probe,
2446         .remove                 = tas2563_codec_remove,
2447         .read                   = tas2563_codec_read,
2448         .write                  = tas2563_codec_write,
2449         .suspend                = tas2563_codec_suspend,
2450         .resume                 = tas2563_codec_resume,
2451 #ifdef KCONTROL_CODEC
2452         .component_driver = {
2453 #endif
2454                 .controls               = tas2563_snd_controls,
2455                 .num_controls           = ARRAY_SIZE(tas2563_snd_controls),
2456                 .dapm_widgets           = tas2563_dapm_widgets,
2457                 .num_dapm_widgets       = ARRAY_SIZE(tas2563_dapm_widgets),
2458                 .dapm_routes            = tas2563_audio_map,
2459                 .num_dapm_routes        = ARRAY_SIZE(tas2563_audio_map),
2460 #ifdef KCONTROL_CODEC
2461         },
2462 #endif
2463 };
2465 int tas2563_register_codec(struct tas2563_priv *pTAS2563)
2467         int nResult = 0;
2469         dev_info(pTAS2563->dev, "%s, enter\n", __func__);
2470         nResult = snd_soc_register_codec(pTAS2563->dev,
2471                 &soc_codec_driver_tas2563,
2472                 tas2563_dai_driver, ARRAY_SIZE(tas2563_dai_driver));
2473         return nResult;
2476 int tas2563_deregister_codec(struct tas2563_priv *pTAS2563)
2478         snd_soc_unregister_codec(pTAS2563->dev);
2480         return 0;
2483 MODULE_AUTHOR("Texas Instruments Inc.");
2484 MODULE_DESCRIPTION("TAS2563 ALSA SOC Smart Amplifier driver");
2485 MODULE_LICENSE("GPL v2");
2486 #endif /* CONFIG_TAS2563_CODEC */