File Index
Files and directories
Sign in
FILE

msnd_pinnacle.c

File preview with syntax highlighting.

linux-6.19.14/sound/isa/msnd/msnd_pinnacle.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*********************************************************************
   3 *
   4 * Linux multisound pinnacle/fiji driver for ALSA.
   5 *
   6 * 2002/06/30 Karsten Wiese:
   7 *	for now this is only used to build a pinnacle / fiji driver.
   8 *	the OSS parent of this code is designed to also support
   9 *	the multisound classic via the file msnd_classic.c.
  10 *	to make it easier for some brave heart to implemt classic
  11 *	support in alsa, i left all the MSND_CLASSIC tokens in this file.
  12 *	but for now this untested & undone.
  13 *
  14 * ripped from linux kernel 2.4.18 by Karsten Wiese.
  15 *
  16 * the following is a copy of the 2.4.18 OSS FREE file-heading comment:
  17 *
  18 * Turtle Beach MultiSound Sound Card Driver for Linux
  19 * msnd_pinnacle.c / msnd_classic.c
  20 *
  21 * -- If MSND_CLASSIC is defined:
  22 *
  23 *     -> driver for Turtle Beach Classic/Monterey/Tahiti
  24 *
  25 * -- Else
  26 *
  27 *     -> driver for Turtle Beach Pinnacle/Fiji
  28 *
  29 * 12-3-2000  Modified IO port validation  Steve Sycamore
  30 *
  31 * Copyright (C) 1998 Andrew Veliath
  32 *
  33 ********************************************************************/
  34
  35#include <linux/kernel.h>
  36#include <linux/module.h>
  37#include <linux/interrupt.h>
  38#include <linux/types.h>
  39#include <linux/delay.h>
  40#include <linux/ioport.h>
  41#include <linux/firmware.h>
  42#include <linux/isa.h>
  43#include <linux/isapnp.h>
  44#include <linux/irq.h>
  45#include <linux/io.h>
  46
  47#include <sound/core.h>
  48#include <sound/initval.h>
  49#include <sound/asound.h>
  50#include <sound/pcm.h>
  51#include <sound/mpu401.h>
  52
  53#ifdef MSND_CLASSIC
  54# ifndef __alpha__
  55#  define SLOWIO
  56# endif
  57#endif
  58#include "msnd.h"
  59#ifdef MSND_CLASSIC
  60#  include "msnd_classic.h"
  61#  define LOGNAME			"msnd_classic"
  62#  define DEV_NAME			"msnd-classic"
  63#else
  64#  include "msnd_pinnacle.h"
  65#  define LOGNAME			"snd_msnd_pinnacle"
  66#  define DEV_NAME			"msnd-pinnacle"
  67#endif
  68
  69static void set_default_audio_parameters(struct snd_msnd *chip)
  70{
  71	chip->play_sample_size = snd_pcm_format_width(DEFSAMPLESIZE);
  72	chip->play_sample_rate = DEFSAMPLERATE;
  73	chip->play_channels = DEFCHANNELS;
  74	chip->capture_sample_size = snd_pcm_format_width(DEFSAMPLESIZE);
  75	chip->capture_sample_rate = DEFSAMPLERATE;
  76	chip->capture_channels = DEFCHANNELS;
  77}
  78
  79static void snd_msnd_eval_dsp_msg(struct snd_msnd *chip, u16 wMessage)
  80{
  81	switch (HIBYTE(wMessage)) {
  82	case HIMT_PLAY_DONE: {
  83		if (chip->banksPlayed < 3)
  84			dev_dbg(chip->card->dev, "%08X: HIMT_PLAY_DONE: %i\n",
  85				(unsigned)jiffies, LOBYTE(wMessage));
  86
  87		if (chip->last_playbank == LOBYTE(wMessage)) {
  88			dev_dbg(chip->card->dev,
  89				"chip.last_playbank == LOBYTE(wMessage)\n");
  90			break;
  91		}
  92		chip->banksPlayed++;
  93
  94		if (test_bit(F_WRITING, &chip->flags))
  95			snd_msnd_DAPQ(chip, 0);
  96
  97		chip->last_playbank = LOBYTE(wMessage);
  98		chip->playDMAPos += chip->play_period_bytes;
  99		if (chip->playDMAPos > chip->playLimit)
 100			chip->playDMAPos = 0;
 101		snd_pcm_period_elapsed(chip->playback_substream);
 102
 103		break;
 104	}
 105	case HIMT_RECORD_DONE:
 106		if (chip->last_recbank == LOBYTE(wMessage))
 107			break;
 108		chip->last_recbank = LOBYTE(wMessage);
 109		chip->captureDMAPos += chip->capturePeriodBytes;
 110		if (chip->captureDMAPos > (chip->captureLimit))
 111			chip->captureDMAPos = 0;
 112
 113		if (test_bit(F_READING, &chip->flags))
 114			snd_msnd_DARQ(chip, chip->last_recbank);
 115
 116		snd_pcm_period_elapsed(chip->capture_substream);
 117		break;
 118
 119	case HIMT_DSP:
 120		switch (LOBYTE(wMessage)) {
 121#ifndef MSND_CLASSIC
 122		case HIDSP_PLAY_UNDER:
 123#endif
 124		case HIDSP_INT_PLAY_UNDER:
 125			dev_dbg(chip->card->dev,
 126				LOGNAME ": Play underflow %i\n",
 127				chip->banksPlayed);
 128			if (chip->banksPlayed > 2)
 129				clear_bit(F_WRITING, &chip->flags);
 130			break;
 131
 132		case HIDSP_INT_RECORD_OVER:
 133			dev_dbg(chip->card->dev, LOGNAME ": Record overflow\n");
 134			clear_bit(F_READING, &chip->flags);
 135			break;
 136
 137		default:
 138			dev_dbg(chip->card->dev, LOGNAME
 139				": DSP message %d 0x%02x\n",
 140				LOBYTE(wMessage), LOBYTE(wMessage));
 141			break;
 142		}
 143		break;
 144
 145	default:
 146		dev_dbg(chip->card->dev, LOGNAME ": HIMT message %d 0x%02x\n",
 147			HIBYTE(wMessage), HIBYTE(wMessage));
 148		break;
 149	}
 150}
 151
 152static irqreturn_t snd_msnd_interrupt(int irq, void *dev_id)
 153{
 154	struct snd_msnd *chip = dev_id;
 155	void __iomem *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF;
 156	u16 head, tail, size;
 157
 158	/* Send ack to DSP */
 159	/* inb(chip->io + HP_RXL); */
 160
 161	/* Evaluate queued DSP messages */
 162	head = readw(chip->DSPQ + JQS_wHead);
 163	tail = readw(chip->DSPQ + JQS_wTail);
 164	size = readw(chip->DSPQ + JQS_wSize);
 165	if (head > size || tail > size)
 166		goto out;
 167	while (head != tail) {
 168		snd_msnd_eval_dsp_msg(chip, readw(pwDSPQData + 2 * head));
 169		if (++head > size)
 170			head = 0;
 171		writew(head, chip->DSPQ + JQS_wHead);
 172	}
 173 out:
 174	/* Send ack to DSP */
 175	inb(chip->io + HP_RXL);
 176	return IRQ_HANDLED;
 177}
 178
 179
 180static int snd_msnd_reset_dsp(struct snd_msnd *chip, unsigned char *info)
 181{
 182	long io = chip->io;
 183	int timeout = 100;
 184
 185	outb(HPDSPRESET_ON, io + HP_DSPR);
 186	msleep(1);
 187#ifndef MSND_CLASSIC
 188	if (info)
 189		*info = inb(io + HP_INFO);
 190#endif
 191	outb(HPDSPRESET_OFF, io + HP_DSPR);
 192	msleep(1);
 193	while (timeout-- > 0) {
 194		if (inb(io + HP_CVR) == HP_CVR_DEF)
 195			return 0;
 196		msleep(1);
 197	}
 198	dev_err(chip->card->dev, LOGNAME ": Cannot reset DSP\n");
 199
 200	return -EIO;
 201}
 202
 203static int snd_msnd_probe(struct snd_card *card)
 204{
 205	struct snd_msnd *chip = card->private_data;
 206	unsigned char info;
 207#ifndef MSND_CLASSIC
 208	char *xv, *rev = NULL;
 209	char *pin = "TB Pinnacle", *fiji = "TB Fiji";
 210	char *pinfiji = "TB Pinnacle/Fiji";
 211#endif
 212
 213	if (!request_region(chip->io, DSP_NUMIO, "probing")) {
 214		dev_err(card->dev, LOGNAME ": I/O port conflict\n");
 215		return -ENODEV;
 216	}
 217
 218	if (snd_msnd_reset_dsp(chip, &info) < 0) {
 219		release_region(chip->io, DSP_NUMIO);
 220		return -ENODEV;
 221	}
 222
 223#ifdef MSND_CLASSIC
 224	strscpy(card->shortname, "Classic/Tahiti/Monterey");
 225	strscpy(card->longname, "Turtle Beach Multisound");
 226	dev_info(card->dev, LOGNAME ": %s, "
 227	       "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n",
 228	       card->shortname,
 229	       chip->io, chip->io + DSP_NUMIO - 1,
 230	       chip->irq,
 231	       chip->base, chip->base + 0x7fff);
 232#else
 233	switch (info >> 4) {
 234	case 0xf:
 235		xv = "<= 1.15";
 236		break;
 237	case 0x1:
 238		xv = "1.18/1.2";
 239		break;
 240	case 0x2:
 241		xv = "1.3";
 242		break;
 243	case 0x3:
 244		xv = "1.4";
 245		break;
 246	default:
 247		xv = "unknown";
 248		break;
 249	}
 250
 251	switch (info & 0x7) {
 252	case 0x0:
 253		rev = "I";
 254		strscpy(card->shortname, pin);
 255		break;
 256	case 0x1:
 257		rev = "F";
 258		strscpy(card->shortname, pin);
 259		break;
 260	case 0x2:
 261		rev = "G";
 262		strscpy(card->shortname, pin);
 263		break;
 264	case 0x3:
 265		rev = "H";
 266		strscpy(card->shortname, pin);
 267		break;
 268	case 0x4:
 269		rev = "E";
 270		strscpy(card->shortname, fiji);
 271		break;
 272	case 0x5:
 273		rev = "C";
 274		strscpy(card->shortname, fiji);
 275		break;
 276	case 0x6:
 277		rev = "D";
 278		strscpy(card->shortname, fiji);
 279		break;
 280	case 0x7:
 281		rev = "A-B (Fiji) or A-E (Pinnacle)";
 282		strscpy(card->shortname, pinfiji);
 283		break;
 284	}
 285	strscpy(card->longname, "Turtle Beach Multisound Pinnacle");
 286	dev_info(card->dev, LOGNAME ": %s revision %s, Xilinx version %s, "
 287	       "I/O 0x%lx-0x%lx, IRQ %d, memory mapped to 0x%lX-0x%lX\n",
 288	       card->shortname,
 289	       rev, xv,
 290	       chip->io, chip->io + DSP_NUMIO - 1,
 291	       chip->irq,
 292	       chip->base, chip->base + 0x7fff);
 293#endif
 294
 295	release_region(chip->io, DSP_NUMIO);
 296	return 0;
 297}
 298
 299static int snd_msnd_init_sma(struct snd_msnd *chip)
 300{
 301	static int initted;
 302	u16 mastVolLeft, mastVolRight;
 303
 304#ifdef MSND_CLASSIC
 305	outb(chip->memid, chip->io + HP_MEMM);
 306#endif
 307	outb(HPBLKSEL_0, chip->io + HP_BLKS);
 308	/* Motorola 56k shared memory base */
 309	chip->SMA = chip->mappedbase + SMA_STRUCT_START;
 310
 311	if (initted) {
 312		mastVolLeft = readw(chip->SMA + SMA_wCurrMastVolLeft);
 313		mastVolRight = readw(chip->SMA + SMA_wCurrMastVolRight);
 314	} else
 315		mastVolLeft = mastVolRight = 0;
 316	memset_io(chip->mappedbase, 0, 0x8000);
 317
 318	/* Critical section: bank 1 access */
 319	scoped_guard(spinlock_irqsave, &chip->lock) {
 320		outb(HPBLKSEL_1, chip->io + HP_BLKS);
 321		memset_io(chip->mappedbase, 0, 0x8000);
 322		outb(HPBLKSEL_0, chip->io + HP_BLKS);
 323	}
 324
 325	/* Digital audio play queue */
 326	chip->DAPQ = chip->mappedbase + DAPQ_OFFSET;
 327	snd_msnd_init_queue(chip->DAPQ, DAPQ_DATA_BUFF, DAPQ_BUFF_SIZE);
 328
 329	/* Digital audio record queue */
 330	chip->DARQ = chip->mappedbase + DARQ_OFFSET;
 331	snd_msnd_init_queue(chip->DARQ, DARQ_DATA_BUFF, DARQ_BUFF_SIZE);
 332
 333	/* MIDI out queue */
 334	chip->MODQ = chip->mappedbase + MODQ_OFFSET;
 335	snd_msnd_init_queue(chip->MODQ, MODQ_DATA_BUFF, MODQ_BUFF_SIZE);
 336
 337	/* MIDI in queue */
 338	chip->MIDQ = chip->mappedbase + MIDQ_OFFSET;
 339	snd_msnd_init_queue(chip->MIDQ, MIDQ_DATA_BUFF, MIDQ_BUFF_SIZE);
 340
 341	/* DSP -> host message queue */
 342	chip->DSPQ = chip->mappedbase + DSPQ_OFFSET;
 343	snd_msnd_init_queue(chip->DSPQ, DSPQ_DATA_BUFF, DSPQ_BUFF_SIZE);
 344
 345	/* Setup some DSP values */
 346#ifndef MSND_CLASSIC
 347	writew(1, chip->SMA + SMA_wCurrPlayFormat);
 348	writew(chip->play_sample_size, chip->SMA + SMA_wCurrPlaySampleSize);
 349	writew(chip->play_channels, chip->SMA + SMA_wCurrPlayChannels);
 350	writew(chip->play_sample_rate, chip->SMA + SMA_wCurrPlaySampleRate);
 351#endif
 352	writew(chip->play_sample_rate, chip->SMA + SMA_wCalFreqAtoD);
 353	writew(mastVolLeft, chip->SMA + SMA_wCurrMastVolLeft);
 354	writew(mastVolRight, chip->SMA + SMA_wCurrMastVolRight);
 355#ifndef MSND_CLASSIC
 356	writel(0x00010000, chip->SMA + SMA_dwCurrPlayPitch);
 357	writel(0x00000001, chip->SMA + SMA_dwCurrPlayRate);
 358#endif
 359	writew(0x303, chip->SMA + SMA_wCurrInputTagBits);
 360
 361	initted = 1;
 362
 363	return 0;
 364}
 365
 366
 367static int upload_dsp_code(struct snd_card *card)
 368{
 369	struct snd_msnd *chip = card->private_data;
 370	const struct firmware *init_fw = NULL, *perm_fw = NULL;
 371	int err;
 372
 373	outb(HPBLKSEL_0, chip->io + HP_BLKS);
 374
 375	err = request_firmware(&init_fw, INITCODEFILE, card->dev);
 376	if (err < 0) {
 377		dev_err(card->dev, LOGNAME ": Error loading " INITCODEFILE);
 378		goto cleanup1;
 379	}
 380	err = request_firmware(&perm_fw, PERMCODEFILE, card->dev);
 381	if (err < 0) {
 382		dev_err(card->dev, LOGNAME ": Error loading " PERMCODEFILE);
 383		goto cleanup;
 384	}
 385
 386	memcpy_toio(chip->mappedbase, perm_fw->data, perm_fw->size);
 387	if (snd_msnd_upload_host(chip, init_fw->data, init_fw->size) < 0) {
 388		dev_warn(card->dev, LOGNAME ": Error uploading to DSP\n");
 389		err = -ENODEV;
 390		goto cleanup;
 391	}
 392	dev_info(card->dev, LOGNAME ": DSP firmware uploaded\n");
 393	err = 0;
 394
 395cleanup:
 396	release_firmware(perm_fw);
 397cleanup1:
 398	release_firmware(init_fw);
 399	return err;
 400}
 401
 402#ifdef MSND_CLASSIC
 403static void reset_proteus(struct snd_msnd *chip)
 404{
 405	outb(HPPRORESET_ON, chip->io + HP_PROR);
 406	msleep(TIME_PRO_RESET);
 407	outb(HPPRORESET_OFF, chip->io + HP_PROR);
 408	msleep(TIME_PRO_RESET_DONE);
 409}
 410#endif
 411
 412static int snd_msnd_initialize(struct snd_card *card)
 413{
 414	struct snd_msnd *chip = card->private_data;
 415	int err, timeout;
 416
 417#ifdef MSND_CLASSIC
 418	outb(HPWAITSTATE_0, chip->io + HP_WAIT);
 419	outb(HPBITMODE_16, chip->io + HP_BITM);
 420
 421	reset_proteus(chip);
 422#endif
 423	err = snd_msnd_init_sma(chip);
 424	if (err < 0) {
 425		dev_warn(card->dev, LOGNAME ": Cannot initialize SMA\n");
 426		return err;
 427	}
 428
 429	err = snd_msnd_reset_dsp(chip, NULL);
 430	if (err < 0)
 431		return err;
 432
 433	err = upload_dsp_code(card);
 434	if (err < 0) {
 435		dev_warn(card->dev, LOGNAME ": Cannot upload DSP code\n");
 436		return err;
 437	}
 438
 439	timeout = 200;
 440
 441	while (readw(chip->mappedbase)) {
 442		msleep(1);
 443		if (!timeout--) {
 444			dev_err(card->dev, LOGNAME ": DSP reset timeout\n");
 445			return -EIO;
 446		}
 447	}
 448
 449	snd_msndmix_setup(chip);
 450	return 0;
 451}
 452
 453static int snd_msnd_dsp_full_reset(struct snd_card *card)
 454{
 455	struct snd_msnd *chip = card->private_data;
 456	int rv;
 457
 458	if (test_bit(F_RESETTING, &chip->flags) || ++chip->nresets > 10)
 459		return 0;
 460
 461	set_bit(F_RESETTING, &chip->flags);
 462	snd_msnd_dsp_halt(chip, NULL);	/* Unconditionally halt */
 463
 464	rv = snd_msnd_initialize(card);
 465	if (rv)
 466		dev_warn(card->dev, LOGNAME ": DSP reset failed\n");
 467	snd_msndmix_force_recsrc(chip, 0);
 468	clear_bit(F_RESETTING, &chip->flags);
 469	return rv;
 470}
 471
 472
 473static int snd_msnd_send_dsp_cmd_chk(struct snd_msnd *chip, u8 cmd)
 474{
 475	if (snd_msnd_send_dsp_cmd(chip, cmd) == 0)
 476		return 0;
 477	snd_msnd_dsp_full_reset(chip->card);
 478	return snd_msnd_send_dsp_cmd(chip, cmd);
 479}
 480
 481static int snd_msnd_calibrate_adc(struct snd_msnd *chip, u16 srate)
 482{
 483	dev_dbg(chip->card->dev, "snd_msnd_calibrate_adc(%i)\n", srate);
 484	writew(srate, chip->SMA + SMA_wCalFreqAtoD);
 485	if (chip->calibrate_signal == 0)
 486		writew(readw(chip->SMA + SMA_wCurrHostStatusFlags)
 487		       | 0x0001, chip->SMA + SMA_wCurrHostStatusFlags);
 488	else
 489		writew(readw(chip->SMA + SMA_wCurrHostStatusFlags)
 490		       & ~0x0001, chip->SMA + SMA_wCurrHostStatusFlags);
 491	if (snd_msnd_send_word(chip, 0, 0, HDEXAR_CAL_A_TO_D) == 0 &&
 492	    snd_msnd_send_dsp_cmd_chk(chip, HDEX_AUX_REQ) == 0) {
 493		schedule_timeout_interruptible(msecs_to_jiffies(333));
 494		return 0;
 495	}
 496	dev_warn(chip->card->dev, LOGNAME ": ADC calibration failed\n");
 497	return -EIO;
 498}
 499
 500/*
 501 * ALSA callback function, called when attempting to open the MIDI device.
 502 */
 503static int snd_msnd_mpu401_open(struct snd_mpu401 *mpu)
 504{
 505	snd_msnd_enable_irq(mpu->private_data);
 506	snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_START);
 507	return 0;
 508}
 509
 510static void snd_msnd_mpu401_close(struct snd_mpu401 *mpu)
 511{
 512	snd_msnd_send_dsp_cmd(mpu->private_data, HDEX_MIDI_IN_STOP);
 513	snd_msnd_disable_irq(mpu->private_data);
 514}
 515
 516static long mpu_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 517static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 518
 519static int snd_msnd_attach(struct snd_card *card)
 520{
 521	struct snd_msnd *chip = card->private_data;
 522	int err;
 523
 524	err = devm_request_irq(card->dev, chip->irq, snd_msnd_interrupt, 0,
 525			       card->shortname, chip);
 526	if (err < 0) {
 527		dev_err(card->dev, LOGNAME ": Couldn't grab IRQ %d\n", chip->irq);
 528		return err;
 529	}
 530	card->sync_irq = chip->irq;
 531	if (!devm_request_region(card->dev, chip->io, DSP_NUMIO,
 532				 card->shortname))
 533		return -EBUSY;
 534
 535	if (!devm_request_mem_region(card->dev, chip->base, BUFFSIZE,
 536				     card->shortname)) {
 537		dev_err(card->dev, LOGNAME
 538			": unable to grab memory region 0x%lx-0x%lx\n",
 539			chip->base, chip->base + BUFFSIZE - 1);
 540		return -EBUSY;
 541	}
 542	chip->mappedbase = devm_ioremap(card->dev, chip->base, 0x8000);
 543	if (!chip->mappedbase) {
 544		dev_err(card->dev, LOGNAME
 545			": unable to map memory region 0x%lx-0x%lx\n",
 546			chip->base, chip->base + BUFFSIZE - 1);
 547		return -EIO;
 548	}
 549
 550	err = snd_msnd_dsp_full_reset(card);
 551	if (err < 0)
 552		return err;
 553
 554	err = snd_msnd_pcm(card, 0);
 555	if (err < 0) {
 556		dev_err(card->dev, LOGNAME ": error creating new PCM device\n");
 557		return err;
 558	}
 559
 560	err = snd_msndmix_new(card);
 561	if (err < 0) {
 562		dev_err(card->dev, LOGNAME ": error creating new Mixer device\n");
 563		return err;
 564	}
 565
 566
 567	if (mpu_io[0] != SNDRV_AUTO_PORT) {
 568		struct snd_mpu401 *mpu;
 569
 570		err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
 571					  mpu_io[0],
 572					  MPU401_MODE_INPUT |
 573					  MPU401_MODE_OUTPUT,
 574					  mpu_irq[0],
 575					  &chip->rmidi);
 576		if (err < 0) {
 577			dev_err(card->dev, LOGNAME
 578				": error creating new Midi device\n");
 579			return err;
 580		}
 581		mpu = chip->rmidi->private_data;
 582
 583		mpu->open_input = snd_msnd_mpu401_open;
 584		mpu->close_input = snd_msnd_mpu401_close;
 585		mpu->private_data = chip;
 586	}
 587
 588	disable_irq(chip->irq);
 589	snd_msnd_calibrate_adc(chip, chip->play_sample_rate);
 590	snd_msndmix_force_recsrc(chip, 0);
 591
 592	err = snd_card_register(card);
 593	if (err < 0)
 594		return err;
 595
 596	return 0;
 597}
 598
 599
 600#ifndef MSND_CLASSIC
 601
 602/* Pinnacle/Fiji Logical Device Configuration */
 603
 604static int snd_msnd_write_cfg(struct snd_msnd *chip, int cfg, int reg, int value)
 605{
 606	outb(reg, cfg);
 607	outb(value, cfg + 1);
 608	if (value != inb(cfg + 1)) {
 609		dev_err(chip->card->dev, LOGNAME ": %s: I/O error\n", __func__);
 610		return -EIO;
 611	}
 612	return 0;
 613}
 614
 615static int snd_msnd_write_cfg_io0(struct snd_msnd *chip, int cfg, int num, u16 io)
 616{
 617	if (snd_msnd_write_cfg(chip, cfg, IREG_LOGDEVICE, num))
 618		return -EIO;
 619	if (snd_msnd_write_cfg(chip, cfg, IREG_IO0_BASEHI, HIBYTE(io)))
 620		return -EIO;
 621	if (snd_msnd_write_cfg(chip, cfg, IREG_IO0_BASELO, LOBYTE(io)))
 622		return -EIO;
 623	return 0;
 624}
 625
 626static int snd_msnd_write_cfg_io1(struct snd_msnd *chip, int cfg, int num, u16 io)
 627{
 628	if (snd_msnd_write_cfg(chip, cfg, IREG_LOGDEVICE, num))
 629		return -EIO;
 630	if (snd_msnd_write_cfg(chip, cfg, IREG_IO1_BASEHI, HIBYTE(io)))
 631		return -EIO;
 632	if (snd_msnd_write_cfg(chip, cfg, IREG_IO1_BASELO, LOBYTE(io)))
 633		return -EIO;
 634	return 0;
 635}
 636
 637static int snd_msnd_write_cfg_irq(struct snd_msnd *chip, int cfg, int num, u16 irq)
 638{
 639	if (snd_msnd_write_cfg(chip, cfg, IREG_LOGDEVICE, num))
 640		return -EIO;
 641	if (snd_msnd_write_cfg(chip, cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
 642		return -EIO;
 643	if (snd_msnd_write_cfg(chip, cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
 644		return -EIO;
 645	return 0;
 646}
 647
 648static int snd_msnd_write_cfg_mem(struct snd_msnd *chip, int cfg, int num, int mem)
 649{
 650	u16 wmem;
 651
 652	mem >>= 8;
 653	wmem = (u16)(mem & 0xfff);
 654	if (snd_msnd_write_cfg(chip, cfg, IREG_LOGDEVICE, num))
 655		return -EIO;
 656	if (snd_msnd_write_cfg(chip, cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
 657		return -EIO;
 658	if (snd_msnd_write_cfg(chip, cfg, IREG_MEMBASELO, LOBYTE(wmem)))
 659		return -EIO;
 660	if (wmem && snd_msnd_write_cfg(chip, cfg, IREG_MEMCONTROL,
 661				       MEMTYPE_HIADDR | MEMTYPE_16BIT))
 662		return -EIO;
 663	return 0;
 664}
 665
 666static int snd_msnd_activate_logical(struct snd_msnd *chip, int cfg, int num)
 667{
 668	if (snd_msnd_write_cfg(chip, cfg, IREG_LOGDEVICE, num))
 669		return -EIO;
 670	if (snd_msnd_write_cfg(chip, cfg, IREG_ACTIVATE, LD_ACTIVATE))
 671		return -EIO;
 672	return 0;
 673}
 674
 675static int snd_msnd_write_cfg_logical(struct snd_msnd *chip,
 676				      int cfg, int num, u16 io0,
 677				      u16 io1, u16 irq, int mem)
 678{
 679	if (snd_msnd_write_cfg(chip, cfg, IREG_LOGDEVICE, num))
 680		return -EIO;
 681	if (snd_msnd_write_cfg_io0(chip, cfg, num, io0))
 682		return -EIO;
 683	if (snd_msnd_write_cfg_io1(chip, cfg, num, io1))
 684		return -EIO;
 685	if (snd_msnd_write_cfg_irq(chip, cfg, num, irq))
 686		return -EIO;
 687	if (snd_msnd_write_cfg_mem(chip, cfg, num, mem))
 688		return -EIO;
 689	if (snd_msnd_activate_logical(chip, cfg, num))
 690		return -EIO;
 691	return 0;
 692}
 693
 694static int snd_msnd_pinnacle_cfg_reset(struct snd_msnd *chip, int cfg)
 695{
 696	int i;
 697
 698	/* Reset devices if told to */
 699	dev_info(chip->card->dev, LOGNAME ": Resetting all devices\n");
 700	for (i = 0; i < 4; ++i)
 701		if (snd_msnd_write_cfg_logical(chip, cfg, i, 0, 0, 0, 0))
 702			return -EIO;
 703
 704	return 0;
 705}
 706#endif
 707
 708static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 709static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 710
 711module_param_array(index, int, NULL, 0444);
 712MODULE_PARM_DESC(index, "Index value for msnd_pinnacle soundcard.");
 713module_param_array(id, charp, NULL, 0444);
 714MODULE_PARM_DESC(id, "ID string for msnd_pinnacle soundcard.");
 715
 716static long io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 717static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 718static long mem[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 719
 720#ifndef MSND_CLASSIC
 721static long cfg[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 722
 723/* Extra Peripheral Configuration (Default: Disable) */
 724static long ide_io0[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 725static long ide_io1[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 726static int ide_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
 727
 728static long joystick_io[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
 729/* If we have the digital daugherboard... */
 730static int digital[SNDRV_CARDS];
 731
 732/* Extra Peripheral Configuration */
 733static int reset[SNDRV_CARDS];
 734#endif
 735
 736static int write_ndelay[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 };
 737
 738static int calibrate_signal;
 739
 740#ifdef CONFIG_PNP
 741static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 742module_param_array(isapnp, bool, NULL, 0444);
 743MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard.");
 744#define has_isapnp(x) isapnp[x]
 745#else
 746#define has_isapnp(x) 0
 747#endif
 748
 749MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>");
 750MODULE_DESCRIPTION("Turtle Beach " LONGNAME " Linux Driver");
 751MODULE_LICENSE("GPL");
 752MODULE_FIRMWARE(INITCODEFILE);
 753MODULE_FIRMWARE(PERMCODEFILE);
 754
 755module_param_hw_array(io, long, ioport, NULL, 0444);
 756MODULE_PARM_DESC(io, "IO port #");
 757module_param_hw_array(irq, int, irq, NULL, 0444);
 758module_param_hw_array(mem, long, iomem, NULL, 0444);
 759module_param_array(write_ndelay, int, NULL, 0444);
 760module_param(calibrate_signal, int, 0444);
 761#ifndef MSND_CLASSIC
 762module_param_array(digital, int, NULL, 0444);
 763module_param_hw_array(cfg, long, ioport, NULL, 0444);
 764module_param_array(reset, int, NULL, 0444);
 765module_param_hw_array(mpu_io, long, ioport, NULL, 0444);
 766module_param_hw_array(mpu_irq, int, irq, NULL, 0444);
 767module_param_hw_array(ide_io0, long, ioport, NULL, 0444);
 768module_param_hw_array(ide_io1, long, ioport, NULL, 0444);
 769module_param_hw_array(ide_irq, int, irq, NULL, 0444);
 770module_param_hw_array(joystick_io, long, ioport, NULL, 0444);
 771#endif
 772
 773
 774static int snd_msnd_isa_match(struct device *pdev, unsigned int i)
 775{
 776	if (io[i] == SNDRV_AUTO_PORT)
 777		return 0;
 778
 779	if (irq[i] == SNDRV_AUTO_PORT || mem[i] == SNDRV_AUTO_PORT) {
 780		dev_warn(pdev, LOGNAME ": io, irq and mem must be set\n");
 781		return 0;
 782	}
 783
 784#ifdef MSND_CLASSIC
 785	if (!(io[i] == 0x290 ||
 786	      io[i] == 0x260 ||
 787	      io[i] == 0x250 ||
 788	      io[i] == 0x240 ||
 789	      io[i] == 0x230 ||
 790	      io[i] == 0x220 ||
 791	      io[i] == 0x210 ||
 792	      io[i] == 0x3e0)) {
 793		dev_err(pdev, LOGNAME ": \"io\" - DSP I/O base must be set "
 794			" to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, "
 795			"or 0x3E0\n");
 796		return 0;
 797	}
 798#else
 799	if (io[i] < 0x100 || io[i] > 0x3e0 || (io[i] % 0x10) != 0) {
 800		dev_err(pdev, LOGNAME
 801			": \"io\" - DSP I/O base must within the range 0x100 "
 802			"to 0x3E0 and must be evenly divisible by 0x10\n");
 803		return 0;
 804	}
 805#endif /* MSND_CLASSIC */
 806
 807	if (!(irq[i] == 5 ||
 808	      irq[i] == 7 ||
 809	      irq[i] == 9 ||
 810	      irq[i] == 10 ||
 811	      irq[i] == 11 ||
 812	      irq[i] == 12)) {
 813		dev_err(pdev, LOGNAME
 814			": \"irq\" - must be set to 5, 7, 9, 10, 11 or 12\n");
 815		return 0;
 816	}
 817
 818	if (!(mem[i] == 0xb0000 ||
 819	      mem[i] == 0xc8000 ||
 820	      mem[i] == 0xd0000 ||
 821	      mem[i] == 0xd8000 ||
 822	      mem[i] == 0xe0000 ||
 823	      mem[i] == 0xe8000)) {
 824		dev_err(pdev, LOGNAME ": \"mem\" - must be set to "
 825		       "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or "
 826		       "0xe8000\n");
 827		return 0;
 828	}
 829
 830#ifndef MSND_CLASSIC
 831	if (cfg[i] == SNDRV_AUTO_PORT) {
 832		dev_info(pdev, LOGNAME ": Assuming PnP mode\n");
 833	} else if (cfg[i] != 0x250 && cfg[i] != 0x260 && cfg[i] != 0x270) {
 834		dev_info(pdev, LOGNAME
 835			": Config port must be 0x250, 0x260 or 0x270 "
 836			"(or unspecified for PnP mode)\n");
 837		return 0;
 838	}
 839#endif /* MSND_CLASSIC */
 840
 841	return 1;
 842}
 843
 844static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
 845{
 846	int err;
 847	struct snd_card *card;
 848	struct snd_msnd *chip;
 849
 850	if (has_isapnp(idx)
 851#ifndef MSND_CLASSIC
 852	    || cfg[idx] == SNDRV_AUTO_PORT
 853#endif
 854	    ) {
 855		dev_info(pdev, LOGNAME ": Assuming PnP mode\n");
 856		return -ENODEV;
 857	}
 858
 859	err = snd_devm_card_new(pdev, index[idx], id[idx], THIS_MODULE,
 860				sizeof(struct snd_msnd), &card);
 861	if (err < 0)
 862		return err;
 863
 864	chip = card->private_data;
 865	chip->card = card;
 866
 867#ifdef MSND_CLASSIC
 868	switch (irq[idx]) {
 869	case 5:
 870		chip->irqid = HPIRQ_5; break;
 871	case 7:
 872		chip->irqid = HPIRQ_7; break;
 873	case 9:
 874		chip->irqid = HPIRQ_9; break;
 875	case 10:
 876		chip->irqid = HPIRQ_10; break;
 877	case 11:
 878		chip->irqid = HPIRQ_11; break;
 879	case 12:
 880		chip->irqid = HPIRQ_12; break;
 881	}
 882
 883	switch (mem[idx]) {
 884	case 0xb0000:
 885		chip->memid = HPMEM_B000; break;
 886	case 0xc8000:
 887		chip->memid = HPMEM_C800; break;
 888	case 0xd0000:
 889		chip->memid = HPMEM_D000; break;
 890	case 0xd8000:
 891		chip->memid = HPMEM_D800; break;
 892	case 0xe0000:
 893		chip->memid = HPMEM_E000; break;
 894	case 0xe8000:
 895		chip->memid = HPMEM_E800; break;
 896	}
 897#else
 898	dev_info(pdev, LOGNAME ": Non-PnP mode: configuring at port 0x%lx\n",
 899		 cfg[idx]);
 900
 901	if (!devm_request_region(card->dev, cfg[idx], 2,
 902				 "Pinnacle/Fiji Config")) {
 903		dev_err(pdev, LOGNAME ": Config port 0x%lx conflict\n",
 904			cfg[idx]);
 905		return -EIO;
 906	}
 907	if (reset[idx])
 908		if (snd_msnd_pinnacle_cfg_reset(chip, cfg[idx]))
 909			return -EIO;
 910
 911	/* DSP */
 912	err = snd_msnd_write_cfg_logical(chip, cfg[idx], 0,
 913					 io[idx], 0,
 914					 irq[idx], mem[idx]);
 915
 916	if (err)
 917		return err;
 918
 919	/* The following are Pinnacle specific */
 920
 921	/* MPU */
 922	if (mpu_io[idx] != SNDRV_AUTO_PORT
 923	    && mpu_irq[idx] != SNDRV_AUTO_IRQ) {
 924		dev_info(pdev, LOGNAME
 925		       ": Configuring MPU to I/O 0x%lx IRQ %d\n",
 926		       mpu_io[idx], mpu_irq[idx]);
 927		err = snd_msnd_write_cfg_logical(chip, cfg[idx], 1,
 928						 mpu_io[idx], 0,
 929						 mpu_irq[idx], 0);
 930
 931		if (err)
 932			return err;
 933	}
 934
 935	/* IDE */
 936	if (ide_io0[idx] != SNDRV_AUTO_PORT
 937	    && ide_io1[idx] != SNDRV_AUTO_PORT
 938	    && ide_irq[idx] != SNDRV_AUTO_IRQ) {
 939		dev_info(pdev, LOGNAME
 940		       ": Configuring IDE to I/O 0x%lx, 0x%lx IRQ %d\n",
 941		       ide_io0[idx], ide_io1[idx], ide_irq[idx]);
 942		err = snd_msnd_write_cfg_logical(chip, cfg[idx], 2,
 943						 ide_io0[idx], ide_io1[idx],
 944						 ide_irq[idx], 0);
 945
 946		if (err)
 947			return err;
 948	}
 949
 950	/* Joystick */
 951	if (joystick_io[idx] != SNDRV_AUTO_PORT) {
 952		dev_info(pdev, LOGNAME
 953		       ": Configuring joystick to I/O 0x%lx\n",
 954		       joystick_io[idx]);
 955		err = snd_msnd_write_cfg_logical(chip, cfg[idx], 3,
 956						 joystick_io[idx], 0,
 957						 0, 0);
 958
 959		if (err)
 960			return err;
 961	}
 962
 963#endif /* MSND_CLASSIC */
 964
 965	set_default_audio_parameters(chip);
 966#ifdef MSND_CLASSIC
 967	chip->type = msndClassic;
 968#else
 969	chip->type = msndPinnacle;
 970#endif
 971	chip->io = io[idx];
 972	chip->irq = irq[idx];
 973	chip->base = mem[idx];
 974
 975	chip->calibrate_signal = calibrate_signal ? 1 : 0;
 976	chip->recsrc = 0;
 977	chip->dspq_data_buff = DSPQ_DATA_BUFF;
 978	chip->dspq_buff_size = DSPQ_BUFF_SIZE;
 979	if (write_ndelay[idx])
 980		clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
 981	else
 982		set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
 983#ifndef MSND_CLASSIC
 984	if (digital[idx])
 985		set_bit(F_HAVEDIGITAL, &chip->flags);
 986#endif
 987	spin_lock_init(&chip->lock);
 988	err = snd_msnd_probe(card);
 989	if (err < 0) {
 990		dev_err(pdev, LOGNAME ": Probe failed\n");
 991		return err;
 992	}
 993
 994	err = snd_msnd_attach(card);
 995	if (err < 0) {
 996		dev_err(pdev, LOGNAME ": Attach failed\n");
 997		return err;
 998	}
 999	dev_set_drvdata(pdev, card);
1000
1001	return 0;
1002}
1003
1004static struct isa_driver snd_msnd_driver = {
1005	.match		= snd_msnd_isa_match,
1006	.probe		= snd_msnd_isa_probe,
1007	/* FIXME: suspend, resume */
1008	.driver		= {
1009		.name	= DEV_NAME
1010	},
1011};
1012
1013#ifdef CONFIG_PNP
1014static int snd_msnd_pnp_detect(struct pnp_card_link *pcard,
1015			       const struct pnp_card_device_id *pid)
1016{
1017	static int idx;
1018	struct pnp_dev *pnp_dev;
1019	struct pnp_dev *mpu_dev;
1020	struct snd_card *card;
1021	struct snd_msnd *chip;
1022	int ret;
1023
1024	for ( ; idx < SNDRV_CARDS; idx++) {
1025		if (has_isapnp(idx))
1026			break;
1027	}
1028	if (idx >= SNDRV_CARDS)
1029		return -ENODEV;
1030
1031	/*
1032	 * Check that we still have room for another sound card ...
1033	 */
1034	pnp_dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
1035	if (!pnp_dev)
1036		return -ENODEV;
1037
1038	mpu_dev = pnp_request_card_device(pcard, pid->devs[1].id, NULL);
1039	if (!mpu_dev)
1040		return -ENODEV;
1041
1042	if (!pnp_is_active(pnp_dev) && pnp_activate_dev(pnp_dev) < 0) {
1043		dev_info(&pcard->card->dev, "msnd_pinnacle: device is inactive\n");
1044		return -EBUSY;
1045	}
1046
1047	if (!pnp_is_active(mpu_dev) && pnp_activate_dev(mpu_dev) < 0) {
1048		dev_info(&pcard->card->dev, "msnd_pinnacle: MPU device is inactive\n");
1049		return -EBUSY;
1050	}
1051
1052	/*
1053	 * Create a new ALSA sound card entry, in anticipation
1054	 * of detecting our hardware ...
1055	 */
1056	ret = snd_devm_card_new(&pcard->card->dev,
1057				index[idx], id[idx], THIS_MODULE,
1058				sizeof(struct snd_msnd), &card);
1059	if (ret < 0)
1060		return ret;
1061
1062	chip = card->private_data;
1063	chip->card = card;
1064
1065	/*
1066	 * Read the correct parameters off the ISA PnP bus ...
1067	 */
1068	io[idx] = pnp_port_start(pnp_dev, 0);
1069	irq[idx] = pnp_irq(pnp_dev, 0);
1070	mem[idx] = pnp_mem_start(pnp_dev, 0);
1071	mpu_io[idx] = pnp_port_start(mpu_dev, 0);
1072	mpu_irq[idx] = pnp_irq(mpu_dev, 0);
1073
1074	set_default_audio_parameters(chip);
1075#ifdef MSND_CLASSIC
1076	chip->type = msndClassic;
1077#else
1078	chip->type = msndPinnacle;
1079#endif
1080	chip->io = io[idx];
1081	chip->irq = irq[idx];
1082	chip->base = mem[idx];
1083
1084	chip->calibrate_signal = calibrate_signal ? 1 : 0;
1085	chip->recsrc = 0;
1086	chip->dspq_data_buff = DSPQ_DATA_BUFF;
1087	chip->dspq_buff_size = DSPQ_BUFF_SIZE;
1088	if (write_ndelay[idx])
1089		clear_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
1090	else
1091		set_bit(F_DISABLE_WRITE_NDELAY, &chip->flags);
1092#ifndef MSND_CLASSIC
1093	if (digital[idx])
1094		set_bit(F_HAVEDIGITAL, &chip->flags);
1095#endif
1096	spin_lock_init(&chip->lock);
1097	ret = snd_msnd_probe(card);
1098	if (ret < 0) {
1099		dev_err(&pcard->card->dev, LOGNAME ": Probe failed\n");
1100		return ret;
1101	}
1102
1103	ret = snd_msnd_attach(card);
1104	if (ret < 0) {
1105		dev_err(&pcard->card->dev, LOGNAME ": Attach failed\n");
1106		return ret;
1107	}
1108
1109	pnp_set_card_drvdata(pcard, card);
1110	++idx;
1111	return 0;
1112}
1113
1114static int isa_registered;
1115static int pnp_registered;
1116
1117static const struct pnp_card_device_id msnd_pnpids[] = {
1118	/* Pinnacle PnP */
1119	{ .id = "BVJ0440", .devs = { { "TBS0000" }, { "TBS0001" } } },
1120	{ .id = "" }	/* end */
1121};
1122
1123MODULE_DEVICE_TABLE(pnp_card, msnd_pnpids);
1124
1125static struct pnp_card_driver msnd_pnpc_driver = {
1126	.flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
1127	.name = "msnd_pinnacle",
1128	.id_table = msnd_pnpids,
1129	.probe = snd_msnd_pnp_detect,
1130};
1131#endif /* CONFIG_PNP */
1132
1133static int __init snd_msnd_init(void)
1134{
1135	int err;
1136
1137	err = isa_register_driver(&snd_msnd_driver, SNDRV_CARDS);
1138#ifdef CONFIG_PNP
1139	if (!err)
1140		isa_registered = 1;
1141
1142	err = pnp_register_card_driver(&msnd_pnpc_driver);
1143	if (!err)
1144		pnp_registered = 1;
1145
1146	if (isa_registered)
1147		err = 0;
1148#endif
1149	return err;
1150}
1151
1152static void __exit snd_msnd_exit(void)
1153{
1154#ifdef CONFIG_PNP
1155	if (pnp_registered)
1156		pnp_unregister_card_driver(&msnd_pnpc_driver);
1157	if (isa_registered)
1158#endif
1159		isa_unregister_driver(&snd_msnd_driver);
1160}
1161
1162module_init(snd_msnd_init);
1163module_exit(snd_msnd_exit);
1164
~/ Read-only file preview.