summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/charger/isl923x.c43
-rw-r--r--driver/charger/isl923x.h10
-rw-r--r--include/charger.h20
3 files changed, 69 insertions, 4 deletions
diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c
index 16e7e2c66d..20dd90d378 100644
--- a/driver/charger/isl923x.c
+++ b/driver/charger/isl923x.c
@@ -97,6 +97,49 @@ int charger_get_input_current(int *input_current)
return EC_SUCCESS;
}
+#ifdef CONFIG_CHARGER_ISL9238
+int charger_enable_otg_power(int enabled)
+{
+ int rv, control1;
+
+ rv = raw_read16(ISL923X_REG_CONTROL1, &control1);
+ if (rv)
+ return rv;
+
+ if (enabled)
+ control1 |= ISL923X_C1_OTG;
+ else
+ control1 &= ~ISL923X_C1_OTG;
+
+ return raw_write16(ISL923X_REG_CONTROL1, control1);
+}
+
+/*
+ * TODO(b:67920792): OTG is not implemented for ISL9237 that has different
+ * register scale and range.
+ */
+int charger_set_otg_current_voltage(int output_current, int output_voltage)
+{
+ int rv;
+ uint16_t volt_reg = (output_voltage / ISL9238_OTG_VOLTAGE_STEP)
+ << ISL9238_OTG_VOLTAGE_SHIFT;
+ uint16_t current_reg = (output_current / ISL923X_OTG_CURRENT_STEP)
+ << ISL923X_OTG_CURRENT_SHIFT;
+
+ if (output_current < 0 || output_current > ISL923X_OTG_CURRENT_MAX ||
+ output_voltage > ISL9238_OTG_VOLTAGE_MAX)
+ return EC_ERROR_INVAL;
+
+ /* Set voltage. */
+ rv = raw_write16(ISL923X_REG_OTG_VOLTAGE, volt_reg);
+ if (rv)
+ return rv;
+
+ /* Set current. */
+ return raw_write16(ISL923X_REG_OTG_CURRENT, current_reg);
+}
+#endif /* CONFIG_CHARGER_ISL9238 */
+
int charger_manufacturer_id(int *id)
{
int rv;
diff --git a/driver/charger/isl923x.h b/driver/charger/isl923x.h
index 371227f902..1681944e64 100644
--- a/driver/charger/isl923x.h
+++ b/driver/charger/isl923x.h
@@ -211,10 +211,16 @@
#define ISL9238_C3_PSYS_GAIN (1 << 9)
/* OTG voltage limit in mV, current limit in mA */
-#define ISL923X_OTG_VOLTAGE_MIN 4864
-#define ISL923X_OTG_VOLTAGE_MAX 5376
+#define ISL9237_OTG_VOLTAGE_MIN 4864
+#define ISL9237_OTG_VOLTAGE_MAX 5376
+#define ISL9238_OTG_VOLTAGE_MAX 27456
#define ISL923X_OTG_CURRENT_MAX 4096
+#define ISL9238_OTG_VOLTAGE_STEP 12
+#define ISL9238_OTG_VOLTAGE_SHIFT 3
+#define ISL923X_OTG_CURRENT_STEP 128
+#define ISL923X_OTG_CURRENT_SHIFT 7
+
/* Info register fields */
#define ISL9237_INFO_PROG_RESISTOR_MASK 0xf
#define ISL923X_INFO_TRICKLE_ACTIVE_MASK (1 << 4)
diff --git a/include/charger.h b/include/charger.h
index a9f4f41fbd..16f7c3cbd0 100644
--- a/include/charger.h
+++ b/include/charger.h
@@ -65,12 +65,28 @@ int charger_get_status(int *status);
int charger_set_mode(int mode);
/**
- * For chargers that are able to supply 5V output power for OTG dongle, this
- * function enables or disables 5V power output.
+ * For chargers that are able to supply output power for OTG dongle, this
+ * function enables or disables power output.
*/
int charger_enable_otg_power(int enabled);
/**
+ * Sets OTG current limit and voltage (independent of whether OTG power is
+ * currently enabled).
+ *
+ * Depending on the charger and use case, one needs to be careful about
+ * changing the current/voltage while OTG power is enabled, and it might be wise
+ * to reset the value before enabling OTG power to ensure one does not provide
+ * excessive voltage to a device.
+ *
+ * @param output_current Requested current limit in mA.
+ * @param output_voltage Requested voltage in mV.
+ *
+ * @return EC_SUCCESS on success, an error otherwise.
+ */
+int charger_set_otg_current_voltage(int output_current, int output_voltage);
+
+/**
* Return the closest match the charger can supply to the requested current.
*
* @param current Requested current in mA.