1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright (c) 2011 Bayard G. Bell. All rights reserved. 25 */ 26 27 /* 28 * I2C leaf driver for the PCF8591 29 */ 30 31 #include <sys/param.h> 32 #include <sys/types.h> 33 #include <sys/signal.h> 34 #include <sys/errno.h> 35 #include <sys/file.h> 36 #include <sys/termio.h> 37 #include <sys/termios.h> 38 #include <sys/cmn_err.h> 39 #include <sys/stream.h> 40 #include <sys/strsun.h> 41 #include <sys/stropts.h> 42 #include <sys/strtty.h> 43 #include <sys/debug.h> 44 #include <sys/eucioctl.h> 45 #include <sys/cred.h> 46 #include <sys/uio.h> 47 #include <sys/stat.h> 48 #include <sys/kmem.h> 49 50 #include <sys/ddi.h> 51 #include <sys/sunddi.h> 52 #include <sys/obpdefs.h> 53 #include <sys/conf.h> 54 #include <sys/modctl.h> 55 #include <sys/stat.h> 56 #include <sys/open.h> 57 #include <sys/uio.h> 58 59 #include <sys/i2c/misc/i2c_svc.h> 60 #include <sys/envctrl_gen.h> 61 #include <sys/netract_gen.h> 62 #include <sys/pcf8591_nct.h> 63 64 65 /* 66 * CONTROL OF CHIP 67 * PCF8591 Temp sensing control register definitions 68 * 69 * --------------------------------------------- 70 * | 0 | AOE | X | X | 0 | AIF | X | X | 71 * --------------------------------------------- 72 * AOE = Analog out enable.. not used on out implementation 73 * 5 & 4 = Analog Input Programming.. see data sheet for bits.. 74 * 75 * AIF = Auto increment flag 76 * bits 1 & 0 are for the Chennel number. 77 */ 78 79 80 #define I2CTRANS_DATA 0 81 #define I2CRAW_DATA 1 82 #define TEMP_TABLE_SIZE 256 83 84 #define SHUTDOWN_TEMP_MIN 55 85 #define SHUTDOWN_TEMP_MAX 85 86 87 #ifdef DEBUG 88 #define dbg_print(level, str) cmn_err(level, str); 89 #else 90 #define dbg_print(level, str) {; } 91 #endif 92 93 94 extern int nct_i2c_transfer(i2c_client_hdl_t i2c_hdl, i2c_transfer_t *i2c_tran); 95 static uchar_t _cpu_temps[TEMP_TABLE_SIZE + 4]; /* see attach */ 96 97 static void *pcf8591_soft_statep; 98 99 /* 100 * cb ops (only need ioctl) 101 */ 102 static int pcf8591_open(dev_t *, int, int, cred_t *); 103 static int pcf8591_close(dev_t, int, int, cred_t *); 104 static int pcf8591_read(dev_t dev, struct uio *uiop, cred_t *cred_p); 105 static int pcf8591_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 106 107 static struct cb_ops pcf8591_cbops = { 108 pcf8591_open, /* open */ 109 pcf8591_close, /* close */ 110 nodev, /* strategy */ 111 nodev, /* print */ 112 nodev, /* dump */ 113 pcf8591_read, /* read */ 114 nodev, /* write */ 115 pcf8591_ioctl, /* ioctl */ 116 nodev, /* devmap */ 117 nodev, /* mmap */ 118 nodev, /* segmap */ 119 nochpoll, /* poll */ 120 ddi_prop_op, /* cb_prop_op */ 121 NULL, /* streamtab */ 122 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 123 CB_REV, /* rev */ 124 nodev, /* int (*cb_aread)() */ 125 nodev /* int (*cb_awrite)() */ 126 }; 127 128 /* 129 * dev ops 130 */ 131 static int pcf8591_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 132 void **result); 133 static int pcf8591_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 134 static int pcf8591_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 135 136 /* kstat routines */ 137 static int pcf8591_add_kstats(struct pcf8591_unit *); 138 static void pcf8591_delete_kstats(struct pcf8591_unit *); 139 static int pcf8591_temp_kstat_update(kstat_t *, int); 140 static int pcf8591_read_chip(struct pcf8591_unit *, uint8_t, int); 141 static int pcf8591_read_props(struct pcf8591_unit *unitp); 142 143 static struct dev_ops pcf8591_ops = { 144 DEVO_REV, 145 0, 146 pcf8591_info, 147 nulldev, 148 nulldev, 149 pcf8591_attach, 150 pcf8591_detach, 151 nodev, 152 &pcf8591_cbops, 153 NULL, 154 NULL, 155 ddi_quiesce_not_supported, /* devo_quiesce */ 156 }; 157 158 extern struct mod_ops mod_driverops; 159 160 static struct modldrv pcf8591_modldrv = { 161 &mod_driverops, /* type of module - driver */ 162 "Netract pcf8591 (adio)", 163 &pcf8591_ops, 164 }; 165 166 static struct modlinkage pcf8591_modlinkage = { 167 MODREV_1, 168 &pcf8591_modldrv, 169 0 170 }; 171 172 int pcf8591_debug = 0x02; 173 static uint8_t translate_cputemp(uint8_t value); 174 175 int 176 _init(void) 177 { 178 register int error; 179 180 error = mod_install(&pcf8591_modlinkage); 181 if (error == 0) { 182 (void) ddi_soft_state_init(&pcf8591_soft_statep, 183 sizeof (struct pcf8591_unit), PCF8591_MAX_DEVS); 184 } 185 186 return (error); 187 } 188 189 int 190 _fini(void) 191 { 192 register int error; 193 194 error = mod_remove(&pcf8591_modlinkage); 195 if (error == 0) { 196 ddi_soft_state_fini(&pcf8591_soft_statep); 197 } 198 199 return (error); 200 } 201 202 int 203 _info(struct modinfo *modinfop) 204 { 205 return (mod_info(&pcf8591_modlinkage, modinfop)); 206 } 207 208 /*ARGSUSED*/ 209 static int 210 pcf8591_open(dev_t *devp, int flags, int otyp, cred_t *credp) 211 { 212 int err = 0; 213 struct pcf8591_unit *unitp; 214 minor_t minor = getminor(*devp); 215 216 int instance = PCF8591_MINOR_TO_DEVINST(minor); 217 int channel = PCF8591_MINOR_TO_CHANNEL(minor); 218 219 if (instance < 0) { 220 return (ENXIO); 221 } 222 223 unitp = (struct pcf8591_unit *) 224 ddi_get_soft_state(pcf8591_soft_statep, instance); 225 226 if (unitp == NULL) { 227 return (ENXIO); 228 } 229 230 if (otyp != OTYP_CHR) { 231 return (EINVAL); 232 } 233 234 mutex_enter(&unitp->umutex); 235 236 if (flags & FEXCL) { 237 if (unitp->pcf8591_oflag[channel] != 0) { 238 err = EBUSY; 239 } else { 240 unitp->pcf8591_oflag[channel] = FEXCL; 241 } 242 } else { 243 if (unitp->pcf8591_oflag[channel] == FEXCL) { 244 err = EBUSY; 245 } else { 246 unitp->pcf8591_oflag[channel] = FOPEN; 247 } 248 } 249 250 mutex_exit(&unitp->umutex); 251 252 return (err); 253 } 254 255 /*ARGSUSED*/ 256 static int 257 pcf8591_close(dev_t devp, int flags, int otyp, cred_t *credp) 258 { 259 struct pcf8591_unit *unitp; 260 minor_t minor = getminor(devp); 261 262 int instance = PCF8591_MINOR_TO_DEVINST(minor); 263 int channel = PCF8591_MINOR_TO_CHANNEL(minor); 264 265 #ifdef lint 266 flags = flags; 267 otyp = otyp; 268 #endif 269 270 if (instance < 0) { 271 return (ENXIO); 272 } 273 274 unitp = (struct pcf8591_unit *) 275 ddi_get_soft_state(pcf8591_soft_statep, instance); 276 277 if (unitp == NULL) { 278 return (ENXIO); 279 } 280 281 mutex_enter(&unitp->umutex); 282 283 unitp->pcf8591_oflag[channel] = 0; 284 285 mutex_exit(&unitp->umutex); 286 287 return (DDI_SUCCESS); 288 } 289 290 static int 291 pcf8591_io(dev_t dev, struct uio *uiop, int rw) 292 { 293 int err = 0; 294 struct pcf8591_unit *unitp; 295 minor_t minor = getminor(dev); 296 297 int instance = PCF8591_MINOR_TO_DEVINST(minor); 298 int channel = PCF8591_MINOR_TO_CHANNEL(minor); 299 300 int bytes_to_rw; 301 int translate = 0; 302 303 /* 304 * At this point we don't have a write operation to pcf8591. 305 */ 306 if (rw == B_WRITE) { 307 return (EACCES); 308 } 309 310 if (instance < 0) { 311 return (ENXIO); 312 } 313 314 unitp = (struct pcf8591_unit *) 315 ddi_get_soft_state(pcf8591_soft_statep, instance); 316 if (unitp == NULL) { 317 return (ENXIO); 318 } 319 320 if ((bytes_to_rw = uiop->uio_resid) > PCF8591_TRAN_SIZE) { 321 return (EINVAL); 322 } 323 324 /* 325 * Need to serialize all read operations, since there is a single 326 * i2c_transfer_t structure allocated for all read and write ops. 327 * We can't share the i2c bus among multiple transactions anyway, 328 * so this does not affect performance. 329 */ 330 mutex_enter(&unitp->umutex); 331 while (unitp->pcf8591_flags == PCF8591_BUSY) { 332 if (cv_wait_sig(&unitp->pcf8591_cv, &unitp->umutex) <= 0) { 333 mutex_exit(&unitp->umutex); 334 335 return (EINTR); 336 } 337 } 338 unitp->pcf8591_flags = PCF8591_BUSY; 339 mutex_exit(&unitp->umutex); 340 341 if (bytes_to_rw == 1) 342 translate = 1; 343 /* 344 * Event sequence: 345 * 1. set up the control register write, for now we'll always read 346 * channel 0, which is the only active 8591 port on the Nordica 347 * TODO: We'll need a minor node for each port that is used. 348 * 2. increment read count to read the throw-away byte 349 * 3. start the write/read of control/data registers 350 * 4. throw the first byte away 351 * 5. then return the data 352 */ 353 354 unitp->i2c_tran->i2c_flags = I2C_WR_RD; 355 unitp->i2c_tran->i2c_wlen = 1; 356 unitp->i2c_tran->i2c_wbuf[0] = (unitp->pcf8591_inprog | 357 channel); 358 /* 359 * read extra byte to throw away the first, (PCF8591 datasheet) 360 */ 361 unitp->i2c_tran->i2c_rlen = bytes_to_rw + 1; 362 363 if (nct_i2c_transfer(unitp->pcf8591_hdl, 364 unitp->i2c_tran) != I2C_SUCCESS) { 365 err = EIO; 366 } else { 367 /* 368 * Throw away the first byte according to PCF8591 datasheet 369 * If translating, use the second byte. 370 */ 371 if (translate) { 372 unitp->i2c_tran->i2c_rbuf[0] = 373 translate_cputemp(unitp->i2c_tran->i2c_rbuf[1]); 374 } else { 375 unitp->i2c_tran->i2c_rbuf[0] = 376 unitp->i2c_tran->i2c_rbuf[1]; 377 unitp->i2c_tran->i2c_rbuf[1] = 0; 378 } 379 380 err = uiomove(unitp->i2c_tran->i2c_rbuf, 381 bytes_to_rw, 382 UIO_READ, 383 uiop); 384 } 385 mutex_enter(&unitp->umutex); 386 unitp->pcf8591_flags = 0; 387 cv_signal(&unitp->pcf8591_cv); 388 mutex_exit(&unitp->umutex); 389 390 return (err); 391 } 392 393 /*ARGSUSED*/ 394 static int 395 pcf8591_read(dev_t dev, struct uio *uiop, cred_t *cred_p) 396 { 397 return (pcf8591_io(dev, uiop, B_READ)); 398 } 399 400 static int 401 call_copyin(caddr_t arg, struct pcf8591_unit *unitp, int mode) 402 { 403 uchar_t *wbuf; 404 uchar_t *rbuf; 405 i2c_transfer_t i2ct; 406 i2c_transfer_t *i2ctp = unitp->i2c_tran; 407 408 409 if (ddi_copyin((void *)arg, (caddr_t)&i2ct, 410 sizeof (i2c_transfer_t), mode) != DDI_SUCCESS) { 411 return (I2C_FAILURE); 412 } 413 414 /* 415 * Save the read and write buffer pointers in the transfer 416 * structure, otherwise these will get overwritten when we 417 * do a bcopy. Restore once done. 418 */ 419 420 wbuf = i2ctp->i2c_wbuf; 421 rbuf = i2ctp->i2c_rbuf; 422 423 bcopy(&i2ct, i2ctp, sizeof (i2c_transfer_t)); 424 425 i2ctp->i2c_wbuf = wbuf; 426 i2ctp->i2c_rbuf = rbuf; 427 428 /* 429 * copyin the read and write buffers to the saved buffers. 430 */ 431 432 if (i2ct.i2c_wlen != 0) { 433 if (ddi_copyin(i2ct.i2c_wbuf, (caddr_t)i2ctp->i2c_wbuf, 434 i2ct.i2c_wlen, mode) != DDI_SUCCESS) { 435 return (I2C_FAILURE); 436 } 437 } 438 439 return (I2C_SUCCESS); 440 } 441 442 static int 443 call_copyout(caddr_t arg, struct pcf8591_unit *unitp, int mode) 444 { 445 i2c_transfer_t i2ct; 446 i2c_transfer_t *i2ctp = unitp->i2c_tran; 447 uint16_t i2c_actlen; 448 449 /* 450 * We will copyout the last three fields only, skipping 451 * the remaining ones, before copying the rbuf to the 452 * user buffer. 453 */ 454 455 int uskip = sizeof (i2c_transfer_t) - 3*sizeof (int16_t), 456 kskip = sizeof (i2c_transfer_t) - 3*sizeof (int16_t); 457 458 /* 459 * First copyin the user structure to the temporary i2ct, 460 * so that we have the wbuf and rbuf addresses in it. 461 */ 462 463 uskip = sizeof (i2c_transfer_t) - 3 * (sizeof (uint16_t)); 464 465 /* 466 * copyout the last three out fields now. 467 */ 468 469 if (ddi_copyout((void *)((intptr_t)i2ctp+kskip), (void *) 470 ((intptr_t)arg + uskip), 3*sizeof (uint16_t), mode) 471 != DDI_SUCCESS) { 472 return (I2C_FAILURE); 473 } 474 475 /* 476 * In case we have something to write, get the address of the read 477 * buffer. 478 */ 479 480 if (i2ctp->i2c_rlen - i2ctp->i2c_r_resid > 0) { 481 482 if (ddi_copyin((void *)arg, &i2ct, 483 sizeof (i2c_transfer_t), mode) != DDI_SUCCESS) { 484 return (I2C_FAILURE); 485 } 486 487 /* 488 * copyout the read buffer to the saved user buffer in i2ct. 489 */ 490 491 i2c_actlen = i2ctp->i2c_rlen - i2ctp->i2c_r_resid; 492 if (ddi_copyout(i2ctp->i2c_rbuf, i2ct.i2c_rbuf, 493 i2c_actlen, mode) != DDI_SUCCESS) { 494 return (I2C_FAILURE); 495 } 496 } 497 498 return (I2C_SUCCESS); 499 } 500 501 /* 502 * The ioctls will use the same name as the Javelin ioctls. We 503 * will have a very restricted set for MC, and unlike Javelin 504 * will not have a envctrl_chip structure to return values 505 * from the driver. All we will have is a uint8_t value to 506 * get or set values from the driver. Also, unlike the Javelin, 507 * where 'index' is used to specify the input port from where 508 * temperature is collected, here different minor nodes will be 509 * created by the driver for each port, eliminating the need for 510 * 'index' - leaving us with only the value to pass. 511 */ 512 513 /*ARGSUSED*/ 514 static int 515 pcf8591_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 516 cred_t *credp, int *rvalp) 517 { 518 int err = 0; 519 struct pcf8591_unit *unitp; 520 minor_t minor = getminor(dev); 521 522 int instance = PCF8591_MINOR_TO_DEVINST(minor); 523 int channel = PCF8591_MINOR_TO_CHANNEL(minor); 524 525 unitp = (struct pcf8591_unit *) 526 ddi_get_soft_state(pcf8591_soft_statep, instance); 527 528 mutex_enter(&unitp->umutex); 529 while (unitp->pcf8591_flags == PCF8591_BUSY) { 530 if (cv_wait_sig(&unitp->pcf8591_cv, &unitp->umutex) <= 0) { 531 mutex_exit(&unitp->umutex); 532 533 return (EINTR); 534 } 535 } 536 unitp->pcf8591_flags = PCF8591_BUSY; 537 mutex_exit(&unitp->umutex); 538 539 switch (cmd) { 540 541 case ENVC_IOC_GETTEMP: { 542 /* 543 * Read the status byte from pcf8591 chip. The value will 544 * be already converted to Celcius by translate_cputemp. 545 */ 546 (void) pcf8591_read_chip(unitp, channel, 1); 547 if (ddi_copyout(unitp->i2c_tran->i2c_rbuf, 548 (caddr_t)arg, sizeof (uint8_t), mode) != DDI_SUCCESS) { 549 err = EFAULT; 550 } 551 break; 552 } 553 554 case ENVC_IOC_GETMODE: { 555 uint8_t curr_mode = unitp->current_mode; 556 557 if (ddi_copyout((caddr_t)&curr_mode, (caddr_t)arg, 558 sizeof (uint8_t), mode) != DDI_SUCCESS) { 559 err = EFAULT; 560 } 561 break; 562 } 563 564 case ENVC_IOC_SETMODE: { 565 uint8_t curr_mode; 566 if (ddi_copyin((caddr_t)arg, (caddr_t)&curr_mode, 567 sizeof (uint8_t), mode) != DDI_SUCCESS) { 568 err = EFAULT; 569 break; 570 } 571 if (curr_mode == ENVCTRL_DIAG_MODE || 572 curr_mode == ENVCTRL_NORMAL_MODE) { 573 unitp->current_mode = curr_mode; /* Don't do anything */ 574 } 575 break; 576 } 577 578 /* Testing, may be removed */ 579 case I2CDEV_TRAN: 580 if (call_copyin((caddr_t)arg, unitp, mode) != I2C_SUCCESS) { 581 err = EFAULT; 582 break; 583 } 584 if (nct_i2c_transfer(unitp->pcf8591_hdl, unitp->i2c_tran) 585 != I2C_SUCCESS) { 586 err = EFAULT; 587 break; 588 } 589 if (call_copyout((caddr_t)arg, unitp, mode) != I2C_SUCCESS) { 590 err = EFAULT; 591 break; 592 } 593 break; 594 595 /* 596 * TESTING TRANSLATION from "adc" "table" property 597 * translate thermistor index into temp Celcius 598 */ 599 case I2CDEV_GETTEMP: { 600 struct i2c_transfer *tp; 601 if (call_copyin((caddr_t)arg, unitp, mode) != I2C_SUCCESS) { 602 err = EFAULT; 603 break; 604 } 605 tp = unitp->i2c_tran; 606 if (tp->i2c_rlen != 1) { 607 err = EINVAL; 608 break; 609 } 610 /* 611 * Throw away the first byte according to PCF8591 datasheet, 612 * so read two bytes 613 */ 614 tp->i2c_rlen = 2; 615 if (nct_i2c_transfer(unitp->pcf8591_hdl, unitp->i2c_tran) 616 != I2C_SUCCESS) { 617 err = EFAULT; 618 break; 619 } 620 #ifdef DEBUG 621 if (pcf8591_debug & 0x0010) 622 cmn_err(CE_NOTE, 623 "pcf8591_ioctl: i2c_rlen=%d; " 624 "i2c_rbuf[0,1]=0x%x,0x%x\n", 625 tp->i2c_rlen, tp->i2c_rbuf[0], tp->i2c_rbuf[1]); 626 #endif /* DEBUG */ 627 /* 628 * Throw away the first byte according to PCF8591 datasheet 629 */ 630 if ((tp->i2c_rbuf[0] = translate_cputemp(tp->i2c_rbuf[1])) 631 == 0) { 632 err = EINVAL; 633 break; 634 } 635 tp->i2c_rbuf[1] = 0; 636 637 if (call_copyout((caddr_t)arg, unitp, mode) != I2C_SUCCESS) { 638 err = EFAULT; 639 break; 640 } 641 break; 642 } 643 644 case I2CDEV_GETTABLES: { 645 break; 646 } 647 default: 648 err = EINVAL; 649 } 650 651 mutex_enter(&unitp->umutex); 652 unitp->pcf8591_flags = 0; 653 cv_signal(&unitp->pcf8591_cv); 654 mutex_exit(&unitp->umutex); 655 656 return (err); 657 } 658 659 static int 660 pcf8591_do_detach(dev_info_t *dip) 661 { 662 register struct pcf8591_unit *unitp; 663 int instance; 664 uint_t attach_flag; 665 666 instance = ddi_get_instance(dip); 667 unitp = ddi_get_soft_state(pcf8591_soft_statep, instance); 668 attach_flag = unitp->attach_flag; 669 670 if (attach_flag & PCF8591_KSTAT_INIT) { 671 pcf8591_delete_kstats(unitp); 672 } 673 674 if (attach_flag & PCF8591_LOCK_INIT) { 675 mutex_destroy(&unitp->umutex); 676 cv_destroy(&unitp->pcf8591_cv); 677 } 678 679 /* 680 * Restore the lengths of the rbuf and wbuf, which was originally 681 * allocated so that the appropriate amount of rbuf and wbuf are 682 * freed. 683 */ 684 if (attach_flag & PCF8591_ALLOC_TRANSFER) { 685 unitp->i2c_tran->i2c_wlen = MAX_WLEN; 686 unitp->i2c_tran->i2c_rlen = MAX_RLEN; 687 i2c_transfer_free(unitp->pcf8591_hdl, unitp->i2c_tran); 688 } 689 690 if (attach_flag & PCF8591_REGISTER_CLIENT) { 691 i2c_client_unregister(unitp->pcf8591_hdl); 692 } 693 694 if (attach_flag & PCF8591_MINORS_CREATED) { 695 ddi_remove_minor_node(dip, NULL); 696 } 697 698 /* 699 * Free the memory allocated for the properties. 700 */ 701 if (attach_flag & PCF8591_PROPS_READ) { 702 ddi_prop_free(unitp->props.name); 703 if (unitp->props.num_chans_used) { 704 ddi_prop_free(unitp->props.channels_in_use); 705 } 706 707 if (unitp->props.channels_description) { 708 ddi_prop_free(unitp->props.channels_description); 709 } 710 } 711 712 if (attach_flag & PCF8591_SOFT_STATE_ALLOC) { 713 ddi_soft_state_free(pcf8591_soft_statep, instance); 714 } 715 716 return (DDI_SUCCESS); 717 } 718 719 static int 720 pcf8591_do_suspend(dev_info_t *dip) 721 { 722 int instance = ddi_get_instance(dip); 723 struct pcf8591_unit *unitp = (struct pcf8591_unit *) 724 ddi_get_soft_state(pcf8591_soft_statep, instance); 725 726 if (unitp == NULL) { 727 return (ENXIO); 728 } 729 730 /* 731 * Set the busy flag so that future transactions block 732 * until resume. 733 */ 734 mutex_enter(&unitp->umutex); 735 while (unitp->pcf8591_flags == PCF8591_BUSY) { 736 if (cv_wait_sig(&unitp->pcf8591_cv, 737 &unitp->umutex) <= 0) { 738 mutex_exit(&unitp->umutex); 739 740 return (DDI_FAILURE); 741 } 742 } 743 unitp->pcf8591_flags = PCF8591_BUSY; 744 mutex_exit(&unitp->umutex); 745 746 return (DDI_SUCCESS); 747 } 748 749 static int 750 pcf8591_do_resume(dev_info_t *dip) 751 { 752 int instance = ddi_get_instance(dip); 753 struct pcf8591_unit *unitp = (struct pcf8591_unit *) 754 ddi_get_soft_state(pcf8591_soft_statep, instance); 755 if (unitp == NULL) { 756 return (ENXIO); 757 } 758 759 mutex_enter(&unitp->umutex); 760 unitp->pcf8591_flags = 0; 761 cv_signal(&unitp->pcf8591_cv); 762 mutex_exit(&unitp->umutex); 763 764 return (DDI_SUCCESS); 765 } 766 767 static int 768 pcf8591_do_attach(dev_info_t *dip) 769 { 770 register struct pcf8591_unit *unitp; 771 int i, instance; 772 char name[MAXNAMELEN]; 773 minor_t minor; 774 775 instance = ddi_get_instance(dip); 776 777 if (ddi_soft_state_zalloc(pcf8591_soft_statep, instance) != 0) { 778 return (DDI_FAILURE); 779 } 780 781 unitp = ddi_get_soft_state(pcf8591_soft_statep, instance); 782 783 if (unitp == NULL) { 784 return (DDI_FAILURE); 785 } 786 787 unitp->dip = dip; 788 789 unitp->attach_flag = PCF8591_SOFT_STATE_ALLOC; 790 791 if (pcf8591_read_props(unitp) != DDI_PROP_SUCCESS) { 792 (void) pcf8591_do_detach(dip); 793 return (DDI_FAILURE); 794 } 795 796 unitp->attach_flag |= PCF8591_PROPS_READ; 797 798 /* 799 * Set the current operating mode to NORMAL_MODE. 800 */ 801 unitp->current_mode = ENVCTRL_NORMAL_MODE; /* normal mode */ 802 803 (void) snprintf(unitp->pcf8591_name, PCF8591_NAMELEN, 804 "%s%d", ddi_driver_name(dip), instance); 805 806 /* 807 * Create a minor node corresponding to channel 0 to 3 808 */ 809 for (i = 0; i < PCF8591_MAX_CHANS; i++) { 810 if (i == 0) { 811 (void) sprintf(name, "cputemp"); 812 } else { 813 (void) sprintf(name, "%d", i); 814 } 815 minor = PCF8591_MINOR_NUM(instance, i); 816 if (ddi_create_minor_node(dip, name, S_IFCHR, minor, 817 PCF8591_NODE_TYPE, NULL) == DDI_FAILURE) { 818 ddi_remove_minor_node(dip, NULL); 819 (void) pcf8591_do_detach(dip); 820 return (DDI_FAILURE); 821 } 822 } 823 824 unitp->attach_flag |= PCF8591_MINORS_CREATED; 825 826 if (i2c_client_register(dip, &unitp->pcf8591_hdl) 827 != I2C_SUCCESS) { 828 (void) pcf8591_do_detach(dip); 829 return (DDI_FAILURE); 830 } 831 832 unitp->attach_flag |= PCF8591_REGISTER_CLIENT; 833 834 /* 835 * We allocate a single i2c_transfer_t structure for all 836 * i2c transactions. 837 */ 838 if (i2c_transfer_alloc(unitp->pcf8591_hdl, &unitp->i2c_tran, 839 MAX_WLEN, MAX_RLEN, KM_SLEEP) != I2C_SUCCESS) { 840 (void) pcf8591_do_detach(dip); 841 return (DDI_FAILURE); 842 } 843 844 unitp->attach_flag |= PCF8591_ALLOC_TRANSFER; 845 846 /* 847 * The flags will be set to I2C_WR because for all reads from 848 * the 8591 we need to also write the control byte. 849 */ 850 unitp->i2c_tran->i2c_flags = I2C_WR; 851 unitp->i2c_tran->i2c_version = I2C_XFER_REV; 852 853 854 /* 855 * Set the analog programming mode to default. Upper nibble 856 * in control byte. Four single ended inputs, output not enabled. 857 */ 858 unitp->pcf8591_inprog = PCF8591_4SINGLE | PCF8591_ANALOG_INPUT_EN; 859 860 /* 861 * Set the open flag for each channel to 0. 862 */ 863 for (i = 0; i < PCF8591_MAX_CHANS; i++) { 864 unitp->pcf8591_oflag[i] = 0; 865 } 866 867 /* 868 * Set the busy flag to 0. 869 */ 870 unitp->pcf8591_flags = 0; 871 872 mutex_init(&unitp->umutex, NULL, MUTEX_DRIVER, NULL); 873 cv_init(&unitp->pcf8591_cv, NULL, CV_DRIVER, NULL); 874 875 unitp->attach_flag |= PCF8591_LOCK_INIT; 876 877 if (pcf8591_add_kstats(unitp) != DDI_SUCCESS) { 878 (void) pcf8591_do_detach(dip); 879 return (DDI_FAILURE); 880 } 881 882 unitp->attach_flag |= PCF8591_KSTAT_INIT; 883 884 ddi_report_dev(dip); 885 886 return (DDI_SUCCESS); 887 } 888 889 /* ARGSUSED */ 890 static int 891 pcf8591_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 892 { 893 dev_t dev; 894 int instance; 895 896 if (infocmd == DDI_INFO_DEVT2INSTANCE) { 897 dev = (dev_t)arg; 898 instance = PCF8591_MINOR_TO_DEVINST(getminor(dev)); 899 *result = (void *)(uintptr_t)instance; 900 return (DDI_SUCCESS); 901 } 902 return (DDI_FAILURE); 903 } 904 905 static int 906 pcf8591_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 907 { 908 switch (cmd) { 909 case DDI_ATTACH: 910 return (pcf8591_do_attach(dip)); 911 case DDI_RESUME: 912 return (pcf8591_do_resume(dip)); 913 default: 914 return (DDI_FAILURE); 915 } 916 } 917 918 static int 919 pcf8591_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 920 { 921 switch (cmd) { 922 case DDI_DETACH: 923 return (pcf8591_do_detach(dip)); 924 case DDI_SUSPEND: 925 return (pcf8591_do_suspend(dip)); 926 default: 927 return (DDI_FAILURE); 928 } 929 } 930 931 static uint8_t 932 translate_cputemp(uint8_t value) 933 { 934 return (_cpu_temps[value]); 935 } 936 937 static int 938 pcf8591_add_kstats(struct pcf8591_unit *unitp) 939 { 940 if ((unitp->tempksp = kstat_create(I2C_PCF8591_NAME, 941 unitp->instance, I2C_KSTAT_CPUTEMP, "misc", 942 KSTAT_TYPE_RAW, sizeof (unitp->temp_kstats), 943 KSTAT_FLAG_PERSISTENT | KSTAT_FLAG_WRITABLE)) == NULL) { 944 945 return (DDI_FAILURE); 946 } 947 948 /* 949 * The kstat fields are already initialized in the attach routine.. 950 */ 951 952 unitp->tempksp->ks_update = pcf8591_temp_kstat_update; 953 unitp->tempksp->ks_private = (void *)unitp; 954 955 (void) strcpy(unitp->temp_kstats.label, 956 unitp->props.channels_description[0]); 957 unitp->temp_kstats.type = ENVC_NETRACT_CPU_SENSOR; 958 959 kstat_install(unitp->tempksp); 960 961 return (DDI_SUCCESS); 962 } 963 964 static void 965 pcf8591_delete_kstats(struct pcf8591_unit *unitp) 966 { 967 kstat_delete(unitp->tempksp); 968 } 969 970 static int 971 pcf8591_temp_kstat_update(kstat_t *ksp, int rw) 972 { 973 struct pcf8591_unit *unitp; 974 char *kstatp; 975 int err = 0; 976 int channel = 0; 977 int warn_temp = 0; 978 int shutdown_temp = 0; 979 980 unitp = (struct pcf8591_unit *)ksp->ks_private; 981 982 mutex_enter(&unitp->umutex); 983 while (unitp->pcf8591_flags == PCF8591_BUSY) { 984 if (cv_wait_sig(&unitp->pcf8591_cv, 985 &unitp->umutex) <= 0) { 986 mutex_exit(&unitp->umutex); 987 988 return (EINTR); 989 } 990 } 991 992 unitp->pcf8591_flags = PCF8591_BUSY; 993 mutex_exit(&unitp->umutex); 994 995 kstatp = (char *)ksp->ks_data; 996 997 if (rw == KSTAT_WRITE) { 998 999 /* check for the size of buffer */ 1000 if (ksp->ks_data_size != sizeof (unitp->temp_kstats)) { 1001 err = EIO; 1002 goto bail; 1003 } 1004 1005 warn_temp = ((envctrl_temp_t *)kstatp)->warning_threshold; 1006 shutdown_temp = ((envctrl_temp_t *)kstatp)->shutdown_threshold; 1007 1008 if (shutdown_temp < SHUTDOWN_TEMP_MIN || shutdown_temp > 1009 SHUTDOWN_TEMP_MAX) { 1010 err = EIO; 1011 goto bail; 1012 } 1013 1014 if (warn_temp < 0 || shutdown_temp <= warn_temp) { 1015 err = EIO; 1016 goto bail; 1017 } 1018 1019 /* write into kstat fields */ 1020 unitp->temp_kstats.warning_threshold = warn_temp; 1021 unitp->temp_kstats.shutdown_threshold = shutdown_temp; 1022 1023 } else { 1024 (void) pcf8591_read_chip(unitp, channel, 1); 1025 unitp->temp_kstats.value = 1026 unitp->i2c_tran->i2c_rbuf[0]; 1027 bcopy((caddr_t)&unitp->temp_kstats, kstatp, 1028 sizeof (unitp->temp_kstats)); 1029 } 1030 1031 bail: 1032 1033 mutex_enter(&unitp->umutex); 1034 unitp->pcf8591_flags = 0; 1035 cv_signal(&unitp->pcf8591_cv); 1036 mutex_exit(&unitp->umutex); 1037 1038 return (err); 1039 } 1040 1041 static int 1042 pcf8591_read_chip(struct pcf8591_unit *unitp, uint8_t channel, 1043 int size) 1044 { 1045 int retval = I2C_SUCCESS; 1046 1047 /* 1048 * We need to read an extra byte, since as per specification 1049 * the first byte read should be discarded. 1050 */ 1051 i2c_transfer_t *tp = unitp->i2c_tran; 1052 tp->i2c_flags = I2C_WR_RD; 1053 tp->i2c_rlen = size+1; 1054 tp->i2c_wlen = 1; 1055 tp->i2c_wbuf[0] = (unitp->pcf8591_inprog | 1056 channel); 1057 1058 retval = nct_i2c_transfer(unitp->pcf8591_hdl, tp); 1059 if (retval == I2C_SUCCESS) { 1060 tp->i2c_rbuf[0] = translate_cputemp(tp->i2c_rbuf[1]); 1061 } 1062 1063 if (tp->i2c_rbuf[0] == 0) { 1064 retval = I2C_FAILURE; 1065 } 1066 1067 return (retval); 1068 } 1069 1070 /* 1071 * Reads the properties of the pcf8591 device. 1072 */ 1073 static int 1074 pcf8591_read_props(struct pcf8591_unit *unitp) 1075 { 1076 dev_info_t *dip = unitp->dip; 1077 int i, retval = 0, prop_len; 1078 int instance = ddi_get_instance(dip); 1079 int warning_temp, shutdown_temp; 1080 uint32_t *prop_value = NULL; 1081 uchar_t *creg_prop; 1082 char *function; 1083 uint_t tblsz; 1084 1085 #ifdef lint 1086 instance = instance; 1087 #endif 1088 /* 1089 * Check for the pcf8591_function property, and make sure it's 1090 * cputemp. 1091 */ 1092 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1093 "pcf8591_function", &function) != DDI_SUCCESS) { 1094 dbg_print(CE_WARN, "Couldn't find pcf8591_function property"); 1095 1096 return (DDI_FAILURE); 1097 } 1098 1099 if (strcmp(function, "cputemp") != 0) { 1100 dbg_print(CE_WARN, "pcf8591_function is not cputemp"); 1101 ddi_prop_free(function); 1102 1103 return (DDI_FAILURE); 1104 } 1105 1106 ddi_prop_free(function); 1107 1108 retval = ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1109 "name", &unitp->props.name); 1110 if (retval != DDI_PROP_SUCCESS) { 1111 1112 return (retval); 1113 } 1114 #ifdef DEBUG 1115 else if (pcf8591_debug & 0x02) 1116 cmn_err(CE_NOTE, 1117 "pcf8591_read_props:ddi_prop_lookup_string(%s): \ 1118 found %s ", "name", unitp->props.name); 1119 #endif /* DEBUG */ 1120 1121 retval = ddi_getlongprop(DDI_DEV_T_ANY, dip, 1122 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, 1123 "reg", (caddr_t)&prop_value, &prop_len); 1124 if (retval == DDI_PROP_SUCCESS) { 1125 unitp->props.i2c_bus = (uint16_t)prop_value[0]; 1126 unitp->props.slave_address = (uint16_t)prop_value[1]; 1127 kmem_free(prop_value, prop_len); 1128 #ifdef DEBUG 1129 if (pcf8591_debug & 0x02) 1130 cmn_err(CE_NOTE, 1131 "pcf8591:ddi_getlongprop(%s) returns %d," 1132 " i2c_bus,slave=0x%x,0x%x", 1133 "reg", retval, unitp->props.i2c_bus, 1134 unitp->props.slave_address); 1135 #endif /* DEBUG */ 1136 } else { 1137 unitp->props.i2c_bus = (uint16_t)-1; 1138 unitp->props.slave_address = (uint16_t)-1; 1139 #ifdef DEBUG 1140 cmn_err(CE_WARN, 1141 "pcf8591_read_props:ddi_getlongprop(%s) returns %d," 1142 " default it to 0x%x:0x%X", 1143 "reg", retval, unitp->props.i2c_bus, 1144 unitp->props.slave_address); 1145 #endif /* DEBUG */ 1146 } 1147 (void) ddi_getproplen(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1148 "channels-in-use", &prop_len); 1149 retval = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, 1150 dip, DDI_PROP_DONTPASS, 1151 "channels-in-use", 1152 (uchar_t **)&unitp->props.channels_in_use, 1153 &unitp->props.num_chans_used); 1154 if (retval == DDI_PROP_SUCCESS) { 1155 unitp->props.num_chans_used /= sizeof (pcf8591_channel_t); 1156 } else { 1157 unitp->props.num_chans_used = 0; 1158 } 1159 1160 #ifdef DEBUG 1161 if (pcf8591_debug & 0x0002) 1162 cmn_err(CE_NOTE, 1163 "pcf8591_read_props:ddi_prop_lookup_byte_array(%s)" 1164 "returns %d\n" 1165 "\t\tlength=%d, #elements=%d", 1166 "channels-in-use", retval, 1167 prop_len, unitp->props.num_chans_used); 1168 #endif /* DEBUG */ 1169 1170 retval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, 1171 DDI_PROP_DONTPASS, "channels-description", 1172 (char ***)&unitp->props.channels_description, 1173 (uint_t *)&prop_len); 1174 1175 if (retval != DDI_PROP_SUCCESS) { 1176 prop_len = 0; 1177 unitp->props.channels_description = NULL; 1178 } 1179 1180 #ifdef DEBUG 1181 if (pcf8591_debug & 0x0002) { 1182 cmn_err(CE_NOTE, 1183 "pcf8591_read_props:ddi_prop_lookup_string_array(%s)" 1184 "returns %d, length=%d", 1185 "channels-description", retval, prop_len); 1186 for (i = 0; i < prop_len; ++i) { 1187 cmn_err(CE_NOTE, "channels-description[%d]=<%s>", 1188 i, unitp->props.channels_description[i]); 1189 } 1190 } 1191 #endif /* DEBUG */ 1192 1193 /* 1194 * The following code was borrowed from envctrltwo.c 1195 * I haven't yet investigated why the copy target is index + 2 1196 */ 1197 retval = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 1198 DDI_PROP_DONTPASS, "tables", &creg_prop, (uint_t *)&prop_len); 1199 1200 if (retval != DDI_PROP_SUCCESS) { 1201 #ifdef DEBUG 1202 cmn_err(CE_WARN, "%s%d: Unable to read pcf8591 tables property", 1203 ddi_get_name(dip), instance); 1204 #endif /* DEBUG */ 1205 1206 return (DDI_NOT_WELL_FORMED); 1207 } 1208 1209 tblsz = (sizeof (_cpu_temps) / sizeof (uchar_t)); 1210 if (prop_len <= tblsz) { 1211 for (i = 0; i < prop_len; i++) { 1212 _cpu_temps[i] = creg_prop[i]; 1213 } 1214 } 1215 #ifdef DEBUG 1216 if (pcf8591_debug & 0x0002) 1217 cmn_err(CE_NOTE, "pcf8591_read_props: _cpu_temps size=%d; " 1218 "tables prop_len=%d\n", tblsz, prop_len); 1219 #endif /* DEBUG */ 1220 1221 ddi_prop_free(creg_prop); 1222 1223 /* 1224 * Read shutdown temp and warning temp properties. 1225 */ 1226 warning_temp = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 1227 DDI_PROP_DONTPASS, "warning-temp", PCF8591_WARNING_TEMP); 1228 1229 shutdown_temp = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 1230 DDI_PROP_DONTPASS, "shutdown-temp", PCF8591_SHUTDOWN_TEMP); 1231 1232 /* 1233 * Fill up the warning and shutdown temp values in kstat structure. 1234 */ 1235 unitp->temp_kstats.warning_threshold = warning_temp; 1236 unitp->temp_kstats.shutdown_threshold = shutdown_temp; 1237 1238 return (DDI_PROP_SUCCESS); 1239 }