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"
50 #define RESTART_MAX 3
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 int ret;
296 dev_err(pTAS2557->dev, "%s\n", __func__);
297 pTAS2557->mnErrCode |= ERROR_FAILSAFE;
298 if (hrtimer_active(&pTAS2557->mtimer))
299 hrtimer_cancel(&pTAS2557->mtimer);
301 if(pTAS2557->mnRestart < RESTART_MAX)
302 {
303 pTAS2557->mnRestart ++;
304 msleep(100);
305 dev_err(pTAS2557->dev, "I2C COMM error, restart SmartAmp.\n");
306 schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(100));
307 return;
308 }
309 pTAS2557->enableIRQ(pTAS2557, false, false);
310 ret = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
311 if (ret < 0)
312 dev_dbg(pTAS2557->dev, "failed load shutdown\n");
314 pTAS2557->mbPowerUp = false;
315 pTAS2557->hw_reset(pTAS2557);
316 ret = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
317 if (ret < 0)
318 dev_dbg(pTAS2557->dev, "failed sw reset\n");
320 udelay(1000);
321 ret = pTAS2557->write(pTAS2557, TAS2557_SPK_CTRL_REG, 0x04);
322 if (ret < 0)
323 dev_dbg(pTAS2557->dev, "failed in spk ctrl\n");
324 if (pTAS2557->mpFirmware != NULL)
325 tas2557_clear_firmware(pTAS2557->mpFirmware);
326 }
328 int tas2557_checkPLL(struct tas2557_priv *pTAS2557)
329 {
330 int nResult = 0;
331 /*
332 * TO DO
333 */
335 return nResult;
336 }
338 /*
339 * tas2557_load_coefficient
340 */
341 static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557,
342 int nPrevConfig, int nNewConfig, bool bPowerOn)
343 {
344 int nResult = 0;
345 struct TPLL *pPLL;
346 struct TProgram *pProgram;
347 struct TConfiguration *pPrevConfiguration;
348 struct TConfiguration *pNewConfiguration;
349 bool bRestorePower = false;
351 if (!pTAS2557->mpFirmware->mnConfigurations) {
352 dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
353 goto end;
354 }
356 if (nNewConfig >= pTAS2557->mpFirmware->mnConfigurations) {
357 dev_err(pTAS2557->dev, "%s, invalid configuration New=%d, total=%d\n",
358 __func__, nNewConfig, pTAS2557->mpFirmware->mnConfigurations);
359 goto end;
360 }
362 if (nPrevConfig < 0)
363 pPrevConfiguration = NULL;
364 else if (nPrevConfig == nNewConfig) {
365 dev_dbg(pTAS2557->dev, "%s, config [%d] already loaded\n",
366 __func__, nNewConfig);
367 goto end;
368 } else
369 pPrevConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nPrevConfig]);
371 pNewConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nNewConfig]);
372 pTAS2557->mnCurrentConfiguration = nNewConfig;
373 if (pPrevConfiguration) {
374 if (pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL) {
375 dev_dbg(pTAS2557->dev, "%s, PLL same\n", __func__);
376 goto prog_coefficient;
377 }
378 }
380 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
381 if (bPowerOn) {
382 dev_dbg(pTAS2557->dev, "%s, power down to load new PLL\n", __func__);
383 if (hrtimer_active(&pTAS2557->mtimer))
384 hrtimer_cancel(&pTAS2557->mtimer);
386 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
387 pTAS2557->enableIRQ(pTAS2557, false, false);
389 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
390 if (nResult < 0)
391 goto end;
392 bRestorePower = true;
393 }
395 /* load PLL */
396 pPLL = &(pTAS2557->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
397 dev_dbg(pTAS2557->dev, "load PLL: %s block for Configuration %s\n",
398 pPLL->mpName, pNewConfiguration->mpName);
399 nResult = tas2557_load_block(pTAS2557, &(pPLL->mBlock));
400 if (nResult < 0)
401 goto end;
402 pTAS2557->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
404 dev_dbg(pTAS2557->dev, "load configuration %s conefficient pre block\n",
405 pNewConfiguration->mpName);
406 nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), TAS2557_BLOCK_CFG_PRE_DEV_A);
407 if (nResult < 0)
408 goto end;
410 prog_coefficient:
411 dev_dbg(pTAS2557->dev, "load new configuration: %s, coeff block data\n",
412 pNewConfiguration->mpName);
413 nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData),
414 TAS2557_BLOCK_CFG_COEFF_DEV_A);
415 if (nResult < 0)
416 goto end;
418 if (pTAS2557->mpCalFirmware->mnCalibrations) {
419 nResult = tas2557_set_calibration(pTAS2557, pTAS2557->mnCurrentCalibration);
420 if (nResult < 0)
421 goto end;
422 }
424 if (bRestorePower) {
425 pTAS2557->clearIRQ(pTAS2557);
426 dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
427 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
428 if (nResult < 0)
429 goto end;
430 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
431 nResult = tas2557_checkPLL(pTAS2557);
432 if (nResult < 0) {
433 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
434 pTAS2557->mbPowerUp = false;
435 goto end;
436 }
437 }
438 dev_dbg(pTAS2557->dev,
439 "device powered up, load unmute\n");
440 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
441 if (nResult < 0)
442 goto end;
443 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
444 pTAS2557->enableIRQ(pTAS2557, true, true);
445 if (!hrtimer_active(&pTAS2557->mtimer)) {
446 pTAS2557->mnDieTvReadCounter = 0;
447 hrtimer_start(&pTAS2557->mtimer,
448 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
449 }
450 }
451 }
452 end:
454 pTAS2557->mnNewConfiguration = pTAS2557->mnCurrentConfiguration;
455 return nResult;
456 }
458 int tas2557_update_edge(struct tas2557_priv *pTAS2557)
459 {
460 int nResult = 0;
461 dev_dbg(pTAS2557->dev,
462 "%s, edge: %d\n",
463 __func__, pTAS2557->mnEdge);
465 nResult = pTAS2557->update_bits(pTAS2557, TAS2557_SPK_CTRL_REG, 0x7, pTAS2557->mnEdge);
467 return nResult;
468 }
470 int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable)
471 {
472 int nResult = 0;
473 unsigned int nValue;
474 const char *pFWName;
475 struct TProgram *pProgram;
477 dev_dbg(pTAS2557->dev, "Enable: %d\n", bEnable);
479 if ((pTAS2557->mpFirmware->mnPrograms == 0)
480 || (pTAS2557->mpFirmware->mnConfigurations == 0)) {
481 dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
482 /*Load firmware*/
483 if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) {
484 dev_info(pTAS2557->dev, "PG2.1 Silicon found\n");
485 pFWName = TAS2557_FW_NAME;
486 } else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) {
487 dev_info(pTAS2557->dev, "PG1.0 Silicon found\n");
488 pFWName = TAS2557_PG1P0_FW_NAME;
489 } else {
490 nResult = -ENOTSUPP;
491 dev_info(pTAS2557->dev, "unsupport Silicon 0x%x\n", pTAS2557->mnPGID);
492 goto end;
493 }
494 nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName,
495 pTAS2557->dev, GFP_KERNEL, pTAS2557, tas2557_fw_ready);
496 if(nResult < 0)
497 goto end;
498 dev_err(pTAS2557->dev, "%s, firmware is loaded\n", __func__);
499 }
501 /* check safe guard*/
502 nResult = pTAS2557->read(pTAS2557, TAS2557_SAFE_GUARD_REG, &nValue);
503 if (nResult < 0)
504 goto end;
505 if ((nValue&0xff) != TAS2557_SAFE_GUARD_PATTERN) {
506 dev_err(pTAS2557->dev, "ERROR safe guard failure!\n");
507 nResult = -EPIPE;
508 pTAS2557->mnErrCode = ERROR_SAFE_GUARD;
509 pTAS2557->mbPowerUp = true;
510 goto end;
511 }
513 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
514 if (bEnable) {
515 if (!pTAS2557->mbPowerUp) {
516 if (!pTAS2557->mbCalibrationLoaded) {
517 tas2557_set_calibration(pTAS2557, 0xFF);
518 pTAS2557->mbCalibrationLoaded = true;
519 }
521 if (pTAS2557->mbLoadConfigurationPrePowerUp) {
522 dev_dbg(pTAS2557->dev, "load coefficient before power\n");
523 pTAS2557->mbLoadConfigurationPrePowerUp = false;
524 nResult = tas2557_load_coefficient(pTAS2557,
525 pTAS2557->mnCurrentConfiguration, pTAS2557->mnNewConfiguration, false);
526 if (nResult < 0)
527 goto end;
528 }
530 pTAS2557->clearIRQ(pTAS2557);
531 /* power on device */
532 dev_dbg(pTAS2557->dev, "Enable: load startup sequence\n");
533 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
534 if (nResult < 0)
535 goto end;
536 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
537 nResult = tas2557_checkPLL(pTAS2557);
538 if (nResult < 0) {
539 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
540 goto end;
541 }
542 }
543 dev_dbg(pTAS2557->dev, "Enable: load unmute sequence\n");
544 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
545 if (nResult < 0)
546 goto end;
548 pTAS2557->mbPowerUp = true;
550 tas2557_get_die_temperature(pTAS2557, &nValue);
551 if(nValue == 0x80000000)
552 {
553 dev_err(pTAS2557->dev, "%s, thermal sensor is wrong, mute output\n", __func__);
554 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
555 pTAS2557->mbPowerUp = false;
556 goto end;
557 }
559 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
560 /* turn on IRQ */
561 pTAS2557->enableIRQ(pTAS2557, true, true);
562 if (!hrtimer_active(&pTAS2557->mtimer)) {
563 pTAS2557->mnDieTvReadCounter = 0;
564 hrtimer_start(&pTAS2557->mtimer,
565 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
566 }
567 }
568 pTAS2557->mnRestart = 0;
569 }
570 } else {
571 if (pTAS2557->mbPowerUp) {
572 if (hrtimer_active(&pTAS2557->mtimer))
573 hrtimer_cancel(&pTAS2557->mtimer);
575 dev_dbg(pTAS2557->dev, "Enable: load shutdown sequence\n");
576 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
577 /* turn off IRQ */
578 pTAS2557->enableIRQ(pTAS2557, false, false);
579 }
580 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
581 if (nResult < 0)
582 goto end;
584 pTAS2557->mbPowerUp = false;
585 pTAS2557->mnRestart = 0;
586 }
587 }
589 nResult = 0;
591 end:
592 if (nResult < 0) {
593 if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK | ERROR_SAFE_GUARD))
594 failsafe(pTAS2557);
595 }
597 return nResult;
598 }
600 int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate)
601 {
602 int nResult = 0;
603 struct TConfiguration *pConfiguration;
604 unsigned int nConfiguration;
606 dev_dbg(pTAS2557->dev, "tas2557_setup_clocks: nSamplingRate = %d [Hz]\n",
607 nSamplingRate);
609 if ((!pTAS2557->mpFirmware->mpPrograms) ||
610 (!pTAS2557->mpFirmware->mpConfigurations)) {
611 dev_err(pTAS2557->dev, "Firmware not loaded\n");
612 nResult = -EINVAL;
613 goto end;
614 }
616 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
617 if (pConfiguration->mnSamplingRate == nSamplingRate) {
618 dev_info(pTAS2557->dev, "Sampling rate for current configuration matches: %d\n",
619 nSamplingRate);
620 nResult = 0;
621 goto end;
622 }
624 for (nConfiguration = 0;
625 nConfiguration < pTAS2557->mpFirmware->mnConfigurations;
626 nConfiguration++) {
627 pConfiguration =
628 &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
629 if ((pConfiguration->mnSamplingRate == nSamplingRate)
630 && (pConfiguration->mnProgram == pTAS2557->mnCurrentProgram)) {
631 dev_info(pTAS2557->dev,
632 "Found configuration: %s, with compatible sampling rate %d\n",
633 pConfiguration->mpName, nSamplingRate);
634 nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
635 goto end;
636 }
637 }
639 dev_err(pTAS2557->dev, "Cannot find a configuration that supports sampling rate: %d\n",
640 nSamplingRate);
642 end:
644 return nResult;
645 }
647 static void fw_print_header(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware)
648 {
649 dev_info(pTAS2557->dev, "FW Size = %d", pFirmware->mnFWSize);
650 dev_info(pTAS2557->dev, "Checksum = 0x%04X", pFirmware->mnChecksum);
651 dev_info(pTAS2557->dev, "PPC Version = 0x%04X", pFirmware->mnPPCVersion);
652 dev_info(pTAS2557->dev, "FW Version = 0x%04X", pFirmware->mnFWVersion);
653 dev_info(pTAS2557->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
654 dev_info(pTAS2557->dev, "Timestamp = %d", pFirmware->mnTimeStamp);
655 dev_info(pTAS2557->dev, "DDC Name = %s", pFirmware->mpDDCName);
656 dev_info(pTAS2557->dev, "Description = %s", pFirmware->mpDescription);
657 }
659 inline unsigned int fw_convert_number(unsigned char *pData)
660 {
661 return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
662 }
664 static int fw_parse_header(struct tas2557_priv *pTAS2557,
665 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
666 {
667 unsigned char *pDataStart = pData;
668 unsigned int n;
669 unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
671 if (nSize < 104) {
672 dev_err(pTAS2557->dev, "Firmware: Header too short");
673 return -EINVAL;
674 }
676 if (memcmp(pData, pMagicNumber, 4)) {
677 dev_err(pTAS2557->dev, "Firmware: Magic number doesn't match");
678 return -EINVAL;
679 }
680 pData += 4;
682 pFirmware->mnFWSize = fw_convert_number(pData);
683 pData += 4;
685 pFirmware->mnChecksum = fw_convert_number(pData);
686 pData += 4;
688 pFirmware->mnPPCVersion = fw_convert_number(pData);
689 pData += 4;
691 pFirmware->mnFWVersion = fw_convert_number(pData);
692 pData += 4;
694 pFirmware->mnDriverVersion = fw_convert_number(pData);
695 pData += 4;
697 pFirmware->mnTimeStamp = fw_convert_number(pData);
698 pData += 4;
700 memcpy(pFirmware->mpDDCName, pData, 64);
701 pData += 64;
703 n = strlen(pData);
704 pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
705 pData += n + 1;
706 if ((pData - pDataStart) >= nSize) {
707 dev_err(pTAS2557->dev, "Firmware: Header too short after DDC description");
708 return -EINVAL;
709 }
711 pFirmware->mnDeviceFamily = fw_convert_number(pData);
712 pData += 4;
713 if (pFirmware->mnDeviceFamily != 0) {
714 dev_err(pTAS2557->dev,
715 "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
716 return -EINVAL;
717 }
719 pFirmware->mnDevice = fw_convert_number(pData);
720 pData += 4;
722 if (pFirmware->mnDevice != 2) {
723 dev_err(pTAS2557->dev,
724 "device %d, not TAS2557 Dual Mono", pFirmware->mnDevice);
725 return -EINVAL;
726 }
728 fw_print_header(pTAS2557, pFirmware);
729 return pData - pDataStart;
730 }
732 static int fw_parse_block_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
733 struct TBlock *pBlock, unsigned char *pData)
734 {
735 unsigned char *pDataStart = pData;
736 unsigned int n;
738 pBlock->mnType = fw_convert_number(pData);
739 pData += 4;
741 if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) {
742 pBlock->mbPChkSumPresent = pData[0];
743 pData++;
745 pBlock->mnPChkSum = pData[0];
746 pData++;
748 pBlock->mbYChkSumPresent = pData[0];
749 pData++;
751 pBlock->mnYChkSum = pData[0];
752 pData++;
753 } else {
754 pBlock->mbPChkSumPresent = 0;
755 pBlock->mbYChkSumPresent = 0;
756 }
758 pBlock->mnCommands = fw_convert_number(pData);
759 pData += 4;
761 n = pBlock->mnCommands * 4;
762 pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
763 pData += n;
764 return pData - pDataStart;
765 }
767 static int fw_parse_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
768 struct TData *pImageData, unsigned char *pData)
769 {
770 unsigned char *pDataStart = pData;
771 unsigned int nBlock;
772 unsigned int n;
774 memcpy(pImageData->mpName, pData, 64);
775 pData += 64;
777 n = strlen(pData);
778 pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
779 pData += n + 1;
781 pImageData->mnBlocks = (pData[0] << 8) + pData[1];
782 pData += 2;
784 pImageData->mpBlocks =
785 kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
786 if(pImageData->mpBlocks == NULL)
787 {
788 dev_dbg(pTAS2557->dev, "failed malloc blocks mem\n");
789 goto end;
790 }
792 for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
793 n = fw_parse_block_data(pTAS2557, pFirmware,
794 &(pImageData->mpBlocks[nBlock]), pData);
795 pData += n;
796 }
797 return pData - pDataStart;
798 }
800 static int fw_parse_pll_data(struct tas2557_priv *pTAS2557,
801 struct TFirmware *pFirmware, unsigned char *pData)
802 {
803 unsigned char *pDataStart = pData;
804 unsigned int n;
805 unsigned int nPLL;
806 struct TPLL *pPLL;
808 pFirmware->mnPLLs = (pData[0] << 8) + pData[1];
809 pData += 2;
811 if (pFirmware->mnPLLs == 0)
812 goto end;
814 pFirmware->mpPLLs = kmalloc_array(pFirmware->mnPLLs, sizeof(struct TPLL), GFP_KERNEL);
815 for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) {
816 pPLL = &(pFirmware->mpPLLs[nPLL]);
818 memcpy(pPLL->mpName, pData, 64);
819 pData += 64;
821 n = strlen(pData);
822 pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
823 pData += n + 1;
825 n = fw_parse_block_data(pTAS2557, pFirmware, &(pPLL->mBlock), pData);
826 pData += n;
827 }
829 end:
830 return pData - pDataStart;
831 }
833 static int fw_parse_program_data(struct tas2557_priv *pTAS2557,
834 struct TFirmware *pFirmware, unsigned char *pData)
835 {
836 unsigned char *pDataStart = pData;
837 unsigned int n;
838 unsigned int nProgram;
839 struct TProgram *pProgram;
841 pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
842 pData += 2;
844 if (pFirmware->mnPrograms == 0)
845 goto end;
847 pFirmware->mpPrograms =
848 kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
849 if(pFirmware->mpPrograms == NULL)
850 {
851 dev_dbg(pTAS2557->dev, "failed malloc program mem\n");
852 goto end;
853 }
855 for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
856 pProgram = &(pFirmware->mpPrograms[nProgram]);
857 memcpy(pProgram->mpName, pData, 64);
858 pData += 64;
860 n = strlen(pData);
861 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
862 pData += n + 1;
864 pProgram->mnAppMode = pData[0];
865 pData++;
867 pProgram->mnBoost = (pData[0] << 8) + pData[1];
868 pData += 2;
870 n = fw_parse_data(pTAS2557, pFirmware, &(pProgram->mData), pData);
871 pData += n;
872 }
874 end:
876 return pData - pDataStart;
877 }
879 static int fw_parse_configuration_data(struct tas2557_priv *pTAS2557,
880 struct TFirmware *pFirmware, unsigned char *pData)
881 {
882 unsigned char *pDataStart = pData;
883 unsigned int n;
884 unsigned int nConfiguration;
885 struct TConfiguration *pConfiguration;
887 pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
888 pData += 2;
890 if (pFirmware->mnConfigurations == 0)
891 goto end;
893 pFirmware->mpConfigurations =
894 kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
895 GFP_KERNEL);
896 if(pFirmware->mpConfigurations == NULL)
897 {
898 dev_dbg(pTAS2557->dev, "failed malloc configuration mem\n");
899 goto end;
900 }
902 for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
903 nConfiguration++) {
904 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
905 memcpy(pConfiguration->mpName, pData, 64);
906 pData += 64;
908 n = strlen(pData);
909 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
910 pData += n + 1;
912 if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV)
913 || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC)
914 && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) {
915 pConfiguration->mnDevices = (pData[0] << 8) + pData[1];
916 pData += 2;
917 } else
918 pConfiguration->mnDevices = 1;
920 pConfiguration->mnProgram = pData[0];
921 pData++;
923 pConfiguration->mnPLL = pData[0];
924 pData++;
926 pConfiguration->mnSamplingRate = fw_convert_number(pData);
927 pData += 4;
929 if (pFirmware->mnDriverVersion >= PPC_DRIVER_MTPLLSRC) {
930 pConfiguration->mnPLLSrc = pData[0];
931 pData++;
933 pConfiguration->mnPLLSrcRate = fw_convert_number(pData);
934 pData += 4;
935 }
937 n = fw_parse_data(pTAS2557, pFirmware, &(pConfiguration->mData), pData);
938 pData += n;
939 }
941 end:
943 return pData - pDataStart;
944 }
946 int fw_parse_calibration_data(struct tas2557_priv *pTAS2557,
947 struct TFirmware *pFirmware, unsigned char *pData)
948 {
949 unsigned char *pDataStart = pData;
950 unsigned int n;
951 unsigned int nCalibration;
952 struct TCalibration *pCalibration;
954 pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
955 pData += 2;
957 if (pFirmware->mnCalibrations == 0)
958 goto end;
960 pFirmware->mpCalibrations =
961 kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
962 if(pFirmware->mpCalibrations == NULL)
963 {
964 dev_err(pTAS2557->dev, "failed to malloc calibration mem\n");
965 goto end;
966 }
968 for (nCalibration = 0;
969 nCalibration < pFirmware->mnCalibrations;
970 nCalibration++) {
971 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
972 memcpy(pCalibration->mpName, pData, 64);
973 pData += 64;
975 n = strlen(pData);
976 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
977 pData += n + 1;
979 pCalibration->mnProgram = pData[0];
980 pData++;
982 pCalibration->mnConfiguration = pData[0];
983 pData++;
985 n = fw_parse_data(pTAS2557, pFirmware, &(pCalibration->mData), pData);
986 pData += n;
987 }
989 end:
991 return pData - pDataStart;
992 }
994 static int fw_parse(struct tas2557_priv *pTAS2557,
995 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
996 {
997 int nPosition = 0;
999 nPosition = fw_parse_header(pTAS2557, pFirmware, pData, nSize);
1000 if (nPosition < 0) {
1001 dev_err(pTAS2557->dev, "Firmware: Wrong Header");
1002 return -EINVAL;
1003 }
1005 if (nPosition >= nSize) {
1006 dev_err(pTAS2557->dev, "Firmware: Too short");
1007 return -EINVAL;
1008 }
1010 pData += nPosition;
1011 nSize -= nPosition;
1012 nPosition = 0;
1014 nPosition = fw_parse_pll_data(pTAS2557, pFirmware, pData);
1016 pData += nPosition;
1017 nSize -= nPosition;
1018 nPosition = 0;
1020 nPosition = fw_parse_program_data(pTAS2557, pFirmware, pData);
1022 pData += nPosition;
1023 nSize -= nPosition;
1024 nPosition = 0;
1026 nPosition = fw_parse_configuration_data(pTAS2557, pFirmware, pData);
1028 pData += nPosition;
1029 nSize -= nPosition;
1030 nPosition = 0;
1032 if (nSize > 64)
1033 nPosition = fw_parse_calibration_data(pTAS2557, pFirmware, pData);
1034 return 0;
1035 }
1038 static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
1039 0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
1040 0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
1041 0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
1042 0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
1043 0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
1044 0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
1045 0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
1046 0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
1047 0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
1048 0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
1049 0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
1050 0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
1051 0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
1052 0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
1053 0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
1054 0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
1055 };
1057 static int isInPageYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1058 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1059 {
1060 int nResult = 0;
1062 if (nBook == TAS2557_YRAM_BOOK1) {
1063 if (nPage == TAS2557_YRAM1_PAGE) {
1064 if (nReg >= TAS2557_YRAM1_START_REG) {
1065 pCRCData->mnOffset = nReg;
1066 pCRCData->mnLen = len;
1067 nResult = 1;
1068 } else if ((nReg + len) > TAS2557_YRAM1_START_REG) {
1069 pCRCData->mnOffset = TAS2557_YRAM1_START_REG;
1070 pCRCData->mnLen = len - (TAS2557_YRAM1_START_REG - nReg);
1071 nResult = 1;
1072 } else
1073 nResult = 0;
1074 } else if (nPage == TAS2557_YRAM3_PAGE) {
1075 if (nReg > TAS2557_YRAM3_END_REG) {
1076 nResult = 0;
1077 } else if (nReg >= TAS2557_YRAM3_START_REG) {
1078 if ((nReg + len) > TAS2557_YRAM3_END_REG) {
1079 pCRCData->mnOffset = nReg;
1080 pCRCData->mnLen = TAS2557_YRAM3_END_REG - nReg + 1;
1081 nResult = 1;
1082 } else {
1083 pCRCData->mnOffset = nReg;
1084 pCRCData->mnLen = len;
1085 nResult = 1;
1086 }
1087 } else {
1088 if ((nReg + (len - 1)) < TAS2557_YRAM3_START_REG)
1089 nResult = 0;
1090 else {
1091 pCRCData->mnOffset = TAS2557_YRAM3_START_REG;
1092 pCRCData->mnLen = len - (TAS2557_YRAM3_START_REG - nReg);
1093 nResult = 1;
1094 }
1095 }
1096 }
1097 } else if (nBook == TAS2557_YRAM_BOOK2) {
1098 if (nPage == TAS2557_YRAM5_PAGE) {
1099 if (nReg > TAS2557_YRAM5_END_REG) {
1100 nResult = 0;
1101 } else if (nReg >= TAS2557_YRAM5_START_REG) {
1102 if ((nReg + len) > TAS2557_YRAM5_END_REG) {
1103 pCRCData->mnOffset = nReg;
1104 pCRCData->mnLen = TAS2557_YRAM5_END_REG - nReg + 1;
1105 nResult = 1;
1106 } else {
1107 pCRCData->mnOffset = nReg;
1108 pCRCData->mnLen = len;
1109 nResult = 1;
1110 }
1111 } else {
1112 if ((nReg + (len - 1)) < TAS2557_YRAM5_START_REG)
1113 nResult = 0;
1114 else {
1115 pCRCData->mnOffset = TAS2557_YRAM5_START_REG;
1116 pCRCData->mnLen = len - (TAS2557_YRAM5_START_REG - nReg);
1117 nResult = 1;
1118 }
1119 }
1120 }
1121 } else
1122 nResult = 0;
1124 return nResult;
1125 }
1127 static int isInBlockYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1128 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1129 {
1130 int nResult;
1132 if (nBook == TAS2557_YRAM_BOOK1) {
1133 if (nPage < TAS2557_YRAM2_START_PAGE)
1134 nResult = 0;
1135 else if (nPage <= TAS2557_YRAM2_END_PAGE) {
1136 if (nReg > TAS2557_YRAM2_END_REG)
1137 nResult = 0;
1138 else if (nReg >= TAS2557_YRAM2_START_REG) {
1139 pCRCData->mnOffset = nReg;
1140 pCRCData->mnLen = len;
1141 nResult = 1;
1142 } else {
1143 if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG)
1144 nResult = 0;
1145 else {
1146 pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
1147 pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
1148 nResult = 1;
1149 }
1150 }
1151 } else
1152 nResult = 0;
1153 } else if (nBook == TAS2557_YRAM_BOOK2) {
1154 if (nPage < TAS2557_YRAM4_START_PAGE)
1155 nResult = 0;
1156 else if (nPage <= TAS2557_YRAM4_END_PAGE) {
1157 if (nReg > TAS2557_YRAM2_END_REG)
1158 nResult = 0;
1159 else if (nReg >= TAS2557_YRAM2_START_REG) {
1160 pCRCData->mnOffset = nReg;
1161 pCRCData->mnLen = len;
1162 nResult = 1;
1163 } else {
1164 if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG)
1165 nResult = 0;
1166 else {
1167 pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
1168 pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
1169 nResult = 1;
1170 }
1171 }
1172 } else
1173 nResult = 0;
1174 } else
1175 nResult = 0;
1177 return nResult;
1178 }
1181 static int isYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1182 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1183 {
1184 int nResult;
1186 nResult = isInPageYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
1188 if (nResult == 0)
1189 nResult = isInBlockYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
1191 return nResult;
1192 }
1194 /*
1195 * crc8 - calculate a crc8 over the given input data.
1196 *
1197 * table: crc table used for calculation.
1198 * pdata: pointer to data buffer.
1199 * nbytes: number of bytes in data buffer.
1200 * crc: previous returned crc8 value.
1201 */
1202 static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
1203 {
1204 /* loop over the buffer data */
1205 while (nbytes-- > 0)
1206 crc = table[(crc ^ *pdata++) & 0xff];
1208 return crc;
1209 }
1211 static int doSingleRegCheckSum(struct tas2557_priv *pTAS2557,
1212 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
1213 {
1214 int nResult = 0;
1215 struct TYCRC sCRCData;
1216 unsigned int nData1 = 0;
1218 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1219 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1220 && (nReg >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1221 && (nReg <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
1222 /* DSP swap command, pass */
1223 nResult = 0;
1224 goto end;
1225 }
1227 nResult = isYRAM(pTAS2557, &sCRCData, nBook, nPage, nReg, 1);
1228 if (nResult == 1) {
1229 nResult = pTAS2557->read(pTAS2557, TAS2557_REG(nBook, nPage, nReg), &nData1);
1230 if (nResult < 0)
1231 goto end;
1233 if (nData1 != nValue) {
1234 dev_err(pTAS2557->dev, "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1235 __LINE__, nBook, nPage, nReg, nValue, nData1);
1236 nResult = -EAGAIN;
1237 goto end;
1238 }
1240 nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0);
1241 }
1243 end:
1245 return nResult;
1246 }
1248 static int doMultiRegCheckSum(struct tas2557_priv *pTAS2557,
1249 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
1250 {
1251 int nResult = 0, i;
1252 unsigned char nCRCChkSum = 0;
1253 unsigned char nBuf1[128];
1254 struct TYCRC TCRCData;
1256 if ((nReg + len-1) > 127) {
1257 nResult = -EINVAL;
1258 dev_err(pTAS2557->dev, "firmware error\n");
1259 goto end;
1260 }
1262 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1263 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1264 && (nReg == TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1265 && (len == 4)) {
1266 /* DSP swap command, pass */
1267 nResult = 0;
1268 goto end;
1269 }
1271 nResult = isYRAM(pTAS2557, &TCRCData, nBook, nPage, nReg, len);
1272 if (nResult == 1) {
1273 if (len == 1) {
1274 dev_err(pTAS2557->dev, "firmware error\n");
1275 nResult = -EINVAL;
1276 goto end;
1277 } else {
1278 nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
1279 if (nResult < 0)
1280 goto end;
1282 for (i = 0; i < TCRCData.mnLen; i++) {
1283 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1284 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1285 && ((i + TCRCData.mnOffset)
1286 >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1287 && ((i + TCRCData.mnOffset)
1288 <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
1289 /* DSP swap command, bypass */
1290 continue;
1291 } else
1292 nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf1[i], 1, 0);
1293 }
1295 nResult = nCRCChkSum;
1296 }
1297 }
1299 end:
1301 return nResult;
1302 }
1304 static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock)
1305 {
1306 int nResult = 0;
1307 unsigned int nCommand = 0;
1308 unsigned char nBook;
1309 unsigned char nPage;
1310 unsigned char nOffset;
1311 unsigned char nData;
1312 unsigned int nLength;
1313 unsigned int nSleep;
1314 unsigned char nCRCChkSum = 0;
1315 unsigned int nValue1;
1316 int nRetry = 6;
1317 unsigned char *pData = pBlock->mpData;
1319 dev_dbg(pTAS2557->dev, "TAS2557 load block: Type = %d, commands = %d\n",
1320 pBlock->mnType, pBlock->mnCommands);
1321 start:
1322 if (pBlock->mbPChkSumPresent) {
1323 nResult = pTAS2557->write(pTAS2557, TAS2557_CRC_RESET_REG, 1);
1324 if (nResult < 0)
1325 goto end;
1326 }
1328 if (pBlock->mbYChkSumPresent)
1329 nCRCChkSum = 0;
1331 nCommand = 0;
1333 while (nCommand < pBlock->mnCommands) {
1334 pData = pBlock->mpData + nCommand * 4;
1336 nBook = pData[0];
1337 nPage = pData[1];
1338 nOffset = pData[2];
1339 nData = pData[3];
1341 nCommand++;
1343 if (nOffset <= 0x7F) {
1344 nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), nData);
1345 if (nResult < 0)
1346 goto end;
1347 if (pBlock->mbYChkSumPresent) {
1348 nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, nData);
1349 if (nResult < 0)
1350 goto check;
1351 nCRCChkSum += (unsigned char)nResult;
1352 }
1353 } else if (nOffset == 0x81) {
1354 nSleep = (nBook << 8) + nPage;
1355 msleep(nSleep);
1356 } else if (nOffset == 0x85) {
1357 pData += 4;
1358 nLength = (nBook << 8) + nPage;
1359 nBook = pData[0];
1360 nPage = pData[1];
1361 nOffset = pData[2];
1362 if (nLength > 1) {
1363 nResult = pTAS2557->bulk_write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData + 3, nLength);
1364 if (nResult < 0)
1365 goto end;
1366 if (pBlock->mbYChkSumPresent) {
1367 nResult = doMultiRegCheckSum(pTAS2557, nBook, nPage, nOffset, nLength);
1368 if (nResult < 0)
1369 goto check;
1370 nCRCChkSum += (unsigned char)nResult;
1371 }
1372 } else {
1373 nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData[3]);
1374 if (nResult < 0)
1375 goto end;
1376 if (pBlock->mbYChkSumPresent) {
1377 nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, pData[3]);
1378 if (nResult < 0)
1379 goto check;
1380 nCRCChkSum += (unsigned char)nResult;
1381 }
1382 }
1384 nCommand++;
1386 if (nLength >= 2)
1387 nCommand += ((nLength - 2) / 4) + 1;
1388 }
1389 }
1390 if (pBlock->mbPChkSumPresent) {
1391 nResult = pTAS2557->read(pTAS2557, TAS2557_CRC_CHECKSUM_REG, &nValue1);
1392 if (nResult < 0)
1393 goto end;
1394 if ((nValue1&0xff) != pBlock->mnPChkSum) {
1395 dev_err(pTAS2557->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
1396 pBlock->mnPChkSum, (nValue1&0xff));
1397 nResult = -EAGAIN;
1398 pTAS2557->mnErrCode |= ERROR_PRAM_CRCCHK;
1399 goto check;
1400 }
1402 nResult = 0;
1403 pTAS2557->mnErrCode &= ~ERROR_PRAM_CRCCHK;
1404 dev_dbg(pTAS2557->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
1405 }
1407 if (pBlock->mbYChkSumPresent) {
1408 if (nCRCChkSum != pBlock->mnYChkSum) {
1409 dev_err(pTAS2557->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
1410 pBlock->mnYChkSum, nCRCChkSum);
1411 nResult = -EAGAIN;
1412 pTAS2557->mnErrCode |= ERROR_YRAM_CRCCHK;
1413 goto check;
1414 }
1415 pTAS2557->mnErrCode &= ~ERROR_YRAM_CRCCHK;
1416 nResult = 0;
1417 dev_dbg(pTAS2557->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
1418 }
1420 check:
1421 if (nResult == -EAGAIN) {
1422 nRetry--;
1423 if (nRetry > 0)
1424 goto start;
1425 }
1427 end:
1428 if (nResult < 0) {
1429 dev_err(pTAS2557->dev, "Block (%d) load error\n",
1430 pBlock->mnType);
1431 }
1432 return nResult;
1433 }
1435 static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData, unsigned int nType)
1436 {
1437 int nResult = 0;
1438 unsigned int nBlock;
1439 struct TBlock *pBlock;
1441 dev_dbg(pTAS2557->dev,
1442 "TAS2557 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
1444 for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
1445 pBlock = &(pData->mpBlocks[nBlock]);
1446 if (pBlock->mnType == nType) {
1447 nResult = tas2557_load_block(pTAS2557, pBlock);
1448 if (nResult < 0)
1449 break;
1450 }
1451 }
1453 return nResult;
1454 }
1456 static int tas2557_load_configuration(struct tas2557_priv *pTAS2557,
1457 unsigned int nConfiguration, bool bLoadSame)
1458 {
1459 int nResult = 0;
1460 struct TConfiguration *pCurrentConfiguration = NULL;
1461 struct TConfiguration *pNewConfiguration = NULL;
1463 dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, nConfiguration);
1465 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1466 (!pTAS2557->mpFirmware->mpConfigurations)) {
1467 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1468 nResult = 0;
1469 goto end;
1470 }
1472 if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
1473 dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
1474 nConfiguration);
1475 nResult = 0;
1476 goto end;
1477 }
1479 if ((!pTAS2557->mbLoadConfigurationPrePowerUp)
1480 && (nConfiguration == pTAS2557->mnCurrentConfiguration)
1481 && (!bLoadSame)) {
1482 dev_info(pTAS2557->dev, "Configuration %d is already loaded\n",
1483 nConfiguration);
1484 nResult = 0;
1485 goto end;
1486 }
1488 pCurrentConfiguration =
1489 &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
1490 pNewConfiguration =
1491 &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
1492 if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
1493 dev_err(pTAS2557->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
1494 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
1495 nResult = 0;
1496 goto end;
1497 }
1499 if (pNewConfiguration->mnPLL >= pTAS2557->mpFirmware->mnPLLs) {
1500 dev_err(pTAS2557->dev, "Configuration %d, %s doesn't have a valid PLL index %d\n",
1501 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
1502 nResult = 0;
1503 goto end;
1504 }
1506 if (pTAS2557->mbPowerUp) {
1507 pTAS2557->mbLoadConfigurationPrePowerUp = false;
1508 nResult = tas2557_load_coefficient(pTAS2557, pTAS2557->mnCurrentConfiguration, nConfiguration, true);
1509 } else {
1510 dev_dbg(pTAS2557->dev,
1511 "TAS2557 was powered down, will load coefficient when power up\n");
1512 pTAS2557->mbLoadConfigurationPrePowerUp = true;
1513 pTAS2557->mnNewConfiguration = nConfiguration;
1514 }
1516 end:
1518 if (nResult < 0) {
1519 if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
1520 failsafe(pTAS2557);
1521 }
1523 return nResult;
1524 }
1526 int tas2557_set_config(struct tas2557_priv *pTAS2557, int config)
1527 {
1528 struct TConfiguration *pConfiguration;
1529 struct TProgram *pProgram;
1530 unsigned int nProgram = pTAS2557->mnCurrentProgram;
1531 unsigned int nConfiguration = config;
1532 int nResult = 0;
1534 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1535 (!pTAS2557->mpFirmware->mpConfigurations)) {
1536 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1537 nResult = -EINVAL;
1538 goto end;
1539 }
1541 if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
1542 dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
1543 nConfiguration);
1544 nResult = -EINVAL;
1545 goto end;
1546 }
1548 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
1549 pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
1551 if (nProgram != pConfiguration->mnProgram) {
1552 dev_err(pTAS2557->dev,
1553 "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
1554 nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
1555 nProgram, pProgram->mpName);
1556 nResult = -EINVAL;
1557 goto end;
1558 }
1560 nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
1562 end:
1564 return nResult;
1565 }
1567 void tas2557_clear_firmware(struct TFirmware *pFirmware)
1568 {
1569 unsigned int n, nn;
1571 if (!pFirmware)
1572 return;
1574 kfree(pFirmware->mpDescription);
1576 if (pFirmware->mpPLLs != NULL) {
1577 for (n = 0; n < pFirmware->mnPLLs; n++) {
1578 kfree(pFirmware->mpPLLs[n].mpDescription);
1579 kfree(pFirmware->mpPLLs[n].mBlock.mpData);
1580 }
1581 kfree(pFirmware->mpPLLs);
1582 }
1584 if (pFirmware->mpPrograms != NULL) {
1585 for (n = 0; n < pFirmware->mnPrograms; n++) {
1586 kfree(pFirmware->mpPrograms[n].mpDescription);
1587 kfree(pFirmware->mpPrograms[n].mData.mpDescription);
1588 for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
1589 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
1590 kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
1591 }
1592 kfree(pFirmware->mpPrograms);
1593 }
1595 if (pFirmware->mpConfigurations != NULL) {
1596 for (n = 0; n < pFirmware->mnConfigurations; n++) {
1597 kfree(pFirmware->mpConfigurations[n].mpDescription);
1598 kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
1599 for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
1600 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
1601 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
1602 }
1603 kfree(pFirmware->mpConfigurations);
1604 }
1606 if (pFirmware->mpCalibrations != NULL) {
1607 for (n = 0; n < pFirmware->mnCalibrations; n++) {
1608 kfree(pFirmware->mpCalibrations[n].mpDescription);
1609 kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
1610 for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
1611 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
1612 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
1613 }
1614 kfree(pFirmware->mpCalibrations);
1615 }
1617 memset(pFirmware, 0x00, sizeof(struct TFirmware));
1618 }
1620 static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, char *pFileName)
1621 {
1622 int nResult = 0;
1624 int nFile;
1625 mm_segment_t fs;
1626 unsigned char pBuffer[1000];
1627 int nSize = 0;
1629 dev_dbg(pTAS2557->dev, "%s:\n", __func__);
1631 fs = get_fs();
1632 set_fs(KERNEL_DS);
1633 nFile = sys_open(pFileName, O_RDONLY, 0);
1635 dev_info(pTAS2557->dev, "TAS2557 calibration file = %s, handle = %d\n",
1636 pFileName, nFile);
1638 if (nFile >= 0) {
1639 nSize = sys_read(nFile, pBuffer, 1000);
1640 sys_close(nFile);
1641 } else {
1642 dev_err(pTAS2557->dev, "TAS2557 cannot open calibration file: %s\n",
1643 pFileName);
1644 }
1646 set_fs(fs);
1648 if (!nSize)
1649 goto end;
1651 tas2557_clear_firmware(pTAS2557->mpCalFirmware);
1652 dev_info(pTAS2557->dev, "TAS2557 calibration file size = %d\n", nSize);
1653 nResult = fw_parse(pTAS2557, pTAS2557->mpCalFirmware, pBuffer, nSize);
1655 if (nResult)
1656 dev_err(pTAS2557->dev, "TAS2557 calibration file is corrupt\n");
1657 else
1658 dev_info(pTAS2557->dev, "TAS2557 calibration: %d calibrations\n",
1659 pTAS2557->mpCalFirmware->mnCalibrations);
1660 end:
1662 return nResult;
1663 }
1665 static bool tas2557_get_coefficient_in_block(struct tas2557_priv *pTAS2557,
1666 struct TBlock *pBlock, int nReg, int *pnValue)
1667 {
1668 int nCoefficient = 0;
1669 bool bFound = false;
1670 unsigned char *pCommands;
1671 int nBook, nPage, nOffset, len;
1672 int i, n;
1674 pCommands = pBlock->mpData;
1675 for (i = 0 ; i < pBlock->mnCommands;) {
1676 nBook = pCommands[4 * i + 0];
1677 nPage = pCommands[4 * i + 1];
1678 nOffset = pCommands[4 * i + 2];
1679 if ((nOffset < 0x7f) || (nOffset == 0x81))
1680 i++;
1681 else if (nOffset == 0x85) {
1682 len = ((int)nBook << 8) | nPage;
1683 nBook = pCommands[4 * i + 4];
1684 nPage = pCommands[4 * i + 5];
1685 nOffset = pCommands[4 * i + 6];
1686 n = 4 * i + 7;
1687 i += 2;
1688 i += ((len - 1) / 4);
1689 if ((len - 1) % 4)
1690 i++;
1691 if ((nBook != TAS2557_BOOK_ID(nReg))
1692 || (nPage != TAS2557_PAGE_ID(nReg)))
1693 continue;
1694 if (nOffset > TAS2557_PAGE_REG(nReg))
1695 continue;
1696 if ((len + nOffset) >= (TAS2557_PAGE_REG(nReg) + 4)) {
1697 n += (TAS2557_PAGE_REG(nReg) - nOffset);
1698 nCoefficient = ((int)pCommands[n] << 24)
1699 | ((int)pCommands[n + 1] << 16)
1700 | ((int)pCommands[n + 2] << 8)
1701 | (int)pCommands[n + 3];
1702 bFound = true;
1703 break;
1704 }
1705 } else {
1706 dev_err(pTAS2557->dev, "%s, format error %d\n", __func__, nOffset);
1707 break;
1708 }
1709 }
1711 if (bFound) {
1712 *pnValue = nCoefficient;
1713 dev_dbg(pTAS2557->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", __func__,
1714 TAS2557_BOOK_ID(nReg), TAS2557_PAGE_ID(nReg), TAS2557_PAGE_REG(nReg),
1715 nCoefficient);
1716 }
1718 return bFound;
1719 }
1721 static bool tas2557_get_coefficient_in_data(struct tas2557_priv *pTAS2557,
1722 struct TData *pData, int blockType, int nReg, int *pnValue)
1723 {
1724 bool bFound = false;
1725 struct TBlock *pBlock;
1726 int i;
1728 for (i = 0; i < pData->mnBlocks; i++) {
1729 pBlock = &(pData->mpBlocks[i]);
1730 if (pBlock->mnType == blockType) {
1731 bFound = tas2557_get_coefficient_in_block(pTAS2557,
1732 pBlock, nReg, pnValue);
1733 if (bFound)
1734 break;
1735 }
1736 }
1738 return bFound;
1739 }
1741 static bool tas2557_find_Tmax_in_configuration(struct tas2557_priv *pTAS2557,
1742 struct TConfiguration *pConfiguration, int *pnTMax)
1743 {
1744 struct TData *pData;
1745 bool bFound = false;
1746 int nBlockType, nReg, nCoefficient;
1748 if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
1749 nReg = TAS2557_PG2P1_CALI_T_REG;
1750 else
1751 nReg = TAS2557_PG1P0_CALI_T_REG;
1753 nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A;
1755 pData = &(pConfiguration->mData);
1756 bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCoefficient);
1757 if (bFound)
1758 *pnTMax = nCoefficient;
1760 return bFound;
1761 }
1763 void tas2557_fw_ready(const struct firmware *pFW, void *pContext)
1764 {
1765 struct tas2557_priv *pTAS2557 = (struct tas2557_priv *) pContext;
1766 int nResult;
1767 unsigned int nProgram = 0;
1768 unsigned int nSampleRate = 0;
1770 #ifdef CONFIG_TAS2557_CODEC
1771 mutex_lock(&pTAS2557->codec_lock);
1772 #endif
1774 #ifdef CONFIG_TAS2557_MISC
1775 mutex_lock(&pTAS2557->file_lock);
1776 #endif
1778 dev_info(pTAS2557->dev, "%s:\n", __func__);
1780 if (unlikely(!pFW) || unlikely(!pFW->data)) {
1781 dev_err(pTAS2557->dev, "%s firmware is not loaded.\n",
1782 TAS2557_FW_NAME);
1783 goto end;
1784 }
1786 if (pTAS2557->mpFirmware->mpConfigurations) {
1787 nProgram = pTAS2557->mnCurrentProgram;
1788 nSampleRate = pTAS2557->mnCurrentSampleRate;
1789 dev_dbg(pTAS2557->dev, "clear current firmware\n");
1790 tas2557_clear_firmware(pTAS2557->mpFirmware);
1791 }
1793 nResult = fw_parse(pTAS2557, pTAS2557->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
1794 release_firmware(pFW);
1795 if (nResult < 0) {
1796 dev_err(pTAS2557->dev, "firmware is corrupt\n");
1797 goto end;
1798 }
1800 if (!pTAS2557->mpFirmware->mnPrograms) {
1801 dev_err(pTAS2557->dev, "firmware contains no programs\n");
1802 nResult = -EINVAL;
1803 goto end;
1804 }
1806 if (!pTAS2557->mpFirmware->mnConfigurations) {
1807 dev_err(pTAS2557->dev, "firmware contains no configurations\n");
1808 nResult = -EINVAL;
1809 goto end;
1810 }
1812 if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
1813 dev_info(pTAS2557->dev,
1814 "no previous program, set to default\n");
1815 nProgram = 0;
1816 }
1818 pTAS2557->mnCurrentSampleRate = nSampleRate;
1819 nResult = tas2557_set_program(pTAS2557, nProgram, -1);
1821 end:
1822 ;
1823 #ifdef CONFIG_TAS2557_CODEC
1824 mutex_unlock(&pTAS2557->codec_lock);
1825 #endif
1827 #ifdef CONFIG_TAS2557_MISC
1828 mutex_unlock(&pTAS2557->file_lock);
1829 #endif
1830 }
1832 int tas2557_set_program(struct tas2557_priv *pTAS2557,
1833 unsigned int nProgram, int nConfig)
1834 {
1835 struct TProgram *pProgram;
1836 unsigned int nConfiguration = 0;
1837 unsigned int nSampleRate = 0;
1838 unsigned char nGain;
1839 bool bFound = false;
1840 int nResult = 0;
1842 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1843 (!pTAS2557->mpFirmware->mpConfigurations)) {
1844 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1845 nResult = 0;
1846 goto end;
1847 }
1849 if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
1850 dev_err(pTAS2557->dev, "TAS2557: Program %d doesn't exist\n",
1851 nProgram);
1852 nResult = 0;
1853 goto end;
1854 }
1856 if (nConfig < 0) {
1857 nConfiguration = 0;
1858 nSampleRate = pTAS2557->mnCurrentSampleRate;
1859 while (!bFound && (nConfiguration < pTAS2557->mpFirmware->mnConfigurations)) {
1860 if (pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
1861 if (nSampleRate == 0) {
1862 bFound = true;
1863 dev_info(pTAS2557->dev, "find default configuration %d\n", nConfiguration);
1864 } else if (nSampleRate == pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
1865 bFound = true;
1866 dev_info(pTAS2557->dev, "find matching configuration %d\n", nConfiguration);
1867 } else {
1868 nConfiguration++;
1869 }
1870 } else {
1871 nConfiguration++;
1872 }
1873 }
1874 if (!bFound) {
1875 dev_err(pTAS2557->dev,
1876 "Program %d, no valid configuration found for sample rate %d, ignore\n",
1877 nProgram, nSampleRate);
1878 nResult = 0;
1879 goto end;
1880 }
1881 } else {
1882 if (pTAS2557->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
1883 dev_err(pTAS2557->dev, "%s, configuration program doesn't match\n", __func__);
1884 nResult = 0;
1885 goto end;
1886 }
1887 nConfiguration = nConfig;
1888 }
1890 pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
1891 if (pTAS2557->mbPowerUp) {
1892 dev_info(pTAS2557->dev,
1893 "device powered up, power down to load program %d (%s)\n",
1894 nProgram, pProgram->mpName);
1895 if (hrtimer_active(&pTAS2557->mtimer))
1896 hrtimer_cancel(&pTAS2557->mtimer);
1898 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
1899 pTAS2557->enableIRQ(pTAS2557, false, false);
1901 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
1902 if (nResult < 0)
1903 goto end;
1904 }
1906 pTAS2557->hw_reset(pTAS2557);
1907 nResult = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
1908 if (nResult < 0)
1909 goto end;
1910 msleep(1);
1911 nResult = tas2557_load_default(pTAS2557);
1912 if (nResult < 0)
1913 goto end;
1915 dev_info(pTAS2557->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
1916 nResult = tas2557_load_data(pTAS2557, &(pProgram->mData), TAS2557_BLOCK_PGM_DEV_A);
1917 if (nResult < 0)
1918 goto end;
1919 pTAS2557->mnCurrentProgram = nProgram;
1921 nResult = tas2557_get_DAC_gain(pTAS2557, &nGain);
1922 if (nResult < 0)
1923 goto end;
1924 pTAS2557->mnDevGain = nGain;
1925 pTAS2557->mnDevCurrentGain = nGain;
1927 nResult = tas2557_load_coefficient(pTAS2557, -1, nConfiguration, false);
1928 if (nResult < 0)
1929 goto end;
1931 tas2557_update_edge(pTAS2557);
1933 if (pTAS2557->mbPowerUp) {
1934 pTAS2557->clearIRQ(pTAS2557);
1935 dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
1936 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
1937 if (nResult < 0)
1938 goto end;
1939 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1940 nResult = tas2557_checkPLL(pTAS2557);
1941 if (nResult < 0) {
1942 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
1943 pTAS2557->mbPowerUp = false;
1944 goto end;
1945 }
1946 }
1947 dev_dbg(pTAS2557->dev, "device powered up, load unmute\n");
1948 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
1949 if (nResult < 0)
1950 goto end;
1952 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1953 pTAS2557->enableIRQ(pTAS2557, true, true);
1954 if (!hrtimer_active(&pTAS2557->mtimer)) {
1955 pTAS2557->mnDieTvReadCounter = 0;
1956 hrtimer_start(&pTAS2557->mtimer,
1957 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1958 }
1959 }
1960 }
1962 end:
1964 if (nResult < 0) {
1965 if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
1966 failsafe(pTAS2557);
1967 }
1968 return nResult;
1969 }
1971 int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration)
1972 {
1973 struct TCalibration *pCalibration = NULL;
1974 struct TConfiguration *pConfiguration;
1975 struct TProgram *pProgram;
1976 int nTmax = 0;
1977 bool bFound = false;
1978 int nResult = 0;
1980 if ((!pTAS2557->mpFirmware->mpPrograms)
1981 || (!pTAS2557->mpFirmware->mpConfigurations)) {
1982 dev_err(pTAS2557->dev, "Firmware not loaded\n\r");
1983 nResult = 0;
1984 goto end;
1985 }
1987 if (nCalibration == 0x00FF) {
1988 nResult = tas2557_load_calibration(pTAS2557, TAS2557_CAL_NAME);
1989 if (nResult < 0) {
1990 dev_info(pTAS2557->dev, "load new calibration file %s fail %d\n",
1991 TAS2557_CAL_NAME, nResult);
1992 goto end;
1993 }
1994 nCalibration = 0;
1995 }
1997 if (nCalibration >= pTAS2557->mpCalFirmware->mnCalibrations) {
1998 dev_err(pTAS2557->dev,
1999 "Calibration %d doesn't exist\n", nCalibration);
2000 nResult = 0;
2001 goto end;
2002 }
2004 pTAS2557->mnCurrentCalibration = nCalibration;
2005 if (pTAS2557->mbLoadConfigurationPrePowerUp)
2006 goto end;
2008 pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[nCalibration]);
2009 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
2010 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
2011 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
2012 if (pTAS2557->mbBypassTMax) {
2013 bFound = tas2557_find_Tmax_in_configuration(pTAS2557, pConfiguration, &nTmax);
2014 if (bFound && (nTmax == TAS2557_COEFFICIENT_TMAX)) {
2015 dev_dbg(pTAS2557->dev, "%s, config[%s] bypass load calibration\n",
2016 __func__, pConfiguration->mpName);
2017 goto end;
2018 }
2019 }
2021 dev_dbg(pTAS2557->dev, "%s, load calibration\n", __func__);
2022 nResult = tas2557_load_data(pTAS2557, &(pCalibration->mData), TAS2557_BLOCK_CFG_COEFF_DEV_A);
2023 if (nResult < 0)
2024 goto end;
2025 }
2027 end:
2028 if (nResult < 0) {
2029 tas2557_clear_firmware(pTAS2557->mpCalFirmware);
2030 nResult = tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, pTAS2557->mnCurrentConfiguration);
2031 }
2033 return nResult;
2034 }
2036 bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0)
2037 {
2038 struct TCalibration *pCalibration;
2039 struct TData *pData;
2040 int nReg;
2041 int nCali_Re;
2042 bool bFound = false;
2043 int nBlockType;
2045 if (!pTAS2557->mpCalFirmware->mnCalibrations) {
2046 dev_err(pTAS2557->dev, "%s, no calibration data\n", __func__);
2047 goto end;
2048 }
2050 if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
2051 nReg = TAS2557_PG2P1_CALI_R0_REG;
2052 else
2053 nReg = TAS2557_PG1P0_CALI_R0_REG;
2055 nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A;
2057 pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[pTAS2557->mnCurrentCalibration]);
2058 pData = &(pCalibration->mData);
2060 bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCali_Re);
2062 end:
2064 if (bFound)
2065 *prm_r0 = nCali_Re;
2067 return bFound;
2068 }
2070 int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557)
2071 {
2072 struct device_node *np = dev->of_node;
2073 int rc = 0, ret = 0;
2074 unsigned int value;
2076 pTAS2557->mnResetGPIO = of_get_named_gpio(np, "ti,cdc-reset-gpio", 0);
2077 if (!gpio_is_valid(pTAS2557->mnResetGPIO)) {
2078 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2079 "ti,cdc-reset-gpio", np->full_name,
2080 pTAS2557->mnResetGPIO);
2081 ret = -EINVAL;
2082 goto end;
2083 } else
2084 dev_dbg(pTAS2557->dev, "ti,cdc-reset-gpio=%d\n", pTAS2557->mnResetGPIO);
2086 pTAS2557->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0);
2087 if (!gpio_is_valid(pTAS2557->mnGpioINT))
2088 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2089 "ti,irq-gpio", np->full_name,
2090 pTAS2557->mnGpioINT);
2093 rc = of_property_read_u32(np, "ti,i2s-bits", &value);
2094 if (rc)
2095 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2096 "ti,i2s-bits", np->full_name, rc);
2097 else
2098 pTAS2557->mnI2SBits = value;
2100 rc = of_property_read_u32(np, "ti,bypass-tmax", &value);
2101 if (rc)
2102 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2103 "ti,bypass-tmax", np->full_name, rc);
2104 else
2105 pTAS2557->mbBypassTMax = (value > 0);
2107 end:
2109 return ret;
2110 }
2112 MODULE_AUTHOR("Texas Instruments Inc.");
2113 MODULE_DESCRIPTION("TAS2557 common functions for Android Linux");
2114 MODULE_LICENSE("GPL v2");