diff options
Diffstat (limited to 'sound/pci/via82xx.c')
-rw-r--r-- | sound/pci/via82xx.c | 74 |
1 files changed, 63 insertions, 11 deletions
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 78a5dfb66796..7d46bee828c7 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -361,7 +361,8 @@ struct _snd_via82xx { | |||
361 | unsigned int mpu_port_saved; | 361 | unsigned int mpu_port_saved; |
362 | #endif | 362 | #endif |
363 | 363 | ||
364 | unsigned char playback_volume[2]; /* for VIA8233/C/8235; default = 0 */ | 364 | unsigned char playback_volume[4][2]; /* for VIA8233/C/8235; default = 0 */ |
365 | unsigned char playback_volume_c[2]; /* for VIA8233/C/8235; default = 0 */ | ||
365 | 366 | ||
366 | unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */ | 367 | unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */ |
367 | 368 | ||
@@ -937,8 +938,8 @@ static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream) | |||
937 | snd_assert((rbits & ~0xfffff) == 0, return -EINVAL); | 938 | snd_assert((rbits & ~0xfffff) == 0, return -EINVAL); |
938 | snd_via82xx_channel_reset(chip, viadev); | 939 | snd_via82xx_channel_reset(chip, viadev); |
939 | snd_via82xx_set_table_ptr(chip, viadev); | 940 | snd_via82xx_set_table_ptr(chip, viadev); |
940 | outb(chip->playback_volume[0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L)); | 941 | outb(chip->playback_volume[viadev->reg_offset / 0x10][0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L)); |
941 | outb(chip->playback_volume[1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R)); | 942 | outb(chip->playback_volume[viadev->reg_offset / 0x10][1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R)); |
942 | outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */ | 943 | outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */ |
943 | (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */ | 944 | (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */ |
944 | rbits | /* rate */ | 945 | rbits | /* rate */ |
@@ -1498,14 +1499,46 @@ static int snd_via8233_dxs_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_in | |||
1498 | static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | 1499 | static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
1499 | { | 1500 | { |
1500 | via82xx_t *chip = snd_kcontrol_chip(kcontrol); | 1501 | via82xx_t *chip = snd_kcontrol_chip(kcontrol); |
1501 | ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[0]; | 1502 | unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id); |
1502 | ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[1]; | 1503 | |
1504 | ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0]; | ||
1505 | ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1]; | ||
1506 | return 0; | ||
1507 | } | ||
1508 | |||
1509 | static int snd_via8233_pcmdxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
1510 | { | ||
1511 | via82xx_t *chip = snd_kcontrol_chip(kcontrol); | ||
1512 | ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[0]; | ||
1513 | ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[1]; | ||
1503 | return 0; | 1514 | return 0; |
1504 | } | 1515 | } |
1505 | 1516 | ||
1506 | static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | 1517 | static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
1507 | { | 1518 | { |
1508 | via82xx_t *chip = snd_kcontrol_chip(kcontrol); | 1519 | via82xx_t *chip = snd_kcontrol_chip(kcontrol); |
1520 | unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id); | ||
1521 | unsigned long port = chip->port + 0x10 * idx; | ||
1522 | unsigned char val; | ||
1523 | int i, change = 0; | ||
1524 | |||
1525 | for (i = 0; i < 2; i++) { | ||
1526 | val = ucontrol->value.integer.value[i]; | ||
1527 | if (val > VIA_DXS_MAX_VOLUME) | ||
1528 | val = VIA_DXS_MAX_VOLUME; | ||
1529 | val = VIA_DXS_MAX_VOLUME - val; | ||
1530 | change |= val != chip->playback_volume[idx][i]; | ||
1531 | if (change) { | ||
1532 | chip->playback_volume[idx][i] = val; | ||
1533 | outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i); | ||
1534 | } | ||
1535 | } | ||
1536 | return change; | ||
1537 | } | ||
1538 | |||
1539 | static int snd_via8233_pcmdxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
1540 | { | ||
1541 | via82xx_t *chip = snd_kcontrol_chip(kcontrol); | ||
1509 | unsigned int idx; | 1542 | unsigned int idx; |
1510 | unsigned char val; | 1543 | unsigned char val; |
1511 | int i, change = 0; | 1544 | int i, change = 0; |
@@ -1515,11 +1548,12 @@ static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val | |||
1515 | if (val > VIA_DXS_MAX_VOLUME) | 1548 | if (val > VIA_DXS_MAX_VOLUME) |
1516 | val = VIA_DXS_MAX_VOLUME; | 1549 | val = VIA_DXS_MAX_VOLUME; |
1517 | val = VIA_DXS_MAX_VOLUME - val; | 1550 | val = VIA_DXS_MAX_VOLUME - val; |
1518 | if (val != chip->playback_volume[i]) { | 1551 | if (val != chip->playback_volume_c[i]) { |
1519 | change = 1; | 1552 | change = 1; |
1520 | chip->playback_volume[i] = val; | 1553 | chip->playback_volume_c[i] = val; |
1521 | for (idx = 0; idx < 4; idx++) { | 1554 | for (idx = 0; idx < 4; idx++) { |
1522 | unsigned long port = chip->port + 0x10 * idx; | 1555 | unsigned long port = chip->port + 0x10 * idx; |
1556 | chip->playback_volume[idx][i] = val; | ||
1523 | outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i); | 1557 | outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i); |
1524 | } | 1558 | } |
1525 | } | 1559 | } |
@@ -1527,10 +1561,19 @@ static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val | |||
1527 | return change; | 1561 | return change; |
1528 | } | 1562 | } |
1529 | 1563 | ||
1530 | static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = { | 1564 | static snd_kcontrol_new_t snd_via8233_pcmdxs_volume_control __devinitdata = { |
1531 | .name = "PCM Playback Volume", | 1565 | .name = "PCM Playback Volume", |
1532 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1566 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1533 | .info = snd_via8233_dxs_volume_info, | 1567 | .info = snd_via8233_dxs_volume_info, |
1568 | .get = snd_via8233_pcmdxs_volume_get, | ||
1569 | .put = snd_via8233_pcmdxs_volume_put, | ||
1570 | }; | ||
1571 | |||
1572 | static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = { | ||
1573 | .name = "VIA DXS Playback Volume", | ||
1574 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1575 | .count = 4, | ||
1576 | .info = snd_via8233_dxs_volume_info, | ||
1534 | .get = snd_via8233_dxs_volume_get, | 1577 | .get = snd_via8233_dxs_volume_get, |
1535 | .put = snd_via8233_dxs_volume_put, | 1578 | .put = snd_via8233_dxs_volume_put, |
1536 | }; | 1579 | }; |
@@ -1723,12 +1766,19 @@ static int __devinit snd_via8233_init_misc(via82xx_t *chip) | |||
1723 | strcpy(sid.name, "PCM Playback Volume"); | 1766 | strcpy(sid.name, "PCM Playback Volume"); |
1724 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 1767 | sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
1725 | if (! snd_ctl_find_id(chip->card, &sid)) { | 1768 | if (! snd_ctl_find_id(chip->card, &sid)) { |
1769 | snd_printd(KERN_INFO "Using DXS as PCM Playback\n"); | ||
1770 | err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_pcmdxs_volume_control, chip)); | ||
1771 | if (err < 0) | ||
1772 | return err; | ||
1773 | } | ||
1774 | else /* Using DXS when PCM emulation is enabled is really weird */ | ||
1775 | { | ||
1776 | /* Standalone DXS controls */ | ||
1726 | err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip)); | 1777 | err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip)); |
1727 | if (err < 0) | 1778 | if (err < 0) |
1728 | return err; | 1779 | return err; |
1729 | } | 1780 | } |
1730 | } | 1781 | } |
1731 | |||
1732 | /* select spdif data slot 10/11 */ | 1782 | /* select spdif data slot 10/11 */ |
1733 | pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val); | 1783 | pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val); |
1734 | val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011; | 1784 | val = (val & ~VIA8233_SPDIF_SLOT_MASK) | VIA8233_SPDIF_SLOT_1011; |
@@ -1941,8 +1991,10 @@ static int snd_via82xx_chip_init(via82xx_t *chip) | |||
1941 | int i, idx; | 1991 | int i, idx; |
1942 | for (idx = 0; idx < 4; idx++) { | 1992 | for (idx = 0; idx < 4; idx++) { |
1943 | unsigned long port = chip->port + 0x10 * idx; | 1993 | unsigned long port = chip->port + 0x10 * idx; |
1944 | for (i = 0; i < 2; i++) | 1994 | for (i = 0; i < 2; i++) { |
1945 | outb(chip->playback_volume[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i); | 1995 | chip->playback_volume[idx][i]=chip->playback_volume_c[i]; |
1996 | outb(chip->playback_volume_c[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i); | ||
1997 | } | ||
1946 | } | 1998 | } |
1947 | } | 1999 | } |
1948 | 2000 | ||