1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <linux/delay.h>
28#include <linux/pm.h>
29#include <linux/init.h>
30#include <linux/interrupt.h>
31#include <linux/slab.h>
32#include <linux/ioport.h>
33#include <linux/module.h>
34#include <linux/io.h>
35#include <sound/core.h>
36#include <sound/wss.h>
37#include <sound/pcm_params.h>
38#include <sound/tlv.h>
39
40#include <asm/dma.h>
41#include <asm/irq.h>
42
43MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
44MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
45MODULE_LICENSE("GPL");
46
47#if 0
48#define SNDRV_DEBUG_MCE
49#endif
50
51
52
53
54
55static unsigned char freq_bits[14] = {
56 0x00 | CS4231_XTAL2,
57 0x0E | CS4231_XTAL2,
58 0x00 | CS4231_XTAL1,
59 0x0E | CS4231_XTAL1,
60 0x02 | CS4231_XTAL2,
61 0x02 | CS4231_XTAL1,
62 0x04 | CS4231_XTAL2,
63 0x06 | CS4231_XTAL2,
64 0x04 | CS4231_XTAL1,
65 0x06 | CS4231_XTAL1,
66 0x0C | CS4231_XTAL2,
67 0x08 | CS4231_XTAL2,
68 0x0A | CS4231_XTAL2,
69 0x0C | CS4231_XTAL1
70};
71
72static unsigned int rates[14] = {
73 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
74 27042, 32000, 33075, 37800, 44100, 48000
75};
76
77static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
78 .count = ARRAY_SIZE(rates),
79 .list = rates,
80 .mask = 0,
81};
82
83static int snd_wss_xrate(struct snd_pcm_runtime *runtime)
84{
85 return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
86 &hw_constraints_rates);
87}
88
89static unsigned char snd_wss_original_image[32] =
90{
91 0x00,
92 0x00,
93 0x9f,
94 0x9f,
95 0x9f,
96 0x9f,
97 0xbf,
98 0xbf,
99 0x20,
100 CS4231_AUTOCALIB,
101 0x00,
102 0x00,
103 CS4231_MODE2,
104 0xfc,
105 0x00,
106 0x00,
107 0x80,
108 0x01,
109 0x9f,
110 0x9f,
111 0x00,
112 0x00,
113 0x00,
114 0x00,
115 0x00,
116 0x00,
117 0xcf,
118 0x00,
119 0x20,
120 0x00,
121 0x00,
122 0x00,
123};
124
125static unsigned char snd_opti93x_original_image[32] =
126{
127 0x00,
128 0x00,
129 0x88,
130 0x88,
131 0x88,
132 0x88,
133 0x80,
134 0x80,
135 0x00,
136 0x00,
137 0x00,
138 0x00,
139 0x0a,
140 0x00,
141 0x00,
142 0x00,
143 0x88,
144 0x88,
145 0x88,
146 0x88,
147 0x88,
148 0x88,
149 0x80,
150 0x80,
151 0x00,
152 0x00,
153 0x00,
154 0x00,
155 0x00,
156 0x00,
157 0x00,
158 0x00
159};
160
161
162
163
164
165static inline void wss_outb(struct snd_wss *chip, u8 offset, u8 val)
166{
167 outb(val, chip->port + offset);
168}
169
170static inline u8 wss_inb(struct snd_wss *chip, u8 offset)
171{
172 return inb(chip->port + offset);
173}
174
175static void snd_wss_wait(struct snd_wss *chip)
176{
177 int timeout;
178
179 for (timeout = 250;
180 timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
181 timeout--)
182 udelay(100);
183}
184
185static void snd_wss_dout(struct snd_wss *chip, unsigned char reg,
186 unsigned char value)
187{
188 int timeout;
189
190 for (timeout = 250;
191 timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
192 timeout--)
193 udelay(10);
194 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
195 wss_outb(chip, CS4231P(REG), value);
196 mb();
197}
198
199void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char value)
200{
201 snd_wss_wait(chip);
202#ifdef CONFIG_SND_DEBUG
203 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
204 snd_printk(KERN_DEBUG "out: auto calibration time out "
205 "- reg = 0x%x, value = 0x%x\n", reg, value);
206#endif
207 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
208 wss_outb(chip, CS4231P(REG), value);
209 chip->image[reg] = value;
210 mb();
211 snd_printdd("codec out - reg 0x%x = 0x%x\n",
212 chip->mce_bit | reg, value);
213}
214EXPORT_SYMBOL(snd_wss_out);
215
216unsigned char snd_wss_in(struct snd_wss *chip, unsigned char reg)
217{
218 snd_wss_wait(chip);
219#ifdef CONFIG_SND_DEBUG
220 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
221 snd_printk(KERN_DEBUG "in: auto calibration time out "
222 "- reg = 0x%x\n", reg);
223#endif
224 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
225 mb();
226 return wss_inb(chip, CS4231P(REG));
227}
228EXPORT_SYMBOL(snd_wss_in);
229
230void snd_cs4236_ext_out(struct snd_wss *chip, unsigned char reg,
231 unsigned char val)
232{
233 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
234 wss_outb(chip, CS4231P(REG),
235 reg | (chip->image[CS4236_EXT_REG] & 0x01));
236 wss_outb(chip, CS4231P(REG), val);
237 chip->eimage[CS4236_REG(reg)] = val;
238#if 0
239 printk(KERN_DEBUG "ext out : reg = 0x%x, val = 0x%x\n", reg, val);
240#endif
241}
242EXPORT_SYMBOL(snd_cs4236_ext_out);
243
244unsigned char snd_cs4236_ext_in(struct snd_wss *chip, unsigned char reg)
245{
246 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
247 wss_outb(chip, CS4231P(REG),
248 reg | (chip->image[CS4236_EXT_REG] & 0x01));
249#if 1
250 return wss_inb(chip, CS4231P(REG));
251#else
252 {
253 unsigned char res;
254 res = wss_inb(chip, CS4231P(REG));
255 printk(KERN_DEBUG "ext in : reg = 0x%x, val = 0x%x\n",
256 reg, res);
257 return res;
258 }
259#endif
260}
261EXPORT_SYMBOL(snd_cs4236_ext_in);
262
263#if 0
264
265static void snd_wss_debug(struct snd_wss *chip)
266{
267 printk(KERN_DEBUG
268 "CS4231 REGS: INDEX = 0x%02x "
269 " STATUS = 0x%02x\n",
270 wss_inb(chip, CS4231P(REGSEL)),
271 wss_inb(chip, CS4231P(STATUS)));
272 printk(KERN_DEBUG
273 " 0x00: left input = 0x%02x "
274 " 0x10: alt 1 (CFIG 2) = 0x%02x\n",
275 snd_wss_in(chip, 0x00),
276 snd_wss_in(chip, 0x10));
277 printk(KERN_DEBUG
278 " 0x01: right input = 0x%02x "
279 " 0x11: alt 2 (CFIG 3) = 0x%02x\n",
280 snd_wss_in(chip, 0x01),
281 snd_wss_in(chip, 0x11));
282 printk(KERN_DEBUG
283 " 0x02: GF1 left input = 0x%02x "
284 " 0x12: left line in = 0x%02x\n",
285 snd_wss_in(chip, 0x02),
286 snd_wss_in(chip, 0x12));
287 printk(KERN_DEBUG
288 " 0x03: GF1 right input = 0x%02x "
289 " 0x13: right line in = 0x%02x\n",
290 snd_wss_in(chip, 0x03),
291 snd_wss_in(chip, 0x13));
292 printk(KERN_DEBUG
293 " 0x04: CD left input = 0x%02x "
294 " 0x14: timer low = 0x%02x\n",
295 snd_wss_in(chip, 0x04),
296 snd_wss_in(chip, 0x14));
297 printk(KERN_DEBUG
298 " 0x05: CD right input = 0x%02x "
299 " 0x15: timer high = 0x%02x\n",
300 snd_wss_in(chip, 0x05),
301 snd_wss_in(chip, 0x15));
302 printk(KERN_DEBUG
303 " 0x06: left output = 0x%02x "
304 " 0x16: left MIC (PnP) = 0x%02x\n",
305 snd_wss_in(chip, 0x06),
306 snd_wss_in(chip, 0x16));
307 printk(KERN_DEBUG
308 " 0x07: right output = 0x%02x "
309 " 0x17: right MIC (PnP) = 0x%02x\n",
310 snd_wss_in(chip, 0x07),
311 snd_wss_in(chip, 0x17));
312 printk(KERN_DEBUG
313 " 0x08: playback format = 0x%02x "
314 " 0x18: IRQ status = 0x%02x\n",
315 snd_wss_in(chip, 0x08),
316 snd_wss_in(chip, 0x18));
317 printk(KERN_DEBUG
318 " 0x09: iface (CFIG 1) = 0x%02x "
319 " 0x19: left line out = 0x%02x\n",
320 snd_wss_in(chip, 0x09),
321 snd_wss_in(chip, 0x19));
322 printk(KERN_DEBUG
323 " 0x0a: pin control = 0x%02x "
324 " 0x1a: mono control = 0x%02x\n",
325 snd_wss_in(chip, 0x0a),
326 snd_wss_in(chip, 0x1a));
327 printk(KERN_DEBUG
328 " 0x0b: init & status = 0x%02x "
329 " 0x1b: right line out = 0x%02x\n",
330 snd_wss_in(chip, 0x0b),
331 snd_wss_in(chip, 0x1b));
332 printk(KERN_DEBUG
333 " 0x0c: revision & mode = 0x%02x "
334 " 0x1c: record format = 0x%02x\n",
335 snd_wss_in(chip, 0x0c),
336 snd_wss_in(chip, 0x1c));
337 printk(KERN_DEBUG
338 " 0x0d: loopback = 0x%02x "
339 " 0x1d: var freq (PnP) = 0x%02x\n",
340 snd_wss_in(chip, 0x0d),
341 snd_wss_in(chip, 0x1d));
342 printk(KERN_DEBUG
343 " 0x0e: ply upr count = 0x%02x "
344 " 0x1e: ply lwr count = 0x%02x\n",
345 snd_wss_in(chip, 0x0e),
346 snd_wss_in(chip, 0x1e));
347 printk(KERN_DEBUG
348 " 0x0f: rec upr count = 0x%02x "
349 " 0x1f: rec lwr count = 0x%02x\n",
350 snd_wss_in(chip, 0x0f),
351 snd_wss_in(chip, 0x1f));
352}
353
354#endif
355
356
357
358
359
360static void snd_wss_busy_wait(struct snd_wss *chip)
361{
362 int timeout;
363
364
365 for (timeout = 5; timeout > 0; timeout--)
366 wss_inb(chip, CS4231P(REGSEL));
367
368 for (timeout = 25000;
369 timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
370 timeout--)
371 udelay(10);
372}
373
374void snd_wss_mce_up(struct snd_wss *chip)
375{
376 unsigned long flags;
377 int timeout;
378
379 snd_wss_wait(chip);
380#ifdef CONFIG_SND_DEBUG
381 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
382 snd_printk(KERN_DEBUG
383 "mce_up - auto calibration time out (0)\n");
384#endif
385 spin_lock_irqsave(&chip->reg_lock, flags);
386 chip->mce_bit |= CS4231_MCE;
387 timeout = wss_inb(chip, CS4231P(REGSEL));
388 if (timeout == 0x80)
389 snd_printk(KERN_DEBUG "mce_up [0x%lx]: "
390 "serious init problem - codec still busy\n",
391 chip->port);
392 if (!(timeout & CS4231_MCE))
393 wss_outb(chip, CS4231P(REGSEL),
394 chip->mce_bit | (timeout & 0x1f));
395 spin_unlock_irqrestore(&chip->reg_lock, flags);
396}
397EXPORT_SYMBOL(snd_wss_mce_up);
398
399void snd_wss_mce_down(struct snd_wss *chip)
400{
401 unsigned long flags;
402 unsigned long end_time;
403 int timeout;
404 int hw_mask = WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK | WSS_HW_AD1848;
405
406 snd_wss_busy_wait(chip);
407
408#ifdef CONFIG_SND_DEBUG
409 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
410 snd_printk(KERN_DEBUG "mce_down [0x%lx] - "
411 "auto calibration time out (0)\n",
412 (long)CS4231P(REGSEL));
413#endif
414 spin_lock_irqsave(&chip->reg_lock, flags);
415 chip->mce_bit &= ~CS4231_MCE;
416 timeout = wss_inb(chip, CS4231P(REGSEL));
417 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
418 spin_unlock_irqrestore(&chip->reg_lock, flags);
419 if (timeout == 0x80)
420 snd_printk(KERN_DEBUG "mce_down [0x%lx]: "
421 "serious init problem - codec still busy\n",
422 chip->port);
423 if ((timeout & CS4231_MCE) == 0 || !(chip->hardware & hw_mask))
424 return;
425
426
427
428
429
430
431 msleep(1);
432
433 snd_printdd("(1) jiffies = %lu\n", jiffies);
434
435
436 end_time = jiffies + msecs_to_jiffies(250);
437 while (snd_wss_in(chip, CS4231_TEST_INIT) &
438 CS4231_CALIB_IN_PROGRESS) {
439
440 if (time_after(jiffies, end_time)) {
441 snd_printk(KERN_ERR "mce_down - "
442 "auto calibration time out (2)\n");
443 return;
444 }
445 msleep(1);
446 }
447
448 snd_printdd("(2) jiffies = %lu\n", jiffies);
449
450
451 end_time = jiffies + msecs_to_jiffies(100);
452 while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
453 if (time_after(jiffies, end_time)) {
454 snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
455 return;
456 }
457 msleep(1);
458 }
459
460 snd_printdd("(3) jiffies = %lu\n", jiffies);
461 snd_printd("mce_down - exit = 0x%x\n", wss_inb(chip, CS4231P(REGSEL)));
462}
463EXPORT_SYMBOL(snd_wss_mce_down);
464
465static unsigned int snd_wss_get_count(unsigned char format, unsigned int size)
466{
467 switch (format & 0xe0) {
468 case CS4231_LINEAR_16:
469 case CS4231_LINEAR_16_BIG:
470 size >>= 1;
471 break;
472 case CS4231_ADPCM_16:
473 return size >> 2;
474 }
475 if (format & CS4231_STEREO)
476 size >>= 1;
477 return size;
478}
479
480static int snd_wss_trigger(struct snd_pcm_substream *substream,
481 int cmd)
482{
483 struct snd_wss *chip = snd_pcm_substream_chip(substream);
484 int result = 0;
485 unsigned int what;
486 struct snd_pcm_substream *s;
487 int do_start;
488
489 switch (cmd) {
490 case SNDRV_PCM_TRIGGER_START:
491 case SNDRV_PCM_TRIGGER_RESUME:
492 do_start = 1; break;
493 case SNDRV_PCM_TRIGGER_STOP:
494 case SNDRV_PCM_TRIGGER_SUSPEND:
495 do_start = 0; break;
496 default:
497 return -EINVAL;
498 }
499
500 what = 0;
501 snd_pcm_group_for_each_entry(s, substream) {
502 if (s == chip->playback_substream) {
503 what |= CS4231_PLAYBACK_ENABLE;
504 snd_pcm_trigger_done(s, substream);
505 } else if (s == chip->capture_substream) {
506 what |= CS4231_RECORD_ENABLE;
507 snd_pcm_trigger_done(s, substream);
508 }
509 }
510 spin_lock(&chip->reg_lock);
511 if (do_start) {
512 chip->image[CS4231_IFACE_CTRL] |= what;
513 if (chip->trigger)
514 chip->trigger(chip, what, 1);
515 } else {
516 chip->image[CS4231_IFACE_CTRL] &= ~what;
517 if (chip->trigger)
518 chip->trigger(chip, what, 0);
519 }
520 snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
521 spin_unlock(&chip->reg_lock);
522#if 0
523 snd_wss_debug(chip);
524#endif
525 return result;
526}
527
528
529
530
531
532static unsigned char snd_wss_get_rate(unsigned int rate)
533{
534 int i;
535
536 for (i = 0; i < ARRAY_SIZE(rates); i++)
537 if (rate == rates[i])
538 return freq_bits[i];
539
540 return freq_bits[ARRAY_SIZE(rates) - 1];
541}
542
543static unsigned char snd_wss_get_format(struct snd_wss *chip,
544 int format,
545 int channels)
546{
547 unsigned char rformat;
548
549 rformat = CS4231_LINEAR_8;
550 switch (format) {
551 case SNDRV_PCM_FORMAT_MU_LAW: rformat = CS4231_ULAW_8; break;
552 case SNDRV_PCM_FORMAT_A_LAW: rformat = CS4231_ALAW_8; break;
553 case SNDRV_PCM_FORMAT_S16_LE: rformat = CS4231_LINEAR_16; break;
554 case SNDRV_PCM_FORMAT_S16_BE: rformat = CS4231_LINEAR_16_BIG; break;
555 case SNDRV_PCM_FORMAT_IMA_ADPCM: rformat = CS4231_ADPCM_16; break;
556 }
557 if (channels > 1)
558 rformat |= CS4231_STEREO;
559#if 0
560 snd_printk(KERN_DEBUG "get_format: 0x%x (mode=0x%x)\n", format, mode);
561#endif
562 return rformat;
563}
564
565static void snd_wss_calibrate_mute(struct snd_wss *chip, int mute)
566{
567 unsigned long flags;
568
569 mute = mute ? 0x80 : 0;
570 spin_lock_irqsave(&chip->reg_lock, flags);
571 if (chip->calibrate_mute == mute) {
572 spin_unlock_irqrestore(&chip->reg_lock, flags);
573 return;
574 }
575 if (!mute) {
576 snd_wss_dout(chip, CS4231_LEFT_INPUT,
577 chip->image[CS4231_LEFT_INPUT]);
578 snd_wss_dout(chip, CS4231_RIGHT_INPUT,
579 chip->image[CS4231_RIGHT_INPUT]);
580 snd_wss_dout(chip, CS4231_LOOPBACK,
581 chip->image[CS4231_LOOPBACK]);
582 } else {
583 snd_wss_dout(chip, CS4231_LEFT_INPUT,
584 0);
585 snd_wss_dout(chip, CS4231_RIGHT_INPUT,
586 0);
587 snd_wss_dout(chip, CS4231_LOOPBACK,
588 0xfd);
589 }
590
591 snd_wss_dout(chip, CS4231_AUX1_LEFT_INPUT,
592 mute | chip->image[CS4231_AUX1_LEFT_INPUT]);
593 snd_wss_dout(chip, CS4231_AUX1_RIGHT_INPUT,
594 mute | chip->image[CS4231_AUX1_RIGHT_INPUT]);
595 snd_wss_dout(chip, CS4231_AUX2_LEFT_INPUT,
596 mute | chip->image[CS4231_AUX2_LEFT_INPUT]);
597 snd_wss_dout(chip, CS4231_AUX2_RIGHT_INPUT,
598 mute | chip->image[CS4231_AUX2_RIGHT_INPUT]);
599 snd_wss_dout(chip, CS4231_LEFT_OUTPUT,
600 mute | chip->image[CS4231_LEFT_OUTPUT]);
601 snd_wss_dout(chip, CS4231_RIGHT_OUTPUT,
602 mute | chip->image[CS4231_RIGHT_OUTPUT]);
603 if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
604 snd_wss_dout(chip, CS4231_LEFT_LINE_IN,
605 mute | chip->image[CS4231_LEFT_LINE_IN]);
606 snd_wss_dout(chip, CS4231_RIGHT_LINE_IN,
607 mute | chip->image[CS4231_RIGHT_LINE_IN]);
608 snd_wss_dout(chip, CS4231_MONO_CTRL,
609 mute ? 0xc0 : chip->image[CS4231_MONO_CTRL]);
610 }
611 if (chip->hardware == WSS_HW_INTERWAVE) {
612 snd_wss_dout(chip, CS4231_LEFT_MIC_INPUT,
613 mute | chip->image[CS4231_LEFT_MIC_INPUT]);
614 snd_wss_dout(chip, CS4231_RIGHT_MIC_INPUT,
615 mute | chip->image[CS4231_RIGHT_MIC_INPUT]);
616 snd_wss_dout(chip, CS4231_LINE_LEFT_OUTPUT,
617 mute | chip->image[CS4231_LINE_LEFT_OUTPUT]);
618 snd_wss_dout(chip, CS4231_LINE_RIGHT_OUTPUT,
619 mute | chip->image[CS4231_LINE_RIGHT_OUTPUT]);
620 }
621 chip->calibrate_mute = mute;
622 spin_unlock_irqrestore(&chip->reg_lock, flags);
623}
624
625static void snd_wss_playback_format(struct snd_wss *chip,
626 struct snd_pcm_hw_params *params,
627 unsigned char pdfr)
628{
629 unsigned long flags;
630 int full_calib = 1;
631
632 mutex_lock(&chip->mce_mutex);
633 if (chip->hardware == WSS_HW_CS4231A ||
634 (chip->hardware & WSS_HW_CS4232_MASK)) {
635 spin_lock_irqsave(&chip->reg_lock, flags);
636 if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (pdfr & 0x0f)) {
637 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
638 chip->image[CS4231_ALT_FEATURE_1] | 0x10);
639 chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
640 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
641 chip->image[CS4231_PLAYBK_FORMAT]);
642 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
643 chip->image[CS4231_ALT_FEATURE_1] &= ~0x10);
644 udelay(100);
645 full_calib = 0;
646 }
647 spin_unlock_irqrestore(&chip->reg_lock, flags);
648 } else if (chip->hardware == WSS_HW_AD1845) {
649 unsigned rate = params_rate(params);
650
651
652
653
654
655
656
657
658
659
660 spin_lock_irqsave(&chip->reg_lock, flags);
661 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, (pdfr & 0xf0));
662 snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
663 snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
664 full_calib = 0;
665 spin_unlock_irqrestore(&chip->reg_lock, flags);
666 }
667 if (full_calib) {
668 snd_wss_mce_up(chip);
669 spin_lock_irqsave(&chip->reg_lock, flags);
670 if (chip->hardware != WSS_HW_INTERWAVE && !chip->single_dma) {
671 if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE)
672 pdfr = (pdfr & 0xf0) |
673 (chip->image[CS4231_REC_FORMAT] & 0x0f);
674 } else {
675 chip->image[CS4231_PLAYBK_FORMAT] = pdfr;
676 }
677 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, pdfr);
678 spin_unlock_irqrestore(&chip->reg_lock, flags);
679 if (chip->hardware == WSS_HW_OPL3SA2)
680 udelay(100);
681 snd_wss_mce_down(chip);
682 }
683 mutex_unlock(&chip->mce_mutex);
684}
685
686static void snd_wss_capture_format(struct snd_wss *chip,
687 struct snd_pcm_hw_params *params,
688 unsigned char cdfr)
689{
690 unsigned long flags;
691 int full_calib = 1;
692
693 mutex_lock(&chip->mce_mutex);
694 if (chip->hardware == WSS_HW_CS4231A ||
695 (chip->hardware & WSS_HW_CS4232_MASK)) {
696 spin_lock_irqsave(&chip->reg_lock, flags);
697 if ((chip->image[CS4231_PLAYBK_FORMAT] & 0x0f) == (cdfr & 0x0f) ||
698 (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
699 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
700 chip->image[CS4231_ALT_FEATURE_1] | 0x20);
701 snd_wss_out(chip, CS4231_REC_FORMAT,
702 chip->image[CS4231_REC_FORMAT] = cdfr);
703 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
704 chip->image[CS4231_ALT_FEATURE_1] &= ~0x20);
705 full_calib = 0;
706 }
707 spin_unlock_irqrestore(&chip->reg_lock, flags);
708 } else if (chip->hardware == WSS_HW_AD1845) {
709 unsigned rate = params_rate(params);
710
711
712
713
714
715
716
717
718
719
720 spin_lock_irqsave(&chip->reg_lock, flags);
721 snd_wss_out(chip, CS4231_REC_FORMAT, (cdfr & 0xf0));
722 snd_wss_out(chip, AD1845_UPR_FREQ_SEL, (rate >> 8) & 0xff);
723 snd_wss_out(chip, AD1845_LWR_FREQ_SEL, rate & 0xff);
724 full_calib = 0;
725 spin_unlock_irqrestore(&chip->reg_lock, flags);
726 }
727 if (full_calib) {
728 snd_wss_mce_up(chip);
729 spin_lock_irqsave(&chip->reg_lock, flags);
730 if (chip->hardware != WSS_HW_INTERWAVE &&
731 !(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE)) {
732 if (chip->single_dma)
733 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, cdfr);
734 else
735 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
736 (chip->image[CS4231_PLAYBK_FORMAT] & 0xf0) |
737 (cdfr & 0x0f));
738 spin_unlock_irqrestore(&chip->reg_lock, flags);
739 snd_wss_mce_down(chip);
740 snd_wss_mce_up(chip);
741 spin_lock_irqsave(&chip->reg_lock, flags);
742 }
743 if (chip->hardware & WSS_HW_AD1848_MASK)
744 snd_wss_out(chip, CS4231_PLAYBK_FORMAT, cdfr);
745 else
746 snd_wss_out(chip, CS4231_REC_FORMAT, cdfr);
747 spin_unlock_irqrestore(&chip->reg_lock, flags);
748 snd_wss_mce_down(chip);
749 }
750 mutex_unlock(&chip->mce_mutex);
751}
752
753
754
755
756
757static unsigned long snd_wss_timer_resolution(struct snd_timer *timer)
758{
759 struct snd_wss *chip = snd_timer_chip(timer);
760 if (chip->hardware & WSS_HW_CS4236B_MASK)
761 return 14467;
762 else
763 return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920;
764}
765
766static int snd_wss_timer_start(struct snd_timer *timer)
767{
768 unsigned long flags;
769 unsigned int ticks;
770 struct snd_wss *chip = snd_timer_chip(timer);
771 spin_lock_irqsave(&chip->reg_lock, flags);
772 ticks = timer->sticks;
773 if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
774 (unsigned char)(ticks >> 8) != chip->image[CS4231_TIMER_HIGH] ||
775 (unsigned char)ticks != chip->image[CS4231_TIMER_LOW]) {
776 chip->image[CS4231_TIMER_HIGH] = (unsigned char) (ticks >> 8);
777 snd_wss_out(chip, CS4231_TIMER_HIGH,
778 chip->image[CS4231_TIMER_HIGH]);
779 chip->image[CS4231_TIMER_LOW] = (unsigned char) ticks;
780 snd_wss_out(chip, CS4231_TIMER_LOW,
781 chip->image[CS4231_TIMER_LOW]);
782 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
783 chip->image[CS4231_ALT_FEATURE_1] |
784 CS4231_TIMER_ENABLE);
785 }
786 spin_unlock_irqrestore(&chip->reg_lock, flags);
787 return 0;
788}
789
790static int snd_wss_timer_stop(struct snd_timer *timer)
791{
792 unsigned long flags;
793 struct snd_wss *chip = snd_timer_chip(timer);
794 spin_lock_irqsave(&chip->reg_lock, flags);
795 chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE;
796 snd_wss_out(chip, CS4231_ALT_FEATURE_1,
797 chip->image[CS4231_ALT_FEATURE_1]);
798 spin_unlock_irqrestore(&chip->reg_lock, flags);
799 return 0;
800}
801
802static void snd_wss_init(struct snd_wss *chip)
803{
804 unsigned long flags;
805
806 snd_wss_calibrate_mute(chip, 1);
807 snd_wss_mce_down(chip);
808
809#ifdef SNDRV_DEBUG_MCE
810 snd_printk(KERN_DEBUG "init: (1)\n");
811#endif
812 snd_wss_mce_up(chip);
813 spin_lock_irqsave(&chip->reg_lock, flags);
814 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
815 CS4231_PLAYBACK_PIO |
816 CS4231_RECORD_ENABLE |
817 CS4231_RECORD_PIO |
818 CS4231_CALIB_MODE);
819 chip->image[CS4231_IFACE_CTRL] |= CS4231_AUTOCALIB;
820 snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
821 spin_unlock_irqrestore(&chip->reg_lock, flags);
822 snd_wss_mce_down(chip);
823
824#ifdef SNDRV_DEBUG_MCE
825 snd_printk(KERN_DEBUG "init: (2)\n");
826#endif
827
828 snd_wss_mce_up(chip);
829 spin_lock_irqsave(&chip->reg_lock, flags);
830 chip->image[CS4231_IFACE_CTRL] &= ~CS4231_AUTOCALIB;
831 snd_wss_out(chip, CS4231_IFACE_CTRL, chip->image[CS4231_IFACE_CTRL]);
832 snd_wss_out(chip,
833 CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1]);
834 spin_unlock_irqrestore(&chip->reg_lock, flags);
835 snd_wss_mce_down(chip);
836
837#ifdef SNDRV_DEBUG_MCE
838 snd_printk(KERN_DEBUG "init: (3) - afei = 0x%x\n",
839 chip->image[CS4231_ALT_FEATURE_1]);
840#endif
841
842 spin_lock_irqsave(&chip->reg_lock, flags);
843 snd_wss_out(chip, CS4231_ALT_FEATURE_2,
844 chip->image[CS4231_ALT_FEATURE_2]);
845 spin_unlock_irqrestore(&chip->reg_lock, flags);
846
847 snd_wss_mce_up(chip);
848 spin_lock_irqsave(&chip->reg_lock, flags);
849 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
850 chip->image[CS4231_PLAYBK_FORMAT]);
851 spin_unlock_irqrestore(&chip->reg_lock, flags);
852 snd_wss_mce_down(chip);
853
854#ifdef SNDRV_DEBUG_MCE
855 snd_printk(KERN_DEBUG "init: (4)\n");
856#endif
857
858 snd_wss_mce_up(chip);
859 spin_lock_irqsave(&chip->reg_lock, flags);
860 if (!(chip->hardware & WSS_HW_AD1848_MASK))
861 snd_wss_out(chip, CS4231_REC_FORMAT,
862 chip->image[CS4231_REC_FORMAT]);
863 spin_unlock_irqrestore(&chip->reg_lock, flags);
864 snd_wss_mce_down(chip);
865 snd_wss_calibrate_mute(chip, 0);
866
867#ifdef SNDRV_DEBUG_MCE
868 snd_printk(KERN_DEBUG "init: (5)\n");
869#endif
870}
871
872static int snd_wss_open(struct snd_wss *chip, unsigned int mode)
873{
874 unsigned long flags;
875
876 mutex_lock(&chip->open_mutex);
877 if ((chip->mode & mode) ||
878 ((chip->mode & WSS_MODE_OPEN) && chip->single_dma)) {
879 mutex_unlock(&chip->open_mutex);
880 return -EAGAIN;
881 }
882 if (chip->mode & WSS_MODE_OPEN) {
883 chip->mode |= mode;
884 mutex_unlock(&chip->open_mutex);
885 return 0;
886 }
887
888 spin_lock_irqsave(&chip->reg_lock, flags);
889 if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
890 snd_wss_out(chip, CS4231_IRQ_STATUS,
891 CS4231_PLAYBACK_IRQ |
892 CS4231_RECORD_IRQ |
893 CS4231_TIMER_IRQ);
894 snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
895 }
896 wss_outb(chip, CS4231P(STATUS), 0);
897 wss_outb(chip, CS4231P(STATUS), 0);
898 chip->image[CS4231_PIN_CTRL] |= CS4231_IRQ_ENABLE;
899 snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
900 if (!(chip->hardware & WSS_HW_AD1848_MASK)) {
901 snd_wss_out(chip, CS4231_IRQ_STATUS,
902 CS4231_PLAYBACK_IRQ |
903 CS4231_RECORD_IRQ |
904 CS4231_TIMER_IRQ);
905 snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
906 }
907 spin_unlock_irqrestore(&chip->reg_lock, flags);
908
909 chip->mode = mode;
910 mutex_unlock(&chip->open_mutex);
911 return 0;
912}
913
914static void snd_wss_close(struct snd_wss *chip, unsigned int mode)
915{
916 unsigned long flags;
917
918 mutex_lock(&chip->open_mutex);
919 chip->mode &= ~mode;
920 if (chip->mode & WSS_MODE_OPEN) {
921 mutex_unlock(&chip->open_mutex);
922 return;
923 }
924
925 spin_lock_irqsave(&chip->reg_lock, flags);
926 if (!(chip->hardware & WSS_HW_AD1848_MASK))
927 snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
928 wss_outb(chip, CS4231P(STATUS), 0);
929 wss_outb(chip, CS4231P(STATUS), 0);
930 chip->image[CS4231_PIN_CTRL] &= ~CS4231_IRQ_ENABLE;
931 snd_wss_out(chip, CS4231_PIN_CTRL, chip->image[CS4231_PIN_CTRL]);
932
933
934
935 if (chip->image[CS4231_IFACE_CTRL] & (CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
936 CS4231_RECORD_ENABLE | CS4231_RECORD_PIO)) {
937 spin_unlock_irqrestore(&chip->reg_lock, flags);
938 snd_wss_mce_up(chip);
939 spin_lock_irqsave(&chip->reg_lock, flags);
940 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO |
941 CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
942 snd_wss_out(chip, CS4231_IFACE_CTRL,
943 chip->image[CS4231_IFACE_CTRL]);
944 spin_unlock_irqrestore(&chip->reg_lock, flags);
945 snd_wss_mce_down(chip);
946 spin_lock_irqsave(&chip->reg_lock, flags);
947 }
948
949
950 if (!(chip->hardware & WSS_HW_AD1848_MASK))
951 snd_wss_out(chip, CS4231_IRQ_STATUS, 0);
952 wss_outb(chip, CS4231P(STATUS), 0);
953 wss_outb(chip, CS4231P(STATUS), 0);
954 spin_unlock_irqrestore(&chip->reg_lock, flags);
955
956 chip->mode = 0;
957 mutex_unlock(&chip->open_mutex);
958}
959
960
961
962
963
964static int snd_wss_timer_open(struct snd_timer *timer)
965{
966 struct snd_wss *chip = snd_timer_chip(timer);
967 snd_wss_open(chip, WSS_MODE_TIMER);
968 return 0;
969}
970
971static int snd_wss_timer_close(struct snd_timer *timer)
972{
973 struct snd_wss *chip = snd_timer_chip(timer);
974 snd_wss_close(chip, WSS_MODE_TIMER);
975 return 0;
976}
977
978static struct snd_timer_hardware snd_wss_timer_table =
979{
980 .flags = SNDRV_TIMER_HW_AUTO,
981 .resolution = 9945,
982 .ticks = 65535,
983 .open = snd_wss_timer_open,
984 .close = snd_wss_timer_close,
985 .c_resolution = snd_wss_timer_resolution,
986 .start = snd_wss_timer_start,
987 .stop = snd_wss_timer_stop,
988};
989
990
991
992
993
994static int snd_wss_playback_hw_params(struct snd_pcm_substream *substream,
995 struct snd_pcm_hw_params *hw_params)
996{
997 struct snd_wss *chip = snd_pcm_substream_chip(substream);
998 unsigned char new_pdfr;
999 int err;
1000
1001 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1002 return err;
1003 new_pdfr = snd_wss_get_format(chip, params_format(hw_params),
1004 params_channels(hw_params)) |
1005 snd_wss_get_rate(params_rate(hw_params));
1006 chip->set_playback_format(chip, hw_params, new_pdfr);
1007 return 0;
1008}
1009
1010static int snd_wss_playback_hw_free(struct snd_pcm_substream *substream)
1011{
1012 return snd_pcm_lib_free_pages(substream);
1013}
1014
1015static int snd_wss_playback_prepare(struct snd_pcm_substream *substream)
1016{
1017 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1018 struct snd_pcm_runtime *runtime = substream->runtime;
1019 unsigned long flags;
1020 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1021 unsigned int count = snd_pcm_lib_period_bytes(substream);
1022
1023 spin_lock_irqsave(&chip->reg_lock, flags);
1024 chip->p_dma_size = size;
1025 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO);
1026 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
1027 count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1;
1028 snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
1029 snd_wss_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
1030 spin_unlock_irqrestore(&chip->reg_lock, flags);
1031#if 0
1032 snd_wss_debug(chip);
1033#endif
1034 return 0;
1035}
1036
1037static int snd_wss_capture_hw_params(struct snd_pcm_substream *substream,
1038 struct snd_pcm_hw_params *hw_params)
1039{
1040 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1041 unsigned char new_cdfr;
1042 int err;
1043
1044 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1045 return err;
1046 new_cdfr = snd_wss_get_format(chip, params_format(hw_params),
1047 params_channels(hw_params)) |
1048 snd_wss_get_rate(params_rate(hw_params));
1049 chip->set_capture_format(chip, hw_params, new_cdfr);
1050 return 0;
1051}
1052
1053static int snd_wss_capture_hw_free(struct snd_pcm_substream *substream)
1054{
1055 return snd_pcm_lib_free_pages(substream);
1056}
1057
1058static int snd_wss_capture_prepare(struct snd_pcm_substream *substream)
1059{
1060 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1061 struct snd_pcm_runtime *runtime = substream->runtime;
1062 unsigned long flags;
1063 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1064 unsigned int count = snd_pcm_lib_period_bytes(substream);
1065
1066 spin_lock_irqsave(&chip->reg_lock, flags);
1067 chip->c_dma_size = size;
1068 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
1069 snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
1070 if (chip->hardware & WSS_HW_AD1848_MASK)
1071 count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT],
1072 count);
1073 else
1074 count = snd_wss_get_count(chip->image[CS4231_REC_FORMAT],
1075 count);
1076 count--;
1077 if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
1078 snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
1079 snd_wss_out(chip, CS4231_PLY_UPR_CNT,
1080 (unsigned char) (count >> 8));
1081 } else {
1082 snd_wss_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count);
1083 snd_wss_out(chip, CS4231_REC_UPR_CNT,
1084 (unsigned char) (count >> 8));
1085 }
1086 spin_unlock_irqrestore(&chip->reg_lock, flags);
1087 return 0;
1088}
1089
1090void snd_wss_overrange(struct snd_wss *chip)
1091{
1092 unsigned long flags;
1093 unsigned char res;
1094
1095 spin_lock_irqsave(&chip->reg_lock, flags);
1096 res = snd_wss_in(chip, CS4231_TEST_INIT);
1097 spin_unlock_irqrestore(&chip->reg_lock, flags);
1098 if (res & (0x08 | 0x02))
1099 chip->capture_substream->runtime->overrange++;
1100}
1101EXPORT_SYMBOL(snd_wss_overrange);
1102
1103irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
1104{
1105 struct snd_wss *chip = dev_id;
1106 unsigned char status;
1107
1108 if (chip->hardware & WSS_HW_AD1848_MASK)
1109
1110 status = CS4231_PLAYBACK_IRQ;
1111 else
1112 status = snd_wss_in(chip, CS4231_IRQ_STATUS);
1113 if (status & CS4231_TIMER_IRQ) {
1114 if (chip->timer)
1115 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1116 }
1117 if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
1118 if (status & CS4231_PLAYBACK_IRQ) {
1119 if (chip->mode & WSS_MODE_PLAY) {
1120 if (chip->playback_substream)
1121 snd_pcm_period_elapsed(chip->playback_substream);
1122 }
1123 if (chip->mode & WSS_MODE_RECORD) {
1124 if (chip->capture_substream) {
1125 snd_wss_overrange(chip);
1126 snd_pcm_period_elapsed(chip->capture_substream);
1127 }
1128 }
1129 }
1130 } else {
1131 if (status & CS4231_PLAYBACK_IRQ) {
1132 if (chip->playback_substream)
1133 snd_pcm_period_elapsed(chip->playback_substream);
1134 }
1135 if (status & CS4231_RECORD_IRQ) {
1136 if (chip->capture_substream) {
1137 snd_wss_overrange(chip);
1138 snd_pcm_period_elapsed(chip->capture_substream);
1139 }
1140 }
1141 }
1142
1143 spin_lock(&chip->reg_lock);
1144 status = ~CS4231_ALL_IRQS | ~status;
1145 if (chip->hardware & WSS_HW_AD1848_MASK)
1146 wss_outb(chip, CS4231P(STATUS), 0);
1147 else
1148 snd_wss_out(chip, CS4231_IRQ_STATUS, status);
1149 spin_unlock(&chip->reg_lock);
1150 return IRQ_HANDLED;
1151}
1152EXPORT_SYMBOL(snd_wss_interrupt);
1153
1154static snd_pcm_uframes_t snd_wss_playback_pointer(struct snd_pcm_substream *substream)
1155{
1156 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1157 size_t ptr;
1158
1159 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
1160 return 0;
1161 ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
1162 return bytes_to_frames(substream->runtime, ptr);
1163}
1164
1165static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *substream)
1166{
1167 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1168 size_t ptr;
1169
1170 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
1171 return 0;
1172 ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
1173 return bytes_to_frames(substream->runtime, ptr);
1174}
1175
1176
1177
1178
1179
1180static int snd_ad1848_probe(struct snd_wss *chip)
1181{
1182 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
1183 unsigned long flags;
1184 unsigned char r;
1185 unsigned short hardware = 0;
1186 int err = 0;
1187 int i;
1188
1189 while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
1190 if (time_after(jiffies, timeout))
1191 return -ENODEV;
1192 cond_resched();
1193 }
1194 spin_lock_irqsave(&chip->reg_lock, flags);
1195
1196
1197 snd_wss_dout(chip, CS4231_MISC_INFO, 0);
1198
1199 snd_wss_dout(chip, CS4231_RIGHT_INPUT, 0x45);
1200 r = snd_wss_in(chip, CS4231_RIGHT_INPUT);
1201 if (r != 0x45) {
1202
1203 if ((r & ~CS4231_ENABLE_MIC_GAIN) != 0x45) {
1204 err = -ENODEV;
1205 goto out;
1206 }
1207 hardware = WSS_HW_AD1847;
1208 } else {
1209 snd_wss_dout(chip, CS4231_LEFT_INPUT, 0xaa);
1210 r = snd_wss_in(chip, CS4231_LEFT_INPUT);
1211
1212 if ((r | CS4231_ENABLE_MIC_GAIN) != 0xaa) {
1213 err = -ENODEV;
1214 goto out;
1215 }
1216 }
1217
1218
1219 wss_inb(chip, CS4231P(STATUS));
1220 wss_outb(chip, CS4231P(STATUS), 0);
1221 mb();
1222
1223 if ((chip->hardware & WSS_HW_TYPE_MASK) != WSS_HW_DETECT)
1224 goto out;
1225
1226 if (hardware) {
1227 chip->hardware = hardware;
1228 goto out;
1229 }
1230
1231 r = snd_wss_in(chip, CS4231_MISC_INFO);
1232
1233
1234 snd_wss_dout(chip, CS4231_MISC_INFO, CS4231_MODE2);
1235 for (i = 0; i < 16; i++) {
1236 if (snd_wss_in(chip, i) != snd_wss_in(chip, 16 + i)) {
1237
1238 if ((r & 0xf) != 0xa)
1239 goto out_mode;
1240
1241
1242
1243
1244 snd_wss_dout(chip, CS4231_VERSION, 0);
1245 r = snd_wss_in(chip, CS4231_VERSION) & 0xe7;
1246 if (!r)
1247 chip->hardware = WSS_HW_CMI8330;
1248 goto out_mode;
1249 }
1250 }
1251 if (r & 0x80)
1252 chip->hardware = WSS_HW_CS4248;
1253 else
1254 chip->hardware = WSS_HW_AD1848;
1255out_mode:
1256 snd_wss_dout(chip, CS4231_MISC_INFO, 0);
1257out:
1258 spin_unlock_irqrestore(&chip->reg_lock, flags);
1259 return err;
1260}
1261
1262static int snd_wss_probe(struct snd_wss *chip)
1263{
1264 unsigned long flags;
1265 int i, id, rev, regnum;
1266 unsigned char *ptr;
1267 unsigned int hw;
1268
1269 id = snd_ad1848_probe(chip);
1270 if (id < 0)
1271 return id;
1272
1273 hw = chip->hardware;
1274 if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
1275 for (i = 0; i < 50; i++) {
1276 mb();
1277 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
1278 msleep(2);
1279 else {
1280 spin_lock_irqsave(&chip->reg_lock, flags);
1281 snd_wss_out(chip, CS4231_MISC_INFO,
1282 CS4231_MODE2);
1283 id = snd_wss_in(chip, CS4231_MISC_INFO) & 0x0f;
1284 spin_unlock_irqrestore(&chip->reg_lock, flags);
1285 if (id == 0x0a)
1286 break;
1287 }
1288 }
1289 snd_printdd("wss: port = 0x%lx, id = 0x%x\n", chip->port, id);
1290 if (id != 0x0a)
1291 return -ENODEV;
1292
1293 rev = snd_wss_in(chip, CS4231_VERSION) & 0xe7;
1294 snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev);
1295 if (rev == 0x80) {
1296 unsigned char tmp = snd_wss_in(chip, 23);
1297 snd_wss_out(chip, 23, ~tmp);
1298 if (snd_wss_in(chip, 23) != tmp)
1299 chip->hardware = WSS_HW_AD1845;
1300 else
1301 chip->hardware = WSS_HW_CS4231;
1302 } else if (rev == 0xa0) {
1303 chip->hardware = WSS_HW_CS4231A;
1304 } else if (rev == 0xa2) {
1305 chip->hardware = WSS_HW_CS4232;
1306 } else if (rev == 0xb2) {
1307 chip->hardware = WSS_HW_CS4232A;
1308 } else if (rev == 0x83) {
1309 chip->hardware = WSS_HW_CS4236;
1310 } else if (rev == 0x03) {
1311 chip->hardware = WSS_HW_CS4236B;
1312 } else {
1313 snd_printk(KERN_ERR
1314 "unknown CS chip with version 0x%x\n", rev);
1315 return -ENODEV;
1316 }
1317 }
1318 spin_lock_irqsave(&chip->reg_lock, flags);
1319 wss_inb(chip, CS4231P(STATUS));
1320 wss_outb(chip, CS4231P(STATUS), 0);
1321 mb();
1322 spin_unlock_irqrestore(&chip->reg_lock, flags);
1323
1324 if (!(chip->hardware & WSS_HW_AD1848_MASK))
1325 chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
1326 switch (chip->hardware) {
1327 case WSS_HW_INTERWAVE:
1328 chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3;
1329 break;
1330 case WSS_HW_CS4235:
1331 case WSS_HW_CS4236B:
1332 case WSS_HW_CS4237B:
1333 case WSS_HW_CS4238B:
1334 case WSS_HW_CS4239:
1335 if (hw == WSS_HW_DETECT3)
1336 chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3;
1337 else
1338 chip->hardware = WSS_HW_CS4236;
1339 break;
1340 }
1341
1342 chip->image[CS4231_IFACE_CTRL] =
1343 (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) |
1344 (chip->single_dma ? CS4231_SINGLE_DMA : 0);
1345 if (chip->hardware != WSS_HW_OPTI93X) {
1346 chip->image[CS4231_ALT_FEATURE_1] = 0x80;
1347 chip->image[CS4231_ALT_FEATURE_2] =
1348 chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01;
1349 }
1350
1351 if (chip->hardware == WSS_HW_AD1845)
1352 chip->image[AD1845_PWR_DOWN] = 8;
1353
1354 ptr = (unsigned char *) &chip->image;
1355 regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32;
1356 snd_wss_mce_down(chip);
1357 spin_lock_irqsave(&chip->reg_lock, flags);
1358 for (i = 0; i < regnum; i++)
1359 snd_wss_out(chip, i, *ptr++);
1360 spin_unlock_irqrestore(&chip->reg_lock, flags);
1361 snd_wss_mce_up(chip);
1362 snd_wss_mce_down(chip);
1363
1364 mdelay(2);
1365
1366
1367 if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
1368 if (chip->hardware == WSS_HW_CS4236B) {
1369 rev = snd_cs4236_ext_in(chip, CS4236_VERSION);
1370 snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff);
1371 id = snd_cs4236_ext_in(chip, CS4236_VERSION);
1372 snd_cs4236_ext_out(chip, CS4236_VERSION, rev);
1373 snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id);
1374 if ((id & 0x1f) == 0x1d) {
1375 chip->hardware = WSS_HW_CS4235;
1376 switch (id >> 5) {
1377 case 4:
1378 case 5:
1379 case 6:
1380 break;
1381 default:
1382 snd_printk(KERN_WARNING
1383 "unknown CS4235 chip "
1384 "(enhanced version = 0x%x)\n",
1385 id);
1386 }
1387 } else if ((id & 0x1f) == 0x0b) {
1388 switch (id >> 5) {
1389 case 4:
1390 case 5:
1391 case 6:
1392 case 7:
1393 chip->hardware = WSS_HW_CS4236B;
1394 break;
1395 default:
1396 snd_printk(KERN_WARNING
1397 "unknown CS4236 chip "
1398 "(enhanced version = 0x%x)\n",
1399 id);
1400 }
1401 } else if ((id & 0x1f) == 0x08) {
1402 chip->hardware = WSS_HW_CS4237B;
1403 switch (id >> 5) {
1404 case 4:
1405 case 5:
1406 case 6:
1407 case 7:
1408 break;
1409 default:
1410 snd_printk(KERN_WARNING
1411 "unknown CS4237B chip "
1412 "(enhanced version = 0x%x)\n",
1413 id);
1414 }
1415 } else if ((id & 0x1f) == 0x09) {
1416 chip->hardware = WSS_HW_CS4238B;
1417 switch (id >> 5) {
1418 case 5:
1419 case 6:
1420 case 7:
1421 break;
1422 default:
1423 snd_printk(KERN_WARNING
1424 "unknown CS4238B chip "
1425 "(enhanced version = 0x%x)\n",
1426 id);
1427 }
1428 } else if ((id & 0x1f) == 0x1e) {
1429 chip->hardware = WSS_HW_CS4239;
1430 switch (id >> 5) {
1431 case 4:
1432 case 5:
1433 case 6:
1434 break;
1435 default:
1436 snd_printk(KERN_WARNING
1437 "unknown CS4239 chip "
1438 "(enhanced version = 0x%x)\n",
1439 id);
1440 }
1441 } else {
1442 snd_printk(KERN_WARNING
1443 "unknown CS4236/CS423xB chip "
1444 "(enhanced version = 0x%x)\n", id);
1445 }
1446 }
1447 }
1448 return 0;
1449}
1450
1451
1452
1453
1454
1455static struct snd_pcm_hardware snd_wss_playback =
1456{
1457 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1458 SNDRV_PCM_INFO_MMAP_VALID |
1459 SNDRV_PCM_INFO_SYNC_START),
1460 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1461 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1462 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1463 .rate_min = 5510,
1464 .rate_max = 48000,
1465 .channels_min = 1,
1466 .channels_max = 2,
1467 .buffer_bytes_max = (128*1024),
1468 .period_bytes_min = 64,
1469 .period_bytes_max = (128*1024),
1470 .periods_min = 1,
1471 .periods_max = 1024,
1472 .fifo_size = 0,
1473};
1474
1475static struct snd_pcm_hardware snd_wss_capture =
1476{
1477 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1478 SNDRV_PCM_INFO_MMAP_VALID |
1479 SNDRV_PCM_INFO_RESUME |
1480 SNDRV_PCM_INFO_SYNC_START),
1481 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1482 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1483 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1484 .rate_min = 5510,
1485 .rate_max = 48000,
1486 .channels_min = 1,
1487 .channels_max = 2,
1488 .buffer_bytes_max = (128*1024),
1489 .period_bytes_min = 64,
1490 .period_bytes_max = (128*1024),
1491 .periods_min = 1,
1492 .periods_max = 1024,
1493 .fifo_size = 0,
1494};
1495
1496
1497
1498
1499
1500static int snd_wss_playback_open(struct snd_pcm_substream *substream)
1501{
1502 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1503 struct snd_pcm_runtime *runtime = substream->runtime;
1504 int err;
1505
1506 runtime->hw = snd_wss_playback;
1507
1508
1509 if (chip->hardware & WSS_HW_AD1848_MASK)
1510 runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
1511 SNDRV_PCM_FMTBIT_S16_BE);
1512
1513
1514 if (chip->hardware == WSS_HW_INTERWAVE && chip->dma1 > 3)
1515 runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW;
1516
1517
1518 if (chip->hardware == WSS_HW_CS4235 ||
1519 chip->hardware == WSS_HW_CS4239)
1520 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1521
1522 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
1523 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
1524
1525 if (chip->claim_dma) {
1526 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
1527 return err;
1528 }
1529
1530 err = snd_wss_open(chip, WSS_MODE_PLAY);
1531 if (err < 0) {
1532 if (chip->release_dma)
1533 chip->release_dma(chip, chip->dma_private_data, chip->dma1);
1534 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1535 return err;
1536 }
1537 chip->playback_substream = substream;
1538 snd_pcm_set_sync(substream);
1539 chip->rate_constraint(runtime);
1540 return 0;
1541}
1542
1543static int snd_wss_capture_open(struct snd_pcm_substream *substream)
1544{
1545 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1546 struct snd_pcm_runtime *runtime = substream->runtime;
1547 int err;
1548
1549 runtime->hw = snd_wss_capture;
1550
1551
1552 if (chip->hardware & WSS_HW_AD1848_MASK)
1553 runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
1554 SNDRV_PCM_FMTBIT_S16_BE);
1555
1556
1557 if (chip->hardware == WSS_HW_CS4235 ||
1558 chip->hardware == WSS_HW_CS4239 ||
1559 chip->hardware == WSS_HW_OPTI93X)
1560 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 |
1561 SNDRV_PCM_FMTBIT_S16_LE;
1562
1563 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1564 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
1565
1566 if (chip->claim_dma) {
1567 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
1568 return err;
1569 }
1570
1571 err = snd_wss_open(chip, WSS_MODE_RECORD);
1572 if (err < 0) {
1573 if (chip->release_dma)
1574 chip->release_dma(chip, chip->dma_private_data, chip->dma2);
1575 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1576 return err;
1577 }
1578 chip->capture_substream = substream;
1579 snd_pcm_set_sync(substream);
1580 chip->rate_constraint(runtime);
1581 return 0;
1582}
1583
1584static int snd_wss_playback_close(struct snd_pcm_substream *substream)
1585{
1586 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1587
1588 chip->playback_substream = NULL;
1589 snd_wss_close(chip, WSS_MODE_PLAY);
1590 return 0;
1591}
1592
1593static int snd_wss_capture_close(struct snd_pcm_substream *substream)
1594{
1595 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1596
1597 chip->capture_substream = NULL;
1598 snd_wss_close(chip, WSS_MODE_RECORD);
1599 return 0;
1600}
1601
1602static void snd_wss_thinkpad_twiddle(struct snd_wss *chip, int on)
1603{
1604 int tmp;
1605
1606 if (!chip->thinkpad_flag)
1607 return;
1608
1609 outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
1610 tmp = inb(AD1848_THINKPAD_CTL_PORT2);
1611
1612 if (on)
1613
1614 tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
1615 else
1616
1617 tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
1618
1619 outb(tmp, AD1848_THINKPAD_CTL_PORT2);
1620}
1621
1622#ifdef CONFIG_PM
1623
1624
1625static void snd_wss_suspend(struct snd_wss *chip)
1626{
1627 int reg;
1628 unsigned long flags;
1629
1630 snd_pcm_suspend_all(chip->pcm);
1631 spin_lock_irqsave(&chip->reg_lock, flags);
1632 for (reg = 0; reg < 32; reg++)
1633 chip->image[reg] = snd_wss_in(chip, reg);
1634 spin_unlock_irqrestore(&chip->reg_lock, flags);
1635 if (chip->thinkpad_flag)
1636 snd_wss_thinkpad_twiddle(chip, 0);
1637}
1638
1639
1640static void snd_wss_resume(struct snd_wss *chip)
1641{
1642 int reg;
1643 unsigned long flags;
1644
1645
1646 if (chip->thinkpad_flag)
1647 snd_wss_thinkpad_twiddle(chip, 1);
1648 snd_wss_mce_up(chip);
1649 spin_lock_irqsave(&chip->reg_lock, flags);
1650 for (reg = 0; reg < 32; reg++) {
1651 switch (reg) {
1652 case CS4231_VERSION:
1653 break;
1654 default:
1655 snd_wss_out(chip, reg, chip->image[reg]);
1656 break;
1657 }
1658 }
1659
1660 if (chip->hardware == WSS_HW_OPL3SA2)
1661 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
1662 chip->image[CS4231_PLAYBK_FORMAT]);
1663 spin_unlock_irqrestore(&chip->reg_lock, flags);
1664#if 1
1665 snd_wss_mce_down(chip);
1666#else
1667
1668
1669
1670
1671 snd_wss_busy_wait(chip);
1672 spin_lock_irqsave(&chip->reg_lock, flags);
1673 chip->mce_bit &= ~CS4231_MCE;
1674 timeout = wss_inb(chip, CS4231P(REGSEL));
1675 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
1676 spin_unlock_irqrestore(&chip->reg_lock, flags);
1677 if (timeout == 0x80)
1678 snd_printk(KERN_ERR "down [0x%lx]: serious init problem "
1679 "- codec still busy\n", chip->port);
1680 if ((timeout & CS4231_MCE) == 0 ||
1681 !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) {
1682 return;
1683 }
1684 snd_wss_busy_wait(chip);
1685#endif
1686}
1687#endif
1688
1689static int snd_wss_free(struct snd_wss *chip)
1690{
1691 release_and_free_resource(chip->res_port);
1692 release_and_free_resource(chip->res_cport);
1693 if (chip->irq >= 0) {
1694 disable_irq(chip->irq);
1695 if (!(chip->hwshare & WSS_HWSHARE_IRQ))
1696 free_irq(chip->irq, (void *) chip);
1697 }
1698 if (!(chip->hwshare & WSS_HWSHARE_DMA1) && chip->dma1 >= 0) {
1699 snd_dma_disable(chip->dma1);
1700 free_dma(chip->dma1);
1701 }
1702 if (!(chip->hwshare & WSS_HWSHARE_DMA2) &&
1703 chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
1704 snd_dma_disable(chip->dma2);
1705 free_dma(chip->dma2);
1706 }
1707 if (chip->timer)
1708 snd_device_free(chip->card, chip->timer);
1709 kfree(chip);
1710 return 0;
1711}
1712
1713static int snd_wss_dev_free(struct snd_device *device)
1714{
1715 struct snd_wss *chip = device->device_data;
1716 return snd_wss_free(chip);
1717}
1718
1719const char *snd_wss_chip_id(struct snd_wss *chip)
1720{
1721 switch (chip->hardware) {
1722 case WSS_HW_CS4231:
1723 return "CS4231";
1724 case WSS_HW_CS4231A:
1725 return "CS4231A";
1726 case WSS_HW_CS4232:
1727 return "CS4232";
1728 case WSS_HW_CS4232A:
1729 return "CS4232A";
1730 case WSS_HW_CS4235:
1731 return "CS4235";
1732 case WSS_HW_CS4236:
1733 return "CS4236";
1734 case WSS_HW_CS4236B:
1735 return "CS4236B";
1736 case WSS_HW_CS4237B:
1737 return "CS4237B";
1738 case WSS_HW_CS4238B:
1739 return "CS4238B";
1740 case WSS_HW_CS4239:
1741 return "CS4239";
1742 case WSS_HW_INTERWAVE:
1743 return "AMD InterWave";
1744 case WSS_HW_OPL3SA2:
1745 return chip->card->shortname;
1746 case WSS_HW_AD1845:
1747 return "AD1845";
1748 case WSS_HW_OPTI93X:
1749 return "OPTi 93x";
1750 case WSS_HW_AD1847:
1751 return "AD1847";
1752 case WSS_HW_AD1848:
1753 return "AD1848";
1754 case WSS_HW_CS4248:
1755 return "CS4248";
1756 case WSS_HW_CMI8330:
1757 return "CMI8330/C3D";
1758 default:
1759 return "???";
1760 }
1761}
1762EXPORT_SYMBOL(snd_wss_chip_id);
1763
1764static int snd_wss_new(struct snd_card *card,
1765 unsigned short hardware,
1766 unsigned short hwshare,
1767 struct snd_wss **rchip)
1768{
1769 struct snd_wss *chip;
1770
1771 *rchip = NULL;
1772 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1773 if (chip == NULL)
1774 return -ENOMEM;
1775 chip->hardware = hardware;
1776 chip->hwshare = hwshare;
1777
1778 spin_lock_init(&chip->reg_lock);
1779 mutex_init(&chip->mce_mutex);
1780 mutex_init(&chip->open_mutex);
1781 chip->card = card;
1782 chip->rate_constraint = snd_wss_xrate;
1783 chip->set_playback_format = snd_wss_playback_format;
1784 chip->set_capture_format = snd_wss_capture_format;
1785 if (chip->hardware == WSS_HW_OPTI93X)
1786 memcpy(&chip->image, &snd_opti93x_original_image,
1787 sizeof(snd_opti93x_original_image));
1788 else
1789 memcpy(&chip->image, &snd_wss_original_image,
1790 sizeof(snd_wss_original_image));
1791 if (chip->hardware & WSS_HW_AD1848_MASK) {
1792 chip->image[CS4231_PIN_CTRL] = 0;
1793 chip->image[CS4231_TEST_INIT] = 0;
1794 }
1795
1796 *rchip = chip;
1797 return 0;
1798}
1799
1800int snd_wss_create(struct snd_card *card,
1801 unsigned long port,
1802 unsigned long cport,
1803 int irq, int dma1, int dma2,
1804 unsigned short hardware,
1805 unsigned short hwshare,
1806 struct snd_wss **rchip)
1807{
1808 static struct snd_device_ops ops = {
1809 .dev_free = snd_wss_dev_free,
1810 };
1811 struct snd_wss *chip;
1812 int err;
1813
1814 err = snd_wss_new(card, hardware, hwshare, &chip);
1815 if (err < 0)
1816 return err;
1817
1818 chip->irq = -1;
1819 chip->dma1 = -1;
1820 chip->dma2 = -1;
1821
1822 chip->res_port = request_region(port, 4, "WSS");
1823 if (!chip->res_port) {
1824 snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port);
1825 snd_wss_free(chip);
1826 return -EBUSY;
1827 }
1828 chip->port = port;
1829 if ((long)cport >= 0) {
1830 chip->res_cport = request_region(cport, 8, "CS4232 Control");
1831 if (!chip->res_cport) {
1832 snd_printk(KERN_ERR
1833 "wss: can't grab control port 0x%lx\n", cport);
1834 snd_wss_free(chip);
1835 return -ENODEV;
1836 }
1837 }
1838 chip->cport = cport;
1839 if (!(hwshare & WSS_HWSHARE_IRQ))
1840 if (request_irq(irq, snd_wss_interrupt, 0,
1841 "WSS", (void *) chip)) {
1842 snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
1843 snd_wss_free(chip);
1844 return -EBUSY;
1845 }
1846 chip->irq = irq;
1847 if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "WSS - 1")) {
1848 snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1);
1849 snd_wss_free(chip);
1850 return -EBUSY;
1851 }
1852 chip->dma1 = dma1;
1853 if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 &&
1854 dma2 >= 0 && request_dma(dma2, "WSS - 2")) {
1855 snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2);
1856 snd_wss_free(chip);
1857 return -EBUSY;
1858 }
1859 if (dma1 == dma2 || dma2 < 0) {
1860 chip->single_dma = 1;
1861 chip->dma2 = chip->dma1;
1862 } else
1863 chip->dma2 = dma2;
1864
1865 if (hardware == WSS_HW_THINKPAD) {
1866 chip->thinkpad_flag = 1;
1867 chip->hardware = WSS_HW_DETECT;
1868 snd_wss_thinkpad_twiddle(chip, 1);
1869 }
1870
1871
1872 if (snd_wss_probe(chip) < 0) {
1873 snd_wss_free(chip);
1874 return -ENODEV;
1875 }
1876 snd_wss_init(chip);
1877
1878#if 0
1879 if (chip->hardware & WSS_HW_CS4232_MASK) {
1880 if (chip->res_cport == NULL)
1881 snd_printk(KERN_ERR "CS4232 control port features are "
1882 "not accessible\n");
1883 }
1884#endif
1885
1886
1887 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1888 if (err < 0) {
1889 snd_wss_free(chip);
1890 return err;
1891 }
1892
1893#ifdef CONFIG_PM
1894
1895 chip->suspend = snd_wss_suspend;
1896 chip->resume = snd_wss_resume;
1897#endif
1898
1899 *rchip = chip;
1900 return 0;
1901}
1902EXPORT_SYMBOL(snd_wss_create);
1903
1904static struct snd_pcm_ops snd_wss_playback_ops = {
1905 .open = snd_wss_playback_open,
1906 .close = snd_wss_playback_close,
1907 .ioctl = snd_pcm_lib_ioctl,
1908 .hw_params = snd_wss_playback_hw_params,
1909 .hw_free = snd_wss_playback_hw_free,
1910 .prepare = snd_wss_playback_prepare,
1911 .trigger = snd_wss_trigger,
1912 .pointer = snd_wss_playback_pointer,
1913};
1914
1915static struct snd_pcm_ops snd_wss_capture_ops = {
1916 .open = snd_wss_capture_open,
1917 .close = snd_wss_capture_close,
1918 .ioctl = snd_pcm_lib_ioctl,
1919 .hw_params = snd_wss_capture_hw_params,
1920 .hw_free = snd_wss_capture_hw_free,
1921 .prepare = snd_wss_capture_prepare,
1922 .trigger = snd_wss_trigger,
1923 .pointer = snd_wss_capture_pointer,
1924};
1925
1926int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
1927{
1928 struct snd_pcm *pcm;
1929 int err;
1930
1931 err = snd_pcm_new(chip->card, "WSS", device, 1, 1, &pcm);
1932 if (err < 0)
1933 return err;
1934
1935 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops);
1936 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops);
1937
1938
1939 pcm->private_data = chip;
1940 pcm->info_flags = 0;
1941 if (chip->single_dma)
1942 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
1943 if (chip->hardware != WSS_HW_INTERWAVE)
1944 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1945 strcpy(pcm->name, snd_wss_chip_id(chip));
1946
1947 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1948 snd_dma_isa_data(),
1949 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
1950
1951 chip->pcm = pcm;
1952 if (rpcm)
1953 *rpcm = pcm;
1954 return 0;
1955}
1956EXPORT_SYMBOL(snd_wss_pcm);
1957
1958static void snd_wss_timer_free(struct snd_timer *timer)
1959{
1960 struct snd_wss *chip = timer->private_data;
1961 chip->timer = NULL;
1962}
1963
1964int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer)
1965{
1966 struct snd_timer *timer;
1967 struct snd_timer_id tid;
1968 int err;
1969
1970
1971 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1972 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1973 tid.card = chip->card->number;
1974 tid.device = device;
1975 tid.subdevice = 0;
1976 if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
1977 return err;
1978 strcpy(timer->name, snd_wss_chip_id(chip));
1979 timer->private_data = chip;
1980 timer->private_free = snd_wss_timer_free;
1981 timer->hw = snd_wss_timer_table;
1982 chip->timer = timer;
1983 if (rtimer)
1984 *rtimer = timer;
1985 return 0;
1986}
1987EXPORT_SYMBOL(snd_wss_timer);
1988
1989
1990
1991
1992
1993static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
1994 struct snd_ctl_elem_info *uinfo)
1995{
1996 static char *texts[4] = {
1997 "Line", "Aux", "Mic", "Mix"
1998 };
1999 static char *opl3sa_texts[4] = {
2000 "Line", "CD", "Mic", "Mix"
2001 };
2002 static char *gusmax_texts[4] = {
2003 "Line", "Synth", "Mic", "Mix"
2004 };
2005 char **ptexts = texts;
2006 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2007
2008 if (snd_BUG_ON(!chip->card))
2009 return -EINVAL;
2010 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2011 uinfo->count = 2;
2012 uinfo->value.enumerated.items = 4;
2013 if (uinfo->value.enumerated.item > 3)
2014 uinfo->value.enumerated.item = 3;
2015 if (!strcmp(chip->card->driver, "GUS MAX"))
2016 ptexts = gusmax_texts;
2017 switch (chip->hardware) {
2018 case WSS_HW_INTERWAVE:
2019 ptexts = gusmax_texts;
2020 break;
2021 case WSS_HW_OPTI93X:
2022 case WSS_HW_OPL3SA2:
2023 ptexts = opl3sa_texts;
2024 break;
2025 }
2026 strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]);
2027 return 0;
2028}
2029
2030static int snd_wss_get_mux(struct snd_kcontrol *kcontrol,
2031 struct snd_ctl_elem_value *ucontrol)
2032{
2033 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2034 unsigned long flags;
2035
2036 spin_lock_irqsave(&chip->reg_lock, flags);
2037 ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
2038 ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
2039 spin_unlock_irqrestore(&chip->reg_lock, flags);
2040 return 0;
2041}
2042
2043static int snd_wss_put_mux(struct snd_kcontrol *kcontrol,
2044 struct snd_ctl_elem_value *ucontrol)
2045{
2046 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2047 unsigned long flags;
2048 unsigned short left, right;
2049 int change;
2050
2051 if (ucontrol->value.enumerated.item[0] > 3 ||
2052 ucontrol->value.enumerated.item[1] > 3)
2053 return -EINVAL;
2054 left = ucontrol->value.enumerated.item[0] << 6;
2055 right = ucontrol->value.enumerated.item[1] << 6;
2056 spin_lock_irqsave(&chip->reg_lock, flags);
2057 left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
2058 right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
2059 change = left != chip->image[CS4231_LEFT_INPUT] ||
2060 right != chip->image[CS4231_RIGHT_INPUT];
2061 snd_wss_out(chip, CS4231_LEFT_INPUT, left);
2062 snd_wss_out(chip, CS4231_RIGHT_INPUT, right);
2063 spin_unlock_irqrestore(&chip->reg_lock, flags);
2064 return change;
2065}
2066
2067int snd_wss_info_single(struct snd_kcontrol *kcontrol,
2068 struct snd_ctl_elem_info *uinfo)
2069{
2070 int mask = (kcontrol->private_value >> 16) & 0xff;
2071
2072 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2073 uinfo->count = 1;
2074 uinfo->value.integer.min = 0;
2075 uinfo->value.integer.max = mask;
2076 return 0;
2077}
2078EXPORT_SYMBOL(snd_wss_info_single);
2079
2080int snd_wss_get_single(struct snd_kcontrol *kcontrol,
2081 struct snd_ctl_elem_value *ucontrol)
2082{
2083 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2084 unsigned long flags;
2085 int reg = kcontrol->private_value & 0xff;
2086 int shift = (kcontrol->private_value >> 8) & 0xff;
2087 int mask = (kcontrol->private_value >> 16) & 0xff;
2088 int invert = (kcontrol->private_value >> 24) & 0xff;
2089
2090 spin_lock_irqsave(&chip->reg_lock, flags);
2091 ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
2092 spin_unlock_irqrestore(&chip->reg_lock, flags);
2093 if (invert)
2094 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2095 return 0;
2096}
2097EXPORT_SYMBOL(snd_wss_get_single);
2098
2099int snd_wss_put_single(struct snd_kcontrol *kcontrol,
2100 struct snd_ctl_elem_value *ucontrol)
2101{
2102 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2103 unsigned long flags;
2104 int reg = kcontrol->private_value & 0xff;
2105 int shift = (kcontrol->private_value >> 8) & 0xff;
2106 int mask = (kcontrol->private_value >> 16) & 0xff;
2107 int invert = (kcontrol->private_value >> 24) & 0xff;
2108 int change;
2109 unsigned short val;
2110
2111 val = (ucontrol->value.integer.value[0] & mask);
2112 if (invert)
2113 val = mask - val;
2114 val <<= shift;
2115 spin_lock_irqsave(&chip->reg_lock, flags);
2116 val = (chip->image[reg] & ~(mask << shift)) | val;
2117 change = val != chip->image[reg];
2118 snd_wss_out(chip, reg, val);
2119 spin_unlock_irqrestore(&chip->reg_lock, flags);
2120 return change;
2121}
2122EXPORT_SYMBOL(snd_wss_put_single);
2123
2124int snd_wss_info_double(struct snd_kcontrol *kcontrol,
2125 struct snd_ctl_elem_info *uinfo)
2126{
2127 int mask = (kcontrol->private_value >> 24) & 0xff;
2128
2129 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2130 uinfo->count = 2;
2131 uinfo->value.integer.min = 0;
2132 uinfo->value.integer.max = mask;
2133 return 0;
2134}
2135EXPORT_SYMBOL(snd_wss_info_double);
2136
2137int snd_wss_get_double(struct snd_kcontrol *kcontrol,
2138 struct snd_ctl_elem_value *ucontrol)
2139{
2140 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2141 unsigned long flags;
2142 int left_reg = kcontrol->private_value & 0xff;
2143 int right_reg = (kcontrol->private_value >> 8) & 0xff;
2144 int shift_left = (kcontrol->private_value >> 16) & 0x07;
2145 int shift_right = (kcontrol->private_value >> 19) & 0x07;
2146 int mask = (kcontrol->private_value >> 24) & 0xff;
2147 int invert = (kcontrol->private_value >> 22) & 1;
2148
2149 spin_lock_irqsave(&chip->reg_lock, flags);
2150 ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
2151 ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
2152 spin_unlock_irqrestore(&chip->reg_lock, flags);
2153 if (invert) {
2154 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2155 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
2156 }
2157 return 0;
2158}
2159EXPORT_SYMBOL(snd_wss_get_double);
2160
2161int snd_wss_put_double(struct snd_kcontrol *kcontrol,
2162 struct snd_ctl_elem_value *ucontrol)
2163{
2164 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2165 unsigned long flags;
2166 int left_reg = kcontrol->private_value & 0xff;
2167 int right_reg = (kcontrol->private_value >> 8) & 0xff;
2168 int shift_left = (kcontrol->private_value >> 16) & 0x07;
2169 int shift_right = (kcontrol->private_value >> 19) & 0x07;
2170 int mask = (kcontrol->private_value >> 24) & 0xff;
2171 int invert = (kcontrol->private_value >> 22) & 1;
2172 int change;
2173 unsigned short val1, val2;
2174
2175 val1 = ucontrol->value.integer.value[0] & mask;
2176 val2 = ucontrol->value.integer.value[1] & mask;
2177 if (invert) {
2178 val1 = mask - val1;
2179 val2 = mask - val2;
2180 }
2181 val1 <<= shift_left;
2182 val2 <<= shift_right;
2183 spin_lock_irqsave(&chip->reg_lock, flags);
2184 if (left_reg != right_reg) {
2185 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
2186 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
2187 change = val1 != chip->image[left_reg] ||
2188 val2 != chip->image[right_reg];
2189 snd_wss_out(chip, left_reg, val1);
2190 snd_wss_out(chip, right_reg, val2);
2191 } else {
2192 mask = (mask << shift_left) | (mask << shift_right);
2193 val1 = (chip->image[left_reg] & ~mask) | val1 | val2;
2194 change = val1 != chip->image[left_reg];
2195 snd_wss_out(chip, left_reg, val1);
2196 }
2197 spin_unlock_irqrestore(&chip->reg_lock, flags);
2198 return change;
2199}
2200EXPORT_SYMBOL(snd_wss_put_double);
2201
2202static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
2203static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
2204static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
2205static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
2206
2207static struct snd_kcontrol_new snd_wss_controls[] = {
2208WSS_DOUBLE("PCM Playback Switch", 0,
2209 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2210WSS_DOUBLE_TLV("PCM Playback Volume", 0,
2211 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
2212 db_scale_6bit),
2213WSS_DOUBLE("Aux Playback Switch", 0,
2214 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2215WSS_DOUBLE_TLV("Aux Playback Volume", 0,
2216 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
2217 db_scale_5bit_12db_max),
2218WSS_DOUBLE("Aux Playback Switch", 1,
2219 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2220WSS_DOUBLE_TLV("Aux Playback Volume", 1,
2221 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
2222 db_scale_5bit_12db_max),
2223WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
2224 0, 0, 15, 0, db_scale_rec_gain),
2225{
2226 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2227 .name = "Capture Source",
2228 .info = snd_wss_info_mux,
2229 .get = snd_wss_get_mux,
2230 .put = snd_wss_put_mux,
2231},
2232WSS_DOUBLE("Mic Boost (+20dB)", 0,
2233 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2234WSS_SINGLE("Loopback Capture Switch", 0,
2235 CS4231_LOOPBACK, 0, 1, 0),
2236WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1,
2237 db_scale_6bit),
2238WSS_DOUBLE("Line Playback Switch", 0,
2239 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2240WSS_DOUBLE_TLV("Line Playback Volume", 0,
2241 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
2242 db_scale_5bit_12db_max),
2243WSS_SINGLE("Beep Playback Switch", 0,
2244 CS4231_MONO_CTRL, 7, 1, 1),
2245WSS_SINGLE_TLV("Beep Playback Volume", 0,
2246 CS4231_MONO_CTRL, 0, 15, 1,
2247 db_scale_4bit),
2248WSS_SINGLE("Mono Output Playback Switch", 0,
2249 CS4231_MONO_CTRL, 6, 1, 1),
2250WSS_SINGLE("Beep Bypass Playback Switch", 0,
2251 CS4231_MONO_CTRL, 5, 1, 0),
2252};
2253
2254int snd_wss_mixer(struct snd_wss *chip)
2255{
2256 struct snd_card *card;
2257 unsigned int idx;
2258 int err;
2259 int count = ARRAY_SIZE(snd_wss_controls);
2260
2261 if (snd_BUG_ON(!chip || !chip->pcm))
2262 return -EINVAL;
2263
2264 card = chip->card;
2265
2266 strcpy(card->mixername, chip->pcm->name);
2267
2268
2269 if (chip->hardware & WSS_HW_AD1848_MASK)
2270 count = 11;
2271
2272 else if (chip->hardware == WSS_HW_OPTI93X)
2273 count = 9;
2274
2275 for (idx = 0; idx < count; idx++) {
2276 err = snd_ctl_add(card,
2277 snd_ctl_new1(&snd_wss_controls[idx],
2278 chip));
2279 if (err < 0)
2280 return err;
2281 }
2282 return 0;
2283}
2284EXPORT_SYMBOL(snd_wss_mixer);
2285
2286const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction)
2287{
2288 return direction == SNDRV_PCM_STREAM_PLAYBACK ?
2289 &snd_wss_playback_ops : &snd_wss_capture_ops;
2290}
2291EXPORT_SYMBOL(snd_wss_get_pcm_ops);
2292
2293
2294
2295
2296
2297static int __init alsa_wss_init(void)
2298{
2299 return 0;
2300}
2301
2302static void __exit alsa_wss_exit(void)
2303{
2304}
2305
2306module_init(alsa_wss_init);
2307module_exit(alsa_wss_exit);
2308