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