HDA sound driver hack for Acer Aspire 1641
Maxime Guillaud
bsd-ports at mguillaud.net
Sat Jul 22 12:24:16 UTC 2006
After some tweaking of Andrea Bittau's code, I managed to get the sound
(output only) working on my Acer Aspire 1641 WLMi.
You can get the driver from
http://www.mguillaud.net/acer1641/FreeBSD/hdac.tgz
I also attach a diff against Andrea's original code, FYI.
Maxime
-------------- next part --------------
diff -ur hdac-20060608/hda_reg.h /usr/src/sys/dev/hdac/hda_reg.h
--- hdac-20060608/hda_reg.h Sun Jun 4 01:10:31 2006
+++ /usr/src/sys/dev/hdac/hda_reg.h Wed Jul 5 18:49:17 2006
@@ -1192,4 +1192,35 @@
(((param) & HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_MASK) >> \
HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_SHIFT)
+
+#define HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK 0x00000000f
+#define HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK 0x0000000f0
+#define HDA_CONFIG_DEFAULTCONF_MISC_MASK 0x000000f00
+#define HDA_CONFIG_DEFAULTCONF_COLOR_MASK 0x00000f000
+#define HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK 0x000f00000
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_MASK 0x000f00000
+#define HDA_CONFIG_DEFAULTCONF_LOCATION_MASK 0x03f000000
+#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK 0x0c0000000
+
+#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK (0<<30)
+#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE (1<<30)
+#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED (2<<30)
+#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_BOTH (3<<30)
+
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT (0<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER (1<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT (2<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_CD (3<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT (4<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT (5<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_LINE (6<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_HANDSET (7<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN (8<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_AUX (9<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN (10<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_TELEPHONY (11<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_IN (12<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_IN (13<<20)
+#define HDA_CONFIG_DEFAULTCONF_DEVICE_OTHER (15<<20)
+
#endif
diff -ur hdac-20060608/hdac.c /usr/src/sys/dev/hdac/hdac.c
--- hdac-20060608/hdac.c Mon Jun 5 21:15:12 2006
+++ /usr/src/sys/dev/hdac/hdac.c Sat Jul 15 12:02:49 2006
@@ -54,6 +54,7 @@
#define INTEL_VENDORID 0x8086
+#define INTEL_82801F 0x2668
#define INTEL_82801G 0x27d8
@@ -62,6 +63,8 @@
uint16_t vendor;
char *description;
} hdac_devices[] = {
+ { INTEL_82801F, INTEL_VENDORID,
+ "Intel 82801F High Definition Audio Controller" },
{ INTEL_82801G, INTEL_VENDORID,
"Intel 82801G High Definition Audio Controller" }
};
@@ -247,7 +250,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 +264,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--;
}
@@ -785,7 +789,8 @@
devinfo->revision_id = HDA_PARAM_REVISION_ID_REVISION_ID(revisionid);
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);
}
@@ -811,6 +816,40 @@
}
static void
+sorbo_print_conn(struct hdac_softc *sc, int cad, int nid)
+{
+ uint32_t rc,i,cll;
+ uint32_t l=0;
+ uint16_t payload;
+ char connection_list[1024];
+ char connection_string[256];
+
+ cll = hdac_command_sendone_internal(sc,
+ HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_CONN_LIST_LENGTH), cad);
+
+ snprintf(connection_list, 1024, "node %d: %d connections, list: ", nid, cll);
+ for (i=0;i<cll;i++)
+ {
+ if ((i % 4)==0)
+ l = hdac_command_sendone_internal(sc, HDA_CMD_GET_CONN_LIST_ENTRY(cad, nid, i), cad);
+
+ payload = (1 << 13) | i; /* left, input i*/
+ rc = hdac_command_sendone_internal(sc, HDA_CMD_GET_AMP_GAIN_MUTE(cad, nid, payload), cad);
+
+ snprintf(connection_string, 256, "input from node %d (input amp %d), ",(l>>8*(i%4)) & 0xff,rc);
+ strlcat(connection_list, connection_string, 1024);
+ }
+
+ payload = (1 << 15) | (1 << 13); /* left, output */
+ rc = hdac_command_sendone_internal(sc, HDA_CMD_GET_AMP_GAIN_MUTE(cad, nid, payload), cad);
+
+ snprintf(connection_string,256, "output amp %d\n",rc);
+ strlcat(connection_list, connection_string, 1024);
+ device_printf(sc->dev, connection_list);
+
+}
+
+static void
sorbo_conf_output(struct hdac_softc *sc, int cad, int nid)
{
uint32_t rc, sf, st;
@@ -830,7 +869,7 @@
st = hdac_command_sendone_internal(sc,
HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_SUPP_STREAM_FORMATS), cad);
- device_printf(sc->dev, "Cap %x sf %x st %x\n", rc, sf, st);
+ device_printf(sc->dev, "Output, Cap %x sf %x st %x\n", rc, sf, st);
rc = hdac_command_sendone_internal(sc,
HDA_CMD_GET_CONV_STREAM_CHAN(cad, nid), 0);
@@ -854,12 +893,25 @@
}
static void
-sorbo_set_amp(struct hdac_softc *sc, int cda, int ni, int amp)
+sorbo_set_amp(struct hdac_softc *sc, int cda, int ni, int left, int right)
{
- uint16_t pay = (1 << 15) | (3 << 12) | amp;
+ uint16_t pay = 0;
- hdac_command_sendone_internal(sc,
- HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, pay), cda);
+ if (left != right) {
+ pay = (1 << 15) | (1 << 13) | left;
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, pay), cda);
+
+ pay = (1 << 15) | (1 << 12) | right;
+
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, pay), cda);
+ } else {
+ pay = (1 << 15) | (3 << 12) | left;
+
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, pay), cda);
+ }
}
static void
@@ -871,6 +923,80 @@
uint32_t ct = 0;
uint32_t capa = 0;
uint32_t sense = 0;
+ char connection_type_string[32], device_string[32];
+ int defaultconf;
+
+ defaultconf=HDA_CMD_GET_CONFIGURATION_DEFAULT(cad, nid);
+ switch (defaultconf & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK)
+ {
+ case HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK:
+ strncpy(connection_type_string,"jack", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE:
+ strncpy(connection_type_string,"none", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED:
+ strncpy(connection_type_string,"fixed", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_BOTH:
+ strncpy(connection_type_string,"jack and fixed", 32);
+ break;
+ default:
+ strncpy(connection_type_string,"unknown", 32);
+ break;
+ }
+
+ switch (defaultconf & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK)
+ {
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT:
+ strncpy(device_string,"line out", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER:
+ strncpy(device_string,"speaker", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT:
+ strncpy(device_string,"headphones out", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_CD:
+ strncpy(device_string,"CD", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT:
+ strncpy(device_string,"SPDIF out", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT:
+ strncpy(device_string,"digital (other) out", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_LINE:
+ strncpy(device_string,"modem, line side", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_HANDSET:
+ strncpy(device_string,"modem, handset side", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN:
+ strncpy(device_string,"line in", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_AUX:
+ strncpy(device_string,"AUX", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN:
+ strncpy(device_string,"Mic in", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_TELEPHONY:
+ strncpy(device_string,"telephony", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_IN:
+ strncpy(device_string,"SPDIF in", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_IN:
+ strncpy(device_string,"digital (other) in", 32);
+ break;
+ case HDA_CONFIG_DEFAULTCONF_DEVICE_OTHER:
+ strncpy(device_string,"other", 32);
+ break;
+ default:
+ strncpy(device_string,"unknown", 32);
+ break;
+ }
rc = hdac_command_sendone_internal(sc,
HDA_CMD_GET_PARAMETER(cad, nid, HDA_PARAM_CONN_LIST_LENGTH), cad);
@@ -899,8 +1025,7 @@
sense = hdac_command_sendone_internal(sc,
HDA_CMD_GET_PIN_SENSE(cad, nid), cad);
- device_printf(sc->dev, "nid %d entries %x list %x cur %d ctr %x cap %x s %x\n",
- nid, rc, l, p, ct, capa, sense);
+ device_printf(sc->dev, "node %d: entries %x list %x cur %d ctr %x cap %x s %x, default connectivity: %s, device type: %s\n", nid, rc, l, p, ct, capa, sense,connection_type_string,device_string);
sorbo_get_amp(sc, cad, nid);
}
@@ -924,28 +1049,80 @@
static void
sorbo_print_widget(struct hdac_softc *sc, int codecid, int nodeid)
{
- uint32_t rc;
+ uint32_t rc,p;
int type;
+ char type_string[32];
rc = hdac_command_sendone_internal(sc,
- HDA_CMD_GET_PARAMETER(0, nodeid, HDA_PARAM_AUDIO_WIDGET_CAP), 0);
+ HDA_CMD_GET_PARAMETER(0, nodeid, HDA_PARAM_AUDIO_WIDGET_CAP), codecid);
type = HDA_PARAM_AUDIO_WIDGET_CAP_TYPE(rc);
- device_printf(sc->dev, "node %d type %x cap %x\n", nodeid, type, rc);
+ switch (type)
+ {
+ case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT:
+ strncpy(type_string,"audio output", 32);
+ break;
+ case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT:
+ strncpy(type_string,"audio input", 32);
+ break;
+ case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER:
+ strncpy(type_string,"audio mixer", 32);
+ break;
+ case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR:
+ strncpy(type_string,"audio selector", 32);
+ break;
+ case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX:
+ strncpy(type_string,"pin", 32);
+ break;
+ case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET:
+ strncpy(type_string,"power widget", 32);
+ break;
+ case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET:
+ strncpy(type_string,"volume widget", 32);
+ break;
+ case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET:
+ strncpy(type_string,"beep widget", 32);
+ break;
+ case HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VENDOR_WIDGET:
+ strncpy(type_string,"vendor widget", 32);
+ break;
+ default:
+ strncpy(type_string,"unknown type", 32);
+ break;
+ }
+
+
+ device_printf(sc->dev, "node %d: type %x (%s), cap %x,\n", nodeid, type, type_string,rc);
+
+ 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)
- sorbo_set_amp(sc, codecid, nodeid, 40);
+ if (0)
+ sorbo_set_amp(sc, codecid, nodeid, 40,40);
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);
}
- 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);
+ else if ((type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR) || (type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER))
+ sorbo_print_conn(sc, codecid, nodeid);
+ if (type == HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR)
+ {
+ p = hdac_command_sendone_internal(sc,
+ HDA_CMD_GET_CONN_SELECT_CONTROL(codecid, nodeid), codecid);
+ device_printf(sc->dev, "current connection: %x\n",p);
+ }
+
+
+
}
static void
@@ -955,19 +1132,21 @@
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);
@@ -1231,6 +1410,57 @@
}
static void
+sorbo_set_input_amp(struct hdac_softc *sc, int cda, int ni, int index, int mute, int left, int right)
+{
+ uint16_t payload = 0;
+
+ if (left != right) {
+ payload = (1 << 14) | (1 << 13) | (index << 8) | (mute<<7) | left;
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, payload), cda);
+
+ payload = (1 << 14) | (1 << 12) | (index << 8) | (mute<<7) | right;
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, payload), cda);
+ } else {
+ payload = (1 << 14) | (3 << 12) | (index << 8) | (mute<<7) | left;
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, payload), cda);
+ }
+
+}
+
+
+static void
+sorbo_set_output_amp(struct hdac_softc *sc, int cda, int ni, int mute, int left, int right)
+{
+ uint16_t payload = 0;
+
+ if (left != right) {
+ payload = (1 << 15) | (1 << 13) | (mute<<7) | left;
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, payload), cda);
+
+ payload = (1 << 15) | (1 << 12) | (mute<<7) | right;
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, payload), cda);
+ } else {
+ payload = (1 << 15) | (3 << 12) | (mute<<7) | left;
+ hdac_command_sendone_internal(sc,
+ HDA_CMD_SET_AMP_GAIN_MUTE(cda, ni, payload), cda);
+ }
+
+}
+
+
+static void
+sorbo_set_conn_select_control(struct hdac_softc *sc, int codecid, int nodeid, uint8_t index)
+{
+ hdac_command_sendone_internal(sc, HDA_CMD_SET_CONNECTION_SELECT_CONTROL(codecid, nodeid, index), codecid);
+}
+
+
+static void
hdac_attach2(void *arg)
{
struct hdac_softc *sc;
@@ -1248,15 +1478,71 @@
hdac_scan_codecs(sc);
- if (0)
+/* 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_conf_output(sc, 0, 2);
+
+ sorbo_set_amp(sc, 0, 2, 40,40);
+ sorbo_set_amp(sc, 0, 3, 40,40);
+ sorbo_set_amp(sc, 0, 4, 40,40);
+ sorbo_set_amp(sc, 0, 5, 40,40);
+ sorbo_set_amp(sc, 0, 6, 40,40);
+ sorbo_set_amp(sc, 0, 7, 40,40);
+ sorbo_set_amp(sc, 0, 8, 40,40);
+ sorbo_set_amp(sc, 0, 9, 40,40);
+ sorbo_set_amp(sc, 0, 10, 40,40);
+ sorbo_set_amp(sc, 0, 11, 40,40);
+ sorbo_set_amp(sc, 0, 12, 40,40);
+ sorbo_set_amp(sc, 0, 13, 40,40);
+ sorbo_set_amp(sc, 0, 14, 40,40);
+ sorbo_set_amp(sc, 0, 15, 40,40);
+ sorbo_set_amp(sc, 0, 16, 40,40);
+ sorbo_set_amp(sc, 0, 17, 40,40);
+ sorbo_set_amp(sc, 0, 18, 40,40);
+ sorbo_set_amp(sc, 0, 19, 40,40);
+ sorbo_set_amp(sc, 0, 20, 40,40);
+ sorbo_set_amp(sc, 0, 21, 40,40);
+ sorbo_set_amp(sc, 0, 22, 40,40);
+ sorbo_set_amp(sc, 0, 23, 40,40);
+ sorbo_set_amp(sc, 0, 24, 40,40);
+ sorbo_set_amp(sc, 0, 25, 40,40);
+ sorbo_set_amp(sc, 0, 26, 40,40);
+ sorbo_set_amp(sc, 0, 27, 40,40);
+
+
+ sorbo_set_input_amp(sc, 0, 8, 0, 0, 41,41);
+ sorbo_set_output_amp(sc, 0, 8, 0, 42,43);
+ sorbo_set_input_amp(sc, 0, 9, 0, 0, 43,44);
+ sorbo_set_output_amp(sc, 0, 9, 0, 45,45);
+ sorbo_set_conn_select_control(sc, 0, 11, 0); /* select input from mixer 8 */
+ sorbo_set_input_amp(sc, 0, 10, 0, 0, 45,45);
+ sorbo_set_output_amp(sc, 0, 10, 0, 46,46);
+ sorbo_set_input_amp(sc, 0, 11, 0, 0, 47,47);
+ sorbo_set_output_amp(sc, 0, 11, 0, 48,48);
+
+/* sorbo_set_amp(sc, 0, 8, 6); */
+
+
+ sorbo_print_widget(sc, 0, 2);
+ sorbo_print_widget(sc, 0, 8);
+ sorbo_print_widget(sc, 0, 9);
+ sorbo_print_widget(sc, 0, 10);
+ sorbo_print_widget(sc, 0, 11);
+ sorbo_print_widget(sc, 0, 13);
+ sorbo_print_widget(sc, 0, 16);
+ sorbo_print_widget(sc, 0, 17);
+ sorbo_print_widget(sc, 0, 18);
+
+ sorbo_print_widget(sc, 0, 20);
+
+
+
sorbo_alloc_bdl(sc, 256);
sorbo_enable_stream_interrupts(sc);
sc->lame = 1;
@@ -1583,7 +1869,7 @@
hdacmix_init(struct snd_mixer *m)
{
mix_setrecdevs(m, 0);
- mix_setdevs(m, SOUND_MASK_VOLUME);
+ mix_setdevs(m, SOUND_MASK_VOLUME | SOUND_MASK_PCM);
return 0;
}
@@ -1591,21 +1877,32 @@
static int
hdacmix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
{
- int vol = 0;
- int max = 63;
+ int left_vol = 0, right_vol = 0;
+ int max = ((1<<6) - 1);
struct hdac_softc *sc = mix_getdevinfo(m);
- vol = (left*63)/100;
-
- if (left == 100 || vol > max)
- vol = max;
-
-// printf("Vol = %d\n", vol);
- if (sc->lame)
- sorbo_set_amp(sc, 0, 5, vol);
+
+ left_vol = (left * max) / 100;
+ if ((left == 100) || (left_vol > max))
+ left_vol = max;
+
+ right_vol = (right * max) / 100;
+ if ((right == 100) || (right_vol > max))
+ right_vol = max;
+
+ if (sc->lame) {
+ switch(dev) {
+ case SOUND_MIXER_VOLUME:
+ sorbo_set_output_amp(sc, 0, 8, 0, left_vol, right_vol);
+ break;
+ case SOUND_MIXER_PCM:
+ sorbo_set_input_amp(sc, 0, 8, 0, 0, left_vol, right_vol);
+ break;
+ }
+ }
- vol = left | (left << 8);
+ left_vol = left | (right << 8);
- return vol;
+ return left_vol;
}
static int
More information about the freebsd-mobile
mailing list