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", &reg[0],
+	    sizeof(reg[0])) != sizeof(reg[0]) ||
+	    OF_getprop(OF_parent(gpio), "reg", &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", &reg[0],
 +	    sizeof(reg[0])) != sizeof(reg[0]) ||
 +	    OF_getprop(OF_parent(gpio), "reg", &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;
  }

NetBSD Home
NetBSD PR Database Search

(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.