aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/emu10k1
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/pci/emu10k1
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'sound/pci/emu10k1')
-rw-r--r--sound/pci/emu10k1/Makefile23
-rw-r--r--sound/pci/emu10k1/emu10k1.c240
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c540
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c875
-rw-r--r--sound/pci/emu10k1/emu10k1_patch.c223
-rw-r--r--sound/pci/emu10k1/emu10k1_synth.c120
-rw-r--r--sound/pci/emu10k1/emu10k1_synth_local.h38
-rw-r--r--sound/pci/emu10k1/emu10k1x.c1643
-rw-r--r--sound/pci/emu10k1/emufx.c2320
-rw-r--r--sound/pci/emu10k1/emumixer.c955
-rw-r--r--sound/pci/emu10k1/emumpu401.c374
-rw-r--r--sound/pci/emu10k1/emupcm.c1724
-rw-r--r--sound/pci/emu10k1/emuproc.c568
-rw-r--r--sound/pci/emu10k1/io.c404
-rw-r--r--sound/pci/emu10k1/irq.c189
-rw-r--r--sound/pci/emu10k1/memory.c564
-rw-r--r--sound/pci/emu10k1/p16v.c736
-rw-r--r--sound/pci/emu10k1/p16v.h299
-rw-r--r--sound/pci/emu10k1/timer.c97
-rw-r--r--sound/pci/emu10k1/voice.c152
20 files changed, 12084 insertions, 0 deletions
diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
new file mode 100644
index 000000000000..e521c38cef45
--- /dev/null
+++ b/sound/pci/emu10k1/Makefile
@@ -0,0 +1,23 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-emu10k1-objs := emu10k1.o emu10k1_main.o \
7 irq.o memory.o voice.o emumpu401.o emupcm.o io.o \
8 emuproc.o emumixer.o emufx.o timer.o p16v.o
9snd-emu10k1-synth-objs := emu10k1_synth.o emu10k1_callback.o emu10k1_patch.o
10snd-emu10k1x-objs := emu10k1x.o
11
12#
13# this function returns:
14# "m" - CONFIG_SND_SEQUENCER is m
15# <empty string> - CONFIG_SND_SEQUENCER is undefined
16# otherwise parameter #1 value
17#
18sequencer = $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),$(if $(1),m),$(if $(CONFIG_SND_SEQUENCER),$(1)))
19
20# Toplevel Module Dependency
21obj-$(CONFIG_SND_EMU10K1) += snd-emu10k1.o
22obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-emu10k1-synth.o
23obj-$(CONFIG_SND_EMU10K1X) += snd-emu10k1x.o
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
new file mode 100644
index 000000000000..6446afe19d80
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -0,0 +1,240 @@
1/*
2 * The driver for the EMU10K1 (SB Live!) based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4 *
5 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
6 * Added support for Audigy 2 Value.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 *
24 */
25
26#include <sound/driver.h>
27#include <linux/init.h>
28#include <linux/pci.h>
29#include <linux/time.h>
30#include <linux/moduleparam.h>
31#include <sound/core.h>
32#include <sound/emu10k1.h>
33#include <sound/initval.h>
34
35MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
36MODULE_DESCRIPTION("EMU10K1");
37MODULE_LICENSE("GPL");
38MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS},"
39 "{Creative Labs,SB Audigy}}");
40
41#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
42#define ENABLE_SYNTH
43#include <sound/emu10k1_synth.h>
44#endif
45
46static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
47static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
48static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
49static int extin[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
50static int extout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
51static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4};
52static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
53static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
54static int enable_ir[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
55
56module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
58module_param_array(id, charp, NULL, 0444);
59MODULE_PARM_DESC(id, "ID string for the EMU10K1 soundcard.");
60module_param_array(enable, bool, NULL, 0444);
61MODULE_PARM_DESC(enable, "Enable the EMU10K1 soundcard.");
62module_param_array(extin, int, NULL, 0444);
63MODULE_PARM_DESC(extin, "Available external inputs for FX8010. Zero=default.");
64module_param_array(extout, int, NULL, 0444);
65MODULE_PARM_DESC(extout, "Available external outputs for FX8010. Zero=default.");
66module_param_array(seq_ports, int, NULL, 0444);
67MODULE_PARM_DESC(seq_ports, "Allocated sequencer ports for internal synthesizer.");
68module_param_array(max_synth_voices, int, NULL, 0444);
69MODULE_PARM_DESC(max_synth_voices, "Maximum number of voices for WaveTable.");
70module_param_array(max_buffer_size, int, NULL, 0444);
71MODULE_PARM_DESC(max_buffer_size, "Maximum sample buffer size in MB.");
72module_param_array(enable_ir, bool, NULL, 0444);
73MODULE_PARM_DESC(enable_ir, "Enable IR.");
74
75/*
76 * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
77 */
78static struct pci_device_id snd_emu10k1_ids[] = {
79 { 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* EMU10K1 */
80 { 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy */
81 { 0x1102, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy 2 Value SB0400 */
82 { 0, }
83};
84
85/*
86 * Audigy 2 Value notes:
87 * A_IOCFG Input (GPIO)
88 * 0x400 = Front analog jack plugged in. (Green socket)
89 * 0x1000 = Read analog jack plugged in. (Black socket)
90 * 0x2000 = Center/LFE analog jack plugged in. (Orange socket)
91 * A_IOCFG Output (GPIO)
92 * 0x60 = Sound out of front Left.
93 * Win sets it to 0xXX61
94 */
95
96MODULE_DEVICE_TABLE(pci, snd_emu10k1_ids);
97
98static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
99 const struct pci_device_id *pci_id)
100{
101 static int dev;
102 snd_card_t *card;
103 emu10k1_t *emu;
104#ifdef ENABLE_SYNTH
105 snd_seq_device_t *wave = NULL;
106#endif
107 int err;
108
109 if (dev >= SNDRV_CARDS)
110 return -ENODEV;
111 if (!enable[dev]) {
112 dev++;
113 return -ENOENT;
114 }
115
116 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
117 if (card == NULL)
118 return -ENOMEM;
119 if (max_buffer_size[dev] < 32)
120 max_buffer_size[dev] = 32;
121 else if (max_buffer_size[dev] > 1024)
122 max_buffer_size[dev] = 1024;
123 if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev],
124 (long)max_buffer_size[dev] * 1024 * 1024,
125 enable_ir[dev],
126 &emu)) < 0) {
127 snd_card_free(card);
128 return err;
129 }
130 if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) {
131 snd_card_free(card);
132 return err;
133 }
134 if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) {
135 snd_card_free(card);
136 return err;
137 }
138 if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) {
139 snd_card_free(card);
140 return err;
141 }
142 /* This stores the periods table. */
143 if (emu->audigy && emu->revision == 4) { /* P16V */
144 if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) {
145 snd_p16v_free(emu);
146 return -ENOMEM;
147 }
148 }
149
150 if ((err = snd_emu10k1_mixer(emu)) < 0) {
151 snd_card_free(card);
152 return err;
153 }
154
155 if ((err = snd_emu10k1_timer(emu, 0)) < 0) {
156 snd_card_free(card);
157 return err;
158 }
159
160 if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0) {
161 snd_card_free(card);
162 return err;
163 }
164 if (emu->audigy && emu->revision == 4) { /* P16V */
165 if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) {
166 snd_card_free(card);
167 return err;
168 }
169 }
170 if (emu->audigy) {
171 if ((err = snd_emu10k1_audigy_midi(emu)) < 0) {
172 snd_card_free(card);
173 return err;
174 }
175 } else {
176 if ((err = snd_emu10k1_midi(emu)) < 0) {
177 snd_card_free(card);
178 return err;
179 }
180 }
181 if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0) {
182 snd_card_free(card);
183 return err;
184 }
185#ifdef ENABLE_SYNTH
186 if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
187 sizeof(snd_emu10k1_synth_arg_t), &wave) < 0 ||
188 wave == NULL) {
189 snd_printk("can't initialize Emu10k1 wavetable synth\n");
190 } else {
191 snd_emu10k1_synth_arg_t *arg;
192 arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
193 strcpy(wave->name, "Emu-10k1 Synth");
194 arg->hwptr = emu;
195 arg->index = 1;
196 arg->seq_ports = seq_ports[dev];
197 arg->max_voices = max_synth_voices[dev];
198 }
199#endif
200
201 strcpy(card->driver, emu->card_capabilities->driver);
202 strcpy(card->shortname, emu->card_capabilities->name);
203 snprintf(card->longname, sizeof(card->longname),
204 "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i",
205 card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
206
207 if ((err = snd_card_register(card)) < 0) {
208 snd_card_free(card);
209 return err;
210 }
211 pci_set_drvdata(pci, card);
212 dev++;
213 return 0;
214}
215
216static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
217{
218 snd_card_free(pci_get_drvdata(pci));
219 pci_set_drvdata(pci, NULL);
220}
221
222static struct pci_driver driver = {
223 .name = "EMU10K1_Audigy",
224 .id_table = snd_emu10k1_ids,
225 .probe = snd_card_emu10k1_probe,
226 .remove = __devexit_p(snd_card_emu10k1_remove),
227};
228
229static int __init alsa_card_emu10k1_init(void)
230{
231 return pci_module_init(&driver);
232}
233
234static void __exit alsa_card_emu10k1_exit(void)
235{
236 pci_unregister_driver(&driver);
237}
238
239module_init(alsa_card_emu10k1_init)
240module_exit(alsa_card_emu10k1_exit)
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
new file mode 100644
index 000000000000..7cf2f908eed9
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -0,0 +1,540 @@
1/*
2 * synth callback routines for Emu10k1
3 *
4 * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "emu10k1_synth_local.h"
22#include <sound/asoundef.h>
23
24/* voice status */
25enum {
26 V_FREE=0, V_OFF, V_RELEASED, V_PLAYING, V_END
27};
28
29/* Keeps track of what we are finding */
30typedef struct best_voice {
31 unsigned int time;
32 int voice;
33} best_voice_t;
34
35/*
36 * prototypes
37 */
38static void lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only);
39static snd_emux_voice_t *get_voice(snd_emux_t *emu, snd_emux_port_t *port);
40static int start_voice(snd_emux_voice_t *vp);
41static void trigger_voice(snd_emux_voice_t *vp);
42static void release_voice(snd_emux_voice_t *vp);
43static void update_voice(snd_emux_voice_t *vp, int update);
44static void terminate_voice(snd_emux_voice_t *vp);
45static void free_voice(snd_emux_voice_t *vp);
46
47static void set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp);
48static void set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp);
49static void set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp);
50
51/*
52 * Ensure a value is between two points
53 * macro evaluates its args more than once, so changed to upper-case.
54 */
55#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
56#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
57
58
59/*
60 * set up operators
61 */
62static snd_emux_operators_t emu10k1_ops = {
63 .owner = THIS_MODULE,
64 .get_voice = get_voice,
65 .prepare = start_voice,
66 .trigger = trigger_voice,
67 .release = release_voice,
68 .update = update_voice,
69 .terminate = terminate_voice,
70 .free_voice = free_voice,
71 .sample_new = snd_emu10k1_sample_new,
72 .sample_free = snd_emu10k1_sample_free,
73};
74
75void
76snd_emu10k1_ops_setup(snd_emux_t *emu)
77{
78 emu->ops = emu10k1_ops;
79}
80
81
82/*
83 * get more voice for pcm
84 *
85 * terminate most inactive voice and give it as a pcm voice.
86 */
87int
88snd_emu10k1_synth_get_voice(emu10k1_t *hw)
89{
90 snd_emux_t *emu;
91 snd_emux_voice_t *vp;
92 best_voice_t best[V_END];
93 unsigned long flags;
94 int i;
95
96 emu = hw->synth;
97
98 spin_lock_irqsave(&emu->voice_lock, flags);
99 lookup_voices(emu, hw, best, 1); /* no OFF voices */
100 for (i = 0; i < V_END; i++) {
101 if (best[i].voice >= 0) {
102 int ch;
103 vp = &emu->voices[best[i].voice];
104 if ((ch = vp->ch) < 0) {
105 //printk("synth_get_voice: ch < 0 (%d) ??", i);
106 continue;
107 }
108 vp->emu->num_voices--;
109 vp->ch = -1;
110 vp->state = SNDRV_EMUX_ST_OFF;
111 spin_unlock_irqrestore(&emu->voice_lock, flags);
112 return ch;
113 }
114 }
115 spin_unlock_irqrestore(&emu->voice_lock, flags);
116
117 /* not found */
118 return -ENOMEM;
119}
120
121
122/*
123 * turn off the voice (not terminated)
124 */
125static void
126release_voice(snd_emux_voice_t *vp)
127{
128 int dcysusv;
129 emu10k1_t *hw;
130
131 hw = vp->hw;
132 dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
133 snd_emu10k1_ptr_write(hw, DCYSUSM, vp->ch, dcysusv);
134 dcysusv = 0x8000 | (unsigned char)vp->reg.parm.volrelease | DCYSUSV_CHANNELENABLE_MASK;
135 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, dcysusv);
136}
137
138
139/*
140 * terminate the voice
141 */
142static void
143terminate_voice(snd_emux_voice_t *vp)
144{
145 emu10k1_t *hw;
146
147 snd_assert(vp, return);
148 hw = vp->hw;
149 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
150 if (vp->block) {
151 emu10k1_memblk_t *emem;
152 emem = (emu10k1_memblk_t *)vp->block;
153 if (emem->map_locked > 0)
154 emem->map_locked--;
155 }
156}
157
158/*
159 * release the voice to system
160 */
161static void
162free_voice(snd_emux_voice_t *vp)
163{
164 emu10k1_t *hw;
165
166 hw = vp->hw;
167 if (vp->ch >= 0) {
168 snd_emu10k1_ptr_write(hw, IFATN, vp->ch, 0xff00);
169 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
170 // snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0);
171 snd_emu10k1_ptr_write(hw, VTFT, vp->ch, 0xffff);
172 snd_emu10k1_ptr_write(hw, CVCF, vp->ch, 0xffff);
173 snd_emu10k1_voice_free(hw, &hw->voices[vp->ch]);
174 vp->emu->num_voices--;
175 vp->ch = -1;
176 }
177}
178
179
180/*
181 * update registers
182 */
183static void
184update_voice(snd_emux_voice_t *vp, int update)
185{
186 emu10k1_t *hw;
187
188 hw = vp->hw;
189 if (update & SNDRV_EMUX_UPDATE_VOLUME)
190 snd_emu10k1_ptr_write(hw, IFATN_ATTENUATION, vp->ch, vp->avol);
191 if (update & SNDRV_EMUX_UPDATE_PITCH)
192 snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);
193 if (update & SNDRV_EMUX_UPDATE_PAN) {
194 snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_A, vp->ch, vp->apan);
195 snd_emu10k1_ptr_write(hw, PTRX_FXSENDAMOUNT_B, vp->ch, vp->aaux);
196 }
197 if (update & SNDRV_EMUX_UPDATE_FMMOD)
198 set_fmmod(hw, vp);
199 if (update & SNDRV_EMUX_UPDATE_TREMFREQ)
200 snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
201 if (update & SNDRV_EMUX_UPDATE_FM2FRQ2)
202 set_fm2frq2(hw, vp);
203 if (update & SNDRV_EMUX_UPDATE_Q)
204 set_filterQ(hw, vp);
205}
206
207
208/*
209 * look up voice table - get the best voice in order of preference
210 */
211/* spinlock held! */
212static void
213lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only)
214{
215 snd_emux_voice_t *vp;
216 best_voice_t *bp;
217 int i;
218
219 for (i = 0; i < V_END; i++) {
220 best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */;
221 best[i].voice = -1;
222 }
223
224 /*
225 * Go through them all and get a best one to use.
226 * NOTE: could also look at volume and pick the quietest one.
227 */
228 for (i = 0; i < emu->max_voices; i++) {
229 int state, val;
230
231 vp = &emu->voices[i];
232 state = vp->state;
233 if (state == SNDRV_EMUX_ST_OFF) {
234 if (vp->ch < 0) {
235 if (active_only)
236 continue;
237 bp = best + V_FREE;
238 } else
239 bp = best + V_OFF;
240 }
241 else if (state == SNDRV_EMUX_ST_RELEASED ||
242 state == SNDRV_EMUX_ST_PENDING) {
243 bp = best + V_RELEASED;
244#if 0
245 val = snd_emu10k1_ptr_read(hw, CVCF_CURRENTVOL, vp->ch);
246 if (! val)
247 bp = best + V_OFF;
248#endif
249 }
250 else if (state == SNDRV_EMUX_ST_STANDBY)
251 continue;
252 else if (state & SNDRV_EMUX_ST_ON)
253 bp = best + V_PLAYING;
254 else
255 continue;
256
257 /* check if sample is finished playing (non-looping only) */
258 if (bp != best + V_OFF && bp != best + V_FREE &&
259 (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_SINGLESHOT)) {
260 val = snd_emu10k1_ptr_read(hw, CCCA_CURRADDR, vp->ch);
261 if (val >= vp->reg.loopstart)
262 bp = best + V_OFF;
263 }
264
265 if (vp->time < bp->time) {
266 bp->time = vp->time;
267 bp->voice = i;
268 }
269 }
270}
271
272/*
273 * get an empty voice
274 *
275 * emu->voice_lock is already held.
276 */
277static snd_emux_voice_t *
278get_voice(snd_emux_t *emu, snd_emux_port_t *port)
279{
280 emu10k1_t *hw;
281 snd_emux_voice_t *vp;
282 best_voice_t best[V_END];
283 int i;
284
285 hw = emu->hw;
286
287 lookup_voices(emu, hw, best, 0);
288 for (i = 0; i < V_END; i++) {
289 if (best[i].voice >= 0) {
290 vp = &emu->voices[best[i].voice];
291 if (vp->ch < 0) {
292 /* allocate a voice */
293 emu10k1_voice_t *hwvoice;
294 if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, &hwvoice) < 0 || hwvoice == NULL)
295 continue;
296 vp->ch = hwvoice->number;
297 emu->num_voices++;
298 }
299 return vp;
300 }
301 }
302
303 /* not found */
304 return NULL;
305}
306
307/*
308 * prepare envelopes and LFOs
309 */
310static int
311start_voice(snd_emux_voice_t *vp)
312{
313 unsigned int temp;
314 int ch;
315 unsigned int addr, mapped_offset;
316 snd_midi_channel_t *chan;
317 emu10k1_t *hw;
318 emu10k1_memblk_t *emem;
319
320 hw = vp->hw;
321 ch = vp->ch;
322 snd_assert(ch >= 0, return -EINVAL);
323 chan = vp->chan;
324
325 emem = (emu10k1_memblk_t *)vp->block;
326 if (emem == NULL)
327 return -EINVAL;
328 emem->map_locked++;
329 if (snd_emu10k1_memblk_map(hw, emem) < 0) {
330 // printk("emu: cannot map!\n");
331 return -ENOMEM;
332 }
333 mapped_offset = snd_emu10k1_memblk_offset(emem) >> 1;
334 vp->reg.start += mapped_offset;
335 vp->reg.end += mapped_offset;
336 vp->reg.loopstart += mapped_offset;
337 vp->reg.loopend += mapped_offset;
338
339 /* set channel routing */
340 /* A = left(0), B = right(1), C = reverb(c), D = chorus(d) */
341 if (hw->audigy) {
342 temp = FXBUS_MIDI_LEFT | (FXBUS_MIDI_RIGHT << 8) |
343 (FXBUS_MIDI_REVERB << 16) | (FXBUS_MIDI_CHORUS << 24);
344 snd_emu10k1_ptr_write(hw, A_FXRT1, ch, temp);
345 } else {
346 temp = (FXBUS_MIDI_LEFT << 16) | (FXBUS_MIDI_RIGHT << 20) |
347 (FXBUS_MIDI_REVERB << 24) | (FXBUS_MIDI_CHORUS << 28);
348 snd_emu10k1_ptr_write(hw, FXRT, ch, temp);
349 }
350
351 /* channel to be silent and idle */
352 snd_emu10k1_ptr_write(hw, DCYSUSV, ch, 0x0080);
353 snd_emu10k1_ptr_write(hw, VTFT, ch, 0x0000FFFF);
354 snd_emu10k1_ptr_write(hw, CVCF, ch, 0x0000FFFF);
355 snd_emu10k1_ptr_write(hw, PTRX, ch, 0);
356 snd_emu10k1_ptr_write(hw, CPF, ch, 0);
357
358 /* set pitch offset */
359 snd_emu10k1_ptr_write(hw, IP, vp->ch, vp->apitch);
360
361 /* set envelope parameters */
362 snd_emu10k1_ptr_write(hw, ENVVAL, ch, vp->reg.parm.moddelay);
363 snd_emu10k1_ptr_write(hw, ATKHLDM, ch, vp->reg.parm.modatkhld);
364 snd_emu10k1_ptr_write(hw, DCYSUSM, ch, vp->reg.parm.moddcysus);
365 snd_emu10k1_ptr_write(hw, ENVVOL, ch, vp->reg.parm.voldelay);
366 snd_emu10k1_ptr_write(hw, ATKHLDV, ch, vp->reg.parm.volatkhld);
367 /* decay/sustain parameter for volume envelope is used
368 for triggerg the voice */
369
370 /* cutoff and volume */
371 temp = (unsigned int)vp->acutoff << 8 | (unsigned char)vp->avol;
372 snd_emu10k1_ptr_write(hw, IFATN, vp->ch, temp);
373
374 /* modulation envelope heights */
375 snd_emu10k1_ptr_write(hw, PEFE, ch, vp->reg.parm.pefe);
376
377 /* lfo1/2 delay */
378 snd_emu10k1_ptr_write(hw, LFOVAL1, ch, vp->reg.parm.lfo1delay);
379 snd_emu10k1_ptr_write(hw, LFOVAL2, ch, vp->reg.parm.lfo2delay);
380
381 /* lfo1 pitch & cutoff shift */
382 set_fmmod(hw, vp);
383 /* lfo1 volume & freq */
384 snd_emu10k1_ptr_write(hw, TREMFRQ, vp->ch, vp->reg.parm.tremfrq);
385 /* lfo2 pitch & freq */
386 set_fm2frq2(hw, vp);
387
388 /* reverb and loop start (reverb 8bit, MSB) */
389 temp = vp->reg.parm.reverb;
390 temp += (int)vp->chan->control[MIDI_CTL_E1_REVERB_DEPTH] * 9 / 10;
391 LIMITMAX(temp, 255);
392 addr = vp->reg.loopstart;
393 snd_emu10k1_ptr_write(hw, PSST, vp->ch, (temp << 24) | addr);
394
395 /* chorus & loop end (chorus 8bit, MSB) */
396 addr = vp->reg.loopend;
397 temp = vp->reg.parm.chorus;
398 temp += (int)chan->control[MIDI_CTL_E3_CHORUS_DEPTH] * 9 / 10;
399 LIMITMAX(temp, 255);
400 temp = (temp <<24) | addr;
401 snd_emu10k1_ptr_write(hw, DSL, ch, temp);
402
403 /* clear filter delay memory */
404 snd_emu10k1_ptr_write(hw, Z1, ch, 0);
405 snd_emu10k1_ptr_write(hw, Z2, ch, 0);
406
407 /* invalidate maps */
408 temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK;
409 snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
410 snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
411#if 0
412 /* cache */
413 {
414 unsigned int val, sample;
415 val = 32;
416 if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
417 sample = 0x80808080;
418 else {
419 sample = 0;
420 val *= 2;
421 }
422
423 /* cache */
424 snd_emu10k1_ptr_write(hw, CCR, ch, 0x1c << 16);
425 snd_emu10k1_ptr_write(hw, CDE, ch, sample);
426 snd_emu10k1_ptr_write(hw, CDF, ch, sample);
427
428 /* invalidate maps */
429 temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK;
430 snd_emu10k1_ptr_write(hw, MAPA, ch, temp);
431 snd_emu10k1_ptr_write(hw, MAPB, ch, temp);
432
433 /* fill cache */
434 val -= 4;
435 val <<= 25;
436 val |= 0x1c << 16;
437 snd_emu10k1_ptr_write(hw, CCR, ch, val);
438 }
439#endif
440
441 /* Q & current address (Q 4bit value, MSB) */
442 addr = vp->reg.start;
443 temp = vp->reg.parm.filterQ;
444 temp = (temp<<28) | addr;
445 if (vp->apitch < 0xe400)
446 temp |= CCCA_INTERPROM_0;
447 else {
448 unsigned int shift = (vp->apitch - 0xe000) >> 10;
449 temp |= shift << 25;
450 }
451 if (vp->reg.sample_mode & SNDRV_SFNT_SAMPLE_8BITS)
452 temp |= CCCA_8BITSELECT;
453 snd_emu10k1_ptr_write(hw, CCCA, ch, temp);
454
455 /* reset volume */
456 temp = (unsigned int)vp->vtarget << 16;
457 snd_emu10k1_ptr_write(hw, VTFT, ch, temp | vp->ftarget);
458 snd_emu10k1_ptr_write(hw, CVCF, ch, temp | 0xff00);
459 return 0;
460}
461
462/*
463 * Start envelope
464 */
465static void
466trigger_voice(snd_emux_voice_t *vp)
467{
468 unsigned int temp, ptarget;
469 emu10k1_t *hw;
470 emu10k1_memblk_t *emem;
471
472 hw = vp->hw;
473
474 emem = (emu10k1_memblk_t *)vp->block;
475 if (! emem || emem->mapped_page < 0)
476 return; /* not mapped */
477
478#if 0
479 ptarget = (unsigned int)vp->ptarget << 16;
480#else
481 ptarget = IP_TO_CP(vp->apitch);
482#endif
483 /* set pitch target and pan (volume) */
484 temp = ptarget | (vp->apan << 8) | vp->aaux;
485 snd_emu10k1_ptr_write(hw, PTRX, vp->ch, temp);
486
487 /* pitch target */
488 snd_emu10k1_ptr_write(hw, CPF, vp->ch, ptarget);
489
490 /* trigger voice */
491 snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, vp->reg.parm.voldcysus|DCYSUSV_CHANNELENABLE_MASK);
492}
493
494#define MOD_SENSE 18
495
496/* set lfo1 modulation height and cutoff */
497static void
498set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp)
499{
500 unsigned short fmmod;
501 short pitch;
502 unsigned char cutoff;
503 int modulation;
504
505 pitch = (char)(vp->reg.parm.fmmod>>8);
506 cutoff = (vp->reg.parm.fmmod & 0xff);
507 modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
508 pitch += (MOD_SENSE * modulation) / 1200;
509 LIMITVALUE(pitch, -128, 127);
510 fmmod = ((unsigned char)pitch<<8) | cutoff;
511 snd_emu10k1_ptr_write(hw, FMMOD, vp->ch, fmmod);
512}
513
514/* set lfo2 pitch & frequency */
515static void
516set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp)
517{
518 unsigned short fm2frq2;
519 short pitch;
520 unsigned char freq;
521 int modulation;
522
523 pitch = (char)(vp->reg.parm.fm2frq2>>8);
524 freq = vp->reg.parm.fm2frq2 & 0xff;
525 modulation = vp->chan->gm_modulation + vp->chan->midi_pressure;
526 pitch += (MOD_SENSE * modulation) / 1200;
527 LIMITVALUE(pitch, -128, 127);
528 fm2frq2 = ((unsigned char)pitch<<8) | freq;
529 snd_emu10k1_ptr_write(hw, FM2FRQ2, vp->ch, fm2frq2);
530}
531
532/* set filterQ */
533static void
534set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp)
535{
536 unsigned int val;
537 val = snd_emu10k1_ptr_read(hw, CCCA, vp->ch) & ~CCCA_RESONANCE;
538 val |= (vp->reg.parm.filterQ << 28);
539 snd_emu10k1_ptr_write(hw, CCCA, vp->ch, val);
540}
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
new file mode 100644
index 000000000000..c3c96f9f2c7f
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -0,0 +1,875 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips
5 *
6 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
7 * Added support for Audigy 2 Value.
8 *
9 *
10 * BUGS:
11 * --
12 *
13 * TODO:
14 * --
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#include <sound/driver.h>
33#include <linux/delay.h>
34#include <linux/init.h>
35#include <linux/interrupt.h>
36#include <linux/pci.h>
37#include <linux/slab.h>
38#include <linux/vmalloc.h>
39
40#include <sound/core.h>
41#include <sound/emu10k1.h>
42#include "p16v.h"
43
44#if 0
45MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Creative Labs, Inc.");
46MODULE_DESCRIPTION("Routines for control of EMU10K1 chips");
47MODULE_LICENSE("GPL");
48#endif
49
50/*************************************************************************
51 * EMU10K1 init / done
52 *************************************************************************/
53
54void snd_emu10k1_voice_init(emu10k1_t * emu, int ch)
55{
56 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
57 snd_emu10k1_ptr_write(emu, IP, ch, 0);
58 snd_emu10k1_ptr_write(emu, VTFT, ch, 0xffff);
59 snd_emu10k1_ptr_write(emu, CVCF, ch, 0xffff);
60 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
61 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
62 snd_emu10k1_ptr_write(emu, CCR, ch, 0);
63
64 snd_emu10k1_ptr_write(emu, PSST, ch, 0);
65 snd_emu10k1_ptr_write(emu, DSL, ch, 0x10);
66 snd_emu10k1_ptr_write(emu, CCCA, ch, 0);
67 snd_emu10k1_ptr_write(emu, Z1, ch, 0);
68 snd_emu10k1_ptr_write(emu, Z2, ch, 0);
69 snd_emu10k1_ptr_write(emu, FXRT, ch, 0x32100000);
70
71 snd_emu10k1_ptr_write(emu, ATKHLDM, ch, 0);
72 snd_emu10k1_ptr_write(emu, DCYSUSM, ch, 0);
73 snd_emu10k1_ptr_write(emu, IFATN, ch, 0xffff);
74 snd_emu10k1_ptr_write(emu, PEFE, ch, 0);
75 snd_emu10k1_ptr_write(emu, FMMOD, ch, 0);
76 snd_emu10k1_ptr_write(emu, TREMFRQ, ch, 24); /* 1 Hz */
77 snd_emu10k1_ptr_write(emu, FM2FRQ2, ch, 24); /* 1 Hz */
78 snd_emu10k1_ptr_write(emu, TEMPENV, ch, 0);
79
80 /*** these are last so OFF prevents writing ***/
81 snd_emu10k1_ptr_write(emu, LFOVAL2, ch, 0);
82 snd_emu10k1_ptr_write(emu, LFOVAL1, ch, 0);
83 snd_emu10k1_ptr_write(emu, ATKHLDV, ch, 0);
84 snd_emu10k1_ptr_write(emu, ENVVOL, ch, 0);
85 snd_emu10k1_ptr_write(emu, ENVVAL, ch, 0);
86
87 /* Audigy extra stuffs */
88 if (emu->audigy) {
89 snd_emu10k1_ptr_write(emu, 0x4c, ch, 0); /* ?? */
90 snd_emu10k1_ptr_write(emu, 0x4d, ch, 0); /* ?? */
91 snd_emu10k1_ptr_write(emu, 0x4e, ch, 0); /* ?? */
92 snd_emu10k1_ptr_write(emu, 0x4f, ch, 0); /* ?? */
93 snd_emu10k1_ptr_write(emu, A_FXRT1, ch, 0x03020100);
94 snd_emu10k1_ptr_write(emu, A_FXRT2, ch, 0x3f3f3f3f);
95 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, ch, 0);
96 }
97}
98
99static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir)
100{
101 int ch, idx, err;
102 unsigned int silent_page;
103
104 emu->fx8010.itram_size = (16 * 1024)/2;
105 emu->fx8010.etram_pages.area = NULL;
106 emu->fx8010.etram_pages.bytes = 0;
107
108 /* disable audio and lock cache */
109 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
110
111 /* reset recording buffers */
112 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
113 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
114 snd_emu10k1_ptr_write(emu, FXBS, 0, ADCBS_BUFSIZE_NONE);
115 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
116 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
117 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
118
119 /* disable channel interrupt */
120 outl(0, emu->port + INTE);
121 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
122 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
123 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
124 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
125
126 if (emu->audigy){
127 /* set SPDIF bypass mode */
128 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
129 /* enable rear left + rear right AC97 slots */
130 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT | AC97SLOT_REAR_LEFT);
131 }
132
133 /* init envelope engine */
134 for (ch = 0; ch < NUM_G; ch++) {
135 emu->voices[ch].emu = emu;
136 emu->voices[ch].number = ch;
137 snd_emu10k1_voice_init(emu, ch);
138 }
139
140 /*
141 * Init to 0x02109204 :
142 * Clock accuracy = 0 (1000ppm)
143 * Sample Rate = 2 (48kHz)
144 * Audio Channel = 1 (Left of 2)
145 * Source Number = 0 (Unspecified)
146 * Generation Status = 1 (Original for Cat Code 12)
147 * Cat Code = 12 (Digital Signal Mixer)
148 * Mode = 0 (Mode 0)
149 * Emphasis = 0 (None)
150 * CP = 1 (Copyright unasserted)
151 * AN = 0 (Audio data)
152 * P = 0 (Consumer)
153 */
154 snd_emu10k1_ptr_write(emu, SPCS0, 0,
155 emu->spdif_bits[0] =
156 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
157 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
158 SPCS_GENERATIONSTATUS | 0x00001200 |
159 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
160 snd_emu10k1_ptr_write(emu, SPCS1, 0,
161 emu->spdif_bits[1] =
162 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
163 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
164 SPCS_GENERATIONSTATUS | 0x00001200 |
165 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
166 snd_emu10k1_ptr_write(emu, SPCS2, 0,
167 emu->spdif_bits[2] =
168 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
169 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
170 SPCS_GENERATIONSTATUS | 0x00001200 |
171 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
172
173 if (emu->audigy && emu->revision == 4) { /* audigy2 */
174 /* Hacks for Alice3 to work independent of haP16V driver */
175 u32 tmp;
176
177 //Setup SRCMulti_I2S SamplingRate
178 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
179 tmp &= 0xfffff1ff;
180 tmp |= (0x2<<9);
181 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
182
183 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
184 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
185 /* Setup SRCMulti Input Audio Enable */
186 /* Use 0xFFFFFFFF to enable P16V sounds. */
187 snd_emu10k1_ptr20_write(emu, SRCMULTI_ENABLE, 0, 0xFFFFFFFF);
188
189 /* Enabled Phased (8-channel) P16V playback */
190 outl(0x0201, emu->port + HCFG2);
191 /* Set playback routing. */
192 snd_emu10k1_ptr_write(emu, CAPTURE_P16V_SOURCE, 0, 78e4);
193 }
194 if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */
195 /* Hacks for Alice3 to work independent of haP16V driver */
196 u32 tmp;
197
198 snd_printk(KERN_ERR "Audigy2 value:Special config.\n");
199 //Setup SRCMulti_I2S SamplingRate
200 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
201 tmp &= 0xfffff1ff;
202 tmp |= (0x2<<9);
203 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
204
205 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
206 outl(0x600000, emu->port + 0x20);
207 outl(0x14, emu->port + 0x24);
208
209 /* Setup SRCMulti Input Audio Enable */
210 outl(0x7b0000, emu->port + 0x20);
211 outl(0xFF000000, emu->port + 0x24);
212
213 /* Setup SPDIF Out Audio Enable */
214 /* The Audigy 2 Value has a separate SPDIF out,
215 * so no need for a mixer switch
216 */
217 outl(0x7a0000, emu->port + 0x20);
218 outl(0xFF000000, emu->port + 0x24);
219 tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
220 outl(tmp, emu->port + A_IOCFG);
221 }
222
223
224 /*
225 * Clear page with silence & setup all pointers to this page
226 */
227 memset(emu->silent_page.area, 0, PAGE_SIZE);
228 silent_page = emu->silent_page.addr << 1;
229 for (idx = 0; idx < MAXPAGES; idx++)
230 ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
231 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
232 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
233 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
234
235 silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK;
236 for (ch = 0; ch < NUM_G; ch++) {
237 snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page);
238 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
239 }
240
241 /*
242 * Hokay, setup HCFG
243 * Mute Disable Audio = 0
244 * Lock Tank Memory = 1
245 * Lock Sound Memory = 0
246 * Auto Mute = 1
247 */
248 if (emu->audigy) {
249 if (emu->revision == 4) /* audigy2 */
250 outl(HCFG_AUDIOENABLE |
251 HCFG_AC3ENABLE_CDSPDIF |
252 HCFG_AC3ENABLE_GPSPDIF |
253 HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
254 else
255 outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
256 } else if (emu->model == 0x20 ||
257 emu->model == 0xc400 ||
258 (emu->model == 0x21 && emu->revision < 6))
259 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
260 else
261 // With on-chip joystick
262 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
263
264 if (enable_ir) { /* enable IR for SB Live */
265 if (emu->audigy) {
266 unsigned int reg = inl(emu->port + A_IOCFG);
267 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
268 udelay(500);
269 outl(reg | A_IOCFG_GPOUT1 | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
270 udelay(100);
271 outl(reg, emu->port + A_IOCFG);
272 } else {
273 unsigned int reg = inl(emu->port + HCFG);
274 outl(reg | HCFG_GPOUT2, emu->port + HCFG);
275 udelay(500);
276 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
277 udelay(100);
278 outl(reg, emu->port + HCFG);
279 }
280 }
281
282 if (emu->audigy) { /* enable analog output */
283 unsigned int reg = inl(emu->port + A_IOCFG);
284 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
285 }
286
287 /*
288 * Initialize the effect engine
289 */
290 if ((err = snd_emu10k1_init_efx(emu)) < 0)
291 return err;
292
293 /*
294 * Enable the audio bit
295 */
296 outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
297
298 /* Enable analog/digital outs on audigy */
299 if (emu->audigy) {
300 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
301
302 if (emu->revision == 4) { /* audigy2 */
303 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
304 * This has to be done after init ALice3 I2SOut beyond 48KHz.
305 * So, sequence is important. */
306 outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
307 } else if (emu->serial == 0x10011102) { /* audigy2 value */
308 /* Unmute Analog now. */
309 outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
310 } else {
311 /* Disable routing from AC97 line out to Front speakers */
312 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
313 }
314 }
315
316#if 0
317 {
318 unsigned int tmp;
319 /* FIXME: the following routine disables LiveDrive-II !! */
320 // TOSLink detection
321 emu->tos_link = 0;
322 tmp = inl(emu->port + HCFG);
323 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
324 outl(tmp|0x800, emu->port + HCFG);
325 udelay(50);
326 if (tmp != (inl(emu->port + HCFG) & ~0x800)) {
327 emu->tos_link = 1;
328 outl(tmp, emu->port + HCFG);
329 }
330 }
331 }
332#endif
333
334 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
335
336 emu->reserved_page = (emu10k1_memblk_t *)snd_emu10k1_synth_alloc(emu, 4096);
337 if (emu->reserved_page)
338 emu->reserved_page->map_locked = 1;
339
340 return 0;
341}
342
343static int snd_emu10k1_done(emu10k1_t * emu)
344{
345 int ch;
346
347 outl(0, emu->port + INTE);
348
349 /*
350 * Shutdown the chip
351 */
352 for (ch = 0; ch < NUM_G; ch++)
353 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
354 for (ch = 0; ch < NUM_G; ch++) {
355 snd_emu10k1_ptr_write(emu, VTFT, ch, 0);
356 snd_emu10k1_ptr_write(emu, CVCF, ch, 0);
357 snd_emu10k1_ptr_write(emu, PTRX, ch, 0);
358 snd_emu10k1_ptr_write(emu, CPF, ch, 0);
359 }
360
361 /* reset recording buffers */
362 snd_emu10k1_ptr_write(emu, MICBS, 0, 0);
363 snd_emu10k1_ptr_write(emu, MICBA, 0, 0);
364 snd_emu10k1_ptr_write(emu, FXBS, 0, 0);
365 snd_emu10k1_ptr_write(emu, FXBA, 0, 0);
366 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
367 snd_emu10k1_ptr_write(emu, ADCBS, 0, ADCBS_BUFSIZE_NONE);
368 snd_emu10k1_ptr_write(emu, ADCBA, 0, 0);
369 snd_emu10k1_ptr_write(emu, TCBS, 0, TCBS_BUFFSIZE_16K);
370 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
371 if (emu->audigy)
372 snd_emu10k1_ptr_write(emu, A_DBG, 0, A_DBG_SINGLE_STEP);
373 else
374 snd_emu10k1_ptr_write(emu, DBG, 0, EMU10K1_DBG_SINGLE_STEP);
375
376 /* disable channel interrupt */
377 snd_emu10k1_ptr_write(emu, CLIEL, 0, 0);
378 snd_emu10k1_ptr_write(emu, CLIEH, 0, 0);
379 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
380 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
381
382 /* remove reserved page */
383 if (emu->reserved_page != NULL) {
384 snd_emu10k1_synth_free(emu, (snd_util_memblk_t *)emu->reserved_page);
385 emu->reserved_page = NULL;
386 }
387
388 /* disable audio and lock cache */
389 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
390 snd_emu10k1_ptr_write(emu, PTB, 0, 0);
391
392 snd_emu10k1_free_efx(emu);
393
394 return 0;
395}
396
397/*************************************************************************
398 * ECARD functional implementation
399 *************************************************************************/
400
401/* In A1 Silicon, these bits are in the HC register */
402#define HOOKN_BIT (1L << 12)
403#define HANDN_BIT (1L << 11)
404#define PULSEN_BIT (1L << 10)
405
406#define EC_GDI1 (1 << 13)
407#define EC_GDI0 (1 << 14)
408
409#define EC_NUM_CONTROL_BITS 20
410
411#define EC_AC3_DATA_SELN 0x0001L
412#define EC_EE_DATA_SEL 0x0002L
413#define EC_EE_CNTRL_SELN 0x0004L
414#define EC_EECLK 0x0008L
415#define EC_EECS 0x0010L
416#define EC_EESDO 0x0020L
417#define EC_TRIM_CSN 0x0040L
418#define EC_TRIM_SCLK 0x0080L
419#define EC_TRIM_SDATA 0x0100L
420#define EC_TRIM_MUTEN 0x0200L
421#define EC_ADCCAL 0x0400L
422#define EC_ADCRSTN 0x0800L
423#define EC_DACCAL 0x1000L
424#define EC_DACMUTEN 0x2000L
425#define EC_LEDN 0x4000L
426
427#define EC_SPDIF0_SEL_SHIFT 15
428#define EC_SPDIF1_SEL_SHIFT 17
429#define EC_SPDIF0_SEL_MASK (0x3L << EC_SPDIF0_SEL_SHIFT)
430#define EC_SPDIF1_SEL_MASK (0x7L << EC_SPDIF1_SEL_SHIFT)
431#define EC_SPDIF0_SELECT(_x) (((_x) << EC_SPDIF0_SEL_SHIFT) & EC_SPDIF0_SEL_MASK)
432#define EC_SPDIF1_SELECT(_x) (((_x) << EC_SPDIF1_SEL_SHIFT) & EC_SPDIF1_SEL_MASK)
433#define EC_CURRENT_PROM_VERSION 0x01 /* Self-explanatory. This should
434 * be incremented any time the EEPROM's
435 * format is changed. */
436
437#define EC_EEPROM_SIZE 0x40 /* ECARD EEPROM has 64 16-bit words */
438
439/* Addresses for special values stored in to EEPROM */
440#define EC_PROM_VERSION_ADDR 0x20 /* Address of the current prom version */
441#define EC_BOARDREV0_ADDR 0x21 /* LSW of board rev */
442#define EC_BOARDREV1_ADDR 0x22 /* MSW of board rev */
443
444#define EC_LAST_PROMFILE_ADDR 0x2f
445
446#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
447 * can be up to 30 characters in length
448 * and is stored as a NULL-terminated
449 * ASCII string. Any unused bytes must be
450 * filled with zeros */
451#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
452
453
454/* Most of this stuff is pretty self-evident. According to the hardware
455 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
456 * offset problem. Weird.
457 */
458#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
459 EC_TRIM_CSN)
460
461
462#define EC_DEFAULT_ADC_GAIN 0xC4C4
463#define EC_DEFAULT_SPDIF0_SEL 0x0
464#define EC_DEFAULT_SPDIF1_SEL 0x4
465
466/**************************************************************************
467 * @func Clock bits into the Ecard's control latch. The Ecard uses a
468 * control latch will is loaded bit-serially by toggling the Modem control
469 * lines from function 2 on the E8010. This function hides these details
470 * and presents the illusion that we are actually writing to a distinct
471 * register.
472 */
473
474static void snd_emu10k1_ecard_write(emu10k1_t * emu, unsigned int value)
475{
476 unsigned short count;
477 unsigned int data;
478 unsigned long hc_port;
479 unsigned int hc_value;
480
481 hc_port = emu->port + HCFG;
482 hc_value = inl(hc_port) & ~(HOOKN_BIT | HANDN_BIT | PULSEN_BIT);
483 outl(hc_value, hc_port);
484
485 for (count = 0; count < EC_NUM_CONTROL_BITS; count++) {
486
487 /* Set up the value */
488 data = ((value & 0x1) ? PULSEN_BIT : 0);
489 value >>= 1;
490
491 outl(hc_value | data, hc_port);
492
493 /* Clock the shift register */
494 outl(hc_value | data | HANDN_BIT, hc_port);
495 outl(hc_value | data, hc_port);
496 }
497
498 /* Latch the bits */
499 outl(hc_value | HOOKN_BIT, hc_port);
500 outl(hc_value, hc_port);
501}
502
503/**************************************************************************
504 * @func Set the gain of the ECARD's CS3310 Trim/gain controller. The
505 * trim value consists of a 16bit value which is composed of two
506 * 8 bit gain/trim values, one for the left channel and one for the
507 * right channel. The following table maps from the Gain/Attenuation
508 * value in decibels into the corresponding bit pattern for a single
509 * channel.
510 */
511
512static void snd_emu10k1_ecard_setadcgain(emu10k1_t * emu,
513 unsigned short gain)
514{
515 unsigned int bit;
516
517 /* Enable writing to the TRIM registers */
518 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
519
520 /* Do it again to insure that we meet hold time requirements */
521 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl & ~EC_TRIM_CSN);
522
523 for (bit = (1 << 15); bit; bit >>= 1) {
524 unsigned int value;
525
526 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
527
528 if (gain & bit)
529 value |= EC_TRIM_SDATA;
530
531 /* Clock the bit */
532 snd_emu10k1_ecard_write(emu, value);
533 snd_emu10k1_ecard_write(emu, value | EC_TRIM_SCLK);
534 snd_emu10k1_ecard_write(emu, value);
535 }
536
537 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
538}
539
540static int __devinit snd_emu10k1_ecard_init(emu10k1_t * emu)
541{
542 unsigned int hc_value;
543
544 /* Set up the initial settings */
545 emu->ecard_ctrl = EC_RAW_RUN_MODE |
546 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
547 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
548
549 /* Step 0: Set the codec type in the hardware control register
550 * and enable audio output */
551 hc_value = inl(emu->port + HCFG);
552 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
553 inl(emu->port + HCFG);
554
555 /* Step 1: Turn off the led and deassert TRIM_CS */
556 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
557
558 /* Step 2: Calibrate the ADC and DAC */
559 snd_emu10k1_ecard_write(emu, EC_DACCAL | EC_LEDN | EC_TRIM_CSN);
560
561 /* Step 3: Wait for awhile; XXX We can't get away with this
562 * under a real operating system; we'll need to block and wait that
563 * way. */
564 snd_emu10k1_wait(emu, 48000);
565
566 /* Step 4: Switch off the DAC and ADC calibration. Note
567 * That ADC_CAL is actually an inverted signal, so we assert
568 * it here to stop calibration. */
569 snd_emu10k1_ecard_write(emu, EC_ADCCAL | EC_LEDN | EC_TRIM_CSN);
570
571 /* Step 4: Switch into run mode */
572 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
573
574 /* Step 5: Set the analog input gain */
575 snd_emu10k1_ecard_setadcgain(emu, EC_DEFAULT_ADC_GAIN);
576
577 return 0;
578}
579
580/*
581 * Create the EMU10K1 instance
582 */
583
584static int snd_emu10k1_free(emu10k1_t *emu)
585{
586 if (emu->port) { /* avoid access to already used hardware */
587 snd_emu10k1_fx8010_tram_setup(emu, 0);
588 snd_emu10k1_done(emu);
589 }
590 if (emu->memhdr)
591 snd_util_memhdr_free(emu->memhdr);
592 if (emu->silent_page.area)
593 snd_dma_free_pages(&emu->silent_page);
594 if (emu->ptb_pages.area)
595 snd_dma_free_pages(&emu->ptb_pages);
596 vfree(emu->page_ptr_table);
597 vfree(emu->page_addr_table);
598 if (emu->irq >= 0)
599 free_irq(emu->irq, (void *)emu);
600 if (emu->port)
601 pci_release_regions(emu->pci);
602 pci_disable_device(emu->pci);
603 if (emu->audigy && emu->revision == 4) /* P16V */
604 snd_p16v_free(emu);
605 kfree(emu);
606 return 0;
607}
608
609static int snd_emu10k1_dev_free(snd_device_t *device)
610{
611 emu10k1_t *emu = device->device_data;
612 return snd_emu10k1_free(emu);
613}
614
615/* vendor, device, subsystem, emu10k1_chip, emu10k2_chip, ca0102_chip, ca0108_chip, ca0151_chip, spk71, spdif_bug, ac97_chip, ecard, driver, name */
616
617static emu_chip_details_t emu_chip_details[] = {
618 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
619 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
620 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
621 .emu10k2_chip = 1,
622 .ca0108_chip = 1,
623 .spk71 = 1} ,
624 {.vendor = 0x1102, .device = 0x0008,
625 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
626 .emu10k2_chip = 1,
627 .ca0108_chip = 1} ,
628 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
629 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]",
630 .emu10k2_chip = 1,
631 .ca0102_chip = 1,
632 .ca0151_chip = 1,
633 .spk71 = 1,
634 .spdif_bug = 1,
635 .ac97_chip = 1} ,
636 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
637 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]",
638 .emu10k2_chip = 1,
639 .ca0102_chip = 1,
640 .ca0151_chip = 1,
641 .spk71 = 1,
642 .spdif_bug = 1,
643 .ac97_chip = 1} ,
644 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
645 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]",
646 .emu10k2_chip = 1,
647 .ca0102_chip = 1,
648 .ca0151_chip = 1,
649 .spk71 = 1,
650 .spdif_bug = 1,
651 .ac97_chip = 1} ,
652 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
653 .driver = "Audigy2", .name = "Audigy 2 [SB0240]",
654 .emu10k2_chip = 1,
655 .ca0102_chip = 1,
656 .ca0151_chip = 1,
657 .spk71 = 1,
658 .spdif_bug = 1,
659 .ac97_chip = 1} ,
660 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
661 .driver = "Audigy2", .name = "Audigy 2 EX [1005]",
662 .emu10k2_chip = 1,
663 .ca0102_chip = 1,
664 .ca0151_chip = 1,
665 .spdif_bug = 1} ,
666 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
667 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]",
668 .emu10k2_chip = 1,
669 .ca0102_chip = 1,
670 .ca0151_chip = 1,
671 .spk71 = 1,
672 .spdif_bug = 1,
673 .ac97_chip = 1} ,
674 {.vendor = 0x1102, .device = 0x0004,
675 .driver = "Audigy", .name = "Audigy 1 or 2 [Unknown]",
676 .emu10k2_chip = 1,
677 .ca0102_chip = 1,
678 .spdif_bug = 1} ,
679 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
680 .driver = "EMU10K1", .name = "E-mu APS [4001]",
681 .emu10k1_chip = 1,
682 .ecard = 1} ,
683 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
684 .driver = "EMU10K1", .name = "SB Live 5.1",
685 .emu10k1_chip = 1,
686 .ac97_chip = 1} ,
687 {.vendor = 0x1102, .device = 0x0002,
688 .driver = "EMU10K1", .name = "SB Live [Unknown]",
689 .emu10k1_chip = 1,
690 .ac97_chip = 1} ,
691 { } /* terminator */
692};
693
694int __devinit snd_emu10k1_create(snd_card_t * card,
695 struct pci_dev * pci,
696 unsigned short extin_mask,
697 unsigned short extout_mask,
698 long max_cache_bytes,
699 int enable_ir,
700 emu10k1_t ** remu)
701{
702 emu10k1_t *emu;
703 int err;
704 int is_audigy;
705 unsigned char revision;
706 const emu_chip_details_t *c;
707 static snd_device_ops_t ops = {
708 .dev_free = snd_emu10k1_dev_free,
709 };
710
711 *remu = NULL;
712
713 /* enable PCI device */
714 if ((err = pci_enable_device(pci)) < 0)
715 return err;
716
717 emu = kcalloc(1, sizeof(*emu), GFP_KERNEL);
718 if (emu == NULL) {
719 pci_disable_device(pci);
720 return -ENOMEM;
721 }
722 emu->card = card;
723 spin_lock_init(&emu->reg_lock);
724 spin_lock_init(&emu->emu_lock);
725 spin_lock_init(&emu->voice_lock);
726 spin_lock_init(&emu->synth_lock);
727 spin_lock_init(&emu->memblk_lock);
728 init_MUTEX(&emu->ptb_lock);
729 init_MUTEX(&emu->fx8010.lock);
730 INIT_LIST_HEAD(&emu->mapped_link_head);
731 INIT_LIST_HEAD(&emu->mapped_order_link_head);
732 emu->pci = pci;
733 emu->irq = -1;
734 emu->synth = NULL;
735 emu->get_synth_voice = NULL;
736 /* read revision & serial */
737 pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
738 emu->revision = revision;
739 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
740 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
741 emu->card_type = EMU10K1_CARD_CREATIVE;
742 snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model);
743
744 for (c = emu_chip_details; c->vendor; c++) {
745 if (c->vendor == pci->vendor && c->device == pci->device) {
746 if (c->subsystem == emu->serial) break;
747 if (c->subsystem == 0) break;
748 }
749 }
750 if (c->vendor == 0) {
751 snd_printk(KERN_ERR "emu10k1: Card not recognised\n");
752 kfree(emu);
753 pci_disable_device(pci);
754 return -ENOENT;
755 }
756 emu->card_capabilities = c;
757 if (c->subsystem != 0)
758 snd_printdd("Sound card name=%s\n", c->name);
759 else
760 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x\n", c->name, pci->vendor, pci->device, emu->serial);
761
762 is_audigy = emu->audigy = c->emu10k2_chip;
763
764 /* set the DMA transfer mask */
765 emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK;
766 if (pci_set_dma_mask(pci, emu->dma_mask) < 0 ||
767 pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) {
768 snd_printk(KERN_ERR "architecture does not support PCI busmaster DMA with mask 0x%lx\n", emu->dma_mask);
769 kfree(emu);
770 pci_disable_device(pci);
771 return -ENXIO;
772 }
773 if (is_audigy)
774 emu->gpr_base = A_FXGPREGBASE;
775 else
776 emu->gpr_base = FXGPREGBASE;
777
778 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) {
779 kfree(emu);
780 pci_disable_device(pci);
781 return err;
782 }
783 emu->port = pci_resource_start(pci, 0);
784
785 if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) {
786 snd_emu10k1_free(emu);
787 return -EBUSY;
788 }
789 emu->irq = pci->irq;
790
791 emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
792 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
793 32 * 1024, &emu->ptb_pages) < 0) {
794 snd_emu10k1_free(emu);
795 return -ENOMEM;
796 }
797
798 emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
799 emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
800 if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
801 snd_emu10k1_free(emu);
802 return -ENOMEM;
803 }
804
805 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
806 EMUPAGESIZE, &emu->silent_page) < 0) {
807 snd_emu10k1_free(emu);
808 return -ENOMEM;
809 }
810 emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
811 if (emu->memhdr == NULL) {
812 snd_emu10k1_free(emu);
813 return -ENOMEM;
814 }
815 emu->memhdr->block_extra_size = sizeof(emu10k1_memblk_t) - sizeof(snd_util_memblk_t);
816
817 pci_set_master(pci);
818
819 if (c->ecard) {
820 emu->card_type = EMU10K1_CARD_EMUAPS;
821 emu->APS = 1;
822 }
823 if (! c->ac97_chip)
824 emu->no_ac97 = 1;
825
826 emu->spk71 = c->spk71;
827
828 emu->fx8010.fxbus_mask = 0x303f;
829 if (extin_mask == 0)
830 extin_mask = 0x3fcf;
831 if (extout_mask == 0)
832 extout_mask = 0x7fff;
833 emu->fx8010.extin_mask = extin_mask;
834 emu->fx8010.extout_mask = extout_mask;
835
836 if (emu->APS) {
837 if ((err = snd_emu10k1_ecard_init(emu)) < 0) {
838 snd_emu10k1_free(emu);
839 return err;
840 }
841 } else {
842 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
843 does not support this, it shouldn't do any harm */
844 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
845 }
846
847 if ((err = snd_emu10k1_init(emu, enable_ir)) < 0) {
848 snd_emu10k1_free(emu);
849 return err;
850 }
851
852 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0) {
853 snd_emu10k1_free(emu);
854 return err;
855 }
856
857 snd_emu10k1_proc_init(emu);
858
859 snd_card_set_dev(card, &pci->dev);
860 *remu = emu;
861 return 0;
862}
863
864/* memory.c */
865EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
866EXPORT_SYMBOL(snd_emu10k1_synth_free);
867EXPORT_SYMBOL(snd_emu10k1_synth_bzero);
868EXPORT_SYMBOL(snd_emu10k1_synth_copy_from_user);
869EXPORT_SYMBOL(snd_emu10k1_memblk_map);
870/* voice.c */
871EXPORT_SYMBOL(snd_emu10k1_voice_alloc);
872EXPORT_SYMBOL(snd_emu10k1_voice_free);
873/* io.c */
874EXPORT_SYMBOL(snd_emu10k1_ptr_read);
875EXPORT_SYMBOL(snd_emu10k1_ptr_write);
diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c
new file mode 100644
index 000000000000..4df668eb32b4
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_patch.c
@@ -0,0 +1,223 @@
1/*
2 * Patch transfer callback for Emu10k1
3 *
4 * Copyright (C) 2000 Takashi iwai <tiwai@suse.de>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20/*
21 * All the code for loading in a patch. There is very little that is
22 * chip specific here. Just the actual writing to the board.
23 */
24
25#include "emu10k1_synth_local.h"
26
27/*
28 */
29#define BLANK_LOOP_START 4
30#define BLANK_LOOP_END 8
31#define BLANK_LOOP_SIZE 12
32#define BLANK_HEAD_SIZE 32
33
34/*
35 * allocate a sample block and copy data from userspace
36 */
37int
38snd_emu10k1_sample_new(snd_emux_t *rec, snd_sf_sample_t *sp,
39 snd_util_memhdr_t *hdr, const void __user *data, long count)
40{
41 int offset;
42 int truesize, size, loopsize, blocksize;
43 int loopend, sampleend;
44 unsigned int start_addr;
45 emu10k1_t *emu;
46
47 emu = rec->hw;
48 snd_assert(sp != NULL, return -EINVAL);
49 snd_assert(hdr != NULL, return -EINVAL);
50
51 if (sp->v.size == 0) {
52 snd_printd("emu: rom font for sample %d\n", sp->v.sample);
53 return 0;
54 }
55
56 /* recalculate address offset */
57 sp->v.end -= sp->v.start;
58 sp->v.loopstart -= sp->v.start;
59 sp->v.loopend -= sp->v.start;
60 sp->v.start = 0;
61
62 /* some samples have invalid data. the addresses are corrected in voice info */
63 sampleend = sp->v.end;
64 if (sampleend > sp->v.size)
65 sampleend = sp->v.size;
66 loopend = sp->v.loopend;
67 if (loopend > sampleend)
68 loopend = sampleend;
69
70 /* be sure loop points start < end */
71 if (sp->v.loopstart >= sp->v.loopend) {
72 int tmp = sp->v.loopstart;
73 sp->v.loopstart = sp->v.loopend;
74 sp->v.loopend = tmp;
75 }
76
77 /* compute true data size to be loaded */
78 truesize = sp->v.size + BLANK_HEAD_SIZE;
79 loopsize = 0;
80#if 0 /* not supported */
81 if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP))
82 loopsize = sp->v.loopend - sp->v.loopstart;
83 truesize += loopsize;
84#endif
85 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK)
86 truesize += BLANK_LOOP_SIZE;
87
88 /* try to allocate a memory block */
89 blocksize = truesize;
90 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
91 blocksize *= 2;
92 sp->block = snd_emu10k1_synth_alloc(emu, blocksize);
93 if (sp->block == NULL) {
94 snd_printd("emu10k1: synth malloc failed (size=%d)\n", blocksize);
95 /* not ENOMEM (for compatibility with OSS) */
96 return -ENOSPC;
97 }
98 /* set the total size */
99 sp->v.truesize = blocksize;
100
101 /* write blank samples at head */
102 offset = 0;
103 size = BLANK_HEAD_SIZE;
104 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
105 size *= 2;
106 snd_assert(offset + size <= blocksize, return -EINVAL);
107 snd_emu10k1_synth_bzero(emu, sp->block, offset, size);
108 offset += size;
109
110 /* copy start->loopend */
111 size = loopend;
112 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
113 size *= 2;
114 snd_assert(offset + size <= blocksize, return -EINVAL);
115 if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
116 snd_emu10k1_synth_free(emu, sp->block);
117 sp->block = NULL;
118 return -EFAULT;
119 }
120 offset += size;
121 data += size;
122
123#if 0 /* not suppported yet */
124 /* handle reverse (or bidirectional) loop */
125 if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
126 /* copy loop in reverse */
127 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
128 int woffset;
129 unsigned short *wblock = (unsigned short*)block;
130 woffset = offset / 2;
131 snd_assert(offset + loopsize*2 <= blocksize, return -EINVAL);
132 for (i = 0; i < loopsize; i++)
133 wblock[woffset + i] = wblock[woffset - i -1];
134 offset += loopsize * 2;
135 } else {
136 snd_assert(offset + loopsize <= blocksize, return -EINVAL);
137 for (i = 0; i < loopsize; i++)
138 block[offset + i] = block[offset - i -1];
139 offset += loopsize;
140 }
141
142 /* modify loop pointers */
143 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_BIDIR_LOOP) {
144 sp->v.loopend += loopsize;
145 } else {
146 sp->v.loopstart += loopsize;
147 sp->v.loopend += loopsize;
148 }
149 /* add sample pointer */
150 sp->v.end += loopsize;
151 }
152#endif
153
154 /* loopend -> sample end */
155 size = sp->v.size - loopend;
156 snd_assert(size >= 0, return -EINVAL);
157 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
158 size *= 2;
159 if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
160 snd_emu10k1_synth_free(emu, sp->block);
161 sp->block = NULL;
162 return -EFAULT;
163 }
164 offset += size;
165
166 /* clear rest of samples (if any) */
167 if (offset < blocksize)
168 snd_emu10k1_synth_bzero(emu, sp->block, offset, blocksize - offset);
169
170 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
171 /* if no blank loop is attached in the sample, add it */
172 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
173 sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
174 sp->v.loopend = sp->v.end + BLANK_LOOP_END;
175 }
176 }
177
178#if 0 /* not supported yet */
179 if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) {
180 /* unsigned -> signed */
181 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
182 unsigned short *wblock = (unsigned short*)block;
183 for (i = 0; i < truesize; i++)
184 wblock[i] ^= 0x8000;
185 } else {
186 for (i = 0; i < truesize; i++)
187 block[i] ^= 0x80;
188 }
189 }
190#endif
191
192 /* recalculate offset */
193 start_addr = BLANK_HEAD_SIZE * 2;
194 if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
195 start_addr >>= 1;
196 sp->v.start += start_addr;
197 sp->v.end += start_addr;
198 sp->v.loopstart += start_addr;
199 sp->v.loopend += start_addr;
200
201 return 0;
202}
203
204/*
205 * free a sample block
206 */
207int
208snd_emu10k1_sample_free(snd_emux_t *rec, snd_sf_sample_t *sp,
209 snd_util_memhdr_t *hdr)
210{
211 emu10k1_t *emu;
212
213 emu = rec->hw;
214 snd_assert(sp != NULL, return -EINVAL);
215 snd_assert(hdr != NULL, return -EINVAL);
216
217 if (sp->block) {
218 snd_emu10k1_synth_free(emu, sp->block);
219 sp->block = NULL;
220 }
221 return 0;
222}
223
diff --git a/sound/pci/emu10k1/emu10k1_synth.c b/sound/pci/emu10k1/emu10k1_synth.c
new file mode 100644
index 000000000000..8bd58d1dcc26
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_synth.c
@@ -0,0 +1,120 @@
1/*
2 * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
3 *
4 * Routines for control of EMU10K1 WaveTable synth
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "emu10k1_synth_local.h"
22#include <linux/init.h>
23
24MODULE_AUTHOR("Takashi Iwai");
25MODULE_DESCRIPTION("Routines for control of EMU10K1 WaveTable synth");
26MODULE_LICENSE("GPL");
27
28/*
29 * create a new hardware dependent device for Emu10k1
30 */
31static int snd_emu10k1_synth_new_device(snd_seq_device_t *dev)
32{
33 snd_emux_t *emu;
34 emu10k1_t *hw;
35 snd_emu10k1_synth_arg_t *arg;
36 unsigned long flags;
37
38 arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
39 if (arg == NULL)
40 return -EINVAL;
41
42 if (arg->seq_ports <= 0)
43 return 0; /* nothing */
44 if (arg->max_voices < 1)
45 arg->max_voices = 1;
46 else if (arg->max_voices > 64)
47 arg->max_voices = 64;
48
49 if (snd_emux_new(&emu) < 0)
50 return -ENOMEM;
51
52 snd_emu10k1_ops_setup(emu);
53 emu->hw = hw = arg->hwptr;
54 emu->max_voices = arg->max_voices;
55 emu->num_ports = arg->seq_ports;
56 emu->pitch_shift = -501;
57 emu->memhdr = hw->memhdr;
58 emu->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2; /* maximum two ports */
59 emu->midi_devidx = hw->audigy ? 2 : 1; /* audigy has two external midis */
60 emu->linear_panning = 0;
61 emu->hwdep_idx = 2; /* FIXED */
62
63 if (snd_emux_register(emu, dev->card, arg->index, "Emu10k1") < 0) {
64 snd_emux_free(emu);
65 emu->hw = NULL;
66 return -ENOMEM;
67 }
68
69 spin_lock_irqsave(&hw->voice_lock, flags);
70 hw->synth = emu;
71 hw->get_synth_voice = snd_emu10k1_synth_get_voice;
72 spin_unlock_irqrestore(&hw->voice_lock, flags);
73
74 dev->driver_data = emu;
75
76 return 0;
77}
78
79static int snd_emu10k1_synth_delete_device(snd_seq_device_t *dev)
80{
81 snd_emux_t *emu;
82 emu10k1_t *hw;
83 unsigned long flags;
84
85 if (dev->driver_data == NULL)
86 return 0; /* not registered actually */
87
88 emu = dev->driver_data;
89
90 hw = emu->hw;
91 spin_lock_irqsave(&hw->voice_lock, flags);
92 hw->synth = NULL;
93 hw->get_synth_voice = NULL;
94 spin_unlock_irqrestore(&hw->voice_lock, flags);
95
96 snd_emux_free(emu);
97 return 0;
98}
99
100/*
101 * INIT part
102 */
103
104static int __init alsa_emu10k1_synth_init(void)
105{
106
107 static snd_seq_dev_ops_t ops = {
108 snd_emu10k1_synth_new_device,
109 snd_emu10k1_synth_delete_device,
110 };
111 return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, &ops, sizeof(snd_emu10k1_synth_arg_t));
112}
113
114static void __exit alsa_emu10k1_synth_exit(void)
115{
116 snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH);
117}
118
119module_init(alsa_emu10k1_synth_init)
120module_exit(alsa_emu10k1_synth_exit)
diff --git a/sound/pci/emu10k1/emu10k1_synth_local.h b/sound/pci/emu10k1/emu10k1_synth_local.h
new file mode 100644
index 000000000000..7f50b01ddb76
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1_synth_local.h
@@ -0,0 +1,38 @@
1#ifndef __EMU10K1_SYNTH_LOCAL_H
2#define __EMU10K1_SYNTH_LOCAL_H
3/*
4 * Local defininitons for Emu10k1 wavetable
5 *
6 * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <sound/driver.h>
24#include <linux/time.h>
25#include <sound/core.h>
26#include <sound/emu10k1_synth.h>
27
28/* emu10k1_patch.c */
29int snd_emu10k1_sample_new(snd_emux_t *private_data, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void __user *_data, long count);
30int snd_emu10k1_sample_free(snd_emux_t *private_data, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr);
31int snd_emu10k1_memhdr_init(snd_emux_t *emu);
32
33/* emu10k1_callback.c */
34void snd_emu10k1_ops_setup(snd_emux_t *emu);
35int snd_emu10k1_synth_get_voice(emu10k1_t *hw);
36
37
38#endif /* __EMU10K1_SYNTH_LOCAL_H */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
new file mode 100644
index 000000000000..27dfd8ddddf4
--- /dev/null
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -0,0 +1,1643 @@
1/*
2 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
3 * Driver EMU10K1X chips
4 *
5 * Parts of this code were adapted from audigyls.c driver which is
6 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
7 *
8 * BUGS:
9 * --
10 *
11 * TODO:
12 *
13 * Chips (SB0200 model):
14 * - EMU10K1X-DBQ
15 * - STAC 9708T
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 *
31 */
32#include <sound/driver.h>
33#include <linux/init.h>
34#include <linux/interrupt.h>
35#include <linux/pci.h>
36#include <linux/slab.h>
37#include <linux/moduleparam.h>
38#include <sound/core.h>
39#include <sound/initval.h>
40#include <sound/pcm.h>
41#include <sound/ac97_codec.h>
42#include <sound/info.h>
43#include <sound/rawmidi.h>
44
45MODULE_AUTHOR("Francisco Moraes <fmoraes@nc.rr.com>");
46MODULE_DESCRIPTION("EMU10K1X");
47MODULE_LICENSE("GPL");
48MODULE_SUPPORTED_DEVICE("{{Dell Creative Labs,SB Live!}");
49
50// module parameters (see "Module Parameters")
51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
53static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
54
55module_param_array(index, int, NULL, 0444);
56MODULE_PARM_DESC(index, "Index value for the EMU10K1X soundcard.");
57module_param_array(id, charp, NULL, 0444);
58MODULE_PARM_DESC(id, "ID string for the EMU10K1X soundcard.");
59module_param_array(enable, bool, NULL, 0444);
60MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
61
62
63// some definitions were borrowed from emu10k1 driver as they seem to be the same
64/************************************************************************************************/
65/* PCI function 0 registers, address = <val> + PCIBASE0 */
66/************************************************************************************************/
67
68#define PTR 0x00 /* Indexed register set pointer register */
69 /* NOTE: The CHANNELNUM and ADDRESS words can */
70 /* be modified independently of each other. */
71
72#define DATA 0x04 /* Indexed register set data register */
73
74#define IPR 0x08 /* Global interrupt pending register */
75 /* Clear pending interrupts by writing a 1 to */
76 /* the relevant bits and zero to the other bits */
77#define IPR_MIDITRANSBUFEMPTY 0x00000001 /* MIDI UART transmit buffer empty */
78#define IPR_MIDIRECVBUFEMPTY 0x00000002 /* MIDI UART receive buffer empty */
79#define IPR_CH_0_LOOP 0x00000800 /* Channel 0 loop */
80#define IPR_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */
81#define IPR_CAP_0_LOOP 0x00080000 /* Channel capture loop */
82#define IPR_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */
83
84#define INTE 0x0c /* Interrupt enable register */
85#define INTE_MIDITXENABLE 0x00000001 /* Enable MIDI transmit-buffer-empty interrupts */
86#define INTE_MIDIRXENABLE 0x00000002 /* Enable MIDI receive-buffer-empty interrupts */
87#define INTE_CH_0_LOOP 0x00000800 /* Channel 0 loop */
88#define INTE_CH_0_HALF_LOOP 0x00000100 /* Channel 0 half loop */
89#define INTE_CAP_0_LOOP 0x00080000 /* Channel capture loop */
90#define INTE_CAP_0_HALF_LOOP 0x00010000 /* Channel capture half loop */
91
92#define HCFG 0x14 /* Hardware config register */
93
94#define HCFG_LOCKSOUNDCACHE 0x00000008 /* 1 = Cancel bustmaster accesses to soundcache */
95 /* NOTE: This should generally never be used. */
96#define HCFG_AUDIOENABLE 0x00000001 /* 0 = CODECs transmit zero-valued samples */
97 /* Should be set to 1 when the EMU10K1 is */
98 /* completely initialized. */
99#define GPIO 0x18 /* Defaults: 00001080-Analog, 00001000-SPDIF. */
100
101
102#define AC97DATA 0x1c /* AC97 register set data register (16 bit) */
103
104#define AC97ADDRESS 0x1e /* AC97 register set address register (8 bit) */
105
106/********************************************************************************************************/
107/* Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers */
108/********************************************************************************************************/
109#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
110 /* One list entry: 4 bytes for DMA address,
111 * 4 bytes for period_size << 16.
112 * One list entry is 8 bytes long.
113 * One list entry for each period in the buffer.
114 */
115#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
116#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
117#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */
118#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */
119#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */
120#define PLAYBACK_UNKNOWN1 0x07
121#define PLAYBACK_UNKNOWN2 0x08
122
123/* Only one capture channel supported */
124#define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */
125#define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */
126#define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */
127#define CAPTURE_UNKNOWN 0x13
128
129/* From 0x20 - 0x3f, last samples played on each channel */
130
131#define TRIGGER_CHANNEL 0x40 /* Trigger channel playback */
132#define TRIGGER_CHANNEL_0 0x00000001 /* Trigger channel 0 */
133#define TRIGGER_CHANNEL_1 0x00000002 /* Trigger channel 1 */
134#define TRIGGER_CHANNEL_2 0x00000004 /* Trigger channel 2 */
135#define TRIGGER_CAPTURE 0x00000100 /* Trigger capture channel */
136
137#define ROUTING 0x41 /* Setup sound routing ? */
138#define ROUTING_FRONT_LEFT 0x00000001
139#define ROUTING_FRONT_RIGHT 0x00000002
140#define ROUTING_REAR_LEFT 0x00000004
141#define ROUTING_REAR_RIGHT 0x00000008
142#define ROUTING_CENTER_LFE 0x00010000
143
144#define SPCS0 0x42 /* SPDIF output Channel Status 0 register */
145
146#define SPCS1 0x43 /* SPDIF output Channel Status 1 register */
147
148#define SPCS2 0x44 /* SPDIF output Channel Status 2 register */
149
150#define SPCS_CLKACCYMASK 0x30000000 /* Clock accuracy */
151#define SPCS_CLKACCY_1000PPM 0x00000000 /* 1000 parts per million */
152#define SPCS_CLKACCY_50PPM 0x10000000 /* 50 parts per million */
153#define SPCS_CLKACCY_VARIABLE 0x20000000 /* Variable accuracy */
154#define SPCS_SAMPLERATEMASK 0x0f000000 /* Sample rate */
155#define SPCS_SAMPLERATE_44 0x00000000 /* 44.1kHz sample rate */
156#define SPCS_SAMPLERATE_48 0x02000000 /* 48kHz sample rate */
157#define SPCS_SAMPLERATE_32 0x03000000 /* 32kHz sample rate */
158#define SPCS_CHANNELNUMMASK 0x00f00000 /* Channel number */
159#define SPCS_CHANNELNUM_UNSPEC 0x00000000 /* Unspecified channel number */
160#define SPCS_CHANNELNUM_LEFT 0x00100000 /* Left channel */
161#define SPCS_CHANNELNUM_RIGHT 0x00200000 /* Right channel */
162#define SPCS_SOURCENUMMASK 0x000f0000 /* Source number */
163#define SPCS_SOURCENUM_UNSPEC 0x00000000 /* Unspecified source number */
164#define SPCS_GENERATIONSTATUS 0x00008000 /* Originality flag (see IEC-958 spec) */
165#define SPCS_CATEGORYCODEMASK 0x00007f00 /* Category code (see IEC-958 spec) */
166#define SPCS_MODEMASK 0x000000c0 /* Mode (see IEC-958 spec) */
167#define SPCS_EMPHASISMASK 0x00000038 /* Emphasis */
168#define SPCS_EMPHASIS_NONE 0x00000000 /* No emphasis */
169#define SPCS_EMPHASIS_50_15 0x00000008 /* 50/15 usec 2 channel */
170#define SPCS_COPYRIGHT 0x00000004 /* Copyright asserted flag -- do not modify */
171#define SPCS_NOTAUDIODATA 0x00000002 /* 0 = Digital audio, 1 = not audio */
172#define SPCS_PROFESSIONAL 0x00000001 /* 0 = Consumer (IEC-958), 1 = pro (AES3-1992) */
173
174#define SPDIF_SELECT 0x45 /* Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF */
175
176/* This is the MPU port on the card */
177#define MUDATA 0x47
178#define MUCMD 0x48
179#define MUSTAT MUCMD
180
181/* From 0x50 - 0x5f, last samples captured */
182
183/**
184 * The hardware has 3 channels for playback and 1 for capture.
185 * - channel 0 is the front channel
186 * - channel 1 is the rear channel
187 * - channel 2 is the center/lfe chanel
188 * Volume is controlled by the AC97 for the front and rear channels by
189 * the PCM Playback Volume, Sigmatel Surround Playback Volume and
190 * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
191 * the front/rear channel mixing in the REAR OUT jack. When using the
192 * 4-Speaker Stereo, both front and rear channels will be mixed in the
193 * REAR OUT.
194 * The center/lfe channel has no volume control and cannot be muted during
195 * playback.
196 */
197
198typedef struct snd_emu10k1x_voice emu10k1x_voice_t;
199typedef struct snd_emu10k1x emu10k1x_t;
200typedef struct snd_emu10k1x_pcm emu10k1x_pcm_t;
201
202struct snd_emu10k1x_voice {
203 emu10k1x_t *emu;
204 int number;
205 int use;
206
207 emu10k1x_pcm_t *epcm;
208};
209
210struct snd_emu10k1x_pcm {
211 emu10k1x_t *emu;
212 snd_pcm_substream_t *substream;
213 emu10k1x_voice_t *voice;
214 unsigned short running;
215};
216
217typedef struct {
218 struct snd_emu10k1x *emu;
219 snd_rawmidi_t *rmidi;
220 snd_rawmidi_substream_t *substream_input;
221 snd_rawmidi_substream_t *substream_output;
222 unsigned int midi_mode;
223 spinlock_t input_lock;
224 spinlock_t output_lock;
225 spinlock_t open_lock;
226 int tx_enable, rx_enable;
227 int port;
228 int ipr_tx, ipr_rx;
229 void (*interrupt)(emu10k1x_t *emu, unsigned int status);
230} emu10k1x_midi_t;
231
232// definition of the chip-specific record
233struct snd_emu10k1x {
234 snd_card_t *card;
235 struct pci_dev *pci;
236
237 unsigned long port;
238 struct resource *res_port;
239 int irq;
240
241 unsigned int revision; /* chip revision */
242 unsigned int serial; /* serial number */
243 unsigned short model; /* subsystem id */
244
245 spinlock_t emu_lock;
246 spinlock_t voice_lock;
247
248 ac97_t *ac97;
249 snd_pcm_t *pcm;
250
251 emu10k1x_voice_t voices[3];
252 emu10k1x_voice_t capture_voice;
253 u32 spdif_bits[3]; // SPDIF out setup
254
255 struct snd_dma_buffer dma_buffer;
256
257 emu10k1x_midi_t midi;
258};
259
260/* hardware definition */
261static snd_pcm_hardware_t snd_emu10k1x_playback_hw = {
262 .info = (SNDRV_PCM_INFO_MMAP |
263 SNDRV_PCM_INFO_INTERLEAVED |
264 SNDRV_PCM_INFO_BLOCK_TRANSFER |
265 SNDRV_PCM_INFO_MMAP_VALID),
266 .formats = SNDRV_PCM_FMTBIT_S16_LE,
267 .rates = SNDRV_PCM_RATE_48000,
268 .rate_min = 48000,
269 .rate_max = 48000,
270 .channels_min = 2,
271 .channels_max = 2,
272 .buffer_bytes_max = (32*1024),
273 .period_bytes_min = 64,
274 .period_bytes_max = (16*1024),
275 .periods_min = 2,
276 .periods_max = 8,
277 .fifo_size = 0,
278};
279
280static snd_pcm_hardware_t snd_emu10k1x_capture_hw = {
281 .info = (SNDRV_PCM_INFO_MMAP |
282 SNDRV_PCM_INFO_INTERLEAVED |
283 SNDRV_PCM_INFO_BLOCK_TRANSFER |
284 SNDRV_PCM_INFO_MMAP_VALID),
285 .formats = SNDRV_PCM_FMTBIT_S16_LE,
286 .rates = SNDRV_PCM_RATE_48000,
287 .rate_min = 48000,
288 .rate_max = 48000,
289 .channels_min = 2,
290 .channels_max = 2,
291 .buffer_bytes_max = (32*1024),
292 .period_bytes_min = 64,
293 .period_bytes_max = (16*1024),
294 .periods_min = 2,
295 .periods_max = 2,
296 .fifo_size = 0,
297};
298
299static unsigned int snd_emu10k1x_ptr_read(emu10k1x_t * emu,
300 unsigned int reg,
301 unsigned int chn)
302{
303 unsigned long flags;
304 unsigned int regptr, val;
305
306 regptr = (reg << 16) | chn;
307
308 spin_lock_irqsave(&emu->emu_lock, flags);
309 outl(regptr, emu->port + PTR);
310 val = inl(emu->port + DATA);
311 spin_unlock_irqrestore(&emu->emu_lock, flags);
312 return val;
313}
314
315static void snd_emu10k1x_ptr_write(emu10k1x_t *emu,
316 unsigned int reg,
317 unsigned int chn,
318 unsigned int data)
319{
320 unsigned int regptr;
321 unsigned long flags;
322
323 regptr = (reg << 16) | chn;
324
325 spin_lock_irqsave(&emu->emu_lock, flags);
326 outl(regptr, emu->port + PTR);
327 outl(data, emu->port + DATA);
328 spin_unlock_irqrestore(&emu->emu_lock, flags);
329}
330
331static void snd_emu10k1x_intr_enable(emu10k1x_t *emu, unsigned int intrenb)
332{
333 unsigned long flags;
334 unsigned int enable;
335
336 spin_lock_irqsave(&emu->emu_lock, flags);
337 enable = inl(emu->port + INTE) | intrenb;
338 outl(enable, emu->port + INTE);
339 spin_unlock_irqrestore(&emu->emu_lock, flags);
340}
341
342static void snd_emu10k1x_intr_disable(emu10k1x_t *emu, unsigned int intrenb)
343{
344 unsigned long flags;
345 unsigned int enable;
346
347 spin_lock_irqsave(&emu->emu_lock, flags);
348 enable = inl(emu->port + INTE) & ~intrenb;
349 outl(enable, emu->port + INTE);
350 spin_unlock_irqrestore(&emu->emu_lock, flags);
351}
352
353static void snd_emu10k1x_gpio_write(emu10k1x_t *emu, unsigned int value)
354{
355 unsigned long flags;
356
357 spin_lock_irqsave(&emu->emu_lock, flags);
358 outl(value, emu->port + GPIO);
359 spin_unlock_irqrestore(&emu->emu_lock, flags);
360}
361
362static void snd_emu10k1x_pcm_free_substream(snd_pcm_runtime_t *runtime)
363{
364 emu10k1x_pcm_t *epcm = runtime->private_data;
365
366 if (epcm)
367 kfree(epcm);
368}
369
370static void snd_emu10k1x_pcm_interrupt(emu10k1x_t *emu, emu10k1x_voice_t *voice)
371{
372 emu10k1x_pcm_t *epcm;
373
374 if ((epcm = voice->epcm) == NULL)
375 return;
376 if (epcm->substream == NULL)
377 return;
378#if 0
379 snd_printk(KERN_INFO "IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
380 epcm->substream->ops->pointer(epcm->substream),
381 snd_pcm_lib_period_bytes(epcm->substream),
382 snd_pcm_lib_buffer_bytes(epcm->substream));
383#endif
384 snd_pcm_period_elapsed(epcm->substream);
385}
386
387/* open callback */
388static int snd_emu10k1x_playback_open(snd_pcm_substream_t *substream)
389{
390 emu10k1x_t *chip = snd_pcm_substream_chip(substream);
391 emu10k1x_pcm_t *epcm;
392 snd_pcm_runtime_t *runtime = substream->runtime;
393 int err;
394
395 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
396 return err;
397 }
398 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
399 return err;
400
401 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
402 if (epcm == NULL)
403 return -ENOMEM;
404 epcm->emu = chip;
405 epcm->substream = substream;
406
407 runtime->private_data = epcm;
408 runtime->private_free = snd_emu10k1x_pcm_free_substream;
409
410 runtime->hw = snd_emu10k1x_playback_hw;
411
412 return 0;
413}
414
415/* close callback */
416static int snd_emu10k1x_playback_close(snd_pcm_substream_t *substream)
417{
418 return 0;
419}
420
421/* hw_params callback */
422static int snd_emu10k1x_pcm_hw_params(snd_pcm_substream_t *substream,
423 snd_pcm_hw_params_t * hw_params)
424{
425 snd_pcm_runtime_t *runtime = substream->runtime;
426 emu10k1x_pcm_t *epcm = runtime->private_data;
427
428 if (! epcm->voice) {
429 epcm->voice = &epcm->emu->voices[substream->pcm->device];
430 epcm->voice->use = 1;
431 epcm->voice->epcm = epcm;
432 }
433
434 return snd_pcm_lib_malloc_pages(substream,
435 params_buffer_bytes(hw_params));
436}
437
438/* hw_free callback */
439static int snd_emu10k1x_pcm_hw_free(snd_pcm_substream_t *substream)
440{
441 snd_pcm_runtime_t *runtime = substream->runtime;
442 emu10k1x_pcm_t *epcm;
443
444 if (runtime->private_data == NULL)
445 return 0;
446
447 epcm = runtime->private_data;
448
449 if (epcm->voice) {
450 epcm->voice->use = 0;
451 epcm->voice->epcm = NULL;
452 epcm->voice = NULL;
453 }
454
455 return snd_pcm_lib_free_pages(substream);
456}
457
458/* prepare callback */
459static int snd_emu10k1x_pcm_prepare(snd_pcm_substream_t *substream)
460{
461 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
462 snd_pcm_runtime_t *runtime = substream->runtime;
463 emu10k1x_pcm_t *epcm = runtime->private_data;
464 int voice = epcm->voice->number;
465 u32 *table_base = (u32 *)(emu->dma_buffer.area+1024*voice);
466 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
467 int i;
468
469 for(i=0; i < runtime->periods; i++) {
470 *table_base++=runtime->dma_addr+(i*period_size_bytes);
471 *table_base++=period_size_bytes<<16;
472 }
473
474 snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer.addr+1024*voice);
475 snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19);
476 snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0);
477 snd_emu10k1x_ptr_write(emu, PLAYBACK_POINTER, voice, 0);
478 snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN1, voice, 0);
479 snd_emu10k1x_ptr_write(emu, PLAYBACK_UNKNOWN2, voice, 0);
480 snd_emu10k1x_ptr_write(emu, PLAYBACK_DMA_ADDR, voice, runtime->dma_addr);
481
482 snd_emu10k1x_ptr_write(emu, PLAYBACK_PERIOD_SIZE, voice, frames_to_bytes(runtime, runtime->period_size)<<16);
483
484 return 0;
485}
486
487/* trigger callback */
488static int snd_emu10k1x_pcm_trigger(snd_pcm_substream_t *substream,
489 int cmd)
490{
491 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
492 snd_pcm_runtime_t *runtime = substream->runtime;
493 emu10k1x_pcm_t *epcm = runtime->private_data;
494 int channel = epcm->voice->number;
495 int result = 0;
496
497// snd_printk(KERN_INFO "trigger - emu10k1x = 0x%x, cmd = %i, pointer = %d\n", (int)emu, cmd, (int)substream->ops->pointer(substream));
498
499 switch (cmd) {
500 case SNDRV_PCM_TRIGGER_START:
501 if(runtime->periods == 2)
502 snd_emu10k1x_intr_enable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
503 else
504 snd_emu10k1x_intr_enable(emu, INTE_CH_0_LOOP << channel);
505 epcm->running = 1;
506 snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|(TRIGGER_CHANNEL_0<<channel));
507 break;
508 case SNDRV_PCM_TRIGGER_STOP:
509 epcm->running = 0;
510 snd_emu10k1x_intr_disable(emu, (INTE_CH_0_LOOP | INTE_CH_0_HALF_LOOP) << channel);
511 snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CHANNEL_0<<channel));
512 break;
513 default:
514 result = -EINVAL;
515 break;
516 }
517 return result;
518}
519
520/* pointer callback */
521static snd_pcm_uframes_t
522snd_emu10k1x_pcm_pointer(snd_pcm_substream_t *substream)
523{
524 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
525 snd_pcm_runtime_t *runtime = substream->runtime;
526 emu10k1x_pcm_t *epcm = runtime->private_data;
527 int channel = epcm->voice->number;
528 snd_pcm_uframes_t ptr = 0, ptr1 = 0, ptr2= 0,ptr3 = 0,ptr4 = 0;
529
530 if (!epcm->running)
531 return 0;
532
533 ptr3 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
534 ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
535 ptr4 = snd_emu10k1x_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
536
537 if(ptr4 == 0 && ptr1 == frames_to_bytes(runtime, runtime->buffer_size))
538 return 0;
539
540 if (ptr3 != ptr4)
541 ptr1 = snd_emu10k1x_ptr_read(emu, PLAYBACK_POINTER, channel);
542 ptr2 = bytes_to_frames(runtime, ptr1);
543 ptr2 += (ptr4 >> 3) * runtime->period_size;
544 ptr = ptr2;
545
546 if (ptr >= runtime->buffer_size)
547 ptr -= runtime->buffer_size;
548
549 return ptr;
550}
551
552/* operators */
553static snd_pcm_ops_t snd_emu10k1x_playback_ops = {
554 .open = snd_emu10k1x_playback_open,
555 .close = snd_emu10k1x_playback_close,
556 .ioctl = snd_pcm_lib_ioctl,
557 .hw_params = snd_emu10k1x_pcm_hw_params,
558 .hw_free = snd_emu10k1x_pcm_hw_free,
559 .prepare = snd_emu10k1x_pcm_prepare,
560 .trigger = snd_emu10k1x_pcm_trigger,
561 .pointer = snd_emu10k1x_pcm_pointer,
562};
563
564/* open_capture callback */
565static int snd_emu10k1x_pcm_open_capture(snd_pcm_substream_t *substream)
566{
567 emu10k1x_t *chip = snd_pcm_substream_chip(substream);
568 emu10k1x_pcm_t *epcm;
569 snd_pcm_runtime_t *runtime = substream->runtime;
570 int err;
571
572 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
573 return err;
574 if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
575 return err;
576
577 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
578 if (epcm == NULL)
579 return -ENOMEM;
580
581 epcm->emu = chip;
582 epcm->substream = substream;
583
584 runtime->private_data = epcm;
585 runtime->private_free = snd_emu10k1x_pcm_free_substream;
586
587 runtime->hw = snd_emu10k1x_capture_hw;
588
589 return 0;
590}
591
592/* close callback */
593static int snd_emu10k1x_pcm_close_capture(snd_pcm_substream_t *substream)
594{
595 return 0;
596}
597
598/* hw_params callback */
599static int snd_emu10k1x_pcm_hw_params_capture(snd_pcm_substream_t *substream,
600 snd_pcm_hw_params_t * hw_params)
601{
602 snd_pcm_runtime_t *runtime = substream->runtime;
603 emu10k1x_pcm_t *epcm = runtime->private_data;
604
605 if (! epcm->voice) {
606 if (epcm->emu->capture_voice.use)
607 return -EBUSY;
608 epcm->voice = &epcm->emu->capture_voice;
609 epcm->voice->epcm = epcm;
610 epcm->voice->use = 1;
611 }
612
613 return snd_pcm_lib_malloc_pages(substream,
614 params_buffer_bytes(hw_params));
615}
616
617/* hw_free callback */
618static int snd_emu10k1x_pcm_hw_free_capture(snd_pcm_substream_t *substream)
619{
620 snd_pcm_runtime_t *runtime = substream->runtime;
621
622 emu10k1x_pcm_t *epcm;
623
624 if (runtime->private_data == NULL)
625 return 0;
626 epcm = runtime->private_data;
627
628 if (epcm->voice) {
629 epcm->voice->use = 0;
630 epcm->voice->epcm = NULL;
631 epcm->voice = NULL;
632 }
633
634 return snd_pcm_lib_free_pages(substream);
635}
636
637/* prepare capture callback */
638static int snd_emu10k1x_pcm_prepare_capture(snd_pcm_substream_t *substream)
639{
640 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
641 snd_pcm_runtime_t *runtime = substream->runtime;
642
643 snd_emu10k1x_ptr_write(emu, CAPTURE_DMA_ADDR, 0, runtime->dma_addr);
644 snd_emu10k1x_ptr_write(emu, CAPTURE_BUFFER_SIZE, 0, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
645 snd_emu10k1x_ptr_write(emu, CAPTURE_POINTER, 0, 0);
646 snd_emu10k1x_ptr_write(emu, CAPTURE_UNKNOWN, 0, 0);
647
648 return 0;
649}
650
651/* trigger_capture callback */
652static int snd_emu10k1x_pcm_trigger_capture(snd_pcm_substream_t *substream,
653 int cmd)
654{
655 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
656 snd_pcm_runtime_t *runtime = substream->runtime;
657 emu10k1x_pcm_t *epcm = runtime->private_data;
658 int result = 0;
659
660 switch (cmd) {
661 case SNDRV_PCM_TRIGGER_START:
662 snd_emu10k1x_intr_enable(emu, INTE_CAP_0_LOOP |
663 INTE_CAP_0_HALF_LOOP);
664 snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0)|TRIGGER_CAPTURE);
665 epcm->running = 1;
666 break;
667 case SNDRV_PCM_TRIGGER_STOP:
668 epcm->running = 0;
669 snd_emu10k1x_intr_disable(emu, INTE_CAP_0_LOOP |
670 INTE_CAP_0_HALF_LOOP);
671 snd_emu10k1x_ptr_write(emu, TRIGGER_CHANNEL, 0, snd_emu10k1x_ptr_read(emu, TRIGGER_CHANNEL, 0) & ~(TRIGGER_CAPTURE));
672 break;
673 default:
674 result = -EINVAL;
675 break;
676 }
677 return result;
678}
679
680/* pointer_capture callback */
681static snd_pcm_uframes_t
682snd_emu10k1x_pcm_pointer_capture(snd_pcm_substream_t *substream)
683{
684 emu10k1x_t *emu = snd_pcm_substream_chip(substream);
685 snd_pcm_runtime_t *runtime = substream->runtime;
686 emu10k1x_pcm_t *epcm = runtime->private_data;
687 snd_pcm_uframes_t ptr;
688
689 if (!epcm->running)
690 return 0;
691
692 ptr = bytes_to_frames(runtime, snd_emu10k1x_ptr_read(emu, CAPTURE_POINTER, 0));
693 if (ptr >= runtime->buffer_size)
694 ptr -= runtime->buffer_size;
695
696 return ptr;
697}
698
699static snd_pcm_ops_t snd_emu10k1x_capture_ops = {
700 .open = snd_emu10k1x_pcm_open_capture,
701 .close = snd_emu10k1x_pcm_close_capture,
702 .ioctl = snd_pcm_lib_ioctl,
703 .hw_params = snd_emu10k1x_pcm_hw_params_capture,
704 .hw_free = snd_emu10k1x_pcm_hw_free_capture,
705 .prepare = snd_emu10k1x_pcm_prepare_capture,
706 .trigger = snd_emu10k1x_pcm_trigger_capture,
707 .pointer = snd_emu10k1x_pcm_pointer_capture,
708};
709
710static unsigned short snd_emu10k1x_ac97_read(ac97_t *ac97,
711 unsigned short reg)
712{
713 emu10k1x_t *emu = ac97->private_data;
714 unsigned long flags;
715 unsigned short val;
716
717 spin_lock_irqsave(&emu->emu_lock, flags);
718 outb(reg, emu->port + AC97ADDRESS);
719 val = inw(emu->port + AC97DATA);
720 spin_unlock_irqrestore(&emu->emu_lock, flags);
721 return val;
722}
723
724static void snd_emu10k1x_ac97_write(ac97_t *ac97,
725 unsigned short reg, unsigned short val)
726{
727 emu10k1x_t *emu = ac97->private_data;
728 unsigned long flags;
729
730 spin_lock_irqsave(&emu->emu_lock, flags);
731 outb(reg, emu->port + AC97ADDRESS);
732 outw(val, emu->port + AC97DATA);
733 spin_unlock_irqrestore(&emu->emu_lock, flags);
734}
735
736static int snd_emu10k1x_ac97(emu10k1x_t *chip)
737{
738 ac97_bus_t *pbus;
739 ac97_template_t ac97;
740 int err;
741 static ac97_bus_ops_t ops = {
742 .write = snd_emu10k1x_ac97_write,
743 .read = snd_emu10k1x_ac97_read,
744 };
745
746 if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
747 return err;
748 pbus->no_vra = 1; /* we don't need VRA */
749
750 memset(&ac97, 0, sizeof(ac97));
751 ac97.private_data = chip;
752 ac97.scaps = AC97_SCAP_NO_SPDIF;
753 return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
754}
755
756static int snd_emu10k1x_free(emu10k1x_t *chip)
757{
758 snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0);
759 // disable interrupts
760 outl(0, chip->port + INTE);
761 // disable audio
762 outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
763
764 // release the i/o port
765 if (chip->res_port) {
766 release_resource(chip->res_port);
767 kfree_nocheck(chip->res_port);
768 }
769 // release the irq
770 if (chip->irq >= 0)
771 free_irq(chip->irq, (void *)chip);
772
773 // release the DMA
774 if (chip->dma_buffer.area) {
775 snd_dma_free_pages(&chip->dma_buffer);
776 }
777
778 pci_disable_device(chip->pci);
779
780 // release the data
781 kfree(chip);
782 return 0;
783}
784
785static int snd_emu10k1x_dev_free(snd_device_t *device)
786{
787 emu10k1x_t *chip = device->device_data;
788 return snd_emu10k1x_free(chip);
789}
790
791static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id,
792 struct pt_regs *regs)
793{
794 unsigned int status;
795
796 emu10k1x_t *chip = dev_id;
797 emu10k1x_voice_t *pvoice = chip->voices;
798 int i;
799 int mask;
800
801 status = inl(chip->port + IPR);
802
803 if(status) {
804 // capture interrupt
805 if(status & (IPR_CAP_0_LOOP | IPR_CAP_0_HALF_LOOP)) {
806 emu10k1x_voice_t *pvoice = &chip->capture_voice;
807 if(pvoice->use)
808 snd_emu10k1x_pcm_interrupt(chip, pvoice);
809 else
810 snd_emu10k1x_intr_disable(chip,
811 INTE_CAP_0_LOOP |
812 INTE_CAP_0_HALF_LOOP);
813 }
814
815 mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP;
816 for(i = 0; i < 3; i++) {
817 if(status & mask) {
818 if(pvoice->use)
819 snd_emu10k1x_pcm_interrupt(chip, pvoice);
820 else
821 snd_emu10k1x_intr_disable(chip, mask);
822 }
823 pvoice++;
824 mask <<= 1;
825 }
826
827 if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
828 if (chip->midi.interrupt)
829 chip->midi.interrupt(chip, status);
830 else
831 snd_emu10k1x_intr_disable(chip, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
832 }
833
834 // acknowledge the interrupt if necessary
835 if(status)
836 outl(status, chip->port+IPR);
837
838// snd_printk(KERN_INFO "interrupt %08x\n", status);
839 }
840
841 return IRQ_HANDLED;
842}
843
844static void snd_emu10k1x_pcm_free(snd_pcm_t *pcm)
845{
846 emu10k1x_t *emu = pcm->private_data;
847 emu->pcm = NULL;
848 snd_pcm_lib_preallocate_free_for_all(pcm);
849}
850
851static int __devinit snd_emu10k1x_pcm(emu10k1x_t *emu, int device, snd_pcm_t **rpcm)
852{
853 snd_pcm_t *pcm;
854 int err;
855 int capture = 0;
856
857 if (rpcm)
858 *rpcm = NULL;
859 if (device == 0)
860 capture = 1;
861
862 if ((err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm)) < 0)
863 return err;
864
865 pcm->private_data = emu;
866 pcm->private_free = snd_emu10k1x_pcm_free;
867
868 switch(device) {
869 case 0:
870 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
871 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1x_capture_ops);
872 break;
873 case 1:
874 case 2:
875 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1x_playback_ops);
876 break;
877 }
878
879 pcm->info_flags = 0;
880 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
881 switch(device) {
882 case 0:
883 strcpy(pcm->name, "EMU10K1X Front");
884 break;
885 case 1:
886 strcpy(pcm->name, "EMU10K1X Rear");
887 break;
888 case 2:
889 strcpy(pcm->name, "EMU10K1X Center/LFE");
890 break;
891 }
892 emu->pcm = pcm;
893
894 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
895 snd_dma_pci_data(emu->pci),
896 32*1024, 32*1024);
897
898 if (rpcm)
899 *rpcm = pcm;
900
901 return 0;
902}
903
904static int __devinit snd_emu10k1x_create(snd_card_t *card,
905 struct pci_dev *pci,
906 emu10k1x_t **rchip)
907{
908 emu10k1x_t *chip;
909 int err;
910 int ch;
911 static snd_device_ops_t ops = {
912 .dev_free = snd_emu10k1x_dev_free,
913 };
914
915 *rchip = NULL;
916
917 if ((err = pci_enable_device(pci)) < 0)
918 return err;
919 if (pci_set_dma_mask(pci, 0x0fffffff) < 0 ||
920 pci_set_consistent_dma_mask(pci, 0x0fffffff) < 0) {
921 snd_printk(KERN_ERR "error to set 28bit mask DMA\n");
922 pci_disable_device(pci);
923 return -ENXIO;
924 }
925
926 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
927 if (chip == NULL) {
928 pci_disable_device(pci);
929 return -ENOMEM;
930 }
931
932 chip->card = card;
933 chip->pci = pci;
934 chip->irq = -1;
935
936 spin_lock_init(&chip->emu_lock);
937 spin_lock_init(&chip->voice_lock);
938
939 chip->port = pci_resource_start(pci, 0);
940 if ((chip->res_port = request_region(chip->port, 8,
941 "EMU10K1X")) == NULL) {
942 snd_printk(KERN_ERR "emu10k1x: cannot allocate the port 0x%lx\n", chip->port);
943 snd_emu10k1x_free(chip);
944 return -EBUSY;
945 }
946
947 if (request_irq(pci->irq, snd_emu10k1x_interrupt,
948 SA_INTERRUPT|SA_SHIRQ, "EMU10K1X",
949 (void *)chip)) {
950 snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
951 snd_emu10k1x_free(chip);
952 return -EBUSY;
953 }
954 chip->irq = pci->irq;
955
956 if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
957 4 * 1024, &chip->dma_buffer) < 0) {
958 snd_emu10k1x_free(chip);
959 return -ENOMEM;
960 }
961
962 pci_set_master(pci);
963 /* read revision & serial */
964 pci_read_config_byte(pci, PCI_REVISION_ID, (char *)&chip->revision);
965 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
966 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
967 snd_printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
968 chip->revision, chip->serial);
969
970 outl(0, chip->port + INTE);
971
972 for(ch = 0; ch < 3; ch++) {
973 chip->voices[ch].emu = chip;
974 chip->voices[ch].number = ch;
975 }
976
977 /*
978 * Init to 0x02109204 :
979 * Clock accuracy = 0 (1000ppm)
980 * Sample Rate = 2 (48kHz)
981 * Audio Channel = 1 (Left of 2)
982 * Source Number = 0 (Unspecified)
983 * Generation Status = 1 (Original for Cat Code 12)
984 * Cat Code = 12 (Digital Signal Mixer)
985 * Mode = 0 (Mode 0)
986 * Emphasis = 0 (None)
987 * CP = 1 (Copyright unasserted)
988 * AN = 0 (Audio data)
989 * P = 0 (Consumer)
990 */
991 snd_emu10k1x_ptr_write(chip, SPCS0, 0,
992 chip->spdif_bits[0] =
993 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
994 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
995 SPCS_GENERATIONSTATUS | 0x00001200 |
996 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
997 snd_emu10k1x_ptr_write(chip, SPCS1, 0,
998 chip->spdif_bits[1] =
999 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1000 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1001 SPCS_GENERATIONSTATUS | 0x00001200 |
1002 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1003 snd_emu10k1x_ptr_write(chip, SPCS2, 0,
1004 chip->spdif_bits[2] =
1005 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1006 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1007 SPCS_GENERATIONSTATUS | 0x00001200 |
1008 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1009
1010 snd_emu10k1x_ptr_write(chip, SPDIF_SELECT, 0, 0x700); // disable SPDIF
1011 snd_emu10k1x_ptr_write(chip, ROUTING, 0, 0x1003F); // routing
1012 snd_emu10k1x_gpio_write(chip, 0x1080); // analog mode
1013
1014 outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG);
1015
1016 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
1017 chip, &ops)) < 0) {
1018 snd_emu10k1x_free(chip);
1019 return err;
1020 }
1021 *rchip = chip;
1022 return 0;
1023}
1024
1025static void snd_emu10k1x_proc_reg_read(snd_info_entry_t *entry,
1026 snd_info_buffer_t * buffer)
1027{
1028 emu10k1x_t *emu = entry->private_data;
1029 unsigned long value,value1,value2;
1030 unsigned long flags;
1031 int i;
1032
1033 snd_iprintf(buffer, "Registers:\n\n");
1034 for(i = 0; i < 0x20; i+=4) {
1035 spin_lock_irqsave(&emu->emu_lock, flags);
1036 value = inl(emu->port + i);
1037 spin_unlock_irqrestore(&emu->emu_lock, flags);
1038 snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
1039 }
1040 snd_iprintf(buffer, "\nRegisters\n\n");
1041 for(i = 0; i <= 0x48; i++) {
1042 value = snd_emu10k1x_ptr_read(emu, i, 0);
1043 if(i < 0x10 || (i >= 0x20 && i < 0x40)) {
1044 value1 = snd_emu10k1x_ptr_read(emu, i, 1);
1045 value2 = snd_emu10k1x_ptr_read(emu, i, 2);
1046 snd_iprintf(buffer, "%02X: %08lX %08lX %08lX\n", i, value, value1, value2);
1047 } else {
1048 snd_iprintf(buffer, "%02X: %08lX\n", i, value);
1049 }
1050 }
1051}
1052
1053static void snd_emu10k1x_proc_reg_write(snd_info_entry_t *entry,
1054 snd_info_buffer_t *buffer)
1055{
1056 emu10k1x_t *emu = entry->private_data;
1057 char line[64];
1058 unsigned int reg, channel_id , val;
1059
1060 while (!snd_info_get_line(buffer, line, sizeof(line))) {
1061 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
1062 continue;
1063
1064 if ((reg < 0x49) && (reg >=0) && (val <= 0xffffffff)
1065 && (channel_id >=0) && (channel_id <= 2) )
1066 snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
1067 }
1068}
1069
1070static int __devinit snd_emu10k1x_proc_init(emu10k1x_t * emu)
1071{
1072 snd_info_entry_t *entry;
1073
1074 if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) {
1075 snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1x_proc_reg_read);
1076 entry->c.text.write_size = 64;
1077 entry->c.text.write = snd_emu10k1x_proc_reg_write;
1078 entry->private_data = emu;
1079 }
1080
1081 return 0;
1082}
1083
1084static int snd_emu10k1x_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1085{
1086 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1087 uinfo->count = 1;
1088 uinfo->value.integer.min = 0;
1089 uinfo->value.integer.max = 1;
1090 return 0;
1091}
1092
1093static int snd_emu10k1x_shared_spdif_get(snd_kcontrol_t * kcontrol,
1094 snd_ctl_elem_value_t * ucontrol)
1095{
1096 emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
1097
1098 ucontrol->value.integer.value[0] = (snd_emu10k1x_ptr_read(emu, SPDIF_SELECT, 0) == 0x700) ? 0 : 1;
1099
1100 return 0;
1101}
1102
1103static int snd_emu10k1x_shared_spdif_put(snd_kcontrol_t * kcontrol,
1104 snd_ctl_elem_value_t * ucontrol)
1105{
1106 emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
1107 unsigned int val;
1108 int change = 0;
1109
1110 val = ucontrol->value.integer.value[0] ;
1111
1112 if (val) {
1113 // enable spdif output
1114 snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x000);
1115 snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x700);
1116 snd_emu10k1x_gpio_write(emu, 0x1000);
1117 } else {
1118 // disable spdif output
1119 snd_emu10k1x_ptr_write(emu, SPDIF_SELECT, 0, 0x700);
1120 snd_emu10k1x_ptr_write(emu, ROUTING, 0, 0x1003F);
1121 snd_emu10k1x_gpio_write(emu, 0x1080);
1122 }
1123 return change;
1124}
1125
1126static snd_kcontrol_new_t snd_emu10k1x_shared_spdif __devinitdata =
1127{
1128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1129 .name = "Analog/Digital Output Jack",
1130 .info = snd_emu10k1x_shared_spdif_info,
1131 .get = snd_emu10k1x_shared_spdif_get,
1132 .put = snd_emu10k1x_shared_spdif_put
1133};
1134
1135static int snd_emu10k1x_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1136{
1137 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1138 uinfo->count = 1;
1139 return 0;
1140}
1141
1142static int snd_emu10k1x_spdif_get(snd_kcontrol_t * kcontrol,
1143 snd_ctl_elem_value_t * ucontrol)
1144{
1145 emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
1146 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1147
1148 ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
1149 ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
1150 ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
1151 ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
1152 return 0;
1153}
1154
1155static int snd_emu10k1x_spdif_get_mask(snd_kcontrol_t * kcontrol,
1156 snd_ctl_elem_value_t * ucontrol)
1157{
1158 ucontrol->value.iec958.status[0] = 0xff;
1159 ucontrol->value.iec958.status[1] = 0xff;
1160 ucontrol->value.iec958.status[2] = 0xff;
1161 ucontrol->value.iec958.status[3] = 0xff;
1162 return 0;
1163}
1164
1165static int snd_emu10k1x_spdif_put(snd_kcontrol_t * kcontrol,
1166 snd_ctl_elem_value_t * ucontrol)
1167{
1168 emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
1169 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1170 int change;
1171 unsigned int val;
1172
1173 val = (ucontrol->value.iec958.status[0] << 0) |
1174 (ucontrol->value.iec958.status[1] << 8) |
1175 (ucontrol->value.iec958.status[2] << 16) |
1176 (ucontrol->value.iec958.status[3] << 24);
1177 change = val != emu->spdif_bits[idx];
1178 if (change) {
1179 snd_emu10k1x_ptr_write(emu, SPCS0 + idx, 0, val);
1180 emu->spdif_bits[idx] = val;
1181 }
1182 return change;
1183}
1184
1185static snd_kcontrol_new_t snd_emu10k1x_spdif_mask_control =
1186{
1187 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1189 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
1190 .count = 3,
1191 .info = snd_emu10k1x_spdif_info,
1192 .get = snd_emu10k1x_spdif_get_mask
1193};
1194
1195static snd_kcontrol_new_t snd_emu10k1x_spdif_control =
1196{
1197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1198 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
1199 .count = 3,
1200 .info = snd_emu10k1x_spdif_info,
1201 .get = snd_emu10k1x_spdif_get,
1202 .put = snd_emu10k1x_spdif_put
1203};
1204
1205static int __devinit snd_emu10k1x_mixer(emu10k1x_t *emu)
1206{
1207 int err;
1208 snd_kcontrol_t *kctl;
1209 snd_card_t *card = emu->card;
1210
1211 if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu)) == NULL)
1212 return -ENOMEM;
1213 if ((err = snd_ctl_add(card, kctl)))
1214 return err;
1215 if ((kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu)) == NULL)
1216 return -ENOMEM;
1217 if ((err = snd_ctl_add(card, kctl)))
1218 return err;
1219 if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu)) == NULL)
1220 return -ENOMEM;
1221 if ((err = snd_ctl_add(card, kctl)))
1222 return err;
1223
1224 return 0;
1225}
1226
1227#define EMU10K1X_MIDI_MODE_INPUT (1<<0)
1228#define EMU10K1X_MIDI_MODE_OUTPUT (1<<1)
1229
1230static inline unsigned char mpu401_read(emu10k1x_t *emu, emu10k1x_midi_t *mpu, int idx)
1231{
1232 return (unsigned char)snd_emu10k1x_ptr_read(emu, mpu->port + idx, 0);
1233}
1234
1235static inline void mpu401_write(emu10k1x_t *emu, emu10k1x_midi_t *mpu, int data, int idx)
1236{
1237 snd_emu10k1x_ptr_write(emu, mpu->port + idx, 0, data);
1238}
1239
1240#define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0)
1241#define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1)
1242#define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0)
1243#define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1)
1244
1245#define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80))
1246#define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40))
1247
1248#define MPU401_RESET 0xff
1249#define MPU401_ENTER_UART 0x3f
1250#define MPU401_ACK 0xfe
1251
1252static void mpu401_clear_rx(emu10k1x_t *emu, emu10k1x_midi_t *mpu)
1253{
1254 int timeout = 100000;
1255 for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
1256 mpu401_read_data(emu, mpu);
1257#ifdef CONFIG_SND_DEBUG
1258 if (timeout <= 0)
1259 snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n", mpu401_read_stat(emu, mpu));
1260#endif
1261}
1262
1263/*
1264
1265 */
1266
1267static void do_emu10k1x_midi_interrupt(emu10k1x_t *emu, emu10k1x_midi_t *midi, unsigned int status)
1268{
1269 unsigned char byte;
1270
1271 if (midi->rmidi == NULL) {
1272 snd_emu10k1x_intr_disable(emu, midi->tx_enable | midi->rx_enable);
1273 return;
1274 }
1275
1276 spin_lock(&midi->input_lock);
1277 if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
1278 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
1279 mpu401_clear_rx(emu, midi);
1280 } else {
1281 byte = mpu401_read_data(emu, midi);
1282 if (midi->substream_input)
1283 snd_rawmidi_receive(midi->substream_input, &byte, 1);
1284 }
1285 }
1286 spin_unlock(&midi->input_lock);
1287
1288 spin_lock(&midi->output_lock);
1289 if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
1290 if (midi->substream_output &&
1291 snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
1292 mpu401_write_data(emu, midi, byte);
1293 } else {
1294 snd_emu10k1x_intr_disable(emu, midi->tx_enable);
1295 }
1296 }
1297 spin_unlock(&midi->output_lock);
1298}
1299
1300static void snd_emu10k1x_midi_interrupt(emu10k1x_t *emu, unsigned int status)
1301{
1302 do_emu10k1x_midi_interrupt(emu, &emu->midi, status);
1303}
1304
1305static void snd_emu10k1x_midi_cmd(emu10k1x_t * emu, emu10k1x_midi_t *midi, unsigned char cmd, int ack)
1306{
1307 unsigned long flags;
1308 int timeout, ok;
1309
1310 spin_lock_irqsave(&midi->input_lock, flags);
1311 mpu401_write_data(emu, midi, 0x00);
1312 /* mpu401_clear_rx(emu, midi); */
1313
1314 mpu401_write_cmd(emu, midi, cmd);
1315 if (ack) {
1316 ok = 0;
1317 timeout = 10000;
1318 while (!ok && timeout-- > 0) {
1319 if (mpu401_input_avail(emu, midi)) {
1320 if (mpu401_read_data(emu, midi) == MPU401_ACK)
1321 ok = 1;
1322 }
1323 }
1324 if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
1325 ok = 1;
1326 } else {
1327 ok = 1;
1328 }
1329 spin_unlock_irqrestore(&midi->input_lock, flags);
1330 if (!ok)
1331 snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
1332 cmd, emu->port,
1333 mpu401_read_stat(emu, midi),
1334 mpu401_read_data(emu, midi));
1335}
1336
1337static int snd_emu10k1x_midi_input_open(snd_rawmidi_substream_t * substream)
1338{
1339 emu10k1x_t *emu;
1340 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1341 unsigned long flags;
1342
1343 emu = midi->emu;
1344 snd_assert(emu, return -ENXIO);
1345 spin_lock_irqsave(&midi->open_lock, flags);
1346 midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT;
1347 midi->substream_input = substream;
1348 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
1349 spin_unlock_irqrestore(&midi->open_lock, flags);
1350 snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1);
1351 snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
1352 } else {
1353 spin_unlock_irqrestore(&midi->open_lock, flags);
1354 }
1355 return 0;
1356}
1357
1358static int snd_emu10k1x_midi_output_open(snd_rawmidi_substream_t * substream)
1359{
1360 emu10k1x_t *emu;
1361 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1362 unsigned long flags;
1363
1364 emu = midi->emu;
1365 snd_assert(emu, return -ENXIO);
1366 spin_lock_irqsave(&midi->open_lock, flags);
1367 midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT;
1368 midi->substream_output = substream;
1369 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
1370 spin_unlock_irqrestore(&midi->open_lock, flags);
1371 snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 1);
1372 snd_emu10k1x_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
1373 } else {
1374 spin_unlock_irqrestore(&midi->open_lock, flags);
1375 }
1376 return 0;
1377}
1378
1379static int snd_emu10k1x_midi_input_close(snd_rawmidi_substream_t * substream)
1380{
1381 emu10k1x_t *emu;
1382 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1383 unsigned long flags;
1384
1385 emu = midi->emu;
1386 snd_assert(emu, return -ENXIO);
1387 spin_lock_irqsave(&midi->open_lock, flags);
1388 snd_emu10k1x_intr_disable(emu, midi->rx_enable);
1389 midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT;
1390 midi->substream_input = NULL;
1391 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT)) {
1392 spin_unlock_irqrestore(&midi->open_lock, flags);
1393 snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
1394 } else {
1395 spin_unlock_irqrestore(&midi->open_lock, flags);
1396 }
1397 return 0;
1398}
1399
1400static int snd_emu10k1x_midi_output_close(snd_rawmidi_substream_t * substream)
1401{
1402 emu10k1x_t *emu;
1403 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1404 unsigned long flags;
1405
1406 emu = midi->emu;
1407 snd_assert(emu, return -ENXIO);
1408 spin_lock_irqsave(&midi->open_lock, flags);
1409 snd_emu10k1x_intr_disable(emu, midi->tx_enable);
1410 midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT;
1411 midi->substream_output = NULL;
1412 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_INPUT)) {
1413 spin_unlock_irqrestore(&midi->open_lock, flags);
1414 snd_emu10k1x_midi_cmd(emu, midi, MPU401_RESET, 0);
1415 } else {
1416 spin_unlock_irqrestore(&midi->open_lock, flags);
1417 }
1418 return 0;
1419}
1420
1421static void snd_emu10k1x_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
1422{
1423 emu10k1x_t *emu;
1424 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1425 emu = midi->emu;
1426 snd_assert(emu, return);
1427
1428 if (up)
1429 snd_emu10k1x_intr_enable(emu, midi->rx_enable);
1430 else
1431 snd_emu10k1x_intr_disable(emu, midi->rx_enable);
1432}
1433
1434static void snd_emu10k1x_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
1435{
1436 emu10k1x_t *emu;
1437 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
1438 unsigned long flags;
1439
1440 emu = midi->emu;
1441 snd_assert(emu, return);
1442
1443 if (up) {
1444 int max = 4;
1445 unsigned char byte;
1446
1447 /* try to send some amount of bytes here before interrupts */
1448 spin_lock_irqsave(&midi->output_lock, flags);
1449 while (max > 0) {
1450 if (mpu401_output_ready(emu, midi)) {
1451 if (!(midi->midi_mode & EMU10K1X_MIDI_MODE_OUTPUT) ||
1452 snd_rawmidi_transmit(substream, &byte, 1) != 1) {
1453 /* no more data */
1454 spin_unlock_irqrestore(&midi->output_lock, flags);
1455 return;
1456 }
1457 mpu401_write_data(emu, midi, byte);
1458 max--;
1459 } else {
1460 break;
1461 }
1462 }
1463 spin_unlock_irqrestore(&midi->output_lock, flags);
1464 snd_emu10k1x_intr_enable(emu, midi->tx_enable);
1465 } else {
1466 snd_emu10k1x_intr_disable(emu, midi->tx_enable);
1467 }
1468}
1469
1470/*
1471
1472 */
1473
1474static snd_rawmidi_ops_t snd_emu10k1x_midi_output =
1475{
1476 .open = snd_emu10k1x_midi_output_open,
1477 .close = snd_emu10k1x_midi_output_close,
1478 .trigger = snd_emu10k1x_midi_output_trigger,
1479};
1480
1481static snd_rawmidi_ops_t snd_emu10k1x_midi_input =
1482{
1483 .open = snd_emu10k1x_midi_input_open,
1484 .close = snd_emu10k1x_midi_input_close,
1485 .trigger = snd_emu10k1x_midi_input_trigger,
1486};
1487
1488static void snd_emu10k1x_midi_free(snd_rawmidi_t *rmidi)
1489{
1490 emu10k1x_midi_t *midi = (emu10k1x_midi_t *)rmidi->private_data;
1491 midi->interrupt = NULL;
1492 midi->rmidi = NULL;
1493}
1494
1495static int __devinit emu10k1x_midi_init(emu10k1x_t *emu, emu10k1x_midi_t *midi, int device, char *name)
1496{
1497 snd_rawmidi_t *rmidi;
1498 int err;
1499
1500 if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
1501 return err;
1502 midi->emu = emu;
1503 spin_lock_init(&midi->open_lock);
1504 spin_lock_init(&midi->input_lock);
1505 spin_lock_init(&midi->output_lock);
1506 strcpy(rmidi->name, name);
1507 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1x_midi_output);
1508 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1x_midi_input);
1509 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
1510 SNDRV_RAWMIDI_INFO_INPUT |
1511 SNDRV_RAWMIDI_INFO_DUPLEX;
1512 rmidi->private_data = midi;
1513 rmidi->private_free = snd_emu10k1x_midi_free;
1514 midi->rmidi = rmidi;
1515 return 0;
1516}
1517
1518static int __devinit snd_emu10k1x_midi(emu10k1x_t *emu)
1519{
1520 emu10k1x_midi_t *midi = &emu->midi;
1521 int err;
1522
1523 if ((err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)")) < 0)
1524 return err;
1525
1526 midi->tx_enable = INTE_MIDITXENABLE;
1527 midi->rx_enable = INTE_MIDIRXENABLE;
1528 midi->port = MUDATA;
1529 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
1530 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
1531 midi->interrupt = snd_emu10k1x_midi_interrupt;
1532 return 0;
1533}
1534
1535static int __devinit snd_emu10k1x_probe(struct pci_dev *pci,
1536 const struct pci_device_id *pci_id)
1537{
1538 static int dev;
1539 snd_card_t *card;
1540 emu10k1x_t *chip;
1541 int err;
1542
1543 if (dev >= SNDRV_CARDS)
1544 return -ENODEV;
1545 if (!enable[dev]) {
1546 dev++;
1547 return -ENOENT;
1548 }
1549
1550 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1551 if (card == NULL)
1552 return -ENOMEM;
1553
1554 if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) {
1555 snd_card_free(card);
1556 return err;
1557 }
1558
1559 if ((err = snd_emu10k1x_pcm(chip, 0, NULL)) < 0) {
1560 snd_card_free(card);
1561 return err;
1562 }
1563 if ((err = snd_emu10k1x_pcm(chip, 1, NULL)) < 0) {
1564 snd_card_free(card);
1565 return err;
1566 }
1567 if ((err = snd_emu10k1x_pcm(chip, 2, NULL)) < 0) {
1568 snd_card_free(card);
1569 return err;
1570 }
1571
1572 if ((err = snd_emu10k1x_ac97(chip)) < 0) {
1573 snd_card_free(card);
1574 return err;
1575 }
1576
1577 if ((err = snd_emu10k1x_mixer(chip)) < 0) {
1578 snd_card_free(card);
1579 return err;
1580 }
1581
1582 if ((err = snd_emu10k1x_midi(chip)) < 0) {
1583 snd_card_free(card);
1584 return err;
1585 }
1586
1587 snd_emu10k1x_proc_init(chip);
1588
1589 strcpy(card->driver, "EMU10K1X");
1590 strcpy(card->shortname, "Dell Sound Blaster Live!");
1591 sprintf(card->longname, "%s at 0x%lx irq %i",
1592 card->shortname, chip->port, chip->irq);
1593
1594 if ((err = snd_card_register(card)) < 0) {
1595 snd_card_free(card);
1596 return err;
1597 }
1598
1599 pci_set_drvdata(pci, card);
1600 dev++;
1601 return 0;
1602}
1603
1604static void __devexit snd_emu10k1x_remove(struct pci_dev *pci)
1605{
1606 snd_card_free(pci_get_drvdata(pci));
1607 pci_set_drvdata(pci, NULL);
1608}
1609
1610// PCI IDs
1611static struct pci_device_id snd_emu10k1x_ids[] = {
1612 { 0x1102, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dell OEM version (EMU10K1) */
1613 { 0, }
1614};
1615MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
1616
1617// pci_driver definition
1618static struct pci_driver driver = {
1619 .name = "EMU10K1X",
1620 .id_table = snd_emu10k1x_ids,
1621 .probe = snd_emu10k1x_probe,
1622 .remove = __devexit_p(snd_emu10k1x_remove),
1623};
1624
1625// initialization of the module
1626static int __init alsa_card_emu10k1x_init(void)
1627{
1628 int err;
1629
1630 if ((err = pci_module_init(&driver)) > 0)
1631 return err;
1632
1633 return 0;
1634}
1635
1636// clean up the module
1637static void __exit alsa_card_emu10k1x_exit(void)
1638{
1639 pci_unregister_driver(&driver);
1640}
1641
1642module_init(alsa_card_emu10k1x_init)
1643module_exit(alsa_card_emu10k1x_exit)
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
new file mode 100644
index 000000000000..b9fa2e887fee
--- /dev/null
+++ b/sound/pci/emu10k1/emufx.c
@@ -0,0 +1,2320 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for effect processor FX8010
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/pci.h>
30#include <linux/delay.h>
31#include <linux/slab.h>
32#include <linux/init.h>
33#include <sound/core.h>
34#include <sound/emu10k1.h>
35
36#if 0 /* for testing purposes - digital out -> capture */
37#define EMU10K1_CAPTURE_DIGITAL_OUT
38#endif
39#if 0 /* for testing purposes - set S/PDIF to AC3 output */
40#define EMU10K1_SET_AC3_IEC958
41#endif
42#if 0 /* for testing purposes - feed the front signal to Center/LFE outputs */
43#define EMU10K1_CENTER_LFE_FROM_FRONT
44#endif
45
46/*
47 * Tables
48 */
49
50static char *fxbuses[16] = {
51 /* 0x00 */ "PCM Left",
52 /* 0x01 */ "PCM Right",
53 /* 0x02 */ "PCM Surround Left",
54 /* 0x03 */ "PCM Surround Right",
55 /* 0x04 */ "MIDI Left",
56 /* 0x05 */ "MIDI Right",
57 /* 0x06 */ "Center",
58 /* 0x07 */ "LFE",
59 /* 0x08 */ NULL,
60 /* 0x09 */ NULL,
61 /* 0x0a */ NULL,
62 /* 0x0b */ NULL,
63 /* 0x0c */ "MIDI Reverb",
64 /* 0x0d */ "MIDI Chorus",
65 /* 0x0e */ NULL,
66 /* 0x0f */ NULL
67};
68
69static char *creative_ins[16] = {
70 /* 0x00 */ "AC97 Left",
71 /* 0x01 */ "AC97 Right",
72 /* 0x02 */ "TTL IEC958 Left",
73 /* 0x03 */ "TTL IEC958 Right",
74 /* 0x04 */ "Zoom Video Left",
75 /* 0x05 */ "Zoom Video Right",
76 /* 0x06 */ "Optical IEC958 Left",
77 /* 0x07 */ "Optical IEC958 Right",
78 /* 0x08 */ "Line/Mic 1 Left",
79 /* 0x09 */ "Line/Mic 1 Right",
80 /* 0x0a */ "Coaxial IEC958 Left",
81 /* 0x0b */ "Coaxial IEC958 Right",
82 /* 0x0c */ "Line/Mic 2 Left",
83 /* 0x0d */ "Line/Mic 2 Right",
84 /* 0x0e */ NULL,
85 /* 0x0f */ NULL
86};
87
88static char *audigy_ins[16] = {
89 /* 0x00 */ "AC97 Left",
90 /* 0x01 */ "AC97 Right",
91 /* 0x02 */ "Audigy CD Left",
92 /* 0x03 */ "Audigy CD Right",
93 /* 0x04 */ "Optical IEC958 Left",
94 /* 0x05 */ "Optical IEC958 Right",
95 /* 0x06 */ NULL,
96 /* 0x07 */ NULL,
97 /* 0x08 */ "Line/Mic 2 Left",
98 /* 0x09 */ "Line/Mic 2 Right",
99 /* 0x0a */ "SPDIF Left",
100 /* 0x0b */ "SPDIF Right",
101 /* 0x0c */ "Aux2 Left",
102 /* 0x0d */ "Aux2 Right",
103 /* 0x0e */ NULL,
104 /* 0x0f */ NULL
105};
106
107static char *creative_outs[32] = {
108 /* 0x00 */ "AC97 Left",
109 /* 0x01 */ "AC97 Right",
110 /* 0x02 */ "Optical IEC958 Left",
111 /* 0x03 */ "Optical IEC958 Right",
112 /* 0x04 */ "Center",
113 /* 0x05 */ "LFE",
114 /* 0x06 */ "Headphone Left",
115 /* 0x07 */ "Headphone Right",
116 /* 0x08 */ "Surround Left",
117 /* 0x09 */ "Surround Right",
118 /* 0x0a */ "PCM Capture Left",
119 /* 0x0b */ "PCM Capture Right",
120 /* 0x0c */ "MIC Capture",
121 /* 0x0d */ "AC97 Surround Left",
122 /* 0x0e */ "AC97 Surround Right",
123 /* 0x0f */ NULL,
124 /* 0x10 */ NULL,
125 /* 0x11 */ "Analog Center",
126 /* 0x12 */ "Analog LFE",
127 /* 0x13 */ NULL,
128 /* 0x14 */ NULL,
129 /* 0x15 */ NULL,
130 /* 0x16 */ NULL,
131 /* 0x17 */ NULL,
132 /* 0x18 */ NULL,
133 /* 0x19 */ NULL,
134 /* 0x1a */ NULL,
135 /* 0x1b */ NULL,
136 /* 0x1c */ NULL,
137 /* 0x1d */ NULL,
138 /* 0x1e */ NULL,
139 /* 0x1f */ NULL,
140};
141
142static char *audigy_outs[32] = {
143 /* 0x00 */ "Digital Front Left",
144 /* 0x01 */ "Digital Front Right",
145 /* 0x02 */ "Digital Center",
146 /* 0x03 */ "Digital LEF",
147 /* 0x04 */ "Headphone Left",
148 /* 0x05 */ "Headphone Right",
149 /* 0x06 */ "Digital Rear Left",
150 /* 0x07 */ "Digital Rear Right",
151 /* 0x08 */ "Front Left",
152 /* 0x09 */ "Front Right",
153 /* 0x0a */ "Center",
154 /* 0x0b */ "LFE",
155 /* 0x0c */ NULL,
156 /* 0x0d */ NULL,
157 /* 0x0e */ "Rear Left",
158 /* 0x0f */ "Rear Right",
159 /* 0x10 */ "AC97 Front Left",
160 /* 0x11 */ "AC97 Front Right",
161 /* 0x12 */ "ADC Caputre Left",
162 /* 0x13 */ "ADC Capture Right",
163 /* 0x14 */ NULL,
164 /* 0x15 */ NULL,
165 /* 0x16 */ NULL,
166 /* 0x17 */ NULL,
167 /* 0x18 */ NULL,
168 /* 0x19 */ NULL,
169 /* 0x1a */ NULL,
170 /* 0x1b */ NULL,
171 /* 0x1c */ NULL,
172 /* 0x1d */ NULL,
173 /* 0x1e */ NULL,
174 /* 0x1f */ NULL,
175};
176
177static const u32 bass_table[41][5] = {
178 { 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
179 { 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
180 { 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
181 { 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
182 { 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
183 { 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
184 { 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
185 { 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
186 { 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
187 { 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
188 { 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
189 { 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
190 { 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
191 { 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
192 { 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
193 { 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
194 { 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
195 { 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
196 { 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
197 { 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
198 { 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
199 { 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
200 { 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
201 { 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
202 { 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
203 { 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
204 { 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
205 { 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
206 { 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
207 { 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
208 { 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
209 { 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
210 { 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
211 { 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
212 { 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
213 { 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
214 { 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
215 { 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
216 { 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
217 { 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
218 { 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
219};
220
221static const u32 treble_table[41][5] = {
222 { 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
223 { 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
224 { 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
225 { 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
226 { 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
227 { 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
228 { 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
229 { 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
230 { 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
231 { 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
232 { 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
233 { 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
234 { 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
235 { 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
236 { 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
237 { 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
238 { 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
239 { 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
240 { 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
241 { 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
242 { 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
243 { 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
244 { 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
245 { 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
246 { 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
247 { 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
248 { 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
249 { 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
250 { 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
251 { 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
252 { 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
253 { 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
254 { 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
255 { 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
256 { 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
257 { 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
258 { 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
259 { 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
260 { 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
261 { 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
262 { 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
263};
264
265static const u32 db_table[101] = {
266 0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
267 0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
268 0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
269 0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
270 0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
271 0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
272 0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
273 0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
274 0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
275 0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
276 0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
277 0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
278 0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
279 0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
280 0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
281 0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
282 0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
283 0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
284 0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
285 0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
286 0x7fffffff,
287};
288
289static const u32 onoff_table[2] = {
290 0x00000000, 0x00000001
291};
292
293/*
294 */
295
296static inline mm_segment_t snd_enter_user(void)
297{
298 mm_segment_t fs = get_fs();
299 set_fs(get_ds());
300 return fs;
301}
302
303static inline void snd_leave_user(mm_segment_t fs)
304{
305 set_fs(fs);
306}
307
308/*
309 * controls
310 */
311
312static int snd_emu10k1_gpr_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
313{
314 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
315
316 if (ctl->min == 0 && ctl->max == 1)
317 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
318 else
319 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
320 uinfo->count = ctl->vcount;
321 uinfo->value.integer.min = ctl->min;
322 uinfo->value.integer.max = ctl->max;
323 return 0;
324}
325
326static int snd_emu10k1_gpr_ctl_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
327{
328 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
329 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
330 unsigned long flags;
331 unsigned int i;
332
333 spin_lock_irqsave(&emu->reg_lock, flags);
334 for (i = 0; i < ctl->vcount; i++)
335 ucontrol->value.integer.value[i] = ctl->value[i];
336 spin_unlock_irqrestore(&emu->reg_lock, flags);
337 return 0;
338}
339
340static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
341{
342 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
343 snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
344 unsigned long flags;
345 unsigned int nval, val;
346 unsigned int i, j;
347 int change = 0;
348
349 spin_lock_irqsave(&emu->reg_lock, flags);
350 for (i = 0; i < ctl->vcount; i++) {
351 nval = ucontrol->value.integer.value[i];
352 if (nval < ctl->min)
353 nval = ctl->min;
354 if (nval > ctl->max)
355 nval = ctl->max;
356 if (nval != ctl->value[i])
357 change = 1;
358 val = ctl->value[i] = nval;
359 switch (ctl->translation) {
360 case EMU10K1_GPR_TRANSLATION_NONE:
361 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, val);
362 break;
363 case EMU10K1_GPR_TRANSLATION_TABLE100:
364 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, db_table[val]);
365 break;
366 case EMU10K1_GPR_TRANSLATION_BASS:
367 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
368 for (j = 0; j < 5; j++)
369 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, bass_table[val][j]);
370 break;
371 case EMU10K1_GPR_TRANSLATION_TREBLE:
372 snd_runtime_check((ctl->count % 5) == 0 && (ctl->count / 5) == ctl->vcount, change = -EIO; goto __error);
373 for (j = 0; j < 5; j++)
374 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[j * ctl->vcount + i], 0, treble_table[val][j]);
375 break;
376 case EMU10K1_GPR_TRANSLATION_ONOFF:
377 snd_emu10k1_ptr_write(emu, emu->gpr_base + ctl->gpr[i], 0, onoff_table[val]);
378 break;
379 }
380 }
381 __error:
382 spin_unlock_irqrestore(&emu->reg_lock, flags);
383 return change;
384}
385
386/*
387 * Interrupt handler
388 */
389
390static void snd_emu10k1_fx8010_interrupt(emu10k1_t *emu)
391{
392 snd_emu10k1_fx8010_irq_t *irq, *nirq;
393
394 irq = emu->fx8010.irq_handlers;
395 while (irq) {
396 nirq = irq->next; /* irq ptr can be removed from list */
397 if (snd_emu10k1_ptr_read(emu, emu->gpr_base + irq->gpr_running, 0) & 0xffff0000) {
398 if (irq->handler)
399 irq->handler(emu, irq->private_data);
400 snd_emu10k1_ptr_write(emu, emu->gpr_base + irq->gpr_running, 0, 1);
401 }
402 irq = nirq;
403 }
404}
405
406int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
407 snd_fx8010_irq_handler_t *handler,
408 unsigned char gpr_running,
409 void *private_data,
410 snd_emu10k1_fx8010_irq_t **r_irq)
411{
412 snd_emu10k1_fx8010_irq_t *irq;
413 unsigned long flags;
414
415 snd_runtime_check(emu, return -EINVAL);
416 snd_runtime_check(handler, return -EINVAL);
417 irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
418 if (irq == NULL)
419 return -ENOMEM;
420 irq->handler = handler;
421 irq->gpr_running = gpr_running;
422 irq->private_data = private_data;
423 irq->next = NULL;
424 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
425 if (emu->fx8010.irq_handlers == NULL) {
426 emu->fx8010.irq_handlers = irq;
427 emu->dsp_interrupt = snd_emu10k1_fx8010_interrupt;
428 snd_emu10k1_intr_enable(emu, INTE_FXDSPENABLE);
429 } else {
430 irq->next = emu->fx8010.irq_handlers;
431 emu->fx8010.irq_handlers = irq;
432 }
433 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
434 if (r_irq)
435 *r_irq = irq;
436 return 0;
437}
438
439int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
440 snd_emu10k1_fx8010_irq_t *irq)
441{
442 snd_emu10k1_fx8010_irq_t *tmp;
443 unsigned long flags;
444
445 snd_runtime_check(irq, return -EINVAL);
446 spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
447 if ((tmp = emu->fx8010.irq_handlers) == irq) {
448 emu->fx8010.irq_handlers = tmp->next;
449 if (emu->fx8010.irq_handlers == NULL) {
450 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
451 emu->dsp_interrupt = NULL;
452 }
453 } else {
454 while (tmp && tmp->next != irq)
455 tmp = tmp->next;
456 if (tmp)
457 tmp->next = tmp->next->next;
458 }
459 spin_unlock_irqrestore(&emu->fx8010.irq_lock, flags);
460 kfree(irq);
461 return 0;
462}
463
464/*************************************************************************
465 * EMU10K1 effect manager
466 *************************************************************************/
467
468static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
469 u32 op, u32 r, u32 a, u32 x, u32 y)
470{
471 u_int32_t *code;
472 snd_assert(*ptr < 512, return);
473 code = (u_int32_t *)icode->code + (*ptr) * 2;
474 set_bit(*ptr, icode->code_valid);
475 code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
476 code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
477 (*ptr)++;
478}
479
480#define OP(icode, ptr, op, r, a, x, y) \
481 snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
482
483static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
484 u32 op, u32 r, u32 a, u32 x, u32 y)
485{
486 u_int32_t *code;
487 snd_assert(*ptr < 1024, return);
488 code = (u_int32_t *)icode->code + (*ptr) * 2;
489 set_bit(*ptr, icode->code_valid);
490 code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
491 code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
492 (*ptr)++;
493}
494
495#define A_OP(icode, ptr, op, r, a, x, y) \
496 snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
497
498static void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
499{
500 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
501 snd_emu10k1_ptr_write(emu, pc, 0, data);
502}
503
504unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc)
505{
506 pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
507 return snd_emu10k1_ptr_read(emu, pc, 0);
508}
509
510static int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
511{
512 int gpr;
513 u32 val;
514
515 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
516 if (!test_bit(gpr, icode->gpr_valid))
517 continue;
518 if (get_user(val, &icode->gpr_map[gpr]))
519 return -EFAULT;
520 snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
521 }
522 return 0;
523}
524
525static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
526{
527 int gpr;
528 u32 val;
529
530 for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
531 set_bit(gpr, icode->gpr_valid);
532 val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
533 if (put_user(val, &icode->gpr_map[gpr]))
534 return -EFAULT;
535 }
536 return 0;
537}
538
539static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
540{
541 int tram;
542 u32 addr, val;
543
544 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
545 if (!test_bit(tram, icode->tram_valid))
546 continue;
547 if (get_user(val, &icode->tram_data_map[tram]) ||
548 get_user(addr, &icode->tram_addr_map[tram]))
549 return -EFAULT;
550 snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
551 if (!emu->audigy) {
552 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr);
553 } else {
554 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + tram, 0, addr << 12);
555 snd_emu10k1_ptr_write(emu, A_TANKMEMCTLREGBASE + tram, 0, addr >> 20);
556 }
557 }
558 return 0;
559}
560
561static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
562{
563 int tram;
564 u32 val, addr;
565
566 memset(icode->tram_valid, 0, sizeof(icode->tram_valid));
567 for (tram = 0; tram < (emu->audigy ? 0x100 : 0xa0); tram++) {
568 set_bit(tram, icode->tram_valid);
569 val = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + tram, 0);
570 if (!emu->audigy) {
571 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0);
572 } else {
573 addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
574 addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
575 }
576 if (put_user(val, &icode->tram_data_map[tram]) ||
577 put_user(addr, &icode->tram_addr_map[tram]))
578 return -EFAULT;
579 }
580 return 0;
581}
582
583static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
584{
585 u32 pc, lo, hi;
586
587 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
588 if (!test_bit(pc / 2, icode->code_valid))
589 continue;
590 if (get_user(lo, &icode->code[pc + 0]) ||
591 get_user(hi, &icode->code[pc + 1]))
592 return -EFAULT;
593 snd_emu10k1_efx_write(emu, pc + 0, lo);
594 snd_emu10k1_efx_write(emu, pc + 1, hi);
595 }
596 return 0;
597}
598
599static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
600{
601 u32 pc;
602
603 memset(icode->code_valid, 0, sizeof(icode->code_valid));
604 for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
605 set_bit(pc / 2, icode->code_valid);
606 if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
607 return -EFAULT;
608 if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
609 return -EFAULT;
610 }
611 return 0;
612}
613
614static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
615{
616 snd_emu10k1_fx8010_ctl_t *ctl;
617 snd_kcontrol_t *kcontrol;
618 struct list_head *list;
619
620 list_for_each(list, &emu->fx8010.gpr_ctl) {
621 ctl = emu10k1_gpr_ctl(list);
622 kcontrol = ctl->kcontrol;
623 if (kcontrol->id.iface == id->iface &&
624 !strcmp(kcontrol->id.name, id->name) &&
625 kcontrol->id.index == id->index)
626 return ctl;
627 }
628 return NULL;
629}
630
631static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
632{
633 unsigned int i;
634 snd_ctl_elem_id_t __user *_id;
635 snd_ctl_elem_id_t id;
636 emu10k1_fx8010_control_gpr_t __user *_gctl;
637 emu10k1_fx8010_control_gpr_t *gctl;
638 int err;
639
640 for (i = 0, _id = icode->gpr_del_controls;
641 i < icode->gpr_del_control_count; i++, _id++) {
642 if (copy_from_user(&id, _id, sizeof(id)))
643 return -EFAULT;
644 if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
645 return -ENOENT;
646 }
647 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
648 if (! gctl)
649 return -ENOMEM;
650 err = 0;
651 for (i = 0, _gctl = icode->gpr_add_controls;
652 i < icode->gpr_add_control_count; i++, _gctl++) {
653 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
654 err = -EFAULT;
655 goto __error;
656 }
657 if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
658 continue;
659 down_read(&emu->card->controls_rwsem);
660 if (snd_ctl_find_id(emu->card, &gctl->id) != NULL) {
661 up_read(&emu->card->controls_rwsem);
662 err = -EEXIST;
663 goto __error;
664 }
665 up_read(&emu->card->controls_rwsem);
666 if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
667 gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
668 err = -EINVAL;
669 goto __error;
670 }
671 }
672 for (i = 0, _gctl = icode->gpr_list_controls;
673 i < icode->gpr_list_control_count; i++, _gctl++) {
674 /* FIXME: we need to check the WRITE access */
675 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
676 err = -EFAULT;
677 goto __error;
678 }
679 }
680 __error:
681 kfree(gctl);
682 return err;
683}
684
685static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
686{
687 snd_emu10k1_fx8010_ctl_t *ctl;
688
689 ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
690 kctl->private_value = 0;
691 list_del(&ctl->list);
692 kfree(ctl);
693}
694
695static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
696{
697 unsigned int i, j;
698 emu10k1_fx8010_control_gpr_t __user *_gctl;
699 emu10k1_fx8010_control_gpr_t *gctl;
700 snd_emu10k1_fx8010_ctl_t *ctl, *nctl;
701 snd_kcontrol_new_t knew;
702 snd_kcontrol_t *kctl;
703 snd_ctl_elem_value_t *val;
704 int err = 0;
705
706 val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
707 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
708 nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
709 if (!val || !gctl || !nctl) {
710 err = -ENOMEM;
711 goto __error;
712 }
713
714 for (i = 0, _gctl = icode->gpr_add_controls;
715 i < icode->gpr_add_control_count; i++, _gctl++) {
716 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
717 err = -EFAULT;
718 goto __error;
719 }
720 snd_runtime_check(gctl->id.iface == SNDRV_CTL_ELEM_IFACE_MIXER ||
721 gctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM, err = -EINVAL; goto __error);
722 snd_runtime_check(gctl->id.name[0] != '\0', err = -EINVAL; goto __error);
723 ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
724 memset(&knew, 0, sizeof(knew));
725 knew.iface = gctl->id.iface;
726 knew.name = gctl->id.name;
727 knew.index = gctl->id.index;
728 knew.device = gctl->id.device;
729 knew.subdevice = gctl->id.subdevice;
730 knew.info = snd_emu10k1_gpr_ctl_info;
731 knew.get = snd_emu10k1_gpr_ctl_get;
732 knew.put = snd_emu10k1_gpr_ctl_put;
733 memset(nctl, 0, sizeof(*nctl));
734 nctl->vcount = gctl->vcount;
735 nctl->count = gctl->count;
736 for (j = 0; j < 32; j++) {
737 nctl->gpr[j] = gctl->gpr[j];
738 nctl->value[j] = ~gctl->value[j]; /* inverted, we want to write new value in gpr_ctl_put() */
739 val->value.integer.value[j] = gctl->value[j];
740 }
741 nctl->min = gctl->min;
742 nctl->max = gctl->max;
743 nctl->translation = gctl->translation;
744 if (ctl == NULL) {
745 ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
746 if (ctl == NULL) {
747 err = -ENOMEM;
748 goto __error;
749 }
750 knew.private_value = (unsigned long)ctl;
751 *ctl = *nctl;
752 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
753 kfree(ctl);
754 goto __error;
755 }
756 kctl->private_free = snd_emu10k1_ctl_private_free;
757 ctl->kcontrol = kctl;
758 list_add_tail(&ctl->list, &emu->fx8010.gpr_ctl);
759 } else {
760 /* overwrite */
761 nctl->list = ctl->list;
762 nctl->kcontrol = ctl->kcontrol;
763 *ctl = *nctl;
764 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
765 SNDRV_CTL_EVENT_MASK_INFO, &ctl->kcontrol->id);
766 }
767 snd_emu10k1_gpr_ctl_put(ctl->kcontrol, val);
768 }
769 __error:
770 kfree(nctl);
771 kfree(gctl);
772 kfree(val);
773 return err;
774}
775
776static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
777{
778 unsigned int i;
779 snd_ctl_elem_id_t id;
780 snd_ctl_elem_id_t __user *_id;
781 snd_emu10k1_fx8010_ctl_t *ctl;
782 snd_card_t *card = emu->card;
783
784 for (i = 0, _id = icode->gpr_del_controls;
785 i < icode->gpr_del_control_count; i++, _id++) {
786 snd_runtime_check(copy_from_user(&id, _id, sizeof(id)) == 0, return -EFAULT);
787 down_write(&card->controls_rwsem);
788 ctl = snd_emu10k1_look_for_ctl(emu, &id);
789 if (ctl)
790 snd_ctl_remove(card, ctl->kcontrol);
791 up_write(&card->controls_rwsem);
792 }
793 return 0;
794}
795
796static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
797{
798 unsigned int i = 0, j;
799 unsigned int total = 0;
800 emu10k1_fx8010_control_gpr_t *gctl;
801 emu10k1_fx8010_control_gpr_t __user *_gctl;
802 snd_emu10k1_fx8010_ctl_t *ctl;
803 snd_ctl_elem_id_t *id;
804 struct list_head *list;
805
806 gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
807 if (! gctl)
808 return -ENOMEM;
809
810 _gctl = icode->gpr_list_controls;
811 list_for_each(list, &emu->fx8010.gpr_ctl) {
812 ctl = emu10k1_gpr_ctl(list);
813 total++;
814 if (_gctl && i < icode->gpr_list_control_count) {
815 memset(gctl, 0, sizeof(*gctl));
816 id = &ctl->kcontrol->id;
817 gctl->id.iface = id->iface;
818 strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
819 gctl->id.index = id->index;
820 gctl->id.device = id->device;
821 gctl->id.subdevice = id->subdevice;
822 gctl->vcount = ctl->vcount;
823 gctl->count = ctl->count;
824 for (j = 0; j < 32; j++) {
825 gctl->gpr[j] = ctl->gpr[j];
826 gctl->value[j] = ctl->value[j];
827 }
828 gctl->min = ctl->min;
829 gctl->max = ctl->max;
830 gctl->translation = ctl->translation;
831 if (copy_to_user(_gctl, gctl, sizeof(*gctl))) {
832 kfree(gctl);
833 return -EFAULT;
834 }
835 _gctl++;
836 i++;
837 }
838 }
839 icode->gpr_list_control_total = total;
840 kfree(gctl);
841 return 0;
842}
843
844static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
845{
846 int err = 0;
847
848 down(&emu->fx8010.lock);
849 if ((err = snd_emu10k1_verify_controls(emu, icode)) < 0)
850 goto __error;
851 strlcpy(emu->fx8010.name, icode->name, sizeof(emu->fx8010.name));
852 /* stop FX processor - this may be dangerous, but it's better to miss
853 some samples than generate wrong ones - [jk] */
854 if (emu->audigy)
855 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
856 else
857 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
858 /* ok, do the main job */
859 if ((err = snd_emu10k1_del_controls(emu, icode)) < 0 ||
860 (err = snd_emu10k1_gpr_poke(emu, icode)) < 0 ||
861 (err = snd_emu10k1_tram_poke(emu, icode)) < 0 ||
862 (err = snd_emu10k1_code_poke(emu, icode)) < 0 ||
863 (err = snd_emu10k1_add_controls(emu, icode)) < 0)
864 goto __error;
865 /* start FX processor when the DSP code is updated */
866 if (emu->audigy)
867 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
868 else
869 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
870 __error:
871 up(&emu->fx8010.lock);
872 return err;
873}
874
875static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
876{
877 int err;
878
879 down(&emu->fx8010.lock);
880 strlcpy(icode->name, emu->fx8010.name, sizeof(icode->name));
881 /* ok, do the main job */
882 err = snd_emu10k1_gpr_peek(emu, icode);
883 if (err >= 0)
884 err = snd_emu10k1_tram_peek(emu, icode);
885 if (err >= 0)
886 err = snd_emu10k1_code_peek(emu, icode);
887 if (err >= 0)
888 err = snd_emu10k1_list_controls(emu, icode);
889 up(&emu->fx8010.lock);
890 return err;
891}
892
893static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
894{
895 unsigned int i;
896 int err = 0;
897 snd_emu10k1_fx8010_pcm_t *pcm;
898
899 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
900 return -EINVAL;
901 if (ipcm->channels > 32)
902 return -EINVAL;
903 pcm = &emu->fx8010.pcm[ipcm->substream];
904 down(&emu->fx8010.lock);
905 spin_lock_irq(&emu->reg_lock);
906 if (pcm->opened) {
907 err = -EBUSY;
908 goto __error;
909 }
910 if (ipcm->channels == 0) { /* remove */
911 pcm->valid = 0;
912 } else {
913 /* FIXME: we need to add universal code to the PCM transfer routine */
914 if (ipcm->channels != 2) {
915 err = -EINVAL;
916 goto __error;
917 }
918 pcm->valid = 1;
919 pcm->opened = 0;
920 pcm->channels = ipcm->channels;
921 pcm->tram_start = ipcm->tram_start;
922 pcm->buffer_size = ipcm->buffer_size;
923 pcm->gpr_size = ipcm->gpr_size;
924 pcm->gpr_count = ipcm->gpr_count;
925 pcm->gpr_tmpcount = ipcm->gpr_tmpcount;
926 pcm->gpr_ptr = ipcm->gpr_ptr;
927 pcm->gpr_trigger = ipcm->gpr_trigger;
928 pcm->gpr_running = ipcm->gpr_running;
929 for (i = 0; i < pcm->channels; i++)
930 pcm->etram[i] = ipcm->etram[i];
931 }
932 __error:
933 spin_unlock_irq(&emu->reg_lock);
934 up(&emu->fx8010.lock);
935 return err;
936}
937
938static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
939{
940 unsigned int i;
941 int err = 0;
942 snd_emu10k1_fx8010_pcm_t *pcm;
943
944 if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
945 return -EINVAL;
946 pcm = &emu->fx8010.pcm[ipcm->substream];
947 down(&emu->fx8010.lock);
948 spin_lock_irq(&emu->reg_lock);
949 ipcm->channels = pcm->channels;
950 ipcm->tram_start = pcm->tram_start;
951 ipcm->buffer_size = pcm->buffer_size;
952 ipcm->gpr_size = pcm->gpr_size;
953 ipcm->gpr_ptr = pcm->gpr_ptr;
954 ipcm->gpr_count = pcm->gpr_count;
955 ipcm->gpr_tmpcount = pcm->gpr_tmpcount;
956 ipcm->gpr_trigger = pcm->gpr_trigger;
957 ipcm->gpr_running = pcm->gpr_running;
958 for (i = 0; i < pcm->channels; i++)
959 ipcm->etram[i] = pcm->etram[i];
960 ipcm->res1 = ipcm->res2 = 0;
961 ipcm->pad = 0;
962 spin_unlock_irq(&emu->reg_lock);
963 up(&emu->fx8010.lock);
964 return err;
965}
966
967#define SND_EMU10K1_GPR_CONTROLS 41
968#define SND_EMU10K1_INPUTS 10
969#define SND_EMU10K1_PLAYBACK_CHANNELS 8
970#define SND_EMU10K1_CAPTURE_CHANNELS 4
971
972static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
973{
974 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
975 strcpy(ctl->id.name, name);
976 ctl->vcount = ctl->count = 1;
977 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
978 ctl->min = 0;
979 ctl->max = 100;
980 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
981}
982
983static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
984{
985 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
986 strcpy(ctl->id.name, name);
987 ctl->vcount = ctl->count = 2;
988 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
989 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
990 ctl->min = 0;
991 ctl->max = 100;
992 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
993}
994
995static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
996{
997 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
998 strcpy(ctl->id.name, name);
999 ctl->vcount = ctl->count = 1;
1000 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1001 ctl->min = 0;
1002 ctl->max = 1;
1003 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1004}
1005
1006static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
1007{
1008 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1009 strcpy(ctl->id.name, name);
1010 ctl->vcount = ctl->count = 2;
1011 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1012 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1013 ctl->min = 0;
1014 ctl->max = 1;
1015 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1016}
1017
1018
1019/*
1020 * initial DSP configuration for Audigy
1021 */
1022
1023static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
1024{
1025 int err, i, z, gpr, nctl;
1026 const int playback = 10;
1027 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1028 const int stereo_mix = capture + 2;
1029 const int tmp = 0x88;
1030 u32 ptr;
1031 emu10k1_fx8010_code_t *icode = NULL;
1032 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1033 u32 *gpr_map;
1034 mm_segment_t seg;
1035
1036 spin_lock_init(&emu->fx8010.irq_lock);
1037 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1038
1039 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL ||
1040 (icode->gpr_map = (u_int32_t __user *)kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1041 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
1042 err = -ENOMEM;
1043 goto __err;
1044 }
1045 gpr_map = (u32 *)icode->gpr_map;
1046
1047 icode->tram_data_map = icode->gpr_map + 512;
1048 icode->tram_addr_map = icode->tram_data_map + 256;
1049 icode->code = icode->tram_addr_map + 256;
1050
1051 /* clear free GPRs */
1052 for (i = 0; i < 512; i++)
1053 set_bit(i, icode->gpr_valid);
1054
1055 /* clear TRAM data & address lines */
1056 for (i = 0; i < 256; i++)
1057 set_bit(i, icode->tram_valid);
1058
1059 strcpy(icode->name, "Audigy DSP code for ALSA");
1060 ptr = 0;
1061 nctl = 0;
1062 gpr = stereo_mix + 10;
1063
1064 /* stop FX processor */
1065 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1066
1067 /* PCM front Playback Volume (independent from stereo mix) */
1068 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
1069 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
1070 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Front Playback Volume", gpr, 100);
1071 gpr += 2;
1072
1073 /* PCM Surround Playback (independent from stereo mix) */
1074 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_REAR));
1075 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_REAR));
1076 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Surround Playback Volume", gpr, 100);
1077 gpr += 2;
1078
1079 /* PCM Side Playback (independent from stereo mix) */
1080 if (emu->spk71) {
1081 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
1082 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
1083 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
1084 gpr += 2;
1085 }
1086
1087 /* PCM Center Playback (independent from stereo mix) */
1088 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_CENTER));
1089 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM Center Playback Volume", gpr, 100);
1090 gpr++;
1091
1092 /* PCM LFE Playback (independent from stereo mix) */
1093 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LFE));
1094 snd_emu10k1_init_mono_control(&controls[nctl++], "PCM LFE Playback Volume", gpr, 100);
1095 gpr++;
1096
1097 /*
1098 * Stereo Mix
1099 */
1100 /* Wave (PCM) Playback Volume (will be renamed later) */
1101 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1102 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1103 snd_emu10k1_init_stereo_control(&controls[nctl++], "Wave Playback Volume", gpr, 100);
1104 gpr += 2;
1105
1106 /* Synth Playback */
1107 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+0), A_GPR(stereo_mix+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1108 A_OP(icode, &ptr, iMAC0, A_GPR(stereo_mix+1), A_GPR(stereo_mix+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1109 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Playback Volume", gpr, 100);
1110 gpr += 2;
1111
1112 /* Wave (PCM) Capture */
1113 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT));
1114 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT));
1115 snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Capture Volume", gpr, 0);
1116 gpr += 2;
1117
1118 /* Synth Capture */
1119 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_FXBUS(FXBUS_MIDI_LEFT));
1120 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1121 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1122 gpr += 2;
1123
1124 /*
1125 * inputs
1126 */
1127#define A_ADD_VOLUME_IN(var,vol,input) \
1128A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1129
1130 /* AC'97 Playback Volume - used only for mic (renamed later) */
1131 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1132 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
1133 snd_emu10k1_init_stereo_control(&controls[nctl++], "AMic Playback Volume", gpr, 0);
1134 gpr += 2;
1135 /* AC'97 Capture Volume - used only for mic */
1136 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AC97_L);
1137 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AC97_R);
1138 snd_emu10k1_init_stereo_control(&controls[nctl++], "Mic Capture Volume", gpr, 0);
1139 gpr += 2;
1140
1141 /* mic capture buffer */
1142 A_OP(icode, &ptr, iINTERP, A_EXTOUT(A_EXTOUT_MIC_CAP), A_EXTIN(A_EXTIN_AC97_L), 0xcd, A_EXTIN(A_EXTIN_AC97_R));
1143
1144 /* Audigy CD Playback Volume */
1145 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
1146 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1147 snd_emu10k1_init_stereo_control(&controls[nctl++],
1148 emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
1149 gpr, 0);
1150 gpr += 2;
1151 /* Audigy CD Capture Volume */
1152 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
1153 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
1154 snd_emu10k1_init_stereo_control(&controls[nctl++],
1155 emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
1156 gpr, 0);
1157 gpr += 2;
1158
1159 /* Optical SPDIF Playback Volume */
1160 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_OPT_SPDIF_L);
1161 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1162 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Playback Volume", gpr, 0);
1163 gpr += 2;
1164 /* Optical SPDIF Capture Volume */
1165 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_OPT_SPDIF_L);
1166 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_OPT_SPDIF_R);
1167 snd_emu10k1_init_stereo_control(&controls[nctl++], "IEC958 Optical Capture Volume", gpr, 0);
1168 gpr += 2;
1169
1170 /* Line2 Playback Volume */
1171 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
1172 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
1173 snd_emu10k1_init_stereo_control(&controls[nctl++],
1174 emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
1175 gpr, 0);
1176 gpr += 2;
1177 /* Line2 Capture Volume */
1178 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
1179 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
1180 snd_emu10k1_init_stereo_control(&controls[nctl++],
1181 emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
1182 gpr, 0);
1183 gpr += 2;
1184
1185 /* Philips ADC Playback Volume */
1186 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_ADC_L);
1187 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_ADC_R);
1188 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Playback Volume", gpr, 0);
1189 gpr += 2;
1190 /* Philips ADC Capture Volume */
1191 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_ADC_L);
1192 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_ADC_R);
1193 snd_emu10k1_init_stereo_control(&controls[nctl++], "Analog Mix Capture Volume", gpr, 0);
1194 gpr += 2;
1195
1196 /* Aux2 Playback Volume */
1197 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
1198 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
1199 snd_emu10k1_init_stereo_control(&controls[nctl++],
1200 emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
1201 gpr, 0);
1202 gpr += 2;
1203 /* Aux2 Capture Volume */
1204 A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
1205 A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
1206 snd_emu10k1_init_stereo_control(&controls[nctl++],
1207 emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
1208 gpr, 0);
1209 gpr += 2;
1210
1211 /* Stereo Mix Front Playback Volume */
1212 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_GPR(playback), A_GPR(gpr), A_GPR(stereo_mix));
1213 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_GPR(playback+1), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1214 snd_emu10k1_init_stereo_control(&controls[nctl++], "Front Playback Volume", gpr, 100);
1215 gpr += 2;
1216
1217 /* Stereo Mix Surround Playback */
1218 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2), A_GPR(playback+2), A_GPR(gpr), A_GPR(stereo_mix));
1219 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3), A_GPR(playback+3), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1220 snd_emu10k1_init_stereo_control(&controls[nctl++], "Surround Playback Volume", gpr, 0);
1221 gpr += 2;
1222
1223 /* Stereo Mix Center Playback */
1224 /* Center = sub = Left/2 + Right/2 */
1225 A_OP(icode, &ptr, iINTERP, A_GPR(tmp), A_GPR(stereo_mix), 0xcd, A_GPR(stereo_mix+1));
1226 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4), A_GPR(playback+4), A_GPR(gpr), A_GPR(tmp));
1227 snd_emu10k1_init_mono_control(&controls[nctl++], "Center Playback Volume", gpr, 0);
1228 gpr++;
1229
1230 /* Stereo Mix LFE Playback */
1231 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5), A_GPR(playback+5), A_GPR(gpr), A_GPR(tmp));
1232 snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
1233 gpr++;
1234
1235 if (emu->spk71) {
1236 /* Stereo Mix Side Playback */
1237 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
1238 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
1239 snd_emu10k1_init_stereo_control(&controls[nctl++], "Side Playback Volume", gpr, 0);
1240 gpr += 2;
1241 }
1242
1243 /*
1244 * outputs
1245 */
1246#define A_PUT_OUTPUT(out,src) A_OP(icode, &ptr, iACC3, A_EXTOUT(out), A_C_00000000, A_C_00000000, A_GPR(src))
1247#define A_PUT_STEREO_OUTPUT(out1,out2,src) \
1248 {A_PUT_OUTPUT(out1,src); A_PUT_OUTPUT(out2,src+1);}
1249
1250#define _A_SWITCH(icode, ptr, dst, src, sw) \
1251 A_OP((icode), ptr, iMACINT0, dst, A_C_00000000, src, sw);
1252#define A_SWITCH(icode, ptr, dst, src, sw) \
1253 _A_SWITCH(icode, ptr, A_GPR(dst), A_GPR(src), A_GPR(sw))
1254#define _A_SWITCH_NEG(icode, ptr, dst, src) \
1255 A_OP((icode), ptr, iANDXOR, dst, src, A_C_00000001, A_C_00000001);
1256#define A_SWITCH_NEG(icode, ptr, dst, src) \
1257 _A_SWITCH_NEG(icode, ptr, A_GPR(dst), A_GPR(src))
1258
1259
1260 /*
1261 * Process tone control
1262 */
1263 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), A_GPR(playback + 0), A_C_00000000, A_C_00000000); /* left */
1264 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), A_GPR(playback + 1), A_C_00000000, A_C_00000000); /* right */
1265 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), A_GPR(playback + 2), A_C_00000000, A_C_00000000); /* rear left */
1266 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000); /* rear right */
1267 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
1268 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
1269 if (emu->spk71) {
1270 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 6), A_GPR(playback + 6), A_C_00000000, A_C_00000000); /* side left */
1271 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 7), A_GPR(playback + 7), A_C_00000000, A_C_00000000); /* side right */
1272 }
1273
1274
1275 ctl = &controls[nctl + 0];
1276 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1277 strcpy(ctl->id.name, "Tone Control - Bass");
1278 ctl->vcount = 2;
1279 ctl->count = 10;
1280 ctl->min = 0;
1281 ctl->max = 40;
1282 ctl->value[0] = ctl->value[1] = 20;
1283 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1284 ctl = &controls[nctl + 1];
1285 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1286 strcpy(ctl->id.name, "Tone Control - Treble");
1287 ctl->vcount = 2;
1288 ctl->count = 10;
1289 ctl->min = 0;
1290 ctl->max = 40;
1291 ctl->value[0] = ctl->value[1] = 20;
1292 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1293
1294#define BASS_GPR 0x8c
1295#define TREBLE_GPR 0x96
1296
1297 for (z = 0; z < 5; z++) {
1298 int j;
1299 for (j = 0; j < 2; j++) {
1300 controls[nctl + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1301 controls[nctl + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1302 }
1303 }
1304 for (z = 0; z < 4; z++) { /* front/rear/center-lfe/side */
1305 int j, k, l, d;
1306 for (j = 0; j < 2; j++) { /* left/right */
1307 k = 0xb0 + (z * 8) + (j * 4);
1308 l = 0xe0 + (z * 8) + (j * 4);
1309 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1310
1311 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(d), A_GPR(BASS_GPR + 0 + j));
1312 A_OP(icode, &ptr, iMACMV, A_GPR(k+1), A_GPR(k), A_GPR(k+1), A_GPR(BASS_GPR + 4 + j));
1313 A_OP(icode, &ptr, iMACMV, A_GPR(k), A_GPR(d), A_GPR(k), A_GPR(BASS_GPR + 2 + j));
1314 A_OP(icode, &ptr, iMACMV, A_GPR(k+3), A_GPR(k+2), A_GPR(k+3), A_GPR(BASS_GPR + 8 + j));
1315 A_OP(icode, &ptr, iMAC0, A_GPR(k+2), A_GPR_ACCU, A_GPR(k+2), A_GPR(BASS_GPR + 6 + j));
1316 A_OP(icode, &ptr, iACC3, A_GPR(k+2), A_GPR(k+2), A_GPR(k+2), A_C_00000000);
1317
1318 A_OP(icode, &ptr, iMAC0, A_C_00000000, A_C_00000000, A_GPR(k+2), A_GPR(TREBLE_GPR + 0 + j));
1319 A_OP(icode, &ptr, iMACMV, A_GPR(l+1), A_GPR(l), A_GPR(l+1), A_GPR(TREBLE_GPR + 4 + j));
1320 A_OP(icode, &ptr, iMACMV, A_GPR(l), A_GPR(k+2), A_GPR(l), A_GPR(TREBLE_GPR + 2 + j));
1321 A_OP(icode, &ptr, iMACMV, A_GPR(l+3), A_GPR(l+2), A_GPR(l+3), A_GPR(TREBLE_GPR + 8 + j));
1322 A_OP(icode, &ptr, iMAC0, A_GPR(l+2), A_GPR_ACCU, A_GPR(l+2), A_GPR(TREBLE_GPR + 6 + j));
1323 A_OP(icode, &ptr, iMACINT0, A_GPR(l+2), A_C_00000000, A_GPR(l+2), A_C_00000010);
1324
1325 A_OP(icode, &ptr, iACC3, A_GPR(d), A_GPR(l+2), A_C_00000000, A_C_00000000);
1326
1327 if (z == 2) /* center */
1328 break;
1329 }
1330 }
1331 nctl += 2;
1332
1333#undef BASS_GPR
1334#undef TREBLE_GPR
1335
1336 for (z = 0; z < 8; z++) {
1337 A_SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1338 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1339 A_SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1340 A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1341 }
1342 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "Tone Control - Switch", gpr, 0);
1343 gpr += 2;
1344
1345 /* Master volume (will be renamed later) */
1346 A_OP(icode, &ptr, iMAC0, A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+0+SND_EMU10K1_PLAYBACK_CHANNELS));
1347 A_OP(icode, &ptr, iMAC0, A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+1+SND_EMU10K1_PLAYBACK_CHANNELS));
1348 A_OP(icode, &ptr, iMAC0, A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+2+SND_EMU10K1_PLAYBACK_CHANNELS));
1349 A_OP(icode, &ptr, iMAC0, A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+3+SND_EMU10K1_PLAYBACK_CHANNELS));
1350 A_OP(icode, &ptr, iMAC0, A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+4+SND_EMU10K1_PLAYBACK_CHANNELS));
1351 A_OP(icode, &ptr, iMAC0, A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+5+SND_EMU10K1_PLAYBACK_CHANNELS));
1352 A_OP(icode, &ptr, iMAC0, A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+6+SND_EMU10K1_PLAYBACK_CHANNELS));
1353 A_OP(icode, &ptr, iMAC0, A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS), A_C_00000000, A_GPR(gpr), A_GPR(playback+7+SND_EMU10K1_PLAYBACK_CHANNELS));
1354 snd_emu10k1_init_mono_control(&controls[nctl++], "Wave Master Playback Volume", gpr, 0);
1355 gpr += 2;
1356
1357 /* analog speakers */
1358 A_PUT_STEREO_OUTPUT(A_EXTOUT_AFRONT_L, A_EXTOUT_AFRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1359 A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1360 A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1361 A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1362 if (emu->spk71)
1363 A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
1364
1365 /* headphone */
1366 A_PUT_STEREO_OUTPUT(A_EXTOUT_HEADPHONE_L, A_EXTOUT_HEADPHONE_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1367
1368 /* digital outputs */
1369 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1370
1371 /* IEC958 Optical Raw Playback Switch */
1372 gpr_map[gpr++] = 0;
1373 gpr_map[gpr++] = 0x1008;
1374 gpr_map[gpr++] = 0xffff0000;
1375 for (z = 0; z < 2; z++) {
1376 A_OP(icode, &ptr, iMAC0, A_GPR(tmp + 2), A_FXBUS(FXBUS_PT_LEFT + z), A_C_00000000, A_C_00000000);
1377 A_OP(icode, &ptr, iSKIP, A_GPR_COND, A_GPR_COND, A_GPR(gpr - 2), A_C_00000001);
1378 A_OP(icode, &ptr, iACC3, A_GPR(tmp + 2), A_C_00000000, A_C_00010000, A_GPR(tmp + 2));
1379 A_OP(icode, &ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_GPR(gpr - 1), A_C_00000000);
1380 A_SWITCH(icode, &ptr, tmp + 0, tmp + 2, gpr + z);
1381 A_SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1382 A_SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1383 if ((z==1) && (emu->card_capabilities->spdif_bug)) {
1384 /* Due to a SPDIF output bug on some Audigy cards, this code delays the Right channel by 1 sample */
1385 snd_printk("Installing spdif_bug patch: %s\n", emu->card_capabilities->name);
1386 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(gpr - 3), A_C_00000000, A_C_00000000);
1387 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 3), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1388 } else {
1389 A_OP(icode, &ptr, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L + z), A_GPR(tmp + 0), A_GPR(tmp + 1), A_C_00000000);
1390 }
1391 }
1392 snd_emu10k1_init_stereo_onoff_control(controls + nctl++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1393 gpr += 2;
1394
1395 A_PUT_STEREO_OUTPUT(A_EXTOUT_REAR_L, A_EXTOUT_REAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
1396 A_PUT_OUTPUT(A_EXTOUT_CENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
1397 A_PUT_OUTPUT(A_EXTOUT_LFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
1398
1399 /* ADC buffer */
1400#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1401 A_PUT_STEREO_OUTPUT(A_EXTOUT_ADC_CAP_L, A_EXTOUT_ADC_CAP_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS);
1402#else
1403 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_L, capture);
1404 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1405#endif
1406
1407 /* EFX capture - capture the 16 EXTINs */
1408 for (z = 0; z < 16; z++) {
1409 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1410 }
1411
1412 /*
1413 * ok, set up done..
1414 */
1415
1416 if (gpr > tmp) {
1417 snd_BUG();
1418 err = -EIO;
1419 goto __err;
1420 }
1421 /* clear remaining instruction memory */
1422 while (ptr < 0x400)
1423 A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
1424
1425 seg = snd_enter_user();
1426 icode->gpr_add_control_count = nctl;
1427 icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
1428 err = snd_emu10k1_icode_poke(emu, icode);
1429 snd_leave_user(seg);
1430
1431 __err:
1432 kfree(controls);
1433 if (icode != NULL) {
1434 kfree((void *)icode->gpr_map);
1435 kfree(icode);
1436 }
1437 return err;
1438}
1439
1440
1441/*
1442 * initial DSP configuration for Emu10k1
1443 */
1444
1445/* when volume = max, then copy only to avoid volume modification */
1446/* with iMAC0 (negative values) */
1447static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1448{
1449 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1450 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1451 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
1452 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1453}
1454static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1455{
1456 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1457 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1458 OP(icode, ptr, iMACINT0, dst, dst, src, C_00000001);
1459 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1460 OP(icode, ptr, iMAC0, dst, dst, src, vol);
1461}
1462static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
1463{
1464 OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
1465 OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1466 OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
1467 OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
1468 OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
1469}
1470
1471#define VOLUME(icode, ptr, dst, src, vol) \
1472 _volume(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1473#define VOLUME_IN(icode, ptr, dst, src, vol) \
1474 _volume(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1475#define VOLUME_ADD(icode, ptr, dst, src, vol) \
1476 _volume_add(icode, ptr, GPR(dst), GPR(src), GPR(vol))
1477#define VOLUME_ADDIN(icode, ptr, dst, src, vol) \
1478 _volume_add(icode, ptr, GPR(dst), EXTIN(src), GPR(vol))
1479#define VOLUME_OUT(icode, ptr, dst, src, vol) \
1480 _volume_out(icode, ptr, EXTOUT(dst), GPR(src), GPR(vol))
1481#define _SWITCH(icode, ptr, dst, src, sw) \
1482 OP((icode), ptr, iMACINT0, dst, C_00000000, src, sw);
1483#define SWITCH(icode, ptr, dst, src, sw) \
1484 _SWITCH(icode, ptr, GPR(dst), GPR(src), GPR(sw))
1485#define SWITCH_IN(icode, ptr, dst, src, sw) \
1486 _SWITCH(icode, ptr, GPR(dst), EXTIN(src), GPR(sw))
1487#define _SWITCH_NEG(icode, ptr, dst, src) \
1488 OP((icode), ptr, iANDXOR, dst, src, C_00000001, C_00000001);
1489#define SWITCH_NEG(icode, ptr, dst, src) \
1490 _SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
1491
1492
1493static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
1494{
1495 int err, i, z, gpr, tmp, playback, capture;
1496 u32 ptr;
1497 emu10k1_fx8010_code_t *icode;
1498 emu10k1_fx8010_pcm_t *ipcm = NULL;
1499 emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
1500 u32 *gpr_map;
1501 mm_segment_t seg;
1502
1503 spin_lock_init(&emu->fx8010.irq_lock);
1504 INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
1505
1506 if ((icode = kcalloc(1, sizeof(*icode), GFP_KERNEL)) == NULL)
1507 return -ENOMEM;
1508 if ((icode->gpr_map = (u_int32_t __user *)kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
1509 (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
1510 (ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL)) == NULL) {
1511 err = -ENOMEM;
1512 goto __err;
1513 }
1514 gpr_map = (u32 *)icode->gpr_map;
1515
1516 icode->tram_data_map = icode->gpr_map + 256;
1517 icode->tram_addr_map = icode->tram_data_map + 160;
1518 icode->code = icode->tram_addr_map + 160;
1519
1520 /* clear free GPRs */
1521 for (i = 0; i < 256; i++)
1522 set_bit(i, icode->gpr_valid);
1523
1524 /* clear TRAM data & address lines */
1525 for (i = 0; i < 160; i++)
1526 set_bit(i, icode->tram_valid);
1527
1528 strcpy(icode->name, "SB Live! FX8010 code for ALSA v1.2 by Jaroslav Kysela");
1529 ptr = 0; i = 0;
1530 /* we have 10 inputs */
1531 playback = SND_EMU10K1_INPUTS;
1532 /* we have 6 playback channels and tone control doubles */
1533 capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2);
1534 gpr = capture + SND_EMU10K1_CAPTURE_CHANNELS;
1535 tmp = 0x88; /* we need 4 temporary GPR */
1536 /* from 0x8c to 0xff is the area for tone control */
1537
1538 /* stop FX processor */
1539 snd_emu10k1_ptr_write(emu, DBG, 0, (emu->fx8010.dbg = 0) | EMU10K1_DBG_SINGLE_STEP);
1540
1541 /*
1542 * Process FX Buses
1543 */
1544 OP(icode, &ptr, iMACINT0, GPR(0), C_00000000, FXBUS(FXBUS_PCM_LEFT), C_00000004);
1545 OP(icode, &ptr, iMACINT0, GPR(1), C_00000000, FXBUS(FXBUS_PCM_RIGHT), C_00000004);
1546 OP(icode, &ptr, iMACINT0, GPR(2), C_00000000, FXBUS(FXBUS_MIDI_LEFT), C_00000004);
1547 OP(icode, &ptr, iMACINT0, GPR(3), C_00000000, FXBUS(FXBUS_MIDI_RIGHT), C_00000004);
1548 OP(icode, &ptr, iMACINT0, GPR(4), C_00000000, FXBUS(FXBUS_PCM_LEFT_REAR), C_00000004);
1549 OP(icode, &ptr, iMACINT0, GPR(5), C_00000000, FXBUS(FXBUS_PCM_RIGHT_REAR), C_00000004);
1550 OP(icode, &ptr, iMACINT0, GPR(6), C_00000000, FXBUS(FXBUS_PCM_CENTER), C_00000004);
1551 OP(icode, &ptr, iMACINT0, GPR(7), C_00000000, FXBUS(FXBUS_PCM_LFE), C_00000004);
1552 OP(icode, &ptr, iMACINT0, GPR(8), C_00000000, C_00000000, C_00000000); /* S/PDIF left */
1553 OP(icode, &ptr, iMACINT0, GPR(9), C_00000000, C_00000000, C_00000000); /* S/PDIF right */
1554
1555 /* Raw S/PDIF PCM */
1556 ipcm->substream = 0;
1557 ipcm->channels = 2;
1558 ipcm->tram_start = 0;
1559 ipcm->buffer_size = (64 * 1024) / 2;
1560 ipcm->gpr_size = gpr++;
1561 ipcm->gpr_ptr = gpr++;
1562 ipcm->gpr_count = gpr++;
1563 ipcm->gpr_tmpcount = gpr++;
1564 ipcm->gpr_trigger = gpr++;
1565 ipcm->gpr_running = gpr++;
1566 ipcm->etram[0] = 0;
1567 ipcm->etram[1] = 1;
1568
1569 gpr_map[gpr + 0] = 0xfffff000;
1570 gpr_map[gpr + 1] = 0xffff0000;
1571 gpr_map[gpr + 2] = 0x70000000;
1572 gpr_map[gpr + 3] = 0x00000007;
1573 gpr_map[gpr + 4] = 0x001f << 11;
1574 gpr_map[gpr + 5] = 0x001c << 11;
1575 gpr_map[gpr + 6] = (0x22 - 0x01) - 1; /* skip at 01 to 22 */
1576 gpr_map[gpr + 7] = (0x22 - 0x06) - 1; /* skip at 06 to 22 */
1577 gpr_map[gpr + 8] = 0x2000000 + (2<<11);
1578 gpr_map[gpr + 9] = 0x4000000 + (2<<11);
1579 gpr_map[gpr + 10] = 1<<11;
1580 gpr_map[gpr + 11] = (0x24 - 0x0a) - 1; /* skip at 0a to 24 */
1581 gpr_map[gpr + 12] = 0;
1582
1583 /* if the trigger flag is not set, skip */
1584 /* 00: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_trigger), C_00000000, C_00000000);
1585 /* 01: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_ZERO, GPR(gpr + 6));
1586 /* if the running flag is set, we're running */
1587 /* 02: */ OP(icode, &ptr, iMAC0, C_00000000, GPR(ipcm->gpr_running), C_00000000, C_00000000);
1588 /* 03: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000004);
1589 /* wait until ((GPR_DBAC>>11) & 0x1f) == 0x1c) */
1590 /* 04: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), GPR_DBAC, GPR(gpr + 4), C_00000000);
1591 /* 05: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(gpr + 5));
1592 /* 06: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 7));
1593 /* 07: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000010, C_00000001, C_00000000);
1594
1595 /* 08: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000000, C_00000001);
1596 /* 09: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), GPR(gpr + 12), C_ffffffff, C_00000000);
1597 /* 0a: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, GPR(gpr + 11));
1598 /* 0b: */ OP(icode, &ptr, iACC3, GPR(gpr + 12), C_00000001, C_00000000, C_00000000);
1599
1600 /* 0c: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[0]), GPR(gpr + 0), C_00000000);
1601 /* 0d: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1602 /* 0e: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1603 /* 0f: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1604 /* 10: */ OP(icode, &ptr, iANDXOR, GPR(8), GPR(8), GPR(gpr + 1), GPR(gpr + 2));
1605
1606 /* 11: */ OP(icode, &ptr, iANDXOR, GPR(tmp + 0), ETRAM_DATA(ipcm->etram[1]), GPR(gpr + 0), C_00000000);
1607 /* 12: */ OP(icode, &ptr, iLOG, GPR(tmp + 0), GPR(tmp + 0), GPR(gpr + 3), C_00000000);
1608 /* 13: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(tmp + 0), GPR(gpr + 1), GPR(gpr + 2));
1609 /* 14: */ OP(icode, &ptr, iSKIP, C_00000000, GPR_COND, CC_REG_MINUS, C_00000001);
1610 /* 15: */ OP(icode, &ptr, iANDXOR, GPR(9), GPR(9), GPR(gpr + 1), GPR(gpr + 2));
1611
1612 /* 16: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(ipcm->gpr_ptr), C_00000001, C_00000000);
1613 /* 17: */ OP(icode, &ptr, iMACINT0, C_00000000, GPR(tmp + 0), C_ffffffff, GPR(ipcm->gpr_size));
1614 /* 18: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_MINUS, C_00000001);
1615 /* 19: */ OP(icode, &ptr, iACC3, GPR(tmp + 0), C_00000000, C_00000000, C_00000000);
1616 /* 1a: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_ptr), GPR(tmp + 0), C_00000000, C_00000000);
1617
1618 /* 1b: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_tmpcount), C_ffffffff, C_00000000);
1619 /* 1c: */ OP(icode, &ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
1620 /* 1d: */ OP(icode, &ptr, iACC3, GPR(ipcm->gpr_tmpcount), GPR(ipcm->gpr_count), C_00000000, C_00000000);
1621 /* 1e: */ OP(icode, &ptr, iACC3, GPR_IRQ, C_80000000, C_00000000, C_00000000);
1622 /* 1f: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00000001, C_00010000);
1623
1624 /* 20: */ OP(icode, &ptr, iANDXOR, GPR(ipcm->gpr_running), GPR(ipcm->gpr_running), C_00010000, C_00000001);
1625 /* 21: */ OP(icode, &ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000002);
1626
1627 /* 22: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[0]), GPR(gpr + 8), GPR_DBAC, C_ffffffff);
1628 /* 23: */ OP(icode, &ptr, iMACINT1, ETRAM_ADDR(ipcm->etram[1]), GPR(gpr + 9), GPR_DBAC, C_ffffffff);
1629
1630 /* 24: */
1631 gpr += 13;
1632
1633 /* Wave Playback Volume */
1634 for (z = 0; z < 2; z++)
1635 VOLUME(icode, &ptr, playback + z, z, gpr + z);
1636 snd_emu10k1_init_stereo_control(controls + i++, "Wave Playback Volume", gpr, 100);
1637 gpr += 2;
1638
1639 /* Wave Surround Playback Volume */
1640 for (z = 0; z < 2; z++)
1641 VOLUME(icode, &ptr, playback + 2 + z, z, gpr + z);
1642 snd_emu10k1_init_stereo_control(controls + i++, "Wave Surround Playback Volume", gpr, 0);
1643 gpr += 2;
1644
1645 /* Wave Center/LFE Playback Volume */
1646 OP(icode, &ptr, iACC3, GPR(tmp + 0), FXBUS(FXBUS_PCM_LEFT), FXBUS(FXBUS_PCM_RIGHT), C_00000000);
1647 OP(icode, &ptr, iMACINT0, GPR(tmp + 0), C_00000000, GPR(tmp + 0), C_00000002);
1648 VOLUME(icode, &ptr, playback + 4, tmp + 0, gpr);
1649 snd_emu10k1_init_mono_control(controls + i++, "Wave Center Playback Volume", gpr++, 0);
1650 VOLUME(icode, &ptr, playback + 5, tmp + 0, gpr);
1651 snd_emu10k1_init_mono_control(controls + i++, "Wave LFE Playback Volume", gpr++, 0);
1652
1653 /* Wave Capture Volume + Switch */
1654 for (z = 0; z < 2; z++) {
1655 SWITCH(icode, &ptr, tmp + 0, z, gpr + 2 + z);
1656 VOLUME(icode, &ptr, capture + z, tmp + 0, gpr + z);
1657 }
1658 snd_emu10k1_init_stereo_control(controls + i++, "Wave Capture Volume", gpr, 0);
1659 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Wave Capture Switch", gpr + 2, 0);
1660 gpr += 4;
1661
1662 /* Synth Playback Volume */
1663 for (z = 0; z < 2; z++)
1664 VOLUME_ADD(icode, &ptr, playback + z, 2 + z, gpr + z);
1665 snd_emu10k1_init_stereo_control(controls + i++, "Synth Playback Volume", gpr, 100);
1666 gpr += 2;
1667
1668 /* Synth Capture Volume + Switch */
1669 for (z = 0; z < 2; z++) {
1670 SWITCH(icode, &ptr, tmp + 0, 2 + z, gpr + 2 + z);
1671 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1672 }
1673 snd_emu10k1_init_stereo_control(controls + i++, "Synth Capture Volume", gpr, 0);
1674 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Synth Capture Switch", gpr + 2, 0);
1675 gpr += 4;
1676
1677 /* Surround Digital Playback Volume (renamed later without Digital) */
1678 for (z = 0; z < 2; z++)
1679 VOLUME_ADD(icode, &ptr, playback + 2 + z, 4 + z, gpr + z);
1680 snd_emu10k1_init_stereo_control(controls + i++, "Surround Digital Playback Volume", gpr, 100);
1681 gpr += 2;
1682
1683 /* Surround Capture Volume + Switch */
1684 for (z = 0; z < 2; z++) {
1685 SWITCH(icode, &ptr, tmp + 0, 4 + z, gpr + 2 + z);
1686 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1687 }
1688 snd_emu10k1_init_stereo_control(controls + i++, "Surround Capture Volume", gpr, 0);
1689 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Surround Capture Switch", gpr + 2, 0);
1690 gpr += 4;
1691
1692 /* Center Playback Volume (renamed later without Digital) */
1693 VOLUME_ADD(icode, &ptr, playback + 4, 6, gpr);
1694 snd_emu10k1_init_mono_control(controls + i++, "Center Digital Playback Volume", gpr++, 100);
1695
1696 /* LFE Playback Volume + Switch (renamed later without Digital) */
1697 VOLUME_ADD(icode, &ptr, playback + 5, 7, gpr);
1698 snd_emu10k1_init_mono_control(controls + i++, "LFE Digital Playback Volume", gpr++, 100);
1699
1700 /*
1701 * Process inputs
1702 */
1703
1704 if (emu->fx8010.extin_mask & ((1<<EXTIN_AC97_L)|(1<<EXTIN_AC97_R))) {
1705 /* AC'97 Playback Volume */
1706 VOLUME_ADDIN(icode, &ptr, playback + 0, EXTIN_AC97_L, gpr); gpr++;
1707 VOLUME_ADDIN(icode, &ptr, playback + 1, EXTIN_AC97_R, gpr); gpr++;
1708 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Playback Volume", gpr-2, 0);
1709 /* AC'97 Capture Volume */
1710 VOLUME_ADDIN(icode, &ptr, capture + 0, EXTIN_AC97_L, gpr); gpr++;
1711 VOLUME_ADDIN(icode, &ptr, capture + 1, EXTIN_AC97_R, gpr); gpr++;
1712 snd_emu10k1_init_stereo_control(controls + i++, "AC97 Capture Volume", gpr-2, 100);
1713 }
1714
1715 if (emu->fx8010.extin_mask & ((1<<EXTIN_SPDIF_CD_L)|(1<<EXTIN_SPDIF_CD_R))) {
1716 /* IEC958 TTL Playback Volume */
1717 for (z = 0; z < 2; z++)
1718 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_SPDIF_CD_L + z, gpr + z);
1719 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Playback Volume", gpr, 0);
1720 gpr += 2;
1721
1722 /* IEC958 TTL Capture Volume + Switch */
1723 for (z = 0; z < 2; z++) {
1724 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_SPDIF_CD_L + z, gpr + 2 + z);
1725 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1726 }
1727 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 TTL Capture Volume", gpr, 0);
1728 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 TTL Capture Switch", gpr + 2, 0);
1729 gpr += 4;
1730 }
1731
1732 if (emu->fx8010.extin_mask & ((1<<EXTIN_ZOOM_L)|(1<<EXTIN_ZOOM_R))) {
1733 /* Zoom Video Playback Volume */
1734 for (z = 0; z < 2; z++)
1735 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_ZOOM_L + z, gpr + z);
1736 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Playback Volume", gpr, 0);
1737 gpr += 2;
1738
1739 /* Zoom Video Capture Volume + Switch */
1740 for (z = 0; z < 2; z++) {
1741 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_ZOOM_L + z, gpr + 2 + z);
1742 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1743 }
1744 snd_emu10k1_init_stereo_control(controls + i++, "Zoom Video Capture Volume", gpr, 0);
1745 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Zoom Video Capture Switch", gpr + 2, 0);
1746 gpr += 4;
1747 }
1748
1749 if (emu->fx8010.extin_mask & ((1<<EXTIN_TOSLINK_L)|(1<<EXTIN_TOSLINK_R))) {
1750 /* IEC958 Optical Playback Volume */
1751 for (z = 0; z < 2; z++)
1752 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_TOSLINK_L + z, gpr + z);
1753 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Playback Volume", gpr, 0);
1754 gpr += 2;
1755
1756 /* IEC958 Optical Capture Volume */
1757 for (z = 0; z < 2; z++) {
1758 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_TOSLINK_L + z, gpr + 2 + z);
1759 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1760 }
1761 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 LiveDrive Capture Volume", gpr, 0);
1762 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 LiveDrive Capture Switch", gpr + 2, 0);
1763 gpr += 4;
1764 }
1765
1766 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE1_L)|(1<<EXTIN_LINE1_R))) {
1767 /* Line LiveDrive Playback Volume */
1768 for (z = 0; z < 2; z++)
1769 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE1_L + z, gpr + z);
1770 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Playback Volume", gpr, 0);
1771 gpr += 2;
1772
1773 /* Line LiveDrive Capture Volume + Switch */
1774 for (z = 0; z < 2; z++) {
1775 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE1_L + z, gpr + 2 + z);
1776 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1777 }
1778 snd_emu10k1_init_stereo_control(controls + i++, "Line LiveDrive Capture Volume", gpr, 0);
1779 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line LiveDrive Capture Switch", gpr + 2, 0);
1780 gpr += 4;
1781 }
1782
1783 if (emu->fx8010.extin_mask & ((1<<EXTIN_COAX_SPDIF_L)|(1<<EXTIN_COAX_SPDIF_R))) {
1784 /* IEC958 Coax Playback Volume */
1785 for (z = 0; z < 2; z++)
1786 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_COAX_SPDIF_L + z, gpr + z);
1787 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Playback Volume", gpr, 0);
1788 gpr += 2;
1789
1790 /* IEC958 Coax Capture Volume + Switch */
1791 for (z = 0; z < 2; z++) {
1792 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_COAX_SPDIF_L + z, gpr + 2 + z);
1793 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1794 }
1795 snd_emu10k1_init_stereo_control(controls + i++, "IEC958 Coaxial Capture Volume", gpr, 0);
1796 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Coaxial Capture Switch", gpr + 2, 0);
1797 gpr += 4;
1798 }
1799
1800 if (emu->fx8010.extin_mask & ((1<<EXTIN_LINE2_L)|(1<<EXTIN_LINE2_R))) {
1801 /* Line LiveDrive Playback Volume */
1802 for (z = 0; z < 2; z++)
1803 VOLUME_ADDIN(icode, &ptr, playback + z, EXTIN_LINE2_L + z, gpr + z);
1804 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Playback Volume", gpr, 0);
1805 controls[i-1].id.index = 1;
1806 gpr += 2;
1807
1808 /* Line LiveDrive Capture Volume */
1809 for (z = 0; z < 2; z++) {
1810 SWITCH_IN(icode, &ptr, tmp + 0, EXTIN_LINE2_L + z, gpr + 2 + z);
1811 VOLUME_ADD(icode, &ptr, capture + z, tmp + 0, gpr + z);
1812 }
1813 snd_emu10k1_init_stereo_control(controls + i++, "Line2 LiveDrive Capture Volume", gpr, 0);
1814 controls[i-1].id.index = 1;
1815 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Line2 LiveDrive Capture Switch", gpr + 2, 0);
1816 controls[i-1].id.index = 1;
1817 gpr += 4;
1818 }
1819
1820 /*
1821 * Process tone control
1822 */
1823 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), GPR(playback + 0), C_00000000, C_00000000); /* left */
1824 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), GPR(playback + 1), C_00000000, C_00000000); /* right */
1825 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2), GPR(playback + 2), C_00000000, C_00000000); /* rear left */
1826 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), GPR(playback + 3), C_00000000, C_00000000); /* rear right */
1827 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), GPR(playback + 4), C_00000000, C_00000000); /* center */
1828 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
1829
1830 ctl = &controls[i + 0];
1831 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1832 strcpy(ctl->id.name, "Tone Control - Bass");
1833 ctl->vcount = 2;
1834 ctl->count = 10;
1835 ctl->min = 0;
1836 ctl->max = 40;
1837 ctl->value[0] = ctl->value[1] = 20;
1838 ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
1839 ctl = &controls[i + 1];
1840 ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1841 strcpy(ctl->id.name, "Tone Control - Treble");
1842 ctl->vcount = 2;
1843 ctl->count = 10;
1844 ctl->min = 0;
1845 ctl->max = 40;
1846 ctl->value[0] = ctl->value[1] = 20;
1847 ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE;
1848
1849#define BASS_GPR 0x8c
1850#define TREBLE_GPR 0x96
1851
1852 for (z = 0; z < 5; z++) {
1853 int j;
1854 for (j = 0; j < 2; j++) {
1855 controls[i + 0].gpr[z * 2 + j] = BASS_GPR + z * 2 + j;
1856 controls[i + 1].gpr[z * 2 + j] = TREBLE_GPR + z * 2 + j;
1857 }
1858 }
1859 for (z = 0; z < 3; z++) { /* front/rear/center-lfe */
1860 int j, k, l, d;
1861 for (j = 0; j < 2; j++) { /* left/right */
1862 k = 0xa0 + (z * 8) + (j * 4);
1863 l = 0xd0 + (z * 8) + (j * 4);
1864 d = playback + SND_EMU10K1_PLAYBACK_CHANNELS + z * 2 + j;
1865
1866 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(d), GPR(BASS_GPR + 0 + j));
1867 OP(icode, &ptr, iMACMV, GPR(k+1), GPR(k), GPR(k+1), GPR(BASS_GPR + 4 + j));
1868 OP(icode, &ptr, iMACMV, GPR(k), GPR(d), GPR(k), GPR(BASS_GPR + 2 + j));
1869 OP(icode, &ptr, iMACMV, GPR(k+3), GPR(k+2), GPR(k+3), GPR(BASS_GPR + 8 + j));
1870 OP(icode, &ptr, iMAC0, GPR(k+2), GPR_ACCU, GPR(k+2), GPR(BASS_GPR + 6 + j));
1871 OP(icode, &ptr, iACC3, GPR(k+2), GPR(k+2), GPR(k+2), C_00000000);
1872
1873 OP(icode, &ptr, iMAC0, C_00000000, C_00000000, GPR(k+2), GPR(TREBLE_GPR + 0 + j));
1874 OP(icode, &ptr, iMACMV, GPR(l+1), GPR(l), GPR(l+1), GPR(TREBLE_GPR + 4 + j));
1875 OP(icode, &ptr, iMACMV, GPR(l), GPR(k+2), GPR(l), GPR(TREBLE_GPR + 2 + j));
1876 OP(icode, &ptr, iMACMV, GPR(l+3), GPR(l+2), GPR(l+3), GPR(TREBLE_GPR + 8 + j));
1877 OP(icode, &ptr, iMAC0, GPR(l+2), GPR_ACCU, GPR(l+2), GPR(TREBLE_GPR + 6 + j));
1878 OP(icode, &ptr, iMACINT0, GPR(l+2), C_00000000, GPR(l+2), C_00000010);
1879
1880 OP(icode, &ptr, iACC3, GPR(d), GPR(l+2), C_00000000, C_00000000);
1881
1882 if (z == 2) /* center */
1883 break;
1884 }
1885 }
1886 i += 2;
1887
1888#undef BASS_GPR
1889#undef TREBLE_GPR
1890
1891 for (z = 0; z < 6; z++) {
1892 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, gpr + 0);
1893 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 0);
1894 SWITCH(icode, &ptr, tmp + 1, playback + z, tmp + 1);
1895 OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1896 }
1897 snd_emu10k1_init_stereo_onoff_control(controls + i++, "Tone Control - Switch", gpr, 0);
1898 gpr += 2;
1899
1900 /*
1901 * Process outputs
1902 */
1903 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_L)|(1<<EXTOUT_AC97_R))) {
1904 /* AC'97 Playback Volume */
1905
1906 for (z = 0; z < 2; z++)
1907 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), C_00000000, C_00000000);
1908 }
1909
1910 if (emu->fx8010.extout_mask & ((1<<EXTOUT_TOSLINK_L)|(1<<EXTOUT_TOSLINK_R))) {
1911 /* IEC958 Optical Raw Playback Switch */
1912
1913 for (z = 0; z < 2; z++) {
1914 SWITCH(icode, &ptr, tmp + 0, 8 + z, gpr + z);
1915 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + z);
1916 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1917 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_TOSLINK_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1918#ifdef EMU10K1_CAPTURE_DIGITAL_OUT
1919 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1920#endif
1921 }
1922
1923 snd_emu10k1_init_stereo_onoff_control(controls + i++, "IEC958 Optical Raw Playback Switch", gpr, 0);
1924 gpr += 2;
1925 }
1926
1927 if (emu->fx8010.extout_mask & ((1<<EXTOUT_HEADPHONE_L)|(1<<EXTOUT_HEADPHONE_R))) {
1928 /* Headphone Playback Volume */
1929
1930 for (z = 0; z < 2; z++) {
1931 SWITCH(icode, &ptr, tmp + 0, playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4 + z, gpr + 2 + z);
1932 SWITCH_NEG(icode, &ptr, tmp + 1, gpr + 2 + z);
1933 SWITCH(icode, &ptr, tmp + 1, playback + SND_EMU10K1_PLAYBACK_CHANNELS + z, tmp + 1);
1934 OP(icode, &ptr, iACC3, GPR(tmp + 0), GPR(tmp + 0), GPR(tmp + 1), C_00000000);
1935 VOLUME_OUT(icode, &ptr, EXTOUT_HEADPHONE_L + z, tmp + 0, gpr + z);
1936 }
1937
1938 snd_emu10k1_init_stereo_control(controls + i++, "Headphone Playback Volume", gpr + 0, 0);
1939 controls[i-1].id.index = 1; /* AC'97 can have also Headphone control */
1940 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone Center Playback Switch", gpr + 2, 0);
1941 controls[i-1].id.index = 1;
1942 snd_emu10k1_init_mono_onoff_control(controls + i++, "Headphone LFE Playback Switch", gpr + 3, 0);
1943 controls[i-1].id.index = 1;
1944
1945 gpr += 4;
1946 }
1947
1948 if (emu->fx8010.extout_mask & ((1<<EXTOUT_REAR_L)|(1<<EXTOUT_REAR_R)))
1949 for (z = 0; z < 2; z++)
1950 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1951
1952 if (emu->fx8010.extout_mask & ((1<<EXTOUT_AC97_REAR_L)|(1<<EXTOUT_AC97_REAR_R)))
1953 for (z = 0; z < 2; z++)
1954 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_REAR_L + z), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 2 + z), C_00000000, C_00000000);
1955
1956 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_CENTER)) {
1957#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1958 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1959 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), C_00000000, C_00000000);
1960#else
1961 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_CENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1962 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ACENTER), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 0), C_00000000, C_00000000);
1963#endif
1964 }
1965
1966 if (emu->fx8010.extout_mask & (1<<EXTOUT_AC97_LFE)) {
1967#ifndef EMU10K1_CENTER_LFE_FROM_FRONT
1968 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1969 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), C_00000000, C_00000000);
1970#else
1971 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_AC97_LFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1972 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ALFE), GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 1), C_00000000, C_00000000);
1973#endif
1974 }
1975
1976#ifndef EMU10K1_CAPTURE_DIGITAL_OUT
1977 for (z = 0; z < 2; z++)
1978 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_ADC_CAP_L + z), GPR(capture + z), C_00000000, C_00000000);
1979#endif
1980
1981 if (emu->fx8010.extout_mask & (1<<EXTOUT_MIC_CAP))
1982 OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
1983
1984 /* EFX capture - capture the 16 EXTINS */
1985 OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
1986 OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
1987 OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
1988 OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
1989 /* Dont connect anything to FXBUS2 1 and 2. These are shared with
1990 * Center/LFE on the SBLive 5.1. The kX driver only changes the
1991 * routing when it detects an SBLive 5.1.
1992 *
1993 * Since only 14 of the 16 EXTINs are used, this is not a big problem.
1994 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture
1995 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture
1996 * channel.
1997 */
1998 for (z = 4; z < 14; z++) {
1999 OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
2000 }
2001
2002 if (gpr > tmp) {
2003 snd_BUG();
2004 err = -EIO;
2005 goto __err;
2006 }
2007 if (i > SND_EMU10K1_GPR_CONTROLS) {
2008 snd_BUG();
2009 err = -EIO;
2010 goto __err;
2011 }
2012
2013 /* clear remaining instruction memory */
2014 while (ptr < 0x200)
2015 OP(icode, &ptr, iACC3, C_00000000, C_00000000, C_00000000, C_00000000);
2016
2017 if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
2018 goto __err;
2019 seg = snd_enter_user();
2020 icode->gpr_add_control_count = i;
2021 icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
2022 err = snd_emu10k1_icode_poke(emu, icode);
2023 snd_leave_user(seg);
2024 if (err >= 0)
2025 err = snd_emu10k1_ipcm_poke(emu, ipcm);
2026 __err:
2027 kfree(ipcm);
2028 kfree(controls);
2029 if (icode != NULL) {
2030 kfree((void *)icode->gpr_map);
2031 kfree(icode);
2032 }
2033 return err;
2034}
2035
2036int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
2037{
2038 if (emu->audigy)
2039 return _snd_emu10k1_audigy_init_efx(emu);
2040 else
2041 return _snd_emu10k1_init_efx(emu);
2042}
2043
2044void snd_emu10k1_free_efx(emu10k1_t *emu)
2045{
2046 /* stop processor */
2047 if (emu->audigy)
2048 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = A_DBG_SINGLE_STEP);
2049 else
2050 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2051}
2052
2053#if 0 // FIXME: who use them?
2054int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
2055{
2056 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2057 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 1);
2058 return 0;
2059}
2060
2061int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
2062{
2063 snd_runtime_check(output >= 0 && output < 6, return -EINVAL);
2064 snd_emu10k1_ptr_write(emu, emu->gpr_base + 0x94 + output, 0, 0);
2065 return 0;
2066}
2067#endif
2068
2069int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
2070{
2071 u8 size_reg = 0;
2072
2073 /* size is in samples */
2074 if (size != 0) {
2075 size = (size - 1) >> 13;
2076
2077 while (size) {
2078 size >>= 1;
2079 size_reg++;
2080 }
2081 size = 0x2000 << size_reg;
2082 }
2083 if ((emu->fx8010.etram_pages.bytes / 2) == size)
2084 return 0;
2085 spin_lock_irq(&emu->emu_lock);
2086 outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
2087 spin_unlock_irq(&emu->emu_lock);
2088 snd_emu10k1_ptr_write(emu, TCB, 0, 0);
2089 snd_emu10k1_ptr_write(emu, TCBS, 0, 0);
2090 if (emu->fx8010.etram_pages.area != NULL) {
2091 snd_dma_free_pages(&emu->fx8010.etram_pages);
2092 emu->fx8010.etram_pages.area = NULL;
2093 emu->fx8010.etram_pages.bytes = 0;
2094 }
2095
2096 if (size > 0) {
2097 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
2098 size * 2, &emu->fx8010.etram_pages) < 0)
2099 return -ENOMEM;
2100 memset(emu->fx8010.etram_pages.area, 0, size * 2);
2101 snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
2102 snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
2103 spin_lock_irq(&emu->emu_lock);
2104 outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
2105 spin_unlock_irq(&emu->emu_lock);
2106 }
2107
2108 return 0;
2109}
2110
2111static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
2112{
2113 return 0;
2114}
2115
2116static void copy_string(char *dst, char *src, char *null, int idx)
2117{
2118 if (src == NULL)
2119 sprintf(dst, "%s %02X", null, idx);
2120 else
2121 strcpy(dst, src);
2122}
2123
2124static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
2125{
2126 char **fxbus, **extin, **extout;
2127 unsigned short fxbus_mask, extin_mask, extout_mask;
2128 int res;
2129
2130 memset(info, 0, sizeof(info));
2131 info->card = emu->card_type;
2132 info->internal_tram_size = emu->fx8010.itram_size;
2133 info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
2134 fxbus = fxbuses;
2135 extin = emu->audigy ? audigy_ins : creative_ins;
2136 extout = emu->audigy ? audigy_outs : creative_outs;
2137 fxbus_mask = emu->fx8010.fxbus_mask;
2138 extin_mask = emu->fx8010.extin_mask;
2139 extout_mask = emu->fx8010.extout_mask;
2140 for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
2141 copy_string(info->fxbus_names[res], fxbus_mask & (1 << res) ? *fxbus : NULL, "FXBUS", res);
2142 copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
2143 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2144 }
2145 for (res = 16; res < 32; res++, extout++)
2146 copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
2147 info->gpr_controls = emu->fx8010.gpr_count;
2148 return 0;
2149}
2150
2151static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
2152{
2153 emu10k1_t *emu = hw->private_data;
2154 emu10k1_fx8010_info_t *info;
2155 emu10k1_fx8010_code_t *icode;
2156 emu10k1_fx8010_pcm_t *ipcm;
2157 unsigned int addr;
2158 void __user *argp = (void __user *)arg;
2159 int res;
2160
2161 switch (cmd) {
2162 case SNDRV_EMU10K1_IOCTL_INFO:
2163 info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
2164 if (!info)
2165 return -ENOMEM;
2166 if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
2167 kfree(info);
2168 return res;
2169 }
2170 if (copy_to_user(argp, info, sizeof(*info))) {
2171 kfree(info);
2172 return -EFAULT;
2173 }
2174 kfree(info);
2175 return 0;
2176 case SNDRV_EMU10K1_IOCTL_CODE_POKE:
2177 if (!capable(CAP_SYS_ADMIN))
2178 return -EPERM;
2179 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2180 if (icode == NULL)
2181 return -ENOMEM;
2182 if (copy_from_user(icode, argp, sizeof(*icode))) {
2183 kfree(icode);
2184 return -EFAULT;
2185 }
2186 res = snd_emu10k1_icode_poke(emu, icode);
2187 kfree(icode);
2188 return res;
2189 case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
2190 icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
2191 if (icode == NULL)
2192 return -ENOMEM;
2193 if (copy_from_user(icode, argp, sizeof(*icode))) {
2194 kfree(icode);
2195 return -EFAULT;
2196 }
2197 res = snd_emu10k1_icode_peek(emu, icode);
2198 if (res == 0 && copy_to_user(argp, icode, sizeof(*icode))) {
2199 kfree(icode);
2200 return -EFAULT;
2201 }
2202 kfree(icode);
2203 return res;
2204 case SNDRV_EMU10K1_IOCTL_PCM_POKE:
2205 ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
2206 if (ipcm == NULL)
2207 return -ENOMEM;
2208 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2209 kfree(ipcm);
2210 return -EFAULT;
2211 }
2212 res = snd_emu10k1_ipcm_poke(emu, ipcm);
2213 kfree(ipcm);
2214 return res;
2215 case SNDRV_EMU10K1_IOCTL_PCM_PEEK:
2216 ipcm = kcalloc(1, sizeof(*ipcm), GFP_KERNEL);
2217 if (ipcm == NULL)
2218 return -ENOMEM;
2219 if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
2220 kfree(ipcm);
2221 return -EFAULT;
2222 }
2223 res = snd_emu10k1_ipcm_peek(emu, ipcm);
2224 if (res == 0 && copy_to_user(argp, ipcm, sizeof(*ipcm))) {
2225 kfree(ipcm);
2226 return -EFAULT;
2227 }
2228 kfree(ipcm);
2229 return res;
2230 case SNDRV_EMU10K1_IOCTL_TRAM_SETUP:
2231 if (!capable(CAP_SYS_ADMIN))
2232 return -EPERM;
2233 if (get_user(addr, (unsigned int __user *)argp))
2234 return -EFAULT;
2235 down(&emu->fx8010.lock);
2236 res = snd_emu10k1_fx8010_tram_setup(emu, addr);
2237 up(&emu->fx8010.lock);
2238 return res;
2239 case SNDRV_EMU10K1_IOCTL_STOP:
2240 if (!capable(CAP_SYS_ADMIN))
2241 return -EPERM;
2242 if (emu->audigy)
2243 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP);
2244 else
2245 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP);
2246 return 0;
2247 case SNDRV_EMU10K1_IOCTL_CONTINUE:
2248 if (!capable(CAP_SYS_ADMIN))
2249 return -EPERM;
2250 if (emu->audigy)
2251 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg = 0);
2252 else
2253 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = 0);
2254 return 0;
2255 case SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER:
2256 if (!capable(CAP_SYS_ADMIN))
2257 return -EPERM;
2258 if (emu->audigy)
2259 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_ZC);
2260 else
2261 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_ZC);
2262 udelay(10);
2263 if (emu->audigy)
2264 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
2265 else
2266 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
2267 return 0;
2268 case SNDRV_EMU10K1_IOCTL_SINGLE_STEP:
2269 if (!capable(CAP_SYS_ADMIN))
2270 return -EPERM;
2271 if (get_user(addr, (unsigned int __user *)argp))
2272 return -EFAULT;
2273 if (addr > 0x1ff)
2274 return -EINVAL;
2275 if (emu->audigy)
2276 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | addr);
2277 else
2278 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | addr);
2279 udelay(10);
2280 if (emu->audigy)
2281 snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg |= A_DBG_SINGLE_STEP | A_DBG_STEP_ADDR | addr);
2282 else
2283 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg |= EMU10K1_DBG_SINGLE_STEP | EMU10K1_DBG_STEP | addr);
2284 return 0;
2285 case SNDRV_EMU10K1_IOCTL_DBG_READ:
2286 if (emu->audigy)
2287 addr = snd_emu10k1_ptr_read(emu, A_DBG, 0);
2288 else
2289 addr = snd_emu10k1_ptr_read(emu, DBG, 0);
2290 if (put_user(addr, (unsigned int __user *)argp))
2291 return -EFAULT;
2292 return 0;
2293 }
2294 return -ENOTTY;
2295}
2296
2297static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
2298{
2299 return 0;
2300}
2301
2302int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
2303{
2304 snd_hwdep_t *hw;
2305 int err;
2306
2307 if (rhwdep)
2308 *rhwdep = NULL;
2309 if ((err = snd_hwdep_new(emu->card, "FX8010", device, &hw)) < 0)
2310 return err;
2311 strcpy(hw->name, "EMU10K1 (FX8010)");
2312 hw->iface = SNDRV_HWDEP_IFACE_EMU10K1;
2313 hw->ops.open = snd_emu10k1_fx8010_open;
2314 hw->ops.ioctl = snd_emu10k1_fx8010_ioctl;
2315 hw->ops.release = snd_emu10k1_fx8010_release;
2316 hw->private_data = emu;
2317 if (rhwdep)
2318 *rhwdep = hw;
2319 return 0;
2320}
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
new file mode 100644
index 000000000000..044663d31aa7
--- /dev/null
+++ b/sound/pci/emu10k1/emumixer.c
@@ -0,0 +1,955 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>,
3 * Takashi Iwai <tiwai@suse.de>
4 * Creative Labs, Inc.
5 * Routines for control of EMU10K1 chips / mixer routines
6 * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
7 *
8 * BUGS:
9 * --
10 *
11 * TODO:
12 * --
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30#include <sound/driver.h>
31#include <linux/time.h>
32#include <linux/init.h>
33#include <sound/core.h>
34#include <sound/emu10k1.h>
35
36#define AC97_ID_STAC9758 0x83847658
37
38static int snd_emu10k1_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
39{
40 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
41 uinfo->count = 1;
42 return 0;
43}
44
45static int snd_emu10k1_spdif_get(snd_kcontrol_t * kcontrol,
46 snd_ctl_elem_value_t * ucontrol)
47{
48 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
49 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
50 unsigned long flags;
51
52 spin_lock_irqsave(&emu->reg_lock, flags);
53 ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
54 ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff;
55 ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff;
56 ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff;
57 spin_unlock_irqrestore(&emu->reg_lock, flags);
58 return 0;
59}
60
61static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol,
62 snd_ctl_elem_value_t * ucontrol)
63{
64 ucontrol->value.iec958.status[0] = 0xff;
65 ucontrol->value.iec958.status[1] = 0xff;
66 ucontrol->value.iec958.status[2] = 0xff;
67 ucontrol->value.iec958.status[3] = 0xff;
68 return 0;
69}
70
71static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
72{
73 static char *texts[] = {"44100", "48000", "96000"};
74
75 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
76 uinfo->count = 1;
77 uinfo->value.enumerated.items = 3;
78 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
79 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
80 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
81 return 0;
82}
83
84static int snd_audigy_spdif_output_rate_get(snd_kcontrol_t * kcontrol,
85 snd_ctl_elem_value_t * ucontrol)
86{
87 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
88 unsigned int tmp;
89 unsigned long flags;
90
91
92 spin_lock_irqsave(&emu->reg_lock, flags);
93 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
94 switch (tmp & A_SPDIF_RATE_MASK) {
95 case A_SPDIF_44100:
96 ucontrol->value.enumerated.item[0] = 0;
97 break;
98 case A_SPDIF_48000:
99 ucontrol->value.enumerated.item[0] = 1;
100 break;
101 case A_SPDIF_96000:
102 ucontrol->value.enumerated.item[0] = 2;
103 break;
104 default:
105 ucontrol->value.enumerated.item[0] = 1;
106 }
107 spin_unlock_irqrestore(&emu->reg_lock, flags);
108 return 0;
109}
110
111static int snd_audigy_spdif_output_rate_put(snd_kcontrol_t * kcontrol,
112 snd_ctl_elem_value_t * ucontrol)
113{
114 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
115 int change;
116 unsigned int reg, val, tmp;
117 unsigned long flags;
118
119 switch(ucontrol->value.enumerated.item[0]) {
120 case 0:
121 val = A_SPDIF_44100;
122 break;
123 case 1:
124 val = A_SPDIF_48000;
125 break;
126 case 2:
127 val = A_SPDIF_96000;
128 break;
129 default:
130 val = A_SPDIF_48000;
131 break;
132 }
133
134
135 spin_lock_irqsave(&emu->reg_lock, flags);
136 reg = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
137 tmp = reg & ~A_SPDIF_RATE_MASK;
138 tmp |= val;
139 if ((change = (tmp != reg)))
140 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
141 spin_unlock_irqrestore(&emu->reg_lock, flags);
142 return change;
143}
144
145static snd_kcontrol_new_t snd_audigy_spdif_output_rate =
146{
147 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
148 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
149 .name = "Audigy SPDIF Output Sample Rate",
150 .count = 1,
151 .info = snd_audigy_spdif_output_rate_info,
152 .get = snd_audigy_spdif_output_rate_get,
153 .put = snd_audigy_spdif_output_rate_put
154};
155
156static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
157 snd_ctl_elem_value_t * ucontrol)
158{
159 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
160 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
161 int change;
162 unsigned int val;
163 unsigned long flags;
164
165 val = (ucontrol->value.iec958.status[0] << 0) |
166 (ucontrol->value.iec958.status[1] << 8) |
167 (ucontrol->value.iec958.status[2] << 16) |
168 (ucontrol->value.iec958.status[3] << 24);
169 spin_lock_irqsave(&emu->reg_lock, flags);
170 change = val != emu->spdif_bits[idx];
171 if (change) {
172 snd_emu10k1_ptr_write(emu, SPCS0 + idx, 0, val);
173 emu->spdif_bits[idx] = val;
174 }
175 spin_unlock_irqrestore(&emu->reg_lock, flags);
176 return change;
177}
178
179static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
180{
181 .access = SNDRV_CTL_ELEM_ACCESS_READ,
182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
183 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
184 .count = 4,
185 .info = snd_emu10k1_spdif_info,
186 .get = snd_emu10k1_spdif_get_mask
187};
188
189static snd_kcontrol_new_t snd_emu10k1_spdif_control =
190{
191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
192 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
193 .count = 4,
194 .info = snd_emu10k1_spdif_info,
195 .get = snd_emu10k1_spdif_get,
196 .put = snd_emu10k1_spdif_put
197};
198
199
200static void update_emu10k1_fxrt(emu10k1_t *emu, int voice, unsigned char *route)
201{
202 if (emu->audigy) {
203 snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
204 snd_emu10k1_compose_audigy_fxrt1(route));
205 snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
206 snd_emu10k1_compose_audigy_fxrt2(route));
207 } else {
208 snd_emu10k1_ptr_write(emu, FXRT, voice,
209 snd_emu10k1_compose_send_routing(route));
210 }
211}
212
213static void update_emu10k1_send_volume(emu10k1_t *emu, int voice, unsigned char *volume)
214{
215 snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_A, voice, volume[0]);
216 snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_B, voice, volume[1]);
217 snd_emu10k1_ptr_write(emu, PSST_FXSENDAMOUNT_C, voice, volume[2]);
218 snd_emu10k1_ptr_write(emu, DSL_FXSENDAMOUNT_D, voice, volume[3]);
219 if (emu->audigy) {
220 unsigned int val = ((unsigned int)volume[4] << 24) |
221 ((unsigned int)volume[5] << 16) |
222 ((unsigned int)volume[6] << 8) |
223 (unsigned int)volume[7];
224 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice, val);
225 }
226}
227
228/* PCM stream controls */
229
230static int snd_emu10k1_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
231{
232 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
233 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
234 uinfo->count = emu->audigy ? 3*8 : 3*4;
235 uinfo->value.integer.min = 0;
236 uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
237 return 0;
238}
239
240static int snd_emu10k1_send_routing_get(snd_kcontrol_t * kcontrol,
241 snd_ctl_elem_value_t * ucontrol)
242{
243 unsigned long flags;
244 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
245 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
246 int voice, idx;
247 int num_efx = emu->audigy ? 8 : 4;
248 int mask = emu->audigy ? 0x3f : 0x0f;
249
250 spin_lock_irqsave(&emu->reg_lock, flags);
251 for (voice = 0; voice < 3; voice++)
252 for (idx = 0; idx < num_efx; idx++)
253 ucontrol->value.integer.value[(voice * num_efx) + idx] =
254 mix->send_routing[voice][idx] & mask;
255 spin_unlock_irqrestore(&emu->reg_lock, flags);
256 return 0;
257}
258
259static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol,
260 snd_ctl_elem_value_t * ucontrol)
261{
262 unsigned long flags;
263 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
264 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
265 int change = 0, voice, idx, val;
266 int num_efx = emu->audigy ? 8 : 4;
267 int mask = emu->audigy ? 0x3f : 0x0f;
268
269 spin_lock_irqsave(&emu->reg_lock, flags);
270 for (voice = 0; voice < 3; voice++)
271 for (idx = 0; idx < num_efx; idx++) {
272 val = ucontrol->value.integer.value[(voice * num_efx) + idx] & mask;
273 if (mix->send_routing[voice][idx] != val) {
274 mix->send_routing[voice][idx] = val;
275 change = 1;
276 }
277 }
278 if (change && mix->epcm) {
279 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
280 update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
281 &mix->send_routing[1][0]);
282 update_emu10k1_fxrt(emu, mix->epcm->voices[1]->number,
283 &mix->send_routing[2][0]);
284 } else if (mix->epcm->voices[0]) {
285 update_emu10k1_fxrt(emu, mix->epcm->voices[0]->number,
286 &mix->send_routing[0][0]);
287 }
288 }
289 spin_unlock_irqrestore(&emu->reg_lock, flags);
290 return change;
291}
292
293static snd_kcontrol_new_t snd_emu10k1_send_routing_control =
294{
295 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
296 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
297 .name = "EMU10K1 PCM Send Routing",
298 .count = 32,
299 .info = snd_emu10k1_send_routing_info,
300 .get = snd_emu10k1_send_routing_get,
301 .put = snd_emu10k1_send_routing_put
302};
303
304static int snd_emu10k1_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
305{
306 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
307 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
308 uinfo->count = emu->audigy ? 3*8 : 3*4;
309 uinfo->value.integer.min = 0;
310 uinfo->value.integer.max = 255;
311 return 0;
312}
313
314static int snd_emu10k1_send_volume_get(snd_kcontrol_t * kcontrol,
315 snd_ctl_elem_value_t * ucontrol)
316{
317 unsigned long flags;
318 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
319 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
320 int idx;
321 int num_efx = emu->audigy ? 8 : 4;
322
323 spin_lock_irqsave(&emu->reg_lock, flags);
324 for (idx = 0; idx < 3*num_efx; idx++)
325 ucontrol->value.integer.value[idx] = mix->send_volume[idx/num_efx][idx%num_efx];
326 spin_unlock_irqrestore(&emu->reg_lock, flags);
327 return 0;
328}
329
330static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol,
331 snd_ctl_elem_value_t * ucontrol)
332{
333 unsigned long flags;
334 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
335 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
336 int change = 0, idx, val;
337 int num_efx = emu->audigy ? 8 : 4;
338
339 spin_lock_irqsave(&emu->reg_lock, flags);
340 for (idx = 0; idx < 3*num_efx; idx++) {
341 val = ucontrol->value.integer.value[idx] & 255;
342 if (mix->send_volume[idx/num_efx][idx%num_efx] != val) {
343 mix->send_volume[idx/num_efx][idx%num_efx] = val;
344 change = 1;
345 }
346 }
347 if (change && mix->epcm) {
348 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
349 update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
350 &mix->send_volume[1][0]);
351 update_emu10k1_send_volume(emu, mix->epcm->voices[1]->number,
352 &mix->send_volume[2][0]);
353 } else if (mix->epcm->voices[0]) {
354 update_emu10k1_send_volume(emu, mix->epcm->voices[0]->number,
355 &mix->send_volume[0][0]);
356 }
357 }
358 spin_unlock_irqrestore(&emu->reg_lock, flags);
359 return change;
360}
361
362static snd_kcontrol_new_t snd_emu10k1_send_volume_control =
363{
364 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
366 .name = "EMU10K1 PCM Send Volume",
367 .count = 32,
368 .info = snd_emu10k1_send_volume_info,
369 .get = snd_emu10k1_send_volume_get,
370 .put = snd_emu10k1_send_volume_put
371};
372
373static int snd_emu10k1_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
374{
375 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
376 uinfo->count = 3;
377 uinfo->value.integer.min = 0;
378 uinfo->value.integer.max = 0xffff;
379 return 0;
380}
381
382static int snd_emu10k1_attn_get(snd_kcontrol_t * kcontrol,
383 snd_ctl_elem_value_t * ucontrol)
384{
385 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
386 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
387 unsigned long flags;
388 int idx;
389
390 spin_lock_irqsave(&emu->reg_lock, flags);
391 for (idx = 0; idx < 3; idx++)
392 ucontrol->value.integer.value[idx] = mix->attn[idx];
393 spin_unlock_irqrestore(&emu->reg_lock, flags);
394 return 0;
395}
396
397static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol,
398 snd_ctl_elem_value_t * ucontrol)
399{
400 unsigned long flags;
401 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
402 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
403 int change = 0, idx, val;
404
405 spin_lock_irqsave(&emu->reg_lock, flags);
406 for (idx = 0; idx < 3; idx++) {
407 val = ucontrol->value.integer.value[idx] & 0xffff;
408 if (mix->attn[idx] != val) {
409 mix->attn[idx] = val;
410 change = 1;
411 }
412 }
413 if (change && mix->epcm) {
414 if (mix->epcm->voices[0] && mix->epcm->voices[1]) {
415 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[1]);
416 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[1]->number, mix->attn[2]);
417 } else if (mix->epcm->voices[0]) {
418 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[0]->number, mix->attn[0]);
419 }
420 }
421 spin_unlock_irqrestore(&emu->reg_lock, flags);
422 return change;
423}
424
425static snd_kcontrol_new_t snd_emu10k1_attn_control =
426{
427 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
429 .name = "EMU10K1 PCM Volume",
430 .count = 32,
431 .info = snd_emu10k1_attn_info,
432 .get = snd_emu10k1_attn_get,
433 .put = snd_emu10k1_attn_put
434};
435
436/* Mutichannel PCM stream controls */
437
438static int snd_emu10k1_efx_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
439{
440 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
441 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
442 uinfo->count = emu->audigy ? 8 : 4;
443 uinfo->value.integer.min = 0;
444 uinfo->value.integer.max = emu->audigy ? 0x3f : 0x0f;
445 return 0;
446}
447
448static int snd_emu10k1_efx_send_routing_get(snd_kcontrol_t * kcontrol,
449 snd_ctl_elem_value_t * ucontrol)
450{
451 unsigned long flags;
452 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
453 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
454 int idx;
455 int num_efx = emu->audigy ? 8 : 4;
456 int mask = emu->audigy ? 0x3f : 0x0f;
457
458 spin_lock_irqsave(&emu->reg_lock, flags);
459 for (idx = 0; idx < num_efx; idx++)
460 ucontrol->value.integer.value[idx] =
461 mix->send_routing[0][idx] & mask;
462 spin_unlock_irqrestore(&emu->reg_lock, flags);
463 return 0;
464}
465
466static int snd_emu10k1_efx_send_routing_put(snd_kcontrol_t * kcontrol,
467 snd_ctl_elem_value_t * ucontrol)
468{
469 unsigned long flags;
470 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
471 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
472 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
473 int change = 0, idx, val;
474 int num_efx = emu->audigy ? 8 : 4;
475 int mask = emu->audigy ? 0x3f : 0x0f;
476
477 spin_lock_irqsave(&emu->reg_lock, flags);
478 for (idx = 0; idx < num_efx; idx++) {
479 val = ucontrol->value.integer.value[idx] & mask;
480 if (mix->send_routing[0][idx] != val) {
481 mix->send_routing[0][idx] = val;
482 change = 1;
483 }
484 }
485
486 if (change && mix->epcm) {
487 if (mix->epcm->voices[ch]) {
488 update_emu10k1_fxrt(emu, mix->epcm->voices[ch]->number,
489 &mix->send_routing[0][0]);
490 }
491 }
492 spin_unlock_irqrestore(&emu->reg_lock, flags);
493 return change;
494}
495
496static snd_kcontrol_new_t snd_emu10k1_efx_send_routing_control =
497{
498 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
499 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
500 .name = "Multichannel PCM Send Routing",
501 .count = 16,
502 .info = snd_emu10k1_efx_send_routing_info,
503 .get = snd_emu10k1_efx_send_routing_get,
504 .put = snd_emu10k1_efx_send_routing_put
505};
506
507static int snd_emu10k1_efx_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
508{
509 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
510 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
511 uinfo->count = emu->audigy ? 8 : 4;
512 uinfo->value.integer.min = 0;
513 uinfo->value.integer.max = 255;
514 return 0;
515}
516
517static int snd_emu10k1_efx_send_volume_get(snd_kcontrol_t * kcontrol,
518 snd_ctl_elem_value_t * ucontrol)
519{
520 unsigned long flags;
521 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
522 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
523 int idx;
524 int num_efx = emu->audigy ? 8 : 4;
525
526 spin_lock_irqsave(&emu->reg_lock, flags);
527 for (idx = 0; idx < num_efx; idx++)
528 ucontrol->value.integer.value[idx] = mix->send_volume[0][idx];
529 spin_unlock_irqrestore(&emu->reg_lock, flags);
530 return 0;
531}
532
533static int snd_emu10k1_efx_send_volume_put(snd_kcontrol_t * kcontrol,
534 snd_ctl_elem_value_t * ucontrol)
535{
536 unsigned long flags;
537 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
538 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
539 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
540 int change = 0, idx, val;
541 int num_efx = emu->audigy ? 8 : 4;
542
543 spin_lock_irqsave(&emu->reg_lock, flags);
544 for (idx = 0; idx < num_efx; idx++) {
545 val = ucontrol->value.integer.value[idx] & 255;
546 if (mix->send_volume[0][idx] != val) {
547 mix->send_volume[0][idx] = val;
548 change = 1;
549 }
550 }
551 if (change && mix->epcm) {
552 if (mix->epcm->voices[ch]) {
553 update_emu10k1_send_volume(emu, mix->epcm->voices[ch]->number,
554 &mix->send_volume[0][0]);
555 }
556 }
557 spin_unlock_irqrestore(&emu->reg_lock, flags);
558 return change;
559}
560
561
562static snd_kcontrol_new_t snd_emu10k1_efx_send_volume_control =
563{
564 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
565 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
566 .name = "Multichannel PCM Send Volume",
567 .count = 16,
568 .info = snd_emu10k1_efx_send_volume_info,
569 .get = snd_emu10k1_efx_send_volume_get,
570 .put = snd_emu10k1_efx_send_volume_put
571};
572
573static int snd_emu10k1_efx_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
574{
575 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
576 uinfo->count = 1;
577 uinfo->value.integer.min = 0;
578 uinfo->value.integer.max = 0xffff;
579 return 0;
580}
581
582static int snd_emu10k1_efx_attn_get(snd_kcontrol_t * kcontrol,
583 snd_ctl_elem_value_t * ucontrol)
584{
585 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
586 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
587 unsigned long flags;
588
589 spin_lock_irqsave(&emu->reg_lock, flags);
590 ucontrol->value.integer.value[0] = mix->attn[0];
591 spin_unlock_irqrestore(&emu->reg_lock, flags);
592 return 0;
593}
594
595static int snd_emu10k1_efx_attn_put(snd_kcontrol_t * kcontrol,
596 snd_ctl_elem_value_t * ucontrol)
597{
598 unsigned long flags;
599 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
600 int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
601 emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
602 int change = 0, val;
603
604 spin_lock_irqsave(&emu->reg_lock, flags);
605 val = ucontrol->value.integer.value[0] & 0xffff;
606 if (mix->attn[0] != val) {
607 mix->attn[0] = val;
608 change = 1;
609 }
610 if (change && mix->epcm) {
611 if (mix->epcm->voices[ch]) {
612 snd_emu10k1_ptr_write(emu, VTFT_VOLUMETARGET, mix->epcm->voices[ch]->number, mix->attn[0]);
613 }
614 }
615 spin_unlock_irqrestore(&emu->reg_lock, flags);
616 return change;
617}
618
619static snd_kcontrol_new_t snd_emu10k1_efx_attn_control =
620{
621 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
622 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
623 .name = "Multichannel PCM Volume",
624 .count = 16,
625 .info = snd_emu10k1_efx_attn_info,
626 .get = snd_emu10k1_efx_attn_get,
627 .put = snd_emu10k1_efx_attn_put
628};
629
630static int snd_emu10k1_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
631{
632 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
633 uinfo->count = 1;
634 uinfo->value.integer.min = 0;
635 uinfo->value.integer.max = 1;
636 return 0;
637}
638
639static int snd_emu10k1_shared_spdif_get(snd_kcontrol_t * kcontrol,
640 snd_ctl_elem_value_t * ucontrol)
641{
642 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
643
644 if (emu->audigy)
645 ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
646 else
647 ucontrol->value.integer.value[0] = inl(emu->port + HCFG) & HCFG_GPOUT0 ? 1 : 0;
648 return 0;
649}
650
651static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol,
652 snd_ctl_elem_value_t * ucontrol)
653{
654 unsigned long flags;
655 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
656 unsigned int reg, val;
657 int change = 0;
658
659 spin_lock_irqsave(&emu->reg_lock, flags);
660 if (emu->audigy) {
661 reg = inl(emu->port + A_IOCFG);
662 val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
663 change = (reg & A_IOCFG_GPOUT0) != val;
664 if (change) {
665 reg &= ~A_IOCFG_GPOUT0;
666 reg |= val;
667 outl(reg | val, emu->port + A_IOCFG);
668 }
669 }
670 reg = inl(emu->port + HCFG);
671 val = ucontrol->value.integer.value[0] ? HCFG_GPOUT0 : 0;
672 change |= (reg & HCFG_GPOUT0) != val;
673 if (change) {
674 reg &= ~HCFG_GPOUT0;
675 reg |= val;
676 outl(reg | val, emu->port + HCFG);
677 }
678 spin_unlock_irqrestore(&emu->reg_lock, flags);
679 return change;
680}
681
682static snd_kcontrol_new_t snd_emu10k1_shared_spdif __devinitdata =
683{
684 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
685 .name = "SB Live Analog/Digital Output Jack",
686 .info = snd_emu10k1_shared_spdif_info,
687 .get = snd_emu10k1_shared_spdif_get,
688 .put = snd_emu10k1_shared_spdif_put
689};
690
691static snd_kcontrol_new_t snd_audigy_shared_spdif __devinitdata =
692{
693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
694 .name = "Audigy Analog/Digital Output Jack",
695 .info = snd_emu10k1_shared_spdif_info,
696 .get = snd_emu10k1_shared_spdif_get,
697 .put = snd_emu10k1_shared_spdif_put
698};
699
700/*
701 */
702static void snd_emu10k1_mixer_free_ac97(ac97_t *ac97)
703{
704 emu10k1_t *emu = ac97->private_data;
705 emu->ac97 = NULL;
706}
707
708/*
709 */
710static int remove_ctl(snd_card_t *card, const char *name)
711{
712 snd_ctl_elem_id_t id;
713 memset(&id, 0, sizeof(id));
714 strcpy(id.name, name);
715 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
716 return snd_ctl_remove_id(card, &id);
717}
718
719static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name)
720{
721 snd_ctl_elem_id_t sid;
722 memset(&sid, 0, sizeof(sid));
723 strcpy(sid.name, name);
724 sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
725 return snd_ctl_find_id(card, &sid);
726}
727
728static int rename_ctl(snd_card_t *card, const char *src, const char *dst)
729{
730 snd_kcontrol_t *kctl = ctl_find(card, src);
731 if (kctl) {
732 strcpy(kctl->id.name, dst);
733 return 0;
734 }
735 return -ENOENT;
736}
737
738int __devinit snd_emu10k1_mixer(emu10k1_t *emu)
739{
740 int err, pcm;
741 snd_kcontrol_t *kctl;
742 snd_card_t *card = emu->card;
743 char **c;
744 static char *emu10k1_remove_ctls[] = {
745 /* no AC97 mono, surround, center/lfe */
746 "Master Mono Playback Switch",
747 "Master Mono Playback Volume",
748 "PCM Out Path & Mute",
749 "Mono Output Select",
750 "Surround Playback Switch",
751 "Surround Playback Volume",
752 "Center Playback Switch",
753 "Center Playback Volume",
754 "LFE Playback Switch",
755 "LFE Playback Volume",
756 NULL
757 };
758 static char *emu10k1_rename_ctls[] = {
759 "Surround Digital Playback Volume", "Surround Playback Volume",
760 "Center Digital Playback Volume", "Center Playback Volume",
761 "LFE Digital Playback Volume", "LFE Playback Volume",
762 NULL
763 };
764 static char *audigy_remove_ctls[] = {
765 /* Master/PCM controls on ac97 of Audigy has no effect */
766 "PCM Playback Switch",
767 "PCM Playback Volume",
768 "Master Mono Playback Switch",
769 "Master Mono Playback Volume",
770 "Master Playback Switch",
771 "Master Playback Volume",
772 "PCM Out Path & Mute",
773 "Mono Output Select",
774 /* remove unused AC97 capture controls */
775 "Capture Source",
776 "Capture Switch",
777 "Capture Volume",
778 "Mic Select",
779 "Video Playback Switch",
780 "Video Playback Volume",
781 "Mic Playback Switch",
782 "Mic Playback Volume",
783 NULL
784 };
785 static char *audigy_rename_ctls[] = {
786 /* use conventional names */
787 "Wave Playback Volume", "PCM Playback Volume",
788 /* "Wave Capture Volume", "PCM Capture Volume", */
789 "Wave Master Playback Volume", "Master Playback Volume",
790 "AMic Playback Volume", "Mic Playback Volume",
791 NULL
792 };
793
794 if (!emu->no_ac97) {
795 ac97_bus_t *pbus;
796 ac97_template_t ac97;
797 static ac97_bus_ops_t ops = {
798 .write = snd_emu10k1_ac97_write,
799 .read = snd_emu10k1_ac97_read,
800 };
801
802 if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
803 return err;
804 pbus->no_vra = 1; /* we don't need VRA */
805
806 memset(&ac97, 0, sizeof(ac97));
807 ac97.private_data = emu;
808 ac97.private_free = snd_emu10k1_mixer_free_ac97;
809 ac97.scaps = AC97_SCAP_NO_SPDIF;
810 if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0)
811 return err;
812 if (emu->audigy) {
813 /* set master volume to 0 dB */
814 snd_ac97_write(emu->ac97, AC97_MASTER, 0x0000);
815 /* set capture source to mic */
816 snd_ac97_write(emu->ac97, AC97_REC_SEL, 0x0000);
817 c = audigy_remove_ctls;
818 } else {
819 /*
820 * Credits for cards based on STAC9758:
821 * James Courtier-Dutton <James@superbug.demon.co.uk>
822 * Voluspa <voluspa@comhem.se>
823 */
824 if (emu->ac97->id == AC97_ID_STAC9758) {
825 emu->rear_ac97 = 1;
826 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
827 }
828 /* remove unused AC97 controls */
829 snd_ac97_write(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
830 snd_ac97_write(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
831 c = emu10k1_remove_ctls;
832 }
833 for (; *c; c++)
834 remove_ctl(card, *c);
835 } else {
836 if (emu->APS)
837 strcpy(emu->card->mixername, "EMU APS");
838 else if (emu->audigy)
839 strcpy(emu->card->mixername, "SB Audigy");
840 else
841 strcpy(emu->card->mixername, "Emu10k1");
842 }
843
844 if (emu->audigy)
845 c = audigy_rename_ctls;
846 else
847 c = emu10k1_rename_ctls;
848 for (; *c; c += 2)
849 rename_ctl(card, c[0], c[1]);
850
851 if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
852 return -ENOMEM;
853 if ((err = snd_ctl_add(card, kctl)))
854 return err;
855 if ((kctl = emu->ctl_send_volume = snd_ctl_new1(&snd_emu10k1_send_volume_control, emu)) == NULL)
856 return -ENOMEM;
857 if ((err = snd_ctl_add(card, kctl)))
858 return err;
859 if ((kctl = emu->ctl_attn = snd_ctl_new1(&snd_emu10k1_attn_control, emu)) == NULL)
860 return -ENOMEM;
861 if ((err = snd_ctl_add(card, kctl)))
862 return err;
863
864 if ((kctl = emu->ctl_efx_send_routing = snd_ctl_new1(&snd_emu10k1_efx_send_routing_control, emu)) == NULL)
865 return -ENOMEM;
866 if ((err = snd_ctl_add(card, kctl)))
867 return err;
868
869 if ((kctl = emu->ctl_efx_send_volume = snd_ctl_new1(&snd_emu10k1_efx_send_volume_control, emu)) == NULL)
870 return -ENOMEM;
871 if ((err = snd_ctl_add(card, kctl)))
872 return err;
873
874 if ((kctl = emu->ctl_efx_attn = snd_ctl_new1(&snd_emu10k1_efx_attn_control, emu)) == NULL)
875 return -ENOMEM;
876 if ((err = snd_ctl_add(card, kctl)))
877 return err;
878
879 /* initialize the routing and volume table for each pcm playback stream */
880 for (pcm = 0; pcm < 32; pcm++) {
881 emu10k1_pcm_mixer_t *mix;
882 int v;
883
884 mix = &emu->pcm_mixer[pcm];
885 mix->epcm = NULL;
886
887 for (v = 0; v < 4; v++)
888 mix->send_routing[0][v] =
889 mix->send_routing[1][v] =
890 mix->send_routing[2][v] = v;
891
892 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
893 mix->send_volume[0][0] = mix->send_volume[0][1] =
894 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
895
896 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
897 }
898
899 /* initialize the routing and volume table for the multichannel playback stream */
900 for (pcm = 0; pcm < NUM_EFX_PLAYBACK; pcm++) {
901 emu10k1_pcm_mixer_t *mix;
902 int v;
903
904 mix = &emu->efx_pcm_mixer[pcm];
905 mix->epcm = NULL;
906
907 mix->send_routing[0][0] = pcm;
908 mix->send_routing[0][1] = (pcm == 0) ? 1 : 0;
909 for (v = 0; v < 2; v++)
910 mix->send_routing[0][2+v] = 13+v;
911 if (emu->audigy)
912 for (v = 0; v < 4; v++)
913 mix->send_routing[0][4+v] = 60+v;
914
915 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
916 mix->send_volume[0][0] = 255;
917
918 mix->attn[0] = 0xffff;
919 }
920
921 if (! emu->APS) { /* FIXME: APS has these controls? */
922 /* sb live! and audigy */
923 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
924 return -ENOMEM;
925 if ((err = snd_ctl_add(card, kctl)))
926 return err;
927 if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_control, emu)) == NULL)
928 return -ENOMEM;
929 if ((err = snd_ctl_add(card, kctl)))
930 return err;
931 }
932
933 if (emu->audigy) {
934 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
935 return -ENOMEM;
936 if ((err = snd_ctl_add(card, kctl)))
937 return err;
938 if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
939 return -ENOMEM;
940 if ((err = snd_ctl_add(card, kctl)))
941 return err;
942 } else if (! emu->APS) {
943 /* sb live! */
944 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
945 return -ENOMEM;
946 if ((err = snd_ctl_add(card, kctl)))
947 return err;
948 }
949 if (emu->audigy && emu->revision == 4) { /* P16V */
950 if ((err = snd_p16v_mixer(emu)))
951 return err;
952 }
953
954 return 0;
955}
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
new file mode 100644
index 000000000000..eb57458a9665
--- /dev/null
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -0,0 +1,374 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Routines for control of EMU10K1 MPU-401 in UART mode
4 *
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <sound/driver.h>
23#include <linux/time.h>
24#include <linux/init.h>
25#include <sound/core.h>
26#include <sound/emu10k1.h>
27
28#define EMU10K1_MIDI_MODE_INPUT (1<<0)
29#define EMU10K1_MIDI_MODE_OUTPUT (1<<1)
30
31static inline unsigned char mpu401_read(emu10k1_t *emu, emu10k1_midi_t *mpu, int idx)
32{
33 if (emu->audigy)
34 return (unsigned char)snd_emu10k1_ptr_read(emu, mpu->port + idx, 0);
35 else
36 return inb(emu->port + mpu->port + idx);
37}
38
39static inline void mpu401_write(emu10k1_t *emu, emu10k1_midi_t *mpu, int data, int idx)
40{
41 if (emu->audigy)
42 snd_emu10k1_ptr_write(emu, mpu->port + idx, 0, data);
43 else
44 outb(data, emu->port + mpu->port + idx);
45}
46
47#define mpu401_write_data(emu, mpu, data) mpu401_write(emu, mpu, data, 0)
48#define mpu401_write_cmd(emu, mpu, data) mpu401_write(emu, mpu, data, 1)
49#define mpu401_read_data(emu, mpu) mpu401_read(emu, mpu, 0)
50#define mpu401_read_stat(emu, mpu) mpu401_read(emu, mpu, 1)
51
52#define mpu401_input_avail(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x80))
53#define mpu401_output_ready(emu,mpu) (!(mpu401_read_stat(emu,mpu) & 0x40))
54
55#define MPU401_RESET 0xff
56#define MPU401_ENTER_UART 0x3f
57#define MPU401_ACK 0xfe
58
59static void mpu401_clear_rx(emu10k1_t *emu, emu10k1_midi_t *mpu)
60{
61 int timeout = 100000;
62 for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
63 mpu401_read_data(emu, mpu);
64#ifdef CONFIG_SND_DEBUG
65 if (timeout <= 0)
66 snd_printk(KERN_ERR "cmd: clear rx timeout (status = 0x%x)\n", mpu401_read_stat(emu, mpu));
67#endif
68}
69
70/*
71
72 */
73
74static void do_emu10k1_midi_interrupt(emu10k1_t *emu, emu10k1_midi_t *midi, unsigned int status)
75{
76 unsigned char byte;
77
78 if (midi->rmidi == NULL) {
79 snd_emu10k1_intr_disable(emu, midi->tx_enable | midi->rx_enable);
80 return;
81 }
82
83 spin_lock(&midi->input_lock);
84 if ((status & midi->ipr_rx) && mpu401_input_avail(emu, midi)) {
85 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
86 mpu401_clear_rx(emu, midi);
87 } else {
88 byte = mpu401_read_data(emu, midi);
89 if (midi->substream_input)
90 snd_rawmidi_receive(midi->substream_input, &byte, 1);
91 }
92 }
93 spin_unlock(&midi->input_lock);
94
95 spin_lock(&midi->output_lock);
96 if ((status & midi->ipr_tx) && mpu401_output_ready(emu, midi)) {
97 if (midi->substream_output &&
98 snd_rawmidi_transmit(midi->substream_output, &byte, 1) == 1) {
99 mpu401_write_data(emu, midi, byte);
100 } else {
101 snd_emu10k1_intr_disable(emu, midi->tx_enable);
102 }
103 }
104 spin_unlock(&midi->output_lock);
105}
106
107static void snd_emu10k1_midi_interrupt(emu10k1_t *emu, unsigned int status)
108{
109 do_emu10k1_midi_interrupt(emu, &emu->midi, status);
110}
111
112static void snd_emu10k1_midi_interrupt2(emu10k1_t *emu, unsigned int status)
113{
114 do_emu10k1_midi_interrupt(emu, &emu->midi2, status);
115}
116
117static void snd_emu10k1_midi_cmd(emu10k1_t * emu, emu10k1_midi_t *midi, unsigned char cmd, int ack)
118{
119 unsigned long flags;
120 int timeout, ok;
121
122 spin_lock_irqsave(&midi->input_lock, flags);
123 mpu401_write_data(emu, midi, 0x00);
124 /* mpu401_clear_rx(emu, midi); */
125
126 mpu401_write_cmd(emu, midi, cmd);
127 if (ack) {
128 ok = 0;
129 timeout = 10000;
130 while (!ok && timeout-- > 0) {
131 if (mpu401_input_avail(emu, midi)) {
132 if (mpu401_read_data(emu, midi) == MPU401_ACK)
133 ok = 1;
134 }
135 }
136 if (!ok && mpu401_read_data(emu, midi) == MPU401_ACK)
137 ok = 1;
138 } else {
139 ok = 1;
140 }
141 spin_unlock_irqrestore(&midi->input_lock, flags);
142 if (!ok)
143 snd_printk(KERN_ERR "midi_cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)!!!\n",
144 cmd, emu->port,
145 mpu401_read_stat(emu, midi),
146 mpu401_read_data(emu, midi));
147}
148
149static int snd_emu10k1_midi_input_open(snd_rawmidi_substream_t * substream)
150{
151 emu10k1_t *emu;
152 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
153 unsigned long flags;
154
155 emu = midi->emu;
156 snd_assert(emu, return -ENXIO);
157 spin_lock_irqsave(&midi->open_lock, flags);
158 midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT;
159 midi->substream_input = substream;
160 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
161 spin_unlock_irqrestore(&midi->open_lock, flags);
162 snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1);
163 snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
164 } else {
165 spin_unlock_irqrestore(&midi->open_lock, flags);
166 }
167 return 0;
168}
169
170static int snd_emu10k1_midi_output_open(snd_rawmidi_substream_t * substream)
171{
172 emu10k1_t *emu;
173 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
174 unsigned long flags;
175
176 emu = midi->emu;
177 snd_assert(emu, return -ENXIO);
178 spin_lock_irqsave(&midi->open_lock, flags);
179 midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT;
180 midi->substream_output = substream;
181 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
182 spin_unlock_irqrestore(&midi->open_lock, flags);
183 snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 1);
184 snd_emu10k1_midi_cmd(emu, midi, MPU401_ENTER_UART, 1);
185 } else {
186 spin_unlock_irqrestore(&midi->open_lock, flags);
187 }
188 return 0;
189}
190
191static int snd_emu10k1_midi_input_close(snd_rawmidi_substream_t * substream)
192{
193 emu10k1_t *emu;
194 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
195 unsigned long flags;
196
197 emu = midi->emu;
198 snd_assert(emu, return -ENXIO);
199 spin_lock_irqsave(&midi->open_lock, flags);
200 snd_emu10k1_intr_disable(emu, midi->rx_enable);
201 midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT;
202 midi->substream_input = NULL;
203 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT)) {
204 spin_unlock_irqrestore(&midi->open_lock, flags);
205 snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
206 } else {
207 spin_unlock_irqrestore(&midi->open_lock, flags);
208 }
209 return 0;
210}
211
212static int snd_emu10k1_midi_output_close(snd_rawmidi_substream_t * substream)
213{
214 emu10k1_t *emu;
215 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
216 unsigned long flags;
217
218 emu = midi->emu;
219 snd_assert(emu, return -ENXIO);
220 spin_lock_irqsave(&midi->open_lock, flags);
221 snd_emu10k1_intr_disable(emu, midi->tx_enable);
222 midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT;
223 midi->substream_output = NULL;
224 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_INPUT)) {
225 spin_unlock_irqrestore(&midi->open_lock, flags);
226 snd_emu10k1_midi_cmd(emu, midi, MPU401_RESET, 0);
227 } else {
228 spin_unlock_irqrestore(&midi->open_lock, flags);
229 }
230 return 0;
231}
232
233static void snd_emu10k1_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
234{
235 emu10k1_t *emu;
236 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
237 emu = midi->emu;
238 snd_assert(emu, return);
239
240 if (up)
241 snd_emu10k1_intr_enable(emu, midi->rx_enable);
242 else
243 snd_emu10k1_intr_disable(emu, midi->rx_enable);
244}
245
246static void snd_emu10k1_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
247{
248 emu10k1_t *emu;
249 emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
250 unsigned long flags;
251
252 emu = midi->emu;
253 snd_assert(emu, return);
254
255 if (up) {
256 int max = 4;
257 unsigned char byte;
258
259 /* try to send some amount of bytes here before interrupts */
260 spin_lock_irqsave(&midi->output_lock, flags);
261 while (max > 0) {
262 if (mpu401_output_ready(emu, midi)) {
263 if (!(midi->midi_mode & EMU10K1_MIDI_MODE_OUTPUT) ||
264 snd_rawmidi_transmit(substream, &byte, 1) != 1) {
265 /* no more data */
266 spin_unlock_irqrestore(&midi->output_lock, flags);
267 return;
268 }
269 mpu401_write_data(emu, midi, byte);
270 max--;
271 } else {
272 break;
273 }
274 }
275 spin_unlock_irqrestore(&midi->output_lock, flags);
276 snd_emu10k1_intr_enable(emu, midi->tx_enable);
277 } else {
278 snd_emu10k1_intr_disable(emu, midi->tx_enable);
279 }
280}
281
282/*
283
284 */
285
286static snd_rawmidi_ops_t snd_emu10k1_midi_output =
287{
288 .open = snd_emu10k1_midi_output_open,
289 .close = snd_emu10k1_midi_output_close,
290 .trigger = snd_emu10k1_midi_output_trigger,
291};
292
293static snd_rawmidi_ops_t snd_emu10k1_midi_input =
294{
295 .open = snd_emu10k1_midi_input_open,
296 .close = snd_emu10k1_midi_input_close,
297 .trigger = snd_emu10k1_midi_input_trigger,
298};
299
300static void snd_emu10k1_midi_free(snd_rawmidi_t *rmidi)
301{
302 emu10k1_midi_t *midi = (emu10k1_midi_t *)rmidi->private_data;
303 midi->interrupt = NULL;
304 midi->rmidi = NULL;
305}
306
307static int __devinit emu10k1_midi_init(emu10k1_t *emu, emu10k1_midi_t *midi, int device, char *name)
308{
309 snd_rawmidi_t *rmidi;
310 int err;
311
312 if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
313 return err;
314 midi->emu = emu;
315 spin_lock_init(&midi->open_lock);
316 spin_lock_init(&midi->input_lock);
317 spin_lock_init(&midi->output_lock);
318 strcpy(rmidi->name, name);
319 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_emu10k1_midi_output);
320 snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_emu10k1_midi_input);
321 rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
322 SNDRV_RAWMIDI_INFO_INPUT |
323 SNDRV_RAWMIDI_INFO_DUPLEX;
324 rmidi->private_data = midi;
325 rmidi->private_free = snd_emu10k1_midi_free;
326 midi->rmidi = rmidi;
327 return 0;
328}
329
330int __devinit snd_emu10k1_midi(emu10k1_t *emu)
331{
332 emu10k1_midi_t *midi = &emu->midi;
333 int err;
334
335 if ((err = emu10k1_midi_init(emu, midi, 0, "EMU10K1 MPU-401 (UART)")) < 0)
336 return err;
337
338 midi->tx_enable = INTE_MIDITXENABLE;
339 midi->rx_enable = INTE_MIDIRXENABLE;
340 midi->port = MUDATA;
341 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
342 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
343 midi->interrupt = snd_emu10k1_midi_interrupt;
344 return 0;
345}
346
347int __devinit snd_emu10k1_audigy_midi(emu10k1_t *emu)
348{
349 emu10k1_midi_t *midi;
350 int err;
351
352 midi = &emu->midi;
353 if ((err = emu10k1_midi_init(emu, midi, 0, "Audigy MPU-401 (UART)")) < 0)
354 return err;
355
356 midi->tx_enable = INTE_MIDITXENABLE;
357 midi->rx_enable = INTE_MIDIRXENABLE;
358 midi->port = A_MUDATA1;
359 midi->ipr_tx = IPR_MIDITRANSBUFEMPTY;
360 midi->ipr_rx = IPR_MIDIRECVBUFEMPTY;
361 midi->interrupt = snd_emu10k1_midi_interrupt;
362
363 midi = &emu->midi2;
364 if ((err = emu10k1_midi_init(emu, midi, 1, "Audigy MPU-401 #2")) < 0)
365 return err;
366
367 midi->tx_enable = INTE_A_MIDITXENABLE2;
368 midi->rx_enable = INTE_A_MIDIRXENABLE2;
369 midi->port = A_MUDATA2;
370 midi->ipr_tx = IPR_A_MIDITRANSBUFEMPTY2;
371 midi->ipr_rx = IPR_A_MIDIRECVBUFEMPTY2;
372 midi->interrupt = snd_emu10k1_midi_interrupt2;
373 return 0;
374}
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
new file mode 100644
index 000000000000..d1c2a02c486b
--- /dev/null
+++ b/sound/pci/emu10k1/emupcm.c
@@ -0,0 +1,1724 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips / PCM routines
5 * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
6 *
7 * BUGS:
8 * --
9 *
10 * TODO:
11 * --
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27 */
28
29#include <sound/driver.h>
30#include <linux/pci.h>
31#include <linux/delay.h>
32#include <linux/slab.h>
33#include <linux/time.h>
34#include <linux/init.h>
35#include <sound/core.h>
36#include <sound/emu10k1.h>
37
38static void snd_emu10k1_pcm_interrupt(emu10k1_t *emu, emu10k1_voice_t *voice)
39{
40 emu10k1_pcm_t *epcm;
41
42 if ((epcm = voice->epcm) == NULL)
43 return;
44 if (epcm->substream == NULL)
45 return;
46#if 0
47 printk("IRQ: position = 0x%x, period = 0x%x, size = 0x%x\n",
48 epcm->substream->runtime->hw->pointer(emu, epcm->substream),
49 snd_pcm_lib_period_bytes(epcm->substream),
50 snd_pcm_lib_buffer_bytes(epcm->substream));
51#endif
52 snd_pcm_period_elapsed(epcm->substream);
53}
54
55static void snd_emu10k1_pcm_ac97adc_interrupt(emu10k1_t *emu, unsigned int status)
56{
57#if 0
58 if (status & IPR_ADCBUFHALFFULL) {
59 if (emu->pcm_capture_substream->runtime->mode == SNDRV_PCM_MODE_FRAME)
60 return;
61 }
62#endif
63 snd_pcm_period_elapsed(emu->pcm_capture_substream);
64}
65
66static void snd_emu10k1_pcm_ac97mic_interrupt(emu10k1_t *emu, unsigned int status)
67{
68#if 0
69 if (status & IPR_MICBUFHALFFULL) {
70 if (emu->pcm_capture_mic_substream->runtime->mode == SNDRV_PCM_MODE_FRAME)
71 return;
72 }
73#endif
74 snd_pcm_period_elapsed(emu->pcm_capture_mic_substream);
75}
76
77static void snd_emu10k1_pcm_efx_interrupt(emu10k1_t *emu, unsigned int status)
78{
79#if 0
80 if (status & IPR_EFXBUFHALFFULL) {
81 if (emu->pcm_capture_efx_substream->runtime->mode == SNDRV_PCM_MODE_FRAME)
82 return;
83 }
84#endif
85 snd_pcm_period_elapsed(emu->pcm_capture_efx_substream);
86}
87
88static snd_pcm_uframes_t snd_emu10k1_efx_playback_pointer(snd_pcm_substream_t * substream)
89{
90 emu10k1_t *emu = snd_pcm_substream_chip(substream);
91 snd_pcm_runtime_t *runtime = substream->runtime;
92 emu10k1_pcm_t *epcm = runtime->private_data;
93 unsigned int ptr;
94
95 if (!epcm->running)
96 return 0;
97 ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->voices[0]->number) & 0x00ffffff;
98 ptr += runtime->buffer_size;
99 ptr -= epcm->ccca_start_addr;
100 ptr %= runtime->buffer_size;
101
102 return ptr;
103}
104
105static int snd_emu10k1_pcm_channel_alloc(emu10k1_pcm_t * epcm, int voices)
106{
107 int err, i;
108
109 if (epcm->voices[1] != NULL && voices < 2) {
110 snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
111 epcm->voices[1] = NULL;
112 }
113 for (i = 0; i < voices; i++) {
114 if (epcm->voices[i] == NULL)
115 break;
116 }
117 if (i == voices)
118 return 0; /* already allocated */
119
120 for (i = 0; i < ARRAY_SIZE(epcm->voices); i++) {
121 if (epcm->voices[i]) {
122 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
123 epcm->voices[i] = NULL;
124 }
125 }
126 err = snd_emu10k1_voice_alloc(epcm->emu,
127 epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX,
128 voices,
129 &epcm->voices[0]);
130
131 if (err < 0)
132 return err;
133 epcm->voices[0]->epcm = epcm;
134 if (voices > 1) {
135 for (i = 1; i < voices; i++) {
136 epcm->voices[i] = &epcm->emu->voices[epcm->voices[0]->number + i];
137 epcm->voices[i]->epcm = epcm;
138 }
139 }
140 if (epcm->extra == NULL) {
141 err = snd_emu10k1_voice_alloc(epcm->emu,
142 epcm->type == PLAYBACK_EMUVOICE ? EMU10K1_PCM : EMU10K1_EFX,
143 1,
144 &epcm->extra);
145 if (err < 0) {
146 // printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame);
147 for (i = 0; i < voices; i++) {
148 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
149 epcm->voices[i] = NULL;
150 }
151 return err;
152 }
153 epcm->extra->epcm = epcm;
154 epcm->extra->interrupt = snd_emu10k1_pcm_interrupt;
155 }
156 return 0;
157}
158
159static unsigned int capture_period_sizes[31] = {
160 384, 448, 512, 640,
161 384*2, 448*2, 512*2, 640*2,
162 384*4, 448*4, 512*4, 640*4,
163 384*8, 448*8, 512*8, 640*8,
164 384*16, 448*16, 512*16, 640*16,
165 384*32, 448*32, 512*32, 640*32,
166 384*64, 448*64, 512*64, 640*64,
167 384*128,448*128,512*128
168};
169
170static snd_pcm_hw_constraint_list_t hw_constraints_capture_period_sizes = {
171 .count = 31,
172 .list = capture_period_sizes,
173 .mask = 0
174};
175
176static unsigned int capture_rates[8] = {
177 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000
178};
179
180static snd_pcm_hw_constraint_list_t hw_constraints_capture_rates = {
181 .count = 8,
182 .list = capture_rates,
183 .mask = 0
184};
185
186static unsigned int snd_emu10k1_capture_rate_reg(unsigned int rate)
187{
188 switch (rate) {
189 case 8000: return ADCCR_SAMPLERATE_8;
190 case 11025: return ADCCR_SAMPLERATE_11;
191 case 16000: return ADCCR_SAMPLERATE_16;
192 case 22050: return ADCCR_SAMPLERATE_22;
193 case 24000: return ADCCR_SAMPLERATE_24;
194 case 32000: return ADCCR_SAMPLERATE_32;
195 case 44100: return ADCCR_SAMPLERATE_44;
196 case 48000: return ADCCR_SAMPLERATE_48;
197 default:
198 snd_BUG();
199 return ADCCR_SAMPLERATE_8;
200 }
201}
202
203static unsigned int snd_emu10k1_audigy_capture_rate_reg(unsigned int rate)
204{
205 switch (rate) {
206 case 8000: return A_ADCCR_SAMPLERATE_8;
207 case 11025: return A_ADCCR_SAMPLERATE_11;
208 case 12000: return A_ADCCR_SAMPLERATE_12; /* really supported? */
209 case 16000: return ADCCR_SAMPLERATE_16;
210 case 22050: return ADCCR_SAMPLERATE_22;
211 case 24000: return ADCCR_SAMPLERATE_24;
212 case 32000: return ADCCR_SAMPLERATE_32;
213 case 44100: return ADCCR_SAMPLERATE_44;
214 case 48000: return ADCCR_SAMPLERATE_48;
215 default:
216 snd_BUG();
217 return A_ADCCR_SAMPLERATE_8;
218 }
219}
220
221static unsigned int emu10k1_calc_pitch_target(unsigned int rate)
222{
223 unsigned int pitch_target;
224
225 pitch_target = (rate << 8) / 375;
226 pitch_target = (pitch_target >> 1) + (pitch_target & 1);
227 return pitch_target;
228}
229
230#define PITCH_48000 0x00004000
231#define PITCH_96000 0x00008000
232#define PITCH_85000 0x00007155
233#define PITCH_80726 0x00006ba2
234#define PITCH_67882 0x00005a82
235#define PITCH_57081 0x00004c1c
236
237static unsigned int emu10k1_select_interprom(unsigned int pitch_target)
238{
239 if (pitch_target == PITCH_48000)
240 return CCCA_INTERPROM_0;
241 else if (pitch_target < PITCH_48000)
242 return CCCA_INTERPROM_1;
243 else if (pitch_target >= PITCH_96000)
244 return CCCA_INTERPROM_0;
245 else if (pitch_target >= PITCH_85000)
246 return CCCA_INTERPROM_6;
247 else if (pitch_target >= PITCH_80726)
248 return CCCA_INTERPROM_5;
249 else if (pitch_target >= PITCH_67882)
250 return CCCA_INTERPROM_4;
251 else if (pitch_target >= PITCH_57081)
252 return CCCA_INTERPROM_3;
253 else
254 return CCCA_INTERPROM_2;
255}
256
257/*
258 * calculate cache invalidate size
259 *
260 * stereo: channel is stereo
261 * w_16: using 16bit samples
262 *
263 * returns: cache invalidate size in samples
264 */
265static int inline emu10k1_ccis(int stereo, int w_16)
266{
267 if (w_16) {
268 return stereo ? 24 : 26;
269 } else {
270 return stereo ? 24*2 : 26*2;
271 }
272}
273
274static void snd_emu10k1_pcm_init_voice(emu10k1_t *emu,
275 int master, int extra,
276 emu10k1_voice_t *evoice,
277 unsigned int start_addr,
278 unsigned int end_addr,
279 emu10k1_pcm_mixer_t *mix)
280{
281 snd_pcm_substream_t *substream = evoice->epcm->substream;
282 snd_pcm_runtime_t *runtime = substream->runtime;
283 unsigned int silent_page, tmp;
284 int voice, stereo, w_16;
285 unsigned char attn, send_amount[8];
286 unsigned char send_routing[8];
287 unsigned long flags;
288 unsigned int pitch_target;
289 unsigned int ccis;
290
291 voice = evoice->number;
292 stereo = runtime->channels == 2;
293 w_16 = snd_pcm_format_width(runtime->format) == 16;
294
295 if (!extra && stereo) {
296 start_addr >>= 1;
297 end_addr >>= 1;
298 }
299 if (w_16) {
300 start_addr >>= 1;
301 end_addr >>= 1;
302 }
303
304 spin_lock_irqsave(&emu->reg_lock, flags);
305
306 /* volume parameters */
307 if (extra) {
308 attn = 0;
309 memset(send_routing, 0, sizeof(send_routing));
310 send_routing[0] = 0;
311 send_routing[1] = 1;
312 send_routing[2] = 2;
313 send_routing[3] = 3;
314 memset(send_amount, 0, sizeof(send_amount));
315 } else {
316 /* mono, left, right (master voice = left) */
317 tmp = stereo ? (master ? 1 : 2) : 0;
318 memcpy(send_routing, &mix->send_routing[tmp][0], 8);
319 memcpy(send_amount, &mix->send_volume[tmp][0], 8);
320 }
321
322 ccis = emu10k1_ccis(stereo, w_16);
323
324 if (master) {
325 evoice->epcm->ccca_start_addr = start_addr + ccis;
326 if (extra) {
327 start_addr += ccis;
328 end_addr += ccis;
329 }
330 if (stereo && !extra) {
331 snd_emu10k1_ptr_write(emu, CPF, voice, CPF_STEREO_MASK);
332 snd_emu10k1_ptr_write(emu, CPF, (voice + 1), CPF_STEREO_MASK);
333 } else {
334 snd_emu10k1_ptr_write(emu, CPF, voice, 0);
335 }
336 }
337
338 // setup routing
339 if (emu->audigy) {
340 snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
341 snd_emu10k1_compose_audigy_fxrt1(send_routing));
342 snd_emu10k1_ptr_write(emu, A_FXRT2, voice,
343 snd_emu10k1_compose_audigy_fxrt2(send_routing));
344 snd_emu10k1_ptr_write(emu, A_SENDAMOUNTS, voice,
345 ((unsigned int)send_amount[4] << 24) |
346 ((unsigned int)send_amount[5] << 16) |
347 ((unsigned int)send_amount[6] << 8) |
348 (unsigned int)send_amount[7]);
349 } else
350 snd_emu10k1_ptr_write(emu, FXRT, voice,
351 snd_emu10k1_compose_send_routing(send_routing));
352 // Stop CA
353 // Assumption that PT is already 0 so no harm overwriting
354 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
355 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
356 snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24));
357 pitch_target = emu10k1_calc_pitch_target(runtime->rate);
358 if (extra)
359 snd_emu10k1_ptr_write(emu, CCCA, voice, start_addr |
360 emu10k1_select_interprom(pitch_target) |
361 (w_16 ? 0 : CCCA_8BITSELECT));
362 else
363 snd_emu10k1_ptr_write(emu, CCCA, voice, (start_addr + ccis) |
364 emu10k1_select_interprom(pitch_target) |
365 (w_16 ? 0 : CCCA_8BITSELECT));
366 // Clear filter delay memory
367 snd_emu10k1_ptr_write(emu, Z1, voice, 0);
368 snd_emu10k1_ptr_write(emu, Z2, voice, 0);
369 // invalidate maps
370 silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
371 snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
372 snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
373 // modulation envelope
374 snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
375 snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
376 snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0);
377 snd_emu10k1_ptr_write(emu, DCYSUSM, voice, 0x007f);
378 snd_emu10k1_ptr_write(emu, LFOVAL1, voice, 0x8000);
379 snd_emu10k1_ptr_write(emu, LFOVAL2, voice, 0x8000);
380 snd_emu10k1_ptr_write(emu, FMMOD, voice, 0);
381 snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0);
382 snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0);
383 snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000);
384 // volume envelope
385 snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f);
386 snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000);
387 // filter envelope
388 snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f);
389 // pitch envelope
390 snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0);
391
392 spin_unlock_irqrestore(&emu->reg_lock, flags);
393}
394
395static int snd_emu10k1_playback_hw_params(snd_pcm_substream_t * substream,
396 snd_pcm_hw_params_t * hw_params)
397{
398 emu10k1_t *emu = snd_pcm_substream_chip(substream);
399 snd_pcm_runtime_t *runtime = substream->runtime;
400 emu10k1_pcm_t *epcm = runtime->private_data;
401 int err;
402
403 if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0)
404 return err;
405 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
406 return err;
407 if (err > 0) { /* change */
408 snd_util_memblk_t *memblk;
409 if (epcm->memblk != NULL)
410 snd_emu10k1_free_pages(emu, epcm->memblk);
411 memblk = snd_emu10k1_alloc_pages(emu, substream);
412 if ((epcm->memblk = memblk) == NULL || ((emu10k1_memblk_t *)memblk)->mapped_page < 0) {
413 epcm->start_addr = 0;
414 return -ENOMEM;
415 }
416 epcm->start_addr = ((emu10k1_memblk_t *)memblk)->mapped_page << PAGE_SHIFT;
417 }
418 return 0;
419}
420
421static int snd_emu10k1_playback_hw_free(snd_pcm_substream_t * substream)
422{
423 emu10k1_t *emu = snd_pcm_substream_chip(substream);
424 snd_pcm_runtime_t *runtime = substream->runtime;
425 emu10k1_pcm_t *epcm;
426
427 if (runtime->private_data == NULL)
428 return 0;
429 epcm = runtime->private_data;
430 if (epcm->extra) {
431 snd_emu10k1_voice_free(epcm->emu, epcm->extra);
432 epcm->extra = NULL;
433 }
434 if (epcm->voices[1]) {
435 snd_emu10k1_voice_free(epcm->emu, epcm->voices[1]);
436 epcm->voices[1] = NULL;
437 }
438 if (epcm->voices[0]) {
439 snd_emu10k1_voice_free(epcm->emu, epcm->voices[0]);
440 epcm->voices[0] = NULL;
441 }
442 if (epcm->memblk) {
443 snd_emu10k1_free_pages(emu, epcm->memblk);
444 epcm->memblk = NULL;
445 epcm->start_addr = 0;
446 }
447 snd_pcm_lib_free_pages(substream);
448 return 0;
449}
450
451static int snd_emu10k1_efx_playback_hw_free(snd_pcm_substream_t * substream)
452{
453 emu10k1_t *emu = snd_pcm_substream_chip(substream);
454 snd_pcm_runtime_t *runtime = substream->runtime;
455 emu10k1_pcm_t *epcm;
456 int i;
457
458 if (runtime->private_data == NULL)
459 return 0;
460 epcm = runtime->private_data;
461 if (epcm->extra) {
462 snd_emu10k1_voice_free(epcm->emu, epcm->extra);
463 epcm->extra = NULL;
464 }
465 for (i=0; i < NUM_EFX_PLAYBACK; i++) {
466 if (epcm->voices[i]) {
467 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
468 epcm->voices[i] = NULL;
469 }
470 }
471 if (epcm->memblk) {
472 snd_emu10k1_free_pages(emu, epcm->memblk);
473 epcm->memblk = NULL;
474 epcm->start_addr = 0;
475 }
476 snd_pcm_lib_free_pages(substream);
477 return 0;
478}
479
480static int snd_emu10k1_playback_prepare(snd_pcm_substream_t * substream)
481{
482 emu10k1_t *emu = snd_pcm_substream_chip(substream);
483 snd_pcm_runtime_t *runtime = substream->runtime;
484 emu10k1_pcm_t *epcm = runtime->private_data;
485 unsigned int start_addr, end_addr;
486
487 start_addr = epcm->start_addr;
488 end_addr = snd_pcm_lib_period_bytes(substream);
489 if (runtime->channels == 2) {
490 start_addr >>= 1;
491 end_addr >>= 1;
492 }
493 end_addr += start_addr;
494 snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
495 start_addr, end_addr, NULL);
496 start_addr = epcm->start_addr;
497 end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
498 snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0],
499 start_addr, end_addr,
500 &emu->pcm_mixer[substream->number]);
501 if (epcm->voices[1])
502 snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1],
503 start_addr, end_addr,
504 &emu->pcm_mixer[substream->number]);
505 return 0;
506}
507
508static int snd_emu10k1_efx_playback_prepare(snd_pcm_substream_t * substream)
509{
510 emu10k1_t *emu = snd_pcm_substream_chip(substream);
511 snd_pcm_runtime_t *runtime = substream->runtime;
512 emu10k1_pcm_t *epcm = runtime->private_data;
513 unsigned int start_addr, end_addr;
514 unsigned int channel_size;
515 int i;
516
517 start_addr = epcm->start_addr;
518 end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream);
519
520 /*
521 * the kX driver leaves some space between voices
522 */
523 channel_size = ( end_addr - start_addr ) / NUM_EFX_PLAYBACK;
524
525 snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra,
526 start_addr, start_addr + (channel_size / 2), NULL);
527
528 /* only difference with the master voice is we use it for the pointer */
529 snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0],
530 start_addr, start_addr + channel_size,
531 &emu->efx_pcm_mixer[0]);
532
533 start_addr += channel_size;
534 for (i = 1; i < NUM_EFX_PLAYBACK; i++) {
535 snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[i],
536 start_addr, start_addr + channel_size,
537 &emu->efx_pcm_mixer[i]);
538 start_addr += channel_size;
539 }
540
541 return 0;
542}
543
544static snd_pcm_hardware_t snd_emu10k1_efx_playback =
545{
546 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_NONINTERLEAVED |
547 SNDRV_PCM_INFO_BLOCK_TRANSFER |
548 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
549 .formats = SNDRV_PCM_FMTBIT_S16_LE,
550 .rates = SNDRV_PCM_RATE_48000,
551 .rate_min = 48000,
552 .rate_max = 48000,
553 .channels_min = NUM_EFX_PLAYBACK,
554 .channels_max = NUM_EFX_PLAYBACK,
555 .buffer_bytes_max = (64*1024),
556 .period_bytes_min = 64,
557 .period_bytes_max = (64*1024),
558 .periods_min = 2,
559 .periods_max = 2,
560 .fifo_size = 0,
561};
562
563static int snd_emu10k1_capture_hw_params(snd_pcm_substream_t * substream,
564 snd_pcm_hw_params_t * hw_params)
565{
566 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
567}
568
569static int snd_emu10k1_capture_hw_free(snd_pcm_substream_t * substream)
570{
571 return snd_pcm_lib_free_pages(substream);
572}
573
574static int snd_emu10k1_capture_prepare(snd_pcm_substream_t * substream)
575{
576 emu10k1_t *emu = snd_pcm_substream_chip(substream);
577 snd_pcm_runtime_t *runtime = substream->runtime;
578 emu10k1_pcm_t *epcm = runtime->private_data;
579 int idx;
580
581 /* zeroing the buffer size will stop capture */
582 snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, 0);
583 switch (epcm->type) {
584 case CAPTURE_AC97ADC:
585 snd_emu10k1_ptr_write(emu, ADCCR, 0, 0);
586 break;
587 case CAPTURE_EFX:
588 if (emu->audigy) {
589 snd_emu10k1_ptr_write(emu, A_FXWC1, 0, 0);
590 snd_emu10k1_ptr_write(emu, A_FXWC2, 0, 0);
591 } else
592 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
593 break;
594 default:
595 break;
596 }
597 snd_emu10k1_ptr_write(emu, epcm->capture_ba_reg, 0, runtime->dma_addr);
598 epcm->capture_bufsize = snd_pcm_lib_buffer_bytes(substream);
599 epcm->capture_bs_val = 0;
600 for (idx = 0; idx < 31; idx++) {
601 if (capture_period_sizes[idx] == epcm->capture_bufsize) {
602 epcm->capture_bs_val = idx + 1;
603 break;
604 }
605 }
606 if (epcm->capture_bs_val == 0) {
607 snd_BUG();
608 epcm->capture_bs_val++;
609 }
610 if (epcm->type == CAPTURE_AC97ADC) {
611 epcm->capture_cr_val = emu->audigy ? A_ADCCR_LCHANENABLE : ADCCR_LCHANENABLE;
612 if (runtime->channels > 1)
613 epcm->capture_cr_val |= emu->audigy ? A_ADCCR_RCHANENABLE : ADCCR_RCHANENABLE;
614 epcm->capture_cr_val |= emu->audigy ?
615 snd_emu10k1_audigy_capture_rate_reg(runtime->rate) :
616 snd_emu10k1_capture_rate_reg(runtime->rate);
617 }
618 return 0;
619}
620
621static void snd_emu10k1_playback_invalidate_cache(emu10k1_t *emu, int extra, emu10k1_voice_t *evoice)
622{
623 snd_pcm_runtime_t *runtime;
624 unsigned int voice, stereo, i, ccis, cra = 64, cs, sample;
625
626 if (evoice == NULL)
627 return;
628 runtime = evoice->epcm->substream->runtime;
629 voice = evoice->number;
630 stereo = (!extra && runtime->channels == 2);
631 sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080;
632 ccis = emu10k1_ccis(stereo, sample == 0);
633 // set cs to 2 * number of cache registers beside the invalidated
634 cs = (sample == 0) ? (32-ccis) : (64-ccis+1) >> 1;
635 if (cs > 16) cs = 16;
636 for (i = 0; i < cs; i++) {
637 snd_emu10k1_ptr_write(emu, CD0 + i, voice, sample);
638 if (stereo) {
639 snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample);
640 }
641 }
642 // reset cache
643 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0);
644 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra);
645 if (stereo) {
646 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0);
647 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra);
648 }
649 // fill cache
650 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis);
651 if (stereo) {
652 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis);
653 }
654}
655
656static void snd_emu10k1_playback_prepare_voice(emu10k1_t *emu, emu10k1_voice_t *evoice,
657 int master, int extra,
658 emu10k1_pcm_mixer_t *mix)
659{
660 snd_pcm_substream_t *substream;
661 snd_pcm_runtime_t *runtime;
662 unsigned int attn, vattn;
663 unsigned int voice, tmp;
664
665 if (evoice == NULL) /* skip second voice for mono */
666 return;
667 substream = evoice->epcm->substream;
668 runtime = substream->runtime;
669 voice = evoice->number;
670
671 attn = extra ? 0 : 0x00ff;
672 tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0;
673 vattn = mix != NULL ? (mix->attn[tmp] << 16) : 0;
674 snd_emu10k1_ptr_write(emu, IFATN, voice, attn);
675 snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | 0xffff);
676 snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | 0xffff);
677 snd_emu10k1_ptr_write(emu, DCYSUSV, voice, 0x7f7f);
678 snd_emu10k1_voice_clear_loop_stop(emu, voice);
679}
680
681static void snd_emu10k1_playback_trigger_voice(emu10k1_t *emu, emu10k1_voice_t *evoice, int master, int extra)
682{
683 snd_pcm_substream_t *substream;
684 snd_pcm_runtime_t *runtime;
685 unsigned int voice, pitch, pitch_target;
686
687 if (evoice == NULL) /* skip second voice for mono */
688 return;
689 substream = evoice->epcm->substream;
690 runtime = substream->runtime;
691 voice = evoice->number;
692
693 pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8;
694 pitch_target = emu10k1_calc_pitch_target(runtime->rate);
695 snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target);
696 if (master || evoice->epcm->type == PLAYBACK_EFX)
697 snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target);
698 snd_emu10k1_ptr_write(emu, IP, voice, pitch);
699 if (extra)
700 snd_emu10k1_voice_intr_enable(emu, voice);
701}
702
703static void snd_emu10k1_playback_stop_voice(emu10k1_t *emu, emu10k1_voice_t *evoice)
704{
705 unsigned int voice;
706
707 if (evoice == NULL)
708 return;
709 voice = evoice->number;
710 snd_emu10k1_voice_intr_disable(emu, voice);
711 snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, 0);
712 snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, 0);
713 snd_emu10k1_ptr_write(emu, IFATN, voice, 0xffff);
714 snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
715 snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
716 snd_emu10k1_ptr_write(emu, IP, voice, 0);
717}
718
719static int snd_emu10k1_playback_trigger(snd_pcm_substream_t * substream,
720 int cmd)
721{
722 emu10k1_t *emu = snd_pcm_substream_chip(substream);
723 snd_pcm_runtime_t *runtime = substream->runtime;
724 emu10k1_pcm_t *epcm = runtime->private_data;
725 emu10k1_pcm_mixer_t *mix;
726 int result = 0;
727
728 // printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream));
729 spin_lock(&emu->reg_lock);
730 switch (cmd) {
731 case SNDRV_PCM_TRIGGER_START:
732 snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); /* do we need this? */
733 snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]);
734 /* follow thru */
735 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
736 mix = &emu->pcm_mixer[substream->number];
737 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
738 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
739 snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
740 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1, 0);
741 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0, 0);
742 snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
743 epcm->running = 1;
744 break;
745 case SNDRV_PCM_TRIGGER_STOP:
746 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
747 epcm->running = 0;
748 snd_emu10k1_playback_stop_voice(emu, epcm->voices[0]);
749 snd_emu10k1_playback_stop_voice(emu, epcm->voices[1]);
750 snd_emu10k1_playback_stop_voice(emu, epcm->extra);
751 break;
752 default:
753 result = -EINVAL;
754 break;
755 }
756 spin_unlock(&emu->reg_lock);
757 return result;
758}
759
760static int snd_emu10k1_capture_trigger(snd_pcm_substream_t * substream,
761 int cmd)
762{
763 emu10k1_t *emu = snd_pcm_substream_chip(substream);
764 snd_pcm_runtime_t *runtime = substream->runtime;
765 emu10k1_pcm_t *epcm = runtime->private_data;
766 int result = 0;
767
768 spin_lock(&emu->reg_lock);
769 switch (cmd) {
770 case SNDRV_PCM_TRIGGER_START:
771 // hmm this should cause full and half full interrupt to be raised?
772 outl(epcm->capture_ipr, emu->port + IPR);
773 snd_emu10k1_intr_enable(emu, epcm->capture_inte);
774 // printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs);
775 switch (epcm->type) {
776 case CAPTURE_AC97ADC:
777 snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val);
778 break;
779 case CAPTURE_EFX:
780 if (emu->audigy) {
781 snd_emu10k1_ptr_write(emu, A_FXWC1, 0, epcm->capture_cr_val);
782 snd_emu10k1_ptr_write(emu, A_FXWC2, 0, epcm->capture_cr_val2);
783 } else
784 snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val);
785 break;
786 default:
787 break;
788 }
789 snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, epcm->capture_bs_val);
790 epcm->running = 1;
791 epcm->first_ptr = 1;
792 break;
793 case SNDRV_PCM_TRIGGER_STOP:
794 epcm->running = 0;
795 snd_emu10k1_intr_disable(emu, epcm->capture_inte);
796 outl(epcm->capture_ipr, emu->port + IPR);
797 snd_emu10k1_ptr_write(emu, epcm->capture_bs_reg, 0, 0);
798 switch (epcm->type) {
799 case CAPTURE_AC97ADC:
800 snd_emu10k1_ptr_write(emu, ADCCR, 0, 0);
801 break;
802 case CAPTURE_EFX:
803 if (emu->audigy) {
804 snd_emu10k1_ptr_write(emu, A_FXWC1, 0, 0);
805 snd_emu10k1_ptr_write(emu, A_FXWC2, 0, 0);
806 } else
807 snd_emu10k1_ptr_write(emu, FXWC, 0, 0);
808 break;
809 default:
810 break;
811 }
812 break;
813 default:
814 result = -EINVAL;
815 }
816 spin_unlock(&emu->reg_lock);
817 return result;
818}
819
820static snd_pcm_uframes_t snd_emu10k1_playback_pointer(snd_pcm_substream_t * substream)
821{
822 emu10k1_t *emu = snd_pcm_substream_chip(substream);
823 snd_pcm_runtime_t *runtime = substream->runtime;
824 emu10k1_pcm_t *epcm = runtime->private_data;
825 unsigned int ptr;
826
827 if (!epcm->running)
828 return 0;
829 ptr = snd_emu10k1_ptr_read(emu, CCCA, epcm->voices[0]->number) & 0x00ffffff;
830#if 0 /* Perex's code */
831 ptr += runtime->buffer_size;
832 ptr -= epcm->ccca_start_addr;
833 ptr %= runtime->buffer_size;
834#else /* EMU10K1 Open Source code from Creative */
835 if (ptr < epcm->ccca_start_addr)
836 ptr += runtime->buffer_size - epcm->ccca_start_addr;
837 else {
838 ptr -= epcm->ccca_start_addr;
839 if (ptr >= runtime->buffer_size)
840 ptr -= runtime->buffer_size;
841 }
842#endif
843 // printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size);
844 return ptr;
845}
846
847
848static int snd_emu10k1_efx_playback_trigger(snd_pcm_substream_t * substream,
849 int cmd)
850{
851 emu10k1_t *emu = snd_pcm_substream_chip(substream);
852 snd_pcm_runtime_t *runtime = substream->runtime;
853 emu10k1_pcm_t *epcm = runtime->private_data;
854 int i;
855 int result = 0;
856
857 spin_lock(&emu->reg_lock);
858 switch (cmd) {
859 case SNDRV_PCM_TRIGGER_START:
860 // prepare voices
861 for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
862 snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]);
863 }
864 snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra);
865
866 /* follow thru */
867 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
868 snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
869 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0,
870 &emu->efx_pcm_mixer[0]);
871 for (i = 1; i < NUM_EFX_PLAYBACK; i++)
872 snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0, 0,
873 &emu->efx_pcm_mixer[i]);
874 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 0, 0);
875 snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1);
876 for (i = 1; i < NUM_EFX_PLAYBACK; i++)
877 snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0, 0);
878 epcm->running = 1;
879 break;
880 case SNDRV_PCM_TRIGGER_STOP:
881 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
882 epcm->running = 0;
883 for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
884 snd_emu10k1_playback_stop_voice(emu, epcm->voices[i]);
885 }
886 snd_emu10k1_playback_stop_voice(emu, epcm->extra);
887 break;
888 default:
889 result = -EINVAL;
890 break;
891 }
892 spin_unlock(&emu->reg_lock);
893 return result;
894}
895
896
897static snd_pcm_uframes_t snd_emu10k1_capture_pointer(snd_pcm_substream_t * substream)
898{
899 emu10k1_t *emu = snd_pcm_substream_chip(substream);
900 snd_pcm_runtime_t *runtime = substream->runtime;
901 emu10k1_pcm_t *epcm = runtime->private_data;
902 unsigned int ptr;
903
904 if (!epcm->running)
905 return 0;
906 if (epcm->first_ptr) {
907 udelay(50); // hack, it takes awhile until capture is started
908 epcm->first_ptr = 0;
909 }
910 ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff;
911 return bytes_to_frames(runtime, ptr);
912}
913
914/*
915 * Playback support device description
916 */
917
918static snd_pcm_hardware_t snd_emu10k1_playback =
919{
920 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
921 SNDRV_PCM_INFO_BLOCK_TRANSFER |
922 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
923 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
924 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_96000,
925 .rate_min = 4000,
926 .rate_max = 96000,
927 .channels_min = 1,
928 .channels_max = 2,
929 .buffer_bytes_max = (128*1024),
930 .period_bytes_min = 64,
931 .period_bytes_max = (128*1024),
932 .periods_min = 1,
933 .periods_max = 1024,
934 .fifo_size = 0,
935};
936
937/*
938 * Capture support device description
939 */
940
941static snd_pcm_hardware_t snd_emu10k1_capture =
942{
943 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
944 SNDRV_PCM_INFO_BLOCK_TRANSFER |
945 SNDRV_PCM_INFO_MMAP_VALID),
946 .formats = SNDRV_PCM_FMTBIT_S16_LE,
947 .rates = SNDRV_PCM_RATE_8000_48000,
948 .rate_min = 8000,
949 .rate_max = 48000,
950 .channels_min = 1,
951 .channels_max = 2,
952 .buffer_bytes_max = (64*1024),
953 .period_bytes_min = 384,
954 .period_bytes_max = (64*1024),
955 .periods_min = 2,
956 .periods_max = 2,
957 .fifo_size = 0,
958};
959
960/*
961 *
962 */
963
964static void snd_emu10k1_pcm_mixer_notify1(emu10k1_t *emu, snd_kcontrol_t *kctl, int idx, int activate)
965{
966 snd_ctl_elem_id_t id;
967
968 snd_runtime_check(kctl != NULL, return);
969 if (activate)
970 kctl->vd[idx].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
971 else
972 kctl->vd[idx].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
973 snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE |
974 SNDRV_CTL_EVENT_MASK_INFO,
975 snd_ctl_build_ioff(&id, kctl, idx));
976}
977
978static void snd_emu10k1_pcm_mixer_notify(emu10k1_t *emu, int idx, int activate)
979{
980 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_routing, idx, activate);
981 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_volume, idx, activate);
982 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_attn, idx, activate);
983}
984
985static void snd_emu10k1_pcm_efx_mixer_notify(emu10k1_t *emu, int idx, int activate)
986{
987 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_routing, idx, activate);
988 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_volume, idx, activate);
989 snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_attn, idx, activate);
990}
991
992static void snd_emu10k1_pcm_free_substream(snd_pcm_runtime_t *runtime)
993{
994 emu10k1_pcm_t *epcm = runtime->private_data;
995
996 kfree(epcm);
997}
998
999static int snd_emu10k1_efx_playback_close(snd_pcm_substream_t * substream)
1000{
1001 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1002 emu10k1_pcm_mixer_t *mix;
1003 int i;
1004
1005 for (i=0; i < NUM_EFX_PLAYBACK; i++) {
1006 mix = &emu->efx_pcm_mixer[i];
1007 mix->epcm = NULL;
1008 snd_emu10k1_pcm_efx_mixer_notify(emu, i, 0);
1009 }
1010 return 0;
1011}
1012
1013static int snd_emu10k1_efx_playback_open(snd_pcm_substream_t * substream)
1014{
1015 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1016 emu10k1_pcm_t *epcm;
1017 emu10k1_pcm_mixer_t *mix;
1018 snd_pcm_runtime_t *runtime = substream->runtime;
1019 int i;
1020
1021 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1022 if (epcm == NULL)
1023 return -ENOMEM;
1024 epcm->emu = emu;
1025 epcm->type = PLAYBACK_EFX;
1026 epcm->substream = substream;
1027
1028 emu->pcm_playback_efx_substream = substream;
1029
1030 runtime->private_data = epcm;
1031 runtime->private_free = snd_emu10k1_pcm_free_substream;
1032 runtime->hw = snd_emu10k1_efx_playback;
1033
1034 for (i=0; i < NUM_EFX_PLAYBACK; i++) {
1035 mix = &emu->efx_pcm_mixer[i];
1036 mix->send_routing[0][0] = i;
1037 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
1038 mix->send_volume[0][0] = 255;
1039 mix->attn[0] = 0xffff;
1040 mix->epcm = epcm;
1041 snd_emu10k1_pcm_efx_mixer_notify(emu, i, 1);
1042 }
1043 return 0;
1044}
1045
1046static int snd_emu10k1_playback_open(snd_pcm_substream_t * substream)
1047{
1048 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1049 emu10k1_pcm_t *epcm;
1050 emu10k1_pcm_mixer_t *mix;
1051 snd_pcm_runtime_t *runtime = substream->runtime;
1052 int i, err;
1053
1054 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1055 if (epcm == NULL)
1056 return -ENOMEM;
1057 epcm->emu = emu;
1058 epcm->type = PLAYBACK_EMUVOICE;
1059 epcm->substream = substream;
1060 runtime->private_data = epcm;
1061 runtime->private_free = snd_emu10k1_pcm_free_substream;
1062 runtime->hw = snd_emu10k1_playback;
1063 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
1064 kfree(epcm);
1065 return err;
1066 }
1067 if ((err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX)) < 0) {
1068 kfree(epcm);
1069 return err;
1070 }
1071 mix = &emu->pcm_mixer[substream->number];
1072 for (i = 0; i < 4; i++)
1073 mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i;
1074 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
1075 mix->send_volume[0][0] = mix->send_volume[0][1] =
1076 mix->send_volume[1][0] = mix->send_volume[2][1] = 255;
1077 mix->attn[0] = mix->attn[1] = mix->attn[2] = 0xffff;
1078 mix->epcm = epcm;
1079 snd_emu10k1_pcm_mixer_notify(emu, substream->number, 1);
1080 return 0;
1081}
1082
1083static int snd_emu10k1_playback_close(snd_pcm_substream_t * substream)
1084{
1085 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1086 emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[substream->number];
1087
1088 mix->epcm = NULL;
1089 snd_emu10k1_pcm_mixer_notify(emu, substream->number, 0);
1090 return 0;
1091}
1092
1093static int snd_emu10k1_capture_open(snd_pcm_substream_t * substream)
1094{
1095 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1096 snd_pcm_runtime_t *runtime = substream->runtime;
1097 emu10k1_pcm_t *epcm;
1098
1099 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1100 if (epcm == NULL)
1101 return -ENOMEM;
1102 epcm->emu = emu;
1103 epcm->type = CAPTURE_AC97ADC;
1104 epcm->substream = substream;
1105 epcm->capture_ipr = IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL;
1106 epcm->capture_inte = INTE_ADCBUFENABLE;
1107 epcm->capture_ba_reg = ADCBA;
1108 epcm->capture_bs_reg = ADCBS;
1109 epcm->capture_idx_reg = emu->audigy ? A_ADCIDX : ADCIDX;
1110 runtime->private_data = epcm;
1111 runtime->private_free = snd_emu10k1_pcm_free_substream;
1112 runtime->hw = snd_emu10k1_capture;
1113 emu->capture_interrupt = snd_emu10k1_pcm_ac97adc_interrupt;
1114 emu->pcm_capture_substream = substream;
1115 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);
1116 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_capture_rates);
1117 return 0;
1118}
1119
1120static int snd_emu10k1_capture_close(snd_pcm_substream_t * substream)
1121{
1122 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1123
1124 emu->capture_interrupt = NULL;
1125 emu->pcm_capture_substream = NULL;
1126 return 0;
1127}
1128
1129static int snd_emu10k1_capture_mic_open(snd_pcm_substream_t * substream)
1130{
1131 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1132 emu10k1_pcm_t *epcm;
1133 snd_pcm_runtime_t *runtime = substream->runtime;
1134
1135 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1136 if (epcm == NULL)
1137 return -ENOMEM;
1138 epcm->emu = emu;
1139 epcm->type = CAPTURE_AC97MIC;
1140 epcm->substream = substream;
1141 epcm->capture_ipr = IPR_MICBUFFULL|IPR_MICBUFHALFFULL;
1142 epcm->capture_inte = INTE_MICBUFENABLE;
1143 epcm->capture_ba_reg = MICBA;
1144 epcm->capture_bs_reg = MICBS;
1145 epcm->capture_idx_reg = emu->audigy ? A_MICIDX : MICIDX;
1146 substream->runtime->private_data = epcm;
1147 substream->runtime->private_free = snd_emu10k1_pcm_free_substream;
1148 runtime->hw = snd_emu10k1_capture;
1149 runtime->hw.rates = SNDRV_PCM_RATE_8000;
1150 runtime->hw.rate_min = runtime->hw.rate_max = 8000;
1151 runtime->hw.channels_min = 1;
1152 emu->capture_mic_interrupt = snd_emu10k1_pcm_ac97mic_interrupt;
1153 emu->pcm_capture_mic_substream = substream;
1154 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);
1155 return 0;
1156}
1157
1158static int snd_emu10k1_capture_mic_close(snd_pcm_substream_t * substream)
1159{
1160 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1161
1162 emu->capture_interrupt = NULL;
1163 emu->pcm_capture_mic_substream = NULL;
1164 return 0;
1165}
1166
1167static int snd_emu10k1_capture_efx_open(snd_pcm_substream_t * substream)
1168{
1169 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1170 emu10k1_pcm_t *epcm;
1171 snd_pcm_runtime_t *runtime = substream->runtime;
1172 int nefx = emu->audigy ? 64 : 32;
1173 int idx;
1174
1175 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
1176 if (epcm == NULL)
1177 return -ENOMEM;
1178 epcm->emu = emu;
1179 epcm->type = CAPTURE_EFX;
1180 epcm->substream = substream;
1181 epcm->capture_ipr = IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL;
1182 epcm->capture_inte = INTE_EFXBUFENABLE;
1183 epcm->capture_ba_reg = FXBA;
1184 epcm->capture_bs_reg = FXBS;
1185 epcm->capture_idx_reg = FXIDX;
1186 substream->runtime->private_data = epcm;
1187 substream->runtime->private_free = snd_emu10k1_pcm_free_substream;
1188 runtime->hw = snd_emu10k1_capture;
1189 runtime->hw.rates = SNDRV_PCM_RATE_48000;
1190 runtime->hw.rate_min = runtime->hw.rate_max = 48000;
1191 spin_lock_irq(&emu->reg_lock);
1192 runtime->hw.channels_min = runtime->hw.channels_max = 0;
1193 for (idx = 0; idx < nefx; idx++) {
1194 if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) {
1195 runtime->hw.channels_min++;
1196 runtime->hw.channels_max++;
1197 }
1198 }
1199 epcm->capture_cr_val = emu->efx_voices_mask[0];
1200 epcm->capture_cr_val2 = emu->efx_voices_mask[1];
1201 spin_unlock_irq(&emu->reg_lock);
1202 emu->capture_efx_interrupt = snd_emu10k1_pcm_efx_interrupt;
1203 emu->pcm_capture_efx_substream = substream;
1204 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, &hw_constraints_capture_period_sizes);
1205 return 0;
1206}
1207
1208static int snd_emu10k1_capture_efx_close(snd_pcm_substream_t * substream)
1209{
1210 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1211
1212 emu->capture_interrupt = NULL;
1213 emu->pcm_capture_efx_substream = NULL;
1214 return 0;
1215}
1216
1217static snd_pcm_ops_t snd_emu10k1_playback_ops = {
1218 .open = snd_emu10k1_playback_open,
1219 .close = snd_emu10k1_playback_close,
1220 .ioctl = snd_pcm_lib_ioctl,
1221 .hw_params = snd_emu10k1_playback_hw_params,
1222 .hw_free = snd_emu10k1_playback_hw_free,
1223 .prepare = snd_emu10k1_playback_prepare,
1224 .trigger = snd_emu10k1_playback_trigger,
1225 .pointer = snd_emu10k1_playback_pointer,
1226 .page = snd_pcm_sgbuf_ops_page,
1227};
1228
1229static snd_pcm_ops_t snd_emu10k1_capture_ops = {
1230 .open = snd_emu10k1_capture_open,
1231 .close = snd_emu10k1_capture_close,
1232 .ioctl = snd_pcm_lib_ioctl,
1233 .hw_params = snd_emu10k1_capture_hw_params,
1234 .hw_free = snd_emu10k1_capture_hw_free,
1235 .prepare = snd_emu10k1_capture_prepare,
1236 .trigger = snd_emu10k1_capture_trigger,
1237 .pointer = snd_emu10k1_capture_pointer,
1238};
1239
1240/* EFX playback */
1241static snd_pcm_ops_t snd_emu10k1_efx_playback_ops = {
1242 .open = snd_emu10k1_efx_playback_open,
1243 .close = snd_emu10k1_efx_playback_close,
1244 .ioctl = snd_pcm_lib_ioctl,
1245 .hw_params = snd_emu10k1_playback_hw_params,
1246 .hw_free = snd_emu10k1_efx_playback_hw_free,
1247 .prepare = snd_emu10k1_efx_playback_prepare,
1248 .trigger = snd_emu10k1_efx_playback_trigger,
1249 .pointer = snd_emu10k1_efx_playback_pointer,
1250 .page = snd_pcm_sgbuf_ops_page,
1251};
1252
1253static void snd_emu10k1_pcm_free(snd_pcm_t *pcm)
1254{
1255 emu10k1_t *emu = pcm->private_data;
1256 emu->pcm = NULL;
1257 snd_pcm_lib_preallocate_free_for_all(pcm);
1258}
1259
1260int __devinit snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
1261{
1262 snd_pcm_t *pcm;
1263 snd_pcm_substream_t *substream;
1264 int err;
1265
1266 if (rpcm)
1267 *rpcm = NULL;
1268
1269 if ((err = snd_pcm_new(emu->card, "emu10k1", device, 32, 1, &pcm)) < 0)
1270 return err;
1271
1272 pcm->private_data = emu;
1273 pcm->private_free = snd_emu10k1_pcm_free;
1274
1275 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_playback_ops);
1276 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_ops);
1277
1278 pcm->info_flags = 0;
1279 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
1280 strcpy(pcm->name, "ADC Capture/Standard PCM Playback");
1281 emu->pcm = pcm;
1282
1283 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
1284 if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0)
1285 return err;
1286
1287 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next)
1288 snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
1289
1290 if (rpcm)
1291 *rpcm = pcm;
1292
1293 return 0;
1294}
1295
1296int __devinit snd_emu10k1_pcm_multi(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
1297{
1298 snd_pcm_t *pcm;
1299 snd_pcm_substream_t *substream;
1300 int err;
1301
1302 if (rpcm)
1303 *rpcm = NULL;
1304
1305 if ((err = snd_pcm_new(emu->card, "emu10k1", device, 1, 0, &pcm)) < 0)
1306 return err;
1307
1308 pcm->private_data = emu;
1309 pcm->private_free = snd_emu10k1_pcm_free;
1310
1311 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_efx_playback_ops);
1312
1313 pcm->info_flags = 0;
1314 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
1315 strcpy(pcm->name, "Multichannel Playback");
1316 emu->pcm = pcm;
1317
1318 for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
1319 if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0)
1320 return err;
1321
1322 if (rpcm)
1323 *rpcm = pcm;
1324
1325 return 0;
1326}
1327
1328
1329static snd_pcm_ops_t snd_emu10k1_capture_mic_ops = {
1330 .open = snd_emu10k1_capture_mic_open,
1331 .close = snd_emu10k1_capture_mic_close,
1332 .ioctl = snd_pcm_lib_ioctl,
1333 .hw_params = snd_emu10k1_capture_hw_params,
1334 .hw_free = snd_emu10k1_capture_hw_free,
1335 .prepare = snd_emu10k1_capture_prepare,
1336 .trigger = snd_emu10k1_capture_trigger,
1337 .pointer = snd_emu10k1_capture_pointer,
1338};
1339
1340static void snd_emu10k1_pcm_mic_free(snd_pcm_t *pcm)
1341{
1342 emu10k1_t *emu = pcm->private_data;
1343 emu->pcm_mic = NULL;
1344 snd_pcm_lib_preallocate_free_for_all(pcm);
1345}
1346
1347int __devinit snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
1348{
1349 snd_pcm_t *pcm;
1350 int err;
1351
1352 if (rpcm)
1353 *rpcm = NULL;
1354
1355 if ((err = snd_pcm_new(emu->card, "emu10k1 mic", device, 0, 1, &pcm)) < 0)
1356 return err;
1357
1358 pcm->private_data = emu;
1359 pcm->private_free = snd_emu10k1_pcm_mic_free;
1360
1361 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_mic_ops);
1362
1363 pcm->info_flags = 0;
1364 strcpy(pcm->name, "Mic Capture");
1365 emu->pcm_mic = pcm;
1366
1367 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
1368
1369 if (rpcm)
1370 *rpcm = pcm;
1371 return 0;
1372}
1373
1374static int snd_emu10k1_pcm_efx_voices_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1375{
1376 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
1377 int nefx = emu->audigy ? 64 : 32;
1378 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1379 uinfo->count = nefx;
1380 uinfo->value.integer.min = 0;
1381 uinfo->value.integer.max = 1;
1382 return 0;
1383}
1384
1385static int snd_emu10k1_pcm_efx_voices_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1386{
1387 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
1388 int nefx = emu->audigy ? 64 : 32;
1389 int idx;
1390
1391 spin_lock_irq(&emu->reg_lock);
1392 for (idx = 0; idx < nefx; idx++)
1393 ucontrol->value.integer.value[idx] = (emu->efx_voices_mask[idx / 32] & (1 << (idx % 32))) ? 1 : 0;
1394 spin_unlock_irq(&emu->reg_lock);
1395 return 0;
1396}
1397
1398static int snd_emu10k1_pcm_efx_voices_mask_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1399{
1400 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
1401 unsigned int nval[2], bits;
1402 int nefx = emu->audigy ? 64 : 32;
1403 int nefxb = emu->audigy ? 7 : 6;
1404 int change, idx;
1405
1406 nval[0] = nval[1] = 0;
1407 for (idx = 0, bits = 0; idx < nefx; idx++)
1408 if (ucontrol->value.integer.value[idx]) {
1409 nval[idx / 32] |= 1 << (idx % 32);
1410 bits++;
1411 }
1412
1413 for (idx = 0; idx < nefxb; idx++)
1414 if (1 << idx == bits)
1415 break;
1416
1417 if (idx >= nefxb)
1418 return -EINVAL;
1419
1420 spin_lock_irq(&emu->reg_lock);
1421 change = (nval[0] != emu->efx_voices_mask[0]) ||
1422 (nval[1] != emu->efx_voices_mask[1]);
1423 emu->efx_voices_mask[0] = nval[0];
1424 emu->efx_voices_mask[1] = nval[1];
1425 spin_unlock_irq(&emu->reg_lock);
1426 return change;
1427}
1428
1429static snd_kcontrol_new_t snd_emu10k1_pcm_efx_voices_mask = {
1430 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1431 .name = "Captured FX8010 Outputs",
1432 .info = snd_emu10k1_pcm_efx_voices_mask_info,
1433 .get = snd_emu10k1_pcm_efx_voices_mask_get,
1434 .put = snd_emu10k1_pcm_efx_voices_mask_put
1435};
1436
1437static snd_pcm_ops_t snd_emu10k1_capture_efx_ops = {
1438 .open = snd_emu10k1_capture_efx_open,
1439 .close = snd_emu10k1_capture_efx_close,
1440 .ioctl = snd_pcm_lib_ioctl,
1441 .hw_params = snd_emu10k1_capture_hw_params,
1442 .hw_free = snd_emu10k1_capture_hw_free,
1443 .prepare = snd_emu10k1_capture_prepare,
1444 .trigger = snd_emu10k1_capture_trigger,
1445 .pointer = snd_emu10k1_capture_pointer,
1446};
1447
1448
1449/* EFX playback */
1450
1451#define INITIAL_TRAM_SHIFT 14
1452#define INITIAL_TRAM_POS(size) ((((size) / 2) - INITIAL_TRAM_SHIFT) - 1)
1453
1454static void snd_emu10k1_fx8010_playback_irq(emu10k1_t *emu, void *private_data)
1455{
1456 snd_pcm_substream_t *substream = private_data;
1457 snd_pcm_period_elapsed(substream);
1458}
1459
1460static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left,
1461 unsigned short *dst_right,
1462 unsigned short *src,
1463 unsigned int count,
1464 unsigned int tram_shift)
1465{
1466 // printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count);
1467 if ((tram_shift & 1) == 0) {
1468 while (count--) {
1469 *dst_left-- = *src++;
1470 *dst_right-- = *src++;
1471 }
1472 } else {
1473 while (count--) {
1474 *dst_right-- = *src++;
1475 *dst_left-- = *src++;
1476 }
1477 }
1478}
1479
1480static void fx8010_pb_trans_copy(snd_pcm_substream_t *substream,
1481 snd_pcm_indirect_t *rec, size_t bytes)
1482{
1483 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1484 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1485 unsigned int tram_size = pcm->buffer_size;
1486 unsigned short *src = (unsigned short *)(substream->runtime->dma_area + rec->sw_data);
1487 unsigned int frames = bytes >> 2, count;
1488 unsigned int tram_pos = pcm->tram_pos;
1489 unsigned int tram_shift = pcm->tram_shift;
1490
1491 while (frames > tram_pos) {
1492 count = tram_pos + 1;
1493 snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + tram_pos,
1494 (unsigned short *)emu->fx8010.etram_pages.area + tram_pos + tram_size / 2,
1495 src, count, tram_shift);
1496 src += count * 2;
1497 frames -= count;
1498 tram_pos = (tram_size / 2) - 1;
1499 tram_shift++;
1500 }
1501 snd_emu10k1_fx8010_playback_tram_poke1((unsigned short *)emu->fx8010.etram_pages.area + tram_pos,
1502 (unsigned short *)emu->fx8010.etram_pages.area + tram_pos + tram_size / 2,
1503 src, frames, tram_shift);
1504 tram_pos -= frames;
1505 pcm->tram_pos = tram_pos;
1506 pcm->tram_shift = tram_shift;
1507}
1508
1509static int snd_emu10k1_fx8010_playback_transfer(snd_pcm_substream_t *substream)
1510{
1511 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1512 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1513
1514 snd_pcm_indirect_playback_transfer(substream, &pcm->pcm_rec, fx8010_pb_trans_copy);
1515 return 0;
1516}
1517
1518static int snd_emu10k1_fx8010_playback_hw_params(snd_pcm_substream_t * substream,
1519 snd_pcm_hw_params_t * hw_params)
1520{
1521 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
1522}
1523
1524static int snd_emu10k1_fx8010_playback_hw_free(snd_pcm_substream_t * substream)
1525{
1526 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1527 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1528 unsigned int i;
1529
1530 for (i = 0; i < pcm->channels; i++)
1531 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, 0);
1532 snd_pcm_lib_free_pages(substream);
1533 return 0;
1534}
1535
1536static int snd_emu10k1_fx8010_playback_prepare(snd_pcm_substream_t * substream)
1537{
1538 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1539 snd_pcm_runtime_t *runtime = substream->runtime;
1540 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1541 unsigned int i;
1542
1543 // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2);
1544 memset(&pcm->pcm_rec, 0, sizeof(pcm->pcm_rec));
1545 pcm->pcm_rec.hw_buffer_size = pcm->buffer_size * 2; /* byte size */
1546 pcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
1547 pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
1548 pcm->tram_shift = 0;
1549 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_running, 0, 0); /* reset */
1550 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0); /* reset */
1551 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_size, 0, runtime->buffer_size);
1552 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_ptr, 0, 0); /* reset ptr number */
1553 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_count, 0, runtime->period_size);
1554 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_tmpcount, 0, runtime->period_size);
1555 for (i = 0; i < pcm->channels; i++)
1556 snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + 0x80 + pcm->etram[i], 0, (TANKMEMADDRREG_READ|TANKMEMADDRREG_ALIGN) + i * (runtime->buffer_size / pcm->channels));
1557 return 0;
1558}
1559
1560static int snd_emu10k1_fx8010_playback_trigger(snd_pcm_substream_t * substream, int cmd)
1561{
1562 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1563 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1564 int result = 0;
1565
1566 spin_lock(&emu->reg_lock);
1567 switch (cmd) {
1568 case SNDRV_PCM_TRIGGER_START:
1569 /* follow thru */
1570 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1571#ifdef EMU10K1_SET_AC3_IEC958
1572 {
1573 int i;
1574 for (i = 0; i < 3; i++) {
1575 unsigned int bits;
1576 bits = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1577 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS |
1578 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT | SPCS_NOTAUDIODATA;
1579 snd_emu10k1_ptr_write(emu, SPCS0 + i, 0, bits);
1580 }
1581 }
1582#endif
1583 result = snd_emu10k1_fx8010_register_irq_handler(emu, snd_emu10k1_fx8010_playback_irq, pcm->gpr_running, substream, &pcm->irq);
1584 if (result < 0)
1585 goto __err;
1586 snd_emu10k1_fx8010_playback_transfer(substream); /* roll the ball */
1587 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 1);
1588 break;
1589 case SNDRV_PCM_TRIGGER_STOP:
1590 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1591 snd_emu10k1_fx8010_unregister_irq_handler(emu, pcm->irq); pcm->irq = NULL;
1592 snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0);
1593 pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
1594 pcm->tram_shift = 0;
1595 break;
1596 default:
1597 result = -EINVAL;
1598 break;
1599 }
1600 __err:
1601 spin_unlock(&emu->reg_lock);
1602 return result;
1603}
1604
1605static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(snd_pcm_substream_t * substream)
1606{
1607 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1608 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1609 size_t ptr; /* byte pointer */
1610
1611 if (!snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_trigger, 0))
1612 return 0;
1613 ptr = snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_ptr, 0) << 2;
1614 return snd_pcm_indirect_playback_pointer(substream, &pcm->pcm_rec, ptr);
1615}
1616
1617static snd_pcm_hardware_t snd_emu10k1_fx8010_playback =
1618{
1619 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1620 /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE),
1621 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
1622 .rates = SNDRV_PCM_RATE_48000,
1623 .rate_min = 48000,
1624 .rate_max = 48000,
1625 .channels_min = 1,
1626 .channels_max = 1,
1627 .buffer_bytes_max = (128*1024),
1628 .period_bytes_min = 1024,
1629 .period_bytes_max = (128*1024),
1630 .periods_min = 1,
1631 .periods_max = 1024,
1632 .fifo_size = 0,
1633};
1634
1635static int snd_emu10k1_fx8010_playback_open(snd_pcm_substream_t * substream)
1636{
1637 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1638 snd_pcm_runtime_t *runtime = substream->runtime;
1639 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1640
1641 runtime->hw = snd_emu10k1_fx8010_playback;
1642 runtime->hw.channels_min = runtime->hw.channels_max = pcm->channels;
1643 runtime->hw.period_bytes_max = (pcm->buffer_size * 2) / 2;
1644 spin_lock_irq(&emu->reg_lock);
1645 if (pcm->valid == 0) {
1646 spin_unlock_irq(&emu->reg_lock);
1647 return -ENODEV;
1648 }
1649 pcm->opened = 1;
1650 spin_unlock_irq(&emu->reg_lock);
1651 return 0;
1652}
1653
1654static int snd_emu10k1_fx8010_playback_close(snd_pcm_substream_t * substream)
1655{
1656 emu10k1_t *emu = snd_pcm_substream_chip(substream);
1657 snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
1658
1659 spin_lock_irq(&emu->reg_lock);
1660 pcm->opened = 0;
1661 spin_unlock_irq(&emu->reg_lock);
1662 return 0;
1663}
1664
1665static snd_pcm_ops_t snd_emu10k1_fx8010_playback_ops = {
1666 .open = snd_emu10k1_fx8010_playback_open,
1667 .close = snd_emu10k1_fx8010_playback_close,
1668 .ioctl = snd_pcm_lib_ioctl,
1669 .hw_params = snd_emu10k1_fx8010_playback_hw_params,
1670 .hw_free = snd_emu10k1_fx8010_playback_hw_free,
1671 .prepare = snd_emu10k1_fx8010_playback_prepare,
1672 .trigger = snd_emu10k1_fx8010_playback_trigger,
1673 .pointer = snd_emu10k1_fx8010_playback_pointer,
1674 .ack = snd_emu10k1_fx8010_playback_transfer,
1675};
1676
1677static void snd_emu10k1_pcm_efx_free(snd_pcm_t *pcm)
1678{
1679 emu10k1_t *emu = pcm->private_data;
1680 emu->pcm_efx = NULL;
1681 snd_pcm_lib_preallocate_free_for_all(pcm);
1682}
1683
1684int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
1685{
1686 snd_pcm_t *pcm;
1687 int err;
1688
1689 if (rpcm)
1690 *rpcm = NULL;
1691
1692 if ((err = snd_pcm_new(emu->card, "emu10k1 efx", device, 8, 1, &pcm)) < 0)
1693 return err;
1694
1695 pcm->private_data = emu;
1696 pcm->private_free = snd_emu10k1_pcm_efx_free;
1697
1698 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
1699 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_efx_ops);
1700
1701 pcm->info_flags = 0;
1702 strcpy(pcm->name, "Multichannel Capture/PT Playback");
1703 emu->pcm_efx = pcm;
1704 if (rpcm)
1705 *rpcm = pcm;
1706
1707 /* EFX capture - record the "FXBUS2" channels, by default we connect the EXTINs
1708 * to these
1709 */
1710
1711 /* emu->efx_voices_mask[0] = FXWC_DEFAULTROUTE_C | FXWC_DEFAULTROUTE_A; */
1712 if (emu->audigy) {
1713 emu->efx_voices_mask[0] = 0;
1714 emu->efx_voices_mask[1] = 0xffff;
1715 } else {
1716 emu->efx_voices_mask[0] = 0xffff0000;
1717 emu->efx_voices_mask[1] = 0;
1718 }
1719 snd_ctl_add(emu->card, snd_ctl_new1(&snd_emu10k1_pcm_efx_voices_mask, emu));
1720
1721 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
1722
1723 return 0;
1724}
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
new file mode 100644
index 000000000000..d990d5eb45a8
--- /dev/null
+++ b/sound/pci/emu10k1/emuproc.c
@@ -0,0 +1,568 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips / proc interface routines
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/slab.h>
30#include <linux/init.h>
31#include <sound/core.h>
32#include <sound/emu10k1.h>
33
34static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu,
35 snd_info_buffer_t * buffer,
36 char *title,
37 int status_reg,
38 int rate_reg)
39{
40 static char *clkaccy[4] = { "1000ppm", "50ppm", "variable", "unknown" };
41 static int samplerate[16] = { 44100, 1, 48000, 32000, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
42 static char *channel[16] = { "unspec", "left", "right", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" };
43 static char *emphasis[8] = { "none", "50/15 usec 2 channel", "2", "3", "4", "5", "6", "7" };
44 unsigned int status, rate = 0;
45
46 status = snd_emu10k1_ptr_read(emu, status_reg, 0);
47 if (rate_reg > 0)
48 rate = snd_emu10k1_ptr_read(emu, rate_reg, 0);
49
50 snd_iprintf(buffer, "\n%s\n", title);
51
52 snd_iprintf(buffer, "Professional Mode : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no");
53 snd_iprintf(buffer, "Not Audio Data : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no");
54 snd_iprintf(buffer, "Copyright : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no");
55 snd_iprintf(buffer, "Emphasis : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]);
56 snd_iprintf(buffer, "Mode : %i\n", (status & SPCS_MODEMASK) >> 6);
57 snd_iprintf(buffer, "Category Code : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8);
58 snd_iprintf(buffer, "Generation Status : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy");
59 snd_iprintf(buffer, "Source Mask : %i\n", (status & SPCS_SOURCENUMMASK) >> 16);
60 snd_iprintf(buffer, "Channel Number : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]);
61 snd_iprintf(buffer, "Sample Rate : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]);
62 snd_iprintf(buffer, "Clock Accuracy : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]);
63
64 if (rate_reg > 0) {
65 snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off");
66 snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off");
67 snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", rate & SRCS_ESTSAMPLERATE);
68 }
69}
70
71static void snd_emu10k1_proc_read(snd_info_entry_t *entry,
72 snd_info_buffer_t * buffer)
73{
74 /* FIXME - output names are in emufx.c too */
75 static char *creative_outs[32] = {
76 /* 00 */ "AC97 Left",
77 /* 01 */ "AC97 Right",
78 /* 02 */ "Optical IEC958 Left",
79 /* 03 */ "Optical IEC958 Right",
80 /* 04 */ "Center",
81 /* 05 */ "LFE",
82 /* 06 */ "Headphone Left",
83 /* 07 */ "Headphone Right",
84 /* 08 */ "Surround Left",
85 /* 09 */ "Surround Right",
86 /* 10 */ "PCM Capture Left",
87 /* 11 */ "PCM Capture Right",
88 /* 12 */ "MIC Capture",
89 /* 13 */ "AC97 Surround Left",
90 /* 14 */ "AC97 Surround Right",
91 /* 15 */ "???",
92 /* 16 */ "???",
93 /* 17 */ "Analog Center",
94 /* 18 */ "Analog LFE",
95 /* 19 */ "???",
96 /* 20 */ "???",
97 /* 21 */ "???",
98 /* 22 */ "???",
99 /* 23 */ "???",
100 /* 24 */ "???",
101 /* 25 */ "???",
102 /* 26 */ "???",
103 /* 27 */ "???",
104 /* 28 */ "???",
105 /* 29 */ "???",
106 /* 30 */ "???",
107 /* 31 */ "???"
108 };
109
110 static char *audigy_outs[64] = {
111 /* 00 */ "Digital Front Left",
112 /* 01 */ "Digital Front Right",
113 /* 02 */ "Digital Center",
114 /* 03 */ "Digital LEF",
115 /* 04 */ "Headphone Left",
116 /* 05 */ "Headphone Right",
117 /* 06 */ "Digital Rear Left",
118 /* 07 */ "Digital Rear Right",
119 /* 08 */ "Front Left",
120 /* 09 */ "Front Right",
121 /* 10 */ "Center",
122 /* 11 */ "LFE",
123 /* 12 */ "???",
124 /* 13 */ "???",
125 /* 14 */ "Rear Left",
126 /* 15 */ "Rear Right",
127 /* 16 */ "AC97 Front Left",
128 /* 17 */ "AC97 Front Right",
129 /* 18 */ "ADC Caputre Left",
130 /* 19 */ "ADC Capture Right",
131 /* 20 */ "???",
132 /* 21 */ "???",
133 /* 22 */ "???",
134 /* 23 */ "???",
135 /* 24 */ "???",
136 /* 25 */ "???",
137 /* 26 */ "???",
138 /* 27 */ "???",
139 /* 28 */ "???",
140 /* 29 */ "???",
141 /* 30 */ "???",
142 /* 31 */ "???",
143 /* 32 */ "FXBUS2_0",
144 /* 33 */ "FXBUS2_1",
145 /* 34 */ "FXBUS2_2",
146 /* 35 */ "FXBUS2_3",
147 /* 36 */ "FXBUS2_4",
148 /* 37 */ "FXBUS2_5",
149 /* 38 */ "FXBUS2_6",
150 /* 39 */ "FXBUS2_7",
151 /* 40 */ "FXBUS2_8",
152 /* 41 */ "FXBUS2_9",
153 /* 42 */ "FXBUS2_10",
154 /* 43 */ "FXBUS2_11",
155 /* 44 */ "FXBUS2_12",
156 /* 45 */ "FXBUS2_13",
157 /* 46 */ "FXBUS2_14",
158 /* 47 */ "FXBUS2_15",
159 /* 48 */ "FXBUS2_16",
160 /* 49 */ "FXBUS2_17",
161 /* 50 */ "FXBUS2_18",
162 /* 51 */ "FXBUS2_19",
163 /* 52 */ "FXBUS2_20",
164 /* 53 */ "FXBUS2_21",
165 /* 54 */ "FXBUS2_22",
166 /* 55 */ "FXBUS2_23",
167 /* 56 */ "FXBUS2_24",
168 /* 57 */ "FXBUS2_25",
169 /* 58 */ "FXBUS2_26",
170 /* 59 */ "FXBUS2_27",
171 /* 60 */ "FXBUS2_28",
172 /* 61 */ "FXBUS2_29",
173 /* 62 */ "FXBUS2_30",
174 /* 63 */ "FXBUS2_31"
175 };
176
177 emu10k1_t *emu = entry->private_data;
178 unsigned int val, val1;
179 int nefx = emu->audigy ? 64 : 32;
180 char **outputs = emu->audigy ? audigy_outs : creative_outs;
181 int idx;
182
183 snd_iprintf(buffer, "EMU10K1\n\n");
184 snd_iprintf(buffer, "Card : %s\n",
185 emu->audigy ? "Audigy" : (emu->APS ? "EMU APS" : "Creative"));
186 snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size);
187 snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2);
188 snd_iprintf(buffer, "\n");
189 snd_iprintf(buffer, "Effect Send Routing :\n");
190 for (idx = 0; idx < NUM_G; idx++) {
191 val = emu->audigy ?
192 snd_emu10k1_ptr_read(emu, A_FXRT1, idx) :
193 snd_emu10k1_ptr_read(emu, FXRT, idx);
194 val1 = emu->audigy ?
195 snd_emu10k1_ptr_read(emu, A_FXRT2, idx) :
196 0;
197 if (emu->audigy) {
198 snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i, ",
199 idx,
200 val & 0x3f,
201 (val >> 8) & 0x3f,
202 (val >> 16) & 0x3f,
203 (val >> 24) & 0x3f);
204 snd_iprintf(buffer, "E=%i, F=%i, G=%i, H=%i\n",
205 val1 & 0x3f,
206 (val1 >> 8) & 0x3f,
207 (val1 >> 16) & 0x3f,
208 (val1 >> 24) & 0x3f);
209 } else {
210 snd_iprintf(buffer, "Ch%i: A=%i, B=%i, C=%i, D=%i\n",
211 idx,
212 (val >> 16) & 0x0f,
213 (val >> 20) & 0x0f,
214 (val >> 24) & 0x0f,
215 (val >> 28) & 0x0f);
216 }
217 }
218 snd_iprintf(buffer, "\nCaptured FX Outputs :\n");
219 for (idx = 0; idx < nefx; idx++) {
220 if (emu->efx_voices_mask[idx/32] & (1 << (idx%32)))
221 snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]);
222 }
223 snd_iprintf(buffer, "\nAll FX Outputs :\n");
224 for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++)
225 snd_iprintf(buffer, " Output %02i [%s]\n", idx, outputs[idx]);
226 snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 0", SPCS0, -1);
227 snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 1", SPCS1, -1);
228 snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 2/3", SPCS2, -1);
229 snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF", CDCS, CDSRCS);
230 snd_emu10k1_proc_spdif_status(emu, buffer, "General purpose S/PDIF", GPSCS, GPSRCS);
231 val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0);
232 snd_iprintf(buffer, "\nZoomed Video\n");
233 snd_iprintf(buffer, "Rate Locked : %s\n", val & SRCS_RATELOCKED ? "on" : "off");
234 snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", val & SRCS_ESTSAMPLERATE);
235}
236
237static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry,
238 snd_info_buffer_t * buffer)
239{
240 u32 pc;
241 emu10k1_t *emu = entry->private_data;
242
243 snd_iprintf(buffer, "FX8010 Instruction List '%s'\n", emu->fx8010.name);
244 snd_iprintf(buffer, " Code dump :\n");
245 for (pc = 0; pc < (emu->audigy ? 1024 : 512); pc++) {
246 u32 low, high;
247
248 low = snd_emu10k1_efx_read(emu, pc * 2);
249 high = snd_emu10k1_efx_read(emu, pc * 2 + 1);
250 if (emu->audigy)
251 snd_iprintf(buffer, " OP(0x%02x, 0x%03x, 0x%03x, 0x%03x, 0x%03x) /* 0x%04x: 0x%08x%08x */\n",
252 (high >> 24) & 0x0f,
253 (high >> 12) & 0x7ff,
254 (high >> 0) & 0x7ff,
255 (low >> 12) & 0x7ff,
256 (low >> 0) & 0x7ff,
257 pc,
258 high, low);
259 else
260 snd_iprintf(buffer, " OP(0x%02x, 0x%03x, 0x%03x, 0x%03x, 0x%03x) /* 0x%04x: 0x%08x%08x */\n",
261 (high >> 20) & 0x0f,
262 (high >> 10) & 0x3ff,
263 (high >> 0) & 0x3ff,
264 (low >> 10) & 0x3ff,
265 (low >> 0) & 0x3ff,
266 pc,
267 high, low);
268 }
269}
270
271#define TOTAL_SIZE_GPR (0x100*4)
272#define A_TOTAL_SIZE_GPR (0x200*4)
273#define TOTAL_SIZE_TANKMEM_DATA (0xa0*4)
274#define TOTAL_SIZE_TANKMEM_ADDR (0xa0*4)
275#define A_TOTAL_SIZE_TANKMEM_DATA (0x100*4)
276#define A_TOTAL_SIZE_TANKMEM_ADDR (0x100*4)
277#define TOTAL_SIZE_CODE (0x200*8)
278#define A_TOTAL_SIZE_CODE (0x400*8)
279
280static long snd_emu10k1_fx8010_read(snd_info_entry_t *entry, void *file_private_data,
281 struct file *file, char __user *buf,
282 unsigned long count, unsigned long pos)
283{
284 long size;
285 emu10k1_t *emu = entry->private_data;
286 unsigned int offset;
287 int tram_addr = 0;
288
289 if (!strcmp(entry->name, "fx8010_tram_addr")) {
290 offset = TANKMEMADDRREGBASE;
291 tram_addr = 1;
292 } else if (!strcmp(entry->name, "fx8010_tram_data")) {
293 offset = TANKMEMDATAREGBASE;
294 } else if (!strcmp(entry->name, "fx8010_code")) {
295 offset = emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
296 } else {
297 offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE;
298 }
299 size = count;
300 if (pos + size > entry->size)
301 size = (long)entry->size - pos;
302 if (size > 0) {
303 unsigned int *tmp;
304 long res;
305 unsigned int idx;
306 if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL)
307 return -ENOMEM;
308 for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++)
309 if (tram_addr && emu->audigy) {
310 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11;
311 tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20;
312 } else
313 tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0);
314 if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size))
315 res = -EFAULT;
316 else {
317 res = size;
318 }
319 kfree(tmp);
320 return res;
321 }
322 return 0;
323}
324
325static void snd_emu10k1_proc_voices_read(snd_info_entry_t *entry,
326 snd_info_buffer_t * buffer)
327{
328 emu10k1_t *emu = entry->private_data;
329 emu10k1_voice_t *voice;
330 int idx;
331
332 snd_iprintf(buffer, "ch\tuse\tpcm\tefx\tsynth\tmidi\n");
333 for (idx = 0; idx < NUM_G; idx++) {
334 voice = &emu->voices[idx];
335 snd_iprintf(buffer, "%i\t%i\t%i\t%i\t%i\t%i\n",
336 idx,
337 voice->use,
338 voice->pcm,
339 voice->efx,
340 voice->synth,
341 voice->midi);
342 }
343}
344
345#ifdef CONFIG_SND_DEBUG
346static void snd_emu_proc_io_reg_read(snd_info_entry_t *entry,
347 snd_info_buffer_t * buffer)
348{
349 emu10k1_t *emu = entry->private_data;
350 unsigned long value;
351 unsigned long flags;
352 int i;
353 snd_iprintf(buffer, "IO Registers:\n\n");
354 for(i = 0; i < 0x40; i+=4) {
355 spin_lock_irqsave(&emu->emu_lock, flags);
356 value = inl(emu->port + i);
357 spin_unlock_irqrestore(&emu->emu_lock, flags);
358 snd_iprintf(buffer, "%02X: %08lX\n", i, value);
359 }
360}
361
362static void snd_emu_proc_io_reg_write(snd_info_entry_t *entry,
363 snd_info_buffer_t * buffer)
364{
365 emu10k1_t *emu = entry->private_data;
366 unsigned long flags;
367 char line[64];
368 u32 reg, val;
369 while (!snd_info_get_line(buffer, line, sizeof(line))) {
370 if (sscanf(line, "%x %x", &reg, &val) != 2)
371 continue;
372 if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) {
373 spin_lock_irqsave(&emu->emu_lock, flags);
374 outl(val, emu->port + (reg & 0xfffffffc));
375 spin_unlock_irqrestore(&emu->emu_lock, flags);
376 }
377 }
378}
379
380static unsigned int snd_ptr_read(emu10k1_t * emu,
381 unsigned int iobase,
382 unsigned int reg,
383 unsigned int chn)
384{
385 unsigned long flags;
386 unsigned int regptr, val;
387
388 regptr = (reg << 16) | chn;
389
390 spin_lock_irqsave(&emu->emu_lock, flags);
391 outl(regptr, emu->port + iobase + PTR);
392 val = inl(emu->port + iobase + DATA);
393 spin_unlock_irqrestore(&emu->emu_lock, flags);
394 return val;
395}
396
397static void snd_ptr_write(emu10k1_t *emu,
398 unsigned int iobase,
399 unsigned int reg,
400 unsigned int chn,
401 unsigned int data)
402{
403 unsigned int regptr;
404 unsigned long flags;
405
406 regptr = (reg << 16) | chn;
407
408 spin_lock_irqsave(&emu->emu_lock, flags);
409 outl(regptr, emu->port + iobase + PTR);
410 outl(data, emu->port + iobase + DATA);
411 spin_unlock_irqrestore(&emu->emu_lock, flags);
412}
413
414
415static void snd_emu_proc_ptr_reg_read(snd_info_entry_t *entry,
416 snd_info_buffer_t * buffer, int iobase, int offset, int length, int voices)
417{
418 emu10k1_t *emu = entry->private_data;
419 unsigned long value;
420 int i,j;
421 if (offset+length > 0x80) {
422 snd_iprintf(buffer, "Input values out of range\n");
423 return;
424 }
425 snd_iprintf(buffer, "Registers 0x%x\n", iobase);
426 for(i = offset; i < offset+length; i++) {
427 snd_iprintf(buffer, "%02X: ",i);
428 for (j = 0; j < voices; j++) {
429 if(iobase == 0)
430 value = snd_ptr_read(emu, 0, i, j);
431 else
432 value = snd_ptr_read(emu, 0x20, i, j);
433 snd_iprintf(buffer, "%08lX ", value);
434 }
435 snd_iprintf(buffer, "\n");
436 }
437}
438
439static void snd_emu_proc_ptr_reg_write(snd_info_entry_t *entry,
440 snd_info_buffer_t * buffer, int iobase)
441{
442 emu10k1_t *emu = entry->private_data;
443 char line[64];
444 unsigned int reg, channel_id , val;
445 while (!snd_info_get_line(buffer, line, sizeof(line))) {
446 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
447 continue;
448 if ((reg < 0x80) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) )
449 snd_ptr_write(emu, iobase, reg, channel_id, val);
450 }
451}
452
453static void snd_emu_proc_ptr_reg_write00(snd_info_entry_t *entry,
454 snd_info_buffer_t * buffer)
455{
456 snd_emu_proc_ptr_reg_write(entry, buffer, 0);
457}
458
459static void snd_emu_proc_ptr_reg_write20(snd_info_entry_t *entry,
460 snd_info_buffer_t * buffer)
461{
462 snd_emu_proc_ptr_reg_write(entry, buffer, 0x20);
463}
464
465
466static void snd_emu_proc_ptr_reg_read00a(snd_info_entry_t *entry,
467 snd_info_buffer_t * buffer)
468{
469 snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0, 0x40, 64);
470}
471
472static void snd_emu_proc_ptr_reg_read00b(snd_info_entry_t *entry,
473 snd_info_buffer_t * buffer)
474{
475 snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0x40, 0x40, 64);
476}
477
478static void snd_emu_proc_ptr_reg_read20a(snd_info_entry_t *entry,
479 snd_info_buffer_t * buffer)
480{
481 snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0, 0x40, 4);
482}
483
484static void snd_emu_proc_ptr_reg_read20b(snd_info_entry_t *entry,
485 snd_info_buffer_t * buffer)
486{
487 snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x40, 0x40, 4);
488}
489#endif
490
491static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = {
492 .read = snd_emu10k1_fx8010_read,
493};
494
495int __devinit snd_emu10k1_proc_init(emu10k1_t * emu)
496{
497 snd_info_entry_t *entry;
498#ifdef CONFIG_SND_DEBUG
499 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
500 snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read);
501 entry->c.text.write_size = 64;
502 entry->c.text.write = snd_emu_proc_io_reg_write;
503 }
504 if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) {
505 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00a);
506 entry->c.text.write_size = 64;
507 entry->c.text.write = snd_emu_proc_ptr_reg_write00;
508 }
509 if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) {
510 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00b);
511 entry->c.text.write_size = 64;
512 entry->c.text.write = snd_emu_proc_ptr_reg_write00;
513 }
514 if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) {
515 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20a);
516 entry->c.text.write_size = 64;
517 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
518 }
519 if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) {
520 snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20b);
521 entry->c.text.write_size = 64;
522 entry->c.text.write = snd_emu_proc_ptr_reg_write20;
523 }
524#endif
525
526 if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
527 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read);
528
529 if (! snd_card_proc_new(emu->card, "voices", &entry))
530 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read);
531
532 if (! snd_card_proc_new(emu->card, "fx8010_gpr", &entry)) {
533 entry->content = SNDRV_INFO_CONTENT_DATA;
534 entry->private_data = emu;
535 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
536 entry->size = emu->audigy ? A_TOTAL_SIZE_GPR : TOTAL_SIZE_GPR;
537 entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
538 }
539 if (! snd_card_proc_new(emu->card, "fx8010_tram_data", &entry)) {
540 entry->content = SNDRV_INFO_CONTENT_DATA;
541 entry->private_data = emu;
542 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
543 entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_DATA : TOTAL_SIZE_TANKMEM_DATA ;
544 entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
545 }
546 if (! snd_card_proc_new(emu->card, "fx8010_tram_addr", &entry)) {
547 entry->content = SNDRV_INFO_CONTENT_DATA;
548 entry->private_data = emu;
549 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
550 entry->size = emu->audigy ? A_TOTAL_SIZE_TANKMEM_ADDR : TOTAL_SIZE_TANKMEM_ADDR ;
551 entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
552 }
553 if (! snd_card_proc_new(emu->card, "fx8010_code", &entry)) {
554 entry->content = SNDRV_INFO_CONTENT_DATA;
555 entry->private_data = emu;
556 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
557 entry->size = emu->audigy ? A_TOTAL_SIZE_CODE : TOTAL_SIZE_CODE;
558 entry->c.ops = &snd_emu10k1_proc_ops_fx8010;
559 }
560 if (! snd_card_proc_new(emu->card, "fx8010_acode", &entry)) {
561 entry->content = SNDRV_INFO_CONTENT_TEXT;
562 entry->private_data = emu;
563 entry->mode = S_IFREG | S_IRUGO /*| S_IWUSR*/;
564 entry->c.text.read_size = 128*1024;
565 entry->c.text.read = snd_emu10k1_proc_acode_read;
566 }
567 return 0;
568}
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
new file mode 100644
index 000000000000..b9d3ae0dcab7
--- /dev/null
+++ b/sound/pci/emu10k1/io.c
@@ -0,0 +1,404 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/time.h>
30#include <sound/core.h>
31#include <sound/emu10k1.h>
32
33unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn)
34{
35 unsigned long flags;
36 unsigned int regptr, val;
37 unsigned int mask;
38
39 mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
40 regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
41
42 if (reg & 0xff000000) {
43 unsigned char size, offset;
44
45 size = (reg >> 24) & 0x3f;
46 offset = (reg >> 16) & 0x1f;
47 mask = ((1 << size) - 1) << offset;
48
49 spin_lock_irqsave(&emu->emu_lock, flags);
50 outl(regptr, emu->port + PTR);
51 val = inl(emu->port + DATA);
52 spin_unlock_irqrestore(&emu->emu_lock, flags);
53
54 return (val & mask) >> offset;
55 } else {
56 spin_lock_irqsave(&emu->emu_lock, flags);
57 outl(regptr, emu->port + PTR);
58 val = inl(emu->port + DATA);
59 spin_unlock_irqrestore(&emu->emu_lock, flags);
60 return val;
61 }
62}
63
64void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data)
65{
66 unsigned int regptr;
67 unsigned long flags;
68 unsigned int mask;
69
70 mask = emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK;
71 regptr = ((reg << 16) & mask) | (chn & PTR_CHANNELNUM_MASK);
72
73 if (reg & 0xff000000) {
74 unsigned char size, offset;
75
76 size = (reg >> 24) & 0x3f;
77 offset = (reg >> 16) & 0x1f;
78 mask = ((1 << size) - 1) << offset;
79 data = (data << offset) & mask;
80
81 spin_lock_irqsave(&emu->emu_lock, flags);
82 outl(regptr, emu->port + PTR);
83 data |= inl(emu->port + DATA) & ~mask;
84 outl(data, emu->port + DATA);
85 spin_unlock_irqrestore(&emu->emu_lock, flags);
86 } else {
87 spin_lock_irqsave(&emu->emu_lock, flags);
88 outl(regptr, emu->port + PTR);
89 outl(data, emu->port + DATA);
90 spin_unlock_irqrestore(&emu->emu_lock, flags);
91 }
92}
93
94unsigned int snd_emu10k1_ptr20_read(emu10k1_t * emu,
95 unsigned int reg,
96 unsigned int chn)
97{
98 unsigned long flags;
99 unsigned int regptr, val;
100
101 regptr = (reg << 16) | chn;
102
103 spin_lock_irqsave(&emu->emu_lock, flags);
104 outl(regptr, emu->port + 0x20 + PTR);
105 val = inl(emu->port + 0x20 + DATA);
106 spin_unlock_irqrestore(&emu->emu_lock, flags);
107 return val;
108}
109
110void snd_emu10k1_ptr20_write(emu10k1_t *emu,
111 unsigned int reg,
112 unsigned int chn,
113 unsigned int data)
114{
115 unsigned int regptr;
116 unsigned long flags;
117
118 regptr = (reg << 16) | chn;
119
120 spin_lock_irqsave(&emu->emu_lock, flags);
121 outl(regptr, emu->port + 0x20 + PTR);
122 outl(data, emu->port + 0x20 + DATA);
123 spin_unlock_irqrestore(&emu->emu_lock, flags);
124}
125
126void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb)
127{
128 unsigned long flags;
129 unsigned int enable;
130
131 spin_lock_irqsave(&emu->emu_lock, flags);
132 enable = inl(emu->port + INTE) | intrenb;
133 outl(enable, emu->port + INTE);
134 spin_unlock_irqrestore(&emu->emu_lock, flags);
135}
136
137void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb)
138{
139 unsigned long flags;
140 unsigned int enable;
141
142 spin_lock_irqsave(&emu->emu_lock, flags);
143 enable = inl(emu->port + INTE) & ~intrenb;
144 outl(enable, emu->port + INTE);
145 spin_unlock_irqrestore(&emu->emu_lock, flags);
146}
147
148void snd_emu10k1_voice_intr_enable(emu10k1_t *emu, unsigned int voicenum)
149{
150 unsigned long flags;
151 unsigned int val;
152
153 spin_lock_irqsave(&emu->emu_lock, flags);
154 /* voice interrupt */
155 if (voicenum >= 32) {
156 outl(CLIEH << 16, emu->port + PTR);
157 val = inl(emu->port + DATA);
158 val |= 1 << (voicenum - 32);
159 } else {
160 outl(CLIEL << 16, emu->port + PTR);
161 val = inl(emu->port + DATA);
162 val |= 1 << voicenum;
163 }
164 outl(val, emu->port + DATA);
165 spin_unlock_irqrestore(&emu->emu_lock, flags);
166}
167
168void snd_emu10k1_voice_intr_disable(emu10k1_t *emu, unsigned int voicenum)
169{
170 unsigned long flags;
171 unsigned int val;
172
173 spin_lock_irqsave(&emu->emu_lock, flags);
174 /* voice interrupt */
175 if (voicenum >= 32) {
176 outl(CLIEH << 16, emu->port + PTR);
177 val = inl(emu->port + DATA);
178 val &= ~(1 << (voicenum - 32));
179 } else {
180 outl(CLIEL << 16, emu->port + PTR);
181 val = inl(emu->port + DATA);
182 val &= ~(1 << voicenum);
183 }
184 outl(val, emu->port + DATA);
185 spin_unlock_irqrestore(&emu->emu_lock, flags);
186}
187
188void snd_emu10k1_voice_intr_ack(emu10k1_t *emu, unsigned int voicenum)
189{
190 unsigned long flags;
191
192 spin_lock_irqsave(&emu->emu_lock, flags);
193 /* voice interrupt */
194 if (voicenum >= 32) {
195 outl(CLIPH << 16, emu->port + PTR);
196 voicenum = 1 << (voicenum - 32);
197 } else {
198 outl(CLIPL << 16, emu->port + PTR);
199 voicenum = 1 << voicenum;
200 }
201 outl(voicenum, emu->port + DATA);
202 spin_unlock_irqrestore(&emu->emu_lock, flags);
203}
204
205void snd_emu10k1_voice_half_loop_intr_enable(emu10k1_t *emu, unsigned int voicenum)
206{
207 unsigned long flags;
208 unsigned int val;
209
210 spin_lock_irqsave(&emu->emu_lock, flags);
211 /* voice interrupt */
212 if (voicenum >= 32) {
213 outl(HLIEH << 16, emu->port + PTR);
214 val = inl(emu->port + DATA);
215 val |= 1 << (voicenum - 32);
216 } else {
217 outl(HLIEL << 16, emu->port + PTR);
218 val = inl(emu->port + DATA);
219 val |= 1 << voicenum;
220 }
221 outl(val, emu->port + DATA);
222 spin_unlock_irqrestore(&emu->emu_lock, flags);
223}
224
225void snd_emu10k1_voice_half_loop_intr_disable(emu10k1_t *emu, unsigned int voicenum)
226{
227 unsigned long flags;
228 unsigned int val;
229
230 spin_lock_irqsave(&emu->emu_lock, flags);
231 /* voice interrupt */
232 if (voicenum >= 32) {
233 outl(HLIEH << 16, emu->port + PTR);
234 val = inl(emu->port + DATA);
235 val &= ~(1 << (voicenum - 32));
236 } else {
237 outl(HLIEL << 16, emu->port + PTR);
238 val = inl(emu->port + DATA);
239 val &= ~(1 << voicenum);
240 }
241 outl(val, emu->port + DATA);
242 spin_unlock_irqrestore(&emu->emu_lock, flags);
243}
244
245void snd_emu10k1_voice_half_loop_intr_ack(emu10k1_t *emu, unsigned int voicenum)
246{
247 unsigned long flags;
248
249 spin_lock_irqsave(&emu->emu_lock, flags);
250 /* voice interrupt */
251 if (voicenum >= 32) {
252 outl(HLIPH << 16, emu->port + PTR);
253 voicenum = 1 << (voicenum - 32);
254 } else {
255 outl(HLIPL << 16, emu->port + PTR);
256 voicenum = 1 << voicenum;
257 }
258 outl(voicenum, emu->port + DATA);
259 spin_unlock_irqrestore(&emu->emu_lock, flags);
260}
261
262void snd_emu10k1_voice_set_loop_stop(emu10k1_t *emu, unsigned int voicenum)
263{
264 unsigned long flags;
265 unsigned int sol;
266
267 spin_lock_irqsave(&emu->emu_lock, flags);
268 /* voice interrupt */
269 if (voicenum >= 32) {
270 outl(SOLEH << 16, emu->port + PTR);
271 sol = inl(emu->port + DATA);
272 sol |= 1 << (voicenum - 32);
273 } else {
274 outl(SOLEL << 16, emu->port + PTR);
275 sol = inl(emu->port + DATA);
276 sol |= 1 << voicenum;
277 }
278 outl(sol, emu->port + DATA);
279 spin_unlock_irqrestore(&emu->emu_lock, flags);
280}
281
282void snd_emu10k1_voice_clear_loop_stop(emu10k1_t *emu, unsigned int voicenum)
283{
284 unsigned long flags;
285 unsigned int sol;
286
287 spin_lock_irqsave(&emu->emu_lock, flags);
288 /* voice interrupt */
289 if (voicenum >= 32) {
290 outl(SOLEH << 16, emu->port + PTR);
291 sol = inl(emu->port + DATA);
292 sol &= ~(1 << (voicenum - 32));
293 } else {
294 outl(SOLEL << 16, emu->port + PTR);
295 sol = inl(emu->port + DATA);
296 sol &= ~(1 << voicenum);
297 }
298 outl(sol, emu->port + DATA);
299 spin_unlock_irqrestore(&emu->emu_lock, flags);
300}
301
302void snd_emu10k1_wait(emu10k1_t *emu, unsigned int wait)
303{
304 volatile unsigned count;
305 unsigned int newtime = 0, curtime;
306
307 curtime = inl(emu->port + WC) >> 6;
308 while (wait-- > 0) {
309 count = 0;
310 while (count++ < 16384) {
311 newtime = inl(emu->port + WC) >> 6;
312 if (newtime != curtime)
313 break;
314 }
315 if (count >= 16384)
316 break;
317 curtime = newtime;
318 }
319}
320
321unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg)
322{
323 emu10k1_t *emu = ac97->private_data;
324 unsigned long flags;
325 unsigned short val;
326
327 spin_lock_irqsave(&emu->emu_lock, flags);
328 outb(reg, emu->port + AC97ADDRESS);
329 val = inw(emu->port + AC97DATA);
330 spin_unlock_irqrestore(&emu->emu_lock, flags);
331 return val;
332}
333
334void snd_emu10k1_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short data)
335{
336 emu10k1_t *emu = ac97->private_data;
337 unsigned long flags;
338
339 spin_lock_irqsave(&emu->emu_lock, flags);
340 outb(reg, emu->port + AC97ADDRESS);
341 outw(data, emu->port + AC97DATA);
342 spin_unlock_irqrestore(&emu->emu_lock, flags);
343}
344
345/*
346 * convert rate to pitch
347 */
348
349unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate)
350{
351 static u32 logMagTable[128] = {
352 0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2,
353 0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5,
354 0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081,
355 0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191,
356 0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7,
357 0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829,
358 0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
359 0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26,
360 0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d,
361 0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885,
362 0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899,
363 0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c,
364 0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3,
365 0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
366 0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83,
367 0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df
368 };
369 static char logSlopeTable[128] = {
370 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
371 0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
372 0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
373 0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
374 0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
375 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
376 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
377 0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
378 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
379 0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
380 0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
381 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
382 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
383 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
384 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
385 0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
386 };
387 int i;
388
389 if (rate == 0)
390 return 0; /* Bail out if no leading "1" */
391 rate *= 11185; /* Scale 48000 to 0x20002380 */
392 for (i = 31; i > 0; i--) {
393 if (rate & 0x80000000) { /* Detect leading "1" */
394 return (((unsigned int) (i - 15) << 20) +
395 logMagTable[0x7f & (rate >> 24)] +
396 (0x7f & (rate >> 17)) *
397 logSlopeTable[0x7f & (rate >> 24)]);
398 }
399 rate <<= 1;
400 }
401
402 return 0; /* Should never reach this point */
403}
404
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
new file mode 100644
index 000000000000..b81a7cafff39
--- /dev/null
+++ b/sound/pci/emu10k1/irq.c
@@ -0,0 +1,189 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Routines for IRQ control of EMU10K1 chips
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/time.h>
30#include <sound/core.h>
31#include <sound/emu10k1.h>
32
33irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
34{
35 emu10k1_t *emu = dev_id;
36 unsigned int status, status2, orig_status, orig_status2;
37 int handled = 0;
38
39 while ((status = inl(emu->port + IPR)) != 0) {
40 // printk("irq - status = 0x%x\n", status);
41 orig_status = status;
42 handled = 1;
43 if (status & IPR_PCIERROR) {
44 snd_printk("interrupt: PCI error\n");
45 snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
46 status &= ~IPR_PCIERROR;
47 }
48 if (status & (IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE)) {
49 if (emu->hwvol_interrupt)
50 emu->hwvol_interrupt(emu, status);
51 else
52 snd_emu10k1_intr_disable(emu, INTE_VOLINCRENABLE|INTE_VOLDECRENABLE|INTE_MUTEENABLE);
53 status &= ~(IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE);
54 }
55 if (status & IPR_CHANNELLOOP) {
56 int voice;
57 int voice_max = status & IPR_CHANNELNUMBERMASK;
58 u32 val;
59 emu10k1_voice_t *pvoice = emu->voices;
60
61 val = snd_emu10k1_ptr_read(emu, CLIPL, 0);
62 for (voice = 0; voice <= voice_max; voice++) {
63 if (voice == 0x20)
64 val = snd_emu10k1_ptr_read(emu, CLIPH, 0);
65 if (val & 1) {
66 if (pvoice->use && pvoice->interrupt != NULL) {
67 pvoice->interrupt(emu, pvoice);
68 snd_emu10k1_voice_intr_ack(emu, voice);
69 } else {
70 snd_emu10k1_voice_intr_disable(emu, voice);
71 }
72 }
73 val >>= 1;
74 pvoice++;
75 }
76 val = snd_emu10k1_ptr_read(emu, HLIPL, 0);
77 for (voice = 0; voice <= voice_max; voice++) {
78 if (voice == 0x20)
79 val = snd_emu10k1_ptr_read(emu, HLIPH, 0);
80 if (val & 1) {
81 if (pvoice->use && pvoice->interrupt != NULL) {
82 pvoice->interrupt(emu, pvoice);
83 snd_emu10k1_voice_half_loop_intr_ack(emu, voice);
84 } else {
85 snd_emu10k1_voice_half_loop_intr_disable(emu, voice);
86 }
87 }
88 val >>= 1;
89 pvoice++;
90 }
91 status &= ~IPR_CHANNELLOOP;
92 }
93 status &= ~IPR_CHANNELNUMBERMASK;
94 if (status & (IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL)) {
95 if (emu->capture_interrupt)
96 emu->capture_interrupt(emu, status);
97 else
98 snd_emu10k1_intr_disable(emu, INTE_ADCBUFENABLE);
99 status &= ~(IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL);
100 }
101 if (status & (IPR_MICBUFFULL|IPR_MICBUFHALFFULL)) {
102 if (emu->capture_mic_interrupt)
103 emu->capture_mic_interrupt(emu, status);
104 else
105 snd_emu10k1_intr_disable(emu, INTE_MICBUFENABLE);
106 status &= ~(IPR_MICBUFFULL|IPR_MICBUFHALFFULL);
107 }
108 if (status & (IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL)) {
109 if (emu->capture_efx_interrupt)
110 emu->capture_efx_interrupt(emu, status);
111 else
112 snd_emu10k1_intr_disable(emu, INTE_EFXBUFENABLE);
113 status &= ~(IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL);
114 }
115 if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
116 if (emu->midi.interrupt)
117 emu->midi.interrupt(emu, status);
118 else
119 snd_emu10k1_intr_disable(emu, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
120 status &= ~(IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY);
121 }
122 if (status & (IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2)) {
123 if (emu->midi2.interrupt)
124 emu->midi2.interrupt(emu, status);
125 else
126 snd_emu10k1_intr_disable(emu, INTE_A_MIDITXENABLE2|INTE_A_MIDIRXENABLE2);
127 status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2);
128 }
129 if (status & IPR_INTERVALTIMER) {
130 if (emu->timer)
131 snd_timer_interrupt(emu->timer, emu->timer->sticks);
132 else
133 snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
134 status &= ~IPR_INTERVALTIMER;
135 }
136 if (status & (IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE)) {
137 if (emu->spdif_interrupt)
138 emu->spdif_interrupt(emu, status);
139 else
140 snd_emu10k1_intr_disable(emu, INTE_GPSPDIFENABLE|INTE_CDSPDIFENABLE);
141 status &= ~(IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE);
142 }
143 if (status & IPR_FXDSP) {
144 if (emu->dsp_interrupt)
145 emu->dsp_interrupt(emu);
146 else
147 snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
148 status &= ~IPR_FXDSP;
149 }
150 if (status) {
151 unsigned int bits;
152 //snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status);
153 //make sure any interrupts we don't handle are disabled:
154 bits = INTE_FXDSPENABLE |
155 INTE_PCIERRORENABLE |
156 INTE_VOLINCRENABLE |
157 INTE_VOLDECRENABLE |
158 INTE_MUTEENABLE |
159 INTE_MICBUFENABLE |
160 INTE_ADCBUFENABLE |
161 INTE_EFXBUFENABLE |
162 INTE_GPSPDIFENABLE |
163 INTE_CDSPDIFENABLE |
164 INTE_INTERVALTIMERENB |
165 INTE_MIDITXENABLE |
166 INTE_MIDIRXENABLE;
167 if (emu->audigy)
168 bits |= INTE_A_MIDITXENABLE2 | INTE_A_MIDIRXENABLE2;
169 snd_emu10k1_intr_disable(emu, bits);
170 }
171 outl(orig_status, emu->port + IPR); /* ack all */
172 }
173 if (emu->audigy && emu->revision == 4) { /* P16V */
174 while ((status2 = inl(emu->port + IPR2)) != 0) {
175 u32 mask = INTE2_PLAYBACK_CH_0_LOOP; /* Full Loop */
176 emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]);
177 orig_status2 = status2;
178 if(status2 & mask) {
179 if(pvoice->use) {
180 snd_pcm_period_elapsed(pvoice->epcm->substream);
181 } else {
182 snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use);
183 }
184 }
185 outl(orig_status2, emu->port + IPR2); /* ack all */
186 }
187 }
188 return IRQ_RETVAL(handled);
189}
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
new file mode 100644
index 000000000000..7a595f0dd7a1
--- /dev/null
+++ b/sound/pci/emu10k1/memory.c
@@ -0,0 +1,564 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
4 *
5 * EMU10K1 memory page allocation (PTB area)
6 *
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <sound/driver.h>
25#include <linux/pci.h>
26#include <linux/time.h>
27#include <sound/core.h>
28#include <sound/emu10k1.h>
29
30/* page arguments of these two macros are Emu page (4096 bytes), not like
31 * aligned pages in others
32 */
33#define __set_ptb_entry(emu,page,addr) \
34 (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page)))
35
36#define UNIT_PAGES (PAGE_SIZE / EMUPAGESIZE)
37#define MAX_ALIGN_PAGES (MAXPAGES / UNIT_PAGES)
38/* get aligned page from offset address */
39#define get_aligned_page(offset) ((offset) >> PAGE_SHIFT)
40/* get offset address from aligned page */
41#define aligned_page_offset(page) ((page) << PAGE_SHIFT)
42
43#if PAGE_SIZE == 4096
44/* page size == EMUPAGESIZE */
45/* fill PTB entrie(s) corresponding to page with addr */
46#define set_ptb_entry(emu,page,addr) __set_ptb_entry(emu,page,addr)
47/* fill PTB entrie(s) corresponding to page with silence pointer */
48#define set_silent_ptb(emu,page) __set_ptb_entry(emu,page,emu->silent_page.addr)
49#else
50/* fill PTB entries -- we need to fill UNIT_PAGES entries */
51static inline void set_ptb_entry(emu10k1_t *emu, int page, dma_addr_t addr)
52{
53 int i;
54 page *= UNIT_PAGES;
55 for (i = 0; i < UNIT_PAGES; i++, page++) {
56 __set_ptb_entry(emu, page, addr);
57 addr += EMUPAGESIZE;
58 }
59}
60static inline void set_silent_ptb(emu10k1_t *emu, int page)
61{
62 int i;
63 page *= UNIT_PAGES;
64 for (i = 0; i < UNIT_PAGES; i++, page++)
65 /* do not increment ptr */
66 __set_ptb_entry(emu, page, emu->silent_page.addr);
67}
68#endif /* PAGE_SIZE */
69
70
71/*
72 */
73static int synth_alloc_pages(emu10k1_t *hw, emu10k1_memblk_t *blk);
74static int synth_free_pages(emu10k1_t *hw, emu10k1_memblk_t *blk);
75
76#define get_emu10k1_memblk(l,member) list_entry(l, emu10k1_memblk_t, member)
77
78
79/* initialize emu10k1 part */
80static void emu10k1_memblk_init(emu10k1_memblk_t *blk)
81{
82 blk->mapped_page = -1;
83 INIT_LIST_HEAD(&blk->mapped_link);
84 INIT_LIST_HEAD(&blk->mapped_order_link);
85 blk->map_locked = 0;
86
87 blk->first_page = get_aligned_page(blk->mem.offset);
88 blk->last_page = get_aligned_page(blk->mem.offset + blk->mem.size - 1);
89 blk->pages = blk->last_page - blk->first_page + 1;
90}
91
92/*
93 * search empty region on PTB with the given size
94 *
95 * if an empty region is found, return the page and store the next mapped block
96 * in nextp
97 * if not found, return a negative error code.
98 */
99static int search_empty_map_area(emu10k1_t *emu, int npages, struct list_head **nextp)
100{
101 int page = 0, found_page = -ENOMEM;
102 int max_size = npages;
103 int size;
104 struct list_head *candidate = &emu->mapped_link_head;
105 struct list_head *pos;
106
107 list_for_each (pos, &emu->mapped_link_head) {
108 emu10k1_memblk_t *blk = get_emu10k1_memblk(pos, mapped_link);
109 snd_assert(blk->mapped_page >= 0, continue);
110 size = blk->mapped_page - page;
111 if (size == npages) {
112 *nextp = pos;
113 return page;
114 }
115 else if (size > max_size) {
116 /* we look for the maximum empty hole */
117 max_size = size;
118 candidate = pos;
119 found_page = page;
120 }
121 page = blk->mapped_page + blk->pages;
122 }
123 size = MAX_ALIGN_PAGES - page;
124 if (size >= max_size) {
125 *nextp = pos;
126 return page;
127 }
128 *nextp = candidate;
129 return found_page;
130}
131
132/*
133 * map a memory block onto emu10k1's PTB
134 *
135 * call with memblk_lock held
136 */
137static int map_memblk(emu10k1_t *emu, emu10k1_memblk_t *blk)
138{
139 int page, pg;
140 struct list_head *next;
141
142 page = search_empty_map_area(emu, blk->pages, &next);
143 if (page < 0) /* not found */
144 return page;
145 /* insert this block in the proper position of mapped list */
146 list_add_tail(&blk->mapped_link, next);
147 /* append this as a newest block in order list */
148 list_add_tail(&blk->mapped_order_link, &emu->mapped_order_link_head);
149 blk->mapped_page = page;
150 /* fill PTB */
151 for (pg = blk->first_page; pg <= blk->last_page; pg++) {
152 set_ptb_entry(emu, page, emu->page_addr_table[pg]);
153 page++;
154 }
155 return 0;
156}
157
158/*
159 * unmap the block
160 * return the size of resultant empty pages
161 *
162 * call with memblk_lock held
163 */
164static int unmap_memblk(emu10k1_t *emu, emu10k1_memblk_t *blk)
165{
166 int start_page, end_page, mpage, pg;
167 struct list_head *p;
168 emu10k1_memblk_t *q;
169
170 /* calculate the expected size of empty region */
171 if ((p = blk->mapped_link.prev) != &emu->mapped_link_head) {
172 q = get_emu10k1_memblk(p, mapped_link);
173 start_page = q->mapped_page + q->pages;
174 } else
175 start_page = 0;
176 if ((p = blk->mapped_link.next) != &emu->mapped_link_head) {
177 q = get_emu10k1_memblk(p, mapped_link);
178 end_page = q->mapped_page;
179 } else
180 end_page = MAX_ALIGN_PAGES;
181
182 /* remove links */
183 list_del(&blk->mapped_link);
184 list_del(&blk->mapped_order_link);
185 /* clear PTB */
186 mpage = blk->mapped_page;
187 for (pg = blk->first_page; pg <= blk->last_page; pg++) {
188 set_silent_ptb(emu, mpage);
189 mpage++;
190 }
191 blk->mapped_page = -1;
192 return end_page - start_page; /* return the new empty size */
193}
194
195/*
196 * search empty pages with the given size, and create a memory block
197 *
198 * unlike synth_alloc the memory block is aligned to the page start
199 */
200static emu10k1_memblk_t *
201search_empty(emu10k1_t *emu, int size)
202{
203 struct list_head *p;
204 emu10k1_memblk_t *blk;
205 int page, psize;
206
207 psize = get_aligned_page(size + PAGE_SIZE -1);
208 page = 0;
209 list_for_each(p, &emu->memhdr->block) {
210 blk = get_emu10k1_memblk(p, mem.list);
211 if (page + psize <= blk->first_page)
212 goto __found_pages;
213 page = blk->last_page + 1;
214 }
215 if (page + psize > emu->max_cache_pages)
216 return NULL;
217
218__found_pages:
219 /* create a new memory block */
220 blk = (emu10k1_memblk_t *)__snd_util_memblk_new(emu->memhdr, psize << PAGE_SHIFT, p->prev);
221 if (blk == NULL)
222 return NULL;
223 blk->mem.offset = aligned_page_offset(page); /* set aligned offset */
224 emu10k1_memblk_init(blk);
225 return blk;
226}
227
228
229/*
230 * check if the given pointer is valid for pages
231 */
232static int is_valid_page(emu10k1_t *emu, dma_addr_t addr)
233{
234 if (addr & ~emu->dma_mask) {
235 snd_printk("max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
236 return 0;
237 }
238 if (addr & (EMUPAGESIZE-1)) {
239 snd_printk("page is not aligned\n");
240 return 0;
241 }
242 return 1;
243}
244
245/*
246 * map the given memory block on PTB.
247 * if the block is already mapped, update the link order.
248 * if no empty pages are found, tries to release unsed memory blocks
249 * and retry the mapping.
250 */
251int snd_emu10k1_memblk_map(emu10k1_t *emu, emu10k1_memblk_t *blk)
252{
253 int err;
254 int size;
255 struct list_head *p, *nextp;
256 emu10k1_memblk_t *deleted;
257 unsigned long flags;
258
259 spin_lock_irqsave(&emu->memblk_lock, flags);
260 if (blk->mapped_page >= 0) {
261 /* update order link */
262 list_del(&blk->mapped_order_link);
263 list_add_tail(&blk->mapped_order_link, &emu->mapped_order_link_head);
264 spin_unlock_irqrestore(&emu->memblk_lock, flags);
265 return 0;
266 }
267 if ((err = map_memblk(emu, blk)) < 0) {
268 /* no enough page - try to unmap some blocks */
269 /* starting from the oldest block */
270 p = emu->mapped_order_link_head.next;
271 for (; p != &emu->mapped_order_link_head; p = nextp) {
272 nextp = p->next;
273 deleted = get_emu10k1_memblk(p, mapped_order_link);
274 if (deleted->map_locked)
275 continue;
276 size = unmap_memblk(emu, deleted);
277 if (size >= blk->pages) {
278 /* ok the empty region is enough large */
279 err = map_memblk(emu, blk);
280 break;
281 }
282 }
283 }
284 spin_unlock_irqrestore(&emu->memblk_lock, flags);
285 return err;
286}
287
288/*
289 * page allocation for DMA
290 */
291snd_util_memblk_t *
292snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream)
293{
294 snd_pcm_runtime_t *runtime = substream->runtime;
295 struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
296 snd_util_memhdr_t *hdr;
297 emu10k1_memblk_t *blk;
298 int page, err, idx;
299
300 snd_assert(emu, return NULL);
301 snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes < MAXPAGES * EMUPAGESIZE, return NULL);
302 hdr = emu->memhdr;
303 snd_assert(hdr, return NULL);
304
305 down(&hdr->block_mutex);
306 blk = search_empty(emu, runtime->dma_bytes);
307 if (blk == NULL) {
308 up(&hdr->block_mutex);
309 return NULL;
310 }
311 /* fill buffer addresses but pointers are not stored so that
312 * snd_free_pci_page() is not called in in synth_free()
313 */
314 idx = 0;
315 for (page = blk->first_page; page <= blk->last_page; page++, idx++) {
316 dma_addr_t addr;
317#ifdef CONFIG_SND_DEBUG
318 if (idx >= sgbuf->pages) {
319 printk(KERN_ERR "emu: pages overflow! (%d-%d) for %d\n",
320 blk->first_page, blk->last_page, sgbuf->pages);
321 up(&hdr->block_mutex);
322 return NULL;
323 }
324#endif
325 addr = sgbuf->table[idx].addr;
326 if (! is_valid_page(emu, addr)) {
327 printk(KERN_ERR "emu: failure page = %d\n", idx);
328 up(&hdr->block_mutex);
329 return NULL;
330 }
331 emu->page_addr_table[page] = addr;
332 emu->page_ptr_table[page] = NULL;
333 }
334
335 /* set PTB entries */
336 blk->map_locked = 1; /* do not unmap this block! */
337 err = snd_emu10k1_memblk_map(emu, blk);
338 if (err < 0) {
339 __snd_util_mem_free(hdr, (snd_util_memblk_t *)blk);
340 up(&hdr->block_mutex);
341 return NULL;
342 }
343 up(&hdr->block_mutex);
344 return (snd_util_memblk_t *)blk;
345}
346
347
348/*
349 * release DMA buffer from page table
350 */
351int snd_emu10k1_free_pages(emu10k1_t *emu, snd_util_memblk_t *blk)
352{
353 snd_assert(emu && blk, return -EINVAL);
354 return snd_emu10k1_synth_free(emu, blk);
355}
356
357
358/*
359 * memory allocation using multiple pages (for synth)
360 * Unlike the DMA allocation above, non-contiguous pages are assined.
361 */
362
363/*
364 * allocate a synth sample area
365 */
366snd_util_memblk_t *
367snd_emu10k1_synth_alloc(emu10k1_t *hw, unsigned int size)
368{
369 emu10k1_memblk_t *blk;
370 snd_util_memhdr_t *hdr = hw->memhdr;
371
372 down(&hdr->block_mutex);
373 blk = (emu10k1_memblk_t *)__snd_util_mem_alloc(hdr, size);
374 if (blk == NULL) {
375 up(&hdr->block_mutex);
376 return NULL;
377 }
378 if (synth_alloc_pages(hw, blk)) {
379 __snd_util_mem_free(hdr, (snd_util_memblk_t *)blk);
380 up(&hdr->block_mutex);
381 return NULL;
382 }
383 snd_emu10k1_memblk_map(hw, blk);
384 up(&hdr->block_mutex);
385 return (snd_util_memblk_t *)blk;
386}
387
388
389/*
390 * free a synth sample area
391 */
392int
393snd_emu10k1_synth_free(emu10k1_t *emu, snd_util_memblk_t *memblk)
394{
395 snd_util_memhdr_t *hdr = emu->memhdr;
396 emu10k1_memblk_t *blk = (emu10k1_memblk_t *)memblk;
397 unsigned long flags;
398
399 down(&hdr->block_mutex);
400 spin_lock_irqsave(&emu->memblk_lock, flags);
401 if (blk->mapped_page >= 0)
402 unmap_memblk(emu, blk);
403 spin_unlock_irqrestore(&emu->memblk_lock, flags);
404 synth_free_pages(emu, blk);
405 __snd_util_mem_free(hdr, memblk);
406 up(&hdr->block_mutex);
407 return 0;
408}
409
410
411/* check new allocation range */
412static void get_single_page_range(snd_util_memhdr_t *hdr, emu10k1_memblk_t *blk, int *first_page_ret, int *last_page_ret)
413{
414 struct list_head *p;
415 emu10k1_memblk_t *q;
416 int first_page, last_page;
417 first_page = blk->first_page;
418 if ((p = blk->mem.list.prev) != &hdr->block) {
419 q = get_emu10k1_memblk(p, mem.list);
420 if (q->last_page == first_page)
421 first_page++; /* first page was already allocated */
422 }
423 last_page = blk->last_page;
424 if ((p = blk->mem.list.next) != &hdr->block) {
425 q = get_emu10k1_memblk(p, mem.list);
426 if (q->first_page == last_page)
427 last_page--; /* last page was already allocated */
428 }
429 *first_page_ret = first_page;
430 *last_page_ret = last_page;
431}
432
433/*
434 * allocate kernel pages
435 */
436static int synth_alloc_pages(emu10k1_t *emu, emu10k1_memblk_t *blk)
437{
438 int page, first_page, last_page;
439 struct snd_dma_buffer dmab;
440
441 emu10k1_memblk_init(blk);
442 get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
443 /* allocate kernel pages */
444 for (page = first_page; page <= last_page; page++) {
445 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci),
446 PAGE_SIZE, &dmab) < 0)
447 goto __fail;
448 if (! is_valid_page(emu, dmab.addr)) {
449 snd_dma_free_pages(&dmab);
450 goto __fail;
451 }
452 emu->page_addr_table[page] = dmab.addr;
453 emu->page_ptr_table[page] = dmab.area;
454 }
455 return 0;
456
457__fail:
458 /* release allocated pages */
459 last_page = page - 1;
460 for (page = first_page; page <= last_page; page++) {
461 dmab.area = emu->page_ptr_table[page];
462 dmab.addr = emu->page_addr_table[page];
463 dmab.bytes = PAGE_SIZE;
464 snd_dma_free_pages(&dmab);
465 emu->page_addr_table[page] = 0;
466 emu->page_ptr_table[page] = NULL;
467 }
468
469 return -ENOMEM;
470}
471
472/*
473 * free pages
474 */
475static int synth_free_pages(emu10k1_t *emu, emu10k1_memblk_t *blk)
476{
477 int page, first_page, last_page;
478 struct snd_dma_buffer dmab;
479
480 get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
481 dmab.dev.type = SNDRV_DMA_TYPE_DEV;
482 dmab.dev.dev = snd_dma_pci_data(emu->pci);
483 for (page = first_page; page <= last_page; page++) {
484 if (emu->page_ptr_table[page] == NULL)
485 continue;
486 dmab.area = emu->page_ptr_table[page];
487 dmab.addr = emu->page_addr_table[page];
488 dmab.bytes = PAGE_SIZE;
489 snd_dma_free_pages(&dmab);
490 emu->page_addr_table[page] = 0;
491 emu->page_ptr_table[page] = NULL;
492 }
493
494 return 0;
495}
496
497/* calculate buffer pointer from offset address */
498inline static void *offset_ptr(emu10k1_t *emu, int page, int offset)
499{
500 char *ptr;
501 snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL);
502 ptr = emu->page_ptr_table[page];
503 if (! ptr) {
504 printk("emu10k1: access to NULL ptr: page = %d\n", page);
505 return NULL;
506 }
507 ptr += offset & (PAGE_SIZE - 1);
508 return (void*)ptr;
509}
510
511/*
512 * bzero(blk + offset, size)
513 */
514int snd_emu10k1_synth_bzero(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, int size)
515{
516 int page, nextofs, end_offset, temp, temp1;
517 void *ptr;
518 emu10k1_memblk_t *p = (emu10k1_memblk_t *)blk;
519
520 offset += blk->offset & (PAGE_SIZE - 1);
521 end_offset = offset + size;
522 page = get_aligned_page(offset);
523 do {
524 nextofs = aligned_page_offset(page + 1);
525 temp = nextofs - offset;
526 temp1 = end_offset - offset;
527 if (temp1 < temp)
528 temp = temp1;
529 ptr = offset_ptr(emu, page + p->first_page, offset);
530 if (ptr)
531 memset(ptr, 0, temp);
532 offset = nextofs;
533 page++;
534 } while (offset < end_offset);
535 return 0;
536}
537
538/*
539 * copy_from_user(blk + offset, data, size)
540 */
541int snd_emu10k1_synth_copy_from_user(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
542{
543 int page, nextofs, end_offset, temp, temp1;
544 void *ptr;
545 emu10k1_memblk_t *p = (emu10k1_memblk_t *)blk;
546
547 offset += blk->offset & (PAGE_SIZE - 1);
548 end_offset = offset + size;
549 page = get_aligned_page(offset);
550 do {
551 nextofs = aligned_page_offset(page + 1);
552 temp = nextofs - offset;
553 temp1 = end_offset - offset;
554 if (temp1 < temp)
555 temp = temp1;
556 ptr = offset_ptr(emu, page + p->first_page, offset);
557 if (ptr && copy_from_user(ptr, data, temp))
558 return -EFAULT;
559 offset = nextofs;
560 data += temp;
561 page++;
562 } while (offset < end_offset);
563 return 0;
564}
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
new file mode 100644
index 000000000000..d03cb2fefc9e
--- /dev/null
+++ b/sound/pci/emu10k1/p16v.c
@@ -0,0 +1,736 @@
1/*
2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver p16v chips
4 * Version: 0.22
5 *
6 * FEATURES currently supported:
7 * Output fixed at S32_LE, 2 channel to hw:0,0
8 * Rates: 44.1, 48, 96, 192.
9 *
10 * Changelog:
11 * 0.8
12 * Use separate card based buffer for periods table.
13 * 0.9
14 * Use 2 channel output streams instead of 8 channel.
15 * (8 channel output streams might be good for ASIO type output)
16 * Corrected speaker output, so Front -> Front etc.
17 * 0.10
18 * Fixed missed interrupts.
19 * 0.11
20 * Add Sound card model number and names.
21 * Add Analog volume controls.
22 * 0.12
23 * Corrected playback interrupts. Now interrupt per period, instead of half period.
24 * 0.13
25 * Use single trigger for multichannel.
26 * 0.14
27 * Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
28 * 0.15
29 * Force buffer_size / period_size == INTEGER.
30 * 0.16
31 * Update p16v.c to work with changed alsa api.
32 * 0.17
33 * Update p16v.c to work with changed alsa api. Removed boot_devs.
34 * 0.18
35 * Merging with snd-emu10k1 driver.
36 * 0.19
37 * One stereo channel at 24bit now works.
38 * 0.20
39 * Added better register defines.
40 * 0.21
41 * Integrated with snd-emu10k1 driver.
42 * 0.22
43 * Removed #if 0 ... #endif
44 *
45 *
46 * BUGS:
47 * Some stability problems when unloading the snd-p16v kernel module.
48 * --
49 *
50 * TODO:
51 * SPDIF out.
52 * Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
53 * Currently capture fixed at 48000Hz.
54 *
55 * --
56 * GENERAL INFO:
57 * Model: SB0240
58 * P16V Chip: CA0151-DBS
59 * Audigy 2 Chip: CA0102-IAT
60 * AC97 Codec: STAC 9721
61 * ADC: Philips 1361T (Stereo 24bit)
62 * DAC: CS4382-K (8-channel, 24bit, 192Khz)
63 *
64 * This code was initally based on code from ALSA's emu10k1x.c which is:
65 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
66 *
67 * This program is free software; you can redistribute it and/or modify
68 * it under the terms of the GNU General Public License as published by
69 * the Free Software Foundation; either version 2 of the License, or
70 * (at your option) any later version.
71 *
72 * This program is distributed in the hope that it will be useful,
73 * but WITHOUT ANY WARRANTY; without even the implied warranty of
74 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75 * GNU General Public License for more details.
76 *
77 * You should have received a copy of the GNU General Public License
78 * along with this program; if not, write to the Free Software
79 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
80 *
81 */
82#include <sound/driver.h>
83#include <linux/delay.h>
84#include <linux/init.h>
85#include <linux/interrupt.h>
86#include <linux/pci.h>
87#include <linux/slab.h>
88#include <linux/moduleparam.h>
89#include <sound/core.h>
90#include <sound/initval.h>
91#include <sound/pcm.h>
92#include <sound/ac97_codec.h>
93#include <sound/info.h>
94#include <sound/emu10k1.h>
95#include "p16v.h"
96
97#define SET_CHANNEL 0 /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
98#define PCM_FRONT_CHANNEL 0
99#define PCM_REAR_CHANNEL 1
100#define PCM_CENTER_LFE_CHANNEL 2
101#define PCM_UNKNOWN_CHANNEL 3
102#define CONTROL_FRONT_CHANNEL 0
103#define CONTROL_REAR_CHANNEL 3
104#define CONTROL_CENTER_LFE_CHANNEL 1
105#define CONTROL_UNKNOWN_CHANNEL 2
106
107/* Card IDs:
108 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350
109 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1007 -> Audigy2 6.1 Model:SB0240
110 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:1002 -> Audigy2 Platinum Model:SB msb0240230009266
111 * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2007 -> Audigy4 Pro Model:SB0380 M1SB0380472001901E
112 *
113 */
114
115 /* hardware definition */
116static snd_pcm_hardware_t snd_p16v_playback_hw = {
117 .info = (SNDRV_PCM_INFO_MMAP |
118 SNDRV_PCM_INFO_INTERLEAVED |
119 SNDRV_PCM_INFO_BLOCK_TRANSFER |
120 SNDRV_PCM_INFO_MMAP_VALID),
121 .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
122 .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 ,
123 .rate_min = 48000,
124 .rate_max = 192000,
125 .channels_min = 8,
126 .channels_max = 8,
127 .buffer_bytes_max = (32*1024),
128 .period_bytes_min = 64,
129 .period_bytes_max = (16*1024),
130 .periods_min = 2,
131 .periods_max = 8,
132 .fifo_size = 0,
133};
134
135static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime)
136{
137 snd_pcm_t *epcm = runtime->private_data;
138
139 if (epcm) {
140 //snd_printk("epcm free: %p\n", epcm);
141 kfree(epcm);
142 }
143}
144
145/* open_playback callback */
146static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
147{
148 emu10k1_t *emu = snd_pcm_substream_chip(substream);
149 emu10k1_voice_t *channel = &(emu->p16v_voices[channel_id]);
150 emu10k1_pcm_t *epcm;
151 snd_pcm_runtime_t *runtime = substream->runtime;
152 int err;
153
154 epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
155 //snd_printk("epcm kcalloc: %p\n", epcm);
156
157 if (epcm == NULL)
158 return -ENOMEM;
159 epcm->emu = emu;
160 epcm->substream = substream;
161 //snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id);
162
163 runtime->private_data = epcm;
164 runtime->private_free = snd_p16v_pcm_free_substream;
165
166 runtime->hw = snd_p16v_playback_hw;
167
168 channel->emu = emu;
169 channel->number = channel_id;
170
171 channel->use=1;
172 //snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use);
173 //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
174 //channel->interrupt = snd_p16v_pcm_channel_interrupt;
175 channel->epcm=epcm;
176 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
177 return err;
178
179 return 0;
180}
181
182/* close callback */
183static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream)
184{
185 emu10k1_t *emu = snd_pcm_substream_chip(substream);
186 //snd_pcm_runtime_t *runtime = substream->runtime;
187 //emu10k1_pcm_t *epcm = runtime->private_data;
188 emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0;
189/* FIXME: maybe zero others */
190 return 0;
191}
192
193static int snd_p16v_pcm_open_playback_front(snd_pcm_substream_t *substream)
194{
195 return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
196}
197
198/* hw_params callback */
199static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream,
200 snd_pcm_hw_params_t * hw_params)
201{
202 int result;
203 //snd_printk("hw_params alloc: substream=%p\n", substream);
204 result = snd_pcm_lib_malloc_pages(substream,
205 params_buffer_bytes(hw_params));
206 //snd_printk("hw_params alloc: result=%d\n", result);
207 //dump_stack();
208 return result;
209}
210
211/* hw_free callback */
212static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream)
213{
214 int result;
215 //snd_printk("hw_params free: substream=%p\n", substream);
216 result = snd_pcm_lib_free_pages(substream);
217 //snd_printk("hw_params free: result=%d\n", result);
218 //dump_stack();
219 return result;
220}
221
222/* prepare playback callback */
223static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream)
224{
225 emu10k1_t *emu = snd_pcm_substream_chip(substream);
226 snd_pcm_runtime_t *runtime = substream->runtime;
227 //emu10k1_pcm_t *epcm = runtime->private_data;
228 int channel = substream->pcm->device - emu->p16v_device_offset;
229 u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel));
230 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
231 int i;
232 u32 tmp;
233
234 //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
235 //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
236 //snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->p16v_buffer.addr, emu->p16v_buffer.area, emu->p16v_buffer.bytes);
237 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
238 switch (runtime->rate) {
239 case 44100:
240 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x8000); /* FIXME: This will change the capture rate as well! */
241 break;
242 case 48000:
243 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x0000); /* FIXME: This will change the capture rate as well! */
244 break;
245 case 96000:
246 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x4000); /* FIXME: This will change the capture rate as well! */
247 break;
248 case 192000:
249 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x2000); /* FIXME: This will change the capture rate as well! */
250 break;
251 default:
252 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, 0x0000); /* FIXME: This will change the capture rate as well! */
253 break;
254 }
255 /* FIXME: Check emu->buffer.size before actually writing to it. */
256 for(i=0; i < runtime->periods; i++) {
257 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
258 table_base[(i*2)+1]=period_size_bytes<<16;
259 }
260
261 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_ADDR, channel, emu->p16v_buffer.addr+(8*16*channel));
262 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
263 snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0);
264 snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
265 snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
266 snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
267 snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
268 snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
269
270 return 0;
271}
272
273static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb)
274{
275 unsigned long flags;
276 unsigned int enable;
277
278 spin_lock_irqsave(&emu->emu_lock, flags);
279 enable = inl(emu->port + INTE2) | intrenb;
280 outl(enable, emu->port + INTE2);
281 spin_unlock_irqrestore(&emu->emu_lock, flags);
282}
283
284static void snd_p16v_intr_disable(emu10k1_t *emu, unsigned int intrenb)
285{
286 unsigned long flags;
287 unsigned int disable;
288
289 spin_lock_irqsave(&emu->emu_lock, flags);
290 disable = inl(emu->port + INTE2) & (~intrenb);
291 outl(disable, emu->port + INTE2);
292 spin_unlock_irqrestore(&emu->emu_lock, flags);
293}
294
295/* trigger_playback callback */
296static int snd_p16v_pcm_trigger_playback(snd_pcm_substream_t *substream,
297 int cmd)
298{
299 emu10k1_t *emu = snd_pcm_substream_chip(substream);
300 snd_pcm_runtime_t *runtime;
301 emu10k1_pcm_t *epcm;
302 int channel;
303 int result = 0;
304 struct list_head *pos;
305 snd_pcm_substream_t *s;
306 u32 basic = 0;
307 u32 inte = 0;
308 int running=0;
309
310 switch (cmd) {
311 case SNDRV_PCM_TRIGGER_START:
312 running=1;
313 break;
314 case SNDRV_PCM_TRIGGER_STOP:
315 default:
316 running=0;
317 break;
318 }
319 snd_pcm_group_for_each(pos, substream) {
320 s = snd_pcm_group_substream_entry(pos);
321 runtime = s->runtime;
322 epcm = runtime->private_data;
323 channel = substream->pcm->device-emu->p16v_device_offset;
324 //snd_printk("p16v channel=%d\n",channel);
325 epcm->running = running;
326 basic |= (0x1<<channel);
327 inte |= (INTE2_PLAYBACK_CH_0_LOOP<<channel);
328 snd_pcm_trigger_done(s, substream);
329 }
330 //snd_printk("basic=0x%x, inte=0x%x\n",basic, inte);
331
332 switch (cmd) {
333 case SNDRV_PCM_TRIGGER_START:
334 snd_p16v_intr_enable(emu, inte);
335 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)| (basic));
336 break;
337 case SNDRV_PCM_TRIGGER_STOP:
338 snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(basic));
339 snd_p16v_intr_disable(emu, inte);
340 break;
341 default:
342 result = -EINVAL;
343 break;
344 }
345 return result;
346}
347
348/* pointer_playback callback */
349static snd_pcm_uframes_t
350snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream)
351{
352 emu10k1_t *emu = snd_pcm_substream_chip(substream);
353 snd_pcm_runtime_t *runtime = substream->runtime;
354 emu10k1_pcm_t *epcm = runtime->private_data;
355 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
356 int channel = substream->pcm->device - emu->p16v_device_offset;
357 if (!epcm->running)
358 return 0;
359
360 ptr3 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
361 ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
362 ptr4 = snd_emu10k1_ptr20_read(emu, PLAYBACK_LIST_PTR, channel);
363 if (ptr3 != ptr4) ptr1 = snd_emu10k1_ptr20_read(emu, PLAYBACK_POINTER, channel);
364 ptr2 = bytes_to_frames(runtime, ptr1);
365 ptr2+= (ptr4 >> 3) * runtime->period_size;
366 ptr=ptr2;
367 if (ptr >= runtime->buffer_size)
368 ptr -= runtime->buffer_size;
369
370 return ptr;
371}
372
373/* operators */
374static snd_pcm_ops_t snd_p16v_playback_front_ops = {
375 .open = snd_p16v_pcm_open_playback_front,
376 .close = snd_p16v_pcm_close_playback,
377 .ioctl = snd_pcm_lib_ioctl,
378 .hw_params = snd_p16v_pcm_hw_params_playback,
379 .hw_free = snd_p16v_pcm_hw_free_playback,
380 .prepare = snd_p16v_pcm_prepare_playback,
381 .trigger = snd_p16v_pcm_trigger_playback,
382 .pointer = snd_p16v_pcm_pointer_playback,
383};
384
385int snd_p16v_free(emu10k1_t *chip)
386{
387 // release the data
388 if (chip->p16v_buffer.area) {
389 snd_dma_free_pages(&chip->p16v_buffer);
390 //snd_printk("period lables free: %p\n", &chip->p16v_buffer);
391 }
392 return 0;
393}
394
395static void snd_p16v_pcm_free(snd_pcm_t *pcm)
396{
397 emu10k1_t *emu = pcm->private_data;
398 //snd_printk("snd_p16v_pcm_free pcm: called\n");
399 snd_pcm_lib_preallocate_free_for_all(pcm);
400 emu->pcm = NULL;
401}
402
403int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm)
404{
405 snd_pcm_t *pcm;
406 snd_pcm_substream_t *substream;
407 int err;
408 int capture=0;
409
410 //snd_printk("snd_p16v_pcm called. device=%d\n", device);
411 emu->p16v_device_offset = device;
412 if (rpcm)
413 *rpcm = NULL;
414 //if (device == 0) capture=1;
415 if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
416 return err;
417
418 pcm->private_data = emu;
419 pcm->private_free = snd_p16v_pcm_free;
420
421 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
422
423 pcm->info_flags = 0;
424 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
425 strcpy(pcm->name, "p16v");
426 emu->pcm = pcm;
427
428 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
429 substream;
430 substream = substream->next) {
431 if ((err = snd_pcm_lib_preallocate_pages(substream,
432 SNDRV_DMA_TYPE_DEV,
433 snd_dma_pci_data(emu->pci),
434 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */
435 return err;
436 //snd_printk("preallocate playback substream: err=%d\n", err);
437 }
438
439 for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
440 substream;
441 substream = substream->next) {
442 if ((err = snd_pcm_lib_preallocate_pages(substream,
443 SNDRV_DMA_TYPE_DEV,
444 snd_dma_pci_data(emu->pci),
445 64*1024, 64*1024)) < 0)
446 return err;
447 //snd_printk("preallocate capture substream: err=%d\n", err);
448 }
449
450 if (rpcm)
451 *rpcm = pcm;
452
453 return 0;
454}
455
456static int snd_p16v_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
457{
458 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
459 uinfo->count = 2;
460 uinfo->value.integer.min = 0;
461 uinfo->value.integer.max = 255;
462 return 0;
463}
464
465static int snd_p16v_volume_get(snd_kcontrol_t * kcontrol,
466 snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
467{
468 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
469 u32 value;
470
471 value = snd_emu10k1_ptr20_read(emu, reg, high_low);
472 if (high_low == 1) {
473 ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
474 ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
475 } else {
476 ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
477 ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
478 }
479 return 0;
480}
481
482static int snd_p16v_volume_get_spdif_front(snd_kcontrol_t * kcontrol,
483 snd_ctl_elem_value_t * ucontrol)
484{
485 int high_low = 0;
486 int reg = PLAYBACK_VOLUME_MIXER7;
487 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
488}
489
490static int snd_p16v_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol,
491 snd_ctl_elem_value_t * ucontrol)
492{
493 int high_low = 1;
494 int reg = PLAYBACK_VOLUME_MIXER7;
495 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
496}
497static int snd_p16v_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol,
498 snd_ctl_elem_value_t * ucontrol)
499{
500 int high_low = 0;
501 int reg = PLAYBACK_VOLUME_MIXER8;
502 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
503}
504static int snd_p16v_volume_get_spdif_rear(snd_kcontrol_t * kcontrol,
505 snd_ctl_elem_value_t * ucontrol)
506{
507 int high_low = 1;
508 int reg = PLAYBACK_VOLUME_MIXER8;
509 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
510}
511
512static int snd_p16v_volume_get_analog_front(snd_kcontrol_t * kcontrol,
513 snd_ctl_elem_value_t * ucontrol)
514{
515 int high_low = 0;
516 int reg = PLAYBACK_VOLUME_MIXER9;
517 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
518}
519
520static int snd_p16v_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol,
521 snd_ctl_elem_value_t * ucontrol)
522{
523 int high_low = 1;
524 int reg = PLAYBACK_VOLUME_MIXER9;
525 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
526}
527static int snd_p16v_volume_get_analog_rear(snd_kcontrol_t * kcontrol,
528 snd_ctl_elem_value_t * ucontrol)
529{
530 int high_low = 1;
531 int reg = PLAYBACK_VOLUME_MIXER10;
532 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
533}
534
535static int snd_p16v_volume_get_analog_unknown(snd_kcontrol_t * kcontrol,
536 snd_ctl_elem_value_t * ucontrol)
537{
538 int high_low = 0;
539 int reg = PLAYBACK_VOLUME_MIXER10;
540 return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
541}
542
543static int snd_p16v_volume_put(snd_kcontrol_t * kcontrol,
544 snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
545{
546 emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
547 u32 value;
548 value = snd_emu10k1_ptr20_read(emu, reg, 0);
549 //value = value & 0xffff;
550 if (high_low == 1) {
551 value &= 0xffff;
552 value = value | ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16);
553 } else {
554 value &= 0xffff0000;
555 value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) );
556 }
557 snd_emu10k1_ptr20_write(emu, reg, 0, value);
558 return 1;
559}
560
561static int snd_p16v_volume_put_spdif_front(snd_kcontrol_t * kcontrol,
562 snd_ctl_elem_value_t * ucontrol)
563{
564 int high_low = 0;
565 int reg = PLAYBACK_VOLUME_MIXER7;
566 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
567}
568
569static int snd_p16v_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol,
570 snd_ctl_elem_value_t * ucontrol)
571{
572 int high_low = 1;
573 int reg = PLAYBACK_VOLUME_MIXER7;
574 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
575}
576
577static int snd_p16v_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol,
578 snd_ctl_elem_value_t * ucontrol)
579{
580 int high_low = 0;
581 int reg = PLAYBACK_VOLUME_MIXER8;
582 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
583}
584
585static int snd_p16v_volume_put_spdif_rear(snd_kcontrol_t * kcontrol,
586 snd_ctl_elem_value_t * ucontrol)
587{
588 int high_low = 1;
589 int reg = PLAYBACK_VOLUME_MIXER8;
590 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
591}
592
593static int snd_p16v_volume_put_analog_front(snd_kcontrol_t * kcontrol,
594 snd_ctl_elem_value_t * ucontrol)
595{
596 int high_low = 0;
597 int reg = PLAYBACK_VOLUME_MIXER9;
598 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
599}
600
601static int snd_p16v_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol,
602 snd_ctl_elem_value_t * ucontrol)
603{
604 int high_low = 1;
605 int reg = PLAYBACK_VOLUME_MIXER9;
606 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
607}
608
609static int snd_p16v_volume_put_analog_rear(snd_kcontrol_t * kcontrol,
610 snd_ctl_elem_value_t * ucontrol)
611{
612 int high_low = 1;
613 int reg = PLAYBACK_VOLUME_MIXER10;
614 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
615}
616
617static int snd_p16v_volume_put_analog_unknown(snd_kcontrol_t * kcontrol,
618 snd_ctl_elem_value_t * ucontrol)
619{
620 int high_low = 0;
621 int reg = PLAYBACK_VOLUME_MIXER10;
622 return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
623}
624
625static snd_kcontrol_new_t snd_p16v_volume_control_analog_front =
626{
627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
628 .name = "HD Analog Front Volume",
629 .info = snd_p16v_volume_info,
630 .get = snd_p16v_volume_get_analog_front,
631 .put = snd_p16v_volume_put_analog_front
632};
633
634static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe =
635{
636 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
637 .name = "HD Analog Center/LFE Volume",
638 .info = snd_p16v_volume_info,
639 .get = snd_p16v_volume_get_analog_center_lfe,
640 .put = snd_p16v_volume_put_analog_center_lfe
641};
642
643static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown =
644{
645 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
646 .name = "HD Analog Unknown Volume",
647 .info = snd_p16v_volume_info,
648 .get = snd_p16v_volume_get_analog_unknown,
649 .put = snd_p16v_volume_put_analog_unknown
650};
651
652static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear =
653{
654 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
655 .name = "HD Analog Rear Volume",
656 .info = snd_p16v_volume_info,
657 .get = snd_p16v_volume_get_analog_rear,
658 .put = snd_p16v_volume_put_analog_rear
659};
660
661static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front =
662{
663 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
664 .name = "HD SPDIF Front Volume",
665 .info = snd_p16v_volume_info,
666 .get = snd_p16v_volume_get_spdif_front,
667 .put = snd_p16v_volume_put_spdif_front
668};
669
670static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe =
671{
672 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
673 .name = "HD SPDIF Center/LFE Volume",
674 .info = snd_p16v_volume_info,
675 .get = snd_p16v_volume_get_spdif_center_lfe,
676 .put = snd_p16v_volume_put_spdif_center_lfe
677};
678
679static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown =
680{
681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
682 .name = "HD SPDIF Unknown Volume",
683 .info = snd_p16v_volume_info,
684 .get = snd_p16v_volume_get_spdif_unknown,
685 .put = snd_p16v_volume_put_spdif_unknown
686};
687
688static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear =
689{
690 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
691 .name = "HD SPDIF Rear Volume",
692 .info = snd_p16v_volume_info,
693 .get = snd_p16v_volume_get_spdif_rear,
694 .put = snd_p16v_volume_put_spdif_rear
695};
696
697int snd_p16v_mixer(emu10k1_t *emu)
698{
699 int err;
700 snd_kcontrol_t *kctl;
701 snd_card_t *card = emu->card;
702 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_front, emu)) == NULL)
703 return -ENOMEM;
704 if ((err = snd_ctl_add(card, kctl)))
705 return err;
706 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_rear, emu)) == NULL)
707 return -ENOMEM;
708 if ((err = snd_ctl_add(card, kctl)))
709 return err;
710 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_center_lfe, emu)) == NULL)
711 return -ENOMEM;
712 if ((err = snd_ctl_add(card, kctl)))
713 return err;
714 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_unknown, emu)) == NULL)
715 return -ENOMEM;
716 if ((err = snd_ctl_add(card, kctl)))
717 return err;
718 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_front, emu)) == NULL)
719 return -ENOMEM;
720 if ((err = snd_ctl_add(card, kctl)))
721 return err;
722 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_rear, emu)) == NULL)
723 return -ENOMEM;
724 if ((err = snd_ctl_add(card, kctl)))
725 return err;
726 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_center_lfe, emu)) == NULL)
727 return -ENOMEM;
728 if ((err = snd_ctl_add(card, kctl)))
729 return err;
730 if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_unknown, emu)) == NULL)
731 return -ENOMEM;
732 if ((err = snd_ctl_add(card, kctl)))
733 return err;
734 return 0;
735}
736
diff --git a/sound/pci/emu10k1/p16v.h b/sound/pci/emu10k1/p16v.h
new file mode 100644
index 000000000000..153214940336
--- /dev/null
+++ b/sound/pci/emu10k1/p16v.h
@@ -0,0 +1,299 @@
1/*
2 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
3 * Driver p16v chips
4 * Version: 0.21
5 *
6 * FEATURES currently supported:
7 * Output fixed at S32_LE, 2 channel to hw:0,0
8 * Rates: 44.1, 48, 96, 192.
9 *
10 * Changelog:
11 * 0.8
12 * Use separate card based buffer for periods table.
13 * 0.9
14 * Use 2 channel output streams instead of 8 channel.
15 * (8 channel output streams might be good for ASIO type output)
16 * Corrected speaker output, so Front -> Front etc.
17 * 0.10
18 * Fixed missed interrupts.
19 * 0.11
20 * Add Sound card model number and names.
21 * Add Analog volume controls.
22 * 0.12
23 * Corrected playback interrupts. Now interrupt per period, instead of half period.
24 * 0.13
25 * Use single trigger for multichannel.
26 * 0.14
27 * Mic capture now works at fixed: S32_LE, 96000Hz, Stereo.
28 * 0.15
29 * Force buffer_size / period_size == INTEGER.
30 * 0.16
31 * Update p16v.c to work with changed alsa api.
32 * 0.17
33 * Update p16v.c to work with changed alsa api. Removed boot_devs.
34 * 0.18
35 * Merging with snd-emu10k1 driver.
36 * 0.19
37 * One stereo channel at 24bit now works.
38 * 0.20
39 * Added better register defines.
40 * 0.21
41 * Split from p16v.c
42 *
43 *
44 * BUGS:
45 * Some stability problems when unloading the snd-p16v kernel module.
46 * --
47 *
48 * TODO:
49 * SPDIF out.
50 * Find out how to change capture sample rates. E.g. To record SPDIF at 48000Hz.
51 * Currently capture fixed at 48000Hz.
52 *
53 * --
54 * GENERAL INFO:
55 * Model: SB0240
56 * P16V Chip: CA0151-DBS
57 * Audigy 2 Chip: CA0102-IAT
58 * AC97 Codec: STAC 9721
59 * ADC: Philips 1361T (Stereo 24bit)
60 * DAC: CS4382-K (8-channel, 24bit, 192Khz)
61 *
62 * This code was initally based on code from ALSA's emu10k1x.c which is:
63 * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
64 *
65 * This program is free software; you can redistribute it and/or modify
66 * it under the terms of the GNU General Public License as published by
67 * the Free Software Foundation; either version 2 of the License, or
68 * (at your option) any later version.
69 *
70 * This program is distributed in the hope that it will be useful,
71 * but WITHOUT ANY WARRANTY; without even the implied warranty of
72 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
73 * GNU General Public License for more details.
74 *
75 * You should have received a copy of the GNU General Public License
76 * along with this program; if not, write to the Free Software
77 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
78 *
79 */
80
81/********************************************************************************************************/
82/* Audigy2 P16V pointer-offset register set, accessed through the PTR2 and DATA2 registers */
83/********************************************************************************************************/
84
85/* The sample rate of the SPDIF outputs is set by modifying a register in the EMU10K2 PTR register A_SPDIF_SAMPLERATE.
86 * The sample rate is also controlled by the same registers that control the rate of the EMU10K2 sample rate converters.
87 */
88
89/* Initally all registers from 0x00 to 0x3f have zero contents. */
90#define PLAYBACK_LIST_ADDR 0x00 /* Base DMA address of a list of pointers to each period/size */
91 /* One list entry: 4 bytes for DMA address,
92 * 4 bytes for period_size << 16.
93 * One list entry is 8 bytes long.
94 * One list entry for each period in the buffer.
95 */
96#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
97#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
98#define PLAYBACK_UNKNOWN3 0x03 /* Not used */
99#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */
100#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */
101#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */
102#define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */
103#define PLAYBACK_FIFO_POINTER 0x08 /* Playback FIFO pointer and number of valid sound samples in cache */
104#define PLAYBACK_UNKNOWN9 0x09 /* Not used */
105#define CAPTURE_DMA_ADDR 0x10 /* Capture DMA address */
106#define CAPTURE_BUFFER_SIZE 0x11 /* Capture buffer size */
107#define CAPTURE_POINTER 0x12 /* Capture buffer pointer. Sample currently in ADC */
108#define CAPTURE_FIFO_POINTER 0x13 /* Capture FIFO pointer and number of valid sound samples in cache */
109#define CAPTURE_P16V_VOLUME1 0x14 /* Low: Capture volume 0xXXXX3030 */
110#define CAPTURE_P16V_VOLUME2 0x15 /* High:Has no effect on capture volume */
111#define CAPTURE_P16V_SOURCE 0x16 /* P16V source select. Set to 0x0700E4E5 for AC97 CAPTURE */
112 /* [0:1] Capture input 0 channel select. 0 = Capture output 0.
113 * 1 = Capture output 1.
114 * 2 = Capture output 2.
115 * 3 = Capture output 3.
116 * [3:2] Capture input 1 channel select. 0 = Capture output 0.
117 * 1 = Capture output 1.
118 * 2 = Capture output 2.
119 * 3 = Capture output 3.
120 * [5:4] Capture input 2 channel select. 0 = Capture output 0.
121 * 1 = Capture output 1.
122 * 2 = Capture output 2.
123 * 3 = Capture output 3.
124 * [7:6] Capture input 3 channel select. 0 = Capture output 0.
125 * 1 = Capture output 1.
126 * 2 = Capture output 2.
127 * 3 = Capture output 3.
128 * [9:8] Playback input 0 channel select. 0 = Play output 0.
129 * 1 = Play output 1.
130 * 2 = Play output 2.
131 * 3 = Play output 3.
132 * [11:10] Playback input 1 channel select. 0 = Play output 0.
133 * 1 = Play output 1.
134 * 2 = Play output 2.
135 * 3 = Play output 3.
136 * [13:12] Playback input 2 channel select. 0 = Play output 0.
137 * 1 = Play output 1.
138 * 2 = Play output 2.
139 * 3 = Play output 3.
140 * [15:14] Playback input 3 channel select. 0 = Play output 0.
141 * 1 = Play output 1.
142 * 2 = Play output 2.
143 * 3 = Play output 3.
144 * [19:16] Playback mixer output enable. 1 bit per channel.
145 * [23:20] Capture mixer output enable. 1 bit per channel.
146 * [26:24] FX engine channel capture 0 = 0x60-0x67.
147 * 1 = 0x68-0x6f.
148 * 2 = 0x70-0x77.
149 * 3 = 0x78-0x7f.
150 * 4 = 0x80-0x87.
151 * 5 = 0x88-0x8f.
152 * 6 = 0x90-0x97.
153 * 7 = 0x98-0x9f.
154 * [31:27] Not used.
155 */
156
157 /* 0x1 = capture on.
158 * 0x100 = capture off.
159 * 0x200 = capture off.
160 * 0x1000 = capture off.
161 */
162#define CAPTURE_RATE_STATUS 0x17 /* Capture sample rate. Read only */
163 /* [15:0] Not used.
164 * [18:16] Channel 0 Detected sample rate. 0 - 44.1khz
165 * 1 - 48 khz
166 * 2 - 96 khz
167 * 3 - 192 khz
168 * 7 - undefined rate.
169 * [19] Channel 0. 1 - Valid, 0 - Not Valid.
170 * [22:20] Channel 1 Detected sample rate.
171 * [23] Channel 1. 1 - Valid, 0 - Not Valid.
172 * [26:24] Channel 2 Detected sample rate.
173 * [27] Channel 2. 1 - Valid, 0 - Not Valid.
174 * [30:28] Channel 3 Detected sample rate.
175 * [31] Channel 3. 1 - Valid, 0 - Not Valid.
176 */
177/* 0x18 - 0x1f unused */
178#define PLAYBACK_LAST_SAMPLE 0x20 /* The sample currently being played. Read only */
179/* 0x21 - 0x3f unused */
180#define BASIC_INTERRUPT 0x40 /* Used by both playback and capture interrupt handler */
181 /* Playback (0x1<<channel_id) Don't touch high 16bits. */
182 /* Capture (0x100<<channel_id). not tested */
183 /* Start Playback [3:0] (one bit per channel)
184 * Start Capture [11:8] (one bit per channel)
185 * Record source select for channel 0 [18:16]
186 * Record source select for channel 1 [22:20]
187 * Record source select for channel 2 [26:24]
188 * Record source select for channel 3 [30:28]
189 * 0 - SPDIF channel.
190 * 1 - I2S channel.
191 * 2 - SRC48 channel.
192 * 3 - SRCMulti_SPDIF channel.
193 * 4 - SRCMulti_I2S channel.
194 * 5 - SPDIF channel.
195 * 6 - fxengine capture.
196 * 7 - AC97 capture.
197 */
198 /* Default 41110000.
199 * Writing 0xffffffff hangs the PC.
200 * Writing 0xffff0000 -> 77770000 so it must be some sort of route.
201 * bit 0x1 starts DMA playback on channel_id 0
202 */
203/* 0x41,42 take values from 0 - 0xffffffff, but have no effect on playback */
204/* 0x43,0x48 do not remember settings */
205/* 0x41-45 unused */
206#define WATERMARK 0x46 /* Test bit to indicate cache level usage */
207 /* Values it can have while playing on channel 0.
208 * 0000f000, 0000f004, 0000f008, 0000f00c.
209 * Readonly.
210 */
211/* 0x47-0x4f unused */
212/* 0x50-0x5f Capture cache data */
213#define SRCSel 0x60 /* SRCSel. Default 0x4. Bypass P16V 0x14 */
214 /* [0] 0 = 10K2 audio, 1 = SRC48 mixer output.
215 * [2] 0 = 10K2 audio, 1 = SRCMulti SPDIF mixer output.
216 * [4] 0 = 10K2 audio, 1 = SRCMulti I2S mixer output.
217 */
218 /* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */
219 /* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */
220 /* SRC48 and SRCMULTI sample rate select and output select. */
221 /* 0xffffffff -> 0xC0000015
222 * 0xXXXXXXX4 = Enable Front Left/Right
223 * Enable PCMs
224 */
225
226/* 0x61 -> 0x6c are Volume controls */
227#define PLAYBACK_VOLUME_MIXER1 0x61 /* SRC48 Low to mixer input volume control. */
228#define PLAYBACK_VOLUME_MIXER2 0x62 /* SRC48 High to mixer input volume control. */
229#define PLAYBACK_VOLUME_MIXER3 0x63 /* SRCMULTI SPDIF Low to mixer input volume control. */
230#define PLAYBACK_VOLUME_MIXER4 0x64 /* SRCMULTI SPDIF High to mixer input volume control. */
231#define PLAYBACK_VOLUME_MIXER5 0x65 /* SRCMULTI I2S Low to mixer input volume control. */
232#define PLAYBACK_VOLUME_MIXER6 0x66 /* SRCMULTI I2S High to mixer input volume control. */
233#define PLAYBACK_VOLUME_MIXER7 0x67 /* P16V Low to SRCMULTI SPDIF mixer input volume control. */
234#define PLAYBACK_VOLUME_MIXER8 0x68 /* P16V High to SRCMULTI SPDIF mixer input volume control. */
235#define PLAYBACK_VOLUME_MIXER9 0x69 /* P16V Low to SRCMULTI I2S mixer input volume control. */
236 /* 0xXXXX3030 = PCM0 Volume (Front).
237 * 0x3030XXXX = PCM1 Volume (Center)
238 */
239#define PLAYBACK_VOLUME_MIXER10 0x6a /* P16V High to SRCMULTI I2S mixer input volume control. */
240 /* 0x3030XXXX = PCM3 Volume (Rear). */
241#define PLAYBACK_VOLUME_MIXER11 0x6b /* E10K2 Low to SRC48 mixer input volume control. */
242#define PLAYBACK_VOLUME_MIXER12 0x6c /* E10K2 High to SRC48 mixer input volume control. */
243
244#define SRC48_ENABLE 0x6d /* SRC48 input audio enable */
245 /* SRC48 converts samples rates 44.1, 48, 96, 192 to 48 khz. */
246 /* [23:16] The corresponding P16V channel to SRC48 enabled if == 1.
247 * [31:24] The corresponding E10K2 channel to SRC48 enabled.
248 */
249#define SRCMULTI_ENABLE 0x6e /* SRCMulti input audio enable. Default 0xffffffff */
250 /* SRCMulti converts 48khz samples rates to 44.1, 48, 96, 192 to 48. */
251 /* [7:0] The corresponding P16V channel to SRCMulti_I2S enabled if == 1.
252 * [15:8] The corresponding E10K2 channel to SRCMulti I2S enabled.
253 * [23:16] The corresponding P16V channel to SRCMulti SPDIF enabled.
254 * [31:24] The corresponding E10K2 channel to SRCMulti SPDIF enabled.
255 */
256 /* Bypass P16V 0xff00ff00
257 * Bitmap. 0 = Off, 1 = On.
258 * P16V playback outputs:
259 * 0xXXXXXXX1 = PCM0 Left. (Front)
260 * 0xXXXXXXX2 = PCM0 Right.
261 * 0xXXXXXXX4 = PCM1 Left. (Center/LFE)
262 * 0xXXXXXXX8 = PCM1 Right.
263 * 0xXXXXXX1X = PCM2 Left. (Unknown)
264 * 0xXXXXXX2X = PCM2 Right.
265 * 0xXXXXXX4X = PCM3 Left. (Rear)
266 * 0xXXXXXX8X = PCM3 Right.
267 */
268#define AUDIO_OUT_ENABLE 0x6f /* Default: 000100FF */
269 /* [3:0] Does something, but not documented. Probably capture enable.
270 * [7:4] Playback channels enable. not documented.
271 * [16] AC97 output enable if == 1
272 * [30] 0 = SRCMulti_I2S input from fxengine 0x68-0x6f.
273 * 1 = SRCMulti_I2S input from SRC48 output.
274 * [31] 0 = SRCMulti_SPDIF input from fxengine 0x60-0x67.
275 * 1 = SRCMulti_SPDIF input from SRC48 output.
276 */
277 /* 0xffffffff -> C00100FF */
278 /* 0 -> Not playback sound, irq still running */
279 /* 0xXXXXXX10 = PCM0 Left/Right On. (Front)
280 * 0xXXXXXX20 = PCM1 Left/Right On. (Center/LFE)
281 * 0xXXXXXX40 = PCM2 Left/Right On. (Unknown)
282 * 0xXXXXXX80 = PCM3 Left/Right On. (Rear)
283 */
284#define PLAYBACK_SPDIF_SELECT 0x70 /* Default: 12030F00 */
285 /* 0xffffffff -> 3FF30FFF */
286 /* 0x00000001 pauses stream/irq fail. */
287 /* All other bits do not effect playback */
288#define PLAYBACK_SPDIF_SRC_SELECT 0x71 /* Default: 0000E4E4 */
289 /* 0xffffffff -> F33FFFFF */
290 /* All bits do not effect playback */
291#define PLAYBACK_SPDIF_USER_DATA0 0x72 /* SPDIF out user data 0 */
292#define PLAYBACK_SPDIF_USER_DATA1 0x73 /* SPDIF out user data 1 */
293/* 0x74-0x75 unknown */
294#define CAPTURE_SPDIF_CONTROL 0x76 /* SPDIF in control setting */
295#define CAPTURE_SPDIF_STATUS 0x77 /* SPDIF in status */
296#define CAPURE_SPDIF_USER_DATA0 0x78 /* SPDIF in user data 0 */
297#define CAPURE_SPDIF_USER_DATA1 0x79 /* SPDIF in user data 1 */
298#define CAPURE_SPDIF_USER_DATA2 0x7a /* SPDIF in user data 2 */
299
diff --git a/sound/pci/emu10k1/timer.c b/sound/pci/emu10k1/timer.c
new file mode 100644
index 000000000000..d2e364607c1d
--- /dev/null
+++ b/sound/pci/emu10k1/timer.c
@@ -0,0 +1,97 @@
1/*
2 * Copyright (c) by Lee Revell <rlrevell@joe-job.com>
3 * Clemens Ladisch <clemens@ladisch.de>
4 * Routines for control of EMU10K1 chips
5 *
6 * BUGS:
7 * --
8 *
9 * TODO:
10 * --
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 */
27
28#include <sound/driver.h>
29#include <linux/time.h>
30#include <sound/core.h>
31#include <sound/emu10k1.h>
32
33static int snd_emu10k1_timer_start(snd_timer_t *timer)
34{
35 emu10k1_t *emu;
36 unsigned long flags;
37 unsigned int delay;
38
39 emu = snd_timer_chip(timer);
40 delay = timer->sticks - 1;
41 if (delay < 5 ) /* minimum time is 5 ticks */
42 delay = 5;
43 spin_lock_irqsave(&emu->reg_lock, flags);
44 snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
45 outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
46 spin_unlock_irqrestore(&emu->reg_lock, flags);
47 return 0;
48}
49
50static int snd_emu10k1_timer_stop(snd_timer_t *timer)
51{
52 emu10k1_t *emu;
53 unsigned long flags;
54
55 emu = snd_timer_chip(timer);
56 spin_lock_irqsave(&emu->reg_lock, flags);
57 snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
58 spin_unlock_irqrestore(&emu->reg_lock, flags);
59 return 0;
60}
61
62static int snd_emu10k1_timer_precise_resolution(snd_timer_t *timer,
63 unsigned long *num, unsigned long *den)
64{
65 *num = 1;
66 *den = 48000;
67 return 0;
68}
69
70static struct _snd_timer_hardware snd_emu10k1_timer_hw = {
71 .flags = SNDRV_TIMER_HW_AUTO,
72 .resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
73 .ticks = 1024,
74 .start = snd_emu10k1_timer_start,
75 .stop = snd_emu10k1_timer_stop,
76 .precise_resolution = snd_emu10k1_timer_precise_resolution,
77};
78
79int __devinit snd_emu10k1_timer(emu10k1_t *emu, int device)
80{
81 snd_timer_t *timer = NULL;
82 snd_timer_id_t tid;
83 int err;
84
85 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
86 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
87 tid.card = emu->card->number;
88 tid.device = device;
89 tid.subdevice = 0;
90 if ((err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer)) >= 0) {
91 strcpy(timer->name, "EMU10K1 timer");
92 timer->private_data = emu;
93 timer->hw = snd_emu10k1_timer_hw;
94 }
95 emu->timer = timer;
96 return err;
97}
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
new file mode 100644
index 000000000000..d251d3440eec
--- /dev/null
+++ b/sound/pci/emu10k1/voice.c
@@ -0,0 +1,152 @@
1/*
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Creative Labs, Inc.
4 * Lee Revell <rlrevell@joe-job.com>
5 * Routines for control of EMU10K1 chips - voice manager
6 *
7 * Rewrote voice allocator for multichannel support - rlrevell 12/2004
8 *
9 * BUGS:
10 * --
11 *
12 * TODO:
13 * --
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31#include <sound/driver.h>
32#include <linux/time.h>
33#include <sound/core.h>
34#include <sound/emu10k1.h>
35
36/* Previously the voice allocator started at 0 every time. The new voice
37 * allocator uses a round robin scheme. The next free voice is tracked in
38 * the card record and each allocation begins where the last left off. The
39 * hardware requires stereo interleaved voices be aligned to an even/odd
40 * boundary. For multichannel voice allocation we ensure than the block of
41 * voices does not cross the 32 voice boundary. This simplifies the
42 * multichannel support and ensures we can use a single write to the
43 * (set|clear)_loop_stop registers. Otherwise (for example) the voices would
44 * get out of sync when pausing/resuming a stream.
45 * --rlrevell
46 */
47
48static int voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int number, emu10k1_voice_t **rvoice)
49{
50 emu10k1_voice_t *voice;
51 int i, j, k, first_voice, last_voice, skip;
52
53 *rvoice = NULL;
54 first_voice = last_voice = 0;
55 for (i = emu->next_free_voice, j = 0; j < NUM_G ; i += number, j += number) {
56 // printk("i %d j %d next free %d!\n", i, j, emu->next_free_voice);
57 i %= NUM_G;
58
59 /* stereo voices must be even/odd */
60 if ((number == 2) && (i % 2)) {
61 i++;
62 continue;
63 }
64
65 skip = 0;
66 for (k = 0; k < number; k++) {
67 voice = &emu->voices[(i+k) % NUM_G];
68 if (voice->use) {
69 skip = 1;
70 break;
71 }
72 }
73 if (!skip) {
74 // printk("allocated voice %d\n", i);
75 first_voice = i;
76 last_voice = (i + number) % NUM_G;
77 emu->next_free_voice = last_voice;
78 break;
79 }
80 }
81
82 if (first_voice == last_voice)
83 return -ENOMEM;
84
85 for (i=0; i < number; i++) {
86 voice = &emu->voices[(first_voice + i) % NUM_G];
87 // printk("voice alloc - %i, %i of %i\n", voice->number, idx-first_voice+1, number);
88 voice->use = 1;
89 switch (type) {
90 case EMU10K1_PCM:
91 voice->pcm = 1;
92 break;
93 case EMU10K1_SYNTH:
94 voice->synth = 1;
95 break;
96 case EMU10K1_MIDI:
97 voice->midi = 1;
98 break;
99 case EMU10K1_EFX:
100 voice->efx = 1;
101 break;
102 }
103 }
104 *rvoice = &emu->voices[first_voice];
105 return 0;
106}
107
108int snd_emu10k1_voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int number, emu10k1_voice_t **rvoice)
109{
110 unsigned long flags;
111 int result;
112
113 snd_assert(rvoice != NULL, return -EINVAL);
114 snd_assert(number, return -EINVAL);
115
116 spin_lock_irqsave(&emu->voice_lock, flags);
117 for (;;) {
118 result = voice_alloc(emu, type, number, rvoice);
119 if (result == 0 || type == EMU10K1_SYNTH || type == EMU10K1_MIDI)
120 break;
121
122 /* free a voice from synth */
123 if (emu->get_synth_voice) {
124 result = emu->get_synth_voice(emu);
125 if (result >= 0) {
126 emu10k1_voice_t *pvoice = &emu->voices[result];
127 pvoice->interrupt = NULL;
128 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0;
129 pvoice->epcm = NULL;
130 }
131 }
132 if (result < 0)
133 break;
134 }
135 spin_unlock_irqrestore(&emu->voice_lock, flags);
136
137 return result;
138}
139
140int snd_emu10k1_voice_free(emu10k1_t *emu, emu10k1_voice_t *pvoice)
141{
142 unsigned long flags;
143
144 snd_assert(pvoice != NULL, return -EINVAL);
145 spin_lock_irqsave(&emu->voice_lock, flags);
146 pvoice->interrupt = NULL;
147 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0;
148 pvoice->epcm = NULL;
149 snd_emu10k1_voice_init(emu, pvoice->number);
150 spin_unlock_irqrestore(&emu->voice_lock, flags);
151 return 0;
152}