Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/macppc/dev various minor fixes and updates:
details: https://anonhg.NetBSD.org/src/rev/a7711a87e9ce
branches: trunk
changeset: 1003563:a7711a87e9ce
user: macallan <macallan%NetBSD.org@localhost>
date: Fri Sep 20 21:24:34 2019 +0000
description:
various minor fixes and updates:
- add (very) basic ONYX support. Treat as 16bit codec with software volume
control. Makes basic audio work on PCIe G5
- correctly detect TAS3001 without 'compatible' property, now this works on
Quicksilver
- mute line input on TAS3001 - it's unconnected on Quicksilver and causes noise
- make more of an effort to match codecs to i2sbus instances, needed on G5 and
some other models with software 'modems'
diffstat:
sys/arch/macppc/dev/snapper.c | 204 +++++++++++++++++++++++++++++++----------
1 files changed, 155 insertions(+), 49 deletions(-)
diffs (truncated from 348 to 300 lines):
diff -r 9b55a2ac5337 -r a7711a87e9ce sys/arch/macppc/dev/snapper.c
--- a/sys/arch/macppc/dev/snapper.c Fri Sep 20 17:25:11 2019 +0000
+++ b/sys/arch/macppc/dev/snapper.c Fri Sep 20 21:24:34 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: snapper.c,v 1.52 2019/06/08 08:02:37 isaki Exp $ */
+/* $NetBSD: snapper.c,v 1.53 2019/09/20 21:24:34 macallan Exp $ */
/* Id: snapper.c,v 1.11 2002/10/31 17:42:13 tsubai Exp */
/* Id: i2s.c,v 1.12 2005/01/15 14:32:35 tsubai Exp */
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: snapper.c,v 1.52 2019/06/08 08:02:37 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: snapper.c,v 1.53 2019/09/20 21:24:34 macallan Exp $");
#include <sys/param.h>
#include <sys/audioio.h>
@@ -55,7 +55,7 @@
#include <macppc/dev/deqvar.h>
#include <macppc/dev/obiovar.h>
-
+//#define SNAPPER_DEBUG
#ifdef SNAPPER_DEBUG
# define DPRINTF printf
#else
@@ -66,9 +66,12 @@
struct snapper_softc {
device_t sc_dev;
- int sc_mode; // 0 for TAS3004
+ int sc_mode;
+#define SNAPPER_IS_TAS3004 0 // codec is TAS3004
#define SNAPPER_IS_TAS3001 1 // codec is TAS3001
-#define SNAPPER_SWVOL 2 // software codec
+#define SNAPPER_IS_PCM3052 2 // codec is PCM3052
+#define SNAPPER_IS_CS8416 3 // codec is CS8416
+#define SNAPPER_SWVOL 4 // software codec
int sc_node;
@@ -475,6 +478,21 @@
};
#define TUMBLER_NFORMATS __arraycount(tumbler_formats)
+/* OF hands us the codec in 16bit mode, run with it for now */
+static const struct audio_format onyx_formats[] = {
+ {
+ .mode = AUMODE_PLAY | AUMODE_RECORD,
+ .encoding = AUDIO_ENCODING_SLINEAR_BE,
+ .validbits = 16,
+ .precision = 16,
+ .channels = 2,
+ .channel_mask = AUFMT_STEREO,
+ .frequency_type = 3,
+ .frequency = { 44100, 48000, 96000 },
+ },
+};
+#define ONYX_NFORMATS __arraycount(onyx_formats)
+
static bus_size_t amp_mute;
static bus_size_t headphone_mute;
static bus_size_t audio_hw_reset;
@@ -492,6 +510,16 @@
/* I2S_INT register definitions */
#define I2S_INT_CLKSTOPPEND 0x01000000 /* clock-stop interrupt pending */
+/* I2S_WORDSIZE register definitions */
+#define INPUT_STEREO (2 << 24)
+#define INPUT_MONO (1 << 24)
+#define INPUT_16BIT (0 << 16)
+#define INPUT_24BIT (3 << 16)
+#define OUTPUT_STEREO (2 << 8)
+#define OUTPUT_MONO (1 << 8)
+#define OUTPUT_16BIT (0 << 0)
+#define OUTPUT_24BIT (3 << 0)
+
/* FCR(0x3c) bits */
#define KEYLARGO_FCR1 0x3c
#define I2S0CLKEN 0x1000
@@ -639,6 +667,9 @@
if (strcmp(compat, "AOAK2") == 0)
return 1;
+ if (strcmp(compat, "AOAbase") == 0)
+ return 1;
+
if (OF_getprop(soundchip, "platform-tas-codec-ref",
&soundcodec, sizeof soundcodec) == sizeof soundcodec)
return 1;
@@ -664,6 +695,8 @@
memset(compat, 0, sizeof compat);
OF_getprop(OF_child(soundbus), "compatible", compat, sizeof compat);
+ sc->sc_mode = SNAPPER_IS_TAS3004;
+
if (strcmp(compat, "tumbler") == 0)
sc->sc_mode = SNAPPER_IS_TAS3001;
sc->sc_swvol_l = 255;
@@ -718,8 +751,8 @@
oirq = intr[2];
iirq = intr[4];
/* cirq_type = intr[1] ? IST_LEVEL : IST_EDGE; */
- oirq_type = intr[3] ? IST_LEVEL : IST_EDGE;
- iirq_type = intr[5] ? IST_LEVEL : IST_EDGE;
+ oirq_type = (intr[3] & 1) ? IST_LEVEL : IST_EDGE;
+ iirq_type = (intr[5] & 1) ? IST_LEVEL : IST_EDGE;
/* intr_establish(cirq, cirq_type, IPL_AUDIO, snapper_intr, sc); */
intr_establish(oirq, oirq_type, IPL_AUDIO, snapper_intr, sc);
@@ -743,25 +776,79 @@
device_t dv;
deviter_t di;
struct deq_softc *deq;
+ char prop[64], next[64], codec[64], *cref;
+ int codec_node, soundbus, sound, ok, deqnode = 0;
sc = device_private(dev);
+
+ /* look for platform-*-codec-ref node */
+
+ /*
+ * XXX
+ * there can be more than one i2sbus, the one we want just so happens
+ * to be the first we see
+ */
+ soundbus = OF_child(sc->sc_node);
+ sound = OF_child(soundbus);
+ ok = OF_nextprop(sound, NULL, next);
+ codec_node = 0;
+ while (ok && (codec_node == 0)) {
+ DPRINTF("prop %d %s\n", ok, next);
+ strncpy(prop, next, 64);
+ if ((cref = strstr(next, "-codec-ref")) != NULL) {
+ OF_getprop(sound, next, &codec_node, 4);
+ if (codec_node != 0) {
+ OF_getprop(codec_node, "compatible", codec, 64);
+ DPRINTF("%08x %s\n", codec_node, codec);
+ }
+ }
+ ok = OF_nextprop(sound, prop, next);
+ }
+
for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
dv != NULL;
dv = deviter_next(&di)) {
if (device_is_a(dv, "deq")) {
deq = device_private(dv);
+ if (codec_node != 0) {
+ if (codec_node != deq->sc_node)
+ continue;
+ }
sc->sc_i2c = deq->sc_i2c;
sc->sc_deqaddr = deq->sc_address;
+ deqnode = deq->sc_node;
}
}
deviter_release(&di);
+ DPRINTF("deqnode: %08x\n", deqnode);
+
/* If we don't find a codec, it's not the end of the world;
* we can control the volume in software in this case.
*/
- if (sc->sc_i2c == NULL)
+ if (sc->sc_i2c == NULL) {
sc->sc_mode = SNAPPER_SWVOL;
+ } else if (deqnode != 0) {
+ int ret;
+ codec[0] = 0;
+ ret = OF_getprop(deqnode, "compatible", codec, 64);
+ DPRINTF("codec <%s> %d\n", codec, ret);
+
+ if (codec[0] == 0) {
+ if (sc->sc_deqaddr == 0x34) {
+ sc->sc_mode = SNAPPER_IS_TAS3001;
+ } else
+ sc->sc_mode = SNAPPER_IS_TAS3004;
+ } else if (strcmp(codec, "tas3004") == 0) {
+ sc->sc_mode = SNAPPER_IS_TAS3004;
+ } else if (strcmp(codec, "pcm3052") == 0) {
+ sc->sc_mode = SNAPPER_IS_PCM3052;
+ } else if (strcmp(codec, "cs8416") == 0) {
+ sc->sc_mode = SNAPPER_IS_CS8416;
+ }
+ }
+ DPRINTF("mode %d\n", sc->sc_mode);
switch (sc->sc_mode) {
case SNAPPER_SWVOL:
aprint_verbose("%s: software codec\n", device_xname(dev));
@@ -769,9 +856,15 @@
case SNAPPER_IS_TAS3001:
aprint_verbose("%s: codec: TAS3001\n", device_xname(dev));
break;
- case 0:
+ case SNAPPER_IS_TAS3004:
aprint_verbose("%s: codec: TAS3004\n", device_xname(dev));
break;
+ case SNAPPER_IS_PCM3052:
+ aprint_verbose("%s: codec: PCM3052 / ONYX\n", device_xname(dev));
+ break;
+ default:
+ aprint_error_dev(sc->sc_dev, "unsupported codec\n");
+ sc->sc_mode = SNAPPER_SWVOL;
}
snapper_init(sc, sc->sc_node);
@@ -826,13 +919,19 @@
{
struct snapper_softc *sc = h;
- if (sc->sc_mode == SNAPPER_IS_TAS3001) {
- return audio_query_format(tumbler_formats, TUMBLER_NFORMATS,
- afp);
- } else {
- return audio_query_format(snapper_formats, SNAPPER_NFORMATS,
- afp);
+ switch (sc->sc_mode) {
+ case SNAPPER_IS_TAS3001:
+ return audio_query_format(tumbler_formats,
+ TUMBLER_NFORMATS, afp);
+ case SNAPPER_SWVOL:
+ case SNAPPER_IS_TAS3004:
+ return audio_query_format(snapper_formats,
+ SNAPPER_NFORMATS, afp);
+ case SNAPPER_IS_PCM3052:
+ return audio_query_format(onyx_formats,
+ ONYX_NFORMATS, afp);
}
+ return -1;
}
static int
@@ -870,8 +969,8 @@
const audio_params_t *param)
{
- if (size < NBPG)
- size = NBPG;
+ if (size < (3 * NBPG))
+ size = (3 * NBPG);
return size & ~PGOFSET;
}
@@ -1476,7 +1575,7 @@
{
uint8_t regs[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int i;
-
+if (sc->sc_mode > 1) return;
/* Left channel of SDIN1 */
ADJUST(i, sc->mixer[0]);
regs[0] = snapper_mixer_gain[i][0];
@@ -1619,11 +1718,13 @@
DPRINTF("precision: %d\n", sc->sc_bitspersample);
switch(sc->sc_bitspersample) {
case 16:
- wordsize = 0x02000200;
+ wordsize = INPUT_STEREO | INPUT_16BIT |
+ OUTPUT_STEREO | OUTPUT_16BIT;
mcr1 = DEQ_MCR1_SC_64 | DEQ_MCR1_SM_I2S | DEQ_MCR1_W_16;
break;
case 24:
- wordsize = 0x03000300;
+ wordsize = INPUT_STEREO | INPUT_24BIT |
+ OUTPUT_STEREO | OUTPUT_24BIT;
mcr1 = DEQ_MCR1_SC_64 | DEQ_MCR1_SM_I2S | DEQ_MCR1_W_24;
break;
default:
@@ -1895,34 +1996,36 @@
delay(10000);
noreset:
- DEQ_WRITE(sc, DEQ_LB0, tas3004_initdata.LB0);
- DEQ_WRITE(sc, DEQ_LB1, tas3004_initdata.LB1);
- DEQ_WRITE(sc, DEQ_LB2, tas3004_initdata.LB2);
- DEQ_WRITE(sc, DEQ_LB3, tas3004_initdata.LB3);
- DEQ_WRITE(sc, DEQ_LB4, tas3004_initdata.LB4);
- DEQ_WRITE(sc, DEQ_LB5, tas3004_initdata.LB5);
- DEQ_WRITE(sc, DEQ_LB6, tas3004_initdata.LB6);
- DEQ_WRITE(sc, DEQ_RB0, tas3004_initdata.RB0);
- DEQ_WRITE(sc, DEQ_RB1, tas3004_initdata.RB1);
- DEQ_WRITE(sc, DEQ_RB1, tas3004_initdata.RB1);
- DEQ_WRITE(sc, DEQ_RB2, tas3004_initdata.RB2);
- DEQ_WRITE(sc, DEQ_RB3, tas3004_initdata.RB3);
- DEQ_WRITE(sc, DEQ_RB4, tas3004_initdata.RB4);
- DEQ_WRITE(sc, DEQ_RB5, tas3004_initdata.RB5);
- DEQ_WRITE(sc, DEQ_MCR1, tas3004_initdata.MCR1);
- DEQ_WRITE(sc, DEQ_MCR2, tas3004_initdata.MCR2);
- DEQ_WRITE(sc, DEQ_DRC, tas3004_initdata.DRC);
- DEQ_WRITE(sc, DEQ_VOLUME, tas3004_initdata.VOLUME);
- DEQ_WRITE(sc, DEQ_TREBLE, tas3004_initdata.TREBLE);
- DEQ_WRITE(sc, DEQ_BASS, tas3004_initdata.BASS);
- DEQ_WRITE(sc, DEQ_MIXER_L, tas3004_initdata.MIXER_L);
- DEQ_WRITE(sc, DEQ_MIXER_R, tas3004_initdata.MIXER_R);
- DEQ_WRITE(sc, DEQ_LLB, tas3004_initdata.LLB);
- DEQ_WRITE(sc, DEQ_RLB, tas3004_initdata.RLB);
- DEQ_WRITE(sc, DEQ_LLB_GAIN, tas3004_initdata.LLB_GAIN);
Home |
Main Index |
Thread Index |
Old Index