A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

axp-pmu: adc refactor

Remove the battery power ADC since it's not used right now,
and seems to fluctuate too rapidly to be of much use.

Change-Id: If115e4e3ce14d4c18ce899f5a889f7f99ab66489

+60 -129
+28 -118
firmware/drivers/axp-pmu.c
··· 36 36 uint8_t reg; 37 37 uint8_t en_reg; 38 38 uint8_t en_bit; 39 + int8_t num; 40 + int8_t den; 39 41 }; 40 42 41 43 struct axp_supply_info { ··· 49 51 }; 50 52 51 53 static const struct axp_adc_info axp_adc_info[NUM_ADC_CHANNELS] = { 52 - {0x56, AXP_REG_ADCENABLE1, 5}, /* ACIN_VOLTAGE */ 53 - {0x58, AXP_REG_ADCENABLE1, 4}, /* ACIN_CURRENT */ 54 - {0x5a, AXP_REG_ADCENABLE1, 3}, /* VBUS_VOLTAGE */ 55 - {0x5c, AXP_REG_ADCENABLE1, 2}, /* VBUS_CURRENT */ 56 - {0x5e, AXP_REG_ADCENABLE2, 7}, /* INTERNAL_TEMP */ 57 - {0x62, AXP_REG_ADCENABLE1, 1}, /* TS_INPUT */ 58 - {0x78, AXP_REG_ADCENABLE1, 7}, /* BATTERY_VOLTAGE */ 59 - {0x7a, AXP_REG_ADCENABLE1, 6}, /* CHARGE_CURRENT */ 60 - {0x7c, AXP_REG_ADCENABLE1, 6}, /* DISCHARGE_CURRENT */ 61 - {0x7e, AXP_REG_ADCENABLE1, 1}, /* APS_VOLTAGE */ 62 - {0x70, 0xff, 0}, /* BATTERY_POWER */ 54 + [ADC_ACIN_VOLTAGE] = {0x56, AXP_REG_ADCENABLE1, 1 << 5, 17, 10}, 55 + [ADC_ACIN_CURRENT] = {0x58, AXP_REG_ADCENABLE1, 1 << 4, 5, 8}, 56 + [ADC_VBUS_VOLTAGE] = {0x5a, AXP_REG_ADCENABLE1, 1 << 3, 17, 10}, 57 + [ADC_VBUS_CURRENT] = {0x5c, AXP_REG_ADCENABLE1, 1 << 2, 3, 8}, 58 + [ADC_INTERNAL_TEMP] = {0x5e, AXP_REG_ADCENABLE2, 1 << 7, 0, 0}, 59 + [ADC_TS_INPUT] = {0x62, AXP_REG_ADCENABLE1, 1 << 1, 4, 5}, 60 + [ADC_BATTERY_VOLTAGE] = {0x78, AXP_REG_ADCENABLE1, 1 << 7, 11, 10}, 61 + [ADC_CHARGE_CURRENT] = {0x7a, AXP_REG_ADCENABLE1, 1 << 6, 1, 2}, 62 + [ADC_DISCHARGE_CURRENT] = {0x7c, AXP_REG_ADCENABLE1, 1 << 6, 1, 2}, 63 + [ADC_APS_VOLTAGE] = {0x7e, AXP_REG_ADCENABLE1, 1 << 1, 7, 5}, 63 64 }; 64 65 65 66 static const struct axp_supply_info axp_supply_info[AXP_NUM_SUPPLIES] = { ··· 126 127 #endif 127 128 }; 128 129 129 - static struct axp_driver { 130 - int adc_enable; 131 - } axp; 132 - 133 - static void axp_init_enabled_adcs(void) 134 - { 135 - axp.adc_enable = 0; 136 - 137 - /* Read enabled ADCs from the hardware */ 138 - uint8_t regs[2]; 139 - int rc = i2c_reg_read(AXP_PMU_BUS, AXP_PMU_ADDR, 140 - AXP_REG_ADCENABLE1, 2, &regs[0]); 141 - if(rc != I2C_STATUS_OK) 142 - return; 143 - 144 - /* Parse registers to set ADC enable bits */ 145 - const struct axp_adc_info* info = axp_adc_info; 146 - for(int i = 0; i < NUM_ADC_CHANNELS; ++i) { 147 - if(info[i].en_reg == 0xff) 148 - continue; 149 - 150 - if(regs[info[i].en_reg - AXP_REG_ADCENABLE1] & info[i].en_bit) 151 - axp.adc_enable |= 1 << i; 152 - } 153 - 154 - /* Handle battery power ADC */ 155 - if((axp.adc_enable & (1 << ADC_BATTERY_VOLTAGE)) && 156 - (axp.adc_enable & (1 << ADC_DISCHARGE_CURRENT))) { 157 - axp.adc_enable |= (1 << ADC_BATTERY_POWER); 158 - } 159 - } 160 - 161 130 void axp_init(void) 162 131 { 163 - axp_init_enabled_adcs(); 164 - 165 - /* We need discharge current ADC to reliably poll for a full battery */ 166 - int bits = axp.adc_enable; 167 - bits |= (1 << ADC_DISCHARGE_CURRENT); 168 - axp_adc_set_enabled(bits); 169 132 } 170 133 171 134 void axp_supply_set_voltage(int supply, int voltage) ··· 294 257 295 258 int axp_adc_read_raw(int adc) 296 259 { 297 - /* Don't give a reading if the ADC is not enabled */ 298 - if((axp.adc_enable & (1 << adc)) == 0) 299 - return INT_MIN; 300 - 301 260 /* Read the ADC */ 302 - uint8_t buf[3]; 303 - int count = (adc == ADC_BATTERY_POWER) ? 3 : 2; 261 + uint8_t buf[2]; 304 262 uint8_t reg = axp_adc_info[adc].reg; 305 - int rc = i2c_reg_read(AXP_PMU_BUS, AXP_PMU_ADDR, reg, count, &buf[0]); 263 + int rc = i2c_reg_read(AXP_PMU_BUS, AXP_PMU_ADDR, reg, 2, &buf[0]); 306 264 if(rc != I2C_STATUS_OK) 307 265 return INT_MIN; 308 266 309 267 /* Parse the value */ 310 - if(adc == ADC_BATTERY_POWER) 311 - return (buf[0] << 16) | (buf[1] << 8) | buf[2]; 312 - else if(adc == ADC_CHARGE_CURRENT || adc == ADC_DISCHARGE_CURRENT) 268 + if(adc == ADC_CHARGE_CURRENT || adc == ADC_DISCHARGE_CURRENT) 313 269 return (buf[0] << 5) | (buf[1] & 0x1f); 314 270 else 315 271 return (buf[0] << 4) | (buf[1] & 0xf); ··· 317 273 318 274 int axp_adc_conv_raw(int adc, int value) 319 275 { 320 - switch(adc) { 321 - case ADC_ACIN_VOLTAGE: 322 - case ADC_VBUS_VOLTAGE: 323 - /* 0 mV ... 6.9615 mV, step 1.7 mV */ 324 - return value * 17 / 10; 325 - case ADC_ACIN_CURRENT: 326 - /* 0 mA ... 2.5594 A, step 0.625 mA */ 327 - return value * 5 / 8; 328 - case ADC_VBUS_CURRENT: 329 - /* 0 mA ... 1.5356 A, step 0.375 mA */ 330 - return value * 3 / 8; 331 - case ADC_INTERNAL_TEMP: 332 - /* -144.7 C ... 264.8 C, step 0.1 C */ 276 + if(adc == ADC_INTERNAL_TEMP) 333 277 return value - 1447; 334 - case ADC_TS_INPUT: 335 - /* 0 mV ... 3.276 V, step 0.8 mV */ 336 - return value * 4 / 5; 337 - case ADC_BATTERY_VOLTAGE: 338 - /* 0 mV ... 4.5045 V, step 1.1 mV */ 339 - return value * 11 / 10; 340 - case ADC_CHARGE_CURRENT: 341 - case ADC_DISCHARGE_CURRENT: 342 - /* 0 mA to 4.095 A, step 0.5 mA */ 343 - return value / 2; 344 - case ADC_APS_VOLTAGE: 345 - /* 0 mV to 5.733 V, step 1.4 mV */ 346 - return value * 7 / 5; 347 - case ADC_BATTERY_POWER: 348 - /* 0 uW to 23.6404 W, step 0.55 uW */ 349 - return value * 11 / 20; 350 - default: 351 - /* Shouldn't happen */ 352 - return INT_MIN; 353 - } 354 - } 355 - 356 - int axp_adc_get_enabled(void) 357 - { 358 - return axp.adc_enable; 278 + else 279 + return axp_adc_info[adc].num * value / axp_adc_info[adc].den; 359 280 } 360 281 361 282 void axp_adc_set_enabled(int adc_bits) 362 283 { 363 - /* Ignore no-op */ 364 - if(adc_bits == axp.adc_enable) 365 - return; 284 + uint8_t xfer[3]; 285 + xfer[0] = 0; 286 + xfer[1] = AXP_REG_ADCENABLE2; 287 + xfer[2] = 0; 366 288 367 289 /* Compute the new register values */ 368 290 const struct axp_adc_info* info = axp_adc_info; 369 - uint8_t regs[2] = {0, 0}; 370 291 for(int i = 0; i < NUM_ADC_CHANNELS; ++i) { 371 - if(info[i].en_reg == 0xff) 292 + if(!(adc_bits & (1 << i))) 372 293 continue; 373 294 374 - if(adc_bits & (1 << i)) 375 - regs[info[i].en_reg - 0x82] |= 1 << info[i].en_bit; 376 - } 377 - 378 - /* These ADCs share an enable bit */ 379 - if(adc_bits & ((1 << ADC_CHARGE_CURRENT)|(1 << ADC_DISCHARGE_CURRENT))) { 380 - adc_bits |= (1 << ADC_CHARGE_CURRENT); 381 - adc_bits |= (1 << ADC_DISCHARGE_CURRENT); 382 - } 383 - 384 - /* Enable required bits for battery power ADC */ 385 - if(adc_bits & (1 << ADC_BATTERY_POWER)) { 386 - regs[0] |= 1 << info[ADC_DISCHARGE_CURRENT].en_bit; 387 - regs[0] |= 1 << info[ADC_BATTERY_VOLTAGE].en_bit; 295 + if(info[i].en_reg == AXP_REG_ADCENABLE1) 296 + xfer[0] |= info[i].en_bit; 297 + else 298 + xfer[2] |= info[i].en_bit; 388 299 } 389 300 390 301 /* Update the configuration */ 391 - i2c_reg_write(AXP_PMU_BUS, AXP_PMU_ADDR, AXP_REG_ADCENABLE1, 2, &regs[0]); 392 - axp.adc_enable = adc_bits; 302 + i2c_reg_write(AXP_PMU_BUS, AXP_PMU_ADDR, AXP_REG_ADCENABLE1, 3, &xfer[0]); 393 303 } 394 304 395 305 int axp_adc_get_rate(void)
+1 -3
firmware/export/axp-pmu.h
··· 37 37 #define ADC_CHARGE_CURRENT 7 38 38 #define ADC_DISCHARGE_CURRENT 8 39 39 #define ADC_APS_VOLTAGE 9 40 - #define ADC_BATTERY_POWER 10 41 - #define NUM_ADC_CHANNELS 11 40 + #define NUM_ADC_CHANNELS 10 42 41 43 42 /* ADC sampling rates */ 44 43 #define AXP_ADC_RATE_25HZ 0 ··· 123 122 extern int axp_adc_read(int adc); 124 123 extern int axp_adc_read_raw(int adc); 125 124 extern int axp_adc_conv_raw(int adc, int value); 126 - extern int axp_adc_get_enabled(void); 127 125 extern void axp_adc_set_enabled(int adc_bits); 128 126 extern int axp_adc_get_rate(void); 129 127 extern void axp_adc_set_rate(int rate);
+9 -4
firmware/target/mips/ingenic_x1000/erosqnative/power-erosqnative.c
··· 63 63 /* Set lowest sample rate */ 64 64 axp_adc_set_rate(AXP_ADC_RATE_25HZ); 65 65 66 - /* Ensure battery voltage ADC is enabled */ 67 - int bits = axp_adc_get_enabled(); 68 - bits |= (1 << ADC_BATTERY_VOLTAGE); 69 - axp_adc_set_enabled(bits); 66 + /* Enable required ADCs */ 67 + axp_adc_set_enabled( 68 + (1 << ADC_BATTERY_VOLTAGE) | 69 + (1 << ADC_CHARGE_CURRENT) | 70 + (1 << ADC_DISCHARGE_CURRENT) | 71 + (1 << ADC_VBUS_VOLTAGE) | 72 + (1 << ADC_VBUS_CURRENT) | 73 + (1 << ADC_INTERNAL_TEMP) | 74 + (1 << ADC_APS_VOLTAGE)); 70 75 71 76 /* Turn on all power outputs */ 72 77 i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
+9 -4
firmware/target/mips/ingenic_x1000/fiiom3k/power-fiiom3k.c
··· 61 61 /* Set lowest sample rate */ 62 62 axp_adc_set_rate(AXP_ADC_RATE_25HZ); 63 63 64 - /* Ensure battery voltage ADC is enabled */ 65 - int bits = axp_adc_get_enabled(); 66 - bits |= (1 << ADC_BATTERY_VOLTAGE); 67 - axp_adc_set_enabled(bits); 64 + /* Enable required ADCs */ 65 + axp_adc_set_enabled( 66 + (1 << ADC_BATTERY_VOLTAGE) | 67 + (1 << ADC_CHARGE_CURRENT) | 68 + (1 << ADC_DISCHARGE_CURRENT) | 69 + (1 << ADC_VBUS_VOLTAGE) | 70 + (1 << ADC_VBUS_CURRENT) | 71 + (1 << ADC_INTERNAL_TEMP) | 72 + (1 << ADC_APS_VOLTAGE)); 68 73 69 74 /* Turn on all power outputs */ 70 75 i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
+13
firmware/target/mips/ingenic_x1000/shanlingq1/power-shanlingq1.c
··· 78 78 cw2015_init(); 79 79 #endif 80 80 81 + /* Set lowest sample rate */ 82 + axp_adc_set_rate(AXP_ADC_RATE_25HZ); 83 + 84 + /* Enable required ADCs */ 85 + axp_adc_set_enabled( 86 + (1 << ADC_BATTERY_VOLTAGE) | 87 + (1 << ADC_CHARGE_CURRENT) | 88 + (1 << ADC_DISCHARGE_CURRENT) | 89 + (1 << ADC_VBUS_VOLTAGE) | 90 + (1 << ADC_VBUS_CURRENT) | 91 + (1 << ADC_INTERNAL_TEMP) | 92 + (1 << ADC_APS_VOLTAGE)); 93 + 81 94 /* Change supply voltage from the default of 1250 mV to 1200 mV, 82 95 * this matches the original firmware's settings. Didn't observe 83 96 * any obviously bad behavior at 1250 mV, but better to be safe. */