List Info

Thread: audio support for the tumbler




audio support for the tumbler
country flaguser name
France
2007-09-16 08:08:58
Hi,

if no one objects, I'll add support for the
"tumbler", as found at
least on my iBook G3/600. I fitted it into the snapper
driver to
minimize duplication, and did some minor cleanup while
there.

Playing and recording work.

Regards,
 Aymeric

Index: snapper.c
============================================================
=======
RCS file: /cvsroot/src/sys/arch/macppc/dev/snapper.c,v
retrieving revision 1.20
diff -u -u -r1.20 snapper.c
--- snapper.c	4 Apr 2007 02:14:57 -0000	1.20
+++ snapper.c	16 Sep 2007 13:03:48 -0000
 -61,8
+61,11 
 struct snapper_softc {
 	struct device sc_dev;
 	int sc_flags;
+#define SNAPPER_IS_TAS3001	0x01
 	int sc_node;
 
+	struct audio_encoding_set *sc_encodings;
+
 	void (*sc_ointr)(void *);	/* dma completion intr handler
*/
 	void *sc_oarg;			/* arg for sc_ointr() */
 	int sc_opages;			/* # of output pages */
 -99,7
+102,6 
 void snapper_attach(struct device *, struct device *, void
*);
 void snapper_defer(struct device *);
 int snapper_intr(void *);
-void snapper_close(void *);
 int snapper_query_encoding(void *, struct audio_encoding
*);
 int snapper_set_params(void *, int, int, audio_params_t *,
     audio_params_t *, stream_filter_list_t *,
stream_filter_list_t *);
 -209,8
+211,8 
 };
 
 const struct audio_hw_if snapper_hw_if = {
-	NULL,			/* open */
-	snapper_close,
+	NULL,
+	NULL,
 	NULL,
 	snapper_query_encoding,
 	snapper_set_params,
 -473,6
+475,12 
 	 2, AUFMT_STEREO, 3, {32000, 44100, 48000}},
 };
 
+#define TUMBLER_NFORMATS	1
+static const struct audio_format
tumbler_formats[TUMBLER_NFORMATS] = {
+	{NULL, AUMODE_PLAY | AUMODE_RECORD,
AUDIO_ENCODING_SLINEAR_BE, 16, 16,
+	 2, AUFMT_STEREO, 3, {32000, 44100, 48000}},
+};
+
 static u_char *amp_mute;
 static u_char *headphone_mute;
 static u_char *audio_hw_reset;
 -499,12
+507,13 
 
 /* TAS3004 registers */
 #define DEQ_MCR1	0x01	/* Main control register 1 (1byte)
*/
-#define DEQ_DRC		0x02	/* Dynamic range compression
(6bytes?) */
+#define DEQ_DRC		0x02	/* Dynamic range compression
(6bytes?)
+					2 bytes on the TAS 3001 */
 #define DEQ_VOLUME	0x04	/* Volume (6bytes) */
 #define DEQ_TREBLE	0x05	/* Treble control (1byte) */
 #define DEQ_BASS	0x06	/* Bass control (1byte) */
-#define DEQ_MIXER_L	0x07	/* Mixer left gain (9bytes) */
-#define DEQ_MIXER_R	0x08	/* Mixer right gain (9bytes) */
+#define DEQ_MIXER_L	0x07	/* Mixer left gain (9bytes; 3 on
TAS3001) */
+#define DEQ_MIXER_R	0x08	/* Mixer right gain (9bytes; 3 on
TAS3001) */
 #define DEQ_LB0		0x0a	/* Left biquad 0 (15bytes) */
 #define DEQ_LB1		0x0b	/* Left biquad 1 (15bytes) */
 #define DEQ_LB2		0x0c	/* Left biquad 2 (15bytes) */
 -534,6
+543,10 
 #define  DEQ_MCR1_SM_L	0x00	/*  Left justified */
 #define  DEQ_MCR1_SM_R	0x10	/*  Right justified */
 #define  DEQ_MCR1_SM_I2S 0x20	/*  I2S */
+#define DEQ_MCR1_ISM	0x0c	/* Input serial port mode */
+#define  DEQ_MCR1_ISM_L	0x00	/*  Left justified */
+#define  DEQ_MCR1_ISM_R	0x04	/*  Right justified */
+#define  DEQ_MCR1_ISM_I2S 0x08	/*  I2S */
 #define DEQ_MCR1_W	0x03	/* Serial port word length */
 #define  DEQ_MCR1_W_16	0x00	/*  16 bit */
 #define  DEQ_MCR1_W_18	0x01	/*  18 bit */
 -623,6
+636,9 
 	if (strcmp(compat, "snapper") == 0)
 		return 1;
 
+	if (strcmp(compat, "tumbler") == 0)
+		return 1;
+
 	if (strcmp(compat, "AOAKeylargo") == 0)
 		return 1;
 
 -644,10
+660,33 
 	unsigned long v;
 	int cirq, oirq, iirq, cirq_type, oirq_type, iirq_type;
 	int soundbus, intr[6];
+	char compat[32];
 
 	sc = (struct snapper_softc *)self;
 	ca = aux;
 
+	soundbus = OF_child(ca->ca_node);
+	bzero(compat, sizeof compat);
+	OF_getprop(OF_child(soundbus), "compatible",
compat, sizeof compat);
+
+	sc->sc_flags = 0;
+	if (strcmp(compat, "tumbler") == 0)
+		sc->sc_flags |= SNAPPER_IS_TAS3001;
+
+	if (sc->sc_flags & SNAPPER_IS_TAS3001) {
+		if (auconv_create_encodings(tumbler_formats,
TUMBLER_NFORMATS,
+				&sc->sc_encodings) != 0) {
+			aprint_normal("can't create encodingsn");
+			return;
+		}
+	} else {
+		if (auconv_create_encodings(snapper_formats,
SNAPPER_NFORMATS,
+				&sc->sc_encodings) != 0) {
+			aprint_normal("can't create encodingsn");
+			return;
+		}
+	}
+
 	v = (((unsigned long) &sc->dbdma_cmdspace[0]) +
0xf) & ~0xf;
 	sc->sc_odmacmd = (struct dbdma_command *) v;
 	sc->sc_idmacmd = sc->sc_odmacmd + 20;
 -668,7
+707,6 
 	sc->sc_odma = (void *)ca->ca_reg[2];
 	sc->sc_idma = (void *)ca->ca_reg[4];
 
-	soundbus = OF_child(ca->ca_node);
 	OF_getprop(soundbus, "interrupts", intr, sizeof
intr);
 	cirq = intr[0];
 	oirq = intr[2];
 -681,9
+719,9 
 	intr_establish(oirq, oirq_type, IPL_AUDIO, snapper_intr,
sc);
 	intr_establish(iirq, iirq_type, IPL_AUDIO, snapper_intr,
sc);
 
-	printf(": irq %d,%d,%dn", cirq, oirq, iirq);
+	aprint_normal(": irq %d,%d,%dn", cirq, oirq,
iirq);
 
-	config_interrupts(self, snapper_defer);
+	config_defer(self, snapper_defer);
 }
 
 void
 -694,12
+732,6 
 	struct deq_softc *deq;
 	
 	sc = (struct snapper_softc *)dev;
-	/*
-	for (dv = alldevs.tqh_first; dv;
dv=dv->dv_list.tqe_next)
-		if (strncmp(dv->dv_xname, "ki2c", 4) == 0
&&
-		    strncmp(device_parent(dv)->dv_xname,
"obio", 4) == 0)
-			sc->sc_i2c = dv;
-	*/
 	for (dv = alldevs.tqh_first; dv;
dv=dv->dv_list.tqe_next)
 		if (strncmp(dv->dv_xname, "deq", 3) == 0
&&
 		    strncmp(device_parent(dv)->dv_xname,
"ki2c", 4) == 0) {
 -764,69
+796,14 
 	return 1;
 }
 
-/*
- * Close function is called at splaudio().
- */
-void
-snapper_close(void *h)
-{
-	struct snapper_softc *sc;
-
-	sc = h;
-	snapper_halt_output(sc);
-	snapper_halt_input(sc);
-
-	sc->sc_ointr = 0;
-	sc->sc_iintr = 0;
-}
 
 int
 snapper_query_encoding(void *h, struct audio_encoding *ae)
 {
 
-	ae->flags = AUDIO_ENCODINGFLAG_EMULATED;
-	switch (ae->index) {
-	case 0:
-		strcpy(ae->name, AudioEslinear);
-		ae->encoding = AUDIO_ENCODING_SLINEAR;
-		ae->precision = 16;
-		ae->flags = 0;
-		return 0;
-	case 1:
-		strcpy(ae->name, AudioEslinear_be);
-		ae->encoding = AUDIO_ENCODING_SLINEAR_BE;
-		ae->precision = 16;
-		ae->flags = 0;
-		return 0;
-	case 2:
-		strcpy(ae->name, AudioEslinear_le);
-		ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
-		ae->precision = 16;
-		return 0;
-	case 3:
-		strcpy(ae->name, AudioEulinear_be);
-		ae->encoding = AUDIO_ENCODING_ULINEAR_BE;
-		ae->precision = 16;
-		return 0;
-	case 4:
-		strcpy(ae->name, AudioEulinear_le);
-		ae->encoding = AUDIO_ENCODING_ULINEAR_LE;
-		ae->precision = 16;
-		return 0;
-	case 5:
-		strcpy(ae->name, AudioEmulaw);
-		ae->encoding = AUDIO_ENCODING_ULAW;
-		ae->precision = 8;
-		return 0;
-	case 6:
-		strcpy(ae->name, AudioEalaw);
-		ae->encoding = AUDIO_ENCODING_ALAW;
-		ae->precision = 8;
-		return 0;
-	default:
-		DPRINTF("snapper_query_encoding: invalid encoding
%dn", ae->index);
-		return EINVAL;
-	}
+	struct snapper_softc *sc = h;
+
+	return auconv_query_encoding(sc->sc_encodings, ae);
 }
 
 int
 -836,7
+813,7 
 {
 	struct snapper_softc *sc;
 	audio_params_t *p;
-	stream_filter_list_t *fil;
+	stream_filter_list_t *fil = NULL; /* XXX gcc */
 	int mode;
 
 	sc = h;
 -870,11
+847,22 
 		}
 
 		fil = mode == AUMODE_PLAY ? pfil : rfil;
-		if (auconv_set_converter(snapper_formats,
SNAPPER_NFORMATS,
-					 mode, p, true, fil) < 0) {
-			DPRINTF("snapper_set_params: auconv_set_converter
failedn");
-			return EINVAL;
+		if (sc->sc_flags & SNAPPER_IS_TAS3001) {
+			if (auconv_set_converter(tumbler_formats,
+				    TUMBLER_NFORMATS, mode, p, true, fil) < 0) {
+				DPRINTF("snapper_set_params: "
+					"auconv_set_converter failedn");
+				return EINVAL;
+			}
+		} else {	/* TAS 3004 */
+			if (auconv_set_converter(snapper_formats,
+				    SNAPPER_NFORMATS, mode, p, true, fil) < 0) {
+				DPRINTF("snapper_set_params: "
+					"auconv_set_converter failedn");
+				return EINVAL;
+			}
 		}
+
 		if (sc->sc_swvol)
 			fil->append(fil, snapper_volume, p);
 		if (fil->req_size > 0)
 -907,6
+895,7 
 	sc = h;
 	dbdma_stop(sc->sc_odma);
 	dbdma_reset(sc->sc_odma);
+	sc->sc_ointr = NULL;
 	return 0;
 }
 
 -918,6
+907,7 
 	sc = h;
 	dbdma_stop(sc->sc_idma);
 	dbdma_reset(sc->sc_idma);
+	sc->sc_iintr = NULL;
 	return 0;
 }
 
 -937,11
+927,12 
 	SNAPPER_VOL_OUTPUT,
 	SNAPPER_DIGI1,
 	SNAPPER_DIGI2,
-	SNAPPER_ANALOG,
-	SNAPPER_INPUT_SELECT,
 	SNAPPER_VOL_INPUT,
 	SNAPPER_TREBLE,
 	SNAPPER_BASS,
+	/* From this point, unsupported by the TAS 3001 */
+	SNAPPER_ANALOG,
+	SNAPPER_INPUT_SELECT,
 	SNAPPER_ENUM_LAST
 };
 
 -978,6
+969,9 
 		return 0;
 
 	case SNAPPER_INPUT_SELECT:
+		if (sc->sc_flags & SNAPPER_IS_TAS3001)
+			return ENXIO;
+
 		/* no change necessary? */
 		if (mc->un.mask == sc->sc_record_source)
 			return 0;
 -1014,11
+1008,18 
 		snapper_write_mixers(sc);
 		return 0;
 	case SNAPPER_DIGI2:
-		sc->mixer[1]=l;
-		sc->mixer[4]=r;
+		if (sc->sc_flags & SNAPPER_IS_TAS3001)
+			sc->mixer[3] = l;
+		else {
+			sc->mixer[1]=l;
+			sc->mixer[4]=r;
+		}
 		snapper_write_mixers(sc);
 		return 0;
 	case SNAPPER_ANALOG:
+		if (sc->sc_flags & SNAPPER_IS_TAS3001)
+			return ENXIO;
+
 		sc->mixer[2]=l;
 		sc->mixer[5]=r;
 		snapper_write_mixers(sc);
 -1050,6
+1051,9 
 		return 0;
 
 	case SNAPPER_INPUT_SELECT:
+		if (sc->sc_flags & SNAPPER_IS_TAS3001)
+			return ENXIO;
+
 		mc->un.mask = sc->sc_record_source;
 		return 0;
 
 -1073,6
+1077,9 
 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
sc->mixer[4];
 		return 0;
 	case SNAPPER_ANALOG:
+		if (sc->sc_flags & SNAPPER_IS_TAS3001)
+			return ENXIO;
+
 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
sc->mixer[2];
 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
sc->mixer[5];
 		return 0;
 -1086,6
+1093,8 
 int
 snapper_query_devinfo(void *h, mixer_devinfo_t *dip)
 {
+	struct snapper_softc *sc = h;
+
 	switch (dip->index) {
 
 	case SNAPPER_OUTPUT_SELECT:
 -1110,6
+1119,9 
 		return 0;
 
 	case SNAPPER_INPUT_SELECT:
+		if (sc->sc_flags & SNAPPER_IS_TAS3001)
+			return ENXIO;
+
 		dip->mixer_class = SNAPPER_RECORD_CLASS;
 		strcpy(dip->label.name, AudioNsource);
 		dip->type = AUDIO_MIXER_SET;
 -1172,16
+1184,21 
 		strcpy(dip->label.name, AudioNdac);
 		dip->type = AUDIO_MIXER_VALUE;
 		dip->prev = dip->next = AUDIO_MIXER_LAST;
-		dip->un.v.num_channels = 2;
+		dip->un.v.num_channels =
+			sc->sc_flags & SNAPPER_IS_TAS3001? 1 : 2;
 		return 0;
 	case SNAPPER_DIGI2:
 		dip->mixer_class = SNAPPER_MONITOR_CLASS;
 		strcpy(dip->label.name, AudioNline);
 		dip->type = AUDIO_MIXER_VALUE;
 		dip->prev = dip->next = AUDIO_MIXER_LAST;
-		dip->un.v.num_channels = 2;
+		dip->un.v.num_channels =
+			sc->sc_flags & SNAPPER_IS_TAS3001? 1 : 2;
 		return 0;
 	case SNAPPER_ANALOG:
+		if (sc->sc_flags & SNAPPER_IS_TAS3001)
+			return ENXIO;
+
 		dip->mixer_class = SNAPPER_MONITOR_CLASS;
 		strcpy(dip->label.name, AudioNmicrophone);
 		dip->type = AUDIO_MIXER_VALUE;
 -1548,6
+1565,9 
 			return EINVAL;
 	}
 
+	if (sc->sc_flags & SNAPPER_IS_TAS3001)
+		mcr1 |= DEQ_MCR1_ISM_I2S;
+
 	ows = in32rb(sc->sc_reg + I2S_WORDSIZE);
 	DPRINTF("I2SSetDataWordSizeReg 0x%08x ->
0x%08xn",
 	    ows, wordsize);
 -1675,6
+1695,15 
 
 	regblock[0] = reg;
 	memcpy(&regblock[1], data, size);
+	if (sc->sc_flags & SNAPPER_IS_TAS3001) {
+		if (reg == DEQ_MIXER_L || reg == DEQ_MIXER_R)
+			size = 3;
+		else if (reg == DEQ_DRC) {
+			size = 2;
+			regblock[1] = 0;
+			regblock[2] = 0;
+		}
+	}
 	iic_acquire_bus(sc->sc_i2c, 0);
 	iic_exec(sc->sc_i2c, I2C_OP_WRITE, sc->sc_deqaddr,
regblock, size + 1,
 	    NULL, 0, 0);

Re: audio support for the tumbler
country flaguser name
United States
2007-09-16 12:49:58
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello,

On Sep 16, 2007, at 09:08, Aymeric Vincent wrote:

> if no one objects, I'll add support for the
"tumbler", as found at
> least on my iBook G3/600. I fitted it into the snapper
driver to
> minimize duplication, and did some minor cleanup while
there.

Looks good to me ( from a quick glance ) - please commit!

have fun
Michael
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iQEVAwUBRu1sxspnzkX8Yg2nAQJ6zQf/QyjytU8+swtac692EM+otk+dq3u/
z0mh
VJSEnivXmduKCdCwq4fBNWDUbX+nZfBEjNC2hV44JnIyEbNjMZEZt1YdO04P
gwkQ
viLwt/LUhs7CHARrBypBeXOQwnHLPEXHH5ClvBoi1qR8Uv7Z08Q6v5pstq+P
H+iM
LwbaPjVnW0uhOjE9yHV44WJ2rEzvphw8g2G7cqWmGG6cyoaL+3Oe/LTkxbrN
bwsA
HquS14hMknZmDYzmc6aRRARTrroUF3T7rHaTpxo87fyXsWubVH3wjc82wQwb
yiaP
4IH35CX/Yib03Viq5H+rz5FKTKTodBzqeXJU7wJEpH68pdRI7SE+bA==
=YHng
-----END PGP SIGNATURE-----

[1-2]

about | contact  Other archives ( Real Estate discussion Medical topics )