Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm/allwinner/axp209.c
Show All 35 Lines | |||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/clock.h> | #include <sys/clock.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/reboot.h> | #include <sys/reboot.h> | ||||
#include <sys/resource.h> | #include <sys/resource.h> | ||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include <sys/sysctl.h> | |||||
#include <dev/iicbus/iicbus.h> | #include <dev/iicbus/iicbus.h> | ||||
#include <dev/iicbus/iiconf.h> | #include <dev/iicbus/iiconf.h> | ||||
#include <dev/ofw/openfirm.h> | #include <dev/ofw/openfirm.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_bus_subr.h> | #include <dev/ofw/ofw_bus_subr.h> | ||||
#include "iicbus_if.h" | #include "iicbus_if.h" | ||||
/* Power State Register */ | /* Power State Register */ | ||||
#define AXP209_PSR 0x00 | #define AXP209_PSR 0x00 | ||||
#define AXP209_PSR_ACIN 0x80 | #define AXP209_PSR_ACIN 0x80 | ||||
#define AXP209_PSR_ACIN_SHIFT 7 | #define AXP209_PSR_ACIN_SHIFT 7 | ||||
#define AXP209_PSR_VBUS 0x20 | #define AXP209_PSR_VBUS 0x20 | ||||
#define AXP209_PSR_VBUS_SHIFT 5 | #define AXP209_PSR_VBUS_SHIFT 5 | ||||
/* Shutdown and battery control */ | /* Shutdown and battery control */ | ||||
#define AXP209_SHUTBAT 0x32 | #define AXP209_SHUTBAT 0x32 | ||||
#define AXP209_SHUTBAT_SHUTDOWN 0x80 | #define AXP209_SHUTBAT_SHUTDOWN 0x80 | ||||
/* Temperature monitor */ | |||||
#define AXP209_TEMPMON 0x5e | |||||
#define AXP209_TEMPMON_H(a) ((a) << 4) | |||||
#define AXP209_TEMPMON_L(a) ((a) & 0xf) | |||||
#define AXP209_TEMPMON_MIN 1447 /* -144.7C */ | |||||
#define AXP209_0C_TO_K 2732 | |||||
struct axp209_softc { | struct axp209_softc { | ||||
uint32_t addr; | uint32_t addr; | ||||
struct intr_config_hook enum_hook; | struct intr_config_hook enum_hook; | ||||
}; | }; | ||||
enum axp209_sensor { | |||||
AXP209_TEMP | |||||
}; | |||||
static int | static int | ||||
axp209_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size) | axp209_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size) | ||||
{ | { | ||||
struct axp209_softc *sc = device_get_softc(dev); | struct axp209_softc *sc = device_get_softc(dev); | ||||
struct iic_msg msg[2]; | struct iic_msg msg[2]; | ||||
msg[0].slave = sc->addr; | msg[0].slave = sc->addr; | ||||
msg[0].flags = IIC_M_WR; | msg[0].flags = IIC_M_WR; | ||||
Show All 21 Lines | axp209_write(device_t dev, uint8_t reg, uint8_t data) | ||||
msg.slave = sc->addr; | msg.slave = sc->addr; | ||||
msg.flags = IIC_M_WR; | msg.flags = IIC_M_WR; | ||||
msg.len = 2; | msg.len = 2; | ||||
msg.buf = buffer; | msg.buf = buffer; | ||||
return (iicbus_transfer(dev, &msg, 1)); | return (iicbus_transfer(dev, &msg, 1)); | ||||
} | } | ||||
static int | |||||
axp209_sysctl(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
device_t dev = arg1; | |||||
enum axp209_sensor sensor = arg2; | |||||
uint8_t data[2]; | |||||
int val, error; | |||||
if (sensor != AXP209_TEMP) | |||||
return (ENOENT); | |||||
error = axp209_read(dev, AXP209_TEMPMON, data, 2); | |||||
if (error != 0) | |||||
return (error); | |||||
/* Temperature is between -144.7C and 264.8C, step +0.1C */ | |||||
val = (AXP209_TEMPMON_H(data[0]) | AXP209_TEMPMON_L(data[1])) - | |||||
AXP209_TEMPMON_MIN + AXP209_0C_TO_K; | |||||
return sysctl_handle_opaque(oidp, &val, sizeof(val), req); | |||||
} | |||||
static void | static void | ||||
axp209_shutdown(void *devp, int howto) | axp209_shutdown(void *devp, int howto) | ||||
{ | { | ||||
device_t dev; | device_t dev; | ||||
if (!(howto & RB_POWEROFF)) | if (!(howto & RB_POWEROFF)) | ||||
return; | return; | ||||
dev = (device_t)devp; | dev = (device_t)devp; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | pwr_src = ((data & AXP209_PSR_ACIN) >> AXP209_PSR_ACIN_SHIFT) | | ||||
((data & AXP209_PSR_VBUS) >> (AXP209_PSR_VBUS_SHIFT - 1)); | ((data & AXP209_PSR_VBUS) >> (AXP209_PSR_VBUS_SHIFT - 1)); | ||||
device_printf(dev, "AXP209 Powered by %s\n", | device_printf(dev, "AXP209 Powered by %s\n", | ||||
pwr_name[pwr_src]); | pwr_name[pwr_src]); | ||||
} | } | ||||
EVENTHANDLER_REGISTER(shutdown_final, axp209_shutdown, dev, | EVENTHANDLER_REGISTER(shutdown_final, axp209_shutdown, dev, | ||||
SHUTDOWN_PRI_LAST); | SHUTDOWN_PRI_LAST); | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), | |||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | |||||
OID_AUTO, "temp", | |||||
CTLTYPE_INT | CTLFLAG_RD, | |||||
dev, AXP209_TEMP, axp209_sysctl, "IK", "Internal temperature"); | |||||
return (0); | return (0); | ||||
} | } | ||||
static device_method_t axp209_methods[] = { | static device_method_t axp209_methods[] = { | ||||
DEVMETHOD(device_probe, axp209_probe), | DEVMETHOD(device_probe, axp209_probe), | ||||
DEVMETHOD(device_attach, axp209_attach), | DEVMETHOD(device_attach, axp209_attach), | ||||
{0, 0}, | {0, 0}, | ||||
Show All 13 Lines |