185 #include <linux/pci.h>
187 #include <linux/slab.h>
188 #include <linux/gameport.h>
189 #include <linux/module.h>
203 #define AZF_USE_AC97_LAYER 1
205 #ifdef AZF_USE_AC97_LAYER
215 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
216 #define SUPPORT_GAMEPORT 1
242 #define DEBUG_CALLS 0
243 #define DEBUG_MIXER 0
244 #define DEBUG_CODEC 0
245 #define DEBUG_TIMER 0
248 #define MIXER_TESTING 0
251 #define snd_azf3328_dbgmisc(format, args...) printk(KERN_DEBUG format, ##args)
253 #define snd_azf3328_dbgmisc(format, args...)
257 #define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
258 #define snd_azf3328_dbgcallenter() printk(KERN_DEBUG "--> %s\n", __func__)
259 #define snd_azf3328_dbgcallleave() printk(KERN_DEBUG "<-- %s\n", __func__)
261 #define snd_azf3328_dbgcalls(format, args...)
262 #define snd_azf3328_dbgcallenter()
263 #define snd_azf3328_dbgcallleave()
267 #define snd_azf3328_dbgmixer(format, args...) printk(KERN_DEBUG format, ##args)
269 #define snd_azf3328_dbgmixer(format, args...)
273 #define snd_azf3328_dbgcodec(format, args...) printk(KERN_DEBUG format, ##args)
275 #define snd_azf3328_dbgcodec(format, args...)
279 #define snd_azf3328_dbgtimer(format, args...) printk(KERN_DEBUG format, ##args)
281 #define snd_azf3328_dbgtimer(format, args...)
285 #define snd_azf3328_dbggame(format, args...) printk(KERN_DEBUG format, ##args)
287 #define snd_azf3328_dbggame(format, args...)
291 #define snd_azf3328_dbgpm(format, args...) printk(KERN_DEBUG format, ##args)
293 #define snd_azf3328_dbgpm(format, args...)
308 static int seqtimer_scaling = 128;
310 MODULE_PARM_DESC(seqtimer_scaling,
"Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
347 #ifdef AZF_USE_AC97_LAYER
354 #ifdef SUPPORT_GAMEPORT
368 #ifdef CONFIG_PM_SLEEP
389 snd_azf3328_io_reg_setb(
unsigned reg,
u8 mask,
bool do_set)
396 new = (do_set) ? (prev|mask) : (prev & ~mask);
526 #define AZF_MUTE_BIT 0x80
530 unsigned reg,
bool do_mute
533 unsigned long portbase = chip->
mixer_io + reg + 1;
538 updated = snd_azf3328_io_reg_setb(portbase,
AZF_MUTE_BIT, do_mute);
541 return (do_mute) ? !updated : updated;
549 return snd_azf3328_mixer_mute_control(
561 return snd_azf3328_mixer_mute_control(
574 snd_azf3328_mixer_mute_control_master(chip, 1);
578 #ifdef AZF_USE_AC97_LAYER
581 snd_azf3328_mixer_ac97_map_unsupported(
unsigned short reg,
const char *
mode)
585 "azt3328: missing %s emulation for AC97 register 0x%02x!\n",
593 #define AZF_REG_MASK 0x3f
594 #define AZF_AC97_REG_UNSUPPORTED 0x8000
595 #define AZF_AC97_REG_REAL_IO_READ 0x4000
596 #define AZF_AC97_REG_REAL_IO_WRITE 0x2000
597 #define AZF_AC97_REG_REAL_IO_RW \
598 (AZF_AC97_REG_REAL_IO_READ | AZF_AC97_REG_REAL_IO_WRITE)
599 #define AZF_AC97_REG_EMU_IO_READ 0x0400
600 #define AZF_AC97_REG_EMU_IO_WRITE 0x0200
601 #define AZF_AC97_REG_EMU_IO_RW \
602 (AZF_AC97_REG_EMU_IO_READ | AZF_AC97_REG_EMU_IO_WRITE)
603 static unsigned short
604 snd_azf3328_mixer_ac97_map_reg_idx(
unsigned short reg)
606 static const struct {
607 unsigned short azf_reg;
608 } azf_reg_mapper[] = {
648 unsigned short reg_idx = reg / 2;
649 reg_azf = azf_reg_mapper[reg_idx].azf_reg;
678 static const unsigned short
679 azf_emulated_ac97_caps =
694 static const unsigned short
695 azf_emulated_ac97_powerdown =
709 static const unsigned int
710 azf_emulated_ac97_vendor_id = 0x415a5401;
712 static unsigned short
713 snd_azf3328_mixer_ac97_read(
struct snd_ac97 *ac97,
unsigned short reg_ac97)
716 unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
718 bool unsupported = 0;
721 "snd_azf3328_mixer_ac97_read reg_ac97 %u\n",
728 reg_val = snd_azf3328_mixer_inw(chip,
745 reg_val |= azf_emulated_ac97_caps;
748 reg_val |= azf_emulated_ac97_powerdown;
756 reg_val = azf_emulated_ac97_vendor_id >> 16;
759 reg_val = azf_emulated_ac97_vendor_id & 0xffff;
768 snd_azf3328_mixer_ac97_map_unsupported(reg_ac97,
"read");
774 snd_azf3328_mixer_ac97_write(
struct snd_ac97 *ac97,
775 unsigned short reg_ac97,
unsigned short val)
778 unsigned short reg_azf = snd_azf3328_mixer_ac97_map_reg_idx(reg_ac97);
779 bool unsupported = 0;
782 "snd_azf3328_mixer_ac97_write reg_ac97 %u val %u\n",
785 if (reg_azf & AZF_AC97_REG_UNSUPPORTED)
789 snd_azf3328_mixer_outw(
817 snd_azf3328_mixer_ac97_map_unsupported(reg_ac97,
"write");
826 .write = snd_azf3328_mixer_ac97_write,
827 .read = snd_azf3328_mixer_ac97_read,
831 memset(&ac97, 0,
sizeof(ac97));
862 snd_azf3328_mixer_write_volume_gradually(
const struct snd_azf3328 *chip,
864 unsigned char dst_vol_left,
865 unsigned char dst_vol_right,
866 int chan_sel,
int delay
870 unsigned char curr_vol_left = 0, curr_vol_right = 0;
871 int left_change = 0, right_change = 0;
876 curr_vol_left =
inb(portbase + 1);
882 dst_vol_left &= ~AZF_MUTE_BIT;
884 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
888 curr_vol_right =
inb(portbase + 0);
890 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
895 if (curr_vol_left != dst_vol_left) {
896 curr_vol_left += left_change;
897 outb(curr_vol_left, portbase + 1);
902 if (curr_vol_right != dst_vol_right) {
903 curr_vol_right += right_change;
908 outb(curr_vol_right, portbase + 0);
914 }
while ((left_change) || (right_change));
921 struct azf3328_mixer_reg {
923 unsigned int lchan_shift, rchan_shift;
925 unsigned int invert: 1;
926 unsigned int stereo: 1;
927 unsigned int enum_c: 4;
930 #define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
931 ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
937 static void snd_azf3328_mixer_reg_decode(
struct azf3328_mixer_reg *
r,
unsigned long val)
940 r->lchan_shift = (val >> 8) & 0x0f;
941 r->rchan_shift = (val >> 12) & 0x0f;
942 r->mask = (val >> 16) & 0xff;
943 r->invert = (val >> 24) & 1;
944 r->stereo = (val >> 25) & 1;
945 r->enum_c = (val >> 26) & 0x0f;
952 #define AZF3328_MIXER_SWITCH(xname, reg, shift, invert) \
953 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
954 .info = snd_azf3328_info_mixer, \
955 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
956 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0x1, invert, 0, 0), \
959 #define AZF3328_MIXER_VOL_STEREO(xname, reg, mask, invert) \
960 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
961 .info = snd_azf3328_info_mixer, \
962 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
963 .private_value = COMPOSE_MIXER_REG(reg, 8, 0, mask, invert, 1, 0), \
966 #define AZF3328_MIXER_VOL_MONO(xname, reg, mask, is_right_chan) \
967 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
968 .info = snd_azf3328_info_mixer, \
969 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
970 .private_value = COMPOSE_MIXER_REG(reg, is_right_chan ? 0 : 8, 0, mask, 1, 0, 0), \
973 #define AZF3328_MIXER_VOL_SPECIAL(xname, reg, mask, shift, invert) \
974 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
975 .info = snd_azf3328_info_mixer, \
976 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
977 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, mask, invert, 0, 0), \
980 #define AZF3328_MIXER_ENUM(xname, reg, enum_c, shift) \
981 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
982 .info = snd_azf3328_info_mixer_enum, \
983 .get = snd_azf3328_get_mixer_enum, .put = snd_azf3328_put_mixer_enum, \
984 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
991 struct azf3328_mixer_reg reg;
995 uinfo->
type = reg.mask == 1 ?
997 uinfo->
count = reg.stereo + 1;
1009 struct azf3328_mixer_reg reg;
1013 snd_azf3328_mixer_reg_decode(®, kcontrol->
private_value);
1015 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
1016 val = (oreg >> reg.lchan_shift) & reg.mask;
1018 val = reg.mask -
val;
1019 ucontrol->
value.integer.value[0] =
val;
1021 val = (oreg >> reg.rchan_shift) & reg.mask;
1023 val = reg.mask -
val;
1024 ucontrol->
value.integer.value[1] =
val;
1027 "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
1029 ucontrol->
value.integer.value[0], ucontrol->
value.integer.value[1],
1030 reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
1040 struct azf3328_mixer_reg reg;
1044 snd_azf3328_mixer_reg_decode(®, kcontrol->
private_value);
1045 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
1046 val = ucontrol->
value.integer.value[0] & reg.mask;
1048 val = reg.mask -
val;
1049 nreg = oreg & ~(reg.mask << reg.lchan_shift);
1050 nreg |= (val << reg.lchan_shift);
1052 val = ucontrol->
value.integer.value[1] & reg.mask;
1054 val = reg.mask -
val;
1055 nreg &= ~(reg.mask << reg.rchan_shift);
1056 nreg |= (val << reg.rchan_shift);
1058 if (reg.mask >= 0x07)
1059 snd_azf3328_mixer_write_volume_gradually(
1060 chip, reg.reg, nreg >> 8, nreg & 0xff,
1062 SET_CHAN_LEFT|SET_CHAN_RIGHT,
1065 snd_azf3328_mixer_outw(chip, reg.reg, nreg);
1068 "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
1069 reg.reg, ucontrol->
value.integer.value[0], ucontrol->
value.integer.value[1],
1070 oreg, reg.lchan_shift, reg.rchan_shift,
1071 nreg, snd_azf3328_mixer_inw(chip, reg.reg));
1073 return (nreg != oreg);
1077 snd_azf3328_info_mixer_enum(
struct snd_kcontrol *kcontrol,
1080 static const char *
const texts1[] = {
1083 static const char *
const texts2[] = {
1086 static const char *
const texts3[] = {
1087 "Mic",
"CD",
"Video",
"Aux",
1088 "Line",
"Mix",
"Mix Mono",
"Phone"
1090 static const char *
const texts4[] = {
1093 struct azf3328_mixer_reg reg;
1094 const char *
const *
p =
NULL;
1096 snd_azf3328_mixer_reg_decode(®, kcontrol->
private_value);
1103 switch(reg.lchan_shift) {
1123 snd_azf3328_get_mixer_enum(
struct snd_kcontrol *kcontrol,
1127 struct azf3328_mixer_reg reg;
1130 snd_azf3328_mixer_reg_decode(®, kcontrol->
private_value);
1131 val = snd_azf3328_mixer_inw(chip, reg.reg);
1133 ucontrol->
value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
1134 ucontrol->
value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
1136 ucontrol->
value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
1139 reg.reg, val, ucontrol->
value.enumerated.item[0], ucontrol->
value.enumerated.item[1],
1140 reg.lchan_shift, reg.enum_c);
1145 snd_azf3328_put_mixer_enum(
struct snd_kcontrol *kcontrol,
1149 struct azf3328_mixer_reg reg;
1152 snd_azf3328_mixer_reg_decode(®, kcontrol->
private_value);
1153 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
1156 if (ucontrol->
value.enumerated.item[0] > reg.enum_c - 1
U ||
1157 ucontrol->
value.enumerated.item[1] > reg.enum_c - 1
U)
1159 val = (ucontrol->
value.enumerated.item[0] << 8) |
1160 (ucontrol->
value.enumerated.item[1] << 0);
1162 if (ucontrol->
value.enumerated.item[0] > reg.enum_c - 1
U)
1164 val &= ~((reg.enum_c - 1) << reg.lchan_shift);
1165 val |= (ucontrol->
value.enumerated.item[0] << reg.lchan_shift);
1167 snd_azf3328_mixer_outw(chip, reg.reg, val);
1171 return (nreg != oreg);
1178 AZF3328_MIXER_VOL_STEREO(
"PCM Playback Volume",
1180 AZF3328_MIXER_SWITCH(
"PCM 3D Bypass Playback Switch",
1189 AZF3328_MIXER_SWITCH(
"Mic Playback Switch",
IDX_MIXER_MIC, 15, 1),
1190 AZF3328_MIXER_VOL_MONO(
"Mic Playback Volume",
IDX_MIXER_MIC, 0x1f, 1),
1191 AZF3328_MIXER_SWITCH(
"Mic Boost (+20dB)",
IDX_MIXER_MIC, 6, 0),
1193 AZF3328_MIXER_VOL_STEREO(
"Line Playback Volume",
IDX_MIXER_LINEIN, 0x1f, 1),
1195 AZF3328_MIXER_VOL_SPECIAL(
"Beep Playback Volume",
IDX_MIXER_PCBEEP, 0x0f, 1, 1),
1196 AZF3328_MIXER_SWITCH(
"Video Playback Switch",
IDX_MIXER_VIDEO, 15, 1),
1197 AZF3328_MIXER_VOL_STEREO(
"Video Playback Volume",
IDX_MIXER_VIDEO, 0x1f, 1),
1198 AZF3328_MIXER_SWITCH(
"Aux Playback Switch",
IDX_MIXER_AUX, 15, 1),
1199 AZF3328_MIXER_VOL_STEREO(
"Aux Playback Volume",
IDX_MIXER_AUX, 0x1f, 1),
1232 static u16 __devinitdata snd_azf3328_init_values[][2] = {
1266 for (idx = 0; idx <
ARRAY_SIZE(snd_azf3328_init_values); ++
idx) {
1267 snd_azf3328_mixer_outw(chip,
1268 snd_azf3328_init_values[idx][0],
1269 snd_azf3328_init_values[idx][1]);
1273 sw = snd_azf3328_mixer_controls;
1274 for (idx = 0; idx <
ARRAY_SIZE(snd_azf3328_mixer_controls);
1310 unsigned int format_width,
1314 unsigned long flags;
1355 if (format_width == 16)
1381 spin_unlock_irqrestore(codec->
lock, flags);
1393 snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1);
1397 snd_azf3328_ctrl_reg_6AH_update(
struct snd_azf3328 *chip,
1413 snd_azf3328_ctrl_enable_codecs(
struct snd_azf3328 *chip,
bool enable)
1418 snd_azf3328_ctrl_reg_6AH_update(
1424 snd_azf3328_ctrl_codec_activity(
struct snd_azf3328 *chip,
1433 "codec_activity: %s codec, enable %d, need_change %d\n",
1434 codec->
name, enable, need_change
1437 static const struct {
1456 ((!chip->
codecs[peer_codecs[codec_type].other1]
1458 && (!chip->
codecs[peer_codecs[codec_type].other2]
1462 snd_azf3328_ctrl_enable_codecs(chip, enable);
1467 snd_azf3328_codec_setfmt_lowpower(codec);
1475 unsigned int period_bytes,
1476 unsigned int buffer_bytes
1480 WARN_ONCE(period_bytes & 1,
"odd period length!?\n");
1481 WARN_ONCE(buffer_bytes != 2 * period_bytes,
1482 "missed our input expectations! %u vs. %u\n",
1483 buffer_bytes, period_bytes);
1487 unsigned long flags;
1491 struct codec_setup_io {
1497 area_length = buffer_bytes/2;
1499 setup_io.dma_start_1 = addr;
1500 setup_io.dma_start_2 = addr+area_length;
1503 "setdma: buffers %08
x[%
u] / %08
x[%
u], %u, %u\
n",
1504 setup_io.dma_start_1, area_length,
1505 setup_io.dma_start_2, area_length,
1506 period_bytes, buffer_bytes);
1517 setup_io.dma_lengths = (area_length << 16) | (area_length);
1520 snd_azf3328_codec_outl_multi(
1523 spin_unlock_irqrestore(codec->lock, flags);
1534 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1535 unsigned int count = snd_pcm_lib_period_bytes(substream);
1543 snd_azf3328_codec_setfmt(codec,
1547 snd_azf3328_codec_setdmaa(codec,
1562 bool previously_muted = 0;
1571 if (is_main_mixer_playback_codec) {
1574 snd_azf3328_mixer_mute_control_pcm(
1579 snd_azf3328_codec_setfmt(codec,
1584 spin_lock(codec->
lock);
1594 spin_unlock(codec->
lock);
1596 snd_azf3328_codec_setdmaa(codec, runtime->
dma_addr,
1597 snd_pcm_lib_period_bytes(substream),
1598 snd_pcm_lib_buffer_bytes(substream)
1601 spin_lock(codec->
lock);
1625 spin_unlock(codec->
lock);
1626 snd_azf3328_ctrl_codec_activity(chip, codec->
type, 1);
1628 if (is_main_mixer_playback_codec) {
1630 if (!previously_muted)
1631 snd_azf3328_mixer_mute_control_pcm(
1641 spin_lock(codec->
lock);
1644 snd_azf3328_codec_inw(
1648 spin_unlock(codec->
lock);
1653 if (is_main_mixer_playback_codec) {
1656 snd_azf3328_mixer_mute_control_pcm(
1661 spin_lock(codec->
lock);
1676 spin_unlock(codec->
lock);
1677 snd_azf3328_ctrl_codec_activity(chip, codec->
type, 0);
1679 if (is_main_mixer_playback_codec) {
1681 if (!previously_muted)
1682 snd_azf3328_mixer_mute_control_pcm(
1693 snd_azf3328_codec_inw(
1718 substream->
runtime->private_data;
1725 #ifdef QUERY_HARDWARE
1726 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1730 frmres = bytes_to_frames( substream->
runtime, result);
1732 jiffies, codec->
name, result, frmres);
1738 #ifdef SUPPORT_GAMEPORT
1740 snd_azf3328_gameport_irq_enable(
struct snd_azf3328 *chip,
1744 snd_azf3328_io_reg_setb(
1752 snd_azf3328_gameport_legacy_address_enable(
struct snd_azf3328 *chip,
1756 snd_azf3328_io_reg_setb(
1764 snd_azf3328_gameport_set_counter_frequency(
struct snd_azf3328 *chip,
1765 unsigned int freq_cfg
1768 snd_azf3328_io_reg_setb(
1773 snd_azf3328_io_reg_setb(
1781 snd_azf3328_gameport_axis_circuit_enable(
struct snd_azf3328 *chip,
bool enable)
1783 snd_azf3328_ctrl_reg_6AH_update(
1789 snd_azf3328_gameport_interrupt(
struct snd_azf3328 *chip)
1804 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1818 snd_azf3328_gameport_set_counter_frequency(chip,
1820 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1826 snd_azf3328_gameport_close(
struct gameport *gameport)
1828 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1831 snd_azf3328_gameport_set_counter_frequency(chip,
1833 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1837 snd_azf3328_gameport_cooked_read(
struct gameport *gameport,
1842 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1845 unsigned long flags;
1852 *buttons = (~(
val) >> 4) & 0xf;
1868 val = (i << 4) | 0x0f;
1871 chip->axes[
i] = snd_azf3328_game_inw(
1887 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1889 for (i = 0; i <
ARRAY_SIZE(chip->axes); i++) {
1890 axes[
i] = chip->axes[
i];
1891 if (axes[i] == 0xffff)
1896 axes[0], axes[1], axes[2], axes[3], *buttons
1905 struct gameport *
gp;
1907 chip->gameport = gp = gameport_allocate_port();
1913 gameport_set_name(gp,
"AZF3328 Gameport");
1915 gameport_set_dev_parent(gp, &chip->
pci->dev);
1917 gameport_set_port_data(gp, chip);
1919 gp->
open = snd_azf3328_gameport_open;
1920 gp->
close = snd_azf3328_gameport_close;
1922 gp->
cooked_read = snd_azf3328_gameport_cooked_read;
1925 snd_azf3328_gameport_legacy_address_enable(chip, 0);
1927 snd_azf3328_gameport_set_counter_frequency(chip,
1929 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1931 gameport_register_port(chip->gameport);
1937 snd_azf3328_gameport_free(
struct snd_azf3328 *chip)
1939 if (chip->gameport) {
1941 chip->gameport =
NULL;
1943 snd_azf3328_gameport_irq_enable(chip, 0);
1949 snd_azf3328_gameport_free(
struct snd_azf3328 *chip) { }
1951 snd_azf3328_gameport_interrupt(
struct snd_azf3328 *chip)
1960 snd_azf3328_irq_log_unknown_type(
u8 which)
1963 "azt3328: unknown IRQ type (%x) occurred, please report!\n",
1979 ++codec_type, ++
codec) {
1982 if (!(status & (1 << codec_type)))
1985 spin_lock(codec->
lock);
1989 spin_unlock(codec->
lock);
1996 snd_azf3328_codec_inl(
2003 snd_azf3328_irq_log_unknown_type(which);
2008 snd_azf3328_interrupt(
int irq,
void *
dev_id)
2026 "irq_count %ld! IDX_IO_IRQSTATUS %04x\n",
2046 snd_azf3328_pcm_interrupt(chip->
codecs, status);
2049 snd_azf3328_gameport_interrupt(chip);
2082 .rate_min = AZF_FREQ_4000,
2083 .rate_max = AZF_FREQ_66200,
2086 .buffer_bytes_max = (64*1024),
2102 static unsigned int snd_azf3328_fixed_rates[] = {
2120 .count =
ARRAY_SIZE(snd_azf3328_fixed_rates),
2121 .list = snd_azf3328_fixed_rates,
2140 runtime->
hw = snd_azf3328_hardware;
2143 &snd_azf3328_hw_constraints_rates);
2172 substream->
runtime->private_data;
2182 static struct snd_pcm_ops snd_azf3328_playback_ops = {
2183 .open = snd_azf3328_pcm_playback_open,
2184 .close = snd_azf3328_pcm_close,
2186 .hw_params = snd_azf3328_hw_params,
2187 .hw_free = snd_azf3328_hw_free,
2188 .prepare = snd_azf3328_pcm_prepare,
2189 .trigger = snd_azf3328_pcm_trigger,
2190 .pointer = snd_azf3328_pcm_pointer
2193 static struct snd_pcm_ops snd_azf3328_capture_ops = {
2194 .open = snd_azf3328_pcm_capture_open,
2195 .close = snd_azf3328_pcm_close,
2197 .hw_params = snd_azf3328_hw_params,
2198 .hw_free = snd_azf3328_hw_free,
2199 .prepare = snd_azf3328_pcm_prepare,
2200 .trigger = snd_azf3328_pcm_trigger,
2201 .pointer = snd_azf3328_pcm_pointer
2204 static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
2205 .open = snd_azf3328_pcm_i2s_out_open,
2206 .close = snd_azf3328_pcm_close,
2208 .hw_params = snd_azf3328_hw_params,
2209 .hw_free = snd_azf3328_hw_free,
2210 .prepare = snd_azf3328_pcm_prepare,
2211 .trigger = snd_azf3328_pcm_trigger,
2212 .pointer = snd_azf3328_pcm_pointer
2218 enum { AZF_PCMDEV_STD, AZF_PCMDEV_I2S_OUT, NUM_AZF_PCMDEVS };
2230 &snd_azf3328_playback_ops);
2232 &snd_azf3328_capture_ops);
2250 &snd_azf3328_i2s_out_ops);
2281 unsigned long flags;
2299 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2305 snd_azf3328_timer_stop(
struct snd_timer *timer)
2308 unsigned long flags;
2321 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2328 snd_azf3328_timer_precise_resolution(
struct snd_timer *timer,
2329 unsigned long *num,
unsigned long *
den)
2333 *den = 1024000 / seqtimer_scaling;
2342 .start = snd_azf3328_timer_start,
2343 .stop = snd_azf3328_timer_stop,
2344 .precise_resolution = snd_azf3328_timer_precise_resolution,
2357 tid.card = chip->
card->number;
2361 snd_azf3328_timer_hw.
resolution *= seqtimer_scaling;
2362 snd_azf3328_timer_hw.
ticks /= seqtimer_scaling;
2370 timer->
hw = snd_azf3328_timer_hw;
2374 snd_azf3328_timer_stop(timer);
2391 snd_azf3328_mixer_reset(chip);
2393 snd_azf3328_timer_stop(chip->
timer);
2394 snd_azf3328_gameport_free(chip);
2409 snd_azf3328_dev_free(
struct snd_device *device)
2412 return snd_azf3328_free(chip);
2418 snd_azf3328_test_bit(
unsigned unsigned reg,
int bit)
2420 unsigned char val, valoff, valon;
2424 outb(val & ~(1 << bit), reg);
2427 outb(val|(1 << bit), reg);
2433 reg, bit, val, valoff, valon
2439 snd_azf3328_debug_show_ports(
const struct snd_azf3328 *chip)
2445 "ctrl_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
2446 "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
2452 snd_azf3328_game_inb(chip, 0),
2453 snd_azf3328_game_inb(chip, 1),
2454 snd_azf3328_game_inb(chip, 2),
2455 snd_azf3328_game_inb(chip, 3),
2456 snd_azf3328_game_inb(chip, 4),
2457 snd_azf3328_game_inb(chip, 5)
2460 for (tmp = 0; tmp < 0x07; tmp += 1)
2463 for (tmp = 0; tmp <= 0x07; tmp += 1)
2465 tmp,
inb(0x200 + tmp),
inb(0x208 + tmp));
2467 for (tmp = 0; tmp <= 0x01; tmp += 1)
2469 "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
2470 "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
2482 tmp, snd_azf3328_ctrl_inw(chip, tmp)
2487 tmp, snd_azf3328_mixer_inw(chip, tmp)
2493 snd_azf3328_create(
struct snd_card *card,
2501 .dev_free = snd_azf3328_dev_free,
2525 pci_set_consistent_dma_mask(pci,
DMA_BIT_MASK(24)) < 0) {
2527 "24bit PCI busmaster DMA\n"
2547 codec_setup->
name =
"PLAYBACK";
2553 codec_setup->
name =
"CAPTURE";
2559 codec_setup->
name =
"I2S_OUT";
2571 snd_azf3328_debug_show_ports(chip);
2578 err = snd_azf3328_mixer_new(chip);
2589 &chip->
codecs[codec_type];
2594 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
2596 spin_lock_irq(codec->
lock);
2599 spin_unlock_irq(codec->
lock);
2611 snd_azf3328_free(chip);
2645 err = snd_azf3328_create(card, pci, pci_id->
driver_data, &chip);
2666 err = snd_azf3328_timer(chip, 0);
2670 err = snd_azf3328_pcm(chip);
2699 "azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
2700 "azt3328: Hardware was completely undocumented, unfortunately.\n"
2701 "azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
2702 "azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
2703 1024000 / seqtimer_scaling, seqtimer_scaling);
2706 snd_azf3328_gameport(chip, dev);
2708 pci_set_drvdata(pci, card);
2724 snd_azf3328_remove(
struct pci_dev *pci)
2728 pci_set_drvdata(pci,
NULL);
2732 #ifdef CONFIG_PM_SLEEP
2738 for (reg = 0; reg <
count; ++
reg) {
2739 *saved_regs =
inl(io_addr);
2741 io_addr, *saved_regs);
2743 io_addr +=
sizeof(*saved_regs);
2748 snd_azf3328_resume_regs(
const u32 *saved_regs,
2749 unsigned long io_addr,
2755 for (reg = 0; reg <
count; ++
reg) {
2756 outl(*saved_regs, io_addr);
2758 io_addr, *saved_regs,
inl(io_addr));
2760 io_addr +=
sizeof(*saved_regs);
2765 snd_azf3328_suspend_ac97(
struct snd_azf3328 *chip)
2767 #ifdef AZF_USE_AC97_LAYER
2768 snd_ac97_suspend(chip->
ac97);
2770 snd_azf3328_suspend_regs(chip->
mixer_io,
2771 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2774 snd_azf3328_mixer_mute_control_master(chip, 1);
2775 snd_azf3328_mixer_mute_control_pcm(chip, 1);
2780 snd_azf3328_resume_ac97(
const struct snd_azf3328 *chip)
2782 #ifdef AZF_USE_AC97_LAYER
2783 snd_ac97_resume(chip->
ac97);
2785 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->
mixer_io,
2797 snd_azf3328_suspend(
struct device *dev)
2802 u16 *saved_regs_ctrl_u16;
2810 snd_azf3328_suspend_ac97(chip);
2812 snd_azf3328_suspend_regs(chip->
ctrl_io,
2813 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
2816 saved_regs_ctrl_u16 = (
u16 *)chip->saved_regs_ctrl;
2819 snd_azf3328_suspend_regs(chip->
game_io,
2820 ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game);
2821 snd_azf3328_suspend_regs(chip->
mpu_io,
2822 ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu);
2823 snd_azf3328_suspend_regs(chip->
opl3_io,
2824 ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3);
2833 snd_azf3328_resume(
struct device *dev)
2843 "disabling device\n");
2849 snd_azf3328_resume_regs(chip->saved_regs_game, chip->
game_io,
2851 snd_azf3328_resume_regs(chip->saved_regs_mpu, chip->
mpu_io,
2853 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->
opl3_io,
2856 snd_azf3328_resume_ac97(chip);
2858 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->
ctrl_io,
2865 static SIMPLE_DEV_PM_OPS(snd_azf3328_pm, snd_azf3328_suspend, snd_azf3328_resume);
2866 #define SND_AZF3328_PM_OPS &snd_azf3328_pm
2868 #define SND_AZF3328_PM_OPS NULL
2872 .name = KBUILD_MODNAME,
2873 .id_table = snd_azf3328_ids,
2874 .probe = snd_azf3328_probe,