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