summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4u/sys/i2c/nexus/smbus.h
blob: a22e3461126bc01a6680ea51c275a51627b35ca3 (plain)
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
/*
 * 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 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SMBUS_H
#define	_SMBUS_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/promif.h>

/*
 * Attach flags
 */
#define	SETUP_REGS	0x01
#define	NEXUS_REGISTER	0x02
#define	IMUTEX		0x04
#define	ADD_INTR	0x08
#define	INTERRUPT_PRI	0x10

/*
 * Register offsets
 */
#define	SMB_STS		0x00
#define	SMB_TYP		0x01
#define	STR_PORT	0x02
#define	DEV_ADDR	0x03
#define	DEV_DATA0	0x04
#define	DEV_DATA1	0x05
#define	BLK_DATA	0x06
#define	SMB_CMD		0x07

/*
 * Bit values for SMB_STS (status) register
 */
#define	FAILED		0x80
#define	BUS_ERR		0x40
#define	DRV_ERR		0x20
#define	CMD_CMPL	0x10
#define	HOST_BSY	0x08
#define	IDLE		0x04
#define	INDEX		0x04
#define	TENBITS		0x02
#define	ALERT		0x01

/*
 * Bit values for the SMB_TYP (command type) register
 */
#define	DEV10B_EN	0x80
#define	QUICK_CMD	0x00
#define	SEND_BYTE	0x10
#define	RCV_BYTE	0x10
#define	WR_BYTE		0x20
#define	RD_BYTE		0x20
#define	WR_WORD		0x30
#define	RD_WORD		0x30
#define	WR_BLK		0x40
#define	RD_BLK		0x40
#define	PRC_CALL	0x50
#define	T_OUT		0x08
#define	KILL		0x04

#define	SMBUS_PIL	4

#define	MAX_BLK_SEND	32

/*
 * Used to or in bit 0 to be 1 for I2C read address.
 */
#define	I2C_READ	0x01

/*
 * The maximum number of times to retry in event of
 * a failure.
 */
#define	SMBUS_MAX_RETRIES	10

/*
 * If smbus_put() should make sure the buffer is flushed.
 */
#define	SMBUS_FLUSH 0x01

/*
 * The time in microseconds to wait before the timeout fires
 * to protect against an interrupt never arriving.
 */
#define	INTR_TIMEOUT 100000

/*
 * Time to wait in microseconds for any transaction before giving up
 * ie 10 seconds.
 */
#define	SMBUS_TRANS_TIMEOUT 10000000

/*
 * smbus event mode selection. select poll or interrupt mode
 */

#define	SMBUS_POLL_MODE		1	/* polling mode */
#define	SMBUS_POLL_TIMEOUT	50000
					/*
					 * how long to wait(us) for
					 * command completion.
					 */
#define	SMBUS_POLL_INTERVAL	1
					/*
					 * time (us) to wait between
					 * polls: must be small in comparison
					 * to the time an an i2c transaction
					 * takes.
					 */
/*
 * Scale polling retries so that the total timeout is "SMBUS_POLL_TIMEOUT"
 */
#define	SMBUS_POLL_MAX_RETRIES	(SMBUS_POLL_TIMEOUT/SMBUS_POLL_INTERVAL)


/*
 * smbus_ppvt_t contains info that is chip specific
 * and is stored on the child's devinfo parent private data.
 */
typedef struct smbus_ppvt {
	int	smbus_ppvt_addr; /* address of I2C device */
} smbus_ppvt_t;

typedef struct smbus {
	dev_info_t		*smbus_dip;
	int			smbus_attachflags;
	kmutex_t		smbus_mutex;
	kmutex_t		smbus_imutex;
	kcondvar_t		smbus_icv;
	kcondvar_t		smbus_cv;
	kcondvar_t		smbus_intr_cv;
	ddi_iblock_cookie_t	smbus_icookie;
	int			smbus_busy;
	int			smbus_wait;
	int			smbus_bus;
	i2c_transfer_t		*smbus_cur_tran;
	dev_info_t		*smbus_cur_dip;
	char			smbus_name[12];
	uint8_t			*smbus_regaddr;
	ddi_acc_handle_t	smbus_rhandle;
	uint8_t			*smbus_configregaddr;
	ddi_acc_handle_t	smbus_confighandle;
	timeout_id_t		smbus_timeout;
	int		smbus_saved_w_resid;
	int		smbus_retries;
	int		smbus_bytes_to_read;
	int		smbus_poll_complete;
							/*
							 * Boolean:true if
							 * polling is complete
							 */
	int		smbus_polling;
							/*
							 * Boolean: true if
							 * driver is polling
							 */
	int		smbus_poll_retries;
								/*
								 * How many
								 * times we
								 * have polled
								 * the status
								 * register. Not
								 * to be
								 * confused with
								 * "retries",
								 * which is how
								 * many times we
								 * tried after
								 * an error
								 */
} smbus_t;

#define	PRT_INIT	0x01
#define	PRT_WR		0x02
#define	PRT_RD		0x04
#define	PRT_PUT		0x08
#define	PRT_GET		0x10
#define	PRT_ATTACH	0x20
#define	PRT_INTR	0x40
#define	PRT_INTR_ERR	0x80
#define	PRT_TRANS	0x100
#define	PRT_SPEC	0x200
#define	PRT_BUFFONLY	0x1000
#define	PRT_PROM	0x2000

/*
 * smbus_switch return status
 */
#define	SMBUS_PENDING	0x01
#define	SMBUS_COMPLETE	0x02
#define	SMBUS_FAILURE	0x03

#define	SMBUS_SUCCESS	0x04

#define	SMBUS_SRC_STATUS	0x48
#define	SMBUS_SRC_ENA		0x44
#define	SMBUS_SMI		0x80000
#define	SMBUS_SMB_INTR_STATUS	0x80000

#define	SMBUS_INTR	"smbus_intr"
#define	SMBUS_TIMEOUT	"smbus_timeout"
#define	SMBUS_POLL	"smbus_poll"

#ifdef	DEBUG
#define	SMBUS_PRINT(a)	smbus_print a
#else
#define	SMBUS_PRINT(a)
#endif


/*
 * Other function delcarations
 */
int smbus_transfer(dev_info_t *, i2c_transfer_t *);
void smbus_print(int flags, const char *fmt, ...);

#ifdef	__cplusplus
}
#endif

#endif /* _SMBUS_H */