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