1*1708Sstevel /* 2*1708Sstevel * CDDL HEADER START 3*1708Sstevel * 4*1708Sstevel * The contents of this file are subject to the terms of the 5*1708Sstevel * Common Development and Distribution License, Version 1.0 only 6*1708Sstevel * (the "License"). You may not use this file except in compliance 7*1708Sstevel * with the License. 8*1708Sstevel * 9*1708Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*1708Sstevel * or http://www.opensolaris.org/os/licensing. 11*1708Sstevel * See the License for the specific language governing permissions 12*1708Sstevel * and limitations under the License. 13*1708Sstevel * 14*1708Sstevel * When distributing Covered Code, include this CDDL HEADER in each 15*1708Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*1708Sstevel * If applicable, add the following below this CDDL HEADER, with the 17*1708Sstevel * fields enclosed by brackets "[]" replaced with your own identifying 18*1708Sstevel * information: Portions Copyright [yyyy] [name of copyright owner] 19*1708Sstevel * 20*1708Sstevel * CDDL HEADER END 21*1708Sstevel */ 22*1708Sstevel /* 23*1708Sstevel * Copyright (c) 1999-2001 by Sun Microsystems, Inc. 24*1708Sstevel * All rights reserved. 25*1708Sstevel */ 26*1708Sstevel 27*1708Sstevel #ifndef _PCF8574_H 28*1708Sstevel #define _PCF8574_H 29*1708Sstevel 30*1708Sstevel #pragma ident "%Z%%M% %I% %E% SMI" 31*1708Sstevel 32*1708Sstevel #ifdef __cplusplus 33*1708Sstevel extern "C" { 34*1708Sstevel #endif 35*1708Sstevel 36*1708Sstevel #define PCF8574_NODE_TYPE "adc_i2c:gpio" 37*1708Sstevel #define I2C_PCF8574_NAME "gpio" 38*1708Sstevel 39*1708Sstevel #define I2C_KSTAT_CPUVOLTAGE "gpio_cpuvoltage" 40*1708Sstevel #define I2C_KSTAT_PWRSUPPLY "gpio_pwrsupply" 41*1708Sstevel #define I2C_KSTAT_FANTRAY "gpio_fantray" 42*1708Sstevel 43*1708Sstevel /* 44*1708Sstevel * PCF8574 ioctls for fantray and powersupplies. 45*1708Sstevel */ 46*1708Sstevel 47*1708Sstevel #define ENVC_IOC_GETTEMP 0x10 48*1708Sstevel #define ENVC_IOC_SETFAN 0x11 49*1708Sstevel #define ENVC_IOC_GETFAN 0x12 50*1708Sstevel #define ENVC_IOC_GETSTATUS 0x15 51*1708Sstevel #define ENVC_IOC_GETTYPE 0x16 52*1708Sstevel #define ENVC_IOC_GETFAULT 0x17 53*1708Sstevel #define ENVC_IOC_PSTEMPOK 0x18 54*1708Sstevel #define ENVC_IOC_PSFANOK 0x1A 55*1708Sstevel #define ENVC_IOC_PSONOFF 0x1B 56*1708Sstevel #define ENVC_IOC_SETSTATUS 0x1C 57*1708Sstevel 58*1708Sstevel #define ENVC_IOC_INTRMASK 0x1D 59*1708Sstevel 60*1708Sstevel #define ENVCTRL_INTRMASK_SET 1 61*1708Sstevel #define ENVCTRL_INTRMASK_CLEAR 0 62*1708Sstevel 63*1708Sstevel #define ENVCTRL_FANSPEED_LOW 0 64*1708Sstevel #define ENVCTRL_FANSPEED_HIGH 1 65*1708Sstevel 66*1708Sstevel /* 67*1708Sstevel * Could not find a definition for CPU voltage monitoring in Javelin 68*1708Sstevel * Code. So writing a structure here. 69*1708Sstevel */ 70*1708Sstevel 71*1708Sstevel typedef struct envctrl_cpuvoltage { 72*1708Sstevel int value; 73*1708Sstevel } envctrl_cpuvoltage_t; 74*1708Sstevel 75*1708Sstevel /* 76*1708Sstevel * ps_present and fan_present fields modified for FRU callback and status 77*1708Sstevel * See sys/scsb_cbi.h and definitions in scsb.c 78*1708Sstevel */ 79*1708Sstevel typedef struct envctrl_pwrsupply { 80*1708Sstevel scsb_fru_status_t ps_present; /* Is powersupply present */ 81*1708Sstevel boolean_t ps_ok; /* Is powersupply ok */ 82*1708Sstevel boolean_t temp_ok; /* Is temperature ok */ 83*1708Sstevel boolean_t psfan_ok; /* Is fan ok */ 84*1708Sstevel boolean_t on_state; /* Powersupply on/off */ 85*1708Sstevel int ps_ver; /* Pwr supply version and type */ 86*1708Sstevel } envctrl_pwrsupp_t; 87*1708Sstevel 88*1708Sstevel typedef struct envctrl_fantray { 89*1708Sstevel scsb_fru_status_t fan_present; /* fan1 present */ 90*1708Sstevel boolean_t fan_ok; /* fan1 ok */ 91*1708Sstevel boolean_t fanspeed; /* to set speed, input */ 92*1708Sstevel int fan_ver; /* Fan version and type */ 93*1708Sstevel } envctrl_fantray_t; 94*1708Sstevel 95*1708Sstevel #ifdef _KERNEL 96*1708Sstevel 97*1708Sstevel #ifndef I2CDEV_TRAN 98*1708Sstevel #define I2CDEV_TRAN 1 99*1708Sstevel #endif 100*1708Sstevel 101*1708Sstevel #define PCF8574_MAX_DEVS 0x08 102*1708Sstevel #define PCF8574_MAX_CHANS 0x01 103*1708Sstevel #define PCF8574_BUSY 0x01 104*1708Sstevel #define PCF8574_NAMELEN 12 105*1708Sstevel #define PCF8574_INTR_ON 0x1 106*1708Sstevel #define PCF8574_INTR_ENABLED 0x2 107*1708Sstevel 108*1708Sstevel #define PCF8574_MINOR_TO_DEVINST(x) (((x) & 0x700) >> 8) 109*1708Sstevel #define PCF8574_MINOR_TO_CHANNEL(x) ((x) & 0x3) 110*1708Sstevel 111*1708Sstevel #define PCF8574_CHANNEL_TO_MINOR(x) ((x) & 0x3) 112*1708Sstevel #define PCF8574_DEVINST_TO_MINOR(x) ((x) << 8) 113*1708Sstevel 114*1708Sstevel 115*1708Sstevel #define PCF8574_TRAN_SIZE 1 116*1708Sstevel #ifndef PCF8574 117*1708Sstevel #define PCF8574 0 118*1708Sstevel #endif 119*1708Sstevel 120*1708Sstevel #ifndef PCF8574A 121*1708Sstevel #define PCF8574A 1 122*1708Sstevel #endif 123*1708Sstevel 124*1708Sstevel #define PCF8574_SET ('A' << 8) 125*1708Sstevel #define PCF8574_GET ('B' << 8) 126*1708Sstevel 127*1708Sstevel #define NUM_OF_PCF8574_DEVICES 8 128*1708Sstevel #define PCF8574_MAXPORTS 8 129*1708Sstevel 130*1708Sstevel #define PCF8574_TYPE_CPUVOLTAGE 0 131*1708Sstevel #define PCF8574_TYPE_FANTRAY 1 132*1708Sstevel #define PCF8574_TYPE_PWRSUPP 2 133*1708Sstevel 134*1708Sstevel #define PCF8574_ADR_CPUVOLTAGE 0x70 135*1708Sstevel #define PCF8574_ADR_PWRSUPPLY1 0x7C 136*1708Sstevel #define PCF8574_ADR_PWRSUPPLY2 0x7E 137*1708Sstevel #define PCF8574_ADR_FANTRAY1 0x74 138*1708Sstevel #define PCF8574_ADR_FANTRAY2 0x76 139*1708Sstevel 140*1708Sstevel /* 141*1708Sstevel * PCF8574 Fan Fail, Power Supply Fail Detector 142*1708Sstevel * This device is driven by interrupts. Each time it interrupts 143*1708Sstevel * you must look at the CSR to see which ports caused the interrupt 144*1708Sstevel * they are indicated by a 1. 145*1708Sstevel * 146*1708Sstevel * Address map of this chip 147*1708Sstevel * 148*1708Sstevel * ------------------------------------------- 149*1708Sstevel * | 0 | 1 | 1 | 1 | A2 | A1 | A0 | 0 | 150*1708Sstevel * ------------------------------------------- 151*1708Sstevel * 152*1708Sstevel */ 153*1708Sstevel #define I2C_PCF8574_PORT0 0x01 154*1708Sstevel #define I2C_PCF8574_PORT1 0x02 155*1708Sstevel #define I2C_PCF8574_PORT2 0x04 156*1708Sstevel #define I2C_PCF8574_PORT3 0x08 157*1708Sstevel #define I2C_PCF8574_PORT4 0x10 158*1708Sstevel #define I2C_PCF8574_PORT5 0x20 159*1708Sstevel #define I2C_PCF8574_PORT6 0x40 160*1708Sstevel #define I2C_PCF8574_PORT7 0x80 161*1708Sstevel 162*1708Sstevel #define MAX_WLEN 64 163*1708Sstevel #define MAX_RLEN 64 164*1708Sstevel 165*1708Sstevel /* 166*1708Sstevel * Following property information taken from the 167*1708Sstevel * "SPARCengine ASM Reference Manual" 168*1708Sstevel * Property pointers are to DDI allocated space 169*1708Sstevel * which must be freed in the detach() routine. 170*1708Sstevel */ 171*1708Sstevel /* 172*1708Sstevel * for pcf8574_properties_t.channels_in_use->io_dir 173*1708Sstevel */ 174*1708Sstevel #define I2C_PROP_IODIR_IN 0 175*1708Sstevel #define I2C_PROP_IODIR_OUT 1 176*1708Sstevel #define I2C_PROP_IODIR_INOUT 2 177*1708Sstevel 178*1708Sstevel /* 179*1708Sstevel * for pcf8574_properties_t.channels_in_use->type 180*1708Sstevel */ 181*1708Sstevel #define I2C_PROP_TYPE_NOCARE 0 182*1708Sstevel #define I2C_PROP_TYPE_TEMP 1 183*1708Sstevel #define I2C_PROP_TYPE_VOLT 2 184*1708Sstevel #define I2C_PROP_TYPE_FANSTATS 3 185*1708Sstevel #define I2C_PROP_TYPE_FANSPEED 4 186*1708Sstevel 187*1708Sstevel /* 188*1708Sstevel * These are now defined in sys/netract_gen.h 189*1708Sstevel * 190*1708Sstevel * #define ENVC_IOC_GETMODE 0x1C 191*1708Sstevel * #define ENVC_IOC_SETMODE 0x1D 192*1708Sstevel */ 193*1708Sstevel 194*1708Sstevel 195*1708Sstevel /* 196*1708Sstevel * Bit positions for the pcf8574 registers. 197*1708Sstevel */ 198*1708Sstevel 199*1708Sstevel #define PCF8574_PS_TYPE(X) ((X) & 0x3) 200*1708Sstevel #define PCF8574_PS_INTMASK(X) (((X) >> 2) & 0x1) 201*1708Sstevel #define PCF8574_PS_ONOFF(X) (((X) >> 3)& 0x1) 202*1708Sstevel #define PCF8574_PS_FANOK(X) (((X) >> 4) & 0x1) 203*1708Sstevel #define PCF8574_PS_TEMPOK(X) (((X) >> 6) & 0x1) 204*1708Sstevel #define PCF8574_PS_FAULT(X) (((X) >> 7) & 0x1) 205*1708Sstevel 206*1708Sstevel #define PCF8574_FAN_TYPE(X) ((X) & 0x3) 207*1708Sstevel #define PCF8574_FAN_INTMASK(X) (((X) >> 2) & 0x1) 208*1708Sstevel #define PCF8574_FAN_FANSPD(X) (((X) >> 3) & 0x1) 209*1708Sstevel #define PCF8574_FAN_FAULT(X) (((X) >> 7) & 0x1) 210*1708Sstevel 211*1708Sstevel /* Constructs the reg byte from bit value */ 212*1708Sstevel #define PCF8574_FAN_SPEED(bit) ((bit) << 3) 213*1708Sstevel #define PCF8574_INT_MASK(bit) ((bit) << 2) 214*1708Sstevel 215*1708Sstevel /* 216*1708Sstevel * To tell the write_chip routine which bits to modify, a 217*1708Sstevel * 1 in the corresponding position selects that bit for 218*1708Sstevel * writing, a 0 ignores it. 219*1708Sstevel */ 220*1708Sstevel #define PCF8574_FANSPEED_BIT 0x08 221*1708Sstevel #define PCF8574_INTRMASK_BIT 0x04 222*1708Sstevel 223*1708Sstevel /* 224*1708Sstevel * Read and write masks for the fan and power supply. 225*1708Sstevel * These masks indicate which ports attached to the 226*1708Sstevel * PCF8574/A are input/output. We should construct the 227*1708Sstevel * read and writemasks from the channels-in-use property 228*1708Sstevel * for each pcf8574 device. In case the property is 229*1708Sstevel * absent, we can assign them with these default values. 230*1708Sstevel * While writing to the chip, we must or with the readmask, 231*1708Sstevel * else that port will be disabled. 232*1708Sstevel */ 233*1708Sstevel 234*1708Sstevel #define PCF8574_FAN_WRITEMASK 0x0c 235*1708Sstevel #define PCF8574_FAN_READMASK 0xff 236*1708Sstevel #define PCF8574_PS_WRITEMASK 0x04 237*1708Sstevel #define PCF8574_PS_READMASK 0xff 238*1708Sstevel #define PCF8584_CPUVOLTAGE_WRITEMASK 0x88 239*1708Sstevel #define PCF8584_CPUVOLTAGE_READMASK 0x41 240*1708Sstevel 241*1708Sstevel /* 242*1708Sstevel * Default values of the Fan and PS registers. 243*1708Sstevel * interrupt enabled. 244*1708Sstevel */ 245*1708Sstevel #define PCF8574_FAN_DEFAULT 0xfb 246*1708Sstevel #define PCF8574_PS_DEFAULT 0xfb 247*1708Sstevel 248*1708Sstevel #define PCF8574_FAN_MASKINTR 0x04 249*1708Sstevel 250*1708Sstevel #define PCF8574_PS_MASKINTR 0x04 251*1708Sstevel 252*1708Sstevel #define PCF8574_FAN_SPEED60 0x00 253*1708Sstevel #define PCF8574_FAN_SPEED100 0x80 254*1708Sstevel 255*1708Sstevel #define PCF8574_NUM_FANTRAY 2 256*1708Sstevel #define PCF8574_NUM_PWRSUPP 2 257*1708Sstevel 258*1708Sstevel #define PCF8574_FAN_SPEED_LOW 0 259*1708Sstevel #define PCF8574_FAN_SPEED_HIGH 1 260*1708Sstevel 261*1708Sstevel /* 262*1708Sstevel * Stage of attachment. 263*1708Sstevel */ 264*1708Sstevel #define PCF8574_SOFT_STATE_ALLOC 0x0001 265*1708Sstevel #define PCF8574_PROPS_READ 0x0002 266*1708Sstevel #define PCF8574_MINORS_CREATED 0x0004 267*1708Sstevel #define PCF8574_ALLOC_TRANSFER 0x0008 268*1708Sstevel #define PCF8574_REGISTER_CLIENT 0x0010 269*1708Sstevel #define PCF8574_LOCK_INIT 0x0020 270*1708Sstevel #define PCF8574_INTR_MUTEX 0x0040 271*1708Sstevel #define PCF8574_INTR_ADDED 0x0080 272*1708Sstevel #define PCF8574_KSTAT_INIT 0x0100 273*1708Sstevel 274*1708Sstevel /* 275*1708Sstevel * PCF8574 ioctls for CPU Voltage (Nordica). 276*1708Sstevel */ 277*1708Sstevel 278*1708Sstevel 279*1708Sstevel typedef struct { 280*1708Sstevel uint8_t port; 281*1708Sstevel uint8_t io_dir; 282*1708Sstevel uint8_t type; 283*1708Sstevel uint8_t last_data; /* N/A */ 284*1708Sstevel } pcf8574_channel_t; 285*1708Sstevel 286*1708Sstevel typedef struct { 287*1708Sstevel char *name; 288*1708Sstevel uint16_t i2c_bus; 289*1708Sstevel uint16_t slave_address; 290*1708Sstevel uint_t num_chans_used; 291*1708Sstevel char **channels_description; 292*1708Sstevel pcf8574_channel_t *channels_in_use; 293*1708Sstevel } pcf8574_properties_t; 294*1708Sstevel 295*1708Sstevel struct pcf8574_unit { 296*1708Sstevel kmutex_t umutex; 297*1708Sstevel int instance; 298*1708Sstevel dev_info_t *dip; 299*1708Sstevel kcondvar_t pcf8574_cv; 300*1708Sstevel i2c_transfer_t *i2c_tran; 301*1708Sstevel i2c_client_hdl_t pcf8574_hdl; 302*1708Sstevel char pcf8574_name[PCF8574_NAMELEN]; 303*1708Sstevel pcf8574_properties_t props; 304*1708Sstevel uint8_t pcf8574_flags; 305*1708Sstevel int pcf8574_oflag; 306*1708Sstevel uint8_t readmask; 307*1708Sstevel uint8_t writemask; 308*1708Sstevel ddi_iblock_cookie_t iblock; 309*1708Sstevel kmutex_t intr_mutex; 310*1708Sstevel uint8_t pcf8574_canintr; 311*1708Sstevel void *envctrl_kstat; 312*1708Sstevel uint8_t current_mode; 313*1708Sstevel int sensor_type; 314*1708Sstevel int pcf8574_type; 315*1708Sstevel struct pollhead poll; 316*1708Sstevel int poll_event; 317*1708Sstevel uint_t attach_flag; 318*1708Sstevel kstat_t *kstatp; 319*1708Sstevel int i2c_status; 320*1708Sstevel }; 321*1708Sstevel 322*1708Sstevel #endif /* _KERNEL */ 323*1708Sstevel 324*1708Sstevel #ifdef __cplusplus 325*1708Sstevel } 326*1708Sstevel #endif 327*1708Sstevel 328*1708Sstevel #endif /* _PCF8574_H */ 329