GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / sound / pci / azt3328.c
blobb0454526ab3e39de2332d2a547be954e827073c3
3 #include <asm/io.h>
4 #include <linux/init.h>
5 #include <linux/pci.h>
6 #include <linux/delay.h>
7 #include <linux/slab.h>
8 #include <linux/gameport.h>
9 #include <linux/moduleparam.h>
10 #include <linux/dma-mapping.h>
11 #include <sound/core.h>
12 #include <sound/control.h>
13 #include <sound/pcm.h>
14 #include <sound/rawmidi.h>
15 #include <sound/mpu401.h>
16 #include <sound/opl3.h>
17 #include <sound/initval.h>
18 #include "azt3328.h"
20 MODULE_AUTHOR("Andreas Mohr <andi AT lisas.de>");
21 MODULE_DESCRIPTION("Aztech AZF3328 (PCI168)");
22 MODULE_LICENSE("GPL");
23 MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
25 #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
26 #define SUPPORT_GAMEPORT 1
27 #endif
29 /* === Debug settings ===
30 Further diagnostic functionality than the settings below
31 does not need to be provided, since one can easily write a bash script
32 to dump the card's I/O ports (those listed in lspci -v -v):
33 function dump()
35 local descr=$1; local addr=$2; local count=$3
37 echo "${descr}: ${count} @ ${addr}:"
38 dd if=/dev/port skip=$[${addr}] count=${count} bs=1 2>/dev/null| hexdump -C
40 and then use something like
41 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
42 "dump codec00 0xa800 32", "dump mixer 0xb800 64", "dump synth 0xbc00 8",
43 possibly within a "while true; do ... sleep 1; done" loop.
44 Tweaking ports could be done using
45 VALSTRING="`printf "%02x" $value`"
46 printf "\x""$VALSTRING"|dd of=/dev/port seek=$[${addr}] bs=1 2>/dev/null
49 #define DEBUG_MISC 0
50 #define DEBUG_CALLS 0
51 #define DEBUG_MIXER 0
52 #define DEBUG_CODEC 0
53 #define DEBUG_IO 0
54 #define DEBUG_TIMER 0
55 #define DEBUG_GAME 0
56 #define DEBUG_PM 0
57 #define MIXER_TESTING 0
59 #if DEBUG_MISC
60 #define snd_azf3328_dbgmisc(format, args...) printk(KERN_DEBUG format, ##args)
61 #else
62 #define snd_azf3328_dbgmisc(format, args...)
63 #endif
65 #if DEBUG_CALLS
66 #define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
67 #define snd_azf3328_dbgcallenter() printk(KERN_DEBUG "--> %s\n", __func__)
68 #define snd_azf3328_dbgcallleave() printk(KERN_DEBUG "<-- %s\n", __func__)
69 #else
70 #define snd_azf3328_dbgcalls(format, args...)
71 #define snd_azf3328_dbgcallenter()
72 #define snd_azf3328_dbgcallleave()
73 #endif
75 #if DEBUG_MIXER
76 #define snd_azf3328_dbgmixer(format, args...) printk(KERN_DEBUG format, ##args)
77 #else
78 #define snd_azf3328_dbgmixer(format, args...)
79 #endif
81 #if DEBUG_CODEC
82 #define snd_azf3328_dbgcodec(format, args...) printk(KERN_DEBUG format, ##args)
83 #else
84 #define snd_azf3328_dbgcodec(format, args...)
85 #endif
87 #if DEBUG_MISC
88 #define snd_azf3328_dbgtimer(format, args...) printk(KERN_DEBUG format, ##args)
89 #else
90 #define snd_azf3328_dbgtimer(format, args...)
91 #endif
93 #if DEBUG_GAME
94 #define snd_azf3328_dbggame(format, args...) printk(KERN_DEBUG format, ##args)
95 #else
96 #define snd_azf3328_dbggame(format, args...)
97 #endif
99 #if DEBUG_PM
100 #define snd_azf3328_dbgpm(format, args...) printk(KERN_DEBUG format, ##args)
101 #else
102 #define snd_azf3328_dbgpm(format, args...)
103 #endif
105 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
106 module_param_array(index, int, NULL, 0444);
107 MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
109 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
110 module_param_array(id, charp, NULL, 0444);
111 MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard.");
113 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
114 module_param_array(enable, bool, NULL, 0444);
115 MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard.");
117 static int seqtimer_scaling = 128;
118 module_param(seqtimer_scaling, int, 0444);
119 MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
121 struct snd_azf3328_codec_data {
122 unsigned long io_base;
123 struct snd_pcm_substream *substream;
124 bool running;
125 const char *name;
128 enum snd_azf3328_codec_type {
129 AZF_CODEC_PLAYBACK = 0,
130 AZF_CODEC_CAPTURE = 1,
131 AZF_CODEC_I2S_OUT = 2,
134 struct snd_azf3328 {
135 /* often-used fields towards beginning, then grouped */
137 unsigned long ctrl_io; /* usually 0xb000, size 128 */
138 unsigned long game_io; /* usually 0xb400, size 8 */
139 unsigned long mpu_io; /* usually 0xb800, size 4 */
140 unsigned long opl3_io; /* usually 0xbc00, size 8 */
141 unsigned long mixer_io; /* usually 0xc000, size 64 */
143 spinlock_t reg_lock;
145 struct snd_timer *timer;
147 struct snd_pcm *pcm[3];
149 /* playback, recording and I2S out codecs */
150 struct snd_azf3328_codec_data codecs[3];
152 struct snd_card *card;
153 struct snd_rawmidi *rmidi;
155 #ifdef SUPPORT_GAMEPORT
156 struct gameport *gameport;
157 u16 axes[4];
158 #endif
160 struct pci_dev *pci;
161 int irq;
163 /* register 0x6a is write-only, thus need to remember setting.
164 * If we need to add more registers here, then we might try to fold this
165 * into some transparent combined shadow register handling with
166 * CONFIG_PM register storage below, but that's slightly difficult. */
167 u16 shadow_reg_ctrl_6AH;
169 #ifdef CONFIG_PM
170 /* register value containers for power management
171 * Note: not always full I/O range preserved (similar to Win driver!) */
172 u32 saved_regs_ctrl[AZF_ALIGN(AZF_IO_SIZE_CTRL_PM) / 4];
173 u32 saved_regs_game[AZF_ALIGN(AZF_IO_SIZE_GAME_PM) / 4];
174 u32 saved_regs_mpu[AZF_ALIGN(AZF_IO_SIZE_MPU_PM) / 4];
175 u32 saved_regs_opl3[AZF_ALIGN(AZF_IO_SIZE_OPL3_PM) / 4];
176 u32 saved_regs_mixer[AZF_ALIGN(AZF_IO_SIZE_MIXER_PM) / 4];
177 #endif
180 static DEFINE_PCI_DEVICE_TABLE(snd_azf3328_ids) = {
181 { 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
182 { 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
183 { 0, }
186 MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
189 static int
190 snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
192 u8 prev = inb(reg), new;
194 new = (do_set) ? (prev|mask) : (prev & ~mask);
195 /* we need to always write the new value no matter whether it differs
196 * or not, since some register bits don't indicate their setting */
197 outb(new, reg);
198 if (new != prev)
199 return 1;
201 return 0;
204 static inline void
205 snd_azf3328_codec_outb(const struct snd_azf3328_codec_data *codec,
206 unsigned reg,
207 u8 value
210 outb(value, codec->io_base + reg);
213 static inline u8
214 snd_azf3328_codec_inb(const struct snd_azf3328_codec_data *codec, unsigned reg)
216 return inb(codec->io_base + reg);
219 static inline void
220 snd_azf3328_codec_outw(const struct snd_azf3328_codec_data *codec,
221 unsigned reg,
222 u16 value
225 outw(value, codec->io_base + reg);
228 static inline u16
229 snd_azf3328_codec_inw(const struct snd_azf3328_codec_data *codec, unsigned reg)
231 return inw(codec->io_base + reg);
234 static inline void
235 snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
236 unsigned reg,
237 u32 value
240 outl(value, codec->io_base + reg);
243 static inline u32
244 snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
246 return inl(codec->io_base + reg);
249 static inline void
250 snd_azf3328_ctrl_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
252 outb(value, chip->ctrl_io + reg);
255 static inline u8
256 snd_azf3328_ctrl_inb(const struct snd_azf3328 *chip, unsigned reg)
258 return inb(chip->ctrl_io + reg);
261 static inline void
262 snd_azf3328_ctrl_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
264 outw(value, chip->ctrl_io + reg);
267 static inline void
268 snd_azf3328_ctrl_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
270 outl(value, chip->ctrl_io + reg);
273 static inline void
274 snd_azf3328_game_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
276 outb(value, chip->game_io + reg);
279 static inline void
280 snd_azf3328_game_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
282 outw(value, chip->game_io + reg);
285 static inline u8
286 snd_azf3328_game_inb(const struct snd_azf3328 *chip, unsigned reg)
288 return inb(chip->game_io + reg);
291 static inline u16
292 snd_azf3328_game_inw(const struct snd_azf3328 *chip, unsigned reg)
294 return inw(chip->game_io + reg);
297 static inline void
298 snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
300 outw(value, chip->mixer_io + reg);
303 static inline u16
304 snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
306 return inw(chip->mixer_io + reg);
309 #define AZF_MUTE_BIT 0x80
311 static bool
312 snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
313 unsigned reg, bool do_mute
316 unsigned long portbase = chip->mixer_io + reg + 1;
317 bool updated;
319 /* the mute bit is on the *second* (i.e. right) register of a
320 * left/right channel setting */
321 updated = snd_azf3328_io_reg_setb(portbase, AZF_MUTE_BIT, do_mute);
323 /* indicate whether it was muted before */
324 return (do_mute) ? !updated : updated;
327 static void
328 snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip,
329 unsigned reg,
330 unsigned char dst_vol_left,
331 unsigned char dst_vol_right,
332 int chan_sel, int delay
335 unsigned long portbase = chip->mixer_io + reg;
336 unsigned char curr_vol_left = 0, curr_vol_right = 0;
337 int left_change = 0, right_change = 0;
339 snd_azf3328_dbgcallenter();
341 if (chan_sel & SET_CHAN_LEFT) {
342 curr_vol_left = inb(portbase + 1);
344 /* take care of muting flag contained in left channel */
345 if (curr_vol_left & AZF_MUTE_BIT)
346 dst_vol_left |= AZF_MUTE_BIT;
347 else
348 dst_vol_left &= ~AZF_MUTE_BIT;
350 left_change = (curr_vol_left > dst_vol_left) ? -1 : 1;
353 if (chan_sel & SET_CHAN_RIGHT) {
354 curr_vol_right = inb(portbase + 0);
356 right_change = (curr_vol_right > dst_vol_right) ? -1 : 1;
359 do {
360 if (left_change) {
361 if (curr_vol_left != dst_vol_left) {
362 curr_vol_left += left_change;
363 outb(curr_vol_left, portbase + 1);
364 } else
365 left_change = 0;
367 if (right_change) {
368 if (curr_vol_right != dst_vol_right) {
369 curr_vol_right += right_change;
371 /* during volume change, the right channel is crackling
372 * somewhat more than the left channel, unfortunately.
373 * This seems to be a hardware issue. */
374 outb(curr_vol_right, portbase + 0);
375 } else
376 right_change = 0;
378 if (delay)
379 mdelay(delay);
380 } while ((left_change) || (right_change));
381 snd_azf3328_dbgcallleave();
385 * general mixer element
387 struct azf3328_mixer_reg {
388 unsigned reg;
389 unsigned int lchan_shift, rchan_shift;
390 unsigned int mask;
391 unsigned int invert: 1;
392 unsigned int stereo: 1;
393 unsigned int enum_c: 4;
396 #define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
397 ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
398 (mask << 16) | \
399 (invert << 24) | \
400 (stereo << 25) | \
401 (enum_c << 26))
403 static void snd_azf3328_mixer_reg_decode(struct azf3328_mixer_reg *r, unsigned long val)
405 r->reg = val & 0xff;
406 r->lchan_shift = (val >> 8) & 0x0f;
407 r->rchan_shift = (val >> 12) & 0x0f;
408 r->mask = (val >> 16) & 0xff;
409 r->invert = (val >> 24) & 1;
410 r->stereo = (val >> 25) & 1;
411 r->enum_c = (val >> 26) & 0x0f;
415 * mixer switches/volumes
418 #define AZF3328_MIXER_SWITCH(xname, reg, shift, invert) \
419 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
420 .info = snd_azf3328_info_mixer, \
421 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
422 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0x1, invert, 0, 0), \
425 #define AZF3328_MIXER_VOL_STEREO(xname, reg, mask, invert) \
426 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
427 .info = snd_azf3328_info_mixer, \
428 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
429 .private_value = COMPOSE_MIXER_REG(reg, 8, 0, mask, invert, 1, 0), \
432 #define AZF3328_MIXER_VOL_MONO(xname, reg, mask, is_right_chan) \
433 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
434 .info = snd_azf3328_info_mixer, \
435 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
436 .private_value = COMPOSE_MIXER_REG(reg, is_right_chan ? 0 : 8, 0, mask, 1, 0, 0), \
439 #define AZF3328_MIXER_VOL_SPECIAL(xname, reg, mask, shift, invert) \
440 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
441 .info = snd_azf3328_info_mixer, \
442 .get = snd_azf3328_get_mixer, .put = snd_azf3328_put_mixer, \
443 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, mask, invert, 0, 0), \
446 #define AZF3328_MIXER_ENUM(xname, reg, enum_c, shift) \
447 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
448 .info = snd_azf3328_info_mixer_enum, \
449 .get = snd_azf3328_get_mixer_enum, .put = snd_azf3328_put_mixer_enum, \
450 .private_value = COMPOSE_MIXER_REG(reg, shift, 0, 0, 0, 0, enum_c), \
453 static int
454 snd_azf3328_info_mixer(struct snd_kcontrol *kcontrol,
455 struct snd_ctl_elem_info *uinfo)
457 struct azf3328_mixer_reg reg;
459 snd_azf3328_dbgcallenter();
460 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
461 uinfo->type = reg.mask == 1 ?
462 SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
463 uinfo->count = reg.stereo + 1;
464 uinfo->value.integer.min = 0;
465 uinfo->value.integer.max = reg.mask;
466 snd_azf3328_dbgcallleave();
467 return 0;
470 static int
471 snd_azf3328_get_mixer(struct snd_kcontrol *kcontrol,
472 struct snd_ctl_elem_value *ucontrol)
474 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
475 struct azf3328_mixer_reg reg;
476 u16 oreg, val;
478 snd_azf3328_dbgcallenter();
479 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
481 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
482 val = (oreg >> reg.lchan_shift) & reg.mask;
483 if (reg.invert)
484 val = reg.mask - val;
485 ucontrol->value.integer.value[0] = val;
486 if (reg.stereo) {
487 val = (oreg >> reg.rchan_shift) & reg.mask;
488 if (reg.invert)
489 val = reg.mask - val;
490 ucontrol->value.integer.value[1] = val;
492 snd_azf3328_dbgmixer("get: %02x is %04x -> vol %02lx|%02lx "
493 "(shift %02d|%02d, mask %02x, inv. %d, stereo %d)\n",
494 reg.reg, oreg,
495 ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
496 reg.lchan_shift, reg.rchan_shift, reg.mask, reg.invert, reg.stereo);
497 snd_azf3328_dbgcallleave();
498 return 0;
501 static int
502 snd_azf3328_put_mixer(struct snd_kcontrol *kcontrol,
503 struct snd_ctl_elem_value *ucontrol)
505 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
506 struct azf3328_mixer_reg reg;
507 u16 oreg, nreg, val;
509 snd_azf3328_dbgcallenter();
510 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
511 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
512 val = ucontrol->value.integer.value[0] & reg.mask;
513 if (reg.invert)
514 val = reg.mask - val;
515 nreg = oreg & ~(reg.mask << reg.lchan_shift);
516 nreg |= (val << reg.lchan_shift);
517 if (reg.stereo) {
518 val = ucontrol->value.integer.value[1] & reg.mask;
519 if (reg.invert)
520 val = reg.mask - val;
521 nreg &= ~(reg.mask << reg.rchan_shift);
522 nreg |= (val << reg.rchan_shift);
524 if (reg.mask >= 0x07) /* it's a volume control, so better take care */
525 snd_azf3328_mixer_write_volume_gradually(
526 chip, reg.reg, nreg >> 8, nreg & 0xff,
527 /* just set both channels, doesn't matter */
528 SET_CHAN_LEFT|SET_CHAN_RIGHT,
530 else
531 snd_azf3328_mixer_outw(chip, reg.reg, nreg);
533 snd_azf3328_dbgmixer("put: %02x to %02lx|%02lx, "
534 "oreg %04x; shift %02d|%02d -> nreg %04x; after: %04x\n",
535 reg.reg, ucontrol->value.integer.value[0], ucontrol->value.integer.value[1],
536 oreg, reg.lchan_shift, reg.rchan_shift,
537 nreg, snd_azf3328_mixer_inw(chip, reg.reg));
538 snd_azf3328_dbgcallleave();
539 return (nreg != oreg);
542 static int
543 snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_info *uinfo)
546 static const char * const texts1[] = {
547 "Mic1", "Mic2"
549 static const char * const texts2[] = {
550 "Mix", "Mic"
552 static const char * const texts3[] = {
553 "Mic", "CD", "Video", "Aux",
554 "Line", "Mix", "Mix Mono", "Phone"
556 static const char * const texts4[] = {
557 "pre 3D", "post 3D"
559 struct azf3328_mixer_reg reg;
560 const char * const *p = NULL;
562 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
563 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
564 uinfo->count = (reg.reg == IDX_MIXER_REC_SELECT) ? 2 : 1;
565 uinfo->value.enumerated.items = reg.enum_c;
566 if (uinfo->value.enumerated.item > reg.enum_c - 1U)
567 uinfo->value.enumerated.item = reg.enum_c - 1U;
568 if (reg.reg == IDX_MIXER_ADVCTL2) {
569 switch(reg.lchan_shift) {
570 case 8: /* modem out sel */
571 p = texts1;
572 break;
573 case 9: /* mono sel source */
574 p = texts2;
575 break;
576 case 15: /* PCM Out Path */
577 p = texts4;
578 break;
580 } else
581 if (reg.reg == IDX_MIXER_REC_SELECT)
582 p = texts3;
584 strcpy(uinfo->value.enumerated.name, p[uinfo->value.enumerated.item]);
585 return 0;
588 static int
589 snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
590 struct snd_ctl_elem_value *ucontrol)
592 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
593 struct azf3328_mixer_reg reg;
594 unsigned short val;
596 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
597 val = snd_azf3328_mixer_inw(chip, reg.reg);
598 if (reg.reg == IDX_MIXER_REC_SELECT) {
599 ucontrol->value.enumerated.item[0] = (val >> 8) & (reg.enum_c - 1);
600 ucontrol->value.enumerated.item[1] = (val >> 0) & (reg.enum_c - 1);
601 } else
602 ucontrol->value.enumerated.item[0] = (val >> reg.lchan_shift) & (reg.enum_c - 1);
604 snd_azf3328_dbgmixer("get_enum: %02x is %04x -> %d|%d (shift %02d, enum_c %d)\n",
605 reg.reg, val, ucontrol->value.enumerated.item[0], ucontrol->value.enumerated.item[1],
606 reg.lchan_shift, reg.enum_c);
607 return 0;
610 static int
611 snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
612 struct snd_ctl_elem_value *ucontrol)
614 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
615 struct azf3328_mixer_reg reg;
616 u16 oreg, nreg, val;
618 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
619 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
620 val = oreg;
621 if (reg.reg == IDX_MIXER_REC_SELECT) {
622 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U ||
623 ucontrol->value.enumerated.item[1] > reg.enum_c - 1U)
624 return -EINVAL;
625 val = (ucontrol->value.enumerated.item[0] << 8) |
626 (ucontrol->value.enumerated.item[1] << 0);
627 } else {
628 if (ucontrol->value.enumerated.item[0] > reg.enum_c - 1U)
629 return -EINVAL;
630 val &= ~((reg.enum_c - 1) << reg.lchan_shift);
631 val |= (ucontrol->value.enumerated.item[0] << reg.lchan_shift);
633 snd_azf3328_mixer_outw(chip, reg.reg, val);
634 nreg = val;
636 snd_azf3328_dbgmixer("put_enum: %02x to %04x, oreg %04x\n", reg.reg, val, oreg);
637 return (nreg != oreg);
640 static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
641 AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
642 AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
643 AZF3328_MIXER_SWITCH("PCM Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
644 AZF3328_MIXER_VOL_STEREO("PCM Playback Volume",
645 IDX_MIXER_WAVEOUT, 0x1f, 1),
646 AZF3328_MIXER_SWITCH("PCM 3D Bypass Playback Switch",
647 IDX_MIXER_ADVCTL2, 7, 1),
648 AZF3328_MIXER_SWITCH("FM Playback Switch", IDX_MIXER_FMSYNTH, 15, 1),
649 AZF3328_MIXER_VOL_STEREO("FM Playback Volume", IDX_MIXER_FMSYNTH, 0x1f, 1),
650 AZF3328_MIXER_SWITCH("CD Playback Switch", IDX_MIXER_CDAUDIO, 15, 1),
651 AZF3328_MIXER_VOL_STEREO("CD Playback Volume", IDX_MIXER_CDAUDIO, 0x1f, 1),
652 AZF3328_MIXER_SWITCH("Capture Switch", IDX_MIXER_REC_VOLUME, 15, 1),
653 AZF3328_MIXER_VOL_STEREO("Capture Volume", IDX_MIXER_REC_VOLUME, 0x0f, 0),
654 AZF3328_MIXER_ENUM("Capture Source", IDX_MIXER_REC_SELECT, 8, 0),
655 AZF3328_MIXER_SWITCH("Mic Playback Switch", IDX_MIXER_MIC, 15, 1),
656 AZF3328_MIXER_VOL_MONO("Mic Playback Volume", IDX_MIXER_MIC, 0x1f, 1),
657 AZF3328_MIXER_SWITCH("Mic Boost (+20dB)", IDX_MIXER_MIC, 6, 0),
658 AZF3328_MIXER_SWITCH("Line Playback Switch", IDX_MIXER_LINEIN, 15, 1),
659 AZF3328_MIXER_VOL_STEREO("Line Playback Volume", IDX_MIXER_LINEIN, 0x1f, 1),
660 AZF3328_MIXER_SWITCH("Beep Playback Switch", IDX_MIXER_PCBEEP, 15, 1),
661 AZF3328_MIXER_VOL_SPECIAL("Beep Playback Volume", IDX_MIXER_PCBEEP, 0x0f, 1, 1),
662 AZF3328_MIXER_SWITCH("Video Playback Switch", IDX_MIXER_VIDEO, 15, 1),
663 AZF3328_MIXER_VOL_STEREO("Video Playback Volume", IDX_MIXER_VIDEO, 0x1f, 1),
664 AZF3328_MIXER_SWITCH("Aux Playback Switch", IDX_MIXER_AUX, 15, 1),
665 AZF3328_MIXER_VOL_STEREO("Aux Playback Volume", IDX_MIXER_AUX, 0x1f, 1),
666 AZF3328_MIXER_SWITCH("Modem Playback Switch", IDX_MIXER_MODEMOUT, 15, 1),
667 AZF3328_MIXER_VOL_MONO("Modem Playback Volume", IDX_MIXER_MODEMOUT, 0x1f, 1),
668 AZF3328_MIXER_SWITCH("Modem Capture Switch", IDX_MIXER_MODEMIN, 15, 1),
669 AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1),
670 AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8),
671 AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9),
672 AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */
673 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0),
674 AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0),
675 AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0),
676 AZF3328_MIXER_VOL_SPECIAL("3D Control - Width", IDX_MIXER_ADVCTL1, 0x07, 1, 0), /* "3D Width" */
677 AZF3328_MIXER_VOL_SPECIAL("3D Control - Depth", IDX_MIXER_ADVCTL1, 0x03, 8, 0), /* "Hifi 3D" */
678 #if MIXER_TESTING
679 AZF3328_MIXER_SWITCH("0", IDX_MIXER_ADVCTL2, 0, 0),
680 AZF3328_MIXER_SWITCH("1", IDX_MIXER_ADVCTL2, 1, 0),
681 AZF3328_MIXER_SWITCH("2", IDX_MIXER_ADVCTL2, 2, 0),
682 AZF3328_MIXER_SWITCH("3", IDX_MIXER_ADVCTL2, 3, 0),
683 AZF3328_MIXER_SWITCH("4", IDX_MIXER_ADVCTL2, 4, 0),
684 AZF3328_MIXER_SWITCH("5", IDX_MIXER_ADVCTL2, 5, 0),
685 AZF3328_MIXER_SWITCH("6", IDX_MIXER_ADVCTL2, 6, 0),
686 AZF3328_MIXER_SWITCH("7", IDX_MIXER_ADVCTL2, 7, 0),
687 AZF3328_MIXER_SWITCH("8", IDX_MIXER_ADVCTL2, 8, 0),
688 AZF3328_MIXER_SWITCH("9", IDX_MIXER_ADVCTL2, 9, 0),
689 AZF3328_MIXER_SWITCH("10", IDX_MIXER_ADVCTL2, 10, 0),
690 AZF3328_MIXER_SWITCH("11", IDX_MIXER_ADVCTL2, 11, 0),
691 AZF3328_MIXER_SWITCH("12", IDX_MIXER_ADVCTL2, 12, 0),
692 AZF3328_MIXER_SWITCH("13", IDX_MIXER_ADVCTL2, 13, 0),
693 AZF3328_MIXER_SWITCH("14", IDX_MIXER_ADVCTL2, 14, 0),
694 AZF3328_MIXER_SWITCH("15", IDX_MIXER_ADVCTL2, 15, 0),
695 #endif
698 static u16 __devinitdata snd_azf3328_init_values[][2] = {
699 { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f },
700 { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f },
701 { IDX_MIXER_BASSTREBLE, 0x0000 },
702 { IDX_MIXER_PCBEEP, MIXER_MUTE_MASK|0x1f1f },
703 { IDX_MIXER_MODEMIN, MIXER_MUTE_MASK|0x1f1f },
704 { IDX_MIXER_MIC, MIXER_MUTE_MASK|0x001f },
705 { IDX_MIXER_LINEIN, MIXER_MUTE_MASK|0x1f1f },
706 { IDX_MIXER_CDAUDIO, MIXER_MUTE_MASK|0x1f1f },
707 { IDX_MIXER_VIDEO, MIXER_MUTE_MASK|0x1f1f },
708 { IDX_MIXER_AUX, MIXER_MUTE_MASK|0x1f1f },
709 { IDX_MIXER_WAVEOUT, MIXER_MUTE_MASK|0x1f1f },
710 { IDX_MIXER_FMSYNTH, MIXER_MUTE_MASK|0x1f1f },
711 { IDX_MIXER_REC_VOLUME, MIXER_MUTE_MASK|0x0707 },
714 static int __devinit
715 snd_azf3328_mixer_new(struct snd_azf3328 *chip)
717 struct snd_card *card;
718 const struct snd_kcontrol_new *sw;
719 unsigned int idx;
720 int err;
722 snd_azf3328_dbgcallenter();
723 if (snd_BUG_ON(!chip || !chip->card))
724 return -EINVAL;
726 card = chip->card;
728 /* mixer reset */
729 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
731 /* mute and zero volume channels */
732 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_init_values); ++idx) {
733 snd_azf3328_mixer_outw(chip,
734 snd_azf3328_init_values[idx][0],
735 snd_azf3328_init_values[idx][1]);
738 /* add mixer controls */
739 sw = snd_azf3328_mixer_controls;
740 for (idx = 0; idx < ARRAY_SIZE(snd_azf3328_mixer_controls);
741 ++idx, ++sw) {
742 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(sw, chip))) < 0)
743 return err;
745 snd_component_add(card, "AZF3328 mixer");
746 strcpy(card->mixername, "AZF3328 mixer");
748 snd_azf3328_dbgcallleave();
749 return 0;
752 static int
753 snd_azf3328_hw_params(struct snd_pcm_substream *substream,
754 struct snd_pcm_hw_params *hw_params)
756 int res;
757 snd_azf3328_dbgcallenter();
758 res = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
759 snd_azf3328_dbgcallleave();
760 return res;
763 static int
764 snd_azf3328_hw_free(struct snd_pcm_substream *substream)
766 snd_azf3328_dbgcallenter();
767 snd_pcm_lib_free_pages(substream);
768 snd_azf3328_dbgcallleave();
769 return 0;
772 static void
773 snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
774 enum snd_azf3328_codec_type codec_type,
775 enum azf_freq_t bitrate,
776 unsigned int format_width,
777 unsigned int channels
780 unsigned long flags;
781 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
782 u16 val = 0xff00;
784 snd_azf3328_dbgcallenter();
785 switch (bitrate) {
786 case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
787 case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
788 case AZF_FREQ_5512:
789 /* the AZF3328 names it "5510" for some strange reason */
790 val |= SOUNDFORMAT_FREQ_5510; break;
791 case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break;
792 case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break;
793 case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break;
794 case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break;
795 case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
796 case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break;
797 case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break;
798 case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break;
799 default:
800 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
801 /* fall-through */
802 case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break;
803 case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break;
804 case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
806 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
807 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
808 /* val = 0xff0a; 47m30.599s (4764,891Hz; -> 4800Hz???) yup, 4803Hz */
809 /* val = 0xff0c; 57m0.510s (4010,263Hz; -> 4000Hz???) yup, 4003Hz */
810 /* val = 0xff05; 5m11.556s (... -> 44100Hz) */
811 /* val = 0xff03; 10m21.529s (21872,463Hz; -> 22050Hz???) */
812 /* val = 0xff0f; 20m41.883s (10937,993Hz; -> 11025Hz???) */
813 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
814 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
816 if (channels == 2)
817 val |= SOUNDFORMAT_FLAG_2CHANNELS;
819 if (format_width == 16)
820 val |= SOUNDFORMAT_FLAG_16BIT;
822 spin_lock_irqsave(&chip->reg_lock, flags);
824 /* set bitrate/format */
825 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
827 if (codec_type == AZF_CODEC_PLAYBACK) /* only do it for playback */
828 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
829 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
830 DMA_RUN_SOMETHING1 |
831 DMA_RUN_SOMETHING2 |
832 SOMETHING_ALMOST_ALWAYS_SET |
833 DMA_EPILOGUE_SOMETHING |
834 DMA_SOMETHING_ELSE
837 spin_unlock_irqrestore(&chip->reg_lock, flags);
838 snd_azf3328_dbgcallleave();
841 static inline void
842 snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip,
843 enum snd_azf3328_codec_type codec_type
846 /* choose lowest frequency for low power consumption.
847 * While this will cause louder noise due to rather coarse frequency,
848 * it should never matter since output should always
849 * get disabled properly when idle anyway. */
850 snd_azf3328_codec_setfmt(chip, codec_type, AZF_FREQ_4000, 8, 1);
853 static void
854 snd_azf3328_ctrl_reg_6AH_update(struct snd_azf3328 *chip,
855 unsigned bitmask,
856 bool enable
859 bool do_mask = !enable;
860 if (do_mask)
861 chip->shadow_reg_ctrl_6AH |= bitmask;
862 else
863 chip->shadow_reg_ctrl_6AH &= ~bitmask;
864 snd_azf3328_dbgcodec("6AH_update mask 0x%04x do_mask %d: val 0x%04x\n",
865 bitmask, do_mask, chip->shadow_reg_ctrl_6AH);
866 snd_azf3328_ctrl_outw(chip, IDX_IO_6AH, chip->shadow_reg_ctrl_6AH);
869 static inline void
870 snd_azf3328_ctrl_enable_codecs(struct snd_azf3328 *chip, bool enable)
872 snd_azf3328_dbgcodec("codec_enable %d\n", enable);
873 /* no idea what exactly is being done here, but I strongly assume it's
874 * PM related */
875 snd_azf3328_ctrl_reg_6AH_update(
876 chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
880 static void
881 snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
882 enum snd_azf3328_codec_type codec_type,
883 bool enable
886 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
887 bool need_change = (codec->running != enable);
889 snd_azf3328_dbgcodec(
890 "codec_activity: %s codec, enable %d, need_change %d\n",
891 codec->name, enable, need_change
893 if (need_change) {
894 static const struct {
895 enum snd_azf3328_codec_type other1;
896 enum snd_azf3328_codec_type other2;
897 } peer_codecs[3] =
898 { { AZF_CODEC_CAPTURE, AZF_CODEC_I2S_OUT },
899 { AZF_CODEC_PLAYBACK, AZF_CODEC_I2S_OUT },
900 { AZF_CODEC_PLAYBACK, AZF_CODEC_CAPTURE } };
901 bool call_function;
903 if (enable)
904 /* if enable codec, call enable_codecs func
905 to enable codec supply... */
906 call_function = 1;
907 else {
908 /* ...otherwise call enable_codecs func
909 (which globally shuts down operation of codecs)
910 only in case the other codecs are currently
911 not active either! */
912 call_function =
913 ((!chip->codecs[peer_codecs[codec_type].other1]
914 .running)
915 && (!chip->codecs[peer_codecs[codec_type].other2]
916 .running));
918 if (call_function)
919 snd_azf3328_ctrl_enable_codecs(chip, enable);
921 /* ...and adjust clock, too
922 * (reduce noise and power consumption) */
923 if (!enable)
924 snd_azf3328_codec_setfmt_lowpower(
925 chip,
926 codec_type
928 codec->running = enable;
932 static void
933 snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip,
934 enum snd_azf3328_codec_type codec_type,
935 unsigned long addr,
936 unsigned int count,
937 unsigned int size
940 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
941 snd_azf3328_dbgcallenter();
942 if (!codec->running) {
943 /* AZF3328 uses a two buffer pointer DMA transfer approach */
945 unsigned long flags, addr_area2;
947 /* width 32bit (prevent overflow): */
948 u32 count_areas, lengths;
950 count_areas = size/2;
951 addr_area2 = addr+count_areas;
952 count_areas--; /* max. index */
953 snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n",
954 addr, count_areas, addr_area2, count_areas);
956 /* build combined I/O buffer length word */
957 lengths = (count_areas << 16) | (count_areas);
958 spin_lock_irqsave(&chip->reg_lock, flags);
959 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_1, addr);
960 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_2,
961 addr_area2);
962 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_LENGTHS,
963 lengths);
964 spin_unlock_irqrestore(&chip->reg_lock, flags);
966 snd_azf3328_dbgcallleave();
969 static int
970 snd_azf3328_codec_prepare(struct snd_pcm_substream *substream)
973 snd_azf3328_dbgcallenter();
974 snd_azf3328_dbgcallleave();
975 return 0;
978 static int
979 snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
980 struct snd_pcm_substream *substream, int cmd)
982 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
983 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
984 struct snd_pcm_runtime *runtime = substream->runtime;
985 int result = 0;
986 u16 flags1;
987 bool previously_muted = 0;
988 bool is_playback_codec = (AZF_CODEC_PLAYBACK == codec_type);
990 snd_azf3328_dbgcalls("snd_azf3328_codec_trigger cmd %d\n", cmd);
992 switch (cmd) {
993 case SNDRV_PCM_TRIGGER_START:
994 snd_azf3328_dbgcodec("START %s\n", codec->name);
996 if (is_playback_codec) {
997 /* mute WaveOut (avoid clicking during setup) */
998 previously_muted =
999 snd_azf3328_mixer_set_mute(
1000 chip, IDX_MIXER_WAVEOUT, 1
1004 snd_azf3328_codec_setfmt(chip, codec_type,
1005 runtime->rate,
1006 snd_pcm_format_width(runtime->format),
1007 runtime->channels);
1009 spin_lock(&chip->reg_lock);
1010 /* first, remember current value: */
1011 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1013 /* stop transfer */
1014 flags1 &= ~DMA_RESUME;
1015 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1017 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
1018 spin_unlock(&chip->reg_lock);
1020 snd_azf3328_codec_setdmaa(chip, codec_type, runtime->dma_addr,
1021 snd_pcm_lib_period_bytes(substream),
1022 snd_pcm_lib_buffer_bytes(substream)
1025 spin_lock(&chip->reg_lock);
1026 #ifdef WIN9X
1027 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
1028 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1030 /* start transfer again */
1031 flags1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1032 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1033 #else /* NT4 */
1034 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1035 0x0000);
1036 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1037 DMA_RUN_SOMETHING1);
1038 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1039 DMA_RUN_SOMETHING1 |
1040 DMA_RUN_SOMETHING2);
1041 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1042 DMA_RESUME |
1043 SOMETHING_ALMOST_ALWAYS_SET |
1044 DMA_EPILOGUE_SOMETHING |
1045 DMA_SOMETHING_ELSE);
1046 #endif
1047 spin_unlock(&chip->reg_lock);
1048 snd_azf3328_ctrl_codec_activity(chip, codec_type, 1);
1050 if (is_playback_codec) {
1051 /* now unmute WaveOut */
1052 if (!previously_muted)
1053 snd_azf3328_mixer_set_mute(
1054 chip, IDX_MIXER_WAVEOUT, 0
1058 snd_azf3328_dbgcodec("STARTED %s\n", codec->name);
1059 break;
1060 case SNDRV_PCM_TRIGGER_RESUME:
1061 snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
1062 /* resume codec if we were active */
1063 spin_lock(&chip->reg_lock);
1064 if (codec->running)
1065 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1066 snd_azf3328_codec_inw(
1067 codec, IDX_IO_CODEC_DMA_FLAGS
1068 ) | DMA_RESUME
1070 spin_unlock(&chip->reg_lock);
1071 break;
1072 case SNDRV_PCM_TRIGGER_STOP:
1073 snd_azf3328_dbgcodec("STOP %s\n", codec->name);
1075 if (is_playback_codec) {
1076 /* mute WaveOut (avoid clicking during setup) */
1077 previously_muted =
1078 snd_azf3328_mixer_set_mute(
1079 chip, IDX_MIXER_WAVEOUT, 1
1083 spin_lock(&chip->reg_lock);
1084 /* first, remember current value: */
1085 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1087 /* stop transfer */
1088 flags1 &= ~DMA_RESUME;
1089 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1091 /* hmm, is this really required? we're resetting the same bit
1092 * immediately thereafter... */
1093 flags1 |= DMA_RUN_SOMETHING1;
1094 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1096 flags1 &= ~DMA_RUN_SOMETHING1;
1097 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1098 spin_unlock(&chip->reg_lock);
1099 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
1101 if (is_playback_codec) {
1102 /* now unmute WaveOut */
1103 if (!previously_muted)
1104 snd_azf3328_mixer_set_mute(
1105 chip, IDX_MIXER_WAVEOUT, 0
1109 snd_azf3328_dbgcodec("STOPPED %s\n", codec->name);
1110 break;
1111 case SNDRV_PCM_TRIGGER_SUSPEND:
1112 snd_azf3328_dbgcodec("SUSPEND %s\n", codec->name);
1113 /* make sure codec is stopped */
1114 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1115 snd_azf3328_codec_inw(
1116 codec, IDX_IO_CODEC_DMA_FLAGS
1117 ) & ~DMA_RESUME
1119 break;
1120 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1121 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1122 break;
1123 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1124 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1125 break;
1126 default:
1127 snd_printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1128 return -EINVAL;
1131 snd_azf3328_dbgcallleave();
1132 return result;
1135 static int
1136 snd_azf3328_codec_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1138 return snd_azf3328_codec_trigger(AZF_CODEC_PLAYBACK, substream, cmd);
1141 static int
1142 snd_azf3328_codec_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1144 return snd_azf3328_codec_trigger(AZF_CODEC_CAPTURE, substream, cmd);
1147 static int
1148 snd_azf3328_codec_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd)
1150 return snd_azf3328_codec_trigger(AZF_CODEC_I2S_OUT, substream, cmd);
1153 static snd_pcm_uframes_t
1154 snd_azf3328_codec_pointer(struct snd_pcm_substream *substream,
1155 enum snd_azf3328_codec_type codec_type
1158 const struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1159 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1160 unsigned long bufptr, result;
1161 snd_pcm_uframes_t frmres;
1163 #ifdef QUERY_HARDWARE
1164 bufptr = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1165 #else
1166 bufptr = substream->runtime->dma_addr;
1167 #endif
1168 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
1170 /* calculate offset */
1171 result -= bufptr;
1172 frmres = bytes_to_frames( substream->runtime, result);
1173 snd_azf3328_dbgcodec("%s @ 0x%8lx, frames %8ld\n",
1174 codec->name, result, frmres);
1175 return frmres;
1178 static snd_pcm_uframes_t
1179 snd_azf3328_codec_playback_pointer(struct snd_pcm_substream *substream)
1181 return snd_azf3328_codec_pointer(substream, AZF_CODEC_PLAYBACK);
1184 static snd_pcm_uframes_t
1185 snd_azf3328_codec_capture_pointer(struct snd_pcm_substream *substream)
1187 return snd_azf3328_codec_pointer(substream, AZF_CODEC_CAPTURE);
1190 static snd_pcm_uframes_t
1191 snd_azf3328_codec_i2s_out_pointer(struct snd_pcm_substream *substream)
1193 return snd_azf3328_codec_pointer(substream, AZF_CODEC_I2S_OUT);
1196 /******************************************************************/
1198 #ifdef SUPPORT_GAMEPORT
1199 static inline void
1200 snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip,
1201 bool enable
1204 snd_azf3328_io_reg_setb(
1205 chip->game_io+IDX_GAME_HWCONFIG,
1206 GAME_HWCFG_IRQ_ENABLE,
1207 enable
1211 static inline void
1212 snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip,
1213 bool enable
1216 snd_azf3328_io_reg_setb(
1217 chip->game_io+IDX_GAME_HWCONFIG,
1218 GAME_HWCFG_LEGACY_ADDRESS_ENABLE,
1219 enable
1223 static void
1224 snd_azf3328_gameport_set_counter_frequency(struct snd_azf3328 *chip,
1225 unsigned int freq_cfg
1228 snd_azf3328_io_reg_setb(
1229 chip->game_io+IDX_GAME_HWCONFIG,
1230 0x02,
1231 (freq_cfg & 1) != 0
1233 snd_azf3328_io_reg_setb(
1234 chip->game_io+IDX_GAME_HWCONFIG,
1235 0x04,
1236 (freq_cfg & 2) != 0
1240 static inline void
1241 snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, bool enable)
1243 snd_azf3328_ctrl_reg_6AH_update(
1244 chip, IO_6A_SOMETHING2_GAMEPORT, enable
1248 static inline void
1249 snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1252 * skeleton handler only
1253 * (we do not want axis reading in interrupt handler - too much load!)
1255 snd_azf3328_dbggame("gameport irq\n");
1257 /* this should ACK the gameport IRQ properly, hopefully. */
1258 snd_azf3328_game_inw(chip, IDX_GAME_AXIS_VALUE);
1261 static int
1262 snd_azf3328_gameport_open(struct gameport *gameport, int mode)
1264 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1265 int res;
1267 snd_azf3328_dbggame("gameport_open, mode %d\n", mode);
1268 switch (mode) {
1269 case GAMEPORT_MODE_COOKED:
1270 case GAMEPORT_MODE_RAW:
1271 res = 0;
1272 break;
1273 default:
1274 res = -1;
1275 break;
1278 snd_azf3328_gameport_set_counter_frequency(chip,
1279 GAME_HWCFG_ADC_COUNTER_FREQ_STD);
1280 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1282 return res;
1285 static void
1286 snd_azf3328_gameport_close(struct gameport *gameport)
1288 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1290 snd_azf3328_dbggame("gameport_close\n");
1291 snd_azf3328_gameport_set_counter_frequency(chip,
1292 GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
1293 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1296 static int
1297 snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1298 int *axes,
1299 int *buttons
1302 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1303 int i;
1304 u8 val;
1305 unsigned long flags;
1307 if (snd_BUG_ON(!chip))
1308 return 0;
1310 spin_lock_irqsave(&chip->reg_lock, flags);
1311 val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE);
1312 *buttons = (~(val) >> 4) & 0xf;
1314 /* ok, this one is a bit dirty: cooked_read is being polled by a timer,
1315 * thus we're atomic and cannot actively wait in here
1316 * (which would be useful for us since it probably would be better
1317 * to trigger a measurement in here, then wait a short amount of
1318 * time until it's finished, then read values of _this_ measurement).
1320 * Thus we simply resort to reading values if they're available already
1321 * and trigger the next measurement.
1324 val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
1325 if (val & GAME_AXES_SAMPLING_READY) {
1326 for (i = 0; i < ARRAY_SIZE(chip->axes); ++i) {
1327 /* configure the axis to read */
1328 val = (i << 4) | 0x0f;
1329 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1331 chip->axes[i] = snd_azf3328_game_inw(
1332 chip, IDX_GAME_AXIS_VALUE
1337 /* trigger next axes sampling, to be evaluated the next time we
1338 * enter this function */
1340 /* for some very, very strange reason we cannot enable
1341 * Measurement Ready monitoring for all axes here,
1342 * at least not when only one joystick connected */
1343 val = 0x03; /* we're able to monitor axes 1 and 2 only */
1344 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
1346 snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
1347 spin_unlock_irqrestore(&chip->reg_lock, flags);
1349 for (i = 0; i < ARRAY_SIZE(chip->axes); i++) {
1350 axes[i] = chip->axes[i];
1351 if (axes[i] == 0xffff)
1352 axes[i] = -1;
1355 snd_azf3328_dbggame("cooked_read: axes %d %d %d %d buttons %d\n",
1356 axes[0], axes[1], axes[2], axes[3], *buttons
1359 return 0;
1362 static int __devinit
1363 snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
1365 struct gameport *gp;
1367 chip->gameport = gp = gameport_allocate_port();
1368 if (!gp) {
1369 printk(KERN_ERR "azt3328: cannot alloc memory for gameport\n");
1370 return -ENOMEM;
1373 gameport_set_name(gp, "AZF3328 Gameport");
1374 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1375 gameport_set_dev_parent(gp, &chip->pci->dev);
1376 gp->io = chip->game_io;
1377 gameport_set_port_data(gp, chip);
1379 gp->open = snd_azf3328_gameport_open;
1380 gp->close = snd_azf3328_gameport_close;
1381 gp->fuzz = 16; /* seems ok */
1382 gp->cooked_read = snd_azf3328_gameport_cooked_read;
1384 /* DISABLE legacy address: we don't need it! */
1385 snd_azf3328_gameport_legacy_address_enable(chip, 0);
1387 snd_azf3328_gameport_set_counter_frequency(chip,
1388 GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
1389 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1391 gameport_register_port(chip->gameport);
1393 return 0;
1396 static void
1397 snd_azf3328_gameport_free(struct snd_azf3328 *chip)
1399 if (chip->gameport) {
1400 gameport_unregister_port(chip->gameport);
1401 chip->gameport = NULL;
1403 snd_azf3328_gameport_irq_enable(chip, 0);
1405 #else
1406 static inline int
1407 snd_azf3328_gameport(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
1408 static inline void
1409 snd_azf3328_gameport_free(struct snd_azf3328 *chip) { }
1410 static inline void
1411 snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1413 printk(KERN_WARNING "huh, game port IRQ occurred!?\n");
1415 #endif /* SUPPORT_GAMEPORT */
1417 /******************************************************************/
1419 static inline void
1420 snd_azf3328_irq_log_unknown_type(u8 which)
1422 snd_azf3328_dbgcodec(
1423 "azt3328: unknown IRQ type (%x) occurred, please report!\n",
1424 which
1428 static inline void
1429 snd_azf3328_codec_interrupt(struct snd_azf3328 *chip, u8 status)
1431 u8 which;
1432 enum snd_azf3328_codec_type codec_type;
1433 const struct snd_azf3328_codec_data *codec;
1435 for (codec_type = AZF_CODEC_PLAYBACK;
1436 codec_type <= AZF_CODEC_I2S_OUT;
1437 ++codec_type) {
1439 /* skip codec if there's no interrupt for it */
1440 if (!(status & (1 << codec_type)))
1441 continue;
1443 codec = &chip->codecs[codec_type];
1445 spin_lock(&chip->reg_lock);
1446 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
1447 /* ack all IRQ types immediately */
1448 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
1449 spin_unlock(&chip->reg_lock);
1451 if ((chip->pcm[codec_type]) && (codec->substream)) {
1452 snd_pcm_period_elapsed(codec->substream);
1453 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
1454 codec->name,
1455 which,
1456 snd_azf3328_codec_inl(
1457 codec, IDX_IO_CODEC_DMA_CURRPOS
1460 } else
1461 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1462 if (which & IRQ_SOMETHING)
1463 snd_azf3328_irq_log_unknown_type(which);
1467 static irqreturn_t
1468 snd_azf3328_interrupt(int irq, void *dev_id)
1470 struct snd_azf3328 *chip = dev_id;
1471 u8 status;
1472 #if DEBUG_CODEC
1473 static unsigned long irq_count;
1474 #endif
1476 status = snd_azf3328_ctrl_inb(chip, IDX_IO_IRQSTATUS);
1478 /* fast path out, to ease interrupt sharing */
1479 if (!(status &
1480 (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT
1481 |IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
1483 return IRQ_NONE; /* must be interrupt for another device */
1485 snd_azf3328_dbgcodec(
1486 "irq_count %ld! IDX_IO_IRQSTATUS %04x\n",
1487 irq_count++ /* debug-only */,
1488 status
1491 if (status & IRQ_TIMER) {
1492 /* snd_azf3328_dbgcodec("timer %ld\n",
1493 snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
1494 & TIMER_VALUE_MASK
1495 ); */
1496 if (chip->timer)
1497 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1498 /* ACK timer */
1499 spin_lock(&chip->reg_lock);
1500 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
1501 spin_unlock(&chip->reg_lock);
1502 snd_azf3328_dbgcodec("azt3328: timer IRQ\n");
1505 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
1506 snd_azf3328_codec_interrupt(chip, status);
1508 if (status & IRQ_GAMEPORT)
1509 snd_azf3328_gameport_interrupt(chip);
1511 /* MPU401 has less critical IRQ requirements
1512 * than timer and playback/recording, right? */
1513 if (status & IRQ_MPU401) {
1514 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
1516 /* hmm, do we have to ack the IRQ here somehow?
1517 * If so, then I don't know how yet... */
1518 snd_azf3328_dbgcodec("azt3328: MPU401 IRQ\n");
1520 return IRQ_HANDLED;
1523 /*****************************************************************/
1525 /* as long as we think we have identical snd_pcm_hardware parameters
1526 for playback, capture and i2s out, we can use the same physical struct
1527 since the struct is simply being copied into a member.
1529 static const struct snd_pcm_hardware snd_azf3328_hardware =
1531 .info = SNDRV_PCM_INFO_MMAP |
1532 SNDRV_PCM_INFO_INTERLEAVED |
1533 SNDRV_PCM_INFO_MMAP_VALID,
1534 .formats = SNDRV_PCM_FMTBIT_S8 |
1535 SNDRV_PCM_FMTBIT_U8 |
1536 SNDRV_PCM_FMTBIT_S16_LE |
1537 SNDRV_PCM_FMTBIT_U16_LE,
1538 .rates = SNDRV_PCM_RATE_5512 |
1539 SNDRV_PCM_RATE_8000_48000 |
1540 SNDRV_PCM_RATE_KNOT,
1541 .rate_min = AZF_FREQ_4000,
1542 .rate_max = AZF_FREQ_66200,
1543 .channels_min = 1,
1544 .channels_max = 2,
1545 .buffer_bytes_max = 65536,
1546 .period_bytes_min = 64,
1547 .period_bytes_max = 65536,
1548 .periods_min = 1,
1549 .periods_max = 1024,
1550 .fifo_size = 0,
1554 static unsigned int snd_azf3328_fixed_rates[] = {
1555 AZF_FREQ_4000,
1556 AZF_FREQ_4800,
1557 AZF_FREQ_5512,
1558 AZF_FREQ_6620,
1559 AZF_FREQ_8000,
1560 AZF_FREQ_9600,
1561 AZF_FREQ_11025,
1562 AZF_FREQ_13240,
1563 AZF_FREQ_16000,
1564 AZF_FREQ_22050,
1565 AZF_FREQ_32000,
1566 AZF_FREQ_44100,
1567 AZF_FREQ_48000,
1568 AZF_FREQ_66200
1571 static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
1572 .count = ARRAY_SIZE(snd_azf3328_fixed_rates),
1573 .list = snd_azf3328_fixed_rates,
1574 .mask = 0,
1577 /*****************************************************************/
1579 static int
1580 snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
1581 enum snd_azf3328_codec_type codec_type
1584 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1585 struct snd_pcm_runtime *runtime = substream->runtime;
1587 snd_azf3328_dbgcallenter();
1588 chip->codecs[codec_type].substream = substream;
1590 /* same parameters for all our codecs - at least we think so... */
1591 runtime->hw = snd_azf3328_hardware;
1593 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1594 &snd_azf3328_hw_constraints_rates);
1595 snd_azf3328_dbgcallleave();
1596 return 0;
1599 static int
1600 snd_azf3328_playback_open(struct snd_pcm_substream *substream)
1602 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
1605 static int
1606 snd_azf3328_capture_open(struct snd_pcm_substream *substream)
1608 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
1611 static int
1612 snd_azf3328_i2s_out_open(struct snd_pcm_substream *substream)
1614 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
1617 static int
1618 snd_azf3328_pcm_close(struct snd_pcm_substream *substream,
1619 enum snd_azf3328_codec_type codec_type
1622 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1624 snd_azf3328_dbgcallenter();
1625 chip->codecs[codec_type].substream = NULL;
1626 snd_azf3328_dbgcallleave();
1627 return 0;
1630 static int
1631 snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1633 return snd_azf3328_pcm_close(substream, AZF_CODEC_PLAYBACK);
1636 static int
1637 snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1639 return snd_azf3328_pcm_close(substream, AZF_CODEC_CAPTURE);
1642 static int
1643 snd_azf3328_i2s_out_close(struct snd_pcm_substream *substream)
1645 return snd_azf3328_pcm_close(substream, AZF_CODEC_I2S_OUT);
1648 /******************************************************************/
1650 static struct snd_pcm_ops snd_azf3328_playback_ops = {
1651 .open = snd_azf3328_playback_open,
1652 .close = snd_azf3328_playback_close,
1653 .ioctl = snd_pcm_lib_ioctl,
1654 .hw_params = snd_azf3328_hw_params,
1655 .hw_free = snd_azf3328_hw_free,
1656 .prepare = snd_azf3328_codec_prepare,
1657 .trigger = snd_azf3328_codec_playback_trigger,
1658 .pointer = snd_azf3328_codec_playback_pointer
1661 static struct snd_pcm_ops snd_azf3328_capture_ops = {
1662 .open = snd_azf3328_capture_open,
1663 .close = snd_azf3328_capture_close,
1664 .ioctl = snd_pcm_lib_ioctl,
1665 .hw_params = snd_azf3328_hw_params,
1666 .hw_free = snd_azf3328_hw_free,
1667 .prepare = snd_azf3328_codec_prepare,
1668 .trigger = snd_azf3328_codec_capture_trigger,
1669 .pointer = snd_azf3328_codec_capture_pointer
1672 static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
1673 .open = snd_azf3328_i2s_out_open,
1674 .close = snd_azf3328_i2s_out_close,
1675 .ioctl = snd_pcm_lib_ioctl,
1676 .hw_params = snd_azf3328_hw_params,
1677 .hw_free = snd_azf3328_hw_free,
1678 .prepare = snd_azf3328_codec_prepare,
1679 .trigger = snd_azf3328_codec_i2s_out_trigger,
1680 .pointer = snd_azf3328_codec_i2s_out_pointer
1683 static int __devinit
1684 snd_azf3328_pcm(struct snd_azf3328 *chip)
1686 enum { AZF_PCMDEV_STD, AZF_PCMDEV_I2S_OUT, NUM_AZF_PCMDEVS }; /* pcm devices */
1688 struct snd_pcm *pcm;
1689 int err;
1691 snd_azf3328_dbgcallenter();
1693 err = snd_pcm_new(chip->card, "AZF3328 DSP", AZF_PCMDEV_STD,
1694 1, 1, &pcm);
1695 if (err < 0)
1696 return err;
1697 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1698 &snd_azf3328_playback_ops);
1699 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1700 &snd_azf3328_capture_ops);
1702 pcm->private_data = chip;
1703 pcm->info_flags = 0;
1704 strcpy(pcm->name, chip->card->shortname);
1705 /* same pcm object for playback/capture (see snd_pcm_new() above) */
1706 chip->pcm[AZF_CODEC_PLAYBACK] = pcm;
1707 chip->pcm[AZF_CODEC_CAPTURE] = pcm;
1709 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1710 snd_dma_pci_data(chip->pci),
1711 64*1024, 64*1024);
1713 err = snd_pcm_new(chip->card, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT,
1714 1, 0, &pcm);
1715 if (err < 0)
1716 return err;
1717 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1718 &snd_azf3328_i2s_out_ops);
1720 pcm->private_data = chip;
1721 pcm->info_flags = 0;
1722 strcpy(pcm->name, chip->card->shortname);
1723 chip->pcm[AZF_CODEC_I2S_OUT] = pcm;
1725 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1726 snd_dma_pci_data(chip->pci),
1727 64*1024, 64*1024);
1729 snd_azf3328_dbgcallleave();
1730 return 0;
1733 /******************************************************************/
1735 /*** NOTE: the physical timer resolution actually is 1024000 ticks per second
1736 *** (probably derived from main crystal via a divider of 24),
1737 *** but announcing those attributes to user-space would make programs
1738 *** configure the timer to a 1 tick value, resulting in an absolutely fatal
1739 *** timer IRQ storm.
1740 *** Thus I chose to announce a down-scaled virtual timer to the outside and
1741 *** calculate real timer countdown values internally.
1742 *** (the scale factor can be set via module parameter "seqtimer_scaling").
1743 ***/
1745 static int
1746 snd_azf3328_timer_start(struct snd_timer *timer)
1748 struct snd_azf3328 *chip;
1749 unsigned long flags;
1750 unsigned int delay;
1752 snd_azf3328_dbgcallenter();
1753 chip = snd_timer_chip(timer);
1754 delay = ((timer->sticks * seqtimer_scaling) - 1) & TIMER_VALUE_MASK;
1755 if (delay < 49) {
1756 /* uhoh, that's not good, since user-space won't know about
1757 * this timing tweak
1758 * (we need to do it to avoid a lockup, though) */
1760 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
1761 delay = 49; /* minimum time is 49 ticks */
1763 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
1764 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1765 spin_lock_irqsave(&chip->reg_lock, flags);
1766 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
1767 spin_unlock_irqrestore(&chip->reg_lock, flags);
1768 snd_azf3328_dbgcallleave();
1769 return 0;
1772 static int
1773 snd_azf3328_timer_stop(struct snd_timer *timer)
1775 struct snd_azf3328 *chip;
1776 unsigned long flags;
1778 snd_azf3328_dbgcallenter();
1779 chip = snd_timer_chip(timer);
1780 spin_lock_irqsave(&chip->reg_lock, flags);
1781 /* disable timer countdown and interrupt */
1782 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
1783 spin_unlock_irqrestore(&chip->reg_lock, flags);
1784 snd_azf3328_dbgcallleave();
1785 return 0;
1789 static int
1790 snd_azf3328_timer_precise_resolution(struct snd_timer *timer,
1791 unsigned long *num, unsigned long *den)
1793 snd_azf3328_dbgcallenter();
1794 *num = 1;
1795 *den = 1024000 / seqtimer_scaling;
1796 snd_azf3328_dbgcallleave();
1797 return 0;
1800 static struct snd_timer_hardware snd_azf3328_timer_hw = {
1801 .flags = SNDRV_TIMER_HW_AUTO,
1802 .resolution = 977, /* 1000000/1024000 = 0.9765625us */
1803 .ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
1804 .start = snd_azf3328_timer_start,
1805 .stop = snd_azf3328_timer_stop,
1806 .precise_resolution = snd_azf3328_timer_precise_resolution,
1809 static int __devinit
1810 snd_azf3328_timer(struct snd_azf3328 *chip, int device)
1812 struct snd_timer *timer = NULL;
1813 struct snd_timer_id tid;
1814 int err;
1816 snd_azf3328_dbgcallenter();
1817 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1818 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1819 tid.card = chip->card->number;
1820 tid.device = device;
1821 tid.subdevice = 0;
1823 snd_azf3328_timer_hw.resolution *= seqtimer_scaling;
1824 snd_azf3328_timer_hw.ticks /= seqtimer_scaling;
1826 err = snd_timer_new(chip->card, "AZF3328", &tid, &timer);
1827 if (err < 0)
1828 goto out;
1830 strcpy(timer->name, "AZF3328 timer");
1831 timer->private_data = chip;
1832 timer->hw = snd_azf3328_timer_hw;
1834 chip->timer = timer;
1836 snd_azf3328_timer_stop(timer);
1838 err = 0;
1840 out:
1841 snd_azf3328_dbgcallleave();
1842 return err;
1845 /******************************************************************/
1847 static int
1848 snd_azf3328_free(struct snd_azf3328 *chip)
1850 if (chip->irq < 0)
1851 goto __end_hw;
1853 /* reset (close) mixer:
1854 * first mute master volume, then reset
1856 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
1857 snd_azf3328_mixer_outw(chip, IDX_MIXER_RESET, 0x0000);
1859 snd_azf3328_timer_stop(chip->timer);
1860 snd_azf3328_gameport_free(chip);
1862 if (chip->irq >= 0)
1863 synchronize_irq(chip->irq);
1864 __end_hw:
1865 if (chip->irq >= 0)
1866 free_irq(chip->irq, chip);
1867 pci_release_regions(chip->pci);
1868 pci_disable_device(chip->pci);
1870 kfree(chip);
1871 return 0;
1874 static int
1875 snd_azf3328_dev_free(struct snd_device *device)
1877 struct snd_azf3328 *chip = device->device_data;
1878 return snd_azf3328_free(chip);
1882 static inline void
1883 snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
1885 #if DEBUG_MISC
1886 u16 tmp;
1888 snd_azf3328_dbgmisc(
1889 "ctrl_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
1890 "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
1891 chip->ctrl_io, chip->game_io, chip->mpu_io,
1892 chip->opl3_io, chip->mixer_io, chip->irq
1895 snd_azf3328_dbgmisc("game %02x %02x %02x %02x %02x %02x\n",
1896 snd_azf3328_game_inb(chip, 0),
1897 snd_azf3328_game_inb(chip, 1),
1898 snd_azf3328_game_inb(chip, 2),
1899 snd_azf3328_game_inb(chip, 3),
1900 snd_azf3328_game_inb(chip, 4),
1901 snd_azf3328_game_inb(chip, 5)
1904 for (tmp = 0; tmp < 0x07; tmp += 1)
1905 snd_azf3328_dbgmisc("mpu_io 0x%04x\n", inb(chip->mpu_io + tmp));
1907 for (tmp = 0; tmp <= 0x07; tmp += 1)
1908 snd_azf3328_dbgmisc("0x%02x: game200 0x%04x, game208 0x%04x\n",
1909 tmp, inb(0x200 + tmp), inb(0x208 + tmp));
1911 for (tmp = 0; tmp <= 0x01; tmp += 1)
1912 snd_azf3328_dbgmisc(
1913 "0x%02x: mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, "
1914 "mpu330 0x%04x opl388 0x%04x opl38c 0x%04x\n",
1915 tmp,
1916 inb(0x300 + tmp),
1917 inb(0x310 + tmp),
1918 inb(0x320 + tmp),
1919 inb(0x330 + tmp),
1920 inb(0x388 + tmp),
1921 inb(0x38c + tmp)
1924 for (tmp = 0; tmp < AZF_IO_SIZE_CTRL; tmp += 2)
1925 snd_azf3328_dbgmisc("ctrl 0x%02x: 0x%04x\n",
1926 tmp, snd_azf3328_ctrl_inw(chip, tmp)
1929 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
1930 snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n",
1931 tmp, snd_azf3328_mixer_inw(chip, tmp)
1933 #endif /* DEBUG_MISC */
1936 static int __devinit
1937 snd_azf3328_create(struct snd_card *card,
1938 struct pci_dev *pci,
1939 unsigned long device_type,
1940 struct snd_azf3328 **rchip)
1942 struct snd_azf3328 *chip;
1943 int err;
1944 static struct snd_device_ops ops = {
1945 .dev_free = snd_azf3328_dev_free,
1947 u8 dma_init;
1948 enum snd_azf3328_codec_type codec_type;
1950 *rchip = NULL;
1952 err = pci_enable_device(pci);
1953 if (err < 0)
1954 return err;
1956 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1957 if (chip == NULL) {
1958 err = -ENOMEM;
1959 goto out_err;
1961 spin_lock_init(&chip->reg_lock);
1962 chip->card = card;
1963 chip->pci = pci;
1964 chip->irq = -1;
1966 /* check if we can restrict PCI DMA transfers to 24 bits */
1967 if (pci_set_dma_mask(pci, DMA_BIT_MASK(24)) < 0 ||
1968 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(24)) < 0) {
1969 snd_printk(KERN_ERR "architecture does not support "
1970 "24bit PCI busmaster DMA\n"
1972 err = -ENXIO;
1973 goto out_err;
1976 err = pci_request_regions(pci, "Aztech AZF3328");
1977 if (err < 0)
1978 goto out_err;
1980 chip->ctrl_io = pci_resource_start(pci, 0);
1981 chip->game_io = pci_resource_start(pci, 1);
1982 chip->mpu_io = pci_resource_start(pci, 2);
1983 chip->opl3_io = pci_resource_start(pci, 3);
1984 chip->mixer_io = pci_resource_start(pci, 4);
1986 chip->codecs[AZF_CODEC_PLAYBACK].io_base =
1987 chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
1988 chip->codecs[AZF_CODEC_PLAYBACK].name = "PLAYBACK";
1989 chip->codecs[AZF_CODEC_CAPTURE].io_base =
1990 chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
1991 chip->codecs[AZF_CODEC_CAPTURE].name = "CAPTURE";
1992 chip->codecs[AZF_CODEC_I2S_OUT].io_base =
1993 chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
1994 chip->codecs[AZF_CODEC_I2S_OUT].name = "I2S_OUT";
1996 if (request_irq(pci->irq, snd_azf3328_interrupt,
1997 IRQF_SHARED, card->shortname, chip)) {
1998 snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
1999 err = -EBUSY;
2000 goto out_err;
2002 chip->irq = pci->irq;
2003 pci_set_master(pci);
2004 synchronize_irq(chip->irq);
2006 snd_azf3328_debug_show_ports(chip);
2008 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
2009 if (err < 0)
2010 goto out_err;
2012 /* create mixer interface & switches */
2013 err = snd_azf3328_mixer_new(chip);
2014 if (err < 0)
2015 goto out_err;
2017 /* standard codec init stuff */
2018 /* default DMA init value */
2019 dma_init = DMA_RUN_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
2021 for (codec_type = AZF_CODEC_PLAYBACK;
2022 codec_type <= AZF_CODEC_I2S_OUT; ++codec_type) {
2023 struct snd_azf3328_codec_data *codec =
2024 &chip->codecs[codec_type];
2026 /* shutdown codecs to save power */
2027 /* have ...ctrl_codec_activity() act properly */
2028 codec->running = 1;
2029 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
2031 spin_lock_irq(&chip->reg_lock);
2032 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
2033 dma_init);
2034 spin_unlock_irq(&chip->reg_lock);
2037 snd_card_set_dev(card, &pci->dev);
2039 *rchip = chip;
2041 err = 0;
2042 goto out;
2044 out_err:
2045 if (chip)
2046 snd_azf3328_free(chip);
2047 pci_disable_device(pci);
2049 out:
2050 return err;
2053 static int __devinit
2054 snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2056 static int dev;
2057 struct snd_card *card;
2058 struct snd_azf3328 *chip;
2059 struct snd_opl3 *opl3;
2060 int err;
2062 snd_azf3328_dbgcallenter();
2063 if (dev >= SNDRV_CARDS)
2064 return -ENODEV;
2065 if (!enable[dev]) {
2066 dev++;
2067 return -ENOENT;
2070 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
2071 if (err < 0)
2072 return err;
2074 strcpy(card->driver, "AZF3328");
2075 strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
2077 err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
2078 if (err < 0)
2079 goto out_err;
2081 card->private_data = chip;
2083 /* chose to use MPU401_HW_AZT2320 ID instead of MPU401_HW_MPU401,
2084 since our hardware ought to be similar, thus use same ID. */
2085 err = snd_mpu401_uart_new(
2086 card, 0,
2087 MPU401_HW_AZT2320, chip->mpu_io, MPU401_INFO_INTEGRATED,
2088 pci->irq, 0, &chip->rmidi
2090 if (err < 0) {
2091 snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n",
2092 chip->mpu_io
2094 goto out_err;
2097 err = snd_azf3328_timer(chip, 0);
2098 if (err < 0)
2099 goto out_err;
2101 err = snd_azf3328_pcm(chip);
2102 if (err < 0)
2103 goto out_err;
2105 if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
2106 OPL3_HW_AUTO, 1, &opl3) < 0) {
2107 snd_printk(KERN_ERR "azf3328: no OPL3 device at 0x%lx-0x%lx?\n",
2108 chip->opl3_io, chip->opl3_io+2
2110 } else {
2111 /* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
2112 err = snd_opl3_timer_new(opl3, 1, 2);
2113 if (err < 0)
2114 goto out_err;
2115 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2116 if (err < 0)
2117 goto out_err;
2120 opl3->private_data = chip;
2122 sprintf(card->longname, "%s at 0x%lx, irq %i",
2123 card->shortname, chip->ctrl_io, chip->irq);
2125 err = snd_card_register(card);
2126 if (err < 0)
2127 goto out_err;
2129 #ifdef MODULE
2130 printk(KERN_INFO
2131 "azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
2132 "azt3328: Hardware was completely undocumented, unfortunately.\n"
2133 "azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
2134 "azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n",
2135 1024000 / seqtimer_scaling, seqtimer_scaling);
2136 #endif
2138 snd_azf3328_gameport(chip, dev);
2140 pci_set_drvdata(pci, card);
2141 dev++;
2143 err = 0;
2144 goto out;
2146 out_err:
2147 snd_printk(KERN_ERR "azf3328: something failed, exiting\n");
2148 snd_card_free(card);
2150 out:
2151 snd_azf3328_dbgcallleave();
2152 return err;
2155 static void __devexit
2156 snd_azf3328_remove(struct pci_dev *pci)
2158 snd_azf3328_dbgcallenter();
2159 snd_card_free(pci_get_drvdata(pci));
2160 pci_set_drvdata(pci, NULL);
2161 snd_azf3328_dbgcallleave();
2164 #ifdef CONFIG_PM
2165 static inline void
2166 snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
2168 unsigned reg;
2170 for (reg = 0; reg < count; ++reg) {
2171 *saved_regs = inl(io_addr);
2172 snd_azf3328_dbgpm("suspend: io 0x%04lx: 0x%08x\n",
2173 io_addr, *saved_regs);
2174 ++saved_regs;
2175 io_addr += sizeof(*saved_regs);
2179 static int
2180 snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2182 struct snd_card *card = pci_get_drvdata(pci);
2183 struct snd_azf3328 *chip = card->private_data;
2184 u16 *saved_regs_ctrl_u16;
2186 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2188 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
2189 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
2191 snd_azf3328_suspend_regs(chip->mixer_io,
2192 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2194 /* make sure to disable master volume etc. to prevent looping sound */
2195 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2196 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
2198 snd_azf3328_suspend_regs(chip->ctrl_io,
2199 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
2201 /* manually store the one currently relevant write-only reg, too */
2202 saved_regs_ctrl_u16 = (u16 *)chip->saved_regs_ctrl;
2203 saved_regs_ctrl_u16[IDX_IO_6AH / 2] = chip->shadow_reg_ctrl_6AH;
2205 snd_azf3328_suspend_regs(chip->game_io,
2206 ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game);
2207 snd_azf3328_suspend_regs(chip->mpu_io,
2208 ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu);
2209 snd_azf3328_suspend_regs(chip->opl3_io,
2210 ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3);
2212 pci_disable_device(pci);
2213 pci_save_state(pci);
2214 pci_set_power_state(pci, pci_choose_state(pci, state));
2215 return 0;
2218 static inline void
2219 snd_azf3328_resume_regs(const u32 *saved_regs,
2220 unsigned long io_addr,
2221 unsigned count
2224 unsigned reg;
2226 for (reg = 0; reg < count; ++reg) {
2227 outl(*saved_regs, io_addr);
2228 snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2229 io_addr, *saved_regs, inl(io_addr));
2230 ++saved_regs;
2231 io_addr += sizeof(*saved_regs);
2235 static int
2236 snd_azf3328_resume(struct pci_dev *pci)
2238 struct snd_card *card = pci_get_drvdata(pci);
2239 const struct snd_azf3328 *chip = card->private_data;
2241 pci_set_power_state(pci, PCI_D0);
2242 pci_restore_state(pci);
2243 if (pci_enable_device(pci) < 0) {
2244 printk(KERN_ERR "azt3328: pci_enable_device failed, "
2245 "disabling device\n");
2246 snd_card_disconnect(card);
2247 return -EIO;
2249 pci_set_master(pci);
2251 snd_azf3328_resume_regs(chip->saved_regs_game, chip->game_io,
2252 ARRAY_SIZE(chip->saved_regs_game));
2253 snd_azf3328_resume_regs(chip->saved_regs_mpu, chip->mpu_io,
2254 ARRAY_SIZE(chip->saved_regs_mpu));
2255 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io,
2256 ARRAY_SIZE(chip->saved_regs_opl3));
2258 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io,
2259 ARRAY_SIZE(chip->saved_regs_mixer));
2261 /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2262 and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2263 resulting in a mixer reset condition persisting until _after_
2264 master vol was restored. Thus master vol needs an extra restore. */
2265 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2267 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io,
2268 ARRAY_SIZE(chip->saved_regs_ctrl));
2270 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2271 return 0;
2273 #endif /* CONFIG_PM */
2276 static struct pci_driver driver = {
2277 .name = "AZF3328",
2278 .id_table = snd_azf3328_ids,
2279 .probe = snd_azf3328_probe,
2280 .remove = __devexit_p(snd_azf3328_remove),
2281 #ifdef CONFIG_PM
2282 .suspend = snd_azf3328_suspend,
2283 .resume = snd_azf3328_resume,
2284 #endif
2287 static int __init
2288 alsa_card_azf3328_init(void)
2290 int err;
2291 snd_azf3328_dbgcallenter();
2292 err = pci_register_driver(&driver);
2293 snd_azf3328_dbgcallleave();
2294 return err;
2297 static void __exit
2298 alsa_card_azf3328_exit(void)
2300 snd_azf3328_dbgcallenter();
2301 pci_unregister_driver(&driver);
2302 snd_azf3328_dbgcallleave();
2305 module_init(alsa_card_azf3328_init)
2306 module_exit(alsa_card_azf3328_exit)