aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.h12
-rw-r--r--sound/pci/hda/hda_intel.c89
-rw-r--r--sound/pci/hda/patch_analog.c1
-rw-r--r--sound/pci/hda/patch_atihdmi.c1
-rw-r--r--sound/pci/hda/patch_cmedia.c1
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/pci/hda/patch_realtek.c1
-rw-r--r--sound/pci/hda/patch_si3054.c2
-rw-r--r--sound/pci/hda/patch_sigmatel.c1
-rw-r--r--sound/pci/hda/patch_via.c1
10 files changed, 66 insertions, 44 deletions
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index f14871151be9..301b5227bfb1 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -590,11 +590,21 @@ struct hda_pcm_stream {
590 struct hda_pcm_ops ops; 590 struct hda_pcm_ops ops;
591}; 591};
592 592
593/* PCM types */
594enum {
595 HDA_PCM_TYPE_AUDIO,
596 HDA_PCM_TYPE_SPDIF,
597 HDA_PCM_TYPE_HDMI,
598 HDA_PCM_TYPE_MODEM,
599 HDA_PCM_NTYPES
600};
601
593/* for PCM creation */ 602/* for PCM creation */
594struct hda_pcm { 603struct hda_pcm {
595 char *name; 604 char *name;
596 struct hda_pcm_stream stream[2]; 605 struct hda_pcm_stream stream[2];
597 unsigned int is_modem; /* modem codec? */ 606 unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */
607 int device; /* assigned device number */
598}; 608};
599 609
600/* codec information */ 610/* codec information */
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);
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index c8649282c2cf..7286ab86ecc4 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -359,6 +359,7 @@ static int ad198x_build_pcms(struct hda_codec *codec)
359 info++; 359 info++;
360 codec->num_pcms++; 360 codec->num_pcms++;
361 info->name = "AD198x Digital"; 361 info->name = "AD198x Digital";
362 info->pcm_type = HDA_PCM_TYPE_SPDIF;
362 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; 363 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
363 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 364 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
364 if (spec->dig_in_nid) { 365 if (spec->dig_in_nid) {
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index 27d2e007404b..e0e9ea995684 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -116,6 +116,7 @@ static int atihdmi_build_pcms(struct hda_codec *codec)
116 codec->pcm_info = info; 116 codec->pcm_info = info;
117 117
118 info->name = "ATI HDMI"; 118 info->name = "ATI HDMI";
119 info->pcm_type = HDA_PCM_TYPE_HDMI;
119 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback; 120 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback;
120 121
121 return 0; 122 return 0;
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 3d6097ba1d68..99ce74b4e9fc 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -571,6 +571,7 @@ static int cmi9880_build_pcms(struct hda_codec *codec)
571 codec->num_pcms++; 571 codec->num_pcms++;
572 info++; 572 info++;
573 info->name = "CMI9880 Digital"; 573 info->name = "CMI9880 Digital";
574 info->pcm_type = HDA_PCM_TYPE_SPDIF;
574 if (spec->multiout.dig_out_nid) { 575 if (spec->multiout.dig_out_nid) {
575 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_digital_playback; 576 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cmi9880_pcm_digital_playback;
576 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 577 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 7206b30cbf94..bb915ede0ceb 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -284,6 +284,7 @@ static int conexant_build_pcms(struct hda_codec *codec)
284 info++; 284 info++;
285 codec->num_pcms++; 285 codec->num_pcms++;
286 info->name = "Conexant Digital"; 286 info->name = "Conexant Digital";
287 info->pcm_type = HDA_PCM_TYPE_SPDIF;
287 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 288 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
288 conexant_pcm_digital_playback; 289 conexant_pcm_digital_playback;
289 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 290 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 45e661e42c0b..85ea3f82de19 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2499,6 +2499,7 @@ static int alc_build_pcms(struct hda_codec *codec)
2499 codec->num_pcms = 2; 2499 codec->num_pcms = 2;
2500 info = spec->pcm_rec + 1; 2500 info = spec->pcm_rec + 1;
2501 info->name = spec->stream_name_digital; 2501 info->name = spec->stream_name_digital;
2502 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2502 if (spec->multiout.dig_out_nid && 2503 if (spec->multiout.dig_out_nid &&
2503 spec->stream_digital_playback) { 2504 spec->stream_digital_playback) {
2504 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 2505 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index d22f5a6b850f..598ee2119bbe 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -206,7 +206,7 @@ static int si3054_build_pcms(struct hda_codec *codec)
206 info->name = "Si3054 Modem"; 206 info->name = "Si3054 Modem";
207 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; 207 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm;
208 info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; 208 info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm;
209 info->is_modem = 1; 209 info->pcm_type = HDA_PCM_TYPE_MODEM;
210 return 0; 210 return 0;
211} 211}
212 212
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 4c3c4e6ce3d6..f693011d25a0 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1899,6 +1899,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
1899 codec->num_pcms++; 1899 codec->num_pcms++;
1900 info++; 1900 info++;
1901 info->name = "STAC92xx Digital"; 1901 info->name = "STAC92xx Digital";
1902 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1902 if (spec->multiout.dig_out_nid) { 1903 if (spec->multiout.dig_out_nid) {
1903 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; 1904 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
1904 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 1905 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 4e5dd4cf36f5..d9a5c6a2dd9f 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -523,6 +523,7 @@ static int via_build_pcms(struct hda_codec *codec)
523 codec->num_pcms++; 523 codec->num_pcms++;
524 info++; 524 info++;
525 info->name = spec->stream_name_digital; 525 info->name = spec->stream_name_digital;
526 info->pcm_type = HDA_PCM_TYPE_SPDIF;
526 if (spec->multiout.dig_out_nid) { 527 if (spec->multiout.dig_out_nid) {
527 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 528 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
528 *(spec->stream_digital_playback); 529 *(spec->stream_digital_playback);