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