1 1.2 thorpej /* $NetBSD: ds28e17iic.c,v 1.2 2025/09/15 13:23:03 thorpej Exp $ */ 2 1.1 brad 3 1.1 brad /* 4 1.1 brad * Copyright (c) 2025 Brad Spencer <brad (at) anduin.eldar.org> 5 1.1 brad * 6 1.1 brad * Permission to use, copy, modify, and distribute this software for any 7 1.1 brad * purpose with or without fee is hereby granted, provided that the above 8 1.1 brad * copyright notice and this permission notice appear in all copies. 9 1.1 brad * 10 1.1 brad * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 1.1 brad * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 1.1 brad * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 1.1 brad * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 1.1 brad * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 1.1 brad * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 1.1 brad * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 1.1 brad */ 18 1.1 brad 19 1.1 brad 20 1.1 brad /* Driver for the DS28E17 1-Wire to I2C bridge chip */ 21 1.1 brad 22 1.1 brad /* https://www.analog.com/en/products/DS28E17.html */ 23 1.1 brad 24 1.1 brad #include <sys/cdefs.h> 25 1.2 thorpej __KERNEL_RCSID(0, "$NetBSD: ds28e17iic.c,v 1.2 2025/09/15 13:23:03 thorpej Exp $"); 26 1.1 brad 27 1.1 brad #include <sys/param.h> 28 1.1 brad #include <sys/systm.h> 29 1.1 brad #include <sys/device.h> 30 1.1 brad #include <sys/kernel.h> 31 1.1 brad #include <sys/proc.h> 32 1.1 brad #include <sys/module.h> 33 1.1 brad #include <sys/sysctl.h> 34 1.1 brad 35 1.1 brad #include <dev/onewire/onewiredevs.h> 36 1.1 brad #include <dev/onewire/onewirereg.h> 37 1.1 brad #include <dev/onewire/onewirevar.h> 38 1.1 brad 39 1.1 brad #include <dev/i2c/i2cvar.h> 40 1.1 brad 41 1.1 brad #include <dev/onewire/ds28e17iicreg.h> 42 1.1 brad #include <dev/onewire/ds28e17iicvar.h> 43 1.1 brad 44 1.1 brad static int ds28e17iic_match(device_t, cfdata_t, void *); 45 1.1 brad static void ds28e17iic_attach(device_t, device_t, void *); 46 1.1 brad static int ds28e17iic_detach(device_t, int); 47 1.1 brad static int ds28e17iic_activate(device_t, enum devact); 48 1.1 brad static int ds28e17iic_verify_sysctl(SYSCTLFN_ARGS); 49 1.1 brad 50 1.1 brad #define DS28E17IIC_DEBUG 51 1.1 brad #ifdef DS28E17IIC_DEBUG 52 1.1 brad #define DPRINTF(s, l, x) \ 53 1.1 brad do { \ 54 1.1 brad if (l <= s->sc_ds28e17iicdebug) \ 55 1.1 brad printf x; \ 56 1.1 brad } while (/*CONSTCOND*/0) 57 1.1 brad #else 58 1.1 brad #define DPRINTF(s, l, x) 59 1.1 brad #endif 60 1.1 brad 61 1.1 brad CFATTACH_DECL_NEW(ds28e17iic, sizeof(struct ds28e17iic_softc), 62 1.1 brad ds28e17iic_match, ds28e17iic_attach, ds28e17iic_detach, ds28e17iic_activate); 63 1.1 brad 64 1.1 brad extern struct cfdriver ds28e17iic_cd; 65 1.1 brad 66 1.1 brad static const struct onewire_matchfam ds28e17iic_fams[] = { 67 1.1 brad { ONEWIRE_FAMILY_DS28E17 }, 68 1.1 brad }; 69 1.1 brad 70 1.1 brad 71 1.1 brad #define READY_DELAY(d) if (d > 0) delay(d) 72 1.1 brad 73 1.1 brad /* The chip uses a 16 bit CRC on the 1-Wire bus when doing any I2C transaction. 74 1.1 brad * But it has some strangness to it.. the CRC can be made up from a number of 75 1.1 brad * parts of the 1-Wire transaction, some of which are only used for some 76 1.1 brad * transactions. Then the result must be inverted and placed in the proper 77 1.1 brad * order. 78 1.1 brad */ 79 1.1 brad 80 1.1 brad static uint16_t 81 1.1 brad ds28e17iic_crc16_bit(uint16_t icrc) 82 1.1 brad { 83 1.1 brad for (size_t i = 0; i < 8; i++) { 84 1.1 brad if (icrc & 0x01) { 85 1.1 brad icrc >>= 1; 86 1.1 brad icrc ^= 0xA001; 87 1.1 brad } else { 88 1.1 brad icrc >>= 1; 89 1.1 brad } 90 1.1 brad } 91 1.1 brad 92 1.1 brad return(icrc); 93 1.1 brad } 94 1.1 brad 95 1.1 brad static void 96 1.1 brad ds28e17iic_crc16(uint8_t crc16[], uint8_t cmd, uint8_t i2c_addr, uint8_t len, uint8_t *data, uint8_t len2) 97 1.1 brad { 98 1.1 brad uint16_t crc = 0; 99 1.1 brad 100 1.1 brad crc ^= cmd; 101 1.1 brad crc = ds28e17iic_crc16_bit(crc); 102 1.1 brad 103 1.1 brad /* This is a magic value which means that it should not be considered. 104 1.1 brad * The address will never be 0xff, but could, in theory, be 0x00, so 105 1.1 brad * don't use that. 106 1.1 brad */ 107 1.1 brad 108 1.1 brad if (i2c_addr != 0xff) { 109 1.1 brad crc ^= i2c_addr; 110 1.1 brad crc = ds28e17iic_crc16_bit(crc); 111 1.1 brad } 112 1.1 brad 113 1.1 brad crc ^= len; 114 1.1 brad crc = ds28e17iic_crc16_bit(crc); 115 1.1 brad 116 1.1 brad if (data != NULL) { 117 1.1 brad for (size_t j = 0; j < len; j++) { 118 1.1 brad crc ^= data[j]; 119 1.1 brad crc = ds28e17iic_crc16_bit(crc); 120 1.1 brad } 121 1.1 brad } 122 1.1 brad 123 1.1 brad if (len2 > 0) { 124 1.1 brad crc ^= len2; 125 1.1 brad crc = ds28e17iic_crc16_bit(crc); 126 1.1 brad } 127 1.1 brad 128 1.1 brad crc = crc ^ 0xffff; 129 1.1 brad 130 1.1 brad crc16[1] = crc >> 8; 131 1.1 brad crc16[0] = crc & 0xff; 132 1.1 brad } 133 1.1 brad 134 1.1 brad int 135 1.1 brad ds28e17iic_verify_sysctl(SYSCTLFN_ARGS) 136 1.1 brad { 137 1.1 brad int error, t; 138 1.1 brad struct sysctlnode node; 139 1.1 brad 140 1.1 brad node = *rnode; 141 1.1 brad t = *(int *)rnode->sysctl_data; 142 1.1 brad node.sysctl_data = &t; 143 1.1 brad error = sysctl_lookup(SYSCTLFN_CALL(&node)); 144 1.1 brad if (error || newp == NULL) 145 1.1 brad return error; 146 1.1 brad 147 1.1 brad if (t < 0) 148 1.1 brad return EINVAL; 149 1.1 brad 150 1.1 brad *(int *)rnode->sysctl_data = t; 151 1.1 brad 152 1.1 brad return 0; 153 1.1 brad } 154 1.1 brad 155 1.1 brad /* There isn't much required to acquire or release the I2C bus, but the man 156 1.1 brad * pages says these are needed 157 1.1 brad */ 158 1.1 brad 159 1.1 brad static int 160 1.1 brad ds28e17iic_acquire_bus(void *v, int flags) 161 1.1 brad { 162 1.1 brad return(0); 163 1.1 brad } 164 1.1 brad 165 1.1 brad static void 166 1.1 brad ds28e17iic_release_bus(void *v, int flags) 167 1.1 brad { 168 1.1 brad return; 169 1.1 brad } 170 1.1 brad 171 1.1 brad /* Perform most of a I2C transaction. Sometimes there there will be 172 1.1 brad * more to read from the 1-Wire bus. That is device command dependent. 173 1.1 brad */ 174 1.1 brad 175 1.1 brad static int 176 1.1 brad ds28e17iic_ow_i2c_transaction(struct ds28e17iic_softc *sc, const char *what, uint8_t device_cmd, 177 1.1 brad uint8_t i2c_addr, uint8_t len1, uint8_t *buf1, uint8_t len2, 178 1.1 brad uint8_t crc16[2], uint8_t *i2c_status) 179 1.1 brad { 180 1.1 brad int err = 0; 181 1.1 brad int readycount; 182 1.1 brad uint8_t ready; 183 1.1 brad 184 1.1 brad if (onewire_reset(sc->sc_onewire) != 0) { 185 1.1 brad err = EIO; 186 1.1 brad } else { 187 1.1 brad ds28e17iic_crc16(crc16,device_cmd,i2c_addr,len1,buf1,len2); 188 1.1 brad onewire_matchrom(sc->sc_onewire, sc->sc_rom); 189 1.1 brad onewire_write_byte(sc->sc_onewire,device_cmd); 190 1.1 brad if (i2c_addr != 0xff) 191 1.1 brad onewire_write_byte(sc->sc_onewire,i2c_addr); 192 1.1 brad onewire_write_byte(sc->sc_onewire,len1); 193 1.1 brad if (buf1 != NULL) 194 1.1 brad onewire_write_block(sc->sc_onewire,buf1,len1); 195 1.1 brad if (len2 > 0) 196 1.1 brad onewire_write_byte(sc->sc_onewire,len2); 197 1.1 brad onewire_write_block(sc->sc_onewire,crc16,2); 198 1.1 brad readycount=0; 199 1.1 brad do { 200 1.1 brad READY_DELAY(sc->sc_readydelay); 201 1.1 brad ready = onewire_read_bit(sc->sc_onewire); 202 1.1 brad readycount++; 203 1.1 brad if (readycount > sc->sc_readycount) 204 1.1 brad err = EAGAIN; 205 1.1 brad } while (ready != 0 && !err); 206 1.1 brad DPRINTF(sc, 3, ("%s: readycount=%d, err=%d\n", 207 1.1 brad what, readycount, err)); 208 1.1 brad *i2c_status = onewire_read_byte(sc->sc_onewire); 209 1.1 brad } 210 1.1 brad 211 1.1 brad return(err); 212 1.1 brad } 213 1.1 brad 214 1.1 brad /* This needs to determine what sort of write is going on. We will may make use 215 1.1 brad * of the fact that the chip can start a write transaction with one command and 216 1.1 brad * add data to it with a second command. 217 1.1 brad */ 218 1.1 brad 219 1.1 brad static int 220 1.1 brad ds28e17iic_i2c_write(struct ds28e17iic_softc *sc, i2c_op_t op, i2c_addr_t addr, 221 1.1 brad const void *cmdbuf, size_t cmdlen, void *databuf, size_t datalen, int flags) 222 1.1 brad { 223 1.1 brad uint8_t crc16[2]; 224 1.1 brad uint8_t dcmd; 225 1.1 brad uint8_t i2c_status; 226 1.1 brad uint8_t i2c_write_status; 227 1.1 brad uint8_t *buf; 228 1.1 brad size_t len; 229 1.1 brad uint8_t maddr; 230 1.1 brad int err = 0; 231 1.1 brad 232 1.1 brad if (sc->sc_dying) 233 1.1 brad return(EIO); 234 1.1 brad 235 1.1 brad /* It would be possible to support more than 256 bytes in a transfer by 236 1.1 brad * breaking it up and using the chip's ability to add data to a write, 237 1.1 brad * but that isn't currently done. 238 1.1 brad */ 239 1.1 brad 240 1.1 brad if (cmdbuf != NULL && 241 1.1 brad cmdlen > 256) 242 1.1 brad return(ENOTSUP); 243 1.1 brad 244 1.1 brad if (databuf != NULL && 245 1.1 brad datalen > 256) 246 1.1 brad return(ENOTSUP); 247 1.1 brad 248 1.1 brad /* Just null out any attempt to not actually do anything, might save us 249 1.1 brad * a panic */ 250 1.1 brad 251 1.1 brad if (cmdbuf == NULL && 252 1.1 brad databuf == NULL) 253 1.1 brad return(err); 254 1.1 brad 255 1.1 brad maddr = addr << 1; 256 1.1 brad 257 1.1 brad onewire_lock(sc->sc_onewire); 258 1.1 brad 259 1.1 brad /* Consider two ways to do a basic write. One is where there is a 260 1.1 brad * cmdbuf and databuf which can use the chip's ability to add to a 261 1.1 brad * ongoing transaction and the other case where there is just the 262 1.1 brad * cmdbuf or the databuf, in which case, just figure out if a stop 263 1.1 brad * is needed. 264 1.1 brad */ 265 1.1 brad 266 1.1 brad if (cmdbuf != NULL && 267 1.1 brad databuf != NULL) { 268 1.1 brad /* This chip considers a zero length write an error */ 269 1.1 brad if (cmdlen == 0 || 270 1.1 brad datalen == 0) { 271 1.1 brad if (sc->sc_reportzerolen) 272 1.1 brad device_printf(sc->sc_dv,"ds28e17iic_i2c_write: ************ called with zero length read: cmdlen: %zu, datalen: %zu ***************\n", 273 1.1 brad cmdlen, datalen); 274 1.1 brad } 275 1.1 brad 276 1.1 brad /* In this case, always start out with a write without stop. */ 277 1.1 brad 278 1.1 brad err = ds28e17iic_ow_i2c_transaction(sc, "ds28e17iic_i2c_write cmd and data 1", 279 1.1 brad DS28E17IIC_DC_WD, maddr, cmdlen, __UNCONST(cmdbuf), 0, crc16, &i2c_status); 280 1.1 brad if (! err) { 281 1.1 brad i2c_write_status = onewire_read_byte(sc->sc_onewire); 282 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_write: both cmd and data 1: i2c_status=%02x, i2c_write_status=%02x\n", 283 1.1 brad i2c_status, i2c_write_status)); 284 1.1 brad if (i2c_status == 0 && 285 1.1 brad i2c_write_status == 0) { 286 1.1 brad /* Add data to the transaction and maybe do a stop as well */ 287 1.1 brad if (I2C_OP_STOP_P(op)) 288 1.1 brad dcmd = DS28E17IIC_DC_WD_ONLY_WITH_STOP; 289 1.1 brad else 290 1.1 brad dcmd = DS28E17IIC_DC_WD_ONLY; 291 1.1 brad 292 1.1 brad err = ds28e17iic_ow_i2c_transaction(sc, "ds28e17iic_i2c_write cmd and data 2", 293 1.1 brad dcmd, 0xff, datalen, databuf, 0, crc16, &i2c_status); 294 1.1 brad if (! err) { 295 1.1 brad i2c_write_status = onewire_read_byte(sc->sc_onewire); 296 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_write: both cmd and data 2: dcmd=%02x, i2c_status=%02x, i2c_write_status=%02x\n", 297 1.1 brad dcmd, i2c_status, i2c_write_status)); 298 1.1 brad if (i2c_status != 0 || 299 1.1 brad i2c_write_status != 0) 300 1.1 brad err = EIO; 301 1.1 brad } else { 302 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_write: cmd and data 2: err=%d\n", err)); 303 1.1 brad } 304 1.1 brad } else { 305 1.1 brad err = EIO; 306 1.1 brad } 307 1.1 brad } else { 308 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_write: cmd and data 1: err=%d\n", err)); 309 1.1 brad } 310 1.1 brad } else { 311 1.1 brad /* Either the cmdbuf or databuf has something, figure out which 312 1.1 brad * and maybe perform a stop after the write. 313 1.1 brad */ 314 1.1 brad if (cmdbuf != NULL) { 315 1.1 brad buf = __UNCONST(cmdbuf); 316 1.1 brad len = cmdlen; 317 1.1 brad } else { 318 1.1 brad buf = databuf; 319 1.1 brad len = datalen; 320 1.1 brad } 321 1.1 brad 322 1.1 brad if (I2C_OP_STOP_P(op)) 323 1.1 brad dcmd = DS28E17IIC_DC_WD_WITH_STOP; 324 1.1 brad else 325 1.1 brad dcmd = DS28E17IIC_DC_WD; 326 1.1 brad 327 1.1 brad if (len == 0) { 328 1.1 brad if (sc->sc_reportzerolen) 329 1.1 brad device_printf(sc->sc_dv,"ds28e17iic_i2c_write: ************ called with zero length read ***************\n"); 330 1.1 brad } 331 1.1 brad 332 1.1 brad err = ds28e17iic_ow_i2c_transaction(sc, "ds28e17iic_i2c_write cmd or data", 333 1.1 brad dcmd, maddr, len, buf, 0, crc16, &i2c_status); 334 1.1 brad if (! err) { 335 1.1 brad i2c_write_status = onewire_read_byte(sc->sc_onewire); 336 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_write: cmd or data: dcmd=%02x, i2c_status=%02x, i2c_write_status=%02x\n", 337 1.1 brad dcmd, i2c_status, i2c_write_status)); 338 1.1 brad if (i2c_status != 0 || 339 1.1 brad i2c_write_status != 0) 340 1.1 brad err = EIO; 341 1.1 brad } else { 342 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_write: cmd or data: err=%d\n", err)); 343 1.1 brad } 344 1.1 brad } 345 1.1 brad 346 1.1 brad onewire_unlock(sc->sc_onewire); 347 1.1 brad 348 1.1 brad return(err); 349 1.1 brad } 350 1.1 brad 351 1.1 brad /* This deals with the situation where the desire is just to read from 352 1.1 brad * the device. The chip does not support Read without Stop, so turn 353 1.1 brad * that into a Read with Stop and hope for the best. 354 1.1 brad */ 355 1.1 brad 356 1.1 brad static int 357 1.1 brad ds28e17iic_i2c_read(struct ds28e17iic_softc *sc, i2c_op_t op, i2c_addr_t addr, 358 1.1 brad void *databuf, size_t datalen, int flags) 359 1.1 brad { 360 1.1 brad uint8_t crc16[2]; 361 1.1 brad uint8_t i2c_status; 362 1.1 brad uint8_t maddr; 363 1.1 brad int err = 0; 364 1.1 brad 365 1.1 brad if (sc->sc_dying) 366 1.1 brad return(EIO); 367 1.1 brad 368 1.1 brad /* It does not appear that it is possible to read more than 256 bytes */ 369 1.1 brad 370 1.1 brad if (databuf != NULL && 371 1.1 brad datalen > 256) 372 1.1 brad return(ENOTSUP); 373 1.1 brad 374 1.1 brad /* Just null out the attempt to not really read anything */ 375 1.1 brad 376 1.1 brad if (databuf == NULL) 377 1.1 brad return(err); 378 1.1 brad 379 1.1 brad maddr = (addr << 1) | 0x01; 380 1.1 brad 381 1.1 brad onewire_lock(sc->sc_onewire); 382 1.1 brad 383 1.1 brad /* Same thing as a write, a zero length read is considered an error */ 384 1.1 brad 385 1.1 brad if (datalen == 0) 386 1.1 brad if (sc->sc_reportzerolen) 387 1.1 brad device_printf(sc->sc_dv,"ds28e17iic_i2c_read: ************ called with zero length read ***************\n"); 388 1.1 brad 389 1.1 brad if (!I2C_OP_STOP_P(op) && 390 1.1 brad sc->sc_reportreadnostop) 391 1.1 brad device_printf(sc->sc_dv,"ds28e17iic_i2c_read: ************ called with READ without STOP ***************\n"); 392 1.1 brad 393 1.1 brad err = ds28e17iic_ow_i2c_transaction(sc, "ds28e17iic_i2c_read", 394 1.1 brad DS28E17IIC_DC_RD_WITH_STOP, maddr, datalen, 395 1.1 brad NULL, 0, crc16, &i2c_status); 396 1.1 brad if (! err) { 397 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_read: i2c_status=%02x\n", i2c_status)); 398 1.1 brad if (i2c_status == 0) { 399 1.1 brad onewire_read_block(sc->sc_onewire, databuf, datalen); 400 1.1 brad } else { 401 1.1 brad err = EIO; 402 1.1 brad } 403 1.1 brad } else { 404 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_read: err=%d\n", err)); 405 1.1 brad } 406 1.1 brad 407 1.1 brad onewire_unlock(sc->sc_onewire); 408 1.1 brad 409 1.1 brad return(err); 410 1.1 brad } 411 1.1 brad 412 1.1 brad /* This deals with the situation where the desire is to write something to 413 1.1 brad * the device and then read some stuff back. The chip does not support Read 414 1.1 brad * without Stop, so turn that into a Read with Stop and hope for the best. 415 1.1 brad */ 416 1.1 brad 417 1.1 brad static int 418 1.1 brad ds28e17iic_i2c_write_read(struct ds28e17iic_softc *sc, i2c_op_t op, i2c_addr_t addr, 419 1.1 brad const void *cmdbuf, size_t cmdlen, void *databuf, size_t datalen, int flags) 420 1.1 brad { 421 1.1 brad uint8_t crc16[2]; 422 1.1 brad uint8_t i2c_status; 423 1.1 brad uint8_t i2c_write_status; 424 1.1 brad uint8_t maddr; 425 1.1 brad int err = 0; 426 1.1 brad 427 1.1 brad if (sc->sc_dying) 428 1.1 brad return(EIO); 429 1.1 brad 430 1.1 brad /* When using the write+read command of the chip, it does not appear to be 431 1.1 brad * possible to read more than 256 bytes, or write more than 256 bytes in a 432 1.1 brad * transaction. 433 1.1 brad */ 434 1.1 brad 435 1.1 brad if (cmdbuf != NULL && 436 1.1 brad cmdlen > 256) 437 1.1 brad return(ENOTSUP); 438 1.1 brad 439 1.1 brad if (databuf != NULL && 440 1.1 brad datalen > 256) 441 1.1 brad return(ENOTSUP); 442 1.1 brad 443 1.1 brad /* Just return if asked to not actually do anything */ 444 1.1 brad 445 1.1 brad if (cmdbuf == NULL && 446 1.1 brad databuf == NULL) 447 1.1 brad return(err); 448 1.1 brad 449 1.1 brad maddr = addr << 1; 450 1.1 brad 451 1.1 brad /* Same as a single read or write, a zero length anything here is 452 1.1 brad * considered an error. 453 1.1 brad */ 454 1.1 brad 455 1.1 brad if (cmdlen == 0 || 456 1.1 brad datalen == 0) { 457 1.1 brad if (sc->sc_reportzerolen) 458 1.1 brad device_printf(sc->sc_dv,"ds28e17iic_i2c_write_read: ************ called with zero length read: cmdlen: %zu, datalen: %zu ***************\n", 459 1.1 brad cmdlen, datalen); 460 1.1 brad } 461 1.1 brad 462 1.1 brad if (!I2C_OP_STOP_P(op) && 463 1.1 brad sc->sc_reportreadnostop) 464 1.1 brad device_printf(sc->sc_dv,"ds28e17iic_i2c_write_read: ************ called with READ without STOP ***************\n"); 465 1.1 brad 466 1.1 brad onewire_lock(sc->sc_onewire); 467 1.1 brad 468 1.1 brad err = ds28e17iic_ow_i2c_transaction(sc, "ds28e17iic_i2c_write_read", 469 1.1 brad DS28E17IIC_DC_WD_RD_WITH_STOP, maddr, cmdlen, 470 1.1 brad __UNCONST(cmdbuf), datalen, crc16, &i2c_status); 471 1.1 brad if (! err) { 472 1.1 brad /* Like with the normal write, even if the i2c_status is not zero, 473 1.1 brad * we have to read the write status too. It will end up being 474 1.1 brad * the value 0xff. */ 475 1.1 brad i2c_write_status = onewire_read_byte(sc->sc_onewire); 476 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_write_read: i2c_status=%02x, i2c_write_status=%02x\n", 477 1.1 brad i2c_status, i2c_write_status)); 478 1.1 brad /* However, don't bother trying to read the data block if there was an error */ 479 1.1 brad if (i2c_status == 0 && 480 1.1 brad i2c_write_status == 0) { 481 1.1 brad onewire_read_block(sc->sc_onewire, databuf, datalen); 482 1.1 brad } else { 483 1.1 brad err = EIO; 484 1.1 brad } 485 1.1 brad } else { 486 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_i2c_write_read: err=%d\n", err)); 487 1.1 brad } 488 1.1 brad 489 1.1 brad onewire_unlock(sc->sc_onewire); 490 1.1 brad 491 1.1 brad return(err); 492 1.1 brad } 493 1.1 brad 494 1.1 brad /* This needs to figure out what sort of thing is being sent to the end device. 495 1.1 brad * The chip will help out with some of this. 496 1.1 brad */ 497 1.1 brad 498 1.1 brad static int 499 1.1 brad ds28e17iic_i2c_exec(void *v, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf, 500 1.1 brad size_t cmdlen, void *databuf, size_t datalen, int flags) 501 1.1 brad { 502 1.1 brad struct ds28e17iic_softc *sc = v; 503 1.1 brad int err = 0; 504 1.1 brad 505 1.1 brad if (sc->sc_dying) 506 1.1 brad return(EIO); 507 1.1 brad 508 1.1 brad /* The chip only supports 7 bit addressing */ 509 1.1 brad 510 1.1 brad if (addr > 0x7f) 511 1.1 brad return (ENOTSUP); 512 1.1 brad 513 1.1 brad /* XXX - this driver could support setting the speed for this I2C 514 1.1 brad * transaction as that information is in the flags, but nothing really 515 1.1 brad * asks to do that, so just ignore that for now. 516 1.1 brad * 517 1.1 brad * If it did support setting speed, do it here. 518 1.1 brad * 519 1.1 brad */ 520 1.1 brad 521 1.1 brad if (I2C_OP_WRITE_P(op)) { 522 1.1 brad /* A write may include the cmdbuf and/or the databuf */ 523 1.1 brad err = ds28e17iic_i2c_write(sc, op, addr, cmdbuf, cmdlen, databuf, datalen, flags); 524 1.1 brad 525 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_exec: I2C WRITE: addr=%02x, err=%d\n", addr, err)); 526 1.1 brad } else { 527 1.1 brad /* If a read includes a cmdbuf, then this is a write+read operation */ 528 1.1 brad if (cmdbuf != NULL) 529 1.1 brad err = ds28e17iic_i2c_write_read(sc, op, addr, cmdbuf, cmdlen, databuf, datalen, flags); 530 1.1 brad else 531 1.1 brad err = ds28e17iic_i2c_read(sc, op, addr, databuf, datalen, flags); 532 1.1 brad 533 1.1 brad DPRINTF(sc, 2, ("ds28e17iic_exec: I2C %s addr=%02x, err=%d\n", 534 1.1 brad cmdbuf != NULL ? "WRITE-READ" : "READ", addr, err)); 535 1.1 brad } 536 1.1 brad 537 1.1 brad return(err); 538 1.1 brad } 539 1.1 brad 540 1.1 brad static int 541 1.1 brad ds28e17iic_sysctl_init(struct ds28e17iic_softc *sc) 542 1.1 brad { 543 1.1 brad int error; 544 1.1 brad const struct sysctlnode *cnode; 545 1.1 brad int sysctlroot_num; 546 1.1 brad 547 1.1 brad if ((error = sysctl_createv(&sc->sc_ds28e17iiclog, 0, NULL, &cnode, 548 1.1 brad 0, CTLTYPE_NODE, device_xname(sc->sc_dv), 549 1.1 brad SYSCTL_DESCR("DS28E17IIC controls"), NULL, 0, NULL, 0, CTL_HW, 550 1.1 brad CTL_CREATE, CTL_EOL)) != 0) 551 1.1 brad return error; 552 1.1 brad 553 1.1 brad sysctlroot_num = cnode->sysctl_num; 554 1.1 brad 555 1.1 brad #ifdef DS28E17IIC_DEBUG 556 1.1 brad if ((error = sysctl_createv(&sc->sc_ds28e17iiclog, 0, NULL, &cnode, 557 1.1 brad CTLFLAG_READWRITE, CTLTYPE_INT, "debug", 558 1.1 brad SYSCTL_DESCR("Debug level"), ds28e17iic_verify_sysctl, 0, 559 1.1 brad &sc->sc_ds28e17iicdebug, 0, CTL_HW, sysctlroot_num, CTL_CREATE, 560 1.1 brad CTL_EOL)) != 0) 561 1.1 brad return error; 562 1.1 brad #endif 563 1.1 brad 564 1.1 brad if ((error = sysctl_createv(&sc->sc_ds28e17iiclog, 0, NULL, &cnode, 565 1.1 brad CTLFLAG_READWRITE, CTLTYPE_INT, "readycount", 566 1.1 brad SYSCTL_DESCR("How many times to wait for the I2C transaction to finish"), ds28e17iic_verify_sysctl, 0, 567 1.1 brad &sc->sc_readycount, 0, CTL_HW, sysctlroot_num, CTL_CREATE, 568 1.1 brad CTL_EOL)) != 0) 569 1.1 brad return error; 570 1.1 brad 571 1.1 brad if ((error = sysctl_createv(&sc->sc_ds28e17iiclog, 0, NULL, &cnode, 572 1.1 brad CTLFLAG_READWRITE, CTLTYPE_INT, "readydelay", 573 1.1 brad SYSCTL_DESCR("Delay in microseconds before checking the I2C transaction"), ds28e17iic_verify_sysctl, 0, 574 1.1 brad &sc->sc_readydelay, 0, CTL_HW, sysctlroot_num, CTL_CREATE, 575 1.1 brad CTL_EOL)) != 0) 576 1.1 brad return error; 577 1.1 brad 578 1.1 brad if ((error = sysctl_createv(&sc->sc_ds28e17iiclog, 0, NULL, &cnode, 579 1.1 brad CTLFLAG_READWRITE, CTLTYPE_BOOL, "reportreadnostop", 580 1.1 brad SYSCTL_DESCR("Report that a READ without STOP was attempted by a device"), 581 1.1 brad NULL, 0, &sc->sc_reportreadnostop, 0, CTL_HW, sysctlroot_num, 582 1.1 brad CTL_CREATE, CTL_EOL)) != 0) 583 1.1 brad return error; 584 1.1 brad 585 1.1 brad if ((error = sysctl_createv(&sc->sc_ds28e17iiclog, 0, NULL, &cnode, 586 1.1 brad CTLFLAG_READWRITE, CTLTYPE_BOOL, "reportzerolen", 587 1.1 brad SYSCTL_DESCR("Report that an attempt to read or write zero length was attempted"), 588 1.1 brad NULL, 0, &sc->sc_reportzerolen, 0, CTL_HW, sysctlroot_num, 589 1.1 brad CTL_CREATE, CTL_EOL)) != 0) 590 1.1 brad return error; 591 1.1 brad 592 1.1 brad return 0; 593 1.1 brad } 594 1.1 brad 595 1.1 brad static int 596 1.1 brad ds28e17iic_match(device_t parent, cfdata_t match, void *aux) 597 1.1 brad { 598 1.1 brad return (onewire_matchbyfam(aux, ds28e17iic_fams, 599 1.1 brad __arraycount(ds28e17iic_fams))); 600 1.1 brad } 601 1.1 brad 602 1.1 brad static void 603 1.1 brad ds28e17iic_attach(device_t parent, device_t self, void *aux) 604 1.1 brad { 605 1.1 brad struct ds28e17iic_softc *sc = device_private(self); 606 1.1 brad struct onewire_attach_args *oa = aux; 607 1.1 brad uint8_t hardware_rev; 608 1.1 brad uint8_t i2c_speed[2]; 609 1.1 brad int err = 0; 610 1.1 brad 611 1.1 brad aprint_normal("\n"); 612 1.1 brad 613 1.1 brad sc->sc_dv = self; 614 1.1 brad sc->sc_onewire = oa->oa_onewire; 615 1.1 brad sc->sc_rom = oa->oa_rom; 616 1.1 brad sc->sc_reportreadnostop = true; 617 1.1 brad sc->sc_reportzerolen = true; 618 1.1 brad sc->sc_ds28e17iicdebug = 0; 619 1.1 brad sc->sc_readycount=20; 620 1.1 brad sc->sc_readydelay = 10; 621 1.1 brad 622 1.1 brad if ((err = ds28e17iic_sysctl_init(sc)) != 0) { 623 1.1 brad aprint_error_dev(self, "Can't setup sysctl tree (%d)\n", err); 624 1.1 brad return; 625 1.1 brad } 626 1.1 brad 627 1.1 brad onewire_lock(sc->sc_onewire); 628 1.1 brad 629 1.1 brad if (onewire_reset(sc->sc_onewire) != 0) { 630 1.1 brad aprint_error_dev(sc->sc_dv, "Could not reset the onewire bus for hardware version\n"); 631 1.1 brad onewire_unlock(sc->sc_onewire); 632 1.1 brad return; 633 1.1 brad } 634 1.1 brad onewire_matchrom(sc->sc_onewire, sc->sc_rom); 635 1.1 brad onewire_write_byte(sc->sc_onewire, DS28E17IIC_DC_DEV_REVISION); 636 1.1 brad hardware_rev = onewire_read_byte(sc->sc_onewire); 637 1.1 brad 638 1.1 brad aprint_normal_dev(sc->sc_dv, "Hardware revision: %d\n", 639 1.1 brad hardware_rev); 640 1.1 brad 641 1.1 brad /* The default for the chip is 400Khz, but some devices may not be able 642 1.1 brad * to deal with that, so set the speed to 100Khz which is standard I2C 643 1.1 brad * speed. 644 1.1 brad */ 645 1.1 brad 646 1.1 brad if (onewire_reset(sc->sc_onewire) != 0) { 647 1.1 brad aprint_error_dev(sc->sc_dv, "Could not reset the onewire bus to set I2C speed\n"); 648 1.1 brad onewire_unlock(sc->sc_onewire); 649 1.1 brad return; 650 1.1 brad } 651 1.1 brad onewire_matchrom(sc->sc_onewire, sc->sc_rom); 652 1.1 brad i2c_speed[0] = DS28E17IIC_DC_WRITE_CONFIG; 653 1.1 brad i2c_speed[1] = DS28E17IIC_SPEED_100KHZ; 654 1.1 brad onewire_write_block(sc->sc_onewire, i2c_speed, 2); 655 1.1 brad 656 1.1 brad onewire_unlock(sc->sc_onewire); 657 1.1 brad 658 1.1 brad iic_tag_init(&sc->sc_i2c_tag); 659 1.1 brad sc->sc_i2c_tag.ic_cookie = sc; 660 1.1 brad sc->sc_i2c_tag.ic_acquire_bus = ds28e17iic_acquire_bus; 661 1.1 brad sc->sc_i2c_tag.ic_release_bus = ds28e17iic_release_bus; 662 1.1 brad sc->sc_i2c_tag.ic_exec = ds28e17iic_i2c_exec; 663 1.1 brad 664 1.2 thorpej sc->sc_i2c_dev = iicbus_attach(self, &sc->sc_i2c_tag); 665 1.1 brad } 666 1.1 brad 667 1.1 brad static int 668 1.1 brad ds28e17iic_detach(device_t self, int flags) 669 1.1 brad { 670 1.1 brad struct ds28e17iic_softc *sc = device_private(self); 671 1.1 brad int err = 0; 672 1.1 brad 673 1.1 brad sc->sc_dying = 1; 674 1.1 brad 675 1.1 brad err = config_detach_children(self, flags); 676 1.1 brad if (err) 677 1.1 brad return err; 678 1.1 brad 679 1.1 brad sysctl_teardown(&sc->sc_ds28e17iiclog); 680 1.1 brad 681 1.1 brad return 0; 682 1.1 brad } 683 1.1 brad 684 1.1 brad static int 685 1.1 brad ds28e17iic_activate(device_t self, enum devact act) 686 1.1 brad { 687 1.1 brad struct ds28e17iic_softc *sc = device_private(self); 688 1.1 brad 689 1.1 brad switch (act) { 690 1.1 brad case DVACT_DEACTIVATE: 691 1.1 brad sc->sc_dying = 1; 692 1.1 brad return 0; 693 1.1 brad default: 694 1.1 brad return EOPNOTSUPP; 695 1.1 brad } 696 1.1 brad } 697 1.1 brad 698 1.1 brad 699 1.1 brad MODULE(MODULE_CLASS_DRIVER, ds28e17iic, "onewire,iic"); 700 1.1 brad 701 1.1 brad #ifdef _MODULE 702 1.1 brad #include "ioconf.c" 703 1.1 brad #endif 704 1.1 brad 705 1.1 brad static int 706 1.1 brad ds28e17iic_modcmd(modcmd_t cmd, void *opaque) 707 1.1 brad { 708 1.1 brad int error; 709 1.1 brad 710 1.1 brad error = 0; 711 1.1 brad switch (cmd) { 712 1.1 brad case MODULE_CMD_INIT: 713 1.1 brad #ifdef _MODULE 714 1.1 brad error = config_init_component(cfdriver_ioconf_ds28e17iic, 715 1.1 brad cfattach_ioconf_ds28e17iic, cfdata_ioconf_ds28e17iic); 716 1.1 brad if (error) 717 1.1 brad aprint_error("%s: unable to init component\n", 718 1.1 brad ds28e17iic_cd.cd_name); 719 1.1 brad #endif 720 1.1 brad break; 721 1.1 brad case MODULE_CMD_FINI: 722 1.1 brad #ifdef _MODULE 723 1.1 brad config_fini_component(cfdriver_ioconf_ds28e17iic, 724 1.1 brad cfattach_ioconf_ds28e17iic, cfdata_ioconf_ds28e17iic); 725 1.1 brad #endif 726 1.1 brad break; 727 1.1 brad default: 728 1.1 brad error = ENOTTY; 729 1.1 brad } 730 1.1 brad return error; 731 1.1 brad } 732