aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-11-24 08:31:46 -0500
committerTakashi Iwai <tiwai@suse.de>2011-11-26 04:19:44 -0500
commit01b65bfb4f8cd45b0d44547c961ef59a0bcf74be (patch)
treeb297e5611802e0734a263718f59434d3e436e6c9 /sound
parentb37c0096b448d099d304bb47c4eada9117dba4cf (diff)
ALSA: hda - Supports more audio streams
So far, the driver supports up to 10 streams. This is a restriction in hda_intel.c and hda_codec.c: in the former, the fixed array size limits the amount, and in the latter, the fixed device-number assignment table (in get_empty_pcm_device()) limits the possibility. This patch reduces the restriction by - using linked list for managing PCM instances in hda_intel.c, and - assigning non-fixed device numbers for the extra devices Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c6
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_intel.c48
3 files changed, 30 insertions, 27 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 4562e9de6a1a..4463f9a9619a 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -3850,6 +3850,12 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type)
3850 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) 3850 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
3851 return audio_idx[type][i]; 3851 return audio_idx[type][i];
3852 3852
3853 /* non-fixed slots starting from 10 */
3854 for (i = 10; i < 32; i++) {
3855 if (!test_and_set_bit(i, bus->pcm_dev_bits))
3856 return i;
3857 }
3858
3853 snd_printk(KERN_WARNING "Too many %s devices\n", 3859 snd_printk(KERN_WARNING "Too many %s devices\n",
3854 snd_hda_pcm_type_name[type]); 3860 snd_hda_pcm_type_name[type]);
3855 return -EAGAIN; 3861 return -EAGAIN;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 564471169cae..17cee4ee8e65 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -547,9 +547,6 @@ enum {
547/* max. codec address */ 547/* max. codec address */
548#define HDA_MAX_CODEC_ADDRESS 0x0f 548#define HDA_MAX_CODEC_ADDRESS 0x0f
549 549
550/* max number of PCM devics per card */
551#define HDA_MAX_PCMS 10
552
553/* 550/*
554 * generic arrays 551 * generic arrays
555 */ 552 */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 096507d2ca9a..ddd7f3b21cdc 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -407,6 +407,14 @@ struct azx_rb {
407 u32 res[AZX_MAX_CODECS]; /* last read value */ 407 u32 res[AZX_MAX_CODECS]; /* last read value */
408}; 408};
409 409
410struct azx_pcm {
411 struct azx *chip;
412 struct snd_pcm *pcm;
413 struct hda_codec *codec;
414 struct hda_pcm_stream *hinfo[2];
415 struct list_head list;
416};
417
410struct azx { 418struct azx {
411 struct snd_card *card; 419 struct snd_card *card;
412 struct pci_dev *pci; 420 struct pci_dev *pci;
@@ -434,7 +442,7 @@ struct azx {
434 struct azx_dev *azx_dev; 442 struct azx_dev *azx_dev;
435 443
436 /* PCM */ 444 /* PCM */
437 struct snd_pcm *pcm[HDA_MAX_PCMS]; 445 struct list_head pcm_list; /* azx_pcm list */
438 446
439 /* HD codec */ 447 /* HD codec */
440 unsigned short codec_mask; 448 unsigned short codec_mask;
@@ -1486,10 +1494,9 @@ static void azx_bus_reset(struct hda_bus *bus)
1486 azx_init_chip(chip, 1); 1494 azx_init_chip(chip, 1);
1487#ifdef CONFIG_PM 1495#ifdef CONFIG_PM
1488 if (chip->initialized) { 1496 if (chip->initialized) {
1489 int i; 1497 struct azx_pcm *p;
1490 1498 list_for_each_entry(p, &chip->pcm_list, list)
1491 for (i = 0; i < HDA_MAX_PCMS; i++) 1499 snd_pcm_suspend_all(p->pcm);
1492 snd_pcm_suspend_all(chip->pcm[i]);
1493 snd_hda_suspend(chip->bus); 1500 snd_hda_suspend(chip->bus);
1494 snd_hda_resume(chip->bus); 1501 snd_hda_resume(chip->bus);
1495 } 1502 }
@@ -1667,12 +1674,6 @@ static struct snd_pcm_hardware azx_pcm_hw = {
1667 .fifo_size = 0, 1674 .fifo_size = 0,
1668}; 1675};
1669 1676
1670struct azx_pcm {
1671 struct azx *chip;
1672 struct hda_codec *codec;
1673 struct hda_pcm_stream *hinfo[2];
1674};
1675
1676static int azx_pcm_open(struct snd_pcm_substream *substream) 1677static int azx_pcm_open(struct snd_pcm_substream *substream)
1677{ 1678{
1678 struct azx_pcm *apcm = snd_pcm_substream_chip(substream); 1679 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
@@ -2197,7 +2198,7 @@ static void azx_pcm_free(struct snd_pcm *pcm)
2197{ 2198{
2198 struct azx_pcm *apcm = pcm->private_data; 2199 struct azx_pcm *apcm = pcm->private_data;
2199 if (apcm) { 2200 if (apcm) {
2200 apcm->chip->pcm[pcm->device] = NULL; 2201 list_del(&apcm->list);
2201 kfree(apcm); 2202 kfree(apcm);
2202 } 2203 }
2203} 2204}
@@ -2215,14 +2216,11 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2215 unsigned int size; 2216 unsigned int size;
2216 int s, err; 2217 int s, err;
2217 2218
2218 if (pcm_dev >= HDA_MAX_PCMS) { 2219 list_for_each_entry(apcm, &chip->pcm_list, list) {
2219 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n", 2220 if (apcm->pcm->device == pcm_dev) {
2220 pcm_dev); 2221 snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
2221 return -EINVAL; 2222 return -EBUSY;
2222 } 2223 }
2223 if (chip->pcm[pcm_dev]) {
2224 snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
2225 return -EBUSY;
2226 } 2224 }
2227 err = snd_pcm_new(chip->card, cpcm->name, pcm_dev, 2225 err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
2228 cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams, 2226 cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams,
@@ -2235,12 +2233,13 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2235 if (apcm == NULL) 2233 if (apcm == NULL)
2236 return -ENOMEM; 2234 return -ENOMEM;
2237 apcm->chip = chip; 2235 apcm->chip = chip;
2236 apcm->pcm = pcm;
2238 apcm->codec = codec; 2237 apcm->codec = codec;
2239 pcm->private_data = apcm; 2238 pcm->private_data = apcm;
2240 pcm->private_free = azx_pcm_free; 2239 pcm->private_free = azx_pcm_free;
2241 if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) 2240 if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM)
2242 pcm->dev_class = SNDRV_PCM_CLASS_MODEM; 2241 pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
2243 chip->pcm[pcm_dev] = pcm; 2242 list_add_tail(&apcm->list, &chip->pcm_list);
2244 cpcm->pcm = pcm; 2243 cpcm->pcm = pcm;
2245 for (s = 0; s < 2; s++) { 2244 for (s = 0; s < 2; s++) {
2246 apcm->hinfo[s] = &cpcm->stream[s]; 2245 apcm->hinfo[s] = &cpcm->stream[s];
@@ -2370,12 +2369,12 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2370{ 2369{
2371 struct snd_card *card = pci_get_drvdata(pci); 2370 struct snd_card *card = pci_get_drvdata(pci);
2372 struct azx *chip = card->private_data; 2371 struct azx *chip = card->private_data;
2373 int i; 2372 struct azx_pcm *p;
2374 2373
2375 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2374 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2376 azx_clear_irq_pending(chip); 2375 azx_clear_irq_pending(chip);
2377 for (i = 0; i < HDA_MAX_PCMS; i++) 2376 list_for_each_entry(p, &chip->pcm_list, list)
2378 snd_pcm_suspend_all(chip->pcm[i]); 2377 snd_pcm_suspend_all(p->pcm);
2379 if (chip->initialized) 2378 if (chip->initialized)
2380 snd_hda_suspend(chip->bus); 2379 snd_hda_suspend(chip->bus);
2381 azx_stop_chip(chip); 2380 azx_stop_chip(chip);
@@ -2672,6 +2671,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2672 check_msi(chip); 2671 check_msi(chip);
2673 chip->dev_index = dev; 2672 chip->dev_index = dev;
2674 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); 2673 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
2674 INIT_LIST_HEAD(&chip->pcm_list);
2675 2675
2676 chip->position_fix[0] = chip->position_fix[1] = 2676 chip->position_fix[0] = chip->position_fix[1] =
2677 check_position_fix(chip, position_fix[dev]); 2677 check_position_fix(chip, position_fix[dev]);