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