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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 31 32 /* 33 * I2C leaf driver for the PCF8591 34 */ 35 36 #include <sys/param.h> 37 #include <sys/types.h> 38 #include <sys/signal.h> 39 #include <sys/errno.h> 40 #include <sys/file.h> 41 #include <sys/termio.h> 42 #include <sys/termios.h> 43 #include <sys/cmn_err.h> 44 #include <sys/stream.h> 45 #include <sys/strsun.h> 46 #include <sys/stropts.h> 47 #include <sys/strtty.h> 48 #include <sys/debug.h> 49 #include <sys/eucioctl.h> 50 #include <sys/cred.h> 51 #include <sys/uio.h> 52 #include <sys/stat.h> 53 #include <sys/kmem.h> 54 55 #include <sys/ddi.h> 56 #include <sys/sunddi.h> 57 #include <sys/obpdefs.h> 58 #include <sys/conf.h> 59 #include <sys/modctl.h> 60 #include <sys/stat.h> 61 #include <sys/open.h> 62 #include <sys/uio.h> 63 64 #include <sys/i2c/misc/i2c_svc.h> 65 #include <sys/envctrl_gen.h> 66 #include <sys/netract_gen.h> 67 #include <sys/pcf8591_nct.h> 68 69 70 /* 71 * CONTROL OF CHIP 72 * PCF8591 Temp sensing control register definitions 73 * 74 * --------------------------------------------- 75 * | 0 | AOE | X | X | 0 | AIF | X | X | 76 * --------------------------------------------- 77 * AOE = Analog out enable.. not used on out implementation 78 * 5 & 4 = Analog Input Programming.. see data sheet for bits.. 79 * 80 * AIF = Auto increment flag 81 * bits 1 & 0 are for the Chennel number. 82 */ 83 84 85 #define I2CTRANS_DATA 0 86 #define I2CRAW_DATA 1 87 #define TEMP_TABLE_SIZE 256 88 89 #define SHUTDOWN_TEMP_MIN 55 90 #define SHUTDOWN_TEMP_MAX 85 91 92 #ifdef DEBUG 93 #define dbg_print(level, str) cmn_err(level, str); 94 #else 95 #define dbg_print(level, str) {; } 96 #endif 97 98 99 extern int nct_i2c_transfer(i2c_client_hdl_t i2c_hdl, i2c_transfer_t *i2c_tran); 100 static uchar_t _cpu_temps[TEMP_TABLE_SIZE + 4]; /* see attach */ 101 102 static void *pcf8591_soft_statep; 103 104 /* 105 * cb ops (only need ioctl) 106 */ 107 static int pcf8591_open(dev_t *, int, int, cred_t *); 108 static int pcf8591_close(dev_t, int, int, cred_t *); 109 static int pcf8591_read(dev_t dev, struct uio *uiop, cred_t *cred_p); 110 static int pcf8591_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 111 112 static struct cb_ops pcf8591_cbops = { 113 pcf8591_open, /* open */ 114 pcf8591_close, /* close */ 115 nodev, /* strategy */ 116 nodev, /* print */ 117 nodev, /* dump */ 118 pcf8591_read, /* read */ 119 nodev, /* write */ 120 pcf8591_ioctl, /* ioctl */ 121 nodev, /* devmap */ 122 nodev, /* mmap */ 123 nodev, /* segmap */ 124 nochpoll, /* poll */ 125 ddi_prop_op, /* cb_prop_op */ 126 NULL, /* streamtab */ 127 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 128 CB_REV, /* rev */ 129 nodev, /* int (*cb_aread)() */ 130 nodev /* int (*cb_awrite)() */ 131 }; 132 133 /* 134 * dev ops 135 */ 136 static int pcf8591_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 137 void **result); 138 static int pcf8591_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 139 static int pcf8591_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 140 141 /* kstat routines */ 142 static int pcf8591_add_kstats(struct pcf8591_unit *); 143 static void pcf8591_delete_kstats(struct pcf8591_unit *); 144 static int pcf8591_temp_kstat_update(kstat_t *, int); 145 static int pcf8591_read_chip(struct pcf8591_unit *, uint8_t, int); 146 static int pcf8591_read_props(struct pcf8591_unit *unitp); 147 148 static struct dev_ops pcf8591_ops = { 149 DEVO_REV, 150 0, 151 pcf8591_info, 152 nulldev, 153 nulldev, 154 pcf8591_attach, 155 pcf8591_detach, 156 nodev, 157 &pcf8591_cbops, 158 NULL 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) %I% ", 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; i2c_rbuf[0,1]=0x%x,0x%x\n", 629 tp->i2c_rlen, tp->i2c_rbuf[0], tp->i2c_rbuf[1]); 630 #endif /* DEBUG */ 631 /* 632 * Throw away the first byte according to PCF8591 datasheet 633 */ 634 if ((tp->i2c_rbuf[0] = translate_cputemp(tp->i2c_rbuf[1])) 635 == 0) { 636 err = EINVAL; 637 break; 638 } 639 tp->i2c_rbuf[1] = 0; 640 641 if (call_copyout((caddr_t)arg, unitp, mode) != I2C_SUCCESS) { 642 err = EFAULT; 643 break; 644 } 645 break; 646 } 647 648 case I2CDEV_GETTABLES: { 649 break; 650 } 651 default: 652 err = EINVAL; 653 } 654 655 mutex_enter(&unitp->umutex); 656 unitp->pcf8591_flags = 0; 657 cv_signal(&unitp->pcf8591_cv); 658 mutex_exit(&unitp->umutex); 659 660 return (err); 661 } 662 663 static int 664 pcf8591_do_detach(dev_info_t *dip) 665 { 666 register struct pcf8591_unit *unitp; 667 int instance; 668 uint_t attach_flag; 669 670 instance = ddi_get_instance(dip); 671 unitp = ddi_get_soft_state(pcf8591_soft_statep, instance); 672 attach_flag = unitp->attach_flag; 673 674 if (attach_flag & PCF8591_KSTAT_INIT) { 675 pcf8591_delete_kstats(unitp); 676 } 677 678 if (attach_flag & PCF8591_LOCK_INIT) { 679 mutex_destroy(&unitp->umutex); 680 cv_destroy(&unitp->pcf8591_cv); 681 } 682 683 /* 684 * Restore the lengths of the rbuf and wbuf, which was originally 685 * allocated so that the appropriate amount of rbuf and wbuf are 686 * freed. 687 */ 688 if (attach_flag & PCF8591_ALLOC_TRANSFER) { 689 unitp->i2c_tran->i2c_wlen = MAX_WLEN; 690 unitp->i2c_tran->i2c_rlen = MAX_RLEN; 691 i2c_transfer_free(unitp->pcf8591_hdl, unitp->i2c_tran); 692 } 693 694 if (attach_flag & PCF8591_REGISTER_CLIENT) { 695 i2c_client_unregister(unitp->pcf8591_hdl); 696 } 697 698 if (attach_flag & PCF8591_MINORS_CREATED) { 699 ddi_remove_minor_node(dip, NULL); 700 } 701 702 /* 703 * Free the memory allocated for the properties. 704 */ 705 if (attach_flag & PCF8591_PROPS_READ) { 706 ddi_prop_free(unitp->props.name); 707 if (unitp->props.num_chans_used) { 708 ddi_prop_free(unitp->props.channels_in_use); 709 } 710 711 if (unitp->props.channels_description) { 712 ddi_prop_free(unitp->props.channels_description); 713 } 714 } 715 716 if (attach_flag & PCF8591_SOFT_STATE_ALLOC) { 717 ddi_soft_state_free(pcf8591_soft_statep, instance); 718 } 719 720 return (DDI_SUCCESS); 721 } 722 723 static int 724 pcf8591_do_suspend(dev_info_t *dip) 725 { 726 int instance = ddi_get_instance(dip); 727 struct pcf8591_unit *unitp = (struct pcf8591_unit *) 728 ddi_get_soft_state(pcf8591_soft_statep, instance); 729 730 if (unitp == NULL) { 731 return (ENXIO); 732 } 733 734 /* 735 * Set the busy flag so that future transactions block 736 * until resume. 737 */ 738 mutex_enter(&unitp->umutex); 739 while (unitp->pcf8591_flags == PCF8591_BUSY) { 740 if (cv_wait_sig(&unitp->pcf8591_cv, 741 &unitp->umutex) <= 0) { 742 mutex_exit(&unitp->umutex); 743 744 return (DDI_FAILURE); 745 } 746 } 747 unitp->pcf8591_flags = PCF8591_BUSY; 748 mutex_exit(&unitp->umutex); 749 750 return (DDI_SUCCESS); 751 } 752 753 static int 754 pcf8591_do_resume(dev_info_t *dip) 755 { 756 int instance = ddi_get_instance(dip); 757 struct pcf8591_unit *unitp = (struct pcf8591_unit *) 758 ddi_get_soft_state(pcf8591_soft_statep, instance); 759 if (unitp == NULL) { 760 return (ENXIO); 761 } 762 763 mutex_enter(&unitp->umutex); 764 unitp->pcf8591_flags = 0; 765 cv_signal(&unitp->pcf8591_cv); 766 mutex_exit(&unitp->umutex); 767 768 return (DDI_SUCCESS); 769 } 770 771 static int 772 pcf8591_do_attach(dev_info_t *dip) 773 { 774 register struct pcf8591_unit *unitp; 775 int i, instance; 776 char name[MAXNAMELEN]; 777 minor_t minor; 778 779 instance = ddi_get_instance(dip); 780 781 if (ddi_soft_state_zalloc(pcf8591_soft_statep, instance) != 0) { 782 return (DDI_FAILURE); 783 } 784 785 unitp = ddi_get_soft_state(pcf8591_soft_statep, instance); 786 787 if (unitp == NULL) { 788 return (DDI_FAILURE); 789 } 790 791 unitp->dip = dip; 792 793 unitp->attach_flag = PCF8591_SOFT_STATE_ALLOC; 794 795 if (pcf8591_read_props(unitp) != DDI_PROP_SUCCESS) { 796 pcf8591_do_detach(dip); 797 798 return (DDI_FAILURE); 799 } 800 801 unitp->attach_flag |= PCF8591_PROPS_READ; 802 803 /* 804 * Set the current operating mode to NORMAL_MODE. 805 */ 806 unitp->current_mode = ENVCTRL_NORMAL_MODE; /* normal mode */ 807 808 snprintf(unitp->pcf8591_name, PCF8591_NAMELEN, 809 "%s%d", ddi_driver_name(dip), instance); 810 811 /* 812 * Create a minor node corresponding to channel 0 to 3 813 */ 814 for (i = 0; i < PCF8591_MAX_CHANS; i++) { 815 if (i == 0) { 816 (void) sprintf(name, "cputemp"); 817 } else { 818 (void) sprintf(name, "%d", i); 819 } 820 minor = PCF8591_MINOR_NUM(instance, i); 821 if (ddi_create_minor_node(dip, name, S_IFCHR, minor, 822 PCF8591_NODE_TYPE, NULL) == DDI_FAILURE) { 823 ddi_remove_minor_node(dip, NULL); 824 pcf8591_do_detach(dip); 825 826 return (DDI_FAILURE); 827 } 828 } 829 830 unitp->attach_flag |= PCF8591_MINORS_CREATED; 831 832 if (i2c_client_register(dip, &unitp->pcf8591_hdl) 833 != I2C_SUCCESS) { 834 pcf8591_do_detach(dip); 835 836 return (DDI_FAILURE); 837 } 838 839 unitp->attach_flag |= PCF8591_REGISTER_CLIENT; 840 841 /* 842 * We allocate a single i2c_transfer_t structure for all 843 * i2c transactions. 844 */ 845 if (i2c_transfer_alloc(unitp->pcf8591_hdl, &unitp->i2c_tran, 846 MAX_WLEN, MAX_RLEN, KM_SLEEP) != I2C_SUCCESS) { 847 pcf8591_do_detach(dip); 848 849 return (DDI_FAILURE); 850 } 851 852 unitp->attach_flag |= PCF8591_ALLOC_TRANSFER; 853 854 /* 855 * The flags will be set to I2C_WR because for all reads from 856 * the 8591 we need to also write the control byte. 857 */ 858 unitp->i2c_tran->i2c_flags = I2C_WR; 859 unitp->i2c_tran->i2c_version = I2C_XFER_REV; 860 861 862 /* 863 * Set the analog programming mode to default. Upper nibble 864 * in control byte. Four single ended inputs, output not enabled. 865 */ 866 unitp->pcf8591_inprog = PCF8591_4SINGLE | PCF8591_ANALOG_INPUT_EN; 867 868 /* 869 * Set the open flag for each channel to 0. 870 */ 871 for (i = 0; i < PCF8591_MAX_CHANS; i++) { 872 unitp->pcf8591_oflag[i] = 0; 873 } 874 875 /* 876 * Set the busy flag to 0. 877 */ 878 unitp->pcf8591_flags = 0; 879 880 mutex_init(&unitp->umutex, NULL, MUTEX_DRIVER, NULL); 881 cv_init(&unitp->pcf8591_cv, NULL, CV_DRIVER, NULL); 882 883 unitp->attach_flag |= PCF8591_LOCK_INIT; 884 885 if (pcf8591_add_kstats(unitp) != DDI_SUCCESS) { 886 pcf8591_do_detach(dip); 887 888 return (DDI_FAILURE); 889 } 890 891 unitp->attach_flag |= PCF8591_KSTAT_INIT; 892 893 ddi_report_dev(dip); 894 895 return (DDI_SUCCESS); 896 } 897 898 /* ARGSUSED */ 899 static int 900 pcf8591_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 901 { 902 dev_t dev; 903 int instance; 904 905 if (infocmd == DDI_INFO_DEVT2INSTANCE) { 906 dev = (dev_t)arg; 907 instance = PCF8591_MINOR_TO_DEVINST(getminor(dev)); 908 *result = (void *)(uintptr_t)instance; 909 return (DDI_SUCCESS); 910 } 911 return (DDI_FAILURE); 912 } 913 914 static int 915 pcf8591_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 916 { 917 switch (cmd) { 918 case DDI_ATTACH: 919 return (pcf8591_do_attach(dip)); 920 case DDI_RESUME: 921 return (pcf8591_do_resume(dip)); 922 default: 923 return (DDI_FAILURE); 924 } 925 } 926 927 static int 928 pcf8591_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 929 { 930 switch (cmd) { 931 case DDI_DETACH: 932 return (pcf8591_do_detach(dip)); 933 case DDI_SUSPEND: 934 return (pcf8591_do_suspend(dip)); 935 default: 936 return (DDI_FAILURE); 937 } 938 } 939 940 static uint8_t 941 translate_cputemp(uint8_t value) 942 { 943 return (_cpu_temps[value]); 944 } 945 946 static int 947 pcf8591_add_kstats(struct pcf8591_unit *unitp) 948 { 949 if ((unitp->tempksp = kstat_create(I2C_PCF8591_NAME, 950 unitp->instance, I2C_KSTAT_CPUTEMP, "misc", 951 KSTAT_TYPE_RAW, sizeof (unitp->temp_kstats), 952 KSTAT_FLAG_PERSISTENT | KSTAT_FLAG_WRITABLE)) == NULL) { 953 954 return (DDI_FAILURE); 955 } 956 957 /* 958 * The kstat fields are already initialized in the attach routine.. 959 */ 960 961 unitp->tempksp->ks_update = pcf8591_temp_kstat_update; 962 unitp->tempksp->ks_private = (void *)unitp; 963 964 strcpy(unitp->temp_kstats.label, 965 unitp->props.channels_description[0]); 966 unitp->temp_kstats.type = ENVC_NETRACT_CPU_SENSOR; 967 968 kstat_install(unitp->tempksp); 969 970 return (DDI_SUCCESS); 971 } 972 973 static void 974 pcf8591_delete_kstats(struct pcf8591_unit *unitp) 975 { 976 kstat_delete(unitp->tempksp); 977 } 978 979 static int 980 pcf8591_temp_kstat_update(kstat_t *ksp, int rw) 981 { 982 struct pcf8591_unit *unitp; 983 char *kstatp; 984 int err = 0; 985 int channel = 0; 986 int warn_temp = 0; 987 int shutdown_temp = 0; 988 989 unitp = (struct pcf8591_unit *)ksp->ks_private; 990 991 mutex_enter(&unitp->umutex); 992 while (unitp->pcf8591_flags == PCF8591_BUSY) { 993 if (cv_wait_sig(&unitp->pcf8591_cv, 994 &unitp->umutex) <= 0) { 995 mutex_exit(&unitp->umutex); 996 997 return (EINTR); 998 } 999 } 1000 1001 unitp->pcf8591_flags = PCF8591_BUSY; 1002 mutex_exit(&unitp->umutex); 1003 1004 kstatp = (char *)ksp->ks_data; 1005 1006 if (rw == KSTAT_WRITE) { 1007 1008 /* check for the size of buffer */ 1009 if (ksp->ks_data_size != sizeof (unitp->temp_kstats)) { 1010 err = EIO; 1011 goto bail; 1012 } 1013 1014 warn_temp = ((envctrl_temp_t *)kstatp)->warning_threshold; 1015 shutdown_temp = ((envctrl_temp_t *)kstatp)->shutdown_threshold; 1016 1017 if (shutdown_temp < SHUTDOWN_TEMP_MIN || shutdown_temp > 1018 SHUTDOWN_TEMP_MAX) { 1019 err = EIO; 1020 goto bail; 1021 } 1022 1023 if (warn_temp < 0 || shutdown_temp <= warn_temp) { 1024 err = EIO; 1025 goto bail; 1026 } 1027 1028 /* write into kstat fields */ 1029 unitp->temp_kstats.warning_threshold = warn_temp; 1030 unitp->temp_kstats.shutdown_threshold = shutdown_temp; 1031 1032 } else { 1033 1034 pcf8591_read_chip(unitp, channel, 1); 1035 unitp->temp_kstats.value = 1036 unitp->i2c_tran->i2c_rbuf[0]; 1037 bcopy((caddr_t)&unitp->temp_kstats, kstatp, 1038 sizeof (unitp->temp_kstats)); 1039 } 1040 1041 bail: 1042 1043 mutex_enter(&unitp->umutex); 1044 unitp->pcf8591_flags = 0; 1045 cv_signal(&unitp->pcf8591_cv); 1046 mutex_exit(&unitp->umutex); 1047 1048 return (err); 1049 } 1050 1051 static int 1052 pcf8591_read_chip(struct pcf8591_unit *unitp, uint8_t channel, 1053 int size) 1054 { 1055 int retval = I2C_SUCCESS; 1056 1057 /* 1058 * We need to read an extra byte, since as per specification 1059 * the first byte read should be discarded. 1060 */ 1061 i2c_transfer_t *tp = unitp->i2c_tran; 1062 tp->i2c_flags = I2C_WR_RD; 1063 tp->i2c_rlen = size+1; 1064 tp->i2c_wlen = 1; 1065 tp->i2c_wbuf[0] = (unitp->pcf8591_inprog | 1066 channel); 1067 1068 retval = nct_i2c_transfer(unitp->pcf8591_hdl, tp); 1069 if (retval == I2C_SUCCESS) { 1070 tp->i2c_rbuf[0] = translate_cputemp(tp->i2c_rbuf[1]); 1071 } 1072 1073 if (tp->i2c_rbuf[0] == 0) { 1074 retval = I2C_FAILURE; 1075 } 1076 1077 return (retval); 1078 } 1079 1080 /* 1081 * Reads the properties of the pcf8591 device. 1082 */ 1083 static int 1084 pcf8591_read_props(struct pcf8591_unit *unitp) 1085 { 1086 dev_info_t *dip = unitp->dip; 1087 int i, retval = 0, prop_len; 1088 int instance = ddi_get_instance(dip); 1089 int warning_temp, shutdown_temp; 1090 uint32_t *prop_value = NULL; 1091 uchar_t *creg_prop; 1092 char *function; 1093 uint_t tblsz; 1094 1095 #ifdef lint 1096 instance = instance; 1097 #endif 1098 /* 1099 * Check for the pcf8591_function property, and make sure it's 1100 * cputemp. 1101 */ 1102 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1103 "pcf8591_function", &function) != DDI_SUCCESS) { 1104 dbg_print(CE_WARN, "Couldn't find pcf8591_function property"); 1105 1106 return (DDI_FAILURE); 1107 } 1108 1109 if (strcmp(function, "cputemp") != 0) { 1110 dbg_print(CE_WARN, "pcf8591_function is not cputemp"); 1111 ddi_prop_free(function); 1112 1113 return (DDI_FAILURE); 1114 } 1115 1116 ddi_prop_free(function); 1117 1118 retval = ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1119 "name", &unitp->props.name); 1120 if (retval != DDI_PROP_SUCCESS) { 1121 1122 return (retval); 1123 } 1124 #ifdef DEBUG 1125 else if (pcf8591_debug & 0x02) 1126 cmn_err(CE_NOTE, 1127 "pcf8591_read_props:ddi_prop_lookup_string(%s): \ 1128 found %s ", "name", unitp->props.name); 1129 #endif /* DEBUG */ 1130 1131 retval = ddi_getlongprop(DDI_DEV_T_ANY, dip, 1132 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, 1133 "reg", (caddr_t)&prop_value, &prop_len); 1134 if (retval == DDI_PROP_SUCCESS) { 1135 unitp->props.i2c_bus = (uint16_t)prop_value[0]; 1136 unitp->props.slave_address = (uint16_t)prop_value[1]; 1137 kmem_free(prop_value, prop_len); 1138 #ifdef DEBUG 1139 if (pcf8591_debug & 0x02) 1140 cmn_err(CE_NOTE, 1141 "pcf8591:ddi_getlongprop(%s) returns %d," 1142 " i2c_bus,slave=0x%x,0x%x", 1143 "reg", retval, unitp->props.i2c_bus, 1144 unitp->props.slave_address); 1145 #endif /* DEBUG */ 1146 } else { 1147 unitp->props.i2c_bus = (uint16_t)-1; 1148 unitp->props.slave_address = (uint16_t)-1; 1149 #ifdef DEBUG 1150 cmn_err(CE_WARN, 1151 "pcf8591_read_props:ddi_getlongprop(%s) returns %d," 1152 " default it to 0x%x:0x%X", 1153 "reg", retval, unitp->props.i2c_bus, 1154 unitp->props.slave_address); 1155 #endif /* DEBUG */ 1156 } 1157 ddi_getproplen(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1158 "channels-in-use", &prop_len); 1159 retval = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, 1160 dip, DDI_PROP_DONTPASS, 1161 "channels-in-use", 1162 (uchar_t **)&unitp->props.channels_in_use, 1163 &unitp->props.num_chans_used); 1164 if (retval == DDI_PROP_SUCCESS) { 1165 unitp->props.num_chans_used /= sizeof (pcf8591_channel_t); 1166 } else { 1167 unitp->props.num_chans_used = 0; 1168 } 1169 1170 #ifdef DEBUG 1171 if (pcf8591_debug & 0x0002) 1172 cmn_err(CE_NOTE, 1173 "pcf8591_read_props:ddi_prop_lookup_byte_array(%s)" 1174 "returns %d\n" 1175 "\t\tlength=%d, #elements=%d", 1176 "channels-in-use", retval, 1177 prop_len, unitp->props.num_chans_used); 1178 #endif /* DEBUG */ 1179 1180 retval = ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, 1181 DDI_PROP_DONTPASS, "channels-description", 1182 (char ***)&unitp->props.channels_description, 1183 (uint_t *)&prop_len); 1184 1185 if (retval != DDI_PROP_SUCCESS) { 1186 prop_len = 0; 1187 unitp->props.channels_description = NULL; 1188 } 1189 1190 #ifdef DEBUG 1191 if (pcf8591_debug & 0x0002) { 1192 cmn_err(CE_NOTE, 1193 "pcf8591_read_props:ddi_prop_lookup_string_array(%s)" 1194 "returns %d, length=%d", 1195 "channels-description", retval, prop_len); 1196 for (i = 0; i < prop_len; ++i) { 1197 cmn_err(CE_NOTE, "channels-description[%d]=<%s>", 1198 i, unitp->props.channels_description[i]); 1199 } 1200 } 1201 #endif /* DEBUG */ 1202 1203 /* 1204 * The following code was borrowed from envctrltwo.c 1205 * I haven't yet investigated why the copy target is index + 2 1206 */ 1207 retval = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 1208 DDI_PROP_DONTPASS, "tables", &creg_prop, (uint_t *)&prop_len); 1209 1210 if (retval != DDI_PROP_SUCCESS) { 1211 #ifdef DEBUG 1212 cmn_err(CE_WARN, "%s%d: Unable to read pcf8591 tables property", 1213 ddi_get_name(dip), instance); 1214 #endif /* DEBUG */ 1215 1216 return (DDI_NOT_WELL_FORMED); 1217 } 1218 1219 tblsz = (sizeof (_cpu_temps) / sizeof (uchar_t)); 1220 if (prop_len <= tblsz) { 1221 for (i = 0; i < prop_len; i++) { 1222 _cpu_temps[i] = creg_prop[i]; 1223 } 1224 } 1225 #ifdef DEBUG 1226 if (pcf8591_debug & 0x0002) 1227 cmn_err(CE_NOTE, "pcf8591_read_props: _cpu_temps size=%d; " 1228 "tables prop_len=%d\n", tblsz, prop_len); 1229 #endif /* DEBUG */ 1230 1231 ddi_prop_free(creg_prop); 1232 1233 /* 1234 * Read shutdown temp and warning temp properties. 1235 */ 1236 warning_temp = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 1237 DDI_PROP_DONTPASS, "warning-temp", PCF8591_WARNING_TEMP); 1238 1239 shutdown_temp = (int)ddi_getprop(DDI_DEV_T_ANY, dip, 1240 DDI_PROP_DONTPASS, "shutdown-temp", PCF8591_SHUTDOWN_TEMP); 1241 1242 /* 1243 * Fill up the warning and shutdown temp values in kstat structure. 1244 */ 1245 unitp->temp_kstats.warning_threshold = warning_temp; 1246 unitp->temp_kstats.shutdown_threshold = shutdown_temp; 1247 1248 return (DDI_PROP_SUCCESS); 1249 } 1250