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 dev_err(pTAS2557->dev, "%s\n", __func__);
295 pTAS2557->mnErrCode |= ERROR_FAILSAFE;
296 if (hrtimer_active(&pTAS2557->mtimer))
297 hrtimer_cancel(&pTAS2557->mtimer);
299 if(pTAS2557->mnRestart < RESTART_MAX)
300 {
301 pTAS2557->mnRestart ++;
302 msleep(100);
303 dev_err(pTAS2557->dev, "I2C COMM error, restart SmartAmp.\n");
304 schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(100));
305 return;
306 }
307 pTAS2557->enableIRQ(pTAS2557, false, false);
308 tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
309 pTAS2557->mbPowerUp = false;
310 pTAS2557->hw_reset(pTAS2557);
311 pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
312 udelay(1000);
313 pTAS2557->write(pTAS2557, TAS2557_SPK_CTRL_REG, 0x04);
314 if (pTAS2557->mpFirmware != NULL)
315 tas2557_clear_firmware(pTAS2557->mpFirmware);
316 }
318 int tas2557_checkPLL(struct tas2557_priv *pTAS2557)
319 {
320 int nResult = 0;
321 /*
322 * TO DO
323 */
325 return nResult;
326 }
328 /*
329 * tas2557_load_coefficient
330 */
331 static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557,
332 int nPrevConfig, int nNewConfig, bool bPowerOn)
333 {
334 int nResult = 0;
335 struct TPLL *pPLL;
336 struct TProgram *pProgram;
337 struct TConfiguration *pPrevConfiguration;
338 struct TConfiguration *pNewConfiguration;
339 bool bRestorePower = false;
341 if (!pTAS2557->mpFirmware->mnConfigurations) {
342 dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
343 goto end;
344 }
346 if (nNewConfig >= pTAS2557->mpFirmware->mnConfigurations) {
347 dev_err(pTAS2557->dev, "%s, invalid configuration New=%d, total=%d\n",
348 __func__, nNewConfig, pTAS2557->mpFirmware->mnConfigurations);
349 goto end;
350 }
352 if (nPrevConfig < 0)
353 pPrevConfiguration = NULL;
354 else if (nPrevConfig == nNewConfig) {
355 dev_dbg(pTAS2557->dev, "%s, config [%d] already loaded\n",
356 __func__, nNewConfig);
357 goto end;
358 } else
359 pPrevConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nPrevConfig]);
361 pNewConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nNewConfig]);
362 pTAS2557->mnCurrentConfiguration = nNewConfig;
363 if (pPrevConfiguration) {
364 if (pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL) {
365 dev_dbg(pTAS2557->dev, "%s, PLL same\n", __func__);
366 goto prog_coefficient;
367 }
368 }
370 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
371 if (bPowerOn) {
372 dev_dbg(pTAS2557->dev, "%s, power down to load new PLL\n", __func__);
373 if (hrtimer_active(&pTAS2557->mtimer))
374 hrtimer_cancel(&pTAS2557->mtimer);
376 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
377 pTAS2557->enableIRQ(pTAS2557, false, false);
379 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
380 if (nResult < 0)
381 goto end;
382 bRestorePower = true;
383 }
385 /* load PLL */
386 pPLL = &(pTAS2557->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
387 dev_dbg(pTAS2557->dev, "load PLL: %s block for Configuration %s\n",
388 pPLL->mpName, pNewConfiguration->mpName);
389 nResult = tas2557_load_block(pTAS2557, &(pPLL->mBlock));
390 if (nResult < 0)
391 goto end;
392 pTAS2557->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
394 dev_dbg(pTAS2557->dev, "load configuration %s conefficient pre block\n",
395 pNewConfiguration->mpName);
396 nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), TAS2557_BLOCK_CFG_PRE_DEV_A);
397 if (nResult < 0)
398 goto end;
400 prog_coefficient:
401 dev_dbg(pTAS2557->dev, "load new configuration: %s, coeff block data\n",
402 pNewConfiguration->mpName);
403 nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData),
404 TAS2557_BLOCK_CFG_COEFF_DEV_A);
405 if (nResult < 0)
406 goto end;
408 if (pTAS2557->mpCalFirmware->mnCalibrations) {
409 nResult = tas2557_set_calibration(pTAS2557, pTAS2557->mnCurrentCalibration);
410 if (nResult < 0)
411 goto end;
412 }
414 if (bRestorePower) {
415 pTAS2557->clearIRQ(pTAS2557);
416 dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
417 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
418 if (nResult < 0)
419 goto end;
420 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
421 nResult = tas2557_checkPLL(pTAS2557);
422 if (nResult < 0) {
423 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
424 pTAS2557->mbPowerUp = false;
425 goto end;
426 }
427 }
428 dev_dbg(pTAS2557->dev,
429 "device powered up, load unmute\n");
430 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
431 if (nResult < 0)
432 goto end;
433 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
434 pTAS2557->enableIRQ(pTAS2557, true, true);
435 if (!hrtimer_active(&pTAS2557->mtimer)) {
436 pTAS2557->mnDieTvReadCounter = 0;
437 hrtimer_start(&pTAS2557->mtimer,
438 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
439 }
440 }
441 }
442 end:
444 pTAS2557->mnNewConfiguration = pTAS2557->mnCurrentConfiguration;
445 return nResult;
446 }
448 int tas2557_update_edge(struct tas2557_priv *pTAS2557)
449 {
450 int nResult = 0;
451 dev_dbg(pTAS2557->dev,
452 "%s, edge: %d\n",
453 __func__, pTAS2557->mnEdge);
455 nResult = pTAS2557->update_bits(pTAS2557, TAS2557_SPK_CTRL_REG, 0x7, pTAS2557->mnEdge);
457 return nResult;
458 }
460 int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable)
461 {
462 int nResult = 0;
463 unsigned int nValue;
464 struct TProgram *pProgram;
466 dev_dbg(pTAS2557->dev, "Enable: %d\n", bEnable);
468 if ((pTAS2557->mpFirmware->mnPrograms == 0)
469 || (pTAS2557->mpFirmware->mnConfigurations == 0)) {
470 dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__);
471 goto end;
472 }
473 /* check safe guard*/
474 nResult = pTAS2557->read(pTAS2557, TAS2557_SAFE_GUARD_REG, &nValue);
475 if (nResult < 0)
476 goto end;
477 if ((nValue&0xff) != TAS2557_SAFE_GUARD_PATTERN) {
478 dev_err(pTAS2557->dev, "ERROR safe guard failure!\n");
479 nResult = -EPIPE;
480 pTAS2557->mnErrCode = ERROR_SAFE_GUARD;
481 pTAS2557->mbPowerUp = true;
482 goto end;
483 }
485 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
486 if (bEnable) {
487 if (!pTAS2557->mbPowerUp) {
488 if (!pTAS2557->mbCalibrationLoaded) {
489 tas2557_set_calibration(pTAS2559, 0xFF);
490 pTAS2557->mbCalibrationLoaded = true;
491 }
493 if (pTAS2557->mbLoadConfigurationPrePowerUp) {
494 dev_dbg(pTAS2557->dev, "load coefficient before power\n");
495 pTAS2557->mbLoadConfigurationPrePowerUp = false;
496 nResult = tas2557_load_coefficient(pTAS2557,
497 pTAS2557->mnCurrentConfiguration, pTAS2557->mnNewConfiguration, false);
498 if (nResult < 0)
499 goto end;
500 }
502 pTAS2557->clearIRQ(pTAS2557);
503 /* power on device */
504 dev_dbg(pTAS2557->dev, "Enable: load startup sequence\n");
505 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
506 if (nResult < 0)
507 goto end;
508 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
509 nResult = tas2557_checkPLL(pTAS2557);
510 if (nResult < 0) {
511 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
512 goto end;
513 }
514 }
515 dev_dbg(pTAS2557->dev, "Enable: load unmute sequence\n");
516 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
517 if (nResult < 0)
518 goto end;
520 pTAS2557->mbPowerUp = true;
522 tas2557_get_die_temperature(pTAS2770, &nValue);
523 if(nValue == 0x80000000)
524 {
525 dev_err(pTAS2557->dev, "%s, thermal sensor is wrong, mute output\n", __func__);
526 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
527 pTAS2557->mbPowerUp = false;
528 goto end;
529 }
531 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
532 /* turn on IRQ */
533 pTAS2557->enableIRQ(pTAS2557, true, true);
534 if (!hrtimer_active(&pTAS2557->mtimer)) {
535 pTAS2557->mnDieTvReadCounter = 0;
536 hrtimer_start(&pTAS2557->mtimer,
537 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
538 }
539 }
540 pTAS2557->mnRestart = 0;
541 }
542 } else {
543 if (pTAS2557->mbPowerUp) {
544 if (hrtimer_active(&pTAS2557->mtimer))
545 hrtimer_cancel(&pTAS2557->mtimer);
547 dev_dbg(pTAS2557->dev, "Enable: load shutdown sequence\n");
548 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
549 /* turn off IRQ */
550 pTAS2557->enableIRQ(pTAS2557, false, false);
551 }
552 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
553 if (nResult < 0)
554 goto end;
556 pTAS2557->mbPowerUp = false;
557 pTAS2557->mnRestart = 0;
558 }
559 }
561 nResult = 0;
563 end:
564 if (nResult < 0) {
565 if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK | ERROR_SAFE_GUARD))
566 failsafe(pTAS2557);
567 }
569 return nResult;
570 }
572 int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate)
573 {
574 int nResult = 0;
575 struct TConfiguration *pConfiguration;
576 unsigned int nConfiguration;
578 dev_dbg(pTAS2557->dev, "tas2557_setup_clocks: nSamplingRate = %d [Hz]\n",
579 nSamplingRate);
581 if ((!pTAS2557->mpFirmware->mpPrograms) ||
582 (!pTAS2557->mpFirmware->mpConfigurations)) {
583 dev_err(pTAS2557->dev, "Firmware not loaded\n");
584 nResult = -EINVAL;
585 goto end;
586 }
588 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
589 if (pConfiguration->mnSamplingRate == nSamplingRate) {
590 dev_info(pTAS2557->dev, "Sampling rate for current configuration matches: %d\n",
591 nSamplingRate);
592 nResult = 0;
593 goto end;
594 }
596 for (nConfiguration = 0;
597 nConfiguration < pTAS2557->mpFirmware->mnConfigurations;
598 nConfiguration++) {
599 pConfiguration =
600 &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
601 if ((pConfiguration->mnSamplingRate == nSamplingRate)
602 && (pConfiguration->mnProgram == pTAS2557->mnCurrentProgram)) {
603 dev_info(pTAS2557->dev,
604 "Found configuration: %s, with compatible sampling rate %d\n",
605 pConfiguration->mpName, nSamplingRate);
606 nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
607 goto end;
608 }
609 }
611 dev_err(pTAS2557->dev, "Cannot find a configuration that supports sampling rate: %d\n",
612 nSamplingRate);
614 end:
616 return nResult;
617 }
619 static void fw_print_header(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware)
620 {
621 dev_info(pTAS2557->dev, "FW Size = %d", pFirmware->mnFWSize);
622 dev_info(pTAS2557->dev, "Checksum = 0x%04X", pFirmware->mnChecksum);
623 dev_info(pTAS2557->dev, "PPC Version = 0x%04X", pFirmware->mnPPCVersion);
624 dev_info(pTAS2557->dev, "FW Version = 0x%04X", pFirmware->mnFWVersion);
625 dev_info(pTAS2557->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion);
626 dev_info(pTAS2557->dev, "Timestamp = %d", pFirmware->mnTimeStamp);
627 dev_info(pTAS2557->dev, "DDC Name = %s", pFirmware->mpDDCName);
628 dev_info(pTAS2557->dev, "Description = %s", pFirmware->mpDescription);
629 }
631 inline unsigned int fw_convert_number(unsigned char *pData)
632 {
633 return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24);
634 }
636 static int fw_parse_header(struct tas2557_priv *pTAS2557,
637 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
638 {
639 unsigned char *pDataStart = pData;
640 unsigned int n;
641 unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 };
643 if (nSize < 104) {
644 dev_err(pTAS2557->dev, "Firmware: Header too short");
645 return -EINVAL;
646 }
648 if (memcmp(pData, pMagicNumber, 4)) {
649 dev_err(pTAS2557->dev, "Firmware: Magic number doesn't match");
650 return -EINVAL;
651 }
652 pData += 4;
654 pFirmware->mnFWSize = fw_convert_number(pData);
655 pData += 4;
657 pFirmware->mnChecksum = fw_convert_number(pData);
658 pData += 4;
660 pFirmware->mnPPCVersion = fw_convert_number(pData);
661 pData += 4;
663 pFirmware->mnFWVersion = fw_convert_number(pData);
664 pData += 4;
666 pFirmware->mnDriverVersion = fw_convert_number(pData);
667 pData += 4;
669 pFirmware->mnTimeStamp = fw_convert_number(pData);
670 pData += 4;
672 memcpy(pFirmware->mpDDCName, pData, 64);
673 pData += 64;
675 n = strlen(pData);
676 pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
677 pData += n + 1;
678 if ((pData - pDataStart) >= nSize) {
679 dev_err(pTAS2557->dev, "Firmware: Header too short after DDC description");
680 return -EINVAL;
681 }
683 pFirmware->mnDeviceFamily = fw_convert_number(pData);
684 pData += 4;
685 if (pFirmware->mnDeviceFamily != 0) {
686 dev_err(pTAS2557->dev,
687 "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily);
688 return -EINVAL;
689 }
691 pFirmware->mnDevice = fw_convert_number(pData);
692 pData += 4;
694 if (pFirmware->mnDevice != 2) {
695 dev_err(pTAS2557->dev,
696 "device %d, not TAS2557 Dual Mono", pFirmware->mnDevice);
697 return -EINVAL;
698 }
700 fw_print_header(pTAS2557, pFirmware);
701 return pData - pDataStart;
702 }
704 static int fw_parse_block_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
705 struct TBlock *pBlock, unsigned char *pData)
706 {
707 unsigned char *pDataStart = pData;
708 unsigned int n;
710 pBlock->mnType = fw_convert_number(pData);
711 pData += 4;
713 if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) {
714 pBlock->mbPChkSumPresent = pData[0];
715 pData++;
717 pBlock->mnPChkSum = pData[0];
718 pData++;
720 pBlock->mbYChkSumPresent = pData[0];
721 pData++;
723 pBlock->mnYChkSum = pData[0];
724 pData++;
725 } else {
726 pBlock->mbPChkSumPresent = 0;
727 pBlock->mbYChkSumPresent = 0;
728 }
730 pBlock->mnCommands = fw_convert_number(pData);
731 pData += 4;
733 n = pBlock->mnCommands * 4;
734 pBlock->mpData = kmemdup(pData, n, GFP_KERNEL);
735 pData += n;
736 return pData - pDataStart;
737 }
739 static int fw_parse_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware,
740 struct TData *pImageData, unsigned char *pData)
741 {
742 unsigned char *pDataStart = pData;
743 unsigned int nBlock;
744 unsigned int n;
746 memcpy(pImageData->mpName, pData, 64);
747 pData += 64;
749 n = strlen(pData);
750 pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
751 pData += n + 1;
753 pImageData->mnBlocks = (pData[0] << 8) + pData[1];
754 pData += 2;
756 pImageData->mpBlocks =
757 kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL);
759 for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) {
760 n = fw_parse_block_data(pTAS2557, pFirmware,
761 &(pImageData->mpBlocks[nBlock]), pData);
762 pData += n;
763 }
764 return pData - pDataStart;
765 }
767 static int fw_parse_pll_data(struct tas2557_priv *pTAS2557,
768 struct TFirmware *pFirmware, unsigned char *pData)
769 {
770 unsigned char *pDataStart = pData;
771 unsigned int n;
772 unsigned int nPLL;
773 struct TPLL *pPLL;
775 pFirmware->mnPLLs = (pData[0] << 8) + pData[1];
776 pData += 2;
778 if (pFirmware->mnPLLs == 0)
779 goto end;
781 pFirmware->mpPLLs = kmalloc_array(pFirmware->mnPLLs, sizeof(struct TPLL), GFP_KERNEL);
782 for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) {
783 pPLL = &(pFirmware->mpPLLs[nPLL]);
785 memcpy(pPLL->mpName, pData, 64);
786 pData += 64;
788 n = strlen(pData);
789 pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
790 pData += n + 1;
792 n = fw_parse_block_data(pTAS2557, pFirmware, &(pPLL->mBlock), pData);
793 pData += n;
794 }
796 end:
797 return pData - pDataStart;
798 }
800 static int fw_parse_program_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 nProgram;
806 struct TProgram *pProgram;
808 pFirmware->mnPrograms = (pData[0] << 8) + pData[1];
809 pData += 2;
811 if (pFirmware->mnPrograms == 0)
812 goto end;
814 pFirmware->mpPrograms =
815 kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL);
816 for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) {
817 pProgram = &(pFirmware->mpPrograms[nProgram]);
818 memcpy(pProgram->mpName, pData, 64);
819 pData += 64;
821 n = strlen(pData);
822 pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
823 pData += n + 1;
825 pProgram->mnAppMode = pData[0];
826 pData++;
828 pProgram->mnBoost = (pData[0] << 8) + pData[1];
829 pData += 2;
831 n = fw_parse_data(pTAS2557, pFirmware, &(pProgram->mData), pData);
832 pData += n;
833 }
835 end:
837 return pData - pDataStart;
838 }
840 static int fw_parse_configuration_data(struct tas2557_priv *pTAS2557,
841 struct TFirmware *pFirmware, unsigned char *pData)
842 {
843 unsigned char *pDataStart = pData;
844 unsigned int n;
845 unsigned int nConfiguration;
846 struct TConfiguration *pConfiguration;
848 pFirmware->mnConfigurations = (pData[0] << 8) + pData[1];
849 pData += 2;
851 if (pFirmware->mnConfigurations == 0)
852 goto end;
854 pFirmware->mpConfigurations =
855 kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations,
856 GFP_KERNEL);
857 for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations;
858 nConfiguration++) {
859 pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]);
860 memcpy(pConfiguration->mpName, pData, 64);
861 pData += 64;
863 n = strlen(pData);
864 pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
865 pData += n + 1;
867 if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV)
868 || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC)
869 && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) {
870 pConfiguration->mnDevices = (pData[0] << 8) + pData[1];
871 pData += 2;
872 } else
873 pConfiguration->mnDevices = 1;
875 pConfiguration->mnProgram = pData[0];
876 pData++;
878 pConfiguration->mnPLL = pData[0];
879 pData++;
881 pConfiguration->mnSamplingRate = fw_convert_number(pData);
882 pData += 4;
884 if (pFirmware->mnDriverVersion >= PPC_DRIVER_MTPLLSRC) {
885 pConfiguration->mnPLLSrc = pData[0];
886 pData++;
888 pConfiguration->mnPLLSrcRate = fw_convert_number(pData);
889 pData += 4;
890 }
892 n = fw_parse_data(pTAS2557, pFirmware, &(pConfiguration->mData), pData);
893 pData += n;
894 }
896 end:
898 return pData - pDataStart;
899 }
901 int fw_parse_calibration_data(struct tas2557_priv *pTAS2557,
902 struct TFirmware *pFirmware, unsigned char *pData)
903 {
904 unsigned char *pDataStart = pData;
905 unsigned int n;
906 unsigned int nCalibration;
907 struct TCalibration *pCalibration;
909 pFirmware->mnCalibrations = (pData[0] << 8) + pData[1];
910 pData += 2;
912 if (pFirmware->mnCalibrations == 0)
913 goto end;
915 pFirmware->mpCalibrations =
916 kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL);
917 for (nCalibration = 0;
918 nCalibration < pFirmware->mnCalibrations;
919 nCalibration++) {
920 pCalibration = &(pFirmware->mpCalibrations[nCalibration]);
921 memcpy(pCalibration->mpName, pData, 64);
922 pData += 64;
924 n = strlen(pData);
925 pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL);
926 pData += n + 1;
928 pCalibration->mnProgram = pData[0];
929 pData++;
931 pCalibration->mnConfiguration = pData[0];
932 pData++;
934 n = fw_parse_data(pTAS2557, pFirmware, &(pCalibration->mData), pData);
935 pData += n;
936 }
938 end:
940 return pData - pDataStart;
941 }
943 static int fw_parse(struct tas2557_priv *pTAS2557,
944 struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize)
945 {
946 int nPosition = 0;
948 nPosition = fw_parse_header(pTAS2557, pFirmware, pData, nSize);
949 if (nPosition < 0) {
950 dev_err(pTAS2557->dev, "Firmware: Wrong Header");
951 return -EINVAL;
952 }
954 if (nPosition >= nSize) {
955 dev_err(pTAS2557->dev, "Firmware: Too short");
956 return -EINVAL;
957 }
959 pData += nPosition;
960 nSize -= nPosition;
961 nPosition = 0;
963 nPosition = fw_parse_pll_data(pTAS2557, pFirmware, pData);
965 pData += nPosition;
966 nSize -= nPosition;
967 nPosition = 0;
969 nPosition = fw_parse_program_data(pTAS2557, pFirmware, pData);
971 pData += nPosition;
972 nSize -= nPosition;
973 nPosition = 0;
975 nPosition = fw_parse_configuration_data(pTAS2557, pFirmware, pData);
977 pData += nPosition;
978 nSize -= nPosition;
979 nPosition = 0;
981 if (nSize > 64)
982 nPosition = fw_parse_calibration_data(pTAS2557, pFirmware, pData);
983 return 0;
984 }
987 static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = {
988 0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C,
989 0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5,
990 0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43,
991 0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA,
992 0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62,
993 0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB,
994 0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D,
995 0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4,
996 0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20,
997 0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89,
998 0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F,
999 0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96,
1000 0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E,
1001 0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7,
1002 0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01,
1003 0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8
1004 };
1006 static int isInPageYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1007 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1008 {
1009 int nResult = 0;
1011 if (nBook == TAS2557_YRAM_BOOK1) {
1012 if (nPage == TAS2557_YRAM1_PAGE) {
1013 if (nReg >= TAS2557_YRAM1_START_REG) {
1014 pCRCData->mnOffset = nReg;
1015 pCRCData->mnLen = len;
1016 nResult = 1;
1017 } else if ((nReg + len) > TAS2557_YRAM1_START_REG) {
1018 pCRCData->mnOffset = TAS2557_YRAM1_START_REG;
1019 pCRCData->mnLen = len - (TAS2557_YRAM1_START_REG - nReg);
1020 nResult = 1;
1021 } else
1022 nResult = 0;
1023 } else if (nPage == TAS2557_YRAM3_PAGE) {
1024 if (nReg > TAS2557_YRAM3_END_REG) {
1025 nResult = 0;
1026 } else if (nReg >= TAS2557_YRAM3_START_REG) {
1027 if ((nReg + len) > TAS2557_YRAM3_END_REG) {
1028 pCRCData->mnOffset = nReg;
1029 pCRCData->mnLen = TAS2557_YRAM3_END_REG - nReg + 1;
1030 nResult = 1;
1031 } else {
1032 pCRCData->mnOffset = nReg;
1033 pCRCData->mnLen = len;
1034 nResult = 1;
1035 }
1036 } else {
1037 if ((nReg + (len - 1)) < TAS2557_YRAM3_START_REG)
1038 nResult = 0;
1039 else {
1040 pCRCData->mnOffset = TAS2557_YRAM3_START_REG;
1041 pCRCData->mnLen = len - (TAS2557_YRAM3_START_REG - nReg);
1042 nResult = 1;
1043 }
1044 }
1045 }
1046 } else if (nBook == TAS2557_YRAM_BOOK2) {
1047 if (nPage == TAS2557_YRAM5_PAGE) {
1048 if (nReg > TAS2557_YRAM5_END_REG) {
1049 nResult = 0;
1050 } else if (nReg >= TAS2557_YRAM5_START_REG) {
1051 if ((nReg + len) > TAS2557_YRAM5_END_REG) {
1052 pCRCData->mnOffset = nReg;
1053 pCRCData->mnLen = TAS2557_YRAM5_END_REG - nReg + 1;
1054 nResult = 1;
1055 } else {
1056 pCRCData->mnOffset = nReg;
1057 pCRCData->mnLen = len;
1058 nResult = 1;
1059 }
1060 } else {
1061 if ((nReg + (len - 1)) < TAS2557_YRAM5_START_REG)
1062 nResult = 0;
1063 else {
1064 pCRCData->mnOffset = TAS2557_YRAM5_START_REG;
1065 pCRCData->mnLen = len - (TAS2557_YRAM5_START_REG - nReg);
1066 nResult = 1;
1067 }
1068 }
1069 }
1070 } else
1071 nResult = 0;
1073 return nResult;
1074 }
1076 static int isInBlockYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1077 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1078 {
1079 int nResult;
1081 if (nBook == TAS2557_YRAM_BOOK1) {
1082 if (nPage < TAS2557_YRAM2_START_PAGE)
1083 nResult = 0;
1084 else if (nPage <= TAS2557_YRAM2_END_PAGE) {
1085 if (nReg > TAS2557_YRAM2_END_REG)
1086 nResult = 0;
1087 else if (nReg >= TAS2557_YRAM2_START_REG) {
1088 pCRCData->mnOffset = nReg;
1089 pCRCData->mnLen = len;
1090 nResult = 1;
1091 } else {
1092 if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG)
1093 nResult = 0;
1094 else {
1095 pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
1096 pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
1097 nResult = 1;
1098 }
1099 }
1100 } else
1101 nResult = 0;
1102 } else if (nBook == TAS2557_YRAM_BOOK2) {
1103 if (nPage < TAS2557_YRAM4_START_PAGE)
1104 nResult = 0;
1105 else if (nPage <= TAS2557_YRAM4_END_PAGE) {
1106 if (nReg > TAS2557_YRAM2_END_REG)
1107 nResult = 0;
1108 else if (nReg >= TAS2557_YRAM2_START_REG) {
1109 pCRCData->mnOffset = nReg;
1110 pCRCData->mnLen = len;
1111 nResult = 1;
1112 } else {
1113 if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG)
1114 nResult = 0;
1115 else {
1116 pCRCData->mnOffset = TAS2557_YRAM2_START_REG;
1117 pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG;
1118 nResult = 1;
1119 }
1120 }
1121 } else
1122 nResult = 0;
1123 } else
1124 nResult = 0;
1126 return nResult;
1127 }
1130 static int isYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData,
1131 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
1132 {
1133 int nResult;
1135 nResult = isInPageYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
1137 if (nResult == 0)
1138 nResult = isInBlockYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len);
1140 return nResult;
1141 }
1143 /*
1144 * crc8 - calculate a crc8 over the given input data.
1145 *
1146 * table: crc table used for calculation.
1147 * pdata: pointer to data buffer.
1148 * nbytes: number of bytes in data buffer.
1149 * crc: previous returned crc8 value.
1150 */
1151 static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc)
1152 {
1153 /* loop over the buffer data */
1154 while (nbytes-- > 0)
1155 crc = table[(crc ^ *pdata++) & 0xff];
1157 return crc;
1158 }
1160 static int doSingleRegCheckSum(struct tas2557_priv *pTAS2557,
1161 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue)
1162 {
1163 int nResult = 0;
1164 struct TYCRC sCRCData;
1165 unsigned int nData1 = 0;
1167 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1168 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1169 && (nReg >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1170 && (nReg <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
1171 /* DSP swap command, pass */
1172 nResult = 0;
1173 goto end;
1174 }
1176 nResult = isYRAM(pTAS2557, &sCRCData, nBook, nPage, nReg, 1);
1177 if (nResult == 1) {
1178 nResult = pTAS2557->read(pTAS2557, TAS2557_REG(nBook, nPage, nReg), &nData1);
1179 if (nResult < 0)
1180 goto end;
1182 if (nData1 != nValue) {
1183 dev_err(pTAS2557->dev, "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1184 __LINE__, nBook, nPage, nReg, nValue, nData1);
1185 nResult = -EAGAIN;
1186 goto end;
1187 }
1189 nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0);
1190 }
1192 end:
1194 return nResult;
1195 }
1197 static int doMultiRegCheckSum(struct tas2557_priv *pTAS2557,
1198 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len)
1199 {
1200 int nResult = 0, i;
1201 unsigned char nCRCChkSum = 0;
1202 unsigned char nBuf1[128];
1203 struct TYCRC TCRCData;
1205 if ((nReg + len-1) > 127) {
1206 nResult = -EINVAL;
1207 dev_err(pTAS2557->dev, "firmware error\n");
1208 goto end;
1209 }
1211 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1212 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1213 && (nReg == TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1214 && (len == 4)) {
1215 /* DSP swap command, pass */
1216 nResult = 0;
1217 goto end;
1218 }
1220 nResult = isYRAM(pTAS2557, &TCRCData, nBook, nPage, nReg, len);
1221 if (nResult == 1) {
1222 if (len == 1) {
1223 dev_err(pTAS2557->dev, "firmware error\n");
1224 nResult = -EINVAL;
1225 goto end;
1226 } else {
1227 nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen);
1228 if (nResult < 0)
1229 goto end;
1231 for (i = 0; i < TCRCData.mnLen; i++) {
1232 if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG))
1233 && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG))
1234 && ((i + TCRCData.mnOffset)
1235 >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG))
1236 && ((i + TCRCData.mnOffset)
1237 <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) {
1238 /* DSP swap command, bypass */
1239 continue;
1240 } else
1241 nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf1[i], 1, 0);
1242 }
1244 nResult = nCRCChkSum;
1245 }
1246 }
1248 end:
1250 return nResult;
1251 }
1253 static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock)
1254 {
1255 int nResult = 0;
1256 unsigned int nCommand = 0;
1257 unsigned char nBook;
1258 unsigned char nPage;
1259 unsigned char nOffset;
1260 unsigned char nData;
1261 unsigned int nLength;
1262 unsigned int nSleep;
1263 unsigned char nCRCChkSum = 0;
1264 unsigned int nValue1;
1265 int nRetry = 6;
1266 unsigned char *pData = pBlock->mpData;
1268 dev_dbg(pTAS2557->dev, "TAS2557 load block: Type = %d, commands = %d\n",
1269 pBlock->mnType, pBlock->mnCommands);
1270 start:
1271 if (pBlock->mbPChkSumPresent) {
1272 nResult = pTAS2557->write(pTAS2557, TAS2557_CRC_RESET_REG, 1);
1273 if (nResult < 0)
1274 goto end;
1275 }
1277 if (pBlock->mbYChkSumPresent)
1278 nCRCChkSum = 0;
1280 nCommand = 0;
1282 while (nCommand < pBlock->mnCommands) {
1283 pData = pBlock->mpData + nCommand * 4;
1285 nBook = pData[0];
1286 nPage = pData[1];
1287 nOffset = pData[2];
1288 nData = pData[3];
1290 nCommand++;
1292 if (nOffset <= 0x7F) {
1293 nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), nData);
1294 if (nResult < 0)
1295 goto end;
1296 if (pBlock->mbYChkSumPresent) {
1297 nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, nData);
1298 if (nResult < 0)
1299 goto check;
1300 nCRCChkSum += (unsigned char)nResult;
1301 }
1302 } else if (nOffset == 0x81) {
1303 nSleep = (nBook << 8) + nPage;
1304 msleep(nSleep);
1305 } else if (nOffset == 0x85) {
1306 pData += 4;
1307 nLength = (nBook << 8) + nPage;
1308 nBook = pData[0];
1309 nPage = pData[1];
1310 nOffset = pData[2];
1311 if (nLength > 1) {
1312 nResult = pTAS2557->bulk_write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData + 3, nLength);
1313 if (nResult < 0)
1314 goto end;
1315 if (pBlock->mbYChkSumPresent) {
1316 nResult = doMultiRegCheckSum(pTAS2557, nBook, nPage, nOffset, nLength);
1317 if (nResult < 0)
1318 goto check;
1319 nCRCChkSum += (unsigned char)nResult;
1320 }
1321 } else {
1322 nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData[3]);
1323 if (nResult < 0)
1324 goto end;
1325 if (pBlock->mbYChkSumPresent) {
1326 nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, pData[3]);
1327 if (nResult < 0)
1328 goto check;
1329 nCRCChkSum += (unsigned char)nResult;
1330 }
1331 }
1333 nCommand++;
1335 if (nLength >= 2)
1336 nCommand += ((nLength - 2) / 4) + 1;
1337 }
1338 }
1339 if (pBlock->mbPChkSumPresent) {
1340 nResult = pTAS2557->read(pTAS2557, TAS2557_CRC_CHECKSUM_REG, &nValue1);
1341 if (nResult < 0)
1342 goto end;
1343 if ((nValue1&0xff) != pBlock->mnPChkSum) {
1344 dev_err(pTAS2557->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
1345 pBlock->mnPChkSum, (nValue1&0xff));
1346 nResult = -EAGAIN;
1347 pTAS2557->mnErrCode |= ERROR_PRAM_CRCCHK;
1348 goto check;
1349 }
1351 nResult = 0;
1352 pTAS2557->mnErrCode &= ~ERROR_PRAM_CRCCHK;
1353 dev_dbg(pTAS2557->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
1354 }
1356 if (pBlock->mbYChkSumPresent) {
1357 if (nCRCChkSum != pBlock->mnYChkSum) {
1358 dev_err(pTAS2557->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
1359 pBlock->mnYChkSum, nCRCChkSum);
1360 nResult = -EAGAIN;
1361 pTAS2557->mnErrCode |= ERROR_YRAM_CRCCHK;
1362 goto check;
1363 }
1364 pTAS2557->mnErrCode &= ~ERROR_YRAM_CRCCHK;
1365 nResult = 0;
1366 dev_dbg(pTAS2557->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
1367 }
1369 check:
1370 if (nResult == -EAGAIN) {
1371 nRetry--;
1372 if (nRetry > 0)
1373 goto start;
1374 }
1376 end:
1377 if (nResult < 0) {
1378 dev_err(pTAS2557->dev, "Block (%d) load error\n",
1379 pBlock->mnType);
1380 }
1381 return nResult;
1382 }
1384 static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData, unsigned int nType)
1385 {
1386 int nResult = 0;
1387 unsigned int nBlock;
1388 struct TBlock *pBlock;
1390 dev_dbg(pTAS2557->dev,
1391 "TAS2557 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType);
1393 for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
1394 pBlock = &(pData->mpBlocks[nBlock]);
1395 if (pBlock->mnType == nType) {
1396 nResult = tas2557_load_block(pTAS2557, pBlock);
1397 if (nResult < 0)
1398 break;
1399 }
1400 }
1402 return nResult;
1403 }
1405 static int tas2557_load_configuration(struct tas2557_priv *pTAS2557,
1406 unsigned int nConfiguration, bool bLoadSame)
1407 {
1408 int nResult = 0;
1409 struct TConfiguration *pCurrentConfiguration = NULL;
1410 struct TConfiguration *pNewConfiguration = NULL;
1412 dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, nConfiguration);
1414 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1415 (!pTAS2557->mpFirmware->mpConfigurations)) {
1416 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1417 nResult = 0;
1418 goto end;
1419 }
1421 if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
1422 dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
1423 nConfiguration);
1424 nResult = 0;
1425 goto end;
1426 }
1428 if ((!pTAS2557->mbLoadConfigurationPrePowerUp)
1429 && (nConfiguration == pTAS2557->mnCurrentConfiguration)
1430 && (!bLoadSame)) {
1431 dev_info(pTAS2557->dev, "Configuration %d is already loaded\n",
1432 nConfiguration);
1433 nResult = 0;
1434 goto end;
1435 }
1437 pCurrentConfiguration =
1438 &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
1439 pNewConfiguration =
1440 &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
1441 if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
1442 dev_err(pTAS2557->dev, "Configuration %d, %s doesn't share the same program as current %d\n",
1443 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
1444 nResult = 0;
1445 goto end;
1446 }
1448 if (pNewConfiguration->mnPLL >= pTAS2557->mpFirmware->mnPLLs) {
1449 dev_err(pTAS2557->dev, "Configuration %d, %s doesn't have a valid PLL index %d\n",
1450 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
1451 nResult = 0;
1452 goto end;
1453 }
1455 if (pTAS2557->mbPowerUp) {
1456 pTAS2557->mbLoadConfigurationPrePowerUp = false;
1457 nResult = tas2557_load_coefficient(pTAS2557, pTAS2557->mnCurrentConfiguration, nConfiguration, true);
1458 } else {
1459 dev_dbg(pTAS2557->dev,
1460 "TAS2557 was powered down, will load coefficient when power up\n");
1461 pTAS2557->mbLoadConfigurationPrePowerUp = true;
1462 pTAS2557->mnNewConfiguration = nConfiguration;
1463 }
1465 end:
1467 if (nResult < 0) {
1468 if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
1469 failsafe(pTAS2557);
1470 }
1472 return nResult;
1473 }
1475 int tas2557_set_config(struct tas2557_priv *pTAS2557, int config)
1476 {
1477 struct TConfiguration *pConfiguration;
1478 struct TProgram *pProgram;
1479 unsigned int nProgram = pTAS2557->mnCurrentProgram;
1480 unsigned int nConfiguration = config;
1481 int nResult = 0;
1483 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1484 (!pTAS2557->mpFirmware->mpConfigurations)) {
1485 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1486 nResult = -EINVAL;
1487 goto end;
1488 }
1490 if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) {
1491 dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n",
1492 nConfiguration);
1493 nResult = -EINVAL;
1494 goto end;
1495 }
1497 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]);
1498 pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
1500 if (nProgram != pConfiguration->mnProgram) {
1501 dev_err(pTAS2557->dev,
1502 "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
1503 nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
1504 nProgram, pProgram->mpName);
1505 nResult = -EINVAL;
1506 goto end;
1507 }
1509 nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false);
1511 end:
1513 return nResult;
1514 }
1516 void tas2557_clear_firmware(struct TFirmware *pFirmware)
1517 {
1518 unsigned int n, nn;
1520 if (!pFirmware)
1521 return;
1523 kfree(pFirmware->mpDescription);
1525 if (pFirmware->mpPLLs != NULL) {
1526 for (n = 0; n < pFirmware->mnPLLs; n++) {
1527 kfree(pFirmware->mpPLLs[n].mpDescription);
1528 kfree(pFirmware->mpPLLs[n].mBlock.mpData);
1529 }
1530 kfree(pFirmware->mpPLLs);
1531 }
1533 if (pFirmware->mpPrograms != NULL) {
1534 for (n = 0; n < pFirmware->mnPrograms; n++) {
1535 kfree(pFirmware->mpPrograms[n].mpDescription);
1536 kfree(pFirmware->mpPrograms[n].mData.mpDescription);
1537 for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++)
1538 kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData);
1539 kfree(pFirmware->mpPrograms[n].mData.mpBlocks);
1540 }
1541 kfree(pFirmware->mpPrograms);
1542 }
1544 if (pFirmware->mpConfigurations != NULL) {
1545 for (n = 0; n < pFirmware->mnConfigurations; n++) {
1546 kfree(pFirmware->mpConfigurations[n].mpDescription);
1547 kfree(pFirmware->mpConfigurations[n].mData.mpDescription);
1548 for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++)
1549 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData);
1550 kfree(pFirmware->mpConfigurations[n].mData.mpBlocks);
1551 }
1552 kfree(pFirmware->mpConfigurations);
1553 }
1555 if (pFirmware->mpCalibrations != NULL) {
1556 for (n = 0; n < pFirmware->mnCalibrations; n++) {
1557 kfree(pFirmware->mpCalibrations[n].mpDescription);
1558 kfree(pFirmware->mpCalibrations[n].mData.mpDescription);
1559 for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++)
1560 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData);
1561 kfree(pFirmware->mpCalibrations[n].mData.mpBlocks);
1562 }
1563 kfree(pFirmware->mpCalibrations);
1564 }
1566 memset(pFirmware, 0x00, sizeof(struct TFirmware));
1567 }
1569 static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, char *pFileName)
1570 {
1571 int nResult = 0;
1573 int nFile;
1574 mm_segment_t fs;
1575 unsigned char pBuffer[1000];
1576 int nSize = 0;
1578 dev_dbg(pTAS2557->dev, "%s:\n", __func__);
1580 fs = get_fs();
1581 set_fs(KERNEL_DS);
1582 nFile = sys_open(pFileName, O_RDONLY, 0);
1584 dev_info(pTAS2557->dev, "TAS2557 calibration file = %s, handle = %d\n",
1585 pFileName, nFile);
1587 if (nFile >= 0) {
1588 nSize = sys_read(nFile, pBuffer, 1000);
1589 sys_close(nFile);
1590 } else {
1591 dev_err(pTAS2557->dev, "TAS2557 cannot open calibration file: %s\n",
1592 pFileName);
1593 }
1595 set_fs(fs);
1597 if (!nSize)
1598 goto end;
1600 tas2557_clear_firmware(pTAS2557->mpCalFirmware);
1601 dev_info(pTAS2557->dev, "TAS2557 calibration file size = %d\n", nSize);
1602 nResult = fw_parse(pTAS2557, pTAS2557->mpCalFirmware, pBuffer, nSize);
1604 if (nResult)
1605 dev_err(pTAS2557->dev, "TAS2557 calibration file is corrupt\n");
1606 else
1607 dev_info(pTAS2557->dev, "TAS2557 calibration: %d calibrations\n",
1608 pTAS2557->mpCalFirmware->mnCalibrations);
1609 end:
1611 return nResult;
1612 }
1614 static bool tas2557_get_coefficient_in_block(struct tas2557_priv *pTAS2557,
1615 struct TBlock *pBlock, int nReg, int *pnValue)
1616 {
1617 int nCoefficient = 0;
1618 bool bFound = false;
1619 unsigned char *pCommands;
1620 int nBook, nPage, nOffset, len;
1621 int i, n;
1623 pCommands = pBlock->mpData;
1624 for (i = 0 ; i < pBlock->mnCommands;) {
1625 nBook = pCommands[4 * i + 0];
1626 nPage = pCommands[4 * i + 1];
1627 nOffset = pCommands[4 * i + 2];
1628 if ((nOffset < 0x7f) || (nOffset == 0x81))
1629 i++;
1630 else if (nOffset == 0x85) {
1631 len = ((int)nBook << 8) | nPage;
1632 nBook = pCommands[4 * i + 4];
1633 nPage = pCommands[4 * i + 5];
1634 nOffset = pCommands[4 * i + 6];
1635 n = 4 * i + 7;
1636 i += 2;
1637 i += ((len - 1) / 4);
1638 if ((len - 1) % 4)
1639 i++;
1640 if ((nBook != TAS2557_BOOK_ID(nReg))
1641 || (nPage != TAS2557_PAGE_ID(nReg)))
1642 continue;
1643 if (nOffset > TAS2557_PAGE_REG(nReg))
1644 continue;
1645 if ((len + nOffset) >= (TAS2557_PAGE_REG(nReg) + 4)) {
1646 n += (TAS2557_PAGE_REG(nReg) - nOffset);
1647 nCoefficient = ((int)pCommands[n] << 24)
1648 | ((int)pCommands[n + 1] << 16)
1649 | ((int)pCommands[n + 2] << 8)
1650 | (int)pCommands[n + 3];
1651 bFound = true;
1652 break;
1653 }
1654 } else {
1655 dev_err(pTAS2557->dev, "%s, format error %d\n", __func__, nOffset);
1656 break;
1657 }
1658 }
1660 if (bFound) {
1661 *pnValue = nCoefficient;
1662 dev_dbg(pTAS2557->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", __func__,
1663 TAS2557_BOOK_ID(nReg), TAS2557_PAGE_ID(nReg), TAS2557_PAGE_REG(nReg),
1664 nCoefficient);
1665 }
1667 return bFound;
1668 }
1670 static bool tas2557_get_coefficient_in_data(struct tas2557_priv *pTAS2557,
1671 struct TData *pData, int blockType, int nReg, int *pnValue)
1672 {
1673 bool bFound = false;
1674 struct TBlock *pBlock;
1675 int i;
1677 for (i = 0; i < pData->mnBlocks; i++) {
1678 pBlock = &(pData->mpBlocks[i]);
1679 if (pBlock->mnType == blockType) {
1680 bFound = tas2557_get_coefficient_in_block(pTAS2557,
1681 pBlock, nReg, pnValue);
1682 if (bFound)
1683 break;
1684 }
1685 }
1687 return bFound;
1688 }
1690 static bool tas2557_find_Tmax_in_configuration(struct tas2557_priv *pTAS2557,
1691 struct TConfiguration *pConfiguration, int *pnTMax)
1692 {
1693 struct TData *pData;
1694 bool bFound = false;
1695 int nBlockType, nReg, nCoefficient;
1697 if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
1698 nReg = TAS2557_PG2P1_CALI_T_REG;
1699 else
1700 nReg = TAS2557_PG1P0_CALI_T_REG;
1702 nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A;
1704 pData = &(pConfiguration->mData);
1705 bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCoefficient);
1706 if (bFound)
1707 *pnTMax = nCoefficient;
1709 return bFound;
1710 }
1712 void tas2557_fw_ready(const struct firmware *pFW, void *pContext)
1713 {
1714 struct tas2557_priv *pTAS2557 = (struct tas2557_priv *) pContext;
1715 int nResult;
1716 unsigned int nProgram = 0;
1717 unsigned int nSampleRate = 0;
1719 #ifdef CONFIG_TAS2557_CODEC
1720 mutex_lock(&pTAS2557->codec_lock);
1721 #endif
1723 #ifdef CONFIG_TAS2557_MISC
1724 mutex_lock(&pTAS2557->file_lock);
1725 #endif
1727 dev_info(pTAS2557->dev, "%s:\n", __func__);
1729 if (unlikely(!pFW) || unlikely(!pFW->data)) {
1730 dev_err(pTAS2557->dev, "%s firmware is not loaded.\n",
1731 TAS2557_FW_NAME);
1732 goto end;
1733 }
1735 if (pTAS2557->mpFirmware->mpConfigurations) {
1736 nProgram = pTAS2557->mnCurrentProgram;
1737 nSampleRate = pTAS2557->mnCurrentSampleRate;
1738 dev_dbg(pTAS2557->dev, "clear current firmware\n");
1739 tas2557_clear_firmware(pTAS2557->mpFirmware);
1740 }
1742 nResult = fw_parse(pTAS2557, pTAS2557->mpFirmware, (unsigned char *)(pFW->data), pFW->size);
1743 release_firmware(pFW);
1744 if (nResult < 0) {
1745 dev_err(pTAS2557->dev, "firmware is corrupt\n");
1746 goto end;
1747 }
1749 if (!pTAS2557->mpFirmware->mnPrograms) {
1750 dev_err(pTAS2557->dev, "firmware contains no programs\n");
1751 nResult = -EINVAL;
1752 goto end;
1753 }
1755 if (!pTAS2557->mpFirmware->mnConfigurations) {
1756 dev_err(pTAS2557->dev, "firmware contains no configurations\n");
1757 nResult = -EINVAL;
1758 goto end;
1759 }
1761 if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
1762 dev_info(pTAS2557->dev,
1763 "no previous program, set to default\n");
1764 nProgram = 0;
1765 }
1767 pTAS2557->mnCurrentSampleRate = nSampleRate;
1768 nResult = tas2557_set_program(pTAS2557, nProgram, -1);
1770 end:
1772 #ifdef CONFIG_TAS2557_CODEC
1773 mutex_unlock(&pTAS2557->codec_lock);
1774 #endif
1776 #ifdef CONFIG_TAS2557_MISC
1777 mutex_unlock(&pTAS2557->file_lock);
1778 #endif
1779 }
1781 int tas2557_set_program(struct tas2557_priv *pTAS2557,
1782 unsigned int nProgram, int nConfig)
1783 {
1784 struct TProgram *pProgram;
1785 unsigned int nConfiguration = 0;
1786 unsigned int nSampleRate = 0;
1787 unsigned char nGain;
1788 bool bFound = false;
1789 int nResult = 0;
1791 if ((!pTAS2557->mpFirmware->mpPrograms) ||
1792 (!pTAS2557->mpFirmware->mpConfigurations)) {
1793 dev_err(pTAS2557->dev, "Firmware not loaded\n");
1794 nResult = 0;
1795 goto end;
1796 }
1798 if (nProgram >= pTAS2557->mpFirmware->mnPrograms) {
1799 dev_err(pTAS2557->dev, "TAS2557: Program %d doesn't exist\n",
1800 nProgram);
1801 nResult = 0;
1802 goto end;
1803 }
1805 if (nConfig < 0) {
1806 nConfiguration = 0;
1807 nSampleRate = pTAS2557->mnCurrentSampleRate;
1808 while (!bFound && (nConfiguration < pTAS2557->mpFirmware->mnConfigurations)) {
1809 if (pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) {
1810 if (nSampleRate == 0) {
1811 bFound = true;
1812 dev_info(pTAS2557->dev, "find default configuration %d\n", nConfiguration);
1813 } else if (nSampleRate == pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) {
1814 bFound = true;
1815 dev_info(pTAS2557->dev, "find matching configuration %d\n", nConfiguration);
1816 } else {
1817 nConfiguration++;
1818 }
1819 } else {
1820 nConfiguration++;
1821 }
1822 }
1823 if (!bFound) {
1824 dev_err(pTAS2557->dev,
1825 "Program %d, no valid configuration found for sample rate %d, ignore\n",
1826 nProgram, nSampleRate);
1827 nResult = 0;
1828 goto end;
1829 }
1830 } else {
1831 if (pTAS2557->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) {
1832 dev_err(pTAS2557->dev, "%s, configuration program doesn't match\n", __func__);
1833 nResult = 0;
1834 goto end;
1835 }
1836 nConfiguration = nConfig;
1837 }
1839 pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]);
1840 if (pTAS2557->mbPowerUp) {
1841 dev_info(pTAS2557->dev,
1842 "device powered up, power down to load program %d (%s)\n",
1843 nProgram, pProgram->mpName);
1844 if (hrtimer_active(&pTAS2557->mtimer))
1845 hrtimer_cancel(&pTAS2557->mtimer);
1847 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)
1848 pTAS2557->enableIRQ(pTAS2557, false, false);
1850 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
1851 if (nResult < 0)
1852 goto end;
1853 }
1855 pTAS2557->hw_reset(pTAS2557);
1856 nResult = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01);
1857 if (nResult < 0)
1858 goto end;
1859 msleep(1);
1860 nResult = tas2557_load_default(pTAS2557);
1861 if (nResult < 0)
1862 goto end;
1864 dev_info(pTAS2557->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
1865 nResult = tas2557_load_data(pTAS2557, &(pProgram->mData), TAS2557_BLOCK_PGM_DEV_A);
1866 if (nResult < 0)
1867 goto end;
1868 pTAS2557->mnCurrentProgram = nProgram;
1870 nResult = tas2557_get_DAC_gain(pTAS2557, &nGain);
1871 if (nResult < 0)
1872 goto end;
1873 pTAS2557->mnDevGain = nGain;
1874 pTAS2557->mnDevCurrentGain = nGain;
1876 nResult = tas2557_load_coefficient(pTAS2557, -1, nConfiguration, false);
1877 if (nResult < 0)
1878 goto end;
1880 tas2557_update_edge(pTAS2557);
1882 if (pTAS2557->mbPowerUp) {
1883 pTAS2557->clearIRQ(pTAS2557);
1884 dev_dbg(pTAS2557->dev, "device powered up, load startup\n");
1885 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data);
1886 if (nResult < 0)
1887 goto end;
1888 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1889 nResult = tas2557_checkPLL(pTAS2557);
1890 if (nResult < 0) {
1891 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data);
1892 pTAS2557->mbPowerUp = false;
1893 goto end;
1894 }
1895 }
1896 dev_dbg(pTAS2557->dev, "device powered up, load unmute\n");
1897 nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data);
1898 if (nResult < 0)
1899 goto end;
1901 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1902 pTAS2557->enableIRQ(pTAS2557, true, true);
1903 if (!hrtimer_active(&pTAS2557->mtimer)) {
1904 pTAS2557->mnDieTvReadCounter = 0;
1905 hrtimer_start(&pTAS2557->mtimer,
1906 ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL);
1907 }
1908 }
1909 }
1911 end:
1913 if (nResult < 0) {
1914 if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK))
1915 failsafe(pTAS2557);
1916 }
1917 return nResult;
1918 }
1920 int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration)
1921 {
1922 struct TCalibration *pCalibration = NULL;
1923 struct TConfiguration *pConfiguration;
1924 struct TProgram *pProgram;
1925 int nTmax = 0;
1926 bool bFound = false;
1927 int nResult = 0;
1929 if ((!pTAS2557->mpFirmware->mpPrograms)
1930 || (!pTAS2557->mpFirmware->mpConfigurations)) {
1931 dev_err(pTAS2557->dev, "Firmware not loaded\n\r");
1932 nResult = 0;
1933 goto end;
1934 }
1936 if (nCalibration == 0x00FF) {
1937 nResult = tas2557_load_calibration(pTAS2557, TAS2557_CAL_NAME);
1938 if (nResult < 0) {
1939 dev_info(pTAS2557->dev, "load new calibration file %s fail %d\n",
1940 TAS2557_CAL_NAME, nResult);
1941 goto end;
1942 }
1943 nCalibration = 0;
1944 }
1946 if (nCalibration >= pTAS2557->mpCalFirmware->mnCalibrations) {
1947 dev_err(pTAS2557->dev,
1948 "Calibration %d doesn't exist\n", nCalibration);
1949 nResult = 0;
1950 goto end;
1951 }
1953 pTAS2557->mnCurrentCalibration = nCalibration;
1954 if (pTAS2557->mbLoadConfigurationPrePowerUp)
1955 goto end;
1957 pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[nCalibration]);
1958 pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
1959 pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
1960 if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
1961 if (pTAS2557->mbBypassTMax) {
1962 bFound = tas2557_find_Tmax_in_configuration(pTAS2557, pConfiguration, &nTmax);
1963 if (bFound && (nTmax == TAS2557_COEFFICIENT_TMAX)) {
1964 dev_dbg(pTAS2557->dev, "%s, config[%s] bypass load calibration\n",
1965 __func__, pConfiguration->mpName);
1966 goto end;
1967 }
1968 }
1970 dev_dbg(pTAS2557->dev, "%s, load calibration\n", __func__);
1971 nResult = tas2557_load_data(pTAS2557, &(pCalibration->mData), TAS2557_BLOCK_CFG_COEFF_DEV_A);
1972 if (nResult < 0)
1973 goto end;
1974 }
1976 end:
1977 if (nResult < 0) {
1978 tas2557_clear_firmware(pTAS2557->mpCalFirmware);
1979 nResult = tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, pTAS2557->mnCurrentConfiguration);
1980 }
1982 return nResult;
1983 }
1985 bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0)
1986 {
1987 struct TCalibration *pCalibration;
1988 struct TData *pData;
1989 int nReg;
1990 int nCali_Re;
1991 bool bFound = false;
1992 int nBlockType;
1994 if (!pTAS2557->mpCalFirmware->mnCalibrations) {
1995 dev_err(pTAS2557->dev, "%s, no calibration data\n", __func__);
1996 goto end;
1997 }
1999 if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
2000 nReg = TAS2557_PG2P1_CALI_R0_REG;
2001 else
2002 nReg = TAS2557_PG1P0_CALI_R0_REG;
2004 nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A;
2006 pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[pTAS2557->mnCurrentCalibration]);
2007 pData = &(pCalibration->mData);
2009 bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCali_Re);
2011 end:
2013 if (bFound)
2014 *prm_r0 = nCali_Re;
2016 return bFound;
2017 }
2019 int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557)
2020 {
2021 struct device_node *np = dev->of_node;
2022 int rc = 0, ret = 0;
2023 unsigned int value;
2025 pTAS2557->mnResetGPIO = of_get_named_gpio(np, "ti,cdc-reset-gpio", 0);
2026 if (!gpio_is_valid(pTAS2557->mnResetGPIO)) {
2027 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2028 "ti,cdc-reset-gpio", np->full_name,
2029 pTAS2557->mnResetGPIO);
2030 ret = -EINVAL;
2031 goto end;
2032 } else
2033 dev_dbg(pTAS2557->dev, "ti,cdc-reset-gpio=%d\n", pTAS2557->mnResetGPIO);
2035 pTAS2557->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0);
2036 if (!gpio_is_valid(pTAS2557->mnGpioINT))
2037 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2038 "ti,irq-gpio", np->full_name,
2039 pTAS2557->mnGpioINT);
2042 rc = of_property_read_u32(np, "ti,i2s-bits", &value);
2043 if (rc)
2044 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2045 "ti,i2s-bits", np->full_name, rc);
2046 else
2047 pTAS2557->mnI2SBits = value;
2049 rc = of_property_read_u32(np, "ti,bypass-tmax", &value);
2050 if (rc)
2051 dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
2052 "ti,bypass-tmax", np->full_name, rc);
2053 else
2054 pTAS2557->mbBypassTMax = (value > 0);
2056 end:
2058 return ret;
2059 }
2061 MODULE_AUTHOR("Texas Instruments Inc.");
2062 MODULE_DESCRIPTION("TAS2557 common functions for Android Linux");
2063 MODULE_LICENSE("GPL v2");