blob: 7bfbdfc2f8bcdca20fc2ec3d2ffc40bc02798d7a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Driver for ESS Solo-1 (ES1938, ES1946, ES1969) soundcard
3 * Copyright (c) by Jaromir Koutek <miri@punknet.cz>,
4 * Jaroslav Kysela <perex@suse.cz>,
5 * Thomas Sailer <sailer@ife.ee.ethz.ch>,
6 * Abramo Bagnara <abramo@alsa-project.org>,
7 * Markus Gruber <gruber@eikon.tum.de>
8 *
9 * Rewritten from sonicvibes.c source.
10 *
11 * TODO:
12 * Rewrite better spinlocks
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/*
32 NOTES:
33 - Capture data is written unaligned starting from dma_base + 1 so I need to
34 disable mmap and to add a copy callback.
35 - After several cycle of the following:
36 while : ; do arecord -d1 -f cd -t raw | aplay -f cd ; done
37 a "playback write error (DMA or IRQ trouble?)" may happen.
38 This is due to playback interrupts not generated.
39 I suspect a timing issue.
40 - Sometimes the interrupt handler is invoked wrongly during playback.
41 This generates some harmless "Unexpected hw_pointer: wrong interrupt
42 acknowledge".
43 I've seen that using small period sizes.
44 Reproducible with:
45 mpg123 test.mp3 &
46 hdparm -t -T /dev/hda
47*/
48
49
50#include <sound/driver.h>
51#include <linux/init.h>
52#include <linux/interrupt.h>
53#include <linux/pci.h>
54#include <linux/slab.h>
55#include <linux/gameport.h>
56#include <linux/moduleparam.h>
57#include <linux/delay.h>
58#include <sound/core.h>
59#include <sound/control.h>
60#include <sound/pcm.h>
61#include <sound/opl3.h>
62#include <sound/mpu401.h>
63#include <sound/initval.h>
64
65#include <asm/io.h>
66
67MODULE_AUTHOR("Jaromir Koutek <miri@punknet.cz>");
68MODULE_DESCRIPTION("ESS Solo-1");
69MODULE_LICENSE("GPL");
70MODULE_SUPPORTED_DEVICE("{{ESS,ES1938},"
71 "{ESS,ES1946},"
72 "{ESS,ES1969},"
73 "{TerraTec,128i PCI}}");
74
75#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
76#define SUPPORT_JOYSTICK 1
77#endif
78
Linus Torvalds1da177e2005-04-16 15:20:36 -070079static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
80static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
81static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
82
83module_param_array(index, int, NULL, 0444);
84MODULE_PARM_DESC(index, "Index value for ESS Solo-1 soundcard.");
85module_param_array(id, charp, NULL, 0444);
86MODULE_PARM_DESC(id, "ID string for ESS Solo-1 soundcard.");
87module_param_array(enable, bool, NULL, 0444);
88MODULE_PARM_DESC(enable, "Enable ESS Solo-1 soundcard.");
89
90#define SLIO_REG(chip, x) ((chip)->io_port + ESSIO_REG_##x)
91
92#define SLDM_REG(chip, x) ((chip)->ddma_port + ESSDM_REG_##x)
93
94#define SLSB_REG(chip, x) ((chip)->sb_port + ESSSB_REG_##x)
95
96#define SL_PCI_LEGACYCONTROL 0x40
97#define SL_PCI_CONFIG 0x50
98#define SL_PCI_DDMACONTROL 0x60
99
100#define ESSIO_REG_AUDIO2DMAADDR 0
101#define ESSIO_REG_AUDIO2DMACOUNT 4
102#define ESSIO_REG_AUDIO2MODE 6
103#define ESSIO_REG_IRQCONTROL 7
104
105#define ESSDM_REG_DMAADDR 0x00
106#define ESSDM_REG_DMACOUNT 0x04
107#define ESSDM_REG_DMACOMMAND 0x08
108#define ESSDM_REG_DMASTATUS 0x08
109#define ESSDM_REG_DMAMODE 0x0b
110#define ESSDM_REG_DMACLEAR 0x0d
111#define ESSDM_REG_DMAMASK 0x0f
112
113#define ESSSB_REG_FMLOWADDR 0x00
114#define ESSSB_REG_FMHIGHADDR 0x02
115#define ESSSB_REG_MIXERADDR 0x04
116#define ESSSB_REG_MIXERDATA 0x05
117
118#define ESSSB_IREG_AUDIO1 0x14
119#define ESSSB_IREG_MICMIX 0x1a
120#define ESSSB_IREG_RECSRC 0x1c
121#define ESSSB_IREG_MASTER 0x32
122#define ESSSB_IREG_FM 0x36
123#define ESSSB_IREG_AUXACD 0x38
124#define ESSSB_IREG_AUXB 0x3a
125#define ESSSB_IREG_PCSPEAKER 0x3c
126#define ESSSB_IREG_LINE 0x3e
127#define ESSSB_IREG_SPATCONTROL 0x50
128#define ESSSB_IREG_SPATLEVEL 0x52
129#define ESSSB_IREG_MASTER_LEFT 0x60
130#define ESSSB_IREG_MASTER_RIGHT 0x62
131#define ESSSB_IREG_MPU401CONTROL 0x64
132#define ESSSB_IREG_MICMIXRECORD 0x68
133#define ESSSB_IREG_AUDIO2RECORD 0x69
134#define ESSSB_IREG_AUXACDRECORD 0x6a
135#define ESSSB_IREG_FMRECORD 0x6b
136#define ESSSB_IREG_AUXBRECORD 0x6c
137#define ESSSB_IREG_MONO 0x6d
138#define ESSSB_IREG_LINERECORD 0x6e
139#define ESSSB_IREG_MONORECORD 0x6f
140#define ESSSB_IREG_AUDIO2SAMPLE 0x70
141#define ESSSB_IREG_AUDIO2MODE 0x71
142#define ESSSB_IREG_AUDIO2FILTER 0x72
143#define ESSSB_IREG_AUDIO2TCOUNTL 0x74
144#define ESSSB_IREG_AUDIO2TCOUNTH 0x76
145#define ESSSB_IREG_AUDIO2CONTROL1 0x78
146#define ESSSB_IREG_AUDIO2CONTROL2 0x7a
147#define ESSSB_IREG_AUDIO2 0x7c
148
149#define ESSSB_REG_RESET 0x06
150
151#define ESSSB_REG_READDATA 0x0a
152#define ESSSB_REG_WRITEDATA 0x0c
153#define ESSSB_REG_READSTATUS 0x0c
154
155#define ESSSB_REG_STATUS 0x0e
156
157#define ESS_CMD_EXTSAMPLERATE 0xa1
158#define ESS_CMD_FILTERDIV 0xa2
159#define ESS_CMD_DMACNTRELOADL 0xa4
160#define ESS_CMD_DMACNTRELOADH 0xa5
161#define ESS_CMD_ANALOGCONTROL 0xa8
162#define ESS_CMD_IRQCONTROL 0xb1
163#define ESS_CMD_DRQCONTROL 0xb2
164#define ESS_CMD_RECLEVEL 0xb4
165#define ESS_CMD_SETFORMAT 0xb6
166#define ESS_CMD_SETFORMAT2 0xb7
167#define ESS_CMD_DMACONTROL 0xb8
168#define ESS_CMD_DMATYPE 0xb9
169#define ESS_CMD_OFFSETLEFT 0xba
170#define ESS_CMD_OFFSETRIGHT 0xbb
171#define ESS_CMD_READREG 0xc0
172#define ESS_CMD_ENABLEEXT 0xc6
173#define ESS_CMD_PAUSEDMA 0xd0
174#define ESS_CMD_ENABLEAUDIO1 0xd1
175#define ESS_CMD_STOPAUDIO1 0xd3
176#define ESS_CMD_AUDIO1STATUS 0xd8
177#define ESS_CMD_CONTDMA 0xd4
178#define ESS_CMD_TESTIRQ 0xf2
179
180#define ESS_RECSRC_MIC 0
181#define ESS_RECSRC_AUXACD 2
182#define ESS_RECSRC_AUXB 5
183#define ESS_RECSRC_LINE 6
184#define ESS_RECSRC_NONE 7
185
186#define DAC1 0x01
187#define ADC1 0x02
188#define DAC2 0x04
189
190/*
191
192 */
193
194typedef struct _snd_es1938 es1938_t;
195
196#define SAVED_REG_SIZE 32 /* max. number of registers to save */
197
198struct _snd_es1938 {
199 int irq;
200
201 unsigned long io_port;
202 unsigned long sb_port;
203 unsigned long vc_port;
204 unsigned long mpu_port;
205 unsigned long game_port;
206 unsigned long ddma_port;
207
208 unsigned char irqmask;
209 unsigned char revision;
210
211 snd_kcontrol_t *hw_volume;
212 snd_kcontrol_t *hw_switch;
213 snd_kcontrol_t *master_volume;
214 snd_kcontrol_t *master_switch;
215
216 struct pci_dev *pci;
217 snd_card_t *card;
218 snd_pcm_t *pcm;
219 snd_pcm_substream_t *capture_substream;
220 snd_pcm_substream_t *playback1_substream;
221 snd_pcm_substream_t *playback2_substream;
222 snd_kmixer_t *mixer;
223 snd_rawmidi_t *rmidi;
224
225 unsigned int dma1_size;
226 unsigned int dma2_size;
227 unsigned int dma1_start;
228 unsigned int dma2_start;
229 unsigned int dma1_shift;
230 unsigned int dma2_shift;
231 unsigned int active;
232
233 spinlock_t reg_lock;
234 spinlock_t mixer_lock;
235 snd_info_entry_t *proc_entry;
236
237#ifdef SUPPORT_JOYSTICK
238 struct gameport *gameport;
239#endif
240#ifdef CONFIG_PM
241 unsigned char saved_regs[SAVED_REG_SIZE];
242#endif
243};
244
245static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs);
246
247static struct pci_device_id snd_es1938_ids[] = {
248 { 0x125d, 0x1969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Solo-1 */
249 { 0, }
250};
251
252MODULE_DEVICE_TABLE(pci, snd_es1938_ids);
253
254#define RESET_LOOP_TIMEOUT 0x10000
255#define WRITE_LOOP_TIMEOUT 0x10000
256#define GET_LOOP_TIMEOUT 0x01000
257
258#undef REG_DEBUG
259/* -----------------------------------------------------------------
260 * Write to a mixer register
261 * -----------------------------------------------------------------*/
262static void snd_es1938_mixer_write(es1938_t *chip, unsigned char reg, unsigned char val)
263{
264 unsigned long flags;
265 spin_lock_irqsave(&chip->mixer_lock, flags);
266 outb(reg, SLSB_REG(chip, MIXERADDR));
267 outb(val, SLSB_REG(chip, MIXERDATA));
268 spin_unlock_irqrestore(&chip->mixer_lock, flags);
269#ifdef REG_DEBUG
270 snd_printk("Mixer reg %02x set to %02x\n", reg, val);
271#endif
272}
273
274/* -----------------------------------------------------------------
275 * Read from a mixer register
276 * -----------------------------------------------------------------*/
277static int snd_es1938_mixer_read(es1938_t *chip, unsigned char reg)
278{
279 int data;
280 unsigned long flags;
281 spin_lock_irqsave(&chip->mixer_lock, flags);
282 outb(reg, SLSB_REG(chip, MIXERADDR));
283 data = inb(SLSB_REG(chip, MIXERDATA));
284 spin_unlock_irqrestore(&chip->mixer_lock, flags);
285#ifdef REG_DEBUG
286 snd_printk("Mixer reg %02x now is %02x\n", reg, data);
287#endif
288 return data;
289}
290
291/* -----------------------------------------------------------------
292 * Write to some bits of a mixer register (return old value)
293 * -----------------------------------------------------------------*/
294static int snd_es1938_mixer_bits(es1938_t *chip, unsigned char reg, unsigned char mask, unsigned char val)
295{
296 unsigned long flags;
297 unsigned char old, new, oval;
298 spin_lock_irqsave(&chip->mixer_lock, flags);
299 outb(reg, SLSB_REG(chip, MIXERADDR));
300 old = inb(SLSB_REG(chip, MIXERDATA));
301 oval = old & mask;
302 if (val != oval) {
303 new = (old & ~mask) | (val & mask);
304 outb(new, SLSB_REG(chip, MIXERDATA));
305#ifdef REG_DEBUG
306 snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new);
307#endif
308 }
309 spin_unlock_irqrestore(&chip->mixer_lock, flags);
310 return oval;
311}
312
313/* -----------------------------------------------------------------
314 * Write command to Controller Registers
315 * -----------------------------------------------------------------*/
316static void snd_es1938_write_cmd(es1938_t *chip, unsigned char cmd)
317{
318 int i;
319 unsigned char v;
320 for (i = 0; i < WRITE_LOOP_TIMEOUT; i++) {
321 if (!(v = inb(SLSB_REG(chip, READSTATUS)) & 0x80)) {
322 outb(cmd, SLSB_REG(chip, WRITEDATA));
323 return;
324 }
325 }
326 printk("snd_es1938_write_cmd timeout (0x02%x/0x02%x)\n", cmd, v);
327}
328
329/* -----------------------------------------------------------------
330 * Read the Read Data Buffer
331 * -----------------------------------------------------------------*/
332static int snd_es1938_get_byte(es1938_t *chip)
333{
334 int i;
335 unsigned char v;
336 for (i = GET_LOOP_TIMEOUT; i; i--)
337 if ((v = inb(SLSB_REG(chip, STATUS))) & 0x80)
338 return inb(SLSB_REG(chip, READDATA));
339 snd_printk("get_byte timeout: status 0x02%x\n", v);
340 return -ENODEV;
341}
342
343/* -----------------------------------------------------------------
344 * Write value cmd register
345 * -----------------------------------------------------------------*/
346static void snd_es1938_write(es1938_t *chip, unsigned char reg, unsigned char val)
347{
348 unsigned long flags;
349 spin_lock_irqsave(&chip->reg_lock, flags);
350 snd_es1938_write_cmd(chip, reg);
351 snd_es1938_write_cmd(chip, val);
352 spin_unlock_irqrestore(&chip->reg_lock, flags);
353#ifdef REG_DEBUG
354 snd_printk("Reg %02x set to %02x\n", reg, val);
355#endif
356}
357
358/* -----------------------------------------------------------------
359 * Read data from cmd register and return it
360 * -----------------------------------------------------------------*/
361static unsigned char snd_es1938_read(es1938_t *chip, unsigned char reg)
362{
363 unsigned char val;
364 unsigned long flags;
365 spin_lock_irqsave(&chip->reg_lock, flags);
366 snd_es1938_write_cmd(chip, ESS_CMD_READREG);
367 snd_es1938_write_cmd(chip, reg);
368 val = snd_es1938_get_byte(chip);
369 spin_unlock_irqrestore(&chip->reg_lock, flags);
370#ifdef REG_DEBUG
371 snd_printk("Reg %02x now is %02x\n", reg, val);
372#endif
373 return val;
374}
375
376/* -----------------------------------------------------------------
377 * Write data to cmd register and return old value
378 * -----------------------------------------------------------------*/
379static int snd_es1938_bits(es1938_t *chip, unsigned char reg, unsigned char mask, unsigned char val)
380{
381 unsigned long flags;
382 unsigned char old, new, oval;
383 spin_lock_irqsave(&chip->reg_lock, flags);
384 snd_es1938_write_cmd(chip, ESS_CMD_READREG);
385 snd_es1938_write_cmd(chip, reg);
386 old = snd_es1938_get_byte(chip);
387 oval = old & mask;
388 if (val != oval) {
389 snd_es1938_write_cmd(chip, reg);
390 new = (old & ~mask) | (val & mask);
391 snd_es1938_write_cmd(chip, new);
392#ifdef REG_DEBUG
393 snd_printk("Reg %02x was %02x, set to %02x\n", reg, old, new);
394#endif
395 }
396 spin_unlock_irqrestore(&chip->reg_lock, flags);
397 return oval;
398}
399
400/* --------------------------------------------------------------------
401 * Reset the chip
402 * --------------------------------------------------------------------*/
403static void snd_es1938_reset(es1938_t *chip)
404{
405 int i;
406
407 outb(3, SLSB_REG(chip, RESET));
408 inb(SLSB_REG(chip, RESET));
409 outb(0, SLSB_REG(chip, RESET));
410 for (i = 0; i < RESET_LOOP_TIMEOUT; i++) {
411 if (inb(SLSB_REG(chip, STATUS)) & 0x80) {
412 if (inb(SLSB_REG(chip, READDATA)) == 0xaa)
413 goto __next;
414 }
415 }
416 snd_printk("ESS Solo-1 reset failed\n");
417
418 __next:
419 snd_es1938_write_cmd(chip, ESS_CMD_ENABLEEXT);
420
421 /* Demand transfer DMA: 4 bytes per DMA request */
422 snd_es1938_write(chip, ESS_CMD_DMATYPE, 2);
423
424 /* Change behaviour of register A1
425 4x oversampling
426 2nd channel DAC asynchronous */
427 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2MODE, 0x32);
428 /* enable/select DMA channel and IRQ channel */
429 snd_es1938_bits(chip, ESS_CMD_IRQCONTROL, 0xf0, 0x50);
430 snd_es1938_bits(chip, ESS_CMD_DRQCONTROL, 0xf0, 0x50);
431 snd_es1938_write_cmd(chip, ESS_CMD_ENABLEAUDIO1);
432 /* Set spatializer parameters to recommended values */
433 snd_es1938_mixer_write(chip, 0x54, 0x8f);
434 snd_es1938_mixer_write(chip, 0x56, 0x95);
435 snd_es1938_mixer_write(chip, 0x58, 0x94);
436 snd_es1938_mixer_write(chip, 0x5a, 0x80);
437}
438
439/* --------------------------------------------------------------------
440 * Reset the FIFOs
441 * --------------------------------------------------------------------*/
442static void snd_es1938_reset_fifo(es1938_t *chip)
443{
444 outb(2, SLSB_REG(chip, RESET));
445 outb(0, SLSB_REG(chip, RESET));
446}
447
448static ratnum_t clocks[2] = {
449 {
450 .num = 793800,
451 .den_min = 1,
452 .den_max = 128,
453 .den_step = 1,
454 },
455 {
456 .num = 768000,
457 .den_min = 1,
458 .den_max = 128,
459 .den_step = 1,
460 }
461};
462
463static snd_pcm_hw_constraint_ratnums_t hw_constraints_clocks = {
464 .nrats = 2,
465 .rats = clocks,
466};
467
468
469static void snd_es1938_rate_set(es1938_t *chip,
470 snd_pcm_substream_t *substream,
471 int mode)
472{
473 unsigned int bits, div0;
474 snd_pcm_runtime_t *runtime = substream->runtime;
475 if (runtime->rate_num == clocks[0].num)
476 bits = 128 - runtime->rate_den;
477 else
478 bits = 256 - runtime->rate_den;
479
480 /* set filter register */
481 div0 = 256 - 7160000*20/(8*82*runtime->rate);
482
483 if (mode == DAC2) {
484 snd_es1938_mixer_write(chip, 0x70, bits);
485 snd_es1938_mixer_write(chip, 0x72, div0);
486 } else {
487 snd_es1938_write(chip, 0xA1, bits);
488 snd_es1938_write(chip, 0xA2, div0);
489 }
490}
491
492/* --------------------------------------------------------------------
493 * Configure Solo1 builtin DMA Controller
494 * --------------------------------------------------------------------*/
495
496static void snd_es1938_playback1_setdma(es1938_t *chip)
497{
498 outb(0x00, SLIO_REG(chip, AUDIO2MODE));
499 outl(chip->dma2_start, SLIO_REG(chip, AUDIO2DMAADDR));
500 outw(0, SLIO_REG(chip, AUDIO2DMACOUNT));
501 outw(chip->dma2_size, SLIO_REG(chip, AUDIO2DMACOUNT));
502}
503
504static void snd_es1938_playback2_setdma(es1938_t *chip)
505{
506 /* Enable DMA controller */
507 outb(0xc4, SLDM_REG(chip, DMACOMMAND));
508 /* 1. Master reset */
509 outb(0, SLDM_REG(chip, DMACLEAR));
510 /* 2. Mask DMA */
511 outb(1, SLDM_REG(chip, DMAMASK));
512 outb(0x18, SLDM_REG(chip, DMAMODE));
513 outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));
514 outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));
515 /* 3. Unmask DMA */
516 outb(0, SLDM_REG(chip, DMAMASK));
517}
518
519static void snd_es1938_capture_setdma(es1938_t *chip)
520{
521 /* Enable DMA controller */
522 outb(0xc4, SLDM_REG(chip, DMACOMMAND));
523 /* 1. Master reset */
524 outb(0, SLDM_REG(chip, DMACLEAR));
525 /* 2. Mask DMA */
526 outb(1, SLDM_REG(chip, DMAMASK));
527 outb(0x14, SLDM_REG(chip, DMAMODE));
528 outl(chip->dma1_start, SLDM_REG(chip, DMAADDR));
529 outw(chip->dma1_size - 1, SLDM_REG(chip, DMACOUNT));
530 /* 3. Unmask DMA */
531 outb(0, SLDM_REG(chip, DMAMASK));
532}
533
534/* ----------------------------------------------------------------------
535 *
536 * *** PCM part ***
537 */
538
539static int snd_es1938_capture_trigger(snd_pcm_substream_t * substream,
540 int cmd)
541{
542 es1938_t *chip = snd_pcm_substream_chip(substream);
543 int val;
544 switch (cmd) {
545 case SNDRV_PCM_TRIGGER_START:
Takashi Iwai93b9f422005-10-10 13:42:24 +0200546 case SNDRV_PCM_TRIGGER_RESUME:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 val = 0x0f;
548 chip->active |= ADC1;
549 break;
550 case SNDRV_PCM_TRIGGER_STOP:
Takashi Iwai93b9f422005-10-10 13:42:24 +0200551 case SNDRV_PCM_TRIGGER_SUSPEND:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 val = 0x00;
553 chip->active &= ~ADC1;
554 break;
555 default:
556 return -EINVAL;
557 }
558 snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);
559 return 0;
560}
561
562static int snd_es1938_playback1_trigger(snd_pcm_substream_t * substream,
563 int cmd)
564{
565 es1938_t *chip = snd_pcm_substream_chip(substream);
566 switch (cmd) {
567 case SNDRV_PCM_TRIGGER_START:
Takashi Iwai93b9f422005-10-10 13:42:24 +0200568 case SNDRV_PCM_TRIGGER_RESUME:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 /* According to the documentation this should be:
570 0x13 but that value may randomly swap stereo channels */
571 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x92);
572 udelay(10);
573 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0x93);
574 /* This two stage init gives the FIFO -> DAC connection time to
575 * settle before first data from DMA flows in. This should ensure
576 * no swapping of stereo channels. Report a bug if otherwise :-) */
577 outb(0x0a, SLIO_REG(chip, AUDIO2MODE));
578 chip->active |= DAC2;
579 break;
580 case SNDRV_PCM_TRIGGER_STOP:
Takashi Iwai93b9f422005-10-10 13:42:24 +0200581 case SNDRV_PCM_TRIGGER_SUSPEND:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 outb(0, SLIO_REG(chip, AUDIO2MODE));
583 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL1, 0);
584 chip->active &= ~DAC2;
585 break;
586 default:
587 return -EINVAL;
588 }
589 return 0;
590}
591
592static int snd_es1938_playback2_trigger(snd_pcm_substream_t * substream,
593 int cmd)
594{
595 es1938_t *chip = snd_pcm_substream_chip(substream);
596 int val;
597 switch (cmd) {
598 case SNDRV_PCM_TRIGGER_START:
Takashi Iwai93b9f422005-10-10 13:42:24 +0200599 case SNDRV_PCM_TRIGGER_RESUME:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 val = 5;
601 chip->active |= DAC1;
602 break;
603 case SNDRV_PCM_TRIGGER_STOP:
Takashi Iwai93b9f422005-10-10 13:42:24 +0200604 case SNDRV_PCM_TRIGGER_SUSPEND:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 val = 0;
606 chip->active &= ~DAC1;
607 break;
608 default:
609 return -EINVAL;
610 }
611 snd_es1938_write(chip, ESS_CMD_DMACONTROL, val);
612 return 0;
613}
614
615static int snd_es1938_playback_trigger(snd_pcm_substream_t *substream,
616 int cmd)
617{
618 switch (substream->number) {
619 case 0:
620 return snd_es1938_playback1_trigger(substream, cmd);
621 case 1:
622 return snd_es1938_playback2_trigger(substream, cmd);
623 }
624 snd_BUG();
625 return -EINVAL;
626}
627
628/* --------------------------------------------------------------------
629 * First channel for Extended Mode Audio 1 ADC Operation
630 * --------------------------------------------------------------------*/
631static int snd_es1938_capture_prepare(snd_pcm_substream_t * substream)
632{
633 es1938_t *chip = snd_pcm_substream_chip(substream);
634 snd_pcm_runtime_t *runtime = substream->runtime;
635 int u, is8, mono;
636 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
637 unsigned int count = snd_pcm_lib_period_bytes(substream);
638
639 chip->dma1_size = size;
640 chip->dma1_start = runtime->dma_addr;
641
642 mono = (runtime->channels > 1) ? 0 : 1;
643 is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
644 u = snd_pcm_format_unsigned(runtime->format);
645
646 chip->dma1_shift = 2 - mono - is8;
647
648 snd_es1938_reset_fifo(chip);
649
650 /* program type */
651 snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));
652
653 /* set clock and counters */
654 snd_es1938_rate_set(chip, substream, ADC1);
655
656 count = 0x10000 - count;
657 snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);
658 snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);
659
660 /* initialize and configure ADC */
661 snd_es1938_write(chip, ESS_CMD_SETFORMAT2, u ? 0x51 : 0x71);
662 snd_es1938_write(chip, ESS_CMD_SETFORMAT2, 0x90 |
663 (u ? 0x00 : 0x20) |
664 (is8 ? 0x00 : 0x04) |
665 (mono ? 0x40 : 0x08));
666
667 // snd_es1938_reset_fifo(chip);
668
669 /* 11. configure system interrupt controller and DMA controller */
670 snd_es1938_capture_setdma(chip);
671
672 return 0;
673}
674
675
676/* ------------------------------------------------------------------------------
677 * Second Audio channel DAC Operation
678 * ------------------------------------------------------------------------------*/
679static int snd_es1938_playback1_prepare(snd_pcm_substream_t * substream)
680{
681 es1938_t *chip = snd_pcm_substream_chip(substream);
682 snd_pcm_runtime_t *runtime = substream->runtime;
683 int u, is8, mono;
684 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
685 unsigned int count = snd_pcm_lib_period_bytes(substream);
686
687 chip->dma2_size = size;
688 chip->dma2_start = runtime->dma_addr;
689
690 mono = (runtime->channels > 1) ? 0 : 1;
691 is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
692 u = snd_pcm_format_unsigned(runtime->format);
693
694 chip->dma2_shift = 2 - mono - is8;
695
696 snd_es1938_reset_fifo(chip);
697
698 /* set clock and counters */
699 snd_es1938_rate_set(chip, substream, DAC2);
700
701 count >>= 1;
702 count = 0x10000 - count;
703 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTL, count & 0xff);
704 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTH, count >> 8);
705
706 /* initialize and configure Audio 2 DAC */
707 snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x40 | (u ? 0 : 4) | (mono ? 0 : 2) | (is8 ? 0 : 1));
708
709 /* program DMA */
710 snd_es1938_playback1_setdma(chip);
711
712 return 0;
713}
714
715static int snd_es1938_playback2_prepare(snd_pcm_substream_t * substream)
716{
717 es1938_t *chip = snd_pcm_substream_chip(substream);
718 snd_pcm_runtime_t *runtime = substream->runtime;
719 int u, is8, mono;
720 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
721 unsigned int count = snd_pcm_lib_period_bytes(substream);
722
723 chip->dma1_size = size;
724 chip->dma1_start = runtime->dma_addr;
725
726 mono = (runtime->channels > 1) ? 0 : 1;
727 is8 = snd_pcm_format_width(runtime->format) == 16 ? 0 : 1;
728 u = snd_pcm_format_unsigned(runtime->format);
729
730 chip->dma1_shift = 2 - mono - is8;
731
732 count = 0x10000 - count;
733
734 /* reset */
735 snd_es1938_reset_fifo(chip);
736
737 snd_es1938_bits(chip, ESS_CMD_ANALOGCONTROL, 0x03, (mono ? 2 : 1));
738
739 /* set clock and counters */
740 snd_es1938_rate_set(chip, substream, DAC1);
741 snd_es1938_write(chip, ESS_CMD_DMACNTRELOADL, count & 0xff);
742 snd_es1938_write(chip, ESS_CMD_DMACNTRELOADH, count >> 8);
743
744 /* initialized and configure DAC */
745 snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x80 : 0x00);
746 snd_es1938_write(chip, ESS_CMD_SETFORMAT, u ? 0x51 : 0x71);
747 snd_es1938_write(chip, ESS_CMD_SETFORMAT2,
748 0x90 | (mono ? 0x40 : 0x08) |
749 (is8 ? 0x00 : 0x04) | (u ? 0x00 : 0x20));
750
751 /* program DMA */
752 snd_es1938_playback2_setdma(chip);
753
754 return 0;
755}
756
757static int snd_es1938_playback_prepare(snd_pcm_substream_t *substream)
758{
759 switch (substream->number) {
760 case 0:
761 return snd_es1938_playback1_prepare(substream);
762 case 1:
763 return snd_es1938_playback2_prepare(substream);
764 }
765 snd_BUG();
766 return -EINVAL;
767}
768
769static snd_pcm_uframes_t snd_es1938_capture_pointer(snd_pcm_substream_t * substream)
770{
771 es1938_t *chip = snd_pcm_substream_chip(substream);
772 size_t ptr;
773 size_t old, new;
774#if 1
775 /* This stuff is *needed*, don't ask why - AB */
776 old = inw(SLDM_REG(chip, DMACOUNT));
777 while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)
778 old = new;
779 ptr = chip->dma1_size - 1 - new;
780#else
781 ptr = inl(SLDM_REG(chip, DMAADDR)) - chip->dma1_start;
782#endif
783 return ptr >> chip->dma1_shift;
784}
785
786static snd_pcm_uframes_t snd_es1938_playback1_pointer(snd_pcm_substream_t * substream)
787{
788 es1938_t *chip = snd_pcm_substream_chip(substream);
789 size_t ptr;
790#if 1
791 ptr = chip->dma2_size - inw(SLIO_REG(chip, AUDIO2DMACOUNT));
792#else
793 ptr = inl(SLIO_REG(chip, AUDIO2DMAADDR)) - chip->dma2_start;
794#endif
795 return ptr >> chip->dma2_shift;
796}
797
798static snd_pcm_uframes_t snd_es1938_playback2_pointer(snd_pcm_substream_t * substream)
799{
800 es1938_t *chip = snd_pcm_substream_chip(substream);
801 size_t ptr;
802 size_t old, new;
803#if 1
804 /* This stuff is *needed*, don't ask why - AB */
805 old = inw(SLDM_REG(chip, DMACOUNT));
806 while ((new = inw(SLDM_REG(chip, DMACOUNT))) != old)
807 old = new;
808 ptr = chip->dma1_size - 1 - new;
809#else
810 ptr = inl(SLDM_REG(chip, DMAADDR)) - chip->dma1_start;
811#endif
812 return ptr >> chip->dma1_shift;
813}
814
815static snd_pcm_uframes_t snd_es1938_playback_pointer(snd_pcm_substream_t *substream)
816{
817 switch (substream->number) {
818 case 0:
819 return snd_es1938_playback1_pointer(substream);
820 case 1:
821 return snd_es1938_playback2_pointer(substream);
822 }
823 snd_BUG();
824 return -EINVAL;
825}
826
827static int snd_es1938_capture_copy(snd_pcm_substream_t *substream,
828 int channel,
829 snd_pcm_uframes_t pos,
830 void __user *dst,
831 snd_pcm_uframes_t count)
832{
833 snd_pcm_runtime_t *runtime = substream->runtime;
834 es1938_t *chip = snd_pcm_substream_chip(substream);
835 pos <<= chip->dma1_shift;
836 count <<= chip->dma1_shift;
837 snd_assert(pos + count <= chip->dma1_size, return -EINVAL);
838 if (pos + count < chip->dma1_size) {
839 if (copy_to_user(dst, runtime->dma_area + pos + 1, count))
840 return -EFAULT;
841 } else {
842 if (copy_to_user(dst, runtime->dma_area + pos + 1, count - 1))
843 return -EFAULT;
844 if (put_user(runtime->dma_area[0], ((unsigned char __user *)dst) + count - 1))
845 return -EFAULT;
846 }
847 return 0;
848}
849
850/*
851 * buffer management
852 */
853static int snd_es1938_pcm_hw_params(snd_pcm_substream_t *substream,
854 snd_pcm_hw_params_t * hw_params)
855
856{
857 int err;
858
859 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
860 return err;
861 return 0;
862}
863
864static int snd_es1938_pcm_hw_free(snd_pcm_substream_t *substream)
865{
866 return snd_pcm_lib_free_pages(substream);
867}
868
869/* ----------------------------------------------------------------------
870 * Audio1 Capture (ADC)
871 * ----------------------------------------------------------------------*/
872static snd_pcm_hardware_t snd_es1938_capture =
873{
874 .info = (SNDRV_PCM_INFO_INTERLEAVED |
875 SNDRV_PCM_INFO_BLOCK_TRANSFER),
876 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE,
877 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
878 .rate_min = 6000,
879 .rate_max = 48000,
880 .channels_min = 1,
881 .channels_max = 2,
882 .buffer_bytes_max = 0x8000, /* DMA controller screws on higher values */
883 .period_bytes_min = 64,
884 .period_bytes_max = 0x8000,
885 .periods_min = 1,
886 .periods_max = 1024,
887 .fifo_size = 256,
888};
889
890/* -----------------------------------------------------------------------
891 * Audio2 Playback (DAC)
892 * -----------------------------------------------------------------------*/
893static snd_pcm_hardware_t snd_es1938_playback =
894{
895 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
896 SNDRV_PCM_INFO_BLOCK_TRANSFER |
897 SNDRV_PCM_INFO_MMAP_VALID),
898 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE,
899 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
900 .rate_min = 6000,
901 .rate_max = 48000,
902 .channels_min = 1,
903 .channels_max = 2,
904 .buffer_bytes_max = 0x8000, /* DMA controller screws on higher values */
905 .period_bytes_min = 64,
906 .period_bytes_max = 0x8000,
907 .periods_min = 1,
908 .periods_max = 1024,
909 .fifo_size = 256,
910};
911
912static int snd_es1938_capture_open(snd_pcm_substream_t * substream)
913{
914 es1938_t *chip = snd_pcm_substream_chip(substream);
915 snd_pcm_runtime_t *runtime = substream->runtime;
916
917 if (chip->playback2_substream)
918 return -EAGAIN;
919 chip->capture_substream = substream;
920 runtime->hw = snd_es1938_capture;
921 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
922 &hw_constraints_clocks);
923 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);
924 return 0;
925}
926
927static int snd_es1938_playback_open(snd_pcm_substream_t * substream)
928{
929 es1938_t *chip = snd_pcm_substream_chip(substream);
930 snd_pcm_runtime_t *runtime = substream->runtime;
931
932 switch (substream->number) {
933 case 0:
934 chip->playback1_substream = substream;
935 break;
936 case 1:
937 if (chip->capture_substream)
938 return -EAGAIN;
939 chip->playback2_substream = substream;
940 break;
941 default:
942 snd_BUG();
943 return -EINVAL;
944 }
945 runtime->hw = snd_es1938_playback;
946 snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
947 &hw_constraints_clocks);
948 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, 0xff00);
949 return 0;
950}
951
952static int snd_es1938_capture_close(snd_pcm_substream_t * substream)
953{
954 es1938_t *chip = snd_pcm_substream_chip(substream);
955
956 chip->capture_substream = NULL;
957 return 0;
958}
959
960static int snd_es1938_playback_close(snd_pcm_substream_t * substream)
961{
962 es1938_t *chip = snd_pcm_substream_chip(substream);
963
964 switch (substream->number) {
965 case 0:
966 chip->playback1_substream = NULL;
967 break;
968 case 1:
969 chip->playback2_substream = NULL;
970 break;
971 default:
972 snd_BUG();
973 return -EINVAL;
974 }
975 return 0;
976}
977
978static snd_pcm_ops_t snd_es1938_playback_ops = {
979 .open = snd_es1938_playback_open,
980 .close = snd_es1938_playback_close,
981 .ioctl = snd_pcm_lib_ioctl,
982 .hw_params = snd_es1938_pcm_hw_params,
983 .hw_free = snd_es1938_pcm_hw_free,
984 .prepare = snd_es1938_playback_prepare,
985 .trigger = snd_es1938_playback_trigger,
986 .pointer = snd_es1938_playback_pointer,
987};
988
989static snd_pcm_ops_t snd_es1938_capture_ops = {
990 .open = snd_es1938_capture_open,
991 .close = snd_es1938_capture_close,
992 .ioctl = snd_pcm_lib_ioctl,
993 .hw_params = snd_es1938_pcm_hw_params,
994 .hw_free = snd_es1938_pcm_hw_free,
995 .prepare = snd_es1938_capture_prepare,
996 .trigger = snd_es1938_capture_trigger,
997 .pointer = snd_es1938_capture_pointer,
998 .copy = snd_es1938_capture_copy,
999};
1000
1001static void snd_es1938_free_pcm(snd_pcm_t *pcm)
1002{
1003 snd_pcm_lib_preallocate_free_for_all(pcm);
1004}
1005
1006static int __devinit snd_es1938_new_pcm(es1938_t *chip, int device)
1007{
1008 snd_pcm_t *pcm;
1009 int err;
1010
1011 if ((err = snd_pcm_new(chip->card, "es-1938-1946", device, 2, 1, &pcm)) < 0)
1012 return err;
1013 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1938_playback_ops);
1014 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1938_capture_ops);
1015
1016 pcm->private_data = chip;
1017 pcm->private_free = snd_es1938_free_pcm;
1018 pcm->info_flags = 0;
1019 strcpy(pcm->name, "ESS Solo-1");
1020
1021 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1022 snd_dma_pci_data(chip->pci), 64*1024, 64*1024);
1023
1024 chip->pcm = pcm;
1025 return 0;
1026}
1027
1028/* -------------------------------------------------------------------
1029 *
1030 * *** Mixer part ***
1031 */
1032
1033static int snd_es1938_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1034{
1035 static char *texts[8] = {
1036 "Mic", "Mic Master", "CD", "AOUT",
1037 "Mic1", "Mix", "Line", "Master"
1038 };
1039
1040 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1041 uinfo->count = 1;
1042 uinfo->value.enumerated.items = 8;
1043 if (uinfo->value.enumerated.item > 7)
1044 uinfo->value.enumerated.item = 7;
1045 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1046 return 0;
1047}
1048
1049static int snd_es1938_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1050{
1051 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1052 ucontrol->value.enumerated.item[0] = snd_es1938_mixer_read(chip, 0x1c) & 0x07;
1053 return 0;
1054}
1055
1056static int snd_es1938_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1057{
1058 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1059 unsigned char val = ucontrol->value.enumerated.item[0];
1060
1061 if (val > 7)
1062 return -EINVAL;
1063 return snd_es1938_mixer_bits(chip, 0x1c, 0x07, val) != val;
1064}
1065
1066static int snd_es1938_info_spatializer_enable(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1067{
1068 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1069 uinfo->count = 1;
1070 uinfo->value.integer.min = 0;
1071 uinfo->value.integer.max = 1;
1072 return 0;
1073}
1074
1075static int snd_es1938_get_spatializer_enable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1076{
1077 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1078 unsigned char val = snd_es1938_mixer_read(chip, 0x50);
1079 ucontrol->value.integer.value[0] = !!(val & 8);
1080 return 0;
1081}
1082
1083static int snd_es1938_put_spatializer_enable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1084{
1085 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1086 unsigned char oval, nval;
1087 int change;
1088 nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04;
1089 oval = snd_es1938_mixer_read(chip, 0x50) & 0x0c;
1090 change = nval != oval;
1091 if (change) {
1092 snd_es1938_mixer_write(chip, 0x50, nval & ~0x04);
1093 snd_es1938_mixer_write(chip, 0x50, nval);
1094 }
1095 return change;
1096}
1097
1098static int snd_es1938_info_hw_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1099{
1100 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1101 uinfo->count = 2;
1102 uinfo->value.integer.min = 0;
1103 uinfo->value.integer.max = 63;
1104 return 0;
1105}
1106
1107static int snd_es1938_get_hw_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1108{
1109 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1110 ucontrol->value.integer.value[0] = snd_es1938_mixer_read(chip, 0x61) & 0x3f;
1111 ucontrol->value.integer.value[1] = snd_es1938_mixer_read(chip, 0x63) & 0x3f;
1112 return 0;
1113}
1114
1115static int snd_es1938_info_hw_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1116{
1117 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1118 uinfo->count = 2;
1119 uinfo->value.integer.min = 0;
1120 uinfo->value.integer.max = 1;
1121 return 0;
1122}
1123
1124static int snd_es1938_get_hw_switch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1125{
1126 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1127 ucontrol->value.integer.value[0] = !(snd_es1938_mixer_read(chip, 0x61) & 0x40);
1128 ucontrol->value.integer.value[1] = !(snd_es1938_mixer_read(chip, 0x63) & 0x40);
1129 return 0;
1130}
1131
1132static void snd_es1938_hwv_free(snd_kcontrol_t *kcontrol)
1133{
1134 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1135 chip->master_volume = NULL;
1136 chip->master_switch = NULL;
1137 chip->hw_volume = NULL;
1138 chip->hw_switch = NULL;
1139}
1140
1141static int snd_es1938_reg_bits(es1938_t *chip, unsigned char reg,
1142 unsigned char mask, unsigned char val)
1143{
1144 if (reg < 0xa0)
1145 return snd_es1938_mixer_bits(chip, reg, mask, val);
1146 else
1147 return snd_es1938_bits(chip, reg, mask, val);
1148}
1149
1150static int snd_es1938_reg_read(es1938_t *chip, unsigned char reg)
1151{
1152 if (reg < 0xa0)
1153 return snd_es1938_mixer_read(chip, reg);
1154 else
1155 return snd_es1938_read(chip, reg);
1156}
1157
1158#define ES1938_SINGLE(xname, xindex, reg, shift, mask, invert) \
1159{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1160 .info = snd_es1938_info_single, \
1161 .get = snd_es1938_get_single, .put = snd_es1938_put_single, \
1162 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
1163
1164static int snd_es1938_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1165{
1166 int mask = (kcontrol->private_value >> 16) & 0xff;
1167
1168 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1169 uinfo->count = 1;
1170 uinfo->value.integer.min = 0;
1171 uinfo->value.integer.max = mask;
1172 return 0;
1173}
1174
1175static int snd_es1938_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1176{
1177 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1178 int reg = kcontrol->private_value & 0xff;
1179 int shift = (kcontrol->private_value >> 8) & 0xff;
1180 int mask = (kcontrol->private_value >> 16) & 0xff;
1181 int invert = (kcontrol->private_value >> 24) & 0xff;
1182 int val;
1183
1184 val = snd_es1938_reg_read(chip, reg);
1185 ucontrol->value.integer.value[0] = (val >> shift) & mask;
1186 if (invert)
1187 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1188 return 0;
1189}
1190
1191static int snd_es1938_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1192{
1193 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1194 int reg = kcontrol->private_value & 0xff;
1195 int shift = (kcontrol->private_value >> 8) & 0xff;
1196 int mask = (kcontrol->private_value >> 16) & 0xff;
1197 int invert = (kcontrol->private_value >> 24) & 0xff;
1198 unsigned char val;
1199
1200 val = (ucontrol->value.integer.value[0] & mask);
1201 if (invert)
1202 val = mask - val;
1203 mask <<= shift;
1204 val <<= shift;
1205 return snd_es1938_reg_bits(chip, reg, mask, val) != val;
1206}
1207
1208#define ES1938_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
1209{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
1210 .info = snd_es1938_info_double, \
1211 .get = snd_es1938_get_double, .put = snd_es1938_put_double, \
1212 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
1213
1214static int snd_es1938_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
1215{
1216 int mask = (kcontrol->private_value >> 24) & 0xff;
1217
1218 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1219 uinfo->count = 2;
1220 uinfo->value.integer.min = 0;
1221 uinfo->value.integer.max = mask;
1222 return 0;
1223}
1224
1225static int snd_es1938_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1226{
1227 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1228 int left_reg = kcontrol->private_value & 0xff;
1229 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1230 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1231 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1232 int mask = (kcontrol->private_value >> 24) & 0xff;
1233 int invert = (kcontrol->private_value >> 22) & 1;
1234 unsigned char left, right;
1235
1236 left = snd_es1938_reg_read(chip, left_reg);
1237 if (left_reg != right_reg)
1238 right = snd_es1938_reg_read(chip, right_reg);
1239 else
1240 right = left;
1241 ucontrol->value.integer.value[0] = (left >> shift_left) & mask;
1242 ucontrol->value.integer.value[1] = (right >> shift_right) & mask;
1243 if (invert) {
1244 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
1245 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
1246 }
1247 return 0;
1248}
1249
1250static int snd_es1938_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
1251{
1252 es1938_t *chip = snd_kcontrol_chip(kcontrol);
1253 int left_reg = kcontrol->private_value & 0xff;
1254 int right_reg = (kcontrol->private_value >> 8) & 0xff;
1255 int shift_left = (kcontrol->private_value >> 16) & 0x07;
1256 int shift_right = (kcontrol->private_value >> 19) & 0x07;
1257 int mask = (kcontrol->private_value >> 24) & 0xff;
1258 int invert = (kcontrol->private_value >> 22) & 1;
1259 int change;
1260 unsigned char val1, val2, mask1, mask2;
1261
1262 val1 = ucontrol->value.integer.value[0] & mask;
1263 val2 = ucontrol->value.integer.value[1] & mask;
1264 if (invert) {
1265 val1 = mask - val1;
1266 val2 = mask - val2;
1267 }
1268 val1 <<= shift_left;
1269 val2 <<= shift_right;
1270 mask1 = mask << shift_left;
1271 mask2 = mask << shift_right;
1272 if (left_reg != right_reg) {
1273 change = 0;
1274 if (snd_es1938_reg_bits(chip, left_reg, mask1, val1) != val1)
1275 change = 1;
1276 if (snd_es1938_reg_bits(chip, right_reg, mask2, val2) != val2)
1277 change = 1;
1278 } else {
1279 change = (snd_es1938_reg_bits(chip, left_reg, mask1 | mask2,
1280 val1 | val2) != (val1 | val2));
1281 }
1282 return change;
1283}
1284
1285static snd_kcontrol_new_t snd_es1938_controls[] = {
1286ES1938_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0),
1287ES1938_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
1288{
1289 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1290 .name = "Hardware Master Playback Volume",
1291 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1292 .info = snd_es1938_info_hw_volume,
1293 .get = snd_es1938_get_hw_volume,
1294},
1295{
1296 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1297 .name = "Hardware Master Playback Switch",
1298 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1299 .info = snd_es1938_info_hw_switch,
1300 .get = snd_es1938_get_hw_switch,
1301},
1302ES1938_SINGLE("Hardware Volume Split", 0, 0x64, 7, 1, 0),
1303ES1938_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0),
1304ES1938_DOUBLE("CD Playback Volume", 0, 0x38, 0x38, 4, 0, 15, 0),
1305ES1938_DOUBLE("FM Playback Volume", 0, 0x36, 0x36, 4, 0, 15, 0),
1306ES1938_DOUBLE("Mono Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
1307ES1938_DOUBLE("Mic Playback Volume", 0, 0x1a, 0x1a, 4, 0, 15, 0),
1308ES1938_DOUBLE("Aux Playback Volume", 0, 0x3a, 0x3a, 4, 0, 15, 0),
1309ES1938_DOUBLE("Capture Volume", 0, 0xb4, 0xb4, 4, 0, 15, 0),
1310ES1938_SINGLE("PC Speaker Volume", 0, 0x3c, 0, 7, 0),
1311ES1938_SINGLE("Record Monitor", 0, 0xa8, 3, 1, 0),
1312ES1938_SINGLE("Capture Switch", 0, 0x1c, 4, 1, 1),
1313{
1314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1315 .name = "Capture Source",
1316 .info = snd_es1938_info_mux,
1317 .get = snd_es1938_get_mux,
1318 .put = snd_es1938_put_mux,
1319},
1320ES1938_DOUBLE("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0),
1321ES1938_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0),
1322ES1938_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0),
1323ES1938_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0),
1324ES1938_DOUBLE("FM Capture Volume", 0, 0x6b, 0x6b, 4, 0, 15, 0),
1325ES1938_DOUBLE("Mono Capture Volume", 0, 0x6f, 0x6f, 4, 0, 15, 0),
1326ES1938_DOUBLE("CD Capture Volume", 0, 0x6a, 0x6a, 4, 0, 15, 0),
1327ES1938_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0),
1328ES1938_DOUBLE("PCM Playback Volume", 0, 0x7c, 0x7c, 4, 0, 15, 0),
1329ES1938_DOUBLE("PCM Playback Volume", 1, 0x14, 0x14, 4, 0, 15, 0),
1330ES1938_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
1331{
1332 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1333 .name = "3D Control - Switch",
1334 .info = snd_es1938_info_spatializer_enable,
1335 .get = snd_es1938_get_spatializer_enable,
1336 .put = snd_es1938_put_spatializer_enable,
1337},
1338ES1938_SINGLE("Mic Boost (+26dB)", 0, 0x7d, 3, 1, 0)
1339};
1340
1341
1342/* ---------------------------------------------------------------------------- */
1343/* ---------------------------------------------------------------------------- */
1344
1345/*
1346 * initialize the chip - used by resume callback, too
1347 */
1348static void snd_es1938_chip_init(es1938_t *chip)
1349{
1350 /* reset chip */
1351 snd_es1938_reset(chip);
1352
1353 /* configure native mode */
1354
1355 /* enable bus master */
1356 pci_set_master(chip->pci);
1357
1358 /* disable legacy audio */
1359 pci_write_config_word(chip->pci, SL_PCI_LEGACYCONTROL, 0x805f);
1360
1361 /* set DDMA base */
1362 pci_write_config_word(chip->pci, SL_PCI_DDMACONTROL, chip->ddma_port | 1);
1363
1364 /* set DMA/IRQ policy */
1365 pci_write_config_dword(chip->pci, SL_PCI_CONFIG, 0);
1366
1367 /* enable Audio 1, Audio 2, MPU401 IRQ and HW volume IRQ*/
1368 outb(0xf0, SLIO_REG(chip, IRQCONTROL));
1369
1370 /* reset DMA */
1371 outb(0, SLDM_REG(chip, DMACLEAR));
1372}
1373
1374#ifdef CONFIG_PM
1375/*
1376 * PM support
1377 */
1378
1379static unsigned char saved_regs[SAVED_REG_SIZE+1] = {
1380 0x14, 0x1a, 0x1c, 0x3a, 0x3c, 0x3e, 0x36, 0x38,
1381 0x50, 0x52, 0x60, 0x61, 0x62, 0x63, 0x64, 0x68,
1382 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x7c, 0x7d,
1383 0xa8, 0xb4,
1384};
1385
1386
1387static int es1938_suspend(snd_card_t *card, pm_message_t state)
1388{
1389 es1938_t *chip = card->pm_private_data;
1390 unsigned char *s, *d;
1391
1392 snd_pcm_suspend_all(chip->pcm);
1393
1394 /* save mixer-related registers */
1395 for (s = saved_regs, d = chip->saved_regs; *s; s++, d++)
1396 *d = snd_es1938_reg_read(chip, *s);
1397
1398 outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
Takashi Iwai93b9f422005-10-10 13:42:24 +02001399 if (chip->irq >= 0)
Rudolf Marekc913f692005-10-10 12:11:23 +02001400 free_irq(chip->irq, (void *)chip);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 pci_disable_device(chip->pci);
1402 return 0;
1403}
1404
1405static int es1938_resume(snd_card_t *card)
1406{
1407 es1938_t *chip = card->pm_private_data;
1408 unsigned char *s, *d;
1409
1410 pci_enable_device(chip->pci);
Takashi Iwai93b9f422005-10-10 13:42:24 +02001411 request_irq(chip->pci->irq, snd_es1938_interrupt,
1412 SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip);
1413 chip->irq = chip->pci->irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 snd_es1938_chip_init(chip);
1415
1416 /* restore mixer-related registers */
1417 for (s = saved_regs, d = chip->saved_regs; *s; s++, d++) {
1418 if (*s < 0xa0)
1419 snd_es1938_mixer_write(chip, *s, *d);
1420 else
1421 snd_es1938_write(chip, *s, *d);
1422 }
1423
1424 return 0;
1425}
1426#endif /* CONFIG_PM */
1427
1428#ifdef SUPPORT_JOYSTICK
1429static int __devinit snd_es1938_create_gameport(es1938_t *chip)
1430{
1431 struct gameport *gp;
1432
1433 chip->gameport = gp = gameport_allocate_port();
1434 if (!gp) {
1435 printk(KERN_ERR "es1938: cannot allocate memory for gameport\n");
1436 return -ENOMEM;
1437 }
1438
1439 gameport_set_name(gp, "ES1938");
1440 gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci));
1441 gameport_set_dev_parent(gp, &chip->pci->dev);
1442 gp->io = chip->game_port;
1443
1444 gameport_register_port(gp);
1445
1446 return 0;
1447}
1448
1449static void snd_es1938_free_gameport(es1938_t *chip)
1450{
1451 if (chip->gameport) {
1452 gameport_unregister_port(chip->gameport);
1453 chip->gameport = NULL;
1454 }
1455}
1456#else
1457static inline int snd_es1938_create_gameport(es1938_t *chip) { return -ENOSYS; }
1458static inline void snd_es1938_free_gameport(es1938_t *chip) { }
1459#endif /* SUPPORT_JOYSTICK */
1460
1461static int snd_es1938_free(es1938_t *chip)
1462{
1463 /* disable irqs */
1464 outb(0x00, SLIO_REG(chip, IRQCONTROL));
1465 if (chip->rmidi)
1466 snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0);
1467
1468 snd_es1938_free_gameport(chip);
1469
1470 if (chip->irq >= 0)
1471 free_irq(chip->irq, (void *)chip);
1472 pci_release_regions(chip->pci);
1473 pci_disable_device(chip->pci);
1474 kfree(chip);
1475 return 0;
1476}
1477
1478static int snd_es1938_dev_free(snd_device_t *device)
1479{
1480 es1938_t *chip = device->device_data;
1481 return snd_es1938_free(chip);
1482}
1483
1484static int __devinit snd_es1938_create(snd_card_t * card,
1485 struct pci_dev * pci,
1486 es1938_t ** rchip)
1487{
1488 es1938_t *chip;
1489 int err;
1490 static snd_device_ops_t ops = {
1491 .dev_free = snd_es1938_dev_free,
1492 };
1493
1494 *rchip = NULL;
1495
1496 /* enable PCI device */
1497 if ((err = pci_enable_device(pci)) < 0)
1498 return err;
1499 /* check, if we can restrict PCI DMA transfers to 24 bits */
1500 if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
1501 pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
1502 snd_printk("architecture does not support 24bit PCI busmaster DMA\n");
1503 pci_disable_device(pci);
1504 return -ENXIO;
1505 }
1506
Takashi Iwaie560d8d2005-09-09 14:21:46 +02001507 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 if (chip == NULL) {
1509 pci_disable_device(pci);
1510 return -ENOMEM;
1511 }
1512 spin_lock_init(&chip->reg_lock);
1513 spin_lock_init(&chip->mixer_lock);
1514 chip->card = card;
1515 chip->pci = pci;
1516 if ((err = pci_request_regions(pci, "ESS Solo-1")) < 0) {
1517 kfree(chip);
1518 pci_disable_device(pci);
1519 return err;
1520 }
1521 chip->io_port = pci_resource_start(pci, 0);
1522 chip->sb_port = pci_resource_start(pci, 1);
1523 chip->vc_port = pci_resource_start(pci, 2);
1524 chip->mpu_port = pci_resource_start(pci, 3);
1525 chip->game_port = pci_resource_start(pci, 4);
1526 if (request_irq(pci->irq, snd_es1938_interrupt, SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip)) {
1527 snd_printk("unable to grab IRQ %d\n", pci->irq);
1528 snd_es1938_free(chip);
1529 return -EBUSY;
1530 }
1531 chip->irq = pci->irq;
1532#ifdef ES1938_DDEBUG
1533 snd_printk("create: io: 0x%lx, sb: 0x%lx, vc: 0x%lx, mpu: 0x%lx, game: 0x%lx\n",
1534 chip->io_port, chip->sb_port, chip->vc_port, chip->mpu_port, chip->game_port);
1535#endif
1536
1537 chip->ddma_port = chip->vc_port + 0x00; /* fix from Thomas Sailer */
1538
1539 snd_es1938_chip_init(chip);
1540
1541 snd_card_set_pm_callback(card, es1938_suspend, es1938_resume, chip);
1542
1543 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1544 snd_es1938_free(chip);
1545 return err;
1546 }
1547
1548 snd_card_set_dev(card, &pci->dev);
1549
1550 *rchip = chip;
1551 return 0;
1552}
1553
1554/* --------------------------------------------------------------------
1555 * Interrupt handler
1556 * -------------------------------------------------------------------- */
1557static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1558{
1559 es1938_t *chip = dev_id;
1560 unsigned char status, audiostatus;
1561 int handled = 0;
1562
1563 status = inb(SLIO_REG(chip, IRQCONTROL));
1564#if 0
1565 printk("Es1938debug - interrupt status: =0x%x\n", status);
1566#endif
1567
1568 /* AUDIO 1 */
1569 if (status & 0x10) {
1570#if 0
1571 printk("Es1938debug - AUDIO channel 1 interrupt\n");
1572 printk("Es1938debug - AUDIO channel 1 DMAC DMA count: %u\n", inw(SLDM_REG(chip, DMACOUNT)));
1573 printk("Es1938debug - AUDIO channel 1 DMAC DMA base: %u\n", inl(SLDM_REG(chip, DMAADDR)));
1574 printk("Es1938debug - AUDIO channel 1 DMAC DMA status: 0x%x\n", inl(SLDM_REG(chip, DMASTATUS)));
1575#endif
1576 /* clear irq */
1577 handled = 1;
1578 audiostatus = inb(SLSB_REG(chip, STATUS));
1579 if (chip->active & ADC1)
1580 snd_pcm_period_elapsed(chip->capture_substream);
1581 else if (chip->active & DAC1)
1582 snd_pcm_period_elapsed(chip->playback2_substream);
1583 }
1584
1585 /* AUDIO 2 */
1586 if (status & 0x20) {
1587#if 0
1588 printk("Es1938debug - AUDIO channel 2 interrupt\n");
1589 printk("Es1938debug - AUDIO channel 2 DMAC DMA count: %u\n", inw(SLIO_REG(chip, AUDIO2DMACOUNT)));
1590 printk("Es1938debug - AUDIO channel 2 DMAC DMA base: %u\n", inl(SLIO_REG(chip, AUDIO2DMAADDR)));
1591
1592#endif
1593 /* clear irq */
1594 handled = 1;
1595 snd_es1938_mixer_bits(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x80, 0);
1596 if (chip->active & DAC2)
1597 snd_pcm_period_elapsed(chip->playback1_substream);
1598 }
1599
1600 /* Hardware volume */
1601 if (status & 0x40) {
1602 int split = snd_es1938_mixer_read(chip, 0x64) & 0x80;
1603 handled = 1;
1604 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);
1605 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
1606 if (!split) {
1607 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id);
1608 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id);
1609 }
1610 /* ack interrupt */
1611 snd_es1938_mixer_write(chip, 0x66, 0x00);
1612 }
1613
1614 /* MPU401 */
1615 if (status & 0x80) {
1616 // the following line is evil! It switches off MIDI interrupt handling after the first interrupt received.
1617 // replacing the last 0 by 0x40 works for ESS-Solo1, but just doing nothing works as well!
1618 // andreas@flying-snail.de
1619 // snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); /* ack? */
1620 if (chip->rmidi) {
1621 handled = 1;
1622 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
1623 }
1624 }
1625 return IRQ_RETVAL(handled);
1626}
1627
1628#define ES1938_DMA_SIZE 64
1629
1630static int __devinit snd_es1938_mixer(es1938_t *chip)
1631{
1632 snd_card_t *card;
1633 unsigned int idx;
1634 int err;
1635
1636 card = chip->card;
1637
1638 strcpy(card->mixername, "ESS Solo-1");
1639
1640 for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {
1641 snd_kcontrol_t *kctl;
1642 kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);
1643 switch (idx) {
1644 case 0:
1645 chip->master_volume = kctl;
1646 kctl->private_free = snd_es1938_hwv_free;
1647 break;
1648 case 1:
1649 chip->master_switch = kctl;
1650 kctl->private_free = snd_es1938_hwv_free;
1651 break;
1652 case 2:
1653 chip->hw_volume = kctl;
1654 kctl->private_free = snd_es1938_hwv_free;
1655 break;
1656 case 3:
1657 chip->hw_switch = kctl;
1658 kctl->private_free = snd_es1938_hwv_free;
1659 break;
1660 }
1661 if ((err = snd_ctl_add(card, kctl)) < 0)
1662 return err;
1663 }
1664 return 0;
1665}
1666
1667
1668static int __devinit snd_es1938_probe(struct pci_dev *pci,
1669 const struct pci_device_id *pci_id)
1670{
1671 static int dev;
1672 snd_card_t *card;
1673 es1938_t *chip;
1674 opl3_t *opl3;
1675 int idx, err;
1676
1677 if (dev >= SNDRV_CARDS)
1678 return -ENODEV;
1679 if (!enable[dev]) {
1680 dev++;
1681 return -ENOENT;
1682 }
1683
1684 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1685 if (card == NULL)
1686 return -ENOMEM;
1687 for (idx = 0; idx < 5; idx++) {
1688 if (pci_resource_start(pci, idx) == 0 ||
1689 !(pci_resource_flags(pci, idx) & IORESOURCE_IO)) {
1690 snd_card_free(card);
1691 return -ENODEV;
1692 }
1693 }
1694 if ((err = snd_es1938_create(card, pci, &chip)) < 0) {
1695 snd_card_free(card);
1696 return err;
1697 }
1698
1699 strcpy(card->driver, "ES1938");
1700 strcpy(card->shortname, "ESS ES1938 (Solo-1)");
1701 sprintf(card->longname, "%s rev %i, irq %i",
1702 card->shortname,
1703 chip->revision,
1704 chip->irq);
1705
1706 if ((err = snd_es1938_new_pcm(chip, 0)) < 0) {
1707 snd_card_free(card);
1708 return err;
1709 }
1710 if ((err = snd_es1938_mixer(chip)) < 0) {
1711 snd_card_free(card);
1712 return err;
1713 }
1714 if (snd_opl3_create(card,
1715 SLSB_REG(chip, FMLOWADDR),
1716 SLSB_REG(chip, FMHIGHADDR),
1717 OPL3_HW_OPL3, 1, &opl3) < 0) {
1718 printk(KERN_ERR "es1938: OPL3 not detected at 0x%lx\n",
1719 SLSB_REG(chip, FMLOWADDR));
1720 } else {
1721 if ((err = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
1722 snd_card_free(card);
1723 return err;
1724 }
1725 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
1726 snd_card_free(card);
1727 return err;
1728 }
1729 }
1730 if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
1731 chip->mpu_port, 1, chip->irq, 0, &chip->rmidi) < 0) {
1732 printk(KERN_ERR "es1938: unable to initialize MPU-401\n");
1733 } else {
1734 // this line is vital for MIDI interrupt handling on ess-solo1
1735 // andreas@flying-snail.de
1736 snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40);
1737 }
1738
1739 snd_es1938_create_gameport(chip);
1740
1741 if ((err = snd_card_register(card)) < 0) {
1742 snd_card_free(card);
1743 return err;
1744 }
1745
1746 pci_set_drvdata(pci, card);
1747 dev++;
1748 return 0;
1749}
1750
1751static void __devexit snd_es1938_remove(struct pci_dev *pci)
1752{
1753 snd_card_free(pci_get_drvdata(pci));
1754 pci_set_drvdata(pci, NULL);
1755}
1756
1757static struct pci_driver driver = {
1758 .name = "ESS ES1938 (Solo-1)",
Clemens Ladisch3bcd4642005-09-12 08:20:54 +02001759 .owner = THIS_MODULE,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 .id_table = snd_es1938_ids,
1761 .probe = snd_es1938_probe,
1762 .remove = __devexit_p(snd_es1938_remove),
1763 SND_PCI_PM_CALLBACKS
1764};
1765
1766static int __init alsa_card_es1938_init(void)
1767{
Takashi Iwai01d25d42005-04-11 16:58:24 +02001768 return pci_register_driver(&driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769}
1770
1771static void __exit alsa_card_es1938_exit(void)
1772{
1773 pci_unregister_driver(&driver);
1774}
1775
1776module_init(alsa_card_es1938_init)
1777module_exit(alsa_card_es1938_exit)