This source file includes following definitions.
- snd_wss_xrate
- wss_outb
- wss_inb
- snd_wss_wait
- snd_wss_dout
- snd_wss_out
- snd_wss_in
- snd_cs4236_ext_out
- snd_cs4236_ext_in
- snd_wss_debug
- snd_wss_busy_wait
- snd_wss_mce_up
- snd_wss_mce_down
- snd_wss_get_count
- snd_wss_trigger
- snd_wss_get_rate
- snd_wss_get_format
- snd_wss_calibrate_mute
- snd_wss_playback_format
- snd_wss_capture_format
- snd_wss_timer_resolution
- snd_wss_timer_start
- snd_wss_timer_stop
- snd_wss_init
- snd_wss_open
- snd_wss_close
- snd_wss_timer_open
- snd_wss_timer_close
- snd_wss_playback_hw_params
- snd_wss_playback_hw_free
- snd_wss_playback_prepare
- snd_wss_capture_hw_params
- snd_wss_capture_hw_free
- snd_wss_capture_prepare
- snd_wss_overrange
- snd_wss_interrupt
- snd_wss_playback_pointer
- snd_wss_capture_pointer
- snd_ad1848_probe
- snd_wss_probe
- snd_wss_playback_open
- snd_wss_capture_open
- snd_wss_playback_close
- snd_wss_capture_close
- snd_wss_thinkpad_twiddle
- snd_wss_suspend
- snd_wss_resume
- snd_wss_free
- snd_wss_dev_free
- snd_wss_chip_id
- snd_wss_new
- snd_wss_create
- snd_wss_pcm
- snd_wss_timer_free
- snd_wss_timer
- snd_wss_info_mux
- snd_wss_get_mux
- snd_wss_put_mux
- snd_wss_info_single
- snd_wss_get_single
- snd_wss_put_single
- snd_wss_info_double
- snd_wss_get_double
- snd_wss_put_double
- snd_wss_mixer
- snd_wss_get_pcm_ops
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
29 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
30 MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
31 MODULE_LICENSE("GPL");
32
33 #if 0
34 #define SNDRV_DEBUG_MCE
35 #endif
36
37
38
39
40
41 static 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
58 static const unsigned int rates[14] = {
59 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
60 27042, 32000, 33075, 37800, 44100, 48000
61 };
62
63 static const struct snd_pcm_hw_constraint_list hw_constraints_rates = {
64 .count = ARRAY_SIZE(rates),
65 .list = rates,
66 .mask = 0,
67 };
68
69 static 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
75 static 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
111 static 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
151 static inline void wss_outb(struct snd_wss *chip, u8 offset, u8 val)
152 {
153 outb(val, chip->port + offset);
154 }
155
156 static inline u8 wss_inb(struct snd_wss *chip, u8 offset)
157 {
158 return inb(chip->port + offset);
159 }
160
161 static 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
171 static 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
185 void 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 }
200 EXPORT_SYMBOL(snd_wss_out);
201
202 unsigned 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 }
214 EXPORT_SYMBOL(snd_wss_in);
215
216 void 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 }
228 EXPORT_SYMBOL(snd_cs4236_ext_out);
229
230 unsigned 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 }
247 EXPORT_SYMBOL(snd_cs4236_ext_in);
248
249 #if 0
250
251 static 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
346 static 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
360 void 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 }
383 EXPORT_SYMBOL(snd_wss_mce_up);
384
385 void 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 }
449 EXPORT_SYMBOL(snd_wss_mce_down);
450
451 static 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
466 static 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
518 static 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
529 static 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
551 static 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
611 static 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
672 static 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
743 static 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
752 static 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
776 static 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
788 static 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
858 static 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
900 static 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
950 static 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
957 static 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
964 static 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
980 static 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 int err;
986
987 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
988 return err;
989 new_pdfr = snd_wss_get_format(chip, params_format(hw_params),
990 params_channels(hw_params)) |
991 snd_wss_get_rate(params_rate(hw_params));
992 chip->set_playback_format(chip, hw_params, new_pdfr);
993 return 0;
994 }
995
996 static int snd_wss_playback_hw_free(struct snd_pcm_substream *substream)
997 {
998 return snd_pcm_lib_free_pages(substream);
999 }
1000
1001 static int snd_wss_playback_prepare(struct snd_pcm_substream *substream)
1002 {
1003 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1004 struct snd_pcm_runtime *runtime = substream->runtime;
1005 unsigned long flags;
1006 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1007 unsigned int count = snd_pcm_lib_period_bytes(substream);
1008
1009 spin_lock_irqsave(&chip->reg_lock, flags);
1010 chip->p_dma_size = size;
1011 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE | CS4231_PLAYBACK_PIO);
1012 snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
1013 count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT], count) - 1;
1014 snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
1015 snd_wss_out(chip, CS4231_PLY_UPR_CNT, (unsigned char) (count >> 8));
1016 spin_unlock_irqrestore(&chip->reg_lock, flags);
1017 #if 0
1018 snd_wss_debug(chip);
1019 #endif
1020 return 0;
1021 }
1022
1023 static int snd_wss_capture_hw_params(struct snd_pcm_substream *substream,
1024 struct snd_pcm_hw_params *hw_params)
1025 {
1026 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1027 unsigned char new_cdfr;
1028 int err;
1029
1030 if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
1031 return err;
1032 new_cdfr = snd_wss_get_format(chip, params_format(hw_params),
1033 params_channels(hw_params)) |
1034 snd_wss_get_rate(params_rate(hw_params));
1035 chip->set_capture_format(chip, hw_params, new_cdfr);
1036 return 0;
1037 }
1038
1039 static int snd_wss_capture_hw_free(struct snd_pcm_substream *substream)
1040 {
1041 return snd_pcm_lib_free_pages(substream);
1042 }
1043
1044 static int snd_wss_capture_prepare(struct snd_pcm_substream *substream)
1045 {
1046 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1047 struct snd_pcm_runtime *runtime = substream->runtime;
1048 unsigned long flags;
1049 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1050 unsigned int count = snd_pcm_lib_period_bytes(substream);
1051
1052 spin_lock_irqsave(&chip->reg_lock, flags);
1053 chip->c_dma_size = size;
1054 chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE | CS4231_RECORD_PIO);
1055 snd_dma_program(chip->dma2, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
1056 if (chip->hardware & WSS_HW_AD1848_MASK)
1057 count = snd_wss_get_count(chip->image[CS4231_PLAYBK_FORMAT],
1058 count);
1059 else
1060 count = snd_wss_get_count(chip->image[CS4231_REC_FORMAT],
1061 count);
1062 count--;
1063 if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
1064 snd_wss_out(chip, CS4231_PLY_LWR_CNT, (unsigned char) count);
1065 snd_wss_out(chip, CS4231_PLY_UPR_CNT,
1066 (unsigned char) (count >> 8));
1067 } else {
1068 snd_wss_out(chip, CS4231_REC_LWR_CNT, (unsigned char) count);
1069 snd_wss_out(chip, CS4231_REC_UPR_CNT,
1070 (unsigned char) (count >> 8));
1071 }
1072 spin_unlock_irqrestore(&chip->reg_lock, flags);
1073 return 0;
1074 }
1075
1076 void snd_wss_overrange(struct snd_wss *chip)
1077 {
1078 unsigned long flags;
1079 unsigned char res;
1080
1081 spin_lock_irqsave(&chip->reg_lock, flags);
1082 res = snd_wss_in(chip, CS4231_TEST_INIT);
1083 spin_unlock_irqrestore(&chip->reg_lock, flags);
1084 if (res & (0x08 | 0x02))
1085 chip->capture_substream->runtime->overrange++;
1086 }
1087 EXPORT_SYMBOL(snd_wss_overrange);
1088
1089 irqreturn_t snd_wss_interrupt(int irq, void *dev_id)
1090 {
1091 struct snd_wss *chip = dev_id;
1092 unsigned char status;
1093
1094 if (chip->hardware & WSS_HW_AD1848_MASK)
1095
1096 status = CS4231_PLAYBACK_IRQ;
1097 else
1098 status = snd_wss_in(chip, CS4231_IRQ_STATUS);
1099 if (status & CS4231_TIMER_IRQ) {
1100 if (chip->timer)
1101 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1102 }
1103 if (chip->single_dma && chip->hardware != WSS_HW_INTERWAVE) {
1104 if (status & CS4231_PLAYBACK_IRQ) {
1105 if (chip->mode & WSS_MODE_PLAY) {
1106 if (chip->playback_substream)
1107 snd_pcm_period_elapsed(chip->playback_substream);
1108 }
1109 if (chip->mode & WSS_MODE_RECORD) {
1110 if (chip->capture_substream) {
1111 snd_wss_overrange(chip);
1112 snd_pcm_period_elapsed(chip->capture_substream);
1113 }
1114 }
1115 }
1116 } else {
1117 if (status & CS4231_PLAYBACK_IRQ) {
1118 if (chip->playback_substream)
1119 snd_pcm_period_elapsed(chip->playback_substream);
1120 }
1121 if (status & CS4231_RECORD_IRQ) {
1122 if (chip->capture_substream) {
1123 snd_wss_overrange(chip);
1124 snd_pcm_period_elapsed(chip->capture_substream);
1125 }
1126 }
1127 }
1128
1129 spin_lock(&chip->reg_lock);
1130 status = ~CS4231_ALL_IRQS | ~status;
1131 if (chip->hardware & WSS_HW_AD1848_MASK)
1132 wss_outb(chip, CS4231P(STATUS), 0);
1133 else
1134 snd_wss_out(chip, CS4231_IRQ_STATUS, status);
1135 spin_unlock(&chip->reg_lock);
1136 return IRQ_HANDLED;
1137 }
1138 EXPORT_SYMBOL(snd_wss_interrupt);
1139
1140 static snd_pcm_uframes_t snd_wss_playback_pointer(struct snd_pcm_substream *substream)
1141 {
1142 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1143 size_t ptr;
1144
1145 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
1146 return 0;
1147 ptr = snd_dma_pointer(chip->dma1, chip->p_dma_size);
1148 return bytes_to_frames(substream->runtime, ptr);
1149 }
1150
1151 static snd_pcm_uframes_t snd_wss_capture_pointer(struct snd_pcm_substream *substream)
1152 {
1153 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1154 size_t ptr;
1155
1156 if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
1157 return 0;
1158 ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
1159 return bytes_to_frames(substream->runtime, ptr);
1160 }
1161
1162
1163
1164
1165
1166 static int snd_ad1848_probe(struct snd_wss *chip)
1167 {
1168 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
1169 unsigned long flags;
1170 unsigned char r;
1171 unsigned short hardware = 0;
1172 int err = 0;
1173 int i;
1174
1175 while (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT) {
1176 if (time_after(jiffies, timeout))
1177 return -ENODEV;
1178 cond_resched();
1179 }
1180 spin_lock_irqsave(&chip->reg_lock, flags);
1181
1182
1183 snd_wss_dout(chip, CS4231_MISC_INFO, 0);
1184
1185 snd_wss_dout(chip, CS4231_RIGHT_INPUT, 0x45);
1186 r = snd_wss_in(chip, CS4231_RIGHT_INPUT);
1187 if (r != 0x45) {
1188
1189 if ((r & ~CS4231_ENABLE_MIC_GAIN) != 0x45) {
1190 err = -ENODEV;
1191 goto out;
1192 }
1193 hardware = WSS_HW_AD1847;
1194 } else {
1195 snd_wss_dout(chip, CS4231_LEFT_INPUT, 0xaa);
1196 r = snd_wss_in(chip, CS4231_LEFT_INPUT);
1197
1198 if ((r | CS4231_ENABLE_MIC_GAIN) != 0xaa) {
1199 err = -ENODEV;
1200 goto out;
1201 }
1202 }
1203
1204
1205 wss_inb(chip, CS4231P(STATUS));
1206 wss_outb(chip, CS4231P(STATUS), 0);
1207 mb();
1208
1209 if ((chip->hardware & WSS_HW_TYPE_MASK) != WSS_HW_DETECT)
1210 goto out;
1211
1212 if (hardware) {
1213 chip->hardware = hardware;
1214 goto out;
1215 }
1216
1217 r = snd_wss_in(chip, CS4231_MISC_INFO);
1218
1219
1220 snd_wss_dout(chip, CS4231_MISC_INFO, CS4231_MODE2);
1221 for (i = 0; i < 16; i++) {
1222 if (snd_wss_in(chip, i) != snd_wss_in(chip, 16 + i)) {
1223
1224 if ((r & 0xf) != 0xa)
1225 goto out_mode;
1226
1227
1228
1229
1230 snd_wss_dout(chip, CS4231_VERSION, 0);
1231 r = snd_wss_in(chip, CS4231_VERSION) & 0xe7;
1232 if (!r)
1233 chip->hardware = WSS_HW_CMI8330;
1234 goto out_mode;
1235 }
1236 }
1237 if (r & 0x80)
1238 chip->hardware = WSS_HW_CS4248;
1239 else
1240 chip->hardware = WSS_HW_AD1848;
1241 out_mode:
1242 snd_wss_dout(chip, CS4231_MISC_INFO, 0);
1243 out:
1244 spin_unlock_irqrestore(&chip->reg_lock, flags);
1245 return err;
1246 }
1247
1248 static int snd_wss_probe(struct snd_wss *chip)
1249 {
1250 unsigned long flags;
1251 int i, id, rev, regnum;
1252 unsigned char *ptr;
1253 unsigned int hw;
1254
1255 id = snd_ad1848_probe(chip);
1256 if (id < 0)
1257 return id;
1258
1259 hw = chip->hardware;
1260 if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
1261 for (i = 0; i < 50; i++) {
1262 mb();
1263 if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
1264 msleep(2);
1265 else {
1266 spin_lock_irqsave(&chip->reg_lock, flags);
1267 snd_wss_out(chip, CS4231_MISC_INFO,
1268 CS4231_MODE2);
1269 id = snd_wss_in(chip, CS4231_MISC_INFO) & 0x0f;
1270 spin_unlock_irqrestore(&chip->reg_lock, flags);
1271 if (id == 0x0a)
1272 break;
1273 }
1274 }
1275 snd_printdd("wss: port = 0x%lx, id = 0x%x\n", chip->port, id);
1276 if (id != 0x0a)
1277 return -ENODEV;
1278
1279 rev = snd_wss_in(chip, CS4231_VERSION) & 0xe7;
1280 snd_printdd("CS4231: VERSION (I25) = 0x%x\n", rev);
1281 if (rev == 0x80) {
1282 unsigned char tmp = snd_wss_in(chip, 23);
1283 snd_wss_out(chip, 23, ~tmp);
1284 if (snd_wss_in(chip, 23) != tmp)
1285 chip->hardware = WSS_HW_AD1845;
1286 else
1287 chip->hardware = WSS_HW_CS4231;
1288 } else if (rev == 0xa0) {
1289 chip->hardware = WSS_HW_CS4231A;
1290 } else if (rev == 0xa2) {
1291 chip->hardware = WSS_HW_CS4232;
1292 } else if (rev == 0xb2) {
1293 chip->hardware = WSS_HW_CS4232A;
1294 } else if (rev == 0x83) {
1295 chip->hardware = WSS_HW_CS4236;
1296 } else if (rev == 0x03) {
1297 chip->hardware = WSS_HW_CS4236B;
1298 } else {
1299 snd_printk(KERN_ERR
1300 "unknown CS chip with version 0x%x\n", rev);
1301 return -ENODEV;
1302 }
1303 }
1304 spin_lock_irqsave(&chip->reg_lock, flags);
1305 wss_inb(chip, CS4231P(STATUS));
1306 wss_outb(chip, CS4231P(STATUS), 0);
1307 mb();
1308 spin_unlock_irqrestore(&chip->reg_lock, flags);
1309
1310 if (!(chip->hardware & WSS_HW_AD1848_MASK))
1311 chip->image[CS4231_MISC_INFO] = CS4231_MODE2;
1312 switch (chip->hardware) {
1313 case WSS_HW_INTERWAVE:
1314 chip->image[CS4231_MISC_INFO] = CS4231_IW_MODE3;
1315 break;
1316 case WSS_HW_CS4235:
1317 case WSS_HW_CS4236B:
1318 case WSS_HW_CS4237B:
1319 case WSS_HW_CS4238B:
1320 case WSS_HW_CS4239:
1321 if (hw == WSS_HW_DETECT3)
1322 chip->image[CS4231_MISC_INFO] = CS4231_4236_MODE3;
1323 else
1324 chip->hardware = WSS_HW_CS4236;
1325 break;
1326 }
1327
1328 chip->image[CS4231_IFACE_CTRL] =
1329 (chip->image[CS4231_IFACE_CTRL] & ~CS4231_SINGLE_DMA) |
1330 (chip->single_dma ? CS4231_SINGLE_DMA : 0);
1331 if (chip->hardware != WSS_HW_OPTI93X) {
1332 chip->image[CS4231_ALT_FEATURE_1] = 0x80;
1333 chip->image[CS4231_ALT_FEATURE_2] =
1334 chip->hardware == WSS_HW_INTERWAVE ? 0xc2 : 0x01;
1335 }
1336
1337 if (chip->hardware == WSS_HW_AD1845)
1338 chip->image[AD1845_PWR_DOWN] = 8;
1339
1340 ptr = (unsigned char *) &chip->image;
1341 regnum = (chip->hardware & WSS_HW_AD1848_MASK) ? 16 : 32;
1342 snd_wss_mce_down(chip);
1343 spin_lock_irqsave(&chip->reg_lock, flags);
1344 for (i = 0; i < regnum; i++)
1345 snd_wss_out(chip, i, *ptr++);
1346 spin_unlock_irqrestore(&chip->reg_lock, flags);
1347 snd_wss_mce_up(chip);
1348 snd_wss_mce_down(chip);
1349
1350 mdelay(2);
1351
1352
1353 if ((hw & WSS_HW_TYPE_MASK) == WSS_HW_DETECT) {
1354 if (chip->hardware == WSS_HW_CS4236B) {
1355 rev = snd_cs4236_ext_in(chip, CS4236_VERSION);
1356 snd_cs4236_ext_out(chip, CS4236_VERSION, 0xff);
1357 id = snd_cs4236_ext_in(chip, CS4236_VERSION);
1358 snd_cs4236_ext_out(chip, CS4236_VERSION, rev);
1359 snd_printdd("CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev, id);
1360 if ((id & 0x1f) == 0x1d) {
1361 chip->hardware = WSS_HW_CS4235;
1362 switch (id >> 5) {
1363 case 4:
1364 case 5:
1365 case 6:
1366 break;
1367 default:
1368 snd_printk(KERN_WARNING
1369 "unknown CS4235 chip "
1370 "(enhanced version = 0x%x)\n",
1371 id);
1372 }
1373 } else if ((id & 0x1f) == 0x0b) {
1374 switch (id >> 5) {
1375 case 4:
1376 case 5:
1377 case 6:
1378 case 7:
1379 chip->hardware = WSS_HW_CS4236B;
1380 break;
1381 default:
1382 snd_printk(KERN_WARNING
1383 "unknown CS4236 chip "
1384 "(enhanced version = 0x%x)\n",
1385 id);
1386 }
1387 } else if ((id & 0x1f) == 0x08) {
1388 chip->hardware = WSS_HW_CS4237B;
1389 switch (id >> 5) {
1390 case 4:
1391 case 5:
1392 case 6:
1393 case 7:
1394 break;
1395 default:
1396 snd_printk(KERN_WARNING
1397 "unknown CS4237B chip "
1398 "(enhanced version = 0x%x)\n",
1399 id);
1400 }
1401 } else if ((id & 0x1f) == 0x09) {
1402 chip->hardware = WSS_HW_CS4238B;
1403 switch (id >> 5) {
1404 case 5:
1405 case 6:
1406 case 7:
1407 break;
1408 default:
1409 snd_printk(KERN_WARNING
1410 "unknown CS4238B chip "
1411 "(enhanced version = 0x%x)\n",
1412 id);
1413 }
1414 } else if ((id & 0x1f) == 0x1e) {
1415 chip->hardware = WSS_HW_CS4239;
1416 switch (id >> 5) {
1417 case 4:
1418 case 5:
1419 case 6:
1420 break;
1421 default:
1422 snd_printk(KERN_WARNING
1423 "unknown CS4239 chip "
1424 "(enhanced version = 0x%x)\n",
1425 id);
1426 }
1427 } else {
1428 snd_printk(KERN_WARNING
1429 "unknown CS4236/CS423xB chip "
1430 "(enhanced version = 0x%x)\n", id);
1431 }
1432 }
1433 }
1434 return 0;
1435 }
1436
1437
1438
1439
1440
1441 static const struct snd_pcm_hardware snd_wss_playback =
1442 {
1443 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1444 SNDRV_PCM_INFO_MMAP_VALID |
1445 SNDRV_PCM_INFO_SYNC_START),
1446 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1447 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1448 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1449 .rate_min = 5510,
1450 .rate_max = 48000,
1451 .channels_min = 1,
1452 .channels_max = 2,
1453 .buffer_bytes_max = (128*1024),
1454 .period_bytes_min = 64,
1455 .period_bytes_max = (128*1024),
1456 .periods_min = 1,
1457 .periods_max = 1024,
1458 .fifo_size = 0,
1459 };
1460
1461 static const struct snd_pcm_hardware snd_wss_capture =
1462 {
1463 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1464 SNDRV_PCM_INFO_MMAP_VALID |
1465 SNDRV_PCM_INFO_RESUME |
1466 SNDRV_PCM_INFO_SYNC_START),
1467 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1468 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
1469 .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
1470 .rate_min = 5510,
1471 .rate_max = 48000,
1472 .channels_min = 1,
1473 .channels_max = 2,
1474 .buffer_bytes_max = (128*1024),
1475 .period_bytes_min = 64,
1476 .period_bytes_max = (128*1024),
1477 .periods_min = 1,
1478 .periods_max = 1024,
1479 .fifo_size = 0,
1480 };
1481
1482
1483
1484
1485
1486 static int snd_wss_playback_open(struct snd_pcm_substream *substream)
1487 {
1488 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1489 struct snd_pcm_runtime *runtime = substream->runtime;
1490 int err;
1491
1492 runtime->hw = snd_wss_playback;
1493
1494
1495 if (chip->hardware & WSS_HW_AD1848_MASK)
1496 runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
1497 SNDRV_PCM_FMTBIT_S16_BE);
1498
1499
1500 if (chip->hardware == WSS_HW_INTERWAVE && chip->dma1 > 3)
1501 runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_MU_LAW;
1502
1503
1504 if (chip->hardware == WSS_HW_CS4235 ||
1505 chip->hardware == WSS_HW_CS4239)
1506 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
1507
1508 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
1509 snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
1510
1511 if (chip->claim_dma) {
1512 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
1513 return err;
1514 }
1515
1516 err = snd_wss_open(chip, WSS_MODE_PLAY);
1517 if (err < 0) {
1518 if (chip->release_dma)
1519 chip->release_dma(chip, chip->dma_private_data, chip->dma1);
1520 return err;
1521 }
1522 chip->playback_substream = substream;
1523 snd_pcm_set_sync(substream);
1524 chip->rate_constraint(runtime);
1525 return 0;
1526 }
1527
1528 static int snd_wss_capture_open(struct snd_pcm_substream *substream)
1529 {
1530 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1531 struct snd_pcm_runtime *runtime = substream->runtime;
1532 int err;
1533
1534 runtime->hw = snd_wss_capture;
1535
1536
1537 if (chip->hardware & WSS_HW_AD1848_MASK)
1538 runtime->hw.formats &= ~(SNDRV_PCM_FMTBIT_IMA_ADPCM |
1539 SNDRV_PCM_FMTBIT_S16_BE);
1540
1541
1542 if (chip->hardware == WSS_HW_CS4235 ||
1543 chip->hardware == WSS_HW_CS4239 ||
1544 chip->hardware == WSS_HW_OPTI93X)
1545 runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 |
1546 SNDRV_PCM_FMTBIT_S16_LE;
1547
1548 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
1549 snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
1550
1551 if (chip->claim_dma) {
1552 if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
1553 return err;
1554 }
1555
1556 err = snd_wss_open(chip, WSS_MODE_RECORD);
1557 if (err < 0) {
1558 if (chip->release_dma)
1559 chip->release_dma(chip, chip->dma_private_data, chip->dma2);
1560 return err;
1561 }
1562 chip->capture_substream = substream;
1563 snd_pcm_set_sync(substream);
1564 chip->rate_constraint(runtime);
1565 return 0;
1566 }
1567
1568 static int snd_wss_playback_close(struct snd_pcm_substream *substream)
1569 {
1570 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1571
1572 chip->playback_substream = NULL;
1573 snd_wss_close(chip, WSS_MODE_PLAY);
1574 return 0;
1575 }
1576
1577 static int snd_wss_capture_close(struct snd_pcm_substream *substream)
1578 {
1579 struct snd_wss *chip = snd_pcm_substream_chip(substream);
1580
1581 chip->capture_substream = NULL;
1582 snd_wss_close(chip, WSS_MODE_RECORD);
1583 return 0;
1584 }
1585
1586 static void snd_wss_thinkpad_twiddle(struct snd_wss *chip, int on)
1587 {
1588 int tmp;
1589
1590 if (!chip->thinkpad_flag)
1591 return;
1592
1593 outb(0x1c, AD1848_THINKPAD_CTL_PORT1);
1594 tmp = inb(AD1848_THINKPAD_CTL_PORT2);
1595
1596 if (on)
1597
1598 tmp |= AD1848_THINKPAD_CS4248_ENABLE_BIT;
1599 else
1600
1601 tmp &= ~AD1848_THINKPAD_CS4248_ENABLE_BIT;
1602
1603 outb(tmp, AD1848_THINKPAD_CTL_PORT2);
1604 }
1605
1606 #ifdef CONFIG_PM
1607
1608
1609 static void snd_wss_suspend(struct snd_wss *chip)
1610 {
1611 int reg;
1612 unsigned long flags;
1613
1614 spin_lock_irqsave(&chip->reg_lock, flags);
1615 for (reg = 0; reg < 32; reg++)
1616 chip->image[reg] = snd_wss_in(chip, reg);
1617 spin_unlock_irqrestore(&chip->reg_lock, flags);
1618 if (chip->thinkpad_flag)
1619 snd_wss_thinkpad_twiddle(chip, 0);
1620 }
1621
1622
1623 static void snd_wss_resume(struct snd_wss *chip)
1624 {
1625 int reg;
1626 unsigned long flags;
1627
1628
1629 if (chip->thinkpad_flag)
1630 snd_wss_thinkpad_twiddle(chip, 1);
1631 snd_wss_mce_up(chip);
1632 spin_lock_irqsave(&chip->reg_lock, flags);
1633 for (reg = 0; reg < 32; reg++) {
1634 switch (reg) {
1635 case CS4231_VERSION:
1636 break;
1637 default:
1638 snd_wss_out(chip, reg, chip->image[reg]);
1639 break;
1640 }
1641 }
1642
1643 if (chip->hardware == WSS_HW_OPL3SA2)
1644 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
1645 chip->image[CS4231_PLAYBK_FORMAT]);
1646 spin_unlock_irqrestore(&chip->reg_lock, flags);
1647 #if 1
1648 snd_wss_mce_down(chip);
1649 #else
1650
1651
1652
1653
1654 snd_wss_busy_wait(chip);
1655 spin_lock_irqsave(&chip->reg_lock, flags);
1656 chip->mce_bit &= ~CS4231_MCE;
1657 timeout = wss_inb(chip, CS4231P(REGSEL));
1658 wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | (timeout & 0x1f));
1659 spin_unlock_irqrestore(&chip->reg_lock, flags);
1660 if (timeout == 0x80)
1661 snd_printk(KERN_ERR "down [0x%lx]: serious init problem "
1662 "- codec still busy\n", chip->port);
1663 if ((timeout & CS4231_MCE) == 0 ||
1664 !(chip->hardware & (WSS_HW_CS4231_MASK | WSS_HW_CS4232_MASK))) {
1665 return;
1666 }
1667 snd_wss_busy_wait(chip);
1668 #endif
1669 }
1670 #endif
1671
1672 static int snd_wss_free(struct snd_wss *chip)
1673 {
1674 release_and_free_resource(chip->res_port);
1675 release_and_free_resource(chip->res_cport);
1676 if (chip->irq >= 0) {
1677 disable_irq(chip->irq);
1678 if (!(chip->hwshare & WSS_HWSHARE_IRQ))
1679 free_irq(chip->irq, (void *) chip);
1680 }
1681 if (!(chip->hwshare & WSS_HWSHARE_DMA1) && chip->dma1 >= 0) {
1682 snd_dma_disable(chip->dma1);
1683 free_dma(chip->dma1);
1684 }
1685 if (!(chip->hwshare & WSS_HWSHARE_DMA2) &&
1686 chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
1687 snd_dma_disable(chip->dma2);
1688 free_dma(chip->dma2);
1689 }
1690 if (chip->timer)
1691 snd_device_free(chip->card, chip->timer);
1692 kfree(chip);
1693 return 0;
1694 }
1695
1696 static int snd_wss_dev_free(struct snd_device *device)
1697 {
1698 struct snd_wss *chip = device->device_data;
1699 return snd_wss_free(chip);
1700 }
1701
1702 const char *snd_wss_chip_id(struct snd_wss *chip)
1703 {
1704 switch (chip->hardware) {
1705 case WSS_HW_CS4231:
1706 return "CS4231";
1707 case WSS_HW_CS4231A:
1708 return "CS4231A";
1709 case WSS_HW_CS4232:
1710 return "CS4232";
1711 case WSS_HW_CS4232A:
1712 return "CS4232A";
1713 case WSS_HW_CS4235:
1714 return "CS4235";
1715 case WSS_HW_CS4236:
1716 return "CS4236";
1717 case WSS_HW_CS4236B:
1718 return "CS4236B";
1719 case WSS_HW_CS4237B:
1720 return "CS4237B";
1721 case WSS_HW_CS4238B:
1722 return "CS4238B";
1723 case WSS_HW_CS4239:
1724 return "CS4239";
1725 case WSS_HW_INTERWAVE:
1726 return "AMD InterWave";
1727 case WSS_HW_OPL3SA2:
1728 return chip->card->shortname;
1729 case WSS_HW_AD1845:
1730 return "AD1845";
1731 case WSS_HW_OPTI93X:
1732 return "OPTi 93x";
1733 case WSS_HW_AD1847:
1734 return "AD1847";
1735 case WSS_HW_AD1848:
1736 return "AD1848";
1737 case WSS_HW_CS4248:
1738 return "CS4248";
1739 case WSS_HW_CMI8330:
1740 return "CMI8330/C3D";
1741 default:
1742 return "???";
1743 }
1744 }
1745 EXPORT_SYMBOL(snd_wss_chip_id);
1746
1747 static int snd_wss_new(struct snd_card *card,
1748 unsigned short hardware,
1749 unsigned short hwshare,
1750 struct snd_wss **rchip)
1751 {
1752 struct snd_wss *chip;
1753
1754 *rchip = NULL;
1755 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1756 if (chip == NULL)
1757 return -ENOMEM;
1758 chip->hardware = hardware;
1759 chip->hwshare = hwshare;
1760
1761 spin_lock_init(&chip->reg_lock);
1762 mutex_init(&chip->mce_mutex);
1763 mutex_init(&chip->open_mutex);
1764 chip->card = card;
1765 chip->rate_constraint = snd_wss_xrate;
1766 chip->set_playback_format = snd_wss_playback_format;
1767 chip->set_capture_format = snd_wss_capture_format;
1768 if (chip->hardware == WSS_HW_OPTI93X)
1769 memcpy(&chip->image, &snd_opti93x_original_image,
1770 sizeof(snd_opti93x_original_image));
1771 else
1772 memcpy(&chip->image, &snd_wss_original_image,
1773 sizeof(snd_wss_original_image));
1774 if (chip->hardware & WSS_HW_AD1848_MASK) {
1775 chip->image[CS4231_PIN_CTRL] = 0;
1776 chip->image[CS4231_TEST_INIT] = 0;
1777 }
1778
1779 *rchip = chip;
1780 return 0;
1781 }
1782
1783 int snd_wss_create(struct snd_card *card,
1784 unsigned long port,
1785 unsigned long cport,
1786 int irq, int dma1, int dma2,
1787 unsigned short hardware,
1788 unsigned short hwshare,
1789 struct snd_wss **rchip)
1790 {
1791 static struct snd_device_ops ops = {
1792 .dev_free = snd_wss_dev_free,
1793 };
1794 struct snd_wss *chip;
1795 int err;
1796
1797 err = snd_wss_new(card, hardware, hwshare, &chip);
1798 if (err < 0)
1799 return err;
1800
1801 chip->irq = -1;
1802 chip->dma1 = -1;
1803 chip->dma2 = -1;
1804
1805 chip->res_port = request_region(port, 4, "WSS");
1806 if (!chip->res_port) {
1807 snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port);
1808 snd_wss_free(chip);
1809 return -EBUSY;
1810 }
1811 chip->port = port;
1812 if ((long)cport >= 0) {
1813 chip->res_cport = request_region(cport, 8, "CS4232 Control");
1814 if (!chip->res_cport) {
1815 snd_printk(KERN_ERR
1816 "wss: can't grab control port 0x%lx\n", cport);
1817 snd_wss_free(chip);
1818 return -ENODEV;
1819 }
1820 }
1821 chip->cport = cport;
1822 if (!(hwshare & WSS_HWSHARE_IRQ))
1823 if (request_irq(irq, snd_wss_interrupt, 0,
1824 "WSS", (void *) chip)) {
1825 snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
1826 snd_wss_free(chip);
1827 return -EBUSY;
1828 }
1829 chip->irq = irq;
1830 if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "WSS - 1")) {
1831 snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1);
1832 snd_wss_free(chip);
1833 return -EBUSY;
1834 }
1835 chip->dma1 = dma1;
1836 if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 &&
1837 dma2 >= 0 && request_dma(dma2, "WSS - 2")) {
1838 snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2);
1839 snd_wss_free(chip);
1840 return -EBUSY;
1841 }
1842 if (dma1 == dma2 || dma2 < 0) {
1843 chip->single_dma = 1;
1844 chip->dma2 = chip->dma1;
1845 } else
1846 chip->dma2 = dma2;
1847
1848 if (hardware == WSS_HW_THINKPAD) {
1849 chip->thinkpad_flag = 1;
1850 chip->hardware = WSS_HW_DETECT;
1851 snd_wss_thinkpad_twiddle(chip, 1);
1852 }
1853
1854
1855 if (snd_wss_probe(chip) < 0) {
1856 snd_wss_free(chip);
1857 return -ENODEV;
1858 }
1859 snd_wss_init(chip);
1860
1861 #if 0
1862 if (chip->hardware & WSS_HW_CS4232_MASK) {
1863 if (chip->res_cport == NULL)
1864 snd_printk(KERN_ERR "CS4232 control port features are "
1865 "not accessible\n");
1866 }
1867 #endif
1868
1869
1870 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1871 if (err < 0) {
1872 snd_wss_free(chip);
1873 return err;
1874 }
1875
1876 #ifdef CONFIG_PM
1877
1878 chip->suspend = snd_wss_suspend;
1879 chip->resume = snd_wss_resume;
1880 #endif
1881
1882 *rchip = chip;
1883 return 0;
1884 }
1885 EXPORT_SYMBOL(snd_wss_create);
1886
1887 static const struct snd_pcm_ops snd_wss_playback_ops = {
1888 .open = snd_wss_playback_open,
1889 .close = snd_wss_playback_close,
1890 .ioctl = snd_pcm_lib_ioctl,
1891 .hw_params = snd_wss_playback_hw_params,
1892 .hw_free = snd_wss_playback_hw_free,
1893 .prepare = snd_wss_playback_prepare,
1894 .trigger = snd_wss_trigger,
1895 .pointer = snd_wss_playback_pointer,
1896 };
1897
1898 static const struct snd_pcm_ops snd_wss_capture_ops = {
1899 .open = snd_wss_capture_open,
1900 .close = snd_wss_capture_close,
1901 .ioctl = snd_pcm_lib_ioctl,
1902 .hw_params = snd_wss_capture_hw_params,
1903 .hw_free = snd_wss_capture_hw_free,
1904 .prepare = snd_wss_capture_prepare,
1905 .trigger = snd_wss_trigger,
1906 .pointer = snd_wss_capture_pointer,
1907 };
1908
1909 int snd_wss_pcm(struct snd_wss *chip, int device)
1910 {
1911 struct snd_pcm *pcm;
1912 int err;
1913
1914 err = snd_pcm_new(chip->card, "WSS", device, 1, 1, &pcm);
1915 if (err < 0)
1916 return err;
1917
1918 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_wss_playback_ops);
1919 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_wss_capture_ops);
1920
1921
1922 pcm->private_data = chip;
1923 pcm->info_flags = 0;
1924 if (chip->single_dma)
1925 pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
1926 if (chip->hardware != WSS_HW_INTERWAVE)
1927 pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
1928 strcpy(pcm->name, snd_wss_chip_id(chip));
1929
1930 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1931 chip->card->dev,
1932 64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
1933
1934 chip->pcm = pcm;
1935 return 0;
1936 }
1937 EXPORT_SYMBOL(snd_wss_pcm);
1938
1939 static void snd_wss_timer_free(struct snd_timer *timer)
1940 {
1941 struct snd_wss *chip = timer->private_data;
1942 chip->timer = NULL;
1943 }
1944
1945 int snd_wss_timer(struct snd_wss *chip, int device)
1946 {
1947 struct snd_timer *timer;
1948 struct snd_timer_id tid;
1949 int err;
1950
1951
1952 tid.dev_class = SNDRV_TIMER_CLASS_CARD;
1953 tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
1954 tid.card = chip->card->number;
1955 tid.device = device;
1956 tid.subdevice = 0;
1957 if ((err = snd_timer_new(chip->card, "CS4231", &tid, &timer)) < 0)
1958 return err;
1959 strcpy(timer->name, snd_wss_chip_id(chip));
1960 timer->private_data = chip;
1961 timer->private_free = snd_wss_timer_free;
1962 timer->hw = snd_wss_timer_table;
1963 chip->timer = timer;
1964 return 0;
1965 }
1966 EXPORT_SYMBOL(snd_wss_timer);
1967
1968
1969
1970
1971
1972 static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
1973 struct snd_ctl_elem_info *uinfo)
1974 {
1975 static const char * const texts[4] = {
1976 "Line", "Aux", "Mic", "Mix"
1977 };
1978 static const char * const opl3sa_texts[4] = {
1979 "Line", "CD", "Mic", "Mix"
1980 };
1981 static const char * const gusmax_texts[4] = {
1982 "Line", "Synth", "Mic", "Mix"
1983 };
1984 const char * const *ptexts = texts;
1985 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
1986
1987 if (snd_BUG_ON(!chip->card))
1988 return -EINVAL;
1989 if (!strcmp(chip->card->driver, "GUS MAX"))
1990 ptexts = gusmax_texts;
1991 switch (chip->hardware) {
1992 case WSS_HW_INTERWAVE:
1993 ptexts = gusmax_texts;
1994 break;
1995 case WSS_HW_OPTI93X:
1996 case WSS_HW_OPL3SA2:
1997 ptexts = opl3sa_texts;
1998 break;
1999 }
2000 return snd_ctl_enum_info(uinfo, 2, 4, ptexts);
2001 }
2002
2003 static int snd_wss_get_mux(struct snd_kcontrol *kcontrol,
2004 struct snd_ctl_elem_value *ucontrol)
2005 {
2006 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2007 unsigned long flags;
2008
2009 spin_lock_irqsave(&chip->reg_lock, flags);
2010 ucontrol->value.enumerated.item[0] = (chip->image[CS4231_LEFT_INPUT] & CS4231_MIXS_ALL) >> 6;
2011 ucontrol->value.enumerated.item[1] = (chip->image[CS4231_RIGHT_INPUT] & CS4231_MIXS_ALL) >> 6;
2012 spin_unlock_irqrestore(&chip->reg_lock, flags);
2013 return 0;
2014 }
2015
2016 static int snd_wss_put_mux(struct snd_kcontrol *kcontrol,
2017 struct snd_ctl_elem_value *ucontrol)
2018 {
2019 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2020 unsigned long flags;
2021 unsigned short left, right;
2022 int change;
2023
2024 if (ucontrol->value.enumerated.item[0] > 3 ||
2025 ucontrol->value.enumerated.item[1] > 3)
2026 return -EINVAL;
2027 left = ucontrol->value.enumerated.item[0] << 6;
2028 right = ucontrol->value.enumerated.item[1] << 6;
2029 spin_lock_irqsave(&chip->reg_lock, flags);
2030 left = (chip->image[CS4231_LEFT_INPUT] & ~CS4231_MIXS_ALL) | left;
2031 right = (chip->image[CS4231_RIGHT_INPUT] & ~CS4231_MIXS_ALL) | right;
2032 change = left != chip->image[CS4231_LEFT_INPUT] ||
2033 right != chip->image[CS4231_RIGHT_INPUT];
2034 snd_wss_out(chip, CS4231_LEFT_INPUT, left);
2035 snd_wss_out(chip, CS4231_RIGHT_INPUT, right);
2036 spin_unlock_irqrestore(&chip->reg_lock, flags);
2037 return change;
2038 }
2039
2040 int snd_wss_info_single(struct snd_kcontrol *kcontrol,
2041 struct snd_ctl_elem_info *uinfo)
2042 {
2043 int mask = (kcontrol->private_value >> 16) & 0xff;
2044
2045 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2046 uinfo->count = 1;
2047 uinfo->value.integer.min = 0;
2048 uinfo->value.integer.max = mask;
2049 return 0;
2050 }
2051 EXPORT_SYMBOL(snd_wss_info_single);
2052
2053 int snd_wss_get_single(struct snd_kcontrol *kcontrol,
2054 struct snd_ctl_elem_value *ucontrol)
2055 {
2056 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2057 unsigned long flags;
2058 int reg = kcontrol->private_value & 0xff;
2059 int shift = (kcontrol->private_value >> 8) & 0xff;
2060 int mask = (kcontrol->private_value >> 16) & 0xff;
2061 int invert = (kcontrol->private_value >> 24) & 0xff;
2062
2063 spin_lock_irqsave(&chip->reg_lock, flags);
2064 ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
2065 spin_unlock_irqrestore(&chip->reg_lock, flags);
2066 if (invert)
2067 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2068 return 0;
2069 }
2070 EXPORT_SYMBOL(snd_wss_get_single);
2071
2072 int snd_wss_put_single(struct snd_kcontrol *kcontrol,
2073 struct snd_ctl_elem_value *ucontrol)
2074 {
2075 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2076 unsigned long flags;
2077 int reg = kcontrol->private_value & 0xff;
2078 int shift = (kcontrol->private_value >> 8) & 0xff;
2079 int mask = (kcontrol->private_value >> 16) & 0xff;
2080 int invert = (kcontrol->private_value >> 24) & 0xff;
2081 int change;
2082 unsigned short val;
2083
2084 val = (ucontrol->value.integer.value[0] & mask);
2085 if (invert)
2086 val = mask - val;
2087 val <<= shift;
2088 spin_lock_irqsave(&chip->reg_lock, flags);
2089 val = (chip->image[reg] & ~(mask << shift)) | val;
2090 change = val != chip->image[reg];
2091 snd_wss_out(chip, reg, val);
2092 spin_unlock_irqrestore(&chip->reg_lock, flags);
2093 return change;
2094 }
2095 EXPORT_SYMBOL(snd_wss_put_single);
2096
2097 int snd_wss_info_double(struct snd_kcontrol *kcontrol,
2098 struct snd_ctl_elem_info *uinfo)
2099 {
2100 int mask = (kcontrol->private_value >> 24) & 0xff;
2101
2102 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
2103 uinfo->count = 2;
2104 uinfo->value.integer.min = 0;
2105 uinfo->value.integer.max = mask;
2106 return 0;
2107 }
2108 EXPORT_SYMBOL(snd_wss_info_double);
2109
2110 int snd_wss_get_double(struct snd_kcontrol *kcontrol,
2111 struct snd_ctl_elem_value *ucontrol)
2112 {
2113 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
2114 unsigned long flags;
2115 int left_reg = kcontrol->private_value & 0xff;
2116 int right_reg = (kcontrol->private_value >> 8) & 0xff;
2117 int shift_left = (kcontrol->private_value >> 16) & 0x07;
2118 int shift_right = (kcontrol->private_value >> 19) & 0x07;
2119 int mask = (kcontrol->private_value >> 24) & 0xff;
2120 int invert = (kcontrol->private_value >> 22) & 1;
2121
2122 spin_lock_irqsave(&chip->reg_lock, flags);
2123 ucontrol->value.integer.value[0] = (chip->image[left_reg] >> shift_left) & mask;
2124 ucontrol->value.integer.value[1] = (chip->image[right_reg] >> shift_right) & mask;
2125 spin_unlock_irqrestore(&chip->reg_lock, flags);
2126 if (invert) {
2127 ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
2128 ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
2129 }
2130 return 0;
2131 }
2132 EXPORT_SYMBOL(snd_wss_get_double);
2133
2134 int snd_wss_put_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 int change;
2146 unsigned short val1, val2;
2147
2148 val1 = ucontrol->value.integer.value[0] & mask;
2149 val2 = ucontrol->value.integer.value[1] & mask;
2150 if (invert) {
2151 val1 = mask - val1;
2152 val2 = mask - val2;
2153 }
2154 val1 <<= shift_left;
2155 val2 <<= shift_right;
2156 spin_lock_irqsave(&chip->reg_lock, flags);
2157 if (left_reg != right_reg) {
2158 val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
2159 val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
2160 change = val1 != chip->image[left_reg] ||
2161 val2 != chip->image[right_reg];
2162 snd_wss_out(chip, left_reg, val1);
2163 snd_wss_out(chip, right_reg, val2);
2164 } else {
2165 mask = (mask << shift_left) | (mask << shift_right);
2166 val1 = (chip->image[left_reg] & ~mask) | val1 | val2;
2167 change = val1 != chip->image[left_reg];
2168 snd_wss_out(chip, left_reg, val1);
2169 }
2170 spin_unlock_irqrestore(&chip->reg_lock, flags);
2171 return change;
2172 }
2173 EXPORT_SYMBOL(snd_wss_put_double);
2174
2175 static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
2176 static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
2177 static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
2178 static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
2179
2180 static struct snd_kcontrol_new snd_wss_controls[] = {
2181 WSS_DOUBLE("PCM Playback Switch", 0,
2182 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2183 WSS_DOUBLE_TLV("PCM Playback Volume", 0,
2184 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
2185 db_scale_6bit),
2186 WSS_DOUBLE("Aux Playback Switch", 0,
2187 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2188 WSS_DOUBLE_TLV("Aux Playback Volume", 0,
2189 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
2190 db_scale_5bit_12db_max),
2191 WSS_DOUBLE("Aux Playback Switch", 1,
2192 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2193 WSS_DOUBLE_TLV("Aux Playback Volume", 1,
2194 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
2195 db_scale_5bit_12db_max),
2196 WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
2197 0, 0, 15, 0, db_scale_rec_gain),
2198 {
2199 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2200 .name = "Capture Source",
2201 .info = snd_wss_info_mux,
2202 .get = snd_wss_get_mux,
2203 .put = snd_wss_put_mux,
2204 },
2205 WSS_DOUBLE("Mic Boost (+20dB)", 0,
2206 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2207 WSS_SINGLE("Loopback Capture Switch", 0,
2208 CS4231_LOOPBACK, 0, 1, 0),
2209 WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1,
2210 db_scale_6bit),
2211 WSS_DOUBLE("Line Playback Switch", 0,
2212 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2213 WSS_DOUBLE_TLV("Line Playback Volume", 0,
2214 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
2215 db_scale_5bit_12db_max),
2216 WSS_SINGLE("Beep Playback Switch", 0,
2217 CS4231_MONO_CTRL, 7, 1, 1),
2218 WSS_SINGLE_TLV("Beep Playback Volume", 0,
2219 CS4231_MONO_CTRL, 0, 15, 1,
2220 db_scale_4bit),
2221 WSS_SINGLE("Mono Output Playback Switch", 0,
2222 CS4231_MONO_CTRL, 6, 1, 1),
2223 WSS_SINGLE("Beep Bypass Playback Switch", 0,
2224 CS4231_MONO_CTRL, 5, 1, 0),
2225 };
2226
2227 int snd_wss_mixer(struct snd_wss *chip)
2228 {
2229 struct snd_card *card;
2230 unsigned int idx;
2231 int err;
2232 int count = ARRAY_SIZE(snd_wss_controls);
2233
2234 if (snd_BUG_ON(!chip || !chip->pcm))
2235 return -EINVAL;
2236
2237 card = chip->card;
2238
2239 strcpy(card->mixername, chip->pcm->name);
2240
2241
2242 if (chip->hardware & WSS_HW_AD1848_MASK)
2243 count = 11;
2244
2245 else if (chip->hardware == WSS_HW_OPTI93X)
2246 count = 9;
2247
2248 for (idx = 0; idx < count; idx++) {
2249 err = snd_ctl_add(card,
2250 snd_ctl_new1(&snd_wss_controls[idx],
2251 chip));
2252 if (err < 0)
2253 return err;
2254 }
2255 return 0;
2256 }
2257 EXPORT_SYMBOL(snd_wss_mixer);
2258
2259 const struct snd_pcm_ops *snd_wss_get_pcm_ops(int direction)
2260 {
2261 return direction == SNDRV_PCM_STREAM_PLAYBACK ?
2262 &snd_wss_playback_ops : &snd_wss_capture_ops;
2263 }
2264 EXPORT_SYMBOL(snd_wss_get_pcm_ops);