aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-08-08 11:12:52 -0400
committerTakashi Iwai <tiwai@suse.de>2012-08-08 11:12:52 -0400
commited36081350d2ca4f692f04c6a2d24d1e3a339da1 (patch)
treedcfebceb1319315ec78be8567d8fbb27e1345b01 /sound
parent012e7eb1e501d0120e0383b81477f63091f5e365 (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.c69
-rw-r--r--sound/pci/hda/hda_codec.h1
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}
1387EXPORT_SYMBOL_HDA(snd_hda_codec_configure); 1387EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
1388 1388
1389/* update the stream-id if changed */
1390static 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 */
1409static 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 */