Date: Thu, 4 Nov 2004 05:04:40 +0800 (MYT) From: Ariff Abdullah <skywizard@MyBSD.org.my> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/73498: No sound from CT4730 (EV1938) based soundcard Message-ID: <20041103210440.13CEB6CC24@tomoyo.MyBSD.org.my> Resent-Message-ID: <200411032110.iA3LAWHm052958@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 73498 >Category: kern >Synopsis: No sound from CT4730 (EV1938) based soundcard >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Nov 03 21:10:28 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Ariff Abdullah >Release: FreeBSD 5.3-STABLE >Organization: MyBSD >Environment: System: FreeBSD 5.3-STABLE/i386 >Description: Broken register programming on CT4730/EV1938 soundcard causing no sound at all, although detected. Possible race condition occur during power-up, causing it failed totally. >How-To-Repeat: Get CT4730/EV1938 (or perhaps any EV1938 based chipset), boot, play anything. >Fix: This patch not just tempering es137x.c, but also ac97.c. It's really need proper review and testing before can be considered *the proper way* to initialize mixer for any AC97 soundcards. --- sys/dev/sound/pci/es137x.c.orig Tue Oct 19 20:12:14 2004 +++ sys/dev/sound/pci/es137x.c Wed Oct 20 01:32:42 2004 @@ -503,6 +503,8 @@ es->num = 0; es->ctrl = 0; es->sctrl = 0; + if (devid == CT4730_PCI_ID) + es->ctrl |= (1 << 16); /* initialize the chips */ if ((devid == ES1371_PCI_ID && revid == ES1371REV_ES1373_8) || (devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) || @@ -557,7 +559,7 @@ es1371_wrcd(kobj_t obj, void *s, int addr, u_int32_t data) { int sl; - unsigned t, x; + unsigned t, x, orig; struct es_info *es = (struct es_info*)s; if (debug > 0) printf("wrcodec addr 0x%x data 0x%x\n", addr, data); @@ -567,14 +569,18 @@ break; sl = spltty(); /* save the current state for later */ - x = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE); + x = orig = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE); /* enable SRC state data in SRC mux */ bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, - (es1371_wait_src_ready(s) & - (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1))); + (x & + (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1)) | 0x00010000); + /* busy wait */ + for (t = 0; t < 0x1000; t++) + if ((bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00870000) == 0x00000000) + break; /* wait for a SAFE time to write addr/data and then do it, dammit */ for (t = 0; t < 0x1000; t++) - if ((bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00070000) == 0x00010000) + if ((bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00870000) == 0x00010000) break; if (debug > 2) @@ -591,7 +597,7 @@ if (debug > 2) printf("two b_s_w: 0x%lx 0x%x 0x%x\n", rman_get_start(es->reg), ES1371_REG_SMPRATE, x); - bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, x); + bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, orig); splx(sl); return 0; @@ -601,7 +607,7 @@ es1371_rdcd(kobj_t obj, void *s, int addr) { int sl; - unsigned t, x = 0; + unsigned t, x = 0, orig; struct es_info *es = (struct es_info *)s; if (debug > 0) printf("rdcodec addr 0x%x ... ", addr); @@ -614,22 +620,27 @@ sl = spltty(); /* save the current state for later */ - x = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE); + x = orig = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE); /* enable SRC state data in SRC mux */ bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, - (es1371_wait_src_ready(s) & - (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1))); + (x & + (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1)) | 0x00010000); + /* busy wait */ + for (t = 0; t < 0x1000; t++) + if ((x = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00870000) == 0x00000000) + break; /* wait for a SAFE time to write addr/data and then do it, dammit */ - for (t = 0; t < 0x5000; t++) - if ((x = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00070000) == 0x00010000) + for (t = 0; t < 0x1000; t++) + if ((x = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00870000) == 0x00010000) break; + if (debug > 0) printf("loop 2 t 0x%x x 0x%x ", t, x); bus_space_write_4(es->st, es->sh, ES1371_REG_CODEC, ((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD); /* restore SRC reg */ es1371_wait_src_ready(s); - bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, x); + bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, orig); splx(sl); --- sys/dev/sound/pcm/ac97.c.orig Tue Oct 19 23:36:34 2004 +++ sys/dev/sound/pcm/ac97.c Thu Oct 21 01:41:46 2004 @@ -610,13 +610,21 @@ for (i = 0; i < 32; i++) { k = codec->noext? codec->mix[i].enable : 1; if (k && (codec->mix[i].reg > 0)) { - old = ac97_rdcd(codec, codec->mix[i].reg); - ac97_wrcd(codec, codec->mix[i].reg, 0x3f); - j = ac97_rdcd(codec, codec->mix[i].reg); + j = old = ac97_rdcd(codec, codec->mix[i].reg); + if (!(j & 0x8000)) { + ac97_wrcd(codec, codec->mix[i].reg, j | 0x8000); + j = ac97_rdcd(codec, codec->mix[i].reg); + } + if ((j & 0x8000)) { + codec->mix[i].enable = 1; + codec->mix[i].bits = 6; + j = 0x8000 | 0x0020; + ac97_wrcd(codec, codec->mix[i].reg, j); + if (j != ac97_rdcd(codec, codec->mix[i].reg)) + codec->mix[i].bits = 5; + } else + codec->mix[i].enable = 0; ac97_wrcd(codec, codec->mix[i].reg, old); - codec->mix[i].enable = (j != 0 && j != old)? 1 : 0; - for (k = 1; j & (1 << k); k++); - codec->mix[i].bits = j? k - codec->mix[i].ofs : 0; } /* printf("mixch %d, en=%d, b=%d\n", i, codec->mix[i].enable, codec->mix[i].bits); */ } @@ -644,8 +652,16 @@ } } - if ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0) - device_printf(codec->dev, "ac97 codec reports dac not ready\n"); + i = 0; + while ((ac97_rdcd(codec, AC97_REG_POWER) & 2) == 0) { + if (++i == 100) { + device_printf(codec->dev, "ac97 codec reports dac not ready\n"); + break; + } + DELAY(1000); + } + if (bootverbose) + device_printf(codec->dev, "ac97 codec dac ready count: %d\n", i); snd_mtxunlock(codec->lock); return 0; } >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041103210440.13CEB6CC24>