File Index
Files and directories
Sign in
FILE

wss_lib.c

File preview with syntax highlighting.

linux-6.19.14/sound/isa/wss/wss_lib.c C
   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
  29MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
  30MODULE_DESCRIPTION("Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
  31MODULE_LICENSE("GPL");
  32
  33#if 0
  34#define SNDRV_DEBUG_MCE
  35#endif
  36
  37/*
  38 *  Some variables
  39 */
  40
  41static 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
  58static const unsigned int rates[14] = {
  59	5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
  60	27042, 32000, 33075, 37800, 44100, 48000
  61};
  62
  63static const struct snd_pcm_hw_constraint_list hw_constraints_rates = {
  64	.count = ARRAY_SIZE(rates),
  65	.list = rates,
  66	.mask = 0,
  67};
  68
  69static int snd_wss_xrate(struct snd_pcm_runtime *runtime)
  70{
  71	return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
  72					  &hw_constraints_rates);
  73}
  74
  75static const unsigned char snd_wss_original_image[32] =
  76{
  77	0x00,			/* 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
 111static 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
 151static inline void wss_outb(struct snd_wss *chip, u8 offset, u8 val)
 152{
 153	outb(val, chip->port + offset);
 154}
 155
 156static inline u8 wss_inb(struct snd_wss *chip, u8 offset)
 157{
 158	return inb(chip->port + offset);
 159}
 160
 161static void snd_wss_wait(struct snd_wss *chip)
 162{
 163	int timeout;
 164
 165	for (timeout = 250;
 166	     timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
 167	     timeout--)
 168		udelay(100);
 169}
 170
 171static void snd_wss_dout(struct snd_wss *chip, unsigned char reg,
 172			 unsigned char value)
 173{
 174	int timeout;
 175
 176	for (timeout = 250;
 177	     timeout > 0 && (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT);
 178	     timeout--)
 179		udelay(10);
 180	wss_outb(chip, CS4231P(REGSEL), chip->mce_bit | reg);
 181	wss_outb(chip, CS4231P(REG), value);
 182	mb();
 183}
 184
 185void snd_wss_out(struct snd_wss *chip, unsigned char reg, unsigned char value)
 186{
 187	snd_wss_wait(chip);
 188#ifdef CONFIG_SND_DEBUG
 189	if (wss_inb(chip, CS4231P(REGSEL)) & CS4231_INIT)
 190		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}
 201EXPORT_SYMBOL(snd_wss_out);
 202
 203unsigned 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}
 215EXPORT_SYMBOL(snd_wss_in);
 216
 217void 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}
 229EXPORT_SYMBOL(snd_cs4236_ext_out);
 230
 231unsigned 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}
 248EXPORT_SYMBOL(snd_cs4236_ext_in);
 249
 250#if 0
 251
 252static 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
 347static 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
 361void 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}
 382EXPORT_SYMBOL(snd_wss_mce_up);
 383
 384void 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}
 449EXPORT_SYMBOL(snd_wss_mce_down);
 450
 451static unsigned int snd_wss_get_count(unsigned char format, unsigned int size)
 452{
 453	switch (format & 0xe0) {
 454	case CS4231_LINEAR_16:
 455	case CS4231_LINEAR_16_BIG:
 456		size >>= 1;
 457		break;
 458	case CS4231_ADPCM_16:
 459		return size >> 2;
 460	}
 461	if (format & CS4231_STEREO)
 462		size >>= 1;
 463	return size;
 464}
 465
 466static int snd_wss_trigger(struct snd_pcm_substream *substream,
 467			   int cmd)
 468{
 469	struct snd_wss *chip = snd_pcm_substream_chip(substream);
 470	int result = 0;
 471	unsigned int what;
 472	struct snd_pcm_substream *s;
 473	int do_start;
 474
 475	switch (cmd) {
 476	case SNDRV_PCM_TRIGGER_START:
 477	case SNDRV_PCM_TRIGGER_RESUME:
 478		do_start = 1; break;
 479	case SNDRV_PCM_TRIGGER_STOP:
 480	case SNDRV_PCM_TRIGGER_SUSPEND:
 481		do_start = 0; break;
 482	default:
 483		return -EINVAL;
 484	}
 485
 486	what = 0;
 487	snd_pcm_group_for_each_entry(s, substream) {
 488		if (s == chip->playback_substream) {
 489			what |= CS4231_PLAYBACK_ENABLE;
 490			snd_pcm_trigger_done(s, substream);
 491		} else if (s == chip->capture_substream) {
 492			what |= CS4231_RECORD_ENABLE;
 493			snd_pcm_trigger_done(s, substream);
 494		}
 495	}
 496	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
 517static 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
 528static 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
 550static 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
 606static 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
 663static 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
 731static 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
 740static 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
 763static 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
 774static 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
 842static 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
 877static 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
 924static 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
 931static 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
 938static 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
 954static 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
 967static 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
 987static 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
1000static 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
1030void 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}
1040EXPORT_SYMBOL(snd_wss_overrange);
1041
1042irqreturn_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}
1090EXPORT_SYMBOL(snd_wss_interrupt);
1091
1092static 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
1103static 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
1118static 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;
1187out_mode:
1188	snd_wss_dout(chip, CS4231_MISC_INFO, 0);
1189	return 0;
1190}
1191
1192static 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
1381static 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
1401static 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
1426static 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
1469static 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
1510static 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
1519static 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
1528static 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 */
1551static 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 */
1564static 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
1613const 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}
1656EXPORT_SYMBOL(snd_wss_chip_id);
1657
1658static 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
1694int 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}
1782EXPORT_SYMBOL(snd_wss_create);
1783
1784static 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
1793static 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
1802int 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}
1829EXPORT_SYMBOL(snd_wss_pcm);
1830
1831static void snd_wss_timer_free(struct snd_timer *timer)
1832{
1833	struct snd_wss *chip = timer->private_data;
1834	chip->timer = NULL;
1835}
1836
1837int 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}
1859EXPORT_SYMBOL(snd_wss_timer);
1860
1861/*
1862 *  MIXER part
1863 */
1864
1865static 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
1896static 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
1907static 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
1929int 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}
1940EXPORT_SYMBOL(snd_wss_info_single);
1941
1942int 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}
1957EXPORT_SYMBOL(snd_wss_get_single);
1958
1959int 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}
1980EXPORT_SYMBOL(snd_wss_put_single);
1981
1982int 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}
1993EXPORT_SYMBOL(snd_wss_info_double);
1994
1995int 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}
2015EXPORT_SYMBOL(snd_wss_get_double);
2016
2017int 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}
2054EXPORT_SYMBOL(snd_wss_put_double);
2055
2056static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
2057static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
2058static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
2059static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
2060
2061static const struct snd_kcontrol_new snd_wss_controls[] = {
2062WSS_DOUBLE("PCM Playback Switch", 0,
2063		CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
2064WSS_DOUBLE_TLV("PCM Playback Volume", 0,
2065		CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
2066		db_scale_6bit),
2067WSS_DOUBLE("Aux Playback Switch", 0,
2068		CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
2069WSS_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),
2072WSS_DOUBLE("Aux Playback Switch", 1,
2073		CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
2074WSS_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),
2077WSS_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},
2086WSS_DOUBLE("Mic Boost (+20dB)", 0,
2087		CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2088WSS_SINGLE("Loopback Capture Switch", 0,
2089		CS4231_LOOPBACK, 0, 1, 0),
2090WSS_SINGLE_TLV("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1,
2091		db_scale_6bit),
2092WSS_DOUBLE("Line Playback Switch", 0,
2093		CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
2094WSS_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),
2097WSS_SINGLE("Beep Playback Switch", 0,
2098		CS4231_MONO_CTRL, 7, 1, 1),
2099WSS_SINGLE_TLV("Beep Playback Volume", 0,
2100		CS4231_MONO_CTRL, 0, 15, 1,
2101		db_scale_4bit),
2102WSS_SINGLE("Mono Output Playback Switch", 0,
2103		CS4231_MONO_CTRL, 6, 1, 1),
2104WSS_SINGLE("Beep Bypass Playback Switch", 0,
2105		CS4231_MONO_CTRL, 5, 1, 0),
2106};
2107
2108int 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}
2138EXPORT_SYMBOL(snd_wss_mixer);
2139
2140const 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}
2145EXPORT_SYMBOL(snd_wss_get_pcm_ops);
~/ Read-only file preview.