unsigned int mpu_port_saved;
#endif
- unsigned char playback_volume[4][2]; /* for VIA8233/C/8235; default = 0 */
+ unsigned char playback_volume[2]; /* for VIA8233/C/8235; default = 0 */
unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
snd_info_entry_t *proc_entry;
#ifdef SUPPORT_JOYSTICK
- struct gameport gameport;
- struct resource *res_joystick;
+ struct gameport *gameport;
#endif
};
snd_assert((rbits & ~0xfffff) == 0, return -EINVAL);
snd_via82xx_channel_reset(chip, viadev);
snd_via82xx_set_table_ptr(chip, viadev);
- outb(chip->playback_volume[viadev->reg_offset / 0x10][0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
- outb(chip->playback_volume[viadev->reg_offset / 0x10][1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
+ outb(chip->playback_volume[0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
+ outb(chip->playback_volume[1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */
(runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */
rbits | /* rate */
static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
via82xx_t *chip = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
- ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
- ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1];
+ ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[0];
+ ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[1];
return 0;
}
static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
via82xx_t *chip = snd_kcontrol_chip(kcontrol);
- unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
- unsigned long port = chip->port + 0x10 * idx;
+ unsigned int idx;
unsigned char val;
int i, change = 0;
if (val > VIA_DXS_MAX_VOLUME)
val = VIA_DXS_MAX_VOLUME;
val = VIA_DXS_MAX_VOLUME - val;
- change |= val != chip->playback_volume[idx][i];
- if (change) {
- chip->playback_volume[idx][i] = val;
- outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+ if (val != chip->playback_volume[i]) {
+ change = 1;
+ chip->playback_volume[i] = val;
+ for (idx = 0; idx < 4; idx++) {
+ unsigned long port = chip->port + 0x10 * idx;
+ outb(val, port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+ }
}
}
return change;
}
static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
- .name = "VIA DXS Playback Volume",
+ .name = "PCM Playback Volume",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .count = 4,
.info = snd_via8233_dxs_volume_info,
.get = snd_via8233_dxs_volume_get,
.put = snd_via8233_dxs_volume_put,
return 0;
}
+#ifdef SUPPORT_JOYSTICK
+#define JOYSTICK_ADDR 0x200
+static int __devinit snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+{
+ struct gameport *gp;
+ struct resource *r;
+
+ if (!joystick[dev])
+ return -ENODEV;
+
+ r = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport");
+ if (!r) {
+ printk(KERN_WARNING "via82xx: cannot reserve joystick port 0x%#x\n", JOYSTICK_ADDR);
+ return -EBUSY;
+ }
+
+ chip->gameport = gp = gameport_allocate_port();
+ if (!gp) {
+ printk(KERN_ERR "via82xx: cannot allocate memory for gameport\n");
+ release_resource(r);
+ kfree_nocheck(r);
+ return -ENOMEM;
+ }
+
+ gameport_set_name(gp, "VIA686 Gameport");
+ gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
+ gameport_set_dev_parent(gp, &chip->pci->dev);
+ gp->io = JOYSTICK_ADDR;
+ gameport_set_port_data(gp, r);
+
+ /* Enable legacy joystick port */
+ *legacy |= VIA_FUNC_ENABLE_GAME;
+ pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, *legacy);
+
+ gameport_register_port(chip->gameport);
+
+ return 0;
+}
+
+static void snd_via686_free_gameport(via82xx_t *chip)
+{
+ if (chip->gameport) {
+ struct resource *r = gameport_get_port_data(chip->gameport);
+
+ gameport_unregister_port(chip->gameport);
+ chip->gameport = NULL;
+ release_resource(r);
+ kfree_nocheck(r);
+ }
+}
+#else
+static inline int snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy)
+{
+ return -ENOSYS;
+}
+static inline void snd_via686_free_gameport(via82xx_t *chip) { }
+#endif
+
+
/*
*
*/
-static int snd_via8233_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev)
{
int i, err, caps;
unsigned char val;
return err;
}
if (chip->chip_type != TYPE_VIA8233A) {
- err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
- if (err < 0)
- return err;
+ /* when no h/w PCM volume control is found, use DXS volume control
+ * as the PCM vol control
+ */
+ snd_ctl_elem_id_t sid;
+ memset(&sid, 0, sizeof(sid));
+ strcpy(sid.name, "PCM Playback Volume");
+ sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ if (! snd_ctl_find_id(chip->card, &sid)) {
+ err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip));
+ if (err < 0)
+ return err;
+ }
}
/* select spdif data slot 10/11 */
return 0;
}
-static int snd_via686_init_misc(via82xx_t *chip, int dev)
+static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev)
{
unsigned char legacy, legacy_cfg;
int rev_h = 0;
mpu_port[dev] = 0;
}
-#ifdef SUPPORT_JOYSTICK
-#define JOYSTICK_ADDR 0x200
- if (joystick[dev] &&
- (chip->res_joystick = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport")) != NULL) {
- legacy |= VIA_FUNC_ENABLE_GAME;
- chip->gameport.io = JOYSTICK_ADDR;
- }
-#endif
-
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg);
if (chip->mpu_res) {
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy);
}
-#ifdef SUPPORT_JOYSTICK
- if (chip->res_joystick)
- gameport_register_port(&chip->gameport);
-#endif
+ snd_via686_create_gameport(chip, dev, &legacy);
#ifdef CONFIG_PM
chip->legacy_saved = legacy;
*
*/
-static int __devinit snd_via82xx_chip_init(via82xx_t *chip)
+static int snd_via82xx_chip_init(via82xx_t *chip)
{
- ac97_t ac97;
unsigned int val;
int max_count;
unsigned char pval;
- memset(&ac97, 0, sizeof(ac97));
- ac97.private_data = chip;
-
#if 0 /* broken on K7M? */
if (chip->chip_type == TYPE_VIA686)
/* disable all legacy ports */
if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
snd_printk("AC'97 codec is not ready [0x%x]\n", val);
- /* and then reset codec.. */
- snd_via82xx_codec_ready(chip, 0);
- snd_via82xx_codec_write(&ac97, AC97_RESET, 0x0000);
- snd_via82xx_codec_read(&ac97, 0);
-
#if 0 /* FIXME: we don't support the second codec yet so skip the detection now.. */
snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
VIA_REG_AC97_SECONDARY_VALID |
}
}
+ if (chip->chip_type != TYPE_VIA8233A) {
+ int i, idx;
+ for (idx = 0; idx < 4; idx++) {
+ unsigned long port = chip->port + 0x10 * idx;
+ for (i = 0; i < 2; i++)
+ outb(chip->playback_volume[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+ }
+ }
+
return 0;
}
/*
* power management
*/
-static int snd_via82xx_suspend(snd_card_t *card, unsigned int state)
+static int snd_via82xx_suspend(snd_card_t *card, pm_message_t state)
{
via82xx_t *chip = card->pm_private_data;
int i;
return 0;
}
-static int snd_via82xx_resume(snd_card_t *card, unsigned int state)
+static int snd_via82xx_resume(snd_card_t *card)
{
via82xx_t *chip = card->pm_private_data;
- int idx, i;
+ int i;
pci_enable_device(chip->pci);
pci_set_power_state(chip->pci, 0);
pci_write_config_byte(chip->pci, VIA8233_SPDIF_CTRL, chip->spdif_ctrl_saved);
outb(chip->capture_src_saved[0], chip->port + VIA_REG_CAPTURE_CHANNEL);
outb(chip->capture_src_saved[1], chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
- for (idx = 0; idx < 4; idx++) {
- unsigned long port = chip->port + 0x10 * idx;
- for (i = 0; i < 2; i++)
- outb(chip->playback_volume[idx][i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
- }
}
snd_ac97_resume(chip->ac97);
kfree_nocheck(chip->mpu_res);
}
pci_release_regions(chip->pci);
+
if (chip->chip_type == TYPE_VIA686) {
-#ifdef SUPPORT_JOYSTICK
- if (chip->res_joystick) {
- gameport_unregister_port(&chip->gameport);
- release_resource(chip->res_joystick);
- kfree_nocheck(chip->res_joystick);
- }
-#endif
+ snd_via686_free_gameport(chip);
pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, chip->old_legacy);
pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->old_legacy_cfg);
}
{ .vendor = 0x1458, .device = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
{ .vendor = 0x1462, .device = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
{ .vendor = 0x1462, .device = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
+ { .vendor = 0x1462, .device = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */
{ .vendor = 0x1462, .device = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
{ .vendor = 0x147b, .device = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
{ .vendor = 0x147b, .device = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */