Home | History | Annotate | Line # | Download | only in dev
smusat.c revision 1.2.4.2
      1      1.1  macallan /*-
      2      1.1  macallan  * Copyright (c) 2013 Phileas Fogg
      3      1.1  macallan  * All rights reserved.
      4      1.1  macallan  *
      5      1.1  macallan  * Redistribution and use in source and binary forms, with or without
      6      1.1  macallan  * modification, are permitted provided that the following conditions
      7      1.1  macallan  * are met:
      8      1.1  macallan  * 1. Redistributions of source code must retain the above copyright
      9      1.1  macallan  *    notice, this list of conditions and the following disclaimer.
     10      1.1  macallan  * 2. Redistributions in binary form must reproduce the above copyright
     11      1.1  macallan  *    notice, this list of conditions and the following disclaimer in the
     12      1.1  macallan  *    documentation and/or other materials provided with the distribution.
     13      1.1  macallan  *
     14      1.1  macallan  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     15      1.1  macallan  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     16      1.1  macallan  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     17      1.1  macallan  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     18      1.1  macallan  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     19      1.1  macallan  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     20      1.1  macallan  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     21      1.1  macallan  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     22      1.1  macallan  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     23      1.1  macallan  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     24      1.1  macallan  * POSSIBILITY OF SUCH DAMAGE.
     25      1.1  macallan  */
     26      1.1  macallan 
     27      1.1  macallan #include <sys/param.h>
     28      1.1  macallan #include <sys/systm.h>
     29      1.1  macallan #include <sys/kernel.h>
     30      1.1  macallan #include <sys/malloc.h>
     31      1.1  macallan #include <sys/device.h>
     32      1.1  macallan #include <sys/proc.h>
     33      1.1  macallan #include <sys/mutex.h>
     34      1.1  macallan #include <sys/time.h>
     35      1.1  macallan #include <sys/sysctl.h>
     36      1.1  macallan 
     37      1.1  macallan #include <machine/autoconf.h>
     38      1.1  macallan 
     39      1.1  macallan #include <dev/ofw/openfirm.h>
     40      1.1  macallan #include <dev/i2c/i2cvar.h>
     41      1.1  macallan #include <dev/sysmon/sysmonvar.h>
     42      1.1  macallan #include <dev/sysmon/sysmon_taskq.h>
     43      1.1  macallan 
     44      1.1  macallan #include <macppc/dev/smuiicvar.h>
     45      1.1  macallan 
     46      1.1  macallan #include "opt_smusat.h"
     47      1.1  macallan 
     48      1.2  macallan extern int smu_get_datablock(int, uint8_t *, size_t);
     49      1.2  macallan 
     50      1.1  macallan enum {
     51      1.1  macallan 	SMUSAT_SENSOR_TEMP,
     52      1.1  macallan 	SMUSAT_SENSOR_CURRENT,
     53      1.1  macallan 	SMUSAT_SENSOR_VOLTAGE,
     54      1.1  macallan 	SMUSAT_SENSOR_POWER,
     55      1.1  macallan };
     56      1.1  macallan 
     57      1.1  macallan struct smusat_softc;
     58      1.1  macallan 
     59      1.1  macallan struct smusat_sensor {
     60      1.1  macallan 	struct smusat_softc *sc;
     61      1.1  macallan 
     62      1.1  macallan 	char location[32];
     63      1.1  macallan 	int type;
     64      1.1  macallan 	int reg;
     65      1.1  macallan 	int zone;
     66      1.1  macallan 	int shift;
     67      1.2  macallan 	int offset;
     68      1.2  macallan 	int scale;
     69      1.1  macallan 	int current_value;
     70      1.1  macallan };
     71      1.1  macallan 
     72      1.1  macallan #define SMUSAT_MAX_SENSORS	16
     73      1.1  macallan #define SMUSAT_MAX_SME_SENSORS	SMUSAT_MAX_SENSORS
     74      1.1  macallan 
     75      1.1  macallan struct smusat_softc {
     76      1.1  macallan 	device_t sc_dev;
     77      1.1  macallan 	int sc_node;
     78      1.1  macallan 	i2c_addr_t sc_addr;
     79      1.2  macallan 	uint8_t sc_cache[16];
     80      1.2  macallan 	time_t sc_last_update;
     81      1.1  macallan 	struct i2c_controller *sc_i2c;
     82      1.1  macallan 	struct sysctlnode *sc_sysctl_me;
     83      1.1  macallan 
     84      1.1  macallan 	int sc_num_sensors;
     85      1.1  macallan 	struct smusat_sensor sc_sensors[SMUSAT_MAX_SENSORS];
     86      1.1  macallan 
     87      1.1  macallan 	struct sysmon_envsys *sc_sme;
     88      1.1  macallan 	envsys_data_t sc_sme_sensors[SMUSAT_MAX_SME_SENSORS];
     89      1.1  macallan };
     90      1.1  macallan 
     91      1.1  macallan #ifdef SMUSAT_DEBUG
     92      1.1  macallan #define DPRINTF printf
     93      1.1  macallan #else
     94      1.1  macallan #define DPRINTF while (0) printf
     95      1.1  macallan #endif
     96      1.1  macallan 
     97      1.1  macallan static int smusat_match(device_t, struct cfdata *, void *);
     98      1.1  macallan static void smusat_attach(device_t, device_t, void *);
     99      1.1  macallan static void smusat_setup_sme(struct smusat_softc *);
    100      1.1  macallan static void smusat_sme_refresh(struct sysmon_envsys *, envsys_data_t *);
    101      1.2  macallan static int smusat_sensors_update(struct smusat_softc *);
    102      1.1  macallan static int smusat_sensor_read(struct smusat_sensor *, int *);
    103      1.1  macallan static int smusat_sysctl_sensor_value(SYSCTLFN_ARGS);
    104      1.1  macallan 
    105      1.1  macallan CFATTACH_DECL_NEW(smusat, sizeof(struct smusat_softc),
    106      1.1  macallan     smusat_match, smusat_attach, NULL, NULL);
    107      1.1  macallan 
    108  1.2.4.1  pgoyette static const char * smusat_compats[] = {
    109  1.2.4.1  pgoyette 	"sat",
    110  1.2.4.1  pgoyette 	"smu-sat",
    111  1.2.4.1  pgoyette 	NULL
    112  1.2.4.1  pgoyette };
    113  1.2.4.1  pgoyette 
    114  1.2.4.2  pgoyette static const struct device_compatible_entry smusat_compat_data[] = {
    115  1.2.4.2  pgoyette 	DEVICE_COMPAT_ENTRY(smusat_compats),
    116  1.2.4.2  pgoyette 	DEVICE_COMPAT_TERMINATOR
    117  1.2.4.2  pgoyette };
    118  1.2.4.2  pgoyette 
    119      1.1  macallan static int
    120      1.1  macallan smusat_match(device_t parent, struct cfdata *cf, void *aux)
    121      1.1  macallan {
    122  1.2.4.1  pgoyette 	struct i2c_attach_args *ia = aux;
    123  1.2.4.2  pgoyette 	int match_result;
    124      1.1  macallan 
    125  1.2.4.2  pgoyette 	if (iic_use_direct_match(ia, cf, smusat_compat_data, &match_result))
    126  1.2.4.2  pgoyette 		return match_result;
    127  1.2.4.2  pgoyette 
    128  1.2.4.2  pgoyette 	if (ia->ia_addr == 0x58)
    129  1.2.4.2  pgoyette 		return I2C_MATCH_ADDRESS_ONLY;
    130  1.2.4.2  pgoyette 
    131  1.2.4.2  pgoyette 	return 0;
    132      1.1  macallan }
    133      1.1  macallan 
    134      1.1  macallan static void
    135      1.1  macallan smusat_attach(device_t parent, device_t self, void *aux)
    136      1.1  macallan {
    137  1.2.4.1  pgoyette 	struct i2c_attach_args *ia = aux;
    138      1.1  macallan 	struct smusat_softc *sc = device_private(self);
    139      1.1  macallan 	struct smusat_sensor *sensor;
    140      1.1  macallan 	struct sysctlnode *sysctl_sensors, *sysctl_sensor, *sysctl_node;
    141      1.1  macallan 	char type[32], sysctl_sensor_name[32];
    142      1.1  macallan 	int node, i, j;
    143      1.1  macallan 
    144      1.1  macallan 	sc->sc_dev = self;
    145  1.2.4.1  pgoyette 	sc->sc_node = ia->ia_cookie;
    146  1.2.4.1  pgoyette 	sc->sc_addr = ia->ia_addr;
    147  1.2.4.1  pgoyette 	sc->sc_i2c = ia->ia_tag;
    148      1.1  macallan 
    149      1.1  macallan 	sysctl_createv(NULL, 0, NULL, (void *) &sc->sc_sysctl_me,
    150      1.1  macallan 	    CTLFLAG_READWRITE,
    151      1.1  macallan 	   CTLTYPE_NODE, device_xname(sc->sc_dev), NULL,
    152      1.1  macallan 	    NULL, 0, NULL, 0,
    153      1.1  macallan 	    CTL_MACHDEP, CTL_CREATE, CTL_EOL);
    154      1.1  macallan 
    155      1.1  macallan 	for (node = OF_child(sc->sc_node);
    156      1.1  macallan 	    (node != 0) && (sc->sc_num_sensors < SMUSAT_MAX_SENSORS);
    157      1.1  macallan 	    node = OF_peer(node)) {
    158      1.1  macallan 		sensor = &sc->sc_sensors[sc->sc_num_sensors];
    159      1.1  macallan 		sensor->sc = sc;
    160      1.1  macallan 
    161      1.1  macallan 		memset(sensor->location, 0, sizeof(sensor->location));
    162      1.1  macallan 		OF_getprop(node, "location", sensor->location,
    163      1.1  macallan 		    sizeof(sensor->location));
    164      1.1  macallan 
    165      1.1  macallan 		if (OF_getprop(node, "reg", &sensor->reg,
    166      1.1  macallan 		        sizeof(sensor->reg)) <= 0)
    167      1.1  macallan 			continue;
    168      1.1  macallan 
    169      1.2  macallan 		if ((sensor->reg < 0x30) || (sensor->reg > 0x37))
    170      1.2  macallan 			continue;
    171      1.2  macallan 		sensor->reg -= 0x30;
    172      1.2  macallan 
    173      1.1  macallan 		if (OF_getprop(node, "zone", &sensor->zone,
    174      1.1  macallan 		        sizeof(sensor->zone)) <= 0)
    175      1.1  macallan 			continue;
    176      1.1  macallan 
    177      1.1  macallan 		memset(type, 0, sizeof(type));
    178      1.1  macallan 		OF_getprop(node, "device_type", type, sizeof(type));
    179      1.1  macallan 
    180      1.1  macallan 		if (strcmp(type, "temp-sensor") == 0) {
    181      1.1  macallan 			sensor->type = SMUSAT_SENSOR_TEMP;
    182      1.1  macallan 			sensor->shift = 10;
    183      1.1  macallan 		} else if (strcmp(type, "current-sensor") == 0) {
    184      1.1  macallan 			sensor->type = SMUSAT_SENSOR_CURRENT;
    185      1.1  macallan 			sensor->shift = 8;
    186      1.1  macallan 		} else if (strcmp(type, "voltage-sensor") == 0) {
    187      1.1  macallan 			sensor->type = SMUSAT_SENSOR_VOLTAGE;
    188      1.1  macallan 			sensor->shift = 4;
    189      1.1  macallan 		} else if (strcmp(type, "power-sensor") == 0) {
    190      1.1  macallan 			sensor->type = SMUSAT_SENSOR_POWER;
    191      1.1  macallan 			sensor->shift = 0;
    192      1.1  macallan 		}
    193      1.1  macallan 
    194      1.1  macallan 		DPRINTF("sensor: location %s reg %x zone %d type %s\n",
    195      1.1  macallan 		    sensor->location, sensor->reg, sensor->zone, type);
    196      1.1  macallan 
    197      1.1  macallan 		sc->sc_num_sensors++;
    198      1.1  macallan 	}
    199      1.1  macallan 
    200      1.1  macallan 	/* Create sysctl nodes for each sensor */
    201      1.1  macallan 
    202      1.1  macallan 	sysctl_createv(NULL, 0, NULL, (void *) &sysctl_sensors,
    203      1.1  macallan 	    CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
    204      1.1  macallan 	    CTLTYPE_NODE, "sensors", NULL,
    205      1.1  macallan 	    NULL, 0, NULL, 0,
    206      1.1  macallan 	    CTL_MACHDEP,
    207      1.1  macallan 	    sc->sc_sysctl_me->sysctl_num,
    208      1.1  macallan 	    CTL_CREATE, CTL_EOL);
    209      1.1  macallan 
    210      1.1  macallan 	for (i = 0; i < sc->sc_num_sensors; i++) {
    211      1.1  macallan 		sensor = &sc->sc_sensors[i];
    212      1.1  macallan 
    213      1.1  macallan 		for (j = 0; j < strlen(sensor->location); j++) {
    214      1.1  macallan 			sysctl_sensor_name[j] = tolower(sensor->location[j]);
    215      1.1  macallan 			if (sysctl_sensor_name[j] == ' ')
    216      1.1  macallan 				sysctl_sensor_name[j] = '_';
    217      1.1  macallan 		}
    218      1.1  macallan 		sysctl_sensor_name[j] = '\0';
    219      1.1  macallan 
    220      1.1  macallan 		sysctl_createv(NULL, 0, NULL, (void *) &sysctl_sensor,
    221      1.1  macallan 		    CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
    222      1.1  macallan 		    CTLTYPE_NODE, sysctl_sensor_name, "sensor information",
    223      1.1  macallan 		    NULL, 0, NULL, 0,
    224      1.1  macallan 		    CTL_MACHDEP,
    225      1.1  macallan 		    sc->sc_sysctl_me->sysctl_num,
    226      1.1  macallan 		    sysctl_sensors->sysctl_num,
    227      1.1  macallan 		    CTL_CREATE, CTL_EOL);
    228      1.1  macallan 
    229      1.1  macallan 		sysctl_createv(NULL, 0, NULL, (void *) &sysctl_node,
    230      1.1  macallan 		    CTLFLAG_READONLY | CTLFLAG_OWNDESC,
    231      1.1  macallan 		    CTLTYPE_INT, "zone", "sensor zone",
    232      1.1  macallan 		    NULL, 0, &sensor->zone, 0,
    233      1.1  macallan 		    CTL_MACHDEP,
    234      1.1  macallan 		    sc->sc_sysctl_me->sysctl_num,
    235      1.1  macallan 		    sysctl_sensors->sysctl_num,
    236      1.1  macallan 		    sysctl_sensor->sysctl_num,
    237      1.1  macallan 		    CTL_CREATE, CTL_EOL);
    238      1.1  macallan 
    239      1.1  macallan 		sysctl_createv(NULL, 0, NULL, (void *) &sysctl_node,
    240      1.1  macallan 		    CTLFLAG_READONLY | CTLFLAG_OWNDESC,
    241      1.1  macallan 		    CTLTYPE_INT, "value", "sensor current value",
    242      1.1  macallan 		    smusat_sysctl_sensor_value, 0, (void *) sensor, 0,
    243      1.1  macallan 		    CTL_MACHDEP,
    244      1.1  macallan 		    sc->sc_sysctl_me->sysctl_num,
    245      1.1  macallan 		    sysctl_sensors->sysctl_num,
    246      1.1  macallan 		    sysctl_sensor->sysctl_num,
    247      1.1  macallan 		    CTL_CREATE, CTL_EOL);
    248      1.1  macallan 	}
    249      1.1  macallan 
    250      1.1  macallan 	smusat_setup_sme(sc);
    251      1.1  macallan 
    252      1.1  macallan 	printf("\n");
    253      1.1  macallan }
    254      1.1  macallan 
    255      1.1  macallan static void
    256      1.1  macallan smusat_setup_sme(struct smusat_softc *sc)
    257      1.1  macallan {
    258      1.1  macallan 	struct smusat_sensor *sensor;
    259      1.1  macallan 	envsys_data_t *sme_sensor;
    260      1.1  macallan 	int i;
    261      1.1  macallan 
    262      1.1  macallan 	sc->sc_sme = sysmon_envsys_create();
    263      1.1  macallan 
    264      1.1  macallan 	for (i = 0; i < sc->sc_num_sensors; i++) {
    265      1.1  macallan 		sme_sensor = &sc->sc_sme_sensors[i];
    266      1.1  macallan 		sensor = &sc->sc_sensors[i];
    267      1.1  macallan 
    268      1.1  macallan 		switch (sensor->type) {
    269      1.1  macallan 		case SMUSAT_SENSOR_TEMP:
    270      1.1  macallan 			sme_sensor->units = ENVSYS_STEMP;
    271      1.1  macallan 		break;
    272      1.1  macallan 		case SMUSAT_SENSOR_CURRENT:
    273      1.1  macallan 			sme_sensor->units = ENVSYS_SAMPS;
    274      1.1  macallan 		break;
    275      1.1  macallan 		case SMUSAT_SENSOR_VOLTAGE:
    276      1.1  macallan 			sme_sensor->units = ENVSYS_SVOLTS_DC;
    277      1.1  macallan 		break;
    278      1.1  macallan 		case SMUSAT_SENSOR_POWER:
    279      1.1  macallan 			sme_sensor->units = ENVSYS_SWATTS;
    280      1.1  macallan 		break;
    281      1.1  macallan 		default:
    282      1.1  macallan 			sme_sensor->units = ENVSYS_INTEGER;
    283      1.1  macallan 		}
    284      1.1  macallan 
    285      1.1  macallan 		sme_sensor->state = ENVSYS_SINVALID;
    286      1.1  macallan 		snprintf(sme_sensor->desc, sizeof(sme_sensor->desc),
    287      1.1  macallan 		    "%s", sensor->location);
    288      1.1  macallan 
    289      1.1  macallan 		if (sysmon_envsys_sensor_attach(sc->sc_sme, sme_sensor)) {
    290      1.1  macallan 			sysmon_envsys_destroy(sc->sc_sme);
    291      1.1  macallan 			return;
    292      1.1  macallan 		}
    293      1.1  macallan 	}
    294      1.1  macallan 
    295      1.1  macallan 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    296      1.1  macallan 	sc->sc_sme->sme_cookie = sc;
    297      1.1  macallan 	sc->sc_sme->sme_refresh = smusat_sme_refresh;
    298      1.1  macallan 
    299      1.1  macallan 	if (sysmon_envsys_register(sc->sc_sme)) {
    300      1.1  macallan 		aprint_error_dev(sc->sc_dev,
    301      1.1  macallan 		    "unable to register with sysmon\n");
    302      1.1  macallan 		sysmon_envsys_destroy(sc->sc_sme);
    303      1.1  macallan 	}
    304      1.1  macallan }
    305      1.1  macallan 
    306      1.1  macallan static void
    307      1.1  macallan smusat_sme_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
    308      1.1  macallan {
    309      1.1  macallan 	struct smusat_softc *sc = sme->sme_cookie;
    310      1.1  macallan 	struct smusat_sensor *sensor;
    311      1.1  macallan 	int which = edata->sensor;
    312      1.1  macallan 	int ret;
    313      1.1  macallan 
    314      1.1  macallan 	edata->state = ENVSYS_SINVALID;
    315      1.1  macallan 
    316      1.1  macallan 	if (which < sc->sc_num_sensors) {
    317      1.1  macallan 		sensor = &sc->sc_sensors[which];
    318      1.1  macallan 
    319      1.2  macallan 		ret = smusat_sensor_read(sensor, NULL);
    320      1.1  macallan 		if (ret == 0) {
    321      1.1  macallan 			switch (sensor->type) {
    322      1.1  macallan 			case SMUSAT_SENSOR_TEMP:
    323      1.1  macallan 				edata->value_cur = sensor->current_value *
    324      1.1  macallan 				    1000000 + 273150000;
    325      1.1  macallan 			break;
    326      1.1  macallan 			case SMUSAT_SENSOR_CURRENT:
    327      1.2  macallan 				edata->value_cur = sensor->current_value * 1000000;
    328      1.1  macallan 			break;
    329      1.1  macallan 			case SMUSAT_SENSOR_VOLTAGE:
    330      1.2  macallan 				edata->value_cur = sensor->current_value * 1000000;
    331      1.1  macallan 			break;
    332      1.1  macallan 			case SMUSAT_SENSOR_POWER:
    333      1.2  macallan 				edata->value_cur = sensor->current_value * 1000000;
    334      1.1  macallan 			break;
    335      1.1  macallan 			default:
    336      1.1  macallan 				edata->value_cur = sensor->current_value;
    337      1.1  macallan 			}
    338      1.1  macallan 
    339      1.1  macallan 			edata->state = ENVSYS_SVALID;
    340      1.1  macallan 		}
    341      1.1  macallan 	}
    342      1.1  macallan }
    343      1.1  macallan 
    344      1.1  macallan static int
    345      1.2  macallan smusat_sensors_update(struct smusat_softc *sc)
    346      1.1  macallan {
    347      1.2  macallan 	u_char reg = 0x3f;
    348      1.1  macallan 	int ret;
    349      1.1  macallan 
    350      1.1  macallan 	iic_acquire_bus(sc->sc_i2c, 0);
    351      1.2  macallan 	ret = iic_exec(sc->sc_i2c, I2C_OP_READ, sc->sc_addr, &reg, 1, sc->sc_cache, 16, 0);
    352      1.1  macallan 	iic_release_bus(sc->sc_i2c, 0);
    353      1.1  macallan 
    354      1.1  macallan 	if (ret != 0)
    355      1.1  macallan 		return (ret);
    356      1.1  macallan 
    357      1.2  macallan 	sc->sc_last_update = time_uptime;
    358      1.1  macallan 
    359      1.1  macallan 	return 0;
    360      1.1  macallan }
    361      1.1  macallan 
    362      1.1  macallan static int
    363      1.1  macallan smusat_sensor_read(struct smusat_sensor *sensor, int *value)
    364      1.1  macallan {
    365      1.2  macallan 	struct smusat_softc *sc = sensor->sc;
    366      1.2  macallan 	int ret, reg;
    367      1.1  macallan 
    368      1.2  macallan 	if (time_uptime - sc->sc_last_update > 1) {
    369      1.2  macallan 		ret = smusat_sensors_update(sc);
    370      1.1  macallan 		if (ret != 0)
    371      1.1  macallan 			return ret;
    372      1.1  macallan 	}
    373      1.1  macallan 
    374      1.2  macallan 	reg = sensor->reg << 1;
    375      1.2  macallan 	sensor->current_value = (sc->sc_cache[reg] << 8) + sc->sc_cache[reg + 1];
    376      1.2  macallan 	sensor->current_value <<= sensor->shift;
    377      1.2  macallan 	/* Discard the .16 */
    378      1.2  macallan 	sensor->current_value >>= 16;
    379      1.2  macallan 
    380      1.2  macallan 	if (value != NULL)
    381      1.2  macallan 		*value = sensor->current_value;
    382      1.1  macallan 
    383      1.1  macallan 	return 0;
    384      1.1  macallan }
    385      1.1  macallan 
    386      1.1  macallan static int
    387      1.1  macallan smusat_sysctl_sensor_value(SYSCTLFN_ARGS)
    388      1.1  macallan {
    389      1.1  macallan 	struct sysctlnode node = *rnode;
    390      1.1  macallan 	struct smusat_sensor *sensor = node.sysctl_data;
    391      1.1  macallan 	int value = 0;
    392      1.1  macallan 	int ret;
    393      1.1  macallan 
    394      1.1  macallan 	node.sysctl_data = &value;
    395      1.1  macallan 
    396      1.1  macallan 	ret = smusat_sensor_read(sensor, &value);
    397      1.1  macallan 	if (ret != 0)
    398      1.1  macallan 		return (ret);
    399      1.1  macallan 
    400      1.1  macallan 	return sysctl_lookup(SYSCTLFN_CALL(&node));
    401      1.1  macallan }
    402      1.1  macallan 
    403      1.1  macallan SYSCTL_SETUP(smusat_sysctl_setup, "SMU-SAT sysctl subtree setup")
    404      1.1  macallan {
    405      1.1  macallan 	sysctl_createv(NULL, 0, NULL, NULL,
    406      1.1  macallan 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
    407      1.1  macallan 	    NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL);
    408      1.1  macallan }
    409