* We now mute internal speakers when using headphones. We don't distinguish between headphones and mic jacks though.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35088 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
fc844f7bfb
commit
e25dcf1a96
@ -286,8 +286,10 @@ struct hda_codec {
|
||||
uint32 responses[MAX_CODEC_RESPONSES];
|
||||
uint32 response_count;
|
||||
|
||||
sem_id unsol_response_sem;
|
||||
thread_id unsol_response_thread;
|
||||
uint32 unsol_responses[MAX_CODEC_UNSOL_RESPONSES];
|
||||
uint32 unsol_response_count;
|
||||
uint32 unsol_response_read, unsol_response_write;
|
||||
|
||||
hda_audio_group* audio_groups[HDA_MAX_AUDIO_GROUPS];
|
||||
uint32 num_audio_groups;
|
||||
|
@ -1092,6 +1092,39 @@ hda_codec_switch_init(hda_audio_group* audioGroup)
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
hda_codec_switch_handler(hda_codec* codec)
|
||||
{
|
||||
while (acquire_sem(codec->unsol_response_sem) == B_OK) {
|
||||
uint32 response = codec->unsol_responses[codec->unsol_response_read++];
|
||||
codec->unsol_response_read %= MAX_CODEC_UNSOL_RESPONSES;
|
||||
|
||||
bool disable = response & 1;
|
||||
hda_audio_group* audioGroup = codec->audio_groups[0];
|
||||
|
||||
for (uint32 i = 0; i < audioGroup->widget_count; i++) {
|
||||
hda_widget& widget = audioGroup->widgets[i];
|
||||
|
||||
if (widget.type != WT_PIN_COMPLEX || !PIN_CAP_IS_OUTPUT(widget.d.pin.capabilities))
|
||||
continue;
|
||||
|
||||
int device = CONF_DEFAULT_DEVICE(widget.d.pin.config);
|
||||
if (device != PIN_DEV_SPEAKER
|
||||
&& device != PIN_DEV_LINE_OUT)
|
||||
continue;
|
||||
|
||||
uint32 ctrl = hda_widget_prepare_pin_ctrl(audioGroup, &widget,
|
||||
true);
|
||||
corb_t verb = MAKE_VERB(audioGroup->codec->addr, widget.node_id,
|
||||
VID_SET_PIN_WIDGET_CONTROL, disable ? 0 : ctrl);
|
||||
hda_send_verbs(audioGroup->codec, &verb, NULL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hda_codec_delete_audio_group(hda_audio_group* audioGroup)
|
||||
{
|
||||
@ -1313,6 +1346,10 @@ hda_codec_delete(hda_codec* codec)
|
||||
return;
|
||||
|
||||
delete_sem(codec->response_sem);
|
||||
delete_sem(codec->unsol_response_sem);
|
||||
|
||||
int32 result;
|
||||
wait_for_thread(codec->unsol_response_thread, &result);
|
||||
|
||||
for (uint32 i = 0; i < codec->num_audio_groups; i++) {
|
||||
hda_codec_delete_audio_group(codec->audio_groups[i]);
|
||||
@ -1338,9 +1375,28 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
|
||||
codec->controller = controller;
|
||||
codec->addr = codecAddress;
|
||||
codec->response_sem = create_sem(0, "hda_codec_response_sem");
|
||||
codec->unsol_response_count = 0;
|
||||
if (codec->response_sem < B_OK) {
|
||||
ERROR("hda: Failed to create semaphore\n");
|
||||
goto err;
|
||||
}
|
||||
controller->codecs[codecAddress] = codec;
|
||||
|
||||
codec->unsol_response_sem = create_sem(0, "hda_codec_unsol_response_sem");
|
||||
if (codec->unsol_response_sem < B_OK) {
|
||||
ERROR("hda: Failed to create semaphore\n");
|
||||
goto err;
|
||||
}
|
||||
codec->unsol_response_read = 0;
|
||||
codec->unsol_response_write = 0;
|
||||
codec->unsol_response_thread = spawn_kernel_thread(
|
||||
(status_t(*)(void*))hda_codec_switch_handler,
|
||||
"hda_codec_unsol_thread", B_LOW_PRIORITY, codec);
|
||||
if (codec->unsol_response_thread < B_OK) {
|
||||
ERROR("hda: Failed to spawn thread\n");
|
||||
goto err;
|
||||
}
|
||||
resume_thread(codec->unsol_response_thread);
|
||||
|
||||
struct {
|
||||
uint32 device : 16;
|
||||
uint32 vendor : 16;
|
||||
@ -1401,7 +1457,6 @@ hda_codec_new(hda_controller* controller, uint32 codecAddress)
|
||||
}
|
||||
|
||||
return codec;
|
||||
|
||||
err:
|
||||
controller->codecs[codecAddress] = NULL;
|
||||
hda_codec_delete(codec);
|
||||
|
@ -211,14 +211,12 @@ hda_interrupt_handler(hda_controller* controller)
|
||||
if ((responseFlags & RESPONSE_FLAGS_UNSOLICITED) != 0) {
|
||||
dprintf("hda: Unsolicited response: %08lx/%08lx\n",
|
||||
response, responseFlags);
|
||||
if (codec->unsol_response_count >= MAX_CODEC_UNSOL_RESPONSES) {
|
||||
dprintf("hda: too many unsol responses received"
|
||||
" for codec %ld: %08lx/%08lx!\n",
|
||||
cad, response, responseFlags);
|
||||
continue;
|
||||
}
|
||||
codec->unsol_responses[codec->unsol_response_count++] =
|
||||
codec->unsol_responses[codec->unsol_response_write++] =
|
||||
response;
|
||||
codec->unsol_response_write %= MAX_CODEC_UNSOL_RESPONSES;
|
||||
release_sem_etc(codec->unsol_response_sem, 1,
|
||||
B_DO_NOT_RESCHEDULE);
|
||||
handled = B_INVOKE_SCHEDULER;
|
||||
continue;
|
||||
}
|
||||
if (codec->response_count >= MAX_CODEC_RESPONSES) {
|
||||
|
Loading…
Reference in New Issue
Block a user