34#include <sys/module.h>
35#include <sys/callout.h>
39#include <sys/kernel.h>
40#include <sys/reboot.h>
42#include <sys/sysctl.h>
43#include <sys/limits.h>
45#include <machine/bus.h>
46#include <machine/md_var.h>
51#include <dev/ofw/openfirm.h>
52#include <dev/ofw/ofw_bus.h>
53#include <powerpc/powermac/powermac_thermal.h>
57#define AD7417_TEMP 0x00
58#define AD7417_CONFIG 0x01
59#define AD7417_ADC 0x04
60#define AD7417_CONFIG2 0x05
61#define AD7417_CONFMASK 0xe0
132 unsigned char buf[4];
141 memcpy(
buf + 1, buff,
len);
149 device_printf(
dev,
"iicbus write failed\n");
152 pause(
"ad7417_write", hz);
177 device_printf(
dev,
"iicbus read failed\n");
180 pause(
"ad7417_read_1", hz);
205 device_printf(
dev,
"iicbus read failed\n");
208 pause(
"ad7417_read_2", hz);
236 in->
val = *((uint16_t*)
buf);
240 device_printf(
dev,
"iicbus write/read failed\n");
243 pause(
"ad7417_write_read", hz);
254 sc = device_get_softc(
dev);
283 const char *name, *compatible;
286 name = ofw_bus_get_name(
dev);
287 compatible = ofw_bus_get_compat(
dev);
292 if (strcmp(name,
"supply-monitor") != 0 ||
293 strcmp(compatible,
"ad7417") != 0)
296 sc = device_get_softc(
dev);
300 device_set_desc(
dev,
"Supply-Monitor AD7417");
312 phandle_t child, node;
317 int i = 0, j,
len = 0, prop_len, prev_len = 0;
319 sc = device_get_softc(
dev);
321 child = ofw_bus_get_node(
dev);
324 prop_len = OF_getprop(child,
"hwsensor-location", location,
326 while (
len < prop_len) {
329 prev_len = strlen(location +
len) + 1;
340 prop_len = OF_getprop(child,
"hwsensor-type", type,
sizeof(type));
341 while (
len < prop_len) {
342 if (strcmp(type +
len,
"temperature") == 0)
346 prev_len = strlen(type +
len) + 1;
352 prop_len = OF_getprop(child,
"hwsensor-id",
id,
sizeof(
id));
353 for (j = 0; j < i; j++)
357 prop_len = OF_getprop(child,
"hwsensor-zone",
id,
sizeof(
id));
358 for (j = 0; j < i; j++)
367 for (node = OF_child(child); node != 0; node = OF_peer(node)) {
369 OF_getprop(node,
"location", location,
sizeof(location));
375 for (j = 0; j < i; j++) {
407 struct sysctl_oid *oid, *sensroot_oid;
408 struct sysctl_ctx_list *ctx;
409 char sysctl_name[32];
414 sc = device_get_softc(
dev);
424 device_printf(
dev,
"WARNING: No AD7417 sensors detected!\n");
427 M_AD7417, M_WAITOK | M_ZERO);
429 ctx = device_get_sysctl_ctx(
dev);
430 sensroot_oid = SYSCTL_ADD_NODE(ctx,
431 SYSCTL_CHILDREN(device_get_sysctl_tree(
dev)), OID_AUTO,
"sensor",
432 CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"AD7417 Sensor Information");
442 if (isspace(sysctl_name[j]))
443 sysctl_name[j] =
'_';
447 oid = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(sensroot_oid),
448 OID_AUTO, sysctl_name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
449 "Sensor Information");
453 desc =
"sensor unit (C)";
456 desc =
"sensor unit (mV)";
459 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
460 unit, CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
467 device_printf(
dev,
"Sensors\n");
469 device_printf(
dev,
"Location: %s ID: %d type: %d\n",
496 *temp = (((int16_t)(
read & 0xffc0)) >> 6) * 25 / 10;
522 *value = ((uint32_t)
data.val) >> 6;
530 static int eeprom_read = 0;
531 static cell_t eeprom[2][40];
532 phandle_t eeprom_node;
533 int rawval, diode_slope, diode_offset;
537 eeprom_node = OF_finddevice(
"/u3/i2c/cpuid@a0");
538 OF_getprop(eeprom_node,
"cpuid", eeprom[0],
sizeof(eeprom[0]));
539 eeprom_node = OF_finddevice(
"/u3/i2c/cpuid@a2");
540 OF_getprop(eeprom_node,
"cpuid", eeprom[1],
sizeof(eeprom[1]));
548 if (strstr(sens->
therm.name,
"CPU B") != NULL) {
549 diode_slope = eeprom[1][0x11] >> 16;
550 diode_offset = (int16_t)(eeprom[1][0x11] & 0xffff) << 12;
552 diode_slope = eeprom[0][0x11] >> 16;
553 diode_offset = (int16_t)(eeprom[0][0x11] & 0xffff) << 12;
556 temp = (rawval*diode_slope + diode_offset) >> 2;
557 temp = (10*(temp >> 16)) + ((10*(temp & 0xffff)) >> 16);
559 return (temp + ZERO_C_TO_K);
569 sc = device_get_softc(sens->
dev);
605 sc = device_get_softc(sens->
dev);
612 if (sens->
type == ADC7417_TEMP_SENSOR) {
632 sc = device_get_softc(
dev);
639 error = sysctl_handle_int(oidp, &value, 0, req);
static int ad7417_probe(device_t)
static int ad7417_write(device_t dev, uint32_t addr, uint8_t reg, uint8_t *buf, int len)
static int ad7417_read_1(device_t dev, uint32_t addr, uint8_t reg, uint8_t *data)
static int ad7417_attach(device_t)
static int ad7417_get_adc(device_t dev, uint32_t addr, unsigned int *value, uint8_t chan)
static MALLOC_DEFINE(M_AD7417, "ad7417", "Supply-Monitor AD7417")
static int ad7417_get_temp(device_t dev, uint32_t addr, int *temp)
static int ad7417_init_adc(device_t dev, uint32_t addr)
static int ad7417_sensor_read(struct ad7417_sensor *sens)
static device_method_t ad7417_methods[]
static driver_t ad7417_driver
static int ad7417_sensor_sysctl(SYSCTL_HANDLER_ARGS)
static int ad7417_read_2(device_t dev, uint32_t addr, uint8_t reg, uint16_t *data)
static int ad7417_fill_sensor_prop(device_t dev)
static int ad7417_diode_read(struct ad7417_sensor *sens)
static int ad7417_write_read(device_t dev, uint32_t addr, struct write_data out, struct read_data *in)
DRIVER_MODULE(ad7417, iicbus, ad7417_driver, ad7417_devclass, 0, 0)
static devclass_t ad7417_devclass
static int ad7417_adc_read(struct ad7417_sensor *sens)
int iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs)
enum ad7417_sensor::@0 type
struct ad7417_sensor * sc_sensors