Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/i2c Use IRQs to update status whenever ...
details: https://anonhg.NetBSD.org/src/rev/9b7eb01d0356
branches: trunk
changeset: 319009:9b7eb01d0356
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun May 13 11:13:02 2018 +0000
description:
Use IRQs to update status whenever we can. Reduces the amount of work that
needs to be done whenever sysmon_envsys refreshes sensors.
diffstat:
sys/dev/i2c/axppmic.c | 146 +++++++++++++++++++++++++++++++++----------------
1 files changed, 98 insertions(+), 48 deletions(-)
diffs (246 lines):
diff -r 2fa493abb141 -r 9b7eb01d0356 sys/dev/i2c/axppmic.c
--- a/sys/dev/i2c/axppmic.c Sun May 13 01:01:37 2018 +0000
+++ b/sys/dev/i2c/axppmic.c Sun May 13 11:13:02 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: axppmic.c,v 1.7 2018/05/12 01:31:07 jmcneill Exp $ */
+/* $NetBSD: axppmic.c,v 1.8 2018/05/13 11:13:02 jmcneill Exp $ */
/*-
* Copyright (c) 2014-2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: axppmic.c,v 1.7 2018/05/12 01:31:07 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: axppmic.c,v 1.8 2018/05/13 11:13:02 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -177,6 +177,14 @@
0x11, __BIT(6), 0x26, __BITS(4,0)),
};
+struct axppmic_irq {
+ u_int reg;
+ uint8_t mask;
+};
+
+#define AXPPMIC_IRQ(_reg, _mask) \
+ { .reg = (_reg), .mask = (_mask) }
+
struct axppmic_config {
const char *name;
const struct axppmic_ctrl *controls;
@@ -184,8 +192,12 @@
u_int irq_regs;
bool has_battery;
bool has_fuel_gauge;
- u_int poklirq_reg;
- uint8_t poklirq_mask;
+ struct axppmic_irq poklirq;
+ struct axppmic_irq acinirq;
+ struct axppmic_irq vbusirq;
+ struct axppmic_irq battirq;
+ struct axppmic_irq chargeirq;
+ struct axppmic_irq chargestirq;
};
enum axppmic_sensor {
@@ -204,12 +216,7 @@
i2c_addr_t sc_addr;
int sc_phandle;
- bool sc_has_battery;
- bool sc_has_fuel_gauge;
- u_int sc_poklirq_reg;
- uint8_t sc_poklirq_mask;
-
- u_int sc_irq_regs;
+ const struct axppmic_config *sc_conf;
struct sysmon_pswitch sc_smpsw;
@@ -242,8 +249,12 @@
.irq_regs = 6,
.has_battery = true,
.has_fuel_gauge = true,
- .poklirq_reg = 5,
- .poklirq_mask = __BIT(3),
+ .poklirq = AXPPMIC_IRQ(5, __BIT(3)),
+ .acinirq = AXPPMIC_IRQ(1, __BITS(6,5)),
+ .vbusirq = AXPPMIC_IRQ(1, __BITS(3,2)),
+ .battirq = AXPPMIC_IRQ(2, __BITS(7,6)),
+ .chargeirq = AXPPMIC_IRQ(2, __BITS(3,2)),
+ .chargestirq = AXPPMIC_IRQ(4, __BITS(1,0)),
};
static const struct axppmic_config axp805_config = {
@@ -251,8 +262,7 @@
.controls = axp805_ctrls,
.ncontrols = __arraycount(axp805_ctrls),
.irq_regs = 2,
- .poklirq_reg = 2,
- .poklirq_mask = __BIT(0),
+ .poklirq = AXPPMIC_IRQ(2, __BIT(0)),
};
static const struct of_compat_data compat_data[] = {
@@ -366,31 +376,8 @@
sysmon_pswitch_event(&sc->sc_smpsw, PSWITCH_EVENT_PRESSED);
}
-static int
-axppmic_intr(void *priv)
-{
- struct axppmic_softc *sc = priv;
- const int flags = I2C_F_POLL;
- u_int n;
- uint8_t stat;
-
- iic_acquire_bus(sc->sc_i2c, flags);
- for (n = 1; n <= sc->sc_irq_regs; n++) {
- if (axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_IRQ_STATUS_REG(n), &stat, flags) == 0) {
- if (n == sc->sc_poklirq_reg && (stat & sc->sc_poklirq_mask) != 0)
- sysmon_task_queue_sched(0, axppmic_task_shut, sc);
-
- axppmic_write(sc->sc_i2c, sc->sc_addr,
- AXP_IRQ_STATUS_REG(sc->sc_poklirq_reg), stat, flags);
- }
- }
- iic_release_bus(sc->sc_i2c, flags);
-
- return 1;
-}
-
static void
-axppmic_sensor_refresh(struct sysmon_envsys *sme, envsys_data_t *e)
+axppmic_sensor_update(struct sysmon_envsys *sme, envsys_data_t *e)
{
struct axppmic_softc *sc = sme->sme_cookie;
const int flags = I2C_F_POLL;
@@ -398,7 +385,6 @@
e->state = ENVSYS_SINVALID;
- iic_acquire_bus(sc->sc_i2c, flags);
switch (e->private) {
case AXP_SENSOR_ACIN_PRESENT:
if (axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_POWER_SOURCE_REG, &val, flags) == 0) {
@@ -456,7 +442,65 @@
}
break;
}
+}
+
+static void
+axppmic_sensor_refresh(struct sysmon_envsys *sme, envsys_data_t *e)
+{
+ struct axppmic_softc *sc = sme->sme_cookie;
+ const int flags = I2C_F_POLL;
+
+ switch (e->private) {
+ case AXP_SENSOR_BATT_CAPACITY:
+ /* Always update battery capacity (fuel gauge) */
+ iic_acquire_bus(sc->sc_i2c, flags);
+ axppmic_sensor_update(sme, e);
+ iic_release_bus(sc->sc_i2c, flags);
+ break;
+ default:
+ /* Refresh if the sensor is not in valid state */
+ if (e->state != ENVSYS_SVALID) {
+ iic_acquire_bus(sc->sc_i2c, flags);
+ axppmic_sensor_update(sme, e);
+ iic_release_bus(sc->sc_i2c, flags);
+ }
+ break;
+ }
+}
+
+static int
+axppmic_intr(void *priv)
+{
+ struct axppmic_softc *sc = priv;
+ const struct axppmic_config *c = sc->sc_conf;
+ const int flags = I2C_F_POLL;
+ uint8_t stat;
+ u_int n;
+
+ iic_acquire_bus(sc->sc_i2c, flags);
+ for (n = 1; n <= c->irq_regs; n++) {
+ if (axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_IRQ_STATUS_REG(n), &stat, flags) == 0) {
+ if (n == c->poklirq.reg && (stat & c->poklirq.mask) != 0)
+ sysmon_task_queue_sched(0, axppmic_task_shut, sc);
+ if (n == c->acinirq.reg && (stat & c->acinirq.mask) != 0)
+ axppmic_sensor_update(sc->sc_sme, &sc->sc_sensor[AXP_SENSOR_ACIN_PRESENT]);
+ if (n == c->vbusirq.reg && (stat & c->vbusirq.mask) != 0)
+ axppmic_sensor_update(sc->sc_sme, &sc->sc_sensor[AXP_SENSOR_VBUS_PRESENT]);
+ if (n == c->battirq.reg && (stat & c->battirq.mask) != 0)
+ axppmic_sensor_update(sc->sc_sme, &sc->sc_sensor[AXP_SENSOR_BATT_PRESENT]);
+ if (n == c->chargeirq.reg && (stat & c->chargeirq.mask) != 0)
+ axppmic_sensor_update(sc->sc_sme, &sc->sc_sensor[AXP_SENSOR_BATT_CHARGING]);
+ if (n == c->chargestirq.reg && (stat & c->chargestirq.mask) != 0)
+ axppmic_sensor_update(sc->sc_sme, &sc->sc_sensor[AXP_SENSOR_BATT_CHARGE_STATE]);
+
+ if (stat != 0)
+ axppmic_write(sc->sc_i2c, sc->sc_addr,
+ AXP_IRQ_STATUS_REG(n), stat, flags);
+ }
+ }
iic_release_bus(sc->sc_i2c, flags);
+
+ return 1;
}
static void
@@ -515,7 +559,7 @@
strlcpy(e->desc, "charge state", sizeof(e->desc));
sysmon_envsys_sensor_attach(sc->sc_sme, e);
- if (sc->sc_has_fuel_gauge) {
+ if (sc->sc_conf->has_fuel_gauge) {
e = &sc->sc_sensor[AXP_SENSOR_BATT_CAPACITY];
e->private = AXP_SENSOR_BATT_CAPACITY;
e->units = ENVSYS_INTEGER;
@@ -529,7 +573,7 @@
static void
axppmic_attach_sensors(struct axppmic_softc *sc)
{
- if (sc->sc_has_battery) {
+ if (sc->sc_conf->has_battery) {
sc->sc_sme = sysmon_envsys_create();
sc->sc_sme->sme_name = device_xname(sc->sc_dev);
sc->sc_sme->sme_cookie = sc;
@@ -577,11 +621,7 @@
sc->sc_i2c = ia->ia_tag;
sc->sc_addr = ia->ia_addr;
sc->sc_phandle = ia->ia_cookie;
- sc->sc_has_battery = c->has_battery;
- sc->sc_has_fuel_gauge = c->has_fuel_gauge;
- sc->sc_irq_regs = c->irq_regs;
- sc->sc_poklirq_reg = c->poklirq_reg;
- sc->sc_poklirq_mask = c->poklirq_mask;
+ sc->sc_conf = c;
aprint_naive("\n");
aprint_normal(": %s\n", c->name);
@@ -593,8 +633,18 @@
iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
for (i = 1; i <= c->irq_regs; i++) {
irq_mask = 0;
- if (i == c->poklirq_reg)
- irq_mask |= c->poklirq_mask;
+ if (i == c->poklirq.reg)
+ irq_mask |= c->poklirq.mask;
+ if (i == c->acinirq.reg)
+ irq_mask |= c->acinirq.mask;
+ if (i == c->vbusirq.reg)
+ irq_mask |= c->vbusirq.mask;
+ if (i == c->battirq.reg)
+ irq_mask |= c->battirq.mask;
+ if (i == c->chargeirq.reg)
+ irq_mask |= c->chargeirq.mask;
+ if (i == c->chargestirq.reg)
+ irq_mask |= c->chargestirq.mask;
axppmic_write(sc->sc_i2c, sc->sc_addr, AXP_IRQ_ENABLE_REG(i), irq_mask, I2C_F_POLL);
}
iic_release_bus(sc->sc_i2c, I2C_F_POLL);
Home |
Main Index |
Thread Index |
Old Index