diff options
Diffstat (limited to 'sound/pci/ymfpci')
| -rw-r--r-- | sound/pci/ymfpci/ymfpci.c | 96 | ||||
| -rw-r--r-- | sound/pci/ymfpci/ymfpci.h | 389 | ||||
| -rw-r--r-- | sound/pci/ymfpci/ymfpci_main.c | 195 | 
3 files changed, 564 insertions, 116 deletions
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 80c68211338..82eed164b27 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -22,9 +22,9 @@  #include <linux/init.h>  #include <linux/pci.h>  #include <linux/time.h> -#include <linux/moduleparam.h> +#include <linux/module.h>  #include <sound/core.h> -#include <sound/ymfpci.h> +#include "ymfpci.h"  #include <sound/mpu401.h>  #include <sound/opl3.h>  #include <sound/initval.h> @@ -41,13 +41,13 @@ MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF724},"  static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */  static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */  static long fm_port[SNDRV_CARDS];  static long mpu_port[SNDRV_CARDS];  #ifdef SUPPORT_JOYSTICK  static long joystick_port[SNDRV_CARDS];  #endif -static int rear_switch[SNDRV_CARDS]; +static bool rear_switch[SNDRV_CARDS];  module_param_array(index, int, NULL, 0444);  MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard."); @@ -79,8 +79,8 @@ static DEFINE_PCI_DEVICE_TABLE(snd_ymfpci_ids) = {  MODULE_DEVICE_TABLE(pci, snd_ymfpci_ids);  #ifdef SUPPORT_JOYSTICK -static int __devinit snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, -						int legacy_ctrl, int legacy_ctrl2) +static int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, +				      int legacy_ctrl, int legacy_ctrl2)  {  	struct gameport *gp;  	struct resource *r = NULL; @@ -106,7 +106,8 @@ static int __devinit snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev  					break;  			}  			if (!r) { -				printk(KERN_ERR "ymfpci: no gameport ports available\n"); +				dev_err(chip->card->dev, +					"no gameport ports available\n");  				return -EBUSY;  			}  		} @@ -116,19 +117,22 @@ static int __devinit snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev  		case 0x204: legacy_ctrl2 |= 2 << 6; break;  		case 0x205: legacy_ctrl2 |= 3 << 6; break;  		default: -			printk(KERN_ERR "ymfpci: invalid joystick port %#x", io_port); +			dev_err(chip->card->dev, +				"invalid joystick port %#x", io_port);  			return -EINVAL;  		}  	}  	if (!r && !(r = request_region(io_port, 1, "YMFPCI gameport"))) { -		printk(KERN_ERR "ymfpci: joystick port %#x is in use.\n", io_port); +		dev_err(chip->card->dev, +			"joystick port %#x is in use.\n", io_port);  		return -EBUSY;  	}  	chip->gameport = gp = gameport_allocate_port();  	if (!gp) { -		printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n"); +		dev_err(chip->card->dev, +			"cannot allocate memory for gameport\n");  		release_and_free_resource(r);  		return -ENOMEM;  	} @@ -167,8 +171,8 @@ static inline int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, i  void snd_ymfpci_free_gameport(struct snd_ymfpci *chip) { }  #endif /* SUPPORT_JOYSTICK */ -static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, -					   const struct pci_device_id *pci_id) +static int snd_card_ymfpci_probe(struct pci_dev *pci, +				 const struct pci_device_id *pci_id)  {  	static int dev;  	struct snd_card *card; @@ -187,7 +191,8 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,  		return -ENOENT;  	} -	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); +	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, +			   0, &card);  	if (err < 0)  		return err; @@ -286,17 +291,22 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,  		snd_card_free(card);  		return err;  	} -	if ((err = snd_ymfpci_pcm_4ch(chip, 2, NULL)) < 0) { +	err = snd_ymfpci_mixer(chip, rear_switch[dev]); +	if (err < 0) {  		snd_card_free(card);  		return err;  	} -	if ((err = snd_ymfpci_pcm2(chip, 3, NULL)) < 0) { -		snd_card_free(card); -		return err; -	} -	if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) { -		snd_card_free(card); -		return err; +	if (chip->ac97->ext_id & AC97_EI_SDAC) { +		err = snd_ymfpci_pcm_4ch(chip, 2, NULL); +		if (err < 0) { +			snd_card_free(card); +			return err; +		} +		err = snd_ymfpci_pcm2(chip, 3, NULL); +		if (err < 0) { +			snd_card_free(card); +			return err; +		}  	}  	if ((err = snd_ymfpci_timer(chip, 0)) < 0) {  		snd_card_free(card); @@ -305,9 +315,12 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,  	if (chip->mpu_res) {  		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,  					       mpu_port[dev], -					       MPU401_INFO_INTEGRATED, -					       pci->irq, 0, &chip->rawmidi)) < 0) { -			printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]); +					       MPU401_INFO_INTEGRATED | +					       MPU401_INFO_IRQ_HOOK, +					       -1, &chip->rawmidi)) < 0) { +			dev_warn(card->dev, +				 "cannot initialize MPU401 at 0x%lx, skipping...\n", +				 mpu_port[dev]);  			legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */  			pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);  		} @@ -317,12 +330,14 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,  					   fm_port[dev],  					   fm_port[dev] + 2,  					   OPL3_HW_OPL3, 1, &opl3)) < 0) { -			printk(KERN_WARNING "ymfpci: cannot initialize FM OPL3 at 0x%lx, skipping...\n", fm_port[dev]); +			dev_warn(card->dev, +				 "cannot initialize FM OPL3 at 0x%lx, skipping...\n", +				 fm_port[dev]);  			legacy_ctrl &= ~YMFPCI_LEGACY_FMEN;  			pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);  		} else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {  			snd_card_free(card); -			snd_printk(KERN_ERR "cannot create opl3 hwdep\n"); +			dev_err(card->dev, "cannot create opl3 hwdep\n");  			return err;  		}  	} @@ -338,32 +353,21 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,  	return 0;  } -static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci) +static void snd_card_ymfpci_remove(struct pci_dev *pci)  {  	snd_card_free(pci_get_drvdata(pci)); -	pci_set_drvdata(pci, NULL);  } -static struct pci_driver driver = { -	.name = "Yamaha DS-1 PCI", +static struct pci_driver ymfpci_driver = { +	.name = KBUILD_MODNAME,  	.id_table = snd_ymfpci_ids,  	.probe = snd_card_ymfpci_probe, -	.remove = __devexit_p(snd_card_ymfpci_remove), -#ifdef CONFIG_PM -	.suspend = snd_ymfpci_suspend, -	.resume = snd_ymfpci_resume, +	.remove = snd_card_ymfpci_remove, +#ifdef CONFIG_PM_SLEEP +	.driver = { +		.pm = &snd_ymfpci_pm, +	},  #endif  }; -static int __init alsa_card_ymfpci_init(void) -{ -	return pci_register_driver(&driver); -} - -static void __exit alsa_card_ymfpci_exit(void) -{ -	pci_unregister_driver(&driver); -} - -module_init(alsa_card_ymfpci_init) -module_exit(alsa_card_ymfpci_exit) +module_pci_driver(ymfpci_driver); diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h new file mode 100644 index 00000000000..4631a234891 --- /dev/null +++ b/sound/pci/ymfpci/ymfpci.h @@ -0,0 +1,389 @@ +#ifndef __SOUND_YMFPCI_H +#define __SOUND_YMFPCI_H + +/* + *  Copyright (c) by Jaroslav Kysela <perex@perex.cz> + *  Definitions for Yahama YMF724/740/744/754 chips + * + * + *   This program is free software; you can redistribute it and/or modify + *   it under the terms of the GNU General Public License as published by + *   the Free Software Foundation; either version 2 of the License, or + *   (at your option) any later version. + * + *   This program is distributed in the hope that it will be useful, + *   but WITHOUT ANY WARRANTY; without even the implied warranty of + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *   GNU General Public License for more details. + * + *   You should have received a copy of the GNU General Public License + *   along with this program; if not, write to the Free Software + *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA + * + */ + +#include <sound/pcm.h> +#include <sound/rawmidi.h> +#include <sound/ac97_codec.h> +#include <sound/timer.h> +#include <linux/gameport.h> + +/* + *  Direct registers + */ + +#define YMFREG(chip, reg)		(chip->port + YDSXGR_##reg) + +#define	YDSXGR_INTFLAG			0x0004 +#define	YDSXGR_ACTIVITY			0x0006 +#define	YDSXGR_GLOBALCTRL		0x0008 +#define	YDSXGR_ZVCTRL			0x000A +#define	YDSXGR_TIMERCTRL		0x0010 +#define	YDSXGR_TIMERCOUNT		0x0012 +#define	YDSXGR_SPDIFOUTCTRL		0x0018 +#define	YDSXGR_SPDIFOUTSTATUS		0x001C +#define	YDSXGR_EEPROMCTRL		0x0020 +#define	YDSXGR_SPDIFINCTRL		0x0034 +#define	YDSXGR_SPDIFINSTATUS		0x0038 +#define	YDSXGR_DSPPROGRAMDL		0x0048 +#define	YDSXGR_DLCNTRL			0x004C +#define	YDSXGR_GPIOININTFLAG		0x0050 +#define	YDSXGR_GPIOININTENABLE		0x0052 +#define	YDSXGR_GPIOINSTATUS		0x0054 +#define	YDSXGR_GPIOOUTCTRL		0x0056 +#define	YDSXGR_GPIOFUNCENABLE		0x0058 +#define	YDSXGR_GPIOTYPECONFIG		0x005A +#define	YDSXGR_AC97CMDDATA		0x0060 +#define	YDSXGR_AC97CMDADR		0x0062 +#define	YDSXGR_PRISTATUSDATA		0x0064 +#define	YDSXGR_PRISTATUSADR		0x0066 +#define	YDSXGR_SECSTATUSDATA		0x0068 +#define	YDSXGR_SECSTATUSADR		0x006A +#define	YDSXGR_SECCONFIG		0x0070 +#define	YDSXGR_LEGACYOUTVOL		0x0080 +#define	YDSXGR_LEGACYOUTVOLL		0x0080 +#define	YDSXGR_LEGACYOUTVOLR		0x0082 +#define	YDSXGR_NATIVEDACOUTVOL		0x0084 +#define	YDSXGR_NATIVEDACOUTVOLL		0x0084 +#define	YDSXGR_NATIVEDACOUTVOLR		0x0086 +#define	YDSXGR_ZVOUTVOL			0x0088 +#define	YDSXGR_ZVOUTVOLL		0x0088 +#define	YDSXGR_ZVOUTVOLR		0x008A +#define	YDSXGR_SECADCOUTVOL		0x008C +#define	YDSXGR_SECADCOUTVOLL		0x008C +#define	YDSXGR_SECADCOUTVOLR		0x008E +#define	YDSXGR_PRIADCOUTVOL		0x0090 +#define	YDSXGR_PRIADCOUTVOLL		0x0090 +#define	YDSXGR_PRIADCOUTVOLR		0x0092 +#define	YDSXGR_LEGACYLOOPVOL		0x0094 +#define	YDSXGR_LEGACYLOOPVOLL		0x0094 +#define	YDSXGR_LEGACYLOOPVOLR		0x0096 +#define	YDSXGR_NATIVEDACLOOPVOL		0x0098 +#define	YDSXGR_NATIVEDACLOOPVOLL	0x0098 +#define	YDSXGR_NATIVEDACLOOPVOLR	0x009A +#define	YDSXGR_ZVLOOPVOL		0x009C +#define	YDSXGR_ZVLOOPVOLL		0x009E +#define	YDSXGR_ZVLOOPVOLR		0x009E +#define	YDSXGR_SECADCLOOPVOL		0x00A0 +#define	YDSXGR_SECADCLOOPVOLL		0x00A0 +#define	YDSXGR_SECADCLOOPVOLR		0x00A2 +#define	YDSXGR_PRIADCLOOPVOL		0x00A4 +#define	YDSXGR_PRIADCLOOPVOLL		0x00A4 +#define	YDSXGR_PRIADCLOOPVOLR		0x00A6 +#define	YDSXGR_NATIVEADCINVOL		0x00A8 +#define	YDSXGR_NATIVEADCINVOLL		0x00A8 +#define	YDSXGR_NATIVEADCINVOLR		0x00AA +#define	YDSXGR_NATIVEDACINVOL		0x00AC +#define	YDSXGR_NATIVEDACINVOLL		0x00AC +#define	YDSXGR_NATIVEDACINVOLR		0x00AE +#define	YDSXGR_BUF441OUTVOL		0x00B0 +#define	YDSXGR_BUF441OUTVOLL		0x00B0 +#define	YDSXGR_BUF441OUTVOLR		0x00B2 +#define	YDSXGR_BUF441LOOPVOL		0x00B4 +#define	YDSXGR_BUF441LOOPVOLL		0x00B4 +#define	YDSXGR_BUF441LOOPVOLR		0x00B6 +#define	YDSXGR_SPDIFOUTVOL		0x00B8 +#define	YDSXGR_SPDIFOUTVOLL		0x00B8 +#define	YDSXGR_SPDIFOUTVOLR		0x00BA +#define	YDSXGR_SPDIFLOOPVOL		0x00BC +#define	YDSXGR_SPDIFLOOPVOLL		0x00BC +#define	YDSXGR_SPDIFLOOPVOLR		0x00BE +#define	YDSXGR_ADCSLOTSR		0x00C0 +#define	YDSXGR_RECSLOTSR		0x00C4 +#define	YDSXGR_ADCFORMAT		0x00C8 +#define	YDSXGR_RECFORMAT		0x00CC +#define	YDSXGR_P44SLOTSR		0x00D0 +#define	YDSXGR_STATUS			0x0100 +#define	YDSXGR_CTRLSELECT		0x0104 +#define	YDSXGR_MODE			0x0108 +#define	YDSXGR_SAMPLECOUNT		0x010C +#define	YDSXGR_NUMOFSAMPLES		0x0110 +#define	YDSXGR_CONFIG			0x0114 +#define	YDSXGR_PLAYCTRLSIZE		0x0140 +#define	YDSXGR_RECCTRLSIZE		0x0144 +#define	YDSXGR_EFFCTRLSIZE		0x0148 +#define	YDSXGR_WORKSIZE			0x014C +#define	YDSXGR_MAPOFREC			0x0150 +#define	YDSXGR_MAPOFEFFECT		0x0154 +#define	YDSXGR_PLAYCTRLBASE		0x0158 +#define	YDSXGR_RECCTRLBASE		0x015C +#define	YDSXGR_EFFCTRLBASE		0x0160 +#define	YDSXGR_WORKBASE			0x0164 +#define	YDSXGR_DSPINSTRAM		0x1000 +#define	YDSXGR_CTRLINSTRAM		0x4000 + +#define YDSXG_AC97READCMD		0x8000 +#define YDSXG_AC97WRITECMD		0x0000 + +#define PCIR_DSXG_LEGACY		0x40 +#define PCIR_DSXG_ELEGACY		0x42 +#define PCIR_DSXG_CTRL			0x48 +#define PCIR_DSXG_PWRCTRL1		0x4a +#define PCIR_DSXG_PWRCTRL2		0x4e +#define PCIR_DSXG_FMBASE		0x60 +#define PCIR_DSXG_SBBASE		0x62 +#define PCIR_DSXG_MPU401BASE		0x64 +#define PCIR_DSXG_JOYBASE		0x66 + +#define YDSXG_DSPLENGTH			0x0080 +#define YDSXG_CTRLLENGTH		0x3000 + +#define YDSXG_DEFAULT_WORK_SIZE		0x0400 + +#define YDSXG_PLAYBACK_VOICES		64 +#define YDSXG_CAPTURE_VOICES		2 +#define YDSXG_EFFECT_VOICES		5 + +#define YMFPCI_LEGACY_SBEN	(1 << 0)	/* soundblaster enable */ +#define YMFPCI_LEGACY_FMEN	(1 << 1)	/* OPL3 enable */ +#define YMFPCI_LEGACY_JPEN	(1 << 2)	/* joystick enable */ +#define YMFPCI_LEGACY_MEN	(1 << 3)	/* MPU401 enable */ +#define YMFPCI_LEGACY_MIEN	(1 << 4)	/* MPU RX irq enable */ +#define YMFPCI_LEGACY_IOBITS	(1 << 5)	/* i/o bits range, 0 = 16bit, 1 =10bit */ +#define YMFPCI_LEGACY_SDMA	(3 << 6)	/* SB DMA select */ +#define YMFPCI_LEGACY_SBIRQ	(7 << 8)	/* SB IRQ select */ +#define YMFPCI_LEGACY_MPUIRQ	(7 << 11)	/* MPU IRQ select */ +#define YMFPCI_LEGACY_SIEN	(1 << 14)	/* serialized IRQ */ +#define YMFPCI_LEGACY_LAD	(1 << 15)	/* legacy audio disable */ + +#define YMFPCI_LEGACY2_FMIO	(3 << 0)	/* OPL3 i/o address (724/740) */ +#define YMFPCI_LEGACY2_SBIO	(3 << 2)	/* SB i/o address (724/740) */ +#define YMFPCI_LEGACY2_MPUIO	(3 << 4)	/* MPU401 i/o address (724/740) */ +#define YMFPCI_LEGACY2_JSIO	(3 << 6)	/* joystick i/o address (724/740) */ +#define YMFPCI_LEGACY2_MAIM	(1 << 8)	/* MPU401 ack intr mask */ +#define YMFPCI_LEGACY2_SMOD	(3 << 11)	/* SB DMA mode */ +#define YMFPCI_LEGACY2_SBVER	(3 << 13)	/* SB version select */ +#define YMFPCI_LEGACY2_IMOD	(1 << 15)	/* legacy IRQ mode */ +/* SIEN:IMOD 0:0 = legacy irq, 0:1 = INTA, 1:0 = serialized IRQ */ + +#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) +#define SUPPORT_JOYSTICK +#endif + +/* + * + */ + +struct snd_ymfpci_playback_bank { +	u32 format; +	u32 loop_default; +	u32 base;			/* 32-bit address */ +	u32 loop_start;			/* 32-bit offset */ +	u32 loop_end;			/* 32-bit offset */ +	u32 loop_frac;			/* 8-bit fraction - loop_start */ +	u32 delta_end;			/* pitch delta end */ +	u32 lpfK_end; +	u32 eg_gain_end; +	u32 left_gain_end; +	u32 right_gain_end; +	u32 eff1_gain_end; +	u32 eff2_gain_end; +	u32 eff3_gain_end; +	u32 lpfQ; +	u32 status; +	u32 num_of_frames; +	u32 loop_count; +	u32 start; +	u32 start_frac; +	u32 delta; +	u32 lpfK; +	u32 eg_gain; +	u32 left_gain; +	u32 right_gain; +	u32 eff1_gain; +	u32 eff2_gain; +	u32 eff3_gain; +	u32 lpfD1; +	u32 lpfD2; + }; + +struct snd_ymfpci_capture_bank { +	u32 base;			/* 32-bit address */ +	u32 loop_end;			/* 32-bit offset */ +	u32 start;			/* 32-bit offset */ +	u32 num_of_loops;		/* counter */ +}; + +struct snd_ymfpci_effect_bank { +	u32 base;			/* 32-bit address */ +	u32 loop_end;			/* 32-bit offset */ +	u32 start;			/* 32-bit offset */ +	u32 temp; +}; + +struct snd_ymfpci_pcm; +struct snd_ymfpci; + +enum snd_ymfpci_voice_type { +	YMFPCI_PCM, +	YMFPCI_SYNTH, +	YMFPCI_MIDI +}; + +struct snd_ymfpci_voice { +	struct snd_ymfpci *chip; +	int number; +	unsigned int use: 1, +	    pcm: 1, +	    synth: 1, +	    midi: 1; +	struct snd_ymfpci_playback_bank *bank; +	dma_addr_t bank_addr; +	void (*interrupt)(struct snd_ymfpci *chip, struct snd_ymfpci_voice *voice); +	struct snd_ymfpci_pcm *ypcm; +}; + +enum snd_ymfpci_pcm_type { +	PLAYBACK_VOICE, +	CAPTURE_REC, +	CAPTURE_AC97, +	EFFECT_DRY_LEFT, +	EFFECT_DRY_RIGHT, +	EFFECT_EFF1, +	EFFECT_EFF2, +	EFFECT_EFF3 +}; + +struct snd_ymfpci_pcm { +	struct snd_ymfpci *chip; +	enum snd_ymfpci_pcm_type type; +	struct snd_pcm_substream *substream; +	struct snd_ymfpci_voice *voices[2];	/* playback only */ +	unsigned int running: 1, +		     use_441_slot: 1, +	             output_front: 1, +	             output_rear: 1, +	             swap_rear: 1; +	unsigned int update_pcm_vol; +	u32 period_size;		/* cached from runtime->period_size */ +	u32 buffer_size;		/* cached from runtime->buffer_size */ +	u32 period_pos; +	u32 last_pos; +	u32 capture_bank_number; +	u32 shift; +}; + +struct snd_ymfpci { +	int irq; + +	unsigned int device_id;	/* PCI device ID */ +	unsigned char rev;	/* PCI revision */ +	unsigned long reg_area_phys; +	void __iomem *reg_area_virt; +	struct resource *res_reg_area; +	struct resource *fm_res; +	struct resource *mpu_res; + +	unsigned short old_legacy_ctrl; +#ifdef SUPPORT_JOYSTICK +	struct gameport *gameport; +#endif + +	struct snd_dma_buffer work_ptr; + +	unsigned int bank_size_playback; +	unsigned int bank_size_capture; +	unsigned int bank_size_effect; +	unsigned int work_size; + +	void *bank_base_playback; +	void *bank_base_capture; +	void *bank_base_effect; +	void *work_base; +	dma_addr_t bank_base_playback_addr; +	dma_addr_t bank_base_capture_addr; +	dma_addr_t bank_base_effect_addr; +	dma_addr_t work_base_addr; +	struct snd_dma_buffer ac3_tmp_base; + +	u32 *ctrl_playback; +	struct snd_ymfpci_playback_bank *bank_playback[YDSXG_PLAYBACK_VOICES][2]; +	struct snd_ymfpci_capture_bank *bank_capture[YDSXG_CAPTURE_VOICES][2]; +	struct snd_ymfpci_effect_bank *bank_effect[YDSXG_EFFECT_VOICES][2]; + +	int start_count; + +	u32 active_bank; +	struct snd_ymfpci_voice voices[64]; +	int src441_used; + +	struct snd_ac97_bus *ac97_bus; +	struct snd_ac97 *ac97; +	struct snd_rawmidi *rawmidi; +	struct snd_timer *timer; +	unsigned int timer_ticks; + +	struct pci_dev *pci; +	struct snd_card *card; +	struct snd_pcm *pcm; +	struct snd_pcm *pcm2; +	struct snd_pcm *pcm_spdif; +	struct snd_pcm *pcm_4ch; +	struct snd_pcm_substream *capture_substream[YDSXG_CAPTURE_VOICES]; +	struct snd_pcm_substream *effect_substream[YDSXG_EFFECT_VOICES]; +	struct snd_kcontrol *ctl_vol_recsrc; +	struct snd_kcontrol *ctl_vol_adcrec; +	struct snd_kcontrol *ctl_vol_spdifrec; +	unsigned short spdif_bits, spdif_pcm_bits; +	struct snd_kcontrol *spdif_pcm_ctl; +	int mode_dup4ch; +	int rear_opened; +	int spdif_opened; +	struct snd_ymfpci_pcm_mixer { +		u16 left; +		u16 right; +		struct snd_kcontrol *ctl; +	} pcm_mixer[32]; + +	spinlock_t reg_lock; +	spinlock_t voice_lock; +	wait_queue_head_t interrupt_sleep; +	atomic_t interrupt_sleep_count; +	struct snd_info_entry *proc_entry; +	const struct firmware *dsp_microcode; +	const struct firmware *controller_microcode; + +#ifdef CONFIG_PM_SLEEP +	u32 *saved_regs; +	u32 saved_ydsxgr_mode; +	u16 saved_dsxg_legacy; +	u16 saved_dsxg_elegacy; +#endif +}; + +int snd_ymfpci_create(struct snd_card *card, +		      struct pci_dev *pci, +		      unsigned short old_legacy_ctrl, +		      struct snd_ymfpci ** rcodec); +void snd_ymfpci_free_gameport(struct snd_ymfpci *chip); + +extern const struct dev_pm_ops snd_ymfpci_pm; + +int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); +int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); +int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); +int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm); +int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch); +int snd_ymfpci_timer(struct snd_ymfpci *chip, int device); + +#endif /* __SOUND_YMFPCI_H */ diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 5518371db13..81c916a5eb9 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -25,14 +25,14 @@  #include <linux/pci.h>  #include <linux/sched.h>  #include <linux/slab.h> -#include <linux/vmalloc.h>  #include <linux/mutex.h> +#include <linux/module.h>  #include <sound/core.h>  #include <sound/control.h>  #include <sound/info.h>  #include <sound/tlv.h> -#include <sound/ymfpci.h> +#include "ymfpci.h"  #include <sound/asoundef.h>  #include <sound/mpu401.h> @@ -86,7 +86,9 @@ static int snd_ymfpci_codec_ready(struct snd_ymfpci *chip, int secondary)  			return 0;  		schedule_timeout_uninterruptible(1);  	} while (time_before(jiffies, end_time)); -	snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); +	dev_err(chip->card->dev, +		"codec_ready: codec %i is not ready [0x%x]\n", +		secondary, snd_ymfpci_readw(chip, reg));  	return -EBUSY;  } @@ -319,7 +321,7 @@ static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_  		ypcm->last_pos = pos;  		if (ypcm->period_pos >= ypcm->period_size) {  			/* -			printk(KERN_DEBUG +			dev_dbg(chip->card->dev,  			       "done - active_bank = 0x%x, start = 0x%x\n",  			       chip->active_bank,  			       voice->bank[chip->active_bank].start); @@ -372,7 +374,7 @@ static void snd_ymfpci_pcm_capture_interrupt(struct snd_pcm_substream *substream  		if (ypcm->period_pos >= ypcm->period_size) {  			ypcm->period_pos %= ypcm->period_size;  			/* -			printk(KERN_DEBUG +			dev_dbg(chip->card->dev,  			       "done - active_bank = 0x%x, start = 0x%x\n",  			       chip->active_bank,  			       voice->bank[chip->active_bank].start); @@ -597,7 +599,7 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int  	}  } -static int __devinit snd_ymfpci_ac3_init(struct snd_ymfpci *chip) +static int snd_ymfpci_ac3_init(struct snd_ymfpci *chip)  {  	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),  				4096, &chip->ac3_tmp_base) < 0) @@ -897,6 +899,18 @@ static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream)  	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);  	struct snd_pcm_runtime *runtime = substream->runtime;  	struct snd_ymfpci_pcm *ypcm; +	int err; + +	runtime->hw = snd_ymfpci_playback; +	/* FIXME? True value is 256/48 = 5.33333 ms */ +	err = snd_pcm_hw_constraint_minmax(runtime, +					   SNDRV_PCM_HW_PARAM_PERIOD_TIME, +					   5334, UINT_MAX); +	if (err < 0) +		return err; +	err = snd_pcm_hw_rule_noresample(runtime, 48000); +	if (err < 0) +		return err;  	ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);  	if (ypcm == NULL) @@ -904,11 +918,8 @@ static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream)  	ypcm->chip = chip;  	ypcm->type = PLAYBACK_VOICE;  	ypcm->substream = substream; -	runtime->hw = snd_ymfpci_playback;  	runtime->private_data = ypcm;  	runtime->private_free = snd_ymfpci_pcm_free_substream; -	/* FIXME? True value is 256/48 = 5.33333 ms */ -	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX);  	return 0;  } @@ -1013,6 +1024,18 @@ static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream,  	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);  	struct snd_pcm_runtime *runtime = substream->runtime;  	struct snd_ymfpci_pcm *ypcm; +	int err; + +	runtime->hw = snd_ymfpci_capture; +	/* FIXME? True value is 256/48 = 5.33333 ms */ +	err = snd_pcm_hw_constraint_minmax(runtime, +					   SNDRV_PCM_HW_PARAM_PERIOD_TIME, +					   5334, UINT_MAX); +	if (err < 0) +		return err; +	err = snd_pcm_hw_rule_noresample(runtime, 48000); +	if (err < 0) +		return err;  	ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);  	if (ypcm == NULL) @@ -1022,9 +1045,6 @@ static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream,  	ypcm->substream = substream;	  	ypcm->capture_bank_number = capture_bank_number;  	chip->capture_substream[capture_bank_number] = substream; -	runtime->hw = snd_ymfpci_capture; -	/* FIXME? True value is 256/48 = 5.33333 ms */ -	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX);  	runtime->private_data = ypcm;  	runtime->private_free = snd_ymfpci_pcm_free_substream;  	snd_ymfpci_hw_start(chip); @@ -1125,7 +1145,7 @@ static struct snd_pcm_ops snd_ymfpci_capture_rec_ops = {  	.pointer =		snd_ymfpci_capture_pointer,  }; -int __devinit snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm) +int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm)  {  	struct snd_pcm *pcm;  	int err; @@ -1147,6 +1167,11 @@ int __devinit snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm  	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,  					      snd_dma_pci_data(chip->pci), 64*1024, 256*1024); +	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, +				     snd_pcm_std_chmaps, 2, 0, NULL); +	if (err < 0) +		return err; +  	if (rpcm)  		*rpcm = pcm;  	return 0; @@ -1163,7 +1188,7 @@ static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = {  	.pointer =		snd_ymfpci_capture_pointer,  }; -int __devinit snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm) +int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm)  {  	struct snd_pcm *pcm;  	int err; @@ -1201,7 +1226,8 @@ static struct snd_pcm_ops snd_ymfpci_playback_spdif_ops = {  	.pointer =		snd_ymfpci_playback_pointer,  }; -int __devinit snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm) +int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, +			 struct snd_pcm **rpcm)  {  	struct snd_pcm *pcm;  	int err; @@ -1238,7 +1264,16 @@ static struct snd_pcm_ops snd_ymfpci_playback_4ch_ops = {  	.pointer =		snd_ymfpci_playback_pointer,  }; -int __devinit snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm) +static const struct snd_pcm_chmap_elem surround_map[] = { +	{ .channels = 1, +	  .map = { SNDRV_CHMAP_MONO } }, +	{ .channels = 2, +	  .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } }, +	{ } +}; + +int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, +		       struct snd_pcm **rpcm)  {  	struct snd_pcm *pcm;  	int err; @@ -1259,6 +1294,11 @@ int __devinit snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd  	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,  					      snd_dma_pci_data(chip->pci), 64*1024, 256*1024); +	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, +				     surround_map, 2, 0, NULL); +	if (err < 0) +		return err; +  	if (rpcm)  		*rpcm = pcm;  	return 0; @@ -1302,7 +1342,7 @@ static int snd_ymfpci_spdif_default_put(struct snd_kcontrol *kcontrol,  	return change;  } -static struct snd_kcontrol_new snd_ymfpci_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_ymfpci_spdif_default =  {  	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,  	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -1330,7 +1370,7 @@ static int snd_ymfpci_spdif_mask_get(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_ymfpci_spdif_mask __devinitdata = +static struct snd_kcontrol_new snd_ymfpci_spdif_mask =  {  	.access =	SNDRV_CTL_ELEM_ACCESS_READ,  	.iface =	SNDRV_CTL_ELEM_IFACE_PCM, @@ -1377,7 +1417,7 @@ static int snd_ymfpci_spdif_stream_put(struct snd_kcontrol *kcontrol,  	return change;  } -static struct snd_kcontrol_new snd_ymfpci_spdif_stream __devinitdata = +static struct snd_kcontrol_new snd_ymfpci_spdif_stream =  {  	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,  	.iface =	SNDRV_CTL_ELEM_IFACE_PCM, @@ -1389,15 +1429,9 @@ static struct snd_kcontrol_new snd_ymfpci_spdif_stream __devinitdata =  static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info)  { -	static char *texts[3] = {"AC'97", "IEC958", "ZV Port"}; +	static const char *const texts[3] = {"AC'97", "IEC958", "ZV Port"}; -	info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; -	info->count = 1; -	info->value.enumerated.items = 3; -	if (info->value.enumerated.item > 2) -		info->value.enumerated.item = 2; -	strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]); -	return 0; +	return snd_ctl_enum_info(info, 1, 3, texts);  }  static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) @@ -1431,7 +1465,7 @@ static int snd_ymfpci_drec_source_put(struct snd_kcontrol *kcontrol, struct snd_  	return reg != old_reg;  } -static struct snd_kcontrol_new snd_ymfpci_drec_source __devinitdata = { +static struct snd_kcontrol_new snd_ymfpci_drec_source = {  	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,  	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,  	.name =		"Direct Recording Source", @@ -1601,8 +1635,16 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e  	return change;  } +static struct snd_kcontrol_new snd_ymfpci_dup4ch = { +	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, +	.name = "4ch Duplication", +	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, +	.info = snd_ymfpci_info_dup4ch, +	.get = snd_ymfpci_get_dup4ch, +	.put = snd_ymfpci_put_dup4ch, +}; -static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ymfpci_controls[] = {  {  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.name = "Wave Playback Volume", @@ -1621,7 +1663,7 @@ YMFPCI_DOUBLE("ADC Playback Volume", 0, YDSXGR_PRIADCOUTVOL),  YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL),  YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL),  YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL), -YMFPCI_DOUBLE("FM Legacy Volume", 0, YDSXGR_LEGACYOUTVOL), +YMFPCI_DOUBLE("FM Legacy Playback Volume", 0, YDSXGR_LEGACYOUTVOL),  YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL),  YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL),  YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL), @@ -1629,13 +1671,6 @@ YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL),  YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0),  YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0),  YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4), -{ -	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, -	.name = "4ch Duplication", -	.info = snd_ymfpci_info_dup4ch, -	.get = snd_ymfpci_get_dup4ch, -	.put = snd_ymfpci_put_dup4ch, -},  }; @@ -1703,7 +1738,7 @@ static int snd_ymfpci_gpio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_  	return 0;  } -static struct snd_kcontrol_new snd_ymfpci_rear_shared __devinitdata = { +static struct snd_kcontrol_new snd_ymfpci_rear_shared = {  	.name = "Shared Rear/Line-In Switch",  	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  	.info = snd_ymfpci_gpio_sw_info, @@ -1767,7 +1802,7 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,  	return 0;  } -static struct snd_kcontrol_new snd_ymfpci_pcm_volume __devinitdata = { +static struct snd_kcontrol_new snd_ymfpci_pcm_volume = {  	.iface = SNDRV_CTL_ELEM_IFACE_PCM,  	.name = "PCM Playback Volume",  	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | @@ -1794,7 +1829,7 @@ static void snd_ymfpci_mixer_free_ac97(struct snd_ac97 *ac97)  	chip->ac97 = NULL;  } -int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) +int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)  {  	struct snd_ac97_template ac97;  	struct snd_kcontrol *kctl; @@ -1825,6 +1860,12 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)  		if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0)  			return err;  	} +	if (chip->ac97->ext_id & AC97_EI_SDAC) { +		kctl = snd_ctl_new1(&snd_ymfpci_dup4ch, chip); +		err = snd_ctl_add(chip->card, kctl); +		if (err < 0) +			return err; +	}  	/* add S/PDIF control */  	if (snd_BUG_ON(!chip->pcm_spdif)) @@ -1932,7 +1973,7 @@ static struct snd_timer_hardware snd_ymfpci_timer_hw = {  	.precise_resolution = snd_ymfpci_timer_precise_resolution,  }; -int __devinit snd_ymfpci_timer(struct snd_ymfpci *chip, int device) +int snd_ymfpci_timer(struct snd_ymfpci *chip, int device)  {  	struct snd_timer *timer = NULL;  	struct snd_timer_id tid; @@ -1968,7 +2009,7 @@ static void snd_ymfpci_proc_read(struct snd_info_entry *entry,  		snd_iprintf(buffer, "%04x: %04x\n", i, snd_ymfpci_readl(chip, i));  } -static int __devinit snd_ymfpci_proc_init(struct snd_card *card, struct snd_ymfpci *chip) +static int snd_ymfpci_proc_init(struct snd_card *card, struct snd_ymfpci *chip)  {  	struct snd_info_entry *entry; @@ -2028,7 +2069,8 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)  			       &chip->pci->dev);  	if (err >= 0) {  		if (chip->dsp_microcode->size != YDSXG_DSPLENGTH) { -			snd_printk(KERN_ERR "DSP microcode has wrong size\n"); +			dev_err(chip->card->dev, +				"DSP microcode has wrong size\n");  			err = -EINVAL;  		}  	} @@ -2043,8 +2085,8 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)  			       &chip->pci->dev);  	if (err >= 0) {  		if (chip->controller_microcode->size != YDSXG_CTRLLENGTH) { -			snd_printk(KERN_ERR "controller microcode" -				   " has wrong size\n"); +			dev_err(chip->card->dev, +				"controller microcode has wrong size\n");  			err = -EINVAL;  		}  	} @@ -2090,7 +2132,7 @@ static void snd_ymfpci_download_image(struct snd_ymfpci *chip)  	snd_ymfpci_enable_dsp(chip);  } -static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip) +static int snd_ymfpci_memalloc(struct snd_ymfpci *chip)  {  	long size, playback_ctrl_size;  	int voice, bank, reg; @@ -2219,11 +2261,11 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)  	/* FIXME: temporarily disabled, otherwise we cannot fire up  	 * the chip again unless reboot.  ACPI bug?  	 */ -	pci_set_power_state(chip->pci, 3); +	pci_set_power_state(chip->pci, PCI_D3hot);  #endif -#ifdef CONFIG_PM -	vfree(chip->saved_regs); +#ifdef CONFIG_PM_SLEEP +	kfree(chip->saved_regs);  #endif  	if (chip->irq >= 0)  		free_irq(chip->irq, chip); @@ -2252,7 +2294,7 @@ static int snd_ymfpci_dev_free(struct snd_device *device)  	return snd_ymfpci_free(chip);  } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int saved_regs_index[] = {  	/* spdif */  	YDSXGR_SPDIFOUTCTRL, @@ -2282,9 +2324,10 @@ static int saved_regs_index[] = {  };  #define YDSXGR_NUM_SAVED_REGS	ARRAY_SIZE(saved_regs_index) -int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state) +static int snd_ymfpci_suspend(struct device *dev)  { -	struct snd_card *card = pci_get_drvdata(pci); +	struct pci_dev *pci = to_pci_dev(dev); +	struct snd_card *card = dev_get_drvdata(dev);  	struct snd_ymfpci *chip = card->private_data;  	unsigned int i; @@ -2297,26 +2340,30 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)  	for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)  		chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);  	chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); +	pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, +			     &chip->saved_dsxg_legacy); +	pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY, +			     &chip->saved_dsxg_elegacy);  	snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);  	snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);  	snd_ymfpci_disable_dsp(chip);  	pci_disable_device(pci);  	pci_save_state(pci); -	pci_set_power_state(pci, pci_choose_state(pci, state)); +	pci_set_power_state(pci, PCI_D3hot);  	return 0;  } -int snd_ymfpci_resume(struct pci_dev *pci) +static int snd_ymfpci_resume(struct device *dev)  { -	struct snd_card *card = pci_get_drvdata(pci); +	struct pci_dev *pci = to_pci_dev(dev); +	struct snd_card *card = dev_get_drvdata(dev);  	struct snd_ymfpci *chip = card->private_data;  	unsigned int i;  	pci_set_power_state(pci, PCI_D0);  	pci_restore_state(pci);  	if (pci_enable_device(pci) < 0) { -		printk(KERN_ERR "ymfpci: pci_enable_device failed, " -		       "disabling device\n"); +		dev_err(dev, "pci_enable_device failed, disabling device\n");  		snd_card_disconnect(card);  		return -EIO;  	} @@ -2331,6 +2378,11 @@ int snd_ymfpci_resume(struct pci_dev *pci)  	snd_ac97_resume(chip->ac97); +	pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, +			      chip->saved_dsxg_legacy); +	pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, +			      chip->saved_dsxg_elegacy); +  	/* start hw again */  	if (chip->start_count > 0) {  		spin_lock_irq(&chip->reg_lock); @@ -2341,12 +2393,14 @@ int snd_ymfpci_resume(struct pci_dev *pci)  	snd_power_change_state(card, SNDRV_CTL_POWER_D0);  	return 0;  } -#endif /* CONFIG_PM */ -int __devinit snd_ymfpci_create(struct snd_card *card, -				struct pci_dev * pci, -				unsigned short old_legacy_ctrl, -				struct snd_ymfpci ** rchip) +SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume); +#endif /* CONFIG_PM_SLEEP */ + +int snd_ymfpci_create(struct snd_card *card, +		      struct pci_dev *pci, +		      unsigned short old_legacy_ctrl, +		      struct snd_ymfpci **rchip)  {  	struct snd_ymfpci *chip;  	int err; @@ -2381,13 +2435,15 @@ int __devinit snd_ymfpci_create(struct snd_card *card,  	chip->src441_used = -1;  	if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) { -		snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1); +		dev_err(chip->card->dev, +			"unable to grab memory region 0x%lx-0x%lx\n", +			chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);  		snd_ymfpci_free(chip);  		return -EBUSY;  	}  	if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED, -			"YMFPCI", chip)) { -		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); +			KBUILD_MODNAME, chip)) { +		dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);  		snd_ymfpci_free(chip);  		return -EBUSY;  	} @@ -2401,7 +2457,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,  	err = snd_ymfpci_request_firmware(chip);  	if (err < 0) { -		snd_printk(KERN_ERR "firmware request failed: %d\n", err); +		dev_err(chip->card->dev, "firmware request failed: %d\n", err);  		snd_ymfpci_free(chip);  		return err;  	} @@ -2419,8 +2475,9 @@ int __devinit snd_ymfpci_create(struct snd_card *card,  		return err;  	} -#ifdef CONFIG_PM -	chip->saved_regs = vmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32)); +#ifdef CONFIG_PM_SLEEP +	chip->saved_regs = kmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32), +				   GFP_KERNEL);  	if (chip->saved_regs == NULL) {  		snd_ymfpci_free(chip);  		return -ENOMEM; @@ -2434,8 +2491,6 @@ int __devinit snd_ymfpci_create(struct snd_card *card,  	snd_ymfpci_proc_init(card, chip); -	snd_card_set_dev(card, &pci->dev); -  	*rchip = chip;  	return 0;  }  | 
