summaryrefslogtreecommitdiffstats
path: root/firmware/drivers
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-04-21 01:45:34 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-04-21 18:31:55 +0000
commit088ebb5fac02932178fe0da31dd8966472225bdf (patch)
tree68f21b20a7eb0a1c1479033ccf031a18701afa6b /firmware/drivers
parentf6d3680cb84c05d3037650b12e6f8c258b2a6758 (diff)
downloadrockbox-088ebb5fac02932178fe0da31dd8966472225bdf.tar.gz
rockbox-088ebb5fac02932178fe0da31dd8966472225bdf.zip
Minor enhancements to axp173 driver
- Added register names to reduce usage of magic numbers - Added function to control max charging current, needed for USB - Corrected comment about axp173, since FiiO M3K has an axp192 Change-Id: I6604ce8d44e5a2ee84061cf042d17ccc4734ac57
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/axp173.c105
1 files changed, 81 insertions, 24 deletions
diff --git a/firmware/drivers/axp173.c b/firmware/drivers/axp173.c
index 22417650fc..0c9b9c81a4 100644
--- a/firmware/drivers/axp173.c
+++ b/firmware/drivers/axp173.c
@@ -35,21 +35,22 @@ static const struct axp173_adc_info {
uint8_t en_reg;
uint8_t en_bit;
} axp173_adc_info[NUM_ADC_CHANNELS] = {
- {0x56, 0x82, 5}, /* ACIN_VOLTAGE */
- {0x58, 0x82, 4}, /* ACIN_CURRENT */
- {0x5a, 0x82, 3}, /* VBUS_VOLTAGE */
- {0x5c, 0x82, 2}, /* VBUS_CURRENT */
- {0x5e, 0x83, 7}, /* INTERNAL_TEMP */
- {0x62, 0x82, 1}, /* TS_INPUT */
- {0x78, 0x82, 7}, /* BATTERY_VOLTAGE */
- {0x7a, 0x82, 6}, /* CHARGE_CURRENT */
- {0x7c, 0x82, 6}, /* DISCHARGE_CURRENT */
- {0x7e, 0x82, 1}, /* APS_VOLTAGE */
- {0x70, 0xff, 0}, /* BATTERY_POWER */
+ {0x56, AXP173_REG_ADCENABLE1, 5}, /* ACIN_VOLTAGE */
+ {0x58, AXP173_REG_ADCENABLE1, 4}, /* ACIN_CURRENT */
+ {0x5a, AXP173_REG_ADCENABLE1, 3}, /* VBUS_VOLTAGE */
+ {0x5c, AXP173_REG_ADCENABLE1, 2}, /* VBUS_CURRENT */
+ {0x5e, AXP173_REG_ADCENABLE2, 7}, /* INTERNAL_TEMP */
+ {0x62, AXP173_REG_ADCENABLE1, 1}, /* TS_INPUT */
+ {0x78, AXP173_REG_ADCENABLE1, 7}, /* BATTERY_VOLTAGE */
+ {0x7a, AXP173_REG_ADCENABLE1, 6}, /* CHARGE_CURRENT */
+ {0x7c, AXP173_REG_ADCENABLE1, 6}, /* DISCHARGE_CURRENT */
+ {0x7e, AXP173_REG_ADCENABLE1, 1}, /* APS_VOLTAGE */
+ {0x70, 0xff, 0}, /* BATTERY_POWER */
};
static struct axp173 {
int adc_enable;
+ int chargecurrent_setting;
} axp173;
static void axp173_init_enabled_adcs(void)
@@ -58,7 +59,8 @@ static void axp173_init_enabled_adcs(void)
/* Read enabled ADCs from the hardware */
uint8_t regs[2];
- int rc = i2c_reg_read(AXP173_BUS, AXP173_ADDR, 0x82, 2, &regs[0]);
+ int rc = i2c_reg_read(AXP173_BUS, AXP173_ADDR,
+ AXP173_REG_ADCENABLE1, 2, &regs[0]);
if(rc != I2C_STATUS_OK)
return;
@@ -68,7 +70,7 @@ static void axp173_init_enabled_adcs(void)
if(info[i].en_reg == 0xff)
continue;
- if(regs[info[i].en_reg - 0x82] & info[i].en_bit)
+ if(regs[info[i].en_reg - AXP173_REG_ADCENABLE1] & info[i].en_bit)
axp173.adc_enable |= 1 << i;
}
@@ -87,12 +89,16 @@ void axp173_init(void)
int bits = axp173.adc_enable;
bits |= (1 << ADC_DISCHARGE_CURRENT);
axp173_adc_set_enabled(bits);
+
+ /* Read the maximum charging current */
+ int value = i2c_reg_read1(AXP173_BUS, AXP173_ADDR, AXP173_REG_CHARGECONTROL1);
+ axp173.chargecurrent_setting = (value < 0) ? -1 : value;
}
/* TODO: this can STILL indicate some false positives! */
int axp173_battery_status(void)
{
- int r = i2c_reg_read1(AXP173_BUS, AXP173_ADDR, 0x00);
+ int r = i2c_reg_read1(AXP173_BUS, AXP173_ADDR, AXP173_REG_POWERSTATUS);
if(r >= 0) {
/* Charging bit indicates we're currently charging */
if((r & 0x04) != 0)
@@ -124,7 +130,7 @@ int axp173_input_status(void)
int input_status = AXP173_INPUT_BATTERY;
#endif
- int r = i2c_reg_read1(AXP173_BUS, AXP173_ADDR, 0x00);
+ int r = i2c_reg_read1(AXP173_BUS, AXP173_ADDR, AXP173_REG_POWERSTATUS);
if(r < 0)
return input_status;
@@ -138,7 +144,7 @@ int axp173_input_status(void)
#ifdef HAVE_BATTERY_SWITCH
/* Check for battery presence if target defines it as removable */
- r = i2c_reg_read1(AXP173_BUS, AXP173_ADDR, 0x01);
+ r = i2c_reg_read1(AXP173_BUS, AXP173_ADDR, AXP173_REG_CHARGESTATUS);
if(r >= 0 && (r & 0x20) != 0)
input_status |= AXP173_INPUT_BATTERY;
#endif
@@ -251,13 +257,13 @@ void axp173_adc_set_enabled(int adc_bits)
}
/* Update the configuration */
- i2c_reg_write(AXP173_BUS, AXP173_ADDR, 0x82, 2, &regs[0]);
+ i2c_reg_write(AXP173_BUS, AXP173_ADDR, AXP173_REG_ADCENABLE1, 2, &regs[0]);
axp173.adc_enable = adc_bits;
}
int axp173_adc_get_rate(void)
{
- int r = i2c_reg_read1(AXP173_BUS, AXP173_ADDR, 0x84);
+ int r = i2c_reg_read1(AXP173_BUS, AXP173_ADDR, AXP173_REG_ADCSAMPLERATE);
if(r < 0)
return AXP173_ADC_RATE_100HZ; /* an arbitrary value */
@@ -266,7 +272,7 @@ int axp173_adc_get_rate(void)
void axp173_adc_set_rate(int rate)
{
- i2c_reg_modify1(AXP173_BUS, AXP173_ADDR, 0x84,
+ i2c_reg_modify1(AXP173_BUS, AXP173_ADDR, AXP173_REG_ADCSAMPLERATE,
0xc0, (rate & 3) << 6, NULL);
}
@@ -278,7 +284,8 @@ static uint32_t axp173_cc_parse(const uint8_t* buf)
void axp173_cc_read(uint32_t* charge, uint32_t* discharge)
{
uint8_t buf[8];
- int rc = i2c_reg_read(AXP173_BUS, AXP173_ADDR, 0xb0, 8, &buf[0]);
+ int rc = i2c_reg_read(AXP173_BUS, AXP173_ADDR,
+ AXP173_REG_COULOMBCOUNTERBASE, 8, &buf[0]);
if(rc != I2C_STATUS_OK) {
if(charge)
*charge = 0;
@@ -295,19 +302,63 @@ void axp173_cc_read(uint32_t* charge, uint32_t* discharge)
void axp173_cc_clear(void)
{
- i2c_reg_setbit1(AXP173_BUS, AXP173_ADDR, 0xb8, 5, 1, NULL);
+ i2c_reg_setbit1(AXP173_BUS, AXP173_ADDR,
+ AXP173_REG_COULOMBCOUNTERCTRL, 5, 1, NULL);
}
void axp173_cc_enable(bool en)
{
- i2c_reg_setbit1(AXP173_BUS, AXP173_ADDR, 0xb8, 7, en ? 1 : 0, NULL);
+ i2c_reg_setbit1(AXP173_BUS, AXP173_ADDR,
+ AXP173_REG_COULOMBCOUNTERCTRL, 7, en ? 1 : 0, NULL);
+}
+
+static const int chargecurrent_tbl[] = {
+ 100, 190, 280, 360,
+ 450, 550, 630, 700,
+ 780, 880, 960, 1000,
+ 1080, 1160, 1240, 1320,
+};
+
+static const int chargecurrent_tblsz = sizeof(chargecurrent_tbl)/sizeof(int);
+
+void axp173_set_charge_current(int maxcurrent)
+{
+ /* Find the charge current just higher than maxcurrent */
+ int value = 0;
+ while(value < chargecurrent_tblsz &&
+ chargecurrent_tbl[value] <= maxcurrent)
+ ++value;
+
+ /* Select the next lower current, the greatest current <= maxcurrent */
+ if(value >= chargecurrent_tblsz)
+ value = chargecurrent_tblsz - 1;
+ else if(value > 0)
+ --value;
+
+ /* Don't issue i2c write if desired setting is already in use */
+ if(value == axp173.chargecurrent_setting)
+ return;
+
+ /* Update register */
+ i2c_reg_modify1(AXP173_BUS, AXP173_ADDR,
+ AXP173_REG_CHARGECONTROL1, 0x0f, value, NULL);
+ axp173.chargecurrent_setting = value;
+}
+
+int axp173_get_charge_current(void)
+{
+ if(axp173.chargecurrent_setting < 0)
+ return chargecurrent_tbl[0];
+ else
+ return chargecurrent_tbl[axp173.chargecurrent_setting];
}
#ifndef BOOTLOADER
#define AXP173_DEBUG_BATTERY_STATUS 0
#define AXP173_DEBUG_INPUT_STATUS 1
-#define AXP173_DEBUG_ADC_RATE 2
-#define AXP173_DEBUG_FIRST_ADC 3
+#define AXP173_DEBUG_CHARGE_CURRENT 2
+#define AXP173_DEBUG_ADC_RATE 3
+#define AXP173_DEBUG_FIRST_ADC 4
#define AXP173_DEBUG_ENTRIES (AXP173_DEBUG_FIRST_ADC + NUM_ADC_CHANNELS)
static int axp173_debug_menu_cb(int action, struct gui_synclist* lists)
@@ -377,6 +428,12 @@ static const char* axp173_debug_menu_get_name(int item, void* data,
return buf;
} break;
+ case AXP173_DEBUG_CHARGE_CURRENT: {
+ int current = axp173_get_charge_current();
+ snprintf(buf, buflen, "Max charge current: %d mA", current);
+ return buf;
+ } break;
+
case AXP173_DEBUG_ADC_RATE: {
int rate = 25 << axp173_adc_get_rate();
snprintf(buf, buflen, "ADC sample rate: %d Hz", rate);