brintos

brintos / linux-shallow public Read only

0
0
Text · 19.2 KiB · e2def87 Raw
818 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Driver for Digigram VX soundcards4 *5 * Hardware core part6 *7 * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>8 */9 10#include <linux/delay.h>11#include <linux/slab.h>12#include <linux/interrupt.h>13#include <linux/init.h>14#include <linux/device.h>15#include <linux/firmware.h>16#include <linux/module.h>17#include <linux/io.h>18#include <sound/core.h>19#include <sound/pcm.h>20#include <sound/asoundef.h>21#include <sound/info.h>22#include <sound/vx_core.h>23#include "vx_cmd.h"24 25MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");26MODULE_DESCRIPTION("Common routines for Digigram VX drivers");27MODULE_LICENSE("GPL");28 29 30/*31 * vx_check_reg_bit - wait for the specified bit is set/reset on a register32 * @reg: register to check33 * @mask: bit mask34 * @bit: resultant bit to be checked35 * @time: time-out of loop in msec36 *37 * returns zero if a bit matches, or a negative error code.38 */39int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int time)40{41	unsigned long end_time = jiffies + (time * HZ + 999) / 1000;42	static const char * const reg_names[VX_REG_MAX] = {43		"ICR", "CVR", "ISR", "IVR", "RXH", "RXM", "RXL",44		"DMA", "CDSP", "RFREQ", "RUER/V2", "DATA", "MEMIRQ",45		"ACQ", "BIT0", "BIT1", "MIC0", "MIC1", "MIC2",46		"MIC3", "INTCSR", "CNTRL", "GPIOC",47		"LOFREQ", "HIFREQ", "CSUER", "RUER"48	};49 50	do {51		if ((snd_vx_inb(chip, reg) & mask) == bit)52			return 0;53		//msleep(10);54	} while (time_after_eq(end_time, jiffies));55	dev_dbg(chip->card->dev,56		"vx_check_reg_bit: timeout, reg=%s, mask=0x%x, val=0x%x\n",57		reg_names[reg], mask, snd_vx_inb(chip, reg));58	return -EIO;59}60 61EXPORT_SYMBOL(snd_vx_check_reg_bit);62 63/*64 * vx_send_irq_dsp - set command irq bit65 * @num: the requested IRQ type, IRQ_XXX66 *67 * this triggers the specified IRQ request68 * returns 0 if successful, or a negative error code.69 * 70 */71static int vx_send_irq_dsp(struct vx_core *chip, int num)72{73	int nirq;74 75	/* wait for Hc = 0 */76	if (snd_vx_check_reg_bit(chip, VX_CVR, CVR_HC, 0, 200) < 0)77		return -EIO;78 79	nirq = num;80	if (vx_has_new_dsp(chip))81		nirq += VXP_IRQ_OFFSET;82	vx_outb(chip, CVR, (nirq >> 1) | CVR_HC);83	return 0;84}85 86 87/*88 * vx_reset_chk - reset CHK bit on ISR89 *90 * returns 0 if successful, or a negative error code.91 */92static int vx_reset_chk(struct vx_core *chip)93{94	/* Reset irq CHK */95	if (vx_send_irq_dsp(chip, IRQ_RESET_CHK) < 0)96		return -EIO;97	/* Wait until CHK = 0 */98	if (vx_check_isr(chip, ISR_CHK, 0, 200) < 0)99		return -EIO;100	return 0;101}102 103/*104 * vx_transfer_end - terminate message transfer105 * @cmd: IRQ message to send (IRQ_MESS_XXX_END)106 *107 * returns 0 if successful, or a negative error code.108 * the error code can be VX-specific, retrieved via vx_get_error().109 * NB: call with mutex held!110 */111static int vx_transfer_end(struct vx_core *chip, int cmd)112{113	int err;114 115	err = vx_reset_chk(chip);116	if (err < 0)117		return err;118 119	/* irq MESS_READ/WRITE_END */120	err = vx_send_irq_dsp(chip, cmd);121	if (err < 0)122		return err;123 124	/* Wait CHK = 1 */125	err = vx_wait_isr_bit(chip, ISR_CHK);126	if (err < 0)127		return err;128 129	/* If error, Read RX */130	err = vx_inb(chip, ISR);131	if (err & ISR_ERR) {132		err = vx_wait_for_rx_full(chip);133		if (err < 0) {134			dev_dbg(chip->card->dev,135				"transfer_end: error in rx_full\n");136			return err;137		}138		err = vx_inb(chip, RXH) << 16;139		err |= vx_inb(chip, RXM) << 8;140		err |= vx_inb(chip, RXL);141		dev_dbg(chip->card->dev, "transfer_end: error = 0x%x\n", err);142		return -(VX_ERR_MASK | err);143	}144	return 0;145}146 147/*148 * vx_read_status - return the status rmh149 * @rmh: rmh record to store the status150 *151 * returns 0 if successful, or a negative error code.152 * the error code can be VX-specific, retrieved via vx_get_error().153 * NB: call with mutex held!154 */155static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh)156{157	int i, err, val, size;158 159	/* no read necessary? */160	if (rmh->DspStat == RMH_SSIZE_FIXED && rmh->LgStat == 0)161		return 0;162 163	/* Wait for RX full (with timeout protection)164	 * The first word of status is in RX165	 */166	err = vx_wait_for_rx_full(chip);167	if (err < 0)168		return err;169 170	/* Read RX */171	val = vx_inb(chip, RXH) << 16;172	val |= vx_inb(chip, RXM) << 8;173	val |= vx_inb(chip, RXL);174 175	/* If status given by DSP, let's decode its size */176	switch (rmh->DspStat) {177	case RMH_SSIZE_ARG:178		size = val & 0xff;179		rmh->Stat[0] = val & 0xffff00;180		rmh->LgStat = size + 1;181		break;182	case RMH_SSIZE_MASK:183		/* Let's count the arg numbers from a mask */184		rmh->Stat[0] = val;185		size = 0;186		while (val) {187			if (val & 0x01)188				size++;189			val >>= 1;190		}191		rmh->LgStat = size + 1;192		break;193	default:194		/* else retrieve the status length given by the driver */195		size = rmh->LgStat;196		rmh->Stat[0] = val;  /* Val is the status 1st word */197		size--;              /* hence adjust remaining length */198		break;199        }200 201	if (size < 1)202		return 0;203	if (snd_BUG_ON(size >= SIZE_MAX_STATUS))204		return -EINVAL;205 206	for (i = 1; i <= size; i++) {207		/* trigger an irq MESS_WRITE_NEXT */208		err = vx_send_irq_dsp(chip, IRQ_MESS_WRITE_NEXT);209		if (err < 0)210			return err;211		/* Wait for RX full (with timeout protection) */212		err = vx_wait_for_rx_full(chip);213		if (err < 0)214			return err;215		rmh->Stat[i] = vx_inb(chip, RXH) << 16;216		rmh->Stat[i] |= vx_inb(chip, RXM) <<  8;217		rmh->Stat[i] |= vx_inb(chip, RXL);218	}219 220	return vx_transfer_end(chip, IRQ_MESS_WRITE_END);221}222 223 224#define MASK_MORE_THAN_1_WORD_COMMAND   0x00008000225#define MASK_1_WORD_COMMAND             0x00ff7fff226 227/*228 * vx_send_msg_nolock - send a DSP message and read back the status229 * @rmh: the rmh record to send and receive230 *231 * returns 0 if successful, or a negative error code.232 * the error code can be VX-specific, retrieved via vx_get_error().233 * 234 * this function doesn't call mutex lock at all.235 */236int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)237{238	int i, err;239	240	if (chip->chip_status & VX_STAT_IS_STALE)241		return -EBUSY;242 243	err = vx_reset_chk(chip);244	if (err < 0) {245		dev_dbg(chip->card->dev, "vx_send_msg: vx_reset_chk error\n");246		return err;247	}248 249	/* Check bit M is set according to length of the command */250	if (rmh->LgCmd > 1)251		rmh->Cmd[0] |= MASK_MORE_THAN_1_WORD_COMMAND;252	else253		rmh->Cmd[0] &= MASK_1_WORD_COMMAND;254 255	/* Wait for TX empty */256	err = vx_wait_isr_bit(chip, ISR_TX_EMPTY);257	if (err < 0) {258		dev_dbg(chip->card->dev, "vx_send_msg: wait tx empty error\n");259		return err;260	}261 262	/* Write Cmd[0] */263	vx_outb(chip, TXH, (rmh->Cmd[0] >> 16) & 0xff);264	vx_outb(chip, TXM, (rmh->Cmd[0] >> 8) & 0xff);265	vx_outb(chip, TXL, rmh->Cmd[0] & 0xff);266 267	/* Trigger irq MESSAGE */268	err = vx_send_irq_dsp(chip, IRQ_MESSAGE);269	if (err < 0) {270		dev_dbg(chip->card->dev,271			"vx_send_msg: send IRQ_MESSAGE error\n");272		return err;273	}274 275	/* Wait for CHK = 1 */276	err = vx_wait_isr_bit(chip, ISR_CHK);277	if (err < 0)278		return err;279 280	/* If error, get error value from RX */281	if (vx_inb(chip, ISR) & ISR_ERR) {282		err = vx_wait_for_rx_full(chip);283		if (err < 0) {284			dev_dbg(chip->card->dev,285				"vx_send_msg: rx_full read error\n");286			return err;287		}288		err = vx_inb(chip, RXH) << 16;289		err |= vx_inb(chip, RXM) << 8;290		err |= vx_inb(chip, RXL);291		dev_dbg(chip->card->dev,292			"msg got error = 0x%x at cmd[0]\n", err);293		err = -(VX_ERR_MASK | err);294		return err;295	}296 297	/* Send the other words */298	if (rmh->LgCmd > 1) {299		for (i = 1; i < rmh->LgCmd; i++) {300			/* Wait for TX ready */301			err = vx_wait_isr_bit(chip, ISR_TX_READY);302			if (err < 0) {303				dev_dbg(chip->card->dev,304					"vx_send_msg: tx_ready error\n");305				return err;306			}307 308			/* Write Cmd[i] */309			vx_outb(chip, TXH, (rmh->Cmd[i] >> 16) & 0xff);310			vx_outb(chip, TXM, (rmh->Cmd[i] >> 8) & 0xff);311			vx_outb(chip, TXL, rmh->Cmd[i] & 0xff);312 313			/* Trigger irq MESS_READ_NEXT */314			err = vx_send_irq_dsp(chip, IRQ_MESS_READ_NEXT);315			if (err < 0) {316				dev_dbg(chip->card->dev,317					"vx_send_msg: IRQ_READ_NEXT error\n");318				return err;319			}320		}321		/* Wait for TX empty */322		err = vx_wait_isr_bit(chip, ISR_TX_READY);323		if (err < 0) {324			dev_dbg(chip->card->dev,325				"vx_send_msg: TX_READY error\n");326			return err;327		}328		/* End of transfer */329		err = vx_transfer_end(chip, IRQ_MESS_READ_END);330		if (err < 0)331			return err;332	}333 334	return vx_read_status(chip, rmh);335}336 337 338/*339 * vx_send_msg - send a DSP message with mutex340 * @rmh: the rmh record to send and receive341 *342 * returns 0 if successful, or a negative error code.343 * see vx_send_msg_nolock().344 */345int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh)346{347	int err;348 349	mutex_lock(&chip->lock);350	err = vx_send_msg_nolock(chip, rmh);351	mutex_unlock(&chip->lock);352	return err;353}354 355 356/*357 * vx_send_rih_nolock - send an RIH to xilinx358 * @cmd: the command to send359 *360 * returns 0 if successful, or a negative error code.361 * the error code can be VX-specific, retrieved via vx_get_error().362 *363 * this function doesn't call mutex at all.364 *365 * unlike RMH, no command is sent to DSP.366 */367int vx_send_rih_nolock(struct vx_core *chip, int cmd)368{369	int err;370 371	if (chip->chip_status & VX_STAT_IS_STALE)372		return -EBUSY;373 374	err = vx_reset_chk(chip);375	if (err < 0)376		return err;377	/* send the IRQ */378	err = vx_send_irq_dsp(chip, cmd);379	if (err < 0)380		return err;381	/* Wait CHK = 1 */382	err = vx_wait_isr_bit(chip, ISR_CHK);383	if (err < 0)384		return err;385	/* If error, read RX */386	if (vx_inb(chip, ISR) & ISR_ERR) {387		err = vx_wait_for_rx_full(chip);388		if (err < 0)389			return err;390		err = vx_inb(chip, RXH) << 16;391		err |= vx_inb(chip, RXM) << 8;392		err |= vx_inb(chip, RXL);393		return -(VX_ERR_MASK | err);394	}395	return 0;396}397 398 399/*400 * vx_send_rih - send an RIH with mutex401 * @cmd: the command to send402 *403 * see vx_send_rih_nolock().404 */405int vx_send_rih(struct vx_core *chip, int cmd)406{407	int err;408 409	mutex_lock(&chip->lock);410	err = vx_send_rih_nolock(chip, cmd);411	mutex_unlock(&chip->lock);412	return err;413}414 415#define END_OF_RESET_WAIT_TIME		500	/* us */416 417/**418 * snd_vx_load_boot_image - boot up the xilinx interface419 * @chip: VX core instance420 * @boot: the boot record to load421 */422int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)423{424	unsigned int i;425	int no_fillup = vx_has_new_dsp(chip);426 427	/* check the length of boot image */428	if (boot->size <= 0)429		return -EINVAL;430	if (boot->size % 3)431		return -EINVAL;432#if 0433	{434		/* more strict check */435		unsigned int c = ((u32)boot->data[0] << 16) | ((u32)boot->data[1] << 8) | boot->data[2];436		if (boot->size != (c + 2) * 3)437			return -EINVAL;438	}439#endif440 441	/* reset dsp */442	vx_reset_dsp(chip);443	444	udelay(END_OF_RESET_WAIT_TIME); /* another wait? */445 446	/* download boot strap */447	for (i = 0; i < 0x600; i += 3) {448		if (i >= boot->size) {449			if (no_fillup)450				break;451			if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {452				dev_err(chip->card->dev, "dsp boot failed at %d\n", i);453				return -EIO;454			}455			vx_outb(chip, TXH, 0);456			vx_outb(chip, TXM, 0);457			vx_outb(chip, TXL, 0);458		} else {459			const unsigned char *image = boot->data + i;460			if (vx_wait_isr_bit(chip, ISR_TX_EMPTY) < 0) {461				dev_err(chip->card->dev, "dsp boot failed at %d\n", i);462				return -EIO;463			}464			vx_outb(chip, TXH, image[0]);465			vx_outb(chip, TXM, image[1]);466			vx_outb(chip, TXL, image[2]);467		}468	}469	return 0;470}471 472EXPORT_SYMBOL(snd_vx_load_boot_image);473 474/*475 * vx_test_irq_src - query the source of interrupts476 *477 * called from irq handler only478 */479static int vx_test_irq_src(struct vx_core *chip, unsigned int *ret)480{481	int err;482 483	vx_init_rmh(&chip->irq_rmh, CMD_TEST_IT);484	mutex_lock(&chip->lock);485	err = vx_send_msg_nolock(chip, &chip->irq_rmh);486	if (err < 0)487		*ret = 0;488	else489		*ret = chip->irq_rmh.Stat[0];490	mutex_unlock(&chip->lock);491	return err;492}493 494 495/*496 * snd_vx_threaded_irq_handler - threaded irq handler497 */498irqreturn_t snd_vx_threaded_irq_handler(int irq, void *dev)499{500	struct vx_core *chip = dev;501	unsigned int events;502		503	if (chip->chip_status & VX_STAT_IS_STALE)504		return IRQ_HANDLED;505 506	if (vx_test_irq_src(chip, &events) < 0)507		return IRQ_HANDLED;508    509	/* We must prevent any application using this DSP510	 * and block any further request until the application511	 * either unregisters or reloads the DSP512	 */513	if (events & FATAL_DSP_ERROR) {514		dev_err(chip->card->dev, "vx_core: fatal DSP error!!\n");515		return IRQ_HANDLED;516	}517 518	/* The start on time code conditions are filled (ie the time code519	 * received by the board is equal to one of those given to it).520	 */521	if (events & TIME_CODE_EVENT_PENDING) {522		; /* so far, nothing to do yet */523	}524 525	/* The frequency has changed on the board (UER mode). */526	if (events & FREQUENCY_CHANGE_EVENT_PENDING)527		vx_change_frequency(chip);528 529	/* update the pcm streams */530	vx_pcm_update_intr(chip, events);531	return IRQ_HANDLED;532}533EXPORT_SYMBOL(snd_vx_threaded_irq_handler);534 535/**536 * snd_vx_irq_handler - interrupt handler537 * @irq: irq number538 * @dev: VX core instance539 */540irqreturn_t snd_vx_irq_handler(int irq, void *dev)541{542	struct vx_core *chip = dev;543 544	if (! (chip->chip_status & VX_STAT_CHIP_INIT) ||545	    (chip->chip_status & VX_STAT_IS_STALE))546		return IRQ_NONE;547	if (! vx_test_and_ack(chip))548		return IRQ_WAKE_THREAD;549	return IRQ_NONE;550}551 552EXPORT_SYMBOL(snd_vx_irq_handler);553 554/*555 */556static void vx_reset_board(struct vx_core *chip, int cold_reset)557{558	if (snd_BUG_ON(!chip->ops->reset_board))559		return;560 561	/* current source, later sync'ed with target */562	chip->audio_source = VX_AUDIO_SRC_LINE;563	if (cold_reset) {564		chip->audio_source_target = chip->audio_source;565		chip->clock_source = INTERNAL_QUARTZ;566		chip->clock_mode = VX_CLOCK_MODE_AUTO;567		chip->freq = 48000;568		chip->uer_detected = VX_UER_MODE_NOT_PRESENT;569		chip->uer_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;570	}571 572	chip->ops->reset_board(chip, cold_reset);573 574	vx_reset_codec(chip, cold_reset);575 576	vx_set_internal_clock(chip, chip->freq);577 578	/* Reset the DSP */579	vx_reset_dsp(chip);580 581	if (vx_is_pcmcia(chip)) {582		/* Acknowledge any pending IRQ and reset the MEMIRQ flag. */583		vx_test_and_ack(chip);584		vx_validate_irq(chip, 1);585	}586 587	/* init CBits */588	vx_set_iec958_status(chip, chip->uer_bits);589}590 591 592/*593 * proc interface594 */595 596static void vx_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)597{598	struct vx_core *chip = entry->private_data;599	static const char * const audio_src_vxp[] = { "Line", "Mic", "Digital" };600	static const char * const audio_src_vx2[] = { "Analog", "Analog", "Digital" };601	static const char * const clock_mode[] = { "Auto", "Internal", "External" };602	static const char * const clock_src[] = { "Internal", "External" };603	static const char * const uer_type[] = { "Consumer", "Professional", "Not Present" };604	605	snd_iprintf(buffer, "%s\n", chip->card->longname);606	snd_iprintf(buffer, "Xilinx Firmware: %s\n",607		    (chip->chip_status & VX_STAT_XILINX_LOADED) ? "Loaded" : "No");608	snd_iprintf(buffer, "Device Initialized: %s\n",609		    (chip->chip_status & VX_STAT_DEVICE_INIT) ? "Yes" : "No");610	snd_iprintf(buffer, "DSP audio info:");611	if (chip->audio_info & VX_AUDIO_INFO_REAL_TIME)612		snd_iprintf(buffer, " realtime");613	if (chip->audio_info & VX_AUDIO_INFO_OFFLINE)614		snd_iprintf(buffer, " offline");615	if (chip->audio_info & VX_AUDIO_INFO_MPEG1)616		snd_iprintf(buffer, " mpeg1");617	if (chip->audio_info & VX_AUDIO_INFO_MPEG2)618		snd_iprintf(buffer, " mpeg2");619	if (chip->audio_info & VX_AUDIO_INFO_LINEAR_8)620		snd_iprintf(buffer, " linear8");621	if (chip->audio_info & VX_AUDIO_INFO_LINEAR_16)622		snd_iprintf(buffer, " linear16");623	if (chip->audio_info & VX_AUDIO_INFO_LINEAR_24)624		snd_iprintf(buffer, " linear24");625	snd_iprintf(buffer, "\n");626	snd_iprintf(buffer, "Input Source: %s\n", vx_is_pcmcia(chip) ?627		    audio_src_vxp[chip->audio_source] :628		    audio_src_vx2[chip->audio_source]);629	snd_iprintf(buffer, "Clock Mode: %s\n", clock_mode[chip->clock_mode]);630	snd_iprintf(buffer, "Clock Source: %s\n", clock_src[chip->clock_source]);631	snd_iprintf(buffer, "Frequency: %d\n", chip->freq);632	snd_iprintf(buffer, "Detected Frequency: %d\n", chip->freq_detected);633	snd_iprintf(buffer, "Detected UER type: %s\n", uer_type[chip->uer_detected]);634	snd_iprintf(buffer, "Min/Max/Cur IBL: %d/%d/%d (granularity=%d)\n",635		    chip->ibl.min_size, chip->ibl.max_size, chip->ibl.size,636		    chip->ibl.granularity);637}638 639static void vx_proc_init(struct vx_core *chip)640{641	snd_card_ro_proc_new(chip->card, "vx-status", chip, vx_proc_read);642}643 644 645/**646 * snd_vx_dsp_boot - load the DSP boot647 * @chip: VX core instance648 * @boot: firmware data649 */650int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot)651{652	int err;653	int cold_reset = !(chip->chip_status & VX_STAT_DEVICE_INIT);654 655	vx_reset_board(chip, cold_reset);656	vx_validate_irq(chip, 0);657 658	err = snd_vx_load_boot_image(chip, boot);659	if (err < 0)660		return err;661	msleep(10);662 663	return 0;664}665 666EXPORT_SYMBOL(snd_vx_dsp_boot);667 668/**669 * snd_vx_dsp_load - load the DSP image670 * @chip: VX core instance671 * @dsp: firmware data672 */673int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)674{675	unsigned int i;676	int err;677	unsigned int csum = 0;678	const unsigned char *image, *cptr;679 680	if (dsp->size % 3)681		return -EINVAL;682 683	vx_toggle_dac_mute(chip, 1);684 685	/* Transfert data buffer from PC to DSP */686	for (i = 0; i < dsp->size; i += 3) {687		image = dsp->data + i;688		/* Wait DSP ready for a new read */689		err = vx_wait_isr_bit(chip, ISR_TX_EMPTY);690		if (err < 0) {691			dev_err(chip->card->dev,692				"dsp loading error at position %d\n", i);693			return err;694		}695		cptr = image;696		csum ^= *cptr;697		csum = (csum >> 24) | (csum << 8);698		vx_outb(chip, TXH, *cptr++);699		csum ^= *cptr;700		csum = (csum >> 24) | (csum << 8);701		vx_outb(chip, TXM, *cptr++);702		csum ^= *cptr;703		csum = (csum >> 24) | (csum << 8);704		vx_outb(chip, TXL, *cptr++);705	}706 707	msleep(200);708 709	err = vx_wait_isr_bit(chip, ISR_CHK);710	if (err < 0)711		return err;712 713	vx_toggle_dac_mute(chip, 0);714 715	vx_test_and_ack(chip);716	vx_validate_irq(chip, 1);717 718	return 0;719}720 721EXPORT_SYMBOL(snd_vx_dsp_load);722 723#ifdef CONFIG_PM724/*725 * suspend726 */727int snd_vx_suspend(struct vx_core *chip)728{729	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);730	chip->chip_status |= VX_STAT_IN_SUSPEND;731 732	return 0;733}734 735EXPORT_SYMBOL(snd_vx_suspend);736 737/*738 * resume739 */740int snd_vx_resume(struct vx_core *chip)741{742	int i, err;743 744	chip->chip_status &= ~VX_STAT_CHIP_INIT;745 746	for (i = 0; i < 4; i++) {747		if (! chip->firmware[i])748			continue;749		err = chip->ops->load_dsp(chip, i, chip->firmware[i]);750		if (err < 0) {751			dev_err(chip->card->dev,752				"vx: firmware resume error at DSP %d\n", i);753			return -EIO;754		}755	}756 757	chip->chip_status |= VX_STAT_CHIP_INIT;758	chip->chip_status &= ~VX_STAT_IN_SUSPEND;759 760	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);761	return 0;762}763 764EXPORT_SYMBOL(snd_vx_resume);765#endif766 767static void snd_vx_release(struct device *dev, void *data)768{769	snd_vx_free_firmware(data);770}771 772/**773 * snd_vx_create - constructor for struct vx_core774 * @card: card instance775 * @hw: hardware specific record776 * @ops: VX ops pointer777 * @extra_size: extra byte size to allocate appending to chip778 *779 * this function allocates the instance and prepare for the hardware780 * initialization.781 *782 * The object is managed via devres, and will be automatically released.783 *784 * return the instance pointer if successful, NULL in error.785 */786struct vx_core *snd_vx_create(struct snd_card *card,787			      const struct snd_vx_hardware *hw,788			      const struct snd_vx_ops *ops,789			      int extra_size)790{791	struct vx_core *chip;792 793	if (snd_BUG_ON(!card || !hw || !ops))794		return NULL;795 796	chip = devres_alloc(snd_vx_release, sizeof(*chip) + extra_size,797			    GFP_KERNEL);798	if (!chip)799		return NULL;800	mutex_init(&chip->lock);801	chip->irq = -1;802	chip->hw = hw;803	chip->type = hw->type;804	chip->ops = ops;805	mutex_init(&chip->mixer_mutex);806 807	chip->card = card;808	card->private_data = chip;809	strcpy(card->driver, hw->name);810	sprintf(card->shortname, "Digigram %s", hw->name);811 812	vx_proc_init(chip);813 814	return chip;815}816 817EXPORT_SYMBOL(snd_vx_create);818