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 <sound/core.h>
35#include <sound/wss.h>
36#include <sound/pcm_params.h>
37#include <sound/tlv.h>
38
39#include <asm/io.h>
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_RESUME |
1460 SNDRV_PCM_INFO_SYNC_START),
1461 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1462 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1463 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1464 .rate_min = 5510,
1465 .rate_max = 48000,
1466 .channels_min = 1,
1467 .channels_max = 2,
1468 .buffer_bytes_max = (128*1024),
1469 .period_bytes_min = 64,
1470 .period_bytes_max = (128*1024),
1471 .periods_min = 1,
1472 .periods_max = 1024,
1473 .fifo_size = 0,
1474};
1475
1476static struct snd_pcm_hardware snd_wss_capture =
1477{
1478 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1479 SNDRV_PCM_INFO_MMAP_VALID |
1480 SNDRV_PCM_INFO_RESUME |
1481 SNDRV_PCM_INFO_SYNC_START),
1482 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1483 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1484 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1485 .rate_min = 5510,
1486 .rate_max = 48000,
1487 .channels_min = 1,
1488 .channels_max = 2,
1489 .buffer_bytes_max = (128*1024),
1490 .period_bytes_min = 64,
1491 .period_bytes_max = (128*1024),
1492 .periods_min = 1,
1493 .periods_max = 1024,
1494 .fifo_size = 0,
1495};
1496
1497
1498
1499
1500
1501static int snd_wss_playback_open(struct snd_pcm_substream *substream)
1502{
1503 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1504 struct snd_pcm_runtime *runtime = substream->runtime;
1505 int err;
1506
1507 runtime->hw = snd_wss_playback;
1508
1509
1510 if (chip->hardware & WSS_HW_AD1848_MASK)
1511 runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
1512 SNDRV_PCM_FMTBIT_S16_BE);
1513
1514
1515 if (chip->hardware == WSS_HW_INTERWAVE && chip->dma1 > 3)
1516 runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW;
1517
1518
1519 if (chip->hardware == WSS_HW_CS4235 ||
1520 chip->hardware == WSS_HW_CS4239)
1521 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1522
1523 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
1524 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
1525
1526 if (chip->claim_dma) {
1527 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
1528 return err;
1529 }
1530
1531 err = snd_wss_open(chip, WSS_MODE_PLAY);
1532 if (err < 0) {
1533 if (chip->release_dma)
1534 chip->release_dma(chip, chip->dma_private_data, chip->dma1);
1535 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1536 return err;
1537 }
1538 chip->playback_substream = substream;
1539 snd_pcm_set_sync(substream);
1540 chip->rate_constraint(runtime);
1541 return 0;
1542}
1543
1544static int snd_wss_capture_open(struct snd_pcm_substream *substream)
1545{
1546 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1547 struct snd_pcm_runtime *runtime = substream->runtime;
1548 int err;
1549
1550 runtime->hw = snd_wss_capture;
1551
1552
1553 if (chip->hardware & WSS_HW_AD1848_MASK)
1554 runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
1555 SNDRV_PCM_FMTBIT_S16_BE);
1556
1557
1558 if (chip->hardware == WSS_HW_CS4235 ||
1559 chip->hardware == WSS_HW_CS4239 ||
1560 chip->hardware == WSS_HW_OPTI93X)
1561 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 |
1562 SNDRV_PCM_FMTBIT_S16_LE;
1563
1564 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1565 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
1566
1567 if (chip->claim_dma) {
1568 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
1569 return err;
1570 }
1571
1572 err = snd_wss_open(chip, WSS_MODE_RECORD);
1573 if (err < 0) {
1574 if (chip->release_dma)
1575 chip->release_dma(chip, chip->dma_private_data, chip->dma2);
1576 snd_free_pages(runtime->dma_area, runtime->dma_bytes);
1577 return err;
1578 }
1579 chip->capture_substream = substream;
1580 snd_pcm_set_sync(substream);
1581 chip->rate_constraint(runtime);
1582 return 0;
1583}
1584
1585static int snd_wss_playback_close(struct snd_pcm_substream *substream)
1586{
1587 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1588
1589 chip->playback_substream = NULL;
1590 snd_wss_close(chip, WSS_MODE_PLAY);
1591 return 0;
1592}
1593
1594static int snd_wss_capture_close(struct snd_pcm_substream *substream)
1595{
1596 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1597
1598 chip->capture_substream = NULL;
1599 snd_wss_close(chip, WSS_MODE_RECORD);
1600 return 0;
1601}
1602
1603static void snd_wss_thinkpad_twiddle(struct snd_wss *chip, int on)
1604{
1605 int tmp;
1606
1607 if (!chip->thinkpad_flag)
1608 return;
1609
1610 outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
1611 tmp = inb(AD1848_THINKPAD_CTL_PORT2);
1612
1613 if (on)
1614
1615 tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
1616 else
1617
1618 tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
1619
1620 outb(tmp, AD1848_THINKPAD_CTL_PORT2);
1621}
1622
1623#ifdef CONFIG_PM
1624
1625
1626static void snd_wss_suspend(struct snd_wss *chip)
1627{
1628 int reg;
1629 unsigned long flags;
1630
1631 snd_pcm_suspend_all(chip->pcm);
1632 spin_lock_irqsave(&chip->reg_lock, flags);
1633 for (reg = 0; reg < 32; reg++)
1634 chip->image[reg] = snd_wss_in(chip, reg);
1635 spin_unlock_irqrestore(&chip->reg_lock, flags);
1636 if (chip->thinkpad_flag)
1637 snd_wss_thinkpad_twiddle(chip, 0);
1638}
1639
1640
1641static void snd_wss_resume(struct snd_wss *chip)
1642{
1643 int reg;
1644 unsigned long flags;
1645
1646
1647 if (chip->thinkpad_flag)
1648 snd_wss_thinkpad_twiddle(chip, 1);
1649 snd_wss_mce_up(chip);
1650 spin_lock_irqsave(&chip->reg_lock, flags);
1651 for (reg = 0; reg < 32; reg++) {
1652 switch (reg) {
1653 case CS4231_VERSION:
1654 break;
1655 default:
1656 snd_wss_out(chip, reg, chip->image[reg]);
1657 break;
1658 }
1659 }
1660 spin_unlock_irqrestore(&chip->reg_lock, flags);
1661#if 1
1662 snd_wss_mce_down(chip);
1663#else
1664
1665
1666
1667
1668 snd_wss_busy_wait(chip);
1669 spin_lock_irqsave(&chip->reg_lock, flags);
1670 chip->mce_bit &= ~CS4231_MCE;
1671 timeout = wss_inb(chip, CS4231P(REGSEL));
1672 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
1673 spin_unlock_irqrestore(&chip->reg_lock, flags);
1674 if (timeout == 0x80)
1675 snd_printk(KERN_ERR "down [0x%lx]: serious init problem "
1676 "- codec still busy\n", chip->port);
1677 if ((timeout & CS4231_MCE) == 0 ||
1678 !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) {
1679 return;
1680 }
1681 snd_wss_busy_wait(chip);
1682#endif
1683}
1684#endif
1685
1686static int snd_wss_free(struct snd_wss *chip)
1687{
1688 release_and_free_resource(chip->res_port);
1689 release_and_free_resource(chip->res_cport);
1690 if (chip->irq >= 0) {
1691 disable_irq(chip->irq);
1692 if (!(chip->hwshare & WSS_HWSHARE_IRQ))
1693 free_irq(chip->irq, (void *) chip);
1694 }
1695 if (!(chip->hwshare & WSS_HWSHARE_DMA1) && chip->dma1 >= 0) {
1696 snd_dma_disable(chip->dma1);
1697 free_dma(chip->dma1);
1698 }
1699 if (!(chip->hwshare & WSS_HWSHARE_DMA2) &&
1700 chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
1701 snd_dma_disable(chip->dma2);
1702 free_dma(chip->dma2);
1703 }
1704 if (chip->timer)
1705 snd_device_free(chip->card, chip->timer);
1706 kfree(chip);
1707 return 0;
1708}
1709
1710static int snd_wss_dev_free(struct snd_device *device)
1711{
1712 struct snd_wss *chip = device->device_data;
1713 return snd_wss_free(chip);
1714}
1715
1716const char *snd_wss_chip_id(struct snd_wss *chip)
1717{
1718 switch (chip->hardware) {
1719 case WSS_HW_CS4231:
1720 return "CS4231";
1721 case WSS_HW_CS4231A:
1722 return "CS4231A";
1723 case WSS_HW_CS4232:
1724 return "CS4232";
1725 case WSS_HW_CS4232A:
1726 return "CS4232A";
1727 case WSS_HW_CS4235:
1728 return "CS4235";
1729 case WSS_HW_CS4236:
1730 return "CS4236";
1731 case WSS_HW_CS4236B:
1732 return "CS4236B";
1733 case WSS_HW_CS4237B:
1734 return "CS4237B";
1735 case WSS_HW_CS4238B:
1736 return "CS4238B";
1737 case WSS_HW_CS4239:
1738 return "CS4239";
1739 case WSS_HW_INTERWAVE:
1740 return "AMD InterWave";
1741 case WSS_HW_OPL3SA2:
1742 return chip->card->shortname;
1743 case WSS_HW_AD1845:
1744 return "AD1845";
1745 case WSS_HW_OPTI93X:
1746 return "OPTi 93x";
1747 case WSS_HW_AD1847:
1748 return "AD1847";
1749 case WSS_HW_AD1848:
1750 return "AD1848";
1751 case WSS_HW_CS4248:
1752 return "CS4248";
1753 case WSS_HW_CMI8330:
1754 return "CMI8330/C3D";
1755 default:
1756 return "???";
1757 }
1758}
1759EXPORT_SYMBOL(snd_wss_chip_id);
1760
1761static int snd_wss_new(struct snd_card *card,
1762 unsigned short hardware,
1763 unsigned short hwshare,
1764 struct snd_wss **rchip)
1765{
1766 struct snd_wss *chip;
1767
1768 *rchip = NULL;
1769 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1770 if (chip == NULL)
1771 return -ENOMEM;
1772 chip->hardware = hardware;
1773 chip->hwshare = hwshare;
1774
1775 spin_lock_init(&chip->reg_lock);
1776 mutex_init(&chip->mce_mutex);
1777 mutex_init(&chip->open_mutex);
1778 chip->card = card;
1779 chip->rate_constraint = snd_wss_xrate;
1780 chip->set_playback_format = snd_wss_playback_format;
1781 chip->set_capture_format = snd_wss_capture_format;
1782 if (chip->hardware == WSS_HW_OPTI93X)
1783 memcpy(&chip->image, &snd_opti93x_original_image,
1784 sizeof(snd_opti93x_original_image));
1785 else
1786 memcpy(&chip->image, &snd_wss_original_image,
1787 sizeof(snd_wss_original_image));
1788 if (chip->hardware & WSS_HW_AD1848_MASK) {
1789 chip->image[CS4231_PIN_CTRL] = 0;
1790 chip->image[CS4231_TEST_INIT] = 0;
1791 }
1792
1793 *rchip = chip;
1794 return 0;
1795}
1796
1797int snd_wss_create(struct snd_card *card,
1798 unsigned long port,
1799 unsigned long cport,
1800 int irq, int dma1, int dma2,
1801 unsigned short hardware,
1802 unsigned short hwshare,
1803 struct snd_wss **rchip)
1804{
1805 static struct snd_device_ops ops = {
1806 .dev_free = snd_wss_dev_free,
1807 };
1808 struct snd_wss *chip;
1809 int err;
1810
1811 err = snd_wss_new(card, hardware, hwshare, &chip);
1812 if (err < 0)
1813 return err;
1814
1815 chip->irq = -1;
1816 chip->dma1 = -1;
1817 chip->dma2 = -1;
1818
1819 chip->res_port = request_region(port, 4, "WSS");
1820 if (!chip->res_port) {
1821 snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port);
1822 snd_wss_free(chip);
1823 return -EBUSY;
1824 }
1825 chip->port = port;
1826 if ((long)cport >= 0) {
1827 chip->res_cport = request_region(cport, 8, "CS4232 Control");
1828 if (!chip->res_cport) {
1829 snd_printk(KERN_ERR
1830 "wss: can't grab control port 0x%lx\n", cport);
1831 snd_wss_free(chip);
1832 return -ENODEV;
1833 }
1834 }
1835 chip->cport = cport;
1836 if (!(hwshare & WSS_HWSHARE_IRQ))
1837 if (request_irq(irq, snd_wss_interrupt, 0,
1838 "WSS", (void *) chip)) {
1839 snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
1840 snd_wss_free(chip);
1841 return -EBUSY;
1842 }
1843 chip->irq = irq;
1844 if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "WSS - 1")) {
1845 snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1);
1846 snd_wss_free(chip);
1847 return -EBUSY;
1848 }
1849 chip->dma1 = dma1;
1850 if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 &&
1851 dma2 >= 0 && request_dma(dma2, "WSS - 2")) {
1852 snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2);
1853 snd_wss_free(chip);
1854 return -EBUSY;
1855 }
1856 if (dma1 == dma2 || dma2 < 0) {
1857 chip->single_dma = 1;
1858 chip->dma2 = chip->dma1;
1859 } else
1860 chip->dma2 = dma2;
1861
1862 if (hardware == WSS_HW_THINKPAD) {
1863 chip->thinkpad_flag = 1;
1864 chip->hardware = WSS_HW_DETECT;
1865 snd_wss_thinkpad_twiddle(chip, 1);
1866 }
1867
1868
1869 if (snd_wss_probe(chip) < 0) {
1870 snd_wss_free(chip);
1871 return -ENODEV;
1872 }
1873 snd_wss_init(chip);
1874
1875#if 0
1876 if (chip->hardware & WSS_HW_CS4232_MASK) {
1877 if (chip->res_cport == NULL)
1878 snd_printk(KERN_ERR "CS4232 control port features are "
1879 "not accessible\n");
1880 }
1881#endif
1882
1883
1884 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1885 if (err < 0) {
1886 snd_wss_free(chip);
1887 return err;
1888 }
1889
1890#ifdef CONFIG_PM
1891
1892 chip->suspend = snd_wss_suspend;
1893 chip->resume = snd_wss_resume;
1894#endif
1895
1896 *rchip = chip;
1897 return 0;
1898}
1899EXPORT_SYMBOL(snd_wss_create);
1900
1901static struct snd_pcm_ops snd_wss_playback_ops = {
1902 .open = snd_wss_playback_open,
1903 .close = snd_wss_playback_close,
1904 .ioctl = snd_pcm_lib_ioctl,
1905 .hw_params = snd_wss_playback_hw_params,
1906 .hw_free = snd_wss_playback_hw_free,
1907 .prepare = snd_wss_playback_prepare,
1908 .trigger = snd_wss_trigger,
1909 .pointer = snd_wss_playback_pointer,
1910};
1911
1912static struct snd_pcm_ops snd_wss_capture_ops = {
1913 .open = snd_wss_capture_open,
1914 .close = snd_wss_capture_close,
1915 .ioctl = snd_pcm_lib_ioctl,
1916 .hw_params = snd_wss_capture_hw_params,
1917 .hw_free = snd_wss_capture_hw_free,
1918 .prepare = snd_wss_capture_prepare,
1919 .trigger = snd_wss_trigger,
1920 .pointer = snd_wss_capture_pointer,
1921};
1922
1923int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
1924{
1925 struct snd_pcm *pcm;
1926 int err;
1927
1928 err = snd_pcm_new(chip->card, "WSS", device, 1, 1, &pcm);
1929 if (err < 0)
1930 return err;
1931
1932 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops);
1933 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops);
1934
1935
1936 pcm->private_data = chip;
1937 pcm->info_flags = 0;
1938 if (chip->single_dma)
1939 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
1940 if (chip->hardware != WSS_HW_INTERWAVE)
1941 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1942 strcpy(pcm->name, snd_wss_chip_id(chip));
1943
1944 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1945 snd_dma_isa_data(),
1946 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
1947
1948 chip->pcm = pcm;
1949 if (rpcm)
1950 *rpcm = pcm;
1951 return 0;
1952}
1953EXPORT_SYMBOL(snd_wss_pcm);
1954
1955static void snd_wss_timer_free(struct snd_timer *timer)
1956{
1957 struct snd_wss *chip = timer->private_data;
1958 chip->timer = NULL;
1959}
1960
1961int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer)
1962{
1963 struct snd_timer *timer;
1964 struct snd_timer_id tid;
1965 int err;
1966
1967
1968 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1969 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1970 tid.card = chip->card->number;
1971 tid.device = device;
1972 tid.subdevice = 0;
1973 if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
1974 return err;
1975 strcpy(timer->name, snd_wss_chip_id(chip));
1976 timer->private_data = chip;
1977 timer->private_free = snd_wss_timer_free;
1978 timer->hw = snd_wss_timer_table;
1979 chip->timer = timer;
1980 if (rtimer)
1981 *rtimer = timer;
1982 return 0;
1983}
1984EXPORT_SYMBOL(snd_wss_timer);
1985
1986
1987
1988
1989
1990static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
1991 struct snd_ctl_elem_info *uinfo)
1992{
1993 static char *texts[4] = {
1994 "Line", "Aux", "Mic", "Mix"
1995 };
1996 static char *opl3sa_texts[4] = {
1997 "Line", "CD", "Mic", "Mix"
1998 };
1999 static char *gusmax_texts[4] = {
2000 "Line", "Synth", "Mic", "Mix"
2001 };
2002 char **ptexts = texts;
2003 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2004
2005 if (snd_BUG_ON(!chip->card))
2006 return -EINVAL;
2007 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2008 uinfo->count = 2;
2009 uinfo->value.enumerated.items = 4;
2010 if (uinfo->value.enumerated.item > 3)
2011 uinfo->value.enumerated.item = 3;
2012 if (!strcmp(chip->card->driver, "GUS MAX"))
2013 ptexts = gusmax_texts;
2014 switch (chip->hardware) {
2015 case WSS_HW_INTERWAVE:
2016 ptexts = gusmax_texts;
2017 break;
2018 case WSS_HW_OPTI93X:
2019 case WSS_HW_OPL3SA2:
2020 ptexts = opl3sa_texts;
2021 break;
2022 }
2023 strcpy(uinfo->value.enumerated.name, ptexts[uinfo->value.enumerated.item]);
2024 return 0;
2025}
2026
2027static int snd_wss_get_mux(struct snd_kcontrol *kcontrol,
2028 struct snd_ctl_elem_value *ucontrol)
2029{
2030 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2031 unsigned long flags;
2032
2033 spin_lock_irqsave(&chip->reg_lock, flags);
2034 ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
2035 ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
2036 spin_unlock_irqrestore(&chip->reg_lock, flags);
2037 return 0;
2038}
2039
2040static int snd_wss_put_mux(struct snd_kcontrol *kcontrol,
2041 struct snd_ctl_elem_value *ucontrol)
2042{
2043 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2044 unsigned long flags;
2045 unsigned short left, right;
2046 int change;
2047
2048 if (ucontrol->value.enumerated.item[0] > 3 ||
2049 ucontrol->value.enumerated.item[1] > 3)
2050 return -EINVAL;
2051 left = ucontrol->value.enumerated.item[0] << 6;
2052 right = ucontrol->value.enumerated.item[1] << 6;
2053 spin_lock_irqsave(&chip->reg_lock, flags);
2054 left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
2055 right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
2056 change = left != chip->image[CS4231_LEFT_INPUT] ||
2057 right != chip->image[CS4231_RIGHT_INPUT];
2058 snd_wss_out(chip, CS4231_LEFT_INPUT, left);
2059 snd_wss_out(chip, CS4231_RIGHT_INPUT, right);
2060 spin_unlock_irqrestore(&chip->reg_lock, flags);
2061 return change;
2062}
2063
2064int snd_wss_info_single(struct snd_kcontrol *kcontrol,
2065 struct snd_ctl_elem_info *uinfo)
2066{
2067 int mask = (kcontrol->private_value >> 16) & 0xff;
2068
2069 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2070 uinfo->count = 1;
2071 uinfo->value.integer.min = 0;
2072 uinfo->value.integer.max = mask;
2073 return 0;
2074}
2075EXPORT_SYMBOL(snd_wss_info_single);
2076
2077int snd_wss_get_single(struct snd_kcontrol *kcontrol,
2078 struct snd_ctl_elem_value *ucontrol)
2079{
2080 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2081 unsigned long flags;
2082 int reg = kcontrol->private_value & 0xff;
2083 int shift = (kcontrol->private_value >> 8) & 0xff;
2084 int mask = (kcontrol->private_value >> 16) & 0xff;
2085 int invert = (kcontrol->private_value >> 24) & 0xff;
2086
2087 spin_lock_irqsave(&chip->reg_lock, flags);
2088 ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
2089 spin_unlock_irqrestore(&chip->reg_lock, flags);
2090 if (invert)
2091 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2092 return 0;
2093}
2094EXPORT_SYMBOL(snd_wss_get_single);
2095
2096int snd_wss_put_single(struct snd_kcontrol *kcontrol,
2097 struct snd_ctl_elem_value *ucontrol)
2098{
2099 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2100 unsigned long flags;
2101 int reg = kcontrol->private_value & 0xff;
2102 int shift = (kcontrol->private_value >> 8) & 0xff;
2103 int mask = (kcontrol->private_value >> 16) & 0xff;
2104 int invert = (kcontrol->private_value >> 24) & 0xff;
2105 int change;
2106 unsigned short val;
2107
2108 val = (ucontrol->value.integer.value[0] & mask);
2109 if (invert)
2110 val = mask - val;
2111 val <<= shift;
2112 spin_lock_irqsave(&chip->reg_lock, flags);
2113 val = (chip->image[reg] & ~(mask << shift)) | val;
2114 change = val != chip->image[reg];
2115 snd_wss_out(chip, reg, val);
2116 spin_unlock_irqrestore(&chip->reg_lock, flags);
2117 return change;
2118}
2119EXPORT_SYMBOL(snd_wss_put_single);
2120
2121int snd_wss_info_double(struct snd_kcontrol *kcontrol,
2122 struct snd_ctl_elem_info *uinfo)
2123{
2124 int mask = (kcontrol->private_value >> 24) & 0xff;
2125
2126 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2127 uinfo->count = 2;
2128 uinfo->value.integer.min = 0;
2129 uinfo->value.integer.max = mask;
2130 return 0;
2131}
2132EXPORT_SYMBOL(snd_wss_info_double);
2133
2134int snd_wss_get_double(struct snd_kcontrol *kcontrol,
2135 struct snd_ctl_elem_value *ucontrol)
2136{
2137 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2138 unsigned long flags;
2139 int left_reg = kcontrol->private_value & 0xff;
2140 int right_reg = (kcontrol->private_value >> 8) & 0xff;
2141 int shift_left = (kcontrol->private_value >> 16) & 0x07;
2142 int shift_right = (kcontrol->private_value >> 19) & 0x07;
2143 int mask = (kcontrol->private_value >> 24) & 0xff;
2144 int invert = (kcontrol->private_value >> 22) & 1;
2145
2146 spin_lock_irqsave(&chip->reg_lock, flags);
2147 ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
2148 ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
2149 spin_unlock_irqrestore(&chip->reg_lock, flags);
2150 if (invert) {
2151 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2152 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
2153 }
2154 return 0;
2155}
2156EXPORT_SYMBOL(snd_wss_get_double);
2157
2158int snd_wss_put_double(struct snd_kcontrol *kcontrol,
2159 struct snd_ctl_elem_value *ucontrol)
2160{
2161 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2162 unsigned long flags;
2163 int left_reg = kcontrol->private_value & 0xff;
2164 int right_reg = (kcontrol->private_value >> 8) & 0xff;
2165 int shift_left = (kcontrol->private_value >> 16) & 0x07;
2166 int shift_right = (kcontrol->private_value >> 19) & 0x07;
2167 int mask = (kcontrol->private_value >> 24) & 0xff;
2168 int invert = (kcontrol->private_value >> 22) & 1;
2169 int change;
2170 unsigned short val1, val2;
2171
2172 val1 = ucontrol->value.integer.value[0] & mask;
2173 val2 = ucontrol->value.integer.value[1] & mask;
2174 if (invert) {
2175 val1 = mask - val1;
2176 val2 = mask - val2;
2177 }
2178 val1 <<= shift_left;
2179 val2 <<= shift_right;
2180 spin_lock_irqsave(&chip->reg_lock, flags);
2181 if (left_reg != right_reg) {
2182 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
2183 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
2184 change = val1 != chip->image[left_reg] ||
2185 val2 != chip->image[right_reg];
2186 snd_wss_out(chip, left_reg, val1);
2187 snd_wss_out(chip, right_reg, val2);
2188 } else {
2189 mask = (mask << shift_left) | (mask << shift_right);
2190 val1 = (chip->image[left_reg] & ~mask) | val1 | val2;
2191 change = val1 != chip->image[left_reg];
2192 snd_wss_out(chip, left_reg, val1);
2193 }
2194 spin_unlock_irqrestore(&chip->reg_lock, flags);
2195 return change;
2196}
2197EXPORT_SYMBOL(snd_wss_put_double);
2198
2199static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
2200static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
2201static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
2202static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
2203
2204static struct snd_kcontrol_new snd_wss_controls[] = {
2205WSS_DOUBLE("PCM Playback Switch", 0,
2206 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2207WSS_DOUBLE_TLV("PCM Playback Volume", 0,
2208 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
2209 db_scale_6bit),
2210WSS_DOUBLE("Aux Playback Switch", 0,
2211 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2212WSS_DOUBLE_TLV("Aux Playback Volume", 0,
2213 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
2214 db_scale_5bit_12db_max),
2215WSS_DOUBLE("Aux Playback Switch", 1,
2216 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2217WSS_DOUBLE_TLV("Aux Playback Volume", 1,
2218 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
2219 db_scale_5bit_12db_max),
2220WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
2221 0, 0, 15, 0, db_scale_rec_gain),
2222{
2223 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2224 .name = "Capture Source",
2225 .info = snd_wss_info_mux,
2226 .get = snd_wss_get_mux,
2227 .put = snd_wss_put_mux,
2228},
2229WSS_DOUBLE("Mic Boost (+20dB)", 0,
2230 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2231WSS_SINGLE("Loopback Capture Switch", 0,
2232 CS4231_LOOPBACK, 0, 1, 0),
2233WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1,
2234 db_scale_6bit),
2235WSS_DOUBLE("Line Playback Switch", 0,
2236 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2237WSS_DOUBLE_TLV("Line Playback Volume", 0,
2238 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
2239 db_scale_5bit_12db_max),
2240WSS_SINGLE("Beep Playback Switch", 0,
2241 CS4231_MONO_CTRL, 7, 1, 1),
2242WSS_SINGLE_TLV("Beep Playback Volume", 0,
2243 CS4231_MONO_CTRL, 0, 15, 1,
2244 db_scale_4bit),
2245WSS_SINGLE("Mono Output Playback Switch", 0,
2246 CS4231_MONO_CTRL, 6, 1, 1),
2247WSS_SINGLE("Beep Bypass Playback Switch", 0,
2248 CS4231_MONO_CTRL, 5, 1, 0),
2249};
2250
2251int snd_wss_mixer(struct snd_wss *chip)
2252{
2253 struct snd_card *card;
2254 unsigned int idx;
2255 int err;
2256 int count = ARRAY_SIZE(snd_wss_controls);
2257
2258 if (snd_BUG_ON(!chip || !chip->pcm))
2259 return -EINVAL;
2260
2261 card = chip->card;
2262
2263 strcpy(card->mixername, chip->pcm->name);
2264
2265
2266 if (chip->hardware & WSS_HW_AD1848_MASK)
2267 count = 11;
2268
2269 else if (chip->hardware == WSS_HW_OPTI93X)
2270 count = 9;
2271
2272 for (idx = 0; idx < count; idx++) {
2273 err = snd_ctl_add(card,
2274 snd_ctl_new1(&snd_wss_controls[idx],
2275 chip));
2276 if (err < 0)
2277 return err;
2278 }
2279 return 0;
2280}
2281EXPORT_SYMBOL(snd_wss_mixer);
2282
2283const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction)
2284{
2285 return direction == SNDRV_PCM_STREAM_PLAYBACK ?
2286 &snd_wss_playback_ops : &snd_wss_capture_ops;
2287}
2288EXPORT_SYMBOL(snd_wss_get_pcm_ops);
2289
2290
2291
2292
2293
2294static int __init alsa_wss_init(void)
2295{
2296 return 0;
2297}
2298
2299static void __exit alsa_wss_exit(void)
2300{
2301}
2302
2303module_init(alsa_wss_init);
2304module_exit(alsa_wss_exit);
2305