xref: /openbsd/sys/arch/armv7/exynos/exiic.c (revision 5a38ef86)
1 /*
2  * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <sys/param.h>
18 #include <sys/systm.h>
19 #include <sys/device.h>
20 #include <sys/rwlock.h>
21 
22 #include <machine/bus.h>
23 #include <machine/fdt.h>
24 
25 #include <dev/ofw/openfirm.h>
26 #include <dev/ofw/ofw_pinctrl.h>
27 #include <dev/ofw/fdt.h>
28 
29 #include <dev/i2c/i2cvar.h>
30 
31 #include <armv7/exynos/exclockvar.h>
32 
33 /* registers */
34 #define I2C_CON				0x00	/* control register */
35 #define I2C_STAT			0x04	/* control/status register */
36 #define I2C_ADD				0x08	/* address register */
37 #define I2C_DS				0x0C	/* transmit/receive data shift register */
38 #define I2C_LC				0x10	/* multi-master line control register */
39 
40 /* bits and bytes */
41 #define I2C_CON_TXCLKVAL_MASK		(0xf << 0) /* tx clock = i2cclk / (i2ccon[3:0] + 1) */
42 #define I2C_CON_INTPENDING		(0x1 << 4) /* 0 = no interrupt pending/clear, 1 = pending */
43 #define I2C_CON_TXRX_INT		(0x1 << 5) /* enable/disable */
44 #define I2C_CON_TXCLKSRC_16		(0x0 << 6) /* i2clk = fpclk/16 */
45 #define I2C_CON_TXCLKSRC_512		(0x1 << 6) /* i2clk = fpclk/512 */
46 #define I2C_CON_ACK			(0x1 << 7)
47 #define I2C_STAT_LAST_RVCD_BIT		(0x1 << 0) /* last received bit 0 => ack, 1 => no ack */
48 #define I2C_STAT_ADDR_ZERO_FLAG		(0x1 << 1) /* 0 => start/stop cond. detected, 1 => received slave addr 0xb */
49 #define I2C_STAT_ADDR_SLAVE_ZERO_FLAG	(0x1 << 2) /* 0 => start/stop cond. detected, 1 => received slave addr matches i2cadd */
50 #define I2C_STAT_ARBITRATION		(0x1 << 3) /* 0 => successful, 1 => failed */
51 #define I2C_STAT_SERIAL_OUTPUT		(0x1 << 4) /* 0 => disable tx/rx, 1 => enable tx/rx */
52 #define I2C_STAT_BUSY_SIGNAL		(0x1 << 5) /* 0 => not busy / stop signal generation, 1 => busy / start signal generation */
53 #define I2C_STAT_MODE_SEL_SLAVE_RX	(0x0 << 6) /* slave receive mode */
54 #define I2C_STAT_MODE_SEL_SLAVE_TX	(0x1 << 6) /* slave transmit mode */
55 #define I2C_STAT_MODE_SEL_MASTER_RX	(0x2 << 6) /* master receive mode */
56 #define I2C_STAT_MODE_SEL_MASTER_TX	(0x3 << 6) /* master transmit */
57 #define I2C_ADD_SLAVE_ADDR(x)		(((x) & 0x7f) << 1)
58 #define I2C_DS_DATA_SHIFT(x)		(((x) & 0xff) << 0)
59 
60 #define I2C_ACK				0
61 #define I2C_NACK			1
62 #define I2C_TIMEOUT			2
63 
64 struct exiic_softc {
65 	struct device		sc_dev;
66 	bus_space_tag_t		sc_iot;
67 	bus_space_handle_t	sc_ioh;
68 	bus_size_t		sc_ios;
69 	void			*sc_ih;
70 	int			sc_node;
71 
72 	struct rwlock		sc_buslock;
73 	struct i2c_controller	i2c_tag;
74 
75 	uint16_t		frequency;
76 	uint16_t		intr_status;
77 };
78 
79 int exiic_match(struct device *, void *, void *);
80 void exiic_attach(struct device *, struct device *, void *);
81 int exiic_detach(struct device *, int);
82 void exiic_scan(struct device *, struct i2cbus_attach_args *, void *);
83 void exiic_setspeed(struct exiic_softc *, int);
84 int exiic_wait_state(struct exiic_softc *, uint32_t, uint32_t, uint32_t);
85 int exiic_start(struct exiic_softc *, int, int, void *, int);
86 
87 void exiic_xfer_start(struct exiic_softc *);
88 int exiic_xfer_wait(struct exiic_softc *);
89 int exiic_i2c_acquire_bus(void *, int);
90 void exiic_i2c_release_bus(void *, int);
91 int exiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t,
92     void *, size_t, int);
93 
94 #define HREAD4(sc, reg)							\
95 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
96 #define HWRITE4(sc, reg, val)						\
97 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
98 #define HSET4(sc, reg, bits)						\
99 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
100 #define HCLR4(sc, reg, bits)						\
101 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
102 
103 
104 const struct cfattach exiic_ca = {
105 	sizeof(struct exiic_softc), exiic_match, exiic_attach, exiic_detach
106 };
107 
108 struct cfdriver exiic_cd = {
109 	NULL, "exiic", DV_DULL
110 };
111 
112 int
113 exiic_match(struct device *parent, void *match, void *aux)
114 {
115 	struct fdt_attach_args *faa = aux;
116 
117 	return OF_is_compatible(faa->fa_node, "samsung,s3c2440-i2c");
118 }
119 
120 void
121 exiic_attach(struct device *parent, struct device *self, void *aux)
122 {
123 	struct exiic_softc *sc = (struct exiic_softc *)self;
124 	struct fdt_attach_args *faa = aux;
125 	struct i2cbus_attach_args iba;
126 
127 	pinctrl_byname(faa->fa_node, "default");
128 
129 	sc->sc_iot = faa->fa_iot;
130 	sc->sc_node = faa->fa_node;
131 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
132 	    faa->fa_reg[0].size, 0, &sc->sc_ioh))
133 		panic("%s: bus_space_map failed!", __func__);
134 
135 	printf("\n");
136 
137 	rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname);
138 
139 	sc->i2c_tag.ic_cookie = sc;
140 	sc->i2c_tag.ic_acquire_bus = exiic_i2c_acquire_bus;
141 	sc->i2c_tag.ic_release_bus = exiic_i2c_release_bus;
142 	sc->i2c_tag.ic_exec = exiic_i2c_exec;
143 
144 	bzero(&iba, sizeof iba);
145 	iba.iba_name = "iic";
146 	iba.iba_tag = &sc->i2c_tag;
147 	iba.iba_bus_scan = exiic_scan;
148 	iba.iba_bus_scan_arg = &sc->sc_node;
149 	config_found(&sc->sc_dev, &iba, NULL);
150 }
151 
152 void
153 exiic_scan(struct device *self, struct i2cbus_attach_args *iba, void *aux)
154 {
155 	int iba_node = *(int *)aux;
156 	extern int iic_print(void *, const char *);
157 	struct i2c_attach_args ia;
158 	char name[32];
159 	uint32_t reg[1];
160 	int node;
161 
162 	for (node = OF_child(iba_node); node; node = OF_peer(node)) {
163 		memset(name, 0, sizeof(name));
164 		memset(reg, 0, sizeof(reg));
165 
166 		if (OF_getprop(node, "compatible", name, sizeof(name)) == -1)
167 			continue;
168 		if (name[0] == '\0')
169 			continue;
170 
171 		if (OF_getprop(node, "reg", &reg, sizeof(reg)) != sizeof(reg))
172 			continue;
173 
174 		memset(&ia, 0, sizeof(ia));
175 		ia.ia_tag = iba->iba_tag;
176 		ia.ia_addr = bemtoh32(&reg[0]);
177 		ia.ia_name = name;
178 		ia.ia_cookie = &node;
179 
180 		config_found(self, &ia, iic_print);
181 	}
182 }
183 
184 void
185 exiic_setspeed(struct exiic_softc *sc, int speed)
186 {
187 	if (!sc->frequency) {
188 		uint32_t freq, div = 0, pres = 16;
189 		freq = exclock_get_i2cclk();
190 
191 		/* calculate prescaler and divisor values */
192 		if ((freq / pres / (16 + 1)) > speed)
193 			/* set prescaler to 512 */
194 			pres = 512;
195 
196 		while ((freq / pres / (div + 1)) > speed)
197 			div++;
198 
199 		/* set prescaler, divisor according to freq, also set ACKGEN, IRQ */
200 		sc->frequency = (div & 0x0F) | 0xA0 | ((pres == 512) ? 0x40 : 0);
201 	}
202 
203 	HWRITE4(sc, I2C_CON, sc->frequency);
204 }
205 
206 int
207 exiic_wait_state(struct exiic_softc *sc, uint32_t reg, uint32_t mask, uint32_t value)
208 {
209 	uint32_t state;
210 	int timeout;
211 	state = HREAD4(sc, reg);
212 	for (timeout = 1000; timeout > 0; timeout--) {
213 		if (((state = HREAD4(sc, reg)) & mask) == value)
214 			return 0;
215 		delay(1000);
216 	}
217 	return ETIMEDOUT;
218 }
219 
220 int
221 exiic_i2c_acquire_bus(void *cookie, int flags)
222 {
223 	struct exiic_softc *sc = cookie;
224 	int ret = rw_enter(&sc->sc_buslock, RW_WRITE);
225 
226 	if (!ret) {
227 		/* set speed to 100 Kbps */
228 		exiic_setspeed(sc, 100);
229 
230 		/* STOP */
231 		HWRITE4(sc, I2C_STAT, 0);
232 		HWRITE4(sc, I2C_ADD, 0);
233 		HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_TX
234 				    | I2C_STAT_SERIAL_OUTPUT);
235 	}
236 
237 	return ret;
238 }
239 
240 void
241 exiic_i2c_release_bus(void *cookie, int flags)
242 {
243 	struct exiic_softc *sc = cookie;
244 
245 	(void) rw_exit(&sc->sc_buslock);
246 }
247 
248 int
249 exiic_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t _addr,
250     const void *cmdbuf, size_t cmdlen, void *databuf, size_t datalen, int flags)
251 {
252 	struct exiic_softc *sc = cookie;
253 	uint32_t ret = 0;
254 	u_int8_t addr = 0;
255 	int i = 0;
256 
257 	addr = (_addr & 0x7f) << 1;
258 
259 	/* clock gating */
260 	//exccm_enable_i2c(sc->unit);
261 
262 	if (exiic_wait_state(sc, I2C_STAT, I2C_STAT_BUSY_SIGNAL, 0)) {
263 		printf("%s: busy\n", __func__);
264 		return (EIO);
265 	}
266 
267 	/* acknowledge generation */
268 	HSET4(sc, I2C_CON, I2C_CON_ACK);
269 
270 	/* Send the slave-address */
271 	HWRITE4(sc, I2C_DS, addr);
272 	if (!I2C_OP_READ_P(op) || (cmdbuf && cmdlen))
273 		HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_TX
274 				    | I2C_STAT_SERIAL_OUTPUT
275 				    | I2C_STAT_BUSY_SIGNAL);
276 	else
277 		HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_RX
278 				    | I2C_STAT_SERIAL_OUTPUT
279 				    | I2C_STAT_BUSY_SIGNAL);
280 
281 	ret = exiic_xfer_wait(sc);
282 	if (ret != I2C_ACK)
283 		goto fail;
284 
285 	/* transmit commands */
286 	if (cmdbuf && cmdlen) {
287 		for (i = 0; i < cmdlen; i++) {
288 			HWRITE4(sc, I2C_DS, ((uint8_t *)cmdbuf)[i]);
289 			exiic_xfer_start(sc);
290 			ret = exiic_xfer_wait(sc);
291 			if (ret != I2C_ACK)
292 				goto fail;
293 		}
294 	}
295 
296 	if (I2C_OP_READ_P(op)) {
297 		if (cmdbuf && cmdlen) {
298 			/* write slave chip address again for actual read */
299 			HWRITE4(sc, I2C_DS, addr);
300 
301 			/* restart */
302 			HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_RX
303 					    | I2C_STAT_SERIAL_OUTPUT
304 					    | I2C_STAT_BUSY_SIGNAL);
305 			exiic_xfer_start(sc);
306 			ret = exiic_xfer_wait(sc);
307 			if (ret != I2C_ACK)
308 				goto fail;
309 		}
310 
311 		for (i = 0; i < datalen && ret == I2C_ACK; i++) {
312 			/* disable ACK for final read */
313 			if (i == datalen - 1)
314 				HCLR4(sc, I2C_CON, I2C_CON_ACK);
315 			exiic_xfer_start(sc);
316 			ret = exiic_xfer_wait(sc);
317 			((uint8_t *)databuf)[i] = HREAD4(sc, I2C_DS);
318 		}
319 		if (ret == I2C_NACK)
320 			ret = I2C_ACK; /* Normal terminated read. */
321 	} else {
322 		for (i = 0; i < datalen && ret == I2C_ACK; i++) {
323 			HWRITE4(sc, I2C_DS, ((uint8_t *)databuf)[i]);
324 			exiic_xfer_start(sc);
325 			ret = exiic_xfer_wait(sc);
326 		}
327 	}
328 
329 fail:
330 	/* send STOP */
331 	if (op & I2C_OP_READ_WITH_STOP) {
332 		HWRITE4(sc, I2C_STAT, I2C_STAT_MODE_SEL_MASTER_RX
333 				    | I2C_STAT_SERIAL_OUTPUT);
334 		exiic_xfer_start(sc);
335 	}
336 
337 	return ret;
338 }
339 
340 void
341 exiic_xfer_start(struct exiic_softc *sc)
342 {
343 	HCLR4(sc, I2C_CON, I2C_CON_INTPENDING);
344 }
345 
346 int
347 exiic_xfer_wait(struct exiic_softc *sc)
348 {
349 	if (!exiic_wait_state(sc, I2C_CON, I2C_CON_INTPENDING,
350 					   I2C_CON_INTPENDING))
351 		return (HREAD4(sc, I2C_STAT) & I2C_STAT_LAST_RVCD_BIT) ?
352 			I2C_NACK : I2C_ACK;
353 	else
354 		return I2C_TIMEOUT;
355 }
356 
357 int
358 exiic_detach(struct device *self, int flags)
359 {
360 	struct exiic_softc *sc = (struct exiic_softc *)self;
361 
362 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
363 	return 0;
364 }
365