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