xref: /onnv-gate/usr/src/uts/sun4u/montecarlo/sys/pcf8574_nct.h (revision 1708:ea74d8598a3a)
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