Member
Posts: 12
Karma: 10000
Join Date: Sep 2017
Device: Kindle PW2
|
I had a poke through the kernel sources and found this in linux-3.0.35\drivers\power\max77696-battery.c:
The battery check seems to go through this logic:
IF the temp difference is less than 15 OR we're in diags OR it's a wario or woody board OR we've set the battery check to disabled, we can return 1 - we passed the check!
This is where I believe my board goes wonky on the display thermistor side. The battery thermistor returns a proper value of about 82F - around 27-28C. The 5.4.0 & 5.4.3.2 kernels, when the ADC fails to retrieve a proper value for the display thermistor, hard-set it to 43C. If the battery is warm enough, the 15-degree delta check is passed and the battery ID check passes. This explains why I was able to have occasional successes booting with the 5.4.x firmware, but none with any higher. I took a look at the output of the 5.8.7.0.1 kernel:
That would explain it! The temp_delta is always greater than 15, so this returns false. Diags isn't set, so that also returns false. This isn't a wario or woody board (I believe), so this also returns false. The battery check is not disabled, also false. Because the entire OR chain is false, the check returns 0. When diags mode is set, the Diags condition of the above chain becomes true, setting the if conditional to true, returning 1, and passing the check.
Looking at max77696-adc.c from the 5.8.7.0.1 sources, we see how the ADC logic works:
The temp range it operates with, ranging from -10 to +75C:
Spoiler:
Code:
static struct lkup_data ntc_lkup[TEMP_RANGE] = {
{75,0x95},
{74,0x9A},
{73,0x9F},
{72,0xA4},
{71,0xAA},
{70,0xAF},
{69,0xB4},
{68,0xBA},
{67,0xBF},
{66,0xC5},
{65,0xCA},
{64,0xD0},
{63,0xD6},
{62,0xDC},
{61,0xE3},
{60,0xE9},
{59,0xF0},
{58,0xF7},
{57,0xFE},
{56,0x105},
{55,0x10D},
{54,0x114},
{53,0x11D},
{52,0x125},
{51,0x12D},
{50,0x136},
{49,0x140},
{48,0x149},
{47,0x153},
{46,0x15D},
{45,0x168},
{44,0x172},
{43,0x17E},
{42,0x189},
{41,0x195},
{40,0x1A2},
{39,0x1AF},
{38,0x1BC},
{37,0x1CA},
{36,0x1D8},
{35,0x1E6},
{34,0x1F6},
{33,0x205},
{32,0x215},
{31,0x226},
{30,0x237},
{29,0x249},
{28,0x25B},
{27,0x26E},
{26,0x281},
{25,0x295},
{24,0x2A9},
{23,0x2BE},
{22,0x2D4},
{21,0x2EA},
{20,0x301},
{19,0x319},
{18,0x331},
{17,0x34A},
{16,0x363},
{15,0x37E},
{14,0x399},
{13,0x3B4},
{12,0x3D1},
{11,0x3EE},
{10,0x40C},
{9,0x42B},
{8,0x44A},
{7,0x46A},
{6,0x48B},
{5,0x4AD},
{4,0x4D0},
{3,0x4F3},
{2,0x517},
{1,0x53C},
{0,0x562},
{-1,0x589},
{-2,0x5B1},
{-3,0x5DA},
{-4,0x603},
{-5,0x62E},
{-6,0x659},
{-7,0x686},
{-8,0x6B3},
{-9,0x6E1},
{-10,0x710},
};
As well as the code that operates on it. It seems to be a comparator, starting at -10C and going up to 75C hoping to strike a match against what it read. If a match is found, it is set to whatever the counter has reached. Otherwise, if the ADC value is outside of the -10/+75C bounds, if it's above the bound, it gets set to 75C. If it's below, it gets set to -10C. As it's being set to 75C, we know the value the ADC is reading is above 75.
Looking at max77696-adc.c from the 5.4.0 sources, sure enough! A range of +3 to +43C!
Spoiler:
Code:
static struct lkup_data ntc_lkup[TEMP_RANGE] = {
{43, 0x17A}, {38, 0x1B4}, {33, 0x1FA}, {30, 0x22C}, {27, 0x25D},
{24, 0x296}, {21, 0x2D3}, {18, 0x322}, {15, 0x35F}, {12, 0x3AD},
{9, 0x403}, {6, 0x45D}, {3, 0x49D},
};
This confirms two scenarios I've seen: that of the display temp set to 43, and that of it set to 3. We now know where those values came from and how they ended up that way.
The question now is what causes the max77696 to retrieve an incorrect value from the display thermistor (also perhaps to have a peek at what the value it retrieves *is*).
|