From f0d5bc974b2e6f0147eed4b9cb1e0372555b0ed1 Mon Sep 17 00:00:00 2001 From: todd Date: Sun, 24 Aug 2008 23:44:44 +0000 Subject: [PATCH] o implement proper volume control table based on chipset docs o attempt to make record work (but silence for now) from drahn@, ok maja@, drahn@ --- sys/arch/macppc/dev/i2s.c | 91 ++++++++++++--- sys/arch/macppc/dev/i2svar.h | 5 +- sys/arch/macppc/dev/openpic.c | 69 +++++++++++- sys/arch/macppc/dev/snapper.c | 202 ++++++++++++++++++++++++++++++++-- 4 files changed, 338 insertions(+), 29 deletions(-) diff --git a/sys/arch/macppc/dev/i2s.c b/sys/arch/macppc/dev/i2s.c index 817ba64d3d4..e4ea99c65a0 100644 --- a/sys/arch/macppc/dev/i2s.c +++ b/sys/arch/macppc/dev/i2s.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i2s.c,v 1.11 2007/12/11 09:11:54 jakemsr Exp $ */ +/* $OpenBSD: i2s.c,v 1.12 2008/08/24 23:44:44 todd Exp $ */ /* $NetBSD: i2s.c,v 1.1 2003/12/27 02:19:34 grant Exp $ */ /*- @@ -64,6 +64,9 @@ int i2s_cint(void *); u_char *i2s_gpio_map(struct i2s_softc *, char *, int *); void i2s_init(struct i2s_softc *, int); +int i2s_intr(void *); +int i2s_iintr(void *); + /* XXX */ void keylargo_fcr_enable(int, u_int32_t); void keylargo_fcr_disable(int, u_int32_t); @@ -135,7 +138,8 @@ i2s_attach(struct device *parent, struct i2s_softc *sc, struct confargs *ca) /* intr_establish(cirq, cirq_type, IPL_AUDIO, i2s_intr, sc); */ mac_intr_establish(parent, oirq, oirq_type, IPL_AUDIO, i2s_intr, sc, sc->sc_dev.dv_xname); - /* intr_establish(iirq, iirq_type, IPL_AUDIO, i2s_intr, sc); */ + mac_intr_establish(parent, iirq, iirq_type, IPL_AUDIO, i2s_iintr, + sc, sc->sc_dev.dv_xname); printf(": irq %d,%d,%d\n", cirq, oirq, iirq); @@ -174,6 +178,37 @@ i2s_intr(v) return 1; } +int +i2s_iintr(v) + void *v; +{ + struct i2s_softc *sc = v; + struct dbdma_command *cmd = sc->sc_idmap; + u_int16_t c, status; + + /* if not set we are not running */ + if (!cmd) + return (0); + DPRINTF(("i2s_intr: cmd %x\n", cmd)); + + c = in16rb(&cmd->d_command); + status = in16rb(&cmd->d_status); + + if (c >> 12 == DBDMA_CMD_IN_LAST) + sc->sc_idmap = sc->sc_idmacmd; + else + sc->sc_idmap++; + + if (c & (DBDMA_INT_ALWAYS << 4)) { + cmd->d_status = 0; + if (status) /* status == 0x8400 */ + if (sc->sc_iintr) + (*sc->sc_iintr)(sc->sc_iarg); + } + + return 1; +} + int i2s_open(h, flags) void *h; @@ -507,14 +542,15 @@ i2s_set_port(h, mc) if (mc->un.mask == sc->sc_record_source) return 0; switch (mc->un.mask) { - case 1 << 0: /* CD */ - case 1 << 1: /* microphone */ - case 1 << 2: /* line in */ + case 1 << 0: /* microphone */ + case 1 << 1: /* line in */ /* XXX TO BE DONE */ break; default: /* invalid argument */ return EINVAL; } + if (sc->sc_setinput != NULL) + (*sc->sc_setinput)(sc, mc->un.mask); sc->sc_record_source = mc->un.mask; return 0; @@ -617,16 +653,13 @@ i2s_query_devinfo(h, dip) strlcpy(dip->label.name, AudioNsource, sizeof(dip->label.name)); dip->type = AUDIO_MIXER_SET; dip->prev = dip->next = AUDIO_MIXER_LAST; - dip->un.s.num_mem = 3; - strlcpy(dip->un.s.member[0].label.name, AudioNcd, + dip->un.s.num_mem = 2; + strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone, sizeof(dip->un.s.member[0].label.name)); dip->un.s.member[0].mask = 1 << 0; - strlcpy(dip->un.s.member[1].label.name, AudioNmicrophone, + strlcpy(dip->un.s.member[1].label.name, AudioNline, sizeof(dip->un.s.member[1].label.name)); dip->un.s.member[1].mask = 1 << 1; - strlcpy(dip->un.s.member[2].label.name, AudioNline, - sizeof(dip->un.s.member[2].label.name)); - dip->un.s.member[2].mask = 1 << 2; return 0; case I2S_VOL_INPUT: @@ -763,9 +796,41 @@ i2s_trigger_input(h, start, end, bsize, intr, arg, param) void *arg; struct audio_params *param; { - DPRINTF(("i2s_trigger_input called\n")); + struct i2s_softc *sc = h; + struct i2s_dma *p; + struct dbdma_command *cmd = sc->sc_idmacmd; + vaddr_t spa, pa, epa; + int c; - return 1; + DPRINTF(("trigger_input %p %p 0x%x\n", start, end, bsize)); + + for (p = sc->sc_dmas; p && p->addr != start; p = p->next); + if (!p) + return -1; + + sc->sc_iintr = intr; + sc->sc_iarg = arg; + sc->sc_idmap = sc->sc_idmacmd; + + spa = p->segs[0].ds_addr; + c = DBDMA_CMD_IN_MORE; + for (pa = spa, epa = spa + (end - start); + pa < epa; pa += bsize, cmd++) { + + if (pa + bsize == epa) + c = DBDMA_CMD_IN_LAST; + + DBDMA_BUILD(cmd, c, 0, bsize, pa, DBDMA_INT_ALWAYS, + DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); + } + + DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0, + DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS); + dbdma_st32(&cmd->d_cmddep, sc->sc_idbdma->d_paddr); + + dbdma_start(sc->sc_idma, sc->sc_idbdma); + + return 0; } diff --git a/sys/arch/macppc/dev/i2svar.h b/sys/arch/macppc/dev/i2svar.h index ca01e72921d..e6af63e1962 100644 --- a/sys/arch/macppc/dev/i2svar.h +++ b/sys/arch/macppc/dev/i2svar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: i2svar.h,v 1.3 2005/11/19 01:07:00 kettenis Exp $ */ -/* $Id: i2svar.h,v 1.3 2005/11/19 01:07:00 kettenis Exp $ */ +/* $OpenBSD: i2svar.h,v 1.4 2008/08/24 23:44:44 todd Exp $ */ +/* $Id: i2svar.h,v 1.4 2008/08/24 23:44:44 todd Exp $ */ /*- * Copyright (c) 2001,2003 Tsubai Masanari. All rights reserved. @@ -61,6 +61,7 @@ struct i2s_softc { void (*sc_setvolume)(struct i2s_softc *, int, int); void (*sc_setbass)(struct i2s_softc *, int); void (*sc_settreble)(struct i2s_softc *, int); + void (*sc_setinput)(struct i2s_softc *, int); u_char *sc_reg; void *sc_i2c; diff --git a/sys/arch/macppc/dev/openpic.c b/sys/arch/macppc/dev/openpic.c index f2791afd555..3baf5a9884e 100644 --- a/sys/arch/macppc/dev/openpic.c +++ b/sys/arch/macppc/dev/openpic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openpic.c,v 1.45 2008/05/04 20:54:22 drahn Exp $ */ +/* $OpenBSD: openpic.c,v 1.46 2008/08/24 23:44:44 todd Exp $ */ /*- * Copyright (c) 1995 Per Fogelstrom @@ -75,7 +75,14 @@ void openpic_enable_irq_mask(int irq_mask); #define HWIRQ_MASK 0x0fffffff /* IRQ vector used for inter-processor interrupts. */ -#define IPI_VECTOR 64 +#define IPI_VECTOR_DDB 64 +#define IPI_VECTOR_NOP 65 +#ifdef MULTIPROCESSOR +static struct evcount ipi_ddb[2]; +static struct evcount ipi_nop[2]; +static int ipi_nopirq = IPI_VECTOR_NOP; +static int ipi_ddbirq = IPI_VECTOR_DDB; +#endif static __inline u_int openpic_read(int); static __inline void openpic_write(int, u_int); @@ -86,6 +93,7 @@ void openpic_init(void); void openpic_set_priority(int, int); static __inline int openpic_read_irq(int); static __inline void openpic_eoi(int); +void openpic_ipi_ddb(void); struct openpic_softc { struct device sc_dev; @@ -664,6 +672,9 @@ openpic_send_ipi(int cpu) #endif + +/* XXX */ extern long hostid; + void ext_intr_openpic() { @@ -679,8 +690,16 @@ ext_intr_openpic() while (realirq != 255) { #ifdef MULTIPROCESSOR - if (realirq == IPI_VECTOR) { + if (realirq == IPI_VECTOR_NOP) { + ipi_nop[ci->ci_cpuid].ec_count++; + openpic_eoi(ci->ci_cpuid); + realirq = openpic_read_irq(ci->ci_cpuid); + continue; + } + if (realirq == IPI_VECTOR_DDB) { + ipi_ddb[ci->ci_cpuid].ec_count++; openpic_eoi(ci->ci_cpuid); + openpic_ipi_ddb(); realirq = openpic_read_irq(ci->ci_cpuid); continue; } @@ -699,8 +718,8 @@ ext_intr_openpic() openpic_eoi(ci->ci_cpuid); } else { openpic_enable_irq_mask(~imask[o_intrmaxlvl[realirq]]); - openpic_eoi(ci->ci_cpuid); ocpl = splraise(imask[o_intrmaxlvl[realirq]]); + openpic_eoi(ci->ci_cpuid); ih = o_intrhand[irq]; while (ih) { @@ -761,8 +780,22 @@ openpic_init() /* Set up inter-processor interrupts. */ x = openpic_read(OPENPIC_IPI_VECTOR(0)); x &= ~(OPENPIC_IMASK | OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK); - x |= (15 << OPENPIC_PRIORITY_SHIFT) | IPI_VECTOR; + x |= (15 << OPENPIC_PRIORITY_SHIFT) | IPI_VECTOR_NOP; openpic_write(OPENPIC_IPI_VECTOR(0), x); + + evcount_attach(&ipi_nop[0], "ipi_nop0", (void *)&ipi_nopirq, + &evcount_intr); + evcount_attach(&ipi_nop[1], "ipi_nop1", (void *)&ipi_nopirq, + &evcount_intr); + + x = openpic_read(OPENPIC_IPI_VECTOR(1)); + x &= ~(OPENPIC_IMASK | OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK); + x |= (15 << OPENPIC_PRIORITY_SHIFT) | IPI_VECTOR_DDB; + openpic_write(OPENPIC_IPI_VECTOR(1), x); + evcount_attach(&ipi_ddb[0], "ipi_ddb0", (void *)&ipi_ddbirq, + &evcount_intr); + evcount_attach(&ipi_ddb[1], "ipi_ddb1", (void *)&ipi_ddbirq, + &evcount_intr); #endif /* XXX set spurious intr vector */ @@ -795,3 +828,29 @@ openpic_prog_button (void *arg) #endif return 1; } + +void +openpic_ipi_ddb() +{ + printf("ipi_ddb() called\n"); + Debugger(); +} + +void +ppc_send_ipi(struct cpu_info *ci, int id) +{ + printf("sending IPI %d to %d\n", id, ci->ci_cpuid); + switch (id) { + case PPC_IPI_NOP: + id = 0; + break; + case PPC_IPI_DDB: + id = 1; + break; + default: + printf("invalid ipi send to cpu %d %d\n", ci->ci_cpuid, id); + return; + } + + openpic_write(OPENPIC_IPI(curcpu()->ci_cpuid, id), 1 << ci->ci_cpuid); +} diff --git a/sys/arch/macppc/dev/snapper.c b/sys/arch/macppc/dev/snapper.c index 1b334af8c78..8b424854dd8 100644 --- a/sys/arch/macppc/dev/snapper.c +++ b/sys/arch/macppc/dev/snapper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: snapper.c,v 1.29 2008/04/21 00:32:42 jakemsr Exp $ */ +/* $OpenBSD: snapper.c,v 1.30 2008/08/24 23:44:44 todd Exp $ */ /* $NetBSD: snapper.c,v 1.1 2003/12/27 02:19:34 grant Exp $ */ /*- @@ -66,6 +66,7 @@ void snapper_defer(struct device *); void snapper_set_volume(struct snapper_softc *, int, int); void snapper_set_bass(struct snapper_softc *, int); void snapper_set_treble(struct snapper_softc *, int); +void snapper_set_input(struct snapper_softc *, int); int tas3004_write(struct snapper_softc *, u_int, const void *); int tas3004_init(struct snapper_softc *); @@ -193,6 +194,163 @@ const uint8_t snapper_basstab[] = { 0x01, /* 18dB */ }; +struct { + int high, mid, low; +} snapper_volumetab[] = { + { 0x07, 0xF1, 0x7B }, /* 18.0 */ + { 0x07, 0x7F, 0xBB }, 0x/* 17.5 */ + { 0x07, 0x14, 0x57 }, /* 17.0 */ + { 0x06, 0xAE, 0xF6 }, /* 16.5 */ + { 0x06, 0x4F, 0x40 }, /* 16.0 */ + { 0x05, 0xF4, 0xE5 }, /* 15.5 */ + { 0x05, 0x9F, 0x98 }, /* 15.0 */ + { 0x05, 0x4F, 0x10 }, /* 14.5 */ + { 0x05, 0x03, 0x0A }, /* 14.0 */ + { 0x04, 0xBB, 0x44 }, /* 13.5 */ + { 0x04, 0x77, 0x83 }, /* 13.0 */ + { 0x04, 0x37, 0x8B }, /* 12.5 */ + { 0x03, 0xFB, 0x28 }, /* 12.0 */ + { 0x03, 0xC2, 0x25 }, /* 11.5 */ + { 0x03, 0x8C, 0x53 }, /* 11.0 */ + { 0x03, 0x59, 0x83 }, /* 10.5 */ + { 0x03, 0x29, 0x8B }, /* 10.0 */ + { 0x02, 0xFC, 0x42 }, /* 9.5 */ + { 0x02, 0xD1, 0x82 }, /* 9.0 */ + { 0x02, 0xA9, 0x25 }, /* 8.5 */ + { 0x02, 0x83, 0x0B }, /* 8.0 */ + { 0x02, 0x5F, 0x12 }, /* 7.5 */ + { 0x02, 0x3D, 0x1D }, /* 7.0 */ + { 0x02, 0x1D, 0x0E }, /* 6.5 */ + { 0x01, 0xFE, 0xCA }, /* 6.0 */ + { 0x01, 0xE2, 0x37 }, /* 5.5 */ + { 0x01, 0xC7, 0x3D }, /* 5.0 */ + { 0x01, 0xAD, 0xC6 }, /* 4.5 */ + { 0x01, 0x95, 0xBC }, /* 4.0 */ + { 0x01, 0x7F, 0x09 }, /* 3.5 */ + { 0x01, 0x69, 0x9C }, /* 3.0 */ + { 0x01, 0x55, 0x62 }, /* 2.5 */ + { 0x01, 0x42, 0x49 }, /* 2.0 */ + { 0x01, 0x30, 0x42 }, /* 1.5 */ + { 0x01, 0x1F, 0x3D }, /* 1.0 */ + { 0x01, 0x0F, 0x2B }, /* 0.5 */ + { 0x01, 0x00, 0x00 }, /* 0.0 */ + { 0x00, 0xF1, 0xAE }, /* -0.5 */ + { 0x00, 0xE4, 0x29 }, /* -1.0 */ + { 0x00, 0xD7, 0x66 }, /* -1.5 */ + { 0x00, 0xCB, 0x59 }, /* -2.0 */ + { 0x00, 0xBF, 0xF9 }, /* -2.5 */ + { 0x00, 0xB5, 0x3C }, /* -3.0 */ + { 0x00, 0xAB, 0x19 }, /* -3.5 */ + { 0x00, 0xA1, 0x86 }, /* -4.0 */ + { 0x00, 0x98, 0x7D }, /* -4.5 */ + { 0x00, 0x8F, 0xF6 }, /* -5.0 */ + { 0x00, 0x87, 0xE8 }, /* -5.5 */ + { 0x00, 0x80, 0x4E }, /* -6.0 */ + { 0x00, 0x79, 0x20 }, /* -6.5 */ + { 0x00, 0x72, 0x5A }, /* -7.0 */ + { 0x00, 0x6B, 0xF4 }, /* -7.5 */ + { 0x00, 0x65, 0xEA }, /* -8.0 */ + { 0x00, 0x60, 0x37 }, /* -8.5 */ + { 0x00, 0x5A, 0xD5 }, /* -9.0 */ + { 0x00, 0x55, 0xC0 }, /* -9.5 */ + { 0x00, 0x50, 0xF4 }, /* -10.0 */ + { 0x00, 0x4C, 0x6D }, /* -10.5 */ + { 0x00, 0x48, 0x27 }, /* -11.0 */ + { 0x00, 0x44, 0x1D }, /* -11.5 */ + { 0x00, 0x40, 0x4E }, /* -12.0 */ + { 0x00, 0x3C, 0xB5 }, /* -12.5 */ + { 0x00, 0x39, 0x50 }, /* -13.0 */ + { 0x00, 0x36, 0x1B }, /* -13.5 */ + { 0x00, 0x33, 0x14 }, /* -14.0 */ + { 0x00, 0x30, 0x39 }, /* -14.5 */ + { 0x00, 0x2D, 0x86 }, /* -15.0 */ + { 0x00, 0x2A, 0xFA }, /* -15.5 */ + { 0x00, 0x28, 0x93 }, /* -16.0 */ + { 0x00, 0x26, 0x4E }, /* -16.5 */ + { 0x00, 0x24, 0x29 }, /* -17.0 */ + { 0x00, 0x22, 0x23 }, /* -17.5 */ + { 0x00, 0x20, 0x3A }, /* -18.0 */ + { 0x00, 0x1E, 0x6D }, /* -18.5 */ + { 0x00, 0x1C, 0xB9 }, /* -19.0 */ + { 0x00, 0x1B, 0x1E }, /* -19.5 */ + { 0x00, 0x19, 0x9A }, /* -20.0 */ + { 0x00, 0x18, 0x2B }, /* -20.5 */ + { 0x00, 0x16, 0xD1 }, /* -21.0 */ + { 0x00, 0x15, 0x8A }, /* -21.5 */ + { 0x00, 0x14, 0x56 }, /* -22.0 */ + { 0x00, 0x13, 0x33 }, /* -22.5 */ + { 0x00, 0x12, 0x20 }, /* -23.0 */ + { 0x00, 0x11, 0x1C }, /* -23.5 */ + { 0x00, 0x10, 0x27 }, /* -24.0 */ + { 0x00, 0x0F, 0x40 }, /* -24.5 */ + { 0x00, 0x0E, 0x65 }, /* -25.0 */ + { 0x00, 0x0D, 0x97 }, /* -25.5 */ + { 0x00, 0x0C, 0xD5 }, /* -26.0 */ + { 0x00, 0x0C, 0x1D }, /* -26.5 */ + { 0x00, 0x0B, 0x6F }, /* -27.0 */ + { 0x00, 0x0A, 0xCC }, /* -27.5 */ + { 0x00, 0x0A, 0x31 }, /* -28.0 */ + { 0x00, 0x09, 0x9F }, /* -28.5 */ + { 0x00, 0x09, 0x15 }, /* -29.0 */ + { 0x00, 0x08, 0x93 }, /* -29.5 */ + { 0x00, 0x08, 0x18 }, /* -30.0 */ + { 0x00, 0x07, 0xA5 }, /* -30.5 */ + { 0x00, 0x07, 0x37 }, /* -31.0 */ + { 0x00, 0x06, 0xD0 }, /* -31.5 */ + { 0x00, 0x06, 0x6E }, /* -32.0 */ + { 0x00, 0x06, 0x12 }, /* -32.5 */ + { 0x00, 0x05, 0xBB }, /* -33.0 */ + { 0x00, 0x05, 0x69 }, /* -33.5 */ + { 0x00, 0x05, 0x1C }, /* -34.0 */ + { 0x00, 0x04, 0xD2 }, /* -34.5 */ + { 0x00, 0x04, 0x8D }, /* -35.0 */ + { 0x00, 0x04, 0x4C }, /* -35.5 */ + { 0x00, 0x04, 0x0F }, /* -36.0 */ + { 0x00, 0x03, 0xD5 }, /* -36.5 */ + { 0x00, 0x03, 0x9E }, /* -37.0 */ + { 0x00, 0x03, 0x6A }, /* -37.5 */ + { 0x00, 0x03, 0x39 }, /* -38.0 */ + { 0x00, 0x03, 0x0B }, /* -38.5 */ + { 0x00, 0x02, 0xDF }, /* -39.0 */ + { 0x00, 0x02, 0xB6 }, /* -39.5 */ + { 0x00, 0x02, 0x8F }, /* -40.0 */ + { 0x00, 0x02, 0x6B }, /* -40.5 */ + { 0x00, 0x02, 0x48 }, /* -41.0 */ + { 0x00, 0x02, 0x27 }, /* -41.5 */ + { 0x00, 0x02, 0x09 }, /* -42.0 */ + { 0x00, 0x01, 0xEB }, /* -42.5 */ + { 0x00, 0x01, 0xD0 }, /* -43.0 */ + { 0x00, 0x01, 0xB6 }, /* -43.5 */ + { 0x00, 0x01, 0x9E }, /* -44.0 */ + { 0x00, 0x01, 0x86 }, /* -44.5 */ + { 0x00, 0x01, 0x71 }, /* -45.0 */ + { 0x00, 0x01, 0x5C }, /* -45.5 */ + { 0x00, 0x01, 0x48 }, /* -46.0 */ + { 0x00, 0x01, 0x36 }, /* -46.5 */ + { 0x00, 0x01, 0x25 }, /* -47.0 */ + { 0x00, 0x01, 0x14 }, /* -47.5 */ + { 0x00, 0x01, 0x05 }, /* -48.0 */ + { 0x00, 0x00, 0xF6 }, /* -48.5 */ + { 0x00, 0x00, 0xE9 }, /* -49.0 */ + { 0x00, 0x00, 0xDC }, /* -49.5 */ + { 0x00, 0x00, 0xCF }, /* -50.0 */ + { 0x00, 0x00, 0xC4 }, /* -50.5 */ + { 0x00, 0x00, 0xB9 }, /* -51.0 */ + { 0x00, 0x00, 0xAE }, /* -51.5 */ + { 0x00, 0x00, 0xA5 }, /* -52.0 */ + { 0x00, 0x00, 0x9B }, /* -52.5 */ + { 0x00, 0x00, 0x93 }, /* -53.0 */ + { 0x00, 0x00, 0x8B }, /* -53.5 */ + { 0x00, 0x00, 0x83 }, /* -54.0 */ + { 0x00, 0x00, 0x7B }, /* -54.5 */ + { 0x00, 0x00, 0x75 }, /* -55.0 */ + { 0x00, 0x00, 0x6E }, /* -55.5 */ + { 0x00, 0x00, 0x68 }, /* -56.0 */ + { 0x00, 0x00, 0x62 }, /* -56.5 */ + { 0x00, 0x00, 0x0 } /* Mute? */ + +}; + /* TAS3004 registers */ #define DEQ_MCR1 0x01 /* Main control register 1 (1byte) */ #define DEQ_DRC 0x02 /* Dynamic range compression (6bytes?) */ @@ -314,6 +472,7 @@ snapper_attach(struct device *parent, struct device *self, void *aux) sc->sc_setvolume = snapper_set_volume; sc->sc_setbass = snapper_set_bass; sc->sc_settreble = snapper_set_treble; + sc->sc_setinput = snapper_set_input; i2s_attach(parent, sc, aux); config_defer(self, snapper_defer); @@ -346,19 +505,29 @@ void snapper_set_volume(struct snapper_softc *sc, int left, int right) { u_char vol[6]; + int nentries = sizeof(snapper_volumetab) / sizeof(snapper_volumetab[0]); + int l, r; sc->sc_vol_l = left; sc->sc_vol_r = right; - left <<= 8; /* XXX for now */ - right <<= 8; + l = nentries - (left * nentries / 256); + r = nentries - (right * nentries / 256); - vol[0] = left >> 16; - vol[1] = left >> 8; - vol[2] = left; - vol[3] = right >> 16; - vol[4] = right >> 8; - vol[5] = right; + DPRINTF(" left %d vol %d %d, right %d vol %d %d\n", + left, l, nentries, + right, r, nentries); + if (l >= nentries) + l = nentries-1; + if (r >= nentries) + r = nentries-1; + + vol[0] = snapper_volumetab[l].high; + vol[1] = snapper_volumetab[l].mid; + vol[2] = snapper_volumetab[l].low; + vol[3] = snapper_volumetab[r].high; + vol[4] = snapper_volumetab[r].mid; + vol[5] = snapper_volumetab[r].low; tas3004_write(sc, DEQ_VOLUME, vol); } @@ -389,6 +558,21 @@ snapper_set_bass(struct snapper_softc *sc, int value) } } +void +snapper_set_input(struct snapper_softc *sc, int mask) +{ + int val = 0; + switch(mask) { + case 1 << 0: /* microphone */ + val = DEQ_ACR_ADM | DEQ_ACR_LRB | DEQ_ACR_INP_B; + break; + case 1 << 1: /* line in */ + val = 0; + break; + } + tas3004_write(sc, DEQ_ACR, &val); +} + const struct tas3004_reg tas3004_initdata = { { DEQ_MCR1_SC_64 | DEQ_MCR1_SM_I2S | DEQ_MCR1_W_20 }, /* MCR1 */ { 1, 0, 0, 0, 0, 0 }, /* DRC */ -- 2.20.1