84 |
writel(val, chip->reg_area_virt + offset); |
writel(val, chip->reg_area_virt + offset); |
85 |
} |
} |
86 |
|
|
87 |
static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary, int sched) |
static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary) |
88 |
{ |
{ |
89 |
signed long end_time; |
signed long end_time; |
90 |
u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; |
u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; |
93 |
do { |
do { |
94 |
if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0) |
if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0) |
95 |
return 0; |
return 0; |
96 |
if (sched) { |
set_current_state(TASK_UNINTERRUPTIBLE); |
97 |
set_current_state(TASK_UNINTERRUPTIBLE); |
schedule_timeout(1); |
|
schedule_timeout(1); |
|
|
} |
|
98 |
} while (end_time - (signed long)jiffies >= 0); |
} while (end_time - (signed long)jiffies >= 0); |
99 |
snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); |
snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); |
100 |
return -EBUSY; |
return -EBUSY; |
105 |
ymfpci_t *chip = snd_magic_cast(ymfpci_t, ac97->private_data, return); |
ymfpci_t *chip = snd_magic_cast(ymfpci_t, ac97->private_data, return); |
106 |
u32 cmd; |
u32 cmd; |
107 |
|
|
108 |
snd_ymfpci_codec_ready(chip, 0, 0); |
snd_ymfpci_codec_ready(chip, 0); |
109 |
cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val; |
cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val; |
110 |
snd_ymfpci_writel(chip, YDSXGR_AC97CMDDATA, cmd); |
snd_ymfpci_writel(chip, YDSXGR_AC97CMDDATA, cmd); |
111 |
} |
} |
114 |
{ |
{ |
115 |
ymfpci_t *chip = snd_magic_cast(ymfpci_t, ac97->private_data, return -ENXIO); |
ymfpci_t *chip = snd_magic_cast(ymfpci_t, ac97->private_data, return -ENXIO); |
116 |
|
|
117 |
if (snd_ymfpci_codec_ready(chip, 0, 0)) |
if (snd_ymfpci_codec_ready(chip, 0)) |
118 |
return ~0; |
return ~0; |
119 |
snd_ymfpci_writew(chip, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg); |
snd_ymfpci_writew(chip, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg); |
120 |
if (snd_ymfpci_codec_ready(chip, 0, 0)) |
if (snd_ymfpci_codec_ready(chip, 0)) |
121 |
return ~0; |
return ~0; |
122 |
if (chip->device_id == PCI_DEVICE_ID_YAMAHA_744 && chip->rev < 2) { |
if (chip->device_id == PCI_DEVICE_ID_YAMAHA_744 && chip->rev < 2) { |
123 |
int i; |
int i; |
1706 |
* joystick support |
* joystick support |
1707 |
*/ |
*/ |
1708 |
|
|
1709 |
|
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) |
1710 |
static int ymfpci_joystick_ports[4] = { |
static int ymfpci_joystick_ports[4] = { |
1711 |
0x201, 0x202, 0x204, 0x205 |
0x201, 0x202, 0x204, 0x205 |
1712 |
}; |
}; |
1713 |
|
|
1714 |
|
static int snd_ymfpci_get_joystick_port(ymfpci_t *chip, int index) |
1715 |
|
{ |
1716 |
|
if (index < 4) |
1717 |
|
return ymfpci_joystick_ports[index]; |
1718 |
|
else |
1719 |
|
return pci_resource_start(chip->pci, 2); |
1720 |
|
} |
1721 |
|
|
1722 |
static void setup_joystick_base(ymfpci_t *chip) |
static void setup_joystick_base(ymfpci_t *chip) |
1723 |
{ |
{ |
1724 |
if (chip->pci->device >= 0x0010) /* YMF 744/754 */ |
if (chip->device_id >= 0x0010) /* YMF 744/754 */ |
1725 |
pci_write_config_word(chip->pci, PCIR_DSXG_JOYBASE, |
pci_write_config_word(chip->pci, PCIR_DSXG_JOYBASE, |
1726 |
ymfpci_joystick_ports[chip->joystick_port]); |
snd_ymfpci_get_joystick_port(chip, chip->joystick_port)); |
1727 |
else { |
else { |
1728 |
u16 legacy_ctrl2; |
u16 legacy_ctrl2; |
1729 |
pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY, &legacy_ctrl2); |
pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY, &legacy_ctrl2); |
1730 |
legacy_ctrl2 &= ~(3 << 6); |
legacy_ctrl2 &= ~YMFPCI_LEGACY2_JSIO; |
1731 |
legacy_ctrl2 |= chip->joystick_port << 6; |
legacy_ctrl2 |= chip->joystick_port << 6; |
1732 |
pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, legacy_ctrl2); |
pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, legacy_ctrl2); |
1733 |
} |
} |
1734 |
} |
} |
1735 |
|
|
1736 |
|
static int snd_ymfpci_enable_joystick(ymfpci_t *chip) |
1737 |
|
{ |
1738 |
|
u16 val; |
1739 |
|
|
1740 |
|
chip->gameport.io = snd_ymfpci_get_joystick_port(chip, chip->joystick_port); |
1741 |
|
chip->joystick_res = request_region(chip->gameport.io, 1, "YMFPCI gameport"); |
1742 |
|
if (!chip->joystick_res) { |
1743 |
|
snd_printk(KERN_WARNING "gameport port %#x in use\n", chip->gameport.io); |
1744 |
|
return 0; |
1745 |
|
} |
1746 |
|
setup_joystick_base(chip); |
1747 |
|
pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, &val); |
1748 |
|
val |= YMFPCI_LEGACY_JPEN; |
1749 |
|
pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, val); |
1750 |
|
gameport_register_port(&chip->gameport); |
1751 |
|
return 1; |
1752 |
|
} |
1753 |
|
|
1754 |
|
static int snd_ymfpci_disable_joystick(ymfpci_t *chip) |
1755 |
|
{ |
1756 |
|
u16 val; |
1757 |
|
|
1758 |
|
gameport_unregister_port(&chip->gameport); |
1759 |
|
pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, &val); |
1760 |
|
val &= ~YMFPCI_LEGACY_JPEN; |
1761 |
|
pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, val); |
1762 |
|
release_resource(chip->joystick_res); |
1763 |
|
kfree_nocheck(chip->joystick_res); |
1764 |
|
chip->joystick_res = NULL; |
1765 |
|
return 1; |
1766 |
|
} |
1767 |
|
|
1768 |
static int snd_ymfpci_joystick_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) |
static int snd_ymfpci_joystick_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) |
1769 |
{ |
{ |
1770 |
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
1780 |
u16 val; |
u16 val; |
1781 |
|
|
1782 |
pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, &val); |
pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, &val); |
1783 |
ucontrol->value.integer.value[0] = (val & 0x04) ? 1 : 0; |
ucontrol->value.integer.value[0] = (val & YMFPCI_LEGACY_JPEN) ? 1 : 0; |
1784 |
return 0; |
return 0; |
1785 |
} |
} |
1786 |
|
|
1787 |
static int snd_ymfpci_joystick_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
static int snd_ymfpci_joystick_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
1788 |
{ |
{ |
1789 |
ymfpci_t *chip = snd_kcontrol_chip(kcontrol); |
ymfpci_t *chip = snd_kcontrol_chip(kcontrol); |
1790 |
u16 val, oval; |
int enabled, change; |
1791 |
|
|
1792 |
pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, &oval); |
down(&chip->joystick_mutex); |
1793 |
val = oval & ~0x04; |
enabled = chip->joystick_res != NULL; |
1794 |
if (ucontrol->value.integer.value[0]) |
change = enabled != !! ucontrol->value.integer.value[0]; |
1795 |
val |= 0x04; |
if (change) { |
1796 |
if (val != oval) { |
if (!enabled) |
1797 |
setup_joystick_base(chip); |
change = snd_ymfpci_enable_joystick(chip); |
1798 |
pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, val); |
else |
1799 |
return 1; |
change = snd_ymfpci_disable_joystick(chip); |
1800 |
} |
} |
1801 |
return 0; |
up(&chip->joystick_mutex); |
1802 |
|
return change; |
1803 |
} |
} |
1804 |
|
|
1805 |
static int snd_ymfpci_joystick_addr_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) |
static int snd_ymfpci_joystick_addr_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) |
1806 |
{ |
{ |
1807 |
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
ymfpci_t *chip = snd_kcontrol_chip(kcontrol); |
1808 |
uinfo->count = 1; |
int ports = chip->device_id >= 0x0010 ? 5 : 4; |
1809 |
uinfo->value.enumerated.items = 4; |
|
1810 |
if (uinfo->value.enumerated.item >= 4) |
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1811 |
uinfo->value.enumerated.item = 3; |
uinfo->count = 1; |
1812 |
sprintf(uinfo->value.enumerated.name, "port 0x%x", ymfpci_joystick_ports[uinfo->value.enumerated.item]); |
uinfo->value.enumerated.items = ports; |
1813 |
return 0; |
if (uinfo->value.enumerated.item >= ports) |
1814 |
|
uinfo->value.enumerated.item = ports - 1; |
1815 |
|
sprintf(uinfo->value.enumerated.name, "port 0x%x", |
1816 |
|
snd_ymfpci_get_joystick_port(chip, uinfo->value.enumerated.item)); |
1817 |
|
return 0; |
1818 |
} |
} |
1819 |
|
|
1820 |
static int snd_ymfpci_joystick_addr_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
static int snd_ymfpci_joystick_addr_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
1827 |
static int snd_ymfpci_joystick_addr_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
static int snd_ymfpci_joystick_addr_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
1828 |
{ |
{ |
1829 |
ymfpci_t *chip = snd_kcontrol_chip(kcontrol); |
ymfpci_t *chip = snd_kcontrol_chip(kcontrol); |
1830 |
if (ucontrol->value.enumerated.item[0] != chip->joystick_port) { |
int change, enabled; |
1831 |
snd_assert(ucontrol->value.enumerated.item[0] >= 0 && ucontrol->value.enumerated.item[0] < 4, return -EINVAL); |
|
1832 |
|
down(&chip->joystick_mutex); |
1833 |
|
change = ucontrol->value.enumerated.item[0] != chip->joystick_port; |
1834 |
|
if (change) { |
1835 |
|
enabled = chip->joystick_res != NULL; |
1836 |
|
if (enabled) |
1837 |
|
snd_ymfpci_disable_joystick(chip); |
1838 |
chip->joystick_port = ucontrol->value.enumerated.item[0]; |
chip->joystick_port = ucontrol->value.enumerated.item[0]; |
1839 |
setup_joystick_base(chip); |
if (enabled) |
1840 |
return 1; |
snd_ymfpci_enable_joystick(chip); |
1841 |
} |
} |
1842 |
return 0; |
up(&chip->joystick_mutex); |
1843 |
|
return change; |
1844 |
} |
} |
1845 |
|
|
1846 |
static snd_kcontrol_new_t snd_ymfpci_control_joystick __devinitdata = { |
static snd_kcontrol_new_t snd_ymfpci_control_joystick __devinitdata = { |
1870 |
return err; |
return err; |
1871 |
return 0; |
return 0; |
1872 |
} |
} |
1873 |
|
#endif /* CONFIG_GAMEPORT */ |
1874 |
|
|
1875 |
|
|
1876 |
/* |
/* |
2119 |
release_resource(chip->fm_res); |
release_resource(chip->fm_res); |
2120 |
kfree_nocheck(chip->fm_res); |
kfree_nocheck(chip->fm_res); |
2121 |
} |
} |
2122 |
|
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) |
2123 |
|
if (chip->joystick_res) |
2124 |
|
snd_ymfpci_disable_joystick(chip); |
2125 |
|
#endif |
2126 |
if (chip->reg_area_virt) |
if (chip->reg_area_virt) |
2127 |
iounmap((void *)chip->reg_area_virt); |
iounmap((void *)chip->reg_area_virt); |
2128 |
if (chip->work_ptr) |
if (chip->work_ptr) |
2207 |
pci_enable_device(chip->pci); |
pci_enable_device(chip->pci); |
2208 |
pci_set_master(chip->pci); |
pci_set_master(chip->pci); |
2209 |
snd_ymfpci_aclink_reset(chip->pci); |
snd_ymfpci_aclink_reset(chip->pci); |
2210 |
snd_ymfpci_codec_ready(chip, 0, 0); |
snd_ymfpci_codec_ready(chip, 0); |
2211 |
snd_ymfpci_download_image(chip); |
snd_ymfpci_download_image(chip); |
2212 |
udelay(100); |
udelay(100); |
2213 |
|
|
2272 |
spin_lock_init(&chip->voice_lock); |
spin_lock_init(&chip->voice_lock); |
2273 |
init_waitqueue_head(&chip->interrupt_sleep); |
init_waitqueue_head(&chip->interrupt_sleep); |
2274 |
atomic_set(&chip->interrupt_sleep_count, 0); |
atomic_set(&chip->interrupt_sleep_count, 0); |
2275 |
|
#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) |
2276 |
|
init_MUTEX(&chip->joystick_mutex); |
2277 |
|
#endif |
2278 |
chip->card = card; |
chip->card = card; |
2279 |
chip->pci = pci; |
chip->pci = pci; |
2280 |
chip->irq = -1; |
chip->irq = -1; |
2297 |
chip->irq = pci->irq; |
chip->irq = pci->irq; |
2298 |
|
|
2299 |
snd_ymfpci_aclink_reset(pci); |
snd_ymfpci_aclink_reset(pci); |
2300 |
if (snd_ymfpci_codec_ready(chip, 0, 1) < 0) { |
if (snd_ymfpci_codec_ready(chip, 0) < 0) { |
2301 |
snd_ymfpci_free(chip); |
snd_ymfpci_free(chip); |
2302 |
return -EIO; |
return -EIO; |
2303 |
} |
} |