1 /*
2 ** =============================================================================
3 ** Copyright (c) 2016 Texas Instruments Inc.
4 **
5 ** This program is free software; you can redistribute it and/or modify it under
6 ** the terms of the GNU General Public License as published by the Free Software
7 ** Foundation; version 2.
8 **
9 ** This program is distributed in the hope that it will be useful, but WITHOUT
10 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 **
13 ** File:
14 ** tas2557-core.c
15 **
16 ** Description:
17 ** TAS2557 common functions for Android Linux
18 **
19 ** =============================================================================
20 */
22 #define DEBUG
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>
41 #include "tas2557.h"
42 #include "tas2557-core.h"
44 #define PPC_DRIVER_VERSION 0x00000200
45 #define TAS2557_CAL_NAME "/data/tas2557_cal.bin"
48 static int tas2557_load_calibration(struct tas2557_priv *pTAS2557,
49 char *pFileName);
50 static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData,
51 unsigned int nType);
52 static void tas2557_clear_firmware(struct TFirmware *pFirmware);
53 static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock);
54 static int tas2557_load_configuration(struct tas2557_priv *pTAS2557,
55 unsigned int nConfiguration, bool bLoadSame);
57 #define TAS2557_UDELAY 0xFFFFFFFE
58 #define TAS2557_MDELAY 0xFFFFFFFD
60 #define TAS2557_BLOCK_PLL 0x00
61 #define TAS2557_BLOCK_PGM_ALL 0x0d
62 #define TAS2557_BLOCK_PGM_DEV_A 0x01
63 #define TAS2557_BLOCK_PGM_DEV_B 0x08
64 #define TAS2557_BLOCK_CFG_COEFF_DEV_A 0x03
65 #define TAS2557_BLOCK_CFG_COEFF_DEV_B 0x0a
66 #define TAS2557_BLOCK_CFG_PRE_DEV_A 0x04
67 #define TAS2557_BLOCK_CFG_PRE_DEV_B 0x0b
68 #define TAS2557_BLOCK_CFG_POST 0x05
69 #define TAS2557_BLOCK_CFG_POST_POWER 0x06
71 static unsigned int p_tas2557_default_data[] = {
72 TAS2557_SAR_ADC2_REG, 0x05, /* enable SAR ADC */
73 /*TODO TAS2555_CLK_ERR_CTRL2, 0x39, enable clock error detection on PLL */
74 /*TODO TAS2555_CLK_ERR_CTRL3, 0x11, enable clock error detection on PLL */
75 TAS2557_SAFE_GUARD_REG, TAS2557_SAFE_GUARD_PATTERN, /* safe guard */
76 0xFFFFFFFF, 0xFFFFFFFF
77 };
79 static unsigned int p_tas2557_irq_config[] = {
80 /* TAS2555_CLK_HALT_REG, 0x71, TODO */
81 TAS2557_INT_GEN1_REG, 0x11, /* enable spk OC and OV */
82 TAS2557_INT_GEN2_REG, 0x11, /* enable clk err1 and die OT */
83 TAS2557_INT_GEN3_REG, 0x11, /* enable clk err2 and brownout */
84 TAS2557_INT_GEN4_REG, 0x01, /* disable SAR, enable clk halt */
85 TAS2557_INT_MODE_REG, 0x80, /* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */
86 TAS2557_GPIO4_PIN_REG, 0x07, /* set GPIO4 as int1, default */
87 0xFFFFFFFF, 0xFFFFFFFF
88 };
90 static unsigned int p_tas2557_startup_data[] = {
91 TAS2557_GPI_PIN_REG, 0x15, /* enable DIN, MCLK, CCI */
92 TAS2557_GPIO1_PIN_REG, 0x01, /* enable BCLK */
93 TAS2557_GPIO2_PIN_REG, 0x01, /* enable WCLK */
94 TAS2557_CLK_ERR_CTRL, 0x00, /* enable clock error detection */
95 TAS2557_POWER_CTRL2_REG, 0xA0, /* Class-D, Boost power up */
96 TAS2557_POWER_CTRL2_REG, 0xA3, /* Class-D, Boost, IV sense power up */
97 TAS2557_POWER_CTRL1_REG, 0xF8, /* PLL, DSP, clock dividers power up */
98 TAS2557_UDELAY, 2000, /* delay */
99 /* TAS2557_CLK_ERR_CTRL, 0x03, TODO enable clock error detection */
100 0xFFFFFFFF, 0xFFFFFFFF
101 };
103 static unsigned int p_tas2557_unmute_data[] = {
104 TAS2557_MUTE_REG, 0x00, /* unmute */
105 TAS2557_SOFT_MUTE_REG, 0x00, /* soft unmute */
106 0xFFFFFFFF, 0xFFFFFFFF
107 };
109 static unsigned int p_tas2557_shutdown_data[] = {
110 TAS2557_CLK_ERR_CTRL, 0x00, /* disable clock error detection */
111 TAS2557_SOFT_MUTE_REG, 0x01, /* soft mute */
112 TAS2557_UDELAY, 10000, /* delay 10ms */
113 TAS2557_MUTE_REG, 0x03, /* mute */
114 TAS2557_POWER_CTRL1_REG, 0x60, /* DSP power down */
115 TAS2557_UDELAY, 2000, /* delay 2ms */
116 TAS2557_POWER_CTRL2_REG, 0x00, /* Class-D, Boost power down */
117 TAS2557_POWER_CTRL1_REG, 0x00, /* all power down */
118 TAS2557_GPIO1_PIN_REG, 0x00, /* disable BCLK */
119 TAS2557_GPIO2_PIN_REG, 0x00, /* disable WCLK */
120 TAS2557_GPI_PIN_REG, 0x00, /* disable DIN, MCLK, CCI */
121 0xFFFFFFFF, 0xFFFFFFFF
122 };
124 static unsigned int p_tas2557_mute_DSP_down_data[] = {
125 TAS2557_MUTE_REG, 0x03, /* mute */
126 TAS2557_POWER_CTRL1_REG, 0x60, /* DSP power down */
127 TAS2557_UDELAY, 0xFF, /* delay */
128 0xFFFFFFFF, 0xFFFFFFFF
129 };
131 static int tas2557_dev_load_data(struct tas2557_priv *pTAS2557,
132 unsigned int *pData)
133 {
134 int ret = 0;
135 unsigned int n = 0;
136 unsigned int nRegister;
137 unsigned int nData;
139 do {
140 nRegister = pData[n * 2];
141 nData = pData[n * 2 + 1];
142 if (nRegister == TAS2557_UDELAY)
143 udelay(nData);
144 else if (nRegister != 0xFFFFFFFF) {
145 ret = pTAS2557->write(pTAS2557, nRegister, nData);
146 if (ret < 0)
147 break;
148 }
149 n++;
150 } while (nRegister != 0xFFFFFFFF);
151 return ret;
152 }
154 int tas2557_configIRQ(struct tas2557_priv *pTAS2557)
155 {
156 return tas2557_dev_load_data(pTAS2557, p_tas2557_irq_config);
157 }
159 int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate)
160 {
161 int ret = 0, n = -1;
163 dev_dbg(pTAS2557->dev, "tas2557_set_bit_rate: nBitRate = %d\n", nBitRate);
165 switch (nBitRate) {
166 case 16:
167 n = 0;
168 break;
169 case 20:
170 n = 1;
171 break;
172 case 24:
173 n = 2;
174 break;
175 case 32:
176 n = 3;
177 break;
178 }
180 if (n >= 0)
181 ret = pTAS2557->update_bits(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, 0x18, n<<3);
182 return ret;
183 }
185 int tas2557_get_bit_rate(struct tas2557_priv *pTAS2557, unsigned char *pBitRate)
186 {
187 int ret = 0;
188 unsigned int nValue = 0;
189 unsigned char bitRate;
191 ret = pTAS2557->read(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, &nValue);
192 if (ret >= 0) {
193 bitRate = (nValue&0x18)>>3;
194 if (bitRate == 0)
195 bitRate = 16;
196 else if (bitRate == 1)
197 bitRate = 20;
198 else if (bitRate == 2)
199 bitRate = 24;
200 else if (bitRate == 3)
201 bitRate = 32;
202 *pBitRate = bitRate;
203 }
205 return ret;
206 }
208 int tas2557_get_DAC_gain(struct tas2557_priv *pTAS2557, unsigned char *pnGain)
209 {
210 int ret = 0;
211 unsigned int nValue = 0;
213 ret = pTAS2557->read(pTAS2557, TAS2557_SPK_CTRL_REG, &nValue);
214 if (ret >= 0)
215 *pnGain = ((nValue&TAS2557_DAC_GAIN_MASK)>>TAS2557_DAC_GAIN_SHIFT);
217 return ret;
218 }
220 int tas2557_set_DAC_gain(struct tas2557_priv *pTAS2557, unsigned int nGain)
221 {
222 int ret = 0;
224 ret = pTAS2557->update_bits(pTAS2557, TAS2557_SPK_CTRL_REG, TAS2557_DAC_GAIN_MASK,
225 (nGain<<TAS2557_DAC_GAIN_SHIFT));
226 return ret;
227 }
229 /*
230 * die temperature calculation:
231 * DieTemp = readout / 2^23
232 */
233 int tas2557_get_die_temperature(struct tas2557_priv *pTAS2557, int *pTemperature)
234 {
235 unsigned char nBuf[4];
236 int temp;
237 int nResult = 0;
239 if (pTAS2557->mbPowerUp) {
240 nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_DIE_TEMP_REG, nBuf, 4);
241 if (nResult >= 0) {
242 temp = ((int)nBuf[0] << 24) | ((int)nBuf[1] << 16) | ((int)nBuf[2] << 8) | nBuf[3];
243 *pTemperature = temp;
244 }
245 } else
246 dev_err(pTAS2557->dev, "Get Die Temperature when music is playing\n");
248 return nResult;
249 }
251 int tas2557_load_platdata(struct tas2557_priv *pTAS2557)
252 {
253 int nResult = 0;
255 if (gpio_is_valid(pTAS2557->mnGpioINT)) {
256 nResult = tas2557_configIRQ(pTAS2557);
257 if (nResult < 0)
258 goto end;
259 }
261 nResult = tas2557_set_bit_rate(pTAS2557, pTAS2557->mnI2SBits);
263 end:
265 return nResult;
266 }
268 int tas2557_load_default(struct tas2557_priv *pTAS2557)
269 {
270 int nResult = 0;
272 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_default_data);
273 if (nResult < 0)
274 goto end;
276 nResult = tas2557_load_platdata(pTAS2557);
277 if (nResult < 0)
278 goto end;
280 /* enable DOUT tri-state for extra BCLKs */
281 nResult = pTAS2557->update_bits(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, 0x01, 0x01);
282 end:
284 return nResult;
285 }
287 static void failsafe(struct tas2557_priv *pTAS2557)
288 {
289 dev_err(pTAS2557->dev, "%s\n", __func__);
290 tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
291 pTAS2557->mbPowerUp = false;
292 pTAS2557->hw_reset(pTAS2557);
293 pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
294 udelay(1000);
295 pTAS2557->write(pTAS2557, TAS2557_SPK_CTRL_REG, 0x04);
296 if (pTAS2557->mpFirmware != NULL)
297 tas2557_clear_firmware(pTAS2557->mpFirmware);
298 }
301 /*
302 * tas2557_load_coefficient
303 */
304 static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557,
305 int nPrevConfig, int nNewConfig, bool bPowerOn)
306 {
307 int nResult = 0;
308 struct TPLL *pPLL;
309 bool bRestorePower = false;
310 struct TProgram *pProgram;
311 struct TConfiguration *pPrevConfiguration;
312 struct TConfiguration *pNewConfiguration;
313 struct TCalibration *pCalibration = NULL;
315 if (!pTAS2557->mpFirmware->mnConfigurations) {
316 dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
317 goto end;
318 }
320 if (nNewConfig >= pTAS2557->mpFirmware->mnConfigurations) {
321 dev_err(pTAS2557->dev, "%s, invalid configuration New=%d, total=%d\n",
322 __func__, nNewConfig, pTAS2557->mpFirmware->mnConfigurations);
323 goto end;
324 }
326 if (nPrevConfig < 0)
327 pPrevConfiguration = NULL;
328 else
329 pPrevConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nPrevConfig]);
331 pNewConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nNewConfig]);
333 if (pPrevConfiguration) {
334 if (pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL) {
335 dev_dbg(pTAS2557->dev, "%s, PLL same\n", __func__);
336 goto prog_coefficient;
337 }
338 }
340 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
341 if (bPowerOn) {
342 dev_dbg(pTAS2557->dev, "%s, power down to load new PLL\n", __func__);
343 if (hrtimer_active(&pTAS2557->mtimer))
344 hrtimer_cancel(&pTAS2557->mtimer);
346 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
347 pTAS2557->enableIRQ(pTAS2557, false);
349 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_mute_DSP_down_data);
350 if (nResult < 0)
351 goto end;
352 bRestorePower = true;
353 }
355 /* load PLL */
356 pPLL = &(pTAS2557->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
357 dev_dbg(pTAS2557->dev, "load PLL: %s block for Configuration %s\n",
358 pPLL->mpName, pNewConfiguration->mpName);
359 nResult = tas2557_load_block(pTAS2557, &(pPLL->mBlock));
360 if (nResult < 0)
361 goto end;
362 pTAS2557->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
363 dev_dbg(pTAS2557->dev, "load configuration %s conefficient pre block\n",
364 pNewConfiguration->mpName);
365 nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), TAS2557_BLOCK_CFG_PRE_DEV_A);
366 if (nResult < 0)
367 goto end;
369 prog_coefficient:
370 dev_dbg(pTAS2557->dev, "load new configuration: %s, coeff block data\n",
371 pNewConfiguration->mpName);
372 nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData),
373 TAS2557_BLOCK_CFG_COEFF_DEV_A);
374 if (nResult < 0)
375 goto end;
376 pTAS2557->mnCurrentConfiguration = nNewConfig;
377 if (pTAS2557->mpCalFirmware->mnCalibrations) {
378 pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[pTAS2557->mnCurrentCalibration]);
379 dev_dbg(pTAS2557->dev, "load calibration\n");
380 nResult = tas2557_load_data(pTAS2557, &(pCalibration->mData),
381 TAS2557_BLOCK_CFG_COEFF_DEV_A);
382 if (nResult < 0)
383 goto end;
384 }
386 if (bRestorePower) {
387 pTAS2557->clearIRQ(pTAS2557);
388 dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
389 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
390 if (nResult < 0)
391 goto end;
392 dev_dbg(pTAS2557->dev,
393 "device powered up, load unmute\n");
394 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
395 if (nResult < 0)
396 goto end;
397 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
398 pTAS2557->enableIRQ(pTAS2557, true);
399 if (!hrtimer_active(&pTAS2557->mtimer)) {
400 pTAS2557->mnDieTvReadCounter = 0;
401 hrtimer_start(&pTAS2557->mtimer,
402 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
403 }
404 }
405 }
406 end:
408 return nResult;
409 }
411 int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable)
412 {
413 int nResult = 0, nRetry = 10;
414 unsigned char nBuf[4];
415 unsigned int nValue;
416 struct TProgram *pProgram;
418 dev_dbg(pTAS2557->dev, "Enable: %d\n", bEnable);
420 if ((pTAS2557->mpFirmware->mnPrograms == 0)
421 || (pTAS2557->mpFirmware->mnConfigurations == 0)) {
422 dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
423 goto end;
424 }
425 /* check safe guard*/
426 nResult = pTAS2557->read(pTAS2557, TAS2557_SAFE_GUARD_REG, &nValue);
427 if (nResult < 0)
428 goto end;
429 if ((nValue&0xff) != TAS2557_SAFE_GUARD_PATTERN) {
430 dev_err(pTAS2557->dev, "ERROR safe guard failure!\n");
431 nResult = -EPIPE;
432 goto end;
433 }
435 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
436 if (bEnable) {
437 if (!pTAS2557->mbPowerUp) {
438 if (pTAS2557->mbLoadConfigurationPrePowerUp) {
439 dev_dbg(pTAS2557->dev, "load coefficient before power\n");
440 nResult = tas2557_load_coefficient(pTAS2557,
441 pTAS2557->mnCurrentConfiguration, pTAS2557->mnNewConfiguration, false);
442 if (nResult < 0)
443 goto end;
444 pTAS2557->mbLoadConfigurationPrePowerUp = false;
445 }
447 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
448 dev_dbg(pTAS2557->dev, "Tuning mode, check PLL\n");
449 /* check PLL */
450 pllcheck:
451 nResult = pTAS2557->write(pTAS2557, TAS2557_POWER_CTRL1_REG, 0xf8);
452 if (nResult < 0)
453 goto end;
454 msleep(2);
455 /* check TAS2557 */
456 memset(nBuf, 0, 4);
457 nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_XMEM_44_REG, nBuf, 4);
458 if (nResult < 0)
459 goto end;
460 nValue = ((unsigned int)nBuf[0] << 24) | ((unsigned int)nBuf[1] << 16) | ((unsigned int)nBuf[2] << 8) | nBuf[3];
461 if (nValue == 0) {
462 nResult = pTAS2557->write(pTAS2557, TAS2557_POWER_CTRL1_REG, 0x60);
463 if (nResult < 0)
464 goto end;
465 msleep(2);
466 nResult = pTAS2557->write(pTAS2557, TAS2557_POWER_CTRL1_REG, 0x00);
467 if (nResult < 0)
468 goto end;
469 msleep(2);
470 nRetry--;
471 nResult = -EAGAIN;
472 if (nRetry == 0)
473 goto end;
475 dev_info(pTAS2557->dev, "PLL is absent, check again %d\n", nRetry);
476 goto pllcheck;
477 }
478 }
480 pTAS2557->clearIRQ(pTAS2557);
481 /* power on device */
482 dev_dbg(pTAS2557->dev, "Enable: load startup sequence\n");
483 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
484 if (nResult < 0)
485 goto end;
486 dev_dbg(pTAS2557->dev, "Enable: load unmute sequence\n");
487 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
488 if (nResult < 0)
489 goto end;
491 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
492 /* turn on IRQ */
493 pTAS2557->enableIRQ(pTAS2557, true);
494 if (!hrtimer_active(&pTAS2557->mtimer)) {
495 pTAS2557->mnDieTvReadCounter = 0;
496 hrtimer_start(&pTAS2557->mtimer,
497 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
498 }
499 }
500 pTAS2557->mbPowerUp = true;
501 }
502 } else {
503 if (pTAS2557->mbPowerUp) {
504 if (hrtimer_active(&pTAS2557->mtimer))
505 hrtimer_cancel(&pTAS2557->mtimer);
507 dev_dbg(pTAS2557->dev, "Enable: load shutdown sequence\n");
508 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
509 /* turn off IRQ */
510 pTAS2557->enableIRQ(pTAS2557, false);
511 }
512 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
513 if (nResult < 0)
514 goto end;
516 pTAS2557->mbPowerUp = false;
517 }
518 }
520 nResult = 0;
522 end:
523 if (nResult < 0) {
524 if (nRetry == 0)
525 dev_err(pTAS2557->dev, "PLL is absent and enable timeout\n");
526 else
527 dev_err(pTAS2557->dev, "enable failure %d\n", nResult);
528 failsafe(pTAS2557);
529 }
531 return nResult;
532 }
534 int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate)
535 {
536 struct TConfiguration *pConfiguration;
537 unsigned int nConfiguration;
538 int nResult = 0;
540 dev_dbg(pTAS2557->dev, "tas2557_setup_clocks: nSamplingRate = %d [Hz]\n",
541 nSamplingRate);
543 if ((!pTAS2557->mpFirmware->mpPrograms) ||
544 (!pTAS2557->mpFirmware->mpConfigurations)) {
545 dev_err(pTAS2557->dev, "Firmware not loaded\n");
546 nResult = -EINVAL;
547 goto end;
548 }
550 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
551 if (pConfiguration->mnSamplingRate == nSamplingRate) {
552 dev_info(pTAS2557->dev, "Sampling rate for current configuration matches: %d\n",
553 nSamplingRate);
554 nResult = 0;
555 goto end;
556 }
558 for (nConfiguration = 0;
559 nConfiguration < pTAS2557->mpFirmware->mnConfigurations;
560 nConfiguration++) {
561 pConfiguration =
562 &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
563 if ((pConfiguration->mnSamplingRate == nSamplingRate)
564 && (pConfiguration->mnProgram == pTAS2557->mnCurrentProgram)) {
565 dev_info(pTAS2557->dev,
566 "Found configuration: %s, with compatible sampling rate %d\n",
567 pConfiguration->mpName, nSamplingRate);
568 nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
569 goto end;
570 }
571 }
573 dev_err(pTAS2557->dev, "Cannot find a configuration that supports sampling rate: %d\n",
574 nSamplingRate);
576 end:
578 return nResult;
579 }
581 static void fw_print_header(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware)
582 {
583 dev_info(pTAS2557->dev, "FW Size = %d", pFirmware->mnFWSize);
584 dev_info(pTAS2557->dev, "Checksum = 0x%04X", pFirmware->mnChecksum);
585 dev_info(pTAS2557->dev, "PPC Version = 0x%04X", pFirmware->mnPPCVersion);
586 dev_info(pTAS2557->dev, "FW Version = 0x%04X", pFirmware->mnFWVersion);
587 dev_info(pTAS2557->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
588 dev_info(pTAS2557->dev, "Timestamp = %d", pFirmware->mnTimeStamp);
589 dev_info(pTAS2557->dev, "DDC Name = %s", pFirmware->mpDDCName);
590 dev_info(pTAS2557->dev, "Description = %s", pFirmware->mpDescription);
591 }
593 inline unsigned int fw_convert_number(unsigned char *pData)
594 {
595 return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
596 }
598 static int fw_parse_header(struct tas2557_priv *pTAS2557,
599 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
600 {
601 unsigned char *pDataStart = pData;
602 unsigned int n;
603 unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
605 if (nSize < 104) {
606 dev_err(pTAS2557->dev, "Firmware: Header too short");
607 return -EINVAL;
608 }
610 if (memcmp(pData, pMagicNumber, 4)) {
611 dev_err(pTAS2557->dev, "Firmware: Magic number doesn't match");
612 return -EINVAL;
613 }
614 pData += 4;
616 pFirmware->mnFWSize = fw_convert_number(pData);
617 pData += 4;
619 pFirmware->mnChecksum = fw_convert_number(pData);
620 pData += 4;
622 pFirmware->mnPPCVersion = fw_convert_number(pData);
623 pData += 4;
625 pFirmware->mnFWVersion = fw_convert_number(pData);
626 pData += 4;
628 pFirmware->mnDriverVersion = fw_convert_number(pData);
629 pData += 4;
631 pFirmware->mnTimeStamp = fw_convert_number(pData);
632 pData += 4;
634 memcpy(pFirmware->mpDDCName, pData, 64);
635 pData += 64;
637 n = strlen(pData);
638 pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
639 pData += n + 1;
640 if ((pData - pDataStart) >= nSize) {
641 dev_err(pTAS2557->dev, "Firmware: Header too short after DDC description");
642 return -EINVAL;
643 }
645 pFirmware->mnDeviceFamily = fw_convert_number(pData);
646 pData += 4;
647 if (pFirmware->mnDeviceFamily != 0) {
648 dev_err(pTAS2557->dev, "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
649 return -EINVAL;
650 }
652 pFirmware->mnDevice = fw_convert_number(pData);
653 pData += 4;
655 if (pFirmware->mnDevice != 2) {
656 dev_err(pTAS2557->dev, "device %d, not TAS2557", pFirmware->mnDevice);
657 return -EINVAL;
658 }
660 fw_print_header(pTAS2557, pFirmware);
661 return pData - pDataStart;
662 }
664 static int fw_parse_block_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
665 struct TBlock *pBlock, unsigned char *pData)
666 {
667 unsigned char *pDataStart = pData;
668 unsigned int n;
670 pBlock->mnType = fw_convert_number(pData);
671 pData += 4;
673 if (pFirmware->mnDriverVersion >= PPC_DRIVER_VERSION) {
674 pBlock->mbPChkSumPresent = pData[0];
675 pData++;
677 pBlock->mnPChkSum = pData[0];
678 pData++;
680 pBlock->mbYChkSumPresent = pData[0];
681 pData++;
683 pBlock->mnYChkSum = pData[0];
684 pData++;
685 } else {
686 pBlock->mbPChkSumPresent = 0;
687 pBlock->mbYChkSumPresent = 0;
688 }
690 pBlock->mnCommands = fw_convert_number(pData);
691 pData += 4;
693 n = pBlock->mnCommands * 4;
694 pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
695 pData += n;
697 return pData - pDataStart;
698 }
700 static int fw_parse_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
701 struct TData *pImageData, unsigned char *pData)
702 {
703 unsigned char *pDataStart = pData;
704 unsigned int nBlock;
705 unsigned int n;
707 memcpy(pImageData->mpName, pData, 64);
708 pData += 64;
710 n = strlen(pData);
711 pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
712 pData += n + 1;
714 pImageData->mnBlocks = (pData[0] << 8) + pData[1];
715 pData += 2;
717 pImageData->mpBlocks =
718 kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
719 for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
720 n = fw_parse_block_data(pTAS2557, pFirmware,
721 &(pImageData->mpBlocks[nBlock]), pData);
722 pData += n;
723 }
725 return pData - pDataStart;
726 }
728 static int fw_parse_pll_data(struct tas2557_priv *pTAS2557,
729 struct TFirmware *pFirmware, unsigned char *pData)
730 {
731 unsigned char *pDataStart = pData;
732 unsigned int n;
733 unsigned int nPLL;
734 struct TPLL *pPLL;
736 pFirmware->mnPLLs = (pData[0] << 8) + pData[1];
737 pData += 2;
739 if (pFirmware->mnPLLs == 0)
740 goto end;
742 pFirmware->mpPLLs = kmalloc_array(pFirmware->mnPLLs, sizeof(struct TPLL), GFP_KERNEL);
743 for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) {
744 pPLL = &(pFirmware->mpPLLs[nPLL]);
746 memcpy(pPLL->mpName, pData, 64);
747 pData += 64;
749 n = strlen(pData);
750 pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
751 pData += n + 1;
753 n = fw_parse_block_data(pTAS2557, pFirmware, &(pPLL->mBlock), pData);
754 pData += n;
755 }
757 end:
758 return pData - pDataStart;
759 }
761 static int fw_parse_program_data(struct tas2557_priv *pTAS2557,
762 struct TFirmware *pFirmware, unsigned char *pData)
763 {
764 unsigned char *pDataStart = pData;
765 unsigned int n;
766 unsigned int nProgram;
767 struct TProgram *pProgram;
769 pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
770 pData += 2;
772 if (pFirmware->mnPrograms == 0)
773 goto end;
775 pFirmware->mpPrograms =
776 kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
777 for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
778 pProgram = &(pFirmware->mpPrograms[nProgram]);
779 memcpy(pProgram->mpName, pData, 64);
780 pData += 64;
782 n = strlen(pData);
783 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
784 pData += n + 1;
786 pProgram->mnAppMode = pData[0];
787 pData++;
789 pProgram->mnBoost = (pData[0] << 8) + pData[1];
790 pData += 2;
792 n = fw_parse_data(pTAS2557, pFirmware, &(pProgram->mData), pData);
793 pData += n;
794 }
796 end:
798 return pData - pDataStart;
799 }
801 static int fw_parse_configuration_data(struct tas2557_priv *pTAS2557,
802 struct TFirmware *pFirmware, unsigned char *pData)
803 {
804 unsigned char *pDataStart = pData;
805 unsigned int n;
806 unsigned int nConfiguration;
807 struct TConfiguration *pConfiguration;
809 pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
810 pData += 2;
812 if (pFirmware->mnConfigurations == 0)
813 goto end;
815 pFirmware->mpConfigurations =
816 kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
817 GFP_KERNEL);
818 for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations; nConfiguration++) {
819 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
820 memcpy(pConfiguration->mpName, pData, 64);
821 pData += 64;
823 n = strlen(pData);
824 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
825 pData += n + 1;
827 pConfiguration->mnProgram = pData[0];
828 pData++;
830 pConfiguration->mnPLL = pData[0];
831 pData++;
833 pConfiguration->mnSamplingRate = fw_convert_number(pData);
834 pData += 4;
836 n = fw_parse_data(pTAS2557, pFirmware, &(pConfiguration->mData), pData);
837 pData += n;
838 }
840 end:
842 return pData - pDataStart;
843 }
845 int fw_parse_calibration_data(struct tas2557_priv *pTAS2557,
846 struct TFirmware *pFirmware, unsigned char *pData)
847 {
848 unsigned char *pDataStart = pData;
849 unsigned int n;
850 unsigned int nCalibration;
851 struct TCalibration *pCalibration;
853 pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
854 pData += 2;
856 if (pFirmware->mnCalibrations == 0)
857 goto end;
859 pFirmware->mpCalibrations =
860 kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
861 for (nCalibration = 0; nCalibration < pFirmware->mnCalibrations; nCalibration++) {
862 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
863 memcpy(pCalibration->mpName, pData, 64);
864 pData += 64;
866 n = strlen(pData);
867 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
868 pData += n + 1;
870 pCalibration->mnProgram = pData[0];
871 pData++;
873 pCalibration->mnConfiguration = pData[0];
874 pData++;
876 n = fw_parse_data(pTAS2557, pFirmware, &(pCalibration->mData), pData);
877 pData += n;
878 }
880 end:
882 return pData - pDataStart;
883 }
885 static int fw_parse(struct tas2557_priv *pTAS2557,
886 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
887 {
888 int nPosition = 0;
890 nPosition = fw_parse_header(pTAS2557, pFirmware, pData, nSize);
891 if (nPosition < 0) {
892 dev_err(pTAS2557->dev, "Firmware: Wrong Header");
893 return -EINVAL;
894 }
896 if (nPosition >= nSize) {
897 dev_err(pTAS2557->dev, "Firmware: Too short");
898 return -EINVAL;
899 }
901 pData += nPosition;
902 nSize -= nPosition;
903 nPosition = 0;
905 nPosition = fw_parse_pll_data(pTAS2557, pFirmware, pData);
907 pData += nPosition;
908 nSize -= nPosition;
909 nPosition = 0;
911 nPosition = fw_parse_program_data(pTAS2557, pFirmware, pData);
913 pData += nPosition;
914 nSize -= nPosition;
915 nPosition = 0;
917 nPosition = fw_parse_configuration_data(pTAS2557, pFirmware, pData);
919 pData += nPosition;
920 nSize -= nPosition;
921 nPosition = 0;
923 if (nSize > 64)
924 nPosition = fw_parse_calibration_data(pTAS2557, pFirmware, pData);
925 return 0;
926 }
929 static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
930 0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
931 0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
932 0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
933 0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
934 0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
935 0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
936 0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
937 0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
938 0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
939 0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
940 0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
941 0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
942 0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
943 0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
944 0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
945 0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
946 };
948 static int isInPageYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
949 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
950 {
951 int nResult = 0;
953 if (nBook == TAS2557_YRAM_BOOK1) {
954 if (nPage == TAS2557_YRAM1_PAGE) {
955 if (nReg >= TAS2557_YRAM1_START_REG) {
956 pCRCData->mnOffset = nReg;
957 pCRCData->mnLen = len;
958 nResult = 1;
959 } else if ((nReg + len) > TAS2557_YRAM1_START_REG) {
960 pCRCData->mnOffset = TAS2557_YRAM1_START_REG;
961 pCRCData->mnLen = len - (TAS2557_YRAM1_START_REG - nReg);
962 nResult = 1;
963 } else
964 nResult = 0;
965 } else if (nPage == TAS2557_YRAM3_PAGE) {
966 if (nReg > TAS2557_YRAM3_END_REG) {
967 nResult = 0;
968 } else if (nReg >= TAS2557_YRAM3_START_REG) {
969 if ((nReg + len) > TAS2557_YRAM3_END_REG) {
970 pCRCData->mnOffset = nReg;
971 pCRCData->mnLen = TAS2557_YRAM3_END_REG - nReg + 1;
972 nResult = 1;
973 } else {
974 pCRCData->mnOffset = nReg;
975 pCRCData->mnLen = len;
976 nResult = 1;
977 }
978 } else {
979 if ((nReg + len) < TAS2557_YRAM3_START_REG)
980 nResult = 0;
981 else {
982 pCRCData->mnOffset = TAS2557_YRAM3_START_REG;
983 pCRCData->mnLen = len - (TAS2557_YRAM3_START_REG - nReg);
984 nResult = 1;
985 }
986 }
987 }
988 } else if (nBook == TAS2557_YRAM_BOOK2) {
989 if (nPage == TAS2557_YRAM5_PAGE) {
990 if (nReg > TAS2557_YRAM5_END_REG) {
991 nResult = 0;
992 } else if (nReg >= TAS2557_YRAM5_START_REG) {
993 if ((nReg + len) > TAS2557_YRAM5_END_REG) {
994 pCRCData->mnOffset = nReg;
995 pCRCData->mnLen = TAS2557_YRAM5_END_REG - nReg + 1;
996 nResult = 1;
997 } else {
998 pCRCData->mnOffset = nReg;
999 pCRCData->mnLen = len;
1000 nResult = 1;
1001 }
1002 } else {
1003 if ((nReg + len) < TAS2557_YRAM5_START_REG)
1004 nResult = 0;
1005 else {
1006 pCRCData->mnOffset = TAS2557_YRAM5_START_REG;
1007 pCRCData->mnLen = len - (TAS2557_YRAM5_START_REG - nReg);
1008 nResult = 1;
1009 }
1010 }
1011 }
1012 } else
1013 nResult = 0;
1015 return nResult;
1016 }
1018 static int isInBlockYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1019 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1020 {
1021 int nResult;
1023 if (nBook == TAS2557_YRAM_BOOK1) {
1024 if (nPage < TAS2557_YRAM2_START_PAGE)
1025 nResult = 0;
1026 else if (nPage <= TAS2557_YRAM2_END_PAGE) {
1027 if (nReg > TAS2557_YRAM2_END_REG)
1028 nResult = 0;
1029 else if (nReg >= TAS2557_YRAM2_START_REG) {
1030 pCRCData->mnOffset = nReg;
1031 pCRCData->mnLen = len;
1032 nResult = 1;
1033 } else {
1034 if ((nReg + len) < TAS2557_YRAM2_START_REG)
1035 nResult = 0;
1036 else {
1037 pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
1038 pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
1039 nResult = 1;
1040 }
1041 }
1042 } else
1043 nResult = 0;
1044 } else if (nBook == TAS2557_YRAM_BOOK2) {
1045 if (nPage < TAS2557_YRAM4_START_PAGE)
1046 nResult = 0;
1047 else if (nPage <= TAS2557_YRAM4_END_PAGE) {
1048 if (nReg > TAS2557_YRAM2_END_REG)
1049 nResult = 0;
1050 else if (nReg >= TAS2557_YRAM2_START_REG) {
1051 pCRCData->mnOffset = nReg;
1052 pCRCData->mnLen = len;
1053 nResult = 1;
1054 } else {
1055 if ((nReg + len) < TAS2557_YRAM2_START_REG)
1056 nResult = 0;
1057 else {
1058 pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
1059 pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
1060 nResult = 1;
1061 }
1062 }
1063 } else
1064 nResult = 0;
1065 } else
1066 nResult = 0;
1068 return nResult;
1069 }
1072 static int isYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1073 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1074 {
1075 int nResult;
1077 nResult = isInPageYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
1079 if (nResult == 0)
1080 nResult = isInBlockYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
1082 return nResult;
1083 }
1085 /*
1086 * crc8 - calculate a crc8 over the given input data.
1087 *
1088 * table: crc table used for calculation.
1089 * pdata: pointer to data buffer.
1090 * nbytes: number of bytes in data buffer.
1091 * crc: previous returned crc8 value.
1092 */
1093 static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
1094 {
1095 /* loop over the buffer data */
1096 while (nbytes-- > 0)
1097 crc = table[(crc ^ *pdata++) & 0xff];
1099 return crc;
1100 }
1102 static int doSingleRegCheckSum(struct tas2557_priv *pTAS2557,
1103 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
1104 {
1105 int nResult = 0;
1106 struct TYCRC sCRCData;
1107 unsigned int nData1 = 0;
1109 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1110 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1111 && (nReg >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1112 && (nReg <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
1113 /* DSP swap command, pass */
1114 nResult = 0;
1115 goto end;
1116 }
1118 nResult = isYRAM(pTAS2557, &sCRCData, nBook, nPage, nReg, 1);
1119 if (nResult == 1) {
1120 nResult = pTAS2557->read(pTAS2557, TAS2557_REG(nBook, nPage, nReg), &nData1);
1121 if (nResult < 0)
1122 goto end;
1124 if (nData1 != nValue) {
1125 dev_err(pTAS2557->dev, "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1126 __LINE__, nBook, nPage, nReg, nValue, nData1);
1127 nResult = -EAGAIN;
1128 goto end;
1129 }
1131 nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0);
1132 }
1134 end:
1136 return nResult;
1137 }
1139 static int doMultiRegCheckSum(struct tas2557_priv *pTAS2557,
1140 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
1141 {
1142 int nResult = 0, i;
1143 unsigned char nCRCChkSum = 0;
1144 unsigned char nBuf1[128];
1145 struct TYCRC TCRCData;
1147 if ((nReg + len-1) > 127) {
1148 nResult = -EINVAL;
1149 dev_err(pTAS2557->dev, "firmware error\n");
1150 goto end;
1151 }
1153 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1154 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1155 && (nReg == TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1156 && (len == 4)) {
1157 /* DSP swap command, pass */
1158 nResult = 0;
1159 goto end;
1160 }
1162 nResult = isYRAM(pTAS2557, &TCRCData, nBook, nPage, nReg, len);
1163 if (nResult == 1) {
1164 if (len == 1) {
1165 dev_err(pTAS2557->dev, "firmware error\n");
1166 nResult = -EINVAL;
1167 goto end;
1168 } else {
1169 nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
1170 if (nResult < 0)
1171 goto end;
1173 for (i = 0; i < TCRCData.mnLen; i++) {
1174 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1175 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1176 && ((i + TCRCData.mnOffset)
1177 >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1178 && ((i + TCRCData.mnOffset)
1179 <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
1180 /* DSP swap command, bypass */
1181 continue;
1182 } else
1183 nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf1[i], 1, 0);
1184 }
1186 nResult = nCRCChkSum;
1187 }
1188 }
1190 end:
1192 return nResult;
1193 }
1195 static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock)
1196 {
1197 int nResult = 0;
1198 unsigned int nCommand = 0;
1199 unsigned char nBook;
1200 unsigned char nPage;
1201 unsigned char nOffset;
1202 unsigned char nData;
1203 unsigned int nLength;
1204 unsigned int nSleep;
1205 unsigned char nCRCChkSum = 0;
1206 unsigned int nValue1;
1207 int nRetry = 6;
1208 unsigned char *pData = pBlock->mpData;
1210 dev_dbg(pTAS2557->dev, "TAS2557 load block: Type = %d, commands = %d\n",
1211 pBlock->mnType, pBlock->mnCommands);
1212 start:
1213 if (pBlock->mbPChkSumPresent) {
1214 nResult = pTAS2557->write(pTAS2557, TAS2557_CRC_RESET_REG, 1);
1215 if (nResult < 0)
1216 goto end;
1217 }
1219 if (pBlock->mbYChkSumPresent)
1220 nCRCChkSum = 0;
1222 nCommand = 0;
1224 while (nCommand < pBlock->mnCommands) {
1225 pData = pBlock->mpData + nCommand * 4;
1227 nBook = pData[0];
1228 nPage = pData[1];
1229 nOffset = pData[2];
1230 nData = pData[3];
1232 nCommand++;
1234 if (nOffset <= 0x7F) {
1235 nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), nData);
1236 if (nResult < 0)
1237 goto end;
1238 if (pBlock->mbYChkSumPresent) {
1239 nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, nData);
1240 if (nResult < 0)
1241 goto check;
1242 nCRCChkSum += (unsigned char)nResult;
1243 }
1244 } else if (nOffset == 0x81) {
1245 nSleep = (nBook << 8) + nPage;
1246 msleep(nSleep);
1247 } else if (nOffset == 0x85) {
1248 pData += 4;
1249 nLength = (nBook << 8) + nPage;
1250 nBook = pData[0];
1251 nPage = pData[1];
1252 nOffset = pData[2];
1253 if (nLength > 1) {
1254 nResult = pTAS2557->bulk_write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData + 3, nLength);
1255 if (nResult < 0)
1256 goto end;
1257 if (pBlock->mbYChkSumPresent) {
1258 nResult = doMultiRegCheckSum(pTAS2557, nBook, nPage, nOffset, nLength);
1259 if (nResult < 0)
1260 goto check;
1261 nCRCChkSum += (unsigned char)nResult;
1262 }
1263 } else {
1264 nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData[3]);
1265 if (nResult < 0)
1266 goto end;
1267 if (pBlock->mbYChkSumPresent) {
1268 nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, pData[3]);
1269 if (nResult < 0)
1270 goto check;
1271 nCRCChkSum += (unsigned char)nResult;
1272 }
1273 }
1275 nCommand++;
1277 if (nLength >= 2)
1278 nCommand += ((nLength - 2) / 4) + 1;
1279 }
1280 }
1281 if (pBlock->mbPChkSumPresent) {
1282 nResult = pTAS2557->read(pTAS2557, TAS2557_CRC_CHECKSUM_REG, &nValue1);
1283 if (nResult < 0)
1284 goto end;
1285 if ((nValue1&0xff) != pBlock->mnPChkSum) {
1286 dev_err(pTAS2557->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
1287 pBlock->mnPChkSum, (nValue1&0xff));
1288 nResult = -EAGAIN;
1289 goto check;
1290 }
1292 nResult = 0;
1293 dev_dbg(pTAS2557->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
1294 }
1296 if (pBlock->mbYChkSumPresent) {
1297 if (nCRCChkSum != pBlock->mnYChkSum) {
1298 dev_err(pTAS2557->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
1299 pBlock->mnYChkSum, nCRCChkSum);
1300 nResult = -EAGAIN;
1301 goto check;
1302 }
1303 nResult = 0;
1304 dev_dbg(pTAS2557->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
1305 }
1307 check:
1308 if (nResult == -EAGAIN) {
1309 nRetry--;
1310 if (nRetry > 0)
1311 goto start;
1312 }
1314 end:
1315 if (nResult < 0) {
1316 dev_err(pTAS2557->dev, "Block (%d) load error\n",
1317 pBlock->mnType);
1318 }
1319 return nResult;
1320 }
1322 static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData, unsigned int nType)
1323 {
1324 int nResult = 0;
1325 unsigned int nBlock;
1326 struct TBlock *pBlock;
1328 dev_dbg(pTAS2557->dev,
1329 "TAS2557 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
1331 for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
1332 pBlock = &(pData->mpBlocks[nBlock]);
1333 if (pBlock->mnType == nType) {
1334 nResult = tas2557_load_block(pTAS2557, pBlock);
1335 if (nResult < 0)
1336 break;
1337 }
1338 }
1340 return nResult;
1341 }
1343 static int tas2557_load_configuration(struct tas2557_priv *pTAS2557,
1344 unsigned int nConfiguration, bool bLoadSame)
1345 {
1346 int nResult = 0;
1347 struct TConfiguration *pCurrentConfiguration = NULL;
1348 struct TConfiguration *pNewConfiguration = NULL;
1350 dev_dbg(pTAS2557->dev, "tas2557_load_configuration: %d\n", nConfiguration);
1352 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1353 (!pTAS2557->mpFirmware->mpConfigurations)) {
1354 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1355 nResult = 0;
1356 goto end;
1357 }
1359 if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
1360 dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
1361 nConfiguration);
1362 nResult = 0;
1363 goto end;
1364 }
1366 if ((nConfiguration == pTAS2557->mnCurrentConfiguration) && (!bLoadSame)) {
1367 dev_info(pTAS2557->dev, "Configuration %d is already loaded\n",
1368 nConfiguration);
1369 nResult = 0;
1370 goto end;
1371 }
1373 pCurrentConfiguration =
1374 &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
1375 pNewConfiguration =
1376 &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
1377 if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
1378 dev_err(pTAS2557->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
1379 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
1380 nResult = 0;
1381 goto end;
1382 }
1384 if (pNewConfiguration->mnPLL >= pTAS2557->mpFirmware->mnPLLs) {
1385 dev_err(pTAS2557->dev, "Configuration %d, %s doesn't have a valid PLL index %d\n",
1386 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
1387 nResult = 0;
1388 goto end;
1389 }
1391 if (pTAS2557->mbPowerUp) {
1392 nResult = tas2557_load_coefficient(pTAS2557, pTAS2557->mnCurrentConfiguration, nConfiguration, true);
1393 pTAS2557->mbLoadConfigurationPrePowerUp = false;
1394 } else {
1395 dev_dbg(pTAS2557->dev,
1396 "TAS2557 was powered down, will load coefficient when power up\n");
1397 pTAS2557->mbLoadConfigurationPrePowerUp = true;
1398 pTAS2557->mnNewConfiguration = nConfiguration;
1399 }
1401 end:
1403 if (nResult < 0)
1404 failsafe(pTAS2557);
1406 return nResult;
1407 }
1409 int tas2557_set_config(struct tas2557_priv *pTAS2557, int config)
1410 {
1411 struct TConfiguration *pConfiguration;
1412 struct TProgram *pProgram;
1413 unsigned int nProgram = pTAS2557->mnCurrentProgram;
1414 unsigned int nConfiguration = config;
1415 int nResult = 0;
1417 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1418 (!pTAS2557->mpFirmware->mpConfigurations)) {
1419 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1420 nResult = -EINVAL;
1421 goto end;
1422 }
1424 if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
1425 dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
1426 nConfiguration);
1427 nResult = -EINVAL;
1428 goto end;
1429 }
1431 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
1432 pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
1434 if (nProgram != pConfiguration->mnProgram) {
1435 dev_err(pTAS2557->dev,
1436 "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
1437 nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
1438 nProgram, pProgram->mpName);
1439 nResult = -EINVAL;
1440 goto end;
1441 }
1443 nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
1445 end:
1447 return nResult;
1448 }
1450 void tas2557_clear_firmware(struct TFirmware *pFirmware)
1451 {
1452 unsigned int n, nn;
1454 if (!pFirmware)
1455 return;
1457 kfree(pFirmware->mpDescription);
1459 if (pFirmware->mpPLLs != NULL) {
1460 for (n = 0; n < pFirmware->mnPLLs; n++) {
1461 kfree(pFirmware->mpPLLs[n].mpDescription);
1462 kfree(pFirmware->mpPLLs[n].mBlock.mpData);
1463 }
1464 kfree(pFirmware->mpPLLs);
1465 }
1467 if (pFirmware->mpPrograms != NULL) {
1468 for (n = 0; n < pFirmware->mnPrograms; n++) {
1469 kfree(pFirmware->mpPrograms[n].mpDescription);
1470 kfree(pFirmware->mpPrograms[n].mData.mpDescription);
1471 for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
1472 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
1473 kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
1474 }
1475 kfree(pFirmware->mpPrograms);
1476 }
1478 if (pFirmware->mpConfigurations != NULL) {
1479 for (n = 0; n < pFirmware->mnConfigurations; n++) {
1480 kfree(pFirmware->mpConfigurations[n].mpDescription);
1481 kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
1482 for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
1483 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
1484 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
1485 }
1486 kfree(pFirmware->mpConfigurations);
1487 }
1489 if (pFirmware->mpCalibrations != NULL) {
1490 for (n = 0; n < pFirmware->mnCalibrations; n++) {
1491 kfree(pFirmware->mpCalibrations[n].mpDescription);
1492 kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
1493 for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
1494 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
1495 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
1496 }
1497 kfree(pFirmware->mpCalibrations);
1498 }
1500 memset(pFirmware, 0x00, sizeof(struct TFirmware));
1501 }
1503 static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, char *pFileName)
1504 {
1505 int nResult = 0;
1506 /*
1507 * int nFile;
1508 * mm_segment_t fs;
1509 * unsigned char pBuffer[1000];
1510 * int nSize = 0;
1511 *
1512 * dev_dbg(pTAS2557->dev, "%s:\n", __func__);
1513 *
1514 * fs = get_fs();
1515 * set_fs(KERNEL_DS);
1516 * nFile = sys_open(pFileName, O_RDONLY, 0);
1517 *
1518 * dev_info(pTAS2557->dev, "TAS2557 calibration file = %s, handle = %d\n",
1519 * pFileName, nFile);
1520 *
1521 * if (nFile >= 0) {
1522 * nSize = sys_read(nFile, pBuffer, 1000);
1523 * sys_close(nFile);
1524 * } else {
1525 * dev_err(pTAS2557->dev, "TAS2557 cannot open calibration file: %s\n",
1526 * pFileName);
1527 * }
1528 *
1529 * set_fs(fs);
1530 *
1531 * if (!nSize)
1532 * goto end;
1533 *
1534 * tas2557_clear_firmware(pTAS2557->mpCalFirmware);
1535 * dev_info(pTAS2557->dev, "TAS2557 calibration file size = %d\n", nSize);
1536 * nResult = fw_parse(pTAS2557, pTAS2557->mpCalFirmware, pBuffer, nSize);
1537 *
1538 * if (nResult)
1539 * dev_err(pTAS2557->dev, "TAS2557 calibration file is corrupt\n");
1540 * else
1541 * dev_info(pTAS2557->dev, "TAS2557 calibration: %d calibrations\n",
1542 * pTAS2557->mpCalFirmware->mnCalibrations);
1543 *
1544 *end:
1545 **/
1546 return nResult;
1547 }
1549 void tas2557_fw_ready(const struct firmware *pFW, void *pContext)
1550 {
1551 struct tas2557_priv *pTAS2557 = (struct tas2557_priv *) pContext;
1552 int nResult;
1553 unsigned int nProgram = 0;
1554 unsigned int nSampleRate = 0;
1556 dev_info(pTAS2557->dev, "%s:\n", __func__);
1558 if (unlikely(!pFW) || unlikely(!pFW->data)) {
1559 dev_err(pTAS2557->dev, "%s firmware is not loaded.\n",
1560 TAS2557_FW_NAME);
1561 goto end;
1562 }
1564 if (pTAS2557->mpFirmware->mpConfigurations) {
1565 nProgram = pTAS2557->mnCurrentProgram;
1566 nSampleRate = pTAS2557->mnCurrentSampleRate;
1567 dev_dbg(pTAS2557->dev, "clear current firmware\n");
1568 tas2557_clear_firmware(pTAS2557->mpFirmware);
1569 }
1571 nResult = fw_parse(pTAS2557, pTAS2557->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
1572 release_firmware(pFW);
1573 if (nResult < 0) {
1574 dev_err(pTAS2557->dev, "firmware is corrupt\n");
1575 goto end;
1576 }
1578 if (!pTAS2557->mpFirmware->mnPrograms) {
1579 dev_err(pTAS2557->dev, "firmware contains no programs\n");
1580 nResult = -EINVAL;
1581 goto end;
1582 }
1584 if (!pTAS2557->mpFirmware->mnConfigurations) {
1585 dev_err(pTAS2557->dev, "firmware contains no configurations\n");
1586 nResult = -EINVAL;
1587 goto end;
1588 }
1590 if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
1591 dev_info(pTAS2557->dev,
1592 "no previous program, set to default\n");
1593 nProgram = 0;
1594 }
1596 pTAS2557->mnCurrentSampleRate = nSampleRate;
1598 nResult = tas2557_set_program(pTAS2557, nProgram, -1);
1600 end:
1601 return;
1602 }
1604 int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, int nConfig)
1605 {
1606 struct TProgram *pProgram;
1607 unsigned int nConfiguration = 0;
1608 unsigned int nSampleRate = 0;
1609 unsigned char nGain;
1610 bool bFound = false;
1611 int nResult = 0;
1613 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1614 (!pTAS2557->mpFirmware->mpConfigurations)) {
1615 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1616 nResult = 0;
1617 goto end;
1618 }
1620 if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
1621 dev_err(pTAS2557->dev, "TAS2557: Program %d doesn't exist\n",
1622 nProgram);
1623 nResult = 0;
1624 goto end;
1625 }
1627 if (nConfig < 0) {
1628 nConfiguration = 0;
1629 nSampleRate = pTAS2557->mnCurrentSampleRate;
1630 while (!bFound && (nConfiguration < pTAS2557->mpFirmware->mnConfigurations)) {
1631 if (pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
1632 if (nSampleRate == 0) {
1633 bFound = true;
1634 dev_info(pTAS2557->dev, "find default configuration %d\n", nConfiguration);
1635 } else if (nSampleRate == pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
1636 bFound = true;
1637 dev_info(pTAS2557->dev, "find matching configuration %d\n", nConfiguration);
1638 } else {
1639 nConfiguration++;
1640 }
1641 } else {
1642 nConfiguration++;
1643 }
1644 }
1645 if (!bFound) {
1646 dev_err(pTAS2557->dev,
1647 "Program %d, no valid configuration found for sample rate %d, ignore\n",
1648 nProgram, nSampleRate);
1649 nResult = 0;
1650 goto end;
1651 }
1652 } else {
1653 if (pTAS2557->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
1654 dev_err(pTAS2557->dev, "%s, configuration program doesn't match\n", __func__);
1655 nResult = 0;
1656 goto end;
1657 }
1658 nConfiguration = nConfig;
1659 }
1661 pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
1662 if (pTAS2557->mbPowerUp) {
1663 dev_info(pTAS2557->dev,
1664 "device powered up, power down to load program %d (%s)\n",
1665 nProgram, pProgram->mpName);
1666 if (hrtimer_active(&pTAS2557->mtimer))
1667 hrtimer_cancel(&pTAS2557->mtimer);
1669 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
1670 pTAS2557->enableIRQ(pTAS2557, false);
1672 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_mute_DSP_down_data);
1673 if (nResult < 0)
1674 goto end;
1675 }
1677 pTAS2557->hw_reset(pTAS2557);
1678 nResult = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
1679 if (nResult < 0)
1680 goto end;
1681 msleep(1);
1682 nResult = tas2557_load_default(pTAS2557);
1683 if (nResult < 0)
1684 goto end;
1686 dev_info(pTAS2557->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
1687 nResult = tas2557_load_data(pTAS2557, &(pProgram->mData), TAS2557_BLOCK_PGM_DEV_A);
1688 if (nResult < 0)
1689 goto end;
1690 pTAS2557->mnCurrentProgram = nProgram;
1692 nResult = tas2557_get_DAC_gain(pTAS2557, &nGain);
1693 if (nResult < 0)
1694 goto end;
1695 pTAS2557->mnDevGain = nGain;
1696 pTAS2557->mnDevCurrentGain = nGain;
1698 nResult = tas2557_load_coefficient(pTAS2557, -1, nConfiguration, false);
1699 if (nResult < 0)
1700 goto end;
1702 if (pTAS2557->mbPowerUp) {
1703 pTAS2557->clearIRQ(pTAS2557);
1704 dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
1705 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
1706 if (nResult < 0)
1707 goto end;
1708 dev_dbg(pTAS2557->dev,
1709 "device powered up, load unmute\n");
1710 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
1711 if (nResult < 0)
1712 goto end;
1714 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1715 pTAS2557->enableIRQ(pTAS2557, true);
1716 if (!hrtimer_active(&pTAS2557->mtimer)) {
1717 pTAS2557->mnDieTvReadCounter = 0;
1718 hrtimer_start(&pTAS2557->mtimer,
1719 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1720 }
1721 }
1722 }
1724 end:
1726 if (nResult < 0)
1727 failsafe(pTAS2557);
1729 return nResult;
1730 }
1732 int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration)
1733 {
1734 struct TCalibration *pCalibration = NULL;
1735 struct TProgram *pProgram;
1736 int nResult = 0;
1738 if ((!pTAS2557->mpFirmware->mpPrograms)
1739 || (!pTAS2557->mpFirmware->mpConfigurations)) {
1740 dev_err(pTAS2557->dev, "Firmware not loaded\n\r");
1741 nResult = 0;
1742 goto end;
1743 }
1745 if (nCalibration == 0x00FF) {
1746 dev_info(pTAS2557->dev, "load new calibration file %s\n", TAS2557_CAL_NAME);
1747 nResult = tas2557_load_calibration(pTAS2557, TAS2557_CAL_NAME);
1748 if (nResult < 0)
1749 goto end;
1750 nCalibration = 0;
1751 }
1753 if (nCalibration >= pTAS2557->mpCalFirmware->mnCalibrations) {
1754 dev_err(pTAS2557->dev,
1755 "Calibration %d doesn't exist\n", nCalibration);
1756 nResult = 0;
1757 goto end;
1758 }
1760 pTAS2557->mnCurrentCalibration = nCalibration;
1761 pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[nCalibration]);
1762 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
1764 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1765 dev_dbg(pTAS2557->dev, "Enable: load calibration\n");
1766 nResult = tas2557_load_data(pTAS2557, &(pCalibration->mData), TAS2557_BLOCK_CFG_COEFF_DEV_A);
1767 if (nResult < 0)
1768 goto end;
1769 }
1771 end:
1772 if (nResult < 0) {
1773 tas2557_clear_firmware(pTAS2557->mpCalFirmware);
1774 nResult = tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, pTAS2557->mnCurrentConfiguration);
1775 }
1777 return nResult;
1778 }
1780 int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557)
1781 {
1782 struct device_node *np = dev->of_node;
1783 int rc = 0, ret = 0;
1784 unsigned int value;
1786 pTAS2557->mnResetGPIO = of_get_named_gpio(np, "ti,cdc-reset-gpio", 0);
1787 if (pTAS2557->mnResetGPIO < 0) {
1788 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
1789 "ti,cdc-reset-gpio", np->full_name,
1790 pTAS2557->mnResetGPIO);
1791 ret = -EINVAL;
1792 } else
1793 dev_dbg(pTAS2557->dev, "ti,cdc-reset-gpio=%d\n", pTAS2557->mnResetGPIO);
1795 if (ret >= 0) {
1796 pTAS2557->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0);
1797 if (pTAS2557->mnGpioINT < 0) {
1798 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
1799 "ti,irq-gpio", np->full_name,
1800 pTAS2557->mnGpioINT);
1801 ret = -EINVAL;
1802 } else
1803 dev_dbg(pTAS2557->dev, "ti,irq-gpio=%d\n", pTAS2557->mnGpioINT);
1804 }
1806 if (ret >= 0) {
1807 rc = of_property_read_u32(np, "ti,i2s-bits", &value);
1808 if (rc) {
1809 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
1810 "ti,i2s-bits", np->full_name, rc);
1811 ret = -EINVAL;
1812 } else {
1813 pTAS2557->mnI2SBits = value;
1814 dev_dbg(pTAS2557->dev, "ti,i2s-bits=%d\n", pTAS2557->mnI2SBits);
1815 }
1816 }
1818 return ret;
1819 }
1821 MODULE_AUTHOR("Texas Instruments Inc.");
1822 MODULE_DESCRIPTION("TAS2557 common functions for Android Linux");
1823 MODULE_LICENSE("GPL v2");