diff options
author | Adrian Bunk <bunk@stusta.de> | 2006-10-04 05:17:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 10:55:32 -0400 |
commit | d56b9b9c464a10ab1ee51a4c6190a2b57b8ef7a6 (patch) | |
tree | a48388734053900a8379042757ee241d1e9dfc7b /sound/oss | |
parent | 595182bcdf64fbfd7ae22c67ea6081b7d387d246 (diff) |
[PATCH] The scheduled removal of some OSS drivers
This patch contains the scheduled removal of OSS drivers that:
- have ALSA drivers for the same hardware without known regressions and
- whose Kconfig options have been removed in 2.6.17.
[michal.k.k.piotrowski@gmail.com: build fix]
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Michal Piotrowski <michal.k.k.piotrowski@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'sound/oss')
59 files changed, 6 insertions, 59106 deletions
diff --git a/sound/oss/Makefile b/sound/oss/Makefile index 86811792002f..8313757b6487 100644 --- a/sound/oss/Makefile +++ b/sound/oss/Makefile | |||
@@ -15,71 +15,42 @@ obj-$(CONFIG_SOUND_HAL2) += hal2.o | |||
15 | obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o | 15 | obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o |
16 | obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o | 16 | obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o |
17 | obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o | 17 | obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o |
18 | obj-$(CONFIG_SOUND_OPL3SA1) += opl3sa.o ad1848.o uart401.o | ||
19 | obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o | 18 | obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o |
20 | obj-$(CONFIG_SOUND_MAD16) += mad16.o ad1848.o sb_lib.o uart401.o | ||
21 | obj-$(CONFIG_SOUND_CS4232) += cs4232.o uart401.o | 19 | obj-$(CONFIG_SOUND_CS4232) += cs4232.o uart401.o |
22 | obj-$(CONFIG_SOUND_MSS) += ad1848.o | 20 | obj-$(CONFIG_SOUND_MSS) += ad1848.o |
23 | obj-$(CONFIG_SOUND_OPL3SA2) += opl3sa2.o ad1848.o mpu401.o | 21 | obj-$(CONFIG_SOUND_OPL3SA2) += opl3sa2.o ad1848.o mpu401.o |
24 | obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o | 22 | obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o |
25 | obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o | 23 | obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o |
26 | obj-$(CONFIG_SOUND_KAHLUA) += kahlua.o | 24 | obj-$(CONFIG_SOUND_KAHLUA) += kahlua.o |
27 | obj-$(CONFIG_SOUND_WAVEFRONT) += wavefront.o | ||
28 | obj-$(CONFIG_SOUND_MAUI) += maui.o mpu401.o | ||
29 | obj-$(CONFIG_SOUND_MPU401) += mpu401.o | 25 | obj-$(CONFIG_SOUND_MPU401) += mpu401.o |
30 | obj-$(CONFIG_SOUND_UART6850) += uart6850.o | 26 | obj-$(CONFIG_SOUND_UART6850) += uart6850.o |
31 | obj-$(CONFIG_SOUND_GUS) += gus.o ad1848.o | ||
32 | obj-$(CONFIG_SOUND_ADLIB) += adlib_card.o opl3.o | 27 | obj-$(CONFIG_SOUND_ADLIB) += adlib_card.o opl3.o |
33 | obj-$(CONFIG_SOUND_YM3812) += opl3.o | 28 | obj-$(CONFIG_SOUND_YM3812) += opl3.o |
34 | obj-$(CONFIG_SOUND_VMIDI) += v_midi.o | 29 | obj-$(CONFIG_SOUND_VMIDI) += v_midi.o |
35 | obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o | 30 | obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o |
36 | obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o | 31 | obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o |
37 | obj-$(CONFIG_SOUND_SGALAXY) += sgalaxy.o ad1848.o | ||
38 | obj-$(CONFIG_SOUND_AD1816) += ad1816.o | 32 | obj-$(CONFIG_SOUND_AD1816) += ad1816.o |
39 | obj-$(CONFIG_SOUND_AD1889) += ad1889.o ac97_codec.o | 33 | obj-$(CONFIG_SOUND_AD1889) += ad1889.o ac97_codec.o |
40 | obj-$(CONFIG_SOUND_ACI_MIXER) += aci.o | 34 | obj-$(CONFIG_SOUND_ACI_MIXER) += aci.o |
41 | obj-$(CONFIG_SOUND_AWE32_SYNTH) += awe_wave.o | ||
42 | 35 | ||
43 | obj-$(CONFIG_SOUND_VIA82CXXX) += via82cxxx_audio.o ac97_codec.o | 36 | obj-$(CONFIG_SOUND_VIA82CXXX) += via82cxxx_audio.o ac97_codec.o |
44 | ifeq ($(CONFIG_MIDI_VIA82CXXX),y) | 37 | ifeq ($(CONFIG_MIDI_VIA82CXXX),y) |
45 | obj-$(CONFIG_SOUND_VIA82CXXX) += sound.o uart401.o | 38 | obj-$(CONFIG_SOUND_VIA82CXXX) += sound.o uart401.o |
46 | endif | 39 | endif |
47 | obj-$(CONFIG_SOUND_YMFPCI) += ymfpci.o ac97_codec.o | ||
48 | ifeq ($(CONFIG_SOUND_YMFPCI_LEGACY),y) | ||
49 | obj-$(CONFIG_SOUND_YMFPCI) += opl3.o uart401.o | ||
50 | endif | ||
51 | obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o | 40 | obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o |
52 | obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o | 41 | obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o |
53 | obj-$(CONFIG_SOUND_VWSND) += vwsnd.o | 42 | obj-$(CONFIG_SOUND_VWSND) += vwsnd.o |
54 | obj-$(CONFIG_SOUND_NM256) += nm256_audio.o ac97.o | 43 | obj-$(CONFIG_SOUND_NM256) += nm256_audio.o ac97.o |
55 | obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97_codec.o | 44 | obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97_codec.o |
56 | obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o | ||
57 | obj-$(CONFIG_SOUND_CMPCI) += cmpci.o | ||
58 | ifeq ($(CONFIG_SOUND_CMPCI_FM),y) | ||
59 | obj-$(CONFIG_SOUND_CMPCI) += sound.o opl3.o | ||
60 | endif | ||
61 | ifeq ($(CONFIG_SOUND_CMPCI_MIDI),y) | ||
62 | obj-$(CONFIG_SOUND_CMPCI) += sound.o mpu401.o | ||
63 | endif | ||
64 | obj-$(CONFIG_SOUND_ES1370) += es1370.o | ||
65 | obj-$(CONFIG_SOUND_ES1371) += es1371.o ac97_codec.o | 45 | obj-$(CONFIG_SOUND_ES1371) += es1371.o ac97_codec.o |
66 | obj-$(CONFIG_SOUND_VRC5477) += nec_vrc5477.o ac97_codec.o | 46 | obj-$(CONFIG_SOUND_VRC5477) += nec_vrc5477.o ac97_codec.o |
67 | obj-$(CONFIG_SOUND_AU1000) += au1000.o ac97_codec.o | ||
68 | obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o | 47 | obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o |
69 | obj-$(CONFIG_SOUND_ESSSOLO1) += esssolo1.o | ||
70 | obj-$(CONFIG_SOUND_FUSION) += cs46xx.o ac97_codec.o | 48 | obj-$(CONFIG_SOUND_FUSION) += cs46xx.o ac97_codec.o |
71 | obj-$(CONFIG_SOUND_MAESTRO) += maestro.o | ||
72 | obj-$(CONFIG_SOUND_MAESTRO3) += maestro3.o ac97_codec.o | ||
73 | obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o | 49 | obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o |
74 | obj-$(CONFIG_SOUND_HARMONY) += harmony.o | ||
75 | obj-$(CONFIG_SOUND_EMU10K1) += ac97_codec.o | 50 | obj-$(CONFIG_SOUND_EMU10K1) += ac97_codec.o |
76 | obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o | 51 | obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o |
77 | obj-$(CONFIG_SOUND_RME96XX) += rme96xx.o | ||
78 | obj-$(CONFIG_SOUND_BT878) += btaudio.o | 52 | obj-$(CONFIG_SOUND_BT878) += btaudio.o |
79 | obj-$(CONFIG_SOUND_ALI5455) += ali5455.o ac97_codec.o | ||
80 | obj-$(CONFIG_SOUND_FORTE) += forte.o ac97_codec.o | ||
81 | 53 | ||
82 | obj-$(CONFIG_SOUND_AD1980) += ac97_plugin_ad1980.o ac97_codec.o | ||
83 | obj-$(CONFIG_SOUND_WM97XX) += ac97_plugin_wm97xx.o | 54 | obj-$(CONFIG_SOUND_WM97XX) += ac97_plugin_wm97xx.o |
84 | 55 | ||
85 | ifeq ($(CONFIG_MIDI_EMU10K1),y) | 56 | ifeq ($(CONFIG_MIDI_EMU10K1),y) |
@@ -87,7 +58,6 @@ ifeq ($(CONFIG_MIDI_EMU10K1),y) | |||
87 | endif | 58 | endif |
88 | 59 | ||
89 | obj-$(CONFIG_SOUND_EMU10K1) += emu10k1/ | 60 | obj-$(CONFIG_SOUND_EMU10K1) += emu10k1/ |
90 | obj-$(CONFIG_SOUND_CS4281) += cs4281/ | ||
91 | obj-$(CONFIG_DMASOUND) += dmasound/ | 61 | obj-$(CONFIG_DMASOUND) += dmasound/ |
92 | 62 | ||
93 | # Declare multi-part drivers. | 63 | # Declare multi-part drivers. |
@@ -98,17 +68,15 @@ sound-objs := \ | |||
98 | midi_syms.o midi_synth.o midibuf.o \ | 68 | midi_syms.o midi_synth.o midibuf.o \ |
99 | sequencer.o sequencer_syms.o sound_timer.o sys_timer.o | 69 | sequencer.o sequencer_syms.o sound_timer.o sys_timer.o |
100 | 70 | ||
101 | gus-objs := gus_card.o gus_midi.o gus_vol.o gus_wave.o ics2101.o | ||
102 | pas2-objs := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o | 71 | pas2-objs := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o |
103 | sb-objs := sb_card.o | 72 | sb-objs := sb_card.o |
104 | sb_lib-objs := sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o | 73 | sb_lib-objs := sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o |
105 | vidc_mod-objs := vidc.o vidc_fill.o | 74 | vidc_mod-objs := vidc.o vidc_fill.o |
106 | wavefront-objs := wavfront.o wf_midi.o yss225.o | ||
107 | 75 | ||
108 | hostprogs-y := bin2hex hex2hex | 76 | hostprogs-y := bin2hex hex2hex |
109 | 77 | ||
110 | # Files generated that shall be removed upon make clean | 78 | # Files generated that shall be removed upon make clean |
111 | clean-files := maui_boot.h msndperm.c msndinit.c pndsperm.c pndspini.c \ | 79 | clean-files := msndperm.c msndinit.c pndsperm.c pndspini.c \ |
112 | pss_boot.h trix_boot.h | 80 | pss_boot.h trix_boot.h |
113 | 81 | ||
114 | # Firmware files that need translation | 82 | # Firmware files that need translation |
@@ -118,21 +86,6 @@ clean-files := maui_boot.h msndperm.c msndinit.c pndsperm.c pndspini.c \ | |||
118 | # will be forced to be remade. | 86 | # will be forced to be remade. |
119 | # | 87 | # |
120 | 88 | ||
121 | # Turtle Beach Maui / Tropez | ||
122 | |||
123 | $(obj)/maui.o: $(obj)/maui_boot.h | ||
124 | |||
125 | ifeq ($(CONFIG_MAUI_HAVE_BOOT),y) | ||
126 | $(obj)/maui_boot.h: $(patsubst "%", %, $(CONFIG_MAUI_BOOT_FILE)) $(obj)/bin2hex | ||
127 | $(obj)/bin2hex -i maui_os < $< > $@ | ||
128 | else | ||
129 | $(obj)/maui_boot.h: | ||
130 | ( \ | ||
131 | echo 'static unsigned char * maui_os = NULL;'; \ | ||
132 | echo 'static int maui_osLen = 0;'; \ | ||
133 | ) > $@ | ||
134 | endif | ||
135 | |||
136 | # Turtle Beach MultiSound | 89 | # Turtle Beach MultiSound |
137 | 90 | ||
138 | ifeq ($(CONFIG_MSNDCLAS_HAVE_BOOT),y) | 91 | ifeq ($(CONFIG_MSNDCLAS_HAVE_BOOT),y) |
diff --git a/sound/oss/ac97.c b/sound/oss/ac97.c index 3ba6d91e891d..72cf4ed77937 100644 --- a/sound/oss/ac97.c +++ b/sound/oss/ac97.c | |||
@@ -112,25 +112,6 @@ ac97_init (struct ac97_hwint *dev) | |||
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | 114 | ||
115 | /* Reset the mixer to the currently saved settings. */ | ||
116 | int | ||
117 | ac97_reset (struct ac97_hwint *dev) | ||
118 | { | ||
119 | int x; | ||
120 | |||
121 | if (dev->reset_device (dev)) | ||
122 | return -1; | ||
123 | |||
124 | /* Now set the registers back to their last-written values. */ | ||
125 | for (x = 0; mixerRegs[x].ac97_regnum != -1; x++) { | ||
126 | int regnum = mixerRegs[x].ac97_regnum; | ||
127 | int value = dev->last_written_mixer_values [regnum / 2]; | ||
128 | if (value >= 0) | ||
129 | ac97_put_register (dev, regnum, value); | ||
130 | } | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | /* Return the contents of register REG; use the cache if the value in it | 115 | /* Return the contents of register REG; use the cache if the value in it |
135 | is valid. Returns a negative error code on failure. */ | 116 | is valid. Returns a negative error code on failure. */ |
136 | static int | 117 | static int |
@@ -441,7 +422,6 @@ EXPORT_SYMBOL(ac97_init); | |||
441 | EXPORT_SYMBOL(ac97_set_values); | 422 | EXPORT_SYMBOL(ac97_set_values); |
442 | EXPORT_SYMBOL(ac97_put_register); | 423 | EXPORT_SYMBOL(ac97_put_register); |
443 | EXPORT_SYMBOL(ac97_mixer_ioctl); | 424 | EXPORT_SYMBOL(ac97_mixer_ioctl); |
444 | EXPORT_SYMBOL(ac97_reset); | ||
445 | MODULE_LICENSE("GPL"); | 425 | MODULE_LICENSE("GPL"); |
446 | 426 | ||
447 | 427 | ||
diff --git a/sound/oss/ac97.h b/sound/oss/ac97.h index 77d454ea3202..01837a9d7d6e 100644 --- a/sound/oss/ac97.h +++ b/sound/oss/ac97.h | |||
@@ -192,9 +192,6 @@ extern int ac97_put_register (struct ac97_hwint *dev, u8 reg, u16 value); | |||
192 | extern int ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd, | 192 | extern int ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd, |
193 | void __user * arg); | 193 | void __user * arg); |
194 | 194 | ||
195 | /* Do a complete reset on the AC97 mixer, restoring all mixer registers to | ||
196 | the current values. Normally used after an APM resume event. */ | ||
197 | extern int ac97_reset (struct ac97_hwint *dev); | ||
198 | #endif | 195 | #endif |
199 | 196 | ||
200 | /* | 197 | /* |
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c index 972327c97644..602db497929a 100644 --- a/sound/oss/ac97_codec.c +++ b/sound/oss/ac97_codec.c | |||
@@ -1399,95 +1399,6 @@ unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate) | |||
1399 | 1399 | ||
1400 | EXPORT_SYMBOL(ac97_set_adc_rate); | 1400 | EXPORT_SYMBOL(ac97_set_adc_rate); |
1401 | 1401 | ||
1402 | int ac97_save_state(struct ac97_codec *codec) | ||
1403 | { | ||
1404 | return 0; | ||
1405 | } | ||
1406 | |||
1407 | EXPORT_SYMBOL(ac97_save_state); | ||
1408 | |||
1409 | int ac97_restore_state(struct ac97_codec *codec) | ||
1410 | { | ||
1411 | int i; | ||
1412 | unsigned int left, right, val; | ||
1413 | |||
1414 | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||
1415 | if (!supported_mixer(codec, i)) | ||
1416 | continue; | ||
1417 | |||
1418 | val = codec->mixer_state[i]; | ||
1419 | right = val >> 8; | ||
1420 | left = val & 0xff; | ||
1421 | codec->write_mixer(codec, i, left, right); | ||
1422 | } | ||
1423 | return 0; | ||
1424 | } | ||
1425 | |||
1426 | EXPORT_SYMBOL(ac97_restore_state); | ||
1427 | |||
1428 | /** | ||
1429 | * ac97_register_driver - register a codec helper | ||
1430 | * @driver: Driver handler | ||
1431 | * | ||
1432 | * Register a handler for codecs matching the codec id. The handler | ||
1433 | * attach function is called for all present codecs and will be | ||
1434 | * called when new codecs are discovered. | ||
1435 | */ | ||
1436 | |||
1437 | int ac97_register_driver(struct ac97_driver *driver) | ||
1438 | { | ||
1439 | struct list_head *l; | ||
1440 | struct ac97_codec *c; | ||
1441 | |||
1442 | mutex_lock(&codec_mutex); | ||
1443 | INIT_LIST_HEAD(&driver->list); | ||
1444 | list_add(&driver->list, &codec_drivers); | ||
1445 | |||
1446 | list_for_each(l, &codecs) | ||
1447 | { | ||
1448 | c = list_entry(l, struct ac97_codec, list); | ||
1449 | if(c->driver != NULL || ((c->model ^ driver->codec_id) & driver->codec_mask)) | ||
1450 | continue; | ||
1451 | if(driver->probe(c, driver)) | ||
1452 | continue; | ||
1453 | c->driver = driver; | ||
1454 | } | ||
1455 | mutex_unlock(&codec_mutex); | ||
1456 | return 0; | ||
1457 | } | ||
1458 | |||
1459 | EXPORT_SYMBOL_GPL(ac97_register_driver); | ||
1460 | |||
1461 | /** | ||
1462 | * ac97_unregister_driver - unregister a codec helper | ||
1463 | * @driver: Driver handler | ||
1464 | * | ||
1465 | * Unregister a handler for codecs matching the codec id. The handler | ||
1466 | * remove function is called for all matching codecs. | ||
1467 | */ | ||
1468 | |||
1469 | void ac97_unregister_driver(struct ac97_driver *driver) | ||
1470 | { | ||
1471 | struct list_head *l; | ||
1472 | struct ac97_codec *c; | ||
1473 | |||
1474 | mutex_lock(&codec_mutex); | ||
1475 | list_del_init(&driver->list); | ||
1476 | |||
1477 | list_for_each(l, &codecs) | ||
1478 | { | ||
1479 | c = list_entry(l, struct ac97_codec, list); | ||
1480 | if (c->driver == driver) { | ||
1481 | driver->remove(c, driver); | ||
1482 | c->driver = NULL; | ||
1483 | } | ||
1484 | } | ||
1485 | |||
1486 | mutex_unlock(&codec_mutex); | ||
1487 | } | ||
1488 | |||
1489 | EXPORT_SYMBOL_GPL(ac97_unregister_driver); | ||
1490 | |||
1491 | static int swap_headphone(int remove_master) | 1402 | static int swap_headphone(int remove_master) |
1492 | { | 1403 | { |
1493 | struct list_head *l; | 1404 | struct list_head *l; |
diff --git a/sound/oss/ac97_plugin_ad1980.c b/sound/oss/ac97_plugin_ad1980.c deleted file mode 100644 index 24a9acd28160..000000000000 --- a/sound/oss/ac97_plugin_ad1980.c +++ /dev/null | |||
@@ -1,126 +0,0 @@ | |||
1 | /* | ||
2 | ac97_plugin_ad1980.c Copyright (C) 2003 Red Hat, Inc. All rights reserved. | ||
3 | |||
4 | The contents of this file are subject to the Open Software License version 1.1 | ||
5 | that can be found at http://www.opensource.org/licenses/osl-1.1.txt and is | ||
6 | included herein by reference. | ||
7 | |||
8 | Alternatively, the contents of this file may be used under the | ||
9 | terms of the GNU General Public License version 2 (the "GPL") as | ||
10 | distributed in the kernel source COPYING file, in which | ||
11 | case the provisions of the GPL are applicable instead of the | ||
12 | above. If you wish to allow the use of your version of this file | ||
13 | only under the terms of the GPL and not to allow others to use | ||
14 | your version of this file under the OSL, indicate your decision | ||
15 | by deleting the provisions above and replace them with the notice | ||
16 | and other provisions required by the GPL. If you do not delete | ||
17 | the provisions above, a recipient may use your version of this | ||
18 | file under either the OSL or the GPL. | ||
19 | |||
20 | Authors: Alan Cox <alan@redhat.com> | ||
21 | |||
22 | This is an example codec plugin. This one switches the connections | ||
23 | around to match the setups some vendors use with audio switched to | ||
24 | non standard front connectors not the normal rear ones | ||
25 | |||
26 | This code primarily exists to demonstrate how to use the codec | ||
27 | interface | ||
28 | |||
29 | */ | ||
30 | |||
31 | #include <linux/config.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/kernel.h> | ||
35 | #include <linux/ac97_codec.h> | ||
36 | |||
37 | /** | ||
38 | * ad1980_remove - codec remove callback | ||
39 | * @codec: The codec that is being removed | ||
40 | * | ||
41 | * This callback occurs when an AC97 codec is being removed. A | ||
42 | * codec remove call will not occur for a codec during that codec | ||
43 | * probe callback. | ||
44 | * | ||
45 | * Most drivers will need to lock their remove versus their | ||
46 | * use of the codec after the probe function. | ||
47 | */ | ||
48 | |||
49 | static void __devexit ad1980_remove(struct ac97_codec *codec, struct ac97_driver *driver) | ||
50 | { | ||
51 | /* Nothing to do in the simple example */ | ||
52 | } | ||
53 | |||
54 | |||
55 | /** | ||
56 | * ad1980_probe - codec found callback | ||
57 | * @codec: ac97 codec matching the idents | ||
58 | * @driver: ac97_driver it matched | ||
59 | * | ||
60 | * This entry point is called when a codec is found which matches | ||
61 | * the driver. At the point it is called the codec is basically | ||
62 | * operational, mixer operations have been initialised and can | ||
63 | * be overriden. Called in process context. The field driver_private | ||
64 | * is available for the driver to use to store stuff. | ||
65 | * | ||
66 | * The caller can claim the device by returning zero, or return | ||
67 | * a negative error code. | ||
68 | */ | ||
69 | |||
70 | static int ad1980_probe(struct ac97_codec *codec, struct ac97_driver *driver) | ||
71 | { | ||
72 | u16 control; | ||
73 | |||
74 | #define AC97_AD_MISC 0x76 | ||
75 | |||
76 | /* Switch the inputs/outputs over (from Dell code) */ | ||
77 | control = codec->codec_read(codec, AC97_AD_MISC); | ||
78 | codec->codec_write(codec, AC97_AD_MISC, control | 0x4420); | ||
79 | |||
80 | /* We could refuse the device since we dont need to hang around, | ||
81 | but we will claim it */ | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | |||
86 | static struct ac97_driver ad1980_driver = { | ||
87 | .codec_id = 0x41445370, | ||
88 | .codec_mask = 0xFFFFFFFF, | ||
89 | .name = "AD1980 example", | ||
90 | .probe = ad1980_probe, | ||
91 | .remove = __devexit_p(ad1980_remove), | ||
92 | }; | ||
93 | |||
94 | /** | ||
95 | * ad1980_exit - module exit path | ||
96 | * | ||
97 | * Our module is being unloaded. At this point unregister_driver | ||
98 | * will call back our remove handler for any existing codecs. You | ||
99 | * may not unregister_driver from interrupt context or from a | ||
100 | * probe/remove callback. | ||
101 | */ | ||
102 | |||
103 | static void ad1980_exit(void) | ||
104 | { | ||
105 | ac97_unregister_driver(&ad1980_driver); | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | * ad1980_init - set up ad1980 handlers | ||
110 | * | ||
111 | * After we call the register function it will call our probe | ||
112 | * function for each existing matching device before returning to us. | ||
113 | * Any devices appearing afterwards whose id's match the codec_id | ||
114 | * will also cause the probe function to be called. | ||
115 | * You may not register_driver from interrupt context or from a | ||
116 | * probe/remove callback. | ||
117 | */ | ||
118 | |||
119 | static int ad1980_init(void) | ||
120 | { | ||
121 | return ac97_register_driver(&ad1980_driver); | ||
122 | } | ||
123 | |||
124 | module_init(ad1980_init); | ||
125 | module_exit(ad1980_exit); | ||
126 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c index f6b6b886c2ad..257b7536fb18 100644 --- a/sound/oss/ad1848.c +++ b/sound/oss/ad1848.c | |||
@@ -195,6 +195,7 @@ static void ad1848_halt(int dev); | |||
195 | static void ad1848_halt_input(int dev); | 195 | static void ad1848_halt_input(int dev); |
196 | static void ad1848_halt_output(int dev); | 196 | static void ad1848_halt_output(int dev); |
197 | static void ad1848_trigger(int dev, int bits); | 197 | static void ad1848_trigger(int dev, int bits); |
198 | static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy); | ||
198 | 199 | ||
199 | #ifndef EXCLUDE_TIMERS | 200 | #ifndef EXCLUDE_TIMERS |
200 | static int ad1848_tmr_install(int dev); | 201 | static int ad1848_tmr_install(int dev); |
@@ -2195,7 +2196,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int | |||
2195 | printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base); | 2196 | printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base); |
2196 | } | 2197 | } |
2197 | 2198 | ||
2198 | irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy) | 2199 | static irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy) |
2199 | { | 2200 | { |
2200 | unsigned char status; | 2201 | unsigned char status; |
2201 | ad1848_info *devc; | 2202 | ad1848_info *devc; |
@@ -2802,7 +2803,6 @@ EXPORT_SYMBOL(ad1848_detect); | |||
2802 | EXPORT_SYMBOL(ad1848_init); | 2803 | EXPORT_SYMBOL(ad1848_init); |
2803 | EXPORT_SYMBOL(ad1848_unload); | 2804 | EXPORT_SYMBOL(ad1848_unload); |
2804 | EXPORT_SYMBOL(ad1848_control); | 2805 | EXPORT_SYMBOL(ad1848_control); |
2805 | EXPORT_SYMBOL(adintr); | ||
2806 | EXPORT_SYMBOL(probe_ms_sound); | 2806 | EXPORT_SYMBOL(probe_ms_sound); |
2807 | EXPORT_SYMBOL(attach_ms_sound); | 2807 | EXPORT_SYMBOL(attach_ms_sound); |
2808 | EXPORT_SYMBOL(unload_ms_sound); | 2808 | EXPORT_SYMBOL(unload_ms_sound); |
diff --git a/sound/oss/ad1848.h b/sound/oss/ad1848.h index d0573b023973..b95ebe28d426 100644 --- a/sound/oss/ad1848.h +++ b/sound/oss/ad1848.h | |||
@@ -18,7 +18,6 @@ void ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int | |||
18 | int ad1848_detect (struct resource *ports, int *flags, int *osp); | 18 | int ad1848_detect (struct resource *ports, int *flags, int *osp); |
19 | int ad1848_control(int cmd, int arg); | 19 | int ad1848_control(int cmd, int arg); |
20 | 20 | ||
21 | irqreturn_t adintr(int irq, void *dev_id, struct pt_regs * dummy); | ||
22 | void attach_ms_sound(struct address_info * hw_config, struct resource *ports, struct module * owner); | 21 | void attach_ms_sound(struct address_info * hw_config, struct resource *ports, struct module * owner); |
23 | 22 | ||
24 | int probe_ms_sound(struct address_info *hw_config, struct resource *ports); | 23 | int probe_ms_sound(struct address_info *hw_config, struct resource *ports); |
diff --git a/sound/oss/ali5455.c b/sound/oss/ali5455.c deleted file mode 100644 index 70dcd703a66f..000000000000 --- a/sound/oss/ali5455.c +++ /dev/null | |||
@@ -1,3735 +0,0 @@ | |||
1 | /* | ||
2 | * ALI ali5455 and friends ICH driver for Linux | ||
3 | * LEI HU <Lei_Hu@ali.com.tw> | ||
4 | * | ||
5 | * Built from: | ||
6 | * drivers/sound/i810_audio | ||
7 | * | ||
8 | * The ALi 5455 is similar but not quite identical to the Intel ICH | ||
9 | * series of controllers. Its easier to keep the driver separated from | ||
10 | * the i810 driver. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | * | ||
26 | * | ||
27 | * ALi 5455 theory of operation | ||
28 | * | ||
29 | * The chipset provides three DMA channels that talk to an AC97 | ||
30 | * CODEC (AC97 is a digital/analog mixer standard). At its simplest | ||
31 | * you get 48Khz audio with basic volume and mixer controls. At the | ||
32 | * best you get rate adaption in the codec. We set the card up so | ||
33 | * that we never take completion interrupts but instead keep the card | ||
34 | * chasing its tail around a ring buffer. This is needed for mmap | ||
35 | * mode audio and happens to work rather well for non-mmap modes too. | ||
36 | * | ||
37 | * The board has one output channel for PCM audio (supported) and | ||
38 | * a stereo line in and mono microphone input. Again these are normally | ||
39 | * locked to 48Khz only. Right now recording is not finished. | ||
40 | * | ||
41 | * There is no midi support, no synth support. Use timidity. To get | ||
42 | * esd working you need to use esd -r 48000 as it won't probe 48KHz | ||
43 | * by default. mpg123 can't handle 48Khz only audio so use xmms. | ||
44 | * | ||
45 | * If you need to force a specific rate set the clocking= option | ||
46 | * | ||
47 | */ | ||
48 | |||
49 | #include <linux/module.h> | ||
50 | #include <linux/string.h> | ||
51 | #include <linux/ctype.h> | ||
52 | #include <linux/ioport.h> | ||
53 | #include <linux/sched.h> | ||
54 | #include <linux/delay.h> | ||
55 | #include <linux/sound.h> | ||
56 | #include <linux/slab.h> | ||
57 | #include <linux/soundcard.h> | ||
58 | #include <linux/pci.h> | ||
59 | #include <asm/io.h> | ||
60 | #include <asm/dma.h> | ||
61 | #include <linux/init.h> | ||
62 | #include <linux/poll.h> | ||
63 | #include <linux/spinlock.h> | ||
64 | #include <linux/smp_lock.h> | ||
65 | #include <linux/ac97_codec.h> | ||
66 | #include <linux/interrupt.h> | ||
67 | #include <linux/mutex.h> | ||
68 | |||
69 | #include <asm/uaccess.h> | ||
70 | |||
71 | #ifndef PCI_DEVICE_ID_ALI_5455 | ||
72 | #define PCI_DEVICE_ID_ALI_5455 0x5455 | ||
73 | #endif | ||
74 | |||
75 | #ifndef PCI_VENDOR_ID_ALI | ||
76 | #define PCI_VENDOR_ID_ALI 0x10b9 | ||
77 | #endif | ||
78 | |||
79 | static int strict_clocking = 0; | ||
80 | static unsigned int clocking = 0; | ||
81 | static unsigned int codec_pcmout_share_spdif_locked = 0; | ||
82 | static unsigned int codec_independent_spdif_locked = 0; | ||
83 | static unsigned int controller_pcmout_share_spdif_locked = 0; | ||
84 | static unsigned int controller_independent_spdif_locked = 0; | ||
85 | static unsigned int globel = 0; | ||
86 | |||
87 | #define ADC_RUNNING 1 | ||
88 | #define DAC_RUNNING 2 | ||
89 | #define CODEC_SPDIFOUT_RUNNING 8 | ||
90 | #define CONTROLLER_SPDIFOUT_RUNNING 4 | ||
91 | |||
92 | #define SPDIF_ENABLE_OUTPUT 4 /* bits 0,1 are PCM */ | ||
93 | |||
94 | #define ALI5455_FMT_16BIT 1 | ||
95 | #define ALI5455_FMT_STEREO 2 | ||
96 | #define ALI5455_FMT_MASK 3 | ||
97 | |||
98 | #define SPDIF_ON 0x0004 | ||
99 | #define SURR_ON 0x0010 | ||
100 | #define CENTER_LFE_ON 0x0020 | ||
101 | #define VOL_MUTED 0x8000 | ||
102 | |||
103 | |||
104 | #define ALI_SPDIF_OUT_CH_STATUS 0xbf | ||
105 | /* the 810's array of pointers to data buffers */ | ||
106 | |||
107 | struct sg_item { | ||
108 | #define BUSADDR_MASK 0xFFFFFFFE | ||
109 | u32 busaddr; | ||
110 | #define CON_IOC 0x80000000 /* interrupt on completion */ | ||
111 | #define CON_BUFPAD 0x40000000 /* pad underrun with last sample, else 0 */ | ||
112 | #define CON_BUFLEN_MASK 0x0000ffff /* buffer length in samples */ | ||
113 | u32 control; | ||
114 | }; | ||
115 | |||
116 | /* an instance of the ali channel */ | ||
117 | #define SG_LEN 32 | ||
118 | struct ali_channel { | ||
119 | /* these sg guys should probably be allocated | ||
120 | separately as nocache. Must be 8 byte aligned */ | ||
121 | struct sg_item sg[SG_LEN]; /* 32*8 */ | ||
122 | u32 offset; /* 4 */ | ||
123 | u32 port; /* 4 */ | ||
124 | u32 used; | ||
125 | u32 num; | ||
126 | }; | ||
127 | |||
128 | /* | ||
129 | * we have 3 separate dma engines. pcm in, pcm out, and mic. | ||
130 | * each dma engine has controlling registers. These goofy | ||
131 | * names are from the datasheet, but make it easy to write | ||
132 | * code while leafing through it. | ||
133 | */ | ||
134 | |||
135 | #define ENUM_ENGINE(PRE,DIG) \ | ||
136 | enum { \ | ||
137 | PRE##_BDBAR = 0x##DIG##0, /* Buffer Descriptor list Base Address */ \ | ||
138 | PRE##_CIV = 0x##DIG##4, /* Current Index Value */ \ | ||
139 | PRE##_LVI = 0x##DIG##5, /* Last Valid Index */ \ | ||
140 | PRE##_SR = 0x##DIG##6, /* Status Register */ \ | ||
141 | PRE##_PICB = 0x##DIG##8, /* Position In Current Buffer */ \ | ||
142 | PRE##_CR = 0x##DIG##b /* Control Register */ \ | ||
143 | } | ||
144 | |||
145 | ENUM_ENGINE(OFF, 0); /* Offsets */ | ||
146 | ENUM_ENGINE(PI, 4); /* PCM In */ | ||
147 | ENUM_ENGINE(PO, 5); /* PCM Out */ | ||
148 | ENUM_ENGINE(MC, 6); /* Mic In */ | ||
149 | ENUM_ENGINE(CODECSPDIFOUT, 7); /* CODEC SPDIF OUT */ | ||
150 | ENUM_ENGINE(CONTROLLERSPDIFIN, A); /* CONTROLLER SPDIF In */ | ||
151 | ENUM_ENGINE(CONTROLLERSPDIFOUT, B); /* CONTROLLER SPDIF OUT */ | ||
152 | |||
153 | |||
154 | enum { | ||
155 | ALI_SCR = 0x00, /* System Control Register */ | ||
156 | ALI_SSR = 0x04, /* System Status Register */ | ||
157 | ALI_DMACR = 0x08, /* DMA Control Register */ | ||
158 | ALI_FIFOCR1 = 0x0c, /* FIFO Control Register 1 */ | ||
159 | ALI_INTERFACECR = 0x10, /* Interface Control Register */ | ||
160 | ALI_INTERRUPTCR = 0x14, /* Interrupt control Register */ | ||
161 | ALI_INTERRUPTSR = 0x18, /* Interrupt Status Register */ | ||
162 | ALI_FIFOCR2 = 0x1c, /* FIFO Control Register 2 */ | ||
163 | ALI_CPR = 0x20, /* Command Port Register */ | ||
164 | ALI_SPR = 0x24, /* Status Port Register */ | ||
165 | ALI_FIFOCR3 = 0x2c, /* FIFO Control Register 3 */ | ||
166 | ALI_TTSR = 0x30, /* Transmit Tag Slot Register */ | ||
167 | ALI_RTSR = 0x34, /* Receive Tag Slot Register */ | ||
168 | ALI_CSPSR = 0x38, /* Command/Status Port Status Register */ | ||
169 | ALI_CAS = 0x3c, /* Codec Write Semaphore Register */ | ||
170 | ALI_SPDIFCSR = 0xf8, /* spdif channel status register */ | ||
171 | ALI_SPDIFICS = 0xfc /* spdif interface control/status */ | ||
172 | }; | ||
173 | |||
174 | // x-status register(x:pcm in ,pcm out, mic in,) | ||
175 | /* interrupts for a dma engine */ | ||
176 | #define DMA_INT_FIFO (1<<4) /* fifo under/over flow */ | ||
177 | #define DMA_INT_COMPLETE (1<<3) /* buffer read/write complete and ioc set */ | ||
178 | #define DMA_INT_LVI (1<<2) /* last valid done */ | ||
179 | #define DMA_INT_CELV (1<<1) /* last valid is current */ | ||
180 | #define DMA_INT_DCH (1) /* DMA Controller Halted (happens on LVI interrupts) */ //not eqult intel | ||
181 | #define DMA_INT_MASK (DMA_INT_FIFO|DMA_INT_COMPLETE|DMA_INT_LVI) | ||
182 | |||
183 | /* interrupts for the whole chip */// by interrupt status register finish | ||
184 | |||
185 | #define INT_SPDIFOUT (1<<23) /* controller spdif out INTERRUPT */ | ||
186 | #define INT_SPDIFIN (1<<22) | ||
187 | #define INT_CODECSPDIFOUT (1<<19) | ||
188 | #define INT_MICIN (1<<18) | ||
189 | #define INT_PCMOUT (1<<17) | ||
190 | #define INT_PCMIN (1<<16) | ||
191 | #define INT_CPRAIS (1<<7) | ||
192 | #define INT_SPRAIS (1<<5) | ||
193 | #define INT_GPIO (1<<1) | ||
194 | #define INT_MASK (INT_SPDIFOUT|INT_CODECSPDIFOUT|INT_MICIN|INT_PCMOUT|INT_PCMIN) | ||
195 | |||
196 | #define DRIVER_VERSION "0.02ac" | ||
197 | |||
198 | /* magic numbers to protect our data structures */ | ||
199 | #define ALI5455_CARD_MAGIC 0x5072696E /* "Prin" */ | ||
200 | #define ALI5455_STATE_MAGIC 0x63657373 /* "cess" */ | ||
201 | #define ALI5455_DMA_MASK 0xffffffff /* DMA buffer mask for pci_alloc_consist */ | ||
202 | #define NR_HW_CH 5 //I think 5 channel | ||
203 | |||
204 | /* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */ | ||
205 | #define NR_AC97 2 | ||
206 | |||
207 | /* Please note that an 8bit mono stream is not valid on this card, you must have a 16bit */ | ||
208 | /* stream at a minimum for this card to be happy */ | ||
209 | static const unsigned sample_size[] = { 1, 2, 2, 4 }; | ||
210 | /* Samples are 16bit values, so we are shifting to a word, not to a byte, hence shift */ | ||
211 | /* values are one less than might be expected */ | ||
212 | static const unsigned sample_shift[] = { -1, 0, 0, 1 }; | ||
213 | |||
214 | #define ALI5455 | ||
215 | static char *card_names[] = { | ||
216 | "ALI 5455" | ||
217 | }; | ||
218 | |||
219 | static struct pci_device_id ali_pci_tbl[] = { | ||
220 | {PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5455, | ||
221 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI5455}, | ||
222 | {0,} | ||
223 | }; | ||
224 | |||
225 | MODULE_DEVICE_TABLE(pci, ali_pci_tbl); | ||
226 | |||
227 | #ifdef CONFIG_PM | ||
228 | #define PM_SUSPENDED(card) (card->pm_suspended) | ||
229 | #else | ||
230 | #define PM_SUSPENDED(card) (0) | ||
231 | #endif | ||
232 | |||
233 | /* "software" or virtual channel, an instance of opened /dev/dsp */ | ||
234 | struct ali_state { | ||
235 | unsigned int magic; | ||
236 | struct ali_card *card; /* Card info */ | ||
237 | |||
238 | /* single open lock mechanism, only used for recording */ | ||
239 | struct mutex open_mutex; | ||
240 | wait_queue_head_t open_wait; | ||
241 | |||
242 | /* file mode */ | ||
243 | mode_t open_mode; | ||
244 | |||
245 | /* virtual channel number */ | ||
246 | int virt; | ||
247 | |||
248 | #ifdef CONFIG_PM | ||
249 | unsigned int pm_saved_dac_rate, pm_saved_adc_rate; | ||
250 | #endif | ||
251 | struct dmabuf { | ||
252 | /* wave sample stuff */ | ||
253 | unsigned int rate; | ||
254 | unsigned char fmt, enable, trigger; | ||
255 | |||
256 | /* hardware channel */ | ||
257 | struct ali_channel *read_channel; | ||
258 | struct ali_channel *write_channel; | ||
259 | struct ali_channel *codec_spdifout_channel; | ||
260 | struct ali_channel *controller_spdifout_channel; | ||
261 | |||
262 | /* OSS buffer management stuff */ | ||
263 | void *rawbuf; | ||
264 | dma_addr_t dma_handle; | ||
265 | unsigned buforder; | ||
266 | unsigned numfrag; | ||
267 | unsigned fragshift; | ||
268 | |||
269 | /* our buffer acts like a circular ring */ | ||
270 | unsigned hwptr; /* where dma last started, updated by update_ptr */ | ||
271 | unsigned swptr; /* where driver last clear/filled, updated by read/write */ | ||
272 | int count; /* bytes to be consumed or been generated by dma machine */ | ||
273 | unsigned total_bytes; /* total bytes dmaed by hardware */ | ||
274 | |||
275 | unsigned error; /* number of over/underruns */ | ||
276 | wait_queue_head_t wait; /* put process on wait queue when no more space in buffer */ | ||
277 | |||
278 | /* redundant, but makes calculations easier */ | ||
279 | /* what the hardware uses */ | ||
280 | unsigned dmasize; | ||
281 | unsigned fragsize; | ||
282 | unsigned fragsamples; | ||
283 | |||
284 | /* what we tell the user to expect */ | ||
285 | unsigned userfrags; | ||
286 | unsigned userfragsize; | ||
287 | |||
288 | /* OSS stuff */ | ||
289 | unsigned mapped:1; | ||
290 | unsigned ready:1; | ||
291 | unsigned update_flag; | ||
292 | unsigned ossfragsize; | ||
293 | unsigned ossmaxfrags; | ||
294 | unsigned subdivision; | ||
295 | } dmabuf; | ||
296 | }; | ||
297 | |||
298 | |||
299 | struct ali_card { | ||
300 | struct ali_channel channel[5]; | ||
301 | unsigned int magic; | ||
302 | |||
303 | /* We keep ali5455 cards in a linked list */ | ||
304 | struct ali_card *next; | ||
305 | |||
306 | /* The ali has a certain amount of cross channel interaction | ||
307 | so we use a single per card lock */ | ||
308 | spinlock_t lock; | ||
309 | spinlock_t ac97_lock; | ||
310 | |||
311 | /* PCI device stuff */ | ||
312 | struct pci_dev *pci_dev; | ||
313 | u16 pci_id; | ||
314 | #ifdef CONFIG_PM | ||
315 | u16 pm_suspended; | ||
316 | int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97]; | ||
317 | #endif | ||
318 | /* soundcore stuff */ | ||
319 | int dev_audio; | ||
320 | |||
321 | /* structures for abstraction of hardware facilities, codecs, banks and channels */ | ||
322 | struct ac97_codec *ac97_codec[NR_AC97]; | ||
323 | struct ali_state *states[NR_HW_CH]; | ||
324 | |||
325 | u16 ac97_features; | ||
326 | u16 ac97_status; | ||
327 | u16 channels; | ||
328 | |||
329 | /* hardware resources */ | ||
330 | unsigned long iobase; | ||
331 | |||
332 | u32 irq; | ||
333 | |||
334 | /* Function support */ | ||
335 | struct ali_channel *(*alloc_pcm_channel) (struct ali_card *); | ||
336 | struct ali_channel *(*alloc_rec_pcm_channel) (struct ali_card *); | ||
337 | struct ali_channel *(*alloc_rec_mic_channel) (struct ali_card *); | ||
338 | struct ali_channel *(*alloc_codec_spdifout_channel) (struct ali_card *); | ||
339 | struct ali_channel *(*alloc_controller_spdifout_channel) (struct ali_card *); | ||
340 | void (*free_pcm_channel) (struct ali_card *, int chan); | ||
341 | |||
342 | /* We have a *very* long init time possibly, so use this to block */ | ||
343 | /* attempts to open our devices before we are ready (stops oops'es) */ | ||
344 | int initializing; | ||
345 | }; | ||
346 | |||
347 | |||
348 | static struct ali_card *devs = NULL; | ||
349 | |||
350 | static int ali_open_mixdev(struct inode *inode, struct file *file); | ||
351 | static int ali_ioctl_mixdev(struct inode *inode, struct file *file, | ||
352 | unsigned int cmd, unsigned long arg); | ||
353 | static u16 ali_ac97_get(struct ac97_codec *dev, u8 reg); | ||
354 | static void ali_ac97_set(struct ac97_codec *dev, u8 reg, u16 data); | ||
355 | |||
356 | static struct ali_channel *ali_alloc_pcm_channel(struct ali_card *card) | ||
357 | { | ||
358 | if (card->channel[1].used == 1) | ||
359 | return NULL; | ||
360 | card->channel[1].used = 1; | ||
361 | return &card->channel[1]; | ||
362 | } | ||
363 | |||
364 | static struct ali_channel *ali_alloc_rec_pcm_channel(struct ali_card *card) | ||
365 | { | ||
366 | if (card->channel[0].used == 1) | ||
367 | return NULL; | ||
368 | card->channel[0].used = 1; | ||
369 | return &card->channel[0]; | ||
370 | } | ||
371 | |||
372 | static struct ali_channel *ali_alloc_rec_mic_channel(struct ali_card *card) | ||
373 | { | ||
374 | if (card->channel[2].used == 1) | ||
375 | return NULL; | ||
376 | card->channel[2].used = 1; | ||
377 | return &card->channel[2]; | ||
378 | } | ||
379 | |||
380 | static struct ali_channel *ali_alloc_codec_spdifout_channel(struct ali_card *card) | ||
381 | { | ||
382 | if (card->channel[3].used == 1) | ||
383 | return NULL; | ||
384 | card->channel[3].used = 1; | ||
385 | return &card->channel[3]; | ||
386 | } | ||
387 | |||
388 | static struct ali_channel *ali_alloc_controller_spdifout_channel(struct ali_card *card) | ||
389 | { | ||
390 | if (card->channel[4].used == 1) | ||
391 | return NULL; | ||
392 | card->channel[4].used = 1; | ||
393 | return &card->channel[4]; | ||
394 | } | ||
395 | static void ali_free_pcm_channel(struct ali_card *card, int channel) | ||
396 | { | ||
397 | card->channel[channel].used = 0; | ||
398 | } | ||
399 | |||
400 | |||
401 | //add support codec spdif out | ||
402 | static int ali_valid_spdif_rate(struct ac97_codec *codec, int rate) | ||
403 | { | ||
404 | unsigned long id = 0L; | ||
405 | |||
406 | id = (ali_ac97_get(codec, AC97_VENDOR_ID1) << 16); | ||
407 | id |= ali_ac97_get(codec, AC97_VENDOR_ID2) & 0xffff; | ||
408 | switch (id) { | ||
409 | case 0x41445361: /* AD1886 */ | ||
410 | if (rate == 48000) { | ||
411 | return 1; | ||
412 | } | ||
413 | break; | ||
414 | case 0x414c4720: /* ALC650 */ | ||
415 | if (rate == 48000) { | ||
416 | return 1; | ||
417 | } | ||
418 | break; | ||
419 | default: /* all other codecs, until we know otherwiae */ | ||
420 | if (rate == 48000 || rate == 44100 || rate == 32000) { | ||
421 | return 1; | ||
422 | } | ||
423 | break; | ||
424 | } | ||
425 | return (0); | ||
426 | } | ||
427 | |||
428 | /* ali_set_spdif_output | ||
429 | * | ||
430 | * Configure the S/PDIF output transmitter. When we turn on | ||
431 | * S/PDIF, we turn off the analog output. This may not be | ||
432 | * the right thing to do. | ||
433 | * | ||
434 | * Assumptions: | ||
435 | * The DSP sample rate must already be set to a supported | ||
436 | * S/PDIF rate (32kHz, 44.1kHz, or 48kHz) or we abort. | ||
437 | */ | ||
438 | static void ali_set_spdif_output(struct ali_state *state, int slots, | ||
439 | int rate) | ||
440 | { | ||
441 | int vol; | ||
442 | int aud_reg; | ||
443 | struct ac97_codec *codec = state->card->ac97_codec[0]; | ||
444 | |||
445 | if (!(state->card->ac97_features & 4)) { | ||
446 | state->card->ac97_status &= ~SPDIF_ON; | ||
447 | } else { | ||
448 | if (slots == -1) { /* Turn off S/PDIF */ | ||
449 | aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS); | ||
450 | ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF)); | ||
451 | |||
452 | /* If the volume wasn't muted before we turned on S/PDIF, unmute it */ | ||
453 | if (!(state->card->ac97_status & VOL_MUTED)) { | ||
454 | aud_reg = ali_ac97_get(codec, AC97_MASTER_VOL_STEREO); | ||
455 | ali_ac97_set(codec, AC97_MASTER_VOL_STEREO, | ||
456 | (aud_reg & ~VOL_MUTED)); | ||
457 | } | ||
458 | state->card->ac97_status &= ~(VOL_MUTED | SPDIF_ON); | ||
459 | return; | ||
460 | } | ||
461 | |||
462 | vol = ali_ac97_get(codec, AC97_MASTER_VOL_STEREO); | ||
463 | state->card->ac97_status = vol & VOL_MUTED; | ||
464 | |||
465 | /* Set S/PDIF transmitter sample rate */ | ||
466 | aud_reg = ali_ac97_get(codec, AC97_SPDIF_CONTROL); | ||
467 | switch (rate) { | ||
468 | case 32000: | ||
469 | aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K; | ||
470 | break; | ||
471 | case 44100: | ||
472 | aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K; | ||
473 | break; | ||
474 | case 48000: | ||
475 | aud_reg = (aud_reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K; | ||
476 | break; | ||
477 | default: | ||
478 | /* turn off S/PDIF */ | ||
479 | aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS); | ||
480 | ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF)); | ||
481 | state->card->ac97_status &= ~SPDIF_ON; | ||
482 | return; | ||
483 | } | ||
484 | |||
485 | ali_ac97_set(codec, AC97_SPDIF_CONTROL, aud_reg); | ||
486 | |||
487 | aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS); | ||
488 | aud_reg = (aud_reg & AC97_EA_SLOT_MASK) | slots | AC97_EA_SPDIF; | ||
489 | ali_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg); | ||
490 | |||
491 | aud_reg = ali_ac97_get(codec, AC97_POWER_CONTROL); | ||
492 | aud_reg |= 0x0002; | ||
493 | ali_ac97_set(codec, AC97_POWER_CONTROL, aud_reg); | ||
494 | udelay(1); | ||
495 | |||
496 | state->card->ac97_status |= SPDIF_ON; | ||
497 | |||
498 | /* Check to make sure the configuration is valid */ | ||
499 | aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS); | ||
500 | if (!(aud_reg & 0x0400)) { | ||
501 | /* turn off S/PDIF */ | ||
502 | ali_ac97_set(codec, AC97_EXTENDED_STATUS, (aud_reg & ~AC97_EA_SPDIF)); | ||
503 | state->card->ac97_status &= ~SPDIF_ON; | ||
504 | return; | ||
505 | } | ||
506 | if (codec_independent_spdif_locked > 0) { | ||
507 | aud_reg = ali_ac97_get(codec, 0x6a); | ||
508 | ali_ac97_set(codec, 0x6a, (aud_reg & 0xefff)); | ||
509 | } | ||
510 | /* Mute the analog output */ | ||
511 | /* Should this only mute the PCM volume??? */ | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /* ali_set_dac_channels | ||
516 | * | ||
517 | * Configure the codec's multi-channel DACs | ||
518 | * | ||
519 | * The logic is backwards. Setting the bit to 1 turns off the DAC. | ||
520 | * | ||
521 | * What about the ICH? We currently configure it using the | ||
522 | * SNDCTL_DSP_CHANNELS ioctl. If we're turnning on the DAC, | ||
523 | * does that imply that we want the ICH set to support | ||
524 | * these channels? | ||
525 | * | ||
526 | * TODO: | ||
527 | * vailidate that the codec really supports these DACs | ||
528 | * before turning them on. | ||
529 | */ | ||
530 | static void ali_set_dac_channels(struct ali_state *state, int channel) | ||
531 | { | ||
532 | int aud_reg; | ||
533 | struct ac97_codec *codec = state->card->ac97_codec[0]; | ||
534 | |||
535 | aud_reg = ali_ac97_get(codec, AC97_EXTENDED_STATUS); | ||
536 | aud_reg |= AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK; | ||
537 | state->card->ac97_status &= ~(SURR_ON | CENTER_LFE_ON); | ||
538 | |||
539 | switch (channel) { | ||
540 | case 2: /* always enabled */ | ||
541 | break; | ||
542 | case 4: | ||
543 | aud_reg &= ~AC97_EA_PRJ; | ||
544 | state->card->ac97_status |= SURR_ON; | ||
545 | break; | ||
546 | case 6: | ||
547 | aud_reg &= ~(AC97_EA_PRJ | AC97_EA_PRI | AC97_EA_PRK); | ||
548 | state->card->ac97_status |= SURR_ON | CENTER_LFE_ON; | ||
549 | break; | ||
550 | default: | ||
551 | break; | ||
552 | } | ||
553 | ali_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg); | ||
554 | |||
555 | } | ||
556 | |||
557 | /* set playback sample rate */ | ||
558 | static unsigned int ali_set_dac_rate(struct ali_state *state, | ||
559 | unsigned int rate) | ||
560 | { | ||
561 | struct dmabuf *dmabuf = &state->dmabuf; | ||
562 | u32 new_rate; | ||
563 | struct ac97_codec *codec = state->card->ac97_codec[0]; | ||
564 | |||
565 | if (!(state->card->ac97_features & 0x0001)) { | ||
566 | dmabuf->rate = clocking; | ||
567 | return clocking; | ||
568 | } | ||
569 | |||
570 | if (rate > 48000) | ||
571 | rate = 48000; | ||
572 | if (rate < 8000) | ||
573 | rate = 8000; | ||
574 | dmabuf->rate = rate; | ||
575 | |||
576 | /* | ||
577 | * Adjust for misclocked crap | ||
578 | */ | ||
579 | |||
580 | rate = (rate * clocking) / 48000; | ||
581 | |||
582 | if (strict_clocking && rate < 8000) { | ||
583 | rate = 8000; | ||
584 | dmabuf->rate = (rate * 48000) / clocking; | ||
585 | } | ||
586 | |||
587 | new_rate = ac97_set_dac_rate(codec, rate); | ||
588 | if (new_rate != rate) { | ||
589 | dmabuf->rate = (new_rate * 48000) / clocking; | ||
590 | } | ||
591 | rate = new_rate; | ||
592 | return dmabuf->rate; | ||
593 | } | ||
594 | |||
595 | /* set recording sample rate */ | ||
596 | static unsigned int ali_set_adc_rate(struct ali_state *state, | ||
597 | unsigned int rate) | ||
598 | { | ||
599 | struct dmabuf *dmabuf = &state->dmabuf; | ||
600 | u32 new_rate; | ||
601 | struct ac97_codec *codec = state->card->ac97_codec[0]; | ||
602 | |||
603 | if (!(state->card->ac97_features & 0x0001)) { | ||
604 | dmabuf->rate = clocking; | ||
605 | return clocking; | ||
606 | } | ||
607 | |||
608 | if (rate > 48000) | ||
609 | rate = 48000; | ||
610 | if (rate < 8000) | ||
611 | rate = 8000; | ||
612 | dmabuf->rate = rate; | ||
613 | |||
614 | /* | ||
615 | * Adjust for misclocked crap | ||
616 | */ | ||
617 | |||
618 | rate = (rate * clocking) / 48000; | ||
619 | if (strict_clocking && rate < 8000) { | ||
620 | rate = 8000; | ||
621 | dmabuf->rate = (rate * 48000) / clocking; | ||
622 | } | ||
623 | |||
624 | new_rate = ac97_set_adc_rate(codec, rate); | ||
625 | |||
626 | if (new_rate != rate) { | ||
627 | dmabuf->rate = (new_rate * 48000) / clocking; | ||
628 | rate = new_rate; | ||
629 | } | ||
630 | return dmabuf->rate; | ||
631 | } | ||
632 | |||
633 | /* set codec independent spdifout sample rate */ | ||
634 | static unsigned int ali_set_codecspdifout_rate(struct ali_state *state, | ||
635 | unsigned int rate) | ||
636 | { | ||
637 | struct dmabuf *dmabuf = &state->dmabuf; | ||
638 | |||
639 | if (!(state->card->ac97_features & 0x0001)) { | ||
640 | dmabuf->rate = clocking; | ||
641 | return clocking; | ||
642 | } | ||
643 | |||
644 | if (rate > 48000) | ||
645 | rate = 48000; | ||
646 | if (rate < 8000) | ||
647 | rate = 8000; | ||
648 | dmabuf->rate = rate; | ||
649 | |||
650 | return dmabuf->rate; | ||
651 | } | ||
652 | |||
653 | /* set controller independent spdif out function sample rate */ | ||
654 | static void ali_set_spdifout_rate(struct ali_state *state, | ||
655 | unsigned int rate) | ||
656 | { | ||
657 | unsigned char ch_st_sel; | ||
658 | unsigned short status_rate; | ||
659 | |||
660 | switch (rate) { | ||
661 | case 44100: | ||
662 | status_rate = 0; | ||
663 | break; | ||
664 | case 32000: | ||
665 | status_rate = 0x300; | ||
666 | break; | ||
667 | case 48000: | ||
668 | default: | ||
669 | status_rate = 0x200; | ||
670 | break; | ||
671 | } | ||
672 | |||
673 | ch_st_sel = inb(state->card->iobase + ALI_SPDIFICS) & ALI_SPDIF_OUT_CH_STATUS; //select spdif_out | ||
674 | |||
675 | ch_st_sel |= 0x80; //select right | ||
676 | outb(ch_st_sel, (state->card->iobase + ALI_SPDIFICS)); | ||
677 | outb(status_rate | 0x20, (state->card->iobase + ALI_SPDIFCSR + 2)); | ||
678 | |||
679 | ch_st_sel &= (~0x80); //select left | ||
680 | outb(ch_st_sel, (state->card->iobase + ALI_SPDIFICS)); | ||
681 | outw(status_rate | 0x10, (state->card->iobase + ALI_SPDIFCSR + 2)); | ||
682 | } | ||
683 | |||
684 | /* get current playback/recording dma buffer pointer (byte offset from LBA), | ||
685 | called with spinlock held! */ | ||
686 | |||
687 | static inline unsigned ali_get_dma_addr(struct ali_state *state, int rec) | ||
688 | { | ||
689 | struct dmabuf *dmabuf = &state->dmabuf; | ||
690 | unsigned int civ, offset, port, port_picb; | ||
691 | unsigned int data; | ||
692 | |||
693 | if (!dmabuf->enable) | ||
694 | return 0; | ||
695 | |||
696 | if (rec == 1) | ||
697 | port = state->card->iobase + dmabuf->read_channel->port; | ||
698 | else if (rec == 2) | ||
699 | port = state->card->iobase + dmabuf->codec_spdifout_channel->port; | ||
700 | else if (rec == 3) | ||
701 | port = state->card->iobase + dmabuf->controller_spdifout_channel->port; | ||
702 | else | ||
703 | port = state->card->iobase + dmabuf->write_channel->port; | ||
704 | |||
705 | port_picb = port + OFF_PICB; | ||
706 | |||
707 | do { | ||
708 | civ = inb(port + OFF_CIV) & 31; | ||
709 | offset = inw(port_picb); | ||
710 | /* Must have a delay here! */ | ||
711 | if (offset == 0) | ||
712 | udelay(1); | ||
713 | |||
714 | /* Reread both registers and make sure that that total | ||
715 | * offset from the first reading to the second is 0. | ||
716 | * There is an issue with SiS hardware where it will count | ||
717 | * picb down to 0, then update civ to the next value, | ||
718 | * then set the new picb to fragsize bytes. We can catch | ||
719 | * it between the civ update and the picb update, making | ||
720 | * it look as though we are 1 fragsize ahead of where we | ||
721 | * are. The next to we get the address though, it will | ||
722 | * be back in thdelay is more than long enough | ||
723 | * that we won't have to worry about the chip still being | ||
724 | * out of sync with reality ;-) | ||
725 | */ | ||
726 | } while (civ != (inb(port + OFF_CIV) & 31) || offset != inw(port_picb)); | ||
727 | |||
728 | data = ((civ + 1) * dmabuf->fragsize - (2 * offset)) % dmabuf->dmasize; | ||
729 | if (inw(port_picb) == 0) | ||
730 | data -= 2048; | ||
731 | |||
732 | return data; | ||
733 | } | ||
734 | |||
735 | /* Stop recording (lock held) */ | ||
736 | static inline void __stop_adc(struct ali_state *state) | ||
737 | { | ||
738 | struct dmabuf *dmabuf = &state->dmabuf; | ||
739 | struct ali_card *card = state->card; | ||
740 | |||
741 | dmabuf->enable &= ~ADC_RUNNING; | ||
742 | |||
743 | outl((1 << 18) | (1 << 16), card->iobase + ALI_DMACR); | ||
744 | udelay(1); | ||
745 | |||
746 | outb(0, card->iobase + PI_CR); | ||
747 | while (inb(card->iobase + PI_CR) != 0); | ||
748 | |||
749 | // now clear any latent interrupt bits (like the halt bit) | ||
750 | outb(inb(card->iobase + PI_SR) | 0x001e, card->iobase + PI_SR); | ||
751 | outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_PCMIN, card->iobase + ALI_INTERRUPTSR); | ||
752 | } | ||
753 | |||
754 | static void stop_adc(struct ali_state *state) | ||
755 | { | ||
756 | struct ali_card *card = state->card; | ||
757 | unsigned long flags; | ||
758 | spin_lock_irqsave(&card->lock, flags); | ||
759 | __stop_adc(state); | ||
760 | spin_unlock_irqrestore(&card->lock, flags); | ||
761 | } | ||
762 | |||
763 | static inline void __start_adc(struct ali_state *state) | ||
764 | { | ||
765 | struct dmabuf *dmabuf = &state->dmabuf; | ||
766 | |||
767 | if (dmabuf->count < dmabuf->dmasize && dmabuf->ready | ||
768 | && !dmabuf->enable && (dmabuf->trigger & PCM_ENABLE_INPUT)) { | ||
769 | dmabuf->enable |= ADC_RUNNING; | ||
770 | outb((1 << 4) | (1 << 2), state->card->iobase + PI_CR); | ||
771 | if (state->card->channel[0].used == 1) | ||
772 | outl(1, state->card->iobase + ALI_DMACR); // DMA CONTROL REGISTRER | ||
773 | udelay(100); | ||
774 | if (state->card->channel[2].used == 1) | ||
775 | outl((1 << 2), state->card->iobase + ALI_DMACR); //DMA CONTROL REGISTER | ||
776 | udelay(100); | ||
777 | } | ||
778 | } | ||
779 | |||
780 | static void start_adc(struct ali_state *state) | ||
781 | { | ||
782 | struct ali_card *card = state->card; | ||
783 | unsigned long flags; | ||
784 | |||
785 | spin_lock_irqsave(&card->lock, flags); | ||
786 | __start_adc(state); | ||
787 | spin_unlock_irqrestore(&card->lock, flags); | ||
788 | } | ||
789 | |||
790 | /* stop playback (lock held) */ | ||
791 | static inline void __stop_dac(struct ali_state *state) | ||
792 | { | ||
793 | struct dmabuf *dmabuf = &state->dmabuf; | ||
794 | struct ali_card *card = state->card; | ||
795 | |||
796 | dmabuf->enable &= ~DAC_RUNNING; | ||
797 | outl(0x00020000, card->iobase + 0x08); | ||
798 | outb(0, card->iobase + PO_CR); | ||
799 | while (inb(card->iobase + PO_CR) != 0) | ||
800 | cpu_relax(); | ||
801 | |||
802 | outb(inb(card->iobase + PO_SR) | 0x001e, card->iobase + PO_SR); | ||
803 | |||
804 | outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_PCMOUT, card->iobase + ALI_INTERRUPTSR); | ||
805 | } | ||
806 | |||
807 | static void stop_dac(struct ali_state *state) | ||
808 | { | ||
809 | struct ali_card *card = state->card; | ||
810 | unsigned long flags; | ||
811 | spin_lock_irqsave(&card->lock, flags); | ||
812 | __stop_dac(state); | ||
813 | spin_unlock_irqrestore(&card->lock, flags); | ||
814 | } | ||
815 | |||
816 | static inline void __start_dac(struct ali_state *state) | ||
817 | { | ||
818 | struct dmabuf *dmabuf = &state->dmabuf; | ||
819 | if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable && | ||
820 | (dmabuf->trigger & PCM_ENABLE_OUTPUT)) { | ||
821 | dmabuf->enable |= DAC_RUNNING; | ||
822 | outb((1 << 4) | (1 << 2), state->card->iobase + PO_CR); | ||
823 | outl((1 << 1), state->card->iobase + 0x08); //dma control register | ||
824 | } | ||
825 | } | ||
826 | |||
827 | static void start_dac(struct ali_state *state) | ||
828 | { | ||
829 | struct ali_card *card = state->card; | ||
830 | unsigned long flags; | ||
831 | spin_lock_irqsave(&card->lock, flags); | ||
832 | __start_dac(state); | ||
833 | spin_unlock_irqrestore(&card->lock, flags); | ||
834 | } | ||
835 | |||
836 | /* stop codec and controller spdif out (lock held) */ | ||
837 | static inline void __stop_spdifout(struct ali_state *state) | ||
838 | { | ||
839 | struct dmabuf *dmabuf = &state->dmabuf; | ||
840 | struct ali_card *card = state->card; | ||
841 | |||
842 | if (codec_independent_spdif_locked > 0) { | ||
843 | dmabuf->enable &= ~CODEC_SPDIFOUT_RUNNING; | ||
844 | outl((1 << 19), card->iobase + 0x08); | ||
845 | outb(0, card->iobase + CODECSPDIFOUT_CR); | ||
846 | |||
847 | while (inb(card->iobase + CODECSPDIFOUT_CR) != 0) | ||
848 | cpu_relax(); | ||
849 | |||
850 | outb(inb(card->iobase + CODECSPDIFOUT_SR) | 0x001e, card->iobase + CODECSPDIFOUT_SR); | ||
851 | outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_CODECSPDIFOUT, card->iobase + ALI_INTERRUPTSR); | ||
852 | } else { | ||
853 | if (controller_independent_spdif_locked > 0) { | ||
854 | dmabuf->enable &= ~CONTROLLER_SPDIFOUT_RUNNING; | ||
855 | outl((1 << 23), card->iobase + 0x08); | ||
856 | outb(0, card->iobase + CONTROLLERSPDIFOUT_CR); | ||
857 | while (inb(card->iobase + CONTROLLERSPDIFOUT_CR) != 0) | ||
858 | cpu_relax(); | ||
859 | outb(inb(card->iobase + CONTROLLERSPDIFOUT_SR) | 0x001e, card->iobase + CONTROLLERSPDIFOUT_SR); | ||
860 | outl(inl(card->iobase + ALI_INTERRUPTSR) & INT_SPDIFOUT, card->iobase + ALI_INTERRUPTSR); | ||
861 | } | ||
862 | } | ||
863 | } | ||
864 | |||
865 | static void stop_spdifout(struct ali_state *state) | ||
866 | { | ||
867 | struct ali_card *card = state->card; | ||
868 | unsigned long flags; | ||
869 | spin_lock_irqsave(&card->lock, flags); | ||
870 | __stop_spdifout(state); | ||
871 | spin_unlock_irqrestore(&card->lock, flags); | ||
872 | } | ||
873 | |||
874 | static inline void __start_spdifout(struct ali_state *state) | ||
875 | { | ||
876 | struct dmabuf *dmabuf = &state->dmabuf; | ||
877 | if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable && | ||
878 | (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) { | ||
879 | if (codec_independent_spdif_locked > 0) { | ||
880 | dmabuf->enable |= CODEC_SPDIFOUT_RUNNING; | ||
881 | outb((1 << 4) | (1 << 2), state->card->iobase + CODECSPDIFOUT_CR); | ||
882 | outl((1 << 3), state->card->iobase + 0x08); //dma control register | ||
883 | } else { | ||
884 | if (controller_independent_spdif_locked > 0) { | ||
885 | dmabuf->enable |= CONTROLLER_SPDIFOUT_RUNNING; | ||
886 | outb((1 << 4) | (1 << 2), state->card->iobase + CONTROLLERSPDIFOUT_CR); | ||
887 | outl((1 << 7), state->card->iobase + 0x08); //dma control register | ||
888 | } | ||
889 | } | ||
890 | } | ||
891 | } | ||
892 | |||
893 | static void start_spdifout(struct ali_state *state) | ||
894 | { | ||
895 | struct ali_card *card = state->card; | ||
896 | unsigned long flags; | ||
897 | spin_lock_irqsave(&card->lock, flags); | ||
898 | __start_spdifout(state); | ||
899 | spin_unlock_irqrestore(&card->lock, flags); | ||
900 | } | ||
901 | |||
902 | #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT) | ||
903 | #define DMABUF_MINORDER 1 | ||
904 | |||
905 | /* allocate DMA buffer, playback , recording,spdif out buffer should be allocated separately */ | ||
906 | static int alloc_dmabuf(struct ali_state *state) | ||
907 | { | ||
908 | struct dmabuf *dmabuf = &state->dmabuf; | ||
909 | void *rawbuf = NULL; | ||
910 | int order, size; | ||
911 | struct page *page, *pend; | ||
912 | |||
913 | /* If we don't have any oss frag params, then use our default ones */ | ||
914 | if (dmabuf->ossmaxfrags == 0) | ||
915 | dmabuf->ossmaxfrags = 4; | ||
916 | if (dmabuf->ossfragsize == 0) | ||
917 | dmabuf->ossfragsize = (PAGE_SIZE << DMABUF_DEFAULTORDER) / dmabuf->ossmaxfrags; | ||
918 | size = dmabuf->ossfragsize * dmabuf->ossmaxfrags; | ||
919 | |||
920 | if (dmabuf->rawbuf && (PAGE_SIZE << dmabuf->buforder) == size) | ||
921 | return 0; | ||
922 | /* alloc enough to satisfy the oss params */ | ||
923 | for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) { | ||
924 | if ((PAGE_SIZE << order) > size) | ||
925 | continue; | ||
926 | if ((rawbuf = pci_alloc_consistent(state->card->pci_dev, | ||
927 | PAGE_SIZE << order, | ||
928 | &dmabuf->dma_handle))) | ||
929 | break; | ||
930 | } | ||
931 | if (!rawbuf) | ||
932 | return -ENOMEM; | ||
933 | |||
934 | dmabuf->ready = dmabuf->mapped = 0; | ||
935 | dmabuf->rawbuf = rawbuf; | ||
936 | dmabuf->buforder = order; | ||
937 | |||
938 | /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ | ||
939 | pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1); | ||
940 | for (page = virt_to_page(rawbuf); page <= pend; page++) | ||
941 | SetPageReserved(page); | ||
942 | return 0; | ||
943 | } | ||
944 | |||
945 | /* free DMA buffer */ | ||
946 | static void dealloc_dmabuf(struct ali_state *state) | ||
947 | { | ||
948 | struct dmabuf *dmabuf = &state->dmabuf; | ||
949 | struct page *page, *pend; | ||
950 | |||
951 | if (dmabuf->rawbuf) { | ||
952 | /* undo marking the pages as reserved */ | ||
953 | pend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1); | ||
954 | for (page = virt_to_page(dmabuf->rawbuf); page <= pend; page++) | ||
955 | ClearPageReserved(page); | ||
956 | pci_free_consistent(state->card->pci_dev, | ||
957 | PAGE_SIZE << dmabuf->buforder, | ||
958 | dmabuf->rawbuf, dmabuf->dma_handle); | ||
959 | } | ||
960 | dmabuf->rawbuf = NULL; | ||
961 | dmabuf->mapped = dmabuf->ready = 0; | ||
962 | } | ||
963 | |||
964 | static int prog_dmabuf(struct ali_state *state, unsigned rec) | ||
965 | { | ||
966 | struct dmabuf *dmabuf = &state->dmabuf; | ||
967 | struct ali_channel *c = NULL; | ||
968 | struct sg_item *sg; | ||
969 | unsigned long flags; | ||
970 | int ret; | ||
971 | unsigned fragint; | ||
972 | int i; | ||
973 | |||
974 | spin_lock_irqsave(&state->card->lock, flags); | ||
975 | if (dmabuf->enable & DAC_RUNNING) | ||
976 | __stop_dac(state); | ||
977 | if (dmabuf->enable & ADC_RUNNING) | ||
978 | __stop_adc(state); | ||
979 | if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) | ||
980 | __stop_spdifout(state); | ||
981 | if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) | ||
982 | __stop_spdifout(state); | ||
983 | |||
984 | dmabuf->total_bytes = 0; | ||
985 | dmabuf->count = dmabuf->error = 0; | ||
986 | dmabuf->swptr = dmabuf->hwptr = 0; | ||
987 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
988 | |||
989 | /* allocate DMA buffer, let alloc_dmabuf determine if we are already | ||
990 | * allocated well enough or if we should replace the current buffer | ||
991 | * (assuming one is already allocated, if it isn't, then allocate it). | ||
992 | */ | ||
993 | if ((ret = alloc_dmabuf(state))) | ||
994 | return ret; | ||
995 | |||
996 | /* FIXME: figure out all this OSS fragment stuff */ | ||
997 | /* I did, it now does what it should according to the OSS API. DL */ | ||
998 | /* We may not have realloced our dmabuf, but the fragment size to | ||
999 | * fragment number ratio may have changed, so go ahead and reprogram | ||
1000 | * things | ||
1001 | */ | ||
1002 | |||
1003 | dmabuf->dmasize = PAGE_SIZE << dmabuf->buforder; | ||
1004 | dmabuf->numfrag = SG_LEN; | ||
1005 | dmabuf->fragsize = dmabuf->dmasize / dmabuf->numfrag; | ||
1006 | dmabuf->fragsamples = dmabuf->fragsize >> 1; | ||
1007 | dmabuf->userfragsize = dmabuf->ossfragsize; | ||
1008 | dmabuf->userfrags = dmabuf->dmasize / dmabuf->ossfragsize; | ||
1009 | |||
1010 | memset(dmabuf->rawbuf, 0, dmabuf->dmasize); | ||
1011 | |||
1012 | if (dmabuf->ossmaxfrags == 4) { | ||
1013 | fragint = 8; | ||
1014 | dmabuf->fragshift = 2; | ||
1015 | } else if (dmabuf->ossmaxfrags == 8) { | ||
1016 | fragint = 4; | ||
1017 | dmabuf->fragshift = 3; | ||
1018 | } else if (dmabuf->ossmaxfrags == 16) { | ||
1019 | fragint = 2; | ||
1020 | dmabuf->fragshift = 4; | ||
1021 | } else { | ||
1022 | fragint = 1; | ||
1023 | dmabuf->fragshift = 5; | ||
1024 | } | ||
1025 | /* | ||
1026 | * Now set up the ring | ||
1027 | */ | ||
1028 | |||
1029 | if (rec == 1) | ||
1030 | c = dmabuf->read_channel; | ||
1031 | else if (rec == 2) | ||
1032 | c = dmabuf->codec_spdifout_channel; | ||
1033 | else if (rec == 3) | ||
1034 | c = dmabuf->controller_spdifout_channel; | ||
1035 | else if (rec == 0) | ||
1036 | c = dmabuf->write_channel; | ||
1037 | if (c != NULL) { | ||
1038 | sg = &c->sg[0]; | ||
1039 | /* | ||
1040 | * Load up 32 sg entries and take an interrupt at half | ||
1041 | * way (we might want more interrupts later..) | ||
1042 | */ | ||
1043 | for (i = 0; i < dmabuf->numfrag; i++) { | ||
1044 | sg->busaddr = | ||
1045 | virt_to_bus(dmabuf->rawbuf + | ||
1046 | dmabuf->fragsize * i); | ||
1047 | // the card will always be doing 16bit stereo | ||
1048 | sg->control = dmabuf->fragsamples; | ||
1049 | sg->control |= CON_BUFPAD; //I modify | ||
1050 | // set us up to get IOC interrupts as often as needed to | ||
1051 | // satisfy numfrag requirements, no more | ||
1052 | if (((i + 1) % fragint) == 0) { | ||
1053 | sg->control |= CON_IOC; | ||
1054 | } | ||
1055 | sg++; | ||
1056 | } | ||
1057 | spin_lock_irqsave(&state->card->lock, flags); | ||
1058 | outb(2, state->card->iobase + c->port + OFF_CR); /* reset DMA machine */ | ||
1059 | outl(virt_to_bus(&c->sg[0]), state->card->iobase + c->port + OFF_BDBAR); | ||
1060 | outb(0, state->card->iobase + c->port + OFF_CIV); | ||
1061 | outb(0, state->card->iobase + c->port + OFF_LVI); | ||
1062 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1063 | } | ||
1064 | /* set the ready flag for the dma buffer */ | ||
1065 | dmabuf->ready = 1; | ||
1066 | return 0; | ||
1067 | } | ||
1068 | |||
1069 | static void __ali_update_lvi(struct ali_state *state, int rec) | ||
1070 | { | ||
1071 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1072 | int x, port; | ||
1073 | port = state->card->iobase; | ||
1074 | if (rec == 1) | ||
1075 | port += dmabuf->read_channel->port; | ||
1076 | else if (rec == 2) | ||
1077 | port += dmabuf->codec_spdifout_channel->port; | ||
1078 | else if (rec == 3) | ||
1079 | port += dmabuf->controller_spdifout_channel->port; | ||
1080 | else if (rec == 0) | ||
1081 | port += dmabuf->write_channel->port; | ||
1082 | /* if we are currently stopped, then our CIV is actually set to our | ||
1083 | * *last* sg segment and we are ready to wrap to the next. However, | ||
1084 | * if we set our LVI to the last sg segment, then it won't wrap to | ||
1085 | * the next sg segment, it won't even get a start. So, instead, when | ||
1086 | * we are stopped, we set both the LVI value and also we increment | ||
1087 | * the CIV value to the next sg segment to be played so that when | ||
1088 | * we call start_{dac,adc}, things will operate properly | ||
1089 | */ | ||
1090 | if (!dmabuf->enable && dmabuf->ready) { | ||
1091 | if (rec && dmabuf->count < dmabuf->dmasize && (dmabuf->trigger & PCM_ENABLE_INPUT)) { | ||
1092 | outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI); | ||
1093 | __start_adc(state); | ||
1094 | while (! (inb(port + OFF_CR) & ((1 << 4) | (1 << 2)))) | ||
1095 | cpu_relax(); | ||
1096 | } else if (!rec && dmabuf->count && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) { | ||
1097 | outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI); | ||
1098 | __start_dac(state); | ||
1099 | while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2)))) | ||
1100 | cpu_relax(); | ||
1101 | } else if (rec && dmabuf->count && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) { | ||
1102 | if (codec_independent_spdif_locked > 0) { | ||
1103 | // outb((inb(port+OFF_CIV))&31, port+OFF_LVI); | ||
1104 | outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI); | ||
1105 | __start_spdifout(state); | ||
1106 | while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2)))) | ||
1107 | cpu_relax(); | ||
1108 | } else { | ||
1109 | if (controller_independent_spdif_locked > 0) { | ||
1110 | outb((inb(port + OFF_CIV) + 1) & 31, port + OFF_LVI); | ||
1111 | __start_spdifout(state); | ||
1112 | while (!(inb(port + OFF_CR) & ((1 << 4) | (1 << 2)))) | ||
1113 | cpu_relax(); | ||
1114 | } | ||
1115 | } | ||
1116 | } | ||
1117 | } | ||
1118 | |||
1119 | /* swptr - 1 is the tail of our transfer */ | ||
1120 | x = (dmabuf->dmasize + dmabuf->swptr - 1) % dmabuf->dmasize; | ||
1121 | x /= dmabuf->fragsize; | ||
1122 | outb(x, port + OFF_LVI); | ||
1123 | } | ||
1124 | |||
1125 | static void ali_update_lvi(struct ali_state *state, int rec) | ||
1126 | { | ||
1127 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1128 | unsigned long flags; | ||
1129 | if (!dmabuf->ready) | ||
1130 | return; | ||
1131 | spin_lock_irqsave(&state->card->lock, flags); | ||
1132 | __ali_update_lvi(state, rec); | ||
1133 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1134 | } | ||
1135 | |||
1136 | /* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */ | ||
1137 | static void ali_update_ptr(struct ali_state *state) | ||
1138 | { | ||
1139 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1140 | unsigned hwptr; | ||
1141 | int diff; | ||
1142 | |||
1143 | /* error handling and process wake up for DAC */ | ||
1144 | if (dmabuf->enable == ADC_RUNNING) { | ||
1145 | /* update hardware pointer */ | ||
1146 | hwptr = ali_get_dma_addr(state, 1); | ||
1147 | diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize; | ||
1148 | dmabuf->hwptr = hwptr; | ||
1149 | dmabuf->total_bytes += diff; | ||
1150 | dmabuf->count += diff; | ||
1151 | if (dmabuf->count > dmabuf->dmasize) { | ||
1152 | /* buffer underrun or buffer overrun */ | ||
1153 | /* this is normal for the end of a read */ | ||
1154 | /* only give an error if we went past the */ | ||
1155 | /* last valid sg entry */ | ||
1156 | if ((inb(state->card->iobase + PI_CIV) & 31) != (inb(state->card->iobase + PI_LVI) & 31)) { | ||
1157 | printk(KERN_WARNING "ali_audio: DMA overrun on read\n"); | ||
1158 | dmabuf->error++; | ||
1159 | } | ||
1160 | } | ||
1161 | if (dmabuf->count > dmabuf->userfragsize) | ||
1162 | wake_up(&dmabuf->wait); | ||
1163 | } | ||
1164 | /* error handling and process wake up for DAC */ | ||
1165 | if (dmabuf->enable == DAC_RUNNING) { | ||
1166 | /* update hardware pointer */ | ||
1167 | hwptr = ali_get_dma_addr(state, 0); | ||
1168 | diff = | ||
1169 | (dmabuf->dmasize + hwptr - | ||
1170 | dmabuf->hwptr) % dmabuf->dmasize; | ||
1171 | #if defined(DEBUG_INTERRUPTS) || defined(DEBUG_MMAP) | ||
1172 | printk("DAC HWP %d,%d,%d\n", hwptr, dmabuf->hwptr, diff); | ||
1173 | #endif | ||
1174 | dmabuf->hwptr = hwptr; | ||
1175 | dmabuf->total_bytes += diff; | ||
1176 | dmabuf->count -= diff; | ||
1177 | if (dmabuf->count < 0) { | ||
1178 | /* buffer underrun or buffer overrun */ | ||
1179 | /* this is normal for the end of a write */ | ||
1180 | /* only give an error if we went past the */ | ||
1181 | /* last valid sg entry */ | ||
1182 | if ((inb(state->card->iobase + PO_CIV) & 31) != (inb(state->card->iobase + PO_LVI) & 31)) { | ||
1183 | printk(KERN_WARNING "ali_audio: DMA overrun on write\n"); | ||
1184 | printk(KERN_DEBUG "ali_audio: CIV %d, LVI %d, hwptr %x, count %d\n", | ||
1185 | inb(state->card->iobase + PO_CIV) & 31, | ||
1186 | inb(state->card->iobase + PO_LVI) & 31, | ||
1187 | dmabuf->hwptr, | ||
1188 | dmabuf->count); | ||
1189 | dmabuf->error++; | ||
1190 | } | ||
1191 | } | ||
1192 | if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize)) | ||
1193 | wake_up(&dmabuf->wait); | ||
1194 | } | ||
1195 | |||
1196 | /* error handling and process wake up for CODEC SPDIF OUT */ | ||
1197 | if (dmabuf->enable == CODEC_SPDIFOUT_RUNNING) { | ||
1198 | /* update hardware pointer */ | ||
1199 | hwptr = ali_get_dma_addr(state, 2); | ||
1200 | diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize; | ||
1201 | dmabuf->hwptr = hwptr; | ||
1202 | dmabuf->total_bytes += diff; | ||
1203 | dmabuf->count -= diff; | ||
1204 | if (dmabuf->count < 0) { | ||
1205 | /* buffer underrun or buffer overrun */ | ||
1206 | /* this is normal for the end of a write */ | ||
1207 | /* only give an error if we went past the */ | ||
1208 | /* last valid sg entry */ | ||
1209 | if ((inb(state->card->iobase + CODECSPDIFOUT_CIV) & 31) != (inb(state->card->iobase + CODECSPDIFOUT_LVI) & 31)) { | ||
1210 | printk(KERN_WARNING "ali_audio: DMA overrun on write\n"); | ||
1211 | printk(KERN_DEBUG "ali_audio: CIV %d, LVI %d, hwptr %x, count %d\n", | ||
1212 | inb(state->card->iobase + CODECSPDIFOUT_CIV) & 31, | ||
1213 | inb(state->card->iobase + CODECSPDIFOUT_LVI) & 31, | ||
1214 | dmabuf->hwptr, dmabuf->count); | ||
1215 | dmabuf->error++; | ||
1216 | } | ||
1217 | } | ||
1218 | if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize)) | ||
1219 | wake_up(&dmabuf->wait); | ||
1220 | } | ||
1221 | /* error handling and process wake up for CONTROLLER SPDIF OUT */ | ||
1222 | if (dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) { | ||
1223 | /* update hardware pointer */ | ||
1224 | hwptr = ali_get_dma_addr(state, 3); | ||
1225 | diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize; | ||
1226 | dmabuf->hwptr = hwptr; | ||
1227 | dmabuf->total_bytes += diff; | ||
1228 | dmabuf->count -= diff; | ||
1229 | if (dmabuf->count < 0) { | ||
1230 | /* buffer underrun or buffer overrun */ | ||
1231 | /* this is normal for the end of a write */ | ||
1232 | /* only give an error if we went past the */ | ||
1233 | /* last valid sg entry */ | ||
1234 | if ((inb(state->card->iobase + CONTROLLERSPDIFOUT_CIV) & 31) != (inb(state->card->iobase + CONTROLLERSPDIFOUT_LVI) & 31)) { | ||
1235 | printk(KERN_WARNING | ||
1236 | "ali_audio: DMA overrun on write\n"); | ||
1237 | printk("ali_audio: CIV %d, LVI %d, hwptr %x, " | ||
1238 | "count %d\n", | ||
1239 | inb(state->card->iobase + CONTROLLERSPDIFOUT_CIV) & 31, | ||
1240 | inb(state->card->iobase + CONTROLLERSPDIFOUT_LVI) & 31, | ||
1241 | dmabuf->hwptr, dmabuf->count); | ||
1242 | dmabuf->error++; | ||
1243 | } | ||
1244 | } | ||
1245 | if (dmabuf->count < (dmabuf->dmasize - dmabuf->userfragsize)) | ||
1246 | wake_up(&dmabuf->wait); | ||
1247 | } | ||
1248 | } | ||
1249 | |||
1250 | static inline int ali_get_free_write_space(struct | ||
1251 | ali_state | ||
1252 | *state) | ||
1253 | { | ||
1254 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1255 | int free; | ||
1256 | |||
1257 | if (dmabuf->count < 0) { | ||
1258 | dmabuf->count = 0; | ||
1259 | dmabuf->swptr = dmabuf->hwptr; | ||
1260 | } | ||
1261 | free = dmabuf->dmasize - dmabuf->swptr; | ||
1262 | if ((dmabuf->count + free) > dmabuf->dmasize){ | ||
1263 | free = dmabuf->dmasize - dmabuf->count; | ||
1264 | } | ||
1265 | return free; | ||
1266 | } | ||
1267 | |||
1268 | static inline int ali_get_available_read_data(struct | ||
1269 | ali_state | ||
1270 | *state) | ||
1271 | { | ||
1272 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1273 | int avail; | ||
1274 | ali_update_ptr(state); | ||
1275 | // catch overruns during record | ||
1276 | if (dmabuf->count > dmabuf->dmasize) { | ||
1277 | dmabuf->count = dmabuf->dmasize; | ||
1278 | dmabuf->swptr = dmabuf->hwptr; | ||
1279 | } | ||
1280 | avail = dmabuf->count; | ||
1281 | avail -= (dmabuf->hwptr % dmabuf->fragsize); | ||
1282 | if (avail < 0) | ||
1283 | return (0); | ||
1284 | return (avail); | ||
1285 | } | ||
1286 | |||
1287 | static int drain_dac(struct ali_state *state, int signals_allowed) | ||
1288 | { | ||
1289 | |||
1290 | DECLARE_WAITQUEUE(wait, current); | ||
1291 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1292 | unsigned long flags; | ||
1293 | unsigned long tmo; | ||
1294 | int count; | ||
1295 | if (!dmabuf->ready) | ||
1296 | return 0; | ||
1297 | if (dmabuf->mapped) { | ||
1298 | stop_dac(state); | ||
1299 | return 0; | ||
1300 | } | ||
1301 | add_wait_queue(&dmabuf->wait, &wait); | ||
1302 | for (;;) { | ||
1303 | |||
1304 | spin_lock_irqsave(&state->card->lock, flags); | ||
1305 | ali_update_ptr(state); | ||
1306 | count = dmabuf->count; | ||
1307 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1308 | if (count <= 0) | ||
1309 | break; | ||
1310 | /* | ||
1311 | * This will make sure that our LVI is correct, that our | ||
1312 | * pointer is updated, and that the DAC is running. We | ||
1313 | * have to force the setting of dmabuf->trigger to avoid | ||
1314 | * any possible deadlocks. | ||
1315 | */ | ||
1316 | if (!dmabuf->enable) { | ||
1317 | dmabuf->trigger = PCM_ENABLE_OUTPUT; | ||
1318 | ali_update_lvi(state, 0); | ||
1319 | } | ||
1320 | if (signal_pending(current) && signals_allowed) { | ||
1321 | break; | ||
1322 | } | ||
1323 | |||
1324 | /* It seems that we have to set the current state to | ||
1325 | * TASK_INTERRUPTIBLE every time to make the process | ||
1326 | * really go to sleep. This also has to be *after* the | ||
1327 | * update_ptr() call because update_ptr is likely to | ||
1328 | * do a wake_up() which will unset this before we ever | ||
1329 | * try to sleep, resuling in a tight loop in this code | ||
1330 | * instead of actually sleeping and waiting for an | ||
1331 | * interrupt to wake us up! | ||
1332 | */ | ||
1333 | set_current_state(TASK_INTERRUPTIBLE); | ||
1334 | /* | ||
1335 | * set the timeout to significantly longer than it *should* | ||
1336 | * take for the DAC to drain the DMA buffer | ||
1337 | */ | ||
1338 | tmo = (count * HZ) / (dmabuf->rate); | ||
1339 | if (!schedule_timeout(tmo >= 2 ? tmo : 2)) { | ||
1340 | printk(KERN_ERR "ali_audio: drain_dac, dma timeout?\n"); | ||
1341 | count = 0; | ||
1342 | break; | ||
1343 | } | ||
1344 | } | ||
1345 | set_current_state(TASK_RUNNING); | ||
1346 | remove_wait_queue(&dmabuf->wait, &wait); | ||
1347 | if (count > 0 && signal_pending(current) && signals_allowed) | ||
1348 | return -ERESTARTSYS; | ||
1349 | stop_dac(state); | ||
1350 | return 0; | ||
1351 | } | ||
1352 | |||
1353 | |||
1354 | static int drain_spdifout(struct ali_state *state, int signals_allowed) | ||
1355 | { | ||
1356 | |||
1357 | DECLARE_WAITQUEUE(wait, current); | ||
1358 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1359 | unsigned long flags; | ||
1360 | unsigned long tmo; | ||
1361 | int count; | ||
1362 | if (!dmabuf->ready) | ||
1363 | return 0; | ||
1364 | if (dmabuf->mapped) { | ||
1365 | stop_spdifout(state); | ||
1366 | return 0; | ||
1367 | } | ||
1368 | add_wait_queue(&dmabuf->wait, &wait); | ||
1369 | for (;;) { | ||
1370 | |||
1371 | spin_lock_irqsave(&state->card->lock, flags); | ||
1372 | ali_update_ptr(state); | ||
1373 | count = dmabuf->count; | ||
1374 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1375 | if (count <= 0) | ||
1376 | break; | ||
1377 | /* | ||
1378 | * This will make sure that our LVI is correct, that our | ||
1379 | * pointer is updated, and that the DAC is running. We | ||
1380 | * have to force the setting of dmabuf->trigger to avoid | ||
1381 | * any possible deadlocks. | ||
1382 | */ | ||
1383 | if (!dmabuf->enable) { | ||
1384 | if (codec_independent_spdif_locked > 0) { | ||
1385 | dmabuf->trigger = SPDIF_ENABLE_OUTPUT; | ||
1386 | ali_update_lvi(state, 2); | ||
1387 | } else { | ||
1388 | if (controller_independent_spdif_locked > 0) { | ||
1389 | dmabuf->trigger = SPDIF_ENABLE_OUTPUT; | ||
1390 | ali_update_lvi(state, 3); | ||
1391 | } | ||
1392 | } | ||
1393 | } | ||
1394 | if (signal_pending(current) && signals_allowed) { | ||
1395 | break; | ||
1396 | } | ||
1397 | |||
1398 | /* It seems that we have to set the current state to | ||
1399 | * TASK_INTERRUPTIBLE every time to make the process | ||
1400 | * really go to sleep. This also has to be *after* the | ||
1401 | * update_ptr() call because update_ptr is likely to | ||
1402 | * do a wake_up() which will unset this before we ever | ||
1403 | * try to sleep, resuling in a tight loop in this code | ||
1404 | * instead of actually sleeping and waiting for an | ||
1405 | * interrupt to wake us up! | ||
1406 | */ | ||
1407 | set_current_state(TASK_INTERRUPTIBLE); | ||
1408 | /* | ||
1409 | * set the timeout to significantly longer than it *should* | ||
1410 | * take for the DAC to drain the DMA buffer | ||
1411 | */ | ||
1412 | tmo = (count * HZ) / (dmabuf->rate); | ||
1413 | if (!schedule_timeout(tmo >= 2 ? tmo : 2)) { | ||
1414 | printk(KERN_ERR "ali_audio: drain_spdifout, dma timeout?\n"); | ||
1415 | count = 0; | ||
1416 | break; | ||
1417 | } | ||
1418 | } | ||
1419 | set_current_state(TASK_RUNNING); | ||
1420 | remove_wait_queue(&dmabuf->wait, &wait); | ||
1421 | if (count > 0 && signal_pending(current) && signals_allowed) | ||
1422 | return -ERESTARTSYS; | ||
1423 | stop_spdifout(state); | ||
1424 | return 0; | ||
1425 | } | ||
1426 | |||
1427 | static void ali_channel_interrupt(struct ali_card *card) | ||
1428 | { | ||
1429 | int i, count; | ||
1430 | |||
1431 | for (i = 0; i < NR_HW_CH; i++) { | ||
1432 | struct ali_state *state = card->states[i]; | ||
1433 | struct ali_channel *c = NULL; | ||
1434 | struct dmabuf *dmabuf; | ||
1435 | unsigned long port = card->iobase; | ||
1436 | u16 status; | ||
1437 | if (!state) | ||
1438 | continue; | ||
1439 | if (!state->dmabuf.ready) | ||
1440 | continue; | ||
1441 | dmabuf = &state->dmabuf; | ||
1442 | if (codec_independent_spdif_locked > 0) { | ||
1443 | if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) { | ||
1444 | c = dmabuf->codec_spdifout_channel; | ||
1445 | } | ||
1446 | } else { | ||
1447 | if (controller_independent_spdif_locked > 0) { | ||
1448 | if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) | ||
1449 | c = dmabuf->controller_spdifout_channel; | ||
1450 | } else { | ||
1451 | if (dmabuf->enable & DAC_RUNNING) { | ||
1452 | c = dmabuf->write_channel; | ||
1453 | } else if (dmabuf->enable & ADC_RUNNING) { | ||
1454 | c = dmabuf->read_channel; | ||
1455 | } else | ||
1456 | continue; | ||
1457 | } | ||
1458 | } | ||
1459 | port += c->port; | ||
1460 | |||
1461 | status = inw(port + OFF_SR); | ||
1462 | |||
1463 | if (status & DMA_INT_COMPLETE) { | ||
1464 | /* only wake_up() waiters if this interrupt signals | ||
1465 | * us being beyond a userfragsize of data open or | ||
1466 | * available, and ali_update_ptr() does that for | ||
1467 | * us | ||
1468 | */ | ||
1469 | ali_update_ptr(state); | ||
1470 | } | ||
1471 | |||
1472 | if (status & DMA_INT_LVI) { | ||
1473 | ali_update_ptr(state); | ||
1474 | wake_up(&dmabuf->wait); | ||
1475 | |||
1476 | if (dmabuf->enable & DAC_RUNNING) | ||
1477 | count = dmabuf->count; | ||
1478 | else if (dmabuf->enable & ADC_RUNNING) | ||
1479 | count = dmabuf->dmasize - dmabuf->count; | ||
1480 | else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) | ||
1481 | count = dmabuf->count; | ||
1482 | else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) | ||
1483 | count = dmabuf->count; | ||
1484 | else count = 0; | ||
1485 | |||
1486 | if (count > 0) { | ||
1487 | if (dmabuf->enable & DAC_RUNNING) | ||
1488 | outl((1 << 1), state->card->iobase + ALI_DMACR); | ||
1489 | else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) | ||
1490 | outl((1 << 3), state->card->iobase + ALI_DMACR); | ||
1491 | else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) | ||
1492 | outl((1 << 7), state->card->iobase + ALI_DMACR); | ||
1493 | } else { | ||
1494 | if (dmabuf->enable & DAC_RUNNING) | ||
1495 | __stop_dac(state); | ||
1496 | if (dmabuf->enable & ADC_RUNNING) | ||
1497 | __stop_adc(state); | ||
1498 | if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) | ||
1499 | __stop_spdifout(state); | ||
1500 | if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) | ||
1501 | __stop_spdifout(state); | ||
1502 | dmabuf->enable = 0; | ||
1503 | wake_up(&dmabuf->wait); | ||
1504 | } | ||
1505 | |||
1506 | } | ||
1507 | if (!(status & DMA_INT_DCH)) { | ||
1508 | ali_update_ptr(state); | ||
1509 | wake_up(&dmabuf->wait); | ||
1510 | if (dmabuf->enable & DAC_RUNNING) | ||
1511 | count = dmabuf->count; | ||
1512 | else if (dmabuf->enable & ADC_RUNNING) | ||
1513 | count = dmabuf->dmasize - dmabuf->count; | ||
1514 | else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) | ||
1515 | count = dmabuf->count; | ||
1516 | else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) | ||
1517 | count = dmabuf->count; | ||
1518 | else | ||
1519 | count = 0; | ||
1520 | |||
1521 | if (count > 0) { | ||
1522 | if (dmabuf->enable & DAC_RUNNING) | ||
1523 | outl((1 << 1), state->card->iobase + ALI_DMACR); | ||
1524 | else if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) | ||
1525 | outl((1 << 3), state->card->iobase + ALI_DMACR); | ||
1526 | else if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) | ||
1527 | outl((1 << 7), state->card->iobase + ALI_DMACR); | ||
1528 | } else { | ||
1529 | if (dmabuf->enable & DAC_RUNNING) | ||
1530 | __stop_dac(state); | ||
1531 | if (dmabuf->enable & ADC_RUNNING) | ||
1532 | __stop_adc(state); | ||
1533 | if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) | ||
1534 | __stop_spdifout(state); | ||
1535 | if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) | ||
1536 | __stop_spdifout(state); | ||
1537 | dmabuf->enable = 0; | ||
1538 | wake_up(&dmabuf->wait); | ||
1539 | } | ||
1540 | } | ||
1541 | outw(status & DMA_INT_MASK, port + OFF_SR); | ||
1542 | } | ||
1543 | } | ||
1544 | |||
1545 | static irqreturn_t ali_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1546 | { | ||
1547 | struct ali_card *card = (struct ali_card *) dev_id; | ||
1548 | u32 status; | ||
1549 | u16 status2; | ||
1550 | |||
1551 | spin_lock(&card->lock); | ||
1552 | status = inl(card->iobase + ALI_INTERRUPTSR); | ||
1553 | if (!(status & INT_MASK)) { | ||
1554 | spin_unlock(&card->lock); | ||
1555 | return IRQ_NONE; /* not for us */ | ||
1556 | } | ||
1557 | |||
1558 | if (codec_independent_spdif_locked > 0) { | ||
1559 | if (globel == 0) { | ||
1560 | globel += 1; | ||
1561 | status2 = inw(card->iobase + 0x76); | ||
1562 | outw(status2 | 0x000c, card->iobase + 0x76); | ||
1563 | } else { | ||
1564 | if (status & (INT_PCMOUT | INT_PCMIN | INT_MICIN | INT_SPDIFOUT | INT_CODECSPDIFOUT)) | ||
1565 | ali_channel_interrupt(card); | ||
1566 | } | ||
1567 | } else { | ||
1568 | if (status & (INT_PCMOUT | INT_PCMIN | INT_MICIN | INT_SPDIFOUT | INT_CODECSPDIFOUT)) | ||
1569 | ali_channel_interrupt(card); | ||
1570 | } | ||
1571 | |||
1572 | /* clear 'em */ | ||
1573 | outl(status & INT_MASK, card->iobase + ALI_INTERRUPTSR); | ||
1574 | spin_unlock(&card->lock); | ||
1575 | return IRQ_HANDLED; | ||
1576 | } | ||
1577 | |||
1578 | /* in this loop, dmabuf.count signifies the amount of data that is | ||
1579 | waiting to be copied to the user's buffer. It is filled by the dma | ||
1580 | machine and drained by this loop. */ | ||
1581 | |||
1582 | static ssize_t ali_read(struct file *file, char __user *buffer, | ||
1583 | size_t count, loff_t * ppos) | ||
1584 | { | ||
1585 | struct ali_state *state = (struct ali_state *) file->private_data; | ||
1586 | struct ali_card *card = state ? state->card : NULL; | ||
1587 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1588 | ssize_t ret; | ||
1589 | unsigned long flags; | ||
1590 | unsigned int swptr; | ||
1591 | int cnt; | ||
1592 | DECLARE_WAITQUEUE(waita, current); | ||
1593 | #ifdef DEBUG2 | ||
1594 | printk("ali_audio: ali_read called, count = %d\n", count); | ||
1595 | #endif | ||
1596 | if (dmabuf->mapped) | ||
1597 | return -ENXIO; | ||
1598 | if (dmabuf->enable & DAC_RUNNING) | ||
1599 | return -ENODEV; | ||
1600 | if (!dmabuf->read_channel) { | ||
1601 | dmabuf->ready = 0; | ||
1602 | dmabuf->read_channel = card->alloc_rec_pcm_channel(card); | ||
1603 | if (!dmabuf->read_channel) { | ||
1604 | return -EBUSY; | ||
1605 | } | ||
1606 | } | ||
1607 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 1))) | ||
1608 | return ret; | ||
1609 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1610 | return -EFAULT; | ||
1611 | ret = 0; | ||
1612 | add_wait_queue(&dmabuf->wait, &waita); | ||
1613 | while (count > 0) { | ||
1614 | set_current_state(TASK_INTERRUPTIBLE); | ||
1615 | spin_lock_irqsave(&card->lock, flags); | ||
1616 | if (PM_SUSPENDED(card)) { | ||
1617 | spin_unlock_irqrestore(&card->lock, flags); | ||
1618 | schedule(); | ||
1619 | if (signal_pending(current)) { | ||
1620 | if (!ret) | ||
1621 | ret = -EAGAIN; | ||
1622 | break; | ||
1623 | } | ||
1624 | continue; | ||
1625 | } | ||
1626 | swptr = dmabuf->swptr; | ||
1627 | cnt = ali_get_available_read_data(state); | ||
1628 | // this is to make the copy_to_user simpler below | ||
1629 | if (cnt > (dmabuf->dmasize - swptr)) | ||
1630 | cnt = dmabuf->dmasize - swptr; | ||
1631 | spin_unlock_irqrestore(&card->lock, flags); | ||
1632 | if (cnt > count) | ||
1633 | cnt = count; | ||
1634 | /* Lop off the last two bits to force the code to always | ||
1635 | * write in full samples. This keeps software that sets | ||
1636 | * O_NONBLOCK but doesn't check the return value of the | ||
1637 | * write call from getting things out of state where they | ||
1638 | * think a full 4 byte sample was written when really only | ||
1639 | * a portion was, resulting in odd sound and stereo | ||
1640 | * hysteresis. | ||
1641 | */ | ||
1642 | cnt &= ~0x3; | ||
1643 | if (cnt <= 0) { | ||
1644 | unsigned long tmo; | ||
1645 | /* | ||
1646 | * Don't let us deadlock. The ADC won't start if | ||
1647 | * dmabuf->trigger isn't set. A call to SETTRIGGER | ||
1648 | * could have turned it off after we set it to on | ||
1649 | * previously. | ||
1650 | */ | ||
1651 | dmabuf->trigger = PCM_ENABLE_INPUT; | ||
1652 | /* | ||
1653 | * This does three things. Updates LVI to be correct, | ||
1654 | * makes sure the ADC is running, and updates the | ||
1655 | * hwptr. | ||
1656 | */ | ||
1657 | ali_update_lvi(state, 1); | ||
1658 | if (file->f_flags & O_NONBLOCK) { | ||
1659 | if (!ret) | ||
1660 | ret = -EAGAIN; | ||
1661 | goto done; | ||
1662 | } | ||
1663 | /* Set the timeout to how long it would take to fill | ||
1664 | * two of our buffers. If we haven't been woke up | ||
1665 | * by then, then we know something is wrong. | ||
1666 | */ | ||
1667 | tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4); | ||
1668 | |||
1669 | /* There are two situations when sleep_on_timeout returns, one is when | ||
1670 | the interrupt is serviced correctly and the process is waked up by | ||
1671 | ISR ON TIME. Another is when timeout is expired, which means that | ||
1672 | either interrupt is NOT serviced correctly (pending interrupt) or it | ||
1673 | is TOO LATE for the process to be scheduled to run (scheduler latency) | ||
1674 | which results in a (potential) buffer overrun. And worse, there is | ||
1675 | NOTHING we can do to prevent it. */ | ||
1676 | if (!schedule_timeout(tmo >= 2 ? tmo : 2)) { | ||
1677 | printk(KERN_ERR | ||
1678 | "ali_audio: recording schedule timeout, " | ||
1679 | "dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
1680 | dmabuf->dmasize, dmabuf->fragsize, | ||
1681 | dmabuf->count, dmabuf->hwptr, | ||
1682 | dmabuf->swptr); | ||
1683 | /* a buffer overrun, we delay the recovery until next time the | ||
1684 | while loop begin and we REALLY have space to record */ | ||
1685 | } | ||
1686 | if (signal_pending(current)) { | ||
1687 | ret = ret ? ret : -ERESTARTSYS; | ||
1688 | goto done; | ||
1689 | } | ||
1690 | continue; | ||
1691 | } | ||
1692 | |||
1693 | if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) { | ||
1694 | if (!ret) | ||
1695 | ret = -EFAULT; | ||
1696 | goto done; | ||
1697 | } | ||
1698 | |||
1699 | swptr = (swptr + cnt) % dmabuf->dmasize; | ||
1700 | spin_lock_irqsave(&card->lock, flags); | ||
1701 | if (PM_SUSPENDED(card)) { | ||
1702 | spin_unlock_irqrestore(&card->lock, flags); | ||
1703 | continue; | ||
1704 | } | ||
1705 | dmabuf->swptr = swptr; | ||
1706 | dmabuf->count -= cnt; | ||
1707 | spin_unlock_irqrestore(&card->lock, flags); | ||
1708 | count -= cnt; | ||
1709 | buffer += cnt; | ||
1710 | ret += cnt; | ||
1711 | } | ||
1712 | done: | ||
1713 | ali_update_lvi(state, 1); | ||
1714 | set_current_state(TASK_RUNNING); | ||
1715 | remove_wait_queue(&dmabuf->wait, &waita); | ||
1716 | return ret; | ||
1717 | } | ||
1718 | |||
1719 | /* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to | ||
1720 | the soundcard. it is drained by the dma machine and filled by this loop. */ | ||
1721 | static ssize_t ali_write(struct file *file, | ||
1722 | const char __user *buffer, size_t count, loff_t * ppos) | ||
1723 | { | ||
1724 | struct ali_state *state = (struct ali_state *) file->private_data; | ||
1725 | struct ali_card *card = state ? state->card : NULL; | ||
1726 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1727 | ssize_t ret; | ||
1728 | unsigned long flags; | ||
1729 | unsigned int swptr = 0; | ||
1730 | int cnt, x; | ||
1731 | DECLARE_WAITQUEUE(waita, current); | ||
1732 | #ifdef DEBUG2 | ||
1733 | printk("ali_audio: ali_write called, count = %d\n", count); | ||
1734 | #endif | ||
1735 | if (dmabuf->mapped) | ||
1736 | return -ENXIO; | ||
1737 | if (dmabuf->enable & ADC_RUNNING) | ||
1738 | return -ENODEV; | ||
1739 | if (codec_independent_spdif_locked > 0) { | ||
1740 | if (!dmabuf->codec_spdifout_channel) { | ||
1741 | dmabuf->ready = 0; | ||
1742 | dmabuf->codec_spdifout_channel = card->alloc_codec_spdifout_channel(card); | ||
1743 | if (!dmabuf->codec_spdifout_channel) | ||
1744 | return -EBUSY; | ||
1745 | } | ||
1746 | } else { | ||
1747 | if (controller_independent_spdif_locked > 0) { | ||
1748 | if (!dmabuf->controller_spdifout_channel) { | ||
1749 | dmabuf->ready = 0; | ||
1750 | dmabuf->controller_spdifout_channel = card->alloc_controller_spdifout_channel(card); | ||
1751 | if (!dmabuf->controller_spdifout_channel) | ||
1752 | return -EBUSY; | ||
1753 | } | ||
1754 | } else { | ||
1755 | if (!dmabuf->write_channel) { | ||
1756 | dmabuf->ready = 0; | ||
1757 | dmabuf->write_channel = | ||
1758 | card->alloc_pcm_channel(card); | ||
1759 | if (!dmabuf->write_channel) | ||
1760 | return -EBUSY; | ||
1761 | } | ||
1762 | } | ||
1763 | } | ||
1764 | |||
1765 | if (codec_independent_spdif_locked > 0) { | ||
1766 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 2))) | ||
1767 | return ret; | ||
1768 | } else { | ||
1769 | if (controller_independent_spdif_locked > 0) { | ||
1770 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 3))) | ||
1771 | return ret; | ||
1772 | } else { | ||
1773 | |||
1774 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 0))) | ||
1775 | return ret; | ||
1776 | } | ||
1777 | } | ||
1778 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1779 | return -EFAULT; | ||
1780 | ret = 0; | ||
1781 | add_wait_queue(&dmabuf->wait, &waita); | ||
1782 | while (count > 0) { | ||
1783 | set_current_state(TASK_INTERRUPTIBLE); | ||
1784 | spin_lock_irqsave(&state->card->lock, flags); | ||
1785 | if (PM_SUSPENDED(card)) { | ||
1786 | spin_unlock_irqrestore(&card->lock, flags); | ||
1787 | schedule(); | ||
1788 | if (signal_pending(current)) { | ||
1789 | if (!ret) | ||
1790 | ret = -EAGAIN; | ||
1791 | break; | ||
1792 | } | ||
1793 | continue; | ||
1794 | } | ||
1795 | |||
1796 | swptr = dmabuf->swptr; | ||
1797 | cnt = ali_get_free_write_space(state); | ||
1798 | /* Bound the maximum size to how much we can copy to the | ||
1799 | * dma buffer before we hit the end. If we have more to | ||
1800 | * copy then it will get done in a second pass of this | ||
1801 | * loop starting from the beginning of the buffer. | ||
1802 | */ | ||
1803 | if (cnt > (dmabuf->dmasize - swptr)) | ||
1804 | cnt = dmabuf->dmasize - swptr; | ||
1805 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1806 | #ifdef DEBUG2 | ||
1807 | printk(KERN_INFO | ||
1808 | "ali_audio: ali_write: %d bytes available space\n", | ||
1809 | cnt); | ||
1810 | #endif | ||
1811 | if (cnt > count) | ||
1812 | cnt = count; | ||
1813 | /* Lop off the last two bits to force the code to always | ||
1814 | * write in full samples. This keeps software that sets | ||
1815 | * O_NONBLOCK but doesn't check the return value of the | ||
1816 | * write call from getting things out of state where they | ||
1817 | * think a full 4 byte sample was written when really only | ||
1818 | * a portion was, resulting in odd sound and stereo | ||
1819 | * hysteresis. | ||
1820 | */ | ||
1821 | cnt &= ~0x3; | ||
1822 | if (cnt <= 0) { | ||
1823 | unsigned long tmo; | ||
1824 | // There is data waiting to be played | ||
1825 | /* | ||
1826 | * Force the trigger setting since we would | ||
1827 | * deadlock with it set any other way | ||
1828 | */ | ||
1829 | if (codec_independent_spdif_locked > 0) { | ||
1830 | dmabuf->trigger = SPDIF_ENABLE_OUTPUT; | ||
1831 | ali_update_lvi(state, 2); | ||
1832 | } else { | ||
1833 | if (controller_independent_spdif_locked > 0) { | ||
1834 | dmabuf->trigger = SPDIF_ENABLE_OUTPUT; | ||
1835 | ali_update_lvi(state, 3); | ||
1836 | } else { | ||
1837 | |||
1838 | dmabuf->trigger = PCM_ENABLE_OUTPUT; | ||
1839 | ali_update_lvi(state, 0); | ||
1840 | } | ||
1841 | } | ||
1842 | if (file->f_flags & O_NONBLOCK) { | ||
1843 | if (!ret) | ||
1844 | ret = -EAGAIN; | ||
1845 | goto ret; | ||
1846 | } | ||
1847 | /* Not strictly correct but works */ | ||
1848 | tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4); | ||
1849 | /* There are two situations when sleep_on_timeout returns, one is when | ||
1850 | the interrupt is serviced correctly and the process is waked up by | ||
1851 | ISR ON TIME. Another is when timeout is expired, which means that | ||
1852 | either interrupt is NOT serviced correctly (pending interrupt) or it | ||
1853 | is TOO LATE for the process to be scheduled to run (scheduler latency) | ||
1854 | which results in a (potential) buffer underrun. And worse, there is | ||
1855 | NOTHING we can do to prevent it. */ | ||
1856 | |||
1857 | /* FIXME - do timeout handling here !! */ | ||
1858 | schedule_timeout(tmo >= 2 ? tmo : 2); | ||
1859 | |||
1860 | if (signal_pending(current)) { | ||
1861 | if (!ret) | ||
1862 | ret = -ERESTARTSYS; | ||
1863 | goto ret; | ||
1864 | } | ||
1865 | continue; | ||
1866 | } | ||
1867 | if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) { | ||
1868 | if (!ret) | ||
1869 | ret = -EFAULT; | ||
1870 | goto ret; | ||
1871 | } | ||
1872 | |||
1873 | swptr = (swptr + cnt) % dmabuf->dmasize; | ||
1874 | spin_lock_irqsave(&state->card->lock, flags); | ||
1875 | if (PM_SUSPENDED(card)) { | ||
1876 | spin_unlock_irqrestore(&card->lock, flags); | ||
1877 | continue; | ||
1878 | } | ||
1879 | |||
1880 | dmabuf->swptr = swptr; | ||
1881 | dmabuf->count += cnt; | ||
1882 | count -= cnt; | ||
1883 | buffer += cnt; | ||
1884 | ret += cnt; | ||
1885 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1886 | } | ||
1887 | if (swptr % dmabuf->fragsize) { | ||
1888 | x = dmabuf->fragsize - (swptr % dmabuf->fragsize); | ||
1889 | memset(dmabuf->rawbuf + swptr, '\0', x); | ||
1890 | } | ||
1891 | ret: | ||
1892 | if (codec_independent_spdif_locked > 0) { | ||
1893 | ali_update_lvi(state, 2); | ||
1894 | } else { | ||
1895 | if (controller_independent_spdif_locked > 0) { | ||
1896 | ali_update_lvi(state, 3); | ||
1897 | } else { | ||
1898 | ali_update_lvi(state, 0); | ||
1899 | } | ||
1900 | } | ||
1901 | set_current_state(TASK_RUNNING); | ||
1902 | remove_wait_queue(&dmabuf->wait, &waita); | ||
1903 | return ret; | ||
1904 | } | ||
1905 | |||
1906 | /* No kernel lock - we have our own spinlock */ | ||
1907 | static unsigned int ali_poll(struct file *file, struct poll_table_struct | ||
1908 | *wait) | ||
1909 | { | ||
1910 | struct ali_state *state = (struct ali_state *) file->private_data; | ||
1911 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1912 | unsigned long flags; | ||
1913 | unsigned int mask = 0; | ||
1914 | if (!dmabuf->ready) | ||
1915 | return 0; | ||
1916 | poll_wait(file, &dmabuf->wait, wait); | ||
1917 | spin_lock_irqsave(&state->card->lock, flags); | ||
1918 | ali_update_ptr(state); | ||
1919 | if (file->f_mode & FMODE_READ && dmabuf->enable & ADC_RUNNING) { | ||
1920 | if (dmabuf->count >= (signed) dmabuf->fragsize) | ||
1921 | mask |= POLLIN | POLLRDNORM; | ||
1922 | } | ||
1923 | if (file->f_mode & FMODE_WRITE && (dmabuf->enable & (DAC_RUNNING|CODEC_SPDIFOUT_RUNNING|CONTROLLER_SPDIFOUT_RUNNING))) { | ||
1924 | if ((signed) dmabuf->dmasize >= dmabuf->count + (signed) dmabuf->fragsize) | ||
1925 | mask |= POLLOUT | POLLWRNORM; | ||
1926 | } | ||
1927 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1928 | return mask; | ||
1929 | } | ||
1930 | |||
1931 | static int ali_mmap(struct file *file, struct vm_area_struct *vma) | ||
1932 | { | ||
1933 | struct ali_state *state = (struct ali_state *) file->private_data; | ||
1934 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1935 | int ret = -EINVAL; | ||
1936 | unsigned long size; | ||
1937 | lock_kernel(); | ||
1938 | if (vma->vm_flags & VM_WRITE) { | ||
1939 | if (!dmabuf->write_channel && (dmabuf->write_channel = state->card->alloc_pcm_channel(state->card)) == NULL) { | ||
1940 | ret = -EBUSY; | ||
1941 | goto out; | ||
1942 | } | ||
1943 | } | ||
1944 | if (vma->vm_flags & VM_READ) { | ||
1945 | if (!dmabuf->read_channel && (dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card)) == NULL) { | ||
1946 | ret = -EBUSY; | ||
1947 | goto out; | ||
1948 | } | ||
1949 | } | ||
1950 | if ((ret = prog_dmabuf(state, 0)) != 0) | ||
1951 | goto out; | ||
1952 | ret = -EINVAL; | ||
1953 | if (vma->vm_pgoff != 0) | ||
1954 | goto out; | ||
1955 | size = vma->vm_end - vma->vm_start; | ||
1956 | if (size > (PAGE_SIZE << dmabuf->buforder)) | ||
1957 | goto out; | ||
1958 | ret = -EAGAIN; | ||
1959 | if (remap_pfn_range(vma, vma->vm_start, | ||
1960 | virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT, | ||
1961 | size, vma->vm_page_prot)) | ||
1962 | goto out; | ||
1963 | dmabuf->mapped = 1; | ||
1964 | dmabuf->trigger = 0; | ||
1965 | ret = 0; | ||
1966 | out: | ||
1967 | unlock_kernel(); | ||
1968 | return ret; | ||
1969 | } | ||
1970 | |||
1971 | static int ali_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1972 | { | ||
1973 | struct ali_state *state = (struct ali_state *) file->private_data; | ||
1974 | struct ali_channel *c = NULL; | ||
1975 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1976 | unsigned long flags; | ||
1977 | audio_buf_info abinfo; | ||
1978 | count_info cinfo; | ||
1979 | unsigned int i_scr; | ||
1980 | int val = 0, ret; | ||
1981 | struct ac97_codec *codec = state->card->ac97_codec[0]; | ||
1982 | void __user *argp = (void __user *)arg; | ||
1983 | int __user *p = argp; | ||
1984 | |||
1985 | #ifdef DEBUG | ||
1986 | printk("ali_audio: ali_ioctl, arg=0x%x, cmd=", | ||
1987 | arg ? *p : 0); | ||
1988 | #endif | ||
1989 | switch (cmd) { | ||
1990 | case OSS_GETVERSION: | ||
1991 | #ifdef DEBUG | ||
1992 | printk("OSS_GETVERSION\n"); | ||
1993 | #endif | ||
1994 | return put_user(SOUND_VERSION, p); | ||
1995 | case SNDCTL_DSP_RESET: | ||
1996 | #ifdef DEBUG | ||
1997 | printk("SNDCTL_DSP_RESET\n"); | ||
1998 | #endif | ||
1999 | spin_lock_irqsave(&state->card->lock, flags); | ||
2000 | if (dmabuf->enable == DAC_RUNNING) { | ||
2001 | c = dmabuf->write_channel; | ||
2002 | __stop_dac(state); | ||
2003 | } | ||
2004 | if (dmabuf->enable == ADC_RUNNING) { | ||
2005 | c = dmabuf->read_channel; | ||
2006 | __stop_adc(state); | ||
2007 | } | ||
2008 | if (dmabuf->enable == CODEC_SPDIFOUT_RUNNING) { | ||
2009 | c = dmabuf->codec_spdifout_channel; | ||
2010 | __stop_spdifout(state); | ||
2011 | } | ||
2012 | if (dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) { | ||
2013 | c = dmabuf->controller_spdifout_channel; | ||
2014 | __stop_spdifout(state); | ||
2015 | } | ||
2016 | if (c != NULL) { | ||
2017 | outb(2, state->card->iobase + c->port + OFF_CR); /* reset DMA machine */ | ||
2018 | outl(virt_to_bus(&c->sg[0]), | ||
2019 | state->card->iobase + c->port + OFF_BDBAR); | ||
2020 | outb(0, state->card->iobase + c->port + OFF_CIV); | ||
2021 | outb(0, state->card->iobase + c->port + OFF_LVI); | ||
2022 | } | ||
2023 | |||
2024 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2025 | synchronize_irq(state->card->pci_dev->irq); | ||
2026 | dmabuf->ready = 0; | ||
2027 | dmabuf->swptr = dmabuf->hwptr = 0; | ||
2028 | dmabuf->count = dmabuf->total_bytes = 0; | ||
2029 | return 0; | ||
2030 | case SNDCTL_DSP_SYNC: | ||
2031 | #ifdef DEBUG | ||
2032 | printk("SNDCTL_DSP_SYNC\n"); | ||
2033 | #endif | ||
2034 | if (codec_independent_spdif_locked > 0) { | ||
2035 | if (dmabuf->enable != CODEC_SPDIFOUT_RUNNING | ||
2036 | || file->f_flags & O_NONBLOCK) | ||
2037 | return 0; | ||
2038 | if ((val = drain_spdifout(state, 1))) | ||
2039 | return val; | ||
2040 | } else { | ||
2041 | if (controller_independent_spdif_locked > 0) { | ||
2042 | if (dmabuf->enable != | ||
2043 | CONTROLLER_SPDIFOUT_RUNNING | ||
2044 | || file->f_flags & O_NONBLOCK) | ||
2045 | return 0; | ||
2046 | if ((val = drain_spdifout(state, 1))) | ||
2047 | return val; | ||
2048 | } else { | ||
2049 | if (dmabuf->enable != DAC_RUNNING | ||
2050 | || file->f_flags & O_NONBLOCK) | ||
2051 | return 0; | ||
2052 | if ((val = drain_dac(state, 1))) | ||
2053 | return val; | ||
2054 | } | ||
2055 | } | ||
2056 | dmabuf->total_bytes = 0; | ||
2057 | return 0; | ||
2058 | case SNDCTL_DSP_SPEED: /* set smaple rate */ | ||
2059 | #ifdef DEBUG | ||
2060 | printk("SNDCTL_DSP_SPEED\n"); | ||
2061 | #endif | ||
2062 | if (get_user(val, p)) | ||
2063 | return -EFAULT; | ||
2064 | if (val >= 0) { | ||
2065 | if (file->f_mode & FMODE_WRITE) { | ||
2066 | if ((state->card->ac97_status & SPDIF_ON)) { /* S/PDIF Enabled */ | ||
2067 | /* RELTEK ALC650 only support 48000, need to check that */ | ||
2068 | if (ali_valid_spdif_rate(codec, val)) { | ||
2069 | if (codec_independent_spdif_locked > 0) { | ||
2070 | ali_set_spdif_output(state, -1, 0); | ||
2071 | stop_spdifout(state); | ||
2072 | dmabuf->ready = 0; | ||
2073 | /* I add test codec independent spdif out */ | ||
2074 | spin_lock_irqsave(&state->card->lock, flags); | ||
2075 | ali_set_codecspdifout_rate(state, val); // I modified | ||
2076 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2077 | /* Set S/PDIF transmitter rate. */ | ||
2078 | i_scr = inl(state->card->iobase + ALI_SCR); | ||
2079 | if ((i_scr & 0x00300000) == 0x00100000) { | ||
2080 | ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked); | ||
2081 | } else { | ||
2082 | if ((i_scr&0x00300000) == 0x00200000) | ||
2083 | { | ||
2084 | ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked); | ||
2085 | } else { | ||
2086 | if ((i_scr & 0x00300000) == 0x00300000) { | ||
2087 | ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked); | ||
2088 | } else { | ||
2089 | ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked); | ||
2090 | } | ||
2091 | } | ||
2092 | } | ||
2093 | |||
2094 | if (!(state->card->ac97_status & SPDIF_ON)) { | ||
2095 | val = dmabuf->rate; | ||
2096 | } | ||
2097 | } else { | ||
2098 | if (controller_independent_spdif_locked > 0) | ||
2099 | { | ||
2100 | stop_spdifout(state); | ||
2101 | dmabuf->ready = 0; | ||
2102 | spin_lock_irqsave(&state->card->lock, flags); | ||
2103 | ali_set_spdifout_rate(state, controller_independent_spdif_locked); | ||
2104 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2105 | } else { | ||
2106 | /* Set DAC rate */ | ||
2107 | ali_set_spdif_output(state, -1, 0); | ||
2108 | stop_dac(state); | ||
2109 | dmabuf->ready = 0; | ||
2110 | spin_lock_irqsave(&state->card->lock, flags); | ||
2111 | ali_set_dac_rate(state, val); | ||
2112 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2113 | /* Set S/PDIF transmitter rate. */ | ||
2114 | ali_set_spdif_output(state, AC97_EA_SPSA_3_4, val); | ||
2115 | if (!(state->card->ac97_status & SPDIF_ON)) | ||
2116 | { | ||
2117 | val = dmabuf->rate; | ||
2118 | } | ||
2119 | } | ||
2120 | } | ||
2121 | } else { /* Not a valid rate for S/PDIF, ignore it */ | ||
2122 | val = dmabuf->rate; | ||
2123 | } | ||
2124 | } else { | ||
2125 | stop_dac(state); | ||
2126 | dmabuf->ready = 0; | ||
2127 | spin_lock_irqsave(&state->card->lock, flags); | ||
2128 | ali_set_dac_rate(state, val); | ||
2129 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2130 | } | ||
2131 | } | ||
2132 | if (file->f_mode & FMODE_READ) { | ||
2133 | stop_adc(state); | ||
2134 | dmabuf->ready = 0; | ||
2135 | spin_lock_irqsave(&state->card->lock, flags); | ||
2136 | ali_set_adc_rate(state, val); | ||
2137 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2138 | } | ||
2139 | } | ||
2140 | return put_user(dmabuf->rate, p); | ||
2141 | case SNDCTL_DSP_STEREO: /* set stereo or mono channel */ | ||
2142 | #ifdef DEBUG | ||
2143 | printk("SNDCTL_DSP_STEREO\n"); | ||
2144 | #endif | ||
2145 | if (dmabuf->enable & DAC_RUNNING) { | ||
2146 | stop_dac(state); | ||
2147 | } | ||
2148 | if (dmabuf->enable & ADC_RUNNING) { | ||
2149 | stop_adc(state); | ||
2150 | } | ||
2151 | if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) { | ||
2152 | stop_spdifout(state); | ||
2153 | } | ||
2154 | if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) { | ||
2155 | stop_spdifout(state); | ||
2156 | } | ||
2157 | return put_user(1, p); | ||
2158 | case SNDCTL_DSP_GETBLKSIZE: | ||
2159 | if (file->f_mode & FMODE_WRITE) { | ||
2160 | if (codec_independent_spdif_locked > 0) { | ||
2161 | if (!dmabuf->ready && (val = prog_dmabuf(state, 2))) | ||
2162 | return val; | ||
2163 | } else { | ||
2164 | if (controller_independent_spdif_locked > 0) { | ||
2165 | if (!dmabuf->ready && (val = prog_dmabuf(state, 3))) | ||
2166 | return val; | ||
2167 | } else { | ||
2168 | if (!dmabuf->ready && (val = prog_dmabuf(state, 0))) | ||
2169 | return val; | ||
2170 | } | ||
2171 | } | ||
2172 | } | ||
2173 | |||
2174 | if (file->f_mode & FMODE_READ) { | ||
2175 | if (!dmabuf->ready && (val = prog_dmabuf(state, 1))) | ||
2176 | return val; | ||
2177 | } | ||
2178 | #ifdef DEBUG | ||
2179 | printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->userfragsize); | ||
2180 | #endif | ||
2181 | return put_user(dmabuf->userfragsize, p); | ||
2182 | case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format */ | ||
2183 | #ifdef DEBUG | ||
2184 | printk("SNDCTL_DSP_GETFMTS\n"); | ||
2185 | #endif | ||
2186 | return put_user(AFMT_S16_LE, p); | ||
2187 | case SNDCTL_DSP_SETFMT: /* Select sample format */ | ||
2188 | #ifdef DEBUG | ||
2189 | printk("SNDCTL_DSP_SETFMT\n"); | ||
2190 | #endif | ||
2191 | return put_user(AFMT_S16_LE, p); | ||
2192 | case SNDCTL_DSP_CHANNELS: // add support 4,6 channel | ||
2193 | #ifdef DEBUG | ||
2194 | printk("SNDCTL_DSP_CHANNELS\n"); | ||
2195 | #endif | ||
2196 | if (get_user(val, p)) | ||
2197 | return -EFAULT; | ||
2198 | if (val > 0) { | ||
2199 | if (dmabuf->enable & DAC_RUNNING) { | ||
2200 | stop_dac(state); | ||
2201 | } | ||
2202 | if (dmabuf->enable & CODEC_SPDIFOUT_RUNNING) { | ||
2203 | stop_spdifout(state); | ||
2204 | } | ||
2205 | if (dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING) { | ||
2206 | stop_spdifout(state); | ||
2207 | } | ||
2208 | if (dmabuf->enable & ADC_RUNNING) { | ||
2209 | stop_adc(state); | ||
2210 | } | ||
2211 | } else { | ||
2212 | return put_user(state->card->channels, p); | ||
2213 | } | ||
2214 | |||
2215 | i_scr = inl(state->card->iobase + ALI_SCR); | ||
2216 | /* Current # of channels enabled */ | ||
2217 | if (i_scr & 0x00000100) | ||
2218 | ret = 4; | ||
2219 | else if (i_scr & 0x00000200) | ||
2220 | ret = 6; | ||
2221 | else | ||
2222 | ret = 2; | ||
2223 | switch (val) { | ||
2224 | case 2: /* 2 channels is always supported */ | ||
2225 | if (codec_independent_spdif_locked > 0) { | ||
2226 | outl(((i_scr & 0xfffffcff) | 0x00100000), (state->card->iobase + ALI_SCR)); | ||
2227 | } else | ||
2228 | outl((i_scr & 0xfffffcff), (state->card->iobase + ALI_SCR)); | ||
2229 | /* Do we need to change mixer settings???? */ | ||
2230 | break; | ||
2231 | case 4: /* Supported on some chipsets, better check first */ | ||
2232 | if (codec_independent_spdif_locked > 0) { | ||
2233 | outl(((i_scr & 0xfffffcff) | 0x00000100 | 0x00200000), (state->card->iobase + ALI_SCR)); | ||
2234 | } else | ||
2235 | outl(((i_scr & 0xfffffcff) | 0x00000100), (state->card->iobase + ALI_SCR)); | ||
2236 | break; | ||
2237 | case 6: /* Supported on some chipsets, better check first */ | ||
2238 | if (codec_independent_spdif_locked > 0) { | ||
2239 | outl(((i_scr & 0xfffffcff) | 0x00000200 | 0x00008000 | 0x00300000), (state->card->iobase + ALI_SCR)); | ||
2240 | } else | ||
2241 | outl(((i_scr & 0xfffffcff) | 0x00000200 | 0x00008000), (state->card->iobase + ALI_SCR)); | ||
2242 | break; | ||
2243 | default: /* nothing else is ever supported by the chipset */ | ||
2244 | val = ret; | ||
2245 | break; | ||
2246 | } | ||
2247 | return put_user(val, p); | ||
2248 | case SNDCTL_DSP_POST: /* the user has sent all data and is notifying us */ | ||
2249 | /* we update the swptr to the end of the last sg segment then return */ | ||
2250 | #ifdef DEBUG | ||
2251 | printk("SNDCTL_DSP_POST\n"); | ||
2252 | #endif | ||
2253 | if (codec_independent_spdif_locked > 0) { | ||
2254 | if (!dmabuf->ready || (dmabuf->enable != CODEC_SPDIFOUT_RUNNING)) | ||
2255 | return 0; | ||
2256 | } else { | ||
2257 | if (controller_independent_spdif_locked > 0) { | ||
2258 | if (!dmabuf->ready || (dmabuf->enable != CONTROLLER_SPDIFOUT_RUNNING)) | ||
2259 | return 0; | ||
2260 | } else { | ||
2261 | if (!dmabuf->ready || (dmabuf->enable != DAC_RUNNING)) | ||
2262 | return 0; | ||
2263 | } | ||
2264 | } | ||
2265 | if ((dmabuf->swptr % dmabuf->fragsize) != 0) { | ||
2266 | val = dmabuf->fragsize - (dmabuf->swptr % dmabuf->fragsize); | ||
2267 | dmabuf->swptr += val; | ||
2268 | dmabuf->count += val; | ||
2269 | } | ||
2270 | return 0; | ||
2271 | case SNDCTL_DSP_SUBDIVIDE: | ||
2272 | if (dmabuf->subdivision) | ||
2273 | return -EINVAL; | ||
2274 | if (get_user(val, p)) | ||
2275 | return -EFAULT; | ||
2276 | if (val != 1 && val != 2 && val != 4) | ||
2277 | return -EINVAL; | ||
2278 | #ifdef DEBUG | ||
2279 | printk("SNDCTL_DSP_SUBDIVIDE %d\n", val); | ||
2280 | #endif | ||
2281 | dmabuf->subdivision = val; | ||
2282 | dmabuf->ready = 0; | ||
2283 | return 0; | ||
2284 | case SNDCTL_DSP_SETFRAGMENT: | ||
2285 | if (get_user(val, p)) | ||
2286 | return -EFAULT; | ||
2287 | dmabuf->ossfragsize = 1 << (val & 0xffff); | ||
2288 | dmabuf->ossmaxfrags = (val >> 16) & 0xffff; | ||
2289 | if (!dmabuf->ossfragsize || !dmabuf->ossmaxfrags) | ||
2290 | return -EINVAL; | ||
2291 | /* | ||
2292 | * Bound the frag size into our allowed range of 256 - 4096 | ||
2293 | */ | ||
2294 | if (dmabuf->ossfragsize < 256) | ||
2295 | dmabuf->ossfragsize = 256; | ||
2296 | else if (dmabuf->ossfragsize > 4096) | ||
2297 | dmabuf->ossfragsize = 4096; | ||
2298 | /* | ||
2299 | * The numfrags could be something reasonable, or it could | ||
2300 | * be 0xffff meaning "Give me as much as possible". So, | ||
2301 | * we check the numfrags * fragsize doesn't exceed our | ||
2302 | * 64k buffer limit, nor is it less than our 8k minimum. | ||
2303 | * If it fails either one of these checks, then adjust the | ||
2304 | * number of fragments, not the size of them. It's OK if | ||
2305 | * our number of fragments doesn't equal 32 or anything | ||
2306 | * like our hardware based number now since we are using | ||
2307 | * a different frag count for the hardware. Before we get | ||
2308 | * into this though, bound the maxfrags to avoid overflow | ||
2309 | * issues. A reasonable bound would be 64k / 256 since our | ||
2310 | * maximum buffer size is 64k and our minimum frag size is | ||
2311 | * 256. On the other end, our minimum buffer size is 8k and | ||
2312 | * our maximum frag size is 4k, so the lower bound should | ||
2313 | * be 2. | ||
2314 | */ | ||
2315 | if (dmabuf->ossmaxfrags > 256) | ||
2316 | dmabuf->ossmaxfrags = 256; | ||
2317 | else if (dmabuf->ossmaxfrags < 2) | ||
2318 | dmabuf->ossmaxfrags = 2; | ||
2319 | val = dmabuf->ossfragsize * dmabuf->ossmaxfrags; | ||
2320 | while (val < 8192) { | ||
2321 | val <<= 1; | ||
2322 | dmabuf->ossmaxfrags <<= 1; | ||
2323 | } | ||
2324 | while (val > 65536) { | ||
2325 | val >>= 1; | ||
2326 | dmabuf->ossmaxfrags >>= 1; | ||
2327 | } | ||
2328 | dmabuf->ready = 0; | ||
2329 | #ifdef DEBUG | ||
2330 | printk("SNDCTL_DSP_SETFRAGMENT 0x%x, %d, %d\n", val, | ||
2331 | dmabuf->ossfragsize, dmabuf->ossmaxfrags); | ||
2332 | #endif | ||
2333 | return 0; | ||
2334 | case SNDCTL_DSP_GETOSPACE: | ||
2335 | if (!(file->f_mode & FMODE_WRITE)) | ||
2336 | return -EINVAL; | ||
2337 | if (codec_independent_spdif_locked > 0) { | ||
2338 | if (!dmabuf->ready && (val = prog_dmabuf(state, 2)) != 0) | ||
2339 | return val; | ||
2340 | } else { | ||
2341 | if (controller_independent_spdif_locked > 0) { | ||
2342 | if (!dmabuf->ready && (val = prog_dmabuf(state, 3)) != 0) | ||
2343 | return val; | ||
2344 | } else { | ||
2345 | if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0) | ||
2346 | return val; | ||
2347 | } | ||
2348 | } | ||
2349 | spin_lock_irqsave(&state->card->lock, flags); | ||
2350 | ali_update_ptr(state); | ||
2351 | abinfo.fragsize = dmabuf->userfragsize; | ||
2352 | abinfo.fragstotal = dmabuf->userfrags; | ||
2353 | if (dmabuf->mapped) | ||
2354 | abinfo.bytes = dmabuf->dmasize; | ||
2355 | else | ||
2356 | abinfo.bytes = ali_get_free_write_space(state); | ||
2357 | abinfo.fragments = abinfo.bytes / dmabuf->userfragsize; | ||
2358 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2359 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2360 | printk("SNDCTL_DSP_GETOSPACE %d, %d, %d, %d\n", | ||
2361 | abinfo.bytes, abinfo.fragsize, abinfo.fragments, | ||
2362 | abinfo.fragstotal); | ||
2363 | #endif | ||
2364 | return copy_to_user(argp, &abinfo, | ||
2365 | sizeof(abinfo)) ? -EFAULT : 0; | ||
2366 | case SNDCTL_DSP_GETOPTR: | ||
2367 | if (!(file->f_mode & FMODE_WRITE)) | ||
2368 | return -EINVAL; | ||
2369 | if (codec_independent_spdif_locked > 0) { | ||
2370 | if (!dmabuf->ready && (val = prog_dmabuf(state, 2)) != 0) | ||
2371 | return val; | ||
2372 | } else { | ||
2373 | if (controller_independent_spdif_locked > 0) { | ||
2374 | if (!dmabuf->ready && (val = prog_dmabuf(state, 3)) != 0) | ||
2375 | return val; | ||
2376 | } else { | ||
2377 | if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0) | ||
2378 | return val; | ||
2379 | } | ||
2380 | } | ||
2381 | spin_lock_irqsave(&state->card->lock, flags); | ||
2382 | val = ali_get_free_write_space(state); | ||
2383 | cinfo.bytes = dmabuf->total_bytes; | ||
2384 | cinfo.ptr = dmabuf->hwptr; | ||
2385 | cinfo.blocks = val / dmabuf->userfragsize; | ||
2386 | if (codec_independent_spdif_locked > 0) { | ||
2387 | if (dmabuf->mapped && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) { | ||
2388 | dmabuf->count += val; | ||
2389 | dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize; | ||
2390 | __ali_update_lvi(state, 2); | ||
2391 | } | ||
2392 | } else { | ||
2393 | if (controller_independent_spdif_locked > 0) { | ||
2394 | if (dmabuf->mapped && (dmabuf->trigger & SPDIF_ENABLE_OUTPUT)) { | ||
2395 | dmabuf->count += val; | ||
2396 | dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize; | ||
2397 | __ali_update_lvi(state, 3); | ||
2398 | } | ||
2399 | } else { | ||
2400 | if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) { | ||
2401 | dmabuf->count += val; | ||
2402 | dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize; | ||
2403 | __ali_update_lvi(state, 0); | ||
2404 | } | ||
2405 | } | ||
2406 | } | ||
2407 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2408 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2409 | printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes, | ||
2410 | cinfo.blocks, cinfo.ptr, dmabuf->count); | ||
2411 | #endif | ||
2412 | return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT : 0; | ||
2413 | case SNDCTL_DSP_GETISPACE: | ||
2414 | if (!(file->f_mode & FMODE_READ)) | ||
2415 | return -EINVAL; | ||
2416 | if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0) | ||
2417 | return val; | ||
2418 | spin_lock_irqsave(&state->card->lock, flags); | ||
2419 | abinfo.bytes = ali_get_available_read_data(state); | ||
2420 | abinfo.fragsize = dmabuf->userfragsize; | ||
2421 | abinfo.fragstotal = dmabuf->userfrags; | ||
2422 | abinfo.fragments = abinfo.bytes / dmabuf->userfragsize; | ||
2423 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2424 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2425 | printk("SNDCTL_DSP_GETISPACE %d, %d, %d, %d\n", | ||
2426 | abinfo.bytes, abinfo.fragsize, abinfo.fragments, | ||
2427 | abinfo.fragstotal); | ||
2428 | #endif | ||
2429 | return copy_to_user(argp, &abinfo, | ||
2430 | sizeof(abinfo)) ? -EFAULT : 0; | ||
2431 | case SNDCTL_DSP_GETIPTR: | ||
2432 | if (!(file->f_mode & FMODE_READ)) | ||
2433 | return -EINVAL; | ||
2434 | if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0) | ||
2435 | return val; | ||
2436 | spin_lock_irqsave(&state->card->lock, flags); | ||
2437 | val = ali_get_available_read_data(state); | ||
2438 | cinfo.bytes = dmabuf->total_bytes; | ||
2439 | cinfo.blocks = val / dmabuf->userfragsize; | ||
2440 | cinfo.ptr = dmabuf->hwptr; | ||
2441 | if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_INPUT)) { | ||
2442 | dmabuf->count -= val; | ||
2443 | dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize; | ||
2444 | __ali_update_lvi(state, 1); | ||
2445 | } | ||
2446 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2447 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2448 | printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes, | ||
2449 | cinfo.blocks, cinfo.ptr, dmabuf->count); | ||
2450 | #endif | ||
2451 | return copy_to_user(argp, &cinfo, sizeof(cinfo))? -EFAULT: 0; | ||
2452 | case SNDCTL_DSP_NONBLOCK: | ||
2453 | #ifdef DEBUG | ||
2454 | printk("SNDCTL_DSP_NONBLOCK\n"); | ||
2455 | #endif | ||
2456 | file->f_flags |= O_NONBLOCK; | ||
2457 | return 0; | ||
2458 | case SNDCTL_DSP_GETCAPS: | ||
2459 | #ifdef DEBUG | ||
2460 | printk("SNDCTL_DSP_GETCAPS\n"); | ||
2461 | #endif | ||
2462 | return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | | ||
2463 | DSP_CAP_MMAP | DSP_CAP_BIND, p); | ||
2464 | case SNDCTL_DSP_GETTRIGGER: | ||
2465 | val = 0; | ||
2466 | #ifdef DEBUG | ||
2467 | printk("SNDCTL_DSP_GETTRIGGER 0x%x\n", dmabuf->trigger); | ||
2468 | #endif | ||
2469 | return put_user(dmabuf->trigger, p); | ||
2470 | case SNDCTL_DSP_SETTRIGGER: | ||
2471 | if (get_user(val, p)) | ||
2472 | return -EFAULT; | ||
2473 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2474 | printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val); | ||
2475 | #endif | ||
2476 | if (!(val & PCM_ENABLE_INPUT) && dmabuf->enable == ADC_RUNNING) { | ||
2477 | stop_adc(state); | ||
2478 | } | ||
2479 | if (!(val & PCM_ENABLE_OUTPUT) && dmabuf->enable == DAC_RUNNING) { | ||
2480 | stop_dac(state); | ||
2481 | } | ||
2482 | if (!(val & SPDIF_ENABLE_OUTPUT) && dmabuf->enable == CODEC_SPDIFOUT_RUNNING) { | ||
2483 | stop_spdifout(state); | ||
2484 | } | ||
2485 | if (!(val & SPDIF_ENABLE_OUTPUT) && dmabuf->enable == CONTROLLER_SPDIFOUT_RUNNING) { | ||
2486 | stop_spdifout(state); | ||
2487 | } | ||
2488 | dmabuf->trigger = val; | ||
2489 | if (val & PCM_ENABLE_OUTPUT && !(dmabuf->enable & DAC_RUNNING)) { | ||
2490 | if (!dmabuf->write_channel) { | ||
2491 | dmabuf->ready = 0; | ||
2492 | dmabuf->write_channel = state->card->alloc_pcm_channel(state->card); | ||
2493 | if (!dmabuf->write_channel) | ||
2494 | return -EBUSY; | ||
2495 | } | ||
2496 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 0))) | ||
2497 | return ret; | ||
2498 | if (dmabuf->mapped) { | ||
2499 | spin_lock_irqsave(&state->card->lock, flags); | ||
2500 | ali_update_ptr(state); | ||
2501 | dmabuf->count = 0; | ||
2502 | dmabuf->swptr = dmabuf->hwptr; | ||
2503 | dmabuf->count = ali_get_free_write_space(state); | ||
2504 | dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize; | ||
2505 | __ali_update_lvi(state, 0); | ||
2506 | spin_unlock_irqrestore(&state->card->lock, | ||
2507 | flags); | ||
2508 | } else | ||
2509 | start_dac(state); | ||
2510 | } | ||
2511 | if (val & SPDIF_ENABLE_OUTPUT && !(dmabuf->enable & CODEC_SPDIFOUT_RUNNING)) { | ||
2512 | if (!dmabuf->codec_spdifout_channel) { | ||
2513 | dmabuf->ready = 0; | ||
2514 | dmabuf->codec_spdifout_channel = state->card->alloc_codec_spdifout_channel(state->card); | ||
2515 | if (!dmabuf->codec_spdifout_channel) | ||
2516 | return -EBUSY; | ||
2517 | } | ||
2518 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 2))) | ||
2519 | return ret; | ||
2520 | if (dmabuf->mapped) { | ||
2521 | spin_lock_irqsave(&state->card->lock, flags); | ||
2522 | ali_update_ptr(state); | ||
2523 | dmabuf->count = 0; | ||
2524 | dmabuf->swptr = dmabuf->hwptr; | ||
2525 | dmabuf->count = ali_get_free_write_space(state); | ||
2526 | dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize; | ||
2527 | __ali_update_lvi(state, 2); | ||
2528 | spin_unlock_irqrestore(&state->card->lock, | ||
2529 | flags); | ||
2530 | } else | ||
2531 | start_spdifout(state); | ||
2532 | } | ||
2533 | if (val & SPDIF_ENABLE_OUTPUT && !(dmabuf->enable & CONTROLLER_SPDIFOUT_RUNNING)) { | ||
2534 | if (!dmabuf->controller_spdifout_channel) { | ||
2535 | dmabuf->ready = 0; | ||
2536 | dmabuf->controller_spdifout_channel = state->card->alloc_controller_spdifout_channel(state->card); | ||
2537 | if (!dmabuf->controller_spdifout_channel) | ||
2538 | return -EBUSY; | ||
2539 | } | ||
2540 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 3))) | ||
2541 | return ret; | ||
2542 | if (dmabuf->mapped) { | ||
2543 | spin_lock_irqsave(&state->card->lock, flags); | ||
2544 | ali_update_ptr(state); | ||
2545 | dmabuf->count = 0; | ||
2546 | dmabuf->swptr = dmabuf->hwptr; | ||
2547 | dmabuf->count = ali_get_free_write_space(state); | ||
2548 | dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize; | ||
2549 | __ali_update_lvi(state, 3); | ||
2550 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2551 | } else | ||
2552 | start_spdifout(state); | ||
2553 | } | ||
2554 | if (val & PCM_ENABLE_INPUT && !(dmabuf->enable & ADC_RUNNING)) { | ||
2555 | if (!dmabuf->read_channel) { | ||
2556 | dmabuf->ready = 0; | ||
2557 | dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card); | ||
2558 | if (!dmabuf->read_channel) | ||
2559 | return -EBUSY; | ||
2560 | } | ||
2561 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 1))) | ||
2562 | return ret; | ||
2563 | if (dmabuf->mapped) { | ||
2564 | spin_lock_irqsave(&state->card->lock, | ||
2565 | flags); | ||
2566 | ali_update_ptr(state); | ||
2567 | dmabuf->swptr = dmabuf->hwptr; | ||
2568 | dmabuf->count = 0; | ||
2569 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2570 | } | ||
2571 | ali_update_lvi(state, 1); | ||
2572 | start_adc(state); | ||
2573 | } | ||
2574 | return 0; | ||
2575 | case SNDCTL_DSP_SETDUPLEX: | ||
2576 | #ifdef DEBUG | ||
2577 | printk("SNDCTL_DSP_SETDUPLEX\n"); | ||
2578 | #endif | ||
2579 | return -EINVAL; | ||
2580 | case SNDCTL_DSP_GETODELAY: | ||
2581 | if (!(file->f_mode & FMODE_WRITE)) | ||
2582 | return -EINVAL; | ||
2583 | spin_lock_irqsave(&state->card->lock, flags); | ||
2584 | ali_update_ptr(state); | ||
2585 | val = dmabuf->count; | ||
2586 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2587 | #ifdef DEBUG | ||
2588 | printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count); | ||
2589 | #endif | ||
2590 | return put_user(val, p); | ||
2591 | case SOUND_PCM_READ_RATE: | ||
2592 | #ifdef DEBUG | ||
2593 | printk("SOUND_PCM_READ_RATE %d\n", dmabuf->rate); | ||
2594 | #endif | ||
2595 | return put_user(dmabuf->rate, p); | ||
2596 | case SOUND_PCM_READ_CHANNELS: | ||
2597 | #ifdef DEBUG | ||
2598 | printk("SOUND_PCM_READ_CHANNELS\n"); | ||
2599 | #endif | ||
2600 | return put_user(2, p); | ||
2601 | case SOUND_PCM_READ_BITS: | ||
2602 | #ifdef DEBUG | ||
2603 | printk("SOUND_PCM_READ_BITS\n"); | ||
2604 | #endif | ||
2605 | return put_user(AFMT_S16_LE, p); | ||
2606 | case SNDCTL_DSP_SETSPDIF: /* Set S/PDIF Control register */ | ||
2607 | #ifdef DEBUG | ||
2608 | printk("SNDCTL_DSP_SETSPDIF\n"); | ||
2609 | #endif | ||
2610 | if (get_user(val, p)) | ||
2611 | return -EFAULT; | ||
2612 | /* Check to make sure the codec supports S/PDIF transmitter */ | ||
2613 | if ((state->card->ac97_features & 4)) { | ||
2614 | /* mask out the transmitter speed bits so the user can't set them */ | ||
2615 | val &= ~0x3000; | ||
2616 | /* Add the current transmitter speed bits to the passed value */ | ||
2617 | ret = ali_ac97_get(codec, AC97_SPDIF_CONTROL); | ||
2618 | val |= (ret & 0x3000); | ||
2619 | ali_ac97_set(codec, AC97_SPDIF_CONTROL, val); | ||
2620 | if (ali_ac97_get(codec, AC97_SPDIF_CONTROL) != val) { | ||
2621 | printk(KERN_ERR "ali_audio: Unable to set S/PDIF configuration to 0x%04x.\n", val); | ||
2622 | return -EFAULT; | ||
2623 | } | ||
2624 | } | ||
2625 | #ifdef DEBUG | ||
2626 | else | ||
2627 | printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n"); | ||
2628 | #endif | ||
2629 | return put_user(val, p); | ||
2630 | case SNDCTL_DSP_GETSPDIF: /* Get S/PDIF Control register */ | ||
2631 | #ifdef DEBUG | ||
2632 | printk("SNDCTL_DSP_GETSPDIF\n"); | ||
2633 | #endif | ||
2634 | if (get_user(val, p)) | ||
2635 | return -EFAULT; | ||
2636 | /* Check to make sure the codec supports S/PDIF transmitter */ | ||
2637 | if (!(state->card->ac97_features & 4)) { | ||
2638 | #ifdef DEBUG | ||
2639 | printk(KERN_WARNING "ali_audio: S/PDIF transmitter not avalible.\n"); | ||
2640 | #endif | ||
2641 | val = 0; | ||
2642 | } else { | ||
2643 | val = ali_ac97_get(codec, AC97_SPDIF_CONTROL); | ||
2644 | } | ||
2645 | |||
2646 | return put_user(val, p); | ||
2647 | //end add support spdif out | ||
2648 | //add support 4,6 channel | ||
2649 | case SNDCTL_DSP_GETCHANNELMASK: | ||
2650 | #ifdef DEBUG | ||
2651 | printk("SNDCTL_DSP_GETCHANNELMASK\n"); | ||
2652 | #endif | ||
2653 | if (get_user(val, p)) | ||
2654 | return -EFAULT; | ||
2655 | /* Based on AC'97 DAC support, not ICH hardware */ | ||
2656 | val = DSP_BIND_FRONT; | ||
2657 | if (state->card->ac97_features & 0x0004) | ||
2658 | val |= DSP_BIND_SPDIF; | ||
2659 | if (state->card->ac97_features & 0x0080) | ||
2660 | val |= DSP_BIND_SURR; | ||
2661 | if (state->card->ac97_features & 0x0140) | ||
2662 | val |= DSP_BIND_CENTER_LFE; | ||
2663 | return put_user(val, p); | ||
2664 | case SNDCTL_DSP_BIND_CHANNEL: | ||
2665 | #ifdef DEBUG | ||
2666 | printk("SNDCTL_DSP_BIND_CHANNEL\n"); | ||
2667 | #endif | ||
2668 | if (get_user(val, p)) | ||
2669 | return -EFAULT; | ||
2670 | if (val == DSP_BIND_QUERY) { | ||
2671 | val = DSP_BIND_FRONT; /* Always report this as being enabled */ | ||
2672 | if (state->card->ac97_status & SPDIF_ON) | ||
2673 | val |= DSP_BIND_SPDIF; | ||
2674 | else { | ||
2675 | if (state->card->ac97_status & SURR_ON) | ||
2676 | val |= DSP_BIND_SURR; | ||
2677 | if (state->card-> | ||
2678 | ac97_status & CENTER_LFE_ON) | ||
2679 | val |= DSP_BIND_CENTER_LFE; | ||
2680 | } | ||
2681 | } else { /* Not a query, set it */ | ||
2682 | if (!(file->f_mode & FMODE_WRITE)) | ||
2683 | return -EINVAL; | ||
2684 | if (dmabuf->enable == DAC_RUNNING) { | ||
2685 | stop_dac(state); | ||
2686 | } | ||
2687 | if (val & DSP_BIND_SPDIF) { /* Turn on SPDIF */ | ||
2688 | /* Ok, this should probably define what slots | ||
2689 | * to use. For now, we'll only set it to the | ||
2690 | * defaults: | ||
2691 | * | ||
2692 | * non multichannel codec maps to slots 3&4 | ||
2693 | * 2 channel codec maps to slots 7&8 | ||
2694 | * 4 channel codec maps to slots 6&9 | ||
2695 | * 6 channel codec maps to slots 10&11 | ||
2696 | * | ||
2697 | * there should be some way for the app to | ||
2698 | * select the slot assignment. | ||
2699 | */ | ||
2700 | i_scr = inl(state->card->iobase + ALI_SCR); | ||
2701 | if (codec_independent_spdif_locked > 0) { | ||
2702 | |||
2703 | if ((i_scr & 0x00300000) == 0x00100000) { | ||
2704 | ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked); | ||
2705 | } else { | ||
2706 | if ((i_scr & 0x00300000) == 0x00200000) { | ||
2707 | ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked); | ||
2708 | } else { | ||
2709 | if ((i_scr & 0x00300000) == 0x00300000) { | ||
2710 | ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked); | ||
2711 | } | ||
2712 | } | ||
2713 | } | ||
2714 | } else { /* codec spdif out (pcm out share ) */ | ||
2715 | ali_set_spdif_output(state, AC97_EA_SPSA_3_4, dmabuf->rate); //I do not modify | ||
2716 | } | ||
2717 | |||
2718 | if (!(state->card->ac97_status & SPDIF_ON)) | ||
2719 | val &= ~DSP_BIND_SPDIF; | ||
2720 | } else { | ||
2721 | int mask; | ||
2722 | int channels; | ||
2723 | /* Turn off S/PDIF if it was on */ | ||
2724 | if (state->card->ac97_status & SPDIF_ON) | ||
2725 | ali_set_spdif_output(state, -1, 0); | ||
2726 | mask = | ||
2727 | val & (DSP_BIND_FRONT | DSP_BIND_SURR | | ||
2728 | DSP_BIND_CENTER_LFE); | ||
2729 | switch (mask) { | ||
2730 | case DSP_BIND_FRONT: | ||
2731 | channels = 2; | ||
2732 | break; | ||
2733 | case DSP_BIND_FRONT | DSP_BIND_SURR: | ||
2734 | channels = 4; | ||
2735 | break; | ||
2736 | case DSP_BIND_FRONT | DSP_BIND_SURR | DSP_BIND_CENTER_LFE: | ||
2737 | channels = 6; | ||
2738 | break; | ||
2739 | default: | ||
2740 | val = DSP_BIND_FRONT; | ||
2741 | channels = 2; | ||
2742 | break; | ||
2743 | } | ||
2744 | ali_set_dac_channels(state, channels); | ||
2745 | /* check that they really got turned on */ | ||
2746 | if (!state->card->ac97_status & SURR_ON) | ||
2747 | val &= ~DSP_BIND_SURR; | ||
2748 | if (!state->card-> | ||
2749 | ac97_status & CENTER_LFE_ON) | ||
2750 | val &= ~DSP_BIND_CENTER_LFE; | ||
2751 | } | ||
2752 | } | ||
2753 | return put_user(val, p); | ||
2754 | case SNDCTL_DSP_MAPINBUF: | ||
2755 | case SNDCTL_DSP_MAPOUTBUF: | ||
2756 | case SNDCTL_DSP_SETSYNCRO: | ||
2757 | case SOUND_PCM_WRITE_FILTER: | ||
2758 | case SOUND_PCM_READ_FILTER: | ||
2759 | return -EINVAL; | ||
2760 | } | ||
2761 | return -EINVAL; | ||
2762 | } | ||
2763 | |||
2764 | static int ali_open(struct inode *inode, struct file *file) | ||
2765 | { | ||
2766 | int i = 0; | ||
2767 | struct ali_card *card = devs; | ||
2768 | struct ali_state *state = NULL; | ||
2769 | struct dmabuf *dmabuf = NULL; | ||
2770 | unsigned int i_scr; | ||
2771 | |||
2772 | /* find an available virtual channel (instance of /dev/dsp) */ | ||
2773 | |||
2774 | while (card != NULL) { | ||
2775 | |||
2776 | /* | ||
2777 | * If we are initializing and then fail, card could go | ||
2778 | * away unuexpectedly while we are in the for() loop. | ||
2779 | * So, check for card on each iteration before we check | ||
2780 | * for card->initializing to avoid a possible oops. | ||
2781 | * This usually only matters for times when the driver is | ||
2782 | * autoloaded by kmod. | ||
2783 | */ | ||
2784 | for (i = 0; i < 50 && card && card->initializing; i++) { | ||
2785 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2786 | schedule_timeout(HZ / 20); | ||
2787 | } | ||
2788 | |||
2789 | for (i = 0; i < NR_HW_CH && card && !card->initializing; i++) { | ||
2790 | if (card->states[i] == NULL) { | ||
2791 | state = card->states[i] = (struct ali_state *) kmalloc(sizeof(struct ali_state), GFP_KERNEL); | ||
2792 | if (state == NULL) | ||
2793 | return -ENOMEM; | ||
2794 | memset(state, 0, sizeof(struct ali_state)); | ||
2795 | dmabuf = &state->dmabuf; | ||
2796 | goto found_virt; | ||
2797 | } | ||
2798 | } | ||
2799 | card = card->next; | ||
2800 | } | ||
2801 | |||
2802 | /* no more virtual channel avaiable */ | ||
2803 | if (!state) | ||
2804 | return -ENODEV; | ||
2805 | found_virt: | ||
2806 | /* initialize the virtual channel */ | ||
2807 | |||
2808 | state->virt = i; | ||
2809 | state->card = card; | ||
2810 | state->magic = ALI5455_STATE_MAGIC; | ||
2811 | init_waitqueue_head(&dmabuf->wait); | ||
2812 | mutex_init(&state->open_mutex); | ||
2813 | file->private_data = state; | ||
2814 | dmabuf->trigger = 0; | ||
2815 | /* allocate hardware channels */ | ||
2816 | if (file->f_mode & FMODE_READ) { | ||
2817 | if ((dmabuf->read_channel = | ||
2818 | card->alloc_rec_pcm_channel(card)) == NULL) { | ||
2819 | kfree(card->states[i]); | ||
2820 | card->states[i] = NULL; | ||
2821 | return -EBUSY; | ||
2822 | } | ||
2823 | dmabuf->trigger |= PCM_ENABLE_INPUT; | ||
2824 | ali_set_adc_rate(state, 8000); | ||
2825 | } | ||
2826 | if (file->f_mode & FMODE_WRITE) { | ||
2827 | if (codec_independent_spdif_locked > 0) { | ||
2828 | if ((dmabuf->codec_spdifout_channel = card->alloc_codec_spdifout_channel(card)) == NULL) { | ||
2829 | kfree(card->states[i]); | ||
2830 | card->states[i] = NULL; | ||
2831 | return -EBUSY; | ||
2832 | } | ||
2833 | dmabuf->trigger |= SPDIF_ENABLE_OUTPUT; | ||
2834 | ali_set_codecspdifout_rate(state, codec_independent_spdif_locked); //It must add | ||
2835 | i_scr = inl(state->card->iobase + ALI_SCR); | ||
2836 | if ((i_scr & 0x00300000) == 0x00100000) { | ||
2837 | ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked); | ||
2838 | } else { | ||
2839 | if ((i_scr & 0x00300000) == 0x00200000) { | ||
2840 | ali_set_spdif_output(state, AC97_EA_SPSA_6_9, codec_independent_spdif_locked); | ||
2841 | } else { | ||
2842 | if ((i_scr & 0x00300000) == 0x00300000) { | ||
2843 | ali_set_spdif_output(state, AC97_EA_SPSA_10_11, codec_independent_spdif_locked); | ||
2844 | } else { | ||
2845 | ali_set_spdif_output(state, AC97_EA_SPSA_7_8, codec_independent_spdif_locked); | ||
2846 | } | ||
2847 | } | ||
2848 | |||
2849 | } | ||
2850 | } else { | ||
2851 | if (controller_independent_spdif_locked > 0) { | ||
2852 | if ((dmabuf->controller_spdifout_channel = card->alloc_controller_spdifout_channel(card)) == NULL) { | ||
2853 | kfree(card->states[i]); | ||
2854 | card->states[i] = NULL; | ||
2855 | return -EBUSY; | ||
2856 | } | ||
2857 | dmabuf->trigger |= SPDIF_ENABLE_OUTPUT; | ||
2858 | ali_set_spdifout_rate(state, controller_independent_spdif_locked); | ||
2859 | } else { | ||
2860 | if ((dmabuf->write_channel = card->alloc_pcm_channel(card)) == NULL) { | ||
2861 | kfree(card->states[i]); | ||
2862 | card->states[i] = NULL; | ||
2863 | return -EBUSY; | ||
2864 | } | ||
2865 | /* Initialize to 8kHz? What if we don't support 8kHz? */ | ||
2866 | /* Let's change this to check for S/PDIF stuff */ | ||
2867 | |||
2868 | dmabuf->trigger |= PCM_ENABLE_OUTPUT; | ||
2869 | if (codec_pcmout_share_spdif_locked) { | ||
2870 | ali_set_dac_rate(state, codec_pcmout_share_spdif_locked); | ||
2871 | ali_set_spdif_output(state, AC97_EA_SPSA_3_4, codec_pcmout_share_spdif_locked); | ||
2872 | } else { | ||
2873 | ali_set_dac_rate(state, 8000); | ||
2874 | } | ||
2875 | } | ||
2876 | |||
2877 | } | ||
2878 | } | ||
2879 | |||
2880 | /* set default sample format. According to OSS Programmer's Guide /dev/dsp | ||
2881 | should be default to unsigned 8-bits, mono, with sample rate 8kHz and | ||
2882 | /dev/dspW will accept 16-bits sample, but we don't support those so we | ||
2883 | set it immediately to stereo and 16bit, which is all we do support */ | ||
2884 | dmabuf->fmt |= ALI5455_FMT_16BIT | ALI5455_FMT_STEREO; | ||
2885 | dmabuf->ossfragsize = 0; | ||
2886 | dmabuf->ossmaxfrags = 0; | ||
2887 | dmabuf->subdivision = 0; | ||
2888 | state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
2889 | outl(0x00000000, card->iobase + ALI_INTERRUPTCR); | ||
2890 | outl(0x00000000, card->iobase + ALI_INTERRUPTSR); | ||
2891 | return nonseekable_open(inode, file); | ||
2892 | } | ||
2893 | |||
2894 | static int ali_release(struct inode *inode, struct file *file) | ||
2895 | { | ||
2896 | struct ali_state *state = (struct ali_state *) file->private_data; | ||
2897 | struct ali_card *card = state->card; | ||
2898 | struct dmabuf *dmabuf = &state->dmabuf; | ||
2899 | unsigned long flags; | ||
2900 | lock_kernel(); | ||
2901 | |||
2902 | /* stop DMA state machine and free DMA buffers/channels */ | ||
2903 | if (dmabuf->trigger & PCM_ENABLE_OUTPUT) | ||
2904 | drain_dac(state, 0); | ||
2905 | |||
2906 | if (dmabuf->trigger & SPDIF_ENABLE_OUTPUT) | ||
2907 | drain_spdifout(state, 0); | ||
2908 | |||
2909 | if (dmabuf->trigger & PCM_ENABLE_INPUT) | ||
2910 | stop_adc(state); | ||
2911 | |||
2912 | spin_lock_irqsave(&card->lock, flags); | ||
2913 | dealloc_dmabuf(state); | ||
2914 | if (file->f_mode & FMODE_WRITE) { | ||
2915 | if (codec_independent_spdif_locked > 0) { | ||
2916 | state->card->free_pcm_channel(state->card, dmabuf->codec_spdifout_channel->num); | ||
2917 | } else { | ||
2918 | if (controller_independent_spdif_locked > 0) | ||
2919 | state->card->free_pcm_channel(state->card, | ||
2920 | dmabuf->controller_spdifout_channel->num); | ||
2921 | else state->card->free_pcm_channel(state->card, | ||
2922 | dmabuf->write_channel->num); | ||
2923 | } | ||
2924 | } | ||
2925 | if (file->f_mode & FMODE_READ) | ||
2926 | state->card->free_pcm_channel(state->card, dmabuf->read_channel->num); | ||
2927 | |||
2928 | state->card->states[state->virt] = NULL; | ||
2929 | kfree(state); | ||
2930 | spin_unlock_irqrestore(&card->lock, flags); | ||
2931 | unlock_kernel(); | ||
2932 | return 0; | ||
2933 | } | ||
2934 | |||
2935 | static /*const */ struct file_operations ali_audio_fops = { | ||
2936 | .owner = THIS_MODULE, | ||
2937 | .llseek = no_llseek, | ||
2938 | .read = ali_read, | ||
2939 | .write = ali_write, | ||
2940 | .poll = ali_poll, | ||
2941 | .ioctl = ali_ioctl, | ||
2942 | .mmap = ali_mmap, | ||
2943 | .open = ali_open, | ||
2944 | .release = ali_release, | ||
2945 | }; | ||
2946 | |||
2947 | /* Read AC97 codec registers */ | ||
2948 | static u16 ali_ac97_get(struct ac97_codec *dev, u8 reg) | ||
2949 | { | ||
2950 | struct ali_card *card = dev->private_data; | ||
2951 | int count1 = 100; | ||
2952 | char val; | ||
2953 | unsigned short int data = 0, count, addr1, addr2 = 0; | ||
2954 | |||
2955 | spin_lock(&card->ac97_lock); | ||
2956 | while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000)) | ||
2957 | udelay(1); | ||
2958 | |||
2959 | addr1 = reg; | ||
2960 | reg |= 0x0080; | ||
2961 | for (count = 0; count < 0x7f; count++) { | ||
2962 | val = inb(card->iobase + ALI_CSPSR); | ||
2963 | if (val & 0x08) | ||
2964 | break; | ||
2965 | } | ||
2966 | if (count == 0x7f) | ||
2967 | { | ||
2968 | spin_unlock(&card->ac97_lock); | ||
2969 | return -1; | ||
2970 | } | ||
2971 | outw(reg, (card->iobase + ALI_CPR) + 2); | ||
2972 | for (count = 0; count < 0x7f; count++) { | ||
2973 | val = inb(card->iobase + ALI_CSPSR); | ||
2974 | if (val & 0x02) { | ||
2975 | data = inw(card->iobase + ALI_SPR); | ||
2976 | addr2 = inw((card->iobase + ALI_SPR) + 2); | ||
2977 | break; | ||
2978 | } | ||
2979 | } | ||
2980 | spin_unlock(&card->ac97_lock); | ||
2981 | if (count == 0x7f) | ||
2982 | return -1; | ||
2983 | if (addr2 != addr1) | ||
2984 | return -1; | ||
2985 | return ((u16) data); | ||
2986 | } | ||
2987 | |||
2988 | /* write ac97 codec register */ | ||
2989 | |||
2990 | static void ali_ac97_set(struct ac97_codec *dev, u8 reg, u16 data) | ||
2991 | { | ||
2992 | struct ali_card *card = dev->private_data; | ||
2993 | int count1 = 100; | ||
2994 | char val; | ||
2995 | unsigned short int count; | ||
2996 | |||
2997 | spin_lock(&card->ac97_lock); | ||
2998 | while (count1-- && (inl(card->iobase + ALI_CAS) & 0x80000000)) | ||
2999 | udelay(1); | ||
3000 | |||
3001 | for (count = 0; count < 0x7f; count++) { | ||
3002 | val = inb(card->iobase + ALI_CSPSR); | ||
3003 | if (val & 0x08) | ||
3004 | break; | ||
3005 | } | ||
3006 | if (count == 0x7f) { | ||
3007 | printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n"); | ||
3008 | spin_unlock(&card->ac97_lock); | ||
3009 | return; | ||
3010 | } | ||
3011 | outw(data, (card->iobase + ALI_CPR)); | ||
3012 | outb(reg, (card->iobase + ALI_CPR) + 2); | ||
3013 | for (count = 0; count < 0x7f; count++) { | ||
3014 | val = inb(card->iobase + ALI_CSPSR); | ||
3015 | if (val & 0x01) | ||
3016 | break; | ||
3017 | } | ||
3018 | spin_unlock(&card->ac97_lock); | ||
3019 | if (count == 0x7f) | ||
3020 | printk(KERN_WARNING "ali_ac97_set: AC97 codec register access timed out. \n"); | ||
3021 | return; | ||
3022 | } | ||
3023 | |||
3024 | /* OSS /dev/mixer file operation methods */ | ||
3025 | |||
3026 | static int ali_open_mixdev(struct inode *inode, struct file *file) | ||
3027 | { | ||
3028 | int i; | ||
3029 | int minor = iminor(inode); | ||
3030 | struct ali_card *card = devs; | ||
3031 | for (card = devs; card != NULL; card = card->next) { | ||
3032 | /* | ||
3033 | * If we are initializing and then fail, card could go | ||
3034 | * away unuexpectedly while we are in the for() loop. | ||
3035 | * So, check for card on each iteration before we check | ||
3036 | * for card->initializing to avoid a possible oops. | ||
3037 | * This usually only matters for times when the driver is | ||
3038 | * autoloaded by kmod. | ||
3039 | */ | ||
3040 | for (i = 0; i < 50 && card && card->initializing; i++) { | ||
3041 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
3042 | schedule_timeout(HZ / 20); | ||
3043 | } | ||
3044 | for (i = 0; i < NR_AC97 && card && !card->initializing; i++) | ||
3045 | if (card->ac97_codec[i] != NULL | ||
3046 | && card->ac97_codec[i]->dev_mixer == minor) { | ||
3047 | file->private_data = card->ac97_codec[i]; | ||
3048 | return nonseekable_open(inode, file); | ||
3049 | } | ||
3050 | } | ||
3051 | return -ENODEV; | ||
3052 | } | ||
3053 | |||
3054 | static int ali_ioctl_mixdev(struct inode *inode, | ||
3055 | struct file *file, | ||
3056 | unsigned int cmd, unsigned long arg) | ||
3057 | { | ||
3058 | struct ac97_codec *codec = (struct ac97_codec *) file->private_data; | ||
3059 | return codec->mixer_ioctl(codec, cmd, arg); | ||
3060 | } | ||
3061 | |||
3062 | static /*const */ struct file_operations ali_mixer_fops = { | ||
3063 | .owner = THIS_MODULE, | ||
3064 | .llseek = no_llseek, | ||
3065 | .ioctl = ali_ioctl_mixdev, | ||
3066 | .open = ali_open_mixdev, | ||
3067 | }; | ||
3068 | |||
3069 | /* AC97 codec initialisation. These small functions exist so we don't | ||
3070 | duplicate code between module init and apm resume */ | ||
3071 | |||
3072 | static inline int ali_ac97_exists(struct ali_card *card, int ac97_number) | ||
3073 | { | ||
3074 | unsigned int i = 1; | ||
3075 | u32 reg = inl(card->iobase + ALI_RTSR); | ||
3076 | if (ac97_number) { | ||
3077 | while (i < 100) { | ||
3078 | |||
3079 | reg = inl(card->iobase + ALI_RTSR); | ||
3080 | if (reg & 0x40) { | ||
3081 | break; | ||
3082 | } else { | ||
3083 | outl(reg | 0x00000040, | ||
3084 | card->iobase + 0x34); | ||
3085 | udelay(1); | ||
3086 | } | ||
3087 | i++; | ||
3088 | } | ||
3089 | |||
3090 | } else { | ||
3091 | while (i < 100) { | ||
3092 | reg = inl(card->iobase + ALI_RTSR); | ||
3093 | if (reg & 0x80) { | ||
3094 | break; | ||
3095 | } else { | ||
3096 | outl(reg | 0x00000080, | ||
3097 | card->iobase + 0x34); | ||
3098 | udelay(1); | ||
3099 | } | ||
3100 | i++; | ||
3101 | } | ||
3102 | } | ||
3103 | |||
3104 | if (ac97_number) | ||
3105 | return reg & 0x40; | ||
3106 | else | ||
3107 | return reg & 0x80; | ||
3108 | } | ||
3109 | |||
3110 | static inline int ali_ac97_enable_variable_rate(struct ac97_codec *codec) | ||
3111 | { | ||
3112 | ali_ac97_set(codec, AC97_EXTENDED_STATUS, 9); | ||
3113 | ali_ac97_set(codec, AC97_EXTENDED_STATUS, ali_ac97_get(codec, AC97_EXTENDED_STATUS) | 0xE800); | ||
3114 | return (ali_ac97_get(codec, AC97_EXTENDED_STATUS) & 1); | ||
3115 | } | ||
3116 | |||
3117 | |||
3118 | static int ali_ac97_probe_and_powerup(struct ali_card *card, struct ac97_codec *codec) | ||
3119 | { | ||
3120 | /* Returns 0 on failure */ | ||
3121 | int i; | ||
3122 | u16 addr; | ||
3123 | if (ac97_probe_codec(codec) == 0) | ||
3124 | return 0; | ||
3125 | /* ac97_probe_codec is success ,then begin to init codec */ | ||
3126 | ali_ac97_set(codec, AC97_RESET, 0xffff); | ||
3127 | if (card->channel[0].used == 1) { | ||
3128 | ali_ac97_set(codec, AC97_RECORD_SELECT, 0x0000); | ||
3129 | ali_ac97_set(codec, AC97_LINEIN_VOL, 0x0808); | ||
3130 | ali_ac97_set(codec, AC97_RECORD_GAIN, 0x0F0F); | ||
3131 | } | ||
3132 | |||
3133 | if (card->channel[2].used == 1) //if MICin then init codec | ||
3134 | { | ||
3135 | ali_ac97_set(codec, AC97_RECORD_SELECT, 0x0000); | ||
3136 | ali_ac97_set(codec, AC97_MIC_VOL, 0x8808); | ||
3137 | ali_ac97_set(codec, AC97_RECORD_GAIN, 0x0F0F); | ||
3138 | ali_ac97_set(codec, AC97_RECORD_GAIN_MIC, 0x0000); | ||
3139 | } | ||
3140 | |||
3141 | ali_ac97_set(codec, AC97_MASTER_VOL_STEREO, 0x0000); | ||
3142 | ali_ac97_set(codec, AC97_HEADPHONE_VOL, 0x0000); | ||
3143 | ali_ac97_set(codec, AC97_PCMOUT_VOL, 0x0000); | ||
3144 | ali_ac97_set(codec, AC97_CD_VOL, 0x0808); | ||
3145 | ali_ac97_set(codec, AC97_VIDEO_VOL, 0x0808); | ||
3146 | ali_ac97_set(codec, AC97_AUX_VOL, 0x0808); | ||
3147 | ali_ac97_set(codec, AC97_PHONE_VOL, 0x8048); | ||
3148 | ali_ac97_set(codec, AC97_PCBEEP_VOL, 0x0000); | ||
3149 | ali_ac97_set(codec, AC97_GENERAL_PURPOSE, AC97_GP_MIX); | ||
3150 | ali_ac97_set(codec, AC97_MASTER_VOL_MONO, 0x0000); | ||
3151 | ali_ac97_set(codec, 0x38, 0x0000); | ||
3152 | addr = ali_ac97_get(codec, 0x2a); | ||
3153 | ali_ac97_set(codec, 0x2a, addr | 0x0001); | ||
3154 | addr = ali_ac97_get(codec, 0x2a); | ||
3155 | addr = ali_ac97_get(codec, 0x28); | ||
3156 | ali_ac97_set(codec, 0x2c, 0xbb80); | ||
3157 | addr = ali_ac97_get(codec, 0x2c); | ||
3158 | /* power it all up */ | ||
3159 | ali_ac97_set(codec, AC97_POWER_CONTROL, | ||
3160 | ali_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00); | ||
3161 | /* wait for analog ready */ | ||
3162 | for (i = 10; i && ((ali_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--) { | ||
3163 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
3164 | schedule_timeout(HZ / 20); | ||
3165 | } | ||
3166 | /* FIXME !! */ | ||
3167 | i++; | ||
3168 | return i; | ||
3169 | } | ||
3170 | |||
3171 | |||
3172 | /* I clone ali5455(2.4.7 ) not clone i810_audio(2.4.18) */ | ||
3173 | |||
3174 | static int ali_reset_5455(struct ali_card *card) | ||
3175 | { | ||
3176 | outl(0x80000003, card->iobase + ALI_SCR); | ||
3177 | outl(0x83838383, card->iobase + ALI_FIFOCR1); | ||
3178 | outl(0x83838383, card->iobase + ALI_FIFOCR2); | ||
3179 | if (controller_pcmout_share_spdif_locked > 0) { | ||
3180 | outl((inl(card->iobase + ALI_SPDIFICS) | 0x00000001), | ||
3181 | card->iobase + ALI_SPDIFICS); | ||
3182 | outl(0x0408000a, card->iobase + ALI_INTERFACECR); | ||
3183 | } else { | ||
3184 | if (codec_independent_spdif_locked > 0) { | ||
3185 | outl((inl(card->iobase + ALI_SCR) | 0x00100000), card->iobase + ALI_SCR); // now I select slot 7 & 8 | ||
3186 | outl(0x00200000, card->iobase + ALI_INTERFACECR); //enable codec independent spdifout | ||
3187 | } else | ||
3188 | outl(0x04080002, card->iobase + ALI_INTERFACECR); | ||
3189 | } | ||
3190 | |||
3191 | outl(0x00000000, card->iobase + ALI_INTERRUPTCR); | ||
3192 | outl(0x00000000, card->iobase + ALI_INTERRUPTSR); | ||
3193 | if (controller_independent_spdif_locked > 0) | ||
3194 | outl((inl(card->iobase + ALI_SPDIFICS) | 0x00000001), | ||
3195 | card->iobase + ALI_SPDIFICS); | ||
3196 | return 1; | ||
3197 | } | ||
3198 | |||
3199 | |||
3200 | static int ali_ac97_random_init_stuff(struct ali_card | ||
3201 | *card) | ||
3202 | { | ||
3203 | u32 reg = inl(card->iobase + ALI_SCR); | ||
3204 | int i = 0; | ||
3205 | reg = inl(card->iobase + ALI_SCR); | ||
3206 | if ((reg & 2) == 0) /* Cold required */ | ||
3207 | reg |= 2; | ||
3208 | else | ||
3209 | reg |= 1; /* Warm */ | ||
3210 | reg &= ~0x80000000; /* ACLink on */ | ||
3211 | outl(reg, card->iobase + ALI_SCR); | ||
3212 | |||
3213 | while (i < 10) { | ||
3214 | if ((inl(card->iobase + 0x18) & (1 << 1)) == 0) | ||
3215 | break; | ||
3216 | current->state = TASK_UNINTERRUPTIBLE; | ||
3217 | schedule_timeout(HZ / 20); | ||
3218 | i++; | ||
3219 | } | ||
3220 | if (i == 10) { | ||
3221 | printk(KERN_ERR "ali_audio: AC'97 reset failed.\n"); | ||
3222 | return 0; | ||
3223 | } | ||
3224 | |||
3225 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
3226 | schedule_timeout(HZ / 2); | ||
3227 | return 1; | ||
3228 | } | ||
3229 | |||
3230 | /* AC97 codec initialisation. */ | ||
3231 | |||
3232 | static int __devinit ali_ac97_init(struct ali_card *card) | ||
3233 | { | ||
3234 | int num_ac97 = 0; | ||
3235 | int total_channels = 0; | ||
3236 | struct ac97_codec *codec; | ||
3237 | u16 eid; | ||
3238 | |||
3239 | if (!ali_ac97_random_init_stuff(card)) | ||
3240 | return 0; | ||
3241 | |||
3242 | /* Number of channels supported */ | ||
3243 | /* What about the codec? Just because the ICH supports */ | ||
3244 | /* multiple channels doesn't mean the codec does. */ | ||
3245 | /* we'll have to modify this in the codec section below */ | ||
3246 | /* to reflect what the codec has. */ | ||
3247 | /* ICH and ICH0 only support 2 channels so don't bother */ | ||
3248 | /* to check.... */ | ||
3249 | inl(card->iobase + ALI_CPR); | ||
3250 | card->channels = 2; | ||
3251 | |||
3252 | for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) { | ||
3253 | |||
3254 | /* Assume codec isn't available until we go through the | ||
3255 | * gauntlet below */ | ||
3256 | card->ac97_codec[num_ac97] = NULL; | ||
3257 | /* The ICH programmer's reference says you should */ | ||
3258 | /* check the ready status before probing. So we chk */ | ||
3259 | /* What do we do if it's not ready? Wait and try */ | ||
3260 | /* again, or abort? */ | ||
3261 | if (!ali_ac97_exists(card, num_ac97)) { | ||
3262 | if (num_ac97 == 0) | ||
3263 | printk(KERN_ERR "ali_audio: Primary codec not ready.\n"); | ||
3264 | break; | ||
3265 | } | ||
3266 | |||
3267 | if ((codec = ac97_alloc_codec()) == NULL) | ||
3268 | return -ENOMEM; | ||
3269 | /* initialize some basic codec information, other fields will be filled | ||
3270 | in ac97_probe_codec */ | ||
3271 | codec->private_data = card; | ||
3272 | codec->id = num_ac97; | ||
3273 | codec->codec_read = ali_ac97_get; | ||
3274 | codec->codec_write = ali_ac97_set; | ||
3275 | if (!ali_ac97_probe_and_powerup(card, codec)) { | ||
3276 | printk(KERN_ERR "ali_audio: timed out waiting for codec %d analog ready", | ||
3277 | num_ac97); | ||
3278 | kfree(codec); | ||
3279 | break; /* it didn't work */ | ||
3280 | } | ||
3281 | |||
3282 | /* Store state information about S/PDIF transmitter */ | ||
3283 | card->ac97_status = 0; | ||
3284 | /* Don't attempt to get eid until powerup is complete */ | ||
3285 | eid = ali_ac97_get(codec, AC97_EXTENDED_ID); | ||
3286 | if (eid == 0xFFFF) { | ||
3287 | printk(KERN_ERR "ali_audio: no codec attached ?\n"); | ||
3288 | kfree(codec); | ||
3289 | break; | ||
3290 | } | ||
3291 | |||
3292 | card->ac97_features = eid; | ||
3293 | /* Now check the codec for useful features to make up for | ||
3294 | the dumbness of the ali5455 hardware engine */ | ||
3295 | if (!(eid & 0x0001)) | ||
3296 | printk(KERN_WARNING | ||
3297 | "ali_audio: only 48Khz playback available.\n"); | ||
3298 | else { | ||
3299 | if (!ali_ac97_enable_variable_rate(codec)) { | ||
3300 | printk(KERN_WARNING | ||
3301 | "ali_audio: Codec refused to allow VRA, using 48Khz only.\n"); | ||
3302 | card->ac97_features &= ~1; | ||
3303 | } | ||
3304 | } | ||
3305 | |||
3306 | /* Determine how many channels the codec(s) support */ | ||
3307 | /* - The primary codec always supports 2 */ | ||
3308 | /* - If the codec supports AMAP, surround DACs will */ | ||
3309 | /* automaticlly get assigned to slots. */ | ||
3310 | /* * Check for surround DACs and increment if */ | ||
3311 | /* found. */ | ||
3312 | /* - Else check if the codec is revision 2.2 */ | ||
3313 | /* * If surround DACs exist, assign them to slots */ | ||
3314 | /* and increment channel count. */ | ||
3315 | |||
3316 | /* All of this only applies to ICH2 and above. ICH */ | ||
3317 | /* and ICH0 only support 2 channels. ICH2 will only */ | ||
3318 | /* support multiple codecs in a "split audio" config. */ | ||
3319 | /* as described above. */ | ||
3320 | |||
3321 | /* TODO: Remove all the debugging messages! */ | ||
3322 | |||
3323 | if ((eid & 0xc000) == 0) /* primary codec */ | ||
3324 | total_channels += 2; | ||
3325 | if ((codec->dev_mixer = register_sound_mixer(&ali_mixer_fops, -1)) < 0) { | ||
3326 | printk(KERN_ERR "ali_audio: couldn't register mixer!\n"); | ||
3327 | kfree(codec); | ||
3328 | break; | ||
3329 | } | ||
3330 | card->ac97_codec[num_ac97] = codec; | ||
3331 | } | ||
3332 | /* pick the minimum of channels supported by ICHx or codec(s) */ | ||
3333 | card->channels = (card->channels > total_channels) ? total_channels : card->channels; | ||
3334 | return num_ac97; | ||
3335 | } | ||
3336 | |||
3337 | static void __devinit ali_configure_clocking(void) | ||
3338 | { | ||
3339 | struct ali_card *card; | ||
3340 | struct ali_state *state; | ||
3341 | struct dmabuf *dmabuf; | ||
3342 | unsigned int i, offset, new_offset; | ||
3343 | unsigned long flags; | ||
3344 | card = devs; | ||
3345 | |||
3346 | /* We could try to set the clocking for multiple cards, but can you even have | ||
3347 | * more than one ali in a machine? Besides, clocking is global, so unless | ||
3348 | * someone actually thinks more than one ali in a machine is possible and | ||
3349 | * decides to rewrite that little bit, setting the rate for more than one card | ||
3350 | * is a waste of time. | ||
3351 | */ | ||
3352 | if (card != NULL) { | ||
3353 | state = card->states[0] = (struct ali_state *) | ||
3354 | kmalloc(sizeof(struct ali_state), GFP_KERNEL); | ||
3355 | if (state == NULL) | ||
3356 | return; | ||
3357 | memset(state, 0, sizeof(struct ali_state)); | ||
3358 | dmabuf = &state->dmabuf; | ||
3359 | dmabuf->write_channel = card->alloc_pcm_channel(card); | ||
3360 | state->virt = 0; | ||
3361 | state->card = card; | ||
3362 | state->magic = ALI5455_STATE_MAGIC; | ||
3363 | init_waitqueue_head(&dmabuf->wait); | ||
3364 | mutex_init(&state->open_mutex); | ||
3365 | dmabuf->fmt = ALI5455_FMT_STEREO | ALI5455_FMT_16BIT; | ||
3366 | dmabuf->trigger = PCM_ENABLE_OUTPUT; | ||
3367 | ali_set_dac_rate(state, 48000); | ||
3368 | if (prog_dmabuf(state, 0) != 0) | ||
3369 | goto config_out_nodmabuf; | ||
3370 | |||
3371 | if (dmabuf->dmasize < 16384) | ||
3372 | goto config_out; | ||
3373 | |||
3374 | dmabuf->count = dmabuf->dmasize; | ||
3375 | outb(31, card->iobase + dmabuf->write_channel->port + OFF_LVI); | ||
3376 | |||
3377 | local_irq_save(flags); | ||
3378 | start_dac(state); | ||
3379 | offset = ali_get_dma_addr(state, 0); | ||
3380 | mdelay(50); | ||
3381 | new_offset = ali_get_dma_addr(state, 0); | ||
3382 | stop_dac(state); | ||
3383 | |||
3384 | outb(2, card->iobase + dmabuf->write_channel->port + OFF_CR); | ||
3385 | local_irq_restore(flags); | ||
3386 | |||
3387 | i = new_offset - offset; | ||
3388 | |||
3389 | if (i == 0) | ||
3390 | goto config_out; | ||
3391 | i = i / 4 * 20; | ||
3392 | if (i > 48500 || i < 47500) { | ||
3393 | clocking = clocking * clocking / i; | ||
3394 | } | ||
3395 | config_out: | ||
3396 | dealloc_dmabuf(state); | ||
3397 | config_out_nodmabuf: | ||
3398 | state->card->free_pcm_channel(state->card, state->dmabuf. write_channel->num); | ||
3399 | kfree(state); | ||
3400 | card->states[0] = NULL; | ||
3401 | } | ||
3402 | } | ||
3403 | |||
3404 | /* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered | ||
3405 | until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */ | ||
3406 | |||
3407 | static int __devinit ali_probe(struct pci_dev *pci_dev, | ||
3408 | const struct pci_device_id *pci_id) | ||
3409 | { | ||
3410 | struct ali_card *card; | ||
3411 | if (pci_enable_device(pci_dev)) | ||
3412 | return -EIO; | ||
3413 | if (pci_set_dma_mask(pci_dev, ALI5455_DMA_MASK)) { | ||
3414 | printk(KERN_ERR "ali5455: architecture does not support" | ||
3415 | " 32bit PCI busmaster DMA\n"); | ||
3416 | return -ENODEV; | ||
3417 | } | ||
3418 | |||
3419 | if ((card = kmalloc(sizeof(struct ali_card), GFP_KERNEL)) == NULL) { | ||
3420 | printk(KERN_ERR "ali_audio: out of memory\n"); | ||
3421 | return -ENOMEM; | ||
3422 | } | ||
3423 | memset(card, 0, sizeof(*card)); | ||
3424 | card->initializing = 1; | ||
3425 | card->iobase = pci_resource_start(pci_dev, 0); | ||
3426 | card->pci_dev = pci_dev; | ||
3427 | card->pci_id = pci_id->device; | ||
3428 | card->irq = pci_dev->irq; | ||
3429 | card->next = devs; | ||
3430 | card->magic = ALI5455_CARD_MAGIC; | ||
3431 | #ifdef CONFIG_PM | ||
3432 | card->pm_suspended = 0; | ||
3433 | #endif | ||
3434 | spin_lock_init(&card->lock); | ||
3435 | spin_lock_init(&card->ac97_lock); | ||
3436 | devs = card; | ||
3437 | pci_set_master(pci_dev); | ||
3438 | printk(KERN_INFO "ali: %s found at IO 0x%04lx, IRQ %d\n", | ||
3439 | card_names[pci_id->driver_data], card->iobase, card->irq); | ||
3440 | card->alloc_pcm_channel = ali_alloc_pcm_channel; | ||
3441 | card->alloc_rec_pcm_channel = ali_alloc_rec_pcm_channel; | ||
3442 | card->alloc_rec_mic_channel = ali_alloc_rec_mic_channel; | ||
3443 | card->alloc_codec_spdifout_channel = ali_alloc_codec_spdifout_channel; | ||
3444 | card->alloc_controller_spdifout_channel = ali_alloc_controller_spdifout_channel; | ||
3445 | card->free_pcm_channel = ali_free_pcm_channel; | ||
3446 | card->channel[0].offset = 0; | ||
3447 | card->channel[0].port = 0x40; | ||
3448 | card->channel[0].num = 0; | ||
3449 | card->channel[1].offset = 0; | ||
3450 | card->channel[1].port = 0x50; | ||
3451 | card->channel[1].num = 1; | ||
3452 | card->channel[2].offset = 0; | ||
3453 | card->channel[2].port = 0x60; | ||
3454 | card->channel[2].num = 2; | ||
3455 | card->channel[3].offset = 0; | ||
3456 | card->channel[3].port = 0x70; | ||
3457 | card->channel[3].num = 3; | ||
3458 | card->channel[4].offset = 0; | ||
3459 | card->channel[4].port = 0xb0; | ||
3460 | card->channel[4].num = 4; | ||
3461 | /* claim our iospace and irq */ | ||
3462 | request_region(card->iobase, 256, card_names[pci_id->driver_data]); | ||
3463 | if (request_irq(card->irq, &ali_interrupt, IRQF_SHARED, | ||
3464 | card_names[pci_id->driver_data], card)) { | ||
3465 | printk(KERN_ERR "ali_audio: unable to allocate irq %d\n", | ||
3466 | card->irq); | ||
3467 | release_region(card->iobase, 256); | ||
3468 | kfree(card); | ||
3469 | return -ENODEV; | ||
3470 | } | ||
3471 | |||
3472 | if (ali_reset_5455(card) <= 0) { | ||
3473 | unregister_sound_dsp(card->dev_audio); | ||
3474 | release_region(card->iobase, 256); | ||
3475 | free_irq(card->irq, card); | ||
3476 | kfree(card); | ||
3477 | return -ENODEV; | ||
3478 | } | ||
3479 | |||
3480 | /* initialize AC97 codec and register /dev/mixer */ | ||
3481 | if (ali_ac97_init(card) < 0) { | ||
3482 | release_region(card->iobase, 256); | ||
3483 | free_irq(card->irq, card); | ||
3484 | kfree(card); | ||
3485 | return -ENODEV; | ||
3486 | } | ||
3487 | |||
3488 | pci_set_drvdata(pci_dev, card); | ||
3489 | |||
3490 | if (clocking == 0) { | ||
3491 | clocking = 48000; | ||
3492 | ali_configure_clocking(); | ||
3493 | } | ||
3494 | |||
3495 | /* register /dev/dsp */ | ||
3496 | if ((card->dev_audio = register_sound_dsp(&ali_audio_fops, -1)) < 0) { | ||
3497 | int i; | ||
3498 | printk(KERN_ERR"ali_audio: couldn't register DSP device!\n"); | ||
3499 | release_region(card->iobase, 256); | ||
3500 | free_irq(card->irq, card); | ||
3501 | for (i = 0; i < NR_AC97; i++) | ||
3502 | if (card->ac97_codec[i] != NULL) { | ||
3503 | unregister_sound_mixer(card->ac97_codec[i]->dev_mixer); | ||
3504 | kfree(card->ac97_codec[i]); | ||
3505 | } | ||
3506 | kfree(card); | ||
3507 | return -ENODEV; | ||
3508 | } | ||
3509 | card->initializing = 0; | ||
3510 | return 0; | ||
3511 | } | ||
3512 | |||
3513 | static void __devexit ali_remove(struct pci_dev *pci_dev) | ||
3514 | { | ||
3515 | int i; | ||
3516 | struct ali_card *card = pci_get_drvdata(pci_dev); | ||
3517 | /* free hardware resources */ | ||
3518 | free_irq(card->irq, devs); | ||
3519 | release_region(card->iobase, 256); | ||
3520 | /* unregister audio devices */ | ||
3521 | for (i = 0; i < NR_AC97; i++) | ||
3522 | if (card->ac97_codec[i] != NULL) { | ||
3523 | unregister_sound_mixer(card->ac97_codec[i]-> | ||
3524 | dev_mixer); | ||
3525 | ac97_release_codec(card->ac97_codec[i]); | ||
3526 | card->ac97_codec[i] = NULL; | ||
3527 | } | ||
3528 | unregister_sound_dsp(card->dev_audio); | ||
3529 | kfree(card); | ||
3530 | } | ||
3531 | |||
3532 | #ifdef CONFIG_PM | ||
3533 | static int ali_pm_suspend(struct pci_dev *dev, pm_message_t pm_state) | ||
3534 | { | ||
3535 | struct ali_card *card = pci_get_drvdata(dev); | ||
3536 | struct ali_state *state; | ||
3537 | unsigned long flags; | ||
3538 | struct dmabuf *dmabuf; | ||
3539 | int i, num_ac97; | ||
3540 | |||
3541 | if (!card) | ||
3542 | return 0; | ||
3543 | spin_lock_irqsave(&card->lock, flags); | ||
3544 | card->pm_suspended = 1; | ||
3545 | for (i = 0; i < NR_HW_CH; i++) { | ||
3546 | state = card->states[i]; | ||
3547 | if (!state) | ||
3548 | continue; | ||
3549 | /* this happens only if there are open files */ | ||
3550 | dmabuf = &state->dmabuf; | ||
3551 | if (dmabuf->enable & DAC_RUNNING || | ||
3552 | (dmabuf->count | ||
3553 | && (dmabuf->trigger & PCM_ENABLE_OUTPUT))) { | ||
3554 | state->pm_saved_dac_rate = dmabuf->rate; | ||
3555 | stop_dac(state); | ||
3556 | } else { | ||
3557 | state->pm_saved_dac_rate = 0; | ||
3558 | } | ||
3559 | if (dmabuf->enable & ADC_RUNNING) { | ||
3560 | state->pm_saved_adc_rate = dmabuf->rate; | ||
3561 | stop_adc(state); | ||
3562 | } else { | ||
3563 | state->pm_saved_adc_rate = 0; | ||
3564 | } | ||
3565 | dmabuf->ready = 0; | ||
3566 | dmabuf->swptr = dmabuf->hwptr = 0; | ||
3567 | dmabuf->count = dmabuf->total_bytes = 0; | ||
3568 | } | ||
3569 | |||
3570 | spin_unlock_irqrestore(&card->lock, flags); | ||
3571 | /* save mixer settings */ | ||
3572 | for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) { | ||
3573 | struct ac97_codec *codec = card->ac97_codec[num_ac97]; | ||
3574 | if (!codec) | ||
3575 | continue; | ||
3576 | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||
3577 | if ((supported_mixer(codec, i)) && (codec->read_mixer)) { | ||
3578 | card->pm_saved_mixer_settings[i][num_ac97] = codec->read_mixer(codec, i); | ||
3579 | } | ||
3580 | } | ||
3581 | } | ||
3582 | pci_save_state(dev); /* XXX do we need this? */ | ||
3583 | pci_disable_device(dev); /* disable busmastering */ | ||
3584 | pci_set_power_state(dev, 3); /* Zzz. */ | ||
3585 | return 0; | ||
3586 | } | ||
3587 | |||
3588 | |||
3589 | static int ali_pm_resume(struct pci_dev *dev) | ||
3590 | { | ||
3591 | int num_ac97, i = 0; | ||
3592 | struct ali_card *card = pci_get_drvdata(dev); | ||
3593 | pci_enable_device(dev); | ||
3594 | pci_restore_state(dev); | ||
3595 | /* observation of a toshiba portege 3440ct suggests that the | ||
3596 | hardware has to be more or less completely reinitialized from | ||
3597 | scratch after an apm suspend. Works For Me. -dan */ | ||
3598 | ali_ac97_random_init_stuff(card); | ||
3599 | for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) { | ||
3600 | struct ac97_codec *codec = card->ac97_codec[num_ac97]; | ||
3601 | /* check they haven't stolen the hardware while we were | ||
3602 | away */ | ||
3603 | if (!codec || !ali_ac97_exists(card, num_ac97)) { | ||
3604 | if (num_ac97) | ||
3605 | continue; | ||
3606 | else | ||
3607 | BUG(); | ||
3608 | } | ||
3609 | if (!ali_ac97_probe_and_powerup(card, codec)) | ||
3610 | BUG(); | ||
3611 | if ((card->ac97_features & 0x0001)) { | ||
3612 | /* at probe time we found we could do variable | ||
3613 | rates, but APM suspend has made it forget | ||
3614 | its magical powers */ | ||
3615 | if (!ali_ac97_enable_variable_rate(codec)) | ||
3616 | BUG(); | ||
3617 | } | ||
3618 | /* we lost our mixer settings, so restore them */ | ||
3619 | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||
3620 | if (supported_mixer(codec, i)) { | ||
3621 | int val = card->pm_saved_mixer_settings[i][num_ac97]; | ||
3622 | codec->mixer_state[i] = val; | ||
3623 | codec->write_mixer(codec, i, | ||
3624 | (val & 0xff), | ||
3625 | ((val >> 8) & 0xff)); | ||
3626 | } | ||
3627 | } | ||
3628 | } | ||
3629 | |||
3630 | /* we need to restore the sample rate from whatever it was */ | ||
3631 | for (i = 0; i < NR_HW_CH; i++) { | ||
3632 | struct ali_state *state = card->states[i]; | ||
3633 | if (state) { | ||
3634 | if (state->pm_saved_adc_rate) | ||
3635 | ali_set_adc_rate(state, state->pm_saved_adc_rate); | ||
3636 | if (state->pm_saved_dac_rate) | ||
3637 | ali_set_dac_rate(state, state->pm_saved_dac_rate); | ||
3638 | } | ||
3639 | } | ||
3640 | |||
3641 | card->pm_suspended = 0; | ||
3642 | /* any processes that were reading/writing during the suspend | ||
3643 | probably ended up here */ | ||
3644 | for (i = 0; i < NR_HW_CH; i++) { | ||
3645 | struct ali_state *state = card->states[i]; | ||
3646 | if (state) | ||
3647 | wake_up(&state->dmabuf.wait); | ||
3648 | } | ||
3649 | return 0; | ||
3650 | } | ||
3651 | #endif /* CONFIG_PM */ | ||
3652 | |||
3653 | MODULE_AUTHOR(""); | ||
3654 | MODULE_DESCRIPTION("ALI 5455 audio support"); | ||
3655 | MODULE_LICENSE("GPL"); | ||
3656 | module_param(clocking, int, 0); | ||
3657 | /* FIXME: bool? */ | ||
3658 | module_param(strict_clocking, uint, 0); | ||
3659 | module_param(codec_pcmout_share_spdif_locked, uint, 0); | ||
3660 | module_param(codec_independent_spdif_locked, uint, 0); | ||
3661 | module_param(controller_pcmout_share_spdif_locked, uint, 0); | ||
3662 | module_param(controller_independent_spdif_locked, uint, 0); | ||
3663 | #define ALI5455_MODULE_NAME "ali5455" | ||
3664 | static struct pci_driver ali_pci_driver = { | ||
3665 | .name = ALI5455_MODULE_NAME, | ||
3666 | .id_table = ali_pci_tbl, | ||
3667 | .probe = ali_probe, | ||
3668 | .remove = __devexit_p(ali_remove), | ||
3669 | #ifdef CONFIG_PM | ||
3670 | .suspend = ali_pm_suspend, | ||
3671 | .resume = ali_pm_resume, | ||
3672 | #endif /* CONFIG_PM */ | ||
3673 | }; | ||
3674 | |||
3675 | static int __init ali_init_module(void) | ||
3676 | { | ||
3677 | printk(KERN_INFO "ALI 5455 + AC97 Audio, version " | ||
3678 | DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n"); | ||
3679 | |||
3680 | if (codec_independent_spdif_locked > 0) { | ||
3681 | if (codec_independent_spdif_locked == 32000 | ||
3682 | || codec_independent_spdif_locked == 44100 | ||
3683 | || codec_independent_spdif_locked == 48000) { | ||
3684 | printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", codec_independent_spdif_locked); | ||
3685 | } else { | ||
3686 | printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n"); | ||
3687 | codec_independent_spdif_locked = 0; | ||
3688 | } | ||
3689 | } | ||
3690 | if (controller_independent_spdif_locked > 0) { | ||
3691 | if (controller_independent_spdif_locked == 32000 | ||
3692 | || controller_independent_spdif_locked == 44100 | ||
3693 | || controller_independent_spdif_locked == 48000) { | ||
3694 | printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", controller_independent_spdif_locked); | ||
3695 | } else { | ||
3696 | printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n"); | ||
3697 | controller_independent_spdif_locked = 0; | ||
3698 | } | ||
3699 | } | ||
3700 | |||
3701 | if (codec_pcmout_share_spdif_locked > 0) { | ||
3702 | if (codec_pcmout_share_spdif_locked == 32000 | ||
3703 | || codec_pcmout_share_spdif_locked == 44100 | ||
3704 | || codec_pcmout_share_spdif_locked == 48000) { | ||
3705 | printk(KERN_INFO "ali_audio: Enabling S/PDIF at sample rate %dHz.\n", codec_pcmout_share_spdif_locked); | ||
3706 | } else { | ||
3707 | printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n"); | ||
3708 | codec_pcmout_share_spdif_locked = 0; | ||
3709 | } | ||
3710 | } | ||
3711 | if (controller_pcmout_share_spdif_locked > 0) { | ||
3712 | if (controller_pcmout_share_spdif_locked == 32000 | ||
3713 | || controller_pcmout_share_spdif_locked == 44100 | ||
3714 | || controller_pcmout_share_spdif_locked == 48000) { | ||
3715 | printk(KERN_INFO "ali_audio: Enabling controller S/PDIF at sample rate %dHz.\n", controller_pcmout_share_spdif_locked); | ||
3716 | } else { | ||
3717 | printk(KERN_INFO "ali_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n"); | ||
3718 | controller_pcmout_share_spdif_locked = 0; | ||
3719 | } | ||
3720 | } | ||
3721 | return pci_register_driver(&ali_pci_driver); | ||
3722 | } | ||
3723 | |||
3724 | static void __exit ali_cleanup_module(void) | ||
3725 | { | ||
3726 | pci_unregister_driver(&ali_pci_driver); | ||
3727 | } | ||
3728 | |||
3729 | module_init(ali_init_module); | ||
3730 | module_exit(ali_cleanup_module); | ||
3731 | /* | ||
3732 | Local Variables: | ||
3733 | c-basic-offset: 8 | ||
3734 | End: | ||
3735 | */ | ||
diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c deleted file mode 100644 index e3796231452a..000000000000 --- a/sound/oss/au1000.c +++ /dev/null | |||
@@ -1,2216 +0,0 @@ | |||
1 | /* | ||
2 | * au1000.c -- Sound driver for Alchemy Au1000 MIPS Internet Edge | ||
3 | * Processor. | ||
4 | * | ||
5 | * Copyright 2001 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * stevel@mvista.com or source@mvista.com | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
17 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
20 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
21 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License along | ||
26 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | * | ||
29 | * | ||
30 | * Module command line parameters: | ||
31 | * | ||
32 | * Supported devices: | ||
33 | * /dev/dsp standard OSS /dev/dsp device | ||
34 | * /dev/mixer standard OSS /dev/mixer device | ||
35 | * | ||
36 | * Notes: | ||
37 | * | ||
38 | * 1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are | ||
39 | * taken, slightly modified or not at all, from the ES1371 driver, | ||
40 | * so refer to the credits in es1371.c for those. The rest of the | ||
41 | * code (probe, open, read, write, the ISR, etc.) is new. | ||
42 | * | ||
43 | * Revision history | ||
44 | * 06.27.2001 Initial version | ||
45 | * 03.20.2002 Added mutex locks around read/write methods, to prevent | ||
46 | * simultaneous access on SMP or preemptible kernels. Also | ||
47 | * removed the counter/pointer fragment aligning at the end | ||
48 | * of read/write methods [stevel]. | ||
49 | * 03.21.2002 Add support for coherent DMA on the audio read/write DMA | ||
50 | * channels [stevel]. | ||
51 | * | ||
52 | */ | ||
53 | #include <linux/module.h> | ||
54 | #include <linux/string.h> | ||
55 | #include <linux/ioport.h> | ||
56 | #include <linux/sched.h> | ||
57 | #include <linux/delay.h> | ||
58 | #include <linux/sound.h> | ||
59 | #include <linux/slab.h> | ||
60 | #include <linux/soundcard.h> | ||
61 | #include <linux/init.h> | ||
62 | #include <linux/page-flags.h> | ||
63 | #include <linux/poll.h> | ||
64 | #include <linux/pci.h> | ||
65 | #include <linux/bitops.h> | ||
66 | #include <linux/proc_fs.h> | ||
67 | #include <linux/spinlock.h> | ||
68 | #include <linux/smp_lock.h> | ||
69 | #include <linux/ac97_codec.h> | ||
70 | #include <linux/interrupt.h> | ||
71 | #include <linux/mutex.h> | ||
72 | |||
73 | #include <asm/io.h> | ||
74 | #include <asm/uaccess.h> | ||
75 | #include <asm/mach-au1x00/au1000.h> | ||
76 | #include <asm/mach-au1x00/au1000_dma.h> | ||
77 | |||
78 | /* --------------------------------------------------------------------- */ | ||
79 | |||
80 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
81 | #undef AU1000_DEBUG | ||
82 | #undef AU1000_VERBOSE_DEBUG | ||
83 | |||
84 | #define AU1000_MODULE_NAME "Au1000 audio" | ||
85 | #define PFX AU1000_MODULE_NAME | ||
86 | |||
87 | #ifdef AU1000_DEBUG | ||
88 | #define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg) | ||
89 | #else | ||
90 | #define dbg(format, arg...) do {} while (0) | ||
91 | #endif | ||
92 | #define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg) | ||
93 | #define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg) | ||
94 | #define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg) | ||
95 | |||
96 | |||
97 | /* misc stuff */ | ||
98 | #define POLL_COUNT 0x5000 | ||
99 | #define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC) | ||
100 | |||
101 | /* Boot options */ | ||
102 | static int vra = 0; // 0 = no VRA, 1 = use VRA if codec supports it | ||
103 | module_param(vra, bool, 0); | ||
104 | MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it"); | ||
105 | |||
106 | |||
107 | /* --------------------------------------------------------------------- */ | ||
108 | |||
109 | struct au1000_state { | ||
110 | /* soundcore stuff */ | ||
111 | int dev_audio; | ||
112 | |||
113 | #ifdef AU1000_DEBUG | ||
114 | /* debug /proc entry */ | ||
115 | struct proc_dir_entry *ps; | ||
116 | struct proc_dir_entry *ac97_ps; | ||
117 | #endif /* AU1000_DEBUG */ | ||
118 | |||
119 | struct ac97_codec codec; | ||
120 | unsigned codec_base_caps;// AC'97 reg 00h, "Reset Register" | ||
121 | unsigned codec_ext_caps; // AC'97 reg 28h, "Extended Audio ID" | ||
122 | int no_vra; // do not use VRA | ||
123 | |||
124 | spinlock_t lock; | ||
125 | struct mutex open_mutex; | ||
126 | struct mutex sem; | ||
127 | mode_t open_mode; | ||
128 | wait_queue_head_t open_wait; | ||
129 | |||
130 | struct dmabuf { | ||
131 | unsigned int dmanr; // DMA Channel number | ||
132 | unsigned sample_rate; // Hz | ||
133 | unsigned src_factor; // SRC interp/decimation (no vra) | ||
134 | unsigned sample_size; // 8 or 16 | ||
135 | int num_channels; // 1 = mono, 2 = stereo, 4, 6 | ||
136 | int dma_bytes_per_sample;// DMA bytes per audio sample frame | ||
137 | int user_bytes_per_sample;// User bytes per audio sample frame | ||
138 | int cnt_factor; // user-to-DMA bytes per audio | ||
139 | // sample frame | ||
140 | void *rawbuf; | ||
141 | dma_addr_t dmaaddr; | ||
142 | unsigned buforder; | ||
143 | unsigned numfrag; // # of DMA fragments in DMA buffer | ||
144 | unsigned fragshift; | ||
145 | void *nextIn; // ptr to next-in to DMA buffer | ||
146 | void *nextOut;// ptr to next-out from DMA buffer | ||
147 | int count; // current byte count in DMA buffer | ||
148 | unsigned total_bytes; // total bytes written or read | ||
149 | unsigned error; // over/underrun | ||
150 | wait_queue_head_t wait; | ||
151 | /* redundant, but makes calculations easier */ | ||
152 | unsigned fragsize; // user perception of fragment size | ||
153 | unsigned dma_fragsize; // DMA (real) fragment size | ||
154 | unsigned dmasize; // Total DMA buffer size | ||
155 | // (mult. of DMA fragsize) | ||
156 | /* OSS stuff */ | ||
157 | unsigned mapped:1; | ||
158 | unsigned ready:1; | ||
159 | unsigned stopped:1; | ||
160 | unsigned ossfragshift; | ||
161 | int ossmaxfrags; | ||
162 | unsigned subdivision; | ||
163 | } dma_dac , dma_adc; | ||
164 | } au1000_state; | ||
165 | |||
166 | /* --------------------------------------------------------------------- */ | ||
167 | |||
168 | |||
169 | static inline unsigned ld2(unsigned int x) | ||
170 | { | ||
171 | unsigned r = 0; | ||
172 | |||
173 | if (x >= 0x10000) { | ||
174 | x >>= 16; | ||
175 | r += 16; | ||
176 | } | ||
177 | if (x >= 0x100) { | ||
178 | x >>= 8; | ||
179 | r += 8; | ||
180 | } | ||
181 | if (x >= 0x10) { | ||
182 | x >>= 4; | ||
183 | r += 4; | ||
184 | } | ||
185 | if (x >= 4) { | ||
186 | x >>= 2; | ||
187 | r += 2; | ||
188 | } | ||
189 | if (x >= 2) | ||
190 | r++; | ||
191 | return r; | ||
192 | } | ||
193 | |||
194 | /* --------------------------------------------------------------------- */ | ||
195 | |||
196 | static void au1000_delay(int msec) | ||
197 | { | ||
198 | unsigned long tmo; | ||
199 | signed long tmo2; | ||
200 | |||
201 | if (in_interrupt()) | ||
202 | return; | ||
203 | |||
204 | tmo = jiffies + (msec * HZ) / 1000; | ||
205 | for (;;) { | ||
206 | tmo2 = tmo - jiffies; | ||
207 | if (tmo2 <= 0) | ||
208 | break; | ||
209 | schedule_timeout(tmo2); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | |||
214 | /* --------------------------------------------------------------------- */ | ||
215 | |||
216 | static u16 rdcodec(struct ac97_codec *codec, u8 addr) | ||
217 | { | ||
218 | struct au1000_state *s = (struct au1000_state *)codec->private_data; | ||
219 | unsigned long flags; | ||
220 | u32 cmd; | ||
221 | u16 data; | ||
222 | int i; | ||
223 | |||
224 | spin_lock_irqsave(&s->lock, flags); | ||
225 | |||
226 | for (i = 0; i < POLL_COUNT; i++) | ||
227 | if (!(au_readl(AC97C_STATUS) & AC97C_CP)) | ||
228 | break; | ||
229 | if (i == POLL_COUNT) | ||
230 | err("rdcodec: codec cmd pending expired!"); | ||
231 | |||
232 | cmd = (u32) addr & AC97C_INDEX_MASK; | ||
233 | cmd |= AC97C_READ; // read command | ||
234 | au_writel(cmd, AC97C_CMD); | ||
235 | |||
236 | /* now wait for the data */ | ||
237 | for (i = 0; i < POLL_COUNT; i++) | ||
238 | if (!(au_readl(AC97C_STATUS) & AC97C_CP)) | ||
239 | break; | ||
240 | if (i == POLL_COUNT) { | ||
241 | err("rdcodec: read poll expired!"); | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | data = au_readl(AC97C_CMD) & 0xffff; | ||
246 | |||
247 | spin_unlock_irqrestore(&s->lock, flags); | ||
248 | |||
249 | return data; | ||
250 | } | ||
251 | |||
252 | |||
253 | static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data) | ||
254 | { | ||
255 | struct au1000_state *s = (struct au1000_state *)codec->private_data; | ||
256 | unsigned long flags; | ||
257 | u32 cmd; | ||
258 | int i; | ||
259 | |||
260 | spin_lock_irqsave(&s->lock, flags); | ||
261 | |||
262 | for (i = 0; i < POLL_COUNT; i++) | ||
263 | if (!(au_readl(AC97C_STATUS) & AC97C_CP)) | ||
264 | break; | ||
265 | if (i == POLL_COUNT) | ||
266 | err("wrcodec: codec cmd pending expired!"); | ||
267 | |||
268 | cmd = (u32) addr & AC97C_INDEX_MASK; | ||
269 | cmd &= ~AC97C_READ; // write command | ||
270 | cmd |= ((u32) data << AC97C_WD_BIT); // OR in the data word | ||
271 | au_writel(cmd, AC97C_CMD); | ||
272 | |||
273 | spin_unlock_irqrestore(&s->lock, flags); | ||
274 | } | ||
275 | |||
276 | static void waitcodec(struct ac97_codec *codec) | ||
277 | { | ||
278 | u16 temp; | ||
279 | int i; | ||
280 | |||
281 | /* codec_wait is used to wait for a ready state after | ||
282 | an AC97C_RESET. */ | ||
283 | au1000_delay(10); | ||
284 | |||
285 | // first poll the CODEC_READY tag bit | ||
286 | for (i = 0; i < POLL_COUNT; i++) | ||
287 | if (au_readl(AC97C_STATUS) & AC97C_READY) | ||
288 | break; | ||
289 | if (i == POLL_COUNT) { | ||
290 | err("waitcodec: CODEC_READY poll expired!"); | ||
291 | return; | ||
292 | } | ||
293 | // get AC'97 powerdown control/status register | ||
294 | temp = rdcodec(codec, AC97_POWER_CONTROL); | ||
295 | |||
296 | // If anything is powered down, power'em up | ||
297 | if (temp & 0x7f00) { | ||
298 | // Power on | ||
299 | wrcodec(codec, AC97_POWER_CONTROL, 0); | ||
300 | au1000_delay(100); | ||
301 | // Reread | ||
302 | temp = rdcodec(codec, AC97_POWER_CONTROL); | ||
303 | } | ||
304 | |||
305 | // Check if Codec REF,ANL,DAC,ADC ready | ||
306 | if ((temp & 0x7f0f) != 0x000f) | ||
307 | err("codec reg 26 status (0x%x) not ready!!", temp); | ||
308 | } | ||
309 | |||
310 | |||
311 | /* --------------------------------------------------------------------- */ | ||
312 | |||
313 | /* stop the ADC before calling */ | ||
314 | static void set_adc_rate(struct au1000_state *s, unsigned rate) | ||
315 | { | ||
316 | struct dmabuf *adc = &s->dma_adc; | ||
317 | struct dmabuf *dac = &s->dma_dac; | ||
318 | unsigned adc_rate, dac_rate; | ||
319 | u16 ac97_extstat; | ||
320 | |||
321 | if (s->no_vra) { | ||
322 | // calc SRC factor | ||
323 | adc->src_factor = ((96000 / rate) + 1) >> 1; | ||
324 | adc->sample_rate = 48000 / adc->src_factor; | ||
325 | return; | ||
326 | } | ||
327 | |||
328 | adc->src_factor = 1; | ||
329 | |||
330 | ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS); | ||
331 | |||
332 | rate = rate > 48000 ? 48000 : rate; | ||
333 | |||
334 | // enable VRA | ||
335 | wrcodec(&s->codec, AC97_EXTENDED_STATUS, | ||
336 | ac97_extstat | AC97_EXTSTAT_VRA); | ||
337 | // now write the sample rate | ||
338 | wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate); | ||
339 | // read it back for actual supported rate | ||
340 | adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE); | ||
341 | |||
342 | #ifdef AU1000_VERBOSE_DEBUG | ||
343 | dbg("%s: set to %d Hz", __FUNCTION__, adc_rate); | ||
344 | #endif | ||
345 | |||
346 | // some codec's don't allow unequal DAC and ADC rates, in which case | ||
347 | // writing one rate reg actually changes both. | ||
348 | dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE); | ||
349 | if (dac->num_channels > 2) | ||
350 | wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate); | ||
351 | if (dac->num_channels > 4) | ||
352 | wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate); | ||
353 | |||
354 | adc->sample_rate = adc_rate; | ||
355 | dac->sample_rate = dac_rate; | ||
356 | } | ||
357 | |||
358 | /* stop the DAC before calling */ | ||
359 | static void set_dac_rate(struct au1000_state *s, unsigned rate) | ||
360 | { | ||
361 | struct dmabuf *dac = &s->dma_dac; | ||
362 | struct dmabuf *adc = &s->dma_adc; | ||
363 | unsigned adc_rate, dac_rate; | ||
364 | u16 ac97_extstat; | ||
365 | |||
366 | if (s->no_vra) { | ||
367 | // calc SRC factor | ||
368 | dac->src_factor = ((96000 / rate) + 1) >> 1; | ||
369 | dac->sample_rate = 48000 / dac->src_factor; | ||
370 | return; | ||
371 | } | ||
372 | |||
373 | dac->src_factor = 1; | ||
374 | |||
375 | ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS); | ||
376 | |||
377 | rate = rate > 48000 ? 48000 : rate; | ||
378 | |||
379 | // enable VRA | ||
380 | wrcodec(&s->codec, AC97_EXTENDED_STATUS, | ||
381 | ac97_extstat | AC97_EXTSTAT_VRA); | ||
382 | // now write the sample rate | ||
383 | wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate); | ||
384 | // I don't support different sample rates for multichannel, | ||
385 | // so make these channels the same. | ||
386 | if (dac->num_channels > 2) | ||
387 | wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate); | ||
388 | if (dac->num_channels > 4) | ||
389 | wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate); | ||
390 | // read it back for actual supported rate | ||
391 | dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE); | ||
392 | |||
393 | #ifdef AU1000_VERBOSE_DEBUG | ||
394 | dbg("%s: set to %d Hz", __FUNCTION__, dac_rate); | ||
395 | #endif | ||
396 | |||
397 | // some codec's don't allow unequal DAC and ADC rates, in which case | ||
398 | // writing one rate reg actually changes both. | ||
399 | adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE); | ||
400 | |||
401 | dac->sample_rate = dac_rate; | ||
402 | adc->sample_rate = adc_rate; | ||
403 | } | ||
404 | |||
405 | static void stop_dac(struct au1000_state *s) | ||
406 | { | ||
407 | struct dmabuf *db = &s->dma_dac; | ||
408 | unsigned long flags; | ||
409 | |||
410 | if (db->stopped) | ||
411 | return; | ||
412 | |||
413 | spin_lock_irqsave(&s->lock, flags); | ||
414 | |||
415 | disable_dma(db->dmanr); | ||
416 | |||
417 | db->stopped = 1; | ||
418 | |||
419 | spin_unlock_irqrestore(&s->lock, flags); | ||
420 | } | ||
421 | |||
422 | static void stop_adc(struct au1000_state *s) | ||
423 | { | ||
424 | struct dmabuf *db = &s->dma_adc; | ||
425 | unsigned long flags; | ||
426 | |||
427 | if (db->stopped) | ||
428 | return; | ||
429 | |||
430 | spin_lock_irqsave(&s->lock, flags); | ||
431 | |||
432 | disable_dma(db->dmanr); | ||
433 | |||
434 | db->stopped = 1; | ||
435 | |||
436 | spin_unlock_irqrestore(&s->lock, flags); | ||
437 | } | ||
438 | |||
439 | |||
440 | static void set_xmit_slots(int num_channels) | ||
441 | { | ||
442 | u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_XMIT_SLOTS_MASK; | ||
443 | |||
444 | switch (num_channels) { | ||
445 | case 1: // mono | ||
446 | case 2: // stereo, slots 3,4 | ||
447 | ac97_config |= (0x3 << AC97C_XMIT_SLOTS_BIT); | ||
448 | break; | ||
449 | case 4: // stereo with surround, slots 3,4,7,8 | ||
450 | ac97_config |= (0x33 << AC97C_XMIT_SLOTS_BIT); | ||
451 | break; | ||
452 | case 6: // stereo with surround and center/LFE, slots 3,4,6,7,8,9 | ||
453 | ac97_config |= (0x7b << AC97C_XMIT_SLOTS_BIT); | ||
454 | break; | ||
455 | } | ||
456 | |||
457 | au_writel(ac97_config, AC97C_CONFIG); | ||
458 | } | ||
459 | |||
460 | static void set_recv_slots(int num_channels) | ||
461 | { | ||
462 | u32 ac97_config = au_readl(AC97C_CONFIG) & ~AC97C_RECV_SLOTS_MASK; | ||
463 | |||
464 | /* | ||
465 | * Always enable slots 3 and 4 (stereo). Slot 6 is | ||
466 | * optional Mic ADC, which I don't support yet. | ||
467 | */ | ||
468 | ac97_config |= (0x3 << AC97C_RECV_SLOTS_BIT); | ||
469 | |||
470 | au_writel(ac97_config, AC97C_CONFIG); | ||
471 | } | ||
472 | |||
473 | static void start_dac(struct au1000_state *s) | ||
474 | { | ||
475 | struct dmabuf *db = &s->dma_dac; | ||
476 | unsigned long flags; | ||
477 | unsigned long buf1, buf2; | ||
478 | |||
479 | if (!db->stopped) | ||
480 | return; | ||
481 | |||
482 | spin_lock_irqsave(&s->lock, flags); | ||
483 | |||
484 | au_readl(AC97C_STATUS); // read status to clear sticky bits | ||
485 | |||
486 | // reset Buffer 1 and 2 pointers to nextOut and nextOut+dma_fragsize | ||
487 | buf1 = virt_to_phys(db->nextOut); | ||
488 | buf2 = buf1 + db->dma_fragsize; | ||
489 | if (buf2 >= db->dmaaddr + db->dmasize) | ||
490 | buf2 -= db->dmasize; | ||
491 | |||
492 | set_xmit_slots(db->num_channels); | ||
493 | |||
494 | init_dma(db->dmanr); | ||
495 | if (get_dma_active_buffer(db->dmanr) == 0) { | ||
496 | clear_dma_done0(db->dmanr); // clear DMA done bit | ||
497 | set_dma_addr0(db->dmanr, buf1); | ||
498 | set_dma_addr1(db->dmanr, buf2); | ||
499 | } else { | ||
500 | clear_dma_done1(db->dmanr); // clear DMA done bit | ||
501 | set_dma_addr1(db->dmanr, buf1); | ||
502 | set_dma_addr0(db->dmanr, buf2); | ||
503 | } | ||
504 | set_dma_count(db->dmanr, db->dma_fragsize>>1); | ||
505 | enable_dma_buffers(db->dmanr); | ||
506 | |||
507 | start_dma(db->dmanr); | ||
508 | |||
509 | #ifdef AU1000_VERBOSE_DEBUG | ||
510 | dump_au1000_dma_channel(db->dmanr); | ||
511 | #endif | ||
512 | |||
513 | db->stopped = 0; | ||
514 | |||
515 | spin_unlock_irqrestore(&s->lock, flags); | ||
516 | } | ||
517 | |||
518 | static void start_adc(struct au1000_state *s) | ||
519 | { | ||
520 | struct dmabuf *db = &s->dma_adc; | ||
521 | unsigned long flags; | ||
522 | unsigned long buf1, buf2; | ||
523 | |||
524 | if (!db->stopped) | ||
525 | return; | ||
526 | |||
527 | spin_lock_irqsave(&s->lock, flags); | ||
528 | |||
529 | au_readl(AC97C_STATUS); // read status to clear sticky bits | ||
530 | |||
531 | // reset Buffer 1 and 2 pointers to nextIn and nextIn+dma_fragsize | ||
532 | buf1 = virt_to_phys(db->nextIn); | ||
533 | buf2 = buf1 + db->dma_fragsize; | ||
534 | if (buf2 >= db->dmaaddr + db->dmasize) | ||
535 | buf2 -= db->dmasize; | ||
536 | |||
537 | set_recv_slots(db->num_channels); | ||
538 | |||
539 | init_dma(db->dmanr); | ||
540 | if (get_dma_active_buffer(db->dmanr) == 0) { | ||
541 | clear_dma_done0(db->dmanr); // clear DMA done bit | ||
542 | set_dma_addr0(db->dmanr, buf1); | ||
543 | set_dma_addr1(db->dmanr, buf2); | ||
544 | } else { | ||
545 | clear_dma_done1(db->dmanr); // clear DMA done bit | ||
546 | set_dma_addr1(db->dmanr, buf1); | ||
547 | set_dma_addr0(db->dmanr, buf2); | ||
548 | } | ||
549 | set_dma_count(db->dmanr, db->dma_fragsize>>1); | ||
550 | enable_dma_buffers(db->dmanr); | ||
551 | |||
552 | start_dma(db->dmanr); | ||
553 | |||
554 | #ifdef AU1000_VERBOSE_DEBUG | ||
555 | dump_au1000_dma_channel(db->dmanr); | ||
556 | #endif | ||
557 | |||
558 | db->stopped = 0; | ||
559 | |||
560 | spin_unlock_irqrestore(&s->lock, flags); | ||
561 | } | ||
562 | |||
563 | /* --------------------------------------------------------------------- */ | ||
564 | |||
565 | #define DMABUF_DEFAULTORDER (17-PAGE_SHIFT) | ||
566 | #define DMABUF_MINORDER 1 | ||
567 | |||
568 | static inline void dealloc_dmabuf(struct au1000_state *s, struct dmabuf *db) | ||
569 | { | ||
570 | struct page *page, *pend; | ||
571 | |||
572 | if (db->rawbuf) { | ||
573 | /* undo marking the pages as reserved */ | ||
574 | pend = virt_to_page(db->rawbuf + | ||
575 | (PAGE_SIZE << db->buforder) - 1); | ||
576 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
577 | ClearPageReserved(page); | ||
578 | dma_free_noncoherent(NULL, | ||
579 | PAGE_SIZE << db->buforder, | ||
580 | db->rawbuf, | ||
581 | db->dmaaddr); | ||
582 | } | ||
583 | db->rawbuf = db->nextIn = db->nextOut = NULL; | ||
584 | db->mapped = db->ready = 0; | ||
585 | } | ||
586 | |||
587 | static int prog_dmabuf(struct au1000_state *s, struct dmabuf *db) | ||
588 | { | ||
589 | int order; | ||
590 | unsigned user_bytes_per_sec; | ||
591 | unsigned bufs; | ||
592 | struct page *page, *pend; | ||
593 | unsigned rate = db->sample_rate; | ||
594 | |||
595 | if (!db->rawbuf) { | ||
596 | db->ready = db->mapped = 0; | ||
597 | for (order = DMABUF_DEFAULTORDER; | ||
598 | order >= DMABUF_MINORDER; order--) | ||
599 | if ((db->rawbuf = dma_alloc_noncoherent(NULL, | ||
600 | PAGE_SIZE << order, | ||
601 | &db->dmaaddr, | ||
602 | 0))) | ||
603 | break; | ||
604 | if (!db->rawbuf) | ||
605 | return -ENOMEM; | ||
606 | db->buforder = order; | ||
607 | /* now mark the pages as reserved; | ||
608 | otherwise remap_pfn_range doesn't do what we want */ | ||
609 | pend = virt_to_page(db->rawbuf + | ||
610 | (PAGE_SIZE << db->buforder) - 1); | ||
611 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
612 | SetPageReserved(page); | ||
613 | } | ||
614 | |||
615 | db->cnt_factor = 1; | ||
616 | if (db->sample_size == 8) | ||
617 | db->cnt_factor *= 2; | ||
618 | if (db->num_channels == 1) | ||
619 | db->cnt_factor *= 2; | ||
620 | db->cnt_factor *= db->src_factor; | ||
621 | |||
622 | db->count = 0; | ||
623 | db->nextIn = db->nextOut = db->rawbuf; | ||
624 | |||
625 | db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels; | ||
626 | db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ? | ||
627 | 2 : db->num_channels); | ||
628 | |||
629 | user_bytes_per_sec = rate * db->user_bytes_per_sample; | ||
630 | bufs = PAGE_SIZE << db->buforder; | ||
631 | if (db->ossfragshift) { | ||
632 | if ((1000 << db->ossfragshift) < user_bytes_per_sec) | ||
633 | db->fragshift = ld2(user_bytes_per_sec/1000); | ||
634 | else | ||
635 | db->fragshift = db->ossfragshift; | ||
636 | } else { | ||
637 | db->fragshift = ld2(user_bytes_per_sec / 100 / | ||
638 | (db->subdivision ? db->subdivision : 1)); | ||
639 | if (db->fragshift < 3) | ||
640 | db->fragshift = 3; | ||
641 | } | ||
642 | |||
643 | db->fragsize = 1 << db->fragshift; | ||
644 | db->dma_fragsize = db->fragsize * db->cnt_factor; | ||
645 | db->numfrag = bufs / db->dma_fragsize; | ||
646 | |||
647 | while (db->numfrag < 4 && db->fragshift > 3) { | ||
648 | db->fragshift--; | ||
649 | db->fragsize = 1 << db->fragshift; | ||
650 | db->dma_fragsize = db->fragsize * db->cnt_factor; | ||
651 | db->numfrag = bufs / db->dma_fragsize; | ||
652 | } | ||
653 | |||
654 | if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) | ||
655 | db->numfrag = db->ossmaxfrags; | ||
656 | |||
657 | db->dmasize = db->dma_fragsize * db->numfrag; | ||
658 | memset(db->rawbuf, 0, bufs); | ||
659 | |||
660 | #ifdef AU1000_VERBOSE_DEBUG | ||
661 | dbg("rate=%d, samplesize=%d, channels=%d", | ||
662 | rate, db->sample_size, db->num_channels); | ||
663 | dbg("fragsize=%d, cnt_factor=%d, dma_fragsize=%d", | ||
664 | db->fragsize, db->cnt_factor, db->dma_fragsize); | ||
665 | dbg("numfrag=%d, dmasize=%d", db->numfrag, db->dmasize); | ||
666 | #endif | ||
667 | |||
668 | db->ready = 1; | ||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | static inline int prog_dmabuf_adc(struct au1000_state *s) | ||
673 | { | ||
674 | stop_adc(s); | ||
675 | return prog_dmabuf(s, &s->dma_adc); | ||
676 | |||
677 | } | ||
678 | |||
679 | static inline int prog_dmabuf_dac(struct au1000_state *s) | ||
680 | { | ||
681 | stop_dac(s); | ||
682 | return prog_dmabuf(s, &s->dma_dac); | ||
683 | } | ||
684 | |||
685 | |||
686 | /* hold spinlock for the following */ | ||
687 | static irqreturn_t dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
688 | { | ||
689 | struct au1000_state *s = (struct au1000_state *) dev_id; | ||
690 | struct dmabuf *dac = &s->dma_dac; | ||
691 | unsigned long newptr; | ||
692 | u32 ac97c_stat, buff_done; | ||
693 | |||
694 | ac97c_stat = au_readl(AC97C_STATUS); | ||
695 | #ifdef AU1000_VERBOSE_DEBUG | ||
696 | if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE)) | ||
697 | dbg("AC97C status = 0x%08x", ac97c_stat); | ||
698 | #endif | ||
699 | |||
700 | if ((buff_done = get_dma_buffer_done(dac->dmanr)) == 0) { | ||
701 | /* fastpath out, to ease interrupt sharing */ | ||
702 | return IRQ_HANDLED; | ||
703 | } | ||
704 | |||
705 | spin_lock(&s->lock); | ||
706 | |||
707 | if (buff_done != (DMA_D0 | DMA_D1)) { | ||
708 | dac->nextOut += dac->dma_fragsize; | ||
709 | if (dac->nextOut >= dac->rawbuf + dac->dmasize) | ||
710 | dac->nextOut -= dac->dmasize; | ||
711 | |||
712 | /* update playback pointers */ | ||
713 | newptr = virt_to_phys(dac->nextOut) + dac->dma_fragsize; | ||
714 | if (newptr >= dac->dmaaddr + dac->dmasize) | ||
715 | newptr -= dac->dmasize; | ||
716 | |||
717 | dac->count -= dac->dma_fragsize; | ||
718 | dac->total_bytes += dac->dma_fragsize; | ||
719 | |||
720 | if (dac->count <= 0) { | ||
721 | #ifdef AU1000_VERBOSE_DEBUG | ||
722 | dbg("dac underrun"); | ||
723 | #endif | ||
724 | spin_unlock(&s->lock); | ||
725 | stop_dac(s); | ||
726 | spin_lock(&s->lock); | ||
727 | dac->count = 0; | ||
728 | dac->nextIn = dac->nextOut; | ||
729 | } else if (buff_done == DMA_D0) { | ||
730 | clear_dma_done0(dac->dmanr); // clear DMA done bit | ||
731 | set_dma_count0(dac->dmanr, dac->dma_fragsize>>1); | ||
732 | set_dma_addr0(dac->dmanr, newptr); | ||
733 | enable_dma_buffer0(dac->dmanr); // reenable | ||
734 | } else { | ||
735 | clear_dma_done1(dac->dmanr); // clear DMA done bit | ||
736 | set_dma_count1(dac->dmanr, dac->dma_fragsize>>1); | ||
737 | set_dma_addr1(dac->dmanr, newptr); | ||
738 | enable_dma_buffer1(dac->dmanr); // reenable | ||
739 | } | ||
740 | } else { | ||
741 | // both done bits set, we missed an interrupt | ||
742 | spin_unlock(&s->lock); | ||
743 | stop_dac(s); | ||
744 | spin_lock(&s->lock); | ||
745 | |||
746 | dac->nextOut += 2*dac->dma_fragsize; | ||
747 | if (dac->nextOut >= dac->rawbuf + dac->dmasize) | ||
748 | dac->nextOut -= dac->dmasize; | ||
749 | |||
750 | dac->count -= 2*dac->dma_fragsize; | ||
751 | dac->total_bytes += 2*dac->dma_fragsize; | ||
752 | |||
753 | if (dac->count > 0) { | ||
754 | spin_unlock(&s->lock); | ||
755 | start_dac(s); | ||
756 | spin_lock(&s->lock); | ||
757 | } | ||
758 | } | ||
759 | |||
760 | /* wake up anybody listening */ | ||
761 | if (waitqueue_active(&dac->wait)) | ||
762 | wake_up(&dac->wait); | ||
763 | |||
764 | spin_unlock(&s->lock); | ||
765 | |||
766 | return IRQ_HANDLED; | ||
767 | } | ||
768 | |||
769 | |||
770 | static irqreturn_t adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
771 | { | ||
772 | struct au1000_state *s = (struct au1000_state *) dev_id; | ||
773 | struct dmabuf *adc = &s->dma_adc; | ||
774 | unsigned long newptr; | ||
775 | u32 ac97c_stat, buff_done; | ||
776 | |||
777 | ac97c_stat = au_readl(AC97C_STATUS); | ||
778 | #ifdef AU1000_VERBOSE_DEBUG | ||
779 | if (ac97c_stat & (AC97C_RU | AC97C_RO)) | ||
780 | dbg("AC97C status = 0x%08x", ac97c_stat); | ||
781 | #endif | ||
782 | |||
783 | if ((buff_done = get_dma_buffer_done(adc->dmanr)) == 0) { | ||
784 | /* fastpath out, to ease interrupt sharing */ | ||
785 | return IRQ_HANDLED; | ||
786 | } | ||
787 | |||
788 | spin_lock(&s->lock); | ||
789 | |||
790 | if (buff_done != (DMA_D0 | DMA_D1)) { | ||
791 | if (adc->count + adc->dma_fragsize > adc->dmasize) { | ||
792 | // Overrun. Stop ADC and log the error | ||
793 | spin_unlock(&s->lock); | ||
794 | stop_adc(s); | ||
795 | adc->error++; | ||
796 | err("adc overrun"); | ||
797 | return IRQ_NONE; | ||
798 | } | ||
799 | |||
800 | adc->nextIn += adc->dma_fragsize; | ||
801 | if (adc->nextIn >= adc->rawbuf + adc->dmasize) | ||
802 | adc->nextIn -= adc->dmasize; | ||
803 | |||
804 | /* update capture pointers */ | ||
805 | newptr = virt_to_phys(adc->nextIn) + adc->dma_fragsize; | ||
806 | if (newptr >= adc->dmaaddr + adc->dmasize) | ||
807 | newptr -= adc->dmasize; | ||
808 | |||
809 | adc->count += adc->dma_fragsize; | ||
810 | adc->total_bytes += adc->dma_fragsize; | ||
811 | |||
812 | if (buff_done == DMA_D0) { | ||
813 | clear_dma_done0(adc->dmanr); // clear DMA done bit | ||
814 | set_dma_count0(adc->dmanr, adc->dma_fragsize>>1); | ||
815 | set_dma_addr0(adc->dmanr, newptr); | ||
816 | enable_dma_buffer0(adc->dmanr); // reenable | ||
817 | } else { | ||
818 | clear_dma_done1(adc->dmanr); // clear DMA done bit | ||
819 | set_dma_count1(adc->dmanr, adc->dma_fragsize>>1); | ||
820 | set_dma_addr1(adc->dmanr, newptr); | ||
821 | enable_dma_buffer1(adc->dmanr); // reenable | ||
822 | } | ||
823 | } else { | ||
824 | // both done bits set, we missed an interrupt | ||
825 | spin_unlock(&s->lock); | ||
826 | stop_adc(s); | ||
827 | spin_lock(&s->lock); | ||
828 | |||
829 | if (adc->count + 2*adc->dma_fragsize > adc->dmasize) { | ||
830 | // Overrun. Log the error | ||
831 | adc->error++; | ||
832 | err("adc overrun"); | ||
833 | spin_unlock(&s->lock); | ||
834 | return IRQ_NONE; | ||
835 | } | ||
836 | |||
837 | adc->nextIn += 2*adc->dma_fragsize; | ||
838 | if (adc->nextIn >= adc->rawbuf + adc->dmasize) | ||
839 | adc->nextIn -= adc->dmasize; | ||
840 | |||
841 | adc->count += 2*adc->dma_fragsize; | ||
842 | adc->total_bytes += 2*adc->dma_fragsize; | ||
843 | |||
844 | spin_unlock(&s->lock); | ||
845 | start_adc(s); | ||
846 | spin_lock(&s->lock); | ||
847 | } | ||
848 | |||
849 | /* wake up anybody listening */ | ||
850 | if (waitqueue_active(&adc->wait)) | ||
851 | wake_up(&adc->wait); | ||
852 | |||
853 | spin_unlock(&s->lock); | ||
854 | |||
855 | return IRQ_HANDLED; | ||
856 | } | ||
857 | |||
858 | /* --------------------------------------------------------------------- */ | ||
859 | |||
860 | static loff_t au1000_llseek(struct file *file, loff_t offset, int origin) | ||
861 | { | ||
862 | return -ESPIPE; | ||
863 | } | ||
864 | |||
865 | |||
866 | static int au1000_open_mixdev(struct inode *inode, struct file *file) | ||
867 | { | ||
868 | file->private_data = &au1000_state; | ||
869 | return nonseekable_open(inode, file); | ||
870 | } | ||
871 | |||
872 | static int au1000_release_mixdev(struct inode *inode, struct file *file) | ||
873 | { | ||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, | ||
878 | unsigned long arg) | ||
879 | { | ||
880 | return codec->mixer_ioctl(codec, cmd, arg); | ||
881 | } | ||
882 | |||
883 | static int au1000_ioctl_mixdev(struct inode *inode, struct file *file, | ||
884 | unsigned int cmd, unsigned long arg) | ||
885 | { | ||
886 | struct au1000_state *s = (struct au1000_state *)file->private_data; | ||
887 | struct ac97_codec *codec = &s->codec; | ||
888 | |||
889 | return mixdev_ioctl(codec, cmd, arg); | ||
890 | } | ||
891 | |||
892 | static /*const */ struct file_operations au1000_mixer_fops = { | ||
893 | .owner = THIS_MODULE, | ||
894 | .llseek = au1000_llseek, | ||
895 | .ioctl = au1000_ioctl_mixdev, | ||
896 | .open = au1000_open_mixdev, | ||
897 | .release = au1000_release_mixdev, | ||
898 | }; | ||
899 | |||
900 | /* --------------------------------------------------------------------- */ | ||
901 | |||
902 | static int drain_dac(struct au1000_state *s, int nonblock) | ||
903 | { | ||
904 | unsigned long flags; | ||
905 | int count, tmo; | ||
906 | |||
907 | if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped) | ||
908 | return 0; | ||
909 | |||
910 | for (;;) { | ||
911 | spin_lock_irqsave(&s->lock, flags); | ||
912 | count = s->dma_dac.count; | ||
913 | spin_unlock_irqrestore(&s->lock, flags); | ||
914 | if (count <= 0) | ||
915 | break; | ||
916 | if (signal_pending(current)) | ||
917 | break; | ||
918 | if (nonblock) | ||
919 | return -EBUSY; | ||
920 | tmo = 1000 * count / (s->no_vra ? | ||
921 | 48000 : s->dma_dac.sample_rate); | ||
922 | tmo /= s->dma_dac.dma_bytes_per_sample; | ||
923 | au1000_delay(tmo); | ||
924 | } | ||
925 | if (signal_pending(current)) | ||
926 | return -ERESTARTSYS; | ||
927 | return 0; | ||
928 | } | ||
929 | |||
930 | /* --------------------------------------------------------------------- */ | ||
931 | |||
932 | static inline u8 S16_TO_U8(s16 ch) | ||
933 | { | ||
934 | return (u8) (ch >> 8) + 0x80; | ||
935 | } | ||
936 | static inline s16 U8_TO_S16(u8 ch) | ||
937 | { | ||
938 | return (s16) (ch - 0x80) << 8; | ||
939 | } | ||
940 | |||
941 | /* | ||
942 | * Translates user samples to dma buffer suitable for AC'97 DAC data: | ||
943 | * If mono, copy left channel to right channel in dma buffer. | ||
944 | * If 8 bit samples, cvt to 16-bit before writing to dma buffer. | ||
945 | * If interpolating (no VRA), duplicate every audio frame src_factor times. | ||
946 | */ | ||
947 | static int translate_from_user(struct dmabuf *db, | ||
948 | char* dmabuf, | ||
949 | char* userbuf, | ||
950 | int dmacount) | ||
951 | { | ||
952 | int sample, i; | ||
953 | int interp_bytes_per_sample; | ||
954 | int num_samples; | ||
955 | int mono = (db->num_channels == 1); | ||
956 | char usersample[12]; | ||
957 | s16 ch, dmasample[6]; | ||
958 | |||
959 | if (db->sample_size == 16 && !mono && db->src_factor == 1) { | ||
960 | // no translation necessary, just copy | ||
961 | if (copy_from_user(dmabuf, userbuf, dmacount)) | ||
962 | return -EFAULT; | ||
963 | return dmacount; | ||
964 | } | ||
965 | |||
966 | interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor; | ||
967 | num_samples = dmacount / interp_bytes_per_sample; | ||
968 | |||
969 | for (sample = 0; sample < num_samples; sample++) { | ||
970 | if (copy_from_user(usersample, userbuf, | ||
971 | db->user_bytes_per_sample)) { | ||
972 | dbg("%s: fault", __FUNCTION__); | ||
973 | return -EFAULT; | ||
974 | } | ||
975 | |||
976 | for (i = 0; i < db->num_channels; i++) { | ||
977 | if (db->sample_size == 8) | ||
978 | ch = U8_TO_S16(usersample[i]); | ||
979 | else | ||
980 | ch = *((s16 *) (&usersample[i * 2])); | ||
981 | dmasample[i] = ch; | ||
982 | if (mono) | ||
983 | dmasample[i + 1] = ch; // right channel | ||
984 | } | ||
985 | |||
986 | // duplicate every audio frame src_factor times | ||
987 | for (i = 0; i < db->src_factor; i++) | ||
988 | memcpy(dmabuf, dmasample, db->dma_bytes_per_sample); | ||
989 | |||
990 | userbuf += db->user_bytes_per_sample; | ||
991 | dmabuf += interp_bytes_per_sample; | ||
992 | } | ||
993 | |||
994 | return num_samples * interp_bytes_per_sample; | ||
995 | } | ||
996 | |||
997 | /* | ||
998 | * Translates AC'97 ADC samples to user buffer: | ||
999 | * If mono, send only left channel to user buffer. | ||
1000 | * If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer. | ||
1001 | * If decimating (no VRA), skip over src_factor audio frames. | ||
1002 | */ | ||
1003 | static int translate_to_user(struct dmabuf *db, | ||
1004 | char* userbuf, | ||
1005 | char* dmabuf, | ||
1006 | int dmacount) | ||
1007 | { | ||
1008 | int sample, i; | ||
1009 | int interp_bytes_per_sample; | ||
1010 | int num_samples; | ||
1011 | int mono = (db->num_channels == 1); | ||
1012 | char usersample[12]; | ||
1013 | |||
1014 | if (db->sample_size == 16 && !mono && db->src_factor == 1) { | ||
1015 | // no translation necessary, just copy | ||
1016 | if (copy_to_user(userbuf, dmabuf, dmacount)) | ||
1017 | return -EFAULT; | ||
1018 | return dmacount; | ||
1019 | } | ||
1020 | |||
1021 | interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor; | ||
1022 | num_samples = dmacount / interp_bytes_per_sample; | ||
1023 | |||
1024 | for (sample = 0; sample < num_samples; sample++) { | ||
1025 | for (i = 0; i < db->num_channels; i++) { | ||
1026 | if (db->sample_size == 8) | ||
1027 | usersample[i] = | ||
1028 | S16_TO_U8(*((s16 *) (&dmabuf[i * 2]))); | ||
1029 | else | ||
1030 | *((s16 *) (&usersample[i * 2])) = | ||
1031 | *((s16 *) (&dmabuf[i * 2])); | ||
1032 | } | ||
1033 | |||
1034 | if (copy_to_user(userbuf, usersample, | ||
1035 | db->user_bytes_per_sample)) { | ||
1036 | dbg("%s: fault", __FUNCTION__); | ||
1037 | return -EFAULT; | ||
1038 | } | ||
1039 | |||
1040 | userbuf += db->user_bytes_per_sample; | ||
1041 | dmabuf += interp_bytes_per_sample; | ||
1042 | } | ||
1043 | |||
1044 | return num_samples * interp_bytes_per_sample; | ||
1045 | } | ||
1046 | |||
1047 | /* | ||
1048 | * Copy audio data to/from user buffer from/to dma buffer, taking care | ||
1049 | * that we wrap when reading/writing the dma buffer. Returns actual byte | ||
1050 | * count written to or read from the dma buffer. | ||
1051 | */ | ||
1052 | static int copy_dmabuf_user(struct dmabuf *db, char* userbuf, | ||
1053 | int count, int to_user) | ||
1054 | { | ||
1055 | char *bufptr = to_user ? db->nextOut : db->nextIn; | ||
1056 | char *bufend = db->rawbuf + db->dmasize; | ||
1057 | int cnt, ret; | ||
1058 | |||
1059 | if (bufptr + count > bufend) { | ||
1060 | int partial = (int) (bufend - bufptr); | ||
1061 | if (to_user) { | ||
1062 | if ((cnt = translate_to_user(db, userbuf, | ||
1063 | bufptr, partial)) < 0) | ||
1064 | return cnt; | ||
1065 | ret = cnt; | ||
1066 | if ((cnt = translate_to_user(db, userbuf + partial, | ||
1067 | db->rawbuf, | ||
1068 | count - partial)) < 0) | ||
1069 | return cnt; | ||
1070 | ret += cnt; | ||
1071 | } else { | ||
1072 | if ((cnt = translate_from_user(db, bufptr, userbuf, | ||
1073 | partial)) < 0) | ||
1074 | return cnt; | ||
1075 | ret = cnt; | ||
1076 | if ((cnt = translate_from_user(db, db->rawbuf, | ||
1077 | userbuf + partial, | ||
1078 | count - partial)) < 0) | ||
1079 | return cnt; | ||
1080 | ret += cnt; | ||
1081 | } | ||
1082 | } else { | ||
1083 | if (to_user) | ||
1084 | ret = translate_to_user(db, userbuf, bufptr, count); | ||
1085 | else | ||
1086 | ret = translate_from_user(db, bufptr, userbuf, count); | ||
1087 | } | ||
1088 | |||
1089 | return ret; | ||
1090 | } | ||
1091 | |||
1092 | |||
1093 | static ssize_t au1000_read(struct file *file, char *buffer, | ||
1094 | size_t count, loff_t *ppos) | ||
1095 | { | ||
1096 | struct au1000_state *s = (struct au1000_state *)file->private_data; | ||
1097 | struct dmabuf *db = &s->dma_adc; | ||
1098 | DECLARE_WAITQUEUE(wait, current); | ||
1099 | ssize_t ret; | ||
1100 | unsigned long flags; | ||
1101 | int cnt, usercnt, avail; | ||
1102 | |||
1103 | if (db->mapped) | ||
1104 | return -ENXIO; | ||
1105 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1106 | return -EFAULT; | ||
1107 | ret = 0; | ||
1108 | |||
1109 | count *= db->cnt_factor; | ||
1110 | |||
1111 | mutex_lock(&s->sem); | ||
1112 | add_wait_queue(&db->wait, &wait); | ||
1113 | |||
1114 | while (count > 0) { | ||
1115 | // wait for samples in ADC dma buffer | ||
1116 | do { | ||
1117 | if (db->stopped) | ||
1118 | start_adc(s); | ||
1119 | spin_lock_irqsave(&s->lock, flags); | ||
1120 | avail = db->count; | ||
1121 | if (avail <= 0) | ||
1122 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1123 | spin_unlock_irqrestore(&s->lock, flags); | ||
1124 | if (avail <= 0) { | ||
1125 | if (file->f_flags & O_NONBLOCK) { | ||
1126 | if (!ret) | ||
1127 | ret = -EAGAIN; | ||
1128 | goto out; | ||
1129 | } | ||
1130 | mutex_unlock(&s->sem); | ||
1131 | schedule(); | ||
1132 | if (signal_pending(current)) { | ||
1133 | if (!ret) | ||
1134 | ret = -ERESTARTSYS; | ||
1135 | goto out2; | ||
1136 | } | ||
1137 | mutex_lock(&s->sem); | ||
1138 | } | ||
1139 | } while (avail <= 0); | ||
1140 | |||
1141 | // copy from nextOut to user | ||
1142 | if ((cnt = copy_dmabuf_user(db, buffer, | ||
1143 | count > avail ? | ||
1144 | avail : count, 1)) < 0) { | ||
1145 | if (!ret) | ||
1146 | ret = -EFAULT; | ||
1147 | goto out; | ||
1148 | } | ||
1149 | |||
1150 | spin_lock_irqsave(&s->lock, flags); | ||
1151 | db->count -= cnt; | ||
1152 | db->nextOut += cnt; | ||
1153 | if (db->nextOut >= db->rawbuf + db->dmasize) | ||
1154 | db->nextOut -= db->dmasize; | ||
1155 | spin_unlock_irqrestore(&s->lock, flags); | ||
1156 | |||
1157 | count -= cnt; | ||
1158 | usercnt = cnt / db->cnt_factor; | ||
1159 | buffer += usercnt; | ||
1160 | ret += usercnt; | ||
1161 | } // while (count > 0) | ||
1162 | |||
1163 | out: | ||
1164 | mutex_unlock(&s->sem); | ||
1165 | out2: | ||
1166 | remove_wait_queue(&db->wait, &wait); | ||
1167 | set_current_state(TASK_RUNNING); | ||
1168 | return ret; | ||
1169 | } | ||
1170 | |||
1171 | static ssize_t au1000_write(struct file *file, const char *buffer, | ||
1172 | size_t count, loff_t * ppos) | ||
1173 | { | ||
1174 | struct au1000_state *s = (struct au1000_state *)file->private_data; | ||
1175 | struct dmabuf *db = &s->dma_dac; | ||
1176 | DECLARE_WAITQUEUE(wait, current); | ||
1177 | ssize_t ret = 0; | ||
1178 | unsigned long flags; | ||
1179 | int cnt, usercnt, avail; | ||
1180 | |||
1181 | #ifdef AU1000_VERBOSE_DEBUG | ||
1182 | dbg("write: count=%d", count); | ||
1183 | #endif | ||
1184 | |||
1185 | if (db->mapped) | ||
1186 | return -ENXIO; | ||
1187 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1188 | return -EFAULT; | ||
1189 | |||
1190 | count *= db->cnt_factor; | ||
1191 | |||
1192 | mutex_lock(&s->sem); | ||
1193 | add_wait_queue(&db->wait, &wait); | ||
1194 | |||
1195 | while (count > 0) { | ||
1196 | // wait for space in playback buffer | ||
1197 | do { | ||
1198 | spin_lock_irqsave(&s->lock, flags); | ||
1199 | avail = (int) db->dmasize - db->count; | ||
1200 | if (avail <= 0) | ||
1201 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1202 | spin_unlock_irqrestore(&s->lock, flags); | ||
1203 | if (avail <= 0) { | ||
1204 | if (file->f_flags & O_NONBLOCK) { | ||
1205 | if (!ret) | ||
1206 | ret = -EAGAIN; | ||
1207 | goto out; | ||
1208 | } | ||
1209 | mutex_unlock(&s->sem); | ||
1210 | schedule(); | ||
1211 | if (signal_pending(current)) { | ||
1212 | if (!ret) | ||
1213 | ret = -ERESTARTSYS; | ||
1214 | goto out2; | ||
1215 | } | ||
1216 | mutex_lock(&s->sem); | ||
1217 | } | ||
1218 | } while (avail <= 0); | ||
1219 | |||
1220 | // copy from user to nextIn | ||
1221 | if ((cnt = copy_dmabuf_user(db, (char *) buffer, | ||
1222 | count > avail ? | ||
1223 | avail : count, 0)) < 0) { | ||
1224 | if (!ret) | ||
1225 | ret = -EFAULT; | ||
1226 | goto out; | ||
1227 | } | ||
1228 | |||
1229 | spin_lock_irqsave(&s->lock, flags); | ||
1230 | db->count += cnt; | ||
1231 | db->nextIn += cnt; | ||
1232 | if (db->nextIn >= db->rawbuf + db->dmasize) | ||
1233 | db->nextIn -= db->dmasize; | ||
1234 | spin_unlock_irqrestore(&s->lock, flags); | ||
1235 | if (db->stopped) | ||
1236 | start_dac(s); | ||
1237 | |||
1238 | count -= cnt; | ||
1239 | usercnt = cnt / db->cnt_factor; | ||
1240 | buffer += usercnt; | ||
1241 | ret += usercnt; | ||
1242 | } // while (count > 0) | ||
1243 | |||
1244 | out: | ||
1245 | mutex_unlock(&s->sem); | ||
1246 | out2: | ||
1247 | remove_wait_queue(&db->wait, &wait); | ||
1248 | set_current_state(TASK_RUNNING); | ||
1249 | return ret; | ||
1250 | } | ||
1251 | |||
1252 | |||
1253 | /* No kernel lock - we have our own spinlock */ | ||
1254 | static unsigned int au1000_poll(struct file *file, | ||
1255 | struct poll_table_struct *wait) | ||
1256 | { | ||
1257 | struct au1000_state *s = (struct au1000_state *)file->private_data; | ||
1258 | unsigned long flags; | ||
1259 | unsigned int mask = 0; | ||
1260 | |||
1261 | if (file->f_mode & FMODE_WRITE) { | ||
1262 | if (!s->dma_dac.ready) | ||
1263 | return 0; | ||
1264 | poll_wait(file, &s->dma_dac.wait, wait); | ||
1265 | } | ||
1266 | if (file->f_mode & FMODE_READ) { | ||
1267 | if (!s->dma_adc.ready) | ||
1268 | return 0; | ||
1269 | poll_wait(file, &s->dma_adc.wait, wait); | ||
1270 | } | ||
1271 | |||
1272 | spin_lock_irqsave(&s->lock, flags); | ||
1273 | |||
1274 | if (file->f_mode & FMODE_READ) { | ||
1275 | if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize) | ||
1276 | mask |= POLLIN | POLLRDNORM; | ||
1277 | } | ||
1278 | if (file->f_mode & FMODE_WRITE) { | ||
1279 | if (s->dma_dac.mapped) { | ||
1280 | if (s->dma_dac.count >= | ||
1281 | (signed)s->dma_dac.dma_fragsize) | ||
1282 | mask |= POLLOUT | POLLWRNORM; | ||
1283 | } else { | ||
1284 | if ((signed) s->dma_dac.dmasize >= | ||
1285 | s->dma_dac.count + (signed)s->dma_dac.dma_fragsize) | ||
1286 | mask |= POLLOUT | POLLWRNORM; | ||
1287 | } | ||
1288 | } | ||
1289 | spin_unlock_irqrestore(&s->lock, flags); | ||
1290 | return mask; | ||
1291 | } | ||
1292 | |||
1293 | static int au1000_mmap(struct file *file, struct vm_area_struct *vma) | ||
1294 | { | ||
1295 | struct au1000_state *s = (struct au1000_state *)file->private_data; | ||
1296 | struct dmabuf *db; | ||
1297 | unsigned long size; | ||
1298 | int ret = 0; | ||
1299 | |||
1300 | dbg("%s", __FUNCTION__); | ||
1301 | |||
1302 | lock_kernel(); | ||
1303 | mutex_lock(&s->sem); | ||
1304 | if (vma->vm_flags & VM_WRITE) | ||
1305 | db = &s->dma_dac; | ||
1306 | else if (vma->vm_flags & VM_READ) | ||
1307 | db = &s->dma_adc; | ||
1308 | else { | ||
1309 | ret = -EINVAL; | ||
1310 | goto out; | ||
1311 | } | ||
1312 | if (vma->vm_pgoff != 0) { | ||
1313 | ret = -EINVAL; | ||
1314 | goto out; | ||
1315 | } | ||
1316 | size = vma->vm_end - vma->vm_start; | ||
1317 | if (size > (PAGE_SIZE << db->buforder)) { | ||
1318 | ret = -EINVAL; | ||
1319 | goto out; | ||
1320 | } | ||
1321 | if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(db->rawbuf), | ||
1322 | size, vma->vm_page_prot)) { | ||
1323 | ret = -EAGAIN; | ||
1324 | goto out; | ||
1325 | } | ||
1326 | vma->vm_flags &= ~VM_IO; | ||
1327 | db->mapped = 1; | ||
1328 | out: | ||
1329 | mutex_unlock(&s->sem); | ||
1330 | unlock_kernel(); | ||
1331 | return ret; | ||
1332 | } | ||
1333 | |||
1334 | |||
1335 | #ifdef AU1000_VERBOSE_DEBUG | ||
1336 | static struct ioctl_str_t { | ||
1337 | unsigned int cmd; | ||
1338 | const char *str; | ||
1339 | } ioctl_str[] = { | ||
1340 | {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"}, | ||
1341 | {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"}, | ||
1342 | {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"}, | ||
1343 | {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"}, | ||
1344 | {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"}, | ||
1345 | {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"}, | ||
1346 | {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"}, | ||
1347 | {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"}, | ||
1348 | {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"}, | ||
1349 | {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"}, | ||
1350 | {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"}, | ||
1351 | {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"}, | ||
1352 | {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"}, | ||
1353 | {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"}, | ||
1354 | {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"}, | ||
1355 | {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"}, | ||
1356 | {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"}, | ||
1357 | {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"}, | ||
1358 | {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"}, | ||
1359 | {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"}, | ||
1360 | {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"}, | ||
1361 | {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"}, | ||
1362 | {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"}, | ||
1363 | {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"}, | ||
1364 | {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"}, | ||
1365 | {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"}, | ||
1366 | {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"}, | ||
1367 | {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"}, | ||
1368 | {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"}, | ||
1369 | {OSS_GETVERSION, "OSS_GETVERSION"}, | ||
1370 | {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"}, | ||
1371 | {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"}, | ||
1372 | {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"}, | ||
1373 | {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"} | ||
1374 | }; | ||
1375 | #endif | ||
1376 | |||
1377 | // Need to hold a spin-lock before calling this! | ||
1378 | static int dma_count_done(struct dmabuf *db) | ||
1379 | { | ||
1380 | if (db->stopped) | ||
1381 | return 0; | ||
1382 | |||
1383 | return db->dma_fragsize - get_dma_residue(db->dmanr); | ||
1384 | } | ||
1385 | |||
1386 | |||
1387 | static int au1000_ioctl(struct inode *inode, struct file *file, | ||
1388 | unsigned int cmd, unsigned long arg) | ||
1389 | { | ||
1390 | struct au1000_state *s = (struct au1000_state *)file->private_data; | ||
1391 | unsigned long flags; | ||
1392 | audio_buf_info abinfo; | ||
1393 | count_info cinfo; | ||
1394 | int count; | ||
1395 | int val, mapped, ret, diff; | ||
1396 | |||
1397 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || | ||
1398 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
1399 | |||
1400 | #ifdef AU1000_VERBOSE_DEBUG | ||
1401 | for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) { | ||
1402 | if (ioctl_str[count].cmd == cmd) | ||
1403 | break; | ||
1404 | } | ||
1405 | if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0])) | ||
1406 | dbg("ioctl %s, arg=0x%lx", ioctl_str[count].str, arg); | ||
1407 | else | ||
1408 | dbg("ioctl 0x%x unknown, arg=0x%lx", cmd, arg); | ||
1409 | #endif | ||
1410 | |||
1411 | switch (cmd) { | ||
1412 | case OSS_GETVERSION: | ||
1413 | return put_user(SOUND_VERSION, (int *) arg); | ||
1414 | |||
1415 | case SNDCTL_DSP_SYNC: | ||
1416 | if (file->f_mode & FMODE_WRITE) | ||
1417 | return drain_dac(s, file->f_flags & O_NONBLOCK); | ||
1418 | return 0; | ||
1419 | |||
1420 | case SNDCTL_DSP_SETDUPLEX: | ||
1421 | return 0; | ||
1422 | |||
1423 | case SNDCTL_DSP_GETCAPS: | ||
1424 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | | ||
1425 | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg); | ||
1426 | |||
1427 | case SNDCTL_DSP_RESET: | ||
1428 | if (file->f_mode & FMODE_WRITE) { | ||
1429 | stop_dac(s); | ||
1430 | synchronize_irq(); | ||
1431 | s->dma_dac.count = s->dma_dac.total_bytes = 0; | ||
1432 | s->dma_dac.nextIn = s->dma_dac.nextOut = | ||
1433 | s->dma_dac.rawbuf; | ||
1434 | } | ||
1435 | if (file->f_mode & FMODE_READ) { | ||
1436 | stop_adc(s); | ||
1437 | synchronize_irq(); | ||
1438 | s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
1439 | s->dma_adc.nextIn = s->dma_adc.nextOut = | ||
1440 | s->dma_adc.rawbuf; | ||
1441 | } | ||
1442 | return 0; | ||
1443 | |||
1444 | case SNDCTL_DSP_SPEED: | ||
1445 | if (get_user(val, (int *) arg)) | ||
1446 | return -EFAULT; | ||
1447 | if (val >= 0) { | ||
1448 | if (file->f_mode & FMODE_READ) { | ||
1449 | stop_adc(s); | ||
1450 | set_adc_rate(s, val); | ||
1451 | } | ||
1452 | if (file->f_mode & FMODE_WRITE) { | ||
1453 | stop_dac(s); | ||
1454 | set_dac_rate(s, val); | ||
1455 | } | ||
1456 | if (s->open_mode & FMODE_READ) | ||
1457 | if ((ret = prog_dmabuf_adc(s))) | ||
1458 | return ret; | ||
1459 | if (s->open_mode & FMODE_WRITE) | ||
1460 | if ((ret = prog_dmabuf_dac(s))) | ||
1461 | return ret; | ||
1462 | } | ||
1463 | return put_user((file->f_mode & FMODE_READ) ? | ||
1464 | s->dma_adc.sample_rate : | ||
1465 | s->dma_dac.sample_rate, | ||
1466 | (int *)arg); | ||
1467 | |||
1468 | case SNDCTL_DSP_STEREO: | ||
1469 | if (get_user(val, (int *) arg)) | ||
1470 | return -EFAULT; | ||
1471 | if (file->f_mode & FMODE_READ) { | ||
1472 | stop_adc(s); | ||
1473 | s->dma_adc.num_channels = val ? 2 : 1; | ||
1474 | if ((ret = prog_dmabuf_adc(s))) | ||
1475 | return ret; | ||
1476 | } | ||
1477 | if (file->f_mode & FMODE_WRITE) { | ||
1478 | stop_dac(s); | ||
1479 | s->dma_dac.num_channels = val ? 2 : 1; | ||
1480 | if (s->codec_ext_caps & AC97_EXT_DACS) { | ||
1481 | // disable surround and center/lfe in AC'97 | ||
1482 | u16 ext_stat = rdcodec(&s->codec, | ||
1483 | AC97_EXTENDED_STATUS); | ||
1484 | wrcodec(&s->codec, AC97_EXTENDED_STATUS, | ||
1485 | ext_stat | (AC97_EXTSTAT_PRI | | ||
1486 | AC97_EXTSTAT_PRJ | | ||
1487 | AC97_EXTSTAT_PRK)); | ||
1488 | } | ||
1489 | if ((ret = prog_dmabuf_dac(s))) | ||
1490 | return ret; | ||
1491 | } | ||
1492 | return 0; | ||
1493 | |||
1494 | case SNDCTL_DSP_CHANNELS: | ||
1495 | if (get_user(val, (int *) arg)) | ||
1496 | return -EFAULT; | ||
1497 | if (val != 0) { | ||
1498 | if (file->f_mode & FMODE_READ) { | ||
1499 | if (val < 0 || val > 2) | ||
1500 | return -EINVAL; | ||
1501 | stop_adc(s); | ||
1502 | s->dma_adc.num_channels = val; | ||
1503 | if ((ret = prog_dmabuf_adc(s))) | ||
1504 | return ret; | ||
1505 | } | ||
1506 | if (file->f_mode & FMODE_WRITE) { | ||
1507 | switch (val) { | ||
1508 | case 1: | ||
1509 | case 2: | ||
1510 | break; | ||
1511 | case 3: | ||
1512 | case 5: | ||
1513 | return -EINVAL; | ||
1514 | case 4: | ||
1515 | if (!(s->codec_ext_caps & | ||
1516 | AC97_EXTID_SDAC)) | ||
1517 | return -EINVAL; | ||
1518 | break; | ||
1519 | case 6: | ||
1520 | if ((s->codec_ext_caps & | ||
1521 | AC97_EXT_DACS) != AC97_EXT_DACS) | ||
1522 | return -EINVAL; | ||
1523 | break; | ||
1524 | default: | ||
1525 | return -EINVAL; | ||
1526 | } | ||
1527 | |||
1528 | stop_dac(s); | ||
1529 | if (val <= 2 && | ||
1530 | (s->codec_ext_caps & AC97_EXT_DACS)) { | ||
1531 | // disable surround and center/lfe | ||
1532 | // channels in AC'97 | ||
1533 | u16 ext_stat = | ||
1534 | rdcodec(&s->codec, | ||
1535 | AC97_EXTENDED_STATUS); | ||
1536 | wrcodec(&s->codec, | ||
1537 | AC97_EXTENDED_STATUS, | ||
1538 | ext_stat | (AC97_EXTSTAT_PRI | | ||
1539 | AC97_EXTSTAT_PRJ | | ||
1540 | AC97_EXTSTAT_PRK)); | ||
1541 | } else if (val >= 4) { | ||
1542 | // enable surround, center/lfe | ||
1543 | // channels in AC'97 | ||
1544 | u16 ext_stat = | ||
1545 | rdcodec(&s->codec, | ||
1546 | AC97_EXTENDED_STATUS); | ||
1547 | ext_stat &= ~AC97_EXTSTAT_PRJ; | ||
1548 | if (val == 6) | ||
1549 | ext_stat &= | ||
1550 | ~(AC97_EXTSTAT_PRI | | ||
1551 | AC97_EXTSTAT_PRK); | ||
1552 | wrcodec(&s->codec, | ||
1553 | AC97_EXTENDED_STATUS, | ||
1554 | ext_stat); | ||
1555 | } | ||
1556 | |||
1557 | s->dma_dac.num_channels = val; | ||
1558 | if ((ret = prog_dmabuf_dac(s))) | ||
1559 | return ret; | ||
1560 | } | ||
1561 | } | ||
1562 | return put_user(val, (int *) arg); | ||
1563 | |||
1564 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
1565 | return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg); | ||
1566 | |||
1567 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */ | ||
1568 | if (get_user(val, (int *) arg)) | ||
1569 | return -EFAULT; | ||
1570 | if (val != AFMT_QUERY) { | ||
1571 | if (file->f_mode & FMODE_READ) { | ||
1572 | stop_adc(s); | ||
1573 | if (val == AFMT_S16_LE) | ||
1574 | s->dma_adc.sample_size = 16; | ||
1575 | else { | ||
1576 | val = AFMT_U8; | ||
1577 | s->dma_adc.sample_size = 8; | ||
1578 | } | ||
1579 | if ((ret = prog_dmabuf_adc(s))) | ||
1580 | return ret; | ||
1581 | } | ||
1582 | if (file->f_mode & FMODE_WRITE) { | ||
1583 | stop_dac(s); | ||
1584 | if (val == AFMT_S16_LE) | ||
1585 | s->dma_dac.sample_size = 16; | ||
1586 | else { | ||
1587 | val = AFMT_U8; | ||
1588 | s->dma_dac.sample_size = 8; | ||
1589 | } | ||
1590 | if ((ret = prog_dmabuf_dac(s))) | ||
1591 | return ret; | ||
1592 | } | ||
1593 | } else { | ||
1594 | if (file->f_mode & FMODE_READ) | ||
1595 | val = (s->dma_adc.sample_size == 16) ? | ||
1596 | AFMT_S16_LE : AFMT_U8; | ||
1597 | else | ||
1598 | val = (s->dma_dac.sample_size == 16) ? | ||
1599 | AFMT_S16_LE : AFMT_U8; | ||
1600 | } | ||
1601 | return put_user(val, (int *) arg); | ||
1602 | |||
1603 | case SNDCTL_DSP_POST: | ||
1604 | return 0; | ||
1605 | |||
1606 | case SNDCTL_DSP_GETTRIGGER: | ||
1607 | val = 0; | ||
1608 | spin_lock_irqsave(&s->lock, flags); | ||
1609 | if (file->f_mode & FMODE_READ && !s->dma_adc.stopped) | ||
1610 | val |= PCM_ENABLE_INPUT; | ||
1611 | if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped) | ||
1612 | val |= PCM_ENABLE_OUTPUT; | ||
1613 | spin_unlock_irqrestore(&s->lock, flags); | ||
1614 | return put_user(val, (int *) arg); | ||
1615 | |||
1616 | case SNDCTL_DSP_SETTRIGGER: | ||
1617 | if (get_user(val, (int *) arg)) | ||
1618 | return -EFAULT; | ||
1619 | if (file->f_mode & FMODE_READ) { | ||
1620 | if (val & PCM_ENABLE_INPUT) | ||
1621 | start_adc(s); | ||
1622 | else | ||
1623 | stop_adc(s); | ||
1624 | } | ||
1625 | if (file->f_mode & FMODE_WRITE) { | ||
1626 | if (val & PCM_ENABLE_OUTPUT) | ||
1627 | start_dac(s); | ||
1628 | else | ||
1629 | stop_dac(s); | ||
1630 | } | ||
1631 | return 0; | ||
1632 | |||
1633 | case SNDCTL_DSP_GETOSPACE: | ||
1634 | if (!(file->f_mode & FMODE_WRITE)) | ||
1635 | return -EINVAL; | ||
1636 | abinfo.fragsize = s->dma_dac.fragsize; | ||
1637 | spin_lock_irqsave(&s->lock, flags); | ||
1638 | count = s->dma_dac.count; | ||
1639 | count -= dma_count_done(&s->dma_dac); | ||
1640 | spin_unlock_irqrestore(&s->lock, flags); | ||
1641 | if (count < 0) | ||
1642 | count = 0; | ||
1643 | abinfo.bytes = (s->dma_dac.dmasize - count) / | ||
1644 | s->dma_dac.cnt_factor; | ||
1645 | abinfo.fragstotal = s->dma_dac.numfrag; | ||
1646 | abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; | ||
1647 | #ifdef AU1000_VERBOSE_DEBUG | ||
1648 | dbg("bytes=%d, fragments=%d", abinfo.bytes, abinfo.fragments); | ||
1649 | #endif | ||
1650 | return copy_to_user((void *) arg, &abinfo, | ||
1651 | sizeof(abinfo)) ? -EFAULT : 0; | ||
1652 | |||
1653 | case SNDCTL_DSP_GETISPACE: | ||
1654 | if (!(file->f_mode & FMODE_READ)) | ||
1655 | return -EINVAL; | ||
1656 | abinfo.fragsize = s->dma_adc.fragsize; | ||
1657 | spin_lock_irqsave(&s->lock, flags); | ||
1658 | count = s->dma_adc.count; | ||
1659 | count += dma_count_done(&s->dma_adc); | ||
1660 | spin_unlock_irqrestore(&s->lock, flags); | ||
1661 | if (count < 0) | ||
1662 | count = 0; | ||
1663 | abinfo.bytes = count / s->dma_adc.cnt_factor; | ||
1664 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
1665 | abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; | ||
1666 | return copy_to_user((void *) arg, &abinfo, | ||
1667 | sizeof(abinfo)) ? -EFAULT : 0; | ||
1668 | |||
1669 | case SNDCTL_DSP_NONBLOCK: | ||
1670 | file->f_flags |= O_NONBLOCK; | ||
1671 | return 0; | ||
1672 | |||
1673 | case SNDCTL_DSP_GETODELAY: | ||
1674 | if (!(file->f_mode & FMODE_WRITE)) | ||
1675 | return -EINVAL; | ||
1676 | spin_lock_irqsave(&s->lock, flags); | ||
1677 | count = s->dma_dac.count; | ||
1678 | count -= dma_count_done(&s->dma_dac); | ||
1679 | spin_unlock_irqrestore(&s->lock, flags); | ||
1680 | if (count < 0) | ||
1681 | count = 0; | ||
1682 | count /= s->dma_dac.cnt_factor; | ||
1683 | return put_user(count, (int *) arg); | ||
1684 | |||
1685 | case SNDCTL_DSP_GETIPTR: | ||
1686 | if (!(file->f_mode & FMODE_READ)) | ||
1687 | return -EINVAL; | ||
1688 | spin_lock_irqsave(&s->lock, flags); | ||
1689 | cinfo.bytes = s->dma_adc.total_bytes; | ||
1690 | count = s->dma_adc.count; | ||
1691 | if (!s->dma_adc.stopped) { | ||
1692 | diff = dma_count_done(&s->dma_adc); | ||
1693 | count += diff; | ||
1694 | cinfo.bytes += diff; | ||
1695 | cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) + diff - | ||
1696 | s->dma_adc.dmaaddr; | ||
1697 | } else | ||
1698 | cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) - | ||
1699 | s->dma_adc.dmaaddr; | ||
1700 | if (s->dma_adc.mapped) | ||
1701 | s->dma_adc.count &= (s->dma_adc.dma_fragsize-1); | ||
1702 | spin_unlock_irqrestore(&s->lock, flags); | ||
1703 | if (count < 0) | ||
1704 | count = 0; | ||
1705 | cinfo.blocks = count >> s->dma_adc.fragshift; | ||
1706 | return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; | ||
1707 | |||
1708 | case SNDCTL_DSP_GETOPTR: | ||
1709 | if (!(file->f_mode & FMODE_READ)) | ||
1710 | return -EINVAL; | ||
1711 | spin_lock_irqsave(&s->lock, flags); | ||
1712 | cinfo.bytes = s->dma_dac.total_bytes; | ||
1713 | count = s->dma_dac.count; | ||
1714 | if (!s->dma_dac.stopped) { | ||
1715 | diff = dma_count_done(&s->dma_dac); | ||
1716 | count -= diff; | ||
1717 | cinfo.bytes += diff; | ||
1718 | cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff - | ||
1719 | s->dma_dac.dmaaddr; | ||
1720 | } else | ||
1721 | cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) - | ||
1722 | s->dma_dac.dmaaddr; | ||
1723 | if (s->dma_dac.mapped) | ||
1724 | s->dma_dac.count &= (s->dma_dac.dma_fragsize-1); | ||
1725 | spin_unlock_irqrestore(&s->lock, flags); | ||
1726 | if (count < 0) | ||
1727 | count = 0; | ||
1728 | cinfo.blocks = count >> s->dma_dac.fragshift; | ||
1729 | return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; | ||
1730 | |||
1731 | case SNDCTL_DSP_GETBLKSIZE: | ||
1732 | if (file->f_mode & FMODE_WRITE) | ||
1733 | return put_user(s->dma_dac.fragsize, (int *) arg); | ||
1734 | else | ||
1735 | return put_user(s->dma_adc.fragsize, (int *) arg); | ||
1736 | |||
1737 | case SNDCTL_DSP_SETFRAGMENT: | ||
1738 | if (get_user(val, (int *) arg)) | ||
1739 | return -EFAULT; | ||
1740 | if (file->f_mode & FMODE_READ) { | ||
1741 | stop_adc(s); | ||
1742 | s->dma_adc.ossfragshift = val & 0xffff; | ||
1743 | s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; | ||
1744 | if (s->dma_adc.ossfragshift < 4) | ||
1745 | s->dma_adc.ossfragshift = 4; | ||
1746 | if (s->dma_adc.ossfragshift > 15) | ||
1747 | s->dma_adc.ossfragshift = 15; | ||
1748 | if (s->dma_adc.ossmaxfrags < 4) | ||
1749 | s->dma_adc.ossmaxfrags = 4; | ||
1750 | if ((ret = prog_dmabuf_adc(s))) | ||
1751 | return ret; | ||
1752 | } | ||
1753 | if (file->f_mode & FMODE_WRITE) { | ||
1754 | stop_dac(s); | ||
1755 | s->dma_dac.ossfragshift = val & 0xffff; | ||
1756 | s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; | ||
1757 | if (s->dma_dac.ossfragshift < 4) | ||
1758 | s->dma_dac.ossfragshift = 4; | ||
1759 | if (s->dma_dac.ossfragshift > 15) | ||
1760 | s->dma_dac.ossfragshift = 15; | ||
1761 | if (s->dma_dac.ossmaxfrags < 4) | ||
1762 | s->dma_dac.ossmaxfrags = 4; | ||
1763 | if ((ret = prog_dmabuf_dac(s))) | ||
1764 | return ret; | ||
1765 | } | ||
1766 | return 0; | ||
1767 | |||
1768 | case SNDCTL_DSP_SUBDIVIDE: | ||
1769 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
1770 | (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) | ||
1771 | return -EINVAL; | ||
1772 | if (get_user(val, (int *) arg)) | ||
1773 | return -EFAULT; | ||
1774 | if (val != 1 && val != 2 && val != 4) | ||
1775 | return -EINVAL; | ||
1776 | if (file->f_mode & FMODE_READ) { | ||
1777 | stop_adc(s); | ||
1778 | s->dma_adc.subdivision = val; | ||
1779 | if ((ret = prog_dmabuf_adc(s))) | ||
1780 | return ret; | ||
1781 | } | ||
1782 | if (file->f_mode & FMODE_WRITE) { | ||
1783 | stop_dac(s); | ||
1784 | s->dma_dac.subdivision = val; | ||
1785 | if ((ret = prog_dmabuf_dac(s))) | ||
1786 | return ret; | ||
1787 | } | ||
1788 | return 0; | ||
1789 | |||
1790 | case SOUND_PCM_READ_RATE: | ||
1791 | return put_user((file->f_mode & FMODE_READ) ? | ||
1792 | s->dma_adc.sample_rate : | ||
1793 | s->dma_dac.sample_rate, | ||
1794 | (int *)arg); | ||
1795 | |||
1796 | case SOUND_PCM_READ_CHANNELS: | ||
1797 | if (file->f_mode & FMODE_READ) | ||
1798 | return put_user(s->dma_adc.num_channels, (int *)arg); | ||
1799 | else | ||
1800 | return put_user(s->dma_dac.num_channels, (int *)arg); | ||
1801 | |||
1802 | case SOUND_PCM_READ_BITS: | ||
1803 | if (file->f_mode & FMODE_READ) | ||
1804 | return put_user(s->dma_adc.sample_size, (int *)arg); | ||
1805 | else | ||
1806 | return put_user(s->dma_dac.sample_size, (int *)arg); | ||
1807 | |||
1808 | case SOUND_PCM_WRITE_FILTER: | ||
1809 | case SNDCTL_DSP_SETSYNCRO: | ||
1810 | case SOUND_PCM_READ_FILTER: | ||
1811 | return -EINVAL; | ||
1812 | } | ||
1813 | |||
1814 | return mixdev_ioctl(&s->codec, cmd, arg); | ||
1815 | } | ||
1816 | |||
1817 | |||
1818 | static int au1000_open(struct inode *inode, struct file *file) | ||
1819 | { | ||
1820 | int minor = iminor(inode); | ||
1821 | DECLARE_WAITQUEUE(wait, current); | ||
1822 | struct au1000_state *s = &au1000_state; | ||
1823 | int ret; | ||
1824 | |||
1825 | #ifdef AU1000_VERBOSE_DEBUG | ||
1826 | if (file->f_flags & O_NONBLOCK) | ||
1827 | dbg("%s: non-blocking", __FUNCTION__); | ||
1828 | else | ||
1829 | dbg("%s: blocking", __FUNCTION__); | ||
1830 | #endif | ||
1831 | |||
1832 | file->private_data = s; | ||
1833 | /* wait for device to become free */ | ||
1834 | mutex_lock(&s->open_mutex); | ||
1835 | while (s->open_mode & file->f_mode) { | ||
1836 | if (file->f_flags & O_NONBLOCK) { | ||
1837 | mutex_unlock(&s->open_mutex); | ||
1838 | return -EBUSY; | ||
1839 | } | ||
1840 | add_wait_queue(&s->open_wait, &wait); | ||
1841 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1842 | mutex_unlock(&s->open_mutex); | ||
1843 | schedule(); | ||
1844 | remove_wait_queue(&s->open_wait, &wait); | ||
1845 | set_current_state(TASK_RUNNING); | ||
1846 | if (signal_pending(current)) | ||
1847 | return -ERESTARTSYS; | ||
1848 | mutex_lock(&s->open_mutex); | ||
1849 | } | ||
1850 | |||
1851 | stop_dac(s); | ||
1852 | stop_adc(s); | ||
1853 | |||
1854 | if (file->f_mode & FMODE_READ) { | ||
1855 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = | ||
1856 | s->dma_adc.subdivision = s->dma_adc.total_bytes = 0; | ||
1857 | s->dma_adc.num_channels = 1; | ||
1858 | s->dma_adc.sample_size = 8; | ||
1859 | set_adc_rate(s, 8000); | ||
1860 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1861 | s->dma_adc.sample_size = 16; | ||
1862 | } | ||
1863 | |||
1864 | if (file->f_mode & FMODE_WRITE) { | ||
1865 | s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = | ||
1866 | s->dma_dac.subdivision = s->dma_dac.total_bytes = 0; | ||
1867 | s->dma_dac.num_channels = 1; | ||
1868 | s->dma_dac.sample_size = 8; | ||
1869 | set_dac_rate(s, 8000); | ||
1870 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1871 | s->dma_dac.sample_size = 16; | ||
1872 | } | ||
1873 | |||
1874 | if (file->f_mode & FMODE_READ) { | ||
1875 | if ((ret = prog_dmabuf_adc(s))) | ||
1876 | return ret; | ||
1877 | } | ||
1878 | if (file->f_mode & FMODE_WRITE) { | ||
1879 | if ((ret = prog_dmabuf_dac(s))) | ||
1880 | return ret; | ||
1881 | } | ||
1882 | |||
1883 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
1884 | mutex_unlock(&s->open_mutex); | ||
1885 | mutex_init(&s->sem); | ||
1886 | return nonseekable_open(inode, file); | ||
1887 | } | ||
1888 | |||
1889 | static int au1000_release(struct inode *inode, struct file *file) | ||
1890 | { | ||
1891 | struct au1000_state *s = (struct au1000_state *)file->private_data; | ||
1892 | |||
1893 | lock_kernel(); | ||
1894 | |||
1895 | if (file->f_mode & FMODE_WRITE) { | ||
1896 | unlock_kernel(); | ||
1897 | drain_dac(s, file->f_flags & O_NONBLOCK); | ||
1898 | lock_kernel(); | ||
1899 | } | ||
1900 | |||
1901 | mutex_lock(&s->open_mutex); | ||
1902 | if (file->f_mode & FMODE_WRITE) { | ||
1903 | stop_dac(s); | ||
1904 | dealloc_dmabuf(s, &s->dma_dac); | ||
1905 | } | ||
1906 | if (file->f_mode & FMODE_READ) { | ||
1907 | stop_adc(s); | ||
1908 | dealloc_dmabuf(s, &s->dma_adc); | ||
1909 | } | ||
1910 | s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE)); | ||
1911 | mutex_unlock(&s->open_mutex); | ||
1912 | wake_up(&s->open_wait); | ||
1913 | unlock_kernel(); | ||
1914 | return 0; | ||
1915 | } | ||
1916 | |||
1917 | static /*const */ struct file_operations au1000_audio_fops = { | ||
1918 | .owner = THIS_MODULE, | ||
1919 | .llseek = au1000_llseek, | ||
1920 | .read = au1000_read, | ||
1921 | .write = au1000_write, | ||
1922 | .poll = au1000_poll, | ||
1923 | .ioctl = au1000_ioctl, | ||
1924 | .mmap = au1000_mmap, | ||
1925 | .open = au1000_open, | ||
1926 | .release = au1000_release, | ||
1927 | }; | ||
1928 | |||
1929 | |||
1930 | /* --------------------------------------------------------------------- */ | ||
1931 | |||
1932 | |||
1933 | /* --------------------------------------------------------------------- */ | ||
1934 | |||
1935 | /* | ||
1936 | * for debugging purposes, we'll create a proc device that dumps the | ||
1937 | * CODEC chipstate | ||
1938 | */ | ||
1939 | |||
1940 | #ifdef AU1000_DEBUG | ||
1941 | static int proc_au1000_dump(char *buf, char **start, off_t fpos, | ||
1942 | int length, int *eof, void *data) | ||
1943 | { | ||
1944 | struct au1000_state *s = &au1000_state; | ||
1945 | int cnt, len = 0; | ||
1946 | |||
1947 | /* print out header */ | ||
1948 | len += sprintf(buf + len, "\n\t\tAU1000 Audio Debug\n\n"); | ||
1949 | |||
1950 | // print out digital controller state | ||
1951 | len += sprintf(buf + len, "AU1000 Audio Controller registers\n"); | ||
1952 | len += sprintf(buf + len, "---------------------------------\n"); | ||
1953 | len += sprintf (buf + len, "AC97C_CONFIG = %08x\n", | ||
1954 | au_readl(AC97C_CONFIG)); | ||
1955 | len += sprintf (buf + len, "AC97C_STATUS = %08x\n", | ||
1956 | au_readl(AC97C_STATUS)); | ||
1957 | len += sprintf (buf + len, "AC97C_CNTRL = %08x\n", | ||
1958 | au_readl(AC97C_CNTRL)); | ||
1959 | |||
1960 | /* print out CODEC state */ | ||
1961 | len += sprintf(buf + len, "\nAC97 CODEC registers\n"); | ||
1962 | len += sprintf(buf + len, "----------------------\n"); | ||
1963 | for (cnt = 0; cnt <= 0x7e; cnt += 2) | ||
1964 | len += sprintf(buf + len, "reg %02x = %04x\n", | ||
1965 | cnt, rdcodec(&s->codec, cnt)); | ||
1966 | |||
1967 | if (fpos >= len) { | ||
1968 | *start = buf; | ||
1969 | *eof = 1; | ||
1970 | return 0; | ||
1971 | } | ||
1972 | *start = buf + fpos; | ||
1973 | if ((len -= fpos) > length) | ||
1974 | return length; | ||
1975 | *eof = 1; | ||
1976 | return len; | ||
1977 | |||
1978 | } | ||
1979 | #endif /* AU1000_DEBUG */ | ||
1980 | |||
1981 | /* --------------------------------------------------------------------- */ | ||
1982 | |||
1983 | MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com"); | ||
1984 | MODULE_DESCRIPTION("Au1000 Audio Driver"); | ||
1985 | |||
1986 | /* --------------------------------------------------------------------- */ | ||
1987 | |||
1988 | static int __devinit au1000_probe(void) | ||
1989 | { | ||
1990 | struct au1000_state *s = &au1000_state; | ||
1991 | int val; | ||
1992 | #ifdef AU1000_DEBUG | ||
1993 | char proc_str[80]; | ||
1994 | #endif | ||
1995 | |||
1996 | memset(s, 0, sizeof(struct au1000_state)); | ||
1997 | |||
1998 | init_waitqueue_head(&s->dma_adc.wait); | ||
1999 | init_waitqueue_head(&s->dma_dac.wait); | ||
2000 | init_waitqueue_head(&s->open_wait); | ||
2001 | mutex_init(&s->open_mutex); | ||
2002 | spin_lock_init(&s->lock); | ||
2003 | s->codec.private_data = s; | ||
2004 | s->codec.id = 0; | ||
2005 | s->codec.codec_read = rdcodec; | ||
2006 | s->codec.codec_write = wrcodec; | ||
2007 | s->codec.codec_wait = waitcodec; | ||
2008 | |||
2009 | if (!request_mem_region(CPHYSADDR(AC97C_CONFIG), | ||
2010 | 0x14, AU1000_MODULE_NAME)) { | ||
2011 | err("AC'97 ports in use"); | ||
2012 | return -1; | ||
2013 | } | ||
2014 | // Allocate the DMA Channels | ||
2015 | if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX, | ||
2016 | "audio DAC", | ||
2017 | dac_dma_interrupt, | ||
2018 | IRQF_DISABLED, s)) < 0) { | ||
2019 | err("Can't get DAC DMA"); | ||
2020 | goto err_dma1; | ||
2021 | } | ||
2022 | if ((s->dma_adc.dmanr = request_au1000_dma(DMA_ID_AC97C_RX, | ||
2023 | "audio ADC", | ||
2024 | adc_dma_interrupt, | ||
2025 | IRQF_DISABLED, s)) < 0) { | ||
2026 | err("Can't get ADC DMA"); | ||
2027 | goto err_dma2; | ||
2028 | } | ||
2029 | |||
2030 | info("DAC: DMA%d/IRQ%d, ADC: DMA%d/IRQ%d", | ||
2031 | s->dma_dac.dmanr, get_dma_done_irq(s->dma_dac.dmanr), | ||
2032 | s->dma_adc.dmanr, get_dma_done_irq(s->dma_adc.dmanr)); | ||
2033 | |||
2034 | // enable DMA coherency in read/write DMA channels | ||
2035 | set_dma_mode(s->dma_dac.dmanr, | ||
2036 | get_dma_mode(s->dma_dac.dmanr) & ~DMA_NC); | ||
2037 | set_dma_mode(s->dma_adc.dmanr, | ||
2038 | get_dma_mode(s->dma_adc.dmanr) & ~DMA_NC); | ||
2039 | |||
2040 | /* register devices */ | ||
2041 | |||
2042 | if ((s->dev_audio = register_sound_dsp(&au1000_audio_fops, -1)) < 0) | ||
2043 | goto err_dev1; | ||
2044 | if ((s->codec.dev_mixer = | ||
2045 | register_sound_mixer(&au1000_mixer_fops, -1)) < 0) | ||
2046 | goto err_dev2; | ||
2047 | |||
2048 | #ifdef AU1000_DEBUG | ||
2049 | /* intialize the debug proc device */ | ||
2050 | s->ps = create_proc_read_entry(AU1000_MODULE_NAME, 0, NULL, | ||
2051 | proc_au1000_dump, NULL); | ||
2052 | #endif /* AU1000_DEBUG */ | ||
2053 | |||
2054 | // configure pins for AC'97 | ||
2055 | au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC); | ||
2056 | |||
2057 | // Assert reset for 10msec to the AC'97 controller, and enable clock | ||
2058 | au_writel(AC97C_RS | AC97C_CE, AC97C_CNTRL); | ||
2059 | au1000_delay(10); | ||
2060 | au_writel(AC97C_CE, AC97C_CNTRL); | ||
2061 | au1000_delay(10); // wait for clock to stabilize | ||
2062 | |||
2063 | /* cold reset the AC'97 */ | ||
2064 | au_writel(AC97C_RESET, AC97C_CONFIG); | ||
2065 | au1000_delay(10); | ||
2066 | au_writel(0, AC97C_CONFIG); | ||
2067 | /* need to delay around 500msec(bleech) to give | ||
2068 | some CODECs enough time to wakeup */ | ||
2069 | au1000_delay(500); | ||
2070 | |||
2071 | /* warm reset the AC'97 to start the bitclk */ | ||
2072 | au_writel(AC97C_SG | AC97C_SYNC, AC97C_CONFIG); | ||
2073 | udelay(100); | ||
2074 | au_writel(0, AC97C_CONFIG); | ||
2075 | |||
2076 | /* codec init */ | ||
2077 | if (!ac97_probe_codec(&s->codec)) | ||
2078 | goto err_dev3; | ||
2079 | |||
2080 | s->codec_base_caps = rdcodec(&s->codec, AC97_RESET); | ||
2081 | s->codec_ext_caps = rdcodec(&s->codec, AC97_EXTENDED_ID); | ||
2082 | info("AC'97 Base/Extended ID = %04x/%04x", | ||
2083 | s->codec_base_caps, s->codec_ext_caps); | ||
2084 | |||
2085 | /* | ||
2086 | * On the Pb1000, audio playback is on the AUX_OUT | ||
2087 | * channel (which defaults to LNLVL_OUT in AC'97 | ||
2088 | * rev 2.2) so make sure this channel is listed | ||
2089 | * as supported (soundcard.h calls this channel | ||
2090 | * ALTPCM). ac97_codec.c does not handle detection | ||
2091 | * of this channel correctly. | ||
2092 | */ | ||
2093 | s->codec.supported_mixers |= SOUND_MASK_ALTPCM; | ||
2094 | /* | ||
2095 | * Now set AUX_OUT's default volume. | ||
2096 | */ | ||
2097 | val = 0x4343; | ||
2098 | mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_ALTPCM, | ||
2099 | (unsigned long) &val); | ||
2100 | |||
2101 | if (!(s->codec_ext_caps & AC97_EXTID_VRA)) { | ||
2102 | // codec does not support VRA | ||
2103 | s->no_vra = 1; | ||
2104 | } else if (!vra) { | ||
2105 | // Boot option says disable VRA | ||
2106 | u16 ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS); | ||
2107 | wrcodec(&s->codec, AC97_EXTENDED_STATUS, | ||
2108 | ac97_extstat & ~AC97_EXTSTAT_VRA); | ||
2109 | s->no_vra = 1; | ||
2110 | } | ||
2111 | if (s->no_vra) | ||
2112 | info("no VRA, interpolating and decimating"); | ||
2113 | |||
2114 | /* set mic to be the recording source */ | ||
2115 | val = SOUND_MASK_MIC; | ||
2116 | mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, | ||
2117 | (unsigned long) &val); | ||
2118 | |||
2119 | #ifdef AU1000_DEBUG | ||
2120 | sprintf(proc_str, "driver/%s/%d/ac97", AU1000_MODULE_NAME, | ||
2121 | s->codec.id); | ||
2122 | s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL, | ||
2123 | ac97_read_proc, &s->codec); | ||
2124 | #endif | ||
2125 | |||
2126 | #ifdef CONFIG_MIPS_XXS1500 | ||
2127 | /* deassert eapd */ | ||
2128 | wrcodec(&s->codec, AC97_POWER_CONTROL, | ||
2129 | rdcodec(&s->codec, AC97_POWER_CONTROL) & ~0x8000); | ||
2130 | /* mute a number of signals which seem to be causing problems | ||
2131 | * if not muted. | ||
2132 | */ | ||
2133 | wrcodec(&s->codec, AC97_PCBEEP_VOL, 0x8000); | ||
2134 | wrcodec(&s->codec, AC97_PHONE_VOL, 0x8008); | ||
2135 | wrcodec(&s->codec, AC97_MIC_VOL, 0x8008); | ||
2136 | wrcodec(&s->codec, AC97_LINEIN_VOL, 0x8808); | ||
2137 | wrcodec(&s->codec, AC97_CD_VOL, 0x8808); | ||
2138 | wrcodec(&s->codec, AC97_VIDEO_VOL, 0x8808); | ||
2139 | wrcodec(&s->codec, AC97_AUX_VOL, 0x8808); | ||
2140 | wrcodec(&s->codec, AC97_PCMOUT_VOL, 0x0808); | ||
2141 | wrcodec(&s->codec, AC97_GENERAL_PURPOSE, 0x2000); | ||
2142 | #endif | ||
2143 | |||
2144 | return 0; | ||
2145 | |||
2146 | err_dev3: | ||
2147 | unregister_sound_mixer(s->codec.dev_mixer); | ||
2148 | err_dev2: | ||
2149 | unregister_sound_dsp(s->dev_audio); | ||
2150 | err_dev1: | ||
2151 | free_au1000_dma(s->dma_adc.dmanr); | ||
2152 | err_dma2: | ||
2153 | free_au1000_dma(s->dma_dac.dmanr); | ||
2154 | err_dma1: | ||
2155 | release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14); | ||
2156 | return -1; | ||
2157 | } | ||
2158 | |||
2159 | static void au1000_remove(void) | ||
2160 | { | ||
2161 | struct au1000_state *s = &au1000_state; | ||
2162 | |||
2163 | if (!s) | ||
2164 | return; | ||
2165 | #ifdef AU1000_DEBUG | ||
2166 | if (s->ps) | ||
2167 | remove_proc_entry(AU1000_MODULE_NAME, NULL); | ||
2168 | #endif /* AU1000_DEBUG */ | ||
2169 | synchronize_irq(); | ||
2170 | free_au1000_dma(s->dma_adc.dmanr); | ||
2171 | free_au1000_dma(s->dma_dac.dmanr); | ||
2172 | release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14); | ||
2173 | unregister_sound_dsp(s->dev_audio); | ||
2174 | unregister_sound_mixer(s->codec.dev_mixer); | ||
2175 | } | ||
2176 | |||
2177 | static int __init init_au1000(void) | ||
2178 | { | ||
2179 | info("stevel@mvista.com, built " __TIME__ " on " __DATE__); | ||
2180 | return au1000_probe(); | ||
2181 | } | ||
2182 | |||
2183 | static void __exit cleanup_au1000(void) | ||
2184 | { | ||
2185 | info("unloading"); | ||
2186 | au1000_remove(); | ||
2187 | } | ||
2188 | |||
2189 | module_init(init_au1000); | ||
2190 | module_exit(cleanup_au1000); | ||
2191 | |||
2192 | /* --------------------------------------------------------------------- */ | ||
2193 | |||
2194 | #ifndef MODULE | ||
2195 | |||
2196 | static int __init au1000_setup(char *options) | ||
2197 | { | ||
2198 | char *this_opt; | ||
2199 | |||
2200 | if (!options || !*options) | ||
2201 | return 0; | ||
2202 | |||
2203 | while ((this_opt = strsep(&options, ","))) { | ||
2204 | if (!*this_opt) | ||
2205 | continue; | ||
2206 | if (!strncmp(this_opt, "vra", 3)) { | ||
2207 | vra = 1; | ||
2208 | } | ||
2209 | } | ||
2210 | |||
2211 | return 1; | ||
2212 | } | ||
2213 | |||
2214 | __setup("au1000_audio=", au1000_setup); | ||
2215 | |||
2216 | #endif /* MODULE */ | ||
diff --git a/sound/oss/audio_syms.c b/sound/oss/audio_syms.c index 5da217fcbedd..3919e4d6b3f3 100644 --- a/sound/oss/audio_syms.c +++ b/sound/oss/audio_syms.c | |||
@@ -10,7 +10,5 @@ char audio_syms_symbol; | |||
10 | #include "sound_calls.h" | 10 | #include "sound_calls.h" |
11 | 11 | ||
12 | EXPORT_SYMBOL(DMAbuf_start_dma); | 12 | EXPORT_SYMBOL(DMAbuf_start_dma); |
13 | EXPORT_SYMBOL(DMAbuf_open_dma); | ||
14 | EXPORT_SYMBOL(DMAbuf_close_dma); | ||
15 | EXPORT_SYMBOL(DMAbuf_inputintr); | 13 | EXPORT_SYMBOL(DMAbuf_inputintr); |
16 | EXPORT_SYMBOL(DMAbuf_outputintr); | 14 | EXPORT_SYMBOL(DMAbuf_outputintr); |
diff --git a/sound/oss/awe_hw.h b/sound/oss/awe_hw.h deleted file mode 100644 index ab00c3c67e4e..000000000000 --- a/sound/oss/awe_hw.h +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/awe_hw.h | ||
3 | * | ||
4 | * Access routines and definitions for the low level driver for the | ||
5 | * Creative AWE32/SB32/AWE64 wave table synth. | ||
6 | * version 0.4.4; Jan. 4, 2000 | ||
7 | * | ||
8 | * Copyright (C) 1996-2000 Takashi Iwai | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #ifndef AWE_HW_H_DEF | ||
26 | #define AWE_HW_H_DEF | ||
27 | |||
28 | /* | ||
29 | * Emu-8000 control registers | ||
30 | * name(channel) reg, port | ||
31 | */ | ||
32 | |||
33 | #define awe_cmd_idx(reg,ch) (((reg)<< 5) | (ch)) | ||
34 | |||
35 | #define Data0 0 /* 0x620: doubleword r/w */ | ||
36 | #define Data1 1 /* 0xA20: doubleword r/w */ | ||
37 | #define Data2 2 /* 0xA22: word r/w */ | ||
38 | #define Data3 3 /* 0xE20: word r/w */ | ||
39 | #define Pointer 4 /* 0xE22 register pointer r/w */ | ||
40 | |||
41 | #define AWE_CPF(ch) awe_cmd_idx(0,ch), Data0 /* DW: current pitch and fractional address */ | ||
42 | #define AWE_PTRX(ch) awe_cmd_idx(1,ch), Data0 /* DW: pitch target and reverb send */ | ||
43 | #define AWE_CVCF(ch) awe_cmd_idx(2,ch), Data0 /* DW: current volume and filter cutoff */ | ||
44 | #define AWE_VTFT(ch) awe_cmd_idx(3,ch), Data0 /* DW: volume and filter cutoff targets */ | ||
45 | #define AWE_0080(ch) awe_cmd_idx(4,ch), Data0 /* DW: ?? */ | ||
46 | #define AWE_00A0(ch) awe_cmd_idx(5,ch), Data0 /* DW: ?? */ | ||
47 | #define AWE_PSST(ch) awe_cmd_idx(6,ch), Data0 /* DW: pan send and loop start address */ | ||
48 | #define AWE_CSL(ch) awe_cmd_idx(7,ch), Data0 /* DW: chorus send and loop end address */ | ||
49 | #define AWE_CCCA(ch) awe_cmd_idx(0,ch), Data1 /* DW: Q, control bits, and current address */ | ||
50 | #define AWE_HWCF4 awe_cmd_idx(1,9), Data1 /* DW: config dw 4 */ | ||
51 | #define AWE_HWCF5 awe_cmd_idx(1,10), Data1 /* DW: config dw 5 */ | ||
52 | #define AWE_HWCF6 awe_cmd_idx(1,13), Data1 /* DW: config dw 6 */ | ||
53 | #define AWE_HWCF7 awe_cmd_idx(1,14), Data1 /* DW: config dw 7? (not documented) */ | ||
54 | #define AWE_SMALR awe_cmd_idx(1,20), Data1 /* DW: sound memory address for left read */ | ||
55 | #define AWE_SMARR awe_cmd_idx(1,21), Data1 /* DW: for right read */ | ||
56 | #define AWE_SMALW awe_cmd_idx(1,22), Data1 /* DW: sound memory address for left write */ | ||
57 | #define AWE_SMARW awe_cmd_idx(1,23), Data1 /* DW: for right write */ | ||
58 | #define AWE_SMLD awe_cmd_idx(1,26), Data1 /* W: sound memory left data */ | ||
59 | #define AWE_SMRD awe_cmd_idx(1,26), Data2 /* W: right data */ | ||
60 | #define AWE_WC awe_cmd_idx(1,27), Data2 /* W: sample counter */ | ||
61 | #define AWE_WC_Cmd awe_cmd_idx(1,27) | ||
62 | #define AWE_WC_Port Data2 | ||
63 | #define AWE_HWCF1 awe_cmd_idx(1,29), Data1 /* W: config w 1 */ | ||
64 | #define AWE_HWCF2 awe_cmd_idx(1,30), Data1 /* W: config w 2 */ | ||
65 | #define AWE_HWCF3 awe_cmd_idx(1,31), Data1 /* W: config w 3 */ | ||
66 | #define AWE_INIT1(ch) awe_cmd_idx(2,ch), Data1 /* W: init array 1 */ | ||
67 | #define AWE_INIT2(ch) awe_cmd_idx(2,ch), Data2 /* W: init array 2 */ | ||
68 | #define AWE_INIT3(ch) awe_cmd_idx(3,ch), Data1 /* W: init array 3 */ | ||
69 | #define AWE_INIT4(ch) awe_cmd_idx(3,ch), Data2 /* W: init array 4 */ | ||
70 | #define AWE_ENVVOL(ch) awe_cmd_idx(4,ch), Data1 /* W: volume envelope delay */ | ||
71 | #define AWE_DCYSUSV(ch) awe_cmd_idx(5,ch), Data1 /* W: volume envelope sustain and decay */ | ||
72 | #define AWE_ENVVAL(ch) awe_cmd_idx(6,ch), Data1 /* W: modulation envelope delay */ | ||
73 | #define AWE_DCYSUS(ch) awe_cmd_idx(7,ch), Data1 /* W: modulation envelope sustain and decay */ | ||
74 | #define AWE_ATKHLDV(ch) awe_cmd_idx(4,ch), Data2 /* W: volume envelope attack and hold */ | ||
75 | #define AWE_LFO1VAL(ch) awe_cmd_idx(5,ch), Data2 /* W: LFO#1 Delay */ | ||
76 | #define AWE_ATKHLD(ch) awe_cmd_idx(6,ch), Data2 /* W: modulation envelope attack and hold */ | ||
77 | #define AWE_LFO2VAL(ch) awe_cmd_idx(7,ch), Data2 /* W: LFO#2 Delay */ | ||
78 | #define AWE_IP(ch) awe_cmd_idx(0,ch), Data3 /* W: initial pitch */ | ||
79 | #define AWE_IFATN(ch) awe_cmd_idx(1,ch), Data3 /* W: initial filter cutoff and attenuation */ | ||
80 | #define AWE_PEFE(ch) awe_cmd_idx(2,ch), Data3 /* W: pitch and filter envelope heights */ | ||
81 | #define AWE_FMMOD(ch) awe_cmd_idx(3,ch), Data3 /* W: vibrato and filter modulation freq */ | ||
82 | #define AWE_TREMFRQ(ch) awe_cmd_idx(4,ch), Data3 /* W: LFO#1 tremolo amount and freq */ | ||
83 | #define AWE_FM2FRQ2(ch) awe_cmd_idx(5,ch), Data3 /* W: LFO#2 vibrato amount and freq */ | ||
84 | |||
85 | /* used during detection (returns ROM version?; not documented in ADIP) */ | ||
86 | #define AWE_U1 0xE0, Data3 /* (R)(W) used in initialization */ | ||
87 | #define AWE_U2(ch) 0xC0+(ch), Data3 /* (W)(W) used in init envelope */ | ||
88 | |||
89 | |||
90 | #define AWE_MAX_VOICES 32 | ||
91 | #define AWE_NORMAL_VOICES 30 /*30&31 are reserved for DRAM refresh*/ | ||
92 | |||
93 | #define AWE_MAX_CHANNELS 32 /* max midi channels (must >= voices) */ | ||
94 | #define AWE_MAX_LAYERS AWE_MAX_VOICES /* maximum number of multiple layers */ | ||
95 | |||
96 | #define AWE_DRAM_OFFSET 0x200000 | ||
97 | #define AWE_MAX_DRAM_SIZE (28 * 1024) /* 28 MB is max onboard memory */ | ||
98 | |||
99 | #endif | ||
diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c deleted file mode 100644 index 01c592cee045..000000000000 --- a/sound/oss/awe_wave.c +++ /dev/null | |||
@@ -1,6149 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/awe_wave.c | ||
3 | * | ||
4 | * The low level driver for the AWE32/SB32/AWE64 wave table synth. | ||
5 | * version 0.4.4; Jan. 4, 2000 | ||
6 | * | ||
7 | * Copyright (C) 1996-2000 Takashi Iwai | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * Changelog: | ||
26 | * Aug 18, 2003, Adam Belay <ambx1@neo.rr.com> | ||
27 | * - detection code rewrite | ||
28 | */ | ||
29 | |||
30 | #include <linux/awe_voice.h> | ||
31 | #include <linux/config.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/pnp.h> | ||
36 | |||
37 | #include "sound_config.h" | ||
38 | |||
39 | #include "awe_wave.h" | ||
40 | #include "awe_hw.h" | ||
41 | |||
42 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
43 | #include "tuning.h" | ||
44 | #include <linux/ultrasound.h> | ||
45 | #endif | ||
46 | |||
47 | /* | ||
48 | * debug message | ||
49 | */ | ||
50 | |||
51 | #ifdef AWE_DEBUG_ON | ||
52 | #define DEBUG(LVL,XXX) {if (ctrls[AWE_MD_DEBUG_MODE] > LVL) { XXX; }} | ||
53 | #define ERRMSG(XXX) {if (ctrls[AWE_MD_DEBUG_MODE]) { XXX; }} | ||
54 | #define FATALERR(XXX) XXX | ||
55 | #else | ||
56 | #define DEBUG(LVL,XXX) /**/ | ||
57 | #define ERRMSG(XXX) XXX | ||
58 | #define FATALERR(XXX) XXX | ||
59 | #endif | ||
60 | |||
61 | /* | ||
62 | * bank and voice record | ||
63 | */ | ||
64 | |||
65 | typedef struct _sf_list sf_list; | ||
66 | typedef struct _awe_voice_list awe_voice_list; | ||
67 | typedef struct _awe_sample_list awe_sample_list; | ||
68 | |||
69 | /* soundfont record */ | ||
70 | struct _sf_list { | ||
71 | unsigned short sf_id; /* id number */ | ||
72 | unsigned short type; /* lock & shared flags */ | ||
73 | int num_info; /* current info table index */ | ||
74 | int num_sample; /* current sample table index */ | ||
75 | int mem_ptr; /* current word byte pointer */ | ||
76 | awe_voice_list *infos, *last_infos; /* instruments */ | ||
77 | awe_sample_list *samples, *last_samples; /* samples */ | ||
78 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
79 | sf_list *shared; /* shared list */ | ||
80 | unsigned char name[AWE_PATCH_NAME_LEN]; /* sharing id */ | ||
81 | #endif | ||
82 | sf_list *next, *prev; | ||
83 | }; | ||
84 | |||
85 | /* instrument list */ | ||
86 | struct _awe_voice_list { | ||
87 | awe_voice_info v; /* instrument information */ | ||
88 | sf_list *holder; /* parent sf_list of this record */ | ||
89 | unsigned char bank, instr; /* preset number information */ | ||
90 | char type, disabled; /* type=normal/mapped, disabled=boolean */ | ||
91 | awe_voice_list *next; /* linked list with same sf_id */ | ||
92 | awe_voice_list *next_instr; /* instrument list */ | ||
93 | awe_voice_list *next_bank; /* hash table list */ | ||
94 | }; | ||
95 | |||
96 | /* voice list type */ | ||
97 | #define V_ST_NORMAL 0 | ||
98 | #define V_ST_MAPPED 1 | ||
99 | |||
100 | /* sample list */ | ||
101 | struct _awe_sample_list { | ||
102 | awe_sample_info v; /* sample information */ | ||
103 | sf_list *holder; /* parent sf_list of this record */ | ||
104 | awe_sample_list *next; /* linked list with same sf_id */ | ||
105 | }; | ||
106 | |||
107 | /* sample and information table */ | ||
108 | static int current_sf_id; /* current number of fonts */ | ||
109 | static int locked_sf_id; /* locked position */ | ||
110 | static sf_list *sfhead, *sftail; /* linked-lists */ | ||
111 | |||
112 | #define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0) | ||
113 | #define awe_free_info() (sftail ? sftail->num_info : 0) | ||
114 | #define awe_free_sample() (sftail ? sftail->num_sample : 0) | ||
115 | |||
116 | #define AWE_MAX_PRESETS 256 | ||
117 | #define AWE_DEFAULT_PRESET 0 | ||
118 | #define AWE_DEFAULT_BANK 0 | ||
119 | #define AWE_DEFAULT_DRUM 0 | ||
120 | #define AWE_DRUM_BANK 128 | ||
121 | |||
122 | #define MAX_LAYERS AWE_MAX_VOICES | ||
123 | |||
124 | /* preset table index */ | ||
125 | static awe_voice_list *preset_table[AWE_MAX_PRESETS]; | ||
126 | |||
127 | /* | ||
128 | * voice table | ||
129 | */ | ||
130 | |||
131 | /* effects table */ | ||
132 | typedef struct FX_Rec { /* channel effects */ | ||
133 | unsigned char flags[AWE_FX_END]; | ||
134 | short val[AWE_FX_END]; | ||
135 | } FX_Rec; | ||
136 | |||
137 | |||
138 | /* channel parameters */ | ||
139 | typedef struct _awe_chan_info { | ||
140 | int channel; /* channel number */ | ||
141 | int bank; /* current tone bank */ | ||
142 | int instr; /* current program */ | ||
143 | int bender; /* midi pitchbend (-8192 - 8192) */ | ||
144 | int bender_range; /* midi bender range (x100) */ | ||
145 | int panning; /* panning (0-127) */ | ||
146 | int main_vol; /* channel volume (0-127) */ | ||
147 | int expression_vol; /* midi expression (0-127) */ | ||
148 | int chan_press; /* channel pressure */ | ||
149 | int sustained; /* sustain status in MIDI */ | ||
150 | FX_Rec fx; /* effects */ | ||
151 | FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */ | ||
152 | } awe_chan_info; | ||
153 | |||
154 | /* voice parameters */ | ||
155 | typedef struct _voice_info { | ||
156 | int state; | ||
157 | #define AWE_ST_OFF (1<<0) /* no sound */ | ||
158 | #define AWE_ST_ON (1<<1) /* playing */ | ||
159 | #define AWE_ST_STANDBY (1<<2) /* stand by for playing */ | ||
160 | #define AWE_ST_SUSTAINED (1<<3) /* sustained */ | ||
161 | #define AWE_ST_MARK (1<<4) /* marked for allocation */ | ||
162 | #define AWE_ST_DRAM (1<<5) /* DRAM read/write */ | ||
163 | #define AWE_ST_FM (1<<6) /* reserved for FM */ | ||
164 | #define AWE_ST_RELEASED (1<<7) /* released */ | ||
165 | |||
166 | int ch; /* midi channel */ | ||
167 | int key; /* internal key for search */ | ||
168 | int layer; /* layer number (for channel mode only) */ | ||
169 | int time; /* allocated time */ | ||
170 | awe_chan_info *cinfo; /* channel info */ | ||
171 | |||
172 | int note; /* midi key (0-127) */ | ||
173 | int velocity; /* midi velocity (0-127) */ | ||
174 | int sostenuto; /* sostenuto on/off */ | ||
175 | awe_voice_info *sample; /* assigned voice */ | ||
176 | |||
177 | /* EMU8000 parameters */ | ||
178 | int apitch; /* pitch parameter */ | ||
179 | int avol; /* volume parameter */ | ||
180 | int apan; /* panning parameter */ | ||
181 | int acutoff; /* cutoff parameter */ | ||
182 | short aaux; /* aux word */ | ||
183 | } voice_info; | ||
184 | |||
185 | /* voice information */ | ||
186 | static voice_info voices[AWE_MAX_VOICES]; | ||
187 | |||
188 | #define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED)) | ||
189 | #define IS_NO_EFFECT(v) (voices[v].state != AWE_ST_ON) | ||
190 | #define IS_PLAYING(v) (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED)) | ||
191 | #define IS_EMPTY(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM)) | ||
192 | |||
193 | |||
194 | /* MIDI channel effects information (for hw control) */ | ||
195 | static awe_chan_info channels[AWE_MAX_CHANNELS]; | ||
196 | |||
197 | |||
198 | /* | ||
199 | * global variables | ||
200 | */ | ||
201 | |||
202 | #ifndef AWE_DEFAULT_BASE_ADDR | ||
203 | #define AWE_DEFAULT_BASE_ADDR 0 /* autodetect */ | ||
204 | #endif | ||
205 | |||
206 | #ifndef AWE_DEFAULT_MEM_SIZE | ||
207 | #define AWE_DEFAULT_MEM_SIZE -1 /* autodetect */ | ||
208 | #endif | ||
209 | |||
210 | static int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */ | ||
211 | static int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */ | ||
212 | #ifdef CONFIG_PNP | ||
213 | static int isapnp = -1; | ||
214 | #else | ||
215 | static int isapnp; | ||
216 | #endif | ||
217 | |||
218 | MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>"); | ||
219 | MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver"); | ||
220 | MODULE_LICENSE("GPL"); | ||
221 | |||
222 | module_param(io, int, 0); | ||
223 | MODULE_PARM_DESC(io, "base i/o port of Emu8000"); | ||
224 | module_param(memsize, int, 0); | ||
225 | MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes"); | ||
226 | module_param(isapnp, bool, 0); | ||
227 | MODULE_PARM_DESC(isapnp, "use ISAPnP detection"); | ||
228 | |||
229 | /* DRAM start offset */ | ||
230 | static int awe_mem_start = AWE_DRAM_OFFSET; | ||
231 | |||
232 | /* maximum channels for playing */ | ||
233 | static int awe_max_voices = AWE_MAX_VOICES; | ||
234 | |||
235 | static int patch_opened; /* sample already loaded? */ | ||
236 | |||
237 | static char atten_relative = FALSE; | ||
238 | static short atten_offset; | ||
239 | |||
240 | static int awe_present = FALSE; /* awe device present? */ | ||
241 | static int awe_busy = FALSE; /* awe device opened? */ | ||
242 | |||
243 | static int my_dev = -1; | ||
244 | |||
245 | #define DEFAULT_DRUM_FLAGS ((1 << 9) | (1 << 25)) | ||
246 | #define IS_DRUM_CHANNEL(c) (drum_flags & (1 << (c))) | ||
247 | #define DRUM_CHANNEL_ON(c) (drum_flags |= (1 << (c))) | ||
248 | #define DRUM_CHANNEL_OFF(c) (drum_flags &= ~(1 << (c))) | ||
249 | static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */ | ||
250 | |||
251 | static int playing_mode = AWE_PLAY_INDIRECT; | ||
252 | #define SINGLE_LAYER_MODE() (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT) | ||
253 | #define MULTI_LAYER_MODE() (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2) | ||
254 | |||
255 | static int current_alloc_time; /* voice allocation index for channel mode */ | ||
256 | |||
257 | static struct synth_info awe_info = { | ||
258 | "AWE32 Synth", /* name */ | ||
259 | 0, /* device */ | ||
260 | SYNTH_TYPE_SAMPLE, /* synth_type */ | ||
261 | SAMPLE_TYPE_AWE32, /* synth_subtype */ | ||
262 | 0, /* perc_mode (obsolete) */ | ||
263 | AWE_MAX_VOICES, /* nr_voices */ | ||
264 | 0, /* nr_drums (obsolete) */ | ||
265 | 400 /* instr_bank_size */ | ||
266 | }; | ||
267 | |||
268 | |||
269 | static struct voice_alloc_info *voice_alloc; /* set at initialization */ | ||
270 | |||
271 | |||
272 | /* | ||
273 | * function prototypes | ||
274 | */ | ||
275 | |||
276 | static int awe_request_region(void); | ||
277 | static void awe_release_region(void); | ||
278 | |||
279 | static void awe_reset_samples(void); | ||
280 | /* emu8000 chip i/o access */ | ||
281 | static void setup_ports(int p1, int p2, int p3); | ||
282 | static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data); | ||
283 | static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data); | ||
284 | static unsigned short awe_peek(unsigned short cmd, unsigned short port); | ||
285 | static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port); | ||
286 | static void awe_wait(unsigned short delay); | ||
287 | |||
288 | /* initialize emu8000 chip */ | ||
289 | static void awe_initialize(void); | ||
290 | |||
291 | /* set voice parameters */ | ||
292 | static void awe_init_ctrl_parms(int init_all); | ||
293 | static void awe_init_voice_info(awe_voice_info *vp); | ||
294 | static void awe_init_voice_parm(awe_voice_parm *pp); | ||
295 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
296 | static int freq_to_note(int freq); | ||
297 | static int calc_rate_offset(int Hz); | ||
298 | /*static int calc_parm_delay(int msec);*/ | ||
299 | static int calc_parm_hold(int msec); | ||
300 | static int calc_parm_attack(int msec); | ||
301 | static int calc_parm_decay(int msec); | ||
302 | static int calc_parm_search(int msec, short *table); | ||
303 | #endif /* gus compat */ | ||
304 | |||
305 | /* turn on/off note */ | ||
306 | static void awe_note_on(int voice); | ||
307 | static void awe_note_off(int voice); | ||
308 | static void awe_terminate(int voice); | ||
309 | static void awe_exclusive_off(int voice); | ||
310 | static void awe_note_off_all(int do_sustain); | ||
311 | |||
312 | /* calculate voice parameters */ | ||
313 | typedef void (*fx_affect_func)(int voice, int forced); | ||
314 | static void awe_set_pitch(int voice, int forced); | ||
315 | static void awe_set_voice_pitch(int voice, int forced); | ||
316 | static void awe_set_volume(int voice, int forced); | ||
317 | static void awe_set_voice_vol(int voice, int forced); | ||
318 | static void awe_set_pan(int voice, int forced); | ||
319 | static void awe_fx_fmmod(int voice, int forced); | ||
320 | static void awe_fx_tremfrq(int voice, int forced); | ||
321 | static void awe_fx_fm2frq2(int voice, int forced); | ||
322 | static void awe_fx_filterQ(int voice, int forced); | ||
323 | static void awe_calc_pitch(int voice); | ||
324 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
325 | static void awe_calc_pitch_from_freq(int voice, int freq); | ||
326 | #endif | ||
327 | static void awe_calc_volume(int voice); | ||
328 | static void awe_update_volume(void); | ||
329 | static void awe_change_master_volume(short val); | ||
330 | static void awe_voice_init(int voice, int init_all); | ||
331 | static void awe_channel_init(int ch, int init_all); | ||
332 | static void awe_fx_init(int ch); | ||
333 | static void awe_send_effect(int voice, int layer, int type, int val); | ||
334 | static void awe_modwheel_change(int voice, int value); | ||
335 | |||
336 | /* sequencer interface */ | ||
337 | static int awe_open(int dev, int mode); | ||
338 | static void awe_close(int dev); | ||
339 | static int awe_ioctl(int dev, unsigned int cmd, void __user * arg); | ||
340 | static int awe_kill_note(int dev, int voice, int note, int velocity); | ||
341 | static int awe_start_note(int dev, int v, int note_num, int volume); | ||
342 | static int awe_set_instr(int dev, int voice, int instr_no); | ||
343 | static int awe_set_instr_2(int dev, int voice, int instr_no); | ||
344 | static void awe_reset(int dev); | ||
345 | static void awe_hw_control(int dev, unsigned char *event); | ||
346 | static int awe_load_patch(int dev, int format, const char __user *addr, | ||
347 | int offs, int count, int pmgr_flag); | ||
348 | static void awe_aftertouch(int dev, int voice, int pressure); | ||
349 | static void awe_controller(int dev, int voice, int ctrl_num, int value); | ||
350 | static void awe_panning(int dev, int voice, int value); | ||
351 | static void awe_volume_method(int dev, int mode); | ||
352 | static void awe_bender(int dev, int voice, int value); | ||
353 | static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc); | ||
354 | static void awe_setup_voice(int dev, int voice, int chn); | ||
355 | |||
356 | #define awe_key_pressure(dev,voice,key,press) awe_start_note(dev,voice,(key)+128,press) | ||
357 | |||
358 | /* hardware controls */ | ||
359 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
360 | static void awe_hw_gus_control(int dev, int cmd, unsigned char *event); | ||
361 | #endif | ||
362 | static void awe_hw_awe_control(int dev, int cmd, unsigned char *event); | ||
363 | static void awe_voice_change(int voice, fx_affect_func func); | ||
364 | static void awe_sostenuto_on(int voice, int forced); | ||
365 | static void awe_sustain_off(int voice, int forced); | ||
366 | static void awe_terminate_and_init(int voice, int forced); | ||
367 | |||
368 | /* voice search */ | ||
369 | static int awe_search_key(int bank, int preset, int note); | ||
370 | static awe_voice_list *awe_search_instr(int bank, int preset, int note); | ||
371 | static int awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, awe_voice_info **vlist); | ||
372 | static void awe_alloc_multi_voices(int ch, int note, int velocity, int key); | ||
373 | static void awe_alloc_one_voice(int voice, int note, int velocity); | ||
374 | static int awe_clear_voice(void); | ||
375 | |||
376 | /* load / remove patches */ | ||
377 | static int awe_open_patch(awe_patch_info *patch, const char __user *addr, int count); | ||
378 | static int awe_close_patch(awe_patch_info *patch, const char __user *addr, int count); | ||
379 | static int awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count); | ||
380 | static int awe_load_info(awe_patch_info *patch, const char __user *addr, int count); | ||
381 | static int awe_remove_info(awe_patch_info *patch, const char __user *addr, int count); | ||
382 | static int awe_load_data(awe_patch_info *patch, const char __user *addr, int count); | ||
383 | static int awe_replace_data(awe_patch_info *patch, const char __user *addr, int count); | ||
384 | static int awe_load_map(awe_patch_info *patch, const char __user *addr, int count); | ||
385 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
386 | static int awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag); | ||
387 | #endif | ||
388 | /*static int awe_probe_info(awe_patch_info *patch, const char __user *addr, int count);*/ | ||
389 | static int awe_probe_data(awe_patch_info *patch, const char __user *addr, int count); | ||
390 | static sf_list *check_patch_opened(int type, char *name); | ||
391 | static int awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *sp, int channels); | ||
392 | static int awe_create_sf(int type, char *name); | ||
393 | static void awe_free_sf(sf_list *sf); | ||
394 | static void add_sf_info(sf_list *sf, awe_voice_list *rec); | ||
395 | static void add_sf_sample(sf_list *sf, awe_sample_list *smp); | ||
396 | static void purge_old_list(awe_voice_list *rec, awe_voice_list *next); | ||
397 | static void add_info_list(awe_voice_list *rec); | ||
398 | static void awe_remove_samples(int sf_id); | ||
399 | static void rebuild_preset_list(void); | ||
400 | static short awe_set_sample(awe_voice_list *rec); | ||
401 | static awe_sample_list *search_sample_index(sf_list *sf, int sample); | ||
402 | |||
403 | static int is_identical_holder(sf_list *sf1, sf_list *sf2); | ||
404 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
405 | static int is_identical_name(unsigned char *name, sf_list *p); | ||
406 | static int is_shared_sf(unsigned char *name); | ||
407 | static int info_duplicated(sf_list *sf, awe_voice_list *rec); | ||
408 | #endif /* allow sharing */ | ||
409 | |||
410 | /* lowlevel functions */ | ||
411 | static void awe_init_audio(void); | ||
412 | static void awe_init_dma(void); | ||
413 | static void awe_init_array(void); | ||
414 | static void awe_send_array(unsigned short *data); | ||
415 | static void awe_tweak_voice(int voice); | ||
416 | static void awe_tweak(void); | ||
417 | static void awe_init_fm(void); | ||
418 | static int awe_open_dram_for_write(int offset, int channels); | ||
419 | static void awe_open_dram_for_check(void); | ||
420 | static void awe_close_dram(void); | ||
421 | /*static void awe_write_dram(unsigned short c);*/ | ||
422 | static int awe_detect_base(int addr); | ||
423 | static int awe_detect(void); | ||
424 | static void awe_check_dram(void); | ||
425 | static int awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count); | ||
426 | static void awe_set_chorus_mode(int mode); | ||
427 | static void awe_update_chorus_mode(void); | ||
428 | static int awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count); | ||
429 | static void awe_set_reverb_mode(int mode); | ||
430 | static void awe_update_reverb_mode(void); | ||
431 | static void awe_equalizer(int bass, int treble); | ||
432 | static void awe_update_equalizer(void); | ||
433 | |||
434 | #ifdef CONFIG_AWE32_MIXER | ||
435 | static void attach_mixer(void); | ||
436 | static void unload_mixer(void); | ||
437 | #endif | ||
438 | |||
439 | #ifdef CONFIG_AWE32_MIDIEMU | ||
440 | static void attach_midiemu(void); | ||
441 | static void unload_midiemu(void); | ||
442 | #endif | ||
443 | |||
444 | #define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b) | ||
445 | |||
446 | /* | ||
447 | * control parameters | ||
448 | */ | ||
449 | |||
450 | |||
451 | #ifdef AWE_USE_NEW_VOLUME_CALC | ||
452 | #define DEF_VOLUME_CALC TRUE | ||
453 | #else | ||
454 | #define DEF_VOLUME_CALC FALSE | ||
455 | #endif /* new volume */ | ||
456 | |||
457 | #define DEF_ZERO_ATTEN 32 /* 12dB below */ | ||
458 | #define DEF_MOD_SENSE 18 | ||
459 | #define DEF_CHORUS_MODE 2 | ||
460 | #define DEF_REVERB_MODE 4 | ||
461 | #define DEF_BASS_LEVEL 5 | ||
462 | #define DEF_TREBLE_LEVEL 9 | ||
463 | |||
464 | static struct CtrlParmsDef { | ||
465 | int value; | ||
466 | int init_each_time; | ||
467 | void (*update)(void); | ||
468 | } ctrl_parms[AWE_MD_END] = { | ||
469 | {0,0, NULL}, {0,0, NULL}, /* <-- not used */ | ||
470 | {AWE_VERSION_NUMBER, FALSE, NULL}, | ||
471 | {TRUE, FALSE, NULL}, /* exclusive */ | ||
472 | {TRUE, FALSE, NULL}, /* realpan */ | ||
473 | {AWE_DEFAULT_BANK, FALSE, NULL}, /* gusbank */ | ||
474 | {FALSE, TRUE, NULL}, /* keep effect */ | ||
475 | {DEF_ZERO_ATTEN, FALSE, awe_update_volume}, /* zero_atten */ | ||
476 | {FALSE, FALSE, NULL}, /* chn_prior */ | ||
477 | {DEF_MOD_SENSE, FALSE, NULL}, /* modwheel sense */ | ||
478 | {AWE_DEFAULT_PRESET, FALSE, NULL}, /* def_preset */ | ||
479 | {AWE_DEFAULT_BANK, FALSE, NULL}, /* def_bank */ | ||
480 | {AWE_DEFAULT_DRUM, FALSE, NULL}, /* def_drum */ | ||
481 | {FALSE, FALSE, NULL}, /* toggle_drum_bank */ | ||
482 | {DEF_VOLUME_CALC, FALSE, awe_update_volume}, /* new_volume_calc */ | ||
483 | {DEF_CHORUS_MODE, FALSE, awe_update_chorus_mode}, /* chorus mode */ | ||
484 | {DEF_REVERB_MODE, FALSE, awe_update_reverb_mode}, /* reverb mode */ | ||
485 | {DEF_BASS_LEVEL, FALSE, awe_update_equalizer}, /* bass level */ | ||
486 | {DEF_TREBLE_LEVEL, FALSE, awe_update_equalizer}, /* treble level */ | ||
487 | {0, FALSE, NULL}, /* debug mode */ | ||
488 | {FALSE, FALSE, NULL}, /* pan exchange */ | ||
489 | }; | ||
490 | |||
491 | static int ctrls[AWE_MD_END]; | ||
492 | |||
493 | |||
494 | /* | ||
495 | * synth operation table | ||
496 | */ | ||
497 | |||
498 | static struct synth_operations awe_operations = | ||
499 | { | ||
500 | .owner = THIS_MODULE, | ||
501 | .id = "EMU8K", | ||
502 | .info = &awe_info, | ||
503 | .midi_dev = 0, | ||
504 | .synth_type = SYNTH_TYPE_SAMPLE, | ||
505 | .synth_subtype = SAMPLE_TYPE_AWE32, | ||
506 | .open = awe_open, | ||
507 | .close = awe_close, | ||
508 | .ioctl = awe_ioctl, | ||
509 | .kill_note = awe_kill_note, | ||
510 | .start_note = awe_start_note, | ||
511 | .set_instr = awe_set_instr_2, | ||
512 | .reset = awe_reset, | ||
513 | .hw_control = awe_hw_control, | ||
514 | .load_patch = awe_load_patch, | ||
515 | .aftertouch = awe_aftertouch, | ||
516 | .controller = awe_controller, | ||
517 | .panning = awe_panning, | ||
518 | .volume_method = awe_volume_method, | ||
519 | .bender = awe_bender, | ||
520 | .alloc_voice = awe_alloc, | ||
521 | .setup_voice = awe_setup_voice | ||
522 | }; | ||
523 | |||
524 | static void free_tables(void) | ||
525 | { | ||
526 | if (sftail) { | ||
527 | sf_list *p, *prev; | ||
528 | for (p = sftail; p; p = prev) { | ||
529 | prev = p->prev; | ||
530 | awe_free_sf(p); | ||
531 | } | ||
532 | } | ||
533 | sfhead = sftail = NULL; | ||
534 | } | ||
535 | |||
536 | /* | ||
537 | * clear sample tables | ||
538 | */ | ||
539 | |||
540 | static void | ||
541 | awe_reset_samples(void) | ||
542 | { | ||
543 | /* free all bank tables */ | ||
544 | memset(preset_table, 0, sizeof(preset_table)); | ||
545 | free_tables(); | ||
546 | |||
547 | current_sf_id = 0; | ||
548 | locked_sf_id = 0; | ||
549 | patch_opened = 0; | ||
550 | } | ||
551 | |||
552 | |||
553 | /* | ||
554 | * EMU register access | ||
555 | */ | ||
556 | |||
557 | /* select a given AWE32 pointer */ | ||
558 | static int awe_ports[5]; | ||
559 | static int port_setuped = FALSE; | ||
560 | static int awe_cur_cmd = -1; | ||
561 | #define awe_set_cmd(cmd) \ | ||
562 | if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; } | ||
563 | |||
564 | /* write 16bit data */ | ||
565 | static void | ||
566 | awe_poke(unsigned short cmd, unsigned short port, unsigned short data) | ||
567 | { | ||
568 | awe_set_cmd(cmd); | ||
569 | outw(data, awe_ports[port]); | ||
570 | } | ||
571 | |||
572 | /* write 32bit data */ | ||
573 | static void | ||
574 | awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data) | ||
575 | { | ||
576 | unsigned short addr = awe_ports[port]; | ||
577 | awe_set_cmd(cmd); | ||
578 | outw(data, addr); /* write lower 16 bits */ | ||
579 | outw(data >> 16, addr + 2); /* write higher 16 bits */ | ||
580 | } | ||
581 | |||
582 | /* read 16bit data */ | ||
583 | static unsigned short | ||
584 | awe_peek(unsigned short cmd, unsigned short port) | ||
585 | { | ||
586 | unsigned short k; | ||
587 | awe_set_cmd(cmd); | ||
588 | k = inw(awe_ports[port]); | ||
589 | return k; | ||
590 | } | ||
591 | |||
592 | /* read 32bit data */ | ||
593 | static unsigned int | ||
594 | awe_peek_dw(unsigned short cmd, unsigned short port) | ||
595 | { | ||
596 | unsigned int k1, k2; | ||
597 | unsigned short addr = awe_ports[port]; | ||
598 | awe_set_cmd(cmd); | ||
599 | k1 = inw(addr); | ||
600 | k2 = inw(addr + 2); | ||
601 | k1 |= k2 << 16; | ||
602 | return k1; | ||
603 | } | ||
604 | |||
605 | /* wait delay number of AWE32 44100Hz clocks */ | ||
606 | #ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */ | ||
607 | static void | ||
608 | awe_wait(unsigned short delay) | ||
609 | { | ||
610 | unsigned short clock, target; | ||
611 | unsigned short port = awe_ports[AWE_WC_Port]; | ||
612 | int counter; | ||
613 | |||
614 | /* sample counter */ | ||
615 | awe_set_cmd(AWE_WC_Cmd); | ||
616 | clock = (unsigned short)inw(port); | ||
617 | target = clock + delay; | ||
618 | counter = 0; | ||
619 | if (target < clock) { | ||
620 | for (; (unsigned short)inw(port) > target; counter++) | ||
621 | if (counter > 65536) | ||
622 | break; | ||
623 | } | ||
624 | for (; (unsigned short)inw(port) < target; counter++) | ||
625 | if (counter > 65536) | ||
626 | break; | ||
627 | } | ||
628 | #else | ||
629 | |||
630 | static void awe_wait(unsigned short delay) | ||
631 | { | ||
632 | current->state = TASK_INTERRUPTIBLE; | ||
633 | schedule_timeout((HZ*(unsigned long)delay + 44099)/44100); | ||
634 | } | ||
635 | /* | ||
636 | static void awe_wait(unsigned short delay) | ||
637 | { | ||
638 | udelay(((unsigned long)delay * 1000000L + 44099) / 44100); | ||
639 | } | ||
640 | */ | ||
641 | #endif /* wait by loop */ | ||
642 | |||
643 | /* write a word data */ | ||
644 | #define awe_write_dram(c) awe_poke(AWE_SMLD, c) | ||
645 | |||
646 | /* | ||
647 | * AWE32 voice parameters | ||
648 | */ | ||
649 | |||
650 | /* initialize voice_info record */ | ||
651 | static void | ||
652 | awe_init_voice_info(awe_voice_info *vp) | ||
653 | { | ||
654 | vp->sample = 0; | ||
655 | vp->rate_offset = 0; | ||
656 | |||
657 | vp->start = 0; | ||
658 | vp->end = 0; | ||
659 | vp->loopstart = 0; | ||
660 | vp->loopend = 0; | ||
661 | vp->mode = 0; | ||
662 | vp->root = 60; | ||
663 | vp->tune = 0; | ||
664 | vp->low = 0; | ||
665 | vp->high = 127; | ||
666 | vp->vellow = 0; | ||
667 | vp->velhigh = 127; | ||
668 | |||
669 | vp->fixkey = -1; | ||
670 | vp->fixvel = -1; | ||
671 | vp->fixpan = -1; | ||
672 | vp->pan = -1; | ||
673 | |||
674 | vp->exclusiveClass = 0; | ||
675 | vp->amplitude = 127; | ||
676 | vp->attenuation = 0; | ||
677 | vp->scaleTuning = 100; | ||
678 | |||
679 | awe_init_voice_parm(&vp->parm); | ||
680 | } | ||
681 | |||
682 | /* initialize voice_parm record: | ||
683 | * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0. | ||
684 | * Vibrato and Tremolo effects are zero. | ||
685 | * Cutoff is maximum. | ||
686 | * Chorus and Reverb effects are zero. | ||
687 | */ | ||
688 | static void | ||
689 | awe_init_voice_parm(awe_voice_parm *pp) | ||
690 | { | ||
691 | pp->moddelay = 0x8000; | ||
692 | pp->modatkhld = 0x7f7f; | ||
693 | pp->moddcysus = 0x7f7f; | ||
694 | pp->modrelease = 0x807f; | ||
695 | pp->modkeyhold = 0; | ||
696 | pp->modkeydecay = 0; | ||
697 | |||
698 | pp->voldelay = 0x8000; | ||
699 | pp->volatkhld = 0x7f7f; | ||
700 | pp->voldcysus = 0x7f7f; | ||
701 | pp->volrelease = 0x807f; | ||
702 | pp->volkeyhold = 0; | ||
703 | pp->volkeydecay = 0; | ||
704 | |||
705 | pp->lfo1delay = 0x8000; | ||
706 | pp->lfo2delay = 0x8000; | ||
707 | pp->pefe = 0; | ||
708 | |||
709 | pp->fmmod = 0; | ||
710 | pp->tremfrq = 0; | ||
711 | pp->fm2frq2 = 0; | ||
712 | |||
713 | pp->cutoff = 0xff; | ||
714 | pp->filterQ = 0; | ||
715 | |||
716 | pp->chorus = 0; | ||
717 | pp->reverb = 0; | ||
718 | } | ||
719 | |||
720 | |||
721 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
722 | |||
723 | /* convert frequency mHz to abstract cents (= midi key * 100) */ | ||
724 | static int | ||
725 | freq_to_note(int mHz) | ||
726 | { | ||
727 | /* abscents = log(mHz/8176) / log(2) * 1200 */ | ||
728 | unsigned int max_val = (unsigned int)0xffffffff / 10000; | ||
729 | int i, times; | ||
730 | unsigned int base; | ||
731 | unsigned int freq; | ||
732 | int note, tune; | ||
733 | |||
734 | if (mHz == 0) | ||
735 | return 0; | ||
736 | if (mHz < 0) | ||
737 | return 12799; /* maximum */ | ||
738 | |||
739 | freq = mHz; | ||
740 | note = 0; | ||
741 | for (base = 8176 * 2; freq >= base; base *= 2) { | ||
742 | note += 12; | ||
743 | if (note >= 128) /* over maximum */ | ||
744 | return 12799; | ||
745 | } | ||
746 | base /= 2; | ||
747 | |||
748 | /* to avoid overflow... */ | ||
749 | times = 10000; | ||
750 | while (freq > max_val) { | ||
751 | max_val *= 10; | ||
752 | times /= 10; | ||
753 | base /= 10; | ||
754 | } | ||
755 | |||
756 | freq = freq * times / base; | ||
757 | for (i = 0; i < 12; i++) { | ||
758 | if (freq < semitone_tuning[i+1]) | ||
759 | break; | ||
760 | note++; | ||
761 | } | ||
762 | |||
763 | tune = 0; | ||
764 | freq = freq * 10000 / semitone_tuning[i]; | ||
765 | for (i = 0; i < 100; i++) { | ||
766 | if (freq < cent_tuning[i+1]) | ||
767 | break; | ||
768 | tune++; | ||
769 | } | ||
770 | |||
771 | return note * 100 + tune; | ||
772 | } | ||
773 | |||
774 | |||
775 | /* convert Hz to AWE32 rate offset: | ||
776 | * sample pitch offset for the specified sample rate | ||
777 | * rate=44100 is no offset, each 4096 is 1 octave (twice). | ||
778 | * eg, when rate is 22050, this offset becomes -4096. | ||
779 | */ | ||
780 | static int | ||
781 | calc_rate_offset(int Hz) | ||
782 | { | ||
783 | /* offset = log(Hz / 44100) / log(2) * 4096 */ | ||
784 | int freq, base, i; | ||
785 | |||
786 | /* maybe smaller than max (44100Hz) */ | ||
787 | if (Hz <= 0 || Hz >= 44100) return 0; | ||
788 | |||
789 | base = 0; | ||
790 | for (freq = Hz * 2; freq < 44100; freq *= 2) | ||
791 | base++; | ||
792 | base *= 1200; | ||
793 | |||
794 | freq = 44100 * 10000 / (freq/2); | ||
795 | for (i = 0; i < 12; i++) { | ||
796 | if (freq < semitone_tuning[i+1]) | ||
797 | break; | ||
798 | base += 100; | ||
799 | } | ||
800 | freq = freq * 10000 / semitone_tuning[i]; | ||
801 | for (i = 0; i < 100; i++) { | ||
802 | if (freq < cent_tuning[i+1]) | ||
803 | break; | ||
804 | base++; | ||
805 | } | ||
806 | return -base * 4096 / 1200; | ||
807 | } | ||
808 | |||
809 | |||
810 | /* | ||
811 | * convert envelope time parameter to AWE32 raw parameter | ||
812 | */ | ||
813 | |||
814 | /* attack & decay/release time table (msec) */ | ||
815 | static short attack_time_tbl[128] = { | ||
816 | 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816, | ||
817 | 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, | ||
818 | 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, | ||
819 | 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, | ||
820 | 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, | ||
821 | 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, | ||
822 | 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, | ||
823 | 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0, | ||
824 | }; | ||
825 | |||
826 | static short decay_time_tbl[128] = { | ||
827 | 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082, | ||
828 | 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507, | ||
829 | 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722, | ||
830 | 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361, | ||
831 | 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180, | ||
832 | 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90, | ||
833 | 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45, | ||
834 | 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22, | ||
835 | }; | ||
836 | |||
837 | #define calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725); | ||
838 | |||
839 | /* delay time = 0x8000 - msec/92 */ | ||
840 | static int | ||
841 | calc_parm_hold(int msec) | ||
842 | { | ||
843 | int val = (0x7f * 92 - msec) / 92; | ||
844 | if (val < 1) val = 1; | ||
845 | if (val > 127) val = 127; | ||
846 | return val; | ||
847 | } | ||
848 | |||
849 | /* attack time: search from time table */ | ||
850 | static int | ||
851 | calc_parm_attack(int msec) | ||
852 | { | ||
853 | return calc_parm_search(msec, attack_time_tbl); | ||
854 | } | ||
855 | |||
856 | /* decay/release time: search from time table */ | ||
857 | static int | ||
858 | calc_parm_decay(int msec) | ||
859 | { | ||
860 | return calc_parm_search(msec, decay_time_tbl); | ||
861 | } | ||
862 | |||
863 | /* search an index for specified time from given time table */ | ||
864 | static int | ||
865 | calc_parm_search(int msec, short *table) | ||
866 | { | ||
867 | int left = 1, right = 127, mid; | ||
868 | while (left < right) { | ||
869 | mid = (left + right) / 2; | ||
870 | if (msec < (int)table[mid]) | ||
871 | left = mid + 1; | ||
872 | else | ||
873 | right = mid; | ||
874 | } | ||
875 | return left; | ||
876 | } | ||
877 | #endif /* AWE_HAS_GUS_COMPATIBILITY */ | ||
878 | |||
879 | |||
880 | /* | ||
881 | * effects table | ||
882 | */ | ||
883 | |||
884 | /* set an effect value */ | ||
885 | #define FX_FLAG_OFF 0 | ||
886 | #define FX_FLAG_SET 1 | ||
887 | #define FX_FLAG_ADD 2 | ||
888 | |||
889 | #define FX_SET(rec,type,value) \ | ||
890 | ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value)) | ||
891 | #define FX_ADD(rec,type,value) \ | ||
892 | ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value)) | ||
893 | #define FX_UNSET(rec,type) \ | ||
894 | ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0) | ||
895 | |||
896 | /* check the effect value is set */ | ||
897 | #define FX_ON(rec,type) ((rec)->flags[type]) | ||
898 | |||
899 | #define PARM_BYTE 0 | ||
900 | #define PARM_WORD 1 | ||
901 | #define PARM_SIGN 2 | ||
902 | |||
903 | static struct PARM_DEFS { | ||
904 | int type; /* byte or word */ | ||
905 | int low, high; /* value range */ | ||
906 | fx_affect_func realtime; /* realtime paramater change */ | ||
907 | } parm_defs[] = { | ||
908 | {PARM_WORD, 0, 0x8000, NULL}, /* env1 delay */ | ||
909 | {PARM_BYTE, 1, 0x7f, NULL}, /* env1 attack */ | ||
910 | {PARM_BYTE, 0, 0x7e, NULL}, /* env1 hold */ | ||
911 | {PARM_BYTE, 1, 0x7f, NULL}, /* env1 decay */ | ||
912 | {PARM_BYTE, 1, 0x7f, NULL}, /* env1 release */ | ||
913 | {PARM_BYTE, 0, 0x7f, NULL}, /* env1 sustain */ | ||
914 | {PARM_BYTE, 0, 0xff, NULL}, /* env1 pitch */ | ||
915 | {PARM_BYTE, 0, 0xff, NULL}, /* env1 cutoff */ | ||
916 | |||
917 | {PARM_WORD, 0, 0x8000, NULL}, /* env2 delay */ | ||
918 | {PARM_BYTE, 1, 0x7f, NULL}, /* env2 attack */ | ||
919 | {PARM_BYTE, 0, 0x7e, NULL}, /* env2 hold */ | ||
920 | {PARM_BYTE, 1, 0x7f, NULL}, /* env2 decay */ | ||
921 | {PARM_BYTE, 1, 0x7f, NULL}, /* env2 release */ | ||
922 | {PARM_BYTE, 0, 0x7f, NULL}, /* env2 sustain */ | ||
923 | |||
924 | {PARM_WORD, 0, 0x8000, NULL}, /* lfo1 delay */ | ||
925 | {PARM_BYTE, 0, 0xff, awe_fx_tremfrq}, /* lfo1 freq */ | ||
926 | {PARM_SIGN, -128, 127, awe_fx_tremfrq}, /* lfo1 volume */ | ||
927 | {PARM_SIGN, -128, 127, awe_fx_fmmod}, /* lfo1 pitch */ | ||
928 | {PARM_BYTE, 0, 0xff, awe_fx_fmmod}, /* lfo1 cutoff */ | ||
929 | |||
930 | {PARM_WORD, 0, 0x8000, NULL}, /* lfo2 delay */ | ||
931 | {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2}, /* lfo2 freq */ | ||
932 | {PARM_SIGN, -128, 127, awe_fx_fm2frq2}, /* lfo2 pitch */ | ||
933 | |||
934 | {PARM_WORD, 0, 0xffff, awe_set_voice_pitch}, /* initial pitch */ | ||
935 | {PARM_BYTE, 0, 0xff, NULL}, /* chorus */ | ||
936 | {PARM_BYTE, 0, 0xff, NULL}, /* reverb */ | ||
937 | {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial cutoff */ | ||
938 | {PARM_BYTE, 0, 15, awe_fx_filterQ}, /* initial resonance */ | ||
939 | |||
940 | {PARM_WORD, 0, 0xffff, NULL}, /* sample start */ | ||
941 | {PARM_WORD, 0, 0xffff, NULL}, /* loop start */ | ||
942 | {PARM_WORD, 0, 0xffff, NULL}, /* loop end */ | ||
943 | {PARM_WORD, 0, 0xffff, NULL}, /* coarse sample start */ | ||
944 | {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop start */ | ||
945 | {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop end */ | ||
946 | {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial attenuation */ | ||
947 | }; | ||
948 | |||
949 | |||
950 | static unsigned char | ||
951 | FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value) | ||
952 | { | ||
953 | int effect = 0; | ||
954 | int on = 0; | ||
955 | if (lay && (on = FX_ON(lay, type)) != 0) | ||
956 | effect = lay->val[type]; | ||
957 | if (!on && (on = FX_ON(rec, type)) != 0) | ||
958 | effect = rec->val[type]; | ||
959 | if (on == FX_FLAG_ADD) { | ||
960 | if (parm_defs[type].type == PARM_SIGN) { | ||
961 | if (value > 0x7f) | ||
962 | effect += (int)value - 0x100; | ||
963 | else | ||
964 | effect += (int)value; | ||
965 | } else { | ||
966 | effect += (int)value; | ||
967 | } | ||
968 | } | ||
969 | if (on) { | ||
970 | if (effect < parm_defs[type].low) | ||
971 | effect = parm_defs[type].low; | ||
972 | else if (effect > parm_defs[type].high) | ||
973 | effect = parm_defs[type].high; | ||
974 | return (unsigned char)effect; | ||
975 | } | ||
976 | return value; | ||
977 | } | ||
978 | |||
979 | /* get word effect value */ | ||
980 | static unsigned short | ||
981 | FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value) | ||
982 | { | ||
983 | int effect = 0; | ||
984 | int on = 0; | ||
985 | if (lay && (on = FX_ON(lay, type)) != 0) | ||
986 | effect = lay->val[type]; | ||
987 | if (!on && (on = FX_ON(rec, type)) != 0) | ||
988 | effect = rec->val[type]; | ||
989 | if (on == FX_FLAG_ADD) | ||
990 | effect += (int)value; | ||
991 | if (on) { | ||
992 | if (effect < parm_defs[type].low) | ||
993 | effect = parm_defs[type].low; | ||
994 | else if (effect > parm_defs[type].high) | ||
995 | effect = parm_defs[type].high; | ||
996 | return (unsigned short)effect; | ||
997 | } | ||
998 | return value; | ||
999 | } | ||
1000 | |||
1001 | /* get word (upper=type1/lower=type2) effect value */ | ||
1002 | static unsigned short | ||
1003 | FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value) | ||
1004 | { | ||
1005 | unsigned short tmp; | ||
1006 | tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8)); | ||
1007 | tmp <<= 8; | ||
1008 | tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff)); | ||
1009 | return tmp; | ||
1010 | } | ||
1011 | |||
1012 | /* address offset */ | ||
1013 | static int | ||
1014 | FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode) | ||
1015 | { | ||
1016 | int addr = 0; | ||
1017 | if (lay && FX_ON(lay, hi)) | ||
1018 | addr = (short)lay->val[hi]; | ||
1019 | else if (FX_ON(rec, hi)) | ||
1020 | addr = (short)rec->val[hi]; | ||
1021 | addr = addr << 15; | ||
1022 | if (lay && FX_ON(lay, lo)) | ||
1023 | addr += (short)lay->val[lo]; | ||
1024 | else if (FX_ON(rec, lo)) | ||
1025 | addr += (short)rec->val[lo]; | ||
1026 | if (!(mode & AWE_SAMPLE_8BITS)) | ||
1027 | addr /= 2; | ||
1028 | return addr; | ||
1029 | } | ||
1030 | |||
1031 | |||
1032 | /* | ||
1033 | * turn on/off sample | ||
1034 | */ | ||
1035 | |||
1036 | /* table for volume target calculation */ | ||
1037 | static unsigned short voltarget[16] = { | ||
1038 | 0xEAC0, 0XE0C8, 0XD740, 0XCE20, 0XC560, 0XBD08, 0XB500, 0XAD58, | ||
1039 | 0XA5F8, 0X9EF0, 0X9830, 0X91C0, 0X8B90, 0X85A8, 0X8000, 0X7A90 | ||
1040 | }; | ||
1041 | |||
1042 | static void | ||
1043 | awe_note_on(int voice) | ||
1044 | { | ||
1045 | unsigned int temp; | ||
1046 | int addr; | ||
1047 | int vtarget, ftarget, ptarget, pitch; | ||
1048 | awe_voice_info *vp; | ||
1049 | awe_voice_parm_block *parm; | ||
1050 | FX_Rec *fx = &voices[voice].cinfo->fx; | ||
1051 | FX_Rec *fx_lay = NULL; | ||
1052 | if (voices[voice].layer < MAX_LAYERS) | ||
1053 | fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer]; | ||
1054 | |||
1055 | /* A voice sample must assigned before calling */ | ||
1056 | if ((vp = voices[voice].sample) == NULL || vp->index == 0) | ||
1057 | return; | ||
1058 | |||
1059 | parm = (awe_voice_parm_block*)&vp->parm; | ||
1060 | |||
1061 | /* channel to be silent and idle */ | ||
1062 | awe_poke(AWE_DCYSUSV(voice), 0x0080); | ||
1063 | awe_poke(AWE_VTFT(voice), 0x0000FFFF); | ||
1064 | awe_poke(AWE_CVCF(voice), 0x0000FFFF); | ||
1065 | awe_poke(AWE_PTRX(voice), 0); | ||
1066 | awe_poke(AWE_CPF(voice), 0); | ||
1067 | |||
1068 | /* set pitch offset */ | ||
1069 | awe_set_pitch(voice, TRUE); | ||
1070 | |||
1071 | /* modulation & volume envelope */ | ||
1072 | if (parm->modatk >= 0x80 && parm->moddelay >= 0x8000) { | ||
1073 | awe_poke(AWE_ENVVAL(voice), 0xBFFF); | ||
1074 | pitch = (parm->env1pit<<4) + voices[voice].apitch; | ||
1075 | if (pitch > 0xffff) pitch = 0xffff; | ||
1076 | /* calculate filter target */ | ||
1077 | ftarget = parm->cutoff + parm->env1fc; | ||
1078 | limitvalue(ftarget, 0, 255); | ||
1079 | ftarget <<= 8; | ||
1080 | } else { | ||
1081 | awe_poke(AWE_ENVVAL(voice), | ||
1082 | FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, parm->moddelay)); | ||
1083 | ftarget = parm->cutoff; | ||
1084 | ftarget <<= 8; | ||
1085 | pitch = voices[voice].apitch; | ||
1086 | } | ||
1087 | |||
1088 | /* calcualte pitch target */ | ||
1089 | if (pitch != 0xffff) { | ||
1090 | ptarget = 1 << (pitch >> 12); | ||
1091 | if (pitch & 0x800) ptarget += (ptarget*0x102e)/0x2710; | ||
1092 | if (pitch & 0x400) ptarget += (ptarget*0x764)/0x2710; | ||
1093 | if (pitch & 0x200) ptarget += (ptarget*0x389)/0x2710; | ||
1094 | ptarget += (ptarget>>1); | ||
1095 | if (ptarget > 0xffff) ptarget = 0xffff; | ||
1096 | |||
1097 | } else ptarget = 0xffff; | ||
1098 | if (parm->modatk >= 0x80) | ||
1099 | awe_poke(AWE_ATKHLD(voice), | ||
1100 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_HOLD, parm->modhld) << 8 | 0x7f); | ||
1101 | else | ||
1102 | awe_poke(AWE_ATKHLD(voice), | ||
1103 | FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK, | ||
1104 | vp->parm.modatkhld)); | ||
1105 | awe_poke(AWE_DCYSUS(voice), | ||
1106 | FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY, | ||
1107 | vp->parm.moddcysus)); | ||
1108 | |||
1109 | if (parm->volatk >= 0x80 && parm->voldelay >= 0x8000) { | ||
1110 | awe_poke(AWE_ENVVOL(voice), 0xBFFF); | ||
1111 | vtarget = voltarget[voices[voice].avol%0x10]>>(voices[voice].avol>>4); | ||
1112 | } else { | ||
1113 | awe_poke(AWE_ENVVOL(voice), | ||
1114 | FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay)); | ||
1115 | vtarget = 0; | ||
1116 | } | ||
1117 | if (parm->volatk >= 0x80) | ||
1118 | awe_poke(AWE_ATKHLDV(voice), | ||
1119 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_HOLD, parm->volhld) << 8 | 0x7f); | ||
1120 | else | ||
1121 | awe_poke(AWE_ATKHLDV(voice), | ||
1122 | FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK, | ||
1123 | vp->parm.volatkhld)); | ||
1124 | /* decay/sustain parameter for volume envelope must be set at last */ | ||
1125 | |||
1126 | /* cutoff and volume */ | ||
1127 | awe_set_volume(voice, TRUE); | ||
1128 | |||
1129 | /* modulation envelope heights */ | ||
1130 | awe_poke(AWE_PEFE(voice), | ||
1131 | FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF, | ||
1132 | vp->parm.pefe)); | ||
1133 | |||
1134 | /* lfo1/2 delay */ | ||
1135 | awe_poke(AWE_LFO1VAL(voice), | ||
1136 | FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay)); | ||
1137 | awe_poke(AWE_LFO2VAL(voice), | ||
1138 | FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay)); | ||
1139 | |||
1140 | /* lfo1 pitch & cutoff shift */ | ||
1141 | awe_fx_fmmod(voice, TRUE); | ||
1142 | /* lfo1 volume & freq */ | ||
1143 | awe_fx_tremfrq(voice, TRUE); | ||
1144 | /* lfo2 pitch & freq */ | ||
1145 | awe_fx_fm2frq2(voice, TRUE); | ||
1146 | /* pan & loop start */ | ||
1147 | awe_set_pan(voice, TRUE); | ||
1148 | |||
1149 | /* chorus & loop end (chorus 8bit, MSB) */ | ||
1150 | addr = vp->loopend - 1; | ||
1151 | addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END, | ||
1152 | AWE_FX_COARSE_LOOP_END, vp->mode); | ||
1153 | temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus); | ||
1154 | temp = (temp <<24) | (unsigned int)addr; | ||
1155 | awe_poke_dw(AWE_CSL(voice), temp); | ||
1156 | DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr)); | ||
1157 | |||
1158 | /* Q & current address (Q 4bit value, MSB) */ | ||
1159 | addr = vp->start - 1; | ||
1160 | addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START, | ||
1161 | AWE_FX_COARSE_SAMPLE_START, vp->mode); | ||
1162 | temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ); | ||
1163 | temp = (temp<<28) | (unsigned int)addr; | ||
1164 | awe_poke_dw(AWE_CCCA(voice), temp); | ||
1165 | DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr)); | ||
1166 | |||
1167 | /* clear unknown registers */ | ||
1168 | awe_poke_dw(AWE_00A0(voice), 0); | ||
1169 | awe_poke_dw(AWE_0080(voice), 0); | ||
1170 | |||
1171 | /* reset volume */ | ||
1172 | awe_poke_dw(AWE_VTFT(voice), (vtarget<<16)|ftarget); | ||
1173 | awe_poke_dw(AWE_CVCF(voice), (vtarget<<16)|ftarget); | ||
1174 | |||
1175 | /* set reverb */ | ||
1176 | temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb); | ||
1177 | temp = (temp << 8) | (ptarget << 16) | voices[voice].aaux; | ||
1178 | awe_poke_dw(AWE_PTRX(voice), temp); | ||
1179 | awe_poke_dw(AWE_CPF(voice), ptarget << 16); | ||
1180 | /* turn on envelope */ | ||
1181 | awe_poke(AWE_DCYSUSV(voice), | ||
1182 | FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY, | ||
1183 | vp->parm.voldcysus)); | ||
1184 | |||
1185 | voices[voice].state = AWE_ST_ON; | ||
1186 | |||
1187 | /* clear voice position for the next note on this channel */ | ||
1188 | if (SINGLE_LAYER_MODE()) { | ||
1189 | FX_UNSET(fx, AWE_FX_SAMPLE_START); | ||
1190 | FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START); | ||
1191 | } | ||
1192 | } | ||
1193 | |||
1194 | |||
1195 | /* turn off the voice */ | ||
1196 | static void | ||
1197 | awe_note_off(int voice) | ||
1198 | { | ||
1199 | awe_voice_info *vp; | ||
1200 | unsigned short tmp; | ||
1201 | FX_Rec *fx = &voices[voice].cinfo->fx; | ||
1202 | FX_Rec *fx_lay = NULL; | ||
1203 | if (voices[voice].layer < MAX_LAYERS) | ||
1204 | fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer]; | ||
1205 | |||
1206 | if ((vp = voices[voice].sample) == NULL) { | ||
1207 | voices[voice].state = AWE_ST_OFF; | ||
1208 | return; | ||
1209 | } | ||
1210 | |||
1211 | tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE, | ||
1212 | (unsigned char)vp->parm.modrelease); | ||
1213 | awe_poke(AWE_DCYSUS(voice), tmp); | ||
1214 | tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE, | ||
1215 | (unsigned char)vp->parm.volrelease); | ||
1216 | awe_poke(AWE_DCYSUSV(voice), tmp); | ||
1217 | voices[voice].state = AWE_ST_RELEASED; | ||
1218 | } | ||
1219 | |||
1220 | /* force to terminate the voice (no releasing echo) */ | ||
1221 | static void | ||
1222 | awe_terminate(int voice) | ||
1223 | { | ||
1224 | awe_poke(AWE_DCYSUSV(voice), 0x807F); | ||
1225 | awe_tweak_voice(voice); | ||
1226 | voices[voice].state = AWE_ST_OFF; | ||
1227 | } | ||
1228 | |||
1229 | /* turn off other voices with the same exclusive class (for drums) */ | ||
1230 | static void | ||
1231 | awe_exclusive_off(int voice) | ||
1232 | { | ||
1233 | int i, exclass; | ||
1234 | |||
1235 | if (voices[voice].sample == NULL) | ||
1236 | return; | ||
1237 | if ((exclass = voices[voice].sample->exclusiveClass) == 0) | ||
1238 | return; /* not exclusive */ | ||
1239 | |||
1240 | /* turn off voices with the same class */ | ||
1241 | for (i = 0; i < awe_max_voices; i++) { | ||
1242 | if (i != voice && IS_PLAYING(i) && | ||
1243 | voices[i].sample && voices[i].ch == voices[voice].ch && | ||
1244 | voices[i].sample->exclusiveClass == exclass) { | ||
1245 | DEBUG(4,printk("AWE32: [exoff(%d)]\n", i)); | ||
1246 | awe_terminate(i); | ||
1247 | awe_voice_init(i, TRUE); | ||
1248 | } | ||
1249 | } | ||
1250 | } | ||
1251 | |||
1252 | |||
1253 | /* | ||
1254 | * change the parameters of an audible voice | ||
1255 | */ | ||
1256 | |||
1257 | /* change pitch */ | ||
1258 | static void | ||
1259 | awe_set_pitch(int voice, int forced) | ||
1260 | { | ||
1261 | if (IS_NO_EFFECT(voice) && !forced) return; | ||
1262 | awe_poke(AWE_IP(voice), voices[voice].apitch); | ||
1263 | DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch)); | ||
1264 | } | ||
1265 | |||
1266 | /* calculate & change pitch */ | ||
1267 | static void | ||
1268 | awe_set_voice_pitch(int voice, int forced) | ||
1269 | { | ||
1270 | awe_calc_pitch(voice); | ||
1271 | awe_set_pitch(voice, forced); | ||
1272 | } | ||
1273 | |||
1274 | /* change volume & cutoff */ | ||
1275 | static void | ||
1276 | awe_set_volume(int voice, int forced) | ||
1277 | { | ||
1278 | awe_voice_info *vp; | ||
1279 | unsigned short tmp2; | ||
1280 | FX_Rec *fx = &voices[voice].cinfo->fx; | ||
1281 | FX_Rec *fx_lay = NULL; | ||
1282 | if (voices[voice].layer < MAX_LAYERS) | ||
1283 | fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer]; | ||
1284 | |||
1285 | if (!IS_PLAYING(voice) && !forced) return; | ||
1286 | if ((vp = voices[voice].sample) == NULL || vp->index == 0) | ||
1287 | return; | ||
1288 | |||
1289 | tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF, | ||
1290 | (unsigned char)voices[voice].acutoff); | ||
1291 | tmp2 = (tmp2 << 8); | ||
1292 | tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN, | ||
1293 | (unsigned char)voices[voice].avol); | ||
1294 | awe_poke(AWE_IFATN(voice), tmp2); | ||
1295 | } | ||
1296 | |||
1297 | /* calculate & change volume */ | ||
1298 | static void | ||
1299 | awe_set_voice_vol(int voice, int forced) | ||
1300 | { | ||
1301 | if (IS_EMPTY(voice)) | ||
1302 | return; | ||
1303 | awe_calc_volume(voice); | ||
1304 | awe_set_volume(voice, forced); | ||
1305 | } | ||
1306 | |||
1307 | |||
1308 | /* change pan; this could make a click noise.. */ | ||
1309 | static void | ||
1310 | awe_set_pan(int voice, int forced) | ||
1311 | { | ||
1312 | unsigned int temp; | ||
1313 | int addr; | ||
1314 | awe_voice_info *vp; | ||
1315 | FX_Rec *fx = &voices[voice].cinfo->fx; | ||
1316 | FX_Rec *fx_lay = NULL; | ||
1317 | if (voices[voice].layer < MAX_LAYERS) | ||
1318 | fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer]; | ||
1319 | |||
1320 | if (IS_NO_EFFECT(voice) && !forced) return; | ||
1321 | if ((vp = voices[voice].sample) == NULL || vp->index == 0) | ||
1322 | return; | ||
1323 | |||
1324 | /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */ | ||
1325 | if (vp->fixpan > 0) /* 0-127 */ | ||
1326 | temp = 255 - (int)vp->fixpan * 2; | ||
1327 | else { | ||
1328 | int pos = 0; | ||
1329 | if (vp->pan >= 0) /* 0-127 */ | ||
1330 | pos = (int)vp->pan * 2 - 128; | ||
1331 | pos += voices[voice].cinfo->panning; /* -128 - 127 */ | ||
1332 | temp = 127 - pos; | ||
1333 | } | ||
1334 | limitvalue(temp, 0, 255); | ||
1335 | if (ctrls[AWE_MD_PAN_EXCHANGE]) { | ||
1336 | temp = 255 - temp; | ||
1337 | } | ||
1338 | if (forced || temp != voices[voice].apan) { | ||
1339 | voices[voice].apan = temp; | ||
1340 | if (temp == 0) | ||
1341 | voices[voice].aaux = 0xff; | ||
1342 | else | ||
1343 | voices[voice].aaux = (-temp) & 0xff; | ||
1344 | addr = vp->loopstart - 1; | ||
1345 | addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START, | ||
1346 | AWE_FX_COARSE_LOOP_START, vp->mode); | ||
1347 | temp = (temp<<24) | (unsigned int)addr; | ||
1348 | awe_poke_dw(AWE_PSST(voice), temp); | ||
1349 | DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr)); | ||
1350 | } | ||
1351 | } | ||
1352 | |||
1353 | /* effects change during playing */ | ||
1354 | static void | ||
1355 | awe_fx_fmmod(int voice, int forced) | ||
1356 | { | ||
1357 | awe_voice_info *vp; | ||
1358 | FX_Rec *fx = &voices[voice].cinfo->fx; | ||
1359 | FX_Rec *fx_lay = NULL; | ||
1360 | if (voices[voice].layer < MAX_LAYERS) | ||
1361 | fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer]; | ||
1362 | |||
1363 | if (IS_NO_EFFECT(voice) && !forced) return; | ||
1364 | if ((vp = voices[voice].sample) == NULL || vp->index == 0) | ||
1365 | return; | ||
1366 | awe_poke(AWE_FMMOD(voice), | ||
1367 | FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF, | ||
1368 | vp->parm.fmmod)); | ||
1369 | } | ||
1370 | |||
1371 | /* set tremolo (lfo1) volume & frequency */ | ||
1372 | static void | ||
1373 | awe_fx_tremfrq(int voice, int forced) | ||
1374 | { | ||
1375 | awe_voice_info *vp; | ||
1376 | FX_Rec *fx = &voices[voice].cinfo->fx; | ||
1377 | FX_Rec *fx_lay = NULL; | ||
1378 | if (voices[voice].layer < MAX_LAYERS) | ||
1379 | fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer]; | ||
1380 | |||
1381 | if (IS_NO_EFFECT(voice) && !forced) return; | ||
1382 | if ((vp = voices[voice].sample) == NULL || vp->index == 0) | ||
1383 | return; | ||
1384 | awe_poke(AWE_TREMFRQ(voice), | ||
1385 | FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ, | ||
1386 | vp->parm.tremfrq)); | ||
1387 | } | ||
1388 | |||
1389 | /* set lfo2 pitch & frequency */ | ||
1390 | static void | ||
1391 | awe_fx_fm2frq2(int voice, int forced) | ||
1392 | { | ||
1393 | awe_voice_info *vp; | ||
1394 | FX_Rec *fx = &voices[voice].cinfo->fx; | ||
1395 | FX_Rec *fx_lay = NULL; | ||
1396 | if (voices[voice].layer < MAX_LAYERS) | ||
1397 | fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer]; | ||
1398 | |||
1399 | if (IS_NO_EFFECT(voice) && !forced) return; | ||
1400 | if ((vp = voices[voice].sample) == NULL || vp->index == 0) | ||
1401 | return; | ||
1402 | awe_poke(AWE_FM2FRQ2(voice), | ||
1403 | FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ, | ||
1404 | vp->parm.fm2frq2)); | ||
1405 | } | ||
1406 | |||
1407 | |||
1408 | /* Q & current address (Q 4bit value, MSB) */ | ||
1409 | static void | ||
1410 | awe_fx_filterQ(int voice, int forced) | ||
1411 | { | ||
1412 | unsigned int addr; | ||
1413 | awe_voice_info *vp; | ||
1414 | FX_Rec *fx = &voices[voice].cinfo->fx; | ||
1415 | FX_Rec *fx_lay = NULL; | ||
1416 | if (voices[voice].layer < MAX_LAYERS) | ||
1417 | fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer]; | ||
1418 | |||
1419 | if (IS_NO_EFFECT(voice) && !forced) return; | ||
1420 | if ((vp = voices[voice].sample) == NULL || vp->index == 0) | ||
1421 | return; | ||
1422 | |||
1423 | addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff; | ||
1424 | addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28); | ||
1425 | awe_poke_dw(AWE_CCCA(voice), addr); | ||
1426 | } | ||
1427 | |||
1428 | /* | ||
1429 | * calculate pitch offset | ||
1430 | * | ||
1431 | * 0xE000 is no pitch offset at 44100Hz sample. | ||
1432 | * Every 4096 is one octave. | ||
1433 | */ | ||
1434 | |||
1435 | static void | ||
1436 | awe_calc_pitch(int voice) | ||
1437 | { | ||
1438 | voice_info *vp = &voices[voice]; | ||
1439 | awe_voice_info *ap; | ||
1440 | awe_chan_info *cp = voices[voice].cinfo; | ||
1441 | int offset; | ||
1442 | |||
1443 | /* search voice information */ | ||
1444 | if ((ap = vp->sample) == NULL) | ||
1445 | return; | ||
1446 | if (ap->index == 0) { | ||
1447 | DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample)); | ||
1448 | if (awe_set_sample((awe_voice_list*)ap) == 0) | ||
1449 | return; | ||
1450 | } | ||
1451 | |||
1452 | /* calculate offset */ | ||
1453 | if (ap->fixkey >= 0) { | ||
1454 | DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune)); | ||
1455 | offset = (ap->fixkey - ap->root) * 4096 / 12; | ||
1456 | } else { | ||
1457 | DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune)); | ||
1458 | offset = (vp->note - ap->root) * 4096 / 12; | ||
1459 | DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset)); | ||
1460 | } | ||
1461 | offset = (offset * ap->scaleTuning) / 100; | ||
1462 | DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset)); | ||
1463 | offset += ap->tune * 4096 / 1200; | ||
1464 | DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset)); | ||
1465 | if (cp->bender != 0) { | ||
1466 | DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender)); | ||
1467 | /* (819200: 1 semitone) ==> (4096: 12 semitones) */ | ||
1468 | offset += cp->bender * cp->bender_range / 2400; | ||
1469 | } | ||
1470 | |||
1471 | /* add initial pitch correction */ | ||
1472 | if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH)) | ||
1473 | offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH]; | ||
1474 | else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH)) | ||
1475 | offset += cp->fx.val[AWE_FX_INIT_PITCH]; | ||
1476 | |||
1477 | /* 0xe000: root pitch */ | ||
1478 | vp->apitch = 0xe000 + ap->rate_offset + offset; | ||
1479 | DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset)); | ||
1480 | if (vp->apitch > 0xffff) | ||
1481 | vp->apitch = 0xffff; | ||
1482 | if (vp->apitch < 0) | ||
1483 | vp->apitch = 0; | ||
1484 | } | ||
1485 | |||
1486 | |||
1487 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
1488 | /* calculate MIDI key and semitone from the specified frequency */ | ||
1489 | static void | ||
1490 | awe_calc_pitch_from_freq(int voice, int freq) | ||
1491 | { | ||
1492 | voice_info *vp = &voices[voice]; | ||
1493 | awe_voice_info *ap; | ||
1494 | FX_Rec *fx = &voices[voice].cinfo->fx; | ||
1495 | FX_Rec *fx_lay = NULL; | ||
1496 | int offset; | ||
1497 | int note; | ||
1498 | |||
1499 | if (voices[voice].layer < MAX_LAYERS) | ||
1500 | fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer]; | ||
1501 | |||
1502 | /* search voice information */ | ||
1503 | if ((ap = vp->sample) == NULL) | ||
1504 | return; | ||
1505 | if (ap->index == 0) { | ||
1506 | DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample)); | ||
1507 | if (awe_set_sample((awe_voice_list*)ap) == 0) | ||
1508 | return; | ||
1509 | } | ||
1510 | note = freq_to_note(freq); | ||
1511 | offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200; | ||
1512 | offset = (offset * ap->scaleTuning) / 100; | ||
1513 | if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH)) | ||
1514 | offset += fx_lay->val[AWE_FX_INIT_PITCH]; | ||
1515 | else if (FX_ON(fx, AWE_FX_INIT_PITCH)) | ||
1516 | offset += fx->val[AWE_FX_INIT_PITCH]; | ||
1517 | vp->apitch = 0xe000 + ap->rate_offset + offset; | ||
1518 | if (vp->apitch > 0xffff) | ||
1519 | vp->apitch = 0xffff; | ||
1520 | if (vp->apitch < 0) | ||
1521 | vp->apitch = 0; | ||
1522 | } | ||
1523 | #endif /* AWE_HAS_GUS_COMPATIBILITY */ | ||
1524 | |||
1525 | |||
1526 | /* | ||
1527 | * calculate volume attenuation | ||
1528 | * | ||
1529 | * Voice volume is controlled by volume attenuation parameter. | ||
1530 | * So volume becomes maximum when avol is 0 (no attenuation), and | ||
1531 | * minimum when 255 (-96dB or silence). | ||
1532 | */ | ||
1533 | |||
1534 | static int vol_table[128] = { | ||
1535 | 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49, | ||
1536 | 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32, | ||
1537 | 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22, | ||
1538 | 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16, | ||
1539 | 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10, | ||
1540 | 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6, | ||
1541 | 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3, | ||
1542 | 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0, | ||
1543 | }; | ||
1544 | |||
1545 | /* tables for volume->attenuation calculation */ | ||
1546 | static unsigned char voltab1[128] = { | ||
1547 | 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, | ||
1548 | 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, | ||
1549 | 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, | ||
1550 | 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, | ||
1551 | 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, | ||
1552 | 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, | ||
1553 | 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, | ||
1554 | 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, | ||
1555 | 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, | ||
1556 | 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, | ||
1557 | 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, | ||
1558 | 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, | ||
1559 | 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
1560 | }; | ||
1561 | |||
1562 | static unsigned char voltab2[128] = { | ||
1563 | 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a, | ||
1564 | 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21, | ||
1565 | 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, | ||
1566 | 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15, | ||
1567 | 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, | ||
1568 | 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, | ||
1569 | 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, | ||
1570 | 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, | ||
1571 | 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, | ||
1572 | 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, | ||
1573 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, | ||
1574 | 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, | ||
1575 | 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
1576 | }; | ||
1577 | |||
1578 | static unsigned char expressiontab[128] = { | ||
1579 | 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42, | ||
1580 | 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30, | ||
1581 | 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25, | ||
1582 | 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e, | ||
1583 | 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18, | ||
1584 | 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13, | ||
1585 | 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f, | ||
1586 | 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, | ||
1587 | 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, | ||
1588 | 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, | ||
1589 | 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, | ||
1590 | 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, | ||
1591 | 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
1592 | }; | ||
1593 | |||
1594 | static void | ||
1595 | awe_calc_volume(int voice) | ||
1596 | { | ||
1597 | voice_info *vp = &voices[voice]; | ||
1598 | awe_voice_info *ap; | ||
1599 | awe_chan_info *cp = voices[voice].cinfo; | ||
1600 | int vol; | ||
1601 | |||
1602 | /* search voice information */ | ||
1603 | if ((ap = vp->sample) == NULL) | ||
1604 | return; | ||
1605 | |||
1606 | ap = vp->sample; | ||
1607 | if (ap->index == 0) { | ||
1608 | DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample)); | ||
1609 | if (awe_set_sample((awe_voice_list*)ap) == 0) | ||
1610 | return; | ||
1611 | } | ||
1612 | |||
1613 | if (ctrls[AWE_MD_NEW_VOLUME_CALC]) { | ||
1614 | int main_vol = cp->main_vol * ap->amplitude / 127; | ||
1615 | limitvalue(vp->velocity, 0, 127); | ||
1616 | limitvalue(main_vol, 0, 127); | ||
1617 | limitvalue(cp->expression_vol, 0, 127); | ||
1618 | |||
1619 | vol = voltab1[main_vol] + voltab2[vp->velocity]; | ||
1620 | vol = (vol * 8) / 3; | ||
1621 | vol += ap->attenuation; | ||
1622 | if (cp->expression_vol < 127) | ||
1623 | vol += ((0x100 - vol) * expressiontab[cp->expression_vol])/128; | ||
1624 | vol += atten_offset; | ||
1625 | if (atten_relative) | ||
1626 | vol += ctrls[AWE_MD_ZERO_ATTEN]; | ||
1627 | limitvalue(vol, 0, 255); | ||
1628 | vp->avol = vol; | ||
1629 | |||
1630 | } else { | ||
1631 | /* 0 - 127 */ | ||
1632 | vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127); | ||
1633 | vol = vol * ap->amplitude / 127; | ||
1634 | |||
1635 | if (vol < 0) vol = 0; | ||
1636 | if (vol > 127) vol = 127; | ||
1637 | |||
1638 | /* calc to attenuation */ | ||
1639 | vol = vol_table[vol]; | ||
1640 | vol += (int)ap->attenuation; | ||
1641 | vol += atten_offset; | ||
1642 | if (atten_relative) | ||
1643 | vol += ctrls[AWE_MD_ZERO_ATTEN]; | ||
1644 | if (vol > 255) vol = 255; | ||
1645 | |||
1646 | vp->avol = vol; | ||
1647 | } | ||
1648 | if (cp->bank != AWE_DRUM_BANK && ((awe_voice_parm_block*)(&ap->parm))->volatk < 0x7d) { | ||
1649 | int atten; | ||
1650 | if (vp->velocity < 70) atten = 70; | ||
1651 | else atten = vp->velocity; | ||
1652 | vp->acutoff = (atten * ap->parm.cutoff + 0xa0) >> 7; | ||
1653 | } else { | ||
1654 | vp->acutoff = ap->parm.cutoff; | ||
1655 | } | ||
1656 | DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol)); | ||
1657 | } | ||
1658 | |||
1659 | /* change master volume */ | ||
1660 | static void | ||
1661 | awe_change_master_volume(short val) | ||
1662 | { | ||
1663 | limitvalue(val, 0, 127); | ||
1664 | atten_offset = vol_table[val]; | ||
1665 | atten_relative = TRUE; | ||
1666 | awe_update_volume(); | ||
1667 | } | ||
1668 | |||
1669 | /* update volumes of all available channels */ | ||
1670 | static void awe_update_volume(void) | ||
1671 | { | ||
1672 | int i; | ||
1673 | for (i = 0; i < awe_max_voices; i++) | ||
1674 | awe_set_voice_vol(i, TRUE); | ||
1675 | } | ||
1676 | |||
1677 | /* set sostenuto on */ | ||
1678 | static void awe_sostenuto_on(int voice, int forced) | ||
1679 | { | ||
1680 | if (IS_NO_EFFECT(voice) && !forced) return; | ||
1681 | voices[voice].sostenuto = 127; | ||
1682 | } | ||
1683 | |||
1684 | |||
1685 | /* drop sustain */ | ||
1686 | static void awe_sustain_off(int voice, int forced) | ||
1687 | { | ||
1688 | if (voices[voice].state == AWE_ST_SUSTAINED) { | ||
1689 | awe_note_off(voice); | ||
1690 | awe_fx_init(voices[voice].ch); | ||
1691 | awe_voice_init(voice, FALSE); | ||
1692 | } | ||
1693 | } | ||
1694 | |||
1695 | |||
1696 | /* terminate and initialize voice */ | ||
1697 | static void awe_terminate_and_init(int voice, int forced) | ||
1698 | { | ||
1699 | awe_terminate(voice); | ||
1700 | awe_fx_init(voices[voice].ch); | ||
1701 | awe_voice_init(voice, TRUE); | ||
1702 | } | ||
1703 | |||
1704 | |||
1705 | /* | ||
1706 | * synth operation routines | ||
1707 | */ | ||
1708 | |||
1709 | #define AWE_VOICE_KEY(v) (0x8000 | (v)) | ||
1710 | #define AWE_CHAN_KEY(c,n) (((c) << 8) | ((n) + 1)) | ||
1711 | #define KEY_CHAN_MATCH(key,c) (((key) >> 8) == (c)) | ||
1712 | |||
1713 | /* initialize the voice */ | ||
1714 | static void | ||
1715 | awe_voice_init(int voice, int init_all) | ||
1716 | { | ||
1717 | voice_info *vp = &voices[voice]; | ||
1718 | |||
1719 | /* reset voice search key */ | ||
1720 | if (playing_mode == AWE_PLAY_DIRECT) | ||
1721 | vp->key = AWE_VOICE_KEY(voice); | ||
1722 | else | ||
1723 | vp->key = 0; | ||
1724 | |||
1725 | /* clear voice mapping */ | ||
1726 | voice_alloc->map[voice] = 0; | ||
1727 | |||
1728 | /* touch the timing flag */ | ||
1729 | vp->time = current_alloc_time; | ||
1730 | |||
1731 | /* initialize other parameters if necessary */ | ||
1732 | if (init_all) { | ||
1733 | vp->note = -1; | ||
1734 | vp->velocity = 0; | ||
1735 | vp->sostenuto = 0; | ||
1736 | |||
1737 | vp->sample = NULL; | ||
1738 | vp->cinfo = &channels[voice]; | ||
1739 | vp->ch = voice; | ||
1740 | vp->state = AWE_ST_OFF; | ||
1741 | |||
1742 | /* emu8000 parameters */ | ||
1743 | vp->apitch = 0; | ||
1744 | vp->avol = 255; | ||
1745 | vp->apan = -1; | ||
1746 | } | ||
1747 | } | ||
1748 | |||
1749 | /* clear effects */ | ||
1750 | static void awe_fx_init(int ch) | ||
1751 | { | ||
1752 | if (SINGLE_LAYER_MODE() && !ctrls[AWE_MD_KEEP_EFFECT]) { | ||
1753 | memset(&channels[ch].fx, 0, sizeof(channels[ch].fx)); | ||
1754 | memset(&channels[ch].fx_layer, 0, sizeof(&channels[ch].fx_layer)); | ||
1755 | } | ||
1756 | } | ||
1757 | |||
1758 | /* initialize channel info */ | ||
1759 | static void awe_channel_init(int ch, int init_all) | ||
1760 | { | ||
1761 | awe_chan_info *cp = &channels[ch]; | ||
1762 | cp->channel = ch; | ||
1763 | if (init_all) { | ||
1764 | cp->panning = 0; /* zero center */ | ||
1765 | cp->bender_range = 200; /* sense * 100 */ | ||
1766 | cp->main_vol = 127; | ||
1767 | if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) { | ||
1768 | cp->instr = ctrls[AWE_MD_DEF_DRUM]; | ||
1769 | cp->bank = AWE_DRUM_BANK; | ||
1770 | } else { | ||
1771 | cp->instr = ctrls[AWE_MD_DEF_PRESET]; | ||
1772 | cp->bank = ctrls[AWE_MD_DEF_BANK]; | ||
1773 | } | ||
1774 | } | ||
1775 | |||
1776 | cp->bender = 0; /* zero tune skew */ | ||
1777 | cp->expression_vol = 127; | ||
1778 | cp->chan_press = 0; | ||
1779 | cp->sustained = 0; | ||
1780 | |||
1781 | if (! ctrls[AWE_MD_KEEP_EFFECT]) { | ||
1782 | memset(&cp->fx, 0, sizeof(cp->fx)); | ||
1783 | memset(&cp->fx_layer, 0, sizeof(cp->fx_layer)); | ||
1784 | } | ||
1785 | } | ||
1786 | |||
1787 | |||
1788 | /* change the voice parameters; voice = channel */ | ||
1789 | static void awe_voice_change(int voice, fx_affect_func func) | ||
1790 | { | ||
1791 | int i; | ||
1792 | switch (playing_mode) { | ||
1793 | case AWE_PLAY_DIRECT: | ||
1794 | func(voice, FALSE); | ||
1795 | break; | ||
1796 | case AWE_PLAY_INDIRECT: | ||
1797 | for (i = 0; i < awe_max_voices; i++) | ||
1798 | if (voices[i].key == AWE_VOICE_KEY(voice)) | ||
1799 | func(i, FALSE); | ||
1800 | break; | ||
1801 | default: | ||
1802 | for (i = 0; i < awe_max_voices; i++) | ||
1803 | if (KEY_CHAN_MATCH(voices[i].key, voice)) | ||
1804 | func(i, FALSE); | ||
1805 | break; | ||
1806 | } | ||
1807 | } | ||
1808 | |||
1809 | |||
1810 | /* | ||
1811 | * device open / close | ||
1812 | */ | ||
1813 | |||
1814 | /* open device: | ||
1815 | * reset status of all voices, and clear sample position flag | ||
1816 | */ | ||
1817 | static int | ||
1818 | awe_open(int dev, int mode) | ||
1819 | { | ||
1820 | if (awe_busy) | ||
1821 | return -EBUSY; | ||
1822 | |||
1823 | awe_busy = TRUE; | ||
1824 | |||
1825 | /* set default mode */ | ||
1826 | awe_init_ctrl_parms(FALSE); | ||
1827 | atten_relative = TRUE; | ||
1828 | atten_offset = 0; | ||
1829 | drum_flags = DEFAULT_DRUM_FLAGS; | ||
1830 | playing_mode = AWE_PLAY_INDIRECT; | ||
1831 | |||
1832 | /* reset voices & channels */ | ||
1833 | awe_reset(dev); | ||
1834 | |||
1835 | patch_opened = 0; | ||
1836 | |||
1837 | return 0; | ||
1838 | } | ||
1839 | |||
1840 | |||
1841 | /* close device: | ||
1842 | * reset all voices again (terminate sounds) | ||
1843 | */ | ||
1844 | static void | ||
1845 | awe_close(int dev) | ||
1846 | { | ||
1847 | awe_reset(dev); | ||
1848 | awe_busy = FALSE; | ||
1849 | } | ||
1850 | |||
1851 | |||
1852 | /* set miscellaneous mode parameters | ||
1853 | */ | ||
1854 | static void | ||
1855 | awe_init_ctrl_parms(int init_all) | ||
1856 | { | ||
1857 | int i; | ||
1858 | for (i = 0; i < AWE_MD_END; i++) { | ||
1859 | if (init_all || ctrl_parms[i].init_each_time) | ||
1860 | ctrls[i] = ctrl_parms[i].value; | ||
1861 | } | ||
1862 | } | ||
1863 | |||
1864 | |||
1865 | /* sequencer I/O control: | ||
1866 | */ | ||
1867 | static int | ||
1868 | awe_ioctl(int dev, unsigned int cmd, void __user *arg) | ||
1869 | { | ||
1870 | switch (cmd) { | ||
1871 | case SNDCTL_SYNTH_INFO: | ||
1872 | if (playing_mode == AWE_PLAY_DIRECT) | ||
1873 | awe_info.nr_voices = awe_max_voices; | ||
1874 | else | ||
1875 | awe_info.nr_voices = AWE_MAX_CHANNELS; | ||
1876 | if (copy_to_user(arg, &awe_info, sizeof(awe_info))) | ||
1877 | return -EFAULT; | ||
1878 | return 0; | ||
1879 | break; | ||
1880 | |||
1881 | case SNDCTL_SEQ_RESETSAMPLES: | ||
1882 | awe_reset(dev); | ||
1883 | awe_reset_samples(); | ||
1884 | return 0; | ||
1885 | break; | ||
1886 | |||
1887 | case SNDCTL_SEQ_PERCMODE: | ||
1888 | /* what's this? */ | ||
1889 | return 0; | ||
1890 | break; | ||
1891 | |||
1892 | case SNDCTL_SYNTH_MEMAVL: | ||
1893 | return memsize - awe_free_mem_ptr() * 2; | ||
1894 | break; | ||
1895 | |||
1896 | default: | ||
1897 | printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd); | ||
1898 | return -EINVAL; | ||
1899 | break; | ||
1900 | } | ||
1901 | } | ||
1902 | |||
1903 | |||
1904 | static int voice_in_range(int voice) | ||
1905 | { | ||
1906 | if (playing_mode == AWE_PLAY_DIRECT) { | ||
1907 | if (voice < 0 || voice >= awe_max_voices) | ||
1908 | return FALSE; | ||
1909 | } else { | ||
1910 | if (voice < 0 || voice >= AWE_MAX_CHANNELS) | ||
1911 | return FALSE; | ||
1912 | } | ||
1913 | return TRUE; | ||
1914 | } | ||
1915 | |||
1916 | static void release_voice(int voice, int do_sustain) | ||
1917 | { | ||
1918 | if (IS_NO_SOUND(voice)) | ||
1919 | return; | ||
1920 | if (do_sustain && (voices[voice].cinfo->sustained == 127 || | ||
1921 | voices[voice].sostenuto == 127)) | ||
1922 | voices[voice].state = AWE_ST_SUSTAINED; | ||
1923 | else { | ||
1924 | awe_note_off(voice); | ||
1925 | awe_fx_init(voices[voice].ch); | ||
1926 | awe_voice_init(voice, FALSE); | ||
1927 | } | ||
1928 | } | ||
1929 | |||
1930 | /* release all notes */ | ||
1931 | static void awe_note_off_all(int do_sustain) | ||
1932 | { | ||
1933 | int i; | ||
1934 | for (i = 0; i < awe_max_voices; i++) | ||
1935 | release_voice(i, do_sustain); | ||
1936 | } | ||
1937 | |||
1938 | /* kill a voice: | ||
1939 | * not terminate, just release the voice. | ||
1940 | */ | ||
1941 | static int | ||
1942 | awe_kill_note(int dev, int voice, int note, int velocity) | ||
1943 | { | ||
1944 | int i, v2, key; | ||
1945 | |||
1946 | DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity)); | ||
1947 | if (! voice_in_range(voice)) | ||
1948 | return -EINVAL; | ||
1949 | |||
1950 | switch (playing_mode) { | ||
1951 | case AWE_PLAY_DIRECT: | ||
1952 | case AWE_PLAY_INDIRECT: | ||
1953 | key = AWE_VOICE_KEY(voice); | ||
1954 | break; | ||
1955 | |||
1956 | case AWE_PLAY_MULTI2: | ||
1957 | v2 = voice_alloc->map[voice] >> 8; | ||
1958 | voice_alloc->map[voice] = 0; | ||
1959 | voice = v2; | ||
1960 | if (voice < 0 || voice >= AWE_MAX_CHANNELS) | ||
1961 | return -EINVAL; | ||
1962 | /* continue to below */ | ||
1963 | default: | ||
1964 | key = AWE_CHAN_KEY(voice, note); | ||
1965 | break; | ||
1966 | } | ||
1967 | |||
1968 | for (i = 0; i < awe_max_voices; i++) { | ||
1969 | if (voices[i].key == key) | ||
1970 | release_voice(i, TRUE); | ||
1971 | } | ||
1972 | return 0; | ||
1973 | } | ||
1974 | |||
1975 | |||
1976 | static void start_or_volume_change(int voice, int velocity) | ||
1977 | { | ||
1978 | voices[voice].velocity = velocity; | ||
1979 | awe_calc_volume(voice); | ||
1980 | if (voices[voice].state == AWE_ST_STANDBY) | ||
1981 | awe_note_on(voice); | ||
1982 | else if (voices[voice].state == AWE_ST_ON) | ||
1983 | awe_set_volume(voice, FALSE); | ||
1984 | } | ||
1985 | |||
1986 | static void set_and_start_voice(int voice, int state) | ||
1987 | { | ||
1988 | /* calculate pitch & volume parameters */ | ||
1989 | voices[voice].state = state; | ||
1990 | awe_calc_pitch(voice); | ||
1991 | awe_calc_volume(voice); | ||
1992 | if (state == AWE_ST_ON) | ||
1993 | awe_note_on(voice); | ||
1994 | } | ||
1995 | |||
1996 | /* start a voice: | ||
1997 | * if note is 255, identical with aftertouch function. | ||
1998 | * Otherwise, start a voice with specified not and volume. | ||
1999 | */ | ||
2000 | static int | ||
2001 | awe_start_note(int dev, int voice, int note, int velocity) | ||
2002 | { | ||
2003 | int i, key, state, volonly; | ||
2004 | |||
2005 | DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity)); | ||
2006 | if (! voice_in_range(voice)) | ||
2007 | return -EINVAL; | ||
2008 | |||
2009 | if (velocity == 0) | ||
2010 | state = AWE_ST_STANDBY; /* stand by for playing */ | ||
2011 | else | ||
2012 | state = AWE_ST_ON; /* really play */ | ||
2013 | volonly = FALSE; | ||
2014 | |||
2015 | switch (playing_mode) { | ||
2016 | case AWE_PLAY_DIRECT: | ||
2017 | case AWE_PLAY_INDIRECT: | ||
2018 | key = AWE_VOICE_KEY(voice); | ||
2019 | if (note == 255) | ||
2020 | volonly = TRUE; | ||
2021 | break; | ||
2022 | |||
2023 | case AWE_PLAY_MULTI2: | ||
2024 | voice = voice_alloc->map[voice] >> 8; | ||
2025 | if (voice < 0 || voice >= AWE_MAX_CHANNELS) | ||
2026 | return -EINVAL; | ||
2027 | /* continue to below */ | ||
2028 | default: | ||
2029 | if (note >= 128) { /* key volume mode */ | ||
2030 | note -= 128; | ||
2031 | volonly = TRUE; | ||
2032 | } | ||
2033 | key = AWE_CHAN_KEY(voice, note); | ||
2034 | break; | ||
2035 | } | ||
2036 | |||
2037 | /* dynamic volume change */ | ||
2038 | if (volonly) { | ||
2039 | for (i = 0; i < awe_max_voices; i++) { | ||
2040 | if (voices[i].key == key) | ||
2041 | start_or_volume_change(i, velocity); | ||
2042 | } | ||
2043 | return 0; | ||
2044 | } | ||
2045 | |||
2046 | /* if the same note still playing, stop it */ | ||
2047 | if (playing_mode != AWE_PLAY_DIRECT || ctrls[AWE_MD_EXCLUSIVE_SOUND]) { | ||
2048 | for (i = 0; i < awe_max_voices; i++) | ||
2049 | if (voices[i].key == key) { | ||
2050 | if (voices[i].state == AWE_ST_ON) { | ||
2051 | awe_note_off(i); | ||
2052 | awe_voice_init(i, FALSE); | ||
2053 | } else if (voices[i].state == AWE_ST_STANDBY) | ||
2054 | awe_voice_init(i, TRUE); | ||
2055 | } | ||
2056 | } | ||
2057 | |||
2058 | /* allocate voices */ | ||
2059 | if (playing_mode == AWE_PLAY_DIRECT) | ||
2060 | awe_alloc_one_voice(voice, note, velocity); | ||
2061 | else | ||
2062 | awe_alloc_multi_voices(voice, note, velocity, key); | ||
2063 | |||
2064 | /* turn off other voices exlusively (for drums) */ | ||
2065 | for (i = 0; i < awe_max_voices; i++) | ||
2066 | if (voices[i].key == key) | ||
2067 | awe_exclusive_off(i); | ||
2068 | |||
2069 | /* set up pitch and volume parameters */ | ||
2070 | for (i = 0; i < awe_max_voices; i++) { | ||
2071 | if (voices[i].key == key && voices[i].state == AWE_ST_OFF) | ||
2072 | set_and_start_voice(i, state); | ||
2073 | } | ||
2074 | |||
2075 | return 0; | ||
2076 | } | ||
2077 | |||
2078 | |||
2079 | /* calculate hash key */ | ||
2080 | static int | ||
2081 | awe_search_key(int bank, int preset, int note) | ||
2082 | { | ||
2083 | unsigned int key; | ||
2084 | |||
2085 | #if 1 /* new hash table */ | ||
2086 | if (bank == AWE_DRUM_BANK) | ||
2087 | key = preset + note + 128; | ||
2088 | else | ||
2089 | key = bank + preset; | ||
2090 | #else | ||
2091 | key = preset; | ||
2092 | #endif | ||
2093 | key %= AWE_MAX_PRESETS; | ||
2094 | |||
2095 | return (int)key; | ||
2096 | } | ||
2097 | |||
2098 | |||
2099 | /* search instrument from hash table */ | ||
2100 | static awe_voice_list * | ||
2101 | awe_search_instr(int bank, int preset, int note) | ||
2102 | { | ||
2103 | awe_voice_list *p; | ||
2104 | int key, key2; | ||
2105 | |||
2106 | key = awe_search_key(bank, preset, note); | ||
2107 | for (p = preset_table[key]; p; p = p->next_bank) { | ||
2108 | if (p->instr == preset && p->bank == bank) | ||
2109 | return p; | ||
2110 | } | ||
2111 | key2 = awe_search_key(bank, preset, 0); /* search default */ | ||
2112 | if (key == key2) | ||
2113 | return NULL; | ||
2114 | for (p = preset_table[key2]; p; p = p->next_bank) { | ||
2115 | if (p->instr == preset && p->bank == bank) | ||
2116 | return p; | ||
2117 | } | ||
2118 | return NULL; | ||
2119 | } | ||
2120 | |||
2121 | |||
2122 | /* assign the instrument to a voice */ | ||
2123 | static int | ||
2124 | awe_set_instr_2(int dev, int voice, int instr_no) | ||
2125 | { | ||
2126 | if (playing_mode == AWE_PLAY_MULTI2) { | ||
2127 | voice = voice_alloc->map[voice] >> 8; | ||
2128 | if (voice < 0 || voice >= AWE_MAX_CHANNELS) | ||
2129 | return -EINVAL; | ||
2130 | } | ||
2131 | return awe_set_instr(dev, voice, instr_no); | ||
2132 | } | ||
2133 | |||
2134 | /* assign the instrument to a channel; voice is the channel number */ | ||
2135 | static int | ||
2136 | awe_set_instr(int dev, int voice, int instr_no) | ||
2137 | { | ||
2138 | awe_chan_info *cinfo; | ||
2139 | |||
2140 | if (! voice_in_range(voice)) | ||
2141 | return -EINVAL; | ||
2142 | |||
2143 | if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS) | ||
2144 | return -EINVAL; | ||
2145 | |||
2146 | cinfo = &channels[voice]; | ||
2147 | cinfo->instr = instr_no; | ||
2148 | DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no)); | ||
2149 | |||
2150 | return 0; | ||
2151 | } | ||
2152 | |||
2153 | |||
2154 | /* reset all voices; terminate sounds and initialize parameters */ | ||
2155 | static void | ||
2156 | awe_reset(int dev) | ||
2157 | { | ||
2158 | int i; | ||
2159 | current_alloc_time = 0; | ||
2160 | /* don't turn off voice 31 and 32. they are used also for FM voices */ | ||
2161 | for (i = 0; i < awe_max_voices; i++) { | ||
2162 | awe_terminate(i); | ||
2163 | awe_voice_init(i, TRUE); | ||
2164 | } | ||
2165 | for (i = 0; i < AWE_MAX_CHANNELS; i++) | ||
2166 | awe_channel_init(i, TRUE); | ||
2167 | for (i = 0; i < 16; i++) { | ||
2168 | awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127; | ||
2169 | awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127; | ||
2170 | } | ||
2171 | awe_init_fm(); | ||
2172 | awe_tweak(); | ||
2173 | } | ||
2174 | |||
2175 | |||
2176 | /* hardware specific control: | ||
2177 | * GUS specific and AWE32 specific controls are available. | ||
2178 | */ | ||
2179 | static void | ||
2180 | awe_hw_control(int dev, unsigned char *event) | ||
2181 | { | ||
2182 | int cmd = event[2]; | ||
2183 | if (cmd & _AWE_MODE_FLAG) | ||
2184 | awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event); | ||
2185 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
2186 | else | ||
2187 | awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event); | ||
2188 | #endif | ||
2189 | } | ||
2190 | |||
2191 | |||
2192 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
2193 | |||
2194 | /* GUS compatible controls */ | ||
2195 | static void | ||
2196 | awe_hw_gus_control(int dev, int cmd, unsigned char *event) | ||
2197 | { | ||
2198 | int voice, i, key; | ||
2199 | unsigned short p1; | ||
2200 | short p2; | ||
2201 | int plong; | ||
2202 | |||
2203 | if (MULTI_LAYER_MODE()) | ||
2204 | return; | ||
2205 | if (cmd == _GUS_NUMVOICES) | ||
2206 | return; | ||
2207 | |||
2208 | voice = event[3]; | ||
2209 | if (! voice_in_range(voice)) | ||
2210 | return; | ||
2211 | |||
2212 | p1 = *(unsigned short *) &event[4]; | ||
2213 | p2 = *(short *) &event[6]; | ||
2214 | plong = *(int*) &event[4]; | ||
2215 | |||
2216 | switch (cmd) { | ||
2217 | case _GUS_VOICESAMPLE: | ||
2218 | awe_set_instr(dev, voice, p1); | ||
2219 | return; | ||
2220 | |||
2221 | case _GUS_VOICEBALA: | ||
2222 | /* 0 to 15 --> -128 to 127 */ | ||
2223 | awe_panning(dev, voice, ((int)p1 << 4) - 128); | ||
2224 | return; | ||
2225 | |||
2226 | case _GUS_VOICEVOL: | ||
2227 | case _GUS_VOICEVOL2: | ||
2228 | /* not supported yet */ | ||
2229 | return; | ||
2230 | |||
2231 | case _GUS_RAMPRANGE: | ||
2232 | case _GUS_RAMPRATE: | ||
2233 | case _GUS_RAMPMODE: | ||
2234 | case _GUS_RAMPON: | ||
2235 | case _GUS_RAMPOFF: | ||
2236 | /* volume ramping not supported */ | ||
2237 | return; | ||
2238 | |||
2239 | case _GUS_VOLUME_SCALE: | ||
2240 | return; | ||
2241 | |||
2242 | case _GUS_VOICE_POS: | ||
2243 | FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START, | ||
2244 | (short)(plong & 0x7fff)); | ||
2245 | FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START, | ||
2246 | (plong >> 15) & 0xffff); | ||
2247 | return; | ||
2248 | } | ||
2249 | |||
2250 | key = AWE_VOICE_KEY(voice); | ||
2251 | for (i = 0; i < awe_max_voices; i++) { | ||
2252 | if (voices[i].key == key) { | ||
2253 | switch (cmd) { | ||
2254 | case _GUS_VOICEON: | ||
2255 | awe_note_on(i); | ||
2256 | break; | ||
2257 | |||
2258 | case _GUS_VOICEOFF: | ||
2259 | awe_terminate(i); | ||
2260 | awe_fx_init(voices[i].ch); | ||
2261 | awe_voice_init(i, TRUE); | ||
2262 | break; | ||
2263 | |||
2264 | case _GUS_VOICEFADE: | ||
2265 | awe_note_off(i); | ||
2266 | awe_fx_init(voices[i].ch); | ||
2267 | awe_voice_init(i, FALSE); | ||
2268 | break; | ||
2269 | |||
2270 | case _GUS_VOICEFREQ: | ||
2271 | awe_calc_pitch_from_freq(i, plong); | ||
2272 | break; | ||
2273 | } | ||
2274 | } | ||
2275 | } | ||
2276 | } | ||
2277 | |||
2278 | #endif /* gus_compat */ | ||
2279 | |||
2280 | |||
2281 | /* AWE32 specific controls */ | ||
2282 | static void | ||
2283 | awe_hw_awe_control(int dev, int cmd, unsigned char *event) | ||
2284 | { | ||
2285 | int voice; | ||
2286 | unsigned short p1; | ||
2287 | short p2; | ||
2288 | int i; | ||
2289 | |||
2290 | voice = event[3]; | ||
2291 | if (! voice_in_range(voice)) | ||
2292 | return; | ||
2293 | |||
2294 | if (playing_mode == AWE_PLAY_MULTI2) { | ||
2295 | voice = voice_alloc->map[voice] >> 8; | ||
2296 | if (voice < 0 || voice >= AWE_MAX_CHANNELS) | ||
2297 | return; | ||
2298 | } | ||
2299 | |||
2300 | p1 = *(unsigned short *) &event[4]; | ||
2301 | p2 = *(short *) &event[6]; | ||
2302 | |||
2303 | switch (cmd) { | ||
2304 | case _AWE_DEBUG_MODE: | ||
2305 | ctrls[AWE_MD_DEBUG_MODE] = p1; | ||
2306 | printk(KERN_DEBUG "AWE32: debug mode = %d\n", ctrls[AWE_MD_DEBUG_MODE]); | ||
2307 | break; | ||
2308 | case _AWE_REVERB_MODE: | ||
2309 | ctrls[AWE_MD_REVERB_MODE] = p1; | ||
2310 | awe_update_reverb_mode(); | ||
2311 | break; | ||
2312 | |||
2313 | case _AWE_CHORUS_MODE: | ||
2314 | ctrls[AWE_MD_CHORUS_MODE] = p1; | ||
2315 | awe_update_chorus_mode(); | ||
2316 | break; | ||
2317 | |||
2318 | case _AWE_REMOVE_LAST_SAMPLES: | ||
2319 | DEBUG(0,printk("AWE32: remove last samples\n")); | ||
2320 | awe_reset(0); | ||
2321 | if (locked_sf_id > 0) | ||
2322 | awe_remove_samples(locked_sf_id); | ||
2323 | break; | ||
2324 | |||
2325 | case _AWE_INITIALIZE_CHIP: | ||
2326 | awe_initialize(); | ||
2327 | break; | ||
2328 | |||
2329 | case _AWE_SEND_EFFECT: | ||
2330 | i = -1; | ||
2331 | if (p1 >= 0x100) { | ||
2332 | i = (p1 >> 8); | ||
2333 | if (i < 0 || i >= MAX_LAYERS) | ||
2334 | break; | ||
2335 | } | ||
2336 | awe_send_effect(voice, i, p1, p2); | ||
2337 | break; | ||
2338 | |||
2339 | case _AWE_RESET_CHANNEL: | ||
2340 | awe_channel_init(voice, !p1); | ||
2341 | break; | ||
2342 | |||
2343 | case _AWE_TERMINATE_ALL: | ||
2344 | awe_reset(0); | ||
2345 | break; | ||
2346 | |||
2347 | case _AWE_TERMINATE_CHANNEL: | ||
2348 | awe_voice_change(voice, awe_terminate_and_init); | ||
2349 | break; | ||
2350 | |||
2351 | case _AWE_RELEASE_ALL: | ||
2352 | awe_note_off_all(FALSE); | ||
2353 | break; | ||
2354 | case _AWE_NOTEOFF_ALL: | ||
2355 | awe_note_off_all(TRUE); | ||
2356 | break; | ||
2357 | |||
2358 | case _AWE_INITIAL_VOLUME: | ||
2359 | DEBUG(0,printk("AWE32: init attenuation %d\n", p1)); | ||
2360 | atten_relative = (char)p2; | ||
2361 | atten_offset = (short)p1; | ||
2362 | awe_update_volume(); | ||
2363 | break; | ||
2364 | |||
2365 | case _AWE_CHN_PRESSURE: | ||
2366 | channels[voice].chan_press = p1; | ||
2367 | awe_modwheel_change(voice, p1); | ||
2368 | break; | ||
2369 | |||
2370 | case _AWE_CHANNEL_MODE: | ||
2371 | DEBUG(0,printk("AWE32: channel mode = %d\n", p1)); | ||
2372 | playing_mode = p1; | ||
2373 | awe_reset(0); | ||
2374 | break; | ||
2375 | |||
2376 | case _AWE_DRUM_CHANNELS: | ||
2377 | DEBUG(0,printk("AWE32: drum flags = %x\n", p1)); | ||
2378 | drum_flags = *(unsigned int*)&event[4]; | ||
2379 | break; | ||
2380 | |||
2381 | case _AWE_MISC_MODE: | ||
2382 | DEBUG(0,printk("AWE32: ctrl parms = %d %d\n", p1, p2)); | ||
2383 | if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END) { | ||
2384 | ctrls[p1] = p2; | ||
2385 | if (ctrl_parms[p1].update) | ||
2386 | ctrl_parms[p1].update(); | ||
2387 | } | ||
2388 | break; | ||
2389 | |||
2390 | case _AWE_EQUALIZER: | ||
2391 | ctrls[AWE_MD_BASS_LEVEL] = p1; | ||
2392 | ctrls[AWE_MD_TREBLE_LEVEL] = p2; | ||
2393 | awe_update_equalizer(); | ||
2394 | break; | ||
2395 | |||
2396 | default: | ||
2397 | DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice)); | ||
2398 | break; | ||
2399 | } | ||
2400 | } | ||
2401 | |||
2402 | |||
2403 | /* change effects */ | ||
2404 | static void | ||
2405 | awe_send_effect(int voice, int layer, int type, int val) | ||
2406 | { | ||
2407 | awe_chan_info *cinfo; | ||
2408 | FX_Rec *fx; | ||
2409 | int mode; | ||
2410 | |||
2411 | cinfo = &channels[voice]; | ||
2412 | if (layer >= 0 && layer < MAX_LAYERS) | ||
2413 | fx = &cinfo->fx_layer[layer]; | ||
2414 | else | ||
2415 | fx = &cinfo->fx; | ||
2416 | |||
2417 | if (type & 0x40) | ||
2418 | mode = FX_FLAG_OFF; | ||
2419 | else if (type & 0x80) | ||
2420 | mode = FX_FLAG_ADD; | ||
2421 | else | ||
2422 | mode = FX_FLAG_SET; | ||
2423 | type &= 0x3f; | ||
2424 | |||
2425 | if (type >= 0 && type < AWE_FX_END) { | ||
2426 | DEBUG(2,printk("AWE32: effects (%d) %d %d\n", voice, type, val)); | ||
2427 | if (mode == FX_FLAG_SET) | ||
2428 | FX_SET(fx, type, val); | ||
2429 | else if (mode == FX_FLAG_ADD) | ||
2430 | FX_ADD(fx, type, val); | ||
2431 | else | ||
2432 | FX_UNSET(fx, type); | ||
2433 | if (mode != FX_FLAG_OFF && parm_defs[type].realtime) { | ||
2434 | DEBUG(2,printk("AWE32: fx_realtime (%d)\n", voice)); | ||
2435 | awe_voice_change(voice, parm_defs[type].realtime); | ||
2436 | } | ||
2437 | } | ||
2438 | } | ||
2439 | |||
2440 | |||
2441 | /* change modulation wheel; voice is already mapped on multi2 mode */ | ||
2442 | static void | ||
2443 | awe_modwheel_change(int voice, int value) | ||
2444 | { | ||
2445 | int i; | ||
2446 | awe_chan_info *cinfo; | ||
2447 | |||
2448 | cinfo = &channels[voice]; | ||
2449 | i = value * ctrls[AWE_MD_MOD_SENSE] / 1200; | ||
2450 | FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i); | ||
2451 | awe_voice_change(voice, awe_fx_fmmod); | ||
2452 | FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i); | ||
2453 | awe_voice_change(voice, awe_fx_fm2frq2); | ||
2454 | } | ||
2455 | |||
2456 | |||
2457 | /* voice pressure change */ | ||
2458 | static void | ||
2459 | awe_aftertouch(int dev, int voice, int pressure) | ||
2460 | { | ||
2461 | int note; | ||
2462 | |||
2463 | DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure)); | ||
2464 | if (! voice_in_range(voice)) | ||
2465 | return; | ||
2466 | |||
2467 | switch (playing_mode) { | ||
2468 | case AWE_PLAY_DIRECT: | ||
2469 | case AWE_PLAY_INDIRECT: | ||
2470 | awe_start_note(dev, voice, 255, pressure); | ||
2471 | break; | ||
2472 | case AWE_PLAY_MULTI2: | ||
2473 | note = (voice_alloc->map[voice] & 0xff) - 1; | ||
2474 | awe_key_pressure(dev, voice, note + 0x80, pressure); | ||
2475 | break; | ||
2476 | } | ||
2477 | } | ||
2478 | |||
2479 | |||
2480 | /* voice control change */ | ||
2481 | static void | ||
2482 | awe_controller(int dev, int voice, int ctrl_num, int value) | ||
2483 | { | ||
2484 | awe_chan_info *cinfo; | ||
2485 | |||
2486 | if (! voice_in_range(voice)) | ||
2487 | return; | ||
2488 | |||
2489 | if (playing_mode == AWE_PLAY_MULTI2) { | ||
2490 | voice = voice_alloc->map[voice] >> 8; | ||
2491 | if (voice < 0 || voice >= AWE_MAX_CHANNELS) | ||
2492 | return; | ||
2493 | } | ||
2494 | |||
2495 | cinfo = &channels[voice]; | ||
2496 | |||
2497 | switch (ctrl_num) { | ||
2498 | case CTL_BANK_SELECT: /* MIDI control #0 */ | ||
2499 | DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value)); | ||
2500 | if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) && | ||
2501 | !ctrls[AWE_MD_TOGGLE_DRUM_BANK]) | ||
2502 | break; | ||
2503 | if (value < 0 || value > 255) | ||
2504 | break; | ||
2505 | cinfo->bank = value; | ||
2506 | if (cinfo->bank == AWE_DRUM_BANK) | ||
2507 | DRUM_CHANNEL_ON(cinfo->channel); | ||
2508 | else | ||
2509 | DRUM_CHANNEL_OFF(cinfo->channel); | ||
2510 | awe_set_instr(dev, voice, cinfo->instr); | ||
2511 | break; | ||
2512 | |||
2513 | case CTL_MODWHEEL: /* MIDI control #1 */ | ||
2514 | DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value)); | ||
2515 | awe_modwheel_change(voice, value); | ||
2516 | break; | ||
2517 | |||
2518 | case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */ | ||
2519 | DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value)); | ||
2520 | /* zero centered */ | ||
2521 | cinfo->bender = value; | ||
2522 | awe_voice_change(voice, awe_set_voice_pitch); | ||
2523 | break; | ||
2524 | |||
2525 | case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */ | ||
2526 | DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value)); | ||
2527 | /* value = sense x 100 */ | ||
2528 | cinfo->bender_range = value; | ||
2529 | /* no audible pitch change yet.. */ | ||
2530 | break; | ||
2531 | |||
2532 | case CTL_EXPRESSION: /* MIDI control #11 */ | ||
2533 | if (SINGLE_LAYER_MODE()) | ||
2534 | value /= 128; | ||
2535 | case CTRL_EXPRESSION: /* SEQ1 V2 control */ | ||
2536 | DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value)); | ||
2537 | /* 0 - 127 */ | ||
2538 | cinfo->expression_vol = value; | ||
2539 | awe_voice_change(voice, awe_set_voice_vol); | ||
2540 | break; | ||
2541 | |||
2542 | case CTL_PAN: /* MIDI control #10 */ | ||
2543 | DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value)); | ||
2544 | /* (0-127) -> signed 8bit */ | ||
2545 | cinfo->panning = value * 2 - 128; | ||
2546 | if (ctrls[AWE_MD_REALTIME_PAN]) | ||
2547 | awe_voice_change(voice, awe_set_pan); | ||
2548 | break; | ||
2549 | |||
2550 | case CTL_MAIN_VOLUME: /* MIDI control #7 */ | ||
2551 | if (SINGLE_LAYER_MODE()) | ||
2552 | value = (value * 100) / 16383; | ||
2553 | case CTRL_MAIN_VOLUME: /* SEQ1 V2 control */ | ||
2554 | DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value)); | ||
2555 | /* 0 - 127 */ | ||
2556 | cinfo->main_vol = value; | ||
2557 | awe_voice_change(voice, awe_set_voice_vol); | ||
2558 | break; | ||
2559 | |||
2560 | case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */ | ||
2561 | DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value)); | ||
2562 | FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2); | ||
2563 | break; | ||
2564 | |||
2565 | case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */ | ||
2566 | DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value)); | ||
2567 | FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2); | ||
2568 | break; | ||
2569 | |||
2570 | case 120: /* all sounds off */ | ||
2571 | awe_note_off_all(FALSE); | ||
2572 | break; | ||
2573 | case 123: /* all notes off */ | ||
2574 | awe_note_off_all(TRUE); | ||
2575 | break; | ||
2576 | |||
2577 | case CTL_SUSTAIN: /* MIDI control #64 */ | ||
2578 | cinfo->sustained = value; | ||
2579 | if (value != 127) | ||
2580 | awe_voice_change(voice, awe_sustain_off); | ||
2581 | break; | ||
2582 | |||
2583 | case CTL_SOSTENUTO: /* MIDI control #66 */ | ||
2584 | if (value == 127) | ||
2585 | awe_voice_change(voice, awe_sostenuto_on); | ||
2586 | else | ||
2587 | awe_voice_change(voice, awe_sustain_off); | ||
2588 | break; | ||
2589 | |||
2590 | default: | ||
2591 | DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n", | ||
2592 | voice, ctrl_num, value)); | ||
2593 | break; | ||
2594 | } | ||
2595 | } | ||
2596 | |||
2597 | |||
2598 | /* voice pan change (value = -128 - 127) */ | ||
2599 | static void | ||
2600 | awe_panning(int dev, int voice, int value) | ||
2601 | { | ||
2602 | awe_chan_info *cinfo; | ||
2603 | |||
2604 | if (! voice_in_range(voice)) | ||
2605 | return; | ||
2606 | |||
2607 | if (playing_mode == AWE_PLAY_MULTI2) { | ||
2608 | voice = voice_alloc->map[voice] >> 8; | ||
2609 | if (voice < 0 || voice >= AWE_MAX_CHANNELS) | ||
2610 | return; | ||
2611 | } | ||
2612 | |||
2613 | cinfo = &channels[voice]; | ||
2614 | cinfo->panning = value; | ||
2615 | DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning)); | ||
2616 | if (ctrls[AWE_MD_REALTIME_PAN]) | ||
2617 | awe_voice_change(voice, awe_set_pan); | ||
2618 | } | ||
2619 | |||
2620 | |||
2621 | /* volume mode change */ | ||
2622 | static void | ||
2623 | awe_volume_method(int dev, int mode) | ||
2624 | { | ||
2625 | /* not impremented */ | ||
2626 | DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode)); | ||
2627 | } | ||
2628 | |||
2629 | |||
2630 | /* pitch wheel change: 0-16384 */ | ||
2631 | static void | ||
2632 | awe_bender(int dev, int voice, int value) | ||
2633 | { | ||
2634 | awe_chan_info *cinfo; | ||
2635 | |||
2636 | if (! voice_in_range(voice)) | ||
2637 | return; | ||
2638 | |||
2639 | if (playing_mode == AWE_PLAY_MULTI2) { | ||
2640 | voice = voice_alloc->map[voice] >> 8; | ||
2641 | if (voice < 0 || voice >= AWE_MAX_CHANNELS) | ||
2642 | return; | ||
2643 | } | ||
2644 | |||
2645 | /* convert to zero centered value */ | ||
2646 | cinfo = &channels[voice]; | ||
2647 | cinfo->bender = value - 8192; | ||
2648 | DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender)); | ||
2649 | awe_voice_change(voice, awe_set_voice_pitch); | ||
2650 | } | ||
2651 | |||
2652 | |||
2653 | /* | ||
2654 | * load a sound patch: | ||
2655 | * three types of patches are accepted: AWE, GUS, and SYSEX. | ||
2656 | */ | ||
2657 | |||
2658 | static int | ||
2659 | awe_load_patch(int dev, int format, const char __user *addr, | ||
2660 | int offs, int count, int pmgr_flag) | ||
2661 | { | ||
2662 | awe_patch_info patch; | ||
2663 | int rc = 0; | ||
2664 | |||
2665 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
2666 | if (format == GUS_PATCH) { | ||
2667 | return awe_load_guspatch(addr, offs, count, pmgr_flag); | ||
2668 | } else | ||
2669 | #endif | ||
2670 | if (format == SYSEX_PATCH) { | ||
2671 | /* no system exclusive message supported yet */ | ||
2672 | return 0; | ||
2673 | } else if (format != AWE_PATCH) { | ||
2674 | printk(KERN_WARNING "AWE32 Error: Invalid patch format (key) 0x%x\n", format); | ||
2675 | return -EINVAL; | ||
2676 | } | ||
2677 | |||
2678 | if (count < AWE_PATCH_INFO_SIZE) { | ||
2679 | printk(KERN_WARNING "AWE32 Error: Patch header too short\n"); | ||
2680 | return -EINVAL; | ||
2681 | } | ||
2682 | if (copy_from_user(((char*)&patch) + offs, addr + offs, | ||
2683 | AWE_PATCH_INFO_SIZE - offs)) | ||
2684 | return -EFAULT; | ||
2685 | |||
2686 | count -= AWE_PATCH_INFO_SIZE; | ||
2687 | if (count < patch.len) { | ||
2688 | printk(KERN_WARNING "AWE32: sample: Patch record too short (%d<%d)\n", | ||
2689 | count, patch.len); | ||
2690 | return -EINVAL; | ||
2691 | } | ||
2692 | |||
2693 | switch (patch.type) { | ||
2694 | case AWE_LOAD_INFO: | ||
2695 | rc = awe_load_info(&patch, addr, count); | ||
2696 | break; | ||
2697 | case AWE_LOAD_DATA: | ||
2698 | rc = awe_load_data(&patch, addr, count); | ||
2699 | break; | ||
2700 | case AWE_OPEN_PATCH: | ||
2701 | rc = awe_open_patch(&patch, addr, count); | ||
2702 | break; | ||
2703 | case AWE_CLOSE_PATCH: | ||
2704 | rc = awe_close_patch(&patch, addr, count); | ||
2705 | break; | ||
2706 | case AWE_UNLOAD_PATCH: | ||
2707 | rc = awe_unload_patch(&patch, addr, count); | ||
2708 | break; | ||
2709 | case AWE_REPLACE_DATA: | ||
2710 | rc = awe_replace_data(&patch, addr, count); | ||
2711 | break; | ||
2712 | case AWE_MAP_PRESET: | ||
2713 | rc = awe_load_map(&patch, addr, count); | ||
2714 | break; | ||
2715 | /* case AWE_PROBE_INFO: | ||
2716 | rc = awe_probe_info(&patch, addr, count); | ||
2717 | break;*/ | ||
2718 | case AWE_PROBE_DATA: | ||
2719 | rc = awe_probe_data(&patch, addr, count); | ||
2720 | break; | ||
2721 | case AWE_REMOVE_INFO: | ||
2722 | rc = awe_remove_info(&patch, addr, count); | ||
2723 | break; | ||
2724 | case AWE_LOAD_CHORUS_FX: | ||
2725 | rc = awe_load_chorus_fx(&patch, addr, count); | ||
2726 | break; | ||
2727 | case AWE_LOAD_REVERB_FX: | ||
2728 | rc = awe_load_reverb_fx(&patch, addr, count); | ||
2729 | break; | ||
2730 | |||
2731 | default: | ||
2732 | printk(KERN_WARNING "AWE32 Error: unknown patch format type %d\n", | ||
2733 | patch.type); | ||
2734 | rc = -EINVAL; | ||
2735 | } | ||
2736 | |||
2737 | return rc; | ||
2738 | } | ||
2739 | |||
2740 | |||
2741 | /* create an sf list record */ | ||
2742 | static int | ||
2743 | awe_create_sf(int type, char *name) | ||
2744 | { | ||
2745 | sf_list *rec; | ||
2746 | |||
2747 | /* terminate sounds */ | ||
2748 | awe_reset(0); | ||
2749 | rec = (sf_list *)kmalloc(sizeof(*rec), GFP_KERNEL); | ||
2750 | if (rec == NULL) | ||
2751 | return 1; /* no memory */ | ||
2752 | rec->sf_id = current_sf_id + 1; | ||
2753 | rec->type = type; | ||
2754 | if (/*current_sf_id == 0 ||*/ (type & AWE_PAT_LOCKED) != 0) | ||
2755 | locked_sf_id = current_sf_id + 1; | ||
2756 | rec->num_info = awe_free_info(); | ||
2757 | rec->num_sample = awe_free_sample(); | ||
2758 | rec->mem_ptr = awe_free_mem_ptr(); | ||
2759 | rec->infos = rec->last_infos = NULL; | ||
2760 | rec->samples = rec->last_samples = NULL; | ||
2761 | |||
2762 | /* add to linked-list */ | ||
2763 | rec->next = NULL; | ||
2764 | rec->prev = sftail; | ||
2765 | if (sftail) | ||
2766 | sftail->next = rec; | ||
2767 | else | ||
2768 | sfhead = rec; | ||
2769 | sftail = rec; | ||
2770 | current_sf_id++; | ||
2771 | |||
2772 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
2773 | rec->shared = NULL; | ||
2774 | if (name) | ||
2775 | memcpy(rec->name, name, AWE_PATCH_NAME_LEN); | ||
2776 | else | ||
2777 | strcpy(rec->name, "*TEMPORARY*"); | ||
2778 | if (current_sf_id > 1 && name && (type & AWE_PAT_SHARED) != 0) { | ||
2779 | /* is the current font really a shared font? */ | ||
2780 | if (is_shared_sf(rec->name)) { | ||
2781 | /* check if the shared font is already installed */ | ||
2782 | sf_list *p; | ||
2783 | for (p = rec->prev; p; p = p->prev) { | ||
2784 | if (is_identical_name(rec->name, p)) { | ||
2785 | rec->shared = p; | ||
2786 | break; | ||
2787 | } | ||
2788 | } | ||
2789 | } | ||
2790 | } | ||
2791 | #endif /* allow sharing */ | ||
2792 | |||
2793 | return 0; | ||
2794 | } | ||
2795 | |||
2796 | |||
2797 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
2798 | |||
2799 | /* check if the given name is a valid shared name */ | ||
2800 | #define ASC_TO_KEY(c) ((c) - 'A' + 1) | ||
2801 | static int is_shared_sf(unsigned char *name) | ||
2802 | { | ||
2803 | static unsigned char id_head[4] = { | ||
2804 | ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'), | ||
2805 | AWE_MAJOR_VERSION, | ||
2806 | }; | ||
2807 | if (memcmp(name, id_head, 4) == 0) | ||
2808 | return TRUE; | ||
2809 | return FALSE; | ||
2810 | } | ||
2811 | |||
2812 | /* check if the given name matches to the existing list */ | ||
2813 | static int is_identical_name(unsigned char *name, sf_list *p) | ||
2814 | { | ||
2815 | char *id = p->name; | ||
2816 | if (is_shared_sf(id) && memcmp(id, name, AWE_PATCH_NAME_LEN) == 0) | ||
2817 | return TRUE; | ||
2818 | return FALSE; | ||
2819 | } | ||
2820 | |||
2821 | /* check if the given voice info exists */ | ||
2822 | static int info_duplicated(sf_list *sf, awe_voice_list *rec) | ||
2823 | { | ||
2824 | /* search for all sharing lists */ | ||
2825 | for (; sf; sf = sf->shared) { | ||
2826 | awe_voice_list *p; | ||
2827 | for (p = sf->infos; p; p = p->next) { | ||
2828 | if (p->type == V_ST_NORMAL && | ||
2829 | p->bank == rec->bank && | ||
2830 | p->instr == rec->instr && | ||
2831 | p->v.low == rec->v.low && | ||
2832 | p->v.high == rec->v.high && | ||
2833 | p->v.sample == rec->v.sample) | ||
2834 | return TRUE; | ||
2835 | } | ||
2836 | } | ||
2837 | return FALSE; | ||
2838 | } | ||
2839 | |||
2840 | #endif /* AWE_ALLOW_SAMPLE_SHARING */ | ||
2841 | |||
2842 | |||
2843 | /* free sf_list record */ | ||
2844 | /* linked-list in this function is not cared */ | ||
2845 | static void | ||
2846 | awe_free_sf(sf_list *sf) | ||
2847 | { | ||
2848 | if (sf->infos) { | ||
2849 | awe_voice_list *p, *next; | ||
2850 | for (p = sf->infos; p; p = next) { | ||
2851 | next = p->next; | ||
2852 | kfree(p); | ||
2853 | } | ||
2854 | } | ||
2855 | if (sf->samples) { | ||
2856 | awe_sample_list *p, *next; | ||
2857 | for (p = sf->samples; p; p = next) { | ||
2858 | next = p->next; | ||
2859 | kfree(p); | ||
2860 | } | ||
2861 | } | ||
2862 | kfree(sf); | ||
2863 | } | ||
2864 | |||
2865 | |||
2866 | /* open patch; create sf list and set opened flag */ | ||
2867 | static int | ||
2868 | awe_open_patch(awe_patch_info *patch, const char __user *addr, int count) | ||
2869 | { | ||
2870 | awe_open_parm parm; | ||
2871 | int shared; | ||
2872 | |||
2873 | if (copy_from_user(&parm, addr + AWE_PATCH_INFO_SIZE, sizeof(parm))) | ||
2874 | return -EFAULT; | ||
2875 | shared = FALSE; | ||
2876 | |||
2877 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
2878 | if (sftail && (parm.type & AWE_PAT_SHARED) != 0) { | ||
2879 | /* is the previous font the same font? */ | ||
2880 | if (is_identical_name(parm.name, sftail)) { | ||
2881 | /* then append to the previous */ | ||
2882 | shared = TRUE; | ||
2883 | awe_reset(0); | ||
2884 | if (parm.type & AWE_PAT_LOCKED) | ||
2885 | locked_sf_id = current_sf_id; | ||
2886 | } | ||
2887 | } | ||
2888 | #endif /* allow sharing */ | ||
2889 | if (! shared) { | ||
2890 | if (awe_create_sf(parm.type, parm.name)) { | ||
2891 | printk(KERN_ERR "AWE32: can't open: failed to alloc new list\n"); | ||
2892 | return -ENOMEM; | ||
2893 | } | ||
2894 | } | ||
2895 | patch_opened = TRUE; | ||
2896 | return current_sf_id; | ||
2897 | } | ||
2898 | |||
2899 | /* check if the patch is already opened */ | ||
2900 | static sf_list * | ||
2901 | check_patch_opened(int type, char *name) | ||
2902 | { | ||
2903 | if (! patch_opened) { | ||
2904 | if (awe_create_sf(type, name)) { | ||
2905 | printk(KERN_ERR "AWE32: failed to alloc new list\n"); | ||
2906 | return NULL; | ||
2907 | } | ||
2908 | patch_opened = TRUE; | ||
2909 | return sftail; | ||
2910 | } | ||
2911 | return sftail; | ||
2912 | } | ||
2913 | |||
2914 | /* close the patch; if no voice is loaded, remove the patch */ | ||
2915 | static int | ||
2916 | awe_close_patch(awe_patch_info *patch, const char __user *addr, int count) | ||
2917 | { | ||
2918 | if (patch_opened && sftail) { | ||
2919 | /* if no voice is loaded, release the current patch */ | ||
2920 | if (sftail->infos == NULL) { | ||
2921 | awe_reset(0); | ||
2922 | awe_remove_samples(current_sf_id - 1); | ||
2923 | } | ||
2924 | } | ||
2925 | patch_opened = 0; | ||
2926 | return 0; | ||
2927 | } | ||
2928 | |||
2929 | |||
2930 | /* remove the latest patch */ | ||
2931 | static int | ||
2932 | awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count) | ||
2933 | { | ||
2934 | if (current_sf_id > 0 && current_sf_id > locked_sf_id) { | ||
2935 | awe_reset(0); | ||
2936 | awe_remove_samples(current_sf_id - 1); | ||
2937 | } | ||
2938 | return 0; | ||
2939 | } | ||
2940 | |||
2941 | /* allocate voice info list records */ | ||
2942 | static awe_voice_list * | ||
2943 | alloc_new_info(void) | ||
2944 | { | ||
2945 | awe_voice_list *newlist; | ||
2946 | |||
2947 | newlist = kmalloc(sizeof(*newlist), GFP_KERNEL); | ||
2948 | if (newlist == NULL) { | ||
2949 | printk(KERN_ERR "AWE32: can't alloc info table\n"); | ||
2950 | return NULL; | ||
2951 | } | ||
2952 | return newlist; | ||
2953 | } | ||
2954 | |||
2955 | /* allocate sample info list records */ | ||
2956 | static awe_sample_list * | ||
2957 | alloc_new_sample(void) | ||
2958 | { | ||
2959 | awe_sample_list *newlist; | ||
2960 | |||
2961 | newlist = (awe_sample_list *)kmalloc(sizeof(*newlist), GFP_KERNEL); | ||
2962 | if (newlist == NULL) { | ||
2963 | printk(KERN_ERR "AWE32: can't alloc sample table\n"); | ||
2964 | return NULL; | ||
2965 | } | ||
2966 | return newlist; | ||
2967 | } | ||
2968 | |||
2969 | /* load voice map */ | ||
2970 | static int | ||
2971 | awe_load_map(awe_patch_info *patch, const char __user *addr, int count) | ||
2972 | { | ||
2973 | awe_voice_map map; | ||
2974 | awe_voice_list *rec, *p; | ||
2975 | sf_list *sf; | ||
2976 | |||
2977 | /* get the link info */ | ||
2978 | if (count < sizeof(map)) { | ||
2979 | printk(KERN_WARNING "AWE32 Error: invalid patch info length\n"); | ||
2980 | return -EINVAL; | ||
2981 | } | ||
2982 | if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map))) | ||
2983 | return -EFAULT; | ||
2984 | |||
2985 | /* check if the identical mapping already exists */ | ||
2986 | p = awe_search_instr(map.map_bank, map.map_instr, map.map_key); | ||
2987 | for (; p; p = p->next_instr) { | ||
2988 | if (p->type == V_ST_MAPPED && | ||
2989 | p->v.start == map.src_instr && | ||
2990 | p->v.end == map.src_bank && | ||
2991 | p->v.fixkey == map.src_key) | ||
2992 | return 0; /* already present! */ | ||
2993 | } | ||
2994 | |||
2995 | if ((sf = check_patch_opened(AWE_PAT_TYPE_MAP, NULL)) == NULL) | ||
2996 | return -ENOMEM; | ||
2997 | |||
2998 | if ((rec = alloc_new_info()) == NULL) | ||
2999 | return -ENOMEM; | ||
3000 | |||
3001 | rec->bank = map.map_bank; | ||
3002 | rec->instr = map.map_instr; | ||
3003 | rec->type = V_ST_MAPPED; | ||
3004 | rec->disabled = FALSE; | ||
3005 | awe_init_voice_info(&rec->v); | ||
3006 | if (map.map_key >= 0) { | ||
3007 | rec->v.low = map.map_key; | ||
3008 | rec->v.high = map.map_key; | ||
3009 | } | ||
3010 | rec->v.start = map.src_instr; | ||
3011 | rec->v.end = map.src_bank; | ||
3012 | rec->v.fixkey = map.src_key; | ||
3013 | add_sf_info(sf, rec); | ||
3014 | add_info_list(rec); | ||
3015 | |||
3016 | return 0; | ||
3017 | } | ||
3018 | |||
3019 | #if 0 | ||
3020 | /* probe preset in the current list -- nothing to be loaded */ | ||
3021 | static int | ||
3022 | awe_probe_info(awe_patch_info *patch, const char __user *addr, int count) | ||
3023 | { | ||
3024 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
3025 | awe_voice_map map; | ||
3026 | awe_voice_list *p; | ||
3027 | |||
3028 | if (! patch_opened) | ||
3029 | return -EINVAL; | ||
3030 | |||
3031 | /* get the link info */ | ||
3032 | if (count < sizeof(map)) { | ||
3033 | printk(KERN_WARNING "AWE32 Error: invalid patch info length\n"); | ||
3034 | return -EINVAL; | ||
3035 | } | ||
3036 | if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map))) | ||
3037 | return -EFAULT; | ||
3038 | |||
3039 | /* check if the identical mapping already exists */ | ||
3040 | if (sftail == NULL) | ||
3041 | return -EINVAL; | ||
3042 | p = awe_search_instr(map.src_bank, map.src_instr, map.src_key); | ||
3043 | for (; p; p = p->next_instr) { | ||
3044 | if (p->type == V_ST_NORMAL && | ||
3045 | is_identical_holder(p->holder, sftail) && | ||
3046 | p->v.low <= map.src_key && | ||
3047 | p->v.high >= map.src_key) | ||
3048 | return 0; /* already present! */ | ||
3049 | } | ||
3050 | #endif /* allow sharing */ | ||
3051 | return -EINVAL; | ||
3052 | } | ||
3053 | #endif | ||
3054 | |||
3055 | /* probe sample in the current list -- nothing to be loaded */ | ||
3056 | static int | ||
3057 | awe_probe_data(awe_patch_info *patch, const char __user *addr, int count) | ||
3058 | { | ||
3059 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
3060 | if (! patch_opened) | ||
3061 | return -EINVAL; | ||
3062 | |||
3063 | /* search the specified sample by optarg */ | ||
3064 | if (search_sample_index(sftail, patch->optarg) != NULL) | ||
3065 | return 0; | ||
3066 | #endif /* allow sharing */ | ||
3067 | return -EINVAL; | ||
3068 | } | ||
3069 | |||
3070 | |||
3071 | /* remove the present instrument layers */ | ||
3072 | static int | ||
3073 | remove_info(sf_list *sf, int bank, int instr) | ||
3074 | { | ||
3075 | awe_voice_list *prev, *next, *p; | ||
3076 | int removed = 0; | ||
3077 | |||
3078 | prev = NULL; | ||
3079 | for (p = sf->infos; p; p = next) { | ||
3080 | next = p->next; | ||
3081 | if (p->type == V_ST_NORMAL && | ||
3082 | p->bank == bank && p->instr == instr) { | ||
3083 | /* remove this layer */ | ||
3084 | if (prev) | ||
3085 | prev->next = next; | ||
3086 | else | ||
3087 | sf->infos = next; | ||
3088 | if (p == sf->last_infos) | ||
3089 | sf->last_infos = prev; | ||
3090 | sf->num_info--; | ||
3091 | removed++; | ||
3092 | kfree(p); | ||
3093 | } else | ||
3094 | prev = p; | ||
3095 | } | ||
3096 | if (removed) | ||
3097 | rebuild_preset_list(); | ||
3098 | return removed; | ||
3099 | } | ||
3100 | |||
3101 | /* load voice information data */ | ||
3102 | static int | ||
3103 | awe_load_info(awe_patch_info *patch, const char __user *addr, int count) | ||
3104 | { | ||
3105 | int offset; | ||
3106 | awe_voice_rec_hdr hdr; | ||
3107 | int i; | ||
3108 | int total_size; | ||
3109 | sf_list *sf; | ||
3110 | awe_voice_list *rec; | ||
3111 | |||
3112 | if (count < AWE_VOICE_REC_SIZE) { | ||
3113 | printk(KERN_WARNING "AWE32 Error: invalid patch info length\n"); | ||
3114 | return -EINVAL; | ||
3115 | } | ||
3116 | |||
3117 | offset = AWE_PATCH_INFO_SIZE; | ||
3118 | if (copy_from_user((char*)&hdr, addr + offset, AWE_VOICE_REC_SIZE)) | ||
3119 | return -EFAULT; | ||
3120 | offset += AWE_VOICE_REC_SIZE; | ||
3121 | |||
3122 | if (hdr.nvoices <= 0 || hdr.nvoices >= 100) { | ||
3123 | printk(KERN_WARNING "AWE32 Error: Invalid voice number %d\n", hdr.nvoices); | ||
3124 | return -EINVAL; | ||
3125 | } | ||
3126 | total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices; | ||
3127 | if (count < total_size) { | ||
3128 | printk(KERN_WARNING "AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n", | ||
3129 | count, hdr.nvoices); | ||
3130 | return -EINVAL; | ||
3131 | } | ||
3132 | |||
3133 | if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL) | ||
3134 | return -ENOMEM; | ||
3135 | |||
3136 | switch (hdr.write_mode) { | ||
3137 | case AWE_WR_EXCLUSIVE: | ||
3138 | /* exclusive mode - if the instrument already exists, | ||
3139 | return error */ | ||
3140 | for (rec = sf->infos; rec; rec = rec->next) { | ||
3141 | if (rec->type == V_ST_NORMAL && | ||
3142 | rec->bank == hdr.bank && | ||
3143 | rec->instr == hdr.instr) | ||
3144 | return -EINVAL; | ||
3145 | } | ||
3146 | break; | ||
3147 | case AWE_WR_REPLACE: | ||
3148 | /* replace mode - remove the instrument if it already exists */ | ||
3149 | remove_info(sf, hdr.bank, hdr.instr); | ||
3150 | break; | ||
3151 | } | ||
3152 | |||
3153 | /* append new layers */ | ||
3154 | for (i = 0; i < hdr.nvoices; i++) { | ||
3155 | rec = alloc_new_info(); | ||
3156 | if (rec == NULL) | ||
3157 | return -ENOMEM; | ||
3158 | |||
3159 | rec->bank = hdr.bank; | ||
3160 | rec->instr = hdr.instr; | ||
3161 | rec->type = V_ST_NORMAL; | ||
3162 | rec->disabled = FALSE; | ||
3163 | |||
3164 | /* copy awe_voice_info parameters */ | ||
3165 | if (copy_from_user(&rec->v, addr + offset, AWE_VOICE_INFO_SIZE)) { | ||
3166 | kfree(rec); | ||
3167 | return -EFAULT; | ||
3168 | } | ||
3169 | offset += AWE_VOICE_INFO_SIZE; | ||
3170 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
3171 | if (sf && sf->shared) { | ||
3172 | if (info_duplicated(sf, rec)) { | ||
3173 | kfree(rec); | ||
3174 | continue; | ||
3175 | } | ||
3176 | } | ||
3177 | #endif /* allow sharing */ | ||
3178 | if (rec->v.mode & AWE_MODE_INIT_PARM) | ||
3179 | awe_init_voice_parm(&rec->v.parm); | ||
3180 | add_sf_info(sf, rec); | ||
3181 | awe_set_sample(rec); | ||
3182 | add_info_list(rec); | ||
3183 | } | ||
3184 | |||
3185 | return 0; | ||
3186 | } | ||
3187 | |||
3188 | |||
3189 | /* remove instrument layers */ | ||
3190 | static int | ||
3191 | awe_remove_info(awe_patch_info *patch, const char __user *addr, int count) | ||
3192 | { | ||
3193 | unsigned char bank, instr; | ||
3194 | sf_list *sf; | ||
3195 | |||
3196 | if (! patch_opened || (sf = sftail) == NULL) { | ||
3197 | printk(KERN_WARNING "AWE32: remove_info: patch not opened\n"); | ||
3198 | return -EINVAL; | ||
3199 | } | ||
3200 | |||
3201 | bank = ((unsigned short)patch->optarg >> 8) & 0xff; | ||
3202 | instr = (unsigned short)patch->optarg & 0xff; | ||
3203 | if (! remove_info(sf, bank, instr)) | ||
3204 | return -EINVAL; | ||
3205 | return 0; | ||
3206 | } | ||
3207 | |||
3208 | |||
3209 | /* load wave sample data */ | ||
3210 | static int | ||
3211 | awe_load_data(awe_patch_info *patch, const char __user *addr, int count) | ||
3212 | { | ||
3213 | int offset, size; | ||
3214 | int rc; | ||
3215 | awe_sample_info tmprec; | ||
3216 | awe_sample_list *rec; | ||
3217 | sf_list *sf; | ||
3218 | |||
3219 | if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL) | ||
3220 | return -ENOMEM; | ||
3221 | |||
3222 | size = (count - AWE_SAMPLE_INFO_SIZE) / 2; | ||
3223 | offset = AWE_PATCH_INFO_SIZE; | ||
3224 | if (copy_from_user(&tmprec, addr + offset, AWE_SAMPLE_INFO_SIZE)) | ||
3225 | return -EFAULT; | ||
3226 | offset += AWE_SAMPLE_INFO_SIZE; | ||
3227 | if (size != tmprec.size) { | ||
3228 | printk(KERN_WARNING "AWE32: load: sample size differed (%d != %d)\n", | ||
3229 | tmprec.size, size); | ||
3230 | return -EINVAL; | ||
3231 | } | ||
3232 | |||
3233 | if (search_sample_index(sf, tmprec.sample) != NULL) { | ||
3234 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
3235 | /* if shared sample, skip this data */ | ||
3236 | if (sf->type & AWE_PAT_SHARED) | ||
3237 | return 0; | ||
3238 | #endif /* allow sharing */ | ||
3239 | DEBUG(1,printk("AWE32: sample data %d already present\n", tmprec.sample)); | ||
3240 | return -EINVAL; | ||
3241 | } | ||
3242 | |||
3243 | if ((rec = alloc_new_sample()) == NULL) | ||
3244 | return -ENOMEM; | ||
3245 | |||
3246 | memcpy(&rec->v, &tmprec, sizeof(tmprec)); | ||
3247 | |||
3248 | if (rec->v.size > 0) { | ||
3249 | if ((rc = awe_write_wave_data(addr, offset, rec, -1)) < 0) { | ||
3250 | kfree(rec); | ||
3251 | return rc; | ||
3252 | } | ||
3253 | sf->mem_ptr += rc; | ||
3254 | } | ||
3255 | |||
3256 | add_sf_sample(sf, rec); | ||
3257 | return 0; | ||
3258 | } | ||
3259 | |||
3260 | |||
3261 | /* replace wave sample data */ | ||
3262 | static int | ||
3263 | awe_replace_data(awe_patch_info *patch, const char __user *addr, int count) | ||
3264 | { | ||
3265 | int offset; | ||
3266 | int size; | ||
3267 | int rc; | ||
3268 | int channels; | ||
3269 | awe_sample_info cursmp; | ||
3270 | int save_mem_ptr; | ||
3271 | sf_list *sf; | ||
3272 | awe_sample_list *rec; | ||
3273 | |||
3274 | if (! patch_opened || (sf = sftail) == NULL) { | ||
3275 | printk(KERN_WARNING "AWE32: replace: patch not opened\n"); | ||
3276 | return -EINVAL; | ||
3277 | } | ||
3278 | |||
3279 | size = (count - AWE_SAMPLE_INFO_SIZE) / 2; | ||
3280 | offset = AWE_PATCH_INFO_SIZE; | ||
3281 | if (copy_from_user(&cursmp, addr + offset, AWE_SAMPLE_INFO_SIZE)) | ||
3282 | return -EFAULT; | ||
3283 | offset += AWE_SAMPLE_INFO_SIZE; | ||
3284 | if (cursmp.size == 0 || size != cursmp.size) { | ||
3285 | printk(KERN_WARNING "AWE32: replace: invalid sample size (%d!=%d)\n", | ||
3286 | cursmp.size, size); | ||
3287 | return -EINVAL; | ||
3288 | } | ||
3289 | channels = patch->optarg; | ||
3290 | if (channels <= 0 || channels > AWE_NORMAL_VOICES) { | ||
3291 | printk(KERN_WARNING "AWE32: replace: invalid channels %d\n", channels); | ||
3292 | return -EINVAL; | ||
3293 | } | ||
3294 | |||
3295 | for (rec = sf->samples; rec; rec = rec->next) { | ||
3296 | if (rec->v.sample == cursmp.sample) | ||
3297 | break; | ||
3298 | } | ||
3299 | if (rec == NULL) { | ||
3300 | printk(KERN_WARNING "AWE32: replace: cannot find existing sample data %d\n", | ||
3301 | cursmp.sample); | ||
3302 | return -EINVAL; | ||
3303 | } | ||
3304 | |||
3305 | if (rec->v.size != cursmp.size) { | ||
3306 | printk(KERN_WARNING "AWE32: replace: exiting size differed (%d!=%d)\n", | ||
3307 | rec->v.size, cursmp.size); | ||
3308 | return -EINVAL; | ||
3309 | } | ||
3310 | |||
3311 | save_mem_ptr = awe_free_mem_ptr(); | ||
3312 | sftail->mem_ptr = rec->v.start - awe_mem_start; | ||
3313 | memcpy(&rec->v, &cursmp, sizeof(cursmp)); | ||
3314 | rec->v.sf_id = current_sf_id; | ||
3315 | if ((rc = awe_write_wave_data(addr, offset, rec, channels)) < 0) | ||
3316 | return rc; | ||
3317 | sftail->mem_ptr = save_mem_ptr; | ||
3318 | |||
3319 | return 0; | ||
3320 | } | ||
3321 | |||
3322 | |||
3323 | /*----------------------------------------------------------------*/ | ||
3324 | |||
3325 | static const char __user *readbuf_addr; | ||
3326 | static int readbuf_offs; | ||
3327 | static int readbuf_flags; | ||
3328 | |||
3329 | /* initialize read buffer */ | ||
3330 | static int | ||
3331 | readbuf_init(const char __user *addr, int offset, awe_sample_info *sp) | ||
3332 | { | ||
3333 | readbuf_addr = addr; | ||
3334 | readbuf_offs = offset; | ||
3335 | readbuf_flags = sp->mode_flags; | ||
3336 | return 0; | ||
3337 | } | ||
3338 | |||
3339 | /* read directly from user buffer */ | ||
3340 | static unsigned short | ||
3341 | readbuf_word(int pos) | ||
3342 | { | ||
3343 | unsigned short c; | ||
3344 | /* read from user buffer */ | ||
3345 | if (readbuf_flags & AWE_SAMPLE_8BITS) { | ||
3346 | unsigned char cc; | ||
3347 | get_user(cc, (unsigned char __user *)(readbuf_addr + readbuf_offs + pos)); | ||
3348 | c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */ | ||
3349 | } else { | ||
3350 | get_user(c, (unsigned short __user *)(readbuf_addr + readbuf_offs + pos * 2)); | ||
3351 | } | ||
3352 | if (readbuf_flags & AWE_SAMPLE_UNSIGNED) | ||
3353 | c ^= 0x8000; /* unsigned -> signed */ | ||
3354 | return c; | ||
3355 | } | ||
3356 | |||
3357 | #define readbuf_word_cache readbuf_word | ||
3358 | #define readbuf_end() /**/ | ||
3359 | |||
3360 | /*----------------------------------------------------------------*/ | ||
3361 | |||
3362 | #define BLANK_LOOP_START 8 | ||
3363 | #define BLANK_LOOP_END 40 | ||
3364 | #define BLANK_LOOP_SIZE 48 | ||
3365 | |||
3366 | /* loading onto memory - return the actual written size */ | ||
3367 | static int | ||
3368 | awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *list, int channels) | ||
3369 | { | ||
3370 | int i, truesize, dram_offset; | ||
3371 | awe_sample_info *sp = &list->v; | ||
3372 | int rc; | ||
3373 | |||
3374 | /* be sure loop points start < end */ | ||
3375 | if (sp->loopstart > sp->loopend) { | ||
3376 | int tmp = sp->loopstart; | ||
3377 | sp->loopstart = sp->loopend; | ||
3378 | sp->loopend = tmp; | ||
3379 | } | ||
3380 | |||
3381 | /* compute true data size to be loaded */ | ||
3382 | truesize = sp->size; | ||
3383 | if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP)) | ||
3384 | truesize += sp->loopend - sp->loopstart; | ||
3385 | if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) | ||
3386 | truesize += BLANK_LOOP_SIZE; | ||
3387 | if (awe_free_mem_ptr() + truesize >= memsize/2) { | ||
3388 | DEBUG(-1,printk("AWE32 Error: Sample memory full\n")); | ||
3389 | return -ENOSPC; | ||
3390 | } | ||
3391 | |||
3392 | /* recalculate address offset */ | ||
3393 | sp->end -= sp->start; | ||
3394 | sp->loopstart -= sp->start; | ||
3395 | sp->loopend -= sp->start; | ||
3396 | |||
3397 | dram_offset = awe_free_mem_ptr() + awe_mem_start; | ||
3398 | sp->start = dram_offset; | ||
3399 | sp->end += dram_offset; | ||
3400 | sp->loopstart += dram_offset; | ||
3401 | sp->loopend += dram_offset; | ||
3402 | |||
3403 | /* set the total size (store onto obsolete checksum value) */ | ||
3404 | if (sp->size == 0) | ||
3405 | sp->checksum = 0; | ||
3406 | else | ||
3407 | sp->checksum = truesize; | ||
3408 | |||
3409 | if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0) | ||
3410 | return rc; | ||
3411 | |||
3412 | if (readbuf_init(addr, offset, sp) < 0) | ||
3413 | return -ENOSPC; | ||
3414 | |||
3415 | for (i = 0; i < sp->size; i++) { | ||
3416 | unsigned short c; | ||
3417 | c = readbuf_word(i); | ||
3418 | awe_write_dram(c); | ||
3419 | if (i == sp->loopend && | ||
3420 | (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) { | ||
3421 | int looplen = sp->loopend - sp->loopstart; | ||
3422 | /* copy reverse loop */ | ||
3423 | int k; | ||
3424 | for (k = 1; k <= looplen; k++) { | ||
3425 | c = readbuf_word_cache(i - k); | ||
3426 | awe_write_dram(c); | ||
3427 | } | ||
3428 | if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) { | ||
3429 | sp->end += looplen; | ||
3430 | } else { | ||
3431 | sp->start += looplen; | ||
3432 | sp->end += looplen; | ||
3433 | } | ||
3434 | } | ||
3435 | } | ||
3436 | readbuf_end(); | ||
3437 | |||
3438 | /* if no blank loop is attached in the sample, add it */ | ||
3439 | if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) { | ||
3440 | for (i = 0; i < BLANK_LOOP_SIZE; i++) | ||
3441 | awe_write_dram(0); | ||
3442 | if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) { | ||
3443 | sp->loopstart = sp->end + BLANK_LOOP_START; | ||
3444 | sp->loopend = sp->end + BLANK_LOOP_END; | ||
3445 | } | ||
3446 | } | ||
3447 | |||
3448 | awe_close_dram(); | ||
3449 | |||
3450 | /* initialize FM */ | ||
3451 | awe_init_fm(); | ||
3452 | |||
3453 | return truesize; | ||
3454 | } | ||
3455 | |||
3456 | |||
3457 | /*----------------------------------------------------------------*/ | ||
3458 | |||
3459 | #ifdef AWE_HAS_GUS_COMPATIBILITY | ||
3460 | |||
3461 | /* calculate GUS envelope time: | ||
3462 | * is this correct? i have no idea.. | ||
3463 | */ | ||
3464 | static int | ||
3465 | calc_gus_envelope_time(int rate, int start, int end) | ||
3466 | { | ||
3467 | int r, p, t; | ||
3468 | r = (3 - ((rate >> 6) & 3)) * 3; | ||
3469 | p = rate & 0x3f; | ||
3470 | t = end - start; | ||
3471 | if (t < 0) t = -t; | ||
3472 | if (13 > r) | ||
3473 | t = t << (13 - r); | ||
3474 | else | ||
3475 | t = t >> (r - 13); | ||
3476 | return (t * 10) / (p * 441); | ||
3477 | } | ||
3478 | |||
3479 | #define calc_gus_sustain(val) (0x7f - vol_table[(val)/2]) | ||
3480 | #define calc_gus_attenuation(val) vol_table[(val)/2] | ||
3481 | |||
3482 | /* load GUS patch */ | ||
3483 | static int | ||
3484 | awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag) | ||
3485 | { | ||
3486 | struct patch_info patch; | ||
3487 | awe_voice_info *rec; | ||
3488 | awe_sample_info *smp; | ||
3489 | awe_voice_list *vrec; | ||
3490 | awe_sample_list *smprec; | ||
3491 | int sizeof_patch; | ||
3492 | int note, rc; | ||
3493 | sf_list *sf; | ||
3494 | |||
3495 | sizeof_patch = (int)((long)&patch.data[0] - (long)&patch); /* header size */ | ||
3496 | if (size < sizeof_patch) { | ||
3497 | printk(KERN_WARNING "AWE32 Error: Patch header too short\n"); | ||
3498 | return -EINVAL; | ||
3499 | } | ||
3500 | if (copy_from_user(((char*)&patch) + offs, addr + offs, sizeof_patch - offs)) | ||
3501 | return -EFAULT; | ||
3502 | size -= sizeof_patch; | ||
3503 | if (size < patch.len) { | ||
3504 | printk(KERN_WARNING "AWE32 Error: Patch record too short (%d<%d)\n", | ||
3505 | size, patch.len); | ||
3506 | return -EINVAL; | ||
3507 | } | ||
3508 | if ((sf = check_patch_opened(AWE_PAT_TYPE_GUS, NULL)) == NULL) | ||
3509 | return -ENOMEM; | ||
3510 | if ((smprec = alloc_new_sample()) == NULL) | ||
3511 | return -ENOMEM; | ||
3512 | if ((vrec = alloc_new_info()) == NULL) { | ||
3513 | kfree(smprec); | ||
3514 | return -ENOMEM; | ||
3515 | } | ||
3516 | |||
3517 | smp = &smprec->v; | ||
3518 | smp->sample = sf->num_sample; | ||
3519 | smp->start = 0; | ||
3520 | smp->end = patch.len; | ||
3521 | smp->loopstart = patch.loop_start; | ||
3522 | smp->loopend = patch.loop_end; | ||
3523 | smp->size = patch.len; | ||
3524 | |||
3525 | /* set up mode flags */ | ||
3526 | smp->mode_flags = 0; | ||
3527 | if (!(patch.mode & WAVE_16_BITS)) | ||
3528 | smp->mode_flags |= AWE_SAMPLE_8BITS; | ||
3529 | if (patch.mode & WAVE_UNSIGNED) | ||
3530 | smp->mode_flags |= AWE_SAMPLE_UNSIGNED; | ||
3531 | smp->mode_flags |= AWE_SAMPLE_NO_BLANK; | ||
3532 | if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK))) | ||
3533 | smp->mode_flags |= AWE_SAMPLE_SINGLESHOT; | ||
3534 | if (patch.mode & WAVE_BIDIR_LOOP) | ||
3535 | smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP; | ||
3536 | if (patch.mode & WAVE_LOOP_BACK) | ||
3537 | smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP; | ||
3538 | |||
3539 | DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags)); | ||
3540 | if (patch.mode & WAVE_16_BITS) { | ||
3541 | /* convert to word offsets */ | ||
3542 | smp->size /= 2; | ||
3543 | smp->end /= 2; | ||
3544 | smp->loopstart /= 2; | ||
3545 | smp->loopend /= 2; | ||
3546 | } | ||
3547 | smp->checksum_flag = 0; | ||
3548 | smp->checksum = 0; | ||
3549 | |||
3550 | if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0) { | ||
3551 | kfree(vrec); | ||
3552 | return rc; | ||
3553 | } | ||
3554 | sf->mem_ptr += rc; | ||
3555 | add_sf_sample(sf, smprec); | ||
3556 | |||
3557 | /* set up voice info */ | ||
3558 | rec = &vrec->v; | ||
3559 | awe_init_voice_info(rec); | ||
3560 | rec->sample = sf->num_info; /* the last sample */ | ||
3561 | rec->rate_offset = calc_rate_offset(patch.base_freq); | ||
3562 | note = freq_to_note(patch.base_note); | ||
3563 | rec->root = note / 100; | ||
3564 | rec->tune = -(note % 100); | ||
3565 | rec->low = freq_to_note(patch.low_note) / 100; | ||
3566 | rec->high = freq_to_note(patch.high_note) / 100; | ||
3567 | DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n", | ||
3568 | rec->rate_offset, note, | ||
3569 | rec->low, rec->high, | ||
3570 | patch.low_note, patch.high_note)); | ||
3571 | /* panning position; -128 - 127 => 0-127 */ | ||
3572 | rec->pan = (patch.panning + 128) / 2; | ||
3573 | |||
3574 | /* detuning is ignored */ | ||
3575 | /* 6points volume envelope */ | ||
3576 | if (patch.mode & WAVE_ENVELOPES) { | ||
3577 | int attack, hold, decay, release; | ||
3578 | attack = calc_gus_envelope_time | ||
3579 | (patch.env_rate[0], 0, patch.env_offset[0]); | ||
3580 | hold = calc_gus_envelope_time | ||
3581 | (patch.env_rate[1], patch.env_offset[0], | ||
3582 | patch.env_offset[1]); | ||
3583 | decay = calc_gus_envelope_time | ||
3584 | (patch.env_rate[2], patch.env_offset[1], | ||
3585 | patch.env_offset[2]); | ||
3586 | release = calc_gus_envelope_time | ||
3587 | (patch.env_rate[3], patch.env_offset[1], | ||
3588 | patch.env_offset[4]); | ||
3589 | release += calc_gus_envelope_time | ||
3590 | (patch.env_rate[4], patch.env_offset[3], | ||
3591 | patch.env_offset[4]); | ||
3592 | release += calc_gus_envelope_time | ||
3593 | (patch.env_rate[5], patch.env_offset[4], | ||
3594 | patch.env_offset[5]); | ||
3595 | rec->parm.volatkhld = (calc_parm_hold(hold) << 8) | | ||
3596 | calc_parm_attack(attack); | ||
3597 | rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) | | ||
3598 | calc_parm_decay(decay); | ||
3599 | rec->parm.volrelease = 0x8000 | calc_parm_decay(release); | ||
3600 | DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release)); | ||
3601 | rec->attenuation = calc_gus_attenuation(patch.env_offset[0]); | ||
3602 | } | ||
3603 | |||
3604 | /* tremolo effect */ | ||
3605 | if (patch.mode & WAVE_TREMOLO) { | ||
3606 | int rate = (patch.tremolo_rate * 1000 / 38) / 42; | ||
3607 | rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate; | ||
3608 | DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n", | ||
3609 | patch.tremolo_rate, patch.tremolo_depth, | ||
3610 | rec->parm.tremfrq)); | ||
3611 | } | ||
3612 | /* vibrato effect */ | ||
3613 | if (patch.mode & WAVE_VIBRATO) { | ||
3614 | int rate = (patch.vibrato_rate * 1000 / 38) / 42; | ||
3615 | rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate; | ||
3616 | DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n", | ||
3617 | patch.tremolo_rate, patch.tremolo_depth, | ||
3618 | rec->parm.tremfrq)); | ||
3619 | } | ||
3620 | |||
3621 | /* scale_freq, scale_factor, volume, and fractions not implemented */ | ||
3622 | |||
3623 | /* append to the tail of the list */ | ||
3624 | vrec->bank = ctrls[AWE_MD_GUS_BANK]; | ||
3625 | vrec->instr = patch.instr_no; | ||
3626 | vrec->disabled = FALSE; | ||
3627 | vrec->type = V_ST_NORMAL; | ||
3628 | |||
3629 | add_sf_info(sf, vrec); | ||
3630 | add_info_list(vrec); | ||
3631 | |||
3632 | /* set the voice index */ | ||
3633 | awe_set_sample(vrec); | ||
3634 | |||
3635 | return 0; | ||
3636 | } | ||
3637 | |||
3638 | #endif /* AWE_HAS_GUS_COMPATIBILITY */ | ||
3639 | |||
3640 | /* | ||
3641 | * sample and voice list handlers | ||
3642 | */ | ||
3643 | |||
3644 | /* append this to the current sf list */ | ||
3645 | static void add_sf_info(sf_list *sf, awe_voice_list *rec) | ||
3646 | { | ||
3647 | if (sf == NULL) | ||
3648 | return; | ||
3649 | rec->holder = sf; | ||
3650 | rec->v.sf_id = sf->sf_id; | ||
3651 | if (sf->last_infos) | ||
3652 | sf->last_infos->next = rec; | ||
3653 | else | ||
3654 | sf->infos = rec; | ||
3655 | sf->last_infos = rec; | ||
3656 | rec->next = NULL; | ||
3657 | sf->num_info++; | ||
3658 | } | ||
3659 | |||
3660 | /* prepend this sample to sf list */ | ||
3661 | static void add_sf_sample(sf_list *sf, awe_sample_list *rec) | ||
3662 | { | ||
3663 | if (sf == NULL) | ||
3664 | return; | ||
3665 | rec->holder = sf; | ||
3666 | rec->v.sf_id = sf->sf_id; | ||
3667 | if (sf->last_samples) | ||
3668 | sf->last_samples->next = rec; | ||
3669 | else | ||
3670 | sf->samples = rec; | ||
3671 | sf->last_samples = rec; | ||
3672 | rec->next = NULL; | ||
3673 | sf->num_sample++; | ||
3674 | } | ||
3675 | |||
3676 | /* purge the old records which don't belong with the same file id */ | ||
3677 | static void purge_old_list(awe_voice_list *rec, awe_voice_list *next) | ||
3678 | { | ||
3679 | rec->next_instr = next; | ||
3680 | if (rec->bank == AWE_DRUM_BANK) { | ||
3681 | /* remove samples with the same note range */ | ||
3682 | awe_voice_list *cur, *prev = rec; | ||
3683 | int low = rec->v.low; | ||
3684 | int high = rec->v.high; | ||
3685 | for (cur = next; cur; cur = cur->next_instr) { | ||
3686 | if (cur->v.low == low && | ||
3687 | cur->v.high == high && | ||
3688 | ! is_identical_holder(cur->holder, rec->holder)) | ||
3689 | prev->next_instr = cur->next_instr; | ||
3690 | else | ||
3691 | prev = cur; | ||
3692 | } | ||
3693 | } else { | ||
3694 | if (! is_identical_holder(next->holder, rec->holder)) | ||
3695 | /* remove all samples */ | ||
3696 | rec->next_instr = NULL; | ||
3697 | } | ||
3698 | } | ||
3699 | |||
3700 | /* prepend to top of the preset table */ | ||
3701 | static void add_info_list(awe_voice_list *rec) | ||
3702 | { | ||
3703 | awe_voice_list *prev, *cur; | ||
3704 | int key; | ||
3705 | |||
3706 | if (rec->disabled) | ||
3707 | return; | ||
3708 | |||
3709 | key = awe_search_key(rec->bank, rec->instr, rec->v.low); | ||
3710 | prev = NULL; | ||
3711 | for (cur = preset_table[key]; cur; cur = cur->next_bank) { | ||
3712 | /* search the first record with the same bank number */ | ||
3713 | if (cur->instr == rec->instr && cur->bank == rec->bank) { | ||
3714 | /* replace the list with the new record */ | ||
3715 | rec->next_bank = cur->next_bank; | ||
3716 | if (prev) | ||
3717 | prev->next_bank = rec; | ||
3718 | else | ||
3719 | preset_table[key] = rec; | ||
3720 | purge_old_list(rec, cur); | ||
3721 | return; | ||
3722 | } | ||
3723 | prev = cur; | ||
3724 | } | ||
3725 | |||
3726 | /* this is the first bank record.. just add this */ | ||
3727 | rec->next_instr = NULL; | ||
3728 | rec->next_bank = preset_table[key]; | ||
3729 | preset_table[key] = rec; | ||
3730 | } | ||
3731 | |||
3732 | /* remove samples later than the specified sf_id */ | ||
3733 | static void | ||
3734 | awe_remove_samples(int sf_id) | ||
3735 | { | ||
3736 | sf_list *p, *prev; | ||
3737 | |||
3738 | if (sf_id <= 0) { | ||
3739 | awe_reset_samples(); | ||
3740 | return; | ||
3741 | } | ||
3742 | /* already removed? */ | ||
3743 | if (current_sf_id <= sf_id) | ||
3744 | return; | ||
3745 | |||
3746 | for (p = sftail; p; p = prev) { | ||
3747 | if (p->sf_id <= sf_id) | ||
3748 | break; | ||
3749 | prev = p->prev; | ||
3750 | awe_free_sf(p); | ||
3751 | } | ||
3752 | sftail = p; | ||
3753 | if (sftail) { | ||
3754 | sf_id = sftail->sf_id; | ||
3755 | sftail->next = NULL; | ||
3756 | } else { | ||
3757 | sf_id = 0; | ||
3758 | sfhead = NULL; | ||
3759 | } | ||
3760 | current_sf_id = sf_id; | ||
3761 | if (locked_sf_id > sf_id) | ||
3762 | locked_sf_id = sf_id; | ||
3763 | |||
3764 | rebuild_preset_list(); | ||
3765 | } | ||
3766 | |||
3767 | /* rebuild preset search list */ | ||
3768 | static void rebuild_preset_list(void) | ||
3769 | { | ||
3770 | sf_list *p; | ||
3771 | awe_voice_list *rec; | ||
3772 | |||
3773 | memset(preset_table, 0, sizeof(preset_table)); | ||
3774 | |||
3775 | for (p = sfhead; p; p = p->next) { | ||
3776 | for (rec = p->infos; rec; rec = rec->next) | ||
3777 | add_info_list(rec); | ||
3778 | } | ||
3779 | } | ||
3780 | |||
3781 | /* compare the given sf_id pair */ | ||
3782 | static int is_identical_holder(sf_list *sf1, sf_list *sf2) | ||
3783 | { | ||
3784 | if (sf1 == NULL || sf2 == NULL) | ||
3785 | return FALSE; | ||
3786 | if (sf1 == sf2) | ||
3787 | return TRUE; | ||
3788 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
3789 | { | ||
3790 | /* compare with the sharing id */ | ||
3791 | sf_list *p; | ||
3792 | int counter = 0; | ||
3793 | if (sf1->sf_id < sf2->sf_id) { /* make sure id1 > id2 */ | ||
3794 | sf_list *tmp; tmp = sf1; sf1 = sf2; sf2 = tmp; | ||
3795 | } | ||
3796 | for (p = sf1->shared; p; p = p->shared) { | ||
3797 | if (counter++ > current_sf_id) | ||
3798 | break; /* strange sharing loop.. quit */ | ||
3799 | if (p == sf2) | ||
3800 | return TRUE; | ||
3801 | } | ||
3802 | } | ||
3803 | #endif /* allow sharing */ | ||
3804 | return FALSE; | ||
3805 | } | ||
3806 | |||
3807 | /* search the sample index matching with the given sample id */ | ||
3808 | static awe_sample_list * | ||
3809 | search_sample_index(sf_list *sf, int sample) | ||
3810 | { | ||
3811 | awe_sample_list *p; | ||
3812 | #ifdef AWE_ALLOW_SAMPLE_SHARING | ||
3813 | int counter = 0; | ||
3814 | while (sf) { | ||
3815 | for (p = sf->samples; p; p = p->next) { | ||
3816 | if (p->v.sample == sample) | ||
3817 | return p; | ||
3818 | } | ||
3819 | sf = sf->shared; | ||
3820 | if (counter++ > current_sf_id) | ||
3821 | break; /* strange sharing loop.. quit */ | ||
3822 | } | ||
3823 | #else | ||
3824 | if (sf) { | ||
3825 | for (p = sf->samples; p; p = p->next) { | ||
3826 | if (p->v.sample == sample) | ||
3827 | return p; | ||
3828 | } | ||
3829 | } | ||
3830 | #endif | ||
3831 | return NULL; | ||
3832 | } | ||
3833 | |||
3834 | /* search the specified sample */ | ||
3835 | /* non-zero = found */ | ||
3836 | static short | ||
3837 | awe_set_sample(awe_voice_list *rec) | ||
3838 | { | ||
3839 | awe_sample_list *smp; | ||
3840 | awe_voice_info *vp = &rec->v; | ||
3841 | |||
3842 | vp->index = 0; | ||
3843 | if ((smp = search_sample_index(rec->holder, vp->sample)) == NULL) | ||
3844 | return 0; | ||
3845 | |||
3846 | /* set the actual sample offsets */ | ||
3847 | vp->start += smp->v.start; | ||
3848 | vp->end += smp->v.end; | ||
3849 | vp->loopstart += smp->v.loopstart; | ||
3850 | vp->loopend += smp->v.loopend; | ||
3851 | /* copy mode flags */ | ||
3852 | vp->mode = smp->v.mode_flags; | ||
3853 | /* set flag */ | ||
3854 | vp->index = 1; | ||
3855 | |||
3856 | return 1; | ||
3857 | } | ||
3858 | |||
3859 | |||
3860 | /* | ||
3861 | * voice allocation | ||
3862 | */ | ||
3863 | |||
3864 | /* look for all voices associated with the specified note & velocity */ | ||
3865 | static int | ||
3866 | awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, | ||
3867 | awe_voice_info **vlist) | ||
3868 | { | ||
3869 | int nvoices; | ||
3870 | |||
3871 | nvoices = 0; | ||
3872 | for (; rec; rec = rec->next_instr) { | ||
3873 | if (note >= rec->v.low && | ||
3874 | note <= rec->v.high && | ||
3875 | velocity >= rec->v.vellow && | ||
3876 | velocity <= rec->v.velhigh) { | ||
3877 | if (rec->type == V_ST_MAPPED) { | ||
3878 | /* mapper */ | ||
3879 | vlist[0] = &rec->v; | ||
3880 | return -1; | ||
3881 | } | ||
3882 | vlist[nvoices++] = &rec->v; | ||
3883 | if (nvoices >= AWE_MAX_VOICES) | ||
3884 | break; | ||
3885 | } | ||
3886 | } | ||
3887 | return nvoices; | ||
3888 | } | ||
3889 | |||
3890 | /* store the voice list from the specified note and velocity. | ||
3891 | if the preset is mapped, seek for the destination preset, and rewrite | ||
3892 | the note number if necessary. | ||
3893 | */ | ||
3894 | static int | ||
3895 | really_alloc_voices(int bank, int instr, int *note, int velocity, awe_voice_info **vlist) | ||
3896 | { | ||
3897 | int nvoices; | ||
3898 | awe_voice_list *vrec; | ||
3899 | int level = 0; | ||
3900 | |||
3901 | for (;;) { | ||
3902 | vrec = awe_search_instr(bank, instr, *note); | ||
3903 | nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist); | ||
3904 | if (nvoices == 0) { | ||
3905 | if (bank == AWE_DRUM_BANK) | ||
3906 | /* search default drumset */ | ||
3907 | vrec = awe_search_instr(bank, ctrls[AWE_MD_DEF_DRUM], *note); | ||
3908 | else | ||
3909 | /* search default preset */ | ||
3910 | vrec = awe_search_instr(ctrls[AWE_MD_DEF_BANK], instr, *note); | ||
3911 | nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist); | ||
3912 | } | ||
3913 | if (nvoices == 0) { | ||
3914 | if (bank == AWE_DRUM_BANK && ctrls[AWE_MD_DEF_DRUM] != 0) | ||
3915 | /* search default drumset */ | ||
3916 | vrec = awe_search_instr(bank, 0, *note); | ||
3917 | else if (bank != AWE_DRUM_BANK && ctrls[AWE_MD_DEF_BANK] != 0) | ||
3918 | /* search default preset */ | ||
3919 | vrec = awe_search_instr(0, instr, *note); | ||
3920 | nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist); | ||
3921 | } | ||
3922 | if (nvoices < 0) { /* mapping */ | ||
3923 | int key = vlist[0]->fixkey; | ||
3924 | instr = vlist[0]->start; | ||
3925 | bank = vlist[0]->end; | ||
3926 | if (level++ > 5) { | ||
3927 | printk(KERN_ERR "AWE32: too deep mapping level\n"); | ||
3928 | return 0; | ||
3929 | } | ||
3930 | if (key >= 0) | ||
3931 | *note = key; | ||
3932 | } else | ||
3933 | break; | ||
3934 | } | ||
3935 | |||
3936 | return nvoices; | ||
3937 | } | ||
3938 | |||
3939 | /* allocate voices corresponding note and velocity; supports multiple insts. */ | ||
3940 | static void | ||
3941 | awe_alloc_multi_voices(int ch, int note, int velocity, int key) | ||
3942 | { | ||
3943 | int i, v, nvoices, bank; | ||
3944 | awe_voice_info *vlist[AWE_MAX_VOICES]; | ||
3945 | |||
3946 | if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) | ||
3947 | bank = AWE_DRUM_BANK; /* always search drumset */ | ||
3948 | else | ||
3949 | bank = channels[ch].bank; | ||
3950 | |||
3951 | /* check the possible voices; note may be changeable if mapped */ | ||
3952 | nvoices = really_alloc_voices(bank, channels[ch].instr, | ||
3953 | ¬e, velocity, vlist); | ||
3954 | |||
3955 | /* set the voices */ | ||
3956 | current_alloc_time++; | ||
3957 | for (i = 0; i < nvoices; i++) { | ||
3958 | v = awe_clear_voice(); | ||
3959 | voices[v].key = key; | ||
3960 | voices[v].ch = ch; | ||
3961 | voices[v].note = note; | ||
3962 | voices[v].velocity = velocity; | ||
3963 | voices[v].time = current_alloc_time; | ||
3964 | voices[v].cinfo = &channels[ch]; | ||
3965 | voices[v].sample = vlist[i]; | ||
3966 | voices[v].state = AWE_ST_MARK; | ||
3967 | voices[v].layer = nvoices - i - 1; /* in reverse order */ | ||
3968 | } | ||
3969 | |||
3970 | /* clear the mark in allocated voices */ | ||
3971 | for (i = 0; i < awe_max_voices; i++) { | ||
3972 | if (voices[i].state == AWE_ST_MARK) | ||
3973 | voices[i].state = AWE_ST_OFF; | ||
3974 | |||
3975 | } | ||
3976 | } | ||
3977 | |||
3978 | |||
3979 | /* search an empty voice. | ||
3980 | if no empty voice is found, at least terminate a voice | ||
3981 | */ | ||
3982 | static int | ||
3983 | awe_clear_voice(void) | ||
3984 | { | ||
3985 | enum { | ||
3986 | OFF=0, RELEASED, SUSTAINED, PLAYING, END | ||
3987 | }; | ||
3988 | struct voice_candidate_t { | ||
3989 | int best; | ||
3990 | int time; | ||
3991 | int vtarget; | ||
3992 | } candidate[END]; | ||
3993 | int i, type, vtarget; | ||
3994 | |||
3995 | vtarget = 0xffff; | ||
3996 | for (type = OFF; type < END; type++) { | ||
3997 | candidate[type].best = -1; | ||
3998 | candidate[type].time = current_alloc_time + 1; | ||
3999 | candidate[type].vtarget = vtarget; | ||
4000 | } | ||
4001 | |||
4002 | for (i = 0; i < awe_max_voices; i++) { | ||
4003 | if (voices[i].state & AWE_ST_OFF) | ||
4004 | type = OFF; | ||
4005 | else if (voices[i].state & AWE_ST_RELEASED) | ||
4006 | type = RELEASED; | ||
4007 | else if (voices[i].state & AWE_ST_SUSTAINED) | ||
4008 | type = SUSTAINED; | ||
4009 | else if (voices[i].state & ~AWE_ST_MARK) | ||
4010 | type = PLAYING; | ||
4011 | else | ||
4012 | continue; | ||
4013 | #ifdef AWE_CHECK_VTARGET | ||
4014 | /* get current volume */ | ||
4015 | vtarget = (awe_peek_dw(AWE_VTFT(i)) >> 16) & 0xffff; | ||
4016 | #endif | ||
4017 | if (candidate[type].best < 0 || | ||
4018 | vtarget < candidate[type].vtarget || | ||
4019 | (vtarget == candidate[type].vtarget && | ||
4020 | voices[i].time < candidate[type].time)) { | ||
4021 | candidate[type].best = i; | ||
4022 | candidate[type].time = voices[i].time; | ||
4023 | candidate[type].vtarget = vtarget; | ||
4024 | } | ||
4025 | } | ||
4026 | |||
4027 | for (type = OFF; type < END; type++) { | ||
4028 | if ((i = candidate[type].best) >= 0) { | ||
4029 | if (voices[i].state != AWE_ST_OFF) | ||
4030 | awe_terminate(i); | ||
4031 | awe_voice_init(i, TRUE); | ||
4032 | return i; | ||
4033 | } | ||
4034 | } | ||
4035 | return 0; | ||
4036 | } | ||
4037 | |||
4038 | |||
4039 | /* search sample for the specified note & velocity and set it on the voice; | ||
4040 | * note that voice is the voice index (not channel index) | ||
4041 | */ | ||
4042 | static void | ||
4043 | awe_alloc_one_voice(int voice, int note, int velocity) | ||
4044 | { | ||
4045 | int ch, nvoices, bank; | ||
4046 | awe_voice_info *vlist[AWE_MAX_VOICES]; | ||
4047 | |||
4048 | ch = voices[voice].ch; | ||
4049 | if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice)) | ||
4050 | bank = AWE_DRUM_BANK; /* always search drumset */ | ||
4051 | else | ||
4052 | bank = voices[voice].cinfo->bank; | ||
4053 | |||
4054 | nvoices = really_alloc_voices(bank, voices[voice].cinfo->instr, | ||
4055 | ¬e, velocity, vlist); | ||
4056 | if (nvoices > 0) { | ||
4057 | voices[voice].time = ++current_alloc_time; | ||
4058 | voices[voice].sample = vlist[0]; /* use the first one */ | ||
4059 | voices[voice].layer = 0; | ||
4060 | voices[voice].note = note; | ||
4061 | voices[voice].velocity = velocity; | ||
4062 | } | ||
4063 | } | ||
4064 | |||
4065 | |||
4066 | /* | ||
4067 | * sequencer2 functions | ||
4068 | */ | ||
4069 | |||
4070 | /* search an empty voice; used by sequencer2 */ | ||
4071 | static int | ||
4072 | awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc) | ||
4073 | { | ||
4074 | playing_mode = AWE_PLAY_MULTI2; | ||
4075 | awe_info.nr_voices = AWE_MAX_CHANNELS; | ||
4076 | return awe_clear_voice(); | ||
4077 | } | ||
4078 | |||
4079 | |||
4080 | /* set up voice; used by sequencer2 */ | ||
4081 | static void | ||
4082 | awe_setup_voice(int dev, int voice, int chn) | ||
4083 | { | ||
4084 | struct channel_info *info; | ||
4085 | if (synth_devs[dev] == NULL || | ||
4086 | (info = &synth_devs[dev]->chn_info[chn]) == NULL) | ||
4087 | return; | ||
4088 | |||
4089 | if (voice < 0 || voice >= awe_max_voices) | ||
4090 | return; | ||
4091 | |||
4092 | DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn)); | ||
4093 | channels[chn].expression_vol = info->controllers[CTL_EXPRESSION]; | ||
4094 | channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME]; | ||
4095 | channels[chn].panning = | ||
4096 | info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */ | ||
4097 | channels[chn].bender = info->bender_value; /* zero center */ | ||
4098 | channels[chn].bank = info->controllers[CTL_BANK_SELECT]; | ||
4099 | channels[chn].sustained = info->controllers[CTL_SUSTAIN]; | ||
4100 | if (info->controllers[CTL_EXT_EFF_DEPTH]) { | ||
4101 | FX_SET(&channels[chn].fx, AWE_FX_REVERB, | ||
4102 | info->controllers[CTL_EXT_EFF_DEPTH] * 2); | ||
4103 | } | ||
4104 | if (info->controllers[CTL_CHORUS_DEPTH]) { | ||
4105 | FX_SET(&channels[chn].fx, AWE_FX_CHORUS, | ||
4106 | info->controllers[CTL_CHORUS_DEPTH] * 2); | ||
4107 | } | ||
4108 | awe_set_instr(dev, chn, info->pgm_num); | ||
4109 | } | ||
4110 | |||
4111 | |||
4112 | #ifdef CONFIG_AWE32_MIXER | ||
4113 | /* | ||
4114 | * AWE32 mixer device control | ||
4115 | */ | ||
4116 | |||
4117 | static int awe_mixer_ioctl(int dev, unsigned int cmd, void __user *arg); | ||
4118 | |||
4119 | static int my_mixerdev = -1; | ||
4120 | |||
4121 | static struct mixer_operations awe_mixer_operations = { | ||
4122 | .owner = THIS_MODULE, | ||
4123 | .id = "AWE", | ||
4124 | .name = "AWE32 Equalizer", | ||
4125 | .ioctl = awe_mixer_ioctl, | ||
4126 | }; | ||
4127 | |||
4128 | static void __init attach_mixer(void) | ||
4129 | { | ||
4130 | if ((my_mixerdev = sound_alloc_mixerdev()) >= 0) { | ||
4131 | mixer_devs[my_mixerdev] = &awe_mixer_operations; | ||
4132 | } | ||
4133 | } | ||
4134 | |||
4135 | static void unload_mixer(void) | ||
4136 | { | ||
4137 | if (my_mixerdev >= 0) | ||
4138 | sound_unload_mixerdev(my_mixerdev); | ||
4139 | } | ||
4140 | |||
4141 | static int | ||
4142 | awe_mixer_ioctl(int dev, unsigned int cmd, void __user * arg) | ||
4143 | { | ||
4144 | int i, level, value; | ||
4145 | |||
4146 | if (((cmd >> 8) & 0xff) != 'M') | ||
4147 | return -EINVAL; | ||
4148 | |||
4149 | if (get_user(level, (int __user *)arg)) | ||
4150 | return -EFAULT; | ||
4151 | level = ((level & 0xff) + (level >> 8)) / 2; | ||
4152 | DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level)); | ||
4153 | |||
4154 | if (_SIOC_DIR(cmd) & _SIOC_WRITE) { | ||
4155 | switch (cmd & 0xff) { | ||
4156 | case SOUND_MIXER_BASS: | ||
4157 | value = level * 12 / 100; | ||
4158 | if (value >= 12) | ||
4159 | value = 11; | ||
4160 | ctrls[AWE_MD_BASS_LEVEL] = value; | ||
4161 | awe_update_equalizer(); | ||
4162 | break; | ||
4163 | case SOUND_MIXER_TREBLE: | ||
4164 | value = level * 12 / 100; | ||
4165 | if (value >= 12) | ||
4166 | value = 11; | ||
4167 | ctrls[AWE_MD_TREBLE_LEVEL] = value; | ||
4168 | awe_update_equalizer(); | ||
4169 | break; | ||
4170 | case SOUND_MIXER_VOLUME: | ||
4171 | level = level * 127 / 100; | ||
4172 | if (level >= 128) level = 127; | ||
4173 | atten_relative = FALSE; | ||
4174 | atten_offset = vol_table[level]; | ||
4175 | awe_update_volume(); | ||
4176 | break; | ||
4177 | } | ||
4178 | } | ||
4179 | switch (cmd & 0xff) { | ||
4180 | case SOUND_MIXER_BASS: | ||
4181 | level = ctrls[AWE_MD_BASS_LEVEL] * 100 / 24; | ||
4182 | level = (level << 8) | level; | ||
4183 | break; | ||
4184 | case SOUND_MIXER_TREBLE: | ||
4185 | level = ctrls[AWE_MD_TREBLE_LEVEL] * 100 / 24; | ||
4186 | level = (level << 8) | level; | ||
4187 | break; | ||
4188 | case SOUND_MIXER_VOLUME: | ||
4189 | value = atten_offset; | ||
4190 | if (atten_relative) | ||
4191 | value += ctrls[AWE_MD_ZERO_ATTEN]; | ||
4192 | for (i = 127; i > 0; i--) { | ||
4193 | if (value <= vol_table[i]) | ||
4194 | break; | ||
4195 | } | ||
4196 | level = i * 100 / 127; | ||
4197 | level = (level << 8) | level; | ||
4198 | break; | ||
4199 | case SOUND_MIXER_DEVMASK: | ||
4200 | level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME; | ||
4201 | break; | ||
4202 | default: | ||
4203 | level = 0; | ||
4204 | break; | ||
4205 | } | ||
4206 | if (put_user(level, (int __user *)arg)) | ||
4207 | return -EFAULT; | ||
4208 | return level; | ||
4209 | } | ||
4210 | #endif /* CONFIG_AWE32_MIXER */ | ||
4211 | |||
4212 | |||
4213 | /* | ||
4214 | * initialization of Emu8000 | ||
4215 | */ | ||
4216 | |||
4217 | /* intiailize audio channels */ | ||
4218 | static void | ||
4219 | awe_init_audio(void) | ||
4220 | { | ||
4221 | int ch; | ||
4222 | |||
4223 | /* turn off envelope engines */ | ||
4224 | for (ch = 0; ch < AWE_MAX_VOICES; ch++) { | ||
4225 | awe_poke(AWE_DCYSUSV(ch), 0x80); | ||
4226 | } | ||
4227 | |||
4228 | /* reset all other parameters to zero */ | ||
4229 | for (ch = 0; ch < AWE_MAX_VOICES; ch++) { | ||
4230 | awe_poke(AWE_ENVVOL(ch), 0); | ||
4231 | awe_poke(AWE_ENVVAL(ch), 0); | ||
4232 | awe_poke(AWE_DCYSUS(ch), 0); | ||
4233 | awe_poke(AWE_ATKHLDV(ch), 0); | ||
4234 | awe_poke(AWE_LFO1VAL(ch), 0); | ||
4235 | awe_poke(AWE_ATKHLD(ch), 0); | ||
4236 | awe_poke(AWE_LFO2VAL(ch), 0); | ||
4237 | awe_poke(AWE_IP(ch), 0); | ||
4238 | awe_poke(AWE_IFATN(ch), 0); | ||
4239 | awe_poke(AWE_PEFE(ch), 0); | ||
4240 | awe_poke(AWE_FMMOD(ch), 0); | ||
4241 | awe_poke(AWE_TREMFRQ(ch), 0); | ||
4242 | awe_poke(AWE_FM2FRQ2(ch), 0); | ||
4243 | awe_poke_dw(AWE_PTRX(ch), 0); | ||
4244 | awe_poke_dw(AWE_VTFT(ch), 0); | ||
4245 | awe_poke_dw(AWE_PSST(ch), 0); | ||
4246 | awe_poke_dw(AWE_CSL(ch), 0); | ||
4247 | awe_poke_dw(AWE_CCCA(ch), 0); | ||
4248 | } | ||
4249 | |||
4250 | for (ch = 0; ch < AWE_MAX_VOICES; ch++) { | ||
4251 | awe_poke_dw(AWE_CPF(ch), 0); | ||
4252 | awe_poke_dw(AWE_CVCF(ch), 0); | ||
4253 | } | ||
4254 | } | ||
4255 | |||
4256 | |||
4257 | /* initialize DMA address */ | ||
4258 | static void | ||
4259 | awe_init_dma(void) | ||
4260 | { | ||
4261 | awe_poke_dw(AWE_SMALR, 0); | ||
4262 | awe_poke_dw(AWE_SMARR, 0); | ||
4263 | awe_poke_dw(AWE_SMALW, 0); | ||
4264 | awe_poke_dw(AWE_SMARW, 0); | ||
4265 | } | ||
4266 | |||
4267 | |||
4268 | /* initialization arrays; from ADIP */ | ||
4269 | |||
4270 | static unsigned short init1[128] = { | ||
4271 | 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330, | ||
4272 | 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730, | ||
4273 | 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30, | ||
4274 | 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30, | ||
4275 | |||
4276 | 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330, | ||
4277 | 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730, | ||
4278 | 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30, | ||
4279 | 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30, | ||
4280 | |||
4281 | 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330, | ||
4282 | 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730, | ||
4283 | 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30, | ||
4284 | 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30, | ||
4285 | |||
4286 | 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330, | ||
4287 | 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730, | ||
4288 | 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30, | ||
4289 | 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30, | ||
4290 | }; | ||
4291 | |||
4292 | static unsigned short init2[128] = { | ||
4293 | 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330, | ||
4294 | 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730, | ||
4295 | 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30, | ||
4296 | 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30, | ||
4297 | |||
4298 | 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330, | ||
4299 | 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730, | ||
4300 | 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30, | ||
4301 | 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30, | ||
4302 | |||
4303 | 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330, | ||
4304 | 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730, | ||
4305 | 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30, | ||
4306 | 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30, | ||
4307 | |||
4308 | 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330, | ||
4309 | 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730, | ||
4310 | 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30, | ||
4311 | 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30, | ||
4312 | }; | ||
4313 | |||
4314 | static unsigned short init3[128] = { | ||
4315 | 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5, | ||
4316 | 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254, | ||
4317 | 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234, | ||
4318 | 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224, | ||
4319 | |||
4320 | 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254, | ||
4321 | 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264, | ||
4322 | 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294, | ||
4323 | 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3, | ||
4324 | |||
4325 | 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287, | ||
4326 | 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7, | ||
4327 | 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386, | ||
4328 | 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55, | ||
4329 | |||
4330 | 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308, | ||
4331 | 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F, | ||
4332 | 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319, | ||
4333 | 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570, | ||
4334 | }; | ||
4335 | |||
4336 | static unsigned short init4[128] = { | ||
4337 | 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5, | ||
4338 | 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254, | ||
4339 | 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234, | ||
4340 | 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224, | ||
4341 | |||
4342 | 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254, | ||
4343 | 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264, | ||
4344 | 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294, | ||
4345 | 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3, | ||
4346 | |||
4347 | 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287, | ||
4348 | 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7, | ||
4349 | 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386, | ||
4350 | 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55, | ||
4351 | |||
4352 | 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308, | ||
4353 | 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F, | ||
4354 | 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319, | ||
4355 | 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570, | ||
4356 | }; | ||
4357 | |||
4358 | |||
4359 | /* send initialization arrays to start up */ | ||
4360 | static void | ||
4361 | awe_init_array(void) | ||
4362 | { | ||
4363 | awe_send_array(init1); | ||
4364 | awe_wait(1024); | ||
4365 | awe_send_array(init2); | ||
4366 | awe_send_array(init3); | ||
4367 | awe_poke_dw(AWE_HWCF4, 0); | ||
4368 | awe_poke_dw(AWE_HWCF5, 0x83); | ||
4369 | awe_poke_dw(AWE_HWCF6, 0x8000); | ||
4370 | awe_send_array(init4); | ||
4371 | } | ||
4372 | |||
4373 | /* send an initialization array */ | ||
4374 | static void | ||
4375 | awe_send_array(unsigned short *data) | ||
4376 | { | ||
4377 | int i; | ||
4378 | unsigned short *p; | ||
4379 | |||
4380 | p = data; | ||
4381 | for (i = 0; i < AWE_MAX_VOICES; i++, p++) | ||
4382 | awe_poke(AWE_INIT1(i), *p); | ||
4383 | for (i = 0; i < AWE_MAX_VOICES; i++, p++) | ||
4384 | awe_poke(AWE_INIT2(i), *p); | ||
4385 | for (i = 0; i < AWE_MAX_VOICES; i++, p++) | ||
4386 | awe_poke(AWE_INIT3(i), *p); | ||
4387 | for (i = 0; i < AWE_MAX_VOICES; i++, p++) | ||
4388 | awe_poke(AWE_INIT4(i), *p); | ||
4389 | } | ||
4390 | |||
4391 | |||
4392 | /* | ||
4393 | * set up awe32 channels to some known state. | ||
4394 | */ | ||
4395 | |||
4396 | /* set the envelope & LFO parameters to the default values; see ADIP */ | ||
4397 | static void | ||
4398 | awe_tweak_voice(int i) | ||
4399 | { | ||
4400 | /* set all mod/vol envelope shape to minimum */ | ||
4401 | awe_poke(AWE_ENVVOL(i), 0x8000); | ||
4402 | awe_poke(AWE_ENVVAL(i), 0x8000); | ||
4403 | awe_poke(AWE_DCYSUS(i), 0x7F7F); | ||
4404 | awe_poke(AWE_ATKHLDV(i), 0x7F7F); | ||
4405 | awe_poke(AWE_ATKHLD(i), 0x7F7F); | ||
4406 | awe_poke(AWE_PEFE(i), 0); /* mod envelope height to zero */ | ||
4407 | awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */ | ||
4408 | awe_poke(AWE_LFO2VAL(i), 0x8000); | ||
4409 | awe_poke(AWE_IP(i), 0xE000); /* no pitch shift */ | ||
4410 | awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */ | ||
4411 | awe_poke(AWE_FMMOD(i), 0); | ||
4412 | awe_poke(AWE_TREMFRQ(i), 0); | ||
4413 | awe_poke(AWE_FM2FRQ2(i), 0); | ||
4414 | } | ||
4415 | |||
4416 | static void | ||
4417 | awe_tweak(void) | ||
4418 | { | ||
4419 | int i; | ||
4420 | /* reset all channels */ | ||
4421 | for (i = 0; i < awe_max_voices; i++) | ||
4422 | awe_tweak_voice(i); | ||
4423 | } | ||
4424 | |||
4425 | |||
4426 | /* | ||
4427 | * initializes the FM section of AWE32; | ||
4428 | * see Vince Vu's unofficial AWE32 programming guide | ||
4429 | */ | ||
4430 | |||
4431 | static void | ||
4432 | awe_init_fm(void) | ||
4433 | { | ||
4434 | #ifndef AWE_ALWAYS_INIT_FM | ||
4435 | /* if no extended memory is on board.. */ | ||
4436 | if (memsize <= 0) | ||
4437 | return; | ||
4438 | #endif | ||
4439 | DEBUG(3,printk("AWE32: initializing FM\n")); | ||
4440 | |||
4441 | /* Initialize the last two channels for DRAM refresh and producing | ||
4442 | the reverb and chorus effects for Yamaha OPL-3 synthesizer */ | ||
4443 | |||
4444 | /* 31: FM left channel, 0xffffe0-0xffffe8 */ | ||
4445 | awe_poke(AWE_DCYSUSV(30), 0x80); | ||
4446 | awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */ | ||
4447 | awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 | | ||
4448 | (DEF_FM_CHORUS_DEPTH << 24)); | ||
4449 | awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8)); | ||
4450 | awe_poke_dw(AWE_CPF(30), 0); | ||
4451 | awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3); | ||
4452 | |||
4453 | /* 32: FM right channel, 0xfffff0-0xfffff8 */ | ||
4454 | awe_poke(AWE_DCYSUSV(31), 0x80); | ||
4455 | awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */ | ||
4456 | awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 | | ||
4457 | (DEF_FM_CHORUS_DEPTH << 24)); | ||
4458 | awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8)); | ||
4459 | awe_poke_dw(AWE_CPF(31), 0x8000); | ||
4460 | awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3); | ||
4461 | |||
4462 | /* skew volume & cutoff */ | ||
4463 | awe_poke_dw(AWE_VTFT(30), 0x8000FFFF); | ||
4464 | awe_poke_dw(AWE_VTFT(31), 0x8000FFFF); | ||
4465 | |||
4466 | voices[30].state = AWE_ST_FM; | ||
4467 | voices[31].state = AWE_ST_FM; | ||
4468 | |||
4469 | /* change maximum channels to 30 */ | ||
4470 | awe_max_voices = AWE_NORMAL_VOICES; | ||
4471 | if (playing_mode == AWE_PLAY_DIRECT) | ||
4472 | awe_info.nr_voices = awe_max_voices; | ||
4473 | else | ||
4474 | awe_info.nr_voices = AWE_MAX_CHANNELS; | ||
4475 | voice_alloc->max_voice = awe_max_voices; | ||
4476 | } | ||
4477 | |||
4478 | /* | ||
4479 | * AWE32 DRAM access routines | ||
4480 | */ | ||
4481 | |||
4482 | /* open DRAM write accessing mode */ | ||
4483 | static int | ||
4484 | awe_open_dram_for_write(int offset, int channels) | ||
4485 | { | ||
4486 | int vidx[AWE_NORMAL_VOICES]; | ||
4487 | int i; | ||
4488 | |||
4489 | if (channels < 0 || channels >= AWE_NORMAL_VOICES) { | ||
4490 | channels = AWE_NORMAL_VOICES; | ||
4491 | for (i = 0; i < AWE_NORMAL_VOICES; i++) | ||
4492 | vidx[i] = i; | ||
4493 | } else { | ||
4494 | for (i = 0; i < channels; i++) { | ||
4495 | vidx[i] = awe_clear_voice(); | ||
4496 | voices[vidx[i]].state = AWE_ST_MARK; | ||
4497 | } | ||
4498 | } | ||
4499 | |||
4500 | /* use all channels for DMA transfer */ | ||
4501 | for (i = 0; i < channels; i++) { | ||
4502 | if (vidx[i] < 0) continue; | ||
4503 | awe_poke(AWE_DCYSUSV(vidx[i]), 0x80); | ||
4504 | awe_poke_dw(AWE_VTFT(vidx[i]), 0); | ||
4505 | awe_poke_dw(AWE_CVCF(vidx[i]), 0); | ||
4506 | awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000); | ||
4507 | awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000); | ||
4508 | awe_poke_dw(AWE_PSST(vidx[i]), 0); | ||
4509 | awe_poke_dw(AWE_CSL(vidx[i]), 0); | ||
4510 | awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000); | ||
4511 | voices[vidx[i]].state = AWE_ST_DRAM; | ||
4512 | } | ||
4513 | /* point channels 31 & 32 to ROM samples for DRAM refresh */ | ||
4514 | awe_poke_dw(AWE_VTFT(30), 0); | ||
4515 | awe_poke_dw(AWE_PSST(30), 0x1d8); | ||
4516 | awe_poke_dw(AWE_CSL(30), 0x1e0); | ||
4517 | awe_poke_dw(AWE_CCCA(30), 0x1d8); | ||
4518 | awe_poke_dw(AWE_VTFT(31), 0); | ||
4519 | awe_poke_dw(AWE_PSST(31), 0x1d8); | ||
4520 | awe_poke_dw(AWE_CSL(31), 0x1e0); | ||
4521 | awe_poke_dw(AWE_CCCA(31), 0x1d8); | ||
4522 | voices[30].state = AWE_ST_FM; | ||
4523 | voices[31].state = AWE_ST_FM; | ||
4524 | |||
4525 | /* if full bit is on, not ready to write on */ | ||
4526 | if (awe_peek_dw(AWE_SMALW) & 0x80000000) { | ||
4527 | for (i = 0; i < channels; i++) { | ||
4528 | awe_poke_dw(AWE_CCCA(vidx[i]), 0); | ||
4529 | voices[vidx[i]].state = AWE_ST_OFF; | ||
4530 | } | ||
4531 | printk("awe: not ready to write..\n"); | ||
4532 | return -EPERM; | ||
4533 | } | ||
4534 | |||
4535 | /* set address to write */ | ||
4536 | awe_poke_dw(AWE_SMALW, offset); | ||
4537 | |||
4538 | return 0; | ||
4539 | } | ||
4540 | |||
4541 | /* open DRAM for RAM size detection */ | ||
4542 | static void | ||
4543 | awe_open_dram_for_check(void) | ||
4544 | { | ||
4545 | int i; | ||
4546 | for (i = 0; i < AWE_NORMAL_VOICES; i++) { | ||
4547 | awe_poke(AWE_DCYSUSV(i), 0x80); | ||
4548 | awe_poke_dw(AWE_VTFT(i), 0); | ||
4549 | awe_poke_dw(AWE_CVCF(i), 0); | ||
4550 | awe_poke_dw(AWE_PTRX(i), 0x40000000); | ||
4551 | awe_poke_dw(AWE_CPF(i), 0x40000000); | ||
4552 | awe_poke_dw(AWE_PSST(i), 0); | ||
4553 | awe_poke_dw(AWE_CSL(i), 0); | ||
4554 | if (i & 1) /* DMA write */ | ||
4555 | awe_poke_dw(AWE_CCCA(i), 0x06000000); | ||
4556 | else /* DMA read */ | ||
4557 | awe_poke_dw(AWE_CCCA(i), 0x04000000); | ||
4558 | voices[i].state = AWE_ST_DRAM; | ||
4559 | } | ||
4560 | } | ||
4561 | |||
4562 | |||
4563 | /* close dram access */ | ||
4564 | static void | ||
4565 | awe_close_dram(void) | ||
4566 | { | ||
4567 | int i; | ||
4568 | /* wait until FULL bit in SMAxW register be false */ | ||
4569 | for (i = 0; i < 10000; i++) { | ||
4570 | if (!(awe_peek_dw(AWE_SMALW) & 0x80000000)) | ||
4571 | break; | ||
4572 | awe_wait(10); | ||
4573 | } | ||
4574 | |||
4575 | for (i = 0; i < AWE_NORMAL_VOICES; i++) { | ||
4576 | if (voices[i].state == AWE_ST_DRAM) { | ||
4577 | awe_poke_dw(AWE_CCCA(i), 0); | ||
4578 | awe_poke(AWE_DCYSUSV(i), 0x807F); | ||
4579 | voices[i].state = AWE_ST_OFF; | ||
4580 | } | ||
4581 | } | ||
4582 | } | ||
4583 | |||
4584 | |||
4585 | /* | ||
4586 | * check dram size on AWE board | ||
4587 | */ | ||
4588 | |||
4589 | /* any three numbers you like */ | ||
4590 | #define UNIQUE_ID1 0x1234 | ||
4591 | #define UNIQUE_ID2 0x4321 | ||
4592 | #define UNIQUE_ID3 0xABCD | ||
4593 | |||
4594 | static void __init | ||
4595 | awe_check_dram(void) | ||
4596 | { | ||
4597 | if (awe_present) /* already initialized */ | ||
4598 | return; | ||
4599 | |||
4600 | if (memsize >= 0) { /* given by config file or module option */ | ||
4601 | memsize *= 1024; /* convert to Kbytes */ | ||
4602 | return; | ||
4603 | } | ||
4604 | |||
4605 | awe_open_dram_for_check(); | ||
4606 | |||
4607 | memsize = 0; | ||
4608 | |||
4609 | /* set up unique two id numbers */ | ||
4610 | awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET); | ||
4611 | awe_poke(AWE_SMLD, UNIQUE_ID1); | ||
4612 | awe_poke(AWE_SMLD, UNIQUE_ID2); | ||
4613 | |||
4614 | while (memsize < AWE_MAX_DRAM_SIZE) { | ||
4615 | awe_wait(5); | ||
4616 | /* read a data on the DRAM start address */ | ||
4617 | awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET); | ||
4618 | awe_peek(AWE_SMLD); /* discard stale data */ | ||
4619 | if (awe_peek(AWE_SMLD) != UNIQUE_ID1) | ||
4620 | break; | ||
4621 | if (awe_peek(AWE_SMLD) != UNIQUE_ID2) | ||
4622 | break; | ||
4623 | memsize += 512; /* increment 512kbytes */ | ||
4624 | /* Write a unique data on the test address; | ||
4625 | * if the address is out of range, the data is written on | ||
4626 | * 0x200000(=AWE_DRAM_OFFSET). Then the two id words are | ||
4627 | * broken by this data. | ||
4628 | */ | ||
4629 | awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + memsize*512L); | ||
4630 | awe_poke(AWE_SMLD, UNIQUE_ID3); | ||
4631 | awe_wait(5); | ||
4632 | /* read a data on the just written DRAM address */ | ||
4633 | awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + memsize*512L); | ||
4634 | awe_peek(AWE_SMLD); /* discard stale data */ | ||
4635 | if (awe_peek(AWE_SMLD) != UNIQUE_ID3) | ||
4636 | break; | ||
4637 | } | ||
4638 | awe_close_dram(); | ||
4639 | |||
4640 | DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", memsize)); | ||
4641 | |||
4642 | /* convert to Kbytes */ | ||
4643 | memsize *= 1024; | ||
4644 | } | ||
4645 | |||
4646 | |||
4647 | /*----------------------------------------------------------------*/ | ||
4648 | |||
4649 | /* | ||
4650 | * chorus and reverb controls; from VV's guide | ||
4651 | */ | ||
4652 | |||
4653 | /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */ | ||
4654 | static char chorus_defined[AWE_CHORUS_NUMBERS]; | ||
4655 | static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = { | ||
4656 | {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */ | ||
4657 | {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */ | ||
4658 | {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */ | ||
4659 | {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */ | ||
4660 | {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */ | ||
4661 | {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */ | ||
4662 | {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */ | ||
4663 | {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */ | ||
4664 | }; | ||
4665 | |||
4666 | static int | ||
4667 | awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count) | ||
4668 | { | ||
4669 | if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) { | ||
4670 | printk(KERN_WARNING "AWE32 Error: invalid chorus mode %d for uploading\n", patch->optarg); | ||
4671 | return -EINVAL; | ||
4672 | } | ||
4673 | if (count < sizeof(awe_chorus_fx_rec)) { | ||
4674 | printk(KERN_WARNING "AWE32 Error: too short chorus fx parameters\n"); | ||
4675 | return -EINVAL; | ||
4676 | } | ||
4677 | if (copy_from_user(&chorus_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE, | ||
4678 | sizeof(awe_chorus_fx_rec))) | ||
4679 | return -EFAULT; | ||
4680 | chorus_defined[patch->optarg] = TRUE; | ||
4681 | return 0; | ||
4682 | } | ||
4683 | |||
4684 | static void | ||
4685 | awe_set_chorus_mode(int effect) | ||
4686 | { | ||
4687 | if (effect < 0 || effect >= AWE_CHORUS_NUMBERS || | ||
4688 | (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect])) | ||
4689 | return; | ||
4690 | awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback); | ||
4691 | awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset); | ||
4692 | awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth); | ||
4693 | awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay); | ||
4694 | awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq); | ||
4695 | awe_poke_dw(AWE_HWCF6, 0x8000); | ||
4696 | awe_poke_dw(AWE_HWCF7, 0x0000); | ||
4697 | } | ||
4698 | |||
4699 | static void | ||
4700 | awe_update_chorus_mode(void) | ||
4701 | { | ||
4702 | awe_set_chorus_mode(ctrls[AWE_MD_CHORUS_MODE]); | ||
4703 | } | ||
4704 | |||
4705 | /*----------------------------------------------------------------*/ | ||
4706 | |||
4707 | /* reverb mode settings; write the following 28 data of 16 bit length | ||
4708 | * on the corresponding ports in the reverb_cmds array | ||
4709 | */ | ||
4710 | static char reverb_defined[AWE_CHORUS_NUMBERS]; | ||
4711 | static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = { | ||
4712 | {{ /* room 1 */ | ||
4713 | 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4, | ||
4714 | 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516, | ||
4715 | 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, | ||
4716 | 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, | ||
4717 | }}, | ||
4718 | {{ /* room 2 */ | ||
4719 | 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284, | ||
4720 | 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548, | ||
4721 | 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, | ||
4722 | 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, | ||
4723 | }}, | ||
4724 | {{ /* room 3 */ | ||
4725 | 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284, | ||
4726 | 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516, | ||
4727 | 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B, | ||
4728 | 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A, | ||
4729 | }}, | ||
4730 | {{ /* hall 1 */ | ||
4731 | 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284, | ||
4732 | 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548, | ||
4733 | 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A, | ||
4734 | 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529, | ||
4735 | }}, | ||
4736 | {{ /* hall 2 */ | ||
4737 | 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254, | ||
4738 | 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3, | ||
4739 | 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, | ||
4740 | 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, | ||
4741 | }}, | ||
4742 | {{ /* plate */ | ||
4743 | 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234, | ||
4744 | 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548, | ||
4745 | 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429, | ||
4746 | 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528, | ||
4747 | }}, | ||
4748 | {{ /* delay */ | ||
4749 | 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204, | ||
4750 | 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500, | ||
4751 | 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, | ||
4752 | 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, | ||
4753 | }}, | ||
4754 | {{ /* panning delay */ | ||
4755 | 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204, | ||
4756 | 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500, | ||
4757 | 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, | ||
4758 | 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, | ||
4759 | }}, | ||
4760 | }; | ||
4761 | |||
4762 | static struct ReverbCmdPair { | ||
4763 | unsigned short cmd, port; | ||
4764 | } reverb_cmds[28] = { | ||
4765 | {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)}, | ||
4766 | {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)}, | ||
4767 | {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)}, | ||
4768 | {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)}, | ||
4769 | {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)}, | ||
4770 | {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)}, | ||
4771 | {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)}, | ||
4772 | }; | ||
4773 | |||
4774 | static int | ||
4775 | awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count) | ||
4776 | { | ||
4777 | if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) { | ||
4778 | printk(KERN_WARNING "AWE32 Error: invalid reverb mode %d for uploading\n", patch->optarg); | ||
4779 | return -EINVAL; | ||
4780 | } | ||
4781 | if (count < sizeof(awe_reverb_fx_rec)) { | ||
4782 | printk(KERN_WARNING "AWE32 Error: too short reverb fx parameters\n"); | ||
4783 | return -EINVAL; | ||
4784 | } | ||
4785 | if (copy_from_user(&reverb_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE, | ||
4786 | sizeof(awe_reverb_fx_rec))) | ||
4787 | return -EFAULT; | ||
4788 | reverb_defined[patch->optarg] = TRUE; | ||
4789 | return 0; | ||
4790 | } | ||
4791 | |||
4792 | static void | ||
4793 | awe_set_reverb_mode(int effect) | ||
4794 | { | ||
4795 | int i; | ||
4796 | if (effect < 0 || effect >= AWE_REVERB_NUMBERS || | ||
4797 | (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect])) | ||
4798 | return; | ||
4799 | for (i = 0; i < 28; i++) | ||
4800 | awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port, | ||
4801 | reverb_parm[effect].parms[i]); | ||
4802 | } | ||
4803 | |||
4804 | static void | ||
4805 | awe_update_reverb_mode(void) | ||
4806 | { | ||
4807 | awe_set_reverb_mode(ctrls[AWE_MD_REVERB_MODE]); | ||
4808 | } | ||
4809 | |||
4810 | /* | ||
4811 | * treble/bass equalizer control | ||
4812 | */ | ||
4813 | |||
4814 | static unsigned short bass_parm[12][3] = { | ||
4815 | {0xD26A, 0xD36A, 0x0000}, /* -12 dB */ | ||
4816 | {0xD25B, 0xD35B, 0x0000}, /* -8 */ | ||
4817 | {0xD24C, 0xD34C, 0x0000}, /* -6 */ | ||
4818 | {0xD23D, 0xD33D, 0x0000}, /* -4 */ | ||
4819 | {0xD21F, 0xD31F, 0x0000}, /* -2 */ | ||
4820 | {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */ | ||
4821 | {0xC219, 0xC319, 0x0001}, /* +2 */ | ||
4822 | {0xC22A, 0xC32A, 0x0001}, /* +4 */ | ||
4823 | {0xC24C, 0xC34C, 0x0001}, /* +6 */ | ||
4824 | {0xC26E, 0xC36E, 0x0001}, /* +8 */ | ||
4825 | {0xC248, 0xC348, 0x0002}, /* +10 */ | ||
4826 | {0xC26A, 0xC36A, 0x0002}, /* +12 dB */ | ||
4827 | }; | ||
4828 | |||
4829 | static unsigned short treble_parm[12][9] = { | ||
4830 | {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */ | ||
4831 | {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, | ||
4832 | {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, | ||
4833 | {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, | ||
4834 | {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, | ||
4835 | {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002}, | ||
4836 | {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002}, | ||
4837 | {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002}, | ||
4838 | {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002}, | ||
4839 | {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */ | ||
4840 | {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, | ||
4841 | {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */ | ||
4842 | }; | ||
4843 | |||
4844 | |||
4845 | /* | ||
4846 | * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB] | ||
4847 | */ | ||
4848 | static void | ||
4849 | awe_equalizer(int bass, int treble) | ||
4850 | { | ||
4851 | unsigned short w; | ||
4852 | |||
4853 | if (bass < 0 || bass > 11 || treble < 0 || treble > 11) | ||
4854 | return; | ||
4855 | awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]); | ||
4856 | awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]); | ||
4857 | awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]); | ||
4858 | awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]); | ||
4859 | awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]); | ||
4860 | awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]); | ||
4861 | awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]); | ||
4862 | awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]); | ||
4863 | awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]); | ||
4864 | awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]); | ||
4865 | w = bass_parm[bass][2] + treble_parm[treble][8]; | ||
4866 | awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262)); | ||
4867 | awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362)); | ||
4868 | } | ||
4869 | |||
4870 | static void awe_update_equalizer(void) | ||
4871 | { | ||
4872 | awe_equalizer(ctrls[AWE_MD_BASS_LEVEL], ctrls[AWE_MD_TREBLE_LEVEL]); | ||
4873 | } | ||
4874 | |||
4875 | |||
4876 | /*----------------------------------------------------------------*/ | ||
4877 | |||
4878 | #ifdef CONFIG_AWE32_MIDIEMU | ||
4879 | |||
4880 | /* | ||
4881 | * Emu8000 MIDI Emulation | ||
4882 | */ | ||
4883 | |||
4884 | /* | ||
4885 | * midi queue record | ||
4886 | */ | ||
4887 | |||
4888 | /* queue type */ | ||
4889 | enum { Q_NONE, Q_VARLEN, Q_READ, Q_SYSEX, }; | ||
4890 | |||
4891 | #define MAX_MIDIBUF 64 | ||
4892 | |||
4893 | /* midi status */ | ||
4894 | typedef struct MidiStatus { | ||
4895 | int queue; /* queue type */ | ||
4896 | int qlen; /* queue length */ | ||
4897 | int read; /* chars read */ | ||
4898 | int status; /* current status */ | ||
4899 | int chan; /* current channel */ | ||
4900 | unsigned char buf[MAX_MIDIBUF]; | ||
4901 | } MidiStatus; | ||
4902 | |||
4903 | /* MIDI mode type */ | ||
4904 | enum { MODE_GM, MODE_GS, MODE_XG, }; | ||
4905 | |||
4906 | /* NRPN / CC -> Emu8000 parameter converter */ | ||
4907 | typedef struct { | ||
4908 | int control; | ||
4909 | int awe_effect; | ||
4910 | unsigned short (*convert)(int val); | ||
4911 | } ConvTable; | ||
4912 | |||
4913 | |||
4914 | /* | ||
4915 | * prototypes | ||
4916 | */ | ||
4917 | |||
4918 | static int awe_midi_open(int dev, int mode, void (*input)(int,unsigned char), void (*output)(int)); | ||
4919 | static void awe_midi_close(int dev); | ||
4920 | static int awe_midi_ioctl(int dev, unsigned cmd, void __user * arg); | ||
4921 | static int awe_midi_outputc(int dev, unsigned char midi_byte); | ||
4922 | |||
4923 | static void init_midi_status(MidiStatus *st); | ||
4924 | static void clear_rpn(void); | ||
4925 | static void get_midi_char(MidiStatus *st, int c); | ||
4926 | /*static void queue_varlen(MidiStatus *st, int c);*/ | ||
4927 | static void special_event(MidiStatus *st, int c); | ||
4928 | static void queue_read(MidiStatus *st, int c); | ||
4929 | static void midi_note_on(MidiStatus *st); | ||
4930 | static void midi_note_off(MidiStatus *st); | ||
4931 | static void midi_key_pressure(MidiStatus *st); | ||
4932 | static void midi_channel_pressure(MidiStatus *st); | ||
4933 | static void midi_pitch_wheel(MidiStatus *st); | ||
4934 | static void midi_program_change(MidiStatus *st); | ||
4935 | static void midi_control_change(MidiStatus *st); | ||
4936 | static void midi_select_bank(MidiStatus *st, int val); | ||
4937 | static void midi_nrpn_event(MidiStatus *st); | ||
4938 | static void midi_rpn_event(MidiStatus *st); | ||
4939 | static void midi_detune(int chan, int coarse, int fine); | ||
4940 | static void midi_system_exclusive(MidiStatus *st); | ||
4941 | static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val); | ||
4942 | static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val); | ||
4943 | static int xg_control_change(MidiStatus *st, int cmd, int val); | ||
4944 | |||
4945 | #define numberof(ary) (sizeof(ary)/sizeof(ary[0])) | ||
4946 | |||
4947 | |||
4948 | /* | ||
4949 | * OSS Midi device record | ||
4950 | */ | ||
4951 | |||
4952 | static struct midi_operations awe_midi_operations = | ||
4953 | { | ||
4954 | .owner = THIS_MODULE, | ||
4955 | .info = {"AWE Midi Emu", 0, 0, SNDCARD_SB}, | ||
4956 | .in_info = {0}, | ||
4957 | .open = awe_midi_open, /*open*/ | ||
4958 | .close = awe_midi_close, /*close*/ | ||
4959 | .ioctl = awe_midi_ioctl, /*ioctl*/ | ||
4960 | .outputc = awe_midi_outputc, /*outputc*/ | ||
4961 | }; | ||
4962 | |||
4963 | static int my_mididev = -1; | ||
4964 | |||
4965 | static void __init attach_midiemu(void) | ||
4966 | { | ||
4967 | if ((my_mididev = sound_alloc_mididev()) < 0) | ||
4968 | printk ("Sound: Too many midi devices detected\n"); | ||
4969 | else | ||
4970 | midi_devs[my_mididev] = &awe_midi_operations; | ||
4971 | } | ||
4972 | |||
4973 | static void unload_midiemu(void) | ||
4974 | { | ||
4975 | if (my_mididev >= 0) | ||
4976 | sound_unload_mididev(my_mididev); | ||
4977 | } | ||
4978 | |||
4979 | |||
4980 | /* | ||
4981 | * open/close midi device | ||
4982 | */ | ||
4983 | |||
4984 | static int midi_opened = FALSE; | ||
4985 | |||
4986 | static int midi_mode; | ||
4987 | static int coarsetune, finetune; | ||
4988 | |||
4989 | static int xg_mapping = TRUE; | ||
4990 | static int xg_bankmode; | ||
4991 | |||
4992 | /* effect sensitivity */ | ||
4993 | |||
4994 | #define FX_CUTOFF 0 | ||
4995 | #define FX_RESONANCE 1 | ||
4996 | #define FX_ATTACK 2 | ||
4997 | #define FX_RELEASE 3 | ||
4998 | #define FX_VIBRATE 4 | ||
4999 | #define FX_VIBDEPTH 5 | ||
5000 | #define FX_VIBDELAY 6 | ||
5001 | #define FX_NUMS 7 | ||
5002 | |||
5003 | #define DEF_FX_CUTOFF 170 | ||
5004 | #define DEF_FX_RESONANCE 6 | ||
5005 | #define DEF_FX_ATTACK 50 | ||
5006 | #define DEF_FX_RELEASE 50 | ||
5007 | #define DEF_FX_VIBRATE 30 | ||
5008 | #define DEF_FX_VIBDEPTH 4 | ||
5009 | #define DEF_FX_VIBDELAY 1500 | ||
5010 | |||
5011 | /* effect sense: */ | ||
5012 | static int gs_sense[] = | ||
5013 | { | ||
5014 | DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE, | ||
5015 | DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY | ||
5016 | }; | ||
5017 | static int xg_sense[] = | ||
5018 | { | ||
5019 | DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE, | ||
5020 | DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY | ||
5021 | }; | ||
5022 | |||
5023 | |||
5024 | /* current status */ | ||
5025 | static MidiStatus curst; | ||
5026 | |||
5027 | |||
5028 | static int | ||
5029 | awe_midi_open (int dev, int mode, | ||
5030 | void (*input)(int,unsigned char), | ||
5031 | void (*output)(int)) | ||
5032 | { | ||
5033 | if (midi_opened) | ||
5034 | return -EBUSY; | ||
5035 | |||
5036 | midi_opened = TRUE; | ||
5037 | |||
5038 | midi_mode = MODE_GM; | ||
5039 | |||
5040 | curst.queue = Q_NONE; | ||
5041 | curst.qlen = 0; | ||
5042 | curst.read = 0; | ||
5043 | curst.status = 0; | ||
5044 | curst.chan = 0; | ||
5045 | memset(curst.buf, 0, sizeof(curst.buf)); | ||
5046 | |||
5047 | init_midi_status(&curst); | ||
5048 | |||
5049 | return 0; | ||
5050 | } | ||
5051 | |||
5052 | static void | ||
5053 | awe_midi_close (int dev) | ||
5054 | { | ||
5055 | midi_opened = FALSE; | ||
5056 | } | ||
5057 | |||
5058 | |||
5059 | static int | ||
5060 | awe_midi_ioctl (int dev, unsigned cmd, void __user *arg) | ||
5061 | { | ||
5062 | return -EPERM; | ||
5063 | } | ||
5064 | |||
5065 | static int | ||
5066 | awe_midi_outputc (int dev, unsigned char midi_byte) | ||
5067 | { | ||
5068 | if (! midi_opened) | ||
5069 | return 1; | ||
5070 | |||
5071 | /* force to change playing mode */ | ||
5072 | playing_mode = AWE_PLAY_MULTI; | ||
5073 | |||
5074 | get_midi_char(&curst, midi_byte); | ||
5075 | return 1; | ||
5076 | } | ||
5077 | |||
5078 | |||
5079 | /* | ||
5080 | * initialize | ||
5081 | */ | ||
5082 | |||
5083 | static void init_midi_status(MidiStatus *st) | ||
5084 | { | ||
5085 | clear_rpn(); | ||
5086 | coarsetune = 0; | ||
5087 | finetune = 0; | ||
5088 | } | ||
5089 | |||
5090 | |||
5091 | /* | ||
5092 | * RPN & NRPN | ||
5093 | */ | ||
5094 | |||
5095 | #define MAX_MIDI_CHANNELS 16 | ||
5096 | |||
5097 | /* RPN & NRPN */ | ||
5098 | static unsigned char nrpn[MAX_MIDI_CHANNELS]; /* current event is NRPN? */ | ||
5099 | static int msb_bit; /* current event is msb for RPN/NRPN */ | ||
5100 | /* RPN & NRPN indeces */ | ||
5101 | static unsigned char rpn_msb[MAX_MIDI_CHANNELS], rpn_lsb[MAX_MIDI_CHANNELS]; | ||
5102 | /* RPN & NRPN values */ | ||
5103 | static int rpn_val[MAX_MIDI_CHANNELS]; | ||
5104 | |||
5105 | static void clear_rpn(void) | ||
5106 | { | ||
5107 | int i; | ||
5108 | for (i = 0; i < MAX_MIDI_CHANNELS; i++) { | ||
5109 | nrpn[i] = 0; | ||
5110 | rpn_msb[i] = 127; | ||
5111 | rpn_lsb[i] = 127; | ||
5112 | rpn_val[i] = 0; | ||
5113 | } | ||
5114 | msb_bit = 0; | ||
5115 | } | ||
5116 | |||
5117 | |||
5118 | /* | ||
5119 | * process midi queue | ||
5120 | */ | ||
5121 | |||
5122 | /* status event types */ | ||
5123 | typedef void (*StatusEvent)(MidiStatus *st); | ||
5124 | static struct StatusEventList { | ||
5125 | StatusEvent process; | ||
5126 | int qlen; | ||
5127 | } status_event[8] = { | ||
5128 | {midi_note_off, 2}, | ||
5129 | {midi_note_on, 2}, | ||
5130 | {midi_key_pressure, 2}, | ||
5131 | {midi_control_change, 2}, | ||
5132 | {midi_program_change, 1}, | ||
5133 | {midi_channel_pressure, 1}, | ||
5134 | {midi_pitch_wheel, 2}, | ||
5135 | {NULL, 0}, | ||
5136 | }; | ||
5137 | |||
5138 | |||
5139 | /* read a char from fifo and process it */ | ||
5140 | static void get_midi_char(MidiStatus *st, int c) | ||
5141 | { | ||
5142 | if (c == 0xfe) { | ||
5143 | /* ignore active sense */ | ||
5144 | st->queue = Q_NONE; | ||
5145 | return; | ||
5146 | } | ||
5147 | |||
5148 | switch (st->queue) { | ||
5149 | /* case Q_VARLEN: queue_varlen(st, c); break;*/ | ||
5150 | case Q_READ: | ||
5151 | case Q_SYSEX: | ||
5152 | queue_read(st, c); | ||
5153 | break; | ||
5154 | case Q_NONE: | ||
5155 | st->read = 0; | ||
5156 | if ((c & 0xf0) == 0xf0) { | ||
5157 | special_event(st, c); | ||
5158 | } else if (c & 0x80) { /* status change */ | ||
5159 | st->status = (c >> 4) & 0x07; | ||
5160 | st->chan = c & 0x0f; | ||
5161 | st->queue = Q_READ; | ||
5162 | st->qlen = status_event[st->status].qlen; | ||
5163 | if (st->qlen == 0) | ||
5164 | st->queue = Q_NONE; | ||
5165 | } | ||
5166 | break; | ||
5167 | } | ||
5168 | } | ||
5169 | |||
5170 | /* 0xfx events */ | ||
5171 | static void special_event(MidiStatus *st, int c) | ||
5172 | { | ||
5173 | switch (c) { | ||
5174 | case 0xf0: /* system exclusive */ | ||
5175 | st->queue = Q_SYSEX; | ||
5176 | st->qlen = 0; | ||
5177 | break; | ||
5178 | case 0xf1: /* MTC quarter frame */ | ||
5179 | case 0xf3: /* song select */ | ||
5180 | st->queue = Q_READ; | ||
5181 | st->qlen = 1; | ||
5182 | break; | ||
5183 | case 0xf2: /* song position */ | ||
5184 | st->queue = Q_READ; | ||
5185 | st->qlen = 2; | ||
5186 | break; | ||
5187 | } | ||
5188 | } | ||
5189 | |||
5190 | #if 0 | ||
5191 | /* read variable length value */ | ||
5192 | static void queue_varlen(MidiStatus *st, int c) | ||
5193 | { | ||
5194 | st->qlen += (c & 0x7f); | ||
5195 | if (c & 0x80) { | ||
5196 | st->qlen <<= 7; | ||
5197 | return; | ||
5198 | } | ||
5199 | if (st->qlen <= 0) { | ||
5200 | st->qlen = 0; | ||
5201 | st->queue = Q_NONE; | ||
5202 | } | ||
5203 | st->queue = Q_READ; | ||
5204 | st->read = 0; | ||
5205 | } | ||
5206 | #endif | ||
5207 | |||
5208 | |||
5209 | /* read a char */ | ||
5210 | static void queue_read(MidiStatus *st, int c) | ||
5211 | { | ||
5212 | if (st->read < MAX_MIDIBUF) { | ||
5213 | if (st->queue != Q_SYSEX) | ||
5214 | c &= 0x7f; | ||
5215 | st->buf[st->read] = (unsigned char)c; | ||
5216 | } | ||
5217 | st->read++; | ||
5218 | if (st->queue == Q_SYSEX && c == 0xf7) { | ||
5219 | midi_system_exclusive(st); | ||
5220 | st->queue = Q_NONE; | ||
5221 | } else if (st->queue == Q_READ && st->read >= st->qlen) { | ||
5222 | if (status_event[st->status].process) | ||
5223 | status_event[st->status].process(st); | ||
5224 | st->queue = Q_NONE; | ||
5225 | } | ||
5226 | } | ||
5227 | |||
5228 | |||
5229 | /* | ||
5230 | * status events | ||
5231 | */ | ||
5232 | |||
5233 | /* note on */ | ||
5234 | static void midi_note_on(MidiStatus *st) | ||
5235 | { | ||
5236 | DEBUG(2,printk("midi: note_on (%d) %d %d\n", st->chan, st->buf[0], st->buf[1])); | ||
5237 | if (st->buf[1] == 0) | ||
5238 | midi_note_off(st); | ||
5239 | else | ||
5240 | awe_start_note(0, st->chan, st->buf[0], st->buf[1]); | ||
5241 | } | ||
5242 | |||
5243 | /* note off */ | ||
5244 | static void midi_note_off(MidiStatus *st) | ||
5245 | { | ||
5246 | DEBUG(2,printk("midi: note_off (%d) %d %d\n", st->chan, st->buf[0], st->buf[1])); | ||
5247 | awe_kill_note(0, st->chan, st->buf[0], st->buf[1]); | ||
5248 | } | ||
5249 | |||
5250 | /* key pressure change */ | ||
5251 | static void midi_key_pressure(MidiStatus *st) | ||
5252 | { | ||
5253 | awe_key_pressure(0, st->chan, st->buf[0], st->buf[1]); | ||
5254 | } | ||
5255 | |||
5256 | /* channel pressure change */ | ||
5257 | static void midi_channel_pressure(MidiStatus *st) | ||
5258 | { | ||
5259 | channels[st->chan].chan_press = st->buf[0]; | ||
5260 | awe_modwheel_change(st->chan, st->buf[0]); | ||
5261 | } | ||
5262 | |||
5263 | /* pitch wheel change */ | ||
5264 | static void midi_pitch_wheel(MidiStatus *st) | ||
5265 | { | ||
5266 | int val = (int)st->buf[1] * 128 + st->buf[0]; | ||
5267 | awe_bender(0, st->chan, val); | ||
5268 | } | ||
5269 | |||
5270 | /* program change */ | ||
5271 | static void midi_program_change(MidiStatus *st) | ||
5272 | { | ||
5273 | int preset; | ||
5274 | preset = st->buf[0]; | ||
5275 | if (midi_mode == MODE_GS && IS_DRUM_CHANNEL(st->chan) && preset == 127) | ||
5276 | preset = 0; | ||
5277 | else if (midi_mode == MODE_XG && xg_mapping && IS_DRUM_CHANNEL(st->chan)) | ||
5278 | preset += 64; | ||
5279 | |||
5280 | awe_set_instr(0, st->chan, preset); | ||
5281 | } | ||
5282 | |||
5283 | #define send_effect(chan,type,val) awe_send_effect(chan,-1,type,val) | ||
5284 | #define add_effect(chan,type,val) awe_send_effect(chan,-1,(type)|0x80,val) | ||
5285 | #define unset_effect(chan,type) awe_send_effect(chan,-1,(type)|0x40,0) | ||
5286 | |||
5287 | /* midi control change */ | ||
5288 | static void midi_control_change(MidiStatus *st) | ||
5289 | { | ||
5290 | int cmd = st->buf[0]; | ||
5291 | int val = st->buf[1]; | ||
5292 | |||
5293 | DEBUG(2,printk("midi: control (%d) %d %d\n", st->chan, cmd, val)); | ||
5294 | if (midi_mode == MODE_XG) { | ||
5295 | if (xg_control_change(st, cmd, val)) | ||
5296 | return; | ||
5297 | } | ||
5298 | |||
5299 | /* controls #31 - #64 are LSB of #0 - #31 */ | ||
5300 | msb_bit = 1; | ||
5301 | if (cmd >= 0x20 && cmd < 0x40) { | ||
5302 | msb_bit = 0; | ||
5303 | cmd -= 0x20; | ||
5304 | } | ||
5305 | |||
5306 | switch (cmd) { | ||
5307 | case CTL_SOFT_PEDAL: | ||
5308 | if (val == 127) | ||
5309 | add_effect(st->chan, AWE_FX_CUTOFF, -160); | ||
5310 | else | ||
5311 | unset_effect(st->chan, AWE_FX_CUTOFF); | ||
5312 | break; | ||
5313 | |||
5314 | case CTL_BANK_SELECT: | ||
5315 | midi_select_bank(st, val); | ||
5316 | break; | ||
5317 | |||
5318 | /* set RPN/NRPN parameter */ | ||
5319 | case CTL_REGIST_PARM_NUM_MSB: | ||
5320 | nrpn[st->chan]=0; rpn_msb[st->chan]=val; | ||
5321 | break; | ||
5322 | case CTL_REGIST_PARM_NUM_LSB: | ||
5323 | nrpn[st->chan]=0; rpn_lsb[st->chan]=val; | ||
5324 | break; | ||
5325 | case CTL_NONREG_PARM_NUM_MSB: | ||
5326 | nrpn[st->chan]=1; rpn_msb[st->chan]=val; | ||
5327 | break; | ||
5328 | case CTL_NONREG_PARM_NUM_LSB: | ||
5329 | nrpn[st->chan]=1; rpn_lsb[st->chan]=val; | ||
5330 | break; | ||
5331 | |||
5332 | /* send RPN/NRPN entry */ | ||
5333 | case CTL_DATA_ENTRY: | ||
5334 | if (msb_bit) | ||
5335 | rpn_val[st->chan] = val * 128; | ||
5336 | else | ||
5337 | rpn_val[st->chan] |= val; | ||
5338 | if (nrpn[st->chan]) | ||
5339 | midi_nrpn_event(st); | ||
5340 | else | ||
5341 | midi_rpn_event(st); | ||
5342 | break; | ||
5343 | |||
5344 | /* increase/decrease data entry */ | ||
5345 | case CTL_DATA_INCREMENT: | ||
5346 | rpn_val[st->chan]++; | ||
5347 | midi_rpn_event(st); | ||
5348 | break; | ||
5349 | case CTL_DATA_DECREMENT: | ||
5350 | rpn_val[st->chan]--; | ||
5351 | midi_rpn_event(st); | ||
5352 | break; | ||
5353 | |||
5354 | /* default */ | ||
5355 | default: | ||
5356 | awe_controller(0, st->chan, cmd, val); | ||
5357 | break; | ||
5358 | } | ||
5359 | } | ||
5360 | |||
5361 | /* tone bank change */ | ||
5362 | static void midi_select_bank(MidiStatus *st, int val) | ||
5363 | { | ||
5364 | if (midi_mode == MODE_XG && msb_bit) { | ||
5365 | xg_bankmode = val; | ||
5366 | /* XG MSB value; not normal bank selection */ | ||
5367 | switch (val) { | ||
5368 | case 127: /* remap to drum channel */ | ||
5369 | awe_controller(0, st->chan, CTL_BANK_SELECT, 128); | ||
5370 | break; | ||
5371 | default: /* remap to normal channel */ | ||
5372 | awe_controller(0, st->chan, CTL_BANK_SELECT, val); | ||
5373 | break; | ||
5374 | } | ||
5375 | return; | ||
5376 | } else if (midi_mode == MODE_GS && !msb_bit) | ||
5377 | /* ignore LSB bank in GS mode (used for mapping) */ | ||
5378 | return; | ||
5379 | |||
5380 | /* normal bank controls; accept both MSB and LSB */ | ||
5381 | if (! IS_DRUM_CHANNEL(st->chan)) { | ||
5382 | if (midi_mode == MODE_XG) { | ||
5383 | if (xg_bankmode) return; | ||
5384 | if (val == 64 || val == 126) | ||
5385 | val = 0; | ||
5386 | } else if (midi_mode == MODE_GS && val == 127) | ||
5387 | val = 0; | ||
5388 | awe_controller(0, st->chan, CTL_BANK_SELECT, val); | ||
5389 | } | ||
5390 | } | ||
5391 | |||
5392 | |||
5393 | /* | ||
5394 | * RPN events | ||
5395 | */ | ||
5396 | |||
5397 | static void midi_rpn_event(MidiStatus *st) | ||
5398 | { | ||
5399 | int type; | ||
5400 | type = (rpn_msb[st->chan]<<8) | rpn_lsb[st->chan]; | ||
5401 | switch (type) { | ||
5402 | case 0x0000: /* Pitch bend sensitivity */ | ||
5403 | /* MSB only / 1 semitone per 128 */ | ||
5404 | if (msb_bit) { | ||
5405 | channels[st->chan].bender_range = | ||
5406 | rpn_val[st->chan] * 100 / 128; | ||
5407 | } | ||
5408 | break; | ||
5409 | |||
5410 | case 0x0001: /* fine tuning: */ | ||
5411 | /* MSB/LSB, 8192=center, 100/8192 cent step */ | ||
5412 | finetune = rpn_val[st->chan] - 8192; | ||
5413 | midi_detune(st->chan, coarsetune, finetune); | ||
5414 | break; | ||
5415 | |||
5416 | case 0x0002: /* coarse tuning */ | ||
5417 | /* MSB only / 8192=center, 1 semitone per 128 */ | ||
5418 | if (msb_bit) { | ||
5419 | coarsetune = rpn_val[st->chan] - 8192; | ||
5420 | midi_detune(st->chan, coarsetune, finetune); | ||
5421 | } | ||
5422 | break; | ||
5423 | |||
5424 | case 0x7F7F: /* "lock-in" RPN */ | ||
5425 | break; | ||
5426 | } | ||
5427 | } | ||
5428 | |||
5429 | |||
5430 | /* tuning: | ||
5431 | * coarse = -8192 to 8192 (100 cent per 128) | ||
5432 | * fine = -8192 to 8192 (max=100cent) | ||
5433 | */ | ||
5434 | static void midi_detune(int chan, int coarse, int fine) | ||
5435 | { | ||
5436 | /* 4096 = 1200 cents in AWE parameter */ | ||
5437 | int val; | ||
5438 | val = coarse * 4096 / (12 * 128); | ||
5439 | val += fine / 24; | ||
5440 | if (val) | ||
5441 | send_effect(chan, AWE_FX_INIT_PITCH, val); | ||
5442 | else | ||
5443 | unset_effect(chan, AWE_FX_INIT_PITCH); | ||
5444 | } | ||
5445 | |||
5446 | |||
5447 | /* | ||
5448 | * system exclusive message | ||
5449 | * GM/GS/XG macros are accepted | ||
5450 | */ | ||
5451 | |||
5452 | static void midi_system_exclusive(MidiStatus *st) | ||
5453 | { | ||
5454 | /* GM on */ | ||
5455 | static unsigned char gm_on_macro[] = { | ||
5456 | 0x7e,0x7f,0x09,0x01, | ||
5457 | }; | ||
5458 | /* XG on */ | ||
5459 | static unsigned char xg_on_macro[] = { | ||
5460 | 0x43,0x10,0x4c,0x00,0x00,0x7e,0x00, | ||
5461 | }; | ||
5462 | /* GS prefix | ||
5463 | * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off | ||
5464 | * reverb mode: XX=0x01, YY=0x30, ZZ=0-7 | ||
5465 | * chorus mode: XX=0x01, YY=0x38, ZZ=0-7 | ||
5466 | */ | ||
5467 | static unsigned char gs_pfx_macro[] = { | ||
5468 | 0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/ | ||
5469 | }; | ||
5470 | |||
5471 | #if 0 | ||
5472 | /* SC88 system mode set | ||
5473 | * single module mode: XX=1 | ||
5474 | * double module mode: XX=0 | ||
5475 | */ | ||
5476 | static unsigned char gs_mode_macro[] = { | ||
5477 | 0x41,0x10,0x42,0x12,0x00,0x00,0x7F,/*ZZ*/ | ||
5478 | }; | ||
5479 | /* SC88 display macro: XX=01:bitmap, 00:text | ||
5480 | */ | ||
5481 | static unsigned char gs_disp_macro[] = { | ||
5482 | 0x41,0x10,0x45,0x12,0x10,/*XX,00*/ | ||
5483 | }; | ||
5484 | #endif | ||
5485 | |||
5486 | /* GM on */ | ||
5487 | if (memcmp(st->buf, gm_on_macro, sizeof(gm_on_macro)) == 0) { | ||
5488 | if (midi_mode != MODE_GS && midi_mode != MODE_XG) | ||
5489 | midi_mode = MODE_GM; | ||
5490 | init_midi_status(st); | ||
5491 | } | ||
5492 | |||
5493 | /* GS macros */ | ||
5494 | else if (memcmp(st->buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) { | ||
5495 | if (midi_mode != MODE_GS && midi_mode != MODE_XG) | ||
5496 | midi_mode = MODE_GS; | ||
5497 | |||
5498 | if (st->buf[5] == 0x00 && st->buf[6] == 0x7f && st->buf[7] == 0x00) { | ||
5499 | /* GS reset */ | ||
5500 | init_midi_status(st); | ||
5501 | } | ||
5502 | |||
5503 | else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x15) { | ||
5504 | /* drum pattern */ | ||
5505 | int p = st->buf[5] & 0x0f; | ||
5506 | if (p == 0) p = 9; | ||
5507 | else if (p < 10) p--; | ||
5508 | if (st->buf[7] == 0) | ||
5509 | DRUM_CHANNEL_OFF(p); | ||
5510 | else | ||
5511 | DRUM_CHANNEL_ON(p); | ||
5512 | |||
5513 | } else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x21) { | ||
5514 | /* program */ | ||
5515 | int p = st->buf[5] & 0x0f; | ||
5516 | if (p == 0) p = 9; | ||
5517 | else if (p < 10) p--; | ||
5518 | if (! IS_DRUM_CHANNEL(p)) | ||
5519 | awe_set_instr(0, p, st->buf[7]); | ||
5520 | |||
5521 | } else if (st->buf[5] == 0x01 && st->buf[6] == 0x30) { | ||
5522 | /* reverb mode */ | ||
5523 | awe_set_reverb_mode(st->buf[7]); | ||
5524 | |||
5525 | } else if (st->buf[5] == 0x01 && st->buf[6] == 0x38) { | ||
5526 | /* chorus mode */ | ||
5527 | awe_set_chorus_mode(st->buf[7]); | ||
5528 | |||
5529 | } else if (st->buf[5] == 0x00 && st->buf[6] == 0x04) { | ||
5530 | /* master volume */ | ||
5531 | awe_change_master_volume(st->buf[7]); | ||
5532 | |||
5533 | } | ||
5534 | } | ||
5535 | |||
5536 | /* XG on */ | ||
5537 | else if (memcmp(st->buf, xg_on_macro, sizeof(xg_on_macro)) == 0) { | ||
5538 | midi_mode = MODE_XG; | ||
5539 | xg_mapping = TRUE; | ||
5540 | xg_bankmode = 0; | ||
5541 | } | ||
5542 | } | ||
5543 | |||
5544 | |||
5545 | /*----------------------------------------------------------------*/ | ||
5546 | |||
5547 | /* | ||
5548 | * convert NRPN/control values | ||
5549 | */ | ||
5550 | |||
5551 | static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val) | ||
5552 | { | ||
5553 | int i, cval; | ||
5554 | for (i = 0; i < num_tables; i++) { | ||
5555 | if (table[i].control == type) { | ||
5556 | cval = table[i].convert(val); | ||
5557 | send_effect(st->chan, table[i].awe_effect, cval); | ||
5558 | return TRUE; | ||
5559 | } | ||
5560 | } | ||
5561 | return FALSE; | ||
5562 | } | ||
5563 | |||
5564 | static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val) | ||
5565 | { | ||
5566 | int i, cval; | ||
5567 | for (i = 0; i < num_tables; i++) { | ||
5568 | if (table[i].control == type) { | ||
5569 | cval = table[i].convert(val); | ||
5570 | add_effect(st->chan, table[i].awe_effect|0x80, cval); | ||
5571 | return TRUE; | ||
5572 | } | ||
5573 | } | ||
5574 | return FALSE; | ||
5575 | } | ||
5576 | |||
5577 | |||
5578 | /* | ||
5579 | * AWE32 NRPN effects | ||
5580 | */ | ||
5581 | |||
5582 | static unsigned short fx_delay(int val); | ||
5583 | static unsigned short fx_attack(int val); | ||
5584 | static unsigned short fx_hold(int val); | ||
5585 | static unsigned short fx_decay(int val); | ||
5586 | static unsigned short fx_the_value(int val); | ||
5587 | static unsigned short fx_twice_value(int val); | ||
5588 | static unsigned short fx_conv_pitch(int val); | ||
5589 | static unsigned short fx_conv_Q(int val); | ||
5590 | |||
5591 | /* function for each NRPN */ /* [range] units */ | ||
5592 | #define fx_env1_delay fx_delay /* [0,5900] 4msec */ | ||
5593 | #define fx_env1_attack fx_attack /* [0,5940] 1msec */ | ||
5594 | #define fx_env1_hold fx_hold /* [0,8191] 1msec */ | ||
5595 | #define fx_env1_decay fx_decay /* [0,5940] 4msec */ | ||
5596 | #define fx_env1_release fx_decay /* [0,5940] 4msec */ | ||
5597 | #define fx_env1_sustain fx_the_value /* [0,127] 0.75dB */ | ||
5598 | #define fx_env1_pitch fx_the_value /* [-127,127] 9.375cents */ | ||
5599 | #define fx_env1_cutoff fx_the_value /* [-127,127] 56.25cents */ | ||
5600 | |||
5601 | #define fx_env2_delay fx_delay /* [0,5900] 4msec */ | ||
5602 | #define fx_env2_attack fx_attack /* [0,5940] 1msec */ | ||
5603 | #define fx_env2_hold fx_hold /* [0,8191] 1msec */ | ||
5604 | #define fx_env2_decay fx_decay /* [0,5940] 4msec */ | ||
5605 | #define fx_env2_release fx_decay /* [0,5940] 4msec */ | ||
5606 | #define fx_env2_sustain fx_the_value /* [0,127] 0.75dB */ | ||
5607 | |||
5608 | #define fx_lfo1_delay fx_delay /* [0,5900] 4msec */ | ||
5609 | #define fx_lfo1_freq fx_twice_value /* [0,127] 84mHz */ | ||
5610 | #define fx_lfo1_volume fx_twice_value /* [0,127] 0.1875dB */ | ||
5611 | #define fx_lfo1_pitch fx_the_value /* [-127,127] 9.375cents */ | ||
5612 | #define fx_lfo1_cutoff fx_twice_value /* [-64,63] 56.25cents */ | ||
5613 | |||
5614 | #define fx_lfo2_delay fx_delay /* [0,5900] 4msec */ | ||
5615 | #define fx_lfo2_freq fx_twice_value /* [0,127] 84mHz */ | ||
5616 | #define fx_lfo2_pitch fx_the_value /* [-127,127] 9.375cents */ | ||
5617 | |||
5618 | #define fx_init_pitch fx_conv_pitch /* [-8192,8192] cents */ | ||
5619 | #define fx_chorus fx_the_value /* [0,255] -- */ | ||
5620 | #define fx_reverb fx_the_value /* [0,255] -- */ | ||
5621 | #define fx_cutoff fx_twice_value /* [0,127] 62Hz */ | ||
5622 | #define fx_filterQ fx_conv_Q /* [0,127] -- */ | ||
5623 | |||
5624 | static unsigned short fx_delay(int val) | ||
5625 | { | ||
5626 | return (unsigned short)calc_parm_delay(val); | ||
5627 | } | ||
5628 | |||
5629 | static unsigned short fx_attack(int val) | ||
5630 | { | ||
5631 | return (unsigned short)calc_parm_attack(val); | ||
5632 | } | ||
5633 | |||
5634 | static unsigned short fx_hold(int val) | ||
5635 | { | ||
5636 | return (unsigned short)calc_parm_hold(val); | ||
5637 | } | ||
5638 | |||
5639 | static unsigned short fx_decay(int val) | ||
5640 | { | ||
5641 | return (unsigned short)calc_parm_decay(val); | ||
5642 | } | ||
5643 | |||
5644 | static unsigned short fx_the_value(int val) | ||
5645 | { | ||
5646 | return (unsigned short)(val & 0xff); | ||
5647 | } | ||
5648 | |||
5649 | static unsigned short fx_twice_value(int val) | ||
5650 | { | ||
5651 | return (unsigned short)((val * 2) & 0xff); | ||
5652 | } | ||
5653 | |||
5654 | static unsigned short fx_conv_pitch(int val) | ||
5655 | { | ||
5656 | return (short)(val * 4096 / 1200); | ||
5657 | } | ||
5658 | |||
5659 | static unsigned short fx_conv_Q(int val) | ||
5660 | { | ||
5661 | return (unsigned short)((val / 8) & 0xff); | ||
5662 | } | ||
5663 | |||
5664 | |||
5665 | static ConvTable awe_effects[] = | ||
5666 | { | ||
5667 | { 0, AWE_FX_LFO1_DELAY, fx_lfo1_delay}, | ||
5668 | { 1, AWE_FX_LFO1_FREQ, fx_lfo1_freq}, | ||
5669 | { 2, AWE_FX_LFO2_DELAY, fx_lfo2_delay}, | ||
5670 | { 3, AWE_FX_LFO2_FREQ, fx_lfo2_freq}, | ||
5671 | |||
5672 | { 4, AWE_FX_ENV1_DELAY, fx_env1_delay}, | ||
5673 | { 5, AWE_FX_ENV1_ATTACK,fx_env1_attack}, | ||
5674 | { 6, AWE_FX_ENV1_HOLD, fx_env1_hold}, | ||
5675 | { 7, AWE_FX_ENV1_DECAY, fx_env1_decay}, | ||
5676 | { 8, AWE_FX_ENV1_SUSTAIN, fx_env1_sustain}, | ||
5677 | { 9, AWE_FX_ENV1_RELEASE, fx_env1_release}, | ||
5678 | |||
5679 | {10, AWE_FX_ENV2_DELAY, fx_env2_delay}, | ||
5680 | {11, AWE_FX_ENV2_ATTACK, fx_env2_attack}, | ||
5681 | {12, AWE_FX_ENV2_HOLD, fx_env2_hold}, | ||
5682 | {13, AWE_FX_ENV2_DECAY, fx_env2_decay}, | ||
5683 | {14, AWE_FX_ENV2_SUSTAIN, fx_env2_sustain}, | ||
5684 | {15, AWE_FX_ENV2_RELEASE, fx_env2_release}, | ||
5685 | |||
5686 | {16, AWE_FX_INIT_PITCH, fx_init_pitch}, | ||
5687 | {17, AWE_FX_LFO1_PITCH, fx_lfo1_pitch}, | ||
5688 | {18, AWE_FX_LFO2_PITCH, fx_lfo2_pitch}, | ||
5689 | {19, AWE_FX_ENV1_PITCH, fx_env1_pitch}, | ||
5690 | {20, AWE_FX_LFO1_VOLUME, fx_lfo1_volume}, | ||
5691 | {21, AWE_FX_CUTOFF, fx_cutoff}, | ||
5692 | {22, AWE_FX_FILTERQ, fx_filterQ}, | ||
5693 | {23, AWE_FX_LFO1_CUTOFF, fx_lfo1_cutoff}, | ||
5694 | {24, AWE_FX_ENV1_CUTOFF, fx_env1_cutoff}, | ||
5695 | {25, AWE_FX_CHORUS, fx_chorus}, | ||
5696 | {26, AWE_FX_REVERB, fx_reverb}, | ||
5697 | }; | ||
5698 | |||
5699 | static int num_awe_effects = numberof(awe_effects); | ||
5700 | |||
5701 | |||
5702 | /* | ||
5703 | * GS(SC88) NRPN effects; still experimental | ||
5704 | */ | ||
5705 | |||
5706 | /* cutoff: quarter semitone step, max=255 */ | ||
5707 | static unsigned short gs_cutoff(int val) | ||
5708 | { | ||
5709 | return (val - 64) * gs_sense[FX_CUTOFF] / 50; | ||
5710 | } | ||
5711 | |||
5712 | /* resonance: 0 to 15(max) */ | ||
5713 | static unsigned short gs_filterQ(int val) | ||
5714 | { | ||
5715 | return (val - 64) * gs_sense[FX_RESONANCE] / 50; | ||
5716 | } | ||
5717 | |||
5718 | /* attack: */ | ||
5719 | static unsigned short gs_attack(int val) | ||
5720 | { | ||
5721 | return -(val - 64) * gs_sense[FX_ATTACK] / 50; | ||
5722 | } | ||
5723 | |||
5724 | /* decay: */ | ||
5725 | static unsigned short gs_decay(int val) | ||
5726 | { | ||
5727 | return -(val - 64) * gs_sense[FX_RELEASE] / 50; | ||
5728 | } | ||
5729 | |||
5730 | /* release: */ | ||
5731 | static unsigned short gs_release(int val) | ||
5732 | { | ||
5733 | return -(val - 64) * gs_sense[FX_RELEASE] / 50; | ||
5734 | } | ||
5735 | |||
5736 | /* vibrato freq: 0.042Hz step, max=255 */ | ||
5737 | static unsigned short gs_vib_rate(int val) | ||
5738 | { | ||
5739 | return (val - 64) * gs_sense[FX_VIBRATE] / 50; | ||
5740 | } | ||
5741 | |||
5742 | /* vibrato depth: max=127, 1 octave */ | ||
5743 | static unsigned short gs_vib_depth(int val) | ||
5744 | { | ||
5745 | return (val - 64) * gs_sense[FX_VIBDEPTH] / 50; | ||
5746 | } | ||
5747 | |||
5748 | /* vibrato delay: -0.725msec step */ | ||
5749 | static unsigned short gs_vib_delay(int val) | ||
5750 | { | ||
5751 | return -(val - 64) * gs_sense[FX_VIBDELAY] / 50; | ||
5752 | } | ||
5753 | |||
5754 | static ConvTable gs_effects[] = | ||
5755 | { | ||
5756 | {32, AWE_FX_CUTOFF, gs_cutoff}, | ||
5757 | {33, AWE_FX_FILTERQ, gs_filterQ}, | ||
5758 | {99, AWE_FX_ENV2_ATTACK, gs_attack}, | ||
5759 | {100, AWE_FX_ENV2_DECAY, gs_decay}, | ||
5760 | {102, AWE_FX_ENV2_RELEASE, gs_release}, | ||
5761 | {8, AWE_FX_LFO1_FREQ, gs_vib_rate}, | ||
5762 | {9, AWE_FX_LFO1_VOLUME, gs_vib_depth}, | ||
5763 | {10, AWE_FX_LFO1_DELAY, gs_vib_delay}, | ||
5764 | }; | ||
5765 | |||
5766 | static int num_gs_effects = numberof(gs_effects); | ||
5767 | |||
5768 | |||
5769 | /* | ||
5770 | * NRPN events: accept as AWE32/SC88 specific controls | ||
5771 | */ | ||
5772 | |||
5773 | static void midi_nrpn_event(MidiStatus *st) | ||
5774 | { | ||
5775 | if (rpn_msb[st->chan] == 127 && rpn_lsb[st->chan] <= 26) { | ||
5776 | if (! msb_bit) /* both MSB/LSB necessary */ | ||
5777 | send_converted_effect(awe_effects, num_awe_effects, | ||
5778 | st, rpn_lsb[st->chan], | ||
5779 | rpn_val[st->chan] - 8192); | ||
5780 | } else if (rpn_msb[st->chan] == 1) { | ||
5781 | if (msb_bit) /* only MSB is valid */ | ||
5782 | add_converted_effect(gs_effects, num_gs_effects, | ||
5783 | st, rpn_lsb[st->chan], | ||
5784 | rpn_val[st->chan] / 128); | ||
5785 | } | ||
5786 | } | ||
5787 | |||
5788 | |||
5789 | /* | ||
5790 | * XG control effects; still experimental | ||
5791 | */ | ||
5792 | |||
5793 | /* cutoff: quarter semitone step, max=255 */ | ||
5794 | static unsigned short xg_cutoff(int val) | ||
5795 | { | ||
5796 | return (val - 64) * xg_sense[FX_CUTOFF] / 64; | ||
5797 | } | ||
5798 | |||
5799 | /* resonance: 0(open) to 15(most nasal) */ | ||
5800 | static unsigned short xg_filterQ(int val) | ||
5801 | { | ||
5802 | return (val - 64) * xg_sense[FX_RESONANCE] / 64; | ||
5803 | } | ||
5804 | |||
5805 | /* attack: */ | ||
5806 | static unsigned short xg_attack(int val) | ||
5807 | { | ||
5808 | return -(val - 64) * xg_sense[FX_ATTACK] / 64; | ||
5809 | } | ||
5810 | |||
5811 | /* release: */ | ||
5812 | static unsigned short xg_release(int val) | ||
5813 | { | ||
5814 | return -(val - 64) * xg_sense[FX_RELEASE] / 64; | ||
5815 | } | ||
5816 | |||
5817 | static ConvTable xg_effects[] = | ||
5818 | { | ||
5819 | {71, AWE_FX_CUTOFF, xg_cutoff}, | ||
5820 | {74, AWE_FX_FILTERQ, xg_filterQ}, | ||
5821 | {72, AWE_FX_ENV2_RELEASE, xg_release}, | ||
5822 | {73, AWE_FX_ENV2_ATTACK, xg_attack}, | ||
5823 | }; | ||
5824 | |||
5825 | static int num_xg_effects = numberof(xg_effects); | ||
5826 | |||
5827 | static int xg_control_change(MidiStatus *st, int cmd, int val) | ||
5828 | { | ||
5829 | return add_converted_effect(xg_effects, num_xg_effects, st, cmd, val); | ||
5830 | } | ||
5831 | |||
5832 | #endif /* CONFIG_AWE32_MIDIEMU */ | ||
5833 | |||
5834 | |||
5835 | /*----------------------------------------------------------------*/ | ||
5836 | |||
5837 | |||
5838 | /* | ||
5839 | * initialization of AWE driver | ||
5840 | */ | ||
5841 | |||
5842 | static void | ||
5843 | awe_initialize(void) | ||
5844 | { | ||
5845 | DEBUG(0,printk("AWE32: initializing..\n")); | ||
5846 | |||
5847 | /* initialize hardware configuration */ | ||
5848 | awe_poke(AWE_HWCF1, 0x0059); | ||
5849 | awe_poke(AWE_HWCF2, 0x0020); | ||
5850 | |||
5851 | /* disable audio; this seems to reduce a clicking noise a bit.. */ | ||
5852 | awe_poke(AWE_HWCF3, 0); | ||
5853 | |||
5854 | /* initialize audio channels */ | ||
5855 | awe_init_audio(); | ||
5856 | |||
5857 | /* initialize DMA */ | ||
5858 | awe_init_dma(); | ||
5859 | |||
5860 | /* initialize init array */ | ||
5861 | awe_init_array(); | ||
5862 | |||
5863 | /* check DRAM memory size */ | ||
5864 | awe_check_dram(); | ||
5865 | |||
5866 | /* initialize the FM section of the AWE32 */ | ||
5867 | awe_init_fm(); | ||
5868 | |||
5869 | /* set up voice envelopes */ | ||
5870 | awe_tweak(); | ||
5871 | |||
5872 | /* enable audio */ | ||
5873 | awe_poke(AWE_HWCF3, 0x0004); | ||
5874 | |||
5875 | /* set default values */ | ||
5876 | awe_init_ctrl_parms(TRUE); | ||
5877 | |||
5878 | /* set equalizer */ | ||
5879 | awe_update_equalizer(); | ||
5880 | |||
5881 | /* set reverb & chorus modes */ | ||
5882 | awe_update_reverb_mode(); | ||
5883 | awe_update_chorus_mode(); | ||
5884 | } | ||
5885 | |||
5886 | |||
5887 | /* | ||
5888 | * Core Device Management Functions | ||
5889 | */ | ||
5890 | |||
5891 | /* store values to i/o port array */ | ||
5892 | static void setup_ports(int port1, int port2, int port3) | ||
5893 | { | ||
5894 | awe_ports[0] = port1; | ||
5895 | if (port2 == 0) | ||
5896 | port2 = port1 + 0x400; | ||
5897 | awe_ports[1] = port2; | ||
5898 | awe_ports[2] = port2 + 2; | ||
5899 | if (port3 == 0) | ||
5900 | port3 = port1 + 0x800; | ||
5901 | awe_ports[3] = port3; | ||
5902 | awe_ports[4] = port3 + 2; | ||
5903 | |||
5904 | port_setuped = TRUE; | ||
5905 | } | ||
5906 | |||
5907 | /* | ||
5908 | * port request | ||
5909 | * 0x620-623, 0xA20-A23, 0xE20-E23 | ||
5910 | */ | ||
5911 | |||
5912 | static int | ||
5913 | awe_request_region(void) | ||
5914 | { | ||
5915 | if (! port_setuped) | ||
5916 | return 0; | ||
5917 | if (! request_region(awe_ports[0], 4, "sound driver (AWE32)")) | ||
5918 | return 0; | ||
5919 | if (! request_region(awe_ports[1], 4, "sound driver (AWE32)")) | ||
5920 | goto err_out; | ||
5921 | if (! request_region(awe_ports[3], 4, "sound driver (AWE32)")) | ||
5922 | goto err_out1; | ||
5923 | return 1; | ||
5924 | err_out1: | ||
5925 | release_region(awe_ports[1], 4); | ||
5926 | err_out: | ||
5927 | release_region(awe_ports[0], 4); | ||
5928 | return 0; | ||
5929 | } | ||
5930 | |||
5931 | static void | ||
5932 | awe_release_region(void) | ||
5933 | { | ||
5934 | if (! port_setuped) return; | ||
5935 | release_region(awe_ports[0], 4); | ||
5936 | release_region(awe_ports[1], 4); | ||
5937 | release_region(awe_ports[3], 4); | ||
5938 | } | ||
5939 | |||
5940 | static int awe_attach_device(void) | ||
5941 | { | ||
5942 | if (awe_present) return 0; /* for OSS38.. called twice? */ | ||
5943 | |||
5944 | /* reserve I/O ports for awedrv */ | ||
5945 | if (! awe_request_region()) { | ||
5946 | printk(KERN_ERR "AWE32: I/O area already used.\n"); | ||
5947 | return 0; | ||
5948 | } | ||
5949 | |||
5950 | /* set buffers to NULL */ | ||
5951 | sfhead = sftail = NULL; | ||
5952 | |||
5953 | my_dev = sound_alloc_synthdev(); | ||
5954 | if (my_dev == -1) { | ||
5955 | printk(KERN_ERR "AWE32 Error: too many synthesizers\n"); | ||
5956 | awe_release_region(); | ||
5957 | return 0; | ||
5958 | } | ||
5959 | |||
5960 | voice_alloc = &awe_operations.alloc; | ||
5961 | voice_alloc->max_voice = awe_max_voices; | ||
5962 | synth_devs[my_dev] = &awe_operations; | ||
5963 | |||
5964 | #ifdef CONFIG_AWE32_MIXER | ||
5965 | attach_mixer(); | ||
5966 | #endif | ||
5967 | #ifdef CONFIG_AWE32_MIDIEMU | ||
5968 | attach_midiemu(); | ||
5969 | #endif | ||
5970 | |||
5971 | /* clear all samples */ | ||
5972 | awe_reset_samples(); | ||
5973 | |||
5974 | /* initialize AWE32 hardware */ | ||
5975 | awe_initialize(); | ||
5976 | |||
5977 | sprintf(awe_info.name, "AWE32-%s (RAM%dk)", | ||
5978 | AWEDRV_VERSION, memsize/1024); | ||
5979 | printk(KERN_INFO "<SoundBlaster EMU8000 (RAM%dk)>\n", memsize/1024); | ||
5980 | |||
5981 | awe_present = TRUE; | ||
5982 | |||
5983 | return 1; | ||
5984 | } | ||
5985 | |||
5986 | static void awe_dettach_device(void) | ||
5987 | { | ||
5988 | if (awe_present) { | ||
5989 | awe_reset_samples(); | ||
5990 | awe_release_region(); | ||
5991 | free_tables(); | ||
5992 | #ifdef CONFIG_AWE32_MIXER | ||
5993 | unload_mixer(); | ||
5994 | #endif | ||
5995 | #ifdef CONFIG_AWE32_MIDIEMU | ||
5996 | unload_midiemu(); | ||
5997 | #endif | ||
5998 | sound_unload_synthdev(my_dev); | ||
5999 | awe_present = FALSE; | ||
6000 | } | ||
6001 | } | ||
6002 | |||
6003 | |||
6004 | /* | ||
6005 | * Legacy device Probing | ||
6006 | */ | ||
6007 | |||
6008 | /* detect emu8000 chip on the specified address; from VV's guide */ | ||
6009 | |||
6010 | static int __init | ||
6011 | awe_detect_base(int addr) | ||
6012 | { | ||
6013 | setup_ports(addr, 0, 0); | ||
6014 | if ((awe_peek(AWE_U1) & 0x000F) != 0x000C) | ||
6015 | return 0; | ||
6016 | if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058) | ||
6017 | return 0; | ||
6018 | if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003) | ||
6019 | return 0; | ||
6020 | DEBUG(0,printk("AWE32 found at %x\n", addr)); | ||
6021 | return 1; | ||
6022 | } | ||
6023 | |||
6024 | static int __init awe_detect_legacy_devices(void) | ||
6025 | { | ||
6026 | int base; | ||
6027 | for (base = 0x620; base <= 0x680; base += 0x20) | ||
6028 | if (awe_detect_base(base)) { | ||
6029 | awe_attach_device(); | ||
6030 | return 1; | ||
6031 | } | ||
6032 | DEBUG(0,printk("AWE32 Legacy detection failed\n")); | ||
6033 | return 0; | ||
6034 | } | ||
6035 | |||
6036 | |||
6037 | /* | ||
6038 | * PnP device Probing | ||
6039 | */ | ||
6040 | |||
6041 | static struct pnp_device_id awe_pnp_ids[] = { | ||
6042 | {.id = "CTL0021", .driver_data = 0}, /* AWE32 WaveTable */ | ||
6043 | {.id = "CTL0022", .driver_data = 0}, /* AWE64 WaveTable */ | ||
6044 | {.id = "CTL0023", .driver_data = 0}, /* AWE64 Gold WaveTable */ | ||
6045 | { } /* terminator */ | ||
6046 | }; | ||
6047 | |||
6048 | MODULE_DEVICE_TABLE(pnp, awe_pnp_ids); | ||
6049 | |||
6050 | static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | ||
6051 | { | ||
6052 | int io1, io2, io3; | ||
6053 | |||
6054 | if (awe_present) { | ||
6055 | printk(KERN_ERR "AWE32: This driver only supports one AWE32 device, skipping.\n"); | ||
6056 | } | ||
6057 | |||
6058 | if (!pnp_port_valid(dev,0) || | ||
6059 | !pnp_port_valid(dev,1) || | ||
6060 | !pnp_port_valid(dev,2)) { | ||
6061 | printk(KERN_ERR "AWE32: The PnP device does not have the required resources.\n"); | ||
6062 | return -EINVAL; | ||
6063 | } | ||
6064 | io1 = pnp_port_start(dev,0); | ||
6065 | io2 = pnp_port_start(dev,1); | ||
6066 | io3 = pnp_port_start(dev,2); | ||
6067 | printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n", | ||
6068 | io1, io2, io3); | ||
6069 | setup_ports(io1, io2, io3); | ||
6070 | |||
6071 | awe_attach_device(); | ||
6072 | return 0; | ||
6073 | } | ||
6074 | |||
6075 | static void awe_pnp_remove(struct pnp_dev *dev) | ||
6076 | { | ||
6077 | awe_dettach_device(); | ||
6078 | } | ||
6079 | |||
6080 | static struct pnp_driver awe_pnp_driver = { | ||
6081 | .name = "AWE32", | ||
6082 | .id_table = awe_pnp_ids, | ||
6083 | .probe = awe_pnp_probe, | ||
6084 | .remove = awe_pnp_remove, | ||
6085 | }; | ||
6086 | |||
6087 | static int __init awe_detect_pnp_devices(void) | ||
6088 | { | ||
6089 | int ret; | ||
6090 | |||
6091 | ret = pnp_register_driver(&awe_pnp_driver); | ||
6092 | if (ret<0) | ||
6093 | printk(KERN_ERR "AWE32: PnP support is unavailable.\n"); | ||
6094 | return ret; | ||
6095 | } | ||
6096 | |||
6097 | |||
6098 | /* | ||
6099 | * device / lowlevel (module) interface | ||
6100 | */ | ||
6101 | |||
6102 | static int __init | ||
6103 | awe_detect(void) | ||
6104 | { | ||
6105 | printk(KERN_INFO "AWE32: Probing for WaveTable...\n"); | ||
6106 | if (isapnp) { | ||
6107 | if (awe_detect_pnp_devices()>=0) | ||
6108 | return 1; | ||
6109 | } else | ||
6110 | printk(KERN_INFO "AWE32: Skipping PnP detection.\n"); | ||
6111 | |||
6112 | if (awe_detect_legacy_devices()) | ||
6113 | return 1; | ||
6114 | |||
6115 | return 0; | ||
6116 | } | ||
6117 | |||
6118 | static int __init attach_awe(void) | ||
6119 | { | ||
6120 | return awe_detect() ? 0 : -ENODEV; | ||
6121 | } | ||
6122 | |||
6123 | static void __exit unload_awe(void) | ||
6124 | { | ||
6125 | pnp_unregister_driver(&awe_pnp_driver); | ||
6126 | awe_dettach_device(); | ||
6127 | } | ||
6128 | |||
6129 | |||
6130 | module_init(attach_awe); | ||
6131 | module_exit(unload_awe); | ||
6132 | |||
6133 | #ifndef MODULE | ||
6134 | static int __init setup_awe(char *str) | ||
6135 | { | ||
6136 | /* io, memsize, isapnp */ | ||
6137 | int ints[4]; | ||
6138 | |||
6139 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
6140 | |||
6141 | io = ints[1]; | ||
6142 | memsize = ints[2]; | ||
6143 | isapnp = ints[3]; | ||
6144 | |||
6145 | return 1; | ||
6146 | } | ||
6147 | |||
6148 | __setup("awe=", setup_awe); | ||
6149 | #endif | ||
diff --git a/sound/oss/awe_wave.h b/sound/oss/awe_wave.h deleted file mode 100644 index fe584810608f..000000000000 --- a/sound/oss/awe_wave.h +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/awe_wave.h | ||
3 | * | ||
4 | * Configuration of AWE32/SB32/AWE64 wave table synth driver. | ||
5 | * version 0.4.4; Jan. 4, 2000 | ||
6 | * | ||
7 | * Copyright (C) 1996-1998 Takashi Iwai | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * chorus & reverb effects send for FM chip: from 0 to 0xff | ||
26 | * larger numbers often cause weird sounds. | ||
27 | */ | ||
28 | |||
29 | #define DEF_FM_CHORUS_DEPTH 0x10 | ||
30 | #define DEF_FM_REVERB_DEPTH 0x10 | ||
31 | |||
32 | |||
33 | /* | ||
34 | * other compile conditions | ||
35 | */ | ||
36 | |||
37 | /* initialize FM passthrough even without extended RAM */ | ||
38 | #undef AWE_ALWAYS_INIT_FM | ||
39 | |||
40 | /* debug on */ | ||
41 | #define AWE_DEBUG_ON | ||
42 | |||
43 | /* GUS compatible mode */ | ||
44 | #define AWE_HAS_GUS_COMPATIBILITY | ||
45 | |||
46 | /* add MIDI emulation by wavetable */ | ||
47 | #define CONFIG_AWE32_MIDIEMU | ||
48 | |||
49 | /* add mixer control of emu8000 equalizer */ | ||
50 | #undef CONFIG_AWE32_MIXER | ||
51 | |||
52 | /* use new volume calculation method as default */ | ||
53 | #define AWE_USE_NEW_VOLUME_CALC | ||
54 | |||
55 | /* check current volume target for searching empty voices */ | ||
56 | #define AWE_CHECK_VTARGET | ||
57 | |||
58 | /* allow sample sharing */ | ||
59 | #define AWE_ALLOW_SAMPLE_SHARING | ||
60 | |||
61 | /* | ||
62 | * AWE32 card configuration: | ||
63 | * uncomment the following lines *ONLY* when auto detection doesn't | ||
64 | * work properly on your machine. | ||
65 | */ | ||
66 | |||
67 | /*#define AWE_DEFAULT_BASE_ADDR 0x620*/ /* base port address */ | ||
68 | /*#define AWE_DEFAULT_MEM_SIZE 512*/ /* kbytes */ | ||
69 | |||
70 | /* | ||
71 | * AWE driver version number | ||
72 | */ | ||
73 | #define AWE_MAJOR_VERSION 0 | ||
74 | #define AWE_MINOR_VERSION 4 | ||
75 | #define AWE_TINY_VERSION 4 | ||
76 | #define AWE_VERSION_NUMBER ((AWE_MAJOR_VERSION<<16)|(AWE_MINOR_VERSION<<8)|AWE_TINY_VERSION) | ||
77 | #define AWEDRV_VERSION "0.4.4" | ||
diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c deleted file mode 100644 index ea51aafaf401..000000000000 --- a/sound/oss/cmpci.c +++ /dev/null | |||
@@ -1,3381 +0,0 @@ | |||
1 | /* | ||
2 | * cmpci.c -- C-Media PCI audio driver. | ||
3 | * | ||
4 | * Copyright (C) 1999 C-media support (support@cmedia.com.tw) | ||
5 | * | ||
6 | * Based on the PCI drivers by Thomas Sailer (sailer@ife.ee.ethz.ch) | ||
7 | * | ||
8 | * For update, visit: | ||
9 | * http://www.cmedia.com.tw | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | * Special thanks to David C. Niemi, Jan Pfeifer | ||
26 | * | ||
27 | * | ||
28 | * Module command line parameters: | ||
29 | * none so far | ||
30 | * | ||
31 | * | ||
32 | * Supported devices: | ||
33 | * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible | ||
34 | * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible | ||
35 | * /dev/midi simple MIDI UART interface, no ioctl | ||
36 | * | ||
37 | * The card has both an FM and a Wavetable synth, but I have to figure | ||
38 | * out first how to drive them... | ||
39 | * | ||
40 | * Revision history | ||
41 | * 06.05.98 0.1 Initial release | ||
42 | * 10.05.98 0.2 Fixed many bugs, esp. ADC rate calculation | ||
43 | * First stab at a simple midi interface (no bells&whistles) | ||
44 | * 13.05.98 0.3 Fix stupid cut&paste error: set_adc_rate was called instead of | ||
45 | * set_dac_rate in the FMODE_WRITE case in cm_open | ||
46 | * Fix hwptr out of bounds (now mpg123 works) | ||
47 | * 14.05.98 0.4 Don't allow excessive interrupt rates | ||
48 | * 08.06.98 0.5 First release using Alan Cox' soundcore instead of miscdevice | ||
49 | * 03.08.98 0.6 Do not include modversions.h | ||
50 | * Now mixer behaviour can basically be selected between | ||
51 | * "OSS documented" and "OSS actual" behaviour | ||
52 | * 31.08.98 0.7 Fix realplayer problems - dac.count issues | ||
53 | * 10.12.98 0.8 Fix drain_dac trying to wait on not yet initialized DMA | ||
54 | * 16.12.98 0.9 Fix a few f_file & FMODE_ bugs | ||
55 | * 06.01.99 0.10 remove the silly SA_INTERRUPT flag. | ||
56 | * hopefully killed the egcs section type conflict | ||
57 | * 12.03.99 0.11 cinfo.blocks should be reset after GETxPTR ioctl. | ||
58 | * reported by Johan Maes <joma@telindus.be> | ||
59 | * 22.03.99 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK | ||
60 | * read/write cannot be executed | ||
61 | * 18.08.99 1.5 Only deallocate DMA buffer when unloading. | ||
62 | * 02.09.99 1.6 Enable SPDIF LOOP | ||
63 | * Change the mixer read back | ||
64 | * 21.09.99 2.33 Use RCS version as driver version. | ||
65 | * Add support for modem, S/PDIF loop and 4 channels. | ||
66 | * (8738 only) | ||
67 | * Fix bug cause x11amp cannot play. | ||
68 | * | ||
69 | * Fixes: | ||
70 | * Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
71 | * 18/05/2001 - .bss nitpicks, fix a bug in set_dac_channels where it | ||
72 | * was calling prog_dmabuf with s->lock held, call missing | ||
73 | * unlock_kernel in cm_midi_release | ||
74 | * 08/10/2001 - use set_current_state in some more places | ||
75 | * | ||
76 | * Carlos Eduardo Gorges <carlos@techlinux.com.br> | ||
77 | * Fri May 25 2001 | ||
78 | * - SMP support ( spin[un]lock* revision ) | ||
79 | * - speaker mixer support | ||
80 | * Mon Aug 13 2001 | ||
81 | * - optimizations and cleanups | ||
82 | * | ||
83 | * 03/01/2003 - open_mode fixes from Georg Acher <acher@in.tum.de> | ||
84 | * Simon Braunschmidt <brasimon@web.de> | ||
85 | * Sat Jan 31 2004 | ||
86 | * - provide support for opl3 FM by releasing IO range after initialization | ||
87 | * | ||
88 | * ChenLi Tien <cltien@cmedia.com.tw> | ||
89 | * Mar 9 2004 | ||
90 | * - Fix S/PDIF out if spdif_loop enabled | ||
91 | * - Load opl3 driver if enabled (fmio in proper range) | ||
92 | * - Load mpu401 if enabled (mpuio in proper range) | ||
93 | * Apr 5 2004 | ||
94 | * - Fix DUAL_DAC dma synchronization bug | ||
95 | * - Check exist FM/MPU401 I/O before activate. | ||
96 | * - Add AFTM_S16_BE format support, so MPlayer/Xine can play AC3/mutlichannel | ||
97 | * on Mac | ||
98 | * - Change to support kernel 2.6 so only small patch needed | ||
99 | * - All parameters default to 0 | ||
100 | * - Add spdif_out to send PCM through S/PDIF out jack | ||
101 | * - Add hw_copy to get 4-spaker output for general PCM/analog output | ||
102 | * | ||
103 | * Stefan Thater <stefan.thaeter@gmx.de> | ||
104 | * Apr 5 2004 | ||
105 | * - Fix mute single channel for CD/Line-in/AUX-in | ||
106 | */ | ||
107 | /*****************************************************************************/ | ||
108 | |||
109 | #include <linux/config.h> | ||
110 | #include <linux/module.h> | ||
111 | #include <linux/string.h> | ||
112 | #include <linux/interrupt.h> | ||
113 | #include <linux/ioport.h> | ||
114 | #include <linux/sched.h> | ||
115 | #include <linux/delay.h> | ||
116 | #include <linux/sound.h> | ||
117 | #include <linux/slab.h> | ||
118 | #include <linux/soundcard.h> | ||
119 | #include <linux/pci.h> | ||
120 | #include <linux/init.h> | ||
121 | #include <linux/poll.h> | ||
122 | #include <linux/spinlock.h> | ||
123 | #include <linux/smp_lock.h> | ||
124 | #include <linux/bitops.h> | ||
125 | #include <linux/wait.h> | ||
126 | #include <linux/dma-mapping.h> | ||
127 | |||
128 | #include <asm/io.h> | ||
129 | #include <asm/page.h> | ||
130 | #include <asm/uaccess.h> | ||
131 | |||
132 | #ifdef CONFIG_SOUND_CMPCI_MIDI | ||
133 | #include "sound_config.h" | ||
134 | #include "mpu401.h" | ||
135 | #endif | ||
136 | #ifdef CONFIG_SOUND_CMPCI_FM | ||
137 | #include "opl3.h" | ||
138 | #endif | ||
139 | #ifdef CONFIG_SOUND_CMPCI_JOYSTICK | ||
140 | #include <linux/gameport.h> | ||
141 | #include <linux/mutex.h> | ||
142 | |||
143 | #endif | ||
144 | |||
145 | /* --------------------------------------------------------------------- */ | ||
146 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
147 | #undef DMABYTEIO | ||
148 | #define DBG(x) {} | ||
149 | /* --------------------------------------------------------------------- */ | ||
150 | |||
151 | #define CM_MAGIC ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A) | ||
152 | |||
153 | /* CM8338 registers definition ****************/ | ||
154 | |||
155 | #define CODEC_CMI_FUNCTRL0 (0x00) | ||
156 | #define CODEC_CMI_FUNCTRL1 (0x04) | ||
157 | #define CODEC_CMI_CHFORMAT (0x08) | ||
158 | #define CODEC_CMI_INT_HLDCLR (0x0C) | ||
159 | #define CODEC_CMI_INT_STATUS (0x10) | ||
160 | #define CODEC_CMI_LEGACY_CTRL (0x14) | ||
161 | #define CODEC_CMI_MISC_CTRL (0x18) | ||
162 | #define CODEC_CMI_TDMA_POS (0x1C) | ||
163 | #define CODEC_CMI_MIXER (0x20) | ||
164 | #define CODEC_SB16_DATA (0x22) | ||
165 | #define CODEC_SB16_ADDR (0x23) | ||
166 | #define CODEC_CMI_MIXER1 (0x24) | ||
167 | #define CODEC_CMI_MIXER2 (0x25) | ||
168 | #define CODEC_CMI_AUX_VOL (0x26) | ||
169 | #define CODEC_CMI_MISC (0x27) | ||
170 | #define CODEC_CMI_AC97 (0x28) | ||
171 | |||
172 | #define CODEC_CMI_CH0_FRAME1 (0x80) | ||
173 | #define CODEC_CMI_CH0_FRAME2 (0x84) | ||
174 | #define CODEC_CMI_CH1_FRAME1 (0x88) | ||
175 | #define CODEC_CMI_CH1_FRAME2 (0x8C) | ||
176 | |||
177 | #define CODEC_CMI_SPDIF_CTRL (0x90) | ||
178 | #define CODEC_CMI_MISC_CTRL2 (0x92) | ||
179 | |||
180 | #define CODEC_CMI_EXT_REG (0xF0) | ||
181 | |||
182 | /* Mixer registers for SB16 ******************/ | ||
183 | |||
184 | #define DSP_MIX_DATARESETIDX ((unsigned char)(0x00)) | ||
185 | |||
186 | #define DSP_MIX_MASTERVOLIDX_L ((unsigned char)(0x30)) | ||
187 | #define DSP_MIX_MASTERVOLIDX_R ((unsigned char)(0x31)) | ||
188 | #define DSP_MIX_VOICEVOLIDX_L ((unsigned char)(0x32)) | ||
189 | #define DSP_MIX_VOICEVOLIDX_R ((unsigned char)(0x33)) | ||
190 | #define DSP_MIX_FMVOLIDX_L ((unsigned char)(0x34)) | ||
191 | #define DSP_MIX_FMVOLIDX_R ((unsigned char)(0x35)) | ||
192 | #define DSP_MIX_CDVOLIDX_L ((unsigned char)(0x36)) | ||
193 | #define DSP_MIX_CDVOLIDX_R ((unsigned char)(0x37)) | ||
194 | #define DSP_MIX_LINEVOLIDX_L ((unsigned char)(0x38)) | ||
195 | #define DSP_MIX_LINEVOLIDX_R ((unsigned char)(0x39)) | ||
196 | |||
197 | #define DSP_MIX_MICVOLIDX ((unsigned char)(0x3A)) | ||
198 | #define DSP_MIX_SPKRVOLIDX ((unsigned char)(0x3B)) | ||
199 | |||
200 | #define DSP_MIX_OUTMIXIDX ((unsigned char)(0x3C)) | ||
201 | |||
202 | #define DSP_MIX_ADCMIXIDX_L ((unsigned char)(0x3D)) | ||
203 | #define DSP_MIX_ADCMIXIDX_R ((unsigned char)(0x3E)) | ||
204 | |||
205 | #define DSP_MIX_INGAINIDX_L ((unsigned char)(0x3F)) | ||
206 | #define DSP_MIX_INGAINIDX_R ((unsigned char)(0x40)) | ||
207 | #define DSP_MIX_OUTGAINIDX_L ((unsigned char)(0x41)) | ||
208 | #define DSP_MIX_OUTGAINIDX_R ((unsigned char)(0x42)) | ||
209 | |||
210 | #define DSP_MIX_AGCIDX ((unsigned char)(0x43)) | ||
211 | |||
212 | #define DSP_MIX_TREBLEIDX_L ((unsigned char)(0x44)) | ||
213 | #define DSP_MIX_TREBLEIDX_R ((unsigned char)(0x45)) | ||
214 | #define DSP_MIX_BASSIDX_L ((unsigned char)(0x46)) | ||
215 | #define DSP_MIX_BASSIDX_R ((unsigned char)(0x47)) | ||
216 | #define DSP_MIX_EXTENSION ((unsigned char)(0xf0)) | ||
217 | // pseudo register for AUX | ||
218 | #define DSP_MIX_AUXVOL_L ((unsigned char)(0x50)) | ||
219 | #define DSP_MIX_AUXVOL_R ((unsigned char)(0x51)) | ||
220 | |||
221 | // I/O length | ||
222 | #define CM_EXTENT_CODEC 0x100 | ||
223 | #define CM_EXTENT_MIDI 0x2 | ||
224 | #define CM_EXTENT_SYNTH 0x4 | ||
225 | #define CM_EXTENT_GAME 0x8 | ||
226 | |||
227 | // Function Control Register 0 (00h) | ||
228 | #define CHADC0 0x01 | ||
229 | #define CHADC1 0x02 | ||
230 | #define PAUSE0 0x04 | ||
231 | #define PAUSE1 0x08 | ||
232 | |||
233 | // Function Control Register 0+2 (02h) | ||
234 | #define CHEN0 0x01 | ||
235 | #define CHEN1 0x02 | ||
236 | #define RST_CH0 0x04 | ||
237 | #define RST_CH1 0x08 | ||
238 | |||
239 | // Function Control Register 1 (04h) | ||
240 | #define JYSTK_EN 0x02 | ||
241 | #define UART_EN 0x04 | ||
242 | #define SPDO2DAC 0x40 | ||
243 | #define SPDFLOOP 0x80 | ||
244 | |||
245 | // Function Control Register 1+1 (05h) | ||
246 | #define SPDF_0 0x01 | ||
247 | #define SPDF_1 0x02 | ||
248 | #define ASFC 0x1c | ||
249 | #define DSFC 0xe0 | ||
250 | #define SPDIF2DAC (SPDF_1 << 8 | SPDO2DAC) | ||
251 | |||
252 | // Channel Format Register (08h) | ||
253 | #define CM_CFMT_STEREO 0x01 | ||
254 | #define CM_CFMT_16BIT 0x02 | ||
255 | #define CM_CFMT_MASK 0x03 | ||
256 | #define POLVALID 0x20 | ||
257 | #define INVSPDIFI 0x80 | ||
258 | |||
259 | // Channel Format Register+2 (0ah) | ||
260 | #define SPD24SEL 0x20 | ||
261 | |||
262 | // Channel Format Register+3 (0bh) | ||
263 | #define CHB3D 0x20 | ||
264 | #define CHB3D5C 0x80 | ||
265 | |||
266 | // Interrupt Hold/Clear Register+2 (0eh) | ||
267 | #define CH0_INT_EN 0x01 | ||
268 | #define CH1_INT_EN 0x02 | ||
269 | |||
270 | // Interrupt Register (10h) | ||
271 | #define CHINT0 0x01 | ||
272 | #define CHINT1 0x02 | ||
273 | #define CH0BUSY 0x04 | ||
274 | #define CH1BUSY 0x08 | ||
275 | |||
276 | // Legacy Control/Status Register+1 (15h) | ||
277 | #define EXBASEN 0x10 | ||
278 | #define BASE2LIN 0x20 | ||
279 | #define CENTR2LIN 0x40 | ||
280 | #define CB2LIN (BASE2LIN | CENTR2LIN) | ||
281 | #define CHB3D6C 0x80 | ||
282 | |||
283 | // Legacy Control/Status Register+2 (16h) | ||
284 | #define DAC2SPDO 0x20 | ||
285 | #define SPDCOPYRHT 0x40 | ||
286 | #define ENSPDOUT 0x80 | ||
287 | |||
288 | // Legacy Control/Status Register+3 (17h) | ||
289 | #define FMSEL 0x03 | ||
290 | #define VSBSEL 0x0c | ||
291 | #define VMPU 0x60 | ||
292 | #define NXCHG 0x80 | ||
293 | |||
294 | // Miscellaneous Control Register (18h) | ||
295 | #define REAR2LIN 0x20 | ||
296 | #define MUTECH1 0x40 | ||
297 | #define ENCENTER 0x80 | ||
298 | |||
299 | // Miscellaneous Control Register+1 (19h) | ||
300 | #define SELSPDIFI2 0x01 | ||
301 | #define SPDF_AC97 0x80 | ||
302 | |||
303 | // Miscellaneous Control Register+2 (1ah) | ||
304 | #define AC3_EN 0x04 | ||
305 | #define FM_EN 0x08 | ||
306 | #define SPD32SEL 0x20 | ||
307 | #define XCHGDAC 0x40 | ||
308 | #define ENDBDAC 0x80 | ||
309 | |||
310 | // Miscellaneous Control Register+3 (1bh) | ||
311 | #define SPDIFI48K 0x01 | ||
312 | #define SPDO5V 0x02 | ||
313 | #define N4SPK3D 0x04 | ||
314 | #define RESET 0x40 | ||
315 | #define PWD 0x80 | ||
316 | #define SPDIF48K (SPDIFI48K << 24 | SPDF_AC97 << 8) | ||
317 | |||
318 | // Mixer1 (24h) | ||
319 | #define CDPLAY 0x01 | ||
320 | #define X3DEN 0x02 | ||
321 | #define REAR2FRONT 0x10 | ||
322 | #define SPK4 0x20 | ||
323 | #define WSMUTE 0x40 | ||
324 | #define FMMUTE 0x80 | ||
325 | |||
326 | // Miscellaneous Register (27h) | ||
327 | #define SPDVALID 0x02 | ||
328 | #define CENTR2MIC 0x04 | ||
329 | |||
330 | // Miscellaneous Register2 (92h) | ||
331 | #define SPD32KFMT 0x10 | ||
332 | |||
333 | #define CM_CFMT_DACSHIFT 2 | ||
334 | #define CM_CFMT_ADCSHIFT 0 | ||
335 | #define CM_FREQ_DACSHIFT 5 | ||
336 | #define CM_FREQ_ADCSHIFT 2 | ||
337 | #define RSTDAC RST_CH1 | ||
338 | #define RSTADC RST_CH0 | ||
339 | #define ENDAC CHEN1 | ||
340 | #define ENADC CHEN0 | ||
341 | #define PAUSEDAC PAUSE1 | ||
342 | #define PAUSEADC PAUSE0 | ||
343 | #define CODEC_CMI_ADC_FRAME1 CODEC_CMI_CH0_FRAME1 | ||
344 | #define CODEC_CMI_ADC_FRAME2 CODEC_CMI_CH0_FRAME2 | ||
345 | #define CODEC_CMI_DAC_FRAME1 CODEC_CMI_CH1_FRAME1 | ||
346 | #define CODEC_CMI_DAC_FRAME2 CODEC_CMI_CH1_FRAME2 | ||
347 | #define DACINT CHINT1 | ||
348 | #define ADCINT CHINT0 | ||
349 | #define DACBUSY CH1BUSY | ||
350 | #define ADCBUSY CH0BUSY | ||
351 | #define ENDACINT CH1_INT_EN | ||
352 | #define ENADCINT CH0_INT_EN | ||
353 | |||
354 | static const unsigned sample_size[] = { 1, 2, 2, 4 }; | ||
355 | static const unsigned sample_shift[] = { 0, 1, 1, 2 }; | ||
356 | |||
357 | #define SND_DEV_DSP16 5 | ||
358 | |||
359 | #define NR_DEVICE 3 /* maximum number of devices */ | ||
360 | |||
361 | #define set_dac1_rate set_adc_rate | ||
362 | #define set_dac1_rate_unlocked set_adc_rate_unlocked | ||
363 | #define stop_dac1 stop_adc | ||
364 | #define stop_dac1_unlocked stop_adc_unlocked | ||
365 | #define get_dmadac1 get_dmaadc | ||
366 | |||
367 | static unsigned int devindex = 0; | ||
368 | |||
369 | //*********************************************/ | ||
370 | |||
371 | struct cm_state { | ||
372 | /* magic */ | ||
373 | unsigned int magic; | ||
374 | |||
375 | /* list of cmedia devices */ | ||
376 | struct list_head devs; | ||
377 | |||
378 | /* the corresponding pci_dev structure */ | ||
379 | struct pci_dev *dev; | ||
380 | |||
381 | int dev_audio; /* soundcore stuff */ | ||
382 | int dev_mixer; | ||
383 | |||
384 | unsigned int iosb, iobase, iosynth, | ||
385 | iomidi, iogame, irq; /* hardware resources */ | ||
386 | unsigned short deviceid; /* pci_id */ | ||
387 | |||
388 | struct { /* mixer stuff */ | ||
389 | unsigned int modcnt; | ||
390 | unsigned short vol[13]; | ||
391 | } mix; | ||
392 | |||
393 | unsigned int rateadc, ratedac; /* wave stuff */ | ||
394 | unsigned char fmt, enable; | ||
395 | |||
396 | spinlock_t lock; | ||
397 | struct mutex open_mutex; | ||
398 | mode_t open_mode; | ||
399 | wait_queue_head_t open_wait; | ||
400 | |||
401 | struct dmabuf { | ||
402 | void *rawbuf; | ||
403 | dma_addr_t dmaaddr; | ||
404 | unsigned buforder; | ||
405 | unsigned numfrag; | ||
406 | unsigned fragshift; | ||
407 | unsigned hwptr, swptr; | ||
408 | unsigned total_bytes; | ||
409 | int count; | ||
410 | unsigned error; /* over/underrun */ | ||
411 | wait_queue_head_t wait; | ||
412 | |||
413 | unsigned fragsize; /* redundant, but makes calculations easier */ | ||
414 | unsigned dmasize; | ||
415 | unsigned fragsamples; | ||
416 | unsigned dmasamples; | ||
417 | |||
418 | unsigned mapped:1; /* OSS stuff */ | ||
419 | unsigned ready:1; | ||
420 | unsigned endcleared:1; | ||
421 | unsigned enabled:1; | ||
422 | unsigned ossfragshift; | ||
423 | int ossmaxfrags; | ||
424 | unsigned subdivision; | ||
425 | } dma_dac, dma_adc; | ||
426 | |||
427 | #ifdef CONFIG_SOUND_CMPCI_MIDI | ||
428 | int midi_devc; | ||
429 | struct address_info mpu_data; | ||
430 | #endif | ||
431 | #ifdef CONFIG_SOUND_CMPCI_JOYSTICK | ||
432 | struct gameport *gameport; | ||
433 | #endif | ||
434 | |||
435 | int chip_version; | ||
436 | int max_channels; | ||
437 | int curr_channels; | ||
438 | int capability; /* HW capability, various for chip versions */ | ||
439 | |||
440 | int status; /* HW or SW state */ | ||
441 | |||
442 | int spdif_counter; /* spdif frame counter */ | ||
443 | }; | ||
444 | |||
445 | /* flags used for capability */ | ||
446 | #define CAN_AC3_HW 0x00000001 /* 037 or later */ | ||
447 | #define CAN_AC3_SW 0x00000002 /* 033 or later */ | ||
448 | #define CAN_AC3 (CAN_AC3_HW | CAN_AC3_SW) | ||
449 | #define CAN_DUAL_DAC 0x00000004 /* 033 or later */ | ||
450 | #define CAN_MULTI_CH_HW 0x00000008 /* 039 or later */ | ||
451 | #define CAN_MULTI_CH (CAN_MULTI_CH_HW | CAN_DUAL_DAC) | ||
452 | #define CAN_LINE_AS_REAR 0x00000010 /* 033 or later */ | ||
453 | #define CAN_LINE_AS_BASS 0x00000020 /* 039 or later */ | ||
454 | #define CAN_MIC_AS_BASS 0x00000040 /* 039 or later */ | ||
455 | |||
456 | /* flags used for status */ | ||
457 | #define DO_AC3_HW 0x00000001 | ||
458 | #define DO_AC3_SW 0x00000002 | ||
459 | #define DO_AC3 (DO_AC3_HW | DO_AC3_SW) | ||
460 | #define DO_DUAL_DAC 0x00000004 | ||
461 | #define DO_MULTI_CH_HW 0x00000008 | ||
462 | #define DO_MULTI_CH (DO_MULTI_CH_HW | DO_DUAL_DAC) | ||
463 | #define DO_LINE_AS_REAR 0x00000010 /* 033 or later */ | ||
464 | #define DO_LINE_AS_BASS 0x00000020 /* 039 or later */ | ||
465 | #define DO_MIC_AS_BASS 0x00000040 /* 039 or later */ | ||
466 | #define DO_SPDIF_OUT 0x00000100 | ||
467 | #define DO_SPDIF_IN 0x00000200 | ||
468 | #define DO_SPDIF_LOOP 0x00000400 | ||
469 | #define DO_BIGENDIAN_W 0x00001000 /* used in PowerPC */ | ||
470 | #define DO_BIGENDIAN_R 0x00002000 /* used in PowerPC */ | ||
471 | |||
472 | static LIST_HEAD(devs); | ||
473 | |||
474 | static int mpuio; | ||
475 | static int fmio; | ||
476 | static int joystick; | ||
477 | static int spdif_inverse; | ||
478 | static int spdif_loop; | ||
479 | static int spdif_out; | ||
480 | static int use_line_as_rear; | ||
481 | static int use_line_as_bass; | ||
482 | static int use_mic_as_bass; | ||
483 | static int mic_boost; | ||
484 | static int hw_copy; | ||
485 | module_param(mpuio, int, 0); | ||
486 | module_param(fmio, int, 0); | ||
487 | module_param(joystick, bool, 0); | ||
488 | module_param(spdif_inverse, bool, 0); | ||
489 | module_param(spdif_loop, bool, 0); | ||
490 | module_param(spdif_out, bool, 0); | ||
491 | module_param(use_line_as_rear, bool, 0); | ||
492 | module_param(use_line_as_bass, bool, 0); | ||
493 | module_param(use_mic_as_bass, bool, 0); | ||
494 | module_param(mic_boost, bool, 0); | ||
495 | module_param(hw_copy, bool, 0); | ||
496 | MODULE_PARM_DESC(mpuio, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable"); | ||
497 | MODULE_PARM_DESC(fmio, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable"); | ||
498 | MODULE_PARM_DESC(joystick, "(1/0) Enable joystick interface, still need joystick driver"); | ||
499 | MODULE_PARM_DESC(spdif_inverse, "(1/0) Invert S/PDIF-in signal"); | ||
500 | MODULE_PARM_DESC(spdif_loop, "(1/0) Route S/PDIF-in to S/PDIF-out directly"); | ||
501 | MODULE_PARM_DESC(spdif_out, "(1/0) Send PCM to S/PDIF-out (PCM volume will not function)"); | ||
502 | MODULE_PARM_DESC(use_line_as_rear, "(1/0) Use line-in jack as rear-out"); | ||
503 | MODULE_PARM_DESC(use_line_as_bass, "(1/0) Use line-in jack as bass/center"); | ||
504 | MODULE_PARM_DESC(use_mic_as_bass, "(1/0) Use mic-in jack as bass/center"); | ||
505 | MODULE_PARM_DESC(mic_boost, "(1/0) Enable microphone boost"); | ||
506 | MODULE_PARM_DESC(hw_copy, "Copy front channel to surround channel"); | ||
507 | |||
508 | /* --------------------------------------------------------------------- */ | ||
509 | |||
510 | static inline unsigned ld2(unsigned int x) | ||
511 | { | ||
512 | unsigned exp=16,l=5,r=0; | ||
513 | static const unsigned num[]={0x2,0x4,0x10,0x100,0x10000}; | ||
514 | |||
515 | /* num: 2, 4, 16, 256, 65536 */ | ||
516 | /* exp: 1, 2, 4, 8, 16 */ | ||
517 | |||
518 | while(l--) { | ||
519 | if( x >= num[l] ) { | ||
520 | if(num[l]>2) x >>= exp; | ||
521 | r+=exp; | ||
522 | } | ||
523 | exp>>=1; | ||
524 | } | ||
525 | |||
526 | return r; | ||
527 | } | ||
528 | |||
529 | /* --------------------------------------------------------------------- */ | ||
530 | |||
531 | static void maskb(unsigned int addr, unsigned int mask, unsigned int value) | ||
532 | { | ||
533 | outb((inb(addr) & mask) | value, addr); | ||
534 | } | ||
535 | |||
536 | static void maskw(unsigned int addr, unsigned int mask, unsigned int value) | ||
537 | { | ||
538 | outw((inw(addr) & mask) | value, addr); | ||
539 | } | ||
540 | |||
541 | static void maskl(unsigned int addr, unsigned int mask, unsigned int value) | ||
542 | { | ||
543 | outl((inl(addr) & mask) | value, addr); | ||
544 | } | ||
545 | |||
546 | static void set_dmadac1(struct cm_state *s, unsigned int addr, unsigned int count) | ||
547 | { | ||
548 | if (addr) | ||
549 | outl(addr, s->iobase + CODEC_CMI_ADC_FRAME1); | ||
550 | outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2); | ||
551 | maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC0, 0); | ||
552 | } | ||
553 | |||
554 | static void set_dmaadc(struct cm_state *s, unsigned int addr, unsigned int count) | ||
555 | { | ||
556 | outl(addr, s->iobase + CODEC_CMI_ADC_FRAME1); | ||
557 | outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2); | ||
558 | maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, CHADC0); | ||
559 | } | ||
560 | |||
561 | static void set_dmadac(struct cm_state *s, unsigned int addr, unsigned int count) | ||
562 | { | ||
563 | outl(addr, s->iobase + CODEC_CMI_DAC_FRAME1); | ||
564 | outw(count - 1, s->iobase + CODEC_CMI_DAC_FRAME2); | ||
565 | maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC1, 0); | ||
566 | if (s->status & DO_DUAL_DAC) | ||
567 | set_dmadac1(s, 0, count); | ||
568 | } | ||
569 | |||
570 | static void set_countadc(struct cm_state *s, unsigned count) | ||
571 | { | ||
572 | outw(count - 1, s->iobase + CODEC_CMI_ADC_FRAME2 + 2); | ||
573 | } | ||
574 | |||
575 | static void set_countdac(struct cm_state *s, unsigned count) | ||
576 | { | ||
577 | outw(count - 1, s->iobase + CODEC_CMI_DAC_FRAME2 + 2); | ||
578 | if (s->status & DO_DUAL_DAC) | ||
579 | set_countadc(s, count); | ||
580 | } | ||
581 | |||
582 | static unsigned get_dmadac(struct cm_state *s) | ||
583 | { | ||
584 | unsigned int curr_addr; | ||
585 | |||
586 | curr_addr = inw(s->iobase + CODEC_CMI_DAC_FRAME2) + 1; | ||
587 | curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK]; | ||
588 | curr_addr = s->dma_dac.dmasize - curr_addr; | ||
589 | |||
590 | return curr_addr; | ||
591 | } | ||
592 | |||
593 | static unsigned get_dmaadc(struct cm_state *s) | ||
594 | { | ||
595 | unsigned int curr_addr; | ||
596 | |||
597 | curr_addr = inw(s->iobase + CODEC_CMI_ADC_FRAME2) + 1; | ||
598 | curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK]; | ||
599 | curr_addr = s->dma_adc.dmasize - curr_addr; | ||
600 | |||
601 | return curr_addr; | ||
602 | } | ||
603 | |||
604 | static void wrmixer(struct cm_state *s, unsigned char idx, unsigned char data) | ||
605 | { | ||
606 | unsigned char regval, pseudo; | ||
607 | |||
608 | // pseudo register | ||
609 | if (idx == DSP_MIX_AUXVOL_L) { | ||
610 | data >>= 4; | ||
611 | data &= 0x0f; | ||
612 | regval = inb(s->iobase + CODEC_CMI_AUX_VOL) & ~0x0f; | ||
613 | outb(regval | data, s->iobase + CODEC_CMI_AUX_VOL); | ||
614 | return; | ||
615 | } | ||
616 | if (idx == DSP_MIX_AUXVOL_R) { | ||
617 | data &= 0xf0; | ||
618 | regval = inb(s->iobase + CODEC_CMI_AUX_VOL) & ~0xf0; | ||
619 | outb(regval | data, s->iobase + CODEC_CMI_AUX_VOL); | ||
620 | return; | ||
621 | } | ||
622 | outb(idx, s->iobase + CODEC_SB16_ADDR); | ||
623 | udelay(10); | ||
624 | // pseudo bits | ||
625 | if (idx == DSP_MIX_OUTMIXIDX) { | ||
626 | pseudo = data & ~0x1f; | ||
627 | pseudo >>= 1; | ||
628 | regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x30; | ||
629 | outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2); | ||
630 | } | ||
631 | if (idx == DSP_MIX_ADCMIXIDX_L) { | ||
632 | pseudo = data & 0x80; | ||
633 | pseudo >>= 1; | ||
634 | regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x40; | ||
635 | outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2); | ||
636 | } | ||
637 | if (idx == DSP_MIX_ADCMIXIDX_R) { | ||
638 | pseudo = data & 0x80; | ||
639 | regval = inb(s->iobase + CODEC_CMI_MIXER2) & ~0x80; | ||
640 | outb(regval | pseudo, s->iobase + CODEC_CMI_MIXER2); | ||
641 | } | ||
642 | outb(data, s->iobase + CODEC_SB16_DATA); | ||
643 | udelay(10); | ||
644 | } | ||
645 | |||
646 | static unsigned char rdmixer(struct cm_state *s, unsigned char idx) | ||
647 | { | ||
648 | unsigned char v, pseudo; | ||
649 | |||
650 | // pseudo register | ||
651 | if (idx == DSP_MIX_AUXVOL_L) { | ||
652 | v = inb(s->iobase + CODEC_CMI_AUX_VOL) & 0x0f; | ||
653 | v <<= 4; | ||
654 | return v; | ||
655 | } | ||
656 | if (idx == DSP_MIX_AUXVOL_L) { | ||
657 | v = inb(s->iobase + CODEC_CMI_AUX_VOL) & 0xf0; | ||
658 | return v; | ||
659 | } | ||
660 | outb(idx, s->iobase + CODEC_SB16_ADDR); | ||
661 | udelay(10); | ||
662 | v = inb(s->iobase + CODEC_SB16_DATA); | ||
663 | udelay(10); | ||
664 | // pseudo bits | ||
665 | if (idx == DSP_MIX_OUTMIXIDX) { | ||
666 | pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x30; | ||
667 | pseudo <<= 1; | ||
668 | v |= pseudo; | ||
669 | } | ||
670 | if (idx == DSP_MIX_ADCMIXIDX_L) { | ||
671 | pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x40; | ||
672 | pseudo <<= 1; | ||
673 | v |= pseudo; | ||
674 | } | ||
675 | if (idx == DSP_MIX_ADCMIXIDX_R) { | ||
676 | pseudo = inb(s->iobase + CODEC_CMI_MIXER2) & 0x80; | ||
677 | v |= pseudo; | ||
678 | } | ||
679 | return v; | ||
680 | } | ||
681 | |||
682 | static void set_fmt_unlocked(struct cm_state *s, unsigned char mask, unsigned char data) | ||
683 | { | ||
684 | if (mask && s->chip_version > 0) { /* 8338 cannot keep this */ | ||
685 | s->fmt = inb(s->iobase + CODEC_CMI_CHFORMAT); | ||
686 | udelay(10); | ||
687 | } | ||
688 | s->fmt = (s->fmt & mask) | data; | ||
689 | outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT); | ||
690 | udelay(10); | ||
691 | } | ||
692 | |||
693 | static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data) | ||
694 | { | ||
695 | unsigned long flags; | ||
696 | |||
697 | spin_lock_irqsave(&s->lock, flags); | ||
698 | set_fmt_unlocked(s,mask,data); | ||
699 | spin_unlock_irqrestore(&s->lock, flags); | ||
700 | } | ||
701 | |||
702 | static void frobindir(struct cm_state *s, unsigned char idx, unsigned char mask, unsigned char data) | ||
703 | { | ||
704 | outb(idx, s->iobase + CODEC_SB16_ADDR); | ||
705 | udelay(10); | ||
706 | outb((inb(s->iobase + CODEC_SB16_DATA) & mask) | data, s->iobase + CODEC_SB16_DATA); | ||
707 | udelay(10); | ||
708 | } | ||
709 | |||
710 | static struct { | ||
711 | unsigned rate; | ||
712 | unsigned lower; | ||
713 | unsigned upper; | ||
714 | unsigned char freq; | ||
715 | } rate_lookup[] = | ||
716 | { | ||
717 | { 5512, (0 + 5512) / 2, (5512 + 8000) / 2, 0 }, | ||
718 | { 8000, (5512 + 8000) / 2, (8000 + 11025) / 2, 4 }, | ||
719 | { 11025, (8000 + 11025) / 2, (11025 + 16000) / 2, 1 }, | ||
720 | { 16000, (11025 + 16000) / 2, (16000 + 22050) / 2, 5 }, | ||
721 | { 22050, (16000 + 22050) / 2, (22050 + 32000) / 2, 2 }, | ||
722 | { 32000, (22050 + 32000) / 2, (32000 + 44100) / 2, 6 }, | ||
723 | { 44100, (32000 + 44100) / 2, (44100 + 48000) / 2, 3 }, | ||
724 | { 48000, (44100 + 48000) / 2, 48000, 7 } | ||
725 | }; | ||
726 | |||
727 | static void set_spdif_copyright(struct cm_state *s, int spdif_copyright) | ||
728 | { | ||
729 | /* enable SPDIF-in Copyright */ | ||
730 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~SPDCOPYRHT, spdif_copyright ? SPDCOPYRHT : 0); | ||
731 | } | ||
732 | |||
733 | static void set_spdif_loop(struct cm_state *s, int spdif_loop) | ||
734 | { | ||
735 | /* enable SPDIF loop */ | ||
736 | if (spdif_loop) { | ||
737 | s->status |= DO_SPDIF_LOOP; | ||
738 | /* turn on spdif-in to spdif-out */ | ||
739 | maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, SPDFLOOP); | ||
740 | } else { | ||
741 | s->status &= ~DO_SPDIF_LOOP; | ||
742 | /* turn off spdif-in to spdif-out */ | ||
743 | maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~SPDFLOOP, 0); | ||
744 | } | ||
745 | } | ||
746 | |||
747 | static void set_spdif_monitor(struct cm_state *s, int channel) | ||
748 | { | ||
749 | // SPDO2DAC | ||
750 | maskw(s->iobase + CODEC_CMI_FUNCTRL1, ~SPDO2DAC, channel == 2 ? SPDO2DAC : 0); | ||
751 | // CDPLAY | ||
752 | if (s->chip_version >= 39) | ||
753 | maskb(s->iobase + CODEC_CMI_MIXER1, ~CDPLAY, channel ? CDPLAY : 0); | ||
754 | } | ||
755 | |||
756 | static void set_spdifout_level(struct cm_state *s, int level5v) | ||
757 | { | ||
758 | /* SPDO5V */ | ||
759 | if (s->chip_version > 0) | ||
760 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~SPDO5V, level5v ? SPDO5V : 0); | ||
761 | } | ||
762 | |||
763 | static void set_spdifin_inverse(struct cm_state *s, int spdif_inverse) | ||
764 | { | ||
765 | if (s->chip_version == 0) /* 8338 has not this feature */ | ||
766 | return; | ||
767 | if (spdif_inverse) { | ||
768 | /* turn on spdif-in inverse */ | ||
769 | if (s->chip_version >= 39) | ||
770 | maskb(s->iobase + CODEC_CMI_CHFORMAT, ~0, INVSPDIFI); | ||
771 | else | ||
772 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 1); | ||
773 | } else { | ||
774 | /* turn off spdif-ininverse */ | ||
775 | if (s->chip_version >= 39) | ||
776 | maskb(s->iobase + CODEC_CMI_CHFORMAT, ~INVSPDIFI, 0); | ||
777 | else | ||
778 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~1, 0); | ||
779 | } | ||
780 | } | ||
781 | |||
782 | static void set_spdifin_channel2(struct cm_state *s, int channel2) | ||
783 | { | ||
784 | /* SELSPDIFI2 */ | ||
785 | if (s->chip_version >= 39) | ||
786 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 1, ~SELSPDIFI2, channel2 ? SELSPDIFI2 : 0); | ||
787 | } | ||
788 | |||
789 | static void set_spdifin_valid(struct cm_state *s, int valid) | ||
790 | { | ||
791 | /* SPDVALID */ | ||
792 | maskb(s->iobase + CODEC_CMI_MISC, ~SPDVALID, valid ? SPDVALID : 0); | ||
793 | } | ||
794 | |||
795 | static void set_spdifout_unlocked(struct cm_state *s, unsigned rate) | ||
796 | { | ||
797 | if (rate != 48000 && rate != 44100) | ||
798 | rate = 0; | ||
799 | if (rate == 48000 || rate == 44100) { | ||
800 | set_spdif_loop(s, 0); | ||
801 | // SPDF_1 | ||
802 | maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0, SPDF_1); | ||
803 | // SPDIFI48K SPDF_AC97 | ||
804 | maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~SPDIF48K, rate == 48000 ? SPDIF48K : 0); | ||
805 | if (s->chip_version >= 55) | ||
806 | // SPD32KFMT | ||
807 | maskb(s->iobase + CODEC_CMI_MISC_CTRL2, ~SPD32KFMT, rate == 48000 ? SPD32KFMT : 0); | ||
808 | if (s->chip_version > 0) | ||
809 | // ENSPDOUT | ||
810 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~0, ENSPDOUT); | ||
811 | // monitor SPDIF out | ||
812 | set_spdif_monitor(s, 2); | ||
813 | s->status |= DO_SPDIF_OUT; | ||
814 | } else { | ||
815 | maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~SPDF_1, 0); | ||
816 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 2, ~ENSPDOUT, 0); | ||
817 | // monitor none | ||
818 | set_spdif_monitor(s, 0); | ||
819 | s->status &= ~DO_SPDIF_OUT; | ||
820 | } | ||
821 | } | ||
822 | |||
823 | static void set_spdifout(struct cm_state *s, unsigned rate) | ||
824 | { | ||
825 | unsigned long flags; | ||
826 | |||
827 | spin_lock_irqsave(&s->lock, flags); | ||
828 | set_spdifout_unlocked(s,rate); | ||
829 | spin_unlock_irqrestore(&s->lock, flags); | ||
830 | } | ||
831 | |||
832 | static void set_spdifin_unlocked(struct cm_state *s, unsigned rate) | ||
833 | { | ||
834 | if (rate == 48000 || rate == 44100) { | ||
835 | // SPDF_1 | ||
836 | maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~0, SPDF_1); | ||
837 | // SPDIFI48K SPDF_AC97 | ||
838 | maskl(s->iobase + CODEC_CMI_MISC_CTRL, ~SPDIF48K, rate == 48000 ? SPDIF48K : 0); | ||
839 | s->status |= DO_SPDIF_IN; | ||
840 | } else { | ||
841 | maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~SPDF_1, 0); | ||
842 | s->status &= ~DO_SPDIF_IN; | ||
843 | } | ||
844 | } | ||
845 | |||
846 | static void set_spdifin(struct cm_state *s, unsigned rate) | ||
847 | { | ||
848 | unsigned long flags; | ||
849 | |||
850 | spin_lock_irqsave(&s->lock, flags); | ||
851 | set_spdifin_unlocked(s,rate); | ||
852 | spin_unlock_irqrestore(&s->lock, flags); | ||
853 | } | ||
854 | |||
855 | /* find parity for bit 4~30 */ | ||
856 | static unsigned parity(unsigned data) | ||
857 | { | ||
858 | unsigned parity = 0; | ||
859 | int counter = 4; | ||
860 | |||
861 | data >>= 4; // start from bit 4 | ||
862 | while (counter <= 30) { | ||
863 | if (data & 1) | ||
864 | parity++; | ||
865 | data >>= 1; | ||
866 | counter++; | ||
867 | } | ||
868 | return parity & 1; | ||
869 | } | ||
870 | |||
871 | static void set_ac3_unlocked(struct cm_state *s, unsigned rate) | ||
872 | { | ||
873 | if (!(s->capability & CAN_AC3)) | ||
874 | return; | ||
875 | /* enable AC3 */ | ||
876 | if (rate && rate != 44100) | ||
877 | rate = 48000; | ||
878 | if (rate == 48000 || rate == 44100) { | ||
879 | // mute DAC | ||
880 | maskb(s->iobase + CODEC_CMI_MIXER1, ~0, WSMUTE); | ||
881 | if (s->chip_version >= 39) | ||
882 | maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~0, MUTECH1); | ||
883 | // AC3EN for 039, 0x04 | ||
884 | if (s->chip_version >= 39) { | ||
885 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, AC3_EN); | ||
886 | if (s->chip_version == 55) | ||
887 | maskb(s->iobase + CODEC_CMI_SPDIF_CTRL, ~2, 0); | ||
888 | // AC3EN for 037, 0x10 | ||
889 | } else if (s->chip_version == 37) | ||
890 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x10); | ||
891 | if (s->capability & CAN_AC3_HW) { | ||
892 | // SPD24SEL for 039, 0x20, but cannot be set | ||
893 | if (s->chip_version == 39) | ||
894 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, SPD24SEL); | ||
895 | // SPD24SEL for 037, 0x02 | ||
896 | else if (s->chip_version == 37) | ||
897 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 0x02); | ||
898 | if (s->chip_version >= 39) | ||
899 | maskb(s->iobase + CODEC_CMI_MIXER1, ~CDPLAY, 0); | ||
900 | |||
901 | s->status |= DO_AC3_HW; | ||
902 | } else { | ||
903 | // SPD32SEL for 037 & 039 | ||
904 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, SPD32SEL); | ||
905 | // set 176K sample rate to fix 033 HW bug | ||
906 | if (s->chip_version == 33) { | ||
907 | if (rate == 48000) | ||
908 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0, 0x08); | ||
909 | else | ||
910 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0); | ||
911 | } | ||
912 | s->status |= DO_AC3_SW; | ||
913 | } | ||
914 | } else { | ||
915 | maskb(s->iobase + CODEC_CMI_MIXER1, ~WSMUTE, 0); | ||
916 | if (s->chip_version >= 39) | ||
917 | maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~MUTECH1, 0); | ||
918 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~(SPD24SEL|0x12), 0); | ||
919 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~(SPD32SEL|AC3_EN), 0); | ||
920 | if (s->chip_version == 33) | ||
921 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 1, ~0x08, 0); | ||
922 | if (s->chip_version >= 39) | ||
923 | maskb(s->iobase + CODEC_CMI_MIXER1, ~0, CDPLAY); | ||
924 | s->status &= ~DO_AC3; | ||
925 | } | ||
926 | s->spdif_counter = 0; | ||
927 | } | ||
928 | |||
929 | static void set_line_as_rear(struct cm_state *s, int use_line_as_rear) | ||
930 | { | ||
931 | if (!(s->capability & CAN_LINE_AS_REAR)) | ||
932 | return; | ||
933 | if (use_line_as_rear) { | ||
934 | maskb(s->iobase + CODEC_CMI_MIXER1, ~0, SPK4); | ||
935 | s->status |= DO_LINE_AS_REAR; | ||
936 | } else { | ||
937 | maskb(s->iobase + CODEC_CMI_MIXER1, ~SPK4, 0); | ||
938 | s->status &= ~DO_LINE_AS_REAR; | ||
939 | } | ||
940 | } | ||
941 | |||
942 | static void set_line_as_bass(struct cm_state *s, int use_line_as_bass) | ||
943 | { | ||
944 | if (!(s->capability & CAN_LINE_AS_BASS)) | ||
945 | return; | ||
946 | if (use_line_as_bass) { | ||
947 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~0, CB2LIN); | ||
948 | s->status |= DO_LINE_AS_BASS; | ||
949 | } else { | ||
950 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CB2LIN, 0); | ||
951 | s->status &= ~DO_LINE_AS_BASS; | ||
952 | } | ||
953 | } | ||
954 | |||
955 | static void set_mic_as_bass(struct cm_state *s, int use_mic_as_bass) | ||
956 | { | ||
957 | if (!(s->capability & CAN_MIC_AS_BASS)) | ||
958 | return; | ||
959 | if (use_mic_as_bass) { | ||
960 | maskb(s->iobase + CODEC_CMI_MISC, ~0, 0x04); | ||
961 | s->status |= DO_MIC_AS_BASS; | ||
962 | } else { | ||
963 | maskb(s->iobase + CODEC_CMI_MISC, ~0x04, 0); | ||
964 | s->status &= ~DO_MIC_AS_BASS; | ||
965 | } | ||
966 | } | ||
967 | |||
968 | static void set_hw_copy(struct cm_state *s, int hw_copy) | ||
969 | { | ||
970 | if (s->max_channels > 2 && hw_copy) | ||
971 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0, N4SPK3D); | ||
972 | else | ||
973 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~N4SPK3D, 0); | ||
974 | } | ||
975 | |||
976 | static void set_ac3(struct cm_state *s, unsigned rate) | ||
977 | { | ||
978 | unsigned long flags; | ||
979 | |||
980 | spin_lock_irqsave(&s->lock, flags); | ||
981 | set_spdifout_unlocked(s, rate); | ||
982 | set_ac3_unlocked(s, rate); | ||
983 | spin_unlock_irqrestore(&s->lock, flags); | ||
984 | } | ||
985 | |||
986 | static int trans_ac3(struct cm_state *s, void *dest, const char __user *source, int size) | ||
987 | { | ||
988 | int i = size / 2; | ||
989 | unsigned long data; | ||
990 | unsigned short data16; | ||
991 | unsigned long *dst = (unsigned long *) dest; | ||
992 | unsigned short __user *src = (unsigned short __user *)source; | ||
993 | int err; | ||
994 | |||
995 | do { | ||
996 | if ((err = __get_user(data16, src++))) | ||
997 | return err; | ||
998 | data = (unsigned long)le16_to_cpu(data16); | ||
999 | data <<= 12; // ok for 16-bit data | ||
1000 | if (s->spdif_counter == 2 || s->spdif_counter == 3) | ||
1001 | data |= 0x40000000; // indicate AC-3 raw data | ||
1002 | if (parity(data)) | ||
1003 | data |= 0x80000000; // parity | ||
1004 | if (s->spdif_counter == 0) | ||
1005 | data |= 3; // preamble 'M' | ||
1006 | else if (s->spdif_counter & 1) | ||
1007 | data |= 5; // odd, 'W' | ||
1008 | else | ||
1009 | data |= 9; // even, 'M' | ||
1010 | *dst++ = cpu_to_le32(data); | ||
1011 | s->spdif_counter++; | ||
1012 | if (s->spdif_counter == 384) | ||
1013 | s->spdif_counter = 0; | ||
1014 | } while (--i); | ||
1015 | |||
1016 | return 0; | ||
1017 | } | ||
1018 | |||
1019 | static void set_adc_rate_unlocked(struct cm_state *s, unsigned rate) | ||
1020 | { | ||
1021 | unsigned char freq = 4; | ||
1022 | int i; | ||
1023 | |||
1024 | if (rate > 48000) | ||
1025 | rate = 48000; | ||
1026 | if (rate < 8000) | ||
1027 | rate = 8000; | ||
1028 | for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) { | ||
1029 | if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) { | ||
1030 | rate = rate_lookup[i].rate; | ||
1031 | freq = rate_lookup[i].freq; | ||
1032 | break; | ||
1033 | } | ||
1034 | } | ||
1035 | s->rateadc = rate; | ||
1036 | freq <<= CM_FREQ_ADCSHIFT; | ||
1037 | |||
1038 | maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~ASFC, freq); | ||
1039 | } | ||
1040 | |||
1041 | static void set_adc_rate(struct cm_state *s, unsigned rate) | ||
1042 | { | ||
1043 | unsigned long flags; | ||
1044 | unsigned char freq = 4; | ||
1045 | int i; | ||
1046 | |||
1047 | if (rate > 48000) | ||
1048 | rate = 48000; | ||
1049 | if (rate < 8000) | ||
1050 | rate = 8000; | ||
1051 | for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) { | ||
1052 | if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) { | ||
1053 | rate = rate_lookup[i].rate; | ||
1054 | freq = rate_lookup[i].freq; | ||
1055 | break; | ||
1056 | } | ||
1057 | } | ||
1058 | s->rateadc = rate; | ||
1059 | freq <<= CM_FREQ_ADCSHIFT; | ||
1060 | |||
1061 | spin_lock_irqsave(&s->lock, flags); | ||
1062 | maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~ASFC, freq); | ||
1063 | spin_unlock_irqrestore(&s->lock, flags); | ||
1064 | } | ||
1065 | |||
1066 | static void set_dac_rate(struct cm_state *s, unsigned rate) | ||
1067 | { | ||
1068 | unsigned long flags; | ||
1069 | unsigned char freq = 4; | ||
1070 | int i; | ||
1071 | |||
1072 | if (rate > 48000) | ||
1073 | rate = 48000; | ||
1074 | if (rate < 8000) | ||
1075 | rate = 8000; | ||
1076 | for (i = 0; i < sizeof(rate_lookup) / sizeof(rate_lookup[0]); i++) { | ||
1077 | if (rate > rate_lookup[i].lower && rate <= rate_lookup[i].upper) { | ||
1078 | rate = rate_lookup[i].rate; | ||
1079 | freq = rate_lookup[i].freq; | ||
1080 | break; | ||
1081 | } | ||
1082 | } | ||
1083 | s->ratedac = rate; | ||
1084 | freq <<= CM_FREQ_DACSHIFT; | ||
1085 | |||
1086 | spin_lock_irqsave(&s->lock, flags); | ||
1087 | maskb(s->iobase + CODEC_CMI_FUNCTRL1 + 1, ~DSFC, freq); | ||
1088 | spin_unlock_irqrestore(&s->lock, flags); | ||
1089 | |||
1090 | if (s->curr_channels <= 2 && spdif_out) | ||
1091 | set_spdifout(s, rate); | ||
1092 | if (s->status & DO_DUAL_DAC) | ||
1093 | set_dac1_rate(s, rate); | ||
1094 | } | ||
1095 | |||
1096 | /* --------------------------------------------------------------------- */ | ||
1097 | static inline void reset_adc(struct cm_state *s) | ||
1098 | { | ||
1099 | /* reset bus master */ | ||
1100 | outb(s->enable | RSTADC, s->iobase + CODEC_CMI_FUNCTRL0 + 2); | ||
1101 | udelay(10); | ||
1102 | outb(s->enable & ~RSTADC, s->iobase + CODEC_CMI_FUNCTRL0 + 2); | ||
1103 | } | ||
1104 | |||
1105 | static inline void reset_dac(struct cm_state *s) | ||
1106 | { | ||
1107 | /* reset bus master */ | ||
1108 | outb(s->enable | RSTDAC, s->iobase + CODEC_CMI_FUNCTRL0 + 2); | ||
1109 | udelay(10); | ||
1110 | outb(s->enable & ~RSTDAC, s->iobase + CODEC_CMI_FUNCTRL0 + 2); | ||
1111 | if (s->status & DO_DUAL_DAC) | ||
1112 | reset_adc(s); | ||
1113 | } | ||
1114 | |||
1115 | static inline void pause_adc(struct cm_state *s) | ||
1116 | { | ||
1117 | maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, PAUSEADC); | ||
1118 | } | ||
1119 | |||
1120 | static inline void pause_dac(struct cm_state *s) | ||
1121 | { | ||
1122 | maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~0, PAUSEDAC); | ||
1123 | if (s->status & DO_DUAL_DAC) | ||
1124 | pause_adc(s); | ||
1125 | } | ||
1126 | |||
1127 | static inline void disable_adc(struct cm_state *s) | ||
1128 | { | ||
1129 | /* disable channel */ | ||
1130 | s->enable &= ~ENADC; | ||
1131 | outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2); | ||
1132 | reset_adc(s); | ||
1133 | } | ||
1134 | |||
1135 | static inline void disable_dac(struct cm_state *s) | ||
1136 | { | ||
1137 | /* disable channel */ | ||
1138 | s->enable &= ~ENDAC; | ||
1139 | outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2); | ||
1140 | reset_dac(s); | ||
1141 | if (s->status & DO_DUAL_DAC) | ||
1142 | disable_adc(s); | ||
1143 | } | ||
1144 | |||
1145 | static inline void enable_adc(struct cm_state *s) | ||
1146 | { | ||
1147 | if (!(s->enable & ENADC)) { | ||
1148 | /* enable channel */ | ||
1149 | s->enable |= ENADC; | ||
1150 | outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2); | ||
1151 | } | ||
1152 | maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~PAUSEADC, 0); | ||
1153 | } | ||
1154 | |||
1155 | static inline void enable_dac_unlocked(struct cm_state *s) | ||
1156 | { | ||
1157 | if (!(s->enable & ENDAC)) { | ||
1158 | /* enable channel */ | ||
1159 | s->enable |= ENDAC; | ||
1160 | outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2); | ||
1161 | } | ||
1162 | maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~PAUSEDAC, 0); | ||
1163 | |||
1164 | if (s->status & DO_DUAL_DAC) | ||
1165 | enable_adc(s); | ||
1166 | } | ||
1167 | |||
1168 | static inline void stop_adc_unlocked(struct cm_state *s) | ||
1169 | { | ||
1170 | if (s->enable & ENADC) { | ||
1171 | /* disable interrupt */ | ||
1172 | maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~ENADCINT, 0); | ||
1173 | disable_adc(s); | ||
1174 | } | ||
1175 | } | ||
1176 | |||
1177 | static inline void stop_adc(struct cm_state *s) | ||
1178 | { | ||
1179 | unsigned long flags; | ||
1180 | |||
1181 | spin_lock_irqsave(&s->lock, flags); | ||
1182 | stop_adc_unlocked(s); | ||
1183 | spin_unlock_irqrestore(&s->lock, flags); | ||
1184 | |||
1185 | } | ||
1186 | |||
1187 | static inline void stop_dac_unlocked(struct cm_state *s) | ||
1188 | { | ||
1189 | if (s->enable & ENDAC) { | ||
1190 | /* disable interrupt */ | ||
1191 | maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~ENDACINT, 0); | ||
1192 | disable_dac(s); | ||
1193 | } | ||
1194 | if (s->status & DO_DUAL_DAC) | ||
1195 | stop_dac1_unlocked(s); | ||
1196 | } | ||
1197 | |||
1198 | static inline void stop_dac(struct cm_state *s) | ||
1199 | { | ||
1200 | unsigned long flags; | ||
1201 | |||
1202 | spin_lock_irqsave(&s->lock, flags); | ||
1203 | stop_dac_unlocked(s); | ||
1204 | spin_unlock_irqrestore(&s->lock, flags); | ||
1205 | } | ||
1206 | |||
1207 | static inline void start_adc_unlocked(struct cm_state *s) | ||
1208 | { | ||
1209 | if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) | ||
1210 | && s->dma_adc.ready) { | ||
1211 | /* enable interrupt */ | ||
1212 | maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENADCINT); | ||
1213 | enable_adc(s); | ||
1214 | } | ||
1215 | } | ||
1216 | |||
1217 | static void start_adc(struct cm_state *s) | ||
1218 | { | ||
1219 | unsigned long flags; | ||
1220 | |||
1221 | spin_lock_irqsave(&s->lock, flags); | ||
1222 | start_adc_unlocked(s); | ||
1223 | spin_unlock_irqrestore(&s->lock, flags); | ||
1224 | } | ||
1225 | |||
1226 | static void start_dac1_unlocked(struct cm_state *s) | ||
1227 | { | ||
1228 | if ((s->dma_adc.mapped || s->dma_adc.count > 0) && s->dma_adc.ready) { | ||
1229 | /* enable interrupt */ | ||
1230 | maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENADCINT); | ||
1231 | enable_dac_unlocked(s); | ||
1232 | } | ||
1233 | } | ||
1234 | |||
1235 | static void start_dac_unlocked(struct cm_state *s) | ||
1236 | { | ||
1237 | if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) { | ||
1238 | /* enable interrupt */ | ||
1239 | maskb(s->iobase + CODEC_CMI_INT_HLDCLR + 2, ~0, ENDACINT); | ||
1240 | enable_dac_unlocked(s); | ||
1241 | } | ||
1242 | if (s->status & DO_DUAL_DAC) | ||
1243 | start_dac1_unlocked(s); | ||
1244 | } | ||
1245 | |||
1246 | static void start_dac(struct cm_state *s) | ||
1247 | { | ||
1248 | unsigned long flags; | ||
1249 | |||
1250 | spin_lock_irqsave(&s->lock, flags); | ||
1251 | start_dac_unlocked(s); | ||
1252 | spin_unlock_irqrestore(&s->lock, flags); | ||
1253 | } | ||
1254 | |||
1255 | static int prog_dmabuf(struct cm_state *s, unsigned rec); | ||
1256 | |||
1257 | static int set_dac_channels(struct cm_state *s, int channels) | ||
1258 | { | ||
1259 | unsigned long flags; | ||
1260 | static unsigned int fmmute = 0; | ||
1261 | |||
1262 | spin_lock_irqsave(&s->lock, flags); | ||
1263 | |||
1264 | if ((channels > 2) && (channels <= s->max_channels) | ||
1265 | && (((s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK) == (CM_CFMT_STEREO | CM_CFMT_16BIT))) { | ||
1266 | set_spdifout_unlocked(s, 0); | ||
1267 | if (s->capability & CAN_MULTI_CH_HW) { | ||
1268 | // NXCHG | ||
1269 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0, NXCHG); | ||
1270 | // CHB3D or CHB3D5C | ||
1271 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~(CHB3D5C|CHB3D), channels > 4 ? CHB3D5C : CHB3D); | ||
1272 | // CHB3D6C | ||
1273 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CHB3D6C, channels == 6 ? CHB3D6C : 0); | ||
1274 | // ENCENTER | ||
1275 | maskb(s->iobase + CODEC_CMI_MISC_CTRL, ~ENCENTER, channels == 6 ? ENCENTER : 0); | ||
1276 | s->status |= DO_MULTI_CH_HW; | ||
1277 | } else if (s->capability & CAN_DUAL_DAC) { | ||
1278 | unsigned char fmtm = ~0, fmts = 0; | ||
1279 | ssize_t ret; | ||
1280 | |||
1281 | // ENDBDAC, turn on double DAC mode | ||
1282 | // XCHGDAC, CH0 -> back, CH1->front | ||
1283 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, ENDBDAC|XCHGDAC); | ||
1284 | // mute FM | ||
1285 | fmmute = inb(s->iobase + CODEC_CMI_MIXER1) & FMMUTE; | ||
1286 | maskb(s->iobase + CODEC_CMI_MIXER1, ~0, FMMUTE); | ||
1287 | s->status |= DO_DUAL_DAC; | ||
1288 | // prepare secondary buffer | ||
1289 | spin_unlock_irqrestore(&s->lock, flags); | ||
1290 | ret = prog_dmabuf(s, 1); | ||
1291 | if (ret) return ret; | ||
1292 | spin_lock_irqsave(&s->lock, flags); | ||
1293 | |||
1294 | // copy the hw state | ||
1295 | fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT); | ||
1296 | fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT); | ||
1297 | // the HW only support 16-bit stereo | ||
1298 | fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT; | ||
1299 | fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT; | ||
1300 | fmts |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT; | ||
1301 | fmts |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT; | ||
1302 | |||
1303 | set_fmt_unlocked(s, fmtm, fmts); | ||
1304 | set_adc_rate_unlocked(s, s->ratedac); | ||
1305 | } | ||
1306 | // disable 4 speaker mode (analog duplicate) | ||
1307 | set_hw_copy(s, 0); | ||
1308 | s->curr_channels = channels; | ||
1309 | |||
1310 | // enable jack redirect | ||
1311 | set_line_as_rear(s, use_line_as_rear); | ||
1312 | if (channels > 4) { | ||
1313 | set_line_as_bass(s, use_line_as_bass); | ||
1314 | set_mic_as_bass(s, use_mic_as_bass); | ||
1315 | } | ||
1316 | } else { | ||
1317 | if (s->status & DO_MULTI_CH_HW) { | ||
1318 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~NXCHG, 0); | ||
1319 | maskb(s->iobase + CODEC_CMI_CHFORMAT + 3, ~(CHB3D5C|CHB3D), 0); | ||
1320 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 1, ~CHB3D6C, 0); | ||
1321 | } else if (s->status & DO_DUAL_DAC) { | ||
1322 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~ENDBDAC, 0); | ||
1323 | maskb(s->iobase + CODEC_CMI_MIXER1, ~FMMUTE, fmmute); | ||
1324 | } | ||
1325 | // enable 4 speaker mode (analog duplicate) | ||
1326 | set_hw_copy(s, hw_copy); | ||
1327 | s->status &= ~DO_MULTI_CH; | ||
1328 | s->curr_channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1; | ||
1329 | // disable jack redirect | ||
1330 | set_line_as_rear(s, hw_copy ? use_line_as_rear : 0); | ||
1331 | set_line_as_bass(s, 0); | ||
1332 | set_mic_as_bass(s, 0); | ||
1333 | } | ||
1334 | spin_unlock_irqrestore(&s->lock, flags); | ||
1335 | return s->curr_channels; | ||
1336 | } | ||
1337 | |||
1338 | /* --------------------------------------------------------------------- */ | ||
1339 | |||
1340 | #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT) | ||
1341 | #define DMABUF_MINORDER 1 | ||
1342 | |||
1343 | static void dealloc_dmabuf(struct cm_state *s, struct dmabuf *db) | ||
1344 | { | ||
1345 | struct page *pstart, *pend; | ||
1346 | |||
1347 | if (db->rawbuf) { | ||
1348 | /* undo marking the pages as reserved */ | ||
1349 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
1350 | for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++) | ||
1351 | ClearPageReserved(pstart); | ||
1352 | pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr); | ||
1353 | } | ||
1354 | db->rawbuf = NULL; | ||
1355 | db->mapped = db->ready = 0; | ||
1356 | } | ||
1357 | |||
1358 | /* Ch1 is used for playback, Ch0 is used for recording */ | ||
1359 | |||
1360 | static int prog_dmabuf(struct cm_state *s, unsigned rec) | ||
1361 | { | ||
1362 | struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac; | ||
1363 | unsigned rate = rec ? s->rateadc : s->ratedac; | ||
1364 | int order; | ||
1365 | unsigned bytepersec; | ||
1366 | unsigned bufs; | ||
1367 | struct page *pstart, *pend; | ||
1368 | unsigned char fmt; | ||
1369 | unsigned long flags; | ||
1370 | |||
1371 | fmt = s->fmt; | ||
1372 | if (rec) { | ||
1373 | stop_adc(s); | ||
1374 | fmt >>= CM_CFMT_ADCSHIFT; | ||
1375 | } else { | ||
1376 | stop_dac(s); | ||
1377 | fmt >>= CM_CFMT_DACSHIFT; | ||
1378 | } | ||
1379 | |||
1380 | fmt &= CM_CFMT_MASK; | ||
1381 | db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; | ||
1382 | if (!db->rawbuf) { | ||
1383 | db->ready = db->mapped = 0; | ||
1384 | for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) | ||
1385 | if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr))) | ||
1386 | break; | ||
1387 | if (!db->rawbuf || !db->dmaaddr) | ||
1388 | return -ENOMEM; | ||
1389 | db->buforder = order; | ||
1390 | /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ | ||
1391 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
1392 | for (pstart = virt_to_page(db->rawbuf); pstart <= pend; pstart++) | ||
1393 | SetPageReserved(pstart); | ||
1394 | } | ||
1395 | bytepersec = rate << sample_shift[fmt]; | ||
1396 | bufs = PAGE_SIZE << db->buforder; | ||
1397 | if (db->ossfragshift) { | ||
1398 | if ((1000 << db->ossfragshift) < bytepersec) | ||
1399 | db->fragshift = ld2(bytepersec/1000); | ||
1400 | else | ||
1401 | db->fragshift = db->ossfragshift; | ||
1402 | } else { | ||
1403 | db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); | ||
1404 | if (db->fragshift < 3) | ||
1405 | db->fragshift = 3; | ||
1406 | } | ||
1407 | db->numfrag = bufs >> db->fragshift; | ||
1408 | while (db->numfrag < 4 && db->fragshift > 3) { | ||
1409 | db->fragshift--; | ||
1410 | db->numfrag = bufs >> db->fragshift; | ||
1411 | } | ||
1412 | db->fragsize = 1 << db->fragshift; | ||
1413 | if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) | ||
1414 | db->numfrag = db->ossmaxfrags; | ||
1415 | /* to make fragsize >= 4096 */ | ||
1416 | db->fragsamples = db->fragsize >> sample_shift[fmt]; | ||
1417 | db->dmasize = db->numfrag << db->fragshift; | ||
1418 | db->dmasamples = db->dmasize >> sample_shift[fmt]; | ||
1419 | memset(db->rawbuf, (fmt & CM_CFMT_16BIT) ? 0 : 0x80, db->dmasize); | ||
1420 | spin_lock_irqsave(&s->lock, flags); | ||
1421 | if (rec) { | ||
1422 | if (s->status & DO_DUAL_DAC) | ||
1423 | set_dmadac1(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]); | ||
1424 | else | ||
1425 | set_dmaadc(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]); | ||
1426 | /* program sample counts */ | ||
1427 | set_countdac(s, db->fragsamples); | ||
1428 | } else { | ||
1429 | set_dmadac(s, db->dmaaddr, db->dmasize >> sample_shift[fmt]); | ||
1430 | /* program sample counts */ | ||
1431 | set_countdac(s, db->fragsamples); | ||
1432 | } | ||
1433 | spin_unlock_irqrestore(&s->lock, flags); | ||
1434 | db->enabled = 1; | ||
1435 | db->ready = 1; | ||
1436 | return 0; | ||
1437 | } | ||
1438 | |||
1439 | static inline void clear_advance(struct cm_state *s) | ||
1440 | { | ||
1441 | unsigned char c = (s->fmt & (CM_CFMT_16BIT << CM_CFMT_DACSHIFT)) ? 0 : 0x80; | ||
1442 | unsigned char *buf = s->dma_dac.rawbuf; | ||
1443 | unsigned char *buf1 = s->dma_adc.rawbuf; | ||
1444 | unsigned bsize = s->dma_dac.dmasize; | ||
1445 | unsigned bptr = s->dma_dac.swptr; | ||
1446 | unsigned len = s->dma_dac.fragsize; | ||
1447 | |||
1448 | if (bptr + len > bsize) { | ||
1449 | unsigned x = bsize - bptr; | ||
1450 | memset(buf + bptr, c, x); | ||
1451 | if (s->status & DO_DUAL_DAC) | ||
1452 | memset(buf1 + bptr, c, x); | ||
1453 | bptr = 0; | ||
1454 | len -= x; | ||
1455 | } | ||
1456 | memset(buf + bptr, c, len); | ||
1457 | if (s->status & DO_DUAL_DAC) | ||
1458 | memset(buf1 + bptr, c, len); | ||
1459 | } | ||
1460 | |||
1461 | /* call with spinlock held! */ | ||
1462 | static void cm_update_ptr(struct cm_state *s) | ||
1463 | { | ||
1464 | unsigned hwptr; | ||
1465 | int diff; | ||
1466 | |||
1467 | /* update ADC pointer */ | ||
1468 | if (s->dma_adc.ready) { | ||
1469 | if (s->status & DO_DUAL_DAC) { | ||
1470 | /* the dac part will finish for this */ | ||
1471 | } else { | ||
1472 | hwptr = get_dmaadc(s) % s->dma_adc.dmasize; | ||
1473 | diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; | ||
1474 | s->dma_adc.hwptr = hwptr; | ||
1475 | s->dma_adc.total_bytes += diff; | ||
1476 | s->dma_adc.count += diff; | ||
1477 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
1478 | wake_up(&s->dma_adc.wait); | ||
1479 | if (!s->dma_adc.mapped) { | ||
1480 | if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { | ||
1481 | pause_adc(s); | ||
1482 | s->dma_adc.error++; | ||
1483 | } | ||
1484 | } | ||
1485 | } | ||
1486 | } | ||
1487 | /* update DAC pointer */ | ||
1488 | if (s->dma_dac.ready) { | ||
1489 | hwptr = get_dmadac(s) % s->dma_dac.dmasize; | ||
1490 | diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize; | ||
1491 | s->dma_dac.hwptr = hwptr; | ||
1492 | s->dma_dac.total_bytes += diff; | ||
1493 | if (s->status & DO_DUAL_DAC) { | ||
1494 | s->dma_adc.hwptr = hwptr; | ||
1495 | s->dma_adc.total_bytes += diff; | ||
1496 | } | ||
1497 | if (s->dma_dac.mapped) { | ||
1498 | s->dma_dac.count += diff; | ||
1499 | if (s->status & DO_DUAL_DAC) | ||
1500 | s->dma_adc.count += diff; | ||
1501 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) | ||
1502 | wake_up(&s->dma_dac.wait); | ||
1503 | } else { | ||
1504 | s->dma_dac.count -= diff; | ||
1505 | if (s->status & DO_DUAL_DAC) | ||
1506 | s->dma_adc.count -= diff; | ||
1507 | if (s->dma_dac.count <= 0) { | ||
1508 | pause_dac(s); | ||
1509 | s->dma_dac.error++; | ||
1510 | } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) { | ||
1511 | clear_advance(s); | ||
1512 | s->dma_dac.endcleared = 1; | ||
1513 | if (s->status & DO_DUAL_DAC) | ||
1514 | s->dma_adc.endcleared = 1; | ||
1515 | } | ||
1516 | if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) | ||
1517 | wake_up(&s->dma_dac.wait); | ||
1518 | } | ||
1519 | } | ||
1520 | } | ||
1521 | |||
1522 | static irqreturn_t cm_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1523 | { | ||
1524 | struct cm_state *s = (struct cm_state *)dev_id; | ||
1525 | unsigned int intsrc, intstat; | ||
1526 | unsigned char mask = 0; | ||
1527 | |||
1528 | /* fastpath out, to ease interrupt sharing */ | ||
1529 | intsrc = inl(s->iobase + CODEC_CMI_INT_STATUS); | ||
1530 | if (!(intsrc & 0x80000000)) | ||
1531 | return IRQ_NONE; | ||
1532 | spin_lock(&s->lock); | ||
1533 | intstat = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2); | ||
1534 | /* acknowledge interrupt */ | ||
1535 | if (intsrc & ADCINT) | ||
1536 | mask |= ENADCINT; | ||
1537 | if (intsrc & DACINT) | ||
1538 | mask |= ENDACINT; | ||
1539 | outb(intstat & ~mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2); | ||
1540 | outb(intstat | mask, s->iobase + CODEC_CMI_INT_HLDCLR + 2); | ||
1541 | cm_update_ptr(s); | ||
1542 | spin_unlock(&s->lock); | ||
1543 | #ifdef CONFIG_SOUND_CMPCI_MIDI | ||
1544 | if (intsrc & 0x00010000) { // UART interrupt | ||
1545 | if (s->midi_devc && intchk_mpu401((void *)s->midi_devc)) | ||
1546 | mpuintr(irq, (void *)s->midi_devc, regs); | ||
1547 | else | ||
1548 | inb(s->iomidi);// dummy read | ||
1549 | } | ||
1550 | #endif | ||
1551 | return IRQ_HANDLED; | ||
1552 | } | ||
1553 | |||
1554 | /* --------------------------------------------------------------------- */ | ||
1555 | |||
1556 | static const char invalid_magic[] = KERN_CRIT "cmpci: invalid magic value\n"; | ||
1557 | |||
1558 | #define VALIDATE_STATE(s) \ | ||
1559 | ({ \ | ||
1560 | if (!(s) || (s)->magic != CM_MAGIC) { \ | ||
1561 | printk(invalid_magic); \ | ||
1562 | return -ENXIO; \ | ||
1563 | } \ | ||
1564 | }) | ||
1565 | |||
1566 | /* --------------------------------------------------------------------- */ | ||
1567 | |||
1568 | #define MT_4 1 | ||
1569 | #define MT_5MUTE 2 | ||
1570 | #define MT_4MUTEMONO 3 | ||
1571 | #define MT_6MUTE 4 | ||
1572 | #define MT_5MUTEMONO 5 | ||
1573 | |||
1574 | static const struct { | ||
1575 | unsigned left; | ||
1576 | unsigned right; | ||
1577 | unsigned type; | ||
1578 | unsigned rec; | ||
1579 | unsigned play; | ||
1580 | } mixtable[SOUND_MIXER_NRDEVICES] = { | ||
1581 | [SOUND_MIXER_CD] = { DSP_MIX_CDVOLIDX_L, DSP_MIX_CDVOLIDX_R, MT_5MUTE, 0x04, 0x06 }, | ||
1582 | [SOUND_MIXER_LINE] = { DSP_MIX_LINEVOLIDX_L, DSP_MIX_LINEVOLIDX_R, MT_5MUTE, 0x10, 0x18 }, | ||
1583 | [SOUND_MIXER_MIC] = { DSP_MIX_MICVOLIDX, DSP_MIX_MICVOLIDX, MT_5MUTEMONO, 0x01, 0x01 }, | ||
1584 | [SOUND_MIXER_SYNTH] = { DSP_MIX_FMVOLIDX_L, DSP_MIX_FMVOLIDX_R, MT_5MUTE, 0x40, 0x00 }, | ||
1585 | [SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5MUTE, 0x00, 0x00 }, | ||
1586 | [SOUND_MIXER_PCM] = { DSP_MIX_VOICEVOLIDX_L, DSP_MIX_VOICEVOLIDX_R, MT_5MUTE, 0x00, 0x00 }, | ||
1587 | [SOUND_MIXER_LINE1] = { DSP_MIX_AUXVOL_L, DSP_MIX_AUXVOL_R, MT_5MUTE, 0x80, 0x60 }, | ||
1588 | [SOUND_MIXER_SPEAKER]= { DSP_MIX_SPKRVOLIDX, DSP_MIX_SPKRVOLIDX, MT_5MUTEMONO, 0x00, 0x01 } | ||
1589 | }; | ||
1590 | |||
1591 | static const unsigned char volidx[SOUND_MIXER_NRDEVICES] = | ||
1592 | { | ||
1593 | [SOUND_MIXER_CD] = 1, | ||
1594 | [SOUND_MIXER_LINE] = 2, | ||
1595 | [SOUND_MIXER_MIC] = 3, | ||
1596 | [SOUND_MIXER_SYNTH] = 4, | ||
1597 | [SOUND_MIXER_VOLUME] = 5, | ||
1598 | [SOUND_MIXER_PCM] = 6, | ||
1599 | [SOUND_MIXER_LINE1] = 7, | ||
1600 | [SOUND_MIXER_SPEAKER]= 8 | ||
1601 | }; | ||
1602 | |||
1603 | static unsigned mixer_outmask(struct cm_state *s) | ||
1604 | { | ||
1605 | unsigned long flags; | ||
1606 | int i, j, k; | ||
1607 | |||
1608 | spin_lock_irqsave(&s->lock, flags); | ||
1609 | j = rdmixer(s, DSP_MIX_OUTMIXIDX); | ||
1610 | spin_unlock_irqrestore(&s->lock, flags); | ||
1611 | for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
1612 | if (j & mixtable[i].play) | ||
1613 | k |= 1 << i; | ||
1614 | return k; | ||
1615 | } | ||
1616 | |||
1617 | static unsigned mixer_recmask(struct cm_state *s) | ||
1618 | { | ||
1619 | unsigned long flags; | ||
1620 | int i, j, k; | ||
1621 | |||
1622 | spin_lock_irqsave(&s->lock, flags); | ||
1623 | j = rdmixer(s, DSP_MIX_ADCMIXIDX_L); | ||
1624 | spin_unlock_irqrestore(&s->lock, flags); | ||
1625 | for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
1626 | if (j & mixtable[i].rec) | ||
1627 | k |= 1 << i; | ||
1628 | return k; | ||
1629 | } | ||
1630 | |||
1631 | static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg) | ||
1632 | { | ||
1633 | unsigned long flags; | ||
1634 | int i, val, j; | ||
1635 | unsigned char l, r, rl, rr; | ||
1636 | void __user *argp = (void __user *)arg; | ||
1637 | int __user *p = argp; | ||
1638 | |||
1639 | VALIDATE_STATE(s); | ||
1640 | if (cmd == SOUND_MIXER_INFO) { | ||
1641 | mixer_info info; | ||
1642 | memset(&info, 0, sizeof(info)); | ||
1643 | strlcpy(info.id, "cmpci", sizeof(info.id)); | ||
1644 | strlcpy(info.name, "C-Media PCI", sizeof(info.name)); | ||
1645 | info.modify_counter = s->mix.modcnt; | ||
1646 | if (copy_to_user(argp, &info, sizeof(info))) | ||
1647 | return -EFAULT; | ||
1648 | return 0; | ||
1649 | } | ||
1650 | if (cmd == SOUND_OLD_MIXER_INFO) { | ||
1651 | _old_mixer_info info; | ||
1652 | memset(&info, 0, sizeof(info)); | ||
1653 | strlcpy(info.id, "cmpci", sizeof(info.id)); | ||
1654 | strlcpy(info.name, "C-Media cmpci", sizeof(info.name)); | ||
1655 | if (copy_to_user(argp, &info, sizeof(info))) | ||
1656 | return -EFAULT; | ||
1657 | return 0; | ||
1658 | } | ||
1659 | if (cmd == OSS_GETVERSION) | ||
1660 | return put_user(SOUND_VERSION, p); | ||
1661 | if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int)) | ||
1662 | return -EINVAL; | ||
1663 | if (_SIOC_DIR(cmd) == _SIOC_READ) { | ||
1664 | switch (_IOC_NR(cmd)) { | ||
1665 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
1666 | val = mixer_recmask(s); | ||
1667 | return put_user(val, p); | ||
1668 | |||
1669 | case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */ | ||
1670 | val = mixer_outmask(s); | ||
1671 | return put_user(val, p); | ||
1672 | |||
1673 | case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ | ||
1674 | for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
1675 | if (mixtable[i].type) | ||
1676 | val |= 1 << i; | ||
1677 | return put_user(val, p); | ||
1678 | |||
1679 | case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ | ||
1680 | for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
1681 | if (mixtable[i].rec) | ||
1682 | val |= 1 << i; | ||
1683 | return put_user(val, p); | ||
1684 | |||
1685 | case SOUND_MIXER_OUTMASK: /* Arg contains a bit for each supported recording source */ | ||
1686 | for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
1687 | if (mixtable[i].play) | ||
1688 | val |= 1 << i; | ||
1689 | return put_user(val, p); | ||
1690 | |||
1691 | case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ | ||
1692 | for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
1693 | if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO) | ||
1694 | val |= 1 << i; | ||
1695 | return put_user(val, p); | ||
1696 | |||
1697 | case SOUND_MIXER_CAPS: | ||
1698 | return put_user(0, p); | ||
1699 | |||
1700 | default: | ||
1701 | i = _IOC_NR(cmd); | ||
1702 | if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type) | ||
1703 | return -EINVAL; | ||
1704 | if (!volidx[i]) | ||
1705 | return -EINVAL; | ||
1706 | return put_user(s->mix.vol[volidx[i]-1], p); | ||
1707 | } | ||
1708 | } | ||
1709 | if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) | ||
1710 | return -EINVAL; | ||
1711 | s->mix.modcnt++; | ||
1712 | switch (_IOC_NR(cmd)) { | ||
1713 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
1714 | if (get_user(val, p)) | ||
1715 | return -EFAULT; | ||
1716 | i = hweight32(val); | ||
1717 | for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||
1718 | if (!(val & (1 << i))) | ||
1719 | continue; | ||
1720 | if (!mixtable[i].rec) { | ||
1721 | val &= ~(1 << i); | ||
1722 | continue; | ||
1723 | } | ||
1724 | j |= mixtable[i].rec; | ||
1725 | } | ||
1726 | spin_lock_irqsave(&s->lock, flags); | ||
1727 | wrmixer(s, DSP_MIX_ADCMIXIDX_L, j); | ||
1728 | wrmixer(s, DSP_MIX_ADCMIXIDX_R, (j & 1) | (j>>1) | (j & 0x80)); | ||
1729 | spin_unlock_irqrestore(&s->lock, flags); | ||
1730 | return 0; | ||
1731 | |||
1732 | case SOUND_MIXER_OUTSRC: /* Arg contains a bit for each recording source */ | ||
1733 | if (get_user(val, p)) | ||
1734 | return -EFAULT; | ||
1735 | for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||
1736 | if (!(val & (1 << i))) | ||
1737 | continue; | ||
1738 | if (!mixtable[i].play) { | ||
1739 | val &= ~(1 << i); | ||
1740 | continue; | ||
1741 | } | ||
1742 | j |= mixtable[i].play; | ||
1743 | } | ||
1744 | spin_lock_irqsave(&s->lock, flags); | ||
1745 | wrmixer(s, DSP_MIX_OUTMIXIDX, j); | ||
1746 | spin_unlock_irqrestore(&s->lock, flags); | ||
1747 | return 0; | ||
1748 | |||
1749 | default: | ||
1750 | i = _IOC_NR(cmd); | ||
1751 | if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type) | ||
1752 | return -EINVAL; | ||
1753 | if (get_user(val, p)) | ||
1754 | return -EFAULT; | ||
1755 | l = val & 0xff; | ||
1756 | r = (val >> 8) & 0xff; | ||
1757 | if (l > 100) | ||
1758 | l = 100; | ||
1759 | if (r > 100) | ||
1760 | r = 100; | ||
1761 | spin_lock_irqsave(&s->lock, flags); | ||
1762 | switch (mixtable[i].type) { | ||
1763 | case MT_4: | ||
1764 | if (l >= 10) | ||
1765 | l -= 10; | ||
1766 | if (r >= 10) | ||
1767 | r -= 10; | ||
1768 | frobindir(s, mixtable[i].left, 0xf0, l / 6); | ||
1769 | frobindir(s, mixtable[i].right, 0xf0, l / 6); | ||
1770 | break; | ||
1771 | |||
1772 | case MT_4MUTEMONO: | ||
1773 | rl = (l < 4 ? 0 : (l - 5) / 3) & 31; | ||
1774 | rr = (rl >> 2) & 7; | ||
1775 | wrmixer(s, mixtable[i].left, rl<<3); | ||
1776 | if (i == SOUND_MIXER_MIC) | ||
1777 | maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1); | ||
1778 | break; | ||
1779 | |||
1780 | case MT_5MUTEMONO: | ||
1781 | rl = l < 4 ? 0 : (l - 5) / 3; | ||
1782 | wrmixer(s, mixtable[i].left, rl<<3); | ||
1783 | l = rdmixer(s, DSP_MIX_OUTMIXIDX) & ~mixtable[i].play; | ||
1784 | r = rl ? mixtable[i].play : 0; | ||
1785 | wrmixer(s, DSP_MIX_OUTMIXIDX, l | r); | ||
1786 | /* for recording */ | ||
1787 | if (i == SOUND_MIXER_MIC) { | ||
1788 | if (s->chip_version >= 37) { | ||
1789 | rr = rl >> 1; | ||
1790 | maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, (rr&0x07)<<1); | ||
1791 | frobindir(s, DSP_MIX_EXTENSION, ~0x01, rr>>3); | ||
1792 | } else { | ||
1793 | rr = rl >> 2; | ||
1794 | maskb(s->iobase + CODEC_CMI_MIXER2, ~0x0e, rr<<1); | ||
1795 | } | ||
1796 | } | ||
1797 | break; | ||
1798 | |||
1799 | case MT_5MUTE: | ||
1800 | rl = l < 4 ? 0 : (l - 5) / 3; | ||
1801 | rr = r < 4 ? 0 : (r - 5) / 3; | ||
1802 | wrmixer(s, mixtable[i].left, rl<<3); | ||
1803 | wrmixer(s, mixtable[i].right, rr<<3); | ||
1804 | l = rdmixer(s, DSP_MIX_OUTMIXIDX); | ||
1805 | l &= ~mixtable[i].play; | ||
1806 | r = (rl|rr) ? mixtable[i].play : 0; | ||
1807 | wrmixer(s, DSP_MIX_OUTMIXIDX, l | r); | ||
1808 | break; | ||
1809 | |||
1810 | case MT_6MUTE: | ||
1811 | if (l < 6) | ||
1812 | rl = 0x00; | ||
1813 | else | ||
1814 | rl = l * 2 / 3; | ||
1815 | if (r < 6) | ||
1816 | rr = 0x00; | ||
1817 | else | ||
1818 | rr = r * 2 / 3; | ||
1819 | wrmixer(s, mixtable[i].left, rl); | ||
1820 | wrmixer(s, mixtable[i].right, rr); | ||
1821 | break; | ||
1822 | } | ||
1823 | spin_unlock_irqrestore(&s->lock, flags); | ||
1824 | |||
1825 | if (!volidx[i]) | ||
1826 | return -EINVAL; | ||
1827 | s->mix.vol[volidx[i]-1] = val; | ||
1828 | return put_user(s->mix.vol[volidx[i]-1], p); | ||
1829 | } | ||
1830 | } | ||
1831 | |||
1832 | /* --------------------------------------------------------------------- */ | ||
1833 | |||
1834 | static int cm_open_mixdev(struct inode *inode, struct file *file) | ||
1835 | { | ||
1836 | int minor = iminor(inode); | ||
1837 | struct list_head *list; | ||
1838 | struct cm_state *s; | ||
1839 | |||
1840 | for (list = devs.next; ; list = list->next) { | ||
1841 | if (list == &devs) | ||
1842 | return -ENODEV; | ||
1843 | s = list_entry(list, struct cm_state, devs); | ||
1844 | if (s->dev_mixer == minor) | ||
1845 | break; | ||
1846 | } | ||
1847 | VALIDATE_STATE(s); | ||
1848 | file->private_data = s; | ||
1849 | return nonseekable_open(inode, file); | ||
1850 | } | ||
1851 | |||
1852 | static int cm_release_mixdev(struct inode *inode, struct file *file) | ||
1853 | { | ||
1854 | struct cm_state *s = (struct cm_state *)file->private_data; | ||
1855 | |||
1856 | VALIDATE_STATE(s); | ||
1857 | return 0; | ||
1858 | } | ||
1859 | |||
1860 | static int cm_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1861 | { | ||
1862 | return mixer_ioctl((struct cm_state *)file->private_data, cmd, arg); | ||
1863 | } | ||
1864 | |||
1865 | static /*const*/ struct file_operations cm_mixer_fops = { | ||
1866 | .owner = THIS_MODULE, | ||
1867 | .llseek = no_llseek, | ||
1868 | .ioctl = cm_ioctl_mixdev, | ||
1869 | .open = cm_open_mixdev, | ||
1870 | .release = cm_release_mixdev, | ||
1871 | }; | ||
1872 | |||
1873 | |||
1874 | /* --------------------------------------------------------------------- */ | ||
1875 | |||
1876 | static int drain_dac(struct cm_state *s, int nonblock) | ||
1877 | { | ||
1878 | DECLARE_WAITQUEUE(wait, current); | ||
1879 | unsigned long flags; | ||
1880 | int count, tmo; | ||
1881 | |||
1882 | if (s->dma_dac.mapped || !s->dma_dac.ready) | ||
1883 | return 0; | ||
1884 | add_wait_queue(&s->dma_dac.wait, &wait); | ||
1885 | for (;;) { | ||
1886 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1887 | spin_lock_irqsave(&s->lock, flags); | ||
1888 | count = s->dma_dac.count; | ||
1889 | spin_unlock_irqrestore(&s->lock, flags); | ||
1890 | if (count <= 0) | ||
1891 | break; | ||
1892 | if (signal_pending(current)) | ||
1893 | break; | ||
1894 | if (nonblock) { | ||
1895 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
1896 | set_current_state(TASK_RUNNING); | ||
1897 | return -EBUSY; | ||
1898 | } | ||
1899 | tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac; | ||
1900 | tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK]; | ||
1901 | if (!schedule_timeout(tmo + 1)) | ||
1902 | DBG(printk(KERN_DEBUG "cmpci: dma timed out??\n");) | ||
1903 | } | ||
1904 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
1905 | set_current_state(TASK_RUNNING); | ||
1906 | if (signal_pending(current)) | ||
1907 | return -ERESTARTSYS; | ||
1908 | return 0; | ||
1909 | } | ||
1910 | |||
1911 | /* --------------------------------------------------------------------- */ | ||
1912 | |||
1913 | static ssize_t cm_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1914 | { | ||
1915 | struct cm_state *s = (struct cm_state *)file->private_data; | ||
1916 | DECLARE_WAITQUEUE(wait, current); | ||
1917 | ssize_t ret; | ||
1918 | unsigned long flags; | ||
1919 | unsigned swptr; | ||
1920 | int cnt; | ||
1921 | |||
1922 | VALIDATE_STATE(s); | ||
1923 | if (s->dma_adc.mapped) | ||
1924 | return -ENXIO; | ||
1925 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
1926 | return ret; | ||
1927 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1928 | return -EFAULT; | ||
1929 | ret = 0; | ||
1930 | |||
1931 | add_wait_queue(&s->dma_adc.wait, &wait); | ||
1932 | while (count > 0) { | ||
1933 | spin_lock_irqsave(&s->lock, flags); | ||
1934 | swptr = s->dma_adc.swptr; | ||
1935 | cnt = s->dma_adc.dmasize-swptr; | ||
1936 | if (s->dma_adc.count < cnt) | ||
1937 | cnt = s->dma_adc.count; | ||
1938 | if (cnt <= 0) | ||
1939 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1940 | spin_unlock_irqrestore(&s->lock, flags); | ||
1941 | if (cnt > count) | ||
1942 | cnt = count; | ||
1943 | if (cnt <= 0) { | ||
1944 | if (s->dma_adc.enabled) | ||
1945 | start_adc(s); | ||
1946 | if (file->f_flags & O_NONBLOCK) { | ||
1947 | if (!ret) | ||
1948 | ret = -EAGAIN; | ||
1949 | goto out; | ||
1950 | } | ||
1951 | if (!schedule_timeout(HZ)) { | ||
1952 | printk(KERN_DEBUG "cmpci: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
1953 | s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, | ||
1954 | s->dma_adc.hwptr, s->dma_adc.swptr); | ||
1955 | spin_lock_irqsave(&s->lock, flags); | ||
1956 | stop_adc_unlocked(s); | ||
1957 | set_dmaadc(s, s->dma_adc.dmaaddr, s->dma_adc.dmasamples); | ||
1958 | /* program sample counts */ | ||
1959 | set_countadc(s, s->dma_adc.fragsamples); | ||
1960 | s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0; | ||
1961 | spin_unlock_irqrestore(&s->lock, flags); | ||
1962 | } | ||
1963 | if (signal_pending(current)) { | ||
1964 | if (!ret) | ||
1965 | ret = -ERESTARTSYS; | ||
1966 | goto out; | ||
1967 | } | ||
1968 | continue; | ||
1969 | } | ||
1970 | if (s->status & DO_BIGENDIAN_R) { | ||
1971 | int i, err; | ||
1972 | unsigned char *src; | ||
1973 | char __user *dst = buffer; | ||
1974 | unsigned char data[2]; | ||
1975 | |||
1976 | src = (unsigned char *) (s->dma_adc.rawbuf + swptr); | ||
1977 | // copy left/right sample at one time | ||
1978 | for (i = 0; i < cnt / 2; i++) { | ||
1979 | data[0] = src[1]; | ||
1980 | data[1] = src[0]; | ||
1981 | if ((err = __put_user(data[0], dst++))) { | ||
1982 | ret = err; | ||
1983 | goto out; | ||
1984 | } | ||
1985 | if ((err = __put_user(data[1], dst++))) { | ||
1986 | ret = err; | ||
1987 | goto out; | ||
1988 | } | ||
1989 | src += 2; | ||
1990 | } | ||
1991 | } else if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { | ||
1992 | if (!ret) | ||
1993 | ret = -EFAULT; | ||
1994 | goto out; | ||
1995 | } | ||
1996 | swptr = (swptr + cnt) % s->dma_adc.dmasize; | ||
1997 | spin_lock_irqsave(&s->lock, flags); | ||
1998 | s->dma_adc.swptr = swptr; | ||
1999 | s->dma_adc.count -= cnt; | ||
2000 | count -= cnt; | ||
2001 | buffer += cnt; | ||
2002 | ret += cnt; | ||
2003 | if (s->dma_adc.enabled) | ||
2004 | start_adc_unlocked(s); | ||
2005 | spin_unlock_irqrestore(&s->lock, flags); | ||
2006 | } | ||
2007 | out: | ||
2008 | remove_wait_queue(&s->dma_adc.wait, &wait); | ||
2009 | set_current_state(TASK_RUNNING); | ||
2010 | return ret; | ||
2011 | } | ||
2012 | |||
2013 | static ssize_t cm_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
2014 | { | ||
2015 | struct cm_state *s = (struct cm_state *)file->private_data; | ||
2016 | DECLARE_WAITQUEUE(wait, current); | ||
2017 | ssize_t ret; | ||
2018 | unsigned long flags; | ||
2019 | unsigned swptr; | ||
2020 | int cnt; | ||
2021 | |||
2022 | VALIDATE_STATE(s); | ||
2023 | if (s->dma_dac.mapped) | ||
2024 | return -ENXIO; | ||
2025 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
2026 | return ret; | ||
2027 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
2028 | return -EFAULT; | ||
2029 | if (s->status & DO_DUAL_DAC) { | ||
2030 | if (s->dma_adc.mapped) | ||
2031 | return -ENXIO; | ||
2032 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
2033 | return ret; | ||
2034 | } | ||
2035 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
2036 | return -EFAULT; | ||
2037 | ret = 0; | ||
2038 | |||
2039 | add_wait_queue(&s->dma_dac.wait, &wait); | ||
2040 | while (count > 0) { | ||
2041 | spin_lock_irqsave(&s->lock, flags); | ||
2042 | if (s->dma_dac.count < 0) { | ||
2043 | s->dma_dac.count = 0; | ||
2044 | s->dma_dac.swptr = s->dma_dac.hwptr; | ||
2045 | } | ||
2046 | if (s->status & DO_DUAL_DAC) { | ||
2047 | s->dma_adc.swptr = s->dma_dac.swptr; | ||
2048 | s->dma_adc.count = s->dma_dac.count; | ||
2049 | s->dma_adc.endcleared = s->dma_dac.endcleared; | ||
2050 | } | ||
2051 | swptr = s->dma_dac.swptr; | ||
2052 | cnt = s->dma_dac.dmasize-swptr; | ||
2053 | if (s->status & DO_AC3_SW) { | ||
2054 | if (s->dma_dac.count + 2 * cnt > s->dma_dac.dmasize) | ||
2055 | cnt = (s->dma_dac.dmasize - s->dma_dac.count) / 2; | ||
2056 | } else { | ||
2057 | if (s->dma_dac.count + cnt > s->dma_dac.dmasize) | ||
2058 | cnt = s->dma_dac.dmasize - s->dma_dac.count; | ||
2059 | } | ||
2060 | if (cnt <= 0) | ||
2061 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2062 | spin_unlock_irqrestore(&s->lock, flags); | ||
2063 | if (cnt > count) | ||
2064 | cnt = count; | ||
2065 | if ((s->status & DO_DUAL_DAC) && (cnt > count / 2)) | ||
2066 | cnt = count / 2; | ||
2067 | if (cnt <= 0) { | ||
2068 | if (s->dma_dac.enabled) | ||
2069 | start_dac(s); | ||
2070 | if (file->f_flags & O_NONBLOCK) { | ||
2071 | if (!ret) | ||
2072 | ret = -EAGAIN; | ||
2073 | goto out; | ||
2074 | } | ||
2075 | if (!schedule_timeout(HZ)) { | ||
2076 | printk(KERN_DEBUG "cmpci: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
2077 | s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, | ||
2078 | s->dma_dac.hwptr, s->dma_dac.swptr); | ||
2079 | spin_lock_irqsave(&s->lock, flags); | ||
2080 | stop_dac_unlocked(s); | ||
2081 | set_dmadac(s, s->dma_dac.dmaaddr, s->dma_dac.dmasamples); | ||
2082 | /* program sample counts */ | ||
2083 | set_countdac(s, s->dma_dac.fragsamples); | ||
2084 | s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0; | ||
2085 | if (s->status & DO_DUAL_DAC) { | ||
2086 | set_dmadac1(s, s->dma_adc.dmaaddr, s->dma_adc.dmasamples); | ||
2087 | s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0; | ||
2088 | } | ||
2089 | spin_unlock_irqrestore(&s->lock, flags); | ||
2090 | } | ||
2091 | if (signal_pending(current)) { | ||
2092 | if (!ret) | ||
2093 | ret = -ERESTARTSYS; | ||
2094 | goto out; | ||
2095 | } | ||
2096 | continue; | ||
2097 | } | ||
2098 | if (s->status & DO_AC3_SW) { | ||
2099 | int err; | ||
2100 | |||
2101 | // clip exceeded data, caught by 033 and 037 | ||
2102 | if (swptr + 2 * cnt > s->dma_dac.dmasize) | ||
2103 | cnt = (s->dma_dac.dmasize - swptr) / 2; | ||
2104 | if ((err = trans_ac3(s, s->dma_dac.rawbuf + swptr, buffer, cnt))) { | ||
2105 | ret = err; | ||
2106 | goto out; | ||
2107 | } | ||
2108 | swptr = (swptr + 2 * cnt) % s->dma_dac.dmasize; | ||
2109 | } else if ((s->status & DO_DUAL_DAC) && (s->status & DO_BIGENDIAN_W)) { | ||
2110 | int i, err; | ||
2111 | const char __user *src = buffer; | ||
2112 | unsigned char *dst0, *dst1; | ||
2113 | unsigned char data[8]; | ||
2114 | |||
2115 | dst0 = (unsigned char *) (s->dma_dac.rawbuf + swptr); | ||
2116 | dst1 = (unsigned char *) (s->dma_adc.rawbuf + swptr); | ||
2117 | // copy left/right sample at one time | ||
2118 | for (i = 0; i < cnt / 4; i++) { | ||
2119 | if ((err = __get_user(data[0], src++))) { | ||
2120 | ret = err; | ||
2121 | goto out; | ||
2122 | } | ||
2123 | if ((err = __get_user(data[1], src++))) { | ||
2124 | ret = err; | ||
2125 | goto out; | ||
2126 | } | ||
2127 | if ((err = __get_user(data[2], src++))) { | ||
2128 | ret = err; | ||
2129 | goto out; | ||
2130 | } | ||
2131 | if ((err = __get_user(data[3], src++))) { | ||
2132 | ret = err; | ||
2133 | goto out; | ||
2134 | } | ||
2135 | if ((err = __get_user(data[4], src++))) { | ||
2136 | ret = err; | ||
2137 | goto out; | ||
2138 | } | ||
2139 | if ((err = __get_user(data[5], src++))) { | ||
2140 | ret = err; | ||
2141 | goto out; | ||
2142 | } | ||
2143 | if ((err = __get_user(data[6], src++))) { | ||
2144 | ret = err; | ||
2145 | goto out; | ||
2146 | } | ||
2147 | if ((err = __get_user(data[7], src++))) { | ||
2148 | ret = err; | ||
2149 | goto out; | ||
2150 | } | ||
2151 | dst0[0] = data[1]; | ||
2152 | dst0[1] = data[0]; | ||
2153 | dst0[2] = data[3]; | ||
2154 | dst0[3] = data[2]; | ||
2155 | dst1[0] = data[5]; | ||
2156 | dst1[1] = data[4]; | ||
2157 | dst1[2] = data[7]; | ||
2158 | dst1[3] = data[6]; | ||
2159 | dst0 += 4; | ||
2160 | dst1 += 4; | ||
2161 | } | ||
2162 | swptr = (swptr + cnt) % s->dma_dac.dmasize; | ||
2163 | } else if (s->status & DO_DUAL_DAC) { | ||
2164 | int i, err; | ||
2165 | unsigned long __user *src = (unsigned long __user *) buffer; | ||
2166 | unsigned long *dst0, *dst1; | ||
2167 | |||
2168 | dst0 = (unsigned long *) (s->dma_dac.rawbuf + swptr); | ||
2169 | dst1 = (unsigned long *) (s->dma_adc.rawbuf + swptr); | ||
2170 | // copy left/right sample at one time | ||
2171 | for (i = 0; i < cnt / 4; i++) { | ||
2172 | if ((err = __get_user(*dst0++, src++))) { | ||
2173 | ret = err; | ||
2174 | goto out; | ||
2175 | } | ||
2176 | if ((err = __get_user(*dst1++, src++))) { | ||
2177 | ret = err; | ||
2178 | goto out; | ||
2179 | } | ||
2180 | } | ||
2181 | swptr = (swptr + cnt) % s->dma_dac.dmasize; | ||
2182 | } else if (s->status & DO_BIGENDIAN_W) { | ||
2183 | int i, err; | ||
2184 | const char __user *src = buffer; | ||
2185 | unsigned char *dst; | ||
2186 | unsigned char data[2]; | ||
2187 | |||
2188 | dst = (unsigned char *) (s->dma_dac.rawbuf + swptr); | ||
2189 | // swap hi/lo bytes for each sample | ||
2190 | for (i = 0; i < cnt / 2; i++) { | ||
2191 | if ((err = __get_user(data[0], src++))) { | ||
2192 | ret = err; | ||
2193 | goto out; | ||
2194 | } | ||
2195 | if ((err = __get_user(data[1], src++))) { | ||
2196 | ret = err; | ||
2197 | goto out; | ||
2198 | } | ||
2199 | dst[0] = data[1]; | ||
2200 | dst[1] = data[0]; | ||
2201 | dst += 2; | ||
2202 | } | ||
2203 | swptr = (swptr + cnt) % s->dma_dac.dmasize; | ||
2204 | } else { | ||
2205 | if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { | ||
2206 | if (!ret) | ||
2207 | ret = -EFAULT; | ||
2208 | goto out; | ||
2209 | } | ||
2210 | swptr = (swptr + cnt) % s->dma_dac.dmasize; | ||
2211 | } | ||
2212 | spin_lock_irqsave(&s->lock, flags); | ||
2213 | s->dma_dac.swptr = swptr; | ||
2214 | s->dma_dac.count += cnt; | ||
2215 | if (s->status & DO_AC3_SW) | ||
2216 | s->dma_dac.count += cnt; | ||
2217 | s->dma_dac.endcleared = 0; | ||
2218 | spin_unlock_irqrestore(&s->lock, flags); | ||
2219 | count -= cnt; | ||
2220 | buffer += cnt; | ||
2221 | ret += cnt; | ||
2222 | if (s->status & DO_DUAL_DAC) { | ||
2223 | count -= cnt; | ||
2224 | buffer += cnt; | ||
2225 | ret += cnt; | ||
2226 | } | ||
2227 | if (s->dma_dac.enabled) | ||
2228 | start_dac(s); | ||
2229 | } | ||
2230 | out: | ||
2231 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
2232 | set_current_state(TASK_RUNNING); | ||
2233 | return ret; | ||
2234 | } | ||
2235 | |||
2236 | static unsigned int cm_poll(struct file *file, struct poll_table_struct *wait) | ||
2237 | { | ||
2238 | struct cm_state *s = (struct cm_state *)file->private_data; | ||
2239 | unsigned long flags; | ||
2240 | unsigned int mask = 0; | ||
2241 | |||
2242 | VALIDATE_STATE(s); | ||
2243 | if (file->f_mode & FMODE_WRITE) { | ||
2244 | if (!s->dma_dac.ready && prog_dmabuf(s, 0)) | ||
2245 | return 0; | ||
2246 | poll_wait(file, &s->dma_dac.wait, wait); | ||
2247 | } | ||
2248 | if (file->f_mode & FMODE_READ) { | ||
2249 | if (!s->dma_adc.ready && prog_dmabuf(s, 1)) | ||
2250 | return 0; | ||
2251 | poll_wait(file, &s->dma_adc.wait, wait); | ||
2252 | } | ||
2253 | spin_lock_irqsave(&s->lock, flags); | ||
2254 | cm_update_ptr(s); | ||
2255 | if (file->f_mode & FMODE_READ) { | ||
2256 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
2257 | mask |= POLLIN | POLLRDNORM; | ||
2258 | } | ||
2259 | if (file->f_mode & FMODE_WRITE) { | ||
2260 | if (s->dma_dac.mapped) { | ||
2261 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) | ||
2262 | mask |= POLLOUT | POLLWRNORM; | ||
2263 | } else { | ||
2264 | if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize) | ||
2265 | mask |= POLLOUT | POLLWRNORM; | ||
2266 | } | ||
2267 | } | ||
2268 | spin_unlock_irqrestore(&s->lock, flags); | ||
2269 | return mask; | ||
2270 | } | ||
2271 | |||
2272 | static int cm_mmap(struct file *file, struct vm_area_struct *vma) | ||
2273 | { | ||
2274 | struct cm_state *s = (struct cm_state *)file->private_data; | ||
2275 | struct dmabuf *db; | ||
2276 | int ret = -EINVAL; | ||
2277 | unsigned long size; | ||
2278 | |||
2279 | VALIDATE_STATE(s); | ||
2280 | lock_kernel(); | ||
2281 | if (vma->vm_flags & VM_WRITE) { | ||
2282 | if ((ret = prog_dmabuf(s, 0)) != 0) | ||
2283 | goto out; | ||
2284 | db = &s->dma_dac; | ||
2285 | } else if (vma->vm_flags & VM_READ) { | ||
2286 | if ((ret = prog_dmabuf(s, 1)) != 0) | ||
2287 | goto out; | ||
2288 | db = &s->dma_adc; | ||
2289 | } else | ||
2290 | goto out; | ||
2291 | ret = -EINVAL; | ||
2292 | if (vma->vm_pgoff != 0) | ||
2293 | goto out; | ||
2294 | size = vma->vm_end - vma->vm_start; | ||
2295 | if (size > (PAGE_SIZE << db->buforder)) | ||
2296 | goto out; | ||
2297 | ret = -EINVAL; | ||
2298 | if (remap_pfn_range(vma, vma->vm_start, | ||
2299 | virt_to_phys(db->rawbuf) >> PAGE_SHIFT, | ||
2300 | size, vma->vm_page_prot)) | ||
2301 | goto out; | ||
2302 | db->mapped = 1; | ||
2303 | ret = 0; | ||
2304 | out: | ||
2305 | unlock_kernel(); | ||
2306 | return ret; | ||
2307 | } | ||
2308 | |||
2309 | #define SNDCTL_SPDIF_COPYRIGHT _SIOW('S', 0, int) // set/reset S/PDIF copy protection | ||
2310 | #define SNDCTL_SPDIF_LOOP _SIOW('S', 1, int) // set/reset S/PDIF loop | ||
2311 | #define SNDCTL_SPDIF_MONITOR _SIOW('S', 2, int) // set S/PDIF monitor | ||
2312 | #define SNDCTL_SPDIF_LEVEL _SIOW('S', 3, int) // set/reset S/PDIF out level | ||
2313 | #define SNDCTL_SPDIF_INV _SIOW('S', 4, int) // set/reset S/PDIF in inverse | ||
2314 | #define SNDCTL_SPDIF_SEL2 _SIOW('S', 5, int) // set S/PDIF in #2 | ||
2315 | #define SNDCTL_SPDIF_VALID _SIOW('S', 6, int) // set S/PDIF valid | ||
2316 | #define SNDCTL_SPDIFOUT _SIOW('S', 7, int) // set S/PDIF out | ||
2317 | #define SNDCTL_SPDIFIN _SIOW('S', 8, int) // set S/PDIF out | ||
2318 | |||
2319 | static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
2320 | { | ||
2321 | struct cm_state *s = (struct cm_state *)file->private_data; | ||
2322 | unsigned long flags; | ||
2323 | audio_buf_info abinfo; | ||
2324 | count_info cinfo; | ||
2325 | int val, mapped, ret; | ||
2326 | unsigned char fmtm, fmtd; | ||
2327 | void __user *argp = (void __user *)arg; | ||
2328 | int __user *p = argp; | ||
2329 | |||
2330 | VALIDATE_STATE(s); | ||
2331 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || | ||
2332 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
2333 | switch (cmd) { | ||
2334 | case OSS_GETVERSION: | ||
2335 | return put_user(SOUND_VERSION, p); | ||
2336 | |||
2337 | case SNDCTL_DSP_SYNC: | ||
2338 | if (file->f_mode & FMODE_WRITE) | ||
2339 | return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/); | ||
2340 | return 0; | ||
2341 | |||
2342 | case SNDCTL_DSP_SETDUPLEX: | ||
2343 | return 0; | ||
2344 | |||
2345 | case SNDCTL_DSP_GETCAPS: | ||
2346 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_BIND, p); | ||
2347 | |||
2348 | case SNDCTL_DSP_RESET: | ||
2349 | if (file->f_mode & FMODE_WRITE) { | ||
2350 | stop_dac(s); | ||
2351 | synchronize_irq(s->irq); | ||
2352 | s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0; | ||
2353 | if (s->status & DO_DUAL_DAC) | ||
2354 | s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
2355 | } | ||
2356 | if (file->f_mode & FMODE_READ) { | ||
2357 | stop_adc(s); | ||
2358 | synchronize_irq(s->irq); | ||
2359 | s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
2360 | } | ||
2361 | return 0; | ||
2362 | |||
2363 | case SNDCTL_DSP_SPEED: | ||
2364 | if (get_user(val, p)) | ||
2365 | return -EFAULT; | ||
2366 | if (val >= 0) { | ||
2367 | if (file->f_mode & FMODE_READ) { | ||
2368 | spin_lock_irqsave(&s->lock, flags); | ||
2369 | stop_adc_unlocked(s); | ||
2370 | s->dma_adc.ready = 0; | ||
2371 | set_adc_rate_unlocked(s, val); | ||
2372 | spin_unlock_irqrestore(&s->lock, flags); | ||
2373 | } | ||
2374 | if (file->f_mode & FMODE_WRITE) { | ||
2375 | stop_dac(s); | ||
2376 | s->dma_dac.ready = 0; | ||
2377 | if (s->status & DO_DUAL_DAC) | ||
2378 | s->dma_adc.ready = 0; | ||
2379 | set_dac_rate(s, val); | ||
2380 | } | ||
2381 | } | ||
2382 | return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p); | ||
2383 | |||
2384 | case SNDCTL_DSP_STEREO: | ||
2385 | if (get_user(val, p)) | ||
2386 | return -EFAULT; | ||
2387 | fmtd = 0; | ||
2388 | fmtm = ~0; | ||
2389 | if (file->f_mode & FMODE_READ) { | ||
2390 | stop_adc(s); | ||
2391 | s->dma_adc.ready = 0; | ||
2392 | if (val) | ||
2393 | fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT; | ||
2394 | else | ||
2395 | fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT); | ||
2396 | } | ||
2397 | if (file->f_mode & FMODE_WRITE) { | ||
2398 | stop_dac(s); | ||
2399 | s->dma_dac.ready = 0; | ||
2400 | if (val) | ||
2401 | fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT; | ||
2402 | else | ||
2403 | fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT); | ||
2404 | if (s->status & DO_DUAL_DAC) { | ||
2405 | s->dma_adc.ready = 0; | ||
2406 | if (val) | ||
2407 | fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT; | ||
2408 | else | ||
2409 | fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT); | ||
2410 | } | ||
2411 | } | ||
2412 | set_fmt(s, fmtm, fmtd); | ||
2413 | return 0; | ||
2414 | |||
2415 | case SNDCTL_DSP_CHANNELS: | ||
2416 | if (get_user(val, p)) | ||
2417 | return -EFAULT; | ||
2418 | if (val != 0) { | ||
2419 | fmtd = 0; | ||
2420 | fmtm = ~0; | ||
2421 | if (file->f_mode & FMODE_READ) { | ||
2422 | stop_adc(s); | ||
2423 | s->dma_adc.ready = 0; | ||
2424 | if (val >= 2) | ||
2425 | fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT; | ||
2426 | else | ||
2427 | fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT); | ||
2428 | } | ||
2429 | if (file->f_mode & FMODE_WRITE) { | ||
2430 | stop_dac(s); | ||
2431 | s->dma_dac.ready = 0; | ||
2432 | if (val >= 2) | ||
2433 | fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT; | ||
2434 | else | ||
2435 | fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_DACSHIFT); | ||
2436 | if (s->status & DO_DUAL_DAC) { | ||
2437 | s->dma_adc.ready = 0; | ||
2438 | if (val >= 2) | ||
2439 | fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT; | ||
2440 | else | ||
2441 | fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT); | ||
2442 | } | ||
2443 | } | ||
2444 | set_fmt(s, fmtm, fmtd); | ||
2445 | if ((s->capability & CAN_MULTI_CH) | ||
2446 | && (file->f_mode & FMODE_WRITE)) { | ||
2447 | val = set_dac_channels(s, val); | ||
2448 | return put_user(val, p); | ||
2449 | } | ||
2450 | } | ||
2451 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) | ||
2452 | : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p); | ||
2453 | |||
2454 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
2455 | return put_user(AFMT_S16_BE|AFMT_S16_LE|AFMT_U8| | ||
2456 | ((s->capability & CAN_AC3) ? AFMT_AC3 : 0), p); | ||
2457 | |||
2458 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
2459 | if (get_user(val, p)) | ||
2460 | return -EFAULT; | ||
2461 | if (val != AFMT_QUERY) { | ||
2462 | fmtd = 0; | ||
2463 | fmtm = ~0; | ||
2464 | if (file->f_mode & FMODE_READ) { | ||
2465 | stop_adc(s); | ||
2466 | s->dma_adc.ready = 0; | ||
2467 | if (val == AFMT_S16_BE || val == AFMT_S16_LE) | ||
2468 | fmtd |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT; | ||
2469 | else | ||
2470 | fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_ADCSHIFT); | ||
2471 | if (val == AFMT_S16_BE) | ||
2472 | s->status |= DO_BIGENDIAN_R; | ||
2473 | else | ||
2474 | s->status &= ~DO_BIGENDIAN_R; | ||
2475 | } | ||
2476 | if (file->f_mode & FMODE_WRITE) { | ||
2477 | stop_dac(s); | ||
2478 | s->dma_dac.ready = 0; | ||
2479 | if (val == AFMT_S16_BE || val == AFMT_S16_LE || val == AFMT_AC3) | ||
2480 | fmtd |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT; | ||
2481 | else | ||
2482 | fmtm &= ~(CM_CFMT_16BIT << CM_CFMT_DACSHIFT); | ||
2483 | if (val == AFMT_AC3) { | ||
2484 | fmtd |= CM_CFMT_STEREO << CM_CFMT_DACSHIFT; | ||
2485 | set_ac3(s, 48000); | ||
2486 | } else | ||
2487 | set_ac3(s, 0); | ||
2488 | if (s->status & DO_DUAL_DAC) { | ||
2489 | s->dma_adc.ready = 0; | ||
2490 | if (val == AFMT_S16_BE || val == AFMT_S16_LE) | ||
2491 | fmtd |= CM_CFMT_STEREO << CM_CFMT_ADCSHIFT; | ||
2492 | else | ||
2493 | fmtm &= ~(CM_CFMT_STEREO << CM_CFMT_ADCSHIFT); | ||
2494 | } | ||
2495 | if (val == AFMT_S16_BE) | ||
2496 | s->status |= DO_BIGENDIAN_W; | ||
2497 | else | ||
2498 | s->status &= ~DO_BIGENDIAN_W; | ||
2499 | } | ||
2500 | set_fmt(s, fmtm, fmtd); | ||
2501 | } | ||
2502 | if (s->status & DO_AC3) return put_user(AFMT_AC3, p); | ||
2503 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) | ||
2504 | : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? val : AFMT_U8, p); | ||
2505 | |||
2506 | case SNDCTL_DSP_POST: | ||
2507 | return 0; | ||
2508 | |||
2509 | case SNDCTL_DSP_GETTRIGGER: | ||
2510 | val = 0; | ||
2511 | if (s->status & DO_DUAL_DAC) { | ||
2512 | if (file->f_mode & FMODE_WRITE && | ||
2513 | (s->enable & ENDAC) && | ||
2514 | (s->enable & ENADC)) | ||
2515 | val |= PCM_ENABLE_OUTPUT; | ||
2516 | return put_user(val, p); | ||
2517 | } | ||
2518 | if (file->f_mode & FMODE_READ && s->enable & ENADC) | ||
2519 | val |= PCM_ENABLE_INPUT; | ||
2520 | if (file->f_mode & FMODE_WRITE && s->enable & ENDAC) | ||
2521 | val |= PCM_ENABLE_OUTPUT; | ||
2522 | return put_user(val, p); | ||
2523 | |||
2524 | case SNDCTL_DSP_SETTRIGGER: | ||
2525 | if (get_user(val, p)) | ||
2526 | return -EFAULT; | ||
2527 | if (file->f_mode & FMODE_READ) { | ||
2528 | if (val & PCM_ENABLE_INPUT) { | ||
2529 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
2530 | return ret; | ||
2531 | s->dma_adc.enabled = 1; | ||
2532 | start_adc(s); | ||
2533 | } else { | ||
2534 | s->dma_adc.enabled = 0; | ||
2535 | stop_adc(s); | ||
2536 | } | ||
2537 | } | ||
2538 | if (file->f_mode & FMODE_WRITE) { | ||
2539 | if (val & PCM_ENABLE_OUTPUT) { | ||
2540 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
2541 | return ret; | ||
2542 | if (s->status & DO_DUAL_DAC) { | ||
2543 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
2544 | return ret; | ||
2545 | } | ||
2546 | s->dma_dac.enabled = 1; | ||
2547 | start_dac(s); | ||
2548 | } else { | ||
2549 | s->dma_dac.enabled = 0; | ||
2550 | stop_dac(s); | ||
2551 | } | ||
2552 | } | ||
2553 | return 0; | ||
2554 | |||
2555 | case SNDCTL_DSP_GETOSPACE: | ||
2556 | if (!(file->f_mode & FMODE_WRITE)) | ||
2557 | return -EINVAL; | ||
2558 | if (!(s->enable & ENDAC) && (val = prog_dmabuf(s, 0)) != 0) | ||
2559 | return val; | ||
2560 | spin_lock_irqsave(&s->lock, flags); | ||
2561 | cm_update_ptr(s); | ||
2562 | abinfo.fragsize = s->dma_dac.fragsize; | ||
2563 | abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count; | ||
2564 | abinfo.fragstotal = s->dma_dac.numfrag; | ||
2565 | abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; | ||
2566 | spin_unlock_irqrestore(&s->lock, flags); | ||
2567 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
2568 | |||
2569 | case SNDCTL_DSP_GETISPACE: | ||
2570 | if (!(file->f_mode & FMODE_READ)) | ||
2571 | return -EINVAL; | ||
2572 | if (!(s->enable & ENADC) && (val = prog_dmabuf(s, 1)) != 0) | ||
2573 | return val; | ||
2574 | spin_lock_irqsave(&s->lock, flags); | ||
2575 | cm_update_ptr(s); | ||
2576 | abinfo.fragsize = s->dma_adc.fragsize; | ||
2577 | abinfo.bytes = s->dma_adc.count; | ||
2578 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
2579 | abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; | ||
2580 | spin_unlock_irqrestore(&s->lock, flags); | ||
2581 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
2582 | |||
2583 | case SNDCTL_DSP_NONBLOCK: | ||
2584 | file->f_flags |= O_NONBLOCK; | ||
2585 | return 0; | ||
2586 | |||
2587 | case SNDCTL_DSP_GETODELAY: | ||
2588 | if (!(file->f_mode & FMODE_WRITE)) | ||
2589 | return -EINVAL; | ||
2590 | spin_lock_irqsave(&s->lock, flags); | ||
2591 | cm_update_ptr(s); | ||
2592 | val = s->dma_dac.count; | ||
2593 | spin_unlock_irqrestore(&s->lock, flags); | ||
2594 | return put_user(val, p); | ||
2595 | |||
2596 | case SNDCTL_DSP_GETIPTR: | ||
2597 | if (!(file->f_mode & FMODE_READ)) | ||
2598 | return -EINVAL; | ||
2599 | spin_lock_irqsave(&s->lock, flags); | ||
2600 | cm_update_ptr(s); | ||
2601 | cinfo.bytes = s->dma_adc.total_bytes; | ||
2602 | cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift; | ||
2603 | cinfo.ptr = s->dma_adc.hwptr; | ||
2604 | if (s->dma_adc.mapped) | ||
2605 | s->dma_adc.count &= s->dma_adc.fragsize-1; | ||
2606 | spin_unlock_irqrestore(&s->lock, flags); | ||
2607 | return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; | ||
2608 | |||
2609 | case SNDCTL_DSP_GETOPTR: | ||
2610 | if (!(file->f_mode & FMODE_WRITE)) | ||
2611 | return -EINVAL; | ||
2612 | spin_lock_irqsave(&s->lock, flags); | ||
2613 | cm_update_ptr(s); | ||
2614 | cinfo.bytes = s->dma_dac.total_bytes; | ||
2615 | cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift; | ||
2616 | cinfo.ptr = s->dma_dac.hwptr; | ||
2617 | if (s->dma_dac.mapped) | ||
2618 | s->dma_dac.count &= s->dma_dac.fragsize-1; | ||
2619 | if (s->status & DO_DUAL_DAC) { | ||
2620 | if (s->dma_adc.mapped) | ||
2621 | s->dma_adc.count &= s->dma_adc.fragsize-1; | ||
2622 | } | ||
2623 | spin_unlock_irqrestore(&s->lock, flags); | ||
2624 | return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; | ||
2625 | |||
2626 | case SNDCTL_DSP_GETBLKSIZE: | ||
2627 | if (file->f_mode & FMODE_WRITE) { | ||
2628 | if ((val = prog_dmabuf(s, 0))) | ||
2629 | return val; | ||
2630 | if (s->status & DO_DUAL_DAC) { | ||
2631 | if ((val = prog_dmabuf(s, 1))) | ||
2632 | return val; | ||
2633 | return put_user(2 * s->dma_dac.fragsize, p); | ||
2634 | } | ||
2635 | return put_user(s->dma_dac.fragsize, p); | ||
2636 | } | ||
2637 | if ((val = prog_dmabuf(s, 1))) | ||
2638 | return val; | ||
2639 | return put_user(s->dma_adc.fragsize, p); | ||
2640 | |||
2641 | case SNDCTL_DSP_SETFRAGMENT: | ||
2642 | if (get_user(val, p)) | ||
2643 | return -EFAULT; | ||
2644 | if (file->f_mode & FMODE_READ) { | ||
2645 | s->dma_adc.ossfragshift = val & 0xffff; | ||
2646 | s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; | ||
2647 | if (s->dma_adc.ossfragshift < 4) | ||
2648 | s->dma_adc.ossfragshift = 4; | ||
2649 | if (s->dma_adc.ossfragshift > 15) | ||
2650 | s->dma_adc.ossfragshift = 15; | ||
2651 | if (s->dma_adc.ossmaxfrags < 4) | ||
2652 | s->dma_adc.ossmaxfrags = 4; | ||
2653 | } | ||
2654 | if (file->f_mode & FMODE_WRITE) { | ||
2655 | s->dma_dac.ossfragshift = val & 0xffff; | ||
2656 | s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; | ||
2657 | if (s->dma_dac.ossfragshift < 4) | ||
2658 | s->dma_dac.ossfragshift = 4; | ||
2659 | if (s->dma_dac.ossfragshift > 15) | ||
2660 | s->dma_dac.ossfragshift = 15; | ||
2661 | if (s->dma_dac.ossmaxfrags < 4) | ||
2662 | s->dma_dac.ossmaxfrags = 4; | ||
2663 | if (s->status & DO_DUAL_DAC) { | ||
2664 | s->dma_adc.ossfragshift = s->dma_dac.ossfragshift; | ||
2665 | s->dma_adc.ossmaxfrags = s->dma_dac.ossmaxfrags; | ||
2666 | } | ||
2667 | } | ||
2668 | return 0; | ||
2669 | |||
2670 | case SNDCTL_DSP_SUBDIVIDE: | ||
2671 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
2672 | (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) | ||
2673 | return -EINVAL; | ||
2674 | if (get_user(val, p)) | ||
2675 | return -EFAULT; | ||
2676 | if (val != 1 && val != 2 && val != 4) | ||
2677 | return -EINVAL; | ||
2678 | if (file->f_mode & FMODE_READ) | ||
2679 | s->dma_adc.subdivision = val; | ||
2680 | if (file->f_mode & FMODE_WRITE) { | ||
2681 | s->dma_dac.subdivision = val; | ||
2682 | if (s->status & DO_DUAL_DAC) | ||
2683 | s->dma_adc.subdivision = val; | ||
2684 | } | ||
2685 | return 0; | ||
2686 | |||
2687 | case SOUND_PCM_READ_RATE: | ||
2688 | return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p); | ||
2689 | |||
2690 | case SOUND_PCM_READ_CHANNELS: | ||
2691 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_STEREO << CM_CFMT_ADCSHIFT) : (CM_CFMT_STEREO << CM_CFMT_DACSHIFT))) ? 2 : 1, p); | ||
2692 | |||
2693 | case SOUND_PCM_READ_BITS: | ||
2694 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (CM_CFMT_16BIT << CM_CFMT_ADCSHIFT) : (CM_CFMT_16BIT << CM_CFMT_DACSHIFT))) ? 16 : 8, p); | ||
2695 | |||
2696 | case SOUND_PCM_READ_FILTER: | ||
2697 | return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p); | ||
2698 | |||
2699 | case SNDCTL_DSP_GETCHANNELMASK: | ||
2700 | return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE|DSP_BIND_SPDIF, p); | ||
2701 | |||
2702 | case SNDCTL_DSP_BIND_CHANNEL: | ||
2703 | if (get_user(val, p)) | ||
2704 | return -EFAULT; | ||
2705 | if (val == DSP_BIND_QUERY) { | ||
2706 | val = DSP_BIND_FRONT; | ||
2707 | if (s->status & DO_SPDIF_OUT) | ||
2708 | val |= DSP_BIND_SPDIF; | ||
2709 | else { | ||
2710 | if (s->curr_channels == 4) | ||
2711 | val |= DSP_BIND_SURR; | ||
2712 | if (s->curr_channels > 4) | ||
2713 | val |= DSP_BIND_CENTER_LFE; | ||
2714 | } | ||
2715 | } else { | ||
2716 | if (file->f_mode & FMODE_READ) { | ||
2717 | stop_adc(s); | ||
2718 | s->dma_adc.ready = 0; | ||
2719 | if (val & DSP_BIND_SPDIF) { | ||
2720 | set_spdifin(s, s->rateadc); | ||
2721 | if (!(s->status & DO_SPDIF_OUT)) | ||
2722 | val &= ~DSP_BIND_SPDIF; | ||
2723 | } | ||
2724 | } | ||
2725 | if (file->f_mode & FMODE_WRITE) { | ||
2726 | stop_dac(s); | ||
2727 | s->dma_dac.ready = 0; | ||
2728 | if (val & DSP_BIND_SPDIF) { | ||
2729 | set_spdifout(s, s->ratedac); | ||
2730 | set_dac_channels(s, s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1); | ||
2731 | if (!(s->status & DO_SPDIF_OUT)) | ||
2732 | val &= ~DSP_BIND_SPDIF; | ||
2733 | } else { | ||
2734 | int channels; | ||
2735 | int mask; | ||
2736 | |||
2737 | mask = val & (DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE); | ||
2738 | switch (mask) { | ||
2739 | case DSP_BIND_FRONT: | ||
2740 | channels = 2; | ||
2741 | break; | ||
2742 | case DSP_BIND_FRONT|DSP_BIND_SURR: | ||
2743 | channels = 4; | ||
2744 | break; | ||
2745 | case DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE: | ||
2746 | channels = 6; | ||
2747 | break; | ||
2748 | default: | ||
2749 | channels = s->fmt & (CM_CFMT_STEREO << CM_CFMT_DACSHIFT) ? 2 : 1; | ||
2750 | break; | ||
2751 | } | ||
2752 | set_dac_channels(s, channels); | ||
2753 | } | ||
2754 | } | ||
2755 | } | ||
2756 | return put_user(val, p); | ||
2757 | |||
2758 | case SOUND_PCM_WRITE_FILTER: | ||
2759 | case SNDCTL_DSP_MAPINBUF: | ||
2760 | case SNDCTL_DSP_MAPOUTBUF: | ||
2761 | case SNDCTL_DSP_SETSYNCRO: | ||
2762 | return -EINVAL; | ||
2763 | case SNDCTL_SPDIF_COPYRIGHT: | ||
2764 | if (get_user(val, p)) | ||
2765 | return -EFAULT; | ||
2766 | set_spdif_copyright(s, val); | ||
2767 | return 0; | ||
2768 | case SNDCTL_SPDIF_LOOP: | ||
2769 | if (get_user(val, p)) | ||
2770 | return -EFAULT; | ||
2771 | set_spdif_loop(s, val); | ||
2772 | return 0; | ||
2773 | case SNDCTL_SPDIF_MONITOR: | ||
2774 | if (get_user(val, p)) | ||
2775 | return -EFAULT; | ||
2776 | set_spdif_monitor(s, val); | ||
2777 | return 0; | ||
2778 | case SNDCTL_SPDIF_LEVEL: | ||
2779 | if (get_user(val, p)) | ||
2780 | return -EFAULT; | ||
2781 | set_spdifout_level(s, val); | ||
2782 | return 0; | ||
2783 | case SNDCTL_SPDIF_INV: | ||
2784 | if (get_user(val, p)) | ||
2785 | return -EFAULT; | ||
2786 | set_spdifin_inverse(s, val); | ||
2787 | return 0; | ||
2788 | case SNDCTL_SPDIF_SEL2: | ||
2789 | if (get_user(val, p)) | ||
2790 | return -EFAULT; | ||
2791 | set_spdifin_channel2(s, val); | ||
2792 | return 0; | ||
2793 | case SNDCTL_SPDIF_VALID: | ||
2794 | if (get_user(val, p)) | ||
2795 | return -EFAULT; | ||
2796 | set_spdifin_valid(s, val); | ||
2797 | return 0; | ||
2798 | case SNDCTL_SPDIFOUT: | ||
2799 | if (get_user(val, p)) | ||
2800 | return -EFAULT; | ||
2801 | set_spdifout(s, val ? s->ratedac : 0); | ||
2802 | return 0; | ||
2803 | case SNDCTL_SPDIFIN: | ||
2804 | if (get_user(val, p)) | ||
2805 | return -EFAULT; | ||
2806 | set_spdifin(s, val ? s->rateadc : 0); | ||
2807 | return 0; | ||
2808 | } | ||
2809 | return mixer_ioctl(s, cmd, arg); | ||
2810 | } | ||
2811 | |||
2812 | static int cm_open(struct inode *inode, struct file *file) | ||
2813 | { | ||
2814 | int minor = iminor(inode); | ||
2815 | DECLARE_WAITQUEUE(wait, current); | ||
2816 | unsigned char fmtm = ~0, fmts = 0; | ||
2817 | struct list_head *list; | ||
2818 | struct cm_state *s; | ||
2819 | |||
2820 | for (list = devs.next; ; list = list->next) { | ||
2821 | if (list == &devs) | ||
2822 | return -ENODEV; | ||
2823 | s = list_entry(list, struct cm_state, devs); | ||
2824 | if (!((s->dev_audio ^ minor) & ~0xf)) | ||
2825 | break; | ||
2826 | } | ||
2827 | VALIDATE_STATE(s); | ||
2828 | file->private_data = s; | ||
2829 | /* wait for device to become free */ | ||
2830 | mutex_lock(&s->open_mutex); | ||
2831 | while (s->open_mode & file->f_mode) { | ||
2832 | if (file->f_flags & O_NONBLOCK) { | ||
2833 | mutex_unlock(&s->open_mutex); | ||
2834 | return -EBUSY; | ||
2835 | } | ||
2836 | add_wait_queue(&s->open_wait, &wait); | ||
2837 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2838 | mutex_unlock(&s->open_mutex); | ||
2839 | schedule(); | ||
2840 | remove_wait_queue(&s->open_wait, &wait); | ||
2841 | set_current_state(TASK_RUNNING); | ||
2842 | if (signal_pending(current)) | ||
2843 | return -ERESTARTSYS; | ||
2844 | mutex_lock(&s->open_mutex); | ||
2845 | } | ||
2846 | if (file->f_mode & FMODE_READ) { | ||
2847 | s->status &= ~DO_BIGENDIAN_R; | ||
2848 | fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_ADCSHIFT); | ||
2849 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
2850 | fmts |= CM_CFMT_16BIT << CM_CFMT_ADCSHIFT; | ||
2851 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; | ||
2852 | s->dma_adc.enabled = 1; | ||
2853 | set_adc_rate(s, 8000); | ||
2854 | // spdif-in is turnned off by default | ||
2855 | set_spdifin(s, 0); | ||
2856 | } | ||
2857 | if (file->f_mode & FMODE_WRITE) { | ||
2858 | s->status &= ~DO_BIGENDIAN_W; | ||
2859 | fmtm &= ~((CM_CFMT_STEREO | CM_CFMT_16BIT) << CM_CFMT_DACSHIFT); | ||
2860 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
2861 | fmts |= CM_CFMT_16BIT << CM_CFMT_DACSHIFT; | ||
2862 | s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; | ||
2863 | s->dma_dac.enabled = 1; | ||
2864 | set_dac_rate(s, 8000); | ||
2865 | // clear previous multichannel, spdif, ac3 state | ||
2866 | set_spdifout(s, 0); | ||
2867 | set_ac3(s, 0); | ||
2868 | set_dac_channels(s, 1); | ||
2869 | } | ||
2870 | set_fmt(s, fmtm, fmts); | ||
2871 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
2872 | mutex_unlock(&s->open_mutex); | ||
2873 | return nonseekable_open(inode, file); | ||
2874 | } | ||
2875 | |||
2876 | static int cm_release(struct inode *inode, struct file *file) | ||
2877 | { | ||
2878 | struct cm_state *s = (struct cm_state *)file->private_data; | ||
2879 | |||
2880 | VALIDATE_STATE(s); | ||
2881 | lock_kernel(); | ||
2882 | if (file->f_mode & FMODE_WRITE) | ||
2883 | drain_dac(s, file->f_flags & O_NONBLOCK); | ||
2884 | mutex_lock(&s->open_mutex); | ||
2885 | if (file->f_mode & FMODE_WRITE) { | ||
2886 | stop_dac(s); | ||
2887 | |||
2888 | dealloc_dmabuf(s, &s->dma_dac); | ||
2889 | if (s->status & DO_DUAL_DAC) | ||
2890 | dealloc_dmabuf(s, &s->dma_adc); | ||
2891 | |||
2892 | if (s->status & DO_MULTI_CH) | ||
2893 | set_dac_channels(s, 1); | ||
2894 | if (s->status & DO_AC3) | ||
2895 | set_ac3(s, 0); | ||
2896 | if (s->status & DO_SPDIF_OUT) | ||
2897 | set_spdifout(s, 0); | ||
2898 | /* enable SPDIF loop */ | ||
2899 | set_spdif_loop(s, spdif_loop); | ||
2900 | s->status &= ~DO_BIGENDIAN_W; | ||
2901 | } | ||
2902 | if (file->f_mode & FMODE_READ) { | ||
2903 | stop_adc(s); | ||
2904 | dealloc_dmabuf(s, &s->dma_adc); | ||
2905 | s->status &= ~DO_BIGENDIAN_R; | ||
2906 | } | ||
2907 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); | ||
2908 | mutex_unlock(&s->open_mutex); | ||
2909 | wake_up(&s->open_wait); | ||
2910 | unlock_kernel(); | ||
2911 | return 0; | ||
2912 | } | ||
2913 | |||
2914 | static /*const*/ struct file_operations cm_audio_fops = { | ||
2915 | .owner = THIS_MODULE, | ||
2916 | .llseek = no_llseek, | ||
2917 | .read = cm_read, | ||
2918 | .write = cm_write, | ||
2919 | .poll = cm_poll, | ||
2920 | .ioctl = cm_ioctl, | ||
2921 | .mmap = cm_mmap, | ||
2922 | .open = cm_open, | ||
2923 | .release = cm_release, | ||
2924 | }; | ||
2925 | |||
2926 | /* --------------------------------------------------------------------- */ | ||
2927 | |||
2928 | static struct initvol { | ||
2929 | int mixch; | ||
2930 | int vol; | ||
2931 | } initvol[] __devinitdata = { | ||
2932 | { SOUND_MIXER_WRITE_CD, 0x4f4f }, | ||
2933 | { SOUND_MIXER_WRITE_LINE, 0x4f4f }, | ||
2934 | { SOUND_MIXER_WRITE_MIC, 0x4f4f }, | ||
2935 | { SOUND_MIXER_WRITE_SYNTH, 0x4f4f }, | ||
2936 | { SOUND_MIXER_WRITE_VOLUME, 0x4f4f }, | ||
2937 | { SOUND_MIXER_WRITE_PCM, 0x4f4f } | ||
2938 | }; | ||
2939 | |||
2940 | /* check chip version and capability */ | ||
2941 | static int query_chip(struct cm_state *s) | ||
2942 | { | ||
2943 | int ChipVersion = -1; | ||
2944 | unsigned char RegValue; | ||
2945 | |||
2946 | // check reg 0Ch, bit 24-31 | ||
2947 | RegValue = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 3); | ||
2948 | if (RegValue == 0) { | ||
2949 | // check reg 08h, bit 24-28 | ||
2950 | RegValue = inb(s->iobase + CODEC_CMI_CHFORMAT + 3); | ||
2951 | RegValue &= 0x1f; | ||
2952 | if (RegValue == 0) { | ||
2953 | ChipVersion = 33; | ||
2954 | s->max_channels = 4; | ||
2955 | s->capability |= CAN_AC3_SW; | ||
2956 | s->capability |= CAN_DUAL_DAC; | ||
2957 | } else { | ||
2958 | ChipVersion = 37; | ||
2959 | s->max_channels = 4; | ||
2960 | s->capability |= CAN_AC3_HW; | ||
2961 | s->capability |= CAN_DUAL_DAC; | ||
2962 | } | ||
2963 | } else { | ||
2964 | // check reg 0Ch, bit 26 | ||
2965 | if (RegValue & (1 << (26-24))) { | ||
2966 | ChipVersion = 39; | ||
2967 | if (RegValue & (1 << (24-24))) | ||
2968 | s->max_channels = 6; | ||
2969 | else | ||
2970 | s->max_channels = 4; | ||
2971 | s->capability |= CAN_AC3_HW; | ||
2972 | s->capability |= CAN_DUAL_DAC; | ||
2973 | s->capability |= CAN_MULTI_CH_HW; | ||
2974 | s->capability |= CAN_LINE_AS_BASS; | ||
2975 | s->capability |= CAN_MIC_AS_BASS; | ||
2976 | } else { | ||
2977 | ChipVersion = 55; // 4 or 6 channels | ||
2978 | s->max_channels = 6; | ||
2979 | s->capability |= CAN_AC3_HW; | ||
2980 | s->capability |= CAN_DUAL_DAC; | ||
2981 | s->capability |= CAN_MULTI_CH_HW; | ||
2982 | s->capability |= CAN_LINE_AS_BASS; | ||
2983 | s->capability |= CAN_MIC_AS_BASS; | ||
2984 | } | ||
2985 | } | ||
2986 | s->capability |= CAN_LINE_AS_REAR; | ||
2987 | return ChipVersion; | ||
2988 | } | ||
2989 | |||
2990 | #ifdef CONFIG_SOUND_CMPCI_JOYSTICK | ||
2991 | static int __devinit cm_create_gameport(struct cm_state *s, int io_port) | ||
2992 | { | ||
2993 | struct gameport *gp; | ||
2994 | |||
2995 | if (!request_region(io_port, CM_EXTENT_GAME, "cmpci GAME")) { | ||
2996 | printk(KERN_ERR "cmpci: gameport io ports 0x%#x in use\n", io_port); | ||
2997 | return -EBUSY; | ||
2998 | } | ||
2999 | |||
3000 | if (!(s->gameport = gp = gameport_allocate_port())) { | ||
3001 | printk(KERN_ERR "cmpci: can not allocate memory for gameport\n"); | ||
3002 | release_region(io_port, CM_EXTENT_GAME); | ||
3003 | return -ENOMEM; | ||
3004 | } | ||
3005 | |||
3006 | gameport_set_name(gp, "C-Media GP"); | ||
3007 | gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev)); | ||
3008 | gp->dev.parent = &s->dev->dev; | ||
3009 | gp->io = io_port; | ||
3010 | |||
3011 | /* enable joystick */ | ||
3012 | maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x02); | ||
3013 | |||
3014 | gameport_register_port(gp); | ||
3015 | |||
3016 | return 0; | ||
3017 | } | ||
3018 | |||
3019 | static void __devexit cm_free_gameport(struct cm_state *s) | ||
3020 | { | ||
3021 | if (s->gameport) { | ||
3022 | int gpio = s->gameport->io; | ||
3023 | |||
3024 | gameport_unregister_port(s->gameport); | ||
3025 | s->gameport = NULL; | ||
3026 | maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0); | ||
3027 | release_region(gpio, CM_EXTENT_GAME); | ||
3028 | } | ||
3029 | } | ||
3030 | #else | ||
3031 | static inline int cm_create_gameport(struct cm_state *s, int io_port) { return -ENOSYS; } | ||
3032 | static inline void cm_free_gameport(struct cm_state *s) { } | ||
3033 | #endif | ||
3034 | |||
3035 | #define echo_option(x)\ | ||
3036 | if (x) strcat(options, "" #x " ") | ||
3037 | |||
3038 | static int __devinit cm_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) | ||
3039 | { | ||
3040 | struct cm_state *s; | ||
3041 | mm_segment_t fs; | ||
3042 | int i, val, ret; | ||
3043 | unsigned char reg_mask; | ||
3044 | int timeout; | ||
3045 | struct resource *ports; | ||
3046 | struct { | ||
3047 | unsigned short deviceid; | ||
3048 | char *devicename; | ||
3049 | } devicetable[] = { | ||
3050 | { PCI_DEVICE_ID_CMEDIA_CM8338A, "CM8338A" }, | ||
3051 | { PCI_DEVICE_ID_CMEDIA_CM8338B, "CM8338B" }, | ||
3052 | { PCI_DEVICE_ID_CMEDIA_CM8738, "CM8738" }, | ||
3053 | { PCI_DEVICE_ID_CMEDIA_CM8738B, "CM8738B" }, | ||
3054 | }; | ||
3055 | char *devicename = "unknown"; | ||
3056 | char options[256]; | ||
3057 | |||
3058 | if ((ret = pci_enable_device(pcidev))) | ||
3059 | return ret; | ||
3060 | if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO)) | ||
3061 | return -ENODEV; | ||
3062 | if (pcidev->irq == 0) | ||
3063 | return -ENODEV; | ||
3064 | i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK); | ||
3065 | if (i) { | ||
3066 | printk(KERN_WARNING "cmpci: architecture does not support 32bit PCI busmaster DMA\n"); | ||
3067 | return i; | ||
3068 | } | ||
3069 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
3070 | if (!s) { | ||
3071 | printk(KERN_WARNING "cmpci: out of memory\n"); | ||
3072 | return -ENOMEM; | ||
3073 | } | ||
3074 | /* search device name */ | ||
3075 | for (i = 0; i < sizeof(devicetable) / sizeof(devicetable[0]); i++) { | ||
3076 | if (devicetable[i].deviceid == pcidev->device) { | ||
3077 | devicename = devicetable[i].devicename; | ||
3078 | break; | ||
3079 | } | ||
3080 | } | ||
3081 | memset(s, 0, sizeof(struct cm_state)); | ||
3082 | init_waitqueue_head(&s->dma_adc.wait); | ||
3083 | init_waitqueue_head(&s->dma_dac.wait); | ||
3084 | init_waitqueue_head(&s->open_wait); | ||
3085 | mutex_init(&s->open_mutex); | ||
3086 | spin_lock_init(&s->lock); | ||
3087 | s->magic = CM_MAGIC; | ||
3088 | s->dev = pcidev; | ||
3089 | s->iobase = pci_resource_start(pcidev, 0); | ||
3090 | s->iosynth = fmio; | ||
3091 | s->iomidi = mpuio; | ||
3092 | #ifdef CONFIG_SOUND_CMPCI_MIDI | ||
3093 | s->midi_devc = 0; | ||
3094 | #endif | ||
3095 | s->status = 0; | ||
3096 | if (s->iobase == 0) | ||
3097 | return -ENODEV; | ||
3098 | s->irq = pcidev->irq; | ||
3099 | |||
3100 | if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) { | ||
3101 | printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1); | ||
3102 | ret = -EBUSY; | ||
3103 | goto err_region5; | ||
3104 | } | ||
3105 | /* dump parameters */ | ||
3106 | strcpy(options, "cmpci: "); | ||
3107 | echo_option(joystick); | ||
3108 | echo_option(spdif_inverse); | ||
3109 | echo_option(spdif_loop); | ||
3110 | echo_option(spdif_out); | ||
3111 | echo_option(use_line_as_rear); | ||
3112 | echo_option(use_line_as_bass); | ||
3113 | echo_option(use_mic_as_bass); | ||
3114 | echo_option(mic_boost); | ||
3115 | echo_option(hw_copy); | ||
3116 | printk(KERN_INFO "%s\n", options); | ||
3117 | |||
3118 | /* initialize codec registers */ | ||
3119 | outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2); /* disable ints */ | ||
3120 | outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */ | ||
3121 | /* reset mixer */ | ||
3122 | wrmixer(s, DSP_MIX_DATARESETIDX, 0); | ||
3123 | |||
3124 | /* request irq */ | ||
3125 | if ((ret = request_irq(s->irq, cm_interrupt, IRQF_SHARED, "cmpci", s))) { | ||
3126 | printk(KERN_ERR "cmpci: irq %u in use\n", s->irq); | ||
3127 | goto err_irq; | ||
3128 | } | ||
3129 | printk(KERN_INFO "cmpci: found %s adapter at io %#x irq %u\n", | ||
3130 | devicename, s->iobase, s->irq); | ||
3131 | /* register devices */ | ||
3132 | if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0) { | ||
3133 | ret = s->dev_audio; | ||
3134 | goto err_dev1; | ||
3135 | } | ||
3136 | if ((s->dev_mixer = register_sound_mixer(&cm_mixer_fops, -1)) < 0) { | ||
3137 | ret = s->dev_mixer; | ||
3138 | goto err_dev2; | ||
3139 | } | ||
3140 | pci_set_master(pcidev); /* enable bus mastering */ | ||
3141 | /* initialize the chips */ | ||
3142 | fs = get_fs(); | ||
3143 | set_fs(KERNEL_DS); | ||
3144 | /* set mixer output */ | ||
3145 | frobindir(s, DSP_MIX_OUTMIXIDX, 0x1f, 0x1f); | ||
3146 | /* set mixer input */ | ||
3147 | val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD|SOUND_MASK_MIC; | ||
3148 | mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); | ||
3149 | for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) { | ||
3150 | val = initvol[i].vol; | ||
3151 | mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); | ||
3152 | } | ||
3153 | set_fs(fs); | ||
3154 | /* use channel 1 for playback, channel 0 for record */ | ||
3155 | maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~CHADC1, CHADC0); | ||
3156 | /* turn off VMIC3 - mic boost */ | ||
3157 | if (mic_boost) | ||
3158 | maskb(s->iobase + CODEC_CMI_MIXER2, ~1, 0); | ||
3159 | else | ||
3160 | maskb(s->iobase + CODEC_CMI_MIXER2, ~0, 1); | ||
3161 | s->deviceid = pcidev->device; | ||
3162 | |||
3163 | if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738 | ||
3164 | || pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738B) { | ||
3165 | |||
3166 | /* chip version and hw capability check */ | ||
3167 | s->chip_version = query_chip(s); | ||
3168 | printk(KERN_INFO "cmpci: chip version = 0%d\n", s->chip_version); | ||
3169 | |||
3170 | /* set SPDIF-in inverse before enable SPDIF loop */ | ||
3171 | set_spdifin_inverse(s, spdif_inverse); | ||
3172 | |||
3173 | /* use SPDIF in #1 */ | ||
3174 | set_spdifin_channel2(s, 0); | ||
3175 | } else { | ||
3176 | s->chip_version = 0; | ||
3177 | /* 8338 will fall here */ | ||
3178 | s->max_channels = 4; | ||
3179 | s->capability |= CAN_DUAL_DAC; | ||
3180 | s->capability |= CAN_LINE_AS_REAR; | ||
3181 | } | ||
3182 | /* enable SPDIF loop */ | ||
3183 | set_spdif_loop(s, spdif_loop); | ||
3184 | |||
3185 | // enable 4 speaker mode (analog duplicate) | ||
3186 | set_hw_copy(s, hw_copy); | ||
3187 | |||
3188 | reg_mask = 0; | ||
3189 | #ifdef CONFIG_SOUND_CMPCI_FM | ||
3190 | /* disable FM */ | ||
3191 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0); | ||
3192 | if (s->iosynth) { | ||
3193 | /* don't enable OPL3 if there is one */ | ||
3194 | if (opl3_detect(s->iosynth, NULL)) { | ||
3195 | s->iosynth = 0; | ||
3196 | } else { | ||
3197 | /* set IO based at 0x388 */ | ||
3198 | switch (s->iosynth) { | ||
3199 | case 0x388: | ||
3200 | reg_mask = 0; | ||
3201 | break; | ||
3202 | case 0x3C8: | ||
3203 | reg_mask = 0x01; | ||
3204 | break; | ||
3205 | case 0x3E0: | ||
3206 | reg_mask = 0x02; | ||
3207 | break; | ||
3208 | case 0x3E8: | ||
3209 | reg_mask = 0x03; | ||
3210 | break; | ||
3211 | default: | ||
3212 | s->iosynth = 0; | ||
3213 | break; | ||
3214 | } | ||
3215 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x03, reg_mask); | ||
3216 | /* enable FM */ | ||
3217 | if (s->iosynth) { | ||
3218 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~0, 8); | ||
3219 | if (opl3_detect(s->iosynth, NULL)) | ||
3220 | ret = opl3_init(s->iosynth, NULL, THIS_MODULE); | ||
3221 | else { | ||
3222 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0); | ||
3223 | s->iosynth = 0; | ||
3224 | } | ||
3225 | } | ||
3226 | } | ||
3227 | } | ||
3228 | #endif | ||
3229 | #ifdef CONFIG_SOUND_CMPCI_MIDI | ||
3230 | switch (s->iomidi) { | ||
3231 | case 0x330: | ||
3232 | reg_mask = 0; | ||
3233 | break; | ||
3234 | case 0x320: | ||
3235 | reg_mask = 0x20; | ||
3236 | break; | ||
3237 | case 0x310: | ||
3238 | reg_mask = 0x40; | ||
3239 | break; | ||
3240 | case 0x300: | ||
3241 | reg_mask = 0x60; | ||
3242 | break; | ||
3243 | default: | ||
3244 | s->iomidi = 0; | ||
3245 | goto skip_mpu; | ||
3246 | } | ||
3247 | ports = request_region(s->iomidi, 2, "mpu401"); | ||
3248 | if (!ports) | ||
3249 | goto skip_mpu; | ||
3250 | /* disable MPU-401 */ | ||
3251 | maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0); | ||
3252 | s->mpu_data.name = "cmpci mpu"; | ||
3253 | s->mpu_data.io_base = s->iomidi; | ||
3254 | s->mpu_data.irq = -s->irq; // tell mpu401 to share irq | ||
3255 | if (probe_mpu401(&s->mpu_data, ports)) { | ||
3256 | release_region(s->iomidi, 2); | ||
3257 | s->iomidi = 0; | ||
3258 | goto skip_mpu; | ||
3259 | } | ||
3260 | maskb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3, ~0x60, reg_mask); | ||
3261 | /* enable MPU-401 */ | ||
3262 | maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04); | ||
3263 | /* clear all previously received interrupt */ | ||
3264 | for (timeout = 900000; timeout > 0; timeout--) { | ||
3265 | if ((inb(s->iomidi + 1) && 0x80) == 0) | ||
3266 | inb(s->iomidi); | ||
3267 | else | ||
3268 | break; | ||
3269 | } | ||
3270 | if (!probe_mpu401(&s->mpu_data, ports)) { | ||
3271 | release_region(s->iomidi, 2); | ||
3272 | s->iomidi = 0; | ||
3273 | maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x04); | ||
3274 | } else { | ||
3275 | attach_mpu401(&s->mpu_data, THIS_MODULE); | ||
3276 | s->midi_devc = s->mpu_data.slots[1]; | ||
3277 | } | ||
3278 | skip_mpu: | ||
3279 | #endif | ||
3280 | /* disable joystick port */ | ||
3281 | maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0); | ||
3282 | if (joystick) | ||
3283 | cm_create_gameport(s, 0x200); | ||
3284 | |||
3285 | /* store it in the driver field */ | ||
3286 | pci_set_drvdata(pcidev, s); | ||
3287 | /* put it into driver list */ | ||
3288 | list_add_tail(&s->devs, &devs); | ||
3289 | /* increment devindex */ | ||
3290 | if (devindex < NR_DEVICE-1) | ||
3291 | devindex++; | ||
3292 | return 0; | ||
3293 | |||
3294 | err_dev2: | ||
3295 | unregister_sound_dsp(s->dev_audio); | ||
3296 | err_dev1: | ||
3297 | printk(KERN_ERR "cmpci: cannot register misc device\n"); | ||
3298 | free_irq(s->irq, s); | ||
3299 | err_irq: | ||
3300 | release_region(s->iobase, CM_EXTENT_CODEC); | ||
3301 | err_region5: | ||
3302 | kfree(s); | ||
3303 | return ret; | ||
3304 | } | ||
3305 | |||
3306 | /* --------------------------------------------------------------------- */ | ||
3307 | |||
3308 | MODULE_AUTHOR("ChenLi Tien, cltien@cmedia.com.tw"); | ||
3309 | MODULE_DESCRIPTION("CM8x38 Audio Driver"); | ||
3310 | MODULE_LICENSE("GPL"); | ||
3311 | |||
3312 | static void __devexit cm_remove(struct pci_dev *dev) | ||
3313 | { | ||
3314 | struct cm_state *s = pci_get_drvdata(dev); | ||
3315 | |||
3316 | if (!s) | ||
3317 | return; | ||
3318 | |||
3319 | cm_free_gameport(s); | ||
3320 | |||
3321 | #ifdef CONFIG_SOUND_CMPCI_FM | ||
3322 | if (s->iosynth) { | ||
3323 | /* disable FM */ | ||
3324 | maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0); | ||
3325 | } | ||
3326 | #endif | ||
3327 | #ifdef CONFIG_SOUND_CMPCI_MIDI | ||
3328 | if (s->iomidi) { | ||
3329 | unload_mpu401(&s->mpu_data); | ||
3330 | /* disable MPU-401 */ | ||
3331 | maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0); | ||
3332 | } | ||
3333 | #endif | ||
3334 | set_spdif_loop(s, 0); | ||
3335 | list_del(&s->devs); | ||
3336 | outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2); /* disable ints */ | ||
3337 | synchronize_irq(s->irq); | ||
3338 | outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */ | ||
3339 | free_irq(s->irq, s); | ||
3340 | |||
3341 | /* reset mixer */ | ||
3342 | wrmixer(s, DSP_MIX_DATARESETIDX, 0); | ||
3343 | |||
3344 | release_region(s->iobase, CM_EXTENT_CODEC); | ||
3345 | unregister_sound_dsp(s->dev_audio); | ||
3346 | unregister_sound_mixer(s->dev_mixer); | ||
3347 | kfree(s); | ||
3348 | pci_set_drvdata(dev, NULL); | ||
3349 | } | ||
3350 | |||
3351 | static struct pci_device_id id_table[] __devinitdata = { | ||
3352 | { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
3353 | { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
3354 | { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
3355 | { PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
3356 | { 0, } | ||
3357 | }; | ||
3358 | |||
3359 | MODULE_DEVICE_TABLE(pci, id_table); | ||
3360 | |||
3361 | static struct pci_driver cm_driver = { | ||
3362 | .name = "cmpci", | ||
3363 | .id_table = id_table, | ||
3364 | .probe = cm_probe, | ||
3365 | .remove = __devexit_p(cm_remove) | ||
3366 | }; | ||
3367 | |||
3368 | static int __init init_cmpci(void) | ||
3369 | { | ||
3370 | printk(KERN_INFO "cmpci: version $Revision: 6.82 $ time " __TIME__ " " __DATE__ "\n"); | ||
3371 | return pci_register_driver(&cm_driver); | ||
3372 | } | ||
3373 | |||
3374 | static void __exit cleanup_cmpci(void) | ||
3375 | { | ||
3376 | printk(KERN_INFO "cmpci: unloading\n"); | ||
3377 | pci_unregister_driver(&cm_driver); | ||
3378 | } | ||
3379 | |||
3380 | module_init(init_cmpci); | ||
3381 | module_exit(cleanup_cmpci); | ||
diff --git a/sound/oss/cs4281/Makefile b/sound/oss/cs4281/Makefile deleted file mode 100644 index 6d527e8530d6..000000000000 --- a/sound/oss/cs4281/Makefile +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | # Makefile for Cirrus Logic-Crystal CS4281 | ||
2 | # | ||
3 | |||
4 | obj-$(CONFIG_SOUND_CS4281) += cs4281.o | ||
5 | |||
6 | cs4281-objs += cs4281m.o | ||
diff --git a/sound/oss/cs4281/cs4281_hwdefs.h b/sound/oss/cs4281/cs4281_hwdefs.h deleted file mode 100644 index 701d595e33f5..000000000000 --- a/sound/oss/cs4281/cs4281_hwdefs.h +++ /dev/null | |||
@@ -1,1234 +0,0 @@ | |||
1 | //**************************************************************************** | ||
2 | // | ||
3 | // HWDEFS.H - Definitions of the registers and data structures used by the | ||
4 | // CS4281 | ||
5 | // | ||
6 | // Copyright (c) 1999,2000,2001 Crystal Semiconductor Corp. | ||
7 | // | ||
8 | //**************************************************************************** | ||
9 | |||
10 | #ifndef _H_HWDEFS | ||
11 | #define _H_HWDEFS | ||
12 | |||
13 | //**************************************************************************** | ||
14 | // | ||
15 | // The following define the offsets of the registers located in the PCI | ||
16 | // configuration space of the CS4281 part. | ||
17 | // | ||
18 | //**************************************************************************** | ||
19 | #define PCICONFIG_DEVID_VENID 0x00000000L | ||
20 | #define PCICONFIG_STATUS_COMMAND 0x00000004L | ||
21 | #define PCICONFIG_CLASS_REVISION 0x00000008L | ||
22 | #define PCICONFIG_LATENCY_TIMER 0x0000000CL | ||
23 | #define PCICONFIG_BA0 0x00000010L | ||
24 | #define PCICONFIG_BA1 0x00000014L | ||
25 | #define PCICONFIG_SUBSYSID_SUBSYSVENID 0x0000002CL | ||
26 | #define PCICONFIG_INTERRUPT 0x0000003CL | ||
27 | |||
28 | //**************************************************************************** | ||
29 | // | ||
30 | // The following define the offsets of the registers accessed via base address | ||
31 | // register zero on the CS4281 part. | ||
32 | // | ||
33 | //**************************************************************************** | ||
34 | #define BA0_HISR 0x00000000L | ||
35 | #define BA0_HICR 0x00000008L | ||
36 | #define BA0_HIMR 0x0000000CL | ||
37 | #define BA0_IIER 0x00000010L | ||
38 | #define BA0_HDSR0 0x000000F0L | ||
39 | #define BA0_HDSR1 0x000000F4L | ||
40 | #define BA0_HDSR2 0x000000F8L | ||
41 | #define BA0_HDSR3 0x000000FCL | ||
42 | #define BA0_DCA0 0x00000110L | ||
43 | #define BA0_DCC0 0x00000114L | ||
44 | #define BA0_DBA0 0x00000118L | ||
45 | #define BA0_DBC0 0x0000011CL | ||
46 | #define BA0_DCA1 0x00000120L | ||
47 | #define BA0_DCC1 0x00000124L | ||
48 | #define BA0_DBA1 0x00000128L | ||
49 | #define BA0_DBC1 0x0000012CL | ||
50 | #define BA0_DCA2 0x00000130L | ||
51 | #define BA0_DCC2 0x00000134L | ||
52 | #define BA0_DBA2 0x00000138L | ||
53 | #define BA0_DBC2 0x0000013CL | ||
54 | #define BA0_DCA3 0x00000140L | ||
55 | #define BA0_DCC3 0x00000144L | ||
56 | #define BA0_DBA3 0x00000148L | ||
57 | #define BA0_DBC3 0x0000014CL | ||
58 | #define BA0_DMR0 0x00000150L | ||
59 | #define BA0_DCR0 0x00000154L | ||
60 | #define BA0_DMR1 0x00000158L | ||
61 | #define BA0_DCR1 0x0000015CL | ||
62 | #define BA0_DMR2 0x00000160L | ||
63 | #define BA0_DCR2 0x00000164L | ||
64 | #define BA0_DMR3 0x00000168L | ||
65 | #define BA0_DCR3 0x0000016CL | ||
66 | #define BA0_DLMR 0x00000170L | ||
67 | #define BA0_DLSR 0x00000174L | ||
68 | #define BA0_FCR0 0x00000180L | ||
69 | #define BA0_FCR1 0x00000184L | ||
70 | #define BA0_FCR2 0x00000188L | ||
71 | #define BA0_FCR3 0x0000018CL | ||
72 | #define BA0_FPDR0 0x00000190L | ||
73 | #define BA0_FPDR1 0x00000194L | ||
74 | #define BA0_FPDR2 0x00000198L | ||
75 | #define BA0_FPDR3 0x0000019CL | ||
76 | #define BA0_FCHS 0x0000020CL | ||
77 | #define BA0_FSIC0 0x00000210L | ||
78 | #define BA0_FSIC1 0x00000214L | ||
79 | #define BA0_FSIC2 0x00000218L | ||
80 | #define BA0_FSIC3 0x0000021CL | ||
81 | #define BA0_PCICFG00 0x00000300L | ||
82 | #define BA0_PCICFG04 0x00000304L | ||
83 | #define BA0_PCICFG08 0x00000308L | ||
84 | #define BA0_PCICFG0C 0x0000030CL | ||
85 | #define BA0_PCICFG10 0x00000310L | ||
86 | #define BA0_PCICFG14 0x00000314L | ||
87 | #define BA0_PCICFG18 0x00000318L | ||
88 | #define BA0_PCICFG1C 0x0000031CL | ||
89 | #define BA0_PCICFG20 0x00000320L | ||
90 | #define BA0_PCICFG24 0x00000324L | ||
91 | #define BA0_PCICFG28 0x00000328L | ||
92 | #define BA0_PCICFG2C 0x0000032CL | ||
93 | #define BA0_PCICFG30 0x00000330L | ||
94 | #define BA0_PCICFG34 0x00000334L | ||
95 | #define BA0_PCICFG38 0x00000338L | ||
96 | #define BA0_PCICFG3C 0x0000033CL | ||
97 | #define BA0_PCICFG40 0x00000340L | ||
98 | #define BA0_PMCS 0x00000344L | ||
99 | #define BA0_CWPR 0x000003E0L | ||
100 | #define BA0_EPPMC 0x000003E4L | ||
101 | #define BA0_GPIOR 0x000003E8L | ||
102 | #define BA0_SPMC 0x000003ECL | ||
103 | #define BA0_CFLR 0x000003F0L | ||
104 | #define BA0_IISR 0x000003F4L | ||
105 | #define BA0_TMS 0x000003F8L | ||
106 | #define BA0_SSVID 0x000003FCL | ||
107 | #define BA0_CLKCR1 0x00000400L | ||
108 | #define BA0_FRR 0x00000410L | ||
109 | #define BA0_SLT12O 0x0000041CL | ||
110 | #define BA0_SERMC 0x00000420L | ||
111 | #define BA0_SERC1 0x00000428L | ||
112 | #define BA0_SERC2 0x0000042CL | ||
113 | #define BA0_SLT12M 0x0000045CL | ||
114 | #define BA0_ACCTL 0x00000460L | ||
115 | #define BA0_ACSTS 0x00000464L | ||
116 | #define BA0_ACOSV 0x00000468L | ||
117 | #define BA0_ACCAD 0x0000046CL | ||
118 | #define BA0_ACCDA 0x00000470L | ||
119 | #define BA0_ACISV 0x00000474L | ||
120 | #define BA0_ACSAD 0x00000478L | ||
121 | #define BA0_ACSDA 0x0000047CL | ||
122 | #define BA0_JSPT 0x00000480L | ||
123 | #define BA0_JSCTL 0x00000484L | ||
124 | #define BA0_MIDCR 0x00000490L | ||
125 | #define BA0_MIDCMD 0x00000494L | ||
126 | #define BA0_MIDSR 0x00000494L | ||
127 | #define BA0_MIDWP 0x00000498L | ||
128 | #define BA0_MIDRP 0x0000049CL | ||
129 | #define BA0_AODSD1 0x000004A8L | ||
130 | #define BA0_AODSD2 0x000004ACL | ||
131 | #define BA0_CFGI 0x000004B0L | ||
132 | #define BA0_SLT12M2 0x000004DCL | ||
133 | #define BA0_ACSTS2 0x000004E4L | ||
134 | #define BA0_ACISV2 0x000004F4L | ||
135 | #define BA0_ACSAD2 0x000004F8L | ||
136 | #define BA0_ACSDA2 0x000004FCL | ||
137 | #define BA0_IOTGP 0x00000500L | ||
138 | #define BA0_IOTSB 0x00000504L | ||
139 | #define BA0_IOTFM 0x00000508L | ||
140 | #define BA0_IOTDMA 0x0000050CL | ||
141 | #define BA0_IOTAC0 0x00000500L | ||
142 | #define BA0_IOTAC1 0x00000504L | ||
143 | #define BA0_IOTAC2 0x00000508L | ||
144 | #define BA0_IOTAC3 0x0000050CL | ||
145 | #define BA0_IOTPCP 0x0000052CL | ||
146 | #define BA0_IOTCC 0x00000530L | ||
147 | #define BA0_IOTCR 0x0000058CL | ||
148 | #define BA0_PCPRR 0x00000600L | ||
149 | #define BA0_PCPGR 0x00000604L | ||
150 | #define BA0_PCPCR 0x00000608L | ||
151 | #define BA0_PCPCIEN 0x00000608L | ||
152 | #define BA0_SBMAR 0x00000700L | ||
153 | #define BA0_SBMDR 0x00000704L | ||
154 | #define BA0_SBRR 0x00000708L | ||
155 | #define BA0_SBRDP 0x0000070CL | ||
156 | #define BA0_SBWDP 0x00000710L | ||
157 | #define BA0_SBWBS 0x00000710L | ||
158 | #define BA0_SBRBS 0x00000714L | ||
159 | #define BA0_FMSR 0x00000730L | ||
160 | #define BA0_B0AP 0x00000730L | ||
161 | #define BA0_FMDP 0x00000734L | ||
162 | #define BA0_B1AP 0x00000738L | ||
163 | #define BA0_B1DP 0x0000073CL | ||
164 | #define BA0_SSPM 0x00000740L | ||
165 | #define BA0_DACSR 0x00000744L | ||
166 | #define BA0_ADCSR 0x00000748L | ||
167 | #define BA0_SSCR 0x0000074CL | ||
168 | #define BA0_FMLVC 0x00000754L | ||
169 | #define BA0_FMRVC 0x00000758L | ||
170 | #define BA0_SRCSA 0x0000075CL | ||
171 | #define BA0_PPLVC 0x00000760L | ||
172 | #define BA0_PPRVC 0x00000764L | ||
173 | #define BA0_PASR 0x00000768L | ||
174 | #define BA0_CASR 0x0000076CL | ||
175 | |||
176 | //**************************************************************************** | ||
177 | // | ||
178 | // The following define the offsets of the AC97 shadow registers, which appear | ||
179 | // as a virtual extension to the base address register zero memory range. | ||
180 | // | ||
181 | //**************************************************************************** | ||
182 | #define AC97_REG_OFFSET_MASK 0x0000007EL | ||
183 | #define AC97_CODEC_NUMBER_MASK 0x00003000L | ||
184 | |||
185 | #define BA0_AC97_RESET 0x00001000L | ||
186 | #define BA0_AC97_MASTER_VOLUME 0x00001002L | ||
187 | #define BA0_AC97_HEADPHONE_VOLUME 0x00001004L | ||
188 | #define BA0_AC97_MASTER_VOLUME_MONO 0x00001006L | ||
189 | #define BA0_AC97_MASTER_TONE 0x00001008L | ||
190 | #define BA0_AC97_PC_BEEP_VOLUME 0x0000100AL | ||
191 | #define BA0_AC97_PHONE_VOLUME 0x0000100CL | ||
192 | #define BA0_AC97_MIC_VOLUME 0x0000100EL | ||
193 | #define BA0_AC97_LINE_IN_VOLUME 0x00001010L | ||
194 | #define BA0_AC97_CD_VOLUME 0x00001012L | ||
195 | #define BA0_AC97_VIDEO_VOLUME 0x00001014L | ||
196 | #define BA0_AC97_AUX_VOLUME 0x00001016L | ||
197 | #define BA0_AC97_PCM_OUT_VOLUME 0x00001018L | ||
198 | #define BA0_AC97_RECORD_SELECT 0x0000101AL | ||
199 | #define BA0_AC97_RECORD_GAIN 0x0000101CL | ||
200 | #define BA0_AC97_RECORD_GAIN_MIC 0x0000101EL | ||
201 | #define BA0_AC97_GENERAL_PURPOSE 0x00001020L | ||
202 | #define BA0_AC97_3D_CONTROL 0x00001022L | ||
203 | #define BA0_AC97_MODEM_RATE 0x00001024L | ||
204 | #define BA0_AC97_POWERDOWN 0x00001026L | ||
205 | #define BA0_AC97_EXT_AUDIO_ID 0x00001028L | ||
206 | #define BA0_AC97_EXT_AUDIO_POWER 0x0000102AL | ||
207 | #define BA0_AC97_PCM_FRONT_DAC_RATE 0x0000102CL | ||
208 | #define BA0_AC97_PCM_SURR_DAC_RATE 0x0000102EL | ||
209 | #define BA0_AC97_PCM_LFE_DAC_RATE 0x00001030L | ||
210 | #define BA0_AC97_PCM_LR_ADC_RATE 0x00001032L | ||
211 | #define BA0_AC97_MIC_ADC_RATE 0x00001034L | ||
212 | #define BA0_AC97_6CH_VOL_C_LFE 0x00001036L | ||
213 | #define BA0_AC97_6CH_VOL_SURROUND 0x00001038L | ||
214 | #define BA0_AC97_RESERVED_3A 0x0000103AL | ||
215 | #define BA0_AC97_EXT_MODEM_ID 0x0000103CL | ||
216 | #define BA0_AC97_EXT_MODEM_POWER 0x0000103EL | ||
217 | #define BA0_AC97_LINE1_CODEC_RATE 0x00001040L | ||
218 | #define BA0_AC97_LINE2_CODEC_RATE 0x00001042L | ||
219 | #define BA0_AC97_HANDSET_CODEC_RATE 0x00001044L | ||
220 | #define BA0_AC97_LINE1_CODEC_LEVEL 0x00001046L | ||
221 | #define BA0_AC97_LINE2_CODEC_LEVEL 0x00001048L | ||
222 | #define BA0_AC97_HANDSET_CODEC_LEVEL 0x0000104AL | ||
223 | #define BA0_AC97_GPIO_PIN_CONFIG 0x0000104CL | ||
224 | #define BA0_AC97_GPIO_PIN_TYPE 0x0000104EL | ||
225 | #define BA0_AC97_GPIO_PIN_STICKY 0x00001050L | ||
226 | #define BA0_AC97_GPIO_PIN_WAKEUP 0x00001052L | ||
227 | #define BA0_AC97_GPIO_PIN_STATUS 0x00001054L | ||
228 | #define BA0_AC97_MISC_MODEM_AFE_STAT 0x00001056L | ||
229 | #define BA0_AC97_RESERVED_58 0x00001058L | ||
230 | #define BA0_AC97_CRYSTAL_REV_N_FAB_ID 0x0000105AL | ||
231 | #define BA0_AC97_TEST_AND_MISC_CTRL 0x0000105CL | ||
232 | #define BA0_AC97_AC_MODE 0x0000105EL | ||
233 | #define BA0_AC97_MISC_CRYSTAL_CONTROL 0x00001060L | ||
234 | #define BA0_AC97_LINE1_HYPRID_CTRL 0x00001062L | ||
235 | #define BA0_AC97_VENDOR_RESERVED_64 0x00001064L | ||
236 | #define BA0_AC97_VENDOR_RESERVED_66 0x00001066L | ||
237 | #define BA0_AC97_SPDIF_CONTROL 0x00001068L | ||
238 | #define BA0_AC97_VENDOR_RESERVED_6A 0x0000106AL | ||
239 | #define BA0_AC97_VENDOR_RESERVED_6C 0x0000106CL | ||
240 | #define BA0_AC97_VENDOR_RESERVED_6E 0x0000106EL | ||
241 | #define BA0_AC97_VENDOR_RESERVED_70 0x00001070L | ||
242 | #define BA0_AC97_VENDOR_RESERVED_72 0x00001072L | ||
243 | #define BA0_AC97_VENDOR_RESERVED_74 0x00001074L | ||
244 | #define BA0_AC97_CAL_ADDRESS 0x00001076L | ||
245 | #define BA0_AC97_CAL_DATA 0x00001078L | ||
246 | #define BA0_AC97_VENDOR_RESERVED_7A 0x0000107AL | ||
247 | #define BA0_AC97_VENDOR_ID1 0x0000107CL | ||
248 | #define BA0_AC97_VENDOR_ID2 0x0000107EL | ||
249 | |||
250 | //**************************************************************************** | ||
251 | // | ||
252 | // The following define the offsets of the registers and memories accessed via | ||
253 | // base address register one on the CS4281 part. | ||
254 | // | ||
255 | //**************************************************************************** | ||
256 | |||
257 | //**************************************************************************** | ||
258 | // | ||
259 | // The following defines are for the flags in the PCI device ID/vendor ID | ||
260 | // register. | ||
261 | // | ||
262 | //**************************************************************************** | ||
263 | #define PDV_VENID_MASK 0x0000FFFFL | ||
264 | #define PDV_DEVID_MASK 0xFFFF0000L | ||
265 | #define PDV_VENID_SHIFT 0L | ||
266 | #define PDV_DEVID_SHIFT 16L | ||
267 | #define VENID_CIRRUS_LOGIC 0x1013L | ||
268 | #define DEVID_CS4281 0x6005L | ||
269 | |||
270 | //**************************************************************************** | ||
271 | // | ||
272 | // The following defines are for the flags in the PCI status and command | ||
273 | // register. | ||
274 | // | ||
275 | //**************************************************************************** | ||
276 | #define PSC_IO_SPACE_ENABLE 0x00000001L | ||
277 | #define PSC_MEMORY_SPACE_ENABLE 0x00000002L | ||
278 | #define PSC_BUS_MASTER_ENABLE 0x00000004L | ||
279 | #define PSC_SPECIAL_CYCLES 0x00000008L | ||
280 | #define PSC_MWI_ENABLE 0x00000010L | ||
281 | #define PSC_VGA_PALETTE_SNOOP 0x00000020L | ||
282 | #define PSC_PARITY_RESPONSE 0x00000040L | ||
283 | #define PSC_WAIT_CONTROL 0x00000080L | ||
284 | #define PSC_SERR_ENABLE 0x00000100L | ||
285 | #define PSC_FAST_B2B_ENABLE 0x00000200L | ||
286 | #define PSC_UDF_MASK 0x007F0000L | ||
287 | #define PSC_FAST_B2B_CAPABLE 0x00800000L | ||
288 | #define PSC_PARITY_ERROR_DETECTED 0x01000000L | ||
289 | #define PSC_DEVSEL_TIMING_MASK 0x06000000L | ||
290 | #define PSC_TARGET_ABORT_SIGNALLED 0x08000000L | ||
291 | #define PSC_RECEIVED_TARGET_ABORT 0x10000000L | ||
292 | #define PSC_RECEIVED_MASTER_ABORT 0x20000000L | ||
293 | #define PSC_SIGNALLED_SERR 0x40000000L | ||
294 | #define PSC_DETECTED_PARITY_ERROR 0x80000000L | ||
295 | #define PSC_UDF_SHIFT 16L | ||
296 | #define PSC_DEVSEL_TIMING_SHIFT 25L | ||
297 | |||
298 | //**************************************************************************** | ||
299 | // | ||
300 | // The following defines are for the flags in the PCI class/revision ID | ||
301 | // register. | ||
302 | // | ||
303 | //**************************************************************************** | ||
304 | #define PCR_REVID_MASK 0x000000FFL | ||
305 | #define PCR_INTERFACE_MASK 0x0000FF00L | ||
306 | #define PCR_SUBCLASS_MASK 0x00FF0000L | ||
307 | #define PCR_CLASS_MASK 0xFF000000L | ||
308 | #define PCR_REVID_SHIFT 0L | ||
309 | #define PCR_INTERFACE_SHIFT 8L | ||
310 | #define PCR_SUBCLASS_SHIFT 16L | ||
311 | #define PCR_CLASS_SHIFT 24L | ||
312 | |||
313 | //**************************************************************************** | ||
314 | // | ||
315 | // The following defines are for the flags in the PCI latency timer register. | ||
316 | // | ||
317 | //**************************************************************************** | ||
318 | #define PLT_CACHE_LINE_SIZE_MASK 0x000000FFL | ||
319 | #define PLT_LATENCY_TIMER_MASK 0x0000FF00L | ||
320 | #define PLT_HEADER_TYPE_MASK 0x00FF0000L | ||
321 | #define PLT_BIST_MASK 0xFF000000L | ||
322 | #define PLT_CACHE_LINE_SIZE_SHIFT 0L | ||
323 | #define PLT_LATENCY_TIMER_SHIFT 8L | ||
324 | #define PLT_HEADER_TYPE_SHIFT 16L | ||
325 | #define PLT_BIST_SHIFT 24L | ||
326 | |||
327 | //**************************************************************************** | ||
328 | // | ||
329 | // The following defines are for the flags in the PCI base address registers. | ||
330 | // | ||
331 | //**************************************************************************** | ||
332 | #define PBAR_MEMORY_SPACE_INDICATOR 0x00000001L | ||
333 | #define PBAR_LOCATION_TYPE_MASK 0x00000006L | ||
334 | #define PBAR_NOT_PREFETCHABLE 0x00000008L | ||
335 | #define PBAR_ADDRESS_MASK 0xFFFFFFF0L | ||
336 | #define PBAR_LOCATION_TYPE_SHIFT 1L | ||
337 | |||
338 | //**************************************************************************** | ||
339 | // | ||
340 | // The following defines are for the flags in the PCI subsystem ID/subsystem | ||
341 | // vendor ID register. | ||
342 | // | ||
343 | //**************************************************************************** | ||
344 | #define PSS_SUBSYSTEM_VENDOR_ID_MASK 0x0000FFFFL | ||
345 | #define PSS_SUBSYSTEM_ID_MASK 0xFFFF0000L | ||
346 | #define PSS_SUBSYSTEM_VENDOR_ID_SHIFT 0L | ||
347 | #define PSS_SUBSYSTEM_ID_SHIFT 16L | ||
348 | |||
349 | //**************************************************************************** | ||
350 | // | ||
351 | // The following defines are for the flags in the PCI interrupt register. | ||
352 | // | ||
353 | //**************************************************************************** | ||
354 | #define PI_LINE_MASK 0x000000FFL | ||
355 | #define PI_PIN_MASK 0x0000FF00L | ||
356 | #define PI_MIN_GRANT_MASK 0x00FF0000L | ||
357 | #define PI_MAX_LATENCY_MASK 0xFF000000L | ||
358 | #define PI_LINE_SHIFT 0L | ||
359 | #define PI_PIN_SHIFT 8L | ||
360 | #define PI_MIN_GRANT_SHIFT 16L | ||
361 | #define PI_MAX_LATENCY_SHIFT 24L | ||
362 | |||
363 | //**************************************************************************** | ||
364 | // | ||
365 | // The following defines are for the flags in the host interrupt status | ||
366 | // register. | ||
367 | // | ||
368 | //**************************************************************************** | ||
369 | #define HISR_HVOLMASK 0x00000003L | ||
370 | #define HISR_VDNI 0x00000001L | ||
371 | #define HISR_VUPI 0x00000002L | ||
372 | #define HISR_GP1I 0x00000004L | ||
373 | #define HISR_GP3I 0x00000008L | ||
374 | #define HISR_GPSI 0x00000010L | ||
375 | #define HISR_GPPI 0x00000020L | ||
376 | #define HISR_DMAI 0x00040000L | ||
377 | #define HISR_FIFOI 0x00100000L | ||
378 | #define HISR_HVOL 0x00200000L | ||
379 | #define HISR_MIDI 0x00400000L | ||
380 | #define HISR_SBINT 0x00800000L | ||
381 | #define HISR_INTENA 0x80000000L | ||
382 | #define HISR_DMA_MASK 0x00000F00L | ||
383 | #define HISR_FIFO_MASK 0x0000F000L | ||
384 | #define HISR_DMA_SHIFT 8L | ||
385 | #define HISR_FIFO_SHIFT 12L | ||
386 | #define HISR_FIFO0 0x00001000L | ||
387 | #define HISR_FIFO1 0x00002000L | ||
388 | #define HISR_FIFO2 0x00004000L | ||
389 | #define HISR_FIFO3 0x00008000L | ||
390 | #define HISR_DMA0 0x00000100L | ||
391 | #define HISR_DMA1 0x00000200L | ||
392 | #define HISR_DMA2 0x00000400L | ||
393 | #define HISR_DMA3 0x00000800L | ||
394 | #define HISR_RESERVED 0x40000000L | ||
395 | |||
396 | //**************************************************************************** | ||
397 | // | ||
398 | // The following defines are for the flags in the host interrupt control | ||
399 | // register. | ||
400 | // | ||
401 | //**************************************************************************** | ||
402 | #define HICR_IEV 0x00000001L | ||
403 | #define HICR_CHGM 0x00000002L | ||
404 | |||
405 | //**************************************************************************** | ||
406 | // | ||
407 | // The following defines are for the flags in the DMA Mode Register n | ||
408 | // (DMRn) | ||
409 | // | ||
410 | //**************************************************************************** | ||
411 | #define DMRn_TR_MASK 0x0000000CL | ||
412 | #define DMRn_TR_SHIFT 2L | ||
413 | #define DMRn_AUTO 0x00000010L | ||
414 | #define DMRn_TR_READ 0x00000008L | ||
415 | #define DMRn_TR_WRITE 0x00000004L | ||
416 | #define DMRn_TYPE_MASK 0x000000C0L | ||
417 | #define DMRn_TYPE_SHIFT 6L | ||
418 | #define DMRn_SIZE8 0x00010000L | ||
419 | #define DMRn_MONO 0x00020000L | ||
420 | #define DMRn_BEND 0x00040000L | ||
421 | #define DMRn_USIGN 0x00080000L | ||
422 | #define DMRn_SIZE20 0x00100000L | ||
423 | #define DMRn_SWAPC 0x00400000L | ||
424 | #define DMRn_CBC 0x01000000L | ||
425 | #define DMRn_TBC 0x02000000L | ||
426 | #define DMRn_POLL 0x10000000L | ||
427 | #define DMRn_DMA 0x20000000L | ||
428 | #define DMRn_FSEL_MASK 0xC0000000L | ||
429 | #define DMRn_FSEL_SHIFT 30L | ||
430 | #define DMRn_FSEL0 0x00000000L | ||
431 | #define DMRn_FSEL1 0x40000000L | ||
432 | #define DMRn_FSEL2 0x80000000L | ||
433 | #define DMRn_FSEL3 0xC0000000L | ||
434 | |||
435 | //**************************************************************************** | ||
436 | // | ||
437 | // The following defines are for the flags in the DMA Command Register n | ||
438 | // (DCRn) | ||
439 | // | ||
440 | //**************************************************************************** | ||
441 | #define DCRn_HTCIE 0x00020000L | ||
442 | #define DCRn_TCIE 0x00010000L | ||
443 | #define DCRn_MSK 0x00000001L | ||
444 | |||
445 | //**************************************************************************** | ||
446 | // | ||
447 | // The following defines are for the flags in the FIFO Control | ||
448 | // register n.(FCRn) | ||
449 | // | ||
450 | //**************************************************************************** | ||
451 | #define FCRn_OF_MASK 0x0000007FL | ||
452 | #define FCRn_OF_SHIFT 0L | ||
453 | #define FCRn_SZ_MASK 0x00007F00L | ||
454 | #define FCRn_SZ_SHIFT 8L | ||
455 | #define FCRn_LS_MASK 0x001F0000L | ||
456 | #define FCRn_LS_SHIFT 16L | ||
457 | #define FCRn_RS_MASK 0x1F000000L | ||
458 | #define FCRn_RS_SHIFT 24L | ||
459 | #define FCRn_FEN 0x80000000L | ||
460 | #define FCRn_PSH 0x20000000L | ||
461 | #define FCRn_DACZ 0x40000000L | ||
462 | |||
463 | //**************************************************************************** | ||
464 | // | ||
465 | // The following defines are for the flags in the serial port Power Management | ||
466 | // control register.(SPMC) | ||
467 | // | ||
468 | //**************************************************************************** | ||
469 | #define SPMC_RSTN 0x00000001L | ||
470 | #define SPMC_ASYN 0x00000002L | ||
471 | #define SPMC_WUP1 0x00000004L | ||
472 | #define SPMC_WUP2 0x00000008L | ||
473 | #define SPMC_ASDI2E 0x00000100L | ||
474 | #define SPMC_ESSPD 0x00000200L | ||
475 | #define SPMC_GISPEN 0x00004000L | ||
476 | #define SPMC_GIPPEN 0x00008000L | ||
477 | |||
478 | //**************************************************************************** | ||
479 | // | ||
480 | // The following defines are for the flags in the Configuration Load register. | ||
481 | // (CFLR) | ||
482 | // | ||
483 | //**************************************************************************** | ||
484 | #define CFLR_CLOCK_SOURCE_MASK 0x00000003L | ||
485 | #define CFLR_CLOCK_SOURCE_AC97 0x00000001L | ||
486 | |||
487 | #define CFLR_CB0_MASK 0x000000FFL | ||
488 | #define CFLR_CB1_MASK 0x0000FF00L | ||
489 | #define CFLR_CB2_MASK 0x00FF0000L | ||
490 | #define CFLR_CB3_MASK 0xFF000000L | ||
491 | #define CFLR_CB0_SHIFT 0L | ||
492 | #define CFLR_CB1_SHIFT 8L | ||
493 | #define CFLR_CB2_SHIFT 16L | ||
494 | #define CFLR_CB3_SHIFT 24L | ||
495 | |||
496 | #define IOTCR_DMA0 0x00000000L | ||
497 | #define IOTCR_DMA1 0x00000400L | ||
498 | #define IOTCR_DMA2 0x00000800L | ||
499 | #define IOTCR_DMA3 0x00000C00L | ||
500 | #define IOTCR_CCLS 0x00000100L | ||
501 | #define IOTCR_PCPCI 0x00000200L | ||
502 | #define IOTCR_DDMA 0x00000300L | ||
503 | |||
504 | #define SBWBS_WBB 0x00000080L | ||
505 | |||
506 | //**************************************************************************** | ||
507 | // | ||
508 | // The following defines are for the flags in the SRC Slot Assignment Register | ||
509 | // (SRCSA) | ||
510 | // | ||
511 | //**************************************************************************** | ||
512 | #define SRCSA_PLSS_MASK 0x0000001FL | ||
513 | #define SRCSA_PLSS_SHIFT 0L | ||
514 | #define SRCSA_PRSS_MASK 0x00001F00L | ||
515 | #define SRCSA_PRSS_SHIFT 8L | ||
516 | #define SRCSA_CLSS_MASK 0x001F0000L | ||
517 | #define SRCSA_CLSS_SHIFT 16L | ||
518 | #define SRCSA_CRSS_MASK 0x1F000000L | ||
519 | #define SRCSA_CRSS_SHIFT 24L | ||
520 | |||
521 | //**************************************************************************** | ||
522 | // | ||
523 | // The following defines are for the flags in the Sound System Power Management | ||
524 | // register.(SSPM) | ||
525 | // | ||
526 | //**************************************************************************** | ||
527 | #define SSPM_FPDN 0x00000080L | ||
528 | #define SSPM_MIXEN 0x00000040L | ||
529 | #define SSPM_CSRCEN 0x00000020L | ||
530 | #define SSPM_PSRCEN 0x00000010L | ||
531 | #define SSPM_JSEN 0x00000008L | ||
532 | #define SSPM_ACLEN 0x00000004L | ||
533 | #define SSPM_FMEN 0x00000002L | ||
534 | |||
535 | //**************************************************************************** | ||
536 | // | ||
537 | // The following defines are for the flags in the Sound System Control | ||
538 | // Register. (SSCR) | ||
539 | // | ||
540 | //**************************************************************************** | ||
541 | #define SSCR_SB 0x00000004L | ||
542 | #define SSCR_HVC 0x00000008L | ||
543 | #define SSCR_LPFIFO 0x00000040L | ||
544 | #define SSCR_LPSRC 0x00000080L | ||
545 | #define SSCR_XLPSRC 0x00000100L | ||
546 | #define SSCR_MVMD 0x00010000L | ||
547 | #define SSCR_MVAD 0x00020000L | ||
548 | #define SSCR_MVLD 0x00040000L | ||
549 | #define SSCR_MVCS 0x00080000L | ||
550 | |||
551 | //**************************************************************************** | ||
552 | // | ||
553 | // The following defines are for the flags in the Clock Control Register 1. | ||
554 | // (CLKCR1) | ||
555 | // | ||
556 | //**************************************************************************** | ||
557 | #define CLKCR1_DLLSS_MASK 0x0000000CL | ||
558 | #define CLKCR1_DLLSS_SHIFT 2L | ||
559 | #define CLKCR1_DLLP 0x00000010L | ||
560 | #define CLKCR1_SWCE 0x00000020L | ||
561 | #define CLKCR1_DLLOS 0x00000040L | ||
562 | #define CLKCR1_CKRA 0x00010000L | ||
563 | #define CLKCR1_CKRN 0x00020000L | ||
564 | #define CLKCR1_DLLRDY 0x01000000L | ||
565 | #define CLKCR1_CLKON 0x02000000L | ||
566 | |||
567 | //**************************************************************************** | ||
568 | // | ||
569 | // The following defines are for the flags in the Sound Blaster Read Buffer | ||
570 | // Status.(SBRBS) | ||
571 | // | ||
572 | //**************************************************************************** | ||
573 | #define SBRBS_RD_MASK 0x0000007FL | ||
574 | #define SBRBS_RD_SHIFT 0L | ||
575 | #define SBRBS_RBF 0x00000080L | ||
576 | |||
577 | //**************************************************************************** | ||
578 | // | ||
579 | // The following defines are for the flags in the serial port master control | ||
580 | // register.(SERMC) | ||
581 | // | ||
582 | //**************************************************************************** | ||
583 | #define SERMC_MSPE 0x00000001L | ||
584 | #define SERMC_PTC_MASK 0x0000000EL | ||
585 | #define SERMC_PTC_SHIFT 1L | ||
586 | #define SERMC_PTC_AC97 0x00000002L | ||
587 | #define SERMC_PLB 0x00000010L | ||
588 | #define SERMC_PXLB 0x00000020L | ||
589 | #define SERMC_LOFV 0x00080000L | ||
590 | #define SERMC_SLB 0x00100000L | ||
591 | #define SERMC_SXLB 0x00200000L | ||
592 | #define SERMC_ODSEN1 0x01000000L | ||
593 | #define SERMC_ODSEN2 0x02000000L | ||
594 | |||
595 | //**************************************************************************** | ||
596 | // | ||
597 | // The following defines are for the flags in the General Purpose I/O Register. | ||
598 | // (GPIOR) | ||
599 | // | ||
600 | //**************************************************************************** | ||
601 | #define GPIOR_VDNS 0x00000001L | ||
602 | #define GPIOR_VUPS 0x00000002L | ||
603 | #define GPIOR_GP1S 0x00000004L | ||
604 | #define GPIOR_GP3S 0x00000008L | ||
605 | #define GPIOR_GPSS 0x00000010L | ||
606 | #define GPIOR_GPPS 0x00000020L | ||
607 | #define GPIOR_GP1D 0x00000400L | ||
608 | #define GPIOR_GP3D 0x00000800L | ||
609 | #define GPIOR_VDNLT 0x00010000L | ||
610 | #define GPIOR_VDNPO 0x00020000L | ||
611 | #define GPIOR_VDNST 0x00040000L | ||
612 | #define GPIOR_VDNW 0x00080000L | ||
613 | #define GPIOR_VUPLT 0x00100000L | ||
614 | #define GPIOR_VUPPO 0x00200000L | ||
615 | #define GPIOR_VUPST 0x00400000L | ||
616 | #define GPIOR_VUPW 0x00800000L | ||
617 | #define GPIOR_GP1OE 0x01000000L | ||
618 | #define GPIOR_GP1PT 0x02000000L | ||
619 | #define GPIOR_GP1ST 0x04000000L | ||
620 | #define GPIOR_GP1W 0x08000000L | ||
621 | #define GPIOR_GP3OE 0x10000000L | ||
622 | #define GPIOR_GP3PT 0x20000000L | ||
623 | #define GPIOR_GP3ST 0x40000000L | ||
624 | #define GPIOR_GP3W 0x80000000L | ||
625 | |||
626 | //**************************************************************************** | ||
627 | // | ||
628 | // The following defines are for the flags in the clock control register 1. | ||
629 | // | ||
630 | //**************************************************************************** | ||
631 | #define CLKCR1_PLLSS_MASK 0x0000000CL | ||
632 | #define CLKCR1_PLLSS_SERIAL 0x00000000L | ||
633 | #define CLKCR1_PLLSS_CRYSTAL 0x00000004L | ||
634 | #define CLKCR1_PLLSS_PCI 0x00000008L | ||
635 | #define CLKCR1_PLLSS_RESERVED 0x0000000CL | ||
636 | #define CLKCR1_PLLP 0x00000010L | ||
637 | #define CLKCR1_SWCE 0x00000020L | ||
638 | #define CLKCR1_PLLOS 0x00000040L | ||
639 | |||
640 | //**************************************************************************** | ||
641 | // | ||
642 | // The following defines are for the flags in the feature reporting register. | ||
643 | // | ||
644 | //**************************************************************************** | ||
645 | #define FRR_FAB_MASK 0x00000003L | ||
646 | #define FRR_MASK_MASK 0x0000001CL | ||
647 | #define FRR_ID_MASK 0x00003000L | ||
648 | #define FRR_FAB_SHIFT 0L | ||
649 | #define FRR_MASK_SHIFT 2L | ||
650 | #define FRR_ID_SHIFT 12L | ||
651 | |||
652 | //**************************************************************************** | ||
653 | // | ||
654 | // The following defines are for the flags in the serial port 1 configuration | ||
655 | // register. | ||
656 | // | ||
657 | //**************************************************************************** | ||
658 | #define SERC1_VALUE 0x00000003L | ||
659 | #define SERC1_SO1EN 0x00000001L | ||
660 | #define SERC1_SO1F_MASK 0x0000000EL | ||
661 | #define SERC1_SO1F_CS423X 0x00000000L | ||
662 | #define SERC1_SO1F_AC97 0x00000002L | ||
663 | #define SERC1_SO1F_DAC 0x00000004L | ||
664 | #define SERC1_SO1F_SPDIF 0x00000006L | ||
665 | |||
666 | //**************************************************************************** | ||
667 | // | ||
668 | // The following defines are for the flags in the serial port 2 configuration | ||
669 | // register. | ||
670 | // | ||
671 | //**************************************************************************** | ||
672 | #define SERC2_VALUE 0x00000003L | ||
673 | #define SERC2_SI1EN 0x00000001L | ||
674 | #define SERC2_SI1F_MASK 0x0000000EL | ||
675 | #define SERC2_SI1F_CS423X 0x00000000L | ||
676 | #define SERC2_SI1F_AC97 0x00000002L | ||
677 | #define SERC2_SI1F_ADC 0x00000004L | ||
678 | #define SERC2_SI1F_SPDIF 0x00000006L | ||
679 | |||
680 | //**************************************************************************** | ||
681 | // | ||
682 | // The following defines are for the flags in the AC97 control register. | ||
683 | // | ||
684 | //**************************************************************************** | ||
685 | #define ACCTL_ESYN 0x00000002L | ||
686 | #define ACCTL_VFRM 0x00000004L | ||
687 | #define ACCTL_DCV 0x00000008L | ||
688 | #define ACCTL_CRW 0x00000010L | ||
689 | #define ACCTL_TC 0x00000040L | ||
690 | |||
691 | //**************************************************************************** | ||
692 | // | ||
693 | // The following defines are for the flags in the AC97 status register. | ||
694 | // | ||
695 | //**************************************************************************** | ||
696 | #define ACSTS_CRDY 0x00000001L | ||
697 | #define ACSTS_VSTS 0x00000002L | ||
698 | |||
699 | //**************************************************************************** | ||
700 | // | ||
701 | // The following defines are for the flags in the AC97 output slot valid | ||
702 | // register. | ||
703 | // | ||
704 | //**************************************************************************** | ||
705 | #define ACOSV_SLV3 0x00000001L | ||
706 | #define ACOSV_SLV4 0x00000002L | ||
707 | #define ACOSV_SLV5 0x00000004L | ||
708 | #define ACOSV_SLV6 0x00000008L | ||
709 | #define ACOSV_SLV7 0x00000010L | ||
710 | #define ACOSV_SLV8 0x00000020L | ||
711 | #define ACOSV_SLV9 0x00000040L | ||
712 | #define ACOSV_SLV10 0x00000080L | ||
713 | #define ACOSV_SLV11 0x00000100L | ||
714 | #define ACOSV_SLV12 0x00000200L | ||
715 | |||
716 | //**************************************************************************** | ||
717 | // | ||
718 | // The following defines are for the flags in the AC97 command address | ||
719 | // register. | ||
720 | // | ||
721 | //**************************************************************************** | ||
722 | #define ACCAD_CI_MASK 0x0000007FL | ||
723 | #define ACCAD_CI_SHIFT 0L | ||
724 | |||
725 | //**************************************************************************** | ||
726 | // | ||
727 | // The following defines are for the flags in the AC97 command data register. | ||
728 | // | ||
729 | //**************************************************************************** | ||
730 | #define ACCDA_CD_MASK 0x0000FFFFL | ||
731 | #define ACCDA_CD_SHIFT 0L | ||
732 | |||
733 | //**************************************************************************** | ||
734 | // | ||
735 | // The following defines are for the flags in the AC97 input slot valid | ||
736 | // register. | ||
737 | // | ||
738 | //**************************************************************************** | ||
739 | #define ACISV_ISV3 0x00000001L | ||
740 | #define ACISV_ISV4 0x00000002L | ||
741 | #define ACISV_ISV5 0x00000004L | ||
742 | #define ACISV_ISV6 0x00000008L | ||
743 | #define ACISV_ISV7 0x00000010L | ||
744 | #define ACISV_ISV8 0x00000020L | ||
745 | #define ACISV_ISV9 0x00000040L | ||
746 | #define ACISV_ISV10 0x00000080L | ||
747 | #define ACISV_ISV11 0x00000100L | ||
748 | #define ACISV_ISV12 0x00000200L | ||
749 | |||
750 | //**************************************************************************** | ||
751 | // | ||
752 | // The following defines are for the flags in the AC97 status address | ||
753 | // register. | ||
754 | // | ||
755 | //**************************************************************************** | ||
756 | #define ACSAD_SI_MASK 0x0000007FL | ||
757 | #define ACSAD_SI_SHIFT 0L | ||
758 | |||
759 | //**************************************************************************** | ||
760 | // | ||
761 | // The following defines are for the flags in the AC97 status data register. | ||
762 | // | ||
763 | //**************************************************************************** | ||
764 | #define ACSDA_SD_MASK 0x0000FFFFL | ||
765 | #define ACSDA_SD_SHIFT 0L | ||
766 | |||
767 | //**************************************************************************** | ||
768 | // | ||
769 | // The following defines are for the flags in the I/O trap address and control | ||
770 | // registers (all 12). | ||
771 | // | ||
772 | //**************************************************************************** | ||
773 | #define IOTAC_SA_MASK 0x0000FFFFL | ||
774 | #define IOTAC_MSK_MASK 0x000F0000L | ||
775 | #define IOTAC_IODC_MASK 0x06000000L | ||
776 | #define IOTAC_IODC_16_BIT 0x00000000L | ||
777 | #define IOTAC_IODC_10_BIT 0x02000000L | ||
778 | #define IOTAC_IODC_12_BIT 0x04000000L | ||
779 | #define IOTAC_WSPI 0x08000000L | ||
780 | #define IOTAC_RSPI 0x10000000L | ||
781 | #define IOTAC_WSE 0x20000000L | ||
782 | #define IOTAC_WE 0x40000000L | ||
783 | #define IOTAC_RE 0x80000000L | ||
784 | #define IOTAC_SA_SHIFT 0L | ||
785 | #define IOTAC_MSK_SHIFT 16L | ||
786 | |||
787 | //**************************************************************************** | ||
788 | // | ||
789 | // The following defines are for the flags in the PC/PCI master enable | ||
790 | // register. | ||
791 | // | ||
792 | //**************************************************************************** | ||
793 | #define PCPCIEN_EN 0x00000001L | ||
794 | |||
795 | //**************************************************************************** | ||
796 | // | ||
797 | // The following defines are for the flags in the joystick poll/trigger | ||
798 | // register. | ||
799 | // | ||
800 | //**************************************************************************** | ||
801 | #define JSPT_CAX 0x00000001L | ||
802 | #define JSPT_CAY 0x00000002L | ||
803 | #define JSPT_CBX 0x00000004L | ||
804 | #define JSPT_CBY 0x00000008L | ||
805 | #define JSPT_BA1 0x00000010L | ||
806 | #define JSPT_BA2 0x00000020L | ||
807 | #define JSPT_BB1 0x00000040L | ||
808 | #define JSPT_BB2 0x00000080L | ||
809 | |||
810 | //**************************************************************************** | ||
811 | // | ||
812 | // The following defines are for the flags in the joystick control register. | ||
813 | // The TBF bit has been moved from MIDSR register to JSCTL register bit 8. | ||
814 | // | ||
815 | //**************************************************************************** | ||
816 | #define JSCTL_SP_MASK 0x00000003L | ||
817 | #define JSCTL_SP_SLOW 0x00000000L | ||
818 | #define JSCTL_SP_MEDIUM_SLOW 0x00000001L | ||
819 | #define JSCTL_SP_MEDIUM_FAST 0x00000002L | ||
820 | #define JSCTL_SP_FAST 0x00000003L | ||
821 | #define JSCTL_ARE 0x00000004L | ||
822 | #define JSCTL_TBF 0x00000100L | ||
823 | |||
824 | |||
825 | //**************************************************************************** | ||
826 | // | ||
827 | // The following defines are for the flags in the MIDI control register. | ||
828 | // | ||
829 | //**************************************************************************** | ||
830 | #define MIDCR_TXE 0x00000001L | ||
831 | #define MIDCR_RXE 0x00000002L | ||
832 | #define MIDCR_RIE 0x00000004L | ||
833 | #define MIDCR_TIE 0x00000008L | ||
834 | #define MIDCR_MLB 0x00000010L | ||
835 | #define MIDCR_MRST 0x00000020L | ||
836 | |||
837 | //**************************************************************************** | ||
838 | // | ||
839 | // The following defines are for the flags in the MIDI status register. | ||
840 | // | ||
841 | //**************************************************************************** | ||
842 | #define MIDSR_RBE 0x00000080L | ||
843 | #define MIDSR_RDA 0x00008000L | ||
844 | |||
845 | //**************************************************************************** | ||
846 | // | ||
847 | // The following defines are for the flags in the MIDI write port register. | ||
848 | // | ||
849 | //**************************************************************************** | ||
850 | #define MIDWP_MWD_MASK 0x000000FFL | ||
851 | #define MIDWP_MWD_SHIFT 0L | ||
852 | |||
853 | //**************************************************************************** | ||
854 | // | ||
855 | // The following defines are for the flags in the MIDI read port register. | ||
856 | // | ||
857 | //**************************************************************************** | ||
858 | #define MIDRP_MRD_MASK 0x000000FFL | ||
859 | #define MIDRP_MRD_SHIFT 0L | ||
860 | |||
861 | //**************************************************************************** | ||
862 | // | ||
863 | // The following defines are for the flags in the configuration interface | ||
864 | // register. | ||
865 | // | ||
866 | //**************************************************************************** | ||
867 | #define CFGI_CLK 0x00000001L | ||
868 | #define CFGI_DOUT 0x00000002L | ||
869 | #define CFGI_DIN_EEN 0x00000004L | ||
870 | #define CFGI_EELD 0x00000008L | ||
871 | |||
872 | //**************************************************************************** | ||
873 | // | ||
874 | // The following defines are for the flags in the subsystem ID and vendor ID | ||
875 | // register. | ||
876 | // | ||
877 | //**************************************************************************** | ||
878 | #define SSVID_VID_MASK 0x0000FFFFL | ||
879 | #define SSVID_SID_MASK 0xFFFF0000L | ||
880 | #define SSVID_VID_SHIFT 0L | ||
881 | #define SSVID_SID_SHIFT 16L | ||
882 | |||
883 | //**************************************************************************** | ||
884 | // | ||
885 | // The following defines are for the flags in the GPIO pin interface register. | ||
886 | // | ||
887 | //**************************************************************************** | ||
888 | #define GPIOR_VOLDN 0x00000001L | ||
889 | #define GPIOR_VOLUP 0x00000002L | ||
890 | #define GPIOR_SI2D 0x00000004L | ||
891 | #define GPIOR_SI2OE 0x00000008L | ||
892 | |||
893 | //**************************************************************************** | ||
894 | // | ||
895 | // The following defines are for the flags in the AC97 status register 2. | ||
896 | // | ||
897 | //**************************************************************************** | ||
898 | #define ACSTS2_CRDY 0x00000001L | ||
899 | #define ACSTS2_VSTS 0x00000002L | ||
900 | |||
901 | //**************************************************************************** | ||
902 | // | ||
903 | // The following defines are for the flags in the AC97 input slot valid | ||
904 | // register 2. | ||
905 | // | ||
906 | //**************************************************************************** | ||
907 | #define ACISV2_ISV3 0x00000001L | ||
908 | #define ACISV2_ISV4 0x00000002L | ||
909 | #define ACISV2_ISV5 0x00000004L | ||
910 | #define ACISV2_ISV6 0x00000008L | ||
911 | #define ACISV2_ISV7 0x00000010L | ||
912 | #define ACISV2_ISV8 0x00000020L | ||
913 | #define ACISV2_ISV9 0x00000040L | ||
914 | #define ACISV2_ISV10 0x00000080L | ||
915 | #define ACISV2_ISV11 0x00000100L | ||
916 | #define ACISV2_ISV12 0x00000200L | ||
917 | |||
918 | //**************************************************************************** | ||
919 | // | ||
920 | // The following defines are for the flags in the AC97 status address | ||
921 | // register 2. | ||
922 | // | ||
923 | //**************************************************************************** | ||
924 | #define ACSAD2_SI_MASK 0x0000007FL | ||
925 | #define ACSAD2_SI_SHIFT 0L | ||
926 | |||
927 | //**************************************************************************** | ||
928 | // | ||
929 | // The following defines are for the flags in the AC97 status data register 2. | ||
930 | // | ||
931 | //**************************************************************************** | ||
932 | #define ACSDA2_SD_MASK 0x0000FFFFL | ||
933 | #define ACSDA2_SD_SHIFT 0L | ||
934 | |||
935 | //**************************************************************************** | ||
936 | // | ||
937 | // The following defines are for the flags in the I/O trap control register. | ||
938 | // | ||
939 | //**************************************************************************** | ||
940 | #define IOTCR_ITD 0x00000001L | ||
941 | #define IOTCR_HRV 0x00000002L | ||
942 | #define IOTCR_SRV 0x00000004L | ||
943 | #define IOTCR_DTI 0x00000008L | ||
944 | #define IOTCR_DFI 0x00000010L | ||
945 | #define IOTCR_DDP 0x00000020L | ||
946 | #define IOTCR_JTE 0x00000040L | ||
947 | #define IOTCR_PPE 0x00000080L | ||
948 | |||
949 | //**************************************************************************** | ||
950 | // | ||
951 | // The following defines are for the flags in the I/O trap address and control | ||
952 | // registers for Hardware Master Volume. | ||
953 | // | ||
954 | //**************************************************************************** | ||
955 | #define IOTGP_SA_MASK 0x0000FFFFL | ||
956 | #define IOTGP_MSK_MASK 0x000F0000L | ||
957 | #define IOTGP_IODC_MASK 0x06000000L | ||
958 | #define IOTGP_IODC_16_BIT 0x00000000L | ||
959 | #define IOTGP_IODC_10_BIT 0x02000000L | ||
960 | #define IOTGP_IODC_12_BIT 0x04000000L | ||
961 | #define IOTGP_WSPI 0x08000000L | ||
962 | #define IOTGP_RSPI 0x10000000L | ||
963 | #define IOTGP_WSE 0x20000000L | ||
964 | #define IOTGP_WE 0x40000000L | ||
965 | #define IOTGP_RE 0x80000000L | ||
966 | #define IOTGP_SA_SHIFT 0L | ||
967 | #define IOTGP_MSK_SHIFT 16L | ||
968 | |||
969 | //**************************************************************************** | ||
970 | // | ||
971 | // The following defines are for the flags in the I/O trap address and control | ||
972 | // registers for Sound Blaster | ||
973 | // | ||
974 | //**************************************************************************** | ||
975 | #define IOTSB_SA_MASK 0x0000FFFFL | ||
976 | #define IOTSB_MSK_MASK 0x000F0000L | ||
977 | #define IOTSB_IODC_MASK 0x06000000L | ||
978 | #define IOTSB_IODC_16_BIT 0x00000000L | ||
979 | #define IOTSB_IODC_10_BIT 0x02000000L | ||
980 | #define IOTSB_IODC_12_BIT 0x04000000L | ||
981 | #define IOTSB_WSPI 0x08000000L | ||
982 | #define IOTSB_RSPI 0x10000000L | ||
983 | #define IOTSB_WSE 0x20000000L | ||
984 | #define IOTSB_WE 0x40000000L | ||
985 | #define IOTSB_RE 0x80000000L | ||
986 | #define IOTSB_SA_SHIFT 0L | ||
987 | #define IOTSB_MSK_SHIFT 16L | ||
988 | |||
989 | //**************************************************************************** | ||
990 | // | ||
991 | // The following defines are for the flags in the I/O trap address and control | ||
992 | // registers for FM. | ||
993 | // | ||
994 | //**************************************************************************** | ||
995 | #define IOTFM_SA_MASK 0x0000FFFFL | ||
996 | #define IOTFM_MSK_MASK 0x000F0000L | ||
997 | #define IOTFM_IODC_MASK 0x06000000L | ||
998 | #define IOTFM_IODC_16_BIT 0x00000000L | ||
999 | #define IOTFM_IODC_10_BIT 0x02000000L | ||
1000 | #define IOTFM_IODC_12_BIT 0x04000000L | ||
1001 | #define IOTFM_WSPI 0x08000000L | ||
1002 | #define IOTFM_RSPI 0x10000000L | ||
1003 | #define IOTFM_WSE 0x20000000L | ||
1004 | #define IOTFM_WE 0x40000000L | ||
1005 | #define IOTFM_RE 0x80000000L | ||
1006 | #define IOTFM_SA_SHIFT 0L | ||
1007 | #define IOTFM_MSK_SHIFT 16L | ||
1008 | |||
1009 | //**************************************************************************** | ||
1010 | // | ||
1011 | // The following defines are for the flags in the PC/PCI request register. | ||
1012 | // | ||
1013 | //**************************************************************************** | ||
1014 | #define PCPRR_RDC_MASK 0x00000007L | ||
1015 | #define PCPRR_REQ 0x00008000L | ||
1016 | #define PCPRR_RDC_SHIFT 0L | ||
1017 | |||
1018 | //**************************************************************************** | ||
1019 | // | ||
1020 | // The following defines are for the flags in the PC/PCI grant register. | ||
1021 | // | ||
1022 | //**************************************************************************** | ||
1023 | #define PCPGR_GDC_MASK 0x00000007L | ||
1024 | #define PCPGR_VL 0x00008000L | ||
1025 | #define PCPGR_GDC_SHIFT 0L | ||
1026 | |||
1027 | //**************************************************************************** | ||
1028 | // | ||
1029 | // The following defines are for the flags in the PC/PCI Control Register. | ||
1030 | // | ||
1031 | //**************************************************************************** | ||
1032 | #define PCPCR_EN 0x00000001L | ||
1033 | |||
1034 | //**************************************************************************** | ||
1035 | // | ||
1036 | // The following defines are for the flags in the debug index register. | ||
1037 | // | ||
1038 | //**************************************************************************** | ||
1039 | #define DREG_REGID_MASK 0x0000007FL | ||
1040 | #define DREG_DEBUG 0x00000080L | ||
1041 | #define DREG_RGBK_MASK 0x00000700L | ||
1042 | #define DREG_TRAP 0x00000800L | ||
1043 | #if !defined(NO_CS4612) | ||
1044 | #if !defined(NO_CS4615) | ||
1045 | #define DREG_TRAPX 0x00001000L | ||
1046 | #endif | ||
1047 | #endif | ||
1048 | #define DREG_REGID_SHIFT 0L | ||
1049 | #define DREG_RGBK_SHIFT 8L | ||
1050 | #define DREG_RGBK_REGID_MASK 0x0000077FL | ||
1051 | #define DREG_REGID_R0 0x00000010L | ||
1052 | #define DREG_REGID_R1 0x00000011L | ||
1053 | #define DREG_REGID_R2 0x00000012L | ||
1054 | #define DREG_REGID_R3 0x00000013L | ||
1055 | #define DREG_REGID_R4 0x00000014L | ||
1056 | #define DREG_REGID_R5 0x00000015L | ||
1057 | #define DREG_REGID_R6 0x00000016L | ||
1058 | #define DREG_REGID_R7 0x00000017L | ||
1059 | #define DREG_REGID_R8 0x00000018L | ||
1060 | #define DREG_REGID_R9 0x00000019L | ||
1061 | #define DREG_REGID_RA 0x0000001AL | ||
1062 | #define DREG_REGID_RB 0x0000001BL | ||
1063 | #define DREG_REGID_RC 0x0000001CL | ||
1064 | #define DREG_REGID_RD 0x0000001DL | ||
1065 | #define DREG_REGID_RE 0x0000001EL | ||
1066 | #define DREG_REGID_RF 0x0000001FL | ||
1067 | #define DREG_REGID_RA_BUS_LOW 0x00000020L | ||
1068 | #define DREG_REGID_RA_BUS_HIGH 0x00000038L | ||
1069 | #define DREG_REGID_YBUS_LOW 0x00000050L | ||
1070 | #define DREG_REGID_YBUS_HIGH 0x00000058L | ||
1071 | #define DREG_REGID_TRAP_0 0x00000100L | ||
1072 | #define DREG_REGID_TRAP_1 0x00000101L | ||
1073 | #define DREG_REGID_TRAP_2 0x00000102L | ||
1074 | #define DREG_REGID_TRAP_3 0x00000103L | ||
1075 | #define DREG_REGID_TRAP_4 0x00000104L | ||
1076 | #define DREG_REGID_TRAP_5 0x00000105L | ||
1077 | #define DREG_REGID_TRAP_6 0x00000106L | ||
1078 | #define DREG_REGID_TRAP_7 0x00000107L | ||
1079 | #define DREG_REGID_INDIRECT_ADDRESS 0x0000010EL | ||
1080 | #define DREG_REGID_TOP_OF_STACK 0x0000010FL | ||
1081 | #if !defined(NO_CS4612) | ||
1082 | #if !defined(NO_CS4615) | ||
1083 | #define DREG_REGID_TRAP_8 0x00000110L | ||
1084 | #define DREG_REGID_TRAP_9 0x00000111L | ||
1085 | #define DREG_REGID_TRAP_10 0x00000112L | ||
1086 | #define DREG_REGID_TRAP_11 0x00000113L | ||
1087 | #define DREG_REGID_TRAP_12 0x00000114L | ||
1088 | #define DREG_REGID_TRAP_13 0x00000115L | ||
1089 | #define DREG_REGID_TRAP_14 0x00000116L | ||
1090 | #define DREG_REGID_TRAP_15 0x00000117L | ||
1091 | #define DREG_REGID_TRAP_16 0x00000118L | ||
1092 | #define DREG_REGID_TRAP_17 0x00000119L | ||
1093 | #define DREG_REGID_TRAP_18 0x0000011AL | ||
1094 | #define DREG_REGID_TRAP_19 0x0000011BL | ||
1095 | #define DREG_REGID_TRAP_20 0x0000011CL | ||
1096 | #define DREG_REGID_TRAP_21 0x0000011DL | ||
1097 | #define DREG_REGID_TRAP_22 0x0000011EL | ||
1098 | #define DREG_REGID_TRAP_23 0x0000011FL | ||
1099 | #endif | ||
1100 | #endif | ||
1101 | #define DREG_REGID_RSA0_LOW 0x00000200L | ||
1102 | #define DREG_REGID_RSA0_HIGH 0x00000201L | ||
1103 | #define DREG_REGID_RSA1_LOW 0x00000202L | ||
1104 | #define DREG_REGID_RSA1_HIGH 0x00000203L | ||
1105 | #define DREG_REGID_RSA2 0x00000204L | ||
1106 | #define DREG_REGID_RSA3 0x00000205L | ||
1107 | #define DREG_REGID_RSI0_LOW 0x00000206L | ||
1108 | #define DREG_REGID_RSI0_HIGH 0x00000207L | ||
1109 | #define DREG_REGID_RSI1 0x00000208L | ||
1110 | #define DREG_REGID_RSI2 0x00000209L | ||
1111 | #define DREG_REGID_SAGUSTATUS 0x0000020AL | ||
1112 | #define DREG_REGID_RSCONFIG01_LOW 0x0000020BL | ||
1113 | #define DREG_REGID_RSCONFIG01_HIGH 0x0000020CL | ||
1114 | #define DREG_REGID_RSCONFIG23_LOW 0x0000020DL | ||
1115 | #define DREG_REGID_RSCONFIG23_HIGH 0x0000020EL | ||
1116 | #define DREG_REGID_RSDMA01E 0x0000020FL | ||
1117 | #define DREG_REGID_RSDMA23E 0x00000210L | ||
1118 | #define DREG_REGID_RSD0_LOW 0x00000211L | ||
1119 | #define DREG_REGID_RSD0_HIGH 0x00000212L | ||
1120 | #define DREG_REGID_RSD1_LOW 0x00000213L | ||
1121 | #define DREG_REGID_RSD1_HIGH 0x00000214L | ||
1122 | #define DREG_REGID_RSD2_LOW 0x00000215L | ||
1123 | #define DREG_REGID_RSD2_HIGH 0x00000216L | ||
1124 | #define DREG_REGID_RSD3_LOW 0x00000217L | ||
1125 | #define DREG_REGID_RSD3_HIGH 0x00000218L | ||
1126 | #define DREG_REGID_SRAR_HIGH 0x0000021AL | ||
1127 | #define DREG_REGID_SRAR_LOW 0x0000021BL | ||
1128 | #define DREG_REGID_DMA_STATE 0x0000021CL | ||
1129 | #define DREG_REGID_CURRENT_DMA_STREAM 0x0000021DL | ||
1130 | #define DREG_REGID_NEXT_DMA_STREAM 0x0000021EL | ||
1131 | #define DREG_REGID_CPU_STATUS 0x00000300L | ||
1132 | #define DREG_REGID_MAC_MODE 0x00000301L | ||
1133 | #define DREG_REGID_STACK_AND_REPEAT 0x00000302L | ||
1134 | #define DREG_REGID_INDEX0 0x00000304L | ||
1135 | #define DREG_REGID_INDEX1 0x00000305L | ||
1136 | #define DREG_REGID_DMA_STATE_0_3 0x00000400L | ||
1137 | #define DREG_REGID_DMA_STATE_4_7 0x00000404L | ||
1138 | #define DREG_REGID_DMA_STATE_8_11 0x00000408L | ||
1139 | #define DREG_REGID_DMA_STATE_12_15 0x0000040CL | ||
1140 | #define DREG_REGID_DMA_STATE_16_19 0x00000410L | ||
1141 | #define DREG_REGID_DMA_STATE_20_23 0x00000414L | ||
1142 | #define DREG_REGID_DMA_STATE_24_27 0x00000418L | ||
1143 | #define DREG_REGID_DMA_STATE_28_31 0x0000041CL | ||
1144 | #define DREG_REGID_DMA_STATE_32_35 0x00000420L | ||
1145 | #define DREG_REGID_DMA_STATE_36_39 0x00000424L | ||
1146 | #define DREG_REGID_DMA_STATE_40_43 0x00000428L | ||
1147 | #define DREG_REGID_DMA_STATE_44_47 0x0000042CL | ||
1148 | #define DREG_REGID_DMA_STATE_48_51 0x00000430L | ||
1149 | #define DREG_REGID_DMA_STATE_52_55 0x00000434L | ||
1150 | #define DREG_REGID_DMA_STATE_56_59 0x00000438L | ||
1151 | #define DREG_REGID_DMA_STATE_60_63 0x0000043CL | ||
1152 | #define DREG_REGID_DMA_STATE_64_67 0x00000440L | ||
1153 | #define DREG_REGID_DMA_STATE_68_71 0x00000444L | ||
1154 | #define DREG_REGID_DMA_STATE_72_75 0x00000448L | ||
1155 | #define DREG_REGID_DMA_STATE_76_79 0x0000044CL | ||
1156 | #define DREG_REGID_DMA_STATE_80_83 0x00000450L | ||
1157 | #define DREG_REGID_DMA_STATE_84_87 0x00000454L | ||
1158 | #define DREG_REGID_DMA_STATE_88_91 0x00000458L | ||
1159 | #define DREG_REGID_DMA_STATE_92_95 0x0000045CL | ||
1160 | #define DREG_REGID_TRAP_SELECT 0x00000500L | ||
1161 | #define DREG_REGID_TRAP_WRITE_0 0x00000500L | ||
1162 | #define DREG_REGID_TRAP_WRITE_1 0x00000501L | ||
1163 | #define DREG_REGID_TRAP_WRITE_2 0x00000502L | ||
1164 | #define DREG_REGID_TRAP_WRITE_3 0x00000503L | ||
1165 | #define DREG_REGID_TRAP_WRITE_4 0x00000504L | ||
1166 | #define DREG_REGID_TRAP_WRITE_5 0x00000505L | ||
1167 | #define DREG_REGID_TRAP_WRITE_6 0x00000506L | ||
1168 | #define DREG_REGID_TRAP_WRITE_7 0x00000507L | ||
1169 | #if !defined(NO_CS4612) | ||
1170 | #if !defined(NO_CS4615) | ||
1171 | #define DREG_REGID_TRAP_WRITE_8 0x00000510L | ||
1172 | #define DREG_REGID_TRAP_WRITE_9 0x00000511L | ||
1173 | #define DREG_REGID_TRAP_WRITE_10 0x00000512L | ||
1174 | #define DREG_REGID_TRAP_WRITE_11 0x00000513L | ||
1175 | #define DREG_REGID_TRAP_WRITE_12 0x00000514L | ||
1176 | #define DREG_REGID_TRAP_WRITE_13 0x00000515L | ||
1177 | #define DREG_REGID_TRAP_WRITE_14 0x00000516L | ||
1178 | #define DREG_REGID_TRAP_WRITE_15 0x00000517L | ||
1179 | #define DREG_REGID_TRAP_WRITE_16 0x00000518L | ||
1180 | #define DREG_REGID_TRAP_WRITE_17 0x00000519L | ||
1181 | #define DREG_REGID_TRAP_WRITE_18 0x0000051AL | ||
1182 | #define DREG_REGID_TRAP_WRITE_19 0x0000051BL | ||
1183 | #define DREG_REGID_TRAP_WRITE_20 0x0000051CL | ||
1184 | #define DREG_REGID_TRAP_WRITE_21 0x0000051DL | ||
1185 | #define DREG_REGID_TRAP_WRITE_22 0x0000051EL | ||
1186 | #define DREG_REGID_TRAP_WRITE_23 0x0000051FL | ||
1187 | #endif | ||
1188 | #endif | ||
1189 | #define DREG_REGID_MAC0_ACC0_LOW 0x00000600L | ||
1190 | #define DREG_REGID_MAC0_ACC1_LOW 0x00000601L | ||
1191 | #define DREG_REGID_MAC0_ACC2_LOW 0x00000602L | ||
1192 | #define DREG_REGID_MAC0_ACC3_LOW 0x00000603L | ||
1193 | #define DREG_REGID_MAC1_ACC0_LOW 0x00000604L | ||
1194 | #define DREG_REGID_MAC1_ACC1_LOW 0x00000605L | ||
1195 | #define DREG_REGID_MAC1_ACC2_LOW 0x00000606L | ||
1196 | #define DREG_REGID_MAC1_ACC3_LOW 0x00000607L | ||
1197 | #define DREG_REGID_MAC0_ACC0_MID 0x00000608L | ||
1198 | #define DREG_REGID_MAC0_ACC1_MID 0x00000609L | ||
1199 | #define DREG_REGID_MAC0_ACC2_MID 0x0000060AL | ||
1200 | #define DREG_REGID_MAC0_ACC3_MID 0x0000060BL | ||
1201 | #define DREG_REGID_MAC1_ACC0_MID 0x0000060CL | ||
1202 | #define DREG_REGID_MAC1_ACC1_MID 0x0000060DL | ||
1203 | #define DREG_REGID_MAC1_ACC2_MID 0x0000060EL | ||
1204 | #define DREG_REGID_MAC1_ACC3_MID 0x0000060FL | ||
1205 | #define DREG_REGID_MAC0_ACC0_HIGH 0x00000610L | ||
1206 | #define DREG_REGID_MAC0_ACC1_HIGH 0x00000611L | ||
1207 | #define DREG_REGID_MAC0_ACC2_HIGH 0x00000612L | ||
1208 | #define DREG_REGID_MAC0_ACC3_HIGH 0x00000613L | ||
1209 | #define DREG_REGID_MAC1_ACC0_HIGH 0x00000614L | ||
1210 | #define DREG_REGID_MAC1_ACC1_HIGH 0x00000615L | ||
1211 | #define DREG_REGID_MAC1_ACC2_HIGH 0x00000616L | ||
1212 | #define DREG_REGID_MAC1_ACC3_HIGH 0x00000617L | ||
1213 | #define DREG_REGID_RSHOUT_LOW 0x00000620L | ||
1214 | #define DREG_REGID_RSHOUT_MID 0x00000628L | ||
1215 | #define DREG_REGID_RSHOUT_HIGH 0x00000630L | ||
1216 | |||
1217 | //**************************************************************************** | ||
1218 | // | ||
1219 | // The following defines are for the flags in the AC97 S/PDIF Control register. | ||
1220 | // | ||
1221 | //**************************************************************************** | ||
1222 | #define SPDIF_CONTROL_SPDIF_EN 0x00008000L | ||
1223 | #define SPDIF_CONTROL_VAL 0x00004000L | ||
1224 | #define SPDIF_CONTROL_COPY 0x00000004L | ||
1225 | #define SPDIF_CONTROL_CC0 0x00000010L | ||
1226 | #define SPDIF_CONTROL_CC1 0x00000020L | ||
1227 | #define SPDIF_CONTROL_CC2 0x00000040L | ||
1228 | #define SPDIF_CONTROL_CC3 0x00000080L | ||
1229 | #define SPDIF_CONTROL_CC4 0x00000100L | ||
1230 | #define SPDIF_CONTROL_CC5 0x00000200L | ||
1231 | #define SPDIF_CONTROL_CC6 0x00000400L | ||
1232 | #define SPDIF_CONTROL_L 0x00000800L | ||
1233 | |||
1234 | #endif // _H_HWDEFS | ||
diff --git a/sound/oss/cs4281/cs4281_wrapper-24.c b/sound/oss/cs4281/cs4281_wrapper-24.c deleted file mode 100644 index 4559f02c9969..000000000000 --- a/sound/oss/cs4281/cs4281_wrapper-24.c +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * "cs4281_wrapper.c" -- Cirrus Logic-Crystal CS4281 linux audio driver. | ||
4 | * | ||
5 | * Copyright (C) 2000,2001 Cirrus Logic Corp. | ||
6 | * -- tom woller (twoller@crystal.cirrus.com) or | ||
7 | * (audio@crystal.cirrus.com). | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | * 12/20/00 trw - new file. | ||
24 | * | ||
25 | *******************************************************************************/ | ||
26 | |||
27 | #include <linux/spinlock.h> | ||
28 | |||
29 | static int cs4281_resume_null(struct pci_dev *pcidev) { return 0; } | ||
30 | static int cs4281_suspend_null(struct pci_dev *pcidev, pm_message_t state) { return 0; } | ||
31 | |||
32 | #define free_dmabuf(state, dmabuf) \ | ||
33 | pci_free_consistent(state->pcidev, \ | ||
34 | PAGE_SIZE << (dmabuf)->buforder, \ | ||
35 | (dmabuf)->rawbuf, (dmabuf)->dmaaddr); | ||
36 | #define free_dmabuf2(state, dmabuf) \ | ||
37 | pci_free_consistent((state)->pcidev, \ | ||
38 | PAGE_SIZE << (state)->buforder_tmpbuff, \ | ||
39 | (state)->tmpbuff, (state)->dmaaddr_tmpbuff); | ||
40 | #define cs4x_pgoff(vma) ((vma)->vm_pgoff) | ||
41 | |||
diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c deleted file mode 100644 index 0400a416dc93..000000000000 --- a/sound/oss/cs4281/cs4281m.c +++ /dev/null | |||
@@ -1,4487 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * "cs4281.c" -- Cirrus Logic-Crystal CS4281 linux audio driver. | ||
4 | * | ||
5 | * Copyright (C) 2000,2001 Cirrus Logic Corp. | ||
6 | * -- adapted from drivers by Thomas Sailer, | ||
7 | * -- but don't bug him; Problems should go to: | ||
8 | * -- tom woller (twoller@crystal.cirrus.com) or | ||
9 | * (audio@crystal.cirrus.com). | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | * Module command line parameters: | ||
26 | * none | ||
27 | * | ||
28 | * Supported devices: | ||
29 | * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible | ||
30 | * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible | ||
31 | * /dev/midi simple MIDI UART interface, no ioctl | ||
32 | * | ||
33 | * Modification History | ||
34 | * 08/20/00 trw - silence and no stopping DAC until release | ||
35 | * 08/23/00 trw - added CS_DBG statements, fix interrupt hang issue on DAC stop. | ||
36 | * 09/18/00 trw - added 16bit only record with conversion | ||
37 | * 09/24/00 trw - added Enhanced Full duplex (separate simultaneous | ||
38 | * capture/playback rates) | ||
39 | * 10/03/00 trw - fixed mmap (fixed GRECORD and the XMMS mmap test plugin | ||
40 | * libOSSm.so) | ||
41 | * 10/11/00 trw - modified for 2.4.0-test9 kernel enhancements (NR_MAP removal) | ||
42 | * 11/03/00 trw - fixed interrupt loss/stutter, added debug. | ||
43 | * 11/10/00 bkz - added __devinit to cs4281_hw_init() | ||
44 | * 11/10/00 trw - fixed SMP and capture spinlock hang. | ||
45 | * 12/04/00 trw - cleaned up CSDEBUG flags and added "defaultorder" moduleparm. | ||
46 | * 12/05/00 trw - fixed polling (myth2), and added underrun swptr fix. | ||
47 | * 12/08/00 trw - added PM support. | ||
48 | * 12/14/00 trw - added wrapper code, builds under 2.4.0, 2.2.17-20, 2.2.17-8 | ||
49 | * (RH/Dell base), 2.2.18, 2.2.12. cleaned up code mods by ident. | ||
50 | * 12/19/00 trw - added PM support for 2.2 base (apm_callback). other PM cleanup. | ||
51 | * 12/21/00 trw - added fractional "defaultorder" inputs. if >100 then use | ||
52 | * defaultorder-100 as power of 2 for the buffer size. example: | ||
53 | * 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size. | ||
54 | * | ||
55 | *******************************************************************************/ | ||
56 | |||
57 | /* uncomment the following line to disable building PM support into the driver */ | ||
58 | //#define NOT_CS4281_PM 1 | ||
59 | |||
60 | #include <linux/list.h> | ||
61 | #include <linux/module.h> | ||
62 | #include <linux/string.h> | ||
63 | #include <linux/ioport.h> | ||
64 | #include <linux/sched.h> | ||
65 | #include <linux/delay.h> | ||
66 | #include <linux/sound.h> | ||
67 | #include <linux/slab.h> | ||
68 | #include <linux/soundcard.h> | ||
69 | #include <linux/pci.h> | ||
70 | #include <linux/bitops.h> | ||
71 | #include <linux/init.h> | ||
72 | #include <linux/interrupt.h> | ||
73 | #include <linux/poll.h> | ||
74 | #include <linux/fs.h> | ||
75 | #include <linux/wait.h> | ||
76 | |||
77 | #include <asm/current.h> | ||
78 | #include <asm/io.h> | ||
79 | #include <asm/dma.h> | ||
80 | #include <asm/page.h> | ||
81 | #include <asm/uaccess.h> | ||
82 | |||
83 | //#include "cs_dm.h" | ||
84 | #include "cs4281_hwdefs.h" | ||
85 | #include "cs4281pm.h" | ||
86 | |||
87 | struct cs4281_state; | ||
88 | |||
89 | static void stop_dac(struct cs4281_state *s); | ||
90 | static void stop_adc(struct cs4281_state *s); | ||
91 | static void start_dac(struct cs4281_state *s); | ||
92 | static void start_adc(struct cs4281_state *s); | ||
93 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
94 | |||
95 | // --------------------------------------------------------------------- | ||
96 | |||
97 | #ifndef PCI_VENDOR_ID_CIRRUS | ||
98 | #define PCI_VENDOR_ID_CIRRUS 0x1013 | ||
99 | #endif | ||
100 | #ifndef PCI_DEVICE_ID_CRYSTAL_CS4281 | ||
101 | #define PCI_DEVICE_ID_CRYSTAL_CS4281 0x6005 | ||
102 | #endif | ||
103 | |||
104 | #define CS4281_MAGIC ((PCI_DEVICE_ID_CRYSTAL_CS4281<<16) | PCI_VENDOR_ID_CIRRUS) | ||
105 | #define CS4281_CFLR_DEFAULT 0x00000001 /* CFLR must be in AC97 link mode */ | ||
106 | |||
107 | // buffer order determines the size of the dma buffer for the driver. | ||
108 | // under Linux, a smaller buffer allows more responsiveness from many of the | ||
109 | // applications (e.g. games). A larger buffer allows some of the apps (esound) | ||
110 | // to not underrun the dma buffer as easily. As default, use 32k (order=3) | ||
111 | // rather than 64k as some of the games work more responsively. | ||
112 | // log base 2( buff sz = 32k). | ||
113 | static unsigned long defaultorder = 3; | ||
114 | module_param(defaultorder, ulong, 0); | ||
115 | |||
116 | // | ||
117 | // Turn on/off debugging compilation by commenting out "#define CSDEBUG" | ||
118 | // | ||
119 | #define CSDEBUG 1 | ||
120 | #if CSDEBUG | ||
121 | #define CSDEBUG_INTERFACE 1 | ||
122 | #else | ||
123 | #undef CSDEBUG_INTERFACE | ||
124 | #endif | ||
125 | // | ||
126 | // cs_debugmask areas | ||
127 | // | ||
128 | #define CS_INIT 0x00000001 // initialization and probe functions | ||
129 | #define CS_ERROR 0x00000002 // tmp debugging bit placeholder | ||
130 | #define CS_INTERRUPT 0x00000004 // interrupt handler (separate from all other) | ||
131 | #define CS_FUNCTION 0x00000008 // enter/leave functions | ||
132 | #define CS_WAVE_WRITE 0x00000010 // write information for wave | ||
133 | #define CS_WAVE_READ 0x00000020 // read information for wave | ||
134 | #define CS_MIDI_WRITE 0x00000040 // write information for midi | ||
135 | #define CS_MIDI_READ 0x00000080 // read information for midi | ||
136 | #define CS_MPU401_WRITE 0x00000100 // write information for mpu401 | ||
137 | #define CS_MPU401_READ 0x00000200 // read information for mpu401 | ||
138 | #define CS_OPEN 0x00000400 // all open functions in the driver | ||
139 | #define CS_RELEASE 0x00000800 // all release functions in the driver | ||
140 | #define CS_PARMS 0x00001000 // functional and operational parameters | ||
141 | #define CS_IOCTL 0x00002000 // ioctl (non-mixer) | ||
142 | #define CS_PM 0x00004000 // power management | ||
143 | #define CS_TMP 0x10000000 // tmp debug mask bit | ||
144 | |||
145 | #define CS_IOCTL_CMD_SUSPEND 0x1 // suspend | ||
146 | #define CS_IOCTL_CMD_RESUME 0x2 // resume | ||
147 | // | ||
148 | // CSDEBUG is usual mode is set to 1, then use the | ||
149 | // cs_debuglevel and cs_debugmask to turn on or off debugging. | ||
150 | // Debug level of 1 has been defined to be kernel errors and info | ||
151 | // that should be printed on any released driver. | ||
152 | // | ||
153 | #if CSDEBUG | ||
154 | #define CS_DBGOUT(mask,level,x) if((cs_debuglevel >= (level)) && ((mask) & cs_debugmask) ) {x;} | ||
155 | #else | ||
156 | #define CS_DBGOUT(mask,level,x) | ||
157 | #endif | ||
158 | |||
159 | #if CSDEBUG | ||
160 | static unsigned long cs_debuglevel = 1; // levels range from 1-9 | ||
161 | static unsigned long cs_debugmask = CS_INIT | CS_ERROR; // use CS_DBGOUT with various mask values | ||
162 | module_param(cs_debuglevel, ulong, 0); | ||
163 | module_param(cs_debugmask, ulong, 0); | ||
164 | #endif | ||
165 | #define CS_TRUE 1 | ||
166 | #define CS_FALSE 0 | ||
167 | |||
168 | // MIDI buffer sizes | ||
169 | #define MIDIINBUF 500 | ||
170 | #define MIDIOUTBUF 500 | ||
171 | |||
172 | #define FMODE_MIDI_SHIFT 3 | ||
173 | #define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) | ||
174 | #define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) | ||
175 | |||
176 | #define CS4281_MAJOR_VERSION 1 | ||
177 | #define CS4281_MINOR_VERSION 13 | ||
178 | #ifdef __ia64__ | ||
179 | #define CS4281_ARCH 64 //architecture key | ||
180 | #else | ||
181 | #define CS4281_ARCH 32 //architecture key | ||
182 | #endif | ||
183 | |||
184 | #define CS_TYPE_ADC 0 | ||
185 | #define CS_TYPE_DAC 1 | ||
186 | |||
187 | |||
188 | static const char invalid_magic[] = | ||
189 | KERN_CRIT "cs4281: invalid magic value\n"; | ||
190 | |||
191 | #define VALIDATE_STATE(s) \ | ||
192 | ({ \ | ||
193 | if (!(s) || (s)->magic != CS4281_MAGIC) { \ | ||
194 | printk(invalid_magic); \ | ||
195 | return -ENXIO; \ | ||
196 | } \ | ||
197 | }) | ||
198 | |||
199 | //LIST_HEAD(cs4281_devs); | ||
200 | static struct list_head cs4281_devs = { &cs4281_devs, &cs4281_devs }; | ||
201 | |||
202 | struct cs4281_state; | ||
203 | |||
204 | #include "cs4281_wrapper-24.c" | ||
205 | |||
206 | struct cs4281_state { | ||
207 | // magic | ||
208 | unsigned int magic; | ||
209 | |||
210 | // we keep the cards in a linked list | ||
211 | struct cs4281_state *next; | ||
212 | |||
213 | // pcidev is needed to turn off the DDMA controller at driver shutdown | ||
214 | struct pci_dev *pcidev; | ||
215 | struct list_head list; | ||
216 | |||
217 | // soundcore stuff | ||
218 | int dev_audio; | ||
219 | int dev_mixer; | ||
220 | int dev_midi; | ||
221 | |||
222 | // hardware resources | ||
223 | unsigned int pBA0phys, pBA1phys; | ||
224 | char __iomem *pBA0; | ||
225 | char __iomem *pBA1; | ||
226 | unsigned int irq; | ||
227 | |||
228 | // mixer registers | ||
229 | struct { | ||
230 | unsigned short vol[10]; | ||
231 | unsigned int recsrc; | ||
232 | unsigned int modcnt; | ||
233 | unsigned short micpreamp; | ||
234 | } mix; | ||
235 | |||
236 | // wave stuff | ||
237 | struct properties { | ||
238 | unsigned fmt; | ||
239 | unsigned fmt_original; // original requested format | ||
240 | unsigned channels; | ||
241 | unsigned rate; | ||
242 | unsigned char clkdiv; | ||
243 | } prop_dac, prop_adc; | ||
244 | unsigned conversion:1; // conversion from 16 to 8 bit in progress | ||
245 | void *tmpbuff; // tmp buffer for sample conversions | ||
246 | unsigned ena; | ||
247 | spinlock_t lock; | ||
248 | struct mutex open_sem; | ||
249 | struct mutex open_sem_adc; | ||
250 | struct mutex open_sem_dac; | ||
251 | mode_t open_mode; | ||
252 | wait_queue_head_t open_wait; | ||
253 | wait_queue_head_t open_wait_adc; | ||
254 | wait_queue_head_t open_wait_dac; | ||
255 | |||
256 | dma_addr_t dmaaddr_tmpbuff; | ||
257 | unsigned buforder_tmpbuff; // Log base 2 of 'rawbuf' size in bytes.. | ||
258 | struct dmabuf { | ||
259 | void *rawbuf; // Physical address of | ||
260 | dma_addr_t dmaaddr; | ||
261 | unsigned buforder; // Log base 2 of 'rawbuf' size in bytes.. | ||
262 | unsigned numfrag; // # of 'fragments' in the buffer. | ||
263 | unsigned fragshift; // Log base 2 of fragment size. | ||
264 | unsigned hwptr, swptr; | ||
265 | unsigned total_bytes; // # bytes process since open. | ||
266 | unsigned blocks; // last returned blocks value GETOPTR | ||
267 | unsigned wakeup; // interrupt occurred on block | ||
268 | int count; | ||
269 | unsigned underrun; // underrun flag | ||
270 | unsigned error; // over/underrun | ||
271 | wait_queue_head_t wait; | ||
272 | // redundant, but makes calculations easier | ||
273 | unsigned fragsize; // 2**fragshift.. | ||
274 | unsigned dmasize; // 2**buforder. | ||
275 | unsigned fragsamples; | ||
276 | // OSS stuff | ||
277 | unsigned mapped:1; // Buffer mapped in cs4281_mmap()? | ||
278 | unsigned ready:1; // prog_dmabuf_dac()/adc() successful? | ||
279 | unsigned endcleared:1; | ||
280 | unsigned type:1; // adc or dac buffer (CS_TYPE_XXX) | ||
281 | unsigned ossfragshift; | ||
282 | int ossmaxfrags; | ||
283 | unsigned subdivision; | ||
284 | } dma_dac, dma_adc; | ||
285 | |||
286 | // midi stuff | ||
287 | struct { | ||
288 | unsigned ird, iwr, icnt; | ||
289 | unsigned ord, owr, ocnt; | ||
290 | wait_queue_head_t iwait; | ||
291 | wait_queue_head_t owait; | ||
292 | struct timer_list timer; | ||
293 | unsigned char ibuf[MIDIINBUF]; | ||
294 | unsigned char obuf[MIDIOUTBUF]; | ||
295 | } midi; | ||
296 | |||
297 | struct cs4281_pm pm; | ||
298 | struct cs4281_pipeline pl[CS4281_NUMBER_OF_PIPELINES]; | ||
299 | }; | ||
300 | |||
301 | #include "cs4281pm-24.c" | ||
302 | |||
303 | #if CSDEBUG | ||
304 | |||
305 | // DEBUG ROUTINES | ||
306 | |||
307 | #define SOUND_MIXER_CS_GETDBGLEVEL _SIOWR('M',120, int) | ||
308 | #define SOUND_MIXER_CS_SETDBGLEVEL _SIOWR('M',121, int) | ||
309 | #define SOUND_MIXER_CS_GETDBGMASK _SIOWR('M',122, int) | ||
310 | #define SOUND_MIXER_CS_SETDBGMASK _SIOWR('M',123, int) | ||
311 | |||
312 | #define SOUND_MIXER_CS_APM _SIOWR('M',124, int) | ||
313 | |||
314 | |||
315 | static void cs_printioctl(unsigned int x) | ||
316 | { | ||
317 | unsigned int i; | ||
318 | unsigned char vidx; | ||
319 | // Index of mixtable1[] member is Device ID | ||
320 | // and must be <= SOUND_MIXER_NRDEVICES. | ||
321 | // Value of array member is index into s->mix.vol[] | ||
322 | static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = { | ||
323 | [SOUND_MIXER_PCM] = 1, // voice | ||
324 | [SOUND_MIXER_LINE1] = 2, // AUX | ||
325 | [SOUND_MIXER_CD] = 3, // CD | ||
326 | [SOUND_MIXER_LINE] = 4, // Line | ||
327 | [SOUND_MIXER_SYNTH] = 5, // FM | ||
328 | [SOUND_MIXER_MIC] = 6, // Mic | ||
329 | [SOUND_MIXER_SPEAKER] = 7, // Speaker | ||
330 | [SOUND_MIXER_RECLEV] = 8, // Recording level | ||
331 | [SOUND_MIXER_VOLUME] = 9 // Master Volume | ||
332 | }; | ||
333 | |||
334 | switch (x) { | ||
335 | case SOUND_MIXER_CS_GETDBGMASK: | ||
336 | CS_DBGOUT(CS_IOCTL, 4, | ||
337 | printk("SOUND_MIXER_CS_GETDBGMASK:\n")); | ||
338 | break; | ||
339 | case SOUND_MIXER_CS_GETDBGLEVEL: | ||
340 | CS_DBGOUT(CS_IOCTL, 4, | ||
341 | printk("SOUND_MIXER_CS_GETDBGLEVEL:\n")); | ||
342 | break; | ||
343 | case SOUND_MIXER_CS_SETDBGMASK: | ||
344 | CS_DBGOUT(CS_IOCTL, 4, | ||
345 | printk("SOUND_MIXER_CS_SETDBGMASK:\n")); | ||
346 | break; | ||
347 | case SOUND_MIXER_CS_SETDBGLEVEL: | ||
348 | CS_DBGOUT(CS_IOCTL, 4, | ||
349 | printk("SOUND_MIXER_CS_SETDBGLEVEL:\n")); | ||
350 | break; | ||
351 | case OSS_GETVERSION: | ||
352 | CS_DBGOUT(CS_IOCTL, 4, printk("OSS_GETVERSION:\n")); | ||
353 | break; | ||
354 | case SNDCTL_DSP_SYNC: | ||
355 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SYNC:\n")); | ||
356 | break; | ||
357 | case SNDCTL_DSP_SETDUPLEX: | ||
358 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETDUPLEX:\n")); | ||
359 | break; | ||
360 | case SNDCTL_DSP_GETCAPS: | ||
361 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETCAPS:\n")); | ||
362 | break; | ||
363 | case SNDCTL_DSP_RESET: | ||
364 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_RESET:\n")); | ||
365 | break; | ||
366 | case SNDCTL_DSP_SPEED: | ||
367 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SPEED:\n")); | ||
368 | break; | ||
369 | case SNDCTL_DSP_STEREO: | ||
370 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_STEREO:\n")); | ||
371 | break; | ||
372 | case SNDCTL_DSP_CHANNELS: | ||
373 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_CHANNELS:\n")); | ||
374 | break; | ||
375 | case SNDCTL_DSP_GETFMTS: | ||
376 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETFMTS:\n")); | ||
377 | break; | ||
378 | case SNDCTL_DSP_SETFMT: | ||
379 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETFMT:\n")); | ||
380 | break; | ||
381 | case SNDCTL_DSP_POST: | ||
382 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_POST:\n")); | ||
383 | break; | ||
384 | case SNDCTL_DSP_GETTRIGGER: | ||
385 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETTRIGGER:\n")); | ||
386 | break; | ||
387 | case SNDCTL_DSP_SETTRIGGER: | ||
388 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETTRIGGER:\n")); | ||
389 | break; | ||
390 | case SNDCTL_DSP_GETOSPACE: | ||
391 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOSPACE:\n")); | ||
392 | break; | ||
393 | case SNDCTL_DSP_GETISPACE: | ||
394 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETISPACE:\n")); | ||
395 | break; | ||
396 | case SNDCTL_DSP_NONBLOCK: | ||
397 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_NONBLOCK:\n")); | ||
398 | break; | ||
399 | case SNDCTL_DSP_GETODELAY: | ||
400 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETODELAY:\n")); | ||
401 | break; | ||
402 | case SNDCTL_DSP_GETIPTR: | ||
403 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETIPTR:\n")); | ||
404 | break; | ||
405 | case SNDCTL_DSP_GETOPTR: | ||
406 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETOPTR:\n")); | ||
407 | break; | ||
408 | case SNDCTL_DSP_GETBLKSIZE: | ||
409 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_GETBLKSIZE:\n")); | ||
410 | break; | ||
411 | case SNDCTL_DSP_SETFRAGMENT: | ||
412 | CS_DBGOUT(CS_IOCTL, 4, | ||
413 | printk("SNDCTL_DSP_SETFRAGMENT:\n")); | ||
414 | break; | ||
415 | case SNDCTL_DSP_SUBDIVIDE: | ||
416 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SUBDIVIDE:\n")); | ||
417 | break; | ||
418 | case SOUND_PCM_READ_RATE: | ||
419 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_RATE:\n")); | ||
420 | break; | ||
421 | case SOUND_PCM_READ_CHANNELS: | ||
422 | CS_DBGOUT(CS_IOCTL, 4, | ||
423 | printk("SOUND_PCM_READ_CHANNELS:\n")); | ||
424 | break; | ||
425 | case SOUND_PCM_READ_BITS: | ||
426 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_BITS:\n")); | ||
427 | break; | ||
428 | case SOUND_PCM_WRITE_FILTER: | ||
429 | CS_DBGOUT(CS_IOCTL, 4, | ||
430 | printk("SOUND_PCM_WRITE_FILTER:\n")); | ||
431 | break; | ||
432 | case SNDCTL_DSP_SETSYNCRO: | ||
433 | CS_DBGOUT(CS_IOCTL, 4, printk("SNDCTL_DSP_SETSYNCRO:\n")); | ||
434 | break; | ||
435 | case SOUND_PCM_READ_FILTER: | ||
436 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_PCM_READ_FILTER:\n")); | ||
437 | break; | ||
438 | case SOUND_MIXER_PRIVATE1: | ||
439 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE1:\n")); | ||
440 | break; | ||
441 | case SOUND_MIXER_PRIVATE2: | ||
442 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE2:\n")); | ||
443 | break; | ||
444 | case SOUND_MIXER_PRIVATE3: | ||
445 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE3:\n")); | ||
446 | break; | ||
447 | case SOUND_MIXER_PRIVATE4: | ||
448 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE4:\n")); | ||
449 | break; | ||
450 | case SOUND_MIXER_PRIVATE5: | ||
451 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_PRIVATE5:\n")); | ||
452 | break; | ||
453 | case SOUND_MIXER_INFO: | ||
454 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_INFO:\n")); | ||
455 | break; | ||
456 | case SOUND_OLD_MIXER_INFO: | ||
457 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_OLD_MIXER_INFO:\n")); | ||
458 | break; | ||
459 | |||
460 | default: | ||
461 | switch (_IOC_NR(x)) { | ||
462 | case SOUND_MIXER_VOLUME: | ||
463 | CS_DBGOUT(CS_IOCTL, 4, | ||
464 | printk("SOUND_MIXER_VOLUME:\n")); | ||
465 | break; | ||
466 | case SOUND_MIXER_SPEAKER: | ||
467 | CS_DBGOUT(CS_IOCTL, 4, | ||
468 | printk("SOUND_MIXER_SPEAKER:\n")); | ||
469 | break; | ||
470 | case SOUND_MIXER_RECLEV: | ||
471 | CS_DBGOUT(CS_IOCTL, 4, | ||
472 | printk("SOUND_MIXER_RECLEV:\n")); | ||
473 | break; | ||
474 | case SOUND_MIXER_MIC: | ||
475 | CS_DBGOUT(CS_IOCTL, 4, | ||
476 | printk("SOUND_MIXER_MIC:\n")); | ||
477 | break; | ||
478 | case SOUND_MIXER_SYNTH: | ||
479 | CS_DBGOUT(CS_IOCTL, 4, | ||
480 | printk("SOUND_MIXER_SYNTH:\n")); | ||
481 | break; | ||
482 | case SOUND_MIXER_RECSRC: | ||
483 | CS_DBGOUT(CS_IOCTL, 4, | ||
484 | printk("SOUND_MIXER_RECSRC:\n")); | ||
485 | break; | ||
486 | case SOUND_MIXER_DEVMASK: | ||
487 | CS_DBGOUT(CS_IOCTL, 4, | ||
488 | printk("SOUND_MIXER_DEVMASK:\n")); | ||
489 | break; | ||
490 | case SOUND_MIXER_RECMASK: | ||
491 | CS_DBGOUT(CS_IOCTL, 4, | ||
492 | printk("SOUND_MIXER_RECMASK:\n")); | ||
493 | break; | ||
494 | case SOUND_MIXER_STEREODEVS: | ||
495 | CS_DBGOUT(CS_IOCTL, 4, | ||
496 | printk("SOUND_MIXER_STEREODEVS:\n")); | ||
497 | break; | ||
498 | case SOUND_MIXER_CAPS: | ||
499 | CS_DBGOUT(CS_IOCTL, 4, printk("SOUND_MIXER_CAPS:\n")); | ||
500 | break; | ||
501 | default: | ||
502 | i = _IOC_NR(x); | ||
503 | if (i >= SOUND_MIXER_NRDEVICES | ||
504 | || !(vidx = mixtable1[i])) { | ||
505 | CS_DBGOUT(CS_IOCTL, 4, printk | ||
506 | ("UNKNOWN IOCTL: 0x%.8x NR=%d\n", | ||
507 | x, i)); | ||
508 | } else { | ||
509 | CS_DBGOUT(CS_IOCTL, 4, printk | ||
510 | ("SOUND_MIXER_IOCTL AC9x: 0x%.8x NR=%d\n", | ||
511 | x, i)); | ||
512 | } | ||
513 | break; | ||
514 | } | ||
515 | } | ||
516 | } | ||
517 | #endif | ||
518 | static int prog_dmabuf_adc(struct cs4281_state *s); | ||
519 | static void prog_codec(struct cs4281_state *s, unsigned type); | ||
520 | |||
521 | // --------------------------------------------------------------------- | ||
522 | // | ||
523 | // Hardware Interfaces For the CS4281 | ||
524 | // | ||
525 | |||
526 | |||
527 | //****************************************************************************** | ||
528 | // "delayus()-- Delay for the specified # of microseconds. | ||
529 | //****************************************************************************** | ||
530 | static void delayus(struct cs4281_state *s, u32 delay) | ||
531 | { | ||
532 | u32 j; | ||
533 | if ((delay > 9999) && (s->pm.flags & CS4281_PM_IDLE)) { | ||
534 | j = (delay * HZ) / 1000000; /* calculate delay in jiffies */ | ||
535 | if (j < 1) | ||
536 | j = 1; /* minimum one jiffy. */ | ||
537 | current->state = TASK_UNINTERRUPTIBLE; | ||
538 | schedule_timeout(j); | ||
539 | } else | ||
540 | udelay(delay); | ||
541 | return; | ||
542 | } | ||
543 | |||
544 | |||
545 | //****************************************************************************** | ||
546 | // "cs4281_read_ac97" -- Reads a word from the specified location in the | ||
547 | // CS4281's address space(based on the BA0 register). | ||
548 | // | ||
549 | // 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address | ||
550 | // 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 register, | ||
551 | // 0h for reads. | ||
552 | // 3. Write ACCTL = Control Register = 460h for initiating the write | ||
553 | // 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h | ||
554 | // 5. if DCV not cleared, break and return error | ||
555 | // 6. Read ACSTS = Status Register = 464h, check VSTS bit | ||
556 | //**************************************************************************** | ||
557 | static int cs4281_read_ac97(struct cs4281_state *card, u32 offset, | ||
558 | u32 * value) | ||
559 | { | ||
560 | u32 count, status; | ||
561 | |||
562 | // Make sure that there is not data sitting | ||
563 | // around from a previous uncompleted access. | ||
564 | // ACSDA = Status Data Register = 47Ch | ||
565 | status = readl(card->pBA0 + BA0_ACSDA); | ||
566 | |||
567 | // Setup the AC97 control registers on the CS4281 to send the | ||
568 | // appropriate command to the AC97 to perform the read. | ||
569 | // ACCAD = Command Address Register = 46Ch | ||
570 | // ACCDA = Command Data Register = 470h | ||
571 | // ACCTL = Control Register = 460h | ||
572 | // bit DCV - will clear when process completed | ||
573 | // bit CRW - Read command | ||
574 | // bit VFRM - valid frame enabled | ||
575 | // bit ESYN - ASYNC generation enabled | ||
576 | |||
577 | // Get the actual AC97 register from the offset | ||
578 | writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD); | ||
579 | writel(0, card->pBA0 + BA0_ACCDA); | ||
580 | writel(ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN, | ||
581 | card->pBA0 + BA0_ACCTL); | ||
582 | |||
583 | // Wait for the read to occur. | ||
584 | for (count = 0; count < 10; count++) { | ||
585 | // First, we want to wait for a short time. | ||
586 | udelay(25); | ||
587 | |||
588 | // Now, check to see if the read has completed. | ||
589 | // ACCTL = 460h, DCV should be reset by now and 460h = 17h | ||
590 | if (!(readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV)) | ||
591 | break; | ||
592 | } | ||
593 | |||
594 | // Make sure the read completed. | ||
595 | if (readl(card->pBA0 + BA0_ACCTL) & ACCTL_DCV) | ||
596 | return 1; | ||
597 | |||
598 | // Wait for the valid status bit to go active. | ||
599 | for (count = 0; count < 10; count++) { | ||
600 | // Read the AC97 status register. | ||
601 | // ACSTS = Status Register = 464h | ||
602 | status = readl(card->pBA0 + BA0_ACSTS); | ||
603 | |||
604 | // See if we have valid status. | ||
605 | // VSTS - Valid Status | ||
606 | if (status & ACSTS_VSTS) | ||
607 | break; | ||
608 | // Wait for a short while. | ||
609 | udelay(25); | ||
610 | } | ||
611 | |||
612 | // Make sure we got valid status. | ||
613 | if (!(status & ACSTS_VSTS)) | ||
614 | return 1; | ||
615 | |||
616 | // Read the data returned from the AC97 register. | ||
617 | // ACSDA = Status Data Register = 474h | ||
618 | *value = readl(card->pBA0 + BA0_ACSDA); | ||
619 | |||
620 | // Success. | ||
621 | return (0); | ||
622 | } | ||
623 | |||
624 | |||
625 | //**************************************************************************** | ||
626 | // | ||
627 | // "cs4281_write_ac97()"-- writes a word to the specified location in the | ||
628 | // CS461x's address space (based on the part's base address zero register). | ||
629 | // | ||
630 | // 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address | ||
631 | // 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 reg. | ||
632 | // 3. Write ACCTL = Control Register = 460h for initiating the write | ||
633 | // 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h | ||
634 | // 5. if DCV not cleared, break and return error | ||
635 | // | ||
636 | //**************************************************************************** | ||
637 | static int cs4281_write_ac97(struct cs4281_state *card, u32 offset, | ||
638 | u32 value) | ||
639 | { | ||
640 | u32 count, status=0; | ||
641 | |||
642 | CS_DBGOUT(CS_FUNCTION, 2, | ||
643 | printk(KERN_INFO "cs4281: cs_4281_write_ac97()+ \n")); | ||
644 | |||
645 | // Setup the AC97 control registers on the CS4281 to send the | ||
646 | // appropriate command to the AC97 to perform the read. | ||
647 | // ACCAD = Command Address Register = 46Ch | ||
648 | // ACCDA = Command Data Register = 470h | ||
649 | // ACCTL = Control Register = 460h | ||
650 | // set DCV - will clear when process completed | ||
651 | // reset CRW - Write command | ||
652 | // set VFRM - valid frame enabled | ||
653 | // set ESYN - ASYNC generation enabled | ||
654 | // set RSTN - ARST# inactive, AC97 codec not reset | ||
655 | |||
656 | // Get the actual AC97 register from the offset | ||
657 | |||
658 | writel(offset - BA0_AC97_RESET, card->pBA0 + BA0_ACCAD); | ||
659 | writel(value, card->pBA0 + BA0_ACCDA); | ||
660 | writel(ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN, | ||
661 | card->pBA0 + BA0_ACCTL); | ||
662 | |||
663 | // Wait for the write to occur. | ||
664 | for (count = 0; count < 100; count++) { | ||
665 | // First, we want to wait for a short time. | ||
666 | udelay(25); | ||
667 | // Now, check to see if the write has completed. | ||
668 | // ACCTL = 460h, DCV should be reset by now and 460h = 07h | ||
669 | status = readl(card->pBA0 + BA0_ACCTL); | ||
670 | if (!(status & ACCTL_DCV)) | ||
671 | break; | ||
672 | } | ||
673 | |||
674 | // Make sure the write completed. | ||
675 | if (status & ACCTL_DCV) { | ||
676 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO | ||
677 | "cs4281: cs_4281_write_ac97()- unable to write. ACCTL_DCV active\n")); | ||
678 | return 1; | ||
679 | } | ||
680 | CS_DBGOUT(CS_FUNCTION, 2, | ||
681 | printk(KERN_INFO "cs4281: cs_4281_write_ac97()- 0\n")); | ||
682 | // Success. | ||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | |||
687 | //****************************************************************************** | ||
688 | // "Init4281()" -- Bring up the part. | ||
689 | //****************************************************************************** | ||
690 | static __devinit int cs4281_hw_init(struct cs4281_state *card) | ||
691 | { | ||
692 | u32 ac97_slotid; | ||
693 | u32 temp1, temp2; | ||
694 | |||
695 | CS_DBGOUT(CS_FUNCTION, 2, | ||
696 | printk(KERN_INFO "cs4281: cs4281_hw_init()+ \n")); | ||
697 | #ifndef NOT_CS4281_PM | ||
698 | if(!card) | ||
699 | return 1; | ||
700 | #endif | ||
701 | temp2 = readl(card->pBA0 + BA0_CFLR); | ||
702 | CS_DBGOUT(CS_INIT | CS_ERROR | CS_PARMS, 4, printk(KERN_INFO | ||
703 | "cs4281: cs4281_hw_init() CFLR 0x%x\n", temp2)); | ||
704 | if(temp2 != CS4281_CFLR_DEFAULT) | ||
705 | { | ||
706 | CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO | ||
707 | "cs4281: cs4281_hw_init() CFLR invalid - resetting from 0x%x to 0x%x\n", | ||
708 | temp2,CS4281_CFLR_DEFAULT)); | ||
709 | writel(CS4281_CFLR_DEFAULT, card->pBA0 + BA0_CFLR); | ||
710 | temp2 = readl(card->pBA0 + BA0_CFLR); | ||
711 | if(temp2 != CS4281_CFLR_DEFAULT) | ||
712 | { | ||
713 | CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO | ||
714 | "cs4281: cs4281_hw_init() Invalid hardware - unable to configure CFLR\n")); | ||
715 | return 1; | ||
716 | } | ||
717 | } | ||
718 | |||
719 | //***************************************7 | ||
720 | // Set up the Sound System Configuration | ||
721 | //*************************************** | ||
722 | |||
723 | // Set the 'Configuration Write Protect' register | ||
724 | // to 4281h. Allows vendor-defined configuration | ||
725 | // space between 0e4h and 0ffh to be written. | ||
726 | |||
727 | writel(0x4281, card->pBA0 + BA0_CWPR); // (3e0h) | ||
728 | |||
729 | // (0), Blast the clock control register to zero so that the | ||
730 | // PLL starts out in a known state, and blast the master serial | ||
731 | // port control register to zero so that the serial ports also | ||
732 | // start out in a known state. | ||
733 | |||
734 | writel(0, card->pBA0 + BA0_CLKCR1); // (400h) | ||
735 | writel(0, card->pBA0 + BA0_SERMC); // (420h) | ||
736 | |||
737 | |||
738 | // (1), Make ESYN go to zero to turn off | ||
739 | // the Sync pulse on the AC97 link. | ||
740 | |||
741 | writel(0, card->pBA0 + BA0_ACCTL); | ||
742 | udelay(50); | ||
743 | |||
744 | |||
745 | // (2) Drive the ARST# pin low for a minimum of 1uS (as defined in | ||
746 | // the AC97 spec) and then drive it high. This is done for non | ||
747 | // AC97 modes since there might be logic external to the CS461x | ||
748 | // that uses the ARST# line for a reset. | ||
749 | |||
750 | writel(0, card->pBA0 + BA0_SPMC); // (3ech) | ||
751 | udelay(100); | ||
752 | writel(SPMC_RSTN, card->pBA0 + BA0_SPMC); | ||
753 | delayus(card,50000); // Wait 50 ms for ABITCLK to become stable. | ||
754 | |||
755 | // (3) Turn on the Sound System Clocks. | ||
756 | writel(CLKCR1_PLLP, card->pBA0 + BA0_CLKCR1); // (400h) | ||
757 | delayus(card,50000); // Wait for the PLL to stabilize. | ||
758 | // Turn on clocking of the core (CLKCR1(400h) = 0x00000030) | ||
759 | writel(CLKCR1_PLLP | CLKCR1_SWCE, card->pBA0 + BA0_CLKCR1); | ||
760 | |||
761 | // (4) Power on everything for now.. | ||
762 | writel(0x7E, card->pBA0 + BA0_SSPM); // (740h) | ||
763 | |||
764 | // (5) Wait for clock stabilization. | ||
765 | for (temp1 = 0; temp1 < 1000; temp1++) { | ||
766 | udelay(1000); | ||
767 | if (readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY) | ||
768 | break; | ||
769 | } | ||
770 | if (!(readl(card->pBA0 + BA0_CLKCR1) & CLKCR1_DLLRDY)) { | ||
771 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR | ||
772 | "cs4281: DLLRDY failed!\n")); | ||
773 | return -EIO; | ||
774 | } | ||
775 | // (6) Enable ASYNC generation. | ||
776 | writel(ACCTL_ESYN, card->pBA0 + BA0_ACCTL); // (460h) | ||
777 | |||
778 | // Now wait 'for a short while' to allow the AC97 | ||
779 | // part to start generating bit clock. (so we don't | ||
780 | // Try to start the PLL without an input clock.) | ||
781 | delayus(card,50000); | ||
782 | |||
783 | // Set the serial port timing configuration, so that the | ||
784 | // clock control circuit gets its clock from the right place. | ||
785 | writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC); // (420h)=2. | ||
786 | |||
787 | // (7) Wait for the codec ready signal from the AC97 codec. | ||
788 | |||
789 | for (temp1 = 0; temp1 < 1000; temp1++) { | ||
790 | // Delay a mil to let things settle out and | ||
791 | // to prevent retrying the read too quickly. | ||
792 | udelay(1000); | ||
793 | if (readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY) // If ready, (464h) | ||
794 | break; // exit the 'for' loop. | ||
795 | } | ||
796 | if (!(readl(card->pBA0 + BA0_ACSTS) & ACSTS_CRDY)) // If never came ready, | ||
797 | { | ||
798 | CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR | ||
799 | "cs4281: ACSTS never came ready!\n")); | ||
800 | return -EIO; // exit initialization. | ||
801 | } | ||
802 | // (8) Assert the 'valid frame' signal so we can | ||
803 | // begin sending commands to the AC97 codec. | ||
804 | writel(ACCTL_VFRM | ACCTL_ESYN, card->pBA0 + BA0_ACCTL); // (460h) | ||
805 | |||
806 | // (9), Wait until CODEC calibration is finished. | ||
807 | // Print an error message if it doesn't. | ||
808 | for (temp1 = 0; temp1 < 1000; temp1++) { | ||
809 | delayus(card,10000); | ||
810 | // Read the AC97 Powerdown Control/Status Register. | ||
811 | cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp2); | ||
812 | if ((temp2 & 0x0000000F) == 0x0000000F) | ||
813 | break; | ||
814 | } | ||
815 | if ((temp2 & 0x0000000F) != 0x0000000F) { | ||
816 | CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR | ||
817 | "cs4281: Codec failed to calibrate. Status = %.8x.\n", | ||
818 | temp2)); | ||
819 | return -EIO; | ||
820 | } | ||
821 | // (10), Set the serial port timing configuration, so that the | ||
822 | // clock control circuit gets its clock from the right place. | ||
823 | writel(SERMC_PTC_AC97, card->pBA0 + BA0_SERMC); // (420h)=2. | ||
824 | |||
825 | |||
826 | // (11) Wait until we've sampled input slots 3 & 4 as valid, meaning | ||
827 | // that the codec is pumping ADC data across the AC link. | ||
828 | for (temp1 = 0; temp1 < 1000; temp1++) { | ||
829 | // Delay a mil to let things settle out and | ||
830 | // to prevent retrying the read too quickly. | ||
831 | delayus(card,1000); //(test) | ||
832 | |||
833 | // Read the input slot valid register; See | ||
834 | // if input slots 3 and 4 are valid yet. | ||
835 | if ( | ||
836 | (readl(card->pBA0 + BA0_ACISV) & | ||
837 | (ACISV_ISV3 | ACISV_ISV4)) == | ||
838 | (ACISV_ISV3 | ACISV_ISV4)) break; // Exit the 'for' if slots are valid. | ||
839 | } | ||
840 | // If we never got valid data, exit initialization. | ||
841 | if ((readl(card->pBA0 + BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) | ||
842 | != (ACISV_ISV3 | ACISV_ISV4)) { | ||
843 | CS_DBGOUT(CS_FUNCTION, 2, | ||
844 | printk(KERN_ERR | ||
845 | "cs4281: Never got valid data!\n")); | ||
846 | return -EIO; // If no valid data, exit initialization. | ||
847 | } | ||
848 | // (12), Start digital data transfer of audio data to the codec. | ||
849 | writel(ACOSV_SLV3 | ACOSV_SLV4, card->pBA0 + BA0_ACOSV); // (468h) | ||
850 | |||
851 | |||
852 | //************************************** | ||
853 | // Unmute the Master and Alternate | ||
854 | // (headphone) volumes. Set to max. | ||
855 | //************************************** | ||
856 | cs4281_write_ac97(card, BA0_AC97_HEADPHONE_VOLUME, 0); | ||
857 | cs4281_write_ac97(card, BA0_AC97_MASTER_VOLUME, 0); | ||
858 | |||
859 | //****************************************** | ||
860 | // Power on the DAC(AddDACUser()from main()) | ||
861 | //****************************************** | ||
862 | cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1); | ||
863 | cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfdff); | ||
864 | |||
865 | // Wait until we sample a DAC ready state. | ||
866 | for (temp2 = 0; temp2 < 32; temp2++) { | ||
867 | // Let's wait a mil to let things settle. | ||
868 | delayus(card,1000); | ||
869 | // Read the current state of the power control reg. | ||
870 | cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1); | ||
871 | // If the DAC ready state bit is set, stop waiting. | ||
872 | if (temp1 & 0x2) | ||
873 | break; | ||
874 | } | ||
875 | |||
876 | //****************************************** | ||
877 | // Power on the ADC(AddADCUser()from main()) | ||
878 | //****************************************** | ||
879 | cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1); | ||
880 | cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfeff); | ||
881 | |||
882 | // Wait until we sample ADC ready state. | ||
883 | for (temp2 = 0; temp2 < 32; temp2++) { | ||
884 | // Let's wait a mil to let things settle. | ||
885 | delayus(card,1000); | ||
886 | // Read the current state of the power control reg. | ||
887 | cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1); | ||
888 | // If the ADC ready state bit is set, stop waiting. | ||
889 | if (temp1 & 0x1) | ||
890 | break; | ||
891 | } | ||
892 | // Set up 4281 Register contents that | ||
893 | // don't change for boot duration. | ||
894 | |||
895 | // For playback, we map AC97 slot 3 and 4(Left | ||
896 | // & Right PCM playback) to DMA Channel 0. | ||
897 | // Set the fifo to be 15 bytes at offset zero. | ||
898 | |||
899 | ac97_slotid = 0x01000f00; // FCR0.RS[4:0]=1(=>slot4, right PCM playback). | ||
900 | // FCR0.LS[4:0]=0(=>slot3, left PCM playback). | ||
901 | // FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0. | ||
902 | writel(ac97_slotid, card->pBA0 + BA0_FCR0); // (180h) | ||
903 | writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR0); // Turn on FIFO Enable. | ||
904 | |||
905 | // For capture, we map AC97 slot 10 and 11(Left | ||
906 | // and Right PCM Record) to DMA Channel 1. | ||
907 | // Set the fifo to be 15 bytes at offset sixteen. | ||
908 | ac97_slotid = 0x0B0A0f10; // FCR1.RS[4:0]=11(=>slot11, right PCM record). | ||
909 | // FCR1.LS[4:0]=10(=>slot10, left PCM record). | ||
910 | // FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16. | ||
911 | writel(ac97_slotid | FCRn_PSH, card->pBA0 + BA0_FCR1); // (184h) | ||
912 | writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR1); // Turn on FIFO Enable. | ||
913 | |||
914 | // Map the Playback SRC to the same AC97 slots(3 & 4-- | ||
915 | // --Playback left & right)as DMA channel 0. | ||
916 | // Map the record SRC to the same AC97 slots(10 & 11-- | ||
917 | // -- Record left & right) as DMA channel 1. | ||
918 | |||
919 | ac97_slotid = 0x0b0a0100; // SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback). | ||
920 | // SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback). | ||
921 | // SCRSA.CRSS[4:0]=11(=>slot11, right PCM record) | ||
922 | // SCRSA.CLSS[4:0]=10(=>slot10, left PCM record). | ||
923 | writel(ac97_slotid, card->pBA0 + BA0_SRCSA); // (75ch) | ||
924 | |||
925 | // Set 'Half Terminal Count Interrupt Enable' and 'Terminal | ||
926 | // Count Interrupt Enable' in DMA Control Registers 0 & 1. | ||
927 | // Set 'MSK' flag to 1 to keep the DMA engines paused. | ||
928 | temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK); // (00030001h) | ||
929 | writel(temp1, card->pBA0 + BA0_DCR0); // (154h | ||
930 | writel(temp1, card->pBA0 + BA0_DCR1); // (15ch) | ||
931 | |||
932 | // Set 'Auto-Initialize Control' to 'enabled'; For playback, | ||
933 | // set 'Transfer Type Control'(TR[1:0]) to 'read transfer', | ||
934 | // for record, set Transfer Type Control to 'write transfer'. | ||
935 | // All other bits set to zero; Some will be changed @ transfer start. | ||
936 | temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ); // (20000018h) | ||
937 | writel(temp1, card->pBA0 + BA0_DMR0); // (150h) | ||
938 | temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE); // (20000014h) | ||
939 | writel(temp1, card->pBA0 + BA0_DMR1); // (158h) | ||
940 | |||
941 | // Enable DMA interrupts generally, and | ||
942 | // DMA0 & DMA1 interrupts specifically. | ||
943 | temp1 = readl(card->pBA0 + BA0_HIMR) & 0xfffbfcff; | ||
944 | writel(temp1, card->pBA0 + BA0_HIMR); | ||
945 | |||
946 | CS_DBGOUT(CS_FUNCTION, 2, | ||
947 | printk(KERN_INFO "cs4281: cs4281_hw_init()- 0\n")); | ||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | #ifndef NOT_CS4281_PM | ||
952 | static void printpm(struct cs4281_state *s) | ||
953 | { | ||
954 | CS_DBGOUT(CS_PM, 9, printk("pm struct:\n")); | ||
955 | CS_DBGOUT(CS_PM, 9, printk("flags:0x%x u32CLKCR1_SAVE: 0%x u32SSPMValue: 0x%x\n", | ||
956 | (unsigned)s->pm.flags,s->pm.u32CLKCR1_SAVE,s->pm.u32SSPMValue)); | ||
957 | CS_DBGOUT(CS_PM, 9, printk("u32PPLVCvalue: 0x%x u32PPRVCvalue: 0x%x\n", | ||
958 | s->pm.u32PPLVCvalue,s->pm.u32PPRVCvalue)); | ||
959 | CS_DBGOUT(CS_PM, 9, printk("u32FMLVCvalue: 0x%x u32FMRVCvalue: 0x%x\n", | ||
960 | s->pm.u32FMLVCvalue,s->pm.u32FMRVCvalue)); | ||
961 | CS_DBGOUT(CS_PM, 9, printk("u32GPIORvalue: 0x%x u32JSCTLvalue: 0x%x\n", | ||
962 | s->pm.u32GPIORvalue,s->pm.u32JSCTLvalue)); | ||
963 | CS_DBGOUT(CS_PM, 9, printk("u32SSCR: 0x%x u32SRCSA: 0x%x\n", | ||
964 | s->pm.u32SSCR,s->pm.u32SRCSA)); | ||
965 | CS_DBGOUT(CS_PM, 9, printk("u32DacASR: 0x%x u32AdcASR: 0x%x\n", | ||
966 | s->pm.u32DacASR,s->pm.u32AdcASR)); | ||
967 | CS_DBGOUT(CS_PM, 9, printk("u32DacSR: 0x%x u32AdcSR: 0x%x\n", | ||
968 | s->pm.u32DacSR,s->pm.u32AdcSR)); | ||
969 | CS_DBGOUT(CS_PM, 9, printk("u32MIDCR_Save: 0x%x\n", | ||
970 | s->pm.u32MIDCR_Save)); | ||
971 | |||
972 | } | ||
973 | static void printpipe(struct cs4281_pipeline *pl) | ||
974 | { | ||
975 | |||
976 | CS_DBGOUT(CS_PM, 9, printk("pm struct:\n")); | ||
977 | CS_DBGOUT(CS_PM, 9, printk("flags:0x%x number: 0%x\n", | ||
978 | (unsigned)pl->flags,pl->number)); | ||
979 | CS_DBGOUT(CS_PM, 9, printk("u32DBAnValue: 0%x u32DBCnValue: 0x%x\n", | ||
980 | pl->u32DBAnValue,pl->u32DBCnValue)); | ||
981 | CS_DBGOUT(CS_PM, 9, printk("u32DMRnValue: 0x%x u32DCRnValue: 0x%x\n", | ||
982 | pl->u32DMRnValue,pl->u32DCRnValue)); | ||
983 | CS_DBGOUT(CS_PM, 9, printk("u32DBAnAddress: 0x%x u32DBCnAddress: 0x%x\n", | ||
984 | pl->u32DBAnAddress,pl->u32DBCnAddress)); | ||
985 | CS_DBGOUT(CS_PM, 9, printk("u32DCAnAddress: 0x%x u32DCCnAddress: 0x%x\n", | ||
986 | pl->u32DCCnAddress,pl->u32DCCnAddress)); | ||
987 | CS_DBGOUT(CS_PM, 9, printk("u32DMRnAddress: 0x%x u32DCRnAddress: 0x%x\n", | ||
988 | pl->u32DMRnAddress,pl->u32DCRnAddress)); | ||
989 | CS_DBGOUT(CS_PM, 9, printk("u32HDSRnAddress: 0x%x u32DBAn_Save: 0x%x\n", | ||
990 | pl->u32HDSRnAddress,pl->u32DBAn_Save)); | ||
991 | CS_DBGOUT(CS_PM, 9, printk("u32DBCn_Save: 0x%x u32DMRn_Save: 0x%x\n", | ||
992 | pl->u32DBCn_Save,pl->u32DMRn_Save)); | ||
993 | CS_DBGOUT(CS_PM, 9, printk("u32DCRn_Save: 0x%x u32DCCn_Save: 0x%x\n", | ||
994 | pl->u32DCRn_Save,pl->u32DCCn_Save)); | ||
995 | CS_DBGOUT(CS_PM, 9, printk("u32DCAn_Save: 0x%x\n", | ||
996 | pl->u32DCAn_Save)); | ||
997 | CS_DBGOUT(CS_PM, 9, printk("u32FCRn_Save: 0x%x u32FSICn_Save: 0x%x\n", | ||
998 | pl->u32FCRn_Save,pl->u32FSICn_Save)); | ||
999 | CS_DBGOUT(CS_PM, 9, printk("u32FCRnValue: 0x%x u32FSICnValue: 0x%x\n", | ||
1000 | pl->u32FCRnValue,pl->u32FSICnValue)); | ||
1001 | CS_DBGOUT(CS_PM, 9, printk("u32FCRnAddress: 0x%x u32FSICnAddress: 0x%x\n", | ||
1002 | pl->u32FCRnAddress,pl->u32FSICnAddress)); | ||
1003 | CS_DBGOUT(CS_PM, 9, printk("u32FPDRnValue: 0x%x u32FPDRnAddress: 0x%x\n", | ||
1004 | pl->u32FPDRnValue,pl->u32FPDRnAddress)); | ||
1005 | } | ||
1006 | static void printpipelines(struct cs4281_state *s) | ||
1007 | { | ||
1008 | int i; | ||
1009 | for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++) | ||
1010 | { | ||
1011 | if(s->pl[i].flags & CS4281_PIPELINE_VALID) | ||
1012 | { | ||
1013 | printpipe(&s->pl[i]); | ||
1014 | } | ||
1015 | } | ||
1016 | } | ||
1017 | /**************************************************************************** | ||
1018 | * | ||
1019 | * Suspend - save the ac97 regs, mute the outputs and power down the part. | ||
1020 | * | ||
1021 | ****************************************************************************/ | ||
1022 | static void cs4281_ac97_suspend(struct cs4281_state *s) | ||
1023 | { | ||
1024 | int Count,i; | ||
1025 | |||
1026 | CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()+\n")); | ||
1027 | /* | ||
1028 | * change the state, save the current hwptr, then stop the dac/adc | ||
1029 | */ | ||
1030 | s->pm.flags &= ~CS4281_PM_IDLE; | ||
1031 | s->pm.flags |= CS4281_PM_SUSPENDING; | ||
1032 | s->pm.u32hwptr_playback = readl(s->pBA0 + BA0_DCA0); | ||
1033 | s->pm.u32hwptr_capture = readl(s->pBA0 + BA0_DCA1); | ||
1034 | stop_dac(s); | ||
1035 | stop_adc(s); | ||
1036 | |||
1037 | for(Count = 0x2, i=0; (Count <= CS4281_AC97_HIGHESTREGTORESTORE) | ||
1038 | && (i < CS4281_AC97_NUMBER_RESTORE_REGS); | ||
1039 | Count += 2, i++) | ||
1040 | { | ||
1041 | cs4281_read_ac97(s, BA0_AC97_RESET + Count, &s->pm.ac97[i]); | ||
1042 | } | ||
1043 | /* | ||
1044 | * Save the ac97 volume registers as well as the current powerdown state. | ||
1045 | * Now, mute the all the outputs (master, headphone, and mono), as well | ||
1046 | * as the PCM volume, in preparation for powering down the entire part. | ||
1047 | */ | ||
1048 | cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME, &s->pm.u32AC97_master_volume); | ||
1049 | cs4281_read_ac97(s, BA0_AC97_HEADPHONE_VOLUME, &s->pm.u32AC97_headphone_volume); | ||
1050 | cs4281_read_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, &s->pm.u32AC97_master_volume_mono); | ||
1051 | cs4281_read_ac97(s, BA0_AC97_PCM_OUT_VOLUME, &s->pm.u32AC97_pcm_out_volume); | ||
1052 | |||
1053 | cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, 0x8000); | ||
1054 | cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, 0x8000); | ||
1055 | cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME_MONO, 0x8000); | ||
1056 | cs4281_write_ac97(s, BA0_AC97_PCM_OUT_VOLUME, 0x8000); | ||
1057 | |||
1058 | cs4281_read_ac97(s, BA0_AC97_POWERDOWN, &s->pm.u32AC97_powerdown); | ||
1059 | cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE, &s->pm.u32AC97_general_purpose); | ||
1060 | |||
1061 | /* | ||
1062 | * And power down everything on the AC97 codec. | ||
1063 | */ | ||
1064 | cs4281_write_ac97(s, BA0_AC97_POWERDOWN, 0xff00); | ||
1065 | CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_suspend()-\n")); | ||
1066 | } | ||
1067 | |||
1068 | /**************************************************************************** | ||
1069 | * | ||
1070 | * Resume - power up the part and restore its registers.. | ||
1071 | * | ||
1072 | ****************************************************************************/ | ||
1073 | static void cs4281_ac97_resume(struct cs4281_state *s) | ||
1074 | { | ||
1075 | int Count,i; | ||
1076 | |||
1077 | CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()+\n")); | ||
1078 | |||
1079 | /* do not save the power state registers at this time | ||
1080 | // | ||
1081 | // If we saved away the power control registers, write them into the | ||
1082 | // shadows so those saved values get restored instead of the current | ||
1083 | // shadowed value. | ||
1084 | // | ||
1085 | if( bPowerStateSaved ) | ||
1086 | { | ||
1087 | PokeShadow( 0x26, ulSaveReg0x26 ); | ||
1088 | bPowerStateSaved = FALSE; | ||
1089 | } | ||
1090 | */ | ||
1091 | |||
1092 | // | ||
1093 | // First, we restore the state of the general purpose register. This | ||
1094 | // contains the mic select (mic1 or mic2) and if we restore this after | ||
1095 | // we restore the mic volume/boost state and mic2 was selected at | ||
1096 | // suspend time, we will end up with a brief period of time where mic1 | ||
1097 | // is selected with the volume/boost settings for mic2, causing | ||
1098 | // acoustic feedback. So we restore the general purpose register | ||
1099 | // first, thereby getting the correct mic selected before we restore | ||
1100 | // the mic volume/boost. | ||
1101 | // | ||
1102 | cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE, s->pm.u32AC97_general_purpose); | ||
1103 | |||
1104 | // | ||
1105 | // Now, while the outputs are still muted, restore the state of power | ||
1106 | // on the AC97 part. | ||
1107 | // | ||
1108 | cs4281_write_ac97(s, BA0_AC97_POWERDOWN, s->pm.u32AC97_powerdown); | ||
1109 | |||
1110 | /* | ||
1111 | * Restore just the first set of registers, from register number | ||
1112 | * 0x02 to the register number that ulHighestRegToRestore specifies. | ||
1113 | */ | ||
1114 | for( Count = 0x2, i=0; | ||
1115 | (Count <= CS4281_AC97_HIGHESTREGTORESTORE) | ||
1116 | && (i < CS4281_AC97_NUMBER_RESTORE_REGS); | ||
1117 | Count += 2, i++) | ||
1118 | { | ||
1119 | cs4281_write_ac97(s, BA0_AC97_RESET + Count, s->pm.ac97[i]); | ||
1120 | } | ||
1121 | CS_DBGOUT(CS_PM, 9, printk("cs4281: cs4281_ac97_resume()-\n")); | ||
1122 | } | ||
1123 | |||
1124 | /* do not save the power state registers at this time | ||
1125 | **************************************************************************** | ||
1126 | * | ||
1127 | * SavePowerState - Save the power registers away. | ||
1128 | * | ||
1129 | **************************************************************************** | ||
1130 | void | ||
1131 | HWAC97codec::SavePowerState(void) | ||
1132 | { | ||
1133 | ENTRY(TM_OBJECTCALLS, "HWAC97codec::SavePowerState()\r\n"); | ||
1134 | |||
1135 | ulSaveReg0x26 = PeekShadow(0x26); | ||
1136 | |||
1137 | // | ||
1138 | // Note that we have saved registers that need to be restored during a | ||
1139 | // resume instead of ulAC97Regs[]. | ||
1140 | // | ||
1141 | bPowerStateSaved = TRUE; | ||
1142 | |||
1143 | } // SavePowerState | ||
1144 | */ | ||
1145 | |||
1146 | static void cs4281_SuspendFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl) | ||
1147 | { | ||
1148 | /* | ||
1149 | * We need to save the contents of the BASIC FIFO Registers. | ||
1150 | */ | ||
1151 | pl->u32FCRn_Save = readl(s->pBA0 + pl->u32FCRnAddress); | ||
1152 | pl->u32FSICn_Save = readl(s->pBA0 + pl->u32FSICnAddress); | ||
1153 | } | ||
1154 | static void cs4281_ResumeFIFO(struct cs4281_state *s, struct cs4281_pipeline *pl) | ||
1155 | { | ||
1156 | /* | ||
1157 | * We need to restore the contents of the BASIC FIFO Registers. | ||
1158 | */ | ||
1159 | writel(pl->u32FCRn_Save,s->pBA0 + pl->u32FCRnAddress); | ||
1160 | writel(pl->u32FSICn_Save,s->pBA0 + pl->u32FSICnAddress); | ||
1161 | } | ||
1162 | static void cs4281_SuspendDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl) | ||
1163 | { | ||
1164 | // | ||
1165 | // We need to save the contents of the BASIC DMA Registers. | ||
1166 | // | ||
1167 | pl->u32DBAn_Save = readl(s->pBA0 + pl->u32DBAnAddress); | ||
1168 | pl->u32DBCn_Save = readl(s->pBA0 + pl->u32DBCnAddress); | ||
1169 | pl->u32DMRn_Save = readl(s->pBA0 + pl->u32DMRnAddress); | ||
1170 | pl->u32DCRn_Save = readl(s->pBA0 + pl->u32DCRnAddress); | ||
1171 | pl->u32DCCn_Save = readl(s->pBA0 + pl->u32DCCnAddress); | ||
1172 | pl->u32DCAn_Save = readl(s->pBA0 + pl->u32DCAnAddress); | ||
1173 | } | ||
1174 | static void cs4281_ResumeDMAengine(struct cs4281_state *s, struct cs4281_pipeline *pl) | ||
1175 | { | ||
1176 | // | ||
1177 | // We need to save the contents of the BASIC DMA Registers. | ||
1178 | // | ||
1179 | writel( pl->u32DBAn_Save, s->pBA0 + pl->u32DBAnAddress); | ||
1180 | writel( pl->u32DBCn_Save, s->pBA0 + pl->u32DBCnAddress); | ||
1181 | writel( pl->u32DMRn_Save, s->pBA0 + pl->u32DMRnAddress); | ||
1182 | writel( pl->u32DCRn_Save, s->pBA0 + pl->u32DCRnAddress); | ||
1183 | writel( pl->u32DCCn_Save, s->pBA0 + pl->u32DCCnAddress); | ||
1184 | writel( pl->u32DCAn_Save, s->pBA0 + pl->u32DCAnAddress); | ||
1185 | } | ||
1186 | |||
1187 | static int cs4281_suspend(struct cs4281_state *s) | ||
1188 | { | ||
1189 | int i; | ||
1190 | u32 u32CLKCR1; | ||
1191 | struct cs4281_pm *pm = &s->pm; | ||
1192 | CS_DBGOUT(CS_PM | CS_FUNCTION, 9, | ||
1193 | printk("cs4281: cs4281_suspend()+ flags=%d\n", | ||
1194 | (unsigned)s->pm.flags)); | ||
1195 | /* | ||
1196 | * check the current state, only suspend if IDLE | ||
1197 | */ | ||
1198 | if(!(s->pm.flags & CS4281_PM_IDLE)) | ||
1199 | { | ||
1200 | CS_DBGOUT(CS_PM | CS_ERROR, 2, | ||
1201 | printk("cs4281: cs4281_suspend() unable to suspend, not IDLE\n")); | ||
1202 | return 1; | ||
1203 | } | ||
1204 | s->pm.flags &= ~CS4281_PM_IDLE; | ||
1205 | s->pm.flags |= CS4281_PM_SUSPENDING; | ||
1206 | |||
1207 | // | ||
1208 | // Gershwin CLKRUN - Set CKRA | ||
1209 | // | ||
1210 | u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1); | ||
1211 | |||
1212 | pm->u32CLKCR1_SAVE = u32CLKCR1; | ||
1213 | if(!(u32CLKCR1 & 0x00010000 ) ) | ||
1214 | writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1); | ||
1215 | |||
1216 | // | ||
1217 | // First, turn on the clocks (yikes) to the devices, so that they will | ||
1218 | // respond when we try to save their state. | ||
1219 | // | ||
1220 | if(!(u32CLKCR1 & CLKCR1_SWCE)) | ||
1221 | { | ||
1222 | writel(u32CLKCR1 | CLKCR1_SWCE , s->pBA0 + BA0_CLKCR1); | ||
1223 | } | ||
1224 | |||
1225 | // | ||
1226 | // Save the power state | ||
1227 | // | ||
1228 | pm->u32SSPMValue = readl(s->pBA0 + BA0_SSPM); | ||
1229 | |||
1230 | // | ||
1231 | // Disable interrupts. | ||
1232 | // | ||
1233 | writel(HICR_CHGM, s->pBA0 + BA0_HICR); | ||
1234 | |||
1235 | // | ||
1236 | // Save the PCM Playback Left and Right Volume Control. | ||
1237 | // | ||
1238 | pm->u32PPLVCvalue = readl(s->pBA0 + BA0_PPLVC); | ||
1239 | pm->u32PPRVCvalue = readl(s->pBA0 + BA0_PPRVC); | ||
1240 | |||
1241 | // | ||
1242 | // Save the FM Synthesis Left and Right Volume Control. | ||
1243 | // | ||
1244 | pm->u32FMLVCvalue = readl(s->pBA0 + BA0_FMLVC); | ||
1245 | pm->u32FMRVCvalue = readl(s->pBA0 + BA0_FMRVC); | ||
1246 | |||
1247 | // | ||
1248 | // Save the GPIOR value. | ||
1249 | // | ||
1250 | pm->u32GPIORvalue = readl(s->pBA0 + BA0_GPIOR); | ||
1251 | |||
1252 | // | ||
1253 | // Save the JSCTL value. | ||
1254 | // | ||
1255 | pm->u32JSCTLvalue = readl(s->pBA0 + BA0_GPIOR); | ||
1256 | |||
1257 | // | ||
1258 | // Save Sound System Control Register | ||
1259 | // | ||
1260 | pm->u32SSCR = readl(s->pBA0 + BA0_SSCR); | ||
1261 | |||
1262 | // | ||
1263 | // Save SRC Slot Assinment register | ||
1264 | // | ||
1265 | pm->u32SRCSA = readl(s->pBA0 + BA0_SRCSA); | ||
1266 | |||
1267 | // | ||
1268 | // Save sample rate | ||
1269 | // | ||
1270 | pm->u32DacASR = readl(s->pBA0 + BA0_PASR); | ||
1271 | pm->u32AdcASR = readl(s->pBA0 + BA0_CASR); | ||
1272 | pm->u32DacSR = readl(s->pBA0 + BA0_DACSR); | ||
1273 | pm->u32AdcSR = readl(s->pBA0 + BA0_ADCSR); | ||
1274 | |||
1275 | // | ||
1276 | // Loop through all of the PipeLines | ||
1277 | // | ||
1278 | for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++) | ||
1279 | { | ||
1280 | if(s->pl[i].flags & CS4281_PIPELINE_VALID) | ||
1281 | { | ||
1282 | // | ||
1283 | // Ask the DMAengines and FIFOs to Suspend. | ||
1284 | // | ||
1285 | cs4281_SuspendDMAengine(s,&s->pl[i]); | ||
1286 | cs4281_SuspendFIFO(s,&s->pl[i]); | ||
1287 | } | ||
1288 | } | ||
1289 | // | ||
1290 | // We need to save the contents of the Midi Control Register. | ||
1291 | // | ||
1292 | pm->u32MIDCR_Save = readl(s->pBA0 + BA0_MIDCR); | ||
1293 | /* | ||
1294 | * save off the AC97 part information | ||
1295 | */ | ||
1296 | cs4281_ac97_suspend(s); | ||
1297 | |||
1298 | // | ||
1299 | // Turn off the serial ports. | ||
1300 | // | ||
1301 | writel(0, s->pBA0 + BA0_SERMC); | ||
1302 | |||
1303 | // | ||
1304 | // Power off FM, Joystick, AC link, | ||
1305 | // | ||
1306 | writel(0, s->pBA0 + BA0_SSPM); | ||
1307 | |||
1308 | // | ||
1309 | // DLL off. | ||
1310 | // | ||
1311 | writel(0, s->pBA0 + BA0_CLKCR1); | ||
1312 | |||
1313 | // | ||
1314 | // AC link off. | ||
1315 | // | ||
1316 | writel(0, s->pBA0 + BA0_SPMC); | ||
1317 | |||
1318 | // | ||
1319 | // Put the chip into D3(hot) state. | ||
1320 | // | ||
1321 | // PokeBA0(BA0_PMCS, 0x00000003); | ||
1322 | |||
1323 | // | ||
1324 | // Gershwin CLKRUN - Clear CKRA | ||
1325 | // | ||
1326 | u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1); | ||
1327 | writel(u32CLKCR1 & 0xFFFEFFFF, s->pBA0 + BA0_CLKCR1); | ||
1328 | |||
1329 | #ifdef CSDEBUG | ||
1330 | printpm(s); | ||
1331 | printpipelines(s); | ||
1332 | #endif | ||
1333 | |||
1334 | s->pm.flags &= ~CS4281_PM_SUSPENDING; | ||
1335 | s->pm.flags |= CS4281_PM_SUSPENDED; | ||
1336 | |||
1337 | CS_DBGOUT(CS_PM | CS_FUNCTION, 9, | ||
1338 | printk("cs4281: cs4281_suspend()- flags=%d\n", | ||
1339 | (unsigned)s->pm.flags)); | ||
1340 | return 0; | ||
1341 | } | ||
1342 | |||
1343 | static int cs4281_resume(struct cs4281_state *s) | ||
1344 | { | ||
1345 | int i; | ||
1346 | unsigned temp1; | ||
1347 | u32 u32CLKCR1; | ||
1348 | struct cs4281_pm *pm = &s->pm; | ||
1349 | CS_DBGOUT(CS_PM | CS_FUNCTION, 4, | ||
1350 | printk( "cs4281: cs4281_resume()+ flags=%d\n", | ||
1351 | (unsigned)s->pm.flags)); | ||
1352 | if(!(s->pm.flags & CS4281_PM_SUSPENDED)) | ||
1353 | { | ||
1354 | CS_DBGOUT(CS_PM | CS_ERROR, 2, | ||
1355 | printk("cs4281: cs4281_resume() unable to resume, not SUSPENDED\n")); | ||
1356 | return 1; | ||
1357 | } | ||
1358 | s->pm.flags &= ~CS4281_PM_SUSPENDED; | ||
1359 | s->pm.flags |= CS4281_PM_RESUMING; | ||
1360 | |||
1361 | // | ||
1362 | // Gershwin CLKRUN - Set CKRA | ||
1363 | // | ||
1364 | u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1); | ||
1365 | writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1); | ||
1366 | |||
1367 | // | ||
1368 | // set the power state. | ||
1369 | // | ||
1370 | //old PokeBA0(BA0_PMCS, 0); | ||
1371 | |||
1372 | // | ||
1373 | // Program the clock circuit and serial ports. | ||
1374 | // | ||
1375 | temp1 = cs4281_hw_init(s); | ||
1376 | if (temp1) { | ||
1377 | CS_DBGOUT(CS_ERROR | CS_INIT, 1, | ||
1378 | printk(KERN_ERR | ||
1379 | "cs4281: resume cs4281_hw_init() error.\n")); | ||
1380 | return -1; | ||
1381 | } | ||
1382 | |||
1383 | // | ||
1384 | // restore the Power state | ||
1385 | // | ||
1386 | writel(pm->u32SSPMValue, s->pBA0 + BA0_SSPM); | ||
1387 | |||
1388 | // | ||
1389 | // Set post SRC mix setting (FM or ALT48K) | ||
1390 | // | ||
1391 | writel(pm->u32SSPM_BITS, s->pBA0 + BA0_SSPM); | ||
1392 | |||
1393 | // | ||
1394 | // Loop through all of the PipeLines | ||
1395 | // | ||
1396 | for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++) | ||
1397 | { | ||
1398 | if(s->pl[i].flags & CS4281_PIPELINE_VALID) | ||
1399 | { | ||
1400 | // | ||
1401 | // Ask the DMAengines and FIFOs to Resume. | ||
1402 | // | ||
1403 | cs4281_ResumeDMAengine(s,&s->pl[i]); | ||
1404 | cs4281_ResumeFIFO(s,&s->pl[i]); | ||
1405 | } | ||
1406 | } | ||
1407 | // | ||
1408 | // We need to restore the contents of the Midi Control Register. | ||
1409 | // | ||
1410 | writel(pm->u32MIDCR_Save, s->pBA0 + BA0_MIDCR); | ||
1411 | |||
1412 | cs4281_ac97_resume(s); | ||
1413 | // | ||
1414 | // Restore the PCM Playback Left and Right Volume Control. | ||
1415 | // | ||
1416 | writel(pm->u32PPLVCvalue, s->pBA0 + BA0_PPLVC); | ||
1417 | writel(pm->u32PPRVCvalue, s->pBA0 + BA0_PPRVC); | ||
1418 | |||
1419 | // | ||
1420 | // Restore the FM Synthesis Left and Right Volume Control. | ||
1421 | // | ||
1422 | writel(pm->u32FMLVCvalue, s->pBA0 + BA0_FMLVC); | ||
1423 | writel(pm->u32FMRVCvalue, s->pBA0 + BA0_FMRVC); | ||
1424 | |||
1425 | // | ||
1426 | // Restore the JSCTL value. | ||
1427 | // | ||
1428 | writel(pm->u32JSCTLvalue, s->pBA0 + BA0_JSCTL); | ||
1429 | |||
1430 | // | ||
1431 | // Restore the GPIOR register value. | ||
1432 | // | ||
1433 | writel(pm->u32GPIORvalue, s->pBA0 + BA0_GPIOR); | ||
1434 | |||
1435 | // | ||
1436 | // Restore Sound System Control Register | ||
1437 | // | ||
1438 | writel(pm->u32SSCR, s->pBA0 + BA0_SSCR); | ||
1439 | |||
1440 | // | ||
1441 | // Restore SRC Slot Assignment register | ||
1442 | // | ||
1443 | writel(pm->u32SRCSA, s->pBA0 + BA0_SRCSA); | ||
1444 | |||
1445 | // | ||
1446 | // Restore sample rate | ||
1447 | // | ||
1448 | writel(pm->u32DacASR, s->pBA0 + BA0_PASR); | ||
1449 | writel(pm->u32AdcASR, s->pBA0 + BA0_CASR); | ||
1450 | writel(pm->u32DacSR, s->pBA0 + BA0_DACSR); | ||
1451 | writel(pm->u32AdcSR, s->pBA0 + BA0_ADCSR); | ||
1452 | |||
1453 | // | ||
1454 | // Restore CFL1/2 registers we saved to compensate for OEM bugs. | ||
1455 | // | ||
1456 | // PokeBA0(BA0_CFLR, ulConfig); | ||
1457 | |||
1458 | // | ||
1459 | // Gershwin CLKRUN - Clear CKRA | ||
1460 | // | ||
1461 | writel(pm->u32CLKCR1_SAVE, s->pBA0 + BA0_CLKCR1); | ||
1462 | |||
1463 | // | ||
1464 | // Enable interrupts on the part. | ||
1465 | // | ||
1466 | writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR); | ||
1467 | |||
1468 | #ifdef CSDEBUG | ||
1469 | printpm(s); | ||
1470 | printpipelines(s); | ||
1471 | #endif | ||
1472 | /* | ||
1473 | * change the state, restore the current hwptrs, then stop the dac/adc | ||
1474 | */ | ||
1475 | s->pm.flags |= CS4281_PM_IDLE; | ||
1476 | s->pm.flags &= ~(CS4281_PM_SUSPENDING | CS4281_PM_SUSPENDED | ||
1477 | | CS4281_PM_RESUMING | CS4281_PM_RESUMED); | ||
1478 | |||
1479 | writel(s->pm.u32hwptr_playback, s->pBA0 + BA0_DCA0); | ||
1480 | writel(s->pm.u32hwptr_capture, s->pBA0 + BA0_DCA1); | ||
1481 | start_dac(s); | ||
1482 | start_adc(s); | ||
1483 | |||
1484 | CS_DBGOUT(CS_PM | CS_FUNCTION, 9, printk("cs4281: cs4281_resume()- flags=%d\n", | ||
1485 | (unsigned)s->pm.flags)); | ||
1486 | return 0; | ||
1487 | } | ||
1488 | |||
1489 | #endif | ||
1490 | |||
1491 | //****************************************************************************** | ||
1492 | // "cs4281_play_rate()" -- | ||
1493 | //****************************************************************************** | ||
1494 | static void cs4281_play_rate(struct cs4281_state *card, u32 playrate) | ||
1495 | { | ||
1496 | u32 DACSRvalue = 1; | ||
1497 | |||
1498 | // Based on the sample rate, program the DACSR register. | ||
1499 | if (playrate == 8000) | ||
1500 | DACSRvalue = 5; | ||
1501 | if (playrate == 11025) | ||
1502 | DACSRvalue = 4; | ||
1503 | else if (playrate == 22050) | ||
1504 | DACSRvalue = 2; | ||
1505 | else if (playrate == 44100) | ||
1506 | DACSRvalue = 1; | ||
1507 | else if ((playrate <= 48000) && (playrate >= 6023)) | ||
1508 | DACSRvalue = 24576000 / (playrate * 16); | ||
1509 | else if (playrate < 6023) | ||
1510 | // Not allowed by open. | ||
1511 | return; | ||
1512 | else if (playrate > 48000) | ||
1513 | // Not allowed by open. | ||
1514 | return; | ||
1515 | CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 2, printk(KERN_INFO | ||
1516 | "cs4281: cs4281_play_rate(): DACSRvalue=0x%.8x playrate=%d\n", | ||
1517 | DACSRvalue, playrate)); | ||
1518 | // Write the 'sample rate select code' | ||
1519 | // to the 'DAC Sample Rate' register. | ||
1520 | writel(DACSRvalue, card->pBA0 + BA0_DACSR); // (744h) | ||
1521 | } | ||
1522 | |||
1523 | //****************************************************************************** | ||
1524 | // "cs4281_record_rate()" -- Initialize the record sample rate converter. | ||
1525 | //****************************************************************************** | ||
1526 | static void cs4281_record_rate(struct cs4281_state *card, u32 outrate) | ||
1527 | { | ||
1528 | u32 ADCSRvalue = 1; | ||
1529 | |||
1530 | // | ||
1531 | // Based on the sample rate, program the ADCSR register | ||
1532 | // | ||
1533 | if (outrate == 8000) | ||
1534 | ADCSRvalue = 5; | ||
1535 | if (outrate == 11025) | ||
1536 | ADCSRvalue = 4; | ||
1537 | else if (outrate == 22050) | ||
1538 | ADCSRvalue = 2; | ||
1539 | else if (outrate == 44100) | ||
1540 | ADCSRvalue = 1; | ||
1541 | else if ((outrate <= 48000) && (outrate >= 6023)) | ||
1542 | ADCSRvalue = 24576000 / (outrate * 16); | ||
1543 | else if (outrate < 6023) { | ||
1544 | // Not allowed by open. | ||
1545 | return; | ||
1546 | } else if (outrate > 48000) { | ||
1547 | // Not allowed by open. | ||
1548 | return; | ||
1549 | } | ||
1550 | CS_DBGOUT(CS_WAVE_READ | CS_PARMS, 2, printk(KERN_INFO | ||
1551 | "cs4281: cs4281_record_rate(): ADCSRvalue=0x%.8x outrate=%d\n", | ||
1552 | ADCSRvalue, outrate)); | ||
1553 | // Write the 'sample rate select code | ||
1554 | // to the 'ADC Sample Rate' register. | ||
1555 | writel(ADCSRvalue, card->pBA0 + BA0_ADCSR); // (748h) | ||
1556 | } | ||
1557 | |||
1558 | |||
1559 | |||
1560 | static void stop_dac(struct cs4281_state *s) | ||
1561 | { | ||
1562 | unsigned long flags; | ||
1563 | unsigned temp1; | ||
1564 | |||
1565 | CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4281: stop_dac():\n")); | ||
1566 | spin_lock_irqsave(&s->lock, flags); | ||
1567 | s->ena &= ~FMODE_WRITE; | ||
1568 | temp1 = readl(s->pBA0 + BA0_DCR0) | DCRn_MSK; | ||
1569 | writel(temp1, s->pBA0 + BA0_DCR0); | ||
1570 | |||
1571 | spin_unlock_irqrestore(&s->lock, flags); | ||
1572 | } | ||
1573 | |||
1574 | |||
1575 | static void start_dac(struct cs4281_state *s) | ||
1576 | { | ||
1577 | unsigned long flags; | ||
1578 | unsigned temp1; | ||
1579 | |||
1580 | CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4281: start_dac()+\n")); | ||
1581 | spin_lock_irqsave(&s->lock, flags); | ||
1582 | if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped || | ||
1583 | (s->dma_dac.count > 0 | ||
1584 | && s->dma_dac.ready)) | ||
1585 | #ifndef NOT_CS4281_PM | ||
1586 | && (s->pm.flags & CS4281_PM_IDLE)) | ||
1587 | #else | ||
1588 | ) | ||
1589 | #endif | ||
1590 | { | ||
1591 | s->ena |= FMODE_WRITE; | ||
1592 | temp1 = readl(s->pBA0 + BA0_DCR0) & ~DCRn_MSK; // Clear DMA0 channel mask. | ||
1593 | writel(temp1, s->pBA0 + BA0_DCR0); // Start DMA'ing. | ||
1594 | writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR); // Enable interrupts. | ||
1595 | |||
1596 | writel(7, s->pBA0 + BA0_PPRVC); | ||
1597 | writel(7, s->pBA0 + BA0_PPLVC); | ||
1598 | CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 8, printk(KERN_INFO | ||
1599 | "cs4281: start_dac(): writel 0x%x start dma\n", temp1)); | ||
1600 | |||
1601 | } | ||
1602 | spin_unlock_irqrestore(&s->lock, flags); | ||
1603 | CS_DBGOUT(CS_FUNCTION, 3, | ||
1604 | printk(KERN_INFO "cs4281: start_dac()-\n")); | ||
1605 | } | ||
1606 | |||
1607 | |||
1608 | static void stop_adc(struct cs4281_state *s) | ||
1609 | { | ||
1610 | unsigned long flags; | ||
1611 | unsigned temp1; | ||
1612 | |||
1613 | CS_DBGOUT(CS_FUNCTION, 3, | ||
1614 | printk(KERN_INFO "cs4281: stop_adc()+\n")); | ||
1615 | |||
1616 | spin_lock_irqsave(&s->lock, flags); | ||
1617 | s->ena &= ~FMODE_READ; | ||
1618 | |||
1619 | if (s->conversion == 1) { | ||
1620 | s->conversion = 0; | ||
1621 | s->prop_adc.fmt = s->prop_adc.fmt_original; | ||
1622 | } | ||
1623 | temp1 = readl(s->pBA0 + BA0_DCR1) | DCRn_MSK; | ||
1624 | writel(temp1, s->pBA0 + BA0_DCR1); | ||
1625 | spin_unlock_irqrestore(&s->lock, flags); | ||
1626 | CS_DBGOUT(CS_FUNCTION, 3, | ||
1627 | printk(KERN_INFO "cs4281: stop_adc()-\n")); | ||
1628 | } | ||
1629 | |||
1630 | |||
1631 | static void start_adc(struct cs4281_state *s) | ||
1632 | { | ||
1633 | unsigned long flags; | ||
1634 | unsigned temp1; | ||
1635 | |||
1636 | CS_DBGOUT(CS_FUNCTION, 2, | ||
1637 | printk(KERN_INFO "cs4281: start_adc()+\n")); | ||
1638 | |||
1639 | if (!(s->ena & FMODE_READ) && | ||
1640 | (s->dma_adc.mapped || s->dma_adc.count <= | ||
1641 | (signed) (s->dma_adc.dmasize - 2 * s->dma_adc.fragsize)) | ||
1642 | && s->dma_adc.ready | ||
1643 | #ifndef NOT_CS4281_PM | ||
1644 | && (s->pm.flags & CS4281_PM_IDLE)) | ||
1645 | #else | ||
1646 | ) | ||
1647 | #endif | ||
1648 | { | ||
1649 | if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) { | ||
1650 | // | ||
1651 | // now only use 16 bit capture, due to truncation issue | ||
1652 | // in the chip, noticable distortion occurs. | ||
1653 | // allocate buffer and then convert from 16 bit to | ||
1654 | // 8 bit for the user buffer. | ||
1655 | // | ||
1656 | s->prop_adc.fmt_original = s->prop_adc.fmt; | ||
1657 | if (s->prop_adc.fmt & AFMT_S8) { | ||
1658 | s->prop_adc.fmt &= ~AFMT_S8; | ||
1659 | s->prop_adc.fmt |= AFMT_S16_LE; | ||
1660 | } | ||
1661 | if (s->prop_adc.fmt & AFMT_U8) { | ||
1662 | s->prop_adc.fmt &= ~AFMT_U8; | ||
1663 | s->prop_adc.fmt |= AFMT_U16_LE; | ||
1664 | } | ||
1665 | // | ||
1666 | // prog_dmabuf_adc performs a stop_adc() but that is | ||
1667 | // ok since we really haven't started the DMA yet. | ||
1668 | // | ||
1669 | prog_codec(s, CS_TYPE_ADC); | ||
1670 | |||
1671 | if (prog_dmabuf_adc(s) != 0) { | ||
1672 | CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO | ||
1673 | "cs4281: start_adc(): error in prog_dmabuf_adc\n")); | ||
1674 | } | ||
1675 | s->conversion = 1; | ||
1676 | } | ||
1677 | spin_lock_irqsave(&s->lock, flags); | ||
1678 | s->ena |= FMODE_READ; | ||
1679 | temp1 = readl(s->pBA0 + BA0_DCR1) & ~DCRn_MSK; // Clear DMA1 channel mask bit. | ||
1680 | writel(temp1, s->pBA0 + BA0_DCR1); // Start recording | ||
1681 | writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR); // Enable interrupts. | ||
1682 | spin_unlock_irqrestore(&s->lock, flags); | ||
1683 | |||
1684 | CS_DBGOUT(CS_PARMS, 6, printk(KERN_INFO | ||
1685 | "cs4281: start_adc(): writel 0x%x \n", temp1)); | ||
1686 | } | ||
1687 | CS_DBGOUT(CS_FUNCTION, 2, | ||
1688 | printk(KERN_INFO "cs4281: start_adc()-\n")); | ||
1689 | |||
1690 | } | ||
1691 | |||
1692 | |||
1693 | // --------------------------------------------------------------------- | ||
1694 | |||
1695 | #define DMABUF_MINORDER 1 // ==> min buffer size = 8K. | ||
1696 | |||
1697 | |||
1698 | static void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db) | ||
1699 | { | ||
1700 | struct page *map, *mapend; | ||
1701 | |||
1702 | if (db->rawbuf) { | ||
1703 | // Undo prog_dmabuf()'s marking the pages as reserved | ||
1704 | mapend = | ||
1705 | virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - | ||
1706 | 1); | ||
1707 | for (map = virt_to_page(db->rawbuf); map <= mapend; map++) | ||
1708 | ClearPageReserved(map); | ||
1709 | free_dmabuf(s, db); | ||
1710 | } | ||
1711 | if (s->tmpbuff && (db->type == CS_TYPE_ADC)) { | ||
1712 | // Undo prog_dmabuf()'s marking the pages as reserved | ||
1713 | mapend = | ||
1714 | virt_to_page(s->tmpbuff + | ||
1715 | (PAGE_SIZE << s->buforder_tmpbuff) - 1); | ||
1716 | for (map = virt_to_page(s->tmpbuff); map <= mapend; map++) | ||
1717 | ClearPageReserved(map); | ||
1718 | free_dmabuf2(s, db); | ||
1719 | } | ||
1720 | s->tmpbuff = NULL; | ||
1721 | db->rawbuf = NULL; | ||
1722 | db->mapped = db->ready = 0; | ||
1723 | } | ||
1724 | |||
1725 | static int prog_dmabuf(struct cs4281_state *s, struct dmabuf *db) | ||
1726 | { | ||
1727 | int order; | ||
1728 | unsigned bytespersec, temp1; | ||
1729 | unsigned bufs, sample_shift = 0; | ||
1730 | struct page *map, *mapend; | ||
1731 | unsigned long df; | ||
1732 | |||
1733 | CS_DBGOUT(CS_FUNCTION, 2, | ||
1734 | printk(KERN_INFO "cs4281: prog_dmabuf()+\n")); | ||
1735 | db->hwptr = db->swptr = db->total_bytes = db->count = db->error = | ||
1736 | db->endcleared = db->blocks = db->wakeup = db->underrun = 0; | ||
1737 | /* | ||
1738 | * check for order within limits, but do not overwrite value, check | ||
1739 | * later for a fractional defaultorder (i.e. 100+). | ||
1740 | */ | ||
1741 | if((defaultorder > 0) && (defaultorder < 12)) | ||
1742 | df = defaultorder; | ||
1743 | else | ||
1744 | df = 1; | ||
1745 | |||
1746 | if (!db->rawbuf) { | ||
1747 | db->ready = db->mapped = 0; | ||
1748 | for (order = df; order >= DMABUF_MINORDER; order--) | ||
1749 | if ( (db->rawbuf = (void *) pci_alloc_consistent( | ||
1750 | s->pcidev, PAGE_SIZE << order, &db-> dmaaddr))) | ||
1751 | break; | ||
1752 | if (!db->rawbuf) { | ||
1753 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR | ||
1754 | "cs4281: prog_dmabuf(): unable to allocate rawbuf\n")); | ||
1755 | return -ENOMEM; | ||
1756 | } | ||
1757 | db->buforder = order; | ||
1758 | // Now mark the pages as reserved; otherwise the | ||
1759 | // remap_pfn_range() in cs4281_mmap doesn't work. | ||
1760 | // 1. get index to last page in mem_map array for rawbuf. | ||
1761 | mapend = virt_to_page(db->rawbuf + | ||
1762 | (PAGE_SIZE << db->buforder) - 1); | ||
1763 | |||
1764 | // 2. mark each physical page in range as 'reserved'. | ||
1765 | for (map = virt_to_page(db->rawbuf); map <= mapend; map++) | ||
1766 | SetPageReserved(map); | ||
1767 | } | ||
1768 | if (!s->tmpbuff && (db->type == CS_TYPE_ADC)) { | ||
1769 | for (order = df; order >= DMABUF_MINORDER; | ||
1770 | order--) | ||
1771 | if ( (s->tmpbuff = (void *) pci_alloc_consistent( | ||
1772 | s->pcidev, PAGE_SIZE << order, | ||
1773 | &s->dmaaddr_tmpbuff))) | ||
1774 | break; | ||
1775 | if (!s->tmpbuff) { | ||
1776 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR | ||
1777 | "cs4281: prog_dmabuf(): unable to allocate tmpbuff\n")); | ||
1778 | return -ENOMEM; | ||
1779 | } | ||
1780 | s->buforder_tmpbuff = order; | ||
1781 | // Now mark the pages as reserved; otherwise the | ||
1782 | // remap_pfn_range() in cs4281_mmap doesn't work. | ||
1783 | // 1. get index to last page in mem_map array for rawbuf. | ||
1784 | mapend = virt_to_page(s->tmpbuff + | ||
1785 | (PAGE_SIZE << s->buforder_tmpbuff) - 1); | ||
1786 | |||
1787 | // 2. mark each physical page in range as 'reserved'. | ||
1788 | for (map = virt_to_page(s->tmpbuff); map <= mapend; map++) | ||
1789 | SetPageReserved(map); | ||
1790 | } | ||
1791 | if (db->type == CS_TYPE_DAC) { | ||
1792 | if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE)) | ||
1793 | sample_shift++; | ||
1794 | if (s->prop_dac.channels > 1) | ||
1795 | sample_shift++; | ||
1796 | bytespersec = s->prop_dac.rate << sample_shift; | ||
1797 | } else // CS_TYPE_ADC | ||
1798 | { | ||
1799 | if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE)) | ||
1800 | sample_shift++; | ||
1801 | if (s->prop_adc.channels > 1) | ||
1802 | sample_shift++; | ||
1803 | bytespersec = s->prop_adc.rate << sample_shift; | ||
1804 | } | ||
1805 | bufs = PAGE_SIZE << db->buforder; | ||
1806 | |||
1807 | /* | ||
1808 | * added fractional "defaultorder" inputs. if >100 then use | ||
1809 | * defaultorder-100 as power of 2 for the buffer size. example: | ||
1810 | * 106 = 2^(106-100) = 2^6 = 64 bytes for the buffer size. | ||
1811 | */ | ||
1812 | if(defaultorder >= 100) | ||
1813 | { | ||
1814 | bufs = 1 << (defaultorder-100); | ||
1815 | } | ||
1816 | |||
1817 | #define INTERRUPT_RATE_MS 100 // Interrupt rate in milliseconds. | ||
1818 | db->numfrag = 2; | ||
1819 | /* | ||
1820 | * Nominal frag size(bytes/interrupt) | ||
1821 | */ | ||
1822 | temp1 = bytespersec / (1000 / INTERRUPT_RATE_MS); | ||
1823 | db->fragshift = 8; // Min 256 bytes. | ||
1824 | while (1 << db->fragshift < temp1) // Calc power of 2 frag size. | ||
1825 | db->fragshift += 1; | ||
1826 | db->fragsize = 1 << db->fragshift; | ||
1827 | db->dmasize = db->fragsize * 2; | ||
1828 | db->fragsamples = db->fragsize >> sample_shift; // # samples/fragment. | ||
1829 | |||
1830 | // If the calculated size is larger than the allocated | ||
1831 | // buffer, divide the allocated buffer into 2 fragments. | ||
1832 | if (db->dmasize > bufs) { | ||
1833 | |||
1834 | db->numfrag = 2; // Two fragments. | ||
1835 | db->fragsize = bufs >> 1; // Each 1/2 the alloc'ed buffer. | ||
1836 | db->fragsamples = db->fragsize >> sample_shift; // # samples/fragment. | ||
1837 | db->dmasize = bufs; // Use all the alloc'ed buffer. | ||
1838 | |||
1839 | db->fragshift = 0; // Calculate 'fragshift'. | ||
1840 | temp1 = db->fragsize; // update_ptr() uses it | ||
1841 | while ((temp1 >>= 1) > 1) // to calc 'total-bytes' | ||
1842 | db->fragshift += 1; // returned in DSP_GETI/OPTR. | ||
1843 | } | ||
1844 | CS_DBGOUT(CS_PARMS, 3, printk(KERN_INFO | ||
1845 | "cs4281: prog_dmabuf(): numfrag=%d fragsize=%d fragsamples=%d fragshift=%d bufs=%d fmt=0x%x ch=%d\n", | ||
1846 | db->numfrag, db->fragsize, db->fragsamples, | ||
1847 | db->fragshift, bufs, | ||
1848 | (db->type == CS_TYPE_DAC) ? s->prop_dac.fmt : | ||
1849 | s->prop_adc.fmt, | ||
1850 | (db->type == CS_TYPE_DAC) ? s->prop_dac.channels : | ||
1851 | s->prop_adc.channels)); | ||
1852 | CS_DBGOUT(CS_FUNCTION, 2, | ||
1853 | printk(KERN_INFO "cs4281: prog_dmabuf()-\n")); | ||
1854 | return 0; | ||
1855 | } | ||
1856 | |||
1857 | |||
1858 | static int prog_dmabuf_adc(struct cs4281_state *s) | ||
1859 | { | ||
1860 | unsigned long va; | ||
1861 | unsigned count; | ||
1862 | int c; | ||
1863 | stop_adc(s); | ||
1864 | s->dma_adc.type = CS_TYPE_ADC; | ||
1865 | if ((c = prog_dmabuf(s, &s->dma_adc))) | ||
1866 | return c; | ||
1867 | |||
1868 | if (s->dma_adc.rawbuf) { | ||
1869 | memset(s->dma_adc.rawbuf, | ||
1870 | (s->prop_adc. | ||
1871 | fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, | ||
1872 | s->dma_adc.dmasize); | ||
1873 | } | ||
1874 | if (s->tmpbuff) { | ||
1875 | memset(s->tmpbuff, | ||
1876 | (s->prop_adc. | ||
1877 | fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, | ||
1878 | PAGE_SIZE << s->buforder_tmpbuff); | ||
1879 | } | ||
1880 | |||
1881 | va = virt_to_bus(s->dma_adc.rawbuf); | ||
1882 | |||
1883 | count = s->dma_adc.dmasize; | ||
1884 | |||
1885 | if (s->prop_adc. | ||
1886 | fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) | ||
1887 | count /= 2; // 16-bit. | ||
1888 | |||
1889 | if (s->prop_adc.channels > 1) | ||
1890 | count /= 2; // Assume stereo. | ||
1891 | |||
1892 | CS_DBGOUT(CS_WAVE_READ, 3, printk(KERN_INFO | ||
1893 | "cs4281: prog_dmabuf_adc(): count=%d va=0x%.8x\n", | ||
1894 | count, (unsigned) va)); | ||
1895 | |||
1896 | writel(va, s->pBA0 + BA0_DBA1); // Set buffer start address. | ||
1897 | writel(count - 1, s->pBA0 + BA0_DBC1); // Set count. | ||
1898 | s->dma_adc.ready = 1; | ||
1899 | return 0; | ||
1900 | } | ||
1901 | |||
1902 | |||
1903 | static int prog_dmabuf_dac(struct cs4281_state *s) | ||
1904 | { | ||
1905 | unsigned long va; | ||
1906 | unsigned count; | ||
1907 | int c; | ||
1908 | stop_dac(s); | ||
1909 | s->dma_dac.type = CS_TYPE_DAC; | ||
1910 | if ((c = prog_dmabuf(s, &s->dma_dac))) | ||
1911 | return c; | ||
1912 | memset(s->dma_dac.rawbuf, | ||
1913 | (s->prop_dac.fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, | ||
1914 | s->dma_dac.dmasize); | ||
1915 | |||
1916 | va = virt_to_bus(s->dma_dac.rawbuf); | ||
1917 | |||
1918 | count = s->dma_dac.dmasize; | ||
1919 | if (s->prop_dac. | ||
1920 | fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) | ||
1921 | count /= 2; // 16-bit. | ||
1922 | |||
1923 | if (s->prop_dac.channels > 1) | ||
1924 | count /= 2; // Assume stereo. | ||
1925 | |||
1926 | writel(va, s->pBA0 + BA0_DBA0); // Set buffer start address. | ||
1927 | writel(count - 1, s->pBA0 + BA0_DBC0); // Set count. | ||
1928 | |||
1929 | CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO | ||
1930 | "cs4281: prog_dmabuf_dac(): count=%d va=0x%.8x\n", | ||
1931 | count, (unsigned) va)); | ||
1932 | |||
1933 | s->dma_dac.ready = 1; | ||
1934 | return 0; | ||
1935 | } | ||
1936 | |||
1937 | |||
1938 | static void clear_advance(void *buf, unsigned bsize, unsigned bptr, | ||
1939 | unsigned len, unsigned char c) | ||
1940 | { | ||
1941 | if (bptr + len > bsize) { | ||
1942 | unsigned x = bsize - bptr; | ||
1943 | memset(((char *) buf) + bptr, c, x); | ||
1944 | bptr = 0; | ||
1945 | len -= x; | ||
1946 | } | ||
1947 | CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO | ||
1948 | "cs4281: clear_advance(): memset %d at %p for %d size \n", | ||
1949 | (unsigned)c, ((char *) buf) + bptr, len)); | ||
1950 | memset(((char *) buf) + bptr, c, len); | ||
1951 | } | ||
1952 | |||
1953 | |||
1954 | |||
1955 | // call with spinlock held! | ||
1956 | static void cs4281_update_ptr(struct cs4281_state *s, int intflag) | ||
1957 | { | ||
1958 | int diff; | ||
1959 | unsigned hwptr, va; | ||
1960 | |||
1961 | // update ADC pointer | ||
1962 | if (s->ena & FMODE_READ) { | ||
1963 | hwptr = readl(s->pBA0 + BA0_DCA1); // Read capture DMA address. | ||
1964 | va = virt_to_bus(s->dma_adc.rawbuf); | ||
1965 | hwptr -= (unsigned) va; | ||
1966 | diff = | ||
1967 | (s->dma_adc.dmasize + hwptr - | ||
1968 | s->dma_adc.hwptr) % s->dma_adc.dmasize; | ||
1969 | s->dma_adc.hwptr = hwptr; | ||
1970 | s->dma_adc.total_bytes += diff; | ||
1971 | s->dma_adc.count += diff; | ||
1972 | if (s->dma_adc.count > s->dma_adc.dmasize) | ||
1973 | s->dma_adc.count = s->dma_adc.dmasize; | ||
1974 | if (s->dma_adc.mapped) { | ||
1975 | if (s->dma_adc.count >= | ||
1976 | (signed) s->dma_adc.fragsize) wake_up(&s-> | ||
1977 | dma_adc. | ||
1978 | wait); | ||
1979 | } else { | ||
1980 | if (s->dma_adc.count > 0) | ||
1981 | wake_up(&s->dma_adc.wait); | ||
1982 | } | ||
1983 | CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO | ||
1984 | "cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n", | ||
1985 | s, s->dma_adc.hwptr, s->dma_adc.total_bytes, s->dma_adc.count)); | ||
1986 | } | ||
1987 | // update DAC pointer | ||
1988 | // | ||
1989 | // check for end of buffer, means that we are going to wait for another interrupt | ||
1990 | // to allow silence to fill the fifos on the part, to keep pops down to a minimum. | ||
1991 | // | ||
1992 | if (s->ena & FMODE_WRITE) { | ||
1993 | hwptr = readl(s->pBA0 + BA0_DCA0); // Read play DMA address. | ||
1994 | va = virt_to_bus(s->dma_dac.rawbuf); | ||
1995 | hwptr -= (unsigned) va; | ||
1996 | diff = (s->dma_dac.dmasize + hwptr - | ||
1997 | s->dma_dac.hwptr) % s->dma_dac.dmasize; | ||
1998 | s->dma_dac.hwptr = hwptr; | ||
1999 | s->dma_dac.total_bytes += diff; | ||
2000 | if (s->dma_dac.mapped) { | ||
2001 | s->dma_dac.count += diff; | ||
2002 | if (s->dma_dac.count >= s->dma_dac.fragsize) { | ||
2003 | s->dma_dac.wakeup = 1; | ||
2004 | wake_up(&s->dma_dac.wait); | ||
2005 | if (s->dma_dac.count > s->dma_dac.dmasize) | ||
2006 | s->dma_dac.count &= | ||
2007 | s->dma_dac.dmasize - 1; | ||
2008 | } | ||
2009 | } else { | ||
2010 | s->dma_dac.count -= diff; | ||
2011 | if (s->dma_dac.count <= 0) { | ||
2012 | // | ||
2013 | // fill with silence, and do not shut down the DAC. | ||
2014 | // Continue to play silence until the _release. | ||
2015 | // | ||
2016 | CS_DBGOUT(CS_WAVE_WRITE, 6, printk(KERN_INFO | ||
2017 | "cs4281: cs4281_update_ptr(): memset %d at %p for %d size \n", | ||
2018 | (unsigned)(s->prop_dac.fmt & | ||
2019 | (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, | ||
2020 | s->dma_dac.rawbuf, s->dma_dac.dmasize)); | ||
2021 | memset(s->dma_dac.rawbuf, | ||
2022 | (s->prop_dac. | ||
2023 | fmt & (AFMT_U8 | AFMT_U16_LE)) ? | ||
2024 | 0x80 : 0, s->dma_dac.dmasize); | ||
2025 | if (s->dma_dac.count < 0) { | ||
2026 | s->dma_dac.underrun = 1; | ||
2027 | s->dma_dac.count = 0; | ||
2028 | CS_DBGOUT(CS_ERROR, 9, printk(KERN_INFO | ||
2029 | "cs4281: cs4281_update_ptr(): underrun\n")); | ||
2030 | } | ||
2031 | } else if (s->dma_dac.count <= | ||
2032 | (signed) s->dma_dac.fragsize | ||
2033 | && !s->dma_dac.endcleared) { | ||
2034 | clear_advance(s->dma_dac.rawbuf, | ||
2035 | s->dma_dac.dmasize, | ||
2036 | s->dma_dac.swptr, | ||
2037 | s->dma_dac.fragsize, | ||
2038 | (s->prop_dac. | ||
2039 | fmt & (AFMT_U8 | | ||
2040 | AFMT_U16_LE)) ? 0x80 | ||
2041 | : 0); | ||
2042 | s->dma_dac.endcleared = 1; | ||
2043 | } | ||
2044 | if ( (s->dma_dac.count <= (signed) s->dma_dac.dmasize/2) || | ||
2045 | intflag) | ||
2046 | { | ||
2047 | wake_up(&s->dma_dac.wait); | ||
2048 | } | ||
2049 | } | ||
2050 | CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO | ||
2051 | "cs4281: cs4281_update_ptr(): s=%p hwptr=%d total_bytes=%d count=%d \n", | ||
2052 | s, s->dma_dac.hwptr, s->dma_dac.total_bytes, s->dma_dac.count)); | ||
2053 | } | ||
2054 | } | ||
2055 | |||
2056 | |||
2057 | // --------------------------------------------------------------------- | ||
2058 | |||
2059 | static void prog_codec(struct cs4281_state *s, unsigned type) | ||
2060 | { | ||
2061 | unsigned long flags; | ||
2062 | unsigned temp1, format; | ||
2063 | |||
2064 | CS_DBGOUT(CS_FUNCTION, 2, | ||
2065 | printk(KERN_INFO "cs4281: prog_codec()+ \n")); | ||
2066 | |||
2067 | spin_lock_irqsave(&s->lock, flags); | ||
2068 | if (type == CS_TYPE_ADC) { | ||
2069 | temp1 = readl(s->pBA0 + BA0_DCR1); | ||
2070 | writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR1); // Stop capture DMA, if active. | ||
2071 | |||
2072 | // program sampling rates | ||
2073 | // Note, for CS4281, capture & play rates can be set independently. | ||
2074 | cs4281_record_rate(s, s->prop_adc.rate); | ||
2075 | |||
2076 | // program ADC parameters | ||
2077 | format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE; | ||
2078 | if (s->prop_adc. | ||
2079 | fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) { // 16-bit | ||
2080 | if (s->prop_adc.fmt & (AFMT_S16_BE | AFMT_U16_BE)) // Big-endian? | ||
2081 | format |= DMRn_BEND; | ||
2082 | if (s->prop_adc.fmt & (AFMT_U16_LE | AFMT_U16_BE)) | ||
2083 | format |= DMRn_USIGN; // Unsigned. | ||
2084 | } else | ||
2085 | format |= DMRn_SIZE8 | DMRn_USIGN; // 8-bit, unsigned | ||
2086 | if (s->prop_adc.channels < 2) | ||
2087 | format |= DMRn_MONO; | ||
2088 | |||
2089 | writel(format, s->pBA0 + BA0_DMR1); | ||
2090 | |||
2091 | CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO | ||
2092 | "cs4281: prog_codec(): adc %s %s %s rate=%d DMR0 format=0x%.8x\n", | ||
2093 | (format & DMRn_SIZE8) ? "8" : "16", | ||
2094 | (format & DMRn_USIGN) ? "Unsigned" : "Signed", | ||
2095 | (format & DMRn_MONO) ? "Mono" : "Stereo", | ||
2096 | s->prop_adc.rate, format)); | ||
2097 | |||
2098 | s->ena &= ~FMODE_READ; // not capturing data yet | ||
2099 | } | ||
2100 | |||
2101 | |||
2102 | if (type == CS_TYPE_DAC) { | ||
2103 | temp1 = readl(s->pBA0 + BA0_DCR0); | ||
2104 | writel(temp1 | DCRn_MSK, s->pBA0 + BA0_DCR0); // Stop play DMA, if active. | ||
2105 | |||
2106 | // program sampling rates | ||
2107 | // Note, for CS4281, capture & play rates can be set independently. | ||
2108 | cs4281_play_rate(s, s->prop_dac.rate); | ||
2109 | |||
2110 | // program DAC parameters | ||
2111 | format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ; | ||
2112 | if (s->prop_dac. | ||
2113 | fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) { // 16-bit | ||
2114 | if (s->prop_dac.fmt & (AFMT_S16_BE | AFMT_U16_BE)) | ||
2115 | format |= DMRn_BEND; // Big Endian. | ||
2116 | if (s->prop_dac.fmt & (AFMT_U16_LE | AFMT_U16_BE)) | ||
2117 | format |= DMRn_USIGN; // Unsigned. | ||
2118 | } else | ||
2119 | format |= DMRn_SIZE8 | DMRn_USIGN; // 8-bit, unsigned | ||
2120 | |||
2121 | if (s->prop_dac.channels < 2) | ||
2122 | format |= DMRn_MONO; | ||
2123 | |||
2124 | writel(format, s->pBA0 + BA0_DMR0); | ||
2125 | |||
2126 | |||
2127 | CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO | ||
2128 | "cs4281: prog_codec(): dac %s %s %s rate=%d DMR0 format=0x%.8x\n", | ||
2129 | (format & DMRn_SIZE8) ? "8" : "16", | ||
2130 | (format & DMRn_USIGN) ? "Unsigned" : "Signed", | ||
2131 | (format & DMRn_MONO) ? "Mono" : "Stereo", | ||
2132 | s->prop_dac.rate, format)); | ||
2133 | |||
2134 | s->ena &= ~FMODE_WRITE; // not capturing data yet | ||
2135 | |||
2136 | } | ||
2137 | spin_unlock_irqrestore(&s->lock, flags); | ||
2138 | CS_DBGOUT(CS_FUNCTION, 2, | ||
2139 | printk(KERN_INFO "cs4281: prog_codec()- \n")); | ||
2140 | } | ||
2141 | |||
2142 | |||
2143 | static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd, | ||
2144 | unsigned long arg) | ||
2145 | { | ||
2146 | // Index to mixer_src[] is value of AC97 Input Mux Select Reg. | ||
2147 | // Value of array member is recording source Device ID Mask. | ||
2148 | static const unsigned int mixer_src[8] = { | ||
2149 | SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1, | ||
2150 | SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0 | ||
2151 | }; | ||
2152 | void __user *argp = (void __user *)arg; | ||
2153 | |||
2154 | // Index of mixtable1[] member is Device ID | ||
2155 | // and must be <= SOUND_MIXER_NRDEVICES. | ||
2156 | // Value of array member is index into s->mix.vol[] | ||
2157 | static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = { | ||
2158 | [SOUND_MIXER_PCM] = 1, // voice | ||
2159 | [SOUND_MIXER_LINE1] = 2, // AUX | ||
2160 | [SOUND_MIXER_CD] = 3, // CD | ||
2161 | [SOUND_MIXER_LINE] = 4, // Line | ||
2162 | [SOUND_MIXER_SYNTH] = 5, // FM | ||
2163 | [SOUND_MIXER_MIC] = 6, // Mic | ||
2164 | [SOUND_MIXER_SPEAKER] = 7, // Speaker | ||
2165 | [SOUND_MIXER_RECLEV] = 8, // Recording level | ||
2166 | [SOUND_MIXER_VOLUME] = 9 // Master Volume | ||
2167 | }; | ||
2168 | |||
2169 | |||
2170 | static const unsigned mixreg[] = { | ||
2171 | BA0_AC97_PCM_OUT_VOLUME, | ||
2172 | BA0_AC97_AUX_VOLUME, | ||
2173 | BA0_AC97_CD_VOLUME, | ||
2174 | BA0_AC97_LINE_IN_VOLUME | ||
2175 | }; | ||
2176 | unsigned char l, r, rl, rr, vidx; | ||
2177 | unsigned char attentbl[11] = | ||
2178 | { 63, 42, 26, 17, 14, 11, 8, 6, 4, 2, 0 }; | ||
2179 | unsigned temp1; | ||
2180 | int i, val; | ||
2181 | |||
2182 | VALIDATE_STATE(s); | ||
2183 | CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO | ||
2184 | "cs4281: mixer_ioctl(): s=%p cmd=0x%.8x\n", s, cmd)); | ||
2185 | #if CSDEBUG | ||
2186 | cs_printioctl(cmd); | ||
2187 | #endif | ||
2188 | #if CSDEBUG_INTERFACE | ||
2189 | |||
2190 | if ((cmd == SOUND_MIXER_CS_GETDBGMASK) || | ||
2191 | (cmd == SOUND_MIXER_CS_SETDBGMASK) || | ||
2192 | (cmd == SOUND_MIXER_CS_GETDBGLEVEL) || | ||
2193 | (cmd == SOUND_MIXER_CS_SETDBGLEVEL) || | ||
2194 | (cmd == SOUND_MIXER_CS_APM)) | ||
2195 | { | ||
2196 | switch (cmd) { | ||
2197 | |||
2198 | case SOUND_MIXER_CS_GETDBGMASK: | ||
2199 | return put_user(cs_debugmask, | ||
2200 | (unsigned long __user *) argp); | ||
2201 | |||
2202 | case SOUND_MIXER_CS_GETDBGLEVEL: | ||
2203 | return put_user(cs_debuglevel, | ||
2204 | (unsigned long __user *) argp); | ||
2205 | |||
2206 | case SOUND_MIXER_CS_SETDBGMASK: | ||
2207 | if (get_user(val, (unsigned long __user *) argp)) | ||
2208 | return -EFAULT; | ||
2209 | cs_debugmask = val; | ||
2210 | return 0; | ||
2211 | |||
2212 | case SOUND_MIXER_CS_SETDBGLEVEL: | ||
2213 | if (get_user(val, (unsigned long __user *) argp)) | ||
2214 | return -EFAULT; | ||
2215 | cs_debuglevel = val; | ||
2216 | return 0; | ||
2217 | #ifndef NOT_CS4281_PM | ||
2218 | case SOUND_MIXER_CS_APM: | ||
2219 | if (get_user(val, (unsigned long __user *) argp)) | ||
2220 | return -EFAULT; | ||
2221 | if(val == CS_IOCTL_CMD_SUSPEND) | ||
2222 | cs4281_suspend(s); | ||
2223 | else if(val == CS_IOCTL_CMD_RESUME) | ||
2224 | cs4281_resume(s); | ||
2225 | else | ||
2226 | { | ||
2227 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO | ||
2228 | "cs4281: mixer_ioctl(): invalid APM cmd (%d)\n", | ||
2229 | val)); | ||
2230 | } | ||
2231 | return 0; | ||
2232 | #endif | ||
2233 | default: | ||
2234 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO | ||
2235 | "cs4281: mixer_ioctl(): ERROR unknown debug cmd\n")); | ||
2236 | return 0; | ||
2237 | } | ||
2238 | } | ||
2239 | #endif | ||
2240 | |||
2241 | if (cmd == SOUND_MIXER_PRIVATE1) { | ||
2242 | // enable/disable/query mixer preamp | ||
2243 | if (get_user(val, (int __user *) argp)) | ||
2244 | return -EFAULT; | ||
2245 | if (val != -1) { | ||
2246 | cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1); | ||
2247 | temp1 = val ? (temp1 | 0x40) : (temp1 & 0xffbf); | ||
2248 | cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1); | ||
2249 | } | ||
2250 | cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1); | ||
2251 | val = (temp1 & 0x40) ? 1 : 0; | ||
2252 | return put_user(val, (int __user *) argp); | ||
2253 | } | ||
2254 | if (cmd == SOUND_MIXER_PRIVATE2) { | ||
2255 | // enable/disable/query spatializer | ||
2256 | if (get_user(val, (int __user *)argp)) | ||
2257 | return -EFAULT; | ||
2258 | if (val != -1) { | ||
2259 | temp1 = (val & 0x3f) >> 2; | ||
2260 | cs4281_write_ac97(s, BA0_AC97_3D_CONTROL, temp1); | ||
2261 | cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE, | ||
2262 | &temp1); | ||
2263 | cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE, | ||
2264 | temp1 | 0x2000); | ||
2265 | } | ||
2266 | cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1); | ||
2267 | return put_user((temp1 << 2) | 3, (int __user *)argp); | ||
2268 | } | ||
2269 | if (cmd == SOUND_MIXER_INFO) { | ||
2270 | mixer_info info; | ||
2271 | strlcpy(info.id, "CS4281", sizeof(info.id)); | ||
2272 | strlcpy(info.name, "Crystal CS4281", sizeof(info.name)); | ||
2273 | info.modify_counter = s->mix.modcnt; | ||
2274 | if (copy_to_user(argp, &info, sizeof(info))) | ||
2275 | return -EFAULT; | ||
2276 | return 0; | ||
2277 | } | ||
2278 | if (cmd == SOUND_OLD_MIXER_INFO) { | ||
2279 | _old_mixer_info info; | ||
2280 | strlcpy(info.id, "CS4281", sizeof(info.id)); | ||
2281 | strlcpy(info.name, "Crystal CS4281", sizeof(info.name)); | ||
2282 | if (copy_to_user(argp, &info, sizeof(info))) | ||
2283 | return -EFAULT; | ||
2284 | return 0; | ||
2285 | } | ||
2286 | if (cmd == OSS_GETVERSION) | ||
2287 | return put_user(SOUND_VERSION, (int __user *) argp); | ||
2288 | |||
2289 | if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int)) | ||
2290 | return -EINVAL; | ||
2291 | |||
2292 | // If ioctl has only the SIOC_READ bit(bit 31) | ||
2293 | // on, process the only-read commands. | ||
2294 | if (_SIOC_DIR(cmd) == _SIOC_READ) { | ||
2295 | switch (_IOC_NR(cmd)) { | ||
2296 | case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source | ||
2297 | cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT, &temp1); | ||
2298 | return put_user(mixer_src[temp1&7], (int __user *)argp); | ||
2299 | |||
2300 | case SOUND_MIXER_DEVMASK: // Arg contains a bit for each supported device | ||
2301 | return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | | ||
2302 | SOUND_MASK_CD | SOUND_MASK_LINE | | ||
2303 | SOUND_MASK_LINE1 | SOUND_MASK_MIC | | ||
2304 | SOUND_MASK_VOLUME | | ||
2305 | SOUND_MASK_RECLEV | | ||
2306 | SOUND_MASK_SPEAKER, (int __user *)argp); | ||
2307 | |||
2308 | case SOUND_MIXER_RECMASK: // Arg contains a bit for each supported recording source | ||
2309 | return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | | ||
2310 | SOUND_MASK_CD | SOUND_MASK_VOLUME | | ||
2311 | SOUND_MASK_LINE1, (int __user *) argp); | ||
2312 | |||
2313 | case SOUND_MIXER_STEREODEVS: // Mixer channels supporting stereo | ||
2314 | return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | | ||
2315 | SOUND_MASK_CD | SOUND_MASK_LINE | | ||
2316 | SOUND_MASK_LINE1 | SOUND_MASK_MIC | | ||
2317 | SOUND_MASK_VOLUME | | ||
2318 | SOUND_MASK_RECLEV, (int __user *)argp); | ||
2319 | |||
2320 | case SOUND_MIXER_CAPS: | ||
2321 | return put_user(SOUND_CAP_EXCL_INPUT, (int __user *)argp); | ||
2322 | |||
2323 | default: | ||
2324 | i = _IOC_NR(cmd); | ||
2325 | if (i >= SOUND_MIXER_NRDEVICES | ||
2326 | || !(vidx = mixtable1[i])) | ||
2327 | return -EINVAL; | ||
2328 | return put_user(s->mix.vol[vidx - 1], (int __user *)argp); | ||
2329 | } | ||
2330 | } | ||
2331 | // If ioctl doesn't have both the SIOC_READ and | ||
2332 | // the SIOC_WRITE bit set, return invalid. | ||
2333 | if (_SIOC_DIR(cmd) != (_SIOC_READ | _SIOC_WRITE)) | ||
2334 | return -EINVAL; | ||
2335 | |||
2336 | // Increment the count of volume writes. | ||
2337 | s->mix.modcnt++; | ||
2338 | |||
2339 | // Isolate the command; it must be a write. | ||
2340 | switch (_IOC_NR(cmd)) { | ||
2341 | |||
2342 | case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source | ||
2343 | if (get_user(val, (int __user *)argp)) | ||
2344 | return -EFAULT; | ||
2345 | i = hweight32(val); // i = # bits on in val. | ||
2346 | if (i != 1) // One & only 1 bit must be on. | ||
2347 | return 0; | ||
2348 | for (i = 0; i < sizeof(mixer_src) / sizeof(int); i++) { | ||
2349 | if (val == mixer_src[i]) { | ||
2350 | temp1 = (i << 8) | i; | ||
2351 | cs4281_write_ac97(s, | ||
2352 | BA0_AC97_RECORD_SELECT, | ||
2353 | temp1); | ||
2354 | return 0; | ||
2355 | } | ||
2356 | } | ||
2357 | return 0; | ||
2358 | |||
2359 | case SOUND_MIXER_VOLUME: | ||
2360 | if (get_user(val, (int __user *)argp)) | ||
2361 | return -EFAULT; | ||
2362 | l = val & 0xff; | ||
2363 | if (l > 100) | ||
2364 | l = 100; // Max soundcard.h vol is 100. | ||
2365 | if (l < 6) { | ||
2366 | rl = 63; | ||
2367 | l = 0; | ||
2368 | } else | ||
2369 | rl = attentbl[(10 * l) / 100]; // Convert 0-100 vol to 63-0 atten. | ||
2370 | |||
2371 | r = (val >> 8) & 0xff; | ||
2372 | if (r > 100) | ||
2373 | r = 100; // Max right volume is 100, too | ||
2374 | if (r < 6) { | ||
2375 | rr = 63; | ||
2376 | r = 0; | ||
2377 | } else | ||
2378 | rr = attentbl[(10 * r) / 100]; // Convert volume to attenuation. | ||
2379 | |||
2380 | if ((rl > 60) && (rr > 60)) // If both l & r are 'low', | ||
2381 | temp1 = 0x8000; // turn on the mute bit. | ||
2382 | else | ||
2383 | temp1 = 0; | ||
2384 | |||
2385 | temp1 |= (rl << 8) | rr; | ||
2386 | |||
2387 | cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, temp1); | ||
2388 | cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, temp1); | ||
2389 | |||
2390 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
2391 | s->mix.vol[8] = ((unsigned int) r << 8) | l; | ||
2392 | #else | ||
2393 | s->mix.vol[8] = val; | ||
2394 | #endif | ||
2395 | return put_user(s->mix.vol[8], (int __user *)argp); | ||
2396 | |||
2397 | case SOUND_MIXER_SPEAKER: | ||
2398 | if (get_user(val, (int __user *)argp)) | ||
2399 | return -EFAULT; | ||
2400 | l = val & 0xff; | ||
2401 | if (l > 100) | ||
2402 | l = 100; | ||
2403 | if (l < 3) { | ||
2404 | rl = 0; | ||
2405 | l = 0; | ||
2406 | } else { | ||
2407 | rl = (l * 2 - 5) / 13; // Convert 0-100 range to 0-15. | ||
2408 | l = (rl * 13 + 5) / 2; | ||
2409 | } | ||
2410 | |||
2411 | if (rl < 3) { | ||
2412 | temp1 = 0x8000; | ||
2413 | rl = 0; | ||
2414 | } else | ||
2415 | temp1 = 0; | ||
2416 | rl = 15 - rl; // Convert volume to attenuation. | ||
2417 | temp1 |= rl << 1; | ||
2418 | cs4281_write_ac97(s, BA0_AC97_PC_BEEP_VOLUME, temp1); | ||
2419 | |||
2420 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
2421 | s->mix.vol[6] = l << 8; | ||
2422 | #else | ||
2423 | s->mix.vol[6] = val; | ||
2424 | #endif | ||
2425 | return put_user(s->mix.vol[6], (int __user *)argp); | ||
2426 | |||
2427 | case SOUND_MIXER_RECLEV: | ||
2428 | if (get_user(val, (int __user *)argp)) | ||
2429 | return -EFAULT; | ||
2430 | l = val & 0xff; | ||
2431 | if (l > 100) | ||
2432 | l = 100; | ||
2433 | r = (val >> 8) & 0xff; | ||
2434 | if (r > 100) | ||
2435 | r = 100; | ||
2436 | rl = (l * 2 - 5) / 13; // Convert 0-100 scale to 0-15. | ||
2437 | rr = (r * 2 - 5) / 13; | ||
2438 | if (rl < 3 && rr < 3) | ||
2439 | temp1 = 0x8000; | ||
2440 | else | ||
2441 | temp1 = 0; | ||
2442 | |||
2443 | temp1 = temp1 | (rl << 8) | rr; | ||
2444 | cs4281_write_ac97(s, BA0_AC97_RECORD_GAIN, temp1); | ||
2445 | |||
2446 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
2447 | s->mix.vol[7] = ((unsigned int) r << 8) | l; | ||
2448 | #else | ||
2449 | s->mix.vol[7] = val; | ||
2450 | #endif | ||
2451 | return put_user(s->mix.vol[7], (int __user *)argp); | ||
2452 | |||
2453 | case SOUND_MIXER_MIC: | ||
2454 | if (get_user(val, (int __user *)argp)) | ||
2455 | return -EFAULT; | ||
2456 | l = val & 0xff; | ||
2457 | if (l > 100) | ||
2458 | l = 100; | ||
2459 | if (l < 1) { | ||
2460 | l = 0; | ||
2461 | rl = 0; | ||
2462 | } else { | ||
2463 | rl = ((unsigned) l * 5 - 4) / 16; // Convert 0-100 range to 0-31. | ||
2464 | l = (rl * 16 + 4) / 5; | ||
2465 | } | ||
2466 | cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1); | ||
2467 | temp1 &= 0x40; // Isolate 20db gain bit. | ||
2468 | if (rl < 3) { | ||
2469 | temp1 |= 0x8000; | ||
2470 | rl = 0; | ||
2471 | } | ||
2472 | rl = 31 - rl; // Convert volume to attenuation. | ||
2473 | temp1 |= rl; | ||
2474 | cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1); | ||
2475 | |||
2476 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
2477 | s->mix.vol[5] = val << 8; | ||
2478 | #else | ||
2479 | s->mix.vol[5] = val; | ||
2480 | #endif | ||
2481 | return put_user(s->mix.vol[5], (int __user *)argp); | ||
2482 | |||
2483 | |||
2484 | case SOUND_MIXER_SYNTH: | ||
2485 | if (get_user(val, (int __user *)argp)) | ||
2486 | return -EFAULT; | ||
2487 | l = val & 0xff; | ||
2488 | if (l > 100) | ||
2489 | l = 100; | ||
2490 | if (get_user(val, (int __user *)argp)) | ||
2491 | return -EFAULT; | ||
2492 | r = (val >> 8) & 0xff; | ||
2493 | if (r > 100) | ||
2494 | r = 100; | ||
2495 | rl = (l * 2 - 11) / 3; // Convert 0-100 range to 0-63. | ||
2496 | rr = (r * 2 - 11) / 3; | ||
2497 | if (rl < 3) // If l is low, turn on | ||
2498 | temp1 = 0x0080; // the mute bit. | ||
2499 | else | ||
2500 | temp1 = 0; | ||
2501 | |||
2502 | rl = 63 - rl; // Convert vol to attenuation. | ||
2503 | writel(temp1 | rl, s->pBA0 + BA0_FMLVC); | ||
2504 | if (rr < 3) // If rr is low, turn on | ||
2505 | temp1 = 0x0080; // the mute bit. | ||
2506 | else | ||
2507 | temp1 = 0; | ||
2508 | rr = 63 - rr; // Convert vol to attenuation. | ||
2509 | writel(temp1 | rr, s->pBA0 + BA0_FMRVC); | ||
2510 | |||
2511 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
2512 | s->mix.vol[4] = (r << 8) | l; | ||
2513 | #else | ||
2514 | s->mix.vol[4] = val; | ||
2515 | #endif | ||
2516 | return put_user(s->mix.vol[4], (int __user *)argp); | ||
2517 | |||
2518 | |||
2519 | default: | ||
2520 | CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO | ||
2521 | "cs4281: mixer_ioctl(): default\n")); | ||
2522 | |||
2523 | i = _IOC_NR(cmd); | ||
2524 | if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i])) | ||
2525 | return -EINVAL; | ||
2526 | if (get_user(val, (int __user *)argp)) | ||
2527 | return -EFAULT; | ||
2528 | l = val & 0xff; | ||
2529 | if (l > 100) | ||
2530 | l = 100; | ||
2531 | if (l < 1) { | ||
2532 | l = 0; | ||
2533 | rl = 31; | ||
2534 | } else | ||
2535 | rl = (attentbl[(l * 10) / 100]) >> 1; | ||
2536 | |||
2537 | r = (val >> 8) & 0xff; | ||
2538 | if (r > 100) | ||
2539 | r = 100; | ||
2540 | if (r < 1) { | ||
2541 | r = 0; | ||
2542 | rr = 31; | ||
2543 | } else | ||
2544 | rr = (attentbl[(r * 10) / 100]) >> 1; | ||
2545 | if ((rl > 30) && (rr > 30)) | ||
2546 | temp1 = 0x8000; | ||
2547 | else | ||
2548 | temp1 = 0; | ||
2549 | temp1 = temp1 | (rl << 8) | rr; | ||
2550 | cs4281_write_ac97(s, mixreg[vidx - 1], temp1); | ||
2551 | |||
2552 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
2553 | s->mix.vol[vidx - 1] = ((unsigned int) r << 8) | l; | ||
2554 | #else | ||
2555 | s->mix.vol[vidx - 1] = val; | ||
2556 | #endif | ||
2557 | #ifndef NOT_CS4281_PM | ||
2558 | CS_DBGOUT(CS_PM, 9, printk(KERN_INFO | ||
2559 | "write ac97 mixreg[%d]=0x%x mix.vol[]=0x%x\n", | ||
2560 | vidx-1,temp1,s->mix.vol[vidx-1])); | ||
2561 | #endif | ||
2562 | return put_user(s->mix.vol[vidx - 1], (int __user *)argp); | ||
2563 | } | ||
2564 | } | ||
2565 | |||
2566 | |||
2567 | // --------------------------------------------------------------------- | ||
2568 | |||
2569 | static int cs4281_open_mixdev(struct inode *inode, struct file *file) | ||
2570 | { | ||
2571 | unsigned int minor = iminor(inode); | ||
2572 | struct cs4281_state *s=NULL; | ||
2573 | struct list_head *entry; | ||
2574 | |||
2575 | CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, | ||
2576 | printk(KERN_INFO "cs4281: cs4281_open_mixdev()+\n")); | ||
2577 | |||
2578 | list_for_each(entry, &cs4281_devs) | ||
2579 | { | ||
2580 | s = list_entry(entry, struct cs4281_state, list); | ||
2581 | if(s->dev_mixer == minor) | ||
2582 | break; | ||
2583 | } | ||
2584 | if (!s) | ||
2585 | { | ||
2586 | CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, | ||
2587 | printk(KERN_INFO "cs4281: cs4281_open_mixdev()- -ENODEV\n")); | ||
2588 | return -ENODEV; | ||
2589 | } | ||
2590 | VALIDATE_STATE(s); | ||
2591 | file->private_data = s; | ||
2592 | |||
2593 | CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, | ||
2594 | printk(KERN_INFO "cs4281: cs4281_open_mixdev()- 0\n")); | ||
2595 | |||
2596 | return nonseekable_open(inode, file); | ||
2597 | } | ||
2598 | |||
2599 | |||
2600 | static int cs4281_release_mixdev(struct inode *inode, struct file *file) | ||
2601 | { | ||
2602 | struct cs4281_state *s = | ||
2603 | (struct cs4281_state *) file->private_data; | ||
2604 | |||
2605 | VALIDATE_STATE(s); | ||
2606 | return 0; | ||
2607 | } | ||
2608 | |||
2609 | |||
2610 | static int cs4281_ioctl_mixdev(struct inode *inode, struct file *file, | ||
2611 | unsigned int cmd, unsigned long arg) | ||
2612 | { | ||
2613 | return mixer_ioctl((struct cs4281_state *) file->private_data, cmd, | ||
2614 | arg); | ||
2615 | } | ||
2616 | |||
2617 | |||
2618 | // ****************************************************************************************** | ||
2619 | // Mixer file operations struct. | ||
2620 | // ****************************************************************************************** | ||
2621 | static /*const */ struct file_operations cs4281_mixer_fops = { | ||
2622 | .owner = THIS_MODULE, | ||
2623 | .llseek = no_llseek, | ||
2624 | .ioctl = cs4281_ioctl_mixdev, | ||
2625 | .open = cs4281_open_mixdev, | ||
2626 | .release = cs4281_release_mixdev, | ||
2627 | }; | ||
2628 | |||
2629 | // --------------------------------------------------------------------- | ||
2630 | |||
2631 | |||
2632 | static int drain_adc(struct cs4281_state *s, int nonblock) | ||
2633 | { | ||
2634 | DECLARE_WAITQUEUE(wait, current); | ||
2635 | unsigned long flags; | ||
2636 | int count; | ||
2637 | unsigned tmo; | ||
2638 | |||
2639 | if (s->dma_adc.mapped) | ||
2640 | return 0; | ||
2641 | add_wait_queue(&s->dma_adc.wait, &wait); | ||
2642 | for (;;) { | ||
2643 | set_current_state(TASK_INTERRUPTIBLE); | ||
2644 | spin_lock_irqsave(&s->lock, flags); | ||
2645 | count = s->dma_adc.count; | ||
2646 | CS_DBGOUT(CS_FUNCTION, 2, | ||
2647 | printk(KERN_INFO "cs4281: drain_adc() %d\n", count)); | ||
2648 | spin_unlock_irqrestore(&s->lock, flags); | ||
2649 | if (count <= 0) { | ||
2650 | CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO | ||
2651 | "cs4281: drain_adc() count<0\n")); | ||
2652 | break; | ||
2653 | } | ||
2654 | if (signal_pending(current)) | ||
2655 | break; | ||
2656 | if (nonblock) { | ||
2657 | remove_wait_queue(&s->dma_adc.wait, &wait); | ||
2658 | current->state = TASK_RUNNING; | ||
2659 | return -EBUSY; | ||
2660 | } | ||
2661 | tmo = | ||
2662 | 3 * HZ * (count + | ||
2663 | s->dma_adc.fragsize) / 2 / s->prop_adc.rate; | ||
2664 | if (s->prop_adc.fmt & (AFMT_S16_LE | AFMT_U16_LE)) | ||
2665 | tmo >>= 1; | ||
2666 | if (s->prop_adc.channels > 1) | ||
2667 | tmo >>= 1; | ||
2668 | if (!schedule_timeout(tmo + 1)) | ||
2669 | printk(KERN_DEBUG "cs4281: dma timed out??\n"); | ||
2670 | } | ||
2671 | remove_wait_queue(&s->dma_adc.wait, &wait); | ||
2672 | current->state = TASK_RUNNING; | ||
2673 | if (signal_pending(current)) | ||
2674 | return -ERESTARTSYS; | ||
2675 | return 0; | ||
2676 | } | ||
2677 | |||
2678 | static int drain_dac(struct cs4281_state *s, int nonblock) | ||
2679 | { | ||
2680 | DECLARE_WAITQUEUE(wait, current); | ||
2681 | unsigned long flags; | ||
2682 | int count; | ||
2683 | unsigned tmo; | ||
2684 | |||
2685 | if (s->dma_dac.mapped) | ||
2686 | return 0; | ||
2687 | add_wait_queue(&s->dma_dac.wait, &wait); | ||
2688 | for (;;) { | ||
2689 | set_current_state(TASK_INTERRUPTIBLE); | ||
2690 | spin_lock_irqsave(&s->lock, flags); | ||
2691 | count = s->dma_dac.count; | ||
2692 | spin_unlock_irqrestore(&s->lock, flags); | ||
2693 | if (count <= 0) | ||
2694 | break; | ||
2695 | if (signal_pending(current)) | ||
2696 | break; | ||
2697 | if (nonblock) { | ||
2698 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
2699 | current->state = TASK_RUNNING; | ||
2700 | return -EBUSY; | ||
2701 | } | ||
2702 | tmo = | ||
2703 | 3 * HZ * (count + | ||
2704 | s->dma_dac.fragsize) / 2 / s->prop_dac.rate; | ||
2705 | if (s->prop_dac.fmt & (AFMT_S16_LE | AFMT_U16_LE)) | ||
2706 | tmo >>= 1; | ||
2707 | if (s->prop_dac.channels > 1) | ||
2708 | tmo >>= 1; | ||
2709 | if (!schedule_timeout(tmo + 1)) | ||
2710 | printk(KERN_DEBUG "cs4281: dma timed out??\n"); | ||
2711 | } | ||
2712 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
2713 | current->state = TASK_RUNNING; | ||
2714 | if (signal_pending(current)) | ||
2715 | return -ERESTARTSYS; | ||
2716 | return 0; | ||
2717 | } | ||
2718 | |||
2719 | //**************************************************************************** | ||
2720 | // | ||
2721 | // CopySamples copies 16-bit stereo samples from the source to the | ||
2722 | // destination, possibly converting down to either 8-bit or mono or both. | ||
2723 | // count specifies the number of output bytes to write. | ||
2724 | // | ||
2725 | // Arguments: | ||
2726 | // | ||
2727 | // dst - Pointer to a destination buffer. | ||
2728 | // src - Pointer to a source buffer | ||
2729 | // count - The number of bytes to copy into the destination buffer. | ||
2730 | // iChannels - Stereo - 2 | ||
2731 | // Mono - 1 | ||
2732 | // fmt - AFMT_xxx (soundcard.h formats) | ||
2733 | // | ||
2734 | // NOTES: only call this routine for conversion to 8bit from 16bit | ||
2735 | // | ||
2736 | //**************************************************************************** | ||
2737 | static void CopySamples(char *dst, char *src, int count, int iChannels, | ||
2738 | unsigned fmt) | ||
2739 | { | ||
2740 | |||
2741 | unsigned short *psSrc; | ||
2742 | long lAudioSample; | ||
2743 | |||
2744 | CS_DBGOUT(CS_FUNCTION, 2, | ||
2745 | printk(KERN_INFO "cs4281: CopySamples()+ ")); | ||
2746 | CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO | ||
2747 | " dst=%p src=%p count=%d iChannels=%d fmt=0x%x\n", | ||
2748 | dst, src, (unsigned) count, (unsigned) iChannels, (unsigned) fmt)); | ||
2749 | |||
2750 | // Gershwin does format conversion in hardware so normally | ||
2751 | // we don't do any host based coversion. The data formatter | ||
2752 | // truncates 16 bit data to 8 bit and that causes some hiss. | ||
2753 | // We have already forced the HW to do 16 bit sampling and | ||
2754 | // 2 channel so that we can use software to round instead | ||
2755 | // of truncate | ||
2756 | |||
2757 | // | ||
2758 | // See if the data should be output as 8-bit unsigned stereo. | ||
2759 | // or if the data should be output at 8-bit unsigned mono. | ||
2760 | // | ||
2761 | if ( ((iChannels == 2) && (fmt & AFMT_U8)) || | ||
2762 | ((iChannels == 1) && (fmt & AFMT_U8)) ) { | ||
2763 | // | ||
2764 | // Convert each 16-bit unsigned stereo sample to 8-bit unsigned | ||
2765 | // stereo using rounding. | ||
2766 | // | ||
2767 | psSrc = (unsigned short *) src; | ||
2768 | count = count / 2; | ||
2769 | while (count--) { | ||
2770 | lAudioSample = (long) psSrc[count] + (long) 0x80; | ||
2771 | if (lAudioSample > 0xffff) { | ||
2772 | lAudioSample = 0xffff; | ||
2773 | } | ||
2774 | dst[count] = (char) (lAudioSample >> 8); | ||
2775 | } | ||
2776 | } | ||
2777 | // | ||
2778 | // check for 8-bit signed stereo. | ||
2779 | // | ||
2780 | else if ((iChannels == 2) && (fmt & AFMT_S8)) { | ||
2781 | // | ||
2782 | // Convert each 16-bit stereo sample to 8-bit stereo using rounding. | ||
2783 | // | ||
2784 | psSrc = (short *) src; | ||
2785 | while (count--) { | ||
2786 | lAudioSample = | ||
2787 | (((long) psSrc[0] + (long) psSrc[1]) / 2); | ||
2788 | psSrc += 2; | ||
2789 | *dst++ = (char) ((short) lAudioSample >> 8); | ||
2790 | } | ||
2791 | } | ||
2792 | // | ||
2793 | // Otherwise, the data should be output as 8-bit signed mono. | ||
2794 | // | ||
2795 | else if ((iChannels == 1) && (fmt & AFMT_S8)) { | ||
2796 | // | ||
2797 | // Convert each 16-bit signed mono sample to 8-bit signed mono | ||
2798 | // using rounding. | ||
2799 | // | ||
2800 | psSrc = (short *) src; | ||
2801 | count = count / 2; | ||
2802 | while (count--) { | ||
2803 | lAudioSample = | ||
2804 | (((long) psSrc[0] + (long) psSrc[1]) / 2); | ||
2805 | if (lAudioSample > 0x7fff) { | ||
2806 | lAudioSample = 0x7fff; | ||
2807 | } | ||
2808 | psSrc += 2; | ||
2809 | *dst++ = (char) ((short) lAudioSample >> 8); | ||
2810 | } | ||
2811 | } | ||
2812 | } | ||
2813 | |||
2814 | // | ||
2815 | // cs_copy_to_user() | ||
2816 | // replacement for the standard copy_to_user, to allow for a conversion from | ||
2817 | // 16 bit to 8 bit if the record conversion is active. the cs4281 has some | ||
2818 | // issues with 8 bit capture, so the driver always captures data in 16 bit | ||
2819 | // and then if the user requested 8 bit, converts from 16 to 8 bit. | ||
2820 | // | ||
2821 | static unsigned cs_copy_to_user(struct cs4281_state *s, void __user *dest, | ||
2822 | unsigned *hwsrc, unsigned cnt, | ||
2823 | unsigned *copied) | ||
2824 | { | ||
2825 | void *src = hwsrc; //default to the standard destination buffer addr | ||
2826 | |||
2827 | CS_DBGOUT(CS_FUNCTION, 6, printk(KERN_INFO | ||
2828 | "cs_copy_to_user()+ fmt=0x%x fmt_o=0x%x cnt=%d dest=%p\n", | ||
2829 | s->prop_adc.fmt, s->prop_adc.fmt_original, | ||
2830 | (unsigned) cnt, dest)); | ||
2831 | |||
2832 | if (cnt > s->dma_adc.dmasize) { | ||
2833 | cnt = s->dma_adc.dmasize; | ||
2834 | } | ||
2835 | if (!cnt) { | ||
2836 | *copied = 0; | ||
2837 | return 0; | ||
2838 | } | ||
2839 | if (s->conversion) { | ||
2840 | if (!s->tmpbuff) { | ||
2841 | *copied = cnt / 2; | ||
2842 | return 0; | ||
2843 | } | ||
2844 | CopySamples(s->tmpbuff, (void *) hwsrc, cnt, | ||
2845 | (unsigned) s->prop_adc.channels, | ||
2846 | s->prop_adc.fmt_original); | ||
2847 | src = s->tmpbuff; | ||
2848 | cnt = cnt / 2; | ||
2849 | } | ||
2850 | |||
2851 | if (copy_to_user(dest, src, cnt)) { | ||
2852 | *copied = 0; | ||
2853 | return -EFAULT; | ||
2854 | } | ||
2855 | *copied = cnt; | ||
2856 | CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO | ||
2857 | "cs4281: cs_copy_to_user()- copied bytes is %d \n", cnt)); | ||
2858 | return 0; | ||
2859 | } | ||
2860 | |||
2861 | // --------------------------------------------------------------------- | ||
2862 | |||
2863 | static ssize_t cs4281_read(struct file *file, char __user *buffer, size_t count, | ||
2864 | loff_t * ppos) | ||
2865 | { | ||
2866 | struct cs4281_state *s = | ||
2867 | (struct cs4281_state *) file->private_data; | ||
2868 | ssize_t ret; | ||
2869 | unsigned long flags; | ||
2870 | unsigned swptr; | ||
2871 | int cnt; | ||
2872 | unsigned copied = 0; | ||
2873 | |||
2874 | CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2, | ||
2875 | printk(KERN_INFO "cs4281: cs4281_read()+ %Zu \n", count)); | ||
2876 | |||
2877 | VALIDATE_STATE(s); | ||
2878 | if (s->dma_adc.mapped) | ||
2879 | return -ENXIO; | ||
2880 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | ||
2881 | return ret; | ||
2882 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
2883 | return -EFAULT; | ||
2884 | ret = 0; | ||
2885 | // | ||
2886 | // "count" is the amount of bytes to read (from app), is decremented each loop | ||
2887 | // by the amount of bytes that have been returned to the user buffer. | ||
2888 | // "cnt" is the running total of each read from the buffer (changes each loop) | ||
2889 | // "buffer" points to the app's buffer | ||
2890 | // "ret" keeps a running total of the amount of bytes that have been copied | ||
2891 | // to the user buffer. | ||
2892 | // "copied" is the total bytes copied into the user buffer for each loop. | ||
2893 | // | ||
2894 | while (count > 0) { | ||
2895 | CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO | ||
2896 | "_read() count>0 count=%Zu .count=%d .swptr=%d .hwptr=%d \n", | ||
2897 | count, s->dma_adc.count, | ||
2898 | s->dma_adc.swptr, s->dma_adc.hwptr)); | ||
2899 | spin_lock_irqsave(&s->lock, flags); | ||
2900 | |||
2901 | // get the current copy point of the sw buffer | ||
2902 | swptr = s->dma_adc.swptr; | ||
2903 | |||
2904 | // cnt is the amount of unread bytes from the end of the | ||
2905 | // hw buffer to the current sw pointer | ||
2906 | cnt = s->dma_adc.dmasize - swptr; | ||
2907 | |||
2908 | // dma_adc.count is the current total bytes that have not been read. | ||
2909 | // if the amount of unread bytes from the current sw pointer to the | ||
2910 | // end of the buffer is greater than the current total bytes that | ||
2911 | // have not been read, then set the "cnt" (unread bytes) to the | ||
2912 | // amount of unread bytes. | ||
2913 | |||
2914 | if (s->dma_adc.count < cnt) | ||
2915 | cnt = s->dma_adc.count; | ||
2916 | spin_unlock_irqrestore(&s->lock, flags); | ||
2917 | // | ||
2918 | // if we are converting from 8/16 then we need to copy | ||
2919 | // twice the number of 16 bit bytes then 8 bit bytes. | ||
2920 | // | ||
2921 | if (s->conversion) { | ||
2922 | if (cnt > (count * 2)) | ||
2923 | cnt = (count * 2); | ||
2924 | } else { | ||
2925 | if (cnt > count) | ||
2926 | cnt = count; | ||
2927 | } | ||
2928 | // | ||
2929 | // "cnt" NOW is the smaller of the amount that will be read, | ||
2930 | // and the amount that is requested in this read (or partial). | ||
2931 | // if there are no bytes in the buffer to read, then start the | ||
2932 | // ADC and wait for the interrupt handler to wake us up. | ||
2933 | // | ||
2934 | if (cnt <= 0) { | ||
2935 | |||
2936 | // start up the dma engine and then continue back to the top of | ||
2937 | // the loop when wake up occurs. | ||
2938 | start_adc(s); | ||
2939 | if (file->f_flags & O_NONBLOCK) | ||
2940 | return ret ? ret : -EAGAIN; | ||
2941 | interruptible_sleep_on(&s->dma_adc.wait); | ||
2942 | if (signal_pending(current)) | ||
2943 | return ret ? ret : -ERESTARTSYS; | ||
2944 | continue; | ||
2945 | } | ||
2946 | // there are bytes in the buffer to read. | ||
2947 | // copy from the hw buffer over to the user buffer. | ||
2948 | // user buffer is designated by "buffer" | ||
2949 | // virtual address to copy from is rawbuf+swptr | ||
2950 | // the "cnt" is the number of bytes to read. | ||
2951 | |||
2952 | CS_DBGOUT(CS_WAVE_READ, 2, printk(KERN_INFO | ||
2953 | "_read() copy_to cnt=%d count=%Zu ", cnt, count)); | ||
2954 | CS_DBGOUT(CS_WAVE_READ, 8, printk(KERN_INFO | ||
2955 | " .dmasize=%d .count=%d buffer=%p ret=%Zd\n", | ||
2956 | s->dma_adc.dmasize, s->dma_adc.count, buffer, ret)); | ||
2957 | |||
2958 | if (cs_copy_to_user | ||
2959 | (s, buffer, s->dma_adc.rawbuf + swptr, cnt, &copied)) | ||
2960 | return ret ? ret : -EFAULT; | ||
2961 | swptr = (swptr + cnt) % s->dma_adc.dmasize; | ||
2962 | spin_lock_irqsave(&s->lock, flags); | ||
2963 | s->dma_adc.swptr = swptr; | ||
2964 | s->dma_adc.count -= cnt; | ||
2965 | spin_unlock_irqrestore(&s->lock, flags); | ||
2966 | count -= copied; | ||
2967 | buffer += copied; | ||
2968 | ret += copied; | ||
2969 | start_adc(s); | ||
2970 | } | ||
2971 | CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2, | ||
2972 | printk(KERN_INFO "cs4281: cs4281_read()- %Zd\n", ret)); | ||
2973 | return ret; | ||
2974 | } | ||
2975 | |||
2976 | |||
2977 | static ssize_t cs4281_write(struct file *file, const char __user *buffer, | ||
2978 | size_t count, loff_t * ppos) | ||
2979 | { | ||
2980 | struct cs4281_state *s = | ||
2981 | (struct cs4281_state *) file->private_data; | ||
2982 | ssize_t ret; | ||
2983 | unsigned long flags; | ||
2984 | unsigned swptr, hwptr, busaddr; | ||
2985 | int cnt; | ||
2986 | |||
2987 | CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2, | ||
2988 | printk(KERN_INFO "cs4281: cs4281_write()+ count=%Zu\n", | ||
2989 | count)); | ||
2990 | VALIDATE_STATE(s); | ||
2991 | |||
2992 | if (s->dma_dac.mapped) | ||
2993 | return -ENXIO; | ||
2994 | if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s))) | ||
2995 | return ret; | ||
2996 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
2997 | return -EFAULT; | ||
2998 | ret = 0; | ||
2999 | while (count > 0) { | ||
3000 | spin_lock_irqsave(&s->lock, flags); | ||
3001 | if (s->dma_dac.count < 0) { | ||
3002 | s->dma_dac.count = 0; | ||
3003 | s->dma_dac.swptr = s->dma_dac.hwptr; | ||
3004 | } | ||
3005 | if (s->dma_dac.underrun) { | ||
3006 | s->dma_dac.underrun = 0; | ||
3007 | hwptr = readl(s->pBA0 + BA0_DCA0); | ||
3008 | busaddr = virt_to_bus(s->dma_dac.rawbuf); | ||
3009 | hwptr -= (unsigned) busaddr; | ||
3010 | s->dma_dac.swptr = s->dma_dac.hwptr = hwptr; | ||
3011 | } | ||
3012 | swptr = s->dma_dac.swptr; | ||
3013 | cnt = s->dma_dac.dmasize - swptr; | ||
3014 | if (s->dma_dac.count + cnt > s->dma_dac.dmasize) | ||
3015 | cnt = s->dma_dac.dmasize - s->dma_dac.count; | ||
3016 | spin_unlock_irqrestore(&s->lock, flags); | ||
3017 | if (cnt > count) | ||
3018 | cnt = count; | ||
3019 | if (cnt <= 0) { | ||
3020 | start_dac(s); | ||
3021 | if (file->f_flags & O_NONBLOCK) | ||
3022 | return ret ? ret : -EAGAIN; | ||
3023 | interruptible_sleep_on(&s->dma_dac.wait); | ||
3024 | if (signal_pending(current)) | ||
3025 | return ret ? ret : -ERESTARTSYS; | ||
3026 | continue; | ||
3027 | } | ||
3028 | if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) | ||
3029 | return ret ? ret : -EFAULT; | ||
3030 | swptr = (swptr + cnt) % s->dma_dac.dmasize; | ||
3031 | spin_lock_irqsave(&s->lock, flags); | ||
3032 | s->dma_dac.swptr = swptr; | ||
3033 | s->dma_dac.count += cnt; | ||
3034 | s->dma_dac.endcleared = 0; | ||
3035 | spin_unlock_irqrestore(&s->lock, flags); | ||
3036 | count -= cnt; | ||
3037 | buffer += cnt; | ||
3038 | ret += cnt; | ||
3039 | start_dac(s); | ||
3040 | } | ||
3041 | CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2, | ||
3042 | printk(KERN_INFO "cs4281: cs4281_write()- %Zd\n", ret)); | ||
3043 | return ret; | ||
3044 | } | ||
3045 | |||
3046 | |||
3047 | static unsigned int cs4281_poll(struct file *file, | ||
3048 | struct poll_table_struct *wait) | ||
3049 | { | ||
3050 | struct cs4281_state *s = | ||
3051 | (struct cs4281_state *) file->private_data; | ||
3052 | unsigned long flags; | ||
3053 | unsigned int mask = 0; | ||
3054 | |||
3055 | CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4, | ||
3056 | printk(KERN_INFO "cs4281: cs4281_poll()+\n")); | ||
3057 | VALIDATE_STATE(s); | ||
3058 | if (file->f_mode & FMODE_WRITE) { | ||
3059 | CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4, | ||
3060 | printk(KERN_INFO | ||
3061 | "cs4281: cs4281_poll() wait on FMODE_WRITE\n")); | ||
3062 | if(!s->dma_dac.ready && prog_dmabuf_dac(s)) | ||
3063 | return 0; | ||
3064 | poll_wait(file, &s->dma_dac.wait, wait); | ||
3065 | } | ||
3066 | if (file->f_mode & FMODE_READ) { | ||
3067 | CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4, | ||
3068 | printk(KERN_INFO | ||
3069 | "cs4281: cs4281_poll() wait on FMODE_READ\n")); | ||
3070 | if(!s->dma_dac.ready && prog_dmabuf_adc(s)) | ||
3071 | return 0; | ||
3072 | poll_wait(file, &s->dma_adc.wait, wait); | ||
3073 | } | ||
3074 | spin_lock_irqsave(&s->lock, flags); | ||
3075 | cs4281_update_ptr(s,CS_FALSE); | ||
3076 | if (file->f_mode & FMODE_WRITE) { | ||
3077 | if (s->dma_dac.mapped) { | ||
3078 | if (s->dma_dac.count >= | ||
3079 | (signed) s->dma_dac.fragsize) { | ||
3080 | if (s->dma_dac.wakeup) | ||
3081 | mask |= POLLOUT | POLLWRNORM; | ||
3082 | else | ||
3083 | mask = 0; | ||
3084 | s->dma_dac.wakeup = 0; | ||
3085 | } | ||
3086 | } else { | ||
3087 | if ((signed) (s->dma_dac.dmasize/2) >= s->dma_dac.count) | ||
3088 | mask |= POLLOUT | POLLWRNORM; | ||
3089 | } | ||
3090 | } else if (file->f_mode & FMODE_READ) { | ||
3091 | if (s->dma_adc.mapped) { | ||
3092 | if (s->dma_adc.count >= (signed) s->dma_adc.fragsize) | ||
3093 | mask |= POLLIN | POLLRDNORM; | ||
3094 | } else { | ||
3095 | if (s->dma_adc.count > 0) | ||
3096 | mask |= POLLIN | POLLRDNORM; | ||
3097 | } | ||
3098 | } | ||
3099 | spin_unlock_irqrestore(&s->lock, flags); | ||
3100 | CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4, | ||
3101 | printk(KERN_INFO "cs4281: cs4281_poll()- 0x%.8x\n", | ||
3102 | mask)); | ||
3103 | return mask; | ||
3104 | } | ||
3105 | |||
3106 | |||
3107 | static int cs4281_mmap(struct file *file, struct vm_area_struct *vma) | ||
3108 | { | ||
3109 | struct cs4281_state *s = | ||
3110 | (struct cs4281_state *) file->private_data; | ||
3111 | struct dmabuf *db; | ||
3112 | int ret; | ||
3113 | unsigned long size; | ||
3114 | |||
3115 | CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4, | ||
3116 | printk(KERN_INFO "cs4281: cs4281_mmap()+\n")); | ||
3117 | |||
3118 | VALIDATE_STATE(s); | ||
3119 | if (vma->vm_flags & VM_WRITE) { | ||
3120 | if ((ret = prog_dmabuf_dac(s)) != 0) | ||
3121 | return ret; | ||
3122 | db = &s->dma_dac; | ||
3123 | } else if (vma->vm_flags & VM_READ) { | ||
3124 | if ((ret = prog_dmabuf_adc(s)) != 0) | ||
3125 | return ret; | ||
3126 | db = &s->dma_adc; | ||
3127 | } else | ||
3128 | return -EINVAL; | ||
3129 | // | ||
3130 | // only support PLAYBACK for now | ||
3131 | // | ||
3132 | db = &s->dma_dac; | ||
3133 | |||
3134 | if (cs4x_pgoff(vma) != 0) | ||
3135 | return -EINVAL; | ||
3136 | size = vma->vm_end - vma->vm_start; | ||
3137 | if (size > (PAGE_SIZE << db->buforder)) | ||
3138 | return -EINVAL; | ||
3139 | if (remap_pfn_range(vma, vma->vm_start, | ||
3140 | virt_to_phys(db->rawbuf) >> PAGE_SHIFT, | ||
3141 | size, vma->vm_page_prot)) | ||
3142 | return -EAGAIN; | ||
3143 | db->mapped = 1; | ||
3144 | |||
3145 | CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4, | ||
3146 | printk(KERN_INFO "cs4281: cs4281_mmap()- 0 size=%d\n", | ||
3147 | (unsigned) size)); | ||
3148 | |||
3149 | return 0; | ||
3150 | } | ||
3151 | |||
3152 | |||
3153 | static int cs4281_ioctl(struct inode *inode, struct file *file, | ||
3154 | unsigned int cmd, unsigned long arg) | ||
3155 | { | ||
3156 | struct cs4281_state *s = | ||
3157 | (struct cs4281_state *) file->private_data; | ||
3158 | unsigned long flags; | ||
3159 | audio_buf_info abinfo; | ||
3160 | count_info cinfo; | ||
3161 | int val, mapped, ret; | ||
3162 | int __user *p = (int __user *)arg; | ||
3163 | |||
3164 | CS_DBGOUT(CS_FUNCTION, 4, printk(KERN_INFO | ||
3165 | "cs4281: cs4281_ioctl(): file=%p cmd=0x%.8x\n", file, cmd)); | ||
3166 | #if CSDEBUG | ||
3167 | cs_printioctl(cmd); | ||
3168 | #endif | ||
3169 | VALIDATE_STATE(s); | ||
3170 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || | ||
3171 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
3172 | switch (cmd) { | ||
3173 | case OSS_GETVERSION: | ||
3174 | CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO | ||
3175 | "cs4281: cs4281_ioctl(): SOUND_VERSION=0x%.8x\n", | ||
3176 | SOUND_VERSION)); | ||
3177 | return put_user(SOUND_VERSION, p); | ||
3178 | |||
3179 | case SNDCTL_DSP_SYNC: | ||
3180 | CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO | ||
3181 | "cs4281: cs4281_ioctl(): DSP_SYNC\n")); | ||
3182 | if (file->f_mode & FMODE_WRITE) | ||
3183 | return drain_dac(s, | ||
3184 | 0 /*file->f_flags & O_NONBLOCK */ | ||
3185 | ); | ||
3186 | return 0; | ||
3187 | |||
3188 | case SNDCTL_DSP_SETDUPLEX: | ||
3189 | return 0; | ||
3190 | |||
3191 | case SNDCTL_DSP_GETCAPS: | ||
3192 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | | ||
3193 | DSP_CAP_TRIGGER | DSP_CAP_MMAP, | ||
3194 | p); | ||
3195 | |||
3196 | case SNDCTL_DSP_RESET: | ||
3197 | CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO | ||
3198 | "cs4281: cs4281_ioctl(): DSP_RESET\n")); | ||
3199 | if (file->f_mode & FMODE_WRITE) { | ||
3200 | stop_dac(s); | ||
3201 | synchronize_irq(s->irq); | ||
3202 | s->dma_dac.swptr = s->dma_dac.hwptr = | ||
3203 | s->dma_dac.count = s->dma_dac.total_bytes = | ||
3204 | s->dma_dac.blocks = s->dma_dac.wakeup = 0; | ||
3205 | prog_codec(s, CS_TYPE_DAC); | ||
3206 | } | ||
3207 | if (file->f_mode & FMODE_READ) { | ||
3208 | stop_adc(s); | ||
3209 | synchronize_irq(s->irq); | ||
3210 | s->dma_adc.swptr = s->dma_adc.hwptr = | ||
3211 | s->dma_adc.count = s->dma_adc.total_bytes = | ||
3212 | s->dma_adc.blocks = s->dma_dac.wakeup = 0; | ||
3213 | prog_codec(s, CS_TYPE_ADC); | ||
3214 | } | ||
3215 | return 0; | ||
3216 | |||
3217 | case SNDCTL_DSP_SPEED: | ||
3218 | if (get_user(val, p)) | ||
3219 | return -EFAULT; | ||
3220 | CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO | ||
3221 | "cs4281: cs4281_ioctl(): DSP_SPEED val=%d\n", val)); | ||
3222 | // | ||
3223 | // support independent capture and playback channels | ||
3224 | // assume that the file mode bit determines the | ||
3225 | // direction of the data flow. | ||
3226 | // | ||
3227 | if (file->f_mode & FMODE_READ) { | ||
3228 | if (val >= 0) { | ||
3229 | stop_adc(s); | ||
3230 | s->dma_adc.ready = 0; | ||
3231 | // program sampling rates | ||
3232 | if (val > 48000) | ||
3233 | val = 48000; | ||
3234 | if (val < 6300) | ||
3235 | val = 6300; | ||
3236 | s->prop_adc.rate = val; | ||
3237 | prog_codec(s, CS_TYPE_ADC); | ||
3238 | } | ||
3239 | } | ||
3240 | if (file->f_mode & FMODE_WRITE) { | ||
3241 | if (val >= 0) { | ||
3242 | stop_dac(s); | ||
3243 | s->dma_dac.ready = 0; | ||
3244 | // program sampling rates | ||
3245 | if (val > 48000) | ||
3246 | val = 48000; | ||
3247 | if (val < 6300) | ||
3248 | val = 6300; | ||
3249 | s->prop_dac.rate = val; | ||
3250 | prog_codec(s, CS_TYPE_DAC); | ||
3251 | } | ||
3252 | } | ||
3253 | |||
3254 | if (file->f_mode & FMODE_WRITE) | ||
3255 | val = s->prop_dac.rate; | ||
3256 | else if (file->f_mode & FMODE_READ) | ||
3257 | val = s->prop_adc.rate; | ||
3258 | |||
3259 | return put_user(val, p); | ||
3260 | |||
3261 | case SNDCTL_DSP_STEREO: | ||
3262 | if (get_user(val, p)) | ||
3263 | return -EFAULT; | ||
3264 | CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO | ||
3265 | "cs4281: cs4281_ioctl(): DSP_STEREO val=%d\n", val)); | ||
3266 | if (file->f_mode & FMODE_READ) { | ||
3267 | stop_adc(s); | ||
3268 | s->dma_adc.ready = 0; | ||
3269 | s->prop_adc.channels = val ? 2 : 1; | ||
3270 | prog_codec(s, CS_TYPE_ADC); | ||
3271 | } | ||
3272 | if (file->f_mode & FMODE_WRITE) { | ||
3273 | stop_dac(s); | ||
3274 | s->dma_dac.ready = 0; | ||
3275 | s->prop_dac.channels = val ? 2 : 1; | ||
3276 | prog_codec(s, CS_TYPE_DAC); | ||
3277 | } | ||
3278 | return 0; | ||
3279 | |||
3280 | case SNDCTL_DSP_CHANNELS: | ||
3281 | if (get_user(val, p)) | ||
3282 | return -EFAULT; | ||
3283 | CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO | ||
3284 | "cs4281: cs4281_ioctl(): DSP_CHANNELS val=%d\n", | ||
3285 | val)); | ||
3286 | if (val != 0) { | ||
3287 | if (file->f_mode & FMODE_READ) { | ||
3288 | stop_adc(s); | ||
3289 | s->dma_adc.ready = 0; | ||
3290 | if (val >= 2) | ||
3291 | s->prop_adc.channels = 2; | ||
3292 | else | ||
3293 | s->prop_adc.channels = 1; | ||
3294 | prog_codec(s, CS_TYPE_ADC); | ||
3295 | } | ||
3296 | if (file->f_mode & FMODE_WRITE) { | ||
3297 | stop_dac(s); | ||
3298 | s->dma_dac.ready = 0; | ||
3299 | if (val >= 2) | ||
3300 | s->prop_dac.channels = 2; | ||
3301 | else | ||
3302 | s->prop_dac.channels = 1; | ||
3303 | prog_codec(s, CS_TYPE_DAC); | ||
3304 | } | ||
3305 | } | ||
3306 | |||
3307 | if (file->f_mode & FMODE_WRITE) | ||
3308 | val = s->prop_dac.channels; | ||
3309 | else if (file->f_mode & FMODE_READ) | ||
3310 | val = s->prop_adc.channels; | ||
3311 | |||
3312 | return put_user(val, p); | ||
3313 | |||
3314 | case SNDCTL_DSP_GETFMTS: // Returns a mask | ||
3315 | CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO | ||
3316 | "cs4281: cs4281_ioctl(): DSP_GETFMT val=0x%.8x\n", | ||
3317 | AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 | | ||
3318 | AFMT_U8)); | ||
3319 | return put_user(AFMT_S16_LE | AFMT_U16_LE | AFMT_S8 | | ||
3320 | AFMT_U8, p); | ||
3321 | |||
3322 | case SNDCTL_DSP_SETFMT: | ||
3323 | if (get_user(val, p)) | ||
3324 | return -EFAULT; | ||
3325 | CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO | ||
3326 | "cs4281: cs4281_ioctl(): DSP_SETFMT val=0x%.8x\n", | ||
3327 | val)); | ||
3328 | if (val != AFMT_QUERY) { | ||
3329 | if (file->f_mode & FMODE_READ) { | ||
3330 | stop_adc(s); | ||
3331 | s->dma_adc.ready = 0; | ||
3332 | if (val != AFMT_S16_LE | ||
3333 | && val != AFMT_U16_LE && val != AFMT_S8 | ||
3334 | && val != AFMT_U8) | ||
3335 | val = AFMT_U8; | ||
3336 | s->prop_adc.fmt = val; | ||
3337 | s->prop_adc.fmt_original = s->prop_adc.fmt; | ||
3338 | prog_codec(s, CS_TYPE_ADC); | ||
3339 | } | ||
3340 | if (file->f_mode & FMODE_WRITE) { | ||
3341 | stop_dac(s); | ||
3342 | s->dma_dac.ready = 0; | ||
3343 | if (val != AFMT_S16_LE | ||
3344 | && val != AFMT_U16_LE && val != AFMT_S8 | ||
3345 | && val != AFMT_U8) | ||
3346 | val = AFMT_U8; | ||
3347 | s->prop_dac.fmt = val; | ||
3348 | s->prop_dac.fmt_original = s->prop_dac.fmt; | ||
3349 | prog_codec(s, CS_TYPE_DAC); | ||
3350 | } | ||
3351 | } else { | ||
3352 | if (file->f_mode & FMODE_WRITE) | ||
3353 | val = s->prop_dac.fmt_original; | ||
3354 | else if (file->f_mode & FMODE_READ) | ||
3355 | val = s->prop_adc.fmt_original; | ||
3356 | } | ||
3357 | CS_DBGOUT(CS_IOCTL | CS_PARMS, 4, printk(KERN_INFO | ||
3358 | "cs4281: cs4281_ioctl(): DSP_SETFMT return val=0x%.8x\n", | ||
3359 | val)); | ||
3360 | return put_user(val, p); | ||
3361 | |||
3362 | case SNDCTL_DSP_POST: | ||
3363 | CS_DBGOUT(CS_IOCTL, 4, printk(KERN_INFO | ||
3364 | "cs4281: cs4281_ioctl(): DSP_POST\n")); | ||
3365 | return 0; | ||
3366 | |||
3367 | case SNDCTL_DSP_GETTRIGGER: | ||
3368 | val = 0; | ||
3369 | if (file->f_mode & s->ena & FMODE_READ) | ||
3370 | val |= PCM_ENABLE_INPUT; | ||
3371 | if (file->f_mode & s->ena & FMODE_WRITE) | ||
3372 | val |= PCM_ENABLE_OUTPUT; | ||
3373 | return put_user(val, p); | ||
3374 | |||
3375 | case SNDCTL_DSP_SETTRIGGER: | ||
3376 | if (get_user(val, p)) | ||
3377 | return -EFAULT; | ||
3378 | if (file->f_mode & FMODE_READ) { | ||
3379 | if (val & PCM_ENABLE_INPUT) { | ||
3380 | if (!s->dma_adc.ready | ||
3381 | && (ret = prog_dmabuf_adc(s))) | ||
3382 | return ret; | ||
3383 | start_adc(s); | ||
3384 | } else | ||
3385 | stop_adc(s); | ||
3386 | } | ||
3387 | if (file->f_mode & FMODE_WRITE) { | ||
3388 | if (val & PCM_ENABLE_OUTPUT) { | ||
3389 | if (!s->dma_dac.ready | ||
3390 | && (ret = prog_dmabuf_dac(s))) | ||
3391 | return ret; | ||
3392 | start_dac(s); | ||
3393 | } else | ||
3394 | stop_dac(s); | ||
3395 | } | ||
3396 | return 0; | ||
3397 | |||
3398 | case SNDCTL_DSP_GETOSPACE: | ||
3399 | if (!(file->f_mode & FMODE_WRITE)) | ||
3400 | return -EINVAL; | ||
3401 | if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s))) | ||
3402 | return val; | ||
3403 | spin_lock_irqsave(&s->lock, flags); | ||
3404 | cs4281_update_ptr(s,CS_FALSE); | ||
3405 | abinfo.fragsize = s->dma_dac.fragsize; | ||
3406 | if (s->dma_dac.mapped) | ||
3407 | abinfo.bytes = s->dma_dac.dmasize; | ||
3408 | else | ||
3409 | abinfo.bytes = | ||
3410 | s->dma_dac.dmasize - s->dma_dac.count; | ||
3411 | abinfo.fragstotal = s->dma_dac.numfrag; | ||
3412 | abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; | ||
3413 | CS_DBGOUT(CS_FUNCTION | CS_PARMS, 4, printk(KERN_INFO | ||
3414 | "cs4281: cs4281_ioctl(): GETOSPACE .fragsize=%d .bytes=%d .fragstotal=%d .fragments=%d\n", | ||
3415 | abinfo.fragsize,abinfo.bytes,abinfo.fragstotal, | ||
3416 | abinfo.fragments)); | ||
3417 | spin_unlock_irqrestore(&s->lock, flags); | ||
3418 | return copy_to_user(p, &abinfo, | ||
3419 | sizeof(abinfo)) ? -EFAULT : 0; | ||
3420 | |||
3421 | case SNDCTL_DSP_GETISPACE: | ||
3422 | if (!(file->f_mode & FMODE_READ)) | ||
3423 | return -EINVAL; | ||
3424 | if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s))) | ||
3425 | return val; | ||
3426 | spin_lock_irqsave(&s->lock, flags); | ||
3427 | cs4281_update_ptr(s,CS_FALSE); | ||
3428 | if (s->conversion) { | ||
3429 | abinfo.fragsize = s->dma_adc.fragsize / 2; | ||
3430 | abinfo.bytes = s->dma_adc.count / 2; | ||
3431 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
3432 | abinfo.fragments = | ||
3433 | abinfo.bytes >> (s->dma_adc.fragshift - 1); | ||
3434 | } else { | ||
3435 | abinfo.fragsize = s->dma_adc.fragsize; | ||
3436 | abinfo.bytes = s->dma_adc.count; | ||
3437 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
3438 | abinfo.fragments = | ||
3439 | abinfo.bytes >> s->dma_adc.fragshift; | ||
3440 | } | ||
3441 | spin_unlock_irqrestore(&s->lock, flags); | ||
3442 | return copy_to_user(p, &abinfo, | ||
3443 | sizeof(abinfo)) ? -EFAULT : 0; | ||
3444 | |||
3445 | case SNDCTL_DSP_NONBLOCK: | ||
3446 | file->f_flags |= O_NONBLOCK; | ||
3447 | return 0; | ||
3448 | |||
3449 | case SNDCTL_DSP_GETODELAY: | ||
3450 | if (!(file->f_mode & FMODE_WRITE)) | ||
3451 | return -EINVAL; | ||
3452 | if(!s->dma_dac.ready && prog_dmabuf_dac(s)) | ||
3453 | return 0; | ||
3454 | spin_lock_irqsave(&s->lock, flags); | ||
3455 | cs4281_update_ptr(s,CS_FALSE); | ||
3456 | val = s->dma_dac.count; | ||
3457 | spin_unlock_irqrestore(&s->lock, flags); | ||
3458 | return put_user(val, p); | ||
3459 | |||
3460 | case SNDCTL_DSP_GETIPTR: | ||
3461 | if (!(file->f_mode & FMODE_READ)) | ||
3462 | return -EINVAL; | ||
3463 | if(!s->dma_adc.ready && prog_dmabuf_adc(s)) | ||
3464 | return 0; | ||
3465 | spin_lock_irqsave(&s->lock, flags); | ||
3466 | cs4281_update_ptr(s,CS_FALSE); | ||
3467 | cinfo.bytes = s->dma_adc.total_bytes; | ||
3468 | if (s->dma_adc.mapped) { | ||
3469 | cinfo.blocks = | ||
3470 | (cinfo.bytes >> s->dma_adc.fragshift) - | ||
3471 | s->dma_adc.blocks; | ||
3472 | s->dma_adc.blocks = | ||
3473 | cinfo.bytes >> s->dma_adc.fragshift; | ||
3474 | } else { | ||
3475 | if (s->conversion) { | ||
3476 | cinfo.blocks = | ||
3477 | s->dma_adc.count / | ||
3478 | 2 >> (s->dma_adc.fragshift - 1); | ||
3479 | } else | ||
3480 | cinfo.blocks = | ||
3481 | s->dma_adc.count >> s->dma_adc. | ||
3482 | fragshift; | ||
3483 | } | ||
3484 | if (s->conversion) | ||
3485 | cinfo.ptr = s->dma_adc.hwptr / 2; | ||
3486 | else | ||
3487 | cinfo.ptr = s->dma_adc.hwptr; | ||
3488 | if (s->dma_adc.mapped) | ||
3489 | s->dma_adc.count &= s->dma_adc.fragsize - 1; | ||
3490 | spin_unlock_irqrestore(&s->lock, flags); | ||
3491 | if (copy_to_user(p, &cinfo, sizeof(cinfo))) | ||
3492 | return -EFAULT; | ||
3493 | return 0; | ||
3494 | |||
3495 | case SNDCTL_DSP_GETOPTR: | ||
3496 | if (!(file->f_mode & FMODE_WRITE)) | ||
3497 | return -EINVAL; | ||
3498 | if(!s->dma_dac.ready && prog_dmabuf_dac(s)) | ||
3499 | return 0; | ||
3500 | spin_lock_irqsave(&s->lock, flags); | ||
3501 | cs4281_update_ptr(s,CS_FALSE); | ||
3502 | cinfo.bytes = s->dma_dac.total_bytes; | ||
3503 | if (s->dma_dac.mapped) { | ||
3504 | cinfo.blocks = | ||
3505 | (cinfo.bytes >> s->dma_dac.fragshift) - | ||
3506 | s->dma_dac.blocks; | ||
3507 | s->dma_dac.blocks = | ||
3508 | cinfo.bytes >> s->dma_dac.fragshift; | ||
3509 | } else { | ||
3510 | cinfo.blocks = | ||
3511 | s->dma_dac.count >> s->dma_dac.fragshift; | ||
3512 | } | ||
3513 | cinfo.ptr = s->dma_dac.hwptr; | ||
3514 | if (s->dma_dac.mapped) | ||
3515 | s->dma_dac.count &= s->dma_dac.fragsize - 1; | ||
3516 | spin_unlock_irqrestore(&s->lock, flags); | ||
3517 | if (copy_to_user(p, &cinfo, sizeof(cinfo))) | ||
3518 | return -EFAULT; | ||
3519 | return 0; | ||
3520 | |||
3521 | case SNDCTL_DSP_GETBLKSIZE: | ||
3522 | if (file->f_mode & FMODE_WRITE) { | ||
3523 | if ((val = prog_dmabuf_dac(s))) | ||
3524 | return val; | ||
3525 | return put_user(s->dma_dac.fragsize, p); | ||
3526 | } | ||
3527 | if ((val = prog_dmabuf_adc(s))) | ||
3528 | return val; | ||
3529 | if (s->conversion) | ||
3530 | return put_user(s->dma_adc.fragsize / 2, p); | ||
3531 | else | ||
3532 | return put_user(s->dma_adc.fragsize, p); | ||
3533 | |||
3534 | case SNDCTL_DSP_SETFRAGMENT: | ||
3535 | if (get_user(val, p)) | ||
3536 | return -EFAULT; | ||
3537 | return 0; // Say OK, but do nothing. | ||
3538 | |||
3539 | case SNDCTL_DSP_SUBDIVIDE: | ||
3540 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) | ||
3541 | || (file->f_mode & FMODE_WRITE | ||
3542 | && s->dma_dac.subdivision)) return -EINVAL; | ||
3543 | if (get_user(val, p)) | ||
3544 | return -EFAULT; | ||
3545 | if (val != 1 && val != 2 && val != 4) | ||
3546 | return -EINVAL; | ||
3547 | if (file->f_mode & FMODE_READ) | ||
3548 | s->dma_adc.subdivision = val; | ||
3549 | else if (file->f_mode & FMODE_WRITE) | ||
3550 | s->dma_dac.subdivision = val; | ||
3551 | return 0; | ||
3552 | |||
3553 | case SOUND_PCM_READ_RATE: | ||
3554 | if (file->f_mode & FMODE_READ) | ||
3555 | return put_user(s->prop_adc.rate, p); | ||
3556 | else if (file->f_mode & FMODE_WRITE) | ||
3557 | return put_user(s->prop_dac.rate, p); | ||
3558 | |||
3559 | case SOUND_PCM_READ_CHANNELS: | ||
3560 | if (file->f_mode & FMODE_READ) | ||
3561 | return put_user(s->prop_adc.channels, p); | ||
3562 | else if (file->f_mode & FMODE_WRITE) | ||
3563 | return put_user(s->prop_dac.channels, p); | ||
3564 | |||
3565 | case SOUND_PCM_READ_BITS: | ||
3566 | if (file->f_mode & FMODE_READ) | ||
3567 | return | ||
3568 | put_user( | ||
3569 | (s->prop_adc. | ||
3570 | fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16, | ||
3571 | p); | ||
3572 | else if (file->f_mode & FMODE_WRITE) | ||
3573 | return | ||
3574 | put_user( | ||
3575 | (s->prop_dac. | ||
3576 | fmt & (AFMT_S8 | AFMT_U8)) ? 8 : 16, | ||
3577 | p); | ||
3578 | |||
3579 | case SOUND_PCM_WRITE_FILTER: | ||
3580 | case SNDCTL_DSP_SETSYNCRO: | ||
3581 | case SOUND_PCM_READ_FILTER: | ||
3582 | return -EINVAL; | ||
3583 | } | ||
3584 | return mixer_ioctl(s, cmd, arg); | ||
3585 | } | ||
3586 | |||
3587 | |||
3588 | static int cs4281_release(struct inode *inode, struct file *file) | ||
3589 | { | ||
3590 | struct cs4281_state *s = | ||
3591 | (struct cs4281_state *) file->private_data; | ||
3592 | |||
3593 | CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk(KERN_INFO | ||
3594 | "cs4281: cs4281_release(): inode=%p file=%p f_mode=%d\n", | ||
3595 | inode, file, file->f_mode)); | ||
3596 | |||
3597 | VALIDATE_STATE(s); | ||
3598 | |||
3599 | if (file->f_mode & FMODE_WRITE) { | ||
3600 | drain_dac(s, file->f_flags & O_NONBLOCK); | ||
3601 | mutex_lock(&s->open_sem_dac); | ||
3602 | stop_dac(s); | ||
3603 | dealloc_dmabuf(s, &s->dma_dac); | ||
3604 | s->open_mode &= ~FMODE_WRITE; | ||
3605 | mutex_unlock(&s->open_sem_dac); | ||
3606 | wake_up(&s->open_wait_dac); | ||
3607 | } | ||
3608 | if (file->f_mode & FMODE_READ) { | ||
3609 | drain_adc(s, file->f_flags & O_NONBLOCK); | ||
3610 | mutex_lock(&s->open_sem_adc); | ||
3611 | stop_adc(s); | ||
3612 | dealloc_dmabuf(s, &s->dma_adc); | ||
3613 | s->open_mode &= ~FMODE_READ; | ||
3614 | mutex_unlock(&s->open_sem_adc); | ||
3615 | wake_up(&s->open_wait_adc); | ||
3616 | } | ||
3617 | return 0; | ||
3618 | } | ||
3619 | |||
3620 | static int cs4281_open(struct inode *inode, struct file *file) | ||
3621 | { | ||
3622 | unsigned int minor = iminor(inode); | ||
3623 | struct cs4281_state *s=NULL; | ||
3624 | struct list_head *entry; | ||
3625 | |||
3626 | CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO | ||
3627 | "cs4281: cs4281_open(): inode=%p file=%p f_mode=0x%x\n", | ||
3628 | inode, file, file->f_mode)); | ||
3629 | |||
3630 | list_for_each(entry, &cs4281_devs) | ||
3631 | { | ||
3632 | s = list_entry(entry, struct cs4281_state, list); | ||
3633 | |||
3634 | if (!((s->dev_audio ^ minor) & ~0xf)) | ||
3635 | break; | ||
3636 | } | ||
3637 | if (entry == &cs4281_devs) | ||
3638 | return -ENODEV; | ||
3639 | if (!s) { | ||
3640 | CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO | ||
3641 | "cs4281: cs4281_open(): Error - unable to find audio state struct\n")); | ||
3642 | return -ENODEV; | ||
3643 | } | ||
3644 | VALIDATE_STATE(s); | ||
3645 | file->private_data = s; | ||
3646 | |||
3647 | // wait for device to become free | ||
3648 | if (!(file->f_mode & (FMODE_WRITE | FMODE_READ))) { | ||
3649 | CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, printk(KERN_INFO | ||
3650 | "cs4281: cs4281_open(): Error - must open READ and/or WRITE\n")); | ||
3651 | return -ENODEV; | ||
3652 | } | ||
3653 | if (file->f_mode & FMODE_WRITE) { | ||
3654 | mutex_lock(&s->open_sem_dac); | ||
3655 | while (s->open_mode & FMODE_WRITE) { | ||
3656 | if (file->f_flags & O_NONBLOCK) { | ||
3657 | mutex_unlock(&s->open_sem_dac); | ||
3658 | return -EBUSY; | ||
3659 | } | ||
3660 | mutex_unlock(&s->open_sem_dac); | ||
3661 | interruptible_sleep_on(&s->open_wait_dac); | ||
3662 | |||
3663 | if (signal_pending(current)) | ||
3664 | return -ERESTARTSYS; | ||
3665 | mutex_lock(&s->open_sem_dac); | ||
3666 | } | ||
3667 | } | ||
3668 | if (file->f_mode & FMODE_READ) { | ||
3669 | mutex_lock(&s->open_sem_adc); | ||
3670 | while (s->open_mode & FMODE_READ) { | ||
3671 | if (file->f_flags & O_NONBLOCK) { | ||
3672 | mutex_unlock(&s->open_sem_adc); | ||
3673 | return -EBUSY; | ||
3674 | } | ||
3675 | mutex_unlock(&s->open_sem_adc); | ||
3676 | interruptible_sleep_on(&s->open_wait_adc); | ||
3677 | |||
3678 | if (signal_pending(current)) | ||
3679 | return -ERESTARTSYS; | ||
3680 | mutex_lock(&s->open_sem_adc); | ||
3681 | } | ||
3682 | } | ||
3683 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
3684 | if (file->f_mode & FMODE_READ) { | ||
3685 | s->prop_adc.fmt = AFMT_U8; | ||
3686 | s->prop_adc.fmt_original = s->prop_adc.fmt; | ||
3687 | s->prop_adc.channels = 1; | ||
3688 | s->prop_adc.rate = 8000; | ||
3689 | s->prop_adc.clkdiv = 96 | 0x80; | ||
3690 | s->conversion = 0; | ||
3691 | s->ena &= ~FMODE_READ; | ||
3692 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = | ||
3693 | s->dma_adc.subdivision = 0; | ||
3694 | mutex_unlock(&s->open_sem_adc); | ||
3695 | |||
3696 | if (prog_dmabuf_adc(s)) { | ||
3697 | CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR | ||
3698 | "cs4281: adc Program dmabufs failed.\n")); | ||
3699 | cs4281_release(inode, file); | ||
3700 | return -ENOMEM; | ||
3701 | } | ||
3702 | prog_codec(s, CS_TYPE_ADC); | ||
3703 | } | ||
3704 | if (file->f_mode & FMODE_WRITE) { | ||
3705 | s->prop_dac.fmt = AFMT_U8; | ||
3706 | s->prop_dac.fmt_original = s->prop_dac.fmt; | ||
3707 | s->prop_dac.channels = 1; | ||
3708 | s->prop_dac.rate = 8000; | ||
3709 | s->prop_dac.clkdiv = 96 | 0x80; | ||
3710 | s->conversion = 0; | ||
3711 | s->ena &= ~FMODE_WRITE; | ||
3712 | s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = | ||
3713 | s->dma_dac.subdivision = 0; | ||
3714 | mutex_unlock(&s->open_sem_dac); | ||
3715 | |||
3716 | if (prog_dmabuf_dac(s)) { | ||
3717 | CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR | ||
3718 | "cs4281: dac Program dmabufs failed.\n")); | ||
3719 | cs4281_release(inode, file); | ||
3720 | return -ENOMEM; | ||
3721 | } | ||
3722 | prog_codec(s, CS_TYPE_DAC); | ||
3723 | } | ||
3724 | CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, | ||
3725 | printk(KERN_INFO "cs4281: cs4281_open()- 0\n")); | ||
3726 | return nonseekable_open(inode, file); | ||
3727 | } | ||
3728 | |||
3729 | |||
3730 | // ****************************************************************************************** | ||
3731 | // Wave (audio) file operations struct. | ||
3732 | // ****************************************************************************************** | ||
3733 | static /*const */ struct file_operations cs4281_audio_fops = { | ||
3734 | .owner = THIS_MODULE, | ||
3735 | .llseek = no_llseek, | ||
3736 | .read = cs4281_read, | ||
3737 | .write = cs4281_write, | ||
3738 | .poll = cs4281_poll, | ||
3739 | .ioctl = cs4281_ioctl, | ||
3740 | .mmap = cs4281_mmap, | ||
3741 | .open = cs4281_open, | ||
3742 | .release = cs4281_release, | ||
3743 | }; | ||
3744 | |||
3745 | // --------------------------------------------------------------------- | ||
3746 | |||
3747 | // hold spinlock for the following! | ||
3748 | static void cs4281_handle_midi(struct cs4281_state *s) | ||
3749 | { | ||
3750 | unsigned char ch; | ||
3751 | int wake; | ||
3752 | unsigned temp1; | ||
3753 | |||
3754 | wake = 0; | ||
3755 | while (!(readl(s->pBA0 + BA0_MIDSR) & 0x80)) { | ||
3756 | ch = readl(s->pBA0 + BA0_MIDRP); | ||
3757 | if (s->midi.icnt < MIDIINBUF) { | ||
3758 | s->midi.ibuf[s->midi.iwr] = ch; | ||
3759 | s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF; | ||
3760 | s->midi.icnt++; | ||
3761 | } | ||
3762 | wake = 1; | ||
3763 | } | ||
3764 | if (wake) | ||
3765 | wake_up(&s->midi.iwait); | ||
3766 | wake = 0; | ||
3767 | while (!(readl(s->pBA0 + BA0_MIDSR) & 0x40) && s->midi.ocnt > 0) { | ||
3768 | temp1 = (s->midi.obuf[s->midi.ord]) & 0x000000ff; | ||
3769 | writel(temp1, s->pBA0 + BA0_MIDWP); | ||
3770 | s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF; | ||
3771 | s->midi.ocnt--; | ||
3772 | if (s->midi.ocnt < MIDIOUTBUF - 16) | ||
3773 | wake = 1; | ||
3774 | } | ||
3775 | if (wake) | ||
3776 | wake_up(&s->midi.owait); | ||
3777 | } | ||
3778 | |||
3779 | |||
3780 | |||
3781 | static irqreturn_t cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
3782 | { | ||
3783 | struct cs4281_state *s = (struct cs4281_state *) dev_id; | ||
3784 | unsigned int temp1; | ||
3785 | |||
3786 | // fastpath out, to ease interrupt sharing | ||
3787 | temp1 = readl(s->pBA0 + BA0_HISR); // Get Int Status reg. | ||
3788 | |||
3789 | CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO | ||
3790 | "cs4281: cs4281_interrupt() BA0_HISR=0x%.8x\n", temp1)); | ||
3791 | /* | ||
3792 | * If not DMA or MIDI interrupt, then just return. | ||
3793 | */ | ||
3794 | if (!(temp1 & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) { | ||
3795 | writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR); | ||
3796 | CS_DBGOUT(CS_INTERRUPT, 9, printk(KERN_INFO | ||
3797 | "cs4281: cs4281_interrupt(): returning not cs4281 interrupt.\n")); | ||
3798 | return IRQ_NONE; | ||
3799 | } | ||
3800 | |||
3801 | if (temp1 & HISR_DMA0) // If play interrupt, | ||
3802 | readl(s->pBA0 + BA0_HDSR0); // clear the source. | ||
3803 | |||
3804 | if (temp1 & HISR_DMA1) // Same for play. | ||
3805 | readl(s->pBA0 + BA0_HDSR1); | ||
3806 | writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR); // Local EOI | ||
3807 | |||
3808 | spin_lock(&s->lock); | ||
3809 | cs4281_update_ptr(s,CS_TRUE); | ||
3810 | cs4281_handle_midi(s); | ||
3811 | spin_unlock(&s->lock); | ||
3812 | return IRQ_HANDLED; | ||
3813 | } | ||
3814 | |||
3815 | // ************************************************************************** | ||
3816 | |||
3817 | static void cs4281_midi_timer(unsigned long data) | ||
3818 | { | ||
3819 | struct cs4281_state *s = (struct cs4281_state *) data; | ||
3820 | unsigned long flags; | ||
3821 | |||
3822 | spin_lock_irqsave(&s->lock, flags); | ||
3823 | cs4281_handle_midi(s); | ||
3824 | spin_unlock_irqrestore(&s->lock, flags); | ||
3825 | s->midi.timer.expires = jiffies + 1; | ||
3826 | add_timer(&s->midi.timer); | ||
3827 | } | ||
3828 | |||
3829 | |||
3830 | // --------------------------------------------------------------------- | ||
3831 | |||
3832 | static ssize_t cs4281_midi_read(struct file *file, char __user *buffer, | ||
3833 | size_t count, loff_t * ppos) | ||
3834 | { | ||
3835 | struct cs4281_state *s = | ||
3836 | (struct cs4281_state *) file->private_data; | ||
3837 | ssize_t ret; | ||
3838 | unsigned long flags; | ||
3839 | unsigned ptr; | ||
3840 | int cnt; | ||
3841 | |||
3842 | VALIDATE_STATE(s); | ||
3843 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
3844 | return -EFAULT; | ||
3845 | ret = 0; | ||
3846 | while (count > 0) { | ||
3847 | spin_lock_irqsave(&s->lock, flags); | ||
3848 | ptr = s->midi.ird; | ||
3849 | cnt = MIDIINBUF - ptr; | ||
3850 | if (s->midi.icnt < cnt) | ||
3851 | cnt = s->midi.icnt; | ||
3852 | spin_unlock_irqrestore(&s->lock, flags); | ||
3853 | if (cnt > count) | ||
3854 | cnt = count; | ||
3855 | if (cnt <= 0) { | ||
3856 | if (file->f_flags & O_NONBLOCK) | ||
3857 | return ret ? ret : -EAGAIN; | ||
3858 | interruptible_sleep_on(&s->midi.iwait); | ||
3859 | if (signal_pending(current)) | ||
3860 | return ret ? ret : -ERESTARTSYS; | ||
3861 | continue; | ||
3862 | } | ||
3863 | if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) | ||
3864 | return ret ? ret : -EFAULT; | ||
3865 | ptr = (ptr + cnt) % MIDIINBUF; | ||
3866 | spin_lock_irqsave(&s->lock, flags); | ||
3867 | s->midi.ird = ptr; | ||
3868 | s->midi.icnt -= cnt; | ||
3869 | spin_unlock_irqrestore(&s->lock, flags); | ||
3870 | count -= cnt; | ||
3871 | buffer += cnt; | ||
3872 | ret += cnt; | ||
3873 | } | ||
3874 | return ret; | ||
3875 | } | ||
3876 | |||
3877 | |||
3878 | static ssize_t cs4281_midi_write(struct file *file, const char __user *buffer, | ||
3879 | size_t count, loff_t * ppos) | ||
3880 | { | ||
3881 | struct cs4281_state *s = | ||
3882 | (struct cs4281_state *) file->private_data; | ||
3883 | ssize_t ret; | ||
3884 | unsigned long flags; | ||
3885 | unsigned ptr; | ||
3886 | int cnt; | ||
3887 | |||
3888 | VALIDATE_STATE(s); | ||
3889 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
3890 | return -EFAULT; | ||
3891 | ret = 0; | ||
3892 | while (count > 0) { | ||
3893 | spin_lock_irqsave(&s->lock, flags); | ||
3894 | ptr = s->midi.owr; | ||
3895 | cnt = MIDIOUTBUF - ptr; | ||
3896 | if (s->midi.ocnt + cnt > MIDIOUTBUF) | ||
3897 | cnt = MIDIOUTBUF - s->midi.ocnt; | ||
3898 | if (cnt <= 0) | ||
3899 | cs4281_handle_midi(s); | ||
3900 | spin_unlock_irqrestore(&s->lock, flags); | ||
3901 | if (cnt > count) | ||
3902 | cnt = count; | ||
3903 | if (cnt <= 0) { | ||
3904 | if (file->f_flags & O_NONBLOCK) | ||
3905 | return ret ? ret : -EAGAIN; | ||
3906 | interruptible_sleep_on(&s->midi.owait); | ||
3907 | if (signal_pending(current)) | ||
3908 | return ret ? ret : -ERESTARTSYS; | ||
3909 | continue; | ||
3910 | } | ||
3911 | if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) | ||
3912 | return ret ? ret : -EFAULT; | ||
3913 | ptr = (ptr + cnt) % MIDIOUTBUF; | ||
3914 | spin_lock_irqsave(&s->lock, flags); | ||
3915 | s->midi.owr = ptr; | ||
3916 | s->midi.ocnt += cnt; | ||
3917 | spin_unlock_irqrestore(&s->lock, flags); | ||
3918 | count -= cnt; | ||
3919 | buffer += cnt; | ||
3920 | ret += cnt; | ||
3921 | spin_lock_irqsave(&s->lock, flags); | ||
3922 | cs4281_handle_midi(s); | ||
3923 | spin_unlock_irqrestore(&s->lock, flags); | ||
3924 | } | ||
3925 | return ret; | ||
3926 | } | ||
3927 | |||
3928 | |||
3929 | static unsigned int cs4281_midi_poll(struct file *file, | ||
3930 | struct poll_table_struct *wait) | ||
3931 | { | ||
3932 | struct cs4281_state *s = | ||
3933 | (struct cs4281_state *) file->private_data; | ||
3934 | unsigned long flags; | ||
3935 | unsigned int mask = 0; | ||
3936 | |||
3937 | VALIDATE_STATE(s); | ||
3938 | if (file->f_flags & FMODE_WRITE) | ||
3939 | poll_wait(file, &s->midi.owait, wait); | ||
3940 | if (file->f_flags & FMODE_READ) | ||
3941 | poll_wait(file, &s->midi.iwait, wait); | ||
3942 | spin_lock_irqsave(&s->lock, flags); | ||
3943 | if (file->f_flags & FMODE_READ) { | ||
3944 | if (s->midi.icnt > 0) | ||
3945 | mask |= POLLIN | POLLRDNORM; | ||
3946 | } | ||
3947 | if (file->f_flags & FMODE_WRITE) { | ||
3948 | if (s->midi.ocnt < MIDIOUTBUF) | ||
3949 | mask |= POLLOUT | POLLWRNORM; | ||
3950 | } | ||
3951 | spin_unlock_irqrestore(&s->lock, flags); | ||
3952 | return mask; | ||
3953 | } | ||
3954 | |||
3955 | |||
3956 | static int cs4281_midi_open(struct inode *inode, struct file *file) | ||
3957 | { | ||
3958 | unsigned long flags, temp1; | ||
3959 | unsigned int minor = iminor(inode); | ||
3960 | struct cs4281_state *s=NULL; | ||
3961 | struct list_head *entry; | ||
3962 | list_for_each(entry, &cs4281_devs) | ||
3963 | { | ||
3964 | s = list_entry(entry, struct cs4281_state, list); | ||
3965 | |||
3966 | if (s->dev_midi == minor) | ||
3967 | break; | ||
3968 | } | ||
3969 | |||
3970 | if (entry == &cs4281_devs) | ||
3971 | return -ENODEV; | ||
3972 | if (!s) | ||
3973 | { | ||
3974 | CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO | ||
3975 | "cs4281: cs4281_open(): Error - unable to find audio state struct\n")); | ||
3976 | return -ENODEV; | ||
3977 | } | ||
3978 | VALIDATE_STATE(s); | ||
3979 | file->private_data = s; | ||
3980 | // wait for device to become free | ||
3981 | mutex_lock(&s->open_sem); | ||
3982 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { | ||
3983 | if (file->f_flags & O_NONBLOCK) { | ||
3984 | mutex_unlock(&s->open_sem); | ||
3985 | return -EBUSY; | ||
3986 | } | ||
3987 | mutex_unlock(&s->open_sem); | ||
3988 | interruptible_sleep_on(&s->open_wait); | ||
3989 | if (signal_pending(current)) | ||
3990 | return -ERESTARTSYS; | ||
3991 | mutex_lock(&s->open_sem); | ||
3992 | } | ||
3993 | spin_lock_irqsave(&s->lock, flags); | ||
3994 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
3995 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
3996 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
3997 | writel(1, s->pBA0 + BA0_MIDCR); // Reset the interface. | ||
3998 | writel(0, s->pBA0 + BA0_MIDCR); // Return to normal mode. | ||
3999 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
4000 | writel(0x0000000f, s->pBA0 + BA0_MIDCR); // Enable transmit, record, ints. | ||
4001 | temp1 = readl(s->pBA0 + BA0_HIMR); | ||
4002 | writel(temp1 & 0xffbfffff, s->pBA0 + BA0_HIMR); // Enable midi int. recognition. | ||
4003 | writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR); // Enable interrupts | ||
4004 | init_timer(&s->midi.timer); | ||
4005 | s->midi.timer.expires = jiffies + 1; | ||
4006 | s->midi.timer.data = (unsigned long) s; | ||
4007 | s->midi.timer.function = cs4281_midi_timer; | ||
4008 | add_timer(&s->midi.timer); | ||
4009 | } | ||
4010 | if (file->f_mode & FMODE_READ) { | ||
4011 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
4012 | } | ||
4013 | if (file->f_mode & FMODE_WRITE) { | ||
4014 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
4015 | } | ||
4016 | spin_unlock_irqrestore(&s->lock, flags); | ||
4017 | s->open_mode |= | ||
4018 | (file-> | ||
4019 | f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | | ||
4020 | FMODE_MIDI_WRITE); | ||
4021 | mutex_unlock(&s->open_sem); | ||
4022 | return nonseekable_open(inode, file); | ||
4023 | } | ||
4024 | |||
4025 | |||
4026 | static int cs4281_midi_release(struct inode *inode, struct file *file) | ||
4027 | { | ||
4028 | struct cs4281_state *s = | ||
4029 | (struct cs4281_state *) file->private_data; | ||
4030 | DECLARE_WAITQUEUE(wait, current); | ||
4031 | unsigned long flags; | ||
4032 | unsigned count, tmo; | ||
4033 | |||
4034 | VALIDATE_STATE(s); | ||
4035 | |||
4036 | if (file->f_mode & FMODE_WRITE) { | ||
4037 | add_wait_queue(&s->midi.owait, &wait); | ||
4038 | for (;;) { | ||
4039 | set_current_state(TASK_INTERRUPTIBLE); | ||
4040 | spin_lock_irqsave(&s->lock, flags); | ||
4041 | count = s->midi.ocnt; | ||
4042 | spin_unlock_irqrestore(&s->lock, flags); | ||
4043 | if (count <= 0) | ||
4044 | break; | ||
4045 | if (signal_pending(current)) | ||
4046 | break; | ||
4047 | if (file->f_flags & O_NONBLOCK) { | ||
4048 | remove_wait_queue(&s->midi.owait, &wait); | ||
4049 | current->state = TASK_RUNNING; | ||
4050 | return -EBUSY; | ||
4051 | } | ||
4052 | tmo = (count * HZ) / 3100; | ||
4053 | if (!schedule_timeout(tmo ? : 1) && tmo) | ||
4054 | printk(KERN_DEBUG | ||
4055 | "cs4281: midi timed out??\n"); | ||
4056 | } | ||
4057 | remove_wait_queue(&s->midi.owait, &wait); | ||
4058 | current->state = TASK_RUNNING; | ||
4059 | } | ||
4060 | mutex_lock(&s->open_sem); | ||
4061 | s->open_mode &= | ||
4062 | (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ | | ||
4063 | FMODE_MIDI_WRITE); | ||
4064 | spin_lock_irqsave(&s->lock, flags); | ||
4065 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
4066 | writel(0, s->pBA0 + BA0_MIDCR); // Disable Midi interrupts. | ||
4067 | del_timer(&s->midi.timer); | ||
4068 | } | ||
4069 | spin_unlock_irqrestore(&s->lock, flags); | ||
4070 | mutex_unlock(&s->open_sem); | ||
4071 | wake_up(&s->open_wait); | ||
4072 | return 0; | ||
4073 | } | ||
4074 | |||
4075 | // ****************************************************************************************** | ||
4076 | // Midi file operations struct. | ||
4077 | // ****************************************************************************************** | ||
4078 | static /*const */ struct file_operations cs4281_midi_fops = { | ||
4079 | .owner = THIS_MODULE, | ||
4080 | .llseek = no_llseek, | ||
4081 | .read = cs4281_midi_read, | ||
4082 | .write = cs4281_midi_write, | ||
4083 | .poll = cs4281_midi_poll, | ||
4084 | .open = cs4281_midi_open, | ||
4085 | .release = cs4281_midi_release, | ||
4086 | }; | ||
4087 | |||
4088 | |||
4089 | // --------------------------------------------------------------------- | ||
4090 | |||
4091 | // maximum number of devices | ||
4092 | #define NR_DEVICE 8 // Only eight devices supported currently. | ||
4093 | |||
4094 | // --------------------------------------------------------------------- | ||
4095 | |||
4096 | static struct initvol { | ||
4097 | int mixch; | ||
4098 | int vol; | ||
4099 | } initvol[] __devinitdata = { | ||
4100 | |||
4101 | { | ||
4102 | SOUND_MIXER_WRITE_VOLUME, 0x4040}, { | ||
4103 | SOUND_MIXER_WRITE_PCM, 0x4040}, { | ||
4104 | SOUND_MIXER_WRITE_SYNTH, 0x4040}, { | ||
4105 | SOUND_MIXER_WRITE_CD, 0x4040}, { | ||
4106 | SOUND_MIXER_WRITE_LINE, 0x4040}, { | ||
4107 | SOUND_MIXER_WRITE_LINE1, 0x4040}, { | ||
4108 | SOUND_MIXER_WRITE_RECLEV, 0x0000}, { | ||
4109 | SOUND_MIXER_WRITE_SPEAKER, 0x4040}, { | ||
4110 | SOUND_MIXER_WRITE_MIC, 0x0000} | ||
4111 | }; | ||
4112 | |||
4113 | |||
4114 | #ifndef NOT_CS4281_PM | ||
4115 | static void __devinit cs4281_BuildFIFO( | ||
4116 | struct cs4281_pipeline *p, | ||
4117 | struct cs4281_state *s) | ||
4118 | { | ||
4119 | switch(p->number) | ||
4120 | { | ||
4121 | case 0: /* playback */ | ||
4122 | { | ||
4123 | p->u32FCRnAddress = BA0_FCR0; | ||
4124 | p->u32FSICnAddress = BA0_FSIC0; | ||
4125 | p->u32FPDRnAddress = BA0_FPDR0; | ||
4126 | break; | ||
4127 | } | ||
4128 | case 1: /* capture */ | ||
4129 | { | ||
4130 | p->u32FCRnAddress = BA0_FCR1; | ||
4131 | p->u32FSICnAddress = BA0_FSIC1; | ||
4132 | p->u32FPDRnAddress = BA0_FPDR1; | ||
4133 | break; | ||
4134 | } | ||
4135 | |||
4136 | case 2: | ||
4137 | { | ||
4138 | p->u32FCRnAddress = BA0_FCR2; | ||
4139 | p->u32FSICnAddress = BA0_FSIC2; | ||
4140 | p->u32FPDRnAddress = BA0_FPDR2; | ||
4141 | break; | ||
4142 | } | ||
4143 | case 3: | ||
4144 | { | ||
4145 | p->u32FCRnAddress = BA0_FCR3; | ||
4146 | p->u32FSICnAddress = BA0_FSIC3; | ||
4147 | p->u32FPDRnAddress = BA0_FPDR3; | ||
4148 | break; | ||
4149 | } | ||
4150 | default: | ||
4151 | break; | ||
4152 | } | ||
4153 | // | ||
4154 | // first read the hardware to initialize the member variables | ||
4155 | // | ||
4156 | p->u32FCRnValue = readl(s->pBA0 + p->u32FCRnAddress); | ||
4157 | p->u32FSICnValue = readl(s->pBA0 + p->u32FSICnAddress); | ||
4158 | p->u32FPDRnValue = readl(s->pBA0 + p->u32FPDRnAddress); | ||
4159 | |||
4160 | } | ||
4161 | |||
4162 | static void __devinit cs4281_BuildDMAengine( | ||
4163 | struct cs4281_pipeline *p, | ||
4164 | struct cs4281_state *s) | ||
4165 | { | ||
4166 | /* | ||
4167 | * initialize all the addresses of this pipeline dma info. | ||
4168 | */ | ||
4169 | switch(p->number) | ||
4170 | { | ||
4171 | case 0: /* playback */ | ||
4172 | { | ||
4173 | p->u32DBAnAddress = BA0_DBA0; | ||
4174 | p->u32DCAnAddress = BA0_DCA0; | ||
4175 | p->u32DBCnAddress = BA0_DBC0; | ||
4176 | p->u32DCCnAddress = BA0_DCC0; | ||
4177 | p->u32DMRnAddress = BA0_DMR0; | ||
4178 | p->u32DCRnAddress = BA0_DCR0; | ||
4179 | p->u32HDSRnAddress = BA0_HDSR0; | ||
4180 | break; | ||
4181 | } | ||
4182 | |||
4183 | case 1: /* capture */ | ||
4184 | { | ||
4185 | p->u32DBAnAddress = BA0_DBA1; | ||
4186 | p->u32DCAnAddress = BA0_DCA1; | ||
4187 | p->u32DBCnAddress = BA0_DBC1; | ||
4188 | p->u32DCCnAddress = BA0_DCC1; | ||
4189 | p->u32DMRnAddress = BA0_DMR1; | ||
4190 | p->u32DCRnAddress = BA0_DCR1; | ||
4191 | p->u32HDSRnAddress = BA0_HDSR1; | ||
4192 | break; | ||
4193 | } | ||
4194 | |||
4195 | case 2: | ||
4196 | { | ||
4197 | p->u32DBAnAddress = BA0_DBA2; | ||
4198 | p->u32DCAnAddress = BA0_DCA2; | ||
4199 | p->u32DBCnAddress = BA0_DBC2; | ||
4200 | p->u32DCCnAddress = BA0_DCC2; | ||
4201 | p->u32DMRnAddress = BA0_DMR2; | ||
4202 | p->u32DCRnAddress = BA0_DCR2; | ||
4203 | p->u32HDSRnAddress = BA0_HDSR2; | ||
4204 | break; | ||
4205 | } | ||
4206 | |||
4207 | case 3: | ||
4208 | { | ||
4209 | p->u32DBAnAddress = BA0_DBA3; | ||
4210 | p->u32DCAnAddress = BA0_DCA3; | ||
4211 | p->u32DBCnAddress = BA0_DBC3; | ||
4212 | p->u32DCCnAddress = BA0_DCC3; | ||
4213 | p->u32DMRnAddress = BA0_DMR3; | ||
4214 | p->u32DCRnAddress = BA0_DCR3; | ||
4215 | p->u32HDSRnAddress = BA0_HDSR3; | ||
4216 | break; | ||
4217 | } | ||
4218 | default: | ||
4219 | break; | ||
4220 | } | ||
4221 | |||
4222 | // | ||
4223 | // Initialize the dma values for this pipeline | ||
4224 | // | ||
4225 | p->u32DBAnValue = readl(s->pBA0 + p->u32DBAnAddress); | ||
4226 | p->u32DBCnValue = readl(s->pBA0 + p->u32DBCnAddress); | ||
4227 | p->u32DMRnValue = readl(s->pBA0 + p->u32DMRnAddress); | ||
4228 | p->u32DCRnValue = readl(s->pBA0 + p->u32DCRnAddress); | ||
4229 | |||
4230 | } | ||
4231 | |||
4232 | static void __devinit cs4281_InitPM(struct cs4281_state *s) | ||
4233 | { | ||
4234 | int i; | ||
4235 | struct cs4281_pipeline *p; | ||
4236 | |||
4237 | for(i=0;i<CS4281_NUMBER_OF_PIPELINES;i++) | ||
4238 | { | ||
4239 | p = &s->pl[i]; | ||
4240 | p->number = i; | ||
4241 | cs4281_BuildDMAengine(p,s); | ||
4242 | cs4281_BuildFIFO(p,s); | ||
4243 | /* | ||
4244 | * currently only 2 pipelines are used | ||
4245 | * so, only set the valid bit on the playback and capture. | ||
4246 | */ | ||
4247 | if( (i == CS4281_PLAYBACK_PIPELINE_NUMBER) || | ||
4248 | (i == CS4281_CAPTURE_PIPELINE_NUMBER)) | ||
4249 | p->flags |= CS4281_PIPELINE_VALID; | ||
4250 | } | ||
4251 | s->pm.u32SSPM_BITS = 0x7e; /* rev c, use 0x7c for rev a or b */ | ||
4252 | } | ||
4253 | #endif | ||
4254 | |||
4255 | static int __devinit cs4281_probe(struct pci_dev *pcidev, | ||
4256 | const struct pci_device_id *pciid) | ||
4257 | { | ||
4258 | struct cs4281_state *s; | ||
4259 | dma_addr_t dma_mask; | ||
4260 | mm_segment_t fs; | ||
4261 | int i, val; | ||
4262 | unsigned int temp1, temp2; | ||
4263 | |||
4264 | CS_DBGOUT(CS_FUNCTION | CS_INIT, 2, | ||
4265 | printk(KERN_INFO "cs4281: probe()+\n")); | ||
4266 | |||
4267 | if (pci_enable_device(pcidev)) { | ||
4268 | CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR | ||
4269 | "cs4281: pci_enable_device() failed\n")); | ||
4270 | return -1; | ||
4271 | } | ||
4272 | if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM) || | ||
4273 | !(pci_resource_flags(pcidev, 1) & IORESOURCE_MEM)) { | ||
4274 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR | ||
4275 | "cs4281: probe()- Memory region not assigned\n")); | ||
4276 | return -ENODEV; | ||
4277 | } | ||
4278 | if (pcidev->irq == 0) { | ||
4279 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR | ||
4280 | "cs4281: probe() IRQ not assigned\n")); | ||
4281 | return -ENODEV; | ||
4282 | } | ||
4283 | dma_mask = 0xffffffff; /* this enables playback and recording */ | ||
4284 | i = pci_set_dma_mask(pcidev, dma_mask); | ||
4285 | if (i) { | ||
4286 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR | ||
4287 | "cs4281: probe() architecture does not support 32bit PCI busmaster DMA\n")); | ||
4288 | return i; | ||
4289 | } | ||
4290 | if (!(s = kmalloc(sizeof(struct cs4281_state), GFP_KERNEL))) { | ||
4291 | CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR | ||
4292 | "cs4281: probe() no memory for state struct.\n")); | ||
4293 | return -1; | ||
4294 | } | ||
4295 | memset(s, 0, sizeof(struct cs4281_state)); | ||
4296 | init_waitqueue_head(&s->dma_adc.wait); | ||
4297 | init_waitqueue_head(&s->dma_dac.wait); | ||
4298 | init_waitqueue_head(&s->open_wait); | ||
4299 | init_waitqueue_head(&s->open_wait_adc); | ||
4300 | init_waitqueue_head(&s->open_wait_dac); | ||
4301 | init_waitqueue_head(&s->midi.iwait); | ||
4302 | init_waitqueue_head(&s->midi.owait); | ||
4303 | mutex_init(&s->open_sem); | ||
4304 | mutex_init(&s->open_sem_adc); | ||
4305 | mutex_init(&s->open_sem_dac); | ||
4306 | spin_lock_init(&s->lock); | ||
4307 | s->pBA0phys = pci_resource_start(pcidev, 0); | ||
4308 | s->pBA1phys = pci_resource_start(pcidev, 1); | ||
4309 | |||
4310 | /* Convert phys to linear. */ | ||
4311 | s->pBA0 = ioremap_nocache(s->pBA0phys, 4096); | ||
4312 | if (!s->pBA0) { | ||
4313 | CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR | ||
4314 | "cs4281: BA0 I/O mapping failed. Skipping part.\n")); | ||
4315 | goto err_free; | ||
4316 | } | ||
4317 | s->pBA1 = ioremap_nocache(s->pBA1phys, 65536); | ||
4318 | if (!s->pBA1) { | ||
4319 | CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR | ||
4320 | "cs4281: BA1 I/O mapping failed. Skipping part.\n")); | ||
4321 | goto err_unmap; | ||
4322 | } | ||
4323 | |||
4324 | temp1 = readl(s->pBA0 + BA0_PCICFG00); | ||
4325 | temp2 = readl(s->pBA0 + BA0_PCICFG04); | ||
4326 | |||
4327 | CS_DBGOUT(CS_INIT, 2, | ||
4328 | printk(KERN_INFO | ||
4329 | "cs4281: probe() BA0=0x%.8x BA1=0x%.8x pBA0=%p pBA1=%p \n", | ||
4330 | (unsigned) temp1, (unsigned) temp2, s->pBA0, s->pBA1)); | ||
4331 | CS_DBGOUT(CS_INIT, 2, | ||
4332 | printk(KERN_INFO | ||
4333 | "cs4281: probe() pBA0phys=0x%.8x pBA1phys=0x%.8x\n", | ||
4334 | (unsigned) s->pBA0phys, (unsigned) s->pBA1phys)); | ||
4335 | |||
4336 | #ifndef NOT_CS4281_PM | ||
4337 | s->pm.flags = CS4281_PM_IDLE; | ||
4338 | #endif | ||
4339 | temp1 = cs4281_hw_init(s); | ||
4340 | if (temp1) { | ||
4341 | CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR | ||
4342 | "cs4281: cs4281_hw_init() failed. Skipping part.\n")); | ||
4343 | goto err_irq; | ||
4344 | } | ||
4345 | s->magic = CS4281_MAGIC; | ||
4346 | s->pcidev = pcidev; | ||
4347 | s->irq = pcidev->irq; | ||
4348 | if (request_irq | ||
4349 | (s->irq, cs4281_interrupt, IRQF_SHARED, "Crystal CS4281", s)) { | ||
4350 | CS_DBGOUT(CS_INIT | CS_ERROR, 1, | ||
4351 | printk(KERN_ERR "cs4281: irq %u in use\n", s->irq)); | ||
4352 | goto err_irq; | ||
4353 | } | ||
4354 | if ((s->dev_audio = register_sound_dsp(&cs4281_audio_fops, -1)) < | ||
4355 | 0) { | ||
4356 | CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR | ||
4357 | "cs4281: probe() register_sound_dsp() failed.\n")); | ||
4358 | goto err_dev1; | ||
4359 | } | ||
4360 | if ((s->dev_mixer = register_sound_mixer(&cs4281_mixer_fops, -1)) < | ||
4361 | 0) { | ||
4362 | CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR | ||
4363 | "cs4281: probe() register_sound_mixer() failed.\n")); | ||
4364 | goto err_dev2; | ||
4365 | } | ||
4366 | if ((s->dev_midi = register_sound_midi(&cs4281_midi_fops, -1)) < 0) { | ||
4367 | CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_ERR | ||
4368 | "cs4281: probe() register_sound_midi() failed.\n")); | ||
4369 | goto err_dev3; | ||
4370 | } | ||
4371 | #ifndef NOT_CS4281_PM | ||
4372 | cs4281_InitPM(s); | ||
4373 | s->pm.flags |= CS4281_PM_NOT_REGISTERED; | ||
4374 | #endif | ||
4375 | |||
4376 | pci_set_master(pcidev); // enable bus mastering | ||
4377 | |||
4378 | fs = get_fs(); | ||
4379 | set_fs(KERNEL_DS); | ||
4380 | val = SOUND_MASK_LINE; | ||
4381 | mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long) &val); | ||
4382 | for (i = 0; i < sizeof(initvol) / sizeof(initvol[0]); i++) { | ||
4383 | val = initvol[i].vol; | ||
4384 | mixer_ioctl(s, initvol[i].mixch, (unsigned long) &val); | ||
4385 | } | ||
4386 | val = 1; // enable mic preamp | ||
4387 | mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long) &val); | ||
4388 | set_fs(fs); | ||
4389 | |||
4390 | pci_set_drvdata(pcidev, s); | ||
4391 | list_add(&s->list, &cs4281_devs); | ||
4392 | CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO | ||
4393 | "cs4281: probe()- device allocated successfully\n")); | ||
4394 | return 0; | ||
4395 | |||
4396 | err_dev3: | ||
4397 | unregister_sound_mixer(s->dev_mixer); | ||
4398 | err_dev2: | ||
4399 | unregister_sound_dsp(s->dev_audio); | ||
4400 | err_dev1: | ||
4401 | free_irq(s->irq, s); | ||
4402 | err_irq: | ||
4403 | iounmap(s->pBA1); | ||
4404 | err_unmap: | ||
4405 | iounmap(s->pBA0); | ||
4406 | err_free: | ||
4407 | kfree(s); | ||
4408 | |||
4409 | CS_DBGOUT(CS_INIT | CS_ERROR, 1, printk(KERN_INFO | ||
4410 | "cs4281: probe()- no device allocated\n")); | ||
4411 | return -ENODEV; | ||
4412 | } // probe_cs4281 | ||
4413 | |||
4414 | |||
4415 | // --------------------------------------------------------------------- | ||
4416 | |||
4417 | static void __devexit cs4281_remove(struct pci_dev *pci_dev) | ||
4418 | { | ||
4419 | struct cs4281_state *s = pci_get_drvdata(pci_dev); | ||
4420 | // stop DMA controller | ||
4421 | synchronize_irq(s->irq); | ||
4422 | free_irq(s->irq, s); | ||
4423 | unregister_sound_dsp(s->dev_audio); | ||
4424 | unregister_sound_mixer(s->dev_mixer); | ||
4425 | unregister_sound_midi(s->dev_midi); | ||
4426 | iounmap(s->pBA1); | ||
4427 | iounmap(s->pBA0); | ||
4428 | pci_set_drvdata(pci_dev,NULL); | ||
4429 | list_del(&s->list); | ||
4430 | kfree(s); | ||
4431 | CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO | ||
4432 | "cs4281: cs4281_remove()-: remove successful\n")); | ||
4433 | } | ||
4434 | |||
4435 | static struct pci_device_id cs4281_pci_tbl[] = { | ||
4436 | { | ||
4437 | .vendor = PCI_VENDOR_ID_CIRRUS, | ||
4438 | .device = PCI_DEVICE_ID_CRYSTAL_CS4281, | ||
4439 | .subvendor = PCI_ANY_ID, | ||
4440 | .subdevice = PCI_ANY_ID, | ||
4441 | }, | ||
4442 | { 0, }, | ||
4443 | }; | ||
4444 | |||
4445 | MODULE_DEVICE_TABLE(pci, cs4281_pci_tbl); | ||
4446 | |||
4447 | static struct pci_driver cs4281_pci_driver = { | ||
4448 | .name = "cs4281", | ||
4449 | .id_table = cs4281_pci_tbl, | ||
4450 | .probe = cs4281_probe, | ||
4451 | .remove = __devexit_p(cs4281_remove), | ||
4452 | .suspend = CS4281_SUSPEND_TBL, | ||
4453 | .resume = CS4281_RESUME_TBL, | ||
4454 | }; | ||
4455 | |||
4456 | static int __init cs4281_init_module(void) | ||
4457 | { | ||
4458 | int rtn = 0; | ||
4459 | CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO | ||
4460 | "cs4281: cs4281_init_module()+ \n")); | ||
4461 | printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " " | ||
4462 | __DATE__ "\n", CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION, | ||
4463 | CS4281_ARCH); | ||
4464 | rtn = pci_register_driver(&cs4281_pci_driver); | ||
4465 | |||
4466 | CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, | ||
4467 | printk(KERN_INFO "cs4281: cs4281_init_module()- (%d)\n",rtn)); | ||
4468 | return rtn; | ||
4469 | } | ||
4470 | |||
4471 | static void __exit cs4281_cleanup_module(void) | ||
4472 | { | ||
4473 | pci_unregister_driver(&cs4281_pci_driver); | ||
4474 | CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, | ||
4475 | printk(KERN_INFO "cs4281: cleanup_cs4281() finished\n")); | ||
4476 | } | ||
4477 | // --------------------------------------------------------------------- | ||
4478 | |||
4479 | MODULE_AUTHOR("gw boynton, audio@crystal.cirrus.com"); | ||
4480 | MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver"); | ||
4481 | MODULE_LICENSE("GPL"); | ||
4482 | |||
4483 | // --------------------------------------------------------------------- | ||
4484 | |||
4485 | module_init(cs4281_init_module); | ||
4486 | module_exit(cs4281_cleanup_module); | ||
4487 | |||
diff --git a/sound/oss/cs4281/cs4281pm-24.c b/sound/oss/cs4281/cs4281pm-24.c deleted file mode 100644 index 90cbd7679534..000000000000 --- a/sound/oss/cs4281/cs4281pm-24.c +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * "cs4281pm.c" -- Cirrus Logic-Crystal CS4281 linux audio driver. | ||
4 | * | ||
5 | * Copyright (C) 2000,2001 Cirrus Logic Corp. | ||
6 | * -- tom woller (twoller@crystal.cirrus.com) or | ||
7 | * (audio@crystal.cirrus.com). | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | * 12/22/00 trw - new file. | ||
24 | * | ||
25 | *******************************************************************************/ | ||
26 | |||
27 | #ifndef NOT_CS4281_PM | ||
28 | #include <linux/pm.h> | ||
29 | |||
30 | static int cs4281_suspend(struct cs4281_state *s); | ||
31 | static int cs4281_resume(struct cs4281_state *s); | ||
32 | /* | ||
33 | * for now (12/22/00) only enable the pm_register PM support. | ||
34 | * allow these table entries to be null. | ||
35 | #define CS4281_SUSPEND_TBL cs4281_suspend_tbl | ||
36 | #define CS4281_RESUME_TBL cs4281_resume_tbl | ||
37 | */ | ||
38 | #define CS4281_SUSPEND_TBL cs4281_suspend_null | ||
39 | #define CS4281_RESUME_TBL cs4281_resume_null | ||
40 | |||
41 | #else /* CS4281_PM */ | ||
42 | #define CS4281_SUSPEND_TBL cs4281_suspend_null | ||
43 | #define CS4281_RESUME_TBL cs4281_resume_null | ||
44 | #endif /* CS4281_PM */ | ||
45 | |||
diff --git a/sound/oss/cs4281/cs4281pm.h b/sound/oss/cs4281/cs4281pm.h deleted file mode 100644 index b44fdc9ce002..000000000000 --- a/sound/oss/cs4281/cs4281pm.h +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | #ifndef NOT_CS4281_PM | ||
2 | /******************************************************************************* | ||
3 | * | ||
4 | * "cs4281pm.h" -- Cirrus Logic-Crystal CS4281 linux audio driver. | ||
5 | * | ||
6 | * Copyright (C) 2000,2001 Cirrus Logic Corp. | ||
7 | * -- tom woller (twoller@crystal.cirrus.com) or | ||
8 | * (audio@crystal.cirrus.com). | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * 12/22/00 trw - new file. | ||
25 | * | ||
26 | *******************************************************************************/ | ||
27 | /* general pm definitions */ | ||
28 | #define CS4281_AC97_HIGHESTREGTORESTORE 0x26 | ||
29 | #define CS4281_AC97_NUMBER_RESTORE_REGS (CS4281_AC97_HIGHESTREGTORESTORE/2-1) | ||
30 | |||
31 | /* pipeline definitions */ | ||
32 | #define CS4281_NUMBER_OF_PIPELINES 4 | ||
33 | #define CS4281_PIPELINE_VALID 0x0001 | ||
34 | #define CS4281_PLAYBACK_PIPELINE_NUMBER 0x0000 | ||
35 | #define CS4281_CAPTURE_PIPELINE_NUMBER 0x0001 | ||
36 | |||
37 | /* PM state defintions */ | ||
38 | #define CS4281_PM_NOT_REGISTERED 0x1000 | ||
39 | #define CS4281_PM_IDLE 0x0001 | ||
40 | #define CS4281_PM_SUSPENDING 0x0002 | ||
41 | #define CS4281_PM_SUSPENDED 0x0004 | ||
42 | #define CS4281_PM_RESUMING 0x0008 | ||
43 | #define CS4281_PM_RESUMED 0x0010 | ||
44 | |||
45 | struct cs4281_pm { | ||
46 | unsigned long flags; | ||
47 | u32 u32CLKCR1_SAVE,u32SSPMValue,u32PPLVCvalue,u32PPRVCvalue; | ||
48 | u32 u32FMLVCvalue,u32FMRVCvalue,u32GPIORvalue,u32JSCTLvalue,u32SSCR; | ||
49 | u32 u32SRCSA,u32DacASR,u32AdcASR,u32DacSR,u32AdcSR,u32MIDCR_Save; | ||
50 | u32 u32SSPM_BITS; | ||
51 | u32 ac97[CS4281_AC97_NUMBER_RESTORE_REGS]; | ||
52 | u32 u32AC97_master_volume, u32AC97_headphone_volume, u32AC97_master_volume_mono; | ||
53 | u32 u32AC97_pcm_out_volume, u32AC97_powerdown, u32AC97_general_purpose; | ||
54 | u32 u32hwptr_playback,u32hwptr_capture; | ||
55 | }; | ||
56 | |||
57 | struct cs4281_pipeline { | ||
58 | unsigned flags; | ||
59 | unsigned number; | ||
60 | u32 u32DBAnValue,u32DBCnValue,u32DMRnValue,u32DCRnValue; | ||
61 | u32 u32DBAnAddress,u32DCAnAddress,u32DBCnAddress,u32DCCnAddress; | ||
62 | u32 u32DMRnAddress,u32DCRnAddress,u32HDSRnAddress; | ||
63 | u32 u32DBAn_Save,u32DBCn_Save,u32DMRn_Save,u32DCRn_Save; | ||
64 | u32 u32DCCn_Save,u32DCAn_Save; | ||
65 | /* | ||
66 | * technically, these are fifo variables, but just map the | ||
67 | * first fifo with the first pipeline and then use the fifo | ||
68 | * variables inside of the pipeline struct. | ||
69 | */ | ||
70 | u32 u32FCRn_Save,u32FSICn_Save; | ||
71 | u32 u32FCRnValue,u32FCRnAddress,u32FSICnValue,u32FSICnAddress; | ||
72 | u32 u32FPDRnValue,u32FPDRnAddress; | ||
73 | }; | ||
74 | #endif | ||
diff --git a/sound/oss/dm.h b/sound/oss/dm.h deleted file mode 100644 index 14a90593c44f..000000000000 --- a/sound/oss/dm.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | #ifndef _DRIVERS_SOUND_DM_H | ||
2 | #define _DRIVERS_SOUND_DM_H | ||
3 | |||
4 | /* | ||
5 | * Definitions of the 'direct midi sound' interface used | ||
6 | * by the newer commercial OSS package. We should export | ||
7 | * this to userland somewhere in glibc later. | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * Data structure composing an FM "note" or sound event. | ||
12 | */ | ||
13 | |||
14 | struct dm_fm_voice | ||
15 | { | ||
16 | u8 op; | ||
17 | u8 voice; | ||
18 | u8 am; | ||
19 | u8 vibrato; | ||
20 | u8 do_sustain; | ||
21 | u8 kbd_scale; | ||
22 | u8 harmonic; | ||
23 | u8 scale_level; | ||
24 | u8 volume; | ||
25 | u8 attack; | ||
26 | u8 decay; | ||
27 | u8 sustain; | ||
28 | u8 release; | ||
29 | u8 feedback; | ||
30 | u8 connection; | ||
31 | u8 left; | ||
32 | u8 right; | ||
33 | u8 waveform; | ||
34 | }; | ||
35 | |||
36 | /* | ||
37 | * This describes an FM note by its voice, octave, frequency number (10bit) | ||
38 | * and key on/off. | ||
39 | */ | ||
40 | |||
41 | struct dm_fm_note | ||
42 | { | ||
43 | u8 voice; | ||
44 | u8 octave; | ||
45 | u32 fnum; | ||
46 | u8 key_on; | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * FM parameters that apply globally to all voices, and thus are not "notes" | ||
51 | */ | ||
52 | |||
53 | struct dm_fm_params | ||
54 | { | ||
55 | u8 am_depth; | ||
56 | u8 vib_depth; | ||
57 | u8 kbd_split; | ||
58 | u8 rhythm; | ||
59 | |||
60 | /* This block is the percussion instrument data */ | ||
61 | u8 bass; | ||
62 | u8 snare; | ||
63 | u8 tomtom; | ||
64 | u8 cymbal; | ||
65 | u8 hihat; | ||
66 | }; | ||
67 | |||
68 | /* | ||
69 | * FM mode ioctl settings | ||
70 | */ | ||
71 | |||
72 | #define FM_IOCTL_RESET 0x20 | ||
73 | #define FM_IOCTL_PLAY_NOTE 0x21 | ||
74 | #define FM_IOCTL_SET_VOICE 0x22 | ||
75 | #define FM_IOCTL_SET_PARAMS 0x23 | ||
76 | #define FM_IOCTL_SET_MODE 0x24 | ||
77 | #define FM_IOCTL_SET_OPL 0x25 | ||
78 | |||
79 | #endif | ||
diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c index 6c1cf74b78c5..6ff67f73cbb9 100644 --- a/sound/oss/dmabuf.c +++ b/sound/oss/dmabuf.c | |||
@@ -1155,36 +1155,6 @@ void DMAbuf_inputintr(int dev) | |||
1155 | spin_unlock_irqrestore(&dmap->lock,flags); | 1155 | spin_unlock_irqrestore(&dmap->lock,flags); |
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | int DMAbuf_open_dma(int dev) | ||
1159 | { | ||
1160 | /* | ||
1161 | * NOTE! This routine opens only the primary DMA channel (output). | ||
1162 | */ | ||
1163 | struct audio_operations *adev = audio_devs[dev]; | ||
1164 | int err; | ||
1165 | |||
1166 | if ((err = open_dmap(adev, OPEN_READWRITE, adev->dmap_out)) < 0) | ||
1167 | return -EBUSY; | ||
1168 | dma_init_buffers(adev->dmap_out); | ||
1169 | adev->dmap_out->flags |= DMA_ALLOC_DONE; | ||
1170 | adev->dmap_out->fragment_size = adev->dmap_out->buffsize; | ||
1171 | |||
1172 | if (adev->dmap_out->dma >= 0) { | ||
1173 | unsigned long flags; | ||
1174 | |||
1175 | flags=claim_dma_lock(); | ||
1176 | clear_dma_ff(adev->dmap_out->dma); | ||
1177 | disable_dma(adev->dmap_out->dma); | ||
1178 | release_dma_lock(flags); | ||
1179 | } | ||
1180 | return 0; | ||
1181 | } | ||
1182 | |||
1183 | void DMAbuf_close_dma(int dev) | ||
1184 | { | ||
1185 | close_dmap(audio_devs[dev], audio_devs[dev]->dmap_out); | ||
1186 | } | ||
1187 | |||
1188 | void DMAbuf_init(int dev, int dma1, int dma2) | 1158 | void DMAbuf_init(int dev, int dma1, int dma2) |
1189 | { | 1159 | { |
1190 | struct audio_operations *adev = audio_devs[dev]; | 1160 | struct audio_operations *adev = audio_devs[dev]; |
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c deleted file mode 100644 index 13f483149737..000000000000 --- a/sound/oss/es1370.c +++ /dev/null | |||
@@ -1,2819 +0,0 @@ | |||
1 | /*****************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * es1370.c -- Ensoniq ES1370/Asahi Kasei AK4531 audio driver. | ||
5 | * | ||
6 | * Copyright (C) 1998-2001, 2003 Thomas Sailer (t.sailer@alumni.ethz.ch) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * Special thanks to David C. Niemi | ||
23 | * | ||
24 | * | ||
25 | * Module command line parameters: | ||
26 | * lineout if 1 the LINE jack is used as an output instead of an input. | ||
27 | * LINE then contains the unmixed dsp output. This can be used | ||
28 | * to make the card a four channel one: use dsp to output two | ||
29 | * channels to LINE and dac to output the other two channels to | ||
30 | * SPKR. Set the mixer to only output synth to SPKR. | ||
31 | * micbias sets the +5V bias to the mic if using an electretmic. | ||
32 | * | ||
33 | * | ||
34 | * Note: sync mode is not yet supported (i.e. running dsp and dac from the same | ||
35 | * clock source) | ||
36 | * | ||
37 | * Supported devices: | ||
38 | * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible | ||
39 | * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible | ||
40 | * /dev/dsp1 additional DAC, like /dev/dsp, but output only, | ||
41 | * only 5512, 11025, 22050 and 44100 samples/s, | ||
42 | * outputs to mixer "SYNTH" setting | ||
43 | * /dev/midi simple MIDI UART interface, no ioctl | ||
44 | * | ||
45 | * NOTE: the card does not have any FM/Wavetable synthesizer, it is supposed | ||
46 | * to be done in software. That is what /dev/dac is for. By now (Q2 1998) | ||
47 | * there are several MIDI to PCM (WAV) packages, one of them is timidity. | ||
48 | * | ||
49 | * Revision history | ||
50 | * 26.03.1998 0.1 Initial release | ||
51 | * 31.03.1998 0.2 Fix bug in GETOSPACE | ||
52 | * 04.04.1998 0.3 Make it work (again) under 2.0.33 | ||
53 | * Fix mixer write operation not returning the actual | ||
54 | * settings | ||
55 | * 05.04.1998 0.4 First attempt at using the new PCI stuff | ||
56 | * 29.04.1998 0.5 Fix hang when ^C is pressed on amp | ||
57 | * 07.05.1998 0.6 Don't double lock around stop_*() in *_release() | ||
58 | * 10.05.1998 0.7 First stab at a simple midi interface (no bells&whistles) | ||
59 | * 14.05.1998 0.8 Don't allow excessive interrupt rates | ||
60 | * 08.06.1998 0.9 First release using Alan Cox' soundcore instead of | ||
61 | * miscdevice | ||
62 | * 05.07.1998 0.10 Fixed the driver to correctly maintin OSS style volume | ||
63 | * settings (not sure if this should be standard) | ||
64 | * Fixed many references: f_flags should be f_mode | ||
65 | * -- Gerald Britton <gbritton@mit.edu> | ||
66 | * 03.08.1998 0.11 Now mixer behaviour can basically be selected between | ||
67 | * "OSS documented" and "OSS actual" behaviour | ||
68 | * Fixed mixer table thanks to Hakan.Lennestal@lu.erisoft.se | ||
69 | * On module startup, set DAC2 to 11kSPS instead of 5.5kSPS, | ||
70 | * as it produces an annoying ssssh in the lower sampling rate | ||
71 | * Do not include modversions.h | ||
72 | * 22.08.1998 0.12 Mixer registers actually have 5 instead of 4 bits | ||
73 | * pointed out by Itai Nahshon | ||
74 | * 31.08.1998 0.13 Fix realplayer problems - dac.count issues | ||
75 | * 08.10.1998 0.14 Joystick support fixed | ||
76 | * -- Oliver Neukum <c188@org.chemie.uni-muenchen.de> | ||
77 | * 10.12.1998 0.15 Fix drain_dac trying to wait on not yet initialized DMA | ||
78 | * 16.12.1998 0.16 Don't wake up app until there are fragsize bytes to read/write | ||
79 | * 06.01.1999 0.17 remove the silly SA_INTERRUPT flag. | ||
80 | * hopefully killed the egcs section type conflict | ||
81 | * 12.03.1999 0.18 cinfo.blocks should be reset after GETxPTR ioctl. | ||
82 | * reported by Johan Maes <joma@telindus.be> | ||
83 | * 22.03.1999 0.19 return EAGAIN instead of EBUSY when O_NONBLOCK | ||
84 | * read/write cannot be executed | ||
85 | * 07.04.1999 0.20 implemented the following ioctl's: SOUND_PCM_READ_RATE, | ||
86 | * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; | ||
87 | * Alpha fixes reported by Peter Jones <pjones@redhat.com> | ||
88 | * Note: joystick address handling might still be wrong on archs | ||
89 | * other than i386 | ||
90 | * 10.05.1999 0.21 Added support for an electret mic for SB PCI64 | ||
91 | * to the Linux kernel sound driver. This mod also straighten | ||
92 | * out the question marks around the mic impedance setting | ||
93 | * (micz). From Kim.Berts@fisub.mail.abb.com | ||
94 | * 11.05.1999 0.22 Implemented the IMIX call to mute recording monitor. | ||
95 | * Guenter Geiger <geiger@epy.co.at> | ||
96 | * 15.06.1999 0.23 Fix bad allocation bug. | ||
97 | * Thanks to Deti Fliegl <fliegl@in.tum.de> | ||
98 | * 28.06.1999 0.24 Add pci_set_master | ||
99 | * 02.08.1999 0.25 Added workaround for the "phantom write" bug first | ||
100 | * documented by Dave Sharpless from Anchor Games | ||
101 | * 03.08.1999 0.26 adapt to Linus' new __setup/__initcall | ||
102 | * added kernel command line option "es1370=joystick[,lineout[,micbias]]" | ||
103 | * removed CONFIG_SOUND_ES1370_JOYPORT_BOOT kludge | ||
104 | * 12.08.1999 0.27 module_init/__setup fixes | ||
105 | * 19.08.1999 0.28 SOUND_MIXER_IMIX fixes, reported by Gianluca <gialluca@mail.tiscalinet.it> | ||
106 | * 31.08.1999 0.29 add spin_lock_init | ||
107 | * replaced current->state = x with set_current_state(x) | ||
108 | * 03.09.1999 0.30 change read semantics for MIDI to match | ||
109 | * OSS more closely; remove possible wakeup race | ||
110 | * 28.10.1999 0.31 More waitqueue races fixed | ||
111 | * 08.01.2000 0.32 Prevent some ioctl's from returning bad count values on underrun/overrun; | ||
112 | * Tim Janik's BSE (Bedevilled Sound Engine) found this | ||
113 | * 07.02.2000 0.33 Use pci_alloc_consistent and pci_register_driver | ||
114 | * 21.11.2000 0.34 Initialize dma buffers in poll, otherwise poll may return a bogus mask | ||
115 | * 12.12.2000 0.35 More dma buffer initializations, patch from | ||
116 | * Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com> | ||
117 | * 07.01.2001 0.36 Timeout change in wrcodec as requested by Frank Klemm <pfk@fuchs.offl.uni-jena.de> | ||
118 | * 31.01.2001 0.37 Register/Unregister gameport | ||
119 | * Fix SETTRIGGER non OSS API conformity | ||
120 | * 03.01.2003 0.38 open_mode fixes from Georg Acher <acher@in.tum.de> | ||
121 | * | ||
122 | * some important things missing in Ensoniq documentation: | ||
123 | * | ||
124 | * Experimental PCLKDIV results: play the same waveforms on both DAC1 and DAC2 | ||
125 | * and vary PCLKDIV to obtain zero beat. | ||
126 | * 5512sps: 254 | ||
127 | * 44100sps: 30 | ||
128 | * seems to be fs = 1411200/(PCLKDIV+2) | ||
129 | * | ||
130 | * should find out when curr_sample_ct is cleared and | ||
131 | * where exactly the CCB fetches data | ||
132 | * | ||
133 | * The card uses a 22.5792 MHz crystal. | ||
134 | * The LINEIN jack may be converted to an AOUT jack by | ||
135 | * setting pin 47 (XCTL0) of the ES1370 to high. | ||
136 | * Pin 48 (XCTL1) of the ES1370 sets the +5V bias for an electretmic | ||
137 | * | ||
138 | * | ||
139 | */ | ||
140 | |||
141 | /*****************************************************************************/ | ||
142 | |||
143 | #include <linux/interrupt.h> | ||
144 | #include <linux/module.h> | ||
145 | #include <linux/string.h> | ||
146 | #include <linux/ioport.h> | ||
147 | #include <linux/sched.h> | ||
148 | #include <linux/delay.h> | ||
149 | #include <linux/sound.h> | ||
150 | #include <linux/slab.h> | ||
151 | #include <linux/soundcard.h> | ||
152 | #include <linux/pci.h> | ||
153 | #include <linux/smp_lock.h> | ||
154 | #include <linux/init.h> | ||
155 | #include <linux/poll.h> | ||
156 | #include <linux/spinlock.h> | ||
157 | #include <linux/gameport.h> | ||
158 | #include <linux/wait.h> | ||
159 | #include <linux/dma-mapping.h> | ||
160 | #include <linux/mutex.h> | ||
161 | |||
162 | #include <asm/io.h> | ||
163 | #include <asm/page.h> | ||
164 | #include <asm/uaccess.h> | ||
165 | |||
166 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) | ||
167 | #define SUPPORT_JOYSTICK | ||
168 | #endif | ||
169 | |||
170 | /* --------------------------------------------------------------------- */ | ||
171 | |||
172 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
173 | #define DBG(x) {} | ||
174 | /*#define DBG(x) {x}*/ | ||
175 | |||
176 | /* --------------------------------------------------------------------- */ | ||
177 | |||
178 | #ifndef PCI_VENDOR_ID_ENSONIQ | ||
179 | #define PCI_VENDOR_ID_ENSONIQ 0x1274 | ||
180 | #endif | ||
181 | |||
182 | #ifndef PCI_DEVICE_ID_ENSONIQ_ES1370 | ||
183 | #define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000 | ||
184 | #endif | ||
185 | |||
186 | #define ES1370_MAGIC ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1370) | ||
187 | |||
188 | #define ES1370_EXTENT 0x40 | ||
189 | #define JOY_EXTENT 8 | ||
190 | |||
191 | #define ES1370_REG_CONTROL 0x00 | ||
192 | #define ES1370_REG_STATUS 0x04 | ||
193 | #define ES1370_REG_UART_DATA 0x08 | ||
194 | #define ES1370_REG_UART_STATUS 0x09 | ||
195 | #define ES1370_REG_UART_CONTROL 0x09 | ||
196 | #define ES1370_REG_UART_TEST 0x0a | ||
197 | #define ES1370_REG_MEMPAGE 0x0c | ||
198 | #define ES1370_REG_CODEC 0x10 | ||
199 | #define ES1370_REG_SERIAL_CONTROL 0x20 | ||
200 | #define ES1370_REG_DAC1_SCOUNT 0x24 | ||
201 | #define ES1370_REG_DAC2_SCOUNT 0x28 | ||
202 | #define ES1370_REG_ADC_SCOUNT 0x2c | ||
203 | |||
204 | #define ES1370_REG_DAC1_FRAMEADR 0xc30 | ||
205 | #define ES1370_REG_DAC1_FRAMECNT 0xc34 | ||
206 | #define ES1370_REG_DAC2_FRAMEADR 0xc38 | ||
207 | #define ES1370_REG_DAC2_FRAMECNT 0xc3c | ||
208 | #define ES1370_REG_ADC_FRAMEADR 0xd30 | ||
209 | #define ES1370_REG_ADC_FRAMECNT 0xd34 | ||
210 | #define ES1370_REG_PHANTOM_FRAMEADR 0xd38 | ||
211 | #define ES1370_REG_PHANTOM_FRAMECNT 0xd3c | ||
212 | |||
213 | #define ES1370_FMT_U8_MONO 0 | ||
214 | #define ES1370_FMT_U8_STEREO 1 | ||
215 | #define ES1370_FMT_S16_MONO 2 | ||
216 | #define ES1370_FMT_S16_STEREO 3 | ||
217 | #define ES1370_FMT_STEREO 1 | ||
218 | #define ES1370_FMT_S16 2 | ||
219 | #define ES1370_FMT_MASK 3 | ||
220 | |||
221 | static const unsigned sample_size[] = { 1, 2, 2, 4 }; | ||
222 | static const unsigned sample_shift[] = { 0, 1, 1, 2 }; | ||
223 | |||
224 | static const unsigned dac1_samplerate[] = { 5512, 11025, 22050, 44100 }; | ||
225 | |||
226 | #define DAC2_SRTODIV(x) (((1411200+(x)/2)/(x))-2) | ||
227 | #define DAC2_DIVTOSR(x) (1411200/((x)+2)) | ||
228 | |||
229 | #define CTRL_ADC_STOP 0x80000000 /* 1 = ADC stopped */ | ||
230 | #define CTRL_XCTL1 0x40000000 /* electret mic bias */ | ||
231 | #define CTRL_OPEN 0x20000000 /* no function, can be read and written */ | ||
232 | #define CTRL_PCLKDIV 0x1fff0000 /* ADC/DAC2 clock divider */ | ||
233 | #define CTRL_SH_PCLKDIV 16 | ||
234 | #define CTRL_MSFMTSEL 0x00008000 /* MPEG serial data fmt: 0 = Sony, 1 = I2S */ | ||
235 | #define CTRL_M_SBB 0x00004000 /* DAC2 clock: 0 = PCLKDIV, 1 = MPEG */ | ||
236 | #define CTRL_WTSRSEL 0x00003000 /* DAC1 clock freq: 0=5512, 1=11025, 2=22050, 3=44100 */ | ||
237 | #define CTRL_SH_WTSRSEL 12 | ||
238 | #define CTRL_DAC_SYNC 0x00000800 /* 1 = DAC2 runs off DAC1 clock */ | ||
239 | #define CTRL_CCB_INTRM 0x00000400 /* 1 = CCB "voice" ints enabled */ | ||
240 | #define CTRL_M_CB 0x00000200 /* recording source: 0 = ADC, 1 = MPEG */ | ||
241 | #define CTRL_XCTL0 0x00000100 /* 0 = Line in, 1 = Line out */ | ||
242 | #define CTRL_BREQ 0x00000080 /* 1 = test mode (internal mem test) */ | ||
243 | #define CTRL_DAC1_EN 0x00000040 /* enable DAC1 */ | ||
244 | #define CTRL_DAC2_EN 0x00000020 /* enable DAC2 */ | ||
245 | #define CTRL_ADC_EN 0x00000010 /* enable ADC */ | ||
246 | #define CTRL_UART_EN 0x00000008 /* enable MIDI uart */ | ||
247 | #define CTRL_JYSTK_EN 0x00000004 /* enable Joystick port (presumably at address 0x200) */ | ||
248 | #define CTRL_CDC_EN 0x00000002 /* enable serial (CODEC) interface */ | ||
249 | #define CTRL_SERR_DIS 0x00000001 /* 1 = disable PCI SERR signal */ | ||
250 | |||
251 | #define STAT_INTR 0x80000000 /* wired or of all interrupt bits */ | ||
252 | #define STAT_CSTAT 0x00000400 /* 1 = codec busy or codec write in progress */ | ||
253 | #define STAT_CBUSY 0x00000200 /* 1 = codec busy */ | ||
254 | #define STAT_CWRIP 0x00000100 /* 1 = codec write in progress */ | ||
255 | #define STAT_VC 0x00000060 /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */ | ||
256 | #define STAT_SH_VC 5 | ||
257 | #define STAT_MCCB 0x00000010 /* CCB int pending */ | ||
258 | #define STAT_UART 0x00000008 /* UART int pending */ | ||
259 | #define STAT_DAC1 0x00000004 /* DAC1 int pending */ | ||
260 | #define STAT_DAC2 0x00000002 /* DAC2 int pending */ | ||
261 | #define STAT_ADC 0x00000001 /* ADC int pending */ | ||
262 | |||
263 | #define USTAT_RXINT 0x80 /* UART rx int pending */ | ||
264 | #define USTAT_TXINT 0x04 /* UART tx int pending */ | ||
265 | #define USTAT_TXRDY 0x02 /* UART tx ready */ | ||
266 | #define USTAT_RXRDY 0x01 /* UART rx ready */ | ||
267 | |||
268 | #define UCTRL_RXINTEN 0x80 /* 1 = enable RX ints */ | ||
269 | #define UCTRL_TXINTEN 0x60 /* TX int enable field mask */ | ||
270 | #define UCTRL_ENA_TXINT 0x20 /* enable TX int */ | ||
271 | #define UCTRL_CNTRL 0x03 /* control field */ | ||
272 | #define UCTRL_CNTRL_SWR 0x03 /* software reset command */ | ||
273 | |||
274 | #define SCTRL_P2ENDINC 0x00380000 /* */ | ||
275 | #define SCTRL_SH_P2ENDINC 19 | ||
276 | #define SCTRL_P2STINC 0x00070000 /* */ | ||
277 | #define SCTRL_SH_P2STINC 16 | ||
278 | #define SCTRL_R1LOOPSEL 0x00008000 /* 0 = loop mode */ | ||
279 | #define SCTRL_P2LOOPSEL 0x00004000 /* 0 = loop mode */ | ||
280 | #define SCTRL_P1LOOPSEL 0x00002000 /* 0 = loop mode */ | ||
281 | #define SCTRL_P2PAUSE 0x00001000 /* 1 = pause mode */ | ||
282 | #define SCTRL_P1PAUSE 0x00000800 /* 1 = pause mode */ | ||
283 | #define SCTRL_R1INTEN 0x00000400 /* enable interrupt */ | ||
284 | #define SCTRL_P2INTEN 0x00000200 /* enable interrupt */ | ||
285 | #define SCTRL_P1INTEN 0x00000100 /* enable interrupt */ | ||
286 | #define SCTRL_P1SCTRLD 0x00000080 /* reload sample count register for DAC1 */ | ||
287 | #define SCTRL_P2DACSEN 0x00000040 /* 1 = DAC2 play back last sample when disabled */ | ||
288 | #define SCTRL_R1SEB 0x00000020 /* 1 = 16bit */ | ||
289 | #define SCTRL_R1SMB 0x00000010 /* 1 = stereo */ | ||
290 | #define SCTRL_R1FMT 0x00000030 /* format mask */ | ||
291 | #define SCTRL_SH_R1FMT 4 | ||
292 | #define SCTRL_P2SEB 0x00000008 /* 1 = 16bit */ | ||
293 | #define SCTRL_P2SMB 0x00000004 /* 1 = stereo */ | ||
294 | #define SCTRL_P2FMT 0x0000000c /* format mask */ | ||
295 | #define SCTRL_SH_P2FMT 2 | ||
296 | #define SCTRL_P1SEB 0x00000002 /* 1 = 16bit */ | ||
297 | #define SCTRL_P1SMB 0x00000001 /* 1 = stereo */ | ||
298 | #define SCTRL_P1FMT 0x00000003 /* format mask */ | ||
299 | #define SCTRL_SH_P1FMT 0 | ||
300 | |||
301 | /* misc stuff */ | ||
302 | |||
303 | #define FMODE_DAC 4 /* slight misuse of mode_t */ | ||
304 | |||
305 | /* MIDI buffer sizes */ | ||
306 | |||
307 | #define MIDIINBUF 256 | ||
308 | #define MIDIOUTBUF 256 | ||
309 | |||
310 | #define FMODE_MIDI_SHIFT 3 | ||
311 | #define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) | ||
312 | #define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) | ||
313 | |||
314 | /* --------------------------------------------------------------------- */ | ||
315 | |||
316 | struct es1370_state { | ||
317 | /* magic */ | ||
318 | unsigned int magic; | ||
319 | |||
320 | /* list of es1370 devices */ | ||
321 | struct list_head devs; | ||
322 | |||
323 | /* the corresponding pci_dev structure */ | ||
324 | struct pci_dev *dev; | ||
325 | |||
326 | /* soundcore stuff */ | ||
327 | int dev_audio; | ||
328 | int dev_mixer; | ||
329 | int dev_dac; | ||
330 | int dev_midi; | ||
331 | |||
332 | /* hardware resources */ | ||
333 | unsigned long io; /* long for SPARC */ | ||
334 | unsigned int irq; | ||
335 | |||
336 | /* mixer registers; there is no HW readback */ | ||
337 | struct { | ||
338 | unsigned short vol[10]; | ||
339 | unsigned int recsrc; | ||
340 | unsigned int modcnt; | ||
341 | unsigned short micpreamp; | ||
342 | unsigned int imix; | ||
343 | } mix; | ||
344 | |||
345 | /* wave stuff */ | ||
346 | unsigned ctrl; | ||
347 | unsigned sctrl; | ||
348 | |||
349 | spinlock_t lock; | ||
350 | struct mutex open_mutex; | ||
351 | mode_t open_mode; | ||
352 | wait_queue_head_t open_wait; | ||
353 | |||
354 | struct dmabuf { | ||
355 | void *rawbuf; | ||
356 | dma_addr_t dmaaddr; | ||
357 | unsigned buforder; | ||
358 | unsigned numfrag; | ||
359 | unsigned fragshift; | ||
360 | unsigned hwptr, swptr; | ||
361 | unsigned total_bytes; | ||
362 | int count; | ||
363 | unsigned error; /* over/underrun */ | ||
364 | wait_queue_head_t wait; | ||
365 | /* redundant, but makes calculations easier */ | ||
366 | unsigned fragsize; | ||
367 | unsigned dmasize; | ||
368 | unsigned fragsamples; | ||
369 | /* OSS stuff */ | ||
370 | unsigned mapped:1; | ||
371 | unsigned ready:1; | ||
372 | unsigned endcleared:1; | ||
373 | unsigned enabled:1; | ||
374 | unsigned ossfragshift; | ||
375 | int ossmaxfrags; | ||
376 | unsigned subdivision; | ||
377 | } dma_dac1, dma_dac2, dma_adc; | ||
378 | |||
379 | /* The following buffer is used to point the phantom write channel to. */ | ||
380 | unsigned char *bugbuf_cpu; | ||
381 | dma_addr_t bugbuf_dma; | ||
382 | |||
383 | /* midi stuff */ | ||
384 | struct { | ||
385 | unsigned ird, iwr, icnt; | ||
386 | unsigned ord, owr, ocnt; | ||
387 | wait_queue_head_t iwait; | ||
388 | wait_queue_head_t owait; | ||
389 | unsigned char ibuf[MIDIINBUF]; | ||
390 | unsigned char obuf[MIDIOUTBUF]; | ||
391 | } midi; | ||
392 | |||
393 | #ifdef SUPPORT_JOYSTICK | ||
394 | struct gameport *gameport; | ||
395 | #endif | ||
396 | |||
397 | struct mutex mutex; | ||
398 | }; | ||
399 | |||
400 | /* --------------------------------------------------------------------- */ | ||
401 | |||
402 | static LIST_HEAD(devs); | ||
403 | |||
404 | /* --------------------------------------------------------------------- */ | ||
405 | |||
406 | static inline unsigned ld2(unsigned int x) | ||
407 | { | ||
408 | unsigned r = 0; | ||
409 | |||
410 | if (x >= 0x10000) { | ||
411 | x >>= 16; | ||
412 | r += 16; | ||
413 | } | ||
414 | if (x >= 0x100) { | ||
415 | x >>= 8; | ||
416 | r += 8; | ||
417 | } | ||
418 | if (x >= 0x10) { | ||
419 | x >>= 4; | ||
420 | r += 4; | ||
421 | } | ||
422 | if (x >= 4) { | ||
423 | x >>= 2; | ||
424 | r += 2; | ||
425 | } | ||
426 | if (x >= 2) | ||
427 | r++; | ||
428 | return r; | ||
429 | } | ||
430 | |||
431 | /* --------------------------------------------------------------------- */ | ||
432 | |||
433 | static void wrcodec(struct es1370_state *s, unsigned char idx, unsigned char data) | ||
434 | { | ||
435 | unsigned long tmo = jiffies + HZ/10, j; | ||
436 | |||
437 | do { | ||
438 | j = jiffies; | ||
439 | if (!(inl(s->io+ES1370_REG_STATUS) & STAT_CSTAT)) { | ||
440 | outw((((unsigned short)idx)<<8)|data, s->io+ES1370_REG_CODEC); | ||
441 | return; | ||
442 | } | ||
443 | schedule(); | ||
444 | } while ((signed)(tmo-j) > 0); | ||
445 | printk(KERN_ERR "es1370: write to codec register timeout\n"); | ||
446 | } | ||
447 | |||
448 | /* --------------------------------------------------------------------- */ | ||
449 | |||
450 | static inline void stop_adc(struct es1370_state *s) | ||
451 | { | ||
452 | unsigned long flags; | ||
453 | |||
454 | spin_lock_irqsave(&s->lock, flags); | ||
455 | s->ctrl &= ~CTRL_ADC_EN; | ||
456 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
457 | spin_unlock_irqrestore(&s->lock, flags); | ||
458 | } | ||
459 | |||
460 | static inline void stop_dac1(struct es1370_state *s) | ||
461 | { | ||
462 | unsigned long flags; | ||
463 | |||
464 | spin_lock_irqsave(&s->lock, flags); | ||
465 | s->ctrl &= ~CTRL_DAC1_EN; | ||
466 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
467 | spin_unlock_irqrestore(&s->lock, flags); | ||
468 | } | ||
469 | |||
470 | static inline void stop_dac2(struct es1370_state *s) | ||
471 | { | ||
472 | unsigned long flags; | ||
473 | |||
474 | spin_lock_irqsave(&s->lock, flags); | ||
475 | s->ctrl &= ~CTRL_DAC2_EN; | ||
476 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
477 | spin_unlock_irqrestore(&s->lock, flags); | ||
478 | } | ||
479 | |||
480 | static void start_dac1(struct es1370_state *s) | ||
481 | { | ||
482 | unsigned long flags; | ||
483 | unsigned fragremain, fshift; | ||
484 | |||
485 | spin_lock_irqsave(&s->lock, flags); | ||
486 | if (!(s->ctrl & CTRL_DAC1_EN) && (s->dma_dac1.mapped || s->dma_dac1.count > 0) | ||
487 | && s->dma_dac1.ready) { | ||
488 | s->ctrl |= CTRL_DAC1_EN; | ||
489 | s->sctrl = (s->sctrl & ~(SCTRL_P1LOOPSEL | SCTRL_P1PAUSE | SCTRL_P1SCTRLD)) | SCTRL_P1INTEN; | ||
490 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
491 | fragremain = ((- s->dma_dac1.hwptr) & (s->dma_dac1.fragsize-1)); | ||
492 | fshift = sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; | ||
493 | if (fragremain < 2*fshift) | ||
494 | fragremain = s->dma_dac1.fragsize; | ||
495 | outl((fragremain >> fshift) - 1, s->io+ES1370_REG_DAC1_SCOUNT); | ||
496 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
497 | outl((s->dma_dac1.fragsize >> fshift) - 1, s->io+ES1370_REG_DAC1_SCOUNT); | ||
498 | } | ||
499 | spin_unlock_irqrestore(&s->lock, flags); | ||
500 | } | ||
501 | |||
502 | static void start_dac2(struct es1370_state *s) | ||
503 | { | ||
504 | unsigned long flags; | ||
505 | unsigned fragremain, fshift; | ||
506 | |||
507 | spin_lock_irqsave(&s->lock, flags); | ||
508 | if (!(s->ctrl & CTRL_DAC2_EN) && (s->dma_dac2.mapped || s->dma_dac2.count > 0) | ||
509 | && s->dma_dac2.ready) { | ||
510 | s->ctrl |= CTRL_DAC2_EN; | ||
511 | s->sctrl = (s->sctrl & ~(SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN | | ||
512 | SCTRL_P2ENDINC | SCTRL_P2STINC)) | SCTRL_P2INTEN | | ||
513 | (((s->sctrl & SCTRL_P2FMT) ? 2 : 1) << SCTRL_SH_P2ENDINC) | | ||
514 | (0 << SCTRL_SH_P2STINC); | ||
515 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
516 | fragremain = ((- s->dma_dac2.hwptr) & (s->dma_dac2.fragsize-1)); | ||
517 | fshift = sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; | ||
518 | if (fragremain < 2*fshift) | ||
519 | fragremain = s->dma_dac2.fragsize; | ||
520 | outl((fragremain >> fshift) - 1, s->io+ES1370_REG_DAC2_SCOUNT); | ||
521 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
522 | outl((s->dma_dac2.fragsize >> fshift) - 1, s->io+ES1370_REG_DAC2_SCOUNT); | ||
523 | } | ||
524 | spin_unlock_irqrestore(&s->lock, flags); | ||
525 | } | ||
526 | |||
527 | static void start_adc(struct es1370_state *s) | ||
528 | { | ||
529 | unsigned long flags; | ||
530 | unsigned fragremain, fshift; | ||
531 | |||
532 | spin_lock_irqsave(&s->lock, flags); | ||
533 | if (!(s->ctrl & CTRL_ADC_EN) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) | ||
534 | && s->dma_adc.ready) { | ||
535 | s->ctrl |= CTRL_ADC_EN; | ||
536 | s->sctrl = (s->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN; | ||
537 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
538 | fragremain = ((- s->dma_adc.hwptr) & (s->dma_adc.fragsize-1)); | ||
539 | fshift = sample_shift[(s->sctrl & SCTRL_R1FMT) >> SCTRL_SH_R1FMT]; | ||
540 | if (fragremain < 2*fshift) | ||
541 | fragremain = s->dma_adc.fragsize; | ||
542 | outl((fragremain >> fshift) - 1, s->io+ES1370_REG_ADC_SCOUNT); | ||
543 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
544 | outl((s->dma_adc.fragsize >> fshift) - 1, s->io+ES1370_REG_ADC_SCOUNT); | ||
545 | } | ||
546 | spin_unlock_irqrestore(&s->lock, flags); | ||
547 | } | ||
548 | |||
549 | /* --------------------------------------------------------------------- */ | ||
550 | |||
551 | #define DMABUF_DEFAULTORDER (17-PAGE_SHIFT) | ||
552 | #define DMABUF_MINORDER 1 | ||
553 | |||
554 | static inline void dealloc_dmabuf(struct es1370_state *s, struct dmabuf *db) | ||
555 | { | ||
556 | struct page *page, *pend; | ||
557 | |||
558 | if (db->rawbuf) { | ||
559 | /* undo marking the pages as reserved */ | ||
560 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
561 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
562 | ClearPageReserved(page); | ||
563 | pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr); | ||
564 | } | ||
565 | db->rawbuf = NULL; | ||
566 | db->mapped = db->ready = 0; | ||
567 | } | ||
568 | |||
569 | static int prog_dmabuf(struct es1370_state *s, struct dmabuf *db, unsigned rate, unsigned fmt, unsigned reg) | ||
570 | { | ||
571 | int order; | ||
572 | unsigned bytepersec; | ||
573 | unsigned bufs; | ||
574 | struct page *page, *pend; | ||
575 | |||
576 | db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; | ||
577 | if (!db->rawbuf) { | ||
578 | db->ready = db->mapped = 0; | ||
579 | for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) | ||
580 | if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr))) | ||
581 | break; | ||
582 | if (!db->rawbuf) | ||
583 | return -ENOMEM; | ||
584 | db->buforder = order; | ||
585 | /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ | ||
586 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
587 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
588 | SetPageReserved(page); | ||
589 | } | ||
590 | fmt &= ES1370_FMT_MASK; | ||
591 | bytepersec = rate << sample_shift[fmt]; | ||
592 | bufs = PAGE_SIZE << db->buforder; | ||
593 | if (db->ossfragshift) { | ||
594 | if ((1000 << db->ossfragshift) < bytepersec) | ||
595 | db->fragshift = ld2(bytepersec/1000); | ||
596 | else | ||
597 | db->fragshift = db->ossfragshift; | ||
598 | } else { | ||
599 | db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); | ||
600 | if (db->fragshift < 3) | ||
601 | db->fragshift = 3; | ||
602 | } | ||
603 | db->numfrag = bufs >> db->fragshift; | ||
604 | while (db->numfrag < 4 && db->fragshift > 3) { | ||
605 | db->fragshift--; | ||
606 | db->numfrag = bufs >> db->fragshift; | ||
607 | } | ||
608 | db->fragsize = 1 << db->fragshift; | ||
609 | if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) | ||
610 | db->numfrag = db->ossmaxfrags; | ||
611 | db->fragsamples = db->fragsize >> sample_shift[fmt]; | ||
612 | db->dmasize = db->numfrag << db->fragshift; | ||
613 | memset(db->rawbuf, (fmt & ES1370_FMT_S16) ? 0 : 0x80, db->dmasize); | ||
614 | outl((reg >> 8) & 15, s->io+ES1370_REG_MEMPAGE); | ||
615 | outl(db->dmaaddr, s->io+(reg & 0xff)); | ||
616 | outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff)); | ||
617 | db->enabled = 1; | ||
618 | db->ready = 1; | ||
619 | return 0; | ||
620 | } | ||
621 | |||
622 | static inline int prog_dmabuf_adc(struct es1370_state *s) | ||
623 | { | ||
624 | stop_adc(s); | ||
625 | return prog_dmabuf(s, &s->dma_adc, DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), | ||
626 | (s->sctrl >> SCTRL_SH_R1FMT) & ES1370_FMT_MASK, ES1370_REG_ADC_FRAMEADR); | ||
627 | } | ||
628 | |||
629 | static inline int prog_dmabuf_dac2(struct es1370_state *s) | ||
630 | { | ||
631 | stop_dac2(s); | ||
632 | return prog_dmabuf(s, &s->dma_dac2, DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), | ||
633 | (s->sctrl >> SCTRL_SH_P2FMT) & ES1370_FMT_MASK, ES1370_REG_DAC2_FRAMEADR); | ||
634 | } | ||
635 | |||
636 | static inline int prog_dmabuf_dac1(struct es1370_state *s) | ||
637 | { | ||
638 | stop_dac1(s); | ||
639 | return prog_dmabuf(s, &s->dma_dac1, dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], | ||
640 | (s->sctrl >> SCTRL_SH_P1FMT) & ES1370_FMT_MASK, ES1370_REG_DAC1_FRAMEADR); | ||
641 | } | ||
642 | |||
643 | static inline unsigned get_hwptr(struct es1370_state *s, struct dmabuf *db, unsigned reg) | ||
644 | { | ||
645 | unsigned hwptr, diff; | ||
646 | |||
647 | outl((reg >> 8) & 15, s->io+ES1370_REG_MEMPAGE); | ||
648 | hwptr = (inl(s->io+(reg & 0xff)) >> 14) & 0x3fffc; | ||
649 | diff = (db->dmasize + hwptr - db->hwptr) % db->dmasize; | ||
650 | db->hwptr = hwptr; | ||
651 | return diff; | ||
652 | } | ||
653 | |||
654 | static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c) | ||
655 | { | ||
656 | if (bptr + len > bsize) { | ||
657 | unsigned x = bsize - bptr; | ||
658 | memset(((char *)buf) + bptr, c, x); | ||
659 | bptr = 0; | ||
660 | len -= x; | ||
661 | } | ||
662 | memset(((char *)buf) + bptr, c, len); | ||
663 | } | ||
664 | |||
665 | /* call with spinlock held! */ | ||
666 | static void es1370_update_ptr(struct es1370_state *s) | ||
667 | { | ||
668 | int diff; | ||
669 | |||
670 | /* update ADC pointer */ | ||
671 | if (s->ctrl & CTRL_ADC_EN) { | ||
672 | diff = get_hwptr(s, &s->dma_adc, ES1370_REG_ADC_FRAMECNT); | ||
673 | s->dma_adc.total_bytes += diff; | ||
674 | s->dma_adc.count += diff; | ||
675 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
676 | wake_up(&s->dma_adc.wait); | ||
677 | if (!s->dma_adc.mapped) { | ||
678 | if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { | ||
679 | s->ctrl &= ~CTRL_ADC_EN; | ||
680 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
681 | s->dma_adc.error++; | ||
682 | } | ||
683 | } | ||
684 | } | ||
685 | /* update DAC1 pointer */ | ||
686 | if (s->ctrl & CTRL_DAC1_EN) { | ||
687 | diff = get_hwptr(s, &s->dma_dac1, ES1370_REG_DAC1_FRAMECNT); | ||
688 | s->dma_dac1.total_bytes += diff; | ||
689 | if (s->dma_dac1.mapped) { | ||
690 | s->dma_dac1.count += diff; | ||
691 | if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize) | ||
692 | wake_up(&s->dma_dac1.wait); | ||
693 | } else { | ||
694 | s->dma_dac1.count -= diff; | ||
695 | if (s->dma_dac1.count <= 0) { | ||
696 | s->ctrl &= ~CTRL_DAC1_EN; | ||
697 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
698 | s->dma_dac1.error++; | ||
699 | } else if (s->dma_dac1.count <= (signed)s->dma_dac1.fragsize && !s->dma_dac1.endcleared) { | ||
700 | clear_advance(s->dma_dac1.rawbuf, s->dma_dac1.dmasize, s->dma_dac1.swptr, | ||
701 | s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80); | ||
702 | s->dma_dac1.endcleared = 1; | ||
703 | } | ||
704 | if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize) | ||
705 | wake_up(&s->dma_dac1.wait); | ||
706 | } | ||
707 | } | ||
708 | /* update DAC2 pointer */ | ||
709 | if (s->ctrl & CTRL_DAC2_EN) { | ||
710 | diff = get_hwptr(s, &s->dma_dac2, ES1370_REG_DAC2_FRAMECNT); | ||
711 | s->dma_dac2.total_bytes += diff; | ||
712 | if (s->dma_dac2.mapped) { | ||
713 | s->dma_dac2.count += diff; | ||
714 | if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) | ||
715 | wake_up(&s->dma_dac2.wait); | ||
716 | } else { | ||
717 | s->dma_dac2.count -= diff; | ||
718 | if (s->dma_dac2.count <= 0) { | ||
719 | s->ctrl &= ~CTRL_DAC2_EN; | ||
720 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
721 | s->dma_dac2.error++; | ||
722 | } else if (s->dma_dac2.count <= (signed)s->dma_dac2.fragsize && !s->dma_dac2.endcleared) { | ||
723 | clear_advance(s->dma_dac2.rawbuf, s->dma_dac2.dmasize, s->dma_dac2.swptr, | ||
724 | s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80); | ||
725 | s->dma_dac2.endcleared = 1; | ||
726 | } | ||
727 | if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize) | ||
728 | wake_up(&s->dma_dac2.wait); | ||
729 | } | ||
730 | } | ||
731 | } | ||
732 | |||
733 | /* hold spinlock for the following! */ | ||
734 | static void es1370_handle_midi(struct es1370_state *s) | ||
735 | { | ||
736 | unsigned char ch; | ||
737 | int wake; | ||
738 | |||
739 | if (!(s->ctrl & CTRL_UART_EN)) | ||
740 | return; | ||
741 | wake = 0; | ||
742 | while (inb(s->io+ES1370_REG_UART_STATUS) & USTAT_RXRDY) { | ||
743 | ch = inb(s->io+ES1370_REG_UART_DATA); | ||
744 | if (s->midi.icnt < MIDIINBUF) { | ||
745 | s->midi.ibuf[s->midi.iwr] = ch; | ||
746 | s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF; | ||
747 | s->midi.icnt++; | ||
748 | } | ||
749 | wake = 1; | ||
750 | } | ||
751 | if (wake) | ||
752 | wake_up(&s->midi.iwait); | ||
753 | wake = 0; | ||
754 | while ((inb(s->io+ES1370_REG_UART_STATUS) & USTAT_TXRDY) && s->midi.ocnt > 0) { | ||
755 | outb(s->midi.obuf[s->midi.ord], s->io+ES1370_REG_UART_DATA); | ||
756 | s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF; | ||
757 | s->midi.ocnt--; | ||
758 | if (s->midi.ocnt < MIDIOUTBUF-16) | ||
759 | wake = 1; | ||
760 | } | ||
761 | if (wake) | ||
762 | wake_up(&s->midi.owait); | ||
763 | outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1370_REG_UART_CONTROL); | ||
764 | } | ||
765 | |||
766 | static irqreturn_t es1370_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
767 | { | ||
768 | struct es1370_state *s = (struct es1370_state *)dev_id; | ||
769 | unsigned int intsrc, sctl; | ||
770 | |||
771 | /* fastpath out, to ease interrupt sharing */ | ||
772 | intsrc = inl(s->io+ES1370_REG_STATUS); | ||
773 | if (!(intsrc & 0x80000000)) | ||
774 | return IRQ_NONE; | ||
775 | spin_lock(&s->lock); | ||
776 | /* clear audio interrupts first */ | ||
777 | sctl = s->sctrl; | ||
778 | if (intsrc & STAT_ADC) | ||
779 | sctl &= ~SCTRL_R1INTEN; | ||
780 | if (intsrc & STAT_DAC1) | ||
781 | sctl &= ~SCTRL_P1INTEN; | ||
782 | if (intsrc & STAT_DAC2) | ||
783 | sctl &= ~SCTRL_P2INTEN; | ||
784 | outl(sctl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
785 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
786 | es1370_update_ptr(s); | ||
787 | es1370_handle_midi(s); | ||
788 | spin_unlock(&s->lock); | ||
789 | return IRQ_HANDLED; | ||
790 | } | ||
791 | |||
792 | /* --------------------------------------------------------------------- */ | ||
793 | |||
794 | static const char invalid_magic[] = KERN_CRIT "es1370: invalid magic value\n"; | ||
795 | |||
796 | #define VALIDATE_STATE(s) \ | ||
797 | ({ \ | ||
798 | if (!(s) || (s)->magic != ES1370_MAGIC) { \ | ||
799 | printk(invalid_magic); \ | ||
800 | return -ENXIO; \ | ||
801 | } \ | ||
802 | }) | ||
803 | |||
804 | /* --------------------------------------------------------------------- */ | ||
805 | |||
806 | static const struct { | ||
807 | unsigned volidx:4; | ||
808 | unsigned left:4; | ||
809 | unsigned right:4; | ||
810 | unsigned stereo:1; | ||
811 | unsigned recmask:13; | ||
812 | unsigned avail:1; | ||
813 | } mixtable[SOUND_MIXER_NRDEVICES] = { | ||
814 | [SOUND_MIXER_VOLUME] = { 0, 0x0, 0x1, 1, 0x0000, 1 }, /* master */ | ||
815 | [SOUND_MIXER_PCM] = { 1, 0x2, 0x3, 1, 0x0400, 1 }, /* voice */ | ||
816 | [SOUND_MIXER_SYNTH] = { 2, 0x4, 0x5, 1, 0x0060, 1 }, /* FM */ | ||
817 | [SOUND_MIXER_CD] = { 3, 0x6, 0x7, 1, 0x0006, 1 }, /* CD */ | ||
818 | [SOUND_MIXER_LINE] = { 4, 0x8, 0x9, 1, 0x0018, 1 }, /* Line */ | ||
819 | [SOUND_MIXER_LINE1] = { 5, 0xa, 0xb, 1, 0x1800, 1 }, /* AUX */ | ||
820 | [SOUND_MIXER_LINE2] = { 6, 0xc, 0x0, 0, 0x0100, 1 }, /* Mono1 */ | ||
821 | [SOUND_MIXER_LINE3] = { 7, 0xd, 0x0, 0, 0x0200, 1 }, /* Mono2 */ | ||
822 | [SOUND_MIXER_MIC] = { 8, 0xe, 0x0, 0, 0x0001, 1 }, /* Mic */ | ||
823 | [SOUND_MIXER_OGAIN] = { 9, 0xf, 0x0, 0, 0x0000, 1 } /* mono out */ | ||
824 | }; | ||
825 | |||
826 | static void set_recsrc(struct es1370_state *s, unsigned int val) | ||
827 | { | ||
828 | unsigned int i, j; | ||
829 | |||
830 | for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||
831 | if (!(val & (1 << i))) | ||
832 | continue; | ||
833 | if (!mixtable[i].recmask) { | ||
834 | val &= ~(1 << i); | ||
835 | continue; | ||
836 | } | ||
837 | j |= mixtable[i].recmask; | ||
838 | } | ||
839 | s->mix.recsrc = val; | ||
840 | wrcodec(s, 0x12, j & 0xd5); | ||
841 | wrcodec(s, 0x13, j & 0xaa); | ||
842 | wrcodec(s, 0x14, (j >> 8) & 0x17); | ||
843 | wrcodec(s, 0x15, (j >> 8) & 0x0f); | ||
844 | i = (j & 0x37f) | ((j << 1) & 0x3000) | 0xc60; | ||
845 | if (!s->mix.imix) { | ||
846 | i &= 0xff60; /* mute record and line monitor */ | ||
847 | } | ||
848 | wrcodec(s, 0x10, i); | ||
849 | wrcodec(s, 0x11, i >> 8); | ||
850 | } | ||
851 | |||
852 | static int mixer_ioctl(struct es1370_state *s, unsigned int cmd, unsigned long arg) | ||
853 | { | ||
854 | unsigned long flags; | ||
855 | int i, val; | ||
856 | unsigned char l, r, rl, rr; | ||
857 | int __user *p = (int __user *)arg; | ||
858 | |||
859 | VALIDATE_STATE(s); | ||
860 | if (cmd == SOUND_MIXER_PRIVATE1) { | ||
861 | /* enable/disable/query mixer preamp */ | ||
862 | if (get_user(val, p)) | ||
863 | return -EFAULT; | ||
864 | if (val != -1) { | ||
865 | s->mix.micpreamp = !!val; | ||
866 | wrcodec(s, 0x19, s->mix.micpreamp); | ||
867 | } | ||
868 | return put_user(s->mix.micpreamp, p); | ||
869 | } | ||
870 | if (cmd == SOUND_MIXER_PRIVATE2) { | ||
871 | /* enable/disable/query use of linein as second lineout */ | ||
872 | if (get_user(val, p)) | ||
873 | return -EFAULT; | ||
874 | if (val != -1) { | ||
875 | spin_lock_irqsave(&s->lock, flags); | ||
876 | if (val) | ||
877 | s->ctrl |= CTRL_XCTL0; | ||
878 | else | ||
879 | s->ctrl &= ~CTRL_XCTL0; | ||
880 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
881 | spin_unlock_irqrestore(&s->lock, flags); | ||
882 | } | ||
883 | return put_user((s->ctrl & CTRL_XCTL0) ? 1 : 0, p); | ||
884 | } | ||
885 | if (cmd == SOUND_MIXER_PRIVATE3) { | ||
886 | /* enable/disable/query microphone impedance setting */ | ||
887 | if (get_user(val, p)) | ||
888 | return -EFAULT; | ||
889 | if (val != -1) { | ||
890 | spin_lock_irqsave(&s->lock, flags); | ||
891 | if (val) | ||
892 | s->ctrl |= CTRL_XCTL1; | ||
893 | else | ||
894 | s->ctrl &= ~CTRL_XCTL1; | ||
895 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
896 | spin_unlock_irqrestore(&s->lock, flags); | ||
897 | } | ||
898 | return put_user((s->ctrl & CTRL_XCTL1) ? 1 : 0, p); | ||
899 | } | ||
900 | if (cmd == SOUND_MIXER_INFO) { | ||
901 | mixer_info info; | ||
902 | strncpy(info.id, "ES1370", sizeof(info.id)); | ||
903 | strncpy(info.name, "Ensoniq ES1370", sizeof(info.name)); | ||
904 | info.modify_counter = s->mix.modcnt; | ||
905 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | ||
906 | return -EFAULT; | ||
907 | return 0; | ||
908 | } | ||
909 | if (cmd == SOUND_OLD_MIXER_INFO) { | ||
910 | _old_mixer_info info; | ||
911 | strncpy(info.id, "ES1370", sizeof(info.id)); | ||
912 | strncpy(info.name, "Ensoniq ES1370", sizeof(info.name)); | ||
913 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | ||
914 | return -EFAULT; | ||
915 | return 0; | ||
916 | } | ||
917 | if (cmd == OSS_GETVERSION) | ||
918 | return put_user(SOUND_VERSION, p); | ||
919 | if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int)) | ||
920 | return -EINVAL; | ||
921 | if (_SIOC_DIR(cmd) == _SIOC_READ) { | ||
922 | switch (_IOC_NR(cmd)) { | ||
923 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
924 | return put_user(s->mix.recsrc, p); | ||
925 | |||
926 | case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ | ||
927 | val = SOUND_MASK_IMIX; | ||
928 | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
929 | if (mixtable[i].avail) | ||
930 | val |= 1 << i; | ||
931 | return put_user(val, p); | ||
932 | |||
933 | case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ | ||
934 | for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
935 | if (mixtable[i].recmask) | ||
936 | val |= 1 << i; | ||
937 | return put_user(val, p); | ||
938 | |||
939 | case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ | ||
940 | for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
941 | if (mixtable[i].stereo) | ||
942 | val |= 1 << i; | ||
943 | return put_user(val, p); | ||
944 | |||
945 | case SOUND_MIXER_CAPS: | ||
946 | return put_user(0, p); | ||
947 | |||
948 | case SOUND_MIXER_IMIX: | ||
949 | return put_user(s->mix.imix, p); | ||
950 | |||
951 | default: | ||
952 | i = _IOC_NR(cmd); | ||
953 | if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail) | ||
954 | return -EINVAL; | ||
955 | return put_user(s->mix.vol[mixtable[i].volidx], p); | ||
956 | } | ||
957 | } | ||
958 | if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) | ||
959 | return -EINVAL; | ||
960 | s->mix.modcnt++; | ||
961 | switch (_IOC_NR(cmd)) { | ||
962 | |||
963 | case SOUND_MIXER_IMIX: | ||
964 | if (get_user(s->mix.imix, p)) | ||
965 | return -EFAULT; | ||
966 | set_recsrc(s, s->mix.recsrc); | ||
967 | return 0; | ||
968 | |||
969 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
970 | if (get_user(val, p)) | ||
971 | return -EFAULT; | ||
972 | set_recsrc(s, val); | ||
973 | return 0; | ||
974 | |||
975 | default: | ||
976 | i = _IOC_NR(cmd); | ||
977 | if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].avail) | ||
978 | return -EINVAL; | ||
979 | if (get_user(val, p)) | ||
980 | return -EFAULT; | ||
981 | l = val & 0xff; | ||
982 | if (l > 100) | ||
983 | l = 100; | ||
984 | if (mixtable[i].stereo) { | ||
985 | r = (val >> 8) & 0xff; | ||
986 | if (r > 100) | ||
987 | r = 100; | ||
988 | if (l < 7) { | ||
989 | rl = 0x80; | ||
990 | l = 0; | ||
991 | } else { | ||
992 | rl = 31 - ((l - 7) / 3); | ||
993 | l = (31 - rl) * 3 + 7; | ||
994 | } | ||
995 | if (r < 7) { | ||
996 | rr = 0x80; | ||
997 | r = 0; | ||
998 | } else { | ||
999 | rr = 31 - ((r - 7) / 3); | ||
1000 | r = (31 - rr) * 3 + 7; | ||
1001 | } | ||
1002 | wrcodec(s, mixtable[i].right, rr); | ||
1003 | } else { | ||
1004 | if (mixtable[i].left == 15) { | ||
1005 | if (l < 2) { | ||
1006 | rr = rl = 0x80; | ||
1007 | r = l = 0; | ||
1008 | } else { | ||
1009 | rl = 7 - ((l - 2) / 14); | ||
1010 | r = l = (7 - rl) * 14 + 2; | ||
1011 | } | ||
1012 | } else { | ||
1013 | if (l < 7) { | ||
1014 | rl = 0x80; | ||
1015 | r = l = 0; | ||
1016 | } else { | ||
1017 | rl = 31 - ((l - 7) / 3); | ||
1018 | r = l = (31 - rl) * 3 + 7; | ||
1019 | } | ||
1020 | } | ||
1021 | } | ||
1022 | wrcodec(s, mixtable[i].left, rl); | ||
1023 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
1024 | s->mix.vol[mixtable[i].volidx] = ((unsigned int)r << 8) | l; | ||
1025 | #else | ||
1026 | s->mix.vol[mixtable[i].volidx] = val; | ||
1027 | #endif | ||
1028 | return put_user(s->mix.vol[mixtable[i].volidx], p); | ||
1029 | } | ||
1030 | } | ||
1031 | |||
1032 | /* --------------------------------------------------------------------- */ | ||
1033 | |||
1034 | static int es1370_open_mixdev(struct inode *inode, struct file *file) | ||
1035 | { | ||
1036 | unsigned int minor = iminor(inode); | ||
1037 | struct list_head *list; | ||
1038 | struct es1370_state *s; | ||
1039 | |||
1040 | for (list = devs.next; ; list = list->next) { | ||
1041 | if (list == &devs) | ||
1042 | return -ENODEV; | ||
1043 | s = list_entry(list, struct es1370_state, devs); | ||
1044 | if (s->dev_mixer == minor) | ||
1045 | break; | ||
1046 | } | ||
1047 | VALIDATE_STATE(s); | ||
1048 | file->private_data = s; | ||
1049 | return nonseekable_open(inode, file); | ||
1050 | } | ||
1051 | |||
1052 | static int es1370_release_mixdev(struct inode *inode, struct file *file) | ||
1053 | { | ||
1054 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1055 | |||
1056 | VALIDATE_STATE(s); | ||
1057 | return 0; | ||
1058 | } | ||
1059 | |||
1060 | static int es1370_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1061 | { | ||
1062 | return mixer_ioctl((struct es1370_state *)file->private_data, cmd, arg); | ||
1063 | } | ||
1064 | |||
1065 | static /*const*/ struct file_operations es1370_mixer_fops = { | ||
1066 | .owner = THIS_MODULE, | ||
1067 | .llseek = no_llseek, | ||
1068 | .ioctl = es1370_ioctl_mixdev, | ||
1069 | .open = es1370_open_mixdev, | ||
1070 | .release = es1370_release_mixdev, | ||
1071 | }; | ||
1072 | |||
1073 | /* --------------------------------------------------------------------- */ | ||
1074 | |||
1075 | static int drain_dac1(struct es1370_state *s, int nonblock) | ||
1076 | { | ||
1077 | DECLARE_WAITQUEUE(wait, current); | ||
1078 | unsigned long flags; | ||
1079 | int count, tmo; | ||
1080 | |||
1081 | if (s->dma_dac1.mapped || !s->dma_dac1.ready) | ||
1082 | return 0; | ||
1083 | add_wait_queue(&s->dma_dac1.wait, &wait); | ||
1084 | for (;;) { | ||
1085 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1086 | spin_lock_irqsave(&s->lock, flags); | ||
1087 | count = s->dma_dac1.count; | ||
1088 | spin_unlock_irqrestore(&s->lock, flags); | ||
1089 | if (count <= 0) | ||
1090 | break; | ||
1091 | if (signal_pending(current)) | ||
1092 | break; | ||
1093 | if (nonblock) { | ||
1094 | remove_wait_queue(&s->dma_dac1.wait, &wait); | ||
1095 | set_current_state(TASK_RUNNING); | ||
1096 | return -EBUSY; | ||
1097 | } | ||
1098 | tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 | ||
1099 | / dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL]; | ||
1100 | tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; | ||
1101 | if (!schedule_timeout(tmo + 1)) | ||
1102 | DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");) | ||
1103 | } | ||
1104 | remove_wait_queue(&s->dma_dac1.wait, &wait); | ||
1105 | set_current_state(TASK_RUNNING); | ||
1106 | if (signal_pending(current)) | ||
1107 | return -ERESTARTSYS; | ||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
1111 | static int drain_dac2(struct es1370_state *s, int nonblock) | ||
1112 | { | ||
1113 | DECLARE_WAITQUEUE(wait, current); | ||
1114 | unsigned long flags; | ||
1115 | int count, tmo; | ||
1116 | |||
1117 | if (s->dma_dac2.mapped || !s->dma_dac2.ready) | ||
1118 | return 0; | ||
1119 | add_wait_queue(&s->dma_dac2.wait, &wait); | ||
1120 | for (;;) { | ||
1121 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1122 | spin_lock_irqsave(&s->lock, flags); | ||
1123 | count = s->dma_dac2.count; | ||
1124 | spin_unlock_irqrestore(&s->lock, flags); | ||
1125 | if (count <= 0) | ||
1126 | break; | ||
1127 | if (signal_pending(current)) | ||
1128 | break; | ||
1129 | if (nonblock) { | ||
1130 | remove_wait_queue(&s->dma_dac2.wait, &wait); | ||
1131 | set_current_state(TASK_RUNNING); | ||
1132 | return -EBUSY; | ||
1133 | } | ||
1134 | tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 | ||
1135 | / DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV); | ||
1136 | tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; | ||
1137 | if (!schedule_timeout(tmo + 1)) | ||
1138 | DBG(printk(KERN_DEBUG "es1370: dma timed out??\n");) | ||
1139 | } | ||
1140 | remove_wait_queue(&s->dma_dac2.wait, &wait); | ||
1141 | set_current_state(TASK_RUNNING); | ||
1142 | if (signal_pending(current)) | ||
1143 | return -ERESTARTSYS; | ||
1144 | return 0; | ||
1145 | } | ||
1146 | |||
1147 | /* --------------------------------------------------------------------- */ | ||
1148 | |||
1149 | static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1150 | { | ||
1151 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1152 | DECLARE_WAITQUEUE(wait, current); | ||
1153 | ssize_t ret = 0; | ||
1154 | unsigned long flags; | ||
1155 | unsigned swptr; | ||
1156 | int cnt; | ||
1157 | |||
1158 | VALIDATE_STATE(s); | ||
1159 | if (s->dma_adc.mapped) | ||
1160 | return -ENXIO; | ||
1161 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1162 | return -EFAULT; | ||
1163 | mutex_lock(&s->mutex); | ||
1164 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | ||
1165 | goto out; | ||
1166 | |||
1167 | add_wait_queue(&s->dma_adc.wait, &wait); | ||
1168 | while (count > 0) { | ||
1169 | spin_lock_irqsave(&s->lock, flags); | ||
1170 | swptr = s->dma_adc.swptr; | ||
1171 | cnt = s->dma_adc.dmasize-swptr; | ||
1172 | if (s->dma_adc.count < cnt) | ||
1173 | cnt = s->dma_adc.count; | ||
1174 | if (cnt <= 0) | ||
1175 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1176 | spin_unlock_irqrestore(&s->lock, flags); | ||
1177 | if (cnt > count) | ||
1178 | cnt = count; | ||
1179 | if (cnt <= 0) { | ||
1180 | if (s->dma_adc.enabled) | ||
1181 | start_adc(s); | ||
1182 | if (file->f_flags & O_NONBLOCK) { | ||
1183 | if (!ret) | ||
1184 | ret = -EAGAIN; | ||
1185 | goto out; | ||
1186 | } | ||
1187 | mutex_unlock(&s->mutex); | ||
1188 | schedule(); | ||
1189 | if (signal_pending(current)) { | ||
1190 | if (!ret) | ||
1191 | ret = -ERESTARTSYS; | ||
1192 | goto out; | ||
1193 | } | ||
1194 | mutex_lock(&s->mutex); | ||
1195 | if (s->dma_adc.mapped) | ||
1196 | { | ||
1197 | ret = -ENXIO; | ||
1198 | goto out; | ||
1199 | } | ||
1200 | continue; | ||
1201 | } | ||
1202 | if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { | ||
1203 | if (!ret) | ||
1204 | ret = -EFAULT; | ||
1205 | goto out; | ||
1206 | } | ||
1207 | swptr = (swptr + cnt) % s->dma_adc.dmasize; | ||
1208 | spin_lock_irqsave(&s->lock, flags); | ||
1209 | s->dma_adc.swptr = swptr; | ||
1210 | s->dma_adc.count -= cnt; | ||
1211 | spin_unlock_irqrestore(&s->lock, flags); | ||
1212 | count -= cnt; | ||
1213 | buffer += cnt; | ||
1214 | ret += cnt; | ||
1215 | if (s->dma_adc.enabled) | ||
1216 | start_adc(s); | ||
1217 | } | ||
1218 | out: | ||
1219 | mutex_unlock(&s->mutex); | ||
1220 | remove_wait_queue(&s->dma_adc.wait, &wait); | ||
1221 | set_current_state(TASK_RUNNING); | ||
1222 | return ret; | ||
1223 | } | ||
1224 | |||
1225 | static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1226 | { | ||
1227 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1228 | DECLARE_WAITQUEUE(wait, current); | ||
1229 | ssize_t ret = 0; | ||
1230 | unsigned long flags; | ||
1231 | unsigned swptr; | ||
1232 | int cnt; | ||
1233 | |||
1234 | VALIDATE_STATE(s); | ||
1235 | if (s->dma_dac2.mapped) | ||
1236 | return -ENXIO; | ||
1237 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1238 | return -EFAULT; | ||
1239 | mutex_lock(&s->mutex); | ||
1240 | if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) | ||
1241 | goto out; | ||
1242 | ret = 0; | ||
1243 | add_wait_queue(&s->dma_dac2.wait, &wait); | ||
1244 | while (count > 0) { | ||
1245 | spin_lock_irqsave(&s->lock, flags); | ||
1246 | if (s->dma_dac2.count < 0) { | ||
1247 | s->dma_dac2.count = 0; | ||
1248 | s->dma_dac2.swptr = s->dma_dac2.hwptr; | ||
1249 | } | ||
1250 | swptr = s->dma_dac2.swptr; | ||
1251 | cnt = s->dma_dac2.dmasize-swptr; | ||
1252 | if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize) | ||
1253 | cnt = s->dma_dac2.dmasize - s->dma_dac2.count; | ||
1254 | if (cnt <= 0) | ||
1255 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1256 | spin_unlock_irqrestore(&s->lock, flags); | ||
1257 | if (cnt > count) | ||
1258 | cnt = count; | ||
1259 | if (cnt <= 0) { | ||
1260 | if (s->dma_dac2.enabled) | ||
1261 | start_dac2(s); | ||
1262 | if (file->f_flags & O_NONBLOCK) { | ||
1263 | if (!ret) | ||
1264 | ret = -EAGAIN; | ||
1265 | goto out; | ||
1266 | } | ||
1267 | mutex_unlock(&s->mutex); | ||
1268 | schedule(); | ||
1269 | if (signal_pending(current)) { | ||
1270 | if (!ret) | ||
1271 | ret = -ERESTARTSYS; | ||
1272 | goto out; | ||
1273 | } | ||
1274 | mutex_lock(&s->mutex); | ||
1275 | if (s->dma_dac2.mapped) | ||
1276 | { | ||
1277 | ret = -ENXIO; | ||
1278 | goto out; | ||
1279 | } | ||
1280 | continue; | ||
1281 | } | ||
1282 | if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) { | ||
1283 | if (!ret) | ||
1284 | ret = -EFAULT; | ||
1285 | goto out; | ||
1286 | } | ||
1287 | swptr = (swptr + cnt) % s->dma_dac2.dmasize; | ||
1288 | spin_lock_irqsave(&s->lock, flags); | ||
1289 | s->dma_dac2.swptr = swptr; | ||
1290 | s->dma_dac2.count += cnt; | ||
1291 | s->dma_dac2.endcleared = 0; | ||
1292 | spin_unlock_irqrestore(&s->lock, flags); | ||
1293 | count -= cnt; | ||
1294 | buffer += cnt; | ||
1295 | ret += cnt; | ||
1296 | if (s->dma_dac2.enabled) | ||
1297 | start_dac2(s); | ||
1298 | } | ||
1299 | out: | ||
1300 | mutex_unlock(&s->mutex); | ||
1301 | remove_wait_queue(&s->dma_dac2.wait, &wait); | ||
1302 | set_current_state(TASK_RUNNING); | ||
1303 | return ret; | ||
1304 | } | ||
1305 | |||
1306 | /* No kernel lock - we have our own spinlock */ | ||
1307 | static unsigned int es1370_poll(struct file *file, struct poll_table_struct *wait) | ||
1308 | { | ||
1309 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1310 | unsigned long flags; | ||
1311 | unsigned int mask = 0; | ||
1312 | |||
1313 | VALIDATE_STATE(s); | ||
1314 | if (file->f_mode & FMODE_WRITE) { | ||
1315 | if (!s->dma_dac2.ready && prog_dmabuf_dac2(s)) | ||
1316 | return 0; | ||
1317 | poll_wait(file, &s->dma_dac2.wait, wait); | ||
1318 | } | ||
1319 | if (file->f_mode & FMODE_READ) { | ||
1320 | if (!s->dma_adc.ready && prog_dmabuf_adc(s)) | ||
1321 | return 0; | ||
1322 | poll_wait(file, &s->dma_adc.wait, wait); | ||
1323 | } | ||
1324 | spin_lock_irqsave(&s->lock, flags); | ||
1325 | es1370_update_ptr(s); | ||
1326 | if (file->f_mode & FMODE_READ) { | ||
1327 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
1328 | mask |= POLLIN | POLLRDNORM; | ||
1329 | } | ||
1330 | if (file->f_mode & FMODE_WRITE) { | ||
1331 | if (s->dma_dac2.mapped) { | ||
1332 | if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) | ||
1333 | mask |= POLLOUT | POLLWRNORM; | ||
1334 | } else { | ||
1335 | if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize) | ||
1336 | mask |= POLLOUT | POLLWRNORM; | ||
1337 | } | ||
1338 | } | ||
1339 | spin_unlock_irqrestore(&s->lock, flags); | ||
1340 | return mask; | ||
1341 | } | ||
1342 | |||
1343 | static int es1370_mmap(struct file *file, struct vm_area_struct *vma) | ||
1344 | { | ||
1345 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1346 | struct dmabuf *db; | ||
1347 | int ret = 0; | ||
1348 | unsigned long size; | ||
1349 | |||
1350 | VALIDATE_STATE(s); | ||
1351 | lock_kernel(); | ||
1352 | mutex_lock(&s->mutex); | ||
1353 | if (vma->vm_flags & VM_WRITE) { | ||
1354 | if ((ret = prog_dmabuf_dac2(s)) != 0) { | ||
1355 | goto out; | ||
1356 | } | ||
1357 | db = &s->dma_dac2; | ||
1358 | } else if (vma->vm_flags & VM_READ) { | ||
1359 | if ((ret = prog_dmabuf_adc(s)) != 0) { | ||
1360 | goto out; | ||
1361 | } | ||
1362 | db = &s->dma_adc; | ||
1363 | } else { | ||
1364 | ret = -EINVAL; | ||
1365 | goto out; | ||
1366 | } | ||
1367 | if (vma->vm_pgoff != 0) { | ||
1368 | ret = -EINVAL; | ||
1369 | goto out; | ||
1370 | } | ||
1371 | size = vma->vm_end - vma->vm_start; | ||
1372 | if (size > (PAGE_SIZE << db->buforder)) { | ||
1373 | ret = -EINVAL; | ||
1374 | goto out; | ||
1375 | } | ||
1376 | if (remap_pfn_range(vma, vma->vm_start, | ||
1377 | virt_to_phys(db->rawbuf) >> PAGE_SHIFT, | ||
1378 | size, vma->vm_page_prot)) { | ||
1379 | ret = -EAGAIN; | ||
1380 | goto out; | ||
1381 | } | ||
1382 | db->mapped = 1; | ||
1383 | out: | ||
1384 | mutex_unlock(&s->mutex); | ||
1385 | unlock_kernel(); | ||
1386 | return ret; | ||
1387 | } | ||
1388 | |||
1389 | static int es1370_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1390 | { | ||
1391 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1392 | unsigned long flags; | ||
1393 | audio_buf_info abinfo; | ||
1394 | count_info cinfo; | ||
1395 | int count; | ||
1396 | int val, mapped, ret; | ||
1397 | void __user *argp = (void __user *)arg; | ||
1398 | int __user *p = argp; | ||
1399 | |||
1400 | VALIDATE_STATE(s); | ||
1401 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) || | ||
1402 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
1403 | switch (cmd) { | ||
1404 | case OSS_GETVERSION: | ||
1405 | return put_user(SOUND_VERSION, p); | ||
1406 | |||
1407 | case SNDCTL_DSP_SYNC: | ||
1408 | if (file->f_mode & FMODE_WRITE) | ||
1409 | return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/); | ||
1410 | return 0; | ||
1411 | |||
1412 | case SNDCTL_DSP_SETDUPLEX: | ||
1413 | return 0; | ||
1414 | |||
1415 | case SNDCTL_DSP_GETCAPS: | ||
1416 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); | ||
1417 | |||
1418 | case SNDCTL_DSP_RESET: | ||
1419 | if (file->f_mode & FMODE_WRITE) { | ||
1420 | stop_dac2(s); | ||
1421 | synchronize_irq(s->irq); | ||
1422 | s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0; | ||
1423 | } | ||
1424 | if (file->f_mode & FMODE_READ) { | ||
1425 | stop_adc(s); | ||
1426 | synchronize_irq(s->irq); | ||
1427 | s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
1428 | } | ||
1429 | return 0; | ||
1430 | |||
1431 | case SNDCTL_DSP_SPEED: | ||
1432 | if (get_user(val, p)) | ||
1433 | return -EFAULT; | ||
1434 | if (val >= 0) { | ||
1435 | if (s->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE)) | ||
1436 | return -EINVAL; | ||
1437 | if (val < 4000) | ||
1438 | val = 4000; | ||
1439 | if (val > 50000) | ||
1440 | val = 50000; | ||
1441 | stop_adc(s); | ||
1442 | stop_dac2(s); | ||
1443 | s->dma_adc.ready = s->dma_dac2.ready = 0; | ||
1444 | spin_lock_irqsave(&s->lock, flags); | ||
1445 | s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(val) << CTRL_SH_PCLKDIV); | ||
1446 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
1447 | spin_unlock_irqrestore(&s->lock, flags); | ||
1448 | } | ||
1449 | return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p); | ||
1450 | |||
1451 | case SNDCTL_DSP_STEREO: | ||
1452 | if (get_user(val, p)) | ||
1453 | return -EFAULT; | ||
1454 | if (file->f_mode & FMODE_READ) { | ||
1455 | stop_adc(s); | ||
1456 | s->dma_adc.ready = 0; | ||
1457 | spin_lock_irqsave(&s->lock, flags); | ||
1458 | if (val) | ||
1459 | s->sctrl |= SCTRL_R1SMB; | ||
1460 | else | ||
1461 | s->sctrl &= ~SCTRL_R1SMB; | ||
1462 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
1463 | spin_unlock_irqrestore(&s->lock, flags); | ||
1464 | } | ||
1465 | if (file->f_mode & FMODE_WRITE) { | ||
1466 | stop_dac2(s); | ||
1467 | s->dma_dac2.ready = 0; | ||
1468 | spin_lock_irqsave(&s->lock, flags); | ||
1469 | if (val) | ||
1470 | s->sctrl |= SCTRL_P2SMB; | ||
1471 | else | ||
1472 | s->sctrl &= ~SCTRL_P2SMB; | ||
1473 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
1474 | spin_unlock_irqrestore(&s->lock, flags); | ||
1475 | } | ||
1476 | return 0; | ||
1477 | |||
1478 | case SNDCTL_DSP_CHANNELS: | ||
1479 | if (get_user(val, p)) | ||
1480 | return -EFAULT; | ||
1481 | if (val != 0) { | ||
1482 | if (file->f_mode & FMODE_READ) { | ||
1483 | stop_adc(s); | ||
1484 | s->dma_adc.ready = 0; | ||
1485 | spin_lock_irqsave(&s->lock, flags); | ||
1486 | if (val >= 2) | ||
1487 | s->sctrl |= SCTRL_R1SMB; | ||
1488 | else | ||
1489 | s->sctrl &= ~SCTRL_R1SMB; | ||
1490 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
1491 | spin_unlock_irqrestore(&s->lock, flags); | ||
1492 | } | ||
1493 | if (file->f_mode & FMODE_WRITE) { | ||
1494 | stop_dac2(s); | ||
1495 | s->dma_dac2.ready = 0; | ||
1496 | spin_lock_irqsave(&s->lock, flags); | ||
1497 | if (val >= 2) | ||
1498 | s->sctrl |= SCTRL_P2SMB; | ||
1499 | else | ||
1500 | s->sctrl &= ~SCTRL_P2SMB; | ||
1501 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
1502 | spin_unlock_irqrestore(&s->lock, flags); | ||
1503 | } | ||
1504 | } | ||
1505 | return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p); | ||
1506 | |||
1507 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
1508 | return put_user(AFMT_S16_LE|AFMT_U8, p); | ||
1509 | |||
1510 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
1511 | if (get_user(val, p)) | ||
1512 | return -EFAULT; | ||
1513 | if (val != AFMT_QUERY) { | ||
1514 | if (file->f_mode & FMODE_READ) { | ||
1515 | stop_adc(s); | ||
1516 | s->dma_adc.ready = 0; | ||
1517 | spin_lock_irqsave(&s->lock, flags); | ||
1518 | if (val == AFMT_S16_LE) | ||
1519 | s->sctrl |= SCTRL_R1SEB; | ||
1520 | else | ||
1521 | s->sctrl &= ~SCTRL_R1SEB; | ||
1522 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
1523 | spin_unlock_irqrestore(&s->lock, flags); | ||
1524 | } | ||
1525 | if (file->f_mode & FMODE_WRITE) { | ||
1526 | stop_dac2(s); | ||
1527 | s->dma_dac2.ready = 0; | ||
1528 | spin_lock_irqsave(&s->lock, flags); | ||
1529 | if (val == AFMT_S16_LE) | ||
1530 | s->sctrl |= SCTRL_P2SEB; | ||
1531 | else | ||
1532 | s->sctrl &= ~SCTRL_P2SEB; | ||
1533 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
1534 | spin_unlock_irqrestore(&s->lock, flags); | ||
1535 | } | ||
1536 | } | ||
1537 | return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? | ||
1538 | AFMT_S16_LE : AFMT_U8, p); | ||
1539 | |||
1540 | case SNDCTL_DSP_POST: | ||
1541 | return 0; | ||
1542 | |||
1543 | case SNDCTL_DSP_GETTRIGGER: | ||
1544 | val = 0; | ||
1545 | if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) | ||
1546 | val |= PCM_ENABLE_INPUT; | ||
1547 | if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) | ||
1548 | val |= PCM_ENABLE_OUTPUT; | ||
1549 | return put_user(val, p); | ||
1550 | |||
1551 | case SNDCTL_DSP_SETTRIGGER: | ||
1552 | if (get_user(val, p)) | ||
1553 | return -EFAULT; | ||
1554 | if (file->f_mode & FMODE_READ) { | ||
1555 | if (val & PCM_ENABLE_INPUT) { | ||
1556 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | ||
1557 | return ret; | ||
1558 | s->dma_adc.enabled = 1; | ||
1559 | start_adc(s); | ||
1560 | } else { | ||
1561 | s->dma_adc.enabled = 0; | ||
1562 | stop_adc(s); | ||
1563 | } | ||
1564 | } | ||
1565 | if (file->f_mode & FMODE_WRITE) { | ||
1566 | if (val & PCM_ENABLE_OUTPUT) { | ||
1567 | if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) | ||
1568 | return ret; | ||
1569 | s->dma_dac2.enabled = 1; | ||
1570 | start_dac2(s); | ||
1571 | } else { | ||
1572 | s->dma_dac2.enabled = 0; | ||
1573 | stop_dac2(s); | ||
1574 | } | ||
1575 | } | ||
1576 | return 0; | ||
1577 | |||
1578 | case SNDCTL_DSP_GETOSPACE: | ||
1579 | if (!(file->f_mode & FMODE_WRITE)) | ||
1580 | return -EINVAL; | ||
1581 | if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0) | ||
1582 | return val; | ||
1583 | spin_lock_irqsave(&s->lock, flags); | ||
1584 | es1370_update_ptr(s); | ||
1585 | abinfo.fragsize = s->dma_dac2.fragsize; | ||
1586 | count = s->dma_dac2.count; | ||
1587 | if (count < 0) | ||
1588 | count = 0; | ||
1589 | abinfo.bytes = s->dma_dac2.dmasize - count; | ||
1590 | abinfo.fragstotal = s->dma_dac2.numfrag; | ||
1591 | abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift; | ||
1592 | spin_unlock_irqrestore(&s->lock, flags); | ||
1593 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1594 | |||
1595 | case SNDCTL_DSP_GETISPACE: | ||
1596 | if (!(file->f_mode & FMODE_READ)) | ||
1597 | return -EINVAL; | ||
1598 | if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0) | ||
1599 | return val; | ||
1600 | spin_lock_irqsave(&s->lock, flags); | ||
1601 | es1370_update_ptr(s); | ||
1602 | abinfo.fragsize = s->dma_adc.fragsize; | ||
1603 | count = s->dma_adc.count; | ||
1604 | if (count < 0) | ||
1605 | count = 0; | ||
1606 | abinfo.bytes = count; | ||
1607 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
1608 | abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; | ||
1609 | spin_unlock_irqrestore(&s->lock, flags); | ||
1610 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1611 | |||
1612 | case SNDCTL_DSP_NONBLOCK: | ||
1613 | file->f_flags |= O_NONBLOCK; | ||
1614 | return 0; | ||
1615 | |||
1616 | case SNDCTL_DSP_GETODELAY: | ||
1617 | if (!(file->f_mode & FMODE_WRITE)) | ||
1618 | return -EINVAL; | ||
1619 | if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0) | ||
1620 | return val; | ||
1621 | spin_lock_irqsave(&s->lock, flags); | ||
1622 | es1370_update_ptr(s); | ||
1623 | count = s->dma_dac2.count; | ||
1624 | spin_unlock_irqrestore(&s->lock, flags); | ||
1625 | if (count < 0) | ||
1626 | count = 0; | ||
1627 | return put_user(count, p); | ||
1628 | |||
1629 | case SNDCTL_DSP_GETIPTR: | ||
1630 | if (!(file->f_mode & FMODE_READ)) | ||
1631 | return -EINVAL; | ||
1632 | if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0) | ||
1633 | return val; | ||
1634 | spin_lock_irqsave(&s->lock, flags); | ||
1635 | es1370_update_ptr(s); | ||
1636 | cinfo.bytes = s->dma_adc.total_bytes; | ||
1637 | count = s->dma_adc.count; | ||
1638 | if (count < 0) | ||
1639 | count = 0; | ||
1640 | cinfo.blocks = count >> s->dma_adc.fragshift; | ||
1641 | cinfo.ptr = s->dma_adc.hwptr; | ||
1642 | if (s->dma_adc.mapped) | ||
1643 | s->dma_adc.count &= s->dma_adc.fragsize-1; | ||
1644 | spin_unlock_irqrestore(&s->lock, flags); | ||
1645 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1646 | return -EFAULT; | ||
1647 | return 0; | ||
1648 | |||
1649 | case SNDCTL_DSP_GETOPTR: | ||
1650 | if (!(file->f_mode & FMODE_WRITE)) | ||
1651 | return -EINVAL; | ||
1652 | if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0) | ||
1653 | return val; | ||
1654 | spin_lock_irqsave(&s->lock, flags); | ||
1655 | es1370_update_ptr(s); | ||
1656 | cinfo.bytes = s->dma_dac2.total_bytes; | ||
1657 | count = s->dma_dac2.count; | ||
1658 | if (count < 0) | ||
1659 | count = 0; | ||
1660 | cinfo.blocks = count >> s->dma_dac2.fragshift; | ||
1661 | cinfo.ptr = s->dma_dac2.hwptr; | ||
1662 | if (s->dma_dac2.mapped) | ||
1663 | s->dma_dac2.count &= s->dma_dac2.fragsize-1; | ||
1664 | spin_unlock_irqrestore(&s->lock, flags); | ||
1665 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1666 | return -EFAULT; | ||
1667 | return 0; | ||
1668 | |||
1669 | case SNDCTL_DSP_GETBLKSIZE: | ||
1670 | if (file->f_mode & FMODE_WRITE) { | ||
1671 | if ((val = prog_dmabuf_dac2(s))) | ||
1672 | return val; | ||
1673 | return put_user(s->dma_dac2.fragsize, p); | ||
1674 | } | ||
1675 | if ((val = prog_dmabuf_adc(s))) | ||
1676 | return val; | ||
1677 | return put_user(s->dma_adc.fragsize, p); | ||
1678 | |||
1679 | case SNDCTL_DSP_SETFRAGMENT: | ||
1680 | if (get_user(val, p)) | ||
1681 | return -EFAULT; | ||
1682 | if (file->f_mode & FMODE_READ) { | ||
1683 | s->dma_adc.ossfragshift = val & 0xffff; | ||
1684 | s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; | ||
1685 | if (s->dma_adc.ossfragshift < 4) | ||
1686 | s->dma_adc.ossfragshift = 4; | ||
1687 | if (s->dma_adc.ossfragshift > 15) | ||
1688 | s->dma_adc.ossfragshift = 15; | ||
1689 | if (s->dma_adc.ossmaxfrags < 4) | ||
1690 | s->dma_adc.ossmaxfrags = 4; | ||
1691 | } | ||
1692 | if (file->f_mode & FMODE_WRITE) { | ||
1693 | s->dma_dac2.ossfragshift = val & 0xffff; | ||
1694 | s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff; | ||
1695 | if (s->dma_dac2.ossfragshift < 4) | ||
1696 | s->dma_dac2.ossfragshift = 4; | ||
1697 | if (s->dma_dac2.ossfragshift > 15) | ||
1698 | s->dma_dac2.ossfragshift = 15; | ||
1699 | if (s->dma_dac2.ossmaxfrags < 4) | ||
1700 | s->dma_dac2.ossmaxfrags = 4; | ||
1701 | } | ||
1702 | return 0; | ||
1703 | |||
1704 | case SNDCTL_DSP_SUBDIVIDE: | ||
1705 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
1706 | (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision)) | ||
1707 | return -EINVAL; | ||
1708 | if (get_user(val, p)) | ||
1709 | return -EFAULT; | ||
1710 | if (val != 1 && val != 2 && val != 4) | ||
1711 | return -EINVAL; | ||
1712 | if (file->f_mode & FMODE_READ) | ||
1713 | s->dma_adc.subdivision = val; | ||
1714 | if (file->f_mode & FMODE_WRITE) | ||
1715 | s->dma_dac2.subdivision = val; | ||
1716 | return 0; | ||
1717 | |||
1718 | case SOUND_PCM_READ_RATE: | ||
1719 | return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), p); | ||
1720 | |||
1721 | case SOUND_PCM_READ_CHANNELS: | ||
1722 | return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? | ||
1723 | 2 : 1, p); | ||
1724 | |||
1725 | case SOUND_PCM_READ_BITS: | ||
1726 | return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? | ||
1727 | 16 : 8, p); | ||
1728 | |||
1729 | case SOUND_PCM_WRITE_FILTER: | ||
1730 | case SNDCTL_DSP_SETSYNCRO: | ||
1731 | case SOUND_PCM_READ_FILTER: | ||
1732 | return -EINVAL; | ||
1733 | |||
1734 | } | ||
1735 | return mixer_ioctl(s, cmd, arg); | ||
1736 | } | ||
1737 | |||
1738 | static int es1370_open(struct inode *inode, struct file *file) | ||
1739 | { | ||
1740 | unsigned int minor = iminor(inode); | ||
1741 | DECLARE_WAITQUEUE(wait, current); | ||
1742 | unsigned long flags; | ||
1743 | struct list_head *list; | ||
1744 | struct es1370_state *s; | ||
1745 | |||
1746 | for (list = devs.next; ; list = list->next) { | ||
1747 | if (list == &devs) | ||
1748 | return -ENODEV; | ||
1749 | s = list_entry(list, struct es1370_state, devs); | ||
1750 | if (!((s->dev_audio ^ minor) & ~0xf)) | ||
1751 | break; | ||
1752 | } | ||
1753 | VALIDATE_STATE(s); | ||
1754 | file->private_data = s; | ||
1755 | /* wait for device to become free */ | ||
1756 | mutex_lock(&s->open_mutex); | ||
1757 | while (s->open_mode & file->f_mode) { | ||
1758 | if (file->f_flags & O_NONBLOCK) { | ||
1759 | mutex_unlock(&s->open_mutex); | ||
1760 | return -EBUSY; | ||
1761 | } | ||
1762 | add_wait_queue(&s->open_wait, &wait); | ||
1763 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1764 | mutex_unlock(&s->open_mutex); | ||
1765 | schedule(); | ||
1766 | remove_wait_queue(&s->open_wait, &wait); | ||
1767 | set_current_state(TASK_RUNNING); | ||
1768 | if (signal_pending(current)) | ||
1769 | return -ERESTARTSYS; | ||
1770 | mutex_lock(&s->open_mutex); | ||
1771 | } | ||
1772 | spin_lock_irqsave(&s->lock, flags); | ||
1773 | if (!(s->open_mode & (FMODE_READ|FMODE_WRITE))) | ||
1774 | s->ctrl = (s->ctrl & ~CTRL_PCLKDIV) | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV); | ||
1775 | if (file->f_mode & FMODE_READ) { | ||
1776 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; | ||
1777 | s->dma_adc.enabled = 1; | ||
1778 | s->sctrl &= ~SCTRL_R1FMT; | ||
1779 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1780 | s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_R1FMT; | ||
1781 | else | ||
1782 | s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_R1FMT; | ||
1783 | } | ||
1784 | if (file->f_mode & FMODE_WRITE) { | ||
1785 | s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0; | ||
1786 | s->dma_dac2.enabled = 1; | ||
1787 | s->sctrl &= ~SCTRL_P2FMT; | ||
1788 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1789 | s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_P2FMT; | ||
1790 | else | ||
1791 | s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_P2FMT; | ||
1792 | } | ||
1793 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
1794 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
1795 | spin_unlock_irqrestore(&s->lock, flags); | ||
1796 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
1797 | mutex_unlock(&s->open_mutex); | ||
1798 | mutex_init(&s->mutex); | ||
1799 | return nonseekable_open(inode, file); | ||
1800 | } | ||
1801 | |||
1802 | static int es1370_release(struct inode *inode, struct file *file) | ||
1803 | { | ||
1804 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1805 | |||
1806 | VALIDATE_STATE(s); | ||
1807 | lock_kernel(); | ||
1808 | if (file->f_mode & FMODE_WRITE) | ||
1809 | drain_dac2(s, file->f_flags & O_NONBLOCK); | ||
1810 | mutex_lock(&s->open_mutex); | ||
1811 | if (file->f_mode & FMODE_WRITE) { | ||
1812 | stop_dac2(s); | ||
1813 | synchronize_irq(s->irq); | ||
1814 | dealloc_dmabuf(s, &s->dma_dac2); | ||
1815 | } | ||
1816 | if (file->f_mode & FMODE_READ) { | ||
1817 | stop_adc(s); | ||
1818 | dealloc_dmabuf(s, &s->dma_adc); | ||
1819 | } | ||
1820 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); | ||
1821 | wake_up(&s->open_wait); | ||
1822 | mutex_unlock(&s->open_mutex); | ||
1823 | unlock_kernel(); | ||
1824 | return 0; | ||
1825 | } | ||
1826 | |||
1827 | static /*const*/ struct file_operations es1370_audio_fops = { | ||
1828 | .owner = THIS_MODULE, | ||
1829 | .llseek = no_llseek, | ||
1830 | .read = es1370_read, | ||
1831 | .write = es1370_write, | ||
1832 | .poll = es1370_poll, | ||
1833 | .ioctl = es1370_ioctl, | ||
1834 | .mmap = es1370_mmap, | ||
1835 | .open = es1370_open, | ||
1836 | .release = es1370_release, | ||
1837 | }; | ||
1838 | |||
1839 | /* --------------------------------------------------------------------- */ | ||
1840 | |||
1841 | static ssize_t es1370_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1842 | { | ||
1843 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1844 | DECLARE_WAITQUEUE(wait, current); | ||
1845 | ssize_t ret = 0; | ||
1846 | unsigned long flags; | ||
1847 | unsigned swptr; | ||
1848 | int cnt; | ||
1849 | |||
1850 | VALIDATE_STATE(s); | ||
1851 | if (s->dma_dac1.mapped) | ||
1852 | return -ENXIO; | ||
1853 | if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s))) | ||
1854 | return ret; | ||
1855 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1856 | return -EFAULT; | ||
1857 | add_wait_queue(&s->dma_dac1.wait, &wait); | ||
1858 | while (count > 0) { | ||
1859 | spin_lock_irqsave(&s->lock, flags); | ||
1860 | if (s->dma_dac1.count < 0) { | ||
1861 | s->dma_dac1.count = 0; | ||
1862 | s->dma_dac1.swptr = s->dma_dac1.hwptr; | ||
1863 | } | ||
1864 | swptr = s->dma_dac1.swptr; | ||
1865 | cnt = s->dma_dac1.dmasize-swptr; | ||
1866 | if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize) | ||
1867 | cnt = s->dma_dac1.dmasize - s->dma_dac1.count; | ||
1868 | if (cnt <= 0) | ||
1869 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1870 | spin_unlock_irqrestore(&s->lock, flags); | ||
1871 | if (cnt > count) | ||
1872 | cnt = count; | ||
1873 | if (cnt <= 0) { | ||
1874 | if (s->dma_dac1.enabled) | ||
1875 | start_dac1(s); | ||
1876 | if (file->f_flags & O_NONBLOCK) { | ||
1877 | if (!ret) | ||
1878 | ret = -EAGAIN; | ||
1879 | break; | ||
1880 | } | ||
1881 | schedule(); | ||
1882 | if (signal_pending(current)) { | ||
1883 | if (!ret) | ||
1884 | ret = -ERESTARTSYS; | ||
1885 | break; | ||
1886 | } | ||
1887 | continue; | ||
1888 | } | ||
1889 | if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) { | ||
1890 | if (!ret) | ||
1891 | ret = -EFAULT; | ||
1892 | break; | ||
1893 | } | ||
1894 | swptr = (swptr + cnt) % s->dma_dac1.dmasize; | ||
1895 | spin_lock_irqsave(&s->lock, flags); | ||
1896 | s->dma_dac1.swptr = swptr; | ||
1897 | s->dma_dac1.count += cnt; | ||
1898 | s->dma_dac1.endcleared = 0; | ||
1899 | spin_unlock_irqrestore(&s->lock, flags); | ||
1900 | count -= cnt; | ||
1901 | buffer += cnt; | ||
1902 | ret += cnt; | ||
1903 | if (s->dma_dac1.enabled) | ||
1904 | start_dac1(s); | ||
1905 | } | ||
1906 | remove_wait_queue(&s->dma_dac1.wait, &wait); | ||
1907 | set_current_state(TASK_RUNNING); | ||
1908 | return ret; | ||
1909 | } | ||
1910 | |||
1911 | /* No kernel lock - we have our own spinlock */ | ||
1912 | static unsigned int es1370_poll_dac(struct file *file, struct poll_table_struct *wait) | ||
1913 | { | ||
1914 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1915 | unsigned long flags; | ||
1916 | unsigned int mask = 0; | ||
1917 | |||
1918 | VALIDATE_STATE(s); | ||
1919 | if (!s->dma_dac1.ready && prog_dmabuf_dac1(s)) | ||
1920 | return 0; | ||
1921 | poll_wait(file, &s->dma_dac1.wait, wait); | ||
1922 | spin_lock_irqsave(&s->lock, flags); | ||
1923 | es1370_update_ptr(s); | ||
1924 | if (s->dma_dac1.mapped) { | ||
1925 | if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize) | ||
1926 | mask |= POLLOUT | POLLWRNORM; | ||
1927 | } else { | ||
1928 | if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize) | ||
1929 | mask |= POLLOUT | POLLWRNORM; | ||
1930 | } | ||
1931 | spin_unlock_irqrestore(&s->lock, flags); | ||
1932 | return mask; | ||
1933 | } | ||
1934 | |||
1935 | static int es1370_mmap_dac(struct file *file, struct vm_area_struct *vma) | ||
1936 | { | ||
1937 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1938 | int ret; | ||
1939 | unsigned long size; | ||
1940 | |||
1941 | VALIDATE_STATE(s); | ||
1942 | if (!(vma->vm_flags & VM_WRITE)) | ||
1943 | return -EINVAL; | ||
1944 | lock_kernel(); | ||
1945 | if ((ret = prog_dmabuf_dac1(s)) != 0) | ||
1946 | goto out; | ||
1947 | ret = -EINVAL; | ||
1948 | if (vma->vm_pgoff != 0) | ||
1949 | goto out; | ||
1950 | size = vma->vm_end - vma->vm_start; | ||
1951 | if (size > (PAGE_SIZE << s->dma_dac1.buforder)) | ||
1952 | goto out; | ||
1953 | ret = -EAGAIN; | ||
1954 | if (remap_pfn_range(vma, vma->vm_start, | ||
1955 | virt_to_phys(s->dma_dac1.rawbuf) >> PAGE_SHIFT, | ||
1956 | size, vma->vm_page_prot)) | ||
1957 | goto out; | ||
1958 | s->dma_dac1.mapped = 1; | ||
1959 | ret = 0; | ||
1960 | out: | ||
1961 | unlock_kernel(); | ||
1962 | return ret; | ||
1963 | } | ||
1964 | |||
1965 | static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1966 | { | ||
1967 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
1968 | unsigned long flags; | ||
1969 | audio_buf_info abinfo; | ||
1970 | count_info cinfo; | ||
1971 | int count; | ||
1972 | unsigned ctrl; | ||
1973 | int val, ret; | ||
1974 | int __user *p = (int __user *)arg; | ||
1975 | |||
1976 | VALIDATE_STATE(s); | ||
1977 | switch (cmd) { | ||
1978 | case OSS_GETVERSION: | ||
1979 | return put_user(SOUND_VERSION, p); | ||
1980 | |||
1981 | case SNDCTL_DSP_SYNC: | ||
1982 | return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/); | ||
1983 | |||
1984 | case SNDCTL_DSP_SETDUPLEX: | ||
1985 | return -EINVAL; | ||
1986 | |||
1987 | case SNDCTL_DSP_GETCAPS: | ||
1988 | return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); | ||
1989 | |||
1990 | case SNDCTL_DSP_RESET: | ||
1991 | stop_dac1(s); | ||
1992 | synchronize_irq(s->irq); | ||
1993 | s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0; | ||
1994 | return 0; | ||
1995 | |||
1996 | case SNDCTL_DSP_SPEED: | ||
1997 | if (get_user(val, p)) | ||
1998 | return -EFAULT; | ||
1999 | if (val >= 0) { | ||
2000 | stop_dac1(s); | ||
2001 | s->dma_dac1.ready = 0; | ||
2002 | for (ctrl = 0; ctrl <= 2; ctrl++) | ||
2003 | if (val < (dac1_samplerate[ctrl] + dac1_samplerate[ctrl+1]) / 2) | ||
2004 | break; | ||
2005 | spin_lock_irqsave(&s->lock, flags); | ||
2006 | s->ctrl = (s->ctrl & ~CTRL_WTSRSEL) | (ctrl << CTRL_SH_WTSRSEL); | ||
2007 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
2008 | spin_unlock_irqrestore(&s->lock, flags); | ||
2009 | } | ||
2010 | return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p); | ||
2011 | |||
2012 | case SNDCTL_DSP_STEREO: | ||
2013 | if (get_user(val, p)) | ||
2014 | return -EFAULT; | ||
2015 | stop_dac1(s); | ||
2016 | s->dma_dac1.ready = 0; | ||
2017 | spin_lock_irqsave(&s->lock, flags); | ||
2018 | if (val) | ||
2019 | s->sctrl |= SCTRL_P1SMB; | ||
2020 | else | ||
2021 | s->sctrl &= ~SCTRL_P1SMB; | ||
2022 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
2023 | spin_unlock_irqrestore(&s->lock, flags); | ||
2024 | return 0; | ||
2025 | |||
2026 | case SNDCTL_DSP_CHANNELS: | ||
2027 | if (get_user(val, p)) | ||
2028 | return -EFAULT; | ||
2029 | if (val != 0) { | ||
2030 | if (s->dma_dac1.mapped) | ||
2031 | return -EINVAL; | ||
2032 | stop_dac1(s); | ||
2033 | s->dma_dac1.ready = 0; | ||
2034 | spin_lock_irqsave(&s->lock, flags); | ||
2035 | if (val >= 2) | ||
2036 | s->sctrl |= SCTRL_P1SMB; | ||
2037 | else | ||
2038 | s->sctrl &= ~SCTRL_P1SMB; | ||
2039 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
2040 | spin_unlock_irqrestore(&s->lock, flags); | ||
2041 | } | ||
2042 | return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p); | ||
2043 | |||
2044 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
2045 | return put_user(AFMT_S16_LE|AFMT_U8, p); | ||
2046 | |||
2047 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
2048 | if (get_user(val, p)) | ||
2049 | return -EFAULT; | ||
2050 | if (val != AFMT_QUERY) { | ||
2051 | stop_dac1(s); | ||
2052 | s->dma_dac1.ready = 0; | ||
2053 | spin_lock_irqsave(&s->lock, flags); | ||
2054 | if (val == AFMT_S16_LE) | ||
2055 | s->sctrl |= SCTRL_P1SEB; | ||
2056 | else | ||
2057 | s->sctrl &= ~SCTRL_P1SEB; | ||
2058 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
2059 | spin_unlock_irqrestore(&s->lock, flags); | ||
2060 | } | ||
2061 | return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p); | ||
2062 | |||
2063 | case SNDCTL_DSP_POST: | ||
2064 | return 0; | ||
2065 | |||
2066 | case SNDCTL_DSP_GETTRIGGER: | ||
2067 | return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p); | ||
2068 | |||
2069 | case SNDCTL_DSP_SETTRIGGER: | ||
2070 | if (get_user(val, p)) | ||
2071 | return -EFAULT; | ||
2072 | if (val & PCM_ENABLE_OUTPUT) { | ||
2073 | if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s))) | ||
2074 | return ret; | ||
2075 | s->dma_dac1.enabled = 1; | ||
2076 | start_dac1(s); | ||
2077 | } else { | ||
2078 | s->dma_dac1.enabled = 0; | ||
2079 | stop_dac1(s); | ||
2080 | } | ||
2081 | return 0; | ||
2082 | |||
2083 | case SNDCTL_DSP_GETOSPACE: | ||
2084 | if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0) | ||
2085 | return val; | ||
2086 | spin_lock_irqsave(&s->lock, flags); | ||
2087 | es1370_update_ptr(s); | ||
2088 | abinfo.fragsize = s->dma_dac1.fragsize; | ||
2089 | count = s->dma_dac1.count; | ||
2090 | if (count < 0) | ||
2091 | count = 0; | ||
2092 | abinfo.bytes = s->dma_dac1.dmasize - count; | ||
2093 | abinfo.fragstotal = s->dma_dac1.numfrag; | ||
2094 | abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift; | ||
2095 | spin_unlock_irqrestore(&s->lock, flags); | ||
2096 | return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
2097 | |||
2098 | case SNDCTL_DSP_NONBLOCK: | ||
2099 | file->f_flags |= O_NONBLOCK; | ||
2100 | return 0; | ||
2101 | |||
2102 | case SNDCTL_DSP_GETODELAY: | ||
2103 | if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0) | ||
2104 | return val; | ||
2105 | spin_lock_irqsave(&s->lock, flags); | ||
2106 | es1370_update_ptr(s); | ||
2107 | count = s->dma_dac1.count; | ||
2108 | spin_unlock_irqrestore(&s->lock, flags); | ||
2109 | if (count < 0) | ||
2110 | count = 0; | ||
2111 | return put_user(count, p); | ||
2112 | |||
2113 | case SNDCTL_DSP_GETOPTR: | ||
2114 | if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0) | ||
2115 | return val; | ||
2116 | spin_lock_irqsave(&s->lock, flags); | ||
2117 | es1370_update_ptr(s); | ||
2118 | cinfo.bytes = s->dma_dac1.total_bytes; | ||
2119 | count = s->dma_dac1.count; | ||
2120 | if (count < 0) | ||
2121 | count = 0; | ||
2122 | cinfo.blocks = count >> s->dma_dac1.fragshift; | ||
2123 | cinfo.ptr = s->dma_dac1.hwptr; | ||
2124 | if (s->dma_dac1.mapped) | ||
2125 | s->dma_dac1.count &= s->dma_dac1.fragsize-1; | ||
2126 | spin_unlock_irqrestore(&s->lock, flags); | ||
2127 | if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo))) | ||
2128 | return -EFAULT; | ||
2129 | return 0; | ||
2130 | |||
2131 | case SNDCTL_DSP_GETBLKSIZE: | ||
2132 | if ((val = prog_dmabuf_dac1(s))) | ||
2133 | return val; | ||
2134 | return put_user(s->dma_dac1.fragsize, p); | ||
2135 | |||
2136 | case SNDCTL_DSP_SETFRAGMENT: | ||
2137 | if (get_user(val, p)) | ||
2138 | return -EFAULT; | ||
2139 | s->dma_dac1.ossfragshift = val & 0xffff; | ||
2140 | s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff; | ||
2141 | if (s->dma_dac1.ossfragshift < 4) | ||
2142 | s->dma_dac1.ossfragshift = 4; | ||
2143 | if (s->dma_dac1.ossfragshift > 15) | ||
2144 | s->dma_dac1.ossfragshift = 15; | ||
2145 | if (s->dma_dac1.ossmaxfrags < 4) | ||
2146 | s->dma_dac1.ossmaxfrags = 4; | ||
2147 | return 0; | ||
2148 | |||
2149 | case SNDCTL_DSP_SUBDIVIDE: | ||
2150 | if (s->dma_dac1.subdivision) | ||
2151 | return -EINVAL; | ||
2152 | if (get_user(val, p)) | ||
2153 | return -EFAULT; | ||
2154 | if (val != 1 && val != 2 && val != 4) | ||
2155 | return -EINVAL; | ||
2156 | s->dma_dac1.subdivision = val; | ||
2157 | return 0; | ||
2158 | |||
2159 | case SOUND_PCM_READ_RATE: | ||
2160 | return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], p); | ||
2161 | |||
2162 | case SOUND_PCM_READ_CHANNELS: | ||
2163 | return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p); | ||
2164 | |||
2165 | case SOUND_PCM_READ_BITS: | ||
2166 | return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p); | ||
2167 | |||
2168 | case SOUND_PCM_WRITE_FILTER: | ||
2169 | case SNDCTL_DSP_SETSYNCRO: | ||
2170 | case SOUND_PCM_READ_FILTER: | ||
2171 | return -EINVAL; | ||
2172 | |||
2173 | } | ||
2174 | return mixer_ioctl(s, cmd, arg); | ||
2175 | } | ||
2176 | |||
2177 | static int es1370_open_dac(struct inode *inode, struct file *file) | ||
2178 | { | ||
2179 | unsigned int minor = iminor(inode); | ||
2180 | DECLARE_WAITQUEUE(wait, current); | ||
2181 | unsigned long flags; | ||
2182 | struct list_head *list; | ||
2183 | struct es1370_state *s; | ||
2184 | |||
2185 | for (list = devs.next; ; list = list->next) { | ||
2186 | if (list == &devs) | ||
2187 | return -ENODEV; | ||
2188 | s = list_entry(list, struct es1370_state, devs); | ||
2189 | if (!((s->dev_dac ^ minor) & ~0xf)) | ||
2190 | break; | ||
2191 | } | ||
2192 | VALIDATE_STATE(s); | ||
2193 | /* we allow opening with O_RDWR, most programs do it although they will only write */ | ||
2194 | #if 0 | ||
2195 | if (file->f_mode & FMODE_READ) | ||
2196 | return -EPERM; | ||
2197 | #endif | ||
2198 | if (!(file->f_mode & FMODE_WRITE)) | ||
2199 | return -EINVAL; | ||
2200 | file->private_data = s; | ||
2201 | /* wait for device to become free */ | ||
2202 | mutex_lock(&s->open_mutex); | ||
2203 | while (s->open_mode & FMODE_DAC) { | ||
2204 | if (file->f_flags & O_NONBLOCK) { | ||
2205 | mutex_unlock(&s->open_mutex); | ||
2206 | return -EBUSY; | ||
2207 | } | ||
2208 | add_wait_queue(&s->open_wait, &wait); | ||
2209 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2210 | mutex_unlock(&s->open_mutex); | ||
2211 | schedule(); | ||
2212 | remove_wait_queue(&s->open_wait, &wait); | ||
2213 | set_current_state(TASK_RUNNING); | ||
2214 | if (signal_pending(current)) | ||
2215 | return -ERESTARTSYS; | ||
2216 | mutex_lock(&s->open_mutex); | ||
2217 | } | ||
2218 | s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0; | ||
2219 | s->dma_dac1.enabled = 1; | ||
2220 | spin_lock_irqsave(&s->lock, flags); | ||
2221 | s->ctrl = (s->ctrl & ~CTRL_WTSRSEL) | (1 << CTRL_SH_WTSRSEL); | ||
2222 | s->sctrl &= ~SCTRL_P1FMT; | ||
2223 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
2224 | s->sctrl |= ES1370_FMT_S16_MONO << SCTRL_SH_P1FMT; | ||
2225 | else | ||
2226 | s->sctrl |= ES1370_FMT_U8_MONO << SCTRL_SH_P1FMT; | ||
2227 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
2228 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
2229 | spin_unlock_irqrestore(&s->lock, flags); | ||
2230 | s->open_mode |= FMODE_DAC; | ||
2231 | mutex_unlock(&s->open_mutex); | ||
2232 | return nonseekable_open(inode, file); | ||
2233 | } | ||
2234 | |||
2235 | static int es1370_release_dac(struct inode *inode, struct file *file) | ||
2236 | { | ||
2237 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
2238 | |||
2239 | VALIDATE_STATE(s); | ||
2240 | lock_kernel(); | ||
2241 | drain_dac1(s, file->f_flags & O_NONBLOCK); | ||
2242 | mutex_lock(&s->open_mutex); | ||
2243 | stop_dac1(s); | ||
2244 | dealloc_dmabuf(s, &s->dma_dac1); | ||
2245 | s->open_mode &= ~FMODE_DAC; | ||
2246 | wake_up(&s->open_wait); | ||
2247 | mutex_unlock(&s->open_mutex); | ||
2248 | unlock_kernel(); | ||
2249 | return 0; | ||
2250 | } | ||
2251 | |||
2252 | static /*const*/ struct file_operations es1370_dac_fops = { | ||
2253 | .owner = THIS_MODULE, | ||
2254 | .llseek = no_llseek, | ||
2255 | .write = es1370_write_dac, | ||
2256 | .poll = es1370_poll_dac, | ||
2257 | .ioctl = es1370_ioctl_dac, | ||
2258 | .mmap = es1370_mmap_dac, | ||
2259 | .open = es1370_open_dac, | ||
2260 | .release = es1370_release_dac, | ||
2261 | }; | ||
2262 | |||
2263 | /* --------------------------------------------------------------------- */ | ||
2264 | |||
2265 | static ssize_t es1370_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
2266 | { | ||
2267 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
2268 | DECLARE_WAITQUEUE(wait, current); | ||
2269 | ssize_t ret; | ||
2270 | unsigned long flags; | ||
2271 | unsigned ptr; | ||
2272 | int cnt; | ||
2273 | |||
2274 | VALIDATE_STATE(s); | ||
2275 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
2276 | return -EFAULT; | ||
2277 | if (count == 0) | ||
2278 | return 0; | ||
2279 | ret = 0; | ||
2280 | add_wait_queue(&s->midi.iwait, &wait); | ||
2281 | while (count > 0) { | ||
2282 | spin_lock_irqsave(&s->lock, flags); | ||
2283 | ptr = s->midi.ird; | ||
2284 | cnt = MIDIINBUF - ptr; | ||
2285 | if (s->midi.icnt < cnt) | ||
2286 | cnt = s->midi.icnt; | ||
2287 | if (cnt <= 0) | ||
2288 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2289 | spin_unlock_irqrestore(&s->lock, flags); | ||
2290 | if (cnt > count) | ||
2291 | cnt = count; | ||
2292 | if (cnt <= 0) { | ||
2293 | if (file->f_flags & O_NONBLOCK) { | ||
2294 | if (!ret) | ||
2295 | ret = -EAGAIN; | ||
2296 | break; | ||
2297 | } | ||
2298 | schedule(); | ||
2299 | if (signal_pending(current)) { | ||
2300 | if (!ret) | ||
2301 | ret = -ERESTARTSYS; | ||
2302 | break; | ||
2303 | } | ||
2304 | continue; | ||
2305 | } | ||
2306 | if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { | ||
2307 | if (!ret) | ||
2308 | ret = -EFAULT; | ||
2309 | break; | ||
2310 | } | ||
2311 | ptr = (ptr + cnt) % MIDIINBUF; | ||
2312 | spin_lock_irqsave(&s->lock, flags); | ||
2313 | s->midi.ird = ptr; | ||
2314 | s->midi.icnt -= cnt; | ||
2315 | spin_unlock_irqrestore(&s->lock, flags); | ||
2316 | count -= cnt; | ||
2317 | buffer += cnt; | ||
2318 | ret += cnt; | ||
2319 | break; | ||
2320 | } | ||
2321 | __set_current_state(TASK_RUNNING); | ||
2322 | remove_wait_queue(&s->midi.iwait, &wait); | ||
2323 | return ret; | ||
2324 | } | ||
2325 | |||
2326 | static ssize_t es1370_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
2327 | { | ||
2328 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
2329 | DECLARE_WAITQUEUE(wait, current); | ||
2330 | ssize_t ret; | ||
2331 | unsigned long flags; | ||
2332 | unsigned ptr; | ||
2333 | int cnt; | ||
2334 | |||
2335 | VALIDATE_STATE(s); | ||
2336 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
2337 | return -EFAULT; | ||
2338 | if (count == 0) | ||
2339 | return 0; | ||
2340 | ret = 0; | ||
2341 | add_wait_queue(&s->midi.owait, &wait); | ||
2342 | while (count > 0) { | ||
2343 | spin_lock_irqsave(&s->lock, flags); | ||
2344 | ptr = s->midi.owr; | ||
2345 | cnt = MIDIOUTBUF - ptr; | ||
2346 | if (s->midi.ocnt + cnt > MIDIOUTBUF) | ||
2347 | cnt = MIDIOUTBUF - s->midi.ocnt; | ||
2348 | if (cnt <= 0) { | ||
2349 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2350 | es1370_handle_midi(s); | ||
2351 | } | ||
2352 | spin_unlock_irqrestore(&s->lock, flags); | ||
2353 | if (cnt > count) | ||
2354 | cnt = count; | ||
2355 | if (cnt <= 0) { | ||
2356 | if (file->f_flags & O_NONBLOCK) { | ||
2357 | if (!ret) | ||
2358 | ret = -EAGAIN; | ||
2359 | break; | ||
2360 | } | ||
2361 | schedule(); | ||
2362 | if (signal_pending(current)) { | ||
2363 | if (!ret) | ||
2364 | ret = -ERESTARTSYS; | ||
2365 | break; | ||
2366 | } | ||
2367 | continue; | ||
2368 | } | ||
2369 | if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { | ||
2370 | if (!ret) | ||
2371 | ret = -EFAULT; | ||
2372 | break; | ||
2373 | } | ||
2374 | ptr = (ptr + cnt) % MIDIOUTBUF; | ||
2375 | spin_lock_irqsave(&s->lock, flags); | ||
2376 | s->midi.owr = ptr; | ||
2377 | s->midi.ocnt += cnt; | ||
2378 | spin_unlock_irqrestore(&s->lock, flags); | ||
2379 | count -= cnt; | ||
2380 | buffer += cnt; | ||
2381 | ret += cnt; | ||
2382 | spin_lock_irqsave(&s->lock, flags); | ||
2383 | es1370_handle_midi(s); | ||
2384 | spin_unlock_irqrestore(&s->lock, flags); | ||
2385 | } | ||
2386 | __set_current_state(TASK_RUNNING); | ||
2387 | remove_wait_queue(&s->midi.owait, &wait); | ||
2388 | return ret; | ||
2389 | } | ||
2390 | |||
2391 | /* No kernel lock - we have our own spinlock */ | ||
2392 | static unsigned int es1370_midi_poll(struct file *file, struct poll_table_struct *wait) | ||
2393 | { | ||
2394 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
2395 | unsigned long flags; | ||
2396 | unsigned int mask = 0; | ||
2397 | |||
2398 | VALIDATE_STATE(s); | ||
2399 | if (file->f_mode & FMODE_WRITE) | ||
2400 | poll_wait(file, &s->midi.owait, wait); | ||
2401 | if (file->f_mode & FMODE_READ) | ||
2402 | poll_wait(file, &s->midi.iwait, wait); | ||
2403 | spin_lock_irqsave(&s->lock, flags); | ||
2404 | if (file->f_mode & FMODE_READ) { | ||
2405 | if (s->midi.icnt > 0) | ||
2406 | mask |= POLLIN | POLLRDNORM; | ||
2407 | } | ||
2408 | if (file->f_mode & FMODE_WRITE) { | ||
2409 | if (s->midi.ocnt < MIDIOUTBUF) | ||
2410 | mask |= POLLOUT | POLLWRNORM; | ||
2411 | } | ||
2412 | spin_unlock_irqrestore(&s->lock, flags); | ||
2413 | return mask; | ||
2414 | } | ||
2415 | |||
2416 | static int es1370_midi_open(struct inode *inode, struct file *file) | ||
2417 | { | ||
2418 | unsigned int minor = iminor(inode); | ||
2419 | DECLARE_WAITQUEUE(wait, current); | ||
2420 | unsigned long flags; | ||
2421 | struct list_head *list; | ||
2422 | struct es1370_state *s; | ||
2423 | |||
2424 | for (list = devs.next; ; list = list->next) { | ||
2425 | if (list == &devs) | ||
2426 | return -ENODEV; | ||
2427 | s = list_entry(list, struct es1370_state, devs); | ||
2428 | if (s->dev_midi == minor) | ||
2429 | break; | ||
2430 | } | ||
2431 | VALIDATE_STATE(s); | ||
2432 | file->private_data = s; | ||
2433 | /* wait for device to become free */ | ||
2434 | mutex_lock(&s->open_mutex); | ||
2435 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { | ||
2436 | if (file->f_flags & O_NONBLOCK) { | ||
2437 | mutex_unlock(&s->open_mutex); | ||
2438 | return -EBUSY; | ||
2439 | } | ||
2440 | add_wait_queue(&s->open_wait, &wait); | ||
2441 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2442 | mutex_unlock(&s->open_mutex); | ||
2443 | schedule(); | ||
2444 | remove_wait_queue(&s->open_wait, &wait); | ||
2445 | set_current_state(TASK_RUNNING); | ||
2446 | if (signal_pending(current)) | ||
2447 | return -ERESTARTSYS; | ||
2448 | mutex_lock(&s->open_mutex); | ||
2449 | } | ||
2450 | spin_lock_irqsave(&s->lock, flags); | ||
2451 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
2452 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
2453 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
2454 | outb(UCTRL_CNTRL_SWR, s->io+ES1370_REG_UART_CONTROL); | ||
2455 | outb(0, s->io+ES1370_REG_UART_CONTROL); | ||
2456 | outb(0, s->io+ES1370_REG_UART_TEST); | ||
2457 | } | ||
2458 | if (file->f_mode & FMODE_READ) { | ||
2459 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
2460 | } | ||
2461 | if (file->f_mode & FMODE_WRITE) { | ||
2462 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
2463 | } | ||
2464 | s->ctrl |= CTRL_UART_EN; | ||
2465 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
2466 | es1370_handle_midi(s); | ||
2467 | spin_unlock_irqrestore(&s->lock, flags); | ||
2468 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); | ||
2469 | mutex_unlock(&s->open_mutex); | ||
2470 | return nonseekable_open(inode, file); | ||
2471 | } | ||
2472 | |||
2473 | static int es1370_midi_release(struct inode *inode, struct file *file) | ||
2474 | { | ||
2475 | struct es1370_state *s = (struct es1370_state *)file->private_data; | ||
2476 | DECLARE_WAITQUEUE(wait, current); | ||
2477 | unsigned long flags; | ||
2478 | unsigned count, tmo; | ||
2479 | |||
2480 | VALIDATE_STATE(s); | ||
2481 | |||
2482 | lock_kernel(); | ||
2483 | if (file->f_mode & FMODE_WRITE) { | ||
2484 | add_wait_queue(&s->midi.owait, &wait); | ||
2485 | for (;;) { | ||
2486 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2487 | spin_lock_irqsave(&s->lock, flags); | ||
2488 | count = s->midi.ocnt; | ||
2489 | spin_unlock_irqrestore(&s->lock, flags); | ||
2490 | if (count <= 0) | ||
2491 | break; | ||
2492 | if (signal_pending(current)) | ||
2493 | break; | ||
2494 | if (file->f_flags & O_NONBLOCK) | ||
2495 | break; | ||
2496 | tmo = (count * HZ) / 3100; | ||
2497 | if (!schedule_timeout(tmo ? : 1) && tmo) | ||
2498 | DBG(printk(KERN_DEBUG "es1370: midi timed out??\n");) | ||
2499 | } | ||
2500 | remove_wait_queue(&s->midi.owait, &wait); | ||
2501 | set_current_state(TASK_RUNNING); | ||
2502 | } | ||
2503 | mutex_lock(&s->open_mutex); | ||
2504 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); | ||
2505 | spin_lock_irqsave(&s->lock, flags); | ||
2506 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
2507 | s->ctrl &= ~CTRL_UART_EN; | ||
2508 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
2509 | } | ||
2510 | spin_unlock_irqrestore(&s->lock, flags); | ||
2511 | wake_up(&s->open_wait); | ||
2512 | mutex_unlock(&s->open_mutex); | ||
2513 | unlock_kernel(); | ||
2514 | return 0; | ||
2515 | } | ||
2516 | |||
2517 | static /*const*/ struct file_operations es1370_midi_fops = { | ||
2518 | .owner = THIS_MODULE, | ||
2519 | .llseek = no_llseek, | ||
2520 | .read = es1370_midi_read, | ||
2521 | .write = es1370_midi_write, | ||
2522 | .poll = es1370_midi_poll, | ||
2523 | .open = es1370_midi_open, | ||
2524 | .release = es1370_midi_release, | ||
2525 | }; | ||
2526 | |||
2527 | /* --------------------------------------------------------------------- */ | ||
2528 | |||
2529 | /* maximum number of devices; only used for command line params */ | ||
2530 | #define NR_DEVICE 5 | ||
2531 | |||
2532 | static int lineout[NR_DEVICE]; | ||
2533 | static int micbias[NR_DEVICE]; | ||
2534 | |||
2535 | static unsigned int devindex; | ||
2536 | |||
2537 | module_param_array(lineout, bool, NULL, 0); | ||
2538 | MODULE_PARM_DESC(lineout, "if 1 the LINE input is converted to LINE out"); | ||
2539 | module_param_array(micbias, bool, NULL, 0); | ||
2540 | MODULE_PARM_DESC(micbias, "sets the +5V bias for an electret microphone"); | ||
2541 | |||
2542 | MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); | ||
2543 | MODULE_DESCRIPTION("ES1370 AudioPCI Driver"); | ||
2544 | MODULE_LICENSE("GPL"); | ||
2545 | |||
2546 | |||
2547 | /* --------------------------------------------------------------------- */ | ||
2548 | |||
2549 | static struct initvol { | ||
2550 | int mixch; | ||
2551 | int vol; | ||
2552 | } initvol[] __devinitdata = { | ||
2553 | { SOUND_MIXER_WRITE_VOLUME, 0x4040 }, | ||
2554 | { SOUND_MIXER_WRITE_PCM, 0x4040 }, | ||
2555 | { SOUND_MIXER_WRITE_SYNTH, 0x4040 }, | ||
2556 | { SOUND_MIXER_WRITE_CD, 0x4040 }, | ||
2557 | { SOUND_MIXER_WRITE_LINE, 0x4040 }, | ||
2558 | { SOUND_MIXER_WRITE_LINE1, 0x4040 }, | ||
2559 | { SOUND_MIXER_WRITE_LINE2, 0x4040 }, | ||
2560 | { SOUND_MIXER_WRITE_LINE3, 0x4040 }, | ||
2561 | { SOUND_MIXER_WRITE_MIC, 0x4040 }, | ||
2562 | { SOUND_MIXER_WRITE_OGAIN, 0x4040 } | ||
2563 | }; | ||
2564 | |||
2565 | #ifdef SUPPORT_JOYSTICK | ||
2566 | |||
2567 | static int __devinit es1370_register_gameport(struct es1370_state *s) | ||
2568 | { | ||
2569 | struct gameport *gp; | ||
2570 | |||
2571 | if (!request_region(0x200, JOY_EXTENT, "es1370")) { | ||
2572 | printk(KERN_ERR "es1370: joystick io port 0x200 in use\n"); | ||
2573 | return -EBUSY; | ||
2574 | } | ||
2575 | |||
2576 | s->gameport = gp = gameport_allocate_port(); | ||
2577 | if (!gp) { | ||
2578 | printk(KERN_ERR "es1370: can not allocate memory for gameport\n"); | ||
2579 | release_region(0x200, JOY_EXTENT); | ||
2580 | return -ENOMEM; | ||
2581 | } | ||
2582 | |||
2583 | gameport_set_name(gp, "ESS1370"); | ||
2584 | gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev)); | ||
2585 | gp->dev.parent = &s->dev->dev; | ||
2586 | gp->io = 0x200; | ||
2587 | |||
2588 | s->ctrl |= CTRL_JYSTK_EN; | ||
2589 | outl(s->ctrl, s->io + ES1370_REG_CONTROL); | ||
2590 | |||
2591 | gameport_register_port(gp); | ||
2592 | |||
2593 | return 0; | ||
2594 | } | ||
2595 | |||
2596 | static inline void es1370_unregister_gameport(struct es1370_state *s) | ||
2597 | { | ||
2598 | if (s->gameport) { | ||
2599 | int gpio = s->gameport->io; | ||
2600 | gameport_unregister_port(s->gameport); | ||
2601 | release_region(gpio, JOY_EXTENT); | ||
2602 | |||
2603 | } | ||
2604 | } | ||
2605 | |||
2606 | #else | ||
2607 | static inline int es1370_register_gameport(struct es1370_state *s) { return -ENOSYS; } | ||
2608 | static inline void es1370_unregister_gameport(struct es1370_state *s) { } | ||
2609 | #endif /* SUPPORT_JOYSTICK */ | ||
2610 | |||
2611 | static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) | ||
2612 | { | ||
2613 | struct es1370_state *s; | ||
2614 | mm_segment_t fs; | ||
2615 | int i, val, ret; | ||
2616 | |||
2617 | if ((ret=pci_enable_device(pcidev))) | ||
2618 | return ret; | ||
2619 | |||
2620 | if ( !(pci_resource_flags(pcidev, 0) & IORESOURCE_IO) || | ||
2621 | !pci_resource_start(pcidev, 0) | ||
2622 | ) | ||
2623 | return -ENODEV; | ||
2624 | if (pcidev->irq == 0) | ||
2625 | return -ENODEV; | ||
2626 | i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK); | ||
2627 | if (i) { | ||
2628 | printk(KERN_WARNING "es1370: architecture does not support 32bit PCI busmaster DMA\n"); | ||
2629 | return i; | ||
2630 | } | ||
2631 | if (!(s = kmalloc(sizeof(struct es1370_state), GFP_KERNEL))) { | ||
2632 | printk(KERN_WARNING "es1370: out of memory\n"); | ||
2633 | return -ENOMEM; | ||
2634 | } | ||
2635 | memset(s, 0, sizeof(struct es1370_state)); | ||
2636 | init_waitqueue_head(&s->dma_adc.wait); | ||
2637 | init_waitqueue_head(&s->dma_dac1.wait); | ||
2638 | init_waitqueue_head(&s->dma_dac2.wait); | ||
2639 | init_waitqueue_head(&s->open_wait); | ||
2640 | init_waitqueue_head(&s->midi.iwait); | ||
2641 | init_waitqueue_head(&s->midi.owait); | ||
2642 | mutex_init(&s->open_mutex); | ||
2643 | spin_lock_init(&s->lock); | ||
2644 | s->magic = ES1370_MAGIC; | ||
2645 | s->dev = pcidev; | ||
2646 | s->io = pci_resource_start(pcidev, 0); | ||
2647 | s->irq = pcidev->irq; | ||
2648 | if (!request_region(s->io, ES1370_EXTENT, "es1370")) { | ||
2649 | printk(KERN_ERR "es1370: io ports %#lx-%#lx in use\n", s->io, s->io+ES1370_EXTENT-1); | ||
2650 | ret = -EBUSY; | ||
2651 | goto err_region; | ||
2652 | } | ||
2653 | if ((ret=request_irq(s->irq, es1370_interrupt, IRQF_SHARED, "es1370",s))) { | ||
2654 | printk(KERN_ERR "es1370: irq %u in use\n", s->irq); | ||
2655 | goto err_irq; | ||
2656 | } | ||
2657 | |||
2658 | /* initialize codec registers */ | ||
2659 | /* note: setting CTRL_SERR_DIS is reported to break | ||
2660 | * mic bias setting (by Kim.Berts@fisub.mail.abb.com) */ | ||
2661 | s->ctrl = CTRL_CDC_EN | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL); | ||
2662 | if (lineout[devindex]) | ||
2663 | s->ctrl |= CTRL_XCTL0; | ||
2664 | if (micbias[devindex]) | ||
2665 | s->ctrl |= CTRL_XCTL1; | ||
2666 | s->sctrl = 0; | ||
2667 | printk(KERN_INFO "es1370: adapter at io %#lx irq %u, line %s, mic impedance %s\n", | ||
2668 | s->io, s->irq, (s->ctrl & CTRL_XCTL0) ? "out" : "in", | ||
2669 | (s->ctrl & CTRL_XCTL1) ? "1" : "0"); | ||
2670 | /* register devices */ | ||
2671 | if ((s->dev_audio = register_sound_dsp(&es1370_audio_fops, -1)) < 0) { | ||
2672 | ret = s->dev_audio; | ||
2673 | goto err_dev1; | ||
2674 | } | ||
2675 | if ((s->dev_mixer = register_sound_mixer(&es1370_mixer_fops, -1)) < 0) { | ||
2676 | ret = s->dev_mixer; | ||
2677 | goto err_dev2; | ||
2678 | } | ||
2679 | if ((s->dev_dac = register_sound_dsp(&es1370_dac_fops, -1)) < 0) { | ||
2680 | ret = s->dev_dac; | ||
2681 | goto err_dev3; | ||
2682 | } | ||
2683 | if ((s->dev_midi = register_sound_midi(&es1370_midi_fops, -1)) < 0) { | ||
2684 | ret = s->dev_midi; | ||
2685 | goto err_dev4; | ||
2686 | } | ||
2687 | /* initialize the chips */ | ||
2688 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | ||
2689 | outl(s->sctrl, s->io+ES1370_REG_SERIAL_CONTROL); | ||
2690 | /* point phantom write channel to "bugbuf" */ | ||
2691 | s->bugbuf_cpu = pci_alloc_consistent(pcidev,16,&s->bugbuf_dma); | ||
2692 | if (!s->bugbuf_cpu) { | ||
2693 | ret = -ENOMEM; | ||
2694 | goto err_dev5; | ||
2695 | } | ||
2696 | outl((ES1370_REG_PHANTOM_FRAMEADR >> 8) & 15, s->io+ES1370_REG_MEMPAGE); | ||
2697 | outl(s->bugbuf_dma, s->io+(ES1370_REG_PHANTOM_FRAMEADR & 0xff)); | ||
2698 | outl(0, s->io+(ES1370_REG_PHANTOM_FRAMECNT & 0xff)); | ||
2699 | pci_set_master(pcidev); /* enable bus mastering */ | ||
2700 | wrcodec(s, 0x16, 3); /* no RST, PD */ | ||
2701 | wrcodec(s, 0x17, 0); /* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off the LRCLK2 PLL; program DAC_SYNC=0!! */ | ||
2702 | wrcodec(s, 0x18, 0); /* recording source is mixer */ | ||
2703 | wrcodec(s, 0x19, s->mix.micpreamp = 1); /* turn on MIC preamp */ | ||
2704 | s->mix.imix = 1; | ||
2705 | fs = get_fs(); | ||
2706 | set_fs(KERNEL_DS); | ||
2707 | val = SOUND_MASK_LINE|SOUND_MASK_SYNTH|SOUND_MASK_CD; | ||
2708 | mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); | ||
2709 | for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) { | ||
2710 | val = initvol[i].vol; | ||
2711 | mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); | ||
2712 | } | ||
2713 | set_fs(fs); | ||
2714 | |||
2715 | es1370_register_gameport(s); | ||
2716 | |||
2717 | /* store it in the driver field */ | ||
2718 | pci_set_drvdata(pcidev, s); | ||
2719 | /* put it into driver list */ | ||
2720 | list_add_tail(&s->devs, &devs); | ||
2721 | /* increment devindex */ | ||
2722 | if (devindex < NR_DEVICE-1) | ||
2723 | devindex++; | ||
2724 | return 0; | ||
2725 | |||
2726 | err_dev5: | ||
2727 | unregister_sound_midi(s->dev_midi); | ||
2728 | err_dev4: | ||
2729 | unregister_sound_dsp(s->dev_dac); | ||
2730 | err_dev3: | ||
2731 | unregister_sound_mixer(s->dev_mixer); | ||
2732 | err_dev2: | ||
2733 | unregister_sound_dsp(s->dev_audio); | ||
2734 | err_dev1: | ||
2735 | printk(KERN_ERR "es1370: cannot register misc device\n"); | ||
2736 | free_irq(s->irq, s); | ||
2737 | err_irq: | ||
2738 | release_region(s->io, ES1370_EXTENT); | ||
2739 | err_region: | ||
2740 | kfree(s); | ||
2741 | return ret; | ||
2742 | } | ||
2743 | |||
2744 | static void __devexit es1370_remove(struct pci_dev *dev) | ||
2745 | { | ||
2746 | struct es1370_state *s = pci_get_drvdata(dev); | ||
2747 | |||
2748 | if (!s) | ||
2749 | return; | ||
2750 | list_del(&s->devs); | ||
2751 | outl(CTRL_SERR_DIS | (1 << CTRL_SH_WTSRSEL), s->io+ES1370_REG_CONTROL); /* switch everything off */ | ||
2752 | outl(0, s->io+ES1370_REG_SERIAL_CONTROL); /* clear serial interrupts */ | ||
2753 | synchronize_irq(s->irq); | ||
2754 | free_irq(s->irq, s); | ||
2755 | es1370_unregister_gameport(s); | ||
2756 | release_region(s->io, ES1370_EXTENT); | ||
2757 | unregister_sound_dsp(s->dev_audio); | ||
2758 | unregister_sound_mixer(s->dev_mixer); | ||
2759 | unregister_sound_dsp(s->dev_dac); | ||
2760 | unregister_sound_midi(s->dev_midi); | ||
2761 | pci_free_consistent(dev, 16, s->bugbuf_cpu, s->bugbuf_dma); | ||
2762 | kfree(s); | ||
2763 | pci_set_drvdata(dev, NULL); | ||
2764 | } | ||
2765 | |||
2766 | static struct pci_device_id id_table[] = { | ||
2767 | { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
2768 | { 0, } | ||
2769 | }; | ||
2770 | |||
2771 | MODULE_DEVICE_TABLE(pci, id_table); | ||
2772 | |||
2773 | static struct pci_driver es1370_driver = { | ||
2774 | .name = "es1370", | ||
2775 | .id_table = id_table, | ||
2776 | .probe = es1370_probe, | ||
2777 | .remove = __devexit_p(es1370_remove), | ||
2778 | }; | ||
2779 | |||
2780 | static int __init init_es1370(void) | ||
2781 | { | ||
2782 | printk(KERN_INFO "es1370: version v0.38 time " __TIME__ " " __DATE__ "\n"); | ||
2783 | return pci_register_driver(&es1370_driver); | ||
2784 | } | ||
2785 | |||
2786 | static void __exit cleanup_es1370(void) | ||
2787 | { | ||
2788 | printk(KERN_INFO "es1370: unloading\n"); | ||
2789 | pci_unregister_driver(&es1370_driver); | ||
2790 | } | ||
2791 | |||
2792 | module_init(init_es1370); | ||
2793 | module_exit(cleanup_es1370); | ||
2794 | |||
2795 | /* --------------------------------------------------------------------- */ | ||
2796 | |||
2797 | #ifndef MODULE | ||
2798 | |||
2799 | /* format is: es1370=lineout[,micbias]] */ | ||
2800 | |||
2801 | static int __init es1370_setup(char *str) | ||
2802 | { | ||
2803 | static unsigned __initdata nr_dev = 0; | ||
2804 | |||
2805 | if (nr_dev >= NR_DEVICE) | ||
2806 | return 0; | ||
2807 | |||
2808 | (void) | ||
2809 | ((get_option(&str,&lineout [nr_dev]) == 2) | ||
2810 | && get_option(&str,&micbias [nr_dev]) | ||
2811 | ); | ||
2812 | |||
2813 | nr_dev++; | ||
2814 | return 1; | ||
2815 | } | ||
2816 | |||
2817 | __setup("es1370=", es1370_setup); | ||
2818 | |||
2819 | #endif /* MODULE */ | ||
diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c deleted file mode 100644 index 82f40a0a5c9c..000000000000 --- a/sound/oss/esssolo1.c +++ /dev/null | |||
@@ -1,2516 +0,0 @@ | |||
1 | /****************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * esssolo1.c -- ESS Technology Solo1 (ES1946) audio driver. | ||
5 | * | ||
6 | * Copyright (C) 1998-2001, 2003 Thomas Sailer (t.sailer@alumni.ethz.ch) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * Module command line parameters: | ||
23 | * none so far | ||
24 | * | ||
25 | * Supported devices: | ||
26 | * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible | ||
27 | * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible | ||
28 | * /dev/midi simple MIDI UART interface, no ioctl | ||
29 | * | ||
30 | * Revision history | ||
31 | * 10.11.1998 0.1 Initial release (without any hardware) | ||
32 | * 22.03.1999 0.2 cinfo.blocks should be reset after GETxPTR ioctl. | ||
33 | * reported by Johan Maes <joma@telindus.be> | ||
34 | * return EAGAIN instead of EBUSY when O_NONBLOCK | ||
35 | * read/write cannot be executed | ||
36 | * 07.04.1999 0.3 implemented the following ioctl's: SOUND_PCM_READ_RATE, | ||
37 | * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; | ||
38 | * Alpha fixes reported by Peter Jones <pjones@redhat.com> | ||
39 | * 15.06.1999 0.4 Fix bad allocation bug. | ||
40 | * Thanks to Deti Fliegl <fliegl@in.tum.de> | ||
41 | * 28.06.1999 0.5 Add pci_set_master | ||
42 | * 12.08.1999 0.6 Fix MIDI UART crashing the driver | ||
43 | * Changed mixer semantics from OSS documented | ||
44 | * behaviour to OSS "code behaviour". | ||
45 | * Recording might actually work now. | ||
46 | * The real DDMA controller address register is at PCI config | ||
47 | * 0x60, while the register at 0x18 is used as a placeholder | ||
48 | * register for BIOS address allocation. This register | ||
49 | * is supposed to be copied into 0x60, according | ||
50 | * to the Solo1 datasheet. When I do that, I can access | ||
51 | * the DDMA registers except the mask bit, which | ||
52 | * is stuck at 1. When I copy the contents of 0x18 +0x10 | ||
53 | * to the DDMA base register, everything seems to work. | ||
54 | * The fun part is that the Windows Solo1 driver doesn't | ||
55 | * seem to do these tricks. | ||
56 | * Bugs remaining: plops and clicks when starting/stopping playback | ||
57 | * 31.08.1999 0.7 add spin_lock_init | ||
58 | * replaced current->state = x with set_current_state(x) | ||
59 | * 03.09.1999 0.8 change read semantics for MIDI to match | ||
60 | * OSS more closely; remove possible wakeup race | ||
61 | * 07.10.1999 0.9 Fix initialization; complain if sequencer writes time out | ||
62 | * Revised resource grabbing for the FM synthesizer | ||
63 | * 28.10.1999 0.10 More waitqueue races fixed | ||
64 | * 09.12.1999 0.11 Work around stupid Alpha port issue (virt_to_bus(kmalloc(GFP_DMA)) > 16M) | ||
65 | * Disabling recording on Alpha | ||
66 | * 12.01.2000 0.12 Prevent some ioctl's from returning bad count values on underrun/overrun; | ||
67 | * Tim Janik's BSE (Bedevilled Sound Engine) found this | ||
68 | * Integrated (aka redid 8-)) APM support patch by Zach Brown | ||
69 | * 07.02.2000 0.13 Use pci_alloc_consistent and pci_register_driver | ||
70 | * 19.02.2000 0.14 Use pci_dma_supported to determine if recording should be disabled | ||
71 | * 13.03.2000 0.15 Reintroduce initialization of a couple of PCI config space registers | ||
72 | * 21.11.2000 0.16 Initialize dma buffers in poll, otherwise poll may return a bogus mask | ||
73 | * 12.12.2000 0.17 More dma buffer initializations, patch from | ||
74 | * Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com> | ||
75 | * 31.01.2001 0.18 Register/Unregister gameport, original patch from | ||
76 | * Nathaniel Daw <daw@cs.cmu.edu> | ||
77 | * Fix SETTRIGGER non OSS API conformity | ||
78 | * 10.03.2001 provide abs function, prevent picking up a bogus kernel macro | ||
79 | * for abs. Bug report by Andrew Morton <andrewm@uow.edu.au> | ||
80 | * 15.05.2001 pci_enable_device moved, return values in probe cleaned | ||
81 | * up. Marcus Meissner <mm@caldera.de> | ||
82 | * 22.05.2001 0.19 more cleanups, changed PM to PCI 2.4 style, got rid | ||
83 | * of global list of devices, using pci device data. | ||
84 | * Marcus Meissner <mm@caldera.de> | ||
85 | * 03.01.2003 0.20 open_mode fixes from Georg Acher <acher@in.tum.de> | ||
86 | */ | ||
87 | |||
88 | /*****************************************************************************/ | ||
89 | |||
90 | #include <linux/interrupt.h> | ||
91 | #include <linux/module.h> | ||
92 | #include <linux/string.h> | ||
93 | #include <linux/ioport.h> | ||
94 | #include <linux/sched.h> | ||
95 | #include <linux/delay.h> | ||
96 | #include <linux/sound.h> | ||
97 | #include <linux/slab.h> | ||
98 | #include <linux/soundcard.h> | ||
99 | #include <linux/pci.h> | ||
100 | #include <linux/bitops.h> | ||
101 | #include <linux/init.h> | ||
102 | #include <linux/poll.h> | ||
103 | #include <linux/spinlock.h> | ||
104 | #include <linux/smp_lock.h> | ||
105 | #include <linux/gameport.h> | ||
106 | #include <linux/wait.h> | ||
107 | #include <linux/dma-mapping.h> | ||
108 | #include <linux/mutex.h> | ||
109 | |||
110 | |||
111 | #include <asm/io.h> | ||
112 | #include <asm/page.h> | ||
113 | #include <asm/uaccess.h> | ||
114 | |||
115 | #include "dm.h" | ||
116 | |||
117 | /* --------------------------------------------------------------------- */ | ||
118 | |||
119 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
120 | |||
121 | /* --------------------------------------------------------------------- */ | ||
122 | |||
123 | #ifndef PCI_VENDOR_ID_ESS | ||
124 | #define PCI_VENDOR_ID_ESS 0x125d | ||
125 | #endif | ||
126 | #ifndef PCI_DEVICE_ID_ESS_SOLO1 | ||
127 | #define PCI_DEVICE_ID_ESS_SOLO1 0x1969 | ||
128 | #endif | ||
129 | |||
130 | #define SOLO1_MAGIC ((PCI_VENDOR_ID_ESS<<16)|PCI_DEVICE_ID_ESS_SOLO1) | ||
131 | |||
132 | #define DDMABASE_OFFSET 0 /* chip bug workaround kludge */ | ||
133 | #define DDMABASE_EXTENT 16 | ||
134 | |||
135 | #define IOBASE_EXTENT 16 | ||
136 | #define SBBASE_EXTENT 16 | ||
137 | #define VCBASE_EXTENT (DDMABASE_EXTENT+DDMABASE_OFFSET) | ||
138 | #define MPUBASE_EXTENT 4 | ||
139 | #define GPBASE_EXTENT 4 | ||
140 | #define GAMEPORT_EXTENT 4 | ||
141 | |||
142 | #define FMSYNTH_EXTENT 4 | ||
143 | |||
144 | /* MIDI buffer sizes */ | ||
145 | |||
146 | #define MIDIINBUF 256 | ||
147 | #define MIDIOUTBUF 256 | ||
148 | |||
149 | #define FMODE_MIDI_SHIFT 3 | ||
150 | #define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) | ||
151 | #define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) | ||
152 | |||
153 | #define FMODE_DMFM 0x10 | ||
154 | |||
155 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) | ||
156 | #define SUPPORT_JOYSTICK 1 | ||
157 | #endif | ||
158 | |||
159 | static struct pci_driver solo1_driver; | ||
160 | |||
161 | /* --------------------------------------------------------------------- */ | ||
162 | |||
163 | struct solo1_state { | ||
164 | /* magic */ | ||
165 | unsigned int magic; | ||
166 | |||
167 | /* the corresponding pci_dev structure */ | ||
168 | struct pci_dev *dev; | ||
169 | |||
170 | /* soundcore stuff */ | ||
171 | int dev_audio; | ||
172 | int dev_mixer; | ||
173 | int dev_midi; | ||
174 | int dev_dmfm; | ||
175 | |||
176 | /* hardware resources */ | ||
177 | unsigned long iobase, sbbase, vcbase, ddmabase, mpubase; /* long for SPARC */ | ||
178 | unsigned int irq; | ||
179 | |||
180 | /* mixer registers */ | ||
181 | struct { | ||
182 | unsigned short vol[10]; | ||
183 | unsigned int recsrc; | ||
184 | unsigned int modcnt; | ||
185 | unsigned short micpreamp; | ||
186 | } mix; | ||
187 | |||
188 | /* wave stuff */ | ||
189 | unsigned fmt; | ||
190 | unsigned channels; | ||
191 | unsigned rate; | ||
192 | unsigned char clkdiv; | ||
193 | unsigned ena; | ||
194 | |||
195 | spinlock_t lock; | ||
196 | struct mutex open_mutex; | ||
197 | mode_t open_mode; | ||
198 | wait_queue_head_t open_wait; | ||
199 | |||
200 | struct dmabuf { | ||
201 | void *rawbuf; | ||
202 | dma_addr_t dmaaddr; | ||
203 | unsigned buforder; | ||
204 | unsigned numfrag; | ||
205 | unsigned fragshift; | ||
206 | unsigned hwptr, swptr; | ||
207 | unsigned total_bytes; | ||
208 | int count; | ||
209 | unsigned error; /* over/underrun */ | ||
210 | wait_queue_head_t wait; | ||
211 | /* redundant, but makes calculations easier */ | ||
212 | unsigned fragsize; | ||
213 | unsigned dmasize; | ||
214 | unsigned fragsamples; | ||
215 | /* OSS stuff */ | ||
216 | unsigned mapped:1; | ||
217 | unsigned ready:1; | ||
218 | unsigned endcleared:1; | ||
219 | unsigned enabled:1; | ||
220 | unsigned ossfragshift; | ||
221 | int ossmaxfrags; | ||
222 | unsigned subdivision; | ||
223 | } dma_dac, dma_adc; | ||
224 | |||
225 | /* midi stuff */ | ||
226 | struct { | ||
227 | unsigned ird, iwr, icnt; | ||
228 | unsigned ord, owr, ocnt; | ||
229 | wait_queue_head_t iwait; | ||
230 | wait_queue_head_t owait; | ||
231 | struct timer_list timer; | ||
232 | unsigned char ibuf[MIDIINBUF]; | ||
233 | unsigned char obuf[MIDIOUTBUF]; | ||
234 | } midi; | ||
235 | |||
236 | #if SUPPORT_JOYSTICK | ||
237 | struct gameport *gameport; | ||
238 | #endif | ||
239 | }; | ||
240 | |||
241 | /* --------------------------------------------------------------------- */ | ||
242 | |||
243 | static inline void write_seq(struct solo1_state *s, unsigned char data) | ||
244 | { | ||
245 | int i; | ||
246 | unsigned long flags; | ||
247 | |||
248 | /* the local_irq_save stunt is to send the data within the command window */ | ||
249 | for (i = 0; i < 0xffff; i++) { | ||
250 | local_irq_save(flags); | ||
251 | if (!(inb(s->sbbase+0xc) & 0x80)) { | ||
252 | outb(data, s->sbbase+0xc); | ||
253 | local_irq_restore(flags); | ||
254 | return; | ||
255 | } | ||
256 | local_irq_restore(flags); | ||
257 | } | ||
258 | printk(KERN_ERR "esssolo1: write_seq timeout\n"); | ||
259 | outb(data, s->sbbase+0xc); | ||
260 | } | ||
261 | |||
262 | static inline int read_seq(struct solo1_state *s, unsigned char *data) | ||
263 | { | ||
264 | int i; | ||
265 | |||
266 | if (!data) | ||
267 | return 0; | ||
268 | for (i = 0; i < 0xffff; i++) | ||
269 | if (inb(s->sbbase+0xe) & 0x80) { | ||
270 | *data = inb(s->sbbase+0xa); | ||
271 | return 1; | ||
272 | } | ||
273 | printk(KERN_ERR "esssolo1: read_seq timeout\n"); | ||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | static inline int reset_ctrl(struct solo1_state *s) | ||
278 | { | ||
279 | int i; | ||
280 | |||
281 | outb(3, s->sbbase+6); /* clear sequencer and FIFO */ | ||
282 | udelay(10); | ||
283 | outb(0, s->sbbase+6); | ||
284 | for (i = 0; i < 0xffff; i++) | ||
285 | if (inb(s->sbbase+0xe) & 0x80) | ||
286 | if (inb(s->sbbase+0xa) == 0xaa) { | ||
287 | write_seq(s, 0xc6); /* enter enhanced mode */ | ||
288 | return 1; | ||
289 | } | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static void write_ctrl(struct solo1_state *s, unsigned char reg, unsigned char data) | ||
294 | { | ||
295 | write_seq(s, reg); | ||
296 | write_seq(s, data); | ||
297 | } | ||
298 | |||
299 | #if 0 /* unused */ | ||
300 | static unsigned char read_ctrl(struct solo1_state *s, unsigned char reg) | ||
301 | { | ||
302 | unsigned char r; | ||
303 | |||
304 | write_seq(s, 0xc0); | ||
305 | write_seq(s, reg); | ||
306 | read_seq(s, &r); | ||
307 | return r; | ||
308 | } | ||
309 | #endif /* unused */ | ||
310 | |||
311 | static void write_mixer(struct solo1_state *s, unsigned char reg, unsigned char data) | ||
312 | { | ||
313 | outb(reg, s->sbbase+4); | ||
314 | outb(data, s->sbbase+5); | ||
315 | } | ||
316 | |||
317 | static unsigned char read_mixer(struct solo1_state *s, unsigned char reg) | ||
318 | { | ||
319 | outb(reg, s->sbbase+4); | ||
320 | return inb(s->sbbase+5); | ||
321 | } | ||
322 | |||
323 | /* --------------------------------------------------------------------- */ | ||
324 | |||
325 | static inline unsigned ld2(unsigned int x) | ||
326 | { | ||
327 | unsigned r = 0; | ||
328 | |||
329 | if (x >= 0x10000) { | ||
330 | x >>= 16; | ||
331 | r += 16; | ||
332 | } | ||
333 | if (x >= 0x100) { | ||
334 | x >>= 8; | ||
335 | r += 8; | ||
336 | } | ||
337 | if (x >= 0x10) { | ||
338 | x >>= 4; | ||
339 | r += 4; | ||
340 | } | ||
341 | if (x >= 4) { | ||
342 | x >>= 2; | ||
343 | r += 2; | ||
344 | } | ||
345 | if (x >= 2) | ||
346 | r++; | ||
347 | return r; | ||
348 | } | ||
349 | |||
350 | /* --------------------------------------------------------------------- */ | ||
351 | |||
352 | static inline void stop_dac(struct solo1_state *s) | ||
353 | { | ||
354 | unsigned long flags; | ||
355 | |||
356 | spin_lock_irqsave(&s->lock, flags); | ||
357 | s->ena &= ~FMODE_WRITE; | ||
358 | write_mixer(s, 0x78, 0x10); | ||
359 | spin_unlock_irqrestore(&s->lock, flags); | ||
360 | } | ||
361 | |||
362 | static void start_dac(struct solo1_state *s) | ||
363 | { | ||
364 | unsigned long flags; | ||
365 | |||
366 | spin_lock_irqsave(&s->lock, flags); | ||
367 | if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) { | ||
368 | s->ena |= FMODE_WRITE; | ||
369 | write_mixer(s, 0x78, 0x12); | ||
370 | udelay(10); | ||
371 | write_mixer(s, 0x78, 0x13); | ||
372 | } | ||
373 | spin_unlock_irqrestore(&s->lock, flags); | ||
374 | } | ||
375 | |||
376 | static inline void stop_adc(struct solo1_state *s) | ||
377 | { | ||
378 | unsigned long flags; | ||
379 | |||
380 | spin_lock_irqsave(&s->lock, flags); | ||
381 | s->ena &= ~FMODE_READ; | ||
382 | write_ctrl(s, 0xb8, 0xe); | ||
383 | spin_unlock_irqrestore(&s->lock, flags); | ||
384 | } | ||
385 | |||
386 | static void start_adc(struct solo1_state *s) | ||
387 | { | ||
388 | unsigned long flags; | ||
389 | |||
390 | spin_lock_irqsave(&s->lock, flags); | ||
391 | if (!(s->ena & FMODE_READ) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) | ||
392 | && s->dma_adc.ready) { | ||
393 | s->ena |= FMODE_READ; | ||
394 | write_ctrl(s, 0xb8, 0xf); | ||
395 | #if 0 | ||
396 | printk(KERN_DEBUG "solo1: DMAbuffer: 0x%08lx\n", (long)s->dma_adc.rawbuf); | ||
397 | printk(KERN_DEBUG "solo1: DMA: mask: 0x%02x cnt: 0x%04x addr: 0x%08x stat: 0x%02x\n", | ||
398 | inb(s->ddmabase+0xf), inw(s->ddmabase+4), inl(s->ddmabase), inb(s->ddmabase+8)); | ||
399 | #endif | ||
400 | outb(0, s->ddmabase+0xd); /* master reset */ | ||
401 | outb(1, s->ddmabase+0xf); /* mask */ | ||
402 | outb(0x54/*0x14*/, s->ddmabase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */ | ||
403 | outl(virt_to_bus(s->dma_adc.rawbuf), s->ddmabase); | ||
404 | outw(s->dma_adc.dmasize-1, s->ddmabase+4); | ||
405 | outb(0, s->ddmabase+0xf); | ||
406 | } | ||
407 | spin_unlock_irqrestore(&s->lock, flags); | ||
408 | #if 0 | ||
409 | printk(KERN_DEBUG "solo1: start DMA: reg B8: 0x%02x SBstat: 0x%02x\n" | ||
410 | KERN_DEBUG "solo1: DMA: stat: 0x%02x cnt: 0x%04x mask: 0x%02x\n", | ||
411 | read_ctrl(s, 0xb8), inb(s->sbbase+0xc), | ||
412 | inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->ddmabase+0xf)); | ||
413 | printk(KERN_DEBUG "solo1: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" | ||
414 | KERN_DEBUG "solo1: B1: 0x%02x B2: 0x%02x B4: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n", | ||
415 | read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), | ||
416 | read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb4), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), | ||
417 | read_ctrl(s, 0xb9)); | ||
418 | #endif | ||
419 | } | ||
420 | |||
421 | /* --------------------------------------------------------------------- */ | ||
422 | |||
423 | #define DMABUF_DEFAULTORDER (15-PAGE_SHIFT) | ||
424 | #define DMABUF_MINORDER 1 | ||
425 | |||
426 | static inline void dealloc_dmabuf(struct solo1_state *s, struct dmabuf *db) | ||
427 | { | ||
428 | struct page *page, *pend; | ||
429 | |||
430 | if (db->rawbuf) { | ||
431 | /* undo marking the pages as reserved */ | ||
432 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
433 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
434 | ClearPageReserved(page); | ||
435 | pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr); | ||
436 | } | ||
437 | db->rawbuf = NULL; | ||
438 | db->mapped = db->ready = 0; | ||
439 | } | ||
440 | |||
441 | static int prog_dmabuf(struct solo1_state *s, struct dmabuf *db) | ||
442 | { | ||
443 | int order; | ||
444 | unsigned bytespersec; | ||
445 | unsigned bufs, sample_shift = 0; | ||
446 | struct page *page, *pend; | ||
447 | |||
448 | db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; | ||
449 | if (!db->rawbuf) { | ||
450 | db->ready = db->mapped = 0; | ||
451 | for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) | ||
452 | if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr))) | ||
453 | break; | ||
454 | if (!db->rawbuf) | ||
455 | return -ENOMEM; | ||
456 | db->buforder = order; | ||
457 | /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ | ||
458 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
459 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
460 | SetPageReserved(page); | ||
461 | } | ||
462 | if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE)) | ||
463 | sample_shift++; | ||
464 | if (s->channels > 1) | ||
465 | sample_shift++; | ||
466 | bytespersec = s->rate << sample_shift; | ||
467 | bufs = PAGE_SIZE << db->buforder; | ||
468 | if (db->ossfragshift) { | ||
469 | if ((1000 << db->ossfragshift) < bytespersec) | ||
470 | db->fragshift = ld2(bytespersec/1000); | ||
471 | else | ||
472 | db->fragshift = db->ossfragshift; | ||
473 | } else { | ||
474 | db->fragshift = ld2(bytespersec/100/(db->subdivision ? db->subdivision : 1)); | ||
475 | if (db->fragshift < 3) | ||
476 | db->fragshift = 3; | ||
477 | } | ||
478 | db->numfrag = bufs >> db->fragshift; | ||
479 | while (db->numfrag < 4 && db->fragshift > 3) { | ||
480 | db->fragshift--; | ||
481 | db->numfrag = bufs >> db->fragshift; | ||
482 | } | ||
483 | db->fragsize = 1 << db->fragshift; | ||
484 | if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) | ||
485 | db->numfrag = db->ossmaxfrags; | ||
486 | db->fragsamples = db->fragsize >> sample_shift; | ||
487 | db->dmasize = db->numfrag << db->fragshift; | ||
488 | db->enabled = 1; | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static inline int prog_dmabuf_adc(struct solo1_state *s) | ||
493 | { | ||
494 | unsigned long va; | ||
495 | int c; | ||
496 | |||
497 | stop_adc(s); | ||
498 | /* check if PCI implementation supports 24bit busmaster DMA */ | ||
499 | if (s->dev->dma_mask > 0xffffff) | ||
500 | return -EIO; | ||
501 | if ((c = prog_dmabuf(s, &s->dma_adc))) | ||
502 | return c; | ||
503 | va = s->dma_adc.dmaaddr; | ||
504 | if ((va & ~((1<<24)-1))) | ||
505 | panic("solo1: buffer above 16M boundary"); | ||
506 | outb(0, s->ddmabase+0xd); /* clear */ | ||
507 | outb(1, s->ddmabase+0xf); /* mask */ | ||
508 | /*outb(0, s->ddmabase+8);*/ /* enable (enable is active low!) */ | ||
509 | outb(0x54, s->ddmabase+0xb); /* DMA_MODE_READ | DMA_MODE_AUTOINIT */ | ||
510 | outl(va, s->ddmabase); | ||
511 | outw(s->dma_adc.dmasize-1, s->ddmabase+4); | ||
512 | c = - s->dma_adc.fragsamples; | ||
513 | write_ctrl(s, 0xa4, c); | ||
514 | write_ctrl(s, 0xa5, c >> 8); | ||
515 | outb(0, s->ddmabase+0xf); | ||
516 | s->dma_adc.ready = 1; | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | static int prog_dmabuf_dac(struct solo1_state *s) | ||
521 | { | ||
522 | unsigned long va; | ||
523 | int c; | ||
524 | |||
525 | stop_dac(s); | ||
526 | if ((c = prog_dmabuf(s, &s->dma_dac))) | ||
527 | return c; | ||
528 | memset(s->dma_dac.rawbuf, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80, s->dma_dac.dmasize); /* almost correct for U16 */ | ||
529 | va = s->dma_dac.dmaaddr; | ||
530 | if ((va ^ (va + s->dma_dac.dmasize - 1)) & ~((1<<20)-1)) | ||
531 | panic("solo1: buffer crosses 1M boundary"); | ||
532 | outl(va, s->iobase); | ||
533 | /* warning: s->dma_dac.dmasize & 0xffff must not be zero! i.e. this limits us to a 32k buffer */ | ||
534 | outw(s->dma_dac.dmasize, s->iobase+4); | ||
535 | c = - s->dma_dac.fragsamples; | ||
536 | write_mixer(s, 0x74, c); | ||
537 | write_mixer(s, 0x76, c >> 8); | ||
538 | outb(0xa, s->iobase+6); | ||
539 | s->dma_dac.ready = 1; | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c) | ||
544 | { | ||
545 | if (bptr + len > bsize) { | ||
546 | unsigned x = bsize - bptr; | ||
547 | memset(((char *)buf) + bptr, c, x); | ||
548 | bptr = 0; | ||
549 | len -= x; | ||
550 | } | ||
551 | memset(((char *)buf) + bptr, c, len); | ||
552 | } | ||
553 | |||
554 | /* call with spinlock held! */ | ||
555 | |||
556 | static void solo1_update_ptr(struct solo1_state *s) | ||
557 | { | ||
558 | int diff; | ||
559 | unsigned hwptr; | ||
560 | |||
561 | /* update ADC pointer */ | ||
562 | if (s->ena & FMODE_READ) { | ||
563 | hwptr = (s->dma_adc.dmasize - 1 - inw(s->ddmabase+4)) % s->dma_adc.dmasize; | ||
564 | diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; | ||
565 | s->dma_adc.hwptr = hwptr; | ||
566 | s->dma_adc.total_bytes += diff; | ||
567 | s->dma_adc.count += diff; | ||
568 | #if 0 | ||
569 | printk(KERN_DEBUG "solo1: rd: hwptr %u swptr %u dmasize %u count %u\n", | ||
570 | s->dma_adc.hwptr, s->dma_adc.swptr, s->dma_adc.dmasize, s->dma_adc.count); | ||
571 | #endif | ||
572 | if (s->dma_adc.mapped) { | ||
573 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
574 | wake_up(&s->dma_adc.wait); | ||
575 | } else { | ||
576 | if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { | ||
577 | s->ena &= ~FMODE_READ; | ||
578 | write_ctrl(s, 0xb8, 0xe); | ||
579 | s->dma_adc.error++; | ||
580 | } | ||
581 | if (s->dma_adc.count > 0) | ||
582 | wake_up(&s->dma_adc.wait); | ||
583 | } | ||
584 | } | ||
585 | /* update DAC pointer */ | ||
586 | if (s->ena & FMODE_WRITE) { | ||
587 | hwptr = (s->dma_dac.dmasize - inw(s->iobase+4)) % s->dma_dac.dmasize; | ||
588 | diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize; | ||
589 | s->dma_dac.hwptr = hwptr; | ||
590 | s->dma_dac.total_bytes += diff; | ||
591 | #if 0 | ||
592 | printk(KERN_DEBUG "solo1: wr: hwptr %u swptr %u dmasize %u count %u\n", | ||
593 | s->dma_dac.hwptr, s->dma_dac.swptr, s->dma_dac.dmasize, s->dma_dac.count); | ||
594 | #endif | ||
595 | if (s->dma_dac.mapped) { | ||
596 | s->dma_dac.count += diff; | ||
597 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) | ||
598 | wake_up(&s->dma_dac.wait); | ||
599 | } else { | ||
600 | s->dma_dac.count -= diff; | ||
601 | if (s->dma_dac.count <= 0) { | ||
602 | s->ena &= ~FMODE_WRITE; | ||
603 | write_mixer(s, 0x78, 0x12); | ||
604 | s->dma_dac.error++; | ||
605 | } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) { | ||
606 | clear_advance(s->dma_dac.rawbuf, s->dma_dac.dmasize, s->dma_dac.swptr, | ||
607 | s->dma_dac.fragsize, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0 : 0x80); | ||
608 | s->dma_dac.endcleared = 1; | ||
609 | } | ||
610 | if (s->dma_dac.count < (signed)s->dma_dac.dmasize) | ||
611 | wake_up(&s->dma_dac.wait); | ||
612 | } | ||
613 | } | ||
614 | } | ||
615 | |||
616 | /* --------------------------------------------------------------------- */ | ||
617 | |||
618 | static void prog_codec(struct solo1_state *s) | ||
619 | { | ||
620 | unsigned long flags; | ||
621 | int fdiv, filter; | ||
622 | unsigned char c; | ||
623 | |||
624 | reset_ctrl(s); | ||
625 | write_seq(s, 0xd3); | ||
626 | /* program sampling rates */ | ||
627 | filter = s->rate * 9 / 20; /* Set filter roll-off to 90% of rate/2 */ | ||
628 | fdiv = 256 - 7160000 / (filter * 82); | ||
629 | spin_lock_irqsave(&s->lock, flags); | ||
630 | write_ctrl(s, 0xa1, s->clkdiv); | ||
631 | write_ctrl(s, 0xa2, fdiv); | ||
632 | write_mixer(s, 0x70, s->clkdiv); | ||
633 | write_mixer(s, 0x72, fdiv); | ||
634 | /* program ADC parameters */ | ||
635 | write_ctrl(s, 0xb8, 0xe); | ||
636 | write_ctrl(s, 0xb9, /*0x1*/0); | ||
637 | write_ctrl(s, 0xa8, (s->channels > 1) ? 0x11 : 0x12); | ||
638 | c = 0xd0; | ||
639 | if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE)) | ||
640 | c |= 0x04; | ||
641 | if (s->fmt & (AFMT_S16_LE | AFMT_S8)) | ||
642 | c |= 0x20; | ||
643 | if (s->channels > 1) | ||
644 | c ^= 0x48; | ||
645 | write_ctrl(s, 0xb7, (c & 0x70) | 1); | ||
646 | write_ctrl(s, 0xb7, c); | ||
647 | write_ctrl(s, 0xb1, 0x50); | ||
648 | write_ctrl(s, 0xb2, 0x50); | ||
649 | /* program DAC parameters */ | ||
650 | c = 0x40; | ||
651 | if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE)) | ||
652 | c |= 1; | ||
653 | if (s->fmt & (AFMT_S16_LE | AFMT_S8)) | ||
654 | c |= 4; | ||
655 | if (s->channels > 1) | ||
656 | c |= 2; | ||
657 | write_mixer(s, 0x7a, c); | ||
658 | write_mixer(s, 0x78, 0x10); | ||
659 | s->ena = 0; | ||
660 | spin_unlock_irqrestore(&s->lock, flags); | ||
661 | } | ||
662 | |||
663 | /* --------------------------------------------------------------------- */ | ||
664 | |||
665 | static const char invalid_magic[] = KERN_CRIT "solo1: invalid magic value\n"; | ||
666 | |||
667 | #define VALIDATE_STATE(s) \ | ||
668 | ({ \ | ||
669 | if (!(s) || (s)->magic != SOLO1_MAGIC) { \ | ||
670 | printk(invalid_magic); \ | ||
671 | return -ENXIO; \ | ||
672 | } \ | ||
673 | }) | ||
674 | |||
675 | /* --------------------------------------------------------------------- */ | ||
676 | |||
677 | static int mixer_ioctl(struct solo1_state *s, unsigned int cmd, unsigned long arg) | ||
678 | { | ||
679 | static const unsigned int mixer_src[8] = { | ||
680 | SOUND_MASK_MIC, SOUND_MASK_MIC, SOUND_MASK_CD, SOUND_MASK_VOLUME, | ||
681 | SOUND_MASK_MIC, 0, SOUND_MASK_LINE, 0 | ||
682 | }; | ||
683 | static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = { | ||
684 | [SOUND_MIXER_PCM] = 1, /* voice */ | ||
685 | [SOUND_MIXER_SYNTH] = 2, /* FM */ | ||
686 | [SOUND_MIXER_CD] = 3, /* CD */ | ||
687 | [SOUND_MIXER_LINE] = 4, /* Line */ | ||
688 | [SOUND_MIXER_LINE1] = 5, /* AUX */ | ||
689 | [SOUND_MIXER_MIC] = 6, /* Mic */ | ||
690 | [SOUND_MIXER_LINE2] = 7, /* Mono in */ | ||
691 | [SOUND_MIXER_SPEAKER] = 8, /* Speaker */ | ||
692 | [SOUND_MIXER_RECLEV] = 9, /* Recording level */ | ||
693 | [SOUND_MIXER_VOLUME] = 10 /* Master Volume */ | ||
694 | }; | ||
695 | static const unsigned char mixreg[] = { | ||
696 | 0x7c, /* voice */ | ||
697 | 0x36, /* FM */ | ||
698 | 0x38, /* CD */ | ||
699 | 0x3e, /* Line */ | ||
700 | 0x3a, /* AUX */ | ||
701 | 0x1a, /* Mic */ | ||
702 | 0x6d /* Mono in */ | ||
703 | }; | ||
704 | unsigned char l, r, rl, rr, vidx; | ||
705 | int i, val; | ||
706 | int __user *p = (int __user *)arg; | ||
707 | |||
708 | VALIDATE_STATE(s); | ||
709 | |||
710 | if (cmd == SOUND_MIXER_PRIVATE1) { | ||
711 | /* enable/disable/query mixer preamp */ | ||
712 | if (get_user(val, p)) | ||
713 | return -EFAULT; | ||
714 | if (val != -1) { | ||
715 | val = val ? 0xff : 0xf7; | ||
716 | write_mixer(s, 0x7d, (read_mixer(s, 0x7d) | 0x08) & val); | ||
717 | } | ||
718 | val = (read_mixer(s, 0x7d) & 0x08) ? 1 : 0; | ||
719 | return put_user(val, p); | ||
720 | } | ||
721 | if (cmd == SOUND_MIXER_PRIVATE2) { | ||
722 | /* enable/disable/query spatializer */ | ||
723 | if (get_user(val, p)) | ||
724 | return -EFAULT; | ||
725 | if (val != -1) { | ||
726 | val &= 0x3f; | ||
727 | write_mixer(s, 0x52, val); | ||
728 | write_mixer(s, 0x50, val ? 0x08 : 0); | ||
729 | } | ||
730 | return put_user(read_mixer(s, 0x52), p); | ||
731 | } | ||
732 | if (cmd == SOUND_MIXER_INFO) { | ||
733 | mixer_info info; | ||
734 | strncpy(info.id, "Solo1", sizeof(info.id)); | ||
735 | strncpy(info.name, "ESS Solo1", sizeof(info.name)); | ||
736 | info.modify_counter = s->mix.modcnt; | ||
737 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | ||
738 | return -EFAULT; | ||
739 | return 0; | ||
740 | } | ||
741 | if (cmd == SOUND_OLD_MIXER_INFO) { | ||
742 | _old_mixer_info info; | ||
743 | strncpy(info.id, "Solo1", sizeof(info.id)); | ||
744 | strncpy(info.name, "ESS Solo1", sizeof(info.name)); | ||
745 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | ||
746 | return -EFAULT; | ||
747 | return 0; | ||
748 | } | ||
749 | if (cmd == OSS_GETVERSION) | ||
750 | return put_user(SOUND_VERSION, p); | ||
751 | if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int)) | ||
752 | return -EINVAL; | ||
753 | if (_SIOC_DIR(cmd) == _SIOC_READ) { | ||
754 | switch (_IOC_NR(cmd)) { | ||
755 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
756 | return put_user(mixer_src[read_mixer(s, 0x1c) & 7], p); | ||
757 | |||
758 | case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ | ||
759 | return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD | | ||
760 | SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC | | ||
761 | SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV | | ||
762 | SOUND_MASK_SPEAKER, p); | ||
763 | |||
764 | case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ | ||
765 | return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME, p); | ||
766 | |||
767 | case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ | ||
768 | return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD | | ||
769 | SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC | | ||
770 | SOUND_MASK_VOLUME | SOUND_MASK_LINE2 | SOUND_MASK_RECLEV, p); | ||
771 | |||
772 | case SOUND_MIXER_CAPS: | ||
773 | return put_user(SOUND_CAP_EXCL_INPUT, p); | ||
774 | |||
775 | default: | ||
776 | i = _IOC_NR(cmd); | ||
777 | if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i])) | ||
778 | return -EINVAL; | ||
779 | return put_user(s->mix.vol[vidx-1], p); | ||
780 | } | ||
781 | } | ||
782 | if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) | ||
783 | return -EINVAL; | ||
784 | s->mix.modcnt++; | ||
785 | switch (_IOC_NR(cmd)) { | ||
786 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
787 | #if 0 | ||
788 | { | ||
789 | static const unsigned char regs[] = { | ||
790 | 0x1c, 0x1a, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x60, 0x62, 0x6d, 0x7c | ||
791 | }; | ||
792 | int i; | ||
793 | |||
794 | for (i = 0; i < sizeof(regs); i++) | ||
795 | printk(KERN_DEBUG "solo1: mixer reg 0x%02x: 0x%02x\n", | ||
796 | regs[i], read_mixer(s, regs[i])); | ||
797 | printk(KERN_DEBUG "solo1: ctrl reg 0x%02x: 0x%02x\n", | ||
798 | 0xb4, read_ctrl(s, 0xb4)); | ||
799 | } | ||
800 | #endif | ||
801 | if (get_user(val, p)) | ||
802 | return -EFAULT; | ||
803 | i = hweight32(val); | ||
804 | if (i == 0) | ||
805 | return 0; | ||
806 | else if (i > 1) | ||
807 | val &= ~mixer_src[read_mixer(s, 0x1c) & 7]; | ||
808 | for (i = 0; i < 8; i++) { | ||
809 | if (mixer_src[i] & val) | ||
810 | break; | ||
811 | } | ||
812 | if (i > 7) | ||
813 | return 0; | ||
814 | write_mixer(s, 0x1c, i); | ||
815 | return 0; | ||
816 | |||
817 | case SOUND_MIXER_VOLUME: | ||
818 | if (get_user(val, p)) | ||
819 | return -EFAULT; | ||
820 | l = val & 0xff; | ||
821 | if (l > 100) | ||
822 | l = 100; | ||
823 | r = (val >> 8) & 0xff; | ||
824 | if (r > 100) | ||
825 | r = 100; | ||
826 | if (l < 6) { | ||
827 | rl = 0x40; | ||
828 | l = 0; | ||
829 | } else { | ||
830 | rl = (l * 2 - 11) / 3; | ||
831 | l = (rl * 3 + 11) / 2; | ||
832 | } | ||
833 | if (r < 6) { | ||
834 | rr = 0x40; | ||
835 | r = 0; | ||
836 | } else { | ||
837 | rr = (r * 2 - 11) / 3; | ||
838 | r = (rr * 3 + 11) / 2; | ||
839 | } | ||
840 | write_mixer(s, 0x60, rl); | ||
841 | write_mixer(s, 0x62, rr); | ||
842 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
843 | s->mix.vol[9] = ((unsigned int)r << 8) | l; | ||
844 | #else | ||
845 | s->mix.vol[9] = val; | ||
846 | #endif | ||
847 | return put_user(s->mix.vol[9], p); | ||
848 | |||
849 | case SOUND_MIXER_SPEAKER: | ||
850 | if (get_user(val, p)) | ||
851 | return -EFAULT; | ||
852 | l = val & 0xff; | ||
853 | if (l > 100) | ||
854 | l = 100; | ||
855 | else if (l < 2) | ||
856 | l = 2; | ||
857 | rl = (l - 2) / 14; | ||
858 | l = rl * 14 + 2; | ||
859 | write_mixer(s, 0x3c, rl); | ||
860 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
861 | s->mix.vol[7] = l * 0x101; | ||
862 | #else | ||
863 | s->mix.vol[7] = val; | ||
864 | #endif | ||
865 | return put_user(s->mix.vol[7], p); | ||
866 | |||
867 | case SOUND_MIXER_RECLEV: | ||
868 | if (get_user(val, p)) | ||
869 | return -EFAULT; | ||
870 | l = (val << 1) & 0x1fe; | ||
871 | if (l > 200) | ||
872 | l = 200; | ||
873 | else if (l < 5) | ||
874 | l = 5; | ||
875 | r = (val >> 7) & 0x1fe; | ||
876 | if (r > 200) | ||
877 | r = 200; | ||
878 | else if (r < 5) | ||
879 | r = 5; | ||
880 | rl = (l - 5) / 13; | ||
881 | rr = (r - 5) / 13; | ||
882 | r = (rl * 13 + 5) / 2; | ||
883 | l = (rr * 13 + 5) / 2; | ||
884 | write_ctrl(s, 0xb4, (rl << 4) | rr); | ||
885 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
886 | s->mix.vol[8] = ((unsigned int)r << 8) | l; | ||
887 | #else | ||
888 | s->mix.vol[8] = val; | ||
889 | #endif | ||
890 | return put_user(s->mix.vol[8], p); | ||
891 | |||
892 | default: | ||
893 | i = _IOC_NR(cmd); | ||
894 | if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i])) | ||
895 | return -EINVAL; | ||
896 | if (get_user(val, p)) | ||
897 | return -EFAULT; | ||
898 | l = (val << 1) & 0x1fe; | ||
899 | if (l > 200) | ||
900 | l = 200; | ||
901 | else if (l < 5) | ||
902 | l = 5; | ||
903 | r = (val >> 7) & 0x1fe; | ||
904 | if (r > 200) | ||
905 | r = 200; | ||
906 | else if (r < 5) | ||
907 | r = 5; | ||
908 | rl = (l - 5) / 13; | ||
909 | rr = (r - 5) / 13; | ||
910 | r = (rl * 13 + 5) / 2; | ||
911 | l = (rr * 13 + 5) / 2; | ||
912 | write_mixer(s, mixreg[vidx-1], (rl << 4) | rr); | ||
913 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
914 | s->mix.vol[vidx-1] = ((unsigned int)r << 8) | l; | ||
915 | #else | ||
916 | s->mix.vol[vidx-1] = val; | ||
917 | #endif | ||
918 | return put_user(s->mix.vol[vidx-1], p); | ||
919 | } | ||
920 | } | ||
921 | |||
922 | /* --------------------------------------------------------------------- */ | ||
923 | |||
924 | static int solo1_open_mixdev(struct inode *inode, struct file *file) | ||
925 | { | ||
926 | unsigned int minor = iminor(inode); | ||
927 | struct solo1_state *s = NULL; | ||
928 | struct pci_dev *pci_dev = NULL; | ||
929 | |||
930 | while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) { | ||
931 | struct pci_driver *drvr; | ||
932 | drvr = pci_dev_driver (pci_dev); | ||
933 | if (drvr != &solo1_driver) | ||
934 | continue; | ||
935 | s = (struct solo1_state*)pci_get_drvdata(pci_dev); | ||
936 | if (!s) | ||
937 | continue; | ||
938 | if (s->dev_mixer == minor) | ||
939 | break; | ||
940 | } | ||
941 | if (!s) | ||
942 | return -ENODEV; | ||
943 | VALIDATE_STATE(s); | ||
944 | file->private_data = s; | ||
945 | return nonseekable_open(inode, file); | ||
946 | } | ||
947 | |||
948 | static int solo1_release_mixdev(struct inode *inode, struct file *file) | ||
949 | { | ||
950 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
951 | |||
952 | VALIDATE_STATE(s); | ||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static int solo1_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
957 | { | ||
958 | return mixer_ioctl((struct solo1_state *)file->private_data, cmd, arg); | ||
959 | } | ||
960 | |||
961 | static /*const*/ struct file_operations solo1_mixer_fops = { | ||
962 | .owner = THIS_MODULE, | ||
963 | .llseek = no_llseek, | ||
964 | .ioctl = solo1_ioctl_mixdev, | ||
965 | .open = solo1_open_mixdev, | ||
966 | .release = solo1_release_mixdev, | ||
967 | }; | ||
968 | |||
969 | /* --------------------------------------------------------------------- */ | ||
970 | |||
971 | static int drain_dac(struct solo1_state *s, int nonblock) | ||
972 | { | ||
973 | DECLARE_WAITQUEUE(wait, current); | ||
974 | unsigned long flags; | ||
975 | int count; | ||
976 | unsigned tmo; | ||
977 | |||
978 | if (s->dma_dac.mapped) | ||
979 | return 0; | ||
980 | add_wait_queue(&s->dma_dac.wait, &wait); | ||
981 | for (;;) { | ||
982 | set_current_state(TASK_INTERRUPTIBLE); | ||
983 | spin_lock_irqsave(&s->lock, flags); | ||
984 | count = s->dma_dac.count; | ||
985 | spin_unlock_irqrestore(&s->lock, flags); | ||
986 | if (count <= 0) | ||
987 | break; | ||
988 | if (signal_pending(current)) | ||
989 | break; | ||
990 | if (nonblock) { | ||
991 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
992 | set_current_state(TASK_RUNNING); | ||
993 | return -EBUSY; | ||
994 | } | ||
995 | tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->rate; | ||
996 | if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE)) | ||
997 | tmo >>= 1; | ||
998 | if (s->channels > 1) | ||
999 | tmo >>= 1; | ||
1000 | if (!schedule_timeout(tmo + 1)) | ||
1001 | printk(KERN_DEBUG "solo1: dma timed out??\n"); | ||
1002 | } | ||
1003 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
1004 | set_current_state(TASK_RUNNING); | ||
1005 | if (signal_pending(current)) | ||
1006 | return -ERESTARTSYS; | ||
1007 | return 0; | ||
1008 | } | ||
1009 | |||
1010 | /* --------------------------------------------------------------------- */ | ||
1011 | |||
1012 | static ssize_t solo1_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1013 | { | ||
1014 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1015 | DECLARE_WAITQUEUE(wait, current); | ||
1016 | ssize_t ret; | ||
1017 | unsigned long flags; | ||
1018 | unsigned swptr; | ||
1019 | int cnt; | ||
1020 | |||
1021 | VALIDATE_STATE(s); | ||
1022 | if (s->dma_adc.mapped) | ||
1023 | return -ENXIO; | ||
1024 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | ||
1025 | return ret; | ||
1026 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1027 | return -EFAULT; | ||
1028 | ret = 0; | ||
1029 | add_wait_queue(&s->dma_adc.wait, &wait); | ||
1030 | while (count > 0) { | ||
1031 | spin_lock_irqsave(&s->lock, flags); | ||
1032 | swptr = s->dma_adc.swptr; | ||
1033 | cnt = s->dma_adc.dmasize-swptr; | ||
1034 | if (s->dma_adc.count < cnt) | ||
1035 | cnt = s->dma_adc.count; | ||
1036 | if (cnt <= 0) | ||
1037 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1038 | spin_unlock_irqrestore(&s->lock, flags); | ||
1039 | if (cnt > count) | ||
1040 | cnt = count; | ||
1041 | #ifdef DEBUGREC | ||
1042 | printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x SBstat: 0x%02x cnt: %u\n", | ||
1043 | read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc), cnt); | ||
1044 | #endif | ||
1045 | if (cnt <= 0) { | ||
1046 | if (s->dma_adc.enabled) | ||
1047 | start_adc(s); | ||
1048 | #ifdef DEBUGREC | ||
1049 | printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" | ||
1050 | KERN_DEBUG "solo1_read: regs: B1: 0x%02x B2: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n" | ||
1051 | KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n" | ||
1052 | KERN_DEBUG "solo1_read: SBstat: 0x%02x cnt: %u\n", | ||
1053 | read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), | ||
1054 | read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), | ||
1055 | inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt); | ||
1056 | #endif | ||
1057 | if (inb(s->ddmabase+15) & 1) | ||
1058 | printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n"); | ||
1059 | if (file->f_flags & O_NONBLOCK) { | ||
1060 | if (!ret) | ||
1061 | ret = -EAGAIN; | ||
1062 | break; | ||
1063 | } | ||
1064 | schedule(); | ||
1065 | #ifdef DEBUGREC | ||
1066 | printk(KERN_DEBUG "solo1_read: regs: A1: 0x%02x A2: 0x%02x A4: 0x%02x A5: 0x%02x A8: 0x%02x\n" | ||
1067 | KERN_DEBUG "solo1_read: regs: B1: 0x%02x B2: 0x%02x B7: 0x%02x B8: 0x%02x B9: 0x%02x\n" | ||
1068 | KERN_DEBUG "solo1_read: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x mask: 0x%02x\n" | ||
1069 | KERN_DEBUG "solo1_read: SBstat: 0x%02x cnt: %u\n", | ||
1070 | read_ctrl(s, 0xa1), read_ctrl(s, 0xa2), read_ctrl(s, 0xa4), read_ctrl(s, 0xa5), read_ctrl(s, 0xa8), | ||
1071 | read_ctrl(s, 0xb1), read_ctrl(s, 0xb2), read_ctrl(s, 0xb7), read_ctrl(s, 0xb8), read_ctrl(s, 0xb9), | ||
1072 | inl(s->ddmabase), inw(s->ddmabase+4), inb(s->ddmabase+8), inb(s->ddmabase+15), inb(s->sbbase+0xc), cnt); | ||
1073 | #endif | ||
1074 | if (signal_pending(current)) { | ||
1075 | if (!ret) | ||
1076 | ret = -ERESTARTSYS; | ||
1077 | break; | ||
1078 | } | ||
1079 | continue; | ||
1080 | } | ||
1081 | if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { | ||
1082 | if (!ret) | ||
1083 | ret = -EFAULT; | ||
1084 | break; | ||
1085 | } | ||
1086 | swptr = (swptr + cnt) % s->dma_adc.dmasize; | ||
1087 | spin_lock_irqsave(&s->lock, flags); | ||
1088 | s->dma_adc.swptr = swptr; | ||
1089 | s->dma_adc.count -= cnt; | ||
1090 | spin_unlock_irqrestore(&s->lock, flags); | ||
1091 | count -= cnt; | ||
1092 | buffer += cnt; | ||
1093 | ret += cnt; | ||
1094 | if (s->dma_adc.enabled) | ||
1095 | start_adc(s); | ||
1096 | #ifdef DEBUGREC | ||
1097 | printk(KERN_DEBUG "solo1_read: reg B8: 0x%02x DMAstat: 0x%02x DMAcnt: 0x%04x SBstat: 0x%02x\n", | ||
1098 | read_ctrl(s, 0xb8), inb(s->ddmabase+8), inw(s->ddmabase+4), inb(s->sbbase+0xc)); | ||
1099 | #endif | ||
1100 | } | ||
1101 | remove_wait_queue(&s->dma_adc.wait, &wait); | ||
1102 | set_current_state(TASK_RUNNING); | ||
1103 | return ret; | ||
1104 | } | ||
1105 | |||
1106 | static ssize_t solo1_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1107 | { | ||
1108 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1109 | DECLARE_WAITQUEUE(wait, current); | ||
1110 | ssize_t ret; | ||
1111 | unsigned long flags; | ||
1112 | unsigned swptr; | ||
1113 | int cnt; | ||
1114 | |||
1115 | VALIDATE_STATE(s); | ||
1116 | if (s->dma_dac.mapped) | ||
1117 | return -ENXIO; | ||
1118 | if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s))) | ||
1119 | return ret; | ||
1120 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1121 | return -EFAULT; | ||
1122 | #if 0 | ||
1123 | printk(KERN_DEBUG "solo1_write: reg 70: 0x%02x 71: 0x%02x 72: 0x%02x 74: 0x%02x 76: 0x%02x 78: 0x%02x 7A: 0x%02x\n" | ||
1124 | KERN_DEBUG "solo1_write: DMA: addr: 0x%08x cnt: 0x%04x stat: 0x%02x SBstat: 0x%02x\n", | ||
1125 | read_mixer(s, 0x70), read_mixer(s, 0x71), read_mixer(s, 0x72), read_mixer(s, 0x74), read_mixer(s, 0x76), | ||
1126 | read_mixer(s, 0x78), read_mixer(s, 0x7a), inl(s->iobase), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc)); | ||
1127 | printk(KERN_DEBUG "solo1_write: reg 78: 0x%02x reg 7A: 0x%02x DMAcnt: 0x%04x DMAstat: 0x%02x SBstat: 0x%02x\n", | ||
1128 | read_mixer(s, 0x78), read_mixer(s, 0x7a), inw(s->iobase+4), inb(s->iobase+6), inb(s->sbbase+0xc)); | ||
1129 | #endif | ||
1130 | ret = 0; | ||
1131 | add_wait_queue(&s->dma_dac.wait, &wait); | ||
1132 | while (count > 0) { | ||
1133 | spin_lock_irqsave(&s->lock, flags); | ||
1134 | if (s->dma_dac.count < 0) { | ||
1135 | s->dma_dac.count = 0; | ||
1136 | s->dma_dac.swptr = s->dma_dac.hwptr; | ||
1137 | } | ||
1138 | swptr = s->dma_dac.swptr; | ||
1139 | cnt = s->dma_dac.dmasize-swptr; | ||
1140 | if (s->dma_dac.count + cnt > s->dma_dac.dmasize) | ||
1141 | cnt = s->dma_dac.dmasize - s->dma_dac.count; | ||
1142 | if (cnt <= 0) | ||
1143 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1144 | spin_unlock_irqrestore(&s->lock, flags); | ||
1145 | if (cnt > count) | ||
1146 | cnt = count; | ||
1147 | if (cnt <= 0) { | ||
1148 | if (s->dma_dac.enabled) | ||
1149 | start_dac(s); | ||
1150 | if (file->f_flags & O_NONBLOCK) { | ||
1151 | if (!ret) | ||
1152 | ret = -EAGAIN; | ||
1153 | break; | ||
1154 | } | ||
1155 | schedule(); | ||
1156 | if (signal_pending(current)) { | ||
1157 | if (!ret) | ||
1158 | ret = -ERESTARTSYS; | ||
1159 | break; | ||
1160 | } | ||
1161 | continue; | ||
1162 | } | ||
1163 | if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { | ||
1164 | if (!ret) | ||
1165 | ret = -EFAULT; | ||
1166 | break; | ||
1167 | } | ||
1168 | swptr = (swptr + cnt) % s->dma_dac.dmasize; | ||
1169 | spin_lock_irqsave(&s->lock, flags); | ||
1170 | s->dma_dac.swptr = swptr; | ||
1171 | s->dma_dac.count += cnt; | ||
1172 | s->dma_dac.endcleared = 0; | ||
1173 | spin_unlock_irqrestore(&s->lock, flags); | ||
1174 | count -= cnt; | ||
1175 | buffer += cnt; | ||
1176 | ret += cnt; | ||
1177 | if (s->dma_dac.enabled) | ||
1178 | start_dac(s); | ||
1179 | } | ||
1180 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
1181 | set_current_state(TASK_RUNNING); | ||
1182 | return ret; | ||
1183 | } | ||
1184 | |||
1185 | /* No kernel lock - we have our own spinlock */ | ||
1186 | static unsigned int solo1_poll(struct file *file, struct poll_table_struct *wait) | ||
1187 | { | ||
1188 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1189 | unsigned long flags; | ||
1190 | unsigned int mask = 0; | ||
1191 | |||
1192 | VALIDATE_STATE(s); | ||
1193 | if (file->f_mode & FMODE_WRITE) { | ||
1194 | if (!s->dma_dac.ready && prog_dmabuf_dac(s)) | ||
1195 | return 0; | ||
1196 | poll_wait(file, &s->dma_dac.wait, wait); | ||
1197 | } | ||
1198 | if (file->f_mode & FMODE_READ) { | ||
1199 | if (!s->dma_adc.ready && prog_dmabuf_adc(s)) | ||
1200 | return 0; | ||
1201 | poll_wait(file, &s->dma_adc.wait, wait); | ||
1202 | } | ||
1203 | spin_lock_irqsave(&s->lock, flags); | ||
1204 | solo1_update_ptr(s); | ||
1205 | if (file->f_mode & FMODE_READ) { | ||
1206 | if (s->dma_adc.mapped) { | ||
1207 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
1208 | mask |= POLLIN | POLLRDNORM; | ||
1209 | } else { | ||
1210 | if (s->dma_adc.count > 0) | ||
1211 | mask |= POLLIN | POLLRDNORM; | ||
1212 | } | ||
1213 | } | ||
1214 | if (file->f_mode & FMODE_WRITE) { | ||
1215 | if (s->dma_dac.mapped) { | ||
1216 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) | ||
1217 | mask |= POLLOUT | POLLWRNORM; | ||
1218 | } else { | ||
1219 | if ((signed)s->dma_dac.dmasize > s->dma_dac.count) | ||
1220 | mask |= POLLOUT | POLLWRNORM; | ||
1221 | } | ||
1222 | } | ||
1223 | spin_unlock_irqrestore(&s->lock, flags); | ||
1224 | return mask; | ||
1225 | } | ||
1226 | |||
1227 | |||
1228 | static int solo1_mmap(struct file *file, struct vm_area_struct *vma) | ||
1229 | { | ||
1230 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1231 | struct dmabuf *db; | ||
1232 | int ret = -EINVAL; | ||
1233 | unsigned long size; | ||
1234 | |||
1235 | VALIDATE_STATE(s); | ||
1236 | lock_kernel(); | ||
1237 | if (vma->vm_flags & VM_WRITE) { | ||
1238 | if ((ret = prog_dmabuf_dac(s)) != 0) | ||
1239 | goto out; | ||
1240 | db = &s->dma_dac; | ||
1241 | } else if (vma->vm_flags & VM_READ) { | ||
1242 | if ((ret = prog_dmabuf_adc(s)) != 0) | ||
1243 | goto out; | ||
1244 | db = &s->dma_adc; | ||
1245 | } else | ||
1246 | goto out; | ||
1247 | ret = -EINVAL; | ||
1248 | if (vma->vm_pgoff != 0) | ||
1249 | goto out; | ||
1250 | size = vma->vm_end - vma->vm_start; | ||
1251 | if (size > (PAGE_SIZE << db->buforder)) | ||
1252 | goto out; | ||
1253 | ret = -EAGAIN; | ||
1254 | if (remap_pfn_range(vma, vma->vm_start, | ||
1255 | virt_to_phys(db->rawbuf) >> PAGE_SHIFT, | ||
1256 | size, vma->vm_page_prot)) | ||
1257 | goto out; | ||
1258 | db->mapped = 1; | ||
1259 | ret = 0; | ||
1260 | out: | ||
1261 | unlock_kernel(); | ||
1262 | return ret; | ||
1263 | } | ||
1264 | |||
1265 | static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1266 | { | ||
1267 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1268 | unsigned long flags; | ||
1269 | audio_buf_info abinfo; | ||
1270 | count_info cinfo; | ||
1271 | int val, mapped, ret, count; | ||
1272 | int div1, div2; | ||
1273 | unsigned rate1, rate2; | ||
1274 | void __user *argp = (void __user *)arg; | ||
1275 | int __user *p = argp; | ||
1276 | |||
1277 | VALIDATE_STATE(s); | ||
1278 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || | ||
1279 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
1280 | switch (cmd) { | ||
1281 | case OSS_GETVERSION: | ||
1282 | return put_user(SOUND_VERSION, p); | ||
1283 | |||
1284 | case SNDCTL_DSP_SYNC: | ||
1285 | if (file->f_mode & FMODE_WRITE) | ||
1286 | return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/); | ||
1287 | return 0; | ||
1288 | |||
1289 | case SNDCTL_DSP_SETDUPLEX: | ||
1290 | return 0; | ||
1291 | |||
1292 | case SNDCTL_DSP_GETCAPS: | ||
1293 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); | ||
1294 | |||
1295 | case SNDCTL_DSP_RESET: | ||
1296 | if (file->f_mode & FMODE_WRITE) { | ||
1297 | stop_dac(s); | ||
1298 | synchronize_irq(s->irq); | ||
1299 | s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0; | ||
1300 | } | ||
1301 | if (file->f_mode & FMODE_READ) { | ||
1302 | stop_adc(s); | ||
1303 | synchronize_irq(s->irq); | ||
1304 | s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
1305 | } | ||
1306 | prog_codec(s); | ||
1307 | return 0; | ||
1308 | |||
1309 | case SNDCTL_DSP_SPEED: | ||
1310 | if (get_user(val, p)) | ||
1311 | return -EFAULT; | ||
1312 | if (val >= 0) { | ||
1313 | stop_adc(s); | ||
1314 | stop_dac(s); | ||
1315 | s->dma_adc.ready = s->dma_dac.ready = 0; | ||
1316 | /* program sampling rates */ | ||
1317 | if (val > 48000) | ||
1318 | val = 48000; | ||
1319 | if (val < 6300) | ||
1320 | val = 6300; | ||
1321 | div1 = (768000 + val / 2) / val; | ||
1322 | rate1 = (768000 + div1 / 2) / div1; | ||
1323 | div1 = -div1; | ||
1324 | div2 = (793800 + val / 2) / val; | ||
1325 | rate2 = (793800 + div2 / 2) / div2; | ||
1326 | div2 = (-div2) & 0x7f; | ||
1327 | if (abs(val - rate2) < abs(val - rate1)) { | ||
1328 | rate1 = rate2; | ||
1329 | div1 = div2; | ||
1330 | } | ||
1331 | s->rate = rate1; | ||
1332 | s->clkdiv = div1; | ||
1333 | prog_codec(s); | ||
1334 | } | ||
1335 | return put_user(s->rate, p); | ||
1336 | |||
1337 | case SNDCTL_DSP_STEREO: | ||
1338 | if (get_user(val, p)) | ||
1339 | return -EFAULT; | ||
1340 | stop_adc(s); | ||
1341 | stop_dac(s); | ||
1342 | s->dma_adc.ready = s->dma_dac.ready = 0; | ||
1343 | /* program channels */ | ||
1344 | s->channels = val ? 2 : 1; | ||
1345 | prog_codec(s); | ||
1346 | return 0; | ||
1347 | |||
1348 | case SNDCTL_DSP_CHANNELS: | ||
1349 | if (get_user(val, p)) | ||
1350 | return -EFAULT; | ||
1351 | if (val != 0) { | ||
1352 | stop_adc(s); | ||
1353 | stop_dac(s); | ||
1354 | s->dma_adc.ready = s->dma_dac.ready = 0; | ||
1355 | /* program channels */ | ||
1356 | s->channels = (val >= 2) ? 2 : 1; | ||
1357 | prog_codec(s); | ||
1358 | } | ||
1359 | return put_user(s->channels, p); | ||
1360 | |||
1361 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
1362 | return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, p); | ||
1363 | |||
1364 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
1365 | if (get_user(val, p)) | ||
1366 | return -EFAULT; | ||
1367 | if (val != AFMT_QUERY) { | ||
1368 | stop_adc(s); | ||
1369 | stop_dac(s); | ||
1370 | s->dma_adc.ready = s->dma_dac.ready = 0; | ||
1371 | /* program format */ | ||
1372 | if (val != AFMT_S16_LE && val != AFMT_U16_LE && | ||
1373 | val != AFMT_S8 && val != AFMT_U8) | ||
1374 | val = AFMT_U8; | ||
1375 | s->fmt = val; | ||
1376 | prog_codec(s); | ||
1377 | } | ||
1378 | return put_user(s->fmt, p); | ||
1379 | |||
1380 | case SNDCTL_DSP_POST: | ||
1381 | return 0; | ||
1382 | |||
1383 | case SNDCTL_DSP_GETTRIGGER: | ||
1384 | val = 0; | ||
1385 | if (file->f_mode & s->ena & FMODE_READ) | ||
1386 | val |= PCM_ENABLE_INPUT; | ||
1387 | if (file->f_mode & s->ena & FMODE_WRITE) | ||
1388 | val |= PCM_ENABLE_OUTPUT; | ||
1389 | return put_user(val, p); | ||
1390 | |||
1391 | case SNDCTL_DSP_SETTRIGGER: | ||
1392 | if (get_user(val, p)) | ||
1393 | return -EFAULT; | ||
1394 | if (file->f_mode & FMODE_READ) { | ||
1395 | if (val & PCM_ENABLE_INPUT) { | ||
1396 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | ||
1397 | return ret; | ||
1398 | s->dma_dac.enabled = 1; | ||
1399 | start_adc(s); | ||
1400 | if (inb(s->ddmabase+15) & 1) | ||
1401 | printk(KERN_ERR "solo1: cannot start recording, DDMA mask bit stuck at 1\n"); | ||
1402 | } else { | ||
1403 | s->dma_dac.enabled = 0; | ||
1404 | stop_adc(s); | ||
1405 | } | ||
1406 | } | ||
1407 | if (file->f_mode & FMODE_WRITE) { | ||
1408 | if (val & PCM_ENABLE_OUTPUT) { | ||
1409 | if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s))) | ||
1410 | return ret; | ||
1411 | s->dma_dac.enabled = 1; | ||
1412 | start_dac(s); | ||
1413 | } else { | ||
1414 | s->dma_dac.enabled = 0; | ||
1415 | stop_dac(s); | ||
1416 | } | ||
1417 | } | ||
1418 | return 0; | ||
1419 | |||
1420 | case SNDCTL_DSP_GETOSPACE: | ||
1421 | if (!(file->f_mode & FMODE_WRITE)) | ||
1422 | return -EINVAL; | ||
1423 | if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0) | ||
1424 | return val; | ||
1425 | spin_lock_irqsave(&s->lock, flags); | ||
1426 | solo1_update_ptr(s); | ||
1427 | abinfo.fragsize = s->dma_dac.fragsize; | ||
1428 | count = s->dma_dac.count; | ||
1429 | if (count < 0) | ||
1430 | count = 0; | ||
1431 | abinfo.bytes = s->dma_dac.dmasize - count; | ||
1432 | abinfo.fragstotal = s->dma_dac.numfrag; | ||
1433 | abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; | ||
1434 | spin_unlock_irqrestore(&s->lock, flags); | ||
1435 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1436 | |||
1437 | case SNDCTL_DSP_GETISPACE: | ||
1438 | if (!(file->f_mode & FMODE_READ)) | ||
1439 | return -EINVAL; | ||
1440 | if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0) | ||
1441 | return val; | ||
1442 | spin_lock_irqsave(&s->lock, flags); | ||
1443 | solo1_update_ptr(s); | ||
1444 | abinfo.fragsize = s->dma_adc.fragsize; | ||
1445 | abinfo.bytes = s->dma_adc.count; | ||
1446 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
1447 | abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; | ||
1448 | spin_unlock_irqrestore(&s->lock, flags); | ||
1449 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1450 | |||
1451 | case SNDCTL_DSP_NONBLOCK: | ||
1452 | file->f_flags |= O_NONBLOCK; | ||
1453 | return 0; | ||
1454 | |||
1455 | case SNDCTL_DSP_GETODELAY: | ||
1456 | if (!(file->f_mode & FMODE_WRITE)) | ||
1457 | return -EINVAL; | ||
1458 | if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0) | ||
1459 | return val; | ||
1460 | spin_lock_irqsave(&s->lock, flags); | ||
1461 | solo1_update_ptr(s); | ||
1462 | count = s->dma_dac.count; | ||
1463 | spin_unlock_irqrestore(&s->lock, flags); | ||
1464 | if (count < 0) | ||
1465 | count = 0; | ||
1466 | return put_user(count, p); | ||
1467 | |||
1468 | case SNDCTL_DSP_GETIPTR: | ||
1469 | if (!(file->f_mode & FMODE_READ)) | ||
1470 | return -EINVAL; | ||
1471 | if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0) | ||
1472 | return val; | ||
1473 | spin_lock_irqsave(&s->lock, flags); | ||
1474 | solo1_update_ptr(s); | ||
1475 | cinfo.bytes = s->dma_adc.total_bytes; | ||
1476 | cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift; | ||
1477 | cinfo.ptr = s->dma_adc.hwptr; | ||
1478 | if (s->dma_adc.mapped) | ||
1479 | s->dma_adc.count &= s->dma_adc.fragsize-1; | ||
1480 | spin_unlock_irqrestore(&s->lock, flags); | ||
1481 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1482 | return -EFAULT; | ||
1483 | return 0; | ||
1484 | |||
1485 | case SNDCTL_DSP_GETOPTR: | ||
1486 | if (!(file->f_mode & FMODE_WRITE)) | ||
1487 | return -EINVAL; | ||
1488 | if (!s->dma_dac.ready && (val = prog_dmabuf_dac(s)) != 0) | ||
1489 | return val; | ||
1490 | spin_lock_irqsave(&s->lock, flags); | ||
1491 | solo1_update_ptr(s); | ||
1492 | cinfo.bytes = s->dma_dac.total_bytes; | ||
1493 | count = s->dma_dac.count; | ||
1494 | if (count < 0) | ||
1495 | count = 0; | ||
1496 | cinfo.blocks = count >> s->dma_dac.fragshift; | ||
1497 | cinfo.ptr = s->dma_dac.hwptr; | ||
1498 | if (s->dma_dac.mapped) | ||
1499 | s->dma_dac.count &= s->dma_dac.fragsize-1; | ||
1500 | spin_unlock_irqrestore(&s->lock, flags); | ||
1501 | #if 0 | ||
1502 | printk(KERN_DEBUG "esssolo1: GETOPTR: bytes %u blocks %u ptr %u, buforder %u numfrag %u fragshift %u\n" | ||
1503 | KERN_DEBUG "esssolo1: swptr %u count %u fragsize %u dmasize %u fragsamples %u\n", | ||
1504 | cinfo.bytes, cinfo.blocks, cinfo.ptr, s->dma_dac.buforder, s->dma_dac.numfrag, s->dma_dac.fragshift, | ||
1505 | s->dma_dac.swptr, s->dma_dac.count, s->dma_dac.fragsize, s->dma_dac.dmasize, s->dma_dac.fragsamples); | ||
1506 | #endif | ||
1507 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1508 | return -EFAULT; | ||
1509 | return 0; | ||
1510 | |||
1511 | case SNDCTL_DSP_GETBLKSIZE: | ||
1512 | if (file->f_mode & FMODE_WRITE) { | ||
1513 | if ((val = prog_dmabuf_dac(s))) | ||
1514 | return val; | ||
1515 | return put_user(s->dma_dac.fragsize, p); | ||
1516 | } | ||
1517 | if ((val = prog_dmabuf_adc(s))) | ||
1518 | return val; | ||
1519 | return put_user(s->dma_adc.fragsize, p); | ||
1520 | |||
1521 | case SNDCTL_DSP_SETFRAGMENT: | ||
1522 | if (get_user(val, p)) | ||
1523 | return -EFAULT; | ||
1524 | if (file->f_mode & FMODE_READ) { | ||
1525 | s->dma_adc.ossfragshift = val & 0xffff; | ||
1526 | s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; | ||
1527 | if (s->dma_adc.ossfragshift < 4) | ||
1528 | s->dma_adc.ossfragshift = 4; | ||
1529 | if (s->dma_adc.ossfragshift > 15) | ||
1530 | s->dma_adc.ossfragshift = 15; | ||
1531 | if (s->dma_adc.ossmaxfrags < 4) | ||
1532 | s->dma_adc.ossmaxfrags = 4; | ||
1533 | } | ||
1534 | if (file->f_mode & FMODE_WRITE) { | ||
1535 | s->dma_dac.ossfragshift = val & 0xffff; | ||
1536 | s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; | ||
1537 | if (s->dma_dac.ossfragshift < 4) | ||
1538 | s->dma_dac.ossfragshift = 4; | ||
1539 | if (s->dma_dac.ossfragshift > 15) | ||
1540 | s->dma_dac.ossfragshift = 15; | ||
1541 | if (s->dma_dac.ossmaxfrags < 4) | ||
1542 | s->dma_dac.ossmaxfrags = 4; | ||
1543 | } | ||
1544 | return 0; | ||
1545 | |||
1546 | case SNDCTL_DSP_SUBDIVIDE: | ||
1547 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
1548 | (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) | ||
1549 | return -EINVAL; | ||
1550 | if (get_user(val, p)) | ||
1551 | return -EFAULT; | ||
1552 | if (val != 1 && val != 2 && val != 4) | ||
1553 | return -EINVAL; | ||
1554 | if (file->f_mode & FMODE_READ) | ||
1555 | s->dma_adc.subdivision = val; | ||
1556 | if (file->f_mode & FMODE_WRITE) | ||
1557 | s->dma_dac.subdivision = val; | ||
1558 | return 0; | ||
1559 | |||
1560 | case SOUND_PCM_READ_RATE: | ||
1561 | return put_user(s->rate, p); | ||
1562 | |||
1563 | case SOUND_PCM_READ_CHANNELS: | ||
1564 | return put_user(s->channels, p); | ||
1565 | |||
1566 | case SOUND_PCM_READ_BITS: | ||
1567 | return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, p); | ||
1568 | |||
1569 | case SOUND_PCM_WRITE_FILTER: | ||
1570 | case SNDCTL_DSP_SETSYNCRO: | ||
1571 | case SOUND_PCM_READ_FILTER: | ||
1572 | return -EINVAL; | ||
1573 | |||
1574 | } | ||
1575 | return mixer_ioctl(s, cmd, arg); | ||
1576 | } | ||
1577 | |||
1578 | static int solo1_release(struct inode *inode, struct file *file) | ||
1579 | { | ||
1580 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1581 | |||
1582 | VALIDATE_STATE(s); | ||
1583 | lock_kernel(); | ||
1584 | if (file->f_mode & FMODE_WRITE) | ||
1585 | drain_dac(s, file->f_flags & O_NONBLOCK); | ||
1586 | mutex_lock(&s->open_mutex); | ||
1587 | if (file->f_mode & FMODE_WRITE) { | ||
1588 | stop_dac(s); | ||
1589 | outb(0, s->iobase+6); /* disable DMA */ | ||
1590 | dealloc_dmabuf(s, &s->dma_dac); | ||
1591 | } | ||
1592 | if (file->f_mode & FMODE_READ) { | ||
1593 | stop_adc(s); | ||
1594 | outb(1, s->ddmabase+0xf); /* mask DMA channel */ | ||
1595 | outb(0, s->ddmabase+0xd); /* DMA master clear */ | ||
1596 | dealloc_dmabuf(s, &s->dma_adc); | ||
1597 | } | ||
1598 | s->open_mode &= ~(FMODE_READ | FMODE_WRITE); | ||
1599 | wake_up(&s->open_wait); | ||
1600 | mutex_unlock(&s->open_mutex); | ||
1601 | unlock_kernel(); | ||
1602 | return 0; | ||
1603 | } | ||
1604 | |||
1605 | static int solo1_open(struct inode *inode, struct file *file) | ||
1606 | { | ||
1607 | unsigned int minor = iminor(inode); | ||
1608 | DECLARE_WAITQUEUE(wait, current); | ||
1609 | struct solo1_state *s = NULL; | ||
1610 | struct pci_dev *pci_dev = NULL; | ||
1611 | |||
1612 | while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) { | ||
1613 | struct pci_driver *drvr; | ||
1614 | |||
1615 | drvr = pci_dev_driver(pci_dev); | ||
1616 | if (drvr != &solo1_driver) | ||
1617 | continue; | ||
1618 | s = (struct solo1_state*)pci_get_drvdata(pci_dev); | ||
1619 | if (!s) | ||
1620 | continue; | ||
1621 | if (!((s->dev_audio ^ minor) & ~0xf)) | ||
1622 | break; | ||
1623 | } | ||
1624 | if (!s) | ||
1625 | return -ENODEV; | ||
1626 | VALIDATE_STATE(s); | ||
1627 | file->private_data = s; | ||
1628 | /* wait for device to become free */ | ||
1629 | mutex_lock(&s->open_mutex); | ||
1630 | while (s->open_mode & (FMODE_READ | FMODE_WRITE)) { | ||
1631 | if (file->f_flags & O_NONBLOCK) { | ||
1632 | mutex_unlock(&s->open_mutex); | ||
1633 | return -EBUSY; | ||
1634 | } | ||
1635 | add_wait_queue(&s->open_wait, &wait); | ||
1636 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1637 | mutex_unlock(&s->open_mutex); | ||
1638 | schedule(); | ||
1639 | remove_wait_queue(&s->open_wait, &wait); | ||
1640 | set_current_state(TASK_RUNNING); | ||
1641 | if (signal_pending(current)) | ||
1642 | return -ERESTARTSYS; | ||
1643 | mutex_lock(&s->open_mutex); | ||
1644 | } | ||
1645 | s->fmt = AFMT_U8; | ||
1646 | s->channels = 1; | ||
1647 | s->rate = 8000; | ||
1648 | s->clkdiv = 96 | 0x80; | ||
1649 | s->ena = 0; | ||
1650 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; | ||
1651 | s->dma_adc.enabled = 1; | ||
1652 | s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; | ||
1653 | s->dma_dac.enabled = 1; | ||
1654 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
1655 | mutex_unlock(&s->open_mutex); | ||
1656 | prog_codec(s); | ||
1657 | return nonseekable_open(inode, file); | ||
1658 | } | ||
1659 | |||
1660 | static /*const*/ struct file_operations solo1_audio_fops = { | ||
1661 | .owner = THIS_MODULE, | ||
1662 | .llseek = no_llseek, | ||
1663 | .read = solo1_read, | ||
1664 | .write = solo1_write, | ||
1665 | .poll = solo1_poll, | ||
1666 | .ioctl = solo1_ioctl, | ||
1667 | .mmap = solo1_mmap, | ||
1668 | .open = solo1_open, | ||
1669 | .release = solo1_release, | ||
1670 | }; | ||
1671 | |||
1672 | /* --------------------------------------------------------------------- */ | ||
1673 | |||
1674 | /* hold spinlock for the following! */ | ||
1675 | static void solo1_handle_midi(struct solo1_state *s) | ||
1676 | { | ||
1677 | unsigned char ch; | ||
1678 | int wake; | ||
1679 | |||
1680 | if (!(s->mpubase)) | ||
1681 | return; | ||
1682 | wake = 0; | ||
1683 | while (!(inb(s->mpubase+1) & 0x80)) { | ||
1684 | ch = inb(s->mpubase); | ||
1685 | if (s->midi.icnt < MIDIINBUF) { | ||
1686 | s->midi.ibuf[s->midi.iwr] = ch; | ||
1687 | s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF; | ||
1688 | s->midi.icnt++; | ||
1689 | } | ||
1690 | wake = 1; | ||
1691 | } | ||
1692 | if (wake) | ||
1693 | wake_up(&s->midi.iwait); | ||
1694 | wake = 0; | ||
1695 | while (!(inb(s->mpubase+1) & 0x40) && s->midi.ocnt > 0) { | ||
1696 | outb(s->midi.obuf[s->midi.ord], s->mpubase); | ||
1697 | s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF; | ||
1698 | s->midi.ocnt--; | ||
1699 | if (s->midi.ocnt < MIDIOUTBUF-16) | ||
1700 | wake = 1; | ||
1701 | } | ||
1702 | if (wake) | ||
1703 | wake_up(&s->midi.owait); | ||
1704 | } | ||
1705 | |||
1706 | static irqreturn_t solo1_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1707 | { | ||
1708 | struct solo1_state *s = (struct solo1_state *)dev_id; | ||
1709 | unsigned int intsrc; | ||
1710 | |||
1711 | /* fastpath out, to ease interrupt sharing */ | ||
1712 | intsrc = inb(s->iobase+7); /* get interrupt source(s) */ | ||
1713 | if (!intsrc) | ||
1714 | return IRQ_NONE; | ||
1715 | (void)inb(s->sbbase+0xe); /* clear interrupt */ | ||
1716 | spin_lock(&s->lock); | ||
1717 | /* clear audio interrupts first */ | ||
1718 | if (intsrc & 0x20) | ||
1719 | write_mixer(s, 0x7a, read_mixer(s, 0x7a) & 0x7f); | ||
1720 | solo1_update_ptr(s); | ||
1721 | solo1_handle_midi(s); | ||
1722 | spin_unlock(&s->lock); | ||
1723 | return IRQ_HANDLED; | ||
1724 | } | ||
1725 | |||
1726 | static void solo1_midi_timer(unsigned long data) | ||
1727 | { | ||
1728 | struct solo1_state *s = (struct solo1_state *)data; | ||
1729 | unsigned long flags; | ||
1730 | |||
1731 | spin_lock_irqsave(&s->lock, flags); | ||
1732 | solo1_handle_midi(s); | ||
1733 | spin_unlock_irqrestore(&s->lock, flags); | ||
1734 | s->midi.timer.expires = jiffies+1; | ||
1735 | add_timer(&s->midi.timer); | ||
1736 | } | ||
1737 | |||
1738 | /* --------------------------------------------------------------------- */ | ||
1739 | |||
1740 | static ssize_t solo1_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1741 | { | ||
1742 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1743 | DECLARE_WAITQUEUE(wait, current); | ||
1744 | ssize_t ret; | ||
1745 | unsigned long flags; | ||
1746 | unsigned ptr; | ||
1747 | int cnt; | ||
1748 | |||
1749 | VALIDATE_STATE(s); | ||
1750 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1751 | return -EFAULT; | ||
1752 | if (count == 0) | ||
1753 | return 0; | ||
1754 | ret = 0; | ||
1755 | add_wait_queue(&s->midi.iwait, &wait); | ||
1756 | while (count > 0) { | ||
1757 | spin_lock_irqsave(&s->lock, flags); | ||
1758 | ptr = s->midi.ird; | ||
1759 | cnt = MIDIINBUF - ptr; | ||
1760 | if (s->midi.icnt < cnt) | ||
1761 | cnt = s->midi.icnt; | ||
1762 | if (cnt <= 0) | ||
1763 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1764 | spin_unlock_irqrestore(&s->lock, flags); | ||
1765 | if (cnt > count) | ||
1766 | cnt = count; | ||
1767 | if (cnt <= 0) { | ||
1768 | if (file->f_flags & O_NONBLOCK) { | ||
1769 | if (!ret) | ||
1770 | ret = -EAGAIN; | ||
1771 | break; | ||
1772 | } | ||
1773 | schedule(); | ||
1774 | if (signal_pending(current)) { | ||
1775 | if (!ret) | ||
1776 | ret = -ERESTARTSYS; | ||
1777 | break; | ||
1778 | } | ||
1779 | continue; | ||
1780 | } | ||
1781 | if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { | ||
1782 | if (!ret) | ||
1783 | ret = -EFAULT; | ||
1784 | break; | ||
1785 | } | ||
1786 | ptr = (ptr + cnt) % MIDIINBUF; | ||
1787 | spin_lock_irqsave(&s->lock, flags); | ||
1788 | s->midi.ird = ptr; | ||
1789 | s->midi.icnt -= cnt; | ||
1790 | spin_unlock_irqrestore(&s->lock, flags); | ||
1791 | count -= cnt; | ||
1792 | buffer += cnt; | ||
1793 | ret += cnt; | ||
1794 | break; | ||
1795 | } | ||
1796 | __set_current_state(TASK_RUNNING); | ||
1797 | remove_wait_queue(&s->midi.iwait, &wait); | ||
1798 | return ret; | ||
1799 | } | ||
1800 | |||
1801 | static ssize_t solo1_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1802 | { | ||
1803 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1804 | DECLARE_WAITQUEUE(wait, current); | ||
1805 | ssize_t ret; | ||
1806 | unsigned long flags; | ||
1807 | unsigned ptr; | ||
1808 | int cnt; | ||
1809 | |||
1810 | VALIDATE_STATE(s); | ||
1811 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1812 | return -EFAULT; | ||
1813 | if (count == 0) | ||
1814 | return 0; | ||
1815 | ret = 0; | ||
1816 | add_wait_queue(&s->midi.owait, &wait); | ||
1817 | while (count > 0) { | ||
1818 | spin_lock_irqsave(&s->lock, flags); | ||
1819 | ptr = s->midi.owr; | ||
1820 | cnt = MIDIOUTBUF - ptr; | ||
1821 | if (s->midi.ocnt + cnt > MIDIOUTBUF) | ||
1822 | cnt = MIDIOUTBUF - s->midi.ocnt; | ||
1823 | if (cnt <= 0) { | ||
1824 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1825 | solo1_handle_midi(s); | ||
1826 | } | ||
1827 | spin_unlock_irqrestore(&s->lock, flags); | ||
1828 | if (cnt > count) | ||
1829 | cnt = count; | ||
1830 | if (cnt <= 0) { | ||
1831 | if (file->f_flags & O_NONBLOCK) { | ||
1832 | if (!ret) | ||
1833 | ret = -EAGAIN; | ||
1834 | break; | ||
1835 | } | ||
1836 | schedule(); | ||
1837 | if (signal_pending(current)) { | ||
1838 | if (!ret) | ||
1839 | ret = -ERESTARTSYS; | ||
1840 | break; | ||
1841 | } | ||
1842 | continue; | ||
1843 | } | ||
1844 | if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { | ||
1845 | if (!ret) | ||
1846 | ret = -EFAULT; | ||
1847 | break; | ||
1848 | } | ||
1849 | ptr = (ptr + cnt) % MIDIOUTBUF; | ||
1850 | spin_lock_irqsave(&s->lock, flags); | ||
1851 | s->midi.owr = ptr; | ||
1852 | s->midi.ocnt += cnt; | ||
1853 | spin_unlock_irqrestore(&s->lock, flags); | ||
1854 | count -= cnt; | ||
1855 | buffer += cnt; | ||
1856 | ret += cnt; | ||
1857 | spin_lock_irqsave(&s->lock, flags); | ||
1858 | solo1_handle_midi(s); | ||
1859 | spin_unlock_irqrestore(&s->lock, flags); | ||
1860 | } | ||
1861 | __set_current_state(TASK_RUNNING); | ||
1862 | remove_wait_queue(&s->midi.owait, &wait); | ||
1863 | return ret; | ||
1864 | } | ||
1865 | |||
1866 | /* No kernel lock - we have our own spinlock */ | ||
1867 | static unsigned int solo1_midi_poll(struct file *file, struct poll_table_struct *wait) | ||
1868 | { | ||
1869 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1870 | unsigned long flags; | ||
1871 | unsigned int mask = 0; | ||
1872 | |||
1873 | VALIDATE_STATE(s); | ||
1874 | if (file->f_flags & FMODE_WRITE) | ||
1875 | poll_wait(file, &s->midi.owait, wait); | ||
1876 | if (file->f_flags & FMODE_READ) | ||
1877 | poll_wait(file, &s->midi.iwait, wait); | ||
1878 | spin_lock_irqsave(&s->lock, flags); | ||
1879 | if (file->f_flags & FMODE_READ) { | ||
1880 | if (s->midi.icnt > 0) | ||
1881 | mask |= POLLIN | POLLRDNORM; | ||
1882 | } | ||
1883 | if (file->f_flags & FMODE_WRITE) { | ||
1884 | if (s->midi.ocnt < MIDIOUTBUF) | ||
1885 | mask |= POLLOUT | POLLWRNORM; | ||
1886 | } | ||
1887 | spin_unlock_irqrestore(&s->lock, flags); | ||
1888 | return mask; | ||
1889 | } | ||
1890 | |||
1891 | static int solo1_midi_open(struct inode *inode, struct file *file) | ||
1892 | { | ||
1893 | unsigned int minor = iminor(inode); | ||
1894 | DECLARE_WAITQUEUE(wait, current); | ||
1895 | unsigned long flags; | ||
1896 | struct solo1_state *s = NULL; | ||
1897 | struct pci_dev *pci_dev = NULL; | ||
1898 | |||
1899 | while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) { | ||
1900 | struct pci_driver *drvr; | ||
1901 | |||
1902 | drvr = pci_dev_driver(pci_dev); | ||
1903 | if (drvr != &solo1_driver) | ||
1904 | continue; | ||
1905 | s = (struct solo1_state*)pci_get_drvdata(pci_dev); | ||
1906 | if (!s) | ||
1907 | continue; | ||
1908 | if (s->dev_midi == minor) | ||
1909 | break; | ||
1910 | } | ||
1911 | if (!s) | ||
1912 | return -ENODEV; | ||
1913 | VALIDATE_STATE(s); | ||
1914 | file->private_data = s; | ||
1915 | /* wait for device to become free */ | ||
1916 | mutex_lock(&s->open_mutex); | ||
1917 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { | ||
1918 | if (file->f_flags & O_NONBLOCK) { | ||
1919 | mutex_unlock(&s->open_mutex); | ||
1920 | return -EBUSY; | ||
1921 | } | ||
1922 | add_wait_queue(&s->open_wait, &wait); | ||
1923 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1924 | mutex_unlock(&s->open_mutex); | ||
1925 | schedule(); | ||
1926 | remove_wait_queue(&s->open_wait, &wait); | ||
1927 | set_current_state(TASK_RUNNING); | ||
1928 | if (signal_pending(current)) | ||
1929 | return -ERESTARTSYS; | ||
1930 | mutex_lock(&s->open_mutex); | ||
1931 | } | ||
1932 | spin_lock_irqsave(&s->lock, flags); | ||
1933 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
1934 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
1935 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
1936 | outb(0xff, s->mpubase+1); /* reset command */ | ||
1937 | outb(0x3f, s->mpubase+1); /* uart command */ | ||
1938 | if (!(inb(s->mpubase+1) & 0x80)) | ||
1939 | inb(s->mpubase); | ||
1940 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
1941 | outb(0xb0, s->iobase + 7); /* enable A1, A2, MPU irq's */ | ||
1942 | init_timer(&s->midi.timer); | ||
1943 | s->midi.timer.expires = jiffies+1; | ||
1944 | s->midi.timer.data = (unsigned long)s; | ||
1945 | s->midi.timer.function = solo1_midi_timer; | ||
1946 | add_timer(&s->midi.timer); | ||
1947 | } | ||
1948 | if (file->f_mode & FMODE_READ) { | ||
1949 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
1950 | } | ||
1951 | if (file->f_mode & FMODE_WRITE) { | ||
1952 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
1953 | } | ||
1954 | spin_unlock_irqrestore(&s->lock, flags); | ||
1955 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); | ||
1956 | mutex_unlock(&s->open_mutex); | ||
1957 | return nonseekable_open(inode, file); | ||
1958 | } | ||
1959 | |||
1960 | static int solo1_midi_release(struct inode *inode, struct file *file) | ||
1961 | { | ||
1962 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
1963 | DECLARE_WAITQUEUE(wait, current); | ||
1964 | unsigned long flags; | ||
1965 | unsigned count, tmo; | ||
1966 | |||
1967 | VALIDATE_STATE(s); | ||
1968 | |||
1969 | lock_kernel(); | ||
1970 | if (file->f_mode & FMODE_WRITE) { | ||
1971 | add_wait_queue(&s->midi.owait, &wait); | ||
1972 | for (;;) { | ||
1973 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1974 | spin_lock_irqsave(&s->lock, flags); | ||
1975 | count = s->midi.ocnt; | ||
1976 | spin_unlock_irqrestore(&s->lock, flags); | ||
1977 | if (count <= 0) | ||
1978 | break; | ||
1979 | if (signal_pending(current)) | ||
1980 | break; | ||
1981 | if (file->f_flags & O_NONBLOCK) | ||
1982 | break; | ||
1983 | tmo = (count * HZ) / 3100; | ||
1984 | if (!schedule_timeout(tmo ? : 1) && tmo) | ||
1985 | printk(KERN_DEBUG "solo1: midi timed out??\n"); | ||
1986 | } | ||
1987 | remove_wait_queue(&s->midi.owait, &wait); | ||
1988 | set_current_state(TASK_RUNNING); | ||
1989 | } | ||
1990 | mutex_lock(&s->open_mutex); | ||
1991 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); | ||
1992 | spin_lock_irqsave(&s->lock, flags); | ||
1993 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
1994 | outb(0x30, s->iobase + 7); /* enable A1, A2 irq's */ | ||
1995 | del_timer(&s->midi.timer); | ||
1996 | } | ||
1997 | spin_unlock_irqrestore(&s->lock, flags); | ||
1998 | wake_up(&s->open_wait); | ||
1999 | mutex_unlock(&s->open_mutex); | ||
2000 | unlock_kernel(); | ||
2001 | return 0; | ||
2002 | } | ||
2003 | |||
2004 | static /*const*/ struct file_operations solo1_midi_fops = { | ||
2005 | .owner = THIS_MODULE, | ||
2006 | .llseek = no_llseek, | ||
2007 | .read = solo1_midi_read, | ||
2008 | .write = solo1_midi_write, | ||
2009 | .poll = solo1_midi_poll, | ||
2010 | .open = solo1_midi_open, | ||
2011 | .release = solo1_midi_release, | ||
2012 | }; | ||
2013 | |||
2014 | /* --------------------------------------------------------------------- */ | ||
2015 | |||
2016 | static int solo1_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
2017 | { | ||
2018 | static const unsigned char op_offset[18] = { | ||
2019 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, | ||
2020 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, | ||
2021 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 | ||
2022 | }; | ||
2023 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
2024 | struct dm_fm_voice v; | ||
2025 | struct dm_fm_note n; | ||
2026 | struct dm_fm_params p; | ||
2027 | unsigned int io; | ||
2028 | unsigned int regb; | ||
2029 | |||
2030 | switch (cmd) { | ||
2031 | case FM_IOCTL_RESET: | ||
2032 | for (regb = 0xb0; regb < 0xb9; regb++) { | ||
2033 | outb(regb, s->sbbase); | ||
2034 | outb(0, s->sbbase+1); | ||
2035 | outb(regb, s->sbbase+2); | ||
2036 | outb(0, s->sbbase+3); | ||
2037 | } | ||
2038 | return 0; | ||
2039 | |||
2040 | case FM_IOCTL_PLAY_NOTE: | ||
2041 | if (copy_from_user(&n, (void __user *)arg, sizeof(n))) | ||
2042 | return -EFAULT; | ||
2043 | if (n.voice >= 18) | ||
2044 | return -EINVAL; | ||
2045 | if (n.voice >= 9) { | ||
2046 | regb = n.voice - 9; | ||
2047 | io = s->sbbase+2; | ||
2048 | } else { | ||
2049 | regb = n.voice; | ||
2050 | io = s->sbbase; | ||
2051 | } | ||
2052 | outb(0xa0 + regb, io); | ||
2053 | outb(n.fnum & 0xff, io+1); | ||
2054 | outb(0xb0 + regb, io); | ||
2055 | outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1); | ||
2056 | return 0; | ||
2057 | |||
2058 | case FM_IOCTL_SET_VOICE: | ||
2059 | if (copy_from_user(&v, (void __user *)arg, sizeof(v))) | ||
2060 | return -EFAULT; | ||
2061 | if (v.voice >= 18) | ||
2062 | return -EINVAL; | ||
2063 | regb = op_offset[v.voice]; | ||
2064 | io = s->sbbase + ((v.op & 1) << 1); | ||
2065 | outb(0x20 + regb, io); | ||
2066 | outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | | ||
2067 | ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1); | ||
2068 | outb(0x40 + regb, io); | ||
2069 | outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1); | ||
2070 | outb(0x60 + regb, io); | ||
2071 | outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1); | ||
2072 | outb(0x80 + regb, io); | ||
2073 | outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1); | ||
2074 | outb(0xe0 + regb, io); | ||
2075 | outb(v.waveform & 0x7, io+1); | ||
2076 | if (n.voice >= 9) { | ||
2077 | regb = n.voice - 9; | ||
2078 | io = s->sbbase+2; | ||
2079 | } else { | ||
2080 | regb = n.voice; | ||
2081 | io = s->sbbase; | ||
2082 | } | ||
2083 | outb(0xc0 + regb, io); | ||
2084 | outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) | | ||
2085 | (v.connection & 1), io+1); | ||
2086 | return 0; | ||
2087 | |||
2088 | case FM_IOCTL_SET_PARAMS: | ||
2089 | if (copy_from_user(&p, (void __user *)arg, sizeof(p))) | ||
2090 | return -EFAULT; | ||
2091 | outb(0x08, s->sbbase); | ||
2092 | outb((p.kbd_split & 1) << 6, s->sbbase+1); | ||
2093 | outb(0xbd, s->sbbase); | ||
2094 | outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) | | ||
2095 | ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->sbbase+1); | ||
2096 | return 0; | ||
2097 | |||
2098 | case FM_IOCTL_SET_OPL: | ||
2099 | outb(4, s->sbbase+2); | ||
2100 | outb(arg, s->sbbase+3); | ||
2101 | return 0; | ||
2102 | |||
2103 | case FM_IOCTL_SET_MODE: | ||
2104 | outb(5, s->sbbase+2); | ||
2105 | outb(arg & 1, s->sbbase+3); | ||
2106 | return 0; | ||
2107 | |||
2108 | default: | ||
2109 | return -EINVAL; | ||
2110 | } | ||
2111 | } | ||
2112 | |||
2113 | static int solo1_dmfm_open(struct inode *inode, struct file *file) | ||
2114 | { | ||
2115 | unsigned int minor = iminor(inode); | ||
2116 | DECLARE_WAITQUEUE(wait, current); | ||
2117 | struct solo1_state *s = NULL; | ||
2118 | struct pci_dev *pci_dev = NULL; | ||
2119 | |||
2120 | while ((pci_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) { | ||
2121 | struct pci_driver *drvr; | ||
2122 | |||
2123 | drvr = pci_dev_driver(pci_dev); | ||
2124 | if (drvr != &solo1_driver) | ||
2125 | continue; | ||
2126 | s = (struct solo1_state*)pci_get_drvdata(pci_dev); | ||
2127 | if (!s) | ||
2128 | continue; | ||
2129 | if (s->dev_dmfm == minor) | ||
2130 | break; | ||
2131 | } | ||
2132 | if (!s) | ||
2133 | return -ENODEV; | ||
2134 | VALIDATE_STATE(s); | ||
2135 | file->private_data = s; | ||
2136 | /* wait for device to become free */ | ||
2137 | mutex_lock(&s->open_mutex); | ||
2138 | while (s->open_mode & FMODE_DMFM) { | ||
2139 | if (file->f_flags & O_NONBLOCK) { | ||
2140 | mutex_unlock(&s->open_mutex); | ||
2141 | return -EBUSY; | ||
2142 | } | ||
2143 | add_wait_queue(&s->open_wait, &wait); | ||
2144 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2145 | mutex_unlock(&s->open_mutex); | ||
2146 | schedule(); | ||
2147 | remove_wait_queue(&s->open_wait, &wait); | ||
2148 | set_current_state(TASK_RUNNING); | ||
2149 | if (signal_pending(current)) | ||
2150 | return -ERESTARTSYS; | ||
2151 | mutex_lock(&s->open_mutex); | ||
2152 | } | ||
2153 | if (!request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1")) { | ||
2154 | mutex_unlock(&s->open_mutex); | ||
2155 | printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n"); | ||
2156 | return -EBUSY; | ||
2157 | } | ||
2158 | /* init the stuff */ | ||
2159 | outb(1, s->sbbase); | ||
2160 | outb(0x20, s->sbbase+1); /* enable waveforms */ | ||
2161 | outb(4, s->sbbase+2); | ||
2162 | outb(0, s->sbbase+3); /* no 4op enabled */ | ||
2163 | outb(5, s->sbbase+2); | ||
2164 | outb(1, s->sbbase+3); /* enable OPL3 */ | ||
2165 | s->open_mode |= FMODE_DMFM; | ||
2166 | mutex_unlock(&s->open_mutex); | ||
2167 | return nonseekable_open(inode, file); | ||
2168 | } | ||
2169 | |||
2170 | static int solo1_dmfm_release(struct inode *inode, struct file *file) | ||
2171 | { | ||
2172 | struct solo1_state *s = (struct solo1_state *)file->private_data; | ||
2173 | unsigned int regb; | ||
2174 | |||
2175 | VALIDATE_STATE(s); | ||
2176 | lock_kernel(); | ||
2177 | mutex_lock(&s->open_mutex); | ||
2178 | s->open_mode &= ~FMODE_DMFM; | ||
2179 | for (regb = 0xb0; regb < 0xb9; regb++) { | ||
2180 | outb(regb, s->sbbase); | ||
2181 | outb(0, s->sbbase+1); | ||
2182 | outb(regb, s->sbbase+2); | ||
2183 | outb(0, s->sbbase+3); | ||
2184 | } | ||
2185 | release_region(s->sbbase, FMSYNTH_EXTENT); | ||
2186 | wake_up(&s->open_wait); | ||
2187 | mutex_unlock(&s->open_mutex); | ||
2188 | unlock_kernel(); | ||
2189 | return 0; | ||
2190 | } | ||
2191 | |||
2192 | static /*const*/ struct file_operations solo1_dmfm_fops = { | ||
2193 | .owner = THIS_MODULE, | ||
2194 | .llseek = no_llseek, | ||
2195 | .ioctl = solo1_dmfm_ioctl, | ||
2196 | .open = solo1_dmfm_open, | ||
2197 | .release = solo1_dmfm_release, | ||
2198 | }; | ||
2199 | |||
2200 | /* --------------------------------------------------------------------- */ | ||
2201 | |||
2202 | static struct initvol { | ||
2203 | int mixch; | ||
2204 | int vol; | ||
2205 | } initvol[] __devinitdata = { | ||
2206 | { SOUND_MIXER_WRITE_VOLUME, 0x4040 }, | ||
2207 | { SOUND_MIXER_WRITE_PCM, 0x4040 }, | ||
2208 | { SOUND_MIXER_WRITE_SYNTH, 0x4040 }, | ||
2209 | { SOUND_MIXER_WRITE_CD, 0x4040 }, | ||
2210 | { SOUND_MIXER_WRITE_LINE, 0x4040 }, | ||
2211 | { SOUND_MIXER_WRITE_LINE1, 0x4040 }, | ||
2212 | { SOUND_MIXER_WRITE_LINE2, 0x4040 }, | ||
2213 | { SOUND_MIXER_WRITE_RECLEV, 0x4040 }, | ||
2214 | { SOUND_MIXER_WRITE_SPEAKER, 0x4040 }, | ||
2215 | { SOUND_MIXER_WRITE_MIC, 0x4040 } | ||
2216 | }; | ||
2217 | |||
2218 | static int setup_solo1(struct solo1_state *s) | ||
2219 | { | ||
2220 | struct pci_dev *pcidev = s->dev; | ||
2221 | mm_segment_t fs; | ||
2222 | int i, val; | ||
2223 | |||
2224 | /* initialize DDMA base address */ | ||
2225 | printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase); | ||
2226 | pci_write_config_word(pcidev, 0x60, (s->ddmabase & (~0xf)) | 1); | ||
2227 | /* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now) */ | ||
2228 | pci_write_config_dword(pcidev, 0x50, 0); | ||
2229 | /* disable legacy audio address decode */ | ||
2230 | pci_write_config_word(pcidev, 0x40, 0x907f); | ||
2231 | |||
2232 | /* initialize the chips */ | ||
2233 | if (!reset_ctrl(s)) { | ||
2234 | printk(KERN_ERR "esssolo1: cannot reset controller\n"); | ||
2235 | return -1; | ||
2236 | } | ||
2237 | outb(0xb0, s->iobase+7); /* enable A1, A2, MPU irq's */ | ||
2238 | |||
2239 | /* initialize mixer regs */ | ||
2240 | write_mixer(s, 0x7f, 0); /* disable music digital recording */ | ||
2241 | write_mixer(s, 0x7d, 0x0c); /* enable mic preamp, MONO_OUT is 2nd DAC right channel */ | ||
2242 | write_mixer(s, 0x64, 0x45); /* volume control */ | ||
2243 | write_mixer(s, 0x48, 0x10); /* enable music DAC/ES6xx interface */ | ||
2244 | write_mixer(s, 0x50, 0); /* disable spatializer */ | ||
2245 | write_mixer(s, 0x52, 0); | ||
2246 | write_mixer(s, 0x14, 0); /* DAC1 minimum volume */ | ||
2247 | write_mixer(s, 0x71, 0x20); /* enable new 0xA1 reg format */ | ||
2248 | outb(0, s->ddmabase+0xd); /* DMA master clear */ | ||
2249 | outb(1, s->ddmabase+0xf); /* mask channel */ | ||
2250 | /*outb(0, s->ddmabase+0x8);*/ /* enable controller (enable is low active!!) */ | ||
2251 | |||
2252 | pci_set_master(pcidev); /* enable bus mastering */ | ||
2253 | |||
2254 | fs = get_fs(); | ||
2255 | set_fs(KERNEL_DS); | ||
2256 | val = SOUND_MASK_LINE; | ||
2257 | mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); | ||
2258 | for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) { | ||
2259 | val = initvol[i].vol; | ||
2260 | mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); | ||
2261 | } | ||
2262 | val = 1; /* enable mic preamp */ | ||
2263 | mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long)&val); | ||
2264 | set_fs(fs); | ||
2265 | return 0; | ||
2266 | } | ||
2267 | |||
2268 | static int | ||
2269 | solo1_suspend(struct pci_dev *pci_dev, pm_message_t state) { | ||
2270 | struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev); | ||
2271 | if (!s) | ||
2272 | return 1; | ||
2273 | outb(0, s->iobase+6); | ||
2274 | /* DMA master clear */ | ||
2275 | outb(0, s->ddmabase+0xd); | ||
2276 | /* reset sequencer and FIFO */ | ||
2277 | outb(3, s->sbbase+6); | ||
2278 | /* turn off DDMA controller address space */ | ||
2279 | pci_write_config_word(s->dev, 0x60, 0); | ||
2280 | return 0; | ||
2281 | } | ||
2282 | |||
2283 | static int | ||
2284 | solo1_resume(struct pci_dev *pci_dev) { | ||
2285 | struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev); | ||
2286 | if (!s) | ||
2287 | return 1; | ||
2288 | setup_solo1(s); | ||
2289 | return 0; | ||
2290 | } | ||
2291 | |||
2292 | #ifdef SUPPORT_JOYSTICK | ||
2293 | static int __devinit solo1_register_gameport(struct solo1_state *s, int io_port) | ||
2294 | { | ||
2295 | struct gameport *gp; | ||
2296 | |||
2297 | if (!request_region(io_port, GAMEPORT_EXTENT, "ESS Solo1")) { | ||
2298 | printk(KERN_ERR "solo1: gameport io ports are in use\n"); | ||
2299 | return -EBUSY; | ||
2300 | } | ||
2301 | |||
2302 | s->gameport = gp = gameport_allocate_port(); | ||
2303 | if (!gp) { | ||
2304 | printk(KERN_ERR "solo1: can not allocate memory for gameport\n"); | ||
2305 | release_region(io_port, GAMEPORT_EXTENT); | ||
2306 | return -ENOMEM; | ||
2307 | } | ||
2308 | |||
2309 | gameport_set_name(gp, "ESS Solo1 Gameport"); | ||
2310 | gameport_set_phys(gp, "isa%04x/gameport0", io_port); | ||
2311 | gp->dev.parent = &s->dev->dev; | ||
2312 | gp->io = io_port; | ||
2313 | |||
2314 | gameport_register_port(gp); | ||
2315 | |||
2316 | return 0; | ||
2317 | } | ||
2318 | |||
2319 | static inline void solo1_unregister_gameport(struct solo1_state *s) | ||
2320 | { | ||
2321 | if (s->gameport) { | ||
2322 | int gpio = s->gameport->io; | ||
2323 | gameport_unregister_port(s->gameport); | ||
2324 | release_region(gpio, GAMEPORT_EXTENT); | ||
2325 | } | ||
2326 | } | ||
2327 | #else | ||
2328 | static inline int solo1_register_gameport(struct solo1_state *s, int io_port) { return -ENOSYS; } | ||
2329 | static inline void solo1_unregister_gameport(struct solo1_state *s) { } | ||
2330 | #endif /* SUPPORT_JOYSTICK */ | ||
2331 | |||
2332 | static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) | ||
2333 | { | ||
2334 | struct solo1_state *s; | ||
2335 | int gpio; | ||
2336 | int ret; | ||
2337 | |||
2338 | if ((ret=pci_enable_device(pcidev))) | ||
2339 | return ret; | ||
2340 | if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO) || | ||
2341 | !(pci_resource_flags(pcidev, 1) & IORESOURCE_IO) || | ||
2342 | !(pci_resource_flags(pcidev, 2) & IORESOURCE_IO) || | ||
2343 | !(pci_resource_flags(pcidev, 3) & IORESOURCE_IO)) | ||
2344 | return -ENODEV; | ||
2345 | if (pcidev->irq == 0) | ||
2346 | return -ENODEV; | ||
2347 | |||
2348 | /* Recording requires 24-bit DMA, so attempt to set dma mask | ||
2349 | * to 24 bits first, then 32 bits (playback only) if that fails. | ||
2350 | */ | ||
2351 | if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK) && | ||
2352 | pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) { | ||
2353 | printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n"); | ||
2354 | return -ENODEV; | ||
2355 | } | ||
2356 | |||
2357 | if (!(s = kmalloc(sizeof(struct solo1_state), GFP_KERNEL))) { | ||
2358 | printk(KERN_WARNING "solo1: out of memory\n"); | ||
2359 | return -ENOMEM; | ||
2360 | } | ||
2361 | memset(s, 0, sizeof(struct solo1_state)); | ||
2362 | init_waitqueue_head(&s->dma_adc.wait); | ||
2363 | init_waitqueue_head(&s->dma_dac.wait); | ||
2364 | init_waitqueue_head(&s->open_wait); | ||
2365 | init_waitqueue_head(&s->midi.iwait); | ||
2366 | init_waitqueue_head(&s->midi.owait); | ||
2367 | mutex_init(&s->open_mutex); | ||
2368 | spin_lock_init(&s->lock); | ||
2369 | s->magic = SOLO1_MAGIC; | ||
2370 | s->dev = pcidev; | ||
2371 | s->iobase = pci_resource_start(pcidev, 0); | ||
2372 | s->sbbase = pci_resource_start(pcidev, 1); | ||
2373 | s->vcbase = pci_resource_start(pcidev, 2); | ||
2374 | s->ddmabase = s->vcbase + DDMABASE_OFFSET; | ||
2375 | s->mpubase = pci_resource_start(pcidev, 3); | ||
2376 | gpio = pci_resource_start(pcidev, 4); | ||
2377 | s->irq = pcidev->irq; | ||
2378 | ret = -EBUSY; | ||
2379 | if (!request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1")) { | ||
2380 | printk(KERN_ERR "solo1: io ports in use\n"); | ||
2381 | goto err_region1; | ||
2382 | } | ||
2383 | if (!request_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT, "ESS Solo1")) { | ||
2384 | printk(KERN_ERR "solo1: io ports in use\n"); | ||
2385 | goto err_region2; | ||
2386 | } | ||
2387 | if (!request_region(s->ddmabase, DDMABASE_EXTENT, "ESS Solo1")) { | ||
2388 | printk(KERN_ERR "solo1: io ports in use\n"); | ||
2389 | goto err_region3; | ||
2390 | } | ||
2391 | if (!request_region(s->mpubase, MPUBASE_EXTENT, "ESS Solo1")) { | ||
2392 | printk(KERN_ERR "solo1: io ports in use\n"); | ||
2393 | goto err_region4; | ||
2394 | } | ||
2395 | if ((ret=request_irq(s->irq,solo1_interrupt,IRQF_SHARED,"ESS Solo1",s))) { | ||
2396 | printk(KERN_ERR "solo1: irq %u in use\n", s->irq); | ||
2397 | goto err_irq; | ||
2398 | } | ||
2399 | /* register devices */ | ||
2400 | if ((s->dev_audio = register_sound_dsp(&solo1_audio_fops, -1)) < 0) { | ||
2401 | ret = s->dev_audio; | ||
2402 | goto err_dev1; | ||
2403 | } | ||
2404 | if ((s->dev_mixer = register_sound_mixer(&solo1_mixer_fops, -1)) < 0) { | ||
2405 | ret = s->dev_mixer; | ||
2406 | goto err_dev2; | ||
2407 | } | ||
2408 | if ((s->dev_midi = register_sound_midi(&solo1_midi_fops, -1)) < 0) { | ||
2409 | ret = s->dev_midi; | ||
2410 | goto err_dev3; | ||
2411 | } | ||
2412 | if ((s->dev_dmfm = register_sound_special(&solo1_dmfm_fops, 15 /* ?? */)) < 0) { | ||
2413 | ret = s->dev_dmfm; | ||
2414 | goto err_dev4; | ||
2415 | } | ||
2416 | if (setup_solo1(s)) { | ||
2417 | ret = -EIO; | ||
2418 | goto err; | ||
2419 | } | ||
2420 | /* register gameport */ | ||
2421 | solo1_register_gameport(s, gpio); | ||
2422 | /* store it in the driver field */ | ||
2423 | pci_set_drvdata(pcidev, s); | ||
2424 | return 0; | ||
2425 | |||
2426 | err: | ||
2427 | unregister_sound_special(s->dev_dmfm); | ||
2428 | err_dev4: | ||
2429 | unregister_sound_midi(s->dev_midi); | ||
2430 | err_dev3: | ||
2431 | unregister_sound_mixer(s->dev_mixer); | ||
2432 | err_dev2: | ||
2433 | unregister_sound_dsp(s->dev_audio); | ||
2434 | err_dev1: | ||
2435 | printk(KERN_ERR "solo1: initialisation error\n"); | ||
2436 | free_irq(s->irq, s); | ||
2437 | err_irq: | ||
2438 | release_region(s->mpubase, MPUBASE_EXTENT); | ||
2439 | err_region4: | ||
2440 | release_region(s->ddmabase, DDMABASE_EXTENT); | ||
2441 | err_region3: | ||
2442 | release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT); | ||
2443 | err_region2: | ||
2444 | release_region(s->iobase, IOBASE_EXTENT); | ||
2445 | err_region1: | ||
2446 | kfree(s); | ||
2447 | return ret; | ||
2448 | } | ||
2449 | |||
2450 | static void __devexit solo1_remove(struct pci_dev *dev) | ||
2451 | { | ||
2452 | struct solo1_state *s = pci_get_drvdata(dev); | ||
2453 | |||
2454 | if (!s) | ||
2455 | return; | ||
2456 | /* stop DMA controller */ | ||
2457 | outb(0, s->iobase+6); | ||
2458 | outb(0, s->ddmabase+0xd); /* DMA master clear */ | ||
2459 | outb(3, s->sbbase+6); /* reset sequencer and FIFO */ | ||
2460 | synchronize_irq(s->irq); | ||
2461 | pci_write_config_word(s->dev, 0x60, 0); /* turn off DDMA controller address space */ | ||
2462 | free_irq(s->irq, s); | ||
2463 | solo1_unregister_gameport(s); | ||
2464 | release_region(s->iobase, IOBASE_EXTENT); | ||
2465 | release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT); | ||
2466 | release_region(s->ddmabase, DDMABASE_EXTENT); | ||
2467 | release_region(s->mpubase, MPUBASE_EXTENT); | ||
2468 | unregister_sound_dsp(s->dev_audio); | ||
2469 | unregister_sound_mixer(s->dev_mixer); | ||
2470 | unregister_sound_midi(s->dev_midi); | ||
2471 | unregister_sound_special(s->dev_dmfm); | ||
2472 | kfree(s); | ||
2473 | pci_set_drvdata(dev, NULL); | ||
2474 | } | ||
2475 | |||
2476 | static struct pci_device_id id_table[] = { | ||
2477 | { PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_SOLO1, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
2478 | { 0, } | ||
2479 | }; | ||
2480 | |||
2481 | MODULE_DEVICE_TABLE(pci, id_table); | ||
2482 | |||
2483 | static struct pci_driver solo1_driver = { | ||
2484 | .name = "ESS Solo1", | ||
2485 | .id_table = id_table, | ||
2486 | .probe = solo1_probe, | ||
2487 | .remove = __devexit_p(solo1_remove), | ||
2488 | .suspend = solo1_suspend, | ||
2489 | .resume = solo1_resume, | ||
2490 | }; | ||
2491 | |||
2492 | |||
2493 | static int __init init_solo1(void) | ||
2494 | { | ||
2495 | printk(KERN_INFO "solo1: version v0.20 time " __TIME__ " " __DATE__ "\n"); | ||
2496 | return pci_register_driver(&solo1_driver); | ||
2497 | } | ||
2498 | |||
2499 | /* --------------------------------------------------------------------- */ | ||
2500 | |||
2501 | MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); | ||
2502 | MODULE_DESCRIPTION("ESS Solo1 Driver"); | ||
2503 | MODULE_LICENSE("GPL"); | ||
2504 | |||
2505 | |||
2506 | static void __exit cleanup_solo1(void) | ||
2507 | { | ||
2508 | printk(KERN_INFO "solo1: unloading\n"); | ||
2509 | pci_unregister_driver(&solo1_driver); | ||
2510 | } | ||
2511 | |||
2512 | /* --------------------------------------------------------------------- */ | ||
2513 | |||
2514 | module_init(init_solo1); | ||
2515 | module_exit(cleanup_solo1); | ||
2516 | |||
diff --git a/sound/oss/forte.c b/sound/oss/forte.c deleted file mode 100644 index ea1c0207aef2..000000000000 --- a/sound/oss/forte.c +++ /dev/null | |||
@@ -1,2139 +0,0 @@ | |||
1 | /* | ||
2 | * forte.c - ForteMedia FM801 OSS Driver | ||
3 | * | ||
4 | * Written by Martin K. Petersen <mkp@mkp.net> | ||
5 | * Copyright (C) 2002 Hewlett-Packard Company | ||
6 | * Portions Copyright (C) 2003 Martin K. Petersen | ||
7 | * | ||
8 | * Latest version: http://mkp.net/forte/ | ||
9 | * | ||
10 | * Based upon the ALSA FM801 driver by Jaroslav Kysela and OSS drivers | ||
11 | * by Thomas Sailer, Alan Cox, Zach Brown, and Jeff Garzik. Thanks | ||
12 | * guys! | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License version | ||
16 | * 2 as published by the Free Software Foundation. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, but | ||
19 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
21 | * General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
26 | * USA | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/config.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/kernel.h> | ||
33 | |||
34 | #include <linux/init.h> | ||
35 | #include <linux/spinlock.h> | ||
36 | #include <linux/pci.h> | ||
37 | |||
38 | #include <linux/delay.h> | ||
39 | #include <linux/poll.h> | ||
40 | |||
41 | #include <linux/sound.h> | ||
42 | #include <linux/ac97_codec.h> | ||
43 | #include <linux/interrupt.h> | ||
44 | |||
45 | #include <linux/proc_fs.h> | ||
46 | #include <linux/mutex.h> | ||
47 | |||
48 | #include <asm/uaccess.h> | ||
49 | #include <asm/io.h> | ||
50 | |||
51 | #define DRIVER_NAME "forte" | ||
52 | #define DRIVER_VERSION "$Id: forte.c,v 1.63 2003/03/01 05:32:42 mkp Exp $" | ||
53 | #define PFX DRIVER_NAME ": " | ||
54 | |||
55 | #undef M_DEBUG | ||
56 | |||
57 | #ifdef M_DEBUG | ||
58 | #define DPRINTK(args...) printk(KERN_WARNING args) | ||
59 | #else | ||
60 | #define DPRINTK(args...) | ||
61 | #endif | ||
62 | |||
63 | /* Card capabilities */ | ||
64 | #define FORTE_CAPS (DSP_CAP_MMAP | DSP_CAP_TRIGGER) | ||
65 | |||
66 | /* Supported audio formats */ | ||
67 | #define FORTE_FMTS (AFMT_U8 | AFMT_S16_LE) | ||
68 | |||
69 | /* Buffers */ | ||
70 | #define FORTE_MIN_FRAG_SIZE 256 | ||
71 | #define FORTE_MAX_FRAG_SIZE PAGE_SIZE | ||
72 | #define FORTE_DEF_FRAG_SIZE 256 | ||
73 | #define FORTE_MIN_FRAGMENTS 2 | ||
74 | #define FORTE_MAX_FRAGMENTS 256 | ||
75 | #define FORTE_DEF_FRAGMENTS 2 | ||
76 | #define FORTE_MIN_BUF_MSECS 500 | ||
77 | #define FORTE_MAX_BUF_MSECS 1000 | ||
78 | |||
79 | /* PCI BARs */ | ||
80 | #define FORTE_PCM_VOL 0x00 /* PCM Output Volume */ | ||
81 | #define FORTE_FM_VOL 0x02 /* FM Output Volume */ | ||
82 | #define FORTE_I2S_VOL 0x04 /* I2S Volume */ | ||
83 | #define FORTE_REC_SRC 0x06 /* Record Source */ | ||
84 | #define FORTE_PLY_CTRL 0x08 /* Playback Control */ | ||
85 | #define FORTE_PLY_COUNT 0x0a /* Playback Count */ | ||
86 | #define FORTE_PLY_BUF1 0x0c /* Playback Buffer I */ | ||
87 | #define FORTE_PLY_BUF2 0x10 /* Playback Buffer II */ | ||
88 | #define FORTE_CAP_CTRL 0x14 /* Capture Control */ | ||
89 | #define FORTE_CAP_COUNT 0x16 /* Capture Count */ | ||
90 | #define FORTE_CAP_BUF1 0x18 /* Capture Buffer I */ | ||
91 | #define FORTE_CAP_BUF2 0x1c /* Capture Buffer II */ | ||
92 | #define FORTE_CODEC_CTRL 0x22 /* Codec Control */ | ||
93 | #define FORTE_I2S_MODE 0x24 /* I2S Mode Control */ | ||
94 | #define FORTE_VOLUME 0x26 /* Volume Up/Down/Mute Status */ | ||
95 | #define FORTE_I2C_CTRL 0x29 /* I2C Control */ | ||
96 | #define FORTE_AC97_CMD 0x2a /* AC'97 Command */ | ||
97 | #define FORTE_AC97_DATA 0x2c /* AC'97 Data */ | ||
98 | #define FORTE_MPU401_DATA 0x30 /* MPU401 Data */ | ||
99 | #define FORTE_MPU401_CMD 0x31 /* MPU401 Command */ | ||
100 | #define FORTE_GPIO_CTRL 0x52 /* General Purpose I/O Control */ | ||
101 | #define FORTE_GEN_CTRL 0x54 /* General Control */ | ||
102 | #define FORTE_IRQ_MASK 0x56 /* Interrupt Mask */ | ||
103 | #define FORTE_IRQ_STATUS 0x5a /* Interrupt Status */ | ||
104 | #define FORTE_OPL3_BANK0 0x68 /* OPL3 Status Read / Bank 0 Write */ | ||
105 | #define FORTE_OPL3_DATA0 0x69 /* OPL3 Data 0 Write */ | ||
106 | #define FORTE_OPL3_BANK1 0x6a /* OPL3 Bank 1 Write */ | ||
107 | #define FORTE_OPL3_DATA1 0x6b /* OPL3 Bank 1 Write */ | ||
108 | #define FORTE_POWERDOWN 0x70 /* Blocks Power Down Control */ | ||
109 | |||
110 | #define FORTE_CAP_OFFSET FORTE_CAP_CTRL - FORTE_PLY_CTRL | ||
111 | |||
112 | #define FORTE_AC97_ADDR_SHIFT 10 | ||
113 | |||
114 | /* Playback and record control register bits */ | ||
115 | #define FORTE_BUF1_LAST (1<<1) | ||
116 | #define FORTE_BUF2_LAST (1<<2) | ||
117 | #define FORTE_START (1<<5) | ||
118 | #define FORTE_PAUSE (1<<6) | ||
119 | #define FORTE_IMMED_STOP (1<<7) | ||
120 | #define FORTE_RATE_SHIFT 8 | ||
121 | #define FORTE_RATE_MASK (15 << FORTE_RATE_SHIFT) | ||
122 | #define FORTE_CHANNELS_4 (1<<12) /* Playback only */ | ||
123 | #define FORTE_CHANNELS_6 (2<<12) /* Playback only */ | ||
124 | #define FORTE_CHANNELS_6MS (3<<12) /* Playback only */ | ||
125 | #define FORTE_CHANNELS_MASK (3<<12) | ||
126 | #define FORTE_16BIT (1<<14) | ||
127 | #define FORTE_STEREO (1<<15) | ||
128 | |||
129 | /* IRQ status bits */ | ||
130 | #define FORTE_IRQ_PLAYBACK (1<<8) | ||
131 | #define FORTE_IRQ_CAPTURE (1<<9) | ||
132 | #define FORTE_IRQ_VOLUME (1<<14) | ||
133 | #define FORTE_IRQ_MPU (1<<15) | ||
134 | |||
135 | /* CODEC control */ | ||
136 | #define FORTE_CC_CODEC_RESET (1<<5) | ||
137 | #define FORTE_CC_AC97_RESET (1<<6) | ||
138 | |||
139 | /* AC97 cmd */ | ||
140 | #define FORTE_AC97_WRITE (0<<7) | ||
141 | #define FORTE_AC97_READ (1<<7) | ||
142 | #define FORTE_AC97_DP_INVALID (0<<8) | ||
143 | #define FORTE_AC97_DP_VALID (1<<8) | ||
144 | #define FORTE_AC97_PORT_RDY (0<<9) | ||
145 | #define FORTE_AC97_PORT_BSY (1<<9) | ||
146 | |||
147 | |||
148 | struct forte_channel { | ||
149 | const char *name; | ||
150 | |||
151 | unsigned short ctrl; /* Ctrl BAR contents */ | ||
152 | unsigned long iobase; /* Ctrl BAR address */ | ||
153 | |||
154 | wait_queue_head_t wait; | ||
155 | |||
156 | void *buf; /* Buffer */ | ||
157 | dma_addr_t buf_handle; /* Buffer handle */ | ||
158 | |||
159 | unsigned int record; | ||
160 | unsigned int format; | ||
161 | unsigned int rate; | ||
162 | unsigned int stereo; | ||
163 | |||
164 | unsigned int frag_sz; /* Current fragment size */ | ||
165 | unsigned int frag_num; /* Current # of fragments */ | ||
166 | unsigned int frag_msecs; /* Milliseconds per frag */ | ||
167 | unsigned int buf_sz; /* Current buffer size */ | ||
168 | |||
169 | unsigned int hwptr; /* Tail */ | ||
170 | unsigned int swptr; /* Head */ | ||
171 | unsigned int filled_frags; /* Fragments currently full */ | ||
172 | unsigned int next_buf; /* Index of next buffer */ | ||
173 | |||
174 | unsigned int active; /* Channel currently in use */ | ||
175 | unsigned int mapped; /* mmap */ | ||
176 | |||
177 | unsigned int buf_pages; /* Real size of buffer */ | ||
178 | unsigned int nr_irqs; /* Number of interrupts */ | ||
179 | unsigned int bytes; /* Total bytes */ | ||
180 | unsigned int residue; /* Partial fragment */ | ||
181 | }; | ||
182 | |||
183 | |||
184 | struct forte_chip { | ||
185 | struct pci_dev *pci_dev; | ||
186 | unsigned long iobase; | ||
187 | int irq; | ||
188 | |||
189 | struct mutex open_mutex; /* Device access */ | ||
190 | spinlock_t lock; /* State */ | ||
191 | |||
192 | spinlock_t ac97_lock; | ||
193 | struct ac97_codec *ac97; | ||
194 | |||
195 | int multichannel; | ||
196 | int dsp; /* OSS handle */ | ||
197 | int trigger; /* mmap I/O trigger */ | ||
198 | |||
199 | struct forte_channel play; | ||
200 | struct forte_channel rec; | ||
201 | }; | ||
202 | |||
203 | |||
204 | static int channels[] = { 2, 4, 6, }; | ||
205 | static int rates[] = { 5500, 8000, 9600, 11025, 16000, 19200, | ||
206 | 22050, 32000, 38400, 44100, 48000, }; | ||
207 | |||
208 | static struct forte_chip *forte; | ||
209 | static int found; | ||
210 | |||
211 | |||
212 | /* AC97 Codec -------------------------------------------------------------- */ | ||
213 | |||
214 | |||
215 | /** | ||
216 | * forte_ac97_wait: | ||
217 | * @chip: fm801 instance whose AC97 codec to wait on | ||
218 | * | ||
219 | * FIXME: | ||
220 | * Stop busy-waiting | ||
221 | */ | ||
222 | |||
223 | static inline int | ||
224 | forte_ac97_wait (struct forte_chip *chip) | ||
225 | { | ||
226 | int i = 10000; | ||
227 | |||
228 | while ( (inw (chip->iobase + FORTE_AC97_CMD) & FORTE_AC97_PORT_BSY) | ||
229 | && i-- ) | ||
230 | cpu_relax(); | ||
231 | |||
232 | return i == 0; | ||
233 | } | ||
234 | |||
235 | |||
236 | /** | ||
237 | * forte_ac97_read: | ||
238 | * @codec: AC97 codec to read from | ||
239 | * @reg: register to read | ||
240 | */ | ||
241 | |||
242 | static u16 | ||
243 | forte_ac97_read (struct ac97_codec *codec, u8 reg) | ||
244 | { | ||
245 | u16 ret = 0; | ||
246 | struct forte_chip *chip = codec->private_data; | ||
247 | |||
248 | spin_lock (&chip->ac97_lock); | ||
249 | |||
250 | /* Knock, knock */ | ||
251 | if (forte_ac97_wait (chip)) { | ||
252 | printk (KERN_ERR PFX "ac97_read: Serial bus busy\n"); | ||
253 | goto out; | ||
254 | } | ||
255 | |||
256 | /* Send read command */ | ||
257 | outw (reg | (1<<7), chip->iobase + FORTE_AC97_CMD); | ||
258 | |||
259 | if (forte_ac97_wait (chip)) { | ||
260 | printk (KERN_ERR PFX "ac97_read: Bus busy reading reg 0x%x\n", | ||
261 | reg); | ||
262 | goto out; | ||
263 | } | ||
264 | |||
265 | /* Sanity checking */ | ||
266 | if (inw (chip->iobase + FORTE_AC97_CMD) & FORTE_AC97_DP_INVALID) { | ||
267 | printk (KERN_ERR PFX "ac97_read: Invalid data port"); | ||
268 | goto out; | ||
269 | } | ||
270 | |||
271 | /* Fetch result */ | ||
272 | ret = inw (chip->iobase + FORTE_AC97_DATA); | ||
273 | |||
274 | out: | ||
275 | spin_unlock (&chip->ac97_lock); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | |||
280 | /** | ||
281 | * forte_ac97_write: | ||
282 | * @codec: AC97 codec to send command to | ||
283 | * @reg: register to write | ||
284 | * @val: value to write | ||
285 | */ | ||
286 | |||
287 | static void | ||
288 | forte_ac97_write (struct ac97_codec *codec, u8 reg, u16 val) | ||
289 | { | ||
290 | struct forte_chip *chip = codec->private_data; | ||
291 | |||
292 | spin_lock (&chip->ac97_lock); | ||
293 | |||
294 | /* Knock, knock */ | ||
295 | if (forte_ac97_wait (chip)) { | ||
296 | printk (KERN_ERR PFX "ac97_write: Serial bus busy\n"); | ||
297 | goto out; | ||
298 | } | ||
299 | |||
300 | outw (val, chip->iobase + FORTE_AC97_DATA); | ||
301 | outb (reg | FORTE_AC97_WRITE, chip->iobase + FORTE_AC97_CMD); | ||
302 | |||
303 | /* Wait for completion */ | ||
304 | if (forte_ac97_wait (chip)) { | ||
305 | printk (KERN_ERR PFX "ac97_write: Bus busy after write\n"); | ||
306 | goto out; | ||
307 | } | ||
308 | |||
309 | out: | ||
310 | spin_unlock (&chip->ac97_lock); | ||
311 | } | ||
312 | |||
313 | |||
314 | /* Mixer ------------------------------------------------------------------- */ | ||
315 | |||
316 | |||
317 | /** | ||
318 | * forte_mixer_open: | ||
319 | * @inode: | ||
320 | * @file: | ||
321 | */ | ||
322 | |||
323 | static int | ||
324 | forte_mixer_open (struct inode *inode, struct file *file) | ||
325 | { | ||
326 | struct forte_chip *chip = forte; | ||
327 | file->private_data = chip->ac97; | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | |||
332 | /** | ||
333 | * forte_mixer_release: | ||
334 | * @inode: | ||
335 | * @file: | ||
336 | */ | ||
337 | |||
338 | static int | ||
339 | forte_mixer_release (struct inode *inode, struct file *file) | ||
340 | { | ||
341 | /* We will welease Wodewick */ | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | |||
346 | /** | ||
347 | * forte_mixer_ioctl: | ||
348 | * @inode: | ||
349 | * @file: | ||
350 | */ | ||
351 | |||
352 | static int | ||
353 | forte_mixer_ioctl (struct inode *inode, struct file *file, | ||
354 | unsigned int cmd, unsigned long arg) | ||
355 | { | ||
356 | struct ac97_codec *codec = (struct ac97_codec *) file->private_data; | ||
357 | |||
358 | return codec->mixer_ioctl (codec, cmd, arg); | ||
359 | } | ||
360 | |||
361 | |||
362 | static struct file_operations forte_mixer_fops = { | ||
363 | .owner = THIS_MODULE, | ||
364 | .llseek = no_llseek, | ||
365 | .ioctl = forte_mixer_ioctl, | ||
366 | .open = forte_mixer_open, | ||
367 | .release = forte_mixer_release, | ||
368 | }; | ||
369 | |||
370 | |||
371 | /* Channel ----------------------------------------------------------------- */ | ||
372 | |||
373 | /** | ||
374 | * forte_channel_reset: | ||
375 | * @channel: Channel to reset | ||
376 | * | ||
377 | * Locking: Must be called with lock held. | ||
378 | */ | ||
379 | |||
380 | static void | ||
381 | forte_channel_reset (struct forte_channel *channel) | ||
382 | { | ||
383 | if (!channel || !channel->iobase) | ||
384 | return; | ||
385 | |||
386 | DPRINTK ("%s: channel = %s\n", __FUNCTION__, channel->name); | ||
387 | |||
388 | channel->ctrl &= ~FORTE_START; | ||
389 | outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL); | ||
390 | |||
391 | /* We always play at least two fragments, hence these defaults */ | ||
392 | channel->hwptr = channel->frag_sz; | ||
393 | channel->next_buf = 1; | ||
394 | channel->swptr = 0; | ||
395 | channel->filled_frags = 0; | ||
396 | channel->active = 0; | ||
397 | channel->bytes = 0; | ||
398 | channel->nr_irqs = 0; | ||
399 | channel->mapped = 0; | ||
400 | channel->residue = 0; | ||
401 | } | ||
402 | |||
403 | |||
404 | /** | ||
405 | * forte_channel_start: | ||
406 | * @channel: Channel to start (record/playback) | ||
407 | * | ||
408 | * Locking: Must be called with lock held. | ||
409 | */ | ||
410 | |||
411 | static void inline | ||
412 | forte_channel_start (struct forte_channel *channel) | ||
413 | { | ||
414 | if (!channel || !channel->iobase || channel->active) | ||
415 | return; | ||
416 | |||
417 | channel->ctrl &= ~(FORTE_PAUSE | FORTE_BUF1_LAST | FORTE_BUF2_LAST | ||
418 | | FORTE_IMMED_STOP); | ||
419 | channel->ctrl |= FORTE_START; | ||
420 | channel->active = 1; | ||
421 | outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL); | ||
422 | } | ||
423 | |||
424 | |||
425 | /** | ||
426 | * forte_channel_stop: | ||
427 | * @channel: Channel to stop | ||
428 | * | ||
429 | * Locking: Must be called with lock held. | ||
430 | */ | ||
431 | |||
432 | static void inline | ||
433 | forte_channel_stop (struct forte_channel *channel) | ||
434 | { | ||
435 | if (!channel || !channel->iobase) | ||
436 | return; | ||
437 | |||
438 | channel->ctrl &= ~(FORTE_START | FORTE_PAUSE); | ||
439 | channel->ctrl |= FORTE_IMMED_STOP; | ||
440 | |||
441 | channel->active = 0; | ||
442 | outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL); | ||
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
447 | * forte_channel_pause: | ||
448 | * @channel: Channel to pause | ||
449 | * | ||
450 | * Locking: Must be called with lock held. | ||
451 | */ | ||
452 | |||
453 | static void inline | ||
454 | forte_channel_pause (struct forte_channel *channel) | ||
455 | { | ||
456 | if (!channel || !channel->iobase) | ||
457 | return; | ||
458 | |||
459 | channel->ctrl |= FORTE_PAUSE; | ||
460 | |||
461 | channel->active = 0; | ||
462 | outw (channel->ctrl, channel->iobase + FORTE_PLY_CTRL); | ||
463 | } | ||
464 | |||
465 | |||
466 | /** | ||
467 | * forte_channel_rate: | ||
468 | * @channel: Channel whose rate to set. Playback and record are | ||
469 | * independent. | ||
470 | * @rate: Channel rate in Hz | ||
471 | * | ||
472 | * Locking: Must be called with lock held. | ||
473 | */ | ||
474 | |||
475 | static int | ||
476 | forte_channel_rate (struct forte_channel *channel, unsigned int rate) | ||
477 | { | ||
478 | int new_rate; | ||
479 | |||
480 | if (!channel || !channel->iobase) | ||
481 | return -EINVAL; | ||
482 | |||
483 | /* The FM801 only supports a handful of fixed frequencies. | ||
484 | * We find the value closest to what userland requested. | ||
485 | */ | ||
486 | if (rate <= 6250) { rate = 5500; new_rate = 0; } | ||
487 | else if (rate <= 8800) { rate = 8000; new_rate = 1; } | ||
488 | else if (rate <= 10312) { rate = 9600; new_rate = 2; } | ||
489 | else if (rate <= 13512) { rate = 11025; new_rate = 3; } | ||
490 | else if (rate <= 17600) { rate = 16000; new_rate = 4; } | ||
491 | else if (rate <= 20625) { rate = 19200; new_rate = 5; } | ||
492 | else if (rate <= 27025) { rate = 22050; new_rate = 6; } | ||
493 | else if (rate <= 35200) { rate = 32000; new_rate = 7; } | ||
494 | else if (rate <= 41250) { rate = 38400; new_rate = 8; } | ||
495 | else if (rate <= 46050) { rate = 44100; new_rate = 9; } | ||
496 | else { rate = 48000; new_rate = 10; } | ||
497 | |||
498 | channel->ctrl &= ~FORTE_RATE_MASK; | ||
499 | channel->ctrl |= new_rate << FORTE_RATE_SHIFT; | ||
500 | channel->rate = rate; | ||
501 | |||
502 | DPRINTK ("%s: %s rate = %d\n", __FUNCTION__, channel->name, rate); | ||
503 | |||
504 | return rate; | ||
505 | } | ||
506 | |||
507 | |||
508 | /** | ||
509 | * forte_channel_format: | ||
510 | * @channel: Channel whose audio format to set | ||
511 | * @format: OSS format ID | ||
512 | * | ||
513 | * Locking: Must be called with lock held. | ||
514 | */ | ||
515 | |||
516 | static int | ||
517 | forte_channel_format (struct forte_channel *channel, int format) | ||
518 | { | ||
519 | if (!channel || !channel->iobase) | ||
520 | return -EINVAL; | ||
521 | |||
522 | switch (format) { | ||
523 | |||
524 | case AFMT_QUERY: | ||
525 | break; | ||
526 | |||
527 | case AFMT_U8: | ||
528 | channel->ctrl &= ~FORTE_16BIT; | ||
529 | channel->format = AFMT_U8; | ||
530 | break; | ||
531 | |||
532 | case AFMT_S16_LE: | ||
533 | default: | ||
534 | channel->ctrl |= FORTE_16BIT; | ||
535 | channel->format = AFMT_S16_LE; | ||
536 | break; | ||
537 | } | ||
538 | |||
539 | DPRINTK ("%s: %s want %d format, got %d\n", __FUNCTION__, channel->name, | ||
540 | format, channel->format); | ||
541 | |||
542 | return channel->format; | ||
543 | } | ||
544 | |||
545 | |||
546 | /** | ||
547 | * forte_channel_stereo: | ||
548 | * @channel: Channel to toggle | ||
549 | * @stereo: 0 for Mono, 1 for Stereo | ||
550 | * | ||
551 | * Locking: Must be called with lock held. | ||
552 | */ | ||
553 | |||
554 | static int | ||
555 | forte_channel_stereo (struct forte_channel *channel, unsigned int stereo) | ||
556 | { | ||
557 | int ret; | ||
558 | |||
559 | if (!channel || !channel->iobase) | ||
560 | return -EINVAL; | ||
561 | |||
562 | DPRINTK ("%s: %s stereo = %d\n", __FUNCTION__, channel->name, stereo); | ||
563 | |||
564 | switch (stereo) { | ||
565 | |||
566 | case 0: | ||
567 | channel->ctrl &= ~(FORTE_STEREO | FORTE_CHANNELS_MASK); | ||
568 | channel-> stereo = stereo; | ||
569 | ret = stereo; | ||
570 | break; | ||
571 | |||
572 | case 1: | ||
573 | channel->ctrl &= ~FORTE_CHANNELS_MASK; | ||
574 | channel->ctrl |= FORTE_STEREO; | ||
575 | channel-> stereo = stereo; | ||
576 | ret = stereo; | ||
577 | break; | ||
578 | |||
579 | default: | ||
580 | DPRINTK ("Unsupported channel format"); | ||
581 | ret = -EINVAL; | ||
582 | break; | ||
583 | } | ||
584 | |||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | |||
589 | /** | ||
590 | * forte_channel_buffer: | ||
591 | * @channel: Channel whose buffer to set up | ||
592 | * | ||
593 | * Locking: Must be called with lock held. | ||
594 | */ | ||
595 | |||
596 | static void | ||
597 | forte_channel_buffer (struct forte_channel *channel, int sz, int num) | ||
598 | { | ||
599 | unsigned int msecs, shift; | ||
600 | |||
601 | /* Go away, I'm busy */ | ||
602 | if (channel->filled_frags || channel->bytes) | ||
603 | return; | ||
604 | |||
605 | /* Fragment size must be a power of 2 */ | ||
606 | shift = 0; sz++; | ||
607 | while (sz >>= 1) | ||
608 | shift++; | ||
609 | channel->frag_sz = 1 << shift; | ||
610 | |||
611 | /* Round fragment size to something reasonable */ | ||
612 | if (channel->frag_sz < FORTE_MIN_FRAG_SIZE) | ||
613 | channel->frag_sz = FORTE_MIN_FRAG_SIZE; | ||
614 | |||
615 | if (channel->frag_sz > FORTE_MAX_FRAG_SIZE) | ||
616 | channel->frag_sz = FORTE_MAX_FRAG_SIZE; | ||
617 | |||
618 | /* Find fragment length in milliseconds */ | ||
619 | msecs = channel->frag_sz / | ||
620 | (channel->format == AFMT_S16_LE ? 2 : 1) / | ||
621 | (channel->stereo ? 2 : 1) / | ||
622 | (channel->rate / 1000); | ||
623 | |||
624 | channel->frag_msecs = msecs; | ||
625 | |||
626 | /* Pick a suitable number of fragments */ | ||
627 | if (msecs * num < FORTE_MIN_BUF_MSECS) | ||
628 | num = FORTE_MIN_BUF_MSECS / msecs; | ||
629 | |||
630 | if (msecs * num > FORTE_MAX_BUF_MSECS) | ||
631 | num = FORTE_MAX_BUF_MSECS / msecs; | ||
632 | |||
633 | /* Fragment number must be a power of 2 */ | ||
634 | shift = 0; | ||
635 | while (num >>= 1) | ||
636 | shift++; | ||
637 | channel->frag_num = 1 << (shift + 1); | ||
638 | |||
639 | /* Round fragment number to something reasonable */ | ||
640 | if (channel->frag_num < FORTE_MIN_FRAGMENTS) | ||
641 | channel->frag_num = FORTE_MIN_FRAGMENTS; | ||
642 | |||
643 | if (channel->frag_num > FORTE_MAX_FRAGMENTS) | ||
644 | channel->frag_num = FORTE_MAX_FRAGMENTS; | ||
645 | |||
646 | channel->buf_sz = channel->frag_sz * channel->frag_num; | ||
647 | |||
648 | DPRINTK ("%s: %s frag_sz = %d, frag_num = %d, buf_sz = %d\n", | ||
649 | __FUNCTION__, channel->name, channel->frag_sz, | ||
650 | channel->frag_num, channel->buf_sz); | ||
651 | } | ||
652 | |||
653 | |||
654 | /** | ||
655 | * forte_channel_prep: | ||
656 | * @channel: Channel whose buffer to prepare | ||
657 | * | ||
658 | * Locking: Lock held. | ||
659 | */ | ||
660 | |||
661 | static void | ||
662 | forte_channel_prep (struct forte_channel *channel) | ||
663 | { | ||
664 | struct page *page; | ||
665 | int i; | ||
666 | |||
667 | if (channel->buf) | ||
668 | return; | ||
669 | |||
670 | forte_channel_buffer (channel, channel->frag_sz, channel->frag_num); | ||
671 | channel->buf_pages = channel->buf_sz >> PAGE_SHIFT; | ||
672 | |||
673 | if (channel->buf_sz % PAGE_SIZE) | ||
674 | channel->buf_pages++; | ||
675 | |||
676 | DPRINTK ("%s: %s frag_sz = %d, frag_num = %d, buf_sz = %d, pg = %d\n", | ||
677 | __FUNCTION__, channel->name, channel->frag_sz, | ||
678 | channel->frag_num, channel->buf_sz, channel->buf_pages); | ||
679 | |||
680 | /* DMA buffer */ | ||
681 | channel->buf = pci_alloc_consistent (forte->pci_dev, | ||
682 | channel->buf_pages * PAGE_SIZE, | ||
683 | &channel->buf_handle); | ||
684 | |||
685 | if (!channel->buf || !channel->buf_handle) | ||
686 | BUG(); | ||
687 | |||
688 | page = virt_to_page (channel->buf); | ||
689 | |||
690 | /* FIXME: can this go away ? */ | ||
691 | for (i = 0 ; i < channel->buf_pages ; i++) | ||
692 | SetPageReserved(page++); | ||
693 | |||
694 | /* Prep buffer registers */ | ||
695 | outw (channel->frag_sz - 1, channel->iobase + FORTE_PLY_COUNT); | ||
696 | outl (channel->buf_handle, channel->iobase + FORTE_PLY_BUF1); | ||
697 | outl (channel->buf_handle + channel->frag_sz, | ||
698 | channel->iobase + FORTE_PLY_BUF2); | ||
699 | |||
700 | /* Reset hwptr */ | ||
701 | channel->hwptr = channel->frag_sz; | ||
702 | channel->next_buf = 1; | ||
703 | |||
704 | DPRINTK ("%s: %s buffer @ %p (%p)\n", __FUNCTION__, channel->name, | ||
705 | channel->buf, channel->buf_handle); | ||
706 | } | ||
707 | |||
708 | |||
709 | /** | ||
710 | * forte_channel_drain: | ||
711 | * @chip: | ||
712 | * @channel: | ||
713 | * | ||
714 | * Locking: Don't hold the lock. | ||
715 | */ | ||
716 | |||
717 | static inline int | ||
718 | forte_channel_drain (struct forte_channel *channel) | ||
719 | { | ||
720 | DECLARE_WAITQUEUE (wait, current); | ||
721 | unsigned long flags; | ||
722 | |||
723 | DPRINTK ("%s\n", __FUNCTION__); | ||
724 | |||
725 | if (channel->mapped) { | ||
726 | spin_lock_irqsave (&forte->lock, flags); | ||
727 | forte_channel_stop (channel); | ||
728 | spin_unlock_irqrestore (&forte->lock, flags); | ||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | spin_lock_irqsave (&forte->lock, flags); | ||
733 | add_wait_queue (&channel->wait, &wait); | ||
734 | |||
735 | for (;;) { | ||
736 | if (channel->active == 0 || channel->filled_frags == 1) | ||
737 | break; | ||
738 | |||
739 | spin_unlock_irqrestore (&forte->lock, flags); | ||
740 | |||
741 | __set_current_state (TASK_INTERRUPTIBLE); | ||
742 | schedule(); | ||
743 | |||
744 | spin_lock_irqsave (&forte->lock, flags); | ||
745 | } | ||
746 | |||
747 | forte_channel_stop (channel); | ||
748 | forte_channel_reset (channel); | ||
749 | set_current_state (TASK_RUNNING); | ||
750 | remove_wait_queue (&channel->wait, &wait); | ||
751 | spin_unlock_irqrestore (&forte->lock, flags); | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | |||
757 | /** | ||
758 | * forte_channel_init: | ||
759 | * @chip: Forte chip instance the channel hangs off | ||
760 | * @channel: Channel to initialize | ||
761 | * | ||
762 | * Description: | ||
763 | * Initializes a channel, sets defaults, and allocates | ||
764 | * buffers. | ||
765 | * | ||
766 | * Locking: No lock held. | ||
767 | */ | ||
768 | |||
769 | static int | ||
770 | forte_channel_init (struct forte_chip *chip, struct forte_channel *channel) | ||
771 | { | ||
772 | DPRINTK ("%s: chip iobase @ %p\n", __FUNCTION__, (void *)chip->iobase); | ||
773 | |||
774 | spin_lock_irq (&chip->lock); | ||
775 | memset (channel, 0x0, sizeof (*channel)); | ||
776 | |||
777 | if (channel == &chip->play) { | ||
778 | channel->name = "PCM_OUT"; | ||
779 | channel->iobase = chip->iobase; | ||
780 | DPRINTK ("%s: PCM-OUT iobase @ %p\n", __FUNCTION__, | ||
781 | (void *) channel->iobase); | ||
782 | } | ||
783 | else if (channel == &chip->rec) { | ||
784 | channel->name = "PCM_IN"; | ||
785 | channel->iobase = chip->iobase + FORTE_CAP_OFFSET; | ||
786 | channel->record = 1; | ||
787 | DPRINTK ("%s: PCM-IN iobase @ %p\n", __FUNCTION__, | ||
788 | (void *) channel->iobase); | ||
789 | } | ||
790 | else | ||
791 | BUG(); | ||
792 | |||
793 | init_waitqueue_head (&channel->wait); | ||
794 | |||
795 | /* Defaults: 48kHz, 16-bit, stereo */ | ||
796 | channel->ctrl = inw (channel->iobase + FORTE_PLY_CTRL); | ||
797 | forte_channel_reset (channel); | ||
798 | forte_channel_stereo (channel, 1); | ||
799 | forte_channel_format (channel, AFMT_S16_LE); | ||
800 | forte_channel_rate (channel, 48000); | ||
801 | channel->frag_sz = FORTE_DEF_FRAG_SIZE; | ||
802 | channel->frag_num = FORTE_DEF_FRAGMENTS; | ||
803 | |||
804 | chip->trigger = 0; | ||
805 | spin_unlock_irq (&chip->lock); | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | |||
811 | /** | ||
812 | * forte_channel_free: | ||
813 | * @chip: Chip this channel hangs off | ||
814 | * @channel: Channel to nuke | ||
815 | * | ||
816 | * Description: | ||
817 | * Resets channel and frees buffers. | ||
818 | * | ||
819 | * Locking: Hold your horses. | ||
820 | */ | ||
821 | |||
822 | static void | ||
823 | forte_channel_free (struct forte_chip *chip, struct forte_channel *channel) | ||
824 | { | ||
825 | DPRINTK ("%s: %s\n", __FUNCTION__, channel->name); | ||
826 | |||
827 | if (!channel->buf_handle) | ||
828 | return; | ||
829 | |||
830 | pci_free_consistent (chip->pci_dev, channel->buf_pages * PAGE_SIZE, | ||
831 | channel->buf, channel->buf_handle); | ||
832 | |||
833 | memset (channel, 0x0, sizeof (*channel)); | ||
834 | } | ||
835 | |||
836 | |||
837 | /* DSP --------------------------------------------------------------------- */ | ||
838 | |||
839 | |||
840 | /** | ||
841 | * forte_dsp_ioctl: | ||
842 | */ | ||
843 | |||
844 | static int | ||
845 | forte_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd, | ||
846 | unsigned long arg) | ||
847 | { | ||
848 | int ival=0, ret, rval=0, rd, wr, count; | ||
849 | struct forte_chip *chip; | ||
850 | struct audio_buf_info abi; | ||
851 | struct count_info cinfo; | ||
852 | void __user *argp = (void __user *)arg; | ||
853 | int __user *p = argp; | ||
854 | |||
855 | chip = file->private_data; | ||
856 | |||
857 | if (file->f_mode & FMODE_WRITE) | ||
858 | wr = 1; | ||
859 | else | ||
860 | wr = 0; | ||
861 | |||
862 | if (file->f_mode & FMODE_READ) | ||
863 | rd = 1; | ||
864 | else | ||
865 | rd = 0; | ||
866 | |||
867 | switch (cmd) { | ||
868 | |||
869 | case OSS_GETVERSION: | ||
870 | return put_user (SOUND_VERSION, p); | ||
871 | |||
872 | case SNDCTL_DSP_GETCAPS: | ||
873 | DPRINTK ("%s: GETCAPS\n", __FUNCTION__); | ||
874 | |||
875 | ival = FORTE_CAPS; /* DUPLEX */ | ||
876 | return put_user (ival, p); | ||
877 | |||
878 | case SNDCTL_DSP_GETFMTS: | ||
879 | DPRINTK ("%s: GETFMTS\n", __FUNCTION__); | ||
880 | |||
881 | ival = FORTE_FMTS; /* U8, 16LE */ | ||
882 | return put_user (ival, p); | ||
883 | |||
884 | case SNDCTL_DSP_SETFMT: /* U8, 16LE */ | ||
885 | DPRINTK ("%s: SETFMT\n", __FUNCTION__); | ||
886 | |||
887 | if (get_user (ival, p)) | ||
888 | return -EFAULT; | ||
889 | |||
890 | spin_lock_irq (&chip->lock); | ||
891 | |||
892 | if (rd) { | ||
893 | forte_channel_stop (&chip->rec); | ||
894 | rval = forte_channel_format (&chip->rec, ival); | ||
895 | } | ||
896 | |||
897 | if (wr) { | ||
898 | forte_channel_stop (&chip->rec); | ||
899 | rval = forte_channel_format (&chip->play, ival); | ||
900 | } | ||
901 | |||
902 | spin_unlock_irq (&chip->lock); | ||
903 | |||
904 | return put_user (rval, p); | ||
905 | |||
906 | case SNDCTL_DSP_STEREO: /* 0 - mono, 1 - stereo */ | ||
907 | DPRINTK ("%s: STEREO\n", __FUNCTION__); | ||
908 | |||
909 | if (get_user (ival, p)) | ||
910 | return -EFAULT; | ||
911 | |||
912 | spin_lock_irq (&chip->lock); | ||
913 | |||
914 | if (rd) { | ||
915 | forte_channel_stop (&chip->rec); | ||
916 | rval = forte_channel_stereo (&chip->rec, ival); | ||
917 | } | ||
918 | |||
919 | if (wr) { | ||
920 | forte_channel_stop (&chip->rec); | ||
921 | rval = forte_channel_stereo (&chip->play, ival); | ||
922 | } | ||
923 | |||
924 | spin_unlock_irq (&chip->lock); | ||
925 | |||
926 | return put_user (rval, p); | ||
927 | |||
928 | case SNDCTL_DSP_CHANNELS: /* 1 - mono, 2 - stereo */ | ||
929 | DPRINTK ("%s: CHANNELS\n", __FUNCTION__); | ||
930 | |||
931 | if (get_user (ival, p)) | ||
932 | return -EFAULT; | ||
933 | |||
934 | spin_lock_irq (&chip->lock); | ||
935 | |||
936 | if (rd) { | ||
937 | forte_channel_stop (&chip->rec); | ||
938 | rval = forte_channel_stereo (&chip->rec, ival-1) + 1; | ||
939 | } | ||
940 | |||
941 | if (wr) { | ||
942 | forte_channel_stop (&chip->play); | ||
943 | rval = forte_channel_stereo (&chip->play, ival-1) + 1; | ||
944 | } | ||
945 | |||
946 | spin_unlock_irq (&chip->lock); | ||
947 | |||
948 | return put_user (rval, p); | ||
949 | |||
950 | case SNDCTL_DSP_SPEED: | ||
951 | DPRINTK ("%s: SPEED\n", __FUNCTION__); | ||
952 | |||
953 | if (get_user (ival, p)) | ||
954 | return -EFAULT; | ||
955 | |||
956 | spin_lock_irq (&chip->lock); | ||
957 | |||
958 | if (rd) { | ||
959 | forte_channel_stop (&chip->rec); | ||
960 | rval = forte_channel_rate (&chip->rec, ival); | ||
961 | } | ||
962 | |||
963 | if (wr) { | ||
964 | forte_channel_stop (&chip->play); | ||
965 | rval = forte_channel_rate (&chip->play, ival); | ||
966 | } | ||
967 | |||
968 | spin_unlock_irq (&chip->lock); | ||
969 | |||
970 | return put_user(rval, p); | ||
971 | |||
972 | case SNDCTL_DSP_GETBLKSIZE: | ||
973 | DPRINTK ("%s: GETBLKSIZE\n", __FUNCTION__); | ||
974 | |||
975 | spin_lock_irq (&chip->lock); | ||
976 | |||
977 | if (rd) | ||
978 | ival = chip->rec.frag_sz; | ||
979 | |||
980 | if (wr) | ||
981 | ival = chip->play.frag_sz; | ||
982 | |||
983 | spin_unlock_irq (&chip->lock); | ||
984 | |||
985 | return put_user (ival, p); | ||
986 | |||
987 | case SNDCTL_DSP_RESET: | ||
988 | DPRINTK ("%s: RESET\n", __FUNCTION__); | ||
989 | |||
990 | spin_lock_irq (&chip->lock); | ||
991 | |||
992 | if (rd) | ||
993 | forte_channel_reset (&chip->rec); | ||
994 | |||
995 | if (wr) | ||
996 | forte_channel_reset (&chip->play); | ||
997 | |||
998 | spin_unlock_irq (&chip->lock); | ||
999 | |||
1000 | return 0; | ||
1001 | |||
1002 | case SNDCTL_DSP_SYNC: | ||
1003 | DPRINTK ("%s: SYNC\n", __FUNCTION__); | ||
1004 | |||
1005 | if (wr) | ||
1006 | ret = forte_channel_drain (&chip->play); | ||
1007 | |||
1008 | return 0; | ||
1009 | |||
1010 | case SNDCTL_DSP_POST: | ||
1011 | DPRINTK ("%s: POST\n", __FUNCTION__); | ||
1012 | |||
1013 | if (wr) { | ||
1014 | spin_lock_irq (&chip->lock); | ||
1015 | |||
1016 | if (chip->play.filled_frags) | ||
1017 | forte_channel_start (&chip->play); | ||
1018 | |||
1019 | spin_unlock_irq (&chip->lock); | ||
1020 | } | ||
1021 | |||
1022 | return 0; | ||
1023 | |||
1024 | case SNDCTL_DSP_SETFRAGMENT: | ||
1025 | DPRINTK ("%s: SETFRAGMENT\n", __FUNCTION__); | ||
1026 | |||
1027 | if (get_user (ival, p)) | ||
1028 | return -EFAULT; | ||
1029 | |||
1030 | spin_lock_irq (&chip->lock); | ||
1031 | |||
1032 | if (rd) { | ||
1033 | forte_channel_buffer (&chip->rec, ival & 0xffff, | ||
1034 | (ival >> 16) & 0xffff); | ||
1035 | ival = (chip->rec.frag_num << 16) + chip->rec.frag_sz; | ||
1036 | } | ||
1037 | |||
1038 | if (wr) { | ||
1039 | forte_channel_buffer (&chip->play, ival & 0xffff, | ||
1040 | (ival >> 16) & 0xffff); | ||
1041 | ival = (chip->play.frag_num << 16) +chip->play.frag_sz; | ||
1042 | } | ||
1043 | |||
1044 | spin_unlock_irq (&chip->lock); | ||
1045 | |||
1046 | return put_user (ival, p); | ||
1047 | |||
1048 | case SNDCTL_DSP_GETISPACE: | ||
1049 | DPRINTK ("%s: GETISPACE\n", __FUNCTION__); | ||
1050 | |||
1051 | if (!rd) | ||
1052 | return -EINVAL; | ||
1053 | |||
1054 | spin_lock_irq (&chip->lock); | ||
1055 | |||
1056 | abi.fragstotal = chip->rec.frag_num; | ||
1057 | abi.fragsize = chip->rec.frag_sz; | ||
1058 | |||
1059 | if (chip->rec.mapped) { | ||
1060 | abi.fragments = chip->rec.frag_num - 2; | ||
1061 | abi.bytes = abi.fragments * abi.fragsize; | ||
1062 | } | ||
1063 | else { | ||
1064 | abi.fragments = chip->rec.filled_frags; | ||
1065 | abi.bytes = abi.fragments * abi.fragsize; | ||
1066 | } | ||
1067 | |||
1068 | spin_unlock_irq (&chip->lock); | ||
1069 | |||
1070 | return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0; | ||
1071 | |||
1072 | case SNDCTL_DSP_GETIPTR: | ||
1073 | DPRINTK ("%s: GETIPTR\n", __FUNCTION__); | ||
1074 | |||
1075 | if (!rd) | ||
1076 | return -EINVAL; | ||
1077 | |||
1078 | spin_lock_irq (&chip->lock); | ||
1079 | |||
1080 | if (chip->rec.active) | ||
1081 | cinfo.ptr = chip->rec.hwptr; | ||
1082 | else | ||
1083 | cinfo.ptr = 0; | ||
1084 | |||
1085 | cinfo.bytes = chip->rec.bytes; | ||
1086 | cinfo.blocks = chip->rec.nr_irqs; | ||
1087 | chip->rec.nr_irqs = 0; | ||
1088 | |||
1089 | spin_unlock_irq (&chip->lock); | ||
1090 | |||
1091 | return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0; | ||
1092 | |||
1093 | case SNDCTL_DSP_GETOSPACE: | ||
1094 | if (!wr) | ||
1095 | return -EINVAL; | ||
1096 | |||
1097 | spin_lock_irq (&chip->lock); | ||
1098 | |||
1099 | abi.fragstotal = chip->play.frag_num; | ||
1100 | abi.fragsize = chip->play.frag_sz; | ||
1101 | |||
1102 | if (chip->play.mapped) { | ||
1103 | abi.fragments = chip->play.frag_num - 2; | ||
1104 | abi.bytes = chip->play.buf_sz; | ||
1105 | } | ||
1106 | else { | ||
1107 | abi.fragments = chip->play.frag_num - | ||
1108 | chip->play.filled_frags; | ||
1109 | |||
1110 | if (chip->play.residue) | ||
1111 | abi.fragments--; | ||
1112 | |||
1113 | abi.bytes = abi.fragments * abi.fragsize + | ||
1114 | chip->play.residue; | ||
1115 | } | ||
1116 | |||
1117 | spin_unlock_irq (&chip->lock); | ||
1118 | |||
1119 | return copy_to_user (argp, &abi, sizeof (abi)) ? -EFAULT : 0; | ||
1120 | |||
1121 | case SNDCTL_DSP_GETOPTR: | ||
1122 | if (!wr) | ||
1123 | return -EINVAL; | ||
1124 | |||
1125 | spin_lock_irq (&chip->lock); | ||
1126 | |||
1127 | if (chip->play.active) | ||
1128 | cinfo.ptr = chip->play.hwptr; | ||
1129 | else | ||
1130 | cinfo.ptr = 0; | ||
1131 | |||
1132 | cinfo.bytes = chip->play.bytes; | ||
1133 | cinfo.blocks = chip->play.nr_irqs; | ||
1134 | chip->play.nr_irqs = 0; | ||
1135 | |||
1136 | spin_unlock_irq (&chip->lock); | ||
1137 | |||
1138 | return copy_to_user (argp, &cinfo, sizeof (cinfo)) ? -EFAULT : 0; | ||
1139 | |||
1140 | case SNDCTL_DSP_GETODELAY: | ||
1141 | if (!wr) | ||
1142 | return -EINVAL; | ||
1143 | |||
1144 | spin_lock_irq (&chip->lock); | ||
1145 | |||
1146 | if (!chip->play.active) { | ||
1147 | ival = 0; | ||
1148 | } | ||
1149 | else if (chip->play.mapped) { | ||
1150 | count = inw (chip->play.iobase + FORTE_PLY_COUNT) + 1; | ||
1151 | ival = chip->play.frag_sz - count; | ||
1152 | } | ||
1153 | else { | ||
1154 | ival = chip->play.filled_frags * chip->play.frag_sz; | ||
1155 | |||
1156 | if (chip->play.residue) | ||
1157 | ival += chip->play.frag_sz - chip->play.residue; | ||
1158 | } | ||
1159 | |||
1160 | spin_unlock_irq (&chip->lock); | ||
1161 | |||
1162 | return put_user (ival, p); | ||
1163 | |||
1164 | case SNDCTL_DSP_SETDUPLEX: | ||
1165 | DPRINTK ("%s: SETDUPLEX\n", __FUNCTION__); | ||
1166 | |||
1167 | return -EINVAL; | ||
1168 | |||
1169 | case SNDCTL_DSP_GETTRIGGER: | ||
1170 | DPRINTK ("%s: GETTRIGGER\n", __FUNCTION__); | ||
1171 | |||
1172 | return put_user (chip->trigger, p); | ||
1173 | |||
1174 | case SNDCTL_DSP_SETTRIGGER: | ||
1175 | |||
1176 | if (get_user (ival, p)) | ||
1177 | return -EFAULT; | ||
1178 | |||
1179 | DPRINTK ("%s: SETTRIGGER %d\n", __FUNCTION__, ival); | ||
1180 | |||
1181 | if (wr) { | ||
1182 | spin_lock_irq (&chip->lock); | ||
1183 | |||
1184 | if (ival & PCM_ENABLE_OUTPUT) | ||
1185 | forte_channel_start (&chip->play); | ||
1186 | else { | ||
1187 | chip->trigger = 1; | ||
1188 | forte_channel_prep (&chip->play); | ||
1189 | forte_channel_stop (&chip->play); | ||
1190 | } | ||
1191 | |||
1192 | spin_unlock_irq (&chip->lock); | ||
1193 | } | ||
1194 | else if (rd) { | ||
1195 | spin_lock_irq (&chip->lock); | ||
1196 | |||
1197 | if (ival & PCM_ENABLE_INPUT) | ||
1198 | forte_channel_start (&chip->rec); | ||
1199 | else { | ||
1200 | chip->trigger = 1; | ||
1201 | forte_channel_prep (&chip->rec); | ||
1202 | forte_channel_stop (&chip->rec); | ||
1203 | } | ||
1204 | |||
1205 | spin_unlock_irq (&chip->lock); | ||
1206 | } | ||
1207 | |||
1208 | return 0; | ||
1209 | |||
1210 | case SOUND_PCM_READ_RATE: | ||
1211 | DPRINTK ("%s: PCM_READ_RATE\n", __FUNCTION__); | ||
1212 | return put_user (chip->play.rate, p); | ||
1213 | |||
1214 | case SOUND_PCM_READ_CHANNELS: | ||
1215 | DPRINTK ("%s: PCM_READ_CHANNELS\n", __FUNCTION__); | ||
1216 | return put_user (chip->play.stereo, p); | ||
1217 | |||
1218 | case SOUND_PCM_READ_BITS: | ||
1219 | DPRINTK ("%s: PCM_READ_BITS\n", __FUNCTION__); | ||
1220 | return put_user (chip->play.format, p); | ||
1221 | |||
1222 | case SNDCTL_DSP_NONBLOCK: | ||
1223 | DPRINTK ("%s: DSP_NONBLOCK\n", __FUNCTION__); | ||
1224 | file->f_flags |= O_NONBLOCK; | ||
1225 | return 0; | ||
1226 | |||
1227 | default: | ||
1228 | DPRINTK ("Unsupported ioctl: %x (%p)\n", cmd, argp); | ||
1229 | break; | ||
1230 | } | ||
1231 | |||
1232 | return -EINVAL; | ||
1233 | } | ||
1234 | |||
1235 | |||
1236 | /** | ||
1237 | * forte_dsp_open: | ||
1238 | */ | ||
1239 | |||
1240 | static int | ||
1241 | forte_dsp_open (struct inode *inode, struct file *file) | ||
1242 | { | ||
1243 | struct forte_chip *chip = forte; /* FIXME: HACK FROM HELL! */ | ||
1244 | |||
1245 | if (file->f_flags & O_NONBLOCK) { | ||
1246 | if (!mutex_trylock(&chip->open_mutex)) { | ||
1247 | DPRINTK ("%s: returning -EAGAIN\n", __FUNCTION__); | ||
1248 | return -EAGAIN; | ||
1249 | } | ||
1250 | } | ||
1251 | else { | ||
1252 | if (mutex_lock_interruptible(&chip->open_mutex)) { | ||
1253 | DPRINTK ("%s: returning -ERESTARTSYS\n", __FUNCTION__); | ||
1254 | return -ERESTARTSYS; | ||
1255 | } | ||
1256 | } | ||
1257 | |||
1258 | file->private_data = forte; | ||
1259 | |||
1260 | DPRINTK ("%s: dsp opened by %d\n", __FUNCTION__, current->pid); | ||
1261 | |||
1262 | if (file->f_mode & FMODE_WRITE) | ||
1263 | forte_channel_init (forte, &forte->play); | ||
1264 | |||
1265 | if (file->f_mode & FMODE_READ) | ||
1266 | forte_channel_init (forte, &forte->rec); | ||
1267 | |||
1268 | return nonseekable_open(inode, file); | ||
1269 | } | ||
1270 | |||
1271 | |||
1272 | /** | ||
1273 | * forte_dsp_release: | ||
1274 | */ | ||
1275 | |||
1276 | static int | ||
1277 | forte_dsp_release (struct inode *inode, struct file *file) | ||
1278 | { | ||
1279 | struct forte_chip *chip = file->private_data; | ||
1280 | int ret = 0; | ||
1281 | |||
1282 | DPRINTK ("%s: chip @ %p\n", __FUNCTION__, chip); | ||
1283 | |||
1284 | if (file->f_mode & FMODE_WRITE) { | ||
1285 | forte_channel_drain (&chip->play); | ||
1286 | |||
1287 | spin_lock_irq (&chip->lock); | ||
1288 | |||
1289 | forte_channel_free (chip, &chip->play); | ||
1290 | |||
1291 | spin_unlock_irq (&chip->lock); | ||
1292 | } | ||
1293 | |||
1294 | if (file->f_mode & FMODE_READ) { | ||
1295 | while (chip->rec.filled_frags > 0) | ||
1296 | interruptible_sleep_on (&chip->rec.wait); | ||
1297 | |||
1298 | spin_lock_irq (&chip->lock); | ||
1299 | |||
1300 | forte_channel_stop (&chip->rec); | ||
1301 | forte_channel_free (chip, &chip->rec); | ||
1302 | |||
1303 | spin_unlock_irq (&chip->lock); | ||
1304 | } | ||
1305 | |||
1306 | mutex_unlock(&chip->open_mutex); | ||
1307 | |||
1308 | return ret; | ||
1309 | } | ||
1310 | |||
1311 | |||
1312 | /** | ||
1313 | * forte_dsp_poll: | ||
1314 | * | ||
1315 | */ | ||
1316 | |||
1317 | static unsigned int | ||
1318 | forte_dsp_poll (struct file *file, struct poll_table_struct *wait) | ||
1319 | { | ||
1320 | struct forte_chip *chip; | ||
1321 | struct forte_channel *channel; | ||
1322 | unsigned int mask = 0; | ||
1323 | |||
1324 | chip = file->private_data; | ||
1325 | |||
1326 | if (file->f_mode & FMODE_WRITE) { | ||
1327 | channel = &chip->play; | ||
1328 | |||
1329 | if (channel->active) | ||
1330 | poll_wait (file, &channel->wait, wait); | ||
1331 | |||
1332 | spin_lock_irq (&chip->lock); | ||
1333 | |||
1334 | if (channel->frag_num - channel->filled_frags > 0) | ||
1335 | mask |= POLLOUT | POLLWRNORM; | ||
1336 | |||
1337 | spin_unlock_irq (&chip->lock); | ||
1338 | } | ||
1339 | |||
1340 | if (file->f_mode & FMODE_READ) { | ||
1341 | channel = &chip->rec; | ||
1342 | |||
1343 | if (channel->active) | ||
1344 | poll_wait (file, &channel->wait, wait); | ||
1345 | |||
1346 | spin_lock_irq (&chip->lock); | ||
1347 | |||
1348 | if (channel->filled_frags > 0) | ||
1349 | mask |= POLLIN | POLLRDNORM; | ||
1350 | |||
1351 | spin_unlock_irq (&chip->lock); | ||
1352 | } | ||
1353 | |||
1354 | return mask; | ||
1355 | } | ||
1356 | |||
1357 | |||
1358 | /** | ||
1359 | * forte_dsp_mmap: | ||
1360 | */ | ||
1361 | |||
1362 | static int | ||
1363 | forte_dsp_mmap (struct file *file, struct vm_area_struct *vma) | ||
1364 | { | ||
1365 | struct forte_chip *chip; | ||
1366 | struct forte_channel *channel; | ||
1367 | unsigned long size; | ||
1368 | int ret; | ||
1369 | |||
1370 | chip = file->private_data; | ||
1371 | |||
1372 | DPRINTK ("%s: start %lXh, size %ld, pgoff %ld\n", __FUNCTION__, | ||
1373 | vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_pgoff); | ||
1374 | |||
1375 | spin_lock_irq (&chip->lock); | ||
1376 | |||
1377 | if (vma->vm_flags & VM_WRITE && chip->play.active) { | ||
1378 | ret = -EBUSY; | ||
1379 | goto out; | ||
1380 | } | ||
1381 | |||
1382 | if (vma->vm_flags & VM_READ && chip->rec.active) { | ||
1383 | ret = -EBUSY; | ||
1384 | goto out; | ||
1385 | } | ||
1386 | |||
1387 | if (file->f_mode & FMODE_WRITE) | ||
1388 | channel = &chip->play; | ||
1389 | else if (file->f_mode & FMODE_READ) | ||
1390 | channel = &chip->rec; | ||
1391 | else { | ||
1392 | ret = -EINVAL; | ||
1393 | goto out; | ||
1394 | } | ||
1395 | |||
1396 | forte_channel_prep (channel); | ||
1397 | channel->mapped = 1; | ||
1398 | |||
1399 | if (vma->vm_pgoff != 0) { | ||
1400 | ret = -EINVAL; | ||
1401 | goto out; | ||
1402 | } | ||
1403 | |||
1404 | size = vma->vm_end - vma->vm_start; | ||
1405 | |||
1406 | if (size > channel->buf_pages * PAGE_SIZE) { | ||
1407 | DPRINTK ("%s: size (%ld) > buf_sz (%d) \n", __FUNCTION__, | ||
1408 | size, channel->buf_sz); | ||
1409 | ret = -EINVAL; | ||
1410 | goto out; | ||
1411 | } | ||
1412 | |||
1413 | if (remap_pfn_range(vma, vma->vm_start, | ||
1414 | virt_to_phys(channel->buf) >> PAGE_SHIFT, | ||
1415 | size, vma->vm_page_prot)) { | ||
1416 | DPRINTK ("%s: remap el a no worko\n", __FUNCTION__); | ||
1417 | ret = -EAGAIN; | ||
1418 | goto out; | ||
1419 | } | ||
1420 | |||
1421 | ret = 0; | ||
1422 | |||
1423 | out: | ||
1424 | spin_unlock_irq (&chip->lock); | ||
1425 | return ret; | ||
1426 | } | ||
1427 | |||
1428 | |||
1429 | /** | ||
1430 | * forte_dsp_write: | ||
1431 | */ | ||
1432 | |||
1433 | static ssize_t | ||
1434 | forte_dsp_write (struct file *file, const char __user *buffer, size_t bytes, | ||
1435 | loff_t *ppos) | ||
1436 | { | ||
1437 | struct forte_chip *chip; | ||
1438 | struct forte_channel *channel; | ||
1439 | unsigned int i = bytes, sz = 0; | ||
1440 | unsigned long flags; | ||
1441 | |||
1442 | if (!access_ok (VERIFY_READ, buffer, bytes)) | ||
1443 | return -EFAULT; | ||
1444 | |||
1445 | chip = (struct forte_chip *) file->private_data; | ||
1446 | |||
1447 | if (!chip) | ||
1448 | BUG(); | ||
1449 | |||
1450 | channel = &chip->play; | ||
1451 | |||
1452 | if (!channel) | ||
1453 | BUG(); | ||
1454 | |||
1455 | spin_lock_irqsave (&chip->lock, flags); | ||
1456 | |||
1457 | /* Set up buffers with the right fragment size */ | ||
1458 | forte_channel_prep (channel); | ||
1459 | |||
1460 | while (i) { | ||
1461 | /* All fragment buffers in use -> wait */ | ||
1462 | if (channel->frag_num - channel->filled_frags == 0) { | ||
1463 | DECLARE_WAITQUEUE (wait, current); | ||
1464 | |||
1465 | /* For trigger or non-blocking operation, get out */ | ||
1466 | if (chip->trigger || file->f_flags & O_NONBLOCK) { | ||
1467 | spin_unlock_irqrestore (&chip->lock, flags); | ||
1468 | return -EAGAIN; | ||
1469 | } | ||
1470 | |||
1471 | /* Otherwise wait for buffers */ | ||
1472 | add_wait_queue (&channel->wait, &wait); | ||
1473 | |||
1474 | for (;;) { | ||
1475 | spin_unlock_irqrestore (&chip->lock, flags); | ||
1476 | |||
1477 | set_current_state (TASK_INTERRUPTIBLE); | ||
1478 | schedule(); | ||
1479 | |||
1480 | spin_lock_irqsave (&chip->lock, flags); | ||
1481 | |||
1482 | if (channel->frag_num - channel->filled_frags) | ||
1483 | break; | ||
1484 | } | ||
1485 | |||
1486 | remove_wait_queue (&channel->wait, &wait); | ||
1487 | set_current_state (TASK_RUNNING); | ||
1488 | |||
1489 | if (signal_pending (current)) { | ||
1490 | spin_unlock_irqrestore (&chip->lock, flags); | ||
1491 | return -ERESTARTSYS; | ||
1492 | } | ||
1493 | } | ||
1494 | |||
1495 | if (channel->residue) | ||
1496 | sz = channel->residue; | ||
1497 | else if (i > channel->frag_sz) | ||
1498 | sz = channel->frag_sz; | ||
1499 | else | ||
1500 | sz = i; | ||
1501 | |||
1502 | spin_unlock_irqrestore (&chip->lock, flags); | ||
1503 | |||
1504 | if (copy_from_user ((void *) channel->buf + channel->swptr, buffer, sz)) | ||
1505 | return -EFAULT; | ||
1506 | |||
1507 | spin_lock_irqsave (&chip->lock, flags); | ||
1508 | |||
1509 | /* Advance software pointer */ | ||
1510 | buffer += sz; | ||
1511 | channel->swptr += sz; | ||
1512 | channel->swptr %= channel->buf_sz; | ||
1513 | i -= sz; | ||
1514 | |||
1515 | /* Only bump filled_frags if a full fragment has been written */ | ||
1516 | if (channel->swptr % channel->frag_sz == 0) { | ||
1517 | channel->filled_frags++; | ||
1518 | channel->residue = 0; | ||
1519 | } | ||
1520 | else | ||
1521 | channel->residue = channel->frag_sz - sz; | ||
1522 | |||
1523 | /* If playback isn't active, start it */ | ||
1524 | if (channel->active == 0 && chip->trigger == 0) | ||
1525 | forte_channel_start (channel); | ||
1526 | } | ||
1527 | |||
1528 | spin_unlock_irqrestore (&chip->lock, flags); | ||
1529 | |||
1530 | return bytes - i; | ||
1531 | } | ||
1532 | |||
1533 | |||
1534 | /** | ||
1535 | * forte_dsp_read: | ||
1536 | */ | ||
1537 | |||
1538 | static ssize_t | ||
1539 | forte_dsp_read (struct file *file, char __user *buffer, size_t bytes, | ||
1540 | loff_t *ppos) | ||
1541 | { | ||
1542 | struct forte_chip *chip; | ||
1543 | struct forte_channel *channel; | ||
1544 | unsigned int i = bytes, sz; | ||
1545 | unsigned long flags; | ||
1546 | |||
1547 | if (!access_ok (VERIFY_WRITE, buffer, bytes)) | ||
1548 | return -EFAULT; | ||
1549 | |||
1550 | chip = (struct forte_chip *) file->private_data; | ||
1551 | |||
1552 | if (!chip) | ||
1553 | BUG(); | ||
1554 | |||
1555 | channel = &chip->rec; | ||
1556 | |||
1557 | if (!channel) | ||
1558 | BUG(); | ||
1559 | |||
1560 | spin_lock_irqsave (&chip->lock, flags); | ||
1561 | |||
1562 | /* Set up buffers with the right fragment size */ | ||
1563 | forte_channel_prep (channel); | ||
1564 | |||
1565 | /* Start recording */ | ||
1566 | if (!chip->trigger) | ||
1567 | forte_channel_start (channel); | ||
1568 | |||
1569 | while (i) { | ||
1570 | /* No fragment buffers in use -> wait */ | ||
1571 | if (channel->filled_frags == 0) { | ||
1572 | DECLARE_WAITQUEUE (wait, current); | ||
1573 | |||
1574 | /* For trigger mode operation, get out */ | ||
1575 | if (chip->trigger) { | ||
1576 | spin_unlock_irqrestore (&chip->lock, flags); | ||
1577 | return -EAGAIN; | ||
1578 | } | ||
1579 | |||
1580 | add_wait_queue (&channel->wait, &wait); | ||
1581 | |||
1582 | for (;;) { | ||
1583 | if (channel->active == 0) | ||
1584 | break; | ||
1585 | |||
1586 | if (channel->filled_frags) | ||
1587 | break; | ||
1588 | |||
1589 | spin_unlock_irqrestore (&chip->lock, flags); | ||
1590 | |||
1591 | set_current_state (TASK_INTERRUPTIBLE); | ||
1592 | schedule(); | ||
1593 | |||
1594 | spin_lock_irqsave (&chip->lock, flags); | ||
1595 | } | ||
1596 | |||
1597 | set_current_state (TASK_RUNNING); | ||
1598 | remove_wait_queue (&channel->wait, &wait); | ||
1599 | } | ||
1600 | |||
1601 | if (i > channel->frag_sz) | ||
1602 | sz = channel->frag_sz; | ||
1603 | else | ||
1604 | sz = i; | ||
1605 | |||
1606 | spin_unlock_irqrestore (&chip->lock, flags); | ||
1607 | |||
1608 | if (copy_to_user (buffer, (void *)channel->buf+channel->swptr, sz)) { | ||
1609 | DPRINTK ("%s: copy_to_user failed\n", __FUNCTION__); | ||
1610 | return -EFAULT; | ||
1611 | } | ||
1612 | |||
1613 | spin_lock_irqsave (&chip->lock, flags); | ||
1614 | |||
1615 | /* Advance software pointer */ | ||
1616 | buffer += sz; | ||
1617 | if (channel->filled_frags > 0) | ||
1618 | channel->filled_frags--; | ||
1619 | channel->swptr += channel->frag_sz; | ||
1620 | channel->swptr %= channel->buf_sz; | ||
1621 | i -= sz; | ||
1622 | } | ||
1623 | |||
1624 | spin_unlock_irqrestore (&chip->lock, flags); | ||
1625 | |||
1626 | return bytes - i; | ||
1627 | } | ||
1628 | |||
1629 | |||
1630 | static struct file_operations forte_dsp_fops = { | ||
1631 | .owner = THIS_MODULE, | ||
1632 | .llseek = &no_llseek, | ||
1633 | .read = &forte_dsp_read, | ||
1634 | .write = &forte_dsp_write, | ||
1635 | .poll = &forte_dsp_poll, | ||
1636 | .ioctl = &forte_dsp_ioctl, | ||
1637 | .open = &forte_dsp_open, | ||
1638 | .release = &forte_dsp_release, | ||
1639 | .mmap = &forte_dsp_mmap, | ||
1640 | }; | ||
1641 | |||
1642 | |||
1643 | /* Common ------------------------------------------------------------------ */ | ||
1644 | |||
1645 | |||
1646 | /** | ||
1647 | * forte_interrupt: | ||
1648 | */ | ||
1649 | |||
1650 | static irqreturn_t | ||
1651 | forte_interrupt (int irq, void *dev_id, struct pt_regs *regs) | ||
1652 | { | ||
1653 | struct forte_chip *chip = dev_id; | ||
1654 | struct forte_channel *channel = NULL; | ||
1655 | u16 status, count; | ||
1656 | |||
1657 | status = inw (chip->iobase + FORTE_IRQ_STATUS); | ||
1658 | |||
1659 | /* If this is not for us, get outta here ASAP */ | ||
1660 | if ((status & (FORTE_IRQ_PLAYBACK | FORTE_IRQ_CAPTURE)) == 0) | ||
1661 | return IRQ_NONE; | ||
1662 | |||
1663 | if (status & FORTE_IRQ_PLAYBACK) { | ||
1664 | channel = &chip->play; | ||
1665 | |||
1666 | spin_lock (&chip->lock); | ||
1667 | |||
1668 | if (channel->frag_sz == 0) | ||
1669 | goto pack; | ||
1670 | |||
1671 | /* Declare a fragment done */ | ||
1672 | if (channel->filled_frags > 0) | ||
1673 | channel->filled_frags--; | ||
1674 | channel->bytes += channel->frag_sz; | ||
1675 | channel->nr_irqs++; | ||
1676 | |||
1677 | /* Flip-flop between buffer I and II */ | ||
1678 | channel->next_buf ^= 1; | ||
1679 | |||
1680 | /* Advance hardware pointer by fragment size and wrap around */ | ||
1681 | channel->hwptr += channel->frag_sz; | ||
1682 | channel->hwptr %= channel->buf_sz; | ||
1683 | |||
1684 | /* Buffer I or buffer II BAR */ | ||
1685 | outl (channel->buf_handle + channel->hwptr, | ||
1686 | channel->next_buf == 0 ? | ||
1687 | channel->iobase + FORTE_PLY_BUF1 : | ||
1688 | channel->iobase + FORTE_PLY_BUF2); | ||
1689 | |||
1690 | /* If the currently playing fragment is last, schedule pause */ | ||
1691 | if (channel->filled_frags == 1) | ||
1692 | forte_channel_pause (channel); | ||
1693 | |||
1694 | pack: | ||
1695 | /* Acknowledge interrupt */ | ||
1696 | outw (FORTE_IRQ_PLAYBACK, chip->iobase + FORTE_IRQ_STATUS); | ||
1697 | |||
1698 | if (waitqueue_active (&channel->wait)) | ||
1699 | wake_up_all (&channel->wait); | ||
1700 | |||
1701 | spin_unlock (&chip->lock); | ||
1702 | } | ||
1703 | |||
1704 | if (status & FORTE_IRQ_CAPTURE) { | ||
1705 | channel = &chip->rec; | ||
1706 | spin_lock (&chip->lock); | ||
1707 | |||
1708 | /* One fragment filled */ | ||
1709 | channel->filled_frags++; | ||
1710 | |||
1711 | /* Get # of completed bytes */ | ||
1712 | count = inw (channel->iobase + FORTE_PLY_COUNT) + 1; | ||
1713 | |||
1714 | if (count == 0) { | ||
1715 | DPRINTK ("%s: last, filled_frags = %d\n", __FUNCTION__, | ||
1716 | channel->filled_frags); | ||
1717 | channel->filled_frags = 0; | ||
1718 | goto rack; | ||
1719 | } | ||
1720 | |||
1721 | /* Buffer I or buffer II BAR */ | ||
1722 | outl (channel->buf_handle + channel->hwptr, | ||
1723 | channel->next_buf == 0 ? | ||
1724 | channel->iobase + FORTE_PLY_BUF1 : | ||
1725 | channel->iobase + FORTE_PLY_BUF2); | ||
1726 | |||
1727 | /* Flip-flop between buffer I and II */ | ||
1728 | channel->next_buf ^= 1; | ||
1729 | |||
1730 | /* Advance hardware pointer by fragment size and wrap around */ | ||
1731 | channel->hwptr += channel->frag_sz; | ||
1732 | channel->hwptr %= channel->buf_sz; | ||
1733 | |||
1734 | /* Out of buffers */ | ||
1735 | if (channel->filled_frags == channel->frag_num - 1) | ||
1736 | forte_channel_stop (channel); | ||
1737 | rack: | ||
1738 | /* Acknowledge interrupt */ | ||
1739 | outw (FORTE_IRQ_CAPTURE, chip->iobase + FORTE_IRQ_STATUS); | ||
1740 | |||
1741 | spin_unlock (&chip->lock); | ||
1742 | |||
1743 | if (waitqueue_active (&channel->wait)) | ||
1744 | wake_up_all (&channel->wait); | ||
1745 | } | ||
1746 | |||
1747 | return IRQ_HANDLED; | ||
1748 | } | ||
1749 | |||
1750 | |||
1751 | /** | ||
1752 | * forte_proc_read: | ||
1753 | */ | ||
1754 | |||
1755 | static int | ||
1756 | forte_proc_read (char *page, char **start, off_t off, int count, | ||
1757 | int *eof, void *data) | ||
1758 | { | ||
1759 | int i = 0, p_rate, p_chan, r_rate; | ||
1760 | unsigned short p_reg, r_reg; | ||
1761 | |||
1762 | i += sprintf (page, "ForteMedia FM801 OSS Lite driver\n%s\n \n", | ||
1763 | DRIVER_VERSION); | ||
1764 | |||
1765 | if (!forte->iobase) | ||
1766 | return i; | ||
1767 | |||
1768 | p_rate = p_chan = -1; | ||
1769 | p_reg = inw (forte->iobase + FORTE_PLY_CTRL); | ||
1770 | p_rate = (p_reg >> 8) & 15; | ||
1771 | p_chan = (p_reg >> 12) & 3; | ||
1772 | |||
1773 | if (p_rate >= 0 || p_rate <= 10) | ||
1774 | p_rate = rates[p_rate]; | ||
1775 | |||
1776 | if (p_chan >= 0 || p_chan <= 2) | ||
1777 | p_chan = channels[p_chan]; | ||
1778 | |||
1779 | r_rate = -1; | ||
1780 | r_reg = inw (forte->iobase + FORTE_CAP_CTRL); | ||
1781 | r_rate = (r_reg >> 8) & 15; | ||
1782 | |||
1783 | if (r_rate >= 0 || r_rate <= 10) | ||
1784 | r_rate = rates[r_rate]; | ||
1785 | |||
1786 | i += sprintf (page + i, | ||
1787 | " Playback Capture\n" | ||
1788 | "FIFO empty : %-3s %-3s\n" | ||
1789 | "Buf1 Last : %-3s %-3s\n" | ||
1790 | "Buf2 Last : %-3s %-3s\n" | ||
1791 | "Started : %-3s %-3s\n" | ||
1792 | "Paused : %-3s %-3s\n" | ||
1793 | "Immed Stop : %-3s %-3s\n" | ||
1794 | "Rate : %-5d %-5d\n" | ||
1795 | "Channels : %-5d -\n" | ||
1796 | "16-bit : %-3s %-3s\n" | ||
1797 | "Stereo : %-3s %-3s\n" | ||
1798 | " \n" | ||
1799 | "Buffer Sz : %-6d %-6d\n" | ||
1800 | "Frag Sz : %-6d %-6d\n" | ||
1801 | "Frag Num : %-6d %-6d\n" | ||
1802 | "Frag msecs : %-6d %-6d\n" | ||
1803 | "Used Frags : %-6d %-6d\n" | ||
1804 | "Mapped : %-3s %-3s\n", | ||
1805 | p_reg & 1<<0 ? "yes" : "no", | ||
1806 | r_reg & 1<<0 ? "yes" : "no", | ||
1807 | p_reg & 1<<1 ? "yes" : "no", | ||
1808 | r_reg & 1<<1 ? "yes" : "no", | ||
1809 | p_reg & 1<<2 ? "yes" : "no", | ||
1810 | r_reg & 1<<2 ? "yes" : "no", | ||
1811 | p_reg & 1<<5 ? "yes" : "no", | ||
1812 | r_reg & 1<<5 ? "yes" : "no", | ||
1813 | p_reg & 1<<6 ? "yes" : "no", | ||
1814 | r_reg & 1<<6 ? "yes" : "no", | ||
1815 | p_reg & 1<<7 ? "yes" : "no", | ||
1816 | r_reg & 1<<7 ? "yes" : "no", | ||
1817 | p_rate, r_rate, | ||
1818 | p_chan, | ||
1819 | p_reg & 1<<14 ? "yes" : "no", | ||
1820 | r_reg & 1<<14 ? "yes" : "no", | ||
1821 | p_reg & 1<<15 ? "yes" : "no", | ||
1822 | r_reg & 1<<15 ? "yes" : "no", | ||
1823 | forte->play.buf_sz, forte->rec.buf_sz, | ||
1824 | forte->play.frag_sz, forte->rec.frag_sz, | ||
1825 | forte->play.frag_num, forte->rec.frag_num, | ||
1826 | forte->play.frag_msecs, forte->rec.frag_msecs, | ||
1827 | forte->play.filled_frags, forte->rec.filled_frags, | ||
1828 | forte->play.mapped ? "yes" : "no", | ||
1829 | forte->rec.mapped ? "yes" : "no" | ||
1830 | ); | ||
1831 | |||
1832 | return i; | ||
1833 | } | ||
1834 | |||
1835 | |||
1836 | /** | ||
1837 | * forte_proc_init: | ||
1838 | * | ||
1839 | * Creates driver info entries in /proc | ||
1840 | */ | ||
1841 | |||
1842 | static int __init | ||
1843 | forte_proc_init (void) | ||
1844 | { | ||
1845 | if (!proc_mkdir ("driver/forte", NULL)) | ||
1846 | return -EIO; | ||
1847 | |||
1848 | if (!create_proc_read_entry ("driver/forte/chip", 0, NULL, forte_proc_read, forte)) { | ||
1849 | remove_proc_entry ("driver/forte", NULL); | ||
1850 | return -EIO; | ||
1851 | } | ||
1852 | |||
1853 | if (!create_proc_read_entry("driver/forte/ac97", 0, NULL, ac97_read_proc, forte->ac97)) { | ||
1854 | remove_proc_entry ("driver/forte/chip", NULL); | ||
1855 | remove_proc_entry ("driver/forte", NULL); | ||
1856 | return -EIO; | ||
1857 | } | ||
1858 | |||
1859 | return 0; | ||
1860 | } | ||
1861 | |||
1862 | |||
1863 | /** | ||
1864 | * forte_proc_remove: | ||
1865 | * | ||
1866 | * Removes driver info entries in /proc | ||
1867 | */ | ||
1868 | |||
1869 | static void | ||
1870 | forte_proc_remove (void) | ||
1871 | { | ||
1872 | remove_proc_entry ("driver/forte/ac97", NULL); | ||
1873 | remove_proc_entry ("driver/forte/chip", NULL); | ||
1874 | remove_proc_entry ("driver/forte", NULL); | ||
1875 | } | ||
1876 | |||
1877 | |||
1878 | /** | ||
1879 | * forte_chip_init: | ||
1880 | * @chip: Chip instance to initialize | ||
1881 | * | ||
1882 | * Description: | ||
1883 | * Resets chip, configures codec and registers the driver with | ||
1884 | * the sound subsystem. | ||
1885 | * | ||
1886 | * Press and hold Start for 8 secs, then switch on Run | ||
1887 | * and hold for 4 seconds. Let go of Start. Numbers | ||
1888 | * assume a properly oiled TWG. | ||
1889 | */ | ||
1890 | |||
1891 | static int __devinit | ||
1892 | forte_chip_init (struct forte_chip *chip) | ||
1893 | { | ||
1894 | u8 revision; | ||
1895 | u16 cmdw; | ||
1896 | struct ac97_codec *codec; | ||
1897 | |||
1898 | pci_read_config_byte (chip->pci_dev, PCI_REVISION_ID, &revision); | ||
1899 | |||
1900 | if (revision >= 0xB1) { | ||
1901 | chip->multichannel = 1; | ||
1902 | printk (KERN_INFO PFX "Multi-channel device detected.\n"); | ||
1903 | } | ||
1904 | |||
1905 | /* Reset chip */ | ||
1906 | outw (FORTE_CC_CODEC_RESET | FORTE_CC_AC97_RESET, | ||
1907 | chip->iobase + FORTE_CODEC_CTRL); | ||
1908 | udelay(100); | ||
1909 | outw (0, chip->iobase + FORTE_CODEC_CTRL); | ||
1910 | |||
1911 | /* Request read from AC97 */ | ||
1912 | outw (FORTE_AC97_READ | (0 << FORTE_AC97_ADDR_SHIFT), | ||
1913 | chip->iobase + FORTE_AC97_CMD); | ||
1914 | mdelay(750); | ||
1915 | |||
1916 | if ((inw (chip->iobase + FORTE_AC97_CMD) & (3<<8)) != (1<<8)) { | ||
1917 | printk (KERN_INFO PFX "AC97 codec not responding"); | ||
1918 | return -EIO; | ||
1919 | } | ||
1920 | |||
1921 | /* Init volume */ | ||
1922 | outw (0x0808, chip->iobase + FORTE_PCM_VOL); | ||
1923 | outw (0x9f1f, chip->iobase + FORTE_FM_VOL); | ||
1924 | outw (0x8808, chip->iobase + FORTE_I2S_VOL); | ||
1925 | |||
1926 | /* I2S control - I2S mode */ | ||
1927 | outw (0x0003, chip->iobase + FORTE_I2S_MODE); | ||
1928 | |||
1929 | /* Interrupt setup - unmask PLAYBACK & CAPTURE */ | ||
1930 | cmdw = inw (chip->iobase + FORTE_IRQ_MASK); | ||
1931 | cmdw &= ~0x0003; | ||
1932 | outw (cmdw, chip->iobase + FORTE_IRQ_MASK); | ||
1933 | |||
1934 | /* Interrupt clear */ | ||
1935 | outw (FORTE_IRQ_PLAYBACK|FORTE_IRQ_CAPTURE, | ||
1936 | chip->iobase + FORTE_IRQ_STATUS); | ||
1937 | |||
1938 | /* Set up the AC97 codec */ | ||
1939 | if ((codec = ac97_alloc_codec()) == NULL) | ||
1940 | return -ENOMEM; | ||
1941 | codec->private_data = chip; | ||
1942 | codec->codec_read = forte_ac97_read; | ||
1943 | codec->codec_write = forte_ac97_write; | ||
1944 | codec->id = 0; | ||
1945 | |||
1946 | if (ac97_probe_codec (codec) == 0) { | ||
1947 | printk (KERN_ERR PFX "codec probe failed\n"); | ||
1948 | ac97_release_codec(codec); | ||
1949 | return -1; | ||
1950 | } | ||
1951 | |||
1952 | /* Register mixer */ | ||
1953 | if ((codec->dev_mixer = | ||
1954 | register_sound_mixer (&forte_mixer_fops, -1)) < 0) { | ||
1955 | printk (KERN_ERR PFX "couldn't register mixer!\n"); | ||
1956 | ac97_release_codec(codec); | ||
1957 | return -1; | ||
1958 | } | ||
1959 | |||
1960 | chip->ac97 = codec; | ||
1961 | |||
1962 | /* Register DSP */ | ||
1963 | if ((chip->dsp = register_sound_dsp (&forte_dsp_fops, -1) ) < 0) { | ||
1964 | printk (KERN_ERR PFX "couldn't register dsp!\n"); | ||
1965 | return -1; | ||
1966 | } | ||
1967 | |||
1968 | /* Register with /proc */ | ||
1969 | if (forte_proc_init()) { | ||
1970 | printk (KERN_ERR PFX "couldn't add entries to /proc!\n"); | ||
1971 | return -1; | ||
1972 | } | ||
1973 | |||
1974 | return 0; | ||
1975 | } | ||
1976 | |||
1977 | |||
1978 | /** | ||
1979 | * forte_probe: | ||
1980 | * @pci_dev: PCI struct for probed device | ||
1981 | * @pci_id: | ||
1982 | * | ||
1983 | * Description: | ||
1984 | * Allocates chip instance, I/O region, and IRQ | ||
1985 | */ | ||
1986 | static int __init | ||
1987 | forte_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id) | ||
1988 | { | ||
1989 | struct forte_chip *chip; | ||
1990 | int ret = 0; | ||
1991 | |||
1992 | /* FIXME: Support more than one chip */ | ||
1993 | if (found++) | ||
1994 | return -EIO; | ||
1995 | |||
1996 | /* Ignition */ | ||
1997 | if (pci_enable_device (pci_dev)) | ||
1998 | return -EIO; | ||
1999 | |||
2000 | pci_set_master (pci_dev); | ||
2001 | |||
2002 | /* Allocate chip instance and configure */ | ||
2003 | forte = (struct forte_chip *) | ||
2004 | kmalloc (sizeof (struct forte_chip), GFP_KERNEL); | ||
2005 | chip = forte; | ||
2006 | |||
2007 | if (chip == NULL) { | ||
2008 | printk (KERN_WARNING PFX "Out of memory"); | ||
2009 | return -ENOMEM; | ||
2010 | } | ||
2011 | |||
2012 | memset (chip, 0, sizeof (struct forte_chip)); | ||
2013 | chip->pci_dev = pci_dev; | ||
2014 | |||
2015 | mutex_init(&chip->open_mutex); | ||
2016 | spin_lock_init (&chip->lock); | ||
2017 | spin_lock_init (&chip->ac97_lock); | ||
2018 | |||
2019 | if (! request_region (pci_resource_start (pci_dev, 0), | ||
2020 | pci_resource_len (pci_dev, 0), DRIVER_NAME)) { | ||
2021 | printk (KERN_WARNING PFX "Unable to reserve I/O space"); | ||
2022 | ret = -ENOMEM; | ||
2023 | goto error; | ||
2024 | } | ||
2025 | |||
2026 | chip->iobase = pci_resource_start (pci_dev, 0); | ||
2027 | chip->irq = pci_dev->irq; | ||
2028 | |||
2029 | if (request_irq (chip->irq, forte_interrupt, IRQF_SHARED, DRIVER_NAME, | ||
2030 | chip)) { | ||
2031 | printk (KERN_WARNING PFX "Unable to reserve IRQ"); | ||
2032 | ret = -EIO; | ||
2033 | goto error; | ||
2034 | } | ||
2035 | |||
2036 | pci_set_drvdata (pci_dev, chip); | ||
2037 | |||
2038 | printk (KERN_INFO PFX "FM801 chip found at 0x%04lX-0x%16llX IRQ %u\n", | ||
2039 | chip->iobase, (unsigned long long)pci_resource_end (pci_dev, 0), | ||
2040 | chip->irq); | ||
2041 | |||
2042 | /* Power it up */ | ||
2043 | if ((ret = forte_chip_init (chip)) == 0) | ||
2044 | return 0; | ||
2045 | |||
2046 | error: | ||
2047 | if (chip->irq) | ||
2048 | free_irq (chip->irq, chip); | ||
2049 | |||
2050 | if (chip->iobase) | ||
2051 | release_region (pci_resource_start (pci_dev, 0), | ||
2052 | pci_resource_len (pci_dev, 0)); | ||
2053 | |||
2054 | kfree (chip); | ||
2055 | |||
2056 | return ret; | ||
2057 | } | ||
2058 | |||
2059 | |||
2060 | /** | ||
2061 | * forte_remove: | ||
2062 | * @pci_dev: PCI device to unclaim | ||
2063 | * | ||
2064 | */ | ||
2065 | |||
2066 | static void | ||
2067 | forte_remove (struct pci_dev *pci_dev) | ||
2068 | { | ||
2069 | struct forte_chip *chip = pci_get_drvdata (pci_dev); | ||
2070 | |||
2071 | if (chip == NULL) | ||
2072 | return; | ||
2073 | |||
2074 | /* Turn volume down to avoid popping */ | ||
2075 | outw (0x1f1f, chip->iobase + FORTE_PCM_VOL); | ||
2076 | outw (0x1f1f, chip->iobase + FORTE_FM_VOL); | ||
2077 | outw (0x1f1f, chip->iobase + FORTE_I2S_VOL); | ||
2078 | |||
2079 | forte_proc_remove(); | ||
2080 | free_irq (chip->irq, chip); | ||
2081 | release_region (chip->iobase, pci_resource_len (pci_dev, 0)); | ||
2082 | |||
2083 | unregister_sound_dsp (chip->dsp); | ||
2084 | unregister_sound_mixer (chip->ac97->dev_mixer); | ||
2085 | ac97_release_codec(chip->ac97); | ||
2086 | kfree (chip); | ||
2087 | |||
2088 | printk (KERN_INFO PFX "driver released\n"); | ||
2089 | } | ||
2090 | |||
2091 | |||
2092 | static struct pci_device_id forte_pci_ids[] = { | ||
2093 | { 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, | ||
2094 | { 0, } | ||
2095 | }; | ||
2096 | |||
2097 | |||
2098 | static struct pci_driver forte_pci_driver = { | ||
2099 | .name = DRIVER_NAME, | ||
2100 | .id_table = forte_pci_ids, | ||
2101 | .probe = forte_probe, | ||
2102 | .remove = forte_remove, | ||
2103 | |||
2104 | }; | ||
2105 | |||
2106 | |||
2107 | /** | ||
2108 | * forte_init_module: | ||
2109 | * | ||
2110 | */ | ||
2111 | |||
2112 | static int __init | ||
2113 | forte_init_module (void) | ||
2114 | { | ||
2115 | printk (KERN_INFO PFX DRIVER_VERSION "\n"); | ||
2116 | |||
2117 | return pci_register_driver (&forte_pci_driver); | ||
2118 | } | ||
2119 | |||
2120 | |||
2121 | /** | ||
2122 | * forte_cleanup_module: | ||
2123 | * | ||
2124 | */ | ||
2125 | |||
2126 | static void __exit | ||
2127 | forte_cleanup_module (void) | ||
2128 | { | ||
2129 | pci_unregister_driver (&forte_pci_driver); | ||
2130 | } | ||
2131 | |||
2132 | |||
2133 | module_init(forte_init_module); | ||
2134 | module_exit(forte_cleanup_module); | ||
2135 | |||
2136 | MODULE_AUTHOR("Martin K. Petersen <mkp@mkp.net>"); | ||
2137 | MODULE_DESCRIPTION("ForteMedia FM801 OSS Driver"); | ||
2138 | MODULE_LICENSE("GPL"); | ||
2139 | MODULE_DEVICE_TABLE (pci, forte_pci_ids); | ||
diff --git a/sound/oss/gus.h b/sound/oss/gus.h deleted file mode 100644 index 3d5271baf042..000000000000 --- a/sound/oss/gus.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | |||
2 | #include "ad1848.h" | ||
3 | |||
4 | /* From gus_card.c */ | ||
5 | int gus_set_midi_irq(int num); | ||
6 | irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs * dummy); | ||
7 | |||
8 | /* From gus_wave.c */ | ||
9 | int gus_wave_detect(int baseaddr); | ||
10 | void gus_wave_init(struct address_info *hw_config); | ||
11 | void gus_wave_unload (struct address_info *hw_config); | ||
12 | void gus_voice_irq(void); | ||
13 | void gus_write8(int reg, unsigned int data); | ||
14 | void guswave_dma_irq(void); | ||
15 | void gus_delay(void); | ||
16 | int gus_default_mixer_ioctl (int dev, unsigned int cmd, void __user *arg); | ||
17 | void gus_timer_command (unsigned int addr, unsigned int val); | ||
18 | |||
19 | /* From gus_midi.c */ | ||
20 | void gus_midi_init(struct address_info *hw_config); | ||
21 | void gus_midi_interrupt(int dummy); | ||
22 | |||
23 | /* From ics2101.c */ | ||
24 | int ics2101_mixer_init(void); | ||
diff --git a/sound/oss/gus_card.c b/sound/oss/gus_card.c deleted file mode 100644 index a3d6ae33fe8b..000000000000 --- a/sound/oss/gus_card.c +++ /dev/null | |||
@@ -1,293 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/gus_card.c | ||
3 | * | ||
4 | * Detection routine for the Gravis Ultrasound. | ||
5 | * | ||
6 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
7 | * | ||
8 | * | ||
9 | * Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious | ||
10 | * usage of CS4231A codec, GUS wave and MIDI for GUS MAX. | ||
11 | * Christoph Hellwig: Adapted to module_init/module_exit, simple cleanups. | ||
12 | * | ||
13 | * Status: | ||
14 | * Tested... | ||
15 | */ | ||
16 | |||
17 | |||
18 | #include <linux/config.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/module.h> | ||
22 | |||
23 | #include "sound_config.h" | ||
24 | |||
25 | #include "gus.h" | ||
26 | #include "gus_hw.h" | ||
27 | |||
28 | irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy); | ||
29 | |||
30 | int gus_base = 0, gus_irq = 0, gus_dma = 0; | ||
31 | int gus_no_wave_dma = 0; | ||
32 | extern int gus_wave_volume; | ||
33 | extern int gus_pcm_volume; | ||
34 | extern int have_gus_max; | ||
35 | int gus_pnp_flag = 0; | ||
36 | #ifdef CONFIG_SOUND_GUS16 | ||
37 | static int db16; /* Has a Gus16 AD1848 on it */ | ||
38 | #endif | ||
39 | |||
40 | static void __init attach_gus(struct address_info *hw_config) | ||
41 | { | ||
42 | gus_wave_init(hw_config); | ||
43 | |||
44 | if (sound_alloc_dma(hw_config->dma, "GUS")) | ||
45 | printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma); | ||
46 | if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma) | ||
47 | if (sound_alloc_dma(hw_config->dma2, "GUS(2)")) | ||
48 | printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma2); | ||
49 | gus_midi_init(hw_config); | ||
50 | if(request_irq(hw_config->irq, gusintr, 0, "Gravis Ultrasound", hw_config)<0) | ||
51 | printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq); | ||
52 | |||
53 | return; | ||
54 | } | ||
55 | |||
56 | static int __init probe_gus(struct address_info *hw_config) | ||
57 | { | ||
58 | int irq; | ||
59 | int io_addr; | ||
60 | |||
61 | if (hw_config->card_subtype == 1) | ||
62 | gus_pnp_flag = 1; | ||
63 | |||
64 | irq = hw_config->irq; | ||
65 | |||
66 | if (hw_config->card_subtype == 0) /* GUS/MAX/ACE */ | ||
67 | if (irq != 3 && irq != 5 && irq != 7 && irq != 9 && | ||
68 | irq != 11 && irq != 12 && irq != 15) | ||
69 | { | ||
70 | printk(KERN_ERR "GUS: Unsupported IRQ %d\n", irq); | ||
71 | return 0; | ||
72 | } | ||
73 | if (gus_wave_detect(hw_config->io_base)) | ||
74 | return 1; | ||
75 | |||
76 | #ifndef EXCLUDE_GUS_IODETECT | ||
77 | |||
78 | /* | ||
79 | * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6) | ||
80 | */ | ||
81 | |||
82 | for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10) { | ||
83 | if (io_addr == hw_config->io_base) /* Already tested */ | ||
84 | continue; | ||
85 | if (gus_wave_detect(io_addr)) { | ||
86 | hw_config->io_base = io_addr; | ||
87 | return 1; | ||
88 | } | ||
89 | } | ||
90 | #endif | ||
91 | |||
92 | printk("NO GUS card found !\n"); | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static void __exit unload_gus(struct address_info *hw_config) | ||
97 | { | ||
98 | DDB(printk("unload_gus(%x)\n", hw_config->io_base)); | ||
99 | |||
100 | gus_wave_unload(hw_config); | ||
101 | |||
102 | release_region(hw_config->io_base, 16); | ||
103 | release_region(hw_config->io_base + 0x100, 12); /* 0x10c-> is MAX */ | ||
104 | free_irq(hw_config->irq, hw_config); | ||
105 | |||
106 | sound_free_dma(hw_config->dma); | ||
107 | |||
108 | if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma) | ||
109 | sound_free_dma(hw_config->dma2); | ||
110 | } | ||
111 | |||
112 | irqreturn_t gusintr(int irq, void *dev_id, struct pt_regs *dummy) | ||
113 | { | ||
114 | unsigned char src; | ||
115 | extern int gus_timer_enabled; | ||
116 | int handled = 0; | ||
117 | |||
118 | #ifdef CONFIG_SOUND_GUSMAX | ||
119 | if (have_gus_max) { | ||
120 | struct address_info *hw_config = dev_id; | ||
121 | adintr(irq, (void *)hw_config->slots[1], NULL); | ||
122 | } | ||
123 | #endif | ||
124 | #ifdef CONFIG_SOUND_GUS16 | ||
125 | if (db16) { | ||
126 | struct address_info *hw_config = dev_id; | ||
127 | adintr(irq, (void *)hw_config->slots[3], NULL); | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | while (1) | ||
132 | { | ||
133 | if (!(src = inb(u_IrqStatus))) | ||
134 | break; | ||
135 | handled = 1; | ||
136 | if (src & DMA_TC_IRQ) | ||
137 | { | ||
138 | guswave_dma_irq(); | ||
139 | } | ||
140 | if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ)) | ||
141 | { | ||
142 | gus_midi_interrupt(0); | ||
143 | } | ||
144 | if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ)) | ||
145 | { | ||
146 | if (gus_timer_enabled) | ||
147 | sound_timer_interrupt(); | ||
148 | gus_write8(0x45, 0); /* Ack IRQ */ | ||
149 | gus_timer_command(4, 0x80); /* Reset IRQ flags */ | ||
150 | } | ||
151 | if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ)) | ||
152 | gus_voice_irq(); | ||
153 | } | ||
154 | return IRQ_RETVAL(handled); | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Some extra code for the 16 bit sampling option | ||
159 | */ | ||
160 | |||
161 | #ifdef CONFIG_SOUND_GUS16 | ||
162 | |||
163 | static int __init init_gus_db16(struct address_info *hw_config) | ||
164 | { | ||
165 | struct resource *ports; | ||
166 | |||
167 | ports = request_region(hw_config->io_base, 4, "ad1848"); | ||
168 | if (!ports) | ||
169 | return 0; | ||
170 | |||
171 | if (!ad1848_detect(ports, NULL, hw_config->osp)) { | ||
172 | release_region(hw_config->io_base, 4); | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | gus_pcm_volume = 100; | ||
177 | gus_wave_volume = 90; | ||
178 | |||
179 | hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", ports, | ||
180 | hw_config->irq, | ||
181 | hw_config->dma, | ||
182 | hw_config->dma, 0, | ||
183 | hw_config->osp, | ||
184 | THIS_MODULE); | ||
185 | return 1; | ||
186 | } | ||
187 | |||
188 | static void __exit unload_gus_db16(struct address_info *hw_config) | ||
189 | { | ||
190 | |||
191 | ad1848_unload(hw_config->io_base, | ||
192 | hw_config->irq, | ||
193 | hw_config->dma, | ||
194 | hw_config->dma, 0); | ||
195 | sound_unload_audiodev(hw_config->slots[3]); | ||
196 | } | ||
197 | #endif | ||
198 | |||
199 | #ifdef CONFIG_SOUND_GUS16 | ||
200 | static int gus16; | ||
201 | #endif | ||
202 | #ifdef CONFIG_SOUND_GUSMAX | ||
203 | static int no_wave_dma; /* Set if no dma is to be used for the | ||
204 | wave table (GF1 chip) */ | ||
205 | #endif | ||
206 | |||
207 | |||
208 | /* | ||
209 | * Note DMA2 of -1 has the right meaning in the GUS driver as well | ||
210 | * as here. | ||
211 | */ | ||
212 | |||
213 | static struct address_info cfg; | ||
214 | |||
215 | static int __initdata io = -1; | ||
216 | static int __initdata irq = -1; | ||
217 | static int __initdata dma = -1; | ||
218 | static int __initdata dma16 = -1; /* Set this for modules that need it */ | ||
219 | static int __initdata type = 0; /* 1 for PnP */ | ||
220 | |||
221 | module_param(io, int, 0); | ||
222 | module_param(irq, int, 0); | ||
223 | module_param(dma, int, 0); | ||
224 | module_param(dma16, int, 0); | ||
225 | module_param(type, int, 0); | ||
226 | #ifdef CONFIG_SOUND_GUSMAX | ||
227 | module_param(no_wave_dma, int, 0); | ||
228 | #endif | ||
229 | #ifdef CONFIG_SOUND_GUS16 | ||
230 | module_param(db16, int, 0); | ||
231 | module_param(gus16, int, 0); | ||
232 | #endif | ||
233 | MODULE_LICENSE("GPL"); | ||
234 | |||
235 | static int __init init_gus(void) | ||
236 | { | ||
237 | printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n"); | ||
238 | |||
239 | cfg.io_base = io; | ||
240 | cfg.irq = irq; | ||
241 | cfg.dma = dma; | ||
242 | cfg.dma2 = dma16; | ||
243 | cfg.card_subtype = type; | ||
244 | #ifdef CONFIG_SOUND_GUSMAX | ||
245 | gus_no_wave_dma = no_wave_dma; | ||
246 | #endif | ||
247 | |||
248 | if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) { | ||
249 | printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n"); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | |||
253 | #ifdef CONFIG_SOUND_GUS16 | ||
254 | if (gus16 && init_gus_db16(&cfg)) | ||
255 | db16 = 1; | ||
256 | #endif | ||
257 | if (!probe_gus(&cfg)) | ||
258 | return -ENODEV; | ||
259 | attach_gus(&cfg); | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static void __exit cleanup_gus(void) | ||
265 | { | ||
266 | #ifdef CONFIG_SOUND_GUS16 | ||
267 | if (db16) | ||
268 | unload_gus_db16(&cfg); | ||
269 | #endif | ||
270 | unload_gus(&cfg); | ||
271 | } | ||
272 | |||
273 | module_init(init_gus); | ||
274 | module_exit(cleanup_gus); | ||
275 | |||
276 | #ifndef MODULE | ||
277 | static int __init setup_gus(char *str) | ||
278 | { | ||
279 | /* io, irq, dma, dma2 */ | ||
280 | int ints[5]; | ||
281 | |||
282 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
283 | |||
284 | io = ints[1]; | ||
285 | irq = ints[2]; | ||
286 | dma = ints[3]; | ||
287 | dma16 = ints[4]; | ||
288 | |||
289 | return 1; | ||
290 | } | ||
291 | |||
292 | __setup("gus=", setup_gus); | ||
293 | #endif | ||
diff --git a/sound/oss/gus_hw.h b/sound/oss/gus_hw.h deleted file mode 100644 index f97a0b8670e3..000000000000 --- a/sound/oss/gus_hw.h +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | |||
2 | /* | ||
3 | * I/O addresses | ||
4 | */ | ||
5 | |||
6 | #define u_Base (gus_base + 0x000) | ||
7 | #define u_Mixer u_Base | ||
8 | #define u_Status (gus_base + 0x006) | ||
9 | #define u_TimerControl (gus_base + 0x008) | ||
10 | #define u_TimerData (gus_base + 0x009) | ||
11 | #define u_IRQDMAControl (gus_base + 0x00b) | ||
12 | #define u_MidiControl (gus_base + 0x100) | ||
13 | #define MIDI_RESET 0x03 | ||
14 | #define MIDI_ENABLE_XMIT 0x20 | ||
15 | #define MIDI_ENABLE_RCV 0x80 | ||
16 | #define u_MidiStatus u_MidiControl | ||
17 | #define MIDI_RCV_FULL 0x01 | ||
18 | #define MIDI_XMIT_EMPTY 0x02 | ||
19 | #define MIDI_FRAME_ERR 0x10 | ||
20 | #define MIDI_OVERRUN 0x20 | ||
21 | #define MIDI_IRQ_PEND 0x80 | ||
22 | #define u_MidiData (gus_base + 0x101) | ||
23 | #define u_Voice (gus_base + 0x102) | ||
24 | #define u_Command (gus_base + 0x103) | ||
25 | #define u_DataLo (gus_base + 0x104) | ||
26 | #define u_DataHi (gus_base + 0x105) | ||
27 | #define u_MixData (gus_base + 0x106) /* Rev. 3.7+ mixing */ | ||
28 | #define u_MixSelect (gus_base + 0x506) /* registers. */ | ||
29 | #define u_IrqStatus u_Status | ||
30 | # define MIDI_TX_IRQ 0x01 /* pending MIDI xmit IRQ */ | ||
31 | # define MIDI_RX_IRQ 0x02 /* pending MIDI recv IRQ */ | ||
32 | # define GF1_TIMER1_IRQ 0x04 /* general purpose timer */ | ||
33 | # define GF1_TIMER2_IRQ 0x08 /* general purpose timer */ | ||
34 | # define WAVETABLE_IRQ 0x20 /* pending wavetable IRQ */ | ||
35 | # define ENVELOPE_IRQ 0x40 /* pending volume envelope IRQ */ | ||
36 | # define DMA_TC_IRQ 0x80 /* pending dma tc IRQ */ | ||
37 | |||
38 | #define ICS2101 1 | ||
39 | # define ICS_MIXDEVS 6 | ||
40 | # define DEV_MIC 0 | ||
41 | # define DEV_LINE 1 | ||
42 | # define DEV_CD 2 | ||
43 | # define DEV_GF1 3 | ||
44 | # define DEV_UNUSED 4 | ||
45 | # define DEV_VOL 5 | ||
46 | |||
47 | # define CHN_LEFT 0 | ||
48 | # define CHN_RIGHT 1 | ||
49 | #define CS4231 2 | ||
50 | #define u_DRAMIO (gus_base + 0x107) | ||
diff --git a/sound/oss/gus_linearvol.h b/sound/oss/gus_linearvol.h deleted file mode 100644 index 7ad0c30d4fd9..000000000000 --- a/sound/oss/gus_linearvol.h +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | static unsigned short gus_linearvol[128] = { | ||
2 | 0x0000, 0x08ff, 0x09ff, 0x0a80, 0x0aff, 0x0b40, 0x0b80, 0x0bc0, | ||
3 | 0x0bff, 0x0c20, 0x0c40, 0x0c60, 0x0c80, 0x0ca0, 0x0cc0, 0x0ce0, | ||
4 | 0x0cff, 0x0d10, 0x0d20, 0x0d30, 0x0d40, 0x0d50, 0x0d60, 0x0d70, | ||
5 | 0x0d80, 0x0d90, 0x0da0, 0x0db0, 0x0dc0, 0x0dd0, 0x0de0, 0x0df0, | ||
6 | 0x0dff, 0x0e08, 0x0e10, 0x0e18, 0x0e20, 0x0e28, 0x0e30, 0x0e38, | ||
7 | 0x0e40, 0x0e48, 0x0e50, 0x0e58, 0x0e60, 0x0e68, 0x0e70, 0x0e78, | ||
8 | 0x0e80, 0x0e88, 0x0e90, 0x0e98, 0x0ea0, 0x0ea8, 0x0eb0, 0x0eb8, | ||
9 | 0x0ec0, 0x0ec8, 0x0ed0, 0x0ed8, 0x0ee0, 0x0ee8, 0x0ef0, 0x0ef8, | ||
10 | 0x0eff, 0x0f04, 0x0f08, 0x0f0c, 0x0f10, 0x0f14, 0x0f18, 0x0f1c, | ||
11 | 0x0f20, 0x0f24, 0x0f28, 0x0f2c, 0x0f30, 0x0f34, 0x0f38, 0x0f3c, | ||
12 | 0x0f40, 0x0f44, 0x0f48, 0x0f4c, 0x0f50, 0x0f54, 0x0f58, 0x0f5c, | ||
13 | 0x0f60, 0x0f64, 0x0f68, 0x0f6c, 0x0f70, 0x0f74, 0x0f78, 0x0f7c, | ||
14 | 0x0f80, 0x0f84, 0x0f88, 0x0f8c, 0x0f90, 0x0f94, 0x0f98, 0x0f9c, | ||
15 | 0x0fa0, 0x0fa4, 0x0fa8, 0x0fac, 0x0fb0, 0x0fb4, 0x0fb8, 0x0fbc, | ||
16 | 0x0fc0, 0x0fc4, 0x0fc8, 0x0fcc, 0x0fd0, 0x0fd4, 0x0fd8, 0x0fdc, | ||
17 | 0x0fe0, 0x0fe4, 0x0fe8, 0x0fec, 0x0ff0, 0x0ff4, 0x0ff8, 0x0ffc | ||
18 | }; | ||
diff --git a/sound/oss/gus_midi.c b/sound/oss/gus_midi.c deleted file mode 100644 index d1997a417ad0..000000000000 --- a/sound/oss/gus_midi.c +++ /dev/null | |||
@@ -1,256 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/gus_midi.c | ||
3 | * | ||
4 | * The low level driver for the GUS Midi Interface. | ||
5 | * | ||
6 | * | ||
7 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
8 | * | ||
9 | * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
10 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
11 | * for more info. | ||
12 | * | ||
13 | * Changes: | ||
14 | * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> | ||
15 | * Added __init to gus_midi_init() | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include "sound_config.h" | ||
21 | |||
22 | #include "gus.h" | ||
23 | #include "gus_hw.h" | ||
24 | |||
25 | static int midi_busy, input_opened; | ||
26 | static int my_dev; | ||
27 | static int output_used; | ||
28 | static volatile unsigned char gus_midi_control; | ||
29 | static void (*midi_input_intr) (int dev, unsigned char data); | ||
30 | |||
31 | static unsigned char tmp_queue[256]; | ||
32 | extern int gus_pnp_flag; | ||
33 | static volatile int qlen; | ||
34 | static volatile unsigned char qhead, qtail; | ||
35 | extern int gus_base, gus_irq, gus_dma; | ||
36 | extern int *gus_osp; | ||
37 | extern spinlock_t gus_lock; | ||
38 | |||
39 | static int GUS_MIDI_STATUS(void) | ||
40 | { | ||
41 | return inb(u_MidiStatus); | ||
42 | } | ||
43 | |||
44 | static int gus_midi_open(int dev, int mode, void (*input) (int dev, unsigned char data), void (*output) (int dev)) | ||
45 | { | ||
46 | if (midi_busy) | ||
47 | { | ||
48 | /* printk("GUS: Midi busy\n");*/ | ||
49 | return -EBUSY; | ||
50 | } | ||
51 | outb((MIDI_RESET), u_MidiControl); | ||
52 | gus_delay(); | ||
53 | |||
54 | gus_midi_control = 0; | ||
55 | input_opened = 0; | ||
56 | |||
57 | if (mode == OPEN_READ || mode == OPEN_READWRITE) | ||
58 | if (!gus_pnp_flag) | ||
59 | { | ||
60 | gus_midi_control |= MIDI_ENABLE_RCV; | ||
61 | input_opened = 1; | ||
62 | } | ||
63 | outb((gus_midi_control), u_MidiControl); /* Enable */ | ||
64 | |||
65 | midi_busy = 1; | ||
66 | qlen = qhead = qtail = output_used = 0; | ||
67 | midi_input_intr = input; | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int dump_to_midi(unsigned char midi_byte) | ||
73 | { | ||
74 | unsigned long flags; | ||
75 | int ok = 0; | ||
76 | |||
77 | output_used = 1; | ||
78 | |||
79 | spin_lock_irqsave(&gus_lock, flags); | ||
80 | |||
81 | if (GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY) | ||
82 | { | ||
83 | ok = 1; | ||
84 | outb((midi_byte), u_MidiData); | ||
85 | } | ||
86 | else | ||
87 | { | ||
88 | /* | ||
89 | * Enable Midi xmit interrupts (again) | ||
90 | */ | ||
91 | gus_midi_control |= MIDI_ENABLE_XMIT; | ||
92 | outb((gus_midi_control), u_MidiControl); | ||
93 | } | ||
94 | |||
95 | spin_unlock_irqrestore(&gus_lock,flags); | ||
96 | return ok; | ||
97 | } | ||
98 | |||
99 | static void gus_midi_close(int dev) | ||
100 | { | ||
101 | /* | ||
102 | * Reset FIFO pointers, disable intrs | ||
103 | */ | ||
104 | |||
105 | outb((MIDI_RESET), u_MidiControl); | ||
106 | midi_busy = 0; | ||
107 | } | ||
108 | |||
109 | static int gus_midi_out(int dev, unsigned char midi_byte) | ||
110 | { | ||
111 | unsigned long flags; | ||
112 | |||
113 | /* | ||
114 | * Drain the local queue first | ||
115 | */ | ||
116 | spin_lock_irqsave(&gus_lock, flags); | ||
117 | |||
118 | while (qlen && dump_to_midi(tmp_queue[qhead])) | ||
119 | { | ||
120 | qlen--; | ||
121 | qhead++; | ||
122 | } | ||
123 | spin_unlock_irqrestore(&gus_lock,flags); | ||
124 | |||
125 | /* | ||
126 | * Output the byte if the local queue is empty. | ||
127 | */ | ||
128 | |||
129 | if (!qlen) | ||
130 | if (dump_to_midi(midi_byte)) | ||
131 | return 1; /* | ||
132 | * OK | ||
133 | */ | ||
134 | |||
135 | /* | ||
136 | * Put to the local queue | ||
137 | */ | ||
138 | |||
139 | if (qlen >= 256) | ||
140 | return 0; /* | ||
141 | * Local queue full | ||
142 | */ | ||
143 | spin_lock_irqsave(&gus_lock, flags); | ||
144 | |||
145 | tmp_queue[qtail] = midi_byte; | ||
146 | qlen++; | ||
147 | qtail++; | ||
148 | |||
149 | spin_unlock_irqrestore(&gus_lock,flags); | ||
150 | return 1; | ||
151 | } | ||
152 | |||
153 | static int gus_midi_start_read(int dev) | ||
154 | { | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int gus_midi_end_read(int dev) | ||
159 | { | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static void gus_midi_kick(int dev) | ||
164 | { | ||
165 | } | ||
166 | |||
167 | static int gus_midi_buffer_status(int dev) | ||
168 | { | ||
169 | unsigned long flags; | ||
170 | |||
171 | if (!output_used) | ||
172 | return 0; | ||
173 | |||
174 | spin_lock_irqsave(&gus_lock, flags); | ||
175 | |||
176 | if (qlen && dump_to_midi(tmp_queue[qhead])) | ||
177 | { | ||
178 | qlen--; | ||
179 | qhead++; | ||
180 | } | ||
181 | spin_unlock_irqrestore(&gus_lock,flags); | ||
182 | return (qlen > 0) || !(GUS_MIDI_STATUS() & MIDI_XMIT_EMPTY); | ||
183 | } | ||
184 | |||
185 | #define MIDI_SYNTH_NAME "Gravis Ultrasound Midi" | ||
186 | #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT | ||
187 | #include "midi_synth.h" | ||
188 | |||
189 | static struct midi_operations gus_midi_operations = | ||
190 | { | ||
191 | .owner = THIS_MODULE, | ||
192 | .info = {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS}, | ||
193 | .converter = &std_midi_synth, | ||
194 | .in_info = {0}, | ||
195 | .open = gus_midi_open, | ||
196 | .close = gus_midi_close, | ||
197 | .outputc = gus_midi_out, | ||
198 | .start_read = gus_midi_start_read, | ||
199 | .end_read = gus_midi_end_read, | ||
200 | .kick = gus_midi_kick, | ||
201 | .buffer_status = gus_midi_buffer_status, | ||
202 | }; | ||
203 | |||
204 | void __init gus_midi_init(struct address_info *hw_config) | ||
205 | { | ||
206 | int dev = sound_alloc_mididev(); | ||
207 | |||
208 | if (dev == -1) | ||
209 | { | ||
210 | printk(KERN_INFO "gus_midi: Too many midi devices detected\n"); | ||
211 | return; | ||
212 | } | ||
213 | outb((MIDI_RESET), u_MidiControl); | ||
214 | |||
215 | std_midi_synth.midi_dev = my_dev = dev; | ||
216 | hw_config->slots[2] = dev; | ||
217 | midi_devs[dev] = &gus_midi_operations; | ||
218 | sequencer_init(); | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | void gus_midi_interrupt(int dummy) | ||
223 | { | ||
224 | volatile unsigned char stat, data; | ||
225 | int timeout = 10; | ||
226 | |||
227 | spin_lock(&gus_lock); | ||
228 | |||
229 | while (timeout-- > 0 && (stat = GUS_MIDI_STATUS()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY)) | ||
230 | { | ||
231 | if (stat & MIDI_RCV_FULL) | ||
232 | { | ||
233 | data = inb(u_MidiData); | ||
234 | if (input_opened) | ||
235 | midi_input_intr(my_dev, data); | ||
236 | } | ||
237 | if (stat & MIDI_XMIT_EMPTY) | ||
238 | { | ||
239 | while (qlen && dump_to_midi(tmp_queue[qhead])) | ||
240 | { | ||
241 | qlen--; | ||
242 | qhead++; | ||
243 | } | ||
244 | if (!qlen) | ||
245 | { | ||
246 | /* | ||
247 | * Disable Midi output interrupts, since no data in the buffer | ||
248 | */ | ||
249 | gus_midi_control &= ~MIDI_ENABLE_XMIT; | ||
250 | outb((gus_midi_control), u_MidiControl); | ||
251 | outb((gus_midi_control), u_MidiControl); | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | spin_unlock(&gus_lock); | ||
256 | } | ||
diff --git a/sound/oss/gus_vol.c b/sound/oss/gus_vol.c deleted file mode 100644 index 6ae6924e1647..000000000000 --- a/sound/oss/gus_vol.c +++ /dev/null | |||
@@ -1,153 +0,0 @@ | |||
1 | |||
2 | /* | ||
3 | * gus_vol.c - Compute volume for GUS. | ||
4 | * | ||
5 | * | ||
6 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
7 | * | ||
8 | * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
9 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
10 | * for more info. | ||
11 | */ | ||
12 | #include "sound_config.h" | ||
13 | |||
14 | #include "gus.h" | ||
15 | #include "gus_linearvol.h" | ||
16 | |||
17 | #define GUS_VOLUME gus_wave_volume | ||
18 | |||
19 | |||
20 | extern int gus_wave_volume; | ||
21 | |||
22 | /* | ||
23 | * Calculate gus volume from note velocity, main volume, expression, and | ||
24 | * intrinsic patch volume given in patch library. Expression is multiplied | ||
25 | * in, so it emphasizes differences in note velocity, while main volume is | ||
26 | * added in -- I don't know whether this is right, but it seems reasonable to | ||
27 | * me. (In the previous stage, main volume controller messages were changed | ||
28 | * to expression controller messages, if they were found to be used for | ||
29 | * dynamic volume adjustments, so here, main volume can be assumed to be | ||
30 | * constant throughout a song.) | ||
31 | * | ||
32 | * Intrinsic patch volume is added in, but if over 64 is also multiplied in, so | ||
33 | * we can give a big boost to very weak voices like nylon guitar and the | ||
34 | * basses. The normal value is 64. Strings are assigned lower values. | ||
35 | */ | ||
36 | |||
37 | unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev) | ||
38 | { | ||
39 | int i, m, n, x; | ||
40 | |||
41 | |||
42 | /* | ||
43 | * A voice volume of 64 is considered neutral, so adjust the main volume if | ||
44 | * something other than this neutral value was assigned in the patch | ||
45 | * library. | ||
46 | */ | ||
47 | x = 256 + 6 * (voicev - 64); | ||
48 | |||
49 | /* | ||
50 | * Boost expression by voice volume above neutral. | ||
51 | */ | ||
52 | |||
53 | if (voicev > 65) | ||
54 | xpn += voicev - 64; | ||
55 | xpn += (voicev - 64) / 2; | ||
56 | |||
57 | /* | ||
58 | * Combine multiplicative and level components. | ||
59 | */ | ||
60 | x = vel * xpn * 6 + (voicev / 4) * x; | ||
61 | |||
62 | #ifdef GUS_VOLUME | ||
63 | /* | ||
64 | * Further adjustment by installation-specific master volume control | ||
65 | * (default 60). | ||
66 | */ | ||
67 | x = (x * GUS_VOLUME * GUS_VOLUME) / 10000; | ||
68 | #endif | ||
69 | |||
70 | #ifdef GUS_USE_CHN_MAIN_VOLUME | ||
71 | /* | ||
72 | * Experimental support for the channel main volume | ||
73 | */ | ||
74 | |||
75 | mainv = (mainv / 2) + 64; /* Scale to 64 to 127 */ | ||
76 | x = (x * mainv * mainv) / 16384; | ||
77 | #endif | ||
78 | |||
79 | if (x < 2) | ||
80 | return (0); | ||
81 | else if (x >= 65535) | ||
82 | return ((15 << 8) | 255); | ||
83 | |||
84 | /* | ||
85 | * Convert to GUS's logarithmic form with 4 bit exponent i and 8 bit | ||
86 | * mantissa m. | ||
87 | */ | ||
88 | |||
89 | n = x; | ||
90 | i = 7; | ||
91 | if (n < 128) | ||
92 | { | ||
93 | while (i > 0 && n < (1 << i)) | ||
94 | i--; | ||
95 | } | ||
96 | else | ||
97 | { | ||
98 | while (n > 255) | ||
99 | { | ||
100 | n >>= 1; | ||
101 | i++; | ||
102 | } | ||
103 | } | ||
104 | /* | ||
105 | * Mantissa is part of linear volume not expressed in exponent. (This is | ||
106 | * not quite like real logs -- I wonder if it's right.) | ||
107 | */ | ||
108 | m = x - (1 << i); | ||
109 | |||
110 | /* | ||
111 | * Adjust mantissa to 8 bits. | ||
112 | */ | ||
113 | if (m > 0) | ||
114 | { | ||
115 | if (i > 8) | ||
116 | m >>= i - 8; | ||
117 | else if (i < 8) | ||
118 | m <<= 8 - i; | ||
119 | } | ||
120 | return ((i << 8) + m); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Volume-values are interpreted as linear values. Volume is based on the | ||
125 | * value supplied with SEQ_START_NOTE(), channel main volume (if compiled in) | ||
126 | * and the volume set by the mixer-device (default 60%). | ||
127 | */ | ||
128 | |||
129 | unsigned short gus_linear_vol(int vol, int mainvol) | ||
130 | { | ||
131 | int mixer_mainvol; | ||
132 | |||
133 | if (vol <= 0) | ||
134 | vol = 0; | ||
135 | else if (vol >= 127) | ||
136 | vol = 127; | ||
137 | |||
138 | #ifdef GUS_VOLUME | ||
139 | mixer_mainvol = GUS_VOLUME; | ||
140 | #else | ||
141 | mixer_mainvol = 100; | ||
142 | #endif | ||
143 | |||
144 | #ifdef GUS_USE_CHN_MAIN_VOLUME | ||
145 | if (mainvol <= 0) | ||
146 | mainvol = 0; | ||
147 | else if (mainvol >= 127) | ||
148 | mainvol = 127; | ||
149 | #else | ||
150 | mainvol = 127; | ||
151 | #endif | ||
152 | return gus_linearvol[(((vol * mainvol) / 127) * mixer_mainvol) / 100]; | ||
153 | } | ||
diff --git a/sound/oss/gus_wave.c b/sound/oss/gus_wave.c deleted file mode 100644 index 597db7aee632..000000000000 --- a/sound/oss/gus_wave.c +++ /dev/null | |||
@@ -1,3464 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/gus_wave.c | ||
3 | * | ||
4 | * Driver for the Gravis UltraSound wave table synth. | ||
5 | * | ||
6 | * | ||
7 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
8 | * | ||
9 | * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
10 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
11 | * for more info. | ||
12 | * | ||
13 | * | ||
14 | * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) | ||
15 | * Frank van de Pol : Fixed GUS MAX interrupt handling. Enabled simultanious | ||
16 | * usage of CS4231A codec, GUS wave and MIDI for GUS MAX. | ||
17 | * Bartlomiej Zolnierkiewicz : added some __init/__exit | ||
18 | */ | ||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/config.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | |||
24 | #define GUSPNP_AUTODETECT | ||
25 | |||
26 | #include "sound_config.h" | ||
27 | #include <linux/ultrasound.h> | ||
28 | |||
29 | #include "gus.h" | ||
30 | #include "gus_hw.h" | ||
31 | |||
32 | #define GUS_BANK_SIZE (((iw_mode) ? 256*1024*1024 : 256*1024)) | ||
33 | |||
34 | #define MAX_SAMPLE 150 | ||
35 | #define MAX_PATCH 256 | ||
36 | |||
37 | #define NOT_SAMPLE 0xffff | ||
38 | |||
39 | struct voice_info | ||
40 | { | ||
41 | unsigned long orig_freq; | ||
42 | unsigned long current_freq; | ||
43 | unsigned long mode; | ||
44 | int fixed_pitch; | ||
45 | int bender; | ||
46 | int bender_range; | ||
47 | int panning; | ||
48 | int midi_volume; | ||
49 | unsigned int initial_volume; | ||
50 | unsigned int current_volume; | ||
51 | int loop_irq_mode, loop_irq_parm; | ||
52 | #define LMODE_FINISH 1 | ||
53 | #define LMODE_PCM 2 | ||
54 | #define LMODE_PCM_STOP 3 | ||
55 | int volume_irq_mode, volume_irq_parm; | ||
56 | #define VMODE_HALT 1 | ||
57 | #define VMODE_ENVELOPE 2 | ||
58 | #define VMODE_START_NOTE 3 | ||
59 | |||
60 | int env_phase; | ||
61 | unsigned char env_rate[6]; | ||
62 | unsigned char env_offset[6]; | ||
63 | |||
64 | /* | ||
65 | * Volume computation parameters for gus_adagio_vol() | ||
66 | */ | ||
67 | int main_vol, expression_vol, patch_vol; | ||
68 | |||
69 | /* Variables for "Ultraclick" removal */ | ||
70 | int dev_pending, note_pending, volume_pending, | ||
71 | sample_pending; | ||
72 | char kill_pending; | ||
73 | long offset_pending; | ||
74 | |||
75 | }; | ||
76 | |||
77 | static struct voice_alloc_info *voice_alloc; | ||
78 | static struct address_info *gus_hw_config; | ||
79 | extern int gus_base; | ||
80 | extern int gus_irq, gus_dma; | ||
81 | extern int gus_pnp_flag; | ||
82 | extern int gus_no_wave_dma; | ||
83 | static int gus_dma2 = -1; | ||
84 | static int dual_dma_mode; | ||
85 | static long gus_mem_size; | ||
86 | static long free_mem_ptr; | ||
87 | static int gus_busy; | ||
88 | static int gus_no_dma; | ||
89 | static int nr_voices; | ||
90 | static int gus_devnum; | ||
91 | static int volume_base, volume_scale, volume_method; | ||
92 | static int gus_recmask = SOUND_MASK_MIC; | ||
93 | static int recording_active; | ||
94 | static int only_read_access; | ||
95 | static int only_8_bits; | ||
96 | |||
97 | static int iw_mode = 0; | ||
98 | int gus_wave_volume = 60; | ||
99 | int gus_pcm_volume = 80; | ||
100 | int have_gus_max = 0; | ||
101 | static int gus_line_vol = 100, gus_mic_vol; | ||
102 | static unsigned char mix_image = 0x00; | ||
103 | |||
104 | int gus_timer_enabled = 0; | ||
105 | |||
106 | /* | ||
107 | * Current version of this driver doesn't allow synth and PCM functions | ||
108 | * at the same time. The active_device specifies the active driver | ||
109 | */ | ||
110 | |||
111 | static int active_device; | ||
112 | |||
113 | #define GUS_DEV_WAVE 1 /* Wave table synth */ | ||
114 | #define GUS_DEV_PCM_DONE 2 /* PCM device, transfer done */ | ||
115 | #define GUS_DEV_PCM_CONTINUE 3 /* PCM device, transfer done ch. 1/2 */ | ||
116 | |||
117 | static int gus_audio_speed; | ||
118 | static int gus_audio_channels; | ||
119 | static int gus_audio_bits; | ||
120 | static int gus_audio_bsize; | ||
121 | static char bounce_buf[8 * 1024]; /* Must match value set to max_fragment */ | ||
122 | |||
123 | static DECLARE_WAIT_QUEUE_HEAD(dram_sleeper); | ||
124 | |||
125 | /* | ||
126 | * Variables and buffers for PCM output | ||
127 | */ | ||
128 | |||
129 | #define MAX_PCM_BUFFERS (128*MAX_REALTIME_FACTOR) /* Don't change */ | ||
130 | |||
131 | static int pcm_bsize, pcm_nblk, pcm_banksize; | ||
132 | static int pcm_datasize[MAX_PCM_BUFFERS]; | ||
133 | static volatile int pcm_head, pcm_tail, pcm_qlen; | ||
134 | static volatile int pcm_active; | ||
135 | static volatile int dma_active; | ||
136 | static int pcm_opened; | ||
137 | static int pcm_current_dev; | ||
138 | static int pcm_current_block; | ||
139 | static unsigned long pcm_current_buf; | ||
140 | static int pcm_current_count; | ||
141 | static int pcm_current_intrflag; | ||
142 | DEFINE_SPINLOCK(gus_lock); | ||
143 | |||
144 | extern int *gus_osp; | ||
145 | |||
146 | static struct voice_info voices[32]; | ||
147 | |||
148 | static int freq_div_table[] = | ||
149 | { | ||
150 | 44100, /* 14 */ | ||
151 | 41160, /* 15 */ | ||
152 | 38587, /* 16 */ | ||
153 | 36317, /* 17 */ | ||
154 | 34300, /* 18 */ | ||
155 | 32494, /* 19 */ | ||
156 | 30870, /* 20 */ | ||
157 | 29400, /* 21 */ | ||
158 | 28063, /* 22 */ | ||
159 | 26843, /* 23 */ | ||
160 | 25725, /* 24 */ | ||
161 | 24696, /* 25 */ | ||
162 | 23746, /* 26 */ | ||
163 | 22866, /* 27 */ | ||
164 | 22050, /* 28 */ | ||
165 | 21289, /* 29 */ | ||
166 | 20580, /* 30 */ | ||
167 | 19916, /* 31 */ | ||
168 | 19293 /* 32 */ | ||
169 | }; | ||
170 | |||
171 | static struct patch_info *samples; | ||
172 | static long sample_ptrs[MAX_SAMPLE + 1]; | ||
173 | static int sample_map[32]; | ||
174 | static int free_sample; | ||
175 | static int mixer_type; | ||
176 | |||
177 | |||
178 | static int patch_table[MAX_PATCH]; | ||
179 | static int patch_map[32]; | ||
180 | |||
181 | static struct synth_info gus_info = { | ||
182 | "Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, | ||
183 | 0, 16, 0, MAX_PATCH | ||
184 | }; | ||
185 | |||
186 | static void gus_poke(long addr, unsigned char data); | ||
187 | static void compute_and_set_volume(int voice, int volume, int ramp_time); | ||
188 | extern unsigned short gus_adagio_vol(int vel, int mainv, int xpn, int voicev); | ||
189 | extern unsigned short gus_linear_vol(int vol, int mainvol); | ||
190 | static void compute_volume(int voice, int volume); | ||
191 | static void do_volume_irq(int voice); | ||
192 | static void set_input_volumes(void); | ||
193 | static void gus_tmr_install(int io_base); | ||
194 | |||
195 | #define INSTANT_RAMP -1 /* Instant change. No ramping */ | ||
196 | #define FAST_RAMP 0 /* Fastest possible ramp */ | ||
197 | |||
198 | static void reset_sample_memory(void) | ||
199 | { | ||
200 | int i; | ||
201 | |||
202 | for (i = 0; i <= MAX_SAMPLE; i++) | ||
203 | sample_ptrs[i] = -1; | ||
204 | for (i = 0; i < 32; i++) | ||
205 | sample_map[i] = -1; | ||
206 | for (i = 0; i < 32; i++) | ||
207 | patch_map[i] = -1; | ||
208 | |||
209 | gus_poke(0, 0); /* Put a silent sample to the beginning */ | ||
210 | gus_poke(1, 0); | ||
211 | free_mem_ptr = 2; | ||
212 | |||
213 | free_sample = 0; | ||
214 | |||
215 | for (i = 0; i < MAX_PATCH; i++) | ||
216 | patch_table[i] = NOT_SAMPLE; | ||
217 | } | ||
218 | |||
219 | void gus_delay(void) | ||
220 | { | ||
221 | int i; | ||
222 | |||
223 | for (i = 0; i < 7; i++) | ||
224 | inb(u_DRAMIO); | ||
225 | } | ||
226 | |||
227 | static void gus_poke(long addr, unsigned char data) | ||
228 | { /* Writes a byte to the DRAM */ | ||
229 | outb((0x43), u_Command); | ||
230 | outb((addr & 0xff), u_DataLo); | ||
231 | outb(((addr >> 8) & 0xff), u_DataHi); | ||
232 | |||
233 | outb((0x44), u_Command); | ||
234 | outb(((addr >> 16) & 0xff), u_DataHi); | ||
235 | outb((data), u_DRAMIO); | ||
236 | } | ||
237 | |||
238 | static unsigned char gus_peek(long addr) | ||
239 | { /* Reads a byte from the DRAM */ | ||
240 | unsigned char tmp; | ||
241 | |||
242 | outb((0x43), u_Command); | ||
243 | outb((addr & 0xff), u_DataLo); | ||
244 | outb(((addr >> 8) & 0xff), u_DataHi); | ||
245 | |||
246 | outb((0x44), u_Command); | ||
247 | outb(((addr >> 16) & 0xff), u_DataHi); | ||
248 | tmp = inb(u_DRAMIO); | ||
249 | |||
250 | return tmp; | ||
251 | } | ||
252 | |||
253 | void gus_write8(int reg, unsigned int data) | ||
254 | { /* Writes to an indirect register (8 bit) */ | ||
255 | outb((reg), u_Command); | ||
256 | outb(((unsigned char) (data & 0xff)), u_DataHi); | ||
257 | } | ||
258 | |||
259 | static unsigned char gus_read8(int reg) | ||
260 | { | ||
261 | /* Reads from an indirect register (8 bit). Offset 0x80. */ | ||
262 | unsigned char val; | ||
263 | |||
264 | outb((reg | 0x80), u_Command); | ||
265 | val = inb(u_DataHi); | ||
266 | |||
267 | return val; | ||
268 | } | ||
269 | |||
270 | static unsigned char gus_look8(int reg) | ||
271 | { | ||
272 | /* Reads from an indirect register (8 bit). No additional offset. */ | ||
273 | unsigned char val; | ||
274 | |||
275 | outb((reg), u_Command); | ||
276 | val = inb(u_DataHi); | ||
277 | |||
278 | return val; | ||
279 | } | ||
280 | |||
281 | static void gus_write16(int reg, unsigned int data) | ||
282 | { | ||
283 | /* Writes to an indirect register (16 bit) */ | ||
284 | outb((reg), u_Command); | ||
285 | |||
286 | outb(((unsigned char) (data & 0xff)), u_DataLo); | ||
287 | outb(((unsigned char) ((data >> 8) & 0xff)), u_DataHi); | ||
288 | } | ||
289 | |||
290 | static unsigned short gus_read16(int reg) | ||
291 | { | ||
292 | /* Reads from an indirect register (16 bit). Offset 0x80. */ | ||
293 | unsigned char hi, lo; | ||
294 | |||
295 | outb((reg | 0x80), u_Command); | ||
296 | |||
297 | lo = inb(u_DataLo); | ||
298 | hi = inb(u_DataHi); | ||
299 | |||
300 | return ((hi << 8) & 0xff00) | lo; | ||
301 | } | ||
302 | |||
303 | static unsigned short gus_look16(int reg) | ||
304 | { | ||
305 | /* Reads from an indirect register (16 bit). No additional offset. */ | ||
306 | unsigned char hi, lo; | ||
307 | |||
308 | outb((reg), u_Command); | ||
309 | |||
310 | lo = inb(u_DataLo); | ||
311 | hi = inb(u_DataHi); | ||
312 | |||
313 | return ((hi << 8) & 0xff00) | lo; | ||
314 | } | ||
315 | |||
316 | static void gus_write_addr(int reg, unsigned long address, int frac, int is16bit) | ||
317 | { | ||
318 | /* Writes an 24 bit memory address */ | ||
319 | unsigned long hold_address; | ||
320 | |||
321 | if (is16bit) | ||
322 | { | ||
323 | if (iw_mode) | ||
324 | { | ||
325 | /* Interwave spesific address translations */ | ||
326 | address >>= 1; | ||
327 | } | ||
328 | else | ||
329 | { | ||
330 | /* | ||
331 | * Special processing required for 16 bit patches | ||
332 | */ | ||
333 | |||
334 | hold_address = address; | ||
335 | address = address >> 1; | ||
336 | address &= 0x0001ffffL; | ||
337 | address |= (hold_address & 0x000c0000L); | ||
338 | } | ||
339 | } | ||
340 | gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff)); | ||
341 | gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff) | ||
342 | + (frac << 5)); | ||
343 | /* Could writing twice fix problems with GUS_VOICE_POS()? Let's try. */ | ||
344 | gus_delay(); | ||
345 | gus_write16(reg, (unsigned short) ((address >> 7) & 0xffff)); | ||
346 | gus_write16(reg + 1, (unsigned short) ((address << 9) & 0xffff) | ||
347 | + (frac << 5)); | ||
348 | } | ||
349 | |||
350 | static void gus_select_voice(int voice) | ||
351 | { | ||
352 | if (voice < 0 || voice > 31) | ||
353 | return; | ||
354 | outb((voice), u_Voice); | ||
355 | } | ||
356 | |||
357 | static void gus_select_max_voices(int nvoices) | ||
358 | { | ||
359 | if (iw_mode) | ||
360 | nvoices = 32; | ||
361 | if (nvoices < 14) | ||
362 | nvoices = 14; | ||
363 | if (nvoices > 32) | ||
364 | nvoices = 32; | ||
365 | |||
366 | voice_alloc->max_voice = nr_voices = nvoices; | ||
367 | gus_write8(0x0e, (nvoices - 1) | 0xc0); | ||
368 | } | ||
369 | |||
370 | static void gus_voice_on(unsigned int mode) | ||
371 | { | ||
372 | gus_write8(0x00, (unsigned char) (mode & 0xfc)); | ||
373 | gus_delay(); | ||
374 | gus_write8(0x00, (unsigned char) (mode & 0xfc)); | ||
375 | } | ||
376 | |||
377 | static void gus_voice_off(void) | ||
378 | { | ||
379 | gus_write8(0x00, gus_read8(0x00) | 0x03); | ||
380 | } | ||
381 | |||
382 | static void gus_voice_mode(unsigned int m) | ||
383 | { | ||
384 | unsigned char mode = (unsigned char) (m & 0xff); | ||
385 | |||
386 | gus_write8(0x00, (gus_read8(0x00) & 0x03) | | ||
387 | (mode & 0xfc)); /* Don't touch last two bits */ | ||
388 | gus_delay(); | ||
389 | gus_write8(0x00, (gus_read8(0x00) & 0x03) | (mode & 0xfc)); | ||
390 | } | ||
391 | |||
392 | static void gus_voice_freq(unsigned long freq) | ||
393 | { | ||
394 | unsigned long divisor = freq_div_table[nr_voices - 14]; | ||
395 | unsigned short fc; | ||
396 | |||
397 | /* Interwave plays at 44100 Hz with any number of voices */ | ||
398 | if (iw_mode) | ||
399 | fc = (unsigned short) (((freq << 9) + (44100 >> 1)) / 44100); | ||
400 | else | ||
401 | fc = (unsigned short) (((freq << 9) + (divisor >> 1)) / divisor); | ||
402 | fc = fc << 1; | ||
403 | |||
404 | gus_write16(0x01, fc); | ||
405 | } | ||
406 | |||
407 | static void gus_voice_volume(unsigned int vol) | ||
408 | { | ||
409 | gus_write8(0x0d, 0x03); /* Stop ramp before setting volume */ | ||
410 | gus_write16(0x09, (unsigned short) (vol << 4)); | ||
411 | } | ||
412 | |||
413 | static void gus_voice_balance(unsigned int balance) | ||
414 | { | ||
415 | gus_write8(0x0c, (unsigned char) (balance & 0xff)); | ||
416 | } | ||
417 | |||
418 | static void gus_ramp_range(unsigned int low, unsigned int high) | ||
419 | { | ||
420 | gus_write8(0x07, (unsigned char) ((low >> 4) & 0xff)); | ||
421 | gus_write8(0x08, (unsigned char) ((high >> 4) & 0xff)); | ||
422 | } | ||
423 | |||
424 | static void gus_ramp_rate(unsigned int scale, unsigned int rate) | ||
425 | { | ||
426 | gus_write8(0x06, (unsigned char) (((scale & 0x03) << 6) | (rate & 0x3f))); | ||
427 | } | ||
428 | |||
429 | static void gus_rampon(unsigned int m) | ||
430 | { | ||
431 | unsigned char mode = (unsigned char) (m & 0xff); | ||
432 | |||
433 | gus_write8(0x0d, mode & 0xfc); | ||
434 | gus_delay(); | ||
435 | gus_write8(0x0d, mode & 0xfc); | ||
436 | } | ||
437 | |||
438 | static void gus_ramp_mode(unsigned int m) | ||
439 | { | ||
440 | unsigned char mode = (unsigned char) (m & 0xff); | ||
441 | |||
442 | gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | | ||
443 | (mode & 0xfc)); /* Leave the last 2 bits alone */ | ||
444 | gus_delay(); | ||
445 | gus_write8(0x0d, (gus_read8(0x0d) & 0x03) | (mode & 0xfc)); | ||
446 | } | ||
447 | |||
448 | static void gus_rampoff(void) | ||
449 | { | ||
450 | gus_write8(0x0d, 0x03); | ||
451 | } | ||
452 | |||
453 | static void gus_set_voice_pos(int voice, long position) | ||
454 | { | ||
455 | int sample_no; | ||
456 | |||
457 | if ((sample_no = sample_map[voice]) != -1) { | ||
458 | if (position < samples[sample_no].len) { | ||
459 | if (voices[voice].volume_irq_mode == VMODE_START_NOTE) | ||
460 | voices[voice].offset_pending = position; | ||
461 | else | ||
462 | gus_write_addr(0x0a, sample_ptrs[sample_no] + position, 0, | ||
463 | samples[sample_no].mode & WAVE_16_BITS); | ||
464 | } | ||
465 | } | ||
466 | } | ||
467 | |||
468 | static void gus_voice_init(int voice) | ||
469 | { | ||
470 | unsigned long flags; | ||
471 | |||
472 | spin_lock_irqsave(&gus_lock,flags); | ||
473 | gus_select_voice(voice); | ||
474 | gus_voice_volume(0); | ||
475 | gus_voice_off(); | ||
476 | gus_write_addr(0x0a, 0, 0, 0); /* Set current position to 0 */ | ||
477 | gus_write8(0x00, 0x03); /* Voice off */ | ||
478 | gus_write8(0x0d, 0x03); /* Ramping off */ | ||
479 | voice_alloc->map[voice] = 0; | ||
480 | voice_alloc->alloc_times[voice] = 0; | ||
481 | spin_unlock_irqrestore(&gus_lock,flags); | ||
482 | |||
483 | } | ||
484 | |||
485 | static void gus_voice_init2(int voice) | ||
486 | { | ||
487 | voices[voice].panning = 0; | ||
488 | voices[voice].mode = 0; | ||
489 | voices[voice].orig_freq = 20000; | ||
490 | voices[voice].current_freq = 20000; | ||
491 | voices[voice].bender = 0; | ||
492 | voices[voice].bender_range = 200; | ||
493 | voices[voice].initial_volume = 0; | ||
494 | voices[voice].current_volume = 0; | ||
495 | voices[voice].loop_irq_mode = 0; | ||
496 | voices[voice].loop_irq_parm = 0; | ||
497 | voices[voice].volume_irq_mode = 0; | ||
498 | voices[voice].volume_irq_parm = 0; | ||
499 | voices[voice].env_phase = 0; | ||
500 | voices[voice].main_vol = 127; | ||
501 | voices[voice].patch_vol = 127; | ||
502 | voices[voice].expression_vol = 127; | ||
503 | voices[voice].sample_pending = -1; | ||
504 | voices[voice].fixed_pitch = 0; | ||
505 | } | ||
506 | |||
507 | static void step_envelope(int voice) | ||
508 | { | ||
509 | unsigned vol, prev_vol, phase; | ||
510 | unsigned char rate; | ||
511 | unsigned long flags; | ||
512 | |||
513 | if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2) | ||
514 | { | ||
515 | spin_lock_irqsave(&gus_lock,flags); | ||
516 | gus_select_voice(voice); | ||
517 | gus_rampoff(); | ||
518 | spin_unlock_irqrestore(&gus_lock,flags); | ||
519 | return; | ||
520 | /* | ||
521 | * Sustain phase begins. Continue envelope after receiving note off. | ||
522 | */ | ||
523 | } | ||
524 | if (voices[voice].env_phase >= 5) | ||
525 | { | ||
526 | /* Envelope finished. Shoot the voice down */ | ||
527 | gus_voice_init(voice); | ||
528 | return; | ||
529 | } | ||
530 | prev_vol = voices[voice].current_volume; | ||
531 | phase = ++voices[voice].env_phase; | ||
532 | compute_volume(voice, voices[voice].midi_volume); | ||
533 | vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255; | ||
534 | rate = voices[voice].env_rate[phase]; | ||
535 | |||
536 | spin_lock_irqsave(&gus_lock,flags); | ||
537 | gus_select_voice(voice); | ||
538 | |||
539 | gus_voice_volume(prev_vol); | ||
540 | |||
541 | |||
542 | gus_write8(0x06, rate); /* Ramping rate */ | ||
543 | |||
544 | voices[voice].volume_irq_mode = VMODE_ENVELOPE; | ||
545 | |||
546 | if (((vol - prev_vol) / 64) == 0) /* No significant volume change */ | ||
547 | { | ||
548 | spin_unlock_irqrestore(&gus_lock,flags); | ||
549 | step_envelope(voice); /* Continue the envelope on the next step */ | ||
550 | return; | ||
551 | } | ||
552 | if (vol > prev_vol) | ||
553 | { | ||
554 | if (vol >= (4096 - 64)) | ||
555 | vol = 4096 - 65; | ||
556 | gus_ramp_range(0, vol); | ||
557 | gus_rampon(0x20); /* Increasing volume, with IRQ */ | ||
558 | } | ||
559 | else | ||
560 | { | ||
561 | if (vol <= 64) | ||
562 | vol = 65; | ||
563 | gus_ramp_range(vol, 4030); | ||
564 | gus_rampon(0x60); /* Decreasing volume, with IRQ */ | ||
565 | } | ||
566 | voices[voice].current_volume = vol; | ||
567 | spin_unlock_irqrestore(&gus_lock,flags); | ||
568 | } | ||
569 | |||
570 | static void init_envelope(int voice) | ||
571 | { | ||
572 | voices[voice].env_phase = -1; | ||
573 | voices[voice].current_volume = 64; | ||
574 | |||
575 | step_envelope(voice); | ||
576 | } | ||
577 | |||
578 | static void start_release(int voice) | ||
579 | { | ||
580 | if (gus_read8(0x00) & 0x03) | ||
581 | return; /* Voice already stopped */ | ||
582 | |||
583 | voices[voice].env_phase = 2; /* Will be incremented by step_envelope */ | ||
584 | |||
585 | voices[voice].current_volume = voices[voice].initial_volume = | ||
586 | gus_read16(0x09) >> 4; /* Get current volume */ | ||
587 | |||
588 | voices[voice].mode &= ~WAVE_SUSTAIN_ON; | ||
589 | gus_rampoff(); | ||
590 | step_envelope(voice); | ||
591 | } | ||
592 | |||
593 | static void gus_voice_fade(int voice) | ||
594 | { | ||
595 | int instr_no = sample_map[voice], is16bits; | ||
596 | unsigned long flags; | ||
597 | |||
598 | spin_lock_irqsave(&gus_lock,flags); | ||
599 | gus_select_voice(voice); | ||
600 | |||
601 | if (instr_no < 0 || instr_no > MAX_SAMPLE) | ||
602 | { | ||
603 | gus_write8(0x00, 0x03); /* Hard stop */ | ||
604 | voice_alloc->map[voice] = 0; | ||
605 | spin_unlock_irqrestore(&gus_lock,flags); | ||
606 | return; | ||
607 | } | ||
608 | is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* 8 or 16 bits */ | ||
609 | |||
610 | if (voices[voice].mode & WAVE_ENVELOPES) | ||
611 | { | ||
612 | start_release(voice); | ||
613 | spin_unlock_irqrestore(&gus_lock,flags); | ||
614 | return; | ||
615 | } | ||
616 | /* | ||
617 | * Ramp the volume down but not too quickly. | ||
618 | */ | ||
619 | if ((int) (gus_read16(0x09) >> 4) < 100) /* Get current volume */ | ||
620 | { | ||
621 | gus_voice_off(); | ||
622 | gus_rampoff(); | ||
623 | gus_voice_init(voice); | ||
624 | spin_unlock_irqrestore(&gus_lock,flags); | ||
625 | return; | ||
626 | } | ||
627 | gus_ramp_range(65, 4030); | ||
628 | gus_ramp_rate(2, 4); | ||
629 | gus_rampon(0x40 | 0x20); /* Down, once, with IRQ */ | ||
630 | voices[voice].volume_irq_mode = VMODE_HALT; | ||
631 | spin_unlock_irqrestore(&gus_lock,flags); | ||
632 | } | ||
633 | |||
634 | static void gus_reset(void) | ||
635 | { | ||
636 | int i; | ||
637 | |||
638 | gus_select_max_voices(24); | ||
639 | volume_base = 3071; | ||
640 | volume_scale = 4; | ||
641 | volume_method = VOL_METHOD_ADAGIO; | ||
642 | |||
643 | for (i = 0; i < 32; i++) | ||
644 | { | ||
645 | gus_voice_init(i); /* Turn voice off */ | ||
646 | gus_voice_init2(i); | ||
647 | } | ||
648 | } | ||
649 | |||
650 | static void gus_initialize(void) | ||
651 | { | ||
652 | unsigned long flags; | ||
653 | unsigned char dma_image, irq_image, tmp; | ||
654 | |||
655 | static unsigned char gus_irq_map[16] = { | ||
656 | 0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7 | ||
657 | }; | ||
658 | |||
659 | static unsigned char gus_dma_map[8] = { | ||
660 | 0, 1, 0, 2, 0, 3, 4, 5 | ||
661 | }; | ||
662 | |||
663 | spin_lock_irqsave(&gus_lock,flags); | ||
664 | gus_write8(0x4c, 0); /* Reset GF1 */ | ||
665 | gus_delay(); | ||
666 | gus_delay(); | ||
667 | |||
668 | gus_write8(0x4c, 1); /* Release Reset */ | ||
669 | gus_delay(); | ||
670 | gus_delay(); | ||
671 | |||
672 | /* | ||
673 | * Clear all interrupts | ||
674 | */ | ||
675 | |||
676 | gus_write8(0x41, 0); /* DMA control */ | ||
677 | gus_write8(0x45, 0); /* Timer control */ | ||
678 | gus_write8(0x49, 0); /* Sample control */ | ||
679 | |||
680 | gus_select_max_voices(24); | ||
681 | |||
682 | inb(u_Status); /* Touch the status register */ | ||
683 | |||
684 | gus_look8(0x41); /* Clear any pending DMA IRQs */ | ||
685 | gus_look8(0x49); /* Clear any pending sample IRQs */ | ||
686 | gus_read8(0x0f); /* Clear pending IRQs */ | ||
687 | |||
688 | gus_reset(); /* Resets all voices */ | ||
689 | |||
690 | gus_look8(0x41); /* Clear any pending DMA IRQs */ | ||
691 | gus_look8(0x49); /* Clear any pending sample IRQs */ | ||
692 | gus_read8(0x0f); /* Clear pending IRQs */ | ||
693 | |||
694 | gus_write8(0x4c, 7); /* Master reset | DAC enable | IRQ enable */ | ||
695 | |||
696 | /* | ||
697 | * Set up for Digital ASIC | ||
698 | */ | ||
699 | |||
700 | outb((0x05), gus_base + 0x0f); | ||
701 | |||
702 | mix_image |= 0x02; /* Disable line out (for a moment) */ | ||
703 | outb((mix_image), u_Mixer); | ||
704 | |||
705 | outb((0x00), u_IRQDMAControl); | ||
706 | |||
707 | outb((0x00), gus_base + 0x0f); | ||
708 | |||
709 | /* | ||
710 | * Now set up the DMA and IRQ interface | ||
711 | * | ||
712 | * The GUS supports two IRQs and two DMAs. | ||
713 | * | ||
714 | * Just one DMA channel is used. This prevents simultaneous ADC and DAC. | ||
715 | * Adding this support requires significant changes to the dmabuf.c, dsp.c | ||
716 | * and audio.c also. | ||
717 | */ | ||
718 | |||
719 | irq_image = 0; | ||
720 | tmp = gus_irq_map[gus_irq]; | ||
721 | if (!gus_pnp_flag && !tmp) | ||
722 | printk(KERN_WARNING "Warning! GUS IRQ not selected\n"); | ||
723 | irq_image |= tmp; | ||
724 | irq_image |= 0x40; /* Combine IRQ1 (GF1) and IRQ2 (Midi) */ | ||
725 | |||
726 | dual_dma_mode = 1; | ||
727 | if (gus_dma2 == gus_dma || gus_dma2 == -1) | ||
728 | { | ||
729 | dual_dma_mode = 0; | ||
730 | dma_image = 0x40; /* Combine DMA1 (DRAM) and IRQ2 (ADC) */ | ||
731 | |||
732 | tmp = gus_dma_map[gus_dma]; | ||
733 | if (!tmp) | ||
734 | printk(KERN_WARNING "Warning! GUS DMA not selected\n"); | ||
735 | |||
736 | dma_image |= tmp; | ||
737 | } | ||
738 | else | ||
739 | { | ||
740 | /* Setup dual DMA channel mode for GUS MAX */ | ||
741 | |||
742 | dma_image = gus_dma_map[gus_dma]; | ||
743 | if (!dma_image) | ||
744 | printk(KERN_WARNING "Warning! GUS DMA not selected\n"); | ||
745 | |||
746 | tmp = gus_dma_map[gus_dma2] << 3; | ||
747 | if (!tmp) | ||
748 | { | ||
749 | printk(KERN_WARNING "Warning! Invalid GUS MAX DMA\n"); | ||
750 | tmp = 0x40; /* Combine DMA channels */ | ||
751 | dual_dma_mode = 0; | ||
752 | } | ||
753 | dma_image |= tmp; | ||
754 | } | ||
755 | |||
756 | /* | ||
757 | * For some reason the IRQ and DMA addresses must be written twice | ||
758 | */ | ||
759 | |||
760 | /* | ||
761 | * Doing it first time | ||
762 | */ | ||
763 | |||
764 | outb((mix_image), u_Mixer); /* Select DMA control */ | ||
765 | outb((dma_image | 0x80), u_IRQDMAControl); /* Set DMA address */ | ||
766 | |||
767 | outb((mix_image | 0x40), u_Mixer); /* Select IRQ control */ | ||
768 | outb((irq_image), u_IRQDMAControl); /* Set IRQ address */ | ||
769 | |||
770 | /* | ||
771 | * Doing it second time | ||
772 | */ | ||
773 | |||
774 | outb((mix_image), u_Mixer); /* Select DMA control */ | ||
775 | outb((dma_image), u_IRQDMAControl); /* Set DMA address */ | ||
776 | |||
777 | outb((mix_image | 0x40), u_Mixer); /* Select IRQ control */ | ||
778 | outb((irq_image), u_IRQDMAControl); /* Set IRQ address */ | ||
779 | |||
780 | gus_select_voice(0); /* This disables writes to IRQ/DMA reg */ | ||
781 | |||
782 | mix_image &= ~0x02; /* Enable line out */ | ||
783 | mix_image |= 0x08; /* Enable IRQ */ | ||
784 | outb((mix_image), u_Mixer); /* | ||
785 | * Turn mixer channels on | ||
786 | * Note! Mic in is left off. | ||
787 | */ | ||
788 | |||
789 | gus_select_voice(0); /* This disables writes to IRQ/DMA reg */ | ||
790 | |||
791 | gusintr(gus_irq, (void *)gus_hw_config, NULL); /* Serve pending interrupts */ | ||
792 | |||
793 | inb(u_Status); /* Touch the status register */ | ||
794 | |||
795 | gus_look8(0x41); /* Clear any pending DMA IRQs */ | ||
796 | gus_look8(0x49); /* Clear any pending sample IRQs */ | ||
797 | |||
798 | gus_read8(0x0f); /* Clear pending IRQs */ | ||
799 | |||
800 | if (iw_mode) | ||
801 | gus_write8(0x19, gus_read8(0x19) | 0x01); | ||
802 | spin_unlock_irqrestore(&gus_lock,flags); | ||
803 | } | ||
804 | |||
805 | |||
806 | static void __init pnp_mem_init(void) | ||
807 | { | ||
808 | #include "iwmem.h" | ||
809 | #define CHUNK_SIZE (256*1024) | ||
810 | #define BANK_SIZE (4*1024*1024) | ||
811 | #define CHUNKS_PER_BANK (BANK_SIZE/CHUNK_SIZE) | ||
812 | |||
813 | int bank, chunk, addr, total = 0; | ||
814 | int bank_sizes[4]; | ||
815 | int i, j, bits = -1, testbits = -1, nbanks = 0; | ||
816 | |||
817 | /* | ||
818 | * This routine determines what kind of RAM is installed in each of the four | ||
819 | * SIMM banks and configures the DRAM address decode logic accordingly. | ||
820 | */ | ||
821 | |||
822 | /* | ||
823 | * Place the chip into enhanced mode | ||
824 | */ | ||
825 | gus_write8(0x19, gus_read8(0x19) | 0x01); | ||
826 | gus_write8(0x53, gus_look8(0x53) & ~0x02); /* Select DRAM I/O access */ | ||
827 | |||
828 | /* | ||
829 | * Set memory configuration to 4 DRAM banks of 4M in each (16M total). | ||
830 | */ | ||
831 | |||
832 | gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | 0x000c); | ||
833 | |||
834 | /* | ||
835 | * Perform the DRAM size detection for each bank individually. | ||
836 | */ | ||
837 | for (bank = 0; bank < 4; bank++) | ||
838 | { | ||
839 | int size = 0; | ||
840 | |||
841 | addr = bank * BANK_SIZE; | ||
842 | |||
843 | /* Clean check points of each chunk */ | ||
844 | for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++) | ||
845 | { | ||
846 | gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00); | ||
847 | gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00); | ||
848 | } | ||
849 | |||
850 | /* Write a value to each chunk point and verify the result */ | ||
851 | for (chunk = 0; chunk < CHUNKS_PER_BANK; chunk++) | ||
852 | { | ||
853 | gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x55); | ||
854 | gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0xAA); | ||
855 | |||
856 | if (gus_peek(addr + chunk * CHUNK_SIZE + 0L) == 0x55 && | ||
857 | gus_peek(addr + chunk * CHUNK_SIZE + 1L) == 0xAA) | ||
858 | { | ||
859 | /* OK. There is RAM. Now check for possible shadows */ | ||
860 | int ok = 1, chunk2; | ||
861 | |||
862 | for (chunk2 = 0; ok && chunk2 < chunk; chunk2++) | ||
863 | if (gus_peek(addr + chunk2 * CHUNK_SIZE + 0L) || | ||
864 | gus_peek(addr + chunk2 * CHUNK_SIZE + 1L)) | ||
865 | ok = 0; /* Addressing wraps */ | ||
866 | |||
867 | if (ok) | ||
868 | size = (chunk + 1) * CHUNK_SIZE; | ||
869 | } | ||
870 | gus_poke(addr + chunk * CHUNK_SIZE + 0L, 0x00); | ||
871 | gus_poke(addr + chunk * CHUNK_SIZE + 1L, 0x00); | ||
872 | } | ||
873 | bank_sizes[bank] = size; | ||
874 | if (size) | ||
875 | nbanks = bank + 1; | ||
876 | DDB(printk("Interwave: Bank %d, size=%dk\n", bank, size / 1024)); | ||
877 | } | ||
878 | |||
879 | if (nbanks == 0) /* No RAM - Give up */ | ||
880 | { | ||
881 | printk(KERN_ERR "Sound: An Interwave audio chip detected but no DRAM\n"); | ||
882 | printk(KERN_ERR "Sound: Unable to work with this card.\n"); | ||
883 | gus_write8(0x19, gus_read8(0x19) & ~0x01); | ||
884 | gus_mem_size = 0; | ||
885 | return; | ||
886 | } | ||
887 | |||
888 | /* | ||
889 | * Now we know how much DRAM there is in each bank. The next step is | ||
890 | * to find a DRAM size encoding (0 to 12) which is best for the combination | ||
891 | * we have. | ||
892 | * | ||
893 | * First try if any of the possible alternatives matches exactly the amount | ||
894 | * of memory we have. | ||
895 | */ | ||
896 | |||
897 | for (i = 0; bits == -1 && i < 13; i++) | ||
898 | { | ||
899 | bits = i; | ||
900 | |||
901 | for (j = 0; bits != -1 && j < 4; j++) | ||
902 | if (mem_decode[i][j] != bank_sizes[j]) | ||
903 | bits = -1; /* No hit */ | ||
904 | } | ||
905 | |||
906 | /* | ||
907 | * If necessary, try to find a combination where other than the last | ||
908 | * bank matches our configuration and the last bank is left oversized. | ||
909 | * In this way we don't leave holes in the middle of memory. | ||
910 | */ | ||
911 | |||
912 | if (bits == -1) /* No luck yet */ | ||
913 | { | ||
914 | for (i = 0; bits == -1 && i < 13; i++) | ||
915 | { | ||
916 | bits = i; | ||
917 | |||
918 | for (j = 0; bits != -1 && j < nbanks - 1; j++) | ||
919 | if (mem_decode[i][j] != bank_sizes[j]) | ||
920 | bits = -1; /* No hit */ | ||
921 | if (mem_decode[i][nbanks - 1] < bank_sizes[nbanks - 1]) | ||
922 | bits = -1; /* The last bank is too small */ | ||
923 | } | ||
924 | } | ||
925 | /* | ||
926 | * The last resort is to search for a combination where the banks are | ||
927 | * smaller than the actual SIMMs. This leaves some memory in the banks | ||
928 | * unused but doesn't leave holes in the DRAM address space. | ||
929 | */ | ||
930 | if (bits == -1) /* No luck yet */ | ||
931 | { | ||
932 | for (i = 0; i < 13; i++) | ||
933 | { | ||
934 | testbits = i; | ||
935 | for (j = 0; testbits != -1 && j < nbanks - 1; j++) | ||
936 | if (mem_decode[i][j] > bank_sizes[j]) { | ||
937 | testbits = -1; | ||
938 | } | ||
939 | if(testbits > bits) bits = testbits; | ||
940 | } | ||
941 | if (bits != -1) | ||
942 | { | ||
943 | printk(KERN_INFO "Interwave: Can't use all installed RAM.\n"); | ||
944 | printk(KERN_INFO "Interwave: Try reordering SIMMS.\n"); | ||
945 | } | ||
946 | printk(KERN_INFO "Interwave: Can't find working DRAM encoding.\n"); | ||
947 | printk(KERN_INFO "Interwave: Defaulting to 256k. Try reordering SIMMS.\n"); | ||
948 | bits = 0; | ||
949 | } | ||
950 | DDB(printk("Interwave: Selecting DRAM addressing mode %d\n", bits)); | ||
951 | |||
952 | for (bank = 0; bank < 4; bank++) | ||
953 | { | ||
954 | DDB(printk(" Bank %d, mem=%dk (limit %dk)\n", bank, bank_sizes[bank] / 1024, mem_decode[bits][bank] / 1024)); | ||
955 | |||
956 | if (bank_sizes[bank] > mem_decode[bits][bank]) | ||
957 | total += mem_decode[bits][bank]; | ||
958 | else | ||
959 | total += bank_sizes[bank]; | ||
960 | } | ||
961 | |||
962 | DDB(printk("Total %dk of DRAM (enhanced mode)\n", total / 1024)); | ||
963 | |||
964 | /* | ||
965 | * Set the memory addressing mode. | ||
966 | */ | ||
967 | gus_write16(0x52, (gus_look16(0x52) & 0xfff0) | bits); | ||
968 | |||
969 | /* Leave the chip into enhanced mode. Disable LFO */ | ||
970 | gus_mem_size = total; | ||
971 | iw_mode = 1; | ||
972 | gus_write8(0x19, (gus_read8(0x19) | 0x01) & ~0x02); | ||
973 | } | ||
974 | |||
975 | int __init gus_wave_detect(int baseaddr) | ||
976 | { | ||
977 | unsigned long i, max_mem = 1024L; | ||
978 | unsigned long loc; | ||
979 | unsigned char val; | ||
980 | |||
981 | if (!request_region(baseaddr, 16, "GUS")) | ||
982 | return 0; | ||
983 | if (!request_region(baseaddr + 0x100, 12, "GUS")) { /* 0x10c-> is MAX */ | ||
984 | release_region(baseaddr, 16); | ||
985 | return 0; | ||
986 | } | ||
987 | |||
988 | gus_base = baseaddr; | ||
989 | |||
990 | gus_write8(0x4c, 0); /* Reset GF1 */ | ||
991 | gus_delay(); | ||
992 | gus_delay(); | ||
993 | |||
994 | gus_write8(0x4c, 1); /* Release Reset */ | ||
995 | gus_delay(); | ||
996 | gus_delay(); | ||
997 | |||
998 | #ifdef GUSPNP_AUTODETECT | ||
999 | val = gus_look8(0x5b); /* Version number register */ | ||
1000 | gus_write8(0x5b, ~val); /* Invert all bits */ | ||
1001 | |||
1002 | if ((gus_look8(0x5b) & 0xf0) == (val & 0xf0)) /* No change */ | ||
1003 | { | ||
1004 | if ((gus_look8(0x5b) & 0x0f) == ((~val) & 0x0f)) /* Change */ | ||
1005 | { | ||
1006 | DDB(printk("Interwave chip version %d detected\n", (val & 0xf0) >> 4)); | ||
1007 | gus_pnp_flag = 1; | ||
1008 | } | ||
1009 | else | ||
1010 | { | ||
1011 | DDB(printk("Not an Interwave chip (%x)\n", gus_look8(0x5b))); | ||
1012 | gus_pnp_flag = 0; | ||
1013 | } | ||
1014 | } | ||
1015 | gus_write8(0x5b, val); /* Restore all bits */ | ||
1016 | #endif | ||
1017 | |||
1018 | if (gus_pnp_flag) | ||
1019 | pnp_mem_init(); | ||
1020 | if (iw_mode) | ||
1021 | return 1; | ||
1022 | |||
1023 | /* See if there is first block there.... */ | ||
1024 | gus_poke(0L, 0xaa); | ||
1025 | if (gus_peek(0L) != 0xaa) { | ||
1026 | release_region(baseaddr + 0x100, 12); | ||
1027 | release_region(baseaddr, 16); | ||
1028 | return 0; | ||
1029 | } | ||
1030 | |||
1031 | /* Now zero it out so that I can check for mirroring .. */ | ||
1032 | gus_poke(0L, 0x00); | ||
1033 | for (i = 1L; i < max_mem; i++) | ||
1034 | { | ||
1035 | int n, failed; | ||
1036 | |||
1037 | /* check for mirroring ... */ | ||
1038 | if (gus_peek(0L) != 0) | ||
1039 | break; | ||
1040 | loc = i << 10; | ||
1041 | |||
1042 | for (n = loc - 1, failed = 0; n <= loc; n++) | ||
1043 | { | ||
1044 | gus_poke(loc, 0xaa); | ||
1045 | if (gus_peek(loc) != 0xaa) | ||
1046 | failed = 1; | ||
1047 | gus_poke(loc, 0x55); | ||
1048 | if (gus_peek(loc) != 0x55) | ||
1049 | failed = 1; | ||
1050 | } | ||
1051 | if (failed) | ||
1052 | break; | ||
1053 | } | ||
1054 | gus_mem_size = i << 10; | ||
1055 | return 1; | ||
1056 | } | ||
1057 | |||
1058 | static int guswave_ioctl(int dev, unsigned int cmd, void __user *arg) | ||
1059 | { | ||
1060 | |||
1061 | switch (cmd) | ||
1062 | { | ||
1063 | case SNDCTL_SYNTH_INFO: | ||
1064 | gus_info.nr_voices = nr_voices; | ||
1065 | if (copy_to_user(arg, &gus_info, sizeof(gus_info))) | ||
1066 | return -EFAULT; | ||
1067 | return 0; | ||
1068 | |||
1069 | case SNDCTL_SEQ_RESETSAMPLES: | ||
1070 | reset_sample_memory(); | ||
1071 | return 0; | ||
1072 | |||
1073 | case SNDCTL_SEQ_PERCMODE: | ||
1074 | return 0; | ||
1075 | |||
1076 | case SNDCTL_SYNTH_MEMAVL: | ||
1077 | return (gus_mem_size == 0) ? 0 : gus_mem_size - free_mem_ptr - 32; | ||
1078 | |||
1079 | default: | ||
1080 | return -EINVAL; | ||
1081 | } | ||
1082 | } | ||
1083 | |||
1084 | static int guswave_set_instr(int dev, int voice, int instr_no) | ||
1085 | { | ||
1086 | int sample_no; | ||
1087 | |||
1088 | if (instr_no < 0 || instr_no > MAX_PATCH) | ||
1089 | instr_no = 0; /* Default to acoustic piano */ | ||
1090 | |||
1091 | if (voice < 0 || voice > 31) | ||
1092 | return -EINVAL; | ||
1093 | |||
1094 | if (voices[voice].volume_irq_mode == VMODE_START_NOTE) | ||
1095 | { | ||
1096 | voices[voice].sample_pending = instr_no; | ||
1097 | return 0; | ||
1098 | } | ||
1099 | sample_no = patch_table[instr_no]; | ||
1100 | patch_map[voice] = -1; | ||
1101 | |||
1102 | if (sample_no == NOT_SAMPLE) | ||
1103 | { | ||
1104 | /* printk("GUS: Undefined patch %d for voice %d\n", instr_no, voice);*/ | ||
1105 | return -EINVAL; /* Patch not defined */ | ||
1106 | } | ||
1107 | if (sample_ptrs[sample_no] == -1) /* Sample not loaded */ | ||
1108 | { | ||
1109 | /* printk("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);*/ | ||
1110 | return -EINVAL; | ||
1111 | } | ||
1112 | sample_map[voice] = sample_no; | ||
1113 | patch_map[voice] = instr_no; | ||
1114 | return 0; | ||
1115 | } | ||
1116 | |||
1117 | static int guswave_kill_note(int dev, int voice, int note, int velocity) | ||
1118 | { | ||
1119 | unsigned long flags; | ||
1120 | |||
1121 | spin_lock_irqsave(&gus_lock,flags); | ||
1122 | /* voice_alloc->map[voice] = 0xffff; */ | ||
1123 | if (voices[voice].volume_irq_mode == VMODE_START_NOTE) | ||
1124 | { | ||
1125 | voices[voice].kill_pending = 1; | ||
1126 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1127 | } | ||
1128 | else | ||
1129 | { | ||
1130 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1131 | gus_voice_fade(voice); | ||
1132 | } | ||
1133 | |||
1134 | return 0; | ||
1135 | } | ||
1136 | |||
1137 | static void guswave_aftertouch(int dev, int voice, int pressure) | ||
1138 | { | ||
1139 | } | ||
1140 | |||
1141 | static void guswave_panning(int dev, int voice, int value) | ||
1142 | { | ||
1143 | if (voice >= 0 || voice < 32) | ||
1144 | voices[voice].panning = value; | ||
1145 | } | ||
1146 | |||
1147 | static void guswave_volume_method(int dev, int mode) | ||
1148 | { | ||
1149 | if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO) | ||
1150 | volume_method = mode; | ||
1151 | } | ||
1152 | |||
1153 | static void compute_volume(int voice, int volume) | ||
1154 | { | ||
1155 | if (volume < 128) | ||
1156 | voices[voice].midi_volume = volume; | ||
1157 | |||
1158 | switch (volume_method) | ||
1159 | { | ||
1160 | case VOL_METHOD_ADAGIO: | ||
1161 | voices[voice].initial_volume = | ||
1162 | gus_adagio_vol(voices[voice].midi_volume, voices[voice].main_vol, | ||
1163 | voices[voice].expression_vol, | ||
1164 | voices[voice].patch_vol); | ||
1165 | break; | ||
1166 | |||
1167 | case VOL_METHOD_LINEAR: /* Totally ignores patch-volume and expression */ | ||
1168 | voices[voice].initial_volume = gus_linear_vol(volume, voices[voice].main_vol); | ||
1169 | break; | ||
1170 | |||
1171 | default: | ||
1172 | voices[voice].initial_volume = volume_base + | ||
1173 | (voices[voice].midi_volume * volume_scale); | ||
1174 | } | ||
1175 | |||
1176 | if (voices[voice].initial_volume > 4030) | ||
1177 | voices[voice].initial_volume = 4030; | ||
1178 | } | ||
1179 | |||
1180 | static void compute_and_set_volume(int voice, int volume, int ramp_time) | ||
1181 | { | ||
1182 | int curr, target, rate; | ||
1183 | unsigned long flags; | ||
1184 | |||
1185 | compute_volume(voice, volume); | ||
1186 | voices[voice].current_volume = voices[voice].initial_volume; | ||
1187 | |||
1188 | spin_lock_irqsave(&gus_lock,flags); | ||
1189 | /* | ||
1190 | * CAUTION! Interrupts disabled. Enable them before returning | ||
1191 | */ | ||
1192 | |||
1193 | gus_select_voice(voice); | ||
1194 | |||
1195 | curr = gus_read16(0x09) >> 4; | ||
1196 | target = voices[voice].initial_volume; | ||
1197 | |||
1198 | if (ramp_time == INSTANT_RAMP) | ||
1199 | { | ||
1200 | gus_rampoff(); | ||
1201 | gus_voice_volume(target); | ||
1202 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1203 | return; | ||
1204 | } | ||
1205 | if (ramp_time == FAST_RAMP) | ||
1206 | rate = 63; | ||
1207 | else | ||
1208 | rate = 16; | ||
1209 | gus_ramp_rate(0, rate); | ||
1210 | |||
1211 | if ((target - curr) / 64 == 0) /* Close enough to target. */ | ||
1212 | { | ||
1213 | gus_rampoff(); | ||
1214 | gus_voice_volume(target); | ||
1215 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1216 | return; | ||
1217 | } | ||
1218 | if (target > curr) | ||
1219 | { | ||
1220 | if (target > (4095 - 65)) | ||
1221 | target = 4095 - 65; | ||
1222 | gus_ramp_range(curr, target); | ||
1223 | gus_rampon(0x00); /* Ramp up, once, no IRQ */ | ||
1224 | } | ||
1225 | else | ||
1226 | { | ||
1227 | if (target < 65) | ||
1228 | target = 65; | ||
1229 | |||
1230 | gus_ramp_range(target, curr); | ||
1231 | gus_rampon(0x40); /* Ramp down, once, no irq */ | ||
1232 | } | ||
1233 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1234 | } | ||
1235 | |||
1236 | static void dynamic_volume_change(int voice) | ||
1237 | { | ||
1238 | unsigned char status; | ||
1239 | unsigned long flags; | ||
1240 | |||
1241 | spin_lock_irqsave(&gus_lock,flags); | ||
1242 | gus_select_voice(voice); | ||
1243 | status = gus_read8(0x00); /* Get voice status */ | ||
1244 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1245 | |||
1246 | if (status & 0x03) | ||
1247 | return; /* Voice was not running */ | ||
1248 | |||
1249 | if (!(voices[voice].mode & WAVE_ENVELOPES)) | ||
1250 | { | ||
1251 | compute_and_set_volume(voice, voices[voice].midi_volume, 1); | ||
1252 | return; | ||
1253 | } | ||
1254 | |||
1255 | /* | ||
1256 | * Voice is running and has envelopes. | ||
1257 | */ | ||
1258 | |||
1259 | spin_lock_irqsave(&gus_lock,flags); | ||
1260 | gus_select_voice(voice); | ||
1261 | status = gus_read8(0x0d); /* Ramping status */ | ||
1262 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1263 | |||
1264 | if (status & 0x03) /* Sustain phase? */ | ||
1265 | { | ||
1266 | compute_and_set_volume(voice, voices[voice].midi_volume, 1); | ||
1267 | return; | ||
1268 | } | ||
1269 | if (voices[voice].env_phase < 0) | ||
1270 | return; | ||
1271 | |||
1272 | compute_volume(voice, voices[voice].midi_volume); | ||
1273 | |||
1274 | } | ||
1275 | |||
1276 | static void guswave_controller(int dev, int voice, int ctrl_num, int value) | ||
1277 | { | ||
1278 | unsigned long flags; | ||
1279 | unsigned long freq; | ||
1280 | |||
1281 | if (voice < 0 || voice > 31) | ||
1282 | return; | ||
1283 | |||
1284 | switch (ctrl_num) | ||
1285 | { | ||
1286 | case CTRL_PITCH_BENDER: | ||
1287 | voices[voice].bender = value; | ||
1288 | |||
1289 | if (voices[voice].volume_irq_mode != VMODE_START_NOTE) | ||
1290 | { | ||
1291 | freq = compute_finetune(voices[voice].orig_freq, value, voices[voice].bender_range, 0); | ||
1292 | voices[voice].current_freq = freq; | ||
1293 | |||
1294 | spin_lock_irqsave(&gus_lock,flags); | ||
1295 | gus_select_voice(voice); | ||
1296 | gus_voice_freq(freq); | ||
1297 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1298 | } | ||
1299 | break; | ||
1300 | |||
1301 | case CTRL_PITCH_BENDER_RANGE: | ||
1302 | voices[voice].bender_range = value; | ||
1303 | break; | ||
1304 | case CTL_EXPRESSION: | ||
1305 | value /= 128; | ||
1306 | case CTRL_EXPRESSION: | ||
1307 | if (volume_method == VOL_METHOD_ADAGIO) | ||
1308 | { | ||
1309 | voices[voice].expression_vol = value; | ||
1310 | if (voices[voice].volume_irq_mode != VMODE_START_NOTE) | ||
1311 | dynamic_volume_change(voice); | ||
1312 | } | ||
1313 | break; | ||
1314 | |||
1315 | case CTL_PAN: | ||
1316 | voices[voice].panning = (value * 2) - 128; | ||
1317 | break; | ||
1318 | |||
1319 | case CTL_MAIN_VOLUME: | ||
1320 | value = (value * 100) / 16383; | ||
1321 | |||
1322 | case CTRL_MAIN_VOLUME: | ||
1323 | voices[voice].main_vol = value; | ||
1324 | if (voices[voice].volume_irq_mode != VMODE_START_NOTE) | ||
1325 | dynamic_volume_change(voice); | ||
1326 | break; | ||
1327 | |||
1328 | default: | ||
1329 | break; | ||
1330 | } | ||
1331 | } | ||
1332 | |||
1333 | static int guswave_start_note2(int dev, int voice, int note_num, int volume) | ||
1334 | { | ||
1335 | int sample, best_sample, best_delta, delta_freq; | ||
1336 | int is16bits, samplep, patch, pan; | ||
1337 | unsigned long note_freq, base_note, freq, flags; | ||
1338 | unsigned char mode = 0; | ||
1339 | |||
1340 | if (voice < 0 || voice > 31) | ||
1341 | { | ||
1342 | /* printk("GUS: Invalid voice\n");*/ | ||
1343 | return -EINVAL; | ||
1344 | } | ||
1345 | if (note_num == 255) | ||
1346 | { | ||
1347 | if (voices[voice].mode & WAVE_ENVELOPES) | ||
1348 | { | ||
1349 | voices[voice].midi_volume = volume; | ||
1350 | dynamic_volume_change(voice); | ||
1351 | return 0; | ||
1352 | } | ||
1353 | compute_and_set_volume(voice, volume, 1); | ||
1354 | return 0; | ||
1355 | } | ||
1356 | if ((patch = patch_map[voice]) == -1) | ||
1357 | return -EINVAL; | ||
1358 | if ((samplep = patch_table[patch]) == NOT_SAMPLE) | ||
1359 | { | ||
1360 | return -EINVAL; | ||
1361 | } | ||
1362 | note_freq = note_to_freq(note_num); | ||
1363 | |||
1364 | /* | ||
1365 | * Find a sample within a patch so that the note_freq is between low_note | ||
1366 | * and high_note. | ||
1367 | */ | ||
1368 | sample = -1; | ||
1369 | |||
1370 | best_sample = samplep; | ||
1371 | best_delta = 1000000; | ||
1372 | while (samplep != 0 && samplep != NOT_SAMPLE && sample == -1) | ||
1373 | { | ||
1374 | delta_freq = note_freq - samples[samplep].base_note; | ||
1375 | if (delta_freq < 0) | ||
1376 | delta_freq = -delta_freq; | ||
1377 | if (delta_freq < best_delta) | ||
1378 | { | ||
1379 | best_sample = samplep; | ||
1380 | best_delta = delta_freq; | ||
1381 | } | ||
1382 | if (samples[samplep].low_note <= note_freq && | ||
1383 | note_freq <= samples[samplep].high_note) | ||
1384 | { | ||
1385 | sample = samplep; | ||
1386 | } | ||
1387 | else | ||
1388 | samplep = samples[samplep].key; /* Link to next sample */ | ||
1389 | } | ||
1390 | if (sample == -1) | ||
1391 | sample = best_sample; | ||
1392 | |||
1393 | if (sample == -1) | ||
1394 | { | ||
1395 | /* printk("GUS: Patch %d not defined for note %d\n", patch, note_num);*/ | ||
1396 | return 0; /* Should play default patch ??? */ | ||
1397 | } | ||
1398 | is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0; | ||
1399 | voices[voice].mode = samples[sample].mode; | ||
1400 | voices[voice].patch_vol = samples[sample].volume; | ||
1401 | |||
1402 | if (iw_mode) | ||
1403 | gus_write8(0x15, 0x00); /* RAM, Reset voice deactivate bit of SMSI */ | ||
1404 | |||
1405 | if (voices[voice].mode & WAVE_ENVELOPES) | ||
1406 | { | ||
1407 | int i; | ||
1408 | |||
1409 | for (i = 0; i < 6; i++) | ||
1410 | { | ||
1411 | voices[voice].env_rate[i] = samples[sample].env_rate[i]; | ||
1412 | voices[voice].env_offset[i] = samples[sample].env_offset[i]; | ||
1413 | } | ||
1414 | } | ||
1415 | sample_map[voice] = sample; | ||
1416 | |||
1417 | if (voices[voice].fixed_pitch) /* Fixed pitch */ | ||
1418 | { | ||
1419 | freq = samples[sample].base_freq; | ||
1420 | } | ||
1421 | else | ||
1422 | { | ||
1423 | base_note = samples[sample].base_note / 100; | ||
1424 | note_freq /= 100; | ||
1425 | |||
1426 | freq = samples[sample].base_freq * note_freq / base_note; | ||
1427 | } | ||
1428 | |||
1429 | voices[voice].orig_freq = freq; | ||
1430 | |||
1431 | /* | ||
1432 | * Since the pitch bender may have been set before playing the note, we | ||
1433 | * have to calculate the bending now. | ||
1434 | */ | ||
1435 | |||
1436 | freq = compute_finetune(voices[voice].orig_freq, voices[voice].bender, | ||
1437 | voices[voice].bender_range, 0); | ||
1438 | voices[voice].current_freq = freq; | ||
1439 | |||
1440 | pan = (samples[sample].panning + voices[voice].panning) / 32; | ||
1441 | pan += 7; | ||
1442 | if (pan < 0) | ||
1443 | pan = 0; | ||
1444 | if (pan > 15) | ||
1445 | pan = 15; | ||
1446 | |||
1447 | if (samples[sample].mode & WAVE_16_BITS) | ||
1448 | { | ||
1449 | mode |= 0x04; /* 16 bits */ | ||
1450 | if ((sample_ptrs[sample] / GUS_BANK_SIZE) != | ||
1451 | ((sample_ptrs[sample] + samples[sample].len) / GUS_BANK_SIZE)) | ||
1452 | printk(KERN_ERR "GUS: Sample address error\n"); | ||
1453 | } | ||
1454 | spin_lock_irqsave(&gus_lock,flags); | ||
1455 | gus_select_voice(voice); | ||
1456 | gus_voice_off(); | ||
1457 | gus_rampoff(); | ||
1458 | |||
1459 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1460 | |||
1461 | if (voices[voice].mode & WAVE_ENVELOPES) | ||
1462 | { | ||
1463 | compute_volume(voice, volume); | ||
1464 | init_envelope(voice); | ||
1465 | } | ||
1466 | else | ||
1467 | { | ||
1468 | compute_and_set_volume(voice, volume, 0); | ||
1469 | } | ||
1470 | |||
1471 | spin_lock_irqsave(&gus_lock,flags); | ||
1472 | gus_select_voice(voice); | ||
1473 | |||
1474 | if (samples[sample].mode & WAVE_LOOP_BACK) | ||
1475 | gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].len - | ||
1476 | voices[voice].offset_pending, 0, is16bits); /* start=end */ | ||
1477 | else | ||
1478 | gus_write_addr(0x0a, sample_ptrs[sample] + voices[voice].offset_pending, 0, is16bits); /* Sample start=begin */ | ||
1479 | |||
1480 | if (samples[sample].mode & WAVE_LOOPING) | ||
1481 | { | ||
1482 | mode |= 0x08; | ||
1483 | |||
1484 | if (samples[sample].mode & WAVE_BIDIR_LOOP) | ||
1485 | mode |= 0x10; | ||
1486 | |||
1487 | if (samples[sample].mode & WAVE_LOOP_BACK) | ||
1488 | { | ||
1489 | gus_write_addr(0x0a, sample_ptrs[sample] + samples[sample].loop_end - | ||
1490 | voices[voice].offset_pending, | ||
1491 | (samples[sample].fractions >> 4) & 0x0f, is16bits); | ||
1492 | mode |= 0x40; | ||
1493 | } | ||
1494 | gus_write_addr(0x02, sample_ptrs[sample] + samples[sample].loop_start, | ||
1495 | samples[sample].fractions & 0x0f, is16bits); /* Loop start location */ | ||
1496 | gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].loop_end, | ||
1497 | (samples[sample].fractions >> 4) & 0x0f, is16bits); /* Loop end location */ | ||
1498 | } | ||
1499 | else | ||
1500 | { | ||
1501 | mode |= 0x20; /* Loop IRQ at the end */ | ||
1502 | voices[voice].loop_irq_mode = LMODE_FINISH; /* Ramp down at the end */ | ||
1503 | voices[voice].loop_irq_parm = 1; | ||
1504 | gus_write_addr(0x02, sample_ptrs[sample], 0, is16bits); /* Loop start location */ | ||
1505 | gus_write_addr(0x04, sample_ptrs[sample] + samples[sample].len - 1, | ||
1506 | (samples[sample].fractions >> 4) & 0x0f, is16bits); /* Loop end location */ | ||
1507 | } | ||
1508 | gus_voice_freq(freq); | ||
1509 | gus_voice_balance(pan); | ||
1510 | gus_voice_on(mode); | ||
1511 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1512 | |||
1513 | return 0; | ||
1514 | } | ||
1515 | |||
1516 | /* | ||
1517 | * New guswave_start_note by Andrew J. Robinson attempts to minimize clicking | ||
1518 | * when the note playing on the voice is changed. It uses volume | ||
1519 | * ramping. | ||
1520 | */ | ||
1521 | |||
1522 | static int guswave_start_note(int dev, int voice, int note_num, int volume) | ||
1523 | { | ||
1524 | unsigned long flags; | ||
1525 | int mode; | ||
1526 | int ret_val = 0; | ||
1527 | |||
1528 | spin_lock_irqsave(&gus_lock,flags); | ||
1529 | if (note_num == 255) | ||
1530 | { | ||
1531 | if (voices[voice].volume_irq_mode == VMODE_START_NOTE) | ||
1532 | { | ||
1533 | voices[voice].volume_pending = volume; | ||
1534 | } | ||
1535 | else | ||
1536 | { | ||
1537 | ret_val = guswave_start_note2(dev, voice, note_num, volume); | ||
1538 | } | ||
1539 | } | ||
1540 | else | ||
1541 | { | ||
1542 | gus_select_voice(voice); | ||
1543 | mode = gus_read8(0x00); | ||
1544 | if (mode & 0x20) | ||
1545 | gus_write8(0x00, mode & 0xdf); /* No interrupt! */ | ||
1546 | |||
1547 | voices[voice].offset_pending = 0; | ||
1548 | voices[voice].kill_pending = 0; | ||
1549 | voices[voice].volume_irq_mode = 0; | ||
1550 | voices[voice].loop_irq_mode = 0; | ||
1551 | |||
1552 | if (voices[voice].sample_pending >= 0) | ||
1553 | { | ||
1554 | spin_unlock_irqrestore(&gus_lock,flags); /* Run temporarily with interrupts enabled */ | ||
1555 | guswave_set_instr(voices[voice].dev_pending, voice, voices[voice].sample_pending); | ||
1556 | voices[voice].sample_pending = -1; | ||
1557 | spin_lock_irqsave(&gus_lock,flags); | ||
1558 | gus_select_voice(voice); /* Reselect the voice (just to be sure) */ | ||
1559 | } | ||
1560 | if ((mode & 0x01) || (int) ((gus_read16(0x09) >> 4) < (unsigned) 2065)) | ||
1561 | { | ||
1562 | ret_val = guswave_start_note2(dev, voice, note_num, volume); | ||
1563 | } | ||
1564 | else | ||
1565 | { | ||
1566 | voices[voice].dev_pending = dev; | ||
1567 | voices[voice].note_pending = note_num; | ||
1568 | voices[voice].volume_pending = volume; | ||
1569 | voices[voice].volume_irq_mode = VMODE_START_NOTE; | ||
1570 | |||
1571 | gus_rampoff(); | ||
1572 | gus_ramp_range(2000, 4065); | ||
1573 | gus_ramp_rate(0, 63); /* Fastest possible rate */ | ||
1574 | gus_rampon(0x20 | 0x40); /* Ramp down, once, irq */ | ||
1575 | } | ||
1576 | } | ||
1577 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1578 | return ret_val; | ||
1579 | } | ||
1580 | |||
1581 | static void guswave_reset(int dev) | ||
1582 | { | ||
1583 | int i; | ||
1584 | |||
1585 | for (i = 0; i < 32; i++) | ||
1586 | { | ||
1587 | gus_voice_init(i); | ||
1588 | gus_voice_init2(i); | ||
1589 | } | ||
1590 | } | ||
1591 | |||
1592 | static int guswave_open(int dev, int mode) | ||
1593 | { | ||
1594 | int err; | ||
1595 | |||
1596 | if (gus_busy) | ||
1597 | return -EBUSY; | ||
1598 | |||
1599 | voice_alloc->timestamp = 0; | ||
1600 | |||
1601 | if (gus_no_wave_dma) { | ||
1602 | gus_no_dma = 1; | ||
1603 | } else { | ||
1604 | if ((err = DMAbuf_open_dma(gus_devnum)) < 0) | ||
1605 | { | ||
1606 | /* printk( "GUS: Loading samples without DMA\n"); */ | ||
1607 | gus_no_dma = 1; /* Upload samples using PIO */ | ||
1608 | } | ||
1609 | else | ||
1610 | gus_no_dma = 0; | ||
1611 | } | ||
1612 | |||
1613 | init_waitqueue_head(&dram_sleeper); | ||
1614 | gus_busy = 1; | ||
1615 | active_device = GUS_DEV_WAVE; | ||
1616 | |||
1617 | gusintr(gus_irq, (void *)gus_hw_config, NULL); /* Serve pending interrupts */ | ||
1618 | gus_initialize(); | ||
1619 | gus_reset(); | ||
1620 | gusintr(gus_irq, (void *)gus_hw_config, NULL); /* Serve pending interrupts */ | ||
1621 | |||
1622 | return 0; | ||
1623 | } | ||
1624 | |||
1625 | static void guswave_close(int dev) | ||
1626 | { | ||
1627 | gus_busy = 0; | ||
1628 | active_device = 0; | ||
1629 | gus_reset(); | ||
1630 | |||
1631 | if (!gus_no_dma) | ||
1632 | DMAbuf_close_dma(gus_devnum); | ||
1633 | } | ||
1634 | |||
1635 | static int guswave_load_patch(int dev, int format, const char __user *addr, | ||
1636 | int offs, int count, int pmgr_flag) | ||
1637 | { | ||
1638 | struct patch_info patch; | ||
1639 | int instr; | ||
1640 | long sizeof_patch; | ||
1641 | |||
1642 | unsigned long blk_sz, blk_end, left, src_offs, target; | ||
1643 | |||
1644 | sizeof_patch = (long) &patch.data[0] - (long) &patch; /* Header size */ | ||
1645 | |||
1646 | if (format != GUS_PATCH) | ||
1647 | { | ||
1648 | /* printk("GUS Error: Invalid patch format (key) 0x%x\n", format);*/ | ||
1649 | return -EINVAL; | ||
1650 | } | ||
1651 | if (count < sizeof_patch) | ||
1652 | { | ||
1653 | /* printk("GUS Error: Patch header too short\n");*/ | ||
1654 | return -EINVAL; | ||
1655 | } | ||
1656 | count -= sizeof_patch; | ||
1657 | |||
1658 | if (free_sample >= MAX_SAMPLE) | ||
1659 | { | ||
1660 | /* printk("GUS: Sample table full\n");*/ | ||
1661 | return -ENOSPC; | ||
1662 | } | ||
1663 | /* | ||
1664 | * Copy the header from user space but ignore the first bytes which have | ||
1665 | * been transferred already. | ||
1666 | */ | ||
1667 | |||
1668 | if (copy_from_user(&((char *) &patch)[offs], &(addr)[offs], | ||
1669 | sizeof_patch - offs)) | ||
1670 | return -EFAULT; | ||
1671 | |||
1672 | if (patch.mode & WAVE_ROM) | ||
1673 | return -EINVAL; | ||
1674 | if (gus_mem_size == 0) | ||
1675 | return -ENOSPC; | ||
1676 | |||
1677 | instr = patch.instr_no; | ||
1678 | |||
1679 | if (instr < 0 || instr > MAX_PATCH) | ||
1680 | { | ||
1681 | /* printk(KERN_ERR "GUS: Invalid patch number %d\n", instr);*/ | ||
1682 | return -EINVAL; | ||
1683 | } | ||
1684 | if (count < patch.len) | ||
1685 | { | ||
1686 | /* printk(KERN_ERR "GUS Warning: Patch record too short (%d<%d)\n", count, (int) patch.len);*/ | ||
1687 | patch.len = count; | ||
1688 | } | ||
1689 | if (patch.len <= 0 || patch.len > gus_mem_size) | ||
1690 | { | ||
1691 | /* printk(KERN_ERR "GUS: Invalid sample length %d\n", (int) patch.len);*/ | ||
1692 | return -EINVAL; | ||
1693 | } | ||
1694 | if (patch.mode & WAVE_LOOPING) | ||
1695 | { | ||
1696 | if (patch.loop_start < 0 || patch.loop_start >= patch.len) | ||
1697 | { | ||
1698 | /* printk(KERN_ERR "GUS: Invalid loop start\n");*/ | ||
1699 | return -EINVAL; | ||
1700 | } | ||
1701 | if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len) | ||
1702 | { | ||
1703 | /* printk(KERN_ERR "GUS: Invalid loop end\n");*/ | ||
1704 | return -EINVAL; | ||
1705 | } | ||
1706 | } | ||
1707 | free_mem_ptr = (free_mem_ptr + 31) & ~31; /* 32 byte alignment */ | ||
1708 | |||
1709 | if (patch.mode & WAVE_16_BITS) | ||
1710 | { | ||
1711 | /* | ||
1712 | * 16 bit samples must fit one 256k bank. | ||
1713 | */ | ||
1714 | if (patch.len >= GUS_BANK_SIZE) | ||
1715 | { | ||
1716 | /* printk("GUS: Sample (16 bit) too long %d\n", (int) patch.len);*/ | ||
1717 | return -ENOSPC; | ||
1718 | } | ||
1719 | if ((free_mem_ptr / GUS_BANK_SIZE) != | ||
1720 | ((free_mem_ptr + patch.len) / GUS_BANK_SIZE)) | ||
1721 | { | ||
1722 | unsigned long tmp_mem = | ||
1723 | /* Align to 256K */ | ||
1724 | ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE; | ||
1725 | |||
1726 | if ((tmp_mem + patch.len) > gus_mem_size) | ||
1727 | return -ENOSPC; | ||
1728 | |||
1729 | free_mem_ptr = tmp_mem; /* This leaves unusable memory */ | ||
1730 | } | ||
1731 | } | ||
1732 | if ((free_mem_ptr + patch.len) > gus_mem_size) | ||
1733 | return -ENOSPC; | ||
1734 | |||
1735 | sample_ptrs[free_sample] = free_mem_ptr; | ||
1736 | |||
1737 | /* | ||
1738 | * Tremolo is not possible with envelopes | ||
1739 | */ | ||
1740 | |||
1741 | if (patch.mode & WAVE_ENVELOPES) | ||
1742 | patch.mode &= ~WAVE_TREMOLO; | ||
1743 | |||
1744 | if (!(patch.mode & WAVE_FRACTIONS)) | ||
1745 | { | ||
1746 | patch.fractions = 0; | ||
1747 | } | ||
1748 | memcpy((char *) &samples[free_sample], &patch, sizeof_patch); | ||
1749 | |||
1750 | /* | ||
1751 | * Link this_one sample to the list of samples for patch 'instr'. | ||
1752 | */ | ||
1753 | |||
1754 | samples[free_sample].key = patch_table[instr]; | ||
1755 | patch_table[instr] = free_sample; | ||
1756 | |||
1757 | /* | ||
1758 | * Use DMA to transfer the wave data to the DRAM | ||
1759 | */ | ||
1760 | |||
1761 | left = patch.len; | ||
1762 | src_offs = 0; | ||
1763 | target = free_mem_ptr; | ||
1764 | |||
1765 | while (left) /* Not completely transferred yet */ | ||
1766 | { | ||
1767 | blk_sz = audio_devs[gus_devnum]->dmap_out->bytes_in_use; | ||
1768 | if (blk_sz > left) | ||
1769 | blk_sz = left; | ||
1770 | |||
1771 | /* | ||
1772 | * DMA cannot cross bank (256k) boundaries. Check for that. | ||
1773 | */ | ||
1774 | |||
1775 | blk_end = target + blk_sz; | ||
1776 | |||
1777 | if ((target / GUS_BANK_SIZE) != (blk_end / GUS_BANK_SIZE)) | ||
1778 | { | ||
1779 | /* Split the block */ | ||
1780 | blk_end &= ~(GUS_BANK_SIZE - 1); | ||
1781 | blk_sz = blk_end - target; | ||
1782 | } | ||
1783 | if (gus_no_dma) | ||
1784 | { | ||
1785 | /* | ||
1786 | * For some reason the DMA is not possible. We have to use PIO. | ||
1787 | */ | ||
1788 | long i; | ||
1789 | unsigned char data; | ||
1790 | |||
1791 | for (i = 0; i < blk_sz; i++) | ||
1792 | { | ||
1793 | get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[sizeof_patch + i])); | ||
1794 | if (patch.mode & WAVE_UNSIGNED) | ||
1795 | if (!(patch.mode & WAVE_16_BITS) || (i & 0x01)) | ||
1796 | data ^= 0x80; /* Convert to signed */ | ||
1797 | gus_poke(target + i, data); | ||
1798 | } | ||
1799 | } | ||
1800 | else | ||
1801 | { | ||
1802 | unsigned long address, hold_address; | ||
1803 | unsigned char dma_command; | ||
1804 | unsigned long flags; | ||
1805 | |||
1806 | if (audio_devs[gus_devnum]->dmap_out->raw_buf == NULL) | ||
1807 | { | ||
1808 | printk(KERN_ERR "GUS: DMA buffer == NULL\n"); | ||
1809 | return -ENOSPC; | ||
1810 | } | ||
1811 | /* | ||
1812 | * OK, move now. First in and then out. | ||
1813 | */ | ||
1814 | |||
1815 | if (copy_from_user(audio_devs[gus_devnum]->dmap_out->raw_buf, | ||
1816 | &(addr)[sizeof_patch + src_offs], | ||
1817 | blk_sz)) | ||
1818 | return -EFAULT; | ||
1819 | |||
1820 | spin_lock_irqsave(&gus_lock,flags); | ||
1821 | gus_write8(0x41, 0); /* Disable GF1 DMA */ | ||
1822 | DMAbuf_start_dma(gus_devnum, audio_devs[gus_devnum]->dmap_out->raw_buf_phys, | ||
1823 | blk_sz, DMA_MODE_WRITE); | ||
1824 | |||
1825 | /* | ||
1826 | * Set the DRAM address for the wave data | ||
1827 | */ | ||
1828 | |||
1829 | if (iw_mode) | ||
1830 | { | ||
1831 | /* Different address translation in enhanced mode */ | ||
1832 | |||
1833 | unsigned char hi; | ||
1834 | |||
1835 | if (gus_dma > 4) | ||
1836 | address = target >> 1; /* Convert to 16 bit word address */ | ||
1837 | else | ||
1838 | address = target; | ||
1839 | |||
1840 | hi = (unsigned char) ((address >> 16) & 0xf0); | ||
1841 | hi += (unsigned char) (address & 0x0f); | ||
1842 | |||
1843 | gus_write16(0x42, (address >> 4) & 0xffff); /* DMA address (low) */ | ||
1844 | gus_write8(0x50, hi); | ||
1845 | } | ||
1846 | else | ||
1847 | { | ||
1848 | address = target; | ||
1849 | if (audio_devs[gus_devnum]->dmap_out->dma > 3) | ||
1850 | { | ||
1851 | hold_address = address; | ||
1852 | address = address >> 1; | ||
1853 | address &= 0x0001ffffL; | ||
1854 | address |= (hold_address & 0x000c0000L); | ||
1855 | } | ||
1856 | gus_write16(0x42, (address >> 4) & 0xffff); /* DRAM DMA address */ | ||
1857 | } | ||
1858 | |||
1859 | /* | ||
1860 | * Start the DMA transfer | ||
1861 | */ | ||
1862 | |||
1863 | dma_command = 0x21; /* IRQ enable, DMA start */ | ||
1864 | if (patch.mode & WAVE_UNSIGNED) | ||
1865 | dma_command |= 0x80; /* Invert MSB */ | ||
1866 | if (patch.mode & WAVE_16_BITS) | ||
1867 | dma_command |= 0x40; /* 16 bit _DATA_ */ | ||
1868 | if (audio_devs[gus_devnum]->dmap_out->dma > 3) | ||
1869 | dma_command |= 0x04; /* 16 bit DMA _channel_ */ | ||
1870 | |||
1871 | /* | ||
1872 | * Sleep here until the DRAM DMA done interrupt is served | ||
1873 | */ | ||
1874 | active_device = GUS_DEV_WAVE; | ||
1875 | gus_write8(0x41, dma_command); /* Lets go luteet (=bugs) */ | ||
1876 | |||
1877 | spin_unlock_irqrestore(&gus_lock,flags); /* opens a race */ | ||
1878 | if (!interruptible_sleep_on_timeout(&dram_sleeper, HZ)) | ||
1879 | printk("GUS: DMA Transfer timed out\n"); | ||
1880 | } | ||
1881 | |||
1882 | /* | ||
1883 | * Now the next part | ||
1884 | */ | ||
1885 | |||
1886 | left -= blk_sz; | ||
1887 | src_offs += blk_sz; | ||
1888 | target += blk_sz; | ||
1889 | |||
1890 | gus_write8(0x41, 0); /* Stop DMA */ | ||
1891 | } | ||
1892 | |||
1893 | free_mem_ptr += patch.len; | ||
1894 | free_sample++; | ||
1895 | return 0; | ||
1896 | } | ||
1897 | |||
1898 | static void guswave_hw_control(int dev, unsigned char *event_rec) | ||
1899 | { | ||
1900 | int voice, cmd; | ||
1901 | unsigned short p1, p2; | ||
1902 | unsigned int plong; | ||
1903 | unsigned long flags; | ||
1904 | |||
1905 | cmd = event_rec[2]; | ||
1906 | voice = event_rec[3]; | ||
1907 | p1 = *(unsigned short *) &event_rec[4]; | ||
1908 | p2 = *(unsigned short *) &event_rec[6]; | ||
1909 | plong = *(unsigned int *) &event_rec[4]; | ||
1910 | |||
1911 | if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) && | ||
1912 | (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS)) | ||
1913 | do_volume_irq(voice); | ||
1914 | |||
1915 | switch (cmd) | ||
1916 | { | ||
1917 | case _GUS_NUMVOICES: | ||
1918 | spin_lock_irqsave(&gus_lock,flags); | ||
1919 | gus_select_voice(voice); | ||
1920 | gus_select_max_voices(p1); | ||
1921 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1922 | break; | ||
1923 | |||
1924 | case _GUS_VOICESAMPLE: | ||
1925 | guswave_set_instr(dev, voice, p1); | ||
1926 | break; | ||
1927 | |||
1928 | case _GUS_VOICEON: | ||
1929 | spin_lock_irqsave(&gus_lock,flags); | ||
1930 | gus_select_voice(voice); | ||
1931 | p1 &= ~0x20; /* Don't allow interrupts */ | ||
1932 | gus_voice_on(p1); | ||
1933 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1934 | break; | ||
1935 | |||
1936 | case _GUS_VOICEOFF: | ||
1937 | spin_lock_irqsave(&gus_lock,flags); | ||
1938 | gus_select_voice(voice); | ||
1939 | gus_voice_off(); | ||
1940 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1941 | break; | ||
1942 | |||
1943 | case _GUS_VOICEFADE: | ||
1944 | gus_voice_fade(voice); | ||
1945 | break; | ||
1946 | |||
1947 | case _GUS_VOICEMODE: | ||
1948 | spin_lock_irqsave(&gus_lock,flags); | ||
1949 | gus_select_voice(voice); | ||
1950 | p1 &= ~0x20; /* Don't allow interrupts */ | ||
1951 | gus_voice_mode(p1); | ||
1952 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1953 | break; | ||
1954 | |||
1955 | case _GUS_VOICEBALA: | ||
1956 | spin_lock_irqsave(&gus_lock,flags); | ||
1957 | gus_select_voice(voice); | ||
1958 | gus_voice_balance(p1); | ||
1959 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1960 | break; | ||
1961 | |||
1962 | case _GUS_VOICEFREQ: | ||
1963 | spin_lock_irqsave(&gus_lock,flags); | ||
1964 | gus_select_voice(voice); | ||
1965 | gus_voice_freq(plong); | ||
1966 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1967 | break; | ||
1968 | |||
1969 | case _GUS_VOICEVOL: | ||
1970 | spin_lock_irqsave(&gus_lock,flags); | ||
1971 | gus_select_voice(voice); | ||
1972 | gus_voice_volume(p1); | ||
1973 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1974 | break; | ||
1975 | |||
1976 | case _GUS_VOICEVOL2: /* Just update the software voice level */ | ||
1977 | voices[voice].initial_volume = voices[voice].current_volume = p1; | ||
1978 | break; | ||
1979 | |||
1980 | case _GUS_RAMPRANGE: | ||
1981 | if (voices[voice].mode & WAVE_ENVELOPES) | ||
1982 | break; /* NO-NO */ | ||
1983 | spin_lock_irqsave(&gus_lock,flags); | ||
1984 | gus_select_voice(voice); | ||
1985 | gus_ramp_range(p1, p2); | ||
1986 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1987 | break; | ||
1988 | |||
1989 | case _GUS_RAMPRATE: | ||
1990 | if (voices[voice].mode & WAVE_ENVELOPES) | ||
1991 | break; /* NJET-NJET */ | ||
1992 | spin_lock_irqsave(&gus_lock,flags); | ||
1993 | gus_select_voice(voice); | ||
1994 | gus_ramp_rate(p1, p2); | ||
1995 | spin_unlock_irqrestore(&gus_lock,flags); | ||
1996 | break; | ||
1997 | |||
1998 | case _GUS_RAMPMODE: | ||
1999 | if (voices[voice].mode & WAVE_ENVELOPES) | ||
2000 | break; /* NO-NO */ | ||
2001 | spin_lock_irqsave(&gus_lock,flags); | ||
2002 | gus_select_voice(voice); | ||
2003 | p1 &= ~0x20; /* Don't allow interrupts */ | ||
2004 | gus_ramp_mode(p1); | ||
2005 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2006 | break; | ||
2007 | |||
2008 | case _GUS_RAMPON: | ||
2009 | if (voices[voice].mode & WAVE_ENVELOPES) | ||
2010 | break; /* EI-EI */ | ||
2011 | spin_lock_irqsave(&gus_lock,flags); | ||
2012 | gus_select_voice(voice); | ||
2013 | p1 &= ~0x20; /* Don't allow interrupts */ | ||
2014 | gus_rampon(p1); | ||
2015 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2016 | break; | ||
2017 | |||
2018 | case _GUS_RAMPOFF: | ||
2019 | if (voices[voice].mode & WAVE_ENVELOPES) | ||
2020 | break; /* NEJ-NEJ */ | ||
2021 | spin_lock_irqsave(&gus_lock,flags); | ||
2022 | gus_select_voice(voice); | ||
2023 | gus_rampoff(); | ||
2024 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2025 | break; | ||
2026 | |||
2027 | case _GUS_VOLUME_SCALE: | ||
2028 | volume_base = p1; | ||
2029 | volume_scale = p2; | ||
2030 | break; | ||
2031 | |||
2032 | case _GUS_VOICE_POS: | ||
2033 | spin_lock_irqsave(&gus_lock,flags); | ||
2034 | gus_select_voice(voice); | ||
2035 | gus_set_voice_pos(voice, plong); | ||
2036 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2037 | break; | ||
2038 | |||
2039 | default: | ||
2040 | break; | ||
2041 | } | ||
2042 | } | ||
2043 | |||
2044 | static int gus_audio_set_speed(int speed) | ||
2045 | { | ||
2046 | if (speed <= 0) | ||
2047 | speed = gus_audio_speed; | ||
2048 | |||
2049 | if (speed < 4000) | ||
2050 | speed = 4000; | ||
2051 | |||
2052 | if (speed > 44100) | ||
2053 | speed = 44100; | ||
2054 | |||
2055 | gus_audio_speed = speed; | ||
2056 | |||
2057 | if (only_read_access) | ||
2058 | { | ||
2059 | /* Compute nearest valid recording speed and return it */ | ||
2060 | |||
2061 | /* speed = (9878400 / (gus_audio_speed + 2)) / 16; */ | ||
2062 | speed = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16; | ||
2063 | speed = (9878400 / (speed * 16)) - 2; | ||
2064 | } | ||
2065 | return speed; | ||
2066 | } | ||
2067 | |||
2068 | static int gus_audio_set_channels(int channels) | ||
2069 | { | ||
2070 | if (!channels) | ||
2071 | return gus_audio_channels; | ||
2072 | if (channels > 2) | ||
2073 | channels = 2; | ||
2074 | if (channels < 1) | ||
2075 | channels = 1; | ||
2076 | gus_audio_channels = channels; | ||
2077 | return channels; | ||
2078 | } | ||
2079 | |||
2080 | static int gus_audio_set_bits(int bits) | ||
2081 | { | ||
2082 | if (!bits) | ||
2083 | return gus_audio_bits; | ||
2084 | |||
2085 | if (bits != 8 && bits != 16) | ||
2086 | bits = 8; | ||
2087 | |||
2088 | if (only_8_bits) | ||
2089 | bits = 8; | ||
2090 | |||
2091 | gus_audio_bits = bits; | ||
2092 | return bits; | ||
2093 | } | ||
2094 | |||
2095 | static int gus_audio_ioctl(int dev, unsigned int cmd, void __user *arg) | ||
2096 | { | ||
2097 | int val; | ||
2098 | |||
2099 | switch (cmd) | ||
2100 | { | ||
2101 | case SOUND_PCM_WRITE_RATE: | ||
2102 | if (get_user(val, (int __user*)arg)) | ||
2103 | return -EFAULT; | ||
2104 | val = gus_audio_set_speed(val); | ||
2105 | break; | ||
2106 | |||
2107 | case SOUND_PCM_READ_RATE: | ||
2108 | val = gus_audio_speed; | ||
2109 | break; | ||
2110 | |||
2111 | case SNDCTL_DSP_STEREO: | ||
2112 | if (get_user(val, (int __user *)arg)) | ||
2113 | return -EFAULT; | ||
2114 | val = gus_audio_set_channels(val + 1) - 1; | ||
2115 | break; | ||
2116 | |||
2117 | case SOUND_PCM_WRITE_CHANNELS: | ||
2118 | if (get_user(val, (int __user *)arg)) | ||
2119 | return -EFAULT; | ||
2120 | val = gus_audio_set_channels(val); | ||
2121 | break; | ||
2122 | |||
2123 | case SOUND_PCM_READ_CHANNELS: | ||
2124 | val = gus_audio_channels; | ||
2125 | break; | ||
2126 | |||
2127 | case SNDCTL_DSP_SETFMT: | ||
2128 | if (get_user(val, (int __user *)arg)) | ||
2129 | return -EFAULT; | ||
2130 | val = gus_audio_set_bits(val); | ||
2131 | break; | ||
2132 | |||
2133 | case SOUND_PCM_READ_BITS: | ||
2134 | val = gus_audio_bits; | ||
2135 | break; | ||
2136 | |||
2137 | case SOUND_PCM_WRITE_FILTER: /* NOT POSSIBLE */ | ||
2138 | case SOUND_PCM_READ_FILTER: | ||
2139 | val = -EINVAL; | ||
2140 | break; | ||
2141 | default: | ||
2142 | return -EINVAL; | ||
2143 | } | ||
2144 | return put_user(val, (int __user *)arg); | ||
2145 | } | ||
2146 | |||
2147 | static void gus_audio_reset(int dev) | ||
2148 | { | ||
2149 | if (recording_active) | ||
2150 | { | ||
2151 | gus_write8(0x49, 0x00); /* Halt recording */ | ||
2152 | set_input_volumes(); | ||
2153 | } | ||
2154 | } | ||
2155 | |||
2156 | static int saved_iw_mode; /* A hack hack hack */ | ||
2157 | |||
2158 | static int gus_audio_open(int dev, int mode) | ||
2159 | { | ||
2160 | if (gus_busy) | ||
2161 | return -EBUSY; | ||
2162 | |||
2163 | if (gus_pnp_flag && mode & OPEN_READ) | ||
2164 | { | ||
2165 | /* printk(KERN_ERR "GUS: Audio device #%d is playback only.\n", dev);*/ | ||
2166 | return -EIO; | ||
2167 | } | ||
2168 | gus_initialize(); | ||
2169 | |||
2170 | gus_busy = 1; | ||
2171 | active_device = 0; | ||
2172 | |||
2173 | saved_iw_mode = iw_mode; | ||
2174 | if (iw_mode) | ||
2175 | { | ||
2176 | /* There are some problems with audio in enhanced mode so disable it */ | ||
2177 | gus_write8(0x19, gus_read8(0x19) & ~0x01); /* Disable enhanced mode */ | ||
2178 | iw_mode = 0; | ||
2179 | } | ||
2180 | |||
2181 | gus_reset(); | ||
2182 | reset_sample_memory(); | ||
2183 | gus_select_max_voices(14); | ||
2184 | |||
2185 | pcm_active = 0; | ||
2186 | dma_active = 0; | ||
2187 | pcm_opened = 1; | ||
2188 | if (mode & OPEN_READ) | ||
2189 | { | ||
2190 | recording_active = 1; | ||
2191 | set_input_volumes(); | ||
2192 | } | ||
2193 | only_read_access = !(mode & OPEN_WRITE); | ||
2194 | only_8_bits = mode & OPEN_READ; | ||
2195 | if (only_8_bits) | ||
2196 | audio_devs[dev]->format_mask = AFMT_U8; | ||
2197 | else | ||
2198 | audio_devs[dev]->format_mask = AFMT_U8 | AFMT_S16_LE; | ||
2199 | |||
2200 | return 0; | ||
2201 | } | ||
2202 | |||
2203 | static void gus_audio_close(int dev) | ||
2204 | { | ||
2205 | iw_mode = saved_iw_mode; | ||
2206 | gus_reset(); | ||
2207 | gus_busy = 0; | ||
2208 | pcm_opened = 0; | ||
2209 | active_device = 0; | ||
2210 | |||
2211 | if (recording_active) | ||
2212 | { | ||
2213 | gus_write8(0x49, 0x00); /* Halt recording */ | ||
2214 | set_input_volumes(); | ||
2215 | } | ||
2216 | recording_active = 0; | ||
2217 | } | ||
2218 | |||
2219 | static void gus_audio_update_volume(void) | ||
2220 | { | ||
2221 | unsigned long flags; | ||
2222 | int voice; | ||
2223 | |||
2224 | if (pcm_active && pcm_opened) | ||
2225 | for (voice = 0; voice < gus_audio_channels; voice++) | ||
2226 | { | ||
2227 | spin_lock_irqsave(&gus_lock,flags); | ||
2228 | gus_select_voice(voice); | ||
2229 | gus_rampoff(); | ||
2230 | gus_voice_volume(1530 + (25 * gus_pcm_volume)); | ||
2231 | gus_ramp_range(65, 1530 + (25 * gus_pcm_volume)); | ||
2232 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2233 | } | ||
2234 | } | ||
2235 | |||
2236 | static void play_next_pcm_block(void) | ||
2237 | { | ||
2238 | unsigned long flags; | ||
2239 | int speed = gus_audio_speed; | ||
2240 | int this_one, is16bits, chn; | ||
2241 | unsigned long dram_loc; | ||
2242 | unsigned char mode[2], ramp_mode[2]; | ||
2243 | |||
2244 | if (!pcm_qlen) | ||
2245 | return; | ||
2246 | |||
2247 | this_one = pcm_head; | ||
2248 | |||
2249 | for (chn = 0; chn < gus_audio_channels; chn++) | ||
2250 | { | ||
2251 | mode[chn] = 0x00; | ||
2252 | ramp_mode[chn] = 0x03; /* Ramping and rollover off */ | ||
2253 | |||
2254 | if (chn == 0) | ||
2255 | { | ||
2256 | mode[chn] |= 0x20; /* Loop IRQ */ | ||
2257 | voices[chn].loop_irq_mode = LMODE_PCM; | ||
2258 | } | ||
2259 | if (gus_audio_bits != 8) | ||
2260 | { | ||
2261 | is16bits = 1; | ||
2262 | mode[chn] |= 0x04; /* 16 bit data */ | ||
2263 | } | ||
2264 | else | ||
2265 | is16bits = 0; | ||
2266 | |||
2267 | dram_loc = this_one * pcm_bsize; | ||
2268 | dram_loc += chn * pcm_banksize; | ||
2269 | |||
2270 | if (this_one == (pcm_nblk - 1)) /* Last fragment of the DRAM buffer */ | ||
2271 | { | ||
2272 | mode[chn] |= 0x08; /* Enable loop */ | ||
2273 | ramp_mode[chn] = 0x03; /* Disable rollover bit */ | ||
2274 | } | ||
2275 | else | ||
2276 | { | ||
2277 | if (chn == 0) | ||
2278 | ramp_mode[chn] = 0x04; /* Enable rollover bit */ | ||
2279 | } | ||
2280 | spin_lock_irqsave(&gus_lock,flags); | ||
2281 | gus_select_voice(chn); | ||
2282 | gus_voice_freq(speed); | ||
2283 | |||
2284 | if (gus_audio_channels == 1) | ||
2285 | gus_voice_balance(7); /* mono */ | ||
2286 | else if (chn == 0) | ||
2287 | gus_voice_balance(0); /* left */ | ||
2288 | else | ||
2289 | gus_voice_balance(15); /* right */ | ||
2290 | |||
2291 | if (!pcm_active) /* Playback not already active */ | ||
2292 | { | ||
2293 | /* | ||
2294 | * The playback was not started yet (or there has been a pause). | ||
2295 | * Start the voice (again) and ask for a rollover irq at the end of | ||
2296 | * this_one block. If this_one one is last of the buffers, use just | ||
2297 | * the normal loop with irq. | ||
2298 | */ | ||
2299 | |||
2300 | gus_voice_off(); | ||
2301 | gus_rampoff(); | ||
2302 | gus_voice_volume(1530 + (25 * gus_pcm_volume)); | ||
2303 | gus_ramp_range(65, 1530 + (25 * gus_pcm_volume)); | ||
2304 | |||
2305 | gus_write_addr(0x0a, chn * pcm_banksize, 0, is16bits); /* Starting position */ | ||
2306 | gus_write_addr(0x02, chn * pcm_banksize, 0, is16bits); /* Loop start */ | ||
2307 | |||
2308 | if (chn != 0) | ||
2309 | gus_write_addr(0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1, | ||
2310 | 0, is16bits); /* Loop end location */ | ||
2311 | } | ||
2312 | if (chn == 0) | ||
2313 | gus_write_addr(0x04, dram_loc + pcm_bsize - 1, | ||
2314 | 0, is16bits); /* Loop end location */ | ||
2315 | else | ||
2316 | mode[chn] |= 0x08; /* Enable looping */ | ||
2317 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2318 | } | ||
2319 | for (chn = 0; chn < gus_audio_channels; chn++) | ||
2320 | { | ||
2321 | spin_lock_irqsave(&gus_lock,flags); | ||
2322 | gus_select_voice(chn); | ||
2323 | gus_write8(0x0d, ramp_mode[chn]); | ||
2324 | if (iw_mode) | ||
2325 | gus_write8(0x15, 0x00); /* Reset voice deactivate bit of SMSI */ | ||
2326 | gus_voice_on(mode[chn]); | ||
2327 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2328 | } | ||
2329 | pcm_active = 1; | ||
2330 | } | ||
2331 | |||
2332 | static void gus_transfer_output_block(int dev, unsigned long buf, | ||
2333 | int total_count, int intrflag, int chn) | ||
2334 | { | ||
2335 | /* | ||
2336 | * This routine transfers one block of audio data to the DRAM. In mono mode | ||
2337 | * it's called just once. When in stereo mode, this_one routine is called | ||
2338 | * once for both channels. | ||
2339 | * | ||
2340 | * The left/mono channel data is transferred to the beginning of dram and the | ||
2341 | * right data to the area pointed by gus_page_size. | ||
2342 | */ | ||
2343 | |||
2344 | int this_one, count; | ||
2345 | unsigned long flags; | ||
2346 | unsigned char dma_command; | ||
2347 | unsigned long address, hold_address; | ||
2348 | |||
2349 | spin_lock_irqsave(&gus_lock,flags); | ||
2350 | |||
2351 | count = total_count / gus_audio_channels; | ||
2352 | |||
2353 | if (chn == 0) | ||
2354 | { | ||
2355 | if (pcm_qlen >= pcm_nblk) | ||
2356 | printk(KERN_WARNING "GUS Warning: PCM buffers out of sync\n"); | ||
2357 | |||
2358 | this_one = pcm_current_block = pcm_tail; | ||
2359 | pcm_qlen++; | ||
2360 | pcm_tail = (pcm_tail + 1) % pcm_nblk; | ||
2361 | pcm_datasize[this_one] = count; | ||
2362 | } | ||
2363 | else | ||
2364 | this_one = pcm_current_block; | ||
2365 | |||
2366 | gus_write8(0x41, 0); /* Disable GF1 DMA */ | ||
2367 | DMAbuf_start_dma(dev, buf + (chn * count), count, DMA_MODE_WRITE); | ||
2368 | |||
2369 | address = this_one * pcm_bsize; | ||
2370 | address += chn * pcm_banksize; | ||
2371 | |||
2372 | if (audio_devs[dev]->dmap_out->dma > 3) | ||
2373 | { | ||
2374 | hold_address = address; | ||
2375 | address = address >> 1; | ||
2376 | address &= 0x0001ffffL; | ||
2377 | address |= (hold_address & 0x000c0000L); | ||
2378 | } | ||
2379 | gus_write16(0x42, (address >> 4) & 0xffff); /* DRAM DMA address */ | ||
2380 | |||
2381 | dma_command = 0x21; /* IRQ enable, DMA start */ | ||
2382 | |||
2383 | if (gus_audio_bits != 8) | ||
2384 | dma_command |= 0x40; /* 16 bit _DATA_ */ | ||
2385 | else | ||
2386 | dma_command |= 0x80; /* Invert MSB */ | ||
2387 | |||
2388 | if (audio_devs[dev]->dmap_out->dma > 3) | ||
2389 | dma_command |= 0x04; /* 16 bit DMA channel */ | ||
2390 | |||
2391 | gus_write8(0x41, dma_command); /* Kick start */ | ||
2392 | |||
2393 | if (chn == (gus_audio_channels - 1)) /* Last channel */ | ||
2394 | { | ||
2395 | /* | ||
2396 | * Last (right or mono) channel data | ||
2397 | */ | ||
2398 | dma_active = 1; /* DMA started. There is a unacknowledged buffer */ | ||
2399 | active_device = GUS_DEV_PCM_DONE; | ||
2400 | if (!pcm_active && (pcm_qlen > 1 || count < pcm_bsize)) | ||
2401 | { | ||
2402 | play_next_pcm_block(); | ||
2403 | } | ||
2404 | } | ||
2405 | else | ||
2406 | { | ||
2407 | /* | ||
2408 | * Left channel data. The right channel | ||
2409 | * is transferred after DMA interrupt | ||
2410 | */ | ||
2411 | active_device = GUS_DEV_PCM_CONTINUE; | ||
2412 | } | ||
2413 | |||
2414 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2415 | } | ||
2416 | |||
2417 | static void gus_uninterleave8(char *buf, int l) | ||
2418 | { | ||
2419 | /* This routine uninterleaves 8 bit stereo output (LRLRLR->LLLRRR) */ | ||
2420 | int i, p = 0, halfsize = l / 2; | ||
2421 | char *buf2 = buf + halfsize, *src = bounce_buf; | ||
2422 | |||
2423 | memcpy(bounce_buf, buf, l); | ||
2424 | |||
2425 | for (i = 0; i < halfsize; i++) | ||
2426 | { | ||
2427 | buf[i] = src[p++]; /* Left channel */ | ||
2428 | buf2[i] = src[p++]; /* Right channel */ | ||
2429 | } | ||
2430 | } | ||
2431 | |||
2432 | static void gus_uninterleave16(short *buf, int l) | ||
2433 | { | ||
2434 | /* This routine uninterleaves 16 bit stereo output (LRLRLR->LLLRRR) */ | ||
2435 | int i, p = 0, halfsize = l / 2; | ||
2436 | short *buf2 = buf + halfsize, *src = (short *) bounce_buf; | ||
2437 | |||
2438 | memcpy(bounce_buf, (char *) buf, l * 2); | ||
2439 | |||
2440 | for (i = 0; i < halfsize; i++) | ||
2441 | { | ||
2442 | buf[i] = src[p++]; /* Left channel */ | ||
2443 | buf2[i] = src[p++]; /* Right channel */ | ||
2444 | } | ||
2445 | } | ||
2446 | |||
2447 | static void gus_audio_output_block(int dev, unsigned long buf, int total_count, | ||
2448 | int intrflag) | ||
2449 | { | ||
2450 | struct dma_buffparms *dmap = audio_devs[dev]->dmap_out; | ||
2451 | |||
2452 | dmap->flags |= DMA_NODMA | DMA_NOTIMEOUT; | ||
2453 | |||
2454 | pcm_current_buf = buf; | ||
2455 | pcm_current_count = total_count; | ||
2456 | pcm_current_intrflag = intrflag; | ||
2457 | pcm_current_dev = dev; | ||
2458 | if (gus_audio_channels == 2) | ||
2459 | { | ||
2460 | char *b = dmap->raw_buf + (buf - dmap->raw_buf_phys); | ||
2461 | |||
2462 | if (gus_audio_bits == 8) | ||
2463 | gus_uninterleave8(b, total_count); | ||
2464 | else | ||
2465 | gus_uninterleave16((short *) b, total_count / 2); | ||
2466 | } | ||
2467 | gus_transfer_output_block(dev, buf, total_count, intrflag, 0); | ||
2468 | } | ||
2469 | |||
2470 | static void gus_audio_start_input(int dev, unsigned long buf, int count, | ||
2471 | int intrflag) | ||
2472 | { | ||
2473 | unsigned long flags; | ||
2474 | unsigned char mode; | ||
2475 | |||
2476 | spin_lock_irqsave(&gus_lock,flags); | ||
2477 | |||
2478 | DMAbuf_start_dma(dev, buf, count, DMA_MODE_READ); | ||
2479 | mode = 0xa0; /* DMA IRQ enabled, invert MSB */ | ||
2480 | |||
2481 | if (audio_devs[dev]->dmap_in->dma > 3) | ||
2482 | mode |= 0x04; /* 16 bit DMA channel */ | ||
2483 | if (gus_audio_channels > 1) | ||
2484 | mode |= 0x02; /* Stereo */ | ||
2485 | mode |= 0x01; /* DMA enable */ | ||
2486 | |||
2487 | gus_write8(0x49, mode); | ||
2488 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2489 | } | ||
2490 | |||
2491 | static int gus_audio_prepare_for_input(int dev, int bsize, int bcount) | ||
2492 | { | ||
2493 | unsigned int rate; | ||
2494 | |||
2495 | gus_audio_bsize = bsize; | ||
2496 | audio_devs[dev]->dmap_in->flags |= DMA_NODMA; | ||
2497 | rate = (((9878400 + gus_audio_speed / 2) / (gus_audio_speed + 2)) + 8) / 16; | ||
2498 | |||
2499 | gus_write8(0x48, rate & 0xff); /* Set sampling rate */ | ||
2500 | |||
2501 | if (gus_audio_bits != 8) | ||
2502 | { | ||
2503 | /* printk("GUS Error: 16 bit recording not supported\n");*/ | ||
2504 | return -EINVAL; | ||
2505 | } | ||
2506 | return 0; | ||
2507 | } | ||
2508 | |||
2509 | static int gus_audio_prepare_for_output(int dev, int bsize, int bcount) | ||
2510 | { | ||
2511 | int i; | ||
2512 | |||
2513 | long mem_ptr, mem_size; | ||
2514 | |||
2515 | audio_devs[dev]->dmap_out->flags |= DMA_NODMA | DMA_NOTIMEOUT; | ||
2516 | mem_ptr = 0; | ||
2517 | mem_size = gus_mem_size / gus_audio_channels; | ||
2518 | |||
2519 | if (mem_size > (256 * 1024)) | ||
2520 | mem_size = 256 * 1024; | ||
2521 | |||
2522 | pcm_bsize = bsize / gus_audio_channels; | ||
2523 | pcm_head = pcm_tail = pcm_qlen = 0; | ||
2524 | |||
2525 | pcm_nblk = 2; /* MAX_PCM_BUFFERS; */ | ||
2526 | if ((pcm_bsize * pcm_nblk) > mem_size) | ||
2527 | pcm_nblk = mem_size / pcm_bsize; | ||
2528 | |||
2529 | for (i = 0; i < pcm_nblk; i++) | ||
2530 | pcm_datasize[i] = 0; | ||
2531 | |||
2532 | pcm_banksize = pcm_nblk * pcm_bsize; | ||
2533 | |||
2534 | if (gus_audio_bits != 8 && pcm_banksize == (256 * 1024)) | ||
2535 | pcm_nblk--; | ||
2536 | gus_write8(0x41, 0); /* Disable GF1 DMA */ | ||
2537 | return 0; | ||
2538 | } | ||
2539 | |||
2540 | static int gus_local_qlen(int dev) | ||
2541 | { | ||
2542 | return pcm_qlen; | ||
2543 | } | ||
2544 | |||
2545 | |||
2546 | static struct audio_driver gus_audio_driver = | ||
2547 | { | ||
2548 | .owner = THIS_MODULE, | ||
2549 | .open = gus_audio_open, | ||
2550 | .close = gus_audio_close, | ||
2551 | .output_block = gus_audio_output_block, | ||
2552 | .start_input = gus_audio_start_input, | ||
2553 | .ioctl = gus_audio_ioctl, | ||
2554 | .prepare_for_input = gus_audio_prepare_for_input, | ||
2555 | .prepare_for_output = gus_audio_prepare_for_output, | ||
2556 | .halt_io = gus_audio_reset, | ||
2557 | .local_qlen = gus_local_qlen, | ||
2558 | }; | ||
2559 | |||
2560 | static void guswave_setup_voice(int dev, int voice, int chn) | ||
2561 | { | ||
2562 | struct channel_info *info = &synth_devs[dev]->chn_info[chn]; | ||
2563 | |||
2564 | guswave_set_instr(dev, voice, info->pgm_num); | ||
2565 | voices[voice].expression_vol = info->controllers[CTL_EXPRESSION]; /* Just MSB */ | ||
2566 | voices[voice].main_vol = (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128; | ||
2567 | voices[voice].panning = (info->controllers[CTL_PAN] * 2) - 128; | ||
2568 | voices[voice].bender = 0; | ||
2569 | voices[voice].bender_range = info->bender_range; | ||
2570 | |||
2571 | if (chn == 9) | ||
2572 | voices[voice].fixed_pitch = 1; | ||
2573 | } | ||
2574 | |||
2575 | static void guswave_bender(int dev, int voice, int value) | ||
2576 | { | ||
2577 | int freq; | ||
2578 | unsigned long flags; | ||
2579 | |||
2580 | voices[voice].bender = value - 8192; | ||
2581 | freq = compute_finetune(voices[voice].orig_freq, value - 8192, voices[voice].bender_range, 0); | ||
2582 | voices[voice].current_freq = freq; | ||
2583 | |||
2584 | spin_lock_irqsave(&gus_lock,flags); | ||
2585 | gus_select_voice(voice); | ||
2586 | gus_voice_freq(freq); | ||
2587 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2588 | } | ||
2589 | |||
2590 | static int guswave_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc) | ||
2591 | { | ||
2592 | int i, p, best = -1, best_time = 0x7fffffff; | ||
2593 | |||
2594 | p = alloc->ptr; | ||
2595 | /* | ||
2596 | * First look for a completely stopped voice | ||
2597 | */ | ||
2598 | |||
2599 | for (i = 0; i < alloc->max_voice; i++) | ||
2600 | { | ||
2601 | if (alloc->map[p] == 0) | ||
2602 | { | ||
2603 | alloc->ptr = p; | ||
2604 | return p; | ||
2605 | } | ||
2606 | if (alloc->alloc_times[p] < best_time) | ||
2607 | { | ||
2608 | best = p; | ||
2609 | best_time = alloc->alloc_times[p]; | ||
2610 | } | ||
2611 | p = (p + 1) % alloc->max_voice; | ||
2612 | } | ||
2613 | |||
2614 | /* | ||
2615 | * Then look for a releasing voice | ||
2616 | */ | ||
2617 | |||
2618 | for (i = 0; i < alloc->max_voice; i++) | ||
2619 | { | ||
2620 | if (alloc->map[p] == 0xffff) | ||
2621 | { | ||
2622 | alloc->ptr = p; | ||
2623 | return p; | ||
2624 | } | ||
2625 | p = (p + 1) % alloc->max_voice; | ||
2626 | } | ||
2627 | if (best >= 0) | ||
2628 | p = best; | ||
2629 | |||
2630 | alloc->ptr = p; | ||
2631 | return p; | ||
2632 | } | ||
2633 | |||
2634 | static struct synth_operations guswave_operations = | ||
2635 | { | ||
2636 | .owner = THIS_MODULE, | ||
2637 | .id = "GUS", | ||
2638 | .info = &gus_info, | ||
2639 | .midi_dev = 0, | ||
2640 | .synth_type = SYNTH_TYPE_SAMPLE, | ||
2641 | .synth_subtype = SAMPLE_TYPE_GUS, | ||
2642 | .open = guswave_open, | ||
2643 | .close = guswave_close, | ||
2644 | .ioctl = guswave_ioctl, | ||
2645 | .kill_note = guswave_kill_note, | ||
2646 | .start_note = guswave_start_note, | ||
2647 | .set_instr = guswave_set_instr, | ||
2648 | .reset = guswave_reset, | ||
2649 | .hw_control = guswave_hw_control, | ||
2650 | .load_patch = guswave_load_patch, | ||
2651 | .aftertouch = guswave_aftertouch, | ||
2652 | .controller = guswave_controller, | ||
2653 | .panning = guswave_panning, | ||
2654 | .volume_method = guswave_volume_method, | ||
2655 | .bender = guswave_bender, | ||
2656 | .alloc_voice = guswave_alloc, | ||
2657 | .setup_voice = guswave_setup_voice | ||
2658 | }; | ||
2659 | |||
2660 | static void set_input_volumes(void) | ||
2661 | { | ||
2662 | unsigned long flags; | ||
2663 | unsigned char mask = 0xff & ~0x06; /* Just line out enabled */ | ||
2664 | |||
2665 | if (have_gus_max) /* Don't disturb GUS MAX */ | ||
2666 | return; | ||
2667 | |||
2668 | spin_lock_irqsave(&gus_lock,flags); | ||
2669 | |||
2670 | /* | ||
2671 | * Enable channels having vol > 10% | ||
2672 | * Note! bit 0x01 means the line in DISABLED while 0x04 means | ||
2673 | * the mic in ENABLED. | ||
2674 | */ | ||
2675 | if (gus_line_vol > 10) | ||
2676 | mask &= ~0x01; | ||
2677 | if (gus_mic_vol > 10) | ||
2678 | mask |= 0x04; | ||
2679 | |||
2680 | if (recording_active) | ||
2681 | { | ||
2682 | /* | ||
2683 | * Disable channel, if not selected for recording | ||
2684 | */ | ||
2685 | if (!(gus_recmask & SOUND_MASK_LINE)) | ||
2686 | mask |= 0x01; | ||
2687 | if (!(gus_recmask & SOUND_MASK_MIC)) | ||
2688 | mask &= ~0x04; | ||
2689 | } | ||
2690 | mix_image &= ~0x07; | ||
2691 | mix_image |= mask & 0x07; | ||
2692 | outb((mix_image), u_Mixer); | ||
2693 | |||
2694 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2695 | } | ||
2696 | |||
2697 | #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \ | ||
2698 | SOUND_MASK_SYNTH|SOUND_MASK_PCM) | ||
2699 | |||
2700 | int gus_default_mixer_ioctl(int dev, unsigned int cmd, void __user *arg) | ||
2701 | { | ||
2702 | int vol, val; | ||
2703 | |||
2704 | if (((cmd >> 8) & 0xff) != 'M') | ||
2705 | return -EINVAL; | ||
2706 | |||
2707 | if (!access_ok(VERIFY_WRITE, arg, sizeof(int))) | ||
2708 | return -EFAULT; | ||
2709 | |||
2710 | if (_SIOC_DIR(cmd) & _SIOC_WRITE) | ||
2711 | { | ||
2712 | if (__get_user(val, (int __user *) arg)) | ||
2713 | return -EFAULT; | ||
2714 | |||
2715 | switch (cmd & 0xff) | ||
2716 | { | ||
2717 | case SOUND_MIXER_RECSRC: | ||
2718 | gus_recmask = val & MIX_DEVS; | ||
2719 | if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE))) | ||
2720 | gus_recmask = SOUND_MASK_MIC; | ||
2721 | /* Note! Input volumes are updated during next open for recording */ | ||
2722 | val = gus_recmask; | ||
2723 | break; | ||
2724 | |||
2725 | case SOUND_MIXER_MIC: | ||
2726 | vol = val & 0xff; | ||
2727 | if (vol < 0) | ||
2728 | vol = 0; | ||
2729 | if (vol > 100) | ||
2730 | vol = 100; | ||
2731 | gus_mic_vol = vol; | ||
2732 | set_input_volumes(); | ||
2733 | val = vol | (vol << 8); | ||
2734 | break; | ||
2735 | |||
2736 | case SOUND_MIXER_LINE: | ||
2737 | vol = val & 0xff; | ||
2738 | if (vol < 0) | ||
2739 | vol = 0; | ||
2740 | if (vol > 100) | ||
2741 | vol = 100; | ||
2742 | gus_line_vol = vol; | ||
2743 | set_input_volumes(); | ||
2744 | val = vol | (vol << 8); | ||
2745 | break; | ||
2746 | |||
2747 | case SOUND_MIXER_PCM: | ||
2748 | gus_pcm_volume = val & 0xff; | ||
2749 | if (gus_pcm_volume < 0) | ||
2750 | gus_pcm_volume = 0; | ||
2751 | if (gus_pcm_volume > 100) | ||
2752 | gus_pcm_volume = 100; | ||
2753 | gus_audio_update_volume(); | ||
2754 | val = gus_pcm_volume | (gus_pcm_volume << 8); | ||
2755 | break; | ||
2756 | |||
2757 | case SOUND_MIXER_SYNTH: | ||
2758 | gus_wave_volume = val & 0xff; | ||
2759 | if (gus_wave_volume < 0) | ||
2760 | gus_wave_volume = 0; | ||
2761 | if (gus_wave_volume > 100) | ||
2762 | gus_wave_volume = 100; | ||
2763 | if (active_device == GUS_DEV_WAVE) | ||
2764 | { | ||
2765 | int voice; | ||
2766 | for (voice = 0; voice < nr_voices; voice++) | ||
2767 | dynamic_volume_change(voice); /* Apply the new vol */ | ||
2768 | } | ||
2769 | val = gus_wave_volume | (gus_wave_volume << 8); | ||
2770 | break; | ||
2771 | |||
2772 | default: | ||
2773 | return -EINVAL; | ||
2774 | } | ||
2775 | } | ||
2776 | else | ||
2777 | { | ||
2778 | switch (cmd & 0xff) | ||
2779 | { | ||
2780 | /* | ||
2781 | * Return parameters | ||
2782 | */ | ||
2783 | case SOUND_MIXER_RECSRC: | ||
2784 | val = gus_recmask; | ||
2785 | break; | ||
2786 | |||
2787 | case SOUND_MIXER_DEVMASK: | ||
2788 | val = MIX_DEVS; | ||
2789 | break; | ||
2790 | |||
2791 | case SOUND_MIXER_STEREODEVS: | ||
2792 | val = 0; | ||
2793 | break; | ||
2794 | |||
2795 | case SOUND_MIXER_RECMASK: | ||
2796 | val = SOUND_MASK_MIC | SOUND_MASK_LINE; | ||
2797 | break; | ||
2798 | |||
2799 | case SOUND_MIXER_CAPS: | ||
2800 | val = 0; | ||
2801 | break; | ||
2802 | |||
2803 | case SOUND_MIXER_MIC: | ||
2804 | val = gus_mic_vol | (gus_mic_vol << 8); | ||
2805 | break; | ||
2806 | |||
2807 | case SOUND_MIXER_LINE: | ||
2808 | val = gus_line_vol | (gus_line_vol << 8); | ||
2809 | break; | ||
2810 | |||
2811 | case SOUND_MIXER_PCM: | ||
2812 | val = gus_pcm_volume | (gus_pcm_volume << 8); | ||
2813 | break; | ||
2814 | |||
2815 | case SOUND_MIXER_SYNTH: | ||
2816 | val = gus_wave_volume | (gus_wave_volume << 8); | ||
2817 | break; | ||
2818 | |||
2819 | default: | ||
2820 | return -EINVAL; | ||
2821 | } | ||
2822 | } | ||
2823 | return __put_user(val, (int __user *)arg); | ||
2824 | } | ||
2825 | |||
2826 | static struct mixer_operations gus_mixer_operations = | ||
2827 | { | ||
2828 | .owner = THIS_MODULE, | ||
2829 | .id = "GUS", | ||
2830 | .name = "Gravis Ultrasound", | ||
2831 | .ioctl = gus_default_mixer_ioctl | ||
2832 | }; | ||
2833 | |||
2834 | static int __init gus_default_mixer_init(void) | ||
2835 | { | ||
2836 | int n; | ||
2837 | |||
2838 | if ((n = sound_alloc_mixerdev()) != -1) | ||
2839 | { | ||
2840 | /* | ||
2841 | * Don't install if there is another | ||
2842 | * mixer | ||
2843 | */ | ||
2844 | mixer_devs[n] = &gus_mixer_operations; | ||
2845 | } | ||
2846 | if (have_gus_max) | ||
2847 | { | ||
2848 | /* | ||
2849 | * Enable all mixer channels on the GF1 side. Otherwise recording will | ||
2850 | * not be possible using GUS MAX. | ||
2851 | */ | ||
2852 | mix_image &= ~0x07; | ||
2853 | mix_image |= 0x04; /* All channels enabled */ | ||
2854 | outb((mix_image), u_Mixer); | ||
2855 | } | ||
2856 | return n; | ||
2857 | } | ||
2858 | |||
2859 | void __init gus_wave_init(struct address_info *hw_config) | ||
2860 | { | ||
2861 | unsigned long flags; | ||
2862 | unsigned char val; | ||
2863 | char *model_num = "2.4"; | ||
2864 | char tmp[64]; | ||
2865 | int gus_type = 0x24; /* 2.4 */ | ||
2866 | |||
2867 | int irq = hw_config->irq, dma = hw_config->dma, dma2 = hw_config->dma2; | ||
2868 | int sdev; | ||
2869 | |||
2870 | hw_config->slots[0] = -1; /* No wave */ | ||
2871 | hw_config->slots[1] = -1; /* No ad1848 */ | ||
2872 | hw_config->slots[4] = -1; /* No audio */ | ||
2873 | hw_config->slots[5] = -1; /* No mixer */ | ||
2874 | |||
2875 | if (!gus_pnp_flag) | ||
2876 | { | ||
2877 | if (irq < 0 || irq > 15) | ||
2878 | { | ||
2879 | printk(KERN_ERR "ERROR! Invalid IRQ#%d. GUS Disabled", irq); | ||
2880 | return; | ||
2881 | } | ||
2882 | } | ||
2883 | |||
2884 | if (dma < 0 || dma > 7 || dma == 4) | ||
2885 | { | ||
2886 | printk(KERN_ERR "ERROR! Invalid DMA#%d. GUS Disabled", dma); | ||
2887 | return; | ||
2888 | } | ||
2889 | gus_irq = irq; | ||
2890 | gus_dma = dma; | ||
2891 | gus_dma2 = dma2; | ||
2892 | gus_hw_config = hw_config; | ||
2893 | |||
2894 | if (gus_dma2 == -1) | ||
2895 | gus_dma2 = dma; | ||
2896 | |||
2897 | /* | ||
2898 | * Try to identify the GUS model. | ||
2899 | * | ||
2900 | * Versions < 3.6 don't have the digital ASIC. Try to probe it first. | ||
2901 | */ | ||
2902 | |||
2903 | spin_lock_irqsave(&gus_lock,flags); | ||
2904 | outb((0x20), gus_base + 0x0f); | ||
2905 | val = inb(gus_base + 0x0f); | ||
2906 | spin_unlock_irqrestore(&gus_lock,flags); | ||
2907 | |||
2908 | if (gus_pnp_flag || (val != 0xff && (val & 0x06))) /* Should be 0x02?? */ | ||
2909 | { | ||
2910 | int ad_flags = 0; | ||
2911 | |||
2912 | if (gus_pnp_flag) | ||
2913 | ad_flags = 0x12345678; /* Interwave "magic" */ | ||
2914 | /* | ||
2915 | * It has the digital ASIC so the card is at least v3.4. | ||
2916 | * Next try to detect the true model. | ||
2917 | */ | ||
2918 | |||
2919 | if (gus_pnp_flag) /* Hack hack hack */ | ||
2920 | val = 10; | ||
2921 | else | ||
2922 | val = inb(u_MixSelect); | ||
2923 | |||
2924 | /* | ||
2925 | * Value 255 means pre-3.7 which don't have mixer. | ||
2926 | * Values 5 thru 9 mean v3.7 which has a ICS2101 mixer. | ||
2927 | * 10 and above is GUS MAX which has the CS4231 codec/mixer. | ||
2928 | * | ||
2929 | */ | ||
2930 | |||
2931 | if (val == 255 || val < 5) | ||
2932 | { | ||
2933 | model_num = "3.4"; | ||
2934 | gus_type = 0x34; | ||
2935 | } | ||
2936 | else if (val < 10) | ||
2937 | { | ||
2938 | model_num = "3.7"; | ||
2939 | gus_type = 0x37; | ||
2940 | mixer_type = ICS2101; | ||
2941 | request_region(u_MixSelect, 1, "GUS mixer"); | ||
2942 | } | ||
2943 | else | ||
2944 | { | ||
2945 | struct resource *ports; | ||
2946 | ports = request_region(gus_base + 0x10c, 4, "ad1848"); | ||
2947 | model_num = "MAX"; | ||
2948 | gus_type = 0x40; | ||
2949 | mixer_type = CS4231; | ||
2950 | #ifdef CONFIG_SOUND_GUSMAX | ||
2951 | { | ||
2952 | unsigned char max_config = 0x40; /* Codec enable */ | ||
2953 | |||
2954 | if (gus_dma2 == -1) | ||
2955 | gus_dma2 = gus_dma; | ||
2956 | |||
2957 | if (gus_dma > 3) | ||
2958 | max_config |= 0x10; /* 16 bit capture DMA */ | ||
2959 | |||
2960 | if (gus_dma2 > 3) | ||
2961 | max_config |= 0x20; /* 16 bit playback DMA */ | ||
2962 | |||
2963 | max_config |= (gus_base >> 4) & 0x0f; /* Extract the X from 2X0 */ | ||
2964 | |||
2965 | outb((max_config), gus_base + 0x106); /* UltraMax control */ | ||
2966 | } | ||
2967 | |||
2968 | if (!ports) | ||
2969 | goto no_cs4231; | ||
2970 | |||
2971 | if (ad1848_detect(ports, &ad_flags, hw_config->osp)) | ||
2972 | { | ||
2973 | char *name = "GUS MAX"; | ||
2974 | int old_num_mixers = num_mixers; | ||
2975 | |||
2976 | if (gus_pnp_flag) | ||
2977 | name = "GUS PnP"; | ||
2978 | |||
2979 | gus_mic_vol = gus_line_vol = gus_pcm_volume = 100; | ||
2980 | gus_wave_volume = 90; | ||
2981 | have_gus_max = 1; | ||
2982 | if (hw_config->name) | ||
2983 | name = hw_config->name; | ||
2984 | |||
2985 | hw_config->slots[1] = ad1848_init(name, ports, | ||
2986 | -irq, gus_dma2, /* Playback DMA */ | ||
2987 | gus_dma, /* Capture DMA */ | ||
2988 | 1, /* Share DMA channels with GF1 */ | ||
2989 | hw_config->osp, | ||
2990 | THIS_MODULE); | ||
2991 | |||
2992 | if (num_mixers > old_num_mixers) | ||
2993 | { | ||
2994 | /* GUS has it's own mixer map */ | ||
2995 | AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_SYNTH); | ||
2996 | AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD); | ||
2997 | AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE); | ||
2998 | } | ||
2999 | } | ||
3000 | else { | ||
3001 | release_region(gus_base + 0x10c, 4); | ||
3002 | no_cs4231: | ||
3003 | printk(KERN_WARNING "GUS: No CS4231 ??"); | ||
3004 | } | ||
3005 | #else | ||
3006 | printk(KERN_ERR "GUS MAX found, but not compiled in\n"); | ||
3007 | #endif | ||
3008 | } | ||
3009 | } | ||
3010 | else | ||
3011 | { | ||
3012 | /* | ||
3013 | * ASIC not detected so the card must be 2.2 or 2.4. | ||
3014 | * There could still be the 16-bit/mixer daughter card. | ||
3015 | */ | ||
3016 | } | ||
3017 | |||
3018 | if (hw_config->name) | ||
3019 | snprintf(tmp, sizeof(tmp), "%s (%dk)", hw_config->name, | ||
3020 | (int) gus_mem_size / 1024); | ||
3021 | else if (gus_pnp_flag) | ||
3022 | snprintf(tmp, sizeof(tmp), "Gravis UltraSound PnP (%dk)", | ||
3023 | (int) gus_mem_size / 1024); | ||
3024 | else | ||
3025 | snprintf(tmp, sizeof(tmp), "Gravis UltraSound %s (%dk)", model_num, | ||
3026 | (int) gus_mem_size / 1024); | ||
3027 | |||
3028 | |||
3029 | samples = (struct patch_info *)vmalloc((MAX_SAMPLE + 1) * sizeof(*samples)); | ||
3030 | if (samples == NULL) | ||
3031 | { | ||
3032 | printk(KERN_WARNING "gus_init: Cant allocate memory for instrument tables\n"); | ||
3033 | return; | ||
3034 | } | ||
3035 | conf_printf(tmp, hw_config); | ||
3036 | strlcpy(gus_info.name, tmp, sizeof(gus_info.name)); | ||
3037 | |||
3038 | if ((sdev = sound_alloc_synthdev()) == -1) | ||
3039 | printk(KERN_WARNING "gus_init: Too many synthesizers\n"); | ||
3040 | else | ||
3041 | { | ||
3042 | voice_alloc = &guswave_operations.alloc; | ||
3043 | if (iw_mode) | ||
3044 | guswave_operations.id = "IWAVE"; | ||
3045 | hw_config->slots[0] = sdev; | ||
3046 | synth_devs[sdev] = &guswave_operations; | ||
3047 | sequencer_init(); | ||
3048 | gus_tmr_install(gus_base + 8); | ||
3049 | } | ||
3050 | |||
3051 | reset_sample_memory(); | ||
3052 | |||
3053 | gus_initialize(); | ||
3054 | |||
3055 | if ((gus_mem_size > 0) && !gus_no_wave_dma) | ||
3056 | { | ||
3057 | hw_config->slots[4] = -1; | ||
3058 | if ((gus_devnum = sound_install_audiodrv(AUDIO_DRIVER_VERSION, | ||
3059 | "Ultrasound", | ||
3060 | &gus_audio_driver, | ||
3061 | sizeof(struct audio_driver), | ||
3062 | NEEDS_RESTART | | ||
3063 | ((!iw_mode && dma2 != dma && dma2 != -1) ? | ||
3064 | DMA_DUPLEX : 0), | ||
3065 | AFMT_U8 | AFMT_S16_LE, | ||
3066 | NULL, dma, dma2)) < 0) | ||
3067 | { | ||
3068 | return; | ||
3069 | } | ||
3070 | |||
3071 | hw_config->slots[4] = gus_devnum; | ||
3072 | audio_devs[gus_devnum]->min_fragment = 9; /* 512k */ | ||
3073 | audio_devs[gus_devnum]->max_fragment = 11; /* 8k (must match size of bounce_buf */ | ||
3074 | audio_devs[gus_devnum]->mixer_dev = -1; /* Next mixer# */ | ||
3075 | audio_devs[gus_devnum]->flags |= DMA_HARDSTOP; | ||
3076 | } | ||
3077 | |||
3078 | /* | ||
3079 | * Mixer dependent initialization. | ||
3080 | */ | ||
3081 | |||
3082 | switch (mixer_type) | ||
3083 | { | ||
3084 | case ICS2101: | ||
3085 | gus_mic_vol = gus_line_vol = gus_pcm_volume = 100; | ||
3086 | gus_wave_volume = 90; | ||
3087 | request_region(u_MixSelect, 1, "GUS mixer"); | ||
3088 | hw_config->slots[5] = ics2101_mixer_init(); | ||
3089 | audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5]; /* Next mixer# */ | ||
3090 | return; | ||
3091 | |||
3092 | case CS4231: | ||
3093 | /* Initialized elsewhere (ad1848.c) */ | ||
3094 | default: | ||
3095 | hw_config->slots[5] = gus_default_mixer_init(); | ||
3096 | audio_devs[gus_devnum]->mixer_dev = hw_config->slots[5]; /* Next mixer# */ | ||
3097 | return; | ||
3098 | } | ||
3099 | } | ||
3100 | |||
3101 | void __exit gus_wave_unload(struct address_info *hw_config) | ||
3102 | { | ||
3103 | #ifdef CONFIG_SOUND_GUSMAX | ||
3104 | if (have_gus_max) | ||
3105 | { | ||
3106 | ad1848_unload(gus_base + 0x10c, | ||
3107 | -gus_irq, | ||
3108 | gus_dma2, /* Playback DMA */ | ||
3109 | gus_dma, /* Capture DMA */ | ||
3110 | 1); /* Share DMA channels with GF1 */ | ||
3111 | } | ||
3112 | #endif | ||
3113 | |||
3114 | if (mixer_type == ICS2101) | ||
3115 | { | ||
3116 | release_region(u_MixSelect, 1); | ||
3117 | } | ||
3118 | if (hw_config->slots[0] != -1) | ||
3119 | sound_unload_synthdev(hw_config->slots[0]); | ||
3120 | if (hw_config->slots[1] != -1) | ||
3121 | sound_unload_audiodev(hw_config->slots[1]); | ||
3122 | if (hw_config->slots[2] != -1) | ||
3123 | sound_unload_mididev(hw_config->slots[2]); | ||
3124 | if (hw_config->slots[4] != -1) | ||
3125 | sound_unload_audiodev(hw_config->slots[4]); | ||
3126 | if (hw_config->slots[5] != -1) | ||
3127 | sound_unload_mixerdev(hw_config->slots[5]); | ||
3128 | |||
3129 | vfree(samples); | ||
3130 | samples=NULL; | ||
3131 | } | ||
3132 | /* called in interrupt context */ | ||
3133 | static void do_loop_irq(int voice) | ||
3134 | { | ||
3135 | unsigned char tmp; | ||
3136 | int mode, parm; | ||
3137 | |||
3138 | spin_lock(&gus_lock); | ||
3139 | gus_select_voice(voice); | ||
3140 | |||
3141 | tmp = gus_read8(0x00); | ||
3142 | tmp &= ~0x20; /* | ||
3143 | * Disable wave IRQ for this_one voice | ||
3144 | */ | ||
3145 | gus_write8(0x00, tmp); | ||
3146 | |||
3147 | if (tmp & 0x03) /* Voice stopped */ | ||
3148 | voice_alloc->map[voice] = 0; | ||
3149 | |||
3150 | mode = voices[voice].loop_irq_mode; | ||
3151 | voices[voice].loop_irq_mode = 0; | ||
3152 | parm = voices[voice].loop_irq_parm; | ||
3153 | |||
3154 | switch (mode) | ||
3155 | { | ||
3156 | case LMODE_FINISH: /* | ||
3157 | * Final loop finished, shoot volume down | ||
3158 | */ | ||
3159 | |||
3160 | if ((int) (gus_read16(0x09) >> 4) < 100) /* | ||
3161 | * Get current volume | ||
3162 | */ | ||
3163 | { | ||
3164 | gus_voice_off(); | ||
3165 | gus_rampoff(); | ||
3166 | gus_voice_init(voice); | ||
3167 | break; | ||
3168 | } | ||
3169 | gus_ramp_range(65, 4065); | ||
3170 | gus_ramp_rate(0, 63); /* | ||
3171 | * Fastest possible rate | ||
3172 | */ | ||
3173 | gus_rampon(0x20 | 0x40); /* | ||
3174 | * Ramp down, once, irq | ||
3175 | */ | ||
3176 | voices[voice].volume_irq_mode = VMODE_HALT; | ||
3177 | break; | ||
3178 | |||
3179 | case LMODE_PCM_STOP: | ||
3180 | pcm_active = 0; /* Signal to the play_next_pcm_block routine */ | ||
3181 | case LMODE_PCM: | ||
3182 | { | ||
3183 | pcm_qlen--; | ||
3184 | pcm_head = (pcm_head + 1) % pcm_nblk; | ||
3185 | if (pcm_qlen && pcm_active) | ||
3186 | { | ||
3187 | play_next_pcm_block(); | ||
3188 | } | ||
3189 | else | ||
3190 | { | ||
3191 | /* Underrun. Just stop the voice */ | ||
3192 | gus_select_voice(0); /* Left channel */ | ||
3193 | gus_voice_off(); | ||
3194 | gus_rampoff(); | ||
3195 | gus_select_voice(1); /* Right channel */ | ||
3196 | gus_voice_off(); | ||
3197 | gus_rampoff(); | ||
3198 | pcm_active = 0; | ||
3199 | } | ||
3200 | |||
3201 | /* | ||
3202 | * If the queue was full before this interrupt, the DMA transfer was | ||
3203 | * suspended. Let it continue now. | ||
3204 | */ | ||
3205 | |||
3206 | if (audio_devs[gus_devnum]->dmap_out->qlen > 0) | ||
3207 | DMAbuf_outputintr(gus_devnum, 0); | ||
3208 | } | ||
3209 | break; | ||
3210 | |||
3211 | default: | ||
3212 | break; | ||
3213 | } | ||
3214 | spin_unlock(&gus_lock); | ||
3215 | } | ||
3216 | |||
3217 | static void do_volume_irq(int voice) | ||
3218 | { | ||
3219 | unsigned char tmp; | ||
3220 | int mode, parm; | ||
3221 | unsigned long flags; | ||
3222 | |||
3223 | spin_lock_irqsave(&gus_lock,flags); | ||
3224 | |||
3225 | gus_select_voice(voice); | ||
3226 | tmp = gus_read8(0x0d); | ||
3227 | tmp &= ~0x20; /* | ||
3228 | * Disable volume ramp IRQ | ||
3229 | */ | ||
3230 | gus_write8(0x0d, tmp); | ||
3231 | |||
3232 | mode = voices[voice].volume_irq_mode; | ||
3233 | voices[voice].volume_irq_mode = 0; | ||
3234 | parm = voices[voice].volume_irq_parm; | ||
3235 | |||
3236 | switch (mode) | ||
3237 | { | ||
3238 | case VMODE_HALT: /* Decay phase finished */ | ||
3239 | if (iw_mode) | ||
3240 | gus_write8(0x15, 0x02); /* Set voice deactivate bit of SMSI */ | ||
3241 | spin_unlock_irqrestore(&gus_lock,flags); | ||
3242 | gus_voice_init(voice); | ||
3243 | break; | ||
3244 | |||
3245 | case VMODE_ENVELOPE: | ||
3246 | gus_rampoff(); | ||
3247 | spin_unlock_irqrestore(&gus_lock,flags); | ||
3248 | step_envelope(voice); | ||
3249 | break; | ||
3250 | |||
3251 | case VMODE_START_NOTE: | ||
3252 | spin_unlock_irqrestore(&gus_lock,flags); | ||
3253 | guswave_start_note2(voices[voice].dev_pending, voice, | ||
3254 | voices[voice].note_pending, voices[voice].volume_pending); | ||
3255 | if (voices[voice].kill_pending) | ||
3256 | guswave_kill_note(voices[voice].dev_pending, voice, | ||
3257 | voices[voice].note_pending, 0); | ||
3258 | |||
3259 | if (voices[voice].sample_pending >= 0) | ||
3260 | { | ||
3261 | guswave_set_instr(voices[voice].dev_pending, voice, | ||
3262 | voices[voice].sample_pending); | ||
3263 | voices[voice].sample_pending = -1; | ||
3264 | } | ||
3265 | break; | ||
3266 | |||
3267 | default: | ||
3268 | spin_unlock_irqrestore(&gus_lock,flags); | ||
3269 | } | ||
3270 | } | ||
3271 | /* called in irq context */ | ||
3272 | void gus_voice_irq(void) | ||
3273 | { | ||
3274 | unsigned long wave_ignore = 0, volume_ignore = 0; | ||
3275 | unsigned long voice_bit; | ||
3276 | |||
3277 | unsigned char src, voice; | ||
3278 | |||
3279 | while (1) | ||
3280 | { | ||
3281 | src = gus_read8(0x0f); /* | ||
3282 | * Get source info | ||
3283 | */ | ||
3284 | voice = src & 0x1f; | ||
3285 | src &= 0xc0; | ||
3286 | |||
3287 | if (src == (0x80 | 0x40)) | ||
3288 | return; /* | ||
3289 | * No interrupt | ||
3290 | */ | ||
3291 | |||
3292 | voice_bit = 1 << voice; | ||
3293 | |||
3294 | if (!(src & 0x80)) /* | ||
3295 | * Wave IRQ pending | ||
3296 | */ | ||
3297 | if (!(wave_ignore & voice_bit) && (int) voice < nr_voices) /* | ||
3298 | * Not done | ||
3299 | * yet | ||
3300 | */ | ||
3301 | { | ||
3302 | wave_ignore |= voice_bit; | ||
3303 | do_loop_irq(voice); | ||
3304 | } | ||
3305 | if (!(src & 0x40)) /* | ||
3306 | * Volume IRQ pending | ||
3307 | */ | ||
3308 | if (!(volume_ignore & voice_bit) && (int) voice < nr_voices) /* | ||
3309 | * Not done | ||
3310 | * yet | ||
3311 | */ | ||
3312 | { | ||
3313 | volume_ignore |= voice_bit; | ||
3314 | do_volume_irq(voice); | ||
3315 | } | ||
3316 | } | ||
3317 | } | ||
3318 | |||
3319 | void guswave_dma_irq(void) | ||
3320 | { | ||
3321 | unsigned char status; | ||
3322 | |||
3323 | status = gus_look8(0x41); /* Get DMA IRQ Status */ | ||
3324 | if (status & 0x40) /* DMA interrupt pending */ | ||
3325 | switch (active_device) | ||
3326 | { | ||
3327 | case GUS_DEV_WAVE: | ||
3328 | wake_up(&dram_sleeper); | ||
3329 | break; | ||
3330 | |||
3331 | case GUS_DEV_PCM_CONTINUE: /* Left channel data transferred */ | ||
3332 | gus_write8(0x41, 0); /* Disable GF1 DMA */ | ||
3333 | gus_transfer_output_block(pcm_current_dev, pcm_current_buf, | ||
3334 | pcm_current_count, | ||
3335 | pcm_current_intrflag, 1); | ||
3336 | break; | ||
3337 | |||
3338 | case GUS_DEV_PCM_DONE: /* Right or mono channel data transferred */ | ||
3339 | gus_write8(0x41, 0); /* Disable GF1 DMA */ | ||
3340 | if (pcm_qlen < pcm_nblk) | ||
3341 | { | ||
3342 | dma_active = 0; | ||
3343 | if (gus_busy) | ||
3344 | { | ||
3345 | if (audio_devs[gus_devnum]->dmap_out->qlen > 0) | ||
3346 | DMAbuf_outputintr(gus_devnum, 0); | ||
3347 | } | ||
3348 | } | ||
3349 | break; | ||
3350 | |||
3351 | default: | ||
3352 | break; | ||
3353 | } | ||
3354 | status = gus_look8(0x49); /* | ||
3355 | * Get Sampling IRQ Status | ||
3356 | */ | ||
3357 | if (status & 0x40) /* | ||
3358 | * Sampling Irq pending | ||
3359 | */ | ||
3360 | { | ||
3361 | DMAbuf_inputintr(gus_devnum); | ||
3362 | } | ||
3363 | } | ||
3364 | |||
3365 | /* | ||
3366 | * Timer stuff | ||
3367 | */ | ||
3368 | |||
3369 | static volatile int select_addr, data_addr; | ||
3370 | static volatile int curr_timer; | ||
3371 | |||
3372 | void gus_timer_command(unsigned int addr, unsigned int val) | ||
3373 | { | ||
3374 | int i; | ||
3375 | |||
3376 | outb(((unsigned char) (addr & 0xff)), select_addr); | ||
3377 | |||
3378 | for (i = 0; i < 2; i++) | ||
3379 | inb(select_addr); | ||
3380 | |||
3381 | outb(((unsigned char) (val & 0xff)), data_addr); | ||
3382 | |||
3383 | for (i = 0; i < 2; i++) | ||
3384 | inb(select_addr); | ||
3385 | } | ||
3386 | |||
3387 | static void arm_timer(int timer, unsigned int interval) | ||
3388 | { | ||
3389 | curr_timer = timer; | ||
3390 | |||
3391 | if (timer == 1) | ||
3392 | { | ||
3393 | gus_write8(0x46, 256 - interval); /* Set counter for timer 1 */ | ||
3394 | gus_write8(0x45, 0x04); /* Enable timer 1 IRQ */ | ||
3395 | gus_timer_command(0x04, 0x01); /* Start timer 1 */ | ||
3396 | } | ||
3397 | else | ||
3398 | { | ||
3399 | gus_write8(0x47, 256 - interval); /* Set counter for timer 2 */ | ||
3400 | gus_write8(0x45, 0x08); /* Enable timer 2 IRQ */ | ||
3401 | gus_timer_command(0x04, 0x02); /* Start timer 2 */ | ||
3402 | } | ||
3403 | |||
3404 | gus_timer_enabled = 1; | ||
3405 | } | ||
3406 | |||
3407 | static unsigned int gus_tmr_start(int dev, unsigned int usecs_per_tick) | ||
3408 | { | ||
3409 | int timer_no, resolution; | ||
3410 | int divisor; | ||
3411 | |||
3412 | if (usecs_per_tick > (256 * 80)) | ||
3413 | { | ||
3414 | timer_no = 2; | ||
3415 | resolution = 320; /* usec */ | ||
3416 | } | ||
3417 | else | ||
3418 | { | ||
3419 | timer_no = 1; | ||
3420 | resolution = 80; /* usec */ | ||
3421 | } | ||
3422 | divisor = (usecs_per_tick + (resolution / 2)) / resolution; | ||
3423 | arm_timer(timer_no, divisor); | ||
3424 | |||
3425 | return divisor * resolution; | ||
3426 | } | ||
3427 | |||
3428 | static void gus_tmr_disable(int dev) | ||
3429 | { | ||
3430 | gus_write8(0x45, 0); /* Disable both timers */ | ||
3431 | gus_timer_enabled = 0; | ||
3432 | } | ||
3433 | |||
3434 | static void gus_tmr_restart(int dev) | ||
3435 | { | ||
3436 | if (curr_timer == 1) | ||
3437 | gus_write8(0x45, 0x04); /* Start timer 1 again */ | ||
3438 | else | ||
3439 | gus_write8(0x45, 0x08); /* Start timer 2 again */ | ||
3440 | gus_timer_enabled = 1; | ||
3441 | } | ||
3442 | |||
3443 | static struct sound_lowlev_timer gus_tmr = | ||
3444 | { | ||
3445 | 0, | ||
3446 | 1, | ||
3447 | gus_tmr_start, | ||
3448 | gus_tmr_disable, | ||
3449 | gus_tmr_restart | ||
3450 | }; | ||
3451 | |||
3452 | static void gus_tmr_install(int io_base) | ||
3453 | { | ||
3454 | struct sound_lowlev_timer *tmr; | ||
3455 | |||
3456 | select_addr = io_base; | ||
3457 | data_addr = io_base + 1; | ||
3458 | |||
3459 | tmr = &gus_tmr; | ||
3460 | |||
3461 | #ifdef THIS_GETS_FIXED | ||
3462 | sound_timer_init(&gus_tmr, "GUS"); | ||
3463 | #endif | ||
3464 | } | ||
diff --git a/sound/oss/harmony.c b/sound/oss/harmony.c deleted file mode 100644 index 6601b284f03a..000000000000 --- a/sound/oss/harmony.c +++ /dev/null | |||
@@ -1,1330 +0,0 @@ | |||
1 | /* | ||
2 | sound/oss/harmony.c | ||
3 | |||
4 | This is a sound driver for ASP's and Lasi's Harmony sound chip | ||
5 | and is unlikely to be used for anything other than on a HP PA-RISC. | ||
6 | |||
7 | Harmony is found in HP 712s, 715/new and many other GSC based machines. | ||
8 | On older 715 machines you'll find the technically identical chip | ||
9 | called 'Vivace'. Both Harmony and Vicace are supported by this driver. | ||
10 | |||
11 | Copyright 2000 (c) Linuxcare Canada, Alex deVries <alex@onefishtwo.ca> | ||
12 | Copyright 2000-2003 (c) Helge Deller <deller@gmx.de> | ||
13 | Copyright 2001 (c) Matthieu Delahaye <delahaym@esiee.fr> | ||
14 | Copyright 2001 (c) Jean-Christophe Vaugeois <vaugeoij@esiee.fr> | ||
15 | Copyright 2004 (c) Stuart Brady <sdbrady@ntlworld.com> | ||
16 | |||
17 | |||
18 | TODO: | ||
19 | - fix SNDCTL_DSP_GETOSPACE and SNDCTL_DSP_GETISPACE ioctls to | ||
20 | return the real values | ||
21 | - add private ioctl for selecting line- or microphone input | ||
22 | (only one of them is available at the same time) | ||
23 | - add module parameters | ||
24 | - implement mmap functionality | ||
25 | - implement gain meter ? | ||
26 | - ... | ||
27 | */ | ||
28 | |||
29 | #include <linux/delay.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/ioport.h> | ||
34 | #include <linux/types.h> | ||
35 | #include <linux/mm.h> | ||
36 | #include <linux/pci.h> | ||
37 | |||
38 | #include <asm/parisc-device.h> | ||
39 | #include <asm/io.h> | ||
40 | |||
41 | #include "sound_config.h" | ||
42 | |||
43 | |||
44 | #define PFX "harmony: " | ||
45 | #define HARMONY_VERSION "V0.9a" | ||
46 | |||
47 | #undef DEBUG | ||
48 | #ifdef DEBUG | ||
49 | # define DPRINTK printk | ||
50 | #else | ||
51 | # define DPRINTK(x,...) | ||
52 | #endif | ||
53 | |||
54 | |||
55 | #define MAX_BUFS 10 /* maximum number of rotating buffers */ | ||
56 | #define HARMONY_BUF_SIZE 4096 /* needs to be a multiple of PAGE_SIZE (4096)! */ | ||
57 | |||
58 | #define CNTL_C 0x80000000 | ||
59 | #define CNTL_ST 0x00000020 | ||
60 | #define CNTL_44100 0x00000015 /* HARMONY_SR_44KHZ */ | ||
61 | #define CNTL_8000 0x00000008 /* HARMONY_SR_8KHZ */ | ||
62 | |||
63 | #define GAINCTL_HE 0x08000000 | ||
64 | #define GAINCTL_LE 0x04000000 | ||
65 | #define GAINCTL_SE 0x02000000 | ||
66 | |||
67 | #define DSTATUS_PN 0x00000200 | ||
68 | #define DSTATUS_RN 0x00000002 | ||
69 | |||
70 | #define DSTATUS_IE 0x80000000 | ||
71 | |||
72 | #define HARMONY_DF_16BIT_LINEAR 0 | ||
73 | #define HARMONY_DF_8BIT_ULAW 1 | ||
74 | #define HARMONY_DF_8BIT_ALAW 2 | ||
75 | |||
76 | #define HARMONY_SS_MONO 0 | ||
77 | #define HARMONY_SS_STEREO 1 | ||
78 | |||
79 | #define HARMONY_SR_8KHZ 0x08 | ||
80 | #define HARMONY_SR_16KHZ 0x09 | ||
81 | #define HARMONY_SR_27KHZ 0x0A | ||
82 | #define HARMONY_SR_32KHZ 0x0B | ||
83 | #define HARMONY_SR_48KHZ 0x0E | ||
84 | #define HARMONY_SR_9KHZ 0x0F | ||
85 | #define HARMONY_SR_5KHZ 0x10 | ||
86 | #define HARMONY_SR_11KHZ 0x11 | ||
87 | #define HARMONY_SR_18KHZ 0x12 | ||
88 | #define HARMONY_SR_22KHZ 0x13 | ||
89 | #define HARMONY_SR_37KHZ 0x14 | ||
90 | #define HARMONY_SR_44KHZ 0x15 | ||
91 | #define HARMONY_SR_33KHZ 0x16 | ||
92 | #define HARMONY_SR_6KHZ 0x17 | ||
93 | |||
94 | /* | ||
95 | * Some magics numbers used to auto-detect file formats | ||
96 | */ | ||
97 | |||
98 | #define HARMONY_MAGIC_8B_ULAW 1 | ||
99 | #define HARMONY_MAGIC_8B_ALAW 27 | ||
100 | #define HARMONY_MAGIC_16B_LINEAR 3 | ||
101 | #define HARMONY_MAGIC_MONO 1 | ||
102 | #define HARMONY_MAGIC_STEREO 2 | ||
103 | |||
104 | /* | ||
105 | * Channels Positions in mixer register | ||
106 | */ | ||
107 | |||
108 | #define GAIN_HE_SHIFT 27 | ||
109 | #define GAIN_HE_MASK ( 1 << GAIN_HE_SHIFT) | ||
110 | #define GAIN_LE_SHIFT 26 | ||
111 | #define GAIN_LE_MASK ( 1 << GAIN_LE_SHIFT) | ||
112 | #define GAIN_SE_SHIFT 25 | ||
113 | #define GAIN_SE_MASK ( 1 << GAIN_SE_SHIFT) | ||
114 | #define GAIN_IS_SHIFT 24 | ||
115 | #define GAIN_IS_MASK ( 1 << GAIN_IS_SHIFT) | ||
116 | #define GAIN_MA_SHIFT 20 | ||
117 | #define GAIN_MA_MASK ( 0x0f << GAIN_MA_SHIFT) | ||
118 | #define GAIN_LI_SHIFT 16 | ||
119 | #define GAIN_LI_MASK ( 0x0f << GAIN_LI_SHIFT) | ||
120 | #define GAIN_RI_SHIFT 12 | ||
121 | #define GAIN_RI_MASK ( 0x0f << GAIN_RI_SHIFT) | ||
122 | #define GAIN_LO_SHIFT 6 | ||
123 | #define GAIN_LO_MASK ( 0x3f << GAIN_LO_SHIFT) | ||
124 | #define GAIN_RO_SHIFT 0 | ||
125 | #define GAIN_RO_MASK ( 0x3f << GAIN_RO_SHIFT) | ||
126 | |||
127 | |||
128 | #define MAX_OUTPUT_LEVEL (GAIN_RO_MASK >> GAIN_RO_SHIFT) | ||
129 | #define MAX_INPUT_LEVEL (GAIN_RI_MASK >> GAIN_RI_SHIFT) | ||
130 | #define MAX_MONITOR_LEVEL (GAIN_MA_MASK >> GAIN_MA_SHIFT) | ||
131 | |||
132 | #define MIXER_INTERNAL SOUND_MIXER_LINE1 | ||
133 | #define MIXER_LINEOUT SOUND_MIXER_LINE2 | ||
134 | #define MIXER_HEADPHONES SOUND_MIXER_LINE3 | ||
135 | |||
136 | #define MASK_INTERNAL SOUND_MASK_LINE1 | ||
137 | #define MASK_LINEOUT SOUND_MASK_LINE2 | ||
138 | #define MASK_HEADPHONES SOUND_MASK_LINE3 | ||
139 | |||
140 | /* | ||
141 | * Channels Mask in mixer register | ||
142 | */ | ||
143 | |||
144 | #define GAIN_TOTAL_SILENCE 0x00F00FFF | ||
145 | #define GAIN_DEFAULT 0x0FF00000 | ||
146 | |||
147 | |||
148 | struct harmony_hpa { | ||
149 | u8 unused000; | ||
150 | u8 id; | ||
151 | u8 teleshare_id; | ||
152 | u8 unused003; | ||
153 | u32 reset; | ||
154 | u32 cntl; | ||
155 | u32 gainctl; | ||
156 | u32 pnxtadd; | ||
157 | u32 pcuradd; | ||
158 | u32 rnxtadd; | ||
159 | u32 rcuradd; | ||
160 | u32 dstatus; | ||
161 | u32 ov; | ||
162 | u32 pio; | ||
163 | u32 unused02c; | ||
164 | u32 unused030[3]; | ||
165 | u32 diag; | ||
166 | }; | ||
167 | |||
168 | struct harmony_dev { | ||
169 | struct harmony_hpa *hpa; | ||
170 | struct parisc_device *dev; | ||
171 | u32 current_gain; | ||
172 | u32 dac_rate; /* 8000 ... 48000 (Hz) */ | ||
173 | u8 data_format; /* HARMONY_DF_xx_BIT_xxx */ | ||
174 | u8 sample_rate; /* HARMONY_SR_xx_KHZ */ | ||
175 | u8 stereo_select; /* HARMONY_SS_MONO or HARMONY_SS_STEREO */ | ||
176 | int format_initialized :1; | ||
177 | int suspended_playing :1; | ||
178 | int suspended_recording :1; | ||
179 | |||
180 | int blocked_playing :1; | ||
181 | int blocked_recording :1; | ||
182 | int audio_open :1; | ||
183 | int mixer_open :1; | ||
184 | |||
185 | wait_queue_head_t wq_play, wq_record; | ||
186 | int first_filled_play; /* first buffer containing data (next to play) */ | ||
187 | int nb_filled_play; | ||
188 | int play_offset; | ||
189 | int first_filled_record; | ||
190 | int nb_filled_record; | ||
191 | |||
192 | int dsp_unit, mixer_unit; | ||
193 | }; | ||
194 | |||
195 | |||
196 | static struct harmony_dev harmony; | ||
197 | |||
198 | |||
199 | /* | ||
200 | * Dynamic sound buffer allocation and DMA memory | ||
201 | */ | ||
202 | |||
203 | struct harmony_buffer { | ||
204 | unsigned char *addr; | ||
205 | dma_addr_t dma_handle; | ||
206 | int dma_coherent; /* Zero if dma_alloc_coherent() fails */ | ||
207 | unsigned int len; | ||
208 | }; | ||
209 | |||
210 | /* | ||
211 | * Harmony memory buffers | ||
212 | */ | ||
213 | |||
214 | static struct harmony_buffer played_buf, recorded_buf, silent, graveyard; | ||
215 | |||
216 | |||
217 | #define CHECK_WBACK_INV_OFFSET(b,offset,len) \ | ||
218 | do { if (!b.dma_coherent) \ | ||
219 | dma_cache_wback_inv((unsigned long)b.addr+offset,len); \ | ||
220 | } while (0) | ||
221 | |||
222 | |||
223 | static int __init harmony_alloc_buffer(struct harmony_buffer *b, | ||
224 | unsigned int buffer_count) | ||
225 | { | ||
226 | b->len = buffer_count * HARMONY_BUF_SIZE; | ||
227 | b->addr = dma_alloc_coherent(&harmony.dev->dev, | ||
228 | b->len, &b->dma_handle, GFP_KERNEL|GFP_DMA); | ||
229 | if (b->addr && b->dma_handle) { | ||
230 | b->dma_coherent = 1; | ||
231 | DPRINTK(KERN_INFO PFX "coherent memory: 0x%lx, played_buf: 0x%lx\n", | ||
232 | (unsigned long)b->dma_handle, (unsigned long)b->addr); | ||
233 | } else { | ||
234 | b->dma_coherent = 0; | ||
235 | /* kmalloc()ed memory will HPMC on ccio machines ! */ | ||
236 | b->addr = kmalloc(b->len, GFP_KERNEL); | ||
237 | if (!b->addr) { | ||
238 | printk(KERN_ERR PFX "couldn't allocate memory\n"); | ||
239 | return -EBUSY; | ||
240 | } | ||
241 | b->dma_handle = __pa(b->addr); | ||
242 | } | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static void __exit harmony_free_buffer(struct harmony_buffer *b) | ||
247 | { | ||
248 | if (!b->addr) | ||
249 | return; | ||
250 | |||
251 | if (b->dma_coherent) | ||
252 | dma_free_coherent(&harmony.dev->dev, | ||
253 | b->len, b->addr, b->dma_handle); | ||
254 | else | ||
255 | kfree(b->addr); | ||
256 | |||
257 | memset(b, 0, sizeof(*b)); | ||
258 | } | ||
259 | |||
260 | |||
261 | |||
262 | /* | ||
263 | * Low-Level sound-chip programming | ||
264 | */ | ||
265 | |||
266 | static void __inline__ harmony_wait_CNTL(void) | ||
267 | { | ||
268 | /* Wait until we're out of control mode */ | ||
269 | while (gsc_readl(&harmony.hpa->cntl) & CNTL_C) | ||
270 | /* wait */ ; | ||
271 | } | ||
272 | |||
273 | |||
274 | static void harmony_update_control(void) | ||
275 | { | ||
276 | u32 default_cntl; | ||
277 | |||
278 | /* Set CNTL */ | ||
279 | default_cntl = (CNTL_C | /* The C bit */ | ||
280 | (harmony.data_format << 6) | /* Set the data format */ | ||
281 | (harmony.stereo_select << 5) | /* Stereo select */ | ||
282 | (harmony.sample_rate)); /* Set sample rate */ | ||
283 | harmony.format_initialized = 1; | ||
284 | |||
285 | /* initialize CNTL */ | ||
286 | gsc_writel(default_cntl, &harmony.hpa->cntl); | ||
287 | } | ||
288 | |||
289 | static void harmony_set_control(u8 data_format, u8 sample_rate, u8 stereo_select) | ||
290 | { | ||
291 | harmony.sample_rate = sample_rate; | ||
292 | harmony.data_format = data_format; | ||
293 | harmony.stereo_select = stereo_select; | ||
294 | harmony_update_control(); | ||
295 | } | ||
296 | |||
297 | static void harmony_set_rate(u8 data_rate) | ||
298 | { | ||
299 | harmony.sample_rate = data_rate; | ||
300 | harmony_update_control(); | ||
301 | } | ||
302 | |||
303 | static int harmony_detect_rate(int *freq) | ||
304 | { | ||
305 | int newrate; | ||
306 | switch (*freq) { | ||
307 | case 8000: newrate = HARMONY_SR_8KHZ; break; | ||
308 | case 16000: newrate = HARMONY_SR_16KHZ; break; | ||
309 | case 27428: newrate = HARMONY_SR_27KHZ; break; | ||
310 | case 32000: newrate = HARMONY_SR_32KHZ; break; | ||
311 | case 48000: newrate = HARMONY_SR_48KHZ; break; | ||
312 | case 9600: newrate = HARMONY_SR_9KHZ; break; | ||
313 | case 5512: newrate = HARMONY_SR_5KHZ; break; | ||
314 | case 11025: newrate = HARMONY_SR_11KHZ; break; | ||
315 | case 18900: newrate = HARMONY_SR_18KHZ; break; | ||
316 | case 22050: newrate = HARMONY_SR_22KHZ; break; | ||
317 | case 37800: newrate = HARMONY_SR_37KHZ; break; | ||
318 | case 44100: newrate = HARMONY_SR_44KHZ; break; | ||
319 | case 33075: newrate = HARMONY_SR_33KHZ; break; | ||
320 | case 6615: newrate = HARMONY_SR_6KHZ; break; | ||
321 | default: newrate = HARMONY_SR_8KHZ; | ||
322 | *freq = 8000; break; | ||
323 | } | ||
324 | return newrate; | ||
325 | } | ||
326 | |||
327 | static void harmony_set_format(u8 data_format) | ||
328 | { | ||
329 | harmony.data_format = data_format; | ||
330 | harmony_update_control(); | ||
331 | } | ||
332 | |||
333 | static void harmony_set_stereo(u8 stereo_select) | ||
334 | { | ||
335 | harmony.stereo_select = stereo_select; | ||
336 | harmony_update_control(); | ||
337 | } | ||
338 | |||
339 | static void harmony_disable_interrupts(void) | ||
340 | { | ||
341 | harmony_wait_CNTL(); | ||
342 | gsc_writel(0, &harmony.hpa->dstatus); | ||
343 | } | ||
344 | |||
345 | static void harmony_enable_interrupts(void) | ||
346 | { | ||
347 | harmony_wait_CNTL(); | ||
348 | gsc_writel(DSTATUS_IE, &harmony.hpa->dstatus); | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * harmony_silence() | ||
353 | * | ||
354 | * This subroutine fills in a buffer starting at location start and | ||
355 | * silences for length bytes. This references the current | ||
356 | * configuration of the audio format. | ||
357 | * | ||
358 | */ | ||
359 | |||
360 | static void harmony_silence(struct harmony_buffer *buffer, int start, int length) | ||
361 | { | ||
362 | u8 silence_char; | ||
363 | |||
364 | /* Despite what you hear, silence is different in | ||
365 | different audio formats. */ | ||
366 | switch (harmony.data_format) { | ||
367 | case HARMONY_DF_8BIT_ULAW: silence_char = 0x55; break; | ||
368 | case HARMONY_DF_8BIT_ALAW: silence_char = 0xff; break; | ||
369 | case HARMONY_DF_16BIT_LINEAR: /* fall through */ | ||
370 | default: silence_char = 0; | ||
371 | } | ||
372 | |||
373 | memset(buffer->addr+start, silence_char, length); | ||
374 | } | ||
375 | |||
376 | |||
377 | static int harmony_audio_open(struct inode *inode, struct file *file) | ||
378 | { | ||
379 | if (harmony.audio_open) | ||
380 | return -EBUSY; | ||
381 | |||
382 | harmony.audio_open = 1; | ||
383 | harmony.suspended_playing = harmony.suspended_recording = 1; | ||
384 | harmony.blocked_playing = harmony.blocked_recording = 0; | ||
385 | harmony.first_filled_play = harmony.first_filled_record = 0; | ||
386 | harmony.nb_filled_play = harmony.nb_filled_record = 0; | ||
387 | harmony.play_offset = 0; | ||
388 | init_waitqueue_head(&harmony.wq_play); | ||
389 | init_waitqueue_head(&harmony.wq_record); | ||
390 | |||
391 | /* Start off in a balanced mode. */ | ||
392 | harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO); | ||
393 | harmony_update_control(); | ||
394 | harmony.format_initialized = 0; | ||
395 | |||
396 | /* Clear out all the buffers and flush to cache */ | ||
397 | harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS); | ||
398 | CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS); | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | /* | ||
404 | * Release (close) the audio device. | ||
405 | */ | ||
406 | |||
407 | static int harmony_audio_release(struct inode *inode, struct file *file) | ||
408 | { | ||
409 | if (!harmony.audio_open) | ||
410 | return -EBUSY; | ||
411 | |||
412 | harmony.audio_open = 0; | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | /* | ||
418 | * Read recorded data off the audio device. | ||
419 | */ | ||
420 | |||
421 | static ssize_t harmony_audio_read(struct file *file, | ||
422 | char *buffer, | ||
423 | size_t size_count, | ||
424 | loff_t *ppos) | ||
425 | { | ||
426 | int total_count = (int) size_count; | ||
427 | int count = 0; | ||
428 | int buf_to_read; | ||
429 | |||
430 | while (count<total_count) { | ||
431 | /* Wait until we're out of control mode */ | ||
432 | harmony_wait_CNTL(); | ||
433 | |||
434 | /* Figure out which buffer to fill in */ | ||
435 | if (harmony.nb_filled_record <= 2) { | ||
436 | harmony.blocked_recording = 1; | ||
437 | if (harmony.suspended_recording) { | ||
438 | harmony.suspended_recording = 0; | ||
439 | harmony_enable_interrupts(); | ||
440 | } | ||
441 | |||
442 | interruptible_sleep_on(&harmony.wq_record); | ||
443 | harmony.blocked_recording = 0; | ||
444 | } | ||
445 | |||
446 | if (harmony.nb_filled_record < 2) | ||
447 | return -EBUSY; | ||
448 | |||
449 | buf_to_read = harmony.first_filled_record; | ||
450 | |||
451 | /* Copy the page to an aligned buffer */ | ||
452 | if (copy_to_user(buffer+count, recorded_buf.addr + | ||
453 | (HARMONY_BUF_SIZE*buf_to_read), | ||
454 | HARMONY_BUF_SIZE)) { | ||
455 | count = -EFAULT; | ||
456 | break; | ||
457 | } | ||
458 | |||
459 | harmony.nb_filled_record--; | ||
460 | harmony.first_filled_record++; | ||
461 | harmony.first_filled_record %= MAX_BUFS; | ||
462 | |||
463 | count += HARMONY_BUF_SIZE; | ||
464 | } | ||
465 | return count; | ||
466 | } | ||
467 | |||
468 | |||
469 | |||
470 | |||
471 | /* | ||
472 | * Here is the place where we try to recognize file format. | ||
473 | * Sun/NeXT .au files begin with the string .snd | ||
474 | * At offset 12 is specified the encoding. | ||
475 | * At offset 16 is specified speed rate | ||
476 | * At Offset 20 is specified the numbers of voices | ||
477 | */ | ||
478 | |||
479 | #define four_bytes_to_u32(start) (file_header[start] << 24)|\ | ||
480 | (file_header[start+1] << 16)|\ | ||
481 | (file_header[start+2] << 8)|\ | ||
482 | (file_header[start+3]); | ||
483 | |||
484 | #define test_rate(tested,real_value,harmony_value) if ((tested)<=(real_value))\ | ||
485 | |||
486 | |||
487 | static int harmony_format_auto_detect(const char *buffer, int block_size) | ||
488 | { | ||
489 | u8 file_header[24]; | ||
490 | u32 start_string; | ||
491 | int ret = 0; | ||
492 | |||
493 | if (block_size>24) { | ||
494 | if (copy_from_user(file_header, buffer, sizeof(file_header))) | ||
495 | ret = -EFAULT; | ||
496 | |||
497 | start_string = four_bytes_to_u32(0); | ||
498 | |||
499 | if ((file_header[4]==0) && (start_string==0x2E736E64)) { | ||
500 | u32 format; | ||
501 | u32 nb_voices; | ||
502 | u32 speed; | ||
503 | |||
504 | format = four_bytes_to_u32(12); | ||
505 | nb_voices = four_bytes_to_u32(20); | ||
506 | speed = four_bytes_to_u32(16); | ||
507 | |||
508 | switch (format) { | ||
509 | case HARMONY_MAGIC_8B_ULAW: | ||
510 | harmony.data_format = HARMONY_DF_8BIT_ULAW; | ||
511 | break; | ||
512 | case HARMONY_MAGIC_8B_ALAW: | ||
513 | harmony.data_format = HARMONY_DF_8BIT_ALAW; | ||
514 | break; | ||
515 | case HARMONY_MAGIC_16B_LINEAR: | ||
516 | harmony.data_format = HARMONY_DF_16BIT_LINEAR; | ||
517 | break; | ||
518 | default: | ||
519 | harmony_set_control(HARMONY_DF_16BIT_LINEAR, | ||
520 | HARMONY_SR_44KHZ, HARMONY_SS_STEREO); | ||
521 | goto out; | ||
522 | } | ||
523 | switch (nb_voices) { | ||
524 | case HARMONY_MAGIC_MONO: | ||
525 | harmony.stereo_select = HARMONY_SS_MONO; | ||
526 | break; | ||
527 | case HARMONY_MAGIC_STEREO: | ||
528 | harmony.stereo_select = HARMONY_SS_STEREO; | ||
529 | break; | ||
530 | default: | ||
531 | harmony.stereo_select = HARMONY_SS_MONO; | ||
532 | break; | ||
533 | } | ||
534 | harmony_set_rate(harmony_detect_rate(&speed)); | ||
535 | harmony.dac_rate = speed; | ||
536 | goto out; | ||
537 | } | ||
538 | } | ||
539 | harmony_set_control(HARMONY_DF_8BIT_ULAW, HARMONY_SR_8KHZ, HARMONY_SS_MONO); | ||
540 | out: | ||
541 | return ret; | ||
542 | } | ||
543 | #undef four_bytes_to_u32 | ||
544 | |||
545 | |||
546 | static ssize_t harmony_audio_write(struct file *file, | ||
547 | const char *buffer, | ||
548 | size_t size_count, | ||
549 | loff_t *ppos) | ||
550 | { | ||
551 | int total_count = (int) size_count; | ||
552 | int count = 0; | ||
553 | int frame_size; | ||
554 | int buf_to_fill; | ||
555 | int fresh_buffer; | ||
556 | |||
557 | if (!harmony.format_initialized) { | ||
558 | if (harmony_format_auto_detect(buffer, total_count)) | ||
559 | return -EFAULT; | ||
560 | } | ||
561 | |||
562 | while (count<total_count) { | ||
563 | /* Wait until we're out of control mode */ | ||
564 | harmony_wait_CNTL(); | ||
565 | |||
566 | /* Figure out which buffer to fill in */ | ||
567 | if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset) { | ||
568 | harmony.blocked_playing = 1; | ||
569 | interruptible_sleep_on(&harmony.wq_play); | ||
570 | harmony.blocked_playing = 0; | ||
571 | } | ||
572 | if (harmony.nb_filled_play+2 >= MAX_BUFS && !harmony.play_offset) | ||
573 | return -EBUSY; | ||
574 | |||
575 | |||
576 | buf_to_fill = (harmony.first_filled_play+harmony.nb_filled_play); | ||
577 | if (harmony.play_offset) { | ||
578 | buf_to_fill--; | ||
579 | buf_to_fill += MAX_BUFS; | ||
580 | } | ||
581 | buf_to_fill %= MAX_BUFS; | ||
582 | |||
583 | fresh_buffer = (harmony.play_offset == 0); | ||
584 | |||
585 | /* Figure out the size of the frame */ | ||
586 | if ((total_count-count) >= HARMONY_BUF_SIZE - harmony.play_offset) { | ||
587 | frame_size = HARMONY_BUF_SIZE - harmony.play_offset; | ||
588 | } else { | ||
589 | frame_size = total_count - count; | ||
590 | /* Clear out the buffer, since there we'll only be | ||
591 | overlaying part of the old buffer with the new one */ | ||
592 | harmony_silence(&played_buf, | ||
593 | HARMONY_BUF_SIZE*buf_to_fill+frame_size+harmony.play_offset, | ||
594 | HARMONY_BUF_SIZE-frame_size-harmony.play_offset); | ||
595 | } | ||
596 | |||
597 | /* Copy the page to an aligned buffer */ | ||
598 | if (copy_from_user(played_buf.addr +(HARMONY_BUF_SIZE*buf_to_fill) + harmony.play_offset, | ||
599 | buffer+count, frame_size)) | ||
600 | return -EFAULT; | ||
601 | CHECK_WBACK_INV_OFFSET(played_buf, (HARMONY_BUF_SIZE*buf_to_fill + harmony.play_offset), | ||
602 | frame_size); | ||
603 | |||
604 | if (fresh_buffer) | ||
605 | harmony.nb_filled_play++; | ||
606 | |||
607 | count += frame_size; | ||
608 | harmony.play_offset += frame_size; | ||
609 | harmony.play_offset %= HARMONY_BUF_SIZE; | ||
610 | if (harmony.suspended_playing && (harmony.nb_filled_play>=4)) | ||
611 | harmony_enable_interrupts(); | ||
612 | } | ||
613 | |||
614 | return count; | ||
615 | } | ||
616 | |||
617 | static unsigned int harmony_audio_poll(struct file *file, | ||
618 | struct poll_table_struct *wait) | ||
619 | { | ||
620 | unsigned int mask = 0; | ||
621 | |||
622 | if (file->f_mode & FMODE_READ) { | ||
623 | if (!harmony.suspended_recording) | ||
624 | poll_wait(file, &harmony.wq_record, wait); | ||
625 | if (harmony.nb_filled_record) | ||
626 | mask |= POLLIN | POLLRDNORM; | ||
627 | } | ||
628 | |||
629 | if (file->f_mode & FMODE_WRITE) { | ||
630 | if (!harmony.suspended_playing) | ||
631 | poll_wait(file, &harmony.wq_play, wait); | ||
632 | if (harmony.nb_filled_play) | ||
633 | mask |= POLLOUT | POLLWRNORM; | ||
634 | } | ||
635 | |||
636 | return mask; | ||
637 | } | ||
638 | |||
639 | static int harmony_audio_ioctl(struct inode *inode, | ||
640 | struct file *file, | ||
641 | unsigned int cmd, | ||
642 | unsigned long arg) | ||
643 | { | ||
644 | int ival, new_format; | ||
645 | int frag_size, frag_buf; | ||
646 | struct audio_buf_info info; | ||
647 | |||
648 | switch (cmd) { | ||
649 | case OSS_GETVERSION: | ||
650 | return put_user(SOUND_VERSION, (int *) arg); | ||
651 | |||
652 | case SNDCTL_DSP_GETCAPS: | ||
653 | ival = DSP_CAP_DUPLEX; | ||
654 | return put_user(ival, (int *) arg); | ||
655 | |||
656 | case SNDCTL_DSP_GETFMTS: | ||
657 | ival = (AFMT_S16_BE | AFMT_MU_LAW | AFMT_A_LAW ); | ||
658 | return put_user(ival, (int *) arg); | ||
659 | |||
660 | case SNDCTL_DSP_SETFMT: | ||
661 | if (get_user(ival, (int *) arg)) | ||
662 | return -EFAULT; | ||
663 | if (ival != AFMT_QUERY) { | ||
664 | switch (ival) { | ||
665 | case AFMT_MU_LAW: new_format = HARMONY_DF_8BIT_ULAW; break; | ||
666 | case AFMT_A_LAW: new_format = HARMONY_DF_8BIT_ALAW; break; | ||
667 | case AFMT_S16_BE: new_format = HARMONY_DF_16BIT_LINEAR; break; | ||
668 | default: { | ||
669 | DPRINTK(KERN_WARNING PFX | ||
670 | "unsupported sound format 0x%04x requested.\n", | ||
671 | ival); | ||
672 | ival = AFMT_S16_BE; | ||
673 | return put_user(ival, (int *) arg); | ||
674 | } | ||
675 | } | ||
676 | harmony_set_format(new_format); | ||
677 | return 0; | ||
678 | } else { | ||
679 | switch (harmony.data_format) { | ||
680 | case HARMONY_DF_8BIT_ULAW: ival = AFMT_MU_LAW; break; | ||
681 | case HARMONY_DF_8BIT_ALAW: ival = AFMT_A_LAW; break; | ||
682 | case HARMONY_DF_16BIT_LINEAR: ival = AFMT_U16_BE; break; | ||
683 | default: ival = 0; | ||
684 | } | ||
685 | return put_user(ival, (int *) arg); | ||
686 | } | ||
687 | |||
688 | case SOUND_PCM_READ_RATE: | ||
689 | ival = harmony.dac_rate; | ||
690 | return put_user(ival, (int *) arg); | ||
691 | |||
692 | case SNDCTL_DSP_SPEED: | ||
693 | if (get_user(ival, (int *) arg)) | ||
694 | return -EFAULT; | ||
695 | harmony_set_rate(harmony_detect_rate(&ival)); | ||
696 | harmony.dac_rate = ival; | ||
697 | return put_user(ival, (int*) arg); | ||
698 | |||
699 | case SNDCTL_DSP_STEREO: | ||
700 | if (get_user(ival, (int *) arg)) | ||
701 | return -EFAULT; | ||
702 | if (ival != 0 && ival != 1) | ||
703 | return -EINVAL; | ||
704 | harmony_set_stereo(ival); | ||
705 | return 0; | ||
706 | |||
707 | case SNDCTL_DSP_CHANNELS: | ||
708 | if (get_user(ival, (int *) arg)) | ||
709 | return -EFAULT; | ||
710 | if (ival != 1 && ival != 2) { | ||
711 | ival = harmony.stereo_select == HARMONY_SS_MONO ? 1 : 2; | ||
712 | return put_user(ival, (int *) arg); | ||
713 | } | ||
714 | harmony_set_stereo(ival-1); | ||
715 | return 0; | ||
716 | |||
717 | case SNDCTL_DSP_GETBLKSIZE: | ||
718 | ival = HARMONY_BUF_SIZE; | ||
719 | return put_user(ival, (int *) arg); | ||
720 | |||
721 | case SNDCTL_DSP_NONBLOCK: | ||
722 | file->f_flags |= O_NONBLOCK; | ||
723 | return 0; | ||
724 | |||
725 | case SNDCTL_DSP_RESET: | ||
726 | if (!harmony.suspended_recording) { | ||
727 | /* TODO: stop_recording() */ | ||
728 | } | ||
729 | return 0; | ||
730 | |||
731 | case SNDCTL_DSP_SETFRAGMENT: | ||
732 | if (get_user(ival, (int *)arg)) | ||
733 | return -EFAULT; | ||
734 | frag_size = ival & 0xffff; | ||
735 | frag_buf = (ival>>16) & 0xffff; | ||
736 | /* TODO: We use hardcoded fragment sizes and numbers for now */ | ||
737 | frag_size = 12; /* 4096 == 2^12 */ | ||
738 | frag_buf = MAX_BUFS; | ||
739 | ival = (frag_buf << 16) + frag_size; | ||
740 | return put_user(ival, (int *) arg); | ||
741 | |||
742 | case SNDCTL_DSP_GETOSPACE: | ||
743 | if (!(file->f_mode & FMODE_WRITE)) | ||
744 | return -EINVAL; | ||
745 | info.fragstotal = MAX_BUFS; | ||
746 | info.fragments = MAX_BUFS - harmony.nb_filled_play; | ||
747 | info.fragsize = HARMONY_BUF_SIZE; | ||
748 | info.bytes = info.fragments * info.fragsize; | ||
749 | return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0; | ||
750 | |||
751 | case SNDCTL_DSP_GETISPACE: | ||
752 | if (!(file->f_mode & FMODE_READ)) | ||
753 | return -EINVAL; | ||
754 | info.fragstotal = MAX_BUFS; | ||
755 | info.fragments = /*MAX_BUFS-*/ harmony.nb_filled_record; | ||
756 | info.fragsize = HARMONY_BUF_SIZE; | ||
757 | info.bytes = info.fragments * info.fragsize; | ||
758 | return copy_to_user((void *)arg, &info, sizeof(info)) ? -EFAULT : 0; | ||
759 | |||
760 | case SNDCTL_DSP_SYNC: | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | return -EINVAL; | ||
765 | } | ||
766 | |||
767 | |||
768 | /* | ||
769 | * harmony_interrupt() | ||
770 | * | ||
771 | * harmony interruption service routine | ||
772 | * | ||
773 | */ | ||
774 | |||
775 | static irqreturn_t harmony_interrupt(int irq, void *dev, struct pt_regs *regs) | ||
776 | { | ||
777 | u32 dstatus; | ||
778 | struct harmony_hpa *hpa; | ||
779 | |||
780 | /* Setup the hpa */ | ||
781 | hpa = ((struct harmony_dev *)dev)->hpa; | ||
782 | harmony_wait_CNTL(); | ||
783 | |||
784 | /* Read dstatus and pcuradd (the current address) */ | ||
785 | dstatus = gsc_readl(&hpa->dstatus); | ||
786 | |||
787 | /* Turn off interrupts */ | ||
788 | harmony_disable_interrupts(); | ||
789 | |||
790 | /* Check if this is a request to get the next play buffer */ | ||
791 | if (dstatus & DSTATUS_PN) { | ||
792 | if (!harmony.nb_filled_play) { | ||
793 | harmony.suspended_playing = 1; | ||
794 | gsc_writel((unsigned long)silent.dma_handle, &hpa->pnxtadd); | ||
795 | |||
796 | if (!harmony.suspended_recording) | ||
797 | harmony_enable_interrupts(); | ||
798 | } else { | ||
799 | harmony.suspended_playing = 0; | ||
800 | gsc_writel((unsigned long)played_buf.dma_handle + | ||
801 | (HARMONY_BUF_SIZE*harmony.first_filled_play), | ||
802 | &hpa->pnxtadd); | ||
803 | harmony.first_filled_play++; | ||
804 | harmony.first_filled_play %= MAX_BUFS; | ||
805 | harmony.nb_filled_play--; | ||
806 | |||
807 | harmony_enable_interrupts(); | ||
808 | } | ||
809 | |||
810 | if (harmony.blocked_playing) | ||
811 | wake_up_interruptible(&harmony.wq_play); | ||
812 | } | ||
813 | |||
814 | /* Check if we're being asked to fill in a recording buffer */ | ||
815 | if (dstatus & DSTATUS_RN) { | ||
816 | if((harmony.nb_filled_record+2>=MAX_BUFS) || harmony.suspended_recording) | ||
817 | { | ||
818 | harmony.nb_filled_record = 0; | ||
819 | harmony.first_filled_record = 0; | ||
820 | harmony.suspended_recording = 1; | ||
821 | gsc_writel((unsigned long)graveyard.dma_handle, &hpa->rnxtadd); | ||
822 | if (!harmony.suspended_playing) | ||
823 | harmony_enable_interrupts(); | ||
824 | } else { | ||
825 | int buf_to_fill; | ||
826 | buf_to_fill = (harmony.first_filled_record+harmony.nb_filled_record) % MAX_BUFS; | ||
827 | CHECK_WBACK_INV_OFFSET(recorded_buf, HARMONY_BUF_SIZE*buf_to_fill, HARMONY_BUF_SIZE); | ||
828 | gsc_writel((unsigned long)recorded_buf.dma_handle + | ||
829 | HARMONY_BUF_SIZE*buf_to_fill, | ||
830 | &hpa->rnxtadd); | ||
831 | harmony.nb_filled_record++; | ||
832 | harmony_enable_interrupts(); | ||
833 | } | ||
834 | |||
835 | if (harmony.blocked_recording && harmony.nb_filled_record>3) | ||
836 | wake_up_interruptible(&harmony.wq_record); | ||
837 | } | ||
838 | return IRQ_HANDLED; | ||
839 | } | ||
840 | |||
841 | /* | ||
842 | * Sound playing functions | ||
843 | */ | ||
844 | |||
845 | static struct file_operations harmony_audio_fops = { | ||
846 | .owner = THIS_MODULE, | ||
847 | .llseek = no_llseek, | ||
848 | .read = harmony_audio_read, | ||
849 | .write = harmony_audio_write, | ||
850 | .poll = harmony_audio_poll, | ||
851 | .ioctl = harmony_audio_ioctl, | ||
852 | .open = harmony_audio_open, | ||
853 | .release = harmony_audio_release, | ||
854 | }; | ||
855 | |||
856 | static int harmony_audio_init(void) | ||
857 | { | ||
858 | /* Request that IRQ */ | ||
859 | if (request_irq(harmony.dev->irq, harmony_interrupt, 0 ,"harmony", &harmony)) { | ||
860 | printk(KERN_ERR PFX "Error requesting irq %d.\n", harmony.dev->irq); | ||
861 | return -EFAULT; | ||
862 | } | ||
863 | |||
864 | harmony.dsp_unit = register_sound_dsp(&harmony_audio_fops, -1); | ||
865 | if (harmony.dsp_unit < 0) { | ||
866 | printk(KERN_ERR PFX "Error registering dsp\n"); | ||
867 | free_irq(harmony.dev->irq, &harmony); | ||
868 | return -EFAULT; | ||
869 | } | ||
870 | |||
871 | /* Clear the buffers so you don't end up with crap in the buffers. */ | ||
872 | harmony_silence(&played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS); | ||
873 | |||
874 | /* Make sure this makes it to cache */ | ||
875 | CHECK_WBACK_INV_OFFSET(played_buf, 0, HARMONY_BUF_SIZE*MAX_BUFS); | ||
876 | |||
877 | /* Clear out the silent buffer and flush to cache */ | ||
878 | harmony_silence(&silent, 0, HARMONY_BUF_SIZE); | ||
879 | CHECK_WBACK_INV_OFFSET(silent, 0, HARMONY_BUF_SIZE); | ||
880 | |||
881 | harmony.audio_open = 0; | ||
882 | |||
883 | return 0; | ||
884 | } | ||
885 | |||
886 | |||
887 | /* | ||
888 | * mixer functions | ||
889 | */ | ||
890 | |||
891 | static void harmony_mixer_set_gain(void) | ||
892 | { | ||
893 | harmony_wait_CNTL(); | ||
894 | gsc_writel(harmony.current_gain, &harmony.hpa->gainctl); | ||
895 | } | ||
896 | |||
897 | /* | ||
898 | * Read gain of selected channel. | ||
899 | * The OSS rate is from 0 (silent) to 100 -> need some conversions | ||
900 | * | ||
901 | * The harmony gain are attenuation for output and monitor gain. | ||
902 | * is amplifaction for input gain | ||
903 | */ | ||
904 | #define to_harmony_level(level,max) ((level)*max/100) | ||
905 | #define to_oss_level(level,max) ((level)*100/max) | ||
906 | |||
907 | static int harmony_mixer_get_level(int channel) | ||
908 | { | ||
909 | int left_level; | ||
910 | int right_level; | ||
911 | |||
912 | switch (channel) { | ||
913 | case SOUND_MIXER_VOLUME: | ||
914 | left_level = (harmony.current_gain & GAIN_LO_MASK) >> GAIN_LO_SHIFT; | ||
915 | right_level = (harmony.current_gain & GAIN_RO_MASK) >> GAIN_RO_SHIFT; | ||
916 | left_level = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL); | ||
917 | right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL); | ||
918 | return (right_level << 8)+left_level; | ||
919 | |||
920 | case SOUND_MIXER_IGAIN: | ||
921 | left_level = (harmony.current_gain & GAIN_LI_MASK) >> GAIN_LI_SHIFT; | ||
922 | right_level= (harmony.current_gain & GAIN_RI_MASK) >> GAIN_RI_SHIFT; | ||
923 | left_level = to_oss_level(left_level, MAX_INPUT_LEVEL); | ||
924 | right_level= to_oss_level(right_level, MAX_INPUT_LEVEL); | ||
925 | return (right_level << 8)+left_level; | ||
926 | |||
927 | case SOUND_MIXER_MONITOR: | ||
928 | left_level = (harmony.current_gain & GAIN_MA_MASK) >> GAIN_MA_SHIFT; | ||
929 | left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL); | ||
930 | return (left_level << 8)+left_level; | ||
931 | } | ||
932 | return -EINVAL; | ||
933 | } | ||
934 | |||
935 | |||
936 | |||
937 | /* | ||
938 | * Some conversions for the same reasons. | ||
939 | * We give back the new real value(s) due to | ||
940 | * the rescale. | ||
941 | */ | ||
942 | |||
943 | static int harmony_mixer_set_level(int channel, int value) | ||
944 | { | ||
945 | int left_level; | ||
946 | int right_level; | ||
947 | int new_left_level; | ||
948 | int new_right_level; | ||
949 | |||
950 | right_level = (value & 0x0000ff00) >> 8; | ||
951 | left_level = value & 0x000000ff; | ||
952 | if (right_level > 100) right_level = 100; | ||
953 | if (left_level > 100) left_level = 100; | ||
954 | |||
955 | switch (channel) { | ||
956 | case SOUND_MIXER_VOLUME: | ||
957 | right_level = to_harmony_level(100-right_level, MAX_OUTPUT_LEVEL); | ||
958 | left_level = to_harmony_level(100-left_level, MAX_OUTPUT_LEVEL); | ||
959 | new_right_level = to_oss_level(MAX_OUTPUT_LEVEL - right_level, MAX_OUTPUT_LEVEL); | ||
960 | new_left_level = to_oss_level(MAX_OUTPUT_LEVEL - left_level, MAX_OUTPUT_LEVEL); | ||
961 | harmony.current_gain = (harmony.current_gain & ~(GAIN_LO_MASK | GAIN_RO_MASK)) | ||
962 | | (left_level << GAIN_LO_SHIFT) | (right_level << GAIN_RO_SHIFT); | ||
963 | harmony_mixer_set_gain(); | ||
964 | return (new_right_level << 8) + new_left_level; | ||
965 | |||
966 | case SOUND_MIXER_IGAIN: | ||
967 | right_level = to_harmony_level(right_level, MAX_INPUT_LEVEL); | ||
968 | left_level = to_harmony_level(left_level, MAX_INPUT_LEVEL); | ||
969 | new_right_level = to_oss_level(right_level, MAX_INPUT_LEVEL); | ||
970 | new_left_level = to_oss_level(left_level, MAX_INPUT_LEVEL); | ||
971 | harmony.current_gain = (harmony.current_gain & ~(GAIN_LI_MASK | GAIN_RI_MASK)) | ||
972 | | (left_level << GAIN_LI_SHIFT) | (right_level << GAIN_RI_SHIFT); | ||
973 | harmony_mixer_set_gain(); | ||
974 | return (new_right_level << 8) + new_left_level; | ||
975 | |||
976 | case SOUND_MIXER_MONITOR: | ||
977 | left_level = to_harmony_level(100-left_level, MAX_MONITOR_LEVEL); | ||
978 | new_left_level = to_oss_level(MAX_MONITOR_LEVEL-left_level, MAX_MONITOR_LEVEL); | ||
979 | harmony.current_gain = (harmony.current_gain & ~GAIN_MA_MASK) | (left_level << GAIN_MA_SHIFT); | ||
980 | harmony_mixer_set_gain(); | ||
981 | return (new_left_level << 8) + new_left_level; | ||
982 | } | ||
983 | |||
984 | return -EINVAL; | ||
985 | } | ||
986 | |||
987 | #undef to_harmony_level | ||
988 | #undef to_oss_level | ||
989 | |||
990 | /* | ||
991 | * Return the selected input device (mic or line) | ||
992 | */ | ||
993 | |||
994 | static int harmony_mixer_get_recmask(void) | ||
995 | { | ||
996 | int current_input_line; | ||
997 | |||
998 | current_input_line = (harmony.current_gain & GAIN_IS_MASK) | ||
999 | >> GAIN_IS_SHIFT; | ||
1000 | if (current_input_line) | ||
1001 | return SOUND_MASK_MIC; | ||
1002 | |||
1003 | return SOUND_MASK_LINE; | ||
1004 | } | ||
1005 | |||
1006 | /* | ||
1007 | * Set the input (only one at time, arbitrary priority to line in) | ||
1008 | */ | ||
1009 | |||
1010 | static int harmony_mixer_set_recmask(int recmask) | ||
1011 | { | ||
1012 | int new_input_line; | ||
1013 | int new_input_mask; | ||
1014 | int current_input_line; | ||
1015 | |||
1016 | current_input_line = (harmony.current_gain & GAIN_IS_MASK) | ||
1017 | >> GAIN_IS_SHIFT; | ||
1018 | if ((current_input_line && ((recmask & SOUND_MASK_LINE) || !(recmask & SOUND_MASK_MIC))) || | ||
1019 | (!current_input_line && ((recmask & SOUND_MASK_LINE) && !(recmask & SOUND_MASK_MIC)))) { | ||
1020 | new_input_line = 0; | ||
1021 | new_input_mask = SOUND_MASK_LINE; | ||
1022 | } else { | ||
1023 | new_input_line = 1; | ||
1024 | new_input_mask = SOUND_MASK_MIC; | ||
1025 | } | ||
1026 | harmony.current_gain = ((harmony.current_gain & ~GAIN_IS_MASK) | | ||
1027 | (new_input_line << GAIN_IS_SHIFT )); | ||
1028 | harmony_mixer_set_gain(); | ||
1029 | return new_input_mask; | ||
1030 | } | ||
1031 | |||
1032 | |||
1033 | /* | ||
1034 | * give the active outlines | ||
1035 | */ | ||
1036 | |||
1037 | static int harmony_mixer_get_outmask(void) | ||
1038 | { | ||
1039 | int outmask = 0; | ||
1040 | |||
1041 | if (harmony.current_gain & GAIN_SE_MASK) outmask |= MASK_INTERNAL; | ||
1042 | if (harmony.current_gain & GAIN_LE_MASK) outmask |= MASK_LINEOUT; | ||
1043 | if (harmony.current_gain & GAIN_HE_MASK) outmask |= MASK_HEADPHONES; | ||
1044 | |||
1045 | return outmask; | ||
1046 | } | ||
1047 | |||
1048 | |||
1049 | static int harmony_mixer_set_outmask(int outmask) | ||
1050 | { | ||
1051 | if (outmask & MASK_INTERNAL) | ||
1052 | harmony.current_gain |= GAIN_SE_MASK; | ||
1053 | else | ||
1054 | harmony.current_gain &= ~GAIN_SE_MASK; | ||
1055 | |||
1056 | if (outmask & MASK_LINEOUT) | ||
1057 | harmony.current_gain |= GAIN_LE_MASK; | ||
1058 | else | ||
1059 | harmony.current_gain &= ~GAIN_LE_MASK; | ||
1060 | |||
1061 | if (outmask & MASK_HEADPHONES) | ||
1062 | harmony.current_gain |= GAIN_HE_MASK; | ||
1063 | else | ||
1064 | harmony.current_gain &= ~GAIN_HE_MASK; | ||
1065 | |||
1066 | harmony_mixer_set_gain(); | ||
1067 | |||
1068 | return (outmask & (MASK_INTERNAL | MASK_LINEOUT | MASK_HEADPHONES)); | ||
1069 | } | ||
1070 | |||
1071 | /* | ||
1072 | * This code is inspired from sb_mixer.c | ||
1073 | */ | ||
1074 | |||
1075 | static int harmony_mixer_ioctl(struct inode * inode, struct file * file, | ||
1076 | unsigned int cmd, unsigned long arg) | ||
1077 | { | ||
1078 | int val; | ||
1079 | int ret; | ||
1080 | |||
1081 | if (cmd == SOUND_MIXER_INFO) { | ||
1082 | mixer_info info; | ||
1083 | memset(&info, 0, sizeof(info)); | ||
1084 | strncpy(info.id, "harmony", sizeof(info.id)-1); | ||
1085 | strncpy(info.name, "Harmony audio", sizeof(info.name)-1); | ||
1086 | info.modify_counter = 1; /* ? */ | ||
1087 | if (copy_to_user((void *)arg, &info, sizeof(info))) | ||
1088 | return -EFAULT; | ||
1089 | return 0; | ||
1090 | } | ||
1091 | |||
1092 | if (cmd == OSS_GETVERSION) | ||
1093 | return put_user(SOUND_VERSION, (int *)arg); | ||
1094 | |||
1095 | /* read */ | ||
1096 | val = 0; | ||
1097 | if (_SIOC_DIR(cmd) & _SIOC_WRITE) | ||
1098 | if (get_user(val, (int *)arg)) | ||
1099 | return -EFAULT; | ||
1100 | |||
1101 | switch (cmd) { | ||
1102 | case MIXER_READ(SOUND_MIXER_CAPS): | ||
1103 | ret = SOUND_CAP_EXCL_INPUT; | ||
1104 | break; | ||
1105 | case MIXER_READ(SOUND_MIXER_STEREODEVS): | ||
1106 | ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN; | ||
1107 | break; | ||
1108 | |||
1109 | case MIXER_READ(SOUND_MIXER_RECMASK): | ||
1110 | ret = SOUND_MASK_MIC | SOUND_MASK_LINE; | ||
1111 | break; | ||
1112 | case MIXER_READ(SOUND_MIXER_DEVMASK): | ||
1113 | ret = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN | | ||
1114 | SOUND_MASK_MONITOR; | ||
1115 | break; | ||
1116 | case MIXER_READ(SOUND_MIXER_OUTMASK): | ||
1117 | ret = MASK_INTERNAL | MASK_LINEOUT | | ||
1118 | MASK_HEADPHONES; | ||
1119 | break; | ||
1120 | |||
1121 | case MIXER_WRITE(SOUND_MIXER_RECSRC): | ||
1122 | ret = harmony_mixer_set_recmask(val); | ||
1123 | break; | ||
1124 | case MIXER_READ(SOUND_MIXER_RECSRC): | ||
1125 | ret = harmony_mixer_get_recmask(); | ||
1126 | break; | ||
1127 | |||
1128 | case MIXER_WRITE(SOUND_MIXER_OUTSRC): | ||
1129 | ret = harmony_mixer_set_outmask(val); | ||
1130 | break; | ||
1131 | case MIXER_READ(SOUND_MIXER_OUTSRC): | ||
1132 | ret = harmony_mixer_get_outmask(); | ||
1133 | break; | ||
1134 | |||
1135 | case MIXER_WRITE(SOUND_MIXER_VOLUME): | ||
1136 | case MIXER_WRITE(SOUND_MIXER_IGAIN): | ||
1137 | case MIXER_WRITE(SOUND_MIXER_MONITOR): | ||
1138 | ret = harmony_mixer_set_level(cmd & 0xff, val); | ||
1139 | break; | ||
1140 | |||
1141 | case MIXER_READ(SOUND_MIXER_VOLUME): | ||
1142 | case MIXER_READ(SOUND_MIXER_IGAIN): | ||
1143 | case MIXER_READ(SOUND_MIXER_MONITOR): | ||
1144 | ret = harmony_mixer_get_level(cmd & 0xff); | ||
1145 | break; | ||
1146 | |||
1147 | default: | ||
1148 | return -EINVAL; | ||
1149 | } | ||
1150 | |||
1151 | if (put_user(ret, (int *)arg)) | ||
1152 | return -EFAULT; | ||
1153 | return 0; | ||
1154 | } | ||
1155 | |||
1156 | |||
1157 | static int harmony_mixer_open(struct inode *inode, struct file *file) | ||
1158 | { | ||
1159 | if (harmony.mixer_open) | ||
1160 | return -EBUSY; | ||
1161 | harmony.mixer_open = 1; | ||
1162 | return 0; | ||
1163 | } | ||
1164 | |||
1165 | static int harmony_mixer_release(struct inode *inode, struct file *file) | ||
1166 | { | ||
1167 | if (!harmony.mixer_open) | ||
1168 | return -EBUSY; | ||
1169 | harmony.mixer_open = 0; | ||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | static struct file_operations harmony_mixer_fops = { | ||
1174 | .owner = THIS_MODULE, | ||
1175 | .llseek = no_llseek, | ||
1176 | .open = harmony_mixer_open, | ||
1177 | .release = harmony_mixer_release, | ||
1178 | .ioctl = harmony_mixer_ioctl, | ||
1179 | }; | ||
1180 | |||
1181 | |||
1182 | /* | ||
1183 | * Mute all the output and reset Harmony. | ||
1184 | */ | ||
1185 | |||
1186 | static void __init harmony_mixer_reset(void) | ||
1187 | { | ||
1188 | harmony.current_gain = GAIN_TOTAL_SILENCE; | ||
1189 | harmony_mixer_set_gain(); | ||
1190 | harmony_wait_CNTL(); | ||
1191 | gsc_writel(1, &harmony.hpa->reset); | ||
1192 | mdelay(50); /* wait 50 ms */ | ||
1193 | gsc_writel(0, &harmony.hpa->reset); | ||
1194 | harmony.current_gain = GAIN_DEFAULT; | ||
1195 | harmony_mixer_set_gain(); | ||
1196 | } | ||
1197 | |||
1198 | static int __init harmony_mixer_init(void) | ||
1199 | { | ||
1200 | /* Register the device file operations */ | ||
1201 | harmony.mixer_unit = register_sound_mixer(&harmony_mixer_fops, -1); | ||
1202 | if (harmony.mixer_unit < 0) { | ||
1203 | printk(KERN_WARNING PFX "Error Registering Mixer Driver\n"); | ||
1204 | return -EFAULT; | ||
1205 | } | ||
1206 | |||
1207 | harmony_mixer_reset(); | ||
1208 | harmony.mixer_open = 0; | ||
1209 | |||
1210 | return 0; | ||
1211 | } | ||
1212 | |||
1213 | |||
1214 | |||
1215 | /* | ||
1216 | * This is the callback that's called by the inventory hardware code | ||
1217 | * if it finds a match to the registered driver. | ||
1218 | */ | ||
1219 | static int __devinit | ||
1220 | harmony_driver_probe(struct parisc_device *dev) | ||
1221 | { | ||
1222 | u8 id; | ||
1223 | u8 rev; | ||
1224 | u32 cntl; | ||
1225 | int ret; | ||
1226 | |||
1227 | if (harmony.hpa) { | ||
1228 | /* We only support one Harmony at this time */ | ||
1229 | printk(KERN_ERR PFX "driver already registered\n"); | ||
1230 | return -EBUSY; | ||
1231 | } | ||
1232 | |||
1233 | if (!dev->irq) { | ||
1234 | printk(KERN_ERR PFX "no irq found\n"); | ||
1235 | return -ENODEV; | ||
1236 | } | ||
1237 | |||
1238 | /* Set the HPA of harmony */ | ||
1239 | harmony.hpa = (struct harmony_hpa *)dev->hpa.start; | ||
1240 | harmony.dev = dev; | ||
1241 | |||
1242 | /* Grab the ID and revision from the device */ | ||
1243 | id = gsc_readb(&harmony.hpa->id); | ||
1244 | if ((id | 1) != 0x15) { | ||
1245 | printk(KERN_WARNING PFX "wrong harmony id 0x%02x\n", id); | ||
1246 | return -EBUSY; | ||
1247 | } | ||
1248 | cntl = gsc_readl(&harmony.hpa->cntl); | ||
1249 | rev = (cntl>>20) & 0xff; | ||
1250 | |||
1251 | printk(KERN_INFO "Lasi Harmony Audio driver " HARMONY_VERSION ", " | ||
1252 | "h/w id %i, rev. %i at 0x%lx, IRQ %i\n", | ||
1253 | id, rev, dev->hpa.start, harmony.dev->irq); | ||
1254 | |||
1255 | /* Make sure the control bit isn't set, although I don't think it | ||
1256 | ever is. */ | ||
1257 | if (cntl & CNTL_C) { | ||
1258 | printk(KERN_WARNING PFX "CNTL busy\n"); | ||
1259 | harmony.hpa = 0; | ||
1260 | return -EBUSY; | ||
1261 | } | ||
1262 | |||
1263 | /* Initialize the memory buffers */ | ||
1264 | if (harmony_alloc_buffer(&played_buf, MAX_BUFS) || | ||
1265 | harmony_alloc_buffer(&recorded_buf, MAX_BUFS) || | ||
1266 | harmony_alloc_buffer(&graveyard, 1) || | ||
1267 | harmony_alloc_buffer(&silent, 1)) { | ||
1268 | ret = -EBUSY; | ||
1269 | goto out_err; | ||
1270 | } | ||
1271 | |||
1272 | /* Initialize /dev/mixer and /dev/audio */ | ||
1273 | if ((ret=harmony_mixer_init())) | ||
1274 | goto out_err; | ||
1275 | if ((ret=harmony_audio_init())) | ||
1276 | goto out_err; | ||
1277 | |||
1278 | return 0; | ||
1279 | |||
1280 | out_err: | ||
1281 | harmony.hpa = 0; | ||
1282 | harmony_free_buffer(&played_buf); | ||
1283 | harmony_free_buffer(&recorded_buf); | ||
1284 | harmony_free_buffer(&graveyard); | ||
1285 | harmony_free_buffer(&silent); | ||
1286 | return ret; | ||
1287 | } | ||
1288 | |||
1289 | |||
1290 | static struct parisc_device_id harmony_tbl[] = { | ||
1291 | /* { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, Bushmaster/Flounder */ | ||
1292 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B }, /* 712/715 Audio */ | ||
1293 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E }, /* Pace Audio */ | ||
1294 | { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F }, /* Outfield / Coral II */ | ||
1295 | { 0, } | ||
1296 | }; | ||
1297 | |||
1298 | MODULE_DEVICE_TABLE(parisc, harmony_tbl); | ||
1299 | |||
1300 | static struct parisc_driver harmony_driver = { | ||
1301 | .name = "Lasi Harmony", | ||
1302 | .id_table = harmony_tbl, | ||
1303 | .probe = harmony_driver_probe, | ||
1304 | }; | ||
1305 | |||
1306 | static int __init init_harmony(void) | ||
1307 | { | ||
1308 | return register_parisc_driver(&harmony_driver); | ||
1309 | } | ||
1310 | |||
1311 | static void __exit cleanup_harmony(void) | ||
1312 | { | ||
1313 | free_irq(harmony.dev->irq, &harmony); | ||
1314 | unregister_sound_mixer(harmony.mixer_unit); | ||
1315 | unregister_sound_dsp(harmony.dsp_unit); | ||
1316 | harmony_free_buffer(&played_buf); | ||
1317 | harmony_free_buffer(&recorded_buf); | ||
1318 | harmony_free_buffer(&graveyard); | ||
1319 | harmony_free_buffer(&silent); | ||
1320 | unregister_parisc_driver(&harmony_driver); | ||
1321 | } | ||
1322 | |||
1323 | |||
1324 | MODULE_AUTHOR("Alex DeVries <alex@onefishtwo.ca>"); | ||
1325 | MODULE_DESCRIPTION("Harmony sound driver"); | ||
1326 | MODULE_LICENSE("GPL"); | ||
1327 | |||
1328 | module_init(init_harmony); | ||
1329 | module_exit(cleanup_harmony); | ||
1330 | |||
diff --git a/sound/oss/ics2101.c b/sound/oss/ics2101.c deleted file mode 100644 index 45918df150b3..000000000000 --- a/sound/oss/ics2101.c +++ /dev/null | |||
@@ -1,247 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/ics2101.c | ||
3 | * | ||
4 | * Driver for the ICS2101 mixer of GUS v3.7. | ||
5 | * | ||
6 | * | ||
7 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
8 | * | ||
9 | * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
10 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
11 | * for more info. | ||
12 | * | ||
13 | * | ||
14 | * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed) | ||
15 | * Bartlomiej Zolnierkiewicz : added __init to ics2101_mixer_init() | ||
16 | */ | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/spinlock.h> | ||
19 | #include "sound_config.h" | ||
20 | |||
21 | #include <linux/ultrasound.h> | ||
22 | |||
23 | #include "gus.h" | ||
24 | #include "gus_hw.h" | ||
25 | |||
26 | #define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \ | ||
27 | SOUND_MASK_SYNTH| \ | ||
28 | SOUND_MASK_CD | SOUND_MASK_VOLUME) | ||
29 | |||
30 | extern int *gus_osp; | ||
31 | extern int gus_base; | ||
32 | extern spinlock_t gus_lock; | ||
33 | static int volumes[ICS_MIXDEVS]; | ||
34 | static int left_fix[ICS_MIXDEVS] = | ||
35 | {1, 1, 1, 2, 1, 2}; | ||
36 | static int right_fix[ICS_MIXDEVS] = | ||
37 | {2, 2, 2, 1, 2, 1}; | ||
38 | |||
39 | static int scale_vol(int vol) | ||
40 | { | ||
41 | /* | ||
42 | * Experimental volume scaling by Risto Kankkunen. | ||
43 | * This should give smoother volume response than just | ||
44 | * a plain multiplication. | ||
45 | */ | ||
46 | |||
47 | int e; | ||
48 | |||
49 | if (vol < 0) | ||
50 | vol = 0; | ||
51 | if (vol > 100) | ||
52 | vol = 100; | ||
53 | vol = (31 * vol + 50) / 100; | ||
54 | e = 0; | ||
55 | if (vol) | ||
56 | { | ||
57 | while (vol < 16) | ||
58 | { | ||
59 | vol <<= 1; | ||
60 | e--; | ||
61 | } | ||
62 | vol -= 16; | ||
63 | e += 7; | ||
64 | } | ||
65 | return ((e << 4) + vol); | ||
66 | } | ||
67 | |||
68 | static void write_mix(int dev, int chn, int vol) | ||
69 | { | ||
70 | int *selector; | ||
71 | unsigned long flags; | ||
72 | int ctrl_addr = dev << 3; | ||
73 | int attn_addr = dev << 3; | ||
74 | |||
75 | vol = scale_vol(vol); | ||
76 | |||
77 | if (chn == CHN_LEFT) | ||
78 | { | ||
79 | selector = left_fix; | ||
80 | ctrl_addr |= 0x00; | ||
81 | attn_addr |= 0x02; | ||
82 | } | ||
83 | else | ||
84 | { | ||
85 | selector = right_fix; | ||
86 | ctrl_addr |= 0x01; | ||
87 | attn_addr |= 0x03; | ||
88 | } | ||
89 | |||
90 | spin_lock_irqsave(&gus_lock, flags); | ||
91 | outb((ctrl_addr), u_MixSelect); | ||
92 | outb((selector[dev]), u_MixData); | ||
93 | outb((attn_addr), u_MixSelect); | ||
94 | outb(((unsigned char) vol), u_MixData); | ||
95 | spin_unlock_irqrestore(&gus_lock,flags); | ||
96 | } | ||
97 | |||
98 | static int set_volumes(int dev, int vol) | ||
99 | { | ||
100 | int left = vol & 0x00ff; | ||
101 | int right = (vol >> 8) & 0x00ff; | ||
102 | |||
103 | if (left < 0) | ||
104 | left = 0; | ||
105 | if (left > 100) | ||
106 | left = 100; | ||
107 | if (right < 0) | ||
108 | right = 0; | ||
109 | if (right > 100) | ||
110 | right = 100; | ||
111 | |||
112 | write_mix(dev, CHN_LEFT, left); | ||
113 | write_mix(dev, CHN_RIGHT, right); | ||
114 | |||
115 | vol = left + (right << 8); | ||
116 | volumes[dev] = vol; | ||
117 | return vol; | ||
118 | } | ||
119 | |||
120 | static int ics2101_mixer_ioctl(int dev, unsigned int cmd, void __user *arg) | ||
121 | { | ||
122 | int val; | ||
123 | |||
124 | if (((cmd >> 8) & 0xff) == 'M') { | ||
125 | if (_SIOC_DIR(cmd) & _SIOC_WRITE) { | ||
126 | |||
127 | if (get_user(val, (int __user *)arg)) | ||
128 | return -EFAULT; | ||
129 | switch (cmd & 0xff) { | ||
130 | case SOUND_MIXER_RECSRC: | ||
131 | return gus_default_mixer_ioctl(dev, cmd, arg); | ||
132 | |||
133 | case SOUND_MIXER_MIC: | ||
134 | val = set_volumes(DEV_MIC, val); | ||
135 | break; | ||
136 | |||
137 | case SOUND_MIXER_CD: | ||
138 | val = set_volumes(DEV_CD, val); | ||
139 | break; | ||
140 | |||
141 | case SOUND_MIXER_LINE: | ||
142 | val = set_volumes(DEV_LINE, val); | ||
143 | break; | ||
144 | |||
145 | case SOUND_MIXER_SYNTH: | ||
146 | val = set_volumes(DEV_GF1, val); | ||
147 | break; | ||
148 | |||
149 | case SOUND_MIXER_VOLUME: | ||
150 | val = set_volumes(DEV_VOL, val); | ||
151 | break; | ||
152 | |||
153 | default: | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | return put_user(val, (int __user *)arg); | ||
157 | } else { | ||
158 | switch (cmd & 0xff) { | ||
159 | /* | ||
160 | * Return parameters | ||
161 | */ | ||
162 | case SOUND_MIXER_RECSRC: | ||
163 | return gus_default_mixer_ioctl(dev, cmd, arg); | ||
164 | |||
165 | case SOUND_MIXER_DEVMASK: | ||
166 | val = MIX_DEVS; | ||
167 | break; | ||
168 | |||
169 | case SOUND_MIXER_STEREODEVS: | ||
170 | val = SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_SYNTH | SOUND_MASK_VOLUME | SOUND_MASK_MIC; | ||
171 | break; | ||
172 | |||
173 | case SOUND_MIXER_RECMASK: | ||
174 | val = SOUND_MASK_MIC | SOUND_MASK_LINE; | ||
175 | break; | ||
176 | |||
177 | case SOUND_MIXER_CAPS: | ||
178 | val = 0; | ||
179 | break; | ||
180 | |||
181 | case SOUND_MIXER_MIC: | ||
182 | val = volumes[DEV_MIC]; | ||
183 | break; | ||
184 | |||
185 | case SOUND_MIXER_LINE: | ||
186 | val = volumes[DEV_LINE]; | ||
187 | break; | ||
188 | |||
189 | case SOUND_MIXER_CD: | ||
190 | val = volumes[DEV_CD]; | ||
191 | break; | ||
192 | |||
193 | case SOUND_MIXER_VOLUME: | ||
194 | val = volumes[DEV_VOL]; | ||
195 | break; | ||
196 | |||
197 | case SOUND_MIXER_SYNTH: | ||
198 | val = volumes[DEV_GF1]; | ||
199 | break; | ||
200 | |||
201 | default: | ||
202 | return -EINVAL; | ||
203 | } | ||
204 | return put_user(val, (int __user *)arg); | ||
205 | } | ||
206 | } | ||
207 | return -EINVAL; | ||
208 | } | ||
209 | |||
210 | static struct mixer_operations ics2101_mixer_operations = | ||
211 | { | ||
212 | .owner = THIS_MODULE, | ||
213 | .id = "ICS2101", | ||
214 | .name = "ICS2101 Multimedia Mixer", | ||
215 | .ioctl = ics2101_mixer_ioctl | ||
216 | }; | ||
217 | |||
218 | int __init ics2101_mixer_init(void) | ||
219 | { | ||
220 | int i; | ||
221 | int n; | ||
222 | |||
223 | if ((n = sound_alloc_mixerdev()) != -1) | ||
224 | { | ||
225 | mixer_devs[n] = &ics2101_mixer_operations; | ||
226 | |||
227 | /* | ||
228 | * Some GUS v3.7 cards had some channels flipped. Disable | ||
229 | * the flipping feature if the model id is other than 5. | ||
230 | */ | ||
231 | |||
232 | if (inb(u_MixSelect) != 5) | ||
233 | { | ||
234 | for (i = 0; i < ICS_MIXDEVS; i++) | ||
235 | left_fix[i] = 1; | ||
236 | for (i = 0; i < ICS_MIXDEVS; i++) | ||
237 | right_fix[i] = 2; | ||
238 | } | ||
239 | set_volumes(DEV_GF1, 0x5a5a); | ||
240 | set_volumes(DEV_CD, 0x5a5a); | ||
241 | set_volumes(DEV_MIC, 0x0000); | ||
242 | set_volumes(DEV_LINE, 0x5a5a); | ||
243 | set_volumes(DEV_VOL, 0x5a5a); | ||
244 | set_volumes(DEV_UNUSED, 0x0000); | ||
245 | } | ||
246 | return n; | ||
247 | } | ||
diff --git a/sound/oss/iwmem.h b/sound/oss/iwmem.h deleted file mode 100644 index 48d333c7302b..000000000000 --- a/sound/oss/iwmem.h +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/iwmem.h | ||
3 | * | ||
4 | * DRAM size encoding table for AMD Interwave chip. | ||
5 | */ | ||
6 | /* | ||
7 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
8 | * | ||
9 | * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
10 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
11 | * for more info. | ||
12 | * | ||
13 | * Changes: | ||
14 | * Bartlomiej Zolnierkiewicz : added __initdata to mem_decode | ||
15 | */ | ||
16 | |||
17 | |||
18 | #define K 1024 | ||
19 | #define M (1024*K) | ||
20 | static int mem_decode[][4] __initdata = | ||
21 | { | ||
22 | /* Bank0 Bank1 Bank2 Bank3 Encoding bits */ | ||
23 | {256*K, 0, 0, 0}, /* 0 */ | ||
24 | {256*K, 256*K, 0, 0}, /* 1 */ | ||
25 | {256*K, 256*K, 256*K, 256*K}, /* 2 */ | ||
26 | {256*K, 1*M, 0, 0}, /* 3 */ | ||
27 | {256*K, 1*M, 1*M, 1*M}, /* 4 */ | ||
28 | {256*K, 256*K, 1*M, 0}, /* 5 */ | ||
29 | {256*K, 256*K, 1*M, 1*M}, /* 6 */ | ||
30 | {1*M, 0, 0, 0}, /* 7 */ | ||
31 | {1*M, 1*M, 0, 0}, /* 8 */ | ||
32 | {1*M, 1*M, 1*M, 1*M}, /* 9 */ | ||
33 | {4*M, 0, 0, 0}, /* 10 */ | ||
34 | {4*M, 4*M, 0, 0}, /* 11 */ | ||
35 | {4*M, 4*M, 4*M, 4*M} /* 12 */ | ||
36 | }; | ||
diff --git a/sound/oss/mad16.c b/sound/oss/mad16.c deleted file mode 100644 index aa3c50db66c4..000000000000 --- a/sound/oss/mad16.c +++ /dev/null | |||
@@ -1,1113 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
3 | * | ||
4 | * mad16.c | ||
5 | * | ||
6 | * Initialization code for OPTi MAD16 compatible audio chips. Including | ||
7 | * | ||
8 | * OPTi 82C928 MAD16 (replaced by C929) | ||
9 | * OAK OTI-601D Mozart | ||
10 | * OAK OTI-605 Mozart (later version with MPU401 Midi) | ||
11 | * OPTi 82C929 MAD16 Pro | ||
12 | * OPTi 82C930 | ||
13 | * OPTi 82C924 | ||
14 | * | ||
15 | * These audio interface chips don't produce sound themselves. They just | ||
16 | * connect some other components (OPL-[234] and a WSS compatible codec) | ||
17 | * to the PC bus and perform I/O, DMA and IRQ address decoding. There is | ||
18 | * also a UART for the MPU-401 mode (not 82C928/Mozart). | ||
19 | * The Mozart chip appears to be compatible with the 82C928, although later | ||
20 | * issues of the card, using the OTI-605 chip, have an MPU-401 compatible Midi | ||
21 | * port. This port is configured differently to that of the OPTi audio chips. | ||
22 | * | ||
23 | * Changes | ||
24 | * | ||
25 | * Alan Cox Clean up, added module selections. | ||
26 | * | ||
27 | * A. Wik Added support for Opti924 PnP. | ||
28 | * Improved debugging support. 16-May-1998 | ||
29 | * Fixed bug. 16-Jun-1998 | ||
30 | * | ||
31 | * Torsten Duwe Made Opti924 PnP support non-destructive | ||
32 | * 23-Dec-1998 | ||
33 | * | ||
34 | * Paul Grayson Added support for Midi on later Mozart cards. | ||
35 | * 25-Nov-1999 | ||
36 | * Christoph Hellwig Adapted to module_init/module_exit. | ||
37 | * Arnaldo C. de Melo got rid of attach_uart401 21-Sep-2000 | ||
38 | * | ||
39 | * Pavel Rabel Clean up Nov-2000 | ||
40 | */ | ||
41 | |||
42 | #include <linux/config.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <linux/module.h> | ||
45 | #include <linux/gameport.h> | ||
46 | #include <linux/spinlock.h> | ||
47 | #include "sound_config.h" | ||
48 | |||
49 | #include "ad1848.h" | ||
50 | #include "sb.h" | ||
51 | #include "mpu401.h" | ||
52 | |||
53 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) | ||
54 | #define SUPPORT_JOYSTICK 1 | ||
55 | #endif | ||
56 | |||
57 | static int mad16_conf; | ||
58 | static int mad16_cdsel; | ||
59 | static DEFINE_SPINLOCK(lock); | ||
60 | |||
61 | #define C928 1 | ||
62 | #define MOZART 2 | ||
63 | #define C929 3 | ||
64 | #define C930 4 | ||
65 | #define C924 5 | ||
66 | |||
67 | /* | ||
68 | * Registers | ||
69 | * | ||
70 | * The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations). | ||
71 | * All ports are inactive by default. They can be activated by | ||
72 | * writing 0xE2 or 0xE3 to the password register. The password is valid | ||
73 | * only until the next I/O read or write. | ||
74 | * | ||
75 | * 82C930 uses 0xE4 as the password and indirect addressing to access | ||
76 | * the config registers. | ||
77 | */ | ||
78 | |||
79 | #define MC0_PORT 0xf8c /* Dummy port */ | ||
80 | #define MC1_PORT 0xf8d /* SB address, CD-ROM interface type, joystick */ | ||
81 | #define MC2_PORT 0xf8e /* CD-ROM address, IRQ, DMA, plus OPL4 bit */ | ||
82 | #define MC3_PORT 0xf8f | ||
83 | #define PASSWD_REG 0xf8f | ||
84 | #define MC4_PORT 0xf90 | ||
85 | #define MC5_PORT 0xf91 | ||
86 | #define MC6_PORT 0xf92 | ||
87 | #define MC7_PORT 0xf93 | ||
88 | #define MC8_PORT 0xf94 | ||
89 | #define MC9_PORT 0xf95 | ||
90 | #define MC10_PORT 0xf96 | ||
91 | #define MC11_PORT 0xf97 | ||
92 | #define MC12_PORT 0xf98 | ||
93 | |||
94 | static int board_type = C928; | ||
95 | |||
96 | static int *mad16_osp; | ||
97 | static int c931_detected; /* minor differences from C930 */ | ||
98 | static char c924pnp; /* " " " C924 */ | ||
99 | static int debug; /* debugging output */ | ||
100 | |||
101 | #ifdef DDB | ||
102 | #undef DDB | ||
103 | #endif | ||
104 | #define DDB(x) do {if (debug) x;} while (0) | ||
105 | |||
106 | static unsigned char mad_read(int port) | ||
107 | { | ||
108 | unsigned long flags; | ||
109 | unsigned char tmp; | ||
110 | |||
111 | spin_lock_irqsave(&lock,flags); | ||
112 | |||
113 | switch (board_type) /* Output password */ | ||
114 | { | ||
115 | case C928: | ||
116 | case MOZART: | ||
117 | outb((0xE2), PASSWD_REG); | ||
118 | break; | ||
119 | |||
120 | case C929: | ||
121 | outb((0xE3), PASSWD_REG); | ||
122 | break; | ||
123 | |||
124 | case C930: | ||
125 | /* outb(( 0xE4), PASSWD_REG); */ | ||
126 | break; | ||
127 | |||
128 | case C924: | ||
129 | /* the c924 has its ports relocated by -128 if | ||
130 | PnP is enabled -aw */ | ||
131 | if (!c924pnp) | ||
132 | outb((0xE5), PASSWD_REG); else | ||
133 | outb((0xE5), PASSWD_REG - 0x80); | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | if (board_type == C930) | ||
138 | { | ||
139 | outb((port - MC0_PORT), 0xe0e); /* Write to index reg */ | ||
140 | tmp = inb(0xe0f); /* Read from data reg */ | ||
141 | } | ||
142 | else | ||
143 | if (!c924pnp) | ||
144 | tmp = inb(port); else | ||
145 | tmp = inb(port-0x80); | ||
146 | spin_unlock_irqrestore(&lock,flags); | ||
147 | |||
148 | return tmp; | ||
149 | } | ||
150 | |||
151 | static void mad_write(int port, int value) | ||
152 | { | ||
153 | unsigned long flags; | ||
154 | |||
155 | spin_lock_irqsave(&lock,flags); | ||
156 | |||
157 | switch (board_type) /* Output password */ | ||
158 | { | ||
159 | case C928: | ||
160 | case MOZART: | ||
161 | outb((0xE2), PASSWD_REG); | ||
162 | break; | ||
163 | |||
164 | case C929: | ||
165 | outb((0xE3), PASSWD_REG); | ||
166 | break; | ||
167 | |||
168 | case C930: | ||
169 | /* outb(( 0xE4), PASSWD_REG); */ | ||
170 | break; | ||
171 | |||
172 | case C924: | ||
173 | if (!c924pnp) | ||
174 | outb((0xE5), PASSWD_REG); else | ||
175 | outb((0xE5), PASSWD_REG - 0x80); | ||
176 | break; | ||
177 | } | ||
178 | |||
179 | if (board_type == C930) | ||
180 | { | ||
181 | outb((port - MC0_PORT), 0xe0e); /* Write to index reg */ | ||
182 | outb(((unsigned char) (value & 0xff)), 0xe0f); | ||
183 | } | ||
184 | else | ||
185 | if (!c924pnp) | ||
186 | outb(((unsigned char) (value & 0xff)), port); else | ||
187 | outb(((unsigned char) (value & 0xff)), port-0x80); | ||
188 | spin_unlock_irqrestore(&lock,flags); | ||
189 | } | ||
190 | |||
191 | static int __init detect_c930(void) | ||
192 | { | ||
193 | unsigned char tmp = mad_read(MC1_PORT); | ||
194 | |||
195 | if ((tmp & 0x06) != 0x06) | ||
196 | { | ||
197 | DDB(printk("Wrong C930 signature (%x)\n", tmp)); | ||
198 | /* return 0; */ | ||
199 | } | ||
200 | mad_write(MC1_PORT, 0); | ||
201 | |||
202 | if (mad_read(MC1_PORT) != 0x06) | ||
203 | { | ||
204 | DDB(printk("Wrong C930 signature2 (%x)\n", tmp)); | ||
205 | /* return 0; */ | ||
206 | } | ||
207 | mad_write(MC1_PORT, tmp); /* Restore bits */ | ||
208 | |||
209 | mad_write(MC7_PORT, 0); | ||
210 | if ((tmp = mad_read(MC7_PORT)) != 0) | ||
211 | { | ||
212 | DDB(printk("MC7 not writable (%x)\n", tmp)); | ||
213 | return 0; | ||
214 | } | ||
215 | mad_write(MC7_PORT, 0xcb); | ||
216 | if ((tmp = mad_read(MC7_PORT)) != 0xcb) | ||
217 | { | ||
218 | DDB(printk("MC7 not writable2 (%x)\n", tmp)); | ||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | tmp = mad_read(MC0_PORT+18); | ||
223 | if (tmp == 0xff || tmp == 0x00) | ||
224 | return 1; | ||
225 | /* We probably have a C931 */ | ||
226 | DDB(printk("Detected C931 config=0x%02x\n", tmp)); | ||
227 | c931_detected = 1; | ||
228 | |||
229 | /* | ||
230 | * We cannot configure the chip if it is in PnP mode. | ||
231 | * If we have a CSN assigned (bit 8 in MC13) we first try | ||
232 | * a software reset, then a software power off, finally | ||
233 | * Clearing PnP mode. The last option is not | ||
234 | * Bit 8 in MC13 | ||
235 | */ | ||
236 | if ((mad_read(MC0_PORT+13) & 0x80) == 0) | ||
237 | return 1; | ||
238 | |||
239 | /* Software reset */ | ||
240 | mad_write(MC9_PORT, 0x02); | ||
241 | mad_write(MC9_PORT, 0x00); | ||
242 | |||
243 | if ((mad_read(MC0_PORT+13) & 0x80) == 0) | ||
244 | return 1; | ||
245 | |||
246 | /* Power off, and on again */ | ||
247 | mad_write(MC9_PORT, 0xc2); | ||
248 | mad_write(MC9_PORT, 0xc0); | ||
249 | |||
250 | if ((mad_read(MC0_PORT+13) & 0x80) == 0) | ||
251 | return 1; | ||
252 | |||
253 | #if 0 | ||
254 | /* Force off PnP mode. This is not recommended because | ||
255 | * the PnP bios will not recognize the chip on the next | ||
256 | * warm boot and may assignd different resources to other | ||
257 | * PnP/PCI cards. | ||
258 | */ | ||
259 | mad_write(MC0_PORT+17, 0x04); | ||
260 | #endif | ||
261 | return 1; | ||
262 | } | ||
263 | |||
264 | static int __init detect_mad16(void) | ||
265 | { | ||
266 | unsigned char tmp, tmp2, bit; | ||
267 | int i, port; | ||
268 | |||
269 | /* | ||
270 | * Check that reading a register doesn't return bus float (0xff) | ||
271 | * when the card is accessed using password. This may fail in case | ||
272 | * the card is in low power mode. Normally at least the power saving | ||
273 | * mode bit should be 0. | ||
274 | */ | ||
275 | |||
276 | if ((tmp = mad_read(MC1_PORT)) == 0xff) | ||
277 | { | ||
278 | DDB(printk("MC1_PORT returned 0xff\n")); | ||
279 | return 0; | ||
280 | } | ||
281 | for (i = 0xf8d; i <= 0xf98; i++) | ||
282 | if (!c924pnp) | ||
283 | DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i))); | ||
284 | else | ||
285 | DDB(printk("Port %0x (init value) = %0x\n", i-0x80, mad_read(i))); | ||
286 | |||
287 | if (board_type == C930) | ||
288 | return detect_c930(); | ||
289 | |||
290 | /* | ||
291 | * Now check that the gate is closed on first I/O after writing | ||
292 | * the password. (This is how a MAD16 compatible card works). | ||
293 | */ | ||
294 | |||
295 | if ((tmp2 = inb(MC1_PORT)) == tmp) /* It didn't close */ | ||
296 | { | ||
297 | DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2)); | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | bit = (c924pnp) ? 0x20 : 0x80; | ||
302 | port = (c924pnp) ? MC2_PORT : MC1_PORT; | ||
303 | |||
304 | tmp = mad_read(port); | ||
305 | mad_write(port, tmp ^ bit); /* Toggle a bit */ | ||
306 | if ((tmp2 = mad_read(port)) != (tmp ^ bit)) /* Compare the bit */ | ||
307 | { | ||
308 | mad_write(port, tmp); /* Restore */ | ||
309 | DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2)); | ||
310 | return 0; | ||
311 | } | ||
312 | mad_write(port, tmp); /* Restore */ | ||
313 | return 1; /* Bingo */ | ||
314 | } | ||
315 | |||
316 | static int __init wss_init(struct address_info *hw_config) | ||
317 | { | ||
318 | /* | ||
319 | * Check if the IO port returns valid signature. The original MS Sound | ||
320 | * system returns 0x04 while some cards (AudioTrix Pro for example) | ||
321 | * return 0x00. | ||
322 | */ | ||
323 | |||
324 | if ((inb(hw_config->io_base + 3) & 0x3f) != 0x04 && | ||
325 | (inb(hw_config->io_base + 3) & 0x3f) != 0x00) | ||
326 | { | ||
327 | DDB(printk("No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, inb(hw_config->io_base + 3))); | ||
328 | return 0; | ||
329 | } | ||
330 | /* | ||
331 | * Check that DMA0 is not in use with a 8 bit board. | ||
332 | */ | ||
333 | if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80) | ||
334 | { | ||
335 | printk("MSS: Can't use DMA0 with a 8 bit card/slot\n"); | ||
336 | return 0; | ||
337 | } | ||
338 | if (hw_config->irq > 9 && inb(hw_config->io_base + 3) & 0x80) | ||
339 | printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq); | ||
340 | return 1; | ||
341 | } | ||
342 | |||
343 | static void __init init_c930(struct address_info *hw_config, int base) | ||
344 | { | ||
345 | unsigned char cfg = 0; | ||
346 | |||
347 | cfg |= (0x0f & mad16_conf); | ||
348 | |||
349 | if(c931_detected) | ||
350 | { | ||
351 | /* Bit 0 has reversd meaning. Bits 1 and 2 sese | ||
352 | reversed on write. | ||
353 | Support only IDE cdrom. IDE port programmed | ||
354 | somewhere else. */ | ||
355 | cfg = (cfg & 0x09) ^ 0x07; | ||
356 | } | ||
357 | cfg |= base << 4; | ||
358 | mad_write(MC1_PORT, cfg); | ||
359 | |||
360 | /* MC2 is CD configuration. Don't touch it. */ | ||
361 | |||
362 | mad_write(MC3_PORT, 0); /* Disable SB mode IRQ and DMA */ | ||
363 | |||
364 | /* bit 2 of MC4 reverses it's meaning between the C930 | ||
365 | and the C931. */ | ||
366 | cfg = c931_detected ? 0x04 : 0x00; | ||
367 | |||
368 | if(mad16_cdsel & 0x20) | ||
369 | mad_write(MC4_PORT, 0x62|cfg); /* opl4 */ | ||
370 | else | ||
371 | mad_write(MC4_PORT, 0x52|cfg); /* opl3 */ | ||
372 | |||
373 | mad_write(MC5_PORT, 0x3C); /* Init it into mode2 */ | ||
374 | mad_write(MC6_PORT, 0x02); /* Enable WSS, Disable MPU and SB */ | ||
375 | mad_write(MC7_PORT, 0xCB); | ||
376 | mad_write(MC10_PORT, 0x11); | ||
377 | } | ||
378 | |||
379 | static int __init chip_detect(void) | ||
380 | { | ||
381 | int i; | ||
382 | |||
383 | /* | ||
384 | * Then try to detect with the old password | ||
385 | */ | ||
386 | board_type = C924; | ||
387 | |||
388 | DDB(printk("Detect using password = 0xE5\n")); | ||
389 | |||
390 | if (detect_mad16()) { | ||
391 | return 1; | ||
392 | } | ||
393 | |||
394 | board_type = C928; | ||
395 | |||
396 | DDB(printk("Detect using password = 0xE2\n")); | ||
397 | |||
398 | if (detect_mad16()) | ||
399 | { | ||
400 | unsigned char model; | ||
401 | |||
402 | if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) { | ||
403 | DDB(printk("mad16.c: Mozart detected\n")); | ||
404 | board_type = MOZART; | ||
405 | } else { | ||
406 | DDB(printk("mad16.c: 82C928 detected???\n")); | ||
407 | board_type = C928; | ||
408 | } | ||
409 | return 1; | ||
410 | } | ||
411 | |||
412 | board_type = C929; | ||
413 | |||
414 | DDB(printk("Detect using password = 0xE3\n")); | ||
415 | |||
416 | if (detect_mad16()) | ||
417 | { | ||
418 | DDB(printk("mad16.c: 82C929 detected\n")); | ||
419 | return 1; | ||
420 | } | ||
421 | |||
422 | if (inb(PASSWD_REG) != 0xff) | ||
423 | return 0; | ||
424 | |||
425 | /* | ||
426 | * First relocate MC# registers to 0xe0e/0xe0f, disable password | ||
427 | */ | ||
428 | |||
429 | outb((0xE4), PASSWD_REG); | ||
430 | outb((0x80), PASSWD_REG); | ||
431 | |||
432 | board_type = C930; | ||
433 | |||
434 | DDB(printk("Detect using password = 0xE4\n")); | ||
435 | |||
436 | for (i = 0xf8d; i <= 0xf93; i++) | ||
437 | DDB(printk("port %03x = %02x\n", i, mad_read(i))); | ||
438 | |||
439 | if(detect_mad16()) { | ||
440 | DDB(printk("mad16.c: 82C930 detected\n")); | ||
441 | return 1; | ||
442 | } | ||
443 | |||
444 | /* The C931 has the password reg at F8D */ | ||
445 | outb((0xE4), 0xF8D); | ||
446 | outb((0x80), 0xF8D); | ||
447 | DDB(printk("Detect using password = 0xE4 for C931\n")); | ||
448 | |||
449 | if (detect_mad16()) { | ||
450 | return 1; | ||
451 | } | ||
452 | |||
453 | board_type = C924; | ||
454 | c924pnp++; | ||
455 | DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n")); | ||
456 | if (detect_mad16()) { | ||
457 | DDB(printk("mad16.c: 82C924 PnP detected\n")); | ||
458 | return 1; | ||
459 | } | ||
460 | |||
461 | c924pnp=0; | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static int __init probe_mad16(struct address_info *hw_config) | ||
467 | { | ||
468 | int i; | ||
469 | unsigned char tmp; | ||
470 | unsigned char cs4231_mode = 0; | ||
471 | |||
472 | int ad_flags = 0; | ||
473 | |||
474 | signed char bits; | ||
475 | |||
476 | static char dma_bits[4] = { | ||
477 | 1, 2, 0, 3 | ||
478 | }; | ||
479 | |||
480 | int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3; | ||
481 | int dma = hw_config->dma, dma2 = hw_config->dma2; | ||
482 | unsigned char dma2_bit = 0; | ||
483 | int base; | ||
484 | struct resource *ports; | ||
485 | |||
486 | mad16_osp = hw_config->osp; | ||
487 | |||
488 | switch (hw_config->io_base) { | ||
489 | case 0x530: | ||
490 | base = 0; | ||
491 | break; | ||
492 | case 0xe80: | ||
493 | base = 1; | ||
494 | break; | ||
495 | case 0xf40: | ||
496 | base = 2; | ||
497 | break; | ||
498 | case 0x604: | ||
499 | base = 3; | ||
500 | break; | ||
501 | default: | ||
502 | printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base); | ||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | if (dma != 0 && dma != 1 && dma != 3) { | ||
507 | printk(KERN_ERR "MSS: Bad DMA %d\n", dma); | ||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * Check that all ports return 0xff (bus float) when no password | ||
513 | * is written to the password register. | ||
514 | */ | ||
515 | |||
516 | DDB(printk("--- Detecting MAD16 / Mozart ---\n")); | ||
517 | if (!chip_detect()) | ||
518 | return 0; | ||
519 | |||
520 | switch (hw_config->irq) { | ||
521 | case 7: | ||
522 | bits = 8; | ||
523 | break; | ||
524 | case 9: | ||
525 | bits = 0x10; | ||
526 | break; | ||
527 | case 10: | ||
528 | bits = 0x18; | ||
529 | break; | ||
530 | case 12: | ||
531 | bits = 0x20; | ||
532 | break; | ||
533 | case 5: /* Also IRQ5 is possible on C930 */ | ||
534 | if (board_type == C930 || c924pnp) { | ||
535 | bits = 0x28; | ||
536 | break; | ||
537 | } | ||
538 | default: | ||
539 | printk(KERN_ERR "MAD16/Mozart: Bad IRQ %d\n", hw_config->irq); | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | ports = request_region(hw_config->io_base + 4, 4, "ad1848"); | ||
544 | if (!ports) { | ||
545 | printk(KERN_ERR "MSS: I/O port conflict\n"); | ||
546 | return 0; | ||
547 | } | ||
548 | if (!request_region(hw_config->io_base, 4, "mad16 WSS config")) { | ||
549 | release_region(hw_config->io_base + 4, 4); | ||
550 | printk(KERN_ERR "MSS: I/O port conflict\n"); | ||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | if (board_type == C930) { | ||
555 | init_c930(hw_config, base); | ||
556 | goto got_it; | ||
557 | } | ||
558 | |||
559 | for (i = 0xf8d; i <= 0xf93; i++) { | ||
560 | if (!c924pnp) | ||
561 | DDB(printk("port %03x = %02x\n", i, mad_read(i))); | ||
562 | else | ||
563 | DDB(printk("port %03x = %02x\n", i-0x80, mad_read(i))); | ||
564 | } | ||
565 | |||
566 | /* | ||
567 | * Set the WSS address | ||
568 | */ | ||
569 | |||
570 | tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80; /* Enable WSS, Disable SB */ | ||
571 | tmp |= base << 4; /* WSS port select bits */ | ||
572 | |||
573 | /* | ||
574 | * Set optional CD-ROM and joystick settings. | ||
575 | */ | ||
576 | |||
577 | tmp &= ~0x0f; | ||
578 | tmp |= (mad16_conf & 0x0f); /* CD-ROM and joystick bits */ | ||
579 | mad_write(MC1_PORT, tmp); | ||
580 | |||
581 | tmp = mad16_cdsel; | ||
582 | mad_write(MC2_PORT, tmp); | ||
583 | mad_write(MC3_PORT, 0xf0); /* Disable SB */ | ||
584 | |||
585 | if (board_type == C924) /* Specific C924 init values */ | ||
586 | { | ||
587 | mad_write(MC4_PORT, 0xA0); | ||
588 | mad_write(MC5_PORT, 0x05); | ||
589 | mad_write(MC6_PORT, 0x03); | ||
590 | } | ||
591 | if (!ad1848_detect(ports, &ad_flags, mad16_osp)) | ||
592 | goto fail; | ||
593 | |||
594 | if (ad_flags & (AD_F_CS4231 | AD_F_CS4248)) | ||
595 | cs4231_mode = 0x02; /* CS4248/CS4231 sync delay switch */ | ||
596 | |||
597 | if (board_type == C929) | ||
598 | { | ||
599 | mad_write(MC4_PORT, 0xa2); | ||
600 | mad_write(MC5_PORT, 0xA5 | cs4231_mode); | ||
601 | mad_write(MC6_PORT, 0x03); /* Disable MPU401 */ | ||
602 | } | ||
603 | else | ||
604 | { | ||
605 | mad_write(MC4_PORT, 0x02); | ||
606 | mad_write(MC5_PORT, 0x30 | cs4231_mode); | ||
607 | } | ||
608 | |||
609 | for (i = 0xf8d; i <= 0xf93; i++) { | ||
610 | if (!c924pnp) | ||
611 | DDB(printk("port %03x after init = %02x\n", i, mad_read(i))); | ||
612 | else | ||
613 | DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i))); | ||
614 | } | ||
615 | |||
616 | got_it: | ||
617 | ad_flags = 0; | ||
618 | if (!ad1848_detect(ports, &ad_flags, mad16_osp)) | ||
619 | goto fail; | ||
620 | |||
621 | if (!wss_init(hw_config)) | ||
622 | goto fail; | ||
623 | |||
624 | /* | ||
625 | * Set the IRQ and DMA addresses. | ||
626 | */ | ||
627 | |||
628 | outb((bits | 0x40), config_port); | ||
629 | if ((inb(version_port) & 0x40) == 0) | ||
630 | printk(KERN_ERR "[IRQ Conflict?]\n"); | ||
631 | |||
632 | /* | ||
633 | * Handle the capture DMA channel | ||
634 | */ | ||
635 | |||
636 | if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma) | ||
637 | { | ||
638 | if (!((dma == 0 && dma2 == 1) || | ||
639 | (dma == 1 && dma2 == 0) || | ||
640 | (dma == 3 && dma2 == 0))) | ||
641 | { /* Unsupported combination. Try to swap channels */ | ||
642 | int tmp = dma; | ||
643 | |||
644 | dma = dma2; | ||
645 | dma2 = tmp; | ||
646 | } | ||
647 | if ((dma == 0 && dma2 == 1) || (dma == 1 && dma2 == 0) || | ||
648 | (dma == 3 && dma2 == 0)) | ||
649 | { | ||
650 | dma2_bit = 0x04; /* Enable capture DMA */ | ||
651 | } | ||
652 | else | ||
653 | { | ||
654 | printk("MAD16: Invalid capture DMA\n"); | ||
655 | dma2 = dma; | ||
656 | } | ||
657 | } | ||
658 | else dma2 = dma; | ||
659 | |||
660 | outb((bits | dma_bits[dma] | dma2_bit), config_port); /* Write IRQ+DMA setup */ | ||
661 | |||
662 | hw_config->slots[0] = ad1848_init("mad16 WSS", ports, | ||
663 | hw_config->irq, | ||
664 | dma, | ||
665 | dma2, 0, | ||
666 | hw_config->osp, | ||
667 | THIS_MODULE); | ||
668 | return 1; | ||
669 | |||
670 | fail: | ||
671 | release_region(hw_config->io_base + 4, 4); | ||
672 | release_region(hw_config->io_base, 4); | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static int __init probe_mad16_mpu(struct address_info *hw_config) | ||
677 | { | ||
678 | unsigned char tmp; | ||
679 | |||
680 | if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */ | ||
681 | { | ||
682 | |||
683 | #ifdef CONFIG_MAD16_OLDCARD | ||
684 | |||
685 | tmp = mad_read(MC3_PORT); | ||
686 | |||
687 | /* | ||
688 | * MAD16 SB base is defined by the WSS base. It cannot be changed | ||
689 | * alone. | ||
690 | * Ignore configured I/O base. Use the active setting. | ||
691 | */ | ||
692 | |||
693 | if (mad_read(MC1_PORT) & 0x20) | ||
694 | hw_config->io_base = 0x240; | ||
695 | else | ||
696 | hw_config->io_base = 0x220; | ||
697 | |||
698 | switch (hw_config->irq) | ||
699 | { | ||
700 | case 5: | ||
701 | tmp = (tmp & 0x3f) | 0x80; | ||
702 | break; | ||
703 | case 7: | ||
704 | tmp = (tmp & 0x3f); | ||
705 | break; | ||
706 | case 11: | ||
707 | tmp = (tmp & 0x3f) | 0x40; | ||
708 | break; | ||
709 | default: | ||
710 | printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n"); | ||
711 | return 0; | ||
712 | } | ||
713 | |||
714 | mad_write(MC3_PORT, tmp | 0x04); | ||
715 | hw_config->driver_use_1 = SB_MIDI_ONLY; | ||
716 | if (!request_region(hw_config->io_base, 16, "soundblaster")) | ||
717 | return 0; | ||
718 | if (!sb_dsp_detect(hw_config, 0, 0, NULL)) { | ||
719 | release_region(hw_config->io_base, 16); | ||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | if (mad_read(MC1_PORT) & 0x20) | ||
724 | hw_config->io_base = 0x240; | ||
725 | else | ||
726 | hw_config->io_base = 0x220; | ||
727 | |||
728 | hw_config->name = "Mad16/Mozart"; | ||
729 | sb_dsp_init(hw_config, THIS_MODULE); | ||
730 | return 1; | ||
731 | #else | ||
732 | /* assuming all later Mozart cards are identified as | ||
733 | * either 82C928 or Mozart. If so, following code attempts | ||
734 | * to set MPU register. TODO - add probing | ||
735 | */ | ||
736 | |||
737 | tmp = mad_read(MC8_PORT); | ||
738 | |||
739 | switch (hw_config->irq) | ||
740 | { | ||
741 | case 5: | ||
742 | tmp |= 0x08; | ||
743 | break; | ||
744 | case 7: | ||
745 | tmp |= 0x10; | ||
746 | break; | ||
747 | case 9: | ||
748 | tmp |= 0x18; | ||
749 | break; | ||
750 | case 10: | ||
751 | tmp |= 0x20; | ||
752 | break; | ||
753 | case 11: | ||
754 | tmp |= 0x28; | ||
755 | break; | ||
756 | default: | ||
757 | printk(KERN_ERR "mad16/MOZART: invalid mpu_irq\n"); | ||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | switch (hw_config->io_base) | ||
762 | { | ||
763 | case 0x300: | ||
764 | tmp |= 0x01; | ||
765 | break; | ||
766 | case 0x310: | ||
767 | tmp |= 0x03; | ||
768 | break; | ||
769 | case 0x320: | ||
770 | tmp |= 0x05; | ||
771 | break; | ||
772 | case 0x330: | ||
773 | tmp |= 0x07; | ||
774 | break; | ||
775 | default: | ||
776 | printk(KERN_ERR "mad16/MOZART: invalid mpu_io\n"); | ||
777 | return 0; | ||
778 | } | ||
779 | |||
780 | mad_write(MC8_PORT, tmp); /* write MPU port parameters */ | ||
781 | goto probe_401; | ||
782 | #endif | ||
783 | } | ||
784 | tmp = mad_read(MC6_PORT) & 0x83; | ||
785 | tmp |= 0x80; /* MPU-401 enable */ | ||
786 | |||
787 | /* Set the MPU base bits */ | ||
788 | |||
789 | switch (hw_config->io_base) | ||
790 | { | ||
791 | case 0x300: | ||
792 | tmp |= 0x60; | ||
793 | break; | ||
794 | case 0x310: | ||
795 | tmp |= 0x40; | ||
796 | break; | ||
797 | case 0x320: | ||
798 | tmp |= 0x20; | ||
799 | break; | ||
800 | case 0x330: | ||
801 | tmp |= 0x00; | ||
802 | break; | ||
803 | default: | ||
804 | printk(KERN_ERR "MAD16: Invalid MIDI port 0x%x\n", hw_config->io_base); | ||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | /* Set the MPU IRQ bits */ | ||
809 | |||
810 | switch (hw_config->irq) | ||
811 | { | ||
812 | case 5: | ||
813 | tmp |= 0x10; | ||
814 | break; | ||
815 | case 7: | ||
816 | tmp |= 0x18; | ||
817 | break; | ||
818 | case 9: | ||
819 | tmp |= 0x00; | ||
820 | break; | ||
821 | case 10: | ||
822 | tmp |= 0x08; | ||
823 | break; | ||
824 | default: | ||
825 | printk(KERN_ERR "MAD16: Invalid MIDI IRQ %d\n", hw_config->irq); | ||
826 | break; | ||
827 | } | ||
828 | |||
829 | mad_write(MC6_PORT, tmp); /* Write MPU401 config */ | ||
830 | |||
831 | #ifndef CONFIG_MAD16_OLDCARD | ||
832 | probe_401: | ||
833 | #endif | ||
834 | hw_config->driver_use_1 = SB_MIDI_ONLY; | ||
835 | hw_config->name = "Mad16/Mozart"; | ||
836 | return probe_uart401(hw_config, THIS_MODULE); | ||
837 | } | ||
838 | |||
839 | static void __exit unload_mad16(struct address_info *hw_config) | ||
840 | { | ||
841 | ad1848_unload(hw_config->io_base + 4, | ||
842 | hw_config->irq, | ||
843 | hw_config->dma, | ||
844 | hw_config->dma2, 0); | ||
845 | release_region(hw_config->io_base, 4); | ||
846 | sound_unload_audiodev(hw_config->slots[0]); | ||
847 | } | ||
848 | |||
849 | static void __exit unload_mad16_mpu(struct address_info *hw_config) | ||
850 | { | ||
851 | #ifdef CONFIG_MAD16_OLDCARD | ||
852 | if (board_type < C929) /* Early chip. No MPU support. Just SB MIDI */ | ||
853 | { | ||
854 | sb_dsp_unload(hw_config, 0); | ||
855 | return; | ||
856 | } | ||
857 | #endif | ||
858 | |||
859 | unload_uart401(hw_config); | ||
860 | } | ||
861 | |||
862 | static struct address_info cfg; | ||
863 | static struct address_info cfg_mpu; | ||
864 | |||
865 | static int found_mpu; | ||
866 | |||
867 | static int __initdata mpu_io = 0; | ||
868 | static int __initdata mpu_irq = 0; | ||
869 | static int __initdata io = -1; | ||
870 | static int __initdata dma = -1; | ||
871 | static int __initdata dma16 = -1; /* Set this for modules that need it */ | ||
872 | static int __initdata irq = -1; | ||
873 | static int __initdata cdtype = 0; | ||
874 | static int __initdata cdirq = 0; | ||
875 | static int __initdata cdport = 0x340; | ||
876 | static int __initdata cddma = -1; | ||
877 | static int __initdata opl4 = 0; | ||
878 | static int __initdata joystick = 0; | ||
879 | |||
880 | module_param(mpu_io, int, 0); | ||
881 | module_param(mpu_irq, int, 0); | ||
882 | module_param(io, int, 0); | ||
883 | module_param(dma, int, 0); | ||
884 | module_param(dma16, int, 0); | ||
885 | module_param(irq, int, 0); | ||
886 | module_param(cdtype, int, 0); | ||
887 | module_param(cdirq, int, 0); | ||
888 | module_param(cdport, int, 0); | ||
889 | module_param(cddma, int, 0); | ||
890 | module_param(opl4, int, 0); | ||
891 | module_param(joystick, bool, 0); | ||
892 | module_param(debug, bool, 0644); | ||
893 | |||
894 | static int __initdata dma_map[2][8] = | ||
895 | { | ||
896 | {0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02}, | ||
897 | {0x03, -1, 0x01, 0x00, -1, -1, -1, -1} | ||
898 | }; | ||
899 | |||
900 | static int __initdata irq_map[16] = | ||
901 | { | ||
902 | 0x00, -1, -1, 0x0A, | ||
903 | -1, 0x04, -1, 0x08, | ||
904 | -1, 0x10, 0x14, 0x18, | ||
905 | -1, -1, -1, -1 | ||
906 | }; | ||
907 | |||
908 | #ifdef SUPPORT_JOYSTICK | ||
909 | |||
910 | static struct gameport *gameport; | ||
911 | |||
912 | static int __devinit mad16_register_gameport(int io_port) | ||
913 | { | ||
914 | if (!request_region(io_port, 1, "mad16 gameport")) { | ||
915 | printk(KERN_ERR "mad16: gameport address 0x%#x already in use\n", io_port); | ||
916 | return -EBUSY; | ||
917 | } | ||
918 | |||
919 | gameport = gameport_allocate_port(); | ||
920 | if (!gameport) { | ||
921 | printk(KERN_ERR "mad16: can not allocate memory for gameport\n"); | ||
922 | release_region(io_port, 1); | ||
923 | return -ENOMEM; | ||
924 | } | ||
925 | |||
926 | gameport_set_name(gameport, "MAD16 Gameport"); | ||
927 | gameport_set_phys(gameport, "isa%04x/gameport0", io_port); | ||
928 | gameport->io = io_port; | ||
929 | |||
930 | gameport_register_port(gameport); | ||
931 | |||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | static inline void mad16_unregister_gameport(void) | ||
936 | { | ||
937 | if (gameport) { | ||
938 | /* the gameport was initialized so we must free it up */ | ||
939 | gameport_unregister_port(gameport); | ||
940 | gameport = NULL; | ||
941 | release_region(0x201, 1); | ||
942 | } | ||
943 | } | ||
944 | #else | ||
945 | static inline int mad16_register_gameport(int io_port) { return -ENOSYS; } | ||
946 | static inline void mad16_unregister_gameport(void) { } | ||
947 | #endif | ||
948 | |||
949 | static int __devinit init_mad16(void) | ||
950 | { | ||
951 | int dmatype = 0; | ||
952 | |||
953 | printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n"); | ||
954 | |||
955 | printk(KERN_INFO "CDROM "); | ||
956 | switch (cdtype) | ||
957 | { | ||
958 | case 0x00: | ||
959 | printk("Disabled"); | ||
960 | cdirq = 0; | ||
961 | break; | ||
962 | case 0x02: | ||
963 | printk("Sony CDU31A"); | ||
964 | dmatype = 1; | ||
965 | if(cddma == -1) cddma = 3; | ||
966 | break; | ||
967 | case 0x04: | ||
968 | printk("Mitsumi"); | ||
969 | dmatype = 0; | ||
970 | if(cddma == -1) cddma = 5; | ||
971 | break; | ||
972 | case 0x06: | ||
973 | printk("Panasonic Lasermate"); | ||
974 | dmatype = 1; | ||
975 | if(cddma == -1) cddma = 3; | ||
976 | break; | ||
977 | case 0x08: | ||
978 | printk("Secondary IDE"); | ||
979 | dmatype = 0; | ||
980 | if(cddma == -1) cddma = 5; | ||
981 | break; | ||
982 | case 0x0A: | ||
983 | printk("Primary IDE"); | ||
984 | dmatype = 0; | ||
985 | if(cddma == -1) cddma = 5; | ||
986 | break; | ||
987 | default: | ||
988 | printk("\n"); | ||
989 | printk(KERN_ERR "Invalid CDROM type\n"); | ||
990 | return -EINVAL; | ||
991 | } | ||
992 | |||
993 | /* | ||
994 | * Build the config words | ||
995 | */ | ||
996 | |||
997 | mad16_conf = (joystick ^ 1) | cdtype; | ||
998 | mad16_cdsel = 0; | ||
999 | if (opl4) | ||
1000 | mad16_cdsel |= 0x20; | ||
1001 | |||
1002 | if(cdtype){ | ||
1003 | if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1) | ||
1004 | { | ||
1005 | printk("\n"); | ||
1006 | printk(KERN_ERR "Invalid CDROM DMA\n"); | ||
1007 | return -EINVAL; | ||
1008 | } | ||
1009 | if (cddma) | ||
1010 | printk(", DMA %d", cddma); | ||
1011 | else | ||
1012 | printk(", no DMA"); | ||
1013 | |||
1014 | if (!cdirq) | ||
1015 | printk(", no IRQ"); | ||
1016 | else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1) | ||
1017 | { | ||
1018 | printk(", invalid IRQ (disabling)"); | ||
1019 | cdirq = 0; | ||
1020 | } | ||
1021 | else printk(", IRQ %d", cdirq); | ||
1022 | |||
1023 | mad16_cdsel |= dma_map[dmatype][cddma]; | ||
1024 | |||
1025 | if (cdtype < 0x08) | ||
1026 | { | ||
1027 | switch (cdport) | ||
1028 | { | ||
1029 | case 0x340: | ||
1030 | mad16_cdsel |= 0x00; | ||
1031 | break; | ||
1032 | case 0x330: | ||
1033 | mad16_cdsel |= 0x40; | ||
1034 | break; | ||
1035 | case 0x360: | ||
1036 | mad16_cdsel |= 0x80; | ||
1037 | break; | ||
1038 | case 0x320: | ||
1039 | mad16_cdsel |= 0xC0; | ||
1040 | break; | ||
1041 | default: | ||
1042 | printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport); | ||
1043 | return -EINVAL; | ||
1044 | } | ||
1045 | } | ||
1046 | mad16_cdsel |= irq_map[cdirq]; | ||
1047 | } | ||
1048 | |||
1049 | printk(".\n"); | ||
1050 | |||
1051 | cfg.io_base = io; | ||
1052 | cfg.irq = irq; | ||
1053 | cfg.dma = dma; | ||
1054 | cfg.dma2 = dma16; | ||
1055 | |||
1056 | if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) { | ||
1057 | printk(KERN_ERR "I/O, DMA and irq are mandatory\n"); | ||
1058 | return -EINVAL; | ||
1059 | } | ||
1060 | |||
1061 | if (!request_region(MC0_PORT, 12, "mad16")) | ||
1062 | return -EBUSY; | ||
1063 | |||
1064 | if (!probe_mad16(&cfg)) { | ||
1065 | release_region(MC0_PORT, 12); | ||
1066 | return -ENODEV; | ||
1067 | } | ||
1068 | |||
1069 | cfg_mpu.io_base = mpu_io; | ||
1070 | cfg_mpu.irq = mpu_irq; | ||
1071 | |||
1072 | found_mpu = probe_mad16_mpu(&cfg_mpu); | ||
1073 | |||
1074 | if (joystick) | ||
1075 | mad16_register_gameport(0x201); | ||
1076 | |||
1077 | return 0; | ||
1078 | } | ||
1079 | |||
1080 | static void __exit cleanup_mad16(void) | ||
1081 | { | ||
1082 | if (found_mpu) | ||
1083 | unload_mad16_mpu(&cfg_mpu); | ||
1084 | mad16_unregister_gameport(); | ||
1085 | unload_mad16(&cfg); | ||
1086 | release_region(MC0_PORT, 12); | ||
1087 | } | ||
1088 | |||
1089 | module_init(init_mad16); | ||
1090 | module_exit(cleanup_mad16); | ||
1091 | |||
1092 | #ifndef MODULE | ||
1093 | static int __init setup_mad16(char *str) | ||
1094 | { | ||
1095 | /* io, irq */ | ||
1096 | int ints[8]; | ||
1097 | |||
1098 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
1099 | |||
1100 | io = ints[1]; | ||
1101 | irq = ints[2]; | ||
1102 | dma = ints[3]; | ||
1103 | dma16 = ints[4]; | ||
1104 | mpu_io = ints[5]; | ||
1105 | mpu_irq = ints[6]; | ||
1106 | joystick = ints[7]; | ||
1107 | |||
1108 | return 1; | ||
1109 | } | ||
1110 | |||
1111 | __setup("mad16=", setup_mad16); | ||
1112 | #endif | ||
1113 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c deleted file mode 100644 index 1d98d100d739..000000000000 --- a/sound/oss/maestro.c +++ /dev/null | |||
@@ -1,3686 +0,0 @@ | |||
1 | /***************************************************************************** | ||
2 | * | ||
3 | * ESS Maestro/Maestro-2/Maestro-2E driver for Linux 2.[23].x | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | * (c) Copyright 1999 Alan Cox <alan.cox@linux.org> | ||
20 | * | ||
21 | * Based heavily on SonicVibes.c: | ||
22 | * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch) | ||
23 | * | ||
24 | * Heavily modified by Zach Brown <zab@zabbo.net> based on lunch | ||
25 | * with ESS engineers. Many thanks to Howard Kim for providing | ||
26 | * contacts and hardware. Honorable mention goes to Eric | ||
27 | * Brombaugh for all sorts of things. Best regards to the | ||
28 | * proprietors of Hack Central for fine lodging. | ||
29 | * | ||
30 | * Supported devices: | ||
31 | * /dev/dsp0-3 standard /dev/dsp device, (mostly) OSS compatible | ||
32 | * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible | ||
33 | * | ||
34 | * Hardware Description | ||
35 | * | ||
36 | * A working Maestro setup contains the Maestro chip wired to a | ||
37 | * codec or 2. In the Maestro we have the APUs, the ASSP, and the | ||
38 | * Wavecache. The APUs can be though of as virtual audio routing | ||
39 | * channels. They can take data from a number of sources and perform | ||
40 | * basic encodings of the data. The wavecache is a storehouse for | ||
41 | * PCM data. Typically it deals with PCI and interracts with the | ||
42 | * APUs. The ASSP is a wacky DSP like device that ESS is loth | ||
43 | * to release docs on. Thankfully it isn't required on the Maestro | ||
44 | * until you start doing insane things like FM emulation and surround | ||
45 | * encoding. The codecs are almost always AC-97 compliant codecs, | ||
46 | * but it appears that early Maestros may have had PT101 (an ESS | ||
47 | * part?) wired to them. The only real difference in the Maestro | ||
48 | * families is external goop like docking capability, memory for | ||
49 | * the ASSP, and initialization differences. | ||
50 | * | ||
51 | * Driver Operation | ||
52 | * | ||
53 | * We only drive the APU/Wavecache as typical DACs and drive the | ||
54 | * mixers in the codecs. There are 64 APUs. We assign 6 to each | ||
55 | * /dev/dsp? device. 2 channels for output, and 4 channels for | ||
56 | * input. | ||
57 | * | ||
58 | * Each APU can do a number of things, but we only really use | ||
59 | * 3 basic functions. For playback we use them to convert PCM | ||
60 | * data fetched over PCI by the wavecahche into analog data that | ||
61 | * is handed to the codec. One APU for mono, and a pair for stereo. | ||
62 | * When in stereo, the combination of smarts in the APU and Wavecache | ||
63 | * decide which wavecache gets the left or right channel. | ||
64 | * | ||
65 | * For record we still use the old overly mono system. For each in | ||
66 | * coming channel the data comes in from the codec, through a 'input' | ||
67 | * APU, through another rate converter APU, and then into memory via | ||
68 | * the wavecache and PCI. If its stereo, we mash it back into LRLR in | ||
69 | * software. The pass between the 2 APUs is supposedly what requires us | ||
70 | * to have a 512 byte buffer sitting around in wavecache/memory. | ||
71 | * | ||
72 | * The wavecache makes our life even more fun. First off, it can | ||
73 | * only address the first 28 bits of PCI address space, making it | ||
74 | * useless on quite a few architectures. Secondly, its insane. | ||
75 | * It claims to fetch from 4 regions of PCI space, each 4 meg in length. | ||
76 | * But that doesn't really work. You can only use 1 region. So all our | ||
77 | * allocations have to be in 4meg of each other. Booo. Hiss. | ||
78 | * So we have a module parameter, dsps_order, that is the order of | ||
79 | * the number of dsps to provide. All their buffer space is allocated | ||
80 | * on open time. The sonicvibes OSS routines we inherited really want | ||
81 | * power of 2 buffers, so we have all those next to each other, then | ||
82 | * 512 byte regions for the recording wavecaches. This ends up | ||
83 | * wasting quite a bit of memory. The only fixes I can see would be | ||
84 | * getting a kernel allocator that could work in zones, or figuring out | ||
85 | * just how to coerce the WP into doing what we want. | ||
86 | * | ||
87 | * The indirection of the various registers means we have to spinlock | ||
88 | * nearly all register accesses. We have the main register indirection | ||
89 | * like the wave cache, maestro registers, etc. Then we have beasts | ||
90 | * like the APU interface that is indirect registers gotten at through | ||
91 | * the main maestro indirection. Ouch. We spinlock around the actual | ||
92 | * ports on a per card basis. This means spinlock activity at each IO | ||
93 | * operation, but the only IO operation clusters are in non critical | ||
94 | * paths and it makes the code far easier to follow. Interrupts are | ||
95 | * blocked while holding the locks because the int handler has to | ||
96 | * get at some of them :(. The mixer interface doesn't, however. | ||
97 | * We also have an OSS state lock that is thrown around in a few | ||
98 | * places. | ||
99 | * | ||
100 | * This driver has brute force APM suspend support. We catch suspend | ||
101 | * notifications and stop all work being done on the chip. Any people | ||
102 | * that try between this shutdown and the real suspend operation will | ||
103 | * be put to sleep. When we resume we restore our software state on | ||
104 | * the chip and wake up the people that were using it. The code thats | ||
105 | * being used now is quite dirty and assumes we're on a uni-processor | ||
106 | * machine. Much of it will need to be cleaned up for SMP ACPI or | ||
107 | * similar. | ||
108 | * | ||
109 | * We also pay attention to PCI power management now. The driver | ||
110 | * will power down units of the chip that it knows aren't needed. | ||
111 | * The WaveProcessor and company are only powered on when people | ||
112 | * have /dev/dsp*s open. On removal the driver will | ||
113 | * power down the maestro entirely. There could still be | ||
114 | * trouble with BIOSen that magically change power states | ||
115 | * themselves, but we'll see. | ||
116 | * | ||
117 | * History | ||
118 | * v0.15 - May 21 2001 - Marcus Meissner <mm@caldera.de> | ||
119 | * Ported to Linux 2.4 PCI API. Some clean ups, global devs list | ||
120 | * removed (now using pci device driver data). | ||
121 | * PM needs to be polished still. Bumped version. | ||
122 | * (still kind of v0.14) May 13 2001 - Ben Pfaff <pfaffben@msu.edu> | ||
123 | * Add support for 978 docking and basic hardware volume control | ||
124 | * (still kind of v0.14) Nov 23 - Alan Cox <alan@redhat.com> | ||
125 | * Add clocking= for people with seriously warped hardware | ||
126 | * (still v0.14) Nov 10 2000 - Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> | ||
127 | * add __init to maestro_ac97_init() and maestro_install() | ||
128 | * (still based on v0.14) Mar 29 2000 - Zach Brown <zab@redhat.com> | ||
129 | * move to 2.3 power management interface, which | ||
130 | * required hacking some suspend/resume/check paths | ||
131 | * make static compilation work | ||
132 | * v0.14 - Jan 28 2000 - Zach Brown <zab@redhat.com> | ||
133 | * add PCI power management through ACPI regs. | ||
134 | * we now shut down on machine reboot/halt | ||
135 | * leave scary PCI config items alone (isa stuff, mostly) | ||
136 | * enable 1921s, it seems only mine was broke. | ||
137 | * fix swapped left/right pcm dac. har har. | ||
138 | * up bob freq, increase buffers, fix pointers at underflow | ||
139 | * silly compilation problems | ||
140 | * v0.13 - Nov 18 1999 - Zach Brown <zab@redhat.com> | ||
141 | * fix nec Versas? man would that be cool. | ||
142 | * v0.12 - Nov 12 1999 - Zach Brown <zab@redhat.com> | ||
143 | * brown bag volume max fix.. | ||
144 | * v0.11 - Nov 11 1999 - Zach Brown <zab@redhat.com> | ||
145 | * use proper stereo apu decoding, mmap/write should work. | ||
146 | * make volume sliders more useful, tweak rate calculation. | ||
147 | * fix lame 8bit format reporting bug. duh. apm apu saving buglet also | ||
148 | * fix maestro 1 clock freq "bug", remove pt101 support | ||
149 | * v0.10 - Oct 28 1999 - Zach Brown <zab@redhat.com> | ||
150 | * aha, so, sometimes the WP writes a status word to offset 0 | ||
151 | * from one of the PCMBARs. rearrange allocation accordingly.. | ||
152 | * cheers again to Eric for being a good hacker in investigating this. | ||
153 | * Jeroen Hoogervorst submits 7500 fix out of nowhere. yay. :) | ||
154 | * v0.09 - Oct 23 1999 - Zach Brown <zab@redhat.com> | ||
155 | * added APM support. | ||
156 | * re-order something such that some 2Es now work. Magic! | ||
157 | * new codec reset routine. made some codecs come to life. | ||
158 | * fix clear_advance, sync some control with ESS. | ||
159 | * now write to all base regs to be paranoid. | ||
160 | * v0.08 - Oct 20 1999 - Zach Brown <zab@redhat.com> | ||
161 | * Fix initial buflen bug. I am so smart. also smp compiling.. | ||
162 | * I owe Eric yet another beer: fixed recmask, igain, | ||
163 | * muting, and adc sync consistency. Go Team. | ||
164 | * v0.07 - Oct 4 1999 - Zach Brown <zab@redhat.com> | ||
165 | * tweak adc/dac, formating, and stuff to allow full duplex | ||
166 | * allocate dsps memory at open() so we can fit in the wavecache window | ||
167 | * fix wavecache braindamage. again. no more scribbling? | ||
168 | * fix ess 1921 codec bug on some laptops. | ||
169 | * fix dumb pci scanning bug | ||
170 | * started 2.3 cleanup, redid spinlocks, little cleanups | ||
171 | * v0.06 - Sep 20 1999 - Zach Brown <zab@redhat.com> | ||
172 | * fix wavecache thinkos. limit to 1 /dev/dsp. | ||
173 | * eric is wearing his thinking toque this week. | ||
174 | * spotted apu mode bugs and gain ramping problem | ||
175 | * don't touch weird mixer regs, make recmask optional | ||
176 | * fixed igain inversion, defaults for mixers, clean up rec_start | ||
177 | * make mono recording work. | ||
178 | * report subsystem stuff, please send reports. | ||
179 | * littles: parallel out, amp now | ||
180 | * v0.05 - Sep 17 1999 - Zach Brown <zab@redhat.com> | ||
181 | * merged and fixed up Eric's initial recording code | ||
182 | * munged format handling to catch misuse, needs rewrite. | ||
183 | * revert ring bus init, fixup shared int, add pci busmaster setting | ||
184 | * fix mixer oss interface, fix mic mute and recmask | ||
185 | * mask off unsupported mixers, reset with all 1s, modularize defaults | ||
186 | * make sure bob is running while we need it | ||
187 | * got rid of device limit, initial minimal apm hooks | ||
188 | * pull out dead code/includes, only allow multimedia/audio maestros | ||
189 | * v0.04 - Sep 01 1999 - Zach Brown <zab@redhat.com> | ||
190 | * copied memory leak fix from sonicvibes driver | ||
191 | * different ac97 reset, play with 2.0 ac97, simplify ring bus setup | ||
192 | * bob freq code, region sanity, jitter sync fix; all from Eric | ||
193 | * | ||
194 | * TODO | ||
195 | * fix bob frequency | ||
196 | * endianness | ||
197 | * do smart things with ac97 2.0 bits. | ||
198 | * dual codecs | ||
199 | * leave 54->61 open | ||
200 | * | ||
201 | * it also would be fun to have a mode that would not use pci dma at all | ||
202 | * but would copy into the wavecache on board memory and use that | ||
203 | * on architectures that don't like the maestro's pci dma ickiness. | ||
204 | */ | ||
205 | |||
206 | /*****************************************************************************/ | ||
207 | |||
208 | #include <linux/module.h> | ||
209 | #include <linux/sched.h> | ||
210 | #include <linux/smp_lock.h> | ||
211 | #include <linux/string.h> | ||
212 | #include <linux/ctype.h> | ||
213 | #include <linux/ioport.h> | ||
214 | #include <linux/delay.h> | ||
215 | #include <linux/sound.h> | ||
216 | #include <linux/slab.h> | ||
217 | #include <linux/soundcard.h> | ||
218 | #include <linux/pci.h> | ||
219 | #include <linux/spinlock.h> | ||
220 | #include <linux/init.h> | ||
221 | #include <linux/interrupt.h> | ||
222 | #include <linux/poll.h> | ||
223 | #include <linux/reboot.h> | ||
224 | #include <linux/bitops.h> | ||
225 | #include <linux/wait.h> | ||
226 | #include <linux/mutex.h> | ||
227 | |||
228 | |||
229 | #include <asm/current.h> | ||
230 | #include <asm/dma.h> | ||
231 | #include <asm/io.h> | ||
232 | #include <asm/page.h> | ||
233 | #include <asm/uaccess.h> | ||
234 | |||
235 | #include "maestro.h" | ||
236 | |||
237 | static struct pci_driver maestro_pci_driver; | ||
238 | |||
239 | /* --------------------------------------------------------------------- */ | ||
240 | |||
241 | #define M_DEBUG 1 | ||
242 | |||
243 | #ifdef M_DEBUG | ||
244 | static int debug; | ||
245 | #define M_printk(args...) {if (debug) printk(args);} | ||
246 | #else | ||
247 | #define M_printk(x) | ||
248 | #endif | ||
249 | |||
250 | /* we try to setup 2^(dsps_order) /dev/dsp devices */ | ||
251 | static int dsps_order; | ||
252 | /* whether or not we mess around with power management */ | ||
253 | static int use_pm=2; /* set to 1 for force */ | ||
254 | /* clocking for broken hardware - a few laptops seem to use a 50Khz clock | ||
255 | ie insmod with clocking=50000 or so */ | ||
256 | |||
257 | static int clocking=48000; | ||
258 | |||
259 | MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Alan Cox <alan@redhat.com>"); | ||
260 | MODULE_DESCRIPTION("ESS Maestro Driver"); | ||
261 | MODULE_LICENSE("GPL"); | ||
262 | |||
263 | #ifdef M_DEBUG | ||
264 | module_param(debug, bool, 0644); | ||
265 | #endif | ||
266 | module_param(dsps_order, int, 0); | ||
267 | module_param(use_pm, int, 0); | ||
268 | module_param(clocking, int, 0); | ||
269 | |||
270 | /* --------------------------------------------------------------------- */ | ||
271 | #define DRIVER_VERSION "0.15" | ||
272 | |||
273 | #ifndef PCI_VENDOR_ESS | ||
274 | #define PCI_VENDOR_ESS 0x125D | ||
275 | #define PCI_DEVICE_ID_ESS_ESS1968 0x1968 /* Maestro 2 */ | ||
276 | #define PCI_DEVICE_ID_ESS_ESS1978 0x1978 /* Maestro 2E */ | ||
277 | |||
278 | #define PCI_VENDOR_ESS_OLD 0x1285 /* Platform Tech, | ||
279 | the people the maestro | ||
280 | was bought from */ | ||
281 | #define PCI_DEVICE_ID_ESS_ESS0100 0x0100 /* maestro 1 */ | ||
282 | #endif /* PCI_VENDOR_ESS */ | ||
283 | |||
284 | #define ESS_CHAN_HARD 0x100 | ||
285 | |||
286 | /* NEC Versas ? */ | ||
287 | #define NEC_VERSA_SUBID1 0x80581033 | ||
288 | #define NEC_VERSA_SUBID2 0x803c1033 | ||
289 | |||
290 | |||
291 | /* changed so that I could actually find all the | ||
292 | references and fix them up. it's a little more readable now. */ | ||
293 | #define ESS_FMT_STEREO 0x01 | ||
294 | #define ESS_FMT_16BIT 0x02 | ||
295 | #define ESS_FMT_MASK 0x03 | ||
296 | #define ESS_DAC_SHIFT 0 | ||
297 | #define ESS_ADC_SHIFT 4 | ||
298 | |||
299 | #define ESS_STATE_MAGIC 0x125D1968 | ||
300 | #define ESS_CARD_MAGIC 0x19283746 | ||
301 | |||
302 | #define DAC_RUNNING 1 | ||
303 | #define ADC_RUNNING 2 | ||
304 | |||
305 | #define MAX_DSP_ORDER 2 | ||
306 | #define MAX_DSPS (1<<MAX_DSP_ORDER) | ||
307 | #define NR_DSPS (1<<dsps_order) | ||
308 | #define NR_IDRS 32 | ||
309 | |||
310 | #define NR_APUS 64 | ||
311 | #define NR_APU_REGS 16 | ||
312 | |||
313 | /* acpi states */ | ||
314 | enum { | ||
315 | ACPI_D0=0, | ||
316 | ACPI_D1, | ||
317 | ACPI_D2, | ||
318 | ACPI_D3 | ||
319 | }; | ||
320 | |||
321 | /* bits in the acpi masks */ | ||
322 | #define ACPI_12MHZ ( 1 << 15) | ||
323 | #define ACPI_24MHZ ( 1 << 14) | ||
324 | #define ACPI_978 ( 1 << 13) | ||
325 | #define ACPI_SPDIF ( 1 << 12) | ||
326 | #define ACPI_GLUE ( 1 << 11) | ||
327 | #define ACPI__10 ( 1 << 10) /* reserved */ | ||
328 | #define ACPI_PCIINT ( 1 << 9) | ||
329 | #define ACPI_HV ( 1 << 8) /* hardware volume */ | ||
330 | #define ACPI_GPIO ( 1 << 7) | ||
331 | #define ACPI_ASSP ( 1 << 6) | ||
332 | #define ACPI_SB ( 1 << 5) /* sb emul */ | ||
333 | #define ACPI_FM ( 1 << 4) /* fm emul */ | ||
334 | #define ACPI_RB ( 1 << 3) /* ringbus / aclink */ | ||
335 | #define ACPI_MIDI ( 1 << 2) | ||
336 | #define ACPI_GP ( 1 << 1) /* game port */ | ||
337 | #define ACPI_WP ( 1 << 0) /* wave processor */ | ||
338 | |||
339 | #define ACPI_ALL (0xffff) | ||
340 | #define ACPI_SLEEP (~(ACPI_SPDIF|ACPI_ASSP|ACPI_SB|ACPI_FM| \ | ||
341 | ACPI_MIDI|ACPI_GP|ACPI_WP)) | ||
342 | #define ACPI_NONE (ACPI__10) | ||
343 | |||
344 | /* these masks indicate which units we care about at | ||
345 | which states */ | ||
346 | static u16 acpi_state_mask[] = { | ||
347 | [ACPI_D0] = ACPI_ALL, | ||
348 | [ACPI_D1] = ACPI_SLEEP, | ||
349 | [ACPI_D2] = ACPI_SLEEP, | ||
350 | [ACPI_D3] = ACPI_NONE | ||
351 | }; | ||
352 | |||
353 | static char version[] __devinitdata = | ||
354 | KERN_INFO "maestro: version " DRIVER_VERSION " time " __TIME__ " " __DATE__ "\n"; | ||
355 | |||
356 | |||
357 | |||
358 | static const unsigned sample_size[] = { 1, 2, 2, 4 }; | ||
359 | static const unsigned sample_shift[] = { 0, 1, 1, 2 }; | ||
360 | |||
361 | enum card_types_t { | ||
362 | TYPE_MAESTRO, | ||
363 | TYPE_MAESTRO2, | ||
364 | TYPE_MAESTRO2E | ||
365 | }; | ||
366 | |||
367 | static const char *card_names[]={ | ||
368 | [TYPE_MAESTRO] = "ESS Maestro", | ||
369 | [TYPE_MAESTRO2] = "ESS Maestro 2", | ||
370 | [TYPE_MAESTRO2E] = "ESS Maestro 2E" | ||
371 | }; | ||
372 | |||
373 | static int clock_freq[]={ | ||
374 | [TYPE_MAESTRO] = (49152000L / 1024L), | ||
375 | [TYPE_MAESTRO2] = (50000000L / 1024L), | ||
376 | [TYPE_MAESTRO2E] = (50000000L / 1024L) | ||
377 | }; | ||
378 | |||
379 | static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf); | ||
380 | |||
381 | static struct notifier_block maestro_nb = {maestro_notifier, NULL, 0}; | ||
382 | |||
383 | /* --------------------------------------------------------------------- */ | ||
384 | |||
385 | struct ess_state { | ||
386 | unsigned int magic; | ||
387 | /* FIXME: we probably want submixers in here, but only one record pair */ | ||
388 | u8 apu[6]; /* l/r output, l/r intput converters, l/r input apus */ | ||
389 | u8 apu_mode[6]; /* Running mode for this APU */ | ||
390 | u8 apu_pan[6]; /* Panning setup for this APU */ | ||
391 | u32 apu_base[6]; /* base address for this apu */ | ||
392 | struct ess_card *card; /* Card info */ | ||
393 | /* wave stuff */ | ||
394 | unsigned int rateadc, ratedac; | ||
395 | unsigned char fmt, enable; | ||
396 | |||
397 | int index; | ||
398 | |||
399 | /* this locks around the oss state in the driver */ | ||
400 | spinlock_t lock; | ||
401 | /* only let 1 be opening at a time */ | ||
402 | struct mutex open_mutex; | ||
403 | wait_queue_head_t open_wait; | ||
404 | mode_t open_mode; | ||
405 | |||
406 | /* soundcore stuff */ | ||
407 | int dev_audio; | ||
408 | |||
409 | struct dmabuf { | ||
410 | void *rawbuf; | ||
411 | unsigned buforder; | ||
412 | unsigned numfrag; | ||
413 | unsigned fragshift; | ||
414 | /* XXX zab - swptr only in here so that it can be referenced by | ||
415 | clear_advance, as far as I can tell :( */ | ||
416 | unsigned hwptr, swptr; | ||
417 | unsigned total_bytes; | ||
418 | int count; | ||
419 | unsigned error; /* over/underrun */ | ||
420 | wait_queue_head_t wait; | ||
421 | /* redundant, but makes calculations easier */ | ||
422 | unsigned fragsize; | ||
423 | unsigned dmasize; | ||
424 | unsigned fragsamples; | ||
425 | /* OSS stuff */ | ||
426 | unsigned mapped:1; | ||
427 | unsigned ready:1; /* our oss buffers are ready to go */ | ||
428 | unsigned endcleared:1; | ||
429 | unsigned ossfragshift; | ||
430 | int ossmaxfrags; | ||
431 | unsigned subdivision; | ||
432 | u16 base; /* Offset for ptr */ | ||
433 | } dma_dac, dma_adc; | ||
434 | |||
435 | /* pointer to each dsp?s piece of the apu->src buffer page */ | ||
436 | void *mixbuf; | ||
437 | |||
438 | }; | ||
439 | |||
440 | struct ess_card { | ||
441 | unsigned int magic; | ||
442 | |||
443 | /* We keep maestro cards in a linked list */ | ||
444 | struct ess_card *next; | ||
445 | |||
446 | int dev_mixer; | ||
447 | |||
448 | int card_type; | ||
449 | |||
450 | /* as most of this is static, | ||
451 | perhaps it should be a pointer to a global struct */ | ||
452 | struct mixer_goo { | ||
453 | int modcnt; | ||
454 | int supported_mixers; | ||
455 | int stereo_mixers; | ||
456 | int record_sources; | ||
457 | /* the caller must guarantee arg sanity before calling these */ | ||
458 | /* int (*read_mixer)(struct ess_card *card, int index);*/ | ||
459 | void (*write_mixer)(struct ess_card *card,int mixer, unsigned int left,unsigned int right); | ||
460 | int (*recmask_io)(struct ess_card *card,int rw,int mask); | ||
461 | unsigned int mixer_state[SOUND_MIXER_NRDEVICES]; | ||
462 | } mix; | ||
463 | |||
464 | int power_regs; | ||
465 | |||
466 | int in_suspend; | ||
467 | wait_queue_head_t suspend_queue; | ||
468 | |||
469 | struct ess_state channels[MAX_DSPS]; | ||
470 | u16 maestro_map[NR_IDRS]; /* Register map */ | ||
471 | /* we have to store this junk so that we can come back from a | ||
472 | suspend */ | ||
473 | u16 apu_map[NR_APUS][NR_APU_REGS]; /* contents of apu regs */ | ||
474 | |||
475 | /* this locks around the physical registers on the card */ | ||
476 | spinlock_t lock; | ||
477 | |||
478 | /* memory for this card.. wavecache limited :(*/ | ||
479 | void *dmapages; | ||
480 | int dmaorder; | ||
481 | |||
482 | /* hardware resources */ | ||
483 | struct pci_dev *pcidev; | ||
484 | u32 iobase; | ||
485 | u32 irq; | ||
486 | |||
487 | int bob_freq; | ||
488 | char dsps_open; | ||
489 | |||
490 | int dock_mute_vol; | ||
491 | }; | ||
492 | |||
493 | static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val ); | ||
494 | |||
495 | static unsigned | ||
496 | ld2(unsigned int x) | ||
497 | { | ||
498 | unsigned r = 0; | ||
499 | |||
500 | if (x >= 0x10000) { | ||
501 | x >>= 16; | ||
502 | r += 16; | ||
503 | } | ||
504 | if (x >= 0x100) { | ||
505 | x >>= 8; | ||
506 | r += 8; | ||
507 | } | ||
508 | if (x >= 0x10) { | ||
509 | x >>= 4; | ||
510 | r += 4; | ||
511 | } | ||
512 | if (x >= 4) { | ||
513 | x >>= 2; | ||
514 | r += 2; | ||
515 | } | ||
516 | if (x >= 2) | ||
517 | r++; | ||
518 | return r; | ||
519 | } | ||
520 | |||
521 | |||
522 | /* --------------------------------------------------------------------- */ | ||
523 | |||
524 | static void check_suspend(struct ess_card *card); | ||
525 | |||
526 | /* --------------------------------------------------------------------- */ | ||
527 | |||
528 | |||
529 | /* | ||
530 | * ESS Maestro AC97 codec programming interface. | ||
531 | */ | ||
532 | |||
533 | static void maestro_ac97_set(struct ess_card *card, u8 cmd, u16 val) | ||
534 | { | ||
535 | int io = card->iobase; | ||
536 | int i; | ||
537 | /* | ||
538 | * Wait for the codec bus to be free | ||
539 | */ | ||
540 | |||
541 | check_suspend(card); | ||
542 | |||
543 | for(i=0;i<10000;i++) | ||
544 | { | ||
545 | if(!(inb(io+ESS_AC97_INDEX)&1)) | ||
546 | break; | ||
547 | } | ||
548 | /* | ||
549 | * Write the bus | ||
550 | */ | ||
551 | outw(val, io+ESS_AC97_DATA); | ||
552 | mdelay(1); | ||
553 | outb(cmd, io+ESS_AC97_INDEX); | ||
554 | mdelay(1); | ||
555 | } | ||
556 | |||
557 | static u16 maestro_ac97_get(struct ess_card *card, u8 cmd) | ||
558 | { | ||
559 | int io = card->iobase; | ||
560 | int sanity=10000; | ||
561 | u16 data; | ||
562 | int i; | ||
563 | |||
564 | check_suspend(card); | ||
565 | /* | ||
566 | * Wait for the codec bus to be free | ||
567 | */ | ||
568 | |||
569 | for(i=0;i<10000;i++) | ||
570 | { | ||
571 | if(!(inb(io+ESS_AC97_INDEX)&1)) | ||
572 | break; | ||
573 | } | ||
574 | |||
575 | outb(cmd|0x80, io+ESS_AC97_INDEX); | ||
576 | mdelay(1); | ||
577 | |||
578 | while(inb(io+ESS_AC97_INDEX)&1) | ||
579 | { | ||
580 | sanity--; | ||
581 | if(!sanity) | ||
582 | { | ||
583 | printk(KERN_ERR "maestro: ac97 codec timeout reading 0x%x.\n",cmd); | ||
584 | return 0; | ||
585 | } | ||
586 | } | ||
587 | data=inw(io+ESS_AC97_DATA); | ||
588 | mdelay(1); | ||
589 | return data; | ||
590 | } | ||
591 | |||
592 | /* OSS interface to the ac97s.. */ | ||
593 | |||
594 | #define AC97_STEREO_MASK (SOUND_MASK_VOLUME|\ | ||
595 | SOUND_MASK_PCM|SOUND_MASK_LINE|SOUND_MASK_CD|\ | ||
596 | SOUND_MASK_VIDEO|SOUND_MASK_LINE1|SOUND_MASK_IGAIN) | ||
597 | |||
598 | #define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \ | ||
599 | SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_MIC|\ | ||
600 | SOUND_MASK_SPEAKER) | ||
601 | |||
602 | #define AC97_RECORD_MASK (SOUND_MASK_MIC|\ | ||
603 | SOUND_MASK_CD| SOUND_MASK_VIDEO| SOUND_MASK_LINE1| SOUND_MASK_LINE|\ | ||
604 | SOUND_MASK_PHONEIN) | ||
605 | |||
606 | #define supported_mixer(CARD,FOO) ( CARD->mix.supported_mixers & (1<<FOO) ) | ||
607 | |||
608 | /* this table has default mixer values for all OSS mixers. | ||
609 | be sure to fill it in if you add oss mixers | ||
610 | to anyone's supported mixer defines */ | ||
611 | |||
612 | static unsigned int mixer_defaults[SOUND_MIXER_NRDEVICES] = { | ||
613 | [SOUND_MIXER_VOLUME] = 0x3232, | ||
614 | [SOUND_MIXER_BASS] = 0x3232, | ||
615 | [SOUND_MIXER_TREBLE] = 0x3232, | ||
616 | [SOUND_MIXER_SPEAKER] = 0x3232, | ||
617 | [SOUND_MIXER_MIC] = 0x8000, /* annoying */ | ||
618 | [SOUND_MIXER_LINE] = 0x3232, | ||
619 | [SOUND_MIXER_CD] = 0x3232, | ||
620 | [SOUND_MIXER_VIDEO] = 0x3232, | ||
621 | [SOUND_MIXER_LINE1] = 0x3232, | ||
622 | [SOUND_MIXER_PCM] = 0x3232, | ||
623 | [SOUND_MIXER_IGAIN] = 0x3232 | ||
624 | }; | ||
625 | |||
626 | static struct ac97_mixer_hw { | ||
627 | unsigned char offset; | ||
628 | int scale; | ||
629 | } ac97_hw[SOUND_MIXER_NRDEVICES]= { | ||
630 | [SOUND_MIXER_VOLUME] = {0x02,63}, | ||
631 | [SOUND_MIXER_BASS] = {0x08,15}, | ||
632 | [SOUND_MIXER_TREBLE] = {0x08,15}, | ||
633 | [SOUND_MIXER_SPEAKER] = {0x0a,15}, | ||
634 | [SOUND_MIXER_MIC] = {0x0e,31}, | ||
635 | [SOUND_MIXER_LINE] = {0x10,31}, | ||
636 | [SOUND_MIXER_CD] = {0x12,31}, | ||
637 | [SOUND_MIXER_VIDEO] = {0x14,31}, | ||
638 | [SOUND_MIXER_LINE1] = {0x16,31}, | ||
639 | [SOUND_MIXER_PCM] = {0x18,31}, | ||
640 | [SOUND_MIXER_IGAIN] = {0x1c,15} | ||
641 | }; | ||
642 | |||
643 | #if 0 /* *shrug* removed simply because we never used it. | ||
644 | feel free to implement again if needed */ | ||
645 | |||
646 | /* reads the given OSS mixer from the ac97 | ||
647 | the caller must have insured that the ac97 knows | ||
648 | about that given mixer, and should be holding a | ||
649 | spinlock for the card */ | ||
650 | static int ac97_read_mixer(struct ess_card *card, int mixer) | ||
651 | { | ||
652 | u16 val; | ||
653 | int ret=0; | ||
654 | struct ac97_mixer_hw *mh = &ac97_hw[mixer]; | ||
655 | |||
656 | val = maestro_ac97_get(card, mh->offset); | ||
657 | |||
658 | if(AC97_STEREO_MASK & (1<<mixer)) { | ||
659 | /* nice stereo mixers .. */ | ||
660 | int left,right; | ||
661 | |||
662 | left = (val >> 8) & 0x7f; | ||
663 | right = val & 0x7f; | ||
664 | |||
665 | if (mixer == SOUND_MIXER_IGAIN) { | ||
666 | right = (right * 100) / mh->scale; | ||
667 | left = (left * 100) / mh->scale; | ||
668 | } else { | ||
669 | right = 100 - ((right * 100) / mh->scale); | ||
670 | left = 100 - ((left * 100) / mh->scale); | ||
671 | } | ||
672 | |||
673 | ret = left | (right << 8); | ||
674 | } else if (mixer == SOUND_MIXER_SPEAKER) { | ||
675 | ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale); | ||
676 | } else if (mixer == SOUND_MIXER_MIC) { | ||
677 | ret = 100 - (((val & 0x1f) * 100) / mh->scale); | ||
678 | /* the low bit is optional in the tone sliders and masking | ||
679 | it lets is avoid the 0xf 'bypass'.. */ | ||
680 | } else if (mixer == SOUND_MIXER_BASS) { | ||
681 | ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale); | ||
682 | } else if (mixer == SOUND_MIXER_TREBLE) { | ||
683 | ret = 100 - (((val & 0xe) * 100) / mh->scale); | ||
684 | } | ||
685 | |||
686 | M_printk("read mixer %d (0x%x) %x -> %x\n",mixer,mh->offset,val,ret); | ||
687 | |||
688 | return ret; | ||
689 | } | ||
690 | #endif | ||
691 | |||
692 | /* write the OSS encoded volume to the given OSS encoded mixer, | ||
693 | again caller's job to make sure all is well in arg land, | ||
694 | call with spinlock held */ | ||
695 | |||
696 | /* linear scale -> log */ | ||
697 | static unsigned char lin2log[101] = | ||
698 | { | ||
699 | 0, 0 , 15 , 23 , 30 , 34 , 38 , 42 , 45 , 47 , | ||
700 | 50 , 52 , 53 , 55 , 57 , 58 , 60 , 61 , 62 , | ||
701 | 63 , 65 , 66 , 67 , 68 , 69 , 69 , 70 , 71 , | ||
702 | 72 , 73 , 73 , 74 , 75 , 75 , 76 , 77 , 77 , | ||
703 | 78 , 78 , 79 , 80 , 80 , 81 , 81 , 82 , 82 , | ||
704 | 83 , 83 , 84 , 84 , 84 , 85 , 85 , 86 , 86 , | ||
705 | 87 , 87 , 87 , 88 , 88 , 88 , 89 , 89 , 89 , | ||
706 | 90 , 90 , 90 , 91 , 91 , 91 , 92 , 92 , 92 , | ||
707 | 93 , 93 , 93 , 94 , 94 , 94 , 94 , 95 , 95 , | ||
708 | 95 , 95 , 96 , 96 , 96 , 96 , 97 , 97 , 97 , | ||
709 | 97 , 98 , 98 , 98 , 98 , 99 , 99 , 99 , 99 , 99 | ||
710 | }; | ||
711 | |||
712 | static void ac97_write_mixer(struct ess_card *card,int mixer, unsigned int left, unsigned int right) | ||
713 | { | ||
714 | u16 val=0; | ||
715 | struct ac97_mixer_hw *mh = &ac97_hw[mixer]; | ||
716 | |||
717 | M_printk("wrote mixer %d (0x%x) %d,%d",mixer,mh->offset,left,right); | ||
718 | |||
719 | if(AC97_STEREO_MASK & (1<<mixer)) { | ||
720 | /* stereo mixers, mute them if we can */ | ||
721 | |||
722 | if (mixer == SOUND_MIXER_IGAIN) { | ||
723 | /* igain's slider is reversed.. */ | ||
724 | right = (right * mh->scale) / 100; | ||
725 | left = (left * mh->scale) / 100; | ||
726 | if ((left == 0) && (right == 0)) | ||
727 | val |= 0x8000; | ||
728 | } else if (mixer == SOUND_MIXER_PCM || mixer == SOUND_MIXER_CD) { | ||
729 | /* log conversion seems bad for them */ | ||
730 | if ((left == 0) && (right == 0)) | ||
731 | val = 0x8000; | ||
732 | right = ((100 - right) * mh->scale) / 100; | ||
733 | left = ((100 - left) * mh->scale) / 100; | ||
734 | } else { | ||
735 | /* log conversion for the stereo controls */ | ||
736 | if((left == 0) && (right == 0)) | ||
737 | val = 0x8000; | ||
738 | right = ((100 - lin2log[right]) * mh->scale) / 100; | ||
739 | left = ((100 - lin2log[left]) * mh->scale) / 100; | ||
740 | } | ||
741 | |||
742 | val |= (left << 8) | right; | ||
743 | |||
744 | } else if (mixer == SOUND_MIXER_SPEAKER) { | ||
745 | val = (((100 - left) * mh->scale) / 100) << 1; | ||
746 | } else if (mixer == SOUND_MIXER_MIC) { | ||
747 | val = maestro_ac97_get(card, mh->offset) & ~0x801f; | ||
748 | val |= (((100 - left) * mh->scale) / 100); | ||
749 | /* the low bit is optional in the tone sliders and masking | ||
750 | it lets is avoid the 0xf 'bypass'.. */ | ||
751 | } else if (mixer == SOUND_MIXER_BASS) { | ||
752 | val = maestro_ac97_get(card , mh->offset) & ~0x0f00; | ||
753 | val |= ((((100 - left) * mh->scale) / 100) << 8) & 0x0e00; | ||
754 | } else if (mixer == SOUND_MIXER_TREBLE) { | ||
755 | val = maestro_ac97_get(card , mh->offset) & ~0x000f; | ||
756 | val |= (((100 - left) * mh->scale) / 100) & 0x000e; | ||
757 | } | ||
758 | |||
759 | maestro_ac97_set(card , mh->offset, val); | ||
760 | |||
761 | M_printk(" -> %x\n",val); | ||
762 | } | ||
763 | |||
764 | /* the following tables allow us to go from | ||
765 | OSS <-> ac97 quickly. */ | ||
766 | |||
767 | enum ac97_recsettings { | ||
768 | AC97_REC_MIC=0, | ||
769 | AC97_REC_CD, | ||
770 | AC97_REC_VIDEO, | ||
771 | AC97_REC_AUX, | ||
772 | AC97_REC_LINE, | ||
773 | AC97_REC_STEREO, /* combination of all enabled outputs.. */ | ||
774 | AC97_REC_MONO, /*.. or the mono equivalent */ | ||
775 | AC97_REC_PHONE | ||
776 | }; | ||
777 | |||
778 | static unsigned int ac97_oss_mask[] = { | ||
779 | [AC97_REC_MIC] = SOUND_MASK_MIC, | ||
780 | [AC97_REC_CD] = SOUND_MASK_CD, | ||
781 | [AC97_REC_VIDEO] = SOUND_MASK_VIDEO, | ||
782 | [AC97_REC_AUX] = SOUND_MASK_LINE1, | ||
783 | [AC97_REC_LINE] = SOUND_MASK_LINE, | ||
784 | [AC97_REC_PHONE] = SOUND_MASK_PHONEIN | ||
785 | }; | ||
786 | |||
787 | /* indexed by bit position */ | ||
788 | static unsigned int ac97_oss_rm[] = { | ||
789 | [SOUND_MIXER_MIC] = AC97_REC_MIC, | ||
790 | [SOUND_MIXER_CD] = AC97_REC_CD, | ||
791 | [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO, | ||
792 | [SOUND_MIXER_LINE1] = AC97_REC_AUX, | ||
793 | [SOUND_MIXER_LINE] = AC97_REC_LINE, | ||
794 | [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE | ||
795 | }; | ||
796 | |||
797 | /* read or write the recmask | ||
798 | the ac97 can really have left and right recording | ||
799 | inputs independently set, but OSS doesn't seem to | ||
800 | want us to express that to the user. | ||
801 | the caller guarantees that we have a supported bit set, | ||
802 | and they must be holding the card's spinlock */ | ||
803 | static int | ||
804 | ac97_recmask_io(struct ess_card *card, int read, int mask) | ||
805 | { | ||
806 | unsigned int val = ac97_oss_mask[ maestro_ac97_get(card, 0x1a) & 0x7 ]; | ||
807 | |||
808 | if (read) return val; | ||
809 | |||
810 | /* oss can have many inputs, maestro can't. try | ||
811 | to pick the 'new' one */ | ||
812 | |||
813 | if (mask != val) mask &= ~val; | ||
814 | |||
815 | val = ffs(mask) - 1; | ||
816 | val = ac97_oss_rm[val]; | ||
817 | val |= val << 8; /* set both channels */ | ||
818 | |||
819 | M_printk("maestro: setting ac97 recmask to 0x%x\n",val); | ||
820 | |||
821 | maestro_ac97_set(card,0x1a,val); | ||
822 | |||
823 | return 0; | ||
824 | }; | ||
825 | |||
826 | /* | ||
827 | * The Maestro can be wired to a standard AC97 compliant codec | ||
828 | * (see www.intel.com for the pdf's on this), or to a PT101 codec | ||
829 | * which appears to be the ES1918 (data sheet on the esstech.com.tw site) | ||
830 | * | ||
831 | * The PT101 setup is untested. | ||
832 | */ | ||
833 | |||
834 | static u16 __init maestro_ac97_init(struct ess_card *card) | ||
835 | { | ||
836 | u16 vend1, vend2, caps; | ||
837 | |||
838 | card->mix.supported_mixers = AC97_SUPPORTED_MASK; | ||
839 | card->mix.stereo_mixers = AC97_STEREO_MASK; | ||
840 | card->mix.record_sources = AC97_RECORD_MASK; | ||
841 | /* card->mix.read_mixer = ac97_read_mixer;*/ | ||
842 | card->mix.write_mixer = ac97_write_mixer; | ||
843 | card->mix.recmask_io = ac97_recmask_io; | ||
844 | |||
845 | vend1 = maestro_ac97_get(card, 0x7c); | ||
846 | vend2 = maestro_ac97_get(card, 0x7e); | ||
847 | |||
848 | caps = maestro_ac97_get(card, 0x00); | ||
849 | |||
850 | printk(KERN_INFO "maestro: AC97 Codec detected: v: 0x%2x%2x caps: 0x%x pwr: 0x%x\n", | ||
851 | vend1,vend2,caps,maestro_ac97_get(card,0x26) & 0xf); | ||
852 | |||
853 | if (! (caps & 0x4) ) { | ||
854 | /* no bass/treble nobs */ | ||
855 | card->mix.supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE); | ||
856 | } | ||
857 | |||
858 | /* XXX endianness, dork head. */ | ||
859 | /* vendor specifc bits.. */ | ||
860 | switch ((long)(vend1 << 16) | vend2) { | ||
861 | case 0x545200ff: /* TriTech */ | ||
862 | /* no idea what this does */ | ||
863 | maestro_ac97_set(card,0x2a,0x0001); | ||
864 | maestro_ac97_set(card,0x2c,0x0000); | ||
865 | maestro_ac97_set(card,0x2c,0xffff); | ||
866 | break; | ||
867 | #if 0 /* i thought the problems I was seeing were with | ||
868 | the 1921, but apparently they were with the pci board | ||
869 | it was on, so this code is commented out. | ||
870 | lets see if this holds true. */ | ||
871 | case 0x83847609: /* ESS 1921 */ | ||
872 | /* writing to 0xe (mic) or 0x1a (recmask) seems | ||
873 | to hang this codec */ | ||
874 | card->mix.supported_mixers &= ~(SOUND_MASK_MIC); | ||
875 | card->mix.record_sources = 0; | ||
876 | card->mix.recmask_io = NULL; | ||
877 | #if 0 /* don't ask. I have yet to see what these actually do. */ | ||
878 | maestro_ac97_set(card,0x76,0xABBA); /* o/~ Take a chance on me o/~ */ | ||
879 | udelay(20); | ||
880 | maestro_ac97_set(card,0x78,0x3002); | ||
881 | udelay(20); | ||
882 | maestro_ac97_set(card,0x78,0x3802); | ||
883 | udelay(20); | ||
884 | #endif | ||
885 | break; | ||
886 | #endif | ||
887 | default: break; | ||
888 | } | ||
889 | |||
890 | maestro_ac97_set(card, 0x1E, 0x0404); | ||
891 | /* null misc stuff */ | ||
892 | maestro_ac97_set(card, 0x20, 0x0000); | ||
893 | |||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | #if 0 /* there has been 1 person on the planet with a pt101 that we | ||
898 | know of. If they care, they can put this back in :) */ | ||
899 | static u16 maestro_pt101_init(struct ess_card *card,int iobase) | ||
900 | { | ||
901 | printk(KERN_INFO "maestro: PT101 Codec detected, initializing but _not_ installing mixer device.\n"); | ||
902 | /* who knows.. */ | ||
903 | maestro_ac97_set(iobase, 0x2A, 0x0001); | ||
904 | maestro_ac97_set(iobase, 0x2C, 0x0000); | ||
905 | maestro_ac97_set(iobase, 0x2C, 0xFFFF); | ||
906 | maestro_ac97_set(iobase, 0x10, 0x9F1F); | ||
907 | maestro_ac97_set(iobase, 0x12, 0x0808); | ||
908 | maestro_ac97_set(iobase, 0x14, 0x9F1F); | ||
909 | maestro_ac97_set(iobase, 0x16, 0x9F1F); | ||
910 | maestro_ac97_set(iobase, 0x18, 0x0404); | ||
911 | maestro_ac97_set(iobase, 0x1A, 0x0000); | ||
912 | maestro_ac97_set(iobase, 0x1C, 0x0000); | ||
913 | maestro_ac97_set(iobase, 0x02, 0x0404); | ||
914 | maestro_ac97_set(iobase, 0x04, 0x0808); | ||
915 | maestro_ac97_set(iobase, 0x0C, 0x801F); | ||
916 | maestro_ac97_set(iobase, 0x0E, 0x801F); | ||
917 | return 0; | ||
918 | } | ||
919 | #endif | ||
920 | |||
921 | /* this is very magic, and very slow.. */ | ||
922 | static void | ||
923 | maestro_ac97_reset(int ioaddr, struct pci_dev *pcidev) | ||
924 | { | ||
925 | u16 save_68; | ||
926 | u16 w; | ||
927 | u32 vend; | ||
928 | |||
929 | outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); | ||
930 | outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a); | ||
931 | outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c); | ||
932 | |||
933 | /* reset the first codec */ | ||
934 | outw(0x0000, ioaddr+0x36); | ||
935 | save_68 = inw(ioaddr+0x68); | ||
936 | pci_read_config_word(pcidev, 0x58, &w); /* something magical with gpio and bus arb. */ | ||
937 | pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &vend); | ||
938 | if( w & 0x1) | ||
939 | save_68 |= 0x10; | ||
940 | outw(0xfffe, ioaddr + 0x64); /* tickly gpio 0.. */ | ||
941 | outw(0x0001, ioaddr + 0x68); | ||
942 | outw(0x0000, ioaddr + 0x60); | ||
943 | udelay(20); | ||
944 | outw(0x0001, ioaddr + 0x60); | ||
945 | mdelay(20); | ||
946 | |||
947 | outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */ | ||
948 | outw( (inw(ioaddr + 0x38) & 0xfffc)|0x1, ioaddr + 0x38); | ||
949 | outw( (inw(ioaddr + 0x3a) & 0xfffc)|0x1, ioaddr + 0x3a); | ||
950 | outw( (inw(ioaddr + 0x3c) & 0xfffc)|0x1, ioaddr + 0x3c); | ||
951 | |||
952 | /* now the second codec */ | ||
953 | outw(0x0000, ioaddr+0x36); | ||
954 | outw(0xfff7, ioaddr + 0x64); | ||
955 | save_68 = inw(ioaddr+0x68); | ||
956 | outw(0x0009, ioaddr + 0x68); | ||
957 | outw(0x0001, ioaddr + 0x60); | ||
958 | udelay(20); | ||
959 | outw(0x0009, ioaddr + 0x60); | ||
960 | mdelay(500); /* .. ouch.. */ | ||
961 | outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); | ||
962 | outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a); | ||
963 | outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c); | ||
964 | |||
965 | #if 0 /* the loop here needs to be much better if we want it.. */ | ||
966 | M_printk("trying software reset\n"); | ||
967 | /* try and do a software reset */ | ||
968 | outb(0x80|0x7c, ioaddr + 0x30); | ||
969 | for (w=0; ; w++) { | ||
970 | if ((inw(ioaddr+ 0x30) & 1) == 0) { | ||
971 | if(inb(ioaddr + 0x32) !=0) break; | ||
972 | |||
973 | outb(0x80|0x7d, ioaddr + 0x30); | ||
974 | if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break; | ||
975 | outb(0x80|0x7f, ioaddr + 0x30); | ||
976 | if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break; | ||
977 | } | ||
978 | |||
979 | if( w > 10000) { | ||
980 | outb( inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37); /* do a software reset */ | ||
981 | mdelay(500); /* oh my.. */ | ||
982 | outb( inb(ioaddr + 0x37) & ~0x08, ioaddr + 0x37); | ||
983 | udelay(1); | ||
984 | outw( 0x80, ioaddr+0x30); | ||
985 | for(w = 0 ; w < 10000; w++) { | ||
986 | if((inw(ioaddr + 0x30) & 1) ==0) break; | ||
987 | } | ||
988 | } | ||
989 | } | ||
990 | #endif | ||
991 | if ( vend == NEC_VERSA_SUBID1 || vend == NEC_VERSA_SUBID2) { | ||
992 | /* turn on external amp? */ | ||
993 | outw(0xf9ff, ioaddr + 0x64); | ||
994 | outw(inw(ioaddr+0x68) | 0x600, ioaddr + 0x68); | ||
995 | outw(0x0209, ioaddr + 0x60); | ||
996 | } | ||
997 | |||
998 | /* Turn on the 978 docking chip. | ||
999 | First frob the "master output enable" bit, | ||
1000 | then set most of the playback volume control registers to max. */ | ||
1001 | outb(inb(ioaddr+0xc0)|(1<<5), ioaddr+0xc0); | ||
1002 | outb(0xff, ioaddr+0xc3); | ||
1003 | outb(0xff, ioaddr+0xc4); | ||
1004 | outb(0xff, ioaddr+0xc6); | ||
1005 | outb(0xff, ioaddr+0xc8); | ||
1006 | outb(0x3f, ioaddr+0xcf); | ||
1007 | outb(0x3f, ioaddr+0xd0); | ||
1008 | } | ||
1009 | /* | ||
1010 | * Indirect register access. Not all registers are readable so we | ||
1011 | * need to keep register state ourselves | ||
1012 | */ | ||
1013 | |||
1014 | #define WRITEABLE_MAP 0xEFFFFF | ||
1015 | #define READABLE_MAP 0x64003F | ||
1016 | |||
1017 | /* | ||
1018 | * The Maestro engineers were a little indirection happy. These indirected | ||
1019 | * registers themselves include indirect registers at another layer | ||
1020 | */ | ||
1021 | |||
1022 | static void __maestro_write(struct ess_card *card, u16 reg, u16 data) | ||
1023 | { | ||
1024 | long ioaddr = card->iobase; | ||
1025 | |||
1026 | outw(reg, ioaddr+0x02); | ||
1027 | outw(data, ioaddr+0x00); | ||
1028 | if( reg >= NR_IDRS) printk("maestro: IDR %d out of bounds!\n",reg); | ||
1029 | else card->maestro_map[reg]=data; | ||
1030 | |||
1031 | } | ||
1032 | |||
1033 | static void maestro_write(struct ess_state *s, u16 reg, u16 data) | ||
1034 | { | ||
1035 | unsigned long flags; | ||
1036 | |||
1037 | check_suspend(s->card); | ||
1038 | spin_lock_irqsave(&s->card->lock,flags); | ||
1039 | |||
1040 | __maestro_write(s->card,reg,data); | ||
1041 | |||
1042 | spin_unlock_irqrestore(&s->card->lock,flags); | ||
1043 | } | ||
1044 | |||
1045 | static u16 __maestro_read(struct ess_card *card, u16 reg) | ||
1046 | { | ||
1047 | long ioaddr = card->iobase; | ||
1048 | |||
1049 | outw(reg, ioaddr+0x02); | ||
1050 | return card->maestro_map[reg]=inw(ioaddr+0x00); | ||
1051 | } | ||
1052 | |||
1053 | static u16 maestro_read(struct ess_state *s, u16 reg) | ||
1054 | { | ||
1055 | if(READABLE_MAP & (1<<reg)) | ||
1056 | { | ||
1057 | unsigned long flags; | ||
1058 | check_suspend(s->card); | ||
1059 | spin_lock_irqsave(&s->card->lock,flags); | ||
1060 | |||
1061 | __maestro_read(s->card,reg); | ||
1062 | |||
1063 | spin_unlock_irqrestore(&s->card->lock,flags); | ||
1064 | } | ||
1065 | return s->card->maestro_map[reg]; | ||
1066 | } | ||
1067 | |||
1068 | /* | ||
1069 | * These routines handle accessing the second level indirections to the | ||
1070 | * wave ram. | ||
1071 | */ | ||
1072 | |||
1073 | /* | ||
1074 | * The register names are the ones ESS uses (see 104T31.ZIP) | ||
1075 | */ | ||
1076 | |||
1077 | #define IDR0_DATA_PORT 0x00 | ||
1078 | #define IDR1_CRAM_POINTER 0x01 | ||
1079 | #define IDR2_CRAM_DATA 0x02 | ||
1080 | #define IDR3_WAVE_DATA 0x03 | ||
1081 | #define IDR4_WAVE_PTR_LOW 0x04 | ||
1082 | #define IDR5_WAVE_PTR_HI 0x05 | ||
1083 | #define IDR6_TIMER_CTRL 0x06 | ||
1084 | #define IDR7_WAVE_ROMRAM 0x07 | ||
1085 | |||
1086 | static void apu_index_set(struct ess_card *card, u16 index) | ||
1087 | { | ||
1088 | int i; | ||
1089 | __maestro_write(card, IDR1_CRAM_POINTER, index); | ||
1090 | for(i=0;i<1000;i++) | ||
1091 | if(__maestro_read(card, IDR1_CRAM_POINTER)==index) | ||
1092 | return; | ||
1093 | printk(KERN_WARNING "maestro: APU register select failed.\n"); | ||
1094 | } | ||
1095 | |||
1096 | static void apu_data_set(struct ess_card *card, u16 data) | ||
1097 | { | ||
1098 | int i; | ||
1099 | for(i=0;i<1000;i++) | ||
1100 | { | ||
1101 | if(__maestro_read(card, IDR0_DATA_PORT)==data) | ||
1102 | return; | ||
1103 | __maestro_write(card, IDR0_DATA_PORT, data); | ||
1104 | } | ||
1105 | } | ||
1106 | |||
1107 | /* | ||
1108 | * This is the public interface for APU manipulation. It handles the | ||
1109 | * interlock to avoid two APU writes in parallel etc. Don't diddle | ||
1110 | * directly with the stuff above. | ||
1111 | */ | ||
1112 | |||
1113 | static void apu_set_register(struct ess_state *s, u16 channel, u8 reg, u16 data) | ||
1114 | { | ||
1115 | unsigned long flags; | ||
1116 | |||
1117 | check_suspend(s->card); | ||
1118 | |||
1119 | if(channel&ESS_CHAN_HARD) | ||
1120 | channel&=~ESS_CHAN_HARD; | ||
1121 | else | ||
1122 | { | ||
1123 | if(channel>5) | ||
1124 | printk("BAD CHANNEL %d.\n",channel); | ||
1125 | else | ||
1126 | channel = s->apu[channel]; | ||
1127 | /* store based on real hardware apu/reg */ | ||
1128 | s->card->apu_map[channel][reg]=data; | ||
1129 | } | ||
1130 | reg|=(channel<<4); | ||
1131 | |||
1132 | /* hooray for double indirection!! */ | ||
1133 | spin_lock_irqsave(&s->card->lock,flags); | ||
1134 | |||
1135 | apu_index_set(s->card, reg); | ||
1136 | apu_data_set(s->card, data); | ||
1137 | |||
1138 | spin_unlock_irqrestore(&s->card->lock,flags); | ||
1139 | } | ||
1140 | |||
1141 | static u16 apu_get_register(struct ess_state *s, u16 channel, u8 reg) | ||
1142 | { | ||
1143 | unsigned long flags; | ||
1144 | u16 v; | ||
1145 | |||
1146 | check_suspend(s->card); | ||
1147 | |||
1148 | if(channel&ESS_CHAN_HARD) | ||
1149 | channel&=~ESS_CHAN_HARD; | ||
1150 | else | ||
1151 | channel = s->apu[channel]; | ||
1152 | |||
1153 | reg|=(channel<<4); | ||
1154 | |||
1155 | spin_lock_irqsave(&s->card->lock,flags); | ||
1156 | |||
1157 | apu_index_set(s->card, reg); | ||
1158 | v=__maestro_read(s->card, IDR0_DATA_PORT); | ||
1159 | |||
1160 | spin_unlock_irqrestore(&s->card->lock,flags); | ||
1161 | return v; | ||
1162 | } | ||
1163 | |||
1164 | |||
1165 | /* | ||
1166 | * The wavecache buffers between the APUs and | ||
1167 | * pci bus mastering | ||
1168 | */ | ||
1169 | |||
1170 | static void wave_set_register(struct ess_state *s, u16 reg, u16 value) | ||
1171 | { | ||
1172 | long ioaddr = s->card->iobase; | ||
1173 | unsigned long flags; | ||
1174 | check_suspend(s->card); | ||
1175 | |||
1176 | spin_lock_irqsave(&s->card->lock,flags); | ||
1177 | |||
1178 | outw(reg, ioaddr+0x10); | ||
1179 | outw(value, ioaddr+0x12); | ||
1180 | |||
1181 | spin_unlock_irqrestore(&s->card->lock,flags); | ||
1182 | } | ||
1183 | |||
1184 | static u16 wave_get_register(struct ess_state *s, u16 reg) | ||
1185 | { | ||
1186 | long ioaddr = s->card->iobase; | ||
1187 | unsigned long flags; | ||
1188 | u16 value; | ||
1189 | check_suspend(s->card); | ||
1190 | |||
1191 | spin_lock_irqsave(&s->card->lock,flags); | ||
1192 | outw(reg, ioaddr+0x10); | ||
1193 | value=inw(ioaddr+0x12); | ||
1194 | spin_unlock_irqrestore(&s->card->lock,flags); | ||
1195 | |||
1196 | return value; | ||
1197 | } | ||
1198 | |||
1199 | static void sound_reset(int ioaddr) | ||
1200 | { | ||
1201 | outw(0x2000, 0x18+ioaddr); | ||
1202 | udelay(1); | ||
1203 | outw(0x0000, 0x18+ioaddr); | ||
1204 | udelay(1); | ||
1205 | } | ||
1206 | |||
1207 | /* sets the play formats of these apus, should be passed the already shifted format */ | ||
1208 | static void set_apu_fmt(struct ess_state *s, int apu, int mode) | ||
1209 | { | ||
1210 | int apu_fmt = 0x10; | ||
1211 | |||
1212 | if(!(mode&ESS_FMT_16BIT)) apu_fmt+=0x20; | ||
1213 | if((mode&ESS_FMT_STEREO)) apu_fmt+=0x10; | ||
1214 | s->apu_mode[apu] = apu_fmt; | ||
1215 | s->apu_mode[apu+1] = apu_fmt; | ||
1216 | } | ||
1217 | |||
1218 | /* this only fixes the output apu mode to be later set by start_dac and | ||
1219 | company. output apu modes are set in ess_rec_setup */ | ||
1220 | static void set_fmt(struct ess_state *s, unsigned char mask, unsigned char data) | ||
1221 | { | ||
1222 | s->fmt = (s->fmt & mask) | data; | ||
1223 | set_apu_fmt(s, 0, (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK); | ||
1224 | } | ||
1225 | |||
1226 | /* this is off by a little bit.. */ | ||
1227 | static u32 compute_rate(struct ess_state *s, u32 freq) | ||
1228 | { | ||
1229 | u32 clock = clock_freq[s->card->card_type]; | ||
1230 | |||
1231 | freq = (freq * clocking)/48000; | ||
1232 | |||
1233 | if (freq == 48000) | ||
1234 | return 0x10000; | ||
1235 | |||
1236 | return ((freq / clock) <<16 )+ | ||
1237 | (((freq % clock) << 16) / clock); | ||
1238 | } | ||
1239 | |||
1240 | static void set_dac_rate(struct ess_state *s, unsigned int rate) | ||
1241 | { | ||
1242 | u32 freq; | ||
1243 | int fmt = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK; | ||
1244 | |||
1245 | if (rate > 48000) | ||
1246 | rate = 48000; | ||
1247 | if (rate < 4000) | ||
1248 | rate = 4000; | ||
1249 | |||
1250 | s->ratedac = rate; | ||
1251 | |||
1252 | if(! (fmt & ESS_FMT_16BIT) && !(fmt & ESS_FMT_STEREO)) | ||
1253 | rate >>= 1; | ||
1254 | |||
1255 | /* M_printk("computing dac rate %d with mode %d\n",rate,s->fmt);*/ | ||
1256 | |||
1257 | freq = compute_rate(s, rate); | ||
1258 | |||
1259 | /* Load the frequency, turn on 6dB */ | ||
1260 | apu_set_register(s, 0, 2,(apu_get_register(s, 0, 2)&0x00FF)| | ||
1261 | ( ((freq&0xFF)<<8)|0x10 )); | ||
1262 | apu_set_register(s, 0, 3, freq>>8); | ||
1263 | apu_set_register(s, 1, 2,(apu_get_register(s, 1, 2)&0x00FF)| | ||
1264 | ( ((freq&0xFF)<<8)|0x10 )); | ||
1265 | apu_set_register(s, 1, 3, freq>>8); | ||
1266 | } | ||
1267 | |||
1268 | static void set_adc_rate(struct ess_state *s, unsigned rate) | ||
1269 | { | ||
1270 | u32 freq; | ||
1271 | |||
1272 | /* Sample Rate conversion APUs don't like 0x10000 for their rate */ | ||
1273 | if (rate > 47999) | ||
1274 | rate = 47999; | ||
1275 | if (rate < 4000) | ||
1276 | rate = 4000; | ||
1277 | |||
1278 | s->rateadc = rate; | ||
1279 | |||
1280 | freq = compute_rate(s, rate); | ||
1281 | |||
1282 | /* Load the frequency, turn on 6dB */ | ||
1283 | apu_set_register(s, 2, 2,(apu_get_register(s, 2, 2)&0x00FF)| | ||
1284 | ( ((freq&0xFF)<<8)|0x10 )); | ||
1285 | apu_set_register(s, 2, 3, freq>>8); | ||
1286 | apu_set_register(s, 3, 2,(apu_get_register(s, 3, 2)&0x00FF)| | ||
1287 | ( ((freq&0xFF)<<8)|0x10 )); | ||
1288 | apu_set_register(s, 3, 3, freq>>8); | ||
1289 | |||
1290 | /* fix mixer rate at 48khz. and its _must_ be 0x10000. */ | ||
1291 | freq = 0x10000; | ||
1292 | |||
1293 | apu_set_register(s, 4, 2,(apu_get_register(s, 4, 2)&0x00FF)| | ||
1294 | ( ((freq&0xFF)<<8)|0x10 )); | ||
1295 | apu_set_register(s, 4, 3, freq>>8); | ||
1296 | apu_set_register(s, 5, 2,(apu_get_register(s, 5, 2)&0x00FF)| | ||
1297 | ( ((freq&0xFF)<<8)|0x10 )); | ||
1298 | apu_set_register(s, 5, 3, freq>>8); | ||
1299 | } | ||
1300 | |||
1301 | /* Stop our host of recording apus */ | ||
1302 | static inline void stop_adc(struct ess_state *s) | ||
1303 | { | ||
1304 | /* XXX lets hope we don't have to lock around this */ | ||
1305 | if (! (s->enable & ADC_RUNNING)) return; | ||
1306 | |||
1307 | s->enable &= ~ADC_RUNNING; | ||
1308 | apu_set_register(s, 2, 0, apu_get_register(s, 2, 0)&0xFF0F); | ||
1309 | apu_set_register(s, 3, 0, apu_get_register(s, 3, 0)&0xFF0F); | ||
1310 | apu_set_register(s, 4, 0, apu_get_register(s, 2, 0)&0xFF0F); | ||
1311 | apu_set_register(s, 5, 0, apu_get_register(s, 3, 0)&0xFF0F); | ||
1312 | } | ||
1313 | |||
1314 | /* stop output apus */ | ||
1315 | static void stop_dac(struct ess_state *s) | ||
1316 | { | ||
1317 | /* XXX have to lock around this? */ | ||
1318 | if (! (s->enable & DAC_RUNNING)) return; | ||
1319 | |||
1320 | s->enable &= ~DAC_RUNNING; | ||
1321 | apu_set_register(s, 0, 0, apu_get_register(s, 0, 0)&0xFF0F); | ||
1322 | apu_set_register(s, 1, 0, apu_get_register(s, 1, 0)&0xFF0F); | ||
1323 | } | ||
1324 | |||
1325 | static void start_dac(struct ess_state *s) | ||
1326 | { | ||
1327 | /* XXX locks? */ | ||
1328 | if ( (s->dma_dac.mapped || s->dma_dac.count > 0) && | ||
1329 | s->dma_dac.ready && | ||
1330 | (! (s->enable & DAC_RUNNING)) ) { | ||
1331 | |||
1332 | s->enable |= DAC_RUNNING; | ||
1333 | |||
1334 | apu_set_register(s, 0, 0, | ||
1335 | (apu_get_register(s, 0, 0)&0xFF0F)|s->apu_mode[0]); | ||
1336 | |||
1337 | if((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_STEREO) | ||
1338 | apu_set_register(s, 1, 0, | ||
1339 | (apu_get_register(s, 1, 0)&0xFF0F)|s->apu_mode[1]); | ||
1340 | } | ||
1341 | } | ||
1342 | |||
1343 | static void start_adc(struct ess_state *s) | ||
1344 | { | ||
1345 | /* XXX locks? */ | ||
1346 | if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) | ||
1347 | && s->dma_adc.ready && (! (s->enable & ADC_RUNNING)) ) { | ||
1348 | |||
1349 | s->enable |= ADC_RUNNING; | ||
1350 | apu_set_register(s, 2, 0, | ||
1351 | (apu_get_register(s, 2, 0)&0xFF0F)|s->apu_mode[2]); | ||
1352 | apu_set_register(s, 4, 0, | ||
1353 | (apu_get_register(s, 4, 0)&0xFF0F)|s->apu_mode[4]); | ||
1354 | |||
1355 | if( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) { | ||
1356 | apu_set_register(s, 3, 0, | ||
1357 | (apu_get_register(s, 3, 0)&0xFF0F)|s->apu_mode[3]); | ||
1358 | apu_set_register(s, 5, 0, | ||
1359 | (apu_get_register(s, 5, 0)&0xFF0F)|s->apu_mode[5]); | ||
1360 | } | ||
1361 | |||
1362 | } | ||
1363 | } | ||
1364 | |||
1365 | |||
1366 | /* | ||
1367 | * Native play back driver | ||
1368 | */ | ||
1369 | |||
1370 | /* the mode passed should be already shifted and masked */ | ||
1371 | static void | ||
1372 | ess_play_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size) | ||
1373 | { | ||
1374 | u32 pa; | ||
1375 | u32 tmpval; | ||
1376 | int high_apu = 0; | ||
1377 | int channel; | ||
1378 | |||
1379 | M_printk("mode=%d rate=%d buf=%p len=%d.\n", | ||
1380 | mode, rate, buffer, size); | ||
1381 | |||
1382 | /* all maestro sizes are in 16bit words */ | ||
1383 | size >>=1; | ||
1384 | |||
1385 | if(mode&ESS_FMT_STEREO) { | ||
1386 | high_apu++; | ||
1387 | /* only 16/stereo gets size divided */ | ||
1388 | if(mode&ESS_FMT_16BIT) | ||
1389 | size>>=1; | ||
1390 | } | ||
1391 | |||
1392 | for(channel=0; channel <= high_apu; channel++) | ||
1393 | { | ||
1394 | pa = virt_to_bus(buffer); | ||
1395 | |||
1396 | /* set the wavecache control reg */ | ||
1397 | tmpval = (pa - 0x10) & 0xFFF8; | ||
1398 | if(!(mode & ESS_FMT_16BIT)) tmpval |= 4; | ||
1399 | if(mode & ESS_FMT_STEREO) tmpval |= 2; | ||
1400 | ess->apu_base[channel]=tmpval; | ||
1401 | wave_set_register(ess, ess->apu[channel]<<3, tmpval); | ||
1402 | |||
1403 | pa -= virt_to_bus(ess->card->dmapages); | ||
1404 | pa>>=1; /* words */ | ||
1405 | |||
1406 | /* base offset of dma calcs when reading the pointer | ||
1407 | on the left one */ | ||
1408 | if(!channel) ess->dma_dac.base = pa&0xFFFF; | ||
1409 | |||
1410 | pa|=0x00400000; /* System RAM */ | ||
1411 | |||
1412 | /* XXX the 16bit here might not be needed.. */ | ||
1413 | if((mode & ESS_FMT_STEREO) && (mode & ESS_FMT_16BIT)) { | ||
1414 | if(channel) | ||
1415 | pa|=0x00800000; /* Stereo */ | ||
1416 | pa>>=1; | ||
1417 | } | ||
1418 | |||
1419 | /* XXX think about endianess when writing these registers */ | ||
1420 | M_printk("maestro: ess_play_setup: APU[%d] pa = 0x%x\n", ess->apu[channel], pa); | ||
1421 | /* start of sample */ | ||
1422 | apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8); | ||
1423 | apu_set_register(ess, channel, 5, pa&0xFFFF); | ||
1424 | /* sample end */ | ||
1425 | apu_set_register(ess, channel, 6, (pa+size)&0xFFFF); | ||
1426 | /* setting loop len == sample len */ | ||
1427 | apu_set_register(ess, channel, 7, size); | ||
1428 | |||
1429 | /* clear effects/env.. */ | ||
1430 | apu_set_register(ess, channel, 8, 0x0000); | ||
1431 | /* set amp now to 0xd0 (?), low byte is 'amplitude dest'? */ | ||
1432 | apu_set_register(ess, channel, 9, 0xD000); | ||
1433 | |||
1434 | /* clear routing stuff */ | ||
1435 | apu_set_register(ess, channel, 11, 0x0000); | ||
1436 | /* dma on, no envelopes, filter to all 1s) */ | ||
1437 | apu_set_register(ess, channel, 0, 0x400F); | ||
1438 | |||
1439 | if(mode&ESS_FMT_16BIT) | ||
1440 | ess->apu_mode[channel]=0x10; | ||
1441 | else | ||
1442 | ess->apu_mode[channel]=0x30; | ||
1443 | |||
1444 | if(mode&ESS_FMT_STEREO) { | ||
1445 | /* set panning: left or right */ | ||
1446 | apu_set_register(ess, channel, 10, 0x8F00 | (channel ? 0 : 0x10)); | ||
1447 | ess->apu_mode[channel] += 0x10; | ||
1448 | } else | ||
1449 | apu_set_register(ess, channel, 10, 0x8F08); | ||
1450 | } | ||
1451 | |||
1452 | /* clear WP interrupts */ | ||
1453 | outw(1, ess->card->iobase+0x04); | ||
1454 | /* enable WP ints */ | ||
1455 | outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18); | ||
1456 | |||
1457 | /* go team! */ | ||
1458 | set_dac_rate(ess,rate); | ||
1459 | start_dac(ess); | ||
1460 | } | ||
1461 | |||
1462 | /* | ||
1463 | * Native record driver | ||
1464 | */ | ||
1465 | |||
1466 | /* again, passed mode is alrady shifted/masked */ | ||
1467 | static void | ||
1468 | ess_rec_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size) | ||
1469 | { | ||
1470 | int apu_step = 2; | ||
1471 | int channel; | ||
1472 | |||
1473 | M_printk("maestro: ess_rec_setup: mode=%d rate=%d buf=0x%p len=%d.\n", | ||
1474 | mode, rate, buffer, size); | ||
1475 | |||
1476 | /* all maestro sizes are in 16bit words */ | ||
1477 | size >>=1; | ||
1478 | |||
1479 | /* we're given the full size of the buffer, but | ||
1480 | in stereo each channel will only use its half */ | ||
1481 | if(mode&ESS_FMT_STEREO) { | ||
1482 | size >>=1; | ||
1483 | apu_step = 1; | ||
1484 | } | ||
1485 | |||
1486 | /* APU assignments: 2 = mono/left SRC | ||
1487 | 3 = right SRC | ||
1488 | 4 = mono/left Input Mixer | ||
1489 | 5 = right Input Mixer */ | ||
1490 | for(channel=2;channel<6;channel+=apu_step) | ||
1491 | { | ||
1492 | int i; | ||
1493 | int bsize, route; | ||
1494 | u32 pa; | ||
1495 | u32 tmpval; | ||
1496 | |||
1497 | /* data seems to flow from the codec, through an apu into | ||
1498 | the 'mixbuf' bit of page, then through the SRC apu | ||
1499 | and out to the real 'buffer'. ok. sure. */ | ||
1500 | |||
1501 | if(channel & 0x04) { | ||
1502 | /* ok, we're an input mixer going from adc | ||
1503 | through the mixbuf to the other apus */ | ||
1504 | |||
1505 | if(!(channel & 0x01)) { | ||
1506 | pa = virt_to_bus(ess->mixbuf); | ||
1507 | } else { | ||
1508 | pa = virt_to_bus(ess->mixbuf + (PAGE_SIZE >> 4)); | ||
1509 | } | ||
1510 | |||
1511 | /* we source from a 'magic' apu */ | ||
1512 | bsize = PAGE_SIZE >> 5; /* half of this channels alloc, in words */ | ||
1513 | route = 0x14 + (channel - 4); /* parallel in crap, see maestro reg 0xC [8-11] */ | ||
1514 | ess->apu_mode[channel] = 0x90; /* Input Mixer */ | ||
1515 | |||
1516 | } else { | ||
1517 | /* we're a rate converter taking | ||
1518 | input from the input apus and outputing it to | ||
1519 | system memory */ | ||
1520 | if(!(channel & 0x01)) { | ||
1521 | pa = virt_to_bus(buffer); | ||
1522 | } else { | ||
1523 | /* right channel records its split half. | ||
1524 | *2 accommodates for rampant shifting earlier */ | ||
1525 | pa = virt_to_bus(buffer + size*2); | ||
1526 | } | ||
1527 | |||
1528 | ess->apu_mode[channel] = 0xB0; /* Sample Rate Converter */ | ||
1529 | |||
1530 | bsize = size; | ||
1531 | /* get input from inputing apu */ | ||
1532 | route = channel + 2; | ||
1533 | } | ||
1534 | |||
1535 | M_printk("maestro: ess_rec_setup: getting pa 0x%x from %d\n",pa,channel); | ||
1536 | |||
1537 | /* set the wavecache control reg */ | ||
1538 | tmpval = (pa - 0x10) & 0xFFF8; | ||
1539 | ess->apu_base[channel]=tmpval; | ||
1540 | wave_set_register(ess, ess->apu[channel]<<3, tmpval); | ||
1541 | |||
1542 | pa -= virt_to_bus(ess->card->dmapages); | ||
1543 | pa>>=1; /* words */ | ||
1544 | |||
1545 | /* base offset of dma calcs when reading the pointer | ||
1546 | on this left one */ | ||
1547 | if(channel==2) ess->dma_adc.base = pa&0xFFFF; | ||
1548 | |||
1549 | pa|=0x00400000; /* bit 22 -> System RAM */ | ||
1550 | |||
1551 | M_printk("maestro: ess_rec_setup: APU[%d] pa = 0x%x size = 0x%x route = 0x%x\n", | ||
1552 | ess->apu[channel], pa, bsize, route); | ||
1553 | |||
1554 | /* Begin loading the APU */ | ||
1555 | for(i=0;i<15;i++) /* clear all PBRs */ | ||
1556 | apu_set_register(ess, channel, i, 0x0000); | ||
1557 | |||
1558 | apu_set_register(ess, channel, 0, 0x400F); | ||
1559 | |||
1560 | /* need to enable subgroups.. and we should probably | ||
1561 | have different groups for different /dev/dsps.. */ | ||
1562 | apu_set_register(ess, channel, 2, 0x8); | ||
1563 | |||
1564 | /* Load the buffer into the wave engine */ | ||
1565 | apu_set_register(ess, channel, 4, ((pa>>16)&0xFF)<<8); | ||
1566 | /* XXX reg is little endian.. */ | ||
1567 | apu_set_register(ess, channel, 5, pa&0xFFFF); | ||
1568 | apu_set_register(ess, channel, 6, (pa+bsize)&0xFFFF); | ||
1569 | apu_set_register(ess, channel, 7, bsize); | ||
1570 | |||
1571 | /* clear effects/env.. */ | ||
1572 | apu_set_register(ess, channel, 8, 0x00F0); | ||
1573 | |||
1574 | /* amplitude now? sure. why not. */ | ||
1575 | apu_set_register(ess, channel, 9, 0x0000); | ||
1576 | |||
1577 | /* set filter tune, radius, polar pan */ | ||
1578 | apu_set_register(ess, channel, 10, 0x8F08); | ||
1579 | |||
1580 | /* route input */ | ||
1581 | apu_set_register(ess, channel, 11, route); | ||
1582 | } | ||
1583 | |||
1584 | /* clear WP interrupts */ | ||
1585 | outw(1, ess->card->iobase+0x04); | ||
1586 | /* enable WP ints */ | ||
1587 | outw(inw(ess->card->iobase+0x18)|4, ess->card->iobase+0x18); | ||
1588 | |||
1589 | /* let 'er rip */ | ||
1590 | set_adc_rate(ess,rate); | ||
1591 | start_adc(ess); | ||
1592 | } | ||
1593 | /* --------------------------------------------------------------------- */ | ||
1594 | |||
1595 | static void set_dmaa(struct ess_state *s, unsigned int addr, unsigned int count) | ||
1596 | { | ||
1597 | M_printk("set_dmaa??\n"); | ||
1598 | } | ||
1599 | |||
1600 | static void set_dmac(struct ess_state *s, unsigned int addr, unsigned int count) | ||
1601 | { | ||
1602 | M_printk("set_dmac??\n"); | ||
1603 | } | ||
1604 | |||
1605 | /* Playback pointer */ | ||
1606 | static inline unsigned get_dmaa(struct ess_state *s) | ||
1607 | { | ||
1608 | int offset; | ||
1609 | |||
1610 | offset = apu_get_register(s,0,5); | ||
1611 | |||
1612 | /* M_printk("dmaa: offset: %d, base: %d\n",offset,s->dma_dac.base); */ | ||
1613 | |||
1614 | offset-=s->dma_dac.base; | ||
1615 | |||
1616 | return (offset&0xFFFE)<<1; /* hardware is in words */ | ||
1617 | } | ||
1618 | |||
1619 | /* Record pointer */ | ||
1620 | static inline unsigned get_dmac(struct ess_state *s) | ||
1621 | { | ||
1622 | int offset; | ||
1623 | |||
1624 | offset = apu_get_register(s,2,5); | ||
1625 | |||
1626 | /* M_printk("dmac: offset: %d, base: %d\n",offset,s->dma_adc.base); */ | ||
1627 | |||
1628 | /* The offset is an address not a position relative to base */ | ||
1629 | offset-=s->dma_adc.base; | ||
1630 | |||
1631 | return (offset&0xFFFE)<<1; /* hardware is in words */ | ||
1632 | } | ||
1633 | |||
1634 | /* | ||
1635 | * Meet Bob, the timer... | ||
1636 | */ | ||
1637 | |||
1638 | static irqreturn_t ess_interrupt(int irq, void *dev_id, struct pt_regs *regs); | ||
1639 | |||
1640 | static void stop_bob(struct ess_state *s) | ||
1641 | { | ||
1642 | /* Mask IDR 11,17 */ | ||
1643 | maestro_write(s, 0x11, maestro_read(s, 0x11)&~1); | ||
1644 | maestro_write(s, 0x17, maestro_read(s, 0x17)&~1); | ||
1645 | } | ||
1646 | |||
1647 | /* eventually we could be clever and limit bob ints | ||
1648 | to the frequency at which our smallest duration | ||
1649 | chunks may expire */ | ||
1650 | #define ESS_SYSCLK 50000000 | ||
1651 | static void start_bob(struct ess_state *s) | ||
1652 | { | ||
1653 | int prescale; | ||
1654 | int divide; | ||
1655 | |||
1656 | /* XXX make freq selector much smarter, see calc_bob_rate */ | ||
1657 | int freq = 200; | ||
1658 | |||
1659 | /* compute ideal interrupt frequency for buffer size & play rate */ | ||
1660 | /* first, find best prescaler value to match freq */ | ||
1661 | for(prescale=5;prescale<12;prescale++) | ||
1662 | if(freq > (ESS_SYSCLK>>(prescale+9))) | ||
1663 | break; | ||
1664 | |||
1665 | /* next, back off prescaler whilst getting divider into optimum range */ | ||
1666 | divide=1; | ||
1667 | while((prescale > 5) && (divide<32)) | ||
1668 | { | ||
1669 | prescale--; | ||
1670 | divide <<=1; | ||
1671 | } | ||
1672 | divide>>=1; | ||
1673 | |||
1674 | /* now fine-tune the divider for best match */ | ||
1675 | for(;divide<31;divide++) | ||
1676 | if(freq >= ((ESS_SYSCLK>>(prescale+9))/(divide+1))) | ||
1677 | break; | ||
1678 | |||
1679 | /* divide = 0 is illegal, but don't let prescale = 4! */ | ||
1680 | if(divide == 0) | ||
1681 | { | ||
1682 | divide++; | ||
1683 | if(prescale>5) | ||
1684 | prescale--; | ||
1685 | } | ||
1686 | |||
1687 | maestro_write(s, 6, 0x9000 | (prescale<<5) | divide); /* set reg */ | ||
1688 | |||
1689 | /* Now set IDR 11/17 */ | ||
1690 | maestro_write(s, 0x11, maestro_read(s, 0x11)|1); | ||
1691 | maestro_write(s, 0x17, maestro_read(s, 0x17)|1); | ||
1692 | } | ||
1693 | /* --------------------------------------------------------------------- */ | ||
1694 | |||
1695 | /* this quickly calculates the frequency needed for bob | ||
1696 | and sets it if its different than what bob is | ||
1697 | currently running at. its called often so | ||
1698 | needs to be fairly quick. */ | ||
1699 | #define BOB_MIN 50 | ||
1700 | #define BOB_MAX 400 | ||
1701 | static void calc_bob_rate(struct ess_state *s) { | ||
1702 | #if 0 /* this thing tries to set the frequency of bob such that | ||
1703 | there are 2 interrupts / buffer walked by the dac/adc. That | ||
1704 | is probably very wrong for people who actually care about | ||
1705 | mid buffer positioning. it should be calculated as bytes/interrupt | ||
1706 | and that needs to be decided :) so for now just use the static 150 | ||
1707 | in start_bob.*/ | ||
1708 | |||
1709 | unsigned int dac_rate=2,adc_rate=1,newrate; | ||
1710 | static int israte=-1; | ||
1711 | |||
1712 | if (s->dma_dac.fragsize == 0) dac_rate = BOB_MIN; | ||
1713 | else { | ||
1714 | dac_rate = (2 * s->ratedac * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) / | ||
1715 | (s->dma_dac.fragsize) ; | ||
1716 | } | ||
1717 | |||
1718 | if (s->dma_adc.fragsize == 0) adc_rate = BOB_MIN; | ||
1719 | else { | ||
1720 | adc_rate = (2 * s->rateadc * sample_size[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]) / | ||
1721 | (s->dma_adc.fragsize) ; | ||
1722 | } | ||
1723 | |||
1724 | if(dac_rate > adc_rate) newrate = adc_rate; | ||
1725 | else newrate=dac_rate; | ||
1726 | |||
1727 | if(newrate > BOB_MAX) newrate = BOB_MAX; | ||
1728 | else { | ||
1729 | if(newrate < BOB_MIN) | ||
1730 | newrate = BOB_MIN; | ||
1731 | } | ||
1732 | |||
1733 | if( israte != newrate) { | ||
1734 | printk("dac: %d adc: %d rate: %d\n",dac_rate,adc_rate,israte); | ||
1735 | israte=newrate; | ||
1736 | } | ||
1737 | #endif | ||
1738 | |||
1739 | } | ||
1740 | |||
1741 | static int | ||
1742 | prog_dmabuf(struct ess_state *s, unsigned rec) | ||
1743 | { | ||
1744 | struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac; | ||
1745 | unsigned rate = rec ? s->rateadc : s->ratedac; | ||
1746 | unsigned bytepersec; | ||
1747 | unsigned bufs; | ||
1748 | unsigned char fmt; | ||
1749 | unsigned long flags; | ||
1750 | |||
1751 | spin_lock_irqsave(&s->lock, flags); | ||
1752 | fmt = s->fmt; | ||
1753 | if (rec) { | ||
1754 | stop_adc(s); | ||
1755 | fmt >>= ESS_ADC_SHIFT; | ||
1756 | } else { | ||
1757 | stop_dac(s); | ||
1758 | fmt >>= ESS_DAC_SHIFT; | ||
1759 | } | ||
1760 | spin_unlock_irqrestore(&s->lock, flags); | ||
1761 | fmt &= ESS_FMT_MASK; | ||
1762 | |||
1763 | db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; | ||
1764 | |||
1765 | /* this algorithm is a little nuts.. where did /1000 come from? */ | ||
1766 | bytepersec = rate << sample_shift[fmt]; | ||
1767 | bufs = PAGE_SIZE << db->buforder; | ||
1768 | if (db->ossfragshift) { | ||
1769 | if ((1000 << db->ossfragshift) < bytepersec) | ||
1770 | db->fragshift = ld2(bytepersec/1000); | ||
1771 | else | ||
1772 | db->fragshift = db->ossfragshift; | ||
1773 | } else { | ||
1774 | db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); | ||
1775 | if (db->fragshift < 3) | ||
1776 | db->fragshift = 3; | ||
1777 | } | ||
1778 | db->numfrag = bufs >> db->fragshift; | ||
1779 | while (db->numfrag < 4 && db->fragshift > 3) { | ||
1780 | db->fragshift--; | ||
1781 | db->numfrag = bufs >> db->fragshift; | ||
1782 | } | ||
1783 | db->fragsize = 1 << db->fragshift; | ||
1784 | if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) | ||
1785 | db->numfrag = db->ossmaxfrags; | ||
1786 | db->fragsamples = db->fragsize >> sample_shift[fmt]; | ||
1787 | db->dmasize = db->numfrag << db->fragshift; | ||
1788 | |||
1789 | M_printk("maestro: setup oss: numfrag: %d fragsize: %d dmasize: %d\n",db->numfrag,db->fragsize,db->dmasize); | ||
1790 | |||
1791 | memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize); | ||
1792 | |||
1793 | spin_lock_irqsave(&s->lock, flags); | ||
1794 | if (rec) | ||
1795 | ess_rec_setup(s, fmt, s->rateadc, db->rawbuf, db->dmasize); | ||
1796 | else | ||
1797 | ess_play_setup(s, fmt, s->ratedac, db->rawbuf, db->dmasize); | ||
1798 | |||
1799 | spin_unlock_irqrestore(&s->lock, flags); | ||
1800 | db->ready = 1; | ||
1801 | |||
1802 | return 0; | ||
1803 | } | ||
1804 | |||
1805 | static __inline__ void | ||
1806 | clear_advance(struct ess_state *s) | ||
1807 | { | ||
1808 | unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80; | ||
1809 | |||
1810 | unsigned char *buf = s->dma_dac.rawbuf; | ||
1811 | unsigned bsize = s->dma_dac.dmasize; | ||
1812 | unsigned bptr = s->dma_dac.swptr; | ||
1813 | unsigned len = s->dma_dac.fragsize; | ||
1814 | |||
1815 | if (bptr + len > bsize) { | ||
1816 | unsigned x = bsize - bptr; | ||
1817 | memset(buf + bptr, c, x); | ||
1818 | /* account for wrapping? */ | ||
1819 | bptr = 0; | ||
1820 | len -= x; | ||
1821 | } | ||
1822 | memset(buf + bptr, c, len); | ||
1823 | } | ||
1824 | |||
1825 | /* call with spinlock held! */ | ||
1826 | static void | ||
1827 | ess_update_ptr(struct ess_state *s) | ||
1828 | { | ||
1829 | unsigned hwptr; | ||
1830 | int diff; | ||
1831 | |||
1832 | /* update ADC pointer */ | ||
1833 | if (s->dma_adc.ready) { | ||
1834 | /* oh boy should this all be re-written. everything in the current code paths think | ||
1835 | that the various counters/pointers are expressed in bytes to the user but we have | ||
1836 | two apus doing stereo stuff so we fix it up here.. it propagates to all the various | ||
1837 | counters from here. */ | ||
1838 | if ( s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) { | ||
1839 | hwptr = (get_dmac(s)*2) % s->dma_adc.dmasize; | ||
1840 | } else { | ||
1841 | hwptr = get_dmac(s) % s->dma_adc.dmasize; | ||
1842 | } | ||
1843 | diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; | ||
1844 | s->dma_adc.hwptr = hwptr; | ||
1845 | s->dma_adc.total_bytes += diff; | ||
1846 | s->dma_adc.count += diff; | ||
1847 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
1848 | wake_up(&s->dma_adc.wait); | ||
1849 | if (!s->dma_adc.mapped) { | ||
1850 | if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { | ||
1851 | /* FILL ME | ||
1852 | wrindir(s, SV_CIENABLE, s->enable); */ | ||
1853 | stop_adc(s); | ||
1854 | /* brute force everyone back in sync, sigh */ | ||
1855 | s->dma_adc.count = 0; | ||
1856 | s->dma_adc.swptr = 0; | ||
1857 | s->dma_adc.hwptr = 0; | ||
1858 | s->dma_adc.error++; | ||
1859 | } | ||
1860 | } | ||
1861 | } | ||
1862 | /* update DAC pointer */ | ||
1863 | if (s->dma_dac.ready) { | ||
1864 | hwptr = get_dmaa(s) % s->dma_dac.dmasize; | ||
1865 | /* the apu only reports the length it has seen, not the | ||
1866 | length of the memory that has been used (the WP | ||
1867 | knows that) */ | ||
1868 | if ( ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK) == (ESS_FMT_STEREO|ESS_FMT_16BIT)) | ||
1869 | hwptr<<=1; | ||
1870 | |||
1871 | diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize; | ||
1872 | /* M_printk("updating dac: hwptr: %d diff: %d\n",hwptr,diff);*/ | ||
1873 | s->dma_dac.hwptr = hwptr; | ||
1874 | s->dma_dac.total_bytes += diff; | ||
1875 | if (s->dma_dac.mapped) { | ||
1876 | s->dma_dac.count += diff; | ||
1877 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) { | ||
1878 | wake_up(&s->dma_dac.wait); | ||
1879 | } | ||
1880 | } else { | ||
1881 | s->dma_dac.count -= diff; | ||
1882 | /* M_printk("maestro: ess_update_ptr: diff: %d, count: %d\n", diff, s->dma_dac.count); */ | ||
1883 | if (s->dma_dac.count <= 0) { | ||
1884 | M_printk("underflow! diff: %d count: %d hw: %d sw: %d\n", diff, s->dma_dac.count, | ||
1885 | hwptr, s->dma_dac.swptr); | ||
1886 | /* FILL ME | ||
1887 | wrindir(s, SV_CIENABLE, s->enable); */ | ||
1888 | /* XXX how on earth can calling this with the lock held work.. */ | ||
1889 | stop_dac(s); | ||
1890 | /* brute force everyone back in sync, sigh */ | ||
1891 | s->dma_dac.count = 0; | ||
1892 | s->dma_dac.swptr = hwptr; | ||
1893 | s->dma_dac.error++; | ||
1894 | } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) { | ||
1895 | clear_advance(s); | ||
1896 | s->dma_dac.endcleared = 1; | ||
1897 | } | ||
1898 | if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) { | ||
1899 | wake_up(&s->dma_dac.wait); | ||
1900 | /* printk("waking up DAC count: %d sw: %d hw: %d\n",s->dma_dac.count, s->dma_dac.swptr, | ||
1901 | hwptr);*/ | ||
1902 | } | ||
1903 | } | ||
1904 | } | ||
1905 | } | ||
1906 | |||
1907 | static irqreturn_t | ||
1908 | ess_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1909 | { | ||
1910 | struct ess_state *s; | ||
1911 | struct ess_card *c = (struct ess_card *)dev_id; | ||
1912 | int i; | ||
1913 | u32 event; | ||
1914 | |||
1915 | if ( ! (event = inb(c->iobase+0x1A)) ) | ||
1916 | return IRQ_NONE; | ||
1917 | |||
1918 | outw(inw(c->iobase+4)&1, c->iobase+4); | ||
1919 | |||
1920 | /* M_printk("maestro int: %x\n",event);*/ | ||
1921 | if(event&(1<<6)) | ||
1922 | { | ||
1923 | int x; | ||
1924 | enum {UP_EVT, DOWN_EVT, MUTE_EVT} vol_evt; | ||
1925 | int volume; | ||
1926 | |||
1927 | /* Figure out which volume control button was pushed, | ||
1928 | based on differences from the default register | ||
1929 | values. */ | ||
1930 | x = inb(c->iobase+0x1c); | ||
1931 | if (x&1) vol_evt = MUTE_EVT; | ||
1932 | else if (((x>>1)&7) > 4) vol_evt = UP_EVT; | ||
1933 | else vol_evt = DOWN_EVT; | ||
1934 | |||
1935 | /* Reset the volume control registers. */ | ||
1936 | outb(0x88, c->iobase+0x1c); | ||
1937 | outb(0x88, c->iobase+0x1d); | ||
1938 | outb(0x88, c->iobase+0x1e); | ||
1939 | outb(0x88, c->iobase+0x1f); | ||
1940 | |||
1941 | /* Deal with the button press in a hammer-handed | ||
1942 | manner by adjusting the master mixer volume. */ | ||
1943 | volume = c->mix.mixer_state[0] & 0xff; | ||
1944 | if (vol_evt == UP_EVT) { | ||
1945 | volume += 5; | ||
1946 | if (volume > 100) | ||
1947 | volume = 100; | ||
1948 | } | ||
1949 | else if (vol_evt == DOWN_EVT) { | ||
1950 | volume -= 5; | ||
1951 | if (volume < 0) | ||
1952 | volume = 0; | ||
1953 | } else { | ||
1954 | /* vol_evt == MUTE_EVT */ | ||
1955 | if (volume == 0) | ||
1956 | volume = c->dock_mute_vol; | ||
1957 | else { | ||
1958 | c->dock_mute_vol = volume; | ||
1959 | volume = 0; | ||
1960 | } | ||
1961 | } | ||
1962 | set_mixer (c, 0, (volume << 8) | volume); | ||
1963 | } | ||
1964 | |||
1965 | /* Ack all the interrupts. */ | ||
1966 | outb(0xFF, c->iobase+0x1A); | ||
1967 | |||
1968 | /* | ||
1969 | * Update the pointers for all APU's we are running. | ||
1970 | */ | ||
1971 | for(i=0;i<NR_DSPS;i++) | ||
1972 | { | ||
1973 | s=&c->channels[i]; | ||
1974 | if(s->dev_audio == -1) | ||
1975 | break; | ||
1976 | spin_lock(&s->lock); | ||
1977 | ess_update_ptr(s); | ||
1978 | spin_unlock(&s->lock); | ||
1979 | } | ||
1980 | return IRQ_HANDLED; | ||
1981 | } | ||
1982 | |||
1983 | |||
1984 | /* --------------------------------------------------------------------- */ | ||
1985 | |||
1986 | static const char invalid_magic[] = KERN_CRIT "maestro: invalid magic value in %s\n"; | ||
1987 | |||
1988 | #define VALIDATE_MAGIC(FOO,MAG) \ | ||
1989 | ({ \ | ||
1990 | if (!(FOO) || (FOO)->magic != MAG) { \ | ||
1991 | printk(invalid_magic,__FUNCTION__); \ | ||
1992 | return -ENXIO; \ | ||
1993 | } \ | ||
1994 | }) | ||
1995 | |||
1996 | #define VALIDATE_STATE(a) VALIDATE_MAGIC(a,ESS_STATE_MAGIC) | ||
1997 | #define VALIDATE_CARD(a) VALIDATE_MAGIC(a,ESS_CARD_MAGIC) | ||
1998 | |||
1999 | static void set_mixer(struct ess_card *card,unsigned int mixer, unsigned int val ) | ||
2000 | { | ||
2001 | unsigned int left,right; | ||
2002 | /* cleanse input a little */ | ||
2003 | right = ((val >> 8) & 0xff) ; | ||
2004 | left = (val & 0xff) ; | ||
2005 | |||
2006 | if(right > 100) right = 100; | ||
2007 | if(left > 100) left = 100; | ||
2008 | |||
2009 | card->mix.mixer_state[mixer]=(right << 8) | left; | ||
2010 | card->mix.write_mixer(card,mixer,left,right); | ||
2011 | } | ||
2012 | |||
2013 | static void | ||
2014 | mixer_push_state(struct ess_card *card) | ||
2015 | { | ||
2016 | int i; | ||
2017 | for(i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) { | ||
2018 | if( ! supported_mixer(card,i)) continue; | ||
2019 | |||
2020 | set_mixer(card,i,card->mix.mixer_state[i]); | ||
2021 | } | ||
2022 | } | ||
2023 | |||
2024 | static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg) | ||
2025 | { | ||
2026 | int i, val=0; | ||
2027 | unsigned long flags; | ||
2028 | void __user *argp = (void __user *)arg; | ||
2029 | int __user *p = argp; | ||
2030 | |||
2031 | VALIDATE_CARD(card); | ||
2032 | if (cmd == SOUND_MIXER_INFO) { | ||
2033 | mixer_info info; | ||
2034 | memset(&info, 0, sizeof(info)); | ||
2035 | strlcpy(info.id, card_names[card->card_type], sizeof(info.id)); | ||
2036 | strlcpy(info.name, card_names[card->card_type], sizeof(info.name)); | ||
2037 | info.modify_counter = card->mix.modcnt; | ||
2038 | if (copy_to_user(argp, &info, sizeof(info))) | ||
2039 | return -EFAULT; | ||
2040 | return 0; | ||
2041 | } | ||
2042 | if (cmd == SOUND_OLD_MIXER_INFO) { | ||
2043 | _old_mixer_info info; | ||
2044 | memset(&info, 0, sizeof(info)); | ||
2045 | strlcpy(info.id, card_names[card->card_type], sizeof(info.id)); | ||
2046 | strlcpy(info.name, card_names[card->card_type], sizeof(info.name)); | ||
2047 | if (copy_to_user(argp, &info, sizeof(info))) | ||
2048 | return -EFAULT; | ||
2049 | return 0; | ||
2050 | } | ||
2051 | if (cmd == OSS_GETVERSION) | ||
2052 | return put_user(SOUND_VERSION, p); | ||
2053 | |||
2054 | if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int)) | ||
2055 | return -EINVAL; | ||
2056 | |||
2057 | if (_IOC_DIR(cmd) == _IOC_READ) { | ||
2058 | switch (_IOC_NR(cmd)) { | ||
2059 | case SOUND_MIXER_RECSRC: /* give them the current record source */ | ||
2060 | |||
2061 | if(!card->mix.recmask_io) { | ||
2062 | val = 0; | ||
2063 | } else { | ||
2064 | spin_lock_irqsave(&card->lock, flags); | ||
2065 | val = card->mix.recmask_io(card,1,0); | ||
2066 | spin_unlock_irqrestore(&card->lock, flags); | ||
2067 | } | ||
2068 | break; | ||
2069 | |||
2070 | case SOUND_MIXER_DEVMASK: /* give them the supported mixers */ | ||
2071 | val = card->mix.supported_mixers; | ||
2072 | break; | ||
2073 | |||
2074 | case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ | ||
2075 | val = card->mix.record_sources; | ||
2076 | break; | ||
2077 | |||
2078 | case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ | ||
2079 | val = card->mix.stereo_mixers; | ||
2080 | break; | ||
2081 | |||
2082 | case SOUND_MIXER_CAPS: | ||
2083 | val = SOUND_CAP_EXCL_INPUT; | ||
2084 | break; | ||
2085 | |||
2086 | default: /* read a specific mixer */ | ||
2087 | i = _IOC_NR(cmd); | ||
2088 | |||
2089 | if ( ! supported_mixer(card,i)) | ||
2090 | return -EINVAL; | ||
2091 | |||
2092 | /* do we ever want to touch the hardware? */ | ||
2093 | /* spin_lock_irqsave(&card->lock, flags); | ||
2094 | val = card->mix.read_mixer(card,i); | ||
2095 | spin_unlock_irqrestore(&card->lock, flags);*/ | ||
2096 | |||
2097 | val = card->mix.mixer_state[i]; | ||
2098 | /* M_printk("returned 0x%x for mixer %d\n",val,i);*/ | ||
2099 | |||
2100 | break; | ||
2101 | } | ||
2102 | return put_user(val, p); | ||
2103 | } | ||
2104 | |||
2105 | if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ)) | ||
2106 | return -EINVAL; | ||
2107 | |||
2108 | card->mix.modcnt++; | ||
2109 | |||
2110 | if (get_user(val, p)) | ||
2111 | return -EFAULT; | ||
2112 | |||
2113 | switch (_IOC_NR(cmd)) { | ||
2114 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
2115 | |||
2116 | if (!card->mix.recmask_io) return -EINVAL; | ||
2117 | if(!val) return 0; | ||
2118 | if(! (val &= card->mix.record_sources)) return -EINVAL; | ||
2119 | |||
2120 | spin_lock_irqsave(&card->lock, flags); | ||
2121 | card->mix.recmask_io(card,0,val); | ||
2122 | spin_unlock_irqrestore(&card->lock, flags); | ||
2123 | return 0; | ||
2124 | |||
2125 | default: | ||
2126 | i = _IOC_NR(cmd); | ||
2127 | |||
2128 | if ( ! supported_mixer(card,i)) | ||
2129 | return -EINVAL; | ||
2130 | |||
2131 | spin_lock_irqsave(&card->lock, flags); | ||
2132 | set_mixer(card,i,val); | ||
2133 | spin_unlock_irqrestore(&card->lock, flags); | ||
2134 | |||
2135 | return 0; | ||
2136 | } | ||
2137 | } | ||
2138 | |||
2139 | /* --------------------------------------------------------------------- */ | ||
2140 | static int ess_open_mixdev(struct inode *inode, struct file *file) | ||
2141 | { | ||
2142 | unsigned int minor = iminor(inode); | ||
2143 | struct ess_card *card = NULL; | ||
2144 | struct pci_dev *pdev = NULL; | ||
2145 | struct pci_driver *drvr; | ||
2146 | |||
2147 | while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { | ||
2148 | drvr = pci_dev_driver (pdev); | ||
2149 | if (drvr == &maestro_pci_driver) { | ||
2150 | card = (struct ess_card*)pci_get_drvdata (pdev); | ||
2151 | if (!card) | ||
2152 | continue; | ||
2153 | if (card->dev_mixer == minor) | ||
2154 | break; | ||
2155 | } | ||
2156 | } | ||
2157 | if (!card) | ||
2158 | return -ENODEV; | ||
2159 | file->private_data = card; | ||
2160 | return nonseekable_open(inode, file); | ||
2161 | } | ||
2162 | |||
2163 | static int ess_release_mixdev(struct inode *inode, struct file *file) | ||
2164 | { | ||
2165 | struct ess_card *card = (struct ess_card *)file->private_data; | ||
2166 | |||
2167 | VALIDATE_CARD(card); | ||
2168 | |||
2169 | return 0; | ||
2170 | } | ||
2171 | |||
2172 | static int ess_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
2173 | { | ||
2174 | struct ess_card *card = (struct ess_card *)file->private_data; | ||
2175 | |||
2176 | VALIDATE_CARD(card); | ||
2177 | |||
2178 | return mixer_ioctl(card, cmd, arg); | ||
2179 | } | ||
2180 | |||
2181 | static /*const*/ struct file_operations ess_mixer_fops = { | ||
2182 | .owner = THIS_MODULE, | ||
2183 | .llseek = no_llseek, | ||
2184 | .ioctl = ess_ioctl_mixdev, | ||
2185 | .open = ess_open_mixdev, | ||
2186 | .release = ess_release_mixdev, | ||
2187 | }; | ||
2188 | |||
2189 | /* --------------------------------------------------------------------- */ | ||
2190 | |||
2191 | static int drain_dac(struct ess_state *s, int nonblock) | ||
2192 | { | ||
2193 | DECLARE_WAITQUEUE(wait,current); | ||
2194 | unsigned long flags; | ||
2195 | int count; | ||
2196 | signed long tmo; | ||
2197 | |||
2198 | if (s->dma_dac.mapped || !s->dma_dac.ready) | ||
2199 | return 0; | ||
2200 | current->state = TASK_INTERRUPTIBLE; | ||
2201 | add_wait_queue(&s->dma_dac.wait, &wait); | ||
2202 | for (;;) { | ||
2203 | /* XXX uhm.. questionable locking*/ | ||
2204 | spin_lock_irqsave(&s->lock, flags); | ||
2205 | count = s->dma_dac.count; | ||
2206 | spin_unlock_irqrestore(&s->lock, flags); | ||
2207 | if (count <= 0) | ||
2208 | break; | ||
2209 | if (signal_pending(current)) | ||
2210 | break; | ||
2211 | if (nonblock) { | ||
2212 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
2213 | current->state = TASK_RUNNING; | ||
2214 | return -EBUSY; | ||
2215 | } | ||
2216 | tmo = (count * HZ) / s->ratedac; | ||
2217 | tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]; | ||
2218 | /* XXX this is just broken. someone is waking us up alot, or schedule_timeout is broken. | ||
2219 | or something. who cares. - zach */ | ||
2220 | if (!schedule_timeout(tmo ? tmo : 1) && tmo) | ||
2221 | M_printk(KERN_DEBUG "maestro: dma timed out?? %ld\n",jiffies); | ||
2222 | } | ||
2223 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
2224 | current->state = TASK_RUNNING; | ||
2225 | if (signal_pending(current)) | ||
2226 | return -ERESTARTSYS; | ||
2227 | return 0; | ||
2228 | } | ||
2229 | |||
2230 | /* --------------------------------------------------------------------- */ | ||
2231 | /* Zach sez: "god this is gross.." */ | ||
2232 | static int | ||
2233 | comb_stereo(unsigned char *real_buffer,unsigned char *tmp_buffer, int offset, | ||
2234 | int count, int bufsize) | ||
2235 | { | ||
2236 | /* No such thing as stereo recording, so we | ||
2237 | use dual input mixers. which means we have to | ||
2238 | combine mono to stereo buffer. yuck. | ||
2239 | |||
2240 | but we don't have to be able to work a byte at a time..*/ | ||
2241 | |||
2242 | unsigned char *so,*left,*right; | ||
2243 | int i; | ||
2244 | |||
2245 | so = tmp_buffer; | ||
2246 | left = real_buffer + offset; | ||
2247 | right = real_buffer + bufsize/2 + offset; | ||
2248 | |||
2249 | /* M_printk("comb_stereo writing %d to %p from %p and %p, offset: %d size: %d\n",count/2, tmp_buffer,left,right,offset,bufsize);*/ | ||
2250 | |||
2251 | for(i=count/4; i ; i--) { | ||
2252 | (*(so+2)) = *(right++); | ||
2253 | (*(so+3)) = *(right++); | ||
2254 | (*so) = *(left++); | ||
2255 | (*(so+1)) = *(left++); | ||
2256 | so+=4; | ||
2257 | } | ||
2258 | |||
2259 | return 0; | ||
2260 | } | ||
2261 | |||
2262 | /* in this loop, dma_adc.count signifies the amount of data thats waiting | ||
2263 | to be copied to the user's buffer. it is filled by the interrupt | ||
2264 | handler and drained by this loop. */ | ||
2265 | static ssize_t | ||
2266 | ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
2267 | { | ||
2268 | struct ess_state *s = (struct ess_state *)file->private_data; | ||
2269 | ssize_t ret; | ||
2270 | unsigned long flags; | ||
2271 | unsigned swptr; | ||
2272 | int cnt; | ||
2273 | unsigned char *combbuf = NULL; | ||
2274 | |||
2275 | VALIDATE_STATE(s); | ||
2276 | if (s->dma_adc.mapped) | ||
2277 | return -ENXIO; | ||
2278 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
2279 | return ret; | ||
2280 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
2281 | return -EFAULT; | ||
2282 | if(!(combbuf = kmalloc(count,GFP_KERNEL))) | ||
2283 | return -ENOMEM; | ||
2284 | ret = 0; | ||
2285 | |||
2286 | calc_bob_rate(s); | ||
2287 | |||
2288 | while (count > 0) { | ||
2289 | spin_lock_irqsave(&s->lock, flags); | ||
2290 | /* remember, all these things are expressed in bytes to be | ||
2291 | sent to the user.. hence the evil / 2 down below */ | ||
2292 | swptr = s->dma_adc.swptr; | ||
2293 | cnt = s->dma_adc.dmasize-swptr; | ||
2294 | if (s->dma_adc.count < cnt) | ||
2295 | cnt = s->dma_adc.count; | ||
2296 | spin_unlock_irqrestore(&s->lock, flags); | ||
2297 | |||
2298 | if (cnt > count) | ||
2299 | cnt = count; | ||
2300 | |||
2301 | if ( cnt > 0 ) cnt &= ~3; | ||
2302 | |||
2303 | if (cnt <= 0) { | ||
2304 | start_adc(s); | ||
2305 | if (file->f_flags & O_NONBLOCK) | ||
2306 | { | ||
2307 | ret = ret ? ret : -EAGAIN; | ||
2308 | goto rec_return_free; | ||
2309 | } | ||
2310 | if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) { | ||
2311 | if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
2312 | s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, | ||
2313 | s->dma_adc.hwptr, s->dma_adc.swptr); | ||
2314 | stop_adc(s); | ||
2315 | spin_lock_irqsave(&s->lock, flags); | ||
2316 | set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift); | ||
2317 | /* program enhanced mode registers */ | ||
2318 | /* FILL ME */ | ||
2319 | /* wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8); | ||
2320 | wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1); */ | ||
2321 | s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0; | ||
2322 | spin_unlock_irqrestore(&s->lock, flags); | ||
2323 | } | ||
2324 | if (signal_pending(current)) | ||
2325 | { | ||
2326 | ret = ret ? ret : -ERESTARTSYS; | ||
2327 | goto rec_return_free; | ||
2328 | } | ||
2329 | continue; | ||
2330 | } | ||
2331 | |||
2332 | if(s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) { | ||
2333 | /* swptr/2 so that we know the real offset in each apu's buffer */ | ||
2334 | comb_stereo(s->dma_adc.rawbuf,combbuf,swptr/2,cnt,s->dma_adc.dmasize); | ||
2335 | if (copy_to_user(buffer, combbuf, cnt)) { | ||
2336 | ret = ret ? ret : -EFAULT; | ||
2337 | goto rec_return_free; | ||
2338 | } | ||
2339 | } else { | ||
2340 | if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { | ||
2341 | ret = ret ? ret : -EFAULT; | ||
2342 | goto rec_return_free; | ||
2343 | } | ||
2344 | } | ||
2345 | |||
2346 | swptr = (swptr + cnt) % s->dma_adc.dmasize; | ||
2347 | spin_lock_irqsave(&s->lock, flags); | ||
2348 | s->dma_adc.swptr = swptr; | ||
2349 | s->dma_adc.count -= cnt; | ||
2350 | spin_unlock_irqrestore(&s->lock, flags); | ||
2351 | count -= cnt; | ||
2352 | buffer += cnt; | ||
2353 | ret += cnt; | ||
2354 | start_adc(s); | ||
2355 | } | ||
2356 | |||
2357 | rec_return_free: | ||
2358 | kfree(combbuf); | ||
2359 | return ret; | ||
2360 | } | ||
2361 | |||
2362 | static ssize_t | ||
2363 | ess_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
2364 | { | ||
2365 | struct ess_state *s = (struct ess_state *)file->private_data; | ||
2366 | ssize_t ret; | ||
2367 | unsigned long flags; | ||
2368 | unsigned swptr; | ||
2369 | int cnt; | ||
2370 | |||
2371 | VALIDATE_STATE(s); | ||
2372 | if (s->dma_dac.mapped) | ||
2373 | return -ENXIO; | ||
2374 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
2375 | return ret; | ||
2376 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
2377 | return -EFAULT; | ||
2378 | ret = 0; | ||
2379 | |||
2380 | calc_bob_rate(s); | ||
2381 | |||
2382 | while (count > 0) { | ||
2383 | spin_lock_irqsave(&s->lock, flags); | ||
2384 | |||
2385 | if (s->dma_dac.count < 0) { | ||
2386 | s->dma_dac.count = 0; | ||
2387 | s->dma_dac.swptr = s->dma_dac.hwptr; | ||
2388 | } | ||
2389 | swptr = s->dma_dac.swptr; | ||
2390 | |||
2391 | cnt = s->dma_dac.dmasize-swptr; | ||
2392 | |||
2393 | if (s->dma_dac.count + cnt > s->dma_dac.dmasize) | ||
2394 | cnt = s->dma_dac.dmasize - s->dma_dac.count; | ||
2395 | |||
2396 | spin_unlock_irqrestore(&s->lock, flags); | ||
2397 | |||
2398 | if (cnt > count) | ||
2399 | cnt = count; | ||
2400 | |||
2401 | if (cnt <= 0) { | ||
2402 | start_dac(s); | ||
2403 | if (file->f_flags & O_NONBLOCK) { | ||
2404 | if(!ret) ret = -EAGAIN; | ||
2405 | goto return_free; | ||
2406 | } | ||
2407 | if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) { | ||
2408 | if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
2409 | s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, | ||
2410 | s->dma_dac.hwptr, s->dma_dac.swptr); | ||
2411 | stop_dac(s); | ||
2412 | spin_lock_irqsave(&s->lock, flags); | ||
2413 | set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift); | ||
2414 | /* program enhanced mode registers */ | ||
2415 | /* wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8); | ||
2416 | wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1); */ | ||
2417 | /* FILL ME */ | ||
2418 | s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0; | ||
2419 | spin_unlock_irqrestore(&s->lock, flags); | ||
2420 | } | ||
2421 | if (signal_pending(current)) { | ||
2422 | if (!ret) ret = -ERESTARTSYS; | ||
2423 | goto return_free; | ||
2424 | } | ||
2425 | continue; | ||
2426 | } | ||
2427 | if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { | ||
2428 | if (!ret) ret = -EFAULT; | ||
2429 | goto return_free; | ||
2430 | } | ||
2431 | /* printk("wrote %d bytes at sw: %d cnt: %d while hw: %d\n",cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr);*/ | ||
2432 | |||
2433 | swptr = (swptr + cnt) % s->dma_dac.dmasize; | ||
2434 | |||
2435 | spin_lock_irqsave(&s->lock, flags); | ||
2436 | s->dma_dac.swptr = swptr; | ||
2437 | s->dma_dac.count += cnt; | ||
2438 | s->dma_dac.endcleared = 0; | ||
2439 | spin_unlock_irqrestore(&s->lock, flags); | ||
2440 | count -= cnt; | ||
2441 | buffer += cnt; | ||
2442 | ret += cnt; | ||
2443 | start_dac(s); | ||
2444 | } | ||
2445 | return_free: | ||
2446 | return ret; | ||
2447 | } | ||
2448 | |||
2449 | /* No kernel lock - we have our own spinlock */ | ||
2450 | static unsigned int ess_poll(struct file *file, struct poll_table_struct *wait) | ||
2451 | { | ||
2452 | struct ess_state *s = (struct ess_state *)file->private_data; | ||
2453 | unsigned long flags; | ||
2454 | unsigned int mask = 0; | ||
2455 | |||
2456 | VALIDATE_STATE(s); | ||
2457 | |||
2458 | /* In 0.14 prog_dmabuf always returns success anyway ... */ | ||
2459 | if (file->f_mode & FMODE_WRITE) { | ||
2460 | if (!s->dma_dac.ready && prog_dmabuf(s, 0)) | ||
2461 | return 0; | ||
2462 | } | ||
2463 | if (file->f_mode & FMODE_READ) { | ||
2464 | if (!s->dma_adc.ready && prog_dmabuf(s, 1)) | ||
2465 | return 0; | ||
2466 | } | ||
2467 | |||
2468 | if (file->f_mode & FMODE_WRITE) | ||
2469 | poll_wait(file, &s->dma_dac.wait, wait); | ||
2470 | if (file->f_mode & FMODE_READ) | ||
2471 | poll_wait(file, &s->dma_adc.wait, wait); | ||
2472 | spin_lock_irqsave(&s->lock, flags); | ||
2473 | ess_update_ptr(s); | ||
2474 | if (file->f_mode & FMODE_READ) { | ||
2475 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
2476 | mask |= POLLIN | POLLRDNORM; | ||
2477 | } | ||
2478 | if (file->f_mode & FMODE_WRITE) { | ||
2479 | if (s->dma_dac.mapped) { | ||
2480 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) | ||
2481 | mask |= POLLOUT | POLLWRNORM; | ||
2482 | } else { | ||
2483 | if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize) | ||
2484 | mask |= POLLOUT | POLLWRNORM; | ||
2485 | } | ||
2486 | } | ||
2487 | spin_unlock_irqrestore(&s->lock, flags); | ||
2488 | return mask; | ||
2489 | } | ||
2490 | |||
2491 | static int ess_mmap(struct file *file, struct vm_area_struct *vma) | ||
2492 | { | ||
2493 | struct ess_state *s = (struct ess_state *)file->private_data; | ||
2494 | struct dmabuf *db; | ||
2495 | int ret = -EINVAL; | ||
2496 | unsigned long size; | ||
2497 | |||
2498 | VALIDATE_STATE(s); | ||
2499 | lock_kernel(); | ||
2500 | if (vma->vm_flags & VM_WRITE) { | ||
2501 | if ((ret = prog_dmabuf(s, 1)) != 0) | ||
2502 | goto out; | ||
2503 | db = &s->dma_dac; | ||
2504 | } else | ||
2505 | #if 0 | ||
2506 | /* if we can have the wp/wc do the combining | ||
2507 | we can turn this back on. */ | ||
2508 | if (vma->vm_flags & VM_READ) { | ||
2509 | if ((ret = prog_dmabuf(s, 0)) != 0) | ||
2510 | goto out; | ||
2511 | db = &s->dma_adc; | ||
2512 | } else | ||
2513 | #endif | ||
2514 | goto out; | ||
2515 | ret = -EINVAL; | ||
2516 | if (vma->vm_pgoff != 0) | ||
2517 | goto out; | ||
2518 | size = vma->vm_end - vma->vm_start; | ||
2519 | if (size > (PAGE_SIZE << db->buforder)) | ||
2520 | goto out; | ||
2521 | ret = -EAGAIN; | ||
2522 | if (remap_pfn_range(vma, vma->vm_start, | ||
2523 | virt_to_phys(db->rawbuf) >> PAGE_SHIFT, | ||
2524 | size, vma->vm_page_prot)) | ||
2525 | goto out; | ||
2526 | db->mapped = 1; | ||
2527 | ret = 0; | ||
2528 | out: | ||
2529 | unlock_kernel(); | ||
2530 | return ret; | ||
2531 | } | ||
2532 | |||
2533 | static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
2534 | { | ||
2535 | struct ess_state *s = (struct ess_state *)file->private_data; | ||
2536 | unsigned long flags; | ||
2537 | audio_buf_info abinfo; | ||
2538 | count_info cinfo; | ||
2539 | int val, mapped, ret; | ||
2540 | unsigned char fmtm, fmtd; | ||
2541 | void __user *argp = (void __user *)arg; | ||
2542 | int __user *p = argp; | ||
2543 | |||
2544 | /* printk("maestro: ess_ioctl: cmd %d\n", cmd);*/ | ||
2545 | |||
2546 | VALIDATE_STATE(s); | ||
2547 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || | ||
2548 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
2549 | switch (cmd) { | ||
2550 | case OSS_GETVERSION: | ||
2551 | return put_user(SOUND_VERSION, p); | ||
2552 | |||
2553 | case SNDCTL_DSP_SYNC: | ||
2554 | if (file->f_mode & FMODE_WRITE) | ||
2555 | return drain_dac(s, file->f_flags & O_NONBLOCK); | ||
2556 | return 0; | ||
2557 | |||
2558 | case SNDCTL_DSP_SETDUPLEX: | ||
2559 | /* XXX fix */ | ||
2560 | return 0; | ||
2561 | |||
2562 | case SNDCTL_DSP_GETCAPS: | ||
2563 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); | ||
2564 | |||
2565 | case SNDCTL_DSP_RESET: | ||
2566 | if (file->f_mode & FMODE_WRITE) { | ||
2567 | stop_dac(s); | ||
2568 | synchronize_irq(s->card->pcidev->irq); | ||
2569 | s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0; | ||
2570 | } | ||
2571 | if (file->f_mode & FMODE_READ) { | ||
2572 | stop_adc(s); | ||
2573 | synchronize_irq(s->card->pcidev->irq); | ||
2574 | s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
2575 | } | ||
2576 | return 0; | ||
2577 | |||
2578 | case SNDCTL_DSP_SPEED: | ||
2579 | if (get_user(val, p)) | ||
2580 | return -EFAULT; | ||
2581 | if (val >= 0) { | ||
2582 | if (file->f_mode & FMODE_READ) { | ||
2583 | stop_adc(s); | ||
2584 | s->dma_adc.ready = 0; | ||
2585 | set_adc_rate(s, val); | ||
2586 | } | ||
2587 | if (file->f_mode & FMODE_WRITE) { | ||
2588 | stop_dac(s); | ||
2589 | s->dma_dac.ready = 0; | ||
2590 | set_dac_rate(s, val); | ||
2591 | } | ||
2592 | } | ||
2593 | return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p); | ||
2594 | |||
2595 | case SNDCTL_DSP_STEREO: | ||
2596 | if (get_user(val, p)) | ||
2597 | return -EFAULT; | ||
2598 | fmtd = 0; | ||
2599 | fmtm = ~0; | ||
2600 | if (file->f_mode & FMODE_READ) { | ||
2601 | stop_adc(s); | ||
2602 | s->dma_adc.ready = 0; | ||
2603 | if (val) | ||
2604 | fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT; | ||
2605 | else | ||
2606 | fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT); | ||
2607 | } | ||
2608 | if (file->f_mode & FMODE_WRITE) { | ||
2609 | stop_dac(s); | ||
2610 | s->dma_dac.ready = 0; | ||
2611 | if (val) | ||
2612 | fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT; | ||
2613 | else | ||
2614 | fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT); | ||
2615 | } | ||
2616 | set_fmt(s, fmtm, fmtd); | ||
2617 | return 0; | ||
2618 | |||
2619 | case SNDCTL_DSP_CHANNELS: | ||
2620 | if (get_user(val, p)) | ||
2621 | return -EFAULT; | ||
2622 | if (val != 0) { | ||
2623 | fmtd = 0; | ||
2624 | fmtm = ~0; | ||
2625 | if (file->f_mode & FMODE_READ) { | ||
2626 | stop_adc(s); | ||
2627 | s->dma_adc.ready = 0; | ||
2628 | if (val >= 2) | ||
2629 | fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT; | ||
2630 | else | ||
2631 | fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT); | ||
2632 | } | ||
2633 | if (file->f_mode & FMODE_WRITE) { | ||
2634 | stop_dac(s); | ||
2635 | s->dma_dac.ready = 0; | ||
2636 | if (val >= 2) | ||
2637 | fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT; | ||
2638 | else | ||
2639 | fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT); | ||
2640 | } | ||
2641 | set_fmt(s, fmtm, fmtd); | ||
2642 | } | ||
2643 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) | ||
2644 | : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p); | ||
2645 | |||
2646 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
2647 | return put_user(AFMT_U8|AFMT_S16_LE, p); | ||
2648 | |||
2649 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
2650 | if (get_user(val, p)) | ||
2651 | return -EFAULT; | ||
2652 | if (val != AFMT_QUERY) { | ||
2653 | fmtd = 0; | ||
2654 | fmtm = ~0; | ||
2655 | if (file->f_mode & FMODE_READ) { | ||
2656 | stop_adc(s); | ||
2657 | s->dma_adc.ready = 0; | ||
2658 | /* fixed at 16bit for now */ | ||
2659 | fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT; | ||
2660 | #if 0 | ||
2661 | if (val == AFMT_S16_LE) | ||
2662 | fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT; | ||
2663 | else | ||
2664 | fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT); | ||
2665 | #endif | ||
2666 | } | ||
2667 | if (file->f_mode & FMODE_WRITE) { | ||
2668 | stop_dac(s); | ||
2669 | s->dma_dac.ready = 0; | ||
2670 | if (val == AFMT_S16_LE) | ||
2671 | fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT; | ||
2672 | else | ||
2673 | fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT); | ||
2674 | } | ||
2675 | set_fmt(s, fmtm, fmtd); | ||
2676 | } | ||
2677 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? | ||
2678 | (ESS_FMT_16BIT << ESS_ADC_SHIFT) | ||
2679 | : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? | ||
2680 | AFMT_S16_LE : | ||
2681 | AFMT_U8, | ||
2682 | p); | ||
2683 | |||
2684 | case SNDCTL_DSP_POST: | ||
2685 | return 0; | ||
2686 | |||
2687 | case SNDCTL_DSP_GETTRIGGER: | ||
2688 | val = 0; | ||
2689 | if ((file->f_mode & FMODE_READ) && (s->enable & ADC_RUNNING)) | ||
2690 | val |= PCM_ENABLE_INPUT; | ||
2691 | if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) | ||
2692 | val |= PCM_ENABLE_OUTPUT; | ||
2693 | return put_user(val, p); | ||
2694 | |||
2695 | case SNDCTL_DSP_SETTRIGGER: | ||
2696 | if (get_user(val, p)) | ||
2697 | return -EFAULT; | ||
2698 | if (file->f_mode & FMODE_READ) { | ||
2699 | if (val & PCM_ENABLE_INPUT) { | ||
2700 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
2701 | return ret; | ||
2702 | start_adc(s); | ||
2703 | } else | ||
2704 | stop_adc(s); | ||
2705 | } | ||
2706 | if (file->f_mode & FMODE_WRITE) { | ||
2707 | if (val & PCM_ENABLE_OUTPUT) { | ||
2708 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
2709 | return ret; | ||
2710 | start_dac(s); | ||
2711 | } else | ||
2712 | stop_dac(s); | ||
2713 | } | ||
2714 | return 0; | ||
2715 | |||
2716 | case SNDCTL_DSP_GETOSPACE: | ||
2717 | if (!(file->f_mode & FMODE_WRITE)) | ||
2718 | return -EINVAL; | ||
2719 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
2720 | return ret; | ||
2721 | spin_lock_irqsave(&s->lock, flags); | ||
2722 | ess_update_ptr(s); | ||
2723 | abinfo.fragsize = s->dma_dac.fragsize; | ||
2724 | abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count; | ||
2725 | abinfo.fragstotal = s->dma_dac.numfrag; | ||
2726 | abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; | ||
2727 | spin_unlock_irqrestore(&s->lock, flags); | ||
2728 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
2729 | |||
2730 | case SNDCTL_DSP_GETISPACE: | ||
2731 | if (!(file->f_mode & FMODE_READ)) | ||
2732 | return -EINVAL; | ||
2733 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
2734 | return ret; | ||
2735 | spin_lock_irqsave(&s->lock, flags); | ||
2736 | ess_update_ptr(s); | ||
2737 | abinfo.fragsize = s->dma_adc.fragsize; | ||
2738 | abinfo.bytes = s->dma_adc.count; | ||
2739 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
2740 | abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; | ||
2741 | spin_unlock_irqrestore(&s->lock, flags); | ||
2742 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
2743 | |||
2744 | case SNDCTL_DSP_NONBLOCK: | ||
2745 | file->f_flags |= O_NONBLOCK; | ||
2746 | return 0; | ||
2747 | |||
2748 | case SNDCTL_DSP_GETODELAY: | ||
2749 | if (!(file->f_mode & FMODE_WRITE)) | ||
2750 | return -EINVAL; | ||
2751 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
2752 | return ret; | ||
2753 | spin_lock_irqsave(&s->lock, flags); | ||
2754 | ess_update_ptr(s); | ||
2755 | val = s->dma_dac.count; | ||
2756 | spin_unlock_irqrestore(&s->lock, flags); | ||
2757 | return put_user(val, p); | ||
2758 | |||
2759 | case SNDCTL_DSP_GETIPTR: | ||
2760 | if (!(file->f_mode & FMODE_READ)) | ||
2761 | return -EINVAL; | ||
2762 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
2763 | return ret; | ||
2764 | spin_lock_irqsave(&s->lock, flags); | ||
2765 | ess_update_ptr(s); | ||
2766 | cinfo.bytes = s->dma_adc.total_bytes; | ||
2767 | cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift; | ||
2768 | cinfo.ptr = s->dma_adc.hwptr; | ||
2769 | if (s->dma_adc.mapped) | ||
2770 | s->dma_adc.count &= s->dma_adc.fragsize-1; | ||
2771 | spin_unlock_irqrestore(&s->lock, flags); | ||
2772 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
2773 | return -EFAULT; | ||
2774 | return 0; | ||
2775 | |||
2776 | case SNDCTL_DSP_GETOPTR: | ||
2777 | if (!(file->f_mode & FMODE_WRITE)) | ||
2778 | return -EINVAL; | ||
2779 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
2780 | return ret; | ||
2781 | spin_lock_irqsave(&s->lock, flags); | ||
2782 | ess_update_ptr(s); | ||
2783 | cinfo.bytes = s->dma_dac.total_bytes; | ||
2784 | cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift; | ||
2785 | cinfo.ptr = s->dma_dac.hwptr; | ||
2786 | if (s->dma_dac.mapped) | ||
2787 | s->dma_dac.count &= s->dma_dac.fragsize-1; | ||
2788 | spin_unlock_irqrestore(&s->lock, flags); | ||
2789 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
2790 | return -EFAULT; | ||
2791 | return 0; | ||
2792 | |||
2793 | case SNDCTL_DSP_GETBLKSIZE: | ||
2794 | if (file->f_mode & FMODE_WRITE) { | ||
2795 | if ((val = prog_dmabuf(s, 0))) | ||
2796 | return val; | ||
2797 | return put_user(s->dma_dac.fragsize, p); | ||
2798 | } | ||
2799 | if ((val = prog_dmabuf(s, 1))) | ||
2800 | return val; | ||
2801 | return put_user(s->dma_adc.fragsize, p); | ||
2802 | |||
2803 | case SNDCTL_DSP_SETFRAGMENT: | ||
2804 | if (get_user(val, p)) | ||
2805 | return -EFAULT; | ||
2806 | M_printk("maestro: SETFRAGMENT: %0x\n",val); | ||
2807 | if (file->f_mode & FMODE_READ) { | ||
2808 | s->dma_adc.ossfragshift = val & 0xffff; | ||
2809 | s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; | ||
2810 | if (s->dma_adc.ossfragshift < 4) | ||
2811 | s->dma_adc.ossfragshift = 4; | ||
2812 | if (s->dma_adc.ossfragshift > 15) | ||
2813 | s->dma_adc.ossfragshift = 15; | ||
2814 | if (s->dma_adc.ossmaxfrags < 4) | ||
2815 | s->dma_adc.ossmaxfrags = 4; | ||
2816 | } | ||
2817 | if (file->f_mode & FMODE_WRITE) { | ||
2818 | s->dma_dac.ossfragshift = val & 0xffff; | ||
2819 | s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; | ||
2820 | if (s->dma_dac.ossfragshift < 4) | ||
2821 | s->dma_dac.ossfragshift = 4; | ||
2822 | if (s->dma_dac.ossfragshift > 15) | ||
2823 | s->dma_dac.ossfragshift = 15; | ||
2824 | if (s->dma_dac.ossmaxfrags < 4) | ||
2825 | s->dma_dac.ossmaxfrags = 4; | ||
2826 | } | ||
2827 | return 0; | ||
2828 | |||
2829 | case SNDCTL_DSP_SUBDIVIDE: | ||
2830 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
2831 | (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) | ||
2832 | return -EINVAL; | ||
2833 | if (get_user(val, p)) | ||
2834 | return -EFAULT; | ||
2835 | if (val != 1 && val != 2 && val != 4) | ||
2836 | return -EINVAL; | ||
2837 | if (file->f_mode & FMODE_READ) | ||
2838 | s->dma_adc.subdivision = val; | ||
2839 | if (file->f_mode & FMODE_WRITE) | ||
2840 | s->dma_dac.subdivision = val; | ||
2841 | return 0; | ||
2842 | |||
2843 | case SOUND_PCM_READ_RATE: | ||
2844 | return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p); | ||
2845 | |||
2846 | case SOUND_PCM_READ_CHANNELS: | ||
2847 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) | ||
2848 | : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p); | ||
2849 | |||
2850 | case SOUND_PCM_READ_BITS: | ||
2851 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) | ||
2852 | : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p); | ||
2853 | |||
2854 | case SOUND_PCM_WRITE_FILTER: | ||
2855 | case SNDCTL_DSP_SETSYNCRO: | ||
2856 | case SOUND_PCM_READ_FILTER: | ||
2857 | return -EINVAL; | ||
2858 | |||
2859 | } | ||
2860 | return -EINVAL; | ||
2861 | } | ||
2862 | |||
2863 | static void | ||
2864 | set_base_registers(struct ess_state *s,void *vaddr) | ||
2865 | { | ||
2866 | unsigned long packed_phys = virt_to_bus(vaddr)>>12; | ||
2867 | wave_set_register(s, 0x01FC , packed_phys); | ||
2868 | wave_set_register(s, 0x01FD , packed_phys); | ||
2869 | wave_set_register(s, 0x01FE , packed_phys); | ||
2870 | wave_set_register(s, 0x01FF , packed_phys); | ||
2871 | } | ||
2872 | |||
2873 | /* | ||
2874 | * this guy makes sure we're in the right power | ||
2875 | * state for what we want to be doing | ||
2876 | */ | ||
2877 | static void maestro_power(struct ess_card *card, int tostate) | ||
2878 | { | ||
2879 | u16 active_mask = acpi_state_mask[tostate]; | ||
2880 | u8 state; | ||
2881 | |||
2882 | if(!use_pm) return; | ||
2883 | |||
2884 | pci_read_config_byte(card->pcidev, card->power_regs+0x4, &state); | ||
2885 | state&=3; | ||
2886 | |||
2887 | /* make sure we're in the right state */ | ||
2888 | if(state != tostate) { | ||
2889 | M_printk(KERN_WARNING "maestro: dev %02x:%02x.%x switching from D%d to D%d\n", | ||
2890 | card->pcidev->bus->number, | ||
2891 | PCI_SLOT(card->pcidev->devfn), | ||
2892 | PCI_FUNC(card->pcidev->devfn), | ||
2893 | state,tostate); | ||
2894 | pci_write_config_byte(card->pcidev, card->power_regs+0x4, tostate); | ||
2895 | } | ||
2896 | |||
2897 | /* and make sure the units we care about are on | ||
2898 | XXX we might want to do this before state flipping? */ | ||
2899 | pci_write_config_word(card->pcidev, 0x54, ~ active_mask); | ||
2900 | pci_write_config_word(card->pcidev, 0x56, ~ active_mask); | ||
2901 | } | ||
2902 | |||
2903 | /* we allocate a large power of two for all our memory. | ||
2904 | this is cut up into (not to scale :): | ||
2905 | |silly fifo word | 512byte mixbuf per adc | dac/adc * channels | | ||
2906 | */ | ||
2907 | static int | ||
2908 | allocate_buffers(struct ess_state *s) | ||
2909 | { | ||
2910 | void *rawbuf=NULL; | ||
2911 | int order,i; | ||
2912 | struct page *page, *pend; | ||
2913 | |||
2914 | /* alloc as big a chunk as we can */ | ||
2915 | for (order = (dsps_order + (16-PAGE_SHIFT) + 1); order >= (dsps_order + 2 + 1); order--) | ||
2916 | if((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order))) | ||
2917 | break; | ||
2918 | |||
2919 | if (!rawbuf) | ||
2920 | return 1; | ||
2921 | |||
2922 | M_printk("maestro: allocated %ld (%d) bytes at %p\n",PAGE_SIZE<<order,order, rawbuf); | ||
2923 | |||
2924 | if ((virt_to_bus(rawbuf) + (PAGE_SIZE << order) - 1) & ~((1<<28)-1)) { | ||
2925 | printk(KERN_ERR "maestro: DMA buffer beyond 256MB! busaddr 0x%lx size %ld\n", | ||
2926 | virt_to_bus(rawbuf), PAGE_SIZE << order); | ||
2927 | kfree(rawbuf); | ||
2928 | return 1; | ||
2929 | } | ||
2930 | |||
2931 | s->card->dmapages = rawbuf; | ||
2932 | s->card->dmaorder = order; | ||
2933 | |||
2934 | for(i=0;i<NR_DSPS;i++) { | ||
2935 | struct ess_state *ess = &s->card->channels[i]; | ||
2936 | |||
2937 | if(ess->dev_audio == -1) | ||
2938 | continue; | ||
2939 | |||
2940 | ess->dma_dac.ready = s->dma_dac.mapped = 0; | ||
2941 | ess->dma_adc.ready = s->dma_adc.mapped = 0; | ||
2942 | ess->dma_adc.buforder = ess->dma_dac.buforder = order - 1 - dsps_order - 1; | ||
2943 | |||
2944 | /* offset dac and adc buffers starting half way through and then at each [da][ad]c's | ||
2945 | order's intervals.. */ | ||
2946 | ess->dma_dac.rawbuf = rawbuf + (PAGE_SIZE<<(order-1)) + (i * ( PAGE_SIZE << (ess->dma_dac.buforder + 1 ))); | ||
2947 | ess->dma_adc.rawbuf = ess->dma_dac.rawbuf + ( PAGE_SIZE << ess->dma_dac.buforder); | ||
2948 | /* offset mixbuf by a mixbuf so that the lame status fifo can | ||
2949 | happily scribble away.. */ | ||
2950 | ess->mixbuf = rawbuf + (512 * (i+1)); | ||
2951 | |||
2952 | M_printk("maestro: setup apu %d: dac: %p adc: %p mix: %p\n",i,ess->dma_dac.rawbuf, | ||
2953 | ess->dma_adc.rawbuf, ess->mixbuf); | ||
2954 | |||
2955 | } | ||
2956 | |||
2957 | /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ | ||
2958 | pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1); | ||
2959 | for (page = virt_to_page(rawbuf); page <= pend; page++) | ||
2960 | SetPageReserved(page); | ||
2961 | |||
2962 | return 0; | ||
2963 | } | ||
2964 | static void | ||
2965 | free_buffers(struct ess_state *s) | ||
2966 | { | ||
2967 | struct page *page, *pend; | ||
2968 | |||
2969 | s->dma_dac.rawbuf = s->dma_adc.rawbuf = NULL; | ||
2970 | s->dma_dac.mapped = s->dma_adc.mapped = 0; | ||
2971 | s->dma_dac.ready = s->dma_adc.ready = 0; | ||
2972 | |||
2973 | M_printk("maestro: freeing %p\n",s->card->dmapages); | ||
2974 | /* undo marking the pages as reserved */ | ||
2975 | |||
2976 | pend = virt_to_page(s->card->dmapages + (PAGE_SIZE << s->card->dmaorder) - 1); | ||
2977 | for (page = virt_to_page(s->card->dmapages); page <= pend; page++) | ||
2978 | ClearPageReserved(page); | ||
2979 | |||
2980 | free_pages((unsigned long)s->card->dmapages,s->card->dmaorder); | ||
2981 | s->card->dmapages = NULL; | ||
2982 | } | ||
2983 | |||
2984 | static int | ||
2985 | ess_open(struct inode *inode, struct file *file) | ||
2986 | { | ||
2987 | unsigned int minor = iminor(inode); | ||
2988 | struct ess_state *s = NULL; | ||
2989 | unsigned char fmtm = ~0, fmts = 0; | ||
2990 | struct pci_dev *pdev = NULL; | ||
2991 | /* | ||
2992 | * Scan the cards and find the channel. We only | ||
2993 | * do this at open time so it is ok | ||
2994 | */ | ||
2995 | |||
2996 | while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { | ||
2997 | struct ess_card *c; | ||
2998 | struct pci_driver *drvr; | ||
2999 | |||
3000 | drvr = pci_dev_driver (pdev); | ||
3001 | if (drvr == &maestro_pci_driver) { | ||
3002 | int i; | ||
3003 | struct ess_state *sp; | ||
3004 | |||
3005 | c = (struct ess_card*)pci_get_drvdata (pdev); | ||
3006 | if (!c) | ||
3007 | continue; | ||
3008 | for(i=0;i<NR_DSPS;i++) | ||
3009 | { | ||
3010 | sp=&c->channels[i]; | ||
3011 | if(sp->dev_audio < 0) | ||
3012 | continue; | ||
3013 | if((sp->dev_audio ^ minor) & ~0xf) | ||
3014 | continue; | ||
3015 | s=sp; | ||
3016 | } | ||
3017 | } | ||
3018 | } | ||
3019 | if (!s) | ||
3020 | return -ENODEV; | ||
3021 | |||
3022 | VALIDATE_STATE(s); | ||
3023 | file->private_data = s; | ||
3024 | /* wait for device to become free */ | ||
3025 | mutex_lock(&s->open_mutex); | ||
3026 | while (s->open_mode & file->f_mode) { | ||
3027 | if (file->f_flags & O_NONBLOCK) { | ||
3028 | mutex_unlock(&s->open_mutex); | ||
3029 | return -EWOULDBLOCK; | ||
3030 | } | ||
3031 | mutex_unlock(&s->open_mutex); | ||
3032 | interruptible_sleep_on(&s->open_wait); | ||
3033 | if (signal_pending(current)) | ||
3034 | return -ERESTARTSYS; | ||
3035 | mutex_lock(&s->open_mutex); | ||
3036 | } | ||
3037 | |||
3038 | /* under semaphore.. */ | ||
3039 | if ((s->card->dmapages==NULL) && allocate_buffers(s)) { | ||
3040 | mutex_unlock(&s->open_mutex); | ||
3041 | return -ENOMEM; | ||
3042 | } | ||
3043 | |||
3044 | /* we're covered by the open_mutex */ | ||
3045 | if( ! s->card->dsps_open ) { | ||
3046 | maestro_power(s->card,ACPI_D0); | ||
3047 | start_bob(s); | ||
3048 | } | ||
3049 | s->card->dsps_open++; | ||
3050 | M_printk("maestro: open, %d bobs now\n",s->card->dsps_open); | ||
3051 | |||
3052 | /* ok, lets write WC base regs now that we've | ||
3053 | powered up the chip */ | ||
3054 | M_printk("maestro: writing 0x%lx (bus 0x%lx) to the wp\n",virt_to_bus(s->card->dmapages), | ||
3055 | ((virt_to_bus(s->card->dmapages))&0xFFE00000)>>12); | ||
3056 | set_base_registers(s,s->card->dmapages); | ||
3057 | |||
3058 | if (file->f_mode & FMODE_READ) { | ||
3059 | /* | ||
3060 | fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT); | ||
3061 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
3062 | fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; */ | ||
3063 | |||
3064 | fmtm &= ~((ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT); | ||
3065 | fmts = (ESS_FMT_STEREO|ESS_FMT_16BIT) << ESS_ADC_SHIFT; | ||
3066 | |||
3067 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; | ||
3068 | set_adc_rate(s, 8000); | ||
3069 | } | ||
3070 | if (file->f_mode & FMODE_WRITE) { | ||
3071 | fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT); | ||
3072 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
3073 | fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT; | ||
3074 | |||
3075 | s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; | ||
3076 | set_dac_rate(s, 8000); | ||
3077 | } | ||
3078 | set_fmt(s, fmtm, fmts); | ||
3079 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
3080 | |||
3081 | mutex_unlock(&s->open_mutex); | ||
3082 | return nonseekable_open(inode, file); | ||
3083 | } | ||
3084 | |||
3085 | static int | ||
3086 | ess_release(struct inode *inode, struct file *file) | ||
3087 | { | ||
3088 | struct ess_state *s = (struct ess_state *)file->private_data; | ||
3089 | |||
3090 | VALIDATE_STATE(s); | ||
3091 | lock_kernel(); | ||
3092 | if (file->f_mode & FMODE_WRITE) | ||
3093 | drain_dac(s, file->f_flags & O_NONBLOCK); | ||
3094 | mutex_lock(&s->open_mutex); | ||
3095 | if (file->f_mode & FMODE_WRITE) { | ||
3096 | stop_dac(s); | ||
3097 | } | ||
3098 | if (file->f_mode & FMODE_READ) { | ||
3099 | stop_adc(s); | ||
3100 | } | ||
3101 | |||
3102 | s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); | ||
3103 | /* we're covered by the open_mutex */ | ||
3104 | M_printk("maestro: %d dsps now alive\n",s->card->dsps_open-1); | ||
3105 | if( --s->card->dsps_open <= 0) { | ||
3106 | s->card->dsps_open = 0; | ||
3107 | stop_bob(s); | ||
3108 | free_buffers(s); | ||
3109 | maestro_power(s->card,ACPI_D2); | ||
3110 | } | ||
3111 | mutex_unlock(&s->open_mutex); | ||
3112 | wake_up(&s->open_wait); | ||
3113 | unlock_kernel(); | ||
3114 | return 0; | ||
3115 | } | ||
3116 | |||
3117 | static struct file_operations ess_audio_fops = { | ||
3118 | .owner = THIS_MODULE, | ||
3119 | .llseek = no_llseek, | ||
3120 | .read = ess_read, | ||
3121 | .write = ess_write, | ||
3122 | .poll = ess_poll, | ||
3123 | .ioctl = ess_ioctl, | ||
3124 | .mmap = ess_mmap, | ||
3125 | .open = ess_open, | ||
3126 | .release = ess_release, | ||
3127 | }; | ||
3128 | |||
3129 | static int | ||
3130 | maestro_config(struct ess_card *card) | ||
3131 | { | ||
3132 | struct pci_dev *pcidev = card->pcidev; | ||
3133 | struct ess_state *ess = &card->channels[0]; | ||
3134 | int apu,iobase = card->iobase; | ||
3135 | u16 w; | ||
3136 | u32 n; | ||
3137 | |||
3138 | /* We used to muck around with pci config space that | ||
3139 | * we had no business messing with. We don't know enough | ||
3140 | * about the machine to know which DMA mode is appropriate, | ||
3141 | * etc. We were guessing wrong on some machines and making | ||
3142 | * them unhappy. We now trust in the BIOS to do things right, | ||
3143 | * which almost certainly means a new host of problems will | ||
3144 | * arise with broken BIOS implementations. screw 'em. | ||
3145 | * We're already intolerant of machines that don't assign | ||
3146 | * IRQs. | ||
3147 | */ | ||
3148 | |||
3149 | /* do config work at full power */ | ||
3150 | maestro_power(card,ACPI_D0); | ||
3151 | |||
3152 | pci_read_config_word(pcidev, 0x50, &w); | ||
3153 | |||
3154 | w&=~(1<<5); /* Don't swap left/right (undoc)*/ | ||
3155 | |||
3156 | pci_write_config_word(pcidev, 0x50, w); | ||
3157 | |||
3158 | pci_read_config_word(pcidev, 0x52, &w); | ||
3159 | w&=~(1<<15); /* Turn off internal clock multiplier */ | ||
3160 | /* XXX how do we know which to use? */ | ||
3161 | w&=~(1<<14); /* External clock */ | ||
3162 | |||
3163 | w|= (1<<7); /* Hardware volume control on */ | ||
3164 | w|= (1<<6); /* Debounce off: easier to push the HWV buttons. */ | ||
3165 | w&=~(1<<5); /* GPIO 4:5 */ | ||
3166 | w|= (1<<4); /* Disconnect from the CHI. Enabling this made a dell 7500 work. */ | ||
3167 | w&=~(1<<2); /* MIDI fix off (undoc) */ | ||
3168 | w&=~(1<<1); /* reserved, always write 0 */ | ||
3169 | pci_write_config_word(pcidev, 0x52, w); | ||
3170 | |||
3171 | /* | ||
3172 | * Legacy mode | ||
3173 | */ | ||
3174 | |||
3175 | pci_read_config_word(pcidev, 0x40, &w); | ||
3176 | w|=(1<<15); /* legacy decode off */ | ||
3177 | w&=~(1<<14); /* Disable SIRQ */ | ||
3178 | w&=~(0x1f); /* disable mpu irq/io, game port, fm, SB */ | ||
3179 | |||
3180 | pci_write_config_word(pcidev, 0x40, w); | ||
3181 | |||
3182 | /* Set up 978 docking control chip. */ | ||
3183 | pci_read_config_word(pcidev, 0x58, &w); | ||
3184 | w|=1<<2; /* Enable 978. */ | ||
3185 | w|=1<<3; /* Turn on 978 hardware volume control. */ | ||
3186 | w&=~(1<<11); /* Turn on 978 mixer volume control. */ | ||
3187 | pci_write_config_word(pcidev, 0x58, w); | ||
3188 | |||
3189 | sound_reset(iobase); | ||
3190 | |||
3191 | /* | ||
3192 | * Ring Bus Setup | ||
3193 | */ | ||
3194 | |||
3195 | /* setup usual 0x34 stuff.. 0x36 may be chip specific */ | ||
3196 | outw(0xC090, iobase+0x34); /* direct sound, stereo */ | ||
3197 | udelay(20); | ||
3198 | outw(0x3000, iobase+0x36); /* direct sound, stereo */ | ||
3199 | udelay(20); | ||
3200 | |||
3201 | |||
3202 | /* | ||
3203 | * Reset the CODEC | ||
3204 | */ | ||
3205 | |||
3206 | maestro_ac97_reset(iobase,pcidev); | ||
3207 | |||
3208 | /* | ||
3209 | * Ring Bus Setup | ||
3210 | */ | ||
3211 | |||
3212 | n=inl(iobase+0x34); | ||
3213 | n&=~0xF000; | ||
3214 | n|=12<<12; /* Direct Sound, Stereo */ | ||
3215 | outl(n, iobase+0x34); | ||
3216 | |||
3217 | n=inl(iobase+0x34); | ||
3218 | n&=~0x0F00; /* Modem off */ | ||
3219 | outl(n, iobase+0x34); | ||
3220 | |||
3221 | n=inl(iobase+0x34); | ||
3222 | n&=~0x00F0; | ||
3223 | n|=9<<4; /* DAC, Stereo */ | ||
3224 | outl(n, iobase+0x34); | ||
3225 | |||
3226 | n=inl(iobase+0x34); | ||
3227 | n&=~0x000F; /* ASSP off */ | ||
3228 | outl(n, iobase+0x34); | ||
3229 | |||
3230 | n=inl(iobase+0x34); | ||
3231 | n|=(1<<29); /* Enable ring bus */ | ||
3232 | outl(n, iobase+0x34); | ||
3233 | |||
3234 | n=inl(iobase+0x34); | ||
3235 | n|=(1<<28); /* Enable serial bus */ | ||
3236 | outl(n, iobase+0x34); | ||
3237 | |||
3238 | n=inl(iobase+0x34); | ||
3239 | n&=~0x00F00000; /* MIC off */ | ||
3240 | outl(n, iobase+0x34); | ||
3241 | |||
3242 | n=inl(iobase+0x34); | ||
3243 | n&=~0x000F0000; /* I2S off */ | ||
3244 | outl(n, iobase+0x34); | ||
3245 | |||
3246 | |||
3247 | w=inw(iobase+0x18); | ||
3248 | w&=~(1<<7); /* ClkRun off */ | ||
3249 | outw(w, iobase+0x18); | ||
3250 | |||
3251 | w=inw(iobase+0x18); | ||
3252 | w&=~(1<<6); /* Hardware volume control interrupt off... for now. */ | ||
3253 | outw(w, iobase+0x18); | ||
3254 | |||
3255 | w=inw(iobase+0x18); | ||
3256 | w&=~(1<<4); /* ASSP irq off */ | ||
3257 | outw(w, iobase+0x18); | ||
3258 | |||
3259 | w=inw(iobase+0x18); | ||
3260 | w&=~(1<<3); /* ISDN irq off */ | ||
3261 | outw(w, iobase+0x18); | ||
3262 | |||
3263 | w=inw(iobase+0x18); | ||
3264 | w|=(1<<2); /* Direct Sound IRQ on */ | ||
3265 | outw(w, iobase+0x18); | ||
3266 | |||
3267 | w=inw(iobase+0x18); | ||
3268 | w&=~(1<<1); /* MPU401 IRQ off */ | ||
3269 | outw(w, iobase+0x18); | ||
3270 | |||
3271 | w=inw(iobase+0x18); | ||
3272 | w|=(1<<0); /* SB IRQ on */ | ||
3273 | outw(w, iobase+0x18); | ||
3274 | |||
3275 | /* Set hardware volume control registers to midpoints. | ||
3276 | We can tell which button was pushed based on how they change. */ | ||
3277 | outb(0x88, iobase+0x1c); | ||
3278 | outb(0x88, iobase+0x1d); | ||
3279 | outb(0x88, iobase+0x1e); | ||
3280 | outb(0x88, iobase+0x1f); | ||
3281 | |||
3282 | /* it appears some maestros (dell 7500) only work if these are set, | ||
3283 | regardless of whether we use the assp or not. */ | ||
3284 | |||
3285 | outb(0, iobase+0xA4); | ||
3286 | outb(3, iobase+0xA2); | ||
3287 | outb(0, iobase+0xA6); | ||
3288 | |||
3289 | for(apu=0;apu<16;apu++) | ||
3290 | { | ||
3291 | /* Write 0 into the buffer area 0x1E0->1EF */ | ||
3292 | outw(0x01E0+apu, 0x10+iobase); | ||
3293 | outw(0x0000, 0x12+iobase); | ||
3294 | |||
3295 | /* | ||
3296 | * The 1.10 test program seem to write 0 into the buffer area | ||
3297 | * 0x1D0-0x1DF too. | ||
3298 | */ | ||
3299 | outw(0x01D0+apu, 0x10+iobase); | ||
3300 | outw(0x0000, 0x12+iobase); | ||
3301 | } | ||
3302 | |||
3303 | #if 1 | ||
3304 | wave_set_register(ess, IDR7_WAVE_ROMRAM, | ||
3305 | (wave_get_register(ess, IDR7_WAVE_ROMRAM)&0xFF00)); | ||
3306 | wave_set_register(ess, IDR7_WAVE_ROMRAM, | ||
3307 | wave_get_register(ess, IDR7_WAVE_ROMRAM)|0x100); | ||
3308 | wave_set_register(ess, IDR7_WAVE_ROMRAM, | ||
3309 | wave_get_register(ess, IDR7_WAVE_ROMRAM)&~0x200); | ||
3310 | wave_set_register(ess, IDR7_WAVE_ROMRAM, | ||
3311 | wave_get_register(ess, IDR7_WAVE_ROMRAM)|~0x400); | ||
3312 | #else | ||
3313 | maestro_write(ess, IDR7_WAVE_ROMRAM, | ||
3314 | (maestro_read(ess, IDR7_WAVE_ROMRAM)&0xFF00)); | ||
3315 | maestro_write(ess, IDR7_WAVE_ROMRAM, | ||
3316 | maestro_read(ess, IDR7_WAVE_ROMRAM)|0x100); | ||
3317 | maestro_write(ess, IDR7_WAVE_ROMRAM, | ||
3318 | maestro_read(ess, IDR7_WAVE_ROMRAM)&~0x200); | ||
3319 | maestro_write(ess, IDR7_WAVE_ROMRAM, | ||
3320 | maestro_read(ess, IDR7_WAVE_ROMRAM)|0x400); | ||
3321 | #endif | ||
3322 | |||
3323 | maestro_write(ess, IDR2_CRAM_DATA, 0x0000); | ||
3324 | maestro_write(ess, 0x08, 0xB004); | ||
3325 | /* Now back to the DirectSound stuff */ | ||
3326 | maestro_write(ess, 0x09, 0x001B); | ||
3327 | maestro_write(ess, 0x0A, 0x8000); | ||
3328 | maestro_write(ess, 0x0B, 0x3F37); | ||
3329 | maestro_write(ess, 0x0C, 0x0098); | ||
3330 | |||
3331 | /* parallel out ?? */ | ||
3332 | maestro_write(ess, 0x0C, | ||
3333 | (maestro_read(ess, 0x0C)&~0xF000)|0x8000); | ||
3334 | /* parallel in, has something to do with recording :) */ | ||
3335 | maestro_write(ess, 0x0C, | ||
3336 | (maestro_read(ess, 0x0C)&~0x0F00)|0x0500); | ||
3337 | |||
3338 | maestro_write(ess, 0x0D, 0x7632); | ||
3339 | |||
3340 | /* Wave cache control on - test off, sg off, | ||
3341 | enable, enable extra chans 1Mb */ | ||
3342 | |||
3343 | outw(inw(0x14+iobase)|(1<<8),0x14+iobase); | ||
3344 | outw(inw(0x14+iobase)&0xFE03,0x14+iobase); | ||
3345 | outw((inw(0x14+iobase)&0xFFFC), 0x14+iobase); | ||
3346 | outw(inw(0x14+iobase)|(1<<7),0x14+iobase); | ||
3347 | |||
3348 | outw(0xA1A0, 0x14+iobase); /* 0300 ? */ | ||
3349 | |||
3350 | /* Now clear the APU control ram */ | ||
3351 | for(apu=0;apu<NR_APUS;apu++) | ||
3352 | { | ||
3353 | for(w=0;w<NR_APU_REGS;w++) | ||
3354 | apu_set_register(ess, apu|ESS_CHAN_HARD, w, 0); | ||
3355 | |||
3356 | } | ||
3357 | |||
3358 | return 0; | ||
3359 | |||
3360 | } | ||
3361 | |||
3362 | /* this guy tries to find the pci power management | ||
3363 | * register bank. this should really be in core | ||
3364 | * code somewhere. 1 on success. */ | ||
3365 | static int | ||
3366 | parse_power(struct ess_card *card, struct pci_dev *pcidev) | ||
3367 | { | ||
3368 | u32 n; | ||
3369 | u16 w; | ||
3370 | u8 next; | ||
3371 | int max = 64; /* an a 8bit guy pointing to 32bit guys | ||
3372 | can only express so much. */ | ||
3373 | |||
3374 | card->power_regs = 0; | ||
3375 | |||
3376 | /* check to see if we have a capabilities list in | ||
3377 | the config register */ | ||
3378 | pci_read_config_word(pcidev, PCI_STATUS, &w); | ||
3379 | if(!(w & PCI_STATUS_CAP_LIST)) return 0; | ||
3380 | |||
3381 | /* walk the list, starting at the head. */ | ||
3382 | pci_read_config_byte(pcidev,PCI_CAPABILITY_LIST,&next); | ||
3383 | |||
3384 | while(next && max--) { | ||
3385 | pci_read_config_dword(pcidev, next & ~3, &n); | ||
3386 | if((n & 0xff) == PCI_CAP_ID_PM) { | ||
3387 | card->power_regs = next; | ||
3388 | break; | ||
3389 | } | ||
3390 | next = ((n>>8) & 0xff); | ||
3391 | } | ||
3392 | |||
3393 | return card->power_regs ? 1 : 0; | ||
3394 | } | ||
3395 | |||
3396 | static int __init | ||
3397 | maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid) | ||
3398 | { | ||
3399 | int card_type = pdid->driver_data; | ||
3400 | u32 n; | ||
3401 | int iobase; | ||
3402 | int i, ret; | ||
3403 | struct ess_card *card; | ||
3404 | struct ess_state *ess; | ||
3405 | int num = 0; | ||
3406 | |||
3407 | /* when built into the kernel, we only print version if device is found */ | ||
3408 | #ifndef MODULE | ||
3409 | static int printed_version; | ||
3410 | if (!printed_version++) | ||
3411 | printk(version); | ||
3412 | #endif | ||
3413 | |||
3414 | /* don't pick up weird modem maestros */ | ||
3415 | if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO) | ||
3416 | return -ENODEV; | ||
3417 | |||
3418 | |||
3419 | if ((ret=pci_enable_device(pcidev))) | ||
3420 | return ret; | ||
3421 | |||
3422 | iobase = pci_resource_start(pcidev,0); | ||
3423 | if (!iobase || !(pci_resource_flags(pcidev, 0 ) & IORESOURCE_IO)) | ||
3424 | return -ENODEV; | ||
3425 | |||
3426 | if(pcidev->irq == 0) | ||
3427 | return -ENODEV; | ||
3428 | |||
3429 | /* stake our claim on the iospace */ | ||
3430 | if( request_region(iobase, 256, card_names[card_type]) == NULL ) | ||
3431 | { | ||
3432 | printk(KERN_WARNING "maestro: can't allocate 256 bytes I/O at 0x%4.4x\n", iobase); | ||
3433 | return -EBUSY; | ||
3434 | } | ||
3435 | |||
3436 | /* just to be sure */ | ||
3437 | pci_set_master(pcidev); | ||
3438 | |||
3439 | card = kmalloc(sizeof(struct ess_card), GFP_KERNEL); | ||
3440 | if(card == NULL) | ||
3441 | { | ||
3442 | printk(KERN_WARNING "maestro: out of memory\n"); | ||
3443 | release_region(iobase, 256); | ||
3444 | return -ENOMEM; | ||
3445 | } | ||
3446 | |||
3447 | memset(card, 0, sizeof(*card)); | ||
3448 | card->pcidev = pcidev; | ||
3449 | |||
3450 | card->iobase = iobase; | ||
3451 | card->card_type = card_type; | ||
3452 | card->irq = pcidev->irq; | ||
3453 | card->magic = ESS_CARD_MAGIC; | ||
3454 | spin_lock_init(&card->lock); | ||
3455 | init_waitqueue_head(&card->suspend_queue); | ||
3456 | |||
3457 | card->dock_mute_vol = 50; | ||
3458 | |||
3459 | /* init our groups of 6 apus */ | ||
3460 | for(i=0;i<NR_DSPS;i++) | ||
3461 | { | ||
3462 | struct ess_state *s=&card->channels[i]; | ||
3463 | |||
3464 | s->index = i; | ||
3465 | |||
3466 | s->card = card; | ||
3467 | init_waitqueue_head(&s->dma_adc.wait); | ||
3468 | init_waitqueue_head(&s->dma_dac.wait); | ||
3469 | init_waitqueue_head(&s->open_wait); | ||
3470 | spin_lock_init(&s->lock); | ||
3471 | mutex_init(&s->open_mutex); | ||
3472 | s->magic = ESS_STATE_MAGIC; | ||
3473 | |||
3474 | s->apu[0] = 6*i; | ||
3475 | s->apu[1] = (6*i)+1; | ||
3476 | s->apu[2] = (6*i)+2; | ||
3477 | s->apu[3] = (6*i)+3; | ||
3478 | s->apu[4] = (6*i)+4; | ||
3479 | s->apu[5] = (6*i)+5; | ||
3480 | |||
3481 | if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf) | ||
3482 | printk("maestro: BOTCH!\n"); | ||
3483 | /* register devices */ | ||
3484 | if ((s->dev_audio = register_sound_dsp(&ess_audio_fops, -1)) < 0) | ||
3485 | break; | ||
3486 | } | ||
3487 | |||
3488 | num = i; | ||
3489 | |||
3490 | /* clear the rest if we ran out of slots to register */ | ||
3491 | for(;i<NR_DSPS;i++) | ||
3492 | { | ||
3493 | struct ess_state *s=&card->channels[i]; | ||
3494 | s->dev_audio = -1; | ||
3495 | } | ||
3496 | |||
3497 | ess = &card->channels[0]; | ||
3498 | |||
3499 | /* | ||
3500 | * Ok card ready. Begin setup proper | ||
3501 | */ | ||
3502 | |||
3503 | printk(KERN_INFO "maestro: Configuring %s found at IO 0x%04X IRQ %d\n", | ||
3504 | card_names[card_type],iobase,card->irq); | ||
3505 | pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &n); | ||
3506 | printk(KERN_INFO "maestro: subvendor id: 0x%08x\n",n); | ||
3507 | |||
3508 | /* turn off power management unless: | ||
3509 | * - the user explicitly asks for it | ||
3510 | * or | ||
3511 | * - we're not a 2e, lesser chipps seem to have problems. | ||
3512 | * - we're not on our _very_ small whitelist. some implemenetations | ||
3513 | * really don't like the pm code, others require it. | ||
3514 | * feel free to expand this as required. | ||
3515 | */ | ||
3516 | #define SUBSYSTEM_VENDOR(x) (x&0xffff) | ||
3517 | if( (use_pm != 1) && | ||
3518 | ((card_type != TYPE_MAESTRO2E) || (SUBSYSTEM_VENDOR(n) != 0x1028))) | ||
3519 | use_pm = 0; | ||
3520 | |||
3521 | if(!use_pm) | ||
3522 | printk(KERN_INFO "maestro: not attempting power management.\n"); | ||
3523 | else { | ||
3524 | if(!parse_power(card,pcidev)) | ||
3525 | printk(KERN_INFO "maestro: no PCI power management interface found.\n"); | ||
3526 | else { | ||
3527 | pci_read_config_dword(pcidev, card->power_regs, &n); | ||
3528 | printk(KERN_INFO "maestro: PCI power management capability: 0x%x\n",n>>16); | ||
3529 | } | ||
3530 | } | ||
3531 | |||
3532 | maestro_config(card); | ||
3533 | |||
3534 | if(maestro_ac97_get(card, 0x00)==0x0080) { | ||
3535 | printk(KERN_ERR "maestro: my goodness! you seem to have a pt101 codec, which is quite rare.\n" | ||
3536 | "\tyou should tell someone about this.\n"); | ||
3537 | } else { | ||
3538 | maestro_ac97_init(card); | ||
3539 | } | ||
3540 | |||
3541 | if ((card->dev_mixer = register_sound_mixer(&ess_mixer_fops, -1)) < 0) { | ||
3542 | printk("maestro: couldn't register mixer!\n"); | ||
3543 | } else { | ||
3544 | memcpy(card->mix.mixer_state,mixer_defaults,sizeof(card->mix.mixer_state)); | ||
3545 | mixer_push_state(card); | ||
3546 | } | ||
3547 | |||
3548 | if((ret=request_irq(card->irq, ess_interrupt, IRQF_SHARED, card_names[card_type], card))) | ||
3549 | { | ||
3550 | printk(KERN_ERR "maestro: unable to allocate irq %d,\n", card->irq); | ||
3551 | unregister_sound_mixer(card->dev_mixer); | ||
3552 | for(i=0;i<NR_DSPS;i++) | ||
3553 | { | ||
3554 | struct ess_state *s = &card->channels[i]; | ||
3555 | if(s->dev_audio != -1) | ||
3556 | unregister_sound_dsp(s->dev_audio); | ||
3557 | } | ||
3558 | release_region(card->iobase, 256); | ||
3559 | unregister_reboot_notifier(&maestro_nb); | ||
3560 | kfree(card); | ||
3561 | return ret; | ||
3562 | } | ||
3563 | |||
3564 | /* Turn on hardware volume control interrupt. | ||
3565 | This has to come after we grab the IRQ above, | ||
3566 | or a crash will result on installation if a button has been pressed, | ||
3567 | because in that case we'll get an immediate interrupt. */ | ||
3568 | n = inw(iobase+0x18); | ||
3569 | n|=(1<<6); | ||
3570 | outw(n, iobase+0x18); | ||
3571 | |||
3572 | pci_set_drvdata(pcidev,card); | ||
3573 | /* now go to sleep 'till something interesting happens */ | ||
3574 | maestro_power(card,ACPI_D2); | ||
3575 | |||
3576 | printk(KERN_INFO "maestro: %d channels configured.\n", num); | ||
3577 | return 0; | ||
3578 | } | ||
3579 | |||
3580 | static void maestro_remove(struct pci_dev *pcidev) { | ||
3581 | struct ess_card *card = pci_get_drvdata(pcidev); | ||
3582 | int i; | ||
3583 | u32 n; | ||
3584 | |||
3585 | /* XXX maybe should force stop bob, but should be all | ||
3586 | stopped by _release by now */ | ||
3587 | |||
3588 | /* Turn off hardware volume control interrupt. | ||
3589 | This has to come before we leave the IRQ below, | ||
3590 | or a crash results if a button is pressed ! */ | ||
3591 | n = inw(card->iobase+0x18); | ||
3592 | n&=~(1<<6); | ||
3593 | outw(n, card->iobase+0x18); | ||
3594 | |||
3595 | free_irq(card->irq, card); | ||
3596 | unregister_sound_mixer(card->dev_mixer); | ||
3597 | for(i=0;i<NR_DSPS;i++) | ||
3598 | { | ||
3599 | struct ess_state *ess = &card->channels[i]; | ||
3600 | if(ess->dev_audio != -1) | ||
3601 | unregister_sound_dsp(ess->dev_audio); | ||
3602 | } | ||
3603 | /* Goodbye, Mr. Bond. */ | ||
3604 | maestro_power(card,ACPI_D3); | ||
3605 | release_region(card->iobase, 256); | ||
3606 | kfree(card); | ||
3607 | pci_set_drvdata(pcidev,NULL); | ||
3608 | } | ||
3609 | |||
3610 | static struct pci_device_id maestro_pci_tbl[] = { | ||
3611 | {PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2}, | ||
3612 | {PCI_VENDOR_ESS, PCI_DEVICE_ID_ESS_ESS1978, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO2E}, | ||
3613 | {PCI_VENDOR_ESS_OLD, PCI_DEVICE_ID_ESS_ESS0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_MAESTRO}, | ||
3614 | {0,} | ||
3615 | }; | ||
3616 | MODULE_DEVICE_TABLE(pci, maestro_pci_tbl); | ||
3617 | |||
3618 | static struct pci_driver maestro_pci_driver = { | ||
3619 | .name = "maestro", | ||
3620 | .id_table = maestro_pci_tbl, | ||
3621 | .probe = maestro_probe, | ||
3622 | .remove = maestro_remove, | ||
3623 | }; | ||
3624 | |||
3625 | static int __init init_maestro(void) | ||
3626 | { | ||
3627 | int rc; | ||
3628 | |||
3629 | rc = pci_register_driver(&maestro_pci_driver); | ||
3630 | if (rc < 0) | ||
3631 | return rc; | ||
3632 | |||
3633 | if (register_reboot_notifier(&maestro_nb)) | ||
3634 | printk(KERN_WARNING "maestro: reboot notifier registration failed; may not reboot properly.\n"); | ||
3635 | #ifdef MODULE | ||
3636 | printk(version); | ||
3637 | #endif | ||
3638 | if (dsps_order < 0) { | ||
3639 | dsps_order = 1; | ||
3640 | printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order); | ||
3641 | } | ||
3642 | else if (dsps_order > MAX_DSP_ORDER) { | ||
3643 | dsps_order = MAX_DSP_ORDER; | ||
3644 | printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order); | ||
3645 | } | ||
3646 | return 0; | ||
3647 | } | ||
3648 | |||
3649 | static int maestro_notifier(struct notifier_block *nb, unsigned long event, void *buf) | ||
3650 | { | ||
3651 | /* this notifier is called when the kernel is really shut down. */ | ||
3652 | M_printk("maestro: shutting down\n"); | ||
3653 | /* this will remove all card instances too */ | ||
3654 | pci_unregister_driver(&maestro_pci_driver); | ||
3655 | /* XXX dunno about power management */ | ||
3656 | return NOTIFY_OK; | ||
3657 | } | ||
3658 | |||
3659 | /* --------------------------------------------------------------------- */ | ||
3660 | |||
3661 | |||
3662 | static void cleanup_maestro(void) { | ||
3663 | M_printk("maestro: unloading\n"); | ||
3664 | pci_unregister_driver(&maestro_pci_driver); | ||
3665 | unregister_reboot_notifier(&maestro_nb); | ||
3666 | } | ||
3667 | |||
3668 | /* --------------------------------------------------------------------- */ | ||
3669 | |||
3670 | void | ||
3671 | check_suspend(struct ess_card *card) | ||
3672 | { | ||
3673 | DECLARE_WAITQUEUE(wait, current); | ||
3674 | |||
3675 | if(!card->in_suspend) return; | ||
3676 | |||
3677 | card->in_suspend++; | ||
3678 | add_wait_queue(&(card->suspend_queue), &wait); | ||
3679 | current->state = TASK_UNINTERRUPTIBLE; | ||
3680 | schedule(); | ||
3681 | remove_wait_queue(&(card->suspend_queue), &wait); | ||
3682 | current->state = TASK_RUNNING; | ||
3683 | } | ||
3684 | |||
3685 | module_init(init_maestro); | ||
3686 | module_exit(cleanup_maestro); | ||
diff --git a/sound/oss/maestro.h b/sound/oss/maestro.h deleted file mode 100644 index 023ec7f968f9..000000000000 --- a/sound/oss/maestro.h +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /* | ||
2 | * Registers for the ESS PCI cards | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * Memory access | ||
7 | */ | ||
8 | |||
9 | #define ESS_MEM_DATA 0x00 | ||
10 | #define ESS_MEM_INDEX 0x02 | ||
11 | |||
12 | /* | ||
13 | * AC-97 Codec port. Delay 1uS after each write. This is used to | ||
14 | * talk AC-97 (see intel.com). Write data then register. | ||
15 | */ | ||
16 | |||
17 | #define ESS_AC97_INDEX 0x30 /* byte wide */ | ||
18 | #define ESS_AC97_DATA 0x32 | ||
19 | |||
20 | /* | ||
21 | * Reading is a bit different. You write register|0x80 to ubdex | ||
22 | * delay 1uS poll the low bit of index, when it clears read the | ||
23 | * data value. | ||
24 | */ | ||
25 | |||
26 | /* | ||
27 | * Control port. Not yet fully understood | ||
28 | * The value 0xC090 gets loaded to it then 0x0000 and 0x2800 | ||
29 | * to the data port. Then after 4uS the value 0x300 is written | ||
30 | */ | ||
31 | |||
32 | #define RING_BUS_CTRL_L 0x34 | ||
33 | #define RING_BUS_CTRL_H 0x36 | ||
34 | |||
35 | /* | ||
36 | * This is also used during setup. The value 0x17 is written to it | ||
37 | */ | ||
38 | |||
39 | #define ESS_SETUP_18 0x18 | ||
40 | |||
41 | /* | ||
42 | * And this one gets 0x000b | ||
43 | */ | ||
44 | |||
45 | #define ESS_SETUP_A2 0xA2 | ||
46 | |||
47 | /* | ||
48 | * And this 0x0000 | ||
49 | */ | ||
50 | |||
51 | #define ESS_SETUP_A4 0xA4 | ||
52 | #define ESS_SETUP_A6 0xA6 | ||
53 | |||
54 | /* | ||
55 | * Stuff to do with Harpo - the wave stuff | ||
56 | */ | ||
57 | |||
58 | #define ESS_WAVETABLE_SIZE 0x14 | ||
59 | #define ESS_WAVETABLE_2M 0xA180 | ||
60 | |||
diff --git a/sound/oss/maestro3.c b/sound/oss/maestro3.c deleted file mode 100644 index 5548e3cff7ce..000000000000 --- a/sound/oss/maestro3.c +++ /dev/null | |||
@@ -1,2969 +0,0 @@ | |||
1 | /***************************************************************************** | ||
2 | * | ||
3 | * ESS Maestro3/Allegro driver for Linux 2.4.x | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | * (c) Copyright 2000 Zach Brown <zab@zabbo.net> | ||
20 | * | ||
21 | * I need to thank many people for helping make this driver happen. | ||
22 | * As always, Eric Brombaugh was a hacking machine and killed many bugs | ||
23 | * that I was too dumb to notice. Howard Kim at ESS provided reference boards | ||
24 | * and as much docs as he could. Todd and Mick at Dell tested snapshots on | ||
25 | * an army of laptops. msw and deviant at Red Hat also humoured me by hanging | ||
26 | * their laptops every few hours in the name of science. | ||
27 | * | ||
28 | * Shouts go out to Mike "DJ XPCom" Ang. | ||
29 | * | ||
30 | * History | ||
31 | * v1.23 - Jun 5 2002 - Michael Olson <olson@cs.odu.edu> | ||
32 | * added a module option to allow selection of GPIO pin number | ||
33 | * for external amp | ||
34 | * v1.22 - Feb 28 2001 - Zach Brown <zab@zabbo.net> | ||
35 | * allocate mem at insmod/setup, rather than open | ||
36 | * limit pci dma addresses to 28bit, thanks guys. | ||
37 | * v1.21 - Feb 04 2001 - Zach Brown <zab@zabbo.net> | ||
38 | * fix up really dumb notifier -> suspend oops | ||
39 | * v1.20 - Jan 30 2001 - Zach Brown <zab@zabbo.net> | ||
40 | * get rid of pm callback and use pci_dev suspend/resume instead | ||
41 | * m3_probe cleanups, including pm oops think-o | ||
42 | * v1.10 - Jan 6 2001 - Zach Brown <zab@zabbo.net> | ||
43 | * revert to lame remap_page_range mmap() just to make it work | ||
44 | * record mmap fixed. | ||
45 | * fix up incredibly broken open/release resource management | ||
46 | * duh. fix record format setting. | ||
47 | * add SMP locking and cleanup formatting here and there | ||
48 | * v1.00 - Dec 16 2000 - Zach Brown <zab@zabbo.net> | ||
49 | * port to sexy 2.4 interfaces | ||
50 | * properly align instance allocations so recording works | ||
51 | * clean up function namespace a little :/ | ||
52 | * update PCI IDs based on mail from ESS | ||
53 | * arbitrarily bump version number to show its 2.4 now, | ||
54 | * 2.2 will stay 0., oss_audio port gets 2. | ||
55 | * v0.03 - Nov 05 2000 - Zach Brown <zab@zabbo.net> | ||
56 | * disable recording but allow dsp to be opened read | ||
57 | * pull out most silly compat defines | ||
58 | * v0.02 - Nov 04 2000 - Zach Brown <zab@zabbo.net> | ||
59 | * changed clocking setup for m3, slowdown fixed. | ||
60 | * codec reset is hopefully reliable now | ||
61 | * rudimentary apm/power management makes suspend/resume work | ||
62 | * v0.01 - Oct 31 2000 - Zach Brown <zab@zabbo.net> | ||
63 | * first release | ||
64 | * v0.00 - Sep 09 2000 - Zach Brown <zab@zabbo.net> | ||
65 | * first pass derivation from maestro.c | ||
66 | * | ||
67 | * TODO | ||
68 | * in/out allocated contiguously so fullduplex mmap will work? | ||
69 | * no beep on init (mute) | ||
70 | * resetup msrc data memory if freq changes? | ||
71 | * | ||
72 | * -- | ||
73 | * | ||
74 | * Allow me to ramble a bit about the m3 architecture. The core of the | ||
75 | * chip is the 'assp', the custom ESS dsp that runs the show. It has | ||
76 | * a small amount of code and data ram. ESS drops binary dsp code images | ||
77 | * on our heads, but we don't get to see specs on the dsp. | ||
78 | * | ||
79 | * The constant piece of code on the dsp is the 'kernel'. It also has a | ||
80 | * chunk of the dsp memory that is statically set aside for its control | ||
81 | * info. This is the KDATA defines in maestro3.h. Part of its core | ||
82 | * data is a list of code addresses that point to the pieces of DSP code | ||
83 | * that it should walk through in its loop. These other pieces of code | ||
84 | * do the real work. The kernel presumably jumps into each of them in turn. | ||
85 | * These code images tend to have their own data area, and one can have | ||
86 | * multiple data areas representing different states for each of the 'client | ||
87 | * instance' code portions. There is generally a list in the kernel data | ||
88 | * that points to the data instances for a given piece of code. | ||
89 | * | ||
90 | * We've only been given the binary image for the 'minisrc', mini sample | ||
91 | * rate converter. This is rather annoying because it limits the work | ||
92 | * we can do on the dsp, but it also greatly simplifies the job of managing | ||
93 | * dsp data memory for the code and data for our playing streams :). We | ||
94 | * statically allocate the minisrc code into a region we 'know' to be free | ||
95 | * based on the map of the binary kernel image we're loading. We also | ||
96 | * statically allocate the data areas for the maximum number of pcm streams | ||
97 | * we can be dealing with. This max is set by the length of the static list | ||
98 | * in the kernel data that records the number of minisrc data regions we | ||
99 | * can have. Thats right, all software dsp mixing with static code list | ||
100 | * limits. Rock. | ||
101 | * | ||
102 | * How sound goes in and out is still a relative mystery. It appears | ||
103 | * that the dsp has the ability to get input and output through various | ||
104 | * 'connections'. To do IO from or to a connection, you put the address | ||
105 | * of the minisrc client area in the static kernel data lists for that | ||
106 | * input or output. so for pcm -> dsp -> mixer, we put the minisrc data | ||
107 | * instance in the DMA list and also in the list for the mixer. I guess | ||
108 | * it Just Knows which is in/out, and we give some dma control info that | ||
109 | * helps. There are all sorts of cool inputs/outputs that it seems we can't | ||
110 | * use without dsp code images that know how to use them. | ||
111 | * | ||
112 | * So at init time we preload all the memory allocation stuff and set some | ||
113 | * system wide parameters. When we really get a sound to play we build | ||
114 | * up its minisrc header (stream parameters, buffer addresses, input/output | ||
115 | * settings). Then we throw its header on the various lists. We also | ||
116 | * tickle some KDATA settings that ask the assp to raise clock interrupts | ||
117 | * and do some amount of software mixing before handing data to the ac97. | ||
118 | * | ||
119 | * Sorry for the vague details. Feel free to ask Eric or myself if you | ||
120 | * happen to be trying to use this driver elsewhere. Please accept my | ||
121 | * apologies for the quality of the OSS support code, its passed through | ||
122 | * too many hands now and desperately wants to be rethought. | ||
123 | */ | ||
124 | |||
125 | /*****************************************************************************/ | ||
126 | |||
127 | #include <linux/config.h> | ||
128 | #include <linux/module.h> | ||
129 | #include <linux/kernel.h> | ||
130 | #include <linux/string.h> | ||
131 | #include <linux/ctype.h> | ||
132 | #include <linux/ioport.h> | ||
133 | #include <linux/sched.h> | ||
134 | #include <linux/delay.h> | ||
135 | #include <linux/sound.h> | ||
136 | #include <linux/slab.h> | ||
137 | #include <linux/soundcard.h> | ||
138 | #include <linux/pci.h> | ||
139 | #include <linux/vmalloc.h> | ||
140 | #include <linux/init.h> | ||
141 | #include <linux/interrupt.h> | ||
142 | #include <linux/poll.h> | ||
143 | #include <linux/reboot.h> | ||
144 | #include <linux/spinlock.h> | ||
145 | #include <linux/ac97_codec.h> | ||
146 | #include <linux/wait.h> | ||
147 | #include <linux/mutex.h> | ||
148 | |||
149 | |||
150 | #include <asm/io.h> | ||
151 | #include <asm/dma.h> | ||
152 | #include <asm/uaccess.h> | ||
153 | |||
154 | #include "maestro3.h" | ||
155 | |||
156 | #define M_DEBUG 1 | ||
157 | |||
158 | #define DRIVER_VERSION "1.23" | ||
159 | #define M3_MODULE_NAME "maestro3" | ||
160 | #define PFX M3_MODULE_NAME ": " | ||
161 | |||
162 | #define M3_STATE_MAGIC 0x734d724d | ||
163 | #define M3_CARD_MAGIC 0x646e6f50 | ||
164 | |||
165 | #define ESS_FMT_STEREO 0x01 | ||
166 | #define ESS_FMT_16BIT 0x02 | ||
167 | #define ESS_FMT_MASK 0x03 | ||
168 | #define ESS_DAC_SHIFT 0 | ||
169 | #define ESS_ADC_SHIFT 4 | ||
170 | |||
171 | #define DAC_RUNNING 1 | ||
172 | #define ADC_RUNNING 2 | ||
173 | |||
174 | #define SND_DEV_DSP16 5 | ||
175 | |||
176 | #ifdef M_DEBUG | ||
177 | static int debug; | ||
178 | #define DPMOD 1 /* per module load */ | ||
179 | #define DPSTR 2 /* per 'stream' */ | ||
180 | #define DPSYS 3 /* per syscall */ | ||
181 | #define DPCRAP 4 /* stuff the user shouldn't see unless they're really debuggin */ | ||
182 | #define DPINT 5 /* per interrupt, LOTS */ | ||
183 | #define DPRINTK(DP, args...) {if (debug >= (DP)) printk(KERN_DEBUG PFX args);} | ||
184 | #else | ||
185 | #define DPRINTK(x) | ||
186 | #endif | ||
187 | |||
188 | struct m3_list { | ||
189 | int curlen; | ||
190 | u16 mem_addr; | ||
191 | int max; | ||
192 | }; | ||
193 | |||
194 | static int external_amp = 1; | ||
195 | static int gpio_pin = -1; | ||
196 | |||
197 | struct m3_state { | ||
198 | unsigned int magic; | ||
199 | struct m3_card *card; | ||
200 | unsigned char fmt, enable; | ||
201 | |||
202 | int index; | ||
203 | |||
204 | /* this locks around the oss state in the driver */ | ||
205 | /* no, this lock is removed - only use card->lock */ | ||
206 | /* otherwise: against what are you protecting on SMP | ||
207 | when irqhandler uses s->lock | ||
208 | and m3_assp_read uses card->lock ? | ||
209 | */ | ||
210 | struct mutex open_mutex; | ||
211 | wait_queue_head_t open_wait; | ||
212 | mode_t open_mode; | ||
213 | |||
214 | int dev_audio; | ||
215 | |||
216 | struct assp_instance { | ||
217 | u16 code, data; | ||
218 | } dac_inst, adc_inst; | ||
219 | |||
220 | /* should be in dmabuf */ | ||
221 | unsigned int rateadc, ratedac; | ||
222 | |||
223 | struct dmabuf { | ||
224 | void *rawbuf; | ||
225 | unsigned buforder; | ||
226 | unsigned numfrag; | ||
227 | unsigned fragshift; | ||
228 | unsigned hwptr, swptr; | ||
229 | unsigned total_bytes; | ||
230 | int count; | ||
231 | unsigned error; /* over/underrun */ | ||
232 | wait_queue_head_t wait; | ||
233 | /* redundant, but makes calculations easier */ | ||
234 | unsigned fragsize; | ||
235 | unsigned dmasize; | ||
236 | unsigned fragsamples; | ||
237 | /* OSS stuff */ | ||
238 | unsigned mapped:1; | ||
239 | unsigned ready:1; | ||
240 | unsigned endcleared:1; | ||
241 | unsigned ossfragshift; | ||
242 | int ossmaxfrags; | ||
243 | unsigned subdivision; | ||
244 | /* new in m3 */ | ||
245 | int mixer_index, dma_index, msrc_index, adc1_index; | ||
246 | int in_lists; | ||
247 | /* 2.4.. */ | ||
248 | dma_addr_t handle; | ||
249 | |||
250 | } dma_dac, dma_adc; | ||
251 | }; | ||
252 | |||
253 | struct m3_card { | ||
254 | unsigned int magic; | ||
255 | |||
256 | struct m3_card *next; | ||
257 | |||
258 | struct ac97_codec *ac97; | ||
259 | spinlock_t ac97_lock; | ||
260 | |||
261 | int card_type; | ||
262 | |||
263 | #define NR_DSPS 1 | ||
264 | #define MAX_DSPS NR_DSPS | ||
265 | struct m3_state channels[MAX_DSPS]; | ||
266 | |||
267 | /* this locks around the physical registers on the card */ | ||
268 | spinlock_t lock; | ||
269 | |||
270 | /* hardware resources */ | ||
271 | struct pci_dev *pcidev; | ||
272 | u32 iobase; | ||
273 | u32 irq; | ||
274 | |||
275 | int dacs_active; | ||
276 | |||
277 | int timer_users; | ||
278 | |||
279 | struct m3_list msrc_list, | ||
280 | mixer_list, | ||
281 | adc1_list, | ||
282 | dma_list; | ||
283 | |||
284 | /* for storing reset state..*/ | ||
285 | u8 reset_state; | ||
286 | |||
287 | u16 *suspend_mem; | ||
288 | int in_suspend; | ||
289 | wait_queue_head_t suspend_queue; | ||
290 | }; | ||
291 | |||
292 | /* | ||
293 | * an arbitrary volume we set the internal | ||
294 | * volume settings to so that the ac97 volume | ||
295 | * range is a little less insane. 0x7fff is | ||
296 | * max. | ||
297 | */ | ||
298 | #define ARB_VOLUME ( 0x6800 ) | ||
299 | |||
300 | static const unsigned sample_shift[] = { 0, 1, 1, 2 }; | ||
301 | |||
302 | enum { | ||
303 | ESS_ALLEGRO, | ||
304 | ESS_MAESTRO3, | ||
305 | /* | ||
306 | * a maestro3 with 'hardware strapping', only | ||
307 | * found inside ESS? | ||
308 | */ | ||
309 | ESS_MAESTRO3HW, | ||
310 | }; | ||
311 | |||
312 | static char *card_names[] = { | ||
313 | [ESS_ALLEGRO] = "Allegro", | ||
314 | [ESS_MAESTRO3] = "Maestro3(i)", | ||
315 | [ESS_MAESTRO3HW] = "Maestro3(i)hw" | ||
316 | }; | ||
317 | |||
318 | #ifndef PCI_VENDOR_ESS | ||
319 | #define PCI_VENDOR_ESS 0x125D | ||
320 | #endif | ||
321 | |||
322 | #define M3_DEVICE(DEV, TYPE) \ | ||
323 | { \ | ||
324 | .vendor = PCI_VENDOR_ESS, \ | ||
325 | .device = DEV, \ | ||
326 | .subvendor = PCI_ANY_ID, \ | ||
327 | .subdevice = PCI_ANY_ID, \ | ||
328 | .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8, \ | ||
329 | .class_mask = 0xffff << 8, \ | ||
330 | .driver_data = TYPE, \ | ||
331 | } | ||
332 | |||
333 | static struct pci_device_id m3_id_table[] = { | ||
334 | M3_DEVICE(0x1988, ESS_ALLEGRO), | ||
335 | M3_DEVICE(0x1998, ESS_MAESTRO3), | ||
336 | M3_DEVICE(0x199a, ESS_MAESTRO3HW), | ||
337 | {0,} | ||
338 | }; | ||
339 | |||
340 | MODULE_DEVICE_TABLE (pci, m3_id_table); | ||
341 | |||
342 | /* | ||
343 | * reports seem to indicate that the m3 is limited | ||
344 | * to 28bit bus addresses. aaaargggh... | ||
345 | */ | ||
346 | #define M3_PCI_DMA_MASK 0x0fffffff | ||
347 | |||
348 | static unsigned | ||
349 | ld2(unsigned int x) | ||
350 | { | ||
351 | unsigned r = 0; | ||
352 | |||
353 | if (x >= 0x10000) { | ||
354 | x >>= 16; | ||
355 | r += 16; | ||
356 | } | ||
357 | if (x >= 0x100) { | ||
358 | x >>= 8; | ||
359 | r += 8; | ||
360 | } | ||
361 | if (x >= 0x10) { | ||
362 | x >>= 4; | ||
363 | r += 4; | ||
364 | } | ||
365 | if (x >= 4) { | ||
366 | x >>= 2; | ||
367 | r += 2; | ||
368 | } | ||
369 | if (x >= 2) | ||
370 | r++; | ||
371 | return r; | ||
372 | } | ||
373 | |||
374 | static struct m3_card *devs; | ||
375 | |||
376 | /* | ||
377 | * I'm not very good at laying out functions in a file :) | ||
378 | */ | ||
379 | static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf); | ||
380 | static int m3_suspend(struct pci_dev *pci_dev, pm_message_t state); | ||
381 | static void check_suspend(struct m3_card *card); | ||
382 | |||
383 | static struct notifier_block m3_reboot_nb = { | ||
384 | .notifier_call = m3_notifier, | ||
385 | }; | ||
386 | |||
387 | static void m3_outw(struct m3_card *card, | ||
388 | u16 value, unsigned long reg) | ||
389 | { | ||
390 | check_suspend(card); | ||
391 | outw(value, card->iobase + reg); | ||
392 | } | ||
393 | |||
394 | static u16 m3_inw(struct m3_card *card, unsigned long reg) | ||
395 | { | ||
396 | check_suspend(card); | ||
397 | return inw(card->iobase + reg); | ||
398 | } | ||
399 | static void m3_outb(struct m3_card *card, | ||
400 | u8 value, unsigned long reg) | ||
401 | { | ||
402 | check_suspend(card); | ||
403 | outb(value, card->iobase + reg); | ||
404 | } | ||
405 | static u8 m3_inb(struct m3_card *card, unsigned long reg) | ||
406 | { | ||
407 | check_suspend(card); | ||
408 | return inb(card->iobase + reg); | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * access 16bit words to the code or data regions of the dsp's memory. | ||
413 | * index addresses 16bit words. | ||
414 | */ | ||
415 | static u16 __m3_assp_read(struct m3_card *card, u16 region, u16 index) | ||
416 | { | ||
417 | m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE); | ||
418 | m3_outw(card, index, DSP_PORT_MEMORY_INDEX); | ||
419 | return m3_inw(card, DSP_PORT_MEMORY_DATA); | ||
420 | } | ||
421 | static u16 m3_assp_read(struct m3_card *card, u16 region, u16 index) | ||
422 | { | ||
423 | unsigned long flags; | ||
424 | u16 ret; | ||
425 | |||
426 | spin_lock_irqsave(&(card->lock), flags); | ||
427 | ret = __m3_assp_read(card, region, index); | ||
428 | spin_unlock_irqrestore(&(card->lock), flags); | ||
429 | |||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | static void __m3_assp_write(struct m3_card *card, | ||
434 | u16 region, u16 index, u16 data) | ||
435 | { | ||
436 | m3_outw(card, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE); | ||
437 | m3_outw(card, index, DSP_PORT_MEMORY_INDEX); | ||
438 | m3_outw(card, data, DSP_PORT_MEMORY_DATA); | ||
439 | } | ||
440 | static void m3_assp_write(struct m3_card *card, | ||
441 | u16 region, u16 index, u16 data) | ||
442 | { | ||
443 | unsigned long flags; | ||
444 | |||
445 | spin_lock_irqsave(&(card->lock), flags); | ||
446 | __m3_assp_write(card, region, index, data); | ||
447 | spin_unlock_irqrestore(&(card->lock), flags); | ||
448 | } | ||
449 | |||
450 | static void m3_assp_halt(struct m3_card *card) | ||
451 | { | ||
452 | card->reset_state = m3_inb(card, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK; | ||
453 | mdelay(10); | ||
454 | m3_outb(card, card->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B); | ||
455 | } | ||
456 | |||
457 | static void m3_assp_continue(struct m3_card *card) | ||
458 | { | ||
459 | m3_outb(card, card->reset_state | REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B); | ||
460 | } | ||
461 | |||
462 | /* | ||
463 | * This makes me sad. the maestro3 has lists | ||
464 | * internally that must be packed.. 0 terminates, | ||
465 | * apparently, or maybe all unused entries have | ||
466 | * to be 0, the lists have static lengths set | ||
467 | * by the binary code images. | ||
468 | */ | ||
469 | |||
470 | static int m3_add_list(struct m3_card *card, | ||
471 | struct m3_list *list, u16 val) | ||
472 | { | ||
473 | DPRINTK(DPSTR, "adding val 0x%x to list 0x%p at pos %d\n", | ||
474 | val, list, list->curlen); | ||
475 | |||
476 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
477 | list->mem_addr + list->curlen, | ||
478 | val); | ||
479 | |||
480 | return list->curlen++; | ||
481 | |||
482 | } | ||
483 | |||
484 | static void m3_remove_list(struct m3_card *card, | ||
485 | struct m3_list *list, int index) | ||
486 | { | ||
487 | u16 val; | ||
488 | int lastindex = list->curlen - 1; | ||
489 | |||
490 | DPRINTK(DPSTR, "removing ind %d from list 0x%p\n", | ||
491 | index, list); | ||
492 | |||
493 | if(index != lastindex) { | ||
494 | val = m3_assp_read(card, MEMTYPE_INTERNAL_DATA, | ||
495 | list->mem_addr + lastindex); | ||
496 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
497 | list->mem_addr + index, | ||
498 | val); | ||
499 | } | ||
500 | |||
501 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
502 | list->mem_addr + lastindex, | ||
503 | 0); | ||
504 | |||
505 | list->curlen--; | ||
506 | } | ||
507 | |||
508 | static void set_fmt(struct m3_state *s, unsigned char mask, unsigned char data) | ||
509 | { | ||
510 | int tmp; | ||
511 | |||
512 | s->fmt = (s->fmt & mask) | data; | ||
513 | |||
514 | tmp = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK; | ||
515 | |||
516 | /* write to 'mono' word */ | ||
517 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
518 | s->dac_inst.data + SRC3_DIRECTION_OFFSET + 1, | ||
519 | (tmp & ESS_FMT_STEREO) ? 0 : 1); | ||
520 | /* write to '8bit' word */ | ||
521 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
522 | s->dac_inst.data + SRC3_DIRECTION_OFFSET + 2, | ||
523 | (tmp & ESS_FMT_16BIT) ? 0 : 1); | ||
524 | |||
525 | tmp = (s->fmt >> ESS_ADC_SHIFT) & ESS_FMT_MASK; | ||
526 | |||
527 | /* write to 'mono' word */ | ||
528 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
529 | s->adc_inst.data + SRC3_DIRECTION_OFFSET + 1, | ||
530 | (tmp & ESS_FMT_STEREO) ? 0 : 1); | ||
531 | /* write to '8bit' word */ | ||
532 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
533 | s->adc_inst.data + SRC3_DIRECTION_OFFSET + 2, | ||
534 | (tmp & ESS_FMT_16BIT) ? 0 : 1); | ||
535 | } | ||
536 | |||
537 | static void set_dac_rate(struct m3_state *s, unsigned int rate) | ||
538 | { | ||
539 | u32 freq; | ||
540 | |||
541 | if (rate > 48000) | ||
542 | rate = 48000; | ||
543 | if (rate < 8000) | ||
544 | rate = 8000; | ||
545 | |||
546 | s->ratedac = rate; | ||
547 | |||
548 | freq = ((rate << 15) + 24000 ) / 48000; | ||
549 | if(freq) | ||
550 | freq--; | ||
551 | |||
552 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
553 | s->dac_inst.data + CDATA_FREQUENCY, | ||
554 | freq); | ||
555 | } | ||
556 | |||
557 | static void set_adc_rate(struct m3_state *s, unsigned int rate) | ||
558 | { | ||
559 | u32 freq; | ||
560 | |||
561 | if (rate > 48000) | ||
562 | rate = 48000; | ||
563 | if (rate < 8000) | ||
564 | rate = 8000; | ||
565 | |||
566 | s->rateadc = rate; | ||
567 | |||
568 | freq = ((rate << 15) + 24000 ) / 48000; | ||
569 | if(freq) | ||
570 | freq--; | ||
571 | |||
572 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
573 | s->adc_inst.data + CDATA_FREQUENCY, | ||
574 | freq); | ||
575 | } | ||
576 | |||
577 | static void inc_timer_users(struct m3_card *card) | ||
578 | { | ||
579 | unsigned long flags; | ||
580 | |||
581 | spin_lock_irqsave(&card->lock, flags); | ||
582 | |||
583 | card->timer_users++; | ||
584 | DPRINTK(DPSYS, "inc timer users now %d\n", | ||
585 | card->timer_users); | ||
586 | if(card->timer_users != 1) | ||
587 | goto out; | ||
588 | |||
589 | __m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
590 | KDATA_TIMER_COUNT_RELOAD, | ||
591 | 240 ) ; | ||
592 | |||
593 | __m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
594 | KDATA_TIMER_COUNT_CURRENT, | ||
595 | 240 ) ; | ||
596 | |||
597 | m3_outw(card, | ||
598 | m3_inw(card, HOST_INT_CTRL) | CLKRUN_GEN_ENABLE, | ||
599 | HOST_INT_CTRL); | ||
600 | out: | ||
601 | spin_unlock_irqrestore(&card->lock, flags); | ||
602 | } | ||
603 | |||
604 | static void dec_timer_users(struct m3_card *card) | ||
605 | { | ||
606 | unsigned long flags; | ||
607 | |||
608 | spin_lock_irqsave(&card->lock, flags); | ||
609 | |||
610 | card->timer_users--; | ||
611 | DPRINTK(DPSYS, "dec timer users now %d\n", | ||
612 | card->timer_users); | ||
613 | if(card->timer_users > 0 ) | ||
614 | goto out; | ||
615 | |||
616 | __m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
617 | KDATA_TIMER_COUNT_RELOAD, | ||
618 | 0 ) ; | ||
619 | |||
620 | __m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
621 | KDATA_TIMER_COUNT_CURRENT, | ||
622 | 0 ) ; | ||
623 | |||
624 | m3_outw(card, m3_inw(card, HOST_INT_CTRL) & ~CLKRUN_GEN_ENABLE, | ||
625 | HOST_INT_CTRL); | ||
626 | out: | ||
627 | spin_unlock_irqrestore(&card->lock, flags); | ||
628 | } | ||
629 | |||
630 | /* | ||
631 | * {start,stop}_{adc,dac} should be called | ||
632 | * while holding the 'state' lock and they | ||
633 | * will try to grab the 'card' lock.. | ||
634 | */ | ||
635 | static void stop_adc(struct m3_state *s) | ||
636 | { | ||
637 | if (! (s->enable & ADC_RUNNING)) | ||
638 | return; | ||
639 | |||
640 | s->enable &= ~ADC_RUNNING; | ||
641 | dec_timer_users(s->card); | ||
642 | |||
643 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
644 | s->adc_inst.data + CDATA_INSTANCE_READY, 0); | ||
645 | |||
646 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
647 | KDATA_ADC1_REQUEST, 0); | ||
648 | } | ||
649 | |||
650 | static void stop_dac(struct m3_state *s) | ||
651 | { | ||
652 | if (! (s->enable & DAC_RUNNING)) | ||
653 | return; | ||
654 | |||
655 | DPRINTK(DPSYS, "stop_dac()\n"); | ||
656 | |||
657 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
658 | s->dac_inst.data + CDATA_INSTANCE_READY, 0); | ||
659 | |||
660 | s->enable &= ~DAC_RUNNING; | ||
661 | s->card->dacs_active--; | ||
662 | dec_timer_users(s->card); | ||
663 | |||
664 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
665 | KDATA_MIXER_TASK_NUMBER, | ||
666 | s->card->dacs_active ) ; | ||
667 | } | ||
668 | |||
669 | static void start_dac(struct m3_state *s) | ||
670 | { | ||
671 | if( (!s->dma_dac.mapped && s->dma_dac.count < 1) || | ||
672 | !s->dma_dac.ready || | ||
673 | (s->enable & DAC_RUNNING)) | ||
674 | return; | ||
675 | |||
676 | DPRINTK(DPSYS, "start_dac()\n"); | ||
677 | |||
678 | s->enable |= DAC_RUNNING; | ||
679 | s->card->dacs_active++; | ||
680 | inc_timer_users(s->card); | ||
681 | |||
682 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
683 | s->dac_inst.data + CDATA_INSTANCE_READY, 1); | ||
684 | |||
685 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
686 | KDATA_MIXER_TASK_NUMBER, | ||
687 | s->card->dacs_active ) ; | ||
688 | } | ||
689 | |||
690 | static void start_adc(struct m3_state *s) | ||
691 | { | ||
692 | if ((! s->dma_adc.mapped && | ||
693 | s->dma_adc.count >= (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) | ||
694 | || !s->dma_adc.ready | ||
695 | || (s->enable & ADC_RUNNING) ) | ||
696 | return; | ||
697 | |||
698 | DPRINTK(DPSYS, "start_adc()\n"); | ||
699 | |||
700 | s->enable |= ADC_RUNNING; | ||
701 | inc_timer_users(s->card); | ||
702 | |||
703 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
704 | KDATA_ADC1_REQUEST, 1); | ||
705 | |||
706 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
707 | s->adc_inst.data + CDATA_INSTANCE_READY, 1); | ||
708 | } | ||
709 | |||
710 | static struct play_vals { | ||
711 | u16 addr, val; | ||
712 | } pv[] = { | ||
713 | {CDATA_LEFT_VOLUME, ARB_VOLUME}, | ||
714 | {CDATA_RIGHT_VOLUME, ARB_VOLUME}, | ||
715 | {SRC3_DIRECTION_OFFSET, 0} , | ||
716 | /* +1, +2 are stereo/16 bit */ | ||
717 | {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */ | ||
718 | {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */ | ||
719 | {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */ | ||
720 | {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */ | ||
721 | {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */ | ||
722 | {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */ | ||
723 | {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */ | ||
724 | {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */ | ||
725 | {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */ | ||
726 | {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */ | ||
727 | {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */ | ||
728 | {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */ | ||
729 | {SRC3_DIRECTION_OFFSET + 16, 8}, /* numin */ | ||
730 | {SRC3_DIRECTION_OFFSET + 17, 50*2}, /* numout */ | ||
731 | {SRC3_DIRECTION_OFFSET + 18, MINISRC_BIQUAD_STAGE - 1}, /* numstage */ | ||
732 | {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */ | ||
733 | {SRC3_DIRECTION_OFFSET + 21, 0} /* booster */ | ||
734 | }; | ||
735 | |||
736 | |||
737 | /* the mode passed should be already shifted and masked */ | ||
738 | static void m3_play_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size) | ||
739 | { | ||
740 | int dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2); | ||
741 | int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x20 * 2); | ||
742 | int dsp_in_buffer = s->dac_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2); | ||
743 | int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1; | ||
744 | struct dmabuf *db = &s->dma_dac; | ||
745 | int i; | ||
746 | |||
747 | DPRINTK(DPSTR, "mode=%d rate=%d buf=%p len=%d.\n", | ||
748 | mode, rate, buffer, size); | ||
749 | |||
750 | #define LO(x) ((x) & 0xffff) | ||
751 | #define HI(x) LO((x) >> 16) | ||
752 | |||
753 | /* host dma buffer pointers */ | ||
754 | |||
755 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
756 | s->dac_inst.data + CDATA_HOST_SRC_ADDRL, | ||
757 | LO(virt_to_bus(buffer))); | ||
758 | |||
759 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
760 | s->dac_inst.data + CDATA_HOST_SRC_ADDRH, | ||
761 | HI(virt_to_bus(buffer))); | ||
762 | |||
763 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
764 | s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1L, | ||
765 | LO(virt_to_bus(buffer) + size)); | ||
766 | |||
767 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
768 | s->dac_inst.data + CDATA_HOST_SRC_END_PLUS_1H, | ||
769 | HI(virt_to_bus(buffer) + size)); | ||
770 | |||
771 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
772 | s->dac_inst.data + CDATA_HOST_SRC_CURRENTL, | ||
773 | LO(virt_to_bus(buffer))); | ||
774 | |||
775 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
776 | s->dac_inst.data + CDATA_HOST_SRC_CURRENTH, | ||
777 | HI(virt_to_bus(buffer))); | ||
778 | #undef LO | ||
779 | #undef HI | ||
780 | |||
781 | /* dsp buffers */ | ||
782 | |||
783 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
784 | s->dac_inst.data + CDATA_IN_BUF_BEGIN, | ||
785 | dsp_in_buffer); | ||
786 | |||
787 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
788 | s->dac_inst.data + CDATA_IN_BUF_END_PLUS_1, | ||
789 | dsp_in_buffer + (dsp_in_size / 2)); | ||
790 | |||
791 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
792 | s->dac_inst.data + CDATA_IN_BUF_HEAD, | ||
793 | dsp_in_buffer); | ||
794 | |||
795 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
796 | s->dac_inst.data + CDATA_IN_BUF_TAIL, | ||
797 | dsp_in_buffer); | ||
798 | |||
799 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
800 | s->dac_inst.data + CDATA_OUT_BUF_BEGIN, | ||
801 | dsp_out_buffer); | ||
802 | |||
803 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
804 | s->dac_inst.data + CDATA_OUT_BUF_END_PLUS_1, | ||
805 | dsp_out_buffer + (dsp_out_size / 2)); | ||
806 | |||
807 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
808 | s->dac_inst.data + CDATA_OUT_BUF_HEAD, | ||
809 | dsp_out_buffer); | ||
810 | |||
811 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
812 | s->dac_inst.data + CDATA_OUT_BUF_TAIL, | ||
813 | dsp_out_buffer); | ||
814 | |||
815 | /* | ||
816 | * some per client initializers | ||
817 | */ | ||
818 | |||
819 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
820 | s->dac_inst.data + SRC3_DIRECTION_OFFSET + 12, | ||
821 | s->dac_inst.data + 40 + 8); | ||
822 | |||
823 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
824 | s->dac_inst.data + SRC3_DIRECTION_OFFSET + 19, | ||
825 | s->dac_inst.code + MINISRC_COEF_LOC); | ||
826 | |||
827 | /* enable or disable low pass filter? */ | ||
828 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
829 | s->dac_inst.data + SRC3_DIRECTION_OFFSET + 22, | ||
830 | s->ratedac > 45000 ? 0xff : 0 ); | ||
831 | |||
832 | /* tell it which way dma is going? */ | ||
833 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
834 | s->dac_inst.data + CDATA_DMA_CONTROL, | ||
835 | DMACONTROL_AUTOREPEAT + DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR); | ||
836 | |||
837 | /* | ||
838 | * set an armload of static initializers | ||
839 | */ | ||
840 | for(i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) | ||
841 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
842 | s->dac_inst.data + pv[i].addr, pv[i].val); | ||
843 | |||
844 | /* | ||
845 | * put us in the lists if we're not already there | ||
846 | */ | ||
847 | |||
848 | if(db->in_lists == 0) { | ||
849 | |||
850 | db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, | ||
851 | s->dac_inst.data >> DP_SHIFT_COUNT); | ||
852 | |||
853 | db->dma_index = m3_add_list(s->card, &s->card->dma_list, | ||
854 | s->dac_inst.data >> DP_SHIFT_COUNT); | ||
855 | |||
856 | db->mixer_index = m3_add_list(s->card, &s->card->mixer_list, | ||
857 | s->dac_inst.data >> DP_SHIFT_COUNT); | ||
858 | |||
859 | db->in_lists = 1; | ||
860 | } | ||
861 | |||
862 | set_dac_rate(s,rate); | ||
863 | start_dac(s); | ||
864 | } | ||
865 | |||
866 | /* | ||
867 | * Native record driver | ||
868 | */ | ||
869 | static struct rec_vals { | ||
870 | u16 addr, val; | ||
871 | } rv[] = { | ||
872 | {CDATA_LEFT_VOLUME, ARB_VOLUME}, | ||
873 | {CDATA_RIGHT_VOLUME, ARB_VOLUME}, | ||
874 | {SRC3_DIRECTION_OFFSET, 1} , | ||
875 | /* +1, +2 are stereo/16 bit */ | ||
876 | {SRC3_DIRECTION_OFFSET + 3, 0x0000}, /* fraction? */ | ||
877 | {SRC3_DIRECTION_OFFSET + 4, 0}, /* first l */ | ||
878 | {SRC3_DIRECTION_OFFSET + 5, 0}, /* first r */ | ||
879 | {SRC3_DIRECTION_OFFSET + 6, 0}, /* second l */ | ||
880 | {SRC3_DIRECTION_OFFSET + 7, 0}, /* second r */ | ||
881 | {SRC3_DIRECTION_OFFSET + 8, 0}, /* delta l */ | ||
882 | {SRC3_DIRECTION_OFFSET + 9, 0}, /* delta r */ | ||
883 | {SRC3_DIRECTION_OFFSET + 10, 0x8000}, /* round */ | ||
884 | {SRC3_DIRECTION_OFFSET + 11, 0xFF00}, /* higher bute mark */ | ||
885 | {SRC3_DIRECTION_OFFSET + 13, 0}, /* temp0 */ | ||
886 | {SRC3_DIRECTION_OFFSET + 14, 0}, /* c fraction */ | ||
887 | {SRC3_DIRECTION_OFFSET + 15, 0}, /* counter */ | ||
888 | {SRC3_DIRECTION_OFFSET + 16, 50},/* numin */ | ||
889 | {SRC3_DIRECTION_OFFSET + 17, 8}, /* numout */ | ||
890 | {SRC3_DIRECTION_OFFSET + 18, 0}, /* numstage */ | ||
891 | {SRC3_DIRECTION_OFFSET + 19, 0}, /* coef */ | ||
892 | {SRC3_DIRECTION_OFFSET + 20, 0}, /* filtertap */ | ||
893 | {SRC3_DIRECTION_OFFSET + 21, 0}, /* booster */ | ||
894 | {SRC3_DIRECTION_OFFSET + 22, 0xff} /* skip lpf */ | ||
895 | }; | ||
896 | |||
897 | /* again, passed mode is alrady shifted/masked */ | ||
898 | static void m3_rec_setup(struct m3_state *s, int mode, u32 rate, void *buffer, int size) | ||
899 | { | ||
900 | int dsp_in_size = MINISRC_IN_BUFFER_SIZE + (0x10 * 2); | ||
901 | int dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x10 * 2); | ||
902 | int dsp_in_buffer = s->adc_inst.data + (MINISRC_TMP_BUFFER_SIZE / 2); | ||
903 | int dsp_out_buffer = dsp_in_buffer + (dsp_in_size / 2) + 1; | ||
904 | struct dmabuf *db = &s->dma_adc; | ||
905 | int i; | ||
906 | |||
907 | DPRINTK(DPSTR, "rec_setup mode=%d rate=%d buf=%p len=%d.\n", | ||
908 | mode, rate, buffer, size); | ||
909 | |||
910 | #define LO(x) ((x) & 0xffff) | ||
911 | #define HI(x) LO((x) >> 16) | ||
912 | |||
913 | /* host dma buffer pointers */ | ||
914 | |||
915 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
916 | s->adc_inst.data + CDATA_HOST_SRC_ADDRL, | ||
917 | LO(virt_to_bus(buffer))); | ||
918 | |||
919 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
920 | s->adc_inst.data + CDATA_HOST_SRC_ADDRH, | ||
921 | HI(virt_to_bus(buffer))); | ||
922 | |||
923 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
924 | s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1L, | ||
925 | LO(virt_to_bus(buffer) + size)); | ||
926 | |||
927 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
928 | s->adc_inst.data + CDATA_HOST_SRC_END_PLUS_1H, | ||
929 | HI(virt_to_bus(buffer) + size)); | ||
930 | |||
931 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
932 | s->adc_inst.data + CDATA_HOST_SRC_CURRENTL, | ||
933 | LO(virt_to_bus(buffer))); | ||
934 | |||
935 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
936 | s->adc_inst.data + CDATA_HOST_SRC_CURRENTH, | ||
937 | HI(virt_to_bus(buffer))); | ||
938 | #undef LO | ||
939 | #undef HI | ||
940 | |||
941 | /* dsp buffers */ | ||
942 | |||
943 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
944 | s->adc_inst.data + CDATA_IN_BUF_BEGIN, | ||
945 | dsp_in_buffer); | ||
946 | |||
947 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
948 | s->adc_inst.data + CDATA_IN_BUF_END_PLUS_1, | ||
949 | dsp_in_buffer + (dsp_in_size / 2)); | ||
950 | |||
951 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
952 | s->adc_inst.data + CDATA_IN_BUF_HEAD, | ||
953 | dsp_in_buffer); | ||
954 | |||
955 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
956 | s->adc_inst.data + CDATA_IN_BUF_TAIL, | ||
957 | dsp_in_buffer); | ||
958 | |||
959 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
960 | s->adc_inst.data + CDATA_OUT_BUF_BEGIN, | ||
961 | dsp_out_buffer); | ||
962 | |||
963 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
964 | s->adc_inst.data + CDATA_OUT_BUF_END_PLUS_1, | ||
965 | dsp_out_buffer + (dsp_out_size / 2)); | ||
966 | |||
967 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
968 | s->adc_inst.data + CDATA_OUT_BUF_HEAD, | ||
969 | dsp_out_buffer); | ||
970 | |||
971 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
972 | s->adc_inst.data + CDATA_OUT_BUF_TAIL, | ||
973 | dsp_out_buffer); | ||
974 | |||
975 | /* | ||
976 | * some per client initializers | ||
977 | */ | ||
978 | |||
979 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
980 | s->adc_inst.data + SRC3_DIRECTION_OFFSET + 12, | ||
981 | s->adc_inst.data + 40 + 8); | ||
982 | |||
983 | /* tell it which way dma is going? */ | ||
984 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
985 | s->adc_inst.data + CDATA_DMA_CONTROL, | ||
986 | DMACONTROL_DIRECTION + DMACONTROL_AUTOREPEAT + | ||
987 | DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR); | ||
988 | |||
989 | /* | ||
990 | * set an armload of static initializers | ||
991 | */ | ||
992 | for(i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) | ||
993 | m3_assp_write(s->card, MEMTYPE_INTERNAL_DATA, | ||
994 | s->adc_inst.data + rv[i].addr, rv[i].val); | ||
995 | |||
996 | /* | ||
997 | * put us in the lists if we're not already there | ||
998 | */ | ||
999 | |||
1000 | if(db->in_lists == 0) { | ||
1001 | |||
1002 | db->adc1_index = m3_add_list(s->card, &s->card->adc1_list, | ||
1003 | s->adc_inst.data >> DP_SHIFT_COUNT); | ||
1004 | |||
1005 | db->dma_index = m3_add_list(s->card, &s->card->dma_list, | ||
1006 | s->adc_inst.data >> DP_SHIFT_COUNT); | ||
1007 | |||
1008 | db->msrc_index = m3_add_list(s->card, &s->card->msrc_list, | ||
1009 | s->adc_inst.data >> DP_SHIFT_COUNT); | ||
1010 | |||
1011 | db->in_lists = 1; | ||
1012 | } | ||
1013 | |||
1014 | set_adc_rate(s,rate); | ||
1015 | start_adc(s); | ||
1016 | } | ||
1017 | /* --------------------------------------------------------------------- */ | ||
1018 | |||
1019 | static void set_dmaa(struct m3_state *s, unsigned int addr, unsigned int count) | ||
1020 | { | ||
1021 | DPRINTK(DPINT,"set_dmaa??\n"); | ||
1022 | } | ||
1023 | |||
1024 | static void set_dmac(struct m3_state *s, unsigned int addr, unsigned int count) | ||
1025 | { | ||
1026 | DPRINTK(DPINT,"set_dmac??\n"); | ||
1027 | } | ||
1028 | |||
1029 | static u32 get_dma_pos(struct m3_card *card, | ||
1030 | int instance_addr) | ||
1031 | { | ||
1032 | u16 hi = 0, lo = 0; | ||
1033 | int retry = 10; | ||
1034 | |||
1035 | /* | ||
1036 | * try and get a valid answer | ||
1037 | */ | ||
1038 | while(retry--) { | ||
1039 | hi = m3_assp_read(card, MEMTYPE_INTERNAL_DATA, | ||
1040 | instance_addr + CDATA_HOST_SRC_CURRENTH); | ||
1041 | |||
1042 | lo = m3_assp_read(card, MEMTYPE_INTERNAL_DATA, | ||
1043 | instance_addr + CDATA_HOST_SRC_CURRENTL); | ||
1044 | |||
1045 | if(hi == m3_assp_read(card, MEMTYPE_INTERNAL_DATA, | ||
1046 | instance_addr + CDATA_HOST_SRC_CURRENTH)) | ||
1047 | break; | ||
1048 | } | ||
1049 | return lo | (hi<<16); | ||
1050 | } | ||
1051 | |||
1052 | static u32 get_dmaa(struct m3_state *s) | ||
1053 | { | ||
1054 | u32 offset; | ||
1055 | |||
1056 | offset = get_dma_pos(s->card, s->dac_inst.data) - | ||
1057 | virt_to_bus(s->dma_dac.rawbuf); | ||
1058 | |||
1059 | DPRINTK(DPINT,"get_dmaa: 0x%08x\n",offset); | ||
1060 | |||
1061 | return offset; | ||
1062 | } | ||
1063 | |||
1064 | static u32 get_dmac(struct m3_state *s) | ||
1065 | { | ||
1066 | u32 offset; | ||
1067 | |||
1068 | offset = get_dma_pos(s->card, s->adc_inst.data) - | ||
1069 | virt_to_bus(s->dma_adc.rawbuf); | ||
1070 | |||
1071 | DPRINTK(DPINT,"get_dmac: 0x%08x\n",offset); | ||
1072 | |||
1073 | return offset; | ||
1074 | |||
1075 | } | ||
1076 | |||
1077 | static int | ||
1078 | prog_dmabuf(struct m3_state *s, unsigned rec) | ||
1079 | { | ||
1080 | struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac; | ||
1081 | unsigned rate = rec ? s->rateadc : s->ratedac; | ||
1082 | unsigned bytepersec; | ||
1083 | unsigned bufs; | ||
1084 | unsigned char fmt; | ||
1085 | unsigned long flags; | ||
1086 | |||
1087 | spin_lock_irqsave(&s->card->lock, flags); | ||
1088 | |||
1089 | fmt = s->fmt; | ||
1090 | if (rec) { | ||
1091 | stop_adc(s); | ||
1092 | fmt >>= ESS_ADC_SHIFT; | ||
1093 | } else { | ||
1094 | stop_dac(s); | ||
1095 | fmt >>= ESS_DAC_SHIFT; | ||
1096 | } | ||
1097 | fmt &= ESS_FMT_MASK; | ||
1098 | |||
1099 | db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; | ||
1100 | |||
1101 | bytepersec = rate << sample_shift[fmt]; | ||
1102 | bufs = PAGE_SIZE << db->buforder; | ||
1103 | if (db->ossfragshift) { | ||
1104 | if ((1000 << db->ossfragshift) < bytepersec) | ||
1105 | db->fragshift = ld2(bytepersec/1000); | ||
1106 | else | ||
1107 | db->fragshift = db->ossfragshift; | ||
1108 | } else { | ||
1109 | db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); | ||
1110 | if (db->fragshift < 3) | ||
1111 | db->fragshift = 3; | ||
1112 | } | ||
1113 | db->numfrag = bufs >> db->fragshift; | ||
1114 | while (db->numfrag < 4 && db->fragshift > 3) { | ||
1115 | db->fragshift--; | ||
1116 | db->numfrag = bufs >> db->fragshift; | ||
1117 | } | ||
1118 | db->fragsize = 1 << db->fragshift; | ||
1119 | if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) | ||
1120 | db->numfrag = db->ossmaxfrags; | ||
1121 | db->fragsamples = db->fragsize >> sample_shift[fmt]; | ||
1122 | db->dmasize = db->numfrag << db->fragshift; | ||
1123 | |||
1124 | DPRINTK(DPSTR,"prog_dmabuf: numfrag: %d fragsize: %d dmasize: %d\n",db->numfrag,db->fragsize,db->dmasize); | ||
1125 | |||
1126 | memset(db->rawbuf, (fmt & ESS_FMT_16BIT) ? 0 : 0x80, db->dmasize); | ||
1127 | |||
1128 | if (rec) | ||
1129 | m3_rec_setup(s, fmt, s->rateadc, db->rawbuf, db->dmasize); | ||
1130 | else | ||
1131 | m3_play_setup(s, fmt, s->ratedac, db->rawbuf, db->dmasize); | ||
1132 | |||
1133 | db->ready = 1; | ||
1134 | |||
1135 | spin_unlock_irqrestore(&s->card->lock, flags); | ||
1136 | |||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
1140 | static void clear_advance(struct m3_state *s) | ||
1141 | { | ||
1142 | unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80; | ||
1143 | |||
1144 | unsigned char *buf = s->dma_dac.rawbuf; | ||
1145 | unsigned bsize = s->dma_dac.dmasize; | ||
1146 | unsigned bptr = s->dma_dac.swptr; | ||
1147 | unsigned len = s->dma_dac.fragsize; | ||
1148 | |||
1149 | if (bptr + len > bsize) { | ||
1150 | unsigned x = bsize - bptr; | ||
1151 | memset(buf + bptr, c, x); | ||
1152 | /* account for wrapping? */ | ||
1153 | bptr = 0; | ||
1154 | len -= x; | ||
1155 | } | ||
1156 | memset(buf + bptr, c, len); | ||
1157 | } | ||
1158 | |||
1159 | /* call with spinlock held! */ | ||
1160 | static void m3_update_ptr(struct m3_state *s) | ||
1161 | { | ||
1162 | unsigned hwptr; | ||
1163 | int diff; | ||
1164 | |||
1165 | /* update ADC pointer */ | ||
1166 | if (s->dma_adc.ready) { | ||
1167 | hwptr = get_dmac(s) % s->dma_adc.dmasize; | ||
1168 | diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; | ||
1169 | s->dma_adc.hwptr = hwptr; | ||
1170 | s->dma_adc.total_bytes += diff; | ||
1171 | s->dma_adc.count += diff; | ||
1172 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
1173 | wake_up(&s->dma_adc.wait); | ||
1174 | if (!s->dma_adc.mapped) { | ||
1175 | if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { | ||
1176 | stop_adc(s); | ||
1177 | /* brute force everyone back in sync, sigh */ | ||
1178 | s->dma_adc.count = 0; | ||
1179 | s->dma_adc.swptr = 0; | ||
1180 | s->dma_adc.hwptr = 0; | ||
1181 | s->dma_adc.error++; | ||
1182 | } | ||
1183 | } | ||
1184 | } | ||
1185 | /* update DAC pointer */ | ||
1186 | if (s->dma_dac.ready) { | ||
1187 | hwptr = get_dmaa(s) % s->dma_dac.dmasize; | ||
1188 | diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize; | ||
1189 | |||
1190 | DPRINTK(DPINT,"updating dac: hwptr: %6d diff: %6d count: %6d\n", | ||
1191 | hwptr,diff,s->dma_dac.count); | ||
1192 | |||
1193 | s->dma_dac.hwptr = hwptr; | ||
1194 | s->dma_dac.total_bytes += diff; | ||
1195 | |||
1196 | if (s->dma_dac.mapped) { | ||
1197 | |||
1198 | s->dma_dac.count += diff; | ||
1199 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) { | ||
1200 | wake_up(&s->dma_dac.wait); | ||
1201 | } | ||
1202 | } else { | ||
1203 | |||
1204 | s->dma_dac.count -= diff; | ||
1205 | |||
1206 | if (s->dma_dac.count <= 0) { | ||
1207 | DPRINTK(DPCRAP,"underflow! diff: %d (0x%x) count: %d (0x%x) hw: %d (0x%x) sw: %d (0x%x)\n", | ||
1208 | diff, diff, | ||
1209 | s->dma_dac.count, | ||
1210 | s->dma_dac.count, | ||
1211 | hwptr, hwptr, | ||
1212 | s->dma_dac.swptr, | ||
1213 | s->dma_dac.swptr); | ||
1214 | stop_dac(s); | ||
1215 | /* brute force everyone back in sync, sigh */ | ||
1216 | s->dma_dac.count = 0; | ||
1217 | s->dma_dac.swptr = hwptr; | ||
1218 | s->dma_dac.error++; | ||
1219 | } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) { | ||
1220 | clear_advance(s); | ||
1221 | s->dma_dac.endcleared = 1; | ||
1222 | } | ||
1223 | if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) { | ||
1224 | wake_up(&s->dma_dac.wait); | ||
1225 | DPRINTK(DPINT,"waking up DAC count: %d sw: %d hw: %d\n", | ||
1226 | s->dma_dac.count, s->dma_dac.swptr, hwptr); | ||
1227 | } | ||
1228 | } | ||
1229 | } | ||
1230 | } | ||
1231 | |||
1232 | static irqreturn_t m3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1233 | { | ||
1234 | struct m3_card *c = (struct m3_card *)dev_id; | ||
1235 | struct m3_state *s = &c->channels[0]; | ||
1236 | u8 status; | ||
1237 | |||
1238 | status = inb(c->iobase+0x1A); | ||
1239 | |||
1240 | if(status == 0xff) | ||
1241 | return IRQ_NONE; | ||
1242 | |||
1243 | /* presumably acking the ints? */ | ||
1244 | outw(status, c->iobase+0x1A); | ||
1245 | |||
1246 | if(c->in_suspend) | ||
1247 | return IRQ_HANDLED; | ||
1248 | |||
1249 | /* | ||
1250 | * ack an assp int if its running | ||
1251 | * and has an int pending | ||
1252 | */ | ||
1253 | if( status & ASSP_INT_PENDING) { | ||
1254 | u8 ctl = inb(c->iobase + ASSP_CONTROL_B); | ||
1255 | if( !(ctl & STOP_ASSP_CLOCK)) { | ||
1256 | ctl = inb(c->iobase + ASSP_HOST_INT_STATUS ); | ||
1257 | if(ctl & DSP2HOST_REQ_TIMER) { | ||
1258 | outb( DSP2HOST_REQ_TIMER, c->iobase + ASSP_HOST_INT_STATUS); | ||
1259 | /* update adc/dac info if it was a timer int */ | ||
1260 | spin_lock(&c->lock); | ||
1261 | m3_update_ptr(s); | ||
1262 | spin_unlock(&c->lock); | ||
1263 | } | ||
1264 | } | ||
1265 | } | ||
1266 | |||
1267 | /* XXX is this needed? */ | ||
1268 | if(status & 0x40) | ||
1269 | outb(0x40, c->iobase+0x1A); | ||
1270 | return IRQ_HANDLED; | ||
1271 | } | ||
1272 | |||
1273 | |||
1274 | /* --------------------------------------------------------------------- */ | ||
1275 | |||
1276 | static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value in %s\n"; | ||
1277 | |||
1278 | #define VALIDATE_MAGIC(FOO,MAG) \ | ||
1279 | ({ \ | ||
1280 | if (!(FOO) || (FOO)->magic != MAG) { \ | ||
1281 | printk(invalid_magic,__FUNCTION__); \ | ||
1282 | return -ENXIO; \ | ||
1283 | } \ | ||
1284 | }) | ||
1285 | |||
1286 | #define VALIDATE_STATE(a) VALIDATE_MAGIC(a,M3_STATE_MAGIC) | ||
1287 | #define VALIDATE_CARD(a) VALIDATE_MAGIC(a,M3_CARD_MAGIC) | ||
1288 | |||
1289 | /* --------------------------------------------------------------------- */ | ||
1290 | |||
1291 | static int drain_dac(struct m3_state *s, int nonblock) | ||
1292 | { | ||
1293 | DECLARE_WAITQUEUE(wait,current); | ||
1294 | unsigned long flags; | ||
1295 | int count; | ||
1296 | signed long tmo; | ||
1297 | |||
1298 | if (s->dma_dac.mapped || !s->dma_dac.ready) | ||
1299 | return 0; | ||
1300 | set_current_state(TASK_INTERRUPTIBLE); | ||
1301 | add_wait_queue(&s->dma_dac.wait, &wait); | ||
1302 | for (;;) { | ||
1303 | spin_lock_irqsave(&s->card->lock, flags); | ||
1304 | count = s->dma_dac.count; | ||
1305 | spin_unlock_irqrestore(&s->card->lock, flags); | ||
1306 | if (count <= 0) | ||
1307 | break; | ||
1308 | if (signal_pending(current)) | ||
1309 | break; | ||
1310 | if (nonblock) { | ||
1311 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
1312 | set_current_state(TASK_RUNNING); | ||
1313 | return -EBUSY; | ||
1314 | } | ||
1315 | tmo = (count * HZ) / s->ratedac; | ||
1316 | tmo >>= sample_shift[(s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK]; | ||
1317 | /* XXX this is just broken. someone is waking us up alot, or schedule_timeout is broken. | ||
1318 | or something. who cares. - zach */ | ||
1319 | if (!schedule_timeout(tmo ? tmo : 1) && tmo) | ||
1320 | DPRINTK(DPCRAP,"dma timed out?? %ld\n",jiffies); | ||
1321 | } | ||
1322 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
1323 | set_current_state(TASK_RUNNING); | ||
1324 | if (signal_pending(current)) | ||
1325 | return -ERESTARTSYS; | ||
1326 | return 0; | ||
1327 | } | ||
1328 | |||
1329 | static ssize_t m3_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1330 | { | ||
1331 | struct m3_state *s = (struct m3_state *)file->private_data; | ||
1332 | ssize_t ret; | ||
1333 | unsigned long flags; | ||
1334 | unsigned swptr; | ||
1335 | int cnt; | ||
1336 | |||
1337 | VALIDATE_STATE(s); | ||
1338 | if (s->dma_adc.mapped) | ||
1339 | return -ENXIO; | ||
1340 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
1341 | return ret; | ||
1342 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1343 | return -EFAULT; | ||
1344 | ret = 0; | ||
1345 | |||
1346 | spin_lock_irqsave(&s->card->lock, flags); | ||
1347 | |||
1348 | while (count > 0) { | ||
1349 | int timed_out; | ||
1350 | |||
1351 | swptr = s->dma_adc.swptr; | ||
1352 | cnt = s->dma_adc.dmasize-swptr; | ||
1353 | if (s->dma_adc.count < cnt) | ||
1354 | cnt = s->dma_adc.count; | ||
1355 | |||
1356 | if (cnt > count) | ||
1357 | cnt = count; | ||
1358 | |||
1359 | if (cnt <= 0) { | ||
1360 | start_adc(s); | ||
1361 | if (file->f_flags & O_NONBLOCK) | ||
1362 | { | ||
1363 | ret = ret ? ret : -EAGAIN; | ||
1364 | goto out; | ||
1365 | } | ||
1366 | |||
1367 | spin_unlock_irqrestore(&s->card->lock, flags); | ||
1368 | timed_out = interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ) == 0; | ||
1369 | spin_lock_irqsave(&s->card->lock, flags); | ||
1370 | |||
1371 | if(timed_out) { | ||
1372 | printk("read: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n", | ||
1373 | s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, | ||
1374 | s->dma_adc.hwptr, s->dma_adc.swptr); | ||
1375 | stop_adc(s); | ||
1376 | set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift); | ||
1377 | s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0; | ||
1378 | } | ||
1379 | if (signal_pending(current)) | ||
1380 | { | ||
1381 | ret = ret ? ret : -ERESTARTSYS; | ||
1382 | goto out; | ||
1383 | } | ||
1384 | continue; | ||
1385 | } | ||
1386 | |||
1387 | spin_unlock_irqrestore(&s->card->lock, flags); | ||
1388 | if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { | ||
1389 | ret = ret ? ret : -EFAULT; | ||
1390 | return ret; | ||
1391 | } | ||
1392 | spin_lock_irqsave(&s->card->lock, flags); | ||
1393 | |||
1394 | swptr = (swptr + cnt) % s->dma_adc.dmasize; | ||
1395 | s->dma_adc.swptr = swptr; | ||
1396 | s->dma_adc.count -= cnt; | ||
1397 | count -= cnt; | ||
1398 | buffer += cnt; | ||
1399 | ret += cnt; | ||
1400 | start_adc(s); | ||
1401 | } | ||
1402 | |||
1403 | out: | ||
1404 | spin_unlock_irqrestore(&s->card->lock, flags); | ||
1405 | return ret; | ||
1406 | } | ||
1407 | |||
1408 | static ssize_t m3_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1409 | { | ||
1410 | struct m3_state *s = (struct m3_state *)file->private_data; | ||
1411 | ssize_t ret; | ||
1412 | unsigned long flags; | ||
1413 | unsigned swptr; | ||
1414 | int cnt; | ||
1415 | |||
1416 | VALIDATE_STATE(s); | ||
1417 | if (s->dma_dac.mapped) | ||
1418 | return -ENXIO; | ||
1419 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
1420 | return ret; | ||
1421 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1422 | return -EFAULT; | ||
1423 | ret = 0; | ||
1424 | |||
1425 | spin_lock_irqsave(&s->card->lock, flags); | ||
1426 | |||
1427 | while (count > 0) { | ||
1428 | int timed_out; | ||
1429 | |||
1430 | if (s->dma_dac.count < 0) { | ||
1431 | s->dma_dac.count = 0; | ||
1432 | s->dma_dac.swptr = s->dma_dac.hwptr; | ||
1433 | } | ||
1434 | swptr = s->dma_dac.swptr; | ||
1435 | |||
1436 | cnt = s->dma_dac.dmasize-swptr; | ||
1437 | |||
1438 | if (s->dma_dac.count + cnt > s->dma_dac.dmasize) | ||
1439 | cnt = s->dma_dac.dmasize - s->dma_dac.count; | ||
1440 | |||
1441 | |||
1442 | if (cnt > count) | ||
1443 | cnt = count; | ||
1444 | |||
1445 | if (cnt <= 0) { | ||
1446 | start_dac(s); | ||
1447 | if (file->f_flags & O_NONBLOCK) { | ||
1448 | if(!ret) ret = -EAGAIN; | ||
1449 | goto out; | ||
1450 | } | ||
1451 | spin_unlock_irqrestore(&s->card->lock, flags); | ||
1452 | timed_out = interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ) == 0; | ||
1453 | spin_lock_irqsave(&s->card->lock, flags); | ||
1454 | if(timed_out) { | ||
1455 | DPRINTK(DPCRAP,"write: chip lockup? dmasz %u fragsz %u count %u hwptr %u swptr %u\n", | ||
1456 | s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, | ||
1457 | s->dma_dac.hwptr, s->dma_dac.swptr); | ||
1458 | stop_dac(s); | ||
1459 | set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift); | ||
1460 | s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0; | ||
1461 | } | ||
1462 | if (signal_pending(current)) { | ||
1463 | if (!ret) ret = -ERESTARTSYS; | ||
1464 | goto out; | ||
1465 | } | ||
1466 | continue; | ||
1467 | } | ||
1468 | spin_unlock_irqrestore(&s->card->lock, flags); | ||
1469 | if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { | ||
1470 | if (!ret) ret = -EFAULT; | ||
1471 | return ret; | ||
1472 | } | ||
1473 | spin_lock_irqsave(&s->card->lock, flags); | ||
1474 | |||
1475 | DPRINTK(DPSYS,"wrote %6d bytes at sw: %6d cnt: %6d while hw: %6d\n", | ||
1476 | cnt, swptr, s->dma_dac.count, s->dma_dac.hwptr); | ||
1477 | |||
1478 | swptr = (swptr + cnt) % s->dma_dac.dmasize; | ||
1479 | |||
1480 | s->dma_dac.swptr = swptr; | ||
1481 | s->dma_dac.count += cnt; | ||
1482 | s->dma_dac.endcleared = 0; | ||
1483 | count -= cnt; | ||
1484 | buffer += cnt; | ||
1485 | ret += cnt; | ||
1486 | start_dac(s); | ||
1487 | } | ||
1488 | out: | ||
1489 | spin_unlock_irqrestore(&s->card->lock, flags); | ||
1490 | return ret; | ||
1491 | } | ||
1492 | |||
1493 | static unsigned int m3_poll(struct file *file, struct poll_table_struct *wait) | ||
1494 | { | ||
1495 | struct m3_state *s = (struct m3_state *)file->private_data; | ||
1496 | unsigned long flags; | ||
1497 | unsigned int mask = 0; | ||
1498 | |||
1499 | VALIDATE_STATE(s); | ||
1500 | if (file->f_mode & FMODE_WRITE) | ||
1501 | poll_wait(file, &s->dma_dac.wait, wait); | ||
1502 | if (file->f_mode & FMODE_READ) | ||
1503 | poll_wait(file, &s->dma_adc.wait, wait); | ||
1504 | |||
1505 | spin_lock_irqsave(&s->card->lock, flags); | ||
1506 | m3_update_ptr(s); | ||
1507 | |||
1508 | if (file->f_mode & FMODE_READ) { | ||
1509 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
1510 | mask |= POLLIN | POLLRDNORM; | ||
1511 | } | ||
1512 | if (file->f_mode & FMODE_WRITE) { | ||
1513 | if (s->dma_dac.mapped) { | ||
1514 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) | ||
1515 | mask |= POLLOUT | POLLWRNORM; | ||
1516 | } else { | ||
1517 | if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize) | ||
1518 | mask |= POLLOUT | POLLWRNORM; | ||
1519 | } | ||
1520 | } | ||
1521 | |||
1522 | spin_unlock_irqrestore(&s->card->lock, flags); | ||
1523 | return mask; | ||
1524 | } | ||
1525 | |||
1526 | static int m3_mmap(struct file *file, struct vm_area_struct *vma) | ||
1527 | { | ||
1528 | struct m3_state *s = (struct m3_state *)file->private_data; | ||
1529 | unsigned long max_size, size, start, offset; | ||
1530 | struct dmabuf *db; | ||
1531 | int ret = -EINVAL; | ||
1532 | |||
1533 | VALIDATE_STATE(s); | ||
1534 | if (vma->vm_flags & VM_WRITE) { | ||
1535 | if ((ret = prog_dmabuf(s, 0)) != 0) | ||
1536 | return ret; | ||
1537 | db = &s->dma_dac; | ||
1538 | } else | ||
1539 | if (vma->vm_flags & VM_READ) { | ||
1540 | if ((ret = prog_dmabuf(s, 1)) != 0) | ||
1541 | return ret; | ||
1542 | db = &s->dma_adc; | ||
1543 | } else | ||
1544 | return -EINVAL; | ||
1545 | |||
1546 | max_size = db->dmasize; | ||
1547 | |||
1548 | start = vma->vm_start; | ||
1549 | offset = (vma->vm_pgoff << PAGE_SHIFT); | ||
1550 | size = vma->vm_end - vma->vm_start; | ||
1551 | |||
1552 | if(size > max_size) | ||
1553 | goto out; | ||
1554 | if(offset > max_size - size) | ||
1555 | goto out; | ||
1556 | |||
1557 | /* | ||
1558 | * this will be ->nopage() once I can | ||
1559 | * ask Jeff what the hell I'm doing wrong. | ||
1560 | */ | ||
1561 | ret = -EAGAIN; | ||
1562 | if (remap_pfn_range(vma, vma->vm_start, | ||
1563 | virt_to_phys(db->rawbuf) >> PAGE_SHIFT, | ||
1564 | size, vma->vm_page_prot)) | ||
1565 | goto out; | ||
1566 | |||
1567 | db->mapped = 1; | ||
1568 | ret = 0; | ||
1569 | |||
1570 | out: | ||
1571 | return ret; | ||
1572 | } | ||
1573 | |||
1574 | /* | ||
1575 | * this function is a disaster.. | ||
1576 | */ | ||
1577 | #define get_user_ret(x, ptr, ret) ({ if(get_user(x, ptr)) return ret; }) | ||
1578 | static int m3_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1579 | { | ||
1580 | struct m3_state *s = (struct m3_state *)file->private_data; | ||
1581 | struct m3_card *card=s->card; | ||
1582 | unsigned long flags; | ||
1583 | audio_buf_info abinfo; | ||
1584 | count_info cinfo; | ||
1585 | int val, mapped, ret; | ||
1586 | unsigned char fmtm, fmtd; | ||
1587 | void __user *argp = (void __user *)arg; | ||
1588 | int __user *p = argp; | ||
1589 | |||
1590 | VALIDATE_STATE(s); | ||
1591 | |||
1592 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || | ||
1593 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
1594 | |||
1595 | DPRINTK(DPSYS,"m3_ioctl: cmd %d\n", cmd); | ||
1596 | |||
1597 | switch (cmd) { | ||
1598 | case OSS_GETVERSION: | ||
1599 | return put_user(SOUND_VERSION, p); | ||
1600 | |||
1601 | case SNDCTL_DSP_SYNC: | ||
1602 | if (file->f_mode & FMODE_WRITE) | ||
1603 | return drain_dac(s, file->f_flags & O_NONBLOCK); | ||
1604 | return 0; | ||
1605 | |||
1606 | case SNDCTL_DSP_SETDUPLEX: | ||
1607 | /* XXX fix */ | ||
1608 | return 0; | ||
1609 | |||
1610 | case SNDCTL_DSP_GETCAPS: | ||
1611 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); | ||
1612 | |||
1613 | case SNDCTL_DSP_RESET: | ||
1614 | spin_lock_irqsave(&card->lock, flags); | ||
1615 | if (file->f_mode & FMODE_WRITE) { | ||
1616 | stop_dac(s); | ||
1617 | synchronize_irq(s->card->pcidev->irq); | ||
1618 | s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0; | ||
1619 | } | ||
1620 | if (file->f_mode & FMODE_READ) { | ||
1621 | stop_adc(s); | ||
1622 | synchronize_irq(s->card->pcidev->irq); | ||
1623 | s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
1624 | } | ||
1625 | spin_unlock_irqrestore(&card->lock, flags); | ||
1626 | return 0; | ||
1627 | |||
1628 | case SNDCTL_DSP_SPEED: | ||
1629 | get_user_ret(val, p, -EFAULT); | ||
1630 | spin_lock_irqsave(&card->lock, flags); | ||
1631 | if (val >= 0) { | ||
1632 | if (file->f_mode & FMODE_READ) { | ||
1633 | stop_adc(s); | ||
1634 | s->dma_adc.ready = 0; | ||
1635 | set_adc_rate(s, val); | ||
1636 | } | ||
1637 | if (file->f_mode & FMODE_WRITE) { | ||
1638 | stop_dac(s); | ||
1639 | s->dma_dac.ready = 0; | ||
1640 | set_dac_rate(s, val); | ||
1641 | } | ||
1642 | } | ||
1643 | spin_unlock_irqrestore(&card->lock, flags); | ||
1644 | return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p); | ||
1645 | |||
1646 | case SNDCTL_DSP_STEREO: | ||
1647 | get_user_ret(val, p, -EFAULT); | ||
1648 | spin_lock_irqsave(&card->lock, flags); | ||
1649 | fmtd = 0; | ||
1650 | fmtm = ~0; | ||
1651 | if (file->f_mode & FMODE_READ) { | ||
1652 | stop_adc(s); | ||
1653 | s->dma_adc.ready = 0; | ||
1654 | if (val) | ||
1655 | fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT; | ||
1656 | else | ||
1657 | fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT); | ||
1658 | } | ||
1659 | if (file->f_mode & FMODE_WRITE) { | ||
1660 | stop_dac(s); | ||
1661 | s->dma_dac.ready = 0; | ||
1662 | if (val) | ||
1663 | fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT; | ||
1664 | else | ||
1665 | fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT); | ||
1666 | } | ||
1667 | set_fmt(s, fmtm, fmtd); | ||
1668 | spin_unlock_irqrestore(&card->lock, flags); | ||
1669 | return 0; | ||
1670 | |||
1671 | case SNDCTL_DSP_CHANNELS: | ||
1672 | get_user_ret(val, p, -EFAULT); | ||
1673 | spin_lock_irqsave(&card->lock, flags); | ||
1674 | if (val != 0) { | ||
1675 | fmtd = 0; | ||
1676 | fmtm = ~0; | ||
1677 | if (file->f_mode & FMODE_READ) { | ||
1678 | stop_adc(s); | ||
1679 | s->dma_adc.ready = 0; | ||
1680 | if (val >= 2) | ||
1681 | fmtd |= ESS_FMT_STEREO << ESS_ADC_SHIFT; | ||
1682 | else | ||
1683 | fmtm &= ~(ESS_FMT_STEREO << ESS_ADC_SHIFT); | ||
1684 | } | ||
1685 | if (file->f_mode & FMODE_WRITE) { | ||
1686 | stop_dac(s); | ||
1687 | s->dma_dac.ready = 0; | ||
1688 | if (val >= 2) | ||
1689 | fmtd |= ESS_FMT_STEREO << ESS_DAC_SHIFT; | ||
1690 | else | ||
1691 | fmtm &= ~(ESS_FMT_STEREO << ESS_DAC_SHIFT); | ||
1692 | } | ||
1693 | set_fmt(s, fmtm, fmtd); | ||
1694 | } | ||
1695 | spin_unlock_irqrestore(&card->lock, flags); | ||
1696 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) | ||
1697 | : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p); | ||
1698 | |||
1699 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
1700 | return put_user(AFMT_U8|AFMT_S16_LE, p); | ||
1701 | |||
1702 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
1703 | get_user_ret(val, p, -EFAULT); | ||
1704 | spin_lock_irqsave(&card->lock, flags); | ||
1705 | if (val != AFMT_QUERY) { | ||
1706 | fmtd = 0; | ||
1707 | fmtm = ~0; | ||
1708 | if (file->f_mode & FMODE_READ) { | ||
1709 | stop_adc(s); | ||
1710 | s->dma_adc.ready = 0; | ||
1711 | if (val == AFMT_S16_LE) | ||
1712 | fmtd |= ESS_FMT_16BIT << ESS_ADC_SHIFT; | ||
1713 | else | ||
1714 | fmtm &= ~(ESS_FMT_16BIT << ESS_ADC_SHIFT); | ||
1715 | } | ||
1716 | if (file->f_mode & FMODE_WRITE) { | ||
1717 | stop_dac(s); | ||
1718 | s->dma_dac.ready = 0; | ||
1719 | if (val == AFMT_S16_LE) | ||
1720 | fmtd |= ESS_FMT_16BIT << ESS_DAC_SHIFT; | ||
1721 | else | ||
1722 | fmtm &= ~(ESS_FMT_16BIT << ESS_DAC_SHIFT); | ||
1723 | } | ||
1724 | set_fmt(s, fmtm, fmtd); | ||
1725 | } | ||
1726 | spin_unlock_irqrestore(&card->lock, flags); | ||
1727 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? | ||
1728 | (ESS_FMT_16BIT << ESS_ADC_SHIFT) | ||
1729 | : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? | ||
1730 | AFMT_S16_LE : | ||
1731 | AFMT_U8, | ||
1732 | p); | ||
1733 | |||
1734 | case SNDCTL_DSP_POST: | ||
1735 | return 0; | ||
1736 | |||
1737 | case SNDCTL_DSP_GETTRIGGER: | ||
1738 | val = 0; | ||
1739 | if ((file->f_mode & FMODE_READ) && (s->enable & ADC_RUNNING)) | ||
1740 | val |= PCM_ENABLE_INPUT; | ||
1741 | if ((file->f_mode & FMODE_WRITE) && (s->enable & DAC_RUNNING)) | ||
1742 | val |= PCM_ENABLE_OUTPUT; | ||
1743 | return put_user(val, p); | ||
1744 | |||
1745 | case SNDCTL_DSP_SETTRIGGER: | ||
1746 | get_user_ret(val, p, -EFAULT); | ||
1747 | if (file->f_mode & FMODE_READ) { | ||
1748 | if (val & PCM_ENABLE_INPUT) { | ||
1749 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
1750 | return ret; | ||
1751 | start_adc(s); | ||
1752 | } else | ||
1753 | stop_adc(s); | ||
1754 | } | ||
1755 | if (file->f_mode & FMODE_WRITE) { | ||
1756 | if (val & PCM_ENABLE_OUTPUT) { | ||
1757 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
1758 | return ret; | ||
1759 | start_dac(s); | ||
1760 | } else | ||
1761 | stop_dac(s); | ||
1762 | } | ||
1763 | return 0; | ||
1764 | |||
1765 | case SNDCTL_DSP_GETOSPACE: | ||
1766 | if (!(file->f_mode & FMODE_WRITE)) | ||
1767 | return -EINVAL; | ||
1768 | if (!(s->enable & DAC_RUNNING) && (val = prog_dmabuf(s, 0)) != 0) | ||
1769 | return val; | ||
1770 | spin_lock_irqsave(&card->lock, flags); | ||
1771 | m3_update_ptr(s); | ||
1772 | abinfo.fragsize = s->dma_dac.fragsize; | ||
1773 | abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count; | ||
1774 | abinfo.fragstotal = s->dma_dac.numfrag; | ||
1775 | abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; | ||
1776 | spin_unlock_irqrestore(&card->lock, flags); | ||
1777 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1778 | |||
1779 | case SNDCTL_DSP_GETISPACE: | ||
1780 | if (!(file->f_mode & FMODE_READ)) | ||
1781 | return -EINVAL; | ||
1782 | if (!(s->enable & ADC_RUNNING) && (val = prog_dmabuf(s, 1)) != 0) | ||
1783 | return val; | ||
1784 | spin_lock_irqsave(&card->lock, flags); | ||
1785 | m3_update_ptr(s); | ||
1786 | abinfo.fragsize = s->dma_adc.fragsize; | ||
1787 | abinfo.bytes = s->dma_adc.count; | ||
1788 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
1789 | abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; | ||
1790 | spin_unlock_irqrestore(&card->lock, flags); | ||
1791 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1792 | |||
1793 | case SNDCTL_DSP_NONBLOCK: | ||
1794 | file->f_flags |= O_NONBLOCK; | ||
1795 | return 0; | ||
1796 | |||
1797 | case SNDCTL_DSP_GETODELAY: | ||
1798 | if (!(file->f_mode & FMODE_WRITE)) | ||
1799 | return -EINVAL; | ||
1800 | spin_lock_irqsave(&card->lock, flags); | ||
1801 | m3_update_ptr(s); | ||
1802 | val = s->dma_dac.count; | ||
1803 | spin_unlock_irqrestore(&card->lock, flags); | ||
1804 | return put_user(val, p); | ||
1805 | |||
1806 | case SNDCTL_DSP_GETIPTR: | ||
1807 | if (!(file->f_mode & FMODE_READ)) | ||
1808 | return -EINVAL; | ||
1809 | spin_lock_irqsave(&card->lock, flags); | ||
1810 | m3_update_ptr(s); | ||
1811 | cinfo.bytes = s->dma_adc.total_bytes; | ||
1812 | cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift; | ||
1813 | cinfo.ptr = s->dma_adc.hwptr; | ||
1814 | if (s->dma_adc.mapped) | ||
1815 | s->dma_adc.count &= s->dma_adc.fragsize-1; | ||
1816 | spin_unlock_irqrestore(&card->lock, flags); | ||
1817 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1818 | return -EFAULT; | ||
1819 | return 0; | ||
1820 | |||
1821 | case SNDCTL_DSP_GETOPTR: | ||
1822 | if (!(file->f_mode & FMODE_WRITE)) | ||
1823 | return -EINVAL; | ||
1824 | spin_lock_irqsave(&card->lock, flags); | ||
1825 | m3_update_ptr(s); | ||
1826 | cinfo.bytes = s->dma_dac.total_bytes; | ||
1827 | cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift; | ||
1828 | cinfo.ptr = s->dma_dac.hwptr; | ||
1829 | if (s->dma_dac.mapped) | ||
1830 | s->dma_dac.count &= s->dma_dac.fragsize-1; | ||
1831 | spin_unlock_irqrestore(&card->lock, flags); | ||
1832 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1833 | return -EFAULT; | ||
1834 | return 0; | ||
1835 | |||
1836 | case SNDCTL_DSP_GETBLKSIZE: | ||
1837 | if (file->f_mode & FMODE_WRITE) { | ||
1838 | if ((val = prog_dmabuf(s, 0))) | ||
1839 | return val; | ||
1840 | return put_user(s->dma_dac.fragsize, p); | ||
1841 | } | ||
1842 | if ((val = prog_dmabuf(s, 1))) | ||
1843 | return val; | ||
1844 | return put_user(s->dma_adc.fragsize, p); | ||
1845 | |||
1846 | case SNDCTL_DSP_SETFRAGMENT: | ||
1847 | get_user_ret(val, p, -EFAULT); | ||
1848 | spin_lock_irqsave(&card->lock, flags); | ||
1849 | if (file->f_mode & FMODE_READ) { | ||
1850 | s->dma_adc.ossfragshift = val & 0xffff; | ||
1851 | s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; | ||
1852 | if (s->dma_adc.ossfragshift < 4) | ||
1853 | s->dma_adc.ossfragshift = 4; | ||
1854 | if (s->dma_adc.ossfragshift > 15) | ||
1855 | s->dma_adc.ossfragshift = 15; | ||
1856 | if (s->dma_adc.ossmaxfrags < 4) | ||
1857 | s->dma_adc.ossmaxfrags = 4; | ||
1858 | } | ||
1859 | if (file->f_mode & FMODE_WRITE) { | ||
1860 | s->dma_dac.ossfragshift = val & 0xffff; | ||
1861 | s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; | ||
1862 | if (s->dma_dac.ossfragshift < 4) | ||
1863 | s->dma_dac.ossfragshift = 4; | ||
1864 | if (s->dma_dac.ossfragshift > 15) | ||
1865 | s->dma_dac.ossfragshift = 15; | ||
1866 | if (s->dma_dac.ossmaxfrags < 4) | ||
1867 | s->dma_dac.ossmaxfrags = 4; | ||
1868 | } | ||
1869 | spin_unlock_irqrestore(&card->lock, flags); | ||
1870 | return 0; | ||
1871 | |||
1872 | case SNDCTL_DSP_SUBDIVIDE: | ||
1873 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
1874 | (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) | ||
1875 | return -EINVAL; | ||
1876 | get_user_ret(val, p, -EFAULT); | ||
1877 | if (val != 1 && val != 2 && val != 4) | ||
1878 | return -EINVAL; | ||
1879 | if (file->f_mode & FMODE_READ) | ||
1880 | s->dma_adc.subdivision = val; | ||
1881 | if (file->f_mode & FMODE_WRITE) | ||
1882 | s->dma_dac.subdivision = val; | ||
1883 | return 0; | ||
1884 | |||
1885 | case SOUND_PCM_READ_RATE: | ||
1886 | return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p); | ||
1887 | |||
1888 | case SOUND_PCM_READ_CHANNELS: | ||
1889 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_STEREO << ESS_ADC_SHIFT) | ||
1890 | : (ESS_FMT_STEREO << ESS_DAC_SHIFT))) ? 2 : 1, p); | ||
1891 | |||
1892 | case SOUND_PCM_READ_BITS: | ||
1893 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (ESS_FMT_16BIT << ESS_ADC_SHIFT) | ||
1894 | : (ESS_FMT_16BIT << ESS_DAC_SHIFT))) ? 16 : 8, p); | ||
1895 | |||
1896 | case SOUND_PCM_WRITE_FILTER: | ||
1897 | case SNDCTL_DSP_SETSYNCRO: | ||
1898 | case SOUND_PCM_READ_FILTER: | ||
1899 | return -EINVAL; | ||
1900 | |||
1901 | } | ||
1902 | return -EINVAL; | ||
1903 | } | ||
1904 | |||
1905 | static int | ||
1906 | allocate_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db) | ||
1907 | { | ||
1908 | int order; | ||
1909 | |||
1910 | DPRINTK(DPSTR,"allocating for dmabuf %p\n", db); | ||
1911 | |||
1912 | /* | ||
1913 | * alloc as big a chunk as we can, start with | ||
1914 | * 64k 'cause we're insane. based on order cause | ||
1915 | * the amazingly complicated prog_dmabuf wants it. | ||
1916 | * | ||
1917 | * pci_alloc_sonsistent guarantees that it won't cross a natural | ||
1918 | * boundary; the m3 hardware can't have dma cross a 64k bus | ||
1919 | * address boundary. | ||
1920 | */ | ||
1921 | for (order = 16-PAGE_SHIFT; order >= 1; order--) { | ||
1922 | db->rawbuf = pci_alloc_consistent(pci_dev, PAGE_SIZE << order, | ||
1923 | &(db->handle)); | ||
1924 | if(db->rawbuf) | ||
1925 | break; | ||
1926 | } | ||
1927 | |||
1928 | if (!db->rawbuf) | ||
1929 | return 1; | ||
1930 | |||
1931 | DPRINTK(DPSTR,"allocated %ld (%d) bytes at %p\n", | ||
1932 | PAGE_SIZE<<order, order, db->rawbuf); | ||
1933 | |||
1934 | { | ||
1935 | struct page *page, *pend; | ||
1936 | |||
1937 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << order) - 1); | ||
1938 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
1939 | SetPageReserved(page); | ||
1940 | } | ||
1941 | |||
1942 | |||
1943 | db->buforder = order; | ||
1944 | db->ready = 0; | ||
1945 | db->mapped = 0; | ||
1946 | |||
1947 | return 0; | ||
1948 | } | ||
1949 | |||
1950 | static void | ||
1951 | nuke_lists(struct m3_card *card, struct dmabuf *db) | ||
1952 | { | ||
1953 | m3_remove_list(card, &(card->dma_list), db->dma_index); | ||
1954 | m3_remove_list(card, &(card->msrc_list), db->msrc_index); | ||
1955 | db->in_lists = 0; | ||
1956 | } | ||
1957 | |||
1958 | static void | ||
1959 | free_dmabuf(struct pci_dev *pci_dev, struct dmabuf *db) | ||
1960 | { | ||
1961 | if(db->rawbuf == NULL) | ||
1962 | return; | ||
1963 | |||
1964 | DPRINTK(DPSTR,"freeing %p from dmabuf %p\n",db->rawbuf, db); | ||
1965 | |||
1966 | { | ||
1967 | struct page *page, *pend; | ||
1968 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
1969 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
1970 | ClearPageReserved(page); | ||
1971 | } | ||
1972 | |||
1973 | |||
1974 | pci_free_consistent(pci_dev, PAGE_SIZE << db->buforder, | ||
1975 | db->rawbuf, db->handle); | ||
1976 | |||
1977 | db->rawbuf = NULL; | ||
1978 | db->buforder = 0; | ||
1979 | db->mapped = 0; | ||
1980 | db->ready = 0; | ||
1981 | } | ||
1982 | |||
1983 | static int m3_open(struct inode *inode, struct file *file) | ||
1984 | { | ||
1985 | unsigned int minor = iminor(inode); | ||
1986 | struct m3_card *c; | ||
1987 | struct m3_state *s = NULL; | ||
1988 | int i; | ||
1989 | unsigned char fmtm = ~0, fmts = 0; | ||
1990 | unsigned long flags; | ||
1991 | |||
1992 | /* | ||
1993 | * Scan the cards and find the channel. We only | ||
1994 | * do this at open time so it is ok | ||
1995 | */ | ||
1996 | for(c = devs ; c != NULL ; c = c->next) { | ||
1997 | |||
1998 | for(i=0;i<NR_DSPS;i++) { | ||
1999 | |||
2000 | if(c->channels[i].dev_audio < 0) | ||
2001 | continue; | ||
2002 | if((c->channels[i].dev_audio ^ minor) & ~0xf) | ||
2003 | continue; | ||
2004 | |||
2005 | s = &c->channels[i]; | ||
2006 | break; | ||
2007 | } | ||
2008 | } | ||
2009 | |||
2010 | if (!s) | ||
2011 | return -ENODEV; | ||
2012 | |||
2013 | VALIDATE_STATE(s); | ||
2014 | |||
2015 | file->private_data = s; | ||
2016 | |||
2017 | /* wait for device to become free */ | ||
2018 | mutex_lock(&s->open_mutex); | ||
2019 | while (s->open_mode & file->f_mode) { | ||
2020 | if (file->f_flags & O_NONBLOCK) { | ||
2021 | mutex_unlock(&s->open_mutex); | ||
2022 | return -EWOULDBLOCK; | ||
2023 | } | ||
2024 | mutex_unlock(&s->open_mutex); | ||
2025 | interruptible_sleep_on(&s->open_wait); | ||
2026 | if (signal_pending(current)) | ||
2027 | return -ERESTARTSYS; | ||
2028 | mutex_lock(&s->open_mutex); | ||
2029 | } | ||
2030 | |||
2031 | spin_lock_irqsave(&c->lock, flags); | ||
2032 | |||
2033 | if (file->f_mode & FMODE_READ) { | ||
2034 | fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_ADC_SHIFT); | ||
2035 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
2036 | fmts |= ESS_FMT_16BIT << ESS_ADC_SHIFT; | ||
2037 | |||
2038 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; | ||
2039 | set_adc_rate(s, 8000); | ||
2040 | } | ||
2041 | if (file->f_mode & FMODE_WRITE) { | ||
2042 | fmtm &= ~((ESS_FMT_STEREO | ESS_FMT_16BIT) << ESS_DAC_SHIFT); | ||
2043 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
2044 | fmts |= ESS_FMT_16BIT << ESS_DAC_SHIFT; | ||
2045 | |||
2046 | s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; | ||
2047 | set_dac_rate(s, 8000); | ||
2048 | } | ||
2049 | set_fmt(s, fmtm, fmts); | ||
2050 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
2051 | |||
2052 | mutex_unlock(&s->open_mutex); | ||
2053 | spin_unlock_irqrestore(&c->lock, flags); | ||
2054 | return nonseekable_open(inode, file); | ||
2055 | } | ||
2056 | |||
2057 | static int m3_release(struct inode *inode, struct file *file) | ||
2058 | { | ||
2059 | struct m3_state *s = (struct m3_state *)file->private_data; | ||
2060 | struct m3_card *card=s->card; | ||
2061 | unsigned long flags; | ||
2062 | |||
2063 | VALIDATE_STATE(s); | ||
2064 | if (file->f_mode & FMODE_WRITE) | ||
2065 | drain_dac(s, file->f_flags & O_NONBLOCK); | ||
2066 | |||
2067 | mutex_lock(&s->open_mutex); | ||
2068 | spin_lock_irqsave(&card->lock, flags); | ||
2069 | |||
2070 | if (file->f_mode & FMODE_WRITE) { | ||
2071 | stop_dac(s); | ||
2072 | if(s->dma_dac.in_lists) { | ||
2073 | m3_remove_list(s->card, &(s->card->mixer_list), s->dma_dac.mixer_index); | ||
2074 | nuke_lists(s->card, &(s->dma_dac)); | ||
2075 | } | ||
2076 | } | ||
2077 | if (file->f_mode & FMODE_READ) { | ||
2078 | stop_adc(s); | ||
2079 | if(s->dma_adc.in_lists) { | ||
2080 | m3_remove_list(s->card, &(s->card->adc1_list), s->dma_adc.adc1_index); | ||
2081 | nuke_lists(s->card, &(s->dma_adc)); | ||
2082 | } | ||
2083 | } | ||
2084 | |||
2085 | s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); | ||
2086 | |||
2087 | spin_unlock_irqrestore(&card->lock, flags); | ||
2088 | mutex_unlock(&s->open_mutex); | ||
2089 | wake_up(&s->open_wait); | ||
2090 | |||
2091 | return 0; | ||
2092 | } | ||
2093 | |||
2094 | /* | ||
2095 | * Wait for the ac97 serial bus to be free. | ||
2096 | * return nonzero if the bus is still busy. | ||
2097 | */ | ||
2098 | static int m3_ac97_wait(struct m3_card *card) | ||
2099 | { | ||
2100 | int i = 10000; | ||
2101 | |||
2102 | while( (m3_inb(card, 0x30) & 1) && i--) ; | ||
2103 | |||
2104 | return i == 0; | ||
2105 | } | ||
2106 | |||
2107 | static u16 m3_ac97_read(struct ac97_codec *codec, u8 reg) | ||
2108 | { | ||
2109 | u16 ret = 0; | ||
2110 | struct m3_card *card = codec->private_data; | ||
2111 | |||
2112 | spin_lock(&card->ac97_lock); | ||
2113 | |||
2114 | if(m3_ac97_wait(card)) { | ||
2115 | printk(KERN_ERR PFX "serial bus busy reading reg 0x%x\n",reg); | ||
2116 | goto out; | ||
2117 | } | ||
2118 | |||
2119 | m3_outb(card, 0x80 | (reg & 0x7f), 0x30); | ||
2120 | |||
2121 | if(m3_ac97_wait(card)) { | ||
2122 | printk(KERN_ERR PFX "serial bus busy finishing read reg 0x%x\n",reg); | ||
2123 | goto out; | ||
2124 | } | ||
2125 | |||
2126 | ret = m3_inw(card, 0x32); | ||
2127 | DPRINTK(DPCRAP,"reading 0x%04x from 0x%02x\n",ret, reg); | ||
2128 | |||
2129 | out: | ||
2130 | spin_unlock(&card->ac97_lock); | ||
2131 | return ret; | ||
2132 | } | ||
2133 | |||
2134 | static void m3_ac97_write(struct ac97_codec *codec, u8 reg, u16 val) | ||
2135 | { | ||
2136 | struct m3_card *card = codec->private_data; | ||
2137 | |||
2138 | spin_lock(&card->ac97_lock); | ||
2139 | |||
2140 | if(m3_ac97_wait(card)) { | ||
2141 | printk(KERN_ERR PFX "serial bus busy writing 0x%x to 0x%x\n",val, reg); | ||
2142 | goto out; | ||
2143 | } | ||
2144 | DPRINTK(DPCRAP,"writing 0x%04x to 0x%02x\n", val, reg); | ||
2145 | |||
2146 | m3_outw(card, val, 0x32); | ||
2147 | m3_outb(card, reg & 0x7f, 0x30); | ||
2148 | out: | ||
2149 | spin_unlock(&card->ac97_lock); | ||
2150 | } | ||
2151 | /* OSS /dev/mixer file operation methods */ | ||
2152 | static int m3_open_mixdev(struct inode *inode, struct file *file) | ||
2153 | { | ||
2154 | unsigned int minor = iminor(inode); | ||
2155 | struct m3_card *card = devs; | ||
2156 | |||
2157 | for (card = devs; card != NULL; card = card->next) { | ||
2158 | if((card->ac97 != NULL) && (card->ac97->dev_mixer == minor)) | ||
2159 | break; | ||
2160 | } | ||
2161 | |||
2162 | if (!card) { | ||
2163 | return -ENODEV; | ||
2164 | } | ||
2165 | |||
2166 | file->private_data = card->ac97; | ||
2167 | |||
2168 | return nonseekable_open(inode, file); | ||
2169 | } | ||
2170 | |||
2171 | static int m3_release_mixdev(struct inode *inode, struct file *file) | ||
2172 | { | ||
2173 | return 0; | ||
2174 | } | ||
2175 | |||
2176 | static int m3_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, | ||
2177 | unsigned long arg) | ||
2178 | { | ||
2179 | struct ac97_codec *codec = (struct ac97_codec *)file->private_data; | ||
2180 | |||
2181 | return codec->mixer_ioctl(codec, cmd, arg); | ||
2182 | } | ||
2183 | |||
2184 | static struct file_operations m3_mixer_fops = { | ||
2185 | .owner = THIS_MODULE, | ||
2186 | .llseek = no_llseek, | ||
2187 | .ioctl = m3_ioctl_mixdev, | ||
2188 | .open = m3_open_mixdev, | ||
2189 | .release = m3_release_mixdev, | ||
2190 | }; | ||
2191 | |||
2192 | static void remote_codec_config(int io, int isremote) | ||
2193 | { | ||
2194 | isremote = isremote ? 1 : 0; | ||
2195 | |||
2196 | outw( (inw(io + RING_BUS_CTRL_B) & ~SECOND_CODEC_ID_MASK) | isremote, | ||
2197 | io + RING_BUS_CTRL_B); | ||
2198 | outw( (inw(io + SDO_OUT_DEST_CTRL) & ~COMMAND_ADDR_OUT) | isremote, | ||
2199 | io + SDO_OUT_DEST_CTRL); | ||
2200 | outw( (inw(io + SDO_IN_DEST_CTRL) & ~STATUS_ADDR_IN) | isremote, | ||
2201 | io + SDO_IN_DEST_CTRL); | ||
2202 | } | ||
2203 | |||
2204 | /* | ||
2205 | * hack, returns non zero on err | ||
2206 | */ | ||
2207 | static int try_read_vendor(struct m3_card *card) | ||
2208 | { | ||
2209 | u16 ret; | ||
2210 | |||
2211 | if(m3_ac97_wait(card)) | ||
2212 | return 1; | ||
2213 | |||
2214 | m3_outb(card, 0x80 | (AC97_VENDOR_ID1 & 0x7f), 0x30); | ||
2215 | |||
2216 | if(m3_ac97_wait(card)) | ||
2217 | return 1; | ||
2218 | |||
2219 | ret = m3_inw(card, 0x32); | ||
2220 | |||
2221 | return (ret == 0) || (ret == 0xffff); | ||
2222 | } | ||
2223 | |||
2224 | static void m3_codec_reset(struct m3_card *card, int busywait) | ||
2225 | { | ||
2226 | u16 dir; | ||
2227 | int delay1 = 0, delay2 = 0, i; | ||
2228 | int io = card->iobase; | ||
2229 | |||
2230 | switch (card->card_type) { | ||
2231 | /* | ||
2232 | * the onboard codec on the allegro seems | ||
2233 | * to want to wait a very long time before | ||
2234 | * coming back to life | ||
2235 | */ | ||
2236 | case ESS_ALLEGRO: | ||
2237 | delay1 = 50; | ||
2238 | delay2 = 800; | ||
2239 | break; | ||
2240 | case ESS_MAESTRO3: | ||
2241 | case ESS_MAESTRO3HW: | ||
2242 | delay1 = 20; | ||
2243 | delay2 = 500; | ||
2244 | break; | ||
2245 | } | ||
2246 | |||
2247 | for(i = 0; i < 5; i ++) { | ||
2248 | dir = inw(io + GPIO_DIRECTION); | ||
2249 | dir |= 0x10; /* assuming pci bus master? */ | ||
2250 | |||
2251 | remote_codec_config(io, 0); | ||
2252 | |||
2253 | outw(IO_SRAM_ENABLE, io + RING_BUS_CTRL_A); | ||
2254 | udelay(20); | ||
2255 | |||
2256 | outw(dir & ~GPO_PRIMARY_AC97 , io + GPIO_DIRECTION); | ||
2257 | outw(~GPO_PRIMARY_AC97 , io + GPIO_MASK); | ||
2258 | outw(0, io + GPIO_DATA); | ||
2259 | outw(dir | GPO_PRIMARY_AC97, io + GPIO_DIRECTION); | ||
2260 | |||
2261 | if(busywait) { | ||
2262 | mdelay(delay1); | ||
2263 | } else { | ||
2264 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2265 | schedule_timeout((delay1 * HZ) / 1000); | ||
2266 | } | ||
2267 | |||
2268 | outw(GPO_PRIMARY_AC97, io + GPIO_DATA); | ||
2269 | udelay(5); | ||
2270 | /* ok, bring back the ac-link */ | ||
2271 | outw(IO_SRAM_ENABLE | SERIAL_AC_LINK_ENABLE, io + RING_BUS_CTRL_A); | ||
2272 | outw(~0, io + GPIO_MASK); | ||
2273 | |||
2274 | if(busywait) { | ||
2275 | mdelay(delay2); | ||
2276 | } else { | ||
2277 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2278 | schedule_timeout((delay2 * HZ) / 1000); | ||
2279 | } | ||
2280 | if(! try_read_vendor(card)) | ||
2281 | break; | ||
2282 | |||
2283 | delay1 += 10; | ||
2284 | delay2 += 100; | ||
2285 | |||
2286 | DPRINTK(DPMOD, "retrying codec reset with delays of %d and %d ms\n", | ||
2287 | delay1, delay2); | ||
2288 | } | ||
2289 | |||
2290 | #if 0 | ||
2291 | /* more gung-ho reset that doesn't | ||
2292 | * seem to work anywhere :) | ||
2293 | */ | ||
2294 | tmp = inw(io + RING_BUS_CTRL_A); | ||
2295 | outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A); | ||
2296 | mdelay(20); | ||
2297 | outw(tmp, io + RING_BUS_CTRL_A); | ||
2298 | mdelay(50); | ||
2299 | #endif | ||
2300 | } | ||
2301 | |||
2302 | static int __devinit m3_codec_install(struct m3_card *card) | ||
2303 | { | ||
2304 | struct ac97_codec *codec; | ||
2305 | |||
2306 | if ((codec = ac97_alloc_codec()) == NULL) | ||
2307 | return -ENOMEM; | ||
2308 | |||
2309 | codec->private_data = card; | ||
2310 | codec->codec_read = m3_ac97_read; | ||
2311 | codec->codec_write = m3_ac97_write; | ||
2312 | /* someday we should support secondary codecs.. */ | ||
2313 | codec->id = 0; | ||
2314 | |||
2315 | if (ac97_probe_codec(codec) == 0) { | ||
2316 | printk(KERN_ERR PFX "codec probe failed\n"); | ||
2317 | ac97_release_codec(codec); | ||
2318 | return -1; | ||
2319 | } | ||
2320 | |||
2321 | if ((codec->dev_mixer = register_sound_mixer(&m3_mixer_fops, -1)) < 0) { | ||
2322 | printk(KERN_ERR PFX "couldn't register mixer!\n"); | ||
2323 | ac97_release_codec(codec); | ||
2324 | return -1; | ||
2325 | } | ||
2326 | |||
2327 | card->ac97 = codec; | ||
2328 | |||
2329 | return 0; | ||
2330 | } | ||
2331 | |||
2332 | |||
2333 | #define MINISRC_LPF_LEN 10 | ||
2334 | static u16 minisrc_lpf[MINISRC_LPF_LEN] = { | ||
2335 | 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C, | ||
2336 | 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F | ||
2337 | }; | ||
2338 | static void m3_assp_init(struct m3_card *card) | ||
2339 | { | ||
2340 | int i; | ||
2341 | |||
2342 | /* zero kernel data */ | ||
2343 | for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++) | ||
2344 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
2345 | KDATA_BASE_ADDR + i, 0); | ||
2346 | |||
2347 | /* zero mixer data? */ | ||
2348 | for(i = 0 ; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++) | ||
2349 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
2350 | KDATA_BASE_ADDR2 + i, 0); | ||
2351 | |||
2352 | /* init dma pointer */ | ||
2353 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
2354 | KDATA_CURRENT_DMA, | ||
2355 | KDATA_DMA_XFER0); | ||
2356 | |||
2357 | /* write kernel into code memory.. */ | ||
2358 | for(i = 0 ; i < sizeof(assp_kernel_image) / 2; i++) { | ||
2359 | m3_assp_write(card, MEMTYPE_INTERNAL_CODE, | ||
2360 | REV_B_CODE_MEMORY_BEGIN + i, | ||
2361 | assp_kernel_image[i]); | ||
2362 | } | ||
2363 | |||
2364 | /* | ||
2365 | * We only have this one client and we know that 0x400 | ||
2366 | * is free in our kernel's mem map, so lets just | ||
2367 | * drop it there. It seems that the minisrc doesn't | ||
2368 | * need vectors, so we won't bother with them.. | ||
2369 | */ | ||
2370 | for(i = 0 ; i < sizeof(assp_minisrc_image) / 2; i++) { | ||
2371 | m3_assp_write(card, MEMTYPE_INTERNAL_CODE, | ||
2372 | 0x400 + i, | ||
2373 | assp_minisrc_image[i]); | ||
2374 | } | ||
2375 | |||
2376 | /* | ||
2377 | * write the coefficients for the low pass filter? | ||
2378 | */ | ||
2379 | for(i = 0; i < MINISRC_LPF_LEN ; i++) { | ||
2380 | m3_assp_write(card, MEMTYPE_INTERNAL_CODE, | ||
2381 | 0x400 + MINISRC_COEF_LOC + i, | ||
2382 | minisrc_lpf[i]); | ||
2383 | } | ||
2384 | |||
2385 | m3_assp_write(card, MEMTYPE_INTERNAL_CODE, | ||
2386 | 0x400 + MINISRC_COEF_LOC + MINISRC_LPF_LEN, | ||
2387 | 0x8000); | ||
2388 | |||
2389 | /* | ||
2390 | * the minisrc is the only thing on | ||
2391 | * our task list.. | ||
2392 | */ | ||
2393 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
2394 | KDATA_TASK0, | ||
2395 | 0x400); | ||
2396 | |||
2397 | /* | ||
2398 | * init the mixer number.. | ||
2399 | */ | ||
2400 | |||
2401 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
2402 | KDATA_MIXER_TASK_NUMBER,0); | ||
2403 | |||
2404 | /* | ||
2405 | * EXTREME KERNEL MASTER VOLUME | ||
2406 | */ | ||
2407 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
2408 | KDATA_DAC_LEFT_VOLUME, ARB_VOLUME); | ||
2409 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
2410 | KDATA_DAC_RIGHT_VOLUME, ARB_VOLUME); | ||
2411 | |||
2412 | card->mixer_list.mem_addr = KDATA_MIXER_XFER0; | ||
2413 | card->mixer_list.max = MAX_VIRTUAL_MIXER_CHANNELS; | ||
2414 | card->adc1_list.mem_addr = KDATA_ADC1_XFER0; | ||
2415 | card->adc1_list.max = MAX_VIRTUAL_ADC1_CHANNELS; | ||
2416 | card->dma_list.mem_addr = KDATA_DMA_XFER0; | ||
2417 | card->dma_list.max = MAX_VIRTUAL_DMA_CHANNELS; | ||
2418 | card->msrc_list.mem_addr = KDATA_INSTANCE0_MINISRC; | ||
2419 | card->msrc_list.max = MAX_INSTANCE_MINISRC; | ||
2420 | } | ||
2421 | |||
2422 | static int setup_msrc(struct m3_card *card, | ||
2423 | struct assp_instance *inst, int index) | ||
2424 | { | ||
2425 | int data_bytes = 2 * ( MINISRC_TMP_BUFFER_SIZE / 2 + | ||
2426 | MINISRC_IN_BUFFER_SIZE / 2 + | ||
2427 | 1 + MINISRC_OUT_BUFFER_SIZE / 2 + 1 ); | ||
2428 | int address, i; | ||
2429 | |||
2430 | /* | ||
2431 | * the revb memory map has 0x1100 through 0x1c00 | ||
2432 | * free. | ||
2433 | */ | ||
2434 | |||
2435 | /* | ||
2436 | * align instance address to 256 bytes so that it's | ||
2437 | * shifted list address is aligned. | ||
2438 | * list address = (mem address >> 1) >> 7; | ||
2439 | */ | ||
2440 | data_bytes = (data_bytes + 255) & ~255; | ||
2441 | address = 0x1100 + ((data_bytes/2) * index); | ||
2442 | |||
2443 | if((address + (data_bytes/2)) >= 0x1c00) { | ||
2444 | printk(KERN_ERR PFX "no memory for %d bytes at ind %d (addr 0x%x)\n", | ||
2445 | data_bytes, index, address); | ||
2446 | return -1; | ||
2447 | } | ||
2448 | |||
2449 | for(i = 0; i < data_bytes/2 ; i++) | ||
2450 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
2451 | address + i, 0); | ||
2452 | |||
2453 | inst->code = 0x400; | ||
2454 | inst->data = address; | ||
2455 | |||
2456 | return 0; | ||
2457 | } | ||
2458 | |||
2459 | static int m3_assp_client_init(struct m3_state *s) | ||
2460 | { | ||
2461 | setup_msrc(s->card, &(s->dac_inst), s->index * 2); | ||
2462 | setup_msrc(s->card, &(s->adc_inst), (s->index * 2) + 1); | ||
2463 | |||
2464 | return 0; | ||
2465 | } | ||
2466 | |||
2467 | static void m3_amp_enable(struct m3_card *card, int enable) | ||
2468 | { | ||
2469 | /* | ||
2470 | * this works for the reference board, have to find | ||
2471 | * out about others | ||
2472 | * | ||
2473 | * this needs more magic for 4 speaker, but.. | ||
2474 | */ | ||
2475 | int io = card->iobase; | ||
2476 | u16 gpo, polarity_port, polarity; | ||
2477 | |||
2478 | if(!external_amp) | ||
2479 | return; | ||
2480 | |||
2481 | if (gpio_pin >= 0 && gpio_pin <= 15) { | ||
2482 | polarity_port = 0x1000 + (0x100 * gpio_pin); | ||
2483 | } else { | ||
2484 | switch (card->card_type) { | ||
2485 | case ESS_ALLEGRO: | ||
2486 | polarity_port = 0x1800; | ||
2487 | break; | ||
2488 | default: | ||
2489 | polarity_port = 0x1100; | ||
2490 | /* Panasonic toughbook CF72 has to be different... */ | ||
2491 | if(card->pcidev->subsystem_vendor == 0x10F7 && card->pcidev->subsystem_device == 0x833D) | ||
2492 | polarity_port = 0x1D00; | ||
2493 | break; | ||
2494 | } | ||
2495 | } | ||
2496 | |||
2497 | gpo = (polarity_port >> 8) & 0x0F; | ||
2498 | polarity = polarity_port >> 12; | ||
2499 | if ( enable ) | ||
2500 | polarity = !polarity; | ||
2501 | polarity = polarity << gpo; | ||
2502 | gpo = 1 << gpo; | ||
2503 | |||
2504 | outw(~gpo , io + GPIO_MASK); | ||
2505 | |||
2506 | outw( inw(io + GPIO_DIRECTION) | gpo , | ||
2507 | io + GPIO_DIRECTION); | ||
2508 | |||
2509 | outw( (GPO_SECONDARY_AC97 | GPO_PRIMARY_AC97 | polarity) , | ||
2510 | io + GPIO_DATA); | ||
2511 | |||
2512 | outw(0xffff , io + GPIO_MASK); | ||
2513 | } | ||
2514 | |||
2515 | static int | ||
2516 | maestro_config(struct m3_card *card) | ||
2517 | { | ||
2518 | struct pci_dev *pcidev = card->pcidev; | ||
2519 | u32 n; | ||
2520 | u8 t; /* makes as much sense as 'n', no? */ | ||
2521 | |||
2522 | pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n); | ||
2523 | n &= REDUCED_DEBOUNCE; | ||
2524 | n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING; | ||
2525 | pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n); | ||
2526 | |||
2527 | outb(RESET_ASSP, card->iobase + ASSP_CONTROL_B); | ||
2528 | pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n); | ||
2529 | n &= ~INT_CLK_SELECT; | ||
2530 | if(card->card_type >= ESS_MAESTRO3) { | ||
2531 | n &= ~INT_CLK_MULT_ENABLE; | ||
2532 | n |= INT_CLK_SRC_NOT_PCI; | ||
2533 | } | ||
2534 | n &= ~( CLK_MULT_MODE_SELECT | CLK_MULT_MODE_SELECT_2 ); | ||
2535 | pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n); | ||
2536 | |||
2537 | if(card->card_type <= ESS_ALLEGRO) { | ||
2538 | pci_read_config_dword(pcidev, PCI_USER_CONFIG, &n); | ||
2539 | n |= IN_CLK_12MHZ_SELECT; | ||
2540 | pci_write_config_dword(pcidev, PCI_USER_CONFIG, n); | ||
2541 | } | ||
2542 | |||
2543 | t = inb(card->iobase + ASSP_CONTROL_A); | ||
2544 | t &= ~( DSP_CLK_36MHZ_SELECT | ASSP_CLK_49MHZ_SELECT); | ||
2545 | t |= ASSP_CLK_49MHZ_SELECT; | ||
2546 | t |= ASSP_0_WS_ENABLE; | ||
2547 | outb(t, card->iobase + ASSP_CONTROL_A); | ||
2548 | |||
2549 | outb(RUN_ASSP, card->iobase + ASSP_CONTROL_B); | ||
2550 | |||
2551 | return 0; | ||
2552 | } | ||
2553 | |||
2554 | static void m3_enable_ints(struct m3_card *card) | ||
2555 | { | ||
2556 | unsigned long io = card->iobase; | ||
2557 | |||
2558 | outw(ASSP_INT_ENABLE, io + HOST_INT_CTRL); | ||
2559 | outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, | ||
2560 | io + ASSP_CONTROL_C); | ||
2561 | } | ||
2562 | |||
2563 | static struct file_operations m3_audio_fops = { | ||
2564 | .owner = THIS_MODULE, | ||
2565 | .llseek = no_llseek, | ||
2566 | .read = m3_read, | ||
2567 | .write = m3_write, | ||
2568 | .poll = m3_poll, | ||
2569 | .ioctl = m3_ioctl, | ||
2570 | .mmap = m3_mmap, | ||
2571 | .open = m3_open, | ||
2572 | .release = m3_release, | ||
2573 | }; | ||
2574 | |||
2575 | #ifdef CONFIG_PM | ||
2576 | static int alloc_dsp_suspendmem(struct m3_card *card) | ||
2577 | { | ||
2578 | int len = sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH); | ||
2579 | |||
2580 | if( (card->suspend_mem = vmalloc(len)) == NULL) | ||
2581 | return 1; | ||
2582 | |||
2583 | return 0; | ||
2584 | } | ||
2585 | |||
2586 | #else | ||
2587 | #define alloc_dsp_suspendmem(args...) 0 | ||
2588 | #endif | ||
2589 | |||
2590 | /* | ||
2591 | * great day! this function is ugly as hell. | ||
2592 | */ | ||
2593 | static int __devinit m3_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) | ||
2594 | { | ||
2595 | u32 n; | ||
2596 | int i; | ||
2597 | struct m3_card *card = NULL; | ||
2598 | int ret = 0; | ||
2599 | int card_type = pci_id->driver_data; | ||
2600 | |||
2601 | DPRINTK(DPMOD, "in maestro_install\n"); | ||
2602 | |||
2603 | if (pci_enable_device(pci_dev)) | ||
2604 | return -EIO; | ||
2605 | |||
2606 | if (pci_set_dma_mask(pci_dev, M3_PCI_DMA_MASK)) { | ||
2607 | printk(KERN_ERR PFX "architecture does not support limiting to 28bit PCI bus addresses\n"); | ||
2608 | return -ENODEV; | ||
2609 | } | ||
2610 | |||
2611 | pci_set_master(pci_dev); | ||
2612 | |||
2613 | if( (card = kmalloc(sizeof(struct m3_card), GFP_KERNEL)) == NULL) { | ||
2614 | printk(KERN_WARNING PFX "out of memory\n"); | ||
2615 | return -ENOMEM; | ||
2616 | } | ||
2617 | memset(card, 0, sizeof(struct m3_card)); | ||
2618 | card->pcidev = pci_dev; | ||
2619 | init_waitqueue_head(&card->suspend_queue); | ||
2620 | |||
2621 | if ( ! request_region(pci_resource_start(pci_dev, 0), | ||
2622 | pci_resource_len (pci_dev, 0), M3_MODULE_NAME)) { | ||
2623 | |||
2624 | printk(KERN_WARNING PFX "unable to reserve I/O space.\n"); | ||
2625 | ret = -EBUSY; | ||
2626 | goto out; | ||
2627 | } | ||
2628 | |||
2629 | card->iobase = pci_resource_start(pci_dev, 0); | ||
2630 | |||
2631 | if(alloc_dsp_suspendmem(card)) { | ||
2632 | printk(KERN_WARNING PFX "couldn't alloc %d bytes for saving dsp state on suspend\n", | ||
2633 | REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH); | ||
2634 | ret = -ENOMEM; | ||
2635 | goto out; | ||
2636 | } | ||
2637 | |||
2638 | card->card_type = card_type; | ||
2639 | card->irq = pci_dev->irq; | ||
2640 | card->next = devs; | ||
2641 | card->magic = M3_CARD_MAGIC; | ||
2642 | spin_lock_init(&card->lock); | ||
2643 | spin_lock_init(&card->ac97_lock); | ||
2644 | devs = card; | ||
2645 | for(i = 0; i<NR_DSPS; i++) { | ||
2646 | struct m3_state *s = &(card->channels[i]); | ||
2647 | s->dev_audio = -1; | ||
2648 | } | ||
2649 | |||
2650 | printk(KERN_INFO PFX "Configuring ESS %s found at IO 0x%04X IRQ %d\n", | ||
2651 | card_names[card->card_type], card->iobase, card->irq); | ||
2652 | |||
2653 | pci_read_config_dword(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &n); | ||
2654 | printk(KERN_INFO PFX " subvendor id: 0x%08x\n",n); | ||
2655 | |||
2656 | maestro_config(card); | ||
2657 | m3_assp_halt(card); | ||
2658 | |||
2659 | m3_codec_reset(card, 0); | ||
2660 | |||
2661 | if(m3_codec_install(card)) { | ||
2662 | ret = -EIO; | ||
2663 | goto out; | ||
2664 | } | ||
2665 | |||
2666 | m3_assp_init(card); | ||
2667 | m3_amp_enable(card, 1); | ||
2668 | |||
2669 | for(i=0;i<NR_DSPS;i++) { | ||
2670 | struct m3_state *s=&card->channels[i]; | ||
2671 | |||
2672 | s->index = i; | ||
2673 | |||
2674 | s->card = card; | ||
2675 | init_waitqueue_head(&s->dma_adc.wait); | ||
2676 | init_waitqueue_head(&s->dma_dac.wait); | ||
2677 | init_waitqueue_head(&s->open_wait); | ||
2678 | mutex_init(&(s->open_mutex)); | ||
2679 | s->magic = M3_STATE_MAGIC; | ||
2680 | |||
2681 | m3_assp_client_init(s); | ||
2682 | |||
2683 | if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf) | ||
2684 | printk(KERN_WARNING PFX "initing a dsp device that is already in use?\n"); | ||
2685 | /* register devices */ | ||
2686 | if ((s->dev_audio = register_sound_dsp(&m3_audio_fops, -1)) < 0) { | ||
2687 | break; | ||
2688 | } | ||
2689 | |||
2690 | if( allocate_dmabuf(card->pcidev, &(s->dma_adc)) || | ||
2691 | allocate_dmabuf(card->pcidev, &(s->dma_dac))) { | ||
2692 | ret = -ENOMEM; | ||
2693 | goto out; | ||
2694 | } | ||
2695 | } | ||
2696 | |||
2697 | if(request_irq(card->irq, m3_interrupt, IRQF_SHARED, card_names[card->card_type], card)) { | ||
2698 | |||
2699 | printk(KERN_ERR PFX "unable to allocate irq %d,\n", card->irq); | ||
2700 | |||
2701 | ret = -EIO; | ||
2702 | goto out; | ||
2703 | } | ||
2704 | |||
2705 | pci_set_drvdata(pci_dev, card); | ||
2706 | |||
2707 | m3_enable_ints(card); | ||
2708 | m3_assp_continue(card); | ||
2709 | |||
2710 | out: | ||
2711 | if(ret) { | ||
2712 | if(card->iobase) | ||
2713 | release_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); | ||
2714 | vfree(card->suspend_mem); | ||
2715 | if(card->ac97) { | ||
2716 | unregister_sound_mixer(card->ac97->dev_mixer); | ||
2717 | kfree(card->ac97); | ||
2718 | } | ||
2719 | for(i=0;i<NR_DSPS;i++) | ||
2720 | { | ||
2721 | struct m3_state *s = &card->channels[i]; | ||
2722 | if(s->dev_audio != -1) | ||
2723 | unregister_sound_dsp(s->dev_audio); | ||
2724 | } | ||
2725 | kfree(card); | ||
2726 | } | ||
2727 | |||
2728 | return ret; | ||
2729 | } | ||
2730 | |||
2731 | static void m3_remove(struct pci_dev *pci_dev) | ||
2732 | { | ||
2733 | struct m3_card *card; | ||
2734 | |||
2735 | unregister_reboot_notifier(&m3_reboot_nb); | ||
2736 | |||
2737 | while ((card = devs)) { | ||
2738 | int i; | ||
2739 | devs = devs->next; | ||
2740 | |||
2741 | free_irq(card->irq, card); | ||
2742 | unregister_sound_mixer(card->ac97->dev_mixer); | ||
2743 | kfree(card->ac97); | ||
2744 | |||
2745 | for(i=0;i<NR_DSPS;i++) | ||
2746 | { | ||
2747 | struct m3_state *s = &card->channels[i]; | ||
2748 | if(s->dev_audio < 0) | ||
2749 | continue; | ||
2750 | |||
2751 | unregister_sound_dsp(s->dev_audio); | ||
2752 | free_dmabuf(card->pcidev, &s->dma_adc); | ||
2753 | free_dmabuf(card->pcidev, &s->dma_dac); | ||
2754 | } | ||
2755 | |||
2756 | release_region(card->iobase, 256); | ||
2757 | vfree(card->suspend_mem); | ||
2758 | kfree(card); | ||
2759 | } | ||
2760 | devs = NULL; | ||
2761 | } | ||
2762 | |||
2763 | /* | ||
2764 | * some bioses like the sound chip to be powered down | ||
2765 | * at shutdown. We're just calling _suspend to | ||
2766 | * achieve that.. | ||
2767 | */ | ||
2768 | static int m3_notifier(struct notifier_block *nb, unsigned long event, void *buf) | ||
2769 | { | ||
2770 | struct m3_card *card; | ||
2771 | |||
2772 | DPRINTK(DPMOD, "notifier suspending all cards\n"); | ||
2773 | |||
2774 | for(card = devs; card != NULL; card = card->next) { | ||
2775 | if(!card->in_suspend) | ||
2776 | m3_suspend(card->pcidev, PMSG_SUSPEND); /* XXX legal? */ | ||
2777 | } | ||
2778 | return 0; | ||
2779 | } | ||
2780 | |||
2781 | static int m3_suspend(struct pci_dev *pci_dev, pm_message_t state) | ||
2782 | { | ||
2783 | unsigned long flags; | ||
2784 | int i; | ||
2785 | struct m3_card *card = pci_get_drvdata(pci_dev); | ||
2786 | |||
2787 | /* must be a better way.. */ | ||
2788 | spin_lock_irqsave(&card->lock, flags); | ||
2789 | |||
2790 | DPRINTK(DPMOD, "pm in dev %p\n",card); | ||
2791 | |||
2792 | for(i=0;i<NR_DSPS;i++) { | ||
2793 | struct m3_state *s = &card->channels[i]; | ||
2794 | |||
2795 | if(s->dev_audio == -1) | ||
2796 | continue; | ||
2797 | |||
2798 | DPRINTK(DPMOD, "stop_adc/dac() device %d\n",i); | ||
2799 | stop_dac(s); | ||
2800 | stop_adc(s); | ||
2801 | } | ||
2802 | |||
2803 | mdelay(10); /* give the assp a chance to idle.. */ | ||
2804 | |||
2805 | m3_assp_halt(card); | ||
2806 | |||
2807 | if(card->suspend_mem) { | ||
2808 | int index = 0; | ||
2809 | |||
2810 | DPRINTK(DPMOD, "saving code\n"); | ||
2811 | for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++) | ||
2812 | card->suspend_mem[index++] = | ||
2813 | m3_assp_read(card, MEMTYPE_INTERNAL_CODE, i); | ||
2814 | DPRINTK(DPMOD, "saving data\n"); | ||
2815 | for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++) | ||
2816 | card->suspend_mem[index++] = | ||
2817 | m3_assp_read(card, MEMTYPE_INTERNAL_DATA, i); | ||
2818 | } | ||
2819 | |||
2820 | DPRINTK(DPMOD, "powering down apci regs\n"); | ||
2821 | m3_outw(card, 0xffff, 0x54); | ||
2822 | m3_outw(card, 0xffff, 0x56); | ||
2823 | |||
2824 | card->in_suspend = 1; | ||
2825 | |||
2826 | spin_unlock_irqrestore(&card->lock, flags); | ||
2827 | |||
2828 | return 0; | ||
2829 | } | ||
2830 | |||
2831 | static int m3_resume(struct pci_dev *pci_dev) | ||
2832 | { | ||
2833 | unsigned long flags; | ||
2834 | int index; | ||
2835 | int i; | ||
2836 | struct m3_card *card = pci_get_drvdata(pci_dev); | ||
2837 | |||
2838 | spin_lock_irqsave(&card->lock, flags); | ||
2839 | card->in_suspend = 0; | ||
2840 | |||
2841 | DPRINTK(DPMOD, "resuming\n"); | ||
2842 | |||
2843 | /* first lets just bring everything back. .*/ | ||
2844 | |||
2845 | DPRINTK(DPMOD, "bringing power back on card 0x%p\n",card); | ||
2846 | m3_outw(card, 0, 0x54); | ||
2847 | m3_outw(card, 0, 0x56); | ||
2848 | |||
2849 | DPRINTK(DPMOD, "restoring pci configs and reseting codec\n"); | ||
2850 | maestro_config(card); | ||
2851 | m3_assp_halt(card); | ||
2852 | m3_codec_reset(card, 1); | ||
2853 | |||
2854 | DPRINTK(DPMOD, "restoring dsp code card\n"); | ||
2855 | index = 0; | ||
2856 | for(i = REV_B_CODE_MEMORY_BEGIN ; i <= REV_B_CODE_MEMORY_END; i++) | ||
2857 | m3_assp_write(card, MEMTYPE_INTERNAL_CODE, i, | ||
2858 | card->suspend_mem[index++]); | ||
2859 | for(i = REV_B_DATA_MEMORY_BEGIN ; i <= REV_B_DATA_MEMORY_END; i++) | ||
2860 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, i, | ||
2861 | card->suspend_mem[index++]); | ||
2862 | |||
2863 | /* tell the dma engine to restart itself */ | ||
2864 | m3_assp_write(card, MEMTYPE_INTERNAL_DATA, | ||
2865 | KDATA_DMA_ACTIVE, 0); | ||
2866 | |||
2867 | DPRINTK(DPMOD, "resuming dsp\n"); | ||
2868 | m3_assp_continue(card); | ||
2869 | |||
2870 | DPRINTK(DPMOD, "enabling ints\n"); | ||
2871 | m3_enable_ints(card); | ||
2872 | |||
2873 | /* bring back the old school flavor */ | ||
2874 | for(i = 0; i < SOUND_MIXER_NRDEVICES ; i++) { | ||
2875 | int state = card->ac97->mixer_state[i]; | ||
2876 | if (!supported_mixer(card->ac97, i)) | ||
2877 | continue; | ||
2878 | |||
2879 | card->ac97->write_mixer(card->ac97, i, | ||
2880 | state & 0xff, (state >> 8) & 0xff); | ||
2881 | } | ||
2882 | |||
2883 | m3_amp_enable(card, 1); | ||
2884 | |||
2885 | /* | ||
2886 | * now we flip on the music | ||
2887 | */ | ||
2888 | for(i=0;i<NR_DSPS;i++) { | ||
2889 | struct m3_state *s = &card->channels[i]; | ||
2890 | if(s->dev_audio == -1) | ||
2891 | continue; | ||
2892 | /* | ||
2893 | * db->ready makes it so these guys can be | ||
2894 | * called unconditionally.. | ||
2895 | */ | ||
2896 | DPRINTK(DPMOD, "turning on dacs ind %d\n",i); | ||
2897 | start_dac(s); | ||
2898 | start_adc(s); | ||
2899 | } | ||
2900 | |||
2901 | spin_unlock_irqrestore(&card->lock, flags); | ||
2902 | |||
2903 | /* | ||
2904 | * all right, we think things are ready, | ||
2905 | * wake up people who were using the device | ||
2906 | * when we suspended | ||
2907 | */ | ||
2908 | wake_up(&card->suspend_queue); | ||
2909 | |||
2910 | return 0; | ||
2911 | } | ||
2912 | |||
2913 | MODULE_AUTHOR("Zach Brown <zab@zabbo.net>"); | ||
2914 | MODULE_DESCRIPTION("ESS Maestro3/Allegro Driver"); | ||
2915 | MODULE_LICENSE("GPL"); | ||
2916 | |||
2917 | #ifdef M_DEBUG | ||
2918 | module_param(debug, int, 0); | ||
2919 | #endif | ||
2920 | module_param(external_amp, int, 0); | ||
2921 | module_param(gpio_pin, int, 0); | ||
2922 | |||
2923 | static struct pci_driver m3_pci_driver = { | ||
2924 | .name = "ess_m3_audio", | ||
2925 | .id_table = m3_id_table, | ||
2926 | .probe = m3_probe, | ||
2927 | .remove = m3_remove, | ||
2928 | .suspend = m3_suspend, | ||
2929 | .resume = m3_resume, | ||
2930 | }; | ||
2931 | |||
2932 | static int __init m3_init_module(void) | ||
2933 | { | ||
2934 | printk(KERN_INFO PFX "version " DRIVER_VERSION " built at " __TIME__ " " __DATE__ "\n"); | ||
2935 | |||
2936 | if (register_reboot_notifier(&m3_reboot_nb)) { | ||
2937 | printk(KERN_WARNING PFX "reboot notifier registration failed\n"); | ||
2938 | return -ENODEV; /* ? */ | ||
2939 | } | ||
2940 | |||
2941 | if (pci_register_driver(&m3_pci_driver)) { | ||
2942 | unregister_reboot_notifier(&m3_reboot_nb); | ||
2943 | return -ENODEV; | ||
2944 | } | ||
2945 | return 0; | ||
2946 | } | ||
2947 | |||
2948 | static void __exit m3_cleanup_module(void) | ||
2949 | { | ||
2950 | pci_unregister_driver(&m3_pci_driver); | ||
2951 | } | ||
2952 | |||
2953 | module_init(m3_init_module); | ||
2954 | module_exit(m3_cleanup_module); | ||
2955 | |||
2956 | void check_suspend(struct m3_card *card) | ||
2957 | { | ||
2958 | DECLARE_WAITQUEUE(wait, current); | ||
2959 | |||
2960 | if(!card->in_suspend) | ||
2961 | return; | ||
2962 | |||
2963 | card->in_suspend++; | ||
2964 | add_wait_queue(&card->suspend_queue, &wait); | ||
2965 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2966 | schedule(); | ||
2967 | remove_wait_queue(&card->suspend_queue, &wait); | ||
2968 | set_current_state(TASK_RUNNING); | ||
2969 | } | ||
diff --git a/sound/oss/maestro3.h b/sound/oss/maestro3.h deleted file mode 100644 index dde29862c572..000000000000 --- a/sound/oss/maestro3.h +++ /dev/null | |||
@@ -1,821 +0,0 @@ | |||
1 | /* | ||
2 | * ESS Technology allegro audio driver. | ||
3 | * | ||
4 | * Copyright (C) 1992-2000 Don Kim (don.kim@esstech.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | * Hacked for the maestro3 driver by zab | ||
21 | */ | ||
22 | |||
23 | // Allegro PCI configuration registers | ||
24 | #define PCI_LEGACY_AUDIO_CTRL 0x40 | ||
25 | #define SOUND_BLASTER_ENABLE 0x00000001 | ||
26 | #define FM_SYNTHESIS_ENABLE 0x00000002 | ||
27 | #define GAME_PORT_ENABLE 0x00000004 | ||
28 | #define MPU401_IO_ENABLE 0x00000008 | ||
29 | #define MPU401_IRQ_ENABLE 0x00000010 | ||
30 | #define ALIAS_10BIT_IO 0x00000020 | ||
31 | #define SB_DMA_MASK 0x000000C0 | ||
32 | #define SB_DMA_0 0x00000040 | ||
33 | #define SB_DMA_1 0x00000040 | ||
34 | #define SB_DMA_R 0x00000080 | ||
35 | #define SB_DMA_3 0x000000C0 | ||
36 | #define SB_IRQ_MASK 0x00000700 | ||
37 | #define SB_IRQ_5 0x00000000 | ||
38 | #define SB_IRQ_7 0x00000100 | ||
39 | #define SB_IRQ_9 0x00000200 | ||
40 | #define SB_IRQ_10 0x00000300 | ||
41 | #define MIDI_IRQ_MASK 0x00003800 | ||
42 | #define SERIAL_IRQ_ENABLE 0x00004000 | ||
43 | #define DISABLE_LEGACY 0x00008000 | ||
44 | |||
45 | #define PCI_ALLEGRO_CONFIG 0x50 | ||
46 | #define SB_ADDR_240 0x00000004 | ||
47 | #define MPU_ADDR_MASK 0x00000018 | ||
48 | #define MPU_ADDR_330 0x00000000 | ||
49 | #define MPU_ADDR_300 0x00000008 | ||
50 | #define MPU_ADDR_320 0x00000010 | ||
51 | #define MPU_ADDR_340 0x00000018 | ||
52 | #define USE_PCI_TIMING 0x00000040 | ||
53 | #define POSTED_WRITE_ENABLE 0x00000080 | ||
54 | #define DMA_POLICY_MASK 0x00000700 | ||
55 | #define DMA_DDMA 0x00000000 | ||
56 | #define DMA_TDMA 0x00000100 | ||
57 | #define DMA_PCPCI 0x00000200 | ||
58 | #define DMA_WBDMA16 0x00000400 | ||
59 | #define DMA_WBDMA4 0x00000500 | ||
60 | #define DMA_WBDMA2 0x00000600 | ||
61 | #define DMA_WBDMA1 0x00000700 | ||
62 | #define DMA_SAFE_GUARD 0x00000800 | ||
63 | #define HI_PERF_GP_ENABLE 0x00001000 | ||
64 | #define PIC_SNOOP_MODE_0 0x00002000 | ||
65 | #define PIC_SNOOP_MODE_1 0x00004000 | ||
66 | #define SOUNDBLASTER_IRQ_MASK 0x00008000 | ||
67 | #define RING_IN_ENABLE 0x00010000 | ||
68 | #define SPDIF_TEST_MODE 0x00020000 | ||
69 | #define CLK_MULT_MODE_SELECT_2 0x00040000 | ||
70 | #define EEPROM_WRITE_ENABLE 0x00080000 | ||
71 | #define CODEC_DIR_IN 0x00100000 | ||
72 | #define HV_BUTTON_FROM_GD 0x00200000 | ||
73 | #define REDUCED_DEBOUNCE 0x00400000 | ||
74 | #define HV_CTRL_ENABLE 0x00800000 | ||
75 | #define SPDIF_ENABLE 0x01000000 | ||
76 | #define CLK_DIV_SELECT 0x06000000 | ||
77 | #define CLK_DIV_BY_48 0x00000000 | ||
78 | #define CLK_DIV_BY_49 0x02000000 | ||
79 | #define CLK_DIV_BY_50 0x04000000 | ||
80 | #define CLK_DIV_RESERVED 0x06000000 | ||
81 | #define PM_CTRL_ENABLE 0x08000000 | ||
82 | #define CLK_MULT_MODE_SELECT 0x30000000 | ||
83 | #define CLK_MULT_MODE_SHIFT 28 | ||
84 | #define CLK_MULT_MODE_0 0x00000000 | ||
85 | #define CLK_MULT_MODE_1 0x10000000 | ||
86 | #define CLK_MULT_MODE_2 0x20000000 | ||
87 | #define CLK_MULT_MODE_3 0x30000000 | ||
88 | #define INT_CLK_SELECT 0x40000000 | ||
89 | #define INT_CLK_MULT_RESET 0x80000000 | ||
90 | |||
91 | // M3 | ||
92 | #define INT_CLK_SRC_NOT_PCI 0x00100000 | ||
93 | #define INT_CLK_MULT_ENABLE 0x80000000 | ||
94 | |||
95 | #define PCI_ACPI_CONTROL 0x54 | ||
96 | #define PCI_ACPI_D0 0x00000000 | ||
97 | #define PCI_ACPI_D1 0xB4F70000 | ||
98 | #define PCI_ACPI_D2 0xB4F7B4F7 | ||
99 | |||
100 | #define PCI_USER_CONFIG 0x58 | ||
101 | #define EXT_PCI_MASTER_ENABLE 0x00000001 | ||
102 | #define SPDIF_OUT_SELECT 0x00000002 | ||
103 | #define TEST_PIN_DIR_CTRL 0x00000004 | ||
104 | #define AC97_CODEC_TEST 0x00000020 | ||
105 | #define TRI_STATE_BUFFER 0x00000080 | ||
106 | #define IN_CLK_12MHZ_SELECT 0x00000100 | ||
107 | #define MULTI_FUNC_DISABLE 0x00000200 | ||
108 | #define EXT_MASTER_PAIR_SEL 0x00000400 | ||
109 | #define PCI_MASTER_SUPPORT 0x00000800 | ||
110 | #define STOP_CLOCK_ENABLE 0x00001000 | ||
111 | #define EAPD_DRIVE_ENABLE 0x00002000 | ||
112 | #define REQ_TRI_STATE_ENABLE 0x00004000 | ||
113 | #define REQ_LOW_ENABLE 0x00008000 | ||
114 | #define MIDI_1_ENABLE 0x00010000 | ||
115 | #define MIDI_2_ENABLE 0x00020000 | ||
116 | #define SB_AUDIO_SYNC 0x00040000 | ||
117 | #define HV_CTRL_TEST 0x00100000 | ||
118 | #define SOUNDBLASTER_TEST 0x00400000 | ||
119 | |||
120 | #define PCI_USER_CONFIG_C 0x5C | ||
121 | |||
122 | #define PCI_DDMA_CTRL 0x60 | ||
123 | #define DDMA_ENABLE 0x00000001 | ||
124 | |||
125 | |||
126 | // Allegro registers | ||
127 | #define HOST_INT_CTRL 0x18 | ||
128 | #define SB_INT_ENABLE 0x0001 | ||
129 | #define MPU401_INT_ENABLE 0x0002 | ||
130 | #define ASSP_INT_ENABLE 0x0010 | ||
131 | #define RING_INT_ENABLE 0x0020 | ||
132 | #define HV_INT_ENABLE 0x0040 | ||
133 | #define CLKRUN_GEN_ENABLE 0x0100 | ||
134 | #define HV_CTRL_TO_PME 0x0400 | ||
135 | #define SOFTWARE_RESET_ENABLE 0x8000 | ||
136 | |||
137 | /* | ||
138 | * should be using the above defines, probably. | ||
139 | */ | ||
140 | #define REGB_ENABLE_RESET 0x01 | ||
141 | #define REGB_STOP_CLOCK 0x10 | ||
142 | |||
143 | #define HOST_INT_STATUS 0x1A | ||
144 | #define SB_INT_PENDING 0x01 | ||
145 | #define MPU401_INT_PENDING 0x02 | ||
146 | #define ASSP_INT_PENDING 0x10 | ||
147 | #define RING_INT_PENDING 0x20 | ||
148 | #define HV_INT_PENDING 0x40 | ||
149 | |||
150 | #define HARDWARE_VOL_CTRL 0x1B | ||
151 | #define SHADOW_MIX_REG_VOICE 0x1C | ||
152 | #define HW_VOL_COUNTER_VOICE 0x1D | ||
153 | #define SHADOW_MIX_REG_MASTER 0x1E | ||
154 | #define HW_VOL_COUNTER_MASTER 0x1F | ||
155 | |||
156 | #define CODEC_COMMAND 0x30 | ||
157 | #define CODEC_READ_B 0x80 | ||
158 | |||
159 | #define CODEC_STATUS 0x30 | ||
160 | #define CODEC_BUSY_B 0x01 | ||
161 | |||
162 | #define CODEC_DATA 0x32 | ||
163 | |||
164 | #define RING_BUS_CTRL_A 0x36 | ||
165 | #define RAC_PME_ENABLE 0x0100 | ||
166 | #define RAC_SDFS_ENABLE 0x0200 | ||
167 | #define LAC_PME_ENABLE 0x0400 | ||
168 | #define LAC_SDFS_ENABLE 0x0800 | ||
169 | #define SERIAL_AC_LINK_ENABLE 0x1000 | ||
170 | #define IO_SRAM_ENABLE 0x2000 | ||
171 | #define IIS_INPUT_ENABLE 0x8000 | ||
172 | |||
173 | #define RING_BUS_CTRL_B 0x38 | ||
174 | #define SECOND_CODEC_ID_MASK 0x0003 | ||
175 | #define SPDIF_FUNC_ENABLE 0x0010 | ||
176 | #define SECOND_AC_ENABLE 0x0020 | ||
177 | #define SB_MODULE_INTF_ENABLE 0x0040 | ||
178 | #define SSPE_ENABLE 0x0040 | ||
179 | #define M3I_DOCK_ENABLE 0x0080 | ||
180 | |||
181 | #define SDO_OUT_DEST_CTRL 0x3A | ||
182 | #define COMMAND_ADDR_OUT 0x0003 | ||
183 | #define PCM_LR_OUT_LOCAL 0x0000 | ||
184 | #define PCM_LR_OUT_REMOTE 0x0004 | ||
185 | #define PCM_LR_OUT_MUTE 0x0008 | ||
186 | #define PCM_LR_OUT_BOTH 0x000C | ||
187 | #define LINE1_DAC_OUT_LOCAL 0x0000 | ||
188 | #define LINE1_DAC_OUT_REMOTE 0x0010 | ||
189 | #define LINE1_DAC_OUT_MUTE 0x0020 | ||
190 | #define LINE1_DAC_OUT_BOTH 0x0030 | ||
191 | #define PCM_CLS_OUT_LOCAL 0x0000 | ||
192 | #define PCM_CLS_OUT_REMOTE 0x0040 | ||
193 | #define PCM_CLS_OUT_MUTE 0x0080 | ||
194 | #define PCM_CLS_OUT_BOTH 0x00C0 | ||
195 | #define PCM_RLF_OUT_LOCAL 0x0000 | ||
196 | #define PCM_RLF_OUT_REMOTE 0x0100 | ||
197 | #define PCM_RLF_OUT_MUTE 0x0200 | ||
198 | #define PCM_RLF_OUT_BOTH 0x0300 | ||
199 | #define LINE2_DAC_OUT_LOCAL 0x0000 | ||
200 | #define LINE2_DAC_OUT_REMOTE 0x0400 | ||
201 | #define LINE2_DAC_OUT_MUTE 0x0800 | ||
202 | #define LINE2_DAC_OUT_BOTH 0x0C00 | ||
203 | #define HANDSET_OUT_LOCAL 0x0000 | ||
204 | #define HANDSET_OUT_REMOTE 0x1000 | ||
205 | #define HANDSET_OUT_MUTE 0x2000 | ||
206 | #define HANDSET_OUT_BOTH 0x3000 | ||
207 | #define IO_CTRL_OUT_LOCAL 0x0000 | ||
208 | #define IO_CTRL_OUT_REMOTE 0x4000 | ||
209 | #define IO_CTRL_OUT_MUTE 0x8000 | ||
210 | #define IO_CTRL_OUT_BOTH 0xC000 | ||
211 | |||
212 | #define SDO_IN_DEST_CTRL 0x3C | ||
213 | #define STATUS_ADDR_IN 0x0003 | ||
214 | #define PCM_LR_IN_LOCAL 0x0000 | ||
215 | #define PCM_LR_IN_REMOTE 0x0004 | ||
216 | #define PCM_LR_RESERVED 0x0008 | ||
217 | #define PCM_LR_IN_BOTH 0x000C | ||
218 | #define LINE1_ADC_IN_LOCAL 0x0000 | ||
219 | #define LINE1_ADC_IN_REMOTE 0x0010 | ||
220 | #define LINE1_ADC_IN_MUTE 0x0020 | ||
221 | #define MIC_ADC_IN_LOCAL 0x0000 | ||
222 | #define MIC_ADC_IN_REMOTE 0x0040 | ||
223 | #define MIC_ADC_IN_MUTE 0x0080 | ||
224 | #define LINE2_DAC_IN_LOCAL 0x0000 | ||
225 | #define LINE2_DAC_IN_REMOTE 0x0400 | ||
226 | #define LINE2_DAC_IN_MUTE 0x0800 | ||
227 | #define HANDSET_IN_LOCAL 0x0000 | ||
228 | #define HANDSET_IN_REMOTE 0x1000 | ||
229 | #define HANDSET_IN_MUTE 0x2000 | ||
230 | #define IO_STATUS_IN_LOCAL 0x0000 | ||
231 | #define IO_STATUS_IN_REMOTE 0x4000 | ||
232 | |||
233 | #define SPDIF_IN_CTRL 0x3E | ||
234 | #define SPDIF_IN_ENABLE 0x0001 | ||
235 | |||
236 | #define GPIO_DATA 0x60 | ||
237 | #define GPIO_DATA_MASK 0x0FFF | ||
238 | #define GPIO_HV_STATUS 0x3000 | ||
239 | #define GPIO_PME_STATUS 0x4000 | ||
240 | |||
241 | #define GPIO_MASK 0x64 | ||
242 | #define GPIO_DIRECTION 0x68 | ||
243 | #define GPO_PRIMARY_AC97 0x0001 | ||
244 | #define GPI_LINEOUT_SENSE 0x0004 | ||
245 | #define GPO_SECONDARY_AC97 0x0008 | ||
246 | #define GPI_VOL_DOWN 0x0010 | ||
247 | #define GPI_VOL_UP 0x0020 | ||
248 | #define GPI_IIS_CLK 0x0040 | ||
249 | #define GPI_IIS_LRCLK 0x0080 | ||
250 | #define GPI_IIS_DATA 0x0100 | ||
251 | #define GPI_DOCKING_STATUS 0x0100 | ||
252 | #define GPI_HEADPHONE_SENSE 0x0200 | ||
253 | #define GPO_EXT_AMP_SHUTDOWN 0x1000 | ||
254 | |||
255 | // M3 | ||
256 | #define GPO_M3_EXT_AMP_SHUTDN 0x0002 | ||
257 | |||
258 | #define ASSP_INDEX_PORT 0x80 | ||
259 | #define ASSP_MEMORY_PORT 0x82 | ||
260 | #define ASSP_DATA_PORT 0x84 | ||
261 | |||
262 | #define MPU401_DATA_PORT 0x98 | ||
263 | #define MPU401_STATUS_PORT 0x99 | ||
264 | |||
265 | #define CLK_MULT_DATA_PORT 0x9C | ||
266 | |||
267 | #define ASSP_CONTROL_A 0xA2 | ||
268 | #define ASSP_0_WS_ENABLE 0x01 | ||
269 | #define ASSP_CTRL_A_RESERVED1 0x02 | ||
270 | #define ASSP_CTRL_A_RESERVED2 0x04 | ||
271 | #define ASSP_CLK_49MHZ_SELECT 0x08 | ||
272 | #define FAST_PLU_ENABLE 0x10 | ||
273 | #define ASSP_CTRL_A_RESERVED3 0x20 | ||
274 | #define DSP_CLK_36MHZ_SELECT 0x40 | ||
275 | |||
276 | #define ASSP_CONTROL_B 0xA4 | ||
277 | #define RESET_ASSP 0x00 | ||
278 | #define RUN_ASSP 0x01 | ||
279 | #define ENABLE_ASSP_CLOCK 0x00 | ||
280 | #define STOP_ASSP_CLOCK 0x10 | ||
281 | #define RESET_TOGGLE 0x40 | ||
282 | |||
283 | #define ASSP_CONTROL_C 0xA6 | ||
284 | #define ASSP_HOST_INT_ENABLE 0x01 | ||
285 | #define FM_ADDR_REMAP_DISABLE 0x02 | ||
286 | #define HOST_WRITE_PORT_ENABLE 0x08 | ||
287 | |||
288 | #define ASSP_HOST_INT_STATUS 0xAC | ||
289 | #define DSP2HOST_REQ_PIORECORD 0x01 | ||
290 | #define DSP2HOST_REQ_I2SRATE 0x02 | ||
291 | #define DSP2HOST_REQ_TIMER 0x04 | ||
292 | |||
293 | // AC97 registers | ||
294 | // XXX fix this crap up | ||
295 | /*#define AC97_RESET 0x00*/ | ||
296 | |||
297 | #define AC97_VOL_MUTE_B 0x8000 | ||
298 | #define AC97_VOL_M 0x1F | ||
299 | #define AC97_LEFT_VOL_S 8 | ||
300 | |||
301 | #define AC97_MASTER_VOL 0x02 | ||
302 | #define AC97_LINE_LEVEL_VOL 0x04 | ||
303 | #define AC97_MASTER_MONO_VOL 0x06 | ||
304 | #define AC97_PC_BEEP_VOL 0x0A | ||
305 | #define AC97_PC_BEEP_VOL_M 0x0F | ||
306 | #define AC97_SROUND_MASTER_VOL 0x38 | ||
307 | #define AC97_PC_BEEP_VOL_S 1 | ||
308 | |||
309 | /*#define AC97_PHONE_VOL 0x0C | ||
310 | #define AC97_MIC_VOL 0x0E*/ | ||
311 | #define AC97_MIC_20DB_ENABLE 0x40 | ||
312 | |||
313 | /*#define AC97_LINEIN_VOL 0x10 | ||
314 | #define AC97_CD_VOL 0x12 | ||
315 | #define AC97_VIDEO_VOL 0x14 | ||
316 | #define AC97_AUX_VOL 0x16*/ | ||
317 | #define AC97_PCM_OUT_VOL 0x18 | ||
318 | /*#define AC97_RECORD_SELECT 0x1A*/ | ||
319 | #define AC97_RECORD_MIC 0x00 | ||
320 | #define AC97_RECORD_CD 0x01 | ||
321 | #define AC97_RECORD_VIDEO 0x02 | ||
322 | #define AC97_RECORD_AUX 0x03 | ||
323 | #define AC97_RECORD_MONO_MUX 0x02 | ||
324 | #define AC97_RECORD_DIGITAL 0x03 | ||
325 | #define AC97_RECORD_LINE 0x04 | ||
326 | #define AC97_RECORD_STEREO 0x05 | ||
327 | #define AC97_RECORD_MONO 0x06 | ||
328 | #define AC97_RECORD_PHONE 0x07 | ||
329 | |||
330 | /*#define AC97_RECORD_GAIN 0x1C*/ | ||
331 | #define AC97_RECORD_VOL_M 0x0F | ||
332 | |||
333 | /*#define AC97_GENERAL_PURPOSE 0x20*/ | ||
334 | #define AC97_POWER_DOWN_CTRL 0x26 | ||
335 | #define AC97_ADC_READY 0x0001 | ||
336 | #define AC97_DAC_READY 0x0002 | ||
337 | #define AC97_ANALOG_READY 0x0004 | ||
338 | #define AC97_VREF_ON 0x0008 | ||
339 | #define AC97_PR0 0x0100 | ||
340 | #define AC97_PR1 0x0200 | ||
341 | #define AC97_PR2 0x0400 | ||
342 | #define AC97_PR3 0x0800 | ||
343 | #define AC97_PR4 0x1000 | ||
344 | |||
345 | #define AC97_RESERVED1 0x28 | ||
346 | |||
347 | #define AC97_VENDOR_TEST 0x5A | ||
348 | |||
349 | #define AC97_CLOCK_DELAY 0x5C | ||
350 | #define AC97_LINEOUT_MUX_SEL 0x0001 | ||
351 | #define AC97_MONO_MUX_SEL 0x0002 | ||
352 | #define AC97_CLOCK_DELAY_SEL 0x1F | ||
353 | #define AC97_DAC_CDS_SHIFT 6 | ||
354 | #define AC97_ADC_CDS_SHIFT 11 | ||
355 | |||
356 | #define AC97_MULTI_CHANNEL_SEL 0x74 | ||
357 | |||
358 | /*#define AC97_VENDOR_ID1 0x7C | ||
359 | #define AC97_VENDOR_ID2 0x7E*/ | ||
360 | |||
361 | /* | ||
362 | * ASSP control regs | ||
363 | */ | ||
364 | #define DSP_PORT_TIMER_COUNT 0x06 | ||
365 | |||
366 | #define DSP_PORT_MEMORY_INDEX 0x80 | ||
367 | |||
368 | #define DSP_PORT_MEMORY_TYPE 0x82 | ||
369 | #define MEMTYPE_INTERNAL_CODE 0x0002 | ||
370 | #define MEMTYPE_INTERNAL_DATA 0x0003 | ||
371 | #define MEMTYPE_MASK 0x0003 | ||
372 | |||
373 | #define DSP_PORT_MEMORY_DATA 0x84 | ||
374 | |||
375 | #define DSP_PORT_CONTROL_REG_A 0xA2 | ||
376 | #define DSP_PORT_CONTROL_REG_B 0xA4 | ||
377 | #define DSP_PORT_CONTROL_REG_C 0xA6 | ||
378 | |||
379 | #define REV_A_CODE_MEMORY_BEGIN 0x0000 | ||
380 | #define REV_A_CODE_MEMORY_END 0x0FFF | ||
381 | #define REV_A_CODE_MEMORY_UNIT_LENGTH 0x0040 | ||
382 | #define REV_A_CODE_MEMORY_LENGTH (REV_A_CODE_MEMORY_END - REV_A_CODE_MEMORY_BEGIN + 1) | ||
383 | |||
384 | #define REV_B_CODE_MEMORY_BEGIN 0x0000 | ||
385 | #define REV_B_CODE_MEMORY_END 0x0BFF | ||
386 | #define REV_B_CODE_MEMORY_UNIT_LENGTH 0x0040 | ||
387 | #define REV_B_CODE_MEMORY_LENGTH (REV_B_CODE_MEMORY_END - REV_B_CODE_MEMORY_BEGIN + 1) | ||
388 | |||
389 | #define REV_A_DATA_MEMORY_BEGIN 0x1000 | ||
390 | #define REV_A_DATA_MEMORY_END 0x2FFF | ||
391 | #define REV_A_DATA_MEMORY_UNIT_LENGTH 0x0080 | ||
392 | #define REV_A_DATA_MEMORY_LENGTH (REV_A_DATA_MEMORY_END - REV_A_DATA_MEMORY_BEGIN + 1) | ||
393 | |||
394 | #define REV_B_DATA_MEMORY_BEGIN 0x1000 | ||
395 | #define REV_B_DATA_MEMORY_END 0x2BFF | ||
396 | #define REV_B_DATA_MEMORY_UNIT_LENGTH 0x0080 | ||
397 | #define REV_B_DATA_MEMORY_LENGTH (REV_B_DATA_MEMORY_END - REV_B_DATA_MEMORY_BEGIN + 1) | ||
398 | |||
399 | |||
400 | #define NUM_UNITS_KERNEL_CODE 16 | ||
401 | #define NUM_UNITS_KERNEL_DATA 2 | ||
402 | |||
403 | #define NUM_UNITS_KERNEL_CODE_WITH_HSP 16 | ||
404 | #define NUM_UNITS_KERNEL_DATA_WITH_HSP 5 | ||
405 | |||
406 | /* | ||
407 | * Kernel data layout | ||
408 | */ | ||
409 | |||
410 | #define DP_SHIFT_COUNT 7 | ||
411 | |||
412 | #define KDATA_BASE_ADDR 0x1000 | ||
413 | #define KDATA_BASE_ADDR2 0x1080 | ||
414 | |||
415 | #define KDATA_TASK0 (KDATA_BASE_ADDR + 0x0000) | ||
416 | #define KDATA_TASK1 (KDATA_BASE_ADDR + 0x0001) | ||
417 | #define KDATA_TASK2 (KDATA_BASE_ADDR + 0x0002) | ||
418 | #define KDATA_TASK3 (KDATA_BASE_ADDR + 0x0003) | ||
419 | #define KDATA_TASK4 (KDATA_BASE_ADDR + 0x0004) | ||
420 | #define KDATA_TASK5 (KDATA_BASE_ADDR + 0x0005) | ||
421 | #define KDATA_TASK6 (KDATA_BASE_ADDR + 0x0006) | ||
422 | #define KDATA_TASK7 (KDATA_BASE_ADDR + 0x0007) | ||
423 | #define KDATA_TASK_ENDMARK (KDATA_BASE_ADDR + 0x0008) | ||
424 | |||
425 | #define KDATA_CURRENT_TASK (KDATA_BASE_ADDR + 0x0009) | ||
426 | #define KDATA_TASK_SWITCH (KDATA_BASE_ADDR + 0x000A) | ||
427 | |||
428 | #define KDATA_INSTANCE0_POS3D (KDATA_BASE_ADDR + 0x000B) | ||
429 | #define KDATA_INSTANCE1_POS3D (KDATA_BASE_ADDR + 0x000C) | ||
430 | #define KDATA_INSTANCE2_POS3D (KDATA_BASE_ADDR + 0x000D) | ||
431 | #define KDATA_INSTANCE3_POS3D (KDATA_BASE_ADDR + 0x000E) | ||
432 | #define KDATA_INSTANCE4_POS3D (KDATA_BASE_ADDR + 0x000F) | ||
433 | #define KDATA_INSTANCE5_POS3D (KDATA_BASE_ADDR + 0x0010) | ||
434 | #define KDATA_INSTANCE6_POS3D (KDATA_BASE_ADDR + 0x0011) | ||
435 | #define KDATA_INSTANCE7_POS3D (KDATA_BASE_ADDR + 0x0012) | ||
436 | #define KDATA_INSTANCE8_POS3D (KDATA_BASE_ADDR + 0x0013) | ||
437 | #define KDATA_INSTANCE_POS3D_ENDMARK (KDATA_BASE_ADDR + 0x0014) | ||
438 | |||
439 | #define KDATA_INSTANCE0_SPKVIRT (KDATA_BASE_ADDR + 0x0015) | ||
440 | #define KDATA_INSTANCE_SPKVIRT_ENDMARK (KDATA_BASE_ADDR + 0x0016) | ||
441 | |||
442 | #define KDATA_INSTANCE0_SPDIF (KDATA_BASE_ADDR + 0x0017) | ||
443 | #define KDATA_INSTANCE_SPDIF_ENDMARK (KDATA_BASE_ADDR + 0x0018) | ||
444 | |||
445 | #define KDATA_INSTANCE0_MODEM (KDATA_BASE_ADDR + 0x0019) | ||
446 | #define KDATA_INSTANCE_MODEM_ENDMARK (KDATA_BASE_ADDR + 0x001A) | ||
447 | |||
448 | #define KDATA_INSTANCE0_SRC (KDATA_BASE_ADDR + 0x001B) | ||
449 | #define KDATA_INSTANCE1_SRC (KDATA_BASE_ADDR + 0x001C) | ||
450 | #define KDATA_INSTANCE_SRC_ENDMARK (KDATA_BASE_ADDR + 0x001D) | ||
451 | |||
452 | #define KDATA_INSTANCE0_MINISRC (KDATA_BASE_ADDR + 0x001E) | ||
453 | #define KDATA_INSTANCE1_MINISRC (KDATA_BASE_ADDR + 0x001F) | ||
454 | #define KDATA_INSTANCE2_MINISRC (KDATA_BASE_ADDR + 0x0020) | ||
455 | #define KDATA_INSTANCE3_MINISRC (KDATA_BASE_ADDR + 0x0021) | ||
456 | #define KDATA_INSTANCE_MINISRC_ENDMARK (KDATA_BASE_ADDR + 0x0022) | ||
457 | |||
458 | #define KDATA_INSTANCE0_CPYTHRU (KDATA_BASE_ADDR + 0x0023) | ||
459 | #define KDATA_INSTANCE1_CPYTHRU (KDATA_BASE_ADDR + 0x0024) | ||
460 | #define KDATA_INSTANCE_CPYTHRU_ENDMARK (KDATA_BASE_ADDR + 0x0025) | ||
461 | |||
462 | #define KDATA_CURRENT_DMA (KDATA_BASE_ADDR + 0x0026) | ||
463 | #define KDATA_DMA_SWITCH (KDATA_BASE_ADDR + 0x0027) | ||
464 | #define KDATA_DMA_ACTIVE (KDATA_BASE_ADDR + 0x0028) | ||
465 | |||
466 | #define KDATA_DMA_XFER0 (KDATA_BASE_ADDR + 0x0029) | ||
467 | #define KDATA_DMA_XFER1 (KDATA_BASE_ADDR + 0x002A) | ||
468 | #define KDATA_DMA_XFER2 (KDATA_BASE_ADDR + 0x002B) | ||
469 | #define KDATA_DMA_XFER3 (KDATA_BASE_ADDR + 0x002C) | ||
470 | #define KDATA_DMA_XFER4 (KDATA_BASE_ADDR + 0x002D) | ||
471 | #define KDATA_DMA_XFER5 (KDATA_BASE_ADDR + 0x002E) | ||
472 | #define KDATA_DMA_XFER6 (KDATA_BASE_ADDR + 0x002F) | ||
473 | #define KDATA_DMA_XFER7 (KDATA_BASE_ADDR + 0x0030) | ||
474 | #define KDATA_DMA_XFER8 (KDATA_BASE_ADDR + 0x0031) | ||
475 | #define KDATA_DMA_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0032) | ||
476 | |||
477 | #define KDATA_I2S_SAMPLE_COUNT (KDATA_BASE_ADDR + 0x0033) | ||
478 | #define KDATA_I2S_INT_METER (KDATA_BASE_ADDR + 0x0034) | ||
479 | #define KDATA_I2S_ACTIVE (KDATA_BASE_ADDR + 0x0035) | ||
480 | |||
481 | #define KDATA_TIMER_COUNT_RELOAD (KDATA_BASE_ADDR + 0x0036) | ||
482 | #define KDATA_TIMER_COUNT_CURRENT (KDATA_BASE_ADDR + 0x0037) | ||
483 | |||
484 | #define KDATA_HALT_SYNCH_CLIENT (KDATA_BASE_ADDR + 0x0038) | ||
485 | #define KDATA_HALT_SYNCH_DMA (KDATA_BASE_ADDR + 0x0039) | ||
486 | #define KDATA_HALT_ACKNOWLEDGE (KDATA_BASE_ADDR + 0x003A) | ||
487 | |||
488 | #define KDATA_ADC1_XFER0 (KDATA_BASE_ADDR + 0x003B) | ||
489 | #define KDATA_ADC1_XFER_ENDMARK (KDATA_BASE_ADDR + 0x003C) | ||
490 | #define KDATA_ADC1_LEFT_VOLUME (KDATA_BASE_ADDR + 0x003D) | ||
491 | #define KDATA_ADC1_RIGHT_VOLUME (KDATA_BASE_ADDR + 0x003E) | ||
492 | #define KDATA_ADC1_LEFT_SUR_VOL (KDATA_BASE_ADDR + 0x003F) | ||
493 | #define KDATA_ADC1_RIGHT_SUR_VOL (KDATA_BASE_ADDR + 0x0040) | ||
494 | |||
495 | #define KDATA_ADC2_XFER0 (KDATA_BASE_ADDR + 0x0041) | ||
496 | #define KDATA_ADC2_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0042) | ||
497 | #define KDATA_ADC2_LEFT_VOLUME (KDATA_BASE_ADDR + 0x0043) | ||
498 | #define KDATA_ADC2_RIGHT_VOLUME (KDATA_BASE_ADDR + 0x0044) | ||
499 | #define KDATA_ADC2_LEFT_SUR_VOL (KDATA_BASE_ADDR + 0x0045) | ||
500 | #define KDATA_ADC2_RIGHT_SUR_VOL (KDATA_BASE_ADDR + 0x0046) | ||
501 | |||
502 | #define KDATA_CD_XFER0 (KDATA_BASE_ADDR + 0x0047) | ||
503 | #define KDATA_CD_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0048) | ||
504 | #define KDATA_CD_LEFT_VOLUME (KDATA_BASE_ADDR + 0x0049) | ||
505 | #define KDATA_CD_RIGHT_VOLUME (KDATA_BASE_ADDR + 0x004A) | ||
506 | #define KDATA_CD_LEFT_SUR_VOL (KDATA_BASE_ADDR + 0x004B) | ||
507 | #define KDATA_CD_RIGHT_SUR_VOL (KDATA_BASE_ADDR + 0x004C) | ||
508 | |||
509 | #define KDATA_MIC_XFER0 (KDATA_BASE_ADDR + 0x004D) | ||
510 | #define KDATA_MIC_XFER_ENDMARK (KDATA_BASE_ADDR + 0x004E) | ||
511 | #define KDATA_MIC_VOLUME (KDATA_BASE_ADDR + 0x004F) | ||
512 | #define KDATA_MIC_SUR_VOL (KDATA_BASE_ADDR + 0x0050) | ||
513 | |||
514 | #define KDATA_I2S_XFER0 (KDATA_BASE_ADDR + 0x0051) | ||
515 | #define KDATA_I2S_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0052) | ||
516 | |||
517 | #define KDATA_CHI_XFER0 (KDATA_BASE_ADDR + 0x0053) | ||
518 | #define KDATA_CHI_XFER_ENDMARK (KDATA_BASE_ADDR + 0x0054) | ||
519 | |||
520 | #define KDATA_SPDIF_XFER (KDATA_BASE_ADDR + 0x0055) | ||
521 | #define KDATA_SPDIF_CURRENT_FRAME (KDATA_BASE_ADDR + 0x0056) | ||
522 | #define KDATA_SPDIF_FRAME0 (KDATA_BASE_ADDR + 0x0057) | ||
523 | #define KDATA_SPDIF_FRAME1 (KDATA_BASE_ADDR + 0x0058) | ||
524 | #define KDATA_SPDIF_FRAME2 (KDATA_BASE_ADDR + 0x0059) | ||
525 | |||
526 | #define KDATA_SPDIF_REQUEST (KDATA_BASE_ADDR + 0x005A) | ||
527 | #define KDATA_SPDIF_TEMP (KDATA_BASE_ADDR + 0x005B) | ||
528 | |||
529 | #define KDATA_SPDIFIN_XFER0 (KDATA_BASE_ADDR + 0x005C) | ||
530 | #define KDATA_SPDIFIN_XFER_ENDMARK (KDATA_BASE_ADDR + 0x005D) | ||
531 | #define KDATA_SPDIFIN_INT_METER (KDATA_BASE_ADDR + 0x005E) | ||
532 | |||
533 | #define KDATA_DSP_RESET_COUNT (KDATA_BASE_ADDR + 0x005F) | ||
534 | #define KDATA_DEBUG_OUTPUT (KDATA_BASE_ADDR + 0x0060) | ||
535 | |||
536 | #define KDATA_KERNEL_ISR_LIST (KDATA_BASE_ADDR + 0x0061) | ||
537 | |||
538 | #define KDATA_KERNEL_ISR_CBSR1 (KDATA_BASE_ADDR + 0x0062) | ||
539 | #define KDATA_KERNEL_ISR_CBER1 (KDATA_BASE_ADDR + 0x0063) | ||
540 | #define KDATA_KERNEL_ISR_CBCR (KDATA_BASE_ADDR + 0x0064) | ||
541 | #define KDATA_KERNEL_ISR_AR0 (KDATA_BASE_ADDR + 0x0065) | ||
542 | #define KDATA_KERNEL_ISR_AR1 (KDATA_BASE_ADDR + 0x0066) | ||
543 | #define KDATA_KERNEL_ISR_AR2 (KDATA_BASE_ADDR + 0x0067) | ||
544 | #define KDATA_KERNEL_ISR_AR3 (KDATA_BASE_ADDR + 0x0068) | ||
545 | #define KDATA_KERNEL_ISR_AR4 (KDATA_BASE_ADDR + 0x0069) | ||
546 | #define KDATA_KERNEL_ISR_AR5 (KDATA_BASE_ADDR + 0x006A) | ||
547 | #define KDATA_KERNEL_ISR_BRCR (KDATA_BASE_ADDR + 0x006B) | ||
548 | #define KDATA_KERNEL_ISR_PASR (KDATA_BASE_ADDR + 0x006C) | ||
549 | #define KDATA_KERNEL_ISR_PAER (KDATA_BASE_ADDR + 0x006D) | ||
550 | |||
551 | #define KDATA_CLIENT_SCRATCH0 (KDATA_BASE_ADDR + 0x006E) | ||
552 | #define KDATA_CLIENT_SCRATCH1 (KDATA_BASE_ADDR + 0x006F) | ||
553 | #define KDATA_KERNEL_SCRATCH (KDATA_BASE_ADDR + 0x0070) | ||
554 | #define KDATA_KERNEL_ISR_SCRATCH (KDATA_BASE_ADDR + 0x0071) | ||
555 | |||
556 | #define KDATA_OUEUE_LEFT (KDATA_BASE_ADDR + 0x0072) | ||
557 | #define KDATA_QUEUE_RIGHT (KDATA_BASE_ADDR + 0x0073) | ||
558 | |||
559 | #define KDATA_ADC1_REQUEST (KDATA_BASE_ADDR + 0x0074) | ||
560 | #define KDATA_ADC2_REQUEST (KDATA_BASE_ADDR + 0x0075) | ||
561 | #define KDATA_CD_REQUEST (KDATA_BASE_ADDR + 0x0076) | ||
562 | #define KDATA_MIC_REQUEST (KDATA_BASE_ADDR + 0x0077) | ||
563 | |||
564 | #define KDATA_ADC1_MIXER_REQUEST (KDATA_BASE_ADDR + 0x0078) | ||
565 | #define KDATA_ADC2_MIXER_REQUEST (KDATA_BASE_ADDR + 0x0079) | ||
566 | #define KDATA_CD_MIXER_REQUEST (KDATA_BASE_ADDR + 0x007A) | ||
567 | #define KDATA_MIC_MIXER_REQUEST (KDATA_BASE_ADDR + 0x007B) | ||
568 | #define KDATA_MIC_SYNC_COUNTER (KDATA_BASE_ADDR + 0x007C) | ||
569 | |||
570 | /* | ||
571 | * second 'segment' (?) reserved for mixer | ||
572 | * buffers.. | ||
573 | */ | ||
574 | |||
575 | #define KDATA_MIXER_WORD0 (KDATA_BASE_ADDR2 + 0x0000) | ||
576 | #define KDATA_MIXER_WORD1 (KDATA_BASE_ADDR2 + 0x0001) | ||
577 | #define KDATA_MIXER_WORD2 (KDATA_BASE_ADDR2 + 0x0002) | ||
578 | #define KDATA_MIXER_WORD3 (KDATA_BASE_ADDR2 + 0x0003) | ||
579 | #define KDATA_MIXER_WORD4 (KDATA_BASE_ADDR2 + 0x0004) | ||
580 | #define KDATA_MIXER_WORD5 (KDATA_BASE_ADDR2 + 0x0005) | ||
581 | #define KDATA_MIXER_WORD6 (KDATA_BASE_ADDR2 + 0x0006) | ||
582 | #define KDATA_MIXER_WORD7 (KDATA_BASE_ADDR2 + 0x0007) | ||
583 | #define KDATA_MIXER_WORD8 (KDATA_BASE_ADDR2 + 0x0008) | ||
584 | #define KDATA_MIXER_WORD9 (KDATA_BASE_ADDR2 + 0x0009) | ||
585 | #define KDATA_MIXER_WORDA (KDATA_BASE_ADDR2 + 0x000A) | ||
586 | #define KDATA_MIXER_WORDB (KDATA_BASE_ADDR2 + 0x000B) | ||
587 | #define KDATA_MIXER_WORDC (KDATA_BASE_ADDR2 + 0x000C) | ||
588 | #define KDATA_MIXER_WORDD (KDATA_BASE_ADDR2 + 0x000D) | ||
589 | #define KDATA_MIXER_WORDE (KDATA_BASE_ADDR2 + 0x000E) | ||
590 | #define KDATA_MIXER_WORDF (KDATA_BASE_ADDR2 + 0x000F) | ||
591 | |||
592 | #define KDATA_MIXER_XFER0 (KDATA_BASE_ADDR2 + 0x0010) | ||
593 | #define KDATA_MIXER_XFER1 (KDATA_BASE_ADDR2 + 0x0011) | ||
594 | #define KDATA_MIXER_XFER2 (KDATA_BASE_ADDR2 + 0x0012) | ||
595 | #define KDATA_MIXER_XFER3 (KDATA_BASE_ADDR2 + 0x0013) | ||
596 | #define KDATA_MIXER_XFER4 (KDATA_BASE_ADDR2 + 0x0014) | ||
597 | #define KDATA_MIXER_XFER5 (KDATA_BASE_ADDR2 + 0x0015) | ||
598 | #define KDATA_MIXER_XFER6 (KDATA_BASE_ADDR2 + 0x0016) | ||
599 | #define KDATA_MIXER_XFER7 (KDATA_BASE_ADDR2 + 0x0017) | ||
600 | #define KDATA_MIXER_XFER8 (KDATA_BASE_ADDR2 + 0x0018) | ||
601 | #define KDATA_MIXER_XFER9 (KDATA_BASE_ADDR2 + 0x0019) | ||
602 | #define KDATA_MIXER_XFER_ENDMARK (KDATA_BASE_ADDR2 + 0x001A) | ||
603 | |||
604 | #define KDATA_MIXER_TASK_NUMBER (KDATA_BASE_ADDR2 + 0x001B) | ||
605 | #define KDATA_CURRENT_MIXER (KDATA_BASE_ADDR2 + 0x001C) | ||
606 | #define KDATA_MIXER_ACTIVE (KDATA_BASE_ADDR2 + 0x001D) | ||
607 | #define KDATA_MIXER_BANK_STATUS (KDATA_BASE_ADDR2 + 0x001E) | ||
608 | #define KDATA_DAC_LEFT_VOLUME (KDATA_BASE_ADDR2 + 0x001F) | ||
609 | #define KDATA_DAC_RIGHT_VOLUME (KDATA_BASE_ADDR2 + 0x0020) | ||
610 | |||
611 | #define MAX_INSTANCE_MINISRC (KDATA_INSTANCE_MINISRC_ENDMARK - KDATA_INSTANCE0_MINISRC) | ||
612 | #define MAX_VIRTUAL_DMA_CHANNELS (KDATA_DMA_XFER_ENDMARK - KDATA_DMA_XFER0) | ||
613 | #define MAX_VIRTUAL_MIXER_CHANNELS (KDATA_MIXER_XFER_ENDMARK - KDATA_MIXER_XFER0) | ||
614 | #define MAX_VIRTUAL_ADC1_CHANNELS (KDATA_ADC1_XFER_ENDMARK - KDATA_ADC1_XFER0) | ||
615 | |||
616 | /* | ||
617 | * client data area offsets | ||
618 | */ | ||
619 | #define CDATA_INSTANCE_READY 0x00 | ||
620 | |||
621 | #define CDATA_HOST_SRC_ADDRL 0x01 | ||
622 | #define CDATA_HOST_SRC_ADDRH 0x02 | ||
623 | #define CDATA_HOST_SRC_END_PLUS_1L 0x03 | ||
624 | #define CDATA_HOST_SRC_END_PLUS_1H 0x04 | ||
625 | #define CDATA_HOST_SRC_CURRENTL 0x05 | ||
626 | #define CDATA_HOST_SRC_CURRENTH 0x06 | ||
627 | |||
628 | #define CDATA_IN_BUF_CONNECT 0x07 | ||
629 | #define CDATA_OUT_BUF_CONNECT 0x08 | ||
630 | |||
631 | #define CDATA_IN_BUF_BEGIN 0x09 | ||
632 | #define CDATA_IN_BUF_END_PLUS_1 0x0A | ||
633 | #define CDATA_IN_BUF_HEAD 0x0B | ||
634 | #define CDATA_IN_BUF_TAIL 0x0C | ||
635 | #define CDATA_OUT_BUF_BEGIN 0x0D | ||
636 | #define CDATA_OUT_BUF_END_PLUS_1 0x0E | ||
637 | #define CDATA_OUT_BUF_HEAD 0x0F | ||
638 | #define CDATA_OUT_BUF_TAIL 0x10 | ||
639 | |||
640 | #define CDATA_DMA_CONTROL 0x11 | ||
641 | #define CDATA_RESERVED 0x12 | ||
642 | |||
643 | #define CDATA_FREQUENCY 0x13 | ||
644 | #define CDATA_LEFT_VOLUME 0x14 | ||
645 | #define CDATA_RIGHT_VOLUME 0x15 | ||
646 | #define CDATA_LEFT_SUR_VOL 0x16 | ||
647 | #define CDATA_RIGHT_SUR_VOL 0x17 | ||
648 | |||
649 | #define CDATA_HEADER_LEN 0x18 | ||
650 | |||
651 | #define SRC3_DIRECTION_OFFSET CDATA_HEADER_LEN | ||
652 | #define SRC3_MODE_OFFSET (CDATA_HEADER_LEN + 1) | ||
653 | #define SRC3_WORD_LENGTH_OFFSET (CDATA_HEADER_LEN + 2) | ||
654 | #define SRC3_PARAMETER_OFFSET (CDATA_HEADER_LEN + 3) | ||
655 | #define SRC3_COEFF_ADDR_OFFSET (CDATA_HEADER_LEN + 8) | ||
656 | #define SRC3_FILTAP_ADDR_OFFSET (CDATA_HEADER_LEN + 10) | ||
657 | #define SRC3_TEMP_INBUF_ADDR_OFFSET (CDATA_HEADER_LEN + 16) | ||
658 | #define SRC3_TEMP_OUTBUF_ADDR_OFFSET (CDATA_HEADER_LEN + 17) | ||
659 | |||
660 | #define MINISRC_IN_BUFFER_SIZE ( 0x50 * 2 ) | ||
661 | #define MINISRC_OUT_BUFFER_SIZE ( 0x50 * 2 * 2) | ||
662 | #define MINISRC_OUT_BUFFER_SIZE ( 0x50 * 2 * 2) | ||
663 | #define MINISRC_TMP_BUFFER_SIZE ( 112 + ( MINISRC_BIQUAD_STAGE * 3 + 4 ) * 2 * 2 ) | ||
664 | #define MINISRC_BIQUAD_STAGE 2 | ||
665 | #define MINISRC_COEF_LOC 0X175 | ||
666 | |||
667 | #define DMACONTROL_BLOCK_MASK 0x000F | ||
668 | #define DMAC_BLOCK0_SELECTOR 0x0000 | ||
669 | #define DMAC_BLOCK1_SELECTOR 0x0001 | ||
670 | #define DMAC_BLOCK2_SELECTOR 0x0002 | ||
671 | #define DMAC_BLOCK3_SELECTOR 0x0003 | ||
672 | #define DMAC_BLOCK4_SELECTOR 0x0004 | ||
673 | #define DMAC_BLOCK5_SELECTOR 0x0005 | ||
674 | #define DMAC_BLOCK6_SELECTOR 0x0006 | ||
675 | #define DMAC_BLOCK7_SELECTOR 0x0007 | ||
676 | #define DMAC_BLOCK8_SELECTOR 0x0008 | ||
677 | #define DMAC_BLOCK9_SELECTOR 0x0009 | ||
678 | #define DMAC_BLOCKA_SELECTOR 0x000A | ||
679 | #define DMAC_BLOCKB_SELECTOR 0x000B | ||
680 | #define DMAC_BLOCKC_SELECTOR 0x000C | ||
681 | #define DMAC_BLOCKD_SELECTOR 0x000D | ||
682 | #define DMAC_BLOCKE_SELECTOR 0x000E | ||
683 | #define DMAC_BLOCKF_SELECTOR 0x000F | ||
684 | #define DMACONTROL_PAGE_MASK 0x00F0 | ||
685 | #define DMAC_PAGE0_SELECTOR 0x0030 | ||
686 | #define DMAC_PAGE1_SELECTOR 0x0020 | ||
687 | #define DMAC_PAGE2_SELECTOR 0x0010 | ||
688 | #define DMAC_PAGE3_SELECTOR 0x0000 | ||
689 | #define DMACONTROL_AUTOREPEAT 0x1000 | ||
690 | #define DMACONTROL_STOPPED 0x2000 | ||
691 | #define DMACONTROL_DIRECTION 0x0100 | ||
692 | |||
693 | |||
694 | /* | ||
695 | * DSP Code images | ||
696 | */ | ||
697 | |||
698 | static u16 assp_kernel_image[] = { | ||
699 | 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, | ||
700 | 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, | ||
701 | 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, | ||
702 | 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x0063, 0x7980, 0x006B, 0x7980, 0x03B4, 0x7980, 0x03B4, | ||
703 | 0xBF80, 0x2C7C, 0x8806, 0x8804, 0xBE40, 0xBC20, 0xAE09, 0x1000, 0xAE0A, 0x0001, 0x6938, 0xEB08, | ||
704 | 0x0053, 0x695A, 0xEB08, 0x00D6, 0x0009, 0x8B88, 0x6980, 0xE388, 0x0036, 0xBE30, 0xBC20, 0x6909, | ||
705 | 0xB801, 0x9009, 0xBE41, 0xBE41, 0x6928, 0xEB88, 0x0078, 0xBE41, 0xBE40, 0x7980, 0x0038, 0xBE41, | ||
706 | 0xBE41, 0x903A, 0x6938, 0xE308, 0x0056, 0x903A, 0xBE41, 0xBE40, 0xEF00, 0x903A, 0x6939, 0xE308, | ||
707 | 0x005E, 0x903A, 0xEF00, 0x690B, 0x660C, 0xEF8C, 0x690A, 0x660C, 0x620B, 0x6609, 0xEF00, 0x6910, | ||
708 | 0x660F, 0xEF04, 0xE388, 0x0075, 0x690E, 0x660F, 0x6210, 0x660D, 0xEF00, 0x690E, 0x660D, 0xEF00, | ||
709 | 0xAE70, 0x0001, 0xBC20, 0xAE27, 0x0001, 0x6939, 0xEB08, 0x005D, 0x6926, 0xB801, 0x9026, 0x0026, | ||
710 | 0x8B88, 0x6980, 0xE388, 0x00CB, 0x9028, 0x0D28, 0x4211, 0xE100, 0x007A, 0x4711, 0xE100, 0x00A0, | ||
711 | 0x7A80, 0x0063, 0xB811, 0x660A, 0x6209, 0xE304, 0x007A, 0x0C0B, 0x4005, 0x100A, 0xBA01, 0x9012, | ||
712 | 0x0C12, 0x4002, 0x7980, 0x00AF, 0x7A80, 0x006B, 0xBE02, 0x620E, 0x660D, 0xBA10, 0xE344, 0x007A, | ||
713 | 0x0C10, 0x4005, 0x100E, 0xBA01, 0x9012, 0x0C12, 0x4002, 0x1003, 0xBA02, 0x9012, 0x0C12, 0x4000, | ||
714 | 0x1003, 0xE388, 0x00BA, 0x1004, 0x7980, 0x00BC, 0x1004, 0xBA01, 0x9012, 0x0C12, 0x4001, 0x0C05, | ||
715 | 0x4003, 0x0C06, 0x4004, 0x1011, 0xBFB0, 0x01FF, 0x9012, 0x0C12, 0x4006, 0xBC20, 0xEF00, 0xAE26, | ||
716 | 0x1028, 0x6970, 0xBFD0, 0x0001, 0x9070, 0xE388, 0x007A, 0xAE28, 0x0000, 0xEF00, 0xAE70, 0x0300, | ||
717 | 0x0C70, 0xB00C, 0xAE5A, 0x0000, 0xEF00, 0x7A80, 0x038A, 0x697F, 0xB801, 0x907F, 0x0056, 0x8B88, | ||
718 | 0x0CA0, 0xB008, 0xAF71, 0xB000, 0x4E71, 0xE200, 0x00F3, 0xAE56, 0x1057, 0x0056, 0x0CA0, 0xB008, | ||
719 | 0x8056, 0x7980, 0x03A1, 0x0810, 0xBFA0, 0x1059, 0xE304, 0x03A1, 0x8056, 0x7980, 0x03A1, 0x7A80, | ||
720 | 0x038A, 0xBF01, 0xBE43, 0xBE59, 0x907C, 0x6937, 0xE388, 0x010D, 0xBA01, 0xE308, 0x010C, 0xAE71, | ||
721 | 0x0004, 0x0C71, 0x5000, 0x6936, 0x9037, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, 0xBF0A, | ||
722 | 0x0560, 0xF500, 0xBF0A, 0x0520, 0xB900, 0xBB17, 0x90A0, 0x6917, 0xE388, 0x0148, 0x0D17, 0xE100, | ||
723 | 0x0127, 0xBF0C, 0x0578, 0xBF0D, 0x057C, 0x7980, 0x012B, 0xBF0C, 0x0538, 0xBF0D, 0x053C, 0x6900, | ||
724 | 0xE308, 0x0135, 0x8B8C, 0xBE59, 0xBB07, 0x90A0, 0xBC20, 0x7980, 0x0157, 0x030C, 0x8B8B, 0xB903, | ||
725 | 0x8809, 0xBEC6, 0x013E, 0x69AC, 0x90AB, 0x69AD, 0x90AB, 0x0813, 0x660A, 0xE344, 0x0144, 0x0309, | ||
726 | 0x830C, 0xBC20, 0x7980, 0x0157, 0x6955, 0xE388, 0x0157, 0x7C38, 0xBF0B, 0x0578, 0xF500, 0xBF0B, | ||
727 | 0x0538, 0xB907, 0x8809, 0xBEC6, 0x0156, 0x10AB, 0x90AA, 0x6974, 0xE388, 0x0163, 0xAE72, 0x0540, | ||
728 | 0xF500, 0xAE72, 0x0500, 0xAE61, 0x103B, 0x7A80, 0x02F6, 0x6978, 0xE388, 0x0182, 0x8B8C, 0xBF0C, | ||
729 | 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA20, 0x8812, 0x733D, 0x7A80, 0x0380, 0x733E, 0x7A80, 0x0380, | ||
730 | 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA2C, 0x8812, 0x733F, 0x7A80, 0x0380, 0x7340, | ||
731 | 0x7A80, 0x0380, 0x6975, 0xE388, 0x018E, 0xAE72, 0x0548, 0xF500, 0xAE72, 0x0508, 0xAE61, 0x1041, | ||
732 | 0x7A80, 0x02F6, 0x6979, 0xE388, 0x01AD, 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA18, | ||
733 | 0x8812, 0x7343, 0x7A80, 0x0380, 0x7344, 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, | ||
734 | 0x0814, 0xBA24, 0x8812, 0x7345, 0x7A80, 0x0380, 0x7346, 0x7A80, 0x0380, 0x6976, 0xE388, 0x01B9, | ||
735 | 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x1047, 0x7A80, 0x02F6, 0x697A, 0xE388, 0x01D8, | ||
736 | 0x8B8C, 0xBF0C, 0x0560, 0xE500, 0x7C40, 0x0814, 0xBA08, 0x8812, 0x7349, 0x7A80, 0x0380, 0x734A, | ||
737 | 0x7A80, 0x0380, 0x8B8C, 0xBF0C, 0x056C, 0xE500, 0x7C40, 0x0814, 0xBA14, 0x8812, 0x734B, 0x7A80, | ||
738 | 0x0380, 0x734C, 0x7A80, 0x0380, 0xBC21, 0xAE1C, 0x1090, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, | ||
739 | 0x0812, 0xB804, 0x8813, 0x8B8D, 0xBF0D, 0x056C, 0xE500, 0x7C40, 0x0815, 0xB804, 0x8811, 0x7A80, | ||
740 | 0x034A, 0x8B8A, 0xBF0A, 0x0560, 0xE500, 0x7C40, 0x731F, 0xB903, 0x8809, 0xBEC6, 0x01F9, 0x548A, | ||
741 | 0xBE03, 0x98A0, 0x7320, 0xB903, 0x8809, 0xBEC6, 0x0201, 0x548A, 0xBE03, 0x98A0, 0x1F20, 0x2F1F, | ||
742 | 0x9826, 0xBC20, 0x6935, 0xE388, 0x03A1, 0x6933, 0xB801, 0x9033, 0xBFA0, 0x02EE, 0xE308, 0x03A1, | ||
743 | 0x9033, 0xBF00, 0x6951, 0xE388, 0x021F, 0x7334, 0xBE80, 0x5760, 0xBE03, 0x9F7E, 0xBE59, 0x9034, | ||
744 | 0x697E, 0x0D51, 0x9013, 0xBC20, 0x695C, 0xE388, 0x03A1, 0x735E, 0xBE80, 0x5760, 0xBE03, 0x9F7E, | ||
745 | 0xBE59, 0x905E, 0x697E, 0x0D5C, 0x9013, 0x7980, 0x03A1, 0x7A80, 0x038A, 0xBF01, 0xBE43, 0x6977, | ||
746 | 0xE388, 0x024E, 0xAE61, 0x104D, 0x0061, 0x8B88, 0x6980, 0xE388, 0x024E, 0x9071, 0x0D71, 0x000B, | ||
747 | 0xAFA0, 0x8010, 0xAFA0, 0x8010, 0x0810, 0x660A, 0xE308, 0x0249, 0x0009, 0x0810, 0x660C, 0xE388, | ||
748 | 0x024E, 0x800B, 0xBC20, 0x697B, 0xE388, 0x03A1, 0xBF0A, 0x109E, 0x8B8A, 0xAF80, 0x8014, 0x4C80, | ||
749 | 0xE100, 0x0266, 0x697C, 0xBF90, 0x0560, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0564, 0x9073, 0x0473, | ||
750 | 0x7980, 0x0270, 0x697C, 0xBF90, 0x0520, 0x9072, 0x0372, 0x697C, 0xBF90, 0x0524, 0x9073, 0x0473, | ||
751 | 0x697C, 0xB801, 0x907C, 0xBF0A, 0x10FD, 0x8B8A, 0xAF80, 0x8010, 0x734F, 0x548A, 0xBE03, 0x9880, | ||
752 | 0xBC21, 0x7326, 0x548B, 0xBE03, 0x618B, 0x988C, 0xBE03, 0x6180, 0x9880, 0x7980, 0x03A1, 0x7A80, | ||
753 | 0x038A, 0x0D28, 0x4711, 0xE100, 0x02BE, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, 0x02B6, | ||
754 | 0xBFA0, 0x0800, 0xE388, 0x02B2, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02A3, 0x6909, | ||
755 | 0x900B, 0x7980, 0x02A5, 0xAF0B, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, 0x02ED, | ||
756 | 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x6909, 0x900B, 0x7980, 0x02B8, 0xAF0B, 0x4005, | ||
757 | 0xAF05, 0x4003, 0xAF06, 0x4004, 0x7980, 0x02ED, 0xAF12, 0x4006, 0x6912, 0xBFB0, 0x0C00, 0xE388, | ||
758 | 0x02E7, 0xBFA0, 0x0800, 0xE388, 0x02E3, 0x6912, 0xBFB0, 0x0C00, 0xBFA0, 0x0400, 0xE388, 0x02D4, | ||
759 | 0x690D, 0x9010, 0x7980, 0x02D6, 0xAF10, 0x4005, 0x6901, 0x9005, 0x6902, 0x9006, 0x4311, 0xE100, | ||
760 | 0x02ED, 0x6911, 0xBFC0, 0x2000, 0x9011, 0x7980, 0x02ED, 0x690D, 0x9010, 0x7980, 0x02E9, 0xAF10, | ||
761 | 0x4005, 0xAF05, 0x4003, 0xAF06, 0x4004, 0xBC20, 0x6970, 0x9071, 0x7A80, 0x0078, 0x6971, 0x9070, | ||
762 | 0x7980, 0x03A1, 0xBC20, 0x0361, 0x8B8B, 0x6980, 0xEF88, 0x0272, 0x0372, 0x7804, 0x9071, 0x0D71, | ||
763 | 0x8B8A, 0x000B, 0xB903, 0x8809, 0xBEC6, 0x0309, 0x69A8, 0x90AB, 0x69A8, 0x90AA, 0x0810, 0x660A, | ||
764 | 0xE344, 0x030F, 0x0009, 0x0810, 0x660C, 0xE388, 0x0314, 0x800B, 0xBC20, 0x6961, 0xB801, 0x9061, | ||
765 | 0x7980, 0x02F7, 0x7A80, 0x038A, 0x5D35, 0x0001, 0x6934, 0xB801, 0x9034, 0xBF0A, 0x109E, 0x8B8A, | ||
766 | 0xAF80, 0x8014, 0x4880, 0xAE72, 0x0550, 0xF500, 0xAE72, 0x0510, 0xAE61, 0x1051, 0x7A80, 0x02F6, | ||
767 | 0x7980, 0x03A1, 0x7A80, 0x038A, 0x5D35, 0x0002, 0x695E, 0xB801, 0x905E, 0xBF0A, 0x109E, 0x8B8A, | ||
768 | 0xAF80, 0x8014, 0x4780, 0xAE72, 0x0558, 0xF500, 0xAE72, 0x0518, 0xAE61, 0x105C, 0x7A80, 0x02F6, | ||
769 | 0x7980, 0x03A1, 0x001C, 0x8B88, 0x6980, 0xEF88, 0x901D, 0x0D1D, 0x100F, 0x6610, 0xE38C, 0x0358, | ||
770 | 0x690E, 0x6610, 0x620F, 0x660D, 0xBA0F, 0xE301, 0x037A, 0x0410, 0x8B8A, 0xB903, 0x8809, 0xBEC6, | ||
771 | 0x036C, 0x6A8C, 0x61AA, 0x98AB, 0x6A8C, 0x61AB, 0x98AD, 0x6A8C, 0x61AD, 0x98A9, 0x6A8C, 0x61A9, | ||
772 | 0x98AA, 0x7C04, 0x8B8B, 0x7C04, 0x8B8D, 0x7C04, 0x8B89, 0x7C04, 0x0814, 0x660E, 0xE308, 0x0379, | ||
773 | 0x040D, 0x8410, 0xBC21, 0x691C, 0xB801, 0x901C, 0x7980, 0x034A, 0xB903, 0x8809, 0x8B8A, 0xBEC6, | ||
774 | 0x0388, 0x54AC, 0xBE03, 0x618C, 0x98AA, 0xEF00, 0xBC20, 0xBE46, 0x0809, 0x906B, 0x080A, 0x906C, | ||
775 | 0x080B, 0x906D, 0x081A, 0x9062, 0x081B, 0x9063, 0x081E, 0x9064, 0xBE59, 0x881E, 0x8065, 0x8166, | ||
776 | 0x8267, 0x8368, 0x8469, 0x856A, 0xEF00, 0xBC20, 0x696B, 0x8809, 0x696C, 0x880A, 0x696D, 0x880B, | ||
777 | 0x6962, 0x881A, 0x6963, 0x881B, 0x6964, 0x881E, 0x0065, 0x0166, 0x0267, 0x0368, 0x0469, 0x056A, | ||
778 | 0xBE3A, | ||
779 | }; | ||
780 | |||
781 | /* | ||
782 | * Mini sample rate converter code image | ||
783 | * that is to be loaded at 0x400 on the DSP. | ||
784 | */ | ||
785 | static u16 assp_minisrc_image[] = { | ||
786 | |||
787 | 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, | ||
788 | 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, | ||
789 | 0x7A80, 0x002A, 0xBE40, 0x3029, 0xEFCC, 0xBE41, 0x7A80, 0x0028, 0xBE40, 0x3028, 0xEFCC, 0x6907, | ||
790 | 0xE308, 0x042A, 0x6909, 0x902C, 0x7980, 0x042C, 0x690D, 0x902C, 0x1009, 0x881A, 0x100A, 0xBA01, | ||
791 | 0x881B, 0x100D, 0x881C, 0x100E, 0xBA01, 0x881D, 0xBF80, 0x00ED, 0x881E, 0x050C, 0x0124, 0xB904, | ||
792 | 0x9027, 0x6918, 0xE308, 0x04B3, 0x902D, 0x6913, 0xBFA0, 0x7598, 0xF704, 0xAE2D, 0x00FF, 0x8B8D, | ||
793 | 0x6919, 0xE308, 0x0463, 0x691A, 0xE308, 0x0456, 0xB907, 0x8809, 0xBEC6, 0x0453, 0x10A9, 0x90AD, | ||
794 | 0x7980, 0x047C, 0xB903, 0x8809, 0xBEC6, 0x0460, 0x1889, 0x6C22, 0x90AD, 0x10A9, 0x6E23, 0x6C22, | ||
795 | 0x90AD, 0x7980, 0x047C, 0x101A, 0xE308, 0x046F, 0xB903, 0x8809, 0xBEC6, 0x046C, 0x10A9, 0x90A0, | ||
796 | 0x90AD, 0x7980, 0x047C, 0xB901, 0x8809, 0xBEC6, 0x047B, 0x1889, 0x6C22, 0x90A0, 0x90AD, 0x10A9, | ||
797 | 0x6E23, 0x6C22, 0x90A0, 0x90AD, 0x692D, 0xE308, 0x049C, 0x0124, 0xB703, 0xB902, 0x8818, 0x8B89, | ||
798 | 0x022C, 0x108A, 0x7C04, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99A0, | ||
799 | 0x108A, 0x90A0, 0x692B, 0x881F, 0x7E80, 0x055B, 0x692A, 0x8809, 0x8B89, 0x99AF, 0x7B99, 0x0484, | ||
800 | 0x0124, 0x060F, 0x101B, 0x2013, 0x901B, 0xBFA0, 0x7FFF, 0xE344, 0x04AC, 0x901B, 0x8B89, 0x7A80, | ||
801 | 0x051A, 0x6927, 0xBA01, 0x9027, 0x7A80, 0x0523, 0x6927, 0xE308, 0x049E, 0x7980, 0x050F, 0x0624, | ||
802 | 0x1026, 0x2013, 0x9026, 0xBFA0, 0x7FFF, 0xE304, 0x04C0, 0x8B8D, 0x7A80, 0x051A, 0x7980, 0x04B4, | ||
803 | 0x9026, 0x1013, 0x3026, 0x901B, 0x8B8D, 0x7A80, 0x051A, 0x7A80, 0x0523, 0x1027, 0xBA01, 0x9027, | ||
804 | 0xE308, 0x04B4, 0x0124, 0x060F, 0x8B89, 0x691A, 0xE308, 0x04EA, 0x6919, 0xE388, 0x04E0, 0xB903, | ||
805 | 0x8809, 0xBEC6, 0x04DD, 0x1FA0, 0x2FAE, 0x98A9, 0x7980, 0x050F, 0xB901, 0x8818, 0xB907, 0x8809, | ||
806 | 0xBEC6, 0x04E7, 0x10EE, 0x90A9, 0x7980, 0x050F, 0x6919, 0xE308, 0x04FE, 0xB903, 0x8809, 0xBE46, | ||
807 | 0xBEC6, 0x04FA, 0x17A0, 0xBE1E, 0x1FAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0xBE47, | ||
808 | 0x7980, 0x050F, 0xB901, 0x8809, 0xBEC6, 0x050E, 0x16A0, 0x26A0, 0xBFB7, 0xFF00, 0xBE1E, 0x1EA0, | ||
809 | 0x2EAE, 0xBFBF, 0xFF00, 0xBE13, 0xBFDF, 0x8080, 0x99A9, 0x850C, 0x860F, 0x6907, 0xE388, 0x0516, | ||
810 | 0x0D07, 0x8510, 0xBE59, 0x881E, 0xBE4A, 0xEF00, 0x101E, 0x901C, 0x101F, 0x901D, 0x10A0, 0x901E, | ||
811 | 0x10A0, 0x901F, 0xEF00, 0x101E, 0x301C, 0x9020, 0x731B, 0x5420, 0xBE03, 0x9825, 0x1025, 0x201C, | ||
812 | 0x9025, 0x7325, 0x5414, 0xBE03, 0x8B8E, 0x9880, 0x692F, 0xE388, 0x0539, 0xBE59, 0xBB07, 0x6180, | ||
813 | 0x9880, 0x8BA0, 0x101F, 0x301D, 0x9021, 0x731B, 0x5421, 0xBE03, 0x982E, 0x102E, 0x201D, 0x902E, | ||
814 | 0x732E, 0x5415, 0xBE03, 0x9880, 0x692F, 0xE388, 0x054F, 0xBE59, 0xBB07, 0x6180, 0x9880, 0x8BA0, | ||
815 | 0x6918, 0xEF08, 0x7325, 0x5416, 0xBE03, 0x98A0, 0x732E, 0x5417, 0xBE03, 0x98A0, 0xEF00, 0x8BA0, | ||
816 | 0xBEC6, 0x056B, 0xBE59, 0xBB04, 0xAA90, 0xBE04, 0xBE1E, 0x99E0, 0x8BE0, 0x69A0, 0x90D0, 0x69A0, | ||
817 | 0x90D0, 0x081F, 0xB805, 0x881F, 0x8B90, 0x69A0, 0x90D0, 0x69A0, 0x9090, 0x8BD0, 0x8BD8, 0xBE1F, | ||
818 | 0xEF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
819 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||
820 | }; | ||
821 | |||
diff --git a/sound/oss/maui.c b/sound/oss/maui.c deleted file mode 100644 index 317f22589a05..000000000000 --- a/sound/oss/maui.c +++ /dev/null | |||
@@ -1,478 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/maui.c | ||
3 | * | ||
4 | * The low level driver for Turtle Beach Maui and Tropez. | ||
5 | * | ||
6 | * | ||
7 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
8 | * | ||
9 | * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
10 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
11 | * for more info. | ||
12 | * | ||
13 | * Changes: | ||
14 | * Alan Cox General clean up, use kernel IRQ | ||
15 | * system | ||
16 | * Christoph Hellwig Adapted to module_init/module_exit | ||
17 | * Bartlomiej Zolnierkiewicz | ||
18 | * Added __init to download_code() | ||
19 | * | ||
20 | * Status: | ||
21 | * Andrew J. Kroll Tested 06/01/1999 with: | ||
22 | * * OSWF.MOT File Version: 1.15 | ||
23 | * * OSWF.MOT File Dated: 09/12/94 | ||
24 | * * Older versions will cause problems. | ||
25 | */ | ||
26 | |||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/config.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | |||
32 | #define USE_SEQ_MACROS | ||
33 | #define USE_SIMPLE_MACROS | ||
34 | |||
35 | #include "sound_config.h" | ||
36 | #include "sound_firmware.h" | ||
37 | |||
38 | #include "mpu401.h" | ||
39 | |||
40 | static int maui_base = 0x330; | ||
41 | |||
42 | static volatile int irq_ok; | ||
43 | static int *maui_osp; | ||
44 | |||
45 | #define HOST_DATA_PORT (maui_base + 2) | ||
46 | #define HOST_STAT_PORT (maui_base + 3) | ||
47 | #define HOST_CTRL_PORT (maui_base + 3) | ||
48 | |||
49 | #define STAT_TX_INTR 0x40 | ||
50 | #define STAT_TX_AVAIL 0x20 | ||
51 | #define STAT_TX_IENA 0x10 | ||
52 | #define STAT_RX_INTR 0x04 | ||
53 | #define STAT_RX_AVAIL 0x02 | ||
54 | #define STAT_RX_IENA 0x01 | ||
55 | |||
56 | static int (*orig_load_patch)(int dev, int format, const char __user *addr, | ||
57 | int offs, int count, int pmgr_flag) = NULL; | ||
58 | |||
59 | #include "maui_boot.h" | ||
60 | |||
61 | static int maui_wait(int mask) | ||
62 | { | ||
63 | int i; | ||
64 | |||
65 | /* | ||
66 | * Perform a short initial wait without sleeping | ||
67 | */ | ||
68 | |||
69 | for (i = 0; i < 100; i++) | ||
70 | if (inb(HOST_STAT_PORT) & mask) | ||
71 | return 1; | ||
72 | |||
73 | /* | ||
74 | * Wait up to 15 seconds with sleeping | ||
75 | */ | ||
76 | |||
77 | for (i = 0; i < 150; i++) { | ||
78 | if (inb(HOST_STAT_PORT) & mask) | ||
79 | return 1; | ||
80 | current->state = TASK_INTERRUPTIBLE; | ||
81 | schedule_timeout(HZ / 10); | ||
82 | if (signal_pending(current)) | ||
83 | return 0; | ||
84 | } | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int maui_read(void) | ||
89 | { | ||
90 | if (maui_wait(STAT_RX_AVAIL)) | ||
91 | return inb(HOST_DATA_PORT); | ||
92 | return -1; | ||
93 | } | ||
94 | |||
95 | static int maui_write(unsigned char data) | ||
96 | { | ||
97 | if (maui_wait(STAT_TX_AVAIL)) { | ||
98 | outb((data), HOST_DATA_PORT); | ||
99 | return 1; | ||
100 | } | ||
101 | printk(KERN_WARNING "Maui: Write timeout\n"); | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static irqreturn_t mauiintr(int irq, void *dev_id, struct pt_regs *dummy) | ||
106 | { | ||
107 | irq_ok = 1; | ||
108 | return IRQ_HANDLED; | ||
109 | } | ||
110 | |||
111 | static int __init download_code(void) | ||
112 | { | ||
113 | int i, lines = 0; | ||
114 | int eol_seen = 0, done = 0; | ||
115 | int skip = 1; | ||
116 | |||
117 | printk(KERN_INFO "Code download (%d bytes): ", maui_osLen); | ||
118 | |||
119 | for (i = 0; i < maui_osLen; i++) { | ||
120 | if (maui_os[i] != '\r') { | ||
121 | if (!skip || (maui_os[i] == 'S' && (i == 0 || maui_os[i - 1] == '\n'))) { | ||
122 | skip = 0; | ||
123 | |||
124 | if (maui_os[i] == '\n') | ||
125 | eol_seen = skip = 1; | ||
126 | else if (maui_os[i] == 'S') { | ||
127 | if (maui_os[i + 1] == '8') | ||
128 | done = 1; | ||
129 | if (!maui_write(0xF1)) | ||
130 | goto failure; | ||
131 | if (!maui_write('S')) | ||
132 | goto failure; | ||
133 | } else { | ||
134 | if (!maui_write(maui_os[i])) | ||
135 | goto failure; | ||
136 | } | ||
137 | |||
138 | if (eol_seen) { | ||
139 | int c = 0; | ||
140 | int n; | ||
141 | |||
142 | eol_seen = 0; | ||
143 | |||
144 | for (n = 0; n < 2; n++) { | ||
145 | if (maui_wait(STAT_RX_AVAIL)) { | ||
146 | c = inb(HOST_DATA_PORT); | ||
147 | break; | ||
148 | } | ||
149 | } | ||
150 | if (c != 0x80) { | ||
151 | printk("Download not acknowledged\n"); | ||
152 | return 0; | ||
153 | } | ||
154 | else if (!(lines++ % 10)) | ||
155 | printk("."); | ||
156 | |||
157 | if (done) { | ||
158 | printk("\n"); | ||
159 | printk(KERN_INFO "Download complete\n"); | ||
160 | return 1; | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | } | ||
165 | } | ||
166 | |||
167 | failure: | ||
168 | printk("\n"); | ||
169 | printk(KERN_ERR "Download failed!!!\n"); | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int __init maui_init(int irq) | ||
174 | { | ||
175 | unsigned char bits; | ||
176 | |||
177 | switch (irq) { | ||
178 | case 9: | ||
179 | bits = 0x00; | ||
180 | break; | ||
181 | case 5: | ||
182 | bits = 0x08; | ||
183 | break; | ||
184 | case 12: | ||
185 | bits = 0x10; | ||
186 | break; | ||
187 | case 15: | ||
188 | bits = 0x18; | ||
189 | break; | ||
190 | |||
191 | default: | ||
192 | printk(KERN_ERR "Maui: Invalid IRQ %d\n", irq); | ||
193 | return 0; | ||
194 | } | ||
195 | outb((0x00), HOST_CTRL_PORT); /* Reset */ | ||
196 | outb((bits), HOST_DATA_PORT); /* Set the IRQ bits */ | ||
197 | outb((bits | 0x80), HOST_DATA_PORT); /* Set the IRQ bits again? */ | ||
198 | outb((0x80), HOST_CTRL_PORT); /* Leave reset */ | ||
199 | outb((0x80), HOST_CTRL_PORT); /* Leave reset */ | ||
200 | outb((0xD0), HOST_CTRL_PORT); /* Cause interrupt */ | ||
201 | |||
202 | #ifdef CONFIG_SMP | ||
203 | { | ||
204 | int i; | ||
205 | for (i = 0; i < 1000000 && !irq_ok; i++) | ||
206 | ; | ||
207 | if (!irq_ok) | ||
208 | return 0; | ||
209 | } | ||
210 | #endif | ||
211 | outb((0x80), HOST_CTRL_PORT); /* Leave reset */ | ||
212 | |||
213 | printk(KERN_INFO "Turtle Beach Maui initialization\n"); | ||
214 | |||
215 | if (!download_code()) | ||
216 | return 0; | ||
217 | |||
218 | outb((0xE0), HOST_CTRL_PORT); /* Normal operation */ | ||
219 | |||
220 | /* Select mpu401 mode */ | ||
221 | |||
222 | maui_write(0xf0); | ||
223 | maui_write(1); | ||
224 | if (maui_read() != 0x80) { | ||
225 | maui_write(0xf0); | ||
226 | maui_write(1); | ||
227 | if (maui_read() != 0x80) | ||
228 | printk(KERN_ERR "Maui didn't acknowledge set HW mode command\n"); | ||
229 | } | ||
230 | printk(KERN_INFO "Maui initialized OK\n"); | ||
231 | return 1; | ||
232 | } | ||
233 | |||
234 | static int maui_short_wait(int mask) { | ||
235 | int i; | ||
236 | |||
237 | for (i = 0; i < 1000; i++) { | ||
238 | if (inb(HOST_STAT_PORT) & mask) { | ||
239 | return 1; | ||
240 | } | ||
241 | } | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static int maui_load_patch(int dev, int format, const char __user *addr, | ||
246 | int offs, int count, int pmgr_flag) | ||
247 | { | ||
248 | |||
249 | struct sysex_info header; | ||
250 | unsigned long left, src_offs; | ||
251 | int hdr_size = (unsigned long) &header.data[0] - (unsigned long) &header; | ||
252 | int i; | ||
253 | |||
254 | if (format == SYSEX_PATCH) /* Handled by midi_synth.c */ | ||
255 | return orig_load_patch(dev, format, addr, offs, count, pmgr_flag); | ||
256 | |||
257 | if (format != MAUI_PATCH) | ||
258 | { | ||
259 | printk(KERN_WARNING "Maui: Unknown patch format\n"); | ||
260 | } | ||
261 | if (count < hdr_size) { | ||
262 | /* printk("Maui error: Patch header too short\n");*/ | ||
263 | return -EINVAL; | ||
264 | } | ||
265 | count -= hdr_size; | ||
266 | |||
267 | /* | ||
268 | * Copy the header from user space but ignore the first bytes which have | ||
269 | * been transferred already. | ||
270 | */ | ||
271 | |||
272 | if(copy_from_user(&((char *) &header)[offs], &(addr)[offs], hdr_size - offs)) | ||
273 | return -EFAULT; | ||
274 | |||
275 | if (count < header.len) { | ||
276 | printk(KERN_ERR "Maui warning: Host command record too short (%d<%d)\n", count, (int) header.len); | ||
277 | header.len = count; | ||
278 | } | ||
279 | left = header.len; | ||
280 | src_offs = 0; | ||
281 | |||
282 | for (i = 0; i < left; i++) { | ||
283 | unsigned char data; | ||
284 | |||
285 | if(get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[hdr_size + i]))) | ||
286 | return -EFAULT; | ||
287 | if (i == 0 && !(data & 0x80)) | ||
288 | return -EINVAL; | ||
289 | |||
290 | if (maui_write(data) == -1) | ||
291 | return -EIO; | ||
292 | } | ||
293 | |||
294 | if ((i = maui_read()) != 0x80) { | ||
295 | if (i != -1) | ||
296 | printk("Maui: Error status %02x\n", i); | ||
297 | return -EIO; | ||
298 | } | ||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static int __init probe_maui(struct address_info *hw_config) | ||
303 | { | ||
304 | struct resource *ports; | ||
305 | int this_dev; | ||
306 | int i; | ||
307 | int tmp1, tmp2, ret; | ||
308 | |||
309 | ports = request_region(hw_config->io_base, 2, "mpu401"); | ||
310 | if (!ports) | ||
311 | return 0; | ||
312 | |||
313 | if (!request_region(hw_config->io_base + 2, 6, "Maui")) | ||
314 | goto out; | ||
315 | |||
316 | maui_base = hw_config->io_base; | ||
317 | maui_osp = hw_config->osp; | ||
318 | |||
319 | if (request_irq(hw_config->irq, mauiintr, 0, "Maui", NULL) < 0) | ||
320 | goto out2; | ||
321 | |||
322 | /* | ||
323 | * Initialize the processor if necessary | ||
324 | */ | ||
325 | |||
326 | if (maui_osLen > 0) { | ||
327 | if (!(inb(HOST_STAT_PORT) & STAT_TX_AVAIL) || | ||
328 | !maui_write(0x9F) || /* Report firmware version */ | ||
329 | !maui_short_wait(STAT_RX_AVAIL) || | ||
330 | maui_read() == -1 || maui_read() == -1) | ||
331 | if (!maui_init(hw_config->irq)) | ||
332 | goto out3; | ||
333 | } | ||
334 | if (!maui_write(0xCF)) /* Report hardware version */ { | ||
335 | printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n"); | ||
336 | goto out3; | ||
337 | } | ||
338 | if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) { | ||
339 | printk(KERN_ERR "No WaveFront firmware detected (card uninitialized?)\n"); | ||
340 | goto out3; | ||
341 | } | ||
342 | if (tmp1 == 0xff || tmp2 == 0xff) | ||
343 | goto out3; | ||
344 | printk(KERN_DEBUG "WaveFront hardware version %d.%d\n", tmp1, tmp2); | ||
345 | |||
346 | if (!maui_write(0x9F)) /* Report firmware version */ | ||
347 | goto out3; | ||
348 | if ((tmp1 = maui_read()) == -1 || (tmp2 = maui_read()) == -1) | ||
349 | goto out3; | ||
350 | |||
351 | printk(KERN_DEBUG "WaveFront firmware version %d.%d\n", tmp1, tmp2); | ||
352 | |||
353 | if (!maui_write(0x85)) /* Report free DRAM */ | ||
354 | goto out3; | ||
355 | tmp1 = 0; | ||
356 | for (i = 0; i < 4; i++) { | ||
357 | tmp1 |= maui_read() << (7 * i); | ||
358 | } | ||
359 | printk(KERN_DEBUG "Available DRAM %dk\n", tmp1 / 1024); | ||
360 | |||
361 | for (i = 0; i < 1000; i++) | ||
362 | if (probe_mpu401(hw_config, ports)) | ||
363 | break; | ||
364 | |||
365 | ret = probe_mpu401(hw_config, ports); | ||
366 | if (!ret) | ||
367 | goto out3; | ||
368 | |||
369 | conf_printf("Maui", hw_config); | ||
370 | |||
371 | hw_config->irq *= -1; | ||
372 | hw_config->name = "Maui"; | ||
373 | attach_mpu401(hw_config, THIS_MODULE); | ||
374 | |||
375 | if (hw_config->slots[1] != -1) /* The MPU401 driver installed itself */ { | ||
376 | struct synth_operations *synth; | ||
377 | |||
378 | this_dev = hw_config->slots[1]; | ||
379 | |||
380 | /* | ||
381 | * Intercept patch loading calls so that they can be handled | ||
382 | * by the Maui driver. | ||
383 | */ | ||
384 | |||
385 | synth = midi_devs[this_dev]->converter; | ||
386 | if (synth != NULL) { | ||
387 | synth->id = "MAUI"; | ||
388 | orig_load_patch = synth->load_patch; | ||
389 | synth->load_patch = &maui_load_patch; | ||
390 | } else | ||
391 | printk(KERN_ERR "Maui: Can't install patch loader\n"); | ||
392 | } | ||
393 | return 1; | ||
394 | |||
395 | out3: | ||
396 | free_irq(hw_config->irq, NULL); | ||
397 | out2: | ||
398 | release_region(hw_config->io_base + 2, 6); | ||
399 | out: | ||
400 | release_region(hw_config->io_base, 2); | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static void __exit unload_maui(struct address_info *hw_config) | ||
405 | { | ||
406 | int irq = hw_config->irq; | ||
407 | release_region(hw_config->io_base + 2, 6); | ||
408 | unload_mpu401(hw_config); | ||
409 | |||
410 | if (irq < 0) | ||
411 | irq = -irq; | ||
412 | if (irq > 0) | ||
413 | free_irq(irq, NULL); | ||
414 | } | ||
415 | |||
416 | static int fw_load; | ||
417 | |||
418 | static struct address_info cfg; | ||
419 | |||
420 | static int __initdata io = -1; | ||
421 | static int __initdata irq = -1; | ||
422 | |||
423 | module_param(io, int, 0); | ||
424 | module_param(irq, int, 0); | ||
425 | |||
426 | /* | ||
427 | * Install a Maui card. Needs mpu401 loaded already. | ||
428 | */ | ||
429 | |||
430 | static int __init init_maui(void) | ||
431 | { | ||
432 | printk(KERN_INFO "Turtle beach Maui and Tropez driver, Copyright (C) by Hannu Savolainen 1993-1996\n"); | ||
433 | |||
434 | cfg.io_base = io; | ||
435 | cfg.irq = irq; | ||
436 | |||
437 | if (cfg.io_base == -1 || cfg.irq == -1) { | ||
438 | printk(KERN_INFO "maui: irq and io must be set.\n"); | ||
439 | return -EINVAL; | ||
440 | } | ||
441 | |||
442 | if (maui_os == NULL) { | ||
443 | fw_load = 1; | ||
444 | maui_osLen = mod_firmware_load("/etc/sound/oswf.mot", (char **) &maui_os); | ||
445 | } | ||
446 | if (probe_maui(&cfg) == 0) | ||
447 | return -ENODEV; | ||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static void __exit cleanup_maui(void) | ||
453 | { | ||
454 | if (fw_load && maui_os) | ||
455 | vfree(maui_os); | ||
456 | unload_maui(&cfg); | ||
457 | } | ||
458 | |||
459 | module_init(init_maui); | ||
460 | module_exit(cleanup_maui); | ||
461 | |||
462 | #ifndef MODULE | ||
463 | static int __init setup_maui(char *str) | ||
464 | { | ||
465 | /* io, irq */ | ||
466 | int ints[3]; | ||
467 | |||
468 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
469 | |||
470 | io = ints[1]; | ||
471 | irq = ints[2]; | ||
472 | |||
473 | return 1; | ||
474 | } | ||
475 | |||
476 | __setup("maui=", setup_maui); | ||
477 | #endif | ||
478 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c index 321f4c4b5a7b..162d07cc489f 100644 --- a/sound/oss/mpu401.c +++ b/sound/oss/mpu401.c | |||
@@ -432,16 +432,7 @@ static void mpu401_input_loop(struct mpu_config *devc) | |||
432 | devc->m_busy = 0; | 432 | devc->m_busy = 0; |
433 | } | 433 | } |
434 | 434 | ||
435 | int intchk_mpu401(void *dev_id) | 435 | static irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy) |
436 | { | ||
437 | struct mpu_config *devc; | ||
438 | int dev = (int) dev_id; | ||
439 | |||
440 | devc = &dev_conf[dev]; | ||
441 | return input_avail(devc); | ||
442 | } | ||
443 | |||
444 | irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs *dummy) | ||
445 | { | 436 | { |
446 | struct mpu_config *devc; | 437 | struct mpu_config *devc; |
447 | int dev = (int) dev_id; | 438 | int dev = (int) dev_id; |
@@ -1761,8 +1752,6 @@ static int mpu_timer_init(int midi_dev) | |||
1761 | EXPORT_SYMBOL(probe_mpu401); | 1752 | EXPORT_SYMBOL(probe_mpu401); |
1762 | EXPORT_SYMBOL(attach_mpu401); | 1753 | EXPORT_SYMBOL(attach_mpu401); |
1763 | EXPORT_SYMBOL(unload_mpu401); | 1754 | EXPORT_SYMBOL(unload_mpu401); |
1764 | EXPORT_SYMBOL(intchk_mpu401); | ||
1765 | EXPORT_SYMBOL(mpuintr); | ||
1766 | 1755 | ||
1767 | static struct address_info cfg; | 1756 | static struct address_info cfg; |
1768 | 1757 | ||
diff --git a/sound/oss/mpu401.h b/sound/oss/mpu401.h index bdc5bde641e6..84c0e9522ef7 100644 --- a/sound/oss/mpu401.h +++ b/sound/oss/mpu401.h | |||
@@ -10,5 +10,3 @@ int probe_mpu401(struct address_info *hw_config, struct resource *ports); | |||
10 | int attach_mpu401(struct address_info * hw_config, struct module *owner); | 10 | int attach_mpu401(struct address_info * hw_config, struct module *owner); |
11 | void unload_mpu401(struct address_info *hw_info); | 11 | void unload_mpu401(struct address_info *hw_info); |
12 | 12 | ||
13 | int intchk_mpu401(void *dev_id); | ||
14 | irqreturn_t mpuintr(int irq, void *dev_id, struct pt_regs * dummy); | ||
diff --git a/sound/oss/opl3sa.c b/sound/oss/opl3sa.c deleted file mode 100644 index 2535ed0b5fbf..000000000000 --- a/sound/oss/opl3sa.c +++ /dev/null | |||
@@ -1,329 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/opl3sa.c | ||
3 | * | ||
4 | * Low level driver for Yamaha YMF701B aka OPL3-SA chip | ||
5 | * | ||
6 | * | ||
7 | * | ||
8 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
9 | * | ||
10 | * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
11 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
12 | * for more info. | ||
13 | * | ||
14 | * Changes: | ||
15 | * Alan Cox Modularisation | ||
16 | * Christoph Hellwig Adapted to module_init/module_exit | ||
17 | * Arnaldo C. de Melo got rid of attach_uart401 | ||
18 | * | ||
19 | * FIXME: | ||
20 | * Check for install of mpu etc is wrong, should check result of the mss stuff | ||
21 | */ | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | |||
27 | #undef SB_OK | ||
28 | |||
29 | #include "sound_config.h" | ||
30 | |||
31 | #include "ad1848.h" | ||
32 | #include "mpu401.h" | ||
33 | |||
34 | #ifdef SB_OK | ||
35 | #include "sb.h" | ||
36 | static int sb_initialized; | ||
37 | #endif | ||
38 | |||
39 | static DEFINE_SPINLOCK(lock); | ||
40 | |||
41 | static unsigned char opl3sa_read(int addr) | ||
42 | { | ||
43 | unsigned long flags; | ||
44 | unsigned char tmp; | ||
45 | |||
46 | spin_lock_irqsave(&lock,flags); | ||
47 | outb((0x1d), 0xf86); /* password */ | ||
48 | outb(((unsigned char) addr), 0xf86); /* address */ | ||
49 | tmp = inb(0xf87); /* data */ | ||
50 | spin_unlock_irqrestore(&lock,flags); | ||
51 | |||
52 | return tmp; | ||
53 | } | ||
54 | |||
55 | static void opl3sa_write(int addr, int data) | ||
56 | { | ||
57 | unsigned long flags; | ||
58 | |||
59 | spin_lock_irqsave(&lock,flags); | ||
60 | outb((0x1d), 0xf86); /* password */ | ||
61 | outb(((unsigned char) addr), 0xf86); /* address */ | ||
62 | outb(((unsigned char) data), 0xf87); /* data */ | ||
63 | spin_unlock_irqrestore(&lock,flags); | ||
64 | } | ||
65 | |||
66 | static int __init opl3sa_detect(void) | ||
67 | { | ||
68 | int tmp; | ||
69 | |||
70 | if (((tmp = opl3sa_read(0x01)) & 0xc4) != 0x04) | ||
71 | { | ||
72 | DDB(printk("OPL3-SA detect error 1 (%x)\n", opl3sa_read(0x01))); | ||
73 | /* return 0; */ | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * Check that the password feature has any effect | ||
78 | */ | ||
79 | |||
80 | if (inb(0xf87) == tmp) | ||
81 | { | ||
82 | DDB(printk("OPL3-SA detect failed 2 (%x/%x)\n", tmp, inb(0xf87))); | ||
83 | return 0; | ||
84 | } | ||
85 | tmp = (opl3sa_read(0x04) & 0xe0) >> 5; | ||
86 | |||
87 | if (tmp != 0 && tmp != 1) | ||
88 | { | ||
89 | DDB(printk("OPL3-SA detect failed 3 (%d)\n", tmp)); | ||
90 | return 0; | ||
91 | } | ||
92 | DDB(printk("OPL3-SA mode %x detected\n", tmp)); | ||
93 | |||
94 | opl3sa_write(0x01, 0x00); /* Disable MSS */ | ||
95 | opl3sa_write(0x02, 0x00); /* Disable SB */ | ||
96 | opl3sa_write(0x03, 0x00); /* Disable MPU */ | ||
97 | |||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Probe and attach routines for the Windows Sound System mode of | ||
103 | * OPL3-SA | ||
104 | */ | ||
105 | |||
106 | static int __init probe_opl3sa_wss(struct address_info *hw_config, struct resource *ports) | ||
107 | { | ||
108 | unsigned char tmp = 0x24; /* WSS enable */ | ||
109 | |||
110 | /* | ||
111 | * Check if the IO port returns valid signature. The original MS Sound | ||
112 | * system returns 0x04 while some cards (OPL3-SA for example) | ||
113 | * return 0x00. | ||
114 | */ | ||
115 | |||
116 | if (!opl3sa_detect()) | ||
117 | { | ||
118 | printk(KERN_ERR "OSS: OPL3-SA chip not found\n"); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | switch (hw_config->io_base) | ||
123 | { | ||
124 | case 0x530: | ||
125 | tmp |= 0x00; | ||
126 | break; | ||
127 | case 0xe80: | ||
128 | tmp |= 0x08; | ||
129 | break; | ||
130 | case 0xf40: | ||
131 | tmp |= 0x10; | ||
132 | break; | ||
133 | case 0x604: | ||
134 | tmp |= 0x18; | ||
135 | break; | ||
136 | default: | ||
137 | printk(KERN_ERR "OSS: Unsupported OPL3-SA/WSS base %x\n", hw_config->io_base); | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | opl3sa_write(0x01, tmp); /* WSS setup register */ | ||
142 | |||
143 | return probe_ms_sound(hw_config, ports); | ||
144 | } | ||
145 | |||
146 | static void __init attach_opl3sa_wss(struct address_info *hw_config, struct resource *ports) | ||
147 | { | ||
148 | int nm = num_mixers; | ||
149 | |||
150 | /* FIXME */ | ||
151 | attach_ms_sound(hw_config, ports, THIS_MODULE); | ||
152 | if (num_mixers > nm) /* A mixer was installed */ | ||
153 | { | ||
154 | AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD); | ||
155 | AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH); | ||
156 | AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | |||
161 | static int __init probe_opl3sa_mpu(struct address_info *hw_config) | ||
162 | { | ||
163 | unsigned char conf; | ||
164 | static signed char irq_bits[] = { | ||
165 | -1, -1, -1, -1, -1, 1, -1, 2, -1, 3, 4 | ||
166 | }; | ||
167 | |||
168 | if (hw_config->irq > 10) | ||
169 | { | ||
170 | printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq); | ||
171 | return 0; | ||
172 | } | ||
173 | if (irq_bits[hw_config->irq] == -1) | ||
174 | { | ||
175 | printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq); | ||
176 | return 0; | ||
177 | } | ||
178 | switch (hw_config->io_base) | ||
179 | { | ||
180 | case 0x330: | ||
181 | conf = 0x00; | ||
182 | break; | ||
183 | case 0x332: | ||
184 | conf = 0x20; | ||
185 | break; | ||
186 | case 0x334: | ||
187 | conf = 0x40; | ||
188 | break; | ||
189 | case 0x300: | ||
190 | conf = 0x60; | ||
191 | break; | ||
192 | default: | ||
193 | return 0; /* Invalid port */ | ||
194 | } | ||
195 | |||
196 | conf |= 0x83; /* MPU & OPL3 (synth) & game port enable */ | ||
197 | conf |= irq_bits[hw_config->irq] << 2; | ||
198 | |||
199 | opl3sa_write(0x03, conf); | ||
200 | |||
201 | hw_config->name = "OPL3-SA (MPU401)"; | ||
202 | |||
203 | return probe_uart401(hw_config, THIS_MODULE); | ||
204 | } | ||
205 | |||
206 | static void __exit unload_opl3sa_wss(struct address_info *hw_config) | ||
207 | { | ||
208 | int dma2 = hw_config->dma2; | ||
209 | |||
210 | if (dma2 == -1) | ||
211 | dma2 = hw_config->dma; | ||
212 | |||
213 | release_region(0xf86, 2); | ||
214 | release_region(hw_config->io_base, 4); | ||
215 | |||
216 | ad1848_unload(hw_config->io_base + 4, | ||
217 | hw_config->irq, | ||
218 | hw_config->dma, | ||
219 | dma2, | ||
220 | 0); | ||
221 | sound_unload_audiodev(hw_config->slots[0]); | ||
222 | } | ||
223 | |||
224 | static inline void __exit unload_opl3sa_mpu(struct address_info *hw_config) | ||
225 | { | ||
226 | unload_uart401(hw_config); | ||
227 | } | ||
228 | |||
229 | #ifdef SB_OK | ||
230 | static inline void __exit unload_opl3sa_sb(struct address_info *hw_config) | ||
231 | { | ||
232 | sb_dsp_unload(hw_config); | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | static int found_mpu; | ||
237 | |||
238 | static struct address_info cfg; | ||
239 | static struct address_info cfg_mpu; | ||
240 | |||
241 | static int __initdata io = -1; | ||
242 | static int __initdata irq = -1; | ||
243 | static int __initdata dma = -1; | ||
244 | static int __initdata dma2 = -1; | ||
245 | static int __initdata mpu_io = -1; | ||
246 | static int __initdata mpu_irq = -1; | ||
247 | |||
248 | module_param(io, int, 0); | ||
249 | module_param(irq, int, 0); | ||
250 | module_param(dma, int, 0); | ||
251 | module_param(dma2, int, 0); | ||
252 | module_param(mpu_io, int, 0); | ||
253 | module_param(mpu_irq, int, 0); | ||
254 | |||
255 | static int __init init_opl3sa(void) | ||
256 | { | ||
257 | struct resource *ports; | ||
258 | if (io == -1 || irq == -1 || dma == -1) { | ||
259 | printk(KERN_ERR "opl3sa: dma, irq and io must be set.\n"); | ||
260 | return -EINVAL; | ||
261 | } | ||
262 | |||
263 | cfg.io_base = io; | ||
264 | cfg.irq = irq; | ||
265 | cfg.dma = dma; | ||
266 | cfg.dma2 = dma2; | ||
267 | |||
268 | cfg_mpu.io_base = mpu_io; | ||
269 | cfg_mpu.irq = mpu_irq; | ||
270 | |||
271 | ports = request_region(io + 4, 4, "ad1848"); | ||
272 | if (!ports) | ||
273 | return -EBUSY; | ||
274 | |||
275 | if (!request_region(0xf86, 2, "OPL3-SA"))/* Control port is busy */ { | ||
276 | release_region(io + 4, 4); | ||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | if (!request_region(io, 4, "WSS config")) { | ||
281 | release_region(0x86, 2); | ||
282 | release_region(io + 4, 4); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | if (probe_opl3sa_wss(&cfg, ports) == 0) { | ||
287 | release_region(0xf86, 2); | ||
288 | release_region(io, 4); | ||
289 | release_region(io + 4, 4); | ||
290 | return -ENODEV; | ||
291 | } | ||
292 | |||
293 | found_mpu=probe_opl3sa_mpu(&cfg_mpu); | ||
294 | |||
295 | attach_opl3sa_wss(&cfg, ports); | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static void __exit cleanup_opl3sa(void) | ||
300 | { | ||
301 | if(found_mpu) | ||
302 | unload_opl3sa_mpu(&cfg_mpu); | ||
303 | unload_opl3sa_wss(&cfg); | ||
304 | } | ||
305 | |||
306 | module_init(init_opl3sa); | ||
307 | module_exit(cleanup_opl3sa); | ||
308 | |||
309 | #ifndef MODULE | ||
310 | static int __init setup_opl3sa(char *str) | ||
311 | { | ||
312 | /* io, irq, dma, dma2, mpu_io, mpu_irq */ | ||
313 | int ints[7]; | ||
314 | |||
315 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
316 | |||
317 | io = ints[1]; | ||
318 | irq = ints[2]; | ||
319 | dma = ints[3]; | ||
320 | dma2 = ints[4]; | ||
321 | mpu_io = ints[5]; | ||
322 | mpu_irq = ints[6]; | ||
323 | |||
324 | return 1; | ||
325 | } | ||
326 | |||
327 | __setup("opl3sa=", setup_opl3sa); | ||
328 | #endif | ||
329 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c deleted file mode 100644 index f17d25b6f836..000000000000 --- a/sound/oss/rme96xx.c +++ /dev/null | |||
@@ -1,1857 +0,0 @@ | |||
1 | /* (C) 2000 Guenter Geiger <geiger@debian.org> | ||
2 | with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at> | ||
3 | based on es1370.c | ||
4 | |||
5 | |||
6 | |||
7 | * 10 Jan 2001: 0.1 initial version | ||
8 | * 19 Jan 2001: 0.2 fixed bug in select() | ||
9 | * 27 Apr 2001: 0.3 more than one card usable | ||
10 | * 11 May 2001: 0.4 fixed for SMP, included into kernel source tree | ||
11 | * 17 May 2001: 0.5 draining code didn't work on new cards | ||
12 | * 18 May 2001: 0.6 remove synchronize_irq() call | ||
13 | * 17 Jul 2001: 0.7 updated xrmectrl to make it work for newer cards | ||
14 | * 2 feb 2002: 0.8 fixed pci device handling, see below for patches from Heiko (Thanks!) | ||
15 | Marcus Meissner <Marcus.Meissner@caldera.de> | ||
16 | |||
17 | Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de> | ||
18 | HP20020108 fixed handling of "large" read() | ||
19 | HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c | ||
20 | HP20020118 made mixer ioctl and handling of devices>1 more safe | ||
21 | HP20020201 fixed handling of "large" read() properly | ||
22 | added REV 1.5 S/P-DIF receiver support | ||
23 | SNDCTL_DSP_SPEED now returns the actual speed | ||
24 | * 10 Aug 2002: added synchronize_irq() again | ||
25 | |||
26 | TODO: | ||
27 | - test more than one card --- done | ||
28 | - check for pci IOREGION (see es1370) in rme96xx_probe ?? | ||
29 | - error detection | ||
30 | - mmap interface | ||
31 | - mixer mmap interface | ||
32 | - mixer ioctl | ||
33 | - get rid of noise upon first open (why ??) | ||
34 | - allow multiple open (at least for read) | ||
35 | - allow multiple open for non overlapping regions | ||
36 | - recheck the multiple devices part (offsets of different devices, etc) | ||
37 | - do decent draining in _release --- done | ||
38 | - SMP support | ||
39 | - what about using fragstotal>2 for small fragsize? (HP20020118) | ||
40 | - add support for AFMT_S32_LE | ||
41 | */ | ||
42 | |||
43 | #ifndef RMEVERSION | ||
44 | #define RMEVERSION "0.8" | ||
45 | #endif | ||
46 | |||
47 | #include <linux/module.h> | ||
48 | #include <linux/string.h> | ||
49 | #include <linux/sched.h> | ||
50 | #include <linux/sound.h> | ||
51 | #include <linux/soundcard.h> | ||
52 | #include <linux/pci.h> | ||
53 | #include <linux/smp_lock.h> | ||
54 | #include <linux/delay.h> | ||
55 | #include <linux/slab.h> | ||
56 | #include <linux/interrupt.h> | ||
57 | #include <linux/init.h> | ||
58 | #include <linux/interrupt.h> | ||
59 | #include <linux/poll.h> | ||
60 | #include <linux/wait.h> | ||
61 | #include <linux/mutex.h> | ||
62 | |||
63 | #include <asm/dma.h> | ||
64 | #include <asm/page.h> | ||
65 | |||
66 | #include "rme96xx.h" | ||
67 | |||
68 | #define NR_DEVICE 2 | ||
69 | |||
70 | static int devices = 1; | ||
71 | module_param(devices, int, 0); | ||
72 | MODULE_PARM_DESC(devices, "number of dsp devices allocated by the driver"); | ||
73 | |||
74 | |||
75 | MODULE_AUTHOR("Guenter Geiger, geiger@debian.org"); | ||
76 | MODULE_DESCRIPTION("RME9652/36 \"Hammerfall\" Driver"); | ||
77 | MODULE_LICENSE("GPL"); | ||
78 | |||
79 | |||
80 | #ifdef DEBUG | ||
81 | #define DBG(x) printk("RME_DEBUG:");x | ||
82 | #define COMM(x) printk("RME_COMM: " x "\n"); | ||
83 | #else | ||
84 | #define DBG(x) while (0) {} | ||
85 | #define COMM(x) | ||
86 | #endif | ||
87 | |||
88 | /*-------------------------------------------------------------------------- | ||
89 | Preporcessor Macros and Definitions | ||
90 | --------------------------------------------------------------------------*/ | ||
91 | |||
92 | #define RME96xx_MAGIC 0x6473 | ||
93 | |||
94 | /* Registers-Space in offsets from base address with 16MByte size */ | ||
95 | |||
96 | #define RME96xx_IO_EXTENT 16l*1024l*1024l | ||
97 | #define RME96xx_CHANNELS_PER_CARD 26 | ||
98 | |||
99 | /* Write - Register */ | ||
100 | |||
101 | /* 0,4,8,12,16,20,24,28 ... hardware init (erasing fifo-pointer intern) */ | ||
102 | #define RME96xx_num_of_init_regs 8 | ||
103 | |||
104 | #define RME96xx_init_buffer (0/4) | ||
105 | #define RME96xx_play_buffer (32/4) /* pointer to 26x64kBit RAM from mainboard */ | ||
106 | #define RME96xx_rec_buffer (36/4) /* pointer to 26x64kBit RAM from mainboard */ | ||
107 | #define RME96xx_control_register (64/4) /* exact meaning see below */ | ||
108 | #define RME96xx_irq_clear (96/4) /* irq acknowledge */ | ||
109 | #define RME96xx_time_code (100/4) /* if used with alesis adat */ | ||
110 | #define RME96xx_thru_base (128/4) /* 132...228 Thru for 26 channels */ | ||
111 | #define RME96xx_thru_channels RME96xx_CHANNELS_PER_CARD | ||
112 | |||
113 | /* Read Register */ | ||
114 | |||
115 | #define RME96xx_status_register 0 /* meaning see below */ | ||
116 | |||
117 | |||
118 | |||
119 | /* Status Register: */ | ||
120 | /* ------------------------------------------------------------------------ */ | ||
121 | #define RME96xx_IRQ 0x0000001 /* IRQ is High if not reset by RMExx_irq_clear */ | ||
122 | #define RME96xx_lock_2 0x0000002 /* ADAT 3-PLL: 1=locked, 0=unlocked */ | ||
123 | #define RME96xx_lock_1 0x0000004 /* ADAT 2-PLL: 1=locked, 0=unlocked */ | ||
124 | #define RME96xx_lock_0 0x0000008 /* ADAT 1-PLL: 1=locked, 0=unlocked */ | ||
125 | |||
126 | #define RME96xx_fs48 0x0000010 /* sample rate 0 ...44.1/88.2, 1 ... 48/96 Khz */ | ||
127 | #define RME96xx_wsel_rd 0x0000020 /* if Word-Clock is used and valid then 1 */ | ||
128 | #define RME96xx_buf_pos1 0x0000040 /* Bit 6..15 : Position of buffer-pointer in 64Bytes-blocks */ | ||
129 | #define RME96xx_buf_pos2 0x0000080 /* resolution +/- 1 64Byte/block (since 64Bytes bursts) */ | ||
130 | |||
131 | #define RME96xx_buf_pos3 0x0000100 /* 10 bits = 1024 values */ | ||
132 | #define RME96xx_buf_pos4 0x0000200 /* if we mask off the first 6 bits, we can take the status */ | ||
133 | #define RME96xx_buf_pos5 0x0000400 /* register as sample counter in the hardware buffer */ | ||
134 | #define RME96xx_buf_pos6 0x0000800 | ||
135 | |||
136 | #define RME96xx_buf_pos7 0x0001000 | ||
137 | #define RME96xx_buf_pos8 0x0002000 | ||
138 | #define RME96xx_buf_pos9 0x0004000 | ||
139 | #define RME96xx_buf_pos10 0x0008000 | ||
140 | |||
141 | #define RME96xx_sync_2 0x0010000 /* if ADAT-IN3 synced to system clock */ | ||
142 | #define RME96xx_sync_1 0x0020000 /* if ADAT-IN2 synced to system clock */ | ||
143 | #define RME96xx_sync_0 0x0040000 /* if ADAT-IN1 synced to system clock */ | ||
144 | #define RME96xx_DS_rd 0x0080000 /* 1=Double Speed, 0=Normal Speed */ | ||
145 | |||
146 | #define RME96xx_tc_busy 0x0100000 /* 1=time-code copy in progress (960ms) */ | ||
147 | #define RME96xx_tc_out 0x0200000 /* time-code out bit */ | ||
148 | #define RME96xx_F_0 0x0400000 /* 000=64kHz, 100=88.2kHz, 011=96kHz */ | ||
149 | #define RME96xx_F_1 0x0800000 /* 111=32kHz, 110=44.1kHz, 101=48kHz, */ | ||
150 | |||
151 | #define RME96xx_F_2 0x1000000 /* 001=Rev 1.5+ external Crystal Chip */ | ||
152 | #define RME96xx_ERF 0x2000000 /* Error-Flag of SDPIF Receiver (1=No Lock)*/ | ||
153 | #define RME96xx_buffer_id 0x4000000 /* toggles by each interrupt on rec/play */ | ||
154 | #define RME96xx_tc_valid 0x8000000 /* 1 = a signal is detected on time-code input */ | ||
155 | #define RME96xx_SPDIF_READ 0x10000000 /* byte available from Rev 1.5+ SPDIF interface */ | ||
156 | |||
157 | /* Status Register Fields */ | ||
158 | |||
159 | #define RME96xx_lock (RME96xx_lock_0|RME96xx_lock_1|RME96xx_lock_2) | ||
160 | #define RME96xx_sync (RME96xx_sync_0|RME96xx_sync_1|RME96xx_sync_2) | ||
161 | #define RME96xx_F (RME96xx_F_0|RME96xx_F_1|RME96xx_F_2) | ||
162 | #define rme96xx_decode_spdif_rate(x) ((x)>>22) | ||
163 | |||
164 | /* Bit 6..15 : h/w buffer pointer */ | ||
165 | #define RME96xx_buf_pos 0x000FFC0 | ||
166 | /* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later | ||
167 | Rev G EEPROMS and Rev 1.5 cards or later. | ||
168 | */ | ||
169 | #define RME96xx_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME96xx_buf_pos)) | ||
170 | |||
171 | |||
172 | /* Control-Register: */ | ||
173 | /*--------------------------------------------------------------------------------*/ | ||
174 | |||
175 | #define RME96xx_start_bit 0x0001 /* start record/play */ | ||
176 | #define RME96xx_latency0 0x0002 /* Buffer size / latency */ | ||
177 | #define RME96xx_latency1 0x0004 /* buffersize = 512Bytes * 2^n */ | ||
178 | #define RME96xx_latency2 0x0008 /* 0=64samples ... 7=8192samples */ | ||
179 | |||
180 | #define RME96xx_Master 0x0010 /* Clock Mode 1=Master, 0=Slave/Auto */ | ||
181 | #define RME96xx_IE 0x0020 /* Interupt Enable */ | ||
182 | #define RME96xx_freq 0x0040 /* samplerate 0=44.1/88.2, 1=48/96 kHz*/ | ||
183 | #define RME96xx_freq1 0x0080 /* samplerate 0=32 kHz, 1=other rates ??? (from ALSA, but may be wrong) */ | ||
184 | #define RME96xx_DS 0x0100 /* double speed 0=44.1/48, 1=88.2/96 Khz */ | ||
185 | #define RME96xx_PRO 0x0200 /* SPDIF-OUT 0=consumer, 1=professional */ | ||
186 | #define RME96xx_EMP 0x0400 /* SPDIF-OUT emphasis 0=off, 1=on */ | ||
187 | #define RME96xx_Dolby 0x0800 /* SPDIF-OUT non-audio bit 1=set, 0=unset */ | ||
188 | |||
189 | #define RME96xx_opt_out 0x1000 /* use 1st optical OUT as SPDIF: 1=yes, 0=no */ | ||
190 | #define RME96xx_wsel 0x2000 /* use Wordclock as sync (overwrites master) */ | ||
191 | #define RME96xx_inp_0 0x4000 /* SPDIF-IN 00=optical (ADAT1), */ | ||
192 | #define RME96xx_inp_1 0x8000 /* 01=coaxial (Cinch), 10=internal CDROM */ | ||
193 | |||
194 | #define RME96xx_SyncRef0 0x10000 /* preferred sync-source in autosync */ | ||
195 | #define RME96xx_SyncRef1 0x20000 /* 00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */ | ||
196 | |||
197 | #define RME96xx_SPDIF_RESET (1<<18) /* Rev 1.5+: h/w SPDIF receiver */ | ||
198 | #define RME96xx_SPDIF_SELECT (1<<19) | ||
199 | #define RME96xx_SPDIF_CLOCK (1<<20) | ||
200 | #define RME96xx_SPDIF_WRITE (1<<21) | ||
201 | #define RME96xx_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */ | ||
202 | |||
203 | |||
204 | #define RME96xx_ctrl_init (RME96xx_latency0 |\ | ||
205 | RME96xx_Master |\ | ||
206 | RME96xx_inp_1) | ||
207 | |||
208 | |||
209 | |||
210 | /* Control register fields and shortcuts */ | ||
211 | |||
212 | #define RME96xx_latency (RME96xx_latency0|RME96xx_latency1|RME96xx_latency2) | ||
213 | #define RME96xx_inp (RME96xx_inp_0|RME96xx_inp_1) | ||
214 | #define RME96xx_SyncRef (RME96xx_SyncRef0|RME96xx_SyncRef1) | ||
215 | #define RME96xx_mixer_allowed (RME96xx_Master|RME96xx_PRO|RME96xx_EMP|RME96xx_Dolby|RME96xx_opt_out|RME96xx_wsel|RME96xx_inp|RME96xx_SyncRef|RME96xx_ADAT1_INTERNAL) | ||
216 | |||
217 | /* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit1 (??? HP20020201) */ | ||
218 | |||
219 | #define RME96xx_SET_LATENCY(x) (((x)&0x7)<<1) | ||
220 | #define RME96xx_GET_LATENCY(x) (((x)>>1)&0x7) | ||
221 | #define RME96xx_SET_inp(x) (((x)&0x3)<<14) | ||
222 | #define RME96xx_GET_inp(x) (((x)>>14)&0x3) | ||
223 | #define RME96xx_SET_SyncRef(x) (((x)&0x3)<<17) | ||
224 | #define RME96xx_GET_SyncRef(x) (((x)>>17)&0x3) | ||
225 | |||
226 | |||
227 | /* buffer sizes */ | ||
228 | #define RME96xx_BYTES_PER_SAMPLE 4 /* sizeof(u32) */ | ||
229 | #define RME_16K 16*1024 | ||
230 | |||
231 | #define RME96xx_DMA_MAX_SAMPLES (RME_16K) | ||
232 | #define RME96xx_DMA_MAX_SIZE (RME_16K * RME96xx_BYTES_PER_SAMPLE) | ||
233 | #define RME96xx_DMA_MAX_SIZE_ALL (RME96xx_DMA_MAX_SIZE * RME96xx_CHANNELS_PER_CARD) | ||
234 | |||
235 | #define RME96xx_NUM_OF_FRAGMENTS 2 | ||
236 | #define RME96xx_FRAGMENT_MAX_SIZE (RME96xx_DMA_MAX_SIZE/2) | ||
237 | #define RME96xx_FRAGMENT_MAX_SAMPLES (RME96xx_DMA_MAX_SAMPLES/2) | ||
238 | #define RME96xx_MAX_LATENCY 7 /* 16k samples */ | ||
239 | |||
240 | |||
241 | #define RME96xx_MAX_DEVS 4 /* we provide some OSS stereodevs */ | ||
242 | #define RME96xx_MASK_DEVS 0x3 /* RME96xx_MAX_DEVS-1 */ | ||
243 | |||
244 | #define RME_MESS "rme96xx:" | ||
245 | /*------------------------------------------------------------------------ | ||
246 | Types, struct and function declarations | ||
247 | ------------------------------------------------------------------------*/ | ||
248 | |||
249 | |||
250 | /* --------------------------------------------------------------------- */ | ||
251 | |||
252 | static const char invalid_magic[] = KERN_CRIT RME_MESS" invalid magic value\n"; | ||
253 | |||
254 | #define VALIDATE_STATE(s) \ | ||
255 | ({ \ | ||
256 | if (!(s) || (s)->magic != RME96xx_MAGIC) { \ | ||
257 | printk(invalid_magic); \ | ||
258 | return -ENXIO; \ | ||
259 | } \ | ||
260 | }) | ||
261 | |||
262 | /* --------------------------------------------------------------------- */ | ||
263 | |||
264 | |||
265 | static struct file_operations rme96xx_audio_fops; | ||
266 | static struct file_operations rme96xx_mixer_fops; | ||
267 | static int numcards; | ||
268 | |||
269 | typedef int32_t raw_sample_t; | ||
270 | |||
271 | typedef struct _rme96xx_info { | ||
272 | |||
273 | /* hardware settings */ | ||
274 | int magic; | ||
275 | struct pci_dev * pcidev; /* pci_dev structure */ | ||
276 | unsigned long __iomem *iobase; | ||
277 | unsigned int irq; | ||
278 | |||
279 | /* list of rme96xx devices */ | ||
280 | struct list_head devs; | ||
281 | |||
282 | spinlock_t lock; | ||
283 | |||
284 | u32 *recbuf; /* memory for rec buffer */ | ||
285 | u32 *playbuf; /* memory for play buffer */ | ||
286 | |||
287 | u32 control_register; | ||
288 | |||
289 | u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */ | ||
290 | |||
291 | int hw_rev; /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */ | ||
292 | char *card_name; /* hammerfall or hammerfall light names */ | ||
293 | |||
294 | int open_count; /* unused ??? HP20020201 */ | ||
295 | |||
296 | int rate; | ||
297 | int latency; | ||
298 | unsigned int fragsize; | ||
299 | int started; | ||
300 | |||
301 | int hwptr; /* can be negativ because of pci burst offset */ | ||
302 | unsigned int hwbufid; /* set by interrupt, buffer which is written/read now */ | ||
303 | |||
304 | struct dmabuf { | ||
305 | |||
306 | unsigned int format; | ||
307 | int formatshift; | ||
308 | int inchannels; /* number of channels for device */ | ||
309 | int outchannels; /* number of channels for device */ | ||
310 | int mono; /* if true, we play mono on 2 channels */ | ||
311 | int inoffset; /* which channel is considered the first one */ | ||
312 | int outoffset; | ||
313 | |||
314 | /* state */ | ||
315 | int opened; /* open() made */ | ||
316 | int started; /* first write/read */ | ||
317 | int mmapped; /* mmap */ | ||
318 | int open_mode; | ||
319 | |||
320 | struct _rme96xx_info *s; | ||
321 | |||
322 | /* pointer to read/write position in buffer */ | ||
323 | unsigned readptr; | ||
324 | unsigned writeptr; | ||
325 | |||
326 | unsigned error; /* over/underruns cleared on sync again */ | ||
327 | |||
328 | /* waiting and locking */ | ||
329 | wait_queue_head_t wait; | ||
330 | struct mutex open_mutex; | ||
331 | wait_queue_head_t open_wait; | ||
332 | |||
333 | } dma[RME96xx_MAX_DEVS]; | ||
334 | |||
335 | int dspnum[RME96xx_MAX_DEVS]; /* register with sound subsystem */ | ||
336 | int mixer; /* register with sound subsystem */ | ||
337 | } rme96xx_info; | ||
338 | |||
339 | |||
340 | /* fiddling with the card (first level hardware control) */ | ||
341 | |||
342 | static inline void rme96xx_set_ctrl(rme96xx_info* s,int mask) | ||
343 | { | ||
344 | |||
345 | s->control_register|=mask; | ||
346 | writel(s->control_register,s->iobase + RME96xx_control_register); | ||
347 | |||
348 | } | ||
349 | |||
350 | static inline void rme96xx_unset_ctrl(rme96xx_info* s,int mask) | ||
351 | { | ||
352 | |||
353 | s->control_register&=(~mask); | ||
354 | writel(s->control_register,s->iobase + RME96xx_control_register); | ||
355 | |||
356 | } | ||
357 | |||
358 | static inline int rme96xx_get_sample_rate_status(rme96xx_info* s) | ||
359 | { | ||
360 | int val; | ||
361 | u32 status; | ||
362 | status = readl(s->iobase + RME96xx_status_register); | ||
363 | val = (status & RME96xx_fs48) ? 48000 : 44100; | ||
364 | if (status & RME96xx_DS_rd) | ||
365 | val *= 2; | ||
366 | return val; | ||
367 | } | ||
368 | |||
369 | static inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s) | ||
370 | { | ||
371 | int val; | ||
372 | val = (s->control_register & RME96xx_freq) ? 48000 : 44100; | ||
373 | if (s->control_register & RME96xx_DS) | ||
374 | val *= 2; | ||
375 | return val; | ||
376 | } | ||
377 | |||
378 | |||
379 | /* code from ALSA card-rme9652.c for rev 1.5 SPDIF receiver HP 20020201 */ | ||
380 | |||
381 | static void rme96xx_spdif_set_bit (rme96xx_info* s, int mask, int onoff) | ||
382 | { | ||
383 | if (onoff) | ||
384 | s->control_register |= mask; | ||
385 | else | ||
386 | s->control_register &= ~mask; | ||
387 | |||
388 | writel(s->control_register,s->iobase + RME96xx_control_register); | ||
389 | } | ||
390 | |||
391 | static void rme96xx_spdif_write_byte (rme96xx_info* s, const int val) | ||
392 | { | ||
393 | long mask; | ||
394 | long i; | ||
395 | |||
396 | for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) { | ||
397 | if (val & mask) | ||
398 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 1); | ||
399 | else | ||
400 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 0); | ||
401 | |||
402 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1); | ||
403 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | static int rme96xx_spdif_read_byte (rme96xx_info* s) | ||
408 | { | ||
409 | long mask; | ||
410 | long val; | ||
411 | long i; | ||
412 | |||
413 | val = 0; | ||
414 | |||
415 | for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) { | ||
416 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1); | ||
417 | if (readl(s->iobase + RME96xx_status_register) & RME96xx_SPDIF_READ) | ||
418 | val |= mask; | ||
419 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0); | ||
420 | } | ||
421 | |||
422 | return val; | ||
423 | } | ||
424 | |||
425 | static void rme96xx_write_spdif_codec (rme96xx_info* s, const int address, const int data) | ||
426 | { | ||
427 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1); | ||
428 | rme96xx_spdif_write_byte (s, 0x20); | ||
429 | rme96xx_spdif_write_byte (s, address); | ||
430 | rme96xx_spdif_write_byte (s, data); | ||
431 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0); | ||
432 | } | ||
433 | |||
434 | |||
435 | static int rme96xx_spdif_read_codec (rme96xx_info* s, const int address) | ||
436 | { | ||
437 | int ret; | ||
438 | |||
439 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1); | ||
440 | rme96xx_spdif_write_byte (s, 0x20); | ||
441 | rme96xx_spdif_write_byte (s, address); | ||
442 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0); | ||
443 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1); | ||
444 | |||
445 | rme96xx_spdif_write_byte (s, 0x21); | ||
446 | ret = rme96xx_spdif_read_byte (s); | ||
447 | rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0); | ||
448 | |||
449 | return ret; | ||
450 | } | ||
451 | |||
452 | static void rme96xx_initialize_spdif_receiver (rme96xx_info* s) | ||
453 | { | ||
454 | /* XXX what unsets this ? */ | ||
455 | /* no idea ??? HP 20020201 */ | ||
456 | |||
457 | s->control_register |= RME96xx_SPDIF_RESET; | ||
458 | |||
459 | rme96xx_write_spdif_codec (s, 4, 0x40); | ||
460 | rme96xx_write_spdif_codec (s, 17, 0x13); | ||
461 | rme96xx_write_spdif_codec (s, 6, 0x02); | ||
462 | } | ||
463 | |||
464 | static inline int rme96xx_spdif_sample_rate (rme96xx_info *s, int *spdifrate) | ||
465 | { | ||
466 | unsigned int rate_bits; | ||
467 | |||
468 | *spdifrate = 0x1; | ||
469 | if (readl(s->iobase + RME96xx_status_register) & RME96xx_ERF) { | ||
470 | return -1; /* error condition */ | ||
471 | } | ||
472 | |||
473 | if (s->hw_rev == 15) { | ||
474 | |||
475 | int x, y, ret; | ||
476 | |||
477 | x = rme96xx_spdif_read_codec (s, 30); | ||
478 | |||
479 | if (x != 0) | ||
480 | y = 48000 * 64 / x; | ||
481 | else | ||
482 | y = 0; | ||
483 | |||
484 | if (y > 30400 && y < 33600) {ret = 32000; *spdifrate = 0x7;} | ||
485 | else if (y > 41900 && y < 46000) {ret = 44100; *spdifrate = 0x6;} | ||
486 | else if (y > 46000 && y < 50400) {ret = 48000; *spdifrate = 0x5;} | ||
487 | else if (y > 60800 && y < 67200) {ret = 64000; *spdifrate = 0x0;} | ||
488 | else if (y > 83700 && y < 92000) {ret = 88200; *spdifrate = 0x4;} | ||
489 | else if (y > 92000 && y < 100000) {ret = 96000; *spdifrate = 0x3;} | ||
490 | else {ret = 0; *spdifrate = 0x1;} | ||
491 | return ret; | ||
492 | } | ||
493 | |||
494 | rate_bits = readl(s->iobase + RME96xx_status_register) & RME96xx_F; | ||
495 | |||
496 | switch (*spdifrate = rme96xx_decode_spdif_rate(rate_bits)) { | ||
497 | case 0x7: | ||
498 | return 32000; | ||
499 | break; | ||
500 | |||
501 | case 0x6: | ||
502 | return 44100; | ||
503 | break; | ||
504 | |||
505 | case 0x5: | ||
506 | return 48000; | ||
507 | break; | ||
508 | |||
509 | case 0x4: | ||
510 | return 88200; | ||
511 | break; | ||
512 | |||
513 | case 0x3: | ||
514 | return 96000; | ||
515 | break; | ||
516 | |||
517 | case 0x0: | ||
518 | return 64000; | ||
519 | break; | ||
520 | |||
521 | default: | ||
522 | /* was an ALSA warning ... | ||
523 | snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n", | ||
524 | s->card_name, rate_bits); | ||
525 | */ | ||
526 | return 0; | ||
527 | break; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | /* end of code from ALSA card-rme9652.c */ | ||
532 | |||
533 | |||
534 | |||
535 | /* the hwbuf in the status register seems to have some jitter, to get rid of | ||
536 | it, we first only let the numbers grow, to be on the secure side we | ||
537 | subtract a certain amount RME96xx_BURSTBYTES from the resulting number */ | ||
538 | |||
539 | /* the function returns the hardware pointer in bytes */ | ||
540 | #define RME96xx_BURSTBYTES -64 /* bytes by which hwptr could be off */ | ||
541 | |||
542 | static inline int rme96xx_gethwptr(rme96xx_info* s,int exact) | ||
543 | { | ||
544 | unsigned long flags; | ||
545 | if (exact) { | ||
546 | unsigned int hwp; | ||
547 | /* the hwptr seems to be rather unreliable :(, so we don't use it */ | ||
548 | spin_lock_irqsave(&s->lock,flags); | ||
549 | |||
550 | hwp = readl(s->iobase + RME96xx_status_register) & 0xffc0; | ||
551 | s->hwptr = (hwp < s->hwptr) ? s->hwptr : hwp; | ||
552 | // s->hwptr = hwp; | ||
553 | |||
554 | spin_unlock_irqrestore(&s->lock,flags); | ||
555 | return (s->hwptr+RME96xx_BURSTBYTES) & ((s->fragsize<<1)-1); | ||
556 | } | ||
557 | return (s->hwbufid ? s->fragsize : 0); | ||
558 | } | ||
559 | |||
560 | static inline void rme96xx_setlatency(rme96xx_info* s,int l) | ||
561 | { | ||
562 | s->latency = l; | ||
563 | s->fragsize = 1<<(8+l); | ||
564 | rme96xx_unset_ctrl(s,RME96xx_latency); | ||
565 | rme96xx_set_ctrl(s,RME96xx_SET_LATENCY(l)); | ||
566 | } | ||
567 | |||
568 | |||
569 | static void rme96xx_clearbufs(struct dmabuf* dma) | ||
570 | { | ||
571 | int i,j; | ||
572 | unsigned long flags; | ||
573 | |||
574 | /* clear dmabufs */ | ||
575 | for(i=0;i<devices;i++) { | ||
576 | for (j=0;j<dma->outchannels + dma->mono;j++) | ||
577 | memset(&dma->s->playbuf[(dma->outoffset + j)*RME96xx_DMA_MAX_SAMPLES], | ||
578 | 0, RME96xx_DMA_MAX_SIZE); | ||
579 | } | ||
580 | spin_lock_irqsave(&dma->s->lock,flags); | ||
581 | dma->writeptr = 0; | ||
582 | dma->readptr = 0; | ||
583 | spin_unlock_irqrestore(&dma->s->lock,flags); | ||
584 | } | ||
585 | |||
586 | static int rme96xx_startcard(rme96xx_info *s,int stop) | ||
587 | { | ||
588 | int i; | ||
589 | unsigned long flags; | ||
590 | |||
591 | COMM ("startcard"); | ||
592 | if(s->control_register & RME96xx_IE){ | ||
593 | /* disable interrupt first */ | ||
594 | |||
595 | rme96xx_unset_ctrl( s,RME96xx_start_bit ); | ||
596 | udelay(10); | ||
597 | rme96xx_unset_ctrl( s,RME96xx_IE); | ||
598 | spin_lock_irqsave(&s->lock,flags); /* timing is critical */ | ||
599 | s->started = 0; | ||
600 | spin_unlock_irqrestore(&s->lock,flags); | ||
601 | if (stop) { | ||
602 | COMM("Sound card stopped"); | ||
603 | return 1; | ||
604 | } | ||
605 | } | ||
606 | COMM ("interrupt disabled"); | ||
607 | /* first initialize all pointers on card */ | ||
608 | for(i=0;i<RME96xx_num_of_init_regs;i++){ | ||
609 | writel(0,s->iobase + i); | ||
610 | udelay(10); /* ?? */ | ||
611 | } | ||
612 | COMM ("regs cleaned"); | ||
613 | |||
614 | spin_lock_irqsave(&s->lock,flags); /* timing is critical */ | ||
615 | udelay(10); | ||
616 | s->started = 1; | ||
617 | s->hwptr = 0; | ||
618 | spin_unlock_irqrestore(&s->lock,flags); | ||
619 | |||
620 | rme96xx_set_ctrl( s, RME96xx_IE | RME96xx_start_bit); | ||
621 | |||
622 | |||
623 | COMM("Sound card started"); | ||
624 | |||
625 | return 1; | ||
626 | } | ||
627 | |||
628 | |||
629 | static inline int rme96xx_getospace(struct dmabuf * dma, unsigned int hwp) | ||
630 | { | ||
631 | int cnt; | ||
632 | int swptr; | ||
633 | unsigned long flags; | ||
634 | |||
635 | spin_lock_irqsave(&dma->s->lock,flags); | ||
636 | swptr = dma->writeptr; | ||
637 | cnt = (hwp - swptr); | ||
638 | |||
639 | if (cnt < 0) { | ||
640 | cnt = ((dma->s->fragsize<<1) - swptr); | ||
641 | } | ||
642 | spin_unlock_irqrestore(&dma->s->lock,flags); | ||
643 | return cnt; | ||
644 | } | ||
645 | |||
646 | static inline int rme96xx_getispace(struct dmabuf * dma, unsigned int hwp) | ||
647 | { | ||
648 | int cnt; | ||
649 | int swptr; | ||
650 | unsigned long flags; | ||
651 | |||
652 | spin_lock_irqsave(&dma->s->lock,flags); | ||
653 | swptr = dma->readptr; | ||
654 | cnt = (hwp - swptr); | ||
655 | |||
656 | if (cnt < 0) { | ||
657 | cnt = ((dma->s->fragsize<<1) - swptr); | ||
658 | } | ||
659 | spin_unlock_irqrestore(&dma->s->lock,flags); | ||
660 | return cnt; | ||
661 | } | ||
662 | |||
663 | |||
664 | static inline int rme96xx_copyfromuser(struct dmabuf* dma,const char __user * buffer,int count,int hop) | ||
665 | { | ||
666 | int swptr = dma->writeptr; | ||
667 | switch (dma->format) { | ||
668 | case AFMT_S32_BLOCKED: | ||
669 | { | ||
670 | char __user * buf = (char __user *)buffer; | ||
671 | int cnt = count/dma->outchannels; | ||
672 | int i; | ||
673 | for (i=0;i < dma->outchannels;i++) { | ||
674 | char* hwbuf =(char*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES]; | ||
675 | hwbuf+=swptr; | ||
676 | |||
677 | if (copy_from_user(hwbuf,buf, cnt)) | ||
678 | return -1; | ||
679 | buf+=hop; | ||
680 | } | ||
681 | swptr+=cnt; | ||
682 | break; | ||
683 | } | ||
684 | case AFMT_S16_LE: | ||
685 | { | ||
686 | int i,j; | ||
687 | int cnt = count/dma->outchannels; | ||
688 | for (i=0;i < dma->outchannels + dma->mono;i++) { | ||
689 | short __user * sbuf = (short __user *)buffer + i*(!dma->mono); | ||
690 | short* hwbuf =(short*) &dma->s->playbuf[(dma->outoffset + i)*RME96xx_DMA_MAX_SAMPLES]; | ||
691 | hwbuf+=(swptr>>1); | ||
692 | for (j=0;j<(cnt>>1);j++) { | ||
693 | hwbuf++; /* skip the low 16 bits */ | ||
694 | __get_user(*hwbuf++,sbuf++); | ||
695 | sbuf+=(dma->outchannels-1); | ||
696 | } | ||
697 | } | ||
698 | swptr += (cnt<<1); | ||
699 | break; | ||
700 | } | ||
701 | default: | ||
702 | printk(RME_MESS" unsupported format\n"); | ||
703 | return -1; | ||
704 | } /* switch */ | ||
705 | |||
706 | swptr&=((dma->s->fragsize<<1) -1); | ||
707 | dma->writeptr = swptr; | ||
708 | |||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | /* The count argument is the number of bytes */ | ||
713 | static inline int rme96xx_copytouser(struct dmabuf* dma,const char __user* buffer,int count,int hop) | ||
714 | { | ||
715 | int swptr = dma->readptr; | ||
716 | switch (dma->format) { | ||
717 | case AFMT_S32_BLOCKED: | ||
718 | { | ||
719 | char __user * buf = (char __user *)buffer; | ||
720 | int cnt = count/dma->inchannels; | ||
721 | int i; | ||
722 | |||
723 | for (i=0;i < dma->inchannels;i++) { | ||
724 | char* hwbuf =(char*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES]; | ||
725 | hwbuf+=swptr; | ||
726 | |||
727 | if (copy_to_user(buf,hwbuf,cnt)) | ||
728 | return -1; | ||
729 | buf+=hop; | ||
730 | } | ||
731 | swptr+=cnt; | ||
732 | break; | ||
733 | } | ||
734 | case AFMT_S16_LE: | ||
735 | { | ||
736 | int i,j; | ||
737 | int cnt = count/dma->inchannels; | ||
738 | for (i=0;i < dma->inchannels;i++) { | ||
739 | short __user * sbuf = (short __user *)buffer + i; | ||
740 | short* hwbuf =(short*) &dma->s->recbuf[(dma->inoffset + i)*RME96xx_DMA_MAX_SAMPLES]; | ||
741 | hwbuf+=(swptr>>1); | ||
742 | for (j=0;j<(cnt>>1);j++) { | ||
743 | hwbuf++; | ||
744 | __put_user(*hwbuf++,sbuf++); | ||
745 | sbuf+=(dma->inchannels-1); | ||
746 | } | ||
747 | } | ||
748 | swptr += (cnt<<1); | ||
749 | break; | ||
750 | } | ||
751 | default: | ||
752 | printk(RME_MESS" unsupported format\n"); | ||
753 | return -1; | ||
754 | } /* switch */ | ||
755 | |||
756 | swptr&=((dma->s->fragsize<<1) -1); | ||
757 | dma->readptr = swptr; | ||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | |||
762 | static irqreturn_t rme96xx_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
763 | { | ||
764 | int i; | ||
765 | rme96xx_info *s = (rme96xx_info *)dev_id; | ||
766 | struct dmabuf *db; | ||
767 | u32 status; | ||
768 | unsigned long flags; | ||
769 | |||
770 | status = readl(s->iobase + RME96xx_status_register); | ||
771 | if (!(status & RME96xx_IRQ)) { | ||
772 | return IRQ_NONE; | ||
773 | } | ||
774 | |||
775 | spin_lock_irqsave(&s->lock,flags); | ||
776 | writel(0,s->iobase + RME96xx_irq_clear); | ||
777 | |||
778 | s->hwbufid = (status & RME96xx_buffer_id)>>26; | ||
779 | if ((status & 0xffc0) <= 256) s->hwptr = 0; | ||
780 | for(i=0;i<devices;i++) | ||
781 | { | ||
782 | db = &(s->dma[i]); | ||
783 | if(db->started > 0) | ||
784 | wake_up(&(db->wait)); | ||
785 | } | ||
786 | spin_unlock_irqrestore(&s->lock,flags); | ||
787 | return IRQ_HANDLED; | ||
788 | } | ||
789 | |||
790 | |||
791 | |||
792 | /*---------------------------------------------------------------------------- | ||
793 | PCI detection and module initialization stuff | ||
794 | ----------------------------------------------------------------------------*/ | ||
795 | |||
796 | static void* busmaster_malloc(int size) { | ||
797 | int pg; /* 2 s exponent of memory size */ | ||
798 | char *buf; | ||
799 | |||
800 | DBG(printk("kernel malloc pages ..\n")); | ||
801 | |||
802 | for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++); | ||
803 | |||
804 | buf = (char *) __get_free_pages(GFP_KERNEL | GFP_DMA, pg); | ||
805 | |||
806 | if (buf) { | ||
807 | struct page* page, *last_page; | ||
808 | |||
809 | page = virt_to_page(buf); | ||
810 | last_page = page + (1 << pg); | ||
811 | DBG(printk("setting reserved bit\n")); | ||
812 | while (page < last_page) { | ||
813 | SetPageReserved(page); | ||
814 | page++; | ||
815 | } | ||
816 | return buf; | ||
817 | } | ||
818 | DBG(printk("allocated %ld",(long)buf)); | ||
819 | return NULL; | ||
820 | } | ||
821 | |||
822 | static void busmaster_free(void* ptr,int size) { | ||
823 | int pg; | ||
824 | struct page* page, *last_page; | ||
825 | |||
826 | if (ptr == NULL) | ||
827 | return; | ||
828 | |||
829 | for (pg = 0; PAGE_SIZE * (1 << pg) < size; pg++); | ||
830 | |||
831 | page = virt_to_page(ptr); | ||
832 | last_page = page + (1 << pg); | ||
833 | while (page < last_page) { | ||
834 | ClearPageReserved(page); | ||
835 | page++; | ||
836 | } | ||
837 | DBG(printk("freeing pages\n")); | ||
838 | free_pages((unsigned long) ptr, pg); | ||
839 | DBG(printk("done\n")); | ||
840 | } | ||
841 | |||
842 | /* initialize those parts of the info structure which are not pci detectable resources */ | ||
843 | |||
844 | static int rme96xx_dmabuf_init(rme96xx_info * s,struct dmabuf* dma,int ioffset,int ooffset) { | ||
845 | |||
846 | mutex_init(&dma->open_mutex); | ||
847 | init_waitqueue_head(&dma->open_wait); | ||
848 | init_waitqueue_head(&dma->wait); | ||
849 | dma->s = s; | ||
850 | dma->error = 0; | ||
851 | |||
852 | dma->format = AFMT_S32_BLOCKED; | ||
853 | dma->formatshift = 0; | ||
854 | dma->inchannels = dma->outchannels = 1; | ||
855 | dma->inoffset = ioffset; | ||
856 | dma->outoffset = ooffset; | ||
857 | |||
858 | dma->opened=0; | ||
859 | dma->started=0; | ||
860 | dma->mmapped=0; | ||
861 | dma->open_mode=0; | ||
862 | dma->mono=0; | ||
863 | |||
864 | rme96xx_clearbufs(dma); | ||
865 | return 0; | ||
866 | } | ||
867 | |||
868 | |||
869 | static int rme96xx_init(rme96xx_info* s) | ||
870 | { | ||
871 | int i; | ||
872 | int status; | ||
873 | unsigned short rev; | ||
874 | |||
875 | DBG(printk("%s\n", __FUNCTION__)); | ||
876 | numcards++; | ||
877 | |||
878 | s->magic = RME96xx_MAGIC; | ||
879 | |||
880 | spin_lock_init(&s->lock); | ||
881 | |||
882 | COMM ("setup busmaster memory") | ||
883 | s->recbuf = busmaster_malloc(RME96xx_DMA_MAX_SIZE_ALL); | ||
884 | s->playbuf = busmaster_malloc(RME96xx_DMA_MAX_SIZE_ALL); | ||
885 | |||
886 | if (!s->recbuf || !s->playbuf) { | ||
887 | printk(KERN_ERR RME_MESS" Unable to allocate busmaster memory\n"); | ||
888 | return -ENODEV; | ||
889 | } | ||
890 | |||
891 | COMM ("setting rec and playbuffers") | ||
892 | |||
893 | writel((u32) virt_to_bus(s->recbuf),s->iobase + RME96xx_rec_buffer); | ||
894 | writel((u32) virt_to_bus(s->playbuf),s->iobase + RME96xx_play_buffer); | ||
895 | |||
896 | COMM ("initializing control register") | ||
897 | rme96xx_unset_ctrl(s,0xffffffff); | ||
898 | rme96xx_set_ctrl(s,RME96xx_ctrl_init); | ||
899 | |||
900 | |||
901 | COMM ("setup devices") | ||
902 | for (i=0;i < devices;i++) { | ||
903 | struct dmabuf * dma = &s->dma[i]; | ||
904 | rme96xx_dmabuf_init(s,dma,2*i,2*i); | ||
905 | } | ||
906 | |||
907 | /* code from ALSA card-rme9652.c HP 20020201 */ | ||
908 | /* Determine the h/w rev level of the card. This seems like | ||
909 | a particularly kludgy way to encode it, but its what RME | ||
910 | chose to do, so we follow them ... | ||
911 | */ | ||
912 | |||
913 | status = readl(s->iobase + RME96xx_status_register); | ||
914 | if (rme96xx_decode_spdif_rate(status&RME96xx_F) == 1) { | ||
915 | s->hw_rev = 15; | ||
916 | } else { | ||
917 | s->hw_rev = 11; | ||
918 | } | ||
919 | |||
920 | /* Differentiate between the standard Hammerfall, and the | ||
921 | "Light", which does not have the expansion board. This | ||
922 | method comes from information received from Mathhias | ||
923 | Clausen at RME. Display the EEPROM and h/w revID where | ||
924 | relevant. | ||
925 | */ | ||
926 | |||
927 | pci_read_config_word(s->pcidev, PCI_CLASS_REVISION, &rev); | ||
928 | switch (rev & 0xff) { | ||
929 | case 8: /* original eprom */ | ||
930 | if (s->hw_rev == 15) { | ||
931 | s->card_name = "RME Digi9636 (Rev 1.5)"; | ||
932 | } else { | ||
933 | s->card_name = "RME Digi9636"; | ||
934 | } | ||
935 | break; | ||
936 | case 9: /* W36_G EPROM */ | ||
937 | s->card_name = "RME Digi9636 (Rev G)"; | ||
938 | break; | ||
939 | case 4: /* W52_G EPROM */ | ||
940 | s->card_name = "RME Digi9652 (Rev G)"; | ||
941 | break; | ||
942 | default: | ||
943 | case 3: /* original eprom */ | ||
944 | if (s->hw_rev == 15) { | ||
945 | s->card_name = "RME Digi9652 (Rev 1.5)"; | ||
946 | } else { | ||
947 | s->card_name = "RME Digi9652"; | ||
948 | } | ||
949 | break; | ||
950 | } | ||
951 | |||
952 | printk(KERN_INFO RME_MESS" detected %s (hw_rev %d)\n",s->card_name,s->hw_rev); | ||
953 | |||
954 | if (s->hw_rev == 15) | ||
955 | rme96xx_initialize_spdif_receiver (s); | ||
956 | |||
957 | s->started = 0; | ||
958 | rme96xx_setlatency(s,7); | ||
959 | |||
960 | printk(KERN_INFO RME_MESS" card %d initialized\n",numcards); | ||
961 | return 0; | ||
962 | } | ||
963 | |||
964 | |||
965 | /* open uses this to figure out which device was opened .. this seems to be | ||
966 | unnecessary complex */ | ||
967 | |||
968 | static LIST_HEAD(devs); | ||
969 | |||
970 | static int __devinit rme96xx_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) | ||
971 | { | ||
972 | int i; | ||
973 | rme96xx_info *s; | ||
974 | |||
975 | DBG(printk("%s\n", __FUNCTION__)); | ||
976 | |||
977 | if (pcidev->irq == 0) | ||
978 | return -1; | ||
979 | if (!pci_dma_supported(pcidev, 0xffffffff)) { | ||
980 | printk(KERN_WARNING RME_MESS" architecture does not support 32bit PCI busmaster DMA\n"); | ||
981 | return -1; | ||
982 | } | ||
983 | if (!(s = kmalloc(sizeof(rme96xx_info), GFP_KERNEL))) { | ||
984 | printk(KERN_WARNING RME_MESS" out of memory\n"); | ||
985 | return -1; | ||
986 | } | ||
987 | memset(s, 0, sizeof(rme96xx_info)); | ||
988 | |||
989 | s->pcidev = pcidev; | ||
990 | s->iobase = ioremap(pci_resource_start(pcidev, 0),RME96xx_IO_EXTENT); | ||
991 | s->irq = pcidev->irq; | ||
992 | |||
993 | DBG(printk("remapped iobase: %lx irq %d\n",(long)s->iobase,s->irq)); | ||
994 | |||
995 | if (pci_enable_device(pcidev)) | ||
996 | goto err_irq; | ||
997 | if (request_irq(s->irq, rme96xx_interrupt, IRQF_SHARED, "rme96xx", s)) { | ||
998 | printk(KERN_ERR RME_MESS" irq %u in use\n", s->irq); | ||
999 | goto err_irq; | ||
1000 | } | ||
1001 | |||
1002 | /* initialize the card */ | ||
1003 | |||
1004 | i = 0; | ||
1005 | if (rme96xx_init(s) < 0) { | ||
1006 | printk(KERN_ERR RME_MESS" initialization failed\n"); | ||
1007 | goto err_devices; | ||
1008 | } | ||
1009 | for (i=0;i<devices;i++) { | ||
1010 | if ((s->dspnum[i] = register_sound_dsp(&rme96xx_audio_fops, -1)) < 0) | ||
1011 | goto err_devices; | ||
1012 | } | ||
1013 | |||
1014 | if ((s->mixer = register_sound_mixer(&rme96xx_mixer_fops, -1)) < 0) | ||
1015 | goto err_devices; | ||
1016 | |||
1017 | pci_set_drvdata(pcidev, s); | ||
1018 | pcidev->dma_mask = 0xffffffff; /* ????? */ | ||
1019 | /* put it into driver list */ | ||
1020 | list_add_tail(&s->devs, &devs); | ||
1021 | |||
1022 | DBG(printk("initialization successful\n")); | ||
1023 | return 0; | ||
1024 | |||
1025 | /* error handler */ | ||
1026 | err_devices: | ||
1027 | while (i--) | ||
1028 | unregister_sound_dsp(s->dspnum[i]); | ||
1029 | free_irq(s->irq,s); | ||
1030 | err_irq: | ||
1031 | kfree(s); | ||
1032 | return -1; | ||
1033 | } | ||
1034 | |||
1035 | |||
1036 | static void __devexit rme96xx_remove(struct pci_dev *dev) | ||
1037 | { | ||
1038 | int i; | ||
1039 | rme96xx_info *s = pci_get_drvdata(dev); | ||
1040 | |||
1041 | if (!s) { | ||
1042 | printk(KERN_ERR"device structure not valid\n"); | ||
1043 | return ; | ||
1044 | } | ||
1045 | |||
1046 | if (s->started) rme96xx_startcard(s,0); | ||
1047 | |||
1048 | i = devices; | ||
1049 | while (i) { | ||
1050 | i--; | ||
1051 | unregister_sound_dsp(s->dspnum[i]); | ||
1052 | } | ||
1053 | |||
1054 | unregister_sound_mixer(s->mixer); | ||
1055 | synchronize_irq(s->irq); | ||
1056 | free_irq(s->irq,s); | ||
1057 | busmaster_free(s->recbuf,RME96xx_DMA_MAX_SIZE_ALL); | ||
1058 | busmaster_free(s->playbuf,RME96xx_DMA_MAX_SIZE_ALL); | ||
1059 | kfree(s); | ||
1060 | pci_set_drvdata(dev, NULL); | ||
1061 | } | ||
1062 | |||
1063 | |||
1064 | #ifndef PCI_VENDOR_ID_RME | ||
1065 | #define PCI_VENDOR_ID_RME 0x10ee | ||
1066 | #endif | ||
1067 | #ifndef PCI_DEVICE_ID_RME9652 | ||
1068 | #define PCI_DEVICE_ID_RME9652 0x3fc4 | ||
1069 | #endif | ||
1070 | #ifndef PCI_ANY_ID | ||
1071 | #define PCI_ANY_ID 0 | ||
1072 | #endif | ||
1073 | |||
1074 | static struct pci_device_id id_table[] = { | ||
1075 | { | ||
1076 | .vendor = PCI_VENDOR_ID_RME, | ||
1077 | .device = PCI_DEVICE_ID_RME9652, | ||
1078 | .subvendor = PCI_ANY_ID, | ||
1079 | .subdevice = PCI_ANY_ID, | ||
1080 | }, | ||
1081 | { 0, }, | ||
1082 | }; | ||
1083 | |||
1084 | MODULE_DEVICE_TABLE(pci, id_table); | ||
1085 | |||
1086 | static struct pci_driver rme96xx_driver = { | ||
1087 | .name = "rme96xx", | ||
1088 | .id_table = id_table, | ||
1089 | .probe = rme96xx_probe, | ||
1090 | .remove = __devexit_p(rme96xx_remove), | ||
1091 | }; | ||
1092 | |||
1093 | static int __init init_rme96xx(void) | ||
1094 | { | ||
1095 | printk(KERN_INFO RME_MESS" version "RMEVERSION" time " __TIME__ " " __DATE__ "\n"); | ||
1096 | devices = ((devices-1) & RME96xx_MASK_DEVS) + 1; | ||
1097 | printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices); | ||
1098 | numcards = 0; | ||
1099 | return pci_register_driver(&rme96xx_driver); | ||
1100 | } | ||
1101 | |||
1102 | static void __exit cleanup_rme96xx(void) | ||
1103 | { | ||
1104 | printk(KERN_INFO RME_MESS" unloading\n"); | ||
1105 | pci_unregister_driver(&rme96xx_driver); | ||
1106 | } | ||
1107 | |||
1108 | module_init(init_rme96xx); | ||
1109 | module_exit(cleanup_rme96xx); | ||
1110 | |||
1111 | |||
1112 | |||
1113 | |||
1114 | |||
1115 | /*-------------------------------------------------------------------------- | ||
1116 | Implementation of file operations | ||
1117 | ---------------------------------------------------------------------------*/ | ||
1118 | |||
1119 | #define RME96xx_FMT (AFMT_S16_LE|AFMT_U8|AFMT_S32_BLOCKED) | ||
1120 | /* AFTM_U8 is not (yet?) supported ... HP20020201 */ | ||
1121 | |||
1122 | static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, unsigned long arg) | ||
1123 | { | ||
1124 | struct dmabuf * dma = (struct dmabuf *)file->private_data; | ||
1125 | rme96xx_info *s = dma->s; | ||
1126 | unsigned long flags; | ||
1127 | audio_buf_info abinfo; | ||
1128 | count_info cinfo; | ||
1129 | int count; | ||
1130 | int val = 0; | ||
1131 | void __user *argp = (void __user *)arg; | ||
1132 | int __user *p = argp; | ||
1133 | |||
1134 | VALIDATE_STATE(s); | ||
1135 | |||
1136 | DBG(printk("ioctl %ud\n",cmd)); | ||
1137 | |||
1138 | switch (cmd) { | ||
1139 | case OSS_GETVERSION: | ||
1140 | return put_user(SOUND_VERSION, p); | ||
1141 | |||
1142 | case SNDCTL_DSP_SYNC: | ||
1143 | #if 0 | ||
1144 | if (file->f_mode & FMODE_WRITE) | ||
1145 | return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/); | ||
1146 | #endif | ||
1147 | return 0; | ||
1148 | |||
1149 | case SNDCTL_DSP_SETDUPLEX: | ||
1150 | return 0; | ||
1151 | |||
1152 | case SNDCTL_DSP_GETCAPS: | ||
1153 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); | ||
1154 | |||
1155 | case SNDCTL_DSP_RESET: | ||
1156 | // rme96xx_clearbufs(dma); | ||
1157 | return 0; | ||
1158 | |||
1159 | case SNDCTL_DSP_SPEED: | ||
1160 | if (get_user(val, p)) | ||
1161 | return -EFAULT; | ||
1162 | if (val >= 0) { | ||
1163 | /* generally it's not a problem if we change the speed | ||
1164 | if (dma->open_mode & (~file->f_mode) & (FMODE_READ|FMODE_WRITE)) | ||
1165 | return -EINVAL; | ||
1166 | */ | ||
1167 | spin_lock_irqsave(&s->lock, flags); | ||
1168 | |||
1169 | switch (val) { | ||
1170 | case 44100: | ||
1171 | case 88200: | ||
1172 | rme96xx_unset_ctrl(s,RME96xx_freq); | ||
1173 | break; | ||
1174 | case 48000: | ||
1175 | case 96000: | ||
1176 | rme96xx_set_ctrl(s,RME96xx_freq); | ||
1177 | break; | ||
1178 | /* just report current rate as default | ||
1179 | e.g. use 0 to "select" current digital input rate | ||
1180 | default: | ||
1181 | rme96xx_unset_ctrl(s,RME96xx_freq); | ||
1182 | val = 44100; | ||
1183 | */ | ||
1184 | } | ||
1185 | if (val > 50000) | ||
1186 | rme96xx_set_ctrl(s,RME96xx_DS); | ||
1187 | else | ||
1188 | rme96xx_unset_ctrl(s,RME96xx_DS); | ||
1189 | /* set val to actual value HP 20020201 */ | ||
1190 | /* NOTE: if not "Sync Master", reported rate might be not yet "updated" ... but I don't want to insert a long udelay() here */ | ||
1191 | if ((s->control_register & RME96xx_Master) && !(s->control_register & RME96xx_wsel)) | ||
1192 | val = rme96xx_get_sample_rate_ctrl(s); | ||
1193 | else | ||
1194 | val = rme96xx_get_sample_rate_status(s); | ||
1195 | s->rate = val; | ||
1196 | spin_unlock_irqrestore(&s->lock, flags); | ||
1197 | } | ||
1198 | DBG(printk("speed set to %d\n",val)); | ||
1199 | return put_user(val, p); | ||
1200 | |||
1201 | case SNDCTL_DSP_STEREO: /* this plays a mono file on two channels */ | ||
1202 | if (get_user(val, p)) | ||
1203 | return -EFAULT; | ||
1204 | |||
1205 | if (!val) { | ||
1206 | DBG(printk("setting to mono\n")); | ||
1207 | dma->mono=1; | ||
1208 | dma->inchannels = 1; | ||
1209 | dma->outchannels = 1; | ||
1210 | } | ||
1211 | else { | ||
1212 | DBG(printk("setting to stereo\n")); | ||
1213 | dma->mono = 0; | ||
1214 | dma->inchannels = 2; | ||
1215 | dma->outchannels = 2; | ||
1216 | } | ||
1217 | return 0; | ||
1218 | case SNDCTL_DSP_CHANNELS: | ||
1219 | /* remember to check for resonable offset/channel pairs here */ | ||
1220 | if (get_user(val, p)) | ||
1221 | return -EFAULT; | ||
1222 | |||
1223 | if (file->f_mode & FMODE_WRITE) { | ||
1224 | if (val > 0 && (dma->outoffset + val) <= RME96xx_CHANNELS_PER_CARD) | ||
1225 | dma->outchannels = val; | ||
1226 | else | ||
1227 | dma->outchannels = val = 2; | ||
1228 | DBG(printk("setting to outchannels %d\n",val)); | ||
1229 | } | ||
1230 | if (file->f_mode & FMODE_READ) { | ||
1231 | if (val > 0 && (dma->inoffset + val) <= RME96xx_CHANNELS_PER_CARD) | ||
1232 | dma->inchannels = val; | ||
1233 | else | ||
1234 | dma->inchannels = val = 2; | ||
1235 | DBG(printk("setting to inchannels %d\n",val)); | ||
1236 | } | ||
1237 | |||
1238 | dma->mono=0; | ||
1239 | |||
1240 | return put_user(val, p); | ||
1241 | |||
1242 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
1243 | return put_user(RME96xx_FMT, p); | ||
1244 | |||
1245 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
1246 | DBG(printk("setting to format %x\n",val)); | ||
1247 | if (get_user(val, p)) | ||
1248 | return -EFAULT; | ||
1249 | if (val != AFMT_QUERY) { | ||
1250 | if (val & RME96xx_FMT) | ||
1251 | dma->format = val; | ||
1252 | switch (dma->format) { | ||
1253 | case AFMT_S16_LE: | ||
1254 | dma->formatshift=1; | ||
1255 | break; | ||
1256 | case AFMT_S32_BLOCKED: | ||
1257 | dma->formatshift=0; | ||
1258 | break; | ||
1259 | } | ||
1260 | } | ||
1261 | return put_user(dma->format, p); | ||
1262 | |||
1263 | case SNDCTL_DSP_POST: | ||
1264 | return 0; | ||
1265 | |||
1266 | case SNDCTL_DSP_GETTRIGGER: | ||
1267 | val = 0; | ||
1268 | #if 0 | ||
1269 | if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) | ||
1270 | val |= PCM_ENABLE_INPUT; | ||
1271 | if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) | ||
1272 | val |= PCM_ENABLE_OUTPUT; | ||
1273 | #endif | ||
1274 | return put_user(val, p); | ||
1275 | |||
1276 | case SNDCTL_DSP_SETTRIGGER: | ||
1277 | if (get_user(val, p)) | ||
1278 | return -EFAULT; | ||
1279 | #if 0 | ||
1280 | if (file->f_mode & FMODE_READ) { | ||
1281 | if (val & PCM_ENABLE_INPUT) { | ||
1282 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | ||
1283 | return ret; | ||
1284 | start_adc(s); | ||
1285 | } else | ||
1286 | stop_adc(s); | ||
1287 | } | ||
1288 | if (file->f_mode & FMODE_WRITE) { | ||
1289 | if (val & PCM_ENABLE_OUTPUT) { | ||
1290 | if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) | ||
1291 | return ret; | ||
1292 | start_dac2(s); | ||
1293 | } else | ||
1294 | stop_dac2(s); | ||
1295 | } | ||
1296 | #endif | ||
1297 | return 0; | ||
1298 | |||
1299 | case SNDCTL_DSP_GETOSPACE: | ||
1300 | if (!(file->f_mode & FMODE_WRITE)) | ||
1301 | return -EINVAL; | ||
1302 | |||
1303 | val = rme96xx_gethwptr(dma->s,0); | ||
1304 | |||
1305 | |||
1306 | count = rme96xx_getospace(dma,val); | ||
1307 | if (!s->started) count = s->fragsize*2; | ||
1308 | abinfo.fragsize =(s->fragsize*dma->outchannels)>>dma->formatshift; | ||
1309 | abinfo.bytes = (count*dma->outchannels)>>dma->formatshift; | ||
1310 | abinfo.fragstotal = 2; | ||
1311 | abinfo.fragments = (count > s->fragsize); | ||
1312 | |||
1313 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1314 | |||
1315 | case SNDCTL_DSP_GETISPACE: | ||
1316 | if (!(file->f_mode & FMODE_READ)) | ||
1317 | return -EINVAL; | ||
1318 | |||
1319 | val = rme96xx_gethwptr(dma->s,0); | ||
1320 | |||
1321 | count = rme96xx_getispace(dma,val); | ||
1322 | |||
1323 | abinfo.fragsize = (s->fragsize*dma->inchannels)>>dma->formatshift; | ||
1324 | abinfo.bytes = (count*dma->inchannels)>>dma->formatshift; | ||
1325 | abinfo.fragstotal = 2; | ||
1326 | abinfo.fragments = count > s->fragsize; | ||
1327 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1328 | |||
1329 | case SNDCTL_DSP_NONBLOCK: | ||
1330 | file->f_flags |= O_NONBLOCK; | ||
1331 | return 0; | ||
1332 | |||
1333 | case SNDCTL_DSP_GETODELAY: /* What should this exactly do ? , | ||
1334 | ATM it is just abinfo.bytes */ | ||
1335 | if (!(file->f_mode & FMODE_WRITE)) | ||
1336 | return -EINVAL; | ||
1337 | |||
1338 | val = rme96xx_gethwptr(dma->s,0); | ||
1339 | count = val - dma->readptr; | ||
1340 | if (count < 0) | ||
1341 | count += s->fragsize<<1; | ||
1342 | |||
1343 | return put_user(count, p); | ||
1344 | |||
1345 | |||
1346 | /* check out how to use mmaped mode (can only be blocked !!!) */ | ||
1347 | case SNDCTL_DSP_GETIPTR: | ||
1348 | if (!(file->f_mode & FMODE_READ)) | ||
1349 | return -EINVAL; | ||
1350 | val = rme96xx_gethwptr(dma->s,0); | ||
1351 | spin_lock_irqsave(&s->lock,flags); | ||
1352 | cinfo.bytes = s->fragsize<<1; | ||
1353 | count = val - dma->readptr; | ||
1354 | if (count < 0) | ||
1355 | count += s->fragsize<<1; | ||
1356 | |||
1357 | cinfo.blocks = (count > s->fragsize); | ||
1358 | cinfo.ptr = val; | ||
1359 | if (dma->mmapped) | ||
1360 | dma->readptr &= s->fragsize<<1; | ||
1361 | spin_unlock_irqrestore(&s->lock,flags); | ||
1362 | |||
1363 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1364 | return -EFAULT; | ||
1365 | return 0; | ||
1366 | |||
1367 | case SNDCTL_DSP_GETOPTR: | ||
1368 | if (!(file->f_mode & FMODE_READ)) | ||
1369 | return -EINVAL; | ||
1370 | val = rme96xx_gethwptr(dma->s,0); | ||
1371 | spin_lock_irqsave(&s->lock,flags); | ||
1372 | cinfo.bytes = s->fragsize<<1; | ||
1373 | count = val - dma->writeptr; | ||
1374 | if (count < 0) | ||
1375 | count += s->fragsize<<1; | ||
1376 | |||
1377 | cinfo.blocks = (count > s->fragsize); | ||
1378 | cinfo.ptr = val; | ||
1379 | if (dma->mmapped) | ||
1380 | dma->writeptr &= s->fragsize<<1; | ||
1381 | spin_unlock_irqrestore(&s->lock,flags); | ||
1382 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1383 | return -EFAULT; | ||
1384 | return 0; | ||
1385 | case SNDCTL_DSP_GETBLKSIZE: | ||
1386 | return put_user(s->fragsize, p); | ||
1387 | |||
1388 | case SNDCTL_DSP_SETFRAGMENT: | ||
1389 | if (get_user(val, p)) | ||
1390 | return -EFAULT; | ||
1391 | val&=0xffff; | ||
1392 | val -= 7; | ||
1393 | if (val < 0) val = 0; | ||
1394 | if (val > 7) val = 7; | ||
1395 | rme96xx_setlatency(s,val); | ||
1396 | return 0; | ||
1397 | |||
1398 | case SNDCTL_DSP_SUBDIVIDE: | ||
1399 | #if 0 | ||
1400 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
1401 | (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision)) | ||
1402 | return -EINVAL; | ||
1403 | if (get_user(val, p)) | ||
1404 | return -EFAULT; | ||
1405 | if (val != 1 && val != 2 && val != 4) | ||
1406 | return -EINVAL; | ||
1407 | if (file->f_mode & FMODE_READ) | ||
1408 | s->dma_adc.subdivision = val; | ||
1409 | if (file->f_mode & FMODE_WRITE) | ||
1410 | s->dma_dac2.subdivision = val; | ||
1411 | #endif | ||
1412 | return 0; | ||
1413 | |||
1414 | case SOUND_PCM_READ_RATE: | ||
1415 | /* HP20020201 */ | ||
1416 | s->rate = rme96xx_get_sample_rate_status(s); | ||
1417 | return put_user(s->rate, p); | ||
1418 | |||
1419 | case SOUND_PCM_READ_CHANNELS: | ||
1420 | return put_user(dma->outchannels, p); | ||
1421 | |||
1422 | case SOUND_PCM_READ_BITS: | ||
1423 | switch (dma->format) { | ||
1424 | case AFMT_S32_BLOCKED: | ||
1425 | val = 32; | ||
1426 | break; | ||
1427 | case AFMT_S16_LE: | ||
1428 | val = 16; | ||
1429 | break; | ||
1430 | } | ||
1431 | return put_user(val, p); | ||
1432 | |||
1433 | case SOUND_PCM_WRITE_FILTER: | ||
1434 | case SNDCTL_DSP_SETSYNCRO: | ||
1435 | case SOUND_PCM_READ_FILTER: | ||
1436 | return -EINVAL; | ||
1437 | |||
1438 | } | ||
1439 | |||
1440 | |||
1441 | return -ENODEV; | ||
1442 | } | ||
1443 | |||
1444 | |||
1445 | |||
1446 | static int rme96xx_open(struct inode *in, struct file *f) | ||
1447 | { | ||
1448 | int minor = iminor(in); | ||
1449 | struct list_head *list; | ||
1450 | int devnum; | ||
1451 | rme96xx_info *s; | ||
1452 | struct dmabuf* dma; | ||
1453 | DECLARE_WAITQUEUE(wait, current); | ||
1454 | |||
1455 | DBG(printk("device num %d open\n",devnum)); | ||
1456 | |||
1457 | nonseekable_open(in, f); | ||
1458 | for (list = devs.next; ; list = list->next) { | ||
1459 | if (list == &devs) | ||
1460 | return -ENODEV; | ||
1461 | s = list_entry(list, rme96xx_info, devs); | ||
1462 | for (devnum=0; devnum<devices; devnum++) | ||
1463 | if (!((s->dspnum[devnum] ^ minor) & ~0xf)) | ||
1464 | break; | ||
1465 | if (devnum<devices) | ||
1466 | break; | ||
1467 | } | ||
1468 | VALIDATE_STATE(s); | ||
1469 | |||
1470 | dma = &s->dma[devnum]; | ||
1471 | f->private_data = dma; | ||
1472 | /* wait for device to become free */ | ||
1473 | mutex_lock(&dma->open_mutex); | ||
1474 | while (dma->open_mode & f->f_mode) { | ||
1475 | if (f->f_flags & O_NONBLOCK) { | ||
1476 | mutex_unlock(&dma->open_mutex); | ||
1477 | return -EBUSY; | ||
1478 | } | ||
1479 | add_wait_queue(&dma->open_wait, &wait); | ||
1480 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1481 | mutex_unlock(&dma->open_mutex); | ||
1482 | schedule(); | ||
1483 | remove_wait_queue(&dma->open_wait, &wait); | ||
1484 | set_current_state(TASK_RUNNING); | ||
1485 | if (signal_pending(current)) | ||
1486 | return -ERESTARTSYS; | ||
1487 | mutex_lock(&dma->open_mutex); | ||
1488 | } | ||
1489 | |||
1490 | COMM ("hardware open") | ||
1491 | |||
1492 | if (!dma->opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset); | ||
1493 | |||
1494 | dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE)); | ||
1495 | dma->opened = 1; | ||
1496 | mutex_unlock(&dma->open_mutex); | ||
1497 | |||
1498 | DBG(printk("device num %d open finished\n",devnum)); | ||
1499 | return 0; | ||
1500 | } | ||
1501 | |||
1502 | static int rme96xx_release(struct inode *in, struct file *file) | ||
1503 | { | ||
1504 | struct dmabuf * dma = (struct dmabuf*) file->private_data; | ||
1505 | /* int hwp; ... was unused HP20020201 */ | ||
1506 | DBG(printk("%s\n", __FUNCTION__)); | ||
1507 | |||
1508 | COMM ("draining") | ||
1509 | if (dma->open_mode & FMODE_WRITE) { | ||
1510 | #if 0 /* Why doesn't this work with some cards ?? */ | ||
1511 | hwp = rme96xx_gethwptr(dma->s,0); | ||
1512 | while (rme96xx_getospace(dma,hwp)) { | ||
1513 | interruptible_sleep_on(&(dma->wait)); | ||
1514 | hwp = rme96xx_gethwptr(dma->s,0); | ||
1515 | } | ||
1516 | #endif | ||
1517 | rme96xx_clearbufs(dma); | ||
1518 | } | ||
1519 | |||
1520 | dma->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); | ||
1521 | |||
1522 | if (!(dma->open_mode & (FMODE_READ|FMODE_WRITE))) { | ||
1523 | dma->opened = 0; | ||
1524 | if (dma->s->started) rme96xx_startcard(dma->s,1); | ||
1525 | } | ||
1526 | |||
1527 | wake_up(&dma->open_wait); | ||
1528 | mutex_unlock(&dma->open_mutex); | ||
1529 | |||
1530 | return 0; | ||
1531 | } | ||
1532 | |||
1533 | |||
1534 | static ssize_t rme96xx_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1535 | { | ||
1536 | struct dmabuf *dma = (struct dmabuf *)file->private_data; | ||
1537 | ssize_t ret = 0; | ||
1538 | int cnt; /* number of bytes from "buffer" that will/can be used */ | ||
1539 | int hop = count/dma->outchannels; | ||
1540 | int hwp; | ||
1541 | int exact = (file->f_flags & O_NONBLOCK); | ||
1542 | |||
1543 | |||
1544 | if(dma == NULL || (dma->s) == NULL) | ||
1545 | return -ENXIO; | ||
1546 | |||
1547 | if (dma->mmapped || !dma->opened) | ||
1548 | return -ENXIO; | ||
1549 | |||
1550 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1551 | return -EFAULT; | ||
1552 | |||
1553 | if (! (dma->open_mode & FMODE_WRITE)) | ||
1554 | return -ENXIO; | ||
1555 | |||
1556 | if (!dma->s->started) rme96xx_startcard(dma->s,exact); | ||
1557 | hwp = rme96xx_gethwptr(dma->s,0); | ||
1558 | |||
1559 | if(!(dma->started)){ | ||
1560 | COMM ("first write") | ||
1561 | |||
1562 | dma->readptr = hwp; | ||
1563 | dma->writeptr = hwp; | ||
1564 | dma->started = 1; | ||
1565 | } | ||
1566 | |||
1567 | while (count > 0) { | ||
1568 | cnt = rme96xx_getospace(dma,hwp); | ||
1569 | cnt>>=dma->formatshift; | ||
1570 | cnt*=dma->outchannels; | ||
1571 | if (cnt > count) | ||
1572 | cnt = count; | ||
1573 | |||
1574 | if (cnt != 0) { | ||
1575 | if (rme96xx_copyfromuser(dma,buffer,cnt,hop)) | ||
1576 | return ret ? ret : -EFAULT; | ||
1577 | count -= cnt; | ||
1578 | buffer += cnt; | ||
1579 | ret += cnt; | ||
1580 | if (count == 0) return ret; | ||
1581 | } | ||
1582 | if (file->f_flags & O_NONBLOCK) | ||
1583 | return ret ? ret : -EAGAIN; | ||
1584 | |||
1585 | if ((hwp - dma->writeptr) <= 0) { | ||
1586 | interruptible_sleep_on(&(dma->wait)); | ||
1587 | |||
1588 | if (signal_pending(current)) | ||
1589 | return ret ? ret : -ERESTARTSYS; | ||
1590 | } | ||
1591 | |||
1592 | hwp = rme96xx_gethwptr(dma->s,exact); | ||
1593 | |||
1594 | }; /* count > 0 */ | ||
1595 | |||
1596 | return ret; | ||
1597 | } | ||
1598 | |||
1599 | static ssize_t rme96xx_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1600 | { | ||
1601 | struct dmabuf *dma = (struct dmabuf *)file->private_data; | ||
1602 | ssize_t ret = 0; | ||
1603 | int cnt; /* number of bytes from "buffer" that will/can be used */ | ||
1604 | int hop = count/dma->inchannels; | ||
1605 | int hwp; | ||
1606 | int exact = (file->f_flags & O_NONBLOCK); | ||
1607 | |||
1608 | |||
1609 | if(dma == NULL || (dma->s) == NULL) | ||
1610 | return -ENXIO; | ||
1611 | |||
1612 | if (dma->mmapped || !dma->opened) | ||
1613 | return -ENXIO; | ||
1614 | |||
1615 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1616 | return -EFAULT; | ||
1617 | |||
1618 | if (! (dma->open_mode & FMODE_READ)) | ||
1619 | return -ENXIO; | ||
1620 | |||
1621 | if (!dma->s->started) rme96xx_startcard(dma->s,exact); | ||
1622 | hwp = rme96xx_gethwptr(dma->s,0); | ||
1623 | |||
1624 | if(!(dma->started)){ | ||
1625 | COMM ("first read") | ||
1626 | |||
1627 | dma->writeptr = hwp; | ||
1628 | dma->readptr = hwp; | ||
1629 | dma->started = 1; | ||
1630 | } | ||
1631 | |||
1632 | while (count > 0) { | ||
1633 | cnt = rme96xx_getispace(dma,hwp); | ||
1634 | cnt>>=dma->formatshift; | ||
1635 | cnt*=dma->inchannels; | ||
1636 | |||
1637 | if (cnt > count) | ||
1638 | cnt = count; | ||
1639 | |||
1640 | if (cnt != 0) { | ||
1641 | |||
1642 | if (rme96xx_copytouser(dma,buffer,cnt,hop)) | ||
1643 | return ret ? ret : -EFAULT; | ||
1644 | |||
1645 | count -= cnt; | ||
1646 | buffer += cnt; | ||
1647 | ret += cnt; | ||
1648 | if (count == 0) return ret; | ||
1649 | } | ||
1650 | if (file->f_flags & O_NONBLOCK) | ||
1651 | return ret ? ret : -EAGAIN; | ||
1652 | |||
1653 | if ((hwp - dma->readptr) <= 0) { | ||
1654 | interruptible_sleep_on(&(dma->wait)); | ||
1655 | |||
1656 | if (signal_pending(current)) | ||
1657 | return ret ? ret : -ERESTARTSYS; | ||
1658 | } | ||
1659 | hwp = rme96xx_gethwptr(dma->s,exact); | ||
1660 | |||
1661 | }; /* count > 0 */ | ||
1662 | |||
1663 | return ret; | ||
1664 | } | ||
1665 | |||
1666 | static int rm96xx_mmap(struct file *file, struct vm_area_struct *vma) { | ||
1667 | struct dmabuf *dma = (struct dmabuf *)file->private_data; | ||
1668 | rme96xx_info* s = dma->s; | ||
1669 | unsigned long size; | ||
1670 | |||
1671 | VALIDATE_STATE(s); | ||
1672 | lock_kernel(); | ||
1673 | |||
1674 | if (vma->vm_pgoff != 0) { | ||
1675 | unlock_kernel(); | ||
1676 | return -EINVAL; | ||
1677 | } | ||
1678 | size = vma->vm_end - vma->vm_start; | ||
1679 | if (size > RME96xx_DMA_MAX_SIZE) { | ||
1680 | unlock_kernel(); | ||
1681 | return -EINVAL; | ||
1682 | } | ||
1683 | |||
1684 | |||
1685 | if (vma->vm_flags & VM_WRITE) { | ||
1686 | if (!s->started) rme96xx_startcard(s,1); | ||
1687 | |||
1688 | if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->outoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) { | ||
1689 | unlock_kernel(); | ||
1690 | return -EAGAIN; | ||
1691 | } | ||
1692 | } | ||
1693 | else if (vma->vm_flags & VM_READ) { | ||
1694 | if (!s->started) rme96xx_startcard(s,1); | ||
1695 | if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(s->playbuf + dma->inoffset*RME96xx_DMA_MAX_SIZE) >> PAGE_SHIFT, size, vma->vm_page_prot)) { | ||
1696 | unlock_kernel(); | ||
1697 | return -EAGAIN; | ||
1698 | } | ||
1699 | } else { | ||
1700 | unlock_kernel(); | ||
1701 | return -EINVAL; | ||
1702 | } | ||
1703 | |||
1704 | |||
1705 | /* this is the mapping */ | ||
1706 | vma->vm_flags &= ~VM_IO; | ||
1707 | dma->mmapped = 1; | ||
1708 | unlock_kernel(); | ||
1709 | return 0; | ||
1710 | } | ||
1711 | |||
1712 | static unsigned int rme96xx_poll(struct file *file, struct poll_table_struct *wait) | ||
1713 | { | ||
1714 | struct dmabuf *dma = (struct dmabuf *)file->private_data; | ||
1715 | rme96xx_info* s = dma->s; | ||
1716 | unsigned int mask = 0; | ||
1717 | unsigned int hwp,cnt; | ||
1718 | |||
1719 | DBG(printk("rme96xx poll_wait ...\n")); | ||
1720 | VALIDATE_STATE(s); | ||
1721 | |||
1722 | if (!s->started) { | ||
1723 | mask |= POLLOUT | POLLWRNORM; | ||
1724 | } | ||
1725 | poll_wait(file, &dma->wait, wait); | ||
1726 | |||
1727 | hwp = rme96xx_gethwptr(dma->s,0); | ||
1728 | |||
1729 | DBG(printk("rme96xx poll: ..cnt %d > %d\n",cnt,s->fragsize)); | ||
1730 | |||
1731 | cnt = rme96xx_getispace(dma,hwp); | ||
1732 | |||
1733 | if (file->f_mode & FMODE_READ) | ||
1734 | if (cnt > 0) | ||
1735 | mask |= POLLIN | POLLRDNORM; | ||
1736 | |||
1737 | |||
1738 | |||
1739 | cnt = rme96xx_getospace(dma,hwp); | ||
1740 | |||
1741 | if (file->f_mode & FMODE_WRITE) | ||
1742 | if (cnt > 0) | ||
1743 | mask |= POLLOUT | POLLWRNORM; | ||
1744 | |||
1745 | |||
1746 | // printk("rme96xx poll_wait ...%d > %d\n",rme96xx_getospace(dma,hwp),rme96xx_getispace(dma,hwp)); | ||
1747 | |||
1748 | return mask; | ||
1749 | } | ||
1750 | |||
1751 | |||
1752 | static struct file_operations rme96xx_audio_fops = { | ||
1753 | .owner = THIS_MODULE, | ||
1754 | .read = rme96xx_read, | ||
1755 | .write = rme96xx_write, | ||
1756 | .poll = rme96xx_poll, | ||
1757 | .ioctl = rme96xx_ioctl, | ||
1758 | .mmap = rm96xx_mmap, | ||
1759 | .open = rme96xx_open, | ||
1760 | .release = rme96xx_release | ||
1761 | }; | ||
1762 | |||
1763 | static int rme96xx_mixer_open(struct inode *inode, struct file *file) | ||
1764 | { | ||
1765 | int minor = iminor(inode); | ||
1766 | struct list_head *list; | ||
1767 | rme96xx_info *s; | ||
1768 | |||
1769 | COMM ("mixer open"); | ||
1770 | |||
1771 | nonseekable_open(inode, file); | ||
1772 | for (list = devs.next; ; list = list->next) { | ||
1773 | if (list == &devs) | ||
1774 | return -ENODEV; | ||
1775 | s = list_entry(list, rme96xx_info, devs); | ||
1776 | if (s->mixer== minor) | ||
1777 | break; | ||
1778 | } | ||
1779 | VALIDATE_STATE(s); | ||
1780 | file->private_data = s; | ||
1781 | |||
1782 | COMM ("mixer opened") | ||
1783 | return 0; | ||
1784 | } | ||
1785 | |||
1786 | static int rme96xx_mixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1787 | { | ||
1788 | rme96xx_info *s = (rme96xx_info *)file->private_data; | ||
1789 | u32 status; | ||
1790 | int spdifrate; | ||
1791 | void __user *argp = (void __user *)arg; | ||
1792 | int __user *p = argp; | ||
1793 | |||
1794 | status = readl(s->iobase + RME96xx_status_register); | ||
1795 | /* hack to convert rev 1.5 SPDIF rate to "crystalrate" format HP 20020201 */ | ||
1796 | rme96xx_spdif_sample_rate(s,&spdifrate); | ||
1797 | status = (status & ~RME96xx_F) | ((spdifrate<<22) & RME96xx_F); | ||
1798 | |||
1799 | VALIDATE_STATE(s); | ||
1800 | if (cmd == SOUND_MIXER_PRIVATE1) { | ||
1801 | rme_mixer mixer; | ||
1802 | if (copy_from_user(&mixer,argp,sizeof(mixer))) | ||
1803 | return -EFAULT; | ||
1804 | |||
1805 | mixer.devnr &= RME96xx_MASK_DEVS; | ||
1806 | if (mixer.devnr >= devices) | ||
1807 | mixer.devnr = devices-1; | ||
1808 | if (file->f_mode & FMODE_WRITE && !s->dma[mixer.devnr].opened) { | ||
1809 | /* modify only if device not open */ | ||
1810 | if (mixer.o_offset < 0) | ||
1811 | mixer.o_offset = 0; | ||
1812 | if (mixer.o_offset >= RME96xx_CHANNELS_PER_CARD) | ||
1813 | mixer.o_offset = RME96xx_CHANNELS_PER_CARD-1; | ||
1814 | if (mixer.i_offset < 0) | ||
1815 | mixer.i_offset = 0; | ||
1816 | if (mixer.i_offset >= RME96xx_CHANNELS_PER_CARD) | ||
1817 | mixer.i_offset = RME96xx_CHANNELS_PER_CARD-1; | ||
1818 | s->dma[mixer.devnr].outoffset = mixer.o_offset; | ||
1819 | s->dma[mixer.devnr].inoffset = mixer.i_offset; | ||
1820 | } | ||
1821 | |||
1822 | mixer.o_offset = s->dma[mixer.devnr].outoffset; | ||
1823 | mixer.i_offset = s->dma[mixer.devnr].inoffset; | ||
1824 | |||
1825 | return copy_to_user(argp, &mixer, sizeof(mixer)) ? -EFAULT : 0; | ||
1826 | } | ||
1827 | if (cmd == SOUND_MIXER_PRIVATE2) { | ||
1828 | return put_user(status, p); | ||
1829 | } | ||
1830 | if (cmd == SOUND_MIXER_PRIVATE3) { | ||
1831 | u32 control; | ||
1832 | if (copy_from_user(&control,argp,sizeof(control))) | ||
1833 | return -EFAULT; | ||
1834 | if (file->f_mode & FMODE_WRITE) { | ||
1835 | s->control_register &= ~RME96xx_mixer_allowed; | ||
1836 | s->control_register |= control & RME96xx_mixer_allowed; | ||
1837 | writel(control,s->iobase + RME96xx_control_register); | ||
1838 | } | ||
1839 | |||
1840 | return put_user(s->control_register, p); | ||
1841 | } | ||
1842 | return -1; | ||
1843 | } | ||
1844 | |||
1845 | |||
1846 | |||
1847 | static int rme96xx_mixer_release(struct inode *inode, struct file *file) | ||
1848 | { | ||
1849 | return 0; | ||
1850 | } | ||
1851 | |||
1852 | static /*const*/ struct file_operations rme96xx_mixer_fops = { | ||
1853 | .owner = THIS_MODULE, | ||
1854 | .ioctl = rme96xx_mixer_ioctl, | ||
1855 | .open = rme96xx_mixer_open, | ||
1856 | .release = rme96xx_mixer_release, | ||
1857 | }; | ||
diff --git a/sound/oss/rme96xx.h b/sound/oss/rme96xx.h deleted file mode 100644 index 7a3c188ea0a8..000000000000 --- a/sound/oss/rme96xx.h +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | /* (C) 2000 Guenter Geiger <geiger@debian.org> | ||
2 | with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at> | ||
3 | |||
4 | Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de> | ||
5 | HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c | ||
6 | HP20020201 completed? | ||
7 | |||
8 | A text/graphic control panel (rmectrl/xrmectrl) is available from | ||
9 | http://gige.xdv.org/pages/soft/pages/rme | ||
10 | */ | ||
11 | |||
12 | |||
13 | #ifndef AFMT_S32_BLOCKED | ||
14 | #define AFMT_S32_BLOCKED 0x0000400 | ||
15 | #endif | ||
16 | |||
17 | /* AFMT_S16_BLOCKED not yet supported */ | ||
18 | #ifndef AFMT_S16_BLOCKED | ||
19 | #define AFMT_S16_BLOCKED 0x0000800 | ||
20 | #endif | ||
21 | |||
22 | |||
23 | typedef struct rme_status { | ||
24 | unsigned int irq:1; | ||
25 | unsigned int lockmask:3; /* ADAT input PLLs locked */ | ||
26 | /* 100=ADAT1, 010=ADAT2, 001=ADAT3 */ | ||
27 | unsigned int sr48:1; /* sample rate: 0=44.1/88.2 1=48/96 kHz */ | ||
28 | unsigned int wclock:1; /* 1=wordclock used */ | ||
29 | unsigned int bufpoint:10; | ||
30 | unsigned int syncmask:3; /* ADAT input in sync with system clock */ | ||
31 | /* 100=ADAT1, 010=ADAT2, 001=ADAT3 */ | ||
32 | unsigned int doublespeed:1; /* sample rate: 0=44.1/48 1=88.2/96 kHz */ | ||
33 | unsigned int tc_busy:1; | ||
34 | unsigned int tc_out:1; | ||
35 | unsigned int crystalrate:3; /* spdif input sample rate: */ | ||
36 | /* 000=64kHz, 100=88.2kHz, 011=96kHz */ | ||
37 | /* 111=32kHz, 110=44.1kHz, 101=48kHz */ | ||
38 | unsigned int spdif_error:1; /* 1=no spdif lock */ | ||
39 | unsigned int bufid:1; | ||
40 | unsigned int tc_valid:1; /* 1=timecode input detected */ | ||
41 | unsigned int spdif_read:1; | ||
42 | } rme_status_t; | ||
43 | |||
44 | |||
45 | /* only fields marked W: can be modified by writing to SOUND_MIXER_PRIVATE3 */ | ||
46 | typedef struct rme_control { | ||
47 | unsigned int start:1; | ||
48 | unsigned int latency:3; /* buffer size / latency [samples]: */ | ||
49 | /* 0=64 ... 7=8192 */ | ||
50 | unsigned int master:1; /* W: clock mode: 1=master 0=slave/auto */ | ||
51 | unsigned int ie:1; | ||
52 | unsigned int sr48:1; /* samplerate 0=44.1/88.2, 1=48/96 kHz */ | ||
53 | unsigned int spare:1; | ||
54 | unsigned int doublespeed:1; /* double speed 0=44.1/48, 1=88.2/96 Khz */ | ||
55 | unsigned int pro:1; /* W: SPDIF-OUT 0=consumer, 1=professional */ | ||
56 | unsigned int emphasis:1; /* W: SPDIF-OUT emphasis 0=off, 1=on */ | ||
57 | unsigned int dolby:1; /* W: SPDIF-OUT non-audio bit 1=set, 0=unset */ | ||
58 | unsigned int opt_out:1; /* W: use 1st optical OUT as SPDIF: 1=yes, 0=no */ | ||
59 | unsigned int wordclock:1; /* W: use Wordclock as sync (overwrites master) */ | ||
60 | unsigned int spdif_in:2; /* W: SPDIF-IN: */ | ||
61 | /* 00=optical (ADAT1), 01=coaxial (Cinch), 10=internal CDROM */ | ||
62 | unsigned int sync_ref:2; /* W: preferred sync-source in autosync */ | ||
63 | /* 00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */ | ||
64 | unsigned int spdif_reset:1; | ||
65 | unsigned int spdif_select:1; | ||
66 | unsigned int spdif_clock:1; | ||
67 | unsigned int spdif_write:1; | ||
68 | unsigned int adat1_cd:1; /* W: Rev 1.5+: if set, internal CD connector carries ADAT */ | ||
69 | } rme_ctrl_t; | ||
70 | |||
71 | |||
72 | typedef struct _rme_mixer { | ||
73 | int i_offset; | ||
74 | int o_offset; | ||
75 | int devnr; | ||
76 | int spare[8]; | ||
77 | } rme_mixer; | ||
78 | |||
diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c index 0ce4e4ef6fe9..23922377250d 100644 --- a/sound/oss/sequencer.c +++ b/sound/oss/sequencer.c | |||
@@ -16,7 +16,6 @@ | |||
16 | */ | 16 | */ |
17 | #include <linux/kmod.h> | 17 | #include <linux/kmod.h> |
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | #define SEQUENCER_C | ||
20 | #include "sound_config.h" | 19 | #include "sound_config.h" |
21 | 20 | ||
22 | #include "midi_ctrl.h" | 21 | #include "midi_ctrl.h" |
diff --git a/sound/oss/sequencer_syms.c b/sound/oss/sequencer_syms.c index 5d008798c310..118525638bd3 100644 --- a/sound/oss/sequencer_syms.c +++ b/sound/oss/sequencer_syms.c | |||
@@ -20,10 +20,3 @@ EXPORT_SYMBOL(sound_timer_init); | |||
20 | EXPORT_SYMBOL(sound_timer_interrupt); | 20 | EXPORT_SYMBOL(sound_timer_interrupt); |
21 | EXPORT_SYMBOL(sound_timer_syncinterval); | 21 | EXPORT_SYMBOL(sound_timer_syncinterval); |
22 | 22 | ||
23 | /* Tuning */ | ||
24 | |||
25 | #define _SEQUENCER_C_ | ||
26 | #include "tuning.h" | ||
27 | |||
28 | EXPORT_SYMBOL(cent_tuning); | ||
29 | EXPORT_SYMBOL(semitone_tuning); | ||
diff --git a/sound/oss/sgalaxy.c b/sound/oss/sgalaxy.c deleted file mode 100644 index 0bcff6735319..000000000000 --- a/sound/oss/sgalaxy.c +++ /dev/null | |||
@@ -1,207 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/sgalaxy.c | ||
3 | * | ||
4 | * Low level driver for Aztech Sound Galaxy cards. | ||
5 | * Copyright 1998 Artur Skawina <skawina@geocities.com> | ||
6 | * | ||
7 | * Supported cards: | ||
8 | * Aztech Sound Galaxy Waverider Pro 32 - 3D | ||
9 | * Aztech Sound Galaxy Washington 16 | ||
10 | * | ||
11 | * Based on cs4232.c by Hannu Savolainen and Alan Cox. | ||
12 | * | ||
13 | * | ||
14 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
15 | * | ||
16 | * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
17 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
18 | * for more info. | ||
19 | * | ||
20 | * Changes: | ||
21 | * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> | ||
22 | * Added __init to sb_rst() and sb_cmd() | ||
23 | */ | ||
24 | |||
25 | #include <linux/init.h> | ||
26 | #include <linux/module.h> | ||
27 | |||
28 | #include "sound_config.h" | ||
29 | #include "ad1848.h" | ||
30 | |||
31 | static void sleep( unsigned howlong ) | ||
32 | { | ||
33 | current->state = TASK_INTERRUPTIBLE; | ||
34 | schedule_timeout(howlong); | ||
35 | } | ||
36 | |||
37 | #define DPORT 0x80 | ||
38 | |||
39 | /* Sound Blaster regs */ | ||
40 | |||
41 | #define SBDSP_RESET 0x6 | ||
42 | #define SBDSP_READ 0xA | ||
43 | #define SBDSP_COMMAND 0xC | ||
44 | #define SBDSP_STATUS SBDSP_COMMAND | ||
45 | #define SBDSP_DATA_AVAIL 0xE | ||
46 | |||
47 | static int __init sb_rst(int base) | ||
48 | { | ||
49 | int i; | ||
50 | |||
51 | outb( 1, base+SBDSP_RESET ); /* reset the DSP */ | ||
52 | outb( 0, base+SBDSP_RESET ); | ||
53 | |||
54 | for ( i=0; i<500; i++ ) /* delay */ | ||
55 | inb(DPORT); | ||
56 | |||
57 | for ( i=0; i<100000; i++ ) | ||
58 | { | ||
59 | if ( inb( base+SBDSP_DATA_AVAIL )&0x80 ) | ||
60 | break; | ||
61 | } | ||
62 | |||
63 | if ( inb( base+SBDSP_READ )!=0xAA ) | ||
64 | return 0; | ||
65 | |||
66 | return 1; | ||
67 | } | ||
68 | |||
69 | static int __init sb_cmd( int base, unsigned char val ) | ||
70 | { | ||
71 | int i; | ||
72 | |||
73 | for ( i=100000; i; i-- ) | ||
74 | { | ||
75 | if ( (inb( base+SBDSP_STATUS )&0x80)==0 ) | ||
76 | { | ||
77 | outb( val, base+SBDSP_COMMAND ); | ||
78 | break; | ||
79 | } | ||
80 | } | ||
81 | return i; /* i>0 == success */ | ||
82 | } | ||
83 | |||
84 | |||
85 | #define ai_sgbase driver_use_1 | ||
86 | |||
87 | static int __init probe_sgalaxy( struct address_info *ai ) | ||
88 | { | ||
89 | struct resource *ports; | ||
90 | int n; | ||
91 | |||
92 | if (!request_region(ai->io_base, 4, "WSS config")) { | ||
93 | printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | ports = request_region(ai->io_base + 4, 4, "ad1848"); | ||
98 | if (!ports) { | ||
99 | printk(KERN_ERR "sgalaxy: WSS IO port 0x%03x not available\n", ai->io_base); | ||
100 | release_region(ai->io_base, 4); | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | if (!request_region( ai->ai_sgbase, 0x10, "SoundGalaxy SB")) { | ||
105 | printk(KERN_ERR "sgalaxy: SB IO port 0x%03x not available\n", ai->ai_sgbase); | ||
106 | release_region(ai->io_base + 4, 4); | ||
107 | release_region(ai->io_base, 4); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | if (ad1848_detect(ports, NULL, ai->osp)) | ||
112 | goto out; /* The card is already active, check irq etc... */ | ||
113 | |||
114 | /* switch to MSS/WSS mode */ | ||
115 | |||
116 | sb_rst( ai->ai_sgbase ); | ||
117 | |||
118 | sb_cmd( ai->ai_sgbase, 9 ); | ||
119 | sb_cmd( ai->ai_sgbase, 0 ); | ||
120 | |||
121 | sleep( HZ/10 ); | ||
122 | |||
123 | out: | ||
124 | if (!probe_ms_sound(ai, ports)) { | ||
125 | release_region(ai->io_base + 4, 4); | ||
126 | release_region(ai->io_base, 4); | ||
127 | release_region(ai->ai_sgbase, 0x10); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | attach_ms_sound(ai, ports, THIS_MODULE); | ||
132 | n=ai->slots[0]; | ||
133 | |||
134 | if (n!=-1 && audio_devs[n]->mixer_dev != -1 ) { | ||
135 | AD1848_REROUTE( SOUND_MIXER_LINE1, SOUND_MIXER_LINE ); /* Line-in */ | ||
136 | AD1848_REROUTE( SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH ); /* FM+Wavetable*/ | ||
137 | AD1848_REROUTE( SOUND_MIXER_LINE3, SOUND_MIXER_CD ); /* CD */ | ||
138 | } | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | static void __exit unload_sgalaxy( struct address_info *ai ) | ||
143 | { | ||
144 | unload_ms_sound( ai ); | ||
145 | release_region( ai->ai_sgbase, 0x10 ); | ||
146 | } | ||
147 | |||
148 | static struct address_info cfg; | ||
149 | |||
150 | static int __initdata io = -1; | ||
151 | static int __initdata irq = -1; | ||
152 | static int __initdata dma = -1; | ||
153 | static int __initdata dma2 = -1; | ||
154 | static int __initdata sgbase = -1; | ||
155 | |||
156 | module_param(io, int, 0); | ||
157 | module_param(irq, int, 0); | ||
158 | module_param(dma, int, 0); | ||
159 | module_param(dma2, int, 0); | ||
160 | module_param(sgbase, int, 0); | ||
161 | |||
162 | static int __init init_sgalaxy(void) | ||
163 | { | ||
164 | cfg.io_base = io; | ||
165 | cfg.irq = irq; | ||
166 | cfg.dma = dma; | ||
167 | cfg.dma2 = dma2; | ||
168 | cfg.ai_sgbase = sgbase; | ||
169 | |||
170 | if (cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.ai_sgbase == -1 ) { | ||
171 | printk(KERN_ERR "sgalaxy: io, irq, dma and sgbase must be set.\n"); | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | |||
175 | if ( probe_sgalaxy(&cfg) == 0 ) | ||
176 | return -ENODEV; | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static void __exit cleanup_sgalaxy(void) | ||
182 | { | ||
183 | unload_sgalaxy(&cfg); | ||
184 | } | ||
185 | |||
186 | module_init(init_sgalaxy); | ||
187 | module_exit(cleanup_sgalaxy); | ||
188 | |||
189 | #ifndef MODULE | ||
190 | static int __init setup_sgalaxy(char *str) | ||
191 | { | ||
192 | /* io, irq, dma, dma2, sgbase */ | ||
193 | int ints[6]; | ||
194 | |||
195 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
196 | io = ints[1]; | ||
197 | irq = ints[2]; | ||
198 | dma = ints[3]; | ||
199 | dma2 = ints[4]; | ||
200 | sgbase = ints[5]; | ||
201 | |||
202 | return 1; | ||
203 | } | ||
204 | |||
205 | __setup("sgalaxy=", setup_sgalaxy); | ||
206 | #endif | ||
207 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c deleted file mode 100644 index 8ea532d40198..000000000000 --- a/sound/oss/sonicvibes.c +++ /dev/null | |||
@@ -1,2792 +0,0 @@ | |||
1 | /*****************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * sonicvibes.c -- S3 Sonic Vibes audio driver. | ||
5 | * | ||
6 | * Copyright (C) 1998-2001, 2003 Thomas Sailer (t.sailer@alumni.ethz.ch) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * Special thanks to David C. Niemi | ||
23 | * | ||
24 | * | ||
25 | * Module command line parameters: | ||
26 | * none so far | ||
27 | * | ||
28 | * | ||
29 | * Supported devices: | ||
30 | * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible | ||
31 | * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible | ||
32 | * /dev/midi simple MIDI UART interface, no ioctl | ||
33 | * | ||
34 | * The card has both an FM and a Wavetable synth, but I have to figure | ||
35 | * out first how to drive them... | ||
36 | * | ||
37 | * Revision history | ||
38 | * 06.05.1998 0.1 Initial release | ||
39 | * 10.05.1998 0.2 Fixed many bugs, esp. ADC rate calculation | ||
40 | * First stab at a simple midi interface (no bells&whistles) | ||
41 | * 13.05.1998 0.3 Fix stupid cut&paste error: set_adc_rate was called instead of | ||
42 | * set_dac_rate in the FMODE_WRITE case in sv_open | ||
43 | * Fix hwptr out of bounds (now mpg123 works) | ||
44 | * 14.05.1998 0.4 Don't allow excessive interrupt rates | ||
45 | * 08.06.1998 0.5 First release using Alan Cox' soundcore instead of miscdevice | ||
46 | * 03.08.1998 0.6 Do not include modversions.h | ||
47 | * Now mixer behaviour can basically be selected between | ||
48 | * "OSS documented" and "OSS actual" behaviour | ||
49 | * 31.08.1998 0.7 Fix realplayer problems - dac.count issues | ||
50 | * 10.12.1998 0.8 Fix drain_dac trying to wait on not yet initialized DMA | ||
51 | * 16.12.1998 0.9 Fix a few f_file & FMODE_ bugs | ||
52 | * 06.01.1999 0.10 remove the silly SA_INTERRUPT flag. | ||
53 | * hopefully killed the egcs section type conflict | ||
54 | * 12.03.1999 0.11 cinfo.blocks should be reset after GETxPTR ioctl. | ||
55 | * reported by Johan Maes <joma@telindus.be> | ||
56 | * 22.03.1999 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK | ||
57 | * read/write cannot be executed | ||
58 | * 05.04.1999 0.13 added code to sv_read and sv_write which should detect | ||
59 | * lockups of the sound chip and revive it. This is basically | ||
60 | * an ugly hack, but at least applications using this driver | ||
61 | * won't hang forever. I don't know why these lockups happen, | ||
62 | * it might well be the motherboard chipset (an early 486 PCI | ||
63 | * board with ALI chipset), since every busmastering 100MB | ||
64 | * ethernet card I've tried (Realtek 8139 and Macronix tulip clone) | ||
65 | * exhibit similar behaviour (they work for a couple of packets | ||
66 | * and then lock up and can be revived by ifconfig down/up). | ||
67 | * 07.04.1999 0.14 implemented the following ioctl's: SOUND_PCM_READ_RATE, | ||
68 | * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; | ||
69 | * Alpha fixes reported by Peter Jones <pjones@redhat.com> | ||
70 | * Note: dmaio hack might still be wrong on archs other than i386 | ||
71 | * 15.06.1999 0.15 Fix bad allocation bug. | ||
72 | * Thanks to Deti Fliegl <fliegl@in.tum.de> | ||
73 | * 28.06.1999 0.16 Add pci_set_master | ||
74 | * 03.08.1999 0.17 adapt to Linus' new __setup/__initcall | ||
75 | * added kernel command line options "sonicvibes=reverb" and "sonicvibesdmaio=dmaioaddr" | ||
76 | * 12.08.1999 0.18 module_init/__setup fixes | ||
77 | * 24.08.1999 0.19 get rid of the dmaio kludge, replace with allocate_resource | ||
78 | * 31.08.1999 0.20 add spin_lock_init | ||
79 | * use new resource allocation to allocate DDMA IO space | ||
80 | * replaced current->state = x with set_current_state(x) | ||
81 | * 03.09.1999 0.21 change read semantics for MIDI to match | ||
82 | * OSS more closely; remove possible wakeup race | ||
83 | * 28.10.1999 0.22 More waitqueue races fixed | ||
84 | * 01.12.1999 0.23 New argument to allocate_resource | ||
85 | * 07.12.1999 0.24 More allocate_resource semantics change | ||
86 | * 08.01.2000 0.25 Prevent some ioctl's from returning bad count values on underrun/overrun; | ||
87 | * Tim Janik's BSE (Bedevilled Sound Engine) found this | ||
88 | * use Martin Mares' pci_assign_resource | ||
89 | * 07.02.2000 0.26 Use pci_alloc_consistent and pci_register_driver | ||
90 | * 21.11.2000 0.27 Initialize dma buffers in poll, otherwise poll may return a bogus mask | ||
91 | * 12.12.2000 0.28 More dma buffer initializations, patch from | ||
92 | * Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com> | ||
93 | * 31.01.2001 0.29 Register/Unregister gameport | ||
94 | * Fix SETTRIGGER non OSS API conformity | ||
95 | * 18.05.2001 0.30 PCI probing and error values cleaned up by Marcus | ||
96 | * Meissner <mm@caldera.de> | ||
97 | * 03.01.2003 0.31 open_mode fixes from Georg Acher <acher@in.tum.de> | ||
98 | * | ||
99 | */ | ||
100 | |||
101 | /*****************************************************************************/ | ||
102 | |||
103 | #include <linux/module.h> | ||
104 | #include <linux/string.h> | ||
105 | #include <linux/ioport.h> | ||
106 | #include <linux/interrupt.h> | ||
107 | #include <linux/wait.h> | ||
108 | #include <linux/mm.h> | ||
109 | #include <linux/delay.h> | ||
110 | #include <linux/sound.h> | ||
111 | #include <linux/slab.h> | ||
112 | #include <linux/soundcard.h> | ||
113 | #include <linux/pci.h> | ||
114 | #include <linux/init.h> | ||
115 | #include <linux/poll.h> | ||
116 | #include <linux/spinlock.h> | ||
117 | #include <linux/smp_lock.h> | ||
118 | #include <linux/gameport.h> | ||
119 | #include <linux/dma-mapping.h> | ||
120 | #include <linux/mutex.h> | ||
121 | |||
122 | |||
123 | #include <asm/io.h> | ||
124 | #include <asm/uaccess.h> | ||
125 | |||
126 | #include "dm.h" | ||
127 | |||
128 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) | ||
129 | #define SUPPORT_JOYSTICK 1 | ||
130 | #endif | ||
131 | |||
132 | /* --------------------------------------------------------------------- */ | ||
133 | |||
134 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
135 | |||
136 | /* --------------------------------------------------------------------- */ | ||
137 | |||
138 | #ifndef PCI_VENDOR_ID_S3 | ||
139 | #define PCI_VENDOR_ID_S3 0x5333 | ||
140 | #endif | ||
141 | #ifndef PCI_DEVICE_ID_S3_SONICVIBES | ||
142 | #define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 | ||
143 | #endif | ||
144 | |||
145 | #define SV_MAGIC ((PCI_VENDOR_ID_S3<<16)|PCI_DEVICE_ID_S3_SONICVIBES) | ||
146 | |||
147 | #define SV_EXTENT_SB 0x10 | ||
148 | #define SV_EXTENT_ENH 0x10 | ||
149 | #define SV_EXTENT_SYNTH 0x4 | ||
150 | #define SV_EXTENT_MIDI 0x4 | ||
151 | #define SV_EXTENT_GAME 0x8 | ||
152 | #define SV_EXTENT_DMA 0x10 | ||
153 | |||
154 | /* | ||
155 | * we are not a bridge and thus use a resource for DDMA that is used for bridges but | ||
156 | * left empty for normal devices | ||
157 | */ | ||
158 | #define RESOURCE_SB 0 | ||
159 | #define RESOURCE_ENH 1 | ||
160 | #define RESOURCE_SYNTH 2 | ||
161 | #define RESOURCE_MIDI 3 | ||
162 | #define RESOURCE_GAME 4 | ||
163 | #define RESOURCE_DDMA 7 | ||
164 | |||
165 | #define SV_MIDI_DATA 0 | ||
166 | #define SV_MIDI_COMMAND 1 | ||
167 | #define SV_MIDI_STATUS 1 | ||
168 | |||
169 | #define SV_DMA_ADDR0 0 | ||
170 | #define SV_DMA_ADDR1 1 | ||
171 | #define SV_DMA_ADDR2 2 | ||
172 | #define SV_DMA_ADDR3 3 | ||
173 | #define SV_DMA_COUNT0 4 | ||
174 | #define SV_DMA_COUNT1 5 | ||
175 | #define SV_DMA_COUNT2 6 | ||
176 | #define SV_DMA_MODE 0xb | ||
177 | #define SV_DMA_RESET 0xd | ||
178 | #define SV_DMA_MASK 0xf | ||
179 | |||
180 | /* | ||
181 | * DONT reset the DMA controllers unless you understand | ||
182 | * the reset semantics. Assuming reset semantics as in | ||
183 | * the 8237 does not work. | ||
184 | */ | ||
185 | |||
186 | #define DMA_MODE_AUTOINIT 0x10 | ||
187 | #define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ | ||
188 | #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ | ||
189 | |||
190 | #define SV_CODEC_CONTROL 0 | ||
191 | #define SV_CODEC_INTMASK 1 | ||
192 | #define SV_CODEC_STATUS 2 | ||
193 | #define SV_CODEC_IADDR 4 | ||
194 | #define SV_CODEC_IDATA 5 | ||
195 | |||
196 | #define SV_CCTRL_RESET 0x80 | ||
197 | #define SV_CCTRL_INTADRIVE 0x20 | ||
198 | #define SV_CCTRL_WAVETABLE 0x08 | ||
199 | #define SV_CCTRL_REVERB 0x04 | ||
200 | #define SV_CCTRL_ENHANCED 0x01 | ||
201 | |||
202 | #define SV_CINTMASK_DMAA 0x01 | ||
203 | #define SV_CINTMASK_DMAC 0x04 | ||
204 | #define SV_CINTMASK_SPECIAL 0x08 | ||
205 | #define SV_CINTMASK_UPDOWN 0x40 | ||
206 | #define SV_CINTMASK_MIDI 0x80 | ||
207 | |||
208 | #define SV_CSTAT_DMAA 0x01 | ||
209 | #define SV_CSTAT_DMAC 0x04 | ||
210 | #define SV_CSTAT_SPECIAL 0x08 | ||
211 | #define SV_CSTAT_UPDOWN 0x40 | ||
212 | #define SV_CSTAT_MIDI 0x80 | ||
213 | |||
214 | #define SV_CIADDR_TRD 0x80 | ||
215 | #define SV_CIADDR_MCE 0x40 | ||
216 | |||
217 | /* codec indirect registers */ | ||
218 | #define SV_CIMIX_ADCINL 0x00 | ||
219 | #define SV_CIMIX_ADCINR 0x01 | ||
220 | #define SV_CIMIX_AUX1INL 0x02 | ||
221 | #define SV_CIMIX_AUX1INR 0x03 | ||
222 | #define SV_CIMIX_CDINL 0x04 | ||
223 | #define SV_CIMIX_CDINR 0x05 | ||
224 | #define SV_CIMIX_LINEINL 0x06 | ||
225 | #define SV_CIMIX_LINEINR 0x07 | ||
226 | #define SV_CIMIX_MICIN 0x08 | ||
227 | #define SV_CIMIX_SYNTHINL 0x0A | ||
228 | #define SV_CIMIX_SYNTHINR 0x0B | ||
229 | #define SV_CIMIX_AUX2INL 0x0C | ||
230 | #define SV_CIMIX_AUX2INR 0x0D | ||
231 | #define SV_CIMIX_ANALOGINL 0x0E | ||
232 | #define SV_CIMIX_ANALOGINR 0x0F | ||
233 | #define SV_CIMIX_PCMINL 0x10 | ||
234 | #define SV_CIMIX_PCMINR 0x11 | ||
235 | |||
236 | #define SV_CIGAMECONTROL 0x09 | ||
237 | #define SV_CIDATAFMT 0x12 | ||
238 | #define SV_CIENABLE 0x13 | ||
239 | #define SV_CIUPDOWN 0x14 | ||
240 | #define SV_CIREVISION 0x15 | ||
241 | #define SV_CIADCOUTPUT 0x16 | ||
242 | #define SV_CIDMAABASECOUNT1 0x18 | ||
243 | #define SV_CIDMAABASECOUNT0 0x19 | ||
244 | #define SV_CIDMACBASECOUNT1 0x1c | ||
245 | #define SV_CIDMACBASECOUNT0 0x1d | ||
246 | #define SV_CIPCMSR0 0x1e | ||
247 | #define SV_CIPCMSR1 0x1f | ||
248 | #define SV_CISYNTHSR0 0x20 | ||
249 | #define SV_CISYNTHSR1 0x21 | ||
250 | #define SV_CIADCCLKSOURCE 0x22 | ||
251 | #define SV_CIADCALTSR 0x23 | ||
252 | #define SV_CIADCPLLM 0x24 | ||
253 | #define SV_CIADCPLLN 0x25 | ||
254 | #define SV_CISYNTHPLLM 0x26 | ||
255 | #define SV_CISYNTHPLLN 0x27 | ||
256 | #define SV_CIUARTCONTROL 0x2a | ||
257 | #define SV_CIDRIVECONTROL 0x2b | ||
258 | #define SV_CISRSSPACE 0x2c | ||
259 | #define SV_CISRSCENTER 0x2d | ||
260 | #define SV_CIWAVETABLESRC 0x2e | ||
261 | #define SV_CIANALOGPWRDOWN 0x30 | ||
262 | #define SV_CIDIGITALPWRDOWN 0x31 | ||
263 | |||
264 | |||
265 | #define SV_CIMIX_ADCSRC_CD 0x20 | ||
266 | #define SV_CIMIX_ADCSRC_DAC 0x40 | ||
267 | #define SV_CIMIX_ADCSRC_AUX2 0x60 | ||
268 | #define SV_CIMIX_ADCSRC_LINE 0x80 | ||
269 | #define SV_CIMIX_ADCSRC_AUX1 0xa0 | ||
270 | #define SV_CIMIX_ADCSRC_MIC 0xc0 | ||
271 | #define SV_CIMIX_ADCSRC_MIXOUT 0xe0 | ||
272 | #define SV_CIMIX_ADCSRC_MASK 0xe0 | ||
273 | |||
274 | #define SV_CFMT_STEREO 0x01 | ||
275 | #define SV_CFMT_16BIT 0x02 | ||
276 | #define SV_CFMT_MASK 0x03 | ||
277 | #define SV_CFMT_ASHIFT 0 | ||
278 | #define SV_CFMT_CSHIFT 4 | ||
279 | |||
280 | static const unsigned sample_size[] = { 1, 2, 2, 4 }; | ||
281 | static const unsigned sample_shift[] = { 0, 1, 1, 2 }; | ||
282 | |||
283 | #define SV_CENABLE_PPE 0x4 | ||
284 | #define SV_CENABLE_RE 0x2 | ||
285 | #define SV_CENABLE_PE 0x1 | ||
286 | |||
287 | |||
288 | /* MIDI buffer sizes */ | ||
289 | |||
290 | #define MIDIINBUF 256 | ||
291 | #define MIDIOUTBUF 256 | ||
292 | |||
293 | #define FMODE_MIDI_SHIFT 2 | ||
294 | #define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) | ||
295 | #define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) | ||
296 | |||
297 | #define FMODE_DMFM 0x10 | ||
298 | |||
299 | /* --------------------------------------------------------------------- */ | ||
300 | |||
301 | struct sv_state { | ||
302 | /* magic */ | ||
303 | unsigned int magic; | ||
304 | |||
305 | /* list of sonicvibes devices */ | ||
306 | struct list_head devs; | ||
307 | |||
308 | /* the corresponding pci_dev structure */ | ||
309 | struct pci_dev *dev; | ||
310 | |||
311 | /* soundcore stuff */ | ||
312 | int dev_audio; | ||
313 | int dev_mixer; | ||
314 | int dev_midi; | ||
315 | int dev_dmfm; | ||
316 | |||
317 | /* hardware resources */ | ||
318 | unsigned long iosb, ioenh, iosynth, iomidi; /* long for SPARC */ | ||
319 | unsigned int iodmaa, iodmac, irq; | ||
320 | |||
321 | /* mixer stuff */ | ||
322 | struct { | ||
323 | unsigned int modcnt; | ||
324 | #ifndef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
325 | unsigned short vol[13]; | ||
326 | #endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ | ||
327 | } mix; | ||
328 | |||
329 | /* wave stuff */ | ||
330 | unsigned int rateadc, ratedac; | ||
331 | unsigned char fmt, enable; | ||
332 | |||
333 | spinlock_t lock; | ||
334 | struct mutex open_mutex; | ||
335 | mode_t open_mode; | ||
336 | wait_queue_head_t open_wait; | ||
337 | |||
338 | struct dmabuf { | ||
339 | void *rawbuf; | ||
340 | dma_addr_t dmaaddr; | ||
341 | unsigned buforder; | ||
342 | unsigned numfrag; | ||
343 | unsigned fragshift; | ||
344 | unsigned hwptr, swptr; | ||
345 | unsigned total_bytes; | ||
346 | int count; | ||
347 | unsigned error; /* over/underrun */ | ||
348 | wait_queue_head_t wait; | ||
349 | /* redundant, but makes calculations easier */ | ||
350 | unsigned fragsize; | ||
351 | unsigned dmasize; | ||
352 | unsigned fragsamples; | ||
353 | /* OSS stuff */ | ||
354 | unsigned mapped:1; | ||
355 | unsigned ready:1; | ||
356 | unsigned endcleared:1; | ||
357 | unsigned enabled:1; | ||
358 | unsigned ossfragshift; | ||
359 | int ossmaxfrags; | ||
360 | unsigned subdivision; | ||
361 | } dma_dac, dma_adc; | ||
362 | |||
363 | /* midi stuff */ | ||
364 | struct { | ||
365 | unsigned ird, iwr, icnt; | ||
366 | unsigned ord, owr, ocnt; | ||
367 | wait_queue_head_t iwait; | ||
368 | wait_queue_head_t owait; | ||
369 | struct timer_list timer; | ||
370 | unsigned char ibuf[MIDIINBUF]; | ||
371 | unsigned char obuf[MIDIOUTBUF]; | ||
372 | } midi; | ||
373 | |||
374 | #if SUPPORT_JOYSTICK | ||
375 | struct gameport *gameport; | ||
376 | #endif | ||
377 | }; | ||
378 | |||
379 | /* --------------------------------------------------------------------- */ | ||
380 | |||
381 | static LIST_HEAD(devs); | ||
382 | static unsigned long wavetable_mem; | ||
383 | |||
384 | /* --------------------------------------------------------------------- */ | ||
385 | |||
386 | static inline unsigned ld2(unsigned int x) | ||
387 | { | ||
388 | unsigned r = 0; | ||
389 | |||
390 | if (x >= 0x10000) { | ||
391 | x >>= 16; | ||
392 | r += 16; | ||
393 | } | ||
394 | if (x >= 0x100) { | ||
395 | x >>= 8; | ||
396 | r += 8; | ||
397 | } | ||
398 | if (x >= 0x10) { | ||
399 | x >>= 4; | ||
400 | r += 4; | ||
401 | } | ||
402 | if (x >= 4) { | ||
403 | x >>= 2; | ||
404 | r += 2; | ||
405 | } | ||
406 | if (x >= 2) | ||
407 | r++; | ||
408 | return r; | ||
409 | } | ||
410 | |||
411 | /* --------------------------------------------------------------------- */ | ||
412 | |||
413 | /* | ||
414 | * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver. | ||
415 | */ | ||
416 | |||
417 | #undef DMABYTEIO | ||
418 | |||
419 | static void set_dmaa(struct sv_state *s, unsigned int addr, unsigned int count) | ||
420 | { | ||
421 | #ifdef DMABYTEIO | ||
422 | unsigned io = s->iodmaa, u; | ||
423 | |||
424 | count--; | ||
425 | for (u = 4; u > 0; u--, addr >>= 8, io++) | ||
426 | outb(addr & 0xff, io); | ||
427 | for (u = 3; u > 0; u--, count >>= 8, io++) | ||
428 | outb(count & 0xff, io); | ||
429 | #else /* DMABYTEIO */ | ||
430 | count--; | ||
431 | outl(addr, s->iodmaa + SV_DMA_ADDR0); | ||
432 | outl(count, s->iodmaa + SV_DMA_COUNT0); | ||
433 | #endif /* DMABYTEIO */ | ||
434 | outb(0x18, s->iodmaa + SV_DMA_MODE); | ||
435 | } | ||
436 | |||
437 | static void set_dmac(struct sv_state *s, unsigned int addr, unsigned int count) | ||
438 | { | ||
439 | #ifdef DMABYTEIO | ||
440 | unsigned io = s->iodmac, u; | ||
441 | |||
442 | count >>= 1; | ||
443 | count--; | ||
444 | for (u = 4; u > 0; u--, addr >>= 8, io++) | ||
445 | outb(addr & 0xff, io); | ||
446 | for (u = 3; u > 0; u--, count >>= 8, io++) | ||
447 | outb(count & 0xff, io); | ||
448 | #else /* DMABYTEIO */ | ||
449 | count >>= 1; | ||
450 | count--; | ||
451 | outl(addr, s->iodmac + SV_DMA_ADDR0); | ||
452 | outl(count, s->iodmac + SV_DMA_COUNT0); | ||
453 | #endif /* DMABYTEIO */ | ||
454 | outb(0x14, s->iodmac + SV_DMA_MODE); | ||
455 | } | ||
456 | |||
457 | static inline unsigned get_dmaa(struct sv_state *s) | ||
458 | { | ||
459 | #ifdef DMABYTEIO | ||
460 | unsigned io = s->iodmaa+6, v = 0, u; | ||
461 | |||
462 | for (u = 3; u > 0; u--, io--) { | ||
463 | v <<= 8; | ||
464 | v |= inb(io); | ||
465 | } | ||
466 | return v + 1; | ||
467 | #else /* DMABYTEIO */ | ||
468 | return (inl(s->iodmaa + SV_DMA_COUNT0) & 0xffffff) + 1; | ||
469 | #endif /* DMABYTEIO */ | ||
470 | } | ||
471 | |||
472 | static inline unsigned get_dmac(struct sv_state *s) | ||
473 | { | ||
474 | #ifdef DMABYTEIO | ||
475 | unsigned io = s->iodmac+6, v = 0, u; | ||
476 | |||
477 | for (u = 3; u > 0; u--, io--) { | ||
478 | v <<= 8; | ||
479 | v |= inb(io); | ||
480 | } | ||
481 | return (v + 1) << 1; | ||
482 | #else /* DMABYTEIO */ | ||
483 | return ((inl(s->iodmac + SV_DMA_COUNT0) & 0xffffff) + 1) << 1; | ||
484 | #endif /* DMABYTEIO */ | ||
485 | } | ||
486 | |||
487 | static void wrindir(struct sv_state *s, unsigned char idx, unsigned char data) | ||
488 | { | ||
489 | outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR); | ||
490 | udelay(10); | ||
491 | outb(data, s->ioenh + SV_CODEC_IDATA); | ||
492 | udelay(10); | ||
493 | } | ||
494 | |||
495 | static unsigned char rdindir(struct sv_state *s, unsigned char idx) | ||
496 | { | ||
497 | unsigned char v; | ||
498 | |||
499 | outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR); | ||
500 | udelay(10); | ||
501 | v = inb(s->ioenh + SV_CODEC_IDATA); | ||
502 | udelay(10); | ||
503 | return v; | ||
504 | } | ||
505 | |||
506 | static void set_fmt(struct sv_state *s, unsigned char mask, unsigned char data) | ||
507 | { | ||
508 | unsigned long flags; | ||
509 | |||
510 | spin_lock_irqsave(&s->lock, flags); | ||
511 | outb(SV_CIDATAFMT | SV_CIADDR_MCE, s->ioenh + SV_CODEC_IADDR); | ||
512 | if (mask) { | ||
513 | s->fmt = inb(s->ioenh + SV_CODEC_IDATA); | ||
514 | udelay(10); | ||
515 | } | ||
516 | s->fmt = (s->fmt & mask) | data; | ||
517 | outb(s->fmt, s->ioenh + SV_CODEC_IDATA); | ||
518 | udelay(10); | ||
519 | outb(0, s->ioenh + SV_CODEC_IADDR); | ||
520 | spin_unlock_irqrestore(&s->lock, flags); | ||
521 | udelay(10); | ||
522 | } | ||
523 | |||
524 | static void frobindir(struct sv_state *s, unsigned char idx, unsigned char mask, unsigned char data) | ||
525 | { | ||
526 | outb(idx & 0x3f, s->ioenh + SV_CODEC_IADDR); | ||
527 | udelay(10); | ||
528 | outb((inb(s->ioenh + SV_CODEC_IDATA) & mask) ^ data, s->ioenh + SV_CODEC_IDATA); | ||
529 | udelay(10); | ||
530 | } | ||
531 | |||
532 | #define REFFREQUENCY 24576000 | ||
533 | #define ADCMULT 512 | ||
534 | #define FULLRATE 48000 | ||
535 | |||
536 | static unsigned setpll(struct sv_state *s, unsigned char reg, unsigned rate) | ||
537 | { | ||
538 | unsigned long flags; | ||
539 | unsigned char r, m=0, n=0; | ||
540 | unsigned xm, xn, xr, xd, metric = ~0U; | ||
541 | /* the warnings about m and n used uninitialized are bogus and may safely be ignored */ | ||
542 | |||
543 | if (rate < 625000/ADCMULT) | ||
544 | rate = 625000/ADCMULT; | ||
545 | if (rate > 150000000/ADCMULT) | ||
546 | rate = 150000000/ADCMULT; | ||
547 | /* slight violation of specs, needed for continuous sampling rates */ | ||
548 | for (r = 0; rate < 75000000/ADCMULT; r += 0x20, rate <<= 1); | ||
549 | for (xn = 3; xn < 35; xn++) | ||
550 | for (xm = 3; xm < 130; xm++) { | ||
551 | xr = REFFREQUENCY/ADCMULT * xm / xn; | ||
552 | xd = abs((signed)(xr - rate)); | ||
553 | if (xd < metric) { | ||
554 | metric = xd; | ||
555 | m = xm - 2; | ||
556 | n = xn - 2; | ||
557 | } | ||
558 | } | ||
559 | reg &= 0x3f; | ||
560 | spin_lock_irqsave(&s->lock, flags); | ||
561 | outb(reg, s->ioenh + SV_CODEC_IADDR); | ||
562 | udelay(10); | ||
563 | outb(m, s->ioenh + SV_CODEC_IDATA); | ||
564 | udelay(10); | ||
565 | outb(reg+1, s->ioenh + SV_CODEC_IADDR); | ||
566 | udelay(10); | ||
567 | outb(r | n, s->ioenh + SV_CODEC_IDATA); | ||
568 | spin_unlock_irqrestore(&s->lock, flags); | ||
569 | udelay(10); | ||
570 | return (REFFREQUENCY/ADCMULT * (m + 2) / (n + 2)) >> ((r >> 5) & 7); | ||
571 | } | ||
572 | |||
573 | #if 0 | ||
574 | |||
575 | static unsigned getpll(struct sv_state *s, unsigned char reg) | ||
576 | { | ||
577 | unsigned long flags; | ||
578 | unsigned char m, n; | ||
579 | |||
580 | reg &= 0x3f; | ||
581 | spin_lock_irqsave(&s->lock, flags); | ||
582 | outb(reg, s->ioenh + SV_CODEC_IADDR); | ||
583 | udelay(10); | ||
584 | m = inb(s->ioenh + SV_CODEC_IDATA); | ||
585 | udelay(10); | ||
586 | outb(reg+1, s->ioenh + SV_CODEC_IADDR); | ||
587 | udelay(10); | ||
588 | n = inb(s->ioenh + SV_CODEC_IDATA); | ||
589 | spin_unlock_irqrestore(&s->lock, flags); | ||
590 | udelay(10); | ||
591 | return (REFFREQUENCY/ADCMULT * (m + 2) / ((n & 0x1f) + 2)) >> ((n >> 5) & 7); | ||
592 | } | ||
593 | |||
594 | #endif | ||
595 | |||
596 | static void set_dac_rate(struct sv_state *s, unsigned rate) | ||
597 | { | ||
598 | unsigned div; | ||
599 | unsigned long flags; | ||
600 | |||
601 | if (rate > 48000) | ||
602 | rate = 48000; | ||
603 | if (rate < 4000) | ||
604 | rate = 4000; | ||
605 | div = (rate * 65536 + FULLRATE/2) / FULLRATE; | ||
606 | if (div > 65535) | ||
607 | div = 65535; | ||
608 | spin_lock_irqsave(&s->lock, flags); | ||
609 | wrindir(s, SV_CIPCMSR1, div >> 8); | ||
610 | wrindir(s, SV_CIPCMSR0, div); | ||
611 | spin_unlock_irqrestore(&s->lock, flags); | ||
612 | s->ratedac = (div * FULLRATE + 32768) / 65536; | ||
613 | } | ||
614 | |||
615 | static void set_adc_rate(struct sv_state *s, unsigned rate) | ||
616 | { | ||
617 | unsigned long flags; | ||
618 | unsigned rate1, rate2, div; | ||
619 | |||
620 | if (rate > 48000) | ||
621 | rate = 48000; | ||
622 | if (rate < 4000) | ||
623 | rate = 4000; | ||
624 | rate1 = setpll(s, SV_CIADCPLLM, rate); | ||
625 | div = (48000 + rate/2) / rate; | ||
626 | if (div > 8) | ||
627 | div = 8; | ||
628 | rate2 = (48000 + div/2) / div; | ||
629 | spin_lock_irqsave(&s->lock, flags); | ||
630 | wrindir(s, SV_CIADCALTSR, (div-1) << 4); | ||
631 | if (abs((signed)(rate-rate2)) <= abs((signed)(rate-rate1))) { | ||
632 | wrindir(s, SV_CIADCCLKSOURCE, 0x10); | ||
633 | s->rateadc = rate2; | ||
634 | } else { | ||
635 | wrindir(s, SV_CIADCCLKSOURCE, 0x00); | ||
636 | s->rateadc = rate1; | ||
637 | } | ||
638 | spin_unlock_irqrestore(&s->lock, flags); | ||
639 | } | ||
640 | |||
641 | /* --------------------------------------------------------------------- */ | ||
642 | |||
643 | static inline void stop_adc(struct sv_state *s) | ||
644 | { | ||
645 | unsigned long flags; | ||
646 | |||
647 | spin_lock_irqsave(&s->lock, flags); | ||
648 | s->enable &= ~SV_CENABLE_RE; | ||
649 | wrindir(s, SV_CIENABLE, s->enable); | ||
650 | spin_unlock_irqrestore(&s->lock, flags); | ||
651 | } | ||
652 | |||
653 | static inline void stop_dac(struct sv_state *s) | ||
654 | { | ||
655 | unsigned long flags; | ||
656 | |||
657 | spin_lock_irqsave(&s->lock, flags); | ||
658 | s->enable &= ~(SV_CENABLE_PPE | SV_CENABLE_PE); | ||
659 | wrindir(s, SV_CIENABLE, s->enable); | ||
660 | spin_unlock_irqrestore(&s->lock, flags); | ||
661 | } | ||
662 | |||
663 | static void start_dac(struct sv_state *s) | ||
664 | { | ||
665 | unsigned long flags; | ||
666 | |||
667 | spin_lock_irqsave(&s->lock, flags); | ||
668 | if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) { | ||
669 | s->enable = (s->enable & ~SV_CENABLE_PPE) | SV_CENABLE_PE; | ||
670 | wrindir(s, SV_CIENABLE, s->enable); | ||
671 | } | ||
672 | spin_unlock_irqrestore(&s->lock, flags); | ||
673 | } | ||
674 | |||
675 | static void start_adc(struct sv_state *s) | ||
676 | { | ||
677 | unsigned long flags; | ||
678 | |||
679 | spin_lock_irqsave(&s->lock, flags); | ||
680 | if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) | ||
681 | && s->dma_adc.ready) { | ||
682 | s->enable |= SV_CENABLE_RE; | ||
683 | wrindir(s, SV_CIENABLE, s->enable); | ||
684 | } | ||
685 | spin_unlock_irqrestore(&s->lock, flags); | ||
686 | } | ||
687 | |||
688 | /* --------------------------------------------------------------------- */ | ||
689 | |||
690 | #define DMABUF_DEFAULTORDER (17-PAGE_SHIFT) | ||
691 | #define DMABUF_MINORDER 1 | ||
692 | |||
693 | static void dealloc_dmabuf(struct sv_state *s, struct dmabuf *db) | ||
694 | { | ||
695 | struct page *page, *pend; | ||
696 | |||
697 | if (db->rawbuf) { | ||
698 | /* undo marking the pages as reserved */ | ||
699 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
700 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
701 | ClearPageReserved(page); | ||
702 | pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr); | ||
703 | } | ||
704 | db->rawbuf = NULL; | ||
705 | db->mapped = db->ready = 0; | ||
706 | } | ||
707 | |||
708 | |||
709 | /* DMAA is used for playback, DMAC is used for recording */ | ||
710 | |||
711 | static int prog_dmabuf(struct sv_state *s, unsigned rec) | ||
712 | { | ||
713 | struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac; | ||
714 | unsigned rate = rec ? s->rateadc : s->ratedac; | ||
715 | int order; | ||
716 | unsigned bytepersec; | ||
717 | unsigned bufs; | ||
718 | struct page *page, *pend; | ||
719 | unsigned char fmt; | ||
720 | unsigned long flags; | ||
721 | |||
722 | spin_lock_irqsave(&s->lock, flags); | ||
723 | fmt = s->fmt; | ||
724 | if (rec) { | ||
725 | s->enable &= ~SV_CENABLE_RE; | ||
726 | fmt >>= SV_CFMT_CSHIFT; | ||
727 | } else { | ||
728 | s->enable &= ~SV_CENABLE_PE; | ||
729 | fmt >>= SV_CFMT_ASHIFT; | ||
730 | } | ||
731 | wrindir(s, SV_CIENABLE, s->enable); | ||
732 | spin_unlock_irqrestore(&s->lock, flags); | ||
733 | fmt &= SV_CFMT_MASK; | ||
734 | db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; | ||
735 | if (!db->rawbuf) { | ||
736 | db->ready = db->mapped = 0; | ||
737 | for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) | ||
738 | if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr))) | ||
739 | break; | ||
740 | if (!db->rawbuf) | ||
741 | return -ENOMEM; | ||
742 | db->buforder = order; | ||
743 | if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff) | ||
744 | printk(KERN_DEBUG "sv: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n", | ||
745 | virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder); | ||
746 | if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff) | ||
747 | printk(KERN_DEBUG "sv: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n", | ||
748 | virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder); | ||
749 | /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ | ||
750 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
751 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
752 | SetPageReserved(page); | ||
753 | } | ||
754 | bytepersec = rate << sample_shift[fmt]; | ||
755 | bufs = PAGE_SIZE << db->buforder; | ||
756 | if (db->ossfragshift) { | ||
757 | if ((1000 << db->ossfragshift) < bytepersec) | ||
758 | db->fragshift = ld2(bytepersec/1000); | ||
759 | else | ||
760 | db->fragshift = db->ossfragshift; | ||
761 | } else { | ||
762 | db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); | ||
763 | if (db->fragshift < 3) | ||
764 | db->fragshift = 3; | ||
765 | } | ||
766 | db->numfrag = bufs >> db->fragshift; | ||
767 | while (db->numfrag < 4 && db->fragshift > 3) { | ||
768 | db->fragshift--; | ||
769 | db->numfrag = bufs >> db->fragshift; | ||
770 | } | ||
771 | db->fragsize = 1 << db->fragshift; | ||
772 | if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) | ||
773 | db->numfrag = db->ossmaxfrags; | ||
774 | db->fragsamples = db->fragsize >> sample_shift[fmt]; | ||
775 | db->dmasize = db->numfrag << db->fragshift; | ||
776 | memset(db->rawbuf, (fmt & SV_CFMT_16BIT) ? 0 : 0x80, db->dmasize); | ||
777 | spin_lock_irqsave(&s->lock, flags); | ||
778 | if (rec) { | ||
779 | set_dmac(s, db->dmaaddr, db->numfrag << db->fragshift); | ||
780 | /* program enhanced mode registers */ | ||
781 | wrindir(s, SV_CIDMACBASECOUNT1, (db->fragsamples-1) >> 8); | ||
782 | wrindir(s, SV_CIDMACBASECOUNT0, db->fragsamples-1); | ||
783 | } else { | ||
784 | set_dmaa(s, db->dmaaddr, db->numfrag << db->fragshift); | ||
785 | /* program enhanced mode registers */ | ||
786 | wrindir(s, SV_CIDMAABASECOUNT1, (db->fragsamples-1) >> 8); | ||
787 | wrindir(s, SV_CIDMAABASECOUNT0, db->fragsamples-1); | ||
788 | } | ||
789 | spin_unlock_irqrestore(&s->lock, flags); | ||
790 | db->enabled = 1; | ||
791 | db->ready = 1; | ||
792 | return 0; | ||
793 | } | ||
794 | |||
795 | static inline void clear_advance(struct sv_state *s) | ||
796 | { | ||
797 | unsigned char c = (s->fmt & (SV_CFMT_16BIT << SV_CFMT_ASHIFT)) ? 0 : 0x80; | ||
798 | unsigned char *buf = s->dma_dac.rawbuf; | ||
799 | unsigned bsize = s->dma_dac.dmasize; | ||
800 | unsigned bptr = s->dma_dac.swptr; | ||
801 | unsigned len = s->dma_dac.fragsize; | ||
802 | |||
803 | if (bptr + len > bsize) { | ||
804 | unsigned x = bsize - bptr; | ||
805 | memset(buf + bptr, c, x); | ||
806 | bptr = 0; | ||
807 | len -= x; | ||
808 | } | ||
809 | memset(buf + bptr, c, len); | ||
810 | } | ||
811 | |||
812 | /* call with spinlock held! */ | ||
813 | static void sv_update_ptr(struct sv_state *s) | ||
814 | { | ||
815 | unsigned hwptr; | ||
816 | int diff; | ||
817 | |||
818 | /* update ADC pointer */ | ||
819 | if (s->dma_adc.ready) { | ||
820 | hwptr = (s->dma_adc.dmasize - get_dmac(s)) % s->dma_adc.dmasize; | ||
821 | diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize; | ||
822 | s->dma_adc.hwptr = hwptr; | ||
823 | s->dma_adc.total_bytes += diff; | ||
824 | s->dma_adc.count += diff; | ||
825 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
826 | wake_up(&s->dma_adc.wait); | ||
827 | if (!s->dma_adc.mapped) { | ||
828 | if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { | ||
829 | s->enable &= ~SV_CENABLE_RE; | ||
830 | wrindir(s, SV_CIENABLE, s->enable); | ||
831 | s->dma_adc.error++; | ||
832 | } | ||
833 | } | ||
834 | } | ||
835 | /* update DAC pointer */ | ||
836 | if (s->dma_dac.ready) { | ||
837 | hwptr = (s->dma_dac.dmasize - get_dmaa(s)) % s->dma_dac.dmasize; | ||
838 | diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize; | ||
839 | s->dma_dac.hwptr = hwptr; | ||
840 | s->dma_dac.total_bytes += diff; | ||
841 | if (s->dma_dac.mapped) { | ||
842 | s->dma_dac.count += diff; | ||
843 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) | ||
844 | wake_up(&s->dma_dac.wait); | ||
845 | } else { | ||
846 | s->dma_dac.count -= diff; | ||
847 | if (s->dma_dac.count <= 0) { | ||
848 | s->enable &= ~SV_CENABLE_PE; | ||
849 | wrindir(s, SV_CIENABLE, s->enable); | ||
850 | s->dma_dac.error++; | ||
851 | } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && !s->dma_dac.endcleared) { | ||
852 | clear_advance(s); | ||
853 | s->dma_dac.endcleared = 1; | ||
854 | } | ||
855 | if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) | ||
856 | wake_up(&s->dma_dac.wait); | ||
857 | } | ||
858 | } | ||
859 | } | ||
860 | |||
861 | /* hold spinlock for the following! */ | ||
862 | static void sv_handle_midi(struct sv_state *s) | ||
863 | { | ||
864 | unsigned char ch; | ||
865 | int wake; | ||
866 | |||
867 | wake = 0; | ||
868 | while (!(inb(s->iomidi+1) & 0x80)) { | ||
869 | ch = inb(s->iomidi); | ||
870 | if (s->midi.icnt < MIDIINBUF) { | ||
871 | s->midi.ibuf[s->midi.iwr] = ch; | ||
872 | s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF; | ||
873 | s->midi.icnt++; | ||
874 | } | ||
875 | wake = 1; | ||
876 | } | ||
877 | if (wake) | ||
878 | wake_up(&s->midi.iwait); | ||
879 | wake = 0; | ||
880 | while (!(inb(s->iomidi+1) & 0x40) && s->midi.ocnt > 0) { | ||
881 | outb(s->midi.obuf[s->midi.ord], s->iomidi); | ||
882 | s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF; | ||
883 | s->midi.ocnt--; | ||
884 | if (s->midi.ocnt < MIDIOUTBUF-16) | ||
885 | wake = 1; | ||
886 | } | ||
887 | if (wake) | ||
888 | wake_up(&s->midi.owait); | ||
889 | } | ||
890 | |||
891 | static irqreturn_t sv_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
892 | { | ||
893 | struct sv_state *s = (struct sv_state *)dev_id; | ||
894 | unsigned int intsrc; | ||
895 | |||
896 | /* fastpath out, to ease interrupt sharing */ | ||
897 | intsrc = inb(s->ioenh + SV_CODEC_STATUS); | ||
898 | if (!(intsrc & (SV_CSTAT_DMAA | SV_CSTAT_DMAC | SV_CSTAT_MIDI))) | ||
899 | return IRQ_NONE; | ||
900 | spin_lock(&s->lock); | ||
901 | sv_update_ptr(s); | ||
902 | sv_handle_midi(s); | ||
903 | spin_unlock(&s->lock); | ||
904 | return IRQ_HANDLED; | ||
905 | } | ||
906 | |||
907 | static void sv_midi_timer(unsigned long data) | ||
908 | { | ||
909 | struct sv_state *s = (struct sv_state *)data; | ||
910 | unsigned long flags; | ||
911 | |||
912 | spin_lock_irqsave(&s->lock, flags); | ||
913 | sv_handle_midi(s); | ||
914 | spin_unlock_irqrestore(&s->lock, flags); | ||
915 | s->midi.timer.expires = jiffies+1; | ||
916 | add_timer(&s->midi.timer); | ||
917 | } | ||
918 | |||
919 | /* --------------------------------------------------------------------- */ | ||
920 | |||
921 | static const char invalid_magic[] = KERN_CRIT "sv: invalid magic value\n"; | ||
922 | |||
923 | #define VALIDATE_STATE(s) \ | ||
924 | ({ \ | ||
925 | if (!(s) || (s)->magic != SV_MAGIC) { \ | ||
926 | printk(invalid_magic); \ | ||
927 | return -ENXIO; \ | ||
928 | } \ | ||
929 | }) | ||
930 | |||
931 | /* --------------------------------------------------------------------- */ | ||
932 | |||
933 | #define MT_4 1 | ||
934 | #define MT_5MUTE 2 | ||
935 | #define MT_4MUTEMONO 3 | ||
936 | #define MT_6MUTE 4 | ||
937 | |||
938 | static const struct { | ||
939 | unsigned left:5; | ||
940 | unsigned right:5; | ||
941 | unsigned type:3; | ||
942 | unsigned rec:3; | ||
943 | } mixtable[SOUND_MIXER_NRDEVICES] = { | ||
944 | [SOUND_MIXER_RECLEV] = { SV_CIMIX_ADCINL, SV_CIMIX_ADCINR, MT_4, 0 }, | ||
945 | [SOUND_MIXER_LINE1] = { SV_CIMIX_AUX1INL, SV_CIMIX_AUX1INR, MT_5MUTE, 5 }, | ||
946 | [SOUND_MIXER_CD] = { SV_CIMIX_CDINL, SV_CIMIX_CDINR, MT_5MUTE, 1 }, | ||
947 | [SOUND_MIXER_LINE] = { SV_CIMIX_LINEINL, SV_CIMIX_LINEINR, MT_5MUTE, 4 }, | ||
948 | [SOUND_MIXER_MIC] = { SV_CIMIX_MICIN, SV_CIMIX_ADCINL, MT_4MUTEMONO, 6 }, | ||
949 | [SOUND_MIXER_SYNTH] = { SV_CIMIX_SYNTHINL, SV_CIMIX_SYNTHINR, MT_5MUTE, 2 }, | ||
950 | [SOUND_MIXER_LINE2] = { SV_CIMIX_AUX2INL, SV_CIMIX_AUX2INR, MT_5MUTE, 3 }, | ||
951 | [SOUND_MIXER_VOLUME] = { SV_CIMIX_ANALOGINL, SV_CIMIX_ANALOGINR, MT_5MUTE, 7 }, | ||
952 | [SOUND_MIXER_PCM] = { SV_CIMIX_PCMINL, SV_CIMIX_PCMINR, MT_6MUTE, 0 } | ||
953 | }; | ||
954 | |||
955 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
956 | |||
957 | static int return_mixval(struct sv_state *s, unsigned i, int *arg) | ||
958 | { | ||
959 | unsigned long flags; | ||
960 | unsigned char l, r, rl, rr; | ||
961 | |||
962 | spin_lock_irqsave(&s->lock, flags); | ||
963 | l = rdindir(s, mixtable[i].left); | ||
964 | r = rdindir(s, mixtable[i].right); | ||
965 | spin_unlock_irqrestore(&s->lock, flags); | ||
966 | switch (mixtable[i].type) { | ||
967 | case MT_4: | ||
968 | r &= 0xf; | ||
969 | l &= 0xf; | ||
970 | rl = 10 + 6 * (l & 15); | ||
971 | rr = 10 + 6 * (r & 15); | ||
972 | break; | ||
973 | |||
974 | case MT_4MUTEMONO: | ||
975 | rl = 55 - 3 * (l & 15); | ||
976 | if (r & 0x10) | ||
977 | rl += 45; | ||
978 | rr = rl; | ||
979 | r = l; | ||
980 | break; | ||
981 | |||
982 | case MT_5MUTE: | ||
983 | default: | ||
984 | rl = 100 - 3 * (l & 31); | ||
985 | rr = 100 - 3 * (r & 31); | ||
986 | break; | ||
987 | |||
988 | case MT_6MUTE: | ||
989 | rl = 100 - 3 * (l & 63) / 2; | ||
990 | rr = 100 - 3 * (r & 63) / 2; | ||
991 | break; | ||
992 | } | ||
993 | if (l & 0x80) | ||
994 | rl = 0; | ||
995 | if (r & 0x80) | ||
996 | rr = 0; | ||
997 | return put_user((rr << 8) | rl, arg); | ||
998 | } | ||
999 | |||
1000 | #else /* OSS_DOCUMENTED_MIXER_SEMANTICS */ | ||
1001 | |||
1002 | static const unsigned char volidx[SOUND_MIXER_NRDEVICES] = | ||
1003 | { | ||
1004 | [SOUND_MIXER_RECLEV] = 1, | ||
1005 | [SOUND_MIXER_LINE1] = 2, | ||
1006 | [SOUND_MIXER_CD] = 3, | ||
1007 | [SOUND_MIXER_LINE] = 4, | ||
1008 | [SOUND_MIXER_MIC] = 5, | ||
1009 | [SOUND_MIXER_SYNTH] = 6, | ||
1010 | [SOUND_MIXER_LINE2] = 7, | ||
1011 | [SOUND_MIXER_VOLUME] = 8, | ||
1012 | [SOUND_MIXER_PCM] = 9 | ||
1013 | }; | ||
1014 | |||
1015 | #endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ | ||
1016 | |||
1017 | static unsigned mixer_recmask(struct sv_state *s) | ||
1018 | { | ||
1019 | unsigned long flags; | ||
1020 | int i, j; | ||
1021 | |||
1022 | spin_lock_irqsave(&s->lock, flags); | ||
1023 | j = rdindir(s, SV_CIMIX_ADCINL) >> 5; | ||
1024 | spin_unlock_irqrestore(&s->lock, flags); | ||
1025 | j &= 7; | ||
1026 | for (i = 0; i < SOUND_MIXER_NRDEVICES && mixtable[i].rec != j; i++); | ||
1027 | return 1 << i; | ||
1028 | } | ||
1029 | |||
1030 | static int mixer_ioctl(struct sv_state *s, unsigned int cmd, unsigned long arg) | ||
1031 | { | ||
1032 | unsigned long flags; | ||
1033 | int i, val; | ||
1034 | unsigned char l, r, rl, rr; | ||
1035 | int __user *p = (int __user *)arg; | ||
1036 | |||
1037 | VALIDATE_STATE(s); | ||
1038 | if (cmd == SOUND_MIXER_INFO) { | ||
1039 | mixer_info info; | ||
1040 | memset(&info, 0, sizeof(info)); | ||
1041 | strlcpy(info.id, "SonicVibes", sizeof(info.id)); | ||
1042 | strlcpy(info.name, "S3 SonicVibes", sizeof(info.name)); | ||
1043 | info.modify_counter = s->mix.modcnt; | ||
1044 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | ||
1045 | return -EFAULT; | ||
1046 | return 0; | ||
1047 | } | ||
1048 | if (cmd == SOUND_OLD_MIXER_INFO) { | ||
1049 | _old_mixer_info info; | ||
1050 | memset(&info, 0, sizeof(info)); | ||
1051 | strlcpy(info.id, "SonicVibes", sizeof(info.id)); | ||
1052 | strlcpy(info.name, "S3 SonicVibes", sizeof(info.name)); | ||
1053 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | ||
1054 | return -EFAULT; | ||
1055 | return 0; | ||
1056 | } | ||
1057 | if (cmd == OSS_GETVERSION) | ||
1058 | return put_user(SOUND_VERSION, p); | ||
1059 | if (cmd == SOUND_MIXER_PRIVATE1) { /* SRS settings */ | ||
1060 | if (get_user(val, p)) | ||
1061 | return -EFAULT; | ||
1062 | spin_lock_irqsave(&s->lock, flags); | ||
1063 | if (val & 1) { | ||
1064 | if (val & 2) { | ||
1065 | l = 4 - ((val >> 2) & 7); | ||
1066 | if (l & ~3) | ||
1067 | l = 4; | ||
1068 | r = 4 - ((val >> 5) & 7); | ||
1069 | if (r & ~3) | ||
1070 | r = 4; | ||
1071 | wrindir(s, SV_CISRSSPACE, l); | ||
1072 | wrindir(s, SV_CISRSCENTER, r); | ||
1073 | } else | ||
1074 | wrindir(s, SV_CISRSSPACE, 0x80); | ||
1075 | } | ||
1076 | l = rdindir(s, SV_CISRSSPACE); | ||
1077 | r = rdindir(s, SV_CISRSCENTER); | ||
1078 | spin_unlock_irqrestore(&s->lock, flags); | ||
1079 | if (l & 0x80) | ||
1080 | return put_user(0, p); | ||
1081 | return put_user(((4 - (l & 7)) << 2) | ((4 - (r & 7)) << 5) | 2, p); | ||
1082 | } | ||
1083 | if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int)) | ||
1084 | return -EINVAL; | ||
1085 | if (_SIOC_DIR(cmd) == _SIOC_READ) { | ||
1086 | switch (_IOC_NR(cmd)) { | ||
1087 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
1088 | return put_user(mixer_recmask(s), p); | ||
1089 | |||
1090 | case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */ | ||
1091 | for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
1092 | if (mixtable[i].type) | ||
1093 | val |= 1 << i; | ||
1094 | return put_user(val, p); | ||
1095 | |||
1096 | case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ | ||
1097 | for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
1098 | if (mixtable[i].rec) | ||
1099 | val |= 1 << i; | ||
1100 | return put_user(val, p); | ||
1101 | |||
1102 | case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ | ||
1103 | for (val = i = 0; i < SOUND_MIXER_NRDEVICES; i++) | ||
1104 | if (mixtable[i].type && mixtable[i].type != MT_4MUTEMONO) | ||
1105 | val |= 1 << i; | ||
1106 | return put_user(val, p); | ||
1107 | |||
1108 | case SOUND_MIXER_CAPS: | ||
1109 | return put_user(SOUND_CAP_EXCL_INPUT, p); | ||
1110 | |||
1111 | default: | ||
1112 | i = _IOC_NR(cmd); | ||
1113 | if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type) | ||
1114 | return -EINVAL; | ||
1115 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
1116 | return return_mixval(s, i, p); | ||
1117 | #else /* OSS_DOCUMENTED_MIXER_SEMANTICS */ | ||
1118 | if (!volidx[i]) | ||
1119 | return -EINVAL; | ||
1120 | return put_user(s->mix.vol[volidx[i]-1], p); | ||
1121 | #endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ | ||
1122 | } | ||
1123 | } | ||
1124 | if (_SIOC_DIR(cmd) != (_SIOC_READ|_SIOC_WRITE)) | ||
1125 | return -EINVAL; | ||
1126 | s->mix.modcnt++; | ||
1127 | switch (_IOC_NR(cmd)) { | ||
1128 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
1129 | if (get_user(val, p)) | ||
1130 | return -EFAULT; | ||
1131 | i = hweight32(val); | ||
1132 | if (i == 0) | ||
1133 | return 0; /*val = mixer_recmask(s);*/ | ||
1134 | else if (i > 1) | ||
1135 | val &= ~mixer_recmask(s); | ||
1136 | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||
1137 | if (!(val & (1 << i))) | ||
1138 | continue; | ||
1139 | if (mixtable[i].rec) | ||
1140 | break; | ||
1141 | } | ||
1142 | if (i == SOUND_MIXER_NRDEVICES) | ||
1143 | return 0; | ||
1144 | spin_lock_irqsave(&s->lock, flags); | ||
1145 | frobindir(s, SV_CIMIX_ADCINL, 0x1f, mixtable[i].rec << 5); | ||
1146 | frobindir(s, SV_CIMIX_ADCINR, 0x1f, mixtable[i].rec << 5); | ||
1147 | spin_unlock_irqrestore(&s->lock, flags); | ||
1148 | return 0; | ||
1149 | |||
1150 | default: | ||
1151 | i = _IOC_NR(cmd); | ||
1152 | if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type) | ||
1153 | return -EINVAL; | ||
1154 | if (get_user(val, p)) | ||
1155 | return -EFAULT; | ||
1156 | l = val & 0xff; | ||
1157 | r = (val >> 8) & 0xff; | ||
1158 | if (mixtable[i].type == MT_4MUTEMONO) | ||
1159 | l = (r + l) / 2; | ||
1160 | if (l > 100) | ||
1161 | l = 100; | ||
1162 | if (r > 100) | ||
1163 | r = 100; | ||
1164 | spin_lock_irqsave(&s->lock, flags); | ||
1165 | switch (mixtable[i].type) { | ||
1166 | case MT_4: | ||
1167 | if (l >= 10) | ||
1168 | l -= 10; | ||
1169 | if (r >= 10) | ||
1170 | r -= 10; | ||
1171 | frobindir(s, mixtable[i].left, 0xf0, l / 6); | ||
1172 | frobindir(s, mixtable[i].right, 0xf0, l / 6); | ||
1173 | break; | ||
1174 | |||
1175 | case MT_4MUTEMONO: | ||
1176 | rr = 0; | ||
1177 | if (l < 10) | ||
1178 | rl = 0x80; | ||
1179 | else { | ||
1180 | if (l >= 55) { | ||
1181 | rr = 0x10; | ||
1182 | l -= 45; | ||
1183 | } | ||
1184 | rl = (55 - l) / 3; | ||
1185 | } | ||
1186 | wrindir(s, mixtable[i].left, rl); | ||
1187 | frobindir(s, mixtable[i].right, ~0x10, rr); | ||
1188 | break; | ||
1189 | |||
1190 | case MT_5MUTE: | ||
1191 | if (l < 7) | ||
1192 | rl = 0x80; | ||
1193 | else | ||
1194 | rl = (100 - l) / 3; | ||
1195 | if (r < 7) | ||
1196 | rr = 0x80; | ||
1197 | else | ||
1198 | rr = (100 - r) / 3; | ||
1199 | wrindir(s, mixtable[i].left, rl); | ||
1200 | wrindir(s, mixtable[i].right, rr); | ||
1201 | break; | ||
1202 | |||
1203 | case MT_6MUTE: | ||
1204 | if (l < 6) | ||
1205 | rl = 0x80; | ||
1206 | else | ||
1207 | rl = (100 - l) * 2 / 3; | ||
1208 | if (r < 6) | ||
1209 | rr = 0x80; | ||
1210 | else | ||
1211 | rr = (100 - r) * 2 / 3; | ||
1212 | wrindir(s, mixtable[i].left, rl); | ||
1213 | wrindir(s, mixtable[i].right, rr); | ||
1214 | break; | ||
1215 | } | ||
1216 | spin_unlock_irqrestore(&s->lock, flags); | ||
1217 | #ifdef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
1218 | return return_mixval(s, i, p); | ||
1219 | #else /* OSS_DOCUMENTED_MIXER_SEMANTICS */ | ||
1220 | if (!volidx[i]) | ||
1221 | return -EINVAL; | ||
1222 | s->mix.vol[volidx[i]-1] = val; | ||
1223 | return put_user(s->mix.vol[volidx[i]-1], p); | ||
1224 | #endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */ | ||
1225 | } | ||
1226 | } | ||
1227 | |||
1228 | /* --------------------------------------------------------------------- */ | ||
1229 | |||
1230 | static int sv_open_mixdev(struct inode *inode, struct file *file) | ||
1231 | { | ||
1232 | int minor = iminor(inode); | ||
1233 | struct list_head *list; | ||
1234 | struct sv_state *s; | ||
1235 | |||
1236 | for (list = devs.next; ; list = list->next) { | ||
1237 | if (list == &devs) | ||
1238 | return -ENODEV; | ||
1239 | s = list_entry(list, struct sv_state, devs); | ||
1240 | if (s->dev_mixer == minor) | ||
1241 | break; | ||
1242 | } | ||
1243 | VALIDATE_STATE(s); | ||
1244 | file->private_data = s; | ||
1245 | return nonseekable_open(inode, file); | ||
1246 | } | ||
1247 | |||
1248 | static int sv_release_mixdev(struct inode *inode, struct file *file) | ||
1249 | { | ||
1250 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
1251 | |||
1252 | VALIDATE_STATE(s); | ||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | static int sv_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1257 | { | ||
1258 | return mixer_ioctl((struct sv_state *)file->private_data, cmd, arg); | ||
1259 | } | ||
1260 | |||
1261 | static /*const*/ struct file_operations sv_mixer_fops = { | ||
1262 | .owner = THIS_MODULE, | ||
1263 | .llseek = no_llseek, | ||
1264 | .ioctl = sv_ioctl_mixdev, | ||
1265 | .open = sv_open_mixdev, | ||
1266 | .release = sv_release_mixdev, | ||
1267 | }; | ||
1268 | |||
1269 | /* --------------------------------------------------------------------- */ | ||
1270 | |||
1271 | static int drain_dac(struct sv_state *s, int nonblock) | ||
1272 | { | ||
1273 | DECLARE_WAITQUEUE(wait, current); | ||
1274 | unsigned long flags; | ||
1275 | int count, tmo; | ||
1276 | |||
1277 | if (s->dma_dac.mapped || !s->dma_dac.ready) | ||
1278 | return 0; | ||
1279 | add_wait_queue(&s->dma_dac.wait, &wait); | ||
1280 | for (;;) { | ||
1281 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1282 | spin_lock_irqsave(&s->lock, flags); | ||
1283 | count = s->dma_dac.count; | ||
1284 | spin_unlock_irqrestore(&s->lock, flags); | ||
1285 | if (count <= 0) | ||
1286 | break; | ||
1287 | if (signal_pending(current)) | ||
1288 | break; | ||
1289 | if (nonblock) { | ||
1290 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
1291 | set_current_state(TASK_RUNNING); | ||
1292 | return -EBUSY; | ||
1293 | } | ||
1294 | tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac; | ||
1295 | tmo >>= sample_shift[(s->fmt >> SV_CFMT_ASHIFT) & SV_CFMT_MASK]; | ||
1296 | if (!schedule_timeout(tmo + 1)) | ||
1297 | printk(KERN_DEBUG "sv: dma timed out??\n"); | ||
1298 | } | ||
1299 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
1300 | set_current_state(TASK_RUNNING); | ||
1301 | if (signal_pending(current)) | ||
1302 | return -ERESTARTSYS; | ||
1303 | return 0; | ||
1304 | } | ||
1305 | |||
1306 | /* --------------------------------------------------------------------- */ | ||
1307 | |||
1308 | static ssize_t sv_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1309 | { | ||
1310 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
1311 | DECLARE_WAITQUEUE(wait, current); | ||
1312 | ssize_t ret; | ||
1313 | unsigned long flags; | ||
1314 | unsigned swptr; | ||
1315 | int cnt; | ||
1316 | |||
1317 | VALIDATE_STATE(s); | ||
1318 | if (s->dma_adc.mapped) | ||
1319 | return -ENXIO; | ||
1320 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
1321 | return ret; | ||
1322 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1323 | return -EFAULT; | ||
1324 | ret = 0; | ||
1325 | #if 0 | ||
1326 | spin_lock_irqsave(&s->lock, flags); | ||
1327 | sv_update_ptr(s); | ||
1328 | spin_unlock_irqrestore(&s->lock, flags); | ||
1329 | #endif | ||
1330 | add_wait_queue(&s->dma_adc.wait, &wait); | ||
1331 | while (count > 0) { | ||
1332 | spin_lock_irqsave(&s->lock, flags); | ||
1333 | swptr = s->dma_adc.swptr; | ||
1334 | cnt = s->dma_adc.dmasize-swptr; | ||
1335 | if (s->dma_adc.count < cnt) | ||
1336 | cnt = s->dma_adc.count; | ||
1337 | if (cnt <= 0) | ||
1338 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1339 | spin_unlock_irqrestore(&s->lock, flags); | ||
1340 | if (cnt > count) | ||
1341 | cnt = count; | ||
1342 | if (cnt <= 0) { | ||
1343 | if (s->dma_adc.enabled) | ||
1344 | start_adc(s); | ||
1345 | if (file->f_flags & O_NONBLOCK) { | ||
1346 | if (!ret) | ||
1347 | ret = -EAGAIN; | ||
1348 | break; | ||
1349 | } | ||
1350 | if (!schedule_timeout(HZ)) { | ||
1351 | printk(KERN_DEBUG "sv: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
1352 | s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, | ||
1353 | s->dma_adc.hwptr, s->dma_adc.swptr); | ||
1354 | stop_adc(s); | ||
1355 | spin_lock_irqsave(&s->lock, flags); | ||
1356 | set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift); | ||
1357 | /* program enhanced mode registers */ | ||
1358 | wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8); | ||
1359 | wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1); | ||
1360 | s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0; | ||
1361 | spin_unlock_irqrestore(&s->lock, flags); | ||
1362 | } | ||
1363 | if (signal_pending(current)) { | ||
1364 | if (!ret) | ||
1365 | ret = -ERESTARTSYS; | ||
1366 | break; | ||
1367 | } | ||
1368 | continue; | ||
1369 | } | ||
1370 | if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { | ||
1371 | if (!ret) | ||
1372 | ret = -EFAULT; | ||
1373 | break; | ||
1374 | } | ||
1375 | swptr = (swptr + cnt) % s->dma_adc.dmasize; | ||
1376 | spin_lock_irqsave(&s->lock, flags); | ||
1377 | s->dma_adc.swptr = swptr; | ||
1378 | s->dma_adc.count -= cnt; | ||
1379 | spin_unlock_irqrestore(&s->lock, flags); | ||
1380 | count -= cnt; | ||
1381 | buffer += cnt; | ||
1382 | ret += cnt; | ||
1383 | if (s->dma_adc.enabled) | ||
1384 | start_adc(s); | ||
1385 | } | ||
1386 | remove_wait_queue(&s->dma_adc.wait, &wait); | ||
1387 | set_current_state(TASK_RUNNING); | ||
1388 | return ret; | ||
1389 | } | ||
1390 | |||
1391 | static ssize_t sv_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1392 | { | ||
1393 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
1394 | DECLARE_WAITQUEUE(wait, current); | ||
1395 | ssize_t ret; | ||
1396 | unsigned long flags; | ||
1397 | unsigned swptr; | ||
1398 | int cnt; | ||
1399 | |||
1400 | VALIDATE_STATE(s); | ||
1401 | if (s->dma_dac.mapped) | ||
1402 | return -ENXIO; | ||
1403 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
1404 | return ret; | ||
1405 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1406 | return -EFAULT; | ||
1407 | ret = 0; | ||
1408 | #if 0 | ||
1409 | spin_lock_irqsave(&s->lock, flags); | ||
1410 | sv_update_ptr(s); | ||
1411 | spin_unlock_irqrestore(&s->lock, flags); | ||
1412 | #endif | ||
1413 | add_wait_queue(&s->dma_dac.wait, &wait); | ||
1414 | while (count > 0) { | ||
1415 | spin_lock_irqsave(&s->lock, flags); | ||
1416 | if (s->dma_dac.count < 0) { | ||
1417 | s->dma_dac.count = 0; | ||
1418 | s->dma_dac.swptr = s->dma_dac.hwptr; | ||
1419 | } | ||
1420 | swptr = s->dma_dac.swptr; | ||
1421 | cnt = s->dma_dac.dmasize-swptr; | ||
1422 | if (s->dma_dac.count + cnt > s->dma_dac.dmasize) | ||
1423 | cnt = s->dma_dac.dmasize - s->dma_dac.count; | ||
1424 | if (cnt <= 0) | ||
1425 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1426 | spin_unlock_irqrestore(&s->lock, flags); | ||
1427 | if (cnt > count) | ||
1428 | cnt = count; | ||
1429 | if (cnt <= 0) { | ||
1430 | if (s->dma_dac.enabled) | ||
1431 | start_dac(s); | ||
1432 | if (file->f_flags & O_NONBLOCK) { | ||
1433 | if (!ret) | ||
1434 | ret = -EAGAIN; | ||
1435 | break; | ||
1436 | } | ||
1437 | if (!schedule_timeout(HZ)) { | ||
1438 | printk(KERN_DEBUG "sv: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
1439 | s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, | ||
1440 | s->dma_dac.hwptr, s->dma_dac.swptr); | ||
1441 | stop_dac(s); | ||
1442 | spin_lock_irqsave(&s->lock, flags); | ||
1443 | set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift); | ||
1444 | /* program enhanced mode registers */ | ||
1445 | wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8); | ||
1446 | wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1); | ||
1447 | s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0; | ||
1448 | spin_unlock_irqrestore(&s->lock, flags); | ||
1449 | } | ||
1450 | if (signal_pending(current)) { | ||
1451 | if (!ret) | ||
1452 | ret = -ERESTARTSYS; | ||
1453 | break; | ||
1454 | } | ||
1455 | continue; | ||
1456 | } | ||
1457 | if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) { | ||
1458 | if (!ret) | ||
1459 | ret = -EFAULT; | ||
1460 | break; | ||
1461 | } | ||
1462 | swptr = (swptr + cnt) % s->dma_dac.dmasize; | ||
1463 | spin_lock_irqsave(&s->lock, flags); | ||
1464 | s->dma_dac.swptr = swptr; | ||
1465 | s->dma_dac.count += cnt; | ||
1466 | s->dma_dac.endcleared = 0; | ||
1467 | spin_unlock_irqrestore(&s->lock, flags); | ||
1468 | count -= cnt; | ||
1469 | buffer += cnt; | ||
1470 | ret += cnt; | ||
1471 | if (s->dma_dac.enabled) | ||
1472 | start_dac(s); | ||
1473 | } | ||
1474 | remove_wait_queue(&s->dma_dac.wait, &wait); | ||
1475 | set_current_state(TASK_RUNNING); | ||
1476 | return ret; | ||
1477 | } | ||
1478 | |||
1479 | /* No kernel lock - we have our own spinlock */ | ||
1480 | static unsigned int sv_poll(struct file *file, struct poll_table_struct *wait) | ||
1481 | { | ||
1482 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
1483 | unsigned long flags; | ||
1484 | unsigned int mask = 0; | ||
1485 | |||
1486 | VALIDATE_STATE(s); | ||
1487 | if (file->f_mode & FMODE_WRITE) { | ||
1488 | if (!s->dma_dac.ready && prog_dmabuf(s, 1)) | ||
1489 | return 0; | ||
1490 | poll_wait(file, &s->dma_dac.wait, wait); | ||
1491 | } | ||
1492 | if (file->f_mode & FMODE_READ) { | ||
1493 | if (!s->dma_adc.ready && prog_dmabuf(s, 0)) | ||
1494 | return 0; | ||
1495 | poll_wait(file, &s->dma_adc.wait, wait); | ||
1496 | } | ||
1497 | spin_lock_irqsave(&s->lock, flags); | ||
1498 | sv_update_ptr(s); | ||
1499 | if (file->f_mode & FMODE_READ) { | ||
1500 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
1501 | mask |= POLLIN | POLLRDNORM; | ||
1502 | } | ||
1503 | if (file->f_mode & FMODE_WRITE) { | ||
1504 | if (s->dma_dac.mapped) { | ||
1505 | if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) | ||
1506 | mask |= POLLOUT | POLLWRNORM; | ||
1507 | } else { | ||
1508 | if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize) | ||
1509 | mask |= POLLOUT | POLLWRNORM; | ||
1510 | } | ||
1511 | } | ||
1512 | spin_unlock_irqrestore(&s->lock, flags); | ||
1513 | return mask; | ||
1514 | } | ||
1515 | |||
1516 | static int sv_mmap(struct file *file, struct vm_area_struct *vma) | ||
1517 | { | ||
1518 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
1519 | struct dmabuf *db; | ||
1520 | int ret = -EINVAL; | ||
1521 | unsigned long size; | ||
1522 | |||
1523 | VALIDATE_STATE(s); | ||
1524 | lock_kernel(); | ||
1525 | if (vma->vm_flags & VM_WRITE) { | ||
1526 | if ((ret = prog_dmabuf(s, 1)) != 0) | ||
1527 | goto out; | ||
1528 | db = &s->dma_dac; | ||
1529 | } else if (vma->vm_flags & VM_READ) { | ||
1530 | if ((ret = prog_dmabuf(s, 0)) != 0) | ||
1531 | goto out; | ||
1532 | db = &s->dma_adc; | ||
1533 | } else | ||
1534 | goto out; | ||
1535 | ret = -EINVAL; | ||
1536 | if (vma->vm_pgoff != 0) | ||
1537 | goto out; | ||
1538 | size = vma->vm_end - vma->vm_start; | ||
1539 | if (size > (PAGE_SIZE << db->buforder)) | ||
1540 | goto out; | ||
1541 | ret = -EAGAIN; | ||
1542 | if (remap_pfn_range(vma, vma->vm_start, | ||
1543 | virt_to_phys(db->rawbuf) >> PAGE_SHIFT, | ||
1544 | size, vma->vm_page_prot)) | ||
1545 | goto out; | ||
1546 | db->mapped = 1; | ||
1547 | ret = 0; | ||
1548 | out: | ||
1549 | unlock_kernel(); | ||
1550 | return ret; | ||
1551 | } | ||
1552 | |||
1553 | static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1554 | { | ||
1555 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
1556 | unsigned long flags; | ||
1557 | audio_buf_info abinfo; | ||
1558 | count_info cinfo; | ||
1559 | int count; | ||
1560 | int val, mapped, ret; | ||
1561 | unsigned char fmtm, fmtd; | ||
1562 | void __user *argp = (void __user *)arg; | ||
1563 | int __user *p = argp; | ||
1564 | |||
1565 | VALIDATE_STATE(s); | ||
1566 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || | ||
1567 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
1568 | switch (cmd) { | ||
1569 | case OSS_GETVERSION: | ||
1570 | return put_user(SOUND_VERSION, p); | ||
1571 | |||
1572 | case SNDCTL_DSP_SYNC: | ||
1573 | if (file->f_mode & FMODE_WRITE) | ||
1574 | return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/); | ||
1575 | return 0; | ||
1576 | |||
1577 | case SNDCTL_DSP_SETDUPLEX: | ||
1578 | return 0; | ||
1579 | |||
1580 | case SNDCTL_DSP_GETCAPS: | ||
1581 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); | ||
1582 | |||
1583 | case SNDCTL_DSP_RESET: | ||
1584 | if (file->f_mode & FMODE_WRITE) { | ||
1585 | stop_dac(s); | ||
1586 | synchronize_irq(s->irq); | ||
1587 | s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0; | ||
1588 | } | ||
1589 | if (file->f_mode & FMODE_READ) { | ||
1590 | stop_adc(s); | ||
1591 | synchronize_irq(s->irq); | ||
1592 | s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
1593 | } | ||
1594 | return 0; | ||
1595 | |||
1596 | case SNDCTL_DSP_SPEED: | ||
1597 | if (get_user(val, p)) | ||
1598 | return -EFAULT; | ||
1599 | if (val >= 0) { | ||
1600 | if (file->f_mode & FMODE_READ) { | ||
1601 | stop_adc(s); | ||
1602 | s->dma_adc.ready = 0; | ||
1603 | set_adc_rate(s, val); | ||
1604 | } | ||
1605 | if (file->f_mode & FMODE_WRITE) { | ||
1606 | stop_dac(s); | ||
1607 | s->dma_dac.ready = 0; | ||
1608 | set_dac_rate(s, val); | ||
1609 | } | ||
1610 | } | ||
1611 | return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p); | ||
1612 | |||
1613 | case SNDCTL_DSP_STEREO: | ||
1614 | if (get_user(val, p)) | ||
1615 | return -EFAULT; | ||
1616 | fmtd = 0; | ||
1617 | fmtm = ~0; | ||
1618 | if (file->f_mode & FMODE_READ) { | ||
1619 | stop_adc(s); | ||
1620 | s->dma_adc.ready = 0; | ||
1621 | if (val) | ||
1622 | fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT; | ||
1623 | else | ||
1624 | fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT); | ||
1625 | } | ||
1626 | if (file->f_mode & FMODE_WRITE) { | ||
1627 | stop_dac(s); | ||
1628 | s->dma_dac.ready = 0; | ||
1629 | if (val) | ||
1630 | fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT; | ||
1631 | else | ||
1632 | fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT); | ||
1633 | } | ||
1634 | set_fmt(s, fmtm, fmtd); | ||
1635 | return 0; | ||
1636 | |||
1637 | case SNDCTL_DSP_CHANNELS: | ||
1638 | if (get_user(val, p)) | ||
1639 | return -EFAULT; | ||
1640 | if (val != 0) { | ||
1641 | fmtd = 0; | ||
1642 | fmtm = ~0; | ||
1643 | if (file->f_mode & FMODE_READ) { | ||
1644 | stop_adc(s); | ||
1645 | s->dma_adc.ready = 0; | ||
1646 | if (val >= 2) | ||
1647 | fmtd |= SV_CFMT_STEREO << SV_CFMT_CSHIFT; | ||
1648 | else | ||
1649 | fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_CSHIFT); | ||
1650 | } | ||
1651 | if (file->f_mode & FMODE_WRITE) { | ||
1652 | stop_dac(s); | ||
1653 | s->dma_dac.ready = 0; | ||
1654 | if (val >= 2) | ||
1655 | fmtd |= SV_CFMT_STEREO << SV_CFMT_ASHIFT; | ||
1656 | else | ||
1657 | fmtm &= ~(SV_CFMT_STEREO << SV_CFMT_ASHIFT); | ||
1658 | } | ||
1659 | set_fmt(s, fmtm, fmtd); | ||
1660 | } | ||
1661 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) | ||
1662 | : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p); | ||
1663 | |||
1664 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
1665 | return put_user(AFMT_S16_LE|AFMT_U8, p); | ||
1666 | |||
1667 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
1668 | if (get_user(val, p)) | ||
1669 | return -EFAULT; | ||
1670 | if (val != AFMT_QUERY) { | ||
1671 | fmtd = 0; | ||
1672 | fmtm = ~0; | ||
1673 | if (file->f_mode & FMODE_READ) { | ||
1674 | stop_adc(s); | ||
1675 | s->dma_adc.ready = 0; | ||
1676 | if (val == AFMT_S16_LE) | ||
1677 | fmtd |= SV_CFMT_16BIT << SV_CFMT_CSHIFT; | ||
1678 | else | ||
1679 | fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_CSHIFT); | ||
1680 | } | ||
1681 | if (file->f_mode & FMODE_WRITE) { | ||
1682 | stop_dac(s); | ||
1683 | s->dma_dac.ready = 0; | ||
1684 | if (val == AFMT_S16_LE) | ||
1685 | fmtd |= SV_CFMT_16BIT << SV_CFMT_ASHIFT; | ||
1686 | else | ||
1687 | fmtm &= ~(SV_CFMT_16BIT << SV_CFMT_ASHIFT); | ||
1688 | } | ||
1689 | set_fmt(s, fmtm, fmtd); | ||
1690 | } | ||
1691 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) | ||
1692 | : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? AFMT_S16_LE : AFMT_U8, p); | ||
1693 | |||
1694 | case SNDCTL_DSP_POST: | ||
1695 | return 0; | ||
1696 | |||
1697 | case SNDCTL_DSP_GETTRIGGER: | ||
1698 | val = 0; | ||
1699 | if (file->f_mode & FMODE_READ && s->enable & SV_CENABLE_RE) | ||
1700 | val |= PCM_ENABLE_INPUT; | ||
1701 | if (file->f_mode & FMODE_WRITE && s->enable & SV_CENABLE_PE) | ||
1702 | val |= PCM_ENABLE_OUTPUT; | ||
1703 | return put_user(val, p); | ||
1704 | |||
1705 | case SNDCTL_DSP_SETTRIGGER: | ||
1706 | if (get_user(val, p)) | ||
1707 | return -EFAULT; | ||
1708 | if (file->f_mode & FMODE_READ) { | ||
1709 | if (val & PCM_ENABLE_INPUT) { | ||
1710 | if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1))) | ||
1711 | return ret; | ||
1712 | s->dma_adc.enabled = 1; | ||
1713 | start_adc(s); | ||
1714 | } else { | ||
1715 | s->dma_adc.enabled = 0; | ||
1716 | stop_adc(s); | ||
1717 | } | ||
1718 | } | ||
1719 | if (file->f_mode & FMODE_WRITE) { | ||
1720 | if (val & PCM_ENABLE_OUTPUT) { | ||
1721 | if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0))) | ||
1722 | return ret; | ||
1723 | s->dma_dac.enabled = 1; | ||
1724 | start_dac(s); | ||
1725 | } else { | ||
1726 | s->dma_dac.enabled = 0; | ||
1727 | stop_dac(s); | ||
1728 | } | ||
1729 | } | ||
1730 | return 0; | ||
1731 | |||
1732 | case SNDCTL_DSP_GETOSPACE: | ||
1733 | if (!(file->f_mode & FMODE_WRITE)) | ||
1734 | return -EINVAL; | ||
1735 | if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0) | ||
1736 | return val; | ||
1737 | spin_lock_irqsave(&s->lock, flags); | ||
1738 | sv_update_ptr(s); | ||
1739 | abinfo.fragsize = s->dma_dac.fragsize; | ||
1740 | count = s->dma_dac.count; | ||
1741 | if (count < 0) | ||
1742 | count = 0; | ||
1743 | abinfo.bytes = s->dma_dac.dmasize - count; | ||
1744 | abinfo.fragstotal = s->dma_dac.numfrag; | ||
1745 | abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; | ||
1746 | spin_unlock_irqrestore(&s->lock, flags); | ||
1747 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1748 | |||
1749 | case SNDCTL_DSP_GETISPACE: | ||
1750 | if (!(file->f_mode & FMODE_READ)) | ||
1751 | return -EINVAL; | ||
1752 | if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0) | ||
1753 | return val; | ||
1754 | spin_lock_irqsave(&s->lock, flags); | ||
1755 | sv_update_ptr(s); | ||
1756 | abinfo.fragsize = s->dma_adc.fragsize; | ||
1757 | count = s->dma_adc.count; | ||
1758 | if (count < 0) | ||
1759 | count = 0; | ||
1760 | abinfo.bytes = count; | ||
1761 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
1762 | abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; | ||
1763 | spin_unlock_irqrestore(&s->lock, flags); | ||
1764 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1765 | |||
1766 | case SNDCTL_DSP_NONBLOCK: | ||
1767 | file->f_flags |= O_NONBLOCK; | ||
1768 | return 0; | ||
1769 | |||
1770 | case SNDCTL_DSP_GETODELAY: | ||
1771 | if (!(file->f_mode & FMODE_WRITE)) | ||
1772 | return -EINVAL; | ||
1773 | if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0) | ||
1774 | return val; | ||
1775 | spin_lock_irqsave(&s->lock, flags); | ||
1776 | sv_update_ptr(s); | ||
1777 | count = s->dma_dac.count; | ||
1778 | spin_unlock_irqrestore(&s->lock, flags); | ||
1779 | if (count < 0) | ||
1780 | count = 0; | ||
1781 | return put_user(count, p); | ||
1782 | |||
1783 | case SNDCTL_DSP_GETIPTR: | ||
1784 | if (!(file->f_mode & FMODE_READ)) | ||
1785 | return -EINVAL; | ||
1786 | if (!s->dma_adc.ready && (val = prog_dmabuf(s, 1)) != 0) | ||
1787 | return val; | ||
1788 | spin_lock_irqsave(&s->lock, flags); | ||
1789 | sv_update_ptr(s); | ||
1790 | cinfo.bytes = s->dma_adc.total_bytes; | ||
1791 | count = s->dma_adc.count; | ||
1792 | if (count < 0) | ||
1793 | count = 0; | ||
1794 | cinfo.blocks = count >> s->dma_adc.fragshift; | ||
1795 | cinfo.ptr = s->dma_adc.hwptr; | ||
1796 | if (s->dma_adc.mapped) | ||
1797 | s->dma_adc.count &= s->dma_adc.fragsize-1; | ||
1798 | spin_unlock_irqrestore(&s->lock, flags); | ||
1799 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1800 | return -EFAULT; | ||
1801 | return 0; | ||
1802 | |||
1803 | case SNDCTL_DSP_GETOPTR: | ||
1804 | if (!(file->f_mode & FMODE_WRITE)) | ||
1805 | return -EINVAL; | ||
1806 | if (!s->dma_dac.ready && (val = prog_dmabuf(s, 0)) != 0) | ||
1807 | return val; | ||
1808 | spin_lock_irqsave(&s->lock, flags); | ||
1809 | sv_update_ptr(s); | ||
1810 | cinfo.bytes = s->dma_dac.total_bytes; | ||
1811 | count = s->dma_dac.count; | ||
1812 | if (count < 0) | ||
1813 | count = 0; | ||
1814 | cinfo.blocks = count >> s->dma_dac.fragshift; | ||
1815 | cinfo.ptr = s->dma_dac.hwptr; | ||
1816 | if (s->dma_dac.mapped) | ||
1817 | s->dma_dac.count &= s->dma_dac.fragsize-1; | ||
1818 | spin_unlock_irqrestore(&s->lock, flags); | ||
1819 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1820 | return -EFAULT; | ||
1821 | return 0; | ||
1822 | |||
1823 | case SNDCTL_DSP_GETBLKSIZE: | ||
1824 | if (file->f_mode & FMODE_WRITE) { | ||
1825 | if ((val = prog_dmabuf(s, 0))) | ||
1826 | return val; | ||
1827 | return put_user(s->dma_dac.fragsize, p); | ||
1828 | } | ||
1829 | if ((val = prog_dmabuf(s, 1))) | ||
1830 | return val; | ||
1831 | return put_user(s->dma_adc.fragsize, p); | ||
1832 | |||
1833 | case SNDCTL_DSP_SETFRAGMENT: | ||
1834 | if (get_user(val, p)) | ||
1835 | return -EFAULT; | ||
1836 | if (file->f_mode & FMODE_READ) { | ||
1837 | s->dma_adc.ossfragshift = val & 0xffff; | ||
1838 | s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; | ||
1839 | if (s->dma_adc.ossfragshift < 4) | ||
1840 | s->dma_adc.ossfragshift = 4; | ||
1841 | if (s->dma_adc.ossfragshift > 15) | ||
1842 | s->dma_adc.ossfragshift = 15; | ||
1843 | if (s->dma_adc.ossmaxfrags < 4) | ||
1844 | s->dma_adc.ossmaxfrags = 4; | ||
1845 | } | ||
1846 | if (file->f_mode & FMODE_WRITE) { | ||
1847 | s->dma_dac.ossfragshift = val & 0xffff; | ||
1848 | s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; | ||
1849 | if (s->dma_dac.ossfragshift < 4) | ||
1850 | s->dma_dac.ossfragshift = 4; | ||
1851 | if (s->dma_dac.ossfragshift > 15) | ||
1852 | s->dma_dac.ossfragshift = 15; | ||
1853 | if (s->dma_dac.ossmaxfrags < 4) | ||
1854 | s->dma_dac.ossmaxfrags = 4; | ||
1855 | } | ||
1856 | return 0; | ||
1857 | |||
1858 | case SNDCTL_DSP_SUBDIVIDE: | ||
1859 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
1860 | (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) | ||
1861 | return -EINVAL; | ||
1862 | if (get_user(val, p)) | ||
1863 | return -EFAULT; | ||
1864 | if (val != 1 && val != 2 && val != 4) | ||
1865 | return -EINVAL; | ||
1866 | if (file->f_mode & FMODE_READ) | ||
1867 | s->dma_adc.subdivision = val; | ||
1868 | if (file->f_mode & FMODE_WRITE) | ||
1869 | s->dma_dac.subdivision = val; | ||
1870 | return 0; | ||
1871 | |||
1872 | case SOUND_PCM_READ_RATE: | ||
1873 | return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, p); | ||
1874 | |||
1875 | case SOUND_PCM_READ_CHANNELS: | ||
1876 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT) | ||
1877 | : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, p); | ||
1878 | |||
1879 | case SOUND_PCM_READ_BITS: | ||
1880 | return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT) | ||
1881 | : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, p); | ||
1882 | |||
1883 | case SOUND_PCM_WRITE_FILTER: | ||
1884 | case SNDCTL_DSP_SETSYNCRO: | ||
1885 | case SOUND_PCM_READ_FILTER: | ||
1886 | return -EINVAL; | ||
1887 | |||
1888 | } | ||
1889 | return mixer_ioctl(s, cmd, arg); | ||
1890 | } | ||
1891 | |||
1892 | static int sv_open(struct inode *inode, struct file *file) | ||
1893 | { | ||
1894 | int minor = iminor(inode); | ||
1895 | DECLARE_WAITQUEUE(wait, current); | ||
1896 | unsigned char fmtm = ~0, fmts = 0; | ||
1897 | struct list_head *list; | ||
1898 | struct sv_state *s; | ||
1899 | |||
1900 | for (list = devs.next; ; list = list->next) { | ||
1901 | if (list == &devs) | ||
1902 | return -ENODEV; | ||
1903 | s = list_entry(list, struct sv_state, devs); | ||
1904 | if (!((s->dev_audio ^ minor) & ~0xf)) | ||
1905 | break; | ||
1906 | } | ||
1907 | VALIDATE_STATE(s); | ||
1908 | file->private_data = s; | ||
1909 | /* wait for device to become free */ | ||
1910 | mutex_lock(&s->open_mutex); | ||
1911 | while (s->open_mode & file->f_mode) { | ||
1912 | if (file->f_flags & O_NONBLOCK) { | ||
1913 | mutex_unlock(&s->open_mutex); | ||
1914 | return -EBUSY; | ||
1915 | } | ||
1916 | add_wait_queue(&s->open_wait, &wait); | ||
1917 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1918 | mutex_unlock(&s->open_mutex); | ||
1919 | schedule(); | ||
1920 | remove_wait_queue(&s->open_wait, &wait); | ||
1921 | set_current_state(TASK_RUNNING); | ||
1922 | if (signal_pending(current)) | ||
1923 | return -ERESTARTSYS; | ||
1924 | mutex_lock(&s->open_mutex); | ||
1925 | } | ||
1926 | if (file->f_mode & FMODE_READ) { | ||
1927 | fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT); | ||
1928 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1929 | fmts |= SV_CFMT_16BIT << SV_CFMT_CSHIFT; | ||
1930 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; | ||
1931 | s->dma_adc.enabled = 1; | ||
1932 | set_adc_rate(s, 8000); | ||
1933 | } | ||
1934 | if (file->f_mode & FMODE_WRITE) { | ||
1935 | fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_ASHIFT); | ||
1936 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1937 | fmts |= SV_CFMT_16BIT << SV_CFMT_ASHIFT; | ||
1938 | s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; | ||
1939 | s->dma_dac.enabled = 1; | ||
1940 | set_dac_rate(s, 8000); | ||
1941 | } | ||
1942 | set_fmt(s, fmtm, fmts); | ||
1943 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
1944 | mutex_unlock(&s->open_mutex); | ||
1945 | return nonseekable_open(inode, file); | ||
1946 | } | ||
1947 | |||
1948 | static int sv_release(struct inode *inode, struct file *file) | ||
1949 | { | ||
1950 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
1951 | |||
1952 | VALIDATE_STATE(s); | ||
1953 | lock_kernel(); | ||
1954 | if (file->f_mode & FMODE_WRITE) | ||
1955 | drain_dac(s, file->f_flags & O_NONBLOCK); | ||
1956 | mutex_lock(&s->open_mutex); | ||
1957 | if (file->f_mode & FMODE_WRITE) { | ||
1958 | stop_dac(s); | ||
1959 | dealloc_dmabuf(s, &s->dma_dac); | ||
1960 | } | ||
1961 | if (file->f_mode & FMODE_READ) { | ||
1962 | stop_adc(s); | ||
1963 | dealloc_dmabuf(s, &s->dma_adc); | ||
1964 | } | ||
1965 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); | ||
1966 | wake_up(&s->open_wait); | ||
1967 | mutex_unlock(&s->open_mutex); | ||
1968 | unlock_kernel(); | ||
1969 | return 0; | ||
1970 | } | ||
1971 | |||
1972 | static /*const*/ struct file_operations sv_audio_fops = { | ||
1973 | .owner = THIS_MODULE, | ||
1974 | .llseek = no_llseek, | ||
1975 | .read = sv_read, | ||
1976 | .write = sv_write, | ||
1977 | .poll = sv_poll, | ||
1978 | .ioctl = sv_ioctl, | ||
1979 | .mmap = sv_mmap, | ||
1980 | .open = sv_open, | ||
1981 | .release = sv_release, | ||
1982 | }; | ||
1983 | |||
1984 | /* --------------------------------------------------------------------- */ | ||
1985 | |||
1986 | static ssize_t sv_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1987 | { | ||
1988 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
1989 | DECLARE_WAITQUEUE(wait, current); | ||
1990 | ssize_t ret; | ||
1991 | unsigned long flags; | ||
1992 | unsigned ptr; | ||
1993 | int cnt; | ||
1994 | |||
1995 | VALIDATE_STATE(s); | ||
1996 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1997 | return -EFAULT; | ||
1998 | if (count == 0) | ||
1999 | return 0; | ||
2000 | ret = 0; | ||
2001 | add_wait_queue(&s->midi.iwait, &wait); | ||
2002 | while (count > 0) { | ||
2003 | spin_lock_irqsave(&s->lock, flags); | ||
2004 | ptr = s->midi.ird; | ||
2005 | cnt = MIDIINBUF - ptr; | ||
2006 | if (s->midi.icnt < cnt) | ||
2007 | cnt = s->midi.icnt; | ||
2008 | if (cnt <= 0) | ||
2009 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2010 | spin_unlock_irqrestore(&s->lock, flags); | ||
2011 | if (cnt > count) | ||
2012 | cnt = count; | ||
2013 | if (cnt <= 0) { | ||
2014 | if (file->f_flags & O_NONBLOCK) { | ||
2015 | if (!ret) | ||
2016 | ret = -EAGAIN; | ||
2017 | break; | ||
2018 | } | ||
2019 | schedule(); | ||
2020 | if (signal_pending(current)) { | ||
2021 | if (!ret) | ||
2022 | ret = -ERESTARTSYS; | ||
2023 | break; | ||
2024 | } | ||
2025 | continue; | ||
2026 | } | ||
2027 | if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { | ||
2028 | if (!ret) | ||
2029 | ret = -EFAULT; | ||
2030 | break; | ||
2031 | } | ||
2032 | ptr = (ptr + cnt) % MIDIINBUF; | ||
2033 | spin_lock_irqsave(&s->lock, flags); | ||
2034 | s->midi.ird = ptr; | ||
2035 | s->midi.icnt -= cnt; | ||
2036 | spin_unlock_irqrestore(&s->lock, flags); | ||
2037 | count -= cnt; | ||
2038 | buffer += cnt; | ||
2039 | ret += cnt; | ||
2040 | break; | ||
2041 | } | ||
2042 | __set_current_state(TASK_RUNNING); | ||
2043 | remove_wait_queue(&s->midi.iwait, &wait); | ||
2044 | return ret; | ||
2045 | } | ||
2046 | |||
2047 | static ssize_t sv_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
2048 | { | ||
2049 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
2050 | DECLARE_WAITQUEUE(wait, current); | ||
2051 | ssize_t ret; | ||
2052 | unsigned long flags; | ||
2053 | unsigned ptr; | ||
2054 | int cnt; | ||
2055 | |||
2056 | VALIDATE_STATE(s); | ||
2057 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
2058 | return -EFAULT; | ||
2059 | if (count == 0) | ||
2060 | return 0; | ||
2061 | ret = 0; | ||
2062 | add_wait_queue(&s->midi.owait, &wait); | ||
2063 | while (count > 0) { | ||
2064 | spin_lock_irqsave(&s->lock, flags); | ||
2065 | ptr = s->midi.owr; | ||
2066 | cnt = MIDIOUTBUF - ptr; | ||
2067 | if (s->midi.ocnt + cnt > MIDIOUTBUF) | ||
2068 | cnt = MIDIOUTBUF - s->midi.ocnt; | ||
2069 | if (cnt <= 0) { | ||
2070 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2071 | sv_handle_midi(s); | ||
2072 | } | ||
2073 | spin_unlock_irqrestore(&s->lock, flags); | ||
2074 | if (cnt > count) | ||
2075 | cnt = count; | ||
2076 | if (cnt <= 0) { | ||
2077 | if (file->f_flags & O_NONBLOCK) { | ||
2078 | if (!ret) | ||
2079 | ret = -EAGAIN; | ||
2080 | break; | ||
2081 | } | ||
2082 | schedule(); | ||
2083 | if (signal_pending(current)) { | ||
2084 | if (!ret) | ||
2085 | ret = -ERESTARTSYS; | ||
2086 | break; | ||
2087 | } | ||
2088 | continue; | ||
2089 | } | ||
2090 | if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { | ||
2091 | if (!ret) | ||
2092 | ret = -EFAULT; | ||
2093 | break; | ||
2094 | } | ||
2095 | ptr = (ptr + cnt) % MIDIOUTBUF; | ||
2096 | spin_lock_irqsave(&s->lock, flags); | ||
2097 | s->midi.owr = ptr; | ||
2098 | s->midi.ocnt += cnt; | ||
2099 | spin_unlock_irqrestore(&s->lock, flags); | ||
2100 | count -= cnt; | ||
2101 | buffer += cnt; | ||
2102 | ret += cnt; | ||
2103 | spin_lock_irqsave(&s->lock, flags); | ||
2104 | sv_handle_midi(s); | ||
2105 | spin_unlock_irqrestore(&s->lock, flags); | ||
2106 | } | ||
2107 | __set_current_state(TASK_RUNNING); | ||
2108 | remove_wait_queue(&s->midi.owait, &wait); | ||
2109 | return ret; | ||
2110 | } | ||
2111 | |||
2112 | /* No kernel lock - we have our own spinlock */ | ||
2113 | static unsigned int sv_midi_poll(struct file *file, struct poll_table_struct *wait) | ||
2114 | { | ||
2115 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
2116 | unsigned long flags; | ||
2117 | unsigned int mask = 0; | ||
2118 | |||
2119 | VALIDATE_STATE(s); | ||
2120 | if (file->f_mode & FMODE_WRITE) | ||
2121 | poll_wait(file, &s->midi.owait, wait); | ||
2122 | if (file->f_mode & FMODE_READ) | ||
2123 | poll_wait(file, &s->midi.iwait, wait); | ||
2124 | spin_lock_irqsave(&s->lock, flags); | ||
2125 | if (file->f_mode & FMODE_READ) { | ||
2126 | if (s->midi.icnt > 0) | ||
2127 | mask |= POLLIN | POLLRDNORM; | ||
2128 | } | ||
2129 | if (file->f_mode & FMODE_WRITE) { | ||
2130 | if (s->midi.ocnt < MIDIOUTBUF) | ||
2131 | mask |= POLLOUT | POLLWRNORM; | ||
2132 | } | ||
2133 | spin_unlock_irqrestore(&s->lock, flags); | ||
2134 | return mask; | ||
2135 | } | ||
2136 | |||
2137 | static int sv_midi_open(struct inode *inode, struct file *file) | ||
2138 | { | ||
2139 | int minor = iminor(inode); | ||
2140 | DECLARE_WAITQUEUE(wait, current); | ||
2141 | unsigned long flags; | ||
2142 | struct list_head *list; | ||
2143 | struct sv_state *s; | ||
2144 | |||
2145 | for (list = devs.next; ; list = list->next) { | ||
2146 | if (list == &devs) | ||
2147 | return -ENODEV; | ||
2148 | s = list_entry(list, struct sv_state, devs); | ||
2149 | if (s->dev_midi == minor) | ||
2150 | break; | ||
2151 | } | ||
2152 | VALIDATE_STATE(s); | ||
2153 | file->private_data = s; | ||
2154 | /* wait for device to become free */ | ||
2155 | mutex_lock(&s->open_mutex); | ||
2156 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { | ||
2157 | if (file->f_flags & O_NONBLOCK) { | ||
2158 | mutex_unlock(&s->open_mutex); | ||
2159 | return -EBUSY; | ||
2160 | } | ||
2161 | add_wait_queue(&s->open_wait, &wait); | ||
2162 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2163 | mutex_unlock(&s->open_mutex); | ||
2164 | schedule(); | ||
2165 | remove_wait_queue(&s->open_wait, &wait); | ||
2166 | set_current_state(TASK_RUNNING); | ||
2167 | if (signal_pending(current)) | ||
2168 | return -ERESTARTSYS; | ||
2169 | mutex_lock(&s->open_mutex); | ||
2170 | } | ||
2171 | spin_lock_irqsave(&s->lock, flags); | ||
2172 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
2173 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
2174 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
2175 | //outb(inb(s->ioenh + SV_CODEC_CONTROL) | SV_CCTRL_WAVETABLE, s->ioenh + SV_CODEC_CONTROL); | ||
2176 | outb(inb(s->ioenh + SV_CODEC_INTMASK) | SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK); | ||
2177 | wrindir(s, SV_CIUARTCONTROL, 5); /* output MIDI data to external and internal synth */ | ||
2178 | wrindir(s, SV_CIWAVETABLESRC, 1); /* Wavetable in PC RAM */ | ||
2179 | outb(0xff, s->iomidi+1); /* reset command */ | ||
2180 | outb(0x3f, s->iomidi+1); /* uart command */ | ||
2181 | if (!(inb(s->iomidi+1) & 0x80)) | ||
2182 | inb(s->iomidi); | ||
2183 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
2184 | init_timer(&s->midi.timer); | ||
2185 | s->midi.timer.expires = jiffies+1; | ||
2186 | s->midi.timer.data = (unsigned long)s; | ||
2187 | s->midi.timer.function = sv_midi_timer; | ||
2188 | add_timer(&s->midi.timer); | ||
2189 | } | ||
2190 | if (file->f_mode & FMODE_READ) { | ||
2191 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
2192 | } | ||
2193 | if (file->f_mode & FMODE_WRITE) { | ||
2194 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
2195 | } | ||
2196 | spin_unlock_irqrestore(&s->lock, flags); | ||
2197 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); | ||
2198 | mutex_unlock(&s->open_mutex); | ||
2199 | return nonseekable_open(inode, file); | ||
2200 | } | ||
2201 | |||
2202 | static int sv_midi_release(struct inode *inode, struct file *file) | ||
2203 | { | ||
2204 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
2205 | DECLARE_WAITQUEUE(wait, current); | ||
2206 | unsigned long flags; | ||
2207 | unsigned count, tmo; | ||
2208 | |||
2209 | VALIDATE_STATE(s); | ||
2210 | |||
2211 | lock_kernel(); | ||
2212 | if (file->f_mode & FMODE_WRITE) { | ||
2213 | add_wait_queue(&s->midi.owait, &wait); | ||
2214 | for (;;) { | ||
2215 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2216 | spin_lock_irqsave(&s->lock, flags); | ||
2217 | count = s->midi.ocnt; | ||
2218 | spin_unlock_irqrestore(&s->lock, flags); | ||
2219 | if (count <= 0) | ||
2220 | break; | ||
2221 | if (signal_pending(current)) | ||
2222 | break; | ||
2223 | if (file->f_flags & O_NONBLOCK) { | ||
2224 | remove_wait_queue(&s->midi.owait, &wait); | ||
2225 | set_current_state(TASK_RUNNING); | ||
2226 | unlock_kernel(); | ||
2227 | return -EBUSY; | ||
2228 | } | ||
2229 | tmo = (count * HZ) / 3100; | ||
2230 | if (!schedule_timeout(tmo ? : 1) && tmo) | ||
2231 | printk(KERN_DEBUG "sv: midi timed out??\n"); | ||
2232 | } | ||
2233 | remove_wait_queue(&s->midi.owait, &wait); | ||
2234 | set_current_state(TASK_RUNNING); | ||
2235 | } | ||
2236 | mutex_lock(&s->open_mutex); | ||
2237 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); | ||
2238 | spin_lock_irqsave(&s->lock, flags); | ||
2239 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
2240 | outb(inb(s->ioenh + SV_CODEC_INTMASK) & ~SV_CINTMASK_MIDI, s->ioenh + SV_CODEC_INTMASK); | ||
2241 | del_timer(&s->midi.timer); | ||
2242 | } | ||
2243 | spin_unlock_irqrestore(&s->lock, flags); | ||
2244 | wake_up(&s->open_wait); | ||
2245 | mutex_unlock(&s->open_mutex); | ||
2246 | unlock_kernel(); | ||
2247 | return 0; | ||
2248 | } | ||
2249 | |||
2250 | static /*const*/ struct file_operations sv_midi_fops = { | ||
2251 | .owner = THIS_MODULE, | ||
2252 | .llseek = no_llseek, | ||
2253 | .read = sv_midi_read, | ||
2254 | .write = sv_midi_write, | ||
2255 | .poll = sv_midi_poll, | ||
2256 | .open = sv_midi_open, | ||
2257 | .release = sv_midi_release, | ||
2258 | }; | ||
2259 | |||
2260 | /* --------------------------------------------------------------------- */ | ||
2261 | |||
2262 | static int sv_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
2263 | { | ||
2264 | static const unsigned char op_offset[18] = { | ||
2265 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, | ||
2266 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, | ||
2267 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 | ||
2268 | }; | ||
2269 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
2270 | struct dm_fm_voice v; | ||
2271 | struct dm_fm_note n; | ||
2272 | struct dm_fm_params p; | ||
2273 | unsigned int io; | ||
2274 | unsigned int regb; | ||
2275 | |||
2276 | switch (cmd) { | ||
2277 | case FM_IOCTL_RESET: | ||
2278 | for (regb = 0xb0; regb < 0xb9; regb++) { | ||
2279 | outb(regb, s->iosynth); | ||
2280 | outb(0, s->iosynth+1); | ||
2281 | outb(regb, s->iosynth+2); | ||
2282 | outb(0, s->iosynth+3); | ||
2283 | } | ||
2284 | return 0; | ||
2285 | |||
2286 | case FM_IOCTL_PLAY_NOTE: | ||
2287 | if (copy_from_user(&n, (void __user *)arg, sizeof(n))) | ||
2288 | return -EFAULT; | ||
2289 | if (n.voice >= 18) | ||
2290 | return -EINVAL; | ||
2291 | if (n.voice >= 9) { | ||
2292 | regb = n.voice - 9; | ||
2293 | io = s->iosynth+2; | ||
2294 | } else { | ||
2295 | regb = n.voice; | ||
2296 | io = s->iosynth; | ||
2297 | } | ||
2298 | outb(0xa0 + regb, io); | ||
2299 | outb(n.fnum & 0xff, io+1); | ||
2300 | outb(0xb0 + regb, io); | ||
2301 | outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1); | ||
2302 | return 0; | ||
2303 | |||
2304 | case FM_IOCTL_SET_VOICE: | ||
2305 | if (copy_from_user(&v, (void __user *)arg, sizeof(v))) | ||
2306 | return -EFAULT; | ||
2307 | if (v.voice >= 18) | ||
2308 | return -EINVAL; | ||
2309 | regb = op_offset[v.voice]; | ||
2310 | io = s->iosynth + ((v.op & 1) << 1); | ||
2311 | outb(0x20 + regb, io); | ||
2312 | outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | | ||
2313 | ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1); | ||
2314 | outb(0x40 + regb, io); | ||
2315 | outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1); | ||
2316 | outb(0x60 + regb, io); | ||
2317 | outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1); | ||
2318 | outb(0x80 + regb, io); | ||
2319 | outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1); | ||
2320 | outb(0xe0 + regb, io); | ||
2321 | outb(v.waveform & 0x7, io+1); | ||
2322 | if (n.voice >= 9) { | ||
2323 | regb = n.voice - 9; | ||
2324 | io = s->iosynth+2; | ||
2325 | } else { | ||
2326 | regb = n.voice; | ||
2327 | io = s->iosynth; | ||
2328 | } | ||
2329 | outb(0xc0 + regb, io); | ||
2330 | outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) | | ||
2331 | (v.connection & 1), io+1); | ||
2332 | return 0; | ||
2333 | |||
2334 | case FM_IOCTL_SET_PARAMS: | ||
2335 | if (copy_from_user(&p, (void *__user )arg, sizeof(p))) | ||
2336 | return -EFAULT; | ||
2337 | outb(0x08, s->iosynth); | ||
2338 | outb((p.kbd_split & 1) << 6, s->iosynth+1); | ||
2339 | outb(0xbd, s->iosynth); | ||
2340 | outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) | | ||
2341 | ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), s->iosynth+1); | ||
2342 | return 0; | ||
2343 | |||
2344 | case FM_IOCTL_SET_OPL: | ||
2345 | outb(4, s->iosynth+2); | ||
2346 | outb(arg, s->iosynth+3); | ||
2347 | return 0; | ||
2348 | |||
2349 | case FM_IOCTL_SET_MODE: | ||
2350 | outb(5, s->iosynth+2); | ||
2351 | outb(arg & 1, s->iosynth+3); | ||
2352 | return 0; | ||
2353 | |||
2354 | default: | ||
2355 | return -EINVAL; | ||
2356 | } | ||
2357 | } | ||
2358 | |||
2359 | static int sv_dmfm_open(struct inode *inode, struct file *file) | ||
2360 | { | ||
2361 | int minor = iminor(inode); | ||
2362 | DECLARE_WAITQUEUE(wait, current); | ||
2363 | struct list_head *list; | ||
2364 | struct sv_state *s; | ||
2365 | |||
2366 | for (list = devs.next; ; list = list->next) { | ||
2367 | if (list == &devs) | ||
2368 | return -ENODEV; | ||
2369 | s = list_entry(list, struct sv_state, devs); | ||
2370 | if (s->dev_dmfm == minor) | ||
2371 | break; | ||
2372 | } | ||
2373 | VALIDATE_STATE(s); | ||
2374 | file->private_data = s; | ||
2375 | /* wait for device to become free */ | ||
2376 | mutex_lock(&s->open_mutex); | ||
2377 | while (s->open_mode & FMODE_DMFM) { | ||
2378 | if (file->f_flags & O_NONBLOCK) { | ||
2379 | mutex_unlock(&s->open_mutex); | ||
2380 | return -EBUSY; | ||
2381 | } | ||
2382 | add_wait_queue(&s->open_wait, &wait); | ||
2383 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2384 | mutex_unlock(&s->open_mutex); | ||
2385 | schedule(); | ||
2386 | remove_wait_queue(&s->open_wait, &wait); | ||
2387 | set_current_state(TASK_RUNNING); | ||
2388 | if (signal_pending(current)) | ||
2389 | return -ERESTARTSYS; | ||
2390 | mutex_lock(&s->open_mutex); | ||
2391 | } | ||
2392 | /* init the stuff */ | ||
2393 | outb(1, s->iosynth); | ||
2394 | outb(0x20, s->iosynth+1); /* enable waveforms */ | ||
2395 | outb(4, s->iosynth+2); | ||
2396 | outb(0, s->iosynth+3); /* no 4op enabled */ | ||
2397 | outb(5, s->iosynth+2); | ||
2398 | outb(1, s->iosynth+3); /* enable OPL3 */ | ||
2399 | s->open_mode |= FMODE_DMFM; | ||
2400 | mutex_unlock(&s->open_mutex); | ||
2401 | return nonseekable_open(inode, file); | ||
2402 | } | ||
2403 | |||
2404 | static int sv_dmfm_release(struct inode *inode, struct file *file) | ||
2405 | { | ||
2406 | struct sv_state *s = (struct sv_state *)file->private_data; | ||
2407 | unsigned int regb; | ||
2408 | |||
2409 | VALIDATE_STATE(s); | ||
2410 | lock_kernel(); | ||
2411 | mutex_lock(&s->open_mutex); | ||
2412 | s->open_mode &= ~FMODE_DMFM; | ||
2413 | for (regb = 0xb0; regb < 0xb9; regb++) { | ||
2414 | outb(regb, s->iosynth); | ||
2415 | outb(0, s->iosynth+1); | ||
2416 | outb(regb, s->iosynth+2); | ||
2417 | outb(0, s->iosynth+3); | ||
2418 | } | ||
2419 | wake_up(&s->open_wait); | ||
2420 | mutex_unlock(&s->open_mutex); | ||
2421 | unlock_kernel(); | ||
2422 | return 0; | ||
2423 | } | ||
2424 | |||
2425 | static /*const*/ struct file_operations sv_dmfm_fops = { | ||
2426 | .owner = THIS_MODULE, | ||
2427 | .llseek = no_llseek, | ||
2428 | .ioctl = sv_dmfm_ioctl, | ||
2429 | .open = sv_dmfm_open, | ||
2430 | .release = sv_dmfm_release, | ||
2431 | }; | ||
2432 | |||
2433 | /* --------------------------------------------------------------------- */ | ||
2434 | |||
2435 | /* maximum number of devices; only used for command line params */ | ||
2436 | #define NR_DEVICE 5 | ||
2437 | |||
2438 | static int reverb[NR_DEVICE]; | ||
2439 | |||
2440 | #if 0 | ||
2441 | static int wavetable[NR_DEVICE]; | ||
2442 | #endif | ||
2443 | |||
2444 | static unsigned int devindex; | ||
2445 | |||
2446 | module_param_array(reverb, bool, NULL, 0); | ||
2447 | MODULE_PARM_DESC(reverb, "if 1 enables the reverb circuitry. NOTE: your card must have the reverb RAM"); | ||
2448 | #if 0 | ||
2449 | MODULE_PARM(wavetable, "1-" __MODULE_STRING(NR_DEVICE) "i"); | ||
2450 | MODULE_PARM_DESC(wavetable, "if 1 the wavetable synth is enabled"); | ||
2451 | #endif | ||
2452 | |||
2453 | MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); | ||
2454 | MODULE_DESCRIPTION("S3 SonicVibes Driver"); | ||
2455 | MODULE_LICENSE("GPL"); | ||
2456 | |||
2457 | |||
2458 | /* --------------------------------------------------------------------- */ | ||
2459 | |||
2460 | static struct initvol { | ||
2461 | int mixch; | ||
2462 | int vol; | ||
2463 | } initvol[] __devinitdata = { | ||
2464 | { SOUND_MIXER_WRITE_RECLEV, 0x4040 }, | ||
2465 | { SOUND_MIXER_WRITE_LINE1, 0x4040 }, | ||
2466 | { SOUND_MIXER_WRITE_CD, 0x4040 }, | ||
2467 | { SOUND_MIXER_WRITE_LINE, 0x4040 }, | ||
2468 | { SOUND_MIXER_WRITE_MIC, 0x4040 }, | ||
2469 | { SOUND_MIXER_WRITE_SYNTH, 0x4040 }, | ||
2470 | { SOUND_MIXER_WRITE_LINE2, 0x4040 }, | ||
2471 | { SOUND_MIXER_WRITE_VOLUME, 0x4040 }, | ||
2472 | { SOUND_MIXER_WRITE_PCM, 0x4040 } | ||
2473 | }; | ||
2474 | |||
2475 | #define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \ | ||
2476 | (pci_resource_flags((dev), (num)) & IORESOURCE_IO)) | ||
2477 | |||
2478 | #ifdef SUPPORT_JOYSTICK | ||
2479 | static int __devinit sv_register_gameport(struct sv_state *s, int io_port) | ||
2480 | { | ||
2481 | struct gameport *gp; | ||
2482 | |||
2483 | if (!request_region(io_port, SV_EXTENT_GAME, "S3 SonicVibes Gameport")) { | ||
2484 | printk(KERN_ERR "sv: gameport io ports are in use\n"); | ||
2485 | return -EBUSY; | ||
2486 | } | ||
2487 | |||
2488 | s->gameport = gp = gameport_allocate_port(); | ||
2489 | if (!gp) { | ||
2490 | printk(KERN_ERR "sv: can not allocate memory for gameport\n"); | ||
2491 | release_region(io_port, SV_EXTENT_GAME); | ||
2492 | return -ENOMEM; | ||
2493 | } | ||
2494 | |||
2495 | gameport_set_name(gp, "S3 SonicVibes Gameport"); | ||
2496 | gameport_set_phys(gp, "isa%04x/gameport0", io_port); | ||
2497 | gp->dev.parent = &s->dev->dev; | ||
2498 | gp->io = io_port; | ||
2499 | |||
2500 | gameport_register_port(gp); | ||
2501 | |||
2502 | return 0; | ||
2503 | } | ||
2504 | |||
2505 | static inline void sv_unregister_gameport(struct sv_state *s) | ||
2506 | { | ||
2507 | if (s->gameport) { | ||
2508 | int gpio = s->gameport->io; | ||
2509 | gameport_unregister_port(s->gameport); | ||
2510 | release_region(gpio, SV_EXTENT_GAME); | ||
2511 | } | ||
2512 | } | ||
2513 | #else | ||
2514 | static inline int sv_register_gameport(struct sv_state *s, int io_port) { return -ENOSYS; } | ||
2515 | static inline void sv_unregister_gameport(struct sv_state *s) { } | ||
2516 | #endif /* SUPPORT_JOYSTICK */ | ||
2517 | |||
2518 | static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) | ||
2519 | { | ||
2520 | static char __devinitdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller"; | ||
2521 | struct sv_state *s; | ||
2522 | mm_segment_t fs; | ||
2523 | int i, val, ret; | ||
2524 | int gpio; | ||
2525 | char *ddmaname; | ||
2526 | unsigned ddmanamelen; | ||
2527 | |||
2528 | if ((ret=pci_enable_device(pcidev))) | ||
2529 | return ret; | ||
2530 | |||
2531 | if (!RSRCISIOREGION(pcidev, RESOURCE_SB) || | ||
2532 | !RSRCISIOREGION(pcidev, RESOURCE_ENH) || | ||
2533 | !RSRCISIOREGION(pcidev, RESOURCE_SYNTH) || | ||
2534 | !RSRCISIOREGION(pcidev, RESOURCE_MIDI) || | ||
2535 | !RSRCISIOREGION(pcidev, RESOURCE_GAME)) | ||
2536 | return -ENODEV; | ||
2537 | if (pcidev->irq == 0) | ||
2538 | return -ENODEV; | ||
2539 | if (pci_set_dma_mask(pcidev, DMA_24BIT_MASK)) { | ||
2540 | printk(KERN_WARNING "sonicvibes: architecture does not support 24bit PCI busmaster DMA\n"); | ||
2541 | return -ENODEV; | ||
2542 | } | ||
2543 | /* try to allocate a DDMA resource if not already available */ | ||
2544 | if (!RSRCISIOREGION(pcidev, RESOURCE_DDMA)) { | ||
2545 | pcidev->resource[RESOURCE_DDMA].start = 0; | ||
2546 | pcidev->resource[RESOURCE_DDMA].end = 2*SV_EXTENT_DMA-1; | ||
2547 | pcidev->resource[RESOURCE_DDMA].flags = PCI_BASE_ADDRESS_SPACE_IO | IORESOURCE_IO; | ||
2548 | ddmanamelen = strlen(sv_ddma_name)+1; | ||
2549 | if (!(ddmaname = kmalloc(ddmanamelen, GFP_KERNEL))) | ||
2550 | return -1; | ||
2551 | memcpy(ddmaname, sv_ddma_name, ddmanamelen); | ||
2552 | pcidev->resource[RESOURCE_DDMA].name = ddmaname; | ||
2553 | if (pci_assign_resource(pcidev, RESOURCE_DDMA)) { | ||
2554 | pcidev->resource[RESOURCE_DDMA].name = NULL; | ||
2555 | kfree(ddmaname); | ||
2556 | printk(KERN_ERR "sv: cannot allocate DDMA controller io ports\n"); | ||
2557 | return -EBUSY; | ||
2558 | } | ||
2559 | } | ||
2560 | if (!(s = kmalloc(sizeof(struct sv_state), GFP_KERNEL))) { | ||
2561 | printk(KERN_WARNING "sv: out of memory\n"); | ||
2562 | return -ENOMEM; | ||
2563 | } | ||
2564 | memset(s, 0, sizeof(struct sv_state)); | ||
2565 | init_waitqueue_head(&s->dma_adc.wait); | ||
2566 | init_waitqueue_head(&s->dma_dac.wait); | ||
2567 | init_waitqueue_head(&s->open_wait); | ||
2568 | init_waitqueue_head(&s->midi.iwait); | ||
2569 | init_waitqueue_head(&s->midi.owait); | ||
2570 | mutex_init(&s->open_mutex); | ||
2571 | spin_lock_init(&s->lock); | ||
2572 | s->magic = SV_MAGIC; | ||
2573 | s->dev = pcidev; | ||
2574 | s->iosb = pci_resource_start(pcidev, RESOURCE_SB); | ||
2575 | s->ioenh = pci_resource_start(pcidev, RESOURCE_ENH); | ||
2576 | s->iosynth = pci_resource_start(pcidev, RESOURCE_SYNTH); | ||
2577 | s->iomidi = pci_resource_start(pcidev, RESOURCE_MIDI); | ||
2578 | s->iodmaa = pci_resource_start(pcidev, RESOURCE_DDMA); | ||
2579 | s->iodmac = pci_resource_start(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA; | ||
2580 | gpio = pci_resource_start(pcidev, RESOURCE_GAME); | ||
2581 | pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9); /* enable and use extended mode */ | ||
2582 | pci_write_config_dword(pcidev, 0x48, s->iodmac | 9); /* enable */ | ||
2583 | printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#x %#x %#x\n", | ||
2584 | s->iosb, s->ioenh, s->iosynth, s->iomidi, gpio, s->iodmaa, s->iodmac); | ||
2585 | s->irq = pcidev->irq; | ||
2586 | |||
2587 | /* hack */ | ||
2588 | pci_write_config_dword(pcidev, 0x60, wavetable_mem >> 12); /* wavetable base address */ | ||
2589 | |||
2590 | ret = -EBUSY; | ||
2591 | if (!request_region(s->ioenh, SV_EXTENT_ENH, "S3 SonicVibes PCM")) { | ||
2592 | printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1); | ||
2593 | goto err_region5; | ||
2594 | } | ||
2595 | if (!request_region(s->iodmaa, SV_EXTENT_DMA, "S3 SonicVibes DMAA")) { | ||
2596 | printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmaa, s->iodmaa+SV_EXTENT_DMA-1); | ||
2597 | goto err_region4; | ||
2598 | } | ||
2599 | if (!request_region(s->iodmac, SV_EXTENT_DMA, "S3 SonicVibes DMAC")) { | ||
2600 | printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iodmac, s->iodmac+SV_EXTENT_DMA-1); | ||
2601 | goto err_region3; | ||
2602 | } | ||
2603 | if (!request_region(s->iomidi, SV_EXTENT_MIDI, "S3 SonicVibes Midi")) { | ||
2604 | printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1); | ||
2605 | goto err_region2; | ||
2606 | } | ||
2607 | if (!request_region(s->iosynth, SV_EXTENT_SYNTH, "S3 SonicVibes Synth")) { | ||
2608 | printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1); | ||
2609 | goto err_region1; | ||
2610 | } | ||
2611 | |||
2612 | /* initialize codec registers */ | ||
2613 | outb(0x80, s->ioenh + SV_CODEC_CONTROL); /* assert reset */ | ||
2614 | udelay(50); | ||
2615 | outb(0x00, s->ioenh + SV_CODEC_CONTROL); /* deassert reset */ | ||
2616 | udelay(50); | ||
2617 | outb(SV_CCTRL_INTADRIVE | SV_CCTRL_ENHANCED /*| SV_CCTRL_WAVETABLE */ | ||
2618 | | (reverb[devindex] ? SV_CCTRL_REVERB : 0), s->ioenh + SV_CODEC_CONTROL); | ||
2619 | inb(s->ioenh + SV_CODEC_STATUS); /* clear ints */ | ||
2620 | wrindir(s, SV_CIDRIVECONTROL, 0); /* drive current 16mA */ | ||
2621 | wrindir(s, SV_CIENABLE, s->enable = 0); /* disable DMAA and DMAC */ | ||
2622 | outb(~(SV_CINTMASK_DMAA | SV_CINTMASK_DMAC), s->ioenh + SV_CODEC_INTMASK); | ||
2623 | /* outb(0xff, s->iodmaa + SV_DMA_RESET); */ | ||
2624 | /* outb(0xff, s->iodmac + SV_DMA_RESET); */ | ||
2625 | inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */ | ||
2626 | wrindir(s, SV_CIADCCLKSOURCE, 0); /* use pll as ADC clock source */ | ||
2627 | wrindir(s, SV_CIANALOGPWRDOWN, 0); /* power up the analog parts of the device */ | ||
2628 | wrindir(s, SV_CIDIGITALPWRDOWN, 0); /* power up the digital parts of the device */ | ||
2629 | setpll(s, SV_CIADCPLLM, 8000); | ||
2630 | wrindir(s, SV_CISRSSPACE, 0x80); /* SRS off */ | ||
2631 | wrindir(s, SV_CIPCMSR0, (8000 * 65536 / FULLRATE) & 0xff); | ||
2632 | wrindir(s, SV_CIPCMSR1, ((8000 * 65536 / FULLRATE) >> 8) & 0xff); | ||
2633 | wrindir(s, SV_CIADCOUTPUT, 0); | ||
2634 | /* request irq */ | ||
2635 | if ((ret=request_irq(s->irq,sv_interrupt,IRQF_SHARED,"S3 SonicVibes",s))) { | ||
2636 | printk(KERN_ERR "sv: irq %u in use\n", s->irq); | ||
2637 | goto err_irq; | ||
2638 | } | ||
2639 | printk(KERN_INFO "sv: found adapter at io %#lx irq %u dmaa %#06x dmac %#06x revision %u\n", | ||
2640 | s->ioenh, s->irq, s->iodmaa, s->iodmac, rdindir(s, SV_CIREVISION)); | ||
2641 | /* register devices */ | ||
2642 | if ((s->dev_audio = register_sound_dsp(&sv_audio_fops, -1)) < 0) { | ||
2643 | ret = s->dev_audio; | ||
2644 | goto err_dev1; | ||
2645 | } | ||
2646 | if ((s->dev_mixer = register_sound_mixer(&sv_mixer_fops, -1)) < 0) { | ||
2647 | ret = s->dev_mixer; | ||
2648 | goto err_dev2; | ||
2649 | } | ||
2650 | if ((s->dev_midi = register_sound_midi(&sv_midi_fops, -1)) < 0) { | ||
2651 | ret = s->dev_midi; | ||
2652 | goto err_dev3; | ||
2653 | } | ||
2654 | if ((s->dev_dmfm = register_sound_special(&sv_dmfm_fops, 15 /* ?? */)) < 0) { | ||
2655 | ret = s->dev_dmfm; | ||
2656 | goto err_dev4; | ||
2657 | } | ||
2658 | pci_set_master(pcidev); /* enable bus mastering */ | ||
2659 | /* initialize the chips */ | ||
2660 | fs = get_fs(); | ||
2661 | set_fs(KERNEL_DS); | ||
2662 | val = SOUND_MASK_LINE|SOUND_MASK_SYNTH; | ||
2663 | mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); | ||
2664 | for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) { | ||
2665 | val = initvol[i].vol; | ||
2666 | mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); | ||
2667 | } | ||
2668 | set_fs(fs); | ||
2669 | /* register gameport */ | ||
2670 | sv_register_gameport(s, gpio); | ||
2671 | /* store it in the driver field */ | ||
2672 | pci_set_drvdata(pcidev, s); | ||
2673 | /* put it into driver list */ | ||
2674 | list_add_tail(&s->devs, &devs); | ||
2675 | /* increment devindex */ | ||
2676 | if (devindex < NR_DEVICE-1) | ||
2677 | devindex++; | ||
2678 | return 0; | ||
2679 | |||
2680 | err_dev4: | ||
2681 | unregister_sound_midi(s->dev_midi); | ||
2682 | err_dev3: | ||
2683 | unregister_sound_mixer(s->dev_mixer); | ||
2684 | err_dev2: | ||
2685 | unregister_sound_dsp(s->dev_audio); | ||
2686 | err_dev1: | ||
2687 | printk(KERN_ERR "sv: cannot register misc device\n"); | ||
2688 | free_irq(s->irq, s); | ||
2689 | err_irq: | ||
2690 | release_region(s->iosynth, SV_EXTENT_SYNTH); | ||
2691 | err_region1: | ||
2692 | release_region(s->iomidi, SV_EXTENT_MIDI); | ||
2693 | err_region2: | ||
2694 | release_region(s->iodmac, SV_EXTENT_DMA); | ||
2695 | err_region3: | ||
2696 | release_region(s->iodmaa, SV_EXTENT_DMA); | ||
2697 | err_region4: | ||
2698 | release_region(s->ioenh, SV_EXTENT_ENH); | ||
2699 | err_region5: | ||
2700 | kfree(s); | ||
2701 | return ret; | ||
2702 | } | ||
2703 | |||
2704 | static void __devexit sv_remove(struct pci_dev *dev) | ||
2705 | { | ||
2706 | struct sv_state *s = pci_get_drvdata(dev); | ||
2707 | |||
2708 | if (!s) | ||
2709 | return; | ||
2710 | list_del(&s->devs); | ||
2711 | outb(~0, s->ioenh + SV_CODEC_INTMASK); /* disable ints */ | ||
2712 | synchronize_irq(s->irq); | ||
2713 | inb(s->ioenh + SV_CODEC_STATUS); /* ack interrupts */ | ||
2714 | wrindir(s, SV_CIENABLE, 0); /* disable DMAA and DMAC */ | ||
2715 | /*outb(0, s->iodmaa + SV_DMA_RESET);*/ | ||
2716 | /*outb(0, s->iodmac + SV_DMA_RESET);*/ | ||
2717 | free_irq(s->irq, s); | ||
2718 | sv_unregister_gameport(s); | ||
2719 | release_region(s->iodmac, SV_EXTENT_DMA); | ||
2720 | release_region(s->iodmaa, SV_EXTENT_DMA); | ||
2721 | release_region(s->ioenh, SV_EXTENT_ENH); | ||
2722 | release_region(s->iomidi, SV_EXTENT_MIDI); | ||
2723 | release_region(s->iosynth, SV_EXTENT_SYNTH); | ||
2724 | unregister_sound_dsp(s->dev_audio); | ||
2725 | unregister_sound_mixer(s->dev_mixer); | ||
2726 | unregister_sound_midi(s->dev_midi); | ||
2727 | unregister_sound_special(s->dev_dmfm); | ||
2728 | kfree(s); | ||
2729 | pci_set_drvdata(dev, NULL); | ||
2730 | } | ||
2731 | |||
2732 | static struct pci_device_id id_table[] = { | ||
2733 | { PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SONICVIBES, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
2734 | { 0, } | ||
2735 | }; | ||
2736 | |||
2737 | MODULE_DEVICE_TABLE(pci, id_table); | ||
2738 | |||
2739 | static struct pci_driver sv_driver = { | ||
2740 | .name = "sonicvibes", | ||
2741 | .id_table = id_table, | ||
2742 | .probe = sv_probe, | ||
2743 | .remove = __devexit_p(sv_remove), | ||
2744 | }; | ||
2745 | |||
2746 | static int __init init_sonicvibes(void) | ||
2747 | { | ||
2748 | printk(KERN_INFO "sv: version v0.31 time " __TIME__ " " __DATE__ "\n"); | ||
2749 | #if 0 | ||
2750 | if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT))) | ||
2751 | printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n"); | ||
2752 | #endif | ||
2753 | return pci_register_driver(&sv_driver); | ||
2754 | } | ||
2755 | |||
2756 | static void __exit cleanup_sonicvibes(void) | ||
2757 | { | ||
2758 | printk(KERN_INFO "sv: unloading\n"); | ||
2759 | pci_unregister_driver(&sv_driver); | ||
2760 | if (wavetable_mem) | ||
2761 | free_pages(wavetable_mem, 20-PAGE_SHIFT); | ||
2762 | } | ||
2763 | |||
2764 | module_init(init_sonicvibes); | ||
2765 | module_exit(cleanup_sonicvibes); | ||
2766 | |||
2767 | /* --------------------------------------------------------------------- */ | ||
2768 | |||
2769 | #ifndef MODULE | ||
2770 | |||
2771 | /* format is: sonicvibes=[reverb] sonicvibesdmaio=dmaioaddr */ | ||
2772 | |||
2773 | static int __init sonicvibes_setup(char *str) | ||
2774 | { | ||
2775 | static unsigned __initdata nr_dev = 0; | ||
2776 | |||
2777 | if (nr_dev >= NR_DEVICE) | ||
2778 | return 0; | ||
2779 | #if 0 | ||
2780 | if (get_option(&str, &reverb[nr_dev]) == 2) | ||
2781 | (void)get_option(&str, &wavetable[nr_dev]); | ||
2782 | #else | ||
2783 | (void)get_option(&str, &reverb[nr_dev]); | ||
2784 | #endif | ||
2785 | |||
2786 | nr_dev++; | ||
2787 | return 1; | ||
2788 | } | ||
2789 | |||
2790 | __setup("sonicvibes=", sonicvibes_setup); | ||
2791 | |||
2792 | #endif /* MODULE */ | ||
diff --git a/sound/oss/sound_calls.h b/sound/oss/sound_calls.h index 1ae07509664f..cd335ba81450 100644 --- a/sound/oss/sound_calls.h +++ b/sound/oss/sound_calls.h | |||
@@ -13,8 +13,6 @@ int DMAbuf_move_wrpointer(int dev, int l); | |||
13 | void DMAbuf_init(int dev, int dma1, int dma2); | 13 | void DMAbuf_init(int dev, int dma1, int dma2); |
14 | void DMAbuf_deinit(int dev); | 14 | void DMAbuf_deinit(int dev); |
15 | int DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode); | 15 | int DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode); |
16 | int DMAbuf_open_dma (int dev); | ||
17 | void DMAbuf_close_dma (int dev); | ||
18 | void DMAbuf_inputintr(int dev); | 16 | void DMAbuf_inputintr(int dev); |
19 | void DMAbuf_outputintr(int dev, int underflow_flag); | 17 | void DMAbuf_outputintr(int dev, int underflow_flag); |
20 | struct dma_buffparms; | 18 | struct dma_buffparms; |
diff --git a/sound/oss/tuning.h b/sound/oss/tuning.h index 858e1fe6c618..a73e3dd39f9a 100644 --- a/sound/oss/tuning.h +++ b/sound/oss/tuning.h | |||
@@ -1,13 +1,11 @@ | |||
1 | #ifdef SEQUENCER_C | 1 | static unsigned short semitone_tuning[24] = |
2 | |||
3 | unsigned short semitone_tuning[24] = | ||
4 | { | 2 | { |
5 | /* 0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983, | 3 | /* 0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983, |
6 | /* 8 */ 15874, 16818, 17818, 18877, 20000, 21189, 22449, 23784, | 4 | /* 8 */ 15874, 16818, 17818, 18877, 20000, 21189, 22449, 23784, |
7 | /* 16 */ 25198, 26697, 28284, 29966, 31748, 33636, 35636, 37755 | 5 | /* 16 */ 25198, 26697, 28284, 29966, 31748, 33636, 35636, 37755 |
8 | }; | 6 | }; |
9 | 7 | ||
10 | unsigned short cent_tuning[100] = | 8 | static unsigned short cent_tuning[100] = |
11 | { | 9 | { |
12 | /* 0 */ 10000, 10006, 10012, 10017, 10023, 10029, 10035, 10041, | 10 | /* 0 */ 10000, 10006, 10012, 10017, 10023, 10029, 10035, 10041, |
13 | /* 8 */ 10046, 10052, 10058, 10064, 10070, 10075, 10081, 10087, | 11 | /* 8 */ 10046, 10052, 10058, 10064, 10070, 10075, 10081, 10087, |
@@ -23,7 +21,3 @@ unsigned short cent_tuning[100] = | |||
23 | /* 88 */ 10521, 10528, 10534, 10540, 10546, 10552, 10558, 10564, | 21 | /* 88 */ 10521, 10528, 10534, 10540, 10546, 10552, 10558, 10564, |
24 | /* 96 */ 10570, 10576, 10582, 10589 | 22 | /* 96 */ 10570, 10576, 10582, 10589 |
25 | }; | 23 | }; |
26 | #else | ||
27 | extern unsigned short semitone_tuning[24]; | ||
28 | extern unsigned short cent_tuning[100]; | ||
29 | #endif | ||
diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c deleted file mode 100644 index 1dec3958cc7b..000000000000 --- a/sound/oss/wavfront.c +++ /dev/null | |||
@@ -1,3554 +0,0 @@ | |||
1 | /* -*- linux-c -*- | ||
2 | * | ||
3 | * sound/wavfront.c | ||
4 | * | ||
5 | * A Linux driver for Turtle Beach WaveFront Series (Maui, Tropez, Tropez Plus) | ||
6 | * | ||
7 | * This driver supports the onboard wavetable synthesizer (an ICS2115), | ||
8 | * including patch, sample and program loading and unloading, conversion | ||
9 | * of GUS patches during loading, and full user-level access to all | ||
10 | * WaveFront commands. It tries to provide semi-intelligent patch and | ||
11 | * sample management as well. | ||
12 | * | ||
13 | * It also provides support for the ICS emulation of an MPU-401. Full | ||
14 | * support for the ICS emulation's "virtual MIDI mode" is provided in | ||
15 | * wf_midi.c. | ||
16 | * | ||
17 | * Support is also provided for the Tropez Plus' onboard FX processor, | ||
18 | * a Yamaha YSS225. Currently, code exists to configure the YSS225, | ||
19 | * and there is an interface allowing tweaking of any of its memory | ||
20 | * addresses. However, I have been unable to decipher the logical | ||
21 | * positioning of the configuration info for various effects, so for | ||
22 | * now, you just get the YSS225 in the same state as Turtle Beach's | ||
23 | * "SETUPSND.EXE" utility leaves it. | ||
24 | * | ||
25 | * The boards' DAC/ADC (a Crystal CS4232) is supported by cs4232.[co], | ||
26 | * This chip also controls the configuration of the card: the wavefront | ||
27 | * synth is logical unit 4. | ||
28 | * | ||
29 | * | ||
30 | * Supported devices: | ||
31 | * | ||
32 | * /dev/dsp - using cs4232+ad1848 modules, OSS compatible | ||
33 | * /dev/midiNN and /dev/midiNN+1 - using wf_midi code, OSS compatible | ||
34 | * /dev/synth00 - raw synth interface | ||
35 | * | ||
36 | ********************************************************************** | ||
37 | * | ||
38 | * Copyright (C) by Paul Barton-Davis 1998 | ||
39 | * | ||
40 | * Some portions of this file are taken from work that is | ||
41 | * copyright (C) by Hannu Savolainen 1993-1996 | ||
42 | * | ||
43 | * Although the relevant code here is all new, the handling of | ||
44 | * sample/alias/multi- samples is entirely based on a driver by Matt | ||
45 | * Martin and Rutger Nijlunsing which demonstrated how to get things | ||
46 | * to work correctly. The GUS patch loading code has been almost | ||
47 | * unaltered by me, except to fit formatting and function names in the | ||
48 | * rest of the file. Many thanks to them. | ||
49 | * | ||
50 | * Appreciation and thanks to Hannu Savolainen for his early work on the Maui | ||
51 | * driver, and answering a few questions while this one was developed. | ||
52 | * | ||
53 | * Absolutely NO thanks to Turtle Beach/Voyetra and Yamaha for their | ||
54 | * complete lack of help in developing this driver, and in particular | ||
55 | * for their utter silence in response to questions about undocumented | ||
56 | * aspects of configuring a WaveFront soundcard, particularly the | ||
57 | * effects processor. | ||
58 | * | ||
59 | * $Id: wavfront.c,v 0.7 1998/09/09 15:47:36 pbd Exp $ | ||
60 | * | ||
61 | * This program is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
62 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
63 | * for more info. | ||
64 | * | ||
65 | * Changes: | ||
66 | * 11-10-2000 Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> | ||
67 | * Added some __init and __initdata to entries in yss225.c | ||
68 | */ | ||
69 | |||
70 | #include <linux/module.h> | ||
71 | |||
72 | #include <linux/kernel.h> | ||
73 | #include <linux/init.h> | ||
74 | #include <linux/sched.h> | ||
75 | #include <linux/smp_lock.h> | ||
76 | #include <linux/ptrace.h> | ||
77 | #include <linux/fcntl.h> | ||
78 | #include <linux/syscalls.h> | ||
79 | #include <linux/ioport.h> | ||
80 | #include <linux/spinlock.h> | ||
81 | #include <linux/interrupt.h> | ||
82 | #include <linux/config.h> | ||
83 | |||
84 | #include <linux/delay.h> | ||
85 | |||
86 | #include "sound_config.h" | ||
87 | |||
88 | #include <linux/wavefront.h> | ||
89 | |||
90 | #define _MIDI_SYNTH_C_ | ||
91 | #define MIDI_SYNTH_NAME "WaveFront MIDI" | ||
92 | #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT | ||
93 | #include "midi_synth.h" | ||
94 | |||
95 | /* Compile-time control of the extent to which OSS is supported. | ||
96 | |||
97 | I consider /dev/sequencer to be an anachronism, but given its | ||
98 | widespread usage by various Linux MIDI software, it seems worth | ||
99 | offering support to it if it's not too painful. Instead of using | ||
100 | /dev/sequencer, I recommend: | ||
101 | |||
102 | for synth programming and patch loading: /dev/synthNN | ||
103 | for kernel-synchronized MIDI sequencing: the ALSA sequencer | ||
104 | for direct MIDI control: /dev/midiNN | ||
105 | |||
106 | I have never tried static compilation into the kernel. The #if's | ||
107 | for this are really just notes to myself about what the code is | ||
108 | for. | ||
109 | */ | ||
110 | |||
111 | #define OSS_SUPPORT_SEQ 0x1 /* use of /dev/sequencer */ | ||
112 | #define OSS_SUPPORT_STATIC_INSTALL 0x2 /* static compilation into kernel */ | ||
113 | |||
114 | #define OSS_SUPPORT_LEVEL 0x1 /* just /dev/sequencer for now */ | ||
115 | |||
116 | #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ | ||
117 | static int (*midi_load_patch) (int devno, int format, const char __user *addr, | ||
118 | int offs, int count, int pmgr_flag) = NULL; | ||
119 | #endif /* OSS_SUPPORT_SEQ */ | ||
120 | |||
121 | /* if WF_DEBUG not defined, no run-time debugging messages will | ||
122 | be available via the debug flag setting. Given the current | ||
123 | beta state of the driver, this will remain set until a future | ||
124 | version. | ||
125 | */ | ||
126 | |||
127 | #define WF_DEBUG 1 | ||
128 | |||
129 | #ifdef WF_DEBUG | ||
130 | |||
131 | /* Thank goodness for gcc's preprocessor ... */ | ||
132 | |||
133 | #define DPRINT(cond, format, args...) \ | ||
134 | if ((dev.debug & (cond)) == (cond)) { \ | ||
135 | printk (KERN_DEBUG LOGNAME format, ## args); \ | ||
136 | } | ||
137 | #else | ||
138 | #define DPRINT(cond, format, args...) | ||
139 | #endif | ||
140 | |||
141 | #define LOGNAME "WaveFront: " | ||
142 | |||
143 | /* bitmasks for WaveFront status port value */ | ||
144 | |||
145 | #define STAT_RINTR_ENABLED 0x01 | ||
146 | #define STAT_CAN_READ 0x02 | ||
147 | #define STAT_INTR_READ 0x04 | ||
148 | #define STAT_WINTR_ENABLED 0x10 | ||
149 | #define STAT_CAN_WRITE 0x20 | ||
150 | #define STAT_INTR_WRITE 0x40 | ||
151 | |||
152 | /*** Module-accessible parameters ***************************************/ | ||
153 | |||
154 | static int wf_raw; /* we normally check for "raw state" to firmware | ||
155 | loading. if set, then during driver loading, the | ||
156 | state of the board is ignored, and we reset the | ||
157 | board and load the firmware anyway. | ||
158 | */ | ||
159 | |||
160 | static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in | ||
161 | whatever state it is when the driver is loaded. | ||
162 | The default is to download the microprogram and | ||
163 | associated coefficients to set it up for "default" | ||
164 | operation, whatever that means. | ||
165 | */ | ||
166 | |||
167 | static int debug_default; /* you can set this to control debugging | ||
168 | during driver loading. it takes any combination | ||
169 | of the WF_DEBUG_* flags defined in | ||
170 | wavefront.h | ||
171 | */ | ||
172 | |||
173 | /* XXX this needs to be made firmware and hardware version dependent */ | ||
174 | |||
175 | static char *ospath = "/etc/sound/wavefront.os"; /* where to find a processed | ||
176 | version of the WaveFront OS | ||
177 | */ | ||
178 | |||
179 | static int wait_polls = 2000; /* This is a number of tries we poll the | ||
180 | status register before resorting to sleeping. | ||
181 | WaveFront being an ISA card each poll takes | ||
182 | about 1.2us. So before going to | ||
183 | sleep we wait up to 2.4ms in a loop. | ||
184 | */ | ||
185 | |||
186 | static int sleep_length = HZ/100; /* This says how long we're going to | ||
187 | sleep between polls. | ||
188 | 10ms sounds reasonable for fast response. | ||
189 | */ | ||
190 | |||
191 | static int sleep_tries = 50; /* Wait for status 0.5 seconds total. */ | ||
192 | |||
193 | static int reset_time = 2; /* hundreths of a second we wait after a HW reset for | ||
194 | the expected interrupt. | ||
195 | */ | ||
196 | |||
197 | static int ramcheck_time = 20; /* time in seconds to wait while ROM code | ||
198 | checks on-board RAM. | ||
199 | */ | ||
200 | |||
201 | static int osrun_time = 10; /* time in seconds we wait for the OS to | ||
202 | start running. | ||
203 | */ | ||
204 | |||
205 | module_param(wf_raw, int, 0); | ||
206 | module_param(fx_raw, int, 0); | ||
207 | module_param(debug_default, int, 0); | ||
208 | module_param(wait_polls, int, 0); | ||
209 | module_param(sleep_length, int, 0); | ||
210 | module_param(sleep_tries, int, 0); | ||
211 | module_param(ospath, charp, 0); | ||
212 | module_param(reset_time, int, 0); | ||
213 | module_param(ramcheck_time, int, 0); | ||
214 | module_param(osrun_time, int, 0); | ||
215 | |||
216 | /***************************************************************************/ | ||
217 | |||
218 | /* Note: because this module doesn't export any symbols, this really isn't | ||
219 | a global variable, even if it looks like one. I was quite confused by | ||
220 | this when I started writing this as a (newer) module -- pbd. | ||
221 | */ | ||
222 | |||
223 | struct wf_config { | ||
224 | int devno; /* device number from kernel */ | ||
225 | int irq; /* "you were one, one of the few ..." */ | ||
226 | int base; /* low i/o port address */ | ||
227 | |||
228 | #define mpu_data_port base | ||
229 | #define mpu_command_port base + 1 /* write semantics */ | ||
230 | #define mpu_status_port base + 1 /* read semantics */ | ||
231 | #define data_port base + 2 | ||
232 | #define status_port base + 3 /* read semantics */ | ||
233 | #define control_port base + 3 /* write semantics */ | ||
234 | #define block_port base + 4 /* 16 bit, writeonly */ | ||
235 | #define last_block_port base + 6 /* 16 bit, writeonly */ | ||
236 | |||
237 | /* FX ports. These are mapped through the ICS2115 to the YS225. | ||
238 | The ICS2115 takes care of flipping the relevant pins on the | ||
239 | YS225 so that access to each of these ports does the right | ||
240 | thing. Note: these are NOT documented by Turtle Beach. | ||
241 | */ | ||
242 | |||
243 | #define fx_status base + 8 | ||
244 | #define fx_op base + 8 | ||
245 | #define fx_lcr base + 9 | ||
246 | #define fx_dsp_addr base + 0xa | ||
247 | #define fx_dsp_page base + 0xb | ||
248 | #define fx_dsp_lsb base + 0xc | ||
249 | #define fx_dsp_msb base + 0xd | ||
250 | #define fx_mod_addr base + 0xe | ||
251 | #define fx_mod_data base + 0xf | ||
252 | |||
253 | volatile int irq_ok; /* set by interrupt handler */ | ||
254 | volatile int irq_cnt; /* ditto */ | ||
255 | int opened; /* flag, holds open(2) mode */ | ||
256 | char debug; /* debugging flags */ | ||
257 | int freemem; /* installed RAM, in bytes */ | ||
258 | |||
259 | int synth_dev; /* devno for "raw" synth */ | ||
260 | int mididev; /* devno for internal MIDI */ | ||
261 | int ext_mididev; /* devno for external MIDI */ | ||
262 | int fx_mididev; /* devno for FX MIDI interface */ | ||
263 | #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ | ||
264 | int oss_dev; /* devno for OSS sequencer synth */ | ||
265 | #endif /* OSS_SUPPORT_SEQ */ | ||
266 | |||
267 | char fw_version[2]; /* major = [0], minor = [1] */ | ||
268 | char hw_version[2]; /* major = [0], minor = [1] */ | ||
269 | char israw; /* needs Motorola microcode */ | ||
270 | char has_fx; /* has FX processor (Tropez+) */ | ||
271 | char prog_status[WF_MAX_PROGRAM]; /* WF_SLOT_* */ | ||
272 | char patch_status[WF_MAX_PATCH]; /* WF_SLOT_* */ | ||
273 | char sample_status[WF_MAX_SAMPLE]; /* WF_ST_* | WF_SLOT_* */ | ||
274 | int samples_used; /* how many */ | ||
275 | char interrupts_on; /* h/w MPU interrupts enabled ? */ | ||
276 | char rom_samples_rdonly; /* can we write on ROM samples */ | ||
277 | wait_queue_head_t interrupt_sleeper; | ||
278 | } dev; | ||
279 | |||
280 | static DEFINE_SPINLOCK(lock); | ||
281 | static int detect_wffx(void); | ||
282 | static int wffx_ioctl (wavefront_fx_info *); | ||
283 | static int wffx_init (void); | ||
284 | |||
285 | static int wavefront_delete_sample (int sampnum); | ||
286 | static int wavefront_find_free_sample (void); | ||
287 | |||
288 | /* From wf_midi.c */ | ||
289 | |||
290 | extern int virtual_midi_enable (void); | ||
291 | extern int virtual_midi_disable (void); | ||
292 | extern int detect_wf_mpu (int, int); | ||
293 | extern int install_wf_mpu (void); | ||
294 | extern int uninstall_wf_mpu (void); | ||
295 | |||
296 | typedef struct { | ||
297 | int cmd; | ||
298 | char *action; | ||
299 | unsigned int read_cnt; | ||
300 | unsigned int write_cnt; | ||
301 | int need_ack; | ||
302 | } wavefront_command; | ||
303 | |||
304 | static struct { | ||
305 | int errno; | ||
306 | const char *errstr; | ||
307 | } wavefront_errors[] = { | ||
308 | { 0x01, "Bad sample number" }, | ||
309 | { 0x02, "Out of sample memory" }, | ||
310 | { 0x03, "Bad patch number" }, | ||
311 | { 0x04, "Error in number of voices" }, | ||
312 | { 0x06, "Sample load already in progress" }, | ||
313 | { 0x0B, "No sample load request pending" }, | ||
314 | { 0x0E, "Bad MIDI channel number" }, | ||
315 | { 0x10, "Download Record Error" }, | ||
316 | { 0x80, "Success" }, | ||
317 | { 0 } | ||
318 | }; | ||
319 | |||
320 | #define NEEDS_ACK 1 | ||
321 | |||
322 | static wavefront_command wavefront_commands[] = { | ||
323 | { WFC_SET_SYNTHVOL, "set synthesizer volume", 0, 1, NEEDS_ACK }, | ||
324 | { WFC_GET_SYNTHVOL, "get synthesizer volume", 1, 0, 0}, | ||
325 | { WFC_SET_NVOICES, "set number of voices", 0, 1, NEEDS_ACK }, | ||
326 | { WFC_GET_NVOICES, "get number of voices", 1, 0, 0 }, | ||
327 | { WFC_SET_TUNING, "set synthesizer tuning", 0, 2, NEEDS_ACK }, | ||
328 | { WFC_GET_TUNING, "get synthesizer tuning", 2, 0, 0 }, | ||
329 | { WFC_DISABLE_CHANNEL, "disable synth channel", 0, 1, NEEDS_ACK }, | ||
330 | { WFC_ENABLE_CHANNEL, "enable synth channel", 0, 1, NEEDS_ACK }, | ||
331 | { WFC_GET_CHANNEL_STATUS, "get synth channel status", 3, 0, 0 }, | ||
332 | { WFC_MISYNTH_OFF, "disable midi-in to synth", 0, 0, NEEDS_ACK }, | ||
333 | { WFC_MISYNTH_ON, "enable midi-in to synth", 0, 0, NEEDS_ACK }, | ||
334 | { WFC_VMIDI_ON, "enable virtual midi mode", 0, 0, NEEDS_ACK }, | ||
335 | { WFC_VMIDI_OFF, "disable virtual midi mode", 0, 0, NEEDS_ACK }, | ||
336 | { WFC_MIDI_STATUS, "report midi status", 1, 0, 0 }, | ||
337 | { WFC_FIRMWARE_VERSION, "report firmware version", 2, 0, 0 }, | ||
338 | { WFC_HARDWARE_VERSION, "report hardware version", 2, 0, 0 }, | ||
339 | { WFC_GET_NSAMPLES, "report number of samples", 2, 0, 0 }, | ||
340 | { WFC_INSTOUT_LEVELS, "report instantaneous output levels", 7, 0, 0 }, | ||
341 | { WFC_PEAKOUT_LEVELS, "report peak output levels", 7, 0, 0 }, | ||
342 | { WFC_DOWNLOAD_SAMPLE, "download sample", | ||
343 | 0, WF_SAMPLE_BYTES, NEEDS_ACK }, | ||
344 | { WFC_DOWNLOAD_BLOCK, "download block", 0, 0, NEEDS_ACK}, | ||
345 | { WFC_DOWNLOAD_SAMPLE_HEADER, "download sample header", | ||
346 | 0, WF_SAMPLE_HDR_BYTES, NEEDS_ACK }, | ||
347 | { WFC_UPLOAD_SAMPLE_HEADER, "upload sample header", 13, 2, 0 }, | ||
348 | |||
349 | /* This command requires a variable number of bytes to be written. | ||
350 | There is a hack in wavefront_cmd() to support this. The actual | ||
351 | count is passed in as the read buffer ptr, cast appropriately. | ||
352 | Ugh. | ||
353 | */ | ||
354 | |||
355 | { WFC_DOWNLOAD_MULTISAMPLE, "download multisample", 0, 0, NEEDS_ACK }, | ||
356 | |||
357 | /* This one is a hack as well. We just read the first byte of the | ||
358 | response, don't fetch an ACK, and leave the rest to the | ||
359 | calling function. Ugly, ugly, ugly. | ||
360 | */ | ||
361 | |||
362 | { WFC_UPLOAD_MULTISAMPLE, "upload multisample", 2, 1, 0 }, | ||
363 | { WFC_DOWNLOAD_SAMPLE_ALIAS, "download sample alias", | ||
364 | 0, WF_ALIAS_BYTES, NEEDS_ACK }, | ||
365 | { WFC_UPLOAD_SAMPLE_ALIAS, "upload sample alias", WF_ALIAS_BYTES, 2, 0}, | ||
366 | { WFC_DELETE_SAMPLE, "delete sample", 0, 2, NEEDS_ACK }, | ||
367 | { WFC_IDENTIFY_SAMPLE_TYPE, "identify sample type", 5, 2, 0 }, | ||
368 | { WFC_UPLOAD_SAMPLE_PARAMS, "upload sample parameters" }, | ||
369 | { WFC_REPORT_FREE_MEMORY, "report free memory", 4, 0, 0 }, | ||
370 | { WFC_DOWNLOAD_PATCH, "download patch", 0, 134, NEEDS_ACK }, | ||
371 | { WFC_UPLOAD_PATCH, "upload patch", 132, 2, 0 }, | ||
372 | { WFC_DOWNLOAD_PROGRAM, "download program", 0, 33, NEEDS_ACK }, | ||
373 | { WFC_UPLOAD_PROGRAM, "upload program", 32, 1, 0 }, | ||
374 | { WFC_DOWNLOAD_EDRUM_PROGRAM, "download enhanced drum program", 0, 9, | ||
375 | NEEDS_ACK}, | ||
376 | { WFC_UPLOAD_EDRUM_PROGRAM, "upload enhanced drum program", 8, 1, 0}, | ||
377 | { WFC_SET_EDRUM_CHANNEL, "set enhanced drum program channel", | ||
378 | 0, 1, NEEDS_ACK }, | ||
379 | { WFC_DISABLE_DRUM_PROGRAM, "disable drum program", 0, 1, NEEDS_ACK }, | ||
380 | { WFC_REPORT_CHANNEL_PROGRAMS, "report channel program numbers", | ||
381 | 32, 0, 0 }, | ||
382 | { WFC_NOOP, "the no-op command", 0, 0, NEEDS_ACK }, | ||
383 | { 0x00 } | ||
384 | }; | ||
385 | |||
386 | static const char * | ||
387 | wavefront_errorstr (int errnum) | ||
388 | |||
389 | { | ||
390 | int i; | ||
391 | |||
392 | for (i = 0; wavefront_errors[i].errstr; i++) { | ||
393 | if (wavefront_errors[i].errno == errnum) { | ||
394 | return wavefront_errors[i].errstr; | ||
395 | } | ||
396 | } | ||
397 | |||
398 | return "Unknown WaveFront error"; | ||
399 | } | ||
400 | |||
401 | static wavefront_command * | ||
402 | wavefront_get_command (int cmd) | ||
403 | |||
404 | { | ||
405 | int i; | ||
406 | |||
407 | for (i = 0; wavefront_commands[i].cmd != 0; i++) { | ||
408 | if (cmd == wavefront_commands[i].cmd) { | ||
409 | return &wavefront_commands[i]; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | return (wavefront_command *) 0; | ||
414 | } | ||
415 | |||
416 | static inline int | ||
417 | wavefront_status (void) | ||
418 | |||
419 | { | ||
420 | return inb (dev.status_port); | ||
421 | } | ||
422 | |||
423 | static int | ||
424 | wavefront_wait (int mask) | ||
425 | |||
426 | { | ||
427 | int i; | ||
428 | |||
429 | for (i = 0; i < wait_polls; i++) | ||
430 | if (wavefront_status() & mask) | ||
431 | return 1; | ||
432 | |||
433 | for (i = 0; i < sleep_tries; i++) { | ||
434 | |||
435 | if (wavefront_status() & mask) { | ||
436 | set_current_state(TASK_RUNNING); | ||
437 | return 1; | ||
438 | } | ||
439 | |||
440 | set_current_state(TASK_INTERRUPTIBLE); | ||
441 | schedule_timeout(sleep_length); | ||
442 | if (signal_pending(current)) | ||
443 | break; | ||
444 | } | ||
445 | |||
446 | set_current_state(TASK_RUNNING); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static int | ||
451 | wavefront_read (void) | ||
452 | |||
453 | { | ||
454 | if (wavefront_wait (STAT_CAN_READ)) | ||
455 | return inb (dev.data_port); | ||
456 | |||
457 | DPRINT (WF_DEBUG_DATA, "read timeout.\n"); | ||
458 | |||
459 | return -1; | ||
460 | } | ||
461 | |||
462 | static int | ||
463 | wavefront_write (unsigned char data) | ||
464 | |||
465 | { | ||
466 | if (wavefront_wait (STAT_CAN_WRITE)) { | ||
467 | outb (data, dev.data_port); | ||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | DPRINT (WF_DEBUG_DATA, "write timeout.\n"); | ||
472 | |||
473 | return -1; | ||
474 | } | ||
475 | |||
476 | static int | ||
477 | wavefront_cmd (int cmd, unsigned char *rbuf, unsigned char *wbuf) | ||
478 | |||
479 | { | ||
480 | int ack; | ||
481 | int i; | ||
482 | int c; | ||
483 | wavefront_command *wfcmd; | ||
484 | |||
485 | if ((wfcmd = wavefront_get_command (cmd)) == (wavefront_command *) 0) { | ||
486 | printk (KERN_WARNING LOGNAME "command 0x%x not supported.\n", | ||
487 | cmd); | ||
488 | return 1; | ||
489 | } | ||
490 | |||
491 | /* Hack to handle the one variable-size write command. See | ||
492 | wavefront_send_multisample() for the other half of this | ||
493 | gross and ugly strategy. | ||
494 | */ | ||
495 | |||
496 | if (cmd == WFC_DOWNLOAD_MULTISAMPLE) { | ||
497 | wfcmd->write_cnt = (unsigned int) rbuf; | ||
498 | rbuf = NULL; | ||
499 | } | ||
500 | |||
501 | DPRINT (WF_DEBUG_CMD, "0x%x [%s] (%d,%d,%d)\n", | ||
502 | cmd, wfcmd->action, wfcmd->read_cnt, | ||
503 | wfcmd->write_cnt, wfcmd->need_ack); | ||
504 | |||
505 | if (wavefront_write (cmd)) { | ||
506 | DPRINT ((WF_DEBUG_IO|WF_DEBUG_CMD), "cannot request " | ||
507 | "0x%x [%s].\n", | ||
508 | cmd, wfcmd->action); | ||
509 | return 1; | ||
510 | } | ||
511 | |||
512 | if (wfcmd->write_cnt > 0) { | ||
513 | DPRINT (WF_DEBUG_DATA, "writing %d bytes " | ||
514 | "for 0x%x\n", | ||
515 | wfcmd->write_cnt, cmd); | ||
516 | |||
517 | for (i = 0; i < wfcmd->write_cnt; i++) { | ||
518 | if (wavefront_write (wbuf[i])) { | ||
519 | DPRINT (WF_DEBUG_IO, "bad write for byte " | ||
520 | "%d of 0x%x [%s].\n", | ||
521 | i, cmd, wfcmd->action); | ||
522 | return 1; | ||
523 | } | ||
524 | |||
525 | DPRINT (WF_DEBUG_DATA, "write[%d] = 0x%x\n", | ||
526 | i, wbuf[i]); | ||
527 | } | ||
528 | } | ||
529 | |||
530 | if (wfcmd->read_cnt > 0) { | ||
531 | DPRINT (WF_DEBUG_DATA, "reading %d ints " | ||
532 | "for 0x%x\n", | ||
533 | wfcmd->read_cnt, cmd); | ||
534 | |||
535 | for (i = 0; i < wfcmd->read_cnt; i++) { | ||
536 | |||
537 | if ((c = wavefront_read()) == -1) { | ||
538 | DPRINT (WF_DEBUG_IO, "bad read for byte " | ||
539 | "%d of 0x%x [%s].\n", | ||
540 | i, cmd, wfcmd->action); | ||
541 | return 1; | ||
542 | } | ||
543 | |||
544 | /* Now handle errors. Lots of special cases here */ | ||
545 | |||
546 | if (c == 0xff) { | ||
547 | if ((c = wavefront_read ()) == -1) { | ||
548 | DPRINT (WF_DEBUG_IO, "bad read for " | ||
549 | "error byte at " | ||
550 | "read byte %d " | ||
551 | "of 0x%x [%s].\n", | ||
552 | i, cmd, | ||
553 | wfcmd->action); | ||
554 | return 1; | ||
555 | } | ||
556 | |||
557 | /* Can you believe this madness ? */ | ||
558 | |||
559 | if (c == 1 && | ||
560 | wfcmd->cmd == WFC_IDENTIFY_SAMPLE_TYPE) { | ||
561 | rbuf[0] = WF_ST_EMPTY; | ||
562 | return (0); | ||
563 | |||
564 | } else if (c == 3 && | ||
565 | wfcmd->cmd == WFC_UPLOAD_PATCH) { | ||
566 | |||
567 | return 3; | ||
568 | |||
569 | } else if (c == 1 && | ||
570 | wfcmd->cmd == WFC_UPLOAD_PROGRAM) { | ||
571 | |||
572 | return 1; | ||
573 | |||
574 | } else { | ||
575 | |||
576 | DPRINT (WF_DEBUG_IO, "error %d (%s) " | ||
577 | "during " | ||
578 | "read for byte " | ||
579 | "%d of 0x%x " | ||
580 | "[%s].\n", | ||
581 | c, | ||
582 | wavefront_errorstr (c), | ||
583 | i, cmd, | ||
584 | wfcmd->action); | ||
585 | return 1; | ||
586 | |||
587 | } | ||
588 | |||
589 | } else { | ||
590 | rbuf[i] = c; | ||
591 | } | ||
592 | |||
593 | DPRINT (WF_DEBUG_DATA, "read[%d] = 0x%x\n",i, rbuf[i]); | ||
594 | } | ||
595 | } | ||
596 | |||
597 | if ((wfcmd->read_cnt == 0 && wfcmd->write_cnt == 0) || wfcmd->need_ack) { | ||
598 | |||
599 | DPRINT (WF_DEBUG_CMD, "reading ACK for 0x%x\n", cmd); | ||
600 | |||
601 | /* Some commands need an ACK, but return zero instead | ||
602 | of the standard value. | ||
603 | */ | ||
604 | |||
605 | if ((ack = wavefront_read()) == 0) { | ||
606 | ack = WF_ACK; | ||
607 | } | ||
608 | |||
609 | if (ack != WF_ACK) { | ||
610 | if (ack == -1) { | ||
611 | DPRINT (WF_DEBUG_IO, "cannot read ack for " | ||
612 | "0x%x [%s].\n", | ||
613 | cmd, wfcmd->action); | ||
614 | return 1; | ||
615 | |||
616 | } else { | ||
617 | int err = -1; /* something unknown */ | ||
618 | |||
619 | if (ack == 0xff) { /* explicit error */ | ||
620 | |||
621 | if ((err = wavefront_read ()) == -1) { | ||
622 | DPRINT (WF_DEBUG_DATA, | ||
623 | "cannot read err " | ||
624 | "for 0x%x [%s].\n", | ||
625 | cmd, wfcmd->action); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | DPRINT (WF_DEBUG_IO, "0x%x [%s] " | ||
630 | "failed (0x%x, 0x%x, %s)\n", | ||
631 | cmd, wfcmd->action, ack, err, | ||
632 | wavefront_errorstr (err)); | ||
633 | |||
634 | return -err; | ||
635 | } | ||
636 | } | ||
637 | |||
638 | DPRINT (WF_DEBUG_DATA, "ack received " | ||
639 | "for 0x%x [%s]\n", | ||
640 | cmd, wfcmd->action); | ||
641 | } else { | ||
642 | |||
643 | DPRINT (WF_DEBUG_CMD, "0x%x [%s] does not need " | ||
644 | "ACK (%d,%d,%d)\n", | ||
645 | cmd, wfcmd->action, wfcmd->read_cnt, | ||
646 | wfcmd->write_cnt, wfcmd->need_ack); | ||
647 | } | ||
648 | |||
649 | return 0; | ||
650 | |||
651 | } | ||
652 | |||
653 | /*********************************************************************** | ||
654 | WaveFront: data munging | ||
655 | |||
656 | Things here are weird. All data written to the board cannot | ||
657 | have its most significant bit set. Any data item with values | ||
658 | potentially > 0x7F (127) must be split across multiple bytes. | ||
659 | |||
660 | Sometimes, we need to munge numeric values that are represented on | ||
661 | the x86 side as 8-32 bit values. Sometimes, we need to munge data | ||
662 | that is represented on the x86 side as an array of bytes. The most | ||
663 | efficient approach to handling both cases seems to be to use 2 | ||
664 | different functions for munging and 2 for de-munging. This avoids | ||
665 | weird casting and worrying about bit-level offsets. | ||
666 | |||
667 | **********************************************************************/ | ||
668 | |||
669 | static | ||
670 | unsigned char * | ||
671 | munge_int32 (unsigned int src, | ||
672 | unsigned char *dst, | ||
673 | unsigned int dst_size) | ||
674 | { | ||
675 | int i; | ||
676 | |||
677 | for (i = 0;i < dst_size; i++) { | ||
678 | *dst = src & 0x7F; /* Mask high bit of LSB */ | ||
679 | src = src >> 7; /* Rotate Right 7 bits */ | ||
680 | /* Note: we leave the upper bits in place */ | ||
681 | |||
682 | dst++; | ||
683 | }; | ||
684 | return dst; | ||
685 | }; | ||
686 | |||
687 | static int | ||
688 | demunge_int32 (unsigned char* src, int src_size) | ||
689 | |||
690 | { | ||
691 | int i; | ||
692 | int outval = 0; | ||
693 | |||
694 | for (i = src_size - 1; i >= 0; i--) { | ||
695 | outval=(outval<<7)+src[i]; | ||
696 | } | ||
697 | |||
698 | return outval; | ||
699 | }; | ||
700 | |||
701 | static | ||
702 | unsigned char * | ||
703 | munge_buf (unsigned char *src, unsigned char *dst, unsigned int dst_size) | ||
704 | |||
705 | { | ||
706 | int i; | ||
707 | unsigned int last = dst_size / 2; | ||
708 | |||
709 | for (i = 0; i < last; i++) { | ||
710 | *dst++ = src[i] & 0x7f; | ||
711 | *dst++ = src[i] >> 7; | ||
712 | } | ||
713 | return dst; | ||
714 | } | ||
715 | |||
716 | static | ||
717 | unsigned char * | ||
718 | demunge_buf (unsigned char *src, unsigned char *dst, unsigned int src_bytes) | ||
719 | |||
720 | { | ||
721 | int i; | ||
722 | unsigned char *end = src + src_bytes; | ||
723 | |||
724 | end = src + src_bytes; | ||
725 | |||
726 | /* NOTE: src and dst *CAN* point to the same address */ | ||
727 | |||
728 | for (i = 0; src != end; i++) { | ||
729 | dst[i] = *src++; | ||
730 | dst[i] |= (*src++)<<7; | ||
731 | } | ||
732 | |||
733 | return dst; | ||
734 | } | ||
735 | |||
736 | /*********************************************************************** | ||
737 | WaveFront: sample, patch and program management. | ||
738 | ***********************************************************************/ | ||
739 | |||
740 | static int | ||
741 | wavefront_delete_sample (int sample_num) | ||
742 | |||
743 | { | ||
744 | unsigned char wbuf[2]; | ||
745 | int x; | ||
746 | |||
747 | wbuf[0] = sample_num & 0x7f; | ||
748 | wbuf[1] = sample_num >> 7; | ||
749 | |||
750 | if ((x = wavefront_cmd (WFC_DELETE_SAMPLE, NULL, wbuf)) == 0) { | ||
751 | dev.sample_status[sample_num] = WF_ST_EMPTY; | ||
752 | } | ||
753 | |||
754 | return x; | ||
755 | } | ||
756 | |||
757 | static int | ||
758 | wavefront_get_sample_status (int assume_rom) | ||
759 | |||
760 | { | ||
761 | int i; | ||
762 | unsigned char rbuf[32], wbuf[32]; | ||
763 | unsigned int sc_real, sc_alias, sc_multi; | ||
764 | |||
765 | /* check sample status */ | ||
766 | |||
767 | if (wavefront_cmd (WFC_GET_NSAMPLES, rbuf, wbuf)) { | ||
768 | printk (KERN_WARNING LOGNAME "cannot request sample count.\n"); | ||
769 | return -1; | ||
770 | } | ||
771 | |||
772 | sc_real = sc_alias = sc_multi = dev.samples_used = 0; | ||
773 | |||
774 | for (i = 0; i < WF_MAX_SAMPLE; i++) { | ||
775 | |||
776 | wbuf[0] = i & 0x7f; | ||
777 | wbuf[1] = i >> 7; | ||
778 | |||
779 | if (wavefront_cmd (WFC_IDENTIFY_SAMPLE_TYPE, rbuf, wbuf)) { | ||
780 | printk (KERN_WARNING LOGNAME | ||
781 | "cannot identify sample " | ||
782 | "type of slot %d\n", i); | ||
783 | dev.sample_status[i] = WF_ST_EMPTY; | ||
784 | continue; | ||
785 | } | ||
786 | |||
787 | dev.sample_status[i] = (WF_SLOT_FILLED|rbuf[0]); | ||
788 | |||
789 | if (assume_rom) { | ||
790 | dev.sample_status[i] |= WF_SLOT_ROM; | ||
791 | } | ||
792 | |||
793 | switch (rbuf[0] & WF_ST_MASK) { | ||
794 | case WF_ST_SAMPLE: | ||
795 | sc_real++; | ||
796 | break; | ||
797 | case WF_ST_MULTISAMPLE: | ||
798 | sc_multi++; | ||
799 | break; | ||
800 | case WF_ST_ALIAS: | ||
801 | sc_alias++; | ||
802 | break; | ||
803 | case WF_ST_EMPTY: | ||
804 | break; | ||
805 | |||
806 | default: | ||
807 | printk (KERN_WARNING LOGNAME "unknown sample type for " | ||
808 | "slot %d (0x%x)\n", | ||
809 | i, rbuf[0]); | ||
810 | } | ||
811 | |||
812 | if (rbuf[0] != WF_ST_EMPTY) { | ||
813 | dev.samples_used++; | ||
814 | } | ||
815 | } | ||
816 | |||
817 | printk (KERN_INFO LOGNAME | ||
818 | "%d samples used (%d real, %d aliases, %d multi), " | ||
819 | "%d empty\n", dev.samples_used, sc_real, sc_alias, sc_multi, | ||
820 | WF_MAX_SAMPLE - dev.samples_used); | ||
821 | |||
822 | |||
823 | return (0); | ||
824 | |||
825 | } | ||
826 | |||
827 | static int | ||
828 | wavefront_get_patch_status (void) | ||
829 | |||
830 | { | ||
831 | unsigned char patchbuf[WF_PATCH_BYTES]; | ||
832 | unsigned char patchnum[2]; | ||
833 | wavefront_patch *p; | ||
834 | int i, x, cnt, cnt2; | ||
835 | |||
836 | for (i = 0; i < WF_MAX_PATCH; i++) { | ||
837 | patchnum[0] = i & 0x7f; | ||
838 | patchnum[1] = i >> 7; | ||
839 | |||
840 | if ((x = wavefront_cmd (WFC_UPLOAD_PATCH, patchbuf, | ||
841 | patchnum)) == 0) { | ||
842 | |||
843 | dev.patch_status[i] |= WF_SLOT_FILLED; | ||
844 | p = (wavefront_patch *) patchbuf; | ||
845 | dev.sample_status | ||
846 | [p->sample_number|(p->sample_msb<<7)] |= | ||
847 | WF_SLOT_USED; | ||
848 | |||
849 | } else if (x == 3) { /* Bad patch number */ | ||
850 | dev.patch_status[i] = 0; | ||
851 | } else { | ||
852 | printk (KERN_ERR LOGNAME "upload patch " | ||
853 | "error 0x%x\n", x); | ||
854 | dev.patch_status[i] = 0; | ||
855 | return 1; | ||
856 | } | ||
857 | } | ||
858 | |||
859 | /* program status has already filled in slot_used bits */ | ||
860 | |||
861 | for (i = 0, cnt = 0, cnt2 = 0; i < WF_MAX_PATCH; i++) { | ||
862 | if (dev.patch_status[i] & WF_SLOT_FILLED) { | ||
863 | cnt++; | ||
864 | } | ||
865 | if (dev.patch_status[i] & WF_SLOT_USED) { | ||
866 | cnt2++; | ||
867 | } | ||
868 | |||
869 | } | ||
870 | printk (KERN_INFO LOGNAME | ||
871 | "%d patch slots filled, %d in use\n", cnt, cnt2); | ||
872 | |||
873 | return (0); | ||
874 | } | ||
875 | |||
876 | static int | ||
877 | wavefront_get_program_status (void) | ||
878 | |||
879 | { | ||
880 | unsigned char progbuf[WF_PROGRAM_BYTES]; | ||
881 | wavefront_program prog; | ||
882 | unsigned char prognum; | ||
883 | int i, x, l, cnt; | ||
884 | |||
885 | for (i = 0; i < WF_MAX_PROGRAM; i++) { | ||
886 | prognum = i; | ||
887 | |||
888 | if ((x = wavefront_cmd (WFC_UPLOAD_PROGRAM, progbuf, | ||
889 | &prognum)) == 0) { | ||
890 | |||
891 | dev.prog_status[i] |= WF_SLOT_USED; | ||
892 | |||
893 | demunge_buf (progbuf, (unsigned char *) &prog, | ||
894 | WF_PROGRAM_BYTES); | ||
895 | |||
896 | for (l = 0; l < WF_NUM_LAYERS; l++) { | ||
897 | if (prog.layer[l].mute) { | ||
898 | dev.patch_status | ||
899 | [prog.layer[l].patch_number] |= | ||
900 | WF_SLOT_USED; | ||
901 | } | ||
902 | } | ||
903 | } else if (x == 1) { /* Bad program number */ | ||
904 | dev.prog_status[i] = 0; | ||
905 | } else { | ||
906 | printk (KERN_ERR LOGNAME "upload program " | ||
907 | "error 0x%x\n", x); | ||
908 | dev.prog_status[i] = 0; | ||
909 | } | ||
910 | } | ||
911 | |||
912 | for (i = 0, cnt = 0; i < WF_MAX_PROGRAM; i++) { | ||
913 | if (dev.prog_status[i]) { | ||
914 | cnt++; | ||
915 | } | ||
916 | } | ||
917 | |||
918 | printk (KERN_INFO LOGNAME "%d programs slots in use\n", cnt); | ||
919 | |||
920 | return (0); | ||
921 | } | ||
922 | |||
923 | static int | ||
924 | wavefront_send_patch (wavefront_patch_info *header) | ||
925 | |||
926 | { | ||
927 | unsigned char buf[WF_PATCH_BYTES+2]; | ||
928 | unsigned char *bptr; | ||
929 | |||
930 | DPRINT (WF_DEBUG_LOAD_PATCH, "downloading patch %d\n", | ||
931 | header->number); | ||
932 | |||
933 | dev.patch_status[header->number] |= WF_SLOT_FILLED; | ||
934 | |||
935 | bptr = buf; | ||
936 | bptr = munge_int32 (header->number, buf, 2); | ||
937 | munge_buf ((unsigned char *)&header->hdr.p, bptr, WF_PATCH_BYTES); | ||
938 | |||
939 | if (wavefront_cmd (WFC_DOWNLOAD_PATCH, NULL, buf)) { | ||
940 | printk (KERN_ERR LOGNAME "download patch failed\n"); | ||
941 | return -(EIO); | ||
942 | } | ||
943 | |||
944 | return (0); | ||
945 | } | ||
946 | |||
947 | static int | ||
948 | wavefront_send_program (wavefront_patch_info *header) | ||
949 | |||
950 | { | ||
951 | unsigned char buf[WF_PROGRAM_BYTES+1]; | ||
952 | int i; | ||
953 | |||
954 | DPRINT (WF_DEBUG_LOAD_PATCH, "downloading program %d\n", | ||
955 | header->number); | ||
956 | |||
957 | dev.prog_status[header->number] = WF_SLOT_USED; | ||
958 | |||
959 | /* XXX need to zero existing SLOT_USED bit for program_status[i] | ||
960 | where `i' is the program that's being (potentially) overwritten. | ||
961 | */ | ||
962 | |||
963 | for (i = 0; i < WF_NUM_LAYERS; i++) { | ||
964 | if (header->hdr.pr.layer[i].mute) { | ||
965 | dev.patch_status[header->hdr.pr.layer[i].patch_number] |= | ||
966 | WF_SLOT_USED; | ||
967 | |||
968 | /* XXX need to mark SLOT_USED for sample used by | ||
969 | patch_number, but this means we have to load it. Ick. | ||
970 | */ | ||
971 | } | ||
972 | } | ||
973 | |||
974 | buf[0] = header->number; | ||
975 | munge_buf ((unsigned char *)&header->hdr.pr, &buf[1], WF_PROGRAM_BYTES); | ||
976 | |||
977 | if (wavefront_cmd (WFC_DOWNLOAD_PROGRAM, NULL, buf)) { | ||
978 | printk (KERN_WARNING LOGNAME "download patch failed\n"); | ||
979 | return -(EIO); | ||
980 | } | ||
981 | |||
982 | return (0); | ||
983 | } | ||
984 | |||
985 | static int | ||
986 | wavefront_freemem (void) | ||
987 | |||
988 | { | ||
989 | char rbuf[8]; | ||
990 | |||
991 | if (wavefront_cmd (WFC_REPORT_FREE_MEMORY, rbuf, NULL)) { | ||
992 | printk (KERN_WARNING LOGNAME "can't get memory stats.\n"); | ||
993 | return -1; | ||
994 | } else { | ||
995 | return demunge_int32 (rbuf, 4); | ||
996 | } | ||
997 | } | ||
998 | |||
999 | static int | ||
1000 | wavefront_send_sample (wavefront_patch_info *header, | ||
1001 | UINT16 __user *dataptr, | ||
1002 | int data_is_unsigned) | ||
1003 | |||
1004 | { | ||
1005 | /* samples are downloaded via a 16-bit wide i/o port | ||
1006 | (you could think of it as 2 adjacent 8-bit wide ports | ||
1007 | but its less efficient that way). therefore, all | ||
1008 | the blocksizes and so forth listed in the documentation, | ||
1009 | and used conventionally to refer to sample sizes, | ||
1010 | which are given in 8-bit units (bytes), need to be | ||
1011 | divided by 2. | ||
1012 | */ | ||
1013 | |||
1014 | UINT16 sample_short; | ||
1015 | UINT32 length; | ||
1016 | UINT16 __user *data_end = NULL; | ||
1017 | unsigned int i; | ||
1018 | const int max_blksize = 4096/2; | ||
1019 | unsigned int written; | ||
1020 | unsigned int blocksize; | ||
1021 | int dma_ack; | ||
1022 | int blocknum; | ||
1023 | unsigned char sample_hdr[WF_SAMPLE_HDR_BYTES]; | ||
1024 | unsigned char *shptr; | ||
1025 | int skip = 0; | ||
1026 | int initial_skip = 0; | ||
1027 | |||
1028 | DPRINT (WF_DEBUG_LOAD_PATCH, "sample %sdownload for slot %d, " | ||
1029 | "type %d, %d bytes from %p\n", | ||
1030 | header->size ? "" : "header ", | ||
1031 | header->number, header->subkey, | ||
1032 | header->size, | ||
1033 | header->dataptr); | ||
1034 | |||
1035 | if (header->number == WAVEFRONT_FIND_FREE_SAMPLE_SLOT) { | ||
1036 | int x; | ||
1037 | |||
1038 | if ((x = wavefront_find_free_sample ()) < 0) { | ||
1039 | return -ENOMEM; | ||
1040 | } | ||
1041 | printk (KERN_DEBUG LOGNAME "unspecified sample => %d\n", x); | ||
1042 | header->number = x; | ||
1043 | } | ||
1044 | |||
1045 | if (header->size) { | ||
1046 | |||
1047 | /* XXX it's a debatable point whether or not RDONLY semantics | ||
1048 | on the ROM samples should cover just the sample data or | ||
1049 | the sample header. For now, it only covers the sample data, | ||
1050 | so anyone is free at all times to rewrite sample headers. | ||
1051 | |||
1052 | My reason for this is that we have the sample headers | ||
1053 | available in the WFB file for General MIDI, and so these | ||
1054 | can always be reset if needed. The sample data, however, | ||
1055 | cannot be recovered without a complete reset and firmware | ||
1056 | reload of the ICS2115, which is a very expensive operation. | ||
1057 | |||
1058 | So, doing things this way allows us to honor the notion of | ||
1059 | "RESETSAMPLES" reasonably cheaply. Note however, that this | ||
1060 | is done purely at user level: there is no WFB parser in | ||
1061 | this driver, and so a complete reset (back to General MIDI, | ||
1062 | or theoretically some other configuration) is the | ||
1063 | responsibility of the user level library. | ||
1064 | |||
1065 | To try to do this in the kernel would be a little | ||
1066 | crazy: we'd need 158K of kernel space just to hold | ||
1067 | a copy of the patch/program/sample header data. | ||
1068 | */ | ||
1069 | |||
1070 | if (dev.rom_samples_rdonly) { | ||
1071 | if (dev.sample_status[header->number] & WF_SLOT_ROM) { | ||
1072 | printk (KERN_ERR LOGNAME "sample slot %d " | ||
1073 | "write protected\n", | ||
1074 | header->number); | ||
1075 | return -EACCES; | ||
1076 | } | ||
1077 | } | ||
1078 | |||
1079 | wavefront_delete_sample (header->number); | ||
1080 | } | ||
1081 | |||
1082 | if (header->size) { | ||
1083 | dev.freemem = wavefront_freemem (); | ||
1084 | |||
1085 | if (dev.freemem < header->size) { | ||
1086 | printk (KERN_ERR LOGNAME | ||
1087 | "insufficient memory to " | ||
1088 | "load %d byte sample.\n", | ||
1089 | header->size); | ||
1090 | return -ENOMEM; | ||
1091 | } | ||
1092 | |||
1093 | } | ||
1094 | |||
1095 | skip = WF_GET_CHANNEL(&header->hdr.s); | ||
1096 | |||
1097 | if (skip > 0 && header->hdr.s.SampleResolution != LINEAR_16BIT) { | ||
1098 | printk (KERN_ERR LOGNAME "channel selection only " | ||
1099 | "possible on 16-bit samples"); | ||
1100 | return -(EINVAL); | ||
1101 | } | ||
1102 | |||
1103 | switch (skip) { | ||
1104 | case 0: | ||
1105 | initial_skip = 0; | ||
1106 | skip = 1; | ||
1107 | break; | ||
1108 | case 1: | ||
1109 | initial_skip = 0; | ||
1110 | skip = 2; | ||
1111 | break; | ||
1112 | case 2: | ||
1113 | initial_skip = 1; | ||
1114 | skip = 2; | ||
1115 | break; | ||
1116 | case 3: | ||
1117 | initial_skip = 2; | ||
1118 | skip = 3; | ||
1119 | break; | ||
1120 | case 4: | ||
1121 | initial_skip = 3; | ||
1122 | skip = 4; | ||
1123 | break; | ||
1124 | case 5: | ||
1125 | initial_skip = 4; | ||
1126 | skip = 5; | ||
1127 | break; | ||
1128 | case 6: | ||
1129 | initial_skip = 5; | ||
1130 | skip = 6; | ||
1131 | break; | ||
1132 | } | ||
1133 | |||
1134 | DPRINT (WF_DEBUG_LOAD_PATCH, "channel selection: %d => " | ||
1135 | "initial skip = %d, skip = %d\n", | ||
1136 | WF_GET_CHANNEL (&header->hdr.s), | ||
1137 | initial_skip, skip); | ||
1138 | |||
1139 | /* Be safe, and zero the "Unused" bits ... */ | ||
1140 | |||
1141 | WF_SET_CHANNEL(&header->hdr.s, 0); | ||
1142 | |||
1143 | /* adjust size for 16 bit samples by dividing by two. We always | ||
1144 | send 16 bits per write, even for 8 bit samples, so the length | ||
1145 | is always half the size of the sample data in bytes. | ||
1146 | */ | ||
1147 | |||
1148 | length = header->size / 2; | ||
1149 | |||
1150 | /* the data we're sent has not been munged, and in fact, the | ||
1151 | header we have to send isn't just a munged copy either. | ||
1152 | so, build the sample header right here. | ||
1153 | */ | ||
1154 | |||
1155 | shptr = &sample_hdr[0]; | ||
1156 | |||
1157 | shptr = munge_int32 (header->number, shptr, 2); | ||
1158 | |||
1159 | if (header->size) { | ||
1160 | shptr = munge_int32 (length, shptr, 4); | ||
1161 | } | ||
1162 | |||
1163 | /* Yes, a 4 byte result doesn't contain all of the offset bits, | ||
1164 | but the offset only uses 24 bits. | ||
1165 | */ | ||
1166 | |||
1167 | shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleStartOffset), | ||
1168 | shptr, 4); | ||
1169 | shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopStartOffset), | ||
1170 | shptr, 4); | ||
1171 | shptr = munge_int32 (*((UINT32 *) &header->hdr.s.loopEndOffset), | ||
1172 | shptr, 4); | ||
1173 | shptr = munge_int32 (*((UINT32 *) &header->hdr.s.sampleEndOffset), | ||
1174 | shptr, 4); | ||
1175 | |||
1176 | /* This one is truly weird. What kind of weirdo decided that in | ||
1177 | a system dominated by 16 and 32 bit integers, they would use | ||
1178 | a just 12 bits ? | ||
1179 | */ | ||
1180 | |||
1181 | shptr = munge_int32 (header->hdr.s.FrequencyBias, shptr, 3); | ||
1182 | |||
1183 | /* Why is this nybblified, when the MSB is *always* zero ? | ||
1184 | Anyway, we can't take address of bitfield, so make a | ||
1185 | good-faith guess at where it starts. | ||
1186 | */ | ||
1187 | |||
1188 | shptr = munge_int32 (*(&header->hdr.s.FrequencyBias+1), | ||
1189 | shptr, 2); | ||
1190 | |||
1191 | if (wavefront_cmd (header->size ? | ||
1192 | WFC_DOWNLOAD_SAMPLE : WFC_DOWNLOAD_SAMPLE_HEADER, | ||
1193 | NULL, sample_hdr)) { | ||
1194 | printk (KERN_WARNING LOGNAME "sample %sdownload refused.\n", | ||
1195 | header->size ? "" : "header "); | ||
1196 | return -(EIO); | ||
1197 | } | ||
1198 | |||
1199 | if (header->size == 0) { | ||
1200 | goto sent; /* Sorry. Just had to have one somewhere */ | ||
1201 | } | ||
1202 | |||
1203 | data_end = dataptr + length; | ||
1204 | |||
1205 | /* Do any initial skip over an unused channel's data */ | ||
1206 | |||
1207 | dataptr += initial_skip; | ||
1208 | |||
1209 | for (written = 0, blocknum = 0; | ||
1210 | written < length; written += max_blksize, blocknum++) { | ||
1211 | |||
1212 | if ((length - written) > max_blksize) { | ||
1213 | blocksize = max_blksize; | ||
1214 | } else { | ||
1215 | /* round to nearest 16-byte value */ | ||
1216 | blocksize = ((length-written+7)&~0x7); | ||
1217 | } | ||
1218 | |||
1219 | if (wavefront_cmd (WFC_DOWNLOAD_BLOCK, NULL, NULL)) { | ||
1220 | printk (KERN_WARNING LOGNAME "download block " | ||
1221 | "request refused.\n"); | ||
1222 | return -(EIO); | ||
1223 | } | ||
1224 | |||
1225 | for (i = 0; i < blocksize; i++) { | ||
1226 | |||
1227 | if (dataptr < data_end) { | ||
1228 | |||
1229 | __get_user (sample_short, dataptr); | ||
1230 | dataptr += skip; | ||
1231 | |||
1232 | if (data_is_unsigned) { /* GUS ? */ | ||
1233 | |||
1234 | if (WF_SAMPLE_IS_8BIT(&header->hdr.s)) { | ||
1235 | |||
1236 | /* 8 bit sample | ||
1237 | resolution, sign | ||
1238 | extend both bytes. | ||
1239 | */ | ||
1240 | |||
1241 | ((unsigned char*) | ||
1242 | &sample_short)[0] += 0x7f; | ||
1243 | ((unsigned char*) | ||
1244 | &sample_short)[1] += 0x7f; | ||
1245 | |||
1246 | } else { | ||
1247 | |||
1248 | /* 16 bit sample | ||
1249 | resolution, sign | ||
1250 | extend the MSB. | ||
1251 | */ | ||
1252 | |||
1253 | sample_short += 0x7fff; | ||
1254 | } | ||
1255 | } | ||
1256 | |||
1257 | } else { | ||
1258 | |||
1259 | /* In padding section of final block: | ||
1260 | |||
1261 | Don't fetch unsupplied data from | ||
1262 | user space, just continue with | ||
1263 | whatever the final value was. | ||
1264 | */ | ||
1265 | } | ||
1266 | |||
1267 | if (i < blocksize - 1) { | ||
1268 | outw (sample_short, dev.block_port); | ||
1269 | } else { | ||
1270 | outw (sample_short, dev.last_block_port); | ||
1271 | } | ||
1272 | } | ||
1273 | |||
1274 | /* Get "DMA page acknowledge", even though its really | ||
1275 | nothing to do with DMA at all. | ||
1276 | */ | ||
1277 | |||
1278 | if ((dma_ack = wavefront_read ()) != WF_DMA_ACK) { | ||
1279 | if (dma_ack == -1) { | ||
1280 | printk (KERN_ERR LOGNAME "upload sample " | ||
1281 | "DMA ack timeout\n"); | ||
1282 | return -(EIO); | ||
1283 | } else { | ||
1284 | printk (KERN_ERR LOGNAME "upload sample " | ||
1285 | "DMA ack error 0x%x\n", | ||
1286 | dma_ack); | ||
1287 | return -(EIO); | ||
1288 | } | ||
1289 | } | ||
1290 | } | ||
1291 | |||
1292 | dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_SAMPLE); | ||
1293 | |||
1294 | /* Note, label is here because sending the sample header shouldn't | ||
1295 | alter the sample_status info at all. | ||
1296 | */ | ||
1297 | |||
1298 | sent: | ||
1299 | return (0); | ||
1300 | } | ||
1301 | |||
1302 | static int | ||
1303 | wavefront_send_alias (wavefront_patch_info *header) | ||
1304 | |||
1305 | { | ||
1306 | unsigned char alias_hdr[WF_ALIAS_BYTES]; | ||
1307 | |||
1308 | DPRINT (WF_DEBUG_LOAD_PATCH, "download alias, %d is " | ||
1309 | "alias for %d\n", | ||
1310 | header->number, | ||
1311 | header->hdr.a.OriginalSample); | ||
1312 | |||
1313 | munge_int32 (header->number, &alias_hdr[0], 2); | ||
1314 | munge_int32 (header->hdr.a.OriginalSample, &alias_hdr[2], 2); | ||
1315 | munge_int32 (*((unsigned int *)&header->hdr.a.sampleStartOffset), | ||
1316 | &alias_hdr[4], 4); | ||
1317 | munge_int32 (*((unsigned int *)&header->hdr.a.loopStartOffset), | ||
1318 | &alias_hdr[8], 4); | ||
1319 | munge_int32 (*((unsigned int *)&header->hdr.a.loopEndOffset), | ||
1320 | &alias_hdr[12], 4); | ||
1321 | munge_int32 (*((unsigned int *)&header->hdr.a.sampleEndOffset), | ||
1322 | &alias_hdr[16], 4); | ||
1323 | munge_int32 (header->hdr.a.FrequencyBias, &alias_hdr[20], 3); | ||
1324 | munge_int32 (*(&header->hdr.a.FrequencyBias+1), &alias_hdr[23], 2); | ||
1325 | |||
1326 | if (wavefront_cmd (WFC_DOWNLOAD_SAMPLE_ALIAS, NULL, alias_hdr)) { | ||
1327 | printk (KERN_ERR LOGNAME "download alias failed.\n"); | ||
1328 | return -(EIO); | ||
1329 | } | ||
1330 | |||
1331 | dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_ALIAS); | ||
1332 | |||
1333 | return (0); | ||
1334 | } | ||
1335 | |||
1336 | static int | ||
1337 | wavefront_send_multisample (wavefront_patch_info *header) | ||
1338 | { | ||
1339 | int i; | ||
1340 | int num_samples; | ||
1341 | unsigned char msample_hdr[WF_MSAMPLE_BYTES]; | ||
1342 | |||
1343 | munge_int32 (header->number, &msample_hdr[0], 2); | ||
1344 | |||
1345 | /* You'll recall at this point that the "number of samples" value | ||
1346 | in a wavefront_multisample struct is actually the log2 of the | ||
1347 | real number of samples. | ||
1348 | */ | ||
1349 | |||
1350 | num_samples = (1<<(header->hdr.ms.NumberOfSamples&7)); | ||
1351 | msample_hdr[2] = (unsigned char) header->hdr.ms.NumberOfSamples; | ||
1352 | |||
1353 | DPRINT (WF_DEBUG_LOAD_PATCH, "multi %d with %d=%d samples\n", | ||
1354 | header->number, | ||
1355 | header->hdr.ms.NumberOfSamples, | ||
1356 | num_samples); | ||
1357 | |||
1358 | for (i = 0; i < num_samples; i++) { | ||
1359 | DPRINT(WF_DEBUG_LOAD_PATCH|WF_DEBUG_DATA, "sample[%d] = %d\n", | ||
1360 | i, header->hdr.ms.SampleNumber[i]); | ||
1361 | munge_int32 (header->hdr.ms.SampleNumber[i], | ||
1362 | &msample_hdr[3+(i*2)], 2); | ||
1363 | } | ||
1364 | |||
1365 | /* Need a hack here to pass in the number of bytes | ||
1366 | to be written to the synth. This is ugly, and perhaps | ||
1367 | one day, I'll fix it. | ||
1368 | */ | ||
1369 | |||
1370 | if (wavefront_cmd (WFC_DOWNLOAD_MULTISAMPLE, | ||
1371 | (unsigned char *) ((num_samples*2)+3), | ||
1372 | msample_hdr)) { | ||
1373 | printk (KERN_ERR LOGNAME "download of multisample failed.\n"); | ||
1374 | return -(EIO); | ||
1375 | } | ||
1376 | |||
1377 | dev.sample_status[header->number] = (WF_SLOT_FILLED|WF_ST_MULTISAMPLE); | ||
1378 | |||
1379 | return (0); | ||
1380 | } | ||
1381 | |||
1382 | static int | ||
1383 | wavefront_fetch_multisample (wavefront_patch_info *header) | ||
1384 | { | ||
1385 | int i; | ||
1386 | unsigned char log_ns[1]; | ||
1387 | unsigned char number[2]; | ||
1388 | int num_samples; | ||
1389 | |||
1390 | munge_int32 (header->number, number, 2); | ||
1391 | |||
1392 | if (wavefront_cmd (WFC_UPLOAD_MULTISAMPLE, log_ns, number)) { | ||
1393 | printk (KERN_ERR LOGNAME "upload multisample failed.\n"); | ||
1394 | return -(EIO); | ||
1395 | } | ||
1396 | |||
1397 | DPRINT (WF_DEBUG_DATA, "msample %d has %d samples\n", | ||
1398 | header->number, log_ns[0]); | ||
1399 | |||
1400 | header->hdr.ms.NumberOfSamples = log_ns[0]; | ||
1401 | |||
1402 | /* get the number of samples ... */ | ||
1403 | |||
1404 | num_samples = (1 << log_ns[0]); | ||
1405 | |||
1406 | for (i = 0; i < num_samples; i++) { | ||
1407 | s8 d[2]; | ||
1408 | |||
1409 | if ((d[0] = wavefront_read ()) == -1) { | ||
1410 | printk (KERN_ERR LOGNAME "upload multisample failed " | ||
1411 | "during sample loop.\n"); | ||
1412 | return -(EIO); | ||
1413 | } | ||
1414 | |||
1415 | if ((d[1] = wavefront_read ()) == -1) { | ||
1416 | printk (KERN_ERR LOGNAME "upload multisample failed " | ||
1417 | "during sample loop.\n"); | ||
1418 | return -(EIO); | ||
1419 | } | ||
1420 | |||
1421 | header->hdr.ms.SampleNumber[i] = | ||
1422 | demunge_int32 ((unsigned char *) d, 2); | ||
1423 | |||
1424 | DPRINT (WF_DEBUG_DATA, "msample sample[%d] = %d\n", | ||
1425 | i, header->hdr.ms.SampleNumber[i]); | ||
1426 | } | ||
1427 | |||
1428 | return (0); | ||
1429 | } | ||
1430 | |||
1431 | |||
1432 | static int | ||
1433 | wavefront_send_drum (wavefront_patch_info *header) | ||
1434 | |||
1435 | { | ||
1436 | unsigned char drumbuf[WF_DRUM_BYTES]; | ||
1437 | wavefront_drum *drum = &header->hdr.d; | ||
1438 | int i; | ||
1439 | |||
1440 | DPRINT (WF_DEBUG_LOAD_PATCH, "downloading edrum for MIDI " | ||
1441 | "note %d, patch = %d\n", | ||
1442 | header->number, drum->PatchNumber); | ||
1443 | |||
1444 | drumbuf[0] = header->number & 0x7f; | ||
1445 | |||
1446 | for (i = 0; i < 4; i++) { | ||
1447 | munge_int32 (((unsigned char *)drum)[i], &drumbuf[1+(i*2)], 2); | ||
1448 | } | ||
1449 | |||
1450 | if (wavefront_cmd (WFC_DOWNLOAD_EDRUM_PROGRAM, NULL, drumbuf)) { | ||
1451 | printk (KERN_ERR LOGNAME "download drum failed.\n"); | ||
1452 | return -(EIO); | ||
1453 | } | ||
1454 | |||
1455 | return (0); | ||
1456 | } | ||
1457 | |||
1458 | static int | ||
1459 | wavefront_find_free_sample (void) | ||
1460 | |||
1461 | { | ||
1462 | int i; | ||
1463 | |||
1464 | for (i = 0; i < WF_MAX_SAMPLE; i++) { | ||
1465 | if (!(dev.sample_status[i] & WF_SLOT_FILLED)) { | ||
1466 | return i; | ||
1467 | } | ||
1468 | } | ||
1469 | printk (KERN_WARNING LOGNAME "no free sample slots!\n"); | ||
1470 | return -1; | ||
1471 | } | ||
1472 | |||
1473 | static int | ||
1474 | wavefront_find_free_patch (void) | ||
1475 | |||
1476 | { | ||
1477 | int i; | ||
1478 | |||
1479 | for (i = 0; i < WF_MAX_PATCH; i++) { | ||
1480 | if (!(dev.patch_status[i] & WF_SLOT_FILLED)) { | ||
1481 | return i; | ||
1482 | } | ||
1483 | } | ||
1484 | printk (KERN_WARNING LOGNAME "no free patch slots!\n"); | ||
1485 | return -1; | ||
1486 | } | ||
1487 | |||
1488 | static int | ||
1489 | log2_2048(int n) | ||
1490 | |||
1491 | { | ||
1492 | int tbl[]={0, 0, 2048, 3246, 4096, 4755, 5294, 5749, 6143, | ||
1493 | 6492, 6803, 7084, 7342, 7578, 7797, 8001, 8192, | ||
1494 | 8371, 8540, 8699, 8851, 8995, 9132, 9264, 9390, | ||
1495 | 9510, 9626, 9738, 9845, 9949, 10049, 10146}; | ||
1496 | int i; | ||
1497 | |||
1498 | /* Returns 2048*log2(n) */ | ||
1499 | |||
1500 | /* FIXME: this is like doing integer math | ||
1501 | on quantum particles (RuN) */ | ||
1502 | |||
1503 | i=0; | ||
1504 | while(n>=32*256) { | ||
1505 | n>>=8; | ||
1506 | i+=2048*8; | ||
1507 | } | ||
1508 | while(n>=32) { | ||
1509 | n>>=1; | ||
1510 | i+=2048; | ||
1511 | } | ||
1512 | i+=tbl[n]; | ||
1513 | return(i); | ||
1514 | } | ||
1515 | |||
1516 | static int | ||
1517 | wavefront_load_gus_patch (int devno, int format, const char __user *addr, | ||
1518 | int offs, int count, int pmgr_flag) | ||
1519 | { | ||
1520 | struct patch_info guspatch; | ||
1521 | wavefront_patch_info *samp, *pat, *prog; | ||
1522 | wavefront_patch *patp; | ||
1523 | wavefront_sample *sampp; | ||
1524 | wavefront_program *progp; | ||
1525 | |||
1526 | int i,base_note; | ||
1527 | long sizeof_patch; | ||
1528 | int rc = -ENOMEM; | ||
1529 | |||
1530 | samp = kmalloc(3 * sizeof(wavefront_patch_info), GFP_KERNEL); | ||
1531 | if (!samp) | ||
1532 | goto free_fail; | ||
1533 | pat = samp + 1; | ||
1534 | prog = pat + 1; | ||
1535 | |||
1536 | /* Copy in the header of the GUS patch */ | ||
1537 | |||
1538 | sizeof_patch = (long) &guspatch.data[0] - (long) &guspatch; | ||
1539 | if (copy_from_user(&((char *) &guspatch)[offs], | ||
1540 | &(addr)[offs], sizeof_patch - offs)) { | ||
1541 | rc = -EFAULT; | ||
1542 | goto free_fail; | ||
1543 | } | ||
1544 | |||
1545 | if ((i = wavefront_find_free_patch ()) == -1) { | ||
1546 | rc = -EBUSY; | ||
1547 | goto free_fail; | ||
1548 | } | ||
1549 | pat->number = i; | ||
1550 | pat->subkey = WF_ST_PATCH; | ||
1551 | patp = &pat->hdr.p; | ||
1552 | |||
1553 | if ((i = wavefront_find_free_sample ()) == -1) { | ||
1554 | rc = -EBUSY; | ||
1555 | goto free_fail; | ||
1556 | } | ||
1557 | samp->number = i; | ||
1558 | samp->subkey = WF_ST_SAMPLE; | ||
1559 | samp->size = guspatch.len; | ||
1560 | sampp = &samp->hdr.s; | ||
1561 | |||
1562 | prog->number = guspatch.instr_no; | ||
1563 | progp = &prog->hdr.pr; | ||
1564 | |||
1565 | /* Setup the patch structure */ | ||
1566 | |||
1567 | patp->amplitude_bias=guspatch.volume; | ||
1568 | patp->portamento=0; | ||
1569 | patp->sample_number= samp->number & 0xff; | ||
1570 | patp->sample_msb= samp->number >> 8; | ||
1571 | patp->pitch_bend= /*12*/ 0; | ||
1572 | patp->mono=1; | ||
1573 | patp->retrigger=1; | ||
1574 | patp->nohold=(guspatch.mode & WAVE_SUSTAIN_ON) ? 0:1; | ||
1575 | patp->frequency_bias=0; | ||
1576 | patp->restart=0; | ||
1577 | patp->reuse=0; | ||
1578 | patp->reset_lfo=1; | ||
1579 | patp->fm_src2=0; | ||
1580 | patp->fm_src1=WF_MOD_MOD_WHEEL; | ||
1581 | patp->am_src=WF_MOD_PRESSURE; | ||
1582 | patp->am_amount=127; | ||
1583 | patp->fc1_mod_amount=0; | ||
1584 | patp->fc2_mod_amount=0; | ||
1585 | patp->fm_amount1=0; | ||
1586 | patp->fm_amount2=0; | ||
1587 | patp->envelope1.attack_level=127; | ||
1588 | patp->envelope1.decay1_level=127; | ||
1589 | patp->envelope1.decay2_level=127; | ||
1590 | patp->envelope1.sustain_level=127; | ||
1591 | patp->envelope1.release_level=0; | ||
1592 | patp->envelope2.attack_velocity=127; | ||
1593 | patp->envelope2.attack_level=127; | ||
1594 | patp->envelope2.decay1_level=127; | ||
1595 | patp->envelope2.decay2_level=127; | ||
1596 | patp->envelope2.sustain_level=127; | ||
1597 | patp->envelope2.release_level=0; | ||
1598 | patp->envelope2.attack_velocity=127; | ||
1599 | patp->randomizer=0; | ||
1600 | |||
1601 | /* Program for this patch */ | ||
1602 | |||
1603 | progp->layer[0].patch_number= pat->number; /* XXX is this right ? */ | ||
1604 | progp->layer[0].mute=1; | ||
1605 | progp->layer[0].pan_or_mod=1; | ||
1606 | progp->layer[0].pan=7; | ||
1607 | progp->layer[0].mix_level=127 /* guspatch.volume */; | ||
1608 | progp->layer[0].split_type=0; | ||
1609 | progp->layer[0].split_point=0; | ||
1610 | progp->layer[0].play_below=0; | ||
1611 | |||
1612 | for (i = 1; i < 4; i++) { | ||
1613 | progp->layer[i].mute=0; | ||
1614 | } | ||
1615 | |||
1616 | /* Sample data */ | ||
1617 | |||
1618 | sampp->SampleResolution=((~guspatch.mode & WAVE_16_BITS)<<1); | ||
1619 | |||
1620 | for (base_note=0; | ||
1621 | note_to_freq (base_note) < guspatch.base_note; | ||
1622 | base_note++); | ||
1623 | |||
1624 | if ((guspatch.base_note-note_to_freq(base_note)) | ||
1625 | >(note_to_freq(base_note)-guspatch.base_note)) | ||
1626 | base_note++; | ||
1627 | |||
1628 | printk(KERN_DEBUG "ref freq=%d,base note=%d\n", | ||
1629 | guspatch.base_freq, | ||
1630 | base_note); | ||
1631 | |||
1632 | sampp->FrequencyBias = (29550 - log2_2048(guspatch.base_freq) | ||
1633 | + base_note*171); | ||
1634 | printk(KERN_DEBUG "Freq Bias is %d\n", sampp->FrequencyBias); | ||
1635 | sampp->Loop=(guspatch.mode & WAVE_LOOPING) ? 1:0; | ||
1636 | sampp->sampleStartOffset.Fraction=0; | ||
1637 | sampp->sampleStartOffset.Integer=0; | ||
1638 | sampp->loopStartOffset.Fraction=0; | ||
1639 | sampp->loopStartOffset.Integer=guspatch.loop_start | ||
1640 | >>((guspatch.mode&WAVE_16_BITS) ? 1:0); | ||
1641 | sampp->loopEndOffset.Fraction=0; | ||
1642 | sampp->loopEndOffset.Integer=guspatch.loop_end | ||
1643 | >>((guspatch.mode&WAVE_16_BITS) ? 1:0); | ||
1644 | sampp->sampleEndOffset.Fraction=0; | ||
1645 | sampp->sampleEndOffset.Integer=guspatch.len >> (guspatch.mode&1); | ||
1646 | sampp->Bidirectional=(guspatch.mode&WAVE_BIDIR_LOOP) ? 1:0; | ||
1647 | sampp->Reverse=(guspatch.mode&WAVE_LOOP_BACK) ? 1:0; | ||
1648 | |||
1649 | /* Now ship it down */ | ||
1650 | |||
1651 | wavefront_send_sample (samp, | ||
1652 | (unsigned short __user *) &(addr)[sizeof_patch], | ||
1653 | (guspatch.mode & WAVE_UNSIGNED) ? 1:0); | ||
1654 | wavefront_send_patch (pat); | ||
1655 | wavefront_send_program (prog); | ||
1656 | |||
1657 | /* Now pan as best we can ... use the slave/internal MIDI device | ||
1658 | number if it exists (since it talks to the WaveFront), or the | ||
1659 | master otherwise. | ||
1660 | */ | ||
1661 | |||
1662 | if (dev.mididev > 0) { | ||
1663 | midi_synth_controller (dev.mididev, guspatch.instr_no, 10, | ||
1664 | ((guspatch.panning << 4) > 127) ? | ||
1665 | 127 : (guspatch.panning << 4)); | ||
1666 | } | ||
1667 | rc = 0; | ||
1668 | |||
1669 | free_fail: | ||
1670 | kfree(samp); | ||
1671 | return rc; | ||
1672 | } | ||
1673 | |||
1674 | static int | ||
1675 | wavefront_load_patch (const char __user *addr) | ||
1676 | |||
1677 | |||
1678 | { | ||
1679 | wavefront_patch_info header; | ||
1680 | |||
1681 | if (copy_from_user (&header, addr, sizeof(wavefront_patch_info) - | ||
1682 | sizeof(wavefront_any))) { | ||
1683 | printk (KERN_WARNING LOGNAME "bad address for load patch.\n"); | ||
1684 | return -EFAULT; | ||
1685 | } | ||
1686 | |||
1687 | DPRINT (WF_DEBUG_LOAD_PATCH, "download " | ||
1688 | "Sample type: %d " | ||
1689 | "Sample number: %d " | ||
1690 | "Sample size: %d\n", | ||
1691 | header.subkey, | ||
1692 | header.number, | ||
1693 | header.size); | ||
1694 | |||
1695 | switch (header.subkey) { | ||
1696 | case WF_ST_SAMPLE: /* sample or sample_header, based on patch->size */ | ||
1697 | |||
1698 | if (copy_from_user((unsigned char *) &header.hdr.s, | ||
1699 | (unsigned char __user *) header.hdrptr, | ||
1700 | sizeof (wavefront_sample))) | ||
1701 | return -EFAULT; | ||
1702 | |||
1703 | return wavefront_send_sample (&header, header.dataptr, 0); | ||
1704 | |||
1705 | case WF_ST_MULTISAMPLE: | ||
1706 | |||
1707 | if (copy_from_user(&header.hdr.s, header.hdrptr, | ||
1708 | sizeof(wavefront_multisample))) | ||
1709 | return -EFAULT; | ||
1710 | |||
1711 | return wavefront_send_multisample (&header); | ||
1712 | |||
1713 | |||
1714 | case WF_ST_ALIAS: | ||
1715 | |||
1716 | if (copy_from_user(&header.hdr.a, header.hdrptr, | ||
1717 | sizeof (wavefront_alias))) | ||
1718 | return -EFAULT; | ||
1719 | |||
1720 | return wavefront_send_alias (&header); | ||
1721 | |||
1722 | case WF_ST_DRUM: | ||
1723 | if (copy_from_user(&header.hdr.d, header.hdrptr, | ||
1724 | sizeof (wavefront_drum))) | ||
1725 | return -EFAULT; | ||
1726 | |||
1727 | return wavefront_send_drum (&header); | ||
1728 | |||
1729 | case WF_ST_PATCH: | ||
1730 | if (copy_from_user(&header.hdr.p, header.hdrptr, | ||
1731 | sizeof (wavefront_patch))) | ||
1732 | return -EFAULT; | ||
1733 | |||
1734 | return wavefront_send_patch (&header); | ||
1735 | |||
1736 | case WF_ST_PROGRAM: | ||
1737 | if (copy_from_user(&header.hdr.pr, header.hdrptr, | ||
1738 | sizeof (wavefront_program))) | ||
1739 | return -EFAULT; | ||
1740 | |||
1741 | return wavefront_send_program (&header); | ||
1742 | |||
1743 | default: | ||
1744 | printk (KERN_ERR LOGNAME "unknown patch type %d.\n", | ||
1745 | header.subkey); | ||
1746 | return -(EINVAL); | ||
1747 | } | ||
1748 | |||
1749 | return 0; | ||
1750 | } | ||
1751 | |||
1752 | /*********************************************************************** | ||
1753 | WaveFront: /dev/sequencer{,2} and other hardware-dependent interfaces | ||
1754 | ***********************************************************************/ | ||
1755 | |||
1756 | static void | ||
1757 | process_sample_hdr (UCHAR8 *buf) | ||
1758 | |||
1759 | { | ||
1760 | wavefront_sample s; | ||
1761 | UCHAR8 *ptr; | ||
1762 | |||
1763 | ptr = buf; | ||
1764 | |||
1765 | /* The board doesn't send us an exact copy of a "wavefront_sample" | ||
1766 | in response to an Upload Sample Header command. Instead, we | ||
1767 | have to convert the data format back into our data structure, | ||
1768 | just as in the Download Sample command, where we have to do | ||
1769 | something very similar in the reverse direction. | ||
1770 | */ | ||
1771 | |||
1772 | *((UINT32 *) &s.sampleStartOffset) = demunge_int32 (ptr, 4); ptr += 4; | ||
1773 | *((UINT32 *) &s.loopStartOffset) = demunge_int32 (ptr, 4); ptr += 4; | ||
1774 | *((UINT32 *) &s.loopEndOffset) = demunge_int32 (ptr, 4); ptr += 4; | ||
1775 | *((UINT32 *) &s.sampleEndOffset) = demunge_int32 (ptr, 4); ptr += 4; | ||
1776 | *((UINT32 *) &s.FrequencyBias) = demunge_int32 (ptr, 3); ptr += 3; | ||
1777 | |||
1778 | s.SampleResolution = *ptr & 0x3; | ||
1779 | s.Loop = *ptr & 0x8; | ||
1780 | s.Bidirectional = *ptr & 0x10; | ||
1781 | s.Reverse = *ptr & 0x40; | ||
1782 | |||
1783 | /* Now copy it back to where it came from */ | ||
1784 | |||
1785 | memcpy (buf, (unsigned char *) &s, sizeof (wavefront_sample)); | ||
1786 | } | ||
1787 | |||
1788 | static int | ||
1789 | wavefront_synth_control (int cmd, wavefront_control *wc) | ||
1790 | |||
1791 | { | ||
1792 | unsigned char patchnumbuf[2]; | ||
1793 | int i; | ||
1794 | |||
1795 | DPRINT (WF_DEBUG_CMD, "synth control with " | ||
1796 | "cmd 0x%x\n", wc->cmd); | ||
1797 | |||
1798 | /* Pre-handling of or for various commands */ | ||
1799 | |||
1800 | switch (wc->cmd) { | ||
1801 | case WFC_DISABLE_INTERRUPTS: | ||
1802 | printk (KERN_INFO LOGNAME "interrupts disabled.\n"); | ||
1803 | outb (0x80|0x20, dev.control_port); | ||
1804 | dev.interrupts_on = 0; | ||
1805 | return 0; | ||
1806 | |||
1807 | case WFC_ENABLE_INTERRUPTS: | ||
1808 | printk (KERN_INFO LOGNAME "interrupts enabled.\n"); | ||
1809 | outb (0x80|0x40|0x20, dev.control_port); | ||
1810 | dev.interrupts_on = 1; | ||
1811 | return 0; | ||
1812 | |||
1813 | case WFC_INTERRUPT_STATUS: | ||
1814 | wc->rbuf[0] = dev.interrupts_on; | ||
1815 | return 0; | ||
1816 | |||
1817 | case WFC_ROMSAMPLES_RDONLY: | ||
1818 | dev.rom_samples_rdonly = wc->wbuf[0]; | ||
1819 | wc->status = 0; | ||
1820 | return 0; | ||
1821 | |||
1822 | case WFC_IDENTIFY_SLOT_TYPE: | ||
1823 | i = wc->wbuf[0] | (wc->wbuf[1] << 7); | ||
1824 | if (i <0 || i >= WF_MAX_SAMPLE) { | ||
1825 | printk (KERN_WARNING LOGNAME "invalid slot ID %d\n", | ||
1826 | i); | ||
1827 | wc->status = EINVAL; | ||
1828 | return 0; | ||
1829 | } | ||
1830 | wc->rbuf[0] = dev.sample_status[i]; | ||
1831 | wc->status = 0; | ||
1832 | return 0; | ||
1833 | |||
1834 | case WFC_DEBUG_DRIVER: | ||
1835 | dev.debug = wc->wbuf[0]; | ||
1836 | printk (KERN_INFO LOGNAME "debug = 0x%x\n", dev.debug); | ||
1837 | return 0; | ||
1838 | |||
1839 | case WFC_FX_IOCTL: | ||
1840 | wffx_ioctl ((wavefront_fx_info *) &wc->wbuf[0]); | ||
1841 | return 0; | ||
1842 | |||
1843 | case WFC_UPLOAD_PATCH: | ||
1844 | munge_int32 (*((UINT32 *) wc->wbuf), patchnumbuf, 2); | ||
1845 | memcpy (wc->wbuf, patchnumbuf, 2); | ||
1846 | break; | ||
1847 | |||
1848 | case WFC_UPLOAD_MULTISAMPLE: | ||
1849 | /* multisamples have to be handled differently, and | ||
1850 | cannot be dealt with properly by wavefront_cmd() alone. | ||
1851 | */ | ||
1852 | wc->status = wavefront_fetch_multisample | ||
1853 | ((wavefront_patch_info *) wc->rbuf); | ||
1854 | return 0; | ||
1855 | |||
1856 | case WFC_UPLOAD_SAMPLE_ALIAS: | ||
1857 | printk (KERN_INFO LOGNAME "support for sample alias upload " | ||
1858 | "being considered.\n"); | ||
1859 | wc->status = EINVAL; | ||
1860 | return -EINVAL; | ||
1861 | } | ||
1862 | |||
1863 | wc->status = wavefront_cmd (wc->cmd, wc->rbuf, wc->wbuf); | ||
1864 | |||
1865 | /* Post-handling of certain commands. | ||
1866 | |||
1867 | In particular, if the command was an upload, demunge the data | ||
1868 | so that the user-level doesn't have to think about it. | ||
1869 | */ | ||
1870 | |||
1871 | if (wc->status == 0) { | ||
1872 | switch (wc->cmd) { | ||
1873 | /* intercept any freemem requests so that we know | ||
1874 | we are always current with the user-level view | ||
1875 | of things. | ||
1876 | */ | ||
1877 | |||
1878 | case WFC_REPORT_FREE_MEMORY: | ||
1879 | dev.freemem = demunge_int32 (wc->rbuf, 4); | ||
1880 | break; | ||
1881 | |||
1882 | case WFC_UPLOAD_PATCH: | ||
1883 | demunge_buf (wc->rbuf, wc->rbuf, WF_PATCH_BYTES); | ||
1884 | break; | ||
1885 | |||
1886 | case WFC_UPLOAD_PROGRAM: | ||
1887 | demunge_buf (wc->rbuf, wc->rbuf, WF_PROGRAM_BYTES); | ||
1888 | break; | ||
1889 | |||
1890 | case WFC_UPLOAD_EDRUM_PROGRAM: | ||
1891 | demunge_buf (wc->rbuf, wc->rbuf, WF_DRUM_BYTES - 1); | ||
1892 | break; | ||
1893 | |||
1894 | case WFC_UPLOAD_SAMPLE_HEADER: | ||
1895 | process_sample_hdr (wc->rbuf); | ||
1896 | break; | ||
1897 | |||
1898 | case WFC_UPLOAD_SAMPLE_ALIAS: | ||
1899 | printk (KERN_INFO LOGNAME "support for " | ||
1900 | "sample aliases still " | ||
1901 | "being considered.\n"); | ||
1902 | break; | ||
1903 | |||
1904 | case WFC_VMIDI_OFF: | ||
1905 | if (virtual_midi_disable () < 0) { | ||
1906 | return -(EIO); | ||
1907 | } | ||
1908 | break; | ||
1909 | |||
1910 | case WFC_VMIDI_ON: | ||
1911 | if (virtual_midi_enable () < 0) { | ||
1912 | return -(EIO); | ||
1913 | } | ||
1914 | break; | ||
1915 | } | ||
1916 | } | ||
1917 | |||
1918 | return 0; | ||
1919 | } | ||
1920 | |||
1921 | |||
1922 | /***********************************************************************/ | ||
1923 | /* WaveFront: Linux file system interface (for access via raw synth) */ | ||
1924 | /***********************************************************************/ | ||
1925 | |||
1926 | static int | ||
1927 | wavefront_open (struct inode *inode, struct file *file) | ||
1928 | { | ||
1929 | /* XXX fix me */ | ||
1930 | dev.opened = file->f_flags; | ||
1931 | return 0; | ||
1932 | } | ||
1933 | |||
1934 | static int | ||
1935 | wavefront_release(struct inode *inode, struct file *file) | ||
1936 | { | ||
1937 | lock_kernel(); | ||
1938 | dev.opened = 0; | ||
1939 | dev.debug = 0; | ||
1940 | unlock_kernel(); | ||
1941 | return 0; | ||
1942 | } | ||
1943 | |||
1944 | static int | ||
1945 | wavefront_ioctl(struct inode *inode, struct file *file, | ||
1946 | unsigned int cmd, unsigned long arg) | ||
1947 | { | ||
1948 | wavefront_control wc; | ||
1949 | int err; | ||
1950 | |||
1951 | switch (cmd) { | ||
1952 | |||
1953 | case WFCTL_WFCMD: | ||
1954 | if (copy_from_user(&wc, (void __user *) arg, sizeof (wc))) | ||
1955 | return -EFAULT; | ||
1956 | |||
1957 | if ((err = wavefront_synth_control (cmd, &wc)) == 0) { | ||
1958 | if (copy_to_user ((void __user *) arg, &wc, sizeof (wc))) | ||
1959 | return -EFAULT; | ||
1960 | } | ||
1961 | |||
1962 | return err; | ||
1963 | |||
1964 | case WFCTL_LOAD_SPP: | ||
1965 | return wavefront_load_patch ((const char __user *) arg); | ||
1966 | |||
1967 | default: | ||
1968 | printk (KERN_WARNING LOGNAME "invalid ioctl %#x\n", cmd); | ||
1969 | return -(EINVAL); | ||
1970 | |||
1971 | } | ||
1972 | return 0; | ||
1973 | } | ||
1974 | |||
1975 | static /*const*/ struct file_operations wavefront_fops = { | ||
1976 | .owner = THIS_MODULE, | ||
1977 | .llseek = no_llseek, | ||
1978 | .ioctl = wavefront_ioctl, | ||
1979 | .open = wavefront_open, | ||
1980 | .release = wavefront_release, | ||
1981 | }; | ||
1982 | |||
1983 | |||
1984 | /***********************************************************************/ | ||
1985 | /* WaveFront: OSS installation and support interface */ | ||
1986 | /***********************************************************************/ | ||
1987 | |||
1988 | #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ | ||
1989 | |||
1990 | static struct synth_info wavefront_info = | ||
1991 | {"Turtle Beach WaveFront", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_WAVEFRONT, | ||
1992 | 0, 32, 0, 0, SYNTH_CAP_INPUT}; | ||
1993 | |||
1994 | static int | ||
1995 | wavefront_oss_open (int devno, int mode) | ||
1996 | |||
1997 | { | ||
1998 | dev.opened = mode; | ||
1999 | return 0; | ||
2000 | } | ||
2001 | |||
2002 | static void | ||
2003 | wavefront_oss_close (int devno) | ||
2004 | |||
2005 | { | ||
2006 | dev.opened = 0; | ||
2007 | dev.debug = 0; | ||
2008 | return; | ||
2009 | } | ||
2010 | |||
2011 | static int | ||
2012 | wavefront_oss_ioctl (int devno, unsigned int cmd, void __user * arg) | ||
2013 | |||
2014 | { | ||
2015 | wavefront_control wc; | ||
2016 | int err; | ||
2017 | |||
2018 | switch (cmd) { | ||
2019 | case SNDCTL_SYNTH_INFO: | ||
2020 | if(copy_to_user(arg, &wavefront_info, sizeof (wavefront_info))) | ||
2021 | return -EFAULT; | ||
2022 | return 0; | ||
2023 | |||
2024 | case SNDCTL_SEQ_RESETSAMPLES: | ||
2025 | // printk (KERN_WARNING LOGNAME "driver cannot reset samples.\n"); | ||
2026 | return 0; /* don't force an error */ | ||
2027 | |||
2028 | case SNDCTL_SEQ_PERCMODE: | ||
2029 | return 0; /* don't force an error */ | ||
2030 | |||
2031 | case SNDCTL_SYNTH_MEMAVL: | ||
2032 | if ((dev.freemem = wavefront_freemem ()) < 0) { | ||
2033 | printk (KERN_ERR LOGNAME "cannot get memory size\n"); | ||
2034 | return -EIO; | ||
2035 | } else { | ||
2036 | return dev.freemem; | ||
2037 | } | ||
2038 | break; | ||
2039 | |||
2040 | case SNDCTL_SYNTH_CONTROL: | ||
2041 | if(copy_from_user (&wc, arg, sizeof (wc))) | ||
2042 | err = -EFAULT; | ||
2043 | else if ((err = wavefront_synth_control (cmd, &wc)) == 0) { | ||
2044 | if(copy_to_user (arg, &wc, sizeof (wc))) | ||
2045 | err = -EFAULT; | ||
2046 | } | ||
2047 | |||
2048 | return err; | ||
2049 | |||
2050 | default: | ||
2051 | return -(EINVAL); | ||
2052 | } | ||
2053 | } | ||
2054 | |||
2055 | static int | ||
2056 | wavefront_oss_load_patch (int devno, int format, const char __user *addr, | ||
2057 | int offs, int count, int pmgr_flag) | ||
2058 | { | ||
2059 | |||
2060 | if (format == SYSEX_PATCH) { /* Handled by midi_synth.c */ | ||
2061 | if (midi_load_patch == NULL) { | ||
2062 | printk (KERN_ERR LOGNAME | ||
2063 | "SYSEX not loadable: " | ||
2064 | "no midi patch loader!\n"); | ||
2065 | return -(EINVAL); | ||
2066 | } | ||
2067 | |||
2068 | return midi_load_patch (devno, format, addr, | ||
2069 | offs, count, pmgr_flag); | ||
2070 | |||
2071 | } else if (format == GUS_PATCH) { | ||
2072 | return wavefront_load_gus_patch (devno, format, | ||
2073 | addr, offs, count, pmgr_flag); | ||
2074 | |||
2075 | } else if (format != WAVEFRONT_PATCH) { | ||
2076 | printk (KERN_ERR LOGNAME "unknown patch format %d\n", format); | ||
2077 | return -(EINVAL); | ||
2078 | } | ||
2079 | |||
2080 | if (count < sizeof (wavefront_patch_info)) { | ||
2081 | printk (KERN_ERR LOGNAME "sample header too short\n"); | ||
2082 | return -(EINVAL); | ||
2083 | } | ||
2084 | |||
2085 | /* "addr" points to a user-space wavefront_patch_info */ | ||
2086 | |||
2087 | return wavefront_load_patch (addr); | ||
2088 | } | ||
2089 | |||
2090 | static struct synth_operations wavefront_operations = | ||
2091 | { | ||
2092 | .owner = THIS_MODULE, | ||
2093 | .id = "WaveFront", | ||
2094 | .info = &wavefront_info, | ||
2095 | .midi_dev = 0, | ||
2096 | .synth_type = SYNTH_TYPE_SAMPLE, | ||
2097 | .synth_subtype = SAMPLE_TYPE_WAVEFRONT, | ||
2098 | .open = wavefront_oss_open, | ||
2099 | .close = wavefront_oss_close, | ||
2100 | .ioctl = wavefront_oss_ioctl, | ||
2101 | .kill_note = midi_synth_kill_note, | ||
2102 | .start_note = midi_synth_start_note, | ||
2103 | .set_instr = midi_synth_set_instr, | ||
2104 | .reset = midi_synth_reset, | ||
2105 | .load_patch = midi_synth_load_patch, | ||
2106 | .aftertouch = midi_synth_aftertouch, | ||
2107 | .controller = midi_synth_controller, | ||
2108 | .panning = midi_synth_panning, | ||
2109 | .bender = midi_synth_bender, | ||
2110 | .setup_voice = midi_synth_setup_voice | ||
2111 | }; | ||
2112 | #endif /* OSS_SUPPORT_SEQ */ | ||
2113 | |||
2114 | #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_STATIC_INSTALL | ||
2115 | |||
2116 | static void __init attach_wavefront (struct address_info *hw_config) | ||
2117 | { | ||
2118 | (void) install_wavefront (); | ||
2119 | } | ||
2120 | |||
2121 | static int __init probe_wavefront (struct address_info *hw_config) | ||
2122 | { | ||
2123 | return !detect_wavefront (hw_config->irq, hw_config->io_base); | ||
2124 | } | ||
2125 | |||
2126 | static void __exit unload_wavefront (struct address_info *hw_config) | ||
2127 | { | ||
2128 | (void) uninstall_wavefront (); | ||
2129 | } | ||
2130 | |||
2131 | #endif /* OSS_SUPPORT_STATIC_INSTALL */ | ||
2132 | |||
2133 | /***********************************************************************/ | ||
2134 | /* WaveFront: Linux modular sound kernel installation interface */ | ||
2135 | /***********************************************************************/ | ||
2136 | |||
2137 | static irqreturn_t | ||
2138 | wavefrontintr(int irq, void *dev_id, struct pt_regs *dummy) | ||
2139 | { | ||
2140 | struct wf_config *hw = dev_id; | ||
2141 | |||
2142 | /* | ||
2143 | Some comments on interrupts. I attempted a version of this | ||
2144 | driver that used interrupts throughout the code instead of | ||
2145 | doing busy and/or sleep-waiting. Alas, it appears that once | ||
2146 | the Motorola firmware is downloaded, the card *never* | ||
2147 | generates an RX interrupt. These are successfully generated | ||
2148 | during firmware loading, and after that wavefront_status() | ||
2149 | reports that an interrupt is pending on the card from time | ||
2150 | to time, but it never seems to be delivered to this | ||
2151 | driver. Note also that wavefront_status() continues to | ||
2152 | report that RX interrupts are enabled, suggesting that I | ||
2153 | didn't goof up and disable them by mistake. | ||
2154 | |||
2155 | Thus, I stepped back to a prior version of | ||
2156 | wavefront_wait(), the only place where this really | ||
2157 | matters. Its sad, but I've looked through the code to check | ||
2158 | on things, and I really feel certain that the Motorola | ||
2159 | firmware prevents RX-ready interrupts. | ||
2160 | */ | ||
2161 | |||
2162 | if ((wavefront_status() & (STAT_INTR_READ|STAT_INTR_WRITE)) == 0) { | ||
2163 | return IRQ_NONE; | ||
2164 | } | ||
2165 | |||
2166 | hw->irq_ok = 1; | ||
2167 | hw->irq_cnt++; | ||
2168 | wake_up_interruptible (&hw->interrupt_sleeper); | ||
2169 | return IRQ_HANDLED; | ||
2170 | } | ||
2171 | |||
2172 | /* STATUS REGISTER | ||
2173 | |||
2174 | 0 Host Rx Interrupt Enable (1=Enabled) | ||
2175 | 1 Host Rx Register Full (1=Full) | ||
2176 | 2 Host Rx Interrupt Pending (1=Interrupt) | ||
2177 | 3 Unused | ||
2178 | 4 Host Tx Interrupt (1=Enabled) | ||
2179 | 5 Host Tx Register empty (1=Empty) | ||
2180 | 6 Host Tx Interrupt Pending (1=Interrupt) | ||
2181 | 7 Unused | ||
2182 | */ | ||
2183 | |||
2184 | static int | ||
2185 | wavefront_interrupt_bits (int irq) | ||
2186 | |||
2187 | { | ||
2188 | int bits; | ||
2189 | |||
2190 | switch (irq) { | ||
2191 | case 9: | ||
2192 | bits = 0x00; | ||
2193 | break; | ||
2194 | case 5: | ||
2195 | bits = 0x08; | ||
2196 | break; | ||
2197 | case 12: | ||
2198 | bits = 0x10; | ||
2199 | break; | ||
2200 | case 15: | ||
2201 | bits = 0x18; | ||
2202 | break; | ||
2203 | |||
2204 | default: | ||
2205 | printk (KERN_WARNING LOGNAME "invalid IRQ %d\n", irq); | ||
2206 | bits = -1; | ||
2207 | } | ||
2208 | |||
2209 | return bits; | ||
2210 | } | ||
2211 | |||
2212 | static void | ||
2213 | wavefront_should_cause_interrupt (int val, int port, int timeout) | ||
2214 | |||
2215 | { | ||
2216 | unsigned long flags; | ||
2217 | |||
2218 | /* this will not help on SMP - but at least it compiles */ | ||
2219 | spin_lock_irqsave(&lock, flags); | ||
2220 | dev.irq_ok = 0; | ||
2221 | outb (val,port); | ||
2222 | interruptible_sleep_on_timeout (&dev.interrupt_sleeper, timeout); | ||
2223 | spin_unlock_irqrestore(&lock,flags); | ||
2224 | } | ||
2225 | |||
2226 | static int __init wavefront_hw_reset (void) | ||
2227 | { | ||
2228 | int bits; | ||
2229 | int hwv[2]; | ||
2230 | unsigned long irq_mask; | ||
2231 | short reported_irq; | ||
2232 | |||
2233 | /* IRQ already checked in init_module() */ | ||
2234 | |||
2235 | bits = wavefront_interrupt_bits (dev.irq); | ||
2236 | |||
2237 | printk (KERN_DEBUG LOGNAME "autodetecting WaveFront IRQ\n"); | ||
2238 | |||
2239 | irq_mask = probe_irq_on (); | ||
2240 | |||
2241 | outb (0x0, dev.control_port); | ||
2242 | outb (0x80 | 0x40 | bits, dev.data_port); | ||
2243 | wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1, | ||
2244 | dev.control_port, | ||
2245 | (reset_time*HZ)/100); | ||
2246 | |||
2247 | reported_irq = probe_irq_off (irq_mask); | ||
2248 | |||
2249 | if (reported_irq != dev.irq) { | ||
2250 | if (reported_irq == 0) { | ||
2251 | printk (KERN_ERR LOGNAME | ||
2252 | "No unassigned interrupts detected " | ||
2253 | "after h/w reset\n"); | ||
2254 | } else if (reported_irq < 0) { | ||
2255 | printk (KERN_ERR LOGNAME | ||
2256 | "Multiple unassigned interrupts detected " | ||
2257 | "after h/w reset\n"); | ||
2258 | } else { | ||
2259 | printk (KERN_ERR LOGNAME "autodetected IRQ %d not the " | ||
2260 | "value provided (%d)\n", reported_irq, | ||
2261 | dev.irq); | ||
2262 | } | ||
2263 | dev.irq = -1; | ||
2264 | return 1; | ||
2265 | } else { | ||
2266 | printk (KERN_INFO LOGNAME "autodetected IRQ at %d\n", | ||
2267 | reported_irq); | ||
2268 | } | ||
2269 | |||
2270 | if (request_irq (dev.irq, wavefrontintr, | ||
2271 | IRQF_DISABLED|IRQF_SHARED, | ||
2272 | "wavefront synth", &dev) < 0) { | ||
2273 | printk (KERN_WARNING LOGNAME "IRQ %d not available!\n", | ||
2274 | dev.irq); | ||
2275 | return 1; | ||
2276 | } | ||
2277 | |||
2278 | /* try reset of port */ | ||
2279 | |||
2280 | outb (0x0, dev.control_port); | ||
2281 | |||
2282 | /* At this point, the board is in reset, and the H/W initialization | ||
2283 | register is accessed at the same address as the data port. | ||
2284 | |||
2285 | Bit 7 - Enable IRQ Driver | ||
2286 | 0 - Tri-state the Wave-Board drivers for the PC Bus IRQs | ||
2287 | 1 - Enable IRQ selected by bits 5:3 to be driven onto the PC Bus. | ||
2288 | |||
2289 | Bit 6 - MIDI Interface Select | ||
2290 | |||
2291 | 0 - Use the MIDI Input from the 26-pin WaveBlaster | ||
2292 | compatible header as the serial MIDI source | ||
2293 | 1 - Use the MIDI Input from the 9-pin D connector as the | ||
2294 | serial MIDI source. | ||
2295 | |||
2296 | Bits 5:3 - IRQ Selection | ||
2297 | 0 0 0 - IRQ 2/9 | ||
2298 | 0 0 1 - IRQ 5 | ||
2299 | 0 1 0 - IRQ 12 | ||
2300 | 0 1 1 - IRQ 15 | ||
2301 | 1 0 0 - Reserved | ||
2302 | 1 0 1 - Reserved | ||
2303 | 1 1 0 - Reserved | ||
2304 | 1 1 1 - Reserved | ||
2305 | |||
2306 | Bits 2:1 - Reserved | ||
2307 | Bit 0 - Disable Boot ROM | ||
2308 | 0 - memory accesses to 03FC30-03FFFFH utilize the internal Boot ROM | ||
2309 | 1 - memory accesses to 03FC30-03FFFFH are directed to external | ||
2310 | storage. | ||
2311 | |||
2312 | */ | ||
2313 | |||
2314 | /* configure hardware: IRQ, enable interrupts, | ||
2315 | plus external 9-pin MIDI interface selected | ||
2316 | */ | ||
2317 | |||
2318 | outb (0x80 | 0x40 | bits, dev.data_port); | ||
2319 | |||
2320 | /* CONTROL REGISTER | ||
2321 | |||
2322 | 0 Host Rx Interrupt Enable (1=Enabled) 0x1 | ||
2323 | 1 Unused 0x2 | ||
2324 | 2 Unused 0x4 | ||
2325 | 3 Unused 0x8 | ||
2326 | 4 Host Tx Interrupt Enable 0x10 | ||
2327 | 5 Mute (0=Mute; 1=Play) 0x20 | ||
2328 | 6 Master Interrupt Enable (1=Enabled) 0x40 | ||
2329 | 7 Master Reset (0=Reset; 1=Run) 0x80 | ||
2330 | |||
2331 | Take us out of reset, mute output, master + TX + RX interrupts on. | ||
2332 | |||
2333 | We'll get an interrupt presumably to tell us that the TX | ||
2334 | register is clear. | ||
2335 | */ | ||
2336 | |||
2337 | wavefront_should_cause_interrupt(0x80|0x40|0x10|0x1, | ||
2338 | dev.control_port, | ||
2339 | (reset_time*HZ)/100); | ||
2340 | |||
2341 | /* Note: data port is now the data port, not the h/w initialization | ||
2342 | port. | ||
2343 | */ | ||
2344 | |||
2345 | if (!dev.irq_ok) { | ||
2346 | printk (KERN_WARNING LOGNAME | ||
2347 | "intr not received after h/w un-reset.\n"); | ||
2348 | goto gone_bad; | ||
2349 | } | ||
2350 | |||
2351 | dev.interrupts_on = 1; | ||
2352 | |||
2353 | /* Note: data port is now the data port, not the h/w initialization | ||
2354 | port. | ||
2355 | |||
2356 | At this point, only "HW VERSION" or "DOWNLOAD OS" commands | ||
2357 | will work. So, issue one of them, and wait for TX | ||
2358 | interrupt. This can take a *long* time after a cold boot, | ||
2359 | while the ISC ROM does its RAM test. The SDK says up to 4 | ||
2360 | seconds - with 12MB of RAM on a Tropez+, it takes a lot | ||
2361 | longer than that (~16secs). Note that the card understands | ||
2362 | the difference between a warm and a cold boot, so | ||
2363 | subsequent ISC2115 reboots (say, caused by module | ||
2364 | reloading) will get through this much faster. | ||
2365 | |||
2366 | XXX Interesting question: why is no RX interrupt received first ? | ||
2367 | */ | ||
2368 | |||
2369 | wavefront_should_cause_interrupt(WFC_HARDWARE_VERSION, | ||
2370 | dev.data_port, ramcheck_time*HZ); | ||
2371 | |||
2372 | if (!dev.irq_ok) { | ||
2373 | printk (KERN_WARNING LOGNAME | ||
2374 | "post-RAM-check interrupt not received.\n"); | ||
2375 | goto gone_bad; | ||
2376 | } | ||
2377 | |||
2378 | if (!wavefront_wait (STAT_CAN_READ)) { | ||
2379 | printk (KERN_WARNING LOGNAME | ||
2380 | "no response to HW version cmd.\n"); | ||
2381 | goto gone_bad; | ||
2382 | } | ||
2383 | |||
2384 | if ((hwv[0] = wavefront_read ()) == -1) { | ||
2385 | printk (KERN_WARNING LOGNAME | ||
2386 | "board not responding correctly.\n"); | ||
2387 | goto gone_bad; | ||
2388 | } | ||
2389 | |||
2390 | if (hwv[0] == 0xFF) { /* NAK */ | ||
2391 | |||
2392 | /* Board's RAM test failed. Try to read error code, | ||
2393 | and tell us about it either way. | ||
2394 | */ | ||
2395 | |||
2396 | if ((hwv[0] = wavefront_read ()) == -1) { | ||
2397 | printk (KERN_WARNING LOGNAME "on-board RAM test failed " | ||
2398 | "(bad error code).\n"); | ||
2399 | } else { | ||
2400 | printk (KERN_WARNING LOGNAME "on-board RAM test failed " | ||
2401 | "(error code: 0x%x).\n", | ||
2402 | hwv[0]); | ||
2403 | } | ||
2404 | goto gone_bad; | ||
2405 | } | ||
2406 | |||
2407 | /* We're OK, just get the next byte of the HW version response */ | ||
2408 | |||
2409 | if ((hwv[1] = wavefront_read ()) == -1) { | ||
2410 | printk (KERN_WARNING LOGNAME "incorrect h/w response.\n"); | ||
2411 | goto gone_bad; | ||
2412 | } | ||
2413 | |||
2414 | printk (KERN_INFO LOGNAME "hardware version %d.%d\n", | ||
2415 | hwv[0], hwv[1]); | ||
2416 | |||
2417 | return 0; | ||
2418 | |||
2419 | |||
2420 | gone_bad: | ||
2421 | if (dev.irq >= 0) { | ||
2422 | free_irq (dev.irq, &dev); | ||
2423 | dev.irq = -1; | ||
2424 | } | ||
2425 | return (1); | ||
2426 | } | ||
2427 | |||
2428 | static int __init detect_wavefront (int irq, int io_base) | ||
2429 | { | ||
2430 | unsigned char rbuf[4], wbuf[4]; | ||
2431 | |||
2432 | /* TB docs say the device takes up 8 ports, but we know that | ||
2433 | if there is an FX device present (i.e. a Tropez+) it really | ||
2434 | consumes 16. | ||
2435 | */ | ||
2436 | |||
2437 | if (!request_region (io_base, 16, "wavfront")) { | ||
2438 | printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x " | ||
2439 | "already in use - ignored\n", dev.base, | ||
2440 | dev.base+15); | ||
2441 | return -1; | ||
2442 | } | ||
2443 | |||
2444 | dev.irq = irq; | ||
2445 | dev.base = io_base; | ||
2446 | dev.israw = 0; | ||
2447 | dev.debug = debug_default; | ||
2448 | dev.interrupts_on = 0; | ||
2449 | dev.irq_cnt = 0; | ||
2450 | dev.rom_samples_rdonly = 1; /* XXX default lock on ROM sample slots */ | ||
2451 | |||
2452 | if (wavefront_cmd (WFC_FIRMWARE_VERSION, rbuf, wbuf) == 0) { | ||
2453 | |||
2454 | dev.fw_version[0] = rbuf[0]; | ||
2455 | dev.fw_version[1] = rbuf[1]; | ||
2456 | printk (KERN_INFO LOGNAME | ||
2457 | "firmware %d.%d already loaded.\n", | ||
2458 | rbuf[0], rbuf[1]); | ||
2459 | |||
2460 | /* check that a command actually works */ | ||
2461 | |||
2462 | if (wavefront_cmd (WFC_HARDWARE_VERSION, | ||
2463 | rbuf, wbuf) == 0) { | ||
2464 | dev.hw_version[0] = rbuf[0]; | ||
2465 | dev.hw_version[1] = rbuf[1]; | ||
2466 | } else { | ||
2467 | printk (KERN_WARNING LOGNAME "not raw, but no " | ||
2468 | "hardware version!\n"); | ||
2469 | release_region (io_base, 16); | ||
2470 | return 0; | ||
2471 | } | ||
2472 | |||
2473 | if (!wf_raw) { | ||
2474 | /* will re-acquire region in install_wavefront() */ | ||
2475 | release_region (io_base, 16); | ||
2476 | return 1; | ||
2477 | } else { | ||
2478 | printk (KERN_INFO LOGNAME | ||
2479 | "reloading firmware anyway.\n"); | ||
2480 | dev.israw = 1; | ||
2481 | } | ||
2482 | |||
2483 | } else { | ||
2484 | |||
2485 | dev.israw = 1; | ||
2486 | printk (KERN_INFO LOGNAME | ||
2487 | "no response to firmware probe, assume raw.\n"); | ||
2488 | |||
2489 | } | ||
2490 | |||
2491 | init_waitqueue_head (&dev.interrupt_sleeper); | ||
2492 | |||
2493 | if (wavefront_hw_reset ()) { | ||
2494 | printk (KERN_WARNING LOGNAME "hardware reset failed\n"); | ||
2495 | release_region (io_base, 16); | ||
2496 | return 0; | ||
2497 | } | ||
2498 | |||
2499 | /* Check for FX device, present only on Tropez+ */ | ||
2500 | |||
2501 | dev.has_fx = (detect_wffx () == 0); | ||
2502 | |||
2503 | /* will re-acquire region in install_wavefront() */ | ||
2504 | release_region (io_base, 16); | ||
2505 | return 1; | ||
2506 | } | ||
2507 | |||
2508 | #include "os.h" | ||
2509 | #include <linux/fs.h> | ||
2510 | #include <linux/mm.h> | ||
2511 | #include <linux/slab.h> | ||
2512 | #include <asm/uaccess.h> | ||
2513 | |||
2514 | |||
2515 | static int | ||
2516 | wavefront_download_firmware (char *path) | ||
2517 | |||
2518 | { | ||
2519 | unsigned char section[WF_SECTION_MAX]; | ||
2520 | char section_length; /* yes, just a char; max value is WF_SECTION_MAX */ | ||
2521 | int section_cnt_downloaded = 0; | ||
2522 | int fd; | ||
2523 | int c; | ||
2524 | int i; | ||
2525 | mm_segment_t fs; | ||
2526 | |||
2527 | /* This tries to be a bit cleverer than the stuff Alan Cox did for | ||
2528 | the generic sound firmware, in that it actually knows | ||
2529 | something about the structure of the Motorola firmware. In | ||
2530 | particular, it uses a version that has been stripped of the | ||
2531 | 20K of useless header information, and had section lengths | ||
2532 | added, making it possible to load the entire OS without any | ||
2533 | [kv]malloc() activity, since the longest entity we ever read is | ||
2534 | 42 bytes (well, WF_SECTION_MAX) long. | ||
2535 | */ | ||
2536 | |||
2537 | fs = get_fs(); | ||
2538 | set_fs (get_ds()); | ||
2539 | |||
2540 | if ((fd = sys_open (path, 0, 0)) < 0) { | ||
2541 | printk (KERN_WARNING LOGNAME "Unable to load \"%s\".\n", | ||
2542 | path); | ||
2543 | return 1; | ||
2544 | } | ||
2545 | |||
2546 | while (1) { | ||
2547 | int x; | ||
2548 | |||
2549 | if ((x = sys_read (fd, §ion_length, sizeof (section_length))) != | ||
2550 | sizeof (section_length)) { | ||
2551 | printk (KERN_ERR LOGNAME "firmware read error.\n"); | ||
2552 | goto failure; | ||
2553 | } | ||
2554 | |||
2555 | if (section_length == 0) { | ||
2556 | break; | ||
2557 | } | ||
2558 | |||
2559 | if (sys_read (fd, section, section_length) != section_length) { | ||
2560 | printk (KERN_ERR LOGNAME "firmware section " | ||
2561 | "read error.\n"); | ||
2562 | goto failure; | ||
2563 | } | ||
2564 | |||
2565 | /* Send command */ | ||
2566 | |||
2567 | if (wavefront_write (WFC_DOWNLOAD_OS)) { | ||
2568 | goto failure; | ||
2569 | } | ||
2570 | |||
2571 | for (i = 0; i < section_length; i++) { | ||
2572 | if (wavefront_write (section[i])) { | ||
2573 | goto failure; | ||
2574 | } | ||
2575 | } | ||
2576 | |||
2577 | /* get ACK */ | ||
2578 | |||
2579 | if (wavefront_wait (STAT_CAN_READ)) { | ||
2580 | |||
2581 | if ((c = inb (dev.data_port)) != WF_ACK) { | ||
2582 | |||
2583 | printk (KERN_ERR LOGNAME "download " | ||
2584 | "of section #%d not " | ||
2585 | "acknowledged, ack = 0x%x\n", | ||
2586 | section_cnt_downloaded + 1, c); | ||
2587 | goto failure; | ||
2588 | |||
2589 | } | ||
2590 | |||
2591 | } else { | ||
2592 | printk (KERN_ERR LOGNAME "time out for firmware ACK.\n"); | ||
2593 | goto failure; | ||
2594 | } | ||
2595 | |||
2596 | } | ||
2597 | |||
2598 | sys_close (fd); | ||
2599 | set_fs (fs); | ||
2600 | return 0; | ||
2601 | |||
2602 | failure: | ||
2603 | sys_close (fd); | ||
2604 | set_fs (fs); | ||
2605 | printk (KERN_ERR "\nWaveFront: firmware download failed!!!\n"); | ||
2606 | return 1; | ||
2607 | } | ||
2608 | |||
2609 | static int __init wavefront_config_midi (void) | ||
2610 | { | ||
2611 | unsigned char rbuf[4], wbuf[4]; | ||
2612 | |||
2613 | if (detect_wf_mpu (dev.irq, dev.base) < 0) { | ||
2614 | printk (KERN_WARNING LOGNAME | ||
2615 | "could not find working MIDI device\n"); | ||
2616 | return -1; | ||
2617 | } | ||
2618 | |||
2619 | if ((dev.mididev = install_wf_mpu ()) < 0) { | ||
2620 | printk (KERN_WARNING LOGNAME | ||
2621 | "MIDI interfaces not configured\n"); | ||
2622 | return -1; | ||
2623 | } | ||
2624 | |||
2625 | /* Route external MIDI to WaveFront synth (by default) */ | ||
2626 | |||
2627 | if (wavefront_cmd (WFC_MISYNTH_ON, rbuf, wbuf)) { | ||
2628 | printk (KERN_WARNING LOGNAME | ||
2629 | "cannot enable MIDI-IN to synth routing.\n"); | ||
2630 | /* XXX error ? */ | ||
2631 | } | ||
2632 | |||
2633 | |||
2634 | #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ | ||
2635 | /* Get the regular MIDI patch loading function, so we can | ||
2636 | use it if we ever get handed a SYSEX patch. This is | ||
2637 | unlikely, because its so damn slow, but we may as well | ||
2638 | leave this functionality from maui.c behind, since it | ||
2639 | could be useful for sequencer applications that can | ||
2640 | only use MIDI to do patch loading. | ||
2641 | */ | ||
2642 | |||
2643 | if (midi_devs[dev.mididev]->converter != NULL) { | ||
2644 | midi_load_patch = midi_devs[dev.mididev]->converter->load_patch; | ||
2645 | midi_devs[dev.mididev]->converter->load_patch = | ||
2646 | &wavefront_oss_load_patch; | ||
2647 | } | ||
2648 | |||
2649 | #endif /* OSS_SUPPORT_SEQ */ | ||
2650 | |||
2651 | /* Turn on Virtual MIDI, but first *always* turn it off, | ||
2652 | since otherwise consectutive reloads of the driver will | ||
2653 | never cause the hardware to generate the initial "internal" or | ||
2654 | "external" source bytes in the MIDI data stream. This | ||
2655 | is pretty important, since the internal hardware generally will | ||
2656 | be used to generate none or very little MIDI output, and | ||
2657 | thus the only source of MIDI data is actually external. Without | ||
2658 | the switch bytes, the driver will think it all comes from | ||
2659 | the internal interface. Duh. | ||
2660 | */ | ||
2661 | |||
2662 | if (wavefront_cmd (WFC_VMIDI_OFF, rbuf, wbuf)) { | ||
2663 | printk (KERN_WARNING LOGNAME | ||
2664 | "virtual MIDI mode not disabled\n"); | ||
2665 | return 0; /* We're OK, but missing the external MIDI dev */ | ||
2666 | } | ||
2667 | |||
2668 | if ((dev.ext_mididev = virtual_midi_enable ()) < 0) { | ||
2669 | printk (KERN_WARNING LOGNAME "no virtual MIDI access.\n"); | ||
2670 | } else { | ||
2671 | if (wavefront_cmd (WFC_VMIDI_ON, rbuf, wbuf)) { | ||
2672 | printk (KERN_WARNING LOGNAME | ||
2673 | "cannot enable virtual MIDI mode.\n"); | ||
2674 | virtual_midi_disable (); | ||
2675 | } | ||
2676 | } | ||
2677 | |||
2678 | return 0; | ||
2679 | } | ||
2680 | |||
2681 | static int __init wavefront_do_reset (int atboot) | ||
2682 | { | ||
2683 | char voices[1]; | ||
2684 | |||
2685 | if (!atboot && wavefront_hw_reset ()) { | ||
2686 | printk (KERN_WARNING LOGNAME "hw reset failed.\n"); | ||
2687 | goto gone_bad; | ||
2688 | } | ||
2689 | |||
2690 | if (dev.israw) { | ||
2691 | if (wavefront_download_firmware (ospath)) { | ||
2692 | goto gone_bad; | ||
2693 | } | ||
2694 | |||
2695 | dev.israw = 0; | ||
2696 | |||
2697 | /* Wait for the OS to get running. The protocol for | ||
2698 | this is non-obvious, and was determined by | ||
2699 | using port-IO tracing in DOSemu and some | ||
2700 | experimentation here. | ||
2701 | |||
2702 | Rather than using timed waits, use interrupts creatively. | ||
2703 | */ | ||
2704 | |||
2705 | wavefront_should_cause_interrupt (WFC_NOOP, | ||
2706 | dev.data_port, | ||
2707 | (osrun_time*HZ)); | ||
2708 | |||
2709 | if (!dev.irq_ok) { | ||
2710 | printk (KERN_WARNING LOGNAME | ||
2711 | "no post-OS interrupt.\n"); | ||
2712 | goto gone_bad; | ||
2713 | } | ||
2714 | |||
2715 | /* Now, do it again ! */ | ||
2716 | |||
2717 | wavefront_should_cause_interrupt (WFC_NOOP, | ||
2718 | dev.data_port, (10*HZ)); | ||
2719 | |||
2720 | if (!dev.irq_ok) { | ||
2721 | printk (KERN_WARNING LOGNAME | ||
2722 | "no post-OS interrupt(2).\n"); | ||
2723 | goto gone_bad; | ||
2724 | } | ||
2725 | |||
2726 | /* OK, no (RX/TX) interrupts any more, but leave mute | ||
2727 | in effect. | ||
2728 | */ | ||
2729 | |||
2730 | outb (0x80|0x40, dev.control_port); | ||
2731 | |||
2732 | /* No need for the IRQ anymore */ | ||
2733 | |||
2734 | free_irq (dev.irq, &dev); | ||
2735 | |||
2736 | } | ||
2737 | |||
2738 | if (dev.has_fx && fx_raw) { | ||
2739 | wffx_init (); | ||
2740 | } | ||
2741 | |||
2742 | /* SETUPSND.EXE asks for sample memory config here, but since i | ||
2743 | have no idea how to interpret the result, we'll forget | ||
2744 | about it. | ||
2745 | */ | ||
2746 | |||
2747 | if ((dev.freemem = wavefront_freemem ()) < 0) { | ||
2748 | goto gone_bad; | ||
2749 | } | ||
2750 | |||
2751 | printk (KERN_INFO LOGNAME "available DRAM %dk\n", dev.freemem / 1024); | ||
2752 | |||
2753 | if (wavefront_write (0xf0) || | ||
2754 | wavefront_write (1) || | ||
2755 | (wavefront_read () < 0)) { | ||
2756 | dev.debug = 0; | ||
2757 | printk (KERN_WARNING LOGNAME "MPU emulation mode not set.\n"); | ||
2758 | goto gone_bad; | ||
2759 | } | ||
2760 | |||
2761 | voices[0] = 32; | ||
2762 | |||
2763 | if (wavefront_cmd (WFC_SET_NVOICES, NULL, voices)) { | ||
2764 | printk (KERN_WARNING LOGNAME | ||
2765 | "cannot set number of voices to 32.\n"); | ||
2766 | goto gone_bad; | ||
2767 | } | ||
2768 | |||
2769 | |||
2770 | return 0; | ||
2771 | |||
2772 | gone_bad: | ||
2773 | /* reset that sucker so that it doesn't bother us. */ | ||
2774 | |||
2775 | outb (0x0, dev.control_port); | ||
2776 | dev.interrupts_on = 0; | ||
2777 | if (dev.irq >= 0) { | ||
2778 | free_irq (dev.irq, &dev); | ||
2779 | } | ||
2780 | return 1; | ||
2781 | } | ||
2782 | |||
2783 | static int __init wavefront_init (int atboot) | ||
2784 | { | ||
2785 | int samples_are_from_rom; | ||
2786 | |||
2787 | if (dev.israw) { | ||
2788 | samples_are_from_rom = 1; | ||
2789 | } else { | ||
2790 | /* XXX is this always true ? */ | ||
2791 | samples_are_from_rom = 0; | ||
2792 | } | ||
2793 | |||
2794 | if (dev.israw || fx_raw) { | ||
2795 | if (wavefront_do_reset (atboot)) { | ||
2796 | return -1; | ||
2797 | } | ||
2798 | } | ||
2799 | |||
2800 | wavefront_get_sample_status (samples_are_from_rom); | ||
2801 | wavefront_get_program_status (); | ||
2802 | wavefront_get_patch_status (); | ||
2803 | |||
2804 | /* Start normal operation: unreset, master interrupt enabled, no mute | ||
2805 | */ | ||
2806 | |||
2807 | outb (0x80|0x40|0x20, dev.control_port); | ||
2808 | |||
2809 | return (0); | ||
2810 | } | ||
2811 | |||
2812 | static int __init install_wavefront (void) | ||
2813 | { | ||
2814 | if (!request_region (dev.base+2, 6, "wavefront synth")) | ||
2815 | return -1; | ||
2816 | |||
2817 | if (dev.has_fx) { | ||
2818 | if (!request_region (dev.base+8, 8, "wavefront fx")) { | ||
2819 | release_region (dev.base+2, 6); | ||
2820 | return -1; | ||
2821 | } | ||
2822 | } | ||
2823 | |||
2824 | if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) { | ||
2825 | printk (KERN_ERR LOGNAME "cannot register raw synth\n"); | ||
2826 | goto err_out; | ||
2827 | } | ||
2828 | |||
2829 | #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ | ||
2830 | if ((dev.oss_dev = sound_alloc_synthdev()) == -1) { | ||
2831 | printk (KERN_ERR LOGNAME "Too many sequencers\n"); | ||
2832 | /* FIXME: leak: should unregister sound synth */ | ||
2833 | goto err_out; | ||
2834 | } else { | ||
2835 | synth_devs[dev.oss_dev] = &wavefront_operations; | ||
2836 | } | ||
2837 | #endif /* OSS_SUPPORT_SEQ */ | ||
2838 | |||
2839 | if (wavefront_init (1) < 0) { | ||
2840 | printk (KERN_WARNING LOGNAME "initialization failed.\n"); | ||
2841 | |||
2842 | #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ | ||
2843 | sound_unload_synthdev (dev.oss_dev); | ||
2844 | #endif /* OSS_SUPPORT_SEQ */ | ||
2845 | |||
2846 | goto err_out; | ||
2847 | } | ||
2848 | |||
2849 | if (wavefront_config_midi ()) { | ||
2850 | printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n"); | ||
2851 | } | ||
2852 | |||
2853 | return dev.oss_dev; | ||
2854 | |||
2855 | err_out: | ||
2856 | release_region (dev.base+2, 6); | ||
2857 | if (dev.has_fx) | ||
2858 | release_region (dev.base+8, 8); | ||
2859 | return -1; | ||
2860 | } | ||
2861 | |||
2862 | static void __exit uninstall_wavefront (void) | ||
2863 | { | ||
2864 | /* the first two i/o addresses are freed by the wf_mpu code */ | ||
2865 | release_region (dev.base+2, 6); | ||
2866 | |||
2867 | if (dev.has_fx) { | ||
2868 | release_region (dev.base+8, 8); | ||
2869 | } | ||
2870 | |||
2871 | unregister_sound_synth (dev.synth_dev); | ||
2872 | |||
2873 | #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ | ||
2874 | sound_unload_synthdev (dev.oss_dev); | ||
2875 | #endif /* OSS_SUPPORT_SEQ */ | ||
2876 | uninstall_wf_mpu (); | ||
2877 | } | ||
2878 | |||
2879 | /***********************************************************************/ | ||
2880 | /* WaveFront FX control */ | ||
2881 | /***********************************************************************/ | ||
2882 | |||
2883 | #include "yss225.h" | ||
2884 | |||
2885 | /* Control bits for the Load Control Register | ||
2886 | */ | ||
2887 | |||
2888 | #define FX_LSB_TRANSFER 0x01 /* transfer after DSP LSB byte written */ | ||
2889 | #define FX_MSB_TRANSFER 0x02 /* transfer after DSP MSB byte written */ | ||
2890 | #define FX_AUTO_INCR 0x04 /* auto-increment DSP address after transfer */ | ||
2891 | |||
2892 | static int | ||
2893 | wffx_idle (void) | ||
2894 | |||
2895 | { | ||
2896 | int i; | ||
2897 | unsigned int x = 0x80; | ||
2898 | |||
2899 | for (i = 0; i < 1000; i++) { | ||
2900 | x = inb (dev.fx_status); | ||
2901 | if ((x & 0x80) == 0) { | ||
2902 | break; | ||
2903 | } | ||
2904 | } | ||
2905 | |||
2906 | if (x & 0x80) { | ||
2907 | printk (KERN_ERR LOGNAME "FX device never idle.\n"); | ||
2908 | return 0; | ||
2909 | } | ||
2910 | |||
2911 | return (1); | ||
2912 | } | ||
2913 | |||
2914 | int __init detect_wffx (void) | ||
2915 | { | ||
2916 | /* This is a crude check, but its the best one I have for now. | ||
2917 | Certainly on the Maui and the Tropez, wffx_idle() will | ||
2918 | report "never idle", which suggests that this test should | ||
2919 | work OK. | ||
2920 | */ | ||
2921 | |||
2922 | if (inb (dev.fx_status) & 0x80) { | ||
2923 | printk (KERN_INFO LOGNAME "Hmm, probably a Maui or Tropez.\n"); | ||
2924 | return -1; | ||
2925 | } | ||
2926 | |||
2927 | return 0; | ||
2928 | } | ||
2929 | |||
2930 | static void | ||
2931 | wffx_mute (int onoff) | ||
2932 | |||
2933 | { | ||
2934 | if (!wffx_idle()) { | ||
2935 | return; | ||
2936 | } | ||
2937 | |||
2938 | outb (onoff ? 0x02 : 0x00, dev.fx_op); | ||
2939 | } | ||
2940 | |||
2941 | static int | ||
2942 | wffx_memset (int page, | ||
2943 | int addr, int cnt, unsigned short *data) | ||
2944 | { | ||
2945 | if (page < 0 || page > 7) { | ||
2946 | printk (KERN_ERR LOGNAME "FX memset: " | ||
2947 | "page must be >= 0 and <= 7\n"); | ||
2948 | return -(EINVAL); | ||
2949 | } | ||
2950 | |||
2951 | if (addr < 0 || addr > 0x7f) { | ||
2952 | printk (KERN_ERR LOGNAME "FX memset: " | ||
2953 | "addr must be >= 0 and <= 7f\n"); | ||
2954 | return -(EINVAL); | ||
2955 | } | ||
2956 | |||
2957 | if (cnt == 1) { | ||
2958 | |||
2959 | outb (FX_LSB_TRANSFER, dev.fx_lcr); | ||
2960 | outb (page, dev.fx_dsp_page); | ||
2961 | outb (addr, dev.fx_dsp_addr); | ||
2962 | outb ((data[0] >> 8), dev.fx_dsp_msb); | ||
2963 | outb ((data[0] & 0xff), dev.fx_dsp_lsb); | ||
2964 | |||
2965 | printk (KERN_INFO LOGNAME "FX: addr %d:%x set to 0x%x\n", | ||
2966 | page, addr, data[0]); | ||
2967 | |||
2968 | } else { | ||
2969 | int i; | ||
2970 | |||
2971 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
2972 | outb (page, dev.fx_dsp_page); | ||
2973 | outb (addr, dev.fx_dsp_addr); | ||
2974 | |||
2975 | for (i = 0; i < cnt; i++) { | ||
2976 | outb ((data[i] >> 8), dev.fx_dsp_msb); | ||
2977 | outb ((data[i] & 0xff), dev.fx_dsp_lsb); | ||
2978 | if (!wffx_idle ()) { | ||
2979 | break; | ||
2980 | } | ||
2981 | } | ||
2982 | |||
2983 | if (i != cnt) { | ||
2984 | printk (KERN_WARNING LOGNAME | ||
2985 | "FX memset " | ||
2986 | "(0x%x, 0x%x, %p, %d) incomplete\n", | ||
2987 | page, addr, data, cnt); | ||
2988 | return -(EIO); | ||
2989 | } | ||
2990 | } | ||
2991 | |||
2992 | return 0; | ||
2993 | } | ||
2994 | |||
2995 | static int | ||
2996 | wffx_ioctl (wavefront_fx_info *r) | ||
2997 | |||
2998 | { | ||
2999 | unsigned short page_data[256]; | ||
3000 | unsigned short *pd; | ||
3001 | |||
3002 | switch (r->request) { | ||
3003 | case WFFX_MUTE: | ||
3004 | wffx_mute (r->data[0]); | ||
3005 | return 0; | ||
3006 | |||
3007 | case WFFX_MEMSET: | ||
3008 | |||
3009 | if (r->data[2] <= 0) { | ||
3010 | printk (KERN_ERR LOGNAME "cannot write " | ||
3011 | "<= 0 bytes to FX\n"); | ||
3012 | return -(EINVAL); | ||
3013 | } else if (r->data[2] == 1) { | ||
3014 | pd = (unsigned short *) &r->data[3]; | ||
3015 | } else { | ||
3016 | if (r->data[2] > sizeof (page_data)) { | ||
3017 | printk (KERN_ERR LOGNAME "cannot write " | ||
3018 | "> 255 bytes to FX\n"); | ||
3019 | return -(EINVAL); | ||
3020 | } | ||
3021 | if (copy_from_user(page_data, | ||
3022 | (unsigned char __user *)r->data[3], | ||
3023 | r->data[2])) | ||
3024 | return -EFAULT; | ||
3025 | pd = page_data; | ||
3026 | } | ||
3027 | |||
3028 | return wffx_memset (r->data[0], /* page */ | ||
3029 | r->data[1], /* addr */ | ||
3030 | r->data[2], /* cnt */ | ||
3031 | pd); | ||
3032 | |||
3033 | default: | ||
3034 | printk (KERN_WARNING LOGNAME | ||
3035 | "FX: ioctl %d not yet supported\n", | ||
3036 | r->request); | ||
3037 | return -(EINVAL); | ||
3038 | } | ||
3039 | } | ||
3040 | |||
3041 | /* YSS225 initialization. | ||
3042 | |||
3043 | This code was developed using DOSEMU. The Turtle Beach SETUPSND | ||
3044 | utility was run with I/O tracing in DOSEMU enabled, and a reconstruction | ||
3045 | of the port I/O done, using the Yamaha faxback document as a guide | ||
3046 | to add more logic to the code. Its really pretty weird. | ||
3047 | |||
3048 | There was an alternative approach of just dumping the whole I/O | ||
3049 | sequence as a series of port/value pairs and a simple loop | ||
3050 | that output it. However, I hope that eventually I'll get more | ||
3051 | control over what this code does, and so I tried to stick with | ||
3052 | a somewhat "algorithmic" approach. | ||
3053 | */ | ||
3054 | |||
3055 | static int __init wffx_init (void) | ||
3056 | { | ||
3057 | int i; | ||
3058 | int j; | ||
3059 | |||
3060 | /* Set all bits for all channels on the MOD unit to zero */ | ||
3061 | /* XXX But why do this twice ? */ | ||
3062 | |||
3063 | for (j = 0; j < 2; j++) { | ||
3064 | for (i = 0x10; i <= 0xff; i++) { | ||
3065 | |||
3066 | if (!wffx_idle ()) { | ||
3067 | return (-1); | ||
3068 | } | ||
3069 | |||
3070 | outb (i, dev.fx_mod_addr); | ||
3071 | outb (0x0, dev.fx_mod_data); | ||
3072 | } | ||
3073 | } | ||
3074 | |||
3075 | if (!wffx_idle()) return (-1); | ||
3076 | outb (0x02, dev.fx_op); /* mute on */ | ||
3077 | |||
3078 | if (!wffx_idle()) return (-1); | ||
3079 | outb (0x07, dev.fx_dsp_page); | ||
3080 | outb (0x44, dev.fx_dsp_addr); | ||
3081 | outb (0x00, dev.fx_dsp_msb); | ||
3082 | outb (0x00, dev.fx_dsp_lsb); | ||
3083 | if (!wffx_idle()) return (-1); | ||
3084 | outb (0x07, dev.fx_dsp_page); | ||
3085 | outb (0x42, dev.fx_dsp_addr); | ||
3086 | outb (0x00, dev.fx_dsp_msb); | ||
3087 | outb (0x00, dev.fx_dsp_lsb); | ||
3088 | if (!wffx_idle()) return (-1); | ||
3089 | outb (0x07, dev.fx_dsp_page); | ||
3090 | outb (0x43, dev.fx_dsp_addr); | ||
3091 | outb (0x00, dev.fx_dsp_msb); | ||
3092 | outb (0x00, dev.fx_dsp_lsb); | ||
3093 | if (!wffx_idle()) return (-1); | ||
3094 | outb (0x07, dev.fx_dsp_page); | ||
3095 | outb (0x7c, dev.fx_dsp_addr); | ||
3096 | outb (0x00, dev.fx_dsp_msb); | ||
3097 | outb (0x00, dev.fx_dsp_lsb); | ||
3098 | if (!wffx_idle()) return (-1); | ||
3099 | outb (0x07, dev.fx_dsp_page); | ||
3100 | outb (0x7e, dev.fx_dsp_addr); | ||
3101 | outb (0x00, dev.fx_dsp_msb); | ||
3102 | outb (0x00, dev.fx_dsp_lsb); | ||
3103 | if (!wffx_idle()) return (-1); | ||
3104 | outb (0x07, dev.fx_dsp_page); | ||
3105 | outb (0x46, dev.fx_dsp_addr); | ||
3106 | outb (0x00, dev.fx_dsp_msb); | ||
3107 | outb (0x00, dev.fx_dsp_lsb); | ||
3108 | if (!wffx_idle()) return (-1); | ||
3109 | outb (0x07, dev.fx_dsp_page); | ||
3110 | outb (0x49, dev.fx_dsp_addr); | ||
3111 | outb (0x00, dev.fx_dsp_msb); | ||
3112 | outb (0x00, dev.fx_dsp_lsb); | ||
3113 | if (!wffx_idle()) return (-1); | ||
3114 | outb (0x07, dev.fx_dsp_page); | ||
3115 | outb (0x47, dev.fx_dsp_addr); | ||
3116 | outb (0x00, dev.fx_dsp_msb); | ||
3117 | outb (0x00, dev.fx_dsp_lsb); | ||
3118 | if (!wffx_idle()) return (-1); | ||
3119 | outb (0x07, dev.fx_dsp_page); | ||
3120 | outb (0x4a, dev.fx_dsp_addr); | ||
3121 | outb (0x00, dev.fx_dsp_msb); | ||
3122 | outb (0x00, dev.fx_dsp_lsb); | ||
3123 | |||
3124 | /* either because of stupidity by TB's programmers, or because it | ||
3125 | actually does something, rezero the MOD page. | ||
3126 | */ | ||
3127 | for (i = 0x10; i <= 0xff; i++) { | ||
3128 | |||
3129 | if (!wffx_idle ()) { | ||
3130 | return (-1); | ||
3131 | } | ||
3132 | |||
3133 | outb (i, dev.fx_mod_addr); | ||
3134 | outb (0x0, dev.fx_mod_data); | ||
3135 | } | ||
3136 | /* load page zero */ | ||
3137 | |||
3138 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3139 | outb (0x00, dev.fx_dsp_page); | ||
3140 | outb (0x00, dev.fx_dsp_addr); | ||
3141 | |||
3142 | for (i = 0; i < sizeof (page_zero); i += 2) { | ||
3143 | outb (page_zero[i], dev.fx_dsp_msb); | ||
3144 | outb (page_zero[i+1], dev.fx_dsp_lsb); | ||
3145 | if (!wffx_idle()) return (-1); | ||
3146 | } | ||
3147 | |||
3148 | /* Now load page one */ | ||
3149 | |||
3150 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3151 | outb (0x01, dev.fx_dsp_page); | ||
3152 | outb (0x00, dev.fx_dsp_addr); | ||
3153 | |||
3154 | for (i = 0; i < sizeof (page_one); i += 2) { | ||
3155 | outb (page_one[i], dev.fx_dsp_msb); | ||
3156 | outb (page_one[i+1], dev.fx_dsp_lsb); | ||
3157 | if (!wffx_idle()) return (-1); | ||
3158 | } | ||
3159 | |||
3160 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3161 | outb (0x02, dev.fx_dsp_page); | ||
3162 | outb (0x00, dev.fx_dsp_addr); | ||
3163 | |||
3164 | for (i = 0; i < sizeof (page_two); i++) { | ||
3165 | outb (page_two[i], dev.fx_dsp_lsb); | ||
3166 | if (!wffx_idle()) return (-1); | ||
3167 | } | ||
3168 | |||
3169 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3170 | outb (0x03, dev.fx_dsp_page); | ||
3171 | outb (0x00, dev.fx_dsp_addr); | ||
3172 | |||
3173 | for (i = 0; i < sizeof (page_three); i++) { | ||
3174 | outb (page_three[i], dev.fx_dsp_lsb); | ||
3175 | if (!wffx_idle()) return (-1); | ||
3176 | } | ||
3177 | |||
3178 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3179 | outb (0x04, dev.fx_dsp_page); | ||
3180 | outb (0x00, dev.fx_dsp_addr); | ||
3181 | |||
3182 | for (i = 0; i < sizeof (page_four); i++) { | ||
3183 | outb (page_four[i], dev.fx_dsp_lsb); | ||
3184 | if (!wffx_idle()) return (-1); | ||
3185 | } | ||
3186 | |||
3187 | /* Load memory area (page six) */ | ||
3188 | |||
3189 | outb (FX_LSB_TRANSFER, dev.fx_lcr); | ||
3190 | outb (0x06, dev.fx_dsp_page); | ||
3191 | |||
3192 | for (i = 0; i < sizeof (page_six); i += 3) { | ||
3193 | outb (page_six[i], dev.fx_dsp_addr); | ||
3194 | outb (page_six[i+1], dev.fx_dsp_msb); | ||
3195 | outb (page_six[i+2], dev.fx_dsp_lsb); | ||
3196 | if (!wffx_idle()) return (-1); | ||
3197 | } | ||
3198 | |||
3199 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3200 | outb (0x07, dev.fx_dsp_page); | ||
3201 | outb (0x00, dev.fx_dsp_addr); | ||
3202 | |||
3203 | for (i = 0; i < sizeof (page_seven); i += 2) { | ||
3204 | outb (page_seven[i], dev.fx_dsp_msb); | ||
3205 | outb (page_seven[i+1], dev.fx_dsp_lsb); | ||
3206 | if (!wffx_idle()) return (-1); | ||
3207 | } | ||
3208 | |||
3209 | /* Now setup the MOD area. We do this algorithmically in order to | ||
3210 | save a little data space. It could be done in the same fashion | ||
3211 | as the "pages". | ||
3212 | */ | ||
3213 | |||
3214 | for (i = 0x00; i <= 0x0f; i++) { | ||
3215 | outb (0x01, dev.fx_mod_addr); | ||
3216 | outb (i, dev.fx_mod_data); | ||
3217 | if (!wffx_idle()) return (-1); | ||
3218 | outb (0x02, dev.fx_mod_addr); | ||
3219 | outb (0x00, dev.fx_mod_data); | ||
3220 | if (!wffx_idle()) return (-1); | ||
3221 | } | ||
3222 | |||
3223 | for (i = 0xb0; i <= 0xbf; i++) { | ||
3224 | outb (i, dev.fx_mod_addr); | ||
3225 | outb (0x20, dev.fx_mod_data); | ||
3226 | if (!wffx_idle()) return (-1); | ||
3227 | } | ||
3228 | |||
3229 | for (i = 0xf0; i <= 0xff; i++) { | ||
3230 | outb (i, dev.fx_mod_addr); | ||
3231 | outb (0x20, dev.fx_mod_data); | ||
3232 | if (!wffx_idle()) return (-1); | ||
3233 | } | ||
3234 | |||
3235 | for (i = 0x10; i <= 0x1d; i++) { | ||
3236 | outb (i, dev.fx_mod_addr); | ||
3237 | outb (0xff, dev.fx_mod_data); | ||
3238 | if (!wffx_idle()) return (-1); | ||
3239 | } | ||
3240 | |||
3241 | outb (0x1e, dev.fx_mod_addr); | ||
3242 | outb (0x40, dev.fx_mod_data); | ||
3243 | if (!wffx_idle()) return (-1); | ||
3244 | |||
3245 | for (i = 0x1f; i <= 0x2d; i++) { | ||
3246 | outb (i, dev.fx_mod_addr); | ||
3247 | outb (0xff, dev.fx_mod_data); | ||
3248 | if (!wffx_idle()) return (-1); | ||
3249 | } | ||
3250 | |||
3251 | outb (0x2e, dev.fx_mod_addr); | ||
3252 | outb (0x00, dev.fx_mod_data); | ||
3253 | if (!wffx_idle()) return (-1); | ||
3254 | |||
3255 | for (i = 0x2f; i <= 0x3e; i++) { | ||
3256 | outb (i, dev.fx_mod_addr); | ||
3257 | outb (0x00, dev.fx_mod_data); | ||
3258 | if (!wffx_idle()) return (-1); | ||
3259 | } | ||
3260 | |||
3261 | outb (0x3f, dev.fx_mod_addr); | ||
3262 | outb (0x20, dev.fx_mod_data); | ||
3263 | if (!wffx_idle()) return (-1); | ||
3264 | |||
3265 | for (i = 0x40; i <= 0x4d; i++) { | ||
3266 | outb (i, dev.fx_mod_addr); | ||
3267 | outb (0x00, dev.fx_mod_data); | ||
3268 | if (!wffx_idle()) return (-1); | ||
3269 | } | ||
3270 | |||
3271 | outb (0x4e, dev.fx_mod_addr); | ||
3272 | outb (0x0e, dev.fx_mod_data); | ||
3273 | if (!wffx_idle()) return (-1); | ||
3274 | outb (0x4f, dev.fx_mod_addr); | ||
3275 | outb (0x0e, dev.fx_mod_data); | ||
3276 | if (!wffx_idle()) return (-1); | ||
3277 | |||
3278 | |||
3279 | for (i = 0x50; i <= 0x6b; i++) { | ||
3280 | outb (i, dev.fx_mod_addr); | ||
3281 | outb (0x00, dev.fx_mod_data); | ||
3282 | if (!wffx_idle()) return (-1); | ||
3283 | } | ||
3284 | |||
3285 | outb (0x6c, dev.fx_mod_addr); | ||
3286 | outb (0x40, dev.fx_mod_data); | ||
3287 | if (!wffx_idle()) return (-1); | ||
3288 | |||
3289 | outb (0x6d, dev.fx_mod_addr); | ||
3290 | outb (0x00, dev.fx_mod_data); | ||
3291 | if (!wffx_idle()) return (-1); | ||
3292 | |||
3293 | outb (0x6e, dev.fx_mod_addr); | ||
3294 | outb (0x40, dev.fx_mod_data); | ||
3295 | if (!wffx_idle()) return (-1); | ||
3296 | |||
3297 | outb (0x6f, dev.fx_mod_addr); | ||
3298 | outb (0x40, dev.fx_mod_data); | ||
3299 | if (!wffx_idle()) return (-1); | ||
3300 | |||
3301 | for (i = 0x70; i <= 0x7f; i++) { | ||
3302 | outb (i, dev.fx_mod_addr); | ||
3303 | outb (0xc0, dev.fx_mod_data); | ||
3304 | if (!wffx_idle()) return (-1); | ||
3305 | } | ||
3306 | |||
3307 | for (i = 0x80; i <= 0xaf; i++) { | ||
3308 | outb (i, dev.fx_mod_addr); | ||
3309 | outb (0x00, dev.fx_mod_data); | ||
3310 | if (!wffx_idle()) return (-1); | ||
3311 | } | ||
3312 | |||
3313 | for (i = 0xc0; i <= 0xdd; i++) { | ||
3314 | outb (i, dev.fx_mod_addr); | ||
3315 | outb (0x00, dev.fx_mod_data); | ||
3316 | if (!wffx_idle()) return (-1); | ||
3317 | } | ||
3318 | |||
3319 | outb (0xde, dev.fx_mod_addr); | ||
3320 | outb (0x10, dev.fx_mod_data); | ||
3321 | if (!wffx_idle()) return (-1); | ||
3322 | outb (0xdf, dev.fx_mod_addr); | ||
3323 | outb (0x10, dev.fx_mod_data); | ||
3324 | if (!wffx_idle()) return (-1); | ||
3325 | |||
3326 | for (i = 0xe0; i <= 0xef; i++) { | ||
3327 | outb (i, dev.fx_mod_addr); | ||
3328 | outb (0x00, dev.fx_mod_data); | ||
3329 | if (!wffx_idle()) return (-1); | ||
3330 | } | ||
3331 | |||
3332 | for (i = 0x00; i <= 0x0f; i++) { | ||
3333 | outb (0x01, dev.fx_mod_addr); | ||
3334 | outb (i, dev.fx_mod_data); | ||
3335 | outb (0x02, dev.fx_mod_addr); | ||
3336 | outb (0x01, dev.fx_mod_data); | ||
3337 | if (!wffx_idle()) return (-1); | ||
3338 | } | ||
3339 | |||
3340 | outb (0x02, dev.fx_op); /* mute on */ | ||
3341 | |||
3342 | /* Now set the coefficients and so forth for the programs above */ | ||
3343 | |||
3344 | for (i = 0; i < sizeof (coefficients); i += 4) { | ||
3345 | outb (coefficients[i], dev.fx_dsp_page); | ||
3346 | outb (coefficients[i+1], dev.fx_dsp_addr); | ||
3347 | outb (coefficients[i+2], dev.fx_dsp_msb); | ||
3348 | outb (coefficients[i+3], dev.fx_dsp_lsb); | ||
3349 | if (!wffx_idle()) return (-1); | ||
3350 | } | ||
3351 | |||
3352 | /* Some settings (?) that are too small to bundle into loops */ | ||
3353 | |||
3354 | if (!wffx_idle()) return (-1); | ||
3355 | outb (0x1e, dev.fx_mod_addr); | ||
3356 | outb (0x14, dev.fx_mod_data); | ||
3357 | if (!wffx_idle()) return (-1); | ||
3358 | outb (0xde, dev.fx_mod_addr); | ||
3359 | outb (0x20, dev.fx_mod_data); | ||
3360 | if (!wffx_idle()) return (-1); | ||
3361 | outb (0xdf, dev.fx_mod_addr); | ||
3362 | outb (0x20, dev.fx_mod_data); | ||
3363 | |||
3364 | /* some more coefficients */ | ||
3365 | |||
3366 | if (!wffx_idle()) return (-1); | ||
3367 | outb (0x06, dev.fx_dsp_page); | ||
3368 | outb (0x78, dev.fx_dsp_addr); | ||
3369 | outb (0x00, dev.fx_dsp_msb); | ||
3370 | outb (0x40, dev.fx_dsp_lsb); | ||
3371 | if (!wffx_idle()) return (-1); | ||
3372 | outb (0x07, dev.fx_dsp_page); | ||
3373 | outb (0x03, dev.fx_dsp_addr); | ||
3374 | outb (0x0f, dev.fx_dsp_msb); | ||
3375 | outb (0xff, dev.fx_dsp_lsb); | ||
3376 | if (!wffx_idle()) return (-1); | ||
3377 | outb (0x07, dev.fx_dsp_page); | ||
3378 | outb (0x0b, dev.fx_dsp_addr); | ||
3379 | outb (0x0f, dev.fx_dsp_msb); | ||
3380 | outb (0xff, dev.fx_dsp_lsb); | ||
3381 | if (!wffx_idle()) return (-1); | ||
3382 | outb (0x07, dev.fx_dsp_page); | ||
3383 | outb (0x02, dev.fx_dsp_addr); | ||
3384 | outb (0x00, dev.fx_dsp_msb); | ||
3385 | outb (0x00, dev.fx_dsp_lsb); | ||
3386 | if (!wffx_idle()) return (-1); | ||
3387 | outb (0x07, dev.fx_dsp_page); | ||
3388 | outb (0x0a, dev.fx_dsp_addr); | ||
3389 | outb (0x00, dev.fx_dsp_msb); | ||
3390 | outb (0x00, dev.fx_dsp_lsb); | ||
3391 | if (!wffx_idle()) return (-1); | ||
3392 | outb (0x07, dev.fx_dsp_page); | ||
3393 | outb (0x46, dev.fx_dsp_addr); | ||
3394 | outb (0x00, dev.fx_dsp_msb); | ||
3395 | outb (0x00, dev.fx_dsp_lsb); | ||
3396 | if (!wffx_idle()) return (-1); | ||
3397 | outb (0x07, dev.fx_dsp_page); | ||
3398 | outb (0x49, dev.fx_dsp_addr); | ||
3399 | outb (0x00, dev.fx_dsp_msb); | ||
3400 | outb (0x00, dev.fx_dsp_lsb); | ||
3401 | |||
3402 | /* Now, for some strange reason, lets reload every page | ||
3403 | and all the coefficients over again. I have *NO* idea | ||
3404 | why this is done. I do know that no sound is produced | ||
3405 | is this phase is omitted. | ||
3406 | */ | ||
3407 | |||
3408 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3409 | outb (0x00, dev.fx_dsp_page); | ||
3410 | outb (0x10, dev.fx_dsp_addr); | ||
3411 | |||
3412 | for (i = 0; i < sizeof (page_zero_v2); i += 2) { | ||
3413 | outb (page_zero_v2[i], dev.fx_dsp_msb); | ||
3414 | outb (page_zero_v2[i+1], dev.fx_dsp_lsb); | ||
3415 | if (!wffx_idle()) return (-1); | ||
3416 | } | ||
3417 | |||
3418 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3419 | outb (0x01, dev.fx_dsp_page); | ||
3420 | outb (0x10, dev.fx_dsp_addr); | ||
3421 | |||
3422 | for (i = 0; i < sizeof (page_one_v2); i += 2) { | ||
3423 | outb (page_one_v2[i], dev.fx_dsp_msb); | ||
3424 | outb (page_one_v2[i+1], dev.fx_dsp_lsb); | ||
3425 | if (!wffx_idle()) return (-1); | ||
3426 | } | ||
3427 | |||
3428 | if (!wffx_idle()) return (-1); | ||
3429 | if (!wffx_idle()) return (-1); | ||
3430 | |||
3431 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3432 | outb (0x02, dev.fx_dsp_page); | ||
3433 | outb (0x10, dev.fx_dsp_addr); | ||
3434 | |||
3435 | for (i = 0; i < sizeof (page_two_v2); i++) { | ||
3436 | outb (page_two_v2[i], dev.fx_dsp_lsb); | ||
3437 | if (!wffx_idle()) return (-1); | ||
3438 | } | ||
3439 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3440 | outb (0x03, dev.fx_dsp_page); | ||
3441 | outb (0x10, dev.fx_dsp_addr); | ||
3442 | |||
3443 | for (i = 0; i < sizeof (page_three_v2); i++) { | ||
3444 | outb (page_three_v2[i], dev.fx_dsp_lsb); | ||
3445 | if (!wffx_idle()) return (-1); | ||
3446 | } | ||
3447 | |||
3448 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3449 | outb (0x04, dev.fx_dsp_page); | ||
3450 | outb (0x10, dev.fx_dsp_addr); | ||
3451 | |||
3452 | for (i = 0; i < sizeof (page_four_v2); i++) { | ||
3453 | outb (page_four_v2[i], dev.fx_dsp_lsb); | ||
3454 | if (!wffx_idle()) return (-1); | ||
3455 | } | ||
3456 | |||
3457 | outb (FX_LSB_TRANSFER, dev.fx_lcr); | ||
3458 | outb (0x06, dev.fx_dsp_page); | ||
3459 | |||
3460 | /* Page six v.2 is algorithmic */ | ||
3461 | |||
3462 | for (i = 0x10; i <= 0x3e; i += 2) { | ||
3463 | outb (i, dev.fx_dsp_addr); | ||
3464 | outb (0x00, dev.fx_dsp_msb); | ||
3465 | outb (0x00, dev.fx_dsp_lsb); | ||
3466 | if (!wffx_idle()) return (-1); | ||
3467 | } | ||
3468 | |||
3469 | outb (FX_AUTO_INCR|FX_LSB_TRANSFER, dev.fx_lcr); | ||
3470 | outb (0x07, dev.fx_dsp_page); | ||
3471 | outb (0x10, dev.fx_dsp_addr); | ||
3472 | |||
3473 | for (i = 0; i < sizeof (page_seven_v2); i += 2) { | ||
3474 | outb (page_seven_v2[i], dev.fx_dsp_msb); | ||
3475 | outb (page_seven_v2[i+1], dev.fx_dsp_lsb); | ||
3476 | if (!wffx_idle()) return (-1); | ||
3477 | } | ||
3478 | |||
3479 | for (i = 0x00; i < sizeof(mod_v2); i += 2) { | ||
3480 | outb (mod_v2[i], dev.fx_mod_addr); | ||
3481 | outb (mod_v2[i+1], dev.fx_mod_data); | ||
3482 | if (!wffx_idle()) return (-1); | ||
3483 | } | ||
3484 | |||
3485 | for (i = 0; i < sizeof (coefficients2); i += 4) { | ||
3486 | outb (coefficients2[i], dev.fx_dsp_page); | ||
3487 | outb (coefficients2[i+1], dev.fx_dsp_addr); | ||
3488 | outb (coefficients2[i+2], dev.fx_dsp_msb); | ||
3489 | outb (coefficients2[i+3], dev.fx_dsp_lsb); | ||
3490 | if (!wffx_idle()) return (-1); | ||
3491 | } | ||
3492 | |||
3493 | for (i = 0; i < sizeof (coefficients3); i += 2) { | ||
3494 | int x; | ||
3495 | |||
3496 | outb (0x07, dev.fx_dsp_page); | ||
3497 | x = (i % 4) ? 0x4e : 0x4c; | ||
3498 | outb (x, dev.fx_dsp_addr); | ||
3499 | outb (coefficients3[i], dev.fx_dsp_msb); | ||
3500 | outb (coefficients3[i+1], dev.fx_dsp_lsb); | ||
3501 | } | ||
3502 | |||
3503 | outb (0x00, dev.fx_op); /* mute off */ | ||
3504 | if (!wffx_idle()) return (-1); | ||
3505 | |||
3506 | return (0); | ||
3507 | } | ||
3508 | |||
3509 | static int io = -1; | ||
3510 | static int irq = -1; | ||
3511 | |||
3512 | MODULE_AUTHOR ("Paul Barton-Davis <pbd@op.net>"); | ||
3513 | MODULE_DESCRIPTION ("Turtle Beach WaveFront Linux Driver"); | ||
3514 | MODULE_LICENSE("GPL"); | ||
3515 | module_param (io, int, 0); | ||
3516 | module_param (irq, int, 0); | ||
3517 | |||
3518 | static int __init init_wavfront (void) | ||
3519 | { | ||
3520 | printk ("Turtle Beach WaveFront Driver\n" | ||
3521 | "Copyright (C) by Hannu Solvainen, " | ||
3522 | "Paul Barton-Davis 1993-1998.\n"); | ||
3523 | |||
3524 | /* XXX t'would be lovely to ask the CS4232 for these values, eh ? */ | ||
3525 | |||
3526 | if (io == -1 || irq == -1) { | ||
3527 | printk (KERN_INFO LOGNAME "irq and io options must be set.\n"); | ||
3528 | return -EINVAL; | ||
3529 | } | ||
3530 | |||
3531 | if (wavefront_interrupt_bits (irq) < 0) { | ||
3532 | printk (KERN_INFO LOGNAME | ||
3533 | "IRQ must be 9, 5, 12 or 15 (not %d)\n", irq); | ||
3534 | return -ENODEV; | ||
3535 | } | ||
3536 | |||
3537 | if (detect_wavefront (irq, io) < 0) { | ||
3538 | return -ENODEV; | ||
3539 | } | ||
3540 | |||
3541 | if (install_wavefront () < 0) { | ||
3542 | return -EIO; | ||
3543 | } | ||
3544 | |||
3545 | return 0; | ||
3546 | } | ||
3547 | |||
3548 | static void __exit cleanup_wavfront (void) | ||
3549 | { | ||
3550 | uninstall_wavefront (); | ||
3551 | } | ||
3552 | |||
3553 | module_init(init_wavfront); | ||
3554 | module_exit(cleanup_wavfront); | ||
diff --git a/sound/oss/wf_midi.c b/sound/oss/wf_midi.c deleted file mode 100644 index 75c0c143a759..000000000000 --- a/sound/oss/wf_midi.c +++ /dev/null | |||
@@ -1,880 +0,0 @@ | |||
1 | /* | ||
2 | * sound/oss/wf_midi.c | ||
3 | * | ||
4 | * The low level driver for the WaveFront ICS2115 MIDI interface(s) | ||
5 | * Note that there is also an MPU-401 emulation (actually, a UART-401 | ||
6 | * emulation) on the CS4232 on the Tropez Plus. This code has nothing | ||
7 | * to do with that interface at all. | ||
8 | * | ||
9 | * The interface is essentially just a UART-401, but is has the | ||
10 | * interesting property of supporting what Turtle Beach called | ||
11 | * "Virtual MIDI" mode. In this mode, there are effectively *two* | ||
12 | * MIDI buses accessible via the interface, one that is routed | ||
13 | * solely to/from the external WaveFront synthesizer and the other | ||
14 | * corresponding to the pin/socket connector used to link external | ||
15 | * MIDI devices to the board. | ||
16 | * | ||
17 | * This driver fully supports this mode, allowing two distinct | ||
18 | * midi devices (/dev/midiNN and /dev/midiNN+1) to be used | ||
19 | * completely independently, giving 32 channels of MIDI routing, | ||
20 | * 16 to the WaveFront synth and 16 to the external MIDI bus. | ||
21 | * | ||
22 | * Switching between the two is accomplished externally by the driver | ||
23 | * using the two otherwise unused MIDI bytes. See the code for more details. | ||
24 | * | ||
25 | * NOTE: VIRTUAL MIDI MODE IS ON BY DEFAULT (see wavefront.c) | ||
26 | * | ||
27 | * The main reason to turn off Virtual MIDI mode is when you want to | ||
28 | * tightly couple the WaveFront synth with an external MIDI | ||
29 | * device. You won't be able to distinguish the source of any MIDI | ||
30 | * data except via SysEx ID, but thats probably OK, since for the most | ||
31 | * part, the WaveFront won't be sending any MIDI data at all. | ||
32 | * | ||
33 | * The main reason to turn on Virtual MIDI Mode is to provide two | ||
34 | * completely independent 16-channel MIDI buses, one to the | ||
35 | * WaveFront and one to any external MIDI devices. Given the 32 | ||
36 | * voice nature of the WaveFront, its pretty easy to find a use | ||
37 | * for all 16 channels driving just that synth. | ||
38 | * | ||
39 | */ | ||
40 | |||
41 | /* | ||
42 | * Copyright (C) by Paul Barton-Davis 1998 | ||
43 | * Some portions of this file are derived from work that is: | ||
44 | * | ||
45 | * CopyriGht (C) by Hannu Savolainen 1993-1996 | ||
46 | * | ||
47 | * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) | ||
48 | * Version 2 (June 1991). See the "COPYING" file distributed with this software | ||
49 | * for more info. | ||
50 | */ | ||
51 | |||
52 | #include <linux/init.h> | ||
53 | #include <linux/interrupt.h> | ||
54 | #include <linux/spinlock.h> | ||
55 | #include "sound_config.h" | ||
56 | |||
57 | #include <linux/wavefront.h> | ||
58 | |||
59 | #ifdef MODULE | ||
60 | |||
61 | struct wf_mpu_config { | ||
62 | int base; | ||
63 | #define DATAPORT(d) (d)->base | ||
64 | #define COMDPORT(d) (d)->base+1 | ||
65 | #define STATPORT(d) (d)->base+1 | ||
66 | |||
67 | int irq; | ||
68 | int opened; | ||
69 | int devno; | ||
70 | int synthno; | ||
71 | int mode; | ||
72 | #define MODE_MIDI 1 | ||
73 | #define MODE_SYNTH 2 | ||
74 | |||
75 | void (*inputintr) (int dev, unsigned char data); | ||
76 | char isvirtual; /* do virtual I/O stuff */ | ||
77 | }; | ||
78 | |||
79 | static struct wf_mpu_config devs[2]; | ||
80 | static struct wf_mpu_config *phys_dev = &devs[0]; | ||
81 | static struct wf_mpu_config *virt_dev = &devs[1]; | ||
82 | |||
83 | static void start_uart_mode (void); | ||
84 | static DEFINE_SPINLOCK(lock); | ||
85 | |||
86 | #define OUTPUT_READY 0x40 | ||
87 | #define INPUT_AVAIL 0x80 | ||
88 | #define MPU_ACK 0xFE | ||
89 | #define UART_MODE_ON 0x3F | ||
90 | |||
91 | static inline int wf_mpu_status (void) | ||
92 | { | ||
93 | return inb (STATPORT (phys_dev)); | ||
94 | } | ||
95 | |||
96 | static inline int input_avail (void) | ||
97 | { | ||
98 | return !(wf_mpu_status() & INPUT_AVAIL); | ||
99 | } | ||
100 | |||
101 | static inline int output_ready (void) | ||
102 | { | ||
103 | return !(wf_mpu_status() & OUTPUT_READY); | ||
104 | } | ||
105 | |||
106 | static inline int read_data (void) | ||
107 | { | ||
108 | return inb (DATAPORT (phys_dev)); | ||
109 | } | ||
110 | |||
111 | static inline void write_data (unsigned char byte) | ||
112 | { | ||
113 | outb (byte, DATAPORT (phys_dev)); | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * States for the input scanner (should be in dev_table.h) | ||
118 | */ | ||
119 | |||
120 | #define MST_SYSMSG 100 /* System message (sysx etc). */ | ||
121 | #define MST_MTC 102 /* Midi Time Code (MTC) qframe msg */ | ||
122 | #define MST_SONGSEL 103 /* Song select */ | ||
123 | #define MST_SONGPOS 104 /* Song position pointer */ | ||
124 | #define MST_TIMED 105 /* Leading timing byte rcvd */ | ||
125 | |||
126 | /* buffer space check for input scanner */ | ||
127 | |||
128 | #define BUFTEST(mi) if (mi->m_ptr >= MI_MAX || mi->m_ptr < 0) \ | ||
129 | {printk(KERN_ERR "WF-MPU: Invalid buffer pointer %d/%d, s=%d\n", \ | ||
130 | mi->m_ptr, mi->m_left, mi->m_state);mi->m_ptr--;} | ||
131 | |||
132 | static unsigned char len_tab[] = /* # of data bytes following a status | ||
133 | */ | ||
134 | { | ||
135 | 2, /* 8x */ | ||
136 | 2, /* 9x */ | ||
137 | 2, /* Ax */ | ||
138 | 2, /* Bx */ | ||
139 | 1, /* Cx */ | ||
140 | 1, /* Dx */ | ||
141 | 2, /* Ex */ | ||
142 | 0 /* Fx */ | ||
143 | }; | ||
144 | |||
145 | static int | ||
146 | wf_mpu_input_scanner (int devno, int synthdev, unsigned char midic) | ||
147 | |||
148 | { | ||
149 | struct midi_input_info *mi = &midi_devs[devno]->in_info; | ||
150 | |||
151 | switch (mi->m_state) { | ||
152 | case MST_INIT: | ||
153 | switch (midic) { | ||
154 | case 0xf8: | ||
155 | /* Timer overflow */ | ||
156 | break; | ||
157 | |||
158 | case 0xfc: | ||
159 | break; | ||
160 | |||
161 | case 0xfd: | ||
162 | /* XXX do something useful with this. If there is | ||
163 | an external MIDI timer (e.g. a hardware sequencer, | ||
164 | a useful timer can be derived ... | ||
165 | |||
166 | For now, no timer support. | ||
167 | */ | ||
168 | break; | ||
169 | |||
170 | case 0xfe: | ||
171 | return MPU_ACK; | ||
172 | break; | ||
173 | |||
174 | case 0xf0: | ||
175 | case 0xf1: | ||
176 | case 0xf2: | ||
177 | case 0xf3: | ||
178 | case 0xf4: | ||
179 | case 0xf5: | ||
180 | case 0xf6: | ||
181 | case 0xf7: | ||
182 | break; | ||
183 | |||
184 | case 0xf9: | ||
185 | break; | ||
186 | |||
187 | case 0xff: | ||
188 | mi->m_state = MST_SYSMSG; | ||
189 | break; | ||
190 | |||
191 | default: | ||
192 | if (midic <= 0xef) { | ||
193 | mi->m_state = MST_TIMED; | ||
194 | } | ||
195 | else | ||
196 | printk (KERN_ERR "<MPU: Unknown event %02x> ", | ||
197 | midic); | ||
198 | } | ||
199 | break; | ||
200 | |||
201 | case MST_TIMED: | ||
202 | { | ||
203 | int msg = ((int) (midic & 0xf0) >> 4); | ||
204 | |||
205 | mi->m_state = MST_DATA; | ||
206 | |||
207 | if (msg < 8) { /* Data byte */ | ||
208 | |||
209 | msg = ((int) (mi->m_prev_status & 0xf0) >> 4); | ||
210 | msg -= 8; | ||
211 | mi->m_left = len_tab[msg] - 1; | ||
212 | |||
213 | mi->m_ptr = 2; | ||
214 | mi->m_buf[0] = mi->m_prev_status; | ||
215 | mi->m_buf[1] = midic; | ||
216 | |||
217 | if (mi->m_left <= 0) { | ||
218 | mi->m_state = MST_INIT; | ||
219 | do_midi_msg (synthdev, mi->m_buf, mi->m_ptr); | ||
220 | mi->m_ptr = 0; | ||
221 | } | ||
222 | } else if (msg == 0xf) { /* MPU MARK */ | ||
223 | |||
224 | mi->m_state = MST_INIT; | ||
225 | |||
226 | switch (midic) { | ||
227 | case 0xf8: | ||
228 | break; | ||
229 | |||
230 | case 0xf9: | ||
231 | break; | ||
232 | |||
233 | case 0xfc: | ||
234 | break; | ||
235 | |||
236 | default: | ||
237 | break; | ||
238 | } | ||
239 | } else { | ||
240 | mi->m_prev_status = midic; | ||
241 | msg -= 8; | ||
242 | mi->m_left = len_tab[msg]; | ||
243 | |||
244 | mi->m_ptr = 1; | ||
245 | mi->m_buf[0] = midic; | ||
246 | |||
247 | if (mi->m_left <= 0) { | ||
248 | mi->m_state = MST_INIT; | ||
249 | do_midi_msg (synthdev, mi->m_buf, mi->m_ptr); | ||
250 | mi->m_ptr = 0; | ||
251 | } | ||
252 | } | ||
253 | } | ||
254 | break; | ||
255 | |||
256 | case MST_SYSMSG: | ||
257 | switch (midic) { | ||
258 | case 0xf0: | ||
259 | mi->m_state = MST_SYSEX; | ||
260 | break; | ||
261 | |||
262 | case 0xf1: | ||
263 | mi->m_state = MST_MTC; | ||
264 | break; | ||
265 | |||
266 | case 0xf2: | ||
267 | mi->m_state = MST_SONGPOS; | ||
268 | mi->m_ptr = 0; | ||
269 | break; | ||
270 | |||
271 | case 0xf3: | ||
272 | mi->m_state = MST_SONGSEL; | ||
273 | break; | ||
274 | |||
275 | case 0xf6: | ||
276 | mi->m_state = MST_INIT; | ||
277 | |||
278 | /* | ||
279 | * Real time messages | ||
280 | */ | ||
281 | case 0xf8: | ||
282 | /* midi clock */ | ||
283 | mi->m_state = MST_INIT; | ||
284 | /* XXX need ext MIDI timer support */ | ||
285 | break; | ||
286 | |||
287 | case 0xfA: | ||
288 | mi->m_state = MST_INIT; | ||
289 | /* XXX need ext MIDI timer support */ | ||
290 | break; | ||
291 | |||
292 | case 0xFB: | ||
293 | mi->m_state = MST_INIT; | ||
294 | /* XXX need ext MIDI timer support */ | ||
295 | break; | ||
296 | |||
297 | case 0xFC: | ||
298 | mi->m_state = MST_INIT; | ||
299 | /* XXX need ext MIDI timer support */ | ||
300 | break; | ||
301 | |||
302 | case 0xFE: | ||
303 | /* active sensing */ | ||
304 | mi->m_state = MST_INIT; | ||
305 | break; | ||
306 | |||
307 | case 0xff: | ||
308 | mi->m_state = MST_INIT; | ||
309 | break; | ||
310 | |||
311 | default: | ||
312 | printk (KERN_ERR "unknown MIDI sysmsg %0x\n", midic); | ||
313 | mi->m_state = MST_INIT; | ||
314 | } | ||
315 | break; | ||
316 | |||
317 | case MST_MTC: | ||
318 | mi->m_state = MST_INIT; | ||
319 | break; | ||
320 | |||
321 | case MST_SYSEX: | ||
322 | if (midic == 0xf7) { | ||
323 | mi->m_state = MST_INIT; | ||
324 | } else { | ||
325 | /* XXX fix me */ | ||
326 | } | ||
327 | break; | ||
328 | |||
329 | case MST_SONGPOS: | ||
330 | BUFTEST (mi); | ||
331 | mi->m_buf[mi->m_ptr++] = midic; | ||
332 | if (mi->m_ptr == 2) { | ||
333 | mi->m_state = MST_INIT; | ||
334 | mi->m_ptr = 0; | ||
335 | /* XXX need ext MIDI timer support */ | ||
336 | } | ||
337 | break; | ||
338 | |||
339 | case MST_DATA: | ||
340 | BUFTEST (mi); | ||
341 | mi->m_buf[mi->m_ptr++] = midic; | ||
342 | if ((--mi->m_left) <= 0) { | ||
343 | mi->m_state = MST_INIT; | ||
344 | do_midi_msg (synthdev, mi->m_buf, mi->m_ptr); | ||
345 | mi->m_ptr = 0; | ||
346 | } | ||
347 | break; | ||
348 | |||
349 | default: | ||
350 | printk (KERN_ERR "Bad state %d ", mi->m_state); | ||
351 | mi->m_state = MST_INIT; | ||
352 | } | ||
353 | |||
354 | return 1; | ||
355 | } | ||
356 | |||
357 | static irqreturn_t | ||
358 | wf_mpuintr(int irq, void *dev_id, struct pt_regs *dummy) | ||
359 | |||
360 | { | ||
361 | struct wf_mpu_config *physical_dev = dev_id; | ||
362 | static struct wf_mpu_config *input_dev; | ||
363 | struct midi_input_info *mi = &midi_devs[physical_dev->devno]->in_info; | ||
364 | int n; | ||
365 | |||
366 | if (!input_avail()) { /* not for us */ | ||
367 | return IRQ_NONE; | ||
368 | } | ||
369 | |||
370 | if (mi->m_busy) | ||
371 | return IRQ_HANDLED; | ||
372 | spin_lock(&lock); | ||
373 | mi->m_busy = 1; | ||
374 | |||
375 | if (!input_dev) { | ||
376 | input_dev = physical_dev; | ||
377 | } | ||
378 | |||
379 | n = 50; /* XXX why ? */ | ||
380 | |||
381 | do { | ||
382 | unsigned char c = read_data (); | ||
383 | |||
384 | if (phys_dev->isvirtual) { | ||
385 | |||
386 | if (c == WF_EXTERNAL_SWITCH) { | ||
387 | input_dev = virt_dev; | ||
388 | continue; | ||
389 | } else if (c == WF_INTERNAL_SWITCH) { | ||
390 | input_dev = phys_dev; | ||
391 | continue; | ||
392 | } /* else just leave it as it is */ | ||
393 | |||
394 | } else { | ||
395 | input_dev = phys_dev; | ||
396 | } | ||
397 | |||
398 | if (input_dev->mode == MODE_SYNTH) { | ||
399 | |||
400 | wf_mpu_input_scanner (input_dev->devno, | ||
401 | input_dev->synthno, c); | ||
402 | |||
403 | } else if (input_dev->opened & OPEN_READ) { | ||
404 | |||
405 | if (input_dev->inputintr) { | ||
406 | input_dev->inputintr (input_dev->devno, c); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | } while (input_avail() && n-- > 0); | ||
411 | |||
412 | mi->m_busy = 0; | ||
413 | spin_unlock(&lock); | ||
414 | return IRQ_HANDLED; | ||
415 | } | ||
416 | |||
417 | static int | ||
418 | wf_mpu_open (int dev, int mode, | ||
419 | void (*input) (int dev, unsigned char data), | ||
420 | void (*output) (int dev) | ||
421 | ) | ||
422 | { | ||
423 | struct wf_mpu_config *devc; | ||
424 | |||
425 | if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL) | ||
426 | return -(ENXIO); | ||
427 | |||
428 | if (phys_dev->devno == dev) { | ||
429 | devc = phys_dev; | ||
430 | } else if (phys_dev->isvirtual && virt_dev->devno == dev) { | ||
431 | devc = virt_dev; | ||
432 | } else { | ||
433 | printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev); | ||
434 | return -(EINVAL); | ||
435 | } | ||
436 | |||
437 | if (devc->opened) { | ||
438 | return -(EBUSY); | ||
439 | } | ||
440 | |||
441 | devc->mode = MODE_MIDI; | ||
442 | devc->opened = mode; | ||
443 | devc->synthno = 0; | ||
444 | |||
445 | devc->inputintr = input; | ||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | static void | ||
450 | wf_mpu_close (int dev) | ||
451 | { | ||
452 | struct wf_mpu_config *devc; | ||
453 | |||
454 | if (dev < 0 || dev >= num_midis || midi_devs[dev]==NULL) | ||
455 | return; | ||
456 | |||
457 | if (phys_dev->devno == dev) { | ||
458 | devc = phys_dev; | ||
459 | } else if (phys_dev->isvirtual && virt_dev->devno == dev) { | ||
460 | devc = virt_dev; | ||
461 | } else { | ||
462 | printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev); | ||
463 | return; | ||
464 | } | ||
465 | |||
466 | devc->mode = 0; | ||
467 | devc->inputintr = NULL; | ||
468 | devc->opened = 0; | ||
469 | } | ||
470 | |||
471 | static int | ||
472 | wf_mpu_out (int dev, unsigned char midi_byte) | ||
473 | { | ||
474 | int timeout; | ||
475 | unsigned long flags; | ||
476 | static int lastoutdev = -1; | ||
477 | unsigned char switchch; | ||
478 | |||
479 | if (phys_dev->isvirtual && lastoutdev != dev) { | ||
480 | |||
481 | if (dev == phys_dev->devno) { | ||
482 | switchch = WF_INTERNAL_SWITCH; | ||
483 | } else if (dev == virt_dev->devno) { | ||
484 | switchch = WF_EXTERNAL_SWITCH; | ||
485 | } else { | ||
486 | printk (KERN_ERR "WF-MPU: bad device number %d", dev); | ||
487 | return (0); | ||
488 | } | ||
489 | |||
490 | /* XXX fix me */ | ||
491 | |||
492 | for (timeout = 30000; timeout > 0 && !output_ready (); | ||
493 | timeout--); | ||
494 | |||
495 | spin_lock_irqsave(&lock,flags); | ||
496 | |||
497 | if (!output_ready ()) { | ||
498 | printk (KERN_WARNING "WF-MPU: Send switch " | ||
499 | "byte timeout\n"); | ||
500 | spin_unlock_irqrestore(&lock,flags); | ||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | write_data (switchch); | ||
505 | spin_unlock_irqrestore(&lock,flags); | ||
506 | } | ||
507 | |||
508 | lastoutdev = dev; | ||
509 | |||
510 | /* | ||
511 | * Sometimes it takes about 30000 loops before the output becomes ready | ||
512 | * (After reset). Normally it takes just about 10 loops. | ||
513 | */ | ||
514 | |||
515 | /* XXX fix me */ | ||
516 | |||
517 | for (timeout = 30000; timeout > 0 && !output_ready (); timeout--); | ||
518 | |||
519 | spin_lock_irqsave(&lock,flags); | ||
520 | if (!output_ready ()) { | ||
521 | spin_unlock_irqrestore(&lock,flags); | ||
522 | printk (KERN_WARNING "WF-MPU: Send data timeout\n"); | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | write_data (midi_byte); | ||
527 | spin_unlock_irqrestore(&lock,flags); | ||
528 | |||
529 | return 1; | ||
530 | } | ||
531 | |||
532 | static inline int wf_mpu_start_read (int dev) { | ||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | static inline int wf_mpu_end_read (int dev) { | ||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | static int wf_mpu_ioctl (int dev, unsigned cmd, void __user *arg) | ||
541 | { | ||
542 | printk (KERN_WARNING | ||
543 | "WF-MPU: Intelligent mode not supported by hardware.\n"); | ||
544 | return -(EINVAL); | ||
545 | } | ||
546 | |||
547 | static int wf_mpu_buffer_status (int dev) | ||
548 | { | ||
549 | return 0; | ||
550 | } | ||
551 | |||
552 | static struct synth_operations wf_mpu_synth_operations[2]; | ||
553 | static struct midi_operations wf_mpu_midi_operations[2]; | ||
554 | |||
555 | static struct midi_operations wf_mpu_midi_proto = | ||
556 | { | ||
557 | .owner = THIS_MODULE, | ||
558 | .info = {"WF-MPU MIDI", 0, MIDI_CAP_MPU401, SNDCARD_MPU401}, | ||
559 | .in_info = {0}, /* in_info */ | ||
560 | .open = wf_mpu_open, | ||
561 | .close = wf_mpu_close, | ||
562 | .ioctl = wf_mpu_ioctl, | ||
563 | .outputc = wf_mpu_out, | ||
564 | .start_read = wf_mpu_start_read, | ||
565 | .end_read = wf_mpu_end_read, | ||
566 | .buffer_status = wf_mpu_buffer_status, | ||
567 | }; | ||
568 | |||
569 | static struct synth_info wf_mpu_synth_info_proto = | ||
570 | {"WaveFront MPU-401 interface", 0, | ||
571 | SYNTH_TYPE_MIDI, MIDI_TYPE_MPU401, 0, 128, 0, 128, SYNTH_CAP_INPUT}; | ||
572 | |||
573 | static struct synth_info wf_mpu_synth_info[2]; | ||
574 | |||
575 | static int | ||
576 | wf_mpu_synth_ioctl (int dev, unsigned int cmd, void __user *arg) | ||
577 | { | ||
578 | int midi_dev; | ||
579 | int index; | ||
580 | |||
581 | midi_dev = synth_devs[dev]->midi_dev; | ||
582 | |||
583 | if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL) | ||
584 | return -(ENXIO); | ||
585 | |||
586 | if (midi_dev == phys_dev->devno) { | ||
587 | index = 0; | ||
588 | } else if (phys_dev->isvirtual && midi_dev == virt_dev->devno) { | ||
589 | index = 1; | ||
590 | } else { | ||
591 | return -(EINVAL); | ||
592 | } | ||
593 | |||
594 | switch (cmd) { | ||
595 | |||
596 | case SNDCTL_SYNTH_INFO: | ||
597 | if (copy_to_user(arg, | ||
598 | &wf_mpu_synth_info[index], | ||
599 | sizeof (struct synth_info))) | ||
600 | return -EFAULT; | ||
601 | return 0; | ||
602 | |||
603 | case SNDCTL_SYNTH_MEMAVL: | ||
604 | return 0x7fffffff; | ||
605 | |||
606 | default: | ||
607 | return -EINVAL; | ||
608 | } | ||
609 | } | ||
610 | |||
611 | static int | ||
612 | wf_mpu_synth_open (int dev, int mode) | ||
613 | { | ||
614 | int midi_dev; | ||
615 | struct wf_mpu_config *devc; | ||
616 | |||
617 | midi_dev = synth_devs[dev]->midi_dev; | ||
618 | |||
619 | if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev]==NULL) { | ||
620 | return -(ENXIO); | ||
621 | } | ||
622 | |||
623 | if (phys_dev->devno == midi_dev) { | ||
624 | devc = phys_dev; | ||
625 | } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) { | ||
626 | devc = virt_dev; | ||
627 | } else { | ||
628 | printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev); | ||
629 | return -(EINVAL); | ||
630 | } | ||
631 | |||
632 | if (devc->opened) { | ||
633 | return -(EBUSY); | ||
634 | } | ||
635 | |||
636 | devc->mode = MODE_SYNTH; | ||
637 | devc->synthno = dev; | ||
638 | devc->opened = mode; | ||
639 | devc->inputintr = NULL; | ||
640 | return 0; | ||
641 | } | ||
642 | |||
643 | static void | ||
644 | wf_mpu_synth_close (int dev) | ||
645 | { | ||
646 | int midi_dev; | ||
647 | struct wf_mpu_config *devc; | ||
648 | |||
649 | midi_dev = synth_devs[dev]->midi_dev; | ||
650 | |||
651 | if (phys_dev->devno == midi_dev) { | ||
652 | devc = phys_dev; | ||
653 | } else if (phys_dev->isvirtual && virt_dev->devno == midi_dev) { | ||
654 | devc = virt_dev; | ||
655 | } else { | ||
656 | printk (KERN_ERR "WF-MPU: unknown device number %d\n", dev); | ||
657 | return; | ||
658 | } | ||
659 | |||
660 | devc->inputintr = NULL; | ||
661 | devc->opened = 0; | ||
662 | devc->mode = 0; | ||
663 | } | ||
664 | |||
665 | #define _MIDI_SYNTH_C_ | ||
666 | #define MIDI_SYNTH_NAME "WaveFront (MIDI)" | ||
667 | #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT | ||
668 | #include "midi_synth.h" | ||
669 | |||
670 | static struct synth_operations wf_mpu_synth_proto = | ||
671 | { | ||
672 | .owner = THIS_MODULE, | ||
673 | .id = "WaveFront (ICS2115)", | ||
674 | .info = NULL, /* info field, filled in during configuration */ | ||
675 | .midi_dev = 0, /* MIDI dev XXX should this be -1 ? */ | ||
676 | .synth_type = SYNTH_TYPE_MIDI, | ||
677 | .synth_subtype = SAMPLE_TYPE_WAVEFRONT, | ||
678 | .open = wf_mpu_synth_open, | ||
679 | .close = wf_mpu_synth_close, | ||
680 | .ioctl = wf_mpu_synth_ioctl, | ||
681 | .kill_note = midi_synth_kill_note, | ||
682 | .start_note = midi_synth_start_note, | ||
683 | .set_instr = midi_synth_set_instr, | ||
684 | .reset = midi_synth_reset, | ||
685 | .hw_control = midi_synth_hw_control, | ||
686 | .load_patch = midi_synth_load_patch, | ||
687 | .aftertouch = midi_synth_aftertouch, | ||
688 | .controller = midi_synth_controller, | ||
689 | .panning = midi_synth_panning, | ||
690 | .bender = midi_synth_bender, | ||
691 | .setup_voice = midi_synth_setup_voice, | ||
692 | .send_sysex = midi_synth_send_sysex | ||
693 | }; | ||
694 | |||
695 | static int | ||
696 | config_wf_mpu (struct wf_mpu_config *dev) | ||
697 | |||
698 | { | ||
699 | int is_external; | ||
700 | char *name; | ||
701 | int index; | ||
702 | |||
703 | if (dev == phys_dev) { | ||
704 | name = "WaveFront internal MIDI"; | ||
705 | is_external = 0; | ||
706 | index = 0; | ||
707 | memcpy ((char *) &wf_mpu_synth_operations[index], | ||
708 | (char *) &wf_mpu_synth_proto, | ||
709 | sizeof (struct synth_operations)); | ||
710 | } else { | ||
711 | name = "WaveFront external MIDI"; | ||
712 | is_external = 1; | ||
713 | index = 1; | ||
714 | /* no synth operations for an external MIDI interface */ | ||
715 | } | ||
716 | |||
717 | memcpy ((char *) &wf_mpu_synth_info[dev->devno], | ||
718 | (char *) &wf_mpu_synth_info_proto, | ||
719 | sizeof (struct synth_info)); | ||
720 | |||
721 | strcpy (wf_mpu_synth_info[index].name, name); | ||
722 | |||
723 | wf_mpu_synth_operations[index].midi_dev = dev->devno; | ||
724 | wf_mpu_synth_operations[index].info = &wf_mpu_synth_info[index]; | ||
725 | |||
726 | memcpy ((char *) &wf_mpu_midi_operations[index], | ||
727 | (char *) &wf_mpu_midi_proto, | ||
728 | sizeof (struct midi_operations)); | ||
729 | |||
730 | if (is_external) { | ||
731 | wf_mpu_midi_operations[index].converter = NULL; | ||
732 | } else { | ||
733 | wf_mpu_midi_operations[index].converter = | ||
734 | &wf_mpu_synth_operations[index]; | ||
735 | } | ||
736 | |||
737 | strcpy (wf_mpu_midi_operations[index].info.name, name); | ||
738 | |||
739 | midi_devs[dev->devno] = &wf_mpu_midi_operations[index]; | ||
740 | midi_devs[dev->devno]->in_info.m_busy = 0; | ||
741 | midi_devs[dev->devno]->in_info.m_state = MST_INIT; | ||
742 | midi_devs[dev->devno]->in_info.m_ptr = 0; | ||
743 | midi_devs[dev->devno]->in_info.m_left = 0; | ||
744 | midi_devs[dev->devno]->in_info.m_prev_status = 0; | ||
745 | |||
746 | devs[index].opened = 0; | ||
747 | devs[index].mode = 0; | ||
748 | |||
749 | return (0); | ||
750 | } | ||
751 | |||
752 | int virtual_midi_enable (void) | ||
753 | |||
754 | { | ||
755 | if ((virt_dev->devno < 0) && | ||
756 | (virt_dev->devno = sound_alloc_mididev()) == -1) { | ||
757 | printk (KERN_ERR | ||
758 | "WF-MPU: too many midi devices detected\n"); | ||
759 | return -1; | ||
760 | } | ||
761 | |||
762 | config_wf_mpu (virt_dev); | ||
763 | |||
764 | phys_dev->isvirtual = 1; | ||
765 | return virt_dev->devno; | ||
766 | } | ||
767 | |||
768 | int | ||
769 | virtual_midi_disable (void) | ||
770 | |||
771 | { | ||
772 | unsigned long flags; | ||
773 | |||
774 | spin_lock_irqsave(&lock,flags); | ||
775 | |||
776 | wf_mpu_close (virt_dev->devno); | ||
777 | /* no synth on virt_dev, so no need to call wf_mpu_synth_close() */ | ||
778 | phys_dev->isvirtual = 0; | ||
779 | |||
780 | spin_unlock_irqrestore(&lock,flags); | ||
781 | |||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | int __init detect_wf_mpu (int irq, int io_base) | ||
786 | { | ||
787 | if (!request_region(io_base, 2, "wavefront midi")) { | ||
788 | printk (KERN_WARNING "WF-MPU: I/O port %x already in use.\n", | ||
789 | io_base); | ||
790 | return -1; | ||
791 | } | ||
792 | |||
793 | phys_dev->base = io_base; | ||
794 | phys_dev->irq = irq; | ||
795 | phys_dev->devno = -1; | ||
796 | virt_dev->devno = -1; | ||
797 | |||
798 | return 0; | ||
799 | } | ||
800 | |||
801 | int __init install_wf_mpu (void) | ||
802 | { | ||
803 | if ((phys_dev->devno = sound_alloc_mididev()) < 0){ | ||
804 | |||
805 | printk (KERN_ERR "WF-MPU: Too many MIDI devices detected.\n"); | ||
806 | release_region(phys_dev->base, 2); | ||
807 | return -1; | ||
808 | } | ||
809 | |||
810 | phys_dev->isvirtual = 0; | ||
811 | |||
812 | if (config_wf_mpu (phys_dev)) { | ||
813 | |||
814 | printk (KERN_WARNING | ||
815 | "WF-MPU: configuration for MIDI device %d failed\n", | ||
816 | phys_dev->devno); | ||
817 | sound_unload_mididev (phys_dev->devno); | ||
818 | |||
819 | } | ||
820 | |||
821 | /* OK, now we're configured to handle an interrupt ... */ | ||
822 | |||
823 | if (request_irq (phys_dev->irq, wf_mpuintr, IRQF_DISABLED|IRQF_SHARED, | ||
824 | "wavefront midi", phys_dev) < 0) { | ||
825 | |||
826 | printk (KERN_ERR "WF-MPU: Failed to allocate IRQ%d\n", | ||
827 | phys_dev->irq); | ||
828 | return -1; | ||
829 | |||
830 | } | ||
831 | |||
832 | /* This being a WaveFront (ICS-2115) emulated MPU-401, we have | ||
833 | to switch it into UART (dumb) mode, because otherwise, it | ||
834 | won't do anything at all. | ||
835 | */ | ||
836 | |||
837 | start_uart_mode (); | ||
838 | |||
839 | return phys_dev->devno; | ||
840 | } | ||
841 | |||
842 | void | ||
843 | uninstall_wf_mpu (void) | ||
844 | |||
845 | { | ||
846 | release_region (phys_dev->base, 2); | ||
847 | free_irq (phys_dev->irq, phys_dev); | ||
848 | sound_unload_mididev (phys_dev->devno); | ||
849 | |||
850 | if (virt_dev->devno >= 0) { | ||
851 | sound_unload_mididev (virt_dev->devno); | ||
852 | } | ||
853 | } | ||
854 | |||
855 | static void | ||
856 | start_uart_mode (void) | ||
857 | |||
858 | { | ||
859 | int ok, i; | ||
860 | unsigned long flags; | ||
861 | |||
862 | spin_lock_irqsave(&lock,flags); | ||
863 | |||
864 | /* XXX fix me */ | ||
865 | |||
866 | for (i = 0; i < 30000 && !output_ready (); i++); | ||
867 | |||
868 | outb (UART_MODE_ON, COMDPORT(phys_dev)); | ||
869 | |||
870 | for (ok = 0, i = 50000; i > 0 && !ok; i--) { | ||
871 | if (input_avail ()) { | ||
872 | if (read_data () == MPU_ACK) { | ||
873 | ok = 1; | ||
874 | } | ||
875 | } | ||
876 | } | ||
877 | |||
878 | spin_unlock_irqrestore(&lock,flags); | ||
879 | } | ||
880 | #endif | ||
diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c deleted file mode 100644 index 6e22472df952..000000000000 --- a/sound/oss/ymfpci.c +++ /dev/null | |||
@@ -1,2692 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 1999 Jaroslav Kysela <perex@suse.cz> | ||
3 | * Copyright 2000 Alan Cox <alan@redhat.com> | ||
4 | * Copyright 2001 Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de> | ||
5 | * Copyright 2002 Pete Zaitcev <zaitcev@yahoo.com> | ||
6 | * | ||
7 | * Yamaha YMF7xx driver. | ||
8 | * | ||
9 | * This code is a result of high-speed collision | ||
10 | * between ymfpci.c of ALSA and cs46xx.c of Linux. | ||
11 | * -- Pete Zaitcev <zaitcev@yahoo.com>; 2000/09/18 | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | * | ||
27 | * TODO: | ||
28 | * - Use P44Slot for 44.1 playback (beware of idle buzzing in P44Slot). | ||
29 | * - 96KHz playback for DVD - use pitch of 2.0. | ||
30 | * - Retain DMA buffer on close, do not wait the end of frame. | ||
31 | * - Resolve XXX tagged questions. | ||
32 | * - Cannot play 5133Hz. | ||
33 | * - 2001/01/07 Consider if we can remove voice_lock, like so: | ||
34 | * : Allocate/deallocate voices in open/close under semafore. | ||
35 | * : We access voices in interrupt, that only for pcms that open. | ||
36 | * voice_lock around playback_prepare closes interrupts for insane duration. | ||
37 | * - Revisit the way voice_alloc is done - too confusing, overcomplicated. | ||
38 | * Should support various channel types, however. | ||
39 | * - Remove prog_dmabuf from read/write, leave it in open. | ||
40 | * - 2001/01/07 Replace the OPL3 part of CONFIG_SOUND_YMFPCI_LEGACY code with | ||
41 | * native synthesizer through a playback slot. | ||
42 | * - 2001/11/29 ac97_save_state | ||
43 | * Talk to Kai to remove ac97_save_state before it's too late! | ||
44 | * - Second AC97 | ||
45 | * - Restore S/PDIF - Toshibas have it. | ||
46 | * | ||
47 | * Kai used pci_alloc_consistent for DMA buffer, which sounds a little | ||
48 | * unconventional. However, given how small our fragments can be, | ||
49 | * a little uncached access is perhaps better than endless flushing. | ||
50 | * On i386 and other I/O-coherent architectures pci_alloc_consistent | ||
51 | * is entirely harmless. | ||
52 | */ | ||
53 | |||
54 | #include <linux/config.h> | ||
55 | #include <linux/module.h> | ||
56 | #include <linux/init.h> | ||
57 | #include <linux/interrupt.h> | ||
58 | #include <linux/ioport.h> | ||
59 | #include <linux/delay.h> | ||
60 | #include <linux/pci.h> | ||
61 | #include <linux/slab.h> | ||
62 | #include <linux/poll.h> | ||
63 | #include <linux/soundcard.h> | ||
64 | #include <linux/ac97_codec.h> | ||
65 | #include <linux/sound.h> | ||
66 | |||
67 | #include <asm/io.h> | ||
68 | #include <asm/dma.h> | ||
69 | #include <asm/uaccess.h> | ||
70 | |||
71 | #ifdef CONFIG_SOUND_YMFPCI_LEGACY | ||
72 | # include "sound_config.h" | ||
73 | # include "mpu401.h" | ||
74 | #endif | ||
75 | #include "ymfpci.h" | ||
76 | |||
77 | /* | ||
78 | * I do not believe in debug levels as I never can guess what | ||
79 | * part of the code is going to be problematic in the future. | ||
80 | * Don't forget to run your klogd with -c 8. | ||
81 | * | ||
82 | * Example (do not remove): | ||
83 | * #define YMFDBG(fmt, arg...) do{ printk(KERN_DEBUG fmt, ##arg); }while(0) | ||
84 | */ | ||
85 | #define YMFDBGW(fmt, arg...) /* */ /* write counts */ | ||
86 | #define YMFDBGI(fmt, arg...) /* */ /* interrupts */ | ||
87 | #define YMFDBGX(fmt, arg...) /* */ /* ioctl */ | ||
88 | |||
89 | static int ymf_playback_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd); | ||
90 | static void ymf_capture_trigger(ymfpci_t *unit, struct ymf_pcm *ypcm, int cmd); | ||
91 | static void ymfpci_voice_free(ymfpci_t *unit, ymfpci_voice_t *pvoice); | ||
92 | static int ymf_capture_alloc(struct ymf_unit *unit, int *pbank); | ||
93 | static int ymf_playback_prepare(struct ymf_state *state); | ||
94 | static int ymf_capture_prepare(struct ymf_state *state); | ||
95 | static struct ymf_state *ymf_state_alloc(ymfpci_t *unit); | ||
96 | |||
97 | static void ymfpci_aclink_reset(struct pci_dev * pci); | ||
98 | static void ymfpci_disable_dsp(ymfpci_t *unit); | ||
99 | static void ymfpci_download_image(ymfpci_t *codec); | ||
100 | static void ymf_memload(ymfpci_t *unit); | ||
101 | |||
102 | static DEFINE_SPINLOCK(ymf_devs_lock); | ||
103 | static LIST_HEAD(ymf_devs); | ||
104 | |||
105 | /* | ||
106 | * constants | ||
107 | */ | ||
108 | |||
109 | static struct pci_device_id ymf_id_tbl[] = { | ||
110 | #define DEV(dev, data) \ | ||
111 | { PCI_VENDOR_ID_YAMAHA, dev, PCI_ANY_ID, PCI_ANY_ID, 0, 0, \ | ||
112 | (unsigned long)data } | ||
113 | DEV (PCI_DEVICE_ID_YAMAHA_724, "YMF724"), | ||
114 | DEV (PCI_DEVICE_ID_YAMAHA_724F, "YMF724F"), | ||
115 | DEV (PCI_DEVICE_ID_YAMAHA_740, "YMF740"), | ||
116 | DEV (PCI_DEVICE_ID_YAMAHA_740C, "YMF740C"), | ||
117 | DEV (PCI_DEVICE_ID_YAMAHA_744, "YMF744"), | ||
118 | DEV (PCI_DEVICE_ID_YAMAHA_754, "YMF754"), | ||
119 | #undef DEV | ||
120 | { } | ||
121 | }; | ||
122 | MODULE_DEVICE_TABLE(pci, ymf_id_tbl); | ||
123 | |||
124 | /* | ||
125 | * common I/O routines | ||
126 | */ | ||
127 | |||
128 | static inline void ymfpci_writeb(ymfpci_t *codec, u32 offset, u8 val) | ||
129 | { | ||
130 | writeb(val, codec->reg_area_virt + offset); | ||
131 | } | ||
132 | |||
133 | static inline u16 ymfpci_readw(ymfpci_t *codec, u32 offset) | ||
134 | { | ||
135 | return readw(codec->reg_area_virt + offset); | ||
136 | } | ||
137 | |||
138 | static inline void ymfpci_writew(ymfpci_t *codec, u32 offset, u16 val) | ||
139 | { | ||
140 | writew(val, codec->reg_area_virt + offset); | ||
141 | } | ||
142 | |||
143 | static inline u32 ymfpci_readl(ymfpci_t *codec, u32 offset) | ||
144 | { | ||
145 | return readl(codec->reg_area_virt + offset); | ||
146 | } | ||
147 | |||
148 | static inline void ymfpci_writel(ymfpci_t *codec, u32 offset, u32 val) | ||
149 | { | ||
150 | writel(val, codec->reg_area_virt + offset); | ||
151 | } | ||
152 | |||
153 | static int ymfpci_codec_ready(ymfpci_t *codec, int secondary, int sched) | ||
154 | { | ||
155 | signed long end_time; | ||
156 | u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; | ||
157 | |||
158 | end_time = jiffies + 3 * (HZ / 4); | ||
159 | do { | ||
160 | if ((ymfpci_readw(codec, reg) & 0x8000) == 0) | ||
161 | return 0; | ||
162 | if (sched) { | ||
163 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
164 | schedule_timeout(1); | ||
165 | } | ||
166 | } while (end_time - (signed long)jiffies >= 0); | ||
167 | printk(KERN_ERR "ymfpci_codec_ready: codec %i is not ready [0x%x]\n", | ||
168 | secondary, ymfpci_readw(codec, reg)); | ||
169 | return -EBUSY; | ||
170 | } | ||
171 | |||
172 | static void ymfpci_codec_write(struct ac97_codec *dev, u8 reg, u16 val) | ||
173 | { | ||
174 | ymfpci_t *codec = dev->private_data; | ||
175 | u32 cmd; | ||
176 | |||
177 | spin_lock(&codec->ac97_lock); | ||
178 | /* XXX Do make use of dev->id */ | ||
179 | ymfpci_codec_ready(codec, 0, 0); | ||
180 | cmd = ((YDSXG_AC97WRITECMD | reg) << 16) | val; | ||
181 | ymfpci_writel(codec, YDSXGR_AC97CMDDATA, cmd); | ||
182 | spin_unlock(&codec->ac97_lock); | ||
183 | } | ||
184 | |||
185 | static u16 _ymfpci_codec_read(ymfpci_t *unit, u8 reg) | ||
186 | { | ||
187 | int i; | ||
188 | |||
189 | if (ymfpci_codec_ready(unit, 0, 0)) | ||
190 | return ~0; | ||
191 | ymfpci_writew(unit, YDSXGR_AC97CMDADR, YDSXG_AC97READCMD | reg); | ||
192 | if (ymfpci_codec_ready(unit, 0, 0)) | ||
193 | return ~0; | ||
194 | if (unit->pci->device == PCI_DEVICE_ID_YAMAHA_744 && unit->rev < 2) { | ||
195 | for (i = 0; i < 600; i++) | ||
196 | ymfpci_readw(unit, YDSXGR_PRISTATUSDATA); | ||
197 | } | ||
198 | return ymfpci_readw(unit, YDSXGR_PRISTATUSDATA); | ||
199 | } | ||
200 | |||
201 | static u16 ymfpci_codec_read(struct ac97_codec *dev, u8 reg) | ||
202 | { | ||
203 | ymfpci_t *unit = dev->private_data; | ||
204 | u16 ret; | ||
205 | |||
206 | spin_lock(&unit->ac97_lock); | ||
207 | ret = _ymfpci_codec_read(unit, reg); | ||
208 | spin_unlock(&unit->ac97_lock); | ||
209 | |||
210 | return ret; | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * Misc routines | ||
215 | */ | ||
216 | |||
217 | /* | ||
218 | * Calculate the actual sampling rate relatetively to the base clock (48kHz). | ||
219 | */ | ||
220 | static u32 ymfpci_calc_delta(u32 rate) | ||
221 | { | ||
222 | switch (rate) { | ||
223 | case 8000: return 0x02aaab00; | ||
224 | case 11025: return 0x03accd00; | ||
225 | case 16000: return 0x05555500; | ||
226 | case 22050: return 0x07599a00; | ||
227 | case 32000: return 0x0aaaab00; | ||
228 | case 44100: return 0x0eb33300; | ||
229 | default: return ((rate << 16) / 48000) << 12; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | static u32 def_rate[8] = { | ||
234 | 100, 2000, 8000, 11025, 16000, 22050, 32000, 48000 | ||
235 | }; | ||
236 | |||
237 | static u32 ymfpci_calc_lpfK(u32 rate) | ||
238 | { | ||
239 | u32 i; | ||
240 | static u32 val[8] = { | ||
241 | 0x00570000, 0x06AA0000, 0x18B20000, 0x20930000, | ||
242 | 0x2B9A0000, 0x35A10000, 0x3EAA0000, 0x40000000 | ||
243 | }; | ||
244 | |||
245 | if (rate == 44100) | ||
246 | return 0x40000000; /* FIXME: What's the right value? */ | ||
247 | for (i = 0; i < 8; i++) | ||
248 | if (rate <= def_rate[i]) | ||
249 | return val[i]; | ||
250 | return val[0]; | ||
251 | } | ||
252 | |||
253 | static u32 ymfpci_calc_lpfQ(u32 rate) | ||
254 | { | ||
255 | u32 i; | ||
256 | static u32 val[8] = { | ||
257 | 0x35280000, 0x34A70000, 0x32020000, 0x31770000, | ||
258 | 0x31390000, 0x31C90000, 0x33D00000, 0x40000000 | ||
259 | }; | ||
260 | |||
261 | if (rate == 44100) | ||
262 | return 0x370A0000; | ||
263 | for (i = 0; i < 8; i++) | ||
264 | if (rate <= def_rate[i]) | ||
265 | return val[i]; | ||
266 | return val[0]; | ||
267 | } | ||
268 | |||
269 | static u32 ymf_calc_lend(u32 rate) | ||
270 | { | ||
271 | return (rate * YMF_SAMPF) / 48000; | ||
272 | } | ||
273 | |||
274 | /* | ||
275 | * We ever allow only a few formats, but let's be generic, for smaller surprise. | ||
276 | */ | ||
277 | static int ymf_pcm_format_width(int format) | ||
278 | { | ||
279 | static int mask16 = AFMT_S16_LE|AFMT_S16_BE|AFMT_U16_LE|AFMT_U16_BE; | ||
280 | |||
281 | if ((format & (format-1)) != 0) { | ||
282 | printk(KERN_ERR "ymfpci: format 0x%x is not a power of 2\n", format); | ||
283 | return 8; | ||
284 | } | ||
285 | |||
286 | if (format == AFMT_IMA_ADPCM) return 4; | ||
287 | if ((format & mask16) != 0) return 16; | ||
288 | return 8; | ||
289 | } | ||
290 | |||
291 | static void ymf_pcm_update_shift(struct ymf_pcm_format *f) | ||
292 | { | ||
293 | f->shift = 0; | ||
294 | if (f->voices == 2) | ||
295 | f->shift++; | ||
296 | if (ymf_pcm_format_width(f->format) == 16) | ||
297 | f->shift++; | ||
298 | } | ||
299 | |||
300 | /* Are you sure 32K is not too much? See if mpg123 skips on loaded systems. */ | ||
301 | #define DMABUF_DEFAULTORDER (15-PAGE_SHIFT) | ||
302 | #define DMABUF_MINORDER 1 | ||
303 | |||
304 | /* | ||
305 | * Allocate DMA buffer | ||
306 | */ | ||
307 | static int alloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf) | ||
308 | { | ||
309 | void *rawbuf = NULL; | ||
310 | dma_addr_t dma_addr; | ||
311 | int order; | ||
312 | struct page *map, *mapend; | ||
313 | |||
314 | /* alloc as big a chunk as we can */ | ||
315 | for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) { | ||
316 | rawbuf = pci_alloc_consistent(unit->pci, PAGE_SIZE << order, &dma_addr); | ||
317 | if (rawbuf) | ||
318 | break; | ||
319 | } | ||
320 | if (!rawbuf) | ||
321 | return -ENOMEM; | ||
322 | |||
323 | #if 0 | ||
324 | printk(KERN_DEBUG "ymfpci: allocated %ld (order = %d) bytes at %p\n", | ||
325 | PAGE_SIZE << order, order, rawbuf); | ||
326 | #endif | ||
327 | |||
328 | dmabuf->ready = dmabuf->mapped = 0; | ||
329 | dmabuf->rawbuf = rawbuf; | ||
330 | dmabuf->dma_addr = dma_addr; | ||
331 | dmabuf->buforder = order; | ||
332 | |||
333 | /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ | ||
334 | mapend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1); | ||
335 | for (map = virt_to_page(rawbuf); map <= mapend; map++) | ||
336 | set_bit(PG_reserved, &map->flags); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | /* | ||
342 | * Free DMA buffer | ||
343 | */ | ||
344 | static void dealloc_dmabuf(ymfpci_t *unit, struct ymf_dmabuf *dmabuf) | ||
345 | { | ||
346 | struct page *map, *mapend; | ||
347 | |||
348 | if (dmabuf->rawbuf) { | ||
349 | /* undo marking the pages as reserved */ | ||
350 | mapend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1); | ||
351 | for (map = virt_to_page(dmabuf->rawbuf); map <= mapend; map++) | ||
352 | clear_bit(PG_reserved, &map->flags); | ||
353 | |||
354 | pci_free_consistent(unit->pci, PAGE_SIZE << dmabuf->buforder, | ||
355 | dmabuf->rawbuf, dmabuf->dma_addr); | ||
356 | } | ||
357 | dmabuf->rawbuf = NULL; | ||
358 | dmabuf->mapped = dmabuf->ready = 0; | ||
359 | } | ||
360 | |||
361 | static int prog_dmabuf(struct ymf_state *state, int rec) | ||
362 | { | ||
363 | struct ymf_dmabuf *dmabuf; | ||
364 | int w_16; | ||
365 | unsigned bufsize; | ||
366 | unsigned long flags; | ||
367 | int redzone, redfrags; | ||
368 | int ret; | ||
369 | |||
370 | w_16 = ymf_pcm_format_width(state->format.format) == 16; | ||
371 | dmabuf = rec ? &state->rpcm.dmabuf : &state->wpcm.dmabuf; | ||
372 | |||
373 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
374 | dmabuf->hwptr = dmabuf->swptr = 0; | ||
375 | dmabuf->total_bytes = 0; | ||
376 | dmabuf->count = 0; | ||
377 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
378 | |||
379 | /* allocate DMA buffer if not allocated yet */ | ||
380 | if (!dmabuf->rawbuf) | ||
381 | if ((ret = alloc_dmabuf(state->unit, dmabuf))) | ||
382 | return ret; | ||
383 | |||
384 | /* | ||
385 | * Create fake fragment sizes and numbers for OSS ioctls. | ||
386 | * Import what Doom might have set with SNDCTL_DSP_SETFRAGMENT. | ||
387 | */ | ||
388 | bufsize = PAGE_SIZE << dmabuf->buforder; | ||
389 | /* By default we give 4 big buffers. */ | ||
390 | dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT - 2); | ||
391 | if (dmabuf->ossfragshift > 3 && | ||
392 | dmabuf->ossfragshift < dmabuf->fragshift) { | ||
393 | /* If OSS set smaller fragments, give more smaller buffers. */ | ||
394 | dmabuf->fragshift = dmabuf->ossfragshift; | ||
395 | } | ||
396 | dmabuf->fragsize = 1 << dmabuf->fragshift; | ||
397 | |||
398 | dmabuf->numfrag = bufsize >> dmabuf->fragshift; | ||
399 | dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift; | ||
400 | |||
401 | if (dmabuf->ossmaxfrags >= 2) { | ||
402 | redzone = ymf_calc_lend(state->format.rate); | ||
403 | redzone <<= state->format.shift; | ||
404 | redzone *= 3; | ||
405 | redfrags = (redzone + dmabuf->fragsize-1) >> dmabuf->fragshift; | ||
406 | |||
407 | if (dmabuf->ossmaxfrags + redfrags < dmabuf->numfrag) { | ||
408 | dmabuf->numfrag = dmabuf->ossmaxfrags + redfrags; | ||
409 | dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | memset(dmabuf->rawbuf, w_16 ? 0 : 0x80, dmabuf->dmasize); | ||
414 | |||
415 | /* | ||
416 | * Now set up the ring | ||
417 | */ | ||
418 | |||
419 | /* XXX ret = rec? cap_pre(): pbk_pre(); */ | ||
420 | spin_lock_irqsave(&state->unit->voice_lock, flags); | ||
421 | if (rec) { | ||
422 | if ((ret = ymf_capture_prepare(state)) != 0) { | ||
423 | spin_unlock_irqrestore(&state->unit->voice_lock, flags); | ||
424 | return ret; | ||
425 | } | ||
426 | } else { | ||
427 | if ((ret = ymf_playback_prepare(state)) != 0) { | ||
428 | spin_unlock_irqrestore(&state->unit->voice_lock, flags); | ||
429 | return ret; | ||
430 | } | ||
431 | } | ||
432 | spin_unlock_irqrestore(&state->unit->voice_lock, flags); | ||
433 | |||
434 | /* set the ready flag for the dma buffer (this comment is not stupid) */ | ||
435 | dmabuf->ready = 1; | ||
436 | |||
437 | #if 0 | ||
438 | printk(KERN_DEBUG "prog_dmabuf: rate %d format 0x%x," | ||
439 | " numfrag %d fragsize %d dmasize %d\n", | ||
440 | state->format.rate, state->format.format, dmabuf->numfrag, | ||
441 | dmabuf->fragsize, dmabuf->dmasize); | ||
442 | #endif | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static void ymf_start_dac(struct ymf_state *state) | ||
448 | { | ||
449 | ymf_playback_trigger(state->unit, &state->wpcm, 1); | ||
450 | } | ||
451 | |||
452 | // static void ymf_start_adc(struct ymf_state *state) | ||
453 | // { | ||
454 | // ymf_capture_trigger(state->unit, &state->rpcm, 1); | ||
455 | // } | ||
456 | |||
457 | /* | ||
458 | * Wait until output is drained. | ||
459 | * This does not kill the hardware for the sake of ioctls. | ||
460 | */ | ||
461 | static void ymf_wait_dac(struct ymf_state *state) | ||
462 | { | ||
463 | struct ymf_unit *unit = state->unit; | ||
464 | struct ymf_pcm *ypcm = &state->wpcm; | ||
465 | DECLARE_WAITQUEUE(waita, current); | ||
466 | unsigned long flags; | ||
467 | |||
468 | add_wait_queue(&ypcm->dmabuf.wait, &waita); | ||
469 | |||
470 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
471 | if (ypcm->dmabuf.count != 0 && !ypcm->running) { | ||
472 | ymf_playback_trigger(unit, ypcm, 1); | ||
473 | } | ||
474 | |||
475 | #if 0 | ||
476 | if (file->f_flags & O_NONBLOCK) { | ||
477 | /* | ||
478 | * XXX Our mistake is to attach DMA buffer to state | ||
479 | * rather than to some per-device structure. | ||
480 | * Cannot skip waiting, can only make it shorter. | ||
481 | */ | ||
482 | } | ||
483 | #endif | ||
484 | |||
485 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
486 | while (ypcm->running) { | ||
487 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
488 | schedule(); | ||
489 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
490 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
491 | } | ||
492 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
493 | |||
494 | set_current_state(TASK_RUNNING); | ||
495 | remove_wait_queue(&ypcm->dmabuf.wait, &waita); | ||
496 | |||
497 | /* | ||
498 | * This function may take up to 4 seconds to reach this point | ||
499 | * (32K circular buffer, 8000 Hz). User notices. | ||
500 | */ | ||
501 | } | ||
502 | |||
503 | /* Can just stop, without wait. Or can we? */ | ||
504 | static void ymf_stop_adc(struct ymf_state *state) | ||
505 | { | ||
506 | struct ymf_unit *unit = state->unit; | ||
507 | unsigned long flags; | ||
508 | |||
509 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
510 | ymf_capture_trigger(unit, &state->rpcm, 0); | ||
511 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * Hardware start management | ||
516 | */ | ||
517 | |||
518 | static void ymfpci_hw_start(ymfpci_t *unit) | ||
519 | { | ||
520 | unsigned long flags; | ||
521 | |||
522 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
523 | if (unit->start_count++ == 0) { | ||
524 | ymfpci_writel(unit, YDSXGR_MODE, | ||
525 | ymfpci_readl(unit, YDSXGR_MODE) | 3); | ||
526 | unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1; | ||
527 | } | ||
528 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
529 | } | ||
530 | |||
531 | static void ymfpci_hw_stop(ymfpci_t *unit) | ||
532 | { | ||
533 | unsigned long flags; | ||
534 | long timeout = 1000; | ||
535 | |||
536 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
537 | if (--unit->start_count == 0) { | ||
538 | ymfpci_writel(unit, YDSXGR_MODE, | ||
539 | ymfpci_readl(unit, YDSXGR_MODE) & ~3); | ||
540 | while (timeout-- > 0) { | ||
541 | if ((ymfpci_readl(unit, YDSXGR_STATUS) & 2) == 0) | ||
542 | break; | ||
543 | } | ||
544 | } | ||
545 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
546 | } | ||
547 | |||
548 | /* | ||
549 | * Playback voice management | ||
550 | */ | ||
551 | |||
552 | static int voice_alloc(ymfpci_t *codec, ymfpci_voice_type_t type, int pair, ymfpci_voice_t *rvoice[]) | ||
553 | { | ||
554 | ymfpci_voice_t *voice, *voice2; | ||
555 | int idx; | ||
556 | |||
557 | for (idx = 0; idx < YDSXG_PLAYBACK_VOICES; idx += pair ? 2 : 1) { | ||
558 | voice = &codec->voices[idx]; | ||
559 | voice2 = pair ? &codec->voices[idx+1] : NULL; | ||
560 | if (voice->use || (voice2 && voice2->use)) | ||
561 | continue; | ||
562 | voice->use = 1; | ||
563 | if (voice2) | ||
564 | voice2->use = 1; | ||
565 | switch (type) { | ||
566 | case YMFPCI_PCM: | ||
567 | voice->pcm = 1; | ||
568 | if (voice2) | ||
569 | voice2->pcm = 1; | ||
570 | break; | ||
571 | case YMFPCI_SYNTH: | ||
572 | voice->synth = 1; | ||
573 | break; | ||
574 | case YMFPCI_MIDI: | ||
575 | voice->midi = 1; | ||
576 | break; | ||
577 | } | ||
578 | ymfpci_hw_start(codec); | ||
579 | rvoice[0] = voice; | ||
580 | if (voice2) { | ||
581 | ymfpci_hw_start(codec); | ||
582 | rvoice[1] = voice2; | ||
583 | } | ||
584 | return 0; | ||
585 | } | ||
586 | return -EBUSY; /* Your audio channel is open by someone else. */ | ||
587 | } | ||
588 | |||
589 | static void ymfpci_voice_free(ymfpci_t *unit, ymfpci_voice_t *pvoice) | ||
590 | { | ||
591 | ymfpci_hw_stop(unit); | ||
592 | pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0; | ||
593 | pvoice->ypcm = NULL; | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | */ | ||
598 | |||
599 | static void ymf_pcm_interrupt(ymfpci_t *codec, ymfpci_voice_t *voice) | ||
600 | { | ||
601 | struct ymf_pcm *ypcm; | ||
602 | int redzone; | ||
603 | int pos, delta, swptr; | ||
604 | int played, distance; | ||
605 | struct ymf_state *state; | ||
606 | struct ymf_dmabuf *dmabuf; | ||
607 | char silence; | ||
608 | |||
609 | if ((ypcm = voice->ypcm) == NULL) { | ||
610 | return; | ||
611 | } | ||
612 | if ((state = ypcm->state) == NULL) { | ||
613 | ypcm->running = 0; // lock it | ||
614 | return; | ||
615 | } | ||
616 | dmabuf = &ypcm->dmabuf; | ||
617 | spin_lock(&codec->reg_lock); | ||
618 | if (ypcm->running) { | ||
619 | YMFDBGI("ymfpci: %d, intr bank %d count %d start 0x%x:%x\n", | ||
620 | voice->number, codec->active_bank, dmabuf->count, | ||
621 | le32_to_cpu(voice->bank[0].start), | ||
622 | le32_to_cpu(voice->bank[1].start)); | ||
623 | silence = (ymf_pcm_format_width(state->format.format) == 16) ? | ||
624 | 0 : 0x80; | ||
625 | /* We need actual left-hand-side redzone size here. */ | ||
626 | redzone = ymf_calc_lend(state->format.rate); | ||
627 | redzone <<= (state->format.shift + 1); | ||
628 | swptr = dmabuf->swptr; | ||
629 | |||
630 | pos = le32_to_cpu(voice->bank[codec->active_bank].start); | ||
631 | pos <<= state->format.shift; | ||
632 | if (pos < 0 || pos >= dmabuf->dmasize) { /* ucode bug */ | ||
633 | printk(KERN_ERR "ymfpci%d: runaway voice %d: hwptr %d=>%d dmasize %d\n", | ||
634 | codec->dev_audio, voice->number, | ||
635 | dmabuf->hwptr, pos, dmabuf->dmasize); | ||
636 | pos = 0; | ||
637 | } | ||
638 | if (pos < dmabuf->hwptr) { | ||
639 | delta = dmabuf->dmasize - dmabuf->hwptr; | ||
640 | memset(dmabuf->rawbuf + dmabuf->hwptr, silence, delta); | ||
641 | delta += pos; | ||
642 | memset(dmabuf->rawbuf, silence, pos); | ||
643 | } else { | ||
644 | delta = pos - dmabuf->hwptr; | ||
645 | memset(dmabuf->rawbuf + dmabuf->hwptr, silence, delta); | ||
646 | } | ||
647 | dmabuf->hwptr = pos; | ||
648 | |||
649 | if (dmabuf->count == 0) { | ||
650 | printk(KERN_ERR "ymfpci%d: %d: strain: hwptr %d\n", | ||
651 | codec->dev_audio, voice->number, dmabuf->hwptr); | ||
652 | ymf_playback_trigger(codec, ypcm, 0); | ||
653 | } | ||
654 | |||
655 | if (swptr <= pos) { | ||
656 | distance = pos - swptr; | ||
657 | } else { | ||
658 | distance = dmabuf->dmasize - (swptr - pos); | ||
659 | } | ||
660 | if (distance < redzone) { | ||
661 | /* | ||
662 | * hwptr inside redzone => DMA ran out of samples. | ||
663 | */ | ||
664 | if (delta < dmabuf->count) { | ||
665 | /* | ||
666 | * Lost interrupt or other screwage. | ||
667 | */ | ||
668 | printk(KERN_ERR "ymfpci%d: %d: lost: delta %d" | ||
669 | " hwptr %d swptr %d distance %d count %d\n", | ||
670 | codec->dev_audio, voice->number, delta, | ||
671 | dmabuf->hwptr, swptr, distance, dmabuf->count); | ||
672 | } else { | ||
673 | /* | ||
674 | * Normal end of DMA. | ||
675 | */ | ||
676 | YMFDBGI("ymfpci%d: %d: done: delta %d" | ||
677 | " hwptr %d swptr %d distance %d count %d\n", | ||
678 | codec->dev_audio, voice->number, delta, | ||
679 | dmabuf->hwptr, swptr, distance, dmabuf->count); | ||
680 | } | ||
681 | played = dmabuf->count; | ||
682 | if (ypcm->running) { | ||
683 | ymf_playback_trigger(codec, ypcm, 0); | ||
684 | } | ||
685 | } else { | ||
686 | /* | ||
687 | * hwptr is chipping away towards a remote swptr. | ||
688 | * Calculate other distance and apply it to count. | ||
689 | */ | ||
690 | if (swptr >= pos) { | ||
691 | distance = swptr - pos; | ||
692 | } else { | ||
693 | distance = dmabuf->dmasize - (pos - swptr); | ||
694 | } | ||
695 | if (distance < dmabuf->count) { | ||
696 | played = dmabuf->count - distance; | ||
697 | } else { | ||
698 | played = 0; | ||
699 | } | ||
700 | } | ||
701 | |||
702 | dmabuf->total_bytes += played; | ||
703 | dmabuf->count -= played; | ||
704 | if (dmabuf->count < dmabuf->dmasize / 2) { | ||
705 | wake_up(&dmabuf->wait); | ||
706 | } | ||
707 | } | ||
708 | spin_unlock(&codec->reg_lock); | ||
709 | } | ||
710 | |||
711 | static void ymf_cap_interrupt(ymfpci_t *unit, struct ymf_capture *cap) | ||
712 | { | ||
713 | struct ymf_pcm *ypcm; | ||
714 | int redzone; | ||
715 | struct ymf_state *state; | ||
716 | struct ymf_dmabuf *dmabuf; | ||
717 | int pos, delta; | ||
718 | int cnt; | ||
719 | |||
720 | if ((ypcm = cap->ypcm) == NULL) { | ||
721 | return; | ||
722 | } | ||
723 | if ((state = ypcm->state) == NULL) { | ||
724 | ypcm->running = 0; // lock it | ||
725 | return; | ||
726 | } | ||
727 | dmabuf = &ypcm->dmabuf; | ||
728 | spin_lock(&unit->reg_lock); | ||
729 | if (ypcm->running) { | ||
730 | redzone = ymf_calc_lend(state->format.rate); | ||
731 | redzone <<= (state->format.shift + 1); | ||
732 | |||
733 | pos = le32_to_cpu(cap->bank[unit->active_bank].start); | ||
734 | // pos <<= state->format.shift; | ||
735 | if (pos < 0 || pos >= dmabuf->dmasize) { /* ucode bug */ | ||
736 | printk(KERN_ERR "ymfpci%d: runaway capture %d: hwptr %d=>%d dmasize %d\n", | ||
737 | unit->dev_audio, ypcm->capture_bank_number, | ||
738 | dmabuf->hwptr, pos, dmabuf->dmasize); | ||
739 | pos = 0; | ||
740 | } | ||
741 | if (pos < dmabuf->hwptr) { | ||
742 | delta = dmabuf->dmasize - dmabuf->hwptr; | ||
743 | delta += pos; | ||
744 | } else { | ||
745 | delta = pos - dmabuf->hwptr; | ||
746 | } | ||
747 | dmabuf->hwptr = pos; | ||
748 | |||
749 | cnt = dmabuf->count; | ||
750 | cnt += delta; | ||
751 | if (cnt + redzone > dmabuf->dmasize) { | ||
752 | /* Overflow - bump swptr */ | ||
753 | dmabuf->count = dmabuf->dmasize - redzone; | ||
754 | dmabuf->swptr = dmabuf->hwptr + redzone; | ||
755 | if (dmabuf->swptr >= dmabuf->dmasize) { | ||
756 | dmabuf->swptr -= dmabuf->dmasize; | ||
757 | } | ||
758 | } else { | ||
759 | dmabuf->count = cnt; | ||
760 | } | ||
761 | |||
762 | dmabuf->total_bytes += delta; | ||
763 | if (dmabuf->count) { /* && is_sleeping XXX */ | ||
764 | wake_up(&dmabuf->wait); | ||
765 | } | ||
766 | } | ||
767 | spin_unlock(&unit->reg_lock); | ||
768 | } | ||
769 | |||
770 | static int ymf_playback_trigger(ymfpci_t *codec, struct ymf_pcm *ypcm, int cmd) | ||
771 | { | ||
772 | |||
773 | if (ypcm->voices[0] == NULL) { | ||
774 | return -EINVAL; | ||
775 | } | ||
776 | if (cmd != 0) { | ||
777 | codec->ctrl_playback[ypcm->voices[0]->number + 1] = | ||
778 | cpu_to_le32(ypcm->voices[0]->bank_ba); | ||
779 | if (ypcm->voices[1] != NULL) | ||
780 | codec->ctrl_playback[ypcm->voices[1]->number + 1] = | ||
781 | cpu_to_le32(ypcm->voices[1]->bank_ba); | ||
782 | ypcm->running = 1; | ||
783 | } else { | ||
784 | codec->ctrl_playback[ypcm->voices[0]->number + 1] = 0; | ||
785 | if (ypcm->voices[1] != NULL) | ||
786 | codec->ctrl_playback[ypcm->voices[1]->number + 1] = 0; | ||
787 | ypcm->running = 0; | ||
788 | } | ||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | static void ymf_capture_trigger(ymfpci_t *codec, struct ymf_pcm *ypcm, int cmd) | ||
793 | { | ||
794 | u32 tmp; | ||
795 | |||
796 | if (cmd != 0) { | ||
797 | tmp = ymfpci_readl(codec, YDSXGR_MAPOFREC) | (1 << ypcm->capture_bank_number); | ||
798 | ymfpci_writel(codec, YDSXGR_MAPOFREC, tmp); | ||
799 | ypcm->running = 1; | ||
800 | } else { | ||
801 | tmp = ymfpci_readl(codec, YDSXGR_MAPOFREC) & ~(1 << ypcm->capture_bank_number); | ||
802 | ymfpci_writel(codec, YDSXGR_MAPOFREC, tmp); | ||
803 | ypcm->running = 0; | ||
804 | } | ||
805 | } | ||
806 | |||
807 | static int ymfpci_pcm_voice_alloc(struct ymf_pcm *ypcm, int voices) | ||
808 | { | ||
809 | struct ymf_unit *unit; | ||
810 | int err; | ||
811 | |||
812 | unit = ypcm->state->unit; | ||
813 | if (ypcm->voices[1] != NULL && voices < 2) { | ||
814 | ymfpci_voice_free(unit, ypcm->voices[1]); | ||
815 | ypcm->voices[1] = NULL; | ||
816 | } | ||
817 | if (voices == 1 && ypcm->voices[0] != NULL) | ||
818 | return 0; /* already allocated */ | ||
819 | if (voices == 2 && ypcm->voices[0] != NULL && ypcm->voices[1] != NULL) | ||
820 | return 0; /* already allocated */ | ||
821 | if (voices > 1) { | ||
822 | if (ypcm->voices[0] != NULL && ypcm->voices[1] == NULL) { | ||
823 | ymfpci_voice_free(unit, ypcm->voices[0]); | ||
824 | ypcm->voices[0] = NULL; | ||
825 | } | ||
826 | if ((err = voice_alloc(unit, YMFPCI_PCM, 1, ypcm->voices)) < 0) | ||
827 | return err; | ||
828 | ypcm->voices[0]->ypcm = ypcm; | ||
829 | ypcm->voices[1]->ypcm = ypcm; | ||
830 | } else { | ||
831 | if ((err = voice_alloc(unit, YMFPCI_PCM, 0, ypcm->voices)) < 0) | ||
832 | return err; | ||
833 | ypcm->voices[0]->ypcm = ypcm; | ||
834 | } | ||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | static void ymf_pcm_init_voice(ymfpci_voice_t *voice, int stereo, | ||
839 | int rate, int w_16, unsigned long addr, unsigned int end, int spdif) | ||
840 | { | ||
841 | u32 format; | ||
842 | u32 delta = ymfpci_calc_delta(rate); | ||
843 | u32 lpfQ = ymfpci_calc_lpfQ(rate); | ||
844 | u32 lpfK = ymfpci_calc_lpfK(rate); | ||
845 | ymfpci_playback_bank_t *bank; | ||
846 | int nbank; | ||
847 | |||
848 | /* | ||
849 | * The gain is a floating point number. According to the manual, | ||
850 | * bit 31 indicates a sign bit, bit 30 indicates an integer part, | ||
851 | * and bits [29:15] indicate a decimal fraction part. Thus, | ||
852 | * for a gain of 1.0 the constant of 0x40000000 is loaded. | ||
853 | */ | ||
854 | unsigned default_gain = cpu_to_le32(0x40000000); | ||
855 | |||
856 | format = (stereo ? 0x00010000 : 0) | (w_16 ? 0 : 0x80000000); | ||
857 | if (stereo) | ||
858 | end >>= 1; | ||
859 | if (w_16) | ||
860 | end >>= 1; | ||
861 | for (nbank = 0; nbank < 2; nbank++) { | ||
862 | bank = &voice->bank[nbank]; | ||
863 | bank->format = cpu_to_le32(format); | ||
864 | bank->loop_default = 0; /* 0-loops forever, otherwise count */ | ||
865 | bank->base = cpu_to_le32(addr); | ||
866 | bank->loop_start = 0; | ||
867 | bank->loop_end = cpu_to_le32(end); | ||
868 | bank->loop_frac = 0; | ||
869 | bank->eg_gain_end = default_gain; | ||
870 | bank->lpfQ = cpu_to_le32(lpfQ); | ||
871 | bank->status = 0; | ||
872 | bank->num_of_frames = 0; | ||
873 | bank->loop_count = 0; | ||
874 | bank->start = 0; | ||
875 | bank->start_frac = 0; | ||
876 | bank->delta = | ||
877 | bank->delta_end = cpu_to_le32(delta); | ||
878 | bank->lpfK = | ||
879 | bank->lpfK_end = cpu_to_le32(lpfK); | ||
880 | bank->eg_gain = default_gain; | ||
881 | bank->lpfD1 = | ||
882 | bank->lpfD2 = 0; | ||
883 | |||
884 | bank->left_gain = | ||
885 | bank->right_gain = | ||
886 | bank->left_gain_end = | ||
887 | bank->right_gain_end = | ||
888 | bank->eff1_gain = | ||
889 | bank->eff2_gain = | ||
890 | bank->eff3_gain = | ||
891 | bank->eff1_gain_end = | ||
892 | bank->eff2_gain_end = | ||
893 | bank->eff3_gain_end = 0; | ||
894 | |||
895 | if (!stereo) { | ||
896 | if (!spdif) { | ||
897 | bank->left_gain = | ||
898 | bank->right_gain = | ||
899 | bank->left_gain_end = | ||
900 | bank->right_gain_end = default_gain; | ||
901 | } else { | ||
902 | bank->eff2_gain = | ||
903 | bank->eff2_gain_end = | ||
904 | bank->eff3_gain = | ||
905 | bank->eff3_gain_end = default_gain; | ||
906 | } | ||
907 | } else { | ||
908 | if (!spdif) { | ||
909 | if ((voice->number & 1) == 0) { | ||
910 | bank->left_gain = | ||
911 | bank->left_gain_end = default_gain; | ||
912 | } else { | ||
913 | bank->format |= cpu_to_le32(1); | ||
914 | bank->right_gain = | ||
915 | bank->right_gain_end = default_gain; | ||
916 | } | ||
917 | } else { | ||
918 | if ((voice->number & 1) == 0) { | ||
919 | bank->eff2_gain = | ||
920 | bank->eff2_gain_end = default_gain; | ||
921 | } else { | ||
922 | bank->format |= cpu_to_le32(1); | ||
923 | bank->eff3_gain = | ||
924 | bank->eff3_gain_end = default_gain; | ||
925 | } | ||
926 | } | ||
927 | } | ||
928 | } | ||
929 | } | ||
930 | |||
931 | /* | ||
932 | * XXX Capture channel allocation is entirely fake at the moment. | ||
933 | * We use only one channel and mark it busy as required. | ||
934 | */ | ||
935 | static int ymf_capture_alloc(struct ymf_unit *unit, int *pbank) | ||
936 | { | ||
937 | struct ymf_capture *cap; | ||
938 | int cbank; | ||
939 | |||
940 | cbank = 1; /* Only ADC slot is used for now. */ | ||
941 | cap = &unit->capture[cbank]; | ||
942 | if (cap->use) | ||
943 | return -EBUSY; | ||
944 | cap->use = 1; | ||
945 | *pbank = cbank; | ||
946 | return 0; | ||
947 | } | ||
948 | |||
949 | static int ymf_playback_prepare(struct ymf_state *state) | ||
950 | { | ||
951 | struct ymf_pcm *ypcm = &state->wpcm; | ||
952 | int err, nvoice; | ||
953 | |||
954 | if ((err = ymfpci_pcm_voice_alloc(ypcm, state->format.voices)) < 0) { | ||
955 | /* Somebody started 32 mpg123's in parallel? */ | ||
956 | printk(KERN_INFO "ymfpci%d: cannot allocate voice\n", | ||
957 | state->unit->dev_audio); | ||
958 | return err; | ||
959 | } | ||
960 | |||
961 | for (nvoice = 0; nvoice < state->format.voices; nvoice++) { | ||
962 | ymf_pcm_init_voice(ypcm->voices[nvoice], | ||
963 | state->format.voices == 2, state->format.rate, | ||
964 | ymf_pcm_format_width(state->format.format) == 16, | ||
965 | ypcm->dmabuf.dma_addr, ypcm->dmabuf.dmasize, | ||
966 | ypcm->spdif); | ||
967 | } | ||
968 | return 0; | ||
969 | } | ||
970 | |||
971 | static int ymf_capture_prepare(struct ymf_state *state) | ||
972 | { | ||
973 | ymfpci_t *unit = state->unit; | ||
974 | struct ymf_pcm *ypcm = &state->rpcm; | ||
975 | ymfpci_capture_bank_t * bank; | ||
976 | /* XXX This is confusing, gotta rename one of them banks... */ | ||
977 | int nbank; /* flip-flop bank */ | ||
978 | int cbank; /* input [super-]bank */ | ||
979 | struct ymf_capture *cap; | ||
980 | u32 rate, format; | ||
981 | |||
982 | if (ypcm->capture_bank_number == -1) { | ||
983 | if (ymf_capture_alloc(unit, &cbank) != 0) | ||
984 | return -EBUSY; | ||
985 | |||
986 | ypcm->capture_bank_number = cbank; | ||
987 | |||
988 | cap = &unit->capture[cbank]; | ||
989 | cap->bank = unit->bank_capture[cbank][0]; | ||
990 | cap->ypcm = ypcm; | ||
991 | ymfpci_hw_start(unit); | ||
992 | } | ||
993 | |||
994 | // ypcm->frag_size = snd_pcm_lib_transfer_fragment(substream); | ||
995 | // frag_size is replaced with nonfragged byte-aligned rolling buffer | ||
996 | rate = ((48000 * 4096) / state->format.rate) - 1; | ||
997 | format = 0; | ||
998 | if (state->format.voices == 2) | ||
999 | format |= 2; | ||
1000 | if (ymf_pcm_format_width(state->format.format) == 8) | ||
1001 | format |= 1; | ||
1002 | switch (ypcm->capture_bank_number) { | ||
1003 | case 0: | ||
1004 | ymfpci_writel(unit, YDSXGR_RECFORMAT, format); | ||
1005 | ymfpci_writel(unit, YDSXGR_RECSLOTSR, rate); | ||
1006 | break; | ||
1007 | case 1: | ||
1008 | ymfpci_writel(unit, YDSXGR_ADCFORMAT, format); | ||
1009 | ymfpci_writel(unit, YDSXGR_ADCSLOTSR, rate); | ||
1010 | break; | ||
1011 | } | ||
1012 | for (nbank = 0; nbank < 2; nbank++) { | ||
1013 | bank = unit->bank_capture[ypcm->capture_bank_number][nbank]; | ||
1014 | bank->base = cpu_to_le32(ypcm->dmabuf.dma_addr); | ||
1015 | // bank->loop_end = ypcm->dmabuf.dmasize >> state->format.shift; | ||
1016 | bank->loop_end = cpu_to_le32(ypcm->dmabuf.dmasize); | ||
1017 | bank->start = 0; | ||
1018 | bank->num_of_loops = 0; | ||
1019 | } | ||
1020 | #if 0 /* s/pdif */ | ||
1021 | if (state->digital.dig_valid) | ||
1022 | /*state->digital.type == SND_PCM_DIG_AES_IEC958*/ | ||
1023 | ymfpci_writew(codec, YDSXGR_SPDIFOUTSTATUS, | ||
1024 | state->digital.dig_status[0] | (state->digital.dig_status[1] << 8)); | ||
1025 | #endif | ||
1026 | return 0; | ||
1027 | } | ||
1028 | |||
1029 | static irqreturn_t ymf_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
1030 | { | ||
1031 | ymfpci_t *codec = dev_id; | ||
1032 | u32 status, nvoice, mode; | ||
1033 | struct ymf_voice *voice; | ||
1034 | struct ymf_capture *cap; | ||
1035 | |||
1036 | status = ymfpci_readl(codec, YDSXGR_STATUS); | ||
1037 | if (status & 0x80000000) { | ||
1038 | codec->active_bank = ymfpci_readl(codec, YDSXGR_CTRLSELECT) & 1; | ||
1039 | spin_lock(&codec->voice_lock); | ||
1040 | for (nvoice = 0; nvoice < YDSXG_PLAYBACK_VOICES; nvoice++) { | ||
1041 | voice = &codec->voices[nvoice]; | ||
1042 | if (voice->use) | ||
1043 | ymf_pcm_interrupt(codec, voice); | ||
1044 | } | ||
1045 | for (nvoice = 0; nvoice < YDSXG_CAPTURE_VOICES; nvoice++) { | ||
1046 | cap = &codec->capture[nvoice]; | ||
1047 | if (cap->use) | ||
1048 | ymf_cap_interrupt(codec, cap); | ||
1049 | } | ||
1050 | spin_unlock(&codec->voice_lock); | ||
1051 | spin_lock(&codec->reg_lock); | ||
1052 | ymfpci_writel(codec, YDSXGR_STATUS, 0x80000000); | ||
1053 | mode = ymfpci_readl(codec, YDSXGR_MODE) | 2; | ||
1054 | ymfpci_writel(codec, YDSXGR_MODE, mode); | ||
1055 | spin_unlock(&codec->reg_lock); | ||
1056 | } | ||
1057 | |||
1058 | status = ymfpci_readl(codec, YDSXGR_INTFLAG); | ||
1059 | if (status & 1) { | ||
1060 | /* timer handler */ | ||
1061 | ymfpci_writel(codec, YDSXGR_INTFLAG, ~0); | ||
1062 | } | ||
1063 | return IRQ_HANDLED; | ||
1064 | } | ||
1065 | |||
1066 | static void ymf_pcm_free_substream(struct ymf_pcm *ypcm) | ||
1067 | { | ||
1068 | unsigned long flags; | ||
1069 | struct ymf_unit *unit; | ||
1070 | |||
1071 | unit = ypcm->state->unit; | ||
1072 | |||
1073 | if (ypcm->type == PLAYBACK_VOICE) { | ||
1074 | spin_lock_irqsave(&unit->voice_lock, flags); | ||
1075 | if (ypcm->voices[1]) | ||
1076 | ymfpci_voice_free(unit, ypcm->voices[1]); | ||
1077 | if (ypcm->voices[0]) | ||
1078 | ymfpci_voice_free(unit, ypcm->voices[0]); | ||
1079 | spin_unlock_irqrestore(&unit->voice_lock, flags); | ||
1080 | } else { | ||
1081 | if (ypcm->capture_bank_number != -1) { | ||
1082 | unit->capture[ypcm->capture_bank_number].use = 0; | ||
1083 | ypcm->capture_bank_number = -1; | ||
1084 | ymfpci_hw_stop(unit); | ||
1085 | } | ||
1086 | } | ||
1087 | } | ||
1088 | |||
1089 | static struct ymf_state *ymf_state_alloc(ymfpci_t *unit) | ||
1090 | { | ||
1091 | struct ymf_pcm *ypcm; | ||
1092 | struct ymf_state *state; | ||
1093 | |||
1094 | if ((state = kmalloc(sizeof(struct ymf_state), GFP_KERNEL)) == NULL) { | ||
1095 | goto out0; | ||
1096 | } | ||
1097 | memset(state, 0, sizeof(struct ymf_state)); | ||
1098 | |||
1099 | ypcm = &state->wpcm; | ||
1100 | ypcm->state = state; | ||
1101 | ypcm->type = PLAYBACK_VOICE; | ||
1102 | ypcm->capture_bank_number = -1; | ||
1103 | init_waitqueue_head(&ypcm->dmabuf.wait); | ||
1104 | |||
1105 | ypcm = &state->rpcm; | ||
1106 | ypcm->state = state; | ||
1107 | ypcm->type = CAPTURE_AC97; | ||
1108 | ypcm->capture_bank_number = -1; | ||
1109 | init_waitqueue_head(&ypcm->dmabuf.wait); | ||
1110 | |||
1111 | state->unit = unit; | ||
1112 | |||
1113 | state->format.format = AFMT_U8; | ||
1114 | state->format.rate = 8000; | ||
1115 | state->format.voices = 1; | ||
1116 | ymf_pcm_update_shift(&state->format); | ||
1117 | |||
1118 | return state; | ||
1119 | |||
1120 | out0: | ||
1121 | return NULL; | ||
1122 | } | ||
1123 | |||
1124 | /* AES/IEC958 channel status bits */ | ||
1125 | #define SND_PCM_AES0_PROFESSIONAL (1<<0) /* 0 = consumer, 1 = professional */ | ||
1126 | #define SND_PCM_AES0_NONAUDIO (1<<1) /* 0 = audio, 1 = non-audio */ | ||
1127 | #define SND_PCM_AES0_PRO_EMPHASIS (7<<2) /* mask - emphasis */ | ||
1128 | #define SND_PCM_AES0_PRO_EMPHASIS_NOTID (0<<2) /* emphasis not indicated */ | ||
1129 | #define SND_PCM_AES0_PRO_EMPHASIS_NONE (1<<2) /* none emphasis */ | ||
1130 | #define SND_PCM_AES0_PRO_EMPHASIS_5015 (3<<2) /* 50/15us emphasis */ | ||
1131 | #define SND_PCM_AES0_PRO_EMPHASIS_CCITT (7<<2) /* CCITT J.17 emphasis */ | ||
1132 | #define SND_PCM_AES0_PRO_FREQ_UNLOCKED (1<<5) /* source sample frequency: 0 = locked, 1 = unlocked */ | ||
1133 | #define SND_PCM_AES0_PRO_FS (3<<6) /* mask - sample frequency */ | ||
1134 | #define SND_PCM_AES0_PRO_FS_NOTID (0<<6) /* fs not indicated */ | ||
1135 | #define SND_PCM_AES0_PRO_FS_44100 (1<<6) /* 44.1kHz */ | ||
1136 | #define SND_PCM_AES0_PRO_FS_48000 (2<<6) /* 48kHz */ | ||
1137 | #define SND_PCM_AES0_PRO_FS_32000 (3<<6) /* 32kHz */ | ||
1138 | #define SND_PCM_AES0_CON_NOT_COPYRIGHT (1<<2) /* 0 = copyright, 1 = not copyright */ | ||
1139 | #define SND_PCM_AES0_CON_EMPHASIS (7<<3) /* mask - emphasis */ | ||
1140 | #define SND_PCM_AES0_CON_EMPHASIS_NONE (0<<3) /* none emphasis */ | ||
1141 | #define SND_PCM_AES0_CON_EMPHASIS_5015 (1<<3) /* 50/15us emphasis */ | ||
1142 | #define SND_PCM_AES0_CON_MODE (3<<6) /* mask - mode */ | ||
1143 | #define SND_PCM_AES1_PRO_MODE (15<<0) /* mask - channel mode */ | ||
1144 | #define SND_PCM_AES1_PRO_MODE_NOTID (0<<0) /* not indicated */ | ||
1145 | #define SND_PCM_AES1_PRO_MODE_STEREOPHONIC (2<<0) /* stereophonic - ch A is left */ | ||
1146 | #define SND_PCM_AES1_PRO_MODE_SINGLE (4<<0) /* single channel */ | ||
1147 | #define SND_PCM_AES1_PRO_MODE_TWO (8<<0) /* two channels */ | ||
1148 | #define SND_PCM_AES1_PRO_MODE_PRIMARY (12<<0) /* primary/secondary */ | ||
1149 | #define SND_PCM_AES1_PRO_MODE_BYTE3 (15<<0) /* vector to byte 3 */ | ||
1150 | #define SND_PCM_AES1_PRO_USERBITS (15<<4) /* mask - user bits */ | ||
1151 | #define SND_PCM_AES1_PRO_USERBITS_NOTID (0<<4) /* not indicated */ | ||
1152 | #define SND_PCM_AES1_PRO_USERBITS_192 (8<<4) /* 192-bit structure */ | ||
1153 | #define SND_PCM_AES1_PRO_USERBITS_UDEF (12<<4) /* user defined application */ | ||
1154 | #define SND_PCM_AES1_CON_CATEGORY 0x7f | ||
1155 | #define SND_PCM_AES1_CON_GENERAL 0x00 | ||
1156 | #define SND_PCM_AES1_CON_EXPERIMENTAL 0x40 | ||
1157 | #define SND_PCM_AES1_CON_SOLIDMEM_MASK 0x0f | ||
1158 | #define SND_PCM_AES1_CON_SOLIDMEM_ID 0x08 | ||
1159 | #define SND_PCM_AES1_CON_BROADCAST1_MASK 0x07 | ||
1160 | #define SND_PCM_AES1_CON_BROADCAST1_ID 0x04 | ||
1161 | #define SND_PCM_AES1_CON_DIGDIGCONV_MASK 0x07 | ||
1162 | #define SND_PCM_AES1_CON_DIGDIGCONV_ID 0x02 | ||
1163 | #define SND_PCM_AES1_CON_ADC_COPYRIGHT_MASK 0x1f | ||
1164 | #define SND_PCM_AES1_CON_ADC_COPYRIGHT_ID 0x06 | ||
1165 | #define SND_PCM_AES1_CON_ADC_MASK 0x1f | ||
1166 | #define SND_PCM_AES1_CON_ADC_ID 0x16 | ||
1167 | #define SND_PCM_AES1_CON_BROADCAST2_MASK 0x0f | ||
1168 | #define SND_PCM_AES1_CON_BROADCAST2_ID 0x0e | ||
1169 | #define SND_PCM_AES1_CON_LASEROPT_MASK 0x07 | ||
1170 | #define SND_PCM_AES1_CON_LASEROPT_ID 0x01 | ||
1171 | #define SND_PCM_AES1_CON_MUSICAL_MASK 0x07 | ||
1172 | #define SND_PCM_AES1_CON_MUSICAL_ID 0x05 | ||
1173 | #define SND_PCM_AES1_CON_MAGNETIC_MASK 0x07 | ||
1174 | #define SND_PCM_AES1_CON_MAGNETIC_ID 0x03 | ||
1175 | #define SND_PCM_AES1_CON_IEC908_CD (SND_PCM_AES1_CON_LASEROPT_ID|0x00) | ||
1176 | #define SND_PCM_AES1_CON_NON_IEC908_CD (SND_PCM_AES1_CON_LASEROPT_ID|0x08) | ||
1177 | #define SND_PCM_AES1_CON_PCM_CODER (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x00) | ||
1178 | #define SND_PCM_AES1_CON_SAMPLER (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x20) | ||
1179 | #define SND_PCM_AES1_CON_MIXER (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x10) | ||
1180 | #define SND_PCM_AES1_CON_RATE_CONVERTER (SND_PCM_AES1_CON_DIGDIGCONV_ID|0x18) | ||
1181 | #define SND_PCM_AES1_CON_SYNTHESIZER (SND_PCM_AES1_CON_MUSICAL_ID|0x00) | ||
1182 | #define SND_PCM_AES1_CON_MICROPHONE (SND_PCM_AES1_CON_MUSICAL_ID|0x08) | ||
1183 | #define SND_PCM_AES1_CON_DAT (SND_PCM_AES1_CON_MAGNETIC_ID|0x00) | ||
1184 | #define SND_PCM_AES1_CON_VCR (SND_PCM_AES1_CON_MAGNETIC_ID|0x08) | ||
1185 | #define SND_PCM_AES1_CON_ORIGINAL (1<<7) /* this bits depends on the category code */ | ||
1186 | #define SND_PCM_AES2_PRO_SBITS (7<<0) /* mask - sample bits */ | ||
1187 | #define SND_PCM_AES2_PRO_SBITS_20 (2<<0) /* 20-bit - coordination */ | ||
1188 | #define SND_PCM_AES2_PRO_SBITS_24 (4<<0) /* 24-bit - main audio */ | ||
1189 | #define SND_PCM_AES2_PRO_SBITS_UDEF (6<<0) /* user defined application */ | ||
1190 | #define SND_PCM_AES2_PRO_WORDLEN (7<<3) /* mask - source word length */ | ||
1191 | #define SND_PCM_AES2_PRO_WORDLEN_NOTID (0<<3) /* not indicated */ | ||
1192 | #define SND_PCM_AES2_PRO_WORDLEN_22_18 (2<<3) /* 22-bit or 18-bit */ | ||
1193 | #define SND_PCM_AES2_PRO_WORDLEN_23_19 (4<<3) /* 23-bit or 19-bit */ | ||
1194 | #define SND_PCM_AES2_PRO_WORDLEN_24_20 (5<<3) /* 24-bit or 20-bit */ | ||
1195 | #define SND_PCM_AES2_PRO_WORDLEN_20_16 (6<<3) /* 20-bit or 16-bit */ | ||
1196 | #define SND_PCM_AES2_CON_SOURCE (15<<0) /* mask - source number */ | ||
1197 | #define SND_PCM_AES2_CON_SOURCE_UNSPEC (0<<0) /* unspecified */ | ||
1198 | #define SND_PCM_AES2_CON_CHANNEL (15<<4) /* mask - channel number */ | ||
1199 | #define SND_PCM_AES2_CON_CHANNEL_UNSPEC (0<<4) /* unspecified */ | ||
1200 | #define SND_PCM_AES3_CON_FS (15<<0) /* mask - sample frequency */ | ||
1201 | #define SND_PCM_AES3_CON_FS_44100 (0<<0) /* 44.1kHz */ | ||
1202 | #define SND_PCM_AES3_CON_FS_48000 (2<<0) /* 48kHz */ | ||
1203 | #define SND_PCM_AES3_CON_FS_32000 (3<<0) /* 32kHz */ | ||
1204 | #define SND_PCM_AES3_CON_CLOCK (3<<4) /* mask - clock accuracy */ | ||
1205 | #define SND_PCM_AES3_CON_CLOCK_1000PPM (0<<4) /* 1000 ppm */ | ||
1206 | #define SND_PCM_AES3_CON_CLOCK_50PPM (1<<4) /* 50 ppm */ | ||
1207 | #define SND_PCM_AES3_CON_CLOCK_VARIABLE (2<<4) /* variable pitch */ | ||
1208 | |||
1209 | /* | ||
1210 | * User interface | ||
1211 | */ | ||
1212 | |||
1213 | /* | ||
1214 | * in this loop, dmabuf.count signifies the amount of data that is | ||
1215 | * waiting to be copied to the user's buffer. it is filled by the dma | ||
1216 | * machine and drained by this loop. | ||
1217 | */ | ||
1218 | static ssize_t | ||
1219 | ymf_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1220 | { | ||
1221 | struct ymf_state *state = (struct ymf_state *)file->private_data; | ||
1222 | struct ymf_dmabuf *dmabuf = &state->rpcm.dmabuf; | ||
1223 | struct ymf_unit *unit = state->unit; | ||
1224 | DECLARE_WAITQUEUE(waita, current); | ||
1225 | ssize_t ret; | ||
1226 | unsigned long flags; | ||
1227 | unsigned int swptr; | ||
1228 | int cnt; /* This many to go in this revolution */ | ||
1229 | |||
1230 | if (dmabuf->mapped) | ||
1231 | return -ENXIO; | ||
1232 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 1))) | ||
1233 | return ret; | ||
1234 | ret = 0; | ||
1235 | |||
1236 | add_wait_queue(&dmabuf->wait, &waita); | ||
1237 | set_current_state(TASK_INTERRUPTIBLE); | ||
1238 | while (count > 0) { | ||
1239 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
1240 | if (unit->suspended) { | ||
1241 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1242 | schedule(); | ||
1243 | set_current_state(TASK_INTERRUPTIBLE); | ||
1244 | if (signal_pending(current)) { | ||
1245 | if (!ret) ret = -EAGAIN; | ||
1246 | break; | ||
1247 | } | ||
1248 | continue; | ||
1249 | } | ||
1250 | swptr = dmabuf->swptr; | ||
1251 | cnt = dmabuf->dmasize - swptr; | ||
1252 | if (dmabuf->count < cnt) | ||
1253 | cnt = dmabuf->count; | ||
1254 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1255 | |||
1256 | if (cnt > count) | ||
1257 | cnt = count; | ||
1258 | if (cnt <= 0) { | ||
1259 | unsigned long tmo; | ||
1260 | /* buffer is empty, start the dma machine and wait for data to be | ||
1261 | recorded */ | ||
1262 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1263 | if (!state->rpcm.running) { | ||
1264 | ymf_capture_trigger(state->unit, &state->rpcm, 1); | ||
1265 | } | ||
1266 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1267 | if (file->f_flags & O_NONBLOCK) { | ||
1268 | if (!ret) ret = -EAGAIN; | ||
1269 | break; | ||
1270 | } | ||
1271 | /* This isnt strictly right for the 810 but it'll do */ | ||
1272 | tmo = (dmabuf->dmasize * HZ) / (state->format.rate * 2); | ||
1273 | tmo >>= state->format.shift; | ||
1274 | /* There are two situations when sleep_on_timeout returns, one is when | ||
1275 | the interrupt is serviced correctly and the process is waked up by | ||
1276 | ISR ON TIME. Another is when timeout is expired, which means that | ||
1277 | either interrupt is NOT serviced correctly (pending interrupt) or it | ||
1278 | is TOO LATE for the process to be scheduled to run (scheduler latency) | ||
1279 | which results in a (potential) buffer overrun. And worse, there is | ||
1280 | NOTHING we can do to prevent it. */ | ||
1281 | tmo = schedule_timeout(tmo); | ||
1282 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1283 | set_current_state(TASK_INTERRUPTIBLE); | ||
1284 | if (tmo == 0 && dmabuf->count == 0) { | ||
1285 | printk(KERN_ERR "ymfpci%d: recording schedule timeout, " | ||
1286 | "dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
1287 | state->unit->dev_audio, | ||
1288 | dmabuf->dmasize, dmabuf->fragsize, dmabuf->count, | ||
1289 | dmabuf->hwptr, dmabuf->swptr); | ||
1290 | } | ||
1291 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1292 | if (signal_pending(current)) { | ||
1293 | if (!ret) ret = -ERESTARTSYS; | ||
1294 | break; | ||
1295 | } | ||
1296 | continue; | ||
1297 | } | ||
1298 | |||
1299 | if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) { | ||
1300 | if (!ret) ret = -EFAULT; | ||
1301 | break; | ||
1302 | } | ||
1303 | |||
1304 | swptr = (swptr + cnt) % dmabuf->dmasize; | ||
1305 | |||
1306 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
1307 | if (unit->suspended) { | ||
1308 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1309 | continue; | ||
1310 | } | ||
1311 | |||
1312 | dmabuf->swptr = swptr; | ||
1313 | dmabuf->count -= cnt; | ||
1314 | // spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1315 | |||
1316 | count -= cnt; | ||
1317 | buffer += cnt; | ||
1318 | ret += cnt; | ||
1319 | // spin_lock_irqsave(&unit->reg_lock, flags); | ||
1320 | if (!state->rpcm.running) { | ||
1321 | ymf_capture_trigger(unit, &state->rpcm, 1); | ||
1322 | } | ||
1323 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1324 | } | ||
1325 | set_current_state(TASK_RUNNING); | ||
1326 | remove_wait_queue(&dmabuf->wait, &waita); | ||
1327 | |||
1328 | return ret; | ||
1329 | } | ||
1330 | |||
1331 | static ssize_t | ||
1332 | ymf_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1333 | { | ||
1334 | struct ymf_state *state = (struct ymf_state *)file->private_data; | ||
1335 | struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf; | ||
1336 | struct ymf_unit *unit = state->unit; | ||
1337 | DECLARE_WAITQUEUE(waita, current); | ||
1338 | ssize_t ret; | ||
1339 | unsigned long flags; | ||
1340 | unsigned int swptr; | ||
1341 | int cnt; /* This many to go in this revolution */ | ||
1342 | int redzone; | ||
1343 | int delay; | ||
1344 | |||
1345 | YMFDBGW("ymf_write: count %d\n", count); | ||
1346 | |||
1347 | if (dmabuf->mapped) | ||
1348 | return -ENXIO; | ||
1349 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 0))) | ||
1350 | return ret; | ||
1351 | ret = 0; | ||
1352 | |||
1353 | /* | ||
1354 | * Alan's cs46xx works without a red zone - marvel of ingenuity. | ||
1355 | * We are not so brilliant... Red zone does two things: | ||
1356 | * 1. allows for safe start after a pause as we have no way | ||
1357 | * to know what the actual, relentlessly advancing, hwptr is. | ||
1358 | * 2. makes computations in ymf_pcm_interrupt simpler. | ||
1359 | */ | ||
1360 | redzone = ymf_calc_lend(state->format.rate) << state->format.shift; | ||
1361 | redzone *= 3; /* 2 redzone + 1 possible uncertainty reserve. */ | ||
1362 | |||
1363 | add_wait_queue(&dmabuf->wait, &waita); | ||
1364 | set_current_state(TASK_INTERRUPTIBLE); | ||
1365 | while (count > 0) { | ||
1366 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
1367 | if (unit->suspended) { | ||
1368 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1369 | schedule(); | ||
1370 | set_current_state(TASK_INTERRUPTIBLE); | ||
1371 | if (signal_pending(current)) { | ||
1372 | if (!ret) ret = -EAGAIN; | ||
1373 | break; | ||
1374 | } | ||
1375 | continue; | ||
1376 | } | ||
1377 | if (dmabuf->count < 0) { | ||
1378 | printk(KERN_ERR | ||
1379 | "ymf_write: count %d, was legal in cs46xx\n", | ||
1380 | dmabuf->count); | ||
1381 | dmabuf->count = 0; | ||
1382 | } | ||
1383 | if (dmabuf->count == 0) { | ||
1384 | swptr = dmabuf->hwptr; | ||
1385 | if (state->wpcm.running) { | ||
1386 | /* | ||
1387 | * Add uncertainty reserve. | ||
1388 | */ | ||
1389 | cnt = ymf_calc_lend(state->format.rate); | ||
1390 | cnt <<= state->format.shift; | ||
1391 | if ((swptr += cnt) >= dmabuf->dmasize) { | ||
1392 | swptr -= dmabuf->dmasize; | ||
1393 | } | ||
1394 | } | ||
1395 | dmabuf->swptr = swptr; | ||
1396 | } else { | ||
1397 | /* | ||
1398 | * XXX This is not right if dmabuf->count is small - | ||
1399 | * about 2*x frame size or less. We cannot count on | ||
1400 | * on appending and not causing an artefact. | ||
1401 | * Should use a variation of the count==0 case above. | ||
1402 | */ | ||
1403 | swptr = dmabuf->swptr; | ||
1404 | } | ||
1405 | cnt = dmabuf->dmasize - swptr; | ||
1406 | if (dmabuf->count + cnt > dmabuf->dmasize - redzone) | ||
1407 | cnt = (dmabuf->dmasize - redzone) - dmabuf->count; | ||
1408 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1409 | |||
1410 | if (cnt > count) | ||
1411 | cnt = count; | ||
1412 | if (cnt <= 0) { | ||
1413 | YMFDBGW("ymf_write: full, count %d swptr %d\n", | ||
1414 | dmabuf->count, dmabuf->swptr); | ||
1415 | /* | ||
1416 | * buffer is full, start the dma machine and | ||
1417 | * wait for data to be played | ||
1418 | */ | ||
1419 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
1420 | if (!state->wpcm.running) { | ||
1421 | ymf_playback_trigger(unit, &state->wpcm, 1); | ||
1422 | } | ||
1423 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1424 | if (file->f_flags & O_NONBLOCK) { | ||
1425 | if (!ret) ret = -EAGAIN; | ||
1426 | break; | ||
1427 | } | ||
1428 | schedule(); | ||
1429 | set_current_state(TASK_INTERRUPTIBLE); | ||
1430 | if (signal_pending(current)) { | ||
1431 | if (!ret) ret = -ERESTARTSYS; | ||
1432 | break; | ||
1433 | } | ||
1434 | continue; | ||
1435 | } | ||
1436 | if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) { | ||
1437 | if (!ret) ret = -EFAULT; | ||
1438 | break; | ||
1439 | } | ||
1440 | |||
1441 | if ((swptr += cnt) >= dmabuf->dmasize) { | ||
1442 | swptr -= dmabuf->dmasize; | ||
1443 | } | ||
1444 | |||
1445 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
1446 | if (unit->suspended) { | ||
1447 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1448 | continue; | ||
1449 | } | ||
1450 | dmabuf->swptr = swptr; | ||
1451 | dmabuf->count += cnt; | ||
1452 | |||
1453 | /* | ||
1454 | * Start here is a bad idea - may cause startup click | ||
1455 | * in /bin/play when dmabuf is not full yet. | ||
1456 | * However, some broken applications do not make | ||
1457 | * any use of SNDCTL_DSP_SYNC (Doom is the worst). | ||
1458 | * One frame is about 5.3ms, Doom write size is 46ms. | ||
1459 | */ | ||
1460 | delay = state->format.rate / 20; /* 50ms */ | ||
1461 | delay <<= state->format.shift; | ||
1462 | if (dmabuf->count >= delay && !state->wpcm.running) { | ||
1463 | ymf_playback_trigger(unit, &state->wpcm, 1); | ||
1464 | } | ||
1465 | |||
1466 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
1467 | |||
1468 | count -= cnt; | ||
1469 | buffer += cnt; | ||
1470 | ret += cnt; | ||
1471 | } | ||
1472 | |||
1473 | set_current_state(TASK_RUNNING); | ||
1474 | remove_wait_queue(&dmabuf->wait, &waita); | ||
1475 | |||
1476 | YMFDBGW("ymf_write: ret %d dmabuf.count %d\n", ret, dmabuf->count); | ||
1477 | return ret; | ||
1478 | } | ||
1479 | |||
1480 | static unsigned int ymf_poll(struct file *file, struct poll_table_struct *wait) | ||
1481 | { | ||
1482 | struct ymf_state *state = (struct ymf_state *)file->private_data; | ||
1483 | struct ymf_dmabuf *dmabuf; | ||
1484 | int redzone; | ||
1485 | unsigned long flags; | ||
1486 | unsigned int mask = 0; | ||
1487 | |||
1488 | if (file->f_mode & FMODE_WRITE) | ||
1489 | poll_wait(file, &state->wpcm.dmabuf.wait, wait); | ||
1490 | if (file->f_mode & FMODE_READ) | ||
1491 | poll_wait(file, &state->rpcm.dmabuf.wait, wait); | ||
1492 | |||
1493 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1494 | if (file->f_mode & FMODE_READ) { | ||
1495 | dmabuf = &state->rpcm.dmabuf; | ||
1496 | if (dmabuf->count >= (signed)dmabuf->fragsize) | ||
1497 | mask |= POLLIN | POLLRDNORM; | ||
1498 | } | ||
1499 | if (file->f_mode & FMODE_WRITE) { | ||
1500 | redzone = ymf_calc_lend(state->format.rate); | ||
1501 | redzone <<= state->format.shift; | ||
1502 | redzone *= 3; | ||
1503 | |||
1504 | dmabuf = &state->wpcm.dmabuf; | ||
1505 | if (dmabuf->mapped) { | ||
1506 | if (dmabuf->count >= (signed)dmabuf->fragsize) | ||
1507 | mask |= POLLOUT | POLLWRNORM; | ||
1508 | } else { | ||
1509 | /* | ||
1510 | * Don't select unless a full fragment is available. | ||
1511 | * Otherwise artsd does GETOSPACE, sees 0, and loops. | ||
1512 | */ | ||
1513 | if (dmabuf->count + redzone + dmabuf->fragsize | ||
1514 | <= dmabuf->dmasize) | ||
1515 | mask |= POLLOUT | POLLWRNORM; | ||
1516 | } | ||
1517 | } | ||
1518 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1519 | |||
1520 | return mask; | ||
1521 | } | ||
1522 | |||
1523 | static int ymf_mmap(struct file *file, struct vm_area_struct *vma) | ||
1524 | { | ||
1525 | struct ymf_state *state = (struct ymf_state *)file->private_data; | ||
1526 | struct ymf_dmabuf *dmabuf = &state->wpcm.dmabuf; | ||
1527 | int ret; | ||
1528 | unsigned long size; | ||
1529 | |||
1530 | if (vma->vm_flags & VM_WRITE) { | ||
1531 | if ((ret = prog_dmabuf(state, 0)) != 0) | ||
1532 | return ret; | ||
1533 | } else if (vma->vm_flags & VM_READ) { | ||
1534 | if ((ret = prog_dmabuf(state, 1)) != 0) | ||
1535 | return ret; | ||
1536 | } else | ||
1537 | return -EINVAL; | ||
1538 | |||
1539 | if (vma->vm_pgoff != 0) | ||
1540 | return -EINVAL; | ||
1541 | size = vma->vm_end - vma->vm_start; | ||
1542 | if (size > (PAGE_SIZE << dmabuf->buforder)) | ||
1543 | return -EINVAL; | ||
1544 | if (remap_pfn_range(vma, vma->vm_start, | ||
1545 | virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT, | ||
1546 | size, vma->vm_page_prot)) | ||
1547 | return -EAGAIN; | ||
1548 | dmabuf->mapped = 1; | ||
1549 | |||
1550 | /* P3 */ printk(KERN_INFO "ymfpci: using memory mapped sound, untested!\n"); | ||
1551 | return 0; | ||
1552 | } | ||
1553 | |||
1554 | static int ymf_ioctl(struct inode *inode, struct file *file, | ||
1555 | unsigned int cmd, unsigned long arg) | ||
1556 | { | ||
1557 | struct ymf_state *state = (struct ymf_state *)file->private_data; | ||
1558 | struct ymf_dmabuf *dmabuf; | ||
1559 | unsigned long flags; | ||
1560 | audio_buf_info abinfo; | ||
1561 | count_info cinfo; | ||
1562 | int redzone; | ||
1563 | int val; | ||
1564 | void __user *argp = (void __user *)arg; | ||
1565 | int __user *p = argp; | ||
1566 | |||
1567 | switch (cmd) { | ||
1568 | case OSS_GETVERSION: | ||
1569 | YMFDBGX("ymf_ioctl: cmd 0x%x(GETVER) arg 0x%lx\n", cmd, arg); | ||
1570 | return put_user(SOUND_VERSION, p); | ||
1571 | |||
1572 | case SNDCTL_DSP_RESET: | ||
1573 | YMFDBGX("ymf_ioctl: cmd 0x%x(RESET)\n", cmd); | ||
1574 | if (file->f_mode & FMODE_WRITE) { | ||
1575 | ymf_wait_dac(state); | ||
1576 | dmabuf = &state->wpcm.dmabuf; | ||
1577 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1578 | dmabuf->ready = 0; | ||
1579 | dmabuf->swptr = dmabuf->hwptr; | ||
1580 | dmabuf->count = dmabuf->total_bytes = 0; | ||
1581 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1582 | } | ||
1583 | if (file->f_mode & FMODE_READ) { | ||
1584 | ymf_stop_adc(state); | ||
1585 | dmabuf = &state->rpcm.dmabuf; | ||
1586 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1587 | dmabuf->ready = 0; | ||
1588 | dmabuf->swptr = dmabuf->hwptr; | ||
1589 | dmabuf->count = dmabuf->total_bytes = 0; | ||
1590 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1591 | } | ||
1592 | return 0; | ||
1593 | |||
1594 | case SNDCTL_DSP_SYNC: | ||
1595 | YMFDBGX("ymf_ioctl: cmd 0x%x(SYNC)\n", cmd); | ||
1596 | if (file->f_mode & FMODE_WRITE) { | ||
1597 | dmabuf = &state->wpcm.dmabuf; | ||
1598 | if (file->f_flags & O_NONBLOCK) { | ||
1599 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1600 | if (dmabuf->count != 0 && !state->wpcm.running) { | ||
1601 | ymf_start_dac(state); | ||
1602 | } | ||
1603 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1604 | } else { | ||
1605 | ymf_wait_dac(state); | ||
1606 | } | ||
1607 | } | ||
1608 | /* XXX What does this do for reading? dmabuf->count=0; ? */ | ||
1609 | return 0; | ||
1610 | |||
1611 | case SNDCTL_DSP_SPEED: /* set smaple rate */ | ||
1612 | if (get_user(val, p)) | ||
1613 | return -EFAULT; | ||
1614 | YMFDBGX("ymf_ioctl: cmd 0x%x(SPEED) sp %d\n", cmd, val); | ||
1615 | if (val >= 8000 && val <= 48000) { | ||
1616 | if (file->f_mode & FMODE_WRITE) { | ||
1617 | ymf_wait_dac(state); | ||
1618 | dmabuf = &state->wpcm.dmabuf; | ||
1619 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1620 | dmabuf->ready = 0; | ||
1621 | state->format.rate = val; | ||
1622 | ymf_pcm_update_shift(&state->format); | ||
1623 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1624 | } | ||
1625 | if (file->f_mode & FMODE_READ) { | ||
1626 | ymf_stop_adc(state); | ||
1627 | dmabuf = &state->rpcm.dmabuf; | ||
1628 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1629 | dmabuf->ready = 0; | ||
1630 | state->format.rate = val; | ||
1631 | ymf_pcm_update_shift(&state->format); | ||
1632 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1633 | } | ||
1634 | } | ||
1635 | return put_user(state->format.rate, p); | ||
1636 | |||
1637 | /* | ||
1638 | * OSS manual does not mention SNDCTL_DSP_STEREO at all. | ||
1639 | * All channels are mono and if you want stereo, you | ||
1640 | * play into two channels with SNDCTL_DSP_CHANNELS. | ||
1641 | * However, mpg123 calls it. I wonder, why Michael Hipp used it. | ||
1642 | */ | ||
1643 | case SNDCTL_DSP_STEREO: /* set stereo or mono channel */ | ||
1644 | if (get_user(val, p)) | ||
1645 | return -EFAULT; | ||
1646 | YMFDBGX("ymf_ioctl: cmd 0x%x(STEREO) st %d\n", cmd, val); | ||
1647 | if (file->f_mode & FMODE_WRITE) { | ||
1648 | ymf_wait_dac(state); | ||
1649 | dmabuf = &state->wpcm.dmabuf; | ||
1650 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1651 | dmabuf->ready = 0; | ||
1652 | state->format.voices = val ? 2 : 1; | ||
1653 | ymf_pcm_update_shift(&state->format); | ||
1654 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1655 | } | ||
1656 | if (file->f_mode & FMODE_READ) { | ||
1657 | ymf_stop_adc(state); | ||
1658 | dmabuf = &state->rpcm.dmabuf; | ||
1659 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1660 | dmabuf->ready = 0; | ||
1661 | state->format.voices = val ? 2 : 1; | ||
1662 | ymf_pcm_update_shift(&state->format); | ||
1663 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1664 | } | ||
1665 | return 0; | ||
1666 | |||
1667 | case SNDCTL_DSP_GETBLKSIZE: | ||
1668 | YMFDBGX("ymf_ioctl: cmd 0x%x(GETBLK)\n", cmd); | ||
1669 | if (file->f_mode & FMODE_WRITE) { | ||
1670 | if ((val = prog_dmabuf(state, 0))) | ||
1671 | return val; | ||
1672 | val = state->wpcm.dmabuf.fragsize; | ||
1673 | YMFDBGX("ymf_ioctl: GETBLK w %d\n", val); | ||
1674 | return put_user(val, p); | ||
1675 | } | ||
1676 | if (file->f_mode & FMODE_READ) { | ||
1677 | if ((val = prog_dmabuf(state, 1))) | ||
1678 | return val; | ||
1679 | val = state->rpcm.dmabuf.fragsize; | ||
1680 | YMFDBGX("ymf_ioctl: GETBLK r %d\n", val); | ||
1681 | return put_user(val, p); | ||
1682 | } | ||
1683 | return -EINVAL; | ||
1684 | |||
1685 | case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/ | ||
1686 | YMFDBGX("ymf_ioctl: cmd 0x%x(GETFMTS)\n", cmd); | ||
1687 | return put_user(AFMT_S16_LE|AFMT_U8, p); | ||
1688 | |||
1689 | case SNDCTL_DSP_SETFMT: /* Select sample format */ | ||
1690 | if (get_user(val, p)) | ||
1691 | return -EFAULT; | ||
1692 | YMFDBGX("ymf_ioctl: cmd 0x%x(SETFMT) fmt %d\n", cmd, val); | ||
1693 | if (val == AFMT_S16_LE || val == AFMT_U8) { | ||
1694 | if (file->f_mode & FMODE_WRITE) { | ||
1695 | ymf_wait_dac(state); | ||
1696 | dmabuf = &state->wpcm.dmabuf; | ||
1697 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1698 | dmabuf->ready = 0; | ||
1699 | state->format.format = val; | ||
1700 | ymf_pcm_update_shift(&state->format); | ||
1701 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1702 | } | ||
1703 | if (file->f_mode & FMODE_READ) { | ||
1704 | ymf_stop_adc(state); | ||
1705 | dmabuf = &state->rpcm.dmabuf; | ||
1706 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1707 | dmabuf->ready = 0; | ||
1708 | state->format.format = val; | ||
1709 | ymf_pcm_update_shift(&state->format); | ||
1710 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1711 | } | ||
1712 | } | ||
1713 | return put_user(state->format.format, p); | ||
1714 | |||
1715 | case SNDCTL_DSP_CHANNELS: | ||
1716 | if (get_user(val, p)) | ||
1717 | return -EFAULT; | ||
1718 | YMFDBGX("ymf_ioctl: cmd 0x%x(CHAN) ch %d\n", cmd, val); | ||
1719 | if (val != 0) { | ||
1720 | if (file->f_mode & FMODE_WRITE) { | ||
1721 | ymf_wait_dac(state); | ||
1722 | if (val == 1 || val == 2) { | ||
1723 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1724 | dmabuf = &state->wpcm.dmabuf; | ||
1725 | dmabuf->ready = 0; | ||
1726 | state->format.voices = val; | ||
1727 | ymf_pcm_update_shift(&state->format); | ||
1728 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1729 | } | ||
1730 | } | ||
1731 | if (file->f_mode & FMODE_READ) { | ||
1732 | ymf_stop_adc(state); | ||
1733 | if (val == 1 || val == 2) { | ||
1734 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1735 | dmabuf = &state->rpcm.dmabuf; | ||
1736 | dmabuf->ready = 0; | ||
1737 | state->format.voices = val; | ||
1738 | ymf_pcm_update_shift(&state->format); | ||
1739 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1740 | } | ||
1741 | } | ||
1742 | } | ||
1743 | return put_user(state->format.voices, p); | ||
1744 | |||
1745 | case SNDCTL_DSP_POST: | ||
1746 | YMFDBGX("ymf_ioctl: cmd 0x%x(POST)\n", cmd); | ||
1747 | /* | ||
1748 | * Quoting OSS PG: | ||
1749 | * The ioctl SNDCTL_DSP_POST is a lightweight version of | ||
1750 | * SNDCTL_DSP_SYNC. It just tells to the driver that there | ||
1751 | * is likely to be a pause in the output. This makes it | ||
1752 | * possible for the device to handle the pause more | ||
1753 | * intelligently. This ioctl doesn't block the application. | ||
1754 | * | ||
1755 | * The paragraph above is a clumsy way to say "flush ioctl". | ||
1756 | * This ioctl is used by mpg123. | ||
1757 | */ | ||
1758 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1759 | if (state->wpcm.dmabuf.count != 0 && !state->wpcm.running) { | ||
1760 | ymf_start_dac(state); | ||
1761 | } | ||
1762 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1763 | return 0; | ||
1764 | |||
1765 | case SNDCTL_DSP_SETFRAGMENT: | ||
1766 | if (get_user(val, p)) | ||
1767 | return -EFAULT; | ||
1768 | YMFDBGX("ymf_ioctl: cmd 0x%x(SETFRAG) fr 0x%04x:%04x(%d:%d)\n", | ||
1769 | cmd, | ||
1770 | (val >> 16) & 0xFFFF, val & 0xFFFF, | ||
1771 | (val >> 16) & 0xFFFF, val & 0xFFFF); | ||
1772 | dmabuf = &state->wpcm.dmabuf; | ||
1773 | dmabuf->ossfragshift = val & 0xffff; | ||
1774 | dmabuf->ossmaxfrags = (val >> 16) & 0xffff; | ||
1775 | if (dmabuf->ossfragshift < 4) | ||
1776 | dmabuf->ossfragshift = 4; | ||
1777 | if (dmabuf->ossfragshift > 15) | ||
1778 | dmabuf->ossfragshift = 15; | ||
1779 | return 0; | ||
1780 | |||
1781 | case SNDCTL_DSP_GETOSPACE: | ||
1782 | YMFDBGX("ymf_ioctl: cmd 0x%x(GETOSPACE)\n", cmd); | ||
1783 | if (!(file->f_mode & FMODE_WRITE)) | ||
1784 | return -EINVAL; | ||
1785 | dmabuf = &state->wpcm.dmabuf; | ||
1786 | if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0) | ||
1787 | return val; | ||
1788 | redzone = ymf_calc_lend(state->format.rate); | ||
1789 | redzone <<= state->format.shift; | ||
1790 | redzone *= 3; | ||
1791 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1792 | abinfo.fragsize = dmabuf->fragsize; | ||
1793 | abinfo.bytes = dmabuf->dmasize - dmabuf->count - redzone; | ||
1794 | abinfo.fragstotal = dmabuf->numfrag; | ||
1795 | abinfo.fragments = abinfo.bytes >> dmabuf->fragshift; | ||
1796 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1797 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1798 | |||
1799 | case SNDCTL_DSP_GETISPACE: | ||
1800 | YMFDBGX("ymf_ioctl: cmd 0x%x(GETISPACE)\n", cmd); | ||
1801 | if (!(file->f_mode & FMODE_READ)) | ||
1802 | return -EINVAL; | ||
1803 | dmabuf = &state->rpcm.dmabuf; | ||
1804 | if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0) | ||
1805 | return val; | ||
1806 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1807 | abinfo.fragsize = dmabuf->fragsize; | ||
1808 | abinfo.bytes = dmabuf->count; | ||
1809 | abinfo.fragstotal = dmabuf->numfrag; | ||
1810 | abinfo.fragments = abinfo.bytes >> dmabuf->fragshift; | ||
1811 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1812 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1813 | |||
1814 | case SNDCTL_DSP_NONBLOCK: | ||
1815 | YMFDBGX("ymf_ioctl: cmd 0x%x(NONBLOCK)\n", cmd); | ||
1816 | file->f_flags |= O_NONBLOCK; | ||
1817 | return 0; | ||
1818 | |||
1819 | case SNDCTL_DSP_GETCAPS: | ||
1820 | YMFDBGX("ymf_ioctl: cmd 0x%x(GETCAPS)\n", cmd); | ||
1821 | /* return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP, | ||
1822 | p); */ | ||
1823 | return put_user(0, p); | ||
1824 | |||
1825 | case SNDCTL_DSP_GETIPTR: | ||
1826 | YMFDBGX("ymf_ioctl: cmd 0x%x(GETIPTR)\n", cmd); | ||
1827 | if (!(file->f_mode & FMODE_READ)) | ||
1828 | return -EINVAL; | ||
1829 | dmabuf = &state->rpcm.dmabuf; | ||
1830 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1831 | cinfo.bytes = dmabuf->total_bytes; | ||
1832 | cinfo.blocks = dmabuf->count >> dmabuf->fragshift; | ||
1833 | cinfo.ptr = dmabuf->hwptr; | ||
1834 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1835 | YMFDBGX("ymf_ioctl: GETIPTR ptr %d bytes %d\n", | ||
1836 | cinfo.ptr, cinfo.bytes); | ||
1837 | return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; | ||
1838 | |||
1839 | case SNDCTL_DSP_GETOPTR: | ||
1840 | YMFDBGX("ymf_ioctl: cmd 0x%x(GETOPTR)\n", cmd); | ||
1841 | if (!(file->f_mode & FMODE_WRITE)) | ||
1842 | return -EINVAL; | ||
1843 | dmabuf = &state->wpcm.dmabuf; | ||
1844 | spin_lock_irqsave(&state->unit->reg_lock, flags); | ||
1845 | cinfo.bytes = dmabuf->total_bytes; | ||
1846 | cinfo.blocks = dmabuf->count >> dmabuf->fragshift; | ||
1847 | cinfo.ptr = dmabuf->hwptr; | ||
1848 | spin_unlock_irqrestore(&state->unit->reg_lock, flags); | ||
1849 | YMFDBGX("ymf_ioctl: GETOPTR ptr %d bytes %d\n", | ||
1850 | cinfo.ptr, cinfo.bytes); | ||
1851 | return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; | ||
1852 | |||
1853 | case SNDCTL_DSP_SETDUPLEX: | ||
1854 | YMFDBGX("ymf_ioctl: cmd 0x%x(SETDUPLEX)\n", cmd); | ||
1855 | return 0; /* Always duplex */ | ||
1856 | |||
1857 | case SOUND_PCM_READ_RATE: | ||
1858 | YMFDBGX("ymf_ioctl: cmd 0x%x(READ_RATE)\n", cmd); | ||
1859 | return put_user(state->format.rate, p); | ||
1860 | |||
1861 | case SOUND_PCM_READ_CHANNELS: | ||
1862 | YMFDBGX("ymf_ioctl: cmd 0x%x(READ_CH)\n", cmd); | ||
1863 | return put_user(state->format.voices, p); | ||
1864 | |||
1865 | case SOUND_PCM_READ_BITS: | ||
1866 | YMFDBGX("ymf_ioctl: cmd 0x%x(READ_BITS)\n", cmd); | ||
1867 | return put_user(AFMT_S16_LE, p); | ||
1868 | |||
1869 | case SNDCTL_DSP_MAPINBUF: | ||
1870 | case SNDCTL_DSP_MAPOUTBUF: | ||
1871 | case SNDCTL_DSP_SETSYNCRO: | ||
1872 | case SOUND_PCM_WRITE_FILTER: | ||
1873 | case SOUND_PCM_READ_FILTER: | ||
1874 | YMFDBGX("ymf_ioctl: cmd 0x%x unsupported\n", cmd); | ||
1875 | return -ENOTTY; | ||
1876 | |||
1877 | default: | ||
1878 | /* | ||
1879 | * Some programs mix up audio devices and ioctls | ||
1880 | * or perhaps they expect "universal" ioctls, | ||
1881 | * for instance we get SNDCTL_TMR_CONTINUE here. | ||
1882 | * (mpg123 -g 100 ends here too - to be fixed.) | ||
1883 | */ | ||
1884 | YMFDBGX("ymf_ioctl: cmd 0x%x unknown\n", cmd); | ||
1885 | break; | ||
1886 | } | ||
1887 | return -ENOTTY; | ||
1888 | } | ||
1889 | |||
1890 | /* | ||
1891 | * open(2) | ||
1892 | * We use upper part of the minor to distinguish between soundcards. | ||
1893 | * Channels are opened with a clone open. | ||
1894 | */ | ||
1895 | static int ymf_open(struct inode *inode, struct file *file) | ||
1896 | { | ||
1897 | struct list_head *list; | ||
1898 | ymfpci_t *unit = NULL; | ||
1899 | int minor; | ||
1900 | struct ymf_state *state; | ||
1901 | int err; | ||
1902 | |||
1903 | minor = iminor(inode); | ||
1904 | if ((minor & 0x0F) == 3) { /* /dev/dspN */ | ||
1905 | ; | ||
1906 | } else { | ||
1907 | return -ENXIO; | ||
1908 | } | ||
1909 | |||
1910 | unit = NULL; /* gcc warns */ | ||
1911 | spin_lock(&ymf_devs_lock); | ||
1912 | list_for_each(list, &ymf_devs) { | ||
1913 | unit = list_entry(list, ymfpci_t, ymf_devs); | ||
1914 | if (((unit->dev_audio ^ minor) & ~0x0F) == 0) | ||
1915 | break; | ||
1916 | } | ||
1917 | spin_unlock(&ymf_devs_lock); | ||
1918 | if (unit == NULL) | ||
1919 | return -ENODEV; | ||
1920 | |||
1921 | mutex_lock(&unit->open_mutex); | ||
1922 | |||
1923 | if ((state = ymf_state_alloc(unit)) == NULL) { | ||
1924 | mutex_unlock(&unit->open_mutex); | ||
1925 | return -ENOMEM; | ||
1926 | } | ||
1927 | list_add_tail(&state->chain, &unit->states); | ||
1928 | |||
1929 | file->private_data = state; | ||
1930 | |||
1931 | /* | ||
1932 | * ymf_read and ymf_write that we borrowed from cs46xx | ||
1933 | * allocate buffers with prog_dmabuf(). We call prog_dmabuf | ||
1934 | * here so that in case of DMA memory exhaustion open | ||
1935 | * fails rather than write. | ||
1936 | * | ||
1937 | * XXX prog_dmabuf allocates voice. Should allocate explicitly, above. | ||
1938 | */ | ||
1939 | if (file->f_mode & FMODE_WRITE) { | ||
1940 | if (!state->wpcm.dmabuf.ready) { | ||
1941 | if ((err = prog_dmabuf(state, 0)) != 0) { | ||
1942 | goto out_nodma; | ||
1943 | } | ||
1944 | } | ||
1945 | } | ||
1946 | if (file->f_mode & FMODE_READ) { | ||
1947 | if (!state->rpcm.dmabuf.ready) { | ||
1948 | if ((err = prog_dmabuf(state, 1)) != 0) { | ||
1949 | goto out_nodma; | ||
1950 | } | ||
1951 | } | ||
1952 | } | ||
1953 | |||
1954 | #if 0 /* test if interrupts work */ | ||
1955 | ymfpci_writew(unit, YDSXGR_TIMERCOUNT, 0xfffe); /* ~ 680ms */ | ||
1956 | ymfpci_writeb(unit, YDSXGR_TIMERCTRL, | ||
1957 | (YDSXGR_TIMERCTRL_TEN|YDSXGR_TIMERCTRL_TIEN)); | ||
1958 | #endif | ||
1959 | mutex_unlock(&unit->open_mutex); | ||
1960 | |||
1961 | return nonseekable_open(inode, file); | ||
1962 | |||
1963 | out_nodma: | ||
1964 | /* | ||
1965 | * XXX Broken custom: "goto out_xxx" in other place is | ||
1966 | * a nestable exception, but here it is not nestable due to semaphore. | ||
1967 | * XXX Doubtful technique of self-describing objects.... | ||
1968 | */ | ||
1969 | dealloc_dmabuf(unit, &state->wpcm.dmabuf); | ||
1970 | dealloc_dmabuf(unit, &state->rpcm.dmabuf); | ||
1971 | ymf_pcm_free_substream(&state->wpcm); | ||
1972 | ymf_pcm_free_substream(&state->rpcm); | ||
1973 | |||
1974 | list_del(&state->chain); | ||
1975 | kfree(state); | ||
1976 | |||
1977 | mutex_unlock(&unit->open_mutex); | ||
1978 | return err; | ||
1979 | } | ||
1980 | |||
1981 | static int ymf_release(struct inode *inode, struct file *file) | ||
1982 | { | ||
1983 | struct ymf_state *state = (struct ymf_state *)file->private_data; | ||
1984 | ymfpci_t *unit = state->unit; | ||
1985 | |||
1986 | #if 0 /* test if interrupts work */ | ||
1987 | ymfpci_writeb(unit, YDSXGR_TIMERCTRL, 0); | ||
1988 | #endif | ||
1989 | |||
1990 | mutex_lock(&unit->open_mutex); | ||
1991 | |||
1992 | /* | ||
1993 | * XXX Solve the case of O_NONBLOCK close - don't deallocate here. | ||
1994 | * Deallocate when unloading the driver and we can wait. | ||
1995 | */ | ||
1996 | ymf_wait_dac(state); | ||
1997 | ymf_stop_adc(state); /* fortunately, it's immediate */ | ||
1998 | dealloc_dmabuf(unit, &state->wpcm.dmabuf); | ||
1999 | dealloc_dmabuf(unit, &state->rpcm.dmabuf); | ||
2000 | ymf_pcm_free_substream(&state->wpcm); | ||
2001 | ymf_pcm_free_substream(&state->rpcm); | ||
2002 | |||
2003 | list_del(&state->chain); | ||
2004 | file->private_data = NULL; /* Can you tell I programmed Solaris */ | ||
2005 | kfree(state); | ||
2006 | |||
2007 | mutex_unlock(&unit->open_mutex); | ||
2008 | |||
2009 | return 0; | ||
2010 | } | ||
2011 | |||
2012 | /* | ||
2013 | * Mixer operations are based on cs46xx. | ||
2014 | */ | ||
2015 | static int ymf_open_mixdev(struct inode *inode, struct file *file) | ||
2016 | { | ||
2017 | int minor = iminor(inode); | ||
2018 | struct list_head *list; | ||
2019 | ymfpci_t *unit; | ||
2020 | int i; | ||
2021 | |||
2022 | spin_lock(&ymf_devs_lock); | ||
2023 | list_for_each(list, &ymf_devs) { | ||
2024 | unit = list_entry(list, ymfpci_t, ymf_devs); | ||
2025 | for (i = 0; i < NR_AC97; i++) { | ||
2026 | if (unit->ac97_codec[i] != NULL && | ||
2027 | unit->ac97_codec[i]->dev_mixer == minor) { | ||
2028 | spin_unlock(&ymf_devs_lock); | ||
2029 | goto match; | ||
2030 | } | ||
2031 | } | ||
2032 | } | ||
2033 | spin_unlock(&ymf_devs_lock); | ||
2034 | return -ENODEV; | ||
2035 | |||
2036 | match: | ||
2037 | file->private_data = unit->ac97_codec[i]; | ||
2038 | |||
2039 | return nonseekable_open(inode, file); | ||
2040 | } | ||
2041 | |||
2042 | static int ymf_ioctl_mixdev(struct inode *inode, struct file *file, | ||
2043 | unsigned int cmd, unsigned long arg) | ||
2044 | { | ||
2045 | struct ac97_codec *codec = (struct ac97_codec *)file->private_data; | ||
2046 | |||
2047 | return codec->mixer_ioctl(codec, cmd, arg); | ||
2048 | } | ||
2049 | |||
2050 | static int ymf_release_mixdev(struct inode *inode, struct file *file) | ||
2051 | { | ||
2052 | return 0; | ||
2053 | } | ||
2054 | |||
2055 | static /*const*/ struct file_operations ymf_fops = { | ||
2056 | .owner = THIS_MODULE, | ||
2057 | .llseek = no_llseek, | ||
2058 | .read = ymf_read, | ||
2059 | .write = ymf_write, | ||
2060 | .poll = ymf_poll, | ||
2061 | .ioctl = ymf_ioctl, | ||
2062 | .mmap = ymf_mmap, | ||
2063 | .open = ymf_open, | ||
2064 | .release = ymf_release, | ||
2065 | }; | ||
2066 | |||
2067 | static /*const*/ struct file_operations ymf_mixer_fops = { | ||
2068 | .owner = THIS_MODULE, | ||
2069 | .llseek = no_llseek, | ||
2070 | .ioctl = ymf_ioctl_mixdev, | ||
2071 | .open = ymf_open_mixdev, | ||
2072 | .release = ymf_release_mixdev, | ||
2073 | }; | ||
2074 | |||
2075 | /* | ||
2076 | */ | ||
2077 | |||
2078 | static int ymf_suspend(struct pci_dev *pcidev, pm_message_t unused) | ||
2079 | { | ||
2080 | struct ymf_unit *unit = pci_get_drvdata(pcidev); | ||
2081 | unsigned long flags; | ||
2082 | struct ymf_dmabuf *dmabuf; | ||
2083 | struct list_head *p; | ||
2084 | struct ymf_state *state; | ||
2085 | struct ac97_codec *codec; | ||
2086 | int i; | ||
2087 | |||
2088 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
2089 | |||
2090 | unit->suspended = 1; | ||
2091 | |||
2092 | for (i = 0; i < NR_AC97; i++) { | ||
2093 | if ((codec = unit->ac97_codec[i]) != NULL) | ||
2094 | ac97_save_state(codec); | ||
2095 | } | ||
2096 | |||
2097 | list_for_each(p, &unit->states) { | ||
2098 | state = list_entry(p, struct ymf_state, chain); | ||
2099 | |||
2100 | dmabuf = &state->wpcm.dmabuf; | ||
2101 | dmabuf->hwptr = dmabuf->swptr = 0; | ||
2102 | dmabuf->total_bytes = 0; | ||
2103 | dmabuf->count = 0; | ||
2104 | |||
2105 | dmabuf = &state->rpcm.dmabuf; | ||
2106 | dmabuf->hwptr = dmabuf->swptr = 0; | ||
2107 | dmabuf->total_bytes = 0; | ||
2108 | dmabuf->count = 0; | ||
2109 | } | ||
2110 | |||
2111 | ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0); | ||
2112 | ymfpci_disable_dsp(unit); | ||
2113 | |||
2114 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
2115 | |||
2116 | return 0; | ||
2117 | } | ||
2118 | |||
2119 | static int ymf_resume(struct pci_dev *pcidev) | ||
2120 | { | ||
2121 | struct ymf_unit *unit = pci_get_drvdata(pcidev); | ||
2122 | unsigned long flags; | ||
2123 | struct list_head *p; | ||
2124 | struct ymf_state *state; | ||
2125 | struct ac97_codec *codec; | ||
2126 | int i; | ||
2127 | |||
2128 | ymfpci_aclink_reset(unit->pci); | ||
2129 | ymfpci_codec_ready(unit, 0, 1); /* prints diag if not ready. */ | ||
2130 | |||
2131 | #ifdef CONFIG_SOUND_YMFPCI_LEGACY | ||
2132 | /* XXX At this time the legacy registers are probably deprogrammed. */ | ||
2133 | #endif | ||
2134 | |||
2135 | ymfpci_download_image(unit); | ||
2136 | |||
2137 | ymf_memload(unit); | ||
2138 | |||
2139 | spin_lock_irqsave(&unit->reg_lock, flags); | ||
2140 | |||
2141 | if (unit->start_count) { | ||
2142 | ymfpci_writel(unit, YDSXGR_MODE, 3); | ||
2143 | unit->active_bank = ymfpci_readl(unit, YDSXGR_CTRLSELECT) & 1; | ||
2144 | } | ||
2145 | |||
2146 | for (i = 0; i < NR_AC97; i++) { | ||
2147 | if ((codec = unit->ac97_codec[i]) != NULL) | ||
2148 | ac97_restore_state(codec); | ||
2149 | } | ||
2150 | |||
2151 | unit->suspended = 0; | ||
2152 | list_for_each(p, &unit->states) { | ||
2153 | state = list_entry(p, struct ymf_state, chain); | ||
2154 | wake_up(&state->wpcm.dmabuf.wait); | ||
2155 | wake_up(&state->rpcm.dmabuf.wait); | ||
2156 | } | ||
2157 | |||
2158 | spin_unlock_irqrestore(&unit->reg_lock, flags); | ||
2159 | return 0; | ||
2160 | } | ||
2161 | |||
2162 | /* | ||
2163 | * initialization routines | ||
2164 | */ | ||
2165 | |||
2166 | #ifdef CONFIG_SOUND_YMFPCI_LEGACY | ||
2167 | |||
2168 | static int ymfpci_setup_legacy(ymfpci_t *unit, struct pci_dev *pcidev) | ||
2169 | { | ||
2170 | int v; | ||
2171 | int mpuio = -1, oplio = -1; | ||
2172 | |||
2173 | switch (unit->iomidi) { | ||
2174 | case 0x330: | ||
2175 | mpuio = 0; | ||
2176 | break; | ||
2177 | case 0x300: | ||
2178 | mpuio = 1; | ||
2179 | break; | ||
2180 | case 0x332: | ||
2181 | mpuio = 2; | ||
2182 | break; | ||
2183 | case 0x334: | ||
2184 | mpuio = 3; | ||
2185 | break; | ||
2186 | default: ; | ||
2187 | } | ||
2188 | |||
2189 | switch (unit->iosynth) { | ||
2190 | case 0x388: | ||
2191 | oplio = 0; | ||
2192 | break; | ||
2193 | case 0x398: | ||
2194 | oplio = 1; | ||
2195 | break; | ||
2196 | case 0x3a0: | ||
2197 | oplio = 2; | ||
2198 | break; | ||
2199 | case 0x3a8: | ||
2200 | oplio = 3; | ||
2201 | break; | ||
2202 | default: ; | ||
2203 | } | ||
2204 | |||
2205 | if (mpuio >= 0 || oplio >= 0) { | ||
2206 | /* 0x0020: 1 - 10 bits of I/O address decoded, 0 - 16 bits. */ | ||
2207 | v = 0x001e; | ||
2208 | pci_write_config_word(pcidev, PCIR_LEGCTRL, v); | ||
2209 | |||
2210 | switch (pcidev->device) { | ||
2211 | case PCI_DEVICE_ID_YAMAHA_724: | ||
2212 | case PCI_DEVICE_ID_YAMAHA_740: | ||
2213 | case PCI_DEVICE_ID_YAMAHA_724F: | ||
2214 | case PCI_DEVICE_ID_YAMAHA_740C: | ||
2215 | v = 0x8800; | ||
2216 | if (mpuio >= 0) { v |= mpuio<<4; } | ||
2217 | if (oplio >= 0) { v |= oplio; } | ||
2218 | pci_write_config_word(pcidev, PCIR_ELEGCTRL, v); | ||
2219 | break; | ||
2220 | |||
2221 | case PCI_DEVICE_ID_YAMAHA_744: | ||
2222 | case PCI_DEVICE_ID_YAMAHA_754: | ||
2223 | v = 0x8800; | ||
2224 | pci_write_config_word(pcidev, PCIR_ELEGCTRL, v); | ||
2225 | if (oplio >= 0) { | ||
2226 | pci_write_config_word(pcidev, PCIR_OPLADR, unit->iosynth); | ||
2227 | } | ||
2228 | if (mpuio >= 0) { | ||
2229 | pci_write_config_word(pcidev, PCIR_MPUADR, unit->iomidi); | ||
2230 | } | ||
2231 | break; | ||
2232 | |||
2233 | default: | ||
2234 | printk(KERN_ERR "ymfpci: Unknown device ID: 0x%x\n", | ||
2235 | pcidev->device); | ||
2236 | return -EINVAL; | ||
2237 | } | ||
2238 | } | ||
2239 | |||
2240 | return 0; | ||
2241 | } | ||
2242 | #endif /* CONFIG_SOUND_YMFPCI_LEGACY */ | ||
2243 | |||
2244 | static void ymfpci_aclink_reset(struct pci_dev * pci) | ||
2245 | { | ||
2246 | u8 cmd; | ||
2247 | |||
2248 | /* | ||
2249 | * In the 744, 754 only 0x01 exists, 0x02 is undefined. | ||
2250 | * It does not seem to hurt to trip both regardless of revision. | ||
2251 | */ | ||
2252 | pci_read_config_byte(pci, PCIR_DSXGCTRL, &cmd); | ||
2253 | pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc); | ||
2254 | pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd | 0x03); | ||
2255 | pci_write_config_byte(pci, PCIR_DSXGCTRL, cmd & 0xfc); | ||
2256 | |||
2257 | pci_write_config_word(pci, PCIR_DSXPWRCTRL1, 0); | ||
2258 | pci_write_config_word(pci, PCIR_DSXPWRCTRL2, 0); | ||
2259 | } | ||
2260 | |||
2261 | static void ymfpci_enable_dsp(ymfpci_t *codec) | ||
2262 | { | ||
2263 | ymfpci_writel(codec, YDSXGR_CONFIG, 0x00000001); | ||
2264 | } | ||
2265 | |||
2266 | static void ymfpci_disable_dsp(ymfpci_t *codec) | ||
2267 | { | ||
2268 | u32 val; | ||
2269 | int timeout = 1000; | ||
2270 | |||
2271 | val = ymfpci_readl(codec, YDSXGR_CONFIG); | ||
2272 | if (val) | ||
2273 | ymfpci_writel(codec, YDSXGR_CONFIG, 0x00000000); | ||
2274 | while (timeout-- > 0) { | ||
2275 | val = ymfpci_readl(codec, YDSXGR_STATUS); | ||
2276 | if ((val & 0x00000002) == 0) | ||
2277 | break; | ||
2278 | } | ||
2279 | } | ||
2280 | |||
2281 | #include "ymfpci_image.h" | ||
2282 | |||
2283 | static void ymfpci_download_image(ymfpci_t *codec) | ||
2284 | { | ||
2285 | int i, ver_1e; | ||
2286 | u16 ctrl; | ||
2287 | |||
2288 | ymfpci_writel(codec, YDSXGR_NATIVEDACOUTVOL, 0x00000000); | ||
2289 | ymfpci_disable_dsp(codec); | ||
2290 | ymfpci_writel(codec, YDSXGR_MODE, 0x00010000); | ||
2291 | ymfpci_writel(codec, YDSXGR_MODE, 0x00000000); | ||
2292 | ymfpci_writel(codec, YDSXGR_MAPOFREC, 0x00000000); | ||
2293 | ymfpci_writel(codec, YDSXGR_MAPOFEFFECT, 0x00000000); | ||
2294 | ymfpci_writel(codec, YDSXGR_PLAYCTRLBASE, 0x00000000); | ||
2295 | ymfpci_writel(codec, YDSXGR_RECCTRLBASE, 0x00000000); | ||
2296 | ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, 0x00000000); | ||
2297 | ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL); | ||
2298 | ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007); | ||
2299 | |||
2300 | /* setup DSP instruction code */ | ||
2301 | for (i = 0; i < YDSXG_DSPLENGTH / 4; i++) | ||
2302 | ymfpci_writel(codec, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]); | ||
2303 | |||
2304 | switch (codec->pci->device) { | ||
2305 | case PCI_DEVICE_ID_YAMAHA_724F: | ||
2306 | case PCI_DEVICE_ID_YAMAHA_740C: | ||
2307 | case PCI_DEVICE_ID_YAMAHA_744: | ||
2308 | case PCI_DEVICE_ID_YAMAHA_754: | ||
2309 | ver_1e = 1; | ||
2310 | break; | ||
2311 | default: | ||
2312 | ver_1e = 0; | ||
2313 | } | ||
2314 | |||
2315 | if (ver_1e) { | ||
2316 | /* setup control instruction code */ | ||
2317 | for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++) | ||
2318 | ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst1E[i]); | ||
2319 | } else { | ||
2320 | for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++) | ||
2321 | ymfpci_writel(codec, YDSXGR_CTRLINSTRAM + (i << 2), CntrlInst[i]); | ||
2322 | } | ||
2323 | |||
2324 | ymfpci_enable_dsp(codec); | ||
2325 | |||
2326 | /* 0.02s sounds not too bad, we may do schedule_timeout() later. */ | ||
2327 | mdelay(20); /* seems we need some delay after downloading image.. */ | ||
2328 | } | ||
2329 | |||
2330 | static int ymfpci_memalloc(ymfpci_t *codec) | ||
2331 | { | ||
2332 | unsigned int playback_ctrl_size; | ||
2333 | unsigned int bank_size_playback; | ||
2334 | unsigned int bank_size_capture; | ||
2335 | unsigned int bank_size_effect; | ||
2336 | unsigned int size; | ||
2337 | unsigned int off; | ||
2338 | char *ptr; | ||
2339 | dma_addr_t pba; | ||
2340 | int voice, bank; | ||
2341 | |||
2342 | playback_ctrl_size = 4 + 4 * YDSXG_PLAYBACK_VOICES; | ||
2343 | bank_size_playback = ymfpci_readl(codec, YDSXGR_PLAYCTRLSIZE) << 2; | ||
2344 | bank_size_capture = ymfpci_readl(codec, YDSXGR_RECCTRLSIZE) << 2; | ||
2345 | bank_size_effect = ymfpci_readl(codec, YDSXGR_EFFCTRLSIZE) << 2; | ||
2346 | codec->work_size = YDSXG_DEFAULT_WORK_SIZE; | ||
2347 | |||
2348 | size = ((playback_ctrl_size + 0x00ff) & ~0x00ff) + | ||
2349 | ((bank_size_playback * 2 * YDSXG_PLAYBACK_VOICES + 0xff) & ~0xff) + | ||
2350 | ((bank_size_capture * 2 * YDSXG_CAPTURE_VOICES + 0xff) & ~0xff) + | ||
2351 | ((bank_size_effect * 2 * YDSXG_EFFECT_VOICES + 0xff) & ~0xff) + | ||
2352 | codec->work_size; | ||
2353 | |||
2354 | ptr = pci_alloc_consistent(codec->pci, size + 0xff, &pba); | ||
2355 | if (ptr == NULL) | ||
2356 | return -ENOMEM; | ||
2357 | codec->dma_area_va = ptr; | ||
2358 | codec->dma_area_ba = pba; | ||
2359 | codec->dma_area_size = size + 0xff; | ||
2360 | |||
2361 | off = (unsigned long)ptr & 0xff; | ||
2362 | if (off) { | ||
2363 | ptr += 0x100 - off; | ||
2364 | pba += 0x100 - off; | ||
2365 | } | ||
2366 | |||
2367 | /* | ||
2368 | * Hardware requires only ptr[playback_ctrl_size] zeroed, | ||
2369 | * but in our judgement it is a wrong kind of savings, so clear it all. | ||
2370 | */ | ||
2371 | memset(ptr, 0, size); | ||
2372 | |||
2373 | codec->ctrl_playback = (u32 *)ptr; | ||
2374 | codec->ctrl_playback_ba = pba; | ||
2375 | codec->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES); | ||
2376 | ptr += (playback_ctrl_size + 0x00ff) & ~0x00ff; | ||
2377 | pba += (playback_ctrl_size + 0x00ff) & ~0x00ff; | ||
2378 | |||
2379 | off = 0; | ||
2380 | for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) { | ||
2381 | codec->voices[voice].number = voice; | ||
2382 | codec->voices[voice].bank = | ||
2383 | (ymfpci_playback_bank_t *) (ptr + off); | ||
2384 | codec->voices[voice].bank_ba = pba + off; | ||
2385 | off += 2 * bank_size_playback; /* 2 banks */ | ||
2386 | } | ||
2387 | off = (off + 0xff) & ~0xff; | ||
2388 | ptr += off; | ||
2389 | pba += off; | ||
2390 | |||
2391 | off = 0; | ||
2392 | codec->bank_base_capture = pba; | ||
2393 | for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++) | ||
2394 | for (bank = 0; bank < 2; bank++) { | ||
2395 | codec->bank_capture[voice][bank] = | ||
2396 | (ymfpci_capture_bank_t *) (ptr + off); | ||
2397 | off += bank_size_capture; | ||
2398 | } | ||
2399 | off = (off + 0xff) & ~0xff; | ||
2400 | ptr += off; | ||
2401 | pba += off; | ||
2402 | |||
2403 | off = 0; | ||
2404 | codec->bank_base_effect = pba; | ||
2405 | for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++) | ||
2406 | for (bank = 0; bank < 2; bank++) { | ||
2407 | codec->bank_effect[voice][bank] = | ||
2408 | (ymfpci_effect_bank_t *) (ptr + off); | ||
2409 | off += bank_size_effect; | ||
2410 | } | ||
2411 | off = (off + 0xff) & ~0xff; | ||
2412 | ptr += off; | ||
2413 | pba += off; | ||
2414 | |||
2415 | codec->work_base = pba; | ||
2416 | |||
2417 | return 0; | ||
2418 | } | ||
2419 | |||
2420 | static void ymfpci_memfree(ymfpci_t *codec) | ||
2421 | { | ||
2422 | ymfpci_writel(codec, YDSXGR_PLAYCTRLBASE, 0); | ||
2423 | ymfpci_writel(codec, YDSXGR_RECCTRLBASE, 0); | ||
2424 | ymfpci_writel(codec, YDSXGR_EFFCTRLBASE, 0); | ||
2425 | ymfpci_writel(codec, YDSXGR_WORKBASE, 0); | ||
2426 | ymfpci_writel(codec, YDSXGR_WORKSIZE, 0); | ||
2427 | pci_free_consistent(codec->pci, | ||
2428 | codec->dma_area_size, codec->dma_area_va, codec->dma_area_ba); | ||
2429 | } | ||
2430 | |||
2431 | static void ymf_memload(ymfpci_t *unit) | ||
2432 | { | ||
2433 | |||
2434 | ymfpci_writel(unit, YDSXGR_PLAYCTRLBASE, unit->ctrl_playback_ba); | ||
2435 | ymfpci_writel(unit, YDSXGR_RECCTRLBASE, unit->bank_base_capture); | ||
2436 | ymfpci_writel(unit, YDSXGR_EFFCTRLBASE, unit->bank_base_effect); | ||
2437 | ymfpci_writel(unit, YDSXGR_WORKBASE, unit->work_base); | ||
2438 | ymfpci_writel(unit, YDSXGR_WORKSIZE, unit->work_size >> 2); | ||
2439 | |||
2440 | /* S/PDIF output initialization */ | ||
2441 | ymfpci_writew(unit, YDSXGR_SPDIFOUTCTRL, 0); | ||
2442 | ymfpci_writew(unit, YDSXGR_SPDIFOUTSTATUS, | ||
2443 | SND_PCM_AES0_CON_EMPHASIS_NONE | | ||
2444 | (SND_PCM_AES1_CON_ORIGINAL << 8) | | ||
2445 | (SND_PCM_AES1_CON_PCM_CODER << 8)); | ||
2446 | |||
2447 | /* S/PDIF input initialization */ | ||
2448 | ymfpci_writew(unit, YDSXGR_SPDIFINCTRL, 0); | ||
2449 | |||
2450 | /* move this volume setup to mixer */ | ||
2451 | ymfpci_writel(unit, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff); | ||
2452 | ymfpci_writel(unit, YDSXGR_BUF441OUTVOL, 0); | ||
2453 | ymfpci_writel(unit, YDSXGR_NATIVEADCINVOL, 0x3fff3fff); | ||
2454 | ymfpci_writel(unit, YDSXGR_NATIVEDACINVOL, 0x3fff3fff); | ||
2455 | } | ||
2456 | |||
2457 | static int ymf_ac97_init(ymfpci_t *unit, int num_ac97) | ||
2458 | { | ||
2459 | struct ac97_codec *codec; | ||
2460 | u16 eid; | ||
2461 | |||
2462 | if ((codec = ac97_alloc_codec()) == NULL) | ||
2463 | return -ENOMEM; | ||
2464 | |||
2465 | /* initialize some basic codec information, other fields will be filled | ||
2466 | in ac97_probe_codec */ | ||
2467 | codec->private_data = unit; | ||
2468 | codec->id = num_ac97; | ||
2469 | |||
2470 | codec->codec_read = ymfpci_codec_read; | ||
2471 | codec->codec_write = ymfpci_codec_write; | ||
2472 | |||
2473 | if (ac97_probe_codec(codec) == 0) { | ||
2474 | printk(KERN_ERR "ymfpci: ac97_probe_codec failed\n"); | ||
2475 | goto out_kfree; | ||
2476 | } | ||
2477 | |||
2478 | eid = ymfpci_codec_read(codec, AC97_EXTENDED_ID); | ||
2479 | if (eid==0xFFFF) { | ||
2480 | printk(KERN_WARNING "ymfpci: no codec attached ?\n"); | ||
2481 | goto out_kfree; | ||
2482 | } | ||
2483 | |||
2484 | unit->ac97_features = eid; | ||
2485 | |||
2486 | if ((codec->dev_mixer = register_sound_mixer(&ymf_mixer_fops, -1)) < 0) { | ||
2487 | printk(KERN_ERR "ymfpci: couldn't register mixer!\n"); | ||
2488 | goto out_kfree; | ||
2489 | } | ||
2490 | |||
2491 | unit->ac97_codec[num_ac97] = codec; | ||
2492 | |||
2493 | return 0; | ||
2494 | out_kfree: | ||
2495 | ac97_release_codec(codec); | ||
2496 | return -ENODEV; | ||
2497 | } | ||
2498 | |||
2499 | #ifdef CONFIG_SOUND_YMFPCI_LEGACY | ||
2500 | # ifdef MODULE | ||
2501 | static int mpu_io; | ||
2502 | static int synth_io; | ||
2503 | module_param(mpu_io, int, 0); | ||
2504 | module_param(synth_io, int, 0); | ||
2505 | # else | ||
2506 | static int mpu_io = 0x330; | ||
2507 | static int synth_io = 0x388; | ||
2508 | # endif | ||
2509 | static int assigned; | ||
2510 | #endif /* CONFIG_SOUND_YMFPCI_LEGACY */ | ||
2511 | |||
2512 | static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_device_id *ent) | ||
2513 | { | ||
2514 | u16 ctrl; | ||
2515 | unsigned long base; | ||
2516 | ymfpci_t *codec; | ||
2517 | |||
2518 | int err; | ||
2519 | |||
2520 | if ((err = pci_enable_device(pcidev)) != 0) { | ||
2521 | printk(KERN_ERR "ymfpci: pci_enable_device failed\n"); | ||
2522 | return err; | ||
2523 | } | ||
2524 | base = pci_resource_start(pcidev, 0); | ||
2525 | |||
2526 | if ((codec = kmalloc(sizeof(ymfpci_t), GFP_KERNEL)) == NULL) { | ||
2527 | printk(KERN_ERR "ymfpci: no core\n"); | ||
2528 | return -ENOMEM; | ||
2529 | } | ||
2530 | memset(codec, 0, sizeof(*codec)); | ||
2531 | |||
2532 | spin_lock_init(&codec->reg_lock); | ||
2533 | spin_lock_init(&codec->voice_lock); | ||
2534 | spin_lock_init(&codec->ac97_lock); | ||
2535 | mutex_init(&codec->open_mutex); | ||
2536 | INIT_LIST_HEAD(&codec->states); | ||
2537 | codec->pci = pcidev; | ||
2538 | |||
2539 | pci_read_config_byte(pcidev, PCI_REVISION_ID, &codec->rev); | ||
2540 | |||
2541 | if (request_mem_region(base, 0x8000, "ymfpci") == NULL) { | ||
2542 | printk(KERN_ERR "ymfpci: unable to request mem region\n"); | ||
2543 | goto out_free; | ||
2544 | } | ||
2545 | |||
2546 | if ((codec->reg_area_virt = ioremap(base, 0x8000)) == NULL) { | ||
2547 | printk(KERN_ERR "ymfpci: unable to map registers\n"); | ||
2548 | goto out_release_region; | ||
2549 | } | ||
2550 | |||
2551 | pci_set_master(pcidev); | ||
2552 | |||
2553 | printk(KERN_INFO "ymfpci: %s at 0x%lx IRQ %d\n", | ||
2554 | (char *)ent->driver_data, base, pcidev->irq); | ||
2555 | |||
2556 | ymfpci_aclink_reset(pcidev); | ||
2557 | if (ymfpci_codec_ready(codec, 0, 1) < 0) | ||
2558 | goto out_unmap; | ||
2559 | |||
2560 | #ifdef CONFIG_SOUND_YMFPCI_LEGACY | ||
2561 | if (assigned == 0) { | ||
2562 | codec->iomidi = mpu_io; | ||
2563 | codec->iosynth = synth_io; | ||
2564 | if (ymfpci_setup_legacy(codec, pcidev) < 0) | ||
2565 | goto out_unmap; | ||
2566 | assigned = 1; | ||
2567 | } | ||
2568 | #endif | ||
2569 | |||
2570 | ymfpci_download_image(codec); | ||
2571 | |||
2572 | if (ymfpci_memalloc(codec) < 0) | ||
2573 | goto out_disable_dsp; | ||
2574 | ymf_memload(codec); | ||
2575 | |||
2576 | if (request_irq(pcidev->irq, ymf_interrupt, IRQF_SHARED, "ymfpci", codec) != 0) { | ||
2577 | printk(KERN_ERR "ymfpci: unable to request IRQ %d\n", | ||
2578 | pcidev->irq); | ||
2579 | goto out_memfree; | ||
2580 | } | ||
2581 | |||
2582 | /* register /dev/dsp */ | ||
2583 | if ((codec->dev_audio = register_sound_dsp(&ymf_fops, -1)) < 0) { | ||
2584 | printk(KERN_ERR "ymfpci: unable to register dsp\n"); | ||
2585 | goto out_free_irq; | ||
2586 | } | ||
2587 | |||
2588 | /* | ||
2589 | * Poke just the primary for the moment. | ||
2590 | */ | ||
2591 | if ((err = ymf_ac97_init(codec, 0)) != 0) | ||
2592 | goto out_unregister_sound_dsp; | ||
2593 | |||
2594 | #ifdef CONFIG_SOUND_YMFPCI_LEGACY | ||
2595 | codec->opl3_data.name = "ymfpci"; | ||
2596 | codec->mpu_data.name = "ymfpci"; | ||
2597 | |||
2598 | codec->opl3_data.io_base = codec->iosynth; | ||
2599 | codec->opl3_data.irq = -1; | ||
2600 | |||
2601 | codec->mpu_data.io_base = codec->iomidi; | ||
2602 | codec->mpu_data.irq = -1; /* May be different from our PCI IRQ. */ | ||
2603 | |||
2604 | if (codec->iomidi) { | ||
2605 | if (!probe_uart401(&codec->mpu_data, THIS_MODULE)) { | ||
2606 | codec->iomidi = 0; /* XXX kludge */ | ||
2607 | } | ||
2608 | } | ||
2609 | #endif /* CONFIG_SOUND_YMFPCI_LEGACY */ | ||
2610 | |||
2611 | /* put it into driver list */ | ||
2612 | spin_lock(&ymf_devs_lock); | ||
2613 | list_add_tail(&codec->ymf_devs, &ymf_devs); | ||
2614 | spin_unlock(&ymf_devs_lock); | ||
2615 | pci_set_drvdata(pcidev, codec); | ||
2616 | |||
2617 | return 0; | ||
2618 | |||
2619 | out_unregister_sound_dsp: | ||
2620 | unregister_sound_dsp(codec->dev_audio); | ||
2621 | out_free_irq: | ||
2622 | free_irq(pcidev->irq, codec); | ||
2623 | out_memfree: | ||
2624 | ymfpci_memfree(codec); | ||
2625 | out_disable_dsp: | ||
2626 | ymfpci_disable_dsp(codec); | ||
2627 | ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL); | ||
2628 | ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007); | ||
2629 | ymfpci_writel(codec, YDSXGR_STATUS, ~0); | ||
2630 | out_unmap: | ||
2631 | iounmap(codec->reg_area_virt); | ||
2632 | out_release_region: | ||
2633 | release_mem_region(pci_resource_start(pcidev, 0), 0x8000); | ||
2634 | out_free: | ||
2635 | if (codec->ac97_codec[0]) | ||
2636 | ac97_release_codec(codec->ac97_codec[0]); | ||
2637 | return -ENODEV; | ||
2638 | } | ||
2639 | |||
2640 | static void __devexit ymf_remove_one(struct pci_dev *pcidev) | ||
2641 | { | ||
2642 | __u16 ctrl; | ||
2643 | ymfpci_t *codec = pci_get_drvdata(pcidev); | ||
2644 | |||
2645 | /* remove from list of devices */ | ||
2646 | spin_lock(&ymf_devs_lock); | ||
2647 | list_del(&codec->ymf_devs); | ||
2648 | spin_unlock(&ymf_devs_lock); | ||
2649 | |||
2650 | unregister_sound_mixer(codec->ac97_codec[0]->dev_mixer); | ||
2651 | ac97_release_codec(codec->ac97_codec[0]); | ||
2652 | unregister_sound_dsp(codec->dev_audio); | ||
2653 | free_irq(pcidev->irq, codec); | ||
2654 | ymfpci_memfree(codec); | ||
2655 | ymfpci_writel(codec, YDSXGR_STATUS, ~0); | ||
2656 | ymfpci_disable_dsp(codec); | ||
2657 | ctrl = ymfpci_readw(codec, YDSXGR_GLOBALCTRL); | ||
2658 | ymfpci_writew(codec, YDSXGR_GLOBALCTRL, ctrl & ~0x0007); | ||
2659 | iounmap(codec->reg_area_virt); | ||
2660 | release_mem_region(pci_resource_start(pcidev, 0), 0x8000); | ||
2661 | #ifdef CONFIG_SOUND_YMFPCI_LEGACY | ||
2662 | if (codec->iomidi) { | ||
2663 | unload_uart401(&codec->mpu_data); | ||
2664 | } | ||
2665 | #endif /* CONFIG_SOUND_YMFPCI_LEGACY */ | ||
2666 | } | ||
2667 | |||
2668 | MODULE_AUTHOR("Jaroslav Kysela"); | ||
2669 | MODULE_DESCRIPTION("Yamaha YMF7xx PCI Audio"); | ||
2670 | MODULE_LICENSE("GPL"); | ||
2671 | |||
2672 | static struct pci_driver ymfpci_driver = { | ||
2673 | .name = "ymfpci", | ||
2674 | .id_table = ymf_id_tbl, | ||
2675 | .probe = ymf_probe_one, | ||
2676 | .remove = __devexit_p(ymf_remove_one), | ||
2677 | .suspend = ymf_suspend, | ||
2678 | .resume = ymf_resume | ||
2679 | }; | ||
2680 | |||
2681 | static int __init ymf_init_module(void) | ||
2682 | { | ||
2683 | return pci_register_driver(&ymfpci_driver); | ||
2684 | } | ||
2685 | |||
2686 | static void __exit ymf_cleanup_module (void) | ||
2687 | { | ||
2688 | pci_unregister_driver(&ymfpci_driver); | ||
2689 | } | ||
2690 | |||
2691 | module_init(ymf_init_module); | ||
2692 | module_exit(ymf_cleanup_module); | ||
diff --git a/sound/oss/ymfpci.h b/sound/oss/ymfpci.h deleted file mode 100644 index ac1785f2b7e7..000000000000 --- a/sound/oss/ymfpci.h +++ /dev/null | |||
@@ -1,361 +0,0 @@ | |||
1 | #ifndef __YMFPCI_H | ||
2 | #define __YMFPCI_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (c) by Jaroslav Kysela <perex@suse.cz> | ||
6 | * Definitions for Yahama YMF724/740/744/754 chips | ||
7 | * | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * | ||
23 | */ | ||
24 | #include <linux/config.h> | ||
25 | #include <linux/mutex.h> | ||
26 | |||
27 | /* | ||
28 | * Direct registers | ||
29 | */ | ||
30 | |||
31 | /* #define YMFREG(codec, reg) (codec->port + YDSXGR_##reg) */ | ||
32 | |||
33 | #define YDSXGR_INTFLAG 0x0004 | ||
34 | #define YDSXGR_ACTIVITY 0x0006 | ||
35 | #define YDSXGR_GLOBALCTRL 0x0008 | ||
36 | #define YDSXGR_ZVCTRL 0x000A | ||
37 | #define YDSXGR_TIMERCTRL 0x0010 | ||
38 | #define YDSXGR_TIMERCTRL_TEN 0x0001 | ||
39 | #define YDSXGR_TIMERCTRL_TIEN 0x0002 | ||
40 | #define YDSXGR_TIMERCOUNT 0x0012 | ||
41 | #define YDSXGR_SPDIFOUTCTRL 0x0018 | ||
42 | #define YDSXGR_SPDIFOUTSTATUS 0x001C | ||
43 | #define YDSXGR_EEPROMCTRL 0x0020 | ||
44 | #define YDSXGR_SPDIFINCTRL 0x0034 | ||
45 | #define YDSXGR_SPDIFINSTATUS 0x0038 | ||
46 | #define YDSXGR_DSPPROGRAMDL 0x0048 | ||
47 | #define YDSXGR_DLCNTRL 0x004C | ||
48 | #define YDSXGR_GPIOININTFLAG 0x0050 | ||
49 | #define YDSXGR_GPIOININTENABLE 0x0052 | ||
50 | #define YDSXGR_GPIOINSTATUS 0x0054 | ||
51 | #define YDSXGR_GPIOOUTCTRL 0x0056 | ||
52 | #define YDSXGR_GPIOFUNCENABLE 0x0058 | ||
53 | #define YDSXGR_GPIOTYPECONFIG 0x005A | ||
54 | #define YDSXGR_AC97CMDDATA 0x0060 | ||
55 | #define YDSXGR_AC97CMDADR 0x0062 | ||
56 | #define YDSXGR_PRISTATUSDATA 0x0064 | ||
57 | #define YDSXGR_PRISTATUSADR 0x0066 | ||
58 | #define YDSXGR_SECSTATUSDATA 0x0068 | ||
59 | #define YDSXGR_SECSTATUSADR 0x006A | ||
60 | #define YDSXGR_SECCONFIG 0x0070 | ||
61 | #define YDSXGR_LEGACYOUTVOL 0x0080 | ||
62 | #define YDSXGR_LEGACYOUTVOLL 0x0080 | ||
63 | #define YDSXGR_LEGACYOUTVOLR 0x0082 | ||
64 | #define YDSXGR_NATIVEDACOUTVOL 0x0084 | ||
65 | #define YDSXGR_NATIVEDACOUTVOLL 0x0084 | ||
66 | #define YDSXGR_NATIVEDACOUTVOLR 0x0086 | ||
67 | #define YDSXGR_SPDIFOUTVOL 0x0088 | ||
68 | #define YDSXGR_SPDIFOUTVOLL 0x0088 | ||
69 | #define YDSXGR_SPDIFOUTVOLR 0x008A | ||
70 | #define YDSXGR_AC3OUTVOL 0x008C | ||
71 | #define YDSXGR_AC3OUTVOLL 0x008C | ||
72 | #define YDSXGR_AC3OUTVOLR 0x008E | ||
73 | #define YDSXGR_PRIADCOUTVOL 0x0090 | ||
74 | #define YDSXGR_PRIADCOUTVOLL 0x0090 | ||
75 | #define YDSXGR_PRIADCOUTVOLR 0x0092 | ||
76 | #define YDSXGR_LEGACYLOOPVOL 0x0094 | ||
77 | #define YDSXGR_LEGACYLOOPVOLL 0x0094 | ||
78 | #define YDSXGR_LEGACYLOOPVOLR 0x0096 | ||
79 | #define YDSXGR_NATIVEDACLOOPVOL 0x0098 | ||
80 | #define YDSXGR_NATIVEDACLOOPVOLL 0x0098 | ||
81 | #define YDSXGR_NATIVEDACLOOPVOLR 0x009A | ||
82 | #define YDSXGR_SPDIFLOOPVOL 0x009C | ||
83 | #define YDSXGR_SPDIFLOOPVOLL 0x009E | ||
84 | #define YDSXGR_SPDIFLOOPVOLR 0x009E | ||
85 | #define YDSXGR_AC3LOOPVOL 0x00A0 | ||
86 | #define YDSXGR_AC3LOOPVOLL 0x00A0 | ||
87 | #define YDSXGR_AC3LOOPVOLR 0x00A2 | ||
88 | #define YDSXGR_PRIADCLOOPVOL 0x00A4 | ||
89 | #define YDSXGR_PRIADCLOOPVOLL 0x00A4 | ||
90 | #define YDSXGR_PRIADCLOOPVOLR 0x00A6 | ||
91 | #define YDSXGR_NATIVEADCINVOL 0x00A8 | ||
92 | #define YDSXGR_NATIVEADCINVOLL 0x00A8 | ||
93 | #define YDSXGR_NATIVEADCINVOLR 0x00AA | ||
94 | #define YDSXGR_NATIVEDACINVOL 0x00AC | ||
95 | #define YDSXGR_NATIVEDACINVOLL 0x00AC | ||
96 | #define YDSXGR_NATIVEDACINVOLR 0x00AE | ||
97 | #define YDSXGR_BUF441OUTVOL 0x00B0 | ||
98 | #define YDSXGR_BUF441OUTVOLL 0x00B0 | ||
99 | #define YDSXGR_BUF441OUTVOLR 0x00B2 | ||
100 | #define YDSXGR_BUF441LOOPVOL 0x00B4 | ||
101 | #define YDSXGR_BUF441LOOPVOLL 0x00B4 | ||
102 | #define YDSXGR_BUF441LOOPVOLR 0x00B6 | ||
103 | #define YDSXGR_SPDIFOUTVOL2 0x00B8 | ||
104 | #define YDSXGR_SPDIFOUTVOL2L 0x00B8 | ||
105 | #define YDSXGR_SPDIFOUTVOL2R 0x00BA | ||
106 | #define YDSXGR_SPDIFLOOPVOL2 0x00BC | ||
107 | #define YDSXGR_SPDIFLOOPVOL2L 0x00BC | ||
108 | #define YDSXGR_SPDIFLOOPVOL2R 0x00BE | ||
109 | #define YDSXGR_ADCSLOTSR 0x00C0 | ||
110 | #define YDSXGR_RECSLOTSR 0x00C4 | ||
111 | #define YDSXGR_ADCFORMAT 0x00C8 | ||
112 | #define YDSXGR_RECFORMAT 0x00CC | ||
113 | #define YDSXGR_P44SLOTSR 0x00D0 | ||
114 | #define YDSXGR_STATUS 0x0100 | ||
115 | #define YDSXGR_CTRLSELECT 0x0104 | ||
116 | #define YDSXGR_MODE 0x0108 | ||
117 | #define YDSXGR_SAMPLECOUNT 0x010C | ||
118 | #define YDSXGR_NUMOFSAMPLES 0x0110 | ||
119 | #define YDSXGR_CONFIG 0x0114 | ||
120 | #define YDSXGR_PLAYCTRLSIZE 0x0140 | ||
121 | #define YDSXGR_RECCTRLSIZE 0x0144 | ||
122 | #define YDSXGR_EFFCTRLSIZE 0x0148 | ||
123 | #define YDSXGR_WORKSIZE 0x014C | ||
124 | #define YDSXGR_MAPOFREC 0x0150 | ||
125 | #define YDSXGR_MAPOFEFFECT 0x0154 | ||
126 | #define YDSXGR_PLAYCTRLBASE 0x0158 | ||
127 | #define YDSXGR_RECCTRLBASE 0x015C | ||
128 | #define YDSXGR_EFFCTRLBASE 0x0160 | ||
129 | #define YDSXGR_WORKBASE 0x0164 | ||
130 | #define YDSXGR_DSPINSTRAM 0x1000 | ||
131 | #define YDSXGR_CTRLINSTRAM 0x4000 | ||
132 | |||
133 | #define YDSXG_AC97READCMD 0x8000 | ||
134 | #define YDSXG_AC97WRITECMD 0x0000 | ||
135 | |||
136 | #define PCIR_LEGCTRL 0x40 | ||
137 | #define PCIR_ELEGCTRL 0x42 | ||
138 | #define PCIR_DSXGCTRL 0x48 | ||
139 | #define PCIR_DSXPWRCTRL1 0x4a | ||
140 | #define PCIR_DSXPWRCTRL2 0x4e | ||
141 | #define PCIR_OPLADR 0x60 | ||
142 | #define PCIR_SBADR 0x62 | ||
143 | #define PCIR_MPUADR 0x64 | ||
144 | |||
145 | #define YDSXG_DSPLENGTH 0x0080 | ||
146 | #define YDSXG_CTRLLENGTH 0x3000 | ||
147 | |||
148 | #define YDSXG_DEFAULT_WORK_SIZE 0x0400 | ||
149 | |||
150 | #define YDSXG_PLAYBACK_VOICES 64 | ||
151 | #define YDSXG_CAPTURE_VOICES 2 | ||
152 | #define YDSXG_EFFECT_VOICES 5 | ||
153 | |||
154 | /* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */ | ||
155 | #define NR_AC97 2 | ||
156 | |||
157 | #define YMF_SAMPF 256 /* Samples per frame @48000 */ | ||
158 | |||
159 | /* | ||
160 | * The slot/voice control bank (2 of these per voice) | ||
161 | */ | ||
162 | |||
163 | typedef struct stru_ymfpci_playback_bank { | ||
164 | u32 format; | ||
165 | u32 loop_default; | ||
166 | u32 base; /* 32-bit address */ | ||
167 | u32 loop_start; /* 32-bit offset */ | ||
168 | u32 loop_end; /* 32-bit offset */ | ||
169 | u32 loop_frac; /* 8-bit fraction - loop_start */ | ||
170 | u32 delta_end; /* pitch delta end */ | ||
171 | u32 lpfK_end; | ||
172 | u32 eg_gain_end; | ||
173 | u32 left_gain_end; | ||
174 | u32 right_gain_end; | ||
175 | u32 eff1_gain_end; | ||
176 | u32 eff2_gain_end; | ||
177 | u32 eff3_gain_end; | ||
178 | u32 lpfQ; | ||
179 | u32 status; /* P3: Always 0 for some reason. */ | ||
180 | u32 num_of_frames; | ||
181 | u32 loop_count; | ||
182 | u32 start; /* P3: J. reads this to know where chip is. */ | ||
183 | u32 start_frac; | ||
184 | u32 delta; | ||
185 | u32 lpfK; | ||
186 | u32 eg_gain; | ||
187 | u32 left_gain; | ||
188 | u32 right_gain; | ||
189 | u32 eff1_gain; | ||
190 | u32 eff2_gain; | ||
191 | u32 eff3_gain; | ||
192 | u32 lpfD1; | ||
193 | u32 lpfD2; | ||
194 | } ymfpci_playback_bank_t; | ||
195 | |||
196 | typedef struct stru_ymfpci_capture_bank { | ||
197 | u32 base; /* 32-bit address (aligned at 4) */ | ||
198 | u32 loop_end; /* size in BYTES (aligned at 4) */ | ||
199 | u32 start; /* 32-bit offset */ | ||
200 | u32 num_of_loops; /* counter */ | ||
201 | } ymfpci_capture_bank_t; | ||
202 | |||
203 | typedef struct stru_ymfpci_effect_bank { | ||
204 | u32 base; /* 32-bit address */ | ||
205 | u32 loop_end; /* 32-bit offset */ | ||
206 | u32 start; /* 32-bit offset */ | ||
207 | u32 temp; | ||
208 | } ymfpci_effect_bank_t; | ||
209 | |||
210 | typedef struct ymf_voice ymfpci_voice_t; | ||
211 | /* | ||
212 | * Throughout the code Yaroslav names YMF unit pointer "codec" | ||
213 | * even though it does not correspond to any codec. Must be historic. | ||
214 | * We replace it with "unit" over time. | ||
215 | * AC97 parts use "codec" to denote a codec, naturally. | ||
216 | */ | ||
217 | typedef struct ymf_unit ymfpci_t; | ||
218 | |||
219 | typedef enum { | ||
220 | YMFPCI_PCM, | ||
221 | YMFPCI_SYNTH, | ||
222 | YMFPCI_MIDI | ||
223 | } ymfpci_voice_type_t; | ||
224 | |||
225 | struct ymf_voice { | ||
226 | // ymfpci_t *codec; | ||
227 | int number; | ||
228 | char use, pcm, synth, midi; // bool | ||
229 | ymfpci_playback_bank_t *bank; | ||
230 | struct ymf_pcm *ypcm; | ||
231 | dma_addr_t bank_ba; | ||
232 | }; | ||
233 | |||
234 | struct ymf_capture { | ||
235 | // struct ymf_unit *unit; | ||
236 | int use; | ||
237 | ymfpci_capture_bank_t *bank; | ||
238 | struct ymf_pcm *ypcm; | ||
239 | }; | ||
240 | |||
241 | struct ymf_unit { | ||
242 | u8 rev; /* PCI revision */ | ||
243 | void __iomem *reg_area_virt; | ||
244 | void *dma_area_va; | ||
245 | dma_addr_t dma_area_ba; | ||
246 | unsigned int dma_area_size; | ||
247 | |||
248 | dma_addr_t bank_base_capture; | ||
249 | dma_addr_t bank_base_effect; | ||
250 | dma_addr_t work_base; | ||
251 | unsigned int work_size; | ||
252 | |||
253 | u32 *ctrl_playback; | ||
254 | dma_addr_t ctrl_playback_ba; | ||
255 | ymfpci_playback_bank_t *bank_playback[YDSXG_PLAYBACK_VOICES][2]; | ||
256 | ymfpci_capture_bank_t *bank_capture[YDSXG_CAPTURE_VOICES][2]; | ||
257 | ymfpci_effect_bank_t *bank_effect[YDSXG_EFFECT_VOICES][2]; | ||
258 | |||
259 | int start_count; | ||
260 | int suspended; | ||
261 | |||
262 | u32 active_bank; | ||
263 | struct ymf_voice voices[YDSXG_PLAYBACK_VOICES]; | ||
264 | struct ymf_capture capture[YDSXG_CAPTURE_VOICES]; | ||
265 | |||
266 | struct ac97_codec *ac97_codec[NR_AC97]; | ||
267 | u16 ac97_features; | ||
268 | |||
269 | struct pci_dev *pci; | ||
270 | |||
271 | #ifdef CONFIG_SOUND_YMFPCI_LEGACY | ||
272 | /* legacy hardware resources */ | ||
273 | unsigned int iosynth, iomidi; | ||
274 | struct address_info opl3_data, mpu_data; | ||
275 | #endif | ||
276 | |||
277 | spinlock_t reg_lock; | ||
278 | spinlock_t voice_lock; | ||
279 | spinlock_t ac97_lock; | ||
280 | |||
281 | /* soundcore stuff */ | ||
282 | int dev_audio; | ||
283 | struct mutex open_mutex; | ||
284 | |||
285 | struct list_head ymf_devs; | ||
286 | struct list_head states; /* List of states for this unit */ | ||
287 | }; | ||
288 | |||
289 | struct ymf_dmabuf { | ||
290 | dma_addr_t dma_addr; | ||
291 | void *rawbuf; | ||
292 | unsigned buforder; | ||
293 | |||
294 | /* OSS buffer management stuff */ | ||
295 | unsigned numfrag; | ||
296 | unsigned fragshift; | ||
297 | |||
298 | /* our buffer acts like a circular ring */ | ||
299 | unsigned hwptr; /* where dma last started */ | ||
300 | unsigned swptr; /* where driver last clear/filled */ | ||
301 | int count; /* fill count */ | ||
302 | unsigned total_bytes; /* total bytes dmaed by hardware */ | ||
303 | |||
304 | wait_queue_head_t wait; /* put process on wait queue when no more space in buffer */ | ||
305 | |||
306 | /* redundant, but makes calculations easier */ | ||
307 | unsigned fragsize; | ||
308 | unsigned dmasize; /* Total rawbuf[] size */ | ||
309 | |||
310 | /* OSS stuff */ | ||
311 | unsigned mapped:1; | ||
312 | unsigned ready:1; | ||
313 | unsigned ossfragshift; | ||
314 | int ossmaxfrags; | ||
315 | unsigned subdivision; | ||
316 | }; | ||
317 | |||
318 | struct ymf_pcm_format { | ||
319 | int format; /* OSS format */ | ||
320 | int rate; /* rate in Hz */ | ||
321 | int voices; /* number of voices */ | ||
322 | int shift; /* redundant, computed from the above */ | ||
323 | }; | ||
324 | |||
325 | typedef enum { | ||
326 | PLAYBACK_VOICE, | ||
327 | CAPTURE_REC, | ||
328 | CAPTURE_AC97, | ||
329 | EFFECT_DRY_LEFT, | ||
330 | EFFECT_DRY_RIGHT, | ||
331 | EFFECT_EFF1, | ||
332 | EFFECT_EFF2, | ||
333 | EFFECT_EFF3 | ||
334 | } ymfpci_pcm_type_t; | ||
335 | |||
336 | /* This is variant record, but we hate unions. Little waste on pointers []. */ | ||
337 | struct ymf_pcm { | ||
338 | ymfpci_pcm_type_t type; | ||
339 | struct ymf_state *state; | ||
340 | |||
341 | ymfpci_voice_t *voices[2]; | ||
342 | int capture_bank_number; | ||
343 | |||
344 | struct ymf_dmabuf dmabuf; | ||
345 | int running; | ||
346 | int spdif; | ||
347 | }; | ||
348 | |||
349 | /* | ||
350 | * "Software" or virtual channel, an instance of opened /dev/dsp. | ||
351 | * It may have two physical channels (pcms) for duplex operations. | ||
352 | */ | ||
353 | |||
354 | struct ymf_state { | ||
355 | struct list_head chain; | ||
356 | struct ymf_unit *unit; /* backpointer */ | ||
357 | struct ymf_pcm rpcm, wpcm; | ||
358 | struct ymf_pcm_format format; | ||
359 | }; | ||
360 | |||
361 | #endif /* __YMFPCI_H */ | ||
diff --git a/sound/oss/ymfpci_image.h b/sound/oss/ymfpci_image.h deleted file mode 100644 index 112f2fff6c8e..000000000000 --- a/sound/oss/ymfpci_image.h +++ /dev/null | |||
@@ -1,1565 +0,0 @@ | |||
1 | #ifndef _HWMCODE_ | ||
2 | #define _HWMCODE_ | ||
3 | |||
4 | static u32 DspInst[YDSXG_DSPLENGTH / 4] = { | ||
5 | 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, | ||
6 | 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, | ||
7 | 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, | ||
8 | 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000, | ||
9 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
10 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
11 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
12 | 0x00000000, 0x00000000, 0x00000000, 0x00000000 | ||
13 | }; | ||
14 | |||
15 | static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = { | ||
16 | 0x000007, 0x240007, 0x0C0007, 0x1C0007, | ||
17 | 0x060007, 0x700002, 0x000020, 0x030040, | ||
18 | 0x007104, 0x004286, 0x030040, 0x000F0D, | ||
19 | 0x000810, 0x20043A, 0x000282, 0x00020D, | ||
20 | 0x000810, 0x20043A, 0x001282, 0x200E82, | ||
21 | 0x001A82, 0x032D0D, 0x000810, 0x10043A, | ||
22 | 0x02D38D, 0x000810, 0x18043A, 0x00010D, | ||
23 | 0x020015, 0x0000FD, 0x000020, 0x038860, | ||
24 | 0x039060, 0x038060, 0x038040, 0x038040, | ||
25 | 0x038040, 0x018040, 0x000A7D, 0x038040, | ||
26 | 0x038040, 0x018040, 0x200402, 0x000882, | ||
27 | 0x08001A, 0x000904, 0x015986, 0x000007, | ||
28 | 0x260007, 0x000007, 0x000007, 0x018A06, | ||
29 | 0x000007, 0x030C8D, 0x000810, 0x18043A, | ||
30 | 0x260007, 0x00087D, 0x018042, 0x00160A, | ||
31 | 0x04A206, 0x000007, 0x00218D, 0x000810, | ||
32 | 0x08043A, 0x21C206, 0x000007, 0x0007FD, | ||
33 | 0x018042, 0x08000A, 0x000904, 0x029386, | ||
34 | 0x000195, 0x090D04, 0x000007, 0x000820, | ||
35 | 0x0000F5, 0x000B7D, 0x01F060, 0x0000FD, | ||
36 | 0x032206, 0x018040, 0x000A7D, 0x038042, | ||
37 | 0x13804A, 0x18000A, 0x001820, 0x059060, | ||
38 | 0x058860, 0x018040, 0x0000FD, 0x018042, | ||
39 | 0x70000A, 0x000115, 0x071144, 0x032386, | ||
40 | 0x030000, 0x007020, 0x034A06, 0x018040, | ||
41 | 0x00348D, 0x000810, 0x08043A, 0x21EA06, | ||
42 | 0x000007, 0x02D38D, 0x000810, 0x18043A, | ||
43 | 0x018206, 0x000007, 0x240007, 0x000F8D, | ||
44 | 0x000810, 0x00163A, 0x002402, 0x005C02, | ||
45 | 0x0028FD, 0x000020, 0x018040, 0x08000D, | ||
46 | 0x000815, 0x510984, 0x000007, 0x00004D, | ||
47 | 0x000E5D, 0x000E02, 0x00418D, 0x000810, | ||
48 | 0x08043A, 0x2C8A06, 0x000007, 0x00008D, | ||
49 | 0x000924, 0x000F02, 0x00458D, 0x000810, | ||
50 | 0x08043A, 0x2C8A06, 0x000007, 0x00387D, | ||
51 | 0x018042, 0x08000A, 0x001015, 0x010984, | ||
52 | 0x018386, 0x000007, 0x01AA06, 0x000007, | ||
53 | 0x0008FD, 0x018042, 0x18000A, 0x001904, | ||
54 | 0x218086, 0x280007, 0x001810, 0x28043A, | ||
55 | 0x280C02, 0x00000D, 0x000810, 0x28143A, | ||
56 | 0x08808D, 0x000820, 0x0002FD, 0x018040, | ||
57 | 0x200007, 0x00020D, 0x189904, 0x000007, | ||
58 | 0x00402D, 0x0000BD, 0x0002FD, 0x018042, | ||
59 | 0x08000A, 0x000904, 0x055A86, 0x000007, | ||
60 | 0x000100, 0x000A20, 0x00047D, 0x018040, | ||
61 | 0x018042, 0x20000A, 0x003015, 0x012144, | ||
62 | 0x034986, 0x000007, 0x002104, 0x034986, | ||
63 | 0x000007, 0x000F8D, 0x000810, 0x280C3A, | ||
64 | 0x023944, 0x06C986, 0x000007, 0x001810, | ||
65 | 0x28043A, 0x08810D, 0x000820, 0x0002FD, | ||
66 | 0x018040, 0x200007, 0x002810, 0x78003A, | ||
67 | 0x00688D, 0x000810, 0x08043A, 0x288A06, | ||
68 | 0x000007, 0x00400D, 0x001015, 0x189904, | ||
69 | 0x292904, 0x393904, 0x000007, 0x060206, | ||
70 | 0x000007, 0x0004F5, 0x00007D, 0x000020, | ||
71 | 0x00008D, 0x010860, 0x018040, 0x00047D, | ||
72 | 0x038042, 0x21804A, 0x18000A, 0x021944, | ||
73 | 0x215886, 0x000007, 0x004075, 0x71F104, | ||
74 | 0x000007, 0x010042, 0x28000A, 0x002904, | ||
75 | 0x212086, 0x000007, 0x003C0D, 0x30A904, | ||
76 | 0x000007, 0x00077D, 0x018042, 0x08000A, | ||
77 | 0x000904, 0x07DA86, 0x00057D, 0x002820, | ||
78 | 0x03B060, 0x07F206, 0x018040, 0x003020, | ||
79 | 0x03A860, 0x018040, 0x0002FD, 0x018042, | ||
80 | 0x08000A, 0x000904, 0x07FA86, 0x000007, | ||
81 | 0x00057D, 0x018042, 0x28040A, 0x000E8D, | ||
82 | 0x000810, 0x280C3A, 0x00000D, 0x000810, | ||
83 | 0x28143A, 0x09000D, 0x000820, 0x0002FD, | ||
84 | 0x018040, 0x200007, 0x003DFD, 0x000020, | ||
85 | 0x018040, 0x00107D, 0x008D8D, 0x000810, | ||
86 | 0x08043A, 0x288A06, 0x000007, 0x000815, | ||
87 | 0x08001A, 0x010984, 0x095186, 0x00137D, | ||
88 | 0x200500, 0x280F20, 0x338F60, 0x3B8F60, | ||
89 | 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, | ||
90 | 0x038A60, 0x018040, 0x007FBD, 0x383DC4, | ||
91 | 0x000007, 0x001A7D, 0x001375, 0x018042, | ||
92 | 0x09004A, 0x10000A, 0x0B8D04, 0x139504, | ||
93 | 0x000007, 0x000820, 0x019060, 0x001104, | ||
94 | 0x212086, 0x010040, 0x0017FD, 0x018042, | ||
95 | 0x08000A, 0x000904, 0x212286, 0x000007, | ||
96 | 0x00197D, 0x038042, 0x09804A, 0x10000A, | ||
97 | 0x000924, 0x001664, 0x0011FD, 0x038042, | ||
98 | 0x2B804A, 0x19804A, 0x00008D, 0x218944, | ||
99 | 0x000007, 0x002244, 0x0AE186, 0x000007, | ||
100 | 0x001A64, 0x002A24, 0x00197D, 0x080102, | ||
101 | 0x100122, 0x000820, 0x039060, 0x018040, | ||
102 | 0x003DFD, 0x00008D, 0x000820, 0x018040, | ||
103 | 0x001375, 0x001A7D, 0x010042, 0x09804A, | ||
104 | 0x10000A, 0x00021D, 0x0189E4, 0x2992E4, | ||
105 | 0x309144, 0x000007, 0x00060D, 0x000A15, | ||
106 | 0x000C1D, 0x001025, 0x00A9E4, 0x012BE4, | ||
107 | 0x000464, 0x01B3E4, 0x0232E4, 0x000464, | ||
108 | 0x000464, 0x000464, 0x000464, 0x00040D, | ||
109 | 0x08B1C4, 0x000007, 0x000820, 0x000BF5, | ||
110 | 0x030040, 0x00197D, 0x038042, 0x09804A, | ||
111 | 0x000A24, 0x08000A, 0x080E64, 0x000007, | ||
112 | 0x100122, 0x000820, 0x031060, 0x010040, | ||
113 | 0x0064AC, 0x00027D, 0x000020, 0x018040, | ||
114 | 0x00107D, 0x018042, 0x0011FD, 0x3B804A, | ||
115 | 0x09804A, 0x20000A, 0x000095, 0x1A1144, | ||
116 | 0x00A144, 0x0D2086, 0x00040D, 0x00B984, | ||
117 | 0x0D2186, 0x0018FD, 0x018042, 0x0010FD, | ||
118 | 0x09804A, 0x28000A, 0x000095, 0x010924, | ||
119 | 0x002A64, 0x0D1186, 0x000007, 0x002904, | ||
120 | 0x0D2286, 0x000007, 0x0D2A06, 0x080002, | ||
121 | 0x00008D, 0x00387D, 0x000820, 0x018040, | ||
122 | 0x00127D, 0x018042, 0x10000A, 0x003904, | ||
123 | 0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984, | ||
124 | 0x0DA186, 0x000025, 0x0E7A06, 0x00002D, | ||
125 | 0x000015, 0x00082D, 0x02C78D, 0x000820, | ||
126 | 0x0EC206, 0x00000D, 0x7F8035, 0x00B984, | ||
127 | 0x0E7186, 0x400025, 0x00008D, 0x110944, | ||
128 | 0x000007, 0x00018D, 0x109504, 0x000007, | ||
129 | 0x009164, 0x000424, 0x000424, 0x000424, | ||
130 | 0x100102, 0x280002, 0x02C68D, 0x000820, | ||
131 | 0x0EC206, 0x00018D, 0x00042D, 0x00008D, | ||
132 | 0x109504, 0x000007, 0x00020D, 0x109184, | ||
133 | 0x000007, 0x02C70D, 0x000820, 0x00008D, | ||
134 | 0x0038FD, 0x018040, 0x003BFD, 0x001020, | ||
135 | 0x03A860, 0x000815, 0x313184, 0x212184, | ||
136 | 0x000007, 0x03B060, 0x03A060, 0x018040, | ||
137 | 0x0022FD, 0x000095, 0x010924, 0x000424, | ||
138 | 0x000424, 0x001264, 0x100102, 0x000820, | ||
139 | 0x039060, 0x018040, 0x001924, 0x00FB8D, | ||
140 | 0x00397D, 0x000820, 0x058040, 0x038042, | ||
141 | 0x09844A, 0x000606, 0x08040A, 0x000424, | ||
142 | 0x000424, 0x00117D, 0x018042, 0x08000A, | ||
143 | 0x000A24, 0x280502, 0x280C02, 0x09800D, | ||
144 | 0x000820, 0x0002FD, 0x018040, 0x200007, | ||
145 | 0x0022FD, 0x018042, 0x08000A, 0x000095, | ||
146 | 0x280DC4, 0x011924, 0x00197D, 0x018042, | ||
147 | 0x0011FD, 0x09804A, 0x10000A, 0x0000B5, | ||
148 | 0x113144, 0x0A8D04, 0x000007, 0x080A44, | ||
149 | 0x129504, 0x000007, 0x0023FD, 0x001020, | ||
150 | 0x038040, 0x101244, 0x000007, 0x000820, | ||
151 | 0x039060, 0x018040, 0x0002FD, 0x018042, | ||
152 | 0x08000A, 0x000904, 0x10FA86, 0x000007, | ||
153 | 0x003BFD, 0x000100, 0x000A10, 0x0B807A, | ||
154 | 0x13804A, 0x090984, 0x000007, 0x000095, | ||
155 | 0x013D04, 0x118086, 0x10000A, 0x100002, | ||
156 | 0x090984, 0x000007, 0x038042, 0x11804A, | ||
157 | 0x090D04, 0x000007, 0x10000A, 0x090D84, | ||
158 | 0x000007, 0x00257D, 0x000820, 0x018040, | ||
159 | 0x00010D, 0x000810, 0x28143A, 0x00127D, | ||
160 | 0x018042, 0x20000A, 0x00197D, 0x018042, | ||
161 | 0x00117D, 0x31804A, 0x10000A, 0x003124, | ||
162 | 0x01280D, 0x00397D, 0x000820, 0x058040, | ||
163 | 0x038042, 0x09844A, 0x000606, 0x08040A, | ||
164 | 0x300102, 0x003124, 0x000424, 0x000424, | ||
165 | 0x001224, 0x280502, 0x001A4C, 0x130186, | ||
166 | 0x700002, 0x00002D, 0x030000, 0x00387D, | ||
167 | 0x018042, 0x10000A, 0x132A06, 0x002124, | ||
168 | 0x0000AD, 0x100002, 0x00010D, 0x000924, | ||
169 | 0x006B24, 0x01368D, 0x00397D, 0x000820, | ||
170 | 0x058040, 0x038042, 0x09844A, 0x000606, | ||
171 | 0x08040A, 0x003264, 0x00008D, 0x000A24, | ||
172 | 0x001020, 0x00227D, 0x018040, 0x013C0D, | ||
173 | 0x000810, 0x08043A, 0x29D206, 0x000007, | ||
174 | 0x002820, 0x00207D, 0x018040, 0x00117D, | ||
175 | 0x038042, 0x13804A, 0x33800A, 0x00387D, | ||
176 | 0x018042, 0x08000A, 0x000904, 0x163A86, | ||
177 | 0x000007, 0x00008D, 0x030964, 0x01478D, | ||
178 | 0x00397D, 0x000820, 0x058040, 0x038042, | ||
179 | 0x09844A, 0x000606, 0x08040A, 0x380102, | ||
180 | 0x000424, 0x000424, 0x001224, 0x0002FD, | ||
181 | 0x018042, 0x08000A, 0x000904, 0x14A286, | ||
182 | 0x000007, 0x280502, 0x001A4C, 0x163986, | ||
183 | 0x000007, 0x032164, 0x00632C, 0x003DFD, | ||
184 | 0x018042, 0x08000A, 0x000095, 0x090904, | ||
185 | 0x000007, 0x000820, 0x001A4C, 0x156186, | ||
186 | 0x018040, 0x030000, 0x157A06, 0x002124, | ||
187 | 0x00010D, 0x000924, 0x006B24, 0x015B8D, | ||
188 | 0x00397D, 0x000820, 0x058040, 0x038042, | ||
189 | 0x09844A, 0x000606, 0x08040A, 0x003A64, | ||
190 | 0x000095, 0x001224, 0x0002FD, 0x018042, | ||
191 | 0x08000A, 0x000904, 0x15DA86, 0x000007, | ||
192 | 0x01628D, 0x000810, 0x08043A, 0x29D206, | ||
193 | 0x000007, 0x14D206, 0x000007, 0x007020, | ||
194 | 0x08010A, 0x10012A, 0x0020FD, 0x038860, | ||
195 | 0x039060, 0x018040, 0x00227D, 0x018042, | ||
196 | 0x003DFD, 0x08000A, 0x31844A, 0x000904, | ||
197 | 0x16D886, 0x18008B, 0x00008D, 0x189904, | ||
198 | 0x00312C, 0x17AA06, 0x000007, 0x00324C, | ||
199 | 0x173386, 0x000007, 0x001904, 0x173086, | ||
200 | 0x000007, 0x000095, 0x199144, 0x00222C, | ||
201 | 0x003124, 0x00636C, 0x000E3D, 0x001375, | ||
202 | 0x000BFD, 0x010042, 0x09804A, 0x10000A, | ||
203 | 0x038AEC, 0x0393EC, 0x00224C, 0x17A986, | ||
204 | 0x000007, 0x00008D, 0x189904, 0x00226C, | ||
205 | 0x00322C, 0x30050A, 0x301DAB, 0x002083, | ||
206 | 0x0018FD, 0x018042, 0x08000A, 0x018924, | ||
207 | 0x300502, 0x001083, 0x001875, 0x010042, | ||
208 | 0x10000A, 0x00008D, 0x010924, 0x001375, | ||
209 | 0x330542, 0x330CCB, 0x332CCB, 0x3334CB, | ||
210 | 0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB, | ||
211 | 0x305C8B, 0x006083, 0x0002F5, 0x010042, | ||
212 | 0x08000A, 0x000904, 0x187A86, 0x000007, | ||
213 | 0x001E2D, 0x0005FD, 0x018042, 0x08000A, | ||
214 | 0x028924, 0x280502, 0x00060D, 0x000810, | ||
215 | 0x280C3A, 0x00008D, 0x000810, 0x28143A, | ||
216 | 0x0A808D, 0x000820, 0x0002F5, 0x010040, | ||
217 | 0x220007, 0x001275, 0x030042, 0x21004A, | ||
218 | 0x00008D, 0x1A0944, 0x000007, 0x01980D, | ||
219 | 0x000810, 0x08043A, 0x2B2206, 0x000007, | ||
220 | 0x0001F5, 0x030042, 0x0D004A, 0x10000A, | ||
221 | 0x089144, 0x000007, 0x000820, 0x010040, | ||
222 | 0x0025F5, 0x0A3144, 0x000007, 0x000820, | ||
223 | 0x032860, 0x030040, 0x00217D, 0x038042, | ||
224 | 0x0B804A, 0x10000A, 0x000820, 0x031060, | ||
225 | 0x030040, 0x00008D, 0x000124, 0x00012C, | ||
226 | 0x000E64, 0x001A64, 0x00636C, 0x08010A, | ||
227 | 0x10012A, 0x000820, 0x031060, 0x030040, | ||
228 | 0x0020FD, 0x018042, 0x08000A, 0x00227D, | ||
229 | 0x018042, 0x10000A, 0x000820, 0x031060, | ||
230 | 0x030040, 0x00197D, 0x018042, 0x08000A, | ||
231 | 0x0022FD, 0x038042, 0x10000A, 0x000820, | ||
232 | 0x031060, 0x030040, 0x090D04, 0x000007, | ||
233 | 0x000820, 0x030040, 0x038042, 0x0B804A, | ||
234 | 0x10000A, 0x000820, 0x031060, 0x030040, | ||
235 | 0x038042, 0x13804A, 0x19804A, 0x110D04, | ||
236 | 0x198D04, 0x000007, 0x08000A, 0x001020, | ||
237 | 0x031860, 0x030860, 0x030040, 0x00008D, | ||
238 | 0x0B0944, 0x000007, 0x000820, 0x010040, | ||
239 | 0x0005F5, 0x030042, 0x08000A, 0x000820, | ||
240 | 0x010040, 0x0000F5, 0x010042, 0x08000A, | ||
241 | 0x000904, 0x1C6086, 0x001E75, 0x030042, | ||
242 | 0x01044A, 0x000C0A, 0x1C7206, 0x000007, | ||
243 | 0x000402, 0x000C02, 0x00177D, 0x001AF5, | ||
244 | 0x018042, 0x03144A, 0x031C4A, 0x03244A, | ||
245 | 0x032C4A, 0x03344A, 0x033C4A, 0x03444A, | ||
246 | 0x004C0A, 0x00043D, 0x0013F5, 0x001AFD, | ||
247 | 0x030042, 0x0B004A, 0x1B804A, 0x13804A, | ||
248 | 0x20000A, 0x089144, 0x19A144, 0x0389E4, | ||
249 | 0x0399EC, 0x005502, 0x005D0A, 0x030042, | ||
250 | 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, | ||
251 | 0x089144, 0x19A144, 0x0389E4, 0x0399EC, | ||
252 | 0x006502, 0x006D0A, 0x030042, 0x0B004A, | ||
253 | 0x19004A, 0x2B804A, 0x13804A, 0x21804A, | ||
254 | 0x30000A, 0x089144, 0x19A144, 0x2AB144, | ||
255 | 0x0389E4, 0x0399EC, 0x007502, 0x007D0A, | ||
256 | 0x03A9E4, 0x000702, 0x00107D, 0x000415, | ||
257 | 0x018042, 0x08000A, 0x0109E4, 0x000F02, | ||
258 | 0x002AF5, 0x0019FD, 0x010042, 0x09804A, | ||
259 | 0x10000A, 0x000934, 0x001674, 0x0029F5, | ||
260 | 0x010042, 0x10000A, 0x00917C, 0x002075, | ||
261 | 0x010042, 0x08000A, 0x000904, 0x1ED286, | ||
262 | 0x0026F5, 0x0027F5, 0x030042, 0x09004A, | ||
263 | 0x10000A, 0x000A3C, 0x00167C, 0x001A75, | ||
264 | 0x000BFD, 0x010042, 0x51804A, 0x48000A, | ||
265 | 0x160007, 0x001075, 0x010042, 0x282C0A, | ||
266 | 0x281D12, 0x282512, 0x001F32, 0x1E0007, | ||
267 | 0x0E0007, 0x001975, 0x010042, 0x002DF5, | ||
268 | 0x0D004A, 0x10000A, 0x009144, 0x1FB286, | ||
269 | 0x010042, 0x28340A, 0x000E5D, 0x00008D, | ||
270 | 0x000375, 0x000820, 0x010040, 0x05D2F4, | ||
271 | 0x54D104, 0x00735C, 0x205386, 0x000007, | ||
272 | 0x0C0007, 0x080007, 0x0A0007, 0x02040D, | ||
273 | 0x000810, 0x08043A, 0x332206, 0x000007, | ||
274 | 0x205A06, 0x000007, 0x080007, 0x002275, | ||
275 | 0x010042, 0x20000A, 0x002104, 0x212086, | ||
276 | 0x001E2D, 0x0002F5, 0x010042, 0x08000A, | ||
277 | 0x000904, 0x209286, 0x000007, 0x002010, | ||
278 | 0x30043A, 0x00057D, 0x0180C3, 0x08000A, | ||
279 | 0x028924, 0x280502, 0x280C02, 0x0A810D, | ||
280 | 0x000820, 0x0002F5, 0x010040, 0x220007, | ||
281 | 0x0004FD, 0x018042, 0x70000A, 0x030000, | ||
282 | 0x007020, 0x06FA06, 0x018040, 0x02180D, | ||
283 | 0x000810, 0x08043A, 0x2B2206, 0x000007, | ||
284 | 0x0002FD, 0x018042, 0x08000A, 0x000904, | ||
285 | 0x218A86, 0x000007, 0x01F206, 0x000007, | ||
286 | 0x000875, 0x0009FD, 0x00010D, 0x220A06, | ||
287 | 0x000295, 0x000B75, 0x00097D, 0x00000D, | ||
288 | 0x000515, 0x010042, 0x18000A, 0x001904, | ||
289 | 0x287886, 0x0006F5, 0x001020, 0x010040, | ||
290 | 0x0004F5, 0x000820, 0x010040, 0x000775, | ||
291 | 0x010042, 0x09804A, 0x10000A, 0x001124, | ||
292 | 0x000904, 0x22BA86, 0x000815, 0x080102, | ||
293 | 0x101204, 0x22DA06, 0x000575, 0x081204, | ||
294 | 0x000007, 0x100102, 0x000575, 0x000425, | ||
295 | 0x021124, 0x100102, 0x000820, 0x031060, | ||
296 | 0x010040, 0x001924, 0x287886, 0x00008D, | ||
297 | 0x000464, 0x009D04, 0x278886, 0x180102, | ||
298 | 0x000575, 0x010042, 0x28040A, 0x00018D, | ||
299 | 0x000924, 0x280D02, 0x00000D, 0x000924, | ||
300 | 0x281502, 0x10000D, 0x000820, 0x0002F5, | ||
301 | 0x010040, 0x200007, 0x001175, 0x0002FD, | ||
302 | 0x018042, 0x08000A, 0x000904, 0x23C286, | ||
303 | 0x000007, 0x000100, 0x080B20, 0x130B60, | ||
304 | 0x1B0B60, 0x030A60, 0x010040, 0x050042, | ||
305 | 0x3D004A, 0x35004A, 0x2D004A, 0x20000A, | ||
306 | 0x0006F5, 0x010042, 0x28140A, 0x0004F5, | ||
307 | 0x010042, 0x08000A, 0x000315, 0x010D04, | ||
308 | 0x24CA86, 0x004015, 0x000095, 0x010D04, | ||
309 | 0x24B886, 0x100022, 0x10002A, 0x24E206, | ||
310 | 0x000007, 0x333104, 0x2AA904, 0x000007, | ||
311 | 0x032124, 0x280502, 0x001124, 0x000424, | ||
312 | 0x000424, 0x003224, 0x00292C, 0x00636C, | ||
313 | 0x25F386, 0x000007, 0x02B164, 0x000464, | ||
314 | 0x000464, 0x00008D, 0x000A64, 0x280D02, | ||
315 | 0x10008D, 0x000820, 0x0002F5, 0x010040, | ||
316 | 0x220007, 0x00008D, 0x38B904, 0x000007, | ||
317 | 0x03296C, 0x30010A, 0x0002F5, 0x010042, | ||
318 | 0x08000A, 0x000904, 0x25BA86, 0x000007, | ||
319 | 0x02312C, 0x28050A, 0x00008D, 0x01096C, | ||
320 | 0x280D0A, 0x10010D, 0x000820, 0x0002F5, | ||
321 | 0x010040, 0x220007, 0x001124, 0x000424, | ||
322 | 0x000424, 0x003224, 0x300102, 0x032944, | ||
323 | 0x267A86, 0x000007, 0x300002, 0x0004F5, | ||
324 | 0x010042, 0x08000A, 0x000315, 0x010D04, | ||
325 | 0x26C086, 0x003124, 0x000464, 0x300102, | ||
326 | 0x0002F5, 0x010042, 0x08000A, 0x000904, | ||
327 | 0x26CA86, 0x000007, 0x003124, 0x300502, | ||
328 | 0x003924, 0x300583, 0x000883, 0x0005F5, | ||
329 | 0x010042, 0x28040A, 0x00008D, 0x008124, | ||
330 | 0x280D02, 0x00008D, 0x008124, 0x281502, | ||
331 | 0x10018D, 0x000820, 0x0002F5, 0x010040, | ||
332 | 0x220007, 0x001025, 0x000575, 0x030042, | ||
333 | 0x09004A, 0x10000A, 0x0A0904, 0x121104, | ||
334 | 0x000007, 0x001020, 0x050860, 0x050040, | ||
335 | 0x0006FD, 0x018042, 0x09004A, 0x10000A, | ||
336 | 0x0000A5, 0x0A0904, 0x121104, 0x000007, | ||
337 | 0x000820, 0x019060, 0x010040, 0x0002F5, | ||
338 | 0x010042, 0x08000A, 0x000904, 0x284286, | ||
339 | 0x000007, 0x230A06, 0x000007, 0x000606, | ||
340 | 0x000007, 0x0002F5, 0x010042, 0x08000A, | ||
341 | 0x000904, 0x289286, 0x000007, 0x000100, | ||
342 | 0x080B20, 0x138B60, 0x1B8B60, 0x238B60, | ||
343 | 0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60, | ||
344 | 0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60, | ||
345 | 0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60, | ||
346 | 0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60, | ||
347 | 0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60, | ||
348 | 0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60, | ||
349 | 0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60, | ||
350 | 0x000606, 0x018040, 0x00008D, 0x000A64, | ||
351 | 0x280D02, 0x000A24, 0x00027D, 0x018042, | ||
352 | 0x10000A, 0x001224, 0x0003FD, 0x018042, | ||
353 | 0x08000A, 0x000904, 0x2A8286, 0x000007, | ||
354 | 0x00018D, 0x000A24, 0x000464, 0x000464, | ||
355 | 0x080102, 0x000924, 0x000424, 0x000424, | ||
356 | 0x100102, 0x02000D, 0x009144, 0x2AD986, | ||
357 | 0x000007, 0x0001FD, 0x018042, 0x08000A, | ||
358 | 0x000A44, 0x2ABB86, 0x018042, 0x0A000D, | ||
359 | 0x000820, 0x0002FD, 0x018040, 0x200007, | ||
360 | 0x00027D, 0x001020, 0x000606, 0x018040, | ||
361 | 0x0002F5, 0x010042, 0x08000A, 0x000904, | ||
362 | 0x2B2A86, 0x000007, 0x00037D, 0x018042, | ||
363 | 0x08000A, 0x000904, 0x2B5A86, 0x000007, | ||
364 | 0x000075, 0x002E7D, 0x010042, 0x0B804A, | ||
365 | 0x000020, 0x000904, 0x000686, 0x010040, | ||
366 | 0x31844A, 0x30048B, 0x000883, 0x00008D, | ||
367 | 0x000810, 0x28143A, 0x00008D, 0x000810, | ||
368 | 0x280C3A, 0x000675, 0x010042, 0x08000A, | ||
369 | 0x003815, 0x010924, 0x280502, 0x0B000D, | ||
370 | 0x000820, 0x0002F5, 0x010040, 0x000606, | ||
371 | 0x220007, 0x000464, 0x000464, 0x000606, | ||
372 | 0x000007, 0x000134, 0x007F8D, 0x00093C, | ||
373 | 0x281D12, 0x282512, 0x001F32, 0x0E0007, | ||
374 | 0x00010D, 0x00037D, 0x000820, 0x018040, | ||
375 | 0x05D2F4, 0x000007, 0x080007, 0x00037D, | ||
376 | 0x018042, 0x08000A, 0x000904, 0x2D0286, | ||
377 | 0x000007, 0x000606, 0x000007, 0x000007, | ||
378 | 0x000012, 0x100007, 0x320007, 0x600007, | ||
379 | 0x100080, 0x48001A, 0x004904, 0x2D6186, | ||
380 | 0x000007, 0x001210, 0x58003A, 0x000145, | ||
381 | 0x5C5D04, 0x000007, 0x000080, 0x48001A, | ||
382 | 0x004904, 0x2DB186, 0x000007, 0x001210, | ||
383 | 0x50003A, 0x005904, 0x2E0886, 0x000045, | ||
384 | 0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524, | ||
385 | 0x004224, 0x500102, 0x200502, 0x000082, | ||
386 | 0x40001A, 0x004104, 0x2E3986, 0x000007, | ||
387 | 0x003865, 0x40001A, 0x004020, 0x00104D, | ||
388 | 0x04C184, 0x301B86, 0x000040, 0x040007, | ||
389 | 0x000165, 0x000145, 0x004020, 0x000040, | ||
390 | 0x000765, 0x080080, 0x40001A, 0x004104, | ||
391 | 0x2EC986, 0x000007, 0x001210, 0x40003A, | ||
392 | 0x004104, 0x2F2286, 0x00004D, 0x0000CD, | ||
393 | 0x004810, 0x20043A, 0x000882, 0x40001A, | ||
394 | 0x004104, 0x2F3186, 0x000007, 0x004820, | ||
395 | 0x005904, 0x300886, 0x000040, 0x0007E5, | ||
396 | 0x200480, 0x2816A0, 0x3216E0, 0x3A16E0, | ||
397 | 0x4216E0, 0x021260, 0x000040, 0x000032, | ||
398 | 0x400075, 0x00007D, 0x07D574, 0x200512, | ||
399 | 0x000082, 0x40001A, 0x004104, 0x2FE186, | ||
400 | 0x000007, 0x037206, 0x640007, 0x060007, | ||
401 | 0x0000E5, 0x000020, 0x000040, 0x000A65, | ||
402 | 0x000020, 0x020040, 0x020040, 0x000040, | ||
403 | 0x000165, 0x000042, 0x70000A, 0x007104, | ||
404 | 0x30A286, 0x000007, 0x018206, 0x640007, | ||
405 | 0x050000, 0x007020, 0x000040, 0x037206, | ||
406 | 0x640007, 0x000007, 0x00306D, 0x028860, | ||
407 | 0x029060, 0x08000A, 0x028860, 0x008040, | ||
408 | 0x100012, 0x00100D, 0x009184, 0x314186, | ||
409 | 0x000E0D, 0x009184, 0x325186, 0x000007, | ||
410 | 0x300007, 0x001020, 0x003B6D, 0x008040, | ||
411 | 0x000080, 0x08001A, 0x000904, 0x316186, | ||
412 | 0x000007, 0x001220, 0x000DED, 0x008040, | ||
413 | 0x008042, 0x10000A, 0x40000D, 0x109544, | ||
414 | 0x000007, 0x001020, 0x000DED, 0x008040, | ||
415 | 0x008042, 0x20040A, 0x000082, 0x08001A, | ||
416 | 0x000904, 0x31F186, 0x000007, 0x003B6D, | ||
417 | 0x008042, 0x08000A, 0x000E15, 0x010984, | ||
418 | 0x329B86, 0x600007, 0x08001A, 0x000C15, | ||
419 | 0x010984, 0x328386, 0x000020, 0x1A0007, | ||
420 | 0x0002ED, 0x008040, 0x620007, 0x00306D, | ||
421 | 0x028042, 0x0A804A, 0x000820, 0x0A804A, | ||
422 | 0x000606, 0x10804A, 0x000007, 0x282512, | ||
423 | 0x001F32, 0x05D2F4, 0x54D104, 0x00735C, | ||
424 | 0x000786, 0x000007, 0x0C0007, 0x0A0007, | ||
425 | 0x1C0007, 0x003465, 0x020040, 0x004820, | ||
426 | 0x025060, 0x40000A, 0x024060, 0x000040, | ||
427 | 0x454944, 0x000007, 0x004020, 0x003AE5, | ||
428 | 0x000040, 0x0028E5, 0x000042, 0x48000A, | ||
429 | 0x004904, 0x386886, 0x002C65, 0x000042, | ||
430 | 0x40000A, 0x0000D5, 0x454104, 0x000007, | ||
431 | 0x000655, 0x054504, 0x34F286, 0x0001D5, | ||
432 | 0x054504, 0x34F086, 0x002B65, 0x000042, | ||
433 | 0x003AE5, 0x50004A, 0x40000A, 0x45C3D4, | ||
434 | 0x000007, 0x454504, 0x000007, 0x0000CD, | ||
435 | 0x444944, 0x000007, 0x454504, 0x000007, | ||
436 | 0x00014D, 0x554944, 0x000007, 0x045144, | ||
437 | 0x34E986, 0x002C65, 0x000042, 0x48000A, | ||
438 | 0x4CD104, 0x000007, 0x04C144, 0x34F386, | ||
439 | 0x000007, 0x160007, 0x002CE5, 0x040042, | ||
440 | 0x40000A, 0x004020, 0x000040, 0x002965, | ||
441 | 0x000042, 0x40000A, 0x004104, 0x356086, | ||
442 | 0x000007, 0x002402, 0x36A206, 0x005C02, | ||
443 | 0x0025E5, 0x000042, 0x40000A, 0x004274, | ||
444 | 0x002AE5, 0x000042, 0x40000A, 0x004274, | ||
445 | 0x500112, 0x0029E5, 0x000042, 0x40000A, | ||
446 | 0x004234, 0x454104, 0x000007, 0x004020, | ||
447 | 0x000040, 0x003EE5, 0x000020, 0x000040, | ||
448 | 0x002DE5, 0x400152, 0x50000A, 0x045144, | ||
449 | 0x364A86, 0x0000C5, 0x003EE5, 0x004020, | ||
450 | 0x000040, 0x002BE5, 0x000042, 0x40000A, | ||
451 | 0x404254, 0x000007, 0x002AE5, 0x004020, | ||
452 | 0x000040, 0x500132, 0x040134, 0x005674, | ||
453 | 0x0029E5, 0x020042, 0x42000A, 0x000042, | ||
454 | 0x50000A, 0x05417C, 0x0028E5, 0x000042, | ||
455 | 0x48000A, 0x0000C5, 0x4CC144, 0x371086, | ||
456 | 0x0026E5, 0x0027E5, 0x020042, 0x40004A, | ||
457 | 0x50000A, 0x00423C, 0x00567C, 0x0028E5, | ||
458 | 0x004820, 0x000040, 0x281D12, 0x282512, | ||
459 | 0x001F72, 0x002965, 0x000042, 0x40000A, | ||
460 | 0x004104, 0x37AA86, 0x0E0007, 0x160007, | ||
461 | 0x1E0007, 0x003EE5, 0x000042, 0x40000A, | ||
462 | 0x004104, 0x37E886, 0x002D65, 0x000042, | ||
463 | 0x28340A, 0x003465, 0x020042, 0x42004A, | ||
464 | 0x004020, 0x4A004A, 0x50004A, 0x05D2F4, | ||
465 | 0x54D104, 0x00735C, 0x385186, 0x000007, | ||
466 | 0x000606, 0x080007, 0x0C0007, 0x080007, | ||
467 | 0x0A0007, 0x0001E5, 0x020045, 0x004020, | ||
468 | 0x000060, 0x000365, 0x000040, 0x002E65, | ||
469 | 0x001A20, 0x0A1A60, 0x000040, 0x003465, | ||
470 | 0x020042, 0x42004A, 0x004020, 0x4A004A, | ||
471 | 0x000606, 0x50004A, 0x000000, 0x000000, | ||
472 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
473 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
474 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
475 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
476 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
477 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
478 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
479 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
480 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
481 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
482 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
483 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
484 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
485 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
486 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
487 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
488 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
489 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
490 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
491 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
492 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
493 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
494 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
495 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
496 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
497 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
498 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
499 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
500 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
501 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
502 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
503 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
504 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
505 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
506 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
507 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
508 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
509 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
510 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
511 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
512 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
513 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
514 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
515 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
516 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
517 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
518 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
519 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
520 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
521 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
522 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
523 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
524 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
525 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
526 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
527 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
528 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
529 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
530 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
531 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
532 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
533 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
534 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
535 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
536 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
537 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
538 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
539 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
540 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
541 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
542 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
543 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
544 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
545 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
546 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
547 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
548 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
549 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
550 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
551 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
552 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
553 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
554 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
555 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
556 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
557 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
558 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
559 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
560 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
561 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
562 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
563 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
564 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
565 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
566 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
567 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
568 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
569 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
570 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
571 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
572 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
573 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
574 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
575 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
576 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
577 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
578 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
579 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
580 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
581 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
582 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
583 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
584 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
585 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
586 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
587 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
588 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
589 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
590 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
591 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
592 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
593 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
594 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
595 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
596 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
597 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
598 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
599 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
600 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
601 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
602 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
603 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
604 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
605 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
606 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
607 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
608 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
609 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
610 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
611 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
612 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
613 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
614 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
615 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
616 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
617 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
618 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
619 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
620 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
621 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
622 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
623 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
624 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
625 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
626 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
627 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
628 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
629 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
630 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
631 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
632 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
633 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
634 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
635 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
636 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
637 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
638 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
639 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
640 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
641 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
642 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
643 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
644 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
645 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
646 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
647 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
648 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
649 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
650 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
651 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
652 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
653 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
654 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
655 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
656 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
657 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
658 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
659 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
660 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
661 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
662 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
663 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
664 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
665 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
666 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
667 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
668 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
669 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
670 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
671 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
672 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
673 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
674 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
675 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
676 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
677 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
678 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
679 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
680 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
681 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
682 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
683 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
684 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
685 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
686 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
687 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
688 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
689 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
690 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
691 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
692 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
693 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
694 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
695 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
696 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
697 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
698 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
699 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
700 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
701 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
702 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
703 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
704 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
705 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
706 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
707 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
708 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
709 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
710 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
711 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
712 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
713 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
714 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
715 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
716 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
717 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
718 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
719 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
720 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
721 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
722 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
723 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
724 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
725 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
726 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
727 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
728 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
729 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
730 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
731 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
732 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
733 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
734 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
735 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
736 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
737 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
738 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
739 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
740 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
741 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
742 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
743 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
744 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
745 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
746 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
747 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
748 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
749 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
750 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
751 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
752 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
753 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
754 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
755 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
756 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
757 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
758 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
759 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
760 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
761 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
762 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
763 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
764 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
765 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
766 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
767 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
768 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
769 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
770 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
771 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
772 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
773 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
774 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
775 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
776 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
777 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
778 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
779 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
780 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
781 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
782 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
783 | 0x000000, 0x000000, 0x000000, 0x000000 | ||
784 | }; | ||
785 | |||
786 | // -------------------------------------------- | ||
787 | // DS-1E Controller InstructionRAM Code | ||
788 | // 1999/06/21 | ||
789 | // Buf441 slot is Enabled. | ||
790 | // -------------------------------------------- | ||
791 | // 04/09 creat | ||
792 | // 04/12 stop nise fix | ||
793 | // 06/21 WorkingOff timming | ||
794 | static u32 CntrlInst1E[YDSXG_CTRLLENGTH / 4] = { | ||
795 | 0x000007, 0x240007, 0x0C0007, 0x1C0007, | ||
796 | 0x060007, 0x700002, 0x000020, 0x030040, | ||
797 | 0x007104, 0x004286, 0x030040, 0x000F0D, | ||
798 | 0x000810, 0x20043A, 0x000282, 0x00020D, | ||
799 | 0x000810, 0x20043A, 0x001282, 0x200E82, | ||
800 | 0x00800D, 0x000810, 0x20043A, 0x001A82, | ||
801 | 0x03460D, 0x000810, 0x10043A, 0x02EC0D, | ||
802 | 0x000810, 0x18043A, 0x00010D, 0x020015, | ||
803 | 0x0000FD, 0x000020, 0x038860, 0x039060, | ||
804 | 0x038060, 0x038040, 0x038040, 0x038040, | ||
805 | 0x018040, 0x000A7D, 0x038040, 0x038040, | ||
806 | 0x018040, 0x200402, 0x000882, 0x08001A, | ||
807 | 0x000904, 0x017186, 0x000007, 0x260007, | ||
808 | 0x400007, 0x000007, 0x03258D, 0x000810, | ||
809 | 0x18043A, 0x260007, 0x284402, 0x00087D, | ||
810 | 0x018042, 0x00160A, 0x05A206, 0x000007, | ||
811 | 0x440007, 0x00230D, 0x000810, 0x08043A, | ||
812 | 0x22FA06, 0x000007, 0x0007FD, 0x018042, | ||
813 | 0x08000A, 0x000904, 0x02AB86, 0x000195, | ||
814 | 0x090D04, 0x000007, 0x000820, 0x0000F5, | ||
815 | 0x000B7D, 0x01F060, 0x0000FD, 0x033A06, | ||
816 | 0x018040, 0x000A7D, 0x038042, 0x13804A, | ||
817 | 0x18000A, 0x001820, 0x059060, 0x058860, | ||
818 | 0x018040, 0x0000FD, 0x018042, 0x70000A, | ||
819 | 0x000115, 0x071144, 0x033B86, 0x030000, | ||
820 | 0x007020, 0x036206, 0x018040, 0x00360D, | ||
821 | 0x000810, 0x08043A, 0x232206, 0x000007, | ||
822 | 0x02EC0D, 0x000810, 0x18043A, 0x019A06, | ||
823 | 0x000007, 0x240007, 0x000F8D, 0x000810, | ||
824 | 0x00163A, 0x002402, 0x005C02, 0x0028FD, | ||
825 | 0x000020, 0x018040, 0x08000D, 0x000815, | ||
826 | 0x510984, 0x000007, 0x00004D, 0x000E5D, | ||
827 | 0x000E02, 0x00430D, 0x000810, 0x08043A, | ||
828 | 0x2E1206, 0x000007, 0x00008D, 0x000924, | ||
829 | 0x000F02, 0x00470D, 0x000810, 0x08043A, | ||
830 | 0x2E1206, 0x000007, 0x480480, 0x001210, | ||
831 | 0x28043A, 0x00778D, 0x000810, 0x280C3A, | ||
832 | 0x00068D, 0x000810, 0x28143A, 0x284402, | ||
833 | 0x03258D, 0x000810, 0x18043A, 0x07FF8D, | ||
834 | 0x000820, 0x0002FD, 0x018040, 0x260007, | ||
835 | 0x200007, 0x0002FD, 0x018042, 0x08000A, | ||
836 | 0x000904, 0x051286, 0x000007, 0x240007, | ||
837 | 0x02EC0D, 0x000810, 0x18043A, 0x00387D, | ||
838 | 0x018042, 0x08000A, 0x001015, 0x010984, | ||
839 | 0x019B86, 0x000007, 0x01B206, 0x000007, | ||
840 | 0x0008FD, 0x018042, 0x18000A, 0x001904, | ||
841 | 0x22B886, 0x280007, 0x001810, 0x28043A, | ||
842 | 0x280C02, 0x00000D, 0x000810, 0x28143A, | ||
843 | 0x08808D, 0x000820, 0x0002FD, 0x018040, | ||
844 | 0x200007, 0x00020D, 0x189904, 0x000007, | ||
845 | 0x00402D, 0x0000BD, 0x0002FD, 0x018042, | ||
846 | 0x08000A, 0x000904, 0x065A86, 0x000007, | ||
847 | 0x000100, 0x000A20, 0x00047D, 0x018040, | ||
848 | 0x018042, 0x20000A, 0x003015, 0x012144, | ||
849 | 0x036186, 0x000007, 0x002104, 0x036186, | ||
850 | 0x000007, 0x000F8D, 0x000810, 0x280C3A, | ||
851 | 0x023944, 0x07C986, 0x000007, 0x001810, | ||
852 | 0x28043A, 0x08810D, 0x000820, 0x0002FD, | ||
853 | 0x018040, 0x200007, 0x002810, 0x78003A, | ||
854 | 0x00788D, 0x000810, 0x08043A, 0x2A1206, | ||
855 | 0x000007, 0x00400D, 0x001015, 0x189904, | ||
856 | 0x292904, 0x393904, 0x000007, 0x070206, | ||
857 | 0x000007, 0x0004F5, 0x00007D, 0x000020, | ||
858 | 0x00008D, 0x010860, 0x018040, 0x00047D, | ||
859 | 0x038042, 0x21804A, 0x18000A, 0x021944, | ||
860 | 0x229086, 0x000007, 0x004075, 0x71F104, | ||
861 | 0x000007, 0x010042, 0x28000A, 0x002904, | ||
862 | 0x225886, 0x000007, 0x003C0D, 0x30A904, | ||
863 | 0x000007, 0x00077D, 0x018042, 0x08000A, | ||
864 | 0x000904, 0x08DA86, 0x00057D, 0x002820, | ||
865 | 0x03B060, 0x08F206, 0x018040, 0x003020, | ||
866 | 0x03A860, 0x018040, 0x0002FD, 0x018042, | ||
867 | 0x08000A, 0x000904, 0x08FA86, 0x000007, | ||
868 | 0x00057D, 0x018042, 0x28040A, 0x000E8D, | ||
869 | 0x000810, 0x280C3A, 0x00000D, 0x000810, | ||
870 | 0x28143A, 0x09000D, 0x000820, 0x0002FD, | ||
871 | 0x018040, 0x200007, 0x003DFD, 0x000020, | ||
872 | 0x018040, 0x00107D, 0x009D8D, 0x000810, | ||
873 | 0x08043A, 0x2A1206, 0x000007, 0x000815, | ||
874 | 0x08001A, 0x010984, 0x0A5186, 0x00137D, | ||
875 | 0x200500, 0x280F20, 0x338F60, 0x3B8F60, | ||
876 | 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, | ||
877 | 0x038A60, 0x018040, 0x00107D, 0x018042, | ||
878 | 0x08000A, 0x000215, 0x010984, 0x3A8186, | ||
879 | 0x000007, 0x007FBD, 0x383DC4, 0x000007, | ||
880 | 0x001A7D, 0x001375, 0x018042, 0x09004A, | ||
881 | 0x10000A, 0x0B8D04, 0x139504, 0x000007, | ||
882 | 0x000820, 0x019060, 0x001104, 0x225886, | ||
883 | 0x010040, 0x0017FD, 0x018042, 0x08000A, | ||
884 | 0x000904, 0x225A86, 0x000007, 0x00197D, | ||
885 | 0x038042, 0x09804A, 0x10000A, 0x000924, | ||
886 | 0x001664, 0x0011FD, 0x038042, 0x2B804A, | ||
887 | 0x19804A, 0x00008D, 0x218944, 0x000007, | ||
888 | 0x002244, 0x0C1986, 0x000007, 0x001A64, | ||
889 | 0x002A24, 0x00197D, 0x080102, 0x100122, | ||
890 | 0x000820, 0x039060, 0x018040, 0x003DFD, | ||
891 | 0x00008D, 0x000820, 0x018040, 0x001375, | ||
892 | 0x001A7D, 0x010042, 0x09804A, 0x10000A, | ||
893 | 0x00021D, 0x0189E4, 0x2992E4, 0x309144, | ||
894 | 0x000007, 0x00060D, 0x000A15, 0x000C1D, | ||
895 | 0x001025, 0x00A9E4, 0x012BE4, 0x000464, | ||
896 | 0x01B3E4, 0x0232E4, 0x000464, 0x000464, | ||
897 | 0x000464, 0x000464, 0x00040D, 0x08B1C4, | ||
898 | 0x000007, 0x000820, 0x000BF5, 0x030040, | ||
899 | 0x00197D, 0x038042, 0x09804A, 0x000A24, | ||
900 | 0x08000A, 0x080E64, 0x000007, 0x100122, | ||
901 | 0x000820, 0x031060, 0x010040, 0x0064AC, | ||
902 | 0x00027D, 0x000020, 0x018040, 0x00107D, | ||
903 | 0x018042, 0x0011FD, 0x3B804A, 0x09804A, | ||
904 | 0x20000A, 0x000095, 0x1A1144, 0x00A144, | ||
905 | 0x0E5886, 0x00040D, 0x00B984, 0x0E5986, | ||
906 | 0x0018FD, 0x018042, 0x0010FD, 0x09804A, | ||
907 | 0x28000A, 0x000095, 0x010924, 0x002A64, | ||
908 | 0x0E4986, 0x000007, 0x002904, 0x0E5A86, | ||
909 | 0x000007, 0x0E6206, 0x080002, 0x00008D, | ||
910 | 0x00387D, 0x000820, 0x018040, 0x00127D, | ||
911 | 0x018042, 0x10000A, 0x003904, 0x0F0986, | ||
912 | 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986, | ||
913 | 0x000025, 0x0FB206, 0x00002D, 0x000015, | ||
914 | 0x00082D, 0x02E00D, 0x000820, 0x0FFA06, | ||
915 | 0x00000D, 0x7F8035, 0x00B984, 0x0FA986, | ||
916 | 0x400025, 0x00008D, 0x110944, 0x000007, | ||
917 | 0x00018D, 0x109504, 0x000007, 0x009164, | ||
918 | 0x000424, 0x000424, 0x000424, 0x100102, | ||
919 | 0x280002, 0x02DF0D, 0x000820, 0x0FFA06, | ||
920 | 0x00018D, 0x00042D, 0x00008D, 0x109504, | ||
921 | 0x000007, 0x00020D, 0x109184, 0x000007, | ||
922 | 0x02DF8D, 0x000820, 0x00008D, 0x0038FD, | ||
923 | 0x018040, 0x003BFD, 0x001020, 0x03A860, | ||
924 | 0x000815, 0x313184, 0x212184, 0x000007, | ||
925 | 0x03B060, 0x03A060, 0x018040, 0x0022FD, | ||
926 | 0x000095, 0x010924, 0x000424, 0x000424, | ||
927 | 0x001264, 0x100102, 0x000820, 0x039060, | ||
928 | 0x018040, 0x001924, 0x010F0D, 0x00397D, | ||
929 | 0x000820, 0x058040, 0x038042, 0x09844A, | ||
930 | 0x000606, 0x08040A, 0x000424, 0x000424, | ||
931 | 0x00117D, 0x018042, 0x08000A, 0x000A24, | ||
932 | 0x280502, 0x280C02, 0x09800D, 0x000820, | ||
933 | 0x0002FD, 0x018040, 0x200007, 0x0022FD, | ||
934 | 0x018042, 0x08000A, 0x000095, 0x280DC4, | ||
935 | 0x011924, 0x00197D, 0x018042, 0x0011FD, | ||
936 | 0x09804A, 0x10000A, 0x0000B5, 0x113144, | ||
937 | 0x0A8D04, 0x000007, 0x080A44, 0x129504, | ||
938 | 0x000007, 0x0023FD, 0x001020, 0x038040, | ||
939 | 0x101244, 0x000007, 0x000820, 0x039060, | ||
940 | 0x018040, 0x0002FD, 0x018042, 0x08000A, | ||
941 | 0x000904, 0x123286, 0x000007, 0x003BFD, | ||
942 | 0x000100, 0x000A10, 0x0B807A, 0x13804A, | ||
943 | 0x090984, 0x000007, 0x000095, 0x013D04, | ||
944 | 0x12B886, 0x10000A, 0x100002, 0x090984, | ||
945 | 0x000007, 0x038042, 0x11804A, 0x090D04, | ||
946 | 0x000007, 0x10000A, 0x090D84, 0x000007, | ||
947 | 0x00257D, 0x000820, 0x018040, 0x00010D, | ||
948 | 0x000810, 0x28143A, 0x00127D, 0x018042, | ||
949 | 0x20000A, 0x00197D, 0x018042, 0x00117D, | ||
950 | 0x31804A, 0x10000A, 0x003124, 0x013B8D, | ||
951 | 0x00397D, 0x000820, 0x058040, 0x038042, | ||
952 | 0x09844A, 0x000606, 0x08040A, 0x300102, | ||
953 | 0x003124, 0x000424, 0x000424, 0x001224, | ||
954 | 0x280502, 0x001A4C, 0x143986, 0x700002, | ||
955 | 0x00002D, 0x030000, 0x00387D, 0x018042, | ||
956 | 0x10000A, 0x146206, 0x002124, 0x0000AD, | ||
957 | 0x100002, 0x00010D, 0x000924, 0x006B24, | ||
958 | 0x014A0D, 0x00397D, 0x000820, 0x058040, | ||
959 | 0x038042, 0x09844A, 0x000606, 0x08040A, | ||
960 | 0x003264, 0x00008D, 0x000A24, 0x001020, | ||
961 | 0x00227D, 0x018040, 0x014F8D, 0x000810, | ||
962 | 0x08043A, 0x2B5A06, 0x000007, 0x002820, | ||
963 | 0x00207D, 0x018040, 0x00117D, 0x038042, | ||
964 | 0x13804A, 0x33800A, 0x00387D, 0x018042, | ||
965 | 0x08000A, 0x000904, 0x177286, 0x000007, | ||
966 | 0x00008D, 0x030964, 0x015B0D, 0x00397D, | ||
967 | 0x000820, 0x058040, 0x038042, 0x09844A, | ||
968 | 0x000606, 0x08040A, 0x380102, 0x000424, | ||
969 | 0x000424, 0x001224, 0x0002FD, 0x018042, | ||
970 | 0x08000A, 0x000904, 0x15DA86, 0x000007, | ||
971 | 0x280502, 0x001A4C, 0x177186, 0x000007, | ||
972 | 0x032164, 0x00632C, 0x003DFD, 0x018042, | ||
973 | 0x08000A, 0x000095, 0x090904, 0x000007, | ||
974 | 0x000820, 0x001A4C, 0x169986, 0x018040, | ||
975 | 0x030000, 0x16B206, 0x002124, 0x00010D, | ||
976 | 0x000924, 0x006B24, 0x016F0D, 0x00397D, | ||
977 | 0x000820, 0x058040, 0x038042, 0x09844A, | ||
978 | 0x000606, 0x08040A, 0x003A64, 0x000095, | ||
979 | 0x001224, 0x0002FD, 0x018042, 0x08000A, | ||
980 | 0x000904, 0x171286, 0x000007, 0x01760D, | ||
981 | 0x000810, 0x08043A, 0x2B5A06, 0x000007, | ||
982 | 0x160A06, 0x000007, 0x007020, 0x08010A, | ||
983 | 0x10012A, 0x0020FD, 0x038860, 0x039060, | ||
984 | 0x018040, 0x00227D, 0x018042, 0x003DFD, | ||
985 | 0x08000A, 0x31844A, 0x000904, 0x181086, | ||
986 | 0x18008B, 0x00008D, 0x189904, 0x00312C, | ||
987 | 0x18E206, 0x000007, 0x00324C, 0x186B86, | ||
988 | 0x000007, 0x001904, 0x186886, 0x000007, | ||
989 | 0x000095, 0x199144, 0x00222C, 0x003124, | ||
990 | 0x00636C, 0x000E3D, 0x001375, 0x000BFD, | ||
991 | 0x010042, 0x09804A, 0x10000A, 0x038AEC, | ||
992 | 0x0393EC, 0x00224C, 0x18E186, 0x000007, | ||
993 | 0x00008D, 0x189904, 0x00226C, 0x00322C, | ||
994 | 0x30050A, 0x301DAB, 0x002083, 0x0018FD, | ||
995 | 0x018042, 0x08000A, 0x018924, 0x300502, | ||
996 | 0x001083, 0x001875, 0x010042, 0x10000A, | ||
997 | 0x00008D, 0x010924, 0x001375, 0x330542, | ||
998 | 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB, | ||
999 | 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B, | ||
1000 | 0x006083, 0x0002F5, 0x010042, 0x08000A, | ||
1001 | 0x000904, 0x19B286, 0x000007, 0x001E2D, | ||
1002 | 0x0005FD, 0x018042, 0x08000A, 0x028924, | ||
1003 | 0x280502, 0x00060D, 0x000810, 0x280C3A, | ||
1004 | 0x00008D, 0x000810, 0x28143A, 0x0A808D, | ||
1005 | 0x000820, 0x0002F5, 0x010040, 0x220007, | ||
1006 | 0x001275, 0x030042, 0x21004A, 0x00008D, | ||
1007 | 0x1A0944, 0x000007, 0x01AB8D, 0x000810, | ||
1008 | 0x08043A, 0x2CAA06, 0x000007, 0x0001F5, | ||
1009 | 0x030042, 0x0D004A, 0x10000A, 0x089144, | ||
1010 | 0x000007, 0x000820, 0x010040, 0x0025F5, | ||
1011 | 0x0A3144, 0x000007, 0x000820, 0x032860, | ||
1012 | 0x030040, 0x00217D, 0x038042, 0x0B804A, | ||
1013 | 0x10000A, 0x000820, 0x031060, 0x030040, | ||
1014 | 0x00008D, 0x000124, 0x00012C, 0x000E64, | ||
1015 | 0x001A64, 0x00636C, 0x08010A, 0x10012A, | ||
1016 | 0x000820, 0x031060, 0x030040, 0x0020FD, | ||
1017 | 0x018042, 0x08000A, 0x00227D, 0x018042, | ||
1018 | 0x10000A, 0x000820, 0x031060, 0x030040, | ||
1019 | 0x00197D, 0x018042, 0x08000A, 0x0022FD, | ||
1020 | 0x038042, 0x10000A, 0x000820, 0x031060, | ||
1021 | 0x030040, 0x090D04, 0x000007, 0x000820, | ||
1022 | 0x030040, 0x038042, 0x0B804A, 0x10000A, | ||
1023 | 0x000820, 0x031060, 0x030040, 0x038042, | ||
1024 | 0x13804A, 0x19804A, 0x110D04, 0x198D04, | ||
1025 | 0x000007, 0x08000A, 0x001020, 0x031860, | ||
1026 | 0x030860, 0x030040, 0x00008D, 0x0B0944, | ||
1027 | 0x000007, 0x000820, 0x010040, 0x0005F5, | ||
1028 | 0x030042, 0x08000A, 0x000820, 0x010040, | ||
1029 | 0x0000F5, 0x010042, 0x08000A, 0x000904, | ||
1030 | 0x1D9886, 0x001E75, 0x030042, 0x01044A, | ||
1031 | 0x000C0A, 0x1DAA06, 0x000007, 0x000402, | ||
1032 | 0x000C02, 0x00177D, 0x001AF5, 0x018042, | ||
1033 | 0x03144A, 0x031C4A, 0x03244A, 0x032C4A, | ||
1034 | 0x03344A, 0x033C4A, 0x03444A, 0x004C0A, | ||
1035 | 0x00043D, 0x0013F5, 0x001AFD, 0x030042, | ||
1036 | 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, | ||
1037 | 0x089144, 0x19A144, 0x0389E4, 0x0399EC, | ||
1038 | 0x005502, 0x005D0A, 0x030042, 0x0B004A, | ||
1039 | 0x1B804A, 0x13804A, 0x20000A, 0x089144, | ||
1040 | 0x19A144, 0x0389E4, 0x0399EC, 0x006502, | ||
1041 | 0x006D0A, 0x030042, 0x0B004A, 0x19004A, | ||
1042 | 0x2B804A, 0x13804A, 0x21804A, 0x30000A, | ||
1043 | 0x089144, 0x19A144, 0x2AB144, 0x0389E4, | ||
1044 | 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4, | ||
1045 | 0x000702, 0x00107D, 0x000415, 0x018042, | ||
1046 | 0x08000A, 0x0109E4, 0x000F02, 0x002AF5, | ||
1047 | 0x0019FD, 0x010042, 0x09804A, 0x10000A, | ||
1048 | 0x000934, 0x001674, 0x0029F5, 0x010042, | ||
1049 | 0x10000A, 0x00917C, 0x002075, 0x010042, | ||
1050 | 0x08000A, 0x000904, 0x200A86, 0x0026F5, | ||
1051 | 0x0027F5, 0x030042, 0x09004A, 0x10000A, | ||
1052 | 0x000A3C, 0x00167C, 0x001A75, 0x000BFD, | ||
1053 | 0x010042, 0x51804A, 0x48000A, 0x160007, | ||
1054 | 0x001075, 0x010042, 0x282C0A, 0x281D12, | ||
1055 | 0x282512, 0x001F32, 0x1E0007, 0x0E0007, | ||
1056 | 0x001975, 0x010042, 0x002DF5, 0x0D004A, | ||
1057 | 0x10000A, 0x009144, 0x20EA86, 0x010042, | ||
1058 | 0x28340A, 0x000E5D, 0x00008D, 0x000375, | ||
1059 | 0x000820, 0x010040, 0x05D2F4, 0x54D104, | ||
1060 | 0x00735C, 0x218B86, 0x000007, 0x0C0007, | ||
1061 | 0x080007, 0x0A0007, 0x02178D, 0x000810, | ||
1062 | 0x08043A, 0x34B206, 0x000007, 0x219206, | ||
1063 | 0x000007, 0x080007, 0x002275, 0x010042, | ||
1064 | 0x20000A, 0x002104, 0x225886, 0x001E2D, | ||
1065 | 0x0002F5, 0x010042, 0x08000A, 0x000904, | ||
1066 | 0x21CA86, 0x000007, 0x002010, 0x30043A, | ||
1067 | 0x00057D, 0x0180C3, 0x08000A, 0x028924, | ||
1068 | 0x280502, 0x280C02, 0x0A810D, 0x000820, | ||
1069 | 0x0002F5, 0x010040, 0x220007, 0x0004FD, | ||
1070 | 0x018042, 0x70000A, 0x030000, 0x007020, | ||
1071 | 0x07FA06, 0x018040, 0x022B8D, 0x000810, | ||
1072 | 0x08043A, 0x2CAA06, 0x000007, 0x0002FD, | ||
1073 | 0x018042, 0x08000A, 0x000904, 0x22C286, | ||
1074 | 0x000007, 0x020206, 0x000007, 0x000875, | ||
1075 | 0x0009FD, 0x00010D, 0x234206, 0x000295, | ||
1076 | 0x000B75, 0x00097D, 0x00000D, 0x000515, | ||
1077 | 0x010042, 0x18000A, 0x001904, 0x2A0086, | ||
1078 | 0x0006F5, 0x001020, 0x010040, 0x0004F5, | ||
1079 | 0x000820, 0x010040, 0x000775, 0x010042, | ||
1080 | 0x09804A, 0x10000A, 0x001124, 0x000904, | ||
1081 | 0x23F286, 0x000815, 0x080102, 0x101204, | ||
1082 | 0x241206, 0x000575, 0x081204, 0x000007, | ||
1083 | 0x100102, 0x000575, 0x000425, 0x021124, | ||
1084 | 0x100102, 0x000820, 0x031060, 0x010040, | ||
1085 | 0x001924, 0x2A0086, 0x00008D, 0x000464, | ||
1086 | 0x009D04, 0x291086, 0x180102, 0x000575, | ||
1087 | 0x010042, 0x28040A, 0x00018D, 0x000924, | ||
1088 | 0x280D02, 0x00000D, 0x000924, 0x281502, | ||
1089 | 0x10000D, 0x000820, 0x0002F5, 0x010040, | ||
1090 | 0x200007, 0x001175, 0x0002FD, 0x018042, | ||
1091 | 0x08000A, 0x000904, 0x24FA86, 0x000007, | ||
1092 | 0x000100, 0x080B20, 0x130B60, 0x1B0B60, | ||
1093 | 0x030A60, 0x010040, 0x050042, 0x3D004A, | ||
1094 | 0x35004A, 0x2D004A, 0x20000A, 0x0006F5, | ||
1095 | 0x010042, 0x28140A, 0x0004F5, 0x010042, | ||
1096 | 0x08000A, 0x000315, 0x010D04, 0x260286, | ||
1097 | 0x004015, 0x000095, 0x010D04, 0x25F086, | ||
1098 | 0x100022, 0x10002A, 0x261A06, 0x000007, | ||
1099 | 0x333104, 0x2AA904, 0x000007, 0x032124, | ||
1100 | 0x280502, 0x284402, 0x001124, 0x400102, | ||
1101 | 0x000424, 0x000424, 0x003224, 0x00292C, | ||
1102 | 0x00636C, 0x277386, 0x000007, 0x02B164, | ||
1103 | 0x000464, 0x000464, 0x00008D, 0x000A64, | ||
1104 | 0x280D02, 0x10008D, 0x000820, 0x0002F5, | ||
1105 | 0x010040, 0x220007, 0x00008D, 0x38B904, | ||
1106 | 0x000007, 0x03296C, 0x30010A, 0x0002F5, | ||
1107 | 0x010042, 0x08000A, 0x000904, 0x270286, | ||
1108 | 0x000007, 0x00212C, 0x28050A, 0x00316C, | ||
1109 | 0x00046C, 0x00046C, 0x28450A, 0x001124, | ||
1110 | 0x006B64, 0x100102, 0x00008D, 0x01096C, | ||
1111 | 0x280D0A, 0x10010D, 0x000820, 0x0002F5, | ||
1112 | 0x010040, 0x220007, 0x004124, 0x000424, | ||
1113 | 0x000424, 0x003224, 0x300102, 0x032944, | ||
1114 | 0x27FA86, 0x000007, 0x300002, 0x0004F5, | ||
1115 | 0x010042, 0x08000A, 0x000315, 0x010D04, | ||
1116 | 0x284086, 0x003124, 0x000464, 0x300102, | ||
1117 | 0x0002F5, 0x010042, 0x08000A, 0x000904, | ||
1118 | 0x284A86, 0x000007, 0x284402, 0x003124, | ||
1119 | 0x300502, 0x003924, 0x300583, 0x000883, | ||
1120 | 0x0005F5, 0x010042, 0x28040A, 0x00008D, | ||
1121 | 0x008124, 0x280D02, 0x00008D, 0x008124, | ||
1122 | 0x281502, 0x10018D, 0x000820, 0x0002F5, | ||
1123 | 0x010040, 0x220007, 0x001025, 0x000575, | ||
1124 | 0x030042, 0x09004A, 0x10000A, 0x0A0904, | ||
1125 | 0x121104, 0x000007, 0x001020, 0x050860, | ||
1126 | 0x050040, 0x0006FD, 0x018042, 0x09004A, | ||
1127 | 0x10000A, 0x0000A5, 0x0A0904, 0x121104, | ||
1128 | 0x000007, 0x000820, 0x019060, 0x010040, | ||
1129 | 0x0002F5, 0x010042, 0x08000A, 0x000904, | ||
1130 | 0x29CA86, 0x000007, 0x244206, 0x000007, | ||
1131 | 0x000606, 0x000007, 0x0002F5, 0x010042, | ||
1132 | 0x08000A, 0x000904, 0x2A1A86, 0x000007, | ||
1133 | 0x000100, 0x080B20, 0x138B60, 0x1B8B60, | ||
1134 | 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60, | ||
1135 | 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60, | ||
1136 | 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60, | ||
1137 | 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60, | ||
1138 | 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60, | ||
1139 | 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, | ||
1140 | 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60, | ||
1141 | 0x038A60, 0x000606, 0x018040, 0x00008D, | ||
1142 | 0x000A64, 0x280D02, 0x000A24, 0x00027D, | ||
1143 | 0x018042, 0x10000A, 0x001224, 0x0003FD, | ||
1144 | 0x018042, 0x08000A, 0x000904, 0x2C0A86, | ||
1145 | 0x000007, 0x00018D, 0x000A24, 0x000464, | ||
1146 | 0x000464, 0x080102, 0x000924, 0x000424, | ||
1147 | 0x000424, 0x100102, 0x02000D, 0x009144, | ||
1148 | 0x2C6186, 0x000007, 0x0001FD, 0x018042, | ||
1149 | 0x08000A, 0x000A44, 0x2C4386, 0x018042, | ||
1150 | 0x0A000D, 0x000820, 0x0002FD, 0x018040, | ||
1151 | 0x200007, 0x00027D, 0x001020, 0x000606, | ||
1152 | 0x018040, 0x0002F5, 0x010042, 0x08000A, | ||
1153 | 0x000904, 0x2CB286, 0x000007, 0x00037D, | ||
1154 | 0x018042, 0x08000A, 0x000904, 0x2CE286, | ||
1155 | 0x000007, 0x000075, 0x002E7D, 0x010042, | ||
1156 | 0x0B804A, 0x000020, 0x000904, 0x000686, | ||
1157 | 0x010040, 0x31844A, 0x30048B, 0x000883, | ||
1158 | 0x00008D, 0x000810, 0x28143A, 0x00008D, | ||
1159 | 0x000810, 0x280C3A, 0x000675, 0x010042, | ||
1160 | 0x08000A, 0x003815, 0x010924, 0x280502, | ||
1161 | 0x0B000D, 0x000820, 0x0002F5, 0x010040, | ||
1162 | 0x000606, 0x220007, 0x000464, 0x000464, | ||
1163 | 0x000606, 0x000007, 0x000134, 0x007F8D, | ||
1164 | 0x00093C, 0x281D12, 0x282512, 0x001F32, | ||
1165 | 0x0E0007, 0x00010D, 0x00037D, 0x000820, | ||
1166 | 0x018040, 0x05D2F4, 0x000007, 0x080007, | ||
1167 | 0x00037D, 0x018042, 0x08000A, 0x000904, | ||
1168 | 0x2E8A86, 0x000007, 0x000606, 0x000007, | ||
1169 | 0x000007, 0x000012, 0x100007, 0x320007, | ||
1170 | 0x600007, 0x460007, 0x100080, 0x48001A, | ||
1171 | 0x004904, 0x2EF186, 0x000007, 0x001210, | ||
1172 | 0x58003A, 0x000145, 0x5C5D04, 0x000007, | ||
1173 | 0x000080, 0x48001A, 0x004904, 0x2F4186, | ||
1174 | 0x000007, 0x001210, 0x50003A, 0x005904, | ||
1175 | 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5, | ||
1176 | 0x7FFF7D, 0x07D524, 0x004224, 0x500102, | ||
1177 | 0x200502, 0x000082, 0x40001A, 0x004104, | ||
1178 | 0x2FC986, 0x000007, 0x003865, 0x40001A, | ||
1179 | 0x004020, 0x00104D, 0x04C184, 0x31AB86, | ||
1180 | 0x000040, 0x040007, 0x000165, 0x000145, | ||
1181 | 0x004020, 0x000040, 0x000765, 0x080080, | ||
1182 | 0x40001A, 0x004104, 0x305986, 0x000007, | ||
1183 | 0x001210, 0x40003A, 0x004104, 0x30B286, | ||
1184 | 0x00004D, 0x0000CD, 0x004810, 0x20043A, | ||
1185 | 0x000882, 0x40001A, 0x004104, 0x30C186, | ||
1186 | 0x000007, 0x004820, 0x005904, 0x319886, | ||
1187 | 0x000040, 0x0007E5, 0x200480, 0x2816A0, | ||
1188 | 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260, | ||
1189 | 0x000040, 0x000032, 0x400075, 0x00007D, | ||
1190 | 0x07D574, 0x200512, 0x000082, 0x40001A, | ||
1191 | 0x004104, 0x317186, 0x000007, 0x038A06, | ||
1192 | 0x640007, 0x0000E5, 0x000020, 0x000040, | ||
1193 | 0x000A65, 0x000020, 0x020040, 0x020040, | ||
1194 | 0x000040, 0x000165, 0x000042, 0x70000A, | ||
1195 | 0x007104, 0x323286, 0x000007, 0x060007, | ||
1196 | 0x019A06, 0x640007, 0x050000, 0x007020, | ||
1197 | 0x000040, 0x038A06, 0x640007, 0x000007, | ||
1198 | 0x00306D, 0x028860, 0x029060, 0x08000A, | ||
1199 | 0x028860, 0x008040, 0x100012, 0x00100D, | ||
1200 | 0x009184, 0x32D186, 0x000E0D, 0x009184, | ||
1201 | 0x33E186, 0x000007, 0x300007, 0x001020, | ||
1202 | 0x003B6D, 0x008040, 0x000080, 0x08001A, | ||
1203 | 0x000904, 0x32F186, 0x000007, 0x001220, | ||
1204 | 0x000DED, 0x008040, 0x008042, 0x10000A, | ||
1205 | 0x40000D, 0x109544, 0x000007, 0x001020, | ||
1206 | 0x000DED, 0x008040, 0x008042, 0x20040A, | ||
1207 | 0x000082, 0x08001A, 0x000904, 0x338186, | ||
1208 | 0x000007, 0x003B6D, 0x008042, 0x08000A, | ||
1209 | 0x000E15, 0x010984, 0x342B86, 0x600007, | ||
1210 | 0x08001A, 0x000C15, 0x010984, 0x341386, | ||
1211 | 0x000020, 0x1A0007, 0x0002ED, 0x008040, | ||
1212 | 0x620007, 0x00306D, 0x028042, 0x0A804A, | ||
1213 | 0x000820, 0x0A804A, 0x000606, 0x10804A, | ||
1214 | 0x000007, 0x282512, 0x001F32, 0x05D2F4, | ||
1215 | 0x54D104, 0x00735C, 0x000786, 0x000007, | ||
1216 | 0x0C0007, 0x0A0007, 0x1C0007, 0x003465, | ||
1217 | 0x020040, 0x004820, 0x025060, 0x40000A, | ||
1218 | 0x024060, 0x000040, 0x454944, 0x000007, | ||
1219 | 0x004020, 0x003AE5, 0x000040, 0x0028E5, | ||
1220 | 0x000042, 0x48000A, 0x004904, 0x39F886, | ||
1221 | 0x002C65, 0x000042, 0x40000A, 0x0000D5, | ||
1222 | 0x454104, 0x000007, 0x000655, 0x054504, | ||
1223 | 0x368286, 0x0001D5, 0x054504, 0x368086, | ||
1224 | 0x002B65, 0x000042, 0x003AE5, 0x50004A, | ||
1225 | 0x40000A, 0x45C3D4, 0x000007, 0x454504, | ||
1226 | 0x000007, 0x0000CD, 0x444944, 0x000007, | ||
1227 | 0x454504, 0x000007, 0x00014D, 0x554944, | ||
1228 | 0x000007, 0x045144, 0x367986, 0x002C65, | ||
1229 | 0x000042, 0x48000A, 0x4CD104, 0x000007, | ||
1230 | 0x04C144, 0x368386, 0x000007, 0x160007, | ||
1231 | 0x002CE5, 0x040042, 0x40000A, 0x004020, | ||
1232 | 0x000040, 0x002965, 0x000042, 0x40000A, | ||
1233 | 0x004104, 0x36F086, 0x000007, 0x002402, | ||
1234 | 0x383206, 0x005C02, 0x0025E5, 0x000042, | ||
1235 | 0x40000A, 0x004274, 0x002AE5, 0x000042, | ||
1236 | 0x40000A, 0x004274, 0x500112, 0x0029E5, | ||
1237 | 0x000042, 0x40000A, 0x004234, 0x454104, | ||
1238 | 0x000007, 0x004020, 0x000040, 0x003EE5, | ||
1239 | 0x000020, 0x000040, 0x002DE5, 0x400152, | ||
1240 | 0x50000A, 0x045144, 0x37DA86, 0x0000C5, | ||
1241 | 0x003EE5, 0x004020, 0x000040, 0x002BE5, | ||
1242 | 0x000042, 0x40000A, 0x404254, 0x000007, | ||
1243 | 0x002AE5, 0x004020, 0x000040, 0x500132, | ||
1244 | 0x040134, 0x005674, 0x0029E5, 0x020042, | ||
1245 | 0x42000A, 0x000042, 0x50000A, 0x05417C, | ||
1246 | 0x0028E5, 0x000042, 0x48000A, 0x0000C5, | ||
1247 | 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5, | ||
1248 | 0x020042, 0x40004A, 0x50000A, 0x00423C, | ||
1249 | 0x00567C, 0x0028E5, 0x004820, 0x000040, | ||
1250 | 0x281D12, 0x282512, 0x001F72, 0x002965, | ||
1251 | 0x000042, 0x40000A, 0x004104, 0x393A86, | ||
1252 | 0x0E0007, 0x160007, 0x1E0007, 0x003EE5, | ||
1253 | 0x000042, 0x40000A, 0x004104, 0x397886, | ||
1254 | 0x002D65, 0x000042, 0x28340A, 0x003465, | ||
1255 | 0x020042, 0x42004A, 0x004020, 0x4A004A, | ||
1256 | 0x50004A, 0x05D2F4, 0x54D104, 0x00735C, | ||
1257 | 0x39E186, 0x000007, 0x000606, 0x080007, | ||
1258 | 0x0C0007, 0x080007, 0x0A0007, 0x0001E5, | ||
1259 | 0x020045, 0x004020, 0x000060, 0x000365, | ||
1260 | 0x000040, 0x002E65, 0x001A20, 0x0A1A60, | ||
1261 | 0x000040, 0x003465, 0x020042, 0x42004A, | ||
1262 | 0x004020, 0x4A004A, 0x000606, 0x50004A, | ||
1263 | 0x0017FD, 0x018042, 0x08000A, 0x000904, | ||
1264 | 0x225A86, 0x000007, 0x00107D, 0x018042, | ||
1265 | 0x0011FD, 0x33804A, 0x19804A, 0x20000A, | ||
1266 | 0x000095, 0x2A1144, 0x01A144, 0x3B9086, | ||
1267 | 0x00040D, 0x00B184, 0x3B9186, 0x0018FD, | ||
1268 | 0x018042, 0x0010FD, 0x09804A, 0x38000A, | ||
1269 | 0x000095, 0x010924, 0x003A64, 0x3B8186, | ||
1270 | 0x000007, 0x003904, 0x3B9286, 0x000007, | ||
1271 | 0x3B9A06, 0x00000D, 0x00008D, 0x000820, | ||
1272 | 0x00387D, 0x018040, 0x700002, 0x00117D, | ||
1273 | 0x018042, 0x00197D, 0x29804A, 0x30000A, | ||
1274 | 0x380002, 0x003124, 0x000424, 0x000424, | ||
1275 | 0x002A24, 0x280502, 0x00068D, 0x000810, | ||
1276 | 0x28143A, 0x00750D, 0x00B124, 0x002264, | ||
1277 | 0x3D0386, 0x284402, 0x000810, 0x280C3A, | ||
1278 | 0x0B800D, 0x000820, 0x0002FD, 0x018040, | ||
1279 | 0x200007, 0x00758D, 0x00B124, 0x100102, | ||
1280 | 0x012144, 0x3E4986, 0x001810, 0x10003A, | ||
1281 | 0x00387D, 0x018042, 0x08000A, 0x000904, | ||
1282 | 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD, | ||
1283 | 0x00008D, 0x023164, 0x000A64, 0x280D02, | ||
1284 | 0x0B808D, 0x000820, 0x0002FD, 0x018040, | ||
1285 | 0x200007, 0x00387D, 0x018042, 0x08000A, | ||
1286 | 0x000904, 0x3E3286, 0x030000, 0x0002FD, | ||
1287 | 0x018042, 0x08000A, 0x000904, 0x3D8286, | ||
1288 | 0x000007, 0x002810, 0x28043A, 0x00750D, | ||
1289 | 0x030924, 0x002264, 0x280D02, 0x02316C, | ||
1290 | 0x28450A, 0x0B810D, 0x000820, 0x0002FD, | ||
1291 | 0x018040, 0x200007, 0x00008D, 0x000A24, | ||
1292 | 0x3E4A06, 0x100102, 0x001810, 0x10003A, | ||
1293 | 0x0000BD, 0x003810, 0x30043A, 0x00187D, | ||
1294 | 0x018042, 0x0018FD, 0x09804A, 0x20000A, | ||
1295 | 0x0000AD, 0x028924, 0x07212C, 0x001010, | ||
1296 | 0x300583, 0x300D8B, 0x3014BB, 0x301C83, | ||
1297 | 0x002083, 0x00137D, 0x038042, 0x33844A, | ||
1298 | 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB, | ||
1299 | 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083, | ||
1300 | 0x001E0D, 0x0005FD, 0x018042, 0x20000A, | ||
1301 | 0x020924, 0x00068D, 0x00A96C, 0x00009D, | ||
1302 | 0x0002FD, 0x018042, 0x08000A, 0x000904, | ||
1303 | 0x3F6A86, 0x000007, 0x280502, 0x280D0A, | ||
1304 | 0x284402, 0x001810, 0x28143A, 0x0C008D, | ||
1305 | 0x000820, 0x0002FD, 0x018040, 0x220007, | ||
1306 | 0x003904, 0x225886, 0x001E0D, 0x00057D, | ||
1307 | 0x018042, 0x20000A, 0x020924, 0x0000A5, | ||
1308 | 0x0002FD, 0x018042, 0x08000A, 0x000904, | ||
1309 | 0x402A86, 0x000007, 0x280502, 0x280C02, | ||
1310 | 0x002010, 0x28143A, 0x0C010D, 0x000820, | ||
1311 | 0x0002FD, 0x018040, 0x225A06, 0x220007, | ||
1312 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1313 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1314 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1315 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1316 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1317 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1318 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1319 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1320 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1321 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1322 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1323 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1324 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1325 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1326 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1327 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1328 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1329 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1330 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1331 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1332 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1333 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1334 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1335 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1336 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1337 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1338 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1339 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1340 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1341 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1342 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1343 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1344 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1345 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1346 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1347 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1348 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1349 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1350 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1351 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1352 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1353 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1354 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1355 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1356 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1357 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1358 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1359 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1360 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1361 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1362 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1363 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1364 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1365 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1366 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1367 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1368 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1369 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1370 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1371 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1372 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1373 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1374 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1375 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1376 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1377 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1378 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1379 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1380 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1381 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1382 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1383 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1384 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1385 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1386 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1387 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1388 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1389 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1390 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1391 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1392 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1393 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1394 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1395 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1396 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1397 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1398 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1399 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1400 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1401 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1402 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1403 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1404 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1405 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1406 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1407 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1408 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1409 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1410 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1411 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1412 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1413 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1414 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1415 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1416 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1417 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1418 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1419 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1420 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1421 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1422 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1423 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1424 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1425 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1426 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1427 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1428 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1429 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1430 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1431 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1432 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1433 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1434 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1435 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1436 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1437 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1438 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1439 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1440 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1441 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1442 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1443 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1444 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1445 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1446 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1447 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1448 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1449 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1450 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1451 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1452 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1453 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1454 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1455 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1456 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1457 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1458 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1459 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1460 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1461 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1462 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1463 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1464 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1465 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1466 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1467 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1468 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1469 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1470 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1471 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1472 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1473 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1474 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1475 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1476 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1477 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1478 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1479 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1480 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1481 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1482 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1483 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1484 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1485 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1486 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1487 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1488 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1489 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1490 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1491 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1492 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1493 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1494 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1495 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1496 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1497 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1498 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1499 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1500 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1501 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1502 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1503 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1504 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1505 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1506 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1507 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1508 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1509 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1510 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1511 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1512 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1513 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1514 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1515 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1516 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1517 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1518 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1519 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1520 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1521 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1522 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1523 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1524 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1525 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1526 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1527 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1528 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1529 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1530 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1531 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1532 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1533 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1534 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1535 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1536 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1537 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1538 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1539 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1540 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1541 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1542 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1543 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1544 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1545 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1546 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1547 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1548 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1549 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1550 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1551 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1552 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1553 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1554 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1555 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1556 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1557 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1558 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1559 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1560 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1561 | 0x000000, 0x000000, 0x000000, 0x000000, | ||
1562 | 0x000000, 0x000000, 0x000000, 0x000000 | ||
1563 | }; | ||
1564 | |||
1565 | #endif //_HWMCODE_ | ||
diff --git a/sound/oss/yss225.c b/sound/oss/yss225.c deleted file mode 100644 index e700400576d8..000000000000 --- a/sound/oss/yss225.c +++ /dev/null | |||
@@ -1,319 +0,0 @@ | |||
1 | #include <linux/init.h> | ||
2 | |||
3 | unsigned char page_zero[] __initdata = { | ||
4 | 0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, | ||
5 | 0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00, | ||
6 | 0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00, | ||
7 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
9 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
10 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
11 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
12 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
14 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
15 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x19, | ||
16 | 0x01, 0x1a, 0x01, 0x20, 0x01, 0x40, 0x01, 0x17, 0x00, 0x00, 0x01, | ||
17 | 0x80, 0x01, 0x20, 0x00, 0x10, 0x01, 0xa0, 0x03, 0xd1, 0x00, 0x00, | ||
18 | 0x01, 0xf2, 0x02, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xf4, 0x02, | ||
19 | 0xe0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, | ||
20 | 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, 0x00, 0x00, | ||
21 | 0x40, 0x00, 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00, | ||
22 | 0x00, 0x92, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb3, 0x02, | ||
23 | 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x40, | ||
24 | 0x00, 0x80, 0x00, 0xf5, 0x00, 0x20, 0x00, 0x70, 0x00, 0xa0, 0x02, | ||
25 | 0x11, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, | ||
26 | 0x02, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x17, 0x00, 0x1b, 0x00, | ||
27 | 0x1d, 0x02, 0xdf | ||
28 | }; | ||
29 | |||
30 | unsigned char page_one[] __initdata = { | ||
31 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00, | ||
32 | 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00, | ||
33 | 0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, | ||
34 | 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
35 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
36 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x60, | ||
43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x80, 0x00, | ||
44 | 0x00, 0x02, 0xfb, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x1b, 0x02, 0xd7, | ||
45 | 0x00, 0x00, 0x02, 0xf7, 0x03, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, | ||
46 | 0x1c, 0x03, 0x3c, 0x00, 0x00, 0x03, 0x3f, 0x00, 0x00, 0x03, 0xc0, | ||
47 | 0x00, 0x00, 0x03, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5d, 0x00, | ||
48 | 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, 0x7d, 0x00, 0x00, 0x03, 0xc0, | ||
49 | 0x00, 0x00, 0x03, 0x9e, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x03, | ||
50 | 0xbe, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
51 | 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, | ||
52 | 0xdb, 0x00, 0x00, 0x02, 0xdb, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, | ||
53 | 0x02, 0xfb, 0x00, 0x00, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xfb, 0x02, | ||
54 | 0x60, 0x00, 0x1b | ||
55 | }; | ||
56 | |||
57 | unsigned char page_two[] __initdata = { | ||
58 | 0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4, | ||
59 | 0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, | ||
60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x07, | ||
64 | 0x05, 0x05, 0x05, 0x04, 0x07, 0x05, 0x04, 0x07, 0x05, 0x44, 0x46, | ||
65 | 0x44, 0x46, 0x46, 0x07, 0x05, 0x44, 0x46, 0x05, 0x46, 0x05, 0x46, | ||
66 | 0x05, 0x46, 0x05, 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, | ||
67 | 0x44, 0x46, 0x05, 0x07, 0x44, 0x46, 0x05, 0x07, 0x44, 0x05, 0x05, | ||
68 | 0x05, 0x44, 0x05, 0x05, 0x05, 0x46, 0x05, 0x46, 0x05, 0x46, 0x05, | ||
69 | 0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44 | ||
70 | }; | ||
71 | |||
72 | unsigned char page_three[] __initdata = { | ||
73 | 0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06, | ||
74 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
75 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
77 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
78 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, | ||
79 | 0xc0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, | ||
80 | 0x60, 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, 0x42, 0x00, 0x40, | ||
81 | 0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, | ||
82 | 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, | ||
83 | 0x00, 0x42, 0x00, 0x40, 0x00, 0x42, 0x00, 0x02, 0x00, 0x02, 0x00, | ||
84 | 0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40 | ||
85 | }; | ||
86 | |||
87 | unsigned char page_four[] __initdata = { | ||
88 | 0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02, | ||
89 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
90 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
91 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
92 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
93 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | ||
94 | 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, | ||
95 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00, | ||
96 | 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, | ||
97 | 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, | ||
98 | 0x20, 0x00, 0x22, 0x02, 0x22, 0x02, 0x20, 0x00, 0x60, 0x00, 0x22, | ||
99 | 0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01 | ||
100 | }; | ||
101 | |||
102 | unsigned char page_six[] __initdata = { | ||
103 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, | ||
104 | 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e, | ||
105 | 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00, | ||
106 | 0x16, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x1c, 0x00, | ||
107 | 0x00, 0x1e, 0x00, 0x00, 0x20, 0x00, 0x00, 0x22, 0x00, 0x00, 0x24, | ||
108 | 0x00, 0x00, 0x26, 0x00, 0x00, 0x28, 0x00, 0x00, 0x2a, 0x00, 0x00, | ||
109 | 0x2c, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x30, 0x00, 0x00, 0x32, 0x00, | ||
110 | 0x00, 0x34, 0x00, 0x00, 0x36, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3a, | ||
111 | 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0x00, | ||
112 | 0x42, 0x03, 0x00, 0x44, 0x01, 0x00, 0x46, 0x0a, 0x21, 0x48, 0x0d, | ||
113 | 0x23, 0x4a, 0x23, 0x1b, 0x4c, 0x37, 0x8f, 0x4e, 0x45, 0x77, 0x50, | ||
114 | 0x52, 0xe2, 0x52, 0x1c, 0x92, 0x54, 0x1c, 0x52, 0x56, 0x07, 0x00, | ||
115 | 0x58, 0x2f, 0xc6, 0x5a, 0x0b, 0x00, 0x5c, 0x30, 0x06, 0x5e, 0x17, | ||
116 | 0x00, 0x60, 0x3d, 0xda, 0x62, 0x29, 0x00, 0x64, 0x3e, 0x41, 0x66, | ||
117 | 0x39, 0x00, 0x68, 0x4c, 0x48, 0x6a, 0x49, 0x00, 0x6c, 0x4c, 0x6c, | ||
118 | 0x6e, 0x11, 0xd2, 0x70, 0x16, 0x0c, 0x72, 0x00, 0x00, 0x74, 0x00, | ||
119 | 0x80, 0x76, 0x0f, 0x00, 0x78, 0x00, 0x80, 0x7a, 0x13, 0x00, 0x7c, | ||
120 | 0x80, 0x00, 0x7e, 0x80, 0x80 | ||
121 | }; | ||
122 | |||
123 | unsigned char page_seven[] __initdata = { | ||
124 | 0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, | ||
125 | 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, | ||
126 | 0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, | ||
127 | 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
128 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
129 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
130 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
131 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
132 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
133 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
134 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
135 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
137 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, | ||
138 | 0x0f, 0xff, 0x0f, 0xff, 0x02, 0xe9, 0x06, 0x8c, 0x06, 0x8c, 0x0f, | ||
139 | 0xff, 0x1a, 0x75, 0x0d, 0x8b, 0x04, 0xe9, 0x0b, 0x16, 0x1a, 0x38, | ||
140 | 0x0d, 0xc8, 0x04, 0x6f, 0x0b, 0x91, 0x0f, 0xff, 0x06, 0x40, 0x06, | ||
141 | 0x40, 0x02, 0x8f, 0x0f, 0xff, 0x06, 0x62, 0x06, 0x62, 0x02, 0x7b, | ||
142 | 0x0f, 0xff, 0x06, 0x97, 0x06, 0x97, 0x02, 0x52, 0x0f, 0xff, 0x06, | ||
143 | 0xf6, 0x06, 0xf6, 0x02, 0x19, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, | ||
144 | 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x05, 0x55, 0x14, | ||
145 | 0xda, 0x0d, 0x93, 0x04, 0xda, 0x05, 0x93, 0x14, 0xda, 0x0d, 0x93, | ||
146 | 0x04, 0xda, 0x05, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
147 | 0x00, 0x02, 0x00 | ||
148 | }; | ||
149 | |||
150 | unsigned char page_zero_v2[] __initdata = { | ||
151 | 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
152 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
153 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
154 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
155 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
156 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
157 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
159 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
160 | }; | ||
161 | |||
162 | unsigned char page_one_v2[] __initdata = { | ||
163 | 0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
164 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
165 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
170 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
171 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
172 | }; | ||
173 | |||
174 | unsigned char page_two_v2[] __initdata = { | ||
175 | 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
176 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
177 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
178 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
179 | 0x00, 0x00, 0x00, 0x00 | ||
180 | }; | ||
181 | unsigned char page_three_v2[] __initdata = { | ||
182 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
183 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
184 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
185 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
186 | 0x00, 0x00, 0x00, 0x00 | ||
187 | }; | ||
188 | unsigned char page_four_v2[] __initdata = { | ||
189 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
190 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
191 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
192 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
193 | 0x00, 0x00, 0x00, 0x00 | ||
194 | }; | ||
195 | |||
196 | unsigned char page_seven_v2[] __initdata = { | ||
197 | 0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
198 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
200 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
201 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
202 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
203 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
204 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
206 | }; | ||
207 | unsigned char mod_v2[] __initdata = { | ||
208 | 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, | ||
209 | 0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05, | ||
210 | 0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0, | ||
211 | 0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, 0xb4, 0x20, 0xb5, 0x20, | ||
212 | 0xb6, 0x20, 0xb7, 0x20, 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3, | ||
213 | 0x20, 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, 0x10, 0xff, | ||
214 | 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x14, 0xff, 0x15, 0xff, 0x16, | ||
215 | 0xff, 0x17, 0xff, 0x20, 0xff, 0x21, 0xff, 0x22, 0xff, 0x23, 0xff, | ||
216 | 0x24, 0xff, 0x25, 0xff, 0x26, 0xff, 0x27, 0xff, 0x30, 0x00, 0x31, | ||
217 | 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, | ||
218 | 0x37, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, | ||
219 | 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x50, 0x00, 0x51, 0x00, | ||
220 | 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, | ||
221 | 0x00, 0x60, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, | ||
222 | 0x65, 0x00, 0x66, 0x00, 0x67, 0x00, 0x70, 0xc0, 0x71, 0xc0, 0x72, | ||
223 | 0xc0, 0x73, 0xc0, 0x74, 0xc0, 0x75, 0xc0, 0x76, 0xc0, 0x77, 0xc0, | ||
224 | 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, | ||
225 | 0x00, 0x86, 0x00, 0x87, 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, | ||
226 | 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, 0xa0, | ||
227 | 0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, 0xa4, 0x00, 0xa5, 0x00, | ||
228 | 0xa6, 0x00, 0xa7, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, | ||
229 | 0x00, 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, 0xd0, 0x00, | ||
230 | 0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, 0xd4, 0x00, 0xd5, 0x00, 0xd6, | ||
231 | 0x00, 0xd7, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe3, 0x00, | ||
232 | 0xe4, 0x00, 0xe5, 0x00, 0xe6, 0x00, 0xe7, 0x00, 0x01, 0x00, 0x02, | ||
233 | 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03, | ||
234 | 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01, | ||
235 | 0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01 | ||
236 | }; | ||
237 | unsigned char coefficients[] __initdata = { | ||
238 | 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03, | ||
239 | 0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, | ||
240 | 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01, | ||
241 | 0x40, 0x02, 0x40, 0x01, 0x41, 0x02, 0x60, 0x07, 0x40, 0x00, 0x00, | ||
242 | 0x07, 0x41, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, 0x07, 0x4a, 0x00, | ||
243 | 0x00, 0x00, 0x47, 0x01, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x07, 0x47, | ||
244 | 0x00, 0x00, 0x07, 0x4a, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x00, 0x07, | ||
245 | 0x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x07, 0x7c, 0x00, 0x00, | ||
246 | 0x07, 0x7e, 0x00, 0x00, 0x07, 0x44, 0x00, 0x00, 0x00, 0x44, 0x01, | ||
247 | 0x00, 0x07, 0x44, 0x00, 0x00, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, | ||
248 | 0x00, 0x00, 0x00, 0x42, 0x01, 0x1a, 0x00, 0x43, 0x01, 0x20, 0x07, | ||
249 | 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, | ||
250 | 0x07, 0x41, 0x00, 0x00, 0x01, 0x40, 0x02, 0x40, 0x01, 0x41, 0x02, | ||
251 | 0x60, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x44, | ||
252 | 0x0f, 0xff, 0x07, 0x42, 0x00, 0x00, 0x07, 0x43, 0x00, 0x00, 0x07, | ||
253 | 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x07, 0x51, 0x06, 0x40, | ||
254 | 0x07, 0x50, 0x06, 0x40, 0x07, 0x4f, 0x03, 0x81, 0x07, 0x53, 0x1a, | ||
255 | 0x76, 0x07, 0x54, 0x0d, 0x8b, 0x07, 0x55, 0x04, 0xe9, 0x07, 0x56, | ||
256 | 0x0b, 0x17, 0x07, 0x57, 0x1a, 0x38, 0x07, 0x58, 0x0d, 0xc9, 0x07, | ||
257 | 0x59, 0x04, 0x6f, 0x07, 0x5a, 0x0b, 0x91, 0x07, 0x73, 0x14, 0xda, | ||
258 | 0x07, 0x74, 0x0d, 0x93, 0x07, 0x75, 0x04, 0xd9, 0x07, 0x76, 0x05, | ||
259 | 0x93, 0x07, 0x77, 0x14, 0xda, 0x07, 0x78, 0x0d, 0x93, 0x07, 0x79, | ||
260 | 0x04, 0xd9, 0x07, 0x7a, 0x05, 0x93, 0x07, 0x5e, 0x03, 0x68, 0x07, | ||
261 | 0x5c, 0x04, 0x31, 0x07, 0x5d, 0x04, 0x31, 0x07, 0x62, 0x03, 0x52, | ||
262 | 0x07, 0x60, 0x04, 0x76, 0x07, 0x61, 0x04, 0x76, 0x07, 0x66, 0x03, | ||
263 | 0x2e, 0x07, 0x64, 0x04, 0xda, 0x07, 0x65, 0x04, 0xda, 0x07, 0x6a, | ||
264 | 0x02, 0xf6, 0x07, 0x68, 0x05, 0x62, 0x07, 0x69, 0x05, 0x62, 0x06, | ||
265 | 0x46, 0x0a, 0x22, 0x06, 0x48, 0x0d, 0x24, 0x06, 0x6e, 0x11, 0xd3, | ||
266 | 0x06, 0x70, 0x15, 0xcb, 0x06, 0x52, 0x20, 0x93, 0x06, 0x54, 0x20, | ||
267 | 0x54, 0x06, 0x4a, 0x27, 0x1d, 0x06, 0x58, 0x2f, 0xc8, 0x06, 0x5c, | ||
268 | 0x30, 0x07, 0x06, 0x4c, 0x37, 0x90, 0x06, 0x60, 0x3d, 0xdb, 0x06, | ||
269 | 0x64, 0x3e, 0x42, 0x06, 0x4e, 0x45, 0x78, 0x06, 0x68, 0x4c, 0x48, | ||
270 | 0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02, | ||
271 | 0xba | ||
272 | }; | ||
273 | unsigned char coefficients2[] __initdata = { | ||
274 | 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f, | ||
275 | 0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d, | ||
276 | 0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07, | ||
277 | 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, | ||
278 | 0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00 | ||
279 | }; | ||
280 | unsigned char coefficients3[] __initdata = { | ||
281 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00, | ||
282 | 0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc, | ||
283 | 0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01, | ||
284 | 0x47, 0x01, 0x47, 0x01, 0x70, 0x01, 0x70, 0x01, 0x99, 0x01, 0x99, | ||
285 | 0x01, 0xc2, 0x01, 0xc2, 0x01, 0xeb, 0x01, 0xeb, 0x02, 0x14, 0x02, | ||
286 | 0x14, 0x02, 0x3d, 0x02, 0x3d, 0x02, 0x66, 0x02, 0x66, 0x02, 0x8f, | ||
287 | 0x02, 0x8f, 0x02, 0xb8, 0x02, 0xb8, 0x02, 0xe1, 0x02, 0xe1, 0x03, | ||
288 | 0x0a, 0x03, 0x0a, 0x03, 0x33, 0x03, 0x33, 0x03, 0x5c, 0x03, 0x5c, | ||
289 | 0x03, 0x85, 0x03, 0x85, 0x03, 0xae, 0x03, 0xae, 0x03, 0xd7, 0x03, | ||
290 | 0xd7, 0x04, 0x00, 0x04, 0x00, 0x04, 0x28, 0x04, 0x28, 0x04, 0x51, | ||
291 | 0x04, 0x51, 0x04, 0x7a, 0x04, 0x7a, 0x04, 0xa3, 0x04, 0xa3, 0x04, | ||
292 | 0xcc, 0x04, 0xcc, 0x04, 0xf5, 0x04, 0xf5, 0x05, 0x1e, 0x05, 0x1e, | ||
293 | 0x05, 0x47, 0x05, 0x47, 0x05, 0x70, 0x05, 0x70, 0x05, 0x99, 0x05, | ||
294 | 0x99, 0x05, 0xc2, 0x05, 0xc2, 0x05, 0xeb, 0x05, 0xeb, 0x06, 0x14, | ||
295 | 0x06, 0x14, 0x06, 0x3d, 0x06, 0x3d, 0x06, 0x66, 0x06, 0x66, 0x06, | ||
296 | 0x8f, 0x06, 0x8f, 0x06, 0xb8, 0x06, 0xb8, 0x06, 0xe1, 0x06, 0xe1, | ||
297 | 0x07, 0x0a, 0x07, 0x0a, 0x07, 0x33, 0x07, 0x33, 0x07, 0x5c, 0x07, | ||
298 | 0x5c, 0x07, 0x85, 0x07, 0x85, 0x07, 0xae, 0x07, 0xae, 0x07, 0xd7, | ||
299 | 0x07, 0xd7, 0x08, 0x00, 0x08, 0x00, 0x08, 0x28, 0x08, 0x28, 0x08, | ||
300 | 0x51, 0x08, 0x51, 0x08, 0x7a, 0x08, 0x7a, 0x08, 0xa3, 0x08, 0xa3, | ||
301 | 0x08, 0xcc, 0x08, 0xcc, 0x08, 0xf5, 0x08, 0xf5, 0x09, 0x1e, 0x09, | ||
302 | 0x1e, 0x09, 0x47, 0x09, 0x47, 0x09, 0x70, 0x09, 0x70, 0x09, 0x99, | ||
303 | 0x09, 0x99, 0x09, 0xc2, 0x09, 0xc2, 0x09, 0xeb, 0x09, 0xeb, 0x0a, | ||
304 | 0x14, 0x0a, 0x14, 0x0a, 0x3d, 0x0a, 0x3d, 0x0a, 0x66, 0x0a, 0x66, | ||
305 | 0x0a, 0x8f, 0x0a, 0x8f, 0x0a, 0xb8, 0x0a, 0xb8, 0x0a, 0xe1, 0x0a, | ||
306 | 0xe1, 0x0b, 0x0a, 0x0b, 0x0a, 0x0b, 0x33, 0x0b, 0x33, 0x0b, 0x5c, | ||
307 | 0x0b, 0x5c, 0x0b, 0x85, 0x0b, 0x85, 0x0b, 0xae, 0x0b, 0xae, 0x0b, | ||
308 | 0xd7, 0x0b, 0xd7, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x28, 0x0c, 0x28, | ||
309 | 0x0c, 0x51, 0x0c, 0x51, 0x0c, 0x7a, 0x0c, 0x7a, 0x0c, 0xa3, 0x0c, | ||
310 | 0xa3, 0x0c, 0xcc, 0x0c, 0xcc, 0x0c, 0xf5, 0x0c, 0xf5, 0x0d, 0x1e, | ||
311 | 0x0d, 0x1e, 0x0d, 0x47, 0x0d, 0x47, 0x0d, 0x70, 0x0d, 0x70, 0x0d, | ||
312 | 0x99, 0x0d, 0x99, 0x0d, 0xc2, 0x0d, 0xc2, 0x0d, 0xeb, 0x0d, 0xeb, | ||
313 | 0x0e, 0x14, 0x0e, 0x14, 0x0e, 0x3d, 0x0e, 0x3d, 0x0e, 0x66, 0x0e, | ||
314 | 0x66, 0x0e, 0x8f, 0x0e, 0x8f, 0x0e, 0xb8, 0x0e, 0xb8, 0x0e, 0xe1, | ||
315 | 0x0e, 0xe1, 0x0f, 0x0a, 0x0f, 0x0a, 0x0f, 0x33, 0x0f, 0x33, 0x0f, | ||
316 | 0x5c, 0x0f, 0x5c, 0x0f, 0x85, 0x0f, 0x85, 0x0f, 0xae, 0x0f, 0xae, | ||
317 | 0x0f, 0xd7, 0x0f, 0xd7, 0x0f, 0xff, 0x0f, 0xff | ||
318 | }; | ||
319 | |||
diff --git a/sound/oss/yss225.h b/sound/oss/yss225.h deleted file mode 100644 index 56d8b6b5e432..000000000000 --- a/sound/oss/yss225.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | #ifndef __yss255_h__ | ||
2 | #define __yss255_h__ | ||
3 | |||
4 | extern unsigned char page_zero[256]; | ||
5 | extern unsigned char page_one[256]; | ||
6 | extern unsigned char page_two[128]; | ||
7 | extern unsigned char page_three[128]; | ||
8 | extern unsigned char page_four[128]; | ||
9 | extern unsigned char page_six[192]; | ||
10 | extern unsigned char page_seven[256]; | ||
11 | extern unsigned char page_zero_v2[96]; | ||
12 | extern unsigned char page_one_v2[96]; | ||
13 | extern unsigned char page_two_v2[48]; | ||
14 | extern unsigned char page_three_v2[48]; | ||
15 | extern unsigned char page_four_v2[48]; | ||
16 | extern unsigned char page_seven_v2[96]; | ||
17 | extern unsigned char mod_v2[304]; | ||
18 | extern unsigned char coefficients[364]; | ||
19 | extern unsigned char coefficients2[56]; | ||
20 | extern unsigned char coefficients3[404]; | ||
21 | |||
22 | |||
23 | #endif /* __ys225_h__ */ | ||
24 | |||