summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2002-10-14 11:47:37 +0000
committercognet <cognet@FreeBSD.org>2002-10-14 11:47:37 +0000
commit6fa5a2e2481f675cfc3b6521caeaa62d6a5383cb (patch)
tree544ccc50f18c1d364d16c1f408a23c66164d25db /sys/dev/sound
parentab7f45635732a8e996bfe4082080f3bd002325bf (diff)
downloadFreeBSD-src-6fa5a2e2481f675cfc3b6521caeaa62d6a5383cb.zip
FreeBSD-src-6fa5a2e2481f675cfc3b6521caeaa62d6a5383cb.tar.gz
Fix support for the ALi M5451 (rev 0.2) chip.
Reviewed by: orion, mux Approved by: mux (mentor) MFC after: 1 week
Diffstat (limited to 'sys/dev/sound')
-rw-r--r--sys/dev/sound/pci/t4dwave.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c
index 1941303..e62f90e 100644
--- a/sys/dev/sound/pci/t4dwave.c
+++ b/sys/dev/sound/pci/t4dwave.c
@@ -71,6 +71,7 @@ struct tr_rchinfo {
/* device private data */
struct tr_info {
u_int32_t type;
+ u_int32_t rev;
bus_space_tag_t st;
bus_space_handle_t sh;
@@ -167,6 +168,12 @@ tr_rdcd(kobj_t obj, void *devinfo, int regno)
trw=SPA_CDC_RWSTAT;
break;
case ALI_PCI_ID:
+ if (tr->rev > 0x01)
+ treg=TDX_REG_CODECWR;
+ else
+ treg=TDX_REG_CODECRD;
+ trw=TDX_CDC_RWSTAT;
+ break;
case TDX_PCI_ID:
treg=TDX_REG_CODECRD;
trw=TDX_CDC_RWSTAT;
@@ -182,9 +189,25 @@ tr_rdcd(kobj_t obj, void *devinfo, int regno)
regno &= 0x7f;
snd_mtxlock(tr->lock);
- tr_wr(tr, treg, regno | trw, 4);
- j=trw;
- for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) j=tr_rd(tr, treg, 4);
+ if (tr->type == ALI_PCI_ID) {
+ u_int32_t chk1, chk2;
+ j = trw;
+ for (i = TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--)
+ j = tr_rd(tr, treg, 4);
+ if (i > 0) {
+ chk1 = tr_rd(tr, 0xc8, 4);
+ chk2 = tr_rd(tr, 0xc8, 4);
+ for (i = TR_TIMEOUT_CDC; (i > 0) && (chk1 == chk2);
+ i--)
+ chk2 = tr_rd(tr, 0xc8, 4);
+ }
+ }
+ if (tr->type != ALI_PCI_ID || i > 0) {
+ tr_wr(tr, treg, regno | trw, 4);
+ j=trw;
+ for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--)
+ j=tr_rd(tr, treg, 4);
+ }
snd_mtxunlock(tr->lock);
if (i == 0) printf("codec timeout during read of register %x\n", regno);
return (j >> TR_CDC_DATA) & 0xffff;
@@ -221,8 +244,26 @@ tr_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data)
#endif
j=trw;
snd_mtxlock(tr->lock);
- for (i=TR_TIMEOUT_CDC; (i>0) && (j & trw); i--) j=tr_rd(tr, treg, 4);
- tr_wr(tr, treg, (data << TR_CDC_DATA) | regno | trw, 4);
+ if (tr->type == ALI_PCI_ID) {
+ j = trw;
+ for (i = TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--)
+ j = tr_rd(tr, treg, 4);
+ if (i > 0) {
+ u_int32_t chk1, chk2;
+ chk1 = tr_rd(tr, 0xc8, 4);
+ chk2 = tr_rd(tr, 0xc8, 4);
+ for (i = TR_TIMEOUT_CDC; (i > 0) && (chk1 == chk2);
+ i--)
+ chk2 = tr_rd(tr, 0xc8, 4);
+ }
+ }
+ if (tr->type != ALI_PCI_ID || i > 0) {
+ for (i=TR_TIMEOUT_CDC; (i>0) && (j & trw); i--)
+ j=tr_rd(tr, treg, 4);
+ if (tr->type == ALI_PCI_ID && tr->rev > 0x01)
+ trw |= 0x0100;
+ tr_wr(tr, treg, (data << TR_CDC_DATA) | regno | trw, 4);
+ }
#if 0
printf(" - wrote %x, now %x\n", data, tr_rdcd(devinfo, regno));
#endif
@@ -765,6 +806,7 @@ tr_pci_attach(device_t dev)
}
tr->type = pci_get_devid(dev);
+ tr->rev = pci_get_revid(dev);
tr->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
data = pci_read_config(dev, PCIR_COMMAND, 2);
OpenPOWER on IntegriCloud