Subject: Re: snapper microphone support
To: None <port-macppc@netbsd.org>
From: Magnus Henoch <mange@freemail.hu>
List: port-macppc
Date: 12/19/2005 16:08:35
Michael <macallan18@earthlink.net> writes:
> Not really difficult, someone probably did it already - did you have a
> look at arch/macppc/dev/snapper.c ?
I started to hack it, and came to a good start. With the patch below,
the commands:
mixerctl -w record.source=mic
mixerctl -w monitor.Analog=100
audiorecord -d /dev/audio0 foo.wav
give a recording from the internal microphone. The sound is faint,
and there is some noise, but it's something at least. The manual
mentions many features I don't understand; maybe some of them would
give better sound.
Comments on the code are very welcome. I haven't yet figured out how
to enable recording from CD or line-in, or how to set the input
volume.
Magnus
--- snapper.c 12 Dec 2005 10:43:47 +0100 1.7
+++ snapper.c 19 Dec 2005 15:24:38 +0100
@@ -68,6 +68,7 @@
void (*sc_iintr)(void *); /* dma completion intr handler */
void *sc_iarg; /* arg for sc_iintr() */
+ int sc_ipages; /* # of input pages */
u_int sc_record_source; /* recording source mask */
u_int sc_output_mask; /* output source mask */
@@ -398,7 +399,7 @@
/* intr_establish(cirq, cirq_type, IPL_AUDIO, snapper_intr, sc); */
intr_establish(oirq, oirq_type, IPL_AUDIO, snapper_intr, sc);
- /* intr_establish(iirq, iirq_type, IPL_AUDIO, snapper_intr, sc); */
+ intr_establish(iirq, iirq_type, IPL_AUDIO, snapper_intr, sc);
printf(": irq %d,%d,%d\n", cirq, oirq, iirq);
@@ -463,6 +464,20 @@
cmd++;
}
+ cmd = sc->sc_idmacmd;
+ count = sc->sc_ipages;
+ while (count-- > 0) {
+ if ((dbdma_ld16(&cmd->d_command) & 0x30) == 0x30) {
+ status = dbdma_ld16(&cmd->d_status);
+ cmd->d_status = 0;
+ if (status) /* status == 0x8400 */
+ if (sc->sc_iintr)
+ (*sc->sc_iintr)(sc->sc_iarg);
+ }
+ cmd++;
+ }
+
+
return 1;
}
@@ -643,6 +658,7 @@
{
struct snapper_softc *sc;
int l, r;
+ u_char data;
DPRINTF("snapper_set_port dev = %d, type = %d\n", mc->dev, mc->type);
sc = h;
@@ -675,10 +691,14 @@
return 0;
switch (mc->un.mask) {
case 1 << 0: /* CD */
- case 1 << 1: /* microphone */
case 1 << 2: /* line in */
/* XXX TO BE DONE */
break;
+ case 1 << 1: /* microphone */
+ /* Select right channel of B input */
+ data = DEQ_ACR_ADM | DEQ_ACR_LRB | DEQ_ACR_INP_B;
+ tas3004_write(sc, DEQ_ACR, &data);
+ break;
default: /* invalid argument */
return EINVAL;
}
@@ -956,9 +976,53 @@
void (*intr)(void *), void *arg,
const audio_params_t *param)
{
+ struct snapper_softc *sc;
+ struct dbdma_command *cmd;
+ vaddr_t va;
+ int i, len, intmode;
+
+ DPRINTF("trigger_input %p %p 0x%x\n", start, end, bsize);
+ sc = h;
+ cmd = sc->sc_idmacmd;
+ sc->sc_iintr = intr;
+ sc->sc_iarg = arg;
+ sc->sc_ipages = ((char *)end - (char *)start) / NBPG;
+
+#ifdef DIAGNOSTIC
+ if (sc->sc_ipages > 16)
+ panic("snapper_trigger_input");
+#endif
+
+ va = (vaddr_t)start;
+ len = 0;
+ for (i = sc->sc_ipages; i > 0; i--) {
+ len += NBPG;
+ if (len < bsize)
+ intmode = 0;
+ else {
+ len = 0;
+ intmode = DBDMA_INT_ALWAYS;
+ }
+ DBDMA_BUILD(cmd, DBDMA_CMD_IN_MORE, 0, NBPG, vtophys(va),
+ intmode, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
+ cmd++;
+ va += NBPG;
+ }
+
+ DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0,
+ 0/*vtophys((vaddr_t)sc->sc_odmacmd)*/, 0, DBDMA_WAIT_NEVER,
+ DBDMA_BRANCH_ALWAYS);
+
+ dbdma_st32(&cmd->d_cmddep, vtophys((vaddr_t)sc->sc_idmacmd));
+
+ dbdma_start(sc->sc_idma, sc->sc_idmacmd);
+
+ return 0;
+ /*
printf("snapper_trigger_input called\n");
return 1;
+ */
}
void
@@ -1219,8 +1283,8 @@
size = tas3004_regsize[reg];
KASSERT(size > 0);
-#ifdef DEBUG_SNAPPER
- printf("reg: %x, %d %d\n",reg,size,((char*)data)[0]);
+#ifdef SNAPPER_DEBUG
+ printf("reg: %x, %d %d\n",reg,size,((const char*)data)[0]);
#endif
#if 0
ki2c_setmode(sc->sc_i2c, 8); /* std+sub mode */
@@ -1415,7 +1479,7 @@
OF_getprop(gpio, "name", name, sizeof name);
OF_getprop(gpio, "audio-gpio", audio_gpio, sizeof audio_gpio);
OF_getprop(gpio, "AAPL,address", &addr, sizeof addr);
- /* printf("0x%x %s %s\n", gpio, name, audio_gpio); */
+ DPRINTF(" 0x%x %s %s\n", gpio, name, audio_gpio);
/* gpio5 */
if (strcmp(audio_gpio, "headphone-mute") == 0)