diff options
-rw-r--r-- | arch/arm/mach-imx/mach-imx27_visstrim_m10.c | 1 | ||||
-rw-r--r-- | include/sound/soc.h | 1 | ||||
-rw-r--r-- | sound/soc/codecs/da7210.c | 146 | ||||
-rw-r--r-- | sound/soc/codecs/wm8994.c | 69 | ||||
-rw-r--r-- | sound/soc/codecs/wm8996.c | 34 | ||||
-rw-r--r-- | sound/soc/ep93xx/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/ep93xx/ep93xx-pcm.c | 148 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 6 | ||||
-rw-r--r-- | sound/soc/fsl/mpc8610_hpcd.c | 2 | ||||
-rw-r--r-- | sound/soc/fsl/p1022_ds.c | 32 | ||||
-rw-r--r-- | sound/soc/imx/imx-audmux.c | 8 | ||||
-rw-r--r-- | sound/soc/imx/mx27vis-aic32x4.c | 41 | ||||
-rw-r--r-- | sound/soc/pxa/pxa-ssp.c | 3 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 12 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 2 | ||||
-rw-r--r-- | sound/soc/soc-dmaengine-pcm.c | 1 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_alc5632.c | 1 |
17 files changed, 225 insertions, 283 deletions
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index c2766ae02b4..428459fbca4 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -263,6 +263,7 @@ static void __init visstrim_m10_board_init(void) imx27_add_fec(NULL); imx_add_gpio_keys(&visstrim_gpio_keys_platform_data); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); + imx_add_platform_device("mx27vis", 0, NULL, 0, NULL, 0); } static void __init visstrim_m10_timer_init(void) diff --git a/include/sound/soc.h b/include/sound/soc.h index 82bd773f8ab..2ebf7877c14 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -718,6 +718,7 @@ struct snd_soc_platform { int id; struct device *dev; struct snd_soc_platform_driver *driver; + struct mutex mutex; unsigned int suspended:1; /* platform is suspended */ unsigned int probed:1; diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index ab38e93c354..7843711729b 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -17,6 +17,7 @@ #include <linux/delay.h> #include <linux/i2c.h> +#include <linux/regmap.h> #include <linux/slab.h> #include <linux/module.h> #include <sound/pcm.h> @@ -626,41 +627,82 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = { /* Codec private data */ struct da7210_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; }; -/* - * Register cache - */ -static const u8 da7210_reg[] = { - 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */ - 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */ - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */ - 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */ - 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */ - 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */ - 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */ - 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */ - 0x00, /* R88 */ +static struct reg_default da7210_reg_defaults[] = { + { 0x01, 0x11 }, + { 0x03, 0x00 }, + { 0x04, 0x00 }, + { 0x05, 0x00 }, + { 0x06, 0x00 }, + { 0x07, 0x00 }, + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x0c, 0x00 }, + { 0x0d, 0x00 }, + { 0x0e, 0x00 }, + { 0x0f, 0x08 }, + { 0x10, 0x00 }, + { 0x11, 0x00 }, + { 0x12, 0x00 }, + { 0x13, 0x00 }, + { 0x14, 0x08 }, + { 0x15, 0x10 }, + { 0x16, 0x10 }, + { 0x17, 0x54 }, + { 0x18, 0x40 }, + { 0x19, 0x00 }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x00 }, + { 0x1e, 0x00 }, + { 0x1f, 0x00 }, + { 0x20, 0x00 }, + { 0x21, 0x00 }, + { 0x22, 0x00 }, + { 0x23, 0x02 }, + { 0x24, 0x00 }, + { 0x25, 0x76 }, + { 0x26, 0x00 }, + { 0x27, 0x00 }, + { 0x28, 0x04 }, + { 0x29, 0x00 }, + { 0x2a, 0x00 }, + { 0x2b, 0x30 }, + { 0x2c, 0x2A }, + { 0x83, 0x00 }, + { 0x84, 0x00 }, + { 0x85, 0x00 }, + { 0x86, 0x00 }, + { 0x87, 0x00 }, + { 0x88, 0x00 }, }; -static int da7210_volatile_register(struct snd_soc_codec *codec, +static bool da7210_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case DA7210_A_HID_UNLOCK: + case DA7210_A_TEST_UNLOCK: + case DA7210_A_PLL1: + case DA7210_A_CP_MODE: + return false; + default: + return true; + } +} + +static bool da7210_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { case DA7210_STATUS: - return 1; + return true; default: - return 0; + return false; } } @@ -866,7 +908,8 @@ static int da7210_probe(struct snd_soc_codec *codec) dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); - ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type); + codec->control_data = da7210->regmap; + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; @@ -983,12 +1026,14 @@ static int da7210_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); /* As suggested by Dialog */ - snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */ - snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4); - snd_soc_write(codec, DA7210_A_PLL1, 0x01); - snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C); - snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */ - snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00); + /* unlock */ + regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B); + regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4); + regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01); + regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C); + /* re-lock */ + regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00); + regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00); /* Activate all enabled subsystem */ snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); @@ -1000,10 +1045,6 @@ static int da7210_probe(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_dev_da7210 = { .probe = da7210_probe, - .reg_cache_size = ARRAY_SIZE(da7210_reg), - .reg_word_size = sizeof(u8), - .reg_cache_default = da7210_reg, - .volatile_register = da7210_volatile_register, .controls = da7210_snd_controls, .num_controls = ARRAY_SIZE(da7210_snd_controls), @@ -1014,6 +1055,17 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = { .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), }; +static struct regmap_config da7210_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .reg_defaults = da7210_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults), + .volatile_reg = da7210_volatile_register, + .readable_reg = da7210_readable_register, + .cache_type = REGCACHE_RBTREE, +}; + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static int __devinit da7210_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) @@ -1027,16 +1079,34 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, return -ENOMEM; i2c_set_clientdata(i2c, da7210); - da7210->control_type = SND_SOC_I2C; + + da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap); + if (IS_ERR(da7210->regmap)) { + ret = PTR_ERR(da7210->regmap); + dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); + return ret; + } ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7210, &da7210_dai, 1); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); + goto err_regmap; + } + return ret; + +err_regmap: + regmap_exit(da7210->regmap); + return ret; } static int __devexit da7210_i2c_remove(struct i2c_client *client) { + struct da7210_priv *da7210 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); + regmap_exit(da7210->regmap); return 0; } diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index bc12d097ef0..15fcb1bb714 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3166,9 +3166,16 @@ static void wm8958_default_micdet(u16 status, void *data) /* If we have jackdet that will detect removal */ if (wm8994->jackdet) { + mutex_lock(&wm8994->accdet_lock); + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); + wm1811_jackdet_set_mode(codec, + WM1811_JACKDET_MODE_JACK); + + mutex_unlock(&wm8994->accdet_lock); + if (wm8994->pdata->jd_ext_cap) { mutex_lock(&codec->mutex); snd_soc_dapm_disable_pin(&codec->dapm, @@ -3176,9 +3183,6 @@ static void wm8958_default_micdet(u16 status, void *data) snd_soc_dapm_sync(&codec->dapm); mutex_unlock(&codec->mutex); } - - wm1811_jackdet_set_mode(codec, - WM1811_JACKDET_MODE_JACK); } } @@ -3213,6 +3217,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) struct wm8994_priv *wm8994 = data; struct snd_soc_codec *codec = wm8994->codec; int reg; + bool present; mutex_lock(&wm8994->accdet_lock); @@ -3225,11 +3230,10 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) dev_dbg(codec->dev, "JACKDET %x\n", reg); - if (reg & WM1811_JACKDET_LVL) { - dev_dbg(codec->dev, "Jack detected\n"); + present = reg & WM1811_JACKDET_LVL; - snd_soc_jack_report(wm8994->micdet[0].jack, - SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); + if (present) { + dev_dbg(codec->dev, "Jack detected\n"); snd_soc_update_bits(codec, WM8958_MICBIAS2, WM8958_MICB2_DISCH, 0); @@ -3247,32 +3251,12 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, WM8958_MICD_ENA); - - /* If required for an external cap force MICBIAS on */ - if (wm8994->pdata->jd_ext_cap) { - mutex_lock(&codec->mutex); - snd_soc_dapm_force_enable_pin(&codec->dapm, - "MICBIAS2"); - snd_soc_dapm_sync(&codec->dapm); - mutex_unlock(&codec->mutex); - } } else { dev_dbg(codec->dev, "Jack not detected\n"); snd_soc_update_bits(codec, WM8958_MICBIAS2, WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); - if (wm8994->pdata->jd_ext_cap) { - mutex_lock(&codec->mutex); - snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); - snd_soc_dapm_sync(&codec->dapm); - mutex_unlock(&codec->mutex); - } - - snd_soc_jack_report(wm8994->micdet[0].jack, 0, - SND_JACK_MECHANICAL | SND_JACK_HEADSET | - wm8994->btn_mask); - /* Enable debounce while removed */ snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, WM1811_JACKDET_DB, WM1811_JACKDET_DB); @@ -3286,6 +3270,28 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) mutex_unlock(&wm8994->accdet_lock); + /* If required for an external cap force MICBIAS on */ + if (wm8994->pdata->jd_ext_cap) { + mutex_lock(&codec->mutex); + + if (present) + snd_soc_dapm_force_enable_pin(&codec->dapm, + "MICBIAS2"); + else + snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); + + snd_soc_dapm_sync(&codec->dapm); + mutex_unlock(&codec->mutex); + } + + if (present) + snd_soc_jack_report(wm8994->micdet[0].jack, + SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); + else + snd_soc_jack_report(wm8994->micdet[0].jack, 0, + SND_JACK_MECHANICAL | SND_JACK_HEADSET | + wm8994->btn_mask); + return IRQ_HANDLED; } @@ -3389,17 +3395,13 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) struct snd_soc_codec *codec = wm8994->codec; int reg, count; - mutex_lock(&wm8994->accdet_lock); - /* * Jack detection may have detected a removal simulataneously * with an update of the MICDET status; if so it will have * stopped detection and we can ignore this interrupt. */ - if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) { - mutex_unlock(&wm8994->accdet_lock); + if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) return IRQ_HANDLED; - } /* We may occasionally read a detection without an impedence * range being provided - if that happens loop again. @@ -3408,7 +3410,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) do { reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); if (reg < 0) { - mutex_unlock(&wm8994->accdet_lock); dev_err(codec->dev, "Failed to read mic detect status: %d\n", reg); @@ -3439,8 +3440,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) dev_warn(codec->dev, "Accessory detection with no callback\n"); out: - mutex_unlock(&wm8994->accdet_lock); - return IRQ_HANDLED; } diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 9376b19941b..40a124c9f15 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -118,7 +118,6 @@ WM8996_REGULATOR_EVENT(1) WM8996_REGULATOR_EVENT(2) static struct reg_default wm8996_reg[] = { - { WM8996_SOFTWARE_RESET, 0x8996 }, { WM8996_POWER_MANAGEMENT_1, 0x0 }, { WM8996_POWER_MANAGEMENT_2, 0x0 }, { WM8996_POWER_MANAGEMENT_3, 0x0 }, @@ -153,7 +152,6 @@ static struct reg_default wm8996_reg[] = { { WM8996_CHARGE_PUMP_1, 0x1f25 }, { WM8996_CHARGE_PUMP_2, 0xab19 }, { WM8996_DC_SERVO_1, 0x0 }, - { WM8996_DC_SERVO_2, 0x0 }, { WM8996_DC_SERVO_3, 0x0 }, { WM8996_DC_SERVO_5, 0x2a2a }, { WM8996_DC_SERVO_6, 0x0 }, @@ -892,8 +890,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, val = 0; mask = 0; if (wm8996->hpout_pending & HPOUT1L) { - val |= WM8996_HPOUT1L_RMV_SHORT; - mask |= WM8996_HPOUT1L_RMV_SHORT; + val |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP; + mask |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP; } else { mask |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP | @@ -901,8 +899,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, } if (wm8996->hpout_pending & HPOUT1R) { - val |= WM8996_HPOUT1R_RMV_SHORT; - mask |= WM8996_HPOUT1R_RMV_SHORT; + val |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP; + mask |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP; } else { mask |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP | @@ -914,8 +912,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, val = 0; mask = 0; if (wm8996->hpout_pending & HPOUT2L) { - val |= WM8996_HPOUT2L_RMV_SHORT; - mask |= WM8996_HPOUT2L_RMV_SHORT; + val |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP; + mask |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP; } else { mask |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP | @@ -923,8 +921,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, } if (wm8996->hpout_pending & HPOUT2R) { - val |= WM8996_HPOUT2R_RMV_SHORT; - mask |= WM8996_HPOUT2R_RMV_SHORT; + val |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP; + mask |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP; } else { mask |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP | @@ -1216,7 +1214,6 @@ SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8996_POWER_MANAGEMENT_1, 7, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start, SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8996_ANALOGUE_HP_2, 6, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0, rmv_short_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), @@ -1225,7 +1222,6 @@ SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8996_POWER_MANAGEMENT_1, 6, 0,NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start, SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8996_ANALOGUE_HP_2, 2, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0, rmv_short_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), @@ -1234,7 +1230,6 @@ SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8996_POWER_MANAGEMENT_1, 5, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start, SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8996_ANALOGUE_HP_1, 6, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0, rmv_short_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), @@ -1243,7 +1238,6 @@ SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8996_POWER_MANAGEMENT_1, 4, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start, SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8996_ANALOGUE_HP_1, 2, 0, NULL, 0), SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0, rmv_short_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), @@ -1436,32 +1430,28 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { { "HPOUT2L PGA", NULL, "DAC2L" }, { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, - { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" }, - { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, + { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_DCS" }, { "HPOUT2R PGA", NULL, "Charge Pump" }, { "HPOUT2R PGA", NULL, "Bandgap" }, { "HPOUT2R PGA", NULL, "DAC2R" }, { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, - { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" }, - { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, + { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_DCS" }, { "HPOUT1L PGA", NULL, "Charge Pump" }, { "HPOUT1L PGA", NULL, "Bandgap" }, { "HPOUT1L PGA", NULL, "DAC1L" }, { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, - { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" }, - { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, + { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_DCS" }, { "HPOUT1R PGA", NULL, "Charge Pump" }, { "HPOUT1R PGA", NULL, "Bandgap" }, { "HPOUT1R PGA", NULL, "DAC1R" }, { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, - { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" }, - { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" }, + { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_DCS" }, { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" }, { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" }, diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/ep93xx/Kconfig index 91a28de9410..88143db7e75 100644 --- a/sound/soc/ep93xx/Kconfig +++ b/sound/soc/ep93xx/Kconfig @@ -1,6 +1,7 @@ config SND_EP93XX_SOC tristate "SoC Audio support for the Cirrus Logic EP93xx series" depends on ARCH_EP93XX && SND_SOC + select SND_SOC_DMAENGINE_PCM help Say Y or M if you want to add support for codecs attached to the EP93xx I2S or AC97 interfaces. diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c index 32adca38b48..162dbb74f4c 100644 --- a/sound/soc/ep93xx/ep93xx-pcm.c +++ b/sound/soc/ep93xx/ep93xx-pcm.c @@ -23,6 +23,7 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> +#include <sound/dmaengine_pcm.h> #include <mach/dma.h> #include <mach/hardware.h> @@ -52,26 +53,6 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = { .fifo_size = 32, }; -struct ep93xx_runtime_data -{ - int pointer_bytes; - int periods; - int period_bytes; - struct dma_chan *dma_chan; - struct ep93xx_dma_data dma_data; -}; - -static void ep93xx_pcm_dma_callback(void *data) -{ - struct snd_pcm_substream *substream = data; - struct ep93xx_runtime_data *rtd = substream->runtime->private_data; - - rtd->pointer_bytes += rtd->period_bytes; - rtd->pointer_bytes %= rtd->period_bytes * rtd->periods; - - snd_pcm_period_elapsed(substream); -} - static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) { struct ep93xx_dma_data *data = filter_param; @@ -86,98 +67,48 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) static int ep93xx_pcm_open(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *soc_rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = soc_rtd->cpu_dai; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct ep93xx_pcm_dma_params *dma_params; - struct ep93xx_runtime_data *rtd; - dma_cap_mask_t mask; + struct ep93xx_dma_data *dma_data; int ret; - ret = snd_pcm_hw_constraint_integer(substream->runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) - return ret; - snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); - rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); - if (!rtd) + dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL); + if (!dma_data) return -ENOMEM; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_cap_set(DMA_CYCLIC, mask); - dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream); - rtd->dma_data.port = dma_params->dma_port; - rtd->dma_data.name = dma_params->name; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - rtd->dma_data.direction = DMA_MEM_TO_DEV; - else - rtd->dma_data.direction = DMA_DEV_TO_MEM; - - rtd->dma_chan = dma_request_channel(mask, ep93xx_pcm_dma_filter, - &rtd->dma_data); - if (!rtd->dma_chan) { - kfree(rtd); - return -EINVAL; - } - - substream->runtime->private_data = rtd; - return 0; -} + dma_data->port = dma_params->dma_port; + dma_data->name = dma_params->name; + dma_data->direction = snd_pcm_substream_to_dma_direction(substream); -static int ep93xx_pcm_close(struct snd_pcm_substream *substream) -{ - struct ep93xx_runtime_data *rtd = substream->runtime->private_data; + ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data); + if (ret) { + kfree(dma_data); + return ret; + } - dma_release_channel(rtd->dma_chan); - kfree(rtd); - return 0; -} + snd_dmaengine_pcm_set_data(substream, dma_data); -static int ep93xx_pcm_dma_submit(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct ep93xx_runtime_data *rtd = runtime->private_data; - struct dma_chan *chan = rtd->dma_chan; - struct dma_device *dma_dev = chan->device; - struct dma_async_tx_descriptor *desc; - - rtd->pointer_bytes = 0; - desc = dma_dev->device_prep_dma_cyclic(chan, runtime->dma_addr, - rtd->period_bytes * rtd->periods, - rtd->period_bytes, - rtd->dma_data.direction); - if (!desc) - return -EINVAL; - - desc->callback = ep93xx_pcm_dma_callback; - desc->callback_param = substream; - - dmaengine_submit(desc); return 0; } -static void ep93xx_pcm_dma_flush(struct snd_pcm_substream *substream) +static int ep93xx_pcm_close(struct snd_pcm_substream *substream) { - struct snd_pcm_runtime *runtime = substream->runtime; - struct ep93xx_runtime_data *rtd = runtime->private_data; + struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); - dmaengine_terminate_all(rtd->dma_chan); + snd_dmaengine_pcm_close(substream); + kfree(dma_data); + return 0; } static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_pcm_runtime *runtime = substream->runtime; - struct ep93xx_runtime_data *rtd = runtime->private_data; - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - rtd->periods = params_periods(params); - rtd->period_bytes = params_period_bytes(params); return 0; } @@ -187,41 +118,6 @@ static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream) return 0; } -static int ep93xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - int ret; - - ret = 0; - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ret = ep93xx_pcm_dma_submit(substream); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ep93xx_pcm_dma_flush(substream); - break; - - default: - ret = -EINVAL; - break; - } - - return ret; -} - -static snd_pcm_uframes_t ep93xx_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct ep93xx_runtime_data *rtd = substream->runtime->private_data; - - /* FIXME: implement this with sub-period granularity */ - return bytes_to_frames(runtime, rtd->pointer_bytes); -} - static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { @@ -239,8 +135,8 @@ static struct snd_pcm_ops ep93xx_pcm_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = ep93xx_pcm_hw_params, .hw_free = ep93xx_pcm_hw_free, - .trigger = ep93xx_pcm_trigger, - .pointer = ep93xx_pcm_pointer, + .trigger = snd_dmaengine_pcm_trigger, + .pointer = snd_dmaengine_pcm_pointer, .mmap = ep93xx_pcm_mmap, }; diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 3e066966d87..2eb407fa3b4 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -716,12 +716,12 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) } /* Trigger the machine driver's probe function. The platform driver - * name of the machine driver is taken from the /model property of the + * name of the machine driver is taken from /compatible property of the * device tree. We also pass the address of the CPU DAI driver * structure. */ - sprop = of_get_property(of_find_node_by_path("/"), "model", NULL); - /* Sometimes the model name has a "fsl," prefix, so we strip that. */ + sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL); + /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */ p = strrchr(sprop, ','); if (p) sprop = p + 1; diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index fcf9302f59b..afbabf427f2 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -546,7 +546,7 @@ static struct platform_driver mpc8610_hpcd_driver = { .probe = mpc8610_hpcd_probe, .remove = __devexit_p(mpc8610_hpcd_remove), .driver = { - /* The name must match the 'model' property in the device tree, + /* The name must match 'compatible' property in the device tree, * in lowercase letters. */ .name = "snd-soc-mpc8610hpcd", diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c index d32ec4646d2..b8898708347 100644 --- a/sound/soc/fsl/p1022_ds.c +++ b/sound/soc/fsl/p1022_ds.c @@ -543,6 +543,11 @@ static struct platform_driver p1022_ds_driver = { .probe = p1022_ds_probe, .remove = __devexit_p(p1022_ds_remove), .driver = { + /* + * The name must match 'compatible' property in the device tree, + * in lowercase letters. + */ + .name = "snd-soc-p1022ds", .owner = THIS_MODULE, }, }; @@ -556,33 +561,6 @@ static int __init p1022_ds_init(void) { struct device_node *guts_np; struct resource res; - const char *sprop; - - /* - * Check if we're actually running on a P1022DS. Older device trees - * have a model of "fsl,P1022" and newer ones use "fsl,P1022DS", so we - * need to support both. The SSI driver uses that property to link to - * the machine driver, so have to match it. - */ - sprop = of_get_property(of_find_node_by_path("/"), "model", NULL); - if (!sprop) { - pr_err("snd-soc-p1022ds: missing /model node"); - return -ENODEV; - } - - pr_debug("snd-soc-p1022ds: board model name is %s\n", sprop); - - /* - * The name of this board, taken from the device tree. Normally, this is a* - * fixed string, but some P1022DS device trees have a /model property of - * "fsl,P1022", and others have "fsl,P1022DS". - */ - if (strcasecmp(sprop, "fsl,p1022ds") == 0) - p1022_ds_driver.driver.name = "snd-soc-p1022ds"; - else if (strcasecmp(sprop, "fsl,p1022") == 0) - p1022_ds_driver.driver.name = "snd-soc-p1022"; - else - return -ENODEV; /* Get the physical address of the global utilities registers */ guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); diff --git a/sound/soc/imx/imx-audmux.c b/sound/soc/imx/imx-audmux.c index b83699d905b..a839494c5ea 100644 --- a/sound/soc/imx/imx-audmux.c +++ b/sound/soc/imx/imx-audmux.c @@ -167,7 +167,7 @@ static void __init audmux_debugfs_init(void) } } -static void __exit audmux_debugfs_remove(void) +static void __devexit audmux_debugfs_remove(void) { debugfs_remove_recursive(audmux_debugfs_root); } @@ -249,7 +249,7 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, } EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); -static int __init imx_audmux_probe(struct platform_device *pdev) +static int __devinit imx_audmux_probe(struct platform_device *pdev) { struct resource *res; const struct of_device_id *of_id = @@ -276,7 +276,7 @@ static int __init imx_audmux_probe(struct platform_device *pdev) return 0; } -static int __exit imx_audmux_remove(struct platform_device *pdev) +static int __devexit imx_audmux_remove(struct platform_device *pdev) { if (audmux_type == IMX31_AUDMUX) audmux_debugfs_remove(); @@ -287,7 +287,7 @@ static int __exit imx_audmux_remove(struct platform_device *pdev) static struct platform_driver imx_audmux_driver = { .probe = imx_audmux_probe, - .remove = __exit_p(imx_audmux_remove), + .remove = __devexit_p(imx_audmux_remove), .id_table = imx_audmux_ids, .driver = { .name = DRIVER_NAME, diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c index 976f857151f..f6d04ad4bb3 100644 --- a/sound/soc/imx/mx27vis-aic32x4.c +++ b/sound/soc/imx/mx27vis-aic32x4.c @@ -188,22 +188,16 @@ static struct snd_soc_card mx27vis_aic32x4 = { .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), }; -static struct platform_device *mx27vis_aic32x4_snd_device; - -static int __init mx27vis_aic32x4_init(void) +static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev) { int ret; - mx27vis_aic32x4_snd_device = platform_device_alloc("soc-audio", -1); - if (!mx27vis_aic32x4_snd_device) - return -ENOMEM; - - platform_set_drvdata(mx27vis_aic32x4_snd_device, &mx27vis_aic32x4); - ret = platform_device_add(mx27vis_aic32x4_snd_device); - + mx27vis_aic32x4.dev = &pdev->dev; + ret = snd_soc_register_card(&mx27vis_aic32x4); if (ret) { - printk(KERN_ERR "ASoC: Platform device allocation failed\n"); - platform_device_put(mx27vis_aic32x4_snd_device); + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + return ret; } /* Connect SSI0 as clock slave to SSI1 external pins */ @@ -221,22 +215,31 @@ static int __init mx27vis_aic32x4_init(void) ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins, ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP"); - if (ret) { + if (ret) printk(KERN_ERR "ASoC: unable to setup gpios\n"); - platform_device_put(mx27vis_aic32x4_snd_device); - } return ret; } -static void __exit mx27vis_aic32x4_exit(void) +static int __devexit mx27vis_aic32x4_remove(struct platform_device *pdev) { - platform_device_unregister(mx27vis_aic32x4_snd_device); + snd_soc_unregister_card(&mx27vis_aic32x4); + + return 0; } -module_init(mx27vis_aic32x4_init); -module_exit(mx27vis_aic32x4_exit); +static struct platform_driver mx27vis_aic32x4_audio_driver = { + .driver = { + .name = "mx27vis", + .owner = THIS_MODULE, + }, + .probe = mx27vis_aic32x4_probe, + .remove = __devexit_p(mx27vis_aic32x4_remove), +}; + +module_platform_driver(mx27vis_aic32x4_audio_driver); MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:mx27vis"); diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index a57cfbc038e..a16df0fa6ef 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -764,7 +764,8 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai) #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) #define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 7978f6c01ef..93a0daac508 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1531,14 +1531,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) if (dai_link->dai_fmt) { ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai, dai_link->dai_fmt); - if (ret != 0) + if (ret != 0 && ret != -ENOTSUPP) dev_warn(card->rtd[i].codec_dai->dev, "Failed to set DAI format: %d\n", ret); ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai, dai_link->dai_fmt); - if (ret != 0) + if (ret != 0 && ret != -ENOTSUPP) dev_warn(card->rtd[i].cpu_dai->dev, "Failed to set DAI format: %d\n", ret); @@ -2971,10 +2971,11 @@ EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll); */ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - if (dai->driver && dai->driver->ops->set_fmt) - return dai->driver->ops->set_fmt(dai, fmt); - else + if (dai->driver == NULL) return -EINVAL; + if (dai->driver->ops->set_fmt == NULL) + return -ENOTSUPP; + return dai->driver->ops->set_fmt(dai, fmt); } EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); @@ -3382,6 +3383,7 @@ int snd_soc_register_platform(struct device *dev, platform->dapm.dev = dev; platform->dapm.platform = platform; platform->dapm.stream_event = platform_drv->stream_event; + mutex_init(&platform->mutex); mutex_lock(&client_mutex); list_add(&platform->list, &platform_list); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index a4d4aa1e6c4..dcd11609f93 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1667,7 +1667,7 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); if (!dapm->debugfs_dapm) { - printk(KERN_WARNING + dev_warn(dapm->dev, "Failed to create DAPM debugfs directory\n"); return; } diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 0526cf82b54..4420b7030c8 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -142,6 +142,7 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream) direction = snd_pcm_substream_to_dma_direction(substream); + prtd->pos = 0; desc = chan->device->device_prep_dma_cyclic(chan, substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 2a27725cc9b..e45ccd851f6 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -115,7 +115,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = &codec->dapm; struct device_node *np = codec->card->dev->of_node; struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); - int ret; snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &tegra_alc5632_hs_jack); |