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