diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.h | 12 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 89 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_atihdmi.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_si3054.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 1 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 1 |
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 */ | ||
594 | enum { | ||
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 */ |
594 | struct hda_pcm { | 603 | struct 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 | ||
1388 | static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, | 1385 | static 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 | ||
1433 | static int __devinit azx_pcm_create(struct azx *chip) | 1427 | static 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); |