24495e17b11d27d86312c4641a5fda5bd89338e5
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_CRCCHK 0x00000200
45 #define PPC_DRIVER_CONFDEV 0x00000300
46 #define PPC_DRIVER_MTPLLSRC 0x00000400
47 #define PPC_DRIVER_CFGDEV_NONCRC 0x00000101
49 #define TAS2557_CAL_NAME "/data/tas2557_cal.bin"
52 static int tas2557_load_calibration(struct tas2557_priv *pTAS2557,
53 char *pFileName);
54 static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData,
55 unsigned int nType);
56 static void tas2557_clear_firmware(struct TFirmware *pFirmware);
57 static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock);
58 static int tas2557_load_configuration(struct tas2557_priv *pTAS2557,
59 unsigned int nConfiguration, bool bLoadSame);
61 #define TAS2557_UDELAY 0xFFFFFFFE
62 #define TAS2557_MDELAY 0xFFFFFFFD
64 #define TAS2557_BLOCK_PLL 0x00
65 #define TAS2557_BLOCK_PGM_ALL 0x0d
66 #define TAS2557_BLOCK_PGM_DEV_A 0x01
67 #define TAS2557_BLOCK_PGM_DEV_B 0x08
68 #define TAS2557_BLOCK_CFG_COEFF_DEV_A 0x03
69 #define TAS2557_BLOCK_CFG_COEFF_DEV_B 0x0a
70 #define TAS2557_BLOCK_CFG_PRE_DEV_A 0x04
71 #define TAS2557_BLOCK_CFG_PRE_DEV_B 0x0b
72 #define TAS2557_BLOCK_CFG_POST 0x05
73 #define TAS2557_BLOCK_CFG_POST_POWER 0x06
75 static unsigned int p_tas2557_default_data[] = {
76 TAS2557_SAR_ADC2_REG, 0x05, /* enable SAR ADC */
77 TAS2557_CLK_ERR_CTRL2, 0x21, /*clk1:clock hysteresis, 0.34ms; clock halt, 22ms*/
78 TAS2557_CLK_ERR_CTRL3, 0x21, /*clk2: rampDown 15dB/us, clock hysteresis, 10.66us; clock halt, 22ms */
79 TAS2557_SAFE_GUARD_REG, TAS2557_SAFE_GUARD_PATTERN, /* safe guard */
80 0xFFFFFFFF, 0xFFFFFFFF
81 };
83 static unsigned int p_tas2557_irq_config[] = {
84 TAS2557_CLK_HALT_REG, 0x71, /* enable clk halt detect2 interrupt */
85 TAS2557_INT_GEN1_REG, 0x11, /* enable spk OC and OV */
86 TAS2557_INT_GEN2_REG, 0x11, /* enable clk err1 and die OT */
87 TAS2557_INT_GEN3_REG, 0x11, /* enable clk err2 and brownout */
88 TAS2557_INT_GEN4_REG, 0x01, /* disable SAR, enable clk halt */
89 TAS2557_GPIO4_PIN_REG, 0x07, /* set GPIO4 as int1, default */
90 TAS2557_INT_MODE_REG, 0x80, /* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */
91 0xFFFFFFFF, 0xFFFFFFFF
92 };
94 static unsigned int p_tas2557_startup_data[] = {
95 TAS2557_GPI_PIN_REG, 0x15, /* enable DIN, MCLK, CCI */
96 TAS2557_GPIO1_PIN_REG, 0x01, /* enable BCLK */
97 TAS2557_GPIO2_PIN_REG, 0x01, /* enable WCLK */
98 TAS2557_POWER_CTRL2_REG, 0xA0, /* Class-D, Boost power up */
99 TAS2557_POWER_CTRL2_REG, 0xA3, /* Class-D, Boost, IV sense power up */
100 TAS2557_POWER_CTRL1_REG, 0xF8, /* PLL, DSP, clock dividers power up */
101 TAS2557_UDELAY, 2000, /* delay */
102 TAS2557_CLK_ERR_CTRL, 0x2b, /* enable clock error detection */
103 0xFFFFFFFF, 0xFFFFFFFF
104 };
106 static unsigned int p_tas2557_unmute_data[] = {
107 TAS2557_MUTE_REG, 0x00, /* unmute */
108 TAS2557_SOFT_MUTE_REG, 0x00, /* soft unmute */
109 0xFFFFFFFF, 0xFFFFFFFF
110 };
112 static unsigned int p_tas2557_shutdown_data[] = {
113 TAS2557_CLK_ERR_CTRL, 0x00, /* disable clock error detection */
114 TAS2557_SOFT_MUTE_REG, 0x01, /* soft mute */
115 TAS2557_UDELAY, 10000, /* delay 10ms */
116 TAS2557_MUTE_REG, 0x03, /* mute */
117 TAS2557_POWER_CTRL1_REG, 0x60, /* DSP power down */
118 TAS2557_UDELAY, 2000, /* delay 2ms */
119 TAS2557_POWER_CTRL2_REG, 0x00, /* Class-D, Boost power down */
120 TAS2557_POWER_CTRL1_REG, 0x00, /* all power down */
121 TAS2557_GPIO1_PIN_REG, 0x00, /* disable BCLK */
122 TAS2557_GPIO2_PIN_REG, 0x00, /* disable WCLK */
123 TAS2557_GPI_PIN_REG, 0x00, /* disable DIN, MCLK, CCI */
124 0xFFFFFFFF, 0xFFFFFFFF
125 };
127 static int tas2557_dev_load_data(struct tas2557_priv *pTAS2557,
128 unsigned int *pData)
129 {
130 int ret = 0;
131 unsigned int n = 0;
132 unsigned int nRegister;
133 unsigned int nData;
135 do {
136 nRegister = pData[n * 2];
137 nData = pData[n * 2 + 1];
138 if (nRegister == TAS2557_UDELAY)
139 udelay(nData);
140 else if (nRegister != 0xFFFFFFFF) {
141 ret = pTAS2557->write(pTAS2557, nRegister, nData);
142 if (ret < 0)
143 break;
144 }
145 n++;
146 } while (nRegister != 0xFFFFFFFF);
147 return ret;
148 }
150 int tas2557_configIRQ(struct tas2557_priv *pTAS2557)
151 {
152 return tas2557_dev_load_data(pTAS2557, p_tas2557_irq_config);
153 }
155 int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate)
156 {
157 int ret = 0, n = -1;
159 dev_dbg(pTAS2557->dev, "tas2557_set_bit_rate: nBitRate = %d\n", nBitRate);
161 switch (nBitRate) {
162 case 16:
163 n = 0;
164 break;
165 case 20:
166 n = 1;
167 break;
168 case 24:
169 n = 2;
170 break;
171 case 32:
172 n = 3;
173 break;
174 }
176 if (n >= 0)
177 ret = pTAS2557->update_bits(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, 0x18, n<<3);
178 return ret;
179 }
181 int tas2557_get_bit_rate(struct tas2557_priv *pTAS2557, unsigned char *pBitRate)
182 {
183 int ret = 0;
184 unsigned int nValue = 0;
185 unsigned char bitRate;
187 ret = pTAS2557->read(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, &nValue);
188 if (ret >= 0) {
189 bitRate = (nValue&0x18)>>3;
190 if (bitRate == 0)
191 bitRate = 16;
192 else if (bitRate == 1)
193 bitRate = 20;
194 else if (bitRate == 2)
195 bitRate = 24;
196 else if (bitRate == 3)
197 bitRate = 32;
198 *pBitRate = bitRate;
199 }
201 return ret;
202 }
204 int tas2557_get_DAC_gain(struct tas2557_priv *pTAS2557, unsigned char *pnGain)
205 {
206 int ret = 0;
207 unsigned int nValue = 0;
209 ret = pTAS2557->read(pTAS2557, TAS2557_SPK_CTRL_REG, &nValue);
210 if (ret >= 0)
211 *pnGain = ((nValue&TAS2557_DAC_GAIN_MASK)>>TAS2557_DAC_GAIN_SHIFT);
213 return ret;
214 }
216 int tas2557_set_DAC_gain(struct tas2557_priv *pTAS2557, unsigned int nGain)
217 {
218 int ret = 0;
220 ret = pTAS2557->update_bits(pTAS2557, TAS2557_SPK_CTRL_REG, TAS2557_DAC_GAIN_MASK,
221 (nGain<<TAS2557_DAC_GAIN_SHIFT));
222 return ret;
223 }
225 /*
226 * die temperature calculation:
227 * DieTemp = readout / 2^23
228 */
229 int tas2557_get_die_temperature(struct tas2557_priv *pTAS2557, int *pTemperature)
230 {
231 int nResult = 0;
232 unsigned char nBuf[4];
233 int temp;
235 if (!pTAS2557->mpFirmware->mnConfigurations) {
236 dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
237 goto end;
238 }
240 if (!pTAS2557->mbPowerUp) {
241 dev_err(pTAS2557->dev, "%s, device not powered on\n", __func__);
242 goto end;
243 }
245 nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_DIE_TEMP_REG, nBuf, 4);
246 if (nResult >= 0) {
247 temp = ((int)nBuf[0] << 24) | ((int)nBuf[1] << 16) | ((int)nBuf[2] << 8) | nBuf[3];
248 *pTemperature = temp;
249 }
251 end:
253 return nResult;
254 }
256 int tas2557_load_platdata(struct tas2557_priv *pTAS2557)
257 {
258 int nResult = 0;
260 if (gpio_is_valid(pTAS2557->mnGpioINT)) {
261 nResult = tas2557_configIRQ(pTAS2557);
262 if (nResult < 0)
263 goto end;
264 }
266 nResult = tas2557_set_bit_rate(pTAS2557, pTAS2557->mnI2SBits);
268 end:
270 return nResult;
271 }
273 int tas2557_load_default(struct tas2557_priv *pTAS2557)
274 {
275 int nResult = 0;
277 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_default_data);
278 if (nResult < 0)
279 goto end;
281 nResult = tas2557_load_platdata(pTAS2557);
282 if (nResult < 0)
283 goto end;
285 /* enable DOUT tri-state for extra BCLKs */
286 nResult = pTAS2557->update_bits(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, 0x01, 0x01);
287 end:
289 return nResult;
290 }
292 static void failsafe(struct tas2557_priv *pTAS2557)
293 {
294 dev_err(pTAS2557->dev, "%s\n", __func__);
295 pTAS2557->mnErrCode |= ERROR_FAILSAFE;
296 if (hrtimer_active(&pTAS2557->mtimer))
297 hrtimer_cancel(&pTAS2557->mtimer);
298 pTAS2557->enableIRQ(pTAS2557, false, false);
299 tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
300 pTAS2557->mbPowerUp = false;
301 pTAS2557->hw_reset(pTAS2557);
302 pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
303 udelay(1000);
304 pTAS2557->write(pTAS2557, TAS2557_SPK_CTRL_REG, 0x04);
305 if (pTAS2557->mpFirmware != NULL)
306 tas2557_clear_firmware(pTAS2557->mpFirmware);
307 }
309 int tas2557_checkPLL(struct tas2557_priv *pTAS2557)
310 {
311 int nResult = 0;
312 /*
313 * TO DO
314 */
316 return nResult;
317 }
319 /*
320 * tas2557_load_coefficient
321 */
322 static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557,
323 int nPrevConfig, int nNewConfig, bool bPowerOn)
324 {
325 int nResult = 0;
326 struct TPLL *pPLL;
327 struct TProgram *pProgram;
328 struct TConfiguration *pPrevConfiguration;
329 struct TConfiguration *pNewConfiguration;
330 bool bRestorePower = false;
332 if (!pTAS2557->mpFirmware->mnConfigurations) {
333 dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
334 goto end;
335 }
337 if (nNewConfig >= pTAS2557->mpFirmware->mnConfigurations) {
338 dev_err(pTAS2557->dev, "%s, invalid configuration New=%d, total=%d\n",
339 __func__, nNewConfig, pTAS2557->mpFirmware->mnConfigurations);
340 goto end;
341 }
343 if (nPrevConfig < 0)
344 pPrevConfiguration = NULL;
345 else if (nPrevConfig == nNewConfig) {
346 dev_dbg(pTAS2557->dev, "%s, config [%d] already loaded\n",
347 __func__, nNewConfig);
348 goto end;
349 } else
350 pPrevConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nPrevConfig]);
352 pNewConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nNewConfig]);
353 pTAS2557->mnCurrentConfiguration = nNewConfig;
354 if (pPrevConfiguration) {
355 if (pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL) {
356 dev_dbg(pTAS2557->dev, "%s, PLL same\n", __func__);
357 goto prog_coefficient;
358 }
359 }
361 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
362 if (bPowerOn) {
363 dev_dbg(pTAS2557->dev, "%s, power down to load new PLL\n", __func__);
364 if (hrtimer_active(&pTAS2557->mtimer))
365 hrtimer_cancel(&pTAS2557->mtimer);
367 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
368 pTAS2557->enableIRQ(pTAS2557, false, false);
370 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
371 if (nResult < 0)
372 goto end;
373 bRestorePower = true;
374 }
376 /* load PLL */
377 pPLL = &(pTAS2557->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
378 dev_dbg(pTAS2557->dev, "load PLL: %s block for Configuration %s\n",
379 pPLL->mpName, pNewConfiguration->mpName);
380 nResult = tas2557_load_block(pTAS2557, &(pPLL->mBlock));
381 if (nResult < 0)
382 goto end;
383 pTAS2557->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
385 dev_dbg(pTAS2557->dev, "load configuration %s conefficient pre block\n",
386 pNewConfiguration->mpName);
387 nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), TAS2557_BLOCK_CFG_PRE_DEV_A);
388 if (nResult < 0)
389 goto end;
391 prog_coefficient:
392 dev_dbg(pTAS2557->dev, "load new configuration: %s, coeff block data\n",
393 pNewConfiguration->mpName);
394 nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData),
395 TAS2557_BLOCK_CFG_COEFF_DEV_A);
396 if (nResult < 0)
397 goto end;
399 if (pTAS2557->mpCalFirmware->mnCalibrations) {
400 nResult = tas2557_set_calibration(pTAS2557, pTAS2557->mnCurrentCalibration);
401 if (nResult < 0)
402 goto end;
403 }
405 if (bRestorePower) {
406 pTAS2557->clearIRQ(pTAS2557);
407 dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
408 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
409 if (nResult < 0)
410 goto end;
411 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
412 nResult = tas2557_checkPLL(pTAS2557);
413 if (nResult < 0) {
414 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
415 pTAS2557->mbPowerUp = false;
416 goto end;
417 }
418 }
419 dev_dbg(pTAS2557->dev,
420 "device powered up, load unmute\n");
421 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
422 if (nResult < 0)
423 goto end;
424 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
425 pTAS2557->enableIRQ(pTAS2557, true, true);
426 if (!hrtimer_active(&pTAS2557->mtimer)) {
427 pTAS2557->mnDieTvReadCounter = 0;
428 hrtimer_start(&pTAS2557->mtimer,
429 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
430 }
431 }
432 }
433 end:
435 return nResult;
436 }
438 int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable)
439 {
440 int nResult = 0;
441 unsigned int nValue;
442 struct TProgram *pProgram;
444 dev_dbg(pTAS2557->dev, "Enable: %d\n", bEnable);
446 if ((pTAS2557->mpFirmware->mnPrograms == 0)
447 || (pTAS2557->mpFirmware->mnConfigurations == 0)) {
448 dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
449 goto end;
450 }
451 /* check safe guard*/
452 nResult = pTAS2557->read(pTAS2557, TAS2557_SAFE_GUARD_REG, &nValue);
453 if (nResult < 0)
454 goto end;
455 if ((nValue&0xff) != TAS2557_SAFE_GUARD_PATTERN) {
456 dev_err(pTAS2557->dev, "ERROR safe guard failure!\n");
457 nResult = -EPIPE;
458 goto end;
459 }
461 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
462 if (bEnable) {
463 if (!pTAS2557->mbPowerUp) {
464 if (pTAS2557->mbLoadConfigurationPrePowerUp) {
465 dev_dbg(pTAS2557->dev, "load coefficient before power\n");
466 pTAS2557->mbLoadConfigurationPrePowerUp = false;
467 nResult = tas2557_load_coefficient(pTAS2557,
468 pTAS2557->mnCurrentConfiguration, pTAS2557->mnNewConfiguration, false);
469 if (nResult < 0)
470 goto end;
471 }
473 pTAS2557->clearIRQ(pTAS2557);
474 /* power on device */
475 dev_dbg(pTAS2557->dev, "Enable: load startup sequence\n");
476 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
477 if (nResult < 0)
478 goto end;
479 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
480 nResult = tas2557_checkPLL(pTAS2557);
481 if (nResult < 0) {
482 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
483 goto end;
484 }
485 }
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, 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, 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 (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
525 failsafe(pTAS2557);
526 }
528 return nResult;
529 }
531 int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate)
532 {
533 int nResult = 0;
534 struct TConfiguration *pConfiguration;
535 unsigned int nConfiguration;
537 dev_dbg(pTAS2557->dev, "tas2557_setup_clocks: nSamplingRate = %d [Hz]\n",
538 nSamplingRate);
540 if ((!pTAS2557->mpFirmware->mpPrograms) ||
541 (!pTAS2557->mpFirmware->mpConfigurations)) {
542 dev_err(pTAS2557->dev, "Firmware not loaded\n");
543 nResult = -EINVAL;
544 goto end;
545 }
547 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
548 if (pConfiguration->mnSamplingRate == nSamplingRate) {
549 dev_info(pTAS2557->dev, "Sampling rate for current configuration matches: %d\n",
550 nSamplingRate);
551 nResult = 0;
552 goto end;
553 }
555 for (nConfiguration = 0;
556 nConfiguration < pTAS2557->mpFirmware->mnConfigurations;
557 nConfiguration++) {
558 pConfiguration =
559 &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
560 if ((pConfiguration->mnSamplingRate == nSamplingRate)
561 && (pConfiguration->mnProgram == pTAS2557->mnCurrentProgram)) {
562 dev_info(pTAS2557->dev,
563 "Found configuration: %s, with compatible sampling rate %d\n",
564 pConfiguration->mpName, nSamplingRate);
565 nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
566 goto end;
567 }
568 }
570 dev_err(pTAS2557->dev, "Cannot find a configuration that supports sampling rate: %d\n",
571 nSamplingRate);
573 end:
575 return nResult;
576 }
578 static void fw_print_header(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware)
579 {
580 dev_info(pTAS2557->dev, "FW Size = %d", pFirmware->mnFWSize);
581 dev_info(pTAS2557->dev, "Checksum = 0x%04X", pFirmware->mnChecksum);
582 dev_info(pTAS2557->dev, "PPC Version = 0x%04X", pFirmware->mnPPCVersion);
583 dev_info(pTAS2557->dev, "FW Version = 0x%04X", pFirmware->mnFWVersion);
584 dev_info(pTAS2557->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
585 dev_info(pTAS2557->dev, "Timestamp = %d", pFirmware->mnTimeStamp);
586 dev_info(pTAS2557->dev, "DDC Name = %s", pFirmware->mpDDCName);
587 dev_info(pTAS2557->dev, "Description = %s", pFirmware->mpDescription);
588 }
590 inline unsigned int fw_convert_number(unsigned char *pData)
591 {
592 return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
593 }
595 static int fw_parse_header(struct tas2557_priv *pTAS2557,
596 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
597 {
598 unsigned char *pDataStart = pData;
599 unsigned int n;
600 unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
602 if (nSize < 104) {
603 dev_err(pTAS2557->dev, "Firmware: Header too short");
604 return -EINVAL;
605 }
607 if (memcmp(pData, pMagicNumber, 4)) {
608 dev_err(pTAS2557->dev, "Firmware: Magic number doesn't match");
609 return -EINVAL;
610 }
611 pData += 4;
613 pFirmware->mnFWSize = fw_convert_number(pData);
614 pData += 4;
616 pFirmware->mnChecksum = fw_convert_number(pData);
617 pData += 4;
619 pFirmware->mnPPCVersion = fw_convert_number(pData);
620 pData += 4;
622 pFirmware->mnFWVersion = fw_convert_number(pData);
623 pData += 4;
625 pFirmware->mnDriverVersion = fw_convert_number(pData);
626 pData += 4;
628 pFirmware->mnTimeStamp = fw_convert_number(pData);
629 pData += 4;
631 memcpy(pFirmware->mpDDCName, pData, 64);
632 pData += 64;
634 n = strlen(pData);
635 pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
636 pData += n + 1;
637 if ((pData - pDataStart) >= nSize) {
638 dev_err(pTAS2557->dev, "Firmware: Header too short after DDC description");
639 return -EINVAL;
640 }
642 pFirmware->mnDeviceFamily = fw_convert_number(pData);
643 pData += 4;
644 if (pFirmware->mnDeviceFamily != 0) {
645 dev_err(pTAS2557->dev,
646 "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
647 return -EINVAL;
648 }
650 pFirmware->mnDevice = fw_convert_number(pData);
651 pData += 4;
653 if (pFirmware->mnDevice != 2) {
654 dev_err(pTAS2557->dev,
655 "device %d, not TAS2557 Dual Mono", pFirmware->mnDevice);
656 return -EINVAL;
657 }
659 fw_print_header(pTAS2557, pFirmware);
660 return pData - pDataStart;
661 }
663 static int fw_parse_block_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
664 struct TBlock *pBlock, unsigned char *pData)
665 {
666 unsigned char *pDataStart = pData;
667 unsigned int n;
669 pBlock->mnType = fw_convert_number(pData);
670 pData += 4;
672 if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) {
673 pBlock->mbPChkSumPresent = pData[0];
674 pData++;
676 pBlock->mnPChkSum = pData[0];
677 pData++;
679 pBlock->mbYChkSumPresent = pData[0];
680 pData++;
682 pBlock->mnYChkSum = pData[0];
683 pData++;
684 } else {
685 pBlock->mbPChkSumPresent = 0;
686 pBlock->mbYChkSumPresent = 0;
687 }
689 pBlock->mnCommands = fw_convert_number(pData);
690 pData += 4;
692 n = pBlock->mnCommands * 4;
693 pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
694 pData += n;
695 return pData - pDataStart;
696 }
698 static int fw_parse_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
699 struct TData *pImageData, unsigned char *pData)
700 {
701 unsigned char *pDataStart = pData;
702 unsigned int nBlock;
703 unsigned int n;
705 memcpy(pImageData->mpName, pData, 64);
706 pData += 64;
708 n = strlen(pData);
709 pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
710 pData += n + 1;
712 pImageData->mnBlocks = (pData[0] << 8) + pData[1];
713 pData += 2;
715 pImageData->mpBlocks =
716 kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
718 for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
719 n = fw_parse_block_data(pTAS2557, pFirmware,
720 &(pImageData->mpBlocks[nBlock]), pData);
721 pData += n;
722 }
723 return pData - pDataStart;
724 }
726 static int fw_parse_pll_data(struct tas2557_priv *pTAS2557,
727 struct TFirmware *pFirmware, unsigned char *pData)
728 {
729 unsigned char *pDataStart = pData;
730 unsigned int n;
731 unsigned int nPLL;
732 struct TPLL *pPLL;
734 pFirmware->mnPLLs = (pData[0] << 8) + pData[1];
735 pData += 2;
737 if (pFirmware->mnPLLs == 0)
738 goto end;
740 pFirmware->mpPLLs = kmalloc_array(pFirmware->mnPLLs, sizeof(struct TPLL), GFP_KERNEL);
741 for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) {
742 pPLL = &(pFirmware->mpPLLs[nPLL]);
744 memcpy(pPLL->mpName, pData, 64);
745 pData += 64;
747 n = strlen(pData);
748 pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
749 pData += n + 1;
751 n = fw_parse_block_data(pTAS2557, pFirmware, &(pPLL->mBlock), pData);
752 pData += n;
753 }
755 end:
756 return pData - pDataStart;
757 }
759 static int fw_parse_program_data(struct tas2557_priv *pTAS2557,
760 struct TFirmware *pFirmware, unsigned char *pData)
761 {
762 unsigned char *pDataStart = pData;
763 unsigned int n;
764 unsigned int nProgram;
765 struct TProgram *pProgram;
767 pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
768 pData += 2;
770 if (pFirmware->mnPrograms == 0)
771 goto end;
773 pFirmware->mpPrograms =
774 kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
775 for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
776 pProgram = &(pFirmware->mpPrograms[nProgram]);
777 memcpy(pProgram->mpName, pData, 64);
778 pData += 64;
780 n = strlen(pData);
781 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
782 pData += n + 1;
784 pProgram->mnAppMode = pData[0];
785 pData++;
787 pProgram->mnBoost = (pData[0] << 8) + pData[1];
788 pData += 2;
790 n = fw_parse_data(pTAS2557, pFirmware, &(pProgram->mData), pData);
791 pData += n;
792 }
794 end:
796 return pData - pDataStart;
797 }
799 static int fw_parse_configuration_data(struct tas2557_priv *pTAS2557,
800 struct TFirmware *pFirmware, unsigned char *pData)
801 {
802 unsigned char *pDataStart = pData;
803 unsigned int n;
804 unsigned int nConfiguration;
805 struct TConfiguration *pConfiguration;
807 pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
808 pData += 2;
810 if (pFirmware->mnConfigurations == 0)
811 goto end;
813 pFirmware->mpConfigurations =
814 kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
815 GFP_KERNEL);
816 for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
817 nConfiguration++) {
818 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
819 memcpy(pConfiguration->mpName, pData, 64);
820 pData += 64;
822 n = strlen(pData);
823 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
824 pData += n + 1;
826 if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV)
827 || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC)
828 && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) {
829 pConfiguration->mnDevices = (pData[0] << 8) + pData[1];
830 pData += 2;
831 } else
832 pConfiguration->mnDevices = 1;
834 pConfiguration->mnProgram = pData[0];
835 pData++;
837 pConfiguration->mnPLL = pData[0];
838 pData++;
840 pConfiguration->mnSamplingRate = fw_convert_number(pData);
841 pData += 4;
843 if (pFirmware->mnDriverVersion >= PPC_DRIVER_MTPLLSRC) {
844 pConfiguration->mnPLLSrc = pData[0];
845 pData++;
847 pConfiguration->mnPLLSrcRate = fw_convert_number(pData);
848 pData += 4;
849 }
851 n = fw_parse_data(pTAS2557, pFirmware, &(pConfiguration->mData), pData);
852 pData += n;
853 }
855 end:
857 return pData - pDataStart;
858 }
860 int fw_parse_calibration_data(struct tas2557_priv *pTAS2557,
861 struct TFirmware *pFirmware, unsigned char *pData)
862 {
863 unsigned char *pDataStart = pData;
864 unsigned int n;
865 unsigned int nCalibration;
866 struct TCalibration *pCalibration;
868 pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
869 pData += 2;
871 if (pFirmware->mnCalibrations == 0)
872 goto end;
874 pFirmware->mpCalibrations =
875 kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
876 for (nCalibration = 0;
877 nCalibration < pFirmware->mnCalibrations;
878 nCalibration++) {
879 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
880 memcpy(pCalibration->mpName, pData, 64);
881 pData += 64;
883 n = strlen(pData);
884 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
885 pData += n + 1;
887 pCalibration->mnProgram = pData[0];
888 pData++;
890 pCalibration->mnConfiguration = pData[0];
891 pData++;
893 n = fw_parse_data(pTAS2557, pFirmware, &(pCalibration->mData), pData);
894 pData += n;
895 }
897 end:
899 return pData - pDataStart;
900 }
902 static int fw_parse(struct tas2557_priv *pTAS2557,
903 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
904 {
905 int nPosition = 0;
907 nPosition = fw_parse_header(pTAS2557, pFirmware, pData, nSize);
908 if (nPosition < 0) {
909 dev_err(pTAS2557->dev, "Firmware: Wrong Header");
910 return -EINVAL;
911 }
913 if (nPosition >= nSize) {
914 dev_err(pTAS2557->dev, "Firmware: Too short");
915 return -EINVAL;
916 }
918 pData += nPosition;
919 nSize -= nPosition;
920 nPosition = 0;
922 nPosition = fw_parse_pll_data(pTAS2557, pFirmware, pData);
924 pData += nPosition;
925 nSize -= nPosition;
926 nPosition = 0;
928 nPosition = fw_parse_program_data(pTAS2557, pFirmware, pData);
930 pData += nPosition;
931 nSize -= nPosition;
932 nPosition = 0;
934 nPosition = fw_parse_configuration_data(pTAS2557, pFirmware, pData);
936 pData += nPosition;
937 nSize -= nPosition;
938 nPosition = 0;
940 if (nSize > 64)
941 nPosition = fw_parse_calibration_data(pTAS2557, pFirmware, pData);
942 return 0;
943 }
946 static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
947 0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
948 0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
949 0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
950 0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
951 0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
952 0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
953 0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
954 0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
955 0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
956 0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
957 0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
958 0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
959 0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
960 0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
961 0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
962 0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
963 };
965 static int isInPageYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
966 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
967 {
968 int nResult = 0;
970 if (nBook == TAS2557_YRAM_BOOK1) {
971 if (nPage == TAS2557_YRAM1_PAGE) {
972 if (nReg >= TAS2557_YRAM1_START_REG) {
973 pCRCData->mnOffset = nReg;
974 pCRCData->mnLen = len;
975 nResult = 1;
976 } else if ((nReg + len) > TAS2557_YRAM1_START_REG) {
977 pCRCData->mnOffset = TAS2557_YRAM1_START_REG;
978 pCRCData->mnLen = len - (TAS2557_YRAM1_START_REG - nReg);
979 nResult = 1;
980 } else
981 nResult = 0;
982 } else if (nPage == TAS2557_YRAM3_PAGE) {
983 if (nReg > TAS2557_YRAM3_END_REG) {
984 nResult = 0;
985 } else if (nReg >= TAS2557_YRAM3_START_REG) {
986 if ((nReg + len) > TAS2557_YRAM3_END_REG) {
987 pCRCData->mnOffset = nReg;
988 pCRCData->mnLen = TAS2557_YRAM3_END_REG - nReg + 1;
989 nResult = 1;
990 } else {
991 pCRCData->mnOffset = nReg;
992 pCRCData->mnLen = len;
993 nResult = 1;
994 }
995 } else {
996 if ((nReg + (len - 1)) < TAS2557_YRAM3_START_REG)
997 nResult = 0;
998 else {
999 pCRCData->mnOffset = TAS2557_YRAM3_START_REG;
1000 pCRCData->mnLen = len - (TAS2557_YRAM3_START_REG - nReg);
1001 nResult = 1;
1002 }
1003 }
1004 }
1005 } else if (nBook == TAS2557_YRAM_BOOK2) {
1006 if (nPage == TAS2557_YRAM5_PAGE) {
1007 if (nReg > TAS2557_YRAM5_END_REG) {
1008 nResult = 0;
1009 } else if (nReg >= TAS2557_YRAM5_START_REG) {
1010 if ((nReg + len) > TAS2557_YRAM5_END_REG) {
1011 pCRCData->mnOffset = nReg;
1012 pCRCData->mnLen = TAS2557_YRAM5_END_REG - nReg + 1;
1013 nResult = 1;
1014 } else {
1015 pCRCData->mnOffset = nReg;
1016 pCRCData->mnLen = len;
1017 nResult = 1;
1018 }
1019 } else {
1020 if ((nReg + (len - 1)) < TAS2557_YRAM5_START_REG)
1021 nResult = 0;
1022 else {
1023 pCRCData->mnOffset = TAS2557_YRAM5_START_REG;
1024 pCRCData->mnLen = len - (TAS2557_YRAM5_START_REG - nReg);
1025 nResult = 1;
1026 }
1027 }
1028 }
1029 } else
1030 nResult = 0;
1032 return nResult;
1033 }
1035 static int isInBlockYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1036 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1037 {
1038 int nResult;
1040 if (nBook == TAS2557_YRAM_BOOK1) {
1041 if (nPage < TAS2557_YRAM2_START_PAGE)
1042 nResult = 0;
1043 else if (nPage <= TAS2557_YRAM2_END_PAGE) {
1044 if (nReg > TAS2557_YRAM2_END_REG)
1045 nResult = 0;
1046 else if (nReg >= TAS2557_YRAM2_START_REG) {
1047 pCRCData->mnOffset = nReg;
1048 pCRCData->mnLen = len;
1049 nResult = 1;
1050 } else {
1051 if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG)
1052 nResult = 0;
1053 else {
1054 pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
1055 pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
1056 nResult = 1;
1057 }
1058 }
1059 } else
1060 nResult = 0;
1061 } else if (nBook == TAS2557_YRAM_BOOK2) {
1062 if (nPage < TAS2557_YRAM4_START_PAGE)
1063 nResult = 0;
1064 else if (nPage <= TAS2557_YRAM4_END_PAGE) {
1065 if (nReg > TAS2557_YRAM2_END_REG)
1066 nResult = 0;
1067 else if (nReg >= TAS2557_YRAM2_START_REG) {
1068 pCRCData->mnOffset = nReg;
1069 pCRCData->mnLen = len;
1070 nResult = 1;
1071 } else {
1072 if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG)
1073 nResult = 0;
1074 else {
1075 pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
1076 pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
1077 nResult = 1;
1078 }
1079 }
1080 } else
1081 nResult = 0;
1082 } else
1083 nResult = 0;
1085 return nResult;
1086 }
1089 static int isYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1090 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1091 {
1092 int nResult;
1094 nResult = isInPageYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
1096 if (nResult == 0)
1097 nResult = isInBlockYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
1099 return nResult;
1100 }
1102 /*
1103 * crc8 - calculate a crc8 over the given input data.
1104 *
1105 * table: crc table used for calculation.
1106 * pdata: pointer to data buffer.
1107 * nbytes: number of bytes in data buffer.
1108 * crc: previous returned crc8 value.
1109 */
1110 static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
1111 {
1112 /* loop over the buffer data */
1113 while (nbytes-- > 0)
1114 crc = table[(crc ^ *pdata++) & 0xff];
1116 return crc;
1117 }
1119 static int doSingleRegCheckSum(struct tas2557_priv *pTAS2557,
1120 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
1121 {
1122 int nResult = 0;
1123 struct TYCRC sCRCData;
1124 unsigned int nData1 = 0;
1126 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1127 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1128 && (nReg >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1129 && (nReg <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
1130 /* DSP swap command, pass */
1131 nResult = 0;
1132 goto end;
1133 }
1135 nResult = isYRAM(pTAS2557, &sCRCData, nBook, nPage, nReg, 1);
1136 if (nResult == 1) {
1137 nResult = pTAS2557->read(pTAS2557, TAS2557_REG(nBook, nPage, nReg), &nData1);
1138 if (nResult < 0)
1139 goto end;
1141 if (nData1 != nValue) {
1142 dev_err(pTAS2557->dev, "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1143 __LINE__, nBook, nPage, nReg, nValue, nData1);
1144 nResult = -EAGAIN;
1145 goto end;
1146 }
1148 nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0);
1149 }
1151 end:
1153 return nResult;
1154 }
1156 static int doMultiRegCheckSum(struct tas2557_priv *pTAS2557,
1157 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
1158 {
1159 int nResult = 0, i;
1160 unsigned char nCRCChkSum = 0;
1161 unsigned char nBuf1[128];
1162 struct TYCRC TCRCData;
1164 if ((nReg + len-1) > 127) {
1165 nResult = -EINVAL;
1166 dev_err(pTAS2557->dev, "firmware error\n");
1167 goto end;
1168 }
1170 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1171 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1172 && (nReg == TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1173 && (len == 4)) {
1174 /* DSP swap command, pass */
1175 nResult = 0;
1176 goto end;
1177 }
1179 nResult = isYRAM(pTAS2557, &TCRCData, nBook, nPage, nReg, len);
1180 if (nResult == 1) {
1181 if (len == 1) {
1182 dev_err(pTAS2557->dev, "firmware error\n");
1183 nResult = -EINVAL;
1184 goto end;
1185 } else {
1186 nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
1187 if (nResult < 0)
1188 goto end;
1190 for (i = 0; i < TCRCData.mnLen; i++) {
1191 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1192 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1193 && ((i + TCRCData.mnOffset)
1194 >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1195 && ((i + TCRCData.mnOffset)
1196 <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
1197 /* DSP swap command, bypass */
1198 continue;
1199 } else
1200 nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf1[i], 1, 0);
1201 }
1203 nResult = nCRCChkSum;
1204 }
1205 }
1207 end:
1209 return nResult;
1210 }
1212 static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock)
1213 {
1214 int nResult = 0;
1215 unsigned int nCommand = 0;
1216 unsigned char nBook;
1217 unsigned char nPage;
1218 unsigned char nOffset;
1219 unsigned char nData;
1220 unsigned int nLength;
1221 unsigned int nSleep;
1222 unsigned char nCRCChkSum = 0;
1223 unsigned int nValue1;
1224 int nRetry = 6;
1225 unsigned char *pData = pBlock->mpData;
1227 dev_dbg(pTAS2557->dev, "TAS2557 load block: Type = %d, commands = %d\n",
1228 pBlock->mnType, pBlock->mnCommands);
1229 start:
1230 if (pBlock->mbPChkSumPresent) {
1231 nResult = pTAS2557->write(pTAS2557, TAS2557_CRC_RESET_REG, 1);
1232 if (nResult < 0)
1233 goto end;
1234 }
1236 if (pBlock->mbYChkSumPresent)
1237 nCRCChkSum = 0;
1239 nCommand = 0;
1241 while (nCommand < pBlock->mnCommands) {
1242 pData = pBlock->mpData + nCommand * 4;
1244 nBook = pData[0];
1245 nPage = pData[1];
1246 nOffset = pData[2];
1247 nData = pData[3];
1249 nCommand++;
1251 if (nOffset <= 0x7F) {
1252 nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), nData);
1253 if (nResult < 0)
1254 goto end;
1255 if (pBlock->mbYChkSumPresent) {
1256 nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, nData);
1257 if (nResult < 0)
1258 goto check;
1259 nCRCChkSum += (unsigned char)nResult;
1260 }
1261 } else if (nOffset == 0x81) {
1262 nSleep = (nBook << 8) + nPage;
1263 msleep(nSleep);
1264 } else if (nOffset == 0x85) {
1265 pData += 4;
1266 nLength = (nBook << 8) + nPage;
1267 nBook = pData[0];
1268 nPage = pData[1];
1269 nOffset = pData[2];
1270 if (nLength > 1) {
1271 nResult = pTAS2557->bulk_write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData + 3, nLength);
1272 if (nResult < 0)
1273 goto end;
1274 if (pBlock->mbYChkSumPresent) {
1275 nResult = doMultiRegCheckSum(pTAS2557, nBook, nPage, nOffset, nLength);
1276 if (nResult < 0)
1277 goto check;
1278 nCRCChkSum += (unsigned char)nResult;
1279 }
1280 } else {
1281 nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData[3]);
1282 if (nResult < 0)
1283 goto end;
1284 if (pBlock->mbYChkSumPresent) {
1285 nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, pData[3]);
1286 if (nResult < 0)
1287 goto check;
1288 nCRCChkSum += (unsigned char)nResult;
1289 }
1290 }
1292 nCommand++;
1294 if (nLength >= 2)
1295 nCommand += ((nLength - 2) / 4) + 1;
1296 }
1297 }
1298 if (pBlock->mbPChkSumPresent) {
1299 nResult = pTAS2557->read(pTAS2557, TAS2557_CRC_CHECKSUM_REG, &nValue1);
1300 if (nResult < 0)
1301 goto end;
1302 if ((nValue1&0xff) != pBlock->mnPChkSum) {
1303 dev_err(pTAS2557->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
1304 pBlock->mnPChkSum, (nValue1&0xff));
1305 nResult = -EAGAIN;
1306 pTAS2557->mnErrCode |= ERROR_PRAM_CRCCHK;
1307 goto check;
1308 }
1310 nResult = 0;
1311 pTAS2557->mnErrCode &= ~ERROR_PRAM_CRCCHK;
1312 dev_dbg(pTAS2557->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
1313 }
1315 if (pBlock->mbYChkSumPresent) {
1316 if (nCRCChkSum != pBlock->mnYChkSum) {
1317 dev_err(pTAS2557->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
1318 pBlock->mnYChkSum, nCRCChkSum);
1319 nResult = -EAGAIN;
1320 pTAS2557->mnErrCode |= ERROR_YRAM_CRCCHK;
1321 goto check;
1322 }
1323 pTAS2557->mnErrCode &= ~ERROR_YRAM_CRCCHK;
1324 nResult = 0;
1325 dev_dbg(pTAS2557->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
1326 }
1328 check:
1329 if (nResult == -EAGAIN) {
1330 nRetry--;
1331 if (nRetry > 0)
1332 goto start;
1333 }
1335 end:
1336 if (nResult < 0) {
1337 dev_err(pTAS2557->dev, "Block (%d) load error\n",
1338 pBlock->mnType);
1339 }
1340 return nResult;
1341 }
1343 static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData, unsigned int nType)
1344 {
1345 int nResult = 0;
1346 unsigned int nBlock;
1347 struct TBlock *pBlock;
1349 dev_dbg(pTAS2557->dev,
1350 "TAS2557 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
1352 for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
1353 pBlock = &(pData->mpBlocks[nBlock]);
1354 if (pBlock->mnType == nType) {
1355 nResult = tas2557_load_block(pTAS2557, pBlock);
1356 if (nResult < 0)
1357 break;
1358 }
1359 }
1361 return nResult;
1362 }
1364 static int tas2557_load_configuration(struct tas2557_priv *pTAS2557,
1365 unsigned int nConfiguration, bool bLoadSame)
1366 {
1367 int nResult = 0;
1368 struct TConfiguration *pCurrentConfiguration = NULL;
1369 struct TConfiguration *pNewConfiguration = NULL;
1371 dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, nConfiguration);
1373 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1374 (!pTAS2557->mpFirmware->mpConfigurations)) {
1375 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1376 nResult = 0;
1377 goto end;
1378 }
1380 if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
1381 dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
1382 nConfiguration);
1383 nResult = 0;
1384 goto end;
1385 }
1387 if ((!pTAS2557->mbLoadConfigurationPrePowerUp)
1388 && (nConfiguration == pTAS2557->mnCurrentConfiguration)
1389 && (!bLoadSame)) {
1390 dev_info(pTAS2557->dev, "Configuration %d is already loaded\n",
1391 nConfiguration);
1392 nResult = 0;
1393 goto end;
1394 }
1396 pCurrentConfiguration =
1397 &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
1398 pNewConfiguration =
1399 &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
1400 if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
1401 dev_err(pTAS2557->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
1402 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
1403 nResult = 0;
1404 goto end;
1405 }
1407 if (pNewConfiguration->mnPLL >= pTAS2557->mpFirmware->mnPLLs) {
1408 dev_err(pTAS2557->dev, "Configuration %d, %s doesn't have a valid PLL index %d\n",
1409 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
1410 nResult = 0;
1411 goto end;
1412 }
1414 if (pTAS2557->mbPowerUp) {
1415 pTAS2557->mbLoadConfigurationPrePowerUp = false;
1416 nResult = tas2557_load_coefficient(pTAS2557, pTAS2557->mnCurrentConfiguration, nConfiguration, true);
1417 } else {
1418 dev_dbg(pTAS2557->dev,
1419 "TAS2557 was powered down, will load coefficient when power up\n");
1420 pTAS2557->mbLoadConfigurationPrePowerUp = true;
1421 pTAS2557->mnNewConfiguration = nConfiguration;
1422 }
1424 end:
1426 if (nResult < 0) {
1427 if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
1428 failsafe(pTAS2557);
1429 }
1431 return nResult;
1432 }
1434 int tas2557_set_config(struct tas2557_priv *pTAS2557, int config)
1435 {
1436 struct TConfiguration *pConfiguration;
1437 struct TProgram *pProgram;
1438 unsigned int nProgram = pTAS2557->mnCurrentProgram;
1439 unsigned int nConfiguration = config;
1440 int nResult = 0;
1442 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1443 (!pTAS2557->mpFirmware->mpConfigurations)) {
1444 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1445 nResult = -EINVAL;
1446 goto end;
1447 }
1449 if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
1450 dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
1451 nConfiguration);
1452 nResult = -EINVAL;
1453 goto end;
1454 }
1456 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
1457 pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
1459 if (nProgram != pConfiguration->mnProgram) {
1460 dev_err(pTAS2557->dev,
1461 "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
1462 nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
1463 nProgram, pProgram->mpName);
1464 nResult = -EINVAL;
1465 goto end;
1466 }
1468 nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
1470 end:
1472 return nResult;
1473 }
1475 void tas2557_clear_firmware(struct TFirmware *pFirmware)
1476 {
1477 unsigned int n, nn;
1479 if (!pFirmware)
1480 return;
1482 kfree(pFirmware->mpDescription);
1484 if (pFirmware->mpPLLs != NULL) {
1485 for (n = 0; n < pFirmware->mnPLLs; n++) {
1486 kfree(pFirmware->mpPLLs[n].mpDescription);
1487 kfree(pFirmware->mpPLLs[n].mBlock.mpData);
1488 }
1489 kfree(pFirmware->mpPLLs);
1490 }
1492 if (pFirmware->mpPrograms != NULL) {
1493 for (n = 0; n < pFirmware->mnPrograms; n++) {
1494 kfree(pFirmware->mpPrograms[n].mpDescription);
1495 kfree(pFirmware->mpPrograms[n].mData.mpDescription);
1496 for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
1497 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
1498 kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
1499 }
1500 kfree(pFirmware->mpPrograms);
1501 }
1503 if (pFirmware->mpConfigurations != NULL) {
1504 for (n = 0; n < pFirmware->mnConfigurations; n++) {
1505 kfree(pFirmware->mpConfigurations[n].mpDescription);
1506 kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
1507 for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
1508 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
1509 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
1510 }
1511 kfree(pFirmware->mpConfigurations);
1512 }
1514 if (pFirmware->mpCalibrations != NULL) {
1515 for (n = 0; n < pFirmware->mnCalibrations; n++) {
1516 kfree(pFirmware->mpCalibrations[n].mpDescription);
1517 kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
1518 for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
1519 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
1520 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
1521 }
1522 kfree(pFirmware->mpCalibrations);
1523 }
1525 memset(pFirmware, 0x00, sizeof(struct TFirmware));
1526 }
1528 static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, char *pFileName)
1529 {
1530 int nResult = 0;
1531 /*
1532 * int nFile;
1533 * mm_segment_t fs;
1534 * unsigned char pBuffer[1000];
1535 * int nSize = 0;
1536 *
1537 * dev_dbg(pTAS2557->dev, "%s:\n", __func__);
1538 *
1539 * fs = get_fs();
1540 * set_fs(KERNEL_DS);
1541 * nFile = sys_open(pFileName, O_RDONLY, 0);
1542 *
1543 * dev_info(pTAS2557->dev, "TAS2557 calibration file = %s, handle = %d\n",
1544 * pFileName, nFile);
1545 *
1546 * if (nFile >= 0) {
1547 * nSize = sys_read(nFile, pBuffer, 1000);
1548 * sys_close(nFile);
1549 * } else {
1550 * dev_err(pTAS2557->dev, "TAS2557 cannot open calibration file: %s\n",
1551 * pFileName);
1552 * }
1553 *
1554 * set_fs(fs);
1555 *
1556 * if (!nSize)
1557 * goto end;
1558 *
1559 * tas2557_clear_firmware(pTAS2557->mpCalFirmware);
1560 * dev_info(pTAS2557->dev, "TAS2557 calibration file size = %d\n", nSize);
1561 * nResult = fw_parse(pTAS2557, pTAS2557->mpCalFirmware, pBuffer, nSize);
1562 *
1563 * if (nResult)
1564 * dev_err(pTAS2557->dev, "TAS2557 calibration file is corrupt\n");
1565 * else
1566 * dev_info(pTAS2557->dev, "TAS2557 calibration: %d calibrations\n",
1567 * pTAS2557->mpCalFirmware->mnCalibrations);
1568 *
1569 *end:
1570 **/
1571 return nResult;
1572 }
1574 static bool tas2557_get_coefficient_in_block(struct tas2557_priv *pTAS2557,
1575 struct TBlock *pBlock, int nReg, int *pnValue)
1576 {
1577 int nCoefficient = 0;
1578 bool bFound = false;
1579 unsigned char *pCommands;
1580 int nBook, nPage, nOffset, len;
1581 int i, n;
1583 pCommands = pBlock->mpData;
1584 for (i = 0 ; i < pBlock->mnCommands;) {
1585 nBook = pCommands[4 * i + 0];
1586 nPage = pCommands[4 * i + 1];
1587 nOffset = pCommands[4 * i + 2];
1588 if ((nOffset < 0x7f) || (nOffset == 0x81))
1589 i++;
1590 else if (nOffset == 0x85) {
1591 len = ((int)nBook << 8) | nPage;
1592 nBook = pCommands[4 * i + 4];
1593 nPage = pCommands[4 * i + 5];
1594 nOffset = pCommands[4 * i + 6];
1595 n = 4 * i + 7;
1596 i += 2;
1597 i += ((len - 1) / 4);
1598 if ((len - 1) % 4)
1599 i++;
1600 if ((nBook != TAS2557_BOOK_ID(nReg))
1601 || (nPage != TAS2557_PAGE_ID(nReg)))
1602 continue;
1603 if (nOffset > TAS2557_PAGE_REG(nReg))
1604 continue;
1605 if ((len + nOffset) >= (TAS2557_PAGE_REG(nReg) + 4)) {
1606 n += (TAS2557_PAGE_REG(nReg) - nOffset);
1607 nCoefficient = ((int)pCommands[n] << 24)
1608 | ((int)pCommands[n + 1] << 16)
1609 | ((int)pCommands[n + 2] << 8)
1610 | (int)pCommands[n + 3];
1611 bFound = true;
1612 break;
1613 }
1614 } else {
1615 dev_err(pTAS2557->dev, "%s, format error %d\n", __func__, nOffset);
1616 break;
1617 }
1618 }
1620 if (bFound) {
1621 *pnValue = nCoefficient;
1622 dev_dbg(pTAS2557->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", __func__,
1623 TAS2557_BOOK_ID(nReg), TAS2557_PAGE_ID(nReg), TAS2557_PAGE_REG(nReg),
1624 nCoefficient);
1625 }
1627 return bFound;
1628 }
1630 static bool tas2557_get_coefficient_in_data(struct tas2557_priv *pTAS2557,
1631 struct TData *pData, int blockType, int nReg, int *pnValue)
1632 {
1633 bool bFound = false;
1634 struct TBlock *pBlock;
1635 int i;
1637 for (i = 0; i < pData->mnBlocks; i++) {
1638 pBlock = &(pData->mpBlocks[i]);
1639 if (pBlock->mnType == blockType) {
1640 bFound = tas2557_get_coefficient_in_block(pTAS2557,
1641 pBlock, nReg, pnValue);
1642 if (bFound)
1643 break;
1644 }
1645 }
1647 return bFound;
1648 }
1650 static bool tas2557_find_Tmax_in_configuration(struct tas2557_priv *pTAS2557,
1651 struct TConfiguration *pConfiguration, int *pnTMax)
1652 {
1653 struct TData *pData;
1654 bool bFound = false;
1655 int nBlockType, nReg, nCoefficient;
1657 if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
1658 nReg = TAS2557_PG2P1_CALI_T_REG;
1659 else
1660 nReg = TAS2557_PG1P0_CALI_T_REG;
1662 nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A;
1664 pData = &(pConfiguration->mData);
1665 bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCoefficient);
1666 if (bFound)
1667 *pnTMax = nCoefficient;
1669 return bFound;
1670 }
1672 void tas2557_fw_ready(const struct firmware *pFW, void *pContext)
1673 {
1674 struct tas2557_priv *pTAS2557 = (struct tas2557_priv *) pContext;
1675 int nResult;
1676 unsigned int nProgram = 0;
1677 unsigned int nSampleRate = 0;
1679 #ifdef CONFIG_TAS2557_CODEC
1680 mutex_lock(&pTAS2557->codec_lock);
1681 #endif
1683 #ifdef CONFIG_TAS2557_MISC
1684 mutex_lock(&pTAS2557->file_lock);
1685 #endif
1687 dev_info(pTAS2557->dev, "%s:\n", __func__);
1689 if (unlikely(!pFW) || unlikely(!pFW->data)) {
1690 dev_err(pTAS2557->dev, "%s firmware is not loaded.\n",
1691 TAS2557_FW_NAME);
1692 goto end;
1693 }
1695 if (pTAS2557->mpFirmware->mpConfigurations) {
1696 nProgram = pTAS2557->mnCurrentProgram;
1697 nSampleRate = pTAS2557->mnCurrentSampleRate;
1698 dev_dbg(pTAS2557->dev, "clear current firmware\n");
1699 tas2557_clear_firmware(pTAS2557->mpFirmware);
1700 }
1702 nResult = fw_parse(pTAS2557, pTAS2557->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
1703 release_firmware(pFW);
1704 if (nResult < 0) {
1705 dev_err(pTAS2557->dev, "firmware is corrupt\n");
1706 goto end;
1707 }
1709 if (!pTAS2557->mpFirmware->mnPrograms) {
1710 dev_err(pTAS2557->dev, "firmware contains no programs\n");
1711 nResult = -EINVAL;
1712 goto end;
1713 }
1715 if (!pTAS2557->mpFirmware->mnConfigurations) {
1716 dev_err(pTAS2557->dev, "firmware contains no configurations\n");
1717 nResult = -EINVAL;
1718 goto end;
1719 }
1721 if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
1722 dev_info(pTAS2557->dev,
1723 "no previous program, set to default\n");
1724 nProgram = 0;
1725 }
1727 pTAS2557->mnCurrentSampleRate = nSampleRate;
1728 nResult = tas2557_set_program(pTAS2557, nProgram, -1);
1730 end:
1732 #ifdef CONFIG_TAS2557_CODEC
1733 mutex_unlock(&pTAS2557->codec_lock);
1734 #endif
1736 #ifdef CONFIG_TAS2557_MISC
1737 mutex_unlock(&pTAS2557->file_lock);
1738 #endif
1739 }
1741 int tas2557_set_program(struct tas2557_priv *pTAS2557,
1742 unsigned int nProgram, int nConfig)
1743 {
1744 struct TProgram *pProgram;
1745 unsigned int nConfiguration = 0;
1746 unsigned int nSampleRate = 0;
1747 unsigned char nGain;
1748 bool bFound = false;
1749 int nResult = 0;
1751 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1752 (!pTAS2557->mpFirmware->mpConfigurations)) {
1753 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1754 nResult = 0;
1755 goto end;
1756 }
1758 if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
1759 dev_err(pTAS2557->dev, "TAS2557: Program %d doesn't exist\n",
1760 nProgram);
1761 nResult = 0;
1762 goto end;
1763 }
1765 if (nConfig < 0) {
1766 nConfiguration = 0;
1767 nSampleRate = pTAS2557->mnCurrentSampleRate;
1768 while (!bFound && (nConfiguration < pTAS2557->mpFirmware->mnConfigurations)) {
1769 if (pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
1770 if (nSampleRate == 0) {
1771 bFound = true;
1772 dev_info(pTAS2557->dev, "find default configuration %d\n", nConfiguration);
1773 } else if (nSampleRate == pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
1774 bFound = true;
1775 dev_info(pTAS2557->dev, "find matching configuration %d\n", nConfiguration);
1776 } else {
1777 nConfiguration++;
1778 }
1779 } else {
1780 nConfiguration++;
1781 }
1782 }
1783 if (!bFound) {
1784 dev_err(pTAS2557->dev,
1785 "Program %d, no valid configuration found for sample rate %d, ignore\n",
1786 nProgram, nSampleRate);
1787 nResult = 0;
1788 goto end;
1789 }
1790 } else {
1791 if (pTAS2557->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
1792 dev_err(pTAS2557->dev, "%s, configuration program doesn't match\n", __func__);
1793 nResult = 0;
1794 goto end;
1795 }
1796 nConfiguration = nConfig;
1797 }
1799 pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
1800 if (pTAS2557->mbPowerUp) {
1801 dev_info(pTAS2557->dev,
1802 "device powered up, power down to load program %d (%s)\n",
1803 nProgram, pProgram->mpName);
1804 if (hrtimer_active(&pTAS2557->mtimer))
1805 hrtimer_cancel(&pTAS2557->mtimer);
1807 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
1808 pTAS2557->enableIRQ(pTAS2557, false, false);
1810 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
1811 if (nResult < 0)
1812 goto end;
1813 }
1815 pTAS2557->hw_reset(pTAS2557);
1816 nResult = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
1817 if (nResult < 0)
1818 goto end;
1819 msleep(1);
1820 nResult = tas2557_load_default(pTAS2557);
1821 if (nResult < 0)
1822 goto end;
1824 dev_info(pTAS2557->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
1825 nResult = tas2557_load_data(pTAS2557, &(pProgram->mData), TAS2557_BLOCK_PGM_DEV_A);
1826 if (nResult < 0)
1827 goto end;
1828 pTAS2557->mnCurrentProgram = nProgram;
1830 nResult = tas2557_get_DAC_gain(pTAS2557, &nGain);
1831 if (nResult < 0)
1832 goto end;
1833 pTAS2557->mnDevGain = nGain;
1834 pTAS2557->mnDevCurrentGain = nGain;
1836 nResult = tas2557_load_coefficient(pTAS2557, -1, nConfiguration, false);
1837 if (nResult < 0)
1838 goto end;
1840 if (pTAS2557->mbPowerUp) {
1841 pTAS2557->clearIRQ(pTAS2557);
1842 dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
1843 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
1844 if (nResult < 0)
1845 goto end;
1846 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1847 nResult = tas2557_checkPLL(pTAS2557);
1848 if (nResult < 0) {
1849 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
1850 pTAS2557->mbPowerUp = false;
1851 goto end;
1852 }
1853 }
1854 dev_dbg(pTAS2557->dev, "device powered up, load unmute\n");
1855 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
1856 if (nResult < 0)
1857 goto end;
1859 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1860 pTAS2557->enableIRQ(pTAS2557, true, true);
1861 if (!hrtimer_active(&pTAS2557->mtimer)) {
1862 pTAS2557->mnDieTvReadCounter = 0;
1863 hrtimer_start(&pTAS2557->mtimer,
1864 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1865 }
1866 }
1867 }
1869 end:
1871 if (nResult < 0) {
1872 if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
1873 failsafe(pTAS2557);
1874 }
1875 return nResult;
1876 }
1878 int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration)
1879 {
1880 struct TCalibration *pCalibration = NULL;
1881 struct TConfiguration *pConfiguration;
1882 struct TProgram *pProgram;
1883 int nTmax = 0;
1884 bool bFound = false;
1885 int nResult = 0;
1887 if ((!pTAS2557->mpFirmware->mpPrograms)
1888 || (!pTAS2557->mpFirmware->mpConfigurations)) {
1889 dev_err(pTAS2557->dev, "Firmware not loaded\n\r");
1890 nResult = 0;
1891 goto end;
1892 }
1894 if (nCalibration == 0x00FF) {
1895 nResult = tas2557_load_calibration(pTAS2557, TAS2557_CAL_NAME);
1896 if (nResult < 0) {
1897 dev_info(pTAS2557->dev, "load new calibration file %s fail %d\n",
1898 TAS2557_CAL_NAME, nResult);
1899 goto end;
1900 }
1901 nCalibration = 0;
1902 }
1904 if (nCalibration >= pTAS2557->mpCalFirmware->mnCalibrations) {
1905 dev_err(pTAS2557->dev,
1906 "Calibration %d doesn't exist\n", nCalibration);
1907 nResult = 0;
1908 goto end;
1909 }
1911 pTAS2557->mnCurrentCalibration = nCalibration;
1912 if (pTAS2557->mbLoadConfigurationPrePowerUp)
1913 goto end;
1915 pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[nCalibration]);
1916 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
1917 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
1918 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1919 if (pTAS2557->mbBypassTMax) {
1920 bFound = tas2557_find_Tmax_in_configuration(pTAS2557, pConfiguration, &nTmax);
1921 if (bFound && (nTmax == TAS2557_COEFFICIENT_TMAX)) {
1922 dev_dbg(pTAS2557->dev, "%s, config[%s] bypass load calibration\n",
1923 __func__, pConfiguration->mpName);
1924 goto end;
1925 }
1926 }
1928 dev_dbg(pTAS2557->dev, "%s, load calibration\n", __func__);
1929 nResult = tas2557_load_data(pTAS2557, &(pCalibration->mData), TAS2557_BLOCK_CFG_COEFF_DEV_A);
1930 if (nResult < 0)
1931 goto end;
1932 }
1934 end:
1935 if (nResult < 0) {
1936 tas2557_clear_firmware(pTAS2557->mpCalFirmware);
1937 nResult = tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, pTAS2557->mnCurrentConfiguration);
1938 }
1940 return nResult;
1941 }
1943 bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0)
1944 {
1945 struct TCalibration *pCalibration;
1946 struct TData *pData;
1947 int nReg;
1948 int nCali_Re;
1949 bool bFound = false;
1950 int nBlockType;
1952 if (!pTAS2557->mpCalFirmware->mnCalibrations) {
1953 dev_err(pTAS2557->dev, "%s, no calibration data\n", __func__);
1954 goto end;
1955 }
1957 if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
1958 nReg = TAS2557_PG2P1_CALI_R0_REG;
1959 else
1960 nReg = TAS2557_PG1P0_CALI_R0_REG;
1962 nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A;
1964 pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[pTAS2557->mnCurrentCalibration]);
1965 pData = &(pCalibration->mData);
1967 bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCali_Re);
1969 end:
1971 if (bFound)
1972 *prm_r0 = nCali_Re;
1974 return bFound;
1975 }
1977 int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557)
1978 {
1979 struct device_node *np = dev->of_node;
1980 int rc = 0, ret = 0;
1981 unsigned int value;
1983 pTAS2557->mnResetGPIO = of_get_named_gpio(np, "ti,cdc-reset-gpio", 0);
1984 if (!gpio_is_valid(pTAS2557->mnResetGPIO)) {
1985 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
1986 "ti,cdc-reset-gpio", np->full_name,
1987 pTAS2557->mnResetGPIO);
1988 ret = -EINVAL;
1989 goto end;
1990 } else
1991 dev_dbg(pTAS2557->dev, "ti,cdc-reset-gpio=%d\n", pTAS2557->mnResetGPIO);
1993 pTAS2557->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0);
1994 if (!gpio_is_valid(pTAS2557->mnGpioINT))
1995 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
1996 "ti,irq-gpio", np->full_name,
1997 pTAS2557->mnGpioINT);
2000 rc = of_property_read_u32(np, "ti,i2s-bits", &value);
2001 if (rc)
2002 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2003 "ti,i2s-bits", np->full_name, rc);
2004 else
2005 pTAS2557->mnI2SBits = value;
2007 rc = of_property_read_u32(np, "ti,bypass-tmax", &value);
2008 if (rc)
2009 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2010 "ti,bypass-tmax", np->full_name, rc);
2011 else
2012 pTAS2557->mbBypassTMax = (value > 0);
2014 end:
2016 return ret;
2017 }
2019 MODULE_AUTHOR("Texas Instruments Inc.");
2020 MODULE_DESCRIPTION("TAS2557 common functions for Android Linux");
2021 MODULE_LICENSE("GPL v2");