NetBSD Problem Report #38952
From www@NetBSD.org Sat Jun 14 05:10:10 2008
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by narn.NetBSD.org (Postfix) with ESMTP id B821763B9EE
for <gnats-bugs@gnats.netbsd.org>; Sat, 14 Jun 2008 05:10:10 +0000 (UTC)
Message-Id: <20080614051009.7101563B9CD@narn.NetBSD.org>
Date: Sat, 14 Jun 2008 05:10:09 +0000 (UTC)
From: hsaliak@gmail.com
Reply-To: hsaliak@gmail.com
To: gnats-bugs@NetBSD.org
Subject: snapper audio does not work on 14.1" ibook ( Patch for netbsd-4 branch attached).
X-Send-Pr-Version: www-1.0
>Number: 38952
>Category: port-macppc
>Synopsis: snapper audio does not work on 14.1" ibook ( Patch for netbsd-4 branch attached).
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-macppc-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Jun 14 05:15:00 +0000 2008
>Last-Modified: Sun Jun 15 17:00:04 +0000 2008
>Originator: Kailash Sethuraman
>Release: 4.0_STABLE (macppc)
>Organization:
>Environment:
NetBSD rodimus 4.0_STABLE NetBSD 4.0_STABLE (RODIMUS) #10: Sat Jun 14 12:27:18 SGT 2008 hsaliak@rodimus:/usr/src/sys/arch/macppc/compile/RODIMUS macppc
>Description:
On some versions of ibook, the soundchip the snapper driver uses is called "codec" rather than deq.
On these ibooks, audio is currently not available in Netbsd 4.
A look at the current code for the driver shows that its not available in -current as well.
Relevant ofwdump of the codec mixer:
---------------------------------------------------------------------
ff98cdd8: /pci@f2000000/mac-io@17/i2c@18000/i2c-bus@0/codec@6a
name 636f6465 6300.... ........ ........ "codec"
device_type 636f6465 6300.... ........ ........ "codec"
compatible 74617333 30303400 ........ ........ "tas3004
"
0008: 636f6465 6300.... ........ ........ "codec"
000e: 00...... ........ ........ ........ ""
reg 0000006a ........ ........ ........ ...j
built-in
platform-do-tas-codec-ref
ff985200 08000000 00000027 ........ ..R.....
...'
----------------------------------------------------------------------
Relevant ofwdump of the soundbus:
---------------------------------------------------------------------
ff985040: /pci@f2000000/mac-io@17/i2s@0/i2s-a@10000
name 6932732d 6100.... ........ ........ "i2s-a"
device_type 736f756e 64627573 00...... ........ "soundbu
s"
compatible 69327362 757300.. ........ ........ "i2sbus"
built-in
reg 00010000 00001000 00008000 00000100 ........
........
0010: 00008100 00000100 ........ ........ ........
interrupts 0000001e 00000001 00000001 00000000 ........
........
0010: 00000002 00000000 ........ ........ ........
interrupt-parent ff9810d8 ........ ........ ........ ....
platform-headphone-mute ff981f40 ........ ........ ........ ...@
platform-amp-mute ff982098 ........ ........ ........ .. .
platform-hw-reset ff9821e8 ........ ........ ........ ..!.
platform-headphone-detect
ff982338 ........ ........ ........ ..#8
platform-get-enable ff97fc48 ........ ........ ........ ...H
platform-enable ff97fc48 ........ ........ ........ ...H
platform-disable ff97fc48 ........ ........ ........ ...H
platform-get-clock-enable
ff97fc48 ........ ........ ........ ...H
platform-clock-enable ff97fc48 ........ ........ ........ ...H
platform-clock-disable ff97fc48 ........ ........ ........ ...H
platform-get-sw-reset ff97fc48 ........ ........ ........ ...H
platform-clear-sw-reset ff97fc48 ........ ........ ........ ...H
platform-sw-reset ff97fc48 ........ ........ ........ ...H
platform-get-cell-enable
ff97fc48 ........ ........ ........ ...H
platform-cell-enable ff97fc48 ........ ........ ........ ...H
platform-cell-disable ff97fc48 ........ ........ ........ ...H
----------------------------------------------------------------------
>How-To-Repeat:
Install netbsd/macppc ( any version will do ) on a 14.1" ibook g4 which has the appropriate "codec" mixer.
>Fix:
However they still contain the tas3004 chip and can be made to work with the snapper driver very well.
On these ibooks, the following changes need to be made to get the snappper driver working correctly.
- changes to the DEQ mixer , deq.c to also attach to "codec" devices
- Get snapper to use the reg, idma and odma registers from the soundbus.
- amp mute, headphone mute and headphone detect gpio regs should be read from the soundbus's registers "platform-amp-mute" , "platform-headphone-mute" and "platform-headphone-detect" respectively.
The following patch applies on NetBSD 4.0. However, this needs to be adapted to -current as well.
This patch( the snapper.c part of it) is adapted from OpenBSD's snapper driver code. Reference: http://fxr.watson.org/fxr/source/arch/macppc/dev/snapper.c?v=OPENBSD
The Patch:
Index: dev/snapper.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/snapper.c,v
retrieving revision 1.13
diff -b -u -r1.13 snapper.c
--- dev/snapper.c 24 Sep 2006 03:47:09 -0000 1.13
+++ dev/snapper.c 14 Jun 2008 04:34:30 -0000
@@ -88,6 +88,8 @@
unsigned char dbdma_cmdspace[sizeof(struct dbdma_command) * 40 + 15];
struct dbdma_command *sc_odmacmd;
struct dbdma_command *sc_idmacmd;
+ u_int sc_baseaddr; /* needed for snapper_gpio */
+
};
int snapper_match(struct device *, struct cfdata *, void *);
@@ -125,6 +127,7 @@
void snapper_mute_headphone(struct snapper_softc *, int);
int snapper_cint(void *);
int tas3004_init(struct snapper_softc *);
+u_char *snapper_gpio_map(struct snapper_softc *,const char *, int *);
void snapper_init(struct snapper_softc *, int);
struct cfattach snapper_ca = {
@@ -548,7 +551,7 @@
struct confargs *ca;
unsigned long v;
int cirq, oirq, iirq, cirq_type, oirq_type, iirq_type;
- int soundbus, intr[6];
+ int soundbus, intr[6], reg[6];
sc = (struct snapper_softc *)self;
ca = aux;
@@ -564,16 +567,17 @@
}
#endif
- ca->ca_reg[0] += ca->ca_baseaddr;
- ca->ca_reg[2] += ca->ca_baseaddr;
- ca->ca_reg[4] += ca->ca_baseaddr;
-
sc->sc_node = ca->ca_node;
- sc->sc_reg = (void *)ca->ca_reg[0];
- 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, "reg", reg, sizeof reg);
+ reg[0] += ca->ca_baseaddr;
+ reg[2] += ca->ca_baseaddr;
+ reg[4] += ca->ca_baseaddr;
+ sc->sc_reg = (void *)reg[0];
+ sc->sc_odma = (void *)reg[2];
+ sc->sc_idma = (void *)reg[4];
+ sc->sc_baseaddr = ca->ca_baseaddr; /* needed for snapper_gpio_map */
+
OF_getprop(soundbus, "interrupts", intr, sizeof intr);
cirq = intr[0];
oirq = intr[2];
@@ -606,7 +610,8 @@
sc->sc_i2c = dv;
*/
for (dv = alldevs.tqh_first; dv; dv=dv->dv_list.tqe_next)
- if (strncmp(dv->dv_xname, "deq", 3) == 0 &&
+ if (((strncmp(dv->dv_xname, "deq", 3) == 0) ||
+ (strncmp(dv->dv_xname, "codec", 5) == 0)) &&
strncmp(device_parent(dv)->dv_xname, "ki2c", 4) == 0) {
deq=(struct deq_softc *)dv;
sc->sc_i2c = deq->sc_i2c;
@@ -1673,6 +1678,35 @@
#define I2S1EN 0x100000
#define FCR3C_BITMASK "\020\25I2S1EN\24I2S1CLKEN\16I2S0EN\15I2S0CLKEN"
+ /* snapper_gpio_map tries to obtain and map the gpio registers from
+ the soundbus */
+u_char *
+snapper_gpio_map(struct snapper_softc *sc, const char *name, int *irq)
+{
+
+ u_int32_t reg[2];
+ u_int32_t intr[2];
+ int gpio;
+ int soundbus;
+
+
+ if((soundbus = OF_child(sc->sc_node)) == 0)
+ return NULL;
+
+ if (OF_getprop(soundbus, name, &gpio,
+ sizeof(gpio)) != sizeof(gpio) ||
+ OF_getprop(gpio, "reg", ®[0],
+ sizeof(reg[0])) != sizeof(reg[0]) ||
+ OF_getprop(OF_parent(gpio), "reg", ®[1],
+ sizeof(reg[1])) != sizeof(reg[1]))
+ return NULL;
+
+ if (irq && OF_getprop(gpio, "interrupts",
+ intr, sizeof(intr)) == sizeof(intr)) {
+ *irq = intr[0];
+ }
+ return mapiodev(sc->sc_baseaddr + reg[0] + reg[1], 1);
+}
void
snapper_init(struct snapper_softc *sc, int node)
@@ -1690,6 +1724,15 @@
gpio = getnodebyname(OF_parent(node), "gpio");
DPRINTF(" /gpio 0x%x\n", gpio);
gpio = OF_child(gpio);
+ /* Check if we can use the soundbus's 2nd reg for our purpose */
+ amp_mute = snapper_gpio_map(sc, "platform-amp-mute", NULL);
+ headphone_mute = snapper_gpio_map(sc, "platform-headphone-mute", NULL);
+ headphone_detect = snapper_gpio_map(sc, "platform-headphone-detect",
+ &headphone_detect_intr);
+ /* lineout_mute = snapper_gpio_map(sc, "platform-lineout-mute", NULL);
+ lineout_detect = snapper_gpio_map(sc, "platform-lineout-detect",
+ &lineout_detect_intr); */
+ audio_hw_reset = snapper_gpio_map(sc, "platform-hw-reset", NULL);
while (gpio) {
char name[64], audio_gpio[64];
int intr[2];
@@ -1704,13 +1747,13 @@
DPRINTF(" 0x%x %s %s\n", gpio, name, audio_gpio);
/* gpio5 */
- if (strcmp(audio_gpio, "headphone-mute") == 0)
+ if (headphone_mute != NULL && strcmp(audio_gpio, "headphone-mute") == 0)
headphone_mute = addr;
/* gpio6 */
- if (strcmp(audio_gpio, "amp-mute") == 0)
+ if (amp_mute != NULL && strcmp(audio_gpio, "amp-mute") == 0)
amp_mute = addr;
/* extint-gpio15 */
- if (strcmp(audio_gpio, "headphone-detect") == 0) {
+ if (headphone_detect != NULL && strcmp(audio_gpio, "headphone-detect") == 0) {
headphone_detect = addr;
OF_getprop(gpio, "audio-gpio-active-state",
&headphone_detect_active, 4);
@@ -1719,7 +1762,7 @@
headphone_detect_intrtype = intr[1];
}
/* gpio11 (keywest-11) */
- if (strcmp(audio_gpio, "audio-hw-reset") == 0)
+ if (audio_hw_reset != NULL && strcmp(audio_gpio, "audio-hw-reset") == 0)
audio_hw_reset = addr;
gpio = OF_peer(gpio);
}
Index: dev/deq.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/deq.c,v
retrieving revision 1.2
diff -b -u -r1.2 deq.c
--- dev/deq.c 11 Dec 2005 12:18:03 -0000 1.2
+++ dev/deq.c 14 Jun 2008 04:34:30 -0000
@@ -64,11 +64,11 @@
struct ki2c_confargs *ka = aux;
char compat[32];
- if (strcmp(ka->ka_name, "deq") != 0)
+ if ((strcmp(ka->ka_name, "deq") != 0) && (strcmp(ka->ka_name,"codec")!= 0))
return 0;
memset(compat, 0, sizeof(compat));
- if(OF_getprop(ka->ka_node, "i2c-address", compat, sizeof(compat)))
+ if(OF_getprop(ka->ka_node, "i2c-address", compat,sizeof(compat)))
return 1;
return 0;
}
>Audit-Trail:
From: "Kailash Sethuraman" <hsaliak@gmail.com>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: port-macppc/38952: snapper audio does not work on 14.1" ibook ( Patch for netbsd-4 branch attached).
Date: Mon, 16 Jun 2008 00:57:25 +0800
The first patch filed along with the PR is incorrect and will break
existing behaviour.
What I think is the correct patch is attached here, for netbsd-4:
Index: dev/snapper.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/snapper.c,v
retrieving revision 1.13
diff -b -u -r1.13 snapper.c
--- dev/snapper.c 24 Sep 2006 03:47:09 -0000 1.13
+++ dev/snapper.c 14 Jun 2008 04:34:30 -0000
@@ -88,6 +88,8 @@
unsigned char dbdma_cmdspace[sizeof(struct dbdma_command) * 40 + 15];
struct dbdma_command *sc_odmacmd;
struct dbdma_command *sc_idmacmd;
+ u_int sc_baseaddr; /* needed for snapper_gpio */
+
};
int snapper_match(struct device *, struct cfdata *, void *);
@@ -125,6 +127,7 @@
void snapper_mute_headphone(struct snapper_softc *, int);
int snapper_cint(void *);
int tas3004_init(struct snapper_softc *);
+u_char *snapper_gpio_map(struct snapper_softc *,const char *, int *);
void snapper_init(struct snapper_softc *, int);
struct cfattach snapper_ca = {
@@ -548,7 +551,7 @@
struct confargs *ca;
unsigned long v;
int cirq, oirq, iirq, cirq_type, oirq_type, iirq_type;
- int soundbus, intr[6];
+ int soundbus, intr[6], reg[6];
sc = (struct snapper_softc *)self;
ca = aux;
@@ -564,16 +567,17 @@
}
#endif
- ca->ca_reg[0] += ca->ca_baseaddr;
- ca->ca_reg[2] += ca->ca_baseaddr;
- ca->ca_reg[4] += ca->ca_baseaddr;
-
sc->sc_node = ca->ca_node;
- sc->sc_reg = (void *)ca->ca_reg[0];
- 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, "reg", reg, sizeof reg);
+ reg[0] += ca->ca_baseaddr;
+ reg[2] += ca->ca_baseaddr;
+ reg[4] += ca->ca_baseaddr;
+ sc->sc_reg = (void *)reg[0];
+ sc->sc_odma = (void *)reg[2];
+ sc->sc_idma = (void *)reg[4];
+ sc->sc_baseaddr = ca->ca_baseaddr; /* needed for snapper_gpio_map */
+
OF_getprop(soundbus, "interrupts", intr, sizeof intr);
cirq = intr[0];
oirq = intr[2];
@@ -606,7 +610,8 @@
sc->sc_i2c = dv;
*/
for (dv = alldevs.tqh_first; dv; dv=dv->dv_list.tqe_next)
- if (strncmp(dv->dv_xname, "deq", 3) == 0 &&
+ if (((strncmp(dv->dv_xname, "deq", 3) == 0) ||
+ (strncmp(dv->dv_xname, "codec", 5) == 0)) &&
strncmp(device_parent(dv)->dv_xname, "ki2c", 4) == 0) {
deq=(struct deq_softc *)dv;
sc->sc_i2c = deq->sc_i2c;
@@ -1673,6 +1678,35 @@
#define I2S1EN 0x100000
#define FCR3C_BITMASK "\020\25I2S1EN\24I2S1CLKEN\16I2S0EN\15I2S0CLKEN"
+ /* snapper_gpio_map tries to obtain and map the gpio registers from
+ the soundbus */
+u_char *
+snapper_gpio_map(struct snapper_softc *sc, const char *name, int *irq)
+{
+
+ u_int32_t reg[2];
+ u_int32_t intr[2];
+ int gpio;
+ int soundbus;
+
+
+ if((soundbus = OF_child(sc->sc_node)) == 0)
+ return NULL;
+
+ if (OF_getprop(soundbus, name, &gpio,
+ sizeof(gpio)) != sizeof(gpio) ||
+ OF_getprop(gpio, "reg", ®[0],
+ sizeof(reg[0])) != sizeof(reg[0]) ||
+ OF_getprop(OF_parent(gpio), "reg", ®[1],
+ sizeof(reg[1])) != sizeof(reg[1]))
+ return NULL;
+
+ if (irq && OF_getprop(gpio, "interrupts",
+ intr, sizeof(intr)) == sizeof(intr)) {
+ *irq = intr[0];
+ }
+ return mapiodev(sc->sc_baseaddr + reg[0] + reg[1], 1);
+}
void
snapper_init(struct snapper_softc *sc, int node)
@@ -1690,6 +1724,15 @@
gpio = getnodebyname(OF_parent(node), "gpio");
DPRINTF(" /gpio 0x%x\n", gpio);
gpio = OF_child(gpio);
+ /* Check if we can use the soundbus's 2nd reg for our purpose */
+ amp_mute = snapper_gpio_map(sc, "platform-amp-mute", NULL);
+ headphone_mute = snapper_gpio_map(sc, "platform-headphone-mute", NULL);
+ headphone_detect = snapper_gpio_map(sc, "platform-headphone-detect",
+ &headphone_detect_intr);
+ /* lineout_mute = snapper_gpio_map(sc, "platform-lineout-mute", NULL);
+ lineout_detect = snapper_gpio_map(sc, "platform-lineout-detect",
+ &lineout_detect_intr); */
+ audio_hw_reset = snapper_gpio_map(sc, "platform-hw-reset", NULL);
while (gpio) {
char name[64], audio_gpio[64];
int intr[2];
@@ -1704,13 +1747,13 @@
DPRINTF(" 0x%x %s %s\n", gpio, name, audio_gpio);
/* gpio5 */
- if (strcmp(audio_gpio, "headphone-mute") == 0)
+ if (headphone_mute == NULL && strcmp(audio_gpio, "headphone-mute") == 0)
headphone_mute = addr;
/* gpio6 */
- if (strcmp(audio_gpio, "amp-mute") == 0)
+ if (amp_mute == NULL && strcmp(audio_gpio, "amp-mute") == 0)
amp_mute = addr;
/* extint-gpio15 */
- if (strcmp(audio_gpio, "headphone-detect") == 0) {
+ if (headphone_detect == NULL && strcmp(audio_gpio,
"headphone-detect") == 0) {
headphone_detect = addr;
OF_getprop(gpio, "audio-gpio-active-state",
&headphone_detect_active, 4);
@@ -1719,7 +1762,7 @@
headphone_detect_intrtype = intr[1];
}
/* gpio11 (keywest-11) */
- if (strcmp(audio_gpio, "audio-hw-reset") == 0)
+ if (audio_hw_reset == NULL && strcmp(audio_gpio, "audio-hw-reset") == 0)
audio_hw_reset = addr;
gpio = OF_peer(gpio);
}
Index: dev/deq.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/deq.c,v
retrieving revision 1.2
diff -b -u -r1.2 deq.c
--- dev/deq.c 11 Dec 2005 12:18:03 -0000 1.2
+++ dev/deq.c 14 Jun 2008 04:34:30 -0000
@@ -64,11 +64,11 @@
struct ki2c_confargs *ka = aux;
char compat[32];
- if (strcmp(ka->ka_name, "deq") != 0)
+ if ((strcmp(ka->ka_name, "deq") != 0) && (strcmp(ka->ka_name,"codec")!= 0))
return 0;
memset(compat, 0, sizeof(compat));
- if(OF_getprop(ka->ka_node, "i2c-address", compat, sizeof(compat)))
+ if(OF_getprop(ka->ka_node, "i2c-address", compat,sizeof(compat)))
return 1;
return 0;
}
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.