HDA sound driver mod for sigmatel 92xx
Wesley Morgan <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.mobile,gmane.os.freebsd.devel.multimedia |
|---|---|
| Message-ID | <[email protected]> |
With a little help from the netbsd azalia driver (a wonderful piece of work, by the way) and the hda specs, I've been able to get Andrea's hdac code to work with my laptop. I believe the problem was that the codec and dac started out in some kind of low-power mode and needed to be woken up before they would work. Hopefully someone is still working on a proper driver, but for now, I can watch movies again! A diff against Andrea's work is attached. -- This .signature sanitized for your protection _______________________________________________ [email protected] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-mobile To unsubscribe, send any mail to "[email protected]"
sigma.diff
(text/plain, 4.1 KB)
diff -urb hdac/hdac.c hdac-sigma/hdac.c
--- hdac/hdac.c Mon Jun 5 15:15:12 2006
+++ hdac-sigma/hdac.c Sun Jul 9 10:10:37 2006
@@ -247,7 +247,8 @@
* Reset the controller. The reset must remain asserted for
* a minimum of 100us.
*/
- HDAC_WRITE_4(&sc->mem, HDAC_GCTL, 0x0);
+ gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL);
+ HDAC_WRITE_4(&sc->mem, HDAC_GCTL, gctl & ~ HDAC_GCTL_CRST);
count = 10000;
while (count) {
gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL);
@@ -260,11 +261,11 @@
return (ENXIO);
}
DELAY(100);
- HDAC_WRITE_4(&sc->mem, HDAC_GCTL, HDAC_GCTL_CRST);
+ gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL);
+ HDAC_WRITE_4(&sc->mem, HDAC_GCTL, gctl | HDAC_GCTL_CRST);
count = 10000;
while (count) {
- gctl = HDAC_READ_4(&sc->mem, HDAC_GCTL);
- if ((gctl & HDAC_GCTL_CRST) == HDAC_GCTL_CRST)
+ if (HDAC_READ_4(&sc->mem, HDAC_GCTL) & HDAC_GCTL_CRST)
break;
count--;
}
@@ -786,6 +787,10 @@
devinfo->stepping_id = HDA_PARAM_REVISION_ID_STEPPING_ID(revisionid);
devinfo->node_type = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE(fctgrptype);
+
+ device_printf(sc->dev, "Vendor info: %x %x %x %x %x %x\n", vendorid, devinfo->vendor_id, devinfo->device_id,
+ devinfo->revision_id, devinfo->stepping_id, devinfo->node_type);
+
hdac_add_child(sc, devinfo);
}
@@ -816,6 +821,10 @@
uint32_t rc, sf, st;
uint32_t fmt = sorbo_get_fmt(sc);
+
+ rc = HDA_CMD_GET_CONFIGURATION_DEFAULT(cad, nid);
+ device_printf(sc->dev, "Config %x\n", rc);
+
rc = hdac_command_sendone_internal(sc,
HDA_CMD_SET_CONV_STREAM_CHAN(cad, nid, 1 << 4), 0);
if (rc)
@@ -885,8 +894,10 @@
ct = hdac_command_sendone_internal(sc,
HDA_CMD_GET_PIN_WIDGET_CTRL(cad, nid), cad);
- ct |= (1 << 6) | (1 << 7);
- ct = hdac_command_sendone_internal(sc,
+
+ ct |= (1 << 6) | (1 << 2) | (1);
+
+ hdac_command_sendone_internal(sc,
HDA_CMD_SET_PIN_WIDGET_CTRL(cad, nid, ct), cad);
capa = hdac_command_sendone_internal(sc,
@@ -934,18 +945,26 @@
device_printf(sc->dev, "node %d type %x cap %x\n", nodeid, type, rc);
- if (0)
- sorbo_set_amp(sc, codecid, nodeid, 40);
+ if (HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL(rc)) {
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_POWER_STATE(codecid, nodeid, HDA_CMD_POWER_STATE_D0), codecid);
+ }
if (0 && HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET(rc)) {
sorbo_own_proc(sc, codecid, nodeid);
}
- if (0 && type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT) {
+ if (type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT) {
sorbo_conf_output(sc, codecid, nodeid);
+ device_printf(sc->dev, "sorbo_conf_output: codec: %d node: %d\n", codecid, nodeid);
+ }
+ else if (type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR) {
+ sorbo_set_amp(sc, codecid, nodeid, 40);
}
- else if (0 && type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX)
+ else if (type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX) {
sorbo_conf_pin(sc, codecid, nodeid);
+ sorbo_set_amp(sc, codecid, nodeid, 40);
+ }
}
static void
@@ -955,19 +974,22 @@
int startnode;
int endnode;
int i;
-// uint32_t pw;
+ uint32_t pw;
subnode = hdac_command_sendone_internal(sc,
HDA_CMD_GET_PARAMETER(0 , 1, HDA_PARAM_SUB_NODE_COUNT), 0);
+
startnode = HDA_PARAM_SUB_NODE_COUNT_START(subnode);
endnode = startnode + HDA_PARAM_SUB_NODE_COUNT_TOTAL(subnode);
-#if 0
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_POWER_STATE(0, 1, HDA_CMD_POWER_STATE_D0), 0);
+
pw = hdac_command_sendone_internal(sc,
HDA_CMD_GET_POWER_STATE(0, 1), 0);
device_printf(sc->dev, "PW %x\n", pw);
-#endif
+ device_printf(sc->dev, "start: %d endnode: %d\n", startnode, endnode);
for (i = startnode; i < endnode; i++) {
sorbo_print_widget(sc, 0, i);
@@ -1248,15 +1270,12 @@
hdac_scan_codecs(sc);
- if (0)
sorbo_enum(sc);
sorbo_stop_stream(sc);
sorbo_reset_stream(sc);
sorbo_stream_setid(sc);
- sorbo_conf_output(sc, 0, 3);
- sorbo_set_amp(sc, 0, 5, 40);
sorbo_alloc_bdl(sc, 256);
sorbo_enable_stream_interrupts(sc);
sc->lame = 1;
Only in hdac-sigma: hdac.c~