OSDN Git Service

ASoC: tas2559: use power efficient workingqueues
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / sound / soc / codecs / tas2559 / tas2559-core.c
1 /*
2 ** =============================================================================
3 ** Copyright (c) 2016  Texas Instruments Inc.
4 ** Copyright (C) 2017 XiaoMi, Inc.
5 **
6 ** This program is free software; you can redistribute it and/or modify it under
7 ** the terms of the GNU General Public License as published by the Free Software
8 ** Foundation; version 2.
9 **
10 ** This program is distributed in the hope that it will be useful, but WITHOUT
11 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 **
14 ** File:
15 **     tas2559-core.c
16 **
17 ** Description:
18 **     TAS2559 common functions for Android Linux
19 **
20 ** =============================================================================
21 */
22
23 #include <linux/module.h>
24 #include <linux/moduleparam.h>
25 #include <linux/init.h>
26 #include <linux/delay.h>
27 #include <linux/pm.h>
28 #include <linux/i2c.h>
29 #include <linux/gpio.h>
30 #include <linux/regulator/consumer.h>
31 #include <linux/firmware.h>
32 #include <linux/regmap.h>
33 #include <linux/of.h>
34 #include <linux/of_gpio.h>
35 #include <linux/slab.h>
36 #include <linux/syscalls.h>
37 #include <linux/fcntl.h>
38 #include <linux/uaccess.h>
39 #include <linux/crc8.h>
40
41 #include "tas2560.h"
42 #include "tas2559-core.h"
43
44 #define TAS2559_CAL_NAME    "/persist/audio/tas2559_cal.bin"
45 #define RESTART_MAX 3
46
47 static int tas2559_load_calibration(struct tas2559_priv *pTAS2559,
48                                     char *pFileName);
49 static int tas2559_load_data(struct tas2559_priv *pTAS2559, struct TData *pData,
50                              unsigned int nType);
51 static void tas2559_clear_firmware(struct TFirmware *pFirmware);
52 static int tas2559_load_block(struct tas2559_priv *pTAS2559, struct TBlock *pBlock);
53 static int tas2559_load_configuration(struct tas2559_priv *pTAS2559,
54                                       unsigned int nConfiguration, bool bLoadSame);
55
56 #define TAS2559_UDELAY 0xFFFFFFFE
57 #define TAS2559_MDELAY 0xFFFFFFFD
58
59 #define FW_ERR_HEADER -1
60 #define FW_ERR_SIZE -2
61
62 #define TAS2559_BLOCK_PLL                               0x00
63 #define TAS2559_BLOCK_PGM_ALL                   0x0d
64 #define TAS2559_BLOCK_PGM_DEV_A                 0x01
65 #define TAS2559_BLOCK_PGM_DEV_B                 0x08
66 #define TAS2559_BLOCK_CFG_COEFF_DEV_A   0x03
67 #define TAS2559_BLOCK_CFG_COEFF_DEV_B   0x0a
68 #define TAS2559_BLOCK_CFG_PRE_DEV_A             0x04
69 #define TAS2559_BLOCK_CFG_PRE_DEV_B             0x0b
70 #define TAS2559_BLOCK_CFG_POST                  0x05
71 #define TAS2559_BLOCK_CFG_POST_POWER    0x06
72 #define TAS2559_BLOCK_PST_POWERUP_DEV_B 0x0e
73
74 #define PPC_DRIVER_CRCCHK                       0x00000200
75 #define PPC_DRIVER_CONFDEV                      0x00000300
76 #define PPC_DRIVER_CFGDEV_NONCRC        0x00000101
77
78 static unsigned int p_tas2559_default_data[] = {
79         DevA, TAS2559_SAR_ADC2_REG, 0x05,/* enable SAR ADC */
80         DevA, TAS2559_CLK_ERR_CTRL2, 0x21,/*clk1:clock hysteresis, 0.34ms; clock halt, 22ms*/
81         DevA, TAS2559_CLK_ERR_CTRL3, 0x21,/*clk2: rampDown 15dB/us, clock hysteresis, 10.66us; clock halt, 22ms */
82         DevB, TAS2560_CLK_ERR_CTRL2, 0x21,/*rampDown 15dB/us, clock1 hysteresis, 0.34ms; clock2 hysteresis, 10.6us */
83         DevA, TAS2559_SAFE_GUARD_REG, TAS2559_SAFE_GUARD_PATTERN,/* safe guard */
84         DevA, TAS2559_CLK_ERR_CTRL, 0x00,/*enable clock error detection*/
85         DevB, TAS2560_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
86         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
87 };
88
89 static unsigned int p_tas2559_irq_config[] = {
90         DevA, TAS2559_CLK_HALT_REG, 0x71,/* enable clk halt detect2 interrupt */
91         DevA, TAS2559_INT_GEN1_REG, 0x11,/* enable spk OC and OV*/
92         DevA, TAS2559_INT_GEN2_REG, 0x11,/* enable clk err1 and die OT*/
93         DevA, TAS2559_INT_GEN3_REG, 0x11,/* enable clk err2 and brownout*/
94         DevA, TAS2559_INT_GEN4_REG, 0x01,/* disable SAR, enable clk halt*/
95         DevB, TAS2560_INT_GEN_REG, 0xff,/* enable spk OC and OV*/
96         DevA, TAS2559_GPIO4_PIN_REG, 0x07,/* set GPIO4 as int1, default*/
97         DevB, TAS2560_IRQ_PIN_REG, 0x41,
98         DevA, TAS2559_INT_MODE_REG, 0x80,/* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */
99         DevB, TAS2560_INT_MODE_REG, 0x80,/* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */
100         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
101 };
102
103 static unsigned int p_tas2559_startup_data[] = {
104         DevA, TAS2559_GPIO1_PIN_REG, 0x01,/* enable BCLK */
105         DevA, TAS2559_GPIO2_PIN_REG, 0x01,/* enable WCLK */
106         DevA, TAS2559_POWER_CTRL2_REG, 0xA0,/*Class-D, Boost power up*/
107         DevA, TAS2559_POWER_CTRL2_REG, 0xA3,/*Class-D, Boost, IV sense power up*/
108         DevA, TAS2559_POWER_CTRL1_REG, 0xF8,/*PLL, DSP, clock dividers power up*/
109         DevBoth, TAS2559_UDELAY, 2000,/*delay*/
110         DevB, TAS2560_DEV_MODE_REG, 0x02,
111         DevB, TAS2560_MUTE_REG, 0x41,
112         DevBoth, TAS2559_UDELAY, 2000,/*delay*/
113         DevA, TAS2559_CLK_ERR_CTRL, 0x2B,/*enable clock error detection*/
114         DevB, TAS2560_CLK_ERR_CTRL, 0x0B,/* disable clock error detection */
115         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
116 };
117
118 static unsigned int p_tas2559_mute_data[] = {
119         DevA, TAS2559_SOFT_MUTE_REG, 0x01,/*soft mute*/
120         DevB, TAS2560_MUTE_REG, 0x41,
121         DevA, TAS2559_MDELAY, 10,/*delay 10ms*/
122         DevA, TAS2559_MUTE_REG, 0x03,/*mute*/
123         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
124 };
125
126 static unsigned int p_tas2559_unmute_data[] = {
127         DevA, TAS2559_MUTE_REG, 0x00,           /*unmute*/
128         DevB, TAS2560_MUTE_REG, 0x40,
129         DevA, TAS2559_SOFT_MUTE_REG, 0x00,      /*soft unmute*/
130         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
131 };
132
133 static unsigned int p_tas2559_shutdown_data[] = {
134         DevA, TAS2559_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
135         DevB, TAS2560_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
136         DevA, TAS2559_SOFT_MUTE_REG, 0x01,/*soft mute*/
137         DevB, TAS2560_MUTE_REG, 0x41,
138         DevB, TAS2560_MUTE_REG, 0x01,
139         DevBoth, TAS2559_MDELAY, 10,/*delay 10ms*/
140         DevB, TAS2559_MDELAY, 20,/*delay 20ms*/
141         DevA, TAS2559_POWER_CTRL1_REG, 0x60,/*DSP power down*/
142         DevA, TAS2559_MDELAY, 2,/*delay 20ms*/
143         DevA, TAS2559_MUTE_REG, 0x03,/*mute*/
144         DevA, TAS2559_POWER_CTRL2_REG, 0x00,/*Class-D, Boost power down*/
145         DevA, TAS2559_POWER_CTRL1_REG, 0x00,/*all power down*/
146         DevB, TAS2560_DEV_MODE_REG, 0x01,
147         DevA, TAS2559_GPIO1_PIN_REG, 0x00,/* disable BCLK */
148         DevA, TAS2559_GPIO2_PIN_REG, 0x00,/* disable WCLK */
149         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
150 };
151
152 static unsigned int p_tas2559_shutdown_DevB_data[] = {
153         DevA, TAS2559_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
154         DevB, TAS2560_CLK_ERR_CTRL, 0x00,/* disable clock error detection */
155         DevB, TAS2560_MUTE_REG, 0x41,
156         DevB, TAS2560_MUTE_REG, 0x01,
157         DevA, TAS2559_POWER_CTRL1_REG, 0x60,/*DSP power down*/
158         DevBoth, TAS2559_MDELAY, 30,/*delay 2ms*/
159         DevB, TAS2560_DEV_MODE_REG, 0x01,
160         DevA, TAS2559_POWER_CTRL2_REG, 0x00,/*Class-D, Boost power down*/
161         DevA, TAS2559_POWER_CTRL1_REG, 0x00,/*all power down*/
162         DevA, TAS2559_GPIO1_PIN_REG, 0x00,/* disable BCLK */
163         DevA, TAS2559_GPIO2_PIN_REG, 0x00,/* disable WCLK */
164         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
165 };
166
167 static int tas2559_dev_load_data(struct tas2559_priv *pTAS2559,
168                                  enum channel dev, unsigned int *pData)
169 {
170         int nResult = 0;
171         unsigned int n = 0;
172         unsigned int nRegister;
173         unsigned int nData;
174         enum channel chl;
175
176         do {
177                 chl = pData[n * 3];
178
179                 if (chl == 0xffffffff)
180                         break;
181
182                 if (dev & chl) {
183                         nRegister = pData[n * 3 + 1];
184                         nData = pData[n * 3 + 2];
185
186                         if (nRegister == TAS2559_UDELAY) {
187                                 udelay(nData);
188                                 dev_dbg(pTAS2559->dev, "%s, udelay %d\n", __func__, nData);
189                         } else if (nRegister == TAS2559_MDELAY) {
190                                 mdelay(nData);
191                                 dev_dbg(pTAS2559->dev, "%s, msleep %d\n", __func__, nData);
192                         } else if (nRegister != 0xFFFFFFFF) {
193                                 dev_dbg(pTAS2559->dev, "%s, write chl=%d, B[%d]P[%d]R[%d]=0x%x\n",
194                                         __func__, chl, TAS2559_BOOK_ID(nRegister),
195                                         TAS2559_PAGE_ID(nRegister), TAS2559_PAGE_REG(nRegister), nData);
196                                 nResult = pTAS2559->write(pTAS2559, chl, nRegister, nData);
197                                 if (nResult < 0)
198                                         break;
199                         }
200                 }
201
202                 n++;
203         } while (nRegister != 0xFFFFFFFF);
204
205         return nResult;
206 }
207
208 /* reserved
209 *static int tas2559_dev_load_blk_data(struct tas2559_priv *pTAS2559,
210 *       enum channel chl, unsigned int *pData)
211 *{
212 *       unsigned int nRegister;
213 *       unsigned int *nData;
214 *       unsigned char Buf[128];
215 *       unsigned int nLength = 0;
216 *       unsigned int i =0;
217 *       unsigned int nSize = 0;
218 *       int nResult = 0;
219 *
220 *       do {
221 *               nRegister = pData[nLength];
222 *               nSize = pData[nLength + 1];
223 *               nData = &pData[nLength + 2];
224 *               if (nRegister == TAS2559_MDELAY) {
225 *                       mdelay(nData[0]);
226 *                       dev_dbg(pTAS2559->dev, "%s, mDelay %d\n", __func__, nData[0]);
227 *               } else if (nRegister == 0xFFFFFFFF) {
228 *                       dev_dbg(pTAS2559->dev, "%s, end\n", __func__);
229 *                       break;
230 *               } else if (nSize > 128) {
231 *                       dev_err(pTAS2559->dev, "%s, maximum is 128 bytes!\n",
232 *                                       __func__);
233 *                       break;
234 *               } else if (nSize == 0) {
235 *                       dev_err(pTAS2559->dev, "%s, minimum is 1 bytes!\n",
236 *                                       __func__);
237 *                       break;
238 *               } else {
239 *                       if (nSize > 1) {
240 *                               for(i = 0; i < nSize; i++)
241 *                                       Buf[i] = (unsigned char)nData[i];
242 *                               dev_dbg(pTAS2559->dev, "%s, BW B[%d]P[%d]R[%d], size=%d, D0=0x%x\n",
243 *                                       __func__, TAS2559_BOOK_ID(nRegister), TAS2559_PAGE_ID(nRegister),
244 *                                       TAS2559_PAGE_REG(nRegister), nSize, Buf[0]);
245 *                               nResult = pTAS2559->bulk_write(pTAS2559, chl, nRegister, Buf, nSize);
246 *                       } else {
247 *                               dev_dbg(pTAS2559->dev, "%s, W B[%d]P[%d]R[%d], Data=0x%x\n",
248 *                                       __func__, TAS2559_BOOK_ID(nRegister), TAS2559_PAGE_ID(nRegister),
249 *                                       TAS2559_PAGE_REG(nRegister), nData[0]);
250 *                               nResult = pTAS2559->write(pTAS2559,chl,nRegister, nData[0]);
251 *                       }
252 *                       if (nResult < 0)
253 *                               break;
254 *               }
255 *               nLength = nLength + 2 + pData[nLength+1] ;
256 *       } while (nRegister != 0xFFFFFFFF);
257 *
258 *       return nResult;
259 *}
260 */
261
262 static int tas2559_DevStartup(struct tas2559_priv *pTAS2559,
263                               unsigned int dev)
264 {
265         int nResult = 0;
266         enum channel chl = dev;
267
268         if (dev == DevB)
269                 chl = DevBoth;
270
271         dev_dbg(pTAS2559->dev, "%s, chl=%d\n", __func__, chl);
272         nResult = tas2559_dev_load_data(pTAS2559, chl, p_tas2559_startup_data);
273
274         return nResult;
275 }
276
277 static int tas2559_DevShutdown(struct tas2559_priv *pTAS2559,
278                                unsigned int dev)
279 {
280         int nResult = 0;
281
282         dev_dbg(pTAS2559->dev, "%s, dev=%d\n", __func__, dev);
283
284         if (dev == DevB)
285                 nResult = tas2559_dev_load_data(pTAS2559, dev, p_tas2559_shutdown_DevB_data);
286         else
287                 nResult = tas2559_dev_load_data(pTAS2559, dev, p_tas2559_shutdown_data);
288
289         return nResult;
290 }
291
292 int tas2559_configIRQ(struct tas2559_priv *pTAS2559, enum channel dev)
293 {
294         return tas2559_dev_load_data(pTAS2559, dev, p_tas2559_irq_config);
295 }
296
297 int tas2559_SA_DevChnSetup(struct tas2559_priv *pTAS2559, unsigned int mode)
298 {
299         int nResult = 0;
300         struct TProgram *pProgram;
301         unsigned char buf_mute[16] = {0};
302         unsigned char buf_DevA_Left_DevB_Right[16] = {0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0};
303         unsigned char buf_DevA_Right_DevB_Left[16] = {0, 0, 0, 0, 0x40, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0};
304         unsigned char buf_DevA_MonoMix_DevB_MonoMix[16] = {0x20, 0, 0, 0, 0x20, 0, 0, 0, 0x20, 0, 0, 0, 0x20, 0, 0, 0};
305         unsigned char *pDevBuf = NULL;
306
307         dev_dbg(pTAS2559->dev, "%s, mode %d\n", __func__, mode);
308         if ((pTAS2559->mpFirmware->mnPrograms == 0)
309             || (pTAS2559->mpFirmware->mnConfigurations == 0)) {
310                 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
311                 goto end;
312         }
313
314         pProgram = &(pTAS2559->mpFirmware->mpPrograms[pTAS2559->mnCurrentProgram]);
315         if (pProgram->mnAppMode != TAS2559_APP_TUNINGMODE) {
316                 dev_err(pTAS2559->dev, "%s, not tuning mode\n", __func__);
317                 goto end;
318         }
319
320         if (pTAS2559->mbLoadConfigurationPrePowerUp) {
321                 dev_dbg(pTAS2559->dev, "%s, setup channel after coeff update\n", __func__);
322                 pTAS2559->mnChannelState = mode;
323                 goto end;
324         }
325
326         switch (mode) {
327         case TAS2559_AD_BD:
328                 pDevBuf = pTAS2559->mnDefaultChlData;
329                 break;
330
331         case TAS2559_AM_BM:
332                 pDevBuf = buf_mute;
333                 break;
334
335         case TAS2559_AL_BR:
336                 pDevBuf = buf_DevA_Left_DevB_Right;
337                 break;
338
339         case TAS2559_AR_BL:
340                 pDevBuf = buf_DevA_Right_DevB_Left;
341                 break;
342
343         case TAS2559_AH_BH:
344                 pDevBuf = buf_DevA_MonoMix_DevB_MonoMix;
345                 break;
346
347         default:
348                 goto end;
349         }
350
351         if (pDevBuf) {
352                 nResult = pTAS2559->bulk_write(pTAS2559, DevA,
353                                 TAS2559_SA_CHL_CTRL_REG, pDevBuf, 16);
354                 if (nResult < 0)
355                         goto end;
356                 pTAS2559->mnChannelState = mode;
357         }
358
359 end:
360         return nResult;
361 }
362
363 int tas2559_SA_ctl_echoRef(struct tas2559_priv *pTAS2559)
364 {
365         int nResult = 0;
366
367         /*
368         * by default:
369         * TAS2559 echo-ref is on DOUT left channel,
370         * TAS2560 echo-ref is on DOUT right channel
371         */
372         return nResult;
373 }
374
375 int tas2559_set_DAC_gain(struct tas2559_priv *pTAS2559,
376                          enum channel chl, unsigned int nGain)
377 {
378         int nResult = 0;
379         int gain = (nGain & 0x0f);
380
381         if (chl & DevA) {
382                 nResult = pTAS2559->update_bits(pTAS2559, DevA,
383                                                 TAS2559_SPK_CTRL_REG, 0x78, (gain << 3));
384
385                 if (nResult < 0)
386                         goto end;
387         }
388
389         if (chl & DevB)
390                 nResult = pTAS2559->update_bits(pTAS2559, DevB,
391                                                 TAS2560_SPK_CTRL_REG, 0x0f, gain);
392
393 end:
394
395         return nResult;
396 }
397
398 int tas2559_get_DAC_gain(struct tas2559_priv *pTAS2559,
399                          enum channel chl, unsigned char *pnGain)
400 {
401         int nResult = 0;
402         int nGain;
403
404         if (chl == DevA) {
405                 nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_SPK_CTRL_REG, &nGain);
406
407                 if (nResult >= 0)
408                         *pnGain = ((nGain >> 3) & 0x0f);
409         } else
410                 if (chl == DevB) {
411                         nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_SPK_CTRL_REG, &nGain);
412
413                         if (nResult >= 0)
414                                 *pnGain = (nGain & 0x0f);
415                 }
416
417         return nResult;
418 }
419
420 int tas2559_set_bit_rate(struct tas2559_priv *pTAS2559, unsigned int nBitRate)
421 {
422         int nResult = 0, n = -1;
423
424         dev_dbg(pTAS2559->dev, "%s: nBitRate = %d\n", __func__, nBitRate);
425
426         switch (nBitRate) {
427         case 16:
428                 n = 0;
429                 break;
430
431         case 20:
432                 n = 1;
433                 break;
434
435         case 24:
436                 n = 2;
437                 break;
438
439         case 32:
440                 n = 3;
441                 break;
442         }
443
444         if (n >= 0) {
445                 nResult = pTAS2559->update_bits(pTAS2559, DevA,
446                                                 TAS2559_ASI1_DAC_FORMAT_REG, 0x18, n << 3);
447                 if (nResult >= 0) {
448                         /* The ASIM is always configured for 16-bits, hardcode the TAS2560 to 16-bits */
449                         nResult = pTAS2559->update_bits(pTAS2559, DevB,
450                                                         TAS2560_DAI_FMT, 0x03, 0);
451                 }
452         }
453
454         return nResult;
455 }
456
457 int tas2559_get_bit_rate(struct tas2559_priv *pTAS2559, unsigned char *pBitRate)
458 {
459         int nResult = 0;
460         unsigned int nValue = 0;
461         unsigned char bitRate;
462
463         nResult = pTAS2559->read(pTAS2559, DevA,
464                                  TAS2559_ASI1_DAC_FORMAT_REG, &nValue);
465
466         if (nResult >= 0) {
467                 bitRate = (nValue & 0x18) >> 3;
468
469                 if (bitRate == 0)
470                         bitRate = 16;
471                 else
472                         if (bitRate == 1)
473                                 bitRate = 20;
474                         else
475                                 if (bitRate == 2)
476                                         bitRate = 24;
477                                 else
478                                         bitRate = 32;
479
480                 *pBitRate = bitRate;
481         }
482
483         return nResult;
484 }
485
486 int tas2559_DevMute(struct tas2559_priv *pTAS2559, enum channel dev, bool mute)
487 {
488         int nResult = 0;
489
490         dev_dbg(pTAS2559->dev, "%s, dev=%d, mute=%d\n", __func__, dev, mute);
491
492         if (mute)
493                 nResult = tas2559_dev_load_data(pTAS2559, dev, p_tas2559_mute_data);
494         else
495                 nResult = tas2559_dev_load_data(pTAS2559, dev, p_tas2559_unmute_data);
496
497         return nResult;
498 }
499
500 int tas2559_DevMuteStatus(struct tas2559_priv *pTAS2559, enum channel dev, bool *pMute)
501 {
502         int nResult = 0;
503         int nMute = 0;
504
505         if (dev == DevA)
506                 nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_SOFT_MUTE_REG, &nMute);
507         else if (dev == DevB)
508                 nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_MUTE_REG, &nMute);
509         else
510                 goto end;
511
512         *pMute = ((nMute & 0x01) == 0x00);
513
514 end:
515         return nResult;
516 }
517
518 /*
519 * die temperature calculation:
520 * DieTemp = readout / 2^23
521 */
522 int tas2559_get_die_temperature(struct tas2559_priv *pTAS2559, int *pTemperature)
523 {
524         int nResult = 0;
525         unsigned char nBuf[4];
526         int temp;
527
528         if (!pTAS2559->mpFirmware->mnConfigurations) {
529                 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
530                 goto end;
531         }
532
533         if (!pTAS2559->mbPowerUp) {
534                 dev_err(pTAS2559->dev, "%s, device not powered on\n", __func__);
535                 goto end;
536         }
537
538         /* TAS2559 should always be enabled */
539         nResult = pTAS2559->bulk_read(pTAS2559, DevA, TAS2559_DIE_TEMP_REG, nBuf, 4);
540
541         if (nResult >= 0) {
542                 temp = ((int)nBuf[0] << 24) | ((int)nBuf[1] << 16) | ((int)nBuf[2] << 8) | nBuf[3];
543                 *pTemperature = temp;
544         }
545
546 end:
547
548         return nResult;
549 }
550
551 int tas2559_update_VBstVolt(struct tas2559_priv *pTAS2559, enum channel chn)
552 {
553         int nResult = 0;
554         int nVBstVoltSet = -1;
555
556         switch (pTAS2559->mnVBoostVoltage) {
557         case TAS2559_VBST_8P5V:
558                 nVBstVoltSet = 6;
559                 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be 0dB\n", __func__);
560         break;
561
562         case TAS2559_VBST_8P1V:
563                 nVBstVoltSet = 5;
564                 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be -1dB\n", __func__);
565         break;
566
567         case TAS2559_VBST_7P6V:
568                 nVBstVoltSet = 4;
569                 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be -2dB\n", __func__);
570         break;
571
572         case TAS2559_VBST_6P6V:
573                 nVBstVoltSet = 2;
574                 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be -3dB\n", __func__);
575         break;
576
577         case TAS2559_VBST_5P6V:
578                 nVBstVoltSet = 0;
579                 dev_warn(pTAS2559->dev, "%s, PPG of this snapshot should be -4dB\n", __func__);
580         break;
581
582         default:
583                 dev_err(pTAS2559->dev, "%s, error volt %d\n", __func__, pTAS2559->mnVBoostVoltage);
584         break;
585         }
586
587         if (nVBstVoltSet >= 0) {
588                 if (chn & DevA)
589                         nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_VBST_VOLT_REG, 0xe0, (nVBstVoltSet << 5));
590                 if (chn & DevB) {
591                         nResult = pTAS2559->update_bits(pTAS2559, DevB, TAS2560_VBST_VOLT_REG, 0xe0, (nVBstVoltSet << 5));
592                 }
593                 dev_dbg(pTAS2559->dev, "%s, set vbst voltage (%d channel) 0x%x\n", __func__, chn, (nVBstVoltSet << 5));
594         }
595
596         return nResult;
597 }
598
599 int tas2559_get_VBoost(struct tas2559_priv *pTAS2559, int *pVBoost)
600 {
601         int nResult = 0;
602
603         dev_dbg(pTAS2559->dev, "%s, VBoost state %d\n", __func__, pTAS2559->mnVBoostState);
604         switch (pTAS2559->mnVBoostState) {
605         case TAS2559_VBST_NEED_DEFAULT:
606         case TAS2559_VBST_DEFAULT:
607                 *pVBoost = 0;
608         break;
609
610         case TAS2559_VBST_A_ON:
611         case TAS2559_VBST_B_ON:
612         case TAS2559_VBST_A_ON_B_ON:
613                 *pVBoost = 1;
614         break;
615         default:
616                 dev_err(pTAS2559->dev, "%s, error state %d\n", __func__, pTAS2559->mnVBoostState);
617         break;
618         }
619
620         return nResult;
621 }
622
623 static int tas2559_restore_VBstCtl(struct tas2559_priv *pTAS2559, enum channel chn)
624 {
625         int nResult = 0;
626         unsigned int nDevAVBstCtrl, nDevASlpCtrl, nDevABstLevel;
627         unsigned int nDevBVBstCtrl, nDevBSlpCtrl, nDevBBstLevel;
628
629         if (chn & DevA) {
630                 nDevAVBstCtrl = pTAS2559->mnVBoostDefaultCfg[0];
631                 nDevASlpCtrl = pTAS2559->mnVBoostDefaultCfg[1];
632                 nDevABstLevel = pTAS2559->mnVBoostDefaultCfg[2];
633                 nResult = pTAS2559->write(pTAS2559, DevA, TAS2559_VBOOST_CTL_REG, nDevAVBstCtrl);
634                 if (nResult < 0)
635                         goto DevB;
636                 nResult = pTAS2559->write(pTAS2559, DevA, TAS2559_SLEEPMODE_CTL_REG, nDevASlpCtrl);
637                 if (nResult < 0)
638                         goto DevB;
639                 nResult = pTAS2559->write(pTAS2559, DevA, TAS2559_VBST_VOLT_REG, nDevABstLevel);
640                 if (nResult < 0)
641                         goto DevB;
642         }
643
644 DevB:
645         if (chn & DevB) {
646                 nDevBVBstCtrl = pTAS2559->mnVBoostDefaultCfg[3];
647                 nDevBSlpCtrl = pTAS2559->mnVBoostDefaultCfg[4];
648                 nDevBBstLevel = pTAS2559->mnVBoostDefaultCfg[5];
649                 nResult = pTAS2559->write(pTAS2559, DevB, TAS2560_VBOOST_CTL_REG, nDevBVBstCtrl);
650                 if (nResult < 0)
651                         goto end;
652                 nResult = pTAS2559->write(pTAS2559, DevB, TAS2560_SLEEPMODE_CTL_REG, nDevBSlpCtrl);
653                 if (nResult < 0)
654                         goto end;
655                 nResult = pTAS2559->write(pTAS2559, DevB, TAS2560_VBST_VOLT_REG, nDevBBstLevel);
656                 if (nResult < 0)
657                         goto end;
658         }
659 end:
660         return nResult;
661 }
662
663 int tas2559_set_VBoost(struct tas2559_priv *pTAS2559, int vboost, bool bPowerOn)
664 {
665         int nResult = 0;
666         struct TConfiguration *pConfiguration;
667         unsigned int nConfig;
668
669         if ((!pTAS2559->mpFirmware->mnConfigurations)
670                 || (!pTAS2559->mpFirmware->mnPrograms)) {
671                 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
672                 goto end;
673         }
674
675         if (bPowerOn) {
676                 dev_info(pTAS2559->dev, "%s, will load VBoost state next time before power on\n", __func__);
677                 pTAS2559->mbLoadVBoostPrePowerUp = true;
678                 pTAS2559->mnVBoostNewState = vboost;
679                 goto end;
680         }
681
682         if (pTAS2559->mbLoadConfigurationPrePowerUp)
683                 nConfig = pTAS2559->mnNewConfiguration;
684         else
685                 nConfig = pTAS2559->mnCurrentConfiguration;
686
687         pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[nConfig]);
688
689         if (pTAS2559->mnVBoostState == TAS2559_VBST_NEED_DEFAULT) {
690                 if (pConfiguration->mnDevices & DevA) {
691                         nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_VBOOST_CTL_REG, &pTAS2559->mnVBoostDefaultCfg[0]);
692                         if (nResult < 0)
693                                 goto end;
694                         nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_SLEEPMODE_CTL_REG, &pTAS2559->mnVBoostDefaultCfg[1]);
695                         if (nResult < 0)
696                                 goto end;
697                         nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_VBST_VOLT_REG, &pTAS2559->mnVBoostDefaultCfg[2]);
698                         if (nResult < 0)
699                                 goto end;
700                 }
701                 if (pConfiguration->mnDevices & DevB) {
702                         nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_VBOOST_CTL_REG, &pTAS2559->mnVBoostDefaultCfg[3]);
703                         if (nResult < 0)
704                                 goto end;
705                         nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_SLEEPMODE_CTL_REG, &pTAS2559->mnVBoostDefaultCfg[4]);
706                         if (nResult < 0)
707                                 goto end;
708                         nResult = pTAS2559->read(pTAS2559, DevB, TAS2560_VBST_VOLT_REG, &pTAS2559->mnVBoostDefaultCfg[5]);
709                         if (nResult < 0)
710                                 goto end;
711                 }
712                 dev_dbg(pTAS2559->dev, "%s, get default VBoost\n", __func__);
713                 pTAS2559->mnVBoostState = TAS2559_VBST_DEFAULT;
714                 if ((vboost == TAS2559_VBST_DEFAULT)
715                         || (vboost == TAS2559_VBST_NEED_DEFAULT)) {
716                         dev_dbg(pTAS2559->dev, "%s, already default, bypass\n", __func__);
717                         goto end;
718                 }
719         }
720
721         if (vboost) {
722                 if (pConfiguration->mnDevices & DevA) {
723                         if (!(pTAS2559->mnVBoostState & TAS2559_VBST_A_ON)) {
724                                 nResult = tas2559_update_VBstVolt(pTAS2559, DevA);
725                                 if (nResult < 0)
726                                         goto end;
727                                 nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_VBOOST_CTL_REG, 0x40, 0x40);
728                                 if (nResult < 0)
729                                         goto end;
730                                 nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_SLEEPMODE_CTL_REG, 0x40, 0x00);
731                                 if (nResult < 0)
732                                         goto end;
733                                 pTAS2559->mnVBoostState |= TAS2559_VBST_A_ON;
734                                 dev_dbg(pTAS2559->dev, "%s, devA Boost On, %d\n", __func__, pTAS2559->mnVBoostState);
735                         }
736                 } else {
737                         if (pTAS2559->mnVBoostState & TAS2559_VBST_A_ON) {
738                                 nResult = tas2559_restore_VBstCtl(pTAS2559, DevA);
739                                 if (nResult < 0)
740                                         goto end;
741                                 pTAS2559->mnVBoostState &= ~TAS2559_VBST_A_ON;
742                                 dev_dbg(pTAS2559->dev, "%s, devA Boost Off, %d\n", __func__, pTAS2559->mnVBoostState);
743                         }
744                 }
745
746                 if (pConfiguration->mnDevices & DevB) {
747                         if (!(pTAS2559->mnVBoostState & TAS2559_VBST_B_ON)) {
748                                 nResult = tas2559_update_VBstVolt(pTAS2559, DevB);
749                                 if (nResult < 0)
750                                         goto end;
751                                 nResult = pTAS2559->update_bits(pTAS2559, DevB, TAS2560_VBOOST_CTL_REG, 0x01, 0x01);
752                                 if (nResult < 0)
753                                         goto end;
754                                 nResult = pTAS2559->update_bits(pTAS2559, DevB, TAS2560_SLEEPMODE_CTL_REG, 0x08, 0x08);
755                                 if (nResult < 0)
756                                         goto end;
757                                 pTAS2559->mnVBoostState |= TAS2559_VBST_B_ON;
758                                 dev_dbg(pTAS2559->dev, "%s, devB Boost On, %d\n", __func__, pTAS2559->mnVBoostState);
759                         }
760                 }  else {
761                         if (pTAS2559->mnVBoostState & TAS2559_VBST_B_ON) {
762                                 nResult = tas2559_restore_VBstCtl(pTAS2559, DevB);
763                                 if (nResult < 0)
764                                         goto end;
765                                 pTAS2559->mnVBoostState &= ~TAS2559_VBST_B_ON;
766                                 dev_dbg(pTAS2559->dev, "%s, devB Boost Off, %d\n", __func__, pTAS2559->mnVBoostState);
767                         }
768                 }
769         } else {
770                 if (pTAS2559->mnVBoostState & TAS2559_VBST_A_ON) {
771                         nResult = tas2559_restore_VBstCtl(pTAS2559, DevA);
772                         if (nResult < 0)
773                                 goto end;
774                         pTAS2559->mnVBoostState &= ~TAS2559_VBST_A_ON;
775                         dev_dbg(pTAS2559->dev, "%s, devA Boost default, %d\n", __func__, pTAS2559->mnVBoostState);
776                 }
777                 if (pTAS2559->mnVBoostState & TAS2559_VBST_B_ON) {
778                         nResult = tas2559_restore_VBstCtl(pTAS2559, DevB);
779                         if (nResult < 0)
780                                 goto end;
781                         pTAS2559->mnVBoostState &= ~TAS2559_VBST_B_ON;
782                         dev_dbg(pTAS2559->dev, "%s, devB Boost default, %d\n", __func__, pTAS2559->mnVBoostState);
783                 }
784         }
785
786 end:
787
788         return 0;
789 }
790
791 int tas2559_load_platdata(struct tas2559_priv *pTAS2559)
792 {
793         int nResult = 0;
794         int nDev = 0;
795
796         dev_dbg(pTAS2559->dev, "%s\n", __func__);
797
798         if (gpio_is_valid(pTAS2559->mnDevAGPIOIRQ))
799                 nDev |= DevA;
800
801         if (gpio_is_valid(pTAS2559->mnDevBGPIOIRQ))
802                 nDev |= DevB;
803
804         if (nDev) {
805                 nResult = tas2559_configIRQ(pTAS2559, nDev);
806
807                 if (nResult < 0)
808                         goto end;
809         }
810
811         nResult = tas2559_set_bit_rate(pTAS2559, pTAS2559->mnBitRate);
812
813         if (nResult < 0)
814                 goto end;
815
816         nResult = tas2559_SA_ctl_echoRef(pTAS2559);
817
818         if (nResult < 0)
819                 goto end;
820
821 end:
822
823         return nResult;
824 }
825
826 int tas2559_load_default(struct tas2559_priv *pTAS2559)
827 {
828         int nResult = 0;
829
830         dev_dbg(pTAS2559->dev, "%s\n", __func__);
831         nResult = tas2559_dev_load_data(pTAS2559, DevBoth, p_tas2559_default_data);
832
833         if (nResult < 0)
834                 goto end;
835
836         nResult = tas2559_load_platdata(pTAS2559);
837
838         if (nResult < 0)
839                 goto end;
840
841         /* enable DOUT tri-state for extra BCLKs */
842         nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_ASI1_DAC_FORMAT_REG, 0x01, 0x01);
843
844         if (nResult < 0)
845                 goto end;
846
847         nResult = pTAS2559->update_bits(pTAS2559, DevB, TAS2560_ASI_CFG_1, 0x02, 0x02);
848
849         if (nResult < 0)
850                 goto end;
851
852         /* Interrupt pin, low-highZ, high active driven */
853         nResult = pTAS2559->update_bits(pTAS2559, DevA, TAS2559_GPIO_HIZ_CTRL2_REG, 0x30, 0x30);
854
855 end:
856
857         return nResult;
858 }
859
860 static void failsafe(struct tas2559_priv *pTAS2559)
861 {
862         dev_err(pTAS2559->dev, "%s\n", __func__);
863         pTAS2559->mnErrCode |= ERROR_FAILSAFE;
864
865         if (hrtimer_active(&pTAS2559->mtimer))
866                 hrtimer_cancel(&pTAS2559->mtimer);
867
868         if (pTAS2559->mnRestart < RESTART_MAX) {
869                 pTAS2559->mnRestart++;
870                 msleep(100);
871                 dev_err(pTAS2559->dev, "I2C COMM error, restart SmartAmp.\n");
872                 queue_delayed_work(system_power_efficient_wq, &pTAS2559->irq_work, msecs_to_jiffies(100));
873                 return;
874         }
875
876         pTAS2559->enableIRQ(pTAS2559, DevBoth, false);
877         tas2559_DevShutdown(pTAS2559, DevBoth);
878         pTAS2559->mbPowerUp = false;
879         pTAS2559->hw_reset(pTAS2559);
880         pTAS2559->write(pTAS2559, DevBoth, TAS2559_SW_RESET_REG, 0x01);
881         msleep(1);
882         pTAS2559->write(pTAS2559, DevA, TAS2559_SPK_CTRL_REG, 0x04);
883         pTAS2559->write(pTAS2559, DevB, TAS2560_SPK_CTRL_REG, 0x50);
884
885         if (pTAS2559->mpFirmware != NULL)
886                 tas2559_clear_firmware(pTAS2559->mpFirmware);
887 }
888
889 int tas2559_checkPLL(struct tas2559_priv *pTAS2559)
890 {
891         int nResult = 0;
892         /*
893         * TO DO
894         */
895
896         return nResult;
897 }
898
899 /*
900 * tas2559_load_coefficient
901 */
902 static int tas2559_load_coefficient(struct tas2559_priv *pTAS2559,
903                                     int nPrevConfig, int nNewConfig, bool bPowerOn)
904 {
905         int nResult = 0;
906         struct TPLL *pPLL;
907         struct TProgram *pProgram = NULL;
908         struct TConfiguration *pPrevConfiguration;
909         struct TConfiguration *pNewConfiguration;
910         enum channel chl;
911         bool bRestorePower = false;
912
913         dev_dbg(pTAS2559->dev, "%s, Prev=%d, new=%d, Pow=%d\n",
914                 __func__, nPrevConfig, nNewConfig, bPowerOn);
915
916         if (!pTAS2559->mpFirmware->mnConfigurations) {
917                 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
918                 goto end;
919         }
920
921         if (nNewConfig >= pTAS2559->mpFirmware->mnConfigurations) {
922                 dev_err(pTAS2559->dev, "%s, invalid configuration New=%d, total=%d\n",
923                         __func__, nNewConfig, pTAS2559->mpFirmware->mnConfigurations);
924                 goto end;
925         }
926
927         if (nPrevConfig < 0) {
928                 pPrevConfiguration = NULL;
929                 chl = DevBoth;
930         } else
931                 if (nPrevConfig == nNewConfig) {
932                         dev_dbg(pTAS2559->dev, "%d configuration is already loaded\n", nNewConfig);
933                         goto end;
934                 } else {
935                         pPrevConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[nPrevConfig]);
936                         chl = pPrevConfiguration->mnDevices;
937                 }
938
939         pNewConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[nNewConfig]);
940         pTAS2559->mnCurrentConfiguration = nNewConfig;
941
942         if (pPrevConfiguration) {
943                 if ((pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL)
944                     && (pPrevConfiguration->mnDevices == pNewConfiguration->mnDevices)) {
945                         dev_dbg(pTAS2559->dev, "%s, PLL and device same\n", __func__);
946                         goto prog_coefficient;
947                 }
948         }
949
950         pProgram = &(pTAS2559->mpFirmware->mpPrograms[pTAS2559->mnCurrentProgram]);
951
952         if (bPowerOn) {
953                 if (hrtimer_active(&pTAS2559->mtimer))
954                         hrtimer_cancel(&pTAS2559->mtimer);
955
956                 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE)
957                         pTAS2559->enableIRQ(pTAS2559, DevBoth, false);
958
959                 nResult = tas2559_DevShutdown(pTAS2559, chl);
960
961                 if (nResult < 0)
962                         goto end;
963
964                 bRestorePower = true;
965         }
966
967         /* load PLL */
968         pPLL = &(pTAS2559->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
969         dev_dbg(pTAS2559->dev, "load PLL: %s block for Configuration %s\n",
970                 pPLL->mpName, pNewConfiguration->mpName);
971         nResult = tas2559_load_block(pTAS2559, &(pPLL->mBlock));
972
973         if (nResult < 0)
974                 goto end;
975
976         pTAS2559->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
977
978         dev_dbg(pTAS2559->dev, "load configuration %s conefficient pre block\n",
979                 pNewConfiguration->mpName);
980
981         if (pNewConfiguration->mnDevices & DevA) {
982                 nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData), TAS2559_BLOCK_CFG_PRE_DEV_A);
983
984                 if (nResult < 0)
985                         goto end;
986         }
987
988         if (pNewConfiguration->mnDevices & DevB) {
989                 nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData), TAS2559_BLOCK_CFG_PRE_DEV_B);
990
991                 if (nResult < 0)
992                         goto end;
993         }
994
995 prog_coefficient:
996         dev_dbg(pTAS2559->dev, "load new configuration: %s, coeff block data\n",
997                 pNewConfiguration->mpName);
998
999         if (pNewConfiguration->mnDevices & DevA) {
1000                 nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData),
1001                                             TAS2559_BLOCK_CFG_COEFF_DEV_A);
1002                 if (nResult < 0)
1003                         goto end;
1004         }
1005
1006         if (pNewConfiguration->mnDevices & DevB) {
1007                 nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData),
1008                                             TAS2559_BLOCK_CFG_COEFF_DEV_B);
1009                 if (nResult < 0)
1010                         goto end;
1011         }
1012
1013         if (pTAS2559->mnChannelState == TAS2559_AD_BD) {
1014                 nResult = pTAS2559->bulk_read(pTAS2559,
1015                                 DevA, TAS2559_SA_CHL_CTRL_REG, pTAS2559->mnDefaultChlData, 16);
1016                 if (nResult < 0)
1017                         goto end;
1018         } else {
1019                 nResult = tas2559_SA_DevChnSetup(pTAS2559, pTAS2559->mnChannelState);
1020                 if (nResult < 0)
1021                         goto end;
1022         }
1023
1024         if (pTAS2559->mpCalFirmware->mnCalibrations) {
1025                 nResult = tas2559_set_calibration(pTAS2559, pTAS2559->mnCurrentCalibration);
1026                 if (nResult < 0)
1027                         goto end;
1028         }
1029
1030         if (bRestorePower) {
1031                 dev_dbg(pTAS2559->dev, "%s, set vboost, before power on %d\n",
1032                         __func__, pTAS2559->mnVBoostState);
1033                 nResult = tas2559_set_VBoost(pTAS2559, pTAS2559->mnVBoostState, false);
1034                 if (nResult < 0)
1035                         goto end;
1036
1037                 pTAS2559->clearIRQ(pTAS2559);
1038                 nResult = tas2559_DevStartup(pTAS2559, pNewConfiguration->mnDevices);
1039                 if (nResult < 0)
1040                         goto end;
1041
1042                 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1043                         nResult = tas2559_checkPLL(pTAS2559);
1044
1045                         if (nResult < 0) {
1046                                 nResult = tas2559_DevShutdown(pTAS2559, pNewConfiguration->mnDevices);
1047                                 pTAS2559->mbPowerUp = false;
1048                                 goto end;
1049                         }
1050                 }
1051
1052                 if (pNewConfiguration->mnDevices & DevB) {
1053                         nResult = tas2559_load_data(pTAS2559, &(pNewConfiguration->mData),
1054                                                     TAS2559_BLOCK_PST_POWERUP_DEV_B);
1055
1056                         if (nResult < 0)
1057                                 goto end;
1058                 }
1059
1060                 dev_dbg(pTAS2559->dev,
1061                         "device powered up, load unmute\n");
1062                 nResult = tas2559_DevMute(pTAS2559, pNewConfiguration->mnDevices, false);
1063
1064                 if (nResult < 0)
1065                         goto end;
1066
1067                 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1068                         pTAS2559->enableIRQ(pTAS2559, pNewConfiguration->mnDevices, true);
1069
1070                         if (!hrtimer_active(&pTAS2559->mtimer)) {
1071                                 pTAS2559->mnDieTvReadCounter = 0;
1072                                 hrtimer_start(&pTAS2559->mtimer,
1073                                               ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1074                         }
1075                 }
1076         }
1077
1078 end:
1079
1080         if (nResult < 0)
1081                 dev_err(pTAS2559->dev, "%s, load new conf %s error\n", __func__, pNewConfiguration->mpName);
1082
1083         return nResult;
1084 }
1085
1086 int tas2559_enable(struct tas2559_priv *pTAS2559, bool bEnable)
1087 {
1088         int nResult = 0;
1089         struct TProgram *pProgram;
1090         struct TConfiguration *pConfiguration;
1091         unsigned int nValue;
1092
1093         dev_dbg(pTAS2559->dev, "%s: %s\n", __func__, bEnable ? "On" : "Off");
1094
1095         if ((pTAS2559->mpFirmware->mnPrograms == 0)
1096             || (pTAS2559->mpFirmware->mnConfigurations == 0)) {
1097                 dev_err(pTAS2559->dev, "%s, firmware not loaded\n", __func__);
1098                 goto end;
1099         }
1100
1101         /* check safe guard*/
1102         nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_SAFE_GUARD_REG, &nValue);
1103         if (nResult < 0)
1104                 goto end;
1105         if ((nValue & 0xff) != TAS2559_SAFE_GUARD_PATTERN) {
1106                 dev_err(pTAS2559->dev, "ERROR DevA safe guard (0x%x) failure!\n", nValue);
1107                 nResult = -EPIPE;
1108                 pTAS2559->mnErrCode = ERROR_SAFE_GUARD;
1109                 pTAS2559->mbPowerUp = true;
1110                 goto end;
1111         }
1112
1113         pProgram = &(pTAS2559->mpFirmware->mpPrograms[pTAS2559->mnCurrentProgram]);
1114         if (bEnable) {
1115                 if (!pTAS2559->mbPowerUp) {
1116                         if (!pTAS2559->mbCalibrationLoaded) {
1117                                 tas2559_set_calibration(pTAS2559, 0xFF);
1118                                 pTAS2559->mbCalibrationLoaded = true;
1119                         }
1120
1121                         if (pTAS2559->mbLoadConfigurationPrePowerUp) {
1122                                 pTAS2559->mbLoadConfigurationPrePowerUp = false;
1123                                 nResult = tas2559_load_coefficient(pTAS2559,
1124                                                                 pTAS2559->mnCurrentConfiguration, pTAS2559->mnNewConfiguration, false);
1125
1126                                 if (nResult < 0)
1127                                         goto end;
1128                         }
1129
1130                         if (pTAS2559->mbLoadVBoostPrePowerUp) {
1131                                 dev_dbg(pTAS2559->dev, "%s, cfg boost before power on new %d, current=%d\n",
1132                                         __func__, pTAS2559->mnVBoostNewState, pTAS2559->mnVBoostState);
1133                                 nResult = tas2559_set_VBoost(pTAS2559, pTAS2559->mnVBoostNewState, false);
1134                                 if (nResult < 0)
1135                                         goto end;
1136                                 pTAS2559->mbLoadVBoostPrePowerUp = false;
1137                         }
1138
1139                         pTAS2559->clearIRQ(pTAS2559);
1140                         pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
1141                         nResult = tas2559_DevStartup(pTAS2559, pConfiguration->mnDevices);
1142                         if (nResult < 0)
1143                                 goto end;
1144
1145                         if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1146                                 nResult = tas2559_checkPLL(pTAS2559);
1147                                 if (nResult < 0) {
1148                                         nResult = tas2559_DevShutdown(pTAS2559, pConfiguration->mnDevices);
1149                                         goto end;
1150                                 }
1151                         }
1152
1153                         if (pConfiguration->mnDevices & DevB) {
1154                                 nResult = tas2559_load_data(pTAS2559, &(pConfiguration->mData),
1155                                                                 TAS2559_BLOCK_PST_POWERUP_DEV_B);
1156                                 if (nResult < 0)
1157                                         goto end;
1158                         }
1159
1160                         nResult = tas2559_DevMute(pTAS2559, pConfiguration->mnDevices, false);
1161                         if (nResult < 0)
1162                                 goto end;
1163
1164                         if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1165                                 /* turn on IRQ */
1166                                 pTAS2559->enableIRQ(pTAS2559, pConfiguration->mnDevices, true);
1167                                 if (!hrtimer_active(&pTAS2559->mtimer)) {
1168                                         pTAS2559->mnDieTvReadCounter = 0;
1169                                         hrtimer_start(&pTAS2559->mtimer,
1170                                                 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1171                                 }
1172                         }
1173
1174                         pTAS2559->mbPowerUp = true;
1175                         pTAS2559->mnRestart = 0;
1176                 }
1177         } else {
1178                 if (pTAS2559->mbPowerUp) {
1179                         if (hrtimer_active(&pTAS2559->mtimer))
1180                                 hrtimer_cancel(&pTAS2559->mtimer);
1181
1182                         pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
1183
1184                         if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
1185                                 /* turn off IRQ */
1186                                 pTAS2559->enableIRQ(pTAS2559, DevBoth, false);
1187                         }
1188
1189                         nResult = tas2559_DevShutdown(pTAS2559, pConfiguration->mnDevices);
1190                         if (nResult < 0)
1191                                 goto end;
1192
1193                         pTAS2559->mbPowerUp = false;
1194                         pTAS2559->mnRestart = 0;
1195                 }
1196         }
1197
1198         nResult = 0;
1199
1200 end:
1201
1202         if (nResult < 0) {
1203                 if (pTAS2559->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK | ERROR_SAFE_GUARD))
1204                         failsafe(pTAS2559);
1205         }
1206
1207         dev_dbg(pTAS2559->dev, "%s: exit\n", __func__);
1208         return nResult;
1209 }
1210
1211 int tas2559_set_sampling_rate(struct tas2559_priv *pTAS2559, unsigned int nSamplingRate)
1212 {
1213         int nResult = 0;
1214         struct TConfiguration *pConfiguration;
1215         unsigned int nConfiguration;
1216
1217         dev_dbg(pTAS2559->dev, "%s: nSamplingRate = %d [Hz]\n", __func__,
1218                 nSamplingRate);
1219
1220         if ((!pTAS2559->mpFirmware->mpPrograms) ||
1221             (!pTAS2559->mpFirmware->mpConfigurations)) {
1222                 dev_err(pTAS2559->dev, "Firmware not loaded\n");
1223                 nResult = -EINVAL;
1224                 goto end;
1225         }
1226
1227         pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
1228
1229         if (pConfiguration->mnSamplingRate == nSamplingRate) {
1230                 dev_info(pTAS2559->dev, "Sampling rate for current configuration matches: %d\n",
1231                          nSamplingRate);
1232                 nResult = 0;
1233                 goto end;
1234         }
1235
1236         for (nConfiguration = 0;
1237              nConfiguration < pTAS2559->mpFirmware->mnConfigurations;
1238              nConfiguration++) {
1239                 pConfiguration =
1240                         &(pTAS2559->mpFirmware->mpConfigurations[nConfiguration]);
1241
1242                 if ((pConfiguration->mnSamplingRate == nSamplingRate)
1243                     && (pConfiguration->mnProgram == pTAS2559->mnCurrentProgram)) {
1244                         dev_info(pTAS2559->dev,
1245                                  "Found configuration: %s, with compatible sampling rate %d\n",
1246                                  pConfiguration->mpName, nSamplingRate);
1247                         nResult = tas2559_load_configuration(pTAS2559, nConfiguration, false);
1248                         goto end;
1249                 }
1250         }
1251
1252         dev_err(pTAS2559->dev, "Cannot find a configuration that supports sampling rate: %d\n",
1253                 nSamplingRate);
1254
1255 end:
1256
1257         return nResult;
1258 }
1259
1260 static void fw_print_header(struct tas2559_priv *pTAS2559, struct TFirmware *pFirmware)
1261 {
1262         dev_info(pTAS2559->dev, "FW Size       = %d", pFirmware->mnFWSize);
1263         dev_info(pTAS2559->dev, "Checksum      = 0x%04X", pFirmware->mnChecksum);
1264         dev_info(pTAS2559->dev, "PPC Version   = 0x%04X", pFirmware->mnPPCVersion);
1265         dev_info(pTAS2559->dev, "FW  Version    = 0x%04X", pFirmware->mnFWVersion);
1266         dev_info(pTAS2559->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
1267         dev_info(pTAS2559->dev, "Timestamp     = %d", pFirmware->mnTimeStamp);
1268         dev_info(pTAS2559->dev, "DDC Name      = %s", pFirmware->mpDDCName);
1269         dev_info(pTAS2559->dev, "Description   = %s", pFirmware->mpDescription);
1270 }
1271
1272 inline unsigned int fw_convert_number(unsigned char *pData)
1273 {
1274         return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
1275 }
1276
1277 static int fw_parse_header(struct tas2559_priv *pTAS2559,
1278                            struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
1279 {
1280         unsigned char *pDataStart = pData;
1281         unsigned int n;
1282         unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
1283
1284         if (nSize < 104) {
1285                 dev_err(pTAS2559->dev, "Firmware: Header too short");
1286                 return -EINVAL;
1287         }
1288
1289         if (memcmp(pData, pMagicNumber, 4)) {
1290                 dev_err(pTAS2559->dev, "Firmware: Magic number doesn't match");
1291                 return -EINVAL;
1292         }
1293
1294         pData += 4;
1295
1296         pFirmware->mnFWSize = fw_convert_number(pData);
1297         pData += 4;
1298
1299         pFirmware->mnChecksum = fw_convert_number(pData);
1300         pData += 4;
1301
1302         pFirmware->mnPPCVersion = fw_convert_number(pData);
1303         pData += 4;
1304
1305         pFirmware->mnFWVersion = fw_convert_number(pData);
1306         pData += 4;
1307
1308         pFirmware->mnDriverVersion = fw_convert_number(pData);
1309         pData += 4;
1310
1311         pFirmware->mnTimeStamp = fw_convert_number(pData);
1312         pData += 4;
1313
1314         memcpy(pFirmware->mpDDCName, pData, 64);
1315         pData += 64;
1316
1317         n = strlen(pData);
1318         pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1319         pData += n + 1;
1320
1321         if ((pData - pDataStart) >= nSize) {
1322                 dev_err(pTAS2559->dev, "Firmware: Header too short after DDC description");
1323                 return -EINVAL;
1324         }
1325
1326         pFirmware->mnDeviceFamily = fw_convert_number(pData);
1327         pData += 4;
1328
1329         if (pFirmware->mnDeviceFamily != 0) {
1330                 dev_err(pTAS2559->dev,
1331                         "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
1332                 return -EINVAL;
1333         }
1334
1335         pFirmware->mnDevice = fw_convert_number(pData);
1336         pData += 4;
1337
1338         if (pFirmware->mnDevice != 4) {
1339                 dev_err(pTAS2559->dev,
1340                         "device %d, not TAS2559", pFirmware->mnDevice);
1341                 return -EINVAL;
1342         }
1343
1344         fw_print_header(pTAS2559, pFirmware);
1345
1346         return pData - pDataStart;
1347 }
1348
1349 static int fw_parse_block_data(struct tas2559_priv *pTAS2559, struct TFirmware *pFirmware,
1350                                struct TBlock *pBlock, unsigned char *pData)
1351 {
1352         unsigned char *pDataStart = pData;
1353         unsigned int n;
1354
1355         pBlock->mnType = fw_convert_number(pData);
1356         pData += 4;
1357
1358         if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) {
1359                 pBlock->mbPChkSumPresent = pData[0];
1360                 pData++;
1361
1362                 pBlock->mnPChkSum = pData[0];
1363                 pData++;
1364
1365                 pBlock->mbYChkSumPresent = pData[0];
1366                 pData++;
1367
1368                 pBlock->mnYChkSum = pData[0];
1369                 pData++;
1370         } else {
1371                 pBlock->mbPChkSumPresent = 0;
1372                 pBlock->mbYChkSumPresent = 0;
1373         }
1374
1375         pBlock->mnCommands = fw_convert_number(pData);
1376         pData += 4;
1377
1378         n = pBlock->mnCommands * 4;
1379         pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
1380         pData += n;
1381
1382         return pData - pDataStart;
1383 }
1384
1385 static int fw_parse_data(struct tas2559_priv *pTAS2559, struct TFirmware *pFirmware,
1386                          struct TData *pImageData, unsigned char *pData)
1387 {
1388         unsigned char *pDataStart = pData;
1389         unsigned int nBlock;
1390         unsigned int n;
1391
1392         memcpy(pImageData->mpName, pData, 64);
1393         pData += 64;
1394
1395         n = strlen(pData);
1396         pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1397         pData += n + 1;
1398
1399         pImageData->mnBlocks = (pData[0] << 8) + pData[1];
1400         pData += 2;
1401
1402         pImageData->mpBlocks =
1403                 kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
1404
1405         for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
1406                 n = fw_parse_block_data(pTAS2559, pFirmware,
1407                                         &(pImageData->mpBlocks[nBlock]), pData);
1408                 pData += n;
1409         }
1410
1411         return pData - pDataStart;
1412 }
1413
1414 static int fw_parse_pll_data(struct tas2559_priv *pTAS2559,
1415                              struct TFirmware *pFirmware, unsigned char *pData)
1416 {
1417         unsigned char *pDataStart = pData;
1418         unsigned int n;
1419         unsigned int nPLL;
1420         struct TPLL *pPLL;
1421
1422         pFirmware->mnPLLs = (pData[0] << 8) + pData[1];
1423         pData += 2;
1424
1425         if (pFirmware->mnPLLs == 0)
1426                 goto end;
1427
1428         pFirmware->mpPLLs = kmalloc_array(pFirmware->mnPLLs, sizeof(struct TPLL), GFP_KERNEL);
1429
1430         for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) {
1431                 pPLL = &(pFirmware->mpPLLs[nPLL]);
1432
1433                 memcpy(pPLL->mpName, pData, 64);
1434                 pData += 64;
1435
1436                 n = strlen(pData);
1437                 pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1438                 pData += n + 1;
1439
1440                 n = fw_parse_block_data(pTAS2559, pFirmware, &(pPLL->mBlock), pData);
1441                 pData += n;
1442         }
1443
1444 end:
1445         return pData - pDataStart;
1446 }
1447
1448 static int fw_parse_program_data(struct tas2559_priv *pTAS2559,
1449                                  struct TFirmware *pFirmware, unsigned char *pData)
1450 {
1451         unsigned char *pDataStart = pData;
1452         unsigned int n;
1453         unsigned int nProgram;
1454         struct TProgram *pProgram;
1455
1456         pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
1457         pData += 2;
1458
1459         if (pFirmware->mnPrograms == 0)
1460                 goto end;
1461
1462         pFirmware->mpPrograms =
1463                 kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
1464
1465         for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
1466                 pProgram = &(pFirmware->mpPrograms[nProgram]);
1467                 memcpy(pProgram->mpName, pData, 64);
1468                 pData += 64;
1469
1470                 n = strlen(pData);
1471                 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1472                 pData += n + 1;
1473
1474                 pProgram->mnAppMode = pData[0];
1475                 pData++;
1476
1477                 pProgram->mnBoost = (pData[0] << 8) + pData[1];
1478                 pData += 2;
1479
1480                 n = fw_parse_data(pTAS2559, pFirmware, &(pProgram->mData), pData);
1481                 pData += n;
1482         }
1483
1484 end:
1485
1486         return pData - pDataStart;
1487 }
1488
1489 static int fw_parse_configuration_data(struct tas2559_priv *pTAS2559,
1490                                        struct TFirmware *pFirmware, unsigned char *pData)
1491 {
1492         unsigned char *pDataStart = pData;
1493         unsigned int n;
1494         unsigned int nConfiguration;
1495         struct TConfiguration *pConfiguration;
1496
1497         pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
1498         pData += 2;
1499
1500         if (pFirmware->mnConfigurations == 0)
1501                 goto end;
1502
1503         pFirmware->mpConfigurations =
1504                 kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
1505                         GFP_KERNEL);
1506
1507         for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
1508              nConfiguration++) {
1509                 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
1510                 memcpy(pConfiguration->mpName, pData, 64);
1511                 pData += 64;
1512
1513                 n = strlen(pData);
1514                 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1515                 pData += n + 1;
1516
1517                 if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV)
1518                     || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC)
1519                         && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) {
1520                         pConfiguration->mnDevices = (pData[0] << 8) + pData[1];
1521                         pData += 2;
1522                 } else
1523                         pConfiguration->mnDevices = DevBoth;
1524
1525                 pConfiguration->mnProgram = pData[0];
1526                 pData++;
1527
1528                 pConfiguration->mnPLL = pData[0];
1529                 pData++;
1530
1531                 pConfiguration->mnSamplingRate = fw_convert_number(pData);
1532                 pData += 4;
1533
1534                 n = fw_parse_data(pTAS2559, pFirmware, &(pConfiguration->mData), pData);
1535                 pData += n;
1536         }
1537
1538 end:
1539
1540         return pData - pDataStart;
1541 }
1542
1543 int fw_parse_calibration_data(struct tas2559_priv *pTAS2559,
1544                               struct TFirmware *pFirmware, unsigned char *pData)
1545 {
1546         unsigned char *pDataStart = pData;
1547         unsigned int n;
1548         unsigned int nCalibration;
1549         struct TCalibration *pCalibration;
1550
1551         pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
1552         pData += 2;
1553
1554         if (pFirmware->mnCalibrations == 0)
1555                 goto end;
1556
1557         pFirmware->mpCalibrations =
1558                 kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
1559
1560         for (nCalibration = 0;
1561              nCalibration < pFirmware->mnCalibrations;
1562              nCalibration++) {
1563                 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
1564                 memcpy(pCalibration->mpName, pData, 64);
1565                 pData += 64;
1566
1567                 n = strlen(pData);
1568                 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
1569                 pData += n + 1;
1570
1571                 pCalibration->mnProgram = pData[0];
1572                 pData++;
1573
1574                 pCalibration->mnConfiguration = pData[0];
1575                 pData++;
1576
1577                 n = fw_parse_data(pTAS2559, pFirmware, &(pCalibration->mData), pData);
1578                 pData += n;
1579         }
1580
1581 end:
1582
1583         return pData - pDataStart;
1584 }
1585
1586 static int fw_parse(struct tas2559_priv *pTAS2559,
1587                     struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
1588 {
1589         int nPosition = 0;
1590
1591         nPosition = fw_parse_header(pTAS2559, pFirmware, pData, nSize);
1592
1593         if (nPosition < 0) {
1594                 dev_err(pTAS2559->dev, "Firmware: Wrong Header");
1595                 return -EINVAL;
1596         }
1597
1598         if (nPosition >= nSize) {
1599                 dev_err(pTAS2559->dev, "Firmware: Too short");
1600                 return -EINVAL;
1601         }
1602
1603         pData += nPosition;
1604         nSize -= nPosition;
1605         nPosition = 0;
1606
1607         nPosition = fw_parse_pll_data(pTAS2559, pFirmware, pData);
1608
1609         pData += nPosition;
1610         nSize -= nPosition;
1611         nPosition = 0;
1612
1613         nPosition = fw_parse_program_data(pTAS2559, pFirmware, pData);
1614
1615         pData += nPosition;
1616         nSize -= nPosition;
1617         nPosition = 0;
1618
1619         nPosition = fw_parse_configuration_data(pTAS2559, pFirmware, pData);
1620
1621         pData += nPosition;
1622         nSize -= nPosition;
1623         nPosition = 0;
1624
1625         if (nSize > 64)
1626                 nPosition = fw_parse_calibration_data(pTAS2559, pFirmware, pData);
1627
1628         return 0;
1629 }
1630
1631
1632 static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
1633         0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
1634         0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
1635         0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
1636         0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
1637         0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
1638         0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
1639         0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
1640         0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
1641         0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
1642         0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
1643         0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
1644         0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
1645         0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
1646         0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
1647         0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
1648         0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
1649 };
1650
1651 static int DevAPageYRAM(struct tas2559_priv *pTAS2559,
1652                         struct TYCRC *pCRCData,
1653                         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1654 {
1655         int nResult = 0;
1656
1657         if (nBook == TAS2559_YRAM_BOOK1) {
1658                 if (nPage == TAS2559_YRAM1_PAGE) {
1659                         if (nReg >= TAS2559_YRAM1_START_REG) {
1660                                 pCRCData->mnOffset = nReg;
1661                                 pCRCData->mnLen = len;
1662                                 nResult = 1;
1663                         } else if ((nReg + len) > TAS2559_YRAM1_START_REG) {
1664                                 pCRCData->mnOffset = TAS2559_YRAM1_START_REG;
1665                                 pCRCData->mnLen = len - (TAS2559_YRAM1_START_REG - nReg);
1666                                 nResult = 1;
1667                         } else
1668                                 nResult = 0;
1669                 } else if (nPage == TAS2559_YRAM3_PAGE) {
1670                         if (nReg > TAS2559_YRAM3_END_REG) {
1671                                 nResult = 0;
1672                         } else if (nReg >= TAS2559_YRAM3_START_REG) {
1673                                 if ((nReg + len) > TAS2559_YRAM3_END_REG) {
1674                                         pCRCData->mnOffset = nReg;
1675                                         pCRCData->mnLen = TAS2559_YRAM3_END_REG - nReg + 1;
1676                                         nResult = 1;
1677                                 } else {
1678                                         pCRCData->mnOffset = nReg;
1679                                         pCRCData->mnLen = len;
1680                                         nResult = 1;
1681                                 }
1682                         } else {
1683                                 if ((nReg + (len - 1)) < TAS2559_YRAM3_START_REG) {
1684                                         nResult = 0;
1685                                 } else if ((nReg + (len - 1)) <= TAS2559_YRAM3_END_REG) {
1686                                         pCRCData->mnOffset = TAS2559_YRAM3_START_REG;
1687                                         pCRCData->mnLen = len - (TAS2559_YRAM3_START_REG - nReg);
1688                                         nResult = 1;
1689                                 } else {
1690                                         pCRCData->mnOffset = TAS2559_YRAM3_START_REG;
1691                                         pCRCData->mnLen = TAS2559_YRAM3_END_REG - TAS2559_YRAM3_START_REG + 1;
1692                                         nResult = 1;
1693                                 }
1694                         }
1695                 }
1696         } else if (nBook == TAS2559_YRAM_BOOK2) {
1697                 if (nPage == TAS2559_YRAM5_PAGE) {
1698                         if (nReg > TAS2559_YRAM5_END_REG) {
1699                                 nResult = 0;
1700                         } else if (nReg >= TAS2559_YRAM5_START_REG) {
1701                                 if ((nReg + len) > TAS2559_YRAM5_END_REG) {
1702                                         pCRCData->mnOffset = nReg;
1703                                         pCRCData->mnLen = TAS2559_YRAM5_END_REG - nReg + 1;
1704                                         nResult = 1;
1705                                 } else {
1706                                         pCRCData->mnOffset = nReg;
1707                                         pCRCData->mnLen = len;
1708                                         nResult = 1;
1709                                 }
1710                         } else {
1711                                 if ((nReg + (len - 1)) < TAS2559_YRAM5_START_REG) {
1712                                         nResult = 0;
1713                                 } else if ((nReg + (len - 1)) <= TAS2559_YRAM5_END_REG) {
1714                                         pCRCData->mnOffset = TAS2559_YRAM5_START_REG;
1715                                         pCRCData->mnLen = len - (TAS2559_YRAM5_START_REG - nReg);
1716                                         nResult = 1;
1717                                 } else {
1718                                         pCRCData->mnOffset = TAS2559_YRAM5_START_REG;
1719                                         pCRCData->mnLen = TAS2559_YRAM5_END_REG - TAS2559_YRAM5_START_REG + 1;
1720                                         nResult = 1;
1721                                 }
1722                         }
1723                 }
1724         } else if (nBook == TAS2559_YRAM_BOOK3) {
1725                 if (nPage == TAS2559_YRAM6_PAGE) {
1726                         if (nReg > TAS2559_YRAM6_END_REG) {
1727                                 nResult = 0;
1728                         } else if (nReg >= TAS2559_YRAM6_START_REG) {
1729                                 if ((nReg + len) > TAS2559_YRAM6_END_REG) {
1730                                         pCRCData->mnOffset = nReg;
1731                                         pCRCData->mnLen = TAS2559_YRAM6_END_REG - nReg + 1;
1732                                         nResult = 1;
1733                                 } else {
1734                                         pCRCData->mnOffset = nReg;
1735                                         pCRCData->mnLen = len;
1736                                         nResult = 1;
1737                                 }
1738                         } else {
1739                                 if ((nReg + (len - 1)) < TAS2559_YRAM6_START_REG) {
1740                                         nResult = 0;
1741                                 } else if ((nReg + (len - 1)) <= TAS2559_YRAM6_END_REG) {
1742                                         pCRCData->mnOffset = TAS2559_YRAM6_START_REG;
1743                                         pCRCData->mnLen = len - (TAS2559_YRAM6_START_REG - nReg);
1744                                         nResult = 1;
1745                                 } else {
1746                                         pCRCData->mnOffset = TAS2559_YRAM6_START_REG;
1747                                         pCRCData->mnLen = TAS2559_YRAM6_END_REG - TAS2559_YRAM6_START_REG + 1;
1748                                         nResult = 1;
1749                                 }
1750                         }
1751                 }
1752         } else {
1753                 nResult = 0;
1754         }
1755
1756         return nResult;
1757 }
1758
1759 static int isInPageYRAM(struct tas2559_priv *pTAS2559,
1760                         enum channel dev, struct TYCRC *pCRCData,
1761                         unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1762 {
1763         int nResult = 0;
1764
1765         if (dev == DevA)
1766                 nResult = DevAPageYRAM(pTAS2559, pCRCData, nBook, nPage, nReg, len);
1767
1768         return nResult;
1769 }
1770
1771 static int DevABlockYRAM(struct tas2559_priv *pTAS2559,
1772                          struct TYCRC *pCRCData,
1773                          unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1774 {
1775         int nResult = 0;
1776
1777         if (nBook == TAS2559_YRAM_BOOK1) {
1778                 if (nPage < TAS2559_YRAM2_START_PAGE)
1779                         nResult = 0;
1780                 else if (nPage <= TAS2559_YRAM2_END_PAGE) {
1781                         if (nReg > TAS2559_YRAM2_END_REG) {
1782                                 nResult = 0;
1783                         } else if (nReg >= TAS2559_YRAM2_START_REG) {
1784                                 pCRCData->mnOffset = nReg;
1785                                 pCRCData->mnLen = len;
1786                                 nResult = 1;
1787                         } else {
1788                                 if ((nReg + (len - 1)) < TAS2559_YRAM2_START_REG) {
1789                                         nResult = 0;
1790                                 } else {
1791                                         pCRCData->mnOffset = TAS2559_YRAM2_START_REG;
1792                                         pCRCData->mnLen = nReg + len - TAS2559_YRAM2_START_REG;
1793                                         nResult = 1;
1794                                 }
1795                         }
1796                 } else {
1797                         nResult = 0;
1798                 }
1799         } else if (nBook == TAS2559_YRAM_BOOK2) {
1800                 if (nPage < TAS2559_YRAM4_START_PAGE) {
1801                         nResult = 0;
1802                 } else if (nPage <= TAS2559_YRAM4_END_PAGE) {
1803                         if ((nPage == TAS2559_PAGE_ID(TAS2559_SA_COEFF_SWAP_REG))
1804                                 && (nReg == TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG))
1805                                 && (len == 4)) {
1806                                 dev_dbg(pTAS2559->dev, "bypass swap\n");
1807                                 nResult = 0;
1808                         } else if (nReg > TAS2559_YRAM2_END_REG) {
1809                                 nResult = 0;
1810                         } else if (nReg >= TAS2559_YRAM2_START_REG) {
1811                                 pCRCData->mnOffset = nReg;
1812                                 pCRCData->mnLen = len;
1813                                 nResult = 1;
1814                         } else {
1815                                 if ((nReg + (len - 1)) < TAS2559_YRAM2_START_REG) {
1816                                         nResult = 0;
1817                                 } else {
1818                                         pCRCData->mnOffset = TAS2559_YRAM2_START_REG;
1819                                         pCRCData->mnLen = nReg + len - TAS2559_YRAM2_START_REG;
1820                                         nResult = 1;
1821                                 }
1822                         }
1823                 } else {
1824                         nResult = 0;
1825                 }
1826         } else {
1827                         nResult = 0;
1828         }
1829
1830         return nResult;
1831 }
1832
1833 static int DevBBlockYRAM(struct tas2559_priv *pTAS2559,
1834                          struct TYCRC *pCRCData,
1835                          unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1836 {
1837         int nResult = 0;
1838
1839         if (nBook == TAS2560_YRAM_BOOK) {
1840                 if (nPage < TAS2560_YRAM_START_PAGE) {
1841                         nResult = 0;
1842                 } else if (nPage <= TAS2560_YRAM_END_PAGE) {
1843                         if (nReg > TAS2560_YRAM_END_REG) {
1844                                 nResult = 0;
1845                         } else if (nReg >= TAS2560_YRAM_START_REG) {
1846                                 pCRCData->mnOffset = nReg;
1847                                 pCRCData->mnLen = len;
1848                                 nResult = 1;
1849                         } else {
1850                                 if ((nReg + (len - 1)) < TAS2560_YRAM_START_REG) {
1851                                         nResult = 0;
1852                                 } else {
1853                                         pCRCData->mnOffset = TAS2560_YRAM_START_REG;
1854                                         pCRCData->mnLen = nReg + len - TAS2560_YRAM_START_REG;
1855                                         nResult = 1;
1856                                 }
1857                         }
1858                 } else {
1859                                 nResult = 0;
1860                 }
1861         }
1862
1863         return nResult;
1864 }
1865
1866 static int isInBlockYRAM(struct tas2559_priv *pTAS2559,
1867                          enum channel dev, struct TYCRC *pCRCData,
1868                          unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1869 {
1870         int nResult = 0;
1871
1872         if (dev == DevA)
1873                 nResult = DevABlockYRAM(pTAS2559, pCRCData, nBook, nPage, nReg, len);
1874         else
1875                 if (dev == DevB)
1876                         nResult = DevBBlockYRAM(pTAS2559, pCRCData, nBook, nPage, nReg, len);
1877
1878         return nResult;
1879 }
1880
1881
1882 static int isYRAM(struct tas2559_priv *pTAS2559,
1883                   enum channel dev, struct TYCRC *pCRCData,
1884                   unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1885 {
1886         int nResult;
1887
1888         nResult = isInPageYRAM(pTAS2559, dev, pCRCData, nBook, nPage, nReg, len);
1889
1890         if (nResult == 0)
1891                 nResult = isInBlockYRAM(pTAS2559, dev, pCRCData, nBook, nPage, nReg, len);
1892
1893         return nResult;
1894 }
1895
1896 /*
1897  * crc8 - calculate a crc8 over the given input data.
1898  *
1899  * table: crc table used for calculation.
1900  * pdata: pointer to data buffer.
1901  * nbytes: number of bytes in data buffer.
1902  * crc: previous returned crc8 value.
1903  */
1904 static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
1905 {
1906         /* loop over the buffer data */
1907         while (nbytes-- > 0)
1908                 crc = table[(crc ^ *pdata++) & 0xff];
1909
1910         return crc;
1911 }
1912
1913 static int doSingleRegCheckSum(struct tas2559_priv *pTAS2559, enum channel chl,
1914                                unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
1915 {
1916         int nResult = 0;
1917         struct TYCRC sCRCData;
1918         unsigned int nData1 = 0, nData2 = 0;
1919         unsigned char nRegVal;
1920
1921         if (chl == DevA) {
1922                 if ((nBook == TAS2559_BOOK_ID(TAS2559_SA_COEFF_SWAP_REG))
1923                     && (nPage == TAS2559_PAGE_ID(TAS2559_SA_COEFF_SWAP_REG))
1924                     && (nReg >= TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG))
1925                     && (nReg <= (TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG) + 4))) {
1926                         /* DSP swap command, pass */
1927                         nResult = 0;
1928                         goto end;
1929                 }
1930         }
1931
1932         nResult = isYRAM(pTAS2559, chl, &sCRCData, nBook, nPage, nReg, 1);
1933
1934         if (nResult == 1) {
1935                 if (chl == DevA) {
1936                         nResult = pTAS2559->read(pTAS2559, DevA, TAS2559_REG(nBook, nPage, nReg), &nData1);
1937
1938                         if (nResult < 0)
1939                                 goto end;
1940                 } else if (chl == DevB) {
1941                         nResult = pTAS2559->read(pTAS2559, DevB, TAS2559_REG(nBook, nPage, nReg), &nData2);
1942
1943                         if (nResult < 0)
1944                                 goto end;
1945                 }
1946
1947                 if (chl == DevA) {
1948                         if (nData1 != nValue) {
1949                                 dev_err(pTAS2559->dev,
1950                                         "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1951                                         __LINE__, nBook, nPage, nReg, nValue, nData1);
1952                                 nResult = -EAGAIN;
1953                                 pTAS2559->mnErrCode |= ERROR_YRAM_CRCCHK;
1954                                 goto end;
1955                         }
1956
1957                         nRegVal = nData1;
1958                 } else if (chl == DevB) {
1959                         if (nData2 != nValue) {
1960                                 dev_err(pTAS2559->dev,
1961                                         "error (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1962                                         __LINE__, nBook, nPage, nReg, nValue, nData2);
1963                                 nResult = -EAGAIN;
1964                                 pTAS2559->mnErrCode |= ERROR_YRAM_CRCCHK;
1965                                 goto end;
1966                         }
1967
1968                         nRegVal = nData2;
1969                 } else {
1970                         nResult = -EINVAL;
1971                         goto end;
1972                 }
1973
1974                 nResult = ti_crc8(crc8_lookup_table, &nRegVal, 1, 0);
1975         }
1976
1977 end:
1978
1979         return nResult;
1980 }
1981
1982 static int doMultiRegCheckSum(struct tas2559_priv *pTAS2559, enum channel chl,
1983                               unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
1984 {
1985         int nResult = 0, i;
1986         unsigned char nCRCChkSum = 0;
1987         unsigned char nBuf1[128];
1988         unsigned char nBuf2[128];
1989         struct TYCRC TCRCData;
1990         unsigned char *pRegVal;
1991
1992         if ((nReg + len - 1) > 127) {
1993                 nResult = -EINVAL;
1994                 dev_err(pTAS2559->dev, "firmware error\n");
1995                 goto end;
1996         }
1997
1998         if ((nBook == TAS2559_BOOK_ID(TAS2559_SA_COEFF_SWAP_REG))
1999             && (nPage == TAS2559_PAGE_ID(TAS2559_SA_COEFF_SWAP_REG))
2000             && (nReg == TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG))
2001             && (len == 4)) {
2002                 /* DSP swap command, pass */
2003                 nResult = 0;
2004                 goto end;
2005         }
2006
2007         nResult = isYRAM(pTAS2559, chl, &TCRCData, nBook, nPage, nReg, len);
2008
2009         if (nResult == 1) {
2010                 if (len == 1) {
2011                         dev_err(pTAS2559->dev, "firmware error\n");
2012                         nResult = -EINVAL;
2013                         goto end;
2014                 } else {
2015                         if (chl == DevA) {
2016                                 nResult = pTAS2559->bulk_read(pTAS2559, DevA,
2017                                                               TAS2559_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
2018
2019                                 if (nResult < 0)
2020                                         goto end;
2021                         } else if (chl == DevB) {
2022                                 nResult = pTAS2559->bulk_read(pTAS2559, DevB,
2023                                                               TAS2559_REG(nBook, nPage, TCRCData.mnOffset), nBuf2, TCRCData.mnLen);
2024
2025                                 if (nResult < 0)
2026                                         goto end;
2027                         }
2028
2029                         if (chl == DevA) {
2030                                 pRegVal = nBuf1;
2031                         } else if (chl == DevB)
2032                                 pRegVal = nBuf2;
2033                         else {
2034                                 dev_err(pTAS2559->dev, "channel error %d\n", chl);
2035                                 nResult = -EINVAL;
2036                                 goto end;
2037                         }
2038
2039                         for (i = 0; i < TCRCData.mnLen; i++) {
2040                                 if ((nBook == TAS2559_BOOK_ID(TAS2559_SA_COEFF_SWAP_REG))
2041                                     && (nPage == TAS2559_PAGE_ID(TAS2559_SA_COEFF_SWAP_REG))
2042                                     && ((i + TCRCData.mnOffset)
2043                                         >= TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG))
2044                                     && ((i + TCRCData.mnOffset)
2045                                         <= (TAS2559_PAGE_REG(TAS2559_SA_COEFF_SWAP_REG) + 4))) {
2046                                         /* DSP swap command, bypass */
2047                                         continue;
2048                                 } else {
2049                                         nCRCChkSum += ti_crc8(crc8_lookup_table, &pRegVal[i], 1, 0);
2050                                 }
2051                         }
2052
2053                         nResult = nCRCChkSum;
2054                 }
2055         }
2056
2057 end:
2058
2059         return nResult;
2060 }
2061
2062 static int tas2559_load_block(struct tas2559_priv *pTAS2559, struct TBlock *pBlock)
2063 {
2064         int nResult = 0;
2065         unsigned int nCommand = 0;
2066         unsigned char nBook;
2067         unsigned char nPage;
2068         unsigned char nOffset;
2069         unsigned char nData;
2070         unsigned int nValue1;
2071         unsigned int nLength;
2072         unsigned int nSleep;
2073         bool bDoYCRCChk = false;
2074         enum channel chl;
2075         unsigned char nCRCChkSum = 0;
2076         int nRetry = 6;
2077         unsigned char *pData = pBlock->mpData;
2078
2079         dev_dbg(pTAS2559->dev, "%s: Type = %d, commands = %d\n", __func__,
2080                 pBlock->mnType, pBlock->mnCommands);
2081
2082         if (pBlock->mnType == TAS2559_BLOCK_PLL) {
2083                 chl = DevA;
2084         } else if ((pBlock->mnType == TAS2559_BLOCK_PGM_DEV_A)
2085                     || (pBlock->mnType == TAS2559_BLOCK_CFG_COEFF_DEV_A)
2086                     || (pBlock->mnType == TAS2559_BLOCK_CFG_PRE_DEV_A)) {
2087                 chl = DevA;
2088         } else if ((pBlock->mnType == TAS2559_BLOCK_PGM_DEV_B)
2089                     || (pBlock->mnType == TAS2559_BLOCK_PST_POWERUP_DEV_B)
2090                     || (pBlock->mnType == TAS2559_BLOCK_CFG_PRE_DEV_B)) {
2091                 chl = DevB;
2092         } else {
2093                 dev_err(pTAS2559->dev, "block type error %d\n", pBlock->mnType);
2094                 nResult = -EINVAL;
2095                 goto end;
2096         }
2097
2098         if (pBlock->mbYChkSumPresent && pTAS2559->mbYCRCEnable)
2099                 bDoYCRCChk = true;
2100
2101 start:
2102
2103         if (pBlock->mbPChkSumPresent) {
2104                 if (chl == DevA) {
2105                         nResult = pTAS2559->write(pTAS2559, DevA, TAS2559_CRC_RESET_REG, 1);
2106                         if (nResult < 0)
2107                                 goto end;
2108                 } else {
2109                         nResult = pTAS2559->write(pTAS2559, DevB, TAS2560_CRC_CHK_REG, 1);
2110                         if (nResult < 0)
2111                                 goto end;
2112                 }
2113         }
2114
2115         if (bDoYCRCChk)
2116                 nCRCChkSum = 0;
2117
2118         nCommand = 0;
2119
2120         while (nCommand < pBlock->mnCommands) {
2121                 pData = pBlock->mpData + nCommand * 4;
2122                 nBook = pData[0];
2123                 nPage = pData[1];
2124                 nOffset = pData[2];
2125                 nData = pData[3];
2126                 nCommand++;
2127
2128                 if (nOffset <= 0x7F) {
2129                         nResult = pTAS2559->write(pTAS2559,
2130                                                 chl, TAS2559_REG(nBook, nPage, nOffset), nData);
2131                         if (nResult < 0)
2132                                 goto end;
2133
2134                         if (bDoYCRCChk) {
2135                                 nResult = doSingleRegCheckSum(pTAS2559,
2136                                                         chl, nBook, nPage, nOffset, nData);
2137                                 if (nResult < 0)
2138                                         goto check;
2139                                 nCRCChkSum += (unsigned char)nResult;
2140                         }
2141                 } else if (nOffset == 0x81) {
2142                         nSleep = (nBook << 8) + nPage;
2143                         msleep(nSleep);
2144                 } else if (nOffset == 0x85) {
2145                         pData += 4;
2146                         nLength = (nBook << 8) + nPage;
2147                         nBook = pData[0];
2148                         nPage = pData[1];
2149                         nOffset = pData[2];
2150
2151                         if (nLength > 1) {
2152                                 nResult = pTAS2559->bulk_write(pTAS2559,
2153                                                         chl, TAS2559_REG(nBook, nPage, nOffset), pData + 3, nLength);
2154                                 if (nResult < 0)
2155                                         goto end;
2156
2157                                 if (bDoYCRCChk) {
2158                                         nResult = doMultiRegCheckSum(pTAS2559,
2159                                                                 chl, nBook, nPage, nOffset, nLength);
2160                                         if (nResult < 0)
2161                                                 goto check;
2162
2163                                         nCRCChkSum += (unsigned char)nResult;
2164                                 }
2165                         } else {
2166                                 nResult = pTAS2559->write(pTAS2559,
2167                                                         chl, TAS2559_REG(nBook, nPage, nOffset), pData[3]);
2168                                 if (nResult < 0)
2169                                         goto end;
2170
2171                                 if (bDoYCRCChk) {
2172                                         nResult = doSingleRegCheckSum(pTAS2559,
2173                                                                 chl, nBook, nPage, nOffset, pData[3]);
2174                                         if (nResult < 0)
2175                                                 goto check;
2176
2177                                         nCRCChkSum += (unsigned char)nResult;
2178                                 }
2179                         }
2180
2181                         nCommand++;
2182
2183                         if (nLength >= 2)
2184                                 nCommand += ((nLength - 2) / 4) + 1;
2185                 }
2186         }
2187
2188         if (pBlock->mbPChkSumPresent) {
2189                 if (chl == DevA)
2190                         nResult = pTAS2559->read(pTAS2559, DevA,
2191                                                 TAS2559_CRC_CHECKSUM_REG, &nValue1);
2192                 else
2193                         nResult = pTAS2559->read(pTAS2559, DevB,
2194                                                 TAS2560_CRC_CHK_REG, &nValue1);
2195
2196                 if (nResult < 0)
2197                         goto end;
2198
2199                 if (nValue1 != pBlock->mnPChkSum) {
2200                         dev_err(pTAS2559->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
2201                                 pBlock->mnPChkSum, (nValue1 & 0xff));
2202                         nResult = -EAGAIN;
2203                         pTAS2559->mnErrCode |= ERROR_PRAM_CRCCHK;
2204                         goto check;
2205                 }
2206
2207                 nResult = 0;
2208                 pTAS2559->mnErrCode &= ~ERROR_PRAM_CRCCHK;
2209                 dev_dbg(pTAS2559->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
2210         }
2211
2212         if (bDoYCRCChk) {
2213                 if (nCRCChkSum != pBlock->mnYChkSum) {
2214                         dev_err(pTAS2559->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
2215                                 pBlock->mnYChkSum, nCRCChkSum);
2216                         nResult = -EAGAIN;
2217                         pTAS2559->mnErrCode |= ERROR_YRAM_CRCCHK;
2218                         goto check;
2219                 }
2220
2221                 pTAS2559->mnErrCode &= ~ERROR_YRAM_CRCCHK;
2222                 nResult = 0;
2223                 dev_dbg(pTAS2559->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
2224         }
2225
2226 check:
2227
2228         if (nResult == -EAGAIN) {
2229                 nRetry--;
2230
2231                 if (nRetry > 0)
2232                         goto start;
2233         }
2234
2235 end:
2236
2237         if (nResult < 0)
2238                 dev_err(pTAS2559->dev, "Block (%d) load error\n",
2239                         pBlock->mnType);
2240
2241         return nResult;
2242 }
2243
2244 static int tas2559_load_data(struct tas2559_priv *pTAS2559, struct TData *pData, unsigned int nType)
2245 {
2246         int nResult = 0;
2247         unsigned int nBlock;
2248         struct TBlock *pBlock;
2249
2250         dev_dbg(pTAS2559->dev,
2251                 "TAS2559 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
2252
2253         for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
2254                 pBlock = &(pData->mpBlocks[nBlock]);
2255
2256                 if (pBlock->mnType == nType) {
2257                         nResult = tas2559_load_block(pTAS2559, pBlock);
2258
2259                         if (nResult < 0)
2260                                 break;
2261                 }
2262         }
2263
2264         return nResult;
2265 }
2266
2267 static int tas2559_load_configuration(struct tas2559_priv *pTAS2559,
2268                                       unsigned int nConfiguration, bool bLoadSame)
2269 {
2270         int nResult = 0;
2271         struct TConfiguration *pCurrentConfiguration = NULL;
2272         struct TConfiguration *pNewConfiguration = NULL;
2273
2274         dev_dbg(pTAS2559->dev, "%s: %d\n", __func__, nConfiguration);
2275
2276         if ((!pTAS2559->mpFirmware->mpPrograms) ||
2277             (!pTAS2559->mpFirmware->mpConfigurations)) {
2278                 dev_err(pTAS2559->dev, "Firmware not loaded\n");
2279                 nResult = 0;
2280                 goto end;
2281         }
2282
2283         if (nConfiguration >= pTAS2559->mpFirmware->mnConfigurations) {
2284                 dev_err(pTAS2559->dev, "Configuration %d doesn't exist\n",
2285                         nConfiguration);
2286                 nResult = 0;
2287                 goto end;
2288         }
2289
2290         if ((!pTAS2559->mbLoadConfigurationPrePowerUp)
2291             && (nConfiguration == pTAS2559->mnCurrentConfiguration)
2292             && (!bLoadSame)) {
2293                 dev_info(pTAS2559->dev, "Configuration %d is already loaded\n",
2294                          nConfiguration);
2295                 nResult = 0;
2296                 goto end;
2297         }
2298
2299         pCurrentConfiguration =
2300                 &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
2301         pNewConfiguration =
2302                 &(pTAS2559->mpFirmware->mpConfigurations[nConfiguration]);
2303
2304         if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
2305                 dev_err(pTAS2559->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
2306                         nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
2307                 nResult = 0;
2308                 goto end;
2309         }
2310
2311         if (pNewConfiguration->mnPLL >= pTAS2559->mpFirmware->mnPLLs) {
2312                 dev_err(pTAS2559->dev, "Configuration %d, %s doesn't have a valid PLL index %d\n",
2313                         nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
2314                 nResult = 0;
2315                 goto end;
2316         }
2317
2318         if (pTAS2559->mbPowerUp) {
2319                 dev_err(pTAS2559->dev, "%s, device power on, load new conf[%d] %s\n", __func__,
2320                         nConfiguration, pNewConfiguration->mpName);
2321                 nResult = tas2559_load_coefficient(pTAS2559, pTAS2559->mnCurrentConfiguration, nConfiguration, true);
2322                 pTAS2559->mbLoadConfigurationPrePowerUp = false;
2323         } else {
2324                 dev_dbg(pTAS2559->dev,
2325                         "TAS2559 was powered down, will load coefficient when power up\n");
2326                 pTAS2559->mbLoadConfigurationPrePowerUp = true;
2327                 pTAS2559->mnNewConfiguration = nConfiguration;
2328         }
2329
2330 end:
2331
2332         if (nResult < 0) {
2333                 if (pTAS2559->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
2334                         failsafe(pTAS2559);
2335         }
2336
2337         return nResult;
2338 }
2339
2340 int tas2559_set_config(struct tas2559_priv *pTAS2559, int config)
2341 {
2342         struct TConfiguration *pConfiguration;
2343         struct TProgram *pProgram;
2344         unsigned int nProgram = pTAS2559->mnCurrentProgram;
2345         unsigned int nConfiguration = config;
2346         int nResult = 0;
2347
2348         if ((!pTAS2559->mpFirmware->mpPrograms) ||
2349             (!pTAS2559->mpFirmware->mpConfigurations)) {
2350                 dev_err(pTAS2559->dev, "Firmware not loaded\n");
2351                 nResult = -EINVAL;
2352                 goto end;
2353         }
2354
2355         if (nConfiguration >= pTAS2559->mpFirmware->mnConfigurations) {
2356                 dev_err(pTAS2559->dev, "Configuration %d doesn't exist\n",
2357                         nConfiguration);
2358                 nResult = -EINVAL;
2359                 goto end;
2360         }
2361
2362         pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[nConfiguration]);
2363         pProgram = &(pTAS2559->mpFirmware->mpPrograms[nProgram]);
2364
2365         if (nProgram != pConfiguration->mnProgram) {
2366                 dev_err(pTAS2559->dev,
2367                         "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
2368                         nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
2369                         nProgram, pProgram->mpName);
2370                 nResult = -EINVAL;
2371                 goto end;
2372         }
2373
2374         dev_dbg(pTAS2559->dev, "%s, load new conf %s\n", __func__, pConfiguration->mpName);
2375         nResult = tas2559_load_configuration(pTAS2559, nConfiguration, false);
2376
2377 end:
2378
2379         return nResult;
2380 }
2381
2382 void tas2559_clear_firmware(struct TFirmware *pFirmware)
2383 {
2384         unsigned int n, nn;
2385
2386         if (!pFirmware)
2387                 return;
2388
2389         kfree(pFirmware->mpDescription);
2390
2391         if (pFirmware->mpPLLs != NULL) {
2392                 for (n = 0; n < pFirmware->mnPLLs; n++) {
2393                         kfree(pFirmware->mpPLLs[n].mpDescription);
2394                         kfree(pFirmware->mpPLLs[n].mBlock.mpData);
2395                 }
2396
2397                 kfree(pFirmware->mpPLLs);
2398         }
2399
2400         if (pFirmware->mpPrograms != NULL) {
2401                 for (n = 0; n < pFirmware->mnPrograms; n++) {
2402                         kfree(pFirmware->mpPrograms[n].mpDescription);
2403                         kfree(pFirmware->mpPrograms[n].mData.mpDescription);
2404
2405                         for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
2406                                 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
2407
2408                         kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
2409                 }
2410
2411                 kfree(pFirmware->mpPrograms);
2412         }
2413
2414         if (pFirmware->mpConfigurations != NULL) {
2415                 for (n = 0; n < pFirmware->mnConfigurations; n++) {
2416                         kfree(pFirmware->mpConfigurations[n].mpDescription);
2417                         kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
2418
2419                         for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
2420                                 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
2421
2422                         kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
2423                 }
2424
2425                 kfree(pFirmware->mpConfigurations);
2426         }
2427
2428         if (pFirmware->mpCalibrations != NULL) {
2429                 for (n = 0; n < pFirmware->mnCalibrations; n++) {
2430                         kfree(pFirmware->mpCalibrations[n].mpDescription);
2431                         kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
2432
2433                         for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
2434                                 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
2435
2436                         kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
2437                 }
2438
2439                 kfree(pFirmware->mpCalibrations);
2440         }
2441
2442         memset(pFirmware, 0x00, sizeof(struct TFirmware));
2443 }
2444
2445 static int tas2559_load_calibration(struct tas2559_priv *pTAS2559,      char *pFileName)
2446 {
2447         int nResult = 0;
2448         int nFile;
2449         mm_segment_t fs;
2450         unsigned char pBuffer[1000];
2451         int nSize = 0;
2452
2453         dev_dbg(pTAS2559->dev, "%s:\n", __func__);
2454
2455         fs = get_fs();
2456         set_fs(KERNEL_DS);
2457         nFile = sys_open(pFileName, O_RDONLY, 0);
2458
2459         dev_info(pTAS2559->dev, "TAS2559 calibration file = %s, handle = %d\n",
2460                  pFileName, nFile);
2461
2462         if (nFile >= 0) {
2463                 nSize = sys_read(nFile, pBuffer, 1000);
2464                 sys_close(nFile);
2465         } else {
2466                 dev_err(pTAS2559->dev, "TAS2559 cannot open calibration file: %s\n",
2467                         pFileName);
2468                 nResult = -EINVAL;
2469         }
2470
2471         set_fs(fs);
2472
2473         if (!nSize)
2474                 goto end;
2475
2476         tas2559_clear_firmware(pTAS2559->mpCalFirmware);
2477         dev_info(pTAS2559->dev, "TAS2559 calibration file size = %d\n", nSize);
2478         nResult = fw_parse(pTAS2559, pTAS2559->mpCalFirmware, pBuffer, nSize);
2479
2480         if (nResult)
2481                 dev_err(pTAS2559->dev, "TAS2559 calibration file is corrupt\n");
2482         else
2483                 dev_info(pTAS2559->dev, "TAS2559 calibration: %d calibrations\n",
2484                          pTAS2559->mpCalFirmware->mnCalibrations);
2485
2486 end:
2487
2488         return nResult;
2489 }
2490
2491 void tas2559_fw_ready(const struct firmware *pFW, void *pContext)
2492 {
2493         struct tas2559_priv *pTAS2559 = (struct tas2559_priv *) pContext;
2494         int nResult;
2495         unsigned int nProgram = 0;
2496         unsigned int nSampleRate = 0;
2497
2498 #ifdef CONFIG_TAS2559_CODEC
2499         mutex_lock(&pTAS2559->codec_lock);
2500 #endif
2501
2502 #ifdef CONFIG_TAS2559_MISC
2503         mutex_lock(&pTAS2559->file_lock);
2504 #endif
2505         dev_info(pTAS2559->dev, "%s:\n", __func__);
2506
2507         if (unlikely(!pFW) || unlikely(!pFW->data)) {
2508                 dev_err(pTAS2559->dev, "%s firmware is not loaded.\n",
2509                         TAS2559_FW_NAME);
2510                 goto end;
2511         }
2512
2513         if (pTAS2559->mpFirmware->mpConfigurations) {
2514                 nProgram = pTAS2559->mnCurrentProgram;
2515                 nSampleRate = pTAS2559->mnCurrentSampleRate;
2516                 dev_dbg(pTAS2559->dev, "clear current firmware\n");
2517                 tas2559_clear_firmware(pTAS2559->mpFirmware);
2518         }
2519
2520         nResult = fw_parse(pTAS2559, pTAS2559->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
2521         release_firmware(pFW);
2522
2523         if (nResult < 0) {
2524                 dev_err(pTAS2559->dev, "firmware is corrupt\n");
2525                 goto end;
2526         }
2527
2528         if (!pTAS2559->mpFirmware->mnPrograms) {
2529                 dev_err(pTAS2559->dev, "firmware contains no programs\n");
2530                 nResult = -EINVAL;
2531                 goto end;
2532         }
2533
2534         if (!pTAS2559->mpFirmware->mnConfigurations) {
2535                 dev_err(pTAS2559->dev, "firmware contains no configurations\n");
2536                 nResult = -EINVAL;
2537                 goto end;
2538         }
2539
2540         if (nProgram >= pTAS2559->mpFirmware->mnPrograms) {
2541                 dev_info(pTAS2559->dev,
2542                          "no previous program, set to default\n");
2543                 nProgram = 0;
2544         }
2545
2546         pTAS2559->mnCurrentSampleRate = nSampleRate;
2547         nResult = tas2559_set_program(pTAS2559, nProgram, -1);
2548
2549 end:
2550
2551 #ifdef CONFIG_TAS2559_CODEC
2552         mutex_unlock(&pTAS2559->codec_lock);
2553 #endif
2554
2555 #ifdef CONFIG_TAS2559_MISC
2556         mutex_unlock(&pTAS2559->file_lock);
2557 #endif
2558 }
2559
2560 int tas2559_set_program(struct tas2559_priv *pTAS2559,
2561                         unsigned int nProgram, int nConfig)
2562 {
2563         struct TProgram *pProgram;
2564         struct TConfiguration *pConfiguration;
2565         unsigned int nConfiguration = 0;
2566         unsigned int nSampleRate = 0;
2567         bool bFound = false;
2568         int nResult = 0;
2569
2570         if ((!pTAS2559->mpFirmware->mpPrograms) ||
2571             (!pTAS2559->mpFirmware->mpConfigurations)) {
2572                 dev_err(pTAS2559->dev, "Firmware not loaded\n");
2573                 nResult = 0;
2574                 goto end;
2575         }
2576
2577         if (nProgram >= pTAS2559->mpFirmware->mnPrograms) {
2578                 dev_err(pTAS2559->dev, "TAS2559: Program %d doesn't exist\n",
2579                         nProgram);
2580                 nResult = 0;
2581                 goto end;
2582         }
2583
2584         if (nConfig < 0) {
2585                 nConfiguration = 0;
2586                 nSampleRate = pTAS2559->mnCurrentSampleRate;
2587
2588                 while (!bFound && (nConfiguration < pTAS2559->mpFirmware->mnConfigurations)) {
2589                         if (pTAS2559->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
2590                                 if (nSampleRate == 0) {
2591                                         bFound = true;
2592                                         dev_info(pTAS2559->dev, "find default configuration %d\n", nConfiguration);
2593                                 } else if (nSampleRate == pTAS2559->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
2594                                         bFound = true;
2595                                         dev_info(pTAS2559->dev, "find matching configuration %d\n", nConfiguration);
2596                                 } else {
2597                                         nConfiguration++;
2598                                 }
2599                         } else {
2600                                 nConfiguration++;
2601                         }
2602                 }
2603
2604                 if (!bFound) {
2605                         dev_err(pTAS2559->dev,
2606                                 "Program %d, no valid configuration found for sample rate %d, ignore\n",
2607                                 nProgram, nSampleRate);
2608                         nResult = 0;
2609                         goto end;
2610                 }
2611         } else {
2612                 if (pTAS2559->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
2613                         dev_err(pTAS2559->dev, "%s, configuration program doesn't match\n", __func__);
2614                         nResult = 0;
2615                         goto end;
2616                 }
2617
2618                 nConfiguration = nConfig;
2619         }
2620
2621         pProgram = &(pTAS2559->mpFirmware->mpPrograms[nProgram]);
2622
2623         if (pTAS2559->mbPowerUp) {
2624                 dev_info(pTAS2559->dev,
2625                          "device powered up, power down to load program %d (%s)\n",
2626                          nProgram, pProgram->mpName);
2627
2628                 if (hrtimer_active(&pTAS2559->mtimer))
2629                         hrtimer_cancel(&pTAS2559->mtimer);
2630
2631                 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE)
2632                         pTAS2559->enableIRQ(pTAS2559, DevBoth, false);
2633
2634                 nResult = tas2559_DevShutdown(pTAS2559, DevBoth);
2635
2636                 if (nResult < 0)
2637                         goto end;
2638         }
2639
2640         pTAS2559->hw_reset(pTAS2559);
2641         nResult = pTAS2559->write(pTAS2559, DevBoth, TAS2559_SW_RESET_REG, 0x01);
2642         if (nResult < 0)
2643                 goto end;
2644
2645         msleep(1);
2646         nResult = tas2559_load_default(pTAS2559);
2647         if (nResult < 0)
2648                 goto end;
2649
2650         dev_info(pTAS2559->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
2651         nResult = tas2559_load_data(pTAS2559, &(pProgram->mData), TAS2559_BLOCK_PGM_DEV_A);
2652         if (nResult < 0)
2653                 goto end;
2654
2655         nResult = tas2559_load_data(pTAS2559, &(pProgram->mData), TAS2559_BLOCK_PGM_DEV_B);
2656         if (nResult < 0)
2657                 goto end;
2658
2659         pTAS2559->mnCurrentProgram = nProgram;
2660         pTAS2559->mnDevGain = 15;
2661         pTAS2559->mnDevCurrentGain = 15;
2662
2663         nResult = tas2559_load_coefficient(pTAS2559, -1, nConfiguration, false);
2664         if (nResult < 0)
2665                 goto end;
2666
2667         if (pTAS2559->mbPowerUp) {
2668                 dev_info(pTAS2559->dev, "%s, load VBoost before power on %d\n", __func__, pTAS2559->mnVBoostState);
2669                 nResult = tas2559_set_VBoost(pTAS2559, pTAS2559->mnVBoostState, false);
2670                 if (nResult < 0)
2671                         goto end;
2672
2673                 pTAS2559->clearIRQ(pTAS2559);
2674                 pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
2675                 nResult = tas2559_DevStartup(pTAS2559, pConfiguration->mnDevices);
2676                 if (nResult < 0)
2677                         goto end;
2678
2679                 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
2680                         nResult = tas2559_checkPLL(pTAS2559);
2681                         if (nResult < 0) {
2682                                 nResult = tas2559_DevShutdown(pTAS2559, pConfiguration->mnDevices);
2683                                 pTAS2559->mbPowerUp = false;
2684                                 goto end;
2685                         }
2686                 }
2687
2688                 if (pConfiguration->mnDevices & DevB) {
2689                         nResult = tas2559_load_data(pTAS2559, &(pConfiguration->mData),
2690                                                 TAS2559_BLOCK_PST_POWERUP_DEV_B);
2691                         if (nResult < 0)
2692                                 goto end;
2693                 }
2694
2695                 nResult = tas2559_DevMute(pTAS2559, pConfiguration->mnDevices, false);
2696                 if (nResult < 0)
2697                         goto end;
2698
2699                 if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
2700                         pTAS2559->enableIRQ(pTAS2559, pConfiguration->mnDevices, true);
2701
2702                         if (!hrtimer_active(&pTAS2559->mtimer)) {
2703                                 pTAS2559->mnDieTvReadCounter = 0;
2704                                 hrtimer_start(&pTAS2559->mtimer,
2705                                               ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
2706                         }
2707                 }
2708         }
2709
2710 end:
2711
2712         if (nResult < 0) {
2713                 if (pTAS2559->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
2714                         failsafe(pTAS2559);
2715         }
2716
2717         return nResult;
2718 }
2719
2720 int tas2559_set_calibration(struct tas2559_priv *pTAS2559, int nCalibration)
2721 {
2722         struct TCalibration *pCalibration = NULL;
2723         struct TConfiguration *pConfiguration;
2724         struct TProgram *pProgram;
2725         int nResult = 0;
2726
2727         if ((!pTAS2559->mpFirmware->mpPrograms)
2728             || (!pTAS2559->mpFirmware->mpConfigurations)) {
2729                 dev_err(pTAS2559->dev, "Firmware not loaded\n\r");
2730                 nResult = 0;
2731                 goto end;
2732         }
2733
2734         if (nCalibration == 0x00FF) {
2735                 dev_info(pTAS2559->dev, "load new calibration file %s\n", TAS2559_CAL_NAME);
2736                 nResult = tas2559_load_calibration(pTAS2559, TAS2559_CAL_NAME);
2737
2738                 if (nResult < 0) {
2739                         nResult = 0;
2740                         goto end;
2741                 }
2742
2743                 nCalibration = 0;
2744         }
2745
2746         if (nCalibration >= pTAS2559->mpCalFirmware->mnCalibrations) {
2747                 dev_err(pTAS2559->dev,
2748                         "Calibration %d doesn't exist\n", nCalibration);
2749                 nResult = 0;
2750                 goto end;
2751         }
2752
2753         pTAS2559->mnCurrentCalibration = nCalibration;
2754
2755         if (pTAS2559->mbLoadConfigurationPrePowerUp)
2756                 goto end;
2757
2758         pCalibration = &(pTAS2559->mpCalFirmware->mpCalibrations[nCalibration]);
2759         pProgram = &(pTAS2559->mpFirmware->mpPrograms[pTAS2559->mnCurrentProgram]);
2760         pConfiguration = &(pTAS2559->mpFirmware->mpConfigurations[pTAS2559->mnCurrentConfiguration]);
2761
2762         if (pProgram->mnAppMode == TAS2559_APP_TUNINGMODE) {
2763                 dev_dbg(pTAS2559->dev, "Enable: load calibration\n");
2764                 nResult = tas2559_load_data(pTAS2559, &(pCalibration->mData), TAS2559_BLOCK_CFG_COEFF_DEV_A);
2765         }
2766
2767 end:
2768
2769         if (nResult < 0) {
2770                 tas2559_clear_firmware(pTAS2559->mpCalFirmware);
2771                 nResult = tas2559_set_program(pTAS2559, pTAS2559->mnCurrentProgram, pTAS2559->mnCurrentConfiguration);
2772         }
2773
2774         return nResult;
2775 }
2776
2777 int tas2559_get_Cali_prm_r0(struct tas2559_priv *pTAS2559, enum channel chl, int *prm_r0)
2778 {
2779         int nResult = 0;
2780         int n, nn;
2781         struct TCalibration *pCalibration;
2782         struct TData *pData;
2783         struct TBlock *pBlock;
2784         int nReg;
2785         int nBook, nPage, nOffset;
2786         unsigned char *pCommands;
2787         int nCali_Re;
2788         bool bFound = false;
2789         int len;
2790
2791         if (!pTAS2559->mpCalFirmware->mnCalibrations) {
2792                 dev_err(pTAS2559->dev, "%s, no calibration data\n", __func__);
2793                 goto end;
2794         }
2795
2796         if (chl == DevA)
2797                 nReg = TAS2559_DEVA_CALI_R0_REG;
2798         else if (chl == DevB)
2799                 nReg = TAS2559_DEVB_CALI_R0_REG;
2800         else
2801                 goto end;
2802
2803         pCalibration = &(pTAS2559->mpCalFirmware->mpCalibrations[pTAS2559->mnCurrentCalibration]);
2804         pData = &(pCalibration->mData);
2805
2806         for (n = 0; n < pData->mnBlocks; n++) {
2807                 pBlock = &(pData->mpBlocks[n]);
2808                 pCommands = pBlock->mpData;
2809
2810                 for (nn = 0 ; nn < pBlock->mnCommands;) {
2811                         nBook = pCommands[4 * nn + 0];
2812                         nPage = pCommands[4 * nn + 1];
2813                         nOffset = pCommands[4 * nn + 2];
2814
2815                         if ((nOffset < 0x7f) || (nOffset == 0x81))
2816                                 nn++;
2817                         else
2818                                 if (nOffset == 0x85) {
2819                                         len = ((int)nBook << 8) | nPage;
2820
2821                                         nBook = pCommands[4 * nn + 4];
2822                                         nPage = pCommands[4 * nn + 5];
2823                                         nOffset = pCommands[4 * nn + 6];
2824
2825                                         if ((nBook == TAS2559_BOOK_ID(nReg))
2826                                             && (nPage == TAS2559_PAGE_ID(nReg))
2827                                             && (nOffset == TAS2559_PAGE_REG(nReg))) {
2828                                                 nCali_Re = ((int)pCommands[4 * nn + 7] << 24)
2829                                                            | ((int)pCommands[4 * nn + 8] << 16)
2830                                                            | ((int)pCommands[4 * nn + 9] << 8)
2831                                                            | (int)pCommands[4 * nn + 10];
2832                                                 bFound = true;
2833                                                 goto end;
2834                                         }
2835
2836                                         nn += 2;
2837                                         nn += ((len - 1) / 4);
2838
2839                                         if ((len - 1) % 4)
2840                                                 nn++;
2841                                 } else {
2842                                         dev_err(pTAS2559->dev, "%s, format error %d\n", __func__, nOffset);
2843                                         break;
2844                                 }
2845                 }
2846         }
2847
2848 end:
2849
2850         if (bFound)
2851                 *prm_r0 = nCali_Re;
2852
2853         return nResult;
2854 }
2855
2856 int tas2559_parse_dt(struct device *dev, struct tas2559_priv *pTAS2559)
2857 {
2858         struct device_node *np = dev->of_node;
2859         int rc = 0, ret = 0;
2860         unsigned int value;
2861
2862         pTAS2559->mnDevAGPIORST = of_get_named_gpio(np, "ti,tas2559-reset-gpio", 0);
2863         if (!gpio_is_valid(pTAS2559->mnDevAGPIORST))
2864                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2865                         "ti,tas2559-reset-gpio", np->full_name, pTAS2559->mnDevAGPIORST);
2866         else
2867                 dev_dbg(pTAS2559->dev, "%s, tas2559 reset gpio %d\n", __func__, pTAS2559->mnDevAGPIORST);
2868
2869         pTAS2559->mnDevBGPIORST = of_get_named_gpio(np, "ti,tas2560-reset-gpio", 0);
2870         if (!gpio_is_valid(pTAS2559->mnDevBGPIORST))
2871                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2872                         "ti,tas2560-reset-gpio", np->full_name, pTAS2559->mnDevBGPIORST);
2873         else
2874                 dev_dbg(pTAS2559->dev, "%s, tas2560 reset gpio %d\n", __func__, pTAS2559->mnDevBGPIORST);
2875
2876         pTAS2559->mnDevAGPIOIRQ = of_get_named_gpio(np, "ti,tas2559-irq-gpio", 0);
2877         if (!gpio_is_valid(pTAS2559->mnDevAGPIOIRQ))
2878                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2879                         "ti,tas2559-irq-gpio", np->full_name, pTAS2559->mnDevAGPIOIRQ);
2880
2881         pTAS2559->mnDevBGPIOIRQ = of_get_named_gpio(np, "ti,tas2560-irq-gpio", 0);
2882         if (!gpio_is_valid(pTAS2559->mnDevBGPIOIRQ))
2883                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2884                         "ti,tas2560-irq-gpio", np->full_name, pTAS2559->mnDevBGPIOIRQ);
2885
2886         rc = of_property_read_u32(np, "ti,tas2559-addr", &value);
2887         if (rc) {
2888                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2889                         "ti,tas2559-addr", np->full_name, rc);
2890                 ret = -EINVAL;
2891                 goto end;
2892         } else {
2893                 pTAS2559->mnDevAAddr = value;
2894                 dev_dbg(pTAS2559->dev, "ti,tas2559 addr=0x%x\n", pTAS2559->mnDevAAddr);
2895         }
2896
2897         rc = of_property_read_u32(np, "ti,tas2560-addr", &value);
2898         if (rc) {
2899                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2900                         "ti,tas2560-addr", np->full_name, rc);
2901                 ret = -EINVAL;
2902                 goto end;
2903         } else {
2904                 pTAS2559->mnDevBAddr = value;
2905                 dev_dbg(pTAS2559->dev, "ti,tas2560-addr=0x%x\n", pTAS2559->mnDevBAddr);
2906         }
2907
2908         rc = of_property_read_u32(np, "ti,tas2559-channel", &value);
2909         if (rc)
2910                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2911                         "ti,tas2559-channel", np->full_name, rc);
2912         else
2913                 pTAS2559->mnDevAChl = value;
2914
2915         rc = of_property_read_u32(np, "ti,tas2560-channel", &value);
2916         if (rc)
2917                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2918                         "ti,tas2560-channel", np->full_name, rc);
2919         else
2920                 pTAS2559->mnDevBChl = value;
2921
2922         rc = of_property_read_u32(np, "ti,echo-ref", &value);
2923         if (rc)
2924                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2925                         "ti,echo-ref", np->full_name, rc);
2926         else
2927                 pTAS2559->mnEchoRef = value;
2928
2929         rc = of_property_read_u32(np, "ti,bit-rate", &value);
2930         if (rc)
2931                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2932                         "ti,i2s-bits", np->full_name, rc);
2933         else
2934                 pTAS2559->mnBitRate = value;
2935
2936         rc = of_property_read_u32(np, "ti,ycrc-enable", &value);
2937         if (rc)
2938                 dev_err(pTAS2559->dev, "Looking up %s property in node %s failed %d\n",
2939                         "ti,ycrc-enable", np->full_name, rc);
2940         else
2941                 pTAS2559->mbYCRCEnable = (value != 0);
2942
2943 end:
2944
2945         return ret;
2946 }
2947
2948 MODULE_AUTHOR("Texas Instruments Inc.");
2949 MODULE_DESCRIPTION("TAS2559 common functions for Android Linux");
2950 MODULE_LICENSE("GPL v2");