1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 1998 Nicolas Souchu, Marc Bouget
5 * Copyright (c) 2004 Joerg Wunsch
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD$");
32
33#include <sys/param.h>
34#include <sys/bus.h>
35#include <sys/lock.h>
36#include <sys/kernel.h>
37#include <sys/module.h>
38#include <sys/mutex.h>
39#include <sys/systm.h>
40
41#include <machine/bus.h>
42#include <machine/resource.h>
43
44#include <sys/rman.h>
45
46#include <dev/iicbus/iicbus.h>
47#include <dev/iicbus/iiconf.h>
48#include <dev/pcf/pcfvar.h>
49#include "iicbus_if.h"
50
51/* Not so official debugging option. */
52/* #define PCFDEBUG */
53
54static int pcf_wait_byte(struct pcf_softc *pcf);
55static int pcf_noack(struct pcf_softc *pcf, int timeout);
56static void pcf_stop_locked(struct pcf_softc *pcf);
57
58/*
59 * Polling mode for master operations wait for a new
60 * byte incoming or outgoing
61 */
62static int
63pcf_wait_byte(struct pcf_softc *sc)
64{
65	int counter = TIMEOUT;
66
67	PCF_ASSERT_LOCKED(sc);
68	while (counter--) {
69		if ((pcf_get_S1(sc) & PIN) == 0)
70			return (0);
71	}
72
73#ifdef PCFDEBUG
74	printf("pcf: timeout!\n");
75#endif
76
77	return (IIC_ETIMEOUT);
78}
79
80static void
81pcf_stop_locked(struct pcf_softc *sc)
82{
83
84	PCF_ASSERT_LOCKED(sc);
85#ifdef PCFDEBUG
86	device_printf(dev, " >> stop\n");
87#endif
88	/*
89	 * Send STOP condition iff the START condition was previously sent.
90	 * STOP is sent only once even if an iicbus_stop() is called after
91	 * an iicbus_read()... see pcf_read(): the PCF needs to send the stop
92	 * before the last char is read.
93	 */
94	if (sc->pcf_started) {
95		/* set stop condition and enable IT */
96		pcf_set_S1(sc, PIN|ESO|ENI|STO|ACK);
97
98		sc->pcf_started = 0;
99	}
100}
101
102static int
103pcf_noack(struct pcf_softc *sc, int timeout)
104{
105	int noack;
106	int k = timeout/10;
107
108	PCF_ASSERT_LOCKED(sc);
109	do {
110		noack = pcf_get_S1(sc) & LRB;
111		if (!noack)
112			break;
113		DELAY(10);				/* XXX wait 10 us */
114	} while (k--);
115
116	return (noack);
117}
118
119int
120pcf_repeated_start(device_t dev, u_char slave, int timeout)
121{
122	struct pcf_softc *sc = DEVTOSOFTC(dev);
123	int error = 0;
124
125	PCF_LOCK(sc);
126#ifdef PCFDEBUG
127	device_printf(dev, " >> repeated start for slave %#x\n",
128		      (unsigned)slave);
129#endif
130	/* repeated start */
131	pcf_set_S1(sc, ESO|STA|STO|ACK);
132
133	/* set slave address to PCF. Last bit (LSB) must be set correctly
134	 * according to transfer direction */
135	pcf_set_S0(sc, slave);
136
137	/* wait for address sent, polling */
138	if ((error = pcf_wait_byte(sc)))
139		goto error;
140
141	/* check for ack */
142	if (pcf_noack(sc, timeout)) {
143		error = IIC_ENOACK;
144#ifdef PCFDEBUG
145		printf("pcf: no ack on repeated_start!\n");
146#endif
147		goto error;
148	}
149
150	PCF_UNLOCK(sc);
151	return (0);
152
153error:
154	pcf_stop_locked(sc);
155	PCF_UNLOCK(sc);
156	return (error);
157}
158
159int
160pcf_start(device_t dev, u_char slave, int timeout)
161{
162	struct pcf_softc *sc = DEVTOSOFTC(dev);
163	int error = 0;
164
165	PCF_LOCK(sc);
166#ifdef PCFDEBUG
167	device_printf(dev, " >> start for slave %#x\n", (unsigned)slave);
168#endif
169	if ((pcf_get_S1(sc) & nBB) == 0) {
170#ifdef PCFDEBUG
171		printf("pcf: busy!\n");
172#endif
173		PCF_UNLOCK(sc);
174		return (IIC_EBUSERR);
175	}
176
177	/* set slave address to PCF. Last bit (LSB) must be set correctly
178	 * according to transfer direction */
179	pcf_set_S0(sc, slave);
180
181	/* START only */
182	pcf_set_S1(sc, PIN|ESO|STA|ACK);
183
184	sc->pcf_started = 1;
185
186	/* wait for address sent, polling */
187	if ((error = pcf_wait_byte(sc)))
188		goto error;
189
190	/* check for ACK */
191	if (pcf_noack(sc, timeout)) {
192		error = IIC_ENOACK;
193#ifdef PCFDEBUG
194		printf("pcf: no ack on start!\n");
195#endif
196		goto error;
197	}
198
199	PCF_UNLOCK(sc);
200	return (0);
201
202error:
203	pcf_stop_locked(sc);
204	PCF_UNLOCK(sc);
205	return (error);
206}
207
208int
209pcf_stop(device_t dev)
210{
211	struct pcf_softc *sc = DEVTOSOFTC(dev);
212
213#ifdef PCFDEBUG
214	device_printf(dev, " >> stop\n");
215#endif
216	PCF_LOCK(sc);
217	pcf_stop_locked(sc);
218	PCF_UNLOCK(sc);
219
220	return (0);
221}
222
223void
224pcf_intr(void *arg)
225{
226	struct pcf_softc *sc = arg;
227	char data, status, addr;
228	char error = 0;
229
230	PCF_LOCK(sc);
231	status = pcf_get_S1(sc);
232
233	if (status & PIN) {
234		printf("pcf: spurious interrupt, status=0x%x\n",
235		       status & 0xff);
236
237		goto error;
238	}
239
240	if (status & LAB)
241		printf("pcf: bus arbitration lost!\n");
242
243	if (status & BER) {
244		error = IIC_EBUSERR;
245		iicbus_intr(sc->iicbus, INTR_ERROR, &error);
246
247		goto error;
248	}
249
250	do {
251		status = pcf_get_S1(sc);
252
253		switch(sc->pcf_slave_mode) {
254		case SLAVE_TRANSMITTER:
255			if (status & LRB) {
256				/* ack interrupt line */
257				dummy_write(sc);
258
259				/* no ack, don't send anymore */
260				sc->pcf_slave_mode = SLAVE_RECEIVER;
261
262				iicbus_intr(sc->iicbus, INTR_NOACK, NULL);
263				break;
264			}
265
266			/* get data from upper code */
267			iicbus_intr(sc->iicbus, INTR_TRANSMIT, &data);
268
269			pcf_set_S0(sc, data);
270			break;
271
272		case SLAVE_RECEIVER:
273			if (status & AAS) {
274				addr = pcf_get_S0(sc);
275
276				if (status & AD0)
277					iicbus_intr(sc->iicbus, INTR_GENERAL, &addr);
278				else
279					iicbus_intr(sc->iicbus, INTR_START, &addr);
280
281				if (addr & LSB) {
282					sc->pcf_slave_mode = SLAVE_TRANSMITTER;
283
284					/* get the first char from upper code */
285					iicbus_intr(sc->iicbus, INTR_TRANSMIT, &data);
286
287					/* send first data byte */
288					pcf_set_S0(sc, data);
289				}
290
291				break;
292			}
293
294			/* stop condition received? */
295			if (status & STS) {
296				/* ack interrupt line */
297				dummy_read(sc);
298
299				/* emulate intr stop condition */
300				iicbus_intr(sc->iicbus, INTR_STOP, NULL);
301
302			} else {
303				/* get data, ack interrupt line */
304				data = pcf_get_S0(sc);
305
306				/* deliver the character */
307				iicbus_intr(sc->iicbus, INTR_RECEIVE, &data);
308			}
309			break;
310
311		    default:
312			panic("%s: unknown slave mode (%d)!", __func__,
313				sc->pcf_slave_mode);
314		    }
315
316	} while ((pcf_get_S1(sc) & PIN) == 0);
317	PCF_UNLOCK(sc);
318
319	return;
320
321error:
322	/* unknown event on bus...reset PCF */
323	pcf_set_S1(sc, PIN|ESO|ENI|ACK);
324
325	sc->pcf_slave_mode = SLAVE_RECEIVER;
326	PCF_UNLOCK(sc);
327
328	return;
329}
330
331int
332pcf_rst_card(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
333{
334	struct pcf_softc *sc = DEVTOSOFTC(dev);
335
336	PCF_LOCK(sc);
337	if (oldaddr)
338		*oldaddr = sc->pcf_addr;
339
340	/* retrieve own address from bus level */
341	if (!addr)
342		sc->pcf_addr = PCF_DEFAULT_ADDR;
343	else
344		sc->pcf_addr = addr;
345
346	pcf_set_S1(sc, PIN);				/* initialize S1 */
347
348	/* own address S'O<>0 */
349	pcf_set_S0(sc, sc->pcf_addr >> 1);
350
351	/* select clock register */
352	pcf_set_S1(sc, PIN|ES1);
353
354	/* select bus speed : 18=90kb, 19=45kb, 1A=11kb, 1B=1.5kb */
355	switch (speed) {
356	case IIC_SLOW:
357		pcf_set_S0(sc,  0x1b); /* XXX Sun uses 0x1f */
358		break;
359
360	case IIC_FAST:
361		pcf_set_S0(sc,  0x19); /* XXX Sun: 0x1d */
362		break;
363
364	case IIC_UNKNOWN:
365	case IIC_FASTEST:
366	default:
367		pcf_set_S0(sc,  0x18); /* XXX Sun: 0x1c */
368		break;
369	}
370
371	/* set bus on, ack=yes, INT=yes */
372	pcf_set_S1(sc, PIN|ESO|ENI|ACK);
373
374	sc->pcf_slave_mode = SLAVE_RECEIVER;
375	PCF_UNLOCK(sc);
376
377	return (0);
378}
379
380int
381pcf_write(device_t dev, const char *buf, int len, int *sent, int timeout /* us */)
382{
383	struct pcf_softc *sc = DEVTOSOFTC(dev);
384	int bytes, error = 0;
385
386#ifdef PCFDEBUG
387	device_printf(dev, " >> writing %d bytes: %#x%s\n", len,
388		      (unsigned)buf[0], len > 1? "...": "");
389#endif
390
391	bytes = 0;
392	PCF_LOCK(sc);
393	while (len) {
394		pcf_set_S0(sc, *buf++);
395
396		/* wait for the byte to be send */
397		if ((error = pcf_wait_byte(sc)))
398			goto error;
399
400		/* check if ack received */
401		if (pcf_noack(sc, timeout)) {
402			error = IIC_ENOACK;
403			goto error;
404		}
405
406		len --;
407		bytes ++;
408	}
409
410error:
411	*sent = bytes;
412	PCF_UNLOCK(sc);
413
414#ifdef PCFDEBUG
415	device_printf(dev, " >> %d bytes written (%d)\n", bytes, error);
416#endif
417
418	return (error);
419}
420
421int
422pcf_read(device_t dev, char *buf, int len, int *read, int last,
423	 int delay /* us */)
424{
425	struct pcf_softc *sc = DEVTOSOFTC(dev);
426	int bytes, error = 0;
427#ifdef PCFDEBUG
428	char *obuf = buf;
429
430	device_printf(dev, " << reading %d bytes\n", len);
431#endif
432
433	PCF_LOCK(sc);
434	/* trig the bus to get the first data byte in S0 */
435	if (len) {
436		if (len == 1 && last)
437			/* just one byte to read */
438			pcf_set_S1(sc, ESO);		/* no ack */
439
440		dummy_read(sc);
441	}
442
443	bytes = 0;
444	while (len) {
445		/* XXX delay needed here */
446
447		/* wait for trigged byte */
448		if ((error = pcf_wait_byte(sc))) {
449			pcf_stop_locked(sc);
450			goto error;
451		}
452
453		if (len == 1 && last)
454			/* ok, last data byte already in S0, no I2C activity
455			 * on next pcf_get_S0() */
456			pcf_stop_locked(sc);
457
458		else if (len == 2 && last)
459			/* next trigged byte with no ack */
460			pcf_set_S1(sc, ESO);
461
462		/* receive byte, trig next byte */
463		*buf++ = pcf_get_S0(sc);
464
465		len --;
466		bytes ++;
467	}
468
469error:
470	*read = bytes;
471	PCF_UNLOCK(sc);
472
473#ifdef PCFDEBUG
474	device_printf(dev, " << %d bytes read (%d): %#x%s\n", bytes, error,
475		      (unsigned)obuf[0], bytes > 1? "...": "");
476#endif
477
478	return (error);
479}
480
481DRIVER_MODULE(iicbus, pcf, iicbus_driver, iicbus_devclass, 0, 0);
482MODULE_DEPEND(pcf, iicbus, PCF_MINVER, PCF_PREFVER, PCF_MAXVER);
483MODULE_VERSION(pcf, PCF_MODVER);
484