summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTracy Yi2018-07-27 04:25:02 -0500
committerTracy Yi2018-07-27 04:25:02 -0500
commit3d5c19b557c9334191c6c4c007726bdea8cdb7e5 (patch)
treee73cfaa6cb5bead36a15b884ccdde92c8224a989
parent9fcd9154c328c429955ef22e34e216a26fbf61e3 (diff)
downloadtas2560-stereo-android-driver-3d5c19b557c9334191c6c4c007726bdea8cdb7e5.tar.gz
tas2560-stereo-android-driver-3d5c19b557c9334191c6c4c007726bdea8cdb7e5.tar.xz
tas2560-stereo-android-driver-3d5c19b557c9334191c6c4c007726bdea8cdb7e5.zip
Add control to channels seperatelyHEADmaster
Signed-off-by: Tracy Yi <tracy-yi@ti.com>
-rw-r--r--dts.readme9
-rw-r--r--tas2560-codec.c140
-rw-r--r--tas2560-core.c88
-rw-r--r--tas2560-core.h4
-rw-r--r--tas2560-regmap.c99
-rw-r--r--tas2560.h6
6 files changed, 197 insertions, 149 deletions
diff --git a/dts.readme b/dts.readme
index c4ebde6..073bfde 100644
--- a/dts.readme
+++ b/dts.readme
@@ -3,13 +3,14 @@ example for dts:
3 compatible = "ti,tas2560s"; 3 compatible = "ti,tas2560s";
4 reg = <0x4c>; 4 reg = <0x4c>;
5 ti,reset-gpio = <&msmgpio 13 0>; 5 ti,reset-gpio = <&msmgpio 13 0>;
6 ti,irq-gpio = <&msmgpio 59 0>; 6 ti,irq-gpio1 = <&msmgpio 59 0>;
7 ti,irq-gpio2 = <&msmgpio 82 0>;
7 ti,left-channel = <0x4c>; 8 ti,left-channel = <0x4c>;
8 ti,right-channel = <0x4d>; 9 ti,right-channel = <0x4d>;
9 ti,pll = <0>; /* refer to tas2560.h for more details */ 10 ti,pll = <1>; /* refer to tas2560.h for more details */
10 ti,asi-format = <0>; /* 0, i2S; 1, DSP; */ 11 ti,asi-format = <1>; /* 0, i2S; 1, DSP; */
11 ti,left-load = <0>; /* 0, 8Ohm; 1, 6Ohm; 2, 4Ohm */ 12 ti,left-load = <0>; /* 0, 8Ohm; 1, 6Ohm; 2, 4Ohm */
12 ti,right-load = <0>; /* 0, 8Ohm; 1, 6Ohm; 2, 4Ohm */ 13 ti,right-load = <0>; /* 0, 8Ohm; 1, 6Ohm; 2, 4Ohm */
13 ti,ppg = <0>; /* 0, 0dB default; 1, enable -2dB */ 14 ti,ppg = <0>; /* 0, 0dB default; 1, enable -2dB */
14 status = "ok"; 15 status = "ok";
15 }; \ No newline at end of file 16 };
diff --git a/tas2560-codec.c b/tas2560-codec.c
index 4d314a9..1fe8b48 100644
--- a/tas2560-codec.c
+++ b/tas2560-codec.c
@@ -47,6 +47,8 @@
47 47
48#define TAS2560_MDELAY 0xFFFFFFFE 48#define TAS2560_MDELAY 0xFFFFFFFE
49#define KCONTROL_CODEC 49#define KCONTROL_CODEC
50static int spk_r_control = 0;
51static int spk_l_control = 0;
50 52
51static unsigned int tas2560_codec_read(struct snd_soc_codec *codec, unsigned int reg) 53static unsigned int tas2560_codec_read(struct snd_soc_codec *codec, unsigned int reg)
52{ 54{
@@ -93,41 +95,12 @@ static int tas2560_codec_resume(struct snd_soc_codec *codec)
93 mutex_unlock(&pTAS2560->codec_lock); 95 mutex_unlock(&pTAS2560->codec_lock);
94 return ret; 96 return ret;
95} 97}
96/*
97static int tas2560_mix_post_event(struct snd_soc_dapm_widget *w,
98 struct snd_kcontrol *kcontrol, int event)
99{
100 struct snd_soc_codec *codec = w->codec;
101 struct tas2560_priv *pTAS2560 = snd_soc_codec_get_drvdata(codec);
102 enum channel mchannel;
103
104 dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
105
106 if (!strcmp(w->name, "LEFT Mixer")) {
107 mchannel = channel_left;
108 } else if (!strcmp(w->name, "RIGHT Mixer")) {
109 mchannel = channel_right;
110 }
111
112 switch (event) {
113 case SND_SOC_DAPM_POST_PMU:
114 dev_dbg(pTAS2560->dev, "SND_SOC_DAPM_POST_PMU");
115 tas2560_enable(pTAS2560, true, mchannel);
116 break;
117 case SND_SOC_DAPM_POST_PMD:
118 dev_dbg(pTAS2560->dev, "SND_SOC_DAPM_POST_PMD");
119 tas2560_enable(pTAS2560, false, mchannel);
120 break;
121 }
122
123 return 0;
124}
125*/
126 98
127static int tas2560_AIF_post_event(struct snd_soc_dapm_widget *w, 99static int tas2560_AIF_post_event(struct snd_soc_dapm_widget *w,
128 struct snd_kcontrol *kcontrol, int event) 100 struct snd_kcontrol *kcontrol, int event)
129{ 101{
130 struct snd_soc_codec *codec = w->codec; 102 //struct snd_soc_codec *codec = w->codec;
103 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
131 struct tas2560_priv *pTAS2560 = snd_soc_codec_get_drvdata(codec); 104 struct tas2560_priv *pTAS2560 = snd_soc_codec_get_drvdata(codec);
132 105
133 switch (event) { 106 switch (event) {
@@ -142,36 +115,6 @@ static int tas2560_AIF_post_event(struct snd_soc_dapm_widget *w,
142 return 0; 115 return 0;
143} 116}
144 117
145/*
146static int tas2560_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
147 struct snd_ctl_elem_value *ucontrol)
148{
149 struct snd_soc_dapm_widget_list *wlist =
150 dapm_kcontrol_get_wlist(kcontrol);
151 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
152
153 if (ucontrol->value.integer.value[0]) {
154 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 1, NULL);
155 } else if (!ucontrol->value.integer.value[0]) {
156 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, 0, NULL);
157 }
158
159 return 1;
160}
161
162static const struct snd_kcontrol_new spk_mixer_controls[] = {
163 SOC_SINGLE_EXT("LEFT", SND_SOC_NOPM ,
164 0, 1, 0, tas2560_routing_get_audio_mixer,
165 tas2560_routing_put_audio_mixer),
166};
167
168static const struct snd_kcontrol_new rec_mixer_controls[] = {
169 SOC_SINGLE_EXT("RIGHT", SND_SOC_NOPM,
170 0, 1, 0, tas2560_routing_get_audio_mixer,
171 tas2560_routing_put_audio_mixer),
172};
173*/
174
175static const struct snd_soc_dapm_widget tas2560_dapm_widgets[] = { 118static const struct snd_soc_dapm_widget tas2560_dapm_widgets[] = {
176 SND_SOC_DAPM_AIF_IN_E("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0, 119 SND_SOC_DAPM_AIF_IN_E("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0,
177 tas2560_AIF_post_event, SND_SOC_DAPM_POST_PMU | 120 tas2560_AIF_post_event, SND_SOC_DAPM_POST_PMU |
@@ -179,16 +122,6 @@ static const struct snd_soc_dapm_widget tas2560_dapm_widgets[] = {
179 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), 122 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
180 SND_SOC_DAPM_OUT_DRV("ClassD", SND_SOC_NOPM, 0, 0, NULL, 0), 123 SND_SOC_DAPM_OUT_DRV("ClassD", SND_SOC_NOPM, 0, 0, NULL, 0),
181 SND_SOC_DAPM_SUPPLY("PLL", SND_SOC_NOPM, 0, 0, NULL, 0), 124 SND_SOC_DAPM_SUPPLY("PLL", SND_SOC_NOPM, 0, 0, NULL, 0),
182/*
183 SND_SOC_DAPM_MIXER_E("Left Mixer", SND_SOC_NOPM, 0, 0,
184 left_mixer_controls,
185 ARRAY_SIZE(left_mixer_controls),
186 tas2560_mix_post_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
187 SND_SOC_DAPM_MIXER_E("Right Mixer", SND_SOC_NOPM, 0, 0,
188 right_mixer_controls,
189 ARRAY_SIZE(right_mixer_controls),
190 tas2560_mix_post_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
191*/
192 SND_SOC_DAPM_OUTPUT("OUT") 125 SND_SOC_DAPM_OUTPUT("OUT")
193}; 126};
194 127
@@ -226,7 +159,18 @@ static int tas2560_mute(struct snd_soc_dai *dai, int mute)
226 159
227 mutex_lock(&pTAS2560->codec_lock); 160 mutex_lock(&pTAS2560->codec_lock);
228 dev_dbg(pTAS2560->dev, "%s, %d\n", __func__, mute); 161 dev_dbg(pTAS2560->dev, "%s, %d\n", __func__, mute);
229 tas2560_enable(pTAS2560, !mute, channel_both); 162
163 pr_info("%s: spk_l_control = %d,spk_r_control = %d,mute = %d\n", __func__,spk_l_control,spk_r_control,mute);
164
165 if(1 == spk_l_control){
166 pr_info("%s, SPK_L\n", __func__);
167 tas2560_enable(pTAS2560, !mute, channel_left);
168 }
169 if(1 == spk_r_control){
170 pr_info("%s, SPK_R\n", __func__);
171 tas2560_enable(pTAS2560, !mute, channel_right);
172 }
173
230 mutex_unlock(&pTAS2560->codec_lock); 174 mutex_unlock(&pTAS2560->codec_lock);
231 return 0; 175 return 0;
232} 176}
@@ -301,7 +245,6 @@ static struct snd_soc_dai_driver tas2560_dai_driver[] = {
301 .formats = TAS2560_FORMATS, 245 .formats = TAS2560_FORMATS,
302 }, 246 },
303 .ops = &tas2560_dai_ops, 247 .ops = &tas2560_dai_ops,
304 .symmetric_rates = 1,
305 }, 248 },
306}; 249};
307 250
@@ -359,6 +302,41 @@ static int tas2560_set_load(struct snd_kcontrol *pKcontrol,
359 return 0; 302 return 0;
360} 303}
361 304
305static int tas2560_get_left_speaker_switch(struct snd_kcontrol *pKcontrol,
306 struct snd_ctl_elem_value *pUcontrol)
307{
308 pr_info("%s: pUcontrolL = %ld\n", __func__,pUcontrol->value.integer.value[0]);
309 pUcontrol->value.integer.value[0] = spk_l_control;
310
311 return 0;
312}
313
314static int tas2560_set_left_speaker_switch(struct snd_kcontrol *pKcontrol,
315 struct snd_ctl_elem_value *pUcontrol)
316{
317 pr_info("%s: pUcontrolR = %ld,spk_l_control = %d\n", __func__,pUcontrol->value.integer.value[0],spk_l_control);
318 spk_l_control = pUcontrol->value.integer.value[0];
319 return 1;
320}
321
322
323static int tas2560_get_right_speaker_switch(struct snd_kcontrol *pKcontrol,
324 struct snd_ctl_elem_value *pUcontrol)
325{
326 pr_info("%s: pUcontrol = %ld\n", __func__,pUcontrol->value.integer.value[0]);
327 pUcontrol->value.integer.value[0] = spk_r_control;
328
329 return 0;
330}
331
332static int tas2560_set_right_speaker_switch(struct snd_kcontrol *pKcontrol,
333 struct snd_ctl_elem_value *pUcontrol)
334{
335 pr_info("%s: pUcontrol = %ld,spk_r_control = %d\n", __func__,pUcontrol->value.integer.value[0],spk_r_control);
336 spk_r_control = pUcontrol->value.integer.value[0];
337 return 1;
338}
339
362static int tas2560_get_Sampling_Rate(struct snd_kcontrol *pKcontrol, 340static int tas2560_get_Sampling_Rate(struct snd_kcontrol *pKcontrol,
363 struct snd_ctl_elem_value *pUcontrol) 341 struct snd_ctl_elem_value *pUcontrol)
364{ 342{
@@ -435,12 +413,24 @@ static const struct soc_enum load_enum[] = {
435 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(load_text), load_text), 413 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(load_text), load_text),
436}; 414};
437 415
416static const char *speaker_switch_text[] = {"Off", "On"};
417
418static const struct soc_enum spk_enum[] = {
419 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(speaker_switch_text), speaker_switch_text),
420};
421
438static const char *Sampling_Rate_text[] = {"48_khz", "44.1_khz", "16_khz", "8_khz"}; 422static const char *Sampling_Rate_text[] = {"48_khz", "44.1_khz", "16_khz", "8_khz"};
439 423
440static const struct soc_enum Sampling_Rate_enum[] = { 424static const struct soc_enum Sampling_Rate_enum[] = {
441 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(Sampling_Rate_text), Sampling_Rate_text), 425 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(Sampling_Rate_text), Sampling_Rate_text),
442}; 426};
443 427
428static const char *Channel_Index_text[] = {"left", "right"};
429
430static const struct soc_enum Channel_Index_enum[] = {
431 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(Channel_Index_text), Channel_Index_text),
432};
433
444/* 434/*
445 * DAC digital volumes. From 0 to 15 dB in 1 dB steps 435 * DAC digital volumes. From 0 to 15 dB in 1 dB steps
446 */ 436 */
@@ -453,6 +443,10 @@ static const struct snd_kcontrol_new tas2560_snd_controls[] = {
453 tas2560_get_load, tas2560_set_load), 443 tas2560_get_load, tas2560_set_load),
454 SOC_ENUM_EXT("TAS2560 Right Boost load", load_enum[0], 444 SOC_ENUM_EXT("TAS2560 Right Boost load", load_enum[0],
455 tas2560_get_load, tas2560_set_load), 445 tas2560_get_load, tas2560_set_load),
446 SOC_ENUM_EXT("TAS2560 Left Speaker Switch", spk_enum[0],
447 tas2560_get_left_speaker_switch, tas2560_set_left_speaker_switch),
448 SOC_ENUM_EXT("TAS2560 Right Speaker Switch", spk_enum[0],
449 tas2560_get_right_speaker_switch, tas2560_set_right_speaker_switch),
456 SOC_ENUM_EXT("TAS2560 Sampling Rate", Sampling_Rate_enum[0], 450 SOC_ENUM_EXT("TAS2560 Sampling Rate", Sampling_Rate_enum[0],
457 tas2560_get_Sampling_Rate, tas2560_set_Sampling_Rate), 451 tas2560_get_Sampling_Rate, tas2560_set_Sampling_Rate),
458 SOC_SINGLE_EXT("TAS2560 PowerCtrl", SND_SOC_NOPM, 0, 0x0001, 0, 452 SOC_SINGLE_EXT("TAS2560 PowerCtrl", SND_SOC_NOPM, 0, 0x0001, 0,
diff --git a/tas2560-core.c b/tas2560-core.c
index 2e743f3..6446e4c 100644
--- a/tas2560-core.c
+++ b/tas2560-core.c
@@ -125,7 +125,7 @@ static unsigned int p_tas2560_shutdown_data[] = {
125 /* reg address size values */ 125 /* reg address size values */
126 TAS2560_INT_GEN_REG, 0x01, 0x00, 126 TAS2560_INT_GEN_REG, 0x01, 0x00,
127 TAS2560_CLK_ERR_CTRL, 0x01, 0x00, 127 TAS2560_CLK_ERR_CTRL, 0x01, 0x00,
128 TAS2560_MUTE_REG, 0x01, 0x01,tas2560-stereo-android-driver 128 TAS2560_MUTE_REG, 0x01, 0x01,
129 0xFFFFFFFF, 0xFFFFFFFF 129 0xFFFFFFFF, 0xFFFFFFFF
130}; 130};
131#else 131#else
@@ -520,7 +520,7 @@ int tas2560_set_pll_clkin(struct tas2560_priv *pTAS2560, int clk_id,
520int tas2560_setupPLL(struct tas2560_priv *pTAS2560, int pll_clkin) 520int tas2560_setupPLL(struct tas2560_priv *pTAS2560, int pll_clkin)
521{ 521{
522 unsigned int pll_clk = pTAS2560->mnSamplingRate * 1024; 522 unsigned int pll_clk = pTAS2560->mnSamplingRate * 1024;
523 unsigned int power = 0, temp; 523 unsigned int powerL = 0, powerR = 0, temp;
524 unsigned int d, pll_clkin_divide; 524 unsigned int d, pll_clkin_divide;
525 u8 j, p; 525 u8 j, p;
526 int ret = 0; 526 int ret = 0;
@@ -538,10 +538,17 @@ int tas2560_setupPLL(struct tas2560_priv *pTAS2560, int pll_clkin)
538 pll_clkin = pTAS2560->mnSamplingRate * pTAS2560->mnFrameSize; 538 pll_clkin = pTAS2560->mnSamplingRate * pTAS2560->mnFrameSize;
539 } 539 }
540 540
541 pTAS2560->read(pTAS2560, channel_left, TAS2560_PWR_REG, &power); 541 pTAS2560->read(pTAS2560, channel_left, TAS2560_PWR_REG, &powerL);
542 if (power & TAS2560_PWR_BIT_MASK) { 542 if (powerL & TAS2560_PWR_BIT_MASK) {
543 dev_dbg(pTAS2560->dev, "power down to update PLL\n"); 543 dev_dbg(pTAS2560->dev, "power down to update PLL\n");
544 pTAS2560->write(pTAS2560, channel_both, TAS2560_PWR_REG, TAS2560_PWR_BIT_MASK|TAS2560_MUTE_MASK); 544 pTAS2560->write(pTAS2560, channel_left, TAS2560_PWR_REG, TAS2560_PWR_BIT_MASK|TAS2560_MUTE_MASK);
545 msleep(1);
546 }
547
548 pTAS2560->read(pTAS2560, channel_right, TAS2560_PWR_REG, &powerR);
549 if (powerR & TAS2560_PWR_BIT_MASK) {
550 dev_dbg(pTAS2560->dev, "power down to update PLL\n");
551 pTAS2560->write(pTAS2560, channel_right, TAS2560_PWR_REG, TAS2560_PWR_BIT_MASK|TAS2560_MUTE_MASK);
545 msleep(1); 552 msleep(1);
546 } 553 }
547 554
@@ -609,8 +616,12 @@ int tas2560_setupPLL(struct tas2560_priv *pTAS2560, int pll_clkin)
609 } 616 }
610 617
611 /* Restore PLL status */ 618 /* Restore PLL status */
612 if (power & TAS2560_PWR_BIT_MASK) { 619 if (powerL&TAS2560_PWR_BIT_MASK) {
613 pTAS2560->write(pTAS2560, channel_both, TAS2560_PWR_REG, power); 620 pTAS2560->write(pTAS2560, channel_left, TAS2560_PWR_REG, powerL);
621 msleep(1);
622 }
623 if (powerR&TAS2560_PWR_BIT_MASK) {
624 pTAS2560->write(pTAS2560, channel_right, TAS2560_PWR_REG, powerR);
614 msleep(1); 625 msleep(1);
615 } 626 }
616 627
@@ -736,12 +747,20 @@ int tas2560_parse_dt(struct device *dev, struct tas2560_priv *pTAS2560)
736 dev_dbg(pTAS2560->dev, "ti,reset-gpio=%d", pTAS2560->mnResetGPIO); 747 dev_dbg(pTAS2560->dev, "ti,reset-gpio=%d", pTAS2560->mnResetGPIO);
737 } 748 }
738 749
739 pTAS2560->mnIRQGPIO = of_get_named_gpio(np, "ti,irq-gpio", 0); 750 pTAS2560->mnIRQGPIO1 = of_get_named_gpio(np, "ti,irq-gpio1", 0);
740 if (!gpio_is_valid(pTAS2560->mnIRQGPIO)) { 751 if (!gpio_is_valid(pTAS2560->mnIRQGPIO1)) {
741 dev_err(pTAS2560->dev, "Looking up %s property in node %s failed %d\n", 752 dev_err(pTAS2560->dev, "Looking up %s property in node %s failed %d\n",
742 "ti,irq-gpio", np->full_name, pTAS2560->mnIRQGPIO); 753 "ti,irq-gpio1", np->full_name, pTAS2560->mnIRQGPIO1);
743 } else { 754 } else {
744 dev_dbg(pTAS2560->dev, "ti,irq-gpio=%d", pTAS2560->mnIRQGPIO); 755 dev_dbg(pTAS2560->dev, "ti,irq-gpio1=%d", pTAS2560->mnIRQGPIO1);
756 }
757
758 pTAS2560->mnIRQGPIO2 = of_get_named_gpio(np, "ti,irq-gpio2", 0);
759 if (!gpio_is_valid(pTAS2560->mnIRQGPIO2)) {
760 dev_err(pTAS2560->dev, "Looking up %s property in node %s failed %d\n",
761 "ti,irq-gpio2", np->full_name, pTAS2560->mnIRQGPIO2);
762 } else {
763 dev_dbg(pTAS2560->dev, "ti,irq-gpio2=%d", pTAS2560->mnIRQGPIO2);
745 } 764 }
746 765
747 rc = of_property_read_u32(np, "ti,ppg", &pTAS2560->mnPPG); 766 rc = of_property_read_u32(np, "ti,ppg", &pTAS2560->mnPPG);
@@ -795,7 +814,7 @@ int tas2560_load_platdata(struct tas2560_priv *pTAS2560)
795{ 814{
796 int nResult = 0; 815 int nResult = 0;
797 816
798 if (gpio_is_valid(pTAS2560->mnIRQGPIO)) { 817 if ((gpio_is_valid(pTAS2560->mnIRQGPIO1))&& (gpio_is_valid(pTAS2560->mnIRQGPIO2))) {
799 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_irq_config); 818 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_irq_config);
800 if (nResult < 0) 819 if (nResult < 0)
801 goto end; 820 goto end;
@@ -835,7 +854,7 @@ int tas2560_load_platdata(struct tas2560_priv *pTAS2560)
835 nResult = pTAS2560->write(pTAS2560, channel_left, TAS2560_ASI_OFFSET_1, 0x01); 854 nResult = pTAS2560->write(pTAS2560, channel_left, TAS2560_ASI_OFFSET_1, 0x01);
836 if (nResult < 0) 855 if (nResult < 0)
837 goto end; 856 goto end;
838 nResult = pTAS2560->write(pTAS2560, channel_left, TAS2560_ASI_OFFSET_1, 0x21); 857 nResult = pTAS2560->write(pTAS2560, channel_right, TAS2560_ASI_OFFSET_1, 0x21);
839 } else { 858 } else {
840 dev_err(pTAS2560->dev, "need to implement!!!\n"); 859 dev_err(pTAS2560->dev, "need to implement!!!\n");
841 } 860 }
@@ -850,31 +869,31 @@ end:
850 return nResult; 869 return nResult;
851} 870}
852 871
853static int tas2560_load_postpwrup(struct tas2560_priv *pTAS2560) 872static int tas2560_load_postpwrup(struct tas2560_priv *pTAS2560,enum channel mchannel)
854{ 873{
855 int nResult = 0; 874 int nResult = 0;
856 875
857 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_idle_chnl_detect); 876 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_idle_chnl_detect);
858 if (nResult < 0) 877 if (nResult < 0)
859 goto end; 878 goto end;
860 879
861#ifdef TAS2560_HAPTICS 880#ifdef TAS2560_HAPTICS
862 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_haptics_postpwrup); 881 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_haptics_postpwrup);
863 if (nResult < 0) 882 if (nResult < 0)
864 goto end; 883 goto end;
865 884
866 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_disable_voltage_limiter); 885 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_disable_voltage_limiter);
867 if (nResult < 0) 886 if (nResult < 0)
868 goto end; 887 goto end;
869#else 888#else
870 if (pTAS2560->mnPPG) { 889 if (pTAS2560->mnPPG) {
871 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_PPG_data); 890 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_PPG_data);
872 if (nResult < 0) 891 if (nResult < 0)
873 goto end; 892 goto end;
874 } 893 }
875#endif 894#endif
876 895
877 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_HPF_data); 896 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_HPF_data);
878 if (nResult < 0) 897 if (nResult < 0)
879 goto end; 898 goto end;
880 899
@@ -895,22 +914,22 @@ static int tas2560_load_postpwrup(struct tas2560_priv *pTAS2560)
895 if (nResult < 0) 914 if (nResult < 0)
896 goto end; 915 goto end;
897 916
898 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_boost_headroom_data); 917 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_boost_headroom_data);
899 if (nResult < 0) 918 if (nResult < 0)
900 goto end; 919 goto end;
901 920
902 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_thermal_foldback); 921 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_thermal_foldback);
903 if (nResult < 0) 922 if (nResult < 0)
904 goto end; 923 goto end;
905 924
906 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_Vsense_biquad_data); 925 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_Vsense_biquad_data);
907#endif 926#endif
908 927
909end: 928end:
910 return nResult; 929 return nResult;
911} 930}
912 931
913int tas2560_LoadConfig(struct tas2560_priv *pTAS2560, bool bPowerOn) 932int tas2560_LoadConfig(struct tas2560_priv *pTAS2560, bool bPowerOn, enum channel echannel)
914{ 933{
915 int nResult = 0; 934 int nResult = 0;
916 935
@@ -919,7 +938,7 @@ int tas2560_LoadConfig(struct tas2560_priv *pTAS2560, bool bPowerOn)
919 if (hrtimer_active(&pTAS2560->mtimer)) 938 if (hrtimer_active(&pTAS2560->mtimer))
920 hrtimer_cancel(&pTAS2560->mtimer); 939 hrtimer_cancel(&pTAS2560->mtimer);
921 pTAS2560->enableIRQ(pTAS2560, false); 940 pTAS2560->enableIRQ(pTAS2560, false);
922 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_shutdown_data); 941 nResult = tas2560_i2c_load_data(pTAS2560, echannel, p_tas2560_shutdown_data);
923 if (nResult < 0) 942 if (nResult < 0)
924 goto end; 943 goto end;
925 } 944 }
@@ -943,13 +962,13 @@ int tas2560_LoadConfig(struct tas2560_priv *pTAS2560, bool bPowerOn)
943 962
944 if (bPowerOn) { 963 if (bPowerOn) {
945 dev_dbg(pTAS2560->dev, "%s power up\n", __func__); 964 dev_dbg(pTAS2560->dev, "%s power up\n", __func__);
946 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_startup_data); 965 nResult = tas2560_i2c_load_data(pTAS2560, echannel, p_tas2560_startup_data);
947 if (nResult < 0) 966 if (nResult < 0)
948 goto end; 967 goto end;
949 nResult = tas2560_load_postpwrup(pTAS2560); 968 nResult = tas2560_load_postpwrup(pTAS2560,echannel);
950 if (nResult < 0) 969 if (nResult < 0)
951 goto end; 970 goto end;
952 nResult = tas2560_i2c_load_data(pTAS2560, channel_both, p_tas2560_unmute_data); 971 nResult = tas2560_i2c_load_data(pTAS2560, echannel, p_tas2560_unmute_data);
953 if (nResult < 0) 972 if (nResult < 0)
954 goto end; 973 goto end;
955 pTAS2560->enableIRQ(pTAS2560, true); 974 pTAS2560->enableIRQ(pTAS2560, true);
@@ -961,6 +980,7 @@ end:
961int tas2560_enable(struct tas2560_priv *pTAS2560, bool bEnable, enum channel mchannel) 980int tas2560_enable(struct tas2560_priv *pTAS2560, bool bEnable, enum channel mchannel)
962{ 981{
963 int nResult = 0; 982 int nResult = 0;
983 dev_dbg(pTAS2560->dev, "%s tas2560_enable\n", __func__);
964 984
965 if (bEnable) { 985 if (bEnable) {
966 if (!pTAS2560->mbPowerUp[mchannel - 1]) { 986 if (!pTAS2560->mbPowerUp[mchannel - 1]) {
@@ -969,15 +989,19 @@ int tas2560_enable(struct tas2560_priv *pTAS2560, bool bEnable, enum channel mch
969 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_startup_data); 989 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_startup_data);
970 if (nResult < 0) 990 if (nResult < 0)
971 goto end; 991 goto end;
972 nResult = tas2560_load_postpwrup(pTAS2560); 992 nResult = tas2560_load_postpwrup(pTAS2560,mchannel);
973 if (nResult < 0) 993 if (nResult < 0)
974 goto end; 994 goto end;
975#ifndef TAS2560_HAPTICS 995#ifndef TAS2560_HAPTICS
976 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_unmute_data); 996 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_unmute_data);
977#endif 997#endif
978 pTAS2560->mbPowerUp[mchannel - 1] = true;
979 if (nResult < 0) 998 if (nResult < 0)
980 goto end; 999 goto end;
1000 if(mchannel & channel_left)
1001 pTAS2560->mbPowerUp[0] = true;
1002 if(mchannel & channel_right)
1003 pTAS2560->mbPowerUp[1] = true;
1004
981 pTAS2560->enableIRQ(pTAS2560, true); 1005 pTAS2560->enableIRQ(pTAS2560, true);
982 } 1006 }
983 } else { 1007 } else {
@@ -987,7 +1011,11 @@ int tas2560_enable(struct tas2560_priv *pTAS2560, bool bEnable, enum channel mch
987 hrtimer_cancel(&pTAS2560->mtimer); 1011 hrtimer_cancel(&pTAS2560->mtimer);
988 pTAS2560->enableIRQ(pTAS2560, false); 1012 pTAS2560->enableIRQ(pTAS2560, false);
989 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_shutdown_data); 1013 nResult = tas2560_i2c_load_data(pTAS2560, mchannel, p_tas2560_shutdown_data);
990 pTAS2560->mbPowerUp[mchannel - 1] = false; 1014
1015 if(mchannel & channel_left)
1016 pTAS2560->mbPowerUp[0] = false;
1017 if(mchannel & channel_right)
1018 pTAS2560->mbPowerUp[1] = false;
991 } 1019 }
992 } 1020 }
993 1021
diff --git a/tas2560-core.h b/tas2560-core.h
index bc68576..4cd0421 100644
--- a/tas2560-core.h
+++ b/tas2560-core.h
@@ -39,5 +39,7 @@ void tas2560_sw_shutdown(struct tas2560_priv *pTAS2560, int sw_shutdown);
39int tas2560_enable(struct tas2560_priv *pTAS2560, bool bEnable, enum channel echannel); 39int tas2560_enable(struct tas2560_priv *pTAS2560, bool bEnable, enum channel echannel);
40int tas2560_load_default(struct tas2560_priv *pTAS2560); 40int tas2560_load_default(struct tas2560_priv *pTAS2560);
41int tas2560_load_platdata(struct tas2560_priv *pTAS2560); 41int tas2560_load_platdata(struct tas2560_priv *pTAS2560);
42int tas2560_LoadConfig(struct tas2560_priv *pTAS2560, bool bPowerOn); 42
43int tas2560_LoadConfig(struct tas2560_priv *pTAS2560, bool bPowerOn, enum channel echannel);
44
43#endif /* _TAS2560_CORE_H */ 45#endif /* _TAS2560_CORE_H */
diff --git a/tas2560-regmap.c b/tas2560-regmap.c
index 2d2dfa6..98ee9a4 100644
--- a/tas2560-regmap.c
+++ b/tas2560-regmap.c
@@ -360,14 +360,17 @@ void tas2560_enableIRQ(struct tas2560_priv *pTAS2560, bool enable)
360 if (pTAS2560->mbIRQEnable) 360 if (pTAS2560->mbIRQEnable)
361 return; 361 return;
362 362
363 if (gpio_is_valid(pTAS2560->mnIRQGPIO)) 363 if (gpio_is_valid(pTAS2560->mnIRQGPIO1))
364 enable_irq(pTAS2560->mnIRQ); 364 enable_irq(pTAS2560->mnIRQ1);
365 365 if (gpio_is_valid(pTAS2560->mnIRQGPIO2))
366 enable_irq(pTAS2560->mnIRQ2);
366 schedule_delayed_work(&pTAS2560->irq_work, msecs_to_jiffies(10)); 367 schedule_delayed_work(&pTAS2560->irq_work, msecs_to_jiffies(10));
367 pTAS2560->mbIRQEnable = true; 368 pTAS2560->mbIRQEnable = true;
368 } else { 369 } else {
369 if (gpio_is_valid(pTAS2560->mnIRQGPIO)) 370 if (gpio_is_valid(pTAS2560->mnIRQGPIO1))
370 disable_irq_nosync(pTAS2560->mnIRQ); 371 disable_irq_nosync(pTAS2560->mnIRQ1);
372 if (gpio_is_valid(pTAS2560->mnIRQGPIO2))
373 disable_irq_nosync(pTAS2560->mnIRQ2);
371 374
372 pTAS2560->mbIRQEnable = false; 375 pTAS2560->mbIRQEnable = false;
373 } 376 }
@@ -480,7 +483,6 @@ static void irq_work_routine(struct work_struct *work)
480{ 483{
481 struct tas2560_priv *pTAS2560 = 484 struct tas2560_priv *pTAS2560 =
482 container_of(work, struct tas2560_priv, irq_work.work); 485 container_of(work, struct tas2560_priv, irq_work.work);
483 int nResult = 0;
484 enum channel mchannel; 486 enum channel mchannel;
485 487
486#ifdef CONFIG_TAS2560_CODEC_STEREO 488#ifdef CONFIG_TAS2560_CODEC_STEREO
@@ -496,40 +498,32 @@ static void irq_work_routine(struct work_struct *work)
496 goto end; 498 goto end;
497 } 499 }
498 500
499 if((pTAS2560->mbPowerUp[0]) && (pTAS2560->mbPowerUp[1])) 501 if((pTAS2560->mbPowerUp[0]) && (pTAS2560->mbPowerUp[1])){
500 mchannel = channel_both; 502 mchannel = channel_both;
501 else if(pTAS2560->mbPowerUp[0]) 503 }
504 else if(pTAS2560->mbPowerUp[0]){
502 mchannel = channel_left; 505 mchannel = channel_left;
503 else if(pTAS2560->mbPowerUp[1]) 506 }
507 else if(pTAS2560->mbPowerUp[1]){
504 mchannel = channel_right; 508 mchannel = channel_right;
509 }
505 else 510 else
506 { 511 {
507 dev_err(pTAS2560->dev, "%s, device not powered\n", __func__); 512 dev_err(pTAS2560->dev, "%s, device not powered\n", __func__);
508 goto end; 513 goto end;
509 } 514 }
510 515
511 nResult = tas2560_dev_write(pTAS2560, channel_both, TAS2560_INT_GEN_REG, 0x00);
512 if (nResult < 0)
513 {
514 dev_err(pTAS2560->dev, "Cannot write i2c\n");
515 goto reload;
516 }
517
518 /*needs to reset*/ 516 /*needs to reset*/
519 if(irq_print(pTAS2560, channel_left)) 517 if((mchannel & channel_left) && irq_print(pTAS2560, channel_left))
520 goto reload; 518 goto reload;
521 if(irq_print(pTAS2560, channel_right)) 519 if((mchannel & channel_right) && irq_print(pTAS2560, channel_right))
522 goto reload;
523
524 nResult = tas2560_dev_write(pTAS2560, mchannel, TAS2560_INT_GEN_REG, 0xff);
525 if (nResult < 0)
526 goto reload; 520 goto reload;
527 521
528 goto end; 522 goto end;
529 523
530reload: 524reload:
531 /* hardware reset and reload */ 525 /* hardware reset and reload */
532 tas2560_LoadConfig(pTAS2560, true); 526 tas2560_LoadConfig(pTAS2560, true, mchannel);
533 527
534end: 528end:
535 if (!hrtimer_active(&pTAS2560->mtimer)) { 529 if (!hrtimer_active(&pTAS2560->mtimer)) {
@@ -647,18 +641,42 @@ static int tas2560_i2c_probe(struct i2c_client *client,
647 goto free_gpio; 641 goto free_gpio;
648 } 642 }
649 643
650 if (gpio_is_valid(pTAS2560->mnIRQGPIO)) { 644 if (gpio_is_valid(pTAS2560->mnIRQGPIO1)) {
651 nResult = gpio_request(pTAS2560->mnIRQGPIO, "TAS2560-IRQ"); 645 nResult = gpio_request(pTAS2560->mnIRQGPIO1, "TAS2560-IRQ1");
652 if (nResult < 0) { 646 if (nResult < 0) {
653 dev_err(pTAS2560->dev, "%s: GPIO %d request error\n", 647 dev_err(pTAS2560->dev, "%s: GPIO %d request error\n",
654 __func__, pTAS2560->mnIRQGPIO); 648 __func__, pTAS2560->mnIRQGPIO1);
649 goto free_gpio;
650 }
651 gpio_direction_input(pTAS2560->mnIRQGPIO1);
652 pTAS2560->mnIRQ1 = gpio_to_irq(pTAS2560->mnIRQGPIO1);
653 dev_info(pTAS2560->dev, "irq1 = %d\n", pTAS2560->mnIRQ1);
654
655 nResult = request_threaded_irq(pTAS2560->mnIRQ1, tas2560_irq_handler,
656 NULL, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
657 client->name, pTAS2560);
658 if (nResult < 0) {
659 dev_err(pTAS2560->dev,
660 "request_irq failed, %d\n", nResult);
655 goto free_gpio; 661 goto free_gpio;
656 } 662 }
657 gpio_direction_input(pTAS2560->mnIRQGPIO); 663 disable_irq_nosync(pTAS2560->mnIRQ1);
658 pTAS2560->mnIRQ = gpio_to_irq(pTAS2560->mnIRQGPIO); 664 INIT_DELAYED_WORK(&pTAS2560->irq_work, irq_work_routine);
659 dev_info(pTAS2560->dev, "irq = %d\n", pTAS2560->mnIRQ); 665 }
666 else
667 dev_err(pTAS2560->dev, "irq1 GPIO failed");
668 if (gpio_is_valid(pTAS2560->mnIRQGPIO2)) {
669 nResult = gpio_request(pTAS2560->mnIRQGPIO2, "TAS2560-IRQ2");
670 if (nResult < 0) {
671 dev_err(pTAS2560->dev, "%s: GPIO2 %d request error\n",
672 __func__, pTAS2560->mnIRQGPIO2);
673 goto free_gpio;
674 }
675 gpio_direction_input(pTAS2560->mnIRQGPIO2);
676 pTAS2560->mnIRQ2 = gpio_to_irq(pTAS2560->mnIRQGPIO2);
677 dev_info(pTAS2560->dev, "irq = %d\n", pTAS2560->mnIRQ2);
660 678
661 nResult = request_threaded_irq(pTAS2560->mnIRQ, tas2560_irq_handler, 679 nResult = request_threaded_irq(pTAS2560->mnIRQ2, tas2560_irq_handler,
662 NULL, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, 680 NULL, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
663 client->name, pTAS2560); 681 client->name, pTAS2560);
664 if (nResult < 0) { 682 if (nResult < 0) {
@@ -666,7 +684,7 @@ static int tas2560_i2c_probe(struct i2c_client *client,
666 "request_irq failed, %d\n", nResult); 684 "request_irq failed, %d\n", nResult);
667 goto free_gpio; 685 goto free_gpio;
668 } 686 }
669 disable_irq_nosync(pTAS2560->mnIRQ); 687 disable_irq_nosync(pTAS2560->mnIRQ2);
670 INIT_DELAYED_WORK(&pTAS2560->irq_work, irq_work_routine); 688 INIT_DELAYED_WORK(&pTAS2560->irq_work, irq_work_routine);
671 } 689 }
672 else 690 else
@@ -683,11 +701,11 @@ static int tas2560_i2c_probe(struct i2c_client *client,
683 pTAS2560->runtime_suspend = tas2560_runtime_suspend; 701 pTAS2560->runtime_suspend = tas2560_runtime_suspend;
684 pTAS2560->runtime_resume = tas2560_runtime_resume; 702 pTAS2560->runtime_resume = tas2560_runtime_resume;
685 mutex_init(&pTAS2560->dev_lock); 703 mutex_init(&pTAS2560->dev_lock);
686 704 dev_info(&client->dev, "%s tas2560_LoadConfig\n", __func__);
687 nResult = tas2560_LoadConfig(pTAS2560, false); 705 nResult = tas2560_LoadConfig(pTAS2560, false, channel_both);
688 if (nResult < 0) 706 if (nResult < 0)
689 goto destroy_mutex; 707 goto destroy_mutex;
690 708 dev_info(&client->dev, "%s tas2560_LoadConfig out\n", __func__);
691#ifdef CONFIG_TAS2560_CODEC_STEREO 709#ifdef CONFIG_TAS2560_CODEC_STEREO
692 mutex_init(&pTAS2560->codec_lock); 710 mutex_init(&pTAS2560->codec_lock);
693 tas2560_register_codec(pTAS2560); 711 tas2560_register_codec(pTAS2560);
@@ -709,8 +727,10 @@ free_gpio:
709 if (nResult < 0) { 727 if (nResult < 0) {
710 if (gpio_is_valid(pTAS2560->mnResetGPIO)) 728 if (gpio_is_valid(pTAS2560->mnResetGPIO))
711 gpio_free(pTAS2560->mnResetGPIO); 729 gpio_free(pTAS2560->mnResetGPIO);
712 if (gpio_is_valid(pTAS2560->mnIRQGPIO)) 730 if (gpio_is_valid(pTAS2560->mnIRQGPIO1))
713 gpio_free(pTAS2560->mnIRQGPIO); 731 gpio_free(pTAS2560->mnIRQGPIO1);
732 if (gpio_is_valid(pTAS2560->mnIRQGPIO2))
733 gpio_free(pTAS2560->mnIRQGPIO2);
714 } 734 }
715 735
716end: 736end:
@@ -735,9 +755,10 @@ static int tas2560_i2c_remove(struct i2c_client *client)
735 755
736 if (gpio_is_valid(pTAS2560->mnResetGPIO)) 756 if (gpio_is_valid(pTAS2560->mnResetGPIO))
737 gpio_free(pTAS2560->mnResetGPIO); 757 gpio_free(pTAS2560->mnResetGPIO);
738 if (gpio_is_valid(pTAS2560->mnIRQGPIO)) 758 if (gpio_is_valid(pTAS2560->mnIRQGPIO1))
739 gpio_free(pTAS2560->mnIRQGPIO); 759 gpio_free(pTAS2560->mnIRQGPIO1);
740 760 if (gpio_is_valid(pTAS2560->mnIRQGPIO2))
761 gpio_free(pTAS2560->mnIRQGPIO2);
741 return 0; 762 return 0;
742} 763}
743 764
diff --git a/tas2560.h b/tas2560.h
index cf155a5..90cd0a7 100644
--- a/tas2560.h
+++ b/tas2560.h
@@ -200,8 +200,10 @@ struct tas2560_priv {
200 int mnRightLoad ; 200 int mnRightLoad ;
201 int mnASIFormat; 201 int mnASIFormat;
202 int mnResetGPIO; 202 int mnResetGPIO;
203 int mnIRQGPIO; 203 int mnIRQGPIO1;
204 int mnIRQ; 204 int mnIRQGPIO2;
205 int mnIRQ1;
206 int mnIRQ2;
205 bool mbIRQEnable; 207 bool mbIRQEnable;
206 int mnSamplingRate; 208 int mnSamplingRate;
207 int mnFrameSize; 209 int mnFrameSize;