1/*- 2 * Copyright (c) 2012 Andreas Tobler 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 21 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/param.h> 31#include <sys/bus.h> 32#include <sys/systm.h> 33#include <sys/module.h> 34#include <sys/callout.h> 35#include <sys/conf.h> 36#include <sys/cpu.h> 37#include <sys/ctype.h> 38#include <sys/kernel.h> 39#include <sys/reboot.h> 40#include <sys/rman.h> 41#include <sys/sysctl.h> 42#include <sys/limits.h> 43 44#include <machine/bus.h> 45#include <machine/md_var.h> 46 47#include <dev/iicbus/iicbus.h> 48#include <dev/iicbus/iiconf.h> 49 50#include <dev/ofw/openfirm.h> 51#include <dev/ofw/ofw_bus.h> 52#include <powerpc/powermac/powermac_thermal.h> 53 54/* Sensor: Maxim DS1631 */ 55 56#define DS1631_STOP 0x22 57#define DS1631_START 0x51 58#define DS1631_RESET 0x54 59#define DS1631_TEMP 0xAA 60#define DS1631_CONTROL 0xAC 61#define DS1631_CONTROL_1SHOT 0x01 62#define DS1631_CONTROL_9BIT 0x00 63#define DS1631_CONTROL_10BIT 0x04 64#define DS1631_CONTROL_11BIT 0x08 65#define DS1631_CONTROL_12BIT 0x0C 66 67 68 69/* Regular bus attachment functions */ 70static int ds1631_probe(device_t); 71static int ds1631_attach(device_t); 72 73struct ds1631_softc { 74 struct pmac_therm sc_sensor; 75 device_t sc_dev; 76 struct intr_config_hook enum_hook; 77 uint32_t sc_addr; 78 uint32_t init_done; 79}; 80 81struct write_data { 82 uint8_t reg; 83 uint8_t val; 84}; 85 86struct read_data { 87 uint8_t reg; 88 uint16_t val; 89}; 90 91/* Utility functions */ 92static int ds1631_sensor_read(struct ds1631_softc *sc); 93static int ds1631_sensor_sysctl(SYSCTL_HANDLER_ARGS); 94static void ds1631_start(void *xdev); 95static int ds1631_read_1(device_t dev, uint32_t addr, uint8_t reg, 96 uint8_t *data); 97static int ds1631_read_2(device_t dev, uint32_t addr, uint8_t reg, 98 uint16_t *data); 99static int ds1631_write(device_t dev, uint32_t addr, uint8_t reg, 100 uint8_t *buff, int len); 101 102static device_method_t ds1631_methods[] = { 103 /* Device interface */ 104 DEVMETHOD(device_probe, ds1631_probe), 105 DEVMETHOD(device_attach, ds1631_attach), 106 { 0, 0 }, 107}; 108 109static driver_t ds1631_driver = { 110 "ds1631", 111 ds1631_methods, 112 sizeof(struct ds1631_softc) 113}; 114 115static devclass_t ds1631_devclass; 116 117DRIVER_MODULE(ds1631, iicbus, ds1631_driver, ds1631_devclass, 0, 0); 118 119static int 120ds1631_write(device_t dev, uint32_t addr, uint8_t reg, uint8_t *buff, int len) 121{ 122 uint8_t buf[4]; 123 int try = 0; 124 125 struct iic_msg msg[] = { 126 { addr, IIC_M_WR, 0, buf } 127 }; 128 129 /* Prepare the write msg. */ 130 msg[0].len = len + 1; 131 buf[0] = reg; 132 memcpy(buf + 1, buff, len); 133 134 for (;;) 135 { 136 if (iicbus_transfer(dev, msg, 1) == 0) 137 return (0); 138 if (++try > 5) { 139 device_printf(dev, "iicbus write failed\n"); 140 return (-1); 141 } 142 pause("ds1631_write", hz); 143 } 144} 145 146static int 147ds1631_read_1(device_t dev, uint32_t addr, uint8_t reg, uint8_t *data) 148{ 149 uint8_t buf[4]; 150 int err, try = 0; 151 152 struct iic_msg msg[2] = { 153 { addr, IIC_M_WR, 1, ® }, 154 { addr, IIC_M_RD, 1, buf }, 155 }; 156 157 for (;;) 158 { 159 err = iicbus_transfer(dev, msg, 2); 160 if (err != 0) 161 goto retry; 162 163 *data = *((uint8_t*)buf); 164 return (0); 165 retry: 166 if (++try > 5) { 167 device_printf(dev, "iicbus read failed\n"); 168 return (-1); 169 } 170 pause("ds1631_read_1", hz); 171 } 172} 173 174static int 175ds1631_read_2(device_t dev, uint32_t addr, uint8_t reg, uint16_t *data) 176{ 177 uint8_t buf[4]; 178 int err, try = 0; 179 180 struct iic_msg msg[2] = { 181 { addr, IIC_M_WR, 1, ® }, 182 { addr, IIC_M_RD, 2, buf }, 183 }; 184 185 for (;;) 186 { 187 err = iicbus_transfer(dev, msg, 2); 188 if (err != 0) 189 goto retry; 190 191 *data = *((uint16_t*)buf); 192 return (0); 193 retry: 194 if (++try > 5) { 195 device_printf(dev, "iicbus read failed\n"); 196 return (-1); 197 } 198 pause("ds1631_read_2", hz); 199 } 200} 201 202static int 203ds1631_probe(device_t dev) 204{ 205 const char *name, *compatible; 206 struct ds1631_softc *sc; 207 208 name = ofw_bus_get_name(dev); 209 compatible = ofw_bus_get_compat(dev); 210 211 if (!name) 212 return (ENXIO); 213 214 if (strcmp(name, "temp-monitor") != 0 || 215 strcmp(compatible, "ds1631") != 0 ) 216 return (ENXIO); 217 218 sc = device_get_softc(dev); 219 sc->sc_dev = dev; 220 sc->sc_addr = iicbus_get_addr(dev); 221 222 device_set_desc(dev, "Temp-Monitor DS1631"); 223 224 return (0); 225} 226 227static int 228ds1631_attach(device_t dev) 229{ 230 struct ds1631_softc *sc; 231 232 sc = device_get_softc(dev); 233 234 sc->enum_hook.ich_func = ds1631_start; 235 sc->enum_hook.ich_arg = dev; 236 237 /* 238 * We have to wait until interrupts are enabled. I2C read and write 239 * only works if the interrupts are available. 240 * The unin/i2c is controlled by the htpic on unin. But this is not 241 * the master. The openpic on mac-io is controlling the htpic. 242 * This one gets attached after the mac-io probing and then the 243 * interrupts will be available. 244 */ 245 246 if (config_intrhook_establish(&sc->enum_hook) != 0) 247 return (ENOMEM); 248 249 return (0); 250} 251static int 252ds1631_init(device_t dev, uint32_t addr) 253{ 254 uint8_t conf; 255 int err; 256 struct ds1631_softc *sc; 257 258 sc = device_get_softc(dev); 259 260 err = ds1631_read_1(dev, addr, DS1631_CONTROL, &conf); 261 if (err < 0) { 262 device_printf(dev, "ds1631 read config failed: %x\n", err); 263 return (-1); 264 } 265 266 /* Stop the conversion if not in 1SHOT mode. */ 267 if (conf & ~DS1631_CONTROL_1SHOT) 268 err = ds1631_write(dev, addr, DS1631_STOP, &conf, 0); 269 270 /* 271 * Setup the resolution, 10-bit is enough. Each bit increase in 272 * resolution doubles the conversion time. 273 */ 274 conf = DS1631_CONTROL_10BIT; 275 276 err = ds1631_write(dev, addr, DS1631_CONTROL, &conf, 1); 277 if (err < 0) { 278 device_printf(dev, "ds1631 write config failed: %x\n", err); 279 return (-1); 280 } 281 282 /* And now start....*/ 283 err = ds1631_write(dev, addr, DS1631_START, &conf, 0); 284 285 if (err < 0) { 286 device_printf(dev, "ds1631 write start failed: %x\n", err); 287 return (-1); 288 } 289 290 sc->init_done = 1; 291 292 return (0); 293 294} 295static void 296ds1631_start(void *xdev) 297{ 298 phandle_t child, node; 299 struct ds1631_softc *sc; 300 struct sysctl_oid *oid, *sensroot_oid; 301 struct sysctl_ctx_list *ctx; 302 ssize_t plen; 303 int i; 304 char sysctl_desc[40], sysctl_name[40]; 305 306 device_t dev = (device_t)xdev; 307 308 sc = device_get_softc(dev); 309 310 child = ofw_bus_get_node(dev); 311 312 ctx = device_get_sysctl_ctx(dev); 313 sensroot_oid = SYSCTL_ADD_NODE(ctx, 314 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "sensor", 315 CTLFLAG_RD, 0, "DS1631 Sensor Information"); 316 317 if (OF_getprop(child, "hwsensor-zone", &sc->sc_sensor.zone, 318 sizeof(int)) < 0) 319 sc->sc_sensor.zone = 0; 320 321 plen = OF_getprop(child, "hwsensor-location", sc->sc_sensor.name, 322 sizeof(sc->sc_sensor.name)); 323 if (plen == -1) { 324 /* 325 * Ok, no hwsensor-location property, so let's look for a 326 * location property on a sub node. 327 */ 328 for (node = OF_child(child); node; node = OF_peer(node)) 329 plen = OF_getprop(node, "location", sc->sc_sensor.name, 330 sizeof(sc->sc_sensor.name)); 331 } 332 333 if (plen == -1) { 334 strcpy(sysctl_name, "sensor"); 335 } else { 336 for (i = 0; i < strlen(sc->sc_sensor.name); i++) { 337 sysctl_name[i] = tolower(sc->sc_sensor.name[i]); 338 if (isspace(sysctl_name[i])) 339 sysctl_name[i] = '_'; 340 } 341 sysctl_name[i] = 0; 342 } 343 344 /* Make up target temperatures. These are low, for the drive bay. */ 345 if (sc->sc_sensor.zone == 0) { 346 sc->sc_sensor.target_temp = 400 + ZERO_C_TO_K; 347 sc->sc_sensor.max_temp = 500 + ZERO_C_TO_K; 348 } else { 349 sc->sc_sensor.target_temp = 300 + ZERO_C_TO_K; 350 sc->sc_sensor.max_temp = 500 + ZERO_C_TO_K; 351 } 352 353 sc->sc_sensor.read = 354 (int (*)(struct pmac_therm *sc))(ds1631_sensor_read); 355 pmac_thermal_sensor_register(&sc->sc_sensor); 356 357 sprintf(sysctl_desc,"%s %s", sc->sc_sensor.name, "(C)"); 358 oid = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(sensroot_oid), 359 OID_AUTO, sysctl_name, CTLFLAG_RD, 0, 360 "Sensor Information"); 361 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO, "temp", 362 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev, 363 0, ds1631_sensor_sysctl, "IK", sysctl_desc); 364 365 config_intrhook_disestablish(&sc->enum_hook); 366} 367 368static int 369ds1631_sensor_read(struct ds1631_softc *sc) 370{ 371 uint16_t buf[2]; 372 uint16_t read; 373 int err; 374 375 if (!sc->init_done) 376 ds1631_init(sc->sc_dev, sc->sc_addr); 377 378 err = ds1631_read_2(sc->sc_dev, sc->sc_addr, DS1631_TEMP, buf); 379 if (err < 0) { 380 device_printf(sc->sc_dev, "ds1631 read TEMP failed: %x\n", err); 381 return (-1); 382 } 383 384 read = *((int16_t *)buf); 385 386 /* 387 * The default mode of the ADC is 12-bit, the resolution is 0.0625 C 388 * per bit. The temperature is in tenth kelvin. 389 * We use 10-bit resolution which seems enough, resolution is 0.25 C. 390 */ 391 392 return (((int16_t)(read) >> 6) * 25 / 10 + ZERO_C_TO_K); 393} 394 395static int 396ds1631_sensor_sysctl(SYSCTL_HANDLER_ARGS) 397{ 398 device_t dev; 399 struct ds1631_softc *sc; 400 int error; 401 int temp; 402 403 dev = arg1; 404 sc = device_get_softc(dev); 405 406 temp = ds1631_sensor_read(sc); 407 if (temp < 0) 408 return (EIO); 409 410 error = sysctl_handle_int(oidp, &temp, 0, req); 411 412 return (error); 413} 414