Speaker Amplifiers (NXP TFA9890) Research

MWisBest

Inactive Recognized Developer
Dec 26, 2010
934
5,816
0
Green Bay, WI
github.com
Lately I've been digging into the speaker amps to see if I could resolve some of the complaints I've had with them. These chips don't seem to have any detailed information anywhere so I thought I'd document my findings here in hopes that it may be useful to others and more information might come to light.


NXP has a couple pdfs with a basic overview of the chip here: TFA9890_SDS.pdf, TFA9890A_SDS.pdf
No idea what the difference is between "TFA9890" and "TFA9890A", but the A rev PDF has some more details to it at least.


Kernel drivers for the TFA chips have been hard to find, and there's no "standard" driver.
1. Motorola seems to have written their own in-house kernel driver for it which is in the shamu kernel of course. It appears to have originated from the Moto X ("ghost") kernel, and it is by far the cleanest looking and most legible driver I've found.
2. Sony has a very ugly looking driver. They do have the registers documented the best I've seen so far though.
3. OnePlus has another odd-looking driver, this one has NXP copyright headers on it but seems to be related to the Sony one.



Problem Solving
One issue I had with the amps was how the volume cut way back when the battery voltage dropped below a certain point. I'm not talking just the gradual drop-off that happens as the battery voltage lowers over time (which is understandable), I'm talking the volume all of a sudden being halved. It turns out this is a feature of the amp:
"By limiting the supply current when the battery voltage is low, it prevents the audio system from drawing excessive load currents from the battery, which could cause a system undervoltage."
This happens by default at 3.53V. I was surprised to find that the Nexus 6 pushes the battery voltage enough for 3.53V to not only be reached, but surpassed, to as low as 3.0V. There's no way in hell the amps are powerful enough to cause a half-volt drop.
Adjusting the protection voltage level resolves this annoyance. For details, see register 0x05.
NOTE: With the Marshmallow update, the "Empty Learning Feature" of the MAX17042 battery gauge chip was enabled, and for some reason this isn't letting the battery drop to voltages as low as it previously did. So to users it may now seem like the speaker volume @ low battery issue is improved, but it's really due to what was once "35%" battery now being more like "15%".

Lately I've ran into an issue with the amps being more aggressive than they used to be with limiting the volume output. Not sure what's going on, but it started after missing an alarm for 20 minutes which was eventually interrupted by an incoming phone call. I wonder if something happened with the transition between the equalizer preset things that caused damage to the amp or speaker somehow. For the first day after this started, playing music at anywhere over 45% volume resulted in instant "volume throttling", and the more I turned it up the worse it got, eventually so bad that I couldn't hear a damn thing from the bottom speaker at all and barely heard the top one. A few days later this has greatly improved, but it's still not like it was when I got my N6.



Driver Comparison/Analysis
The Sony and OnePlus drivers disable clock gating when resetting the DSP, Moto's does not;
https://github.com/CyanogenMod/andr...c/sound/soc/codecs/tfa/src/initTfa9890.c#L107
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa_dsp.c#L289
The Sony and OnePlus drivers set some PLL registers for "optimal amplifier behavior", Moto's doesn't appear to do so;
https://github.com/CyanogenMod/andr...b4cfc/sound/soc/codecs/tfa/src/Tfa98xx.c#L273
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa_dsp.c#L617
Based on ghost's tfa9890 driver commit history, it seems like this might be taken care of with the firmware patches.
https://github.com/CyanogenMod/andr...mmit/892ac7150aba33e73837e3c713812599ba004355
https://github.com/CyanogenMod/andr...mmit/63fdeaa3c79a765f1c04f4b51c71cbb217db6707
https://github.com/CyanogenMod/andr...mmit/1ac301a19efb69f3d466fc53c6880db886409be3
https://github.com/CyanogenMod/andr...mmit/058e87a8128c233d02dff5290b23f3be0c5e86c9 (Note PLL freq/div info here)


The Sony and OnePlus drivers do some weird stuff with register 0x84 (undocumented, related to "MTP" stuff).
https://github.com/CyanogenMod/andr...fc/sound/soc/codecs/tfa/src/initTfa9890.c#L78
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa_dsp.c#L276
The OnePlus driver even tries to "recover" if 0x84 is empty. It's quite aggressive about it, you'll find it checked in numerous places.
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa_dsp.c#L812

The OnePlus driver ignores SWS and SPKS status flags in the monitor function.
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa98xx.c#L284

The main tfa98xx.c file in the OnePlus driver has some minor similarities to the Motorola driver.



Registers
0x00: Status
0x04: I2S Config
0x05: Battery Protection
-- Dropping the ProtectionThreshold (BSST) to 5 (3.23V) is more reasonable for shamu than the default of 8 (3.53V).
0x06: Audio Control
0x07: DCDC Boost
-- Moar voltage, anyone? (DCVO)
0x08: Speaker Calibration
0x09: System Control
0x0A: I2S Select
0x0C: Voltage Sense Config
Few other things that I haven't yet verified if the documentation matches up with the TFA9890:
0x41: PWM Mute Set
0x48: CurrentSense 3
0x49: CurrentSense 4
Note that the Motorola driver does mess with 0x46 through 0x49, but the values don't seem to line up with this file.



TODO
1. Try to dump and document more registers.
2. Figure out how the various eq/config/preset files work.
3. Why does fading sound all the way to one direction still seem to play through both speakers?
4. Can we speed up the channel swapping that occurs upon rotation?
 

rignfool

Senior Member
Dec 8, 2010
5,004
2,726
253
The Poconos
I wouldn't normally post here but...

It appears that the accelerometer or screen rotation seems to also trigger volume throttling...

And prolonged sound at low battery (racing game) seems to cause problems too...

However... Above 80% battery on the fuel gauge and none of these issues appear

Sent from my Nexus 6 using Tapatalk
 
  • Like
Reactions: MWisBest

MWisBest

Inactive Recognized Developer
Dec 26, 2010
934
5,816
0
Green Bay, WI
github.com
I wouldn't normally post here but...

It appears that the accelerometer or screen rotation seems to also trigger volume throttling...

And prolonged sound at low battery (racing game) seems to cause problems too...

However... Above 80% battery on the fuel gauge and none of these issues appear

Sent from my Nexus 6 using Tapatalk
These are interesting observations, and you're spot on with the screen rotation problem.
Screen rotation basically resets the TFA9890 chips to swap the L&R channels, and as a result the chips lose their state about how they were 'volume throttling' previously. The thing that's supposed to make these chips safe for the speakers is they constantly make sure the volume stays low enough not to damage the speakers, but when the chips are reset like that the volume goes back to full bore momentarily and that could very well damage the speakers and make the amps get overtly protective.
 
  • Like
Reactions: erk1725

rignfool

Senior Member
Dec 8, 2010
5,004
2,726
253
The Poconos
I've been able to get in contact with somebody that has worked on the TFA9890. I'm not sure how much they'll be able to share with me (or how much I'll be able to share here), but from what I'm hearing so far the biggest difficulties with the chip is software.
Interestingly enough... After about 12 months with the noticeable volume throttle... I switched to leankernel... And cannot get the volume to throttle... @Imoseyon has no idea what he would/could have done to fix it...

The only difference on my end... Would be that I am back to using mpdecision...

Any thoughts?
 

MWisBest

Inactive Recognized Developer
Dec 26, 2010
934
5,816
0
Green Bay, WI
github.com
Interestingly enough... After about 12 months with the noticeable volume throttle... I switched to leankernel... And cannot get the volume to throttle... @Imoseyon has no idea what he would/could have done to fix it...

The only difference on my end... Would be that I am back to using mpdecision...

Any thoughts?
I'm not at all surprised to hear something like this happen. These chips are THAT weird.

One suggestion for others having issues with volume throttling (sometimes referred to as "automatic gain control" (AGC)): try to force a recalibration of the speaker impedance detection.
To do this, just run the following commands (as root):
Code:
echo 1 > /sys/bus/i2c/drivers/tfa9890/8-0034/force_calib
echo 1 > /sys/bus/i2c/drivers/tfa9890/8-0035/force_calib
And then reboot.
If the calibration is off for some reason, it can screw up the calculations for AGC.
 

bryantjopplin

Senior Member
Sep 15, 2010
1,635
722
0
I'm not at all surprised to hear something like this happen. These chips are THAT weird.

One suggestion for others having issues with volume throttling (sometimes referred to as "automatic gain control" (AGC)): try to force a recalibration of the speaker impedance detection.
To do this, just run the following commands (as root):
Code:
echo 1 > /sys/bus/i2c/drivers/tfa9890/8-0034/force_calib
echo 1 > /sys/bus/i2c/drivers/tfa9890/8-0035/force_calib
And then reboot.
If the calibration is off for some reason, it can screw up the calculations for AGC.
So your on the n6 off the gnex. What does the calibration actually do?

Sent from my Nexus 6 using Tapatalk

---------- Post added 17-12-2015 at 12:08 AM ---------- Previous post was 16-12-2015 at 11:55 PM ----------

I'm not at all surprised to hear something like this happen. These chips are THAT weird.

One suggestion for others having issues with volume throttling (sometimes referred to as "automatic gain control" (AGC)): try to force a recalibration of the speaker impedance detection.
To do this, just run the following commands (as root):
Code:
echo 1 > /sys/bus/i2c/drivers/tfa9890/8-0034/force_calib
echo 1 > /sys/bus/i2c/drivers/tfa9890/8-0035/force_calib
And then reboot.
If the calibration is off for some reason, it can screw up the calculations for AGC.
Have you seen this

https://youtu.be/oaUtrpALyi8

Sent from my Nexus 6 using Tapatalk
 
  • Like
Reactions: milocj and MWisBest

MWisBest

Inactive Recognized Developer
Dec 26, 2010
934
5,816
0
Green Bay, WI
github.com
What does the calibration actually do?
The TFA9890 has a DSP on it, which is (at least partially) responsible for the Automatic Gain Control function. The speaker impedance is used as part of the calculations for it. I would assume at the very least it is used for Ohm's law. I find it interesting that the speakers are spec'd at 8Ω, yet the impedance the DSP is reading can be more like 6Ω or 7Ω.

No, but it's nothing I'm not already familiar with. :)
 

belovedson

Senior Member
Dec 21, 2010
240
26
0
Bothell, WA and Fortuna, CA
Interestingly enough... After about 12 months with the noticeable volume throttle... I switched to leankernel... And cannot get the volume to throttle... @Imoseyon has no idea what he would/could have done to fix it...

The only difference on my end... Would be that I am back to using mpdecision...

Any thoughts?
Have You noticed anything in the kernel that is preventing volume throttle. I am no expert but based on a previous post and 'software' being the difficult aspect of this chip. Maybe it's code that is causing volume throttling.

Would comparing the lean kernal and stock kernal make a difference.

I am highly interested in this thread. I would like to avoid getting a dac/amp external solution if the internal solution will do
 

MWisBest

Inactive Recognized Developer
Dec 26, 2010
934
5,816
0
Green Bay, WI
github.com
Just a little note, there is definitely something up with Alarms that can cause these chips to basically malfunction (at least with my N6).
Today was the fourth time I have tried using my Nexus 6 as an alarm clock, and three of these four times (including this one) have resulted in the AGC acting incredibly stupid, usually lasting about a week. Any music that has even the slightest amount of bass will trigger AGC at as little as 1/4 volume. Nothing makes it past 1/2.
I have tried dumping every damn register when this happens, and then compared it to a register dump when everything works fine, and there's no discernible difference.

My theory is that it may have something to do with what is played for the alarm, at what volume, and for how long.
  1. The one time when this did not happen after using an Alarm, was when I used one of the default alarm tones. The three times alarms did cause the AGC malfunctions were with a fairly heavy rock song with plenty of drums and stuff in it.
  2. Maxed out Alarm volumes can easily cause the amps to clip, regardless of what tone is played. (This is even before the AGC issues start)
  3. I never hear an alarm right away. It usually takes me at least 15 minutes or so to wake up to an alarm.

The amps have different configs applied depending on what is being played through the speakers: music, ringtone, and voice. If Alarms are played with the "ringtone" configuration somehow, it may very well damage the speakers or amplifiers depending on the three things listed above.

Bottom line: if you're a very heavy sleeper like me, I highly suggest avoiding using the Nexus 6 as an alarm clock.
 
Last edited:

belovedson

Senior Member
Dec 21, 2010
240
26
0
Bothell, WA and Fortuna, CA
Just a little note, there is definitely something up with Alarms that can cause these chips to basically malfunction (at least with my N6).
Today was the fourth time I have tried using my Nexus 6 as an alarm clock, and three of these four times (including this one) have resulted in the AGC acting incredibly stupid, usually lasting about a week. Any music that has even the slightest amount of bass will trigger AGC at as little as 1/4 volume. Nothing makes it past 1/2.
I have tried dumping every damn register when this happens, and then compared it to a register dump when everything works fine, and there's no discernible difference.

My theory is that it may have something to do with what is played for the alarm, at what volume, and for how long.
  1. The one time when this did not happen after using an Alarm, was when I used one of the default alarm tones. The three times alarms did cause the AGC malfunctions were with a fairly heavy rock song with plenty of drums and stuff in it.
  2. Maxed out Alarm volumes can easily cause the amps to clip, regardless of what tone is played. (This is even before the AGC issues start)
  3. I never hear an alarm right away. It usually takes me at least 15 minutes or so to wake up to an alarm.

The amps have different configs applied depending on what is being played through the speakers: music, ringtone, and voice. If Alarms are played with the "ringtone" configuration somehow, it may very well damage the speakers or amplifiers depending on the three things listed above.

Bottom line: if you're a very heavy sleeper like me, I highly suggest avoiding using the Nexus 6 as an alarm clock.
This amplifier is such a pain in the butt. Thanks for letting me know about the alarm. I think my alarm didn't go off once or twice in the past. I wonder if using a regular simple ring tone will offset the issue
 

rignfool

Senior Member
Dec 8, 2010
5,004
2,726
253
The Poconos
Bumping this in hopes there's been some sort of fix.
The best that I have come up with...

Is to run as bone stock a kernel as possible...

We are truly looking for one that still has the 3 second boost for mpdecision... Factory stock... Pure Nexus... One of those...

And... For added flavor... ARISE sound mod smooths everything out...

However... There is nothing you can do when BCL hits... Your volume will drop...

I'm currently experimenting with the thermal-engine config file and gonna see if throttling at higher battery stops the acute voltage drops that I guess causes the speakers to go quiet...
 

unsungkhan

Senior Member
Mar 30, 2012
411
162
0
If anyone is still working on this, I've found a bit of code that looks interesting.

https://github.com/PureNexusProject...b/android-7.1/sound/soc/codecs/tfa9890.c#L783

I've omitted this bit of code, compiled and sound still seems to be working. Might be placebo, but sound seems *a tad bit* louder, but volume deterioration at certain battery levels still in effect.

Any suggestions? What other files can be looked into?
 

Axel85

Senior Member
May 9, 2010
812
148
0
Lately I've been digging into the speaker amps to see if I could resolve some of the complaints I've had with them. These chips don't seem to have any detailed information anywhere so I thought I'd document my findings here in hopes that it may be useful to others and more information might come to light.


NXP has a couple pdfs with a basic overview of the chip here: TFA9890_SDS.pdf, TFA9890A_SDS.pdf
No idea what the difference is between "TFA9890" and "TFA9890A", but the A rev PDF has some more details to it at least.


Kernel drivers for the TFA chips have been hard to find, and there's no "standard" driver.
1. Motorola seems to have written their own in-house kernel driver for it which is in the shamu kernel of course. It appears to have originated from the Moto X ("ghost") kernel, and it is by far the cleanest looking and most legible driver I've found.
2. Sony has a very ugly looking driver. They do have the registers documented the best I've seen so far though.
3. OnePlus has another odd-looking driver, this one has NXP copyright headers on it but seems to be related to the Sony one.



Problem Solving
One issue I had with the amps was how the volume cut way back when the battery voltage dropped below a certain point. I'm not talking just the gradual drop-off that happens as the battery voltage lowers over time (which is understandable), I'm talking the volume all of a sudden being halved. It turns out this is a feature of the amp:
"By limiting the supply current when the battery voltage is low, it prevents the audio system from drawing excessive load currents from the battery, which could cause a system undervoltage."
This happens by default at 3.53V. I was surprised to find that the Nexus 6 pushes the battery voltage enough for 3.53V to not only be reached, but surpassed, to as low as 3.0V. There's no way in hell the amps are powerful enough to cause a half-volt drop.
Adjusting the protection voltage level resolves this annoyance. For details, see register 0x05.
NOTE: With the Marshmallow update, the "Empty Learning Feature" of the MAX17042 battery gauge chip was enabled, and for some reason this isn't letting the battery drop to voltages as low as it previously did. So to users it may now seem like the speaker volume @ low battery issue is improved, but it's really due to what was once "35%" battery now being more like "15%".

Lately I've ran into an issue with the amps being more aggressive than they used to be with limiting the volume output. Not sure what's going on, but it started after missing an alarm for 20 minutes which was eventually interrupted by an incoming phone call. I wonder if something happened with the transition between the equalizer preset things that caused damage to the amp or speaker somehow. For the first day after this started, playing music at anywhere over 45% volume resulted in instant "volume throttling", and the more I turned it up the worse it got, eventually so bad that I couldn't hear a damn thing from the bottom speaker at all and barely heard the top one. A few days later this has greatly improved, but it's still not like it was when I got my N6.



Driver Comparison/Analysis
The Sony and OnePlus drivers disable clock gating when resetting the DSP, Moto's does not;
https://github.com/CyanogenMod/andr...c/sound/soc/codecs/tfa/src/initTfa9890.c#L107
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa_dsp.c#L289
The Sony and OnePlus drivers set some PLL registers for "optimal amplifier behavior", Moto's doesn't appear to do so;
https://github.com/CyanogenMod/andr...b4cfc/sound/soc/codecs/tfa/src/Tfa98xx.c#L273
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa_dsp.c#L617
Based on ghost's tfa9890 driver commit history, it seems like this might be taken care of with the firmware patches.
https://github.com/CyanogenMod/andr...mmit/892ac7150aba33e73837e3c713812599ba004355
https://github.com/CyanogenMod/andr...mmit/63fdeaa3c79a765f1c04f4b51c71cbb217db6707
https://github.com/CyanogenMod/andr...mmit/1ac301a19efb69f3d466fc53c6880db886409be3
https://github.com/CyanogenMod/andr...mmit/058e87a8128c233d02dff5290b23f3be0c5e86c9 (Note PLL freq/div info here)


The Sony and OnePlus drivers do some weird stuff with register 0x84 (undocumented, related to "MTP" stuff).
https://github.com/CyanogenMod/andr...fc/sound/soc/codecs/tfa/src/initTfa9890.c#L78
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa_dsp.c#L276
The OnePlus driver even tries to "recover" if 0x84 is empty. It's quite aggressive about it, you'll find it checked in numerous places.
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa_dsp.c#L812

The OnePlus driver ignores SWS and SPKS status flags in the monitor function.
https://github.com/OnePlusOSS/andro...5.1.1/sound/soc/codecs/tfa9890/tfa98xx.c#L284

The main tfa98xx.c file in the OnePlus driver has some minor similarities to the Motorola driver.



Registers
0x00: Status
0x04: I2S Config
0x05: Battery Protection
-- Dropping the ProtectionThreshold (BSST) to 5 (3.23V) is more reasonable for shamu than the default of 8 (3.53V).
0x06: Audio Control
0x07: DCDC Boost
-- Moar voltage, anyone? (DCVO)
0x08: Speaker Calibration
0x09: System Control
0x0A: I2S Select
0x0C: Voltage Sense Config
Few other things that I haven't yet verified if the documentation matches up with the TFA9890:
0x41: PWM Mute Set
0x48: CurrentSense 3
0x49: CurrentSense 4
Note that the Motorola driver does mess with 0x46 through 0x49, but the values don't seem to line up with this file.



TODO
1. Try to dump and document more registers.
2. Figure out how the various eq/config/preset files work.
3. Why does fading sound all the way to one direction still seem to play through both speakers?
4. Can we speed up the channel swapping that occurs upon rotation?
Very interesting documentation, I M a nexus 6 user since yesterday and I noticed this problem since I first tested audio with a song in YouTube , expecting for great udio performance, but let down in the end... Wish there would be some way to bypass this stupid limitation or bug. I'm a technician , so in some way maybe I could help a little bit to test
 

Axel85

Senior Member
May 9, 2010
812
148
0
I'm not at all surprised to hear something like this happen. These chips are THAT weird.

One suggestion for others having issues with volume throttling (sometimes referred to as "automatic gain control" (AGC)): try to force a recalibration of the speaker impedance detection.
To do this, just run the following commands (as root):
Code:
echo 1 > /sys/bus/i2c/drivers/tfa9890/8-0034/force_calib
echo 1 > /sys/bus/i2c/drivers/tfa9890/8-0035/force_calib
And then reboot.
If the calibration is off for some reason, it can screw up the calculations for AGC.
This incredibly improved my nexus 6 audio of at least 50℅ , I couldn't go over half volume that AGC started to cut volume to a stupid low point. Now I can stay at max with no problem
 

GrayBoltWolf

Senior Member
Mar 21, 2012
5,376
2,518
0
Raleigh, NC
boltwolf.net
Kinda related. If you build from AOSP right now, it seems that the AGC is extremely strong. Hit about 25% volume and it never gets any louder past that. Same with speakerphone on calls. Been tearing my hair out trying to figure this out since the OTA works fine and other ROMs on 7.1.1 work fine too.
 
  • Like
Reactions: h20ray

h20ray

Senior Member
Nov 11, 2011
307
90
58
Semarang
tujuhcahaya.com
Kinda related. If you build from AOSP right now, it seems that the AGC is extremely strong. Hit about 25% volume and it never gets any louder past that. Same with speakerphone on calls. Been tearing my hair out trying to figure this out since the OTA works fine and other ROMs on 7.1.1 work fine too.
agree..
i wish there is some solutions for this problem.. :(
 
  • Like
Reactions: chuckiler