summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authora02204102016-05-20 12:51:44 -0500
committera02204102016-05-20 12:51:44 -0500
commitd6d71fdc23e1b2e364c84104cacedbc11920c256 (patch)
treefa8c7ece916c279b5f4504337ad70f1a1d69d894
parent5839aa0e8dd54d6d741ec9ff4b008a56f13b22fa (diff)
downloadtas2555-android-driver-d6d71fdc23e1b2e364c84104cacedbc11920c256.tar.gz
tas2555-android-driver-d6d71fdc23e1b2e364c84104cacedbc11920c256.tar.xz
tas2555-android-driver-d6d71fdc23e1b2e364c84104cacedbc11920c256.zip
fix bug to check the sample rate when switching between programs and configurations
-rwxr-xr-xdai_link.readme28
-rwxr-xr-xdts.readme7
-rwxr-xr-xtas2555-codec.c8
-rwxr-xr-xtas2555-codec.h2
-rwxr-xr-xtas2555-core.c317
-rwxr-xr-xtas2555-core.h2
-rwxr-xr-xtas2555-misc.c29
-rwxr-xr-xtas2555-regmap.c14
-rwxr-xr-xtas2555.h1
-rwxr-xr-xtiload.c1
10 files changed, 193 insertions, 216 deletions
diff --git a/dai_link.readme b/dai_link.readme
new file mode 100755
index 0000000..6032275
--- /dev/null
+++ b/dai_link.readme
@@ -0,0 +1,28 @@
1example for connecting CPU DAI
2
3#ifdef CONFIG_TAS2555_CODEC
4 {
5 .name = LPASS_BE_PRI_MI2S_RX,
6 .stream_name = "Primary MI2S Hostless Playback",
7 .cpu_dai_name = "msm-dai-q6-mi2s.0", /* CPU DAI name */
8 .platform_name = "msm-pcm-routing",
9 .codec_name = "tas2555.3-004c", /* codec name */
10 .codec_dai_name = "tas2555 ASI1", /* codec DAI name */
11 .no_pcm = 1,
12 .be_id = MSM_BACKEND_DAI_PRI_MI2S_RX,
13 .be_hw_params_fixup = msm_be_prim_mi2s_hw_params_fixup,
14 .ops = &msm8974_prim_mi2s_be_ops,
15 },
16 {
17 .name = LPASS_BE_PRI_MI2S_TX,
18 .stream_name = "Primary MI2S Hostless Capture",
19 .cpu_dai_name = "msm-dai-q6-mi2s.0",
20 .platform_name = "msm-pcm-routing",
21 .codec_name = "tas2555.3-004c",
22 .codec_dai_name = "tas2555 ASI1",
23 .no_pcm = 1,
24 .be_id = MSM_BACKEND_DAI_PRI_MI2S_TX,
25 .be_hw_params_fixup = msm_be_prim_mi2s_hw_params_fixup,
26 .ops = &msm8974_prim_mi2s_be_ops,
27 },
28#endif \ No newline at end of file
diff --git a/dts.readme b/dts.readme
new file mode 100755
index 0000000..ef2daff
--- /dev/null
+++ b/dts.readme
@@ -0,0 +1,7 @@
1example for dts:
2
3 tas2555@4c {
4 compatible = "ti,tas2555";
5 reg = <0x4c>;
6 status = "okay";
7 }; \ No newline at end of file
diff --git a/tas2555-codec.c b/tas2555-codec.c
index e5d8379..3ce720f 100755
--- a/tas2555-codec.c
+++ b/tas2555-codec.c
@@ -48,10 +48,9 @@
48#include <sound/soc.h> 48#include <sound/soc.h>
49#include <sound/initval.h> 49#include <sound/initval.h>
50#include <sound/tlv.h> 50#include <sound/tlv.h>
51//#include <dt-bindings/sound/tas2555.h>
52 51
53#include "tas2555.h"
54#include "tas2555-core.h" 52#include "tas2555-core.h"
53#include "tas2555-codec.h"
55 54
56#undef KCONTROL_CODEC 55#undef KCONTROL_CODEC
57 56
@@ -205,7 +204,7 @@ static int tas2555_codec_probe(struct snd_soc_codec *pCodec)
205{ 204{
206 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(pCodec); 205 struct tas2555_priv *pTAS2555 = snd_soc_codec_get_drvdata(pCodec);
207 206
208 dev_dbg(pTAS2555->dev, "%s\n", __func__); 207 dev_info(pTAS2555->dev, "%s\n", __func__);
209 208
210 return 0; 209 return 0;
211} 210}
@@ -615,6 +614,9 @@ static struct snd_soc_dai_driver tas2555_dai_driver[] = {
615int tas2555_register_codec(struct tas2555_priv *pTAS2555) 614int tas2555_register_codec(struct tas2555_priv *pTAS2555)
616{ 615{
617 int nResult = 0; 616 int nResult = 0;
617
618 dev_info(pTAS2555->dev, "%s, enter\n", __FUNCTION__);
619
618 nResult = snd_soc_register_codec(pTAS2555->dev, 620 nResult = snd_soc_register_codec(pTAS2555->dev,
619 &soc_codec_driver_tas2555, 621 &soc_codec_driver_tas2555,
620 tas2555_dai_driver, ARRAY_SIZE(tas2555_dai_driver)); 622 tas2555_dai_driver, ARRAY_SIZE(tas2555_dai_driver));
diff --git a/tas2555-codec.h b/tas2555-codec.h
index 1ffebeb..460cf6d 100755
--- a/tas2555-codec.h
+++ b/tas2555-codec.h
@@ -26,6 +26,8 @@
26#ifndef _TAS2555_CODEC_H 26#ifndef _TAS2555_CODEC_H
27#define _TAS2555_CODEC_H 27#define _TAS2555_CODEC_H
28 28
29#include "tas2555.h"
30
29extern int tas2555_register_codec(struct tas2555_priv *pTAS2555); 31extern int tas2555_register_codec(struct tas2555_priv *pTAS2555);
30extern int tas2555_deregister_codec(struct tas2555_priv *pTAS2555); 32extern int tas2555_deregister_codec(struct tas2555_priv *pTAS2555);
31 33
diff --git a/tas2555-core.c b/tas2555-core.c
index e59c676..0c53891 100755
--- a/tas2555-core.c
+++ b/tas2555-core.c
@@ -42,6 +42,7 @@
42#include <asm/uaccess.h> 42#include <asm/uaccess.h>
43 43
44#include "tas2555.h" 44#include "tas2555.h"
45#include "tas2555-core.h"
45 46
46#define TAS2555_CAL_NAME "/data/tas2555_cal.bin" 47#define TAS2555_CAL_NAME "/data/tas2555_cal.bin"
47 48
@@ -230,7 +231,7 @@ int tas2555_set_sampling_rate(struct tas2555_priv *pTAS2555, unsigned int nSampl
230 231
231 pConfiguration = &(pTAS2555->mpFirmware->mpConfigurations[pTAS2555->mnCurrentConfiguration]); 232 pConfiguration = &(pTAS2555->mpFirmware->mpConfigurations[pTAS2555->mnCurrentConfiguration]);
232 if (pConfiguration->mnSamplingRate == nSamplingRate) { 233 if (pConfiguration->mnSamplingRate == nSamplingRate) {
233 dev_dbg(pTAS2555->dev, "Sampling rate for current configuration matches: %d\n", 234 dev_info(pTAS2555->dev, "Sampling rate for current configuration matches: %d\n",
234 nSamplingRate); 235 nSamplingRate);
235 return 0; 236 return 0;
236 } 237 }
@@ -240,8 +241,9 @@ int tas2555_set_sampling_rate(struct tas2555_priv *pTAS2555, unsigned int nSampl
240 nConfiguration++) { 241 nConfiguration++) {
241 pConfiguration = 242 pConfiguration =
242 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]); 243 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]);
243 if (pConfiguration->mnSamplingRate == nSamplingRate) { 244 if ((pConfiguration->mnSamplingRate == nSamplingRate)
244 dev_dbg(pTAS2555->dev, 245 &&(pConfiguration->mnProgram == pTAS2555->mnCurrentProgram)){
246 dev_info(pTAS2555->dev,
245 "Found configuration: %s, with compatible sampling rate %d\n", 247 "Found configuration: %s, with compatible sampling rate %d\n",
246 pConfiguration->mpName, nSamplingRate); 248 pConfiguration->mpName, nSamplingRate);
247 tas2555_load_configuration(pTAS2555, nConfiguration, false); 249 tas2555_load_configuration(pTAS2555, nConfiguration, false);
@@ -249,7 +251,7 @@ int tas2555_set_sampling_rate(struct tas2555_priv *pTAS2555, unsigned int nSampl
249 } 251 }
250 } 252 }
251 253
252 dev_dbg(pTAS2555->dev, "Cannot find a configuration that supports sampling rate: %d\n", 254 dev_err(pTAS2555->dev, "Cannot find a configuration that supports sampling rate: %d\n",
253 nSamplingRate); 255 nSamplingRate);
254 256
255 return -EINVAL; 257 return -EINVAL;
@@ -264,8 +266,6 @@ static void fw_print_header(struct tas2555_priv *pTAS2555, TFirmware * pFirmware
264 dev_info(pTAS2555->dev, " Timestamp = %d", pFirmware->mnTimeStamp); 266 dev_info(pTAS2555->dev, " Timestamp = %d", pFirmware->mnTimeStamp);
265 dev_info(pTAS2555->dev, " DDC Name = %s", pFirmware->mpDDCName); 267 dev_info(pTAS2555->dev, " DDC Name = %s", pFirmware->mpDDCName);
266 dev_info(pTAS2555->dev, " Description = %s", pFirmware->mpDescription); 268 dev_info(pTAS2555->dev, " Description = %s", pFirmware->mpDescription);
267 dev_info(pTAS2555->dev, " Device Family = %d", pFirmware->mnDeviceFamily);
268 dev_info(pTAS2555->dev, " Device = %d", pFirmware->mnDevice);
269} 269}
270 270
271inline unsigned int fw_convert_number(unsigned char *pData) 271inline unsigned int fw_convert_number(unsigned char *pData)
@@ -575,20 +575,13 @@ static void tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock)
575 575
576 nCommand++; 576 nCommand++;
577 577
578 if (nOffset <= 0x7F) 578 if (nOffset <= 0x7F){
579 pTAS2555->write(pTAS2555, TAS2555_REG(nBook, nPage, nOffset), 579 pTAS2555->write(pTAS2555, TAS2555_REG(nBook, nPage, nOffset),
580 nData); 580 nData);
581 if (nOffset == 0x81) { 581 }else if (nOffset == 0x81) {
582 unsigned int nSleep = (nBook << 8) + nPage; 582 unsigned int nSleep = (nBook << 8) + nPage;
583 dev_dbg(pTAS2555->dev,
584 "TAS2555 load block: nOffset = 0x81 -> sleep %d [ms]\n",
585 nSleep);
586 msleep(nSleep); 583 msleep(nSleep);
587 dev_dbg(pTAS2555->dev, 584 }else if (nOffset == 0x85) {
588 "TAS2555 load block: just woke up from sleep %d [ms]\n",
589 nSleep);
590 }
591 if (nOffset == 0x85) {
592 pData += 4; 585 pData += 4;
593 nLength = (nBook << 8) + nPage; 586 nLength = (nBook << 8) + nPage;
594 nBook = pData[0]; 587 nBook = pData[0];
@@ -623,8 +616,6 @@ static void tas2555_load_data(struct tas2555_priv *pTAS2555, TData * pData,
623 if (pBlock->mnType == nType) 616 if (pBlock->mnType == nType)
624 tas2555_load_block(pTAS2555, pBlock); 617 tas2555_load_block(pTAS2555, pBlock);
625 } 618 }
626
627 dev_dbg(pTAS2555->dev, "%s(), exit\n", __func__);
628} 619}
629 620
630static void tas2555_load_configuration(struct tas2555_priv *pTAS2555, 621static void tas2555_load_configuration(struct tas2555_priv *pTAS2555,
@@ -649,7 +640,7 @@ static void tas2555_load_configuration(struct tas2555_priv *pTAS2555,
649 } 640 }
650 641
651 if ((nConfiguration == pTAS2555->mnCurrentConfiguration) && (!bLoadSame)) { 642 if ((nConfiguration == pTAS2555->mnCurrentConfiguration) && (!bLoadSame)) {
652 dev_dbg(pTAS2555->dev, "Configuration %d is already loaded\n", 643 dev_info(pTAS2555->dev, "Configuration %d is already loaded\n",
653 nConfiguration); 644 nConfiguration);
654 return; 645 return;
655 } 646 }
@@ -659,13 +650,20 @@ static void tas2555_load_configuration(struct tas2555_priv *pTAS2555,
659 pNewConfiguration = 650 pNewConfiguration =
660 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]); 651 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]);
661 652
653 if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) {
654 dev_err(pTAS2555->dev,
655 "Configuration %d, %s doesn't share the same program as current %d\n",
656 nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram);
657 return;
658 }
659
662 if (pNewConfiguration->mnPLL >= pTAS2555->mpFirmware->mnPLLs) { 660 if (pNewConfiguration->mnPLL >= pTAS2555->mpFirmware->mnPLLs) {
663 dev_err(pTAS2555->dev, 661 dev_err(pTAS2555->dev,
664 "Configuration %d, %s doesn't have a valid PLL index %d\n", 662 "Configuration %d, %s doesn't have a valid PLL index %d\n",
665 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL); 663 nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL);
666 return; 664 return;
667 } 665 }
668 666
669 pNewPLL = &(pTAS2555->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]); 667 pNewPLL = &(pTAS2555->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]);
670 668
671 if (pTAS2555->mbPowerUp) { 669 if (pTAS2555->mbPowerUp) {
@@ -683,6 +681,7 @@ static void tas2555_load_configuration(struct tas2555_priv *pTAS2555,
683 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n", 681 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n",
684 pNewPLL->mpName); 682 pNewPLL->mpName);
685 tas2555_load_block(pTAS2555, &(pNewPLL->mBlock)); 683 tas2555_load_block(pTAS2555, &(pNewPLL->mBlock));
684 pTAS2555->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
686 dev_dbg(pTAS2555->dev, 685 dev_dbg(pTAS2555->dev,
687 "load new configuration: %s, pre block data\n", 686 "load new configuration: %s, pre block data\n",
688 pNewConfiguration->mpName); 687 pNewConfiguration->mpName);
@@ -722,6 +721,7 @@ static void tas2555_load_configuration(struct tas2555_priv *pTAS2555,
722 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n", 721 dev_dbg(pTAS2555->dev, "TAS2555: load new PLL: %s, block data\n",
723 pNewPLL->mpName); 722 pNewPLL->mpName);
724 tas2555_load_block(pTAS2555, &(pNewPLL->mBlock)); 723 tas2555_load_block(pTAS2555, &(pNewPLL->mBlock));
724 pTAS2555->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate;
725 dev_dbg(pTAS2555->dev, 725 dev_dbg(pTAS2555->dev,
726 "load new configuration: %s, pre block data\n", 726 "load new configuration: %s, pre block data\n",
727 pNewConfiguration->mpName); 727 pNewConfiguration->mpName);
@@ -766,9 +766,6 @@ int tas2555_set_config(struct tas2555_priv *pTAS2555, int config)
766 766
767 tas2555_load_configuration(pTAS2555, nConfiguration, false); 767 tas2555_load_configuration(pTAS2555, nConfiguration, false);
768 768
769 dev_dbg(pTAS2555->dev, "tas2555_configuration_put = %d\n",
770 pTAS2555->mnCurrentConfiguration);
771
772 return 0; 769 return 0;
773} 770}
774 771
@@ -860,104 +857,59 @@ static void tas2555_load_calibration(struct tas2555_priv *pTAS2555,
860 pTAS2555->mpCalFirmware->mnCalibrations); 857 pTAS2555->mpCalFirmware->mnCalibrations);
861} 858}
862 859
863void tas2555_fw_load(const struct firmware *pFW, struct tas2555_priv *pTAS2555) 860void tas2555_fw_ready(const struct firmware *pFW, void *pContext)
864{ 861{
865 TConfiguration *pConfiguration; 862 struct tas2555_priv *pTAS2555 = (struct tas2555_priv *) pContext;
866 TPLL *pPLL;
867 int nResult; 863 int nResult;
868 unsigned int Value; 864 unsigned int nProgram = 0;
865 unsigned int nSampleRate = 0;
869 866
870 dev_info(pTAS2555->dev, "%s:\n", __func__); 867 dev_info(pTAS2555->dev, "%s:\n", __func__);
871 868
872 if (unlikely(!pFW) || unlikely(!pFW->data)) { 869 if (unlikely(!pFW) || unlikely(!pFW->data)) {
873 dev_info(pTAS2555->dev, "%s firmware is not loaded.\n", 870 dev_err(pTAS2555->dev, "%s firmware is not loaded.\n",
874 TAS2555_FW_NAME); 871 TAS2555_FW_NAME);
875 return; 872 return;
876 } 873 }
877 874
878 tas2555_clear_firmware(pTAS2555->mpFirmware); 875 if (pTAS2555->mpFirmware->mpConfigurations){
879 876 nProgram = pTAS2555->mnCurrentProgram;
877 nSampleRate = pTAS2555->mnCurrentSampleRate;
878 dev_dbg(pTAS2555->dev, "clear current firmware\n");
879 tas2555_clear_firmware(pTAS2555->mpFirmware);
880 }
881
880 nResult = fw_parse(pTAS2555, pTAS2555->mpFirmware, 882 nResult = fw_parse(pTAS2555, pTAS2555->mpFirmware,
881 (unsigned char *) (pFW->data), pFW->size); 883 (unsigned char *) (pFW->data), pFW->size);
884
885 release_firmware(pFW);
882 886
883 if (nResult) { 887 if (nResult) {
884 dev_err(pTAS2555->dev, "TAS2555 firmware is corrupt\n"); 888 dev_err(pTAS2555->dev, "firmware is corrupt\n");
885 return; 889 return;
886 } 890 }
887 891
888 dev_info(pTAS2555->dev, "TAS2555 firmware: %d programs\n",
889 pTAS2555->mpFirmware->mnPrograms);
890 dev_info(pTAS2555->dev, "TAS2555 firmware: %d configurations\n",
891 pTAS2555->mpFirmware->mnConfigurations);
892
893 if (!pTAS2555->mpFirmware->mnPrograms) { 892 if (!pTAS2555->mpFirmware->mnPrograms) {
894 dev_err(pTAS2555->dev, "TAS2555 firmware contains no programs\n"); 893 dev_err(pTAS2555->dev, "firmware contains no programs\n");
895 return; 894 return;
896 } 895 }
897 896
898 if (!pTAS2555->mpFirmware->mnConfigurations) { 897 if (!pTAS2555->mpFirmware->mnConfigurations) {
899 dev_err(pTAS2555->dev, "TAS2555 firmware contains no configurations\n"); 898 dev_err(pTAS2555->dev,
900 return; 899 "firmware contains no configurations\n");
901 }
902
903 tas2555_dev_load_data(pTAS2555, p_tas2555_mute_DSP_down_data);
904 pTAS2555->write(pTAS2555, TAS2555_SW_RESET_REG, 0x01);
905 udelay(1000);
906
907 pTAS2555->mnCurrentBook = 0;
908 pTAS2555->mnCurrentPage = 0;
909
910 pTAS2555->write(pTAS2555, TAS2555_CRC_RESET_REG, 0x01);
911 dev_info(pTAS2555->dev, "TAS2555 load base image: %s main block\n",
912 pTAS2555->mpFirmware->mpPrograms[0].mpName);
913 tas2555_load_data(pTAS2555, &(pTAS2555->mpFirmware->mpPrograms[0].mData),
914 TAS2555_BLOCK_BASE_MAIN);
915 pTAS2555->mbLoadConfigurationPostPowerUp = true;
916 pTAS2555->mnCurrentConfiguration = 0;
917 pTAS2555->mnCurrentProgram = 0;
918
919 pConfiguration = &(pTAS2555->mpFirmware->mpConfigurations[0]);
920 if (pConfiguration->mnPLL >= pTAS2555->mpFirmware->mnPLLs) {
921 dev_err(pTAS2555->dev,
922 "TAS2555 Configuration #0 doesn't have a valid PLL index #%d, max = %d\n",
923 pConfiguration->mnPLL, pTAS2555->mpFirmware->mnPLLs);
924 return; 900 return;
925 } else {
926 pPLL = &(pTAS2555->mpFirmware->mpPLLs[pConfiguration->mnPLL]);
927 dev_info(pTAS2555->dev,
928 "TAS2555 load PLL: %s block for Configuration %s\n",
929 pPLL->mpName, pConfiguration->mpName);
930 tas2555_load_block(pTAS2555, &(pPLL->mBlock));
931 } 901 }
932
933 nResult = pTAS2555->read(pTAS2555, TAS2555_CRC_CHECKSUM_REG, &Value);
934 if (nResult < 0)
935 dev_err(pTAS2555->dev, "%d, ERROR!\n", __LINE__);
936 else
937 dev_info(pTAS2555->dev, "uCDSP Checksum: 0x%02x\n", Value);
938
939 nResult = pTAS2555->read(pTAS2555, TAS2555_PLL_CLKIN_REG, &Value);
940 dev_info(pTAS2555->dev, "TAS2555 PLL_CLKIN = 0x%02X\n", Value);
941 p_tas2555_startup_data[TAS2555_STARTUP_DATA_PLL_CLKIN_INDEX] = Value;
942
943 tas2555_load_data(pTAS2555, &(pConfiguration->mData),
944 TAS2555_BLOCK_CONF_PRE);
945}
946
947void tas2555_fw_ready(const struct firmware *pFW, void *pContext)
948{
949 struct tas2555_priv *pTAS2555 = (struct tas2555_priv *) pContext;
950
951 tas2555_fw_load(pFW, pTAS2555);
952 902
953 if (unlikely(!pFW) || unlikely(!pFW->data)) { 903 if(nProgram >= pTAS2555->mpFirmware->mnPrograms){
954 dev_info(pTAS2555->dev, "%s firmware is not loaded.\n", 904 dev_info(pTAS2555->dev,
955 TAS2555_FW_NAME); 905 "no previous program, set to default\n");
956 return; 906 nProgram = 0;
957 } 907 }
908
909 pTAS2555->mnCurrentSampleRate = nSampleRate;
958 910
959 release_firmware(pFW); 911 tas2555_set_program(pTAS2555, nProgram);
960} 912}
961 913
962int tas2555_set_program(struct tas2555_priv *pTAS2555, 914int tas2555_set_program(struct tas2555_priv *pTAS2555,
963 unsigned int nProgram) 915 unsigned int nProgram)
@@ -965,75 +917,103 @@ int tas2555_set_program(struct tas2555_priv *pTAS2555,
965 TPLL *pPLL; 917 TPLL *pPLL;
966 TConfiguration *pConfiguration; 918 TConfiguration *pConfiguration;
967 unsigned int nConfiguration = 0; 919 unsigned int nConfiguration = 0;
920 unsigned int nSampleRate = 0;
921 unsigned int Value = 0;
968 bool bFound = false; 922 bool bFound = false;
923 int nResult = -1;
969 924
970 if ((!pTAS2555->mpFirmware->mpPrograms) || 925 if ((!pTAS2555->mpFirmware->mpPrograms) ||
971 (!pTAS2555->mpFirmware->mpConfigurations)) { 926 (!pTAS2555->mpFirmware->mpConfigurations)) {
972 dev_err(pTAS2555->dev, "Firmware not loaded\n"); 927 dev_err(pTAS2555->dev, "Firmware not loaded\n");
973 return -1; 928 return -1;
974 } 929 }
930
975 if (nProgram >= pTAS2555->mpFirmware->mnPrograms) { 931 if (nProgram >= pTAS2555->mpFirmware->mnPrograms) {
976 dev_err(pTAS2555->dev, "TAS2555: Program %d doesn't exist\n", 932 dev_err(pTAS2555->dev, "TAS2555: Program %d doesn't exist\n",
977 nConfiguration); 933 nConfiguration);
978 return -1; 934 return -1;
979 } 935 }
980 936
981 if(pTAS2555->mnCurrentProgram == nProgram){ 937 nConfiguration = 0;
982 dev_info(pTAS2555->dev, 938 nSampleRate = pTAS2555->mnCurrentSampleRate;
983 "Program %d, no need to set again\n", 939
984 nProgram); 940 while (!bFound
985 return 0; 941 && (nConfiguration < pTAS2555->mpFirmware->mnConfigurations)) {
942 if (pTAS2555->mpFirmware->mpConfigurations[nConfiguration].mnProgram
943 == nProgram){
944 if(nSampleRate == 0){
945 bFound = true;
946 dev_info(pTAS2555->dev, "find default configuration %d\n", nConfiguration);
947 }else if(nSampleRate
948 == pTAS2555->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate){
949 bFound = true;
950 dev_info(pTAS2555->dev, "find matching configuration %d\n", nConfiguration);
951 }else{
952 nConfiguration++;
953 }
954 }else{
955 nConfiguration++;
956 }
986 } 957 }
987 958
959 if (!bFound) {
960 dev_err(pTAS2555->dev,
961 "Program %d, no valid configuration found for sample rate %d, ignore\n",
962 nProgram, nSampleRate);
963 return -1;
964 }
965
988 pTAS2555->mnCurrentProgram = nProgram; 966 pTAS2555->mnCurrentProgram = nProgram;
989 967
968 tas2555_dev_load_data(pTAS2555, p_tas2555_mute_DSP_down_data);
990 pTAS2555->write(pTAS2555, TAS2555_SW_RESET_REG, 0x01); 969 pTAS2555->write(pTAS2555, TAS2555_SW_RESET_REG, 0x01);
991 970
992 udelay(1000); 971 udelay(1000);
993 pTAS2555->mnCurrentBook = 0; 972 pTAS2555->mnCurrentBook = 0;
994 pTAS2555->mnCurrentPage = 0; 973 pTAS2555->mnCurrentPage = 0;
995 974
975 dev_info(pTAS2555->dev, "load program %d\n", nProgram);
996 tas2555_load_data(pTAS2555, 976 tas2555_load_data(pTAS2555,
997 &(pTAS2555->mpFirmware->mpPrograms[nProgram].mData), 977 &(pTAS2555->mpFirmware->mpPrograms[nProgram].mData),
998 TAS2555_BLOCK_BASE_MAIN); 978 TAS2555_BLOCK_BASE_MAIN);
999 979
1000 nConfiguration = 0; 980 pTAS2555->mnCurrentConfiguration = nConfiguration;
1001 while (!bFound && (nConfiguration < pTAS2555->mpFirmware->mnConfigurations)) {
1002 if (pTAS2555->mpFirmware->mpConfigurations[nConfiguration].mnProgram ==
1003 nProgram)
1004 bFound = true;
1005 else
1006 nConfiguration++;
1007 }
1008
1009 if (bFound) {
1010 pTAS2555->mnCurrentConfiguration = nConfiguration;
1011 981
1012 pConfiguration = 982 pConfiguration =
1013 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]); 983 &(pTAS2555->mpFirmware->mpConfigurations[nConfiguration]);
1014 pPLL = &(pTAS2555->mpFirmware->mpPLLs[pConfiguration->mnPLL]); 984 pPLL = &(pTAS2555->mpFirmware->mpPLLs[pConfiguration->mnPLL]);
1015 dev_dbg(pTAS2555->dev, 985 dev_dbg(pTAS2555->dev,
1016 "TAS2555 load PLL: %s block for Configuration %s\n", 986 "TAS2555 load PLL: %s block for Configuration %s\n",
1017 pPLL->mpName, pConfiguration->mpName); 987 pPLL->mpName, pConfiguration->mpName);
1018 tas2555_load_block(pTAS2555, &(pPLL->mBlock)); 988
1019 tas2555_load_data(pTAS2555, &(pConfiguration->mData), TAS2555_BLOCK_CONF_PRE); 989 tas2555_load_block(pTAS2555, &(pPLL->mBlock));
990 pTAS2555->mnCurrentSampleRate = pConfiguration->mnSamplingRate;
991 dev_dbg(pTAS2555->dev,
992 "load configuration %s conefficient pre block\n",
993 pConfiguration->mpName);
994 tas2555_load_data(pTAS2555, &(pConfiguration->mData), TAS2555_BLOCK_CONF_PRE);
1020 995
1021 if (pTAS2555->mbPowerUp){ 996 nResult = pTAS2555->read(pTAS2555, TAS2555_CRC_CHECKSUM_REG, &Value);
1022 tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data); 997 dev_info(pTAS2555->dev, "uCDSP Checksum: 0x%02x\n", Value);
1023 tas2555_load_data(pTAS2555, &(pConfiguration->mData), 998 nResult = pTAS2555->read(pTAS2555, TAS2555_PLL_CLKIN_REG, &Value);
1024 TAS2555_BLOCK_CONF_POST_POWER); 999 dev_info(pTAS2555->dev, "TAS2555 PLL_CLKIN = 0x%02X\n", Value);
1025 } 1000 p_tas2555_startup_data[TAS2555_STARTUP_DATA_PLL_CLKIN_INDEX] = Value;
1026 tas2555_load_configuration(pTAS2555, nConfiguration, true);
1027 if (pTAS2555->mbPowerUp)
1028 tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data);
1029 1001
1002 if (pTAS2555->mbPowerUp){
1003 dev_dbg(pTAS2555->dev, "device powered up, load startup\n");
1004 tas2555_dev_load_data(pTAS2555, p_tas2555_startup_data);
1005 dev_dbg(pTAS2555->dev,
1006 "device powered up, load configuration %s post power block\n",
1007 pConfiguration->mpName);
1008 tas2555_load_data(pTAS2555, &(pConfiguration->mData),
1009 TAS2555_BLOCK_CONF_POST_POWER);
1010 }
1011
1012 tas2555_load_configuration(pTAS2555, nConfiguration, true);
1013 if (pTAS2555->mbPowerUp){
1030 dev_dbg(pTAS2555->dev, 1014 dev_dbg(pTAS2555->dev,
1031 "tas2555_program_put = %d, found configuration = %d, %d\n", 1015 "device powered up, load unmute\n");
1032 pTAS2555->mnCurrentProgram, bFound, nConfiguration); 1016 tas2555_dev_load_data(pTAS2555, p_tas2555_unmute_data);
1033 }else{
1034 dev_err(pTAS2555->dev,
1035 "Program %d, no valid configuration found\n",
1036 nProgram);
1037 } 1017 }
1038 1018
1039 return 0; 1019 return 0;
@@ -1044,19 +1024,20 @@ int tas2555_set_calibration(struct tas2555_priv *pTAS2555,
1044{ 1024{
1045 if ((!pTAS2555->mpFirmware->mpPrograms) || (!pTAS2555->mpFirmware->mpConfigurations)) 1025 if ((!pTAS2555->mpFirmware->mpPrograms) || (!pTAS2555->mpFirmware->mpConfigurations))
1046 { 1026 {
1047 printk(KERN_ERR "TAS2555: Firmware not loaded\n\r"); 1027 dev_err(pTAS2555->dev, "Firmware not loaded\n\r");
1048 return -1; 1028 return -1;
1049 } 1029 }
1050 1030
1051 if (nCalibration == 0x00FF) 1031 if (nCalibration == 0x00FF)
1052 { 1032 {
1053 printk(KERN_ERR "TAS2555: load new calibration file %s\n\r", TAS2555_CAL_NAME); 1033 dev_info(pTAS2555->dev, "load new calibration file %s\n", TAS2555_CAL_NAME);
1054 tas2555_load_calibration(pTAS2555, TAS2555_CAL_NAME); 1034 tas2555_load_calibration(pTAS2555, TAS2555_CAL_NAME);
1055 nCalibration = 0; 1035 nCalibration = 0;
1056 } 1036 }
1057 1037
1058 if (nCalibration >= pTAS2555->mpFirmware->mnCalibrations) { 1038 if (nCalibration >= pTAS2555->mpFirmware->mnCalibrations) {
1059 printk(KERN_ERR "TAS2555: Calibration %d doesn't exist\n\r", nCalibration); 1039 dev_err(pTAS2555->dev,
1040 "Calibration %d doesn't exist\n", nCalibration);
1060 return -1; 1041 return -1;
1061 } 1042 }
1062 1043
@@ -1067,64 +1048,6 @@ int tas2555_set_calibration(struct tas2555_priv *pTAS2555,
1067 return 0; 1048 return 0;
1068} 1049}
1069 1050
1070void tas2555_load_fs_firmware(struct tas2555_priv *pTAS2555,
1071 char *pFileName)
1072{
1073 int nFile;
1074 mm_segment_t fs;
1075 struct firmware fw;
1076 unsigned char *p_kBuf;
1077 int nSize = 0;
1078 unsigned int count = 30000;
1079
1080 dev_dbg(pTAS2555->dev, "%s:\n", __func__);
1081 p_kBuf = (unsigned char *)kzalloc(count, GFP_KERNEL);
1082 if(p_kBuf == NULL){
1083 dev_err(pTAS2555->dev, "not enough memory for %d bytes\n", count);
1084 return;
1085 }
1086
1087 fs = get_fs();
1088 set_fs(KERNEL_DS);
1089 nFile = sys_open(pFileName, O_RDONLY, 0);
1090
1091 dev_info(pTAS2555->dev, "TAS2555 firmware file = %s, handle = %d\n",
1092 pFileName, nFile);
1093
1094 if (nFile >= 0) {
1095 nSize = sys_read(nFile, p_kBuf, count);
1096 sys_close(nFile);
1097 } else {
1098 dev_err(pTAS2555->dev, "TAS2555 cannot open firmware file: %s\n",
1099 pFileName);
1100 }
1101
1102 set_fs(fs);
1103
1104 if(nSize == count){
1105 dev_err(pTAS2555->dev,
1106 "buffer length (%d) may not contain all the firmware\n",
1107 count);
1108 }
1109
1110 if (!nSize){
1111 dev_err(pTAS2555->dev,
1112 "firmware size error\n");
1113 }else{
1114 dev_info(pTAS2555->dev, "TAS2555 firmware size= %d\n",
1115 nSize);
1116
1117 fw.size = nSize;
1118 fw.data = p_kBuf;
1119 tas2555_fw_load(&fw, pTAS2555);
1120
1121 dev_info(pTAS2555->dev, "TAS2555 firmware: %d configurations\n",
1122 pTAS2555->mpFirmware->mnConfigurations);
1123 }
1124
1125 kfree(p_kBuf);
1126}
1127
1128MODULE_AUTHOR("Texas Instruments Inc."); 1051MODULE_AUTHOR("Texas Instruments Inc.");
1129MODULE_DESCRIPTION("TAS2555 common functions for Android Linux"); 1052MODULE_DESCRIPTION("TAS2555 common functions for Android Linux");
1130MODULE_LICENSE("GPLv2"); \ No newline at end of file 1053MODULE_LICENSE("GPLv2"); \ No newline at end of file
diff --git a/tas2555-core.h b/tas2555-core.h
index 642c18b..a504b40 100755
--- a/tas2555-core.h
+++ b/tas2555-core.h
@@ -26,6 +26,8 @@
26#ifndef _TAS2555_CORE_H 26#ifndef _TAS2555_CORE_H
27#define _TAS2555_CORE_H 27#define _TAS2555_CORE_H
28 28
29#include "tas2555.h"
30
29extern void tas2555_enable(struct tas2555_priv *pTAS2555, bool bEnable); 31extern void tas2555_enable(struct tas2555_priv *pTAS2555, bool bEnable);
30extern int tas2555_set_sampling_rate(struct tas2555_priv *pTAS2555, 32extern int tas2555_set_sampling_rate(struct tas2555_priv *pTAS2555,
31 unsigned int nSamplingRate); 33 unsigned int nSamplingRate);
diff --git a/tas2555-misc.c b/tas2555-misc.c
index f185336..ade8af5 100755
--- a/tas2555-misc.c
+++ b/tas2555-misc.c
@@ -98,6 +98,11 @@ static int tas2555_file_open(struct inode *inode, struct file *file)
98 98
99static int tas2555_file_release(struct inode *inode, struct file *file) 99static int tas2555_file_release(struct inode *inode, struct file *file)
100{ 100{
101 struct tas2555_priv *pTAS2555 = (struct tas2555_priv *)file->private_data;
102
103 if(g_logEnable) dev_info(pTAS2555->dev,
104 "%s\n", __FUNCTION__);
105
101 file->private_data = (void*)NULL; 106 file->private_data = (void*)NULL;
102 module_put(THIS_MODULE); 107 module_put(THIS_MODULE);
103 108
@@ -354,15 +359,6 @@ static ssize_t tas2555_file_read(struct file *file, char *buf, size_t count, lof
354 } 359 }
355 } 360 }
356 break; 361 break;
357
358 case TIAUDIO_CMD_FW_RELOAD:
359 {
360 if(count == 1){
361 tas2555_load_fs_firmware(pTAS2555, TAS2555_FW_FULL_NAME);
362 }
363
364 }
365 break;
366 } 362 }
367 pTAS2555->mnDBGCmd = 0; 363 pTAS2555->mnDBGCmd = 0;
368 364
@@ -543,6 +539,21 @@ static ssize_t tas2555_file_write(struct file *file, const char *buf, size_t cou
543 } 539 }
544 } 540 }
545 break; 541 break;
542
543 case TIAUDIO_CMD_FW_RELOAD:
544 {
545 if(count == 1){
546 ret = request_firmware_nowait(THIS_MODULE, 1, TAS2555_FW_NAME,
547 pTAS2555->dev, GFP_KERNEL, pTAS2555, tas2555_fw_ready);
548
549 if(g_logEnable)
550 dev_info(pTAS2555->dev,
551 "TIAUDIO_CMD_FW_RELOAD: ret = %d\n",
552 ret);
553 }
554
555 }
556 break;
546 557
547 default: 558 default:
548 pTAS2555->mnDBGCmd = 0; 559 pTAS2555->mnDBGCmd = 0;
diff --git a/tas2555-regmap.c b/tas2555-regmap.c
index 9c94998..fa7dea7 100755
--- a/tas2555-regmap.c
+++ b/tas2555-regmap.c
@@ -96,9 +96,11 @@ static int tas2555_dev_read(struct tas2555_priv *pTAS2555,
96 nRegister &= ~0x80000000; 96 nRegister &= ~0x80000000;
97 } 97 }
98 98
99/*
99 dev_dbg(pTAS2555->dev, "%s: BOOK:PAGE:REG %u:%u:%u\n", __func__, 100 dev_dbg(pTAS2555->dev, "%s: BOOK:PAGE:REG %u:%u:%u\n", __func__,
100 TAS2555_BOOK_ID(nRegister), TAS2555_PAGE_ID(nRegister), 101 TAS2555_BOOK_ID(nRegister), TAS2555_PAGE_ID(nRegister),
101 TAS2555_PAGE_REG(nRegister)); 102 TAS2555_PAGE_REG(nRegister));
103*/
102 tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister), 104 tas2555_change_book_page(pTAS2555, TAS2555_BOOK_ID(nRegister),
103 TAS2555_PAGE_ID(nRegister)); 105 TAS2555_PAGE_ID(nRegister));
104 ret = regmap_read(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), pValue); 106 ret = regmap_read(pTAS2555->mpRegmap, TAS2555_PAGE_REG(nRegister), pValue);
@@ -240,6 +242,8 @@ static int tas2555_i2c_probe(struct i2c_client *pClient,
240 unsigned int n; 242 unsigned int n;
241 int nResult; 243 int nResult;
242 244
245 dev_info(&pClient->dev, "%s enter\n", __FUNCTION__);
246
243 pTAS2555 = devm_kzalloc(&pClient->dev, sizeof(struct tas2555_priv), GFP_KERNEL); 247 pTAS2555 = devm_kzalloc(&pClient->dev, sizeof(struct tas2555_priv), GFP_KERNEL);
244 if (!pTAS2555) 248 if (!pTAS2555)
245 return -ENOMEM; 249 return -ENOMEM;
@@ -308,9 +312,6 @@ static int tas2555_i2c_probe(struct i2c_client *pClient,
308 312
309 tas2555_load_default(pTAS2555); 313 tas2555_load_default(pTAS2555);
310 314
311 nResult = request_firmware_nowait(THIS_MODULE, 1, TAS2555_FW_NAME,
312 &pClient->dev, GFP_KERNEL, pTAS2555, tas2555_fw_ready);
313
314 pTAS2555->mbTILoadActive = false; 315 pTAS2555->mbTILoadActive = false;
315 316
316#ifdef CONFIG_TAS2555_CODEC 317#ifdef CONFIG_TAS2555_CODEC
@@ -327,6 +328,9 @@ static int tas2555_i2c_probe(struct i2c_client *pClient,
327 tiload_driver_init(pTAS2555); 328 tiload_driver_init(pTAS2555);
328#endif 329#endif
329 330
331 nResult = request_firmware_nowait(THIS_MODULE, 1, TAS2555_FW_NAME,
332 pTAS2555->dev, GFP_KERNEL, pTAS2555, tas2555_fw_ready);
333
330 return nResult; 334 return nResult;
331} 335}
332 336
@@ -358,11 +362,7 @@ MODULE_DEVICE_TABLE(i2c, tas2555_i2c_id);
358 362
359#if defined(CONFIG_OF) 363#if defined(CONFIG_OF)
360static const struct of_device_id tas2555_of_match[] = { 364static const struct of_device_id tas2555_of_match[] = {
361#ifdef MTK_PLATFORM_DRIVER
362 {.compatible = "mediatek,EXT_SPEAKER_AMP"},
363#else
364 {.compatible = "ti,tas2555"}, 365 {.compatible = "ti,tas2555"},
365#endif
366 {}, 366 {},
367}; 367};
368 368
diff --git a/tas2555.h b/tas2555.h
index 91d32a0..7723f16 100755
--- a/tas2555.h
+++ b/tas2555.h
@@ -340,6 +340,7 @@ struct tas2555_priv {
340 TFirmware *mpFirmware; 340 TFirmware *mpFirmware;
341 TFirmware *mpCalFirmware; 341 TFirmware *mpCalFirmware;
342 unsigned int mnCurrentProgram; 342 unsigned int mnCurrentProgram;
343 unsigned int mnCurrentSampleRate;
343 unsigned int mnCurrentConfiguration; 344 unsigned int mnCurrentConfiguration;
344 unsigned int mnCurrentCalibration; 345 unsigned int mnCurrentCalibration;
345 int mnCurrentBook; 346 int mnCurrentBook;
diff --git a/tiload.c b/tiload.c
index f35464d..9a7ee7d 100755
--- a/tiload.c
+++ b/tiload.c
@@ -37,6 +37,7 @@
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/i2c.h> 38#include <linux/i2c.h>
39#include <linux/platform_device.h> 39#include <linux/platform_device.h>
40#include <asm/uaccess.h>
40 41
41#include "tiload.h" 42#include "tiload.h"
42 43