aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-02-06 08:03:20 -0500
committerTakashi Iwai <tiwai@suse.de>2008-04-24 06:00:07 -0400
commit7ba72ba1fe891a94b1e9d506236507e4dc50e872 (patch)
tree4c3dc43b6fbb1e9a3f28191a38da563e15180e44 /sound/pci/hda/hda_intel.c
parent6c4cc3a8ed15aacc06a5fd369639fef633cee2bc (diff)
[ALSA] hda-intel - Fix PCM device number assignment
In the current scheme, PCM device numbers are assigned incrementally in the order of codecs. This causes problems when the codec number is irregular, e.g. codec #0 for HDMI and codec #1 for analog. Then the HDMI becomes the first PCM, which is picked up as the default output device. Unfortuantely this doesn't work well with normal setups. This patch introduced the fixed device numbers for the PCM types, namely, analog, SPDIF, HDMI and modem. The PCM devices are assigned according to the corresponding PCM type. After this patch, HDMI will be always assigned to PCM #3, SPDIF to PCM #1, and the first analog to PCM #0, etc. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r--sound/pci/hda/hda_intel.c89
1 files changed, 47 insertions, 42 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 4be36c84b36c..18475de074b2 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -211,9 +211,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
211/* max buffer size - no h/w limit, you can increase as you like */ 211/* max buffer size - no h/w limit, you can increase as you like */
212#define AZX_MAX_BUF_SIZE (1024*1024*1024) 212#define AZX_MAX_BUF_SIZE (1024*1024*1024)
213/* max number of PCM devics per card */ 213/* max number of PCM devics per card */
214#define AZX_MAX_AUDIO_PCMS 6 214#define AZX_MAX_PCMS 8
215#define AZX_MAX_MODEM_PCMS 2
216#define AZX_MAX_PCMS (AZX_MAX_AUDIO_PCMS + AZX_MAX_MODEM_PCMS)
217 215
218/* RIRB int mask: overrun[2], response[0] */ 216/* RIRB int mask: overrun[2], response[0] */
219#define RIRB_INT_RESPONSE 0x01 217#define RIRB_INT_RESPONSE 0x01
@@ -350,7 +348,6 @@ struct azx {
350 struct azx_dev *azx_dev; 348 struct azx_dev *azx_dev;
351 349
352 /* PCM */ 350 /* PCM */
353 unsigned int pcm_devs;
354 struct snd_pcm *pcm[AZX_MAX_PCMS]; 351 struct snd_pcm *pcm[AZX_MAX_PCMS];
355 352
356 /* HD codec */ 353 /* HD codec */
@@ -1386,7 +1383,7 @@ static void azx_pcm_free(struct snd_pcm *pcm)
1386} 1383}
1387 1384
1388static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, 1385static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
1389 struct hda_pcm *cpcm, int pcm_dev) 1386 struct hda_pcm *cpcm)
1390{ 1387{
1391 int err; 1388 int err;
1392 struct snd_pcm *pcm; 1389 struct snd_pcm *pcm;
@@ -1400,7 +1397,7 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
1400 1397
1401 snd_assert(cpcm->name, return -EINVAL); 1398 snd_assert(cpcm->name, return -EINVAL);
1402 1399
1403 err = snd_pcm_new(chip->card, cpcm->name, pcm_dev, 1400 err = snd_pcm_new(chip->card, cpcm->name, cpcm->device,
1404 cpcm->stream[0].substreams, 1401 cpcm->stream[0].substreams,
1405 cpcm->stream[1].substreams, 1402 cpcm->stream[1].substreams,
1406 &pcm); 1403 &pcm);
@@ -1423,59 +1420,67 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
1423 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1420 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1424 snd_dma_pci_data(chip->pci), 1421 snd_dma_pci_data(chip->pci),
1425 1024 * 64, 1024 * 1024); 1422 1024 * 64, 1024 * 1024);
1426 chip->pcm[pcm_dev] = pcm; 1423 chip->pcm[cpcm->device] = pcm;
1427 if (chip->pcm_devs < pcm_dev + 1)
1428 chip->pcm_devs = pcm_dev + 1;
1429
1430 return 0; 1424 return 0;
1431} 1425}
1432 1426
1433static int __devinit azx_pcm_create(struct azx *chip) 1427static int __devinit azx_pcm_create(struct azx *chip)
1434{ 1428{
1429 static const char *dev_name[HDA_PCM_NTYPES] = {
1430 "Audio", "SPDIF", "HDMI", "Modem"
1431 };
1432 /* starting device index for each PCM type */
1433 static int dev_idx[HDA_PCM_NTYPES] = {
1434 [HDA_PCM_TYPE_AUDIO] = 0,
1435 [HDA_PCM_TYPE_SPDIF] = 1,
1436 [HDA_PCM_TYPE_HDMI] = 3,
1437 [HDA_PCM_TYPE_MODEM] = 6
1438 };
1439 /* normal audio device indices; not linear to keep compatibility */
1440 static int audio_idx[4] = { 0, 2, 4, 5 };
1435 struct hda_codec *codec; 1441 struct hda_codec *codec;
1436 int c, err; 1442 int c, err;
1437 int pcm_dev; 1443 int num_devs[HDA_PCM_NTYPES];
1438 1444
1439 err = snd_hda_build_pcms(chip->bus); 1445 err = snd_hda_build_pcms(chip->bus);
1440 if (err < 0) 1446 if (err < 0)
1441 return err; 1447 return err;
1442 1448
1443 /* create audio PCMs */ 1449 /* create audio PCMs */
1444 pcm_dev = 0; 1450 memset(num_devs, 0, sizeof(num_devs));
1445 list_for_each_entry(codec, &chip->bus->codec_list, list) {
1446 for (c = 0; c < codec->num_pcms; c++) {
1447 if (codec->pcm_info[c].is_modem)
1448 continue; /* create later */
1449 if (pcm_dev >= AZX_MAX_AUDIO_PCMS) {
1450 snd_printk(KERN_ERR SFX
1451 "Too many audio PCMs\n");
1452 return -EINVAL;
1453 }
1454 err = create_codec_pcm(chip, codec,
1455 &codec->pcm_info[c], pcm_dev);
1456 if (err < 0)
1457 return err;
1458 pcm_dev++;
1459 }
1460 }
1461
1462 /* create modem PCMs */
1463 pcm_dev = AZX_MAX_AUDIO_PCMS;
1464 list_for_each_entry(codec, &chip->bus->codec_list, list) { 1451 list_for_each_entry(codec, &chip->bus->codec_list, list) {
1465 for (c = 0; c < codec->num_pcms; c++) { 1452 for (c = 0; c < codec->num_pcms; c++) {
1466 if (!codec->pcm_info[c].is_modem) 1453 struct hda_pcm *cpcm = &codec->pcm_info[c];
1467 continue; /* already created */ 1454 int type = cpcm->pcm_type;
1468 if (pcm_dev >= AZX_MAX_PCMS) { 1455 switch (type) {
1469 snd_printk(KERN_ERR SFX 1456 case HDA_PCM_TYPE_AUDIO:
1470 "Too many modem PCMs\n"); 1457 if (num_devs[type] >= ARRAY_SIZE(audio_idx)) {
1471 return -EINVAL; 1458 snd_printk(KERN_WARNING
1459 "Too many audio devices\n");
1460 continue;
1461 }
1462 cpcm->device = audio_idx[num_devs[type]];
1463 break;
1464 case HDA_PCM_TYPE_SPDIF:
1465 case HDA_PCM_TYPE_HDMI:
1466 case HDA_PCM_TYPE_MODEM:
1467 if (num_devs[type]) {
1468 snd_printk(KERN_WARNING
1469 "%s already defined\n",
1470 dev_name[type]);
1471 continue;
1472 }
1473 cpcm->device = dev_idx[type];
1474 break;
1475 default:
1476 snd_printk(KERN_WARNING
1477 "Invalid PCM type %d\n", type);
1478 continue;
1472 } 1479 }
1473 err = create_codec_pcm(chip, codec, 1480 num_devs[type]++;
1474 &codec->pcm_info[c], pcm_dev); 1481 err = create_codec_pcm(chip, codec, cpcm);
1475 if (err < 0) 1482 if (err < 0)
1476 return err; 1483 return err;
1477 chip->pcm[pcm_dev]->dev_class = SNDRV_PCM_CLASS_MODEM;
1478 pcm_dev++;
1479 } 1484 }
1480 } 1485 }
1481 return 0; 1486 return 0;
@@ -1587,7 +1592,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1587 int i; 1592 int i;
1588 1593
1589 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 1594 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1590 for (i = 0; i < chip->pcm_devs; i++) 1595 for (i = 0; i < AZX_MAX_PCMS; i++)
1591 snd_pcm_suspend_all(chip->pcm[i]); 1596 snd_pcm_suspend_all(chip->pcm[i]);
1592 if (chip->initialized) 1597 if (chip->initialized)
1593 snd_hda_suspend(chip->bus, state); 1598 snd_hda_suspend(chip->bus, state);