NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-macppc/38952: snapper audio does not work on 14.1" ibook ( Patch for netbsd-4 branch attached).



>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
>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;
 }



Home | Main Index | Thread Index | Old Index