Module Name:    src
Committed By:   isaki
Date:           Sun Apr 21 06:55:34 UTC 2019

Modified Files:
        src/sys/arch/hp300/dev [isaki-audio2]: arcofi_dio.c
        src/sys/dev/ic [isaki-audio2]: arcofi.c arcofivar.h

Log Message:
Adapt to audio2.
- Use mulaw as default format.  HW supports slinear_be:16 actually
  but it's hard to use due to several hardware restrictions.
- Improve data transfer and interrupt.
Tested by tsutsui@ (a few months ago).  Thank you.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.1.26.1 src/sys/arch/hp300/dev/arcofi_dio.c
cvs rdiff -u -r1.1.28.1 -r1.1.28.2 src/sys/dev/ic/arcofi.c
cvs rdiff -u -r1.1 -r1.1.28.1 src/sys/dev/ic/arcofivar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/hp300/dev/arcofi_dio.c
diff -u src/sys/arch/hp300/dev/arcofi_dio.c:1.1 src/sys/arch/hp300/dev/arcofi_dio.c:1.1.26.1
--- src/sys/arch/hp300/dev/arcofi_dio.c:1.1	Sun Aug 24 08:17:44 2014
+++ src/sys/arch/hp300/dev/arcofi_dio.c	Sun Apr 21 06:55:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: arcofi_dio.c,v 1.1 2014/08/24 08:17:44 tsutsui Exp $	*/
+/*	$NetBSD: arcofi_dio.c,v 1.1.26.1 2019/04/21 06:55:34 isaki Exp $	*/
 /*	$OpenBSD: arcofi_dio.c,v 1.1 2011/12/21 23:12:03 miod Exp $	*/
 
 /*
@@ -80,11 +80,6 @@ arcofi_dio_attach(device_t parent, devic
 		return;
 	}
 
-	sc->sc_sih = softint_establish(SOFTINT_AUDIO, arcofi_swintr, sc);
-	if (sc->sc_sih == NULL) {
-		aprint_error(": can't register soft interrupt\n");
-		return;
-	}
 	ipl = da->da_ipl;
 	dio_intr_establish(arcofi_hwintr, sc, ipl, IPL_AUDIO);
 

Index: src/sys/dev/ic/arcofi.c
diff -u src/sys/dev/ic/arcofi.c:1.1.28.1 src/sys/dev/ic/arcofi.c:1.1.28.2
--- src/sys/dev/ic/arcofi.c:1.1.28.1	Sun Apr 21 05:11:22 2019
+++ src/sys/dev/ic/arcofi.c	Sun Apr 21 06:55:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: arcofi.c,v 1.1.28.1 2019/04/21 05:11:22 isaki Exp $	*/
+/*	$NetBSD: arcofi.c,v 1.1.28.2 2019/04/21 06:55:34 isaki Exp $	*/
 /*	$OpenBSD: arcofi.c,v 1.6 2013/05/15 08:29:24 ratchov Exp $	*/
 
 /*
@@ -36,15 +36,13 @@
 #include <sys/kernel.h>
 #include <sys/proc.h>
 #include <sys/mutex.h>
-#include <sys/condvar.h>
 #include <sys/bus.h>
 #include <sys/intr.h>
 
 #include <sys/audioio.h>
 
 #include <dev/audio_if.h>
-#include <dev/auconv.h>
-#include <dev/mulaw.h>
+#include <dev/audio/mulaw.h>
 
 #include <dev/ic/arcofivar.h>
 
@@ -200,11 +198,10 @@ static uint	arcofi_portmask_to_cr3(int);
 
 static int	arcofi_open(void *, int);
 static void	arcofi_close(void *);
-static int	arcofi_drain(void *);
-static int	arcofi_query_encoding(void *, struct audio_encoding *);
-static int	arcofi_set_params(void *, int, int,
-		    struct audio_params *, struct audio_params *,
-		    stream_filter_list_t *, stream_filter_list_t *);
+static int	arcofi_query_format(void *, audio_format_query_t *);
+static int	arcofi_set_format(void *, int,
+		    const audio_params_t *, const audio_params_t *,
+		    audio_filter_reg_t *, audio_filter_reg_t *);
 static int	arcofi_round_blocksize(void *, int, int,
 		    const audio_params_t *);
 static int	arcofi_commit_settings(void *);
@@ -224,9 +221,8 @@ static void	arcofi_get_locks(void *, kmu
 static const struct audio_hw_if arcofi_hw_if = {
 	.open		  = arcofi_open,
 	.close		  = arcofi_close,
-	.drain		  = arcofi_drain,
-	.query_encoding	  = arcofi_query_encoding,
-	.set_params	  = arcofi_set_params,
+	.query_format	  = arcofi_query_format,
+	.set_format	  = arcofi_set_format,
 	.round_blocksize  = arcofi_round_blocksize,
 	.commit_settings  = arcofi_commit_settings,
 	.start_output	  = arcofi_start_output,
@@ -250,9 +246,10 @@ static const struct audio_hw_if arcofi_h
 	.get_locks	  = arcofi_get_locks,
 };
 
-#define ARCOFI_FORMAT(enc, prec) \
+#define ARCOFI_FORMAT(prio, enc, prec) \
 	{ \
 		.mode		= AUMODE_PLAY | AUMODE_RECORD, \
+		.priority	= (prio), \
 		.encoding	= (enc), \
 		.validbits	= (prec), \
 		.precision	= (prec), \
@@ -263,18 +260,15 @@ static const struct audio_hw_if arcofi_h
 	}
 static const struct audio_format arcofi_formats[] = {
 	/*
-	 * 8-bit encodings:
-	 *  - u-Law and A-Law are native
-	 *  - linear are converted to 16-bit by auconv
+	 * 8-bit u-Law and A-Law are native.
 	 */
-	ARCOFI_FORMAT(AUDIO_ENCODING_ULAW,        8),
-	ARCOFI_FORMAT(AUDIO_ENCODING_ALAW,        8),
+	ARCOFI_FORMAT(1, AUDIO_ENCODING_ULAW,        8),
+	ARCOFI_FORMAT(0, AUDIO_ENCODING_ALAW,        8),
 	/*
-	 * 16-bit encodings:
-	 *  - slinear big-endian is native
-	 *  - unsigned or little-endian are converted by auconv
+	 * 16-bit slinear big-endian is native.
+	 * But it's hard to use due to hardware restrictions.
 	 */
-	ARCOFI_FORMAT(AUDIO_ENCODING_SLINEAR_BE, 16),
+	ARCOFI_FORMAT(0, AUDIO_ENCODING_SLINEAR_BE, 16),
 };
 #define ARCOFI_NFORMATS  __arraycount(arcofi_formats)
 
@@ -339,107 +333,60 @@ arcofi_close(void *v)
 {
 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
 
-	arcofi_halt_input(v);
-	arcofi_halt_output(v);
 	sc->sc_open = 0;
 }
 
 static int
-arcofi_drain(void *v)
+arcofi_query_format(void *v, audio_format_query_t *afp)
 {
-	struct arcofi_softc *sc = (struct arcofi_softc *)v;
-
-#ifdef ARCOFI_DEBUG
-	printf("%s: %s, mode %d\n",
-	    device_xname(sc->sc_dev), __func__, sc->sc_mode);
-#endif
-	if ((arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_OUT_EMPTY) == 0) {
-		/* enable output FIFO empty interrupt... */
-		arcofi_write(sc, ARCOFI_FIFO_IR,
-		    arcofi_read(sc, ARCOFI_FIFO_IR) |
-		    FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY));
-		/* ...and wait for it to fire */
-		if (cv_timedwait(&sc->sc_cv, &sc->sc_intr_lock,
-		    ((ARCOFI_FIFO_SIZE * hz) / 8000) + 100) != 0) {
-			printf("%s: drain did not complete\n",
-			    device_xname(sc->sc_dev));
-			arcofi_write(sc, ARCOFI_FIFO_IR,
-			    arcofi_read(sc, ARCOFI_FIFO_IR) &
-			    ~FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY));
-		}
-	}
-	return 0;
-}
-
-static int
-arcofi_query_encoding(void *v, struct audio_encoding *aep)
-{
-	struct arcofi_softc *sc = (struct arcofi_softc *)v;
 
-	return auconv_query_encoding(sc->sc_encodings, aep);
+	return audio_query_format(arcofi_formats, ARCOFI_NFORMATS, afp);
 }
 
-/*
- * Compute proper sample and hardware settings.
- */
 static int
-arcofi_set_params(void *handle, int setmode, int usemode,
-    audio_params_t *play, audio_params_t *rec,
-    stream_filter_list_t *pfil, stream_filter_list_t *rfil)
+arcofi_set_format(void *handle, int setmode,
+    const audio_params_t *play, const audio_params_t *rec,
+    audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
 {
 	struct arcofi_softc *sc;
-	int i;
 
 	sc = handle;
-	for (i = 0; i < 2; i++) {
-		int mode;
-		audio_params_t *p;
-		stream_filter_list_t *fil;
-		int ind;
-
-		switch (i) {
-		case 0:
-			mode = AUMODE_PLAY;
-			p = play;
-			fil = pfil;
+
+	if ((setmode & AUMODE_PLAY)) {
+		switch (play->encoding) {
+		case AUDIO_ENCODING_ULAW:
+			pfil->codec = audio_internal_to_mulaw;
 			break;
-		case 1:
-			mode = AUMODE_RECORD;
-			p = rec;
-			fil = rfil;
+		case AUDIO_ENCODING_ALAW:
+			pfil->codec = audio_internal_to_alaw;
 			break;
-		default:
-			return EINVAL;
 		}
+	}
+	if ((setmode & AUMODE_RECORD)) {
+		switch (rec->encoding) {
+		case AUDIO_ENCODING_ULAW:
+			rfil->codec = audio_mulaw_to_internal;
+			break;
+		case AUDIO_ENCODING_ALAW:
+			rfil->codec = audio_alaw_to_internal;
+			break;
+		}
+	}
 
-		if ((setmode & mode) == 0)
-			continue;
-
-#ifdef ARCOFI_DEBUG
-		printf("%s: %s, mode %d encoding %d precision %d\n",
-		    device_xname(sc->sc_dev), __func__,
-		    mode, p->encoding, p->precision);
-#endif
+	/* *play and *rec are identical because !AUDIO_PROP_INDEPENDENT */
 
-		ind = auconv_set_converter(arcofi_formats, ARCOFI_NFORMATS,
-		    mode, p, false, fil);
-		if (ind < 0)
-			return EINVAL;
-		if (fil->req_size > 0)
-			p = &fil->filters[0].param;
-		if (p->precision == 8) {
-			if (p->encoding == AUDIO_ENCODING_ALAW)
-				sc->sc_shadow.cr4 &= ~CR4_ULAW;
-			else
-				sc->sc_shadow.cr4 |= CR4_ULAW;
-			sc->sc_shadow.cr3 =
-			    (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
-			    CR3_OPMODE_NORMAL;
-		} else {
-			sc->sc_shadow.cr3 =
-			    (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
-			    CR3_OPMODE_LINEAR;
-		}
+	if (play->precision == 8) {
+		if (play->encoding == AUDIO_ENCODING_ULAW)
+			sc->sc_shadow.cr4 |= CR4_ULAW;
+		else
+			sc->sc_shadow.cr4 &= ~CR4_ULAW;
+		sc->sc_shadow.cr3 =
+		    (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
+		    CR3_OPMODE_NORMAL;
+	} else {
+		sc->sc_shadow.cr3 =
+		    (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
+		    CR3_OPMODE_LINEAR;
 	}
 
 	return 0;
@@ -528,6 +475,48 @@ arcofi_commit_settings(void *v)
 	return rc;
 }
 
+/*
+ * Take it out of the queue as much as possible.
+ */
+static int
+arcofi_recv_data(struct arcofi_softc *sc)
+{
+	uint8_t *cur;
+	uint8_t *past;
+
+	cur = sc->sc_recv.buf;
+	past = sc->sc_recv.past;
+
+	while (cur != past &&
+	    (arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_IN_EMPTY) == 0) {
+		*cur++ = arcofi_read(sc, ARCOFI_FIFO_DATA);
+	}
+	sc->sc_recv.buf = cur;
+
+	return past - cur;
+}
+
+/*
+ * Fill the queue as much as possible.
+ */
+static int
+arcofi_xmit_data(struct arcofi_softc *sc)
+{
+	uint8_t *cur;
+	uint8_t *past;
+
+	cur = sc->sc_xmit.buf;
+	past = sc->sc_xmit.past;
+
+	while (cur != past &&
+	    (arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_OUT_FULL) == 0) {
+		arcofi_write(sc, ARCOFI_FIFO_DATA, *cur++);
+	}
+	sc->sc_xmit.buf = cur;
+
+	return past - cur;
+}
+
 static int
 arcofi_start_input(void *v, void *rbuf, int rsz, void (*cb)(void *),
     void *cbarg)
@@ -1021,8 +1010,7 @@ int
 arcofi_hwintr(void *v)
 {
 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
-	uint8_t *cur, *past;
-	uint8_t csr, fir, data;
+	uint8_t csr, fir;
 	int rc = 0;
 
 	csr = arcofi_read(sc, ARCOFI_CSR);
@@ -1032,67 +1020,35 @@ arcofi_hwintr(void *v)
 	fir = arcofi_read(sc, ARCOFI_FIFO_IR);
 
 	/* receive */
-	if (fir & FIFO_IR_EVENT(FIFO_IR_IN_HALF_EMPTY)) {
+	if ((sc->sc_mode & AUMODE_RECORD) &&
+	    (fir & FIFO_IR_EVENT(FIFO_IR_IN_HALF_EMPTY))) {
 		rc = 1;
-		cur = sc->sc_recv.buf;
-		past = sc->sc_recv.past;
-
-		while ((arcofi_read(sc, ARCOFI_FIFO_SR) &
-		    FIFO_SR_IN_EMPTY) == 0) {
-			data = arcofi_read(sc, ARCOFI_FIFO_DATA);
-			if (cur != NULL && cur != past) {
-				*cur++ = data;
-				if (cur == past) {
-					softint_schedule(sc->sc_sih);
-					break;
-				}
-			}
-		}
-		sc->sc_recv.buf = cur;
 
-		if (cur == NULL || cur == past) {
-			/* underrun, disable further interrupts */
+		if (arcofi_recv_data(sc) == 0) {
+			/* disable further interrupts */
 			arcofi_write(sc, ARCOFI_FIFO_IR,
 			    arcofi_read(sc, ARCOFI_FIFO_IR) &
 			    ~FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY));
+
+			/* callback */
+			sc->sc_recv.cb(sc->sc_recv.cbarg);
 		}
 	}
 
 	/* xmit */
-	if (fir & FIFO_IR_EVENT(FIFO_IR_OUT_HALF_EMPTY)) {
+	if ((sc->sc_mode & AUMODE_PLAY) &&
+	    (fir & FIFO_IR_EVENT(FIFO_IR_OUT_HALF_EMPTY))) {
 		rc = 1;
-		cur = sc->sc_xmit.buf;
-		past = sc->sc_xmit.past;
-		if (cur != NULL) {
-			while ((arcofi_read(sc, ARCOFI_FIFO_SR) &
-			    FIFO_SR_OUT_FULL) == 0) {
-				if (cur != past)
-					arcofi_write(sc, ARCOFI_FIFO_DATA,
-					    *cur++);
-				if (cur == past) {
-					softint_schedule(sc->sc_sih);
-					break;
-				}
-			}
-		}
-		if (cur == NULL || cur == past) {
+
+		if (arcofi_xmit_data(sc) == 0) {
 			/* disable further interrupts */
 			arcofi_write(sc, ARCOFI_FIFO_IR,
 			    arcofi_read(sc, ARCOFI_FIFO_IR) &
 			    ~FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY));
-		}
-		sc->sc_xmit.buf = cur;
-	}
 
-	/* drain */
-	if (fir & FIFO_IR_EVENT(FIFO_IR_OUT_EMPTY)) {
-		rc = 1;
-		arcofi_write(sc, ARCOFI_FIFO_IR,
-		    arcofi_read(sc, ARCOFI_FIFO_IR) &
-		    ~FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY));
-		mutex_spin_enter(&sc->sc_intr_lock);
-		cv_signal(&sc->sc_cv);
-		mutex_spin_exit(&sc->sc_intr_lock);
+			/* callback */
+			sc->sc_xmit.cb(sc->sc_xmit.cbarg);
+		}
 	}
 
 #ifdef ARCOFI_DEBUG
@@ -1105,30 +1061,6 @@ arcofi_hwintr(void *v)
 	return rc;
 }
 
-void
-arcofi_swintr(void *v)
-{
-	struct arcofi_softc *sc = (struct arcofi_softc *)v;
-	int action;
-
-	action = 0;
-	mutex_spin_enter(&sc->sc_intr_lock);
-	if (sc->sc_recv.buf != NULL && sc->sc_recv.buf == sc->sc_recv.past)
-		action |= AUMODE_RECORD;
-	if (sc->sc_xmit.buf != NULL && sc->sc_xmit.buf == sc->sc_xmit.past)
-		action |= AUMODE_PLAY;
-
-	if (action & AUMODE_RECORD) {
-		if (sc->sc_recv.cb)
-			sc->sc_recv.cb(sc->sc_recv.cbarg);
-	}
-	if (action & AUMODE_PLAY) {
-		if (sc->sc_xmit.cb)
-			sc->sc_xmit.cb(sc->sc_xmit.cbarg);
-	}
-	mutex_spin_exit(&sc->sc_intr_lock);
-}
-
 static int
 arcofi_cmd(struct arcofi_softc *sc, uint8_t cmd, const uint8_t *data)
 {
@@ -1208,11 +1140,6 @@ arcofi_attach(struct arcofi_softc *sc, c
 	self = sc->sc_dev;
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);
-	cv_init(&sc->sc_cv, device_xname(self));
-	rc = auconv_create_encodings(arcofi_formats, ARCOFI_NFORMATS,
-	    &sc->sc_encodings);
-	if (rc != 0)
-		goto out;
 
 	/*
 	 * Reset logic.
@@ -1275,8 +1202,6 @@ arcofi_attach(struct arcofi_softc *sc, c
 	arcofi_write(sc, ARCOFI_ID, 0);
 	aprint_error("%s: %02x command failed, error %d\n",
 	    __func__, op, rc);
- out:
-	cv_destroy(&sc->sc_cv);
 	mutex_destroy(&sc->sc_intr_lock);
 	mutex_destroy(&sc->sc_lock);
 }

Index: src/sys/dev/ic/arcofivar.h
diff -u src/sys/dev/ic/arcofivar.h:1.1 src/sys/dev/ic/arcofivar.h:1.1.28.1
--- src/sys/dev/ic/arcofivar.h:1.1	Sun Aug 24 08:17:44 2014
+++ src/sys/dev/ic/arcofivar.h	Sun Apr 21 06:55:34 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: arcofivar.h,v 1.1 2014/08/24 08:17:44 tsutsui Exp $	*/
+/*	$NetBSD: arcofivar.h,v 1.1.28.1 2019/04/21 06:55:34 isaki Exp $	*/
 /*	$OpenBSD: arcofivar.h,v 1.2 2011/12/25 00:07:27 miod Exp $	*/
 
 /*
@@ -26,7 +26,6 @@ struct arcofi_softc {
 	bus_space_handle_t	sc_ioh;
 
 	struct audio_device	sc_audio_device;
-	void			*sc_sih;
 
 	int			sc_open;
 	int			sc_mode;
@@ -47,10 +46,7 @@ struct arcofi_softc {
 				sc_xmit;
 	kmutex_t		sc_lock;
 	kmutex_t		sc_intr_lock;
-	kcondvar_t		sc_cv;
-	struct audio_encoding_set *sc_encodings;
 };
 
 void	arcofi_attach(struct arcofi_softc *, const char *);
 int	arcofi_hwintr(void *);
-void	arcofi_swintr(void *);

Reply via email to