Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/i2c Monitor for power source changes and report with...
details: https://anonhg.NetBSD.org/src/rev/8175a0e0c0b8
branches: trunk
changeset: 789012:8175a0e0c0b8
user: rkujawa <rkujawa%NetBSD.org@localhost>
date: Sun Aug 04 00:24:28 2013 +0000
description:
Monitor for power source changes and report with appropriate information in
dmesg, a pmf event and sysmon_pswitch event.
diffstat:
sys/dev/i2c/tps65217pmic.c | 161 ++++++++++++++++++++++++++++++++++++-----
sys/dev/i2c/tps65217pmicreg.h | 10 ++-
2 files changed, 150 insertions(+), 21 deletions(-)
diffs (263 lines):
diff -r d6915b02ede9 -r 8175a0e0c0b8 sys/dev/i2c/tps65217pmic.c
--- a/sys/dev/i2c/tps65217pmic.c Sun Aug 04 00:21:56 2013 +0000
+++ b/sys/dev/i2c/tps65217pmic.c Sun Aug 04 00:24:28 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tps65217pmic.c,v 1.5 2013/05/16 21:25:27 rkujawa Exp $ */
+/* $NetBSD: tps65217pmic.c,v 1.6 2013/08/04 00:24:28 rkujawa Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.5 2013/05/16 21:25:27 rkujawa Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.6 2013/08/04 00:24:28 rkujawa Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -51,6 +51,9 @@
#include <dev/i2c/tps65217pmicreg.h>
#define NTPS_REG 7
+#define SNUM_REGS NTPS_REG-1
+#define SNUM_USBSTATUS NTPS_REG
+#define SNUM_ACSTATUS NTPS_REG+1
struct tps65217pmic_softc {
device_t sc_dev;
@@ -61,10 +64,22 @@
uint8_t sc_version;
uint8_t sc_revision;
- /* envsys(4) stuff */
+ kmutex_t sc_lock;
+
+ bool sc_acstatus;
+ bool sc_usbstatus;
+ bool sc_acenabled;
+ bool sc_usbenabled;
+
+ callout_t sc_powerpollco;
+
+ /* sysmon(4) stuff */
struct sysmon_envsys *sc_sme;
- envsys_data_t sc_sensor[NTPS_REG];
- kmutex_t sc_lock;
+ envsys_data_t sc_regsensor[NTPS_REG];
+ envsys_data_t sc_acsensor;
+ envsys_data_t sc_usbsensor;
+
+ struct sysmon_pswitch sc_smpsw;
};
/* Voltage regulators */
@@ -117,7 +132,7 @@
static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
-static void tps65217pmic_refresh(struct tps65217pmic_softc *);
+static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *);
static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
@@ -133,6 +148,9 @@
static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
+static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *);
+static void tps65217pmic_power_monitor(void *);
+
CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
@@ -301,16 +319,94 @@
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
- tps65217pmic_refresh(sc);
+ sc->sc_smpsw.smpsw_name = device_xname(self);
+ sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER;
+ sysmon_pswitch_register(&sc->sc_smpsw);
+
+ tps65217pmic_reg_refresh(sc);
tps65217pmic_print_ppath(sc);
tps65217pmic_print_ldos(sc);
+ tps65217pmic_power_monitor_init(sc);
+
tps65217pmic_envsys_register(sc);
}
static void
-tps65217pmic_refresh(struct tps65217pmic_softc *sc)
+tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
+{
+ uint8_t intr, intrmask, status, ppath;
+
+ intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM |
+ TPS65217PMIC_INT_PBM;
+
+ status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
+ ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
+ /* acknowledge and disregard whatever interrupt was generated earlier */
+ intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT);
+
+ sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
+ sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR;
+ sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN;
+ sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN;
+
+ if (intr & intrmask)
+ aprint_normal_dev(sc->sc_dev,
+ "WARNING: hardware interrupt enabled but not supported");
+
+ /* set up callout to poll for power source changes */
+ callout_init(&sc->sc_powerpollco, 0);
+ callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc);
+
+ callout_schedule(&sc->sc_powerpollco, hz);
+}
+
+static void
+tps65217pmic_power_monitor(void *aux)
+{
+ struct tps65217pmic_softc *sc;
+ uint8_t status;
+ bool usbstatus, acstatus;
+
+ sc = aux;
+
+ mutex_enter(&sc->sc_lock);
+
+ status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
+ usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
+ acstatus = status & TPS65217PMIC_STATUS_ACPWR;
+
+ if (usbstatus != sc->sc_usbstatus) {
+ sc->sc_usbstatus = usbstatus;
+ pmf_event_inject(NULL, PMFE_POWER_CHANGED);
+ if (usbstatus)
+ aprint_normal_dev(sc->sc_dev,
+ "USB power source connected\n");
+ else
+ aprint_normal_dev(sc->sc_dev,
+ "USB power source disconnected\n");
+ }
+
+ if (acstatus != sc->sc_acstatus) {
+ sc->sc_acstatus = acstatus;
+ pmf_event_inject(NULL, PMFE_POWER_CHANGED);
+ if (acstatus) {
+ sysmon_pswitch_event(&sc->sc_smpsw,
+ PSWITCH_EVENT_PRESSED);
+ } else {
+ sysmon_pswitch_event(&sc->sc_smpsw,
+ PSWITCH_EVENT_RELEASED);
+ }
+ }
+
+ mutex_exit(&sc->sc_lock);
+
+ callout_schedule(&sc->sc_powerpollco, hz);
+}
+
+static void
+tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc)
{
int i;
struct tps_reg_param *c_reg;
@@ -518,19 +614,35 @@
sc->sc_sme = sysmon_envsys_create();
- /* iterate over all regulators and register them as sensors */
- for(i = 0; i < NTPS_REG; i++) {
+ /* iterate over all regulators and attach them as sensors */
+ for(i = 0; i <= SNUM_REGS; i++) {
/* set name */
- strlcpy(sc->sc_sensor[i].desc, tps_regulators[i].name,
- sizeof(sc->sc_sensor[i].desc));
- sc->sc_sensor[i].units = ENVSYS_SVOLTS_DC;
- sc->sc_sensor[i].state = ENVSYS_SINVALID;
+ strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name,
+ sizeof(sc->sc_regsensor[i].desc));
+ sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC;
+ sc->sc_regsensor[i].state = ENVSYS_SINVALID;
- if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[i]))
+ if (sysmon_envsys_sensor_attach(sc->sc_sme,
+ &sc->sc_regsensor[i]))
aprint_error_dev(sc->sc_dev,
- "error attaching sensor %d\n", i);
+ "error attaching regulator sensor %d\n", i);
}
+ /* attach power source indicators */
+ strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */
+ sc->sc_usbsensor.units = ENVSYS_INDICATOR;
+ sc->sc_usbsensor.state = ENVSYS_SINVALID;
+ if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor))
+ aprint_error_dev(sc->sc_dev,
+ "error attaching USB power source sensor\n");
+ strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */
+ sc->sc_acsensor.units = ENVSYS_INDICATOR;
+ sc->sc_acsensor.state = ENVSYS_SINVALID;
+ if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor))
+ aprint_error_dev(sc->sc_dev,
+ "error attaching AC power source sensor\n");
+
+ /* register everything in sysmon */
sc->sc_sme->sme_name = device_xname(sc->sc_dev);
sc->sc_sme->sme_cookie = sc;
sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
@@ -548,11 +660,20 @@
mutex_enter(&sc->sc_lock);
- tps65217pmic_refresh(sc);
+ tps65217pmic_reg_refresh(sc);
- /* TODO: handle special cases like LS, XADJ... */
- edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
- edata->state = ENVSYS_SVALID;
+ if (edata->sensor <= SNUM_REGS) {
+ /* TODO: handle special cases like LS, XADJ... */
+ edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
+ edata->state = ENVSYS_SVALID;
+ } else if (edata->sensor == SNUM_USBSTATUS) {
+ edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled;
+ edata->state = ENVSYS_SVALID;
+ } else if (edata->sensor == SNUM_ACSTATUS) {
+ edata->value_cur = sc->sc_acstatus && sc->sc_acenabled;
+ edata->state = ENVSYS_SVALID;
+ } else
+ aprint_error_dev(sc->sc_dev, "unknown sensor number\n");
mutex_exit(&sc->sc_lock);
}
diff -r d6915b02ede9 -r 8175a0e0c0b8 sys/dev/i2c/tps65217pmicreg.h
--- a/sys/dev/i2c/tps65217pmicreg.h Sun Aug 04 00:21:56 2013 +0000
+++ b/sys/dev/i2c/tps65217pmicreg.h Sun Aug 04 00:24:28 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tps65217pmicreg.h,v 1.5 2013/05/07 01:16:25 jakllsch Exp $ */
+/* $NetBSD: tps65217pmicreg.h,v 1.6 2013/08/04 00:24:28 rkujawa Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -59,6 +59,14 @@
#define TPS65217PMIC_PPATH_USB_EN __BIT(4)
#define TPS65217PMIC_PPATH_AC_EN __BIT(5)
+#define TPS65217PMIC_INT 0x02
+#define TPS65217PMIC_INT_USBI __BIT(0)
+#define TPS65217PMIC_INT_ACI __BIT(1)
+#define TPS65217PMIC_INT_PBI __BIT(2)
+#define TPS65217PMIC_INT_USBM __BIT(4)
+#define TPS65217PMIC_INT_ACM __BIT(5)
+#define TPS65217PMIC_INT_PBM __BIT(6)
+
#define TPS65217PMIC_WLEDCTRL1 0x07
#define TPS65217PMIC_WLEDCTRL1_FDIM __BITS(1,0)
#define TPS65217PMIC_WLEDCTRL1_FDIM_100Hz 0
Home |
Main Index |
Thread Index |
Old Index