• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/sound/isa/es1688/
1/*
2 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3 *  Routines for control of ESS ES1688/688/488 chip
4 *
5 *
6 *   This program is free software; you can redistribute it and/or modify
7 *   it under the terms of the GNU General Public License as published by
8 *   the Free Software Foundation; either version 2 of the License, or
9 *   (at your option) any later version.
10 *
11 *   This program is distributed in the hope that it will be useful,
12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *   GNU General Public License for more details.
15 *
16 *   You should have received a copy of the GNU General Public License
17 *   along with this program; if not, write to the Free Software
18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 *
20 */
21
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/delay.h>
25#include <linux/slab.h>
26#include <linux/ioport.h>
27#include <sound/core.h>
28#include <sound/es1688.h>
29#include <sound/initval.h>
30
31#include <asm/io.h>
32#include <asm/dma.h>
33
34MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
35MODULE_DESCRIPTION("ESS ESx688 lowlevel module");
36MODULE_LICENSE("GPL");
37
38static int snd_es1688_dsp_command(struct snd_es1688 *chip, unsigned char val)
39{
40	int i;
41
42	for (i = 10000; i; i--)
43		if ((inb(ES1688P(chip, STATUS)) & 0x80) == 0) {
44			outb(val, ES1688P(chip, COMMAND));
45			return 1;
46		}
47#ifdef CONFIG_SND_DEBUG
48	printk(KERN_DEBUG "snd_es1688_dsp_command: timeout (0x%x)\n", val);
49#endif
50	return 0;
51}
52
53static int snd_es1688_dsp_get_byte(struct snd_es1688 *chip)
54{
55	int i;
56
57	for (i = 1000; i; i--)
58		if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80)
59			return inb(ES1688P(chip, READ));
60	snd_printd("es1688 get byte failed: 0x%lx = 0x%x!!!\n", ES1688P(chip, DATA_AVAIL), inb(ES1688P(chip, DATA_AVAIL)));
61	return -ENODEV;
62}
63
64static int snd_es1688_write(struct snd_es1688 *chip,
65			    unsigned char reg, unsigned char data)
66{
67	if (!snd_es1688_dsp_command(chip, reg))
68		return 0;
69	return snd_es1688_dsp_command(chip, data);
70}
71
72static int snd_es1688_read(struct snd_es1688 *chip, unsigned char reg)
73{
74	/* Read a byte from an extended mode register of ES1688 */
75	if (!snd_es1688_dsp_command(chip, 0xc0))
76		return -1;
77	if (!snd_es1688_dsp_command(chip, reg))
78		return -1;
79	return snd_es1688_dsp_get_byte(chip);
80}
81
82void snd_es1688_mixer_write(struct snd_es1688 *chip,
83			    unsigned char reg, unsigned char data)
84{
85	outb(reg, ES1688P(chip, MIXER_ADDR));
86	udelay(10);
87	outb(data, ES1688P(chip, MIXER_DATA));
88	udelay(10);
89}
90
91static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned char reg)
92{
93	unsigned char result;
94
95	outb(reg, ES1688P(chip, MIXER_ADDR));
96	udelay(10);
97	result = inb(ES1688P(chip, MIXER_DATA));
98	udelay(10);
99	return result;
100}
101
102int snd_es1688_reset(struct snd_es1688 *chip)
103{
104	int i;
105
106	outb(3, ES1688P(chip, RESET));		/* valid only for ESS chips, SB -> 1 */
107	udelay(10);
108	outb(0, ES1688P(chip, RESET));
109	udelay(30);
110	for (i = 0; i < 1000 && !(inb(ES1688P(chip, DATA_AVAIL)) & 0x80); i++);
111	if (inb(ES1688P(chip, READ)) != 0xaa) {
112		snd_printd("ess_reset at 0x%lx: failed!!!\n", chip->port);
113		return -ENODEV;
114	}
115	snd_es1688_dsp_command(chip, 0xc6);	/* enable extended mode */
116	return 0;
117}
118EXPORT_SYMBOL(snd_es1688_reset);
119
120static int snd_es1688_probe(struct snd_es1688 *chip)
121{
122	unsigned long flags;
123	unsigned short major, minor, hw;
124	int i;
125
126	/*
127	 *  initialization sequence
128	 */
129
130	spin_lock_irqsave(&chip->reg_lock, flags);	/* Some ESS1688 cards need this */
131	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
132	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
133	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
134	inb(ES1688P(chip, ENABLE2));	/* ENABLE2 */
135	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
136	inb(ES1688P(chip, ENABLE2));	/* ENABLE2 */
137	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
138	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
139	inb(ES1688P(chip, ENABLE2));	/* ENABLE2 */
140	inb(ES1688P(chip, ENABLE1));	/* ENABLE1 */
141	inb(ES1688P(chip, ENABLE0));	/* ENABLE0 */
142
143	if (snd_es1688_reset(chip) < 0) {
144		snd_printdd("ESS: [0x%lx] reset failed... 0x%x\n", chip->port, inb(ES1688P(chip, READ)));
145		spin_unlock_irqrestore(&chip->reg_lock, flags);
146		return -ENODEV;
147	}
148	snd_es1688_dsp_command(chip, 0xe7);	/* return identification */
149
150	for (i = 1000, major = minor = 0; i; i--) {
151		if (inb(ES1688P(chip, DATA_AVAIL)) & 0x80) {
152			if (major == 0) {
153				major = inb(ES1688P(chip, READ));
154			} else {
155				minor = inb(ES1688P(chip, READ));
156			}
157		}
158	}
159
160	spin_unlock_irqrestore(&chip->reg_lock, flags);
161
162	snd_printdd("ESS: [0x%lx] found.. major = 0x%x, minor = 0x%x\n", chip->port, major, minor);
163
164	chip->version = (major << 8) | minor;
165	if (!chip->version)
166		return -ENODEV;	/* probably SB */
167
168	hw = ES1688_HW_AUTO;
169	switch (chip->version & 0xfff0) {
170	case 0x4880:
171		snd_printk(KERN_ERR "[0x%lx] ESS: AudioDrive ES488 detected, "
172			   "but driver is in another place\n", chip->port);
173		return -ENODEV;
174	case 0x6880:
175		hw = (chip->version & 0x0f) >= 8 ? ES1688_HW_1688 : ES1688_HW_688;
176		break;
177	default:
178		snd_printk(KERN_ERR "[0x%lx] ESS: unknown AudioDrive chip "
179			   "with version 0x%x (Jazz16 soundcard?)\n",
180			   chip->port, chip->version);
181		return -ENODEV;
182	}
183
184	spin_lock_irqsave(&chip->reg_lock, flags);
185	snd_es1688_write(chip, 0xb1, 0x10);	/* disable IRQ */
186	snd_es1688_write(chip, 0xb2, 0x00);	/* disable DMA */
187	spin_unlock_irqrestore(&chip->reg_lock, flags);
188
189	/* enable joystick, but disable OPL3 */
190	spin_lock_irqsave(&chip->mixer_lock, flags);
191	snd_es1688_mixer_write(chip, 0x40, 0x01);
192	spin_unlock_irqrestore(&chip->mixer_lock, flags);
193
194	return 0;
195}
196
197static int snd_es1688_init(struct snd_es1688 * chip, int enable)
198{
199	static int irqs[16] = {-1, -1, 0, -1, -1, 1, -1, 2, -1, 0, 3, -1, -1, -1, -1, -1};
200	unsigned long flags;
201	int cfg, irq_bits, dma, dma_bits, tmp, tmp1;
202
203	/* ok.. setup MPU-401 port and joystick and OPL3 */
204	cfg = 0x01;		/* enable joystick, but disable OPL3 */
205	if (enable && chip->mpu_port >= 0x300 && chip->mpu_irq > 0 && chip->hardware != ES1688_HW_688) {
206		tmp = (chip->mpu_port & 0x0f0) >> 4;
207		if (tmp <= 3) {
208			switch (chip->mpu_irq) {
209			case 9:
210				tmp1 = 4;
211				break;
212			case 5:
213				tmp1 = 5;
214				break;
215			case 7:
216				tmp1 = 6;
217				break;
218			case 10:
219				tmp1 = 7;
220				break;
221			default:
222				tmp1 = 0;
223			}
224			if (tmp1) {
225				cfg |= (tmp << 3) | (tmp1 << 5);
226			}
227		}
228	}
229	spin_lock_irqsave(&chip->reg_lock, flags);
230	snd_es1688_mixer_write(chip, 0x40, cfg);
231	spin_unlock_irqrestore(&chip->reg_lock, flags);
232	/* --- */
233	spin_lock_irqsave(&chip->reg_lock, flags);
234	snd_es1688_read(chip, 0xb1);
235	snd_es1688_read(chip, 0xb2);
236	spin_unlock_irqrestore(&chip->reg_lock, flags);
237	if (enable) {
238		cfg = 0xf0;	/* enable only DMA counter interrupt */
239		irq_bits = irqs[chip->irq & 0x0f];
240		if (irq_bits < 0) {
241			snd_printk(KERN_ERR "[0x%lx] ESS: bad IRQ %d "
242				   "for ES1688 chip!!\n",
243				   chip->port, chip->irq);
244			return -EINVAL;
245		}
246		spin_lock_irqsave(&chip->reg_lock, flags);
247		snd_es1688_write(chip, 0xb1, cfg | (irq_bits << 2));
248		spin_unlock_irqrestore(&chip->reg_lock, flags);
249		cfg = 0xf0;	/* extended mode DMA enable */
250		dma = chip->dma8;
251		if (dma > 3 || dma == 2) {
252			snd_printk(KERN_ERR "[0x%lx] ESS: bad DMA channel %d "
253				   "for ES1688 chip!!\n", chip->port, dma);
254			return -EINVAL;
255		} else {
256			dma_bits = dma;
257			if (dma != 3)
258				dma_bits++;
259		}
260		spin_lock_irqsave(&chip->reg_lock, flags);
261		snd_es1688_write(chip, 0xb2, cfg | (dma_bits << 2));
262		spin_unlock_irqrestore(&chip->reg_lock, flags);
263	} else {
264		spin_lock_irqsave(&chip->reg_lock, flags);
265		snd_es1688_write(chip, 0xb1, 0x10);	/* disable IRQ */
266		snd_es1688_write(chip, 0xb2, 0x00);	/* disable DMA */
267		spin_unlock_irqrestore(&chip->reg_lock, flags);
268	}
269	spin_lock_irqsave(&chip->reg_lock, flags);
270	snd_es1688_read(chip, 0xb1);
271	snd_es1688_read(chip, 0xb2);
272	snd_es1688_reset(chip);
273	spin_unlock_irqrestore(&chip->reg_lock, flags);
274	return 0;
275}
276
277/*
278
279 */
280
281static struct snd_ratnum clocks[2] = {
282	{
283		.num = 795444,
284		.den_min = 1,
285		.den_max = 128,
286		.den_step = 1,
287	},
288	{
289		.num = 397722,
290		.den_min = 1,
291		.den_max = 128,
292		.den_step = 1,
293	}
294};
295
296static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks  = {
297	.nrats = 2,
298	.rats = clocks,
299};
300
301static void snd_es1688_set_rate(struct snd_es1688 *chip, struct snd_pcm_substream *substream)
302{
303	struct snd_pcm_runtime *runtime = substream->runtime;
304	unsigned int bits, divider;
305
306	if (runtime->rate_num == clocks[0].num)
307		bits = 256 - runtime->rate_den;
308	else
309		bits = 128 - runtime->rate_den;
310	/* set filter register */
311	divider = 256 - 7160000*20/(8*82*runtime->rate);
312	/* write result to hardware */
313	snd_es1688_write(chip, 0xa1, bits);
314	snd_es1688_write(chip, 0xa2, divider);
315}
316
317static int snd_es1688_ioctl(struct snd_pcm_substream *substream,
318			    unsigned int cmd, void *arg)
319{
320	return snd_pcm_lib_ioctl(substream, cmd, arg);
321}
322
323static int snd_es1688_trigger(struct snd_es1688 *chip, int cmd, unsigned char value)
324{
325	int val;
326
327	if (cmd == SNDRV_PCM_TRIGGER_STOP) {
328		value = 0x00;
329	} else if (cmd != SNDRV_PCM_TRIGGER_START) {
330		return -EINVAL;
331	}
332	spin_lock(&chip->reg_lock);
333	chip->trigger_value = value;
334	val = snd_es1688_read(chip, 0xb8);
335	if ((val < 0) || (val & 0x0f) == value) {
336		spin_unlock(&chip->reg_lock);
337		return -EINVAL;	/* something is wrong */
338	}
339	snd_es1688_write(chip, 0xb8, (val & 0xf0) | value);
340	spin_unlock(&chip->reg_lock);
341	return 0;
342}
343
344static int snd_es1688_hw_params(struct snd_pcm_substream *substream,
345				struct snd_pcm_hw_params *hw_params)
346{
347	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
348}
349
350static int snd_es1688_hw_free(struct snd_pcm_substream *substream)
351{
352	return snd_pcm_lib_free_pages(substream);
353}
354
355static int snd_es1688_playback_prepare(struct snd_pcm_substream *substream)
356{
357	unsigned long flags;
358	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
359	struct snd_pcm_runtime *runtime = substream->runtime;
360	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
361	unsigned int count = snd_pcm_lib_period_bytes(substream);
362
363	chip->dma_size = size;
364	spin_lock_irqsave(&chip->reg_lock, flags);
365	snd_es1688_reset(chip);
366	snd_es1688_set_rate(chip, substream);
367	snd_es1688_write(chip, 0xb8, 4);	/* auto init DMA mode */
368	snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));
369	snd_es1688_write(chip, 0xb9, 2);	/* demand mode (4 bytes/request) */
370	if (runtime->channels == 1) {
371		if (snd_pcm_format_width(runtime->format) == 8) {
372			/* 8. bit mono */
373			snd_es1688_write(chip, 0xb6, 0x80);
374			snd_es1688_write(chip, 0xb7, 0x51);
375			snd_es1688_write(chip, 0xb7, 0xd0);
376		} else {
377			/* 16. bit mono */
378			snd_es1688_write(chip, 0xb6, 0x00);
379			snd_es1688_write(chip, 0xb7, 0x71);
380			snd_es1688_write(chip, 0xb7, 0xf4);
381		}
382	} else {
383		if (snd_pcm_format_width(runtime->format) == 8) {
384			/* 8. bit stereo */
385			snd_es1688_write(chip, 0xb6, 0x80);
386			snd_es1688_write(chip, 0xb7, 0x51);
387			snd_es1688_write(chip, 0xb7, 0x98);
388		} else {
389			/* 16. bit stereo */
390			snd_es1688_write(chip, 0xb6, 0x00);
391			snd_es1688_write(chip, 0xb7, 0x71);
392			snd_es1688_write(chip, 0xb7, 0xbc);
393		}
394	}
395	snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);
396	snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);
397	snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKON);
398	spin_unlock_irqrestore(&chip->reg_lock, flags);
399	/* --- */
400	count = -count;
401	snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
402	spin_lock_irqsave(&chip->reg_lock, flags);
403	snd_es1688_write(chip, 0xa4, (unsigned char) count);
404	snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));
405	spin_unlock_irqrestore(&chip->reg_lock, flags);
406	return 0;
407}
408
409static int snd_es1688_playback_trigger(struct snd_pcm_substream *substream,
410				       int cmd)
411{
412	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
413	return snd_es1688_trigger(chip, cmd, 0x05);
414}
415
416static int snd_es1688_capture_prepare(struct snd_pcm_substream *substream)
417{
418	unsigned long flags;
419	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
420	struct snd_pcm_runtime *runtime = substream->runtime;
421	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
422	unsigned int count = snd_pcm_lib_period_bytes(substream);
423
424	chip->dma_size = size;
425	spin_lock_irqsave(&chip->reg_lock, flags);
426	snd_es1688_reset(chip);
427	snd_es1688_set_rate(chip, substream);
428	snd_es1688_dsp_command(chip, ES1688_DSP_CMD_SPKOFF);
429	snd_es1688_write(chip, 0xb8, 0x0e);	/* auto init DMA mode */
430	snd_es1688_write(chip, 0xa8, (snd_es1688_read(chip, 0xa8) & ~0x03) | (3 - runtime->channels));
431	snd_es1688_write(chip, 0xb9, 2);	/* demand mode (4 bytes/request) */
432	if (runtime->channels == 1) {
433		if (snd_pcm_format_width(runtime->format) == 8) {
434			/* 8. bit mono */
435			snd_es1688_write(chip, 0xb7, 0x51);
436			snd_es1688_write(chip, 0xb7, 0xd0);
437		} else {
438			/* 16. bit mono */
439			snd_es1688_write(chip, 0xb7, 0x71);
440			snd_es1688_write(chip, 0xb7, 0xf4);
441		}
442	} else {
443		if (snd_pcm_format_width(runtime->format) == 8) {
444			/* 8. bit stereo */
445			snd_es1688_write(chip, 0xb7, 0x51);
446			snd_es1688_write(chip, 0xb7, 0x98);
447		} else {
448			/* 16. bit stereo */
449			snd_es1688_write(chip, 0xb7, 0x71);
450			snd_es1688_write(chip, 0xb7, 0xbc);
451		}
452	}
453	snd_es1688_write(chip, 0xb1, (snd_es1688_read(chip, 0xb1) & 0x0f) | 0x50);
454	snd_es1688_write(chip, 0xb2, (snd_es1688_read(chip, 0xb2) & 0x0f) | 0x50);
455	spin_unlock_irqrestore(&chip->reg_lock, flags);
456	/* --- */
457	count = -count;
458	snd_dma_program(chip->dma8, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
459	spin_lock_irqsave(&chip->reg_lock, flags);
460	snd_es1688_write(chip, 0xa4, (unsigned char) count);
461	snd_es1688_write(chip, 0xa5, (unsigned char) (count >> 8));
462	spin_unlock_irqrestore(&chip->reg_lock, flags);
463	return 0;
464}
465
466static int snd_es1688_capture_trigger(struct snd_pcm_substream *substream,
467				      int cmd)
468{
469	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
470	return snd_es1688_trigger(chip, cmd, 0x0f);
471}
472
473static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id)
474{
475	struct snd_es1688 *chip = dev_id;
476
477	if (chip->trigger_value == 0x05)	/* ok.. playback is active */
478		snd_pcm_period_elapsed(chip->playback_substream);
479	if (chip->trigger_value == 0x0f)	/* ok.. capture is active */
480		snd_pcm_period_elapsed(chip->capture_substream);
481
482	inb(ES1688P(chip, DATA_AVAIL));	/* ack interrupt */
483	return IRQ_HANDLED;
484}
485
486static snd_pcm_uframes_t snd_es1688_playback_pointer(struct snd_pcm_substream *substream)
487{
488	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
489	size_t ptr;
490
491	if (chip->trigger_value != 0x05)
492		return 0;
493	ptr = snd_dma_pointer(chip->dma8, chip->dma_size);
494	return bytes_to_frames(substream->runtime, ptr);
495}
496
497static snd_pcm_uframes_t snd_es1688_capture_pointer(struct snd_pcm_substream *substream)
498{
499	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
500	size_t ptr;
501
502	if (chip->trigger_value != 0x0f)
503		return 0;
504	ptr = snd_dma_pointer(chip->dma8, chip->dma_size);
505	return bytes_to_frames(substream->runtime, ptr);
506}
507
508/*
509
510 */
511
512static struct snd_pcm_hardware snd_es1688_playback =
513{
514	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
515				 SNDRV_PCM_INFO_MMAP_VALID),
516	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
517	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
518	.rate_min =		4000,
519	.rate_max =		48000,
520	.channels_min =		1,
521	.channels_max =		2,
522	.buffer_bytes_max =	65536,
523	.period_bytes_min =	64,
524	.period_bytes_max =	65536,
525	.periods_min =		1,
526	.periods_max =		1024,
527	.fifo_size =		0,
528};
529
530static struct snd_pcm_hardware snd_es1688_capture =
531{
532	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
533				 SNDRV_PCM_INFO_MMAP_VALID),
534	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
535	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
536	.rate_min =		4000,
537	.rate_max =		48000,
538	.channels_min =		1,
539	.channels_max =		2,
540	.buffer_bytes_max =	65536,
541	.period_bytes_min =	64,
542	.period_bytes_max =	65536,
543	.periods_min =		1,
544	.periods_max =		1024,
545	.fifo_size =		0,
546};
547
548/*
549
550 */
551
552static int snd_es1688_playback_open(struct snd_pcm_substream *substream)
553{
554	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
555	struct snd_pcm_runtime *runtime = substream->runtime;
556
557	if (chip->capture_substream != NULL)
558		return -EAGAIN;
559	chip->playback_substream = substream;
560	runtime->hw = snd_es1688_playback;
561	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
562				      &hw_constraints_clocks);
563	return 0;
564}
565
566static int snd_es1688_capture_open(struct snd_pcm_substream *substream)
567{
568	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
569	struct snd_pcm_runtime *runtime = substream->runtime;
570
571	if (chip->playback_substream != NULL)
572		return -EAGAIN;
573	chip->capture_substream = substream;
574	runtime->hw = snd_es1688_capture;
575	snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
576				      &hw_constraints_clocks);
577	return 0;
578}
579
580static int snd_es1688_playback_close(struct snd_pcm_substream *substream)
581{
582	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
583
584	chip->playback_substream = NULL;
585	return 0;
586}
587
588static int snd_es1688_capture_close(struct snd_pcm_substream *substream)
589{
590	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
591
592	chip->capture_substream = NULL;
593	return 0;
594}
595
596static int snd_es1688_free(struct snd_es1688 *chip)
597{
598	if (chip->res_port) {
599		snd_es1688_init(chip, 0);
600		release_and_free_resource(chip->res_port);
601	}
602	if (chip->irq >= 0)
603		free_irq(chip->irq, (void *) chip);
604	if (chip->dma8 >= 0) {
605		disable_dma(chip->dma8);
606		free_dma(chip->dma8);
607	}
608	return 0;
609}
610
611static int snd_es1688_dev_free(struct snd_device *device)
612{
613	struct snd_es1688 *chip = device->device_data;
614	return snd_es1688_free(chip);
615}
616
617static const char *snd_es1688_chip_id(struct snd_es1688 *chip)
618{
619	static char tmp[16];
620	sprintf(tmp, "ES%s688 rev %i", chip->hardware == ES1688_HW_688 ? "" : "1", chip->version & 0x0f);
621	return tmp;
622}
623
624int snd_es1688_create(struct snd_card *card,
625		      struct snd_es1688 *chip,
626		      unsigned long port,
627		      unsigned long mpu_port,
628		      int irq,
629		      int mpu_irq,
630		      int dma8,
631		      unsigned short hardware)
632{
633	static struct snd_device_ops ops = {
634		.dev_free =	snd_es1688_dev_free,
635	};
636
637	int err;
638
639	if (chip == NULL)
640		return -ENOMEM;
641	chip->irq = -1;
642	chip->dma8 = -1;
643
644	if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) {
645		snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
646		return -EBUSY;
647	}
648	if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) {
649		snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
650		return -EBUSY;
651	}
652	chip->irq = irq;
653	if (request_dma(dma8, "ES1688")) {
654		snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);
655		return -EBUSY;
656	}
657	chip->dma8 = dma8;
658
659	spin_lock_init(&chip->reg_lock);
660	spin_lock_init(&chip->mixer_lock);
661	chip->port = port;
662	mpu_port &= ~0x000f;
663	if (mpu_port < 0x300 || mpu_port > 0x330)
664		mpu_port = 0;
665	chip->mpu_port = mpu_port;
666	chip->mpu_irq = mpu_irq;
667	chip->hardware = hardware;
668
669	err = snd_es1688_probe(chip);
670	if (err < 0)
671		return err;
672
673	err = snd_es1688_init(chip, 1);
674	if (err < 0)
675		return err;
676
677	/* Register device */
678	return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
679}
680
681static struct snd_pcm_ops snd_es1688_playback_ops = {
682	.open =			snd_es1688_playback_open,
683	.close =		snd_es1688_playback_close,
684	.ioctl =		snd_es1688_ioctl,
685	.hw_params =		snd_es1688_hw_params,
686	.hw_free =		snd_es1688_hw_free,
687	.prepare =		snd_es1688_playback_prepare,
688	.trigger =		snd_es1688_playback_trigger,
689	.pointer =		snd_es1688_playback_pointer,
690};
691
692static struct snd_pcm_ops snd_es1688_capture_ops = {
693	.open =			snd_es1688_capture_open,
694	.close =		snd_es1688_capture_close,
695	.ioctl =		snd_es1688_ioctl,
696	.hw_params =		snd_es1688_hw_params,
697	.hw_free =		snd_es1688_hw_free,
698	.prepare =		snd_es1688_capture_prepare,
699	.trigger =		snd_es1688_capture_trigger,
700	.pointer =		snd_es1688_capture_pointer,
701};
702
703int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip,
704		   int device, struct snd_pcm **rpcm)
705{
706	struct snd_pcm *pcm;
707	int err;
708
709	err = snd_pcm_new(card, "ESx688", device, 1, 1, &pcm);
710	if (err < 0)
711		return err;
712
713	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops);
714	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1688_capture_ops);
715
716	pcm->private_data = chip;
717	pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
718	sprintf(pcm->name, snd_es1688_chip_id(chip));
719	chip->pcm = pcm;
720
721	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
722					      snd_dma_isa_data(),
723					      64*1024, 64*1024);
724
725	if (rpcm)
726		*rpcm = pcm;
727	return 0;
728}
729
730/*
731 *  MIXER part
732 */
733
734static int snd_es1688_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
735{
736	static char *texts[9] = {
737		"Mic", "Mic Master", "CD", "AOUT",
738		"Mic1", "Mix", "Line", "Master"
739	};
740
741	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
742	uinfo->count = 1;
743	uinfo->value.enumerated.items = 8;
744	if (uinfo->value.enumerated.item > 7)
745		uinfo->value.enumerated.item = 7;
746	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
747	return 0;
748}
749
750static int snd_es1688_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
751{
752	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
753	ucontrol->value.enumerated.item[0] = snd_es1688_mixer_read(chip, ES1688_REC_DEV) & 7;
754	return 0;
755}
756
757static int snd_es1688_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
758{
759	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
760	unsigned long flags;
761	unsigned char oval, nval;
762	int change;
763
764	if (ucontrol->value.enumerated.item[0] > 8)
765		return -EINVAL;
766	spin_lock_irqsave(&chip->reg_lock, flags);
767	oval = snd_es1688_mixer_read(chip, ES1688_REC_DEV);
768	nval = (ucontrol->value.enumerated.item[0] & 7) | (oval & ~15);
769	change = nval != oval;
770	if (change)
771		snd_es1688_mixer_write(chip, ES1688_REC_DEV, nval);
772	spin_unlock_irqrestore(&chip->reg_lock, flags);
773	return change;
774}
775
776#define ES1688_SINGLE(xname, xindex, reg, shift, mask, invert) \
777{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
778  .info = snd_es1688_info_single, \
779  .get = snd_es1688_get_single, .put = snd_es1688_put_single, \
780  .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
781
782static int snd_es1688_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
783{
784	int mask = (kcontrol->private_value >> 16) & 0xff;
785
786	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
787	uinfo->count = 1;
788	uinfo->value.integer.min = 0;
789	uinfo->value.integer.max = mask;
790	return 0;
791}
792
793static int snd_es1688_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
794{
795	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
796	unsigned long flags;
797	int reg = kcontrol->private_value & 0xff;
798	int shift = (kcontrol->private_value >> 8) & 0xff;
799	int mask = (kcontrol->private_value >> 16) & 0xff;
800	int invert = (kcontrol->private_value >> 24) & 0xff;
801
802	spin_lock_irqsave(&chip->reg_lock, flags);
803	ucontrol->value.integer.value[0] = (snd_es1688_mixer_read(chip, reg) >> shift) & mask;
804	spin_unlock_irqrestore(&chip->reg_lock, flags);
805	if (invert)
806		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
807	return 0;
808}
809
810static int snd_es1688_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
811{
812	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
813	unsigned long flags;
814	int reg = kcontrol->private_value & 0xff;
815	int shift = (kcontrol->private_value >> 8) & 0xff;
816	int mask = (kcontrol->private_value >> 16) & 0xff;
817	int invert = (kcontrol->private_value >> 24) & 0xff;
818	int change;
819	unsigned char oval, nval;
820
821	nval = (ucontrol->value.integer.value[0] & mask);
822	if (invert)
823		nval = mask - nval;
824	nval <<= shift;
825	spin_lock_irqsave(&chip->reg_lock, flags);
826	oval = snd_es1688_mixer_read(chip, reg);
827	nval = (oval & ~(mask << shift)) | nval;
828	change = nval != oval;
829	if (change)
830		snd_es1688_mixer_write(chip, reg, nval);
831	spin_unlock_irqrestore(&chip->reg_lock, flags);
832	return change;
833}
834
835#define ES1688_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
836{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
837  .info = snd_es1688_info_double, \
838  .get = snd_es1688_get_double, .put = snd_es1688_put_double, \
839  .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
840
841static int snd_es1688_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
842{
843	int mask = (kcontrol->private_value >> 24) & 0xff;
844
845	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
846	uinfo->count = 2;
847	uinfo->value.integer.min = 0;
848	uinfo->value.integer.max = mask;
849	return 0;
850}
851
852static int snd_es1688_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
853{
854	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
855	unsigned long flags;
856	int left_reg = kcontrol->private_value & 0xff;
857	int right_reg = (kcontrol->private_value >> 8) & 0xff;
858	int shift_left = (kcontrol->private_value >> 16) & 0x07;
859	int shift_right = (kcontrol->private_value >> 19) & 0x07;
860	int mask = (kcontrol->private_value >> 24) & 0xff;
861	int invert = (kcontrol->private_value >> 22) & 1;
862	unsigned char left, right;
863
864	spin_lock_irqsave(&chip->reg_lock, flags);
865	if (left_reg < 0xa0)
866		left = snd_es1688_mixer_read(chip, left_reg);
867	else
868		left = snd_es1688_read(chip, left_reg);
869	if (left_reg != right_reg) {
870		if (right_reg < 0xa0)
871			right = snd_es1688_mixer_read(chip, right_reg);
872		else
873			right = snd_es1688_read(chip, right_reg);
874	} else
875		right = left;
876	spin_unlock_irqrestore(&chip->reg_lock, flags);
877	ucontrol->value.integer.value[0] = (left >> shift_left) & mask;
878	ucontrol->value.integer.value[1] = (right >> shift_right) & mask;
879	if (invert) {
880		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
881		ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
882	}
883	return 0;
884}
885
886static int snd_es1688_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
887{
888	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
889	unsigned long flags;
890	int left_reg = kcontrol->private_value & 0xff;
891	int right_reg = (kcontrol->private_value >> 8) & 0xff;
892	int shift_left = (kcontrol->private_value >> 16) & 0x07;
893	int shift_right = (kcontrol->private_value >> 19) & 0x07;
894	int mask = (kcontrol->private_value >> 24) & 0xff;
895	int invert = (kcontrol->private_value >> 22) & 1;
896	int change;
897	unsigned char val1, val2, oval1, oval2;
898
899	val1 = ucontrol->value.integer.value[0] & mask;
900	val2 = ucontrol->value.integer.value[1] & mask;
901	if (invert) {
902		val1 = mask - val1;
903		val2 = mask - val2;
904	}
905	val1 <<= shift_left;
906	val2 <<= shift_right;
907	spin_lock_irqsave(&chip->reg_lock, flags);
908	if (left_reg != right_reg) {
909		if (left_reg < 0xa0)
910			oval1 = snd_es1688_mixer_read(chip, left_reg);
911		else
912			oval1 = snd_es1688_read(chip, left_reg);
913		if (right_reg < 0xa0)
914			oval2 = snd_es1688_mixer_read(chip, right_reg);
915		else
916			oval2 = snd_es1688_read(chip, right_reg);
917		val1 = (oval1 & ~(mask << shift_left)) | val1;
918		val2 = (oval2 & ~(mask << shift_right)) | val2;
919		change = val1 != oval1 || val2 != oval2;
920		if (change) {
921			if (left_reg < 0xa0)
922				snd_es1688_mixer_write(chip, left_reg, val1);
923			else
924				snd_es1688_write(chip, left_reg, val1);
925			if (right_reg < 0xa0)
926				snd_es1688_mixer_write(chip, right_reg, val1);
927			else
928				snd_es1688_write(chip, right_reg, val1);
929		}
930	} else {
931		if (left_reg < 0xa0)
932			oval1 = snd_es1688_mixer_read(chip, left_reg);
933		else
934			oval1 = snd_es1688_read(chip, left_reg);
935		val1 = (oval1 & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2;
936		change = val1 != oval1;
937		if (change) {
938			if (left_reg < 0xa0)
939				snd_es1688_mixer_write(chip, left_reg, val1);
940			else
941				snd_es1688_write(chip, left_reg, val1);
942		}
943
944	}
945	spin_unlock_irqrestore(&chip->reg_lock, flags);
946	return change;
947}
948
949static struct snd_kcontrol_new snd_es1688_controls[] = {
950ES1688_DOUBLE("Master Playback Volume", 0, ES1688_MASTER_DEV, ES1688_MASTER_DEV, 4, 0, 15, 0),
951ES1688_DOUBLE("PCM Playback Volume", 0, ES1688_PCM_DEV, ES1688_PCM_DEV, 4, 0, 15, 0),
952ES1688_DOUBLE("Line Playback Volume", 0, ES1688_LINE_DEV, ES1688_LINE_DEV, 4, 0, 15, 0),
953ES1688_DOUBLE("CD Playback Volume", 0, ES1688_CD_DEV, ES1688_CD_DEV, 4, 0, 15, 0),
954ES1688_DOUBLE("FM Playback Volume", 0, ES1688_FM_DEV, ES1688_FM_DEV, 4, 0, 15, 0),
955ES1688_DOUBLE("Mic Playback Volume", 0, ES1688_MIC_DEV, ES1688_MIC_DEV, 4, 0, 15, 0),
956ES1688_DOUBLE("Aux Playback Volume", 0, ES1688_AUX_DEV, ES1688_AUX_DEV, 4, 0, 15, 0),
957ES1688_SINGLE("Beep Playback Volume", 0, ES1688_SPEAKER_DEV, 0, 7, 0),
958ES1688_DOUBLE("Capture Volume", 0, ES1688_RECLEV_DEV, ES1688_RECLEV_DEV, 4, 0, 15, 0),
959ES1688_SINGLE("Capture Switch", 0, ES1688_REC_DEV, 4, 1, 1),
960{
961	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
962	.name = "Capture Source",
963	.info = snd_es1688_info_mux,
964	.get = snd_es1688_get_mux,
965	.put = snd_es1688_put_mux,
966},
967};
968
969#define ES1688_INIT_TABLE_SIZE (sizeof(snd_es1688_init_table)/2)
970
971static unsigned char snd_es1688_init_table[][2] = {
972	{ ES1688_MASTER_DEV, 0 },
973	{ ES1688_PCM_DEV, 0 },
974	{ ES1688_LINE_DEV, 0 },
975	{ ES1688_CD_DEV, 0 },
976	{ ES1688_FM_DEV, 0 },
977	{ ES1688_MIC_DEV, 0 },
978	{ ES1688_AUX_DEV, 0 },
979	{ ES1688_SPEAKER_DEV, 0 },
980	{ ES1688_RECLEV_DEV, 0 },
981	{ ES1688_REC_DEV, 0x17 }
982};
983
984int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip)
985{
986	unsigned int idx;
987	int err;
988	unsigned char reg, val;
989
990	if (snd_BUG_ON(!chip || !card))
991		return -EINVAL;
992
993	strcpy(card->mixername, snd_es1688_chip_id(chip));
994
995	for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) {
996		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_es1688_controls[idx], chip))) < 0)
997			return err;
998	}
999	for (idx = 0; idx < ES1688_INIT_TABLE_SIZE; idx++) {
1000		reg = snd_es1688_init_table[idx][0];
1001		val = snd_es1688_init_table[idx][1];
1002		if (reg < 0xa0)
1003			snd_es1688_mixer_write(chip, reg, val);
1004		else
1005			snd_es1688_write(chip, reg, val);
1006	}
1007	return 0;
1008}
1009
1010EXPORT_SYMBOL(snd_es1688_mixer_write);
1011EXPORT_SYMBOL(snd_es1688_create);
1012EXPORT_SYMBOL(snd_es1688_pcm);
1013EXPORT_SYMBOL(snd_es1688_mixer);
1014
1015/*
1016 *  INIT part
1017 */
1018
1019static int __init alsa_es1688_init(void)
1020{
1021	return 0;
1022}
1023
1024static void __exit alsa_es1688_exit(void)
1025{
1026}
1027
1028module_init(alsa_es1688_init)
1029module_exit(alsa_es1688_exit)
1030