diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-08-08 11:12:52 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-08-08 11:12:52 -0400 |
commit | ed36081350d2ca4f692f04c6a2d24d1e3a339da1 (patch) | |
tree | dcfebceb1319315ec78be8567d8fbb27e1345b01 /sound | |
parent | 012e7eb1e501d0120e0383b81477f63091f5e365 (diff) |
ALSA: hda - Add codec->pcm_format_first flag
Introduced a new flag to set up the PCM stream format at first before
the stream_id and channel tag. Some codecs (e.g. CA0132) seem
preferring this over stream_id -> format order.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 69 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 1 |
2 files changed, 46 insertions, 24 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 88a9c20eb7a2..598b9e2d85e6 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1386,6 +1386,44 @@ int snd_hda_codec_configure(struct hda_codec *codec) | |||
1386 | } | 1386 | } |
1387 | EXPORT_SYMBOL_HDA(snd_hda_codec_configure); | 1387 | EXPORT_SYMBOL_HDA(snd_hda_codec_configure); |
1388 | 1388 | ||
1389 | /* update the stream-id if changed */ | ||
1390 | static void update_pcm_stream_id(struct hda_codec *codec, | ||
1391 | struct hda_cvt_setup *p, hda_nid_t nid, | ||
1392 | u32 stream_tag, int channel_id) | ||
1393 | { | ||
1394 | unsigned int oldval, newval; | ||
1395 | |||
1396 | if (p->stream_tag != stream_tag || p->channel_id != channel_id) { | ||
1397 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
1398 | newval = (stream_tag << 4) | channel_id; | ||
1399 | if (oldval != newval) | ||
1400 | snd_hda_codec_write(codec, nid, 0, | ||
1401 | AC_VERB_SET_CHANNEL_STREAMID, | ||
1402 | newval); | ||
1403 | p->stream_tag = stream_tag; | ||
1404 | p->channel_id = channel_id; | ||
1405 | } | ||
1406 | } | ||
1407 | |||
1408 | /* update the format-id if changed */ | ||
1409 | static void update_pcm_format(struct hda_codec *codec, struct hda_cvt_setup *p, | ||
1410 | hda_nid_t nid, int format) | ||
1411 | { | ||
1412 | unsigned int oldval; | ||
1413 | |||
1414 | if (p->format_id != format) { | ||
1415 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
1416 | AC_VERB_GET_STREAM_FORMAT, 0); | ||
1417 | if (oldval != format) { | ||
1418 | msleep(1); | ||
1419 | snd_hda_codec_write(codec, nid, 0, | ||
1420 | AC_VERB_SET_STREAM_FORMAT, | ||
1421 | format); | ||
1422 | } | ||
1423 | p->format_id = format; | ||
1424 | } | ||
1425 | } | ||
1426 | |||
1389 | /** | 1427 | /** |
1390 | * snd_hda_codec_setup_stream - set up the codec for streaming | 1428 | * snd_hda_codec_setup_stream - set up the codec for streaming |
1391 | * @codec: the CODEC to set up | 1429 | * @codec: the CODEC to set up |
@@ -1400,7 +1438,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1400 | { | 1438 | { |
1401 | struct hda_codec *c; | 1439 | struct hda_codec *c; |
1402 | struct hda_cvt_setup *p; | 1440 | struct hda_cvt_setup *p; |
1403 | unsigned int oldval, newval; | ||
1404 | int type; | 1441 | int type; |
1405 | int i; | 1442 | int i; |
1406 | 1443 | ||
@@ -1413,29 +1450,13 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1413 | p = get_hda_cvt_setup(codec, nid); | 1450 | p = get_hda_cvt_setup(codec, nid); |
1414 | if (!p) | 1451 | if (!p) |
1415 | return; | 1452 | return; |
1416 | /* update the stream-id if changed */ | 1453 | |
1417 | if (p->stream_tag != stream_tag || p->channel_id != channel_id) { | 1454 | if (codec->pcm_format_first) |
1418 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | 1455 | update_pcm_format(codec, p, nid, format); |
1419 | newval = (stream_tag << 4) | channel_id; | 1456 | update_pcm_stream_id(codec, p, nid, stream_tag, channel_id); |
1420 | if (oldval != newval) | 1457 | if (!codec->pcm_format_first) |
1421 | snd_hda_codec_write(codec, nid, 0, | 1458 | update_pcm_format(codec, p, nid, format); |
1422 | AC_VERB_SET_CHANNEL_STREAMID, | 1459 | |
1423 | newval); | ||
1424 | p->stream_tag = stream_tag; | ||
1425 | p->channel_id = channel_id; | ||
1426 | } | ||
1427 | /* update the format-id if changed */ | ||
1428 | if (p->format_id != format) { | ||
1429 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
1430 | AC_VERB_GET_STREAM_FORMAT, 0); | ||
1431 | if (oldval != format) { | ||
1432 | msleep(1); | ||
1433 | snd_hda_codec_write(codec, nid, 0, | ||
1434 | AC_VERB_SET_STREAM_FORMAT, | ||
1435 | format); | ||
1436 | } | ||
1437 | p->format_id = format; | ||
1438 | } | ||
1439 | p->active = 1; | 1460 | p->active = 1; |
1440 | p->dirty = 0; | 1461 | p->dirty = 0; |
1441 | 1462 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index c422d330ca54..7fbc1bcaf1a9 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -861,6 +861,7 @@ struct hda_codec { | |||
861 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 861 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
862 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | 862 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ |
863 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ | 863 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ |
864 | unsigned int pcm_format_first:1; /* PCM format must be set first */ | ||
864 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 865 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
865 | unsigned int power_on :1; /* current (global) power-state */ | 866 | unsigned int power_on :1; /* current (global) power-state */ |
866 | int power_transition; /* power-state in transition */ | 867 | int power_transition; /* power-state in transition */ |