1*1341Sstevel /*
2*1341Sstevel * CDDL HEADER START
3*1341Sstevel *
4*1341Sstevel * The contents of this file are subject to the terms of the
5*1341Sstevel * Common Development and Distribution License (the "License").
6*1341Sstevel * You may not use this file except in compliance with the License.
7*1341Sstevel *
8*1341Sstevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*1341Sstevel * or http://www.opensolaris.org/os/licensing.
10*1341Sstevel * See the License for the specific language governing permissions
11*1341Sstevel * and limitations under the License.
12*1341Sstevel *
13*1341Sstevel * When distributing Covered Code, include this CDDL HEADER in each
14*1341Sstevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*1341Sstevel * If applicable, add the following below this CDDL HEADER, with the
16*1341Sstevel * fields enclosed by brackets "[]" replaced with your own identifying
17*1341Sstevel * information: Portions Copyright [yyyy] [name of copyright owner]
18*1341Sstevel *
19*1341Sstevel * CDDL HEADER END
20*1341Sstevel */
21*1341Sstevel
22*1341Sstevel /*
23*1341Sstevel * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
24*1341Sstevel * Use is subject to license terms.
25*1341Sstevel */
26*1341Sstevel
27*1341Sstevel #pragma ident "%Z%%M% %I% %E% SMI"
28*1341Sstevel
29*1341Sstevel /*
30*1341Sstevel * Low level environmental control routines.
31*1341Sstevel * These routines implement the I2C bus protocol.
32*1341Sstevel */
33*1341Sstevel
34*1341Sstevel #define EHC_SUCCESS 0
35*1341Sstevel #define EHC_FAILURE (-1)
36*1341Sstevel #define EHC_NO_SLAVE_ACK 3
37*1341Sstevel
38*1341Sstevel #define EHC_MAX_WAIT 100 /* decimal */
39*1341Sstevel
40*1341Sstevel #define EHC_S1_PIN 0x80
41*1341Sstevel #define EHC_S1_ES1 0x20
42*1341Sstevel #define EHC_S1_ES0 0x40
43*1341Sstevel #define EHC_S1_NBB 0x01
44*1341Sstevel #define EHC_S1_ACK 0x01
45*1341Sstevel #define EHC_S1_STA 0x04
46*1341Sstevel #define EHC_S1_STO 0x02
47*1341Sstevel #define EHC_S1_LRB 0x08
48*1341Sstevel #define EHC_S1_BER 0x10
49*1341Sstevel #define EHC_S1_LAB 0x02
50*1341Sstevel #define EHC_S1_AAS 0x04
51*1341Sstevel #define EHC_S1_AD0 0x08
52*1341Sstevel #define EHC_S1_STS 0x20
53*1341Sstevel
54*1341Sstevel #define EHC_S0_OWN 0x55
55*1341Sstevel #define EHC_S0_CLK 0x1d
56*1341Sstevel
57*1341Sstevel #define EHC_BYTE_READ 0x01
58*1341Sstevel
59*1341Sstevel #define EHC_LONGEST_MSG 200000 /* 200 ms */
60*1341Sstevel
61*1341Sstevel #define DUMMY_WRITE_ADDR 0x20
62*1341Sstevel #define DUMMY_WRITE_DATA 0x00
63*1341Sstevel
64*1341Sstevel /*
65*1341Sstevel * PCF8591 Chip Used for temperature sensors
66*1341Sstevel *
67*1341Sstevel * Addressing Register definition.
68*1341Sstevel * A0-A2 valid range is 0-7
69*1341Sstevel *
70*1341Sstevel * ------------------------------------------------
71*1341Sstevel * | 1 | 0 | 0 | 1 | A2 | A1 | A0 | R/W |
72*1341Sstevel * ------------------------------------------------
73*1341Sstevel */
74*1341Sstevel
75*1341Sstevel
76*1341Sstevel #define EHC_PCF8591_MAX_DEVS 0x08
77*1341Sstevel
78*1341Sstevel #define EHC_DEV0 0x00
79*1341Sstevel #define EHC_DEV1 0x02
80*1341Sstevel #define EHC_DEV2 0x04
81*1341Sstevel #define EHC_DEV3 0x06
82*1341Sstevel #define EHC_DEV4 0x08
83*1341Sstevel #define EHC_DEV5 0x0A
84*1341Sstevel #define EHC_DEV6 0x0C
85*1341Sstevel #define EHC_DEV7 0x0E
86*1341Sstevel
87*1341Sstevel
88*1341Sstevel /*
89*1341Sstevel * CONTROL OF CHIP
90*1341Sstevel * PCF8591 Temp sensing control register definitions
91*1341Sstevel *
92*1341Sstevel * ---------------------------------------------
93*1341Sstevel * | 0 | AOE | X | X | 0 | AIF | X | X |
94*1341Sstevel * ---------------------------------------------
95*1341Sstevel * AOE = Analog out enable.. not used on out implementation
96*1341Sstevel * 5 & 4 = Analog Input Programming.. see data sheet for bits..
97*1341Sstevel *
98*1341Sstevel * AIF = Auto increment flag
99*1341Sstevel * bits 1 & 0 are for the Chennel number.
100*1341Sstevel */
101*1341Sstevel
102*1341Sstevel #define EHC_PCF8591_ANALOG_OUTPUT_EN 0x40
103*1341Sstevel #define EHC_PCF8591_ANALOG_INPUT_EN 0x00
104*1341Sstevel #define EHC_PCF8591_READ_BIT 0x01
105*1341Sstevel
106*1341Sstevel
107*1341Sstevel #define EHC_PCF8591_AUTO_INCR 0x04
108*1341Sstevel #define EHC_PCF8591_OSCILATOR 0x40
109*1341Sstevel
110*1341Sstevel #define EHC_PCF8591_MAX_PORTS 0x04
111*1341Sstevel
112*1341Sstevel #define EHC_PCF8591_CH_0 0x00
113*1341Sstevel #define EHC_PCF8591_CH_1 0x01
114*1341Sstevel #define EHC_PCF8591_CH_2 0x02
115*1341Sstevel #define EHC_PCF8591_CH_3 0x03
116*1341Sstevel
117*1341Sstevel
118*1341Sstevel /*
119*1341Sstevel * PCF8574 Fan Fail, Power Supply Fail Detector
120*1341Sstevel * This device is driven by interrupts. Each time it interrupts
121*1341Sstevel * you must look at the CSR to see which ports caused the interrupt
122*1341Sstevel * they are indicated by a 1.
123*1341Sstevel *
124*1341Sstevel * Address map of this chip
125*1341Sstevel *
126*1341Sstevel * -------------------------------------------
127*1341Sstevel * | 0 | 1 | 1 | 1 | A2 | A1 | A0 | 0 |
128*1341Sstevel * -------------------------------------------
129*1341Sstevel *
130*1341Sstevel */
131*1341Sstevel
132*1341Sstevel #define EHC_PCF8574_PORT0 0x01
133*1341Sstevel #define EHC_PCF8574_PORT1 0x02
134*1341Sstevel #define EHC_PCF8574_PORT2 0x04
135*1341Sstevel #define EHC_PCF8574_PORT3 0x08
136*1341Sstevel #define EHC_PCF8574_PORT4 0x10
137*1341Sstevel #define EHC_PCF8574_PORT5 0x20
138*1341Sstevel #define EHC_PCF8574_PORT6 0x40
139*1341Sstevel #define EHC_PCF8574_PORT7 0x80
140*1341Sstevel
141*1341Sstevel /*
142*1341Sstevel * Defines for the PCF8583 Clock Calendar Chip.
143*1341Sstevel */
144*1341Sstevel #define EHC_PCF8583_READ_BIT 0x01
145*1341Sstevel
146*1341Sstevel struct ehc_pcd8584_regs {
147*1341Sstevel uint8_t s0; /* Own Address S0' */
148*1341Sstevel uint8_t s1; /* Control Status register */
149*1341Sstevel uint8_t clock_s2; /* Clock programming register */
150*1341Sstevel };
151*1341Sstevel
152*1341Sstevel struct ehc_envcunit {
153*1341Sstevel struct ehc_pcd8584_regs *bus_ctl_regs;
154*1341Sstevel ddi_acc_handle_t ctlr_handle;
155*1341Sstevel kmutex_t umutex;
156*1341Sstevel };
157*1341Sstevel
158*1341Sstevel int ehc_debug = 0;
159*1341Sstevel
160*1341Sstevel #define DCMN_ERR if (ehc_debug & 0x1) cmn_err
161*1341Sstevel #define DCMN2_ERR if (ehc_debug & 0x2) cmn_err
162*1341Sstevel
163*1341Sstevel /*
164*1341Sstevel * Prototypes for routines used in other modules.
165*1341Sstevel */
166*1341Sstevel
167*1341Sstevel void ehc_init_pcf8584(struct ehc_envcunit *);
168*1341Sstevel int ehc_read_tda8444(struct ehc_envcunit *ehcp);
169*1341Sstevel int ehc_write_tda8444(struct ehc_envcunit *, int, int, int, uint8_t *, int);
170*1341Sstevel int ehc_write_pcf8591(struct ehc_envcunit *, int, int, int, int, int,
171*1341Sstevel uint8_t *, int);
172*1341Sstevel int ehc_read_pcf8591(struct ehc_envcunit *, int, int, int, int, int,
173*1341Sstevel uint8_t *, int);
174*1341Sstevel int ehc_read_pcf8574a(struct ehc_envcunit *, int, uint8_t *, int);
175*1341Sstevel int ehc_write_pcf8574a(struct ehc_envcunit *, int, uint8_t *, int);
176*1341Sstevel int ehc_read_pcf8574(struct ehc_envcunit *, int, uint8_t *, int);
177*1341Sstevel int ehc_write_pcf8574(struct ehc_envcunit *, int, uint8_t *, int);
178*1341Sstevel int ehc_read_lm75(struct ehc_envcunit *, int, uint8_t *, int);
179*1341Sstevel int ehc_write_pcf8583(struct ehc_envcunit *, int, uint8_t *, int);
180*1341Sstevel
181*1341Sstevel /*
182*1341Sstevel * Prototypes for routines used only in this source module.
183*1341Sstevel */
184*1341Sstevel
185*1341Sstevel static int ehc_start_pcf8584(struct ehc_envcunit *, uint8_t);
186*1341Sstevel static void ehc_stop_pcf8584(struct ehc_envcunit *);
187*1341Sstevel static int ehc_read_pcf8584(struct ehc_envcunit *, uint8_t *);
188*1341Sstevel static int ehc_write_pcf8584(struct ehc_envcunit *, uint8_t);
189*1341Sstevel static int ehc_after_read_pcf8584(struct ehc_envcunit *, uint8_t *);
190*1341Sstevel
191*1341Sstevel /*
192*1341Sstevel * put host interface into master mode
193*1341Sstevel */
194*1341Sstevel static int
ehc_start_pcf8584(struct ehc_envcunit * ehcp,uint8_t byteaddress)195*1341Sstevel ehc_start_pcf8584(struct ehc_envcunit *ehcp, uint8_t byteaddress)
196*1341Sstevel {
197*1341Sstevel uint8_t poll_status;
198*1341Sstevel uint8_t discard;
199*1341Sstevel int i;
200*1341Sstevel
201*1341Sstevel /* wait if bus is busy */
202*1341Sstevel
203*1341Sstevel i = 0;
204*1341Sstevel do {
205*1341Sstevel drv_usecwait(1000);
206*1341Sstevel poll_status =
207*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
208*1341Sstevel i++;
209*1341Sstevel } while (((poll_status & EHC_S1_NBB) == 0) && i < EHC_MAX_WAIT);
210*1341Sstevel
211*1341Sstevel if (i == EHC_MAX_WAIT) {
212*1341Sstevel DCMN_ERR(CE_WARN, "ehc_start_pcf8584(): busy bit clear failed");
213*1341Sstevel return (EHC_FAILURE);
214*1341Sstevel }
215*1341Sstevel
216*1341Sstevel if (poll_status & EHC_S1_BER) {
217*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()1: Bus error");
218*1341Sstevel ehc_init_pcf8584(ehcp);
219*1341Sstevel return (EHC_FAILURE);
220*1341Sstevel }
221*1341Sstevel
222*1341Sstevel if (poll_status & EHC_S1_LAB) {
223*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()1: Lost Arbitration");
224*1341Sstevel ehc_init_pcf8584(ehcp);
225*1341Sstevel return (EHC_FAILURE);
226*1341Sstevel }
227*1341Sstevel
228*1341Sstevel /*
229*1341Sstevel * This is a dummy arbitration using the lowest unused address
230*1341Sstevel * possible. This step allows the PCF8584 to always win arbitration
231*1341Sstevel * except in the case of "general call" being issued by the other
232*1341Sstevel * master.
233*1341Sstevel */
234*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, DUMMY_WRITE_ADDR);
235*1341Sstevel
236*1341Sstevel /* generate the "start condition" and clock out the slave address */
237*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
238*1341Sstevel EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK);
239*1341Sstevel
240*1341Sstevel /* wait for completion of transmission */
241*1341Sstevel i = 0;
242*1341Sstevel do {
243*1341Sstevel drv_usecwait(1000);
244*1341Sstevel poll_status =
245*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
246*1341Sstevel i++;
247*1341Sstevel } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
248*1341Sstevel
249*1341Sstevel if (i == EHC_MAX_WAIT) {
250*1341Sstevel DCMN_ERR(CE_WARN, "ehc_start_pcf8584_5(): read of S1 failed");
251*1341Sstevel return (EHC_FAILURE);
252*1341Sstevel }
253*1341Sstevel
254*1341Sstevel if (poll_status & EHC_S1_BER) {
255*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()5: Bus error");
256*1341Sstevel ehc_init_pcf8584(ehcp);
257*1341Sstevel return (EHC_FAILURE);
258*1341Sstevel }
259*1341Sstevel
260*1341Sstevel if (poll_status & EHC_S1_LAB) {
261*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()5: Lost Arbitration");
262*1341Sstevel ehc_init_pcf8584(ehcp);
263*1341Sstevel return (EHC_FAILURE);
264*1341Sstevel }
265*1341Sstevel
266*1341Sstevel /* dummy write */
267*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, DUMMY_WRITE_DATA);
268*1341Sstevel
269*1341Sstevel /* wait for completion of transmission */
270*1341Sstevel i = 0;
271*1341Sstevel do {
272*1341Sstevel drv_usecwait(1000);
273*1341Sstevel poll_status =
274*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
275*1341Sstevel i++;
276*1341Sstevel } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
277*1341Sstevel
278*1341Sstevel if (i == EHC_MAX_WAIT) {
279*1341Sstevel DCMN_ERR(CE_WARN, "ehc_start_pcf8584(): read of S1 failed");
280*1341Sstevel return (EHC_FAILURE);
281*1341Sstevel }
282*1341Sstevel
283*1341Sstevel if (poll_status & EHC_S1_BER) {
284*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()4: Bus error");
285*1341Sstevel ehc_init_pcf8584(ehcp);
286*1341Sstevel return (EHC_FAILURE);
287*1341Sstevel }
288*1341Sstevel
289*1341Sstevel if (poll_status & EHC_S1_LAB) {
290*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()4: Lost Arbitration");
291*1341Sstevel ehc_init_pcf8584(ehcp);
292*1341Sstevel return (EHC_FAILURE);
293*1341Sstevel }
294*1341Sstevel
295*1341Sstevel /*
296*1341Sstevel * generate the repeated "start condition" and
297*1341Sstevel * clock out the slave address
298*1341Sstevel */
299*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
300*1341Sstevel EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK);
301*1341Sstevel
302*1341Sstevel /* load the slave address */
303*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, byteaddress);
304*1341Sstevel
305*1341Sstevel /* wait for completion of transmission */
306*1341Sstevel i = 0;
307*1341Sstevel do {
308*1341Sstevel drv_usecwait(1000);
309*1341Sstevel poll_status =
310*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
311*1341Sstevel i++;
312*1341Sstevel } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
313*1341Sstevel
314*1341Sstevel if (i == EHC_MAX_WAIT) {
315*1341Sstevel DCMN_ERR(CE_WARN, "ehc_start_pcf8584(): read of S1 failed");
316*1341Sstevel return (EHC_FAILURE);
317*1341Sstevel }
318*1341Sstevel
319*1341Sstevel if (poll_status & EHC_S1_BER) {
320*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()2: Bus error");
321*1341Sstevel ehc_init_pcf8584(ehcp);
322*1341Sstevel return (EHC_FAILURE);
323*1341Sstevel }
324*1341Sstevel
325*1341Sstevel if (poll_status & EHC_S1_LAB) {
326*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()2: Lost Arbitration");
327*1341Sstevel ehc_init_pcf8584(ehcp);
328*1341Sstevel return (EHC_FAILURE);
329*1341Sstevel }
330*1341Sstevel
331*1341Sstevel if (poll_status & EHC_S1_LRB) {
332*1341Sstevel DCMN_ERR(CE_WARN, "ehc_start_pcf8584(): No slave ACK");
333*1341Sstevel return (EHC_NO_SLAVE_ACK);
334*1341Sstevel }
335*1341Sstevel
336*1341Sstevel /*
337*1341Sstevel * If this is a read we are setting up for (as indicated by
338*1341Sstevel * the least significant byte being set), read
339*1341Sstevel * and discard the first byte off the bus - this
340*1341Sstevel * is the slave address.
341*1341Sstevel */
342*1341Sstevel
343*1341Sstevel i = 0;
344*1341Sstevel if (byteaddress & EHC_BYTE_READ) {
345*1341Sstevel discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
346*1341Sstevel #ifdef lint
347*1341Sstevel discard = discard;
348*1341Sstevel #endif
349*1341Sstevel
350*1341Sstevel /* wait for completion of transmission */
351*1341Sstevel do {
352*1341Sstevel drv_usecwait(1000);
353*1341Sstevel poll_status =
354*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
355*1341Sstevel i++;
356*1341Sstevel } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
357*1341Sstevel
358*1341Sstevel if (i == EHC_MAX_WAIT) {
359*1341Sstevel DCMN_ERR(CE_WARN,
360*1341Sstevel "ehc_start_pcf8584(): read of S1 failed");
361*1341Sstevel return (EHC_FAILURE);
362*1341Sstevel }
363*1341Sstevel
364*1341Sstevel if (poll_status & EHC_S1_BER) {
365*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_start_pcf8584()3: Bus error");
366*1341Sstevel ehc_init_pcf8584(ehcp);
367*1341Sstevel return (EHC_FAILURE);
368*1341Sstevel }
369*1341Sstevel if (poll_status & EHC_S1_LAB) {
370*1341Sstevel DCMN2_ERR(CE_WARN,
371*1341Sstevel "ehc_start_pcf8584()3: Lost Arbitration");
372*1341Sstevel ehc_init_pcf8584(ehcp);
373*1341Sstevel return (EHC_FAILURE);
374*1341Sstevel }
375*1341Sstevel
376*1341Sstevel }
377*1341Sstevel
378*1341Sstevel return (EHC_SUCCESS);
379*1341Sstevel }
380*1341Sstevel
381*1341Sstevel /*
382*1341Sstevel * put host interface into slave/receiver mode
383*1341Sstevel */
384*1341Sstevel static void
ehc_stop_pcf8584(struct ehc_envcunit * ehcp)385*1341Sstevel ehc_stop_pcf8584(struct ehc_envcunit *ehcp)
386*1341Sstevel {
387*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
388*1341Sstevel EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_STO | EHC_S1_ACK);
389*1341Sstevel }
390*1341Sstevel
391*1341Sstevel static int
ehc_read_pcf8584(struct ehc_envcunit * ehcp,uint8_t * data)392*1341Sstevel ehc_read_pcf8584(struct ehc_envcunit *ehcp, uint8_t *data)
393*1341Sstevel {
394*1341Sstevel uint8_t poll_status;
395*1341Sstevel int i = 0;
396*1341Sstevel
397*1341Sstevel /* Read the byte of interest */
398*1341Sstevel *data = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
399*1341Sstevel
400*1341Sstevel /* wait for completion of transmission */
401*1341Sstevel do {
402*1341Sstevel drv_usecwait(1000);
403*1341Sstevel poll_status =
404*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
405*1341Sstevel i++;
406*1341Sstevel } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
407*1341Sstevel
408*1341Sstevel if (i == EHC_MAX_WAIT) {
409*1341Sstevel DCMN_ERR(CE_WARN, "ehc_read_pcf8584(): read of S1 failed");
410*1341Sstevel return (EHC_FAILURE);
411*1341Sstevel }
412*1341Sstevel
413*1341Sstevel if (poll_status & EHC_S1_BER) {
414*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_read_pcf8584(): Bus error");
415*1341Sstevel ehc_init_pcf8584(ehcp);
416*1341Sstevel return (EHC_FAILURE);
417*1341Sstevel }
418*1341Sstevel
419*1341Sstevel if (poll_status & EHC_S1_LAB) {
420*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_read_pcf8584(): Lost Arbitration");
421*1341Sstevel ehc_init_pcf8584(ehcp);
422*1341Sstevel return (EHC_FAILURE);
423*1341Sstevel }
424*1341Sstevel
425*1341Sstevel return (EHC_SUCCESS);
426*1341Sstevel }
427*1341Sstevel
428*1341Sstevel /*
429*1341Sstevel * host interface is in transmitter state, thus mode is master/transmitter
430*1341Sstevel * NOTE to Bill: this check the LRB bit (only done in transmit mode).
431*1341Sstevel */
432*1341Sstevel
433*1341Sstevel static int
ehc_write_pcf8584(struct ehc_envcunit * ehcp,uint8_t data)434*1341Sstevel ehc_write_pcf8584(struct ehc_envcunit *ehcp, uint8_t data)
435*1341Sstevel {
436*1341Sstevel uint8_t poll_status;
437*1341Sstevel int i = 0;
438*1341Sstevel
439*1341Sstevel /* send the data, EHC_S1_PIN should go to "1" immediately */
440*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, data);
441*1341Sstevel
442*1341Sstevel /* wait for completion of transmission */
443*1341Sstevel do {
444*1341Sstevel drv_usecwait(1000);
445*1341Sstevel poll_status =
446*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
447*1341Sstevel i++;
448*1341Sstevel } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
449*1341Sstevel
450*1341Sstevel if (i == EHC_MAX_WAIT) {
451*1341Sstevel DCMN_ERR(CE_WARN, "ehc_write_pcf8584(): read of S1 failed");
452*1341Sstevel return (EHC_FAILURE);
453*1341Sstevel }
454*1341Sstevel
455*1341Sstevel if (poll_status & EHC_S1_BER) {
456*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_write_pcf8584(): Bus error");
457*1341Sstevel ehc_init_pcf8584(ehcp);
458*1341Sstevel return (EHC_FAILURE);
459*1341Sstevel }
460*1341Sstevel
461*1341Sstevel if (poll_status & EHC_S1_LAB) {
462*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_write_pcf8584(): Lost Arbitration");
463*1341Sstevel ehc_init_pcf8584(ehcp);
464*1341Sstevel return (EHC_FAILURE);
465*1341Sstevel }
466*1341Sstevel
467*1341Sstevel if (poll_status & EHC_S1_LRB) {
468*1341Sstevel DCMN_ERR(CE_WARN, "ehc_write_pcf8584(): No slave ACK");
469*1341Sstevel return (EHC_NO_SLAVE_ACK);
470*1341Sstevel }
471*1341Sstevel
472*1341Sstevel return (EHC_SUCCESS);
473*1341Sstevel }
474*1341Sstevel
475*1341Sstevel static int
ehc_after_read_pcf8584(struct ehc_envcunit * ehcp,uint8_t * data)476*1341Sstevel ehc_after_read_pcf8584(struct ehc_envcunit *ehcp, uint8_t *data)
477*1341Sstevel {
478*1341Sstevel uint8_t discard;
479*1341Sstevel uint8_t poll_status;
480*1341Sstevel int i = 0;
481*1341Sstevel
482*1341Sstevel /* set ACK in register S1 to 0 */
483*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, EHC_S1_ES0);
484*1341Sstevel
485*1341Sstevel /*
486*1341Sstevel * Read the "byte-before-the-last-byte" - sets PIN bit to '1'
487*1341Sstevel */
488*1341Sstevel
489*1341Sstevel *data = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
490*1341Sstevel
491*1341Sstevel /* wait for completion of transmission */
492*1341Sstevel do {
493*1341Sstevel drv_usecwait(1000);
494*1341Sstevel poll_status =
495*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
496*1341Sstevel i++;
497*1341Sstevel } while ((poll_status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
498*1341Sstevel
499*1341Sstevel if (i == EHC_MAX_WAIT) {
500*1341Sstevel DCMN_ERR(CE_WARN, "ehc_after_rd_pcf8584(): read of S1 failed");
501*1341Sstevel return (EHC_FAILURE);
502*1341Sstevel }
503*1341Sstevel
504*1341Sstevel if (poll_status & EHC_S1_BER) {
505*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_after_rd_pcf8584(): Bus error");
506*1341Sstevel ehc_init_pcf8584(ehcp);
507*1341Sstevel return (EHC_FAILURE);
508*1341Sstevel }
509*1341Sstevel
510*1341Sstevel if (poll_status & EHC_S1_LAB) {
511*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_after_rd_pcf8584(): Lost Arbitration");
512*1341Sstevel ehc_init_pcf8584(ehcp);
513*1341Sstevel return (EHC_FAILURE);
514*1341Sstevel }
515*1341Sstevel
516*1341Sstevel /*
517*1341Sstevel * Generate the "stop" condition.
518*1341Sstevel */
519*1341Sstevel ehc_stop_pcf8584(ehcp);
520*1341Sstevel
521*1341Sstevel /*
522*1341Sstevel * Read the "last" byte.
523*1341Sstevel */
524*1341Sstevel discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
525*1341Sstevel #ifdef lint
526*1341Sstevel discard = discard;
527*1341Sstevel #endif
528*1341Sstevel
529*1341Sstevel return (EHC_SUCCESS);
530*1341Sstevel }
531*1341Sstevel
532*1341Sstevel /*
533*1341Sstevel * Below this comment are the externally visible routines comprising the API
534*1341Sstevel */
535*1341Sstevel
536*1341Sstevel /*
537*1341Sstevel * Initialize the 8584 chip
538*1341Sstevel */
539*1341Sstevel
540*1341Sstevel void
ehc_init_pcf8584(struct ehc_envcunit * ehcp)541*1341Sstevel ehc_init_pcf8584(struct ehc_envcunit *ehcp)
542*1341Sstevel {
543*1341Sstevel /*
544*1341Sstevel * Writing PIN bit of S1 causes software reset.
545*1341Sstevel * The next write to S0 will be S0' "own address".
546*1341Sstevel */
547*1341Sstevel
548*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1, EHC_S1_PIN);
549*1341Sstevel
550*1341Sstevel /*
551*1341Sstevel * Write the address which the controller chip will use
552*1341Sstevel * (when addressed as a slave) on the I2C bus.
553*1341Sstevel * DAF - should own address be passed as argument?
554*1341Sstevel */
555*1341Sstevel
556*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, EHC_S0_OWN);
557*1341Sstevel
558*1341Sstevel /*
559*1341Sstevel * Writing PIN bit and ES1 bit of S1 causes software
560*1341Sstevel * reset and selects the S2 register for writing.
561*1341Sstevel * Now, the next write to S0 will be the S2 clock
562*1341Sstevel * control register.
563*1341Sstevel */
564*1341Sstevel
565*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
566*1341Sstevel EHC_S1_PIN | EHC_S1_ES1);
567*1341Sstevel
568*1341Sstevel /*
569*1341Sstevel * Write the value into register that sets internal system clock
570*1341Sstevel * to 12 Mhz, and the I2C bus rate (SCL) to 9 Khz.
571*1341Sstevel * DAF - should these be parameters?
572*1341Sstevel */
573*1341Sstevel
574*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0, EHC_S0_CLK);
575*1341Sstevel
576*1341Sstevel /*
577*1341Sstevel * Writing PIN bit causes software reset and the ES0 bit
578*1341Sstevel * selects the (S0) register for reading/writing. The ACK
579*1341Sstevel * bit being set causes controller to send ACK after each
580*1341Sstevel * byte.
581*1341Sstevel */
582*1341Sstevel
583*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
584*1341Sstevel EHC_S1_PIN | EHC_S1_ES0 | EHC_S1_ACK);
585*1341Sstevel
586*1341Sstevel /*
587*1341Sstevel * Multi-Master: Wait for a period of time equal to the
588*1341Sstevel * longest I2C message. This accounts for the case
589*1341Sstevel * where multiple controllers and, if this particular one
590*1341Sstevel * is "lagging", misses the BB (bus busy) condition.
591*1341Sstevel * DAF - What does this need?
592*1341Sstevel * We wait 200 ms since the longest transaction at this time
593*1341Sstevel * on the i2c bus is a 256 byte read from the seprom which takes
594*1341Sstevel * about 75 ms. Some additional buffer does no harm to the driver.
595*1341Sstevel */
596*1341Sstevel
597*1341Sstevel drv_usecwait(EHC_LONGEST_MSG);
598*1341Sstevel
599*1341Sstevel }
600*1341Sstevel
601*1341Sstevel int
ehc_read_tda8444(struct ehc_envcunit * ehcp)602*1341Sstevel ehc_read_tda8444(struct ehc_envcunit *ehcp)
603*1341Sstevel {
604*1341Sstevel #ifdef lint
605*1341Sstevel ehcp = ehcp;
606*1341Sstevel #endif
607*1341Sstevel return (EHC_FAILURE);
608*1341Sstevel }
609*1341Sstevel
610*1341Sstevel /*
611*1341Sstevel * Write to the TDA8444 chip.
612*1341Sstevel * byteaddress = chip type base address | chip offset address.
613*1341Sstevel */
614*1341Sstevel int
ehc_write_tda8444(struct ehc_envcunit * ehcp,int byteaddress,int instruction,int subaddress,uint8_t * buf,int size)615*1341Sstevel ehc_write_tda8444(struct ehc_envcunit *ehcp, int byteaddress, int instruction,
616*1341Sstevel int subaddress, uint8_t *buf, int size)
617*1341Sstevel {
618*1341Sstevel uint8_t control;
619*1341Sstevel int i, status;
620*1341Sstevel
621*1341Sstevel ASSERT((byteaddress & 0x1) == 0);
622*1341Sstevel ASSERT(subaddress < 8);
623*1341Sstevel ASSERT(instruction == 0xf || instruction == 0x0);
624*1341Sstevel ASSERT(MUTEX_HELD(&ehcp->umutex));
625*1341Sstevel
626*1341Sstevel control = (instruction << 4) | subaddress;
627*1341Sstevel
628*1341Sstevel if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
629*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
630*1341Sstevel /*
631*1341Sstevel * Send the "stop" condition.
632*1341Sstevel */
633*1341Sstevel ehc_stop_pcf8584(ehcp);
634*1341Sstevel }
635*1341Sstevel return (EHC_FAILURE);
636*1341Sstevel }
637*1341Sstevel
638*1341Sstevel if ((status = ehc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) {
639*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
640*1341Sstevel /*
641*1341Sstevel * Send the "stop" condition.
642*1341Sstevel */
643*1341Sstevel ehc_stop_pcf8584(ehcp);
644*1341Sstevel }
645*1341Sstevel return (EHC_FAILURE);
646*1341Sstevel }
647*1341Sstevel
648*1341Sstevel for (i = 0; i < size; i++) {
649*1341Sstevel if ((status = ehc_write_pcf8584(ehcp, (buf[i] & 0x3f))) !=
650*1341Sstevel EHC_SUCCESS) {
651*1341Sstevel if (status == EHC_NO_SLAVE_ACK)
652*1341Sstevel ehc_stop_pcf8584(ehcp);
653*1341Sstevel return (EHC_FAILURE);
654*1341Sstevel }
655*1341Sstevel }
656*1341Sstevel
657*1341Sstevel ehc_stop_pcf8584(ehcp);
658*1341Sstevel
659*1341Sstevel return (EHC_SUCCESS);
660*1341Sstevel }
661*1341Sstevel
662*1341Sstevel /*
663*1341Sstevel * Read from PCF8574A chip.
664*1341Sstevel * byteaddress = chip type base address | chip offset address.
665*1341Sstevel */
666*1341Sstevel int
ehc_read_pcf8574a(struct ehc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)667*1341Sstevel ehc_read_pcf8574a(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
668*1341Sstevel int size)
669*1341Sstevel {
670*1341Sstevel int i;
671*1341Sstevel int status;
672*1341Sstevel uint8_t discard;
673*1341Sstevel
674*1341Sstevel ASSERT((byteaddress & 0x1) == 0);
675*1341Sstevel ASSERT(MUTEX_HELD(&ehcp->umutex));
676*1341Sstevel
677*1341Sstevel /*
678*1341Sstevel * Put the bus into the start condition
679*1341Sstevel */
680*1341Sstevel if ((status = ehc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) !=
681*1341Sstevel EHC_SUCCESS) {
682*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
683*1341Sstevel /*
684*1341Sstevel * Send the "stop" condition.
685*1341Sstevel */
686*1341Sstevel ehc_stop_pcf8584(ehcp);
687*1341Sstevel /*
688*1341Sstevel * Read the last byte - discard it.
689*1341Sstevel */
690*1341Sstevel discard =
691*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
692*1341Sstevel #ifdef lint
693*1341Sstevel discard = discard;
694*1341Sstevel #endif
695*1341Sstevel }
696*1341Sstevel return (EHC_FAILURE);
697*1341Sstevel }
698*1341Sstevel
699*1341Sstevel for (i = 0; i < size - 1; i++) {
700*1341Sstevel if ((status = ehc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
701*1341Sstevel return (EHC_FAILURE);
702*1341Sstevel }
703*1341Sstevel }
704*1341Sstevel
705*1341Sstevel /*
706*1341Sstevel * Handle the part of the bus protocol which comes
707*1341Sstevel * after a read, including reading the last byte.
708*1341Sstevel */
709*1341Sstevel
710*1341Sstevel if (ehc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
711*1341Sstevel return (EHC_FAILURE);
712*1341Sstevel }
713*1341Sstevel
714*1341Sstevel return (EHC_SUCCESS);
715*1341Sstevel }
716*1341Sstevel
717*1341Sstevel /*
718*1341Sstevel * Write to the PCF8574A chip.
719*1341Sstevel * byteaddress = chip type base address | chip offset address.
720*1341Sstevel */
721*1341Sstevel int
ehc_write_pcf8574a(struct ehc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)722*1341Sstevel ehc_write_pcf8574a(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
723*1341Sstevel int size)
724*1341Sstevel {
725*1341Sstevel int i;
726*1341Sstevel int status;
727*1341Sstevel
728*1341Sstevel ASSERT((byteaddress & 0x1) == 0);
729*1341Sstevel ASSERT(MUTEX_HELD(&ehcp->umutex));
730*1341Sstevel
731*1341Sstevel /*
732*1341Sstevel * Put the bus into the start condition (write)
733*1341Sstevel */
734*1341Sstevel if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
735*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
736*1341Sstevel /*
737*1341Sstevel * Send the "stop" condition.
738*1341Sstevel */
739*1341Sstevel ehc_stop_pcf8584(ehcp);
740*1341Sstevel }
741*1341Sstevel return (EHC_FAILURE);
742*1341Sstevel }
743*1341Sstevel
744*1341Sstevel /*
745*1341Sstevel * Send the data - poll as needed.
746*1341Sstevel */
747*1341Sstevel for (i = 0; i < size; i++) {
748*1341Sstevel if ((status = ehc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) {
749*1341Sstevel if (status == EHC_NO_SLAVE_ACK)
750*1341Sstevel ehc_stop_pcf8584(ehcp);
751*1341Sstevel return (EHC_FAILURE);
752*1341Sstevel }
753*1341Sstevel }
754*1341Sstevel
755*1341Sstevel /*
756*1341Sstevel * Transmission complete - generate stop condition and
757*1341Sstevel * put device back into slave receiver mode.
758*1341Sstevel */
759*1341Sstevel ehc_stop_pcf8584(ehcp);
760*1341Sstevel
761*1341Sstevel return (EHC_SUCCESS);
762*1341Sstevel }
763*1341Sstevel
764*1341Sstevel /*
765*1341Sstevel * Read from the PCF8574 chip.
766*1341Sstevel * byteaddress = chip type base address | chip offset address.
767*1341Sstevel */
768*1341Sstevel int
ehc_read_pcf8574(struct ehc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)769*1341Sstevel ehc_read_pcf8574(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
770*1341Sstevel int size)
771*1341Sstevel {
772*1341Sstevel int i;
773*1341Sstevel int status;
774*1341Sstevel uint8_t discard;
775*1341Sstevel
776*1341Sstevel ASSERT((byteaddress & 0x1) == 0);
777*1341Sstevel ASSERT(MUTEX_HELD(&ehcp->umutex));
778*1341Sstevel
779*1341Sstevel /*
780*1341Sstevel * Put the bus into the start condition
781*1341Sstevel */
782*1341Sstevel if ((status = ehc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) !=
783*1341Sstevel EHC_SUCCESS) {
784*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
785*1341Sstevel /*
786*1341Sstevel * Send the "stop" condition.
787*1341Sstevel */
788*1341Sstevel ehc_stop_pcf8584(ehcp);
789*1341Sstevel /*
790*1341Sstevel * Read the last byte - discard it.
791*1341Sstevel */
792*1341Sstevel discard =
793*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
794*1341Sstevel #ifdef lint
795*1341Sstevel discard = discard;
796*1341Sstevel #endif
797*1341Sstevel }
798*1341Sstevel return (EHC_FAILURE);
799*1341Sstevel }
800*1341Sstevel
801*1341Sstevel for (i = 0; i < size - 1; i++) {
802*1341Sstevel if ((status = ehc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
803*1341Sstevel return (EHC_FAILURE);
804*1341Sstevel }
805*1341Sstevel }
806*1341Sstevel
807*1341Sstevel /*
808*1341Sstevel * Handle the part of the bus protocol which comes
809*1341Sstevel * after a read.
810*1341Sstevel */
811*1341Sstevel
812*1341Sstevel if (ehc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
813*1341Sstevel return (EHC_FAILURE);
814*1341Sstevel }
815*1341Sstevel
816*1341Sstevel return (EHC_SUCCESS);
817*1341Sstevel }
818*1341Sstevel
819*1341Sstevel /*
820*1341Sstevel * Write to the PCF8574 chip.
821*1341Sstevel * byteaddress = chip type base address | chip offset address.
822*1341Sstevel */
823*1341Sstevel int
ehc_write_pcf8574(struct ehc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)824*1341Sstevel ehc_write_pcf8574(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
825*1341Sstevel int size)
826*1341Sstevel {
827*1341Sstevel int i;
828*1341Sstevel int status;
829*1341Sstevel
830*1341Sstevel ASSERT((byteaddress & 0x1) == 0);
831*1341Sstevel ASSERT(MUTEX_HELD(&ehcp->umutex));
832*1341Sstevel
833*1341Sstevel /*
834*1341Sstevel * Put the bus into the start condition (write)
835*1341Sstevel */
836*1341Sstevel if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
837*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
838*1341Sstevel /*
839*1341Sstevel * Send the "stop" condition.
840*1341Sstevel */
841*1341Sstevel ehc_stop_pcf8584(ehcp);
842*1341Sstevel }
843*1341Sstevel return (EHC_FAILURE);
844*1341Sstevel }
845*1341Sstevel
846*1341Sstevel /*
847*1341Sstevel * Send the data - poll as needed.
848*1341Sstevel */
849*1341Sstevel for (i = 0; i < size; i++) {
850*1341Sstevel if ((status = ehc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) {
851*1341Sstevel if (status == EHC_NO_SLAVE_ACK)
852*1341Sstevel ehc_stop_pcf8584(ehcp);
853*1341Sstevel return (EHC_FAILURE);
854*1341Sstevel }
855*1341Sstevel }
856*1341Sstevel /*
857*1341Sstevel * Transmission complete - generate stop condition and
858*1341Sstevel * put device back into slave receiver mode.
859*1341Sstevel */
860*1341Sstevel ehc_stop_pcf8584(ehcp);
861*1341Sstevel
862*1341Sstevel return (EHC_SUCCESS);
863*1341Sstevel }
864*1341Sstevel
865*1341Sstevel /*
866*1341Sstevel * Read from the LM75
867*1341Sstevel * byteaddress = chip type base address | chip offset address.
868*1341Sstevel */
869*1341Sstevel int
ehc_read_lm75(struct ehc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)870*1341Sstevel ehc_read_lm75(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
871*1341Sstevel int size)
872*1341Sstevel {
873*1341Sstevel int i;
874*1341Sstevel int status;
875*1341Sstevel uint8_t discard;
876*1341Sstevel
877*1341Sstevel ASSERT((byteaddress & 0x1) == 0);
878*1341Sstevel ASSERT(MUTEX_HELD(&ehcp->umutex));
879*1341Sstevel
880*1341Sstevel /*
881*1341Sstevel * Put the bus into the start condition
882*1341Sstevel */
883*1341Sstevel if ((status = ehc_start_pcf8584(ehcp, EHC_BYTE_READ | byteaddress)) !=
884*1341Sstevel EHC_SUCCESS) {
885*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
886*1341Sstevel /*
887*1341Sstevel * Send the stop condition.
888*1341Sstevel */
889*1341Sstevel ehc_stop_pcf8584(ehcp);
890*1341Sstevel /*
891*1341Sstevel * Read the last byte - discard it.
892*1341Sstevel */
893*1341Sstevel discard =
894*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
895*1341Sstevel #ifdef lint
896*1341Sstevel discard = discard;
897*1341Sstevel #endif
898*1341Sstevel }
899*1341Sstevel return (EHC_FAILURE);
900*1341Sstevel }
901*1341Sstevel
902*1341Sstevel for (i = 0; i < size - 1; i++) {
903*1341Sstevel if ((status = ehc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
904*1341Sstevel return (EHC_FAILURE);
905*1341Sstevel }
906*1341Sstevel }
907*1341Sstevel
908*1341Sstevel /*
909*1341Sstevel * Handle the part of the bus protocol which comes
910*1341Sstevel * after a read.
911*1341Sstevel */
912*1341Sstevel if (ehc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
913*1341Sstevel return (EHC_FAILURE);
914*1341Sstevel }
915*1341Sstevel
916*1341Sstevel return (EHC_SUCCESS);
917*1341Sstevel }
918*1341Sstevel
919*1341Sstevel /*
920*1341Sstevel * Write to the PCF8583 chip.
921*1341Sstevel * byteaddress = chip type base address | chip offset address.
922*1341Sstevel */
923*1341Sstevel int
ehc_write_pcf8583(struct ehc_envcunit * ehcp,int byteaddress,uint8_t * buf,int size)924*1341Sstevel ehc_write_pcf8583(struct ehc_envcunit *ehcp, int byteaddress, uint8_t *buf,
925*1341Sstevel int size)
926*1341Sstevel {
927*1341Sstevel int i;
928*1341Sstevel int status;
929*1341Sstevel
930*1341Sstevel ASSERT((byteaddress & 0x1) == 0);
931*1341Sstevel ASSERT(MUTEX_HELD(&ehcp->umutex));
932*1341Sstevel
933*1341Sstevel if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
934*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
935*1341Sstevel /*
936*1341Sstevel * Send the "stop" condition.
937*1341Sstevel */
938*1341Sstevel ehc_stop_pcf8584(ehcp);
939*1341Sstevel }
940*1341Sstevel return (EHC_FAILURE);
941*1341Sstevel }
942*1341Sstevel
943*1341Sstevel /*
944*1341Sstevel * Send the data - poll as needed.
945*1341Sstevel */
946*1341Sstevel for (i = 0; i < size; i++) {
947*1341Sstevel if ((status = ehc_write_pcf8584(ehcp, buf[i])) != EHC_SUCCESS) {
948*1341Sstevel if (status == EHC_NO_SLAVE_ACK)
949*1341Sstevel ehc_stop_pcf8584(ehcp);
950*1341Sstevel return (EHC_FAILURE);
951*1341Sstevel }
952*1341Sstevel }
953*1341Sstevel
954*1341Sstevel /*
955*1341Sstevel * Transmission complete - generate stop condition and
956*1341Sstevel * put device back into slave receiver mode.
957*1341Sstevel */
958*1341Sstevel ehc_stop_pcf8584(ehcp);
959*1341Sstevel
960*1341Sstevel return (EHC_SUCCESS);
961*1341Sstevel }
962*1341Sstevel
963*1341Sstevel /*
964*1341Sstevel * Read from the PCF8591 chip.
965*1341Sstevel */
966*1341Sstevel int
ehc_read_pcf8591(struct ehc_envcunit * ehcp,int byteaddress,int channel,int autoinc,int amode,int aenable,uint8_t * buf,int size)967*1341Sstevel ehc_read_pcf8591(struct ehc_envcunit *ehcp, int byteaddress, int channel,
968*1341Sstevel int autoinc, int amode, int aenable, uint8_t *buf, int size)
969*1341Sstevel {
970*1341Sstevel int i;
971*1341Sstevel int status;
972*1341Sstevel register uint8_t control;
973*1341Sstevel uint8_t discard;
974*1341Sstevel
975*1341Sstevel ASSERT((byteaddress & 0x1) == 0);
976*1341Sstevel ASSERT(channel < 4);
977*1341Sstevel ASSERT(amode < 4);
978*1341Sstevel ASSERT(MUTEX_HELD(&ehcp->umutex));
979*1341Sstevel
980*1341Sstevel /*
981*1341Sstevel * Write the control word to the PCF8591.
982*1341Sstevel * Follow the control word with a repeated START byte
983*1341Sstevel * rather than a STOP so that reads can follow without giving
984*1341Sstevel * up the bus.
985*1341Sstevel */
986*1341Sstevel
987*1341Sstevel control = ((aenable << 6) | (amode << 4) | (autoinc << 2) | channel);
988*1341Sstevel
989*1341Sstevel if ((status = ehc_start_pcf8584(ehcp, byteaddress)) != EHC_SUCCESS) {
990*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
991*1341Sstevel ehc_stop_pcf8584(ehcp);
992*1341Sstevel }
993*1341Sstevel return (EHC_FAILURE);
994*1341Sstevel }
995*1341Sstevel
996*1341Sstevel if ((status = ehc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) {
997*1341Sstevel if (status == EHC_NO_SLAVE_ACK)
998*1341Sstevel ehc_stop_pcf8584(ehcp);
999*1341Sstevel return (EHC_FAILURE);
1000*1341Sstevel }
1001*1341Sstevel
1002*1341Sstevel /*
1003*1341Sstevel * The following two operations, 0x45 to S1, and the byteaddress
1004*1341Sstevel * to S0, will result in a repeated START being sent out on the bus.
1005*1341Sstevel * Refer to Fig.8 of Philips Semiconductors PCF8584 product spec.
1006*1341Sstevel */
1007*1341Sstevel
1008*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1,
1009*1341Sstevel EHC_S1_ES0 | EHC_S1_STA | EHC_S1_ACK);
1010*1341Sstevel
1011*1341Sstevel ddi_put8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0,
1012*1341Sstevel EHC_BYTE_READ | byteaddress);
1013*1341Sstevel
1014*1341Sstevel i = 0;
1015*1341Sstevel
1016*1341Sstevel do {
1017*1341Sstevel drv_usecwait(1000);
1018*1341Sstevel status =
1019*1341Sstevel ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s1);
1020*1341Sstevel i++;
1021*1341Sstevel } while ((status & EHC_S1_PIN) && i < EHC_MAX_WAIT);
1022*1341Sstevel
1023*1341Sstevel if (i == EHC_MAX_WAIT) {
1024*1341Sstevel DCMN_ERR(CE_WARN, "ehc_read_pcf8591(): read of S1 failed");
1025*1341Sstevel return (EHC_FAILURE);
1026*1341Sstevel }
1027*1341Sstevel
1028*1341Sstevel if (status & EHC_S1_BER) {
1029*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_read_pcf8591(): Bus error");
1030*1341Sstevel ehc_init_pcf8584(ehcp);
1031*1341Sstevel return (EHC_FAILURE);
1032*1341Sstevel }
1033*1341Sstevel
1034*1341Sstevel if (status & EHC_S1_LAB) {
1035*1341Sstevel DCMN2_ERR(CE_WARN, "ehc_read_pcf8591(): Lost Arbitration");
1036*1341Sstevel ehc_init_pcf8584(ehcp);
1037*1341Sstevel return (EHC_FAILURE);
1038*1341Sstevel }
1039*1341Sstevel
1040*1341Sstevel if (status & EHC_S1_LRB) {
1041*1341Sstevel DCMN_ERR(CE_WARN, "ehc_read_pcf8591(): No slave ACK");
1042*1341Sstevel /*
1043*1341Sstevel * Send the stop condition.
1044*1341Sstevel */
1045*1341Sstevel ehc_stop_pcf8584(ehcp);
1046*1341Sstevel /*
1047*1341Sstevel * Read the last byte - discard it.
1048*1341Sstevel */
1049*1341Sstevel discard = ddi_get8(ehcp->ctlr_handle, &ehcp->bus_ctl_regs->s0);
1050*1341Sstevel #ifdef lint
1051*1341Sstevel discard = discard;
1052*1341Sstevel #endif
1053*1341Sstevel return (EHC_FAILURE);
1054*1341Sstevel }
1055*1341Sstevel
1056*1341Sstevel /*
1057*1341Sstevel * Discard first read as per PCF8584 master receiver protocol.
1058*1341Sstevel * This is normally done in the ehc_start_pcf8584() routine.
1059*1341Sstevel */
1060*1341Sstevel if ((status = ehc_read_pcf8584(ehcp, &discard)) != EHC_SUCCESS) {
1061*1341Sstevel return (EHC_FAILURE);
1062*1341Sstevel }
1063*1341Sstevel
1064*1341Sstevel /* Discard second read as per PCF8591 protocol */
1065*1341Sstevel if ((status = ehc_read_pcf8584(ehcp, &discard)) != EHC_SUCCESS) {
1066*1341Sstevel return (EHC_FAILURE);
1067*1341Sstevel }
1068*1341Sstevel
1069*1341Sstevel for (i = 0; i < size - 1; i++) {
1070*1341Sstevel if ((status = ehc_read_pcf8584(ehcp, &buf[i])) != EHC_SUCCESS) {
1071*1341Sstevel return (EHC_FAILURE);
1072*1341Sstevel }
1073*1341Sstevel }
1074*1341Sstevel
1075*1341Sstevel if (ehc_after_read_pcf8584(ehcp, &buf[i]) != EHC_SUCCESS) {
1076*1341Sstevel return (EHC_FAILURE);
1077*1341Sstevel }
1078*1341Sstevel
1079*1341Sstevel return (EHC_SUCCESS);
1080*1341Sstevel }
1081*1341Sstevel
1082*1341Sstevel /*
1083*1341Sstevel * Write to the PCF8591 chip.
1084*1341Sstevel * byteaddress = chip type base address | chip offset address.
1085*1341Sstevel */
1086*1341Sstevel int
ehc_write_pcf8591(struct ehc_envcunit * ehcp,int byteaddress,int channel,int autoinc,int amode,int aenable,uint8_t * buf,int size)1087*1341Sstevel ehc_write_pcf8591(struct ehc_envcunit *ehcp, int byteaddress, int channel,
1088*1341Sstevel int autoinc, int amode, int aenable, uint8_t *buf, int size)
1089*1341Sstevel {
1090*1341Sstevel int i, status;
1091*1341Sstevel register uint8_t control;
1092*1341Sstevel
1093*1341Sstevel ASSERT((byteaddress & 0x1) == 0);
1094*1341Sstevel ASSERT(MUTEX_HELD(&ehcp->umutex));
1095*1341Sstevel
1096*1341Sstevel control = ((aenable << 6) | (amode << 4) | (autoinc << 2) | channel);
1097*1341Sstevel
1098*1341Sstevel status = ehc_start_pcf8584(ehcp, byteaddress);
1099*1341Sstevel if (status != EHC_SUCCESS) {
1100*1341Sstevel if (status == EHC_NO_SLAVE_ACK) {
1101*1341Sstevel /*
1102*1341Sstevel * Send the "stop" condition.
1103*1341Sstevel */
1104*1341Sstevel ehc_stop_pcf8584(ehcp);
1105*1341Sstevel }
1106*1341Sstevel return (EHC_FAILURE);
1107*1341Sstevel }
1108*1341Sstevel
1109*1341Sstevel if ((status = ehc_write_pcf8584(ehcp, control)) != EHC_SUCCESS) {
1110*1341Sstevel if (status == EHC_NO_SLAVE_ACK)
1111*1341Sstevel ehc_stop_pcf8584(ehcp);
1112*1341Sstevel return (EHC_FAILURE);
1113*1341Sstevel }
1114*1341Sstevel
1115*1341Sstevel for (i = 0; i < size; i++) {
1116*1341Sstevel status = ehc_write_pcf8584(ehcp, buf[i]);
1117*1341Sstevel if (status != EHC_SUCCESS) {
1118*1341Sstevel if (status == EHC_NO_SLAVE_ACK)
1119*1341Sstevel ehc_stop_pcf8584(ehcp);
1120*1341Sstevel return (EHC_FAILURE);
1121*1341Sstevel }
1122*1341Sstevel }
1123*1341Sstevel
1124*1341Sstevel ehc_stop_pcf8584(ehcp);
1125*1341Sstevel
1126*1341Sstevel return (EHC_SUCCESS);
1127*1341Sstevel }
1128