diff options
Diffstat (limited to 'sound/soc')
30 files changed, 285 insertions, 273 deletions
| diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index 44b8dcecf571..d6f7694fcad4 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c @@ -179,13 +179,12 @@ static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97)  }  /* AC97 controller operations */ -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops ac97c_bus_ops = {  	.read		= au1xac97c_ac97_read,  	.write		= au1xac97c_ac97_write,  	.reset		= au1xac97c_ac97_cold_reset,  	.warm_reset	= au1xac97c_ac97_warm_reset,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);	/* globals be gone! */  static int alchemy_ac97c_startup(struct snd_pcm_substream *substream,  				 struct snd_soc_dai *dai) @@ -272,6 +271,10 @@ static int au1xac97c_drvprobe(struct platform_device *pdev)  	platform_set_drvdata(pdev, ctx); +	ret = snd_soc_set_ac97_ops(&ac97c_bus_ops); +	if (ret) +		return ret; +  	ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component,  					 &au1xac97c_dai_driver, 1);  	if (ret) @@ -338,19 +341,7 @@ static struct platform_driver au1xac97c_driver = {  	.remove		= au1xac97c_drvremove,  }; -static int __init au1xac97c_load(void) -{ -	ac97c_workdata = NULL; -	return platform_driver_register(&au1xac97c_driver); -} - -static void __exit au1xac97c_unload(void) -{ -	platform_driver_unregister(&au1xac97c_driver); -} - -module_init(au1xac97c_load); -module_exit(au1xac97c_unload); +module_platform_driver(&au1xac97c_driver);  MODULE_LICENSE("GPL");  MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver"); diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 8f1862aa7333..a822ab822bb7 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -201,13 +201,12 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)  }  /* AC97 controller operations */ -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops psc_ac97_ops = {  	.read		= au1xpsc_ac97_read,  	.write		= au1xpsc_ac97_write,  	.reset		= au1xpsc_ac97_cold_reset,  	.warm_reset	= au1xpsc_ac97_warm_reset,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,  				  struct snd_pcm_hw_params *params, @@ -383,15 +382,9 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)  	if (!iores)  		return -ENODEV; -	if (!devm_request_mem_region(&pdev->dev, iores->start, -				     resource_size(iores), -				     pdev->name)) -		return -EBUSY; - -	wd->mmio = devm_ioremap(&pdev->dev, iores->start, -				resource_size(iores)); -	if (!wd->mmio) -		return -EBUSY; +	wd->mmio = devm_ioremap_resource(&pdev->dev, iores); +	if (IS_ERR(wd->mmio)) +		return PTR_ERR(wd->mmio);  	dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);  	if (!dmares) @@ -423,6 +416,10 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)  	platform_set_drvdata(pdev, wd); +	ret = snd_soc_set_ac97_ops(&psc_ac97_ops); +	if (ret) +		return ret; +  	ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component,  					 &wd->dai_drv, 1);  	if (ret) @@ -503,19 +500,7 @@ static struct platform_driver au1xpsc_ac97_driver = {  	.remove		= au1xpsc_ac97_drvremove,  }; -static int __init au1xpsc_ac97_load(void) -{ -	au1xpsc_ac97_workdata = NULL; -	return platform_driver_register(&au1xpsc_ac97_driver); -} - -static void __exit au1xpsc_ac97_unload(void) -{ -	platform_driver_unregister(&au1xpsc_ac97_driver); -} - -module_init(au1xpsc_ac97_load); -module_exit(au1xpsc_ac97_unload); +module_platform_driver(au1xpsc_ac97_driver);  MODULE_LICENSE("GPL");  MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index 490217325975..c5af677ba49c 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c @@ -198,13 +198,12 @@ static void bf5xx_ac97_cold_reset(struct snd_ac97 *ac97)  #endif  } -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops bf5xx_ac97_ops = {  	.read	= bf5xx_ac97_read,  	.write	= bf5xx_ac97_write,  	.warm_reset	= bf5xx_ac97_warm_reset,  	.reset	= bf5xx_ac97_cold_reset,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  #ifdef CONFIG_PM  static int bf5xx_ac97_suspend(struct snd_soc_dai *dai) @@ -293,13 +292,14 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)  #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET  	/* Request PB3 as reset pin */ -	if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) { -		pr_err("Failed to request GPIO_%d for reset\n", -				CONFIG_SND_BF5XX_RESET_GPIO_NUM); -		ret =  -1; +	ret = devm_gpio_request_one(&pdev->dev, +				    CONFIG_SND_BF5XX_RESET_GPIO_NUM, +				    GPIOF_OUT_INIT_HIGH, "SND_AD198x RESET") { +		dev_err(&pdev->dev, +			"Failed to request GPIO_%d for reset: %d\n", +			CONFIG_SND_BF5XX_RESET_GPIO_NUM, ret);  		goto gpio_err;  	} -	gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);  #endif  	sport_handle = sport_init(pdev, 2, sizeof(struct ac97_frame), @@ -335,6 +335,12 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)  		goto sport_config_err;  	} +	ret = snd_soc_set_ac97_ops(&bf5xx_ac97_ops); +	if (ret != 0) { +		dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret); +		goto sport_config_err; +	} +  	ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component,  					 &bfin_ac97_dai, 1);  	if (ret) { @@ -349,10 +355,7 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev)  sport_config_err:  	sport_done(sport_handle);  sport_err: -#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET -	gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); -gpio_err: -#endif +	snd_soc_set_ac97_ops(NULL);  	return ret;  } @@ -363,9 +366,7 @@ static int asoc_bfin_ac97_remove(struct platform_device *pdev)  	snd_soc_unregister_component(&pdev->dev);  	sport_done(sport_handle); -#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET -	gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); -#endif +	snd_soc_set_ac97_ops(NULL);  	return 0;  } diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index 7798fbd5e81d..4bc9490e2c84 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -237,13 +237,12 @@ static irqreturn_t ep93xx_ac97_interrupt(int irq, void *dev_id)  	return IRQ_HANDLED;  } -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops ep93xx_ac97_ops = {  	.read		= ep93xx_ac97_read,  	.write		= ep93xx_ac97_write,  	.reset		= ep93xx_ac97_cold_reset,  	.warm_reset	= ep93xx_ac97_warm_reset,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream,  			       int cmd, struct snd_soc_dai *dai) @@ -395,6 +394,10 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)  	ep93xx_ac97_info = info;  	platform_set_drvdata(pdev, info); +	ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops); +	if (ret) +		goto fail; +  	ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component,  					 &ep93xx_ac97_dai, 1);  	if (ret) @@ -405,7 +408,7 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)  fail:  	platform_set_drvdata(pdev, NULL);  	ep93xx_ac97_info = NULL; -	dev_set_drvdata(&pdev->dev, NULL); +	snd_soc_set_ac97_ops(NULL);  	return ret;  } @@ -420,7 +423,8 @@ static int ep93xx_ac97_remove(struct platform_device *pdev)  	platform_set_drvdata(pdev, NULL);  	ep93xx_ac97_info = NULL; -	dev_set_drvdata(&pdev->dev, NULL); + +	snd_soc_set_ac97_ops(NULL);  	return 0;  } diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index ef2ae32ffc66..ec7351803c24 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -62,13 +62,13 @@ static struct snd_soc_dai_driver ac97_dai = {  static unsigned int ac97_read(struct snd_soc_codec *codec,  	unsigned int reg)  { -	return soc_ac97_ops.read(codec->ac97, reg); +	return soc_ac97_ops->read(codec->ac97, reg);  }  static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,  	unsigned int val)  { -	soc_ac97_ops.write(codec->ac97, reg, val); +	soc_ac97_ops->write(codec->ac97, reg, val);  	return 0;  } @@ -79,7 +79,8 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)  	int ret;  	/* add codec as bus device for standard ac97 */ -	ret = snd_ac97_bus(codec->card->snd_card, 0, &soc_ac97_ops, NULL, &ac97_bus); +	ret = snd_ac97_bus(codec->card->snd_card, 0, soc_ac97_ops, NULL, +			   &ac97_bus);  	if (ret < 0)  		return ret; diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index f385342947d3..89fcf7d6e7b8 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -108,7 +108,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,  	case AC97_EXTENDED_STATUS:  	case AC97_VENDOR_ID1:  	case AC97_VENDOR_ID2: -		return soc_ac97_ops.read(codec->ac97, reg); +		return soc_ac97_ops->read(codec->ac97, reg);  	default:  		reg = reg >> 1; @@ -124,7 +124,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,  {  	u16 *cache = codec->reg_cache; -	soc_ac97_ops.write(codec->ac97, reg, val); +	soc_ac97_ops->write(codec->ac97, reg, val);  	reg = reg >> 1;  	if (reg < ARRAY_SIZE(ad1980_reg))  		cache[reg] = val; @@ -154,13 +154,13 @@ static int ad1980_reset(struct snd_soc_codec *codec, int try_warm)  	u16 retry_cnt = 0;  retry: -	if (try_warm && soc_ac97_ops.warm_reset) { -		soc_ac97_ops.warm_reset(codec->ac97); +	if (try_warm && soc_ac97_ops->warm_reset) { +		soc_ac97_ops->warm_reset(codec->ac97);  		if (ac97_read(codec, AC97_RESET) == 0x0090)  			return 1;  	} -	soc_ac97_ops.reset(codec->ac97); +	soc_ac97_ops->reset(codec->ac97);  	/* Set bit 16slot in register 74h, then every slot will has only 16  	 * bits. This command is sent out in 20bit mode, in which case the  	 * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/ @@ -186,7 +186,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)  	printk(KERN_INFO "AD1980 SoC Audio Codec\n"); -	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); +	ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);  	if (ret < 0) {  		printk(KERN_ERR "ad1980: failed to register AC97 codec\n");  		return ret; diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 0f6f481cec09..987f728718c5 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -86,7 +86,7 @@ static const struct reg_default cs42l52_reg_defaults[] = {  	{ CS42L52_BEEP_VOL, 0x00 },	/* r1D Beep Volume off Time */  	{ CS42L52_BEEP_TONE_CTL, 0x00 },	/* r1E Beep Tone Cfg. */  	{ CS42L52_TONE_CTL, 0x00 },	/* r1F Tone Ctl */ -	{ CS42L52_MASTERA_VOL, 0x88 },	/* r20 Master A Volume */ +	{ CS42L52_MASTERA_VOL, 0x00 },	/* r20 Master A Volume */  	{ CS42L52_MASTERB_VOL, 0x00 },	/* r21 Master B Volume */  	{ CS42L52_HPA_VOL, 0x00 },	/* r22 Headphone A Volume */  	{ CS42L52_HPB_VOL, 0x00 },	/* r23 Headphone B Volume */ @@ -193,6 +193,8 @@ static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0);  static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0); +static DECLARE_TLV_DB_SCALE(mix_tlv, -50, 50, 0); +  static const unsigned int limiter_tlv[] = {  	TLV_DB_RANGE_HEAD(2),  	0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0), @@ -225,7 +227,7 @@ static const char * const mic_bias_level_text[] = {  };  static const struct soc_enum mic_bias_level_enum = -	SOC_ENUM_SINGLE(CS42L52_IFACE_CTL1, 0, +	SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0,  			ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text);  static const char * const cs42l52_mic_text[] = { "Single", "Differential" }; @@ -260,7 +262,7 @@ static const char * const hp_gain_num_text[] = {  };  static const struct soc_enum hp_gain_enum = -	SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 4, +	SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 5,  		ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text);  static const char * const beep_pitch_text[] = { @@ -413,7 +415,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {  	SOC_ENUM("Headphone Analog Gain", hp_gain_enum),  	SOC_DOUBLE_R_SX_TLV("Speaker Volume", CS42L52_SPKA_VOL, -			      CS42L52_SPKB_VOL, 7, 0x1, 0xff, hl_tlv), +			      CS42L52_SPKB_VOL, 0, 0x1, 0xff, hl_tlv),  	SOC_DOUBLE_R_SX_TLV("Bypass Volume", CS42L52_PASSTHRUA_VOL,  			      CS42L52_PASSTHRUB_VOL, 6, 0x18, 0x90, pga_tlv), @@ -441,7 +443,7 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = {  	SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume",  			    CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL, -				6, 0x7f, 0x19, hl_tlv), +				0, 0x7f, 0x19, mix_tlv),  	SOC_DOUBLE_R("PCM Mixer Switch",  		     CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL, 7, 1, 1), diff --git a/sound/soc/codecs/cs42l52.h b/sound/soc/codecs/cs42l52.h index 60985c059071..4277012c4719 100644 --- a/sound/soc/codecs/cs42l52.h +++ b/sound/soc/codecs/cs42l52.h @@ -157,7 +157,7 @@  #define CS42L52_PB_CTL1_INV_PCMA		(1 << 2)  #define CS42L52_PB_CTL1_MSTB_MUTE		(1 << 1)  #define CS42L52_PB_CTL1_MSTA_MUTE		(1 << 0) -#define CS42L52_PB_CTL1_MUTE_MASK		0xFFFD +#define CS42L52_PB_CTL1_MUTE_MASK		0x03  #define CS42L52_PB_CTL1_MUTE			3  #define CS42L52_PB_CTL1_UNMUTE			0 diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index ce0d36412c97..8d14a76c7249 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2233,7 +2233,7 @@ static int max98090_probe(struct snd_soc_codec *codec)  	dev_dbg(codec->dev, "irq = %d\n", max98090->irq);  	ret = request_threaded_irq(max98090->irq, NULL, -		max98090_interrupt, IRQF_TRIGGER_FALLING, +		max98090_interrupt, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,  		"max98090_interrupt", codec);  	if (ret < 0) {  		dev_err(codec->dev, "request_irq failed: %d\n", diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 2eda85ba79ac..a5455c1aea42 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -28,8 +28,6 @@  #include "stac9766.h" -#define STAC9766_VERSION "0.10" -  /*   * STAC9766 register cache   */ @@ -145,14 +143,14 @@ static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,  	if (reg > AC97_STAC_PAGE0) {  		stac9766_ac97_write(codec, AC97_INT_PAGING, 0); -		soc_ac97_ops.write(codec->ac97, reg, val); +		soc_ac97_ops->write(codec->ac97, reg, val);  		stac9766_ac97_write(codec, AC97_INT_PAGING, 1);  		return 0;  	}  	if (reg / 2 >= ARRAY_SIZE(stac9766_reg))  		return -EIO; -	soc_ac97_ops.write(codec->ac97, reg, val); +	soc_ac97_ops->write(codec->ac97, reg, val);  	cache[reg / 2] = val;  	return 0;  } @@ -164,7 +162,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,  	if (reg > AC97_STAC_PAGE0) {  		stac9766_ac97_write(codec, AC97_INT_PAGING, 0); -		val = soc_ac97_ops.read(codec->ac97, reg - AC97_STAC_PAGE0); +		val = soc_ac97_ops->read(codec->ac97, reg - AC97_STAC_PAGE0);  		stac9766_ac97_write(codec, AC97_INT_PAGING, 1);  		return val;  	} @@ -175,7 +173,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,  		reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 ||  		reg == AC97_VENDOR_ID2) { -		val = soc_ac97_ops.read(codec->ac97, reg); +		val = soc_ac97_ops->read(codec->ac97, reg);  		return val;  	}  	return cache[reg / 2]; @@ -242,15 +240,15 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,  static int stac9766_reset(struct snd_soc_codec *codec, int try_warm)  { -	if (try_warm && soc_ac97_ops.warm_reset) { -		soc_ac97_ops.warm_reset(codec->ac97); +	if (try_warm && soc_ac97_ops->warm_reset) { +		soc_ac97_ops->warm_reset(codec->ac97);  		if (stac9766_ac97_read(codec, 0) == stac9766_reg[0])  			return 1;  	} -	soc_ac97_ops.reset(codec->ac97); -	if (soc_ac97_ops.warm_reset) -		soc_ac97_ops.warm_reset(codec->ac97); +	soc_ac97_ops->reset(codec->ac97); +	if (soc_ac97_ops->warm_reset) +		soc_ac97_ops->warm_reset(codec->ac97);  	if (stac9766_ac97_read(codec, 0) != stac9766_reg[0])  		return -EIO;  	return 0; @@ -274,7 +272,7 @@ reset:  		return -EIO;  	}  	codec->ac97->bus->ops->warm_reset(codec->ac97); -	id = soc_ac97_ops.read(codec->ac97, AC97_VENDOR_ID2); +	id = soc_ac97_ops->read(codec->ac97, AC97_VENDOR_ID2);  	if (id != 0x4c13) {  		stac9766_reset(codec, 0);  		reset++; @@ -338,9 +336,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)  {  	int ret = 0; -	printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); - -	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); +	ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);  	if (ret < 0)  		goto codec_err; diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 65d09d60b7c6..1514bf845e4b 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -187,14 +187,14 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,  			break;  		} - -		if (found) -			snd_soc_dapm_sync(widget->dapm);  	} -	ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); -  	mutex_unlock(&widget->codec->mutex); + +	if (found) +		snd_soc_dapm_sync(widget->dapm); + +	ret = snd_soc_update_bits_locked(widget->codec, reg, val_mask, val);  	return ret;  } diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index e895d3939eef..100fdadda56a 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1120,7 +1120,8 @@ SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,  ARIZONA_DSP_WIDGETS(DSP1, "DSP1"),  SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, -		       ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux), +		       ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, +		       &wm5102_aec_loopback_mux),  SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,  		   ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 731884e04776..88ad7db52dde 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -190,7 +190,7 @@ ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),  ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),  ARIZONA_MIXER_CONTROLS("DSP3R", ARIZONA_DSP3RMIX_INPUT_1_SOURCE),  ARIZONA_MIXER_CONTROLS("DSP4L", ARIZONA_DSP4LMIX_INPUT_1_SOURCE), -ARIZONA_MIXER_CONTROLS("DSP5R", ARIZONA_DSP4RMIX_INPUT_1_SOURCE), +ARIZONA_MIXER_CONTROLS("DSP4R", ARIZONA_DSP4RMIX_INPUT_1_SOURCE),  ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),  ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), @@ -503,7 +503,8 @@ SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,  		 NULL, 0),  SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, -		       ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5110_aec_loopback_mux), +		       ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, +		       &wm5110_aec_loopback_mux),  SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,  		     ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0), @@ -976,6 +977,8 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)  	if (ret != 0)  		return ret; +	arizona_init_spk(codec); +  	snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");  	priv->core.arizona->dapm = &codec->dapm; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 1eb152cb1097..29e95f93d482 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -383,6 +383,8 @@ static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,  	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);  	int drc = wm8994_get_drc(kcontrol->id.name); +	if (drc < 0) +		return drc;  	ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];  	return 0; @@ -488,6 +490,9 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,  	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);  	int block = wm8994_get_retune_mobile_block(kcontrol->id.name); +	if (block < 0) +		return block; +  	ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];  	return 0; @@ -1031,7 +1036,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,  {  	struct snd_soc_codec *codec = w->codec;  	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); -	struct wm8994 *control = codec->control_data; +	struct wm8994 *control = wm8994->wm8994;  	int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;  	int i;  	int dac; @@ -3831,8 +3836,14 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)  				ret);  		} else if (!(ret & WM1811_JACKDET_LVL)) {  			dev_dbg(codec->dev, "Ignoring removed jack\n"); -			return IRQ_HANDLED; +			goto out;  		} +	} else if (!(reg & WM8958_MICD_STS)) { +		snd_soc_jack_report(wm8994->micdet[0].jack, 0, +				    SND_JACK_MECHANICAL | SND_JACK_HEADSET | +				    wm8994->btn_mask); +		wm8994->mic_detecting = true; +		goto out;  	}  	if (wm8994->mic_detecting) diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 05b1f346695b..70ce6793c5bd 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -209,7 +209,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg)  	case AC97_RESET:  	case AC97_VENDOR_ID1:  	case AC97_VENDOR_ID2: -		return soc_ac97_ops.read(codec->ac97, reg); +		return soc_ac97_ops->read(codec->ac97, reg);  	default:  		reg = reg >> 1; @@ -225,7 +225,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,  {  	u16 *cache = codec->reg_cache; -	soc_ac97_ops.write(codec->ac97, reg, val); +	soc_ac97_ops->write(codec->ac97, reg, val);  	reg = reg >> 1;  	if (reg < (ARRAY_SIZE(wm9705_reg)))  		cache[reg] = val; @@ -294,8 +294,8 @@ static struct snd_soc_dai_driver wm9705_dai[] = {  static int wm9705_reset(struct snd_soc_codec *codec)  { -	if (soc_ac97_ops.reset) { -		soc_ac97_ops.reset(codec->ac97); +	if (soc_ac97_ops->reset) { +		soc_ac97_ops->reset(codec->ac97);  		if (ac97_read(codec, 0) == wm9705_reg[0])  			return 0; /* Success */  	} @@ -306,7 +306,7 @@ static int wm9705_reset(struct snd_soc_codec *codec)  #ifdef CONFIG_PM  static int wm9705_soc_suspend(struct snd_soc_codec *codec)  { -	soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); +	soc_ac97_ops->write(codec->ac97, AC97_POWERDOWN, 0xffff);  	return 0;  } @@ -323,7 +323,7 @@ static int wm9705_soc_resume(struct snd_soc_codec *codec)  	}  	for (i = 2; i < ARRAY_SIZE(wm9705_reg) << 1; i += 2) { -		soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); +		soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);  	}  	return 0; @@ -337,9 +337,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)  {  	int ret = 0; -	printk(KERN_INFO "WM9705 SoC Audio Codec\n"); - -	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); +	ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);  	if (ret < 0) {  		printk(KERN_ERR "wm9705: failed to register AC97 codec\n");  		return ret; diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 8e9a6a3eeb1a..c5eb746087b4 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -455,7 +455,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,  	if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||  		reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||  		reg == AC97_REC_GAIN) -		return soc_ac97_ops.read(codec->ac97, reg); +		return soc_ac97_ops->read(codec->ac97, reg);  	else {  		reg = reg >> 1; @@ -472,7 +472,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,  	u16 *cache = codec->reg_cache;  	if (reg < 0x7c) -		soc_ac97_ops.write(codec->ac97, reg, val); +		soc_ac97_ops->write(codec->ac97, reg, val);  	reg = reg >> 1;  	if (reg < (ARRAY_SIZE(wm9712_reg)))  		cache[reg] = val; @@ -581,15 +581,15 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,  static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)  { -	if (try_warm && soc_ac97_ops.warm_reset) { -		soc_ac97_ops.warm_reset(codec->ac97); +	if (try_warm && soc_ac97_ops->warm_reset) { +		soc_ac97_ops->warm_reset(codec->ac97);  		if (ac97_read(codec, 0) == wm9712_reg[0])  			return 1;  	} -	soc_ac97_ops.reset(codec->ac97); -	if (soc_ac97_ops.warm_reset) -		soc_ac97_ops.warm_reset(codec->ac97); +	soc_ac97_ops->reset(codec->ac97); +	if (soc_ac97_ops->warm_reset) +		soc_ac97_ops->warm_reset(codec->ac97);  	if (ac97_read(codec, 0) != wm9712_reg[0])  		goto err;  	return 0; @@ -624,7 +624,7 @@ static int wm9712_soc_resume(struct snd_soc_codec *codec)  			if (i == AC97_INT_PAGING || i == AC97_POWERDOWN ||  			    (i > 0x58 && i != 0x5c))  				continue; -			soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); +			soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);  		}  	} @@ -635,7 +635,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)  {  	int ret = 0; -	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); +	ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);  	if (ret < 0) {  		printk(KERN_ERR "wm9712: failed to register AC97 codec\n");  		return ret; diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index f7afa68d8c7f..a53e175c015a 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -652,7 +652,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec,  	if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||  		reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||  		reg == AC97_CD) -		return soc_ac97_ops.read(codec->ac97, reg); +		return soc_ac97_ops->read(codec->ac97, reg);  	else {  		reg = reg >> 1; @@ -668,7 +668,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,  {  	u16 *cache = codec->reg_cache;  	if (reg < 0x7c) -		soc_ac97_ops.write(codec->ac97, reg, val); +		soc_ac97_ops->write(codec->ac97, reg, val);  	reg = reg >> 1;  	if (reg < (ARRAY_SIZE(wm9713_reg)))  		cache[reg] = val; @@ -1095,15 +1095,15 @@ static struct snd_soc_dai_driver wm9713_dai[] = {  int wm9713_reset(struct snd_soc_codec *codec, int try_warm)  { -	if (try_warm && soc_ac97_ops.warm_reset) { -		soc_ac97_ops.warm_reset(codec->ac97); +	if (try_warm && soc_ac97_ops->warm_reset) { +		soc_ac97_ops->warm_reset(codec->ac97);  		if (ac97_read(codec, 0) == wm9713_reg[0])  			return 1;  	} -	soc_ac97_ops.reset(codec->ac97); -	if (soc_ac97_ops.warm_reset) -		soc_ac97_ops.warm_reset(codec->ac97); +	soc_ac97_ops->reset(codec->ac97); +	if (soc_ac97_ops->warm_reset) +		soc_ac97_ops->warm_reset(codec->ac97);  	if (ac97_read(codec, 0) != wm9713_reg[0])  		return -EIO;  	return 0; @@ -1180,7 +1180,7 @@ static int wm9713_soc_resume(struct snd_soc_codec *codec)  			if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID ||  				i == AC97_EXTENDED_MSTATUS || i > 0x66)  				continue; -			soc_ac97_ops.write(codec->ac97, i, cache[i>>1]); +			soc_ac97_ops->write(codec->ac97, i, cache[i>>1]);  		}  	} @@ -1197,7 +1197,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)  		return -ENOMEM;  	snd_soc_codec_set_drvdata(codec, wm9713); -	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); +	ret = snd_soc_new_ac97_codec(codec, soc_ac97_ops, 0);  	if (ret < 0)  		goto codec_err; diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 56ecfc72f2e9..81490febac6d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -631,7 +631,8 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,  				       int word_length)  {  	u32 fmt; -	u32 rotate = (word_length / 4) & 0x7; +	u32 tx_rotate = (word_length / 4) & 0x7; +	u32 rx_rotate = (32 - word_length) / 4;  	u32 mask = (1ULL << word_length) - 1;  	/* @@ -655,9 +656,9 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev,  		mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,  				TXSSZ(fmt), TXSSZ(0x0F));  		mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, -				TXROT(rotate), TXROT(7)); +				TXROT(tx_rotate), TXROT(7));  		mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, -				RXROT(rotate), RXROT(7)); +				RXROT(rx_rotate), RXROT(7));  		mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG,  				mask);  	} diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index c6fa03e2114a..bd40849454a8 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -501,13 +501,12 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)  	imx_ssi_ac97_read(ac97, 0);  } -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops imx_ssi_ac97_ops = {  	.read		= imx_ssi_ac97_read,  	.write		= imx_ssi_ac97_write,  	.reset		= imx_ssi_ac97_reset,  	.warm_reset	= imx_ssi_ac97_warm_reset  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  static int imx_ssi_probe(struct platform_device *pdev)  { @@ -583,6 +582,12 @@ static int imx_ssi_probe(struct platform_device *pdev)  	platform_set_drvdata(pdev, ssi); +	ret = snd_soc_set_ac97_ops(&imx_ssi_ac97_ops); +	if (ret != 0) { +		dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret); +		goto failed_register; +	} +  	ret = snd_soc_register_component(&pdev->dev, &imx_component,  					 dai, 1);  	if (ret) { @@ -630,6 +635,7 @@ failed_register:  	release_mem_region(res->start, resource_size(res));  	clk_disable_unprepare(ssi->clk);  failed_clk: +	snd_soc_set_ac97_ops(NULL);  	return ret;  } @@ -649,6 +655,7 @@ static int imx_ssi_remove(struct platform_device *pdev)  	release_mem_region(res->start, resource_size(res));  	clk_disable_unprepare(ssi->clk); +	snd_soc_set_ac97_ops(NULL);  	return 0;  } diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 4141b35ef0bb..3ef7a0c92efa 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -131,13 +131,12 @@ static void psc_ac97_cold_reset(struct snd_ac97 *ac97)  	psc_ac97_warm_reset(ac97);  } -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops psc_ac97_ops = {  	.read		= psc_ac97_read,  	.write		= psc_ac97_write,  	.reset		= psc_ac97_cold_reset,  	.warm_reset	= psc_ac97_warm_reset,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,  				 struct snd_pcm_hw_params *params, @@ -290,6 +289,12 @@ static int psc_ac97_of_probe(struct platform_device *op)  	if (rc != 0)  		return rc; +	rc = snd_soc_set_ac97_ops(&psc_ac97_ops); +	if (rc != 0) { +		dev_err(&op->dev, "Failed to set AC'97 ops: %d\n", ret); +		return rc; +	} +  	rc = snd_soc_register_component(&op->dev, &psc_ac97_component,  					psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));  	if (rc != 0) { @@ -318,6 +323,7 @@ static int psc_ac97_of_remove(struct platform_device *op)  {  	mpc5200_audio_dma_destroy(op);  	snd_soc_unregister_component(&op->dev); +	snd_soc_set_ac97_ops(NULL);  	return 0;  } diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c index fe3285ceaf5b..f4c2417a8730 100644 --- a/sound/soc/nuc900/nuc900-ac97.c +++ b/sound/soc/nuc900/nuc900-ac97.c @@ -197,13 +197,12 @@ static void nuc900_ac97_cold_reset(struct snd_ac97 *ac97)  }  /* AC97 controller operations */ -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops nuc900_ac97_ops = {  	.read		= nuc900_ac97_read,  	.write		= nuc900_ac97_write,  	.reset		= nuc900_ac97_cold_reset,  	.warm_reset	= nuc900_ac97_warm_reset, -} -EXPORT_SYMBOL_GPL(soc_ac97_ops); +};  static int nuc900_ac97_trigger(struct snd_pcm_substream *substream,  				int cmd, struct snd_soc_dai *dai) @@ -326,64 +325,52 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev)  	if (nuc900_ac97_data)  		return -EBUSY; -	nuc900_audio = kzalloc(sizeof(struct nuc900_audio), GFP_KERNEL); +	nuc900_audio = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_audio), +				    GFP_KERNEL);  	if (!nuc900_audio)  		return -ENOMEM;  	spin_lock_init(&nuc900_audio->lock);  	nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!nuc900_audio->res) { -		ret = -ENODEV; -		goto out0; -	} - -	if (!request_mem_region(nuc900_audio->res->start, -			resource_size(nuc900_audio->res), pdev->name)) { -		ret = -EBUSY; -		goto out0; -	} +	if (!nuc900_audio->res) +		return ret; -	nuc900_audio->mmio = ioremap(nuc900_audio->res->start, -					resource_size(nuc900_audio->res)); -	if (!nuc900_audio->mmio) { -		ret = -ENOMEM; -		goto out1; -	} +	nuc900_audio->mmio = devm_ioremap_resource(&pdev->dev, +						   nuc900_audio->res); +	if (IS_ERR(nuc900_audio->mmio)) +		return PTR_ERR(nuc900_audio->mmio); -	nuc900_audio->clk = clk_get(&pdev->dev, NULL); +	nuc900_audio->clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(nuc900_audio->clk)) {  		ret = PTR_ERR(nuc900_audio->clk); -		goto out2; +		goto out;  	}  	nuc900_audio->irq_num = platform_get_irq(pdev, 0);  	if (!nuc900_audio->irq_num) {  		ret = -EBUSY; -		goto out3; +		goto out;  	}  	nuc900_ac97_data = nuc900_audio; +	ret = snd_soc_set_ac97_ops(&nuc900_ac97_ops); +	if (ret) +		goto out; +  	ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component,  					 &nuc900_ac97_dai, 1);  	if (ret) -		goto out3; +		goto out;  	/* enbale ac97 multifunction pin */  	mfp_set_groupg(nuc900_audio->dev, NULL);  	return 0; -out3: -	clk_put(nuc900_audio->clk); -out2: -	iounmap(nuc900_audio->mmio); -out1: -	release_mem_region(nuc900_audio->res->start, -					resource_size(nuc900_audio->res)); -out0: -	kfree(nuc900_audio); +out: +	snd_soc_set_ac97_ops(NULL);  	return ret;  } @@ -391,13 +378,8 @@ static int nuc900_ac97_drvremove(struct platform_device *pdev)  {  	snd_soc_unregister_component(&pdev->dev); -	clk_put(nuc900_ac97_data->clk); -	iounmap(nuc900_ac97_data->mmio); -	release_mem_region(nuc900_ac97_data->res->start, -				resource_size(nuc900_ac97_data->res)); - -	kfree(nuc900_ac97_data);  	nuc900_ac97_data = NULL; +	snd_soc_set_ac97_ops(NULL);  	return 0;  } diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 57ea8e6c5488..a3c22ba25f08 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -41,13 +41,12 @@ static void pxa2xx_ac97_cold_reset(struct snd_ac97 *ac97)  	pxa2xx_ac97_finish_reset(ac97);  } -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {  	.read	= pxa2xx_ac97_read,  	.write	= pxa2xx_ac97_write,  	.warm_reset	= pxa2xx_ac97_warm_reset,  	.reset	= pxa2xx_ac97_cold_reset,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {  	.name			= "AC97 PCM Stereo out", @@ -244,6 +243,10 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)  		return -ENXIO;  	} +	ret = snd_soc_set_ac97_ops(&pxa2xx_ac97_ops); +	if (ret != 0) +		return ret; +  	/* Punt most of the init to the SoC probe; we may need the machine  	 * driver to do interesting things with the clocking to get us up  	 * and running. @@ -255,6 +258,7 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev)  static int pxa2xx_ac97_dev_remove(struct platform_device *pdev)  {  	snd_soc_unregister_component(&pdev->dev); +	snd_soc_set_ac97_ops(NULL);  	return 0;  } diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index cb88ead98917..2dd623fa3882 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -214,13 +214,12 @@ static irqreturn_t s3c_ac97_irq(int irq, void *dev_id)  	return IRQ_HANDLED;  } -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops s3c_ac97_ops = {  	.read       = s3c_ac97_read,  	.write      = s3c_ac97_write,  	.warm_reset = s3c_ac97_warm_reset,  	.reset      = s3c_ac97_cold_reset,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,  				  struct snd_pcm_hw_params *params, @@ -417,11 +416,9 @@ static int s3c_ac97_probe(struct platform_device *pdev)  		return -ENXIO;  	} -	if (!request_mem_region(mem_res->start, -				resource_size(mem_res), "ac97")) { -		dev_err(&pdev->dev, "Unable to request register region\n"); -		return -EBUSY; -	} +	s3c_ac97.regs = devm_ioremap_resource(&pdev->dev, mem_res); +	if (IS_ERR(s3c_ac97.regs)) +		return PTR_ERR(s3c_ac97.regs);  	s3c_ac97_pcm_out.channel = dmatx_res->start;  	s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; @@ -433,14 +430,7 @@ static int s3c_ac97_probe(struct platform_device *pdev)  	init_completion(&s3c_ac97.done);  	mutex_init(&s3c_ac97.lock); -	s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res)); -	if (s3c_ac97.regs == NULL) { -		dev_err(&pdev->dev, "Unable to ioremap register region\n"); -		ret = -ENXIO; -		goto err1; -	} - -	s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); +	s3c_ac97.ac97_clk = devm_clk_get(&pdev->dev, "ac97");  	if (IS_ERR(s3c_ac97.ac97_clk)) {  		dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n");  		ret = -ENODEV; @@ -461,6 +451,12 @@ static int s3c_ac97_probe(struct platform_device *pdev)  		goto err4;  	} +	ret = snd_soc_set_ac97_ops(&s3c_ac97_ops); +	if (ret != 0) { +		dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret); +		goto err4; +	} +  	ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component,  					 s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));  	if (ret) @@ -480,18 +476,14 @@ err5:  err4:  err3:  	clk_disable_unprepare(s3c_ac97.ac97_clk); -	clk_put(s3c_ac97.ac97_clk);  err2: -	iounmap(s3c_ac97.regs); -err1: -	release_mem_region(mem_res->start, resource_size(mem_res)); - +	snd_soc_set_ac97_ops(NULL);  	return ret;  }  static int s3c_ac97_remove(struct platform_device *pdev)  { -	struct resource *mem_res, *irq_res; +	struct resource *irq_res;  	asoc_dma_platform_unregister(&pdev->dev);  	snd_soc_unregister_component(&pdev->dev); @@ -501,13 +493,7 @@ static int s3c_ac97_remove(struct platform_device *pdev)  		free_irq(irq_res->start, NULL);  	clk_disable_unprepare(s3c_ac97.ac97_clk); -	clk_put(s3c_ac97.ac97_clk); - -	iounmap(s3c_ac97.regs); - -	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (mem_res) -		release_mem_region(mem_res->start, resource_size(mem_res)); +	snd_soc_set_ac97_ops(NULL);  	return 0;  } diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index af19f77b7bf0..0af2e4dfd139 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -227,13 +227,12 @@ static void hac_ac97_coldrst(struct snd_ac97 *ac97)  	hac_ac97_warmrst(ac97);  } -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops hac_ac97_ops = {  	.read	= hac_ac97_read,  	.write	= hac_ac97_write,  	.reset	= hac_ac97_coldrst,  	.warm_reset = hac_ac97_warmrst,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  static int hac_hw_params(struct snd_pcm_substream *substream,  			 struct snd_pcm_hw_params *params, @@ -316,6 +315,10 @@ static const struct snd_soc_component_driver sh4_hac_component = {  static int hac_soc_platform_probe(struct platform_device *pdev)  { +	ret = snd_soc_set_ac97_ops(&hac_ac97_ops); +	if (ret != 0) +		return ret; +  	return snd_soc_register_component(&pdev->dev, &sh4_hac_component,  					  sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));  } @@ -323,6 +326,7 @@ static int hac_soc_platform_probe(struct platform_device *pdev)  static int hac_soc_platform_remove(struct platform_device *pdev)  {  	snd_soc_unregister_component(&pdev->dev); +	snd_soc_set_ac97_ops(NULL);  	return 0;  } diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 3853f7eb3f28..06a8000aa07b 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -220,8 +220,12 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,  			goto err;  	} -	snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, -				SND_SOC_DAPM_STREAM_START); +	if (cstream->direction == SND_COMPRESS_PLAYBACK) +		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, +					SND_SOC_DAPM_STREAM_START); +	else +		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE, +					SND_SOC_DAPM_STREAM_START);  	/* cancel any delayed stream shutdown that is pending */  	rtd->pop_wait = 0; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d56bbea6e75e..562d72e04e6e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2079,6 +2079,22 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,  }  EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); +struct snd_ac97_bus_ops *soc_ac97_ops; + +int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops) +{ +	if (ops == soc_ac97_ops) +		return 0; + +	if (soc_ac97_ops && ops) +		return -EBUSY; + +	soc_ac97_ops = ops; + +	return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops); +  /**   * snd_soc_free_ac97_codec - free AC97 codec device   * @codec: audio codec diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index a80c883bb8be..c7051c457b75 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -55,7 +55,8 @@ static int dapm_up_seq[] = {  	[snd_soc_dapm_clock_supply] = 1,  	[snd_soc_dapm_micbias] = 2,  	[snd_soc_dapm_dai_link] = 2, -	[snd_soc_dapm_dai] = 3, +	[snd_soc_dapm_dai_in] = 3, +	[snd_soc_dapm_dai_out] = 3,  	[snd_soc_dapm_aif_in] = 3,  	[snd_soc_dapm_aif_out] = 3,  	[snd_soc_dapm_mic] = 4, @@ -92,7 +93,8 @@ static int dapm_down_seq[] = {  	[snd_soc_dapm_value_mux] = 9,  	[snd_soc_dapm_aif_in] = 10,  	[snd_soc_dapm_aif_out] = 10, -	[snd_soc_dapm_dai] = 10, +	[snd_soc_dapm_dai_in] = 10, +	[snd_soc_dapm_dai_out] = 10,  	[snd_soc_dapm_dai_link] = 11,  	[snd_soc_dapm_clock_supply] = 12,  	[snd_soc_dapm_regulator_supply] = 12, @@ -419,7 +421,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,  	case snd_soc_dapm_clock_supply:  	case snd_soc_dapm_aif_in:  	case snd_soc_dapm_aif_out: -	case snd_soc_dapm_dai: +	case snd_soc_dapm_dai_in: +	case snd_soc_dapm_dai_out:  	case snd_soc_dapm_hp:  	case snd_soc_dapm_mic:  	case snd_soc_dapm_spk: @@ -820,7 +823,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,  	switch (widget->id) {  	case snd_soc_dapm_adc:  	case snd_soc_dapm_aif_out: -	case snd_soc_dapm_dai: +	case snd_soc_dapm_dai_out:  		if (widget->active) {  			widget->outputs = snd_soc_dapm_suspend_check(widget);  			return widget->outputs; @@ -916,7 +919,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,  	switch (widget->id) {  	case snd_soc_dapm_dac:  	case snd_soc_dapm_aif_in: -	case snd_soc_dapm_dai: +	case snd_soc_dapm_dai_in:  		if (widget->active) {  			widget->inputs = snd_soc_dapm_suspend_check(widget);  			return widget->inputs; @@ -1135,16 +1138,6 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)  	return out != 0 && in != 0;  } -static int dapm_dai_check_power(struct snd_soc_dapm_widget *w) -{ -	DAPM_UPDATE_STAT(w, power_checks); - -	if (w->active) -		return w->active; - -	return dapm_generic_check_power(w); -} -  /* Check to see if an ADC has power */  static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)  { @@ -2318,7 +2311,8 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,  	case snd_soc_dapm_clock_supply:  	case snd_soc_dapm_aif_in:  	case snd_soc_dapm_aif_out: -	case snd_soc_dapm_dai: +	case snd_soc_dapm_dai_in: +	case snd_soc_dapm_dai_out:  	case snd_soc_dapm_dai_link:  		list_add(&path->list, &dapm->card->paths);  		list_add(&path->list_sink, &wsink->sources); @@ -3129,10 +3123,12 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,  		break;  	case snd_soc_dapm_adc:  	case snd_soc_dapm_aif_out: +	case snd_soc_dapm_dai_out:  		w->power_check = dapm_adc_check_power;  		break;  	case snd_soc_dapm_dac:  	case snd_soc_dapm_aif_in: +	case snd_soc_dapm_dai_in:  		w->power_check = dapm_dac_check_power;  		break;  	case snd_soc_dapm_pga: @@ -3152,9 +3148,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,  	case snd_soc_dapm_clock_supply:  		w->power_check = dapm_supply_check_power;  		break; -	case snd_soc_dapm_dai: -		w->power_check = dapm_dai_check_power; -		break;  	default:  		w->power_check = dapm_always_on_check_power;  		break; @@ -3375,7 +3368,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,  	template.reg = SND_SOC_NOPM;  	if (dai->driver->playback.stream_name) { -		template.id = snd_soc_dapm_dai; +		template.id = snd_soc_dapm_dai_in;  		template.name = dai->driver->playback.stream_name;  		template.sname = dai->driver->playback.stream_name; @@ -3393,7 +3386,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,  	}  	if (dai->driver->capture.stream_name) { -		template.id = snd_soc_dapm_dai; +		template.id = snd_soc_dapm_dai_out;  		template.name = dai->driver->capture.stream_name;  		template.sname = dai->driver->capture.stream_name; @@ -3423,8 +3416,13 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)  	/* For each DAI widget... */  	list_for_each_entry(dai_w, &card->widgets, list) { -		if (dai_w->id != snd_soc_dapm_dai) +		switch (dai_w->id) { +		case snd_soc_dapm_dai_in: +		case snd_soc_dapm_dai_out: +			break; +		default:  			continue; +		}  		dai = dai_w->priv; @@ -3433,8 +3431,13 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)  			if (w->dapm != dai_w->dapm)  				continue; -			if (w->id == snd_soc_dapm_dai) +			switch (w->id) { +			case snd_soc_dapm_dai_in: +			case snd_soc_dapm_dai_out:  				continue; +			default: +				break; +			}  			if (!w->sname)  				continue; diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 73bb8eefa491..ccb6be4d658d 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -928,8 +928,13 @@ static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,  	/* Create any new FE <--> BE connections */  	for (i = 0; i < list->num_widgets; i++) { -		if (list->widgets[i]->id != snd_soc_dapm_dai) +		switch (list->widgets[i]->id) { +		case snd_soc_dapm_dai_in: +		case snd_soc_dapm_dai_out: +			break; +		default:  			continue; +		}  		/* is there a valid BE rtd for this widget */  		be = dpcm_get_be(card, list->widgets[i], stream); @@ -2011,9 +2016,11 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)  		if (cpu_dai->driver->capture.channels_min)  			capture = 1;  	} else { -		if (codec_dai->driver->playback.channels_min) +		if (codec_dai->driver->playback.channels_min && +		    cpu_dai->driver->playback.channels_min)  			playback = 1; -		if (codec_dai->driver->capture.channels_min) +		if (codec_dai->driver->capture.channels_min && +		    cpu_dai->driver->capture.channels_min)  			capture = 1;  	} diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index 2f70ea7f6618..f52eab6d2231 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -142,13 +142,12 @@ static void tegra20_ac97_codec_write(struct snd_ac97 *ac97_snd,  	} while (!time_after(jiffies, timeout));  } -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops tegra20_ac97_ops = {  	.read		= tegra20_ac97_codec_read,  	.write		= tegra20_ac97_codec_write,  	.reset		= tegra20_ac97_codec_reset,  	.warm_reset	= tegra20_ac97_codec_warm_reset,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  static inline void tegra20_ac97_start_playback(struct tegra20_ac97 *ac97)  { @@ -327,7 +326,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)  	}  	dev_set_drvdata(&pdev->dev, ac97); -	ac97->clk_ac97 = clk_get(&pdev->dev, NULL); +	ac97->clk_ac97 = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(ac97->clk_ac97)) {  		dev_err(&pdev->dev, "Can't retrieve ac97 clock\n");  		ret = PTR_ERR(ac97->clk_ac97); @@ -341,18 +340,10 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)  		goto err_clk_put;  	} -	memregion = devm_request_mem_region(&pdev->dev, mem->start, -					    resource_size(mem), DRV_NAME); -	if (!memregion) { -		dev_err(&pdev->dev, "Memory region already claimed\n"); -		ret = -EBUSY; -		goto err_clk_put; -	} - -	regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); -	if (!regs) { -		dev_err(&pdev->dev, "ioremap failed\n"); -		ret = -ENOMEM; +	regs = devm_ioremap_resource(&pdev->dev, mem); +	if (IS_ERR(regs)) { +		ret = PTR_ERR(regs); +		dev_err(&pdev->dev, "ioremap failed: %d\n", ret);  		goto err_clk_put;  	} @@ -403,23 +394,9 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)  	ac97->capture_dma_data.maxburst = 4;  	ac97->capture_dma_data.slave_id = of_dma[0]; -	ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component, -					 &tegra20_ac97_dai, 1); -	if (ret) { -		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); -		ret = -ENOMEM; -		goto err_clk_put; -	} - -	ret = tegra_pcm_platform_register(&pdev->dev); -	if (ret) { -		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); -		goto err_unregister_component; -	} -  	ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);  	if (ret) -		goto err_unregister_pcm; +		goto err_clk_put;  	ret = tegra_asoc_utils_set_ac97_rate(&ac97->util_data);  	if (ret) @@ -431,20 +408,40 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)  		goto err_asoc_utils_fini;  	} +	ret = snd_soc_set_ac97_ops(&tegra20_ac97_ops); +	if (ret) { +		dev_err(&pdev->dev, "Failed to set AC'97 ops: %d\n", ret); +		goto err_asoc_utils_fini; +	} + +	ret = snd_soc_register_component(&pdev->dev, &tegra20_ac97_component, +					 &tegra20_ac97_dai, 1); +	if (ret) { +		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); +		ret = -ENOMEM; +		goto err_asoc_utils_fini; +	} + +	ret = tegra_pcm_platform_register(&pdev->dev); +	if (ret) { +		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); +		goto err_unregister_component; +	} +  	/* XXX: crufty ASoC AC97 API - only one AC97 codec allowed */  	workdata = ac97;  	return 0; -err_asoc_utils_fini: -	tegra_asoc_utils_fini(&ac97->util_data);  err_unregister_pcm:  	tegra_pcm_platform_unregister(&pdev->dev);  err_unregister_component:  	snd_soc_unregister_component(&pdev->dev); +err_asoc_utils_fini: +	tegra_asoc_utils_fini(&ac97->util_data);  err_clk_put: -	clk_put(ac97->clk_ac97);  err: +	snd_soc_set_ac97_ops(NULL);  	return ret;  } @@ -458,7 +455,8 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev)  	tegra_asoc_utils_fini(&ac97->util_data);  	clk_disable_unprepare(ac97->clk_ac97); -	clk_put(ac97->clk_ac97); + +	snd_soc_set_ac97_ops(NULL);  	return 0;  } diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 8a2840304d28..4bcce8a3cded 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c @@ -119,12 +119,11 @@ static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97)  }  /* AC97 controller operations */ -struct snd_ac97_bus_ops soc_ac97_ops = { +static struct snd_ac97_bus_ops txx9aclc_ac97_ops = {  	.read		= txx9aclc_ac97_read,  	.write		= txx9aclc_ac97_write,  	.reset		= txx9aclc_ac97_cold_reset,  }; -EXPORT_SYMBOL_GPL(soc_ac97_ops);  static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id)  { @@ -188,9 +187,9 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)  	if (!r)  		return -EBUSY; -	if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r), -				     dev_name(&pdev->dev))) -		return -EBUSY; +	drvdata->base = devm_ioremap_resource(&pdev->dev, r); +	if (IS_ERR(drvdata->base)) +		return PTR_ERR(drvdata->base);  	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);  	if (!drvdata) @@ -201,14 +200,15 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)  	    r->start >= TXX9_DIRECTMAP_BASE &&  	    r->start < TXX9_DIRECTMAP_BASE + 0x400000)  		drvdata->physbase |= 0xf00000000ull; -	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); -	if (!drvdata->base) -		return -EBUSY;  	err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq,  			       0, dev_name(&pdev->dev), drvdata);  	if (err < 0)  		return err; +	err = snd_soc_set_ac97_ops(&txx9aclc_ac97_ops); +	if (err < 0) +		return err; +  	return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component,  					  &txx9aclc_ac97_dai, 1);  } @@ -216,6 +216,7 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)  static int txx9aclc_ac97_dev_remove(struct platform_device *pdev)  {  	snd_soc_unregister_component(&pdev->dev); +	snd_soc_set_ac97_ops(NULL);  	return 0;  } |