diff options
Diffstat (limited to 'sound/pci/ymfpci/ymfpci_main.c')
-rw-r--r-- | sound/pci/ymfpci/ymfpci_main.c | 108 |
1 files changed, 50 insertions, 58 deletions
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index ab7a81c35705..1fe39ed28765 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> | 2 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
3 | * Routines for control of YMF724/740/744/754 chips | 3 | * Routines for control of YMF724/740/744/754 chips |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
@@ -84,7 +84,6 @@ static int snd_ymfpci_codec_ready(struct snd_ymfpci *chip, int secondary) | |||
84 | do { | 84 | do { |
85 | if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0) | 85 | if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0) |
86 | return 0; | 86 | return 0; |
87 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
88 | schedule_timeout_uninterruptible(1); | 87 | schedule_timeout_uninterruptible(1); |
89 | } while (time_before(jiffies, end_time)); | 88 | } while (time_before(jiffies, end_time)); |
90 | snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); | 89 | snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); |
@@ -171,17 +170,6 @@ static u32 snd_ymfpci_calc_lpfQ(u32 rate) | |||
171 | return val[0]; | 170 | return val[0]; |
172 | } | 171 | } |
173 | 172 | ||
174 | static void snd_ymfpci_pcm_441_volume_set(struct snd_ymfpci_pcm *ypcm) | ||
175 | { | ||
176 | unsigned int value; | ||
177 | struct snd_ymfpci_pcm_mixer *mixer; | ||
178 | |||
179 | mixer = &ypcm->chip->pcm_mixer[ypcm->substream->number]; | ||
180 | value = min_t(unsigned int, mixer->left, 0x7fff) >> 1; | ||
181 | value |= (min_t(unsigned int, mixer->right, 0x7fff) >> 1) << 16; | ||
182 | snd_ymfpci_writel(ypcm->chip, YDSXGR_BUF441OUTVOL, value); | ||
183 | } | ||
184 | |||
185 | /* | 173 | /* |
186 | * Hardware start management | 174 | * Hardware start management |
187 | */ | 175 | */ |
@@ -389,6 +377,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream, | |||
389 | { | 377 | { |
390 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); | 378 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); |
391 | struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; | 379 | struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; |
380 | struct snd_kcontrol *kctl = NULL; | ||
392 | int result = 0; | 381 | int result = 0; |
393 | 382 | ||
394 | spin_lock(&chip->reg_lock); | 383 | spin_lock(&chip->reg_lock); |
@@ -406,6 +395,11 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream, | |||
406 | ypcm->running = 1; | 395 | ypcm->running = 1; |
407 | break; | 396 | break; |
408 | case SNDRV_PCM_TRIGGER_STOP: | 397 | case SNDRV_PCM_TRIGGER_STOP: |
398 | if (substream->pcm == chip->pcm && !ypcm->use_441_slot) { | ||
399 | kctl = chip->pcm_mixer[substream->number].ctl; | ||
400 | kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
401 | } | ||
402 | /* fall through */ | ||
409 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 403 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
410 | case SNDRV_PCM_TRIGGER_SUSPEND: | 404 | case SNDRV_PCM_TRIGGER_SUSPEND: |
411 | chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0; | 405 | chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0; |
@@ -419,6 +413,8 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream, | |||
419 | } | 413 | } |
420 | __unlock: | 414 | __unlock: |
421 | spin_unlock(&chip->reg_lock); | 415 | spin_unlock(&chip->reg_lock); |
416 | if (kctl) | ||
417 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); | ||
422 | return result; | 418 | return result; |
423 | } | 419 | } |
424 | static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream, | 420 | static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream, |
@@ -526,7 +522,6 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int | |||
526 | ypcm->chip->src441_used = voice->number; | 522 | ypcm->chip->src441_used = voice->number; |
527 | ypcm->use_441_slot = 1; | 523 | ypcm->use_441_slot = 1; |
528 | format |= 0x10000000; | 524 | format |= 0x10000000; |
529 | snd_ymfpci_pcm_441_volume_set(ypcm); | ||
530 | } | 525 | } |
531 | if (ypcm->chip->src441_used == voice->number && | 526 | if (ypcm->chip->src441_used == voice->number && |
532 | (format & 0x10000000) == 0) { | 527 | (format & 0x10000000) == 0) { |
@@ -667,6 +662,7 @@ static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream) | |||
667 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); | 662 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); |
668 | struct snd_pcm_runtime *runtime = substream->runtime; | 663 | struct snd_pcm_runtime *runtime = substream->runtime; |
669 | struct snd_ymfpci_pcm *ypcm = runtime->private_data; | 664 | struct snd_ymfpci_pcm *ypcm = runtime->private_data; |
665 | struct snd_kcontrol *kctl; | ||
670 | unsigned int nvoice; | 666 | unsigned int nvoice; |
671 | 667 | ||
672 | ypcm->period_size = runtime->period_size; | 668 | ypcm->period_size = runtime->period_size; |
@@ -676,6 +672,12 @@ static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream) | |||
676 | for (nvoice = 0; nvoice < runtime->channels; nvoice++) | 672 | for (nvoice = 0; nvoice < runtime->channels; nvoice++) |
677 | snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime, | 673 | snd_ymfpci_pcm_init_voice(ypcm, nvoice, runtime, |
678 | substream->pcm == chip->pcm); | 674 | substream->pcm == chip->pcm); |
675 | |||
676 | if (substream->pcm == chip->pcm && !ypcm->use_441_slot) { | ||
677 | kctl = chip->pcm_mixer[substream->number].ctl; | ||
678 | kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
679 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); | ||
680 | } | ||
679 | return 0; | 681 | return 0; |
680 | } | 682 | } |
681 | 683 | ||
@@ -926,7 +928,6 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream) | |||
926 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); | 928 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); |
927 | struct snd_pcm_runtime *runtime = substream->runtime; | 929 | struct snd_pcm_runtime *runtime = substream->runtime; |
928 | struct snd_ymfpci_pcm *ypcm; | 930 | struct snd_ymfpci_pcm *ypcm; |
929 | struct snd_kcontrol *kctl; | ||
930 | int err; | 931 | int err; |
931 | 932 | ||
932 | if ((err = snd_ymfpci_playback_open_1(substream)) < 0) | 933 | if ((err = snd_ymfpci_playback_open_1(substream)) < 0) |
@@ -941,10 +942,6 @@ static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream) | |||
941 | chip->rear_opened++; | 942 | chip->rear_opened++; |
942 | } | 943 | } |
943 | spin_unlock_irq(&chip->reg_lock); | 944 | spin_unlock_irq(&chip->reg_lock); |
944 | |||
945 | kctl = chip->pcm_mixer[substream->number].ctl; | ||
946 | kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
947 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); | ||
948 | return 0; | 945 | return 0; |
949 | } | 946 | } |
950 | 947 | ||
@@ -1039,7 +1036,6 @@ static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream) | |||
1039 | { | 1036 | { |
1040 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); | 1037 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); |
1041 | struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; | 1038 | struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; |
1042 | struct snd_kcontrol *kctl; | ||
1043 | 1039 | ||
1044 | spin_lock_irq(&chip->reg_lock); | 1040 | spin_lock_irq(&chip->reg_lock); |
1045 | if (ypcm->output_rear && chip->rear_opened > 0) { | 1041 | if (ypcm->output_rear && chip->rear_opened > 0) { |
@@ -1047,9 +1043,6 @@ static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream) | |||
1047 | ymfpci_close_extension(chip); | 1043 | ymfpci_close_extension(chip); |
1048 | } | 1044 | } |
1049 | spin_unlock_irq(&chip->reg_lock); | 1045 | spin_unlock_irq(&chip->reg_lock); |
1050 | kctl = chip->pcm_mixer[substream->number].ctl; | ||
1051 | kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
1052 | snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, &kctl->id); | ||
1053 | return snd_ymfpci_playback_close_1(substream); | 1046 | return snd_ymfpci_playback_close_1(substream); |
1054 | } | 1047 | } |
1055 | 1048 | ||
@@ -1443,22 +1436,7 @@ static struct snd_kcontrol_new snd_ymfpci_drec_source __devinitdata = { | |||
1443 | .get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \ | 1436 | .get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \ |
1444 | .private_value = ((reg) | ((shift) << 16)) } | 1437 | .private_value = ((reg) | ((shift) << 16)) } |
1445 | 1438 | ||
1446 | static int snd_ymfpci_info_single(struct snd_kcontrol *kcontrol, | 1439 | #define snd_ymfpci_info_single snd_ctl_boolean_mono_info |
1447 | struct snd_ctl_elem_info *uinfo) | ||
1448 | { | ||
1449 | int reg = kcontrol->private_value & 0xffff; | ||
1450 | |||
1451 | switch (reg) { | ||
1452 | case YDSXGR_SPDIFOUTCTRL: break; | ||
1453 | case YDSXGR_SPDIFINCTRL: break; | ||
1454 | default: return -EINVAL; | ||
1455 | } | ||
1456 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1457 | uinfo->count = 1; | ||
1458 | uinfo->value.integer.min = 0; | ||
1459 | uinfo->value.integer.max = 1; | ||
1460 | return 0; | ||
1461 | } | ||
1462 | 1440 | ||
1463 | static int snd_ymfpci_get_single(struct snd_kcontrol *kcontrol, | 1441 | static int snd_ymfpci_get_single(struct snd_kcontrol *kcontrol, |
1464 | struct snd_ctl_elem_value *ucontrol) | 1442 | struct snd_ctl_elem_value *ucontrol) |
@@ -1567,17 +1545,30 @@ static int snd_ymfpci_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1567 | return change; | 1545 | return change; |
1568 | } | 1546 | } |
1569 | 1547 | ||
1548 | static int snd_ymfpci_put_nativedacvol(struct snd_kcontrol *kcontrol, | ||
1549 | struct snd_ctl_elem_value *ucontrol) | ||
1550 | { | ||
1551 | struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol); | ||
1552 | unsigned int reg = YDSXGR_NATIVEDACOUTVOL; | ||
1553 | unsigned int reg2 = YDSXGR_BUF441OUTVOL; | ||
1554 | int change; | ||
1555 | unsigned int value, oval; | ||
1556 | |||
1557 | value = ucontrol->value.integer.value[0] & 0x3fff; | ||
1558 | value |= (ucontrol->value.integer.value[1] & 0x3fff) << 16; | ||
1559 | spin_lock_irq(&chip->reg_lock); | ||
1560 | oval = snd_ymfpci_readl(chip, reg); | ||
1561 | change = value != oval; | ||
1562 | snd_ymfpci_writel(chip, reg, value); | ||
1563 | snd_ymfpci_writel(chip, reg2, value); | ||
1564 | spin_unlock_irq(&chip->reg_lock); | ||
1565 | return change; | ||
1566 | } | ||
1567 | |||
1570 | /* | 1568 | /* |
1571 | * 4ch duplication | 1569 | * 4ch duplication |
1572 | */ | 1570 | */ |
1573 | static int snd_ymfpci_info_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1571 | #define snd_ymfpci_info_dup4ch snd_ctl_boolean_mono_info |
1574 | { | ||
1575 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1576 | uinfo->count = 1; | ||
1577 | uinfo->value.integer.min = 0; | ||
1578 | uinfo->value.integer.max = 1; | ||
1579 | return 0; | ||
1580 | } | ||
1581 | 1572 | ||
1582 | static int snd_ymfpci_get_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1573 | static int snd_ymfpci_get_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1583 | { | 1574 | { |
@@ -1598,7 +1589,17 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1598 | 1589 | ||
1599 | 1590 | ||
1600 | static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { | 1591 | static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { |
1601 | YMFPCI_DOUBLE("Wave Playback Volume", 0, YDSXGR_NATIVEDACOUTVOL), | 1592 | { |
1593 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1594 | .name = "Wave Playback Volume", | ||
1595 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
1596 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
1597 | .info = snd_ymfpci_info_double, | ||
1598 | .get = snd_ymfpci_get_double, | ||
1599 | .put = snd_ymfpci_put_nativedacvol, | ||
1600 | .private_value = YDSXGR_NATIVEDACOUTVOL, | ||
1601 | .tlv = { .p = db_scale_native }, | ||
1602 | }, | ||
1602 | YMFPCI_DOUBLE("Wave Capture Volume", 0, YDSXGR_NATIVEDACLOOPVOL), | 1603 | YMFPCI_DOUBLE("Wave Capture Volume", 0, YDSXGR_NATIVEDACLOOPVOL), |
1603 | YMFPCI_DOUBLE("Digital Capture Volume", 0, YDSXGR_NATIVEDACINVOL), | 1604 | YMFPCI_DOUBLE("Digital Capture Volume", 0, YDSXGR_NATIVEDACINVOL), |
1604 | YMFPCI_DOUBLE("Digital Capture Volume", 1, YDSXGR_NATIVEADCINVOL), | 1605 | YMFPCI_DOUBLE("Digital Capture Volume", 1, YDSXGR_NATIVEADCINVOL), |
@@ -1665,14 +1666,7 @@ static int snd_ymfpci_set_gpio_out(struct snd_ymfpci *chip, int pin, int enable) | |||
1665 | return 0; | 1666 | return 0; |
1666 | } | 1667 | } |
1667 | 1668 | ||
1668 | static int snd_ymfpci_gpio_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1669 | #define snd_ymfpci_gpio_sw_info snd_ctl_boolean_mono_info |
1669 | { | ||
1670 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
1671 | uinfo->count = 1; | ||
1672 | uinfo->value.integer.min = 0; | ||
1673 | uinfo->value.integer.max = 1; | ||
1674 | return 0; | ||
1675 | } | ||
1676 | 1670 | ||
1677 | static int snd_ymfpci_gpio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1671 | static int snd_ymfpci_gpio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
1678 | { | 1672 | { |
@@ -1748,8 +1742,6 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol, | |||
1748 | struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; | 1742 | struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; |
1749 | if (!ypcm->use_441_slot) | 1743 | if (!ypcm->use_441_slot) |
1750 | ypcm->update_pcm_vol = 2; | 1744 | ypcm->update_pcm_vol = 2; |
1751 | else | ||
1752 | snd_ymfpci_pcm_441_volume_set(ypcm); | ||
1753 | } | 1745 | } |
1754 | spin_unlock_irqrestore(&chip->voice_lock, flags); | 1746 | spin_unlock_irqrestore(&chip->voice_lock, flags); |
1755 | return 1; | 1747 | return 1; |