source: GPL/alsa-kernel/pci/es1938.c@ 18

Last change on this file since 18 was 18, checked in by vladest, 20 years ago

initial import

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