xref: /netbsd-src/sys/dev/ic/pca9564.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /*	$NetBSD: pca9564.c,v 1.2 2016/02/14 19:54:21 chs Exp $	*/
2 
3 /*
4  * Copyright (c) 2010 NONAKA Kimihiro <nonaka@netbsd.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: pca9564.c,v 1.2 2016/02/14 19:54:21 chs Exp $");
30 
31 #include <sys/param.h>
32 #include <sys/device.h>
33 #include <sys/mutex.h>
34 #include <sys/bus.h>
35 
36 #include <dev/i2c/i2cvar.h>
37 
38 #include <dev/ic/pca9564reg.h>
39 #include <dev/ic/pca9564var.h>
40 
41 #if defined(PCA9564_DEBUG)
42 int pca9564debug = 0;
43 #define	DPRINTF(s)	if (pca9564debug) printf s
44 #else
45 #define	DPRINTF(s)
46 #endif
47 
48 static int pca9564_acquire_bus(void *, int);
49 static void pca9564_release_bus(void *, int);
50 
51 static int pca9564_send_start(void *, int);
52 static int pca9564_send_stop(void *, int);
53 static int pca9564_initiate_xfer(void *, uint16_t, int);
54 static int pca9564_read_byte(void *, uint8_t *, int);
55 static int pca9564_write_byte(void *, uint8_t, int);
56 
57 static int pca9564_ack(void *, bool, int);
58 
59 #define	CSR_READ(sc, r)		(*sc->sc_ios.read_byte)(sc->sc_dev, r)
60 #define	CSR_WRITE(sc, r, v)	(*sc->sc_ios.write_byte)(sc->sc_dev, r, v)
61 
62 void
63 pca9564_attach(struct pca9564_softc *sc)
64 {
65 	struct i2cbus_attach_args iba;
66 
67 	aprint_naive("\n");
68 	aprint_normal(": PCA9564 I2C Controller\n");
69 
70 	mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE);
71 
72 	sc->sc_i2c.ic_cookie = sc;
73 	sc->sc_i2c.ic_acquire_bus = pca9564_acquire_bus;
74 	sc->sc_i2c.ic_release_bus = pca9564_release_bus;
75 	sc->sc_i2c.ic_send_start = pca9564_send_start;
76 	sc->sc_i2c.ic_send_stop = pca9564_send_stop;
77 	sc->sc_i2c.ic_initiate_xfer = pca9564_initiate_xfer;
78 	sc->sc_i2c.ic_read_byte = pca9564_read_byte;
79 	sc->sc_i2c.ic_write_byte = pca9564_write_byte;
80 	sc->sc_i2c.ic_exec = NULL;
81 
82 	/* set serial clock rate */
83 	switch (sc->sc_i2c_clock) {
84 	case 330000:	/* 330kHz */
85 		sc->sc_i2c_clock = I2CCON_CR_330KHZ;
86 		break;
87 	case 288000:	/* 288kHz */
88 		sc->sc_i2c_clock = I2CCON_CR_288KHZ;
89 		break;
90 	case 217000:	/* 217kHz */
91 		sc->sc_i2c_clock = I2CCON_CR_217KHZ;
92 		break;
93 	case 146000:	/* 146kHz */
94 		sc->sc_i2c_clock = I2CCON_CR_146KHZ;
95 		break;
96 	case 88000:	/* 88kHz */
97 		sc->sc_i2c_clock = I2CCON_CR_88KHZ;
98 		break;
99 	case 0:		/* default */
100 	case 59000:	/* 59kHz */
101 		sc->sc_i2c_clock = I2CCON_CR_59KHZ;
102 		break;
103 	case 44000:	/* 44kHz */
104 		sc->sc_i2c_clock = I2CCON_CR_44KHZ;
105 		break;
106 	case 36000:	/* 36kHz */
107 		sc->sc_i2c_clock = I2CCON_CR_36KHZ;
108 		break;
109 	default:
110 		aprint_error_dev(sc->sc_dev, "unknown i2c clock %dHz\n",
111 		    sc->sc_i2c_clock);
112 		sc->sc_i2c_clock = I2CCON_CR_59KHZ;
113 		break;
114 	}
115 
116 	memset(&iba, 0, sizeof(iba));
117 	iba.iba_tag = &sc->sc_i2c;
118 	(void) config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
119 }
120 
121 static int
122 pca9564_acquire_bus(void *cookie, int flags)
123 {
124 	struct pca9564_softc *sc = cookie;
125 	uint8_t control;
126 
127 	mutex_enter(&sc->sc_buslock);
128 
129 	/* Enable SIO and set clock */
130 	control = CSR_READ(sc, PCA9564_I2CCON);
131 	control |= I2CCON_ENSIO;
132 	control &= ~(I2CCON_STA|I2CCON_STO|I2CCON_SI|I2CCON_AA);
133 	control &= ~I2CCON_CR_MASK;
134 	control |= sc->sc_i2c_clock;
135 	CSR_WRITE(sc, PCA9564_I2CCON, control);
136 	delay(500);
137 
138 	return 0;
139 }
140 
141 static void
142 pca9564_release_bus(void *cookie, int flags)
143 {
144 	struct pca9564_softc *sc = cookie;
145 	uint8_t control;
146 
147 	/* Disable SIO */
148 	control = CSR_READ(sc, PCA9564_I2CCON);
149 	control &= ~I2CCON_ENSIO;
150 	CSR_WRITE(sc, PCA9564_I2CCON, control);
151 
152 	mutex_exit(&sc->sc_buslock);
153 }
154 
155 #define	PCA9564_TIMEOUT		100	/* protocol timeout, in uSecs */
156 
157 static int
158 pca9564_wait(struct pca9564_softc *sc, int flags)
159 {
160 	int timeout;
161 
162 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
163 	for (timeout = PCA9564_TIMEOUT; timeout > 0; timeout--) {
164 		if (CSR_READ(sc, PCA9564_I2CCON) & I2CCON_SI)
165 			break;
166 		delay(1);
167 	}
168 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
169 	if (timeout == 0) {
170 		aprint_error_dev(sc->sc_dev, "timeout\n");
171 		return ETIMEDOUT;
172 	}
173 	return 0;
174 }
175 
176 static int
177 pca9564_send_start(void *cookie, int flags)
178 {
179 	struct pca9564_softc *sc = cookie;
180 	uint8_t control;
181 
182 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
183 	control = CSR_READ(sc, PCA9564_I2CCON);
184 	control |= I2CCON_STA;
185 	control &= ~(I2CCON_STO|I2CCON_SI);
186 	CSR_WRITE(sc, PCA9564_I2CCON, control);
187 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
188 
189 	return pca9564_wait(sc, flags);
190 }
191 
192 static int
193 pca9564_send_stop(void *cookie, int flags)
194 {
195 	struct pca9564_softc *sc = cookie;
196 	uint8_t control;
197 
198 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
199 	control = CSR_READ(sc, PCA9564_I2CCON);
200 	control |= I2CCON_STO;
201 	control &= ~(I2CCON_STA|I2CCON_SI);
202 	CSR_WRITE(sc, PCA9564_I2CCON, control);
203 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
204 
205 	return 0;
206 }
207 
208 static int
209 pca9564_initiate_xfer(void *cookie, uint16_t addr, int flags)
210 {
211 	struct pca9564_softc *sc = cookie;
212 	int error, rd_req = (flags & I2C_F_READ) != 0;
213 	uint8_t data, control;
214 
215 	error = pca9564_send_start(sc, flags);
216 	if (error) {
217 		aprint_error_dev(sc->sc_dev, "failed to send start %s xfer\n",
218 		    rd_req ? "read" : "write");
219 		return error;
220 	}
221 
222 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
223 	control = CSR_READ(sc, PCA9564_I2CCON);
224 
225 	data = (addr << 1) | (rd_req ? 1 : 0);
226 	CSR_WRITE(sc, PCA9564_I2CDAT, data);
227 
228 	control &= ~(I2CCON_STO|I2CCON_STA|I2CCON_SI);
229 	CSR_WRITE(sc, PCA9564_I2CCON, control);
230 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
231 
232 	error = pca9564_wait(sc, flags);
233 	if (error)
234 		aprint_error_dev(sc->sc_dev, "failed to initiate %s xfer\n",
235 		    rd_req ? "read" : "write");
236 	return error;
237 }
238 
239 static int
240 pca9564_read_byte(void *cookie, uint8_t *bytep, int flags)
241 {
242 	struct pca9564_softc *sc = cookie;
243 	int send_stop = (flags & I2C_F_STOP) != 0;
244 	int error;
245 
246 	error = pca9564_ack(sc, !send_stop, flags);
247 	if (error) {
248 		aprint_error_dev(sc->sc_dev, "failed to ack\n");
249 		return error;
250 	}
251 
252 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
253 	*bytep = CSR_READ(sc, PCA9564_I2CDAT);
254 	DPRINTF(("%s: status=%#x, byte=%#x\n", __func__,
255 	    CSR_READ(sc, PCA9564_I2CSTA), *bytep));
256 
257 	if (send_stop)
258 		pca9564_send_stop(sc, flags);
259 
260 	return 0;
261 }
262 
263 static int
264 pca9564_write_byte(void *cookie, uint8_t byte, int flags)
265 {
266 	struct pca9564_softc *sc = cookie;
267 	int send_stop = (flags & I2C_F_STOP) != 0;
268 	int error;
269 	uint8_t control;
270 
271 	DPRINTF(("%s: status=%#x, byte=%#x\n", __func__,
272 	    CSR_READ(sc, PCA9564_I2CSTA), byte));
273 	control = CSR_READ(sc, PCA9564_I2CCON);
274 
275 	CSR_WRITE(sc, PCA9564_I2CDAT, byte);
276 
277 	control &= ~(I2CCON_STO|I2CCON_STA|I2CCON_SI);
278 	CSR_WRITE(sc, PCA9564_I2CCON, control);
279 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
280 
281 	error = pca9564_wait(sc, flags);
282 	if (error)
283 		aprint_error_dev(sc->sc_dev, "write byte failed\n");
284 
285 	if (send_stop)
286 		pca9564_send_stop(sc, flags);
287 
288 	return error;
289 }
290 
291 static int
292 pca9564_ack(void *cookie, bool ack, int flags)
293 {
294 	struct pca9564_softc *sc = cookie;
295 	uint8_t control;
296 
297 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
298 	control = CSR_READ(sc, PCA9564_I2CCON);
299 	control &= ~(I2CCON_STO|I2CCON_STA|I2CCON_SI|I2CCON_AA);
300 	if (ack)
301 		control |= I2CCON_AA;
302 	CSR_WRITE(sc, PCA9564_I2CCON, control);
303 	DPRINTF(("%s: status=%#x\n", __func__, CSR_READ(sc, PCA9564_I2CSTA)));
304 
305 	return pca9564_wait(sc, flags);
306 }
307