summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Li2017-02-15 17:48:29 -0600
committerPeter Li2017-02-15 17:48:29 -0600
commit3f8c8cfd6a6574d0c4ab6f498b8aaa355f493a04 (patch)
tree248dd3b83036a4c77a191e73b00db04dd684301e
parenta76498e7810015aed3be6eb43b57040c7f1b2b9d (diff)
downloadtas2555-android-driver-3f8c8cfd6a6574d0c4ab6f498b8aaa355f493a04.tar.gz
tas2555-android-driver-3f8c8cfd6a6574d0c4ab6f498b8aaa355f493a04.tar.xz
tas2555-android-driver-3f8c8cfd6a6574d0c4ab6f498b8aaa355f493a04.zip
update: 1, IRQ handler; 2, error code; 3, Get Re
-rwxr-xr-xdts.readme2
-rwxr-xr-xtas2555-codec.c180
-rwxr-xr-xtas2555-core.c865
-rwxr-xr-xtas2555-core.h7
-rwxr-xr-xtas2555-misc.c4
-rwxr-xr-xtas2555-regmap.c296
-rwxr-xr-xtas2555.h47
7 files changed, 823 insertions, 578 deletions
diff --git a/dts.readme b/dts.readme
index ef2daff..93ed3eb 100755
--- a/dts.readme
+++ b/dts.readme
@@ -3,5 +3,7 @@ example for dts:
3 tas2555@4c { 3 tas2555@4c {
4 compatible = "ti,tas2555"; 4 compatible = "ti,tas2555";
5 reg = <0x4c>; 5 reg = <0x4c>;
6 ti,cdc-reset-gpio = <&msmgpio 73 0>;
7 ti,irq-gpio = <&msmgpio 59 0>;
6 status = "okay"; 8 status = "okay";
7 }; \ No newline at end of file 9 }; \ No newline at end of file
diff --git a/tas2555-codec.c b/tas2555-codec.c
index f49bac8..92dcbc5 100755
--- a/tas2555-codec.c
+++ b/tas2555-codec.c
@@ -416,70 +416,6 @@ static int tas2555_fs_put(struct snd_kcontrol *pKcontrol,
416 return ret; 416 return ret;
417} 417}
418 418
419static int tas2555_nReHigh_get(struct snd_kcontrol *pKcontrol,
420 struct snd_ctl_elem_value *pValue)
421{
422#ifdef KCONTROL_CODEC
423 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
424#else
425 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
426#endif
427 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
428
429 pValue->value.integer.value[0] = pTAS2555->mnReHigh;
430
431 dev_dbg(pTAS2555->dev, "tas2555_nReHigh_get = %d\n", pTAS2555->mnReHigh);
432 return 0;
433}
434
435static int tas2555_nReHigh_put(struct snd_kcontrol *pKcontrol,
436 struct snd_ctl_elem_value *pValue)
437{
438#ifdef KCONTROL_CODEC
439 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
440#else
441 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
442#endif
443 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
444
445 pTAS2555->mnReHigh = pValue->value.integer.value[0];
446
447 dev_dbg(pTAS2555->dev, "tas2555_nReHigh_put = %d\n", pTAS2555->mnReHigh);
448 return 0;
449}
450
451static int tas2555_nReLow_get(struct snd_kcontrol *pKcontrol,
452 struct snd_ctl_elem_value *pValue)
453{
454#ifdef KCONTROL_CODEC
455 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
456#else
457 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
458#endif
459 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
460
461 pValue->value.integer.value[0] = pTAS2555->mnReLow;
462
463 dev_dbg(pTAS2555->dev, "tas2555_nReLow_get = %d\n", pTAS2555->mnReLow);
464 return 0;
465}
466
467static int tas2555_nReLow_put(struct snd_kcontrol *pKcontrol,
468 struct snd_ctl_elem_value *pValue)
469{
470#ifdef KCONTROL_CODEC
471 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
472#else
473 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
474#endif
475 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
476
477 pTAS2555->mnReLow = pValue->value.integer.value[0];
478
479 dev_dbg(pTAS2555->dev, "tas2555_nReLow_put = %d\n", pTAS2555->mnReLow);
480 return 0;
481}
482
483static int tas2555_nRe_get(struct snd_kcontrol *pKcontrol, 419static int tas2555_nRe_get(struct snd_kcontrol *pKcontrol,
484 struct snd_ctl_elem_value *pValue) 420 struct snd_ctl_elem_value *pValue)
485{ 421{
@@ -508,7 +444,7 @@ static int tas2555_nRe_get(struct snd_kcontrol *pKcontrol,
508 return 0; 444 return 0;
509} 445}
510 446
511static int tas2555_nF0_a1_get(struct snd_kcontrol *pKcontrol, 447static int tas2555_errcode_get(struct snd_kcontrol *pKcontrol,
512 struct snd_ctl_elem_value *pValue) 448 struct snd_ctl_elem_value *pValue)
513{ 449{
514#ifdef KCONTROL_CODEC 450#ifdef KCONTROL_CODEC
@@ -517,50 +453,18 @@ static int tas2555_nF0_a1_get(struct snd_kcontrol *pKcontrol,
517 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); 453 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
518#endif 454#endif
519 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec); 455 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
520 unsigned int nA1; 456 unsigned int errCode = 0;
521 int ret; 457 int nResult;
522 458
523 mutex_lock(&pTAS2555->codec_lock); 459 mutex_lock(&pTAS2555->codec_lock);
524 460
525 if ((pTAS2555->mpFirmware->mnConfigurations > 0) && pTAS2555->mbPowerUp) { 461 nResult = tas2555_get_errcode(pTAS2555, &errCode);
526 ret = tas2555_get_f0_a1(pTAS2555, &nA1); 462 if (nResult >= 0)
527 if (ret >= 0) 463 pValue->value.integer.value[0] = errCode;
528 pValue->value.integer.value[0] = nA1;
529 else
530 pValue->value.integer.value[0] = 0;
531 }
532 464
533 mutex_unlock(&pTAS2555->codec_lock); 465 mutex_unlock(&pTAS2555->codec_lock);
534 466
535 dev_dbg(pTAS2555->dev, "tas2555_nF0_a1_get = %d\n", nA1); 467 dev_dbg(pTAS2555->dev, "tas2555_errcode_get = 0x%x\n", errCode);
536 return 0;
537}
538
539static int tas2555_nF0_a2_get(struct snd_kcontrol *pKcontrol,
540 struct snd_ctl_elem_value *pValue)
541{
542#ifdef KCONTROL_CODEC
543 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
544#else
545 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
546#endif
547 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
548 unsigned int nA2;
549 int ret;
550
551 mutex_lock(&pTAS2555->codec_lock);
552
553 if ((pTAS2555->mpFirmware->mnConfigurations > 0) && pTAS2555->mbPowerUp) {
554 ret = tas2555_get_f0_a2(pTAS2555, &nA2);
555 if (ret >= 0)
556 pValue->value.integer.value[0] = nA2;
557 else
558 pValue->value.integer.value[0] = 0;
559 }
560
561 mutex_unlock(&pTAS2555->codec_lock);
562
563 dev_dbg(pTAS2555->dev, "tas2555_nF0_a2_get = %d\n", nA2);
564 return 0; 468 return 0;
565} 469}
566 470
@@ -577,7 +481,7 @@ static int tas2555_program_get(struct snd_kcontrol *pKcontrol,
577 pValue->value.integer.value[0] = pTAS2555->mnCurrentProgram; 481 pValue->value.integer.value[0] = pTAS2555->mnCurrentProgram;
578 dev_dbg(pTAS2555->dev, "tas2555_program_get = %d\n", 482 dev_dbg(pTAS2555->dev, "tas2555_program_get = %d\n",
579 pTAS2555->mnCurrentProgram); 483 pTAS2555->mnCurrentProgram);
580 mutex_unlock(&pTAS2555->codec_lock); 484 mutex_unlock(&pTAS2555->codec_lock);
581 return 0; 485 return 0;
582} 486}
583 487
@@ -592,9 +496,9 @@ static int tas2555_program_put(struct snd_kcontrol *pKcontrol,
592 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec); 496 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
593 unsigned int nProgram = pValue->value.integer.value[0]; 497 unsigned int nProgram = pValue->value.integer.value[0];
594 int ret = 0; 498 int ret = 0;
595 mutex_lock(&pTAS2555->codec_lock); 499 mutex_lock(&pTAS2555->codec_lock);
596 ret = tas2555_set_program(pTAS2555, nProgram); 500 ret = tas2555_set_program(pTAS2555, nProgram, -1);
597 mutex_unlock(&pTAS2555->codec_lock); 501 mutex_unlock(&pTAS2555->codec_lock);
598 return ret; 502 return ret;
599} 503}
600 504
@@ -608,11 +512,11 @@ static int tas2555_configuration_get(struct snd_kcontrol *pKcontrol,
608#endif 512#endif
609 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec); 513 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
610 514
611 mutex_lock(&pTAS2555->codec_lock); 515 mutex_lock(&pTAS2555->codec_lock);
612 pValue->value.integer.value[0] = pTAS2555->mnCurrentConfiguration; 516 pValue->value.integer.value[0] = pTAS2555->mnCurrentConfiguration;
613 dev_dbg(pTAS2555->dev, "tas2555_configuration_get = %d\n", 517 dev_dbg(pTAS2555->dev, "tas2555_configuration_get = %d\n",
614 pTAS2555->mnCurrentConfiguration); 518 pTAS2555->mnCurrentConfiguration);
615 mutex_unlock(&pTAS2555->codec_lock); 519 mutex_unlock(&pTAS2555->codec_lock);
616 return 0; 520 return 0;
617} 521}
618 522
@@ -628,9 +532,9 @@ static int tas2555_configuration_put(struct snd_kcontrol *pKcontrol,
628 unsigned int nConfiguration = pValue->value.integer.value[0]; 532 unsigned int nConfiguration = pValue->value.integer.value[0];
629 int ret = 0; 533 int ret = 0;
630 534
631 mutex_lock(&pTAS2555->codec_lock); 535 mutex_lock(&pTAS2555->codec_lock);
632 ret = tas2555_set_config(pTAS2555, nConfiguration); 536 ret = tas2555_set_config(pTAS2555, nConfiguration);
633 mutex_unlock(&pTAS2555->codec_lock); 537 mutex_unlock(&pTAS2555->codec_lock);
634 return ret; 538 return ret;
635} 539}
636 540
@@ -644,12 +548,12 @@ static int tas2555_calibration_get(struct snd_kcontrol *pKcontrol,
644#endif 548#endif
645 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec); 549 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
646 550
647 mutex_lock(&pTAS2555->codec_lock); 551 mutex_lock(&pTAS2555->codec_lock);
648 pValue->value.integer.value[0] = pTAS2555->mnCurrentCalibration; 552 pValue->value.integer.value[0] = pTAS2555->mnCurrentCalibration;
649 dev_info(pTAS2555->dev, 553 dev_info(pTAS2555->dev,
650 "tas2555_calibration_get = %d\n", 554 "tas2555_calibration_get = %d\n",
651 pTAS2555->mnCurrentCalibration); 555 pTAS2555->mnCurrentCalibration);
652 mutex_unlock(&pTAS2555->codec_lock); 556 mutex_unlock(&pTAS2555->codec_lock);
653 return 0; 557 return 0;
654} 558}
655 559
@@ -665,13 +569,45 @@ static int tas2555_calibration_put(struct snd_kcontrol *pKcontrol,
665 unsigned int nCalibration = pValue->value.integer.value[0]; 569 unsigned int nCalibration = pValue->value.integer.value[0];
666 int ret = 0; 570 int ret = 0;
667 571
668 mutex_lock(&pTAS2555->codec_lock); 572 mutex_lock(&pTAS2555->codec_lock);
669 ret = tas2555_set_calibration(pTAS2555, nCalibration); 573 ret = tas2555_set_calibration(pTAS2555, nCalibration);
670 mutex_unlock(&pTAS2555->codec_lock); 574 mutex_unlock(&pTAS2555->codec_lock);
671 575
672 return ret; 576 return ret;
673} 577}
674 578
579static int tas2555_nReDelta_get(struct snd_kcontrol *pKcontrol,
580 struct snd_ctl_elem_value *pValue)
581{
582#ifdef KCONTROL_CODEC
583 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
584#else
585 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
586#endif
587 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
588
589 pValue->value.integer.value[0] = pTAS2555->mnReDelta;
590
591 dev_dbg(pTAS2555->dev, "tas2555_nReDelta_get = %d\n", pTAS2555->mnReDelta);
592 return 0;
593}
594
595static int tas2555_nReDelta_put(struct snd_kcontrol *pKcontrol,
596 struct snd_ctl_elem_value *pValue)
597{
598#ifdef KCONTROL_CODEC
599 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
600#else
601 struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
602#endif
603 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(codec);
604 unsigned int ReDelata = pValue->value.integer.value[0];
605
606 pTAS2555->mnReDelta = ReDelata;
607
608 return 0;
609}
610
675/* 611/*
676 * DAC digital volumes. From 0 to 15 dB in 1 dB steps 612 * DAC digital volumes. From 0 to 15 dB in 1 dB steps
677 */ 613 */
@@ -692,16 +628,12 @@ static const struct snd_kcontrol_new tas2555_snd_controls[] = {
692 tas2555_configuration_get, tas2555_configuration_put), 628 tas2555_configuration_get, tas2555_configuration_put),
693 SOC_SINGLE_EXT("FS", SND_SOC_NOPM, 8000, 48000, 0, 629 SOC_SINGLE_EXT("FS", SND_SOC_NOPM, 8000, 48000, 0,
694 tas2555_fs_get, tas2555_fs_put), 630 tas2555_fs_get, tas2555_fs_put),
695 SOC_SINGLE_EXT("nReHigh", SND_SOC_NOPM, 0, 0x7fffffff, 0, 631 SOC_SINGLE_EXT("nRe_Delta", SND_SOC_NOPM, 0, 0x7fffffff, 0,
696 tas2555_nReHigh_get, tas2555_nReHigh_put), 632 tas2555_nReDelta_get, tas2555_nReDelta_put),
697 SOC_SINGLE_EXT("nReLow", SND_SOC_NOPM, 0, 0x7fffffff, 0,
698 tas2555_nReLow_get, tas2555_nReLow_put),
699 SOC_SINGLE_EXT("nRe", SND_SOC_NOPM, 0, 0x7fffffff, 0, 633 SOC_SINGLE_EXT("nRe", SND_SOC_NOPM, 0, 0x7fffffff, 0,
700 tas2555_nRe_get, NULL), 634 tas2555_nRe_get, NULL),
701 SOC_SINGLE_EXT("nF0_A1", SND_SOC_NOPM, 0, 0x7fffffff, 0, 635 SOC_SINGLE_EXT("TAS_Status", SND_SOC_NOPM, 0, 0x7fffffff, 0,
702 tas2555_nF0_a1_get, NULL), 636 tas2555_errcode_get, NULL),
703 SOC_SINGLE_EXT("nF0_A2", SND_SOC_NOPM, 0, 0x7fffffff, 0,
704 tas2555_nF0_a2_get, NULL),
705 SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0, 637 SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0,
706 tas2555_calibration_get, tas2555_calibration_put), 638 tas2555_calibration_get, tas2555_calibration_put),
707}; 639};
diff --git a/tas2555-core.c b/tas2555-core.c
index 4c3514b..541e01e 100755
--- a/tas2555-core.c
+++ b/tas2555-core.c
@@ -75,6 +75,7 @@ static int tas2555_load_configuration(struct tas2555_priv *pTAS2555,
75#define TAS2555_BLOCK_CONF_POST_POWER 0x06 75#define TAS2555_BLOCK_CONF_POST_POWER 0x06
76#define TAS2555_BLOCK_CONF_CAL 0x0A 76#define TAS2555_BLOCK_CONF_CAL 0x0A
77 77
78#if 0
78static unsigned int p_tas2555_default_data[] = { 79static unsigned int p_tas2555_default_data[] = {
79 TAS2555_ASI1_DAC_FORMAT_REG, 0x10, //ASI1 DAC word length = 24 bits 80 TAS2555_ASI1_DAC_FORMAT_REG, 0x10, //ASI1 DAC word length = 24 bits
80 81
@@ -103,10 +104,21 @@ static unsigned int p_tas2555_default_data[] = {
103// TAS2555_CLK_ERR_CTRL, 0x09, //enable clock error detection on PLL 104// TAS2555_CLK_ERR_CTRL, 0x09, //enable clock error detection on PLL
104 0xFFFFFFFF, 0xFFFFFFFF 105 0xFFFFFFFF, 0xFFFFFFFF
105}; 106};
107#endif
108
109static unsigned int p_tas2555_irq_config[] = {
110 /* TAS2555_GPIO4_PIN_REG, 0x07, set GPIO4 as int1, default */
111 TAS2555_INT_GEN1_REG, 0x11, /* enable spk OC and OV */
112 TAS2555_INT_GEN2_REG, 0x11, /* enable clk err1 and die OT */
113 TAS2555_INT_GEN3_REG, 0x11, /* enable clk err2 and brownout */
114 /* TAS2555_INT_GEN4_REG, 0x01, disable SAR, enable clk halt */
115 TAS2555_INT_MODE_REG, 0x80, /* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */
116 0xFFFFFFFF, 0xFFFFFFFF
117};
106 118
107#define TAS2555_STARTUP_DATA_PLL_CLKIN_INDEX 3 119#define TAS2555_STARTUP_DATA_PLL_CLKIN_INDEX 3
108static unsigned int p_tas2555_startup_data[] = { 120static unsigned int p_tas2555_startup_data[] = {
109 TAS2555_CLK_ERR_CTRL, 0x00, //disable clock error detection on PLL 121 TAS2555_CLK_ERR_CTRL, 0x0b, //enable clock error detection on PLL
110 TAS2555_PLL_CLKIN_REG, TAS2555_DEFAULT_PLL_CLKIN, 122 TAS2555_PLL_CLKIN_REG, TAS2555_DEFAULT_PLL_CLKIN,
111 TAS2555_POWER_CTRL2_REG, 0xA0, //Class-D, Boost power up 123 TAS2555_POWER_CTRL2_REG, 0xA0, //Class-D, Boost power up
112 TAS2555_POWER_CTRL2_REG, 0xA3, //Class-D, Boost, IV sense power up 124 TAS2555_POWER_CTRL2_REG, 0xA3, //Class-D, Boost, IV sense power up
@@ -210,7 +222,7 @@ static int tas2555_dev_load_data(struct tas2555_priv *pTAS2555,
210 nData = pData[n * 2 + 1]; 222 nData = pData[n * 2 + 1];
211 if (nRegister == TAS2555_UDELAY) 223 if (nRegister == TAS2555_UDELAY)
212 udelay(nData); 224 udelay(nData);
213 else if (nRegister != 0xFFFFFFFF){ 225 else if (nRegister != 0xFFFFFFFF) {
214 ret = pTAS2555->write(pTAS2555, nRegister, nData); 226 ret = pTAS2555->write(pTAS2555, nRegister, nData);
215 if(ret < 0) { 227 if(ret < 0) {
216 dev_err(pTAS2555->dev, "Reg Write err %d\n", ret); 228 dev_err(pTAS2555->dev, "Reg Write err %d\n", ret);
@@ -219,16 +231,16 @@ static int tas2555_dev_load_data(struct tas2555_priv *pTAS2555,
219 } 231 }
220 n++; 232 n++;
221 } while (nRegister != 0xFFFFFFFF); 233 } while (nRegister != 0xFFFFFFFF);
222 234
223 return ret; 235 return ret;
224} 236}
225 237
226static void failsafe(struct tas2555_priv *pTAS2555) 238static void failsafe(struct tas2555_priv *pTAS2555)
227{ 239{
228 dev_err(pTAS2555->dev, "%s\n", __func__); 240 dev_err(pTAS2555->dev, "%s\n", __func__);
229 switch_set_state(&pTAS2555->sw_dev, 1); 241 pTAS2555->mnErrorCode |= TAS2555_ERROR_FAILSAFE;
230 tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_data); 242 tas2555_enable(pTAS2555, false);
231 pTAS2555->mbPowerUp = false; 243 pTAS2555->hw_reset(pTAS2555);
232 pTAS2555->write(pTAS2555, TAS2555_SW_RESET_REG, 0x01); 244 pTAS2555->write(pTAS2555, TAS2555_SW_RESET_REG, 0x01);
233 udelay(1000); 245 udelay(1000);
234 pTAS2555->write(pTAS2555, TAS2555_SPK_CTRL_REG, 0x04); 246 pTAS2555->write(pTAS2555, TAS2555_SPK_CTRL_REG, 0x04);
@@ -239,89 +251,109 @@ static void failsafe(struct tas2555_priv *pTAS2555)
239 251
240#define Q_FACTOR 0x08000000 252#define Q_FACTOR 0x08000000
241 253
242static bool chkReBoundary(unsigned int ReHigh, unsigned int ReLow) 254static bool chkReBoundary(struct tas2555_priv *pTAS2555,
255 unsigned int ReOrginal, unsigned int ReDelta, unsigned int Re, unsigned char scale, unsigned int *pActRe)
243{ 256{
244 bool ret = false; 257 bool nResult = false;
245 258 unsigned int ReHigh_calc, ReLow_calc, Re_calc = 0;
246 if (ReHigh < Q_FACTOR) 259 static unsigned int counter = 3;
247 goto end; 260
248 261 if (ReOrginal < Q_FACTOR)
249 if (ReLow < Q_FACTOR)
250 goto end;
251
252 if (ReHigh < ReLow)
253 goto end; 262 goto end;
254 263
255 ret = true; 264 switch (scale) {
265 case 0:
266 /* 8Ohm speaker */
267 Re_calc = Re;
268 *pActRe = Re;
269 ReHigh_calc = ReOrginal + ReDelta;
270 ReLow_calc = ReOrginal - ReDelta;
271 break;
272
273 case 1:
274 /* 6Ohm speaker */
275 ReDelta = (ReDelta * 4) / 3;
276 ReHigh_calc = ReOrginal + ReDelta;
277 ReLow_calc = ReOrginal - ReDelta;
278 Re_calc = Re;
279 *pActRe = (Re_calc * 3) / 4;
280 break;
281
282 case 2:
283 /* 4Ohm speaker */
284 ReDelta = ReDelta * 2;
285 ReHigh_calc = ReOrginal + ReDelta;
286 ReLow_calc = ReOrginal - ReDelta;
287 Re_calc = Re;
288 *pActRe = Re_calc / 2;
289 break;
290 }
291
292 if (Re_calc > 0) {
293 pTAS2555->mnReLastKnown = *pActRe;
294
295 if (Re_calc > ReHigh_calc) {
296 counter--;
297 pTAS2555->mnErrorCode |= TAS2555_ERROR_RETOOHIGH;
298 } else if (Re_calc < ReLow_calc) {
299 counter--;
300 pTAS2555->mnErrorCode |= TAS2555_ERROR_RETOOLOW;
301 } else
302 counter = 3;
303
304 if (counter == 0) {
305 counter = 3;
306 nResult = true;
307 }
308 }
256 309
257end: 310end:
258 return ret; 311 return nResult;
259} 312}
260 313
261int tas2555_get_Re(struct tas2555_priv *pTAS2555, unsigned int *pRe) 314static int tas2555_get_ReCoefficient(struct tas2555_priv *pTAS2555, unsigned int *pRe)
262{ 315{
263 int ret = -1; 316 int ret = 0;
264 unsigned int nRe = 0, nValue;
265 unsigned char Buf[4]; 317 unsigned char Buf[4];
266 318
267 if (pTAS2555->mbPowerUp) { 319 /* wait DSP to update the XRAM */
268 ret = pTAS2555->bulk_read(pTAS2555, TAS2555_COEFFICENT_RE_REG, Buf, 4); 320 udelay(2000);
269 if (ret < 0) {
270 dev_err(pTAS2555->dev, "I2C error\n");
271 goto err;
272 }
273 321
274 nRe = ((unsigned int)Buf[0] << 24) | ((unsigned int)Buf[1] << 16) 322 ret = pTAS2555->bulk_read(pTAS2555, TAS2555_COEFFICENT_RE_REG, Buf, 4);
275 | ((unsigned int)Buf[2] << 8) | Buf[3]; 323 if (ret < 0) {
276 324 goto err;
277 ret = pTAS2555->read(pTAS2555, TAS2555_CHANNEL_CTRL_REG, &nValue);
278 if (ret < 0) {
279 dev_err(pTAS2555->dev, "I2C error\n");
280 goto err;
281 }
282
283 nValue = (nValue & 0x06) >> 1;
284 if (nValue == 3)
285 dev_err(pTAS2555->dev, "speaker load config error \n");
286 else if (nValue == 2)
287 nRe /= 2; /* 4 Ohm speaker load */
288 else if (nValue == 1)
289 nRe = (nRe / 4) * 3; /* 6 Ohm speaker load */
290 /* else 8 Ohm speaker load */
291
292 *pRe = nRe;
293
294 if (chkReBoundary(pTAS2555->mnReHigh, pTAS2555->mnReLow)) {
295 if ((nRe < pTAS2555->mnReLow) || (nRe > pTAS2555->mnReHigh)) {
296 failsafe(pTAS2555);
297 } else {
298 dev_dbg(pTAS2555->dev, "Re passed check\n");
299 }
300 }
301 } 325 }
302 326
327 *pRe = ((unsigned int)Buf[0] << 24) | ((unsigned int)Buf[1] << 16)
328 | ((unsigned int)Buf[2] << 8) | Buf[3];
329
303err: 330err:
304 331
305 return ret; 332 return ret;
306} 333}
307 334
308int tas2555_get_f0_a1(struct tas2555_priv *pTAS2555, unsigned int *pA1) 335int tas2555_get_Re(struct tas2555_priv *pTAS2555, unsigned int *pRe)
309{ 336{
310 int ret = -1; 337 int ret = 0;
311 unsigned int nValue; 338 unsigned int nRe = 0, nValue;
312 unsigned char Buf[4];
313 339
314 if (pTAS2555->mbPowerUp) { 340 if (pTAS2555->mbPowerUp) {
315 ret = pTAS2555->bulk_read(pTAS2555, TAS2555_COEFFICENT_A1_REG, Buf, 4); 341 ret = tas2555_get_ReCoefficient(pTAS2555, &nRe);
342 if (ret < 0)
343 goto err;
344
345 ret = pTAS2555->read(pTAS2555, TAS2555_CHANNEL_CTRL_REG, &nValue);
316 if (ret < 0) { 346 if (ret < 0) {
317 dev_err(pTAS2555->dev, "I2C error\n"); 347 dev_err(pTAS2555->dev, "I2C error\n");
318 goto err; 348 goto err;
319 } 349 }
320 350
321 nValue = ((unsigned int)Buf[0] << 24) | ((unsigned int)Buf[1] << 16) 351 nValue = (nValue & 0x06) >> 1;
322 | ((unsigned int)Buf[2] << 8) | Buf[3]; 352 if (chkReBoundary(pTAS2555,
323 353 pTAS2555->mnReOrignal, pTAS2555->mnReDelta, nRe, nValue, pRe))
324 *pA1 = nValue; 354 failsafe(pTAS2555);
355 } else {
356 *pRe = pTAS2555->mnReLastKnown;
325 } 357 }
326 358
327err: 359err:
@@ -329,33 +361,63 @@ err:
329 return ret; 361 return ret;
330} 362}
331 363
332int tas2555_get_f0_a2(struct tas2555_priv *pTAS2555, unsigned int *pA2) 364int tas2555_get_errcode(struct tas2555_priv *pTAS2555, unsigned int *pErrCode)
333{ 365{
334 int ret = -1; 366 unsigned int errcode = 0;
335 unsigned int nValue; 367 unsigned int nValue = 0;
336 unsigned char Buf[4]; 368 int nResult = 0;
337 369
338 if (pTAS2555->mbPowerUp) { 370 nResult = pTAS2555->read(pTAS2555, TAS2555_FLAGS_1, &nValue);
339 ret = pTAS2555->bulk_read(pTAS2555, TAS2555_COEFFICENT_A2_REG, Buf, 4); 371 if (nResult >= 0) {
340 if (ret < 0) { 372 nResult = pTAS2555->read(pTAS2555, TAS2555_FLAGS_2, &nValue);
341 dev_err(pTAS2555->dev, "I2C error\n"); 373
342 goto err; 374 if (nValue & 0x04) {
375 errcode |= TAS2555_ERROR_CLKPRESENT;
376 nResult = pTAS2555->write(pTAS2555, TAS2555_CLK_ERR_CTRL, 0x00);
343 } 377 }
378 if (nValue & 0x08)
379 errcode |= TAS2555_ERROR_BROWNOUT;
380 if (nValue & 0x10)
381 errcode |= TAS2555_ERROR_OVERTMP;
382 if (nValue & 0x40)
383 errcode |= TAS2555_ERROR_UNDERVOLTAGET;
384 if (nValue & 0x80)
385 errcode |= TAS2555_ERROR_OVERCURRENT;
386 if (nValue & 0xdc)
387 nResult = tas2555_enable(pTAS2555, false);
388 }
389
390 *pErrCode = errcode | pTAS2555->mnErrorCode;
391 pTAS2555->mnErrorCode = 0;
392 return nResult;
393}
344 394
345 nValue = ((unsigned int)Buf[0] << 24) | ((unsigned int)Buf[1] << 16) 395int tas2555_configIRQ(struct tas2555_priv *pTAS2555)
346 | ((unsigned int)Buf[2] << 8) | Buf[3]; 396{
397 return tas2555_dev_load_data(pTAS2555, p_tas2555_irq_config);
398}
347 399
348 *pA2 = nValue; 400int tas2555_load_platdata(struct tas2555_priv *pTAS2555)
349 } 401{
402 int ret = 0;
350 403
351err: 404 if (gpio_is_valid(pTAS2555->mnGpioINT)) {
405 ret = tas2555_configIRQ(pTAS2555);
406 if (ret < 0)
407 goto end;
408 ret = pTAS2555->enableIRQ(pTAS2555, false, true);
409 }
352 410
411end:
353 return ret; 412 return ret;
354} 413}
355 414
356int tas2555_load_default(struct tas2555_priv *pTAS2555) 415int tas2555_load_default(struct tas2555_priv *pTAS2555)
357{ 416{
358 return tas2555_dev_load_data(pTAS2555, p_tas2555_default_data); 417 int ret = 0;
418
419 ret = tas2555_load_platdata(pTAS2555);
420 return ret;
359} 421}
360 422
361int tas2555_enable(struct tas2555_priv *pTAS2555, bool bEnable) 423int tas2555_enable(struct tas2555_priv *pTAS2555, bool bEnable)
@@ -373,59 +435,68 @@ int tas2555_enable(struct tas2555_priv *pTAS2555, bool bEnable)
373 } 435 }
374 dev_dbg(pTAS2555->dev, "Enable: load startup sequence\n"); 436 dev_dbg(pTAS2555->dev, "Enable: load startup sequence\n");
375 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data); 437 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data);
376 if(nResult < 0) goto end; 438 if (nResult < 0)
439 goto end;
377 if (pTAS2555->mpFirmware->mpConfigurations) { 440 if (pTAS2555->mpFirmware->mpConfigurations) {
378 pConfiguration = &(pTAS2555->mpFirmware->mpConfigurations[pTAS2555->mnCurrentConfiguration]); 441 pConfiguration = &(pTAS2555->mpFirmware->mpConfigurations[pTAS2555->mnCurrentConfiguration]);
379 nResult = tas2555_load_data(pTAS2555, &(pConfiguration->mData), 442 nResult = tas2555_load_data(pTAS2555, &(pConfiguration->mData), TAS2555_BLOCK_CONF_POST_POWER);
380 TAS2555_BLOCK_CONF_POST_POWER); 443 if (nResult < 0)
381 if(nResult < 0) goto powerdown; 444 goto end;
382 if (pTAS2555->mbLoadConfigurationPostPowerUp) { 445 if (pTAS2555->mbLoadConfigurationPostPowerUp) {
383 dev_dbg(pTAS2555->dev, "Enable: load configuration: %s, %s\n", 446 dev_dbg(pTAS2555->dev, "Enable: load configuration: %s, %s\n", pConfiguration->mpName, pConfiguration->mpDescription);
384 pConfiguration->mpName, pConfiguration->mpDescription); 447 nResult = tas2555_load_data(pTAS2555, &(pConfiguration->mData), TAS2555_BLOCK_CONF_COEFF);
385 nResult = tas2555_load_data(pTAS2555, &(pConfiguration->mData), 448 if (nResult < 0)
386 TAS2555_BLOCK_CONF_COEFF); 449 goto end;
387 if(nResult < 0) goto powerdown;
388 pTAS2555->mbLoadConfigurationPostPowerUp = false; 450 pTAS2555->mbLoadConfigurationPostPowerUp = false;
389 if (pTAS2555->mpCalFirmware->mnCalibrations) { 451 if (pTAS2555->mpCalFirmware->mnCalibrations) {
390 dev_dbg(pTAS2555->dev, "Enable: load calibration\n"); 452 dev_dbg(pTAS2555->dev, "Enable: load calibration\n");
391 nResult = tas2555_load_block(pTAS2555, 453 nResult = tas2555_load_block(pTAS2555, &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock));
392 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock)); 454 if (nResult < 0)
393 if(nResult < 0) goto powerdown; 455 goto end;
456 nResult = tas2555_get_ReCoefficient(pTAS2555, &pTAS2555->mnReOrignal);
457 if (nResult < 0)
458 goto end;
394 pTAS2555->mbLoadCalibrationPostPowerUp = false; 459 pTAS2555->mbLoadCalibrationPostPowerUp = false;
460 } else if (pTAS2555->mnReOrignal == 0) {
461 nResult = tas2555_get_ReCoefficient(pTAS2555, &pTAS2555->mnReOrignal);
462 if (nResult < 0)
463 goto end;
395 } 464 }
396 }else{ 465 } else {
397 if (pTAS2555->mpCalFirmware->mnCalibrations) { 466 if (pTAS2555->mpCalFirmware->mnCalibrations) {
398 if(pTAS2555->mbLoadCalibrationPostPowerUp){ 467 if (pTAS2555->mbLoadCalibrationPostPowerUp) {
399 dev_dbg(pTAS2555->dev, "Enable: load calibration\n"); 468 dev_dbg(pTAS2555->dev, "Enable: load calibration\n");
400 nResult = tas2555_load_block(pTAS2555, 469 nResult = tas2555_load_block(pTAS2555, &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock));
401 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock)); 470 if (nResult < 0)
402 if(nResult < 0) goto powerdown; 471 goto end;
472 nResult = tas2555_get_ReCoefficient(pTAS2555, &pTAS2555->mnReOrignal);
473 if (nResult < 0)
474 goto end;
403 pTAS2555->mbLoadCalibrationPostPowerUp = false; 475 pTAS2555->mbLoadCalibrationPostPowerUp = false;
404 } 476 }
405 } 477 }
406 } 478 }
407 } 479 }
480
408 dev_dbg(pTAS2555->dev, "Enable: load unmute sequence\n"); 481 dev_dbg(pTAS2555->dev, "Enable: load unmute sequence\n");
409 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data); 482 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data);
410 if(nResult < 0) goto end; 483 if (nResult < 0)
484 goto end;
411 pTAS2555->mbPowerUp = true; 485 pTAS2555->mbPowerUp = true;
412 } 486 }
413 } else { 487 } else {
414 if (pTAS2555->mbPowerUp) { 488 if (pTAS2555->mbPowerUp) {
415 dev_dbg(pTAS2555->dev, "Enable: load shutdown sequence\n"); 489 dev_dbg(pTAS2555->dev, "Enable: load shutdown sequence\n");
416 tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_data); 490 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_data);
417 //tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_clk_err); 491 //tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_clk_err);
418 pTAS2555->mbPowerUp = false; 492 pTAS2555->mbPowerUp = false;
419 } 493 }
420 } 494 }
421 495
422powerdown:
423 if(nResult < 0){
424 failsafe(pTAS2555);
425 }
426
427end: 496end:
428 497 if (nResult < 0)
498 failsafe(pTAS2555);
499
429 return nResult; 500 return nResult;
430} 501}
431 502
@@ -460,7 +531,7 @@ int tas2555_set_sampling_rate(struct tas2555_priv *pTAS2555, unsigned int nSampl
460 dev_info(pTAS2555->dev, 531 dev_info(pTAS2555->dev,
461 "Found configuration: %s, with compatible sampling rate %d\n", 532 "Found configuration: %s, with compatible sampling rate %d\n",
462 pConfiguration->mpName, nSamplingRate); 533 pConfiguration->mpName, nSamplingRate);
463 return tas2555_load_configuration(pTAS2555, nConfiguration, false); 534 return tas2555_load_configuration(pTAS2555, nConfiguration, false);
464 } 535 }
465 } 536 }
466 537
@@ -819,150 +890,122 @@ static int isYRAM(struct tas2555_priv *pTAS2555, TYCRC *pCRCData,
819 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len) 890 unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len)
820{ 891{
821 int result = -1; 892 int result = -1;
822 893
823 if(nBook == TAS2555_YRAM_BOOK){ 894 if (nBook == TAS2555_YRAM_BOOK) {
824 if(nPage == TAS2555_YRAM1_PAGE) 895 if (nPage == TAS2555_YRAM1_PAGE) {
825 { 896 if ((nReg >= TAS2555_YRAM1_START_REG)
826 if((nReg >= TAS2555_YRAM1_START_REG) 897 &&(nReg <= TAS2555_YRAM1_END_REG)) {
827 &&(nReg <= TAS2555_YRAM1_END_REG)) 898 if ((nReg + len -1) <= TAS2555_YRAM1_END_REG) {
828 {
829 if((nReg + len -1) <= TAS2555_YRAM1_END_REG){
830 result = 1; 899 result = 1;
831 if(pCRCData != NULL){ 900 if (pCRCData != NULL) {
832 pCRCData->mnOffset = nReg; 901 pCRCData->mnOffset = nReg;
833 pCRCData->mnLen = len; 902 pCRCData->mnLen = len;
834 } 903 }
835 } 904 } else {
836 else 905 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
837 {
838 dev_err(pTAS2555->dev, "nReg 0x%x error, len %d\n", nReg, len); 906 dev_err(pTAS2555->dev, "nReg 0x%x error, len %d\n", nReg, len);
839 } 907 }
840 } 908 } else if (nReg > TAS2555_YRAM1_END_REG) {
841 else if(nReg > TAS2555_YRAM1_END_REG) 909 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
842 {
843 dev_err(pTAS2555->dev, "nReg 0x%x error\n", nReg); 910 dev_err(pTAS2555->dev, "nReg 0x%x error\n", nReg);
844 } 911 } else if (len > 1) {
845 else if(len > 1) 912 if ((nReg + (len-1))> TAS2555_YRAM1_END_REG) {
846 {
847 if((nReg + (len-1)) > TAS2555_YRAM1_END_REG)
848 {
849 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len); 913 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len);
850 } 914 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
851 else if((nReg + (len-1)) >= TAS2555_YRAM1_START_REG) 915 } else if ((nReg + (len-1)) >= TAS2555_YRAM1_START_REG) {
852 {
853 result = 1; 916 result = 1;
854 if(pCRCData != NULL){ 917 if (pCRCData != NULL) {
855 pCRCData->mnOffset = TAS2555_YRAM1_START_REG; 918 pCRCData->mnOffset = TAS2555_YRAM1_START_REG;
856 pCRCData->mnLen = nReg + len - TAS2555_YRAM1_START_REG; 919 pCRCData->mnLen = nReg + len - TAS2555_YRAM1_START_REG;
857 } 920 }
858 } 921 } else
859 else
860 result = 0; 922 result = 0;
861 } 923 } else
862 else
863 result = 0; 924 result = 0;
864 } 925 } else if ((nPage >= TAS2555_YRAM2_START_PAGE)
865 else if((nPage >= TAS2555_YRAM2_START_PAGE) 926 && (nPage <= TAS2555_YRAM2_END_PAGE)) {
866 && (nPage <= TAS2555_YRAM2_END_PAGE)) 927 if (nReg > TAS2555_YRAM2_END_REG) {
867 {
868 if(nReg > TAS2555_YRAM2_END_REG)
869 {
870 dev_err(pTAS2555->dev, "nReg 0x%x error\n", nReg); 928 dev_err(pTAS2555->dev, "nReg 0x%x error\n", nReg);
871 } 929 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
872 else if((nReg >= TAS2555_YRAM2_START_REG) 930 } else if ((nReg >= TAS2555_YRAM2_START_REG)
873 &&(nReg <= TAS2555_YRAM2_END_REG)) 931 && (nReg <= TAS2555_YRAM2_END_REG)) {
874 { 932 if ((nReg + len -1) <= TAS2555_YRAM2_END_REG) {
875 if((nReg + len -1) <= TAS2555_YRAM2_END_REG){
876 result = 1; 933 result = 1;
877 if(pCRCData != NULL){ 934 if (pCRCData != NULL) {
878 pCRCData->mnOffset = nReg; 935 pCRCData->mnOffset = nReg;
879 pCRCData->mnLen = len; 936 pCRCData->mnLen = len;
880 } 937 }
881 } 938 } else {
882 else
883 {
884 dev_err(pTAS2555->dev, "nReg 0x%x error, len %d\n", nReg, len); 939 dev_err(pTAS2555->dev, "nReg 0x%x error, len %d\n", nReg, len);
940 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
885 } 941 }
886 } 942 } else if (len > 1) {
887 else if(len > 1) 943 if ((nReg + (len-1)) > TAS2555_YRAM2_END_REG) {
888 {
889 if((nReg + (len-1)) > TAS2555_YRAM2_END_REG)
890 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len); 944 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len);
891 else if((nReg + (len-1)) >= TAS2555_YRAM2_START_REG) 945 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
892 { 946 } else if ((nReg + (len-1)) >= TAS2555_YRAM2_START_REG) {
893 result = 1; 947 result = 1;
894 if(pCRCData != NULL){ 948 if (pCRCData != NULL) {
895 pCRCData->mnOffset = TAS2555_YRAM2_START_REG; 949 pCRCData->mnOffset = TAS2555_YRAM2_START_REG;
896 pCRCData->mnLen = nReg + len - TAS2555_YRAM1_START_REG; 950 pCRCData->mnLen = nReg + len - TAS2555_YRAM1_START_REG;
897 } 951 }
898 } 952 } else
899 else 953 result = 0;
900 result = 0; 954 }else
901 }
902 else
903 result = 0; 955 result = 0;
904 } 956 } else if(nPage == TAS2555_YRAM3_PAGE) {
905 else if(nPage == TAS2555_YRAM3_PAGE) 957 if (nReg > TAS2555_YRAM2_END_REG) {
906 {
907 if(nReg > TAS2555_YRAM2_END_REG){
908 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len); 958 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len);
909 } 959 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
910 else if(nReg > TAS2555_YRAM3_END_REG) 960 } else if (nReg > TAS2555_YRAM3_END_REG)
911 result = 0; 961 result = 0;
912 else if(nReg >= TAS2555_YRAM3_START_REG) 962 else if (nReg >= TAS2555_YRAM3_START_REG) {
913 { 963 if ((nReg + len -1) <= TAS2555_YRAM3_END_REG) {
914 if((nReg + len -1) <= TAS2555_YRAM3_END_REG){ 964 if (pCRCData != NULL) {
915 if(pCRCData != NULL){
916 pCRCData->mnOffset = nReg; 965 pCRCData->mnOffset = nReg;
917 pCRCData->mnLen = len; 966 pCRCData->mnLen = len;
918 } 967 }
919 result = 1; 968 result = 1;
920 }else if((nReg + len -1) <= TAS2555_YRAM2_END_REG){ 969 } else if((nReg + len -1) <= TAS2555_YRAM2_END_REG) {
921 if(pCRCData != NULL){ 970 if (pCRCData != NULL) {
922 pCRCData->mnOffset = nReg; 971 pCRCData->mnOffset = nReg;
923 pCRCData->mnLen = TAS2555_YRAM3_END_REG - nReg + 1; 972 pCRCData->mnLen = TAS2555_YRAM3_END_REG - nReg + 1;
924 } 973 }
925 result = 1; 974 result = 1;
926 }else{ 975 } else {
927 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len);
928 }
929 }
930 else if(len > 1)
931 {
932 if((nReg + (len-1)) > TAS2555_YRAM2_END_REG)
933 {
934 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len); 976 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len);
977 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
935 } 978 }
936 else if((nReg + (len-1)) >= TAS2555_YRAM3_START_REG) 979 } else if (len > 1) {
937 { 980 if ((nReg + (len-1)) > TAS2555_YRAM2_END_REG) {
938 if((nReg + len -1) <= TAS2555_YRAM3_END_REG){ 981 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len);
939 if(pCRCData != NULL){ 982 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
983 } else if ((nReg + (len-1)) >= TAS2555_YRAM3_START_REG) {
984 if ((nReg + len -1) <= TAS2555_YRAM3_END_REG) {
985 if (pCRCData != NULL) {
940 pCRCData->mnOffset = TAS2555_YRAM3_START_REG; 986 pCRCData->mnOffset = TAS2555_YRAM3_START_REG;
941 pCRCData->mnLen = nReg + len - TAS2555_YRAM3_START_REG; 987 pCRCData->mnLen = nReg + len - TAS2555_YRAM3_START_REG;
942 } 988 }
943 result = 1; 989 result = 1;
944 }else if((nReg + len -1) <= TAS2555_YRAM2_END_REG){ 990 } else if((nReg + len -1) <= TAS2555_YRAM2_END_REG) {
945 if(pCRCData != NULL){ 991 if (pCRCData != NULL) {
946 pCRCData->mnOffset = TAS2555_YRAM3_START_REG; 992 pCRCData->mnOffset = TAS2555_YRAM3_START_REG;
947 pCRCData->mnLen = TAS2555_YRAM3_END_REG - TAS2555_YRAM3_START_REG + 1; 993 pCRCData->mnLen = TAS2555_YRAM3_END_REG - TAS2555_YRAM3_START_REG + 1;
948 } 994 }
949 result = 1; 995 result = 1;
950 }else{ 996 } else {
997 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
951 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len); 998 dev_err(pTAS2555->dev, "nReg 0x%x, len %d error\n", nReg, len);
952 } 999 }
953 } 1000 } else
954 else
955 result = 0; 1001 result = 0;
956 } 1002 } else
957 else
958 result = 0; 1003 result = 0;
959 } 1004 } else
960 else
961 result = 0; 1005 result = 0;
962 } 1006 } else
963 else
964 result = 0; 1007 result = 0;
965 1008
966 return result; 1009 return result;
967} 1010}
968 1011
@@ -989,28 +1032,31 @@ static int doSingleRegCheckSum(struct tas2555_priv *pTAS2555,
989 int nResult = -1; 1032 int nResult = -1;
990 unsigned int nData = 0; 1033 unsigned int nData = 0;
991 unsigned char nRegVal = 0; 1034 unsigned char nRegVal = 0;
992 1035
993 nResult = isYRAM(pTAS2555, NULL, nBook, nPage, nReg, 1); 1036 nResult = isYRAM(pTAS2555, NULL, nBook, nPage, nReg, 1);
994 if(nResult < 0){ 1037 if (nResult < 0) {
995 dev_err(pTAS2555->dev, "firmware error\n"); 1038 dev_err(pTAS2555->dev, "firmware error\n");
996 goto err; 1039 goto end;
997 }else if(nResult == 1){ 1040 } else if (nResult == 1) {
998 nResult = pTAS2555->read(pTAS2555, TAS2555_REG(nBook, nPage, nReg), &nData); 1041 nResult = pTAS2555->read(pTAS2555, TAS2555_REG(nBook, nPage, nReg), &nData);
999 if(nResult < 0) goto err; 1042 if (nResult < 0) {
1043 goto end;
1044 }
1000 nRegVal = (unsigned char)nData; 1045 nRegVal = (unsigned char)nData;
1001 if(nValue != nRegVal){ 1046 if(nValue != nRegVal){
1002 dev_err(pTAS2555->dev, 1047 dev_err(pTAS2555->dev,
1003 "error (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n", 1048 "error (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1004 __LINE__, nBook, nPage, nReg, nValue, nRegVal); 1049 __LINE__, nBook, nPage, nReg, nValue, nRegVal);
1005 nResult = -1; 1050 nResult = -EAGAIN;
1006 goto err; 1051 pTAS2555->mnErrorCode |= TAS2555_ERROR_VALUENOTMATCH;
1052 goto end;
1007 } 1053 }
1008 1054
1009 nResult = ti_crc8(crc8_lookup_table, &nRegVal, 1, 0); 1055 nResult = ti_crc8(crc8_lookup_table, &nRegVal, 1, 0);
1010 } 1056 }
1011 1057
1012err: 1058end:
1013 1059
1014 return nResult; 1060 return nResult;
1015} 1061}
1016 1062
@@ -1021,39 +1067,40 @@ static int doMultiRegCheckSum(struct tas2555_priv *pTAS2555,
1021 unsigned char nCRCChkSum = 0; 1067 unsigned char nCRCChkSum = 0;
1022 unsigned char nBuf[127]; 1068 unsigned char nBuf[127];
1023 TYCRC TCRCData; 1069 TYCRC TCRCData;
1024 1070
1025 if((nReg + len-1) > 127) { 1071 if ((nReg + len-1) > 127) {
1026 dev_err(pTAS2555->dev, "firmware error\n"); 1072 dev_err(pTAS2555->dev, "firmware error\n");
1073 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
1027 goto err; 1074 goto err;
1028 } 1075 }
1029 1076
1030 nResult = isYRAM(pTAS2555, &TCRCData, nBook, nPage, nReg, len); 1077 nResult = isYRAM(pTAS2555, &TCRCData, nBook, nPage, nReg, len);
1031 if(nResult < 0){ 1078 if (nResult < 0) {
1032 dev_err(pTAS2555->dev, "firmware error\n"); 1079 dev_err(pTAS2555->dev, "firmware error\n");
1033 goto err; 1080 goto err;
1034 }else if(nResult == 1){ 1081 } else if (nResult == 1) {
1035 if(len == 1){ 1082 if (len == 1) {
1083 /* here shouldn't happen */
1036 dev_err(pTAS2555->dev, "firmware error\n"); 1084 dev_err(pTAS2555->dev, "firmware error\n");
1037 goto err; 1085 goto err;
1038 } 1086 } else {
1039 else
1040 {
1041 nResult = pTAS2555->bulk_read(pTAS2555, 1087 nResult = pTAS2555->bulk_read(pTAS2555,
1042 TAS2555_REG(nBook, nPage, TCRCData.mnOffset), nBuf, TCRCData.mnLen); 1088 TAS2555_REG(nBook, nPage, TCRCData.mnOffset), nBuf, TCRCData.mnLen);
1043 if(nResult < 0) goto err; 1089 if(nResult < 0) {
1044 1090 goto err;
1045 for(i=0; i < TCRCData.mnLen; i++){ 1091 }
1092 for (i=0; i < TCRCData.mnLen; i++) {
1046 nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf[i], 1, 0); 1093 nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf[i], 1, 0);
1047 } 1094 }
1048
1049 nResult = nCRCChkSum; 1095 nResult = nCRCChkSum;
1050 } 1096 }
1051 } 1097 }
1052 1098
1053err: 1099err:
1054 1100
1055 return nResult; 1101 return nResult;
1056} 1102}
1103
1057static int tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock) 1104static int tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock)
1058{ 1105{
1059 int nResult = 0; 1106 int nResult = 0;
@@ -1072,21 +1119,24 @@ static int tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock)
1072 pBlock->mnType, pBlock->mnCommands); 1119 pBlock->mnType, pBlock->mnCommands);
1073 1120
1074start: 1121start:
1075 if(pBlock->mbPChkSumPresent){ 1122 if (pBlock->mbPChkSumPresent) {
1076 nResult = pTAS2555->write(pTAS2555, TAS2555_CRC_RESET_REG, 1); 1123 nResult = pTAS2555->write(pTAS2555, TAS2555_CRC_RESET_REG, 1);
1077 if(nResult < 0) { 1124 if (nResult < 0) {
1078 dev_err(pTAS2555->dev, "I2C err\n"); 1125 dev_err(pTAS2555->dev, "I2C err\n");
1079 goto err; 1126 goto end;
1080 } 1127 }
1128 pTAS2555->mnErrorCode &= ~TAS2555_ERROR_PCHKSUM;
1081 } 1129 }
1082 1130
1083 if(pBlock->mbYChkSumPresent) nCRCChkSum = 0; 1131 if (pBlock->mbYChkSumPresent) {
1084 1132 nCRCChkSum = 0;
1133 pTAS2555->mnErrorCode &= ~TAS2555_ERROR_YCHKSUM;
1134 }
1135
1085 nCommand = 0; 1136 nCommand = 0;
1086 1137
1087 while (nCommand < pBlock->mnCommands) { 1138 while (nCommand < pBlock->mnCommands) {
1088 pData = pBlock->mpData + nCommand * 4; 1139 pData = pBlock->mpData + nCommand * 4;
1089
1090 nBook = pData[0]; 1140 nBook = pData[0];
1091 nPage = pData[1]; 1141 nPage = pData[1];
1092 nOffset = pData[2]; 1142 nOffset = pData[2];
@@ -1095,85 +1145,90 @@ start:
1095 nCommand++; 1145 nCommand++;
1096 1146
1097 if (nOffset <= 0x7F){ 1147 if (nOffset <= 0x7F){
1098 nResult = pTAS2555->write(pTAS2555, TAS2555_REG(nBook, nPage, nOffset), nData); 1148 nResult = pTAS2555->write(pTAS2555, TAS2555_REG(nBook, nPage, nOffset), nData);
1099 1149 if (nResult < 0) {
1100 if(nResult < 0) goto err; 1150 goto end;
1101 1151 }
1102 if(pBlock->mbYChkSumPresent){ 1152 if (pBlock->mbYChkSumPresent) {
1103 nResult = doSingleRegCheckSum(pTAS2555, nBook, nPage, nOffset, nData); 1153 nResult = doSingleRegCheckSum(pTAS2555, nBook, nPage, nOffset, nData);
1104 if(nResult < 0) goto err; 1154 if (nResult < 0)
1155 goto check;
1105 nCRCChkSum += (unsigned char)nResult; 1156 nCRCChkSum += (unsigned char)nResult;
1106 } 1157 }
1107 1158 } else if (nOffset == 0x81) {
1108 }else if (nOffset == 0x81) {
1109 unsigned int nSleep = (nBook << 8) + nPage; 1159 unsigned int nSleep = (nBook << 8) + nPage;
1110 msleep(nSleep); 1160 msleep(nSleep);
1111 }else if (nOffset == 0x85) { 1161 } else if (nOffset == 0x85) {
1112 pData += 4; 1162 pData += 4;
1113 nLength = (nBook << 8) + nPage; 1163 nLength = (nBook << 8) + nPage;
1114 nBook = pData[0]; 1164 nBook = pData[0];
1115 nPage = pData[1]; 1165 nPage = pData[1];
1116 nOffset = pData[2]; 1166 nOffset = pData[2];
1117 if (nLength > 1){ 1167 if (nLength > 1) {
1118 pTAS2555->bulk_write(pTAS2555, TAS2555_REG(nBook, nPage, 1168 nResult = pTAS2555->bulk_write(pTAS2555, TAS2555_REG(nBook, nPage, nOffset), pData + 3, nLength);
1119 nOffset), pData + 3, nLength); 1169 if (nResult < 0) {
1120 if(pBlock->mbYChkSumPresent){ 1170 goto end;
1171 }
1172 if (pBlock->mbYChkSumPresent) {
1121 nResult = doMultiRegCheckSum(pTAS2555, nBook, nPage, nOffset, nLength); 1173 nResult = doMultiRegCheckSum(pTAS2555, nBook, nPage, nOffset, nLength);
1122 if(nResult < 0) goto err; 1174 if (nResult < 0)
1175 goto check;
1123 nCRCChkSum += (unsigned char)nResult; 1176 nCRCChkSum += (unsigned char)nResult;
1124 } 1177 }
1125 } 1178 } else {
1126 else{ 1179 nResult = pTAS2555->write(pTAS2555, TAS2555_REG(nBook, nPage, nOffset), pData[3]);
1127 pTAS2555->write(pTAS2555, TAS2555_REG(nBook, nPage, nOffset), 1180 if (nResult < 0) {
1128 pData[3]); 1181 goto end;
1129 1182 }
1130 if(pBlock->mbYChkSumPresent){ 1183 if (pBlock->mbYChkSumPresent) {
1131 nResult = doSingleRegCheckSum(pTAS2555, nBook, nPage, nOffset, pData[3]); 1184 nResult = doSingleRegCheckSum(pTAS2555, nBook, nPage, nOffset, pData[3]);
1132 if(nResult < 0) goto err; 1185 if (nResult < 0)
1186 goto check;
1133 nCRCChkSum += (unsigned char)nResult; 1187 nCRCChkSum += (unsigned char)nResult;
1134 } 1188 }
1135 } 1189 }
1136 nCommand++; 1190 nCommand++;
1137 if (nLength >= 2) 1191 if (nLength >= 2)
1138 nCommand += ((nLength - 2) / 4) + 1; 1192 nCommand += ((nLength - 2) / 4) + 1;
1139 } 1193 }
1140 } 1194 }
1141 1195
1142 if(pBlock->mbPChkSumPresent){ 1196 if (pBlock->mbPChkSumPresent) {
1143 pTAS2555->read(pTAS2555, TAS2555_CRC_CHECKSUM_REG, &nValue); 1197 pTAS2555->read(pTAS2555, TAS2555_CRC_CHECKSUM_REG, &nValue);
1144 if((nValue&0xff) != pBlock->mnPChkSum){ 1198 if ((nValue&0xff) != pBlock->mnPChkSum) {
1145 dev_err(pTAS2555->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n", 1199 dev_err(pTAS2555->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
1146 pBlock->mnPChkSum, (nValue&0xff)); 1200 pBlock->mnPChkSum, (nValue&0xff));
1147 nRetry--; 1201 nResult = -EAGAIN;
1148 if(nRetry != 0) { 1202 pTAS2555->mnErrorCode |= TAS2555_ERROR_PCHKSUM;
1149 dev_info(pTAS2555->dev, "try to reload block type(%d)\n", pBlock->mnType); 1203 goto check;
1150 goto start; 1204 } else {
1151 } 1205 nResult = 0;
1152 nResult = -1;
1153 goto err;
1154 }else{
1155 dev_dbg(pTAS2555->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType); 1206 dev_dbg(pTAS2555->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType);
1156 } 1207 }
1157 } 1208 }
1158 1209
1159 if(pBlock->mbYChkSumPresent){ 1210 if (pBlock->mbYChkSumPresent) {
1160 if(nCRCChkSum != pBlock->mnYChkSum){ 1211 if (nCRCChkSum != pBlock->mnYChkSum) {
1161 dev_err(pTAS2555->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n", 1212 dev_err(pTAS2555->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n",
1162 pBlock->mnYChkSum, nCRCChkSum); 1213 pBlock->mnYChkSum, nCRCChkSum);
1163 nRetry--; 1214 pTAS2555->mnErrorCode |= TAS2555_ERROR_YCHKSUM;
1164 if(nRetry != 0) { 1215 nResult = -EAGAIN;
1165 dev_info(pTAS2555->dev, "try to reload block type(%d)\n", pBlock->mnType); 1216 goto check;
1166 goto start; 1217 } else {
1167 } 1218 nResult = 0;
1168 nResult = -1;
1169 goto err;
1170 }else{
1171 dev_dbg(pTAS2555->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType); 1219 dev_dbg(pTAS2555->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType);
1172 } 1220 }
1173 } 1221 }
1174 1222
1175err: 1223check:
1176 if(nResult < 0){ 1224 if (nResult == -EAGAIN) {
1225 nRetry--;
1226 if (nRetry > 0)
1227 goto start;
1228 }
1229
1230end:
1231 if (nResult < 0) {
1177 dev_err(pTAS2555->dev, "Block (%d) load error\n", 1232 dev_err(pTAS2555->dev, "Block (%d) load error\n",
1178 pBlock->mnType); 1233 pBlock->mnType);
1179 } 1234 }
@@ -1193,12 +1248,13 @@ static int tas2555_load_data(struct tas2555_priv *pTAS2555, TData * pData,
1193 1248
1194 for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) { 1249 for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) {
1195 pBlock = &(pData->mpBlocks[nBlock]); 1250 pBlock = &(pData->mpBlocks[nBlock]);
1196 if (pBlock->mnType == nType){ 1251 if (pBlock->mnType == nType) {
1197 nResult = tas2555_load_block(pTAS2555, pBlock); 1252 nResult = tas2555_load_block(pTAS2555, pBlock);
1198 if(nResult < 0) break; 1253 if (nResult < 0)
1254 break;
1199 } 1255 }
1200 } 1256 }
1201 1257
1202 return nResult; 1258 return nResult;
1203} 1259}
1204 1260
@@ -1215,12 +1271,14 @@ static int tas2555_load_configuration(struct tas2555_priv *pTAS2555,
1215 if ((!pTAS2555->mpFirmware->mpPrograms) || 1271 if ((!pTAS2555->mpFirmware->mpPrograms) ||
1216 (!pTAS2555->mpFirmware->mpConfigurations)) { 1272 (!pTAS2555->mpFirmware->mpConfigurations)) {
1217 dev_err(pTAS2555->dev, "Firmware not loaded\n"); 1273 dev_err(pTAS2555->dev, "Firmware not loaded\n");
1274 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWNOTLOAD;
1218 return -1; 1275 return -1;
1219 } 1276 }
1220 1277
1221 if (nConfiguration >= pTAS2555->mpFirmware->mnConfigurations) { 1278 if (nConfiguration >= pTAS2555->mpFirmware->mnConfigurations) {
1222 dev_err(pTAS2555->dev, "Configuration %d doesn't exist\n", 1279 dev_err(pTAS2555->dev, "Configuration %d doesn't exist\n",
1223 nConfiguration); 1280 nConfiguration);
1281 pTAS2555->mnErrorCode |= TAS2555_ERROR_INVALIDPARAM;
1224 return -1; 1282 return -1;
1225 } 1283 }
1226 1284
@@ -1239,6 +1297,7 @@ static int tas2555_load_configuration(struct tas2555_priv *pTAS2555,
1239 dev_err(pTAS2555->dev, 1297 dev_err(pTAS2555->dev,
1240 "Configuration %d, %s doesn't share the same program as current %d\n", 1298 "Configuration %d, %s doesn't share the same program as current %d\n",
1241 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram); 1299 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
1300 pTAS2555->mnErrorCode |= TAS2555_ERROR_INVALIDPARAM;
1242 return -1; 1301 return -1;
1243 } 1302 }
1244 1303
@@ -1246,9 +1305,10 @@ static int tas2555_load_configuration(struct tas2555_priv *pTAS2555,
1246 dev_err(pTAS2555->dev, 1305 dev_err(pTAS2555->dev,
1247 "Configuration %d, %s doesn't have a valid PLL index %d\n", 1306 "Configuration %d, %s doesn't have a valid PLL index %d\n",
1248 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL); 1307 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
1308 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
1249 return -1; 1309 return -1;
1250 } 1310 }
1251 1311
1252 pNewPLL = &(pTAS2555->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]); 1312 pNewPLL = &(pTAS2555->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
1253 1313
1254 if (pTAS2555->mbPowerUp) { 1314 if (pTAS2555->mbPowerUp) {
@@ -1257,59 +1317,69 @@ static int tas2555_load_configuration(struct tas2555_priv *pTAS2555,
1257 "TAS2555 is powered up -> mute and power down DSP before loading new configuration\n"); 1317 "TAS2555 is powered up -> mute and power down DSP before loading new configuration\n");
1258 //tas2555_dev_load_data(pTAS2555, p_tas2555_mute_DSP_down_data); 1318 //tas2555_dev_load_data(pTAS2555, p_tas2555_mute_DSP_down_data);
1259 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_data); 1319 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_shutdown_data);
1260 if(nResult < 0) goto end; 1320 if (nResult < 0)
1321 goto end;
1261 dev_dbg(pTAS2555->dev, 1322 dev_dbg(pTAS2555->dev,
1262 "load post block from current configuration: %s, before loading new configuration: %s\n", 1323 "load post block from current configuration: %s, before loading new configuration: %s\n",
1263 pCurrentConfiguration->mpName, pNewConfiguration->mpName); 1324 pCurrentConfiguration->mpName, pNewConfiguration->mpName);
1264 nResult = tas2555_load_data(pTAS2555, &(pCurrentConfiguration->mData), 1325 nResult = tas2555_load_data(pTAS2555, &(pCurrentConfiguration->mData),
1265 TAS2555_BLOCK_CONF_POST); 1326 TAS2555_BLOCK_CONF_POST);
1266 if(nResult < 0) goto powerdown; 1327 if (nResult < 0)
1328 goto end;
1267 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n", 1329 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n",
1268 pNewPLL->mpName); 1330 pNewPLL->mpName);
1269 nResult = tas2555_load_block(pTAS2555, &(pNewPLL->mBlock)); 1331 nResult = tas2555_load_block(pTAS2555, &(pNewPLL->mBlock));
1270 if(nResult < 0) goto powerdown; 1332 if (nResult < 0)
1333 goto end;
1271 pTAS2555->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate; 1334 pTAS2555->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
1272 dev_dbg(pTAS2555->dev, 1335 dev_dbg(pTAS2555->dev,
1273 "load new configuration: %s, pre block data\n", 1336 "load new configuration: %s, pre block data\n",
1274 pNewConfiguration->mpName); 1337 pNewConfiguration->mpName);
1275 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData), 1338 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
1276 TAS2555_BLOCK_CONF_PRE); 1339 TAS2555_BLOCK_CONF_PRE);
1277 if(nResult < 0) goto powerdown; 1340 if (nResult < 0)
1341 goto end;
1278 dev_dbg(pTAS2555->dev, "TAS2555: power up TAS2555\n"); 1342 dev_dbg(pTAS2555->dev, "TAS2555: power up TAS2555\n");
1279 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data); 1343 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data);
1280 if(nResult < 0) goto end; 1344 if (nResult < 0)
1345 goto end;
1281 dev_dbg(pTAS2555->dev, 1346 dev_dbg(pTAS2555->dev,
1282 "TAS2555: load new configuration: %s, post power up block data\n", 1347 "TAS2555: load new configuration: %s, post power up block data\n",
1283 pNewConfiguration->mpName); 1348 pNewConfiguration->mpName);
1284 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData), 1349 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
1285 TAS2555_BLOCK_CONF_POST_POWER); 1350 TAS2555_BLOCK_CONF_POST_POWER);
1286 if(nResult < 0) goto powerdown; 1351 if (nResult < 0)
1352 goto end;
1287 dev_dbg(pTAS2555->dev, 1353 dev_dbg(pTAS2555->dev,
1288 "TAS2555: load new configuration: %s, coeff block data\n", 1354 "TAS2555: load new configuration: %s, coeff block data\n",
1289 pNewConfiguration->mpName); 1355 pNewConfiguration->mpName);
1290 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData), 1356 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
1291 TAS2555_BLOCK_CONF_COEFF); 1357 TAS2555_BLOCK_CONF_COEFF);
1292 if(nResult < 0) goto powerdown; 1358 if (nResult < 0)
1359 goto end;
1293 dev_dbg(pTAS2555->dev, "TAS2555: unmute TAS2555\n"); 1360 dev_dbg(pTAS2555->dev, "TAS2555: unmute TAS2555\n");
1294 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data); 1361 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data);
1295 if(nResult < 0) goto end; 1362 if (nResult < 0)
1363 goto end;
1296 } else { 1364 } else {
1297 dev_dbg(pTAS2555->dev, 1365 dev_dbg(pTAS2555->dev,
1298 "TAS2555 is powered up, no change in PLL: load new configuration: %s, coeff block data\n", 1366 "TAS2555 is powered up, no change in PLL: load new configuration: %s, coeff block data\n",
1299 pNewConfiguration->mpName); 1367 pNewConfiguration->mpName);
1300 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData), 1368 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
1301 TAS2555_BLOCK_CONF_COEFF); 1369 TAS2555_BLOCK_CONF_COEFF);
1302 if(nResult < 0) goto powerdown; 1370 if (nResult < 0)
1371 goto end;
1303 } 1372 }
1304 1373
1305 if (pTAS2555->mpCalFirmware->mnCalibrations) { 1374 if (pTAS2555->mpCalFirmware->mnCalibrations) {
1306 dev_dbg(pTAS2555->dev, "Enable: load calibration\n"); 1375 dev_dbg(pTAS2555->dev, "Enable: load calibration\n");
1307 nResult = tas2555_load_block(pTAS2555, 1376 nResult = tas2555_load_block(pTAS2555,
1308 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock)); 1377 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock));
1309 pTAS2555->mbLoadCalibrationPostPowerUp = false; 1378 pTAS2555->mbLoadCalibrationPostPowerUp = false;
1310 if(nResult < 0) goto powerdown; 1379 if (nResult < 0)
1380 goto end;
1311 } 1381 }
1312 1382
1313 pTAS2555->mbLoadConfigurationPostPowerUp = false; 1383 pTAS2555->mbLoadConfigurationPostPowerUp = false;
1314 } else { 1384 } else {
1315 dev_dbg(pTAS2555->dev, 1385 dev_dbg(pTAS2555->dev,
@@ -1320,34 +1390,34 @@ static int tas2555_load_configuration(struct tas2555_priv *pTAS2555,
1320 pCurrentConfiguration->mpName, pNewConfiguration->mpName); 1390 pCurrentConfiguration->mpName, pNewConfiguration->mpName);
1321 nResult = tas2555_load_data(pTAS2555, &(pCurrentConfiguration->mData), 1391 nResult = tas2555_load_data(pTAS2555, &(pCurrentConfiguration->mData),
1322 TAS2555_BLOCK_CONF_POST); 1392 TAS2555_BLOCK_CONF_POST);
1323 if(nResult < 0) goto powerdown; 1393 if (nResult < 0)
1394 goto end;
1324 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n", 1395 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n",
1325 pNewPLL->mpName); 1396 pNewPLL->mpName);
1326 nResult = tas2555_load_block(pTAS2555, &(pNewPLL->mBlock)); 1397 nResult = tas2555_load_block(pTAS2555, &(pNewPLL->mBlock));
1327 if(nResult < 0) goto powerdown; 1398 if (nResult < 0)
1399 goto end;
1328 pTAS2555->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate; 1400 pTAS2555->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
1329 dev_dbg(pTAS2555->dev, 1401 dev_dbg(pTAS2555->dev,
1330 "load new configuration: %s, pre block data\n", 1402 "load new configuration: %s, pre block data\n",
1331 pNewConfiguration->mpName); 1403 pNewConfiguration->mpName);
1332 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData), 1404 nResult = tas2555_load_data(pTAS2555, &(pNewConfiguration->mData),
1333 TAS2555_BLOCK_CONF_PRE); 1405 TAS2555_BLOCK_CONF_PRE);
1334 if(nResult < 0) goto powerdown; 1406 if (nResult < 0)
1407 goto end;
1335 } 1408 }
1336 1409
1337 pTAS2555->mbLoadConfigurationPostPowerUp = true; 1410 pTAS2555->mbLoadConfigurationPostPowerUp = true;
1338 } 1411 }
1339 1412
1340 pTAS2555->mnCurrentConfiguration = nConfiguration; 1413 pTAS2555->mnCurrentConfiguration = nConfiguration;
1341 1414
1342powerdown:
1343 if(nResult < 0){
1344 failsafe(pTAS2555);
1345 }
1346
1347end: 1415end:
1348 1416
1417 if (nResult < 0)
1418 failsafe(pTAS2555);
1419
1349 return nResult; 1420 return nResult;
1350
1351} 1421}
1352 1422
1353int tas2555_set_config(struct tas2555_priv *pTAS2555, int config) 1423int tas2555_set_config(struct tas2555_priv *pTAS2555, int config)
@@ -1360,12 +1430,14 @@ int tas2555_set_config(struct tas2555_priv *pTAS2555, int config)
1360 if ((!pTAS2555->mpFirmware->mpPrograms) || 1430 if ((!pTAS2555->mpFirmware->mpPrograms) ||
1361 (!pTAS2555->mpFirmware->mpConfigurations)) { 1431 (!pTAS2555->mpFirmware->mpConfigurations)) {
1362 dev_err(pTAS2555->dev, "Firmware not loaded\n"); 1432 dev_err(pTAS2555->dev, "Firmware not loaded\n");
1433 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWNOTLOAD;
1363 return -1; 1434 return -1;
1364 } 1435 }
1365 1436
1366 if (nConfiguration >= pTAS2555->mpFirmware->mnConfigurations) { 1437 if (nConfiguration >= pTAS2555->mpFirmware->mnConfigurations) {
1367 dev_err(pTAS2555->dev, "Configuration %d doesn't exist\n", 1438 dev_err(pTAS2555->dev, "Configuration %d doesn't exist\n",
1368 nConfiguration); 1439 nConfiguration);
1440 pTAS2555->mnErrorCode |= TAS2555_ERROR_INVALIDPARAM;
1369 return -1; 1441 return -1;
1370 } 1442 }
1371 1443
@@ -1377,6 +1449,7 @@ int tas2555_set_config(struct tas2555_priv *pTAS2555, int config)
1377 "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n", 1449 "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n",
1378 nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram, 1450 nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram,
1379 nProgram, pProgram->mpName); 1451 nProgram, pProgram->mpName);
1452 pTAS2555->mnErrorCode |= TAS2555_ERROR_INVALIDPARAM;
1380 return -1; 1453 return -1;
1381 } 1454 }
1382 1455
@@ -1389,7 +1462,7 @@ void tas2555_clear_firmware(TFirmware *pFirmware)
1389{ 1462{
1390 unsigned int n, nn; 1463 unsigned int n, nn;
1391 if (!pFirmware) return; 1464 if (!pFirmware) return;
1392 if (pFirmware->mpDescription) kfree(pFirmware->mpDescription); 1465 if (pFirmware->mpDescription) kfree(pFirmware->mpDescription);
1393 1466
1394 for (n = 0; n < pFirmware->mnPLLs; n++) 1467 for (n = 0; n < pFirmware->mnPLLs; n++)
1395 { 1468 {
@@ -1485,8 +1558,9 @@ void tas2555_fw_ready(const struct firmware *pFW, void *pContext)
1485 dev_info(pTAS2555->dev, "%s:\n", __func__); 1558 dev_info(pTAS2555->dev, "%s:\n", __func__);
1486 1559
1487 if (unlikely(!pFW) || unlikely(!pFW->data)) { 1560 if (unlikely(!pFW) || unlikely(!pFW->data)) {
1488 dev_err(pTAS2555->dev, "%s firmware is not loaded.\n", 1561 dev_err(pTAS2555->dev, "%s firmware is not loaded\n", TAS2555_FW_NAME);
1489 TAS2555_FW_NAME); 1562 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWNOTLOAD;
1563 nResult = tas2555_load_default(pTAS2555);
1490 return; 1564 return;
1491 } 1565 }
1492 1566
@@ -1498,39 +1572,41 @@ void tas2555_fw_ready(const struct firmware *pFW, void *pContext)
1498 } 1572 }
1499 1573
1500 nResult = fw_parse(pTAS2555, pTAS2555->mpFirmware, 1574 nResult = fw_parse(pTAS2555, pTAS2555->mpFirmware,
1501 (unsigned char *) (pFW->data), pFW->size); 1575 (unsigned char *) (pFW->data), pFW->size);
1502 1576
1503 release_firmware(pFW); 1577 release_firmware(pFW);
1504 1578
1505 if (nResult) { 1579 if (nResult) {
1580 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
1506 dev_err(pTAS2555->dev, "firmware is corrupt\n"); 1581 dev_err(pTAS2555->dev, "firmware is corrupt\n");
1507 return; 1582 return;
1508 } 1583 }
1509 1584
1510 if (!pTAS2555->mpFirmware->mnPrograms) { 1585 if (!pTAS2555->mpFirmware->mnPrograms) {
1586 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
1511 dev_err(pTAS2555->dev, "firmware contains no programs\n"); 1587 dev_err(pTAS2555->dev, "firmware contains no programs\n");
1512 return; 1588 return;
1513 } 1589 }
1514 1590
1515 if (!pTAS2555->mpFirmware->mnConfigurations) { 1591 if (!pTAS2555->mpFirmware->mnConfigurations) {
1516 dev_err(pTAS2555->dev, 1592 dev_err(pTAS2555->dev,
1517 "firmware contains no configurations\n"); 1593 "firmware contains no configurations\n");
1594 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
1518 return; 1595 return;
1519 } 1596 }
1520 1597
1521 if(nProgram >= pTAS2555->mpFirmware->mnPrograms){ 1598 if(nProgram >= pTAS2555->mpFirmware->mnPrograms){
1522 dev_info(pTAS2555->dev, 1599 dev_info(pTAS2555->dev,
1523 "no previous program, set to default\n"); 1600 "no previous program, set to default\n");
1524 nProgram = 0; 1601 nProgram = 0;
1525 } 1602 }
1526 1603
1527 pTAS2555->mnCurrentSampleRate = nSampleRate; 1604 pTAS2555->mnCurrentSampleRate = nSampleRate;
1528 1605
1529 tas2555_set_program(pTAS2555, nProgram); 1606 tas2555_set_program(pTAS2555, nProgram, -1);
1530} 1607}
1531 1608
1532int tas2555_set_program(struct tas2555_priv *pTAS2555, 1609int tas2555_set_program(struct tas2555_priv *pTAS2555, unsigned int nProgram, int nConfig)
1533 unsigned int nProgram)
1534{ 1610{
1535 TPLL *pPLL; 1611 TPLL *pPLL;
1536 TConfiguration *pConfiguration; 1612 TConfiguration *pConfiguration;
@@ -1543,112 +1619,131 @@ int tas2555_set_program(struct tas2555_priv *pTAS2555,
1543 if ((!pTAS2555->mpFirmware->mpPrograms) || 1619 if ((!pTAS2555->mpFirmware->mpPrograms) ||
1544 (!pTAS2555->mpFirmware->mpConfigurations)) { 1620 (!pTAS2555->mpFirmware->mpConfigurations)) {
1545 dev_err(pTAS2555->dev, "Firmware not loaded\n"); 1621 dev_err(pTAS2555->dev, "Firmware not loaded\n");
1622 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWNOTLOAD;
1546 return -1; 1623 return -1;
1547 } 1624 }
1548 1625
1549 if (nProgram >= pTAS2555->mpFirmware->mnPrograms) { 1626 if (nProgram >= pTAS2555->mpFirmware->mnPrograms) {
1550 dev_err(pTAS2555->dev, "TAS2555: Program %d doesn't exist\n", 1627 dev_err(pTAS2555->dev, "TAS2555: Program %d doesn't exist\n",
1551 nConfiguration); 1628 nConfiguration);
1629 pTAS2555->mnErrorCode |= TAS2555_ERROR_INVALIDPARAM;
1552 return -1; 1630 return -1;
1553 } 1631 }
1554 1632
1555 nConfiguration = 0; 1633 if (nConfig < 0) {
1556 nSampleRate = pTAS2555->mnCurrentSampleRate; 1634 nConfiguration = 0;
1557 1635 nSampleRate = pTAS2555->mnCurrentSampleRate;
1558 while (!bFound 1636
1559 && (nConfiguration < pTAS2555->mpFirmware->mnConfigurations)) { 1637 while (!bFound
1560 if (pTAS2555->mpFirmware->mpConfigurations[nConfiguration].mnProgram 1638 && (nConfiguration < pTAS2555->mpFirmware->mnConfigurations)) {
1561 == nProgram){ 1639 if (pTAS2555->mpFirmware->mpConfigurations[nConfiguration].mnProgram
1562 if(nSampleRate == 0){ 1640 == nProgram){
1563 bFound = true; 1641 if(nSampleRate == 0){
1564 dev_info(pTAS2555->dev, "find default configuration %d\n", nConfiguration); 1642 bFound = true;
1565 }else if(nSampleRate 1643 dev_info(pTAS2555->dev, "find default configuration %d\n", nConfiguration);
1566 == pTAS2555->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate){ 1644 }else if(nSampleRate
1567 bFound = true; 1645 == pTAS2555->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate){
1568 dev_info(pTAS2555->dev, "find matching configuration %d\n", nConfiguration); 1646 bFound = true;
1647 dev_info(pTAS2555->dev, "find matching configuration %d\n", nConfiguration);
1648 }else{
1649 nConfiguration++;
1650 }
1569 }else{ 1651 }else{
1570 nConfiguration++; 1652 nConfiguration++;
1571 } 1653 }
1572 }else{
1573 nConfiguration++;
1574 } 1654 }
1575 } 1655 if (!bFound) {
1576 1656 dev_err(pTAS2555->dev,
1577 if (!bFound) { 1657 "Program %d, no valid configuration found for sample rate %d, ignore\n",
1578 dev_err(pTAS2555->dev, 1658 nProgram, nSampleRate);
1579 "Program %d, no valid configuration found for sample rate %d, ignore\n", 1659 pTAS2555->mnErrorCode |= TAS2555_ERROR_FWFORMAT;
1580 nProgram, nSampleRate); 1660 return -1;
1581 return -1; 1661 }
1582 } 1662 } else
1583 1663 nConfiguration = nConfig;
1664
1584 pTAS2555->mnCurrentProgram = nProgram; 1665 pTAS2555->mnCurrentProgram = nProgram;
1585 1666
1586 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_mute_DSP_down_data); 1667 if (pTAS2555->mbPowerUp) {
1587 if(nResult < 0) goto end; 1668 nResult = pTAS2555->enableIRQ(pTAS2555, false, true);
1588 1669 if (nResult < 0)
1670 goto end;
1671 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_mute_DSP_down_data);
1672 if (nResult < 0)
1673 goto end;
1674 }
1675
1589 nResult = pTAS2555->write(pTAS2555, TAS2555_SW_RESET_REG, 0x01); 1676 nResult = pTAS2555->write(pTAS2555, TAS2555_SW_RESET_REG, 0x01);
1590 if(nResult < 0) goto end; 1677 if (nResult < 0) {
1678 goto end;
1679 }
1680 nResult = tas2555_load_default(pTAS2555);
1681 if (nResult < 0)
1682 goto end;
1591 1683
1592 switch_set_state(&pTAS2555->sw_dev, 0);
1593 msleep(1); 1684 msleep(1);
1594 pTAS2555->mnCurrentBook = 0; 1685 pTAS2555->mnCurrentBook = 0;
1595 pTAS2555->mnCurrentPage = 0; 1686 pTAS2555->mnCurrentPage = 0;
1596 1687
1597 dev_info(pTAS2555->dev, "load program %d\n", nProgram); 1688 dev_info(pTAS2555->dev, "load program %d\n", nProgram);
1598 nResult = tas2555_load_data(pTAS2555, 1689 nResult = tas2555_load_data(pTAS2555, &(pTAS2555->mpFirmware->mpPrograms[nProgram].mData), TAS2555_BLOCK_BASE_MAIN);
1599 &(pTAS2555->mpFirmware->mpPrograms[nProgram].mData), 1690 if (nResult < 0)
1600 TAS2555_BLOCK_BASE_MAIN); 1691 goto end;
1601 if(nResult < 0) goto powerdown;
1602 1692
1603 pTAS2555->mnCurrentConfiguration = nConfiguration; 1693 pTAS2555->mnCurrentConfiguration = nConfiguration;
1604 1694
1605 pConfiguration = 1695 pConfiguration = &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]);
1606 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]);
1607 pPLL = &(pTAS2555->mpFirmware->mpPLLs[pConfiguration->mnPLL]); 1696 pPLL = &(pTAS2555->mpFirmware->mpPLLs[pConfiguration->mnPLL]);
1608 dev_dbg(pTAS2555->dev, 1697 dev_dbg(pTAS2555->dev, "TAS2555 load PLL: %s block for Configuration %s\n", pPLL->mpName, pConfiguration->mpName);
1609 "TAS2555 load PLL: %s block for Configuration %s\n",
1610 pPLL->mpName, pConfiguration->mpName);
1611 1698
1612 nResult = tas2555_load_block(pTAS2555, &(pPLL->mBlock)); 1699 nResult = tas2555_load_block(pTAS2555, &(pPLL->mBlock));
1613 if(nResult < 0) goto powerdown; 1700 if (nResult < 0)
1701 goto end;
1614 pTAS2555->mnCurrentSampleRate = pConfiguration->mnSamplingRate; 1702 pTAS2555->mnCurrentSampleRate = pConfiguration->mnSamplingRate;
1615 dev_dbg(pTAS2555->dev, 1703 dev_dbg(pTAS2555->dev,
1616 "load configuration %s conefficient pre block\n", 1704 "load configuration %s conefficient pre block\n",
1617 pConfiguration->mpName); 1705 pConfiguration->mpName);
1618 nResult = tas2555_load_data(pTAS2555, &(pConfiguration->mData), TAS2555_BLOCK_CONF_PRE); 1706 nResult = tas2555_load_data(pTAS2555, &(pConfiguration->mData), TAS2555_BLOCK_CONF_PRE);
1619 if(nResult < 0) goto powerdown; 1707 if(nResult < 0)
1708 goto end;
1620 nResult = pTAS2555->read(pTAS2555, TAS2555_PLL_CLKIN_REG, &Value); 1709 nResult = pTAS2555->read(pTAS2555, TAS2555_PLL_CLKIN_REG, &Value);
1710 if(nResult < 0) {
1711 goto end;
1712 }
1621 dev_info(pTAS2555->dev, "TAS2555 PLL_CLKIN = 0x%02X\n", Value); 1713 dev_info(pTAS2555->dev, "TAS2555 PLL_CLKIN = 0x%02X\n", Value);
1622 p_tas2555_startup_data[TAS2555_STARTUP_DATA_PLL_CLKIN_INDEX] = Value; 1714 p_tas2555_startup_data[TAS2555_STARTUP_DATA_PLL_CLKIN_INDEX] = Value;
1623 1715
1624 if (pTAS2555->mbPowerUp){ 1716 if (pTAS2555->mbPowerUp){
1625 dev_dbg(pTAS2555->dev, "device powered up, load startup\n"); 1717 dev_dbg(pTAS2555->dev, "device powered up, load startup\n");
1626 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data); 1718 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data);
1719 if(nResult < 0)
1720 goto end;
1627 dev_dbg(pTAS2555->dev, 1721 dev_dbg(pTAS2555->dev,
1628 "device powered up, load configuration %s post power block\n", 1722 "device powered up, load configuration %s post power block\n",
1629 pConfiguration->mpName); 1723 pConfiguration->mpName);
1630 nResult = tas2555_load_data(pTAS2555, &(pConfiguration->mData), 1724 nResult = tas2555_load_data(pTAS2555, &(pConfiguration->mData),
1631 TAS2555_BLOCK_CONF_POST_POWER); 1725 TAS2555_BLOCK_CONF_POST_POWER);
1632 if(nResult < 0) goto powerdown; 1726 if(nResult < 0)
1727 goto end;
1633 } 1728 }
1634 1729
1635 nResult = tas2555_load_configuration(pTAS2555, nConfiguration, true); 1730 nResult = tas2555_load_configuration(pTAS2555, nConfiguration, true);
1636 if(nResult < 0) goto powerdown; 1731 if (nResult < 0)
1637 1732 goto end;
1733
1638 if (pTAS2555->mbPowerUp){ 1734 if (pTAS2555->mbPowerUp){
1639 dev_dbg(pTAS2555->dev, 1735 dev_dbg(pTAS2555->dev,
1640 "device powered up, load unmute\n"); 1736 "device powered up, load unmute\n");
1641 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data); 1737 nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data);
1642 if(nResult < 0) goto end; 1738 if (nResult < 0)
1739 goto end;
1643 } 1740 }
1644 1741
1645powerdown: 1742end:
1646 if(nResult < 0){ 1743
1744 if (nResult < 0)
1647 failsafe(pTAS2555); 1745 failsafe(pTAS2555);
1648 }
1649 1746
1650end:
1651
1652 return nResult; 1747 return nResult;
1653} 1748}
1654 1749
@@ -1672,6 +1767,7 @@ int tas2555_set_calibration(struct tas2555_priv *pTAS2555,
1672 if (nCalibration >= pTAS2555->mpFirmware->mnCalibrations) { 1767 if (nCalibration >= pTAS2555->mpFirmware->mnCalibrations) {
1673 dev_err(pTAS2555->dev, 1768 dev_err(pTAS2555->dev,
1674 "Calibration %d doesn't exist\n", nCalibration); 1769 "Calibration %d doesn't exist\n", nCalibration);
1770 pTAS2555->mnErrorCode |= TAS2555_ERROR_INVALIDPARAM;
1675 return -1; 1771 return -1;
1676 } 1772 }
1677 1773
@@ -1679,20 +1775,43 @@ int tas2555_set_calibration(struct tas2555_priv *pTAS2555,
1679 if(pTAS2555->mbPowerUp){ 1775 if(pTAS2555->mbPowerUp){
1680 nResult = tas2555_load_block(pTAS2555, 1776 nResult = tas2555_load_block(pTAS2555,
1681 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock)); 1777 &(pTAS2555->mpCalFirmware->mpCalibrations[pTAS2555->mnCurrentCalibration].mBlock));
1682 if(nResult < 0) goto powerdown; 1778 if (nResult >= 0)
1683 pTAS2555->mbLoadCalibrationPostPowerUp = false; 1779 pTAS2555->mbLoadCalibrationPostPowerUp = false;
1684 }else{ 1780 }else{
1685 pTAS2555->mbLoadCalibrationPostPowerUp = true; 1781 pTAS2555->mbLoadCalibrationPostPowerUp = true;
1686 } 1782 }
1687 1783
1688powerdown:
1689 if(nResult < 0){
1690 failsafe(pTAS2555);
1691 }
1692
1693 return nResult; 1784 return nResult;
1694} 1785}
1695 1786
1787int tas2555_parse_dt(struct device *dev, struct tas2555_priv *pTAS2555)
1788{
1789 struct device_node *np = dev->of_node;
1790 int ret = 0;
1791
1792 pTAS2555->mnResetGPIO = of_get_named_gpio(np, "ti,cdc-reset-gpio", 0);
1793 if (pTAS2555->mnResetGPIO < 0) {
1794 dev_err(pTAS2555->dev, "Looking up %s property in node %s failed %d\n",
1795 "ti,cdc-reset-gpio", np->full_name, pTAS2555->mnResetGPIO);
1796 ret = -EINVAL;
1797 pTAS2555->mnErrorCode |= TAS2555_ERROR_INVALIDPARAM;
1798 } else
1799 dev_dbg(pTAS2555->dev, "ti,cdc-reset-gpio=%d\n", pTAS2555->mnResetGPIO);
1800
1801 if (ret >= 0) {
1802 pTAS2555->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0);
1803 if (pTAS2555->mnGpioINT < 0) {
1804 dev_err(pTAS2555->dev, "Looking up %s property in node %s failed %d\n",
1805 "ti,irq-gpio", np->full_name, pTAS2555->mnGpioINT);
1806 ret = -EINVAL;
1807 pTAS2555->mnErrorCode |= TAS2555_ERROR_INVALIDPARAM;
1808 } else
1809 dev_dbg(pTAS2555->dev, "ti,irq-gpio=%d\n", pTAS2555->mnGpioINT);
1810 }
1811
1812 return ret;
1813}
1814
1696MODULE_AUTHOR("Texas Instruments Inc."); 1815MODULE_AUTHOR("Texas Instruments Inc.");
1697MODULE_DESCRIPTION("TAS2555 common functions for Android Linux"); 1816MODULE_DESCRIPTION("TAS2555 common functions for Android Linux");
1698MODULE_LICENSE("GPLv2"); \ No newline at end of file 1817MODULE_LICENSE("GPLv2"); \ No newline at end of file
diff --git a/tas2555-core.h b/tas2555-core.h
index 7c43697..d8779bd 100755
--- a/tas2555-core.h
+++ b/tas2555-core.h
@@ -48,19 +48,18 @@ typedef struct {
48} TYCRC; 48} TYCRC;
49 49
50int tas2555_enable(struct tas2555_priv *pTAS2555, bool bEnable); 50int tas2555_enable(struct tas2555_priv *pTAS2555, bool bEnable);
51int tas2555_parse_dt(struct device *dev, struct tas2555_priv *pTAS2555);
51int tas2555_set_sampling_rate(struct tas2555_priv *pTAS2555, 52int tas2555_set_sampling_rate(struct tas2555_priv *pTAS2555,
52 unsigned int nSamplingRate); 53 unsigned int nSamplingRate);
53int tas2555_set_config(struct tas2555_priv *pTAS2555, int config); 54int tas2555_set_config(struct tas2555_priv *pTAS2555, int config);
54int tas2555_get_f0_a1(struct tas2555_priv *pTAS2555, unsigned int *pA1);
55int tas2555_get_f0_a2(struct tas2555_priv *pTAS2555, unsigned int *pA2);
56void tas2555_load_fs_firmware(struct tas2555_priv *pTAS2555, 55void tas2555_load_fs_firmware(struct tas2555_priv *pTAS2555,
57 char *pFileName); 56 char *pFileName);
58void tas2555_fw_ready(const struct firmware *pFW, void *pContext); 57void tas2555_fw_ready(const struct firmware *pFW, void *pContext);
59int tas2555_set_program(struct tas2555_priv *pTAS2555, 58int tas2555_set_program(struct tas2555_priv *pTAS2555, unsigned int nProgram, int nConfig);
60 unsigned int nProgram);
61int tas2555_set_calibration(struct tas2555_priv *pTAS2555, 59int tas2555_set_calibration(struct tas2555_priv *pTAS2555,
62 int nCalibration); 60 int nCalibration);
63int tas2555_get_Re(struct tas2555_priv *pTAS2555, unsigned int *pRe); 61int tas2555_get_Re(struct tas2555_priv *pTAS2555, unsigned int *pRe);
62int tas2555_get_errcode(struct tas2555_priv *pTAS2555, unsigned int *pErrCode);
64int tas2555_load_default(struct tas2555_priv *pTAS2555); 63int tas2555_load_default(struct tas2555_priv *pTAS2555);
65void tas2555_clear_firmware(TFirmware *pFirmware); 64void tas2555_clear_firmware(TFirmware *pFirmware);
66 65
diff --git a/tas2555-misc.c b/tas2555-misc.c
index ade8af5..5a32811 100755
--- a/tas2555-misc.c
+++ b/tas2555-misc.c
@@ -447,7 +447,7 @@ static ssize_t tas2555_file_write(struct file *file, const char *buf, size_t cou
447 dev_info(pTAS2555->dev, 447 dev_info(pTAS2555->dev,
448 "TIAUDIO_CMD_PROGRAM, set to %d\n", 448 "TIAUDIO_CMD_PROGRAM, set to %d\n",
449 p_kBuf[1]); 449 p_kBuf[1]);
450 tas2555_set_program(pTAS2555, p_kBuf[1]); 450 tas2555_set_program(pTAS2555, p_kBuf[1], -1);
451 pTAS2555->mnDBGCmd = 0; 451 pTAS2555->mnDBGCmd = 0;
452 } 452 }
453 } 453 }
@@ -599,7 +599,7 @@ static long tas2555_file_unlocked_ioctl(struct file *file, unsigned int cmd, uns
599 599
600 case SMARTPA_SPK_SWITCH_PROGRAM: 600 case SMARTPA_SPK_SWITCH_PROGRAM:
601 { 601 {
602 tas2555_set_program(pTAS2555, arg); 602 tas2555_set_program(pTAS2555, arg, -1);
603 } 603 }
604 break; 604 break;
605 605
diff --git a/tas2555-regmap.c b/tas2555-regmap.c
index 4c61048..6a857b2 100755
--- a/tas2555-regmap.c
+++ b/tas2555-regmap.c
@@ -58,40 +58,65 @@
58#include "tiload.h" 58#include "tiload.h"
59#endif 59#endif
60 60
61static void tas2555_change_book_page(struct tas2555_priv *pTAS2555, unsigned char nBook, 61static int tas2555_change_book_page(struct tas2555_priv *pTAS2555, unsigned char nBook,
62 unsigned char nPage) 62 unsigned char nPage)
63{ 63{
64 int nResult;
65
64 if ((pTAS2555->mnCurrentBook == nBook) 66 if ((pTAS2555->mnCurrentBook == nBook)
65 && pTAS2555->mnCurrentPage == nPage){ 67 && pTAS2555->mnCurrentPage == nPage){
66 return; 68 return 0;
67 } 69 }
68 70
69 if (pTAS2555->mnCurrentBook != nBook) { 71 if (pTAS2555->mnCurrentBook != nBook) {
70 regmap_write(pTAS2555->mpRegmap, TAS2555_BOOKCTL_PAGE, 0); 72 nResult = regmap_write(pTAS2555->mpRegmap, TAS2555_BOOKCTL_PAGE, 0);
73 if (nResult < 0) {
74 dev_err(pTAS2555->dev, "%s, I2C error\n", __func__);
75 pTAS2555->mnErrorCode |= TAS2555_ERROR_I2CIO;
76 goto end;
77 }
71 pTAS2555->mnCurrentPage = 0; 78 pTAS2555->mnCurrentPage = 0;
72 regmap_write(pTAS2555->mpRegmap, TAS2555_BOOKCTL_REG, nBook); 79 nResult = regmap_write(pTAS2555->mpRegmap, TAS2555_BOOKCTL_REG, nBook);
80 if (nResult < 0) {
81 dev_err(pTAS2555->dev, "%s, I2C error\n", __func__);
82 pTAS2555->mnErrorCode |= TAS2555_ERROR_I2CIO;
83 goto end;
84 }
73 pTAS2555->mnCurrentBook = nBook; 85 pTAS2555->mnCurrentBook = nBook;
74 if (nPage != 0) { 86 if (nPage != 0) {
75 regmap_write(pTAS2555->mpRegmap, TAS2555_BOOKCTL_PAGE, nPage); 87 nResult = regmap_write(pTAS2555->mpRegmap, TAS2555_BOOKCTL_PAGE, nPage);
88 if (nResult < 0) {
89 dev_err(pTAS2555->dev, "%s, I2C error\n", __func__);
90 pTAS2555->mnErrorCode |= TAS2555_ERROR_I2CIO;
91 goto end;
92 }
76 pTAS2555->mnCurrentPage = nPage; 93 pTAS2555->mnCurrentPage = nPage;
77 } 94 }
78 } else if (pTAS2555->mnCurrentPage != nPage) { 95 } else if (pTAS2555->mnCurrentPage != nPage) {
79 regmap_write(pTAS2555->mpRegmap, TAS2555_BOOKCTL_PAGE, nPage); 96 nResult = regmap_write(pTAS2555->mpRegmap, TAS2555_BOOKCTL_PAGE, nPage);
97 if (nResult < 0) {
98 dev_err(pTAS2555->dev, "%s, I2C error\n", __func__);
99 pTAS2555->mnErrorCode |= TAS2555_ERROR_I2CIO;
100 goto end;
101 }
80 pTAS2555->mnCurrentPage = nPage; 102 pTAS2555->mnCurrentPage = nPage;
81 } 103 }
104end:
105
106 return nResult;
82} 107}
83 108
84static int tas2555_dev_read(struct tas2555_priv *pTAS2555, 109static int tas2555_dev_read(struct tas2555_priv *pTAS2555,
85 unsigned int nRegister, unsigned int *pValue) 110 unsigned int nRegister, unsigned int *pValue)
86{ 111{
87 int ret = 0; 112 int nResult = 0;
113
114 mutex_lock(&pTAS2555->dev_lock);
88 115
89 mutex_lock(&pTAS2555->dev_lock);
90
91 if (pTAS2555->mbTILoadActive) { 116 if (pTAS2555->mbTILoadActive) {
92 if (!(nRegister & 0x80000000)){ 117 if (!(nRegister & 0x80000000)){
93 mutex_unlock(&pTAS2555->dev_lock); 118 mutex_unlock(&pTAS2555->dev_lock);
94 return 0; // let only reads from TILoad pass. 119 return 0; /* let only reads from TILoad pass. */
95 } 120 }
96 nRegister &= ~0x80000000; 121 nRegister &= ~0x80000000;
97 } 122 }
@@ -101,19 +126,24 @@ static int tas2555_dev_read(struct tas2555_priv *pTAS2555,
101 TAS2555_BOOK_ID(nRegister), TAS2555_PAGE_ID(nRegister), 126 TAS2555_BOOK_ID(nRegister), TAS2555_PAGE_ID(nRegister),
102 TAS2555_PAGE_REG(nRegister)); 127 TAS2555_PAGE_REG(nRegister));
103*/ 128*/
104 tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister), 129 nResult = tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister),
105 TAS2555_PAGE_ID(nRegister)); 130 TAS2555_PAGE_ID(nRegister));
106 ret = regmap_read(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), pValue); 131 if (nResult >= 0) {
107 132 nResult = regmap_read(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), pValue);
133 if (nResult < 0) {
134 dev_err(pTAS2555->dev, "%s, I2C error\n", __func__);
135 pTAS2555->mnErrorCode |= TAS2555_ERROR_I2CIO;
136 }
137 }
108 mutex_unlock(&pTAS2555->dev_lock); 138 mutex_unlock(&pTAS2555->dev_lock);
109 return ret; 139 return nResult;
110} 140}
111 141
112static int tas2555_dev_write(struct tas2555_priv *pTAS2555, 142static int tas2555_dev_write(struct tas2555_priv *pTAS2555,
113 unsigned int nRegister, unsigned int nValue) 143 unsigned int nRegister, unsigned int nValue)
114{ 144{
115 int ret = 0; 145 int nResult = 0;
116 146
117 mutex_lock(&pTAS2555->dev_lock); 147 mutex_lock(&pTAS2555->dev_lock);
118 if ((nRegister == 0xAFFEAFFE) && (nValue == 0xBABEBABE)) { 148 if ((nRegister == 0xAFFEAFFE) && (nValue == 0xBABEBABE)) {
119 pTAS2555->mbTILoadActive = true; 149 pTAS2555->mbTILoadActive = true;
@@ -135,23 +165,28 @@ static int tas2555_dev_write(struct tas2555_priv *pTAS2555,
135 nRegister &= ~0x80000000; 165 nRegister &= ~0x80000000;
136 } 166 }
137 167
138 tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister), 168 nResult = tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister),
139 TAS2555_PAGE_ID(nRegister)); 169 TAS2555_PAGE_ID(nRegister));
140// dev_err(codec->dev, "%s: BOOK:PAGE:REG %u:%u:%u, VAL: 0x%02x\n", 170// dev_err(codec->dev, "%s: BOOK:PAGE:REG %u:%u:%u, VAL: 0x%02x\n",
141// __func__, TAS2555_BOOK_ID(nRegister), TAS2555_PAGE_ID(nRegister), 171// __func__, TAS2555_BOOK_ID(nRegister), TAS2555_PAGE_ID(nRegister),
142// TAS2555_PAGE_REG(nRegister), value); 172// TAS2555_PAGE_REG(nRegister), value);
143 ret = regmap_write(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), 173 if (nResult >= 0) {
144 nValue); 174 nResult = regmap_write(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), nValue);
145 mutex_unlock(&pTAS2555->dev_lock); 175 if (nResult < 0) {
146 176 dev_err(pTAS2555->dev, "%s, I2C error\n", __func__);
147 return ret; 177 pTAS2555->mnErrorCode |= TAS2555_ERROR_I2CIO;
178 }
179 }
180 mutex_unlock(&pTAS2555->dev_lock);
181
182 return nResult;
148} 183}
149 184
150static int tas2555_dev_bulk_read(struct tas2555_priv *pTAS2555, 185static int tas2555_dev_bulk_read(struct tas2555_priv *pTAS2555,
151 unsigned int nRegister, u8 * pData, unsigned int nLength) 186 unsigned int nRegister, u8 * pData, unsigned int nLength)
152{ 187{
153 int ret = 0; 188 int nResult = 0;
154 189
155 mutex_lock(&pTAS2555->dev_lock); 190 mutex_lock(&pTAS2555->dev_lock);
156 if (pTAS2555->mbTILoadActive) { 191 if (pTAS2555->mbTILoadActive) {
157 if (!(nRegister & 0x80000000)){ 192 if (!(nRegister & 0x80000000)){
@@ -161,19 +196,24 @@ static int tas2555_dev_bulk_read(struct tas2555_priv *pTAS2555,
161 nRegister &= ~0x80000000; 196 nRegister &= ~0x80000000;
162 } 197 }
163 198
164 tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister), 199 nResult = tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister),
165 TAS2555_PAGE_ID(nRegister)); 200 TAS2555_PAGE_ID(nRegister));
166 ret = regmap_bulk_read(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), 201 if (nResult >= 0) {
167 pData, nLength); 202 nResult = regmap_bulk_read(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), pData, nLength);
168 mutex_unlock(&pTAS2555->dev_lock); 203 if (nResult < 0) {
204 dev_err(pTAS2555->dev, "%s, I2C error\n", __func__);
205 pTAS2555->mnErrorCode |= TAS2555_ERROR_I2CIO;
206 }
207 }
208 mutex_unlock(&pTAS2555->dev_lock);
169 209
170 return ret; 210 return nResult;
171} 211}
172 212
173static int tas2555_dev_bulk_write(struct tas2555_priv *pTAS2555, 213static int tas2555_dev_bulk_write(struct tas2555_priv *pTAS2555,
174 unsigned int nRegister, u8 * pData, unsigned int nLength) 214 unsigned int nRegister, u8 * pData, unsigned int nLength)
175{ 215{
176 int ret = 0; 216 int nResult = 0;
177 mutex_lock(&pTAS2555->dev_lock); 217 mutex_lock(&pTAS2555->dev_lock);
178 if (pTAS2555->mbTILoadActive) { 218 if (pTAS2555->mbTILoadActive) {
179 if (!(nRegister & 0x80000000)){ 219 if (!(nRegister & 0x80000000)){
@@ -183,22 +223,26 @@ static int tas2555_dev_bulk_write(struct tas2555_priv *pTAS2555,
183 nRegister &= ~0x80000000; 223 nRegister &= ~0x80000000;
184 } 224 }
185 225
186 tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister), 226 nResult = tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister), TAS2555_PAGE_ID(nRegister));
187 TAS2555_PAGE_ID(nRegister)); 227 if (nResult >= 0) {
188 ret = regmap_bulk_write(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), 228 nResult = regmap_bulk_write(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), pData, nLength);
189 pData, nLength); 229 if (nResult < 0) {
190 mutex_unlock(&pTAS2555->dev_lock); 230 dev_err(pTAS2555->dev, "%s, I2C error\n", __func__);
191 231 pTAS2555->mnErrorCode |= TAS2555_ERROR_I2CIO;
192 return ret; 232 }
233 }
234 mutex_unlock(&pTAS2555->dev_lock);
235
236 return nResult;
193} 237}
194 238
195static int tas2555_dev_update_bits(struct tas2555_priv *pTAS2555, 239static int tas2555_dev_update_bits(struct tas2555_priv *pTAS2555,
196 unsigned int nRegister, unsigned int nMask, unsigned int nValue) 240 unsigned int nRegister, unsigned int nMask, unsigned int nValue)
197{ 241{
198 int ret = 0; 242 int nResult = 0;
199 243
200 mutex_lock(&pTAS2555->dev_lock); 244 mutex_lock(&pTAS2555->dev_lock);
201 245
202 if (pTAS2555->mbTILoadActive) { 246 if (pTAS2555->mbTILoadActive) {
203 if (!(nRegister & 0x80000000)){ 247 if (!(nRegister & 0x80000000)){
204 mutex_unlock(&pTAS2555->dev_lock); 248 mutex_unlock(&pTAS2555->dev_lock);
@@ -207,13 +251,120 @@ static int tas2555_dev_update_bits(struct tas2555_priv *pTAS2555,
207 nRegister &= ~0x80000000; 251 nRegister &= ~0x80000000;
208 } 252 }
209 253
210 tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister), 254 nResult = tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister), TAS2555_PAGE_ID(nRegister));
211 TAS2555_PAGE_ID(nRegister)); 255 if (nResult >= 0) {
212 256 nResult = regmap_update_bits(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), nMask, nValue);
213 ret = regmap_update_bits(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), nMask, nValue); 257 if (nResult < 0) {
214 258 dev_err(pTAS2555->dev, "%s, I2C error\n", __func__);
215 mutex_unlock(&pTAS2555->dev_lock); 259 pTAS2555->mnErrorCode |= TAS2555_ERROR_I2CIO;
216 return ret; 260 }
261 }
262 mutex_unlock(&pTAS2555->dev_lock);
263 return nResult;
264}
265
266static void tas2555_hw_reset(struct tas2555_priv *pTAS2555)
267{
268#ifdef ENABLE_GPIO_RESET
269 if (gpio_is_valid(pTAS2555->mnResetGPIO)) {
270 devm_gpio_request_one(pTAS2555->dev, pTAS2555->mnResetGPIO,
271 GPIOF_OUT_INIT_LOW, "TAS2555_RST");
272 msleep(10);
273 gpio_set_value_cansleep(pTAS2555->mnResetGPIO, 1);
274 udelay(1000);
275 }
276#endif
277}
278
279int tas2555_enableIRQ(struct tas2555_priv *pTAS2555, bool enable, bool clear)
280{
281 unsigned int nValue;
282 int nResult = 0;
283
284 if (enable) {
285 if (clear) {
286 nResult = pTAS2555->read(pTAS2555, TAS2555_FLAGS_1, &nValue);
287 if (nResult < 0)
288 goto end;
289 nResult = pTAS2555->read(pTAS2555, TAS2555_FLAGS_2, &nValue);
290 }
291
292 if (!pTAS2555->mbIRQEnable) {
293 if (pTAS2555->mnIRQ != 0)
294 enable_irq(pTAS2555->mnIRQ);
295 pTAS2555->mbIRQEnable = true;
296 }
297 } else {
298 if (pTAS2555->mbIRQEnable) {
299 if (pTAS2555->mnIRQ != 0)
300 disable_irq_nosync(pTAS2555->mnIRQ);
301 pTAS2555->mbIRQEnable = false;
302 }
303
304 if (clear) {
305 nResult = pTAS2555->read(pTAS2555, TAS2555_FLAGS_1, &nValue);
306 if (nResult < 0)
307 goto end;
308 nResult = pTAS2555->read(pTAS2555, TAS2555_FLAGS_2, &nValue);
309 }
310 }
311
312end:
313
314 return nResult;
315}
316
317static void irq_work_routine(struct work_struct *work)
318{
319 int nResult = 0;
320 unsigned int nDevInt1Status = 0, nDevInt2Status = 0;
321 struct tas2555_priv *pTAS2555 =
322 container_of(work, struct tas2555_priv, irq_work.work);
323
324 if (!pTAS2555->mbPowerUp)
325 return;
326
327 nResult = tas2555_dev_read(pTAS2555, TAS2555_FLAGS_1, &nDevInt1Status);
328 if (nResult < 0)
329 dev_err(pTAS2555->dev, "I2C doesn't work\n");
330 else
331 nResult = tas2555_dev_read(pTAS2555, TAS2555_FLAGS_2, &nDevInt2Status);
332
333 if ((nDevInt1Status & 0xdc) != 0) {
334 /* in case of INT_OC, INT_UV, INT_OT, INT_BO, INT_CL, INT_CLK1, INT_CLK2 */
335 dev_err(pTAS2555->dev, "critical error INT Status: 0x%x\n", nDevInt1Status);
336 if (nDevInt1Status & 0x04) {
337 pTAS2555->mnErrorCode |= TAS2555_ERROR_CLKPRESENT;
338 nResult = pTAS2555->write(pTAS2555, TAS2555_CLK_ERR_CTRL, 0x00);
339 }
340 if (nDevInt1Status & 0x08)
341 pTAS2555->mnErrorCode |= TAS2555_ERROR_BROWNOUT;
342 if (nDevInt1Status & 0x10)
343 pTAS2555->mnErrorCode |= TAS2555_ERROR_OVERTMP;
344 if (nDevInt1Status & 0x40)
345 pTAS2555->mnErrorCode |= TAS2555_ERROR_UNDERVOLTAGET;
346 if (nDevInt1Status & 0x80)
347 pTAS2555->mnErrorCode |= TAS2555_ERROR_OVERCURRENT;
348 goto program;
349 } else
350 dev_dbg(pTAS2555->dev, "%s, INT Status: 0x%x\n", __func__, nDevInt1Status);
351
352 return;
353
354program:
355 /* hardware reset and reload */
356 tas2555_hw_reset(pTAS2555);
357 tas2555_set_program(pTAS2555, pTAS2555->mnCurrentProgram, pTAS2555->mnCurrentConfiguration);
358}
359
360static irqreturn_t tas2555_irq_handler(int irq, void *dev_id)
361{
362 struct tas2555_priv *pTAS2555 = (struct tas2555_priv *)dev_id;
363
364 tas2555_enableIRQ(pTAS2555, false, false);
365 /* get IRQ status after 100 ms */
366 schedule_delayed_work(&pTAS2555->irq_work, msecs_to_jiffies(100));
367 return IRQ_HANDLED;
217} 368}
218 369
219static bool tas2555_volatile(struct device *pDev, unsigned int nRegister) 370static bool tas2555_volatile(struct device *pDev, unsigned int nRegister)
@@ -252,18 +403,10 @@ static int tas2555_i2c_probe(struct i2c_client *pClient,
252 i2c_set_clientdata(pClient, pTAS2555); 403 i2c_set_clientdata(pClient, pTAS2555);
253 dev_set_drvdata(&pClient->dev, pTAS2555); 404 dev_set_drvdata(&pClient->dev, pTAS2555);
254 405
255#ifdef ENABLE_GPIO_RESET 406 if (pClient->dev.of_node)
256 pTAS2555->reset_gpio = 407 tas2555_parse_dt(&pClient->dev, pTAS2555);
257 of_get_named_gpio(pClient->dev.of_node, "ti,reset-gpio", 0); 408
258 dev_info(&pClient->dev, "reset gpio is %d\n", pTAS2555->reset_gpio); 409 tas2555_hw_reset(pTAS2555);
259 if (gpio_is_valid(pTAS2555->reset_gpio)) {
260 devm_gpio_request_one(&pClient->dev, pTAS2555->reset_gpio,
261 GPIOF_OUT_INIT_LOW, "TAS2555_RST");
262 msleep(10);
263 gpio_set_value_cansleep(pTAS2555->reset_gpio, 1);
264 udelay(1000);
265 }
266#endif
267 410
268 pTAS2555->mpRegmap = devm_regmap_init_i2c(pClient, &tas2555_i2c_regmap); 411 pTAS2555->mpRegmap = devm_regmap_init_i2c(pClient, &tas2555_i2c_regmap);
269 if (IS_ERR(pTAS2555->mpRegmap)) { 412 if (IS_ERR(pTAS2555->mpRegmap)) {
@@ -278,6 +421,8 @@ static int tas2555_i2c_probe(struct i2c_client *pClient,
278 pTAS2555->bulk_read = tas2555_dev_bulk_read; 421 pTAS2555->bulk_read = tas2555_dev_bulk_read;
279 pTAS2555->bulk_write = tas2555_dev_bulk_write; 422 pTAS2555->bulk_write = tas2555_dev_bulk_write;
280 pTAS2555->update_bits = tas2555_dev_update_bits; 423 pTAS2555->update_bits = tas2555_dev_update_bits;
424 pTAS2555->enableIRQ = tas2555_enableIRQ;
425 pTAS2555->hw_reset = tas2555_hw_reset;
281 pTAS2555->set_config = tas2555_set_config; 426 pTAS2555->set_config = tas2555_set_config;
282 pTAS2555->set_calibration = tas2555_set_calibration; 427 pTAS2555->set_calibration = tas2555_set_calibration;
283 428
@@ -308,18 +453,35 @@ static int tas2555_i2c_probe(struct i2c_client *pClient,
308 pTAS2555->mnCurrentPage = 0; 453 pTAS2555->mnCurrentPage = 0;
309 pTAS2555->mnCurrentBook = 0; 454 pTAS2555->mnCurrentBook = 0;
310 455
456 if (gpio_is_valid(pTAS2555->mnGpioINT)) {
457 nResult = gpio_request(pTAS2555->mnGpioINT, "TAS2555-IRQ");
458 if (nResult < 0) {
459 dev_err(pTAS2555->dev,
460 "%s: GPIO %d request INT error\n",
461 __func__, pTAS2555->mnGpioINT);
462 goto fail;
463 }
464
465 gpio_direction_input(pTAS2555->mnGpioINT);
466 pTAS2555->mnIRQ = gpio_to_irq(pTAS2555->mnGpioINT);
467 dev_dbg(pTAS2555->dev, "irq = %d\n", pTAS2555->mnIRQ);
468 nResult = request_threaded_irq(pTAS2555->mnIRQ, tas2555_irq_handler,
469 NULL, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
470 pClient->name, pTAS2555);
471 if (nResult < 0) {
472 dev_err(pTAS2555->dev,
473 "request_irq failed, %d\n", nResult);
474 goto fail;
475 }
476
477 INIT_DELAYED_WORK(&pTAS2555->irq_work, irq_work_routine);
478 }
479
311 nResult = tas2555_dev_read(pTAS2555, TAS2555_REV_PGID_REG, &n); 480 nResult = tas2555_dev_read(pTAS2555, TAS2555_REV_PGID_REG, &n);
312 dev_info(&pClient->dev, "TAS2555 PGID: 0x%02x\n", n); 481 dev_info(&pClient->dev, "TAS2555 PGID: 0x%02x\n", n);
313 482
314 pTAS2555->mbTILoadActive = false; 483 pTAS2555->mbTILoadActive = false;
315 484
316 pTAS2555->sw_dev.name = "TAS2555-failsafe";
317 nResult = switch_dev_register(&pTAS2555->sw_dev);
318 if (nResult < 0) {
319 dev_err(pTAS2555->dev, "fail to register switch device\n");
320 goto fail;
321 }
322
323#ifdef CONFIG_TAS2555_CODEC 485#ifdef CONFIG_TAS2555_CODEC
324 mutex_init(&pTAS2555->codec_lock); 486 mutex_init(&pTAS2555->codec_lock);
325 tas2555_register_codec(pTAS2555); 487 tas2555_register_codec(pTAS2555);
@@ -348,8 +510,6 @@ static int tas2555_i2c_remove(struct i2c_client *pClient)
348 510
349 dev_info(pTAS2555->dev, "%s\n", __FUNCTION__); 511 dev_info(pTAS2555->dev, "%s\n", __FUNCTION__);
350 512
351 switch_dev_unregister(&pTAS2555->sw_dev);
352
353#ifdef CONFIG_TAS2555_CODEC 513#ifdef CONFIG_TAS2555_CODEC
354 tas2555_deregister_codec(pTAS2555); 514 tas2555_deregister_codec(pTAS2555);
355 mutex_destroy(&pTAS2555->codec_lock); 515 mutex_destroy(&pTAS2555->codec_lock);
diff --git a/tas2555.h b/tas2555.h
index a785bd2..7c1a920 100755
--- a/tas2555.h
+++ b/tas2555.h
@@ -70,8 +70,8 @@
70#define TAS2555_NONAME42_REG TAS2555_REG(0, 0, 42) 70#define TAS2555_NONAME42_REG TAS2555_REG(0, 0, 42)
71#define TAS2555_CLK_ERR_CTRL TAS2555_REG(0, 0, 44) 71#define TAS2555_CLK_ERR_CTRL TAS2555_REG(0, 0, 44)
72#define TAS2555_POWER_UP_FLAG_REG TAS2555_REG(0, 0, 100) 72#define TAS2555_POWER_UP_FLAG_REG TAS2555_REG(0, 0, 100)
73#define TAS2555_FLAGS_1 TAS2555_REG(0, 0, 104) 73#define TAS2555_FLAGS_1 TAS2555_REG(0, 0, 104) /* B0_P0_R0x68*/
74#define TAS2555_FLAGS_2 TAS2555_REG(0, 0, 108) 74#define TAS2555_FLAGS_2 TAS2555_REG(0, 0, 108) /* B0_P0_R0x6c*/
75/* Book0, Page1 registers */ 75/* Book0, Page1 registers */
76#define TAS2555_ASI1_DAC_FORMAT_REG TAS2555_REG(0, 1, 1) 76#define TAS2555_ASI1_DAC_FORMAT_REG TAS2555_REG(0, 1, 1)
77#define TAS2555_ASI1_ADC_FORMAT_REG TAS2555_REG(0, 1, 2) 77#define TAS2555_ASI1_ADC_FORMAT_REG TAS2555_REG(0, 1, 2)
@@ -141,6 +141,12 @@
141#define TAS2555_ASIM_IFACE8_REG TAS2555_REG(0, 1, 105) 141#define TAS2555_ASIM_IFACE8_REG TAS2555_REG(0, 1, 105)
142#define TAS2555_ASIM_IFACE9_REG TAS2555_REG(0, 1, 106) 142#define TAS2555_ASIM_IFACE9_REG TAS2555_REG(0, 1, 106)
143 143
144#define TAS2555_INT_GEN1_REG TAS2555_REG(0, 1, 108) /* B0_P1_R0x6c */
145#define TAS2555_INT_GEN2_REG TAS2555_REG(0, 1, 109)
146#define TAS2555_INT_GEN3_REG TAS2555_REG(0, 1, 110) /* B0_P1_R0x6e */
147#define TAS2555_INT_GEN4_REG TAS2555_REG(0, 1, 111) /* B0_P1_R0x6f */
148#define TAS2555_INT_MODE_REG TAS2555_REG(0, 1, 114) /* B0_P1_R0x72 */
149
144#define TAS2555_MAIN_CLKIN_REG TAS2555_REG(0, 1, 115) 150#define TAS2555_MAIN_CLKIN_REG TAS2555_REG(0, 1, 115)
145#define TAS2555_PLL_CLKIN_REG TAS2555_REG(0, 1, 116) /* B0_P1_R0x74 */ 151#define TAS2555_PLL_CLKIN_REG TAS2555_REG(0, 1, 116) /* B0_P1_R0x74 */
146#define TAS2555_CLKOUT_MUX_REG TAS2555_REG(0, 1, 117) 152#define TAS2555_CLKOUT_MUX_REG TAS2555_REG(0, 1, 117)
@@ -274,6 +280,22 @@
274 280
275#define ARRAY_LEN(x) ((int)(sizeof(x)/sizeof((x)[0]))) 281#define ARRAY_LEN(x) ((int)(sizeof(x)/sizeof((x)[0])))
276 282
283#define TAS2555_ERROR_I2CIO 0x00000001
284#define TAS2555_ERROR_PCHKSUM 0x00000002
285#define TAS2555_ERROR_YCHKSUM 0x00000004
286#define TAS2555_ERROR_FWFORMAT 0x00000008
287#define TAS2555_ERROR_RETOOHIGH 0x00000010
288#define TAS2555_ERROR_RETOOLOW 0x00000020
289#define TAS2555_ERROR_FWNOTLOAD 0x00000040
290#define TAS2555_ERROR_INVALIDPARAM 0x00000080
291#define TAS2555_ERROR_VALUENOTMATCH 0x01000000
292#define TAS2555_ERROR_OVERTMP 0x02000000
293#define TAS2555_ERROR_CLKPRESENT 0x04000000
294#define TAS2555_ERROR_BROWNOUT 0x08000000
295#define TAS2555_ERROR_UNDERVOLTAGET 0x10000000
296#define TAS2555_ERROR_OVERCURRENT 0x20000000
297#define TAS2555_ERROR_FAILSAFE 0x40000000
298
277typedef struct { 299typedef struct {
278 unsigned int mnType; 300 unsigned int mnType;
279 unsigned char mbPChkSumPresent; 301 unsigned char mbPChkSumPresent;
@@ -361,21 +383,26 @@ struct tas2555_priv {
361 unsigned char mnCurrentBook; 383 unsigned char mnCurrentBook;
362 unsigned char mnCurrentPage; 384 unsigned char mnCurrentPage;
363 bool mbTILoadActive; 385 bool mbTILoadActive;
364 int reset_gpio; 386 int mnResetGPIO;
365 bool mbPowerUp; 387 bool mbPowerUp;
366 bool mbLoadConfigurationPostPowerUp; 388 bool mbLoadConfigurationPostPowerUp;
367 389
368 unsigned int mnPowerCtrl; 390 unsigned int mnPowerCtrl;
369 391
370 /* to notify user critical condition */ 392 /* to notify user critical condition */
371 struct switch_dev sw_dev; 393 unsigned int mnReLastKnown;
372 unsigned int mnReHigh; 394 unsigned int mnReOrignal;
373 unsigned int mnReLow; 395 unsigned int mnReDelta;
374 396
375 /* factory test and calibration */ 397 /* factory test and calibration */
376 bool mbLoadCalibrationPostPowerUp; 398 bool mbLoadCalibrationPostPowerUp;
377 bool mbCalibrationLoaded; 399 bool mbCalibrationLoaded;
378 400
401 int mnGpioINT;
402 struct delayed_work irq_work;
403 unsigned int mnIRQ;
404 bool mbIRQEnable;
405
379 int (*read)(struct tas2555_priv * pTAS2555, unsigned int reg, 406 int (*read)(struct tas2555_priv * pTAS2555, unsigned int reg,
380 unsigned int *pValue); 407 unsigned int *pValue);
381 int (*write)(struct tas2555_priv * pTAS2555, unsigned int reg, 408 int (*write)(struct tas2555_priv * pTAS2555, unsigned int reg,
@@ -386,16 +413,22 @@ struct tas2555_priv {
386 unsigned char *pData, unsigned int len); 413 unsigned char *pData, unsigned int len);
387 int (*update_bits)(struct tas2555_priv * pTAS2555, unsigned int reg, 414 int (*update_bits)(struct tas2555_priv * pTAS2555, unsigned int reg,
388 unsigned int mask, unsigned int value); 415 unsigned int mask, unsigned int value);
416 int (*enableIRQ)(struct tas2555_priv *pTAS2555, bool enable, bool clear);
417 void (*hw_reset)(struct tas2555_priv *pTAS2555);
389 int (*set_config)(struct tas2555_priv *pTAS2555, int config); 418 int (*set_config)(struct tas2555_priv *pTAS2555, int config);
390 int (*set_calibration)(struct tas2555_priv *pTAS2555, int calibration); 419 int (*set_calibration)(struct tas2555_priv *pTAS2555, int calibration);
420
391#ifdef CONFIG_TAS2555_CODEC 421#ifdef CONFIG_TAS2555_CODEC
392 struct mutex codec_lock; 422 struct mutex codec_lock;
393#endif 423#endif
424
394#ifdef CONFIG_TAS2555_MISC 425#ifdef CONFIG_TAS2555_MISC
395 int mnDBGCmd; 426 int mnDBGCmd;
396 int mnCurrentReg; 427 int mnCurrentReg;
397 struct mutex file_lock; 428 struct mutex file_lock;
398#endif 429#endif
430
431 unsigned int mnErrorCode;
399}; 432};
400 433
401#endif /* _TAS2555_H */ 434#endif /* _TAS2555_H */