From 19b34bdc6d267723f3fc526ae775efba0ca4c39b Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 20 Feb 2013 17:28:34 +0000 Subject: ASoC: arizona: Move selection of FLL REFCLK into init In preparation for additional features on the FLL this patch moves the code selecting the REFCLK source based on the 32kHz clock into the FLL initialisation function. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 28 ++++++++++++++++------------ sound/soc/codecs/arizona.h | 3 +++ 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index ac948a671ea6..c14e7551a332 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1079,7 +1079,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, { struct arizona *arizona = fll->arizona; struct arizona_fll_cfg cfg, sync; - unsigned int reg, val; + unsigned int reg; int syncsrc; bool ena; int ret; @@ -1096,16 +1096,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, ena = reg & ARIZONA_FLL1_ENA; if (Fout) { - /* Do we have a 32kHz reference? */ - regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); - switch (val & ARIZONA_CLK_32K_SRC_MASK) { - case ARIZONA_CLK_SRC_MCLK1: - case ARIZONA_CLK_SRC_MCLK2: - syncsrc = val & ARIZONA_CLK_32K_SRC_MASK; - break; - default: - syncsrc = -1; - } + syncsrc = fll->ref_src; if (source == syncsrc) syncsrc = -1; @@ -1115,7 +1106,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, if (ret != 0) return ret; - ret = arizona_calc_fll(fll, &cfg, 32768, Fout); + ret = arizona_calc_fll(fll, &cfg, fll->ref_freq, Fout); if (ret != 0) return ret; } else { @@ -1178,6 +1169,7 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, int ok_irq, struct arizona_fll *fll) { int ret; + unsigned int val; init_completion(&fll->ok); @@ -1185,6 +1177,18 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, fll->base = base; fll->arizona = arizona; + /* Configure default refclk to 32kHz if we have one */ + regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); + switch (val & ARIZONA_CLK_32K_SRC_MASK) { + case ARIZONA_CLK_SRC_MCLK1: + case ARIZONA_CLK_SRC_MCLK2: + fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK; + break; + default: + fll->ref_src = -1; + } + fll->ref_freq = 32768; + snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id); snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name), "FLL%d clock OK", id); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 116372c91f5d..124f9f0ef1ac 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -201,6 +201,9 @@ struct arizona_fll { unsigned int fref; unsigned int fout; + int ref_src; + unsigned int ref_freq; + char lock_name[ARIZONA_FLL_NAME_LEN]; char clock_ok_name[ARIZONA_FLL_NAME_LEN]; }; -- cgit v1.2.3 From 9e359c645fa86daf0e3e5cc2dcbe7388f6e4d16a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 20 Feb 2013 17:28:35 +0000 Subject: ASoC: arizona: Tidy up SYNCCLK selection and cache values This patch caches the current SYNCCLK settings in the arizona_fll struct and uses these to simplify the code which determines which source should be used for the REFCLK and SYNCCLK inputs. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 101 ++++++++++++++++++++++----------------------- sound/soc/codecs/arizona.h | 2 + 2 files changed, 52 insertions(+), 51 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index c14e7551a332..03076efa4d9e 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1078,15 +1078,39 @@ int arizona_set_fll(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout) { struct arizona *arizona = fll->arizona; - struct arizona_fll_cfg cfg, sync; + struct arizona_fll_cfg ref, sync; unsigned int reg; - int syncsrc; bool ena; int ret; if (fll->fref == Fref && fll->fout == Fout) return 0; + if (fll->ref_src < 0 || fll->ref_src == source) { + if (Fout) { + ret = arizona_calc_fll(fll, &ref, Fref, Fout); + if (ret != 0) + return ret; + } + + fll->sync_src = -1; + fll->ref_src = source; + fll->ref_freq = Fref; + } else { + if (Fout) { + ret = arizona_calc_fll(fll, &ref, fll->ref_freq, Fout); + if (ret != 0) + return ret; + + ret = arizona_calc_fll(fll, &sync, Fref, Fout); + if (ret != 0) + return ret; + } + + fll->sync_src = source; + fll->sync_freq = Fref; + } + ret = regmap_read(arizona->regmap, fll->base + 1, ®); if (ret != 0) { arizona_fll_err(fll, "Failed to read current state: %d\n", @@ -1096,24 +1120,32 @@ int arizona_set_fll(struct arizona_fll *fll, int source, ena = reg & ARIZONA_FLL1_ENA; if (Fout) { - syncsrc = fll->ref_src; + regmap_update_bits(arizona->regmap, fll->base + 5, + ARIZONA_FLL1_OUTDIV_MASK, + ref.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); - if (source == syncsrc) - syncsrc = -1; + arizona_apply_fll(arizona, fll->base, &ref, fll->ref_src); + if (fll->sync_src >= 0) + arizona_apply_fll(arizona, fll->base + 0x10, &sync, + fll->sync_src); - if (syncsrc >= 0) { - ret = arizona_calc_fll(fll, &sync, Fref, Fout); - if (ret != 0) - return ret; + if (!ena) + pm_runtime_get(arizona->dev); - ret = arizona_calc_fll(fll, &cfg, fll->ref_freq, Fout); - if (ret != 0) - return ret; - } else { - ret = arizona_calc_fll(fll, &cfg, Fref, Fout); - if (ret != 0) - return ret; - } + /* Clear any pending completions */ + try_wait_for_completion(&fll->ok); + + regmap_update_bits(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); + if (fll->sync_src >= 0) + regmap_update_bits(arizona->regmap, fll->base + 0x11, + ARIZONA_FLL1_SYNC_ENA, + ARIZONA_FLL1_SYNC_ENA); + + ret = wait_for_completion_timeout(&fll->ok, + msecs_to_jiffies(250)); + if (ret == 0) + arizona_fll_warn(fll, "Timed out waiting for lock\n"); } else { regmap_update_bits(arizona->regmap, fll->base + 1, ARIZONA_FLL1_ENA, 0); @@ -1122,42 +1154,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source, if (ena) pm_runtime_put_autosuspend(arizona->dev); - - fll->fref = Fref; - fll->fout = Fout; - - return 0; } - regmap_update_bits(arizona->regmap, fll->base + 5, - ARIZONA_FLL1_OUTDIV_MASK, - cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); - - if (syncsrc >= 0) { - arizona_apply_fll(arizona, fll->base, &cfg, syncsrc); - arizona_apply_fll(arizona, fll->base + 0x10, &sync, source); - } else { - arizona_apply_fll(arizona, fll->base, &cfg, source); - } - - if (!ena) - pm_runtime_get(arizona->dev); - - /* Clear any pending completions */ - try_wait_for_completion(&fll->ok); - - regmap_update_bits(arizona->regmap, fll->base + 1, - ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); - if (syncsrc >= 0) - regmap_update_bits(arizona->regmap, fll->base + 0x11, - ARIZONA_FLL1_SYNC_ENA, - ARIZONA_FLL1_SYNC_ENA); - - ret = wait_for_completion_timeout(&fll->ok, - msecs_to_jiffies(250)); - if (ret == 0) - arizona_fll_warn(fll, "Timed out waiting for lock\n"); - fll->fref = Fref; fll->fout = Fout; @@ -1176,6 +1174,7 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, fll->id = id; fll->base = base; fll->arizona = arizona; + fll->sync_src = -1; /* Configure default refclk to 32kHz if we have one */ regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 124f9f0ef1ac..37766b547b9d 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -201,6 +201,8 @@ struct arizona_fll { unsigned int fref; unsigned int fout; + int sync_src; + unsigned int sync_freq; int ref_src; unsigned int ref_freq; -- cgit v1.2.3 From d122d6c974e35c940a638c26aa70bea363141d27 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 20 Feb 2013 17:28:36 +0000 Subject: ASoC: arizona: Factor out check for enabled FLL In preparation for additional features on the FLL this patch factors out the code which checks if an FLL is currently enabled into a seperate function. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 03076efa4d9e..4640bccbfba2 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1074,12 +1074,27 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, ARIZONA_FLL1_CTRL_UPD | cfg->n); } +static bool arizona_is_enabled_fll(struct arizona_fll *fll) +{ + struct arizona *arizona = fll->arizona; + unsigned int reg; + int ret; + + ret = regmap_read(arizona->regmap, fll->base + 1, ®); + if (ret != 0) { + arizona_fll_err(fll, "Failed to read current state: %d\n", + ret); + return ret; + } + + return reg & ARIZONA_FLL1_ENA; +} + int arizona_set_fll(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout) { struct arizona *arizona = fll->arizona; struct arizona_fll_cfg ref, sync; - unsigned int reg; bool ena; int ret; @@ -1111,13 +1126,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, fll->sync_freq = Fref; } - ret = regmap_read(arizona->regmap, fll->base + 1, ®); - if (ret != 0) { - arizona_fll_err(fll, "Failed to read current state: %d\n", - ret); - return ret; - } - ena = reg & ARIZONA_FLL1_ENA; + ena = arizona_is_enabled_fll(fll); if (Fout) { regmap_update_bits(arizona->regmap, fll->base + 5, -- cgit v1.2.3 From 7604054e13897c2da3570e33a67ecb76462212d8 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 20 Feb 2013 17:28:37 +0000 Subject: ASoC: arizona: Factor out FLL disable In preparation for additional features on the FLL this patch factors out the code for disabling an FLL into a seperate function. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 4640bccbfba2..a8821a819adc 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1090,6 +1090,20 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll) return reg & ARIZONA_FLL1_ENA; } +static void arizona_disable_fll(struct arizona_fll *fll) +{ + struct arizona *arizona = fll->arizona; + bool change; + + regmap_update_bits_check(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_ENA, 0, &change); + regmap_update_bits(arizona->regmap, fll->base + 0x11, + ARIZONA_FLL1_SYNC_ENA, 0); + + if (change) + pm_runtime_put_autosuspend(arizona->dev); +} + int arizona_set_fll(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout) { @@ -1156,13 +1170,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, if (ret == 0) arizona_fll_warn(fll, "Timed out waiting for lock\n"); } else { - regmap_update_bits(arizona->regmap, fll->base + 1, - ARIZONA_FLL1_ENA, 0); - regmap_update_bits(arizona->regmap, fll->base + 0x11, - ARIZONA_FLL1_SYNC_ENA, 0); - - if (ena) - pm_runtime_put_autosuspend(arizona->dev); + arizona_disable_fll(fll); } fll->fref = Fref; -- cgit v1.2.3 From 357228153b4a158bdeb05f1c46ee13ef60a675a6 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 20 Feb 2013 17:28:38 +0000 Subject: ASoC: arizona: Factor out FLL enable In preparation for additional features on the FLL this patch factors out the code for enabling an FLL into a seperate function. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 66 +++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 30 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index a8821a819adc..e770945fa019 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1090,6 +1090,41 @@ static bool arizona_is_enabled_fll(struct arizona_fll *fll) return reg & ARIZONA_FLL1_ENA; } +static void arizona_enable_fll(struct arizona_fll *fll, + struct arizona_fll_cfg *ref, + struct arizona_fll_cfg *sync) +{ + struct arizona *arizona = fll->arizona; + int ret; + + regmap_update_bits(arizona->regmap, fll->base + 5, + ARIZONA_FLL1_OUTDIV_MASK, + ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); + + arizona_apply_fll(arizona, fll->base, ref, fll->ref_src); + if (fll->sync_src >= 0) + arizona_apply_fll(arizona, fll->base + 0x10, sync, + fll->sync_src); + + if (!arizona_is_enabled_fll(fll)) + pm_runtime_get(arizona->dev); + + /* Clear any pending completions */ + try_wait_for_completion(&fll->ok); + + regmap_update_bits(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); + if (fll->sync_src >= 0) + regmap_update_bits(arizona->regmap, fll->base + 0x11, + ARIZONA_FLL1_SYNC_ENA, + ARIZONA_FLL1_SYNC_ENA); + + ret = wait_for_completion_timeout(&fll->ok, + msecs_to_jiffies(250)); + if (ret == 0) + arizona_fll_warn(fll, "Timed out waiting for lock\n"); +} + static void arizona_disable_fll(struct arizona_fll *fll) { struct arizona *arizona = fll->arizona; @@ -1107,9 +1142,7 @@ static void arizona_disable_fll(struct arizona_fll *fll) int arizona_set_fll(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout) { - struct arizona *arizona = fll->arizona; struct arizona_fll_cfg ref, sync; - bool ena; int ret; if (fll->fref == Fref && fll->fout == Fout) @@ -1140,35 +1173,8 @@ int arizona_set_fll(struct arizona_fll *fll, int source, fll->sync_freq = Fref; } - ena = arizona_is_enabled_fll(fll); - if (Fout) { - regmap_update_bits(arizona->regmap, fll->base + 5, - ARIZONA_FLL1_OUTDIV_MASK, - ref.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); - - arizona_apply_fll(arizona, fll->base, &ref, fll->ref_src); - if (fll->sync_src >= 0) - arizona_apply_fll(arizona, fll->base + 0x10, &sync, - fll->sync_src); - - if (!ena) - pm_runtime_get(arizona->dev); - - /* Clear any pending completions */ - try_wait_for_completion(&fll->ok); - - regmap_update_bits(arizona->regmap, fll->base + 1, - ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); - if (fll->sync_src >= 0) - regmap_update_bits(arizona->regmap, fll->base + 0x11, - ARIZONA_FLL1_SYNC_ENA, - ARIZONA_FLL1_SYNC_ENA); - - ret = wait_for_completion_timeout(&fll->ok, - msecs_to_jiffies(250)); - if (ret == 0) - arizona_fll_warn(fll, "Timed out waiting for lock\n"); + arizona_enable_fll(fll, &ref, &sync); } else { arizona_disable_fll(fll); } -- cgit v1.2.3 From de1e6eedddeab2fa417c38c231d896198f903129 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 20 Feb 2013 17:28:39 +0000 Subject: ASoC: arizona: Improve suppression of noop FLL updates Previously updates that only changes FLL source would be missed, this patch corrects this. We also ensures that both REFCLK and SYNCCLK frequency changes are considered, in preparation for future updates. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 16 ++++++++++------ sound/soc/codecs/arizona.h | 3 +-- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index e770945fa019..149e44f42f84 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1145,10 +1145,12 @@ int arizona_set_fll(struct arizona_fll *fll, int source, struct arizona_fll_cfg ref, sync; int ret; - if (fll->fref == Fref && fll->fout == Fout) - return 0; - if (fll->ref_src < 0 || fll->ref_src == source) { + if (fll->sync_src == -1 && + fll->ref_src == source && fll->ref_freq == Fref && + fll->fout == Fout) + return 0; + if (Fout) { ret = arizona_calc_fll(fll, &ref, Fref, Fout); if (ret != 0) @@ -1159,6 +1161,10 @@ int arizona_set_fll(struct arizona_fll *fll, int source, fll->ref_src = source; fll->ref_freq = Fref; } else { + if (fll->sync_src == source && + fll->sync_freq == Fref && fll->fout == Fout) + return 0; + if (Fout) { ret = arizona_calc_fll(fll, &ref, fll->ref_freq, Fout); if (ret != 0) @@ -1172,6 +1178,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, fll->sync_src = source; fll->sync_freq = Fref; } + fll->fout = Fout; if (Fout) { arizona_enable_fll(fll, &ref, &sync); @@ -1179,9 +1186,6 @@ int arizona_set_fll(struct arizona_fll *fll, int source, arizona_disable_fll(fll); } - fll->fref = Fref; - fll->fout = Fout; - return 0; } EXPORT_SYMBOL_GPL(arizona_set_fll); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 37766b547b9d..bedf12a527e5 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -198,9 +198,8 @@ struct arizona_fll { unsigned int base; unsigned int vco_mult; struct completion ok; - unsigned int fref; - unsigned int fout; + unsigned int fout; int sync_src; unsigned int sync_freq; int ref_src; -- cgit v1.2.3 From ee929a9780605f21ad67a1ccb626baa41e038c1a Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 20 Feb 2013 17:28:40 +0000 Subject: ASoC: arizona: Add support for directly setting the FLL REFCLK This patch allows the REFCLK to be set directly allowing much greater flexibility in how the FLLs are configured. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 39 +++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/arizona.h | 2 ++ sound/soc/codecs/wm5102.c | 6 ++++++ sound/soc/codecs/wm5102.h | 6 ++++-- sound/soc/codecs/wm5110.c | 6 ++++++ sound/soc/codecs/wm5110.h | 6 ++++-- 6 files changed, 61 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 149e44f42f84..2bebfae3485f 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1139,6 +1139,45 @@ static void arizona_disable_fll(struct arizona_fll *fll) pm_runtime_put_autosuspend(arizona->dev); } +int arizona_set_fll_refclk(struct arizona_fll *fll, int source, + unsigned int Fref, unsigned int Fout) +{ + struct arizona_fll_cfg ref, sync; + int ret; + + if (source < 0) + return -EINVAL; + + if (fll->ref_src == source && fll->ref_freq == Fref && + fll->fout == Fout) + return 0; + + if (Fout) { + ret = arizona_calc_fll(fll, &ref, Fref, Fout); + if (ret != 0) + return ret; + + if (fll->sync_src >= 0) { + ret = arizona_calc_fll(fll, &sync, fll->sync_freq, Fout); + if (ret != 0) + return ret; + } + } + + fll->ref_src = source; + fll->ref_freq = Fref; + fll->fout = Fout; + + if (Fout) { + arizona_enable_fll(fll, &ref, &sync); + } else { + arizona_disable_fll(fll); + } + + return 0; +} +EXPORT_SYMBOL_GPL(arizona_set_fll_refclk); + int arizona_set_fll(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout) { diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index bedf12a527e5..f2ca41f8dc83 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -211,6 +211,8 @@ struct arizona_fll { extern int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, int ok_irq, struct arizona_fll *fll); +extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source, + unsigned int Fref, unsigned int Fout); extern int arizona_set_fll(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout); diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index b8d461db369f..5515d85fd82f 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1483,6 +1483,12 @@ static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source, return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout); case WM5102_FLL2: return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout); + case WM5102_FLL1_REFCLK: + return arizona_set_fll_refclk(&wm5102->fll[0], source, Fref, + Fout); + case WM5102_FLL2_REFCLK: + return arizona_set_fll_refclk(&wm5102->fll[1], source, Fref, + Fout); default: return -EINVAL; } diff --git a/sound/soc/codecs/wm5102.h b/sound/soc/codecs/wm5102.h index d30477f3070c..adb38040f661 100644 --- a/sound/soc/codecs/wm5102.h +++ b/sound/soc/codecs/wm5102.h @@ -15,7 +15,9 @@ #include "arizona.h" -#define WM5102_FLL1 1 -#define WM5102_FLL2 2 +#define WM5102_FLL1 1 +#define WM5102_FLL2 2 +#define WM5102_FLL1_REFCLK 3 +#define WM5102_FLL2_REFCLK 4 #endif diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index cd17b477781d..2d9b55f57eed 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -880,6 +880,12 @@ static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source, return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout); case WM5110_FLL2: return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout); + case WM5110_FLL1_REFCLK: + return arizona_set_fll_refclk(&wm5110->fll[0], source, Fref, + Fout); + case WM5110_FLL2_REFCLK: + return arizona_set_fll_refclk(&wm5110->fll[1], source, Fref, + Fout); default: return -EINVAL; } diff --git a/sound/soc/codecs/wm5110.h b/sound/soc/codecs/wm5110.h index 75e9351ccab0..e6c0cd4235c5 100644 --- a/sound/soc/codecs/wm5110.h +++ b/sound/soc/codecs/wm5110.h @@ -15,7 +15,9 @@ #include "arizona.h" -#define WM5110_FLL1 1 -#define WM5110_FLL2 2 +#define WM5110_FLL1 1 +#define WM5110_FLL2 2 +#define WM5110_FLL1_REFCLK 3 +#define WM5110_FLL2_REFCLK 4 #endif -- cgit v1.2.3 From f3f1163d19ebd5aa374e5df5372a8f932f2bd5f9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 20 Feb 2013 17:28:41 +0000 Subject: ASoC: arizona: Add convience define for clearing SYNCCLK Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 8 ++++---- sound/soc/codecs/arizona.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 2bebfae3485f..6837863b582d 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1185,7 +1185,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, int ret; if (fll->ref_src < 0 || fll->ref_src == source) { - if (fll->sync_src == -1 && + if (fll->sync_src == ARIZONA_FLL_SRC_NONE && fll->ref_src == source && fll->ref_freq == Fref && fll->fout == Fout) return 0; @@ -1196,7 +1196,7 @@ int arizona_set_fll(struct arizona_fll *fll, int source, return ret; } - fll->sync_src = -1; + fll->sync_src = ARIZONA_FLL_SRC_NONE; fll->ref_src = source; fll->ref_freq = Fref; } else { @@ -1240,7 +1240,7 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, fll->id = id; fll->base = base; fll->arizona = arizona; - fll->sync_src = -1; + fll->sync_src = ARIZONA_FLL_SRC_NONE; /* Configure default refclk to 32kHz if we have one */ regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val); @@ -1250,7 +1250,7 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, fll->ref_src = val & ARIZONA_CLK_32K_SRC_MASK; break; default: - fll->ref_src = -1; + fll->ref_src = ARIZONA_FLL_SRC_NONE; } fll->ref_freq = 32768; diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index f2ca41f8dc83..3f84943b23bf 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -32,6 +32,7 @@ #define ARIZONA_CLK_SRC_AIF2BCLK 0x9 #define ARIZONA_CLK_SRC_AIF3BCLK 0xa +#define ARIZONA_FLL_SRC_NONE -1 #define ARIZONA_FLL_SRC_MCLK1 0 #define ARIZONA_FLL_SRC_MCLK2 1 #define ARIZONA_FLL_SRC_SLIMCLK 3 -- cgit v1.2.3 From ddbce97cd1798ba4661e33662c659b168e9f51ed Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 15 Feb 2013 17:27:22 +0000 Subject: ASoC: arizona: Only allow input volume updates when inputs are enabled Since we are automatically managing the mutes we may as well also manage the volume update bits, disabling volume updates while none of the inputs are active. Since we are doing this we may as well allow the volumes to ramp together so only enable volume updates once at the end of power up. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 39 +++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/arizona.h | 3 +++ sound/soc/codecs/wm5102.c | 26 +++++++++++++------------- sound/soc/codecs/wm5110.c | 34 +++++++++++++++++----------------- 4 files changed, 70 insertions(+), 32 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 6837863b582d..debd184cc706 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -332,9 +333,27 @@ const struct soc_enum arizona_ng_hold = 4, arizona_ng_hold_text); EXPORT_SYMBOL_GPL(arizona_ng_hold); +static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + unsigned int val; + int i; + + if (ena) + val = ARIZONA_IN_VU; + else + val = 0; + + for (i = 0; i < priv->num_inputs; i++) + snd_soc_update_bits(codec, + ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4), + ARIZONA_IN_VU, val); +} + int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { + struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); unsigned int reg; if (w->shift % 2) @@ -343,13 +362,29 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8); switch (event) { + case SND_SOC_DAPM_PRE_PMU: + priv->in_pending++; + break; case SND_SOC_DAPM_POST_PMU: snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0); + + /* If this is the last input pending then allow VU */ + priv->in_pending--; + if (priv->in_pending == 0) { + msleep(1); + arizona_in_set_vu(w->codec, 1); + } break; case SND_SOC_DAPM_PRE_PMD: - snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, - ARIZONA_IN1L_MUTE); + snd_soc_update_bits(w->codec, reg, + ARIZONA_IN1L_MUTE | ARIZONA_IN_VU, + ARIZONA_IN1L_MUTE | ARIZONA_IN_VU); break; + case SND_SOC_DAPM_POST_PMD: + /* Disable volume updates if no inputs are enabled */ + reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES); + if (reg == 0) + arizona_in_set_vu(w->codec, 0); } return 0; diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 3f84943b23bf..d592adcc969c 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -65,6 +65,9 @@ struct arizona_priv { int sysclk; int asyncclk; struct arizona_dai_priv dai[ARIZONA_MAX_DAI]; + + int num_inputs; + unsigned int in_pending; }; #define ARIZONA_NUM_MIXER_INPUTS 99 diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 5515d85fd82f..44d4c69d25e5 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -973,22 +973,28 @@ SND_SOC_DAPM_INPUT("IN3R"), SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), @@ -1599,13 +1605,6 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec) #define WM5102_DIG_VU 0x0200 static unsigned int wm5102_digital_vu[] = { - ARIZONA_ADC_DIGITAL_VOLUME_1L, - ARIZONA_ADC_DIGITAL_VOLUME_1R, - ARIZONA_ADC_DIGITAL_VOLUME_2L, - ARIZONA_ADC_DIGITAL_VOLUME_2R, - ARIZONA_ADC_DIGITAL_VOLUME_3L, - ARIZONA_ADC_DIGITAL_VOLUME_3R, - ARIZONA_DAC_DIGITAL_VOLUME_1L, ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_DAC_DIGITAL_VOLUME_2L, @@ -1648,6 +1647,7 @@ static int wm5102_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wm5102); wm5102->core.arizona = arizona; + wm5102->core.num_inputs = 6; wm5102->core.adsp[0].part = "wm5102"; wm5102->core.adsp[0].num = 1; diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 2d9b55f57eed..a64d3b8bc3b4 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -416,28 +416,36 @@ SND_SOC_DAPM_INPUT("IN4R"), SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT, 0, NULL, 0, arizona_in_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1, ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0), @@ -993,15 +1001,6 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec) #define WM5110_DIG_VU 0x0200 static unsigned int wm5110_digital_vu[] = { - ARIZONA_ADC_DIGITAL_VOLUME_1L, - ARIZONA_ADC_DIGITAL_VOLUME_1R, - ARIZONA_ADC_DIGITAL_VOLUME_2L, - ARIZONA_ADC_DIGITAL_VOLUME_2R, - ARIZONA_ADC_DIGITAL_VOLUME_3L, - ARIZONA_ADC_DIGITAL_VOLUME_3R, - ARIZONA_ADC_DIGITAL_VOLUME_4L, - ARIZONA_ADC_DIGITAL_VOLUME_4R, - ARIZONA_DAC_DIGITAL_VOLUME_1L, ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_DAC_DIGITAL_VOLUME_2L, @@ -1046,6 +1045,7 @@ static int wm5110_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wm5110); wm5110->core.arizona = arizona; + wm5110->core.num_inputs = 8; for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++) wm5110->fll[i].vco_mult = 3; -- cgit v1.2.3 From 1c5617fc230b399c1d84711b8a2e316199387eb9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 22 Feb 2013 17:10:37 +0000 Subject: ASoC: arizona: Don't enable FLL on REFCLK configuration Enabling the FLL when REFCLK is being configured is not what the user would expect and can cause issues if SYNCCLK has no specified frequency. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index debd184cc706..e456cb4b196e 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1183,17 +1183,17 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source, if (source < 0) return -EINVAL; - if (fll->ref_src == source && fll->ref_freq == Fref && - fll->fout == Fout) + if (fll->ref_src == source && fll->ref_freq == Fref) return 0; - if (Fout) { - ret = arizona_calc_fll(fll, &ref, Fref, Fout); + if (fll->fout) { + ret = arizona_calc_fll(fll, &ref, Fref, fll->fout); if (ret != 0) return ret; if (fll->sync_src >= 0) { - ret = arizona_calc_fll(fll, &sync, fll->sync_freq, Fout); + ret = arizona_calc_fll(fll, &sync, fll->sync_freq, + fll->fout); if (ret != 0) return ret; } @@ -1201,12 +1201,9 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source, fll->ref_src = source; fll->ref_freq = Fref; - fll->fout = Fout; - if (Fout) { + if (fll->fout) { arizona_enable_fll(fll, &ref, &sync); - } else { - arizona_disable_fll(fll); } return 0; -- cgit v1.2.3 From f6a75d95048895ed3fa6758e1ec1238d945472c7 Mon Sep 17 00:00:00 2001 From: Zoltan Puskas Date: Wed, 20 Feb 2013 17:31:35 +0100 Subject: ASoC: atmel: Add slave mode support to SSC in DSP Mode A Add previously unsupported slave mode to the SSC peripheral when using DSP/PCM Mode A format on the Atmel ARM platform. Signed-off-by: Zoltan Puskas Signed-off-by: Mark Brown --- sound/soc/atmel/atmel_ssc_dai.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index e13580d6c476..94da62345a27 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -533,6 +533,49 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: + /* + * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks. + * + * The SSC transmit clock is obtained from the BCLK signal on + * on the TK line, and the SSC receive clock is + * generated from the transmit clock. + * + * Data is transferred on first BCLK after LRC pulse rising + * edge.If stereo, the right channel data is contiguous with + * the left channel data. + */ + rcmr = SSC_BF(RCMR_PERIOD, 0) + | SSC_BF(RCMR_STTDLY, START_DELAY) + | SSC_BF(RCMR_START, SSC_START_RISING_RF) + | SSC_BF(RCMR_CKI, SSC_CKI_RISING) + | SSC_BF(RCMR_CKO, SSC_CKO_NONE) + | SSC_BF(RCMR_CKS, SSC_CKS_PIN); + + rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) + | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) + | SSC_BF(RFMR_FSLEN, 0) + | SSC_BF(RFMR_DATNB, (channels - 1)) + | SSC_BIT(RFMR_MSBF) + | SSC_BF(RFMR_LOOP, 0) + | SSC_BF(RFMR_DATLEN, (bits - 1)); + + tcmr = SSC_BF(TCMR_PERIOD, 0) + | SSC_BF(TCMR_STTDLY, START_DELAY) + | SSC_BF(TCMR_START, SSC_START_RISING_RF) + | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) + | SSC_BF(TCMR_CKO, SSC_CKO_NONE) + | SSC_BF(TCMR_CKS, SSC_CKS_PIN); + + tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) + | SSC_BF(TFMR_FSDEN, 0) + | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) + | SSC_BF(TFMR_FSLEN, 0) + | SSC_BF(TFMR_DATNB, (channels - 1)) + | SSC_BIT(TFMR_MSBF) + | SSC_BF(TFMR_DATDEF, 0) + | SSC_BF(TFMR_DATLEN, (bits - 1)); + break; + default: printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n", ssc_p->daifmt); -- cgit v1.2.3 From 2952b27e2e463b28d5c0f04000f96b968137ca42 Mon Sep 17 00:00:00 2001 From: Michal Bachraty Date: Thu, 28 Feb 2013 16:07:08 +0100 Subject: ASoC: davinci-mcasp: Add support for multichannel playback Davinci McASP has support for I2S multichannel playback. For I2S playback/receive, each serializer is capable to play 2 channels (L/R) audio data.Serializer function (Playback-receive-none) is configured in DT, depending on hardware specification. It is possible to play less channels than configured in DT. For that purpose,only specific number of active serializers are enabled. McASP FIFO need to have DMA transfer Bcnt set to number of enabled serializers, otherwise no data are transfered to McASP and Alsa generates "DMA/IRQ playback write error (DMA or IRQ trouble?)" error. For TDM mode, McASP is capable to play or receive 32 channels for one serializer. McAsp has support for max 16 serializer, therefore max channels is 32 * 8. Signed-off-by: Michal Bachraty Tested-by: Daniel Mack Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 66 ++++++++++++++++++++++++++++++++++----- sound/soc/davinci/davinci-pcm.c | 16 +++++----- sound/soc/davinci/davinci-pcm.h | 1 + 3 files changed, 68 insertions(+), 15 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 9321e5c9d8c1..5cd85a879579 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -235,6 +235,10 @@ #define DISMOD (val)(val<<2) #define TXSTATE BIT(4) #define RXSTATE BIT(5) +#define SRMOD_MASK 3 +#define SRMOD_INACTIVE 0 +#define SRMOD_TX 1 +#define SRMOD_RX 2 /* * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits @@ -657,12 +661,15 @@ static int davinci_config_channel_size(struct davinci_audio_dev *dev, return 0; } -static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) +static int davinci_hw_common_param(struct davinci_audio_dev *dev, int stream, + int channels) { int i; u8 tx_ser = 0; u8 rx_ser = 0; - + u8 ser; + u8 slots = dev->tdm_slots; + u8 max_active_serializers = (channels + slots - 1) / slots; /* Default configuration */ mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); @@ -679,17 +686,43 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) RXDATADMADIS); } + for (i = 0; i < dev->num_serializer; i++) { + if (dev->serial_dir[i] == TX_MODE) + tx_ser++; + if (dev->serial_dir[i] == RX_MODE) + rx_ser++; + } + + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + ser = tx_ser; + else + ser = rx_ser; + + if (ser < max_active_serializers) { + dev_warn(dev->dev, "stream has more channels (%d) than are " + "enabled in mcasp (%d)\n", channels, ser * slots); + return -EINVAL; + } + + tx_ser = 0; + rx_ser = 0; + for (i = 0; i < dev->num_serializer; i++) { mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), dev->serial_dir[i]); - if (dev->serial_dir[i] == TX_MODE) { + if (dev->serial_dir[i] == TX_MODE && + tx_ser < max_active_serializers) { mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AXR(i)); tx_ser++; - } else if (dev->serial_dir[i] == RX_MODE) { + } else if (dev->serial_dir[i] == RX_MODE && + rx_ser < max_active_serializers) { mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AXR(i)); rx_ser++; + } else { + mcasp_mod_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), + SRMOD_INACTIVE, SRMOD_MASK); } } @@ -729,6 +762,8 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); } } + + return 0; } static void davinci_hw_param(struct davinci_audio_dev *dev, int stream) @@ -812,8 +847,14 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, &dev->dma_params[substream->stream]; int word_length; u8 fifo_level; + u8 slots = dev->tdm_slots; + int channels; + struct snd_interval *pcm_channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + channels = pcm_channels->min; - davinci_hw_common_param(dev, substream->stream); + if (davinci_hw_common_param(dev, substream->stream, channels) == -EINVAL) + return -EINVAL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) fifo_level = dev->txnumevt; else @@ -862,6 +903,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, dma_params->acnt = dma_params->data_type; dma_params->fifo_level = fifo_level; + dma_params->active_serializers = (channels + slots - 1) / slots; davinci_config_channel_size(dev, word_length); return 0; @@ -936,13 +978,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { .name = "davinci-mcasp.0", .playback = { .channels_min = 2, - .channels_max = 2, + .channels_max = 32 * 16, .rates = DAVINCI_MCASP_RATES, .formats = DAVINCI_MCASP_PCM_FMTS, }, .capture = { .channels_min = 2, - .channels_max = 2, + .channels_max = 32 * 16, .rates = DAVINCI_MCASP_RATES, .formats = DAVINCI_MCASP_PCM_FMTS, }, @@ -1015,8 +1057,16 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of( pdata->op_mode = val; ret = of_property_read_u32(np, "tdm-slots", &val); - if (ret >= 0) + if (ret >= 0) { + if (val < 2 || val > 32) { + dev_err(&pdev->dev, + "tdm-slots must be in rage [2-32]\n"); + ret = -EINVAL; + goto nodata; + } + pdata->tdm_slots = val; + } ret = of_property_read_u32(np, "num-serializer", &val); if (ret >= 0) diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index afab81f844ae..078031d61167 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -181,6 +181,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) unsigned short acnt; unsigned int count; unsigned int fifo_level; + unsigned char serializers = prtd->params->active_serializers; period_size = snd_pcm_lib_period_bytes(substream); dma_offset = prtd->period * period_size; @@ -194,14 +195,14 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) data_type = prtd->params->data_type; count = period_size / data_type; if (fifo_level) - count /= fifo_level; + count /= fifo_level * serializers; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { src = dma_pos; dst = prtd->params->dma_addr; src_bidx = data_type; - dst_bidx = 0; - src_cidx = data_type * fifo_level; + dst_bidx = 4; + src_cidx = data_type * fifo_level * serializers; dst_cidx = 0; } else { src = prtd->params->dma_addr; @@ -209,7 +210,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) src_bidx = 0; dst_bidx = data_type; src_cidx = 0; - dst_cidx = data_type * fifo_level; + dst_cidx = data_type * fifo_level * serializers; } acnt = prtd->params->acnt; @@ -223,9 +224,10 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, ASYNC); else - edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, - count, fifo_level, - ABSYNC); + edma_set_transfer_params(prtd->asp_link[0], acnt, + fifo_level * serializers, + count, fifo_level * serializers, + ABSYNC); } static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index b6ef7039dd09..32d7634d7b26 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h @@ -27,6 +27,7 @@ struct davinci_pcm_dma_params { unsigned char data_type; /* xfer data type */ unsigned char convert_mono_stereo; unsigned int fifo_level; + unsigned char active_serializers; /* num. of active audio serializers */ }; int davinci_soc_platform_register(struct device *dev); -- cgit v1.2.3 From c751a1f49b3fbdce0fbbb2c9b56544a7e6833fff Mon Sep 17 00:00:00 2001 From: Dylan Reid Date: Fri, 15 Feb 2013 08:55:10 -0800 Subject: ASoC: max98088: Add TLV data for volume controls. Specify volumes as defined in the MAX98088/9 data sheet. Allows ALSA lib snd_mixer_selem_get_playback_dB_range and related functions to work. Signed-off-by: Dylan Reid Signed-off-by: Mark Brown --- sound/soc/codecs/max98088.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index a4c16fd70f77..3a7b7fd14e3e 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -739,14 +739,32 @@ static const unsigned int max98088_micboost_tlv[] = { 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), }; +static const unsigned int max98088_hp_tlv[] = { + TLV_DB_RANGE_HEAD(5), + 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0), + 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0), + 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0), + 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0), + 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0), +}; + +static const unsigned int max98088_spk_tlv[] = { + TLV_DB_RANGE_HEAD(5), + 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0), + 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0), + 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0), + 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0), + 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0), +}; + static const struct snd_kcontrol_new max98088_snd_controls[] = { - SOC_DOUBLE_R("Headphone Volume", M98088_REG_39_LVL_HP_L, - M98088_REG_3A_LVL_HP_R, 0, 31, 0), - SOC_DOUBLE_R("Speaker Volume", M98088_REG_3D_LVL_SPK_L, - M98088_REG_3E_LVL_SPK_R, 0, 31, 0), - SOC_DOUBLE_R("Receiver Volume", M98088_REG_3B_LVL_REC_L, - M98088_REG_3C_LVL_REC_R, 0, 31, 0), + SOC_DOUBLE_R_TLV("Headphone Volume", M98088_REG_39_LVL_HP_L, + M98088_REG_3A_LVL_HP_R, 0, 31, 0, max98088_hp_tlv), + SOC_DOUBLE_R_TLV("Speaker Volume", M98088_REG_3D_LVL_SPK_L, + M98088_REG_3E_LVL_SPK_R, 0, 31, 0, max98088_spk_tlv), + SOC_DOUBLE_R_TLV("Receiver Volume", M98088_REG_3B_LVL_REC_L, + M98088_REG_3C_LVL_REC_R, 0, 31, 0, max98088_spk_tlv), SOC_DOUBLE_R("Headphone Switch", M98088_REG_39_LVL_HP_L, M98088_REG_3A_LVL_HP_R, 7, 1, 1), -- cgit v1.2.3 From f314cbe84fd81082a286af685c59c2dc4048bc77 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 18 Feb 2013 17:02:10 +0530 Subject: ASoC: max98090: Remove unneeded version.h header include version.h header file inclusion is not required as detected by versioncheck. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index fc176044994d..9ea73aa71198 100755 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -23,8 +23,6 @@ #include #include "max98090.h" -#include - #define DEBUG #define EXTMIC_METHOD #define EXTMIC_METHOD_TEST -- cgit v1.2.3 From a3a6cc84652d82ff795c519c6187d37baa1d9697 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 18 Feb 2013 17:02:11 +0530 Subject: ASoC: max98090: Convert to devm_regmap_init_i2c() devm_regmap_init_i2c() is device managed and makes error handling and code cleanup simpler. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 9ea73aa71198..fef370e03305 100755 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2322,7 +2322,7 @@ static int max98090_i2c_probe(struct i2c_client *i2c, max98090->pdata = i2c->dev.platform_data; max98090->irq = i2c->irq; - max98090->regmap = regmap_init_i2c(i2c, &max98090_regmap); + max98090->regmap = devm_regmap_init_i2c(i2c, &max98090_regmap); if (IS_ERR(max98090->regmap)) { ret = PTR_ERR(max98090->regmap); dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); @@ -2332,18 +2332,13 @@ static int max98090_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98090, max98090_dai, ARRAY_SIZE(max98090_dai)); - if (ret < 0) - regmap_exit(max98090->regmap); - err_enable: return ret; } static int max98090_i2c_remove(struct i2c_client *client) { - struct max98090_priv *max98090 = dev_get_drvdata(&client->dev); snd_soc_unregister_codec(&client->dev); - regmap_exit(max98090->regmap); return 0; } -- cgit v1.2.3 From 3e12af7e139275e5822383e210c86e0ff1ea185c Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 18 Feb 2013 17:02:12 +0530 Subject: ASoC: max98090: Make struct dev_pm_ops const Silences the following checkpatch warning: WARNING: struct dev_pm_ops should normally be const. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index fef370e03305..1cf017f2f587 100755 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2362,7 +2362,7 @@ static int max98090_runtime_suspend(struct device *dev) return 0; } -static struct dev_pm_ops max98090_pm = { +static const struct dev_pm_ops max98090_pm = { SET_RUNTIME_PM_OPS(max98090_runtime_suspend, max98090_runtime_resume, NULL) }; -- cgit v1.2.3 From 4ca74feb6ceb3031e8cf9ef88dedb3ebb984a59a Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 21 Feb 2013 12:24:59 +0530 Subject: ASoC: max98090: Fix checkpatch errors related to spacing Fixes the following type of checkpatch errors: ERROR: "foo * bar" should be "foo *bar" Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 1cf017f2f587..89f83f8e56b2 100755 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -507,16 +507,16 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, return 0; } -static const char * max98090_perf_pwr_text[] = +static const char *max98090_perf_pwr_text[] = { "High Performance", "Low Power" }; -static const char * max98090_pwr_perf_text[] = +static const char *max98090_pwr_perf_text[] = { "Low Power", "High Performance" }; static const struct soc_enum max98090_vcmbandgap_enum = SOC_ENUM_SINGLE(M98090_REG_BIAS_CONTROL, M98090_VCM_MODE_SHIFT, ARRAY_SIZE(max98090_pwr_perf_text), max98090_pwr_perf_text); -static const char * max98090_osr128_text[] = { "64*fs", "128*fs" }; +static const char *max98090_osr128_text[] = { "64*fs", "128*fs" }; static const struct soc_enum max98090_osr128_enum = SOC_ENUM_SINGLE(M98090_REG_ADC_CONTROL, M98090_OSR128_SHIFT, @@ -533,28 +533,28 @@ static const struct soc_enum max98090_filter_dmic34mode_enum = M98090_FLT_DMIC34MODE_SHIFT, ARRAY_SIZE(max98090_mode_text), max98090_mode_text); -static const char * max98090_drcatk_text[] = +static const char *max98090_drcatk_text[] = { "0.5ms", "1ms", "5ms", "10ms", "25ms", "50ms", "100ms", "200ms" }; static const struct soc_enum max98090_drcatk_enum = SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCATK_SHIFT, ARRAY_SIZE(max98090_drcatk_text), max98090_drcatk_text); -static const char * max98090_drcrls_text[] = +static const char *max98090_drcrls_text[] = { "8s", "4s", "2s", "1s", "0.5s", "0.25s", "0.125s", "0.0625s" }; static const struct soc_enum max98090_drcrls_enum = SOC_ENUM_SINGLE(M98090_REG_DRC_TIMING, M98090_DRCRLS_SHIFT, ARRAY_SIZE(max98090_drcrls_text), max98090_drcrls_text); -static const char * max98090_alccmp_text[] = +static const char *max98090_alccmp_text[] = { "1:1", "1:1.5", "1:2", "1:4", "1:INF" }; static const struct soc_enum max98090_alccmp_enum = SOC_ENUM_SINGLE(M98090_REG_DRC_COMPRESSOR, M98090_DRCCMP_SHIFT, ARRAY_SIZE(max98090_alccmp_text), max98090_alccmp_text); -static const char * max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; +static const char *max98090_drcexp_text[] = { "1:1", "2:1", "3:1" }; static const struct soc_enum max98090_drcexp_enum = SOC_ENUM_SINGLE(M98090_REG_DRC_EXPANDER, M98090_DRCEXP_SHIFT, @@ -857,7 +857,7 @@ static const struct soc_enum mic2_mux_enum = static const struct snd_kcontrol_new max98090_mic2_mux = SOC_DAPM_ENUM("MIC2 Mux", mic2_mux_enum); -static const char * max98090_micpre_text[] = { "Off", "On" }; +static const char *max98090_micpre_text[] = { "Off", "On" }; static const struct soc_enum max98090_pa1en_enum = SOC_ENUM_SINGLE(M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT, -- cgit v1.2.3 From 959b6250dbf8398e3c63544f771ff1682a09987e Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 21 Feb 2013 12:25:00 +0530 Subject: ASoC: max98090: Remove unnecessary braces Braces are not required for single line statements. Silences the following checkpatch warnings: WARNING: braces {} are not necessary for single statement blocks. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 89f83f8e56b2..ce0d36412c97 100755 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -1701,9 +1701,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, * seen for the case of TDM mode. The remaining cases have * normal logic. */ - if (max98090->tdm_slots > 1) { + if (max98090->tdm_slots > 1) regval ^= M98090_BCI_MASK; - } snd_soc_write(codec, M98090_REG_INTERFACE_FORMAT, regval); @@ -2057,17 +2056,14 @@ static irqreturn_t max98090_interrupt(int irq, void *data) if (!active) return IRQ_NONE; - if (active & M98090_CLD_MASK) { + if (active & M98090_CLD_MASK) dev_err(codec->dev, "M98090_CLD_MASK\n"); - } - if (active & M98090_SLD_MASK) { + if (active & M98090_SLD_MASK) dev_dbg(codec->dev, "M98090_SLD_MASK\n"); - } - if (active & M98090_ULK_MASK) { + if (active & M98090_ULK_MASK) dev_err(codec->dev, "M98090_ULK_MASK\n"); - } if (active & M98090_JDET_MASK) { dev_dbg(codec->dev, "M98090_JDET_MASK\n"); @@ -2078,13 +2074,11 @@ static irqreturn_t max98090_interrupt(int irq, void *data) msecs_to_jiffies(100)); } - if (active & M98090_DRCACT_MASK) { + if (active & M98090_DRCACT_MASK) dev_dbg(codec->dev, "M98090_DRCACT_MASK\n"); - } - if (active & M98090_DRCCLP_MASK) { + if (active & M98090_DRCCLP_MASK) dev_err(codec->dev, "M98090_DRCCLP_MASK\n"); - } return IRQ_HANDLED; } -- cgit v1.2.3 From ddd17531ad9089ca1a758cd53fb698f396665cb5 Mon Sep 17 00:00:00 2001 From: Sebastien Guiriec Date: Wed, 13 Feb 2013 08:21:54 +0100 Subject: ASoC: omap-mcpdm: Clean up with devm_* function Clean up McPDM driver with devm_ function. Signed-off-by: Sebastien Guiriec Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 5ca11bdac21e..079f277cdba4 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -369,7 +369,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) pm_runtime_get_sync(mcpdm->dev); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); - ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, + ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler, 0, "McPDM", (void *)mcpdm); pm_runtime_put_sync(mcpdm->dev); @@ -389,7 +389,6 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) { struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); - free_irq(mcpdm->irq, (void *)mcpdm); pm_runtime_disable(mcpdm->dev); return 0; @@ -465,14 +464,11 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) if (res == NULL) return -ENOMEM; - if (!devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), "McPDM")) - return -EBUSY; - - mcpdm->io_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!mcpdm->io_base) + mcpdm->io_base = devm_request_and_ioremap(&pdev->dev, res); + if (!mcpdm->io_base) { + dev_err(&pdev->dev, "cannot remap\n"); return -ENOMEM; + } mcpdm->irq = platform_get_irq(pdev, 0); if (mcpdm->irq < 0) -- cgit v1.2.3 From 4f224c612438e0c2067594636c6998ce5048d228 Mon Sep 17 00:00:00 2001 From: Sebastien Guiriec Date: Wed, 13 Feb 2013 08:22:07 +0100 Subject: ASoC: omap-dmic: Clean up with devm_request_and_ioremap Clean up dmic code with devm_request_and_ioremap function. Signed-off-by: Sebastien Guiriec Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index ba49ccd9eed9..77e9e7e68edc 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -493,16 +493,9 @@ static int asoc_dmic_probe(struct platform_device *pdev) goto err_put_clk; } - if (!devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), pdev->name)) { - dev_err(dmic->dev, "memory region already claimed\n"); - ret = -ENODEV; - goto err_put_clk; - } - - dmic->io_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); + dmic->io_base = devm_request_and_ioremap(&pdev->dev, res); if (!dmic->io_base) { + dev_err(&pdev->dev, "cannot remap\n"); ret = -ENOMEM; goto err_put_clk; } -- cgit v1.2.3 From d686500ae87275ed58a074f9e5e8b35b9afe30d8 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 18 Feb 2013 19:59:34 -0800 Subject: ASoC: si476x: Convert SI476X codec to use regmap The latest radio and MFD drivers for SI476X radio chips use regmap API to provide access to the registers and allow for caching of their values when the actual chip is powered off. Convert the codec driver to do the same, so it would not loose the settings when the radio driver powers the chip down. Signed-off-by: Andrey Smirnov Signed-off-by: Mark Brown --- sound/soc/codecs/si476x.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index f2d61a187830..30aebbe6815e 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -45,13 +45,23 @@ static unsigned int si476x_codec_read(struct snd_soc_codec *codec, unsigned int reg) { int err; + unsigned int val; struct si476x_core *core = codec->control_data; si476x_core_lock(core); - err = si476x_core_cmd_get_property(core, reg); + if (!si476x_core_is_powered_up(core)) + regcache_cache_only(core->regmap, true); + + err = regmap_read(core->regmap, reg, &val); + + if (!si476x_core_is_powered_up(core)) + regcache_cache_only(core->regmap, false); si476x_core_unlock(core); - return err; + if (err < 0) + return err; + + return val; } static int si476x_codec_write(struct snd_soc_codec *codec, @@ -61,7 +71,13 @@ static int si476x_codec_write(struct snd_soc_codec *codec, struct si476x_core *core = codec->control_data; si476x_core_lock(core); - err = si476x_core_cmd_set_property(core, reg, val); + if (!si476x_core_is_powered_up(core)) + regcache_cache_only(core->regmap, true); + + err = regmap_write(core->regmap, reg, val); + + if (!si476x_core_is_powered_up(core)) + regcache_cache_only(core->regmap, false); si476x_core_unlock(core); return err; -- cgit v1.2.3 From 06d7c13325228a2272e21caa4aa60805bc4d0fe4 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 18 Feb 2013 19:59:35 -0800 Subject: ASoC: si476x: Cosmetic changes to SI476X codec driver - Add appropriate license header - Change email address in MODULE_AUTHOR - Remove trailing whitespaces Signed-off-by: Andrey Smirnov Signed-off-by: Mark Brown --- sound/soc/codecs/si476x.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 30aebbe6815e..68b648aabdb9 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -1,3 +1,22 @@ +/* + * sound/soc/codecs/si476x.c -- Codec driver for SI476X chips + * + * Copyright (C) 2012 Innovative Converged Devices(ICD) + * Copyright (C) 2013 Andrey Smirnov + * + * Author: Andrey Smirnov + * + * 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; version 2 of the License. + * + * 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. + * + */ + #include #include #include @@ -156,7 +175,7 @@ static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, dev_err(codec_dai->codec->dev, "Failed to set output format\n"); return err; } - + return 0; } @@ -197,7 +216,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream, err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK, - (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | + (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)); if (err < 0) { dev_err(dai->codec->dev, "Failed to set output width\n"); @@ -266,6 +285,6 @@ static struct platform_driver si476x_platform_driver = { }; module_platform_driver(si476x_platform_driver); -MODULE_AUTHOR("Andrey Smirnov "); +MODULE_AUTHOR("Andrey Smirnov "); MODULE_DESCRIPTION("ASoC Si4761/64 codec driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 69de6be70e611c8165b9b5c16d69574d13f2a3b0 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 15 Feb 2013 17:07:30 -0700 Subject: ASoC: tegra: assume CONFIG_OF in tegra_asoc_utils_init Tegra only supports, and always enables, device tree. Remove all runtime checks for DT support from the driver. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_asoc_utils.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index ba419f86384d..49861c6ed874 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -176,11 +176,7 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; else if (of_machine_is_compatible("nvidia,tegra30")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; - else if (!dev->of_node) - /* non-DT is always Tegra20 */ - data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; else - /* DT boot, but unknown SoC */ return -EINVAL; data->clk_pll_a = clk_get_sys(NULL, "pll_a"); -- cgit v1.2.3 From bddd7d0230deb3fbc2cb32e0af04f7cf46397e9e Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 15 Feb 2013 17:07:31 -0700 Subject: ASoC: tegra_wm8753: minor cleanup Various minor cleanups so that the probe() body more closely resembles other drivers, for easier comparison. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm8753.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index c8ef88a67c59..f87fc53e9b8c 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -124,6 +124,7 @@ static struct snd_soc_card snd_soc_tegra_wm8753 = { static int tegra_wm8753_driver_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct snd_soc_card *card = &snd_soc_tegra_wm8753; struct tegra_wm8753 *machine; int ret; @@ -132,8 +133,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) GFP_KERNEL); if (!machine) { dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n"); - ret = -ENOMEM; - goto err; + return -ENOMEM; } card->dev = &pdev->dev; @@ -148,8 +148,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) if (ret) goto err; - tegra_wm8753_dai.codec_of_node = of_parse_phandle( - pdev->dev.of_node, "nvidia,audio-codec", 0); + tegra_wm8753_dai.codec_of_node = of_parse_phandle(np, + "nvidia,audio-codec", 0); if (!tegra_wm8753_dai.codec_of_node) { dev_err(&pdev->dev, "Property 'nvidia,audio-codec' missing or invalid\n"); @@ -157,8 +157,8 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) goto err; } - tegra_wm8753_dai.cpu_of_node = of_parse_phandle( - pdev->dev.of_node, "nvidia,i2s-controller", 0); + tegra_wm8753_dai.cpu_of_node = of_parse_phandle(np, + "nvidia,i2s-controller", 0); if (!tegra_wm8753_dai.cpu_of_node) { dev_err(&pdev->dev, "Property 'nvidia,i2s-controller' missing or invalid\n"); @@ -166,8 +166,7 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) goto err; } - tegra_wm8753_dai.platform_of_node = - tegra_wm8753_dai.cpu_of_node; + tegra_wm8753_dai.platform_of_node = tegra_wm8753_dai.cpu_of_node; ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); if (ret) -- cgit v1.2.3 From 078e027386b2fdeb154393eb87a5b325d0937ed9 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 15 Feb 2013 17:07:32 -0700 Subject: ASoC: tegra_wm9712: assume CONFIG_OF Tegra only supports, and always enables, device tree. Remove all runtime checks for DT support from the driver. Signed-off-by: Stephen Warren Acked-by: Lucas Stach Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_wm9712.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index 68d42403d9b5..ce98e5b28360 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c @@ -79,11 +79,6 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev) struct tegra_wm9712 *machine; int ret; - if (!pdev->dev.of_node) { - dev_err(&pdev->dev, "No platform data supplied\n"); - return -EINVAL; - } - machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712), GFP_KERNEL); if (!machine) { -- cgit v1.2.3 From f726536fc08db7a209e35b011883bbaee8e93db7 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 15 Feb 2013 17:07:33 -0700 Subject: ASoC: tegra_alc5632: assume CONFIG_OF, and other cleanup Tegra only supports, and always enables, device tree. Remove all runtime checks for DT support from the driver. Also, various minor cleanups so that the probe() body more closely resembles other drivers, for easier comparison. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_alc5632.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index c80adb9da472..48d05d9e1002 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -161,20 +161,13 @@ static int tegra_alc5632_probe(struct platform_device *pdev) sizeof(struct tegra_alc5632), GFP_KERNEL); if (!alc5632) { dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); - ret = -ENOMEM; - goto err; + return -ENOMEM; } card->dev = &pdev->dev; platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, alc5632); - if (!(pdev->dev.of_node)) { - dev_err(&pdev->dev, "Must be instantiated using device tree\n"); - ret = -EINVAL; - goto err; - } - alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); if (alc5632->gpio_hp_det == -EPROBE_DEFER) return -EPROBE_DEFER; @@ -197,11 +190,11 @@ static int tegra_alc5632_probe(struct platform_device *pdev) goto err; } - tegra_alc5632_dai.cpu_of_node = of_parse_phandle( - pdev->dev.of_node, "nvidia,i2s-controller", 0); + tegra_alc5632_dai.cpu_of_node = of_parse_phandle(np, + "nvidia,i2s-controller", 0); if (!tegra_alc5632_dai.cpu_of_node) { dev_err(&pdev->dev, - "Property 'nvidia,i2s-controller' missing or invalid\n"); + "Property 'nvidia,i2s-controller' missing or invalid\n"); ret = -EINVAL; goto err; } -- cgit v1.2.3 From bd85a06c2b81d9947426d48125ee7a96a6c67e3c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 15 Feb 2013 17:07:34 -0700 Subject: ASoC: tegra trimslice: assume CONFIG_OF, and other cleanup Tegra only supports, and always enables, device tree. Remove all runtime checks for DT support from the driver. Also, some minor changes so that the probe() body more closely resembles other drivers, for easier comparison. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/trimslice.c | 56 +++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 32 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index 7fcf6c2297db..05c68aab5cf0 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -97,9 +97,6 @@ static const struct snd_soc_dapm_route trimslice_audio_map[] = { static struct snd_soc_dai_link trimslice_tlv320aic23_dai = { .name = "TLV320AIC23", .stream_name = "AIC23", - .codec_name = "tlv320aic23-codec.2-001a", - .platform_name = "tegra20-i2s.0", - .cpu_dai_name = "tegra20-i2s.0", .codec_dai_name = "tlv320aic23-hifi", .ops = &trimslice_asoc_ops, .dai_fmt = SND_SOC_DAIFMT_I2S | @@ -122,6 +119,7 @@ static struct snd_soc_card snd_soc_trimslice = { static int tegra_snd_trimslice_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct snd_soc_card *card = &snd_soc_trimslice; struct tegra_trimslice *trimslice; int ret; @@ -130,44 +128,38 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev) GFP_KERNEL); if (!trimslice) { dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n"); - ret = -ENOMEM; + return -ENOMEM; + } + + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, trimslice); + + trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle(np, + "nvidia,audio-codec", 0); + if (!trimslice_tlv320aic23_dai.codec_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,audio-codec' missing or invalid\n"); + ret = -EINVAL; goto err; } - if (pdev->dev.of_node) { - trimslice_tlv320aic23_dai.codec_name = NULL; - trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle( - pdev->dev.of_node, "nvidia,audio-codec", 0); - if (!trimslice_tlv320aic23_dai.codec_of_node) { - dev_err(&pdev->dev, - "Property 'nvidia,audio-codec' missing or invalid\n"); - ret = -EINVAL; - goto err; - } - - trimslice_tlv320aic23_dai.cpu_dai_name = NULL; - trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle( - pdev->dev.of_node, "nvidia,i2s-controller", 0); - if (!trimslice_tlv320aic23_dai.cpu_of_node) { - dev_err(&pdev->dev, - "Property 'nvidia,i2s-controller' missing or invalid\n"); - ret = -EINVAL; - goto err; - } - - trimslice_tlv320aic23_dai.platform_name = NULL; - trimslice_tlv320aic23_dai.platform_of_node = - trimslice_tlv320aic23_dai.cpu_of_node; + trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle(np, + "nvidia,i2s-controller", 0); + if (!trimslice_tlv320aic23_dai.cpu_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,i2s-controller' missing or invalid\n"); + ret = -EINVAL; + goto err; } + trimslice_tlv320aic23_dai.platform_of_node = + trimslice_tlv320aic23_dai.cpu_of_node; + ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); if (ret) goto err; - card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); - snd_soc_card_set_drvdata(card, trimslice); - ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", -- cgit v1.2.3 From 8f5f5e0f459d37273f841e3f8da38b4e242c8e94 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 15 Feb 2013 17:07:35 -0700 Subject: ASoC: tegra_wm8903: assume CONFIG_OF, remove platform data Tegra only supports, and always enables, device tree. Remove all runtime checks for DT support from the driver. This allows removal of the hard-coded Harmony ASoC mapping table, since Harmony only boots with DT now. All board-specific configuration now comes from device tree, so there is no need to have a platform_data structure. Rework the driver to parse the device tree directly into struct tegra_wm8903. Also some slight re-ordering of probe() so that the code more closely resembles other drivers for easier comparison. Inparticular, the GPIO DT parsing and initial programming are moved together for each GPIO. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- include/sound/tegra_wm8903.h | 26 ------ sound/soc/tegra/tegra_wm8903.c | 179 ++++++++++++++++------------------------- 2 files changed, 70 insertions(+), 135 deletions(-) delete mode 100644 include/sound/tegra_wm8903.h (limited to 'sound/soc') diff --git a/include/sound/tegra_wm8903.h b/include/sound/tegra_wm8903.h deleted file mode 100644 index 57b202ee97c3..000000000000 --- a/include/sound/tegra_wm8903.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2011 NVIDIA, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#ifndef __SOUND_TEGRA_WM38903_H -#define __SOUND_TEGRA_WM38903_H - -struct tegra_wm8903_platform_data { - int gpio_spkr_en; - int gpio_hp_det; - int gpio_hp_mute; - int gpio_int_mic_en; - int gpio_ext_mic_en; -}; - -#endif diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index bbd79bf56303..4ac73730d79a 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -39,7 +39,6 @@ #include #include #include -#include #include "../codecs/wm8903.h" @@ -48,7 +47,11 @@ #define DRV_NAME "tegra-snd-wm8903" struct tegra_wm8903 { - struct tegra_wm8903_platform_data pdata; + int gpio_spkr_en; + int gpio_hp_det; + int gpio_hp_mute; + int gpio_int_mic_en; + int gpio_ext_mic_en; struct tegra_asoc_utils_data util_data; }; @@ -129,12 +132,11 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w, struct snd_soc_dapm_context *dapm = w->dapm; struct snd_soc_card *card = dapm->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = &machine->pdata; - if (!gpio_is_valid(pdata->gpio_spkr_en)) + if (!gpio_is_valid(machine->gpio_spkr_en)) return 0; - gpio_set_value_cansleep(pdata->gpio_spkr_en, + gpio_set_value_cansleep(machine->gpio_spkr_en, SND_SOC_DAPM_EVENT_ON(event)); return 0; @@ -146,12 +148,11 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w, struct snd_soc_dapm_context *dapm = w->dapm; struct snd_soc_card *card = dapm->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = &machine->pdata; - if (!gpio_is_valid(pdata->gpio_hp_mute)) + if (!gpio_is_valid(machine->gpio_hp_mute)) return 0; - gpio_set_value_cansleep(pdata->gpio_hp_mute, + gpio_set_value_cansleep(machine->gpio_hp_mute, !SND_SOC_DAPM_EVENT_ON(event)); return 0; @@ -163,17 +164,6 @@ static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = { SND_SOC_DAPM_MIC("Mic Jack", NULL), }; -static const struct snd_soc_dapm_route harmony_audio_map[] = { - {"Headphone Jack", NULL, "HPOUTR"}, - {"Headphone Jack", NULL, "HPOUTL"}, - {"Int Spk", NULL, "ROP"}, - {"Int Spk", NULL, "RON"}, - {"Int Spk", NULL, "LOP"}, - {"Int Spk", NULL, "LON"}, - {"Mic Jack", NULL, "MICBIAS"}, - {"IN1L", NULL, "Mic Jack"}, -}; - static const struct snd_kcontrol_new tegra_wm8903_controls[] = { SOC_DAPM_PIN_SWITCH("Int Spk"), }; @@ -185,10 +175,9 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = &machine->pdata; - if (gpio_is_valid(pdata->gpio_hp_det)) { - tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; + if (gpio_is_valid(machine->gpio_hp_det)) { + tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det; snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &tegra_wm8903_hp_jack); snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, @@ -226,9 +215,6 @@ static int tegra_wm8903_remove(struct snd_soc_card *card) static struct snd_soc_dai_link tegra_wm8903_dai = { .name = "WM8903", .stream_name = "WM8903 PCM", - .codec_name = "wm8903.0-001a", - .platform_name = "tegra20-i2s.0", - .cpu_dai_name = "tegra20-i2s.0", .codec_dai_name = "wm8903-hifi", .init = tegra_wm8903_init, .ops = &tegra_wm8903_ops, @@ -257,96 +243,25 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct snd_soc_card *card = &snd_soc_tegra_wm8903; struct tegra_wm8903 *machine; - struct tegra_wm8903_platform_data *pdata; int ret; - if (!pdev->dev.platform_data && !pdev->dev.of_node) { - dev_err(&pdev->dev, "No platform data supplied\n"); - return -EINVAL; - } - machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903), GFP_KERNEL); if (!machine) { dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n"); - ret = -ENOMEM; - goto err; + return -ENOMEM; } - pdata = &machine->pdata; card->dev = &pdev->dev; platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); - if (pdev->dev.platform_data) { - memcpy(pdata, card->dev->platform_data, sizeof(*pdata)); - } else if (np) { - pdata->gpio_spkr_en = of_get_named_gpio(np, - "nvidia,spkr-en-gpios", 0); - if (pdata->gpio_spkr_en == -EPROBE_DEFER) - return -EPROBE_DEFER; - - pdata->gpio_hp_mute = of_get_named_gpio(np, - "nvidia,hp-mute-gpios", 0); - if (pdata->gpio_hp_mute == -EPROBE_DEFER) - return -EPROBE_DEFER; - - pdata->gpio_hp_det = of_get_named_gpio(np, - "nvidia,hp-det-gpios", 0); - if (pdata->gpio_hp_det == -EPROBE_DEFER) - return -EPROBE_DEFER; - - pdata->gpio_int_mic_en = of_get_named_gpio(np, - "nvidia,int-mic-en-gpios", 0); - if (pdata->gpio_int_mic_en == -EPROBE_DEFER) - return -EPROBE_DEFER; - - pdata->gpio_ext_mic_en = of_get_named_gpio(np, - "nvidia,ext-mic-en-gpios", 0); - if (pdata->gpio_ext_mic_en == -EPROBE_DEFER) - return -EPROBE_DEFER; - } - - if (np) { - ret = snd_soc_of_parse_card_name(card, "nvidia,model"); - if (ret) - goto err; - - ret = snd_soc_of_parse_audio_routing(card, - "nvidia,audio-routing"); - if (ret) - goto err; - - tegra_wm8903_dai.codec_name = NULL; - tegra_wm8903_dai.codec_of_node = of_parse_phandle(np, - "nvidia,audio-codec", 0); - if (!tegra_wm8903_dai.codec_of_node) { - dev_err(&pdev->dev, - "Property 'nvidia,audio-codec' missing or invalid\n"); - ret = -EINVAL; - goto err; - } - - tegra_wm8903_dai.cpu_dai_name = NULL; - tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np, - "nvidia,i2s-controller", 0); - if (!tegra_wm8903_dai.cpu_of_node) { - dev_err(&pdev->dev, - "Property 'nvidia,i2s-controller' missing or invalid\n"); - ret = -EINVAL; - goto err; - } - - tegra_wm8903_dai.platform_name = NULL; - tegra_wm8903_dai.platform_of_node = - tegra_wm8903_dai.cpu_of_node; - } else { - card->dapm_routes = harmony_audio_map; - card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); - } - - if (gpio_is_valid(pdata->gpio_spkr_en)) { - ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en, + machine->gpio_spkr_en = of_get_named_gpio(np, "nvidia,spkr-en-gpios", + 0); + if (machine->gpio_spkr_en == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (gpio_is_valid(machine->gpio_spkr_en)) { + ret = devm_gpio_request_one(&pdev->dev, machine->gpio_spkr_en, GPIOF_OUT_INIT_LOW, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); @@ -354,8 +269,12 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) } } - if (gpio_is_valid(pdata->gpio_hp_mute)) { - ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute, + machine->gpio_hp_mute = of_get_named_gpio(np, "nvidia,hp-mute-gpios", + 0); + if (machine->gpio_hp_mute == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (gpio_is_valid(machine->gpio_hp_mute)) { + ret = devm_gpio_request_one(&pdev->dev, machine->gpio_hp_mute, GPIOF_OUT_INIT_HIGH, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); @@ -363,9 +282,18 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) } } - if (gpio_is_valid(pdata->gpio_int_mic_en)) { + machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); + if (machine->gpio_hp_det == -EPROBE_DEFER) + return -EPROBE_DEFER; + + machine->gpio_int_mic_en = of_get_named_gpio(np, + "nvidia,int-mic-en-gpios", 0); + if (machine->gpio_int_mic_en == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (gpio_is_valid(machine->gpio_int_mic_en)) { /* Disable int mic; enable signal is active-high */ - ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en, + ret = devm_gpio_request_one(&pdev->dev, + machine->gpio_int_mic_en, GPIOF_OUT_INIT_LOW, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); @@ -373,9 +301,14 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) } } - if (gpio_is_valid(pdata->gpio_ext_mic_en)) { + machine->gpio_ext_mic_en = of_get_named_gpio(np, + "nvidia,ext-mic-en-gpios", 0); + if (machine->gpio_ext_mic_en == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (gpio_is_valid(machine->gpio_ext_mic_en)) { /* Enable ext mic; enable signal is active-low */ - ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en, + ret = devm_gpio_request_one(&pdev->dev, + machine->gpio_ext_mic_en, GPIOF_OUT_INIT_LOW, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); @@ -383,6 +316,34 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) } } + ret = snd_soc_of_parse_card_name(card, "nvidia,model"); + if (ret) + goto err; + + ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); + if (ret) + goto err; + + tegra_wm8903_dai.codec_of_node = of_parse_phandle(np, + "nvidia,audio-codec", 0); + if (!tegra_wm8903_dai.codec_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,audio-codec' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np, + "nvidia,i2s-controller", 0); + if (!tegra_wm8903_dai.cpu_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,i2s-controller' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + tegra_wm8903_dai.platform_of_node = tegra_wm8903_dai.cpu_of_node; + ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); if (ret) goto err; -- cgit v1.2.3 From 21eb2693dd3bb701f831588977f92c4b63eeb132 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 26 Feb 2013 23:36:37 +0000 Subject: ASoC: wm8960: Add input boost volume control Signed-off-by: Mark Brown --- sound/soc/codecs/wm8960.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 9bb927325993..3fea242cbf1a 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -204,6 +204,7 @@ static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0); static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); +static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1); static const struct snd_kcontrol_new wm8960_snd_controls[] = { SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, @@ -213,6 +214,15 @@ SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL, SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL, 7, 1, 0), +SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT3 Volume", + WM8960_INBMIX1, 4, 7, 0, boost_tlv), +SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT2 Volume", + WM8960_INBMIX1, 1, 7, 0, boost_tlv), +SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT3 Volume", + WM8960_INBMIX2, 4, 7, 0, boost_tlv), +SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT2 Volume", + WM8960_INBMIX2, 1, 7, 0, boost_tlv), + SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC, 0, 255, 0, dac_tlv), -- cgit v1.2.3 From dd194b48465ba9c4eef7f16a4815b7761a8172ce Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 2 Mar 2013 15:47:55 +0800 Subject: ASoC: omap: Check regulator enable for DAC on Pandora This will probably never fail but it's better style. Signed-off-by: Mark Brown Acked-by: Peter Ujfalusi Acked-by: Jarkko Nikula --- sound/soc/omap/omap3pandora.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 805512f2555a..10ced9d2e0de 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -80,12 +80,18 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream, static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { + int ret; + /* * The PCM1773 DAC datasheet requires 1ms delay between switching * VCC power on/off and /PD pin high/low */ if (SND_SOC_DAPM_EVENT_ON(event)) { - regulator_enable(omap3pandora_dac_reg); + ret = regulator_enable(omap3pandora_dac_reg); + if (ret) { + dev_err(w->dapm.dev, "Failed to power DAC: %d\n", ret); + return ret; + } mdelay(1); gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); } else { -- cgit v1.2.3 From ff680a173506e0f5f15c1d9c70251e7e3208c761 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 4 Mar 2013 16:00:19 +0800 Subject: ASoC: arizona: If we only have a clock to synchronise with make it REFCLK If there is only one clock active the FLL should use REFCLK rather than SYNCCLK as the clock to synchronise with since REFCLK is always required. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 76 +++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index e456cb4b196e..0599ff8ea935 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1132,14 +1132,30 @@ static void arizona_enable_fll(struct arizona_fll *fll, struct arizona *arizona = fll->arizona; int ret; - regmap_update_bits(arizona->regmap, fll->base + 5, - ARIZONA_FLL1_OUTDIV_MASK, - ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); - - arizona_apply_fll(arizona, fll->base, ref, fll->ref_src); - if (fll->sync_src >= 0) - arizona_apply_fll(arizona, fll->base + 0x10, sync, + /* + * If we have both REFCLK and SYNCCLK then enable both, + * otherwise apply the SYNCCLK settings to REFCLK. + */ + if (fll->ref_src >= 0 && fll->ref_src != fll->sync_src) { + regmap_update_bits(arizona->regmap, fll->base + 5, + ARIZONA_FLL1_OUTDIV_MASK, + ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); + + arizona_apply_fll(arizona, fll->base, ref, fll->ref_src); + if (fll->sync_src >= 0) + arizona_apply_fll(arizona, fll->base + 0x10, sync, + fll->sync_src); + } else if (fll->sync_src >= 0) { + regmap_update_bits(arizona->regmap, fll->base + 5, + ARIZONA_FLL1_OUTDIV_MASK, + sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); + + arizona_apply_fll(arizona, fll->base, sync, fll->sync_src); + } else { + arizona_fll_err(fll, "No clocks provided\n"); + return; + } if (!arizona_is_enabled_fll(fll)) pm_runtime_get(arizona->dev); @@ -1149,7 +1165,8 @@ static void arizona_enable_fll(struct arizona_fll *fll, regmap_update_bits(arizona->regmap, fll->base + 1, ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA); - if (fll->sync_src >= 0) + if (fll->ref_src >= 0 && fll->sync_src >= 0 && + fll->ref_src != fll->sync_src) regmap_update_bits(arizona->regmap, fll->base + 0x11, ARIZONA_FLL1_SYNC_ENA, ARIZONA_FLL1_SYNC_ENA); @@ -1180,9 +1197,6 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source, struct arizona_fll_cfg ref, sync; int ret; - if (source < 0) - return -EINVAL; - if (fll->ref_src == source && fll->ref_freq == Fref) return 0; @@ -1216,39 +1230,25 @@ int arizona_set_fll(struct arizona_fll *fll, int source, struct arizona_fll_cfg ref, sync; int ret; - if (fll->ref_src < 0 || fll->ref_src == source) { - if (fll->sync_src == ARIZONA_FLL_SRC_NONE && - fll->ref_src == source && fll->ref_freq == Fref && - fll->fout == Fout) - return 0; - - if (Fout) { - ret = arizona_calc_fll(fll, &ref, Fref, Fout); - if (ret != 0) - return ret; - } - - fll->sync_src = ARIZONA_FLL_SRC_NONE; - fll->ref_src = source; - fll->ref_freq = Fref; - } else { - if (fll->sync_src == source && - fll->sync_freq == Fref && fll->fout == Fout) - return 0; - - if (Fout) { - ret = arizona_calc_fll(fll, &ref, fll->ref_freq, Fout); - if (ret != 0) - return ret; + if (fll->sync_src == source && + fll->sync_freq == Fref && fll->fout == Fout) + return 0; - ret = arizona_calc_fll(fll, &sync, Fref, Fout); + if (Fout) { + if (fll->ref_src >= 0) { + ret = arizona_calc_fll(fll, &ref, fll->ref_freq, + Fout); if (ret != 0) return ret; } - fll->sync_src = source; - fll->sync_freq = Fref; + ret = arizona_calc_fll(fll, &sync, Fref, Fout); + if (ret != 0) + return ret; } + + fll->sync_src = source; + fll->sync_freq = Fref; fll->fout = Fout; if (Fout) { -- cgit v1.2.3 From e37e04307c2921ee83b192cbeb65d21897d0c6e8 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 5 Mar 2013 15:24:16 +0100 Subject: ASoC: omap3pandora: Fix compilation error Fixes: sound/soc/omap/omap3pandora.c: In function ‘omap3pandora_dac_event’: sound/soc/omap/omap3pandora.c:92:19: error: request for member ‘dev’ in something not a structure or union make[3]: *** [sound/soc/omap/omap3pandora.o] Error 1 Which is introduced by: dd194b4 ASoC: omap: Check regulator enable for DAC on Pandora Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap3pandora.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 10ced9d2e0de..9e46e1d8cb1b 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -89,7 +89,7 @@ static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w, if (SND_SOC_DAPM_EVENT_ON(event)) { ret = regulator_enable(omap3pandora_dac_reg); if (ret) { - dev_err(w->dapm.dev, "Failed to power DAC: %d\n", ret); + dev_err(w->dapm->dev, "Failed to power DAC: %d\n", ret); return ret; } mdelay(1); -- cgit v1.2.3 From cadf2120ff756789a3adaac07c5b85a09649c66e Mon Sep 17 00:00:00 2001 From: Paul Handrigan Date: Tue, 5 Mar 2013 13:12:56 -0600 Subject: ASoC: cs42l73: If Internal MCLK is >= 6.4MHz, then set SCLK to 64*Fs. Signed-off-by: Paul Handrigan Acked-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l73.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 6361dab48bd1..3b20c86cdb01 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1180,7 +1180,11 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, priv->config[id].mmcc &= 0xC0; priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; priv->config[id].spc &= 0xFC; - priv->config[id].spc |= MCK_SCLK_MCLK; + /* Use SCLK=64*Fs if internal MCLK >= 6.4MHz */ + if (priv->mclk >= 6400000) + priv->config[id].spc |= MCK_SCLK_64FS; + else + priv->config[id].spc |= MCK_SCLK_MCLK; } else { /* CS42L73 Slave */ priv->config[id].spc &= 0xFC; -- cgit v1.2.3 From 576411be200ee0e0801f1fe57d5e7ee787bb1a90 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Mar 2013 12:07:16 +0800 Subject: ASoC: arizona: Increase FLL synchroniser bandwidth for high frequencies If we are using a high freqency SYNCCLK then increasing the bandwidth of the synchroniser improves performance. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 0599ff8ea935..e3aee143487e 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1157,6 +1157,17 @@ static void arizona_enable_fll(struct arizona_fll *fll, return; } + /* + * Increase the bandwidth if we're not using a low frequency + * sync source. + */ + if (fll->sync_src >= 0 && fll->sync_freq > 100000) + regmap_update_bits(arizona->regmap, fll->base + 0x17, + ARIZONA_FLL1_SYNC_BW, 0); + else + regmap_update_bits(arizona->regmap, fll->base + 0x17, + ARIZONA_FLL1_SYNC_BW, ARIZONA_FLL1_SYNC_BW); + if (!arizona_is_enabled_fll(fll)) pm_runtime_get(arizona->dev); -- cgit v1.2.3 From 8f113d7d2606003e485c4e8452977750d916dbc6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Mar 2013 12:08:57 +0800 Subject: ASoC: arizona: Optimise FLL loop gains For optimal performance the FLL loop gain should be adjusted depending on the frequency of the input clock for the loop. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index e3aee143487e..8b7855df99de 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -990,6 +990,16 @@ static struct { { 1000000, 13500000, 0, 1 }, }; +static struct { + unsigned int min; + unsigned int max; + u16 gain; +} fll_gains[] = { + { 0, 256000, 0 }, + { 256000, 1000000, 2 }, + { 1000000, 13500000, 4 }, +}; + struct arizona_fll_cfg { int n; int theta; @@ -997,6 +1007,7 @@ struct arizona_fll_cfg { int refdiv; int outdiv; int fratio; + int gain; }; static int arizona_calc_fll(struct arizona_fll *fll, @@ -1056,6 +1067,18 @@ static int arizona_calc_fll(struct arizona_fll *fll, return -EINVAL; } + for (i = 0; i < ARRAY_SIZE(fll_gains); i++) { + if (fll_gains[i].min <= Fref && Fref <= fll_gains[i].max) { + cfg->gain = fll_gains[i].gain; + break; + } + } + if (i == ARRAY_SIZE(fll_gains)) { + arizona_fll_err(fll, "Unable to find gain for Fref=%uHz\n", + Fref); + return -EINVAL; + } + cfg->n = target / (ratio * Fref); if (target % (ratio * Fref)) { @@ -1083,13 +1106,15 @@ static int arizona_calc_fll(struct arizona_fll *fll, cfg->n, cfg->theta, cfg->lambda); arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n", cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv); + arizona_fll_dbg(fll, "GAIN=%d\n", cfg->gain); return 0; } static void arizona_apply_fll(struct arizona *arizona, unsigned int base, - struct arizona_fll_cfg *cfg, int source) + struct arizona_fll_cfg *cfg, int source, + bool sync) { regmap_update_bits(arizona->regmap, base + 3, ARIZONA_FLL1_THETA_MASK, cfg->theta); @@ -1104,6 +1129,15 @@ static void arizona_apply_fll(struct arizona *arizona, unsigned int base, cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT | source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT); + if (sync) + regmap_update_bits(arizona->regmap, base + 0x7, + ARIZONA_FLL1_GAIN_MASK, + cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); + else + regmap_update_bits(arizona->regmap, base + 0x9, + ARIZONA_FLL1_GAIN_MASK, + cfg->gain << ARIZONA_FLL1_GAIN_SHIFT); + regmap_update_bits(arizona->regmap, base + 2, ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK, ARIZONA_FLL1_CTRL_UPD | cfg->n); @@ -1141,17 +1175,18 @@ static void arizona_enable_fll(struct arizona_fll *fll, ARIZONA_FLL1_OUTDIV_MASK, ref->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); - arizona_apply_fll(arizona, fll->base, ref, fll->ref_src); + arizona_apply_fll(arizona, fll->base, ref, fll->ref_src, + false); if (fll->sync_src >= 0) arizona_apply_fll(arizona, fll->base + 0x10, sync, - fll->sync_src); + fll->sync_src, true); } else if (fll->sync_src >= 0) { regmap_update_bits(arizona->regmap, fll->base + 5, ARIZONA_FLL1_OUTDIV_MASK, sync->outdiv << ARIZONA_FLL1_OUTDIV_SHIFT); arizona_apply_fll(arizona, fll->base, sync, - fll->sync_src); + fll->sync_src, false); } else { arizona_fll_err(fll, "No clocks provided\n"); return; -- cgit v1.2.3 From b0ec761b99291f3c0f28ac370f94c145ec806095 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 6 Mar 2013 22:22:15 +0100 Subject: ASoC: ak4104: convert to direct regmap API usage Signed-off-by: Daniel Mack Signed-off-by: Mark Brown --- sound/soc/codecs/ak4104.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 6f6c335a5baa..58f390d3ea7a 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -55,6 +55,7 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { struct snd_soc_codec *codec = codec_dai->codec; + struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); int val = 0; int ret; @@ -77,9 +78,9 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) return -EINVAL; - ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, - AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1, - val); + ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, + AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1, + val); if (ret < 0) return ret; @@ -91,11 +92,12 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; + struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); int val = 0; /* set the IEC958 bits: consumer mode, no copyright bit */ val |= IEC958_AES0_CON_NOT_COPYRIGHT; - snd_soc_write(codec, AK4104_REG_CHN_STATUS(0), val); + regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(0), val); val = 0; @@ -132,7 +134,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - return snd_soc_write(codec, AK4104_REG_CHN_STATUS(3), val); + return regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(3), val); } static const struct snd_soc_dai_ops ak4101_dai_ops = { @@ -160,20 +162,17 @@ static int ak4104_probe(struct snd_soc_codec *codec) int ret; codec->control_data = ak4104->regmap; - ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); - if (ret != 0) - return ret; /* set power-up and non-reset bits */ - ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, - AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, - AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); + ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, + AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, + AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); if (ret < 0) return ret; /* enable transmitter */ - ret = snd_soc_update_bits(codec, AK4104_REG_TX, - AK4104_TX_TXE, AK4104_TX_TXE); + ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX, + AK4104_TX_TXE, AK4104_TX_TXE); if (ret < 0) return ret; @@ -182,8 +181,10 @@ static int ak4104_probe(struct snd_soc_codec *codec) static int ak4104_remove(struct snd_soc_codec *codec) { - snd_soc_update_bits(codec, AK4104_REG_CONTROL1, - AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0); + struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); + + regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, + AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0); return 0; } -- cgit v1.2.3 From b692a436e1dc7227f2b7cf447797c3dc6ece5c29 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 6 Mar 2013 22:22:16 +0100 Subject: ASoC: ak4104: correct tranceiver enable handling Move the enabling of the TX diode to hw_params() and disable it again in hw_free(). This way, the diode is only switched on as long as it needs to be. Signed-off-by: Daniel Mack Signed-off-by: Mark Brown --- sound/soc/codecs/ak4104.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 58f390d3ea7a..c7cfdf957e4d 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -93,7 +93,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_codec *codec = dai->codec; struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); - int val = 0; + int ret, val = 0; /* set the IEC958 bits: consumer mode, no copyright bit */ val |= IEC958_AES0_CON_NOT_COPYRIGHT; @@ -134,11 +134,33 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - return regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(3), val); + ret = regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(3), val); + if (ret < 0) + return ret; + + /* enable transmitter */ + ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX, + AK4104_TX_TXE, AK4104_TX_TXE); + if (ret < 0) + return ret; + + return 0; +} + +static int ak4104_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); + + /* disable transmitter */ + return regmap_update_bits(ak4104->regmap, AK4104_REG_TX, + AK4104_TX_TXE, 0); } static const struct snd_soc_dai_ops ak4101_dai_ops = { .hw_params = ak4104_hw_params, + .hw_free = ak4104_hw_free, .set_fmt = ak4104_set_dai_fmt, }; -- cgit v1.2.3 From eca2e8e24a0c712c2613ce5704e9e73b693d2e98 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 6 Mar 2013 00:09:59 +0800 Subject: ASoC: arizona: Ensure synchroniser is disabled when not needed When live configuring a FLL configuration with no synchroniser disable the synchroniser in case the previous configuration used one. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 8b7855df99de..53ddd529769c 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1187,6 +1187,9 @@ static void arizona_enable_fll(struct arizona_fll *fll, arizona_apply_fll(arizona, fll->base, sync, fll->sync_src, false); + + regmap_update_bits(arizona->regmap, fll->base + 0x11, + ARIZONA_FLL1_SYNC_ENA, 0); } else { arizona_fll_err(fll, "No clocks provided\n"); return; -- cgit v1.2.3 From 86cd684fcb3220f4aa20cf9e32fd1059373a608a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 7 Mar 2013 16:14:04 +0800 Subject: ASoC: arizona: Suppress reference calculations when setting REFCLK to 0 Allow users to keep on specifying their output frequency when disabling the reference clock. Reported-by: Kyung Kwee Ryu Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 53ddd529769c..ad21d8255341 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1249,7 +1249,7 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source, if (fll->ref_src == source && fll->ref_freq == Fref) return 0; - if (fll->fout) { + if (fll->fout && Fref > 0) { ret = arizona_calc_fll(fll, &ref, Fref, fll->fout); if (ret != 0) return ret; @@ -1265,7 +1265,7 @@ int arizona_set_fll_refclk(struct arizona_fll *fll, int source, fll->ref_src = source; fll->ref_freq = Fref; - if (fll->fout) { + if (fll->fout && Fref > 0) { arizona_enable_fll(fll, &ref, &sync); } -- cgit v1.2.3 From cc289be8c913006a43275dfd8ed4ac56b43140a8 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 8 Mar 2013 12:07:28 +0100 Subject: ASoC: Add codec driver for AK5386 Adds a driver for Asahi Kasei's AK5386 Single-ended 24-Bit 192kHz delta-sigma ADC. The device has no control port interface but an optional RESET/PDN GPIO pin. Signed-off-by: Daniel Mack Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/ak5386.txt | 19 +++ sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/ak5386.c | 152 +++++++++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/ak5386.txt create mode 100644 sound/soc/codecs/ak5386.c (limited to 'sound/soc') diff --git a/Documentation/devicetree/bindings/sound/ak5386.txt b/Documentation/devicetree/bindings/sound/ak5386.txt new file mode 100644 index 000000000000..dc3914fe6ce8 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ak5386.txt @@ -0,0 +1,19 @@ +AK5386 Single-ended 24-Bit 192kHz delta-sigma ADC + +This device has no control interface. + +Required properties: + + - compatible : "asahi-kasei,ak5386" + +Optional properties: + + - reset-gpio : a GPIO spec for the reset/power down pin. + If specified, it will be deasserted at probe time. + +Example: + +spdif: ak5386@0 { + compatible = "asahi-kasei,ak5386"; + reset-gpio = <&gpio0 23>; +}; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 45b72561c615..500f666c3875 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -26,6 +26,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_AK4641 if I2C select SND_SOC_AK4642 if I2C select SND_SOC_AK4671 if I2C + select SND_SOC_AK5386 select SND_SOC_ALC5623 if I2C select SND_SOC_ALC5632 if I2C select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC @@ -203,6 +204,9 @@ config SND_SOC_AK4642 config SND_SOC_AK4671 tristate +config SND_SOC_AK5386 + tristate + config SND_SOC_ALC5623 tristate config SND_SOC_ALC5632 diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 6a3b3c3b8b41..3a7ec1c39741 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -14,6 +14,7 @@ snd-soc-ak4535-objs := ak4535.o snd-soc-ak4641-objs := ak4641.o snd-soc-ak4642-objs := ak4642.o snd-soc-ak4671-objs := ak4671.o +snd-soc-ak5386-objs := ak5386.o snd-soc-arizona-objs := arizona.o snd-soc-cq93vc-objs := cq93vc.o snd-soc-cs42l51-objs := cs42l51.o @@ -137,6 +138,7 @@ obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o +obj-$(CONFIG_SND_SOC_AK5386) += snd-soc-ak5386.o obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c new file mode 100644 index 000000000000..1f303983ae02 --- /dev/null +++ b/sound/soc/codecs/ak5386.c @@ -0,0 +1,152 @@ +/* + * ALSA SoC driver for + * Asahi Kasei AK5386 Single-ended 24-Bit 192kHz delta-sigma ADC + * + * (c) 2013 Daniel Mack + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct ak5386_priv { + int reset_gpio; +}; + +static struct snd_soc_codec_driver soc_codec_ak5386; + +static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int format) +{ + struct snd_soc_codec *codec = codec_dai->codec; + + format &= SND_SOC_DAIFMT_FORMAT_MASK; + if (format != SND_SOC_DAIFMT_LEFT_J && + format != SND_SOC_DAIFMT_I2S) { + dev_err(codec->dev, "Invalid DAI format\n"); + return -EINVAL; + } + + return 0; +} + +static int ak5386_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec); + + /* + * From the datasheet: + * + * All external clocks (MCLK, SCLK and LRCK) must be present unless + * PDN pin = “L”. If these clocks are not provided, the AK5386 may + * draw excess current due to its use of internal dynamically + * refreshed logic. If the external clocks are not present, place + * the AK5386 in power-down mode (PDN pin = “L”). + */ + + if (gpio_is_valid(priv->reset_gpio)) + gpio_set_value(priv->reset_gpio, 1); + + return 0; +} + +static int ak5386_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct ak5386_priv *priv = snd_soc_codec_get_drvdata(codec); + + if (gpio_is_valid(priv->reset_gpio)) + gpio_set_value(priv->reset_gpio, 0); + + return 0; +} + +static const struct snd_soc_dai_ops ak5386_dai_ops = { + .set_fmt = ak5386_set_dai_fmt, + .hw_params = ak5386_hw_params, + .hw_free = ak5386_hw_free, +}; + +static struct snd_soc_dai_driver ak5386_dai = { + .name = "ak5386-hifi", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + }, + .ops = &ak5386_dai_ops, +}; + +#ifdef CONFIG_OF +static const struct of_device_id ak5386_dt_ids[] = { + { .compatible = "asahi-kasei,ak5386", }, + { } +}; +MODULE_DEVICE_TABLE(of, ak5386_dt_ids); +#endif + +static int ak5386_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ak5386_priv *priv; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->reset_gpio = -EINVAL; + dev_set_drvdata(dev, priv); + + if (of_match_device(of_match_ptr(ak5386_dt_ids), dev)) + priv->reset_gpio = of_get_named_gpio(dev->of_node, + "reset-gpio", 0); + + if (gpio_is_valid(priv->reset_gpio)) + if (devm_gpio_request_one(dev, priv->reset_gpio, + GPIOF_OUT_INIT_LOW, + "AK5386 Reset")) + priv->reset_gpio = -EINVAL; + + return snd_soc_register_codec(dev, &soc_codec_ak5386, + &ak5386_dai, 1); +} + +static int ak5386_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +static struct platform_driver ak5386_driver = { + .probe = ak5386_probe, + .remove = ak5386_remove, + .driver = { + .name = "ak5386", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ak5386_dt_ids), + }, +}; + +module_platform_driver(ak5386_driver); + +MODULE_DESCRIPTION("ASoC driver for AK5386 ADC"); +MODULE_AUTHOR("Daniel Mack "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 4fa89346fbc34750f96ec0c1b2b59b15596ab333 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 8 Mar 2013 13:52:09 +0100 Subject: ALSA: ASoC: add codec driver for TI TAS5086 This patch adds a driver for TI's TA5086 6-channel PWM processor. This chip has a very unusual register layout, specifically because the registers are of unequal size, and multi-byte registers require bulk writes to take effect. Regmap does not support these kind of mappings. Currently, the driver does not touch any of the registers >= 0x20, so it doesn't matter, because the register map is mapped to an 8-bit array. In case more features will be added in the future that require access to higher registers, the entire regmap H/W I/O routines have to be open-coded. Signed-off-by: Daniel Mack Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/ti,tas5086.txt | 32 ++ include/sound/tas5086.h | 7 + sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/tas5086.c | 601 +++++++++++++++++++++ 5 files changed, 646 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/ti,tas5086.txt create mode 100644 include/sound/tas5086.h create mode 100644 sound/soc/codecs/tas5086.c (limited to 'sound/soc') diff --git a/Documentation/devicetree/bindings/sound/ti,tas5086.txt b/Documentation/devicetree/bindings/sound/ti,tas5086.txt new file mode 100644 index 000000000000..8ea4f5b4818d --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,tas5086.txt @@ -0,0 +1,32 @@ +Texas Instruments TAS5086 6-channel PWM Processor + +Required properties: + + - compatible: Should contain "ti,tas5086". + - reg: The i2c address. Should contain <0x1b>. + +Optional properties: + + - reset-gpio: A GPIO spec to define which pin is connected to the + chip's !RESET pin. If specified, the driver will + assert a hardware reset at probe time. + + - ti,charge-period: This property should contain the time in microseconds + that closely matches the external single-ended + split-capacitor charge period. The hardware chip + waits for this period of time before starting the + PWM signals. This helps reduce pops and clicks. + + When not specified, the hardware default of 1300ms + is retained. + +Examples: + + i2c_bus { + tas5086@1b { + compatible = "ti,tas5086"; + reg = <0x1b>; + reset-gpio = <&gpio 23 0>; + ti,charge-period = <156000>; + }; + }; diff --git a/include/sound/tas5086.h b/include/sound/tas5086.h new file mode 100644 index 000000000000..aac481b7db8f --- /dev/null +++ b/include/sound/tas5086.h @@ -0,0 +1,7 @@ +#ifndef _SND_SOC_CODEC_TAS5086_H_ +#define _SND_SOC_CODEC_TAS5086_H_ + +#define TAS5086_CLK_IDX_MCLK 0 +#define TAS5086_CLK_IDX_SCLK 1 + +#endif /* _SND_SOC_CODEC_TAS5086_H_ */ diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 45b72561c615..86b35245e559 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -63,6 +63,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_STA32X if I2C select SND_SOC_STA529 if I2C select SND_SOC_STAC9766 if SND_SOC_AC97_BUS + select SND_SOC_TAS5086 if I2C select SND_SOC_TLV320AIC23 if I2C select SND_SOC_TLV320AIC26 if SPI_MASTER select SND_SOC_TLV320AIC32X4 if I2C @@ -320,6 +321,9 @@ config SND_SOC_STA529 config SND_SOC_STAC9766 tristate +config SND_SOC_TAS5086 + tristate + config SND_SOC_TLV320AIC23 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 6a3b3c3b8b41..8077bc2b4f43 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -55,6 +55,7 @@ snd-soc-ssm2602-objs := ssm2602.o snd-soc-sta32x-objs := sta32x.o snd-soc-sta529-objs := sta529.o snd-soc-stac9766-objs := stac9766.o +snd-soc-tas5086-objs := tas5086.o snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic26-objs := tlv320aic26.o snd-soc-tlv320aic3x-objs := tlv320aic3x.o @@ -177,6 +178,7 @@ obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o +obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c new file mode 100644 index 000000000000..008bea4d6208 --- /dev/null +++ b/sound/soc/codecs/tas5086.c @@ -0,0 +1,601 @@ +/* + * TAS5086 ASoC codec driver + * + * Copyright (c) 2013 Daniel Mack + * + * 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. + * + * TODO: + * - implement DAPM and input muxing + * - implement modulation limit + * - implement non-default PWM start + * + * Note that this chip has a very unusual register layout, specifically + * because the registers are of unequal size, and multi-byte registers + * require bulk writes to take effect. Regmap does not support that kind + * of devices. + * + * Currently, the driver does not touch any of the registers >= 0x20, so + * it doesn't matter because the entire map can be accessed as 8-bit + * array. In case more features will be added in the future + * that require access to higher registers, the entire regmap H/W I/O + * routines have to be open-coded. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TAS5086_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_3LE) + +#define TAS5086_PCM_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \ + SNDRV_PCM_RATE_192000) + +/* + * TAS5086 registers + */ +#define TAS5086_CLOCK_CONTROL 0x00 /* Clock control register */ +#define TAS5086_CLOCK_RATE(val) (val << 5) +#define TAS5086_CLOCK_RATE_MASK (0x7 << 5) +#define TAS5086_CLOCK_RATIO(val) (val << 2) +#define TAS5086_CLOCK_RATIO_MASK (0x7 << 2) +#define TAS5086_CLOCK_SCLK_RATIO_48 (1 << 1) +#define TAS5086_CLOCK_VALID (1 << 0) + +#define TAS5086_DEEMPH_MASK 0x03 +#define TAS5086_SOFT_MUTE_ALL 0x3f + +#define TAS5086_DEV_ID 0x01 /* Device ID register */ +#define TAS5086_ERROR_STATUS 0x02 /* Error status register */ +#define TAS5086_SYS_CONTROL_1 0x03 /* System control register 1 */ +#define TAS5086_SERIAL_DATA_IF 0x04 /* Serial data interface register */ +#define TAS5086_SYS_CONTROL_2 0x05 /* System control register 2 */ +#define TAS5086_SOFT_MUTE 0x06 /* Soft mute register */ +#define TAS5086_MASTER_VOL 0x07 /* Master volume */ +#define TAS5086_CHANNEL_VOL(X) (0x08 + (X)) /* Channel 1-6 volume */ +#define TAS5086_VOLUME_CONTROL 0x09 /* Volume control register */ +#define TAS5086_MOD_LIMIT 0x10 /* Modulation limit register */ +#define TAS5086_PWM_START 0x18 /* PWM start register */ +#define TAS5086_SURROUND 0x19 /* Surround register */ +#define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */ +#define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */ +#define TAS5086_BKNDERR 0x1c + +/* + * Default TAS5086 power-up configuration + */ +static const struct reg_default tas5086_reg_defaults[] = { + { 0x00, 0x6c }, + { 0x01, 0x03 }, + { 0x02, 0x00 }, + { 0x03, 0xa0 }, + { 0x04, 0x05 }, + { 0x05, 0x60 }, + { 0x06, 0x00 }, + { 0x07, 0xff }, + { 0x08, 0x30 }, + { 0x09, 0x30 }, + { 0x0a, 0x30 }, + { 0x0b, 0x30 }, + { 0x0c, 0x30 }, + { 0x0d, 0x30 }, + { 0x0e, 0xb1 }, + { 0x0f, 0x00 }, + { 0x10, 0x02 }, + { 0x11, 0x00 }, + { 0x12, 0x00 }, + { 0x13, 0x00 }, + { 0x14, 0x00 }, + { 0x15, 0x00 }, + { 0x16, 0x00 }, + { 0x17, 0x00 }, + { 0x18, 0x3f }, + { 0x19, 0x00 }, + { 0x1a, 0x18 }, + { 0x1b, 0x82 }, + { 0x1c, 0x05 }, +}; + +static bool tas5086_accessible_reg(struct device *dev, unsigned int reg) +{ + return !((reg == 0x0f) || (reg >= 0x11 && reg <= 0x17)); +} + +static bool tas5086_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TAS5086_DEV_ID: + case TAS5086_ERROR_STATUS: + return true; + } + + return false; +} + +static bool tas5086_writeable_reg(struct device *dev, unsigned int reg) +{ + return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID); +} + +struct tas5086_private { + struct regmap *regmap; + unsigned int mclk, sclk; + unsigned int format; + bool deemph; + /* Current sample rate for de-emphasis control */ + int rate; + /* GPIO driving Reset pin, if any */ + int gpio_nreset; +}; + +static int tas5086_deemph[] = { 0, 32000, 44100, 48000 }; + +static int tas5086_set_deemph(struct snd_soc_codec *codec) +{ + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + int i, val = 0; + + if (priv->deemph) + for (i = 0; i < ARRAY_SIZE(tas5086_deemph); i++) + if (tas5086_deemph[i] == priv->rate) + val = i; + + return regmap_update_bits(priv->regmap, TAS5086_SYS_CONTROL_1, + TAS5086_DEEMPH_MASK, val); +} + +static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = priv->deemph; + + return 0; +} + +static int tas5086_put_deemph(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + + priv->deemph = ucontrol->value.enumerated.item[0]; + + return tas5086_set_deemph(codec); +} + + +static int tas5086_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + + switch (clk_id) { + case TAS5086_CLK_IDX_MCLK: + priv->mclk = freq; + break; + case TAS5086_CLK_IDX_SCLK: + priv->sclk = freq; + break; + } + + return 0; +} + +static int tas5086_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int format) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + + /* The TAS5086 can only be slave to all clocks */ + if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { + dev_err(codec->dev, "Invalid clocking mode\n"); + return -EINVAL; + } + + /* we need to refer to the data format from hw_params() */ + priv->format = format; + + return 0; +} + +static const int tas5086_sample_rates[] = { + 32000, 38000, 44100, 48000, 88200, 96000, 176400, 192000 +}; + +static const int tas5086_ratios[] = { + 64, 128, 192, 256, 384, 512 +}; + +static int index_in_array(const int *array, int len, int needle) +{ + int i; + + for (i = 0; i < len; i++) + if (array[i] == needle) + return i; + + return -ENOENT; +} + +static int tas5086_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + unsigned int val; + int ret; + + priv->rate = params_rate(params); + + /* Look up the sample rate and refer to the offset in the list */ + val = index_in_array(tas5086_sample_rates, + ARRAY_SIZE(tas5086_sample_rates), priv->rate); + + if (val < 0) { + dev_err(codec->dev, "Invalid sample rate\n"); + return -EINVAL; + } + + ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, + TAS5086_CLOCK_RATE_MASK, + TAS5086_CLOCK_RATE(val)); + if (ret < 0) + return ret; + + /* MCLK / Fs ratio */ + val = index_in_array(tas5086_ratios, ARRAY_SIZE(tas5086_ratios), + priv->mclk / priv->rate); + if (val < 0) { + dev_err(codec->dev, "Inavlid MCLK / Fs ratio\n"); + return -EINVAL; + } + + ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, + TAS5086_CLOCK_RATIO_MASK, + TAS5086_CLOCK_RATIO(val)); + if (ret < 0) + return ret; + + + ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, + TAS5086_CLOCK_SCLK_RATIO_48, + (priv->sclk == 48 * priv->rate) ? + TAS5086_CLOCK_SCLK_RATIO_48 : 0); + if (ret < 0) + return ret; + + /* + * The chip has a very unituitive register mapping and muxes information + * about data format and sample depth into the same register, but not on + * a logical bit-boundary. Hence, we have to refer to the format passed + * in the set_dai_fmt() callback and set up everything from here. + * + * First, determine the 'base' value, using the format ... + */ + switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_RIGHT_J: + val = 0x00; + break; + case SND_SOC_DAIFMT_I2S: + val = 0x03; + break; + case SND_SOC_DAIFMT_LEFT_J: + val = 0x06; + break; + default: + dev_err(codec->dev, "Invalid DAI format\n"); + return -EINVAL; + } + + /* ... then add the offset for the sample bit depth. */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + val += 0; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + val += 1; + break; + case SNDRV_PCM_FORMAT_S24_3LE: + val += 2; + break; + default: + dev_err(codec->dev, "Invalid bit width\n"); + return -EINVAL; + }; + + ret = regmap_write(priv->regmap, TAS5086_SERIAL_DATA_IF, val); + if (ret < 0) + return ret; + + /* clock is considered valid now */ + ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, + TAS5086_CLOCK_VALID, TAS5086_CLOCK_VALID); + if (ret < 0) + return ret; + + return tas5086_set_deemph(codec); +} + +static int tas5086_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_codec *codec = dai->codec; + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + unsigned int val = 0; + + if (mute) + val = TAS5086_SOFT_MUTE_ALL; + + return regmap_write(priv->regmap, TAS5086_SOFT_MUTE, val); +} + +/* TAS5086 controls */ +static const DECLARE_TLV_DB_SCALE(tas5086_dac_tlv, -10350, 50, 1); + +static const struct snd_kcontrol_new tas5086_controls[] = { + SOC_SINGLE_TLV("Master Playback Volume", TAS5086_MASTER_VOL, + 0, 0xff, 1, tas5086_dac_tlv), + SOC_DOUBLE_R_TLV("Channel 1/2 Playback Volume", + TAS5086_CHANNEL_VOL(0), TAS5086_CHANNEL_VOL(1), + 0, 0xff, 1, tas5086_dac_tlv), + SOC_DOUBLE_R_TLV("Channel 3/4 Playback Volume", + TAS5086_CHANNEL_VOL(2), TAS5086_CHANNEL_VOL(3), + 0, 0xff, 1, tas5086_dac_tlv), + SOC_DOUBLE_R_TLV("Channel 5/6 Playback Volume", + TAS5086_CHANNEL_VOL(4), TAS5086_CHANNEL_VOL(5), + 0, 0xff, 1, tas5086_dac_tlv), + SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0, + tas5086_get_deemph, tas5086_put_deemph), +}; + +static const struct snd_soc_dai_ops tas5086_dai_ops = { + .hw_params = tas5086_hw_params, + .set_sysclk = tas5086_set_dai_sysclk, + .set_fmt = tas5086_set_dai_fmt, + .mute_stream = tas5086_mute_stream, +}; + +static struct snd_soc_dai_driver tas5086_dai = { + .name = "tas5086-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 6, + .rates = TAS5086_PCM_RATES, + .formats = TAS5086_PCM_FORMATS, + }, + .ops = &tas5086_dai_ops, +}; + +#ifdef CONFIG_PM +static int tas5086_soc_resume(struct snd_soc_codec *codec) +{ + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + + /* Restore codec state */ + return regcache_sync(priv->regmap); +} +#else +#define tas5086_soc_resume NULL +#endif /* CONFIG_PM */ + +#ifdef CONFIG_OF +static const struct of_device_id tas5086_dt_ids[] = { + { .compatible = "ti,tas5086", }, + { } +}; +MODULE_DEVICE_TABLE(of, tas5086_dt_ids); +#endif + +/* charge period values in microseconds */ +static const int tas5086_charge_period[] = { + 13000, 16900, 23400, 31200, 41600, 54600, 72800, 96200, + 130000, 156000, 234000, 312000, 416000, 546000, 728000, 962000, + 1300000, 169000, 2340000, 3120000, 4160000, 5460000, 7280000, 9620000, +}; + +static int tas5086_probe(struct snd_soc_codec *codec) +{ + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + int charge_period = 1300000; /* hardware default is 1300 ms */ + int i, ret; + + if (of_match_device(of_match_ptr(tas5086_dt_ids), codec->dev)) { + struct device_node *of_node = codec->dev->of_node; + of_property_read_u32(of_node, "ti,charge-period", &charge_period); + } + + /* lookup and set split-capacitor charge period */ + if (charge_period == 0) { + regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0); + } else { + i = index_in_array(tas5086_charge_period, + ARRAY_SIZE(tas5086_charge_period), + charge_period); + if (i >= 0) + regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, + i + 0x08); + else + dev_warn(codec->dev, + "Invalid split-cap charge period of %d ns.\n", + charge_period); + } + + /* enable factory trim */ + ret = regmap_write(priv->regmap, TAS5086_OSC_TRIM, 0x00); + if (ret < 0) + return ret; + + /* start all channels */ + ret = regmap_write(priv->regmap, TAS5086_SYS_CONTROL_2, 0x20); + if (ret < 0) + return ret; + + /* set master volume to 0 dB */ + ret = regmap_write(priv->regmap, TAS5086_MASTER_VOL, 0x30); + if (ret < 0) + return ret; + + /* mute all channels for now */ + ret = regmap_write(priv->regmap, TAS5086_SOFT_MUTE, + TAS5086_SOFT_MUTE_ALL); + if (ret < 0) + return ret; + + return 0; +} + +static int tas5086_remove(struct snd_soc_codec *codec) +{ + struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); + + if (gpio_is_valid(priv->gpio_nreset)) + /* Set codec to the reset state */ + gpio_set_value(priv->gpio_nreset, 0); + + return 0; +}; + +static struct snd_soc_codec_driver soc_codec_dev_tas5086 = { + .probe = tas5086_probe, + .remove = tas5086_remove, + .resume = tas5086_soc_resume, + .controls = tas5086_controls, + .num_controls = ARRAY_SIZE(tas5086_controls), +}; + +static const struct i2c_device_id tas5086_i2c_id[] = { + { "tas5086", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tas5086_i2c_id); + +static const struct regmap_config tas5086_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = ARRAY_SIZE(tas5086_reg_defaults), + .reg_defaults = tas5086_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults), + .cache_type = REGCACHE_RBTREE, + .volatile_reg = tas5086_volatile_reg, + .writeable_reg = tas5086_writeable_reg, + .readable_reg = tas5086_accessible_reg, +}; + +static int tas5086_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct tas5086_private *priv; + struct device *dev = &i2c->dev; + int gpio_nreset = -EINVAL; + int i, ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->regmap = devm_regmap_init_i2c(i2c, &tas5086_regmap); + if (IS_ERR(priv->regmap)) { + ret = PTR_ERR(priv->regmap); + dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); + return ret; + } + + i2c_set_clientdata(i2c, priv); + + if (of_match_device(of_match_ptr(tas5086_dt_ids), dev)) { + struct device_node *of_node = dev->of_node; + gpio_nreset = of_get_named_gpio(of_node, "reset-gpio", 0); + } + + if (gpio_is_valid(gpio_nreset)) + if (devm_gpio_request(dev, gpio_nreset, "TAS5086 Reset")) + gpio_nreset = -EINVAL; + + if (gpio_is_valid(gpio_nreset)) { + /* Reset codec - minimum assertion time is 400ns */ + gpio_direction_output(gpio_nreset, 0); + udelay(1); + gpio_set_value(gpio_nreset, 1); + + /* Codec needs ~15ms to wake up */ + msleep(15); + } + + priv->gpio_nreset = gpio_nreset; + + /* The TAS5086 always returns 0x03 in its TAS5086_DEV_ID register */ + ret = regmap_read(priv->regmap, TAS5086_DEV_ID, &i); + if (ret < 0) + return ret; + + if (i != 0x3) { + dev_err(dev, + "Failed to identify TAS5086 codec (got %02x)\n", i); + return -ENODEV; + } + + return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_tas5086, + &tas5086_dai, 1); +} + +static int tas5086_i2c_remove(struct i2c_client *i2c) +{ + snd_soc_unregister_codec(&i2c->dev); + return 0; +} + +static struct i2c_driver tas5086_i2c_driver = { + .driver = { + .name = "tas5086", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(tas5086_dt_ids), + }, + .id_table = tas5086_i2c_id, + .probe = tas5086_i2c_probe, + .remove = tas5086_i2c_remove, +}; + +static int __init tas5086_modinit(void) +{ + return i2c_add_driver(&tas5086_i2c_driver); +} +module_init(tas5086_modinit); + +static void __exit tas5086_modexit(void) +{ + i2c_del_driver(&tas5086_i2c_driver); +} +module_exit(tas5086_modexit); + +MODULE_AUTHOR("Daniel Mack "); +MODULE_DESCRIPTION("Texas Instruments TAS5086 ALSA SoC Codec Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From c300d6de53ae029576b2805f08d8596d2e511b08 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 12 Mar 2013 21:36:24 +0800 Subject: ASoC: tas5086: use module_i2c_driver to simplify the code Use the module_i2c_driver() macro to make the code smaller and a bit simpler. Signed-off-by: Wei Yongjun Acked-by: Daniel Mack Signed-off-by: Mark Brown --- sound/soc/codecs/tas5086.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 008bea4d6208..40cee844f0cf 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -584,17 +584,7 @@ static struct i2c_driver tas5086_i2c_driver = { .remove = tas5086_i2c_remove, }; -static int __init tas5086_modinit(void) -{ - return i2c_add_driver(&tas5086_i2c_driver); -} -module_init(tas5086_modinit); - -static void __exit tas5086_modexit(void) -{ - i2c_del_driver(&tas5086_i2c_driver); -} -module_exit(tas5086_modexit); +module_i2c_driver(tas5086_i2c_driver); MODULE_AUTHOR("Daniel Mack "); MODULE_DESCRIPTION("Texas Instruments TAS5086 ALSA SoC Codec Driver"); -- cgit v1.2.3 From 14a1b8ca172f4cfbc544051a729d85a380447a82 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Mon, 11 Mar 2013 13:18:23 -0600 Subject: ASoC: adau1373: adau1373_hw_params: Silence overflow warning ADAU1373_BCLKDIV_SOURCE is defined as BIT(5) which uses UL constants. On amd64 the result of the ones complement operator is then truncated to unsigned int according to the prototype of snd_soc_update_bits(). I think gcc is correctly warning that the upper 32 bits are lost. sound/soc/codecs/adau1373.c: In function 'adau1373_hw_params': sound/soc/codecs/adau1373.c:940:3: warning: large integer implicitly truncated to unsigned type [-Woverflow] gcc version 4.6.3 Add 2 more BCLKDIV mask macros as explained by Lars: The BCLKDIV has three fields. The bitclock divider (bit 0-1), the samplerate (bit 2-4) and the source select (bit 5). Here we want to update the bitclock divider field and the samplerate field. When I wrote the code I was lazy and used ~ADAU1373_BCLKDIV_SOURCE as the mask, which for this register is functionally equivalent to ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK. Signed-off-by: Tim Gardner Acked-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adau1373.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 068b3ae56a17..1aa10ddf3a61 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -133,6 +133,8 @@ struct adau1373 { #define ADAU1373_DAI_FORMAT_DSP 0x3 #define ADAU1373_BCLKDIV_SOURCE BIT(5) +#define ADAU1373_BCLKDIV_SR_MASK (0x07 << 2) +#define ADAU1373_BCLKDIV_BCLK_MASK 0x03 #define ADAU1373_BCLKDIV_32 0x03 #define ADAU1373_BCLKDIV_64 0x02 #define ADAU1373_BCLKDIV_128 0x01 @@ -937,7 +939,8 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream, adau1373_dai->enable_src = (div != 0); snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id), - ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64); + ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK, + (div << 2) | ADAU1373_BCLKDIV_64); switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: -- cgit v1.2.3 From 1f5353e765fe2a1168477bfe55e4dd7cdd96b477 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Sun, 10 Mar 2013 10:58:21 -0600 Subject: ASoC: wm_hubs: Silence reg_r and reg_l 'may be used uninitialized' warnings Return an error from wm_hubs_read_dc_servo() if hubs->dcs_readback_mode is not correctly initialized. You might as well bail out since nothing is likely to work correctly afterwards. sound/soc/codecs/wm_hubs.c:321:11: warning: 'reg_r' may be used uninitialized in this function [-Wuninitialized] sound/soc/codecs/wm_hubs.c:251:13: note: 'reg_r' was declared here sound/soc/codecs/wm_hubs.c:322:11: warning: 'reg_l' may be used uninitialized in this function [-Wuninitialized] sound/soc/codecs/wm_hubs.c:251:6: note: 'reg_l' was declared here gcc version 4.6.3 Signed-off-by: Tim Gardner Signed-off-by: Mark Brown --- sound/soc/codecs/wm_hubs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 867ae97ddcec..f5d81b948759 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -199,11 +199,12 @@ static void wm_hubs_dcs_cache_set(struct snd_soc_codec *codec, u16 dcs_cfg) list_add_tail(&cache->list, &hubs->dcs_cache); } -static void wm_hubs_read_dc_servo(struct snd_soc_codec *codec, +static int wm_hubs_read_dc_servo(struct snd_soc_codec *codec, u16 *reg_l, u16 *reg_r) { struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); u16 dcs_reg, reg; + int ret = 0; switch (hubs->dcs_readback_mode) { case 2: @@ -236,8 +237,9 @@ static void wm_hubs_read_dc_servo(struct snd_soc_codec *codec, break; default: WARN(1, "Unknown DCS readback method\n"); - return; + ret = -1; } + return ret; } /* @@ -286,7 +288,8 @@ static void enable_dc_servo(struct snd_soc_codec *codec) WM8993_DCS_TRIG_STARTUP_1); } - wm_hubs_read_dc_servo(codec, ®_l, ®_r); + if (wm_hubs_read_dc_servo(codec, ®_l, ®_r) < 0) + return; dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); -- cgit v1.2.3 From c1963c37ad4425cbd7a05e386167614efdfdc9ce Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sun, 10 Mar 2013 19:33:02 +0100 Subject: ASoC: imx-ssi: Fix AC97 rates This device supports multiple rates as described in later AC97 standards. This patch allows playback of different sample frequencies without conversion. Signed-off-by: Sascha Hauer Signed-off-by: Markus Pargmann Signed-off-by: Mark Brown --- sound/soc/fsl/imx-ssi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 55464a5b0706..7ee0147ec3cd 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -400,7 +400,7 @@ static struct snd_soc_dai_driver imx_ac97_dai = { .stream_name = "AC97 Playback", .channels_min = 2, .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, + .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .capture = { -- cgit v1.2.3 From ecf327c7ca5ddcbe611a33c88c19b8be3d0d2322 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 8 Mar 2013 14:19:38 +0100 Subject: ASoC: davinci-mcasp: clean up davinci_hw_common_param() As pointed of by Vaibhav, commit 2952b27e2 ("ASoC: davinci-mcasp: Add support for multichannel playback") duplicated the logic of counting the active serializers. That can be avoided by shifting the code around a bit. Also, drop two unused defines introduced by the same commit. Signed-off-by: Daniel Mack Acked-by: Vaibhav Bedia Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 5cd85a879579..46c9705cec09 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -237,8 +237,6 @@ #define RXSTATE BIT(5) #define SRMOD_MASK 3 #define SRMOD_INACTIVE 0 -#define SRMOD_TX 1 -#define SRMOD_RX 2 /* * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits @@ -686,27 +684,6 @@ static int davinci_hw_common_param(struct davinci_audio_dev *dev, int stream, RXDATADMADIS); } - for (i = 0; i < dev->num_serializer; i++) { - if (dev->serial_dir[i] == TX_MODE) - tx_ser++; - if (dev->serial_dir[i] == RX_MODE) - rx_ser++; - } - - if (stream == SNDRV_PCM_STREAM_PLAYBACK) - ser = tx_ser; - else - ser = rx_ser; - - if (ser < max_active_serializers) { - dev_warn(dev->dev, "stream has more channels (%d) than are " - "enabled in mcasp (%d)\n", channels, ser * slots); - return -EINVAL; - } - - tx_ser = 0; - rx_ser = 0; - for (i = 0; i < dev->num_serializer; i++) { mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i), dev->serial_dir[i]); @@ -726,6 +703,17 @@ static int davinci_hw_common_param(struct davinci_audio_dev *dev, int stream, } } + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + ser = tx_ser; + else + ser = rx_ser; + + if (ser < max_active_serializers) { + dev_warn(dev->dev, "stream has more channels (%d) than are " + "enabled in mcasp (%d)\n", channels, ser * slots); + return -EINVAL; + } + if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { if (dev->txnumevt * tx_ser > 64) dev->txnumevt = 1; -- cgit v1.2.3 From ec20fba77df4053ef703900be882527b95606592 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 12 Mar 2013 23:09:35 +0100 Subject: ASoC: samsung: remove last traces of neo1973-gta01 The support for the Openmoko Neo1973 GTA01 got removed in commit 1ae5cbc52e7c6619a3f44b87809fd25370df31bb ("ASoC: neo1973_wm8753: remove references to the neo1973-gta01 machine"). Remove its last traces in the Kconfig file too. Signed-off-by: Paul Bolle Acked-by: Kukjin Kim Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 90e7e6653233..475fb0d8b3c6 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -35,11 +35,10 @@ config SND_SAMSUNG_I2S tristate config SND_SOC_SAMSUNG_NEO1973_WM8753 - tristate "Audio support for Openmoko Neo1973 Smartphones (GTA01/GTA02)" - depends on SND_SOC_SAMSUNG && (MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02) + tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)" + depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02 select SND_S3C24XX_I2S select SND_SOC_WM8753 - select SND_SOC_LM4857 if MACH_NEO1973_GTA01 select SND_SOC_DFBMCS320 help Say Y here to enable audio support for the Openmoko Neo1973 -- cgit v1.2.3 From 77c641d3468a66377752ee9ae06e65dee41fe804 Mon Sep 17 00:00:00 2001 From: Silviu-Mihai Popescu Date: Mon, 11 Mar 2013 17:58:57 +0200 Subject: ASoC: omap: convert to devm_ioremap_resource() Convert all uses of devm_request_and_ioremap() to the newly introduced devm_ioremap_resource() which provides more consistent error handling. devm_ioremap_resource() provides its own error messages so all explicit error messages can be removed from the failure code paths. Signed-off-by: Silviu-Mihai Popescu Acked-by: Jarkko Nikula Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 9 +++------ sound/soc/omap/omap-mcpdm.c | 8 +++----- 2 files changed, 6 insertions(+), 11 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 77e9e7e68edc..8ebaf117d81f 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -493,12 +493,9 @@ static int asoc_dmic_probe(struct platform_device *pdev) goto err_put_clk; } - dmic->io_base = devm_request_and_ioremap(&pdev->dev, res); - if (!dmic->io_base) { - dev_err(&pdev->dev, "cannot remap\n"); - ret = -ENOMEM; - goto err_put_clk; - } + dmic->io_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dmic->io_base)) + return PTR_ERR(dmic->io_base); ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai); if (ret) diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 079f277cdba4..ddfcc1834ff0 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -464,11 +464,9 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) if (res == NULL) return -ENOMEM; - mcpdm->io_base = devm_request_and_ioremap(&pdev->dev, res); - if (!mcpdm->io_base) { - dev_err(&pdev->dev, "cannot remap\n"); - return -ENOMEM; - } + mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mcpdm->io_base)) + return PTR_ERR(mcpdm->io_base); mcpdm->irq = platform_get_irq(pdev, 0); if (mcpdm->irq < 0) -- cgit v1.2.3 From 127c5cad87099fef816c8597258fc06285d17bb1 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 12 Mar 2013 20:51:28 -0300 Subject: ASoC: fsl: imx-audmux: Use devm_clk_get() By using devm_clk_get() we can save a call to clk_put(). Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/fsl/imx-audmux.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index 3f333e5b4673..47f046a8fdab 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -262,7 +262,7 @@ static int imx_audmux_probe(struct platform_device *pdev) return PTR_ERR(pinctrl); } - audmux_clk = clk_get(&pdev->dev, "audmux"); + audmux_clk = devm_clk_get(&pdev->dev, "audmux"); if (IS_ERR(audmux_clk)) { dev_dbg(&pdev->dev, "cannot get clock: %ld\n", PTR_ERR(audmux_clk)); @@ -282,7 +282,6 @@ static int imx_audmux_remove(struct platform_device *pdev) { if (audmux_type == IMX31_AUDMUX) audmux_debugfs_remove(); - clk_put(audmux_clk); return 0; } -- cgit v1.2.3 From 9c3372898323cb9596a23097e939df3bd83de5fc Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 12 Mar 2013 17:41:54 -0700 Subject: ASoC: fsi: remove unused irq FSI is using devm_request_irq() from 1ddd82868cc888e008ed520465c172a6cdddd689 (ASoC: fsi: use devm_request_irq()) master->irq is no longer needed. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index c724026a246f..8b91a15110e0 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -296,7 +296,6 @@ struct fsi_core { struct fsi_master { void __iomem *base; - int irq; struct fsi_priv fsia; struct fsi_priv fsib; const struct fsi_core *core; @@ -2002,7 +2001,6 @@ static int fsi_probe(struct platform_device *pdev) } /* master setting */ - master->irq = irq; master->core = core; spin_lock_init(&master->lock); -- cgit v1.2.3 From 030e79f658de11da43d32e7ad814b5d2d64c8bac Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 11 Mar 2013 18:27:21 -0700 Subject: ASoC: add snd_soc_register_component() Current ASoC has register function for platform/codec/dai/card, but doesn't have for cpu. It often produces confusion and fault on ASoC. As result of ASoC community discussion, we consider new struct snd_soc_component for CPU/CODEC, and will switch over to use it. This patch adds very basic struct snd_soc_component, and register function for it. Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Reviewed-by: Stephen Warren Signed-off-by: Mark Brown --- include/sound/soc.h | 19 +++++++++++++ sound/soc/soc-core.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) (limited to 'sound/soc') diff --git a/include/sound/soc.h b/include/sound/soc.h index a6a059ca3874..8c46d0a7e2c0 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -324,6 +324,8 @@ struct snd_soc_dai_link; struct snd_soc_platform_driver; struct snd_soc_codec; struct snd_soc_codec_driver; +struct snd_soc_component; +struct snd_soc_component_driver; struct soc_enum; struct snd_soc_jack; struct snd_soc_jack_zone; @@ -377,6 +379,10 @@ int snd_soc_register_codec(struct device *dev, const struct snd_soc_codec_driver *codec_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_codec(struct device *dev); +int snd_soc_register_component(struct device *dev, + const struct snd_soc_component_driver *cmpnt_drv, + struct snd_soc_dai_driver *dai_drv, int num_dai); +void snd_soc_unregister_component(struct device *dev); int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, unsigned int reg); int snd_soc_codec_readable_register(struct snd_soc_codec *codec, @@ -841,6 +847,19 @@ struct snd_soc_platform { #endif }; +struct snd_soc_component_driver { +}; + +struct snd_soc_component { + const char *name; + int id; + int num_dai; + struct device *dev; + struct list_head list; + + const struct snd_soc_component_driver *driver; +}; + struct snd_soc_dai_link { /* config - must be set by machine driver */ const char *name; /* Codec name */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b7e84a7cd9ee..9e6118573fef 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -58,6 +58,7 @@ static DEFINE_MUTEX(client_mutex); static LIST_HEAD(dai_list); static LIST_HEAD(platform_list); static LIST_HEAD(codec_list); +static LIST_HEAD(component_list); /* * This is a timeout to do a DAPM powerdown after a stream is closed(). @@ -4137,6 +4138,82 @@ found: } EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); + +/** + * snd_soc_register_component - Register a component with the ASoC core + * + */ +int snd_soc_register_component(struct device *dev, + const struct snd_soc_component_driver *cmpnt_drv, + struct snd_soc_dai_driver *dai_drv, + int num_dai) +{ + struct snd_soc_component *cmpnt; + int ret; + + dev_dbg(dev, "component register %s\n", dev_name(dev)); + + cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL); + if (!cmpnt) { + dev_err(dev, "ASoC: Failed to allocate memory\n"); + return -ENOMEM; + } + + cmpnt->name = fmt_single_name(dev, &cmpnt->id); + if (!cmpnt->name) { + dev_err(dev, "ASoC: Failed to simplifying name\n"); + return -ENOMEM; + } + + cmpnt->dev = dev; + cmpnt->driver = cmpnt_drv; + cmpnt->num_dai = num_dai; + + ret = snd_soc_register_dais(dev, dai_drv, num_dai); + if (ret < 0) { + dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); + goto error_component_name; + } + + mutex_lock(&client_mutex); + list_add(&cmpnt->list, &component_list); + mutex_unlock(&client_mutex); + + dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name); + + return ret; + +error_component_name: + kfree(cmpnt->name); + + return ret; +} + +/** + * snd_soc_unregister_component - Unregister a component from the ASoC core + * + */ +void snd_soc_unregister_component(struct device *dev) +{ + struct snd_soc_component *cmpnt; + + list_for_each_entry(cmpnt, &component_list, list) { + if (dev == cmpnt->dev) + goto found; + } + return; + +found: + snd_soc_unregister_dais(dev, cmpnt->num_dai); + + mutex_lock(&client_mutex); + list_del(&cmpnt->list); + mutex_unlock(&client_mutex); + + dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name); + kfree(cmpnt->name); +} + /* Retrieve a card's name from device tree */ int snd_soc_of_parse_card_name(struct snd_soc_card *card, const char *propname) -- cgit v1.2.3 From 28dbd1611f5701c9b5b8c07924c1bd2ad6f64435 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Mar 2013 08:32:53 +0300 Subject: ASoC: tas5086: signedness bug in tas5086_hw_params() "val" has to be signed for the error handling to work. Signed-off-by: Dan Carpenter Acked-by: Daniel Mack Signed-off-by: Mark Brown --- sound/soc/codecs/tas5086.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 40cee844f0cf..d447c4aa1d5e 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -251,7 +251,7 @@ static int tas5086_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_codec *codec = dai->codec; struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); - unsigned int val; + int val; int ret; priv->rate = params_rate(params); -- cgit v1.2.3 From 3f341f741de956980775761370e3abc4122be53a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 8 Mar 2013 15:22:29 +0800 Subject: ASoC: arizona: Provide defines for the clock rates Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 12 ++++++------ sound/soc/codecs/arizona.h | 8 ++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index ad21d8255341..0c70d503fd32 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -504,27 +504,27 @@ int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, break; case 11289600: case 12288000: - val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT; + val |= ARIZONA_CLK_12MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; break; case 22579200: case 24576000: - val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT; + val |= ARIZONA_CLK_24MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; break; case 45158400: case 49152000: - val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT; + val |= ARIZONA_CLK_49MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; break; case 67737600: case 73728000: - val |= 4 << ARIZONA_SYSCLK_FREQ_SHIFT; + val |= ARIZONA_CLK_73MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; break; case 90316800: case 98304000: - val |= 5 << ARIZONA_SYSCLK_FREQ_SHIFT; + val |= ARIZONA_CLK_98MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; break; case 135475200: case 147456000: - val |= 6 << ARIZONA_SYSCLK_FREQ_SHIFT; + val |= ARIZONA_CLK_147MHZ << ARIZONA_SYSCLK_FREQ_SHIFT; break; case 0: dev_dbg(arizona->dev, "%s cleared\n", name); diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index d592adcc969c..572f11bc90b4 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -49,6 +49,14 @@ #define ARIZONA_MIXER_VOL_SHIFT 1 #define ARIZONA_MIXER_VOL_WIDTH 7 +#define ARIZONA_CLK_6MHZ 0 +#define ARIZONA_CLK_12MHZ 1 +#define ARIZONA_CLK_24MHZ 2 +#define ARIZONA_CLK_49MHZ 3 +#define ARIZONA_CLK_73MHZ 4 +#define ARIZONA_CLK_98MHZ 5 +#define ARIZONA_CLK_147MHZ 6 + #define ARIZONA_MAX_DAI 4 #define ARIZONA_MAX_ADSP 4 -- cgit v1.2.3 From f395a21853935ab7a2d0d760cda206ae55300194 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Mar 2013 22:39:54 +0800 Subject: ASoC: wm_adsp: Handle old .bin files Older .bin files report the global coefficients as absolute address writes to zero; maintain compatibility with them. Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 26 ++++++++++++++++++++++---- sound/soc/codecs/wm_adsp.h | 2 ++ 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f3f7e75f8628..febb4c76535e 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -549,8 +549,9 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) buf_size = sizeof(adsp1_id); algs = be32_to_cpu(adsp1_id.algs); + dsp->fw_id = be32_to_cpu(adsp1_id.fw.id); adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", - be32_to_cpu(adsp1_id.fw.id), + dsp->fw_id, (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, be32_to_cpu(adsp1_id.fw.ver) & 0xff, @@ -573,8 +574,9 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) buf_size = sizeof(adsp2_id); algs = be32_to_cpu(adsp2_id.algs); + dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", - be32_to_cpu(adsp2_id.fw.id), + dsp->fw_id, (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16, (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8, be32_to_cpu(adsp2_id.fw.ver) & 0xff, @@ -781,8 +783,24 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) case (WMFW_INFO_TEXT << 8): break; case (WMFW_ABSOLUTE << 8): - region_name = "register"; - reg = offset; + /* + * Old files may use this for global + * coefficients. + */ + if (le32_to_cpu(blk->id) == dsp->fw_id && + offset == 0) { + region_name = "global coefficients"; + mem = wm_adsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No ZM\n"); + break; + } + reg = wm_adsp_region_to_reg(mem, 0); + + } else { + region_name = "register"; + reg = offset; + } break; case WMFW_ADSP1_DM: diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index cb8871a3ec00..d6fd8af53b5d 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -46,6 +46,8 @@ struct wm_adsp { struct list_head alg_regions; + int fw_id; + const struct wm_adsp_region *mem; int num_mems; -- cgit v1.2.3 From 76bf969e6f86e5de788dd943ff2d4340bac71822 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 5 Mar 2013 14:17:47 +0800 Subject: ASoC: arizona: Ensure we clock two channels for I2S mode I2S requires stereo clocking even for mono data. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 0c70d503fd32..2b0803ec8234 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -818,7 +818,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, struct arizona *arizona = priv->arizona; int base = dai->driver->base; const int *rates; - int i, ret; + int i, ret, val; int chan_limit = arizona->pdata.max_channels_clocked[dai->id - 1]; int bclk, lrclk, wl, frame, bclk_target; @@ -834,6 +834,13 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, bclk_target *= chan_limit; } + /* Force stereo for I2S mode */ + val = snd_soc_read(codec, base + ARIZONA_AIF_FORMAT); + if (params_channels(params) == 1 && (val & ARIZONA_AIF1_FMT_MASK)) { + arizona_aif_dbg(dai, "Forcing stereo mode\n"); + bclk_target *= 2; + } + for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) { if (rates[i] >= bclk_target && rates[i] % params_rate(params) == 0) { -- cgit v1.2.3 From da4f2f9e6b59d9236fec1d5cfc85dd3b5679d1b3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 14 Mar 2013 00:19:20 -0700 Subject: ASoC: fsi: use snd_soc_register_component() instead of snd_soc_register_dais() Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index c724026a246f..254c6375f7a1 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1886,6 +1886,10 @@ static struct snd_soc_platform_driver fsi_soc_platform = { .pcm_free = fsi_pcm_free, }; +static const struct snd_soc_component_driver fsi_soc_component = { + .name = "fsi", +}; + /* * platform function */ @@ -2046,10 +2050,10 @@ static int fsi_probe(struct platform_device *pdev) goto exit_fsib; } - ret = snd_soc_register_dais(&pdev->dev, fsi_soc_dai, - ARRAY_SIZE(fsi_soc_dai)); + ret = snd_soc_register_component(&pdev->dev, &fsi_soc_component, + fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); if (ret < 0) { - dev_err(&pdev->dev, "cannot snd dai register\n"); + dev_err(&pdev->dev, "cannot snd component register\n"); goto exit_snd_soc; } @@ -2074,7 +2078,7 @@ static int fsi_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); + snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_platform(&pdev->dev); fsi_stream_remove(&master->fsia); -- cgit v1.2.3 From 2fb148804fe50639be4c5addb9e28aad0fce1687 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 20 Mar 2013 02:22:40 -0300 Subject: ASoC: fsl: imx-pcm-fiq: Use 'unsigned int' for period Fix the following warning when building with W=1 option: sound/soc/fsl/imx-pcm-fiq.c: In function 'snd_hrtimer_callback': sound/soc/fsl/imx-pcm-fiq.c:76:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- sound/soc/fsl/imx-pcm-fiq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 920f945cb2f4..47228c0f929e 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c @@ -34,7 +34,7 @@ #include "imx-ssi.h" struct imx_pcm_runtime_data { - int period; + unsigned int period; int periods; unsigned long offset; unsigned long last_offset; -- cgit v1.2.3 From 623766318aeb5f8dee83b2e8926c39cf83568197 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 20 Mar 2013 10:47:12 +0100 Subject: ASoC: omap-mcpdm: Collect link direction configuration under a struct mcpdm_link_config will collect the link direction related configurations like channel masks, FIFO threshold. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index ddfcc1834ff0..6e19f440a28c 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -45,6 +45,11 @@ #define OMAP44XX_MCPDM_L3_BASE 0x49032000 +struct mcpdm_link_config { + u32 link_mask; /* channel mask for the direction */ + u32 threshold; /* FIFO threshold */ +}; + struct omap_mcpdm { struct device *dev; unsigned long phys_base; @@ -53,13 +58,8 @@ struct omap_mcpdm { struct mutex mutex; - /* channel data */ - u32 dn_channels; - u32 up_channels; - - /* McPDM FIFO thresholds */ - u32 dn_threshold; - u32 up_threshold; + /* Playback/Capture configuration */ + struct mcpdm_link_config config[2]; /* McPDM dn offsets for rx1, and 2 channels */ u32 dn_rx_offset; @@ -130,11 +130,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {} static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) { u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); + u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask; ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); - ctrl |= mcpdm->dn_channels | mcpdm->up_channels; + ctrl |= link_mask; omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); @@ -148,11 +149,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) { u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); + u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask; ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); - ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels); + ctrl &= ~(link_mask); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); @@ -188,8 +190,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm) omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); } - omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold); - omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold); + omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, + mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold); + omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, + mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold); omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET, MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE); @@ -296,6 +300,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); int stream = substream->stream; struct omap_pcm_dma_data *dma_data; + u32 threshold; int channels; int link_mask = 0; @@ -325,15 +330,16 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, dma_data = snd_soc_dai_get_dma_data(dai, substream); + threshold = mcpdm->config[stream].threshold; /* Configure McPDM channels, and DMA packet size */ if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - mcpdm->dn_channels = link_mask << 3; + link_mask <<= 3; dma_data->packet_size = - (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels; + (MCPDM_DN_THRES_MAX - threshold) * channels; } else { - mcpdm->up_channels = link_mask << 0; - dma_data->packet_size = mcpdm->up_threshold * channels; + dma_data->packet_size = threshold * channels; } + mcpdm->config[stream].link_mask = link_mask; return 0; } @@ -380,8 +386,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) } /* Configure McPDM threshold values */ - mcpdm->dn_threshold = 2; - mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3; + mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2; + mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold = + MCPDM_UP_THRES_MAX - 3; return ret; } -- cgit v1.2.3 From 81054b226b76145628670a962674ab312690ab86 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 20 Mar 2013 10:47:13 +0100 Subject: ASoC: omap-mcpdm: Fix for full duplex audio use case Due to HW limitation within OMAP McPDM IP uplink and downlink need to be started at the same time. This causes issues when we have two streams running, for example: arecord | aplay In this case the playback stream would have no channels enabled since at the capture start we are not aware that a playback is going to start. The workaround is to configure the other direction to stereo when the first stream is started. When the second stream is coming we check the new stream's number of channels against the pre-configured channels. If it does not match we stop and restart McPDM to update the configuration. This might result a small pop. If the coming stream is a match we do nothing in the McPDM driver. This workaround can handle most use cases without the need to restart McPDM. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 6e19f440a28c..cd0e2ec90128 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -63,6 +63,9 @@ struct omap_mcpdm { /* McPDM dn offsets for rx1, and 2 channels */ u32 dn_rx_offset; + + /* McPDM needs to be restarted due to runtime reconfiguration */ + bool restart; }; /* @@ -149,7 +152,7 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) { u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); - u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask; + u32 link_mask = MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK; ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); @@ -287,6 +290,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, if (omap_mcpdm_active(mcpdm)) { omap_mcpdm_stop(mcpdm); omap_mcpdm_close_streams(mcpdm); + mcpdm->config[0].link_mask = 0; + mcpdm->config[1].link_mask = 0; } } @@ -334,11 +339,26 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, /* Configure McPDM channels, and DMA packet size */ if (stream == SNDRV_PCM_STREAM_PLAYBACK) { link_mask <<= 3; + + /* If capture is not running assume a stereo stream to come */ + if (!mcpdm->config[!stream].link_mask) + mcpdm->config[!stream].link_mask = 0x3; + dma_data->packet_size = (MCPDM_DN_THRES_MAX - threshold) * channels; } else { + /* If playback is not running assume a stereo stream to come */ + if (!mcpdm->config[!stream].link_mask) + mcpdm->config[!stream].link_mask = (0x3 << 3); + dma_data->packet_size = threshold * channels; } + + /* Check if we need to restart McPDM with this stream */ + if (mcpdm->config[stream].link_mask && + mcpdm->config[stream].link_mask != link_mask) + mcpdm->restart = true; + mcpdm->config[stream].link_mask = link_mask; return 0; @@ -352,6 +372,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, if (!omap_mcpdm_active(mcpdm)) { omap_mcpdm_start(mcpdm); omap_mcpdm_reg_dump(mcpdm); + } else if (mcpdm->restart) { + omap_mcpdm_stop(mcpdm); + omap_mcpdm_start(mcpdm); + mcpdm->restart = false; + omap_mcpdm_reg_dump(mcpdm); } return 0; -- cgit v1.2.3 From 167b5b93a4d53f29d4fda55f96116f525b2eb3d6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 20 Mar 2013 10:47:14 +0100 Subject: ASoC: omap-mcpdm: Remove leftower define for IO address The IO address is no longer hardwired into the driver. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index cd0e2ec90128..e1d3998cb0a5 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -43,8 +43,6 @@ #include "omap-mcpdm.h" #include "omap-pcm.h" -#define OMAP44XX_MCPDM_L3_BASE 0x49032000 - struct mcpdm_link_config { u32 link_mask; /* channel mask for the direction */ u32 threshold; /* FIFO threshold */ -- cgit v1.2.3 From 18b97dbe86735502794ba988d4171dc531d8a589 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Mar 2013 18:57:24 +0100 Subject: ASoC: spear_pcm: Staticize non-exported structs Signed-off-by: Lars-Peter Clausen Acked-by: Rajeev Kumar Signed-off-by: Mark Brown --- sound/soc/spear/spear_pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 9b76cc5a1148..69803919b838 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -25,7 +25,7 @@ #include #include -struct snd_pcm_hardware spear_pcm_hardware = { +static struct snd_pcm_hardware spear_pcm_hardware = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), @@ -178,7 +178,7 @@ static int spear_pcm_new(struct snd_card *card, return 0; } -struct snd_soc_platform_driver spear_soc_platform = { +static struct snd_soc_platform_driver spear_soc_platform = { .ops = &spear_pcm_ops, .pcm_new = spear_pcm_new, .pcm_free = spear_pcm_free, -- cgit v1.2.3 From 00aa0fac76c2f3b5a3543a63798af12c6d48b9b1 Mon Sep 17 00:00:00 2001 From: Alban Bedel Date: Wed, 20 Mar 2013 17:37:32 +0100 Subject: ASoC: wm8903: Add the DAC boost control Signed-off-by: Alban Bedel Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 134e41c870b9..70e5eb200485 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -478,6 +478,8 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, /* ALSA can only do steps of .01dB */ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); +static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0); + static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0); static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); @@ -698,6 +700,8 @@ SOC_ENUM("DAC Mute Mode", mute_mode), SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), SOC_ENUM("DAC Companding Mode", dac_companding), SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), +SOC_SINGLE_TLV("DAC Boost Volume", WM8903_AUDIO_INTERFACE_0, 9, 3, 0, + dac_boost_tlv), SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, wm8903_get_deemph, wm8903_put_deemph), -- cgit v1.2.3 From 3cf956eebe54cdb7cf1701642085507f0354e56a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 20 Mar 2013 10:12:10 +0100 Subject: ASoC: wm8994: Support constraining the maximum number of channels clocked Some systems use the audio CODEC to clock a DAI with multiple data lines in parallel, meaning that bit clocks are only required for a smaller number of channels than data is sent for. In some cases providing the extra bit clocks can take the other devices on the audio bus out of spec. Support such systems by allowing a maximum number of channels to be specified. Signed-off-by: Mark Brown --- include/linux/mfd/wm8994/pdata.h | 8 ++++++++ sound/soc/codecs/wm8994.c | 13 +++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 8e21a094836d..68e776594889 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -17,6 +17,7 @@ #define WM8994_NUM_LDO 2 #define WM8994_NUM_GPIO 11 +#define WM8994_NUM_AIF 3 struct wm8994_ldo_pdata { /** GPIOs to enable regulator, 0 or less if not available */ @@ -215,6 +216,13 @@ struct wm8994_pdata { * system. */ bool spkmode_pu; + + /** + * Maximum number of channels clocks will be generated for, + * useful for systems where and I2S bus with multiple data + * lines is mastered. + */ + int max_channels_clocked[WM8994_NUM_AIF]; }; #endif diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index c9bd445c4976..318ea64b9800 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2656,6 +2656,8 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_codec *codec = dai->codec; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; int aif1_reg; int aif2_reg; int bclk_reg; @@ -2723,7 +2725,14 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, } wm8994->channels[id] = params_channels(params); - switch (params_channels(params)) { + if (pdata->max_channels_clocked[id] && + wm8994->channels[id] > pdata->max_channels_clocked[id]) { + dev_dbg(dai->dev, "Constraining channels to %d from %d\n", + pdata->max_channels_clocked[id], wm8994->channels[id]); + wm8994->channels[id] = pdata->max_channels_clocked[id]; + } + + switch (wm8994->channels[id]) { case 1: case 2: bclk_rate *= 2; @@ -2745,7 +2754,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", dai->id, wm8994->aifclk[id], bclk_rate); - if (params_channels(params) == 1 && + if (wm8994->channels[id] == 1 && (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18) aif2 |= WM8994_AIF1_MONO; -- cgit v1.2.3 From 56447e1324009d7e3cec40e3cc2987843b59a00f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 10 Jan 2013 14:45:58 +0000 Subject: ASoC: arizona: Factor out speaker widgets from CODEC drivers Some system designs have been identified which repurpose portions of the speaker driver circuits for other functions which will require that they not be managed using DAPM. Prepare for this by factoring out the creation of the speaker widgets into the core driver, the widgets will be replaced by dummy ones when the additional functions are enabled. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/arizona.h | 5 +++ sound/soc/codecs/wm5102.c | 52 ++--------------------------- sound/soc/codecs/wm5110.c | 6 ---- 4 files changed, 89 insertions(+), 56 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 2b0803ec8234..009810b8c667 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,87 @@ #define arizona_aif_dbg(_dai, fmt, ...) \ dev_dbg(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__) +static int arizona_spk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_codec *codec = w->codec; + struct arizona *arizona = dev_get_drvdata(codec->dev->parent); + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + bool manual_ena = false; + + switch (arizona->type) { + case WM5102: + switch (arizona->rev) { + case 0: + break; + default: + manual_ena = true; + break; + } + default: + break; + } + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (!priv->spk_ena && manual_ena) { + snd_soc_write(codec, 0x4f5, 0x25a); + priv->spk_ena_pending = true; + } + break; + case SND_SOC_DAPM_POST_PMU: + if (priv->spk_ena_pending) { + msleep(75); + snd_soc_write(codec, 0x4f5, 0xda); + priv->spk_ena_pending = false; + priv->spk_ena++; + } + break; + case SND_SOC_DAPM_PRE_PMD: + if (manual_ena) { + priv->spk_ena--; + if (!priv->spk_ena) + snd_soc_write(codec, 0x4f5, 0x25a); + } + break; + case SND_SOC_DAPM_POST_PMD: + if (manual_ena) { + if (!priv->spk_ena) + snd_soc_write(codec, 0x4f5, 0x0da); + } + break; + } + + return 0; +} + +static const struct snd_soc_dapm_widget arizona_spkl = + SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); + +static const struct snd_soc_dapm_widget arizona_spkr = + SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); + +int arizona_init_spk(struct snd_soc_codec *codec) +{ + int ret; + + ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1); + if (ret != 0) + return ret; + + ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1); + if (ret != 0) + return ret; + + return 0; +} +EXPORT_SYMBOL_GPL(arizona_init_spk); + const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { "None", "Tone Generator 1", diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 572f11bc90b4..9399940f700d 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -76,6 +76,9 @@ struct arizona_priv { int num_inputs; unsigned int in_pending; + + unsigned int spk_ena:2; + unsigned int spk_ena_pending:1; }; #define ARIZONA_NUM_MIXER_INPUTS 99 @@ -228,6 +231,8 @@ extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source, extern int arizona_set_fll(struct arizona_fll *fll, int source, unsigned int Fref, unsigned int Fout); +extern int arizona_init_spk(struct snd_soc_codec *codec); + extern int arizona_init_dai(struct arizona_priv *priv, int dai); int arizona_set_output_mode(struct snd_soc_codec *codec, int output, diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 44d4c69d25e5..97757bc5fd0e 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -36,9 +36,6 @@ struct wm5102_priv { struct arizona_priv core; struct arizona_fll fll[2]; - - unsigned int spk_ena:2; - unsigned int spk_ena_pending:1; }; static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); @@ -817,47 +814,6 @@ ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE), }; -static int wm5102_spk_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, - int event) -{ - struct snd_soc_codec *codec = w->codec; - struct arizona *arizona = dev_get_drvdata(codec->dev->parent); - struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec); - - if (arizona->rev < 1) - return 0; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (!wm5102->spk_ena) { - snd_soc_write(codec, 0x4f5, 0x25a); - wm5102->spk_ena_pending = true; - } - break; - case SND_SOC_DAPM_POST_PMU: - if (wm5102->spk_ena_pending) { - msleep(75); - snd_soc_write(codec, 0x4f5, 0xda); - wm5102->spk_ena_pending = false; - wm5102->spk_ena++; - } - break; - case SND_SOC_DAPM_PRE_PMD: - wm5102->spk_ena--; - if (!wm5102->spk_ena) - snd_soc_write(codec, 0x4f5, 0x25a); - break; - case SND_SOC_DAPM_POST_PMD: - if (!wm5102->spk_ena) - snd_soc_write(codec, 0x4f5, 0x0da); - break; - } - - return 0; -} - - ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE); ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE); @@ -1141,12 +1097,6 @@ SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1, SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, wm5102_spk_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), @@ -1586,6 +1536,8 @@ static int wm5102_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/wm5110.c b/sound/soc/codecs/wm5110.c index a64d3b8bc3b4..b6329c8c19df 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -577,12 +577,6 @@ SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1, SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), -- cgit v1.2.3 From 899817e27a58038546b53bc42eeaa4aae5a886cb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 13 Mar 2013 12:32:10 +0000 Subject: ASoC: arizona: Log thermal events Help with debuggability. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 009810b8c667..895ddf007de2 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -122,6 +122,42 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, return 0; } +static irqreturn_t arizona_thermal_warn(int irq, void *data) +{ + struct arizona *arizona = data; + unsigned int val; + int ret; + + ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, + &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read thermal status: %d\n", + ret); + } else if (val & ARIZONA_SPK_SHUTDOWN_WARN_STS) { + dev_crit(arizona->dev, "Thermal warning\n"); + } + + return IRQ_HANDLED; +} + +static irqreturn_t arizona_thermal_shutdown(int irq, void *data) +{ + struct arizona *arizona = data; + unsigned int val; + int ret; + + ret = regmap_read(arizona->regmap, ARIZONA_INTERRUPT_RAW_STATUS_3, + &val); + if (ret != 0) { + dev_err(arizona->dev, "Failed to read thermal status: %d\n", + ret); + } else if (val & ARIZONA_SPK_SHUTDOWN_STS) { + dev_crit(arizona->dev, "Thermal shutdown\n"); + } + + return IRQ_HANDLED; +} + static const struct snd_soc_dapm_widget arizona_spkl = SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, @@ -134,6 +170,8 @@ static const struct snd_soc_dapm_widget arizona_spkr = int arizona_init_spk(struct snd_soc_codec *codec) { + struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->arizona; int ret; ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1); @@ -144,6 +182,22 @@ int arizona_init_spk(struct snd_soc_codec *codec) if (ret != 0) return ret; + ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN, + "Thermal warning", arizona_thermal_warn, + arizona); + if (ret != 0) + dev_err(arizona->dev, + "Failed to get thermal warning IRQ: %d\n", + ret); + + ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN, + "Thermal shutdown", arizona_thermal_shutdown, + arizona); + if (ret != 0) + dev_err(arizona->dev, + "Failed to get thermal shutdown IRQ: %d\n", + ret); + return 0; } EXPORT_SYMBOL_GPL(arizona_init_spk); -- cgit v1.2.3 From f4a76e7cc6d1c402e990e2111fb94afb305fb974 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 13 Mar 2013 12:22:39 +0000 Subject: ASoC: arizona: Suppress speaker enable if thermal shutdown is flagged Ensure that the device state does not diverge from the state we have set in the register map in order to make the behaviour clearer. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 895ddf007de2..6c773804ffe0 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -75,6 +75,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, struct arizona *arizona = dev_get_drvdata(codec->dev->parent); struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); bool manual_ena = false; + int val; switch (arizona->type) { case WM5102: @@ -97,6 +98,16 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, } break; case SND_SOC_DAPM_POST_PMU: + val = snd_soc_read(codec, ARIZONA_INTERRUPT_RAW_STATUS_3); + if (val & ARIZONA_SPK_SHUTDOWN_STS) { + dev_crit(arizona->dev, + "Speaker not enabled due to temperature\n"); + return -EBUSY; + } + + snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, + 1 << w->shift, 1 << w->shift); + if (priv->spk_ena_pending) { msleep(75); snd_soc_write(codec, 0x4f5, 0xda); @@ -110,6 +121,9 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w, if (!priv->spk_ena) snd_soc_write(codec, 0x4f5, 0x25a); } + + snd_soc_update_bits(codec, ARIZONA_OUTPUT_ENABLES_1, + 1 << w->shift, 0); break; case SND_SOC_DAPM_POST_PMD: if (manual_ena) { @@ -153,18 +167,26 @@ static irqreturn_t arizona_thermal_shutdown(int irq, void *data) ret); } else if (val & ARIZONA_SPK_SHUTDOWN_STS) { dev_crit(arizona->dev, "Thermal shutdown\n"); + ret = regmap_update_bits(arizona->regmap, + ARIZONA_OUTPUT_ENABLES_1, + ARIZONA_OUT4L_ENA | + ARIZONA_OUT4R_ENA, 0); + if (ret != 0) + dev_crit(arizona->dev, + "Failed to disable speaker outputs: %d\n", + ret); } return IRQ_HANDLED; } static const struct snd_soc_dapm_widget arizona_spkl = - SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1, + SND_SOC_DAPM_PGA_E("OUT4L", SND_SOC_NOPM, ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); static const struct snd_soc_dapm_widget arizona_spkr = - SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1, + SND_SOC_DAPM_PGA_E("OUT4R", SND_SOC_NOPM, ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_spk_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU); -- cgit v1.2.3 From dc91428a6152b2c8428a39a27ab9b5e429848f55 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 18 Feb 2013 19:09:23 +0000 Subject: ASoC: arizona: Basic support for ISRC rate selection Since ASoC does not yet really have the framework features needed to support propagating sample rates through the device well yet implement basic support for the ISRCs equivalent to that we currently have for the ASRCs. The user can opt for 8kHz or 16kHz as the rate for the DSP blocks in addition to the main audio rate, these being the primary use cases. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 27 +++++++++++++++++++++++++++ sound/soc/codecs/arizona.h | 6 ++++++ sound/soc/codecs/wm5102.c | 11 ++++++++++- sound/soc/codecs/wm_adsp.c | 24 ++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 6c773804ffe0..26e1579c36cb 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -433,6 +433,33 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values); const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); EXPORT_SYMBOL_GPL(arizona_mixer_tlv); +const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { + "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", +}; +EXPORT_SYMBOL_GPL(arizona_rate_text); + +const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE] = { + 0, 1, 2, 8, +}; +EXPORT_SYMBOL_GPL(arizona_rate_val); + + +const struct soc_enum arizona_isrc_fsl[] = { + SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_1_CTRL_2, + ARIZONA_ISRC1_FSL_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), + SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_2_CTRL_2, + ARIZONA_ISRC2_FSL_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), + SOC_VALUE_ENUM_SINGLE(ARIZONA_ISRC_3_CTRL_2, + ARIZONA_ISRC3_FSL_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), +}; +EXPORT_SYMBOL_GPL(arizona_isrc_fsl); + static const char *arizona_vol_ramp_text[] = { "0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB", "15ms/6dB", "30ms/6dB", diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 9399940f700d..a754a1c0217f 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -180,6 +180,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MIXER_ROUTES(name, name "L"), \ ARIZONA_MIXER_ROUTES(name, name "R") +#define ARIZONA_RATE_ENUM_SIZE 4 +extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; +extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; + +extern const struct soc_enum arizona_isrc_fsl[]; + extern const struct soc_enum arizona_in_vi_ramp; extern const struct soc_enum arizona_in_vd_ramp; diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 97757bc5fd0e..a0084b1febdb 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -731,6 +731,9 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), +SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), + ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), @@ -1532,7 +1535,7 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; - ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 1); + ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2); if (ret != 0) return ret; @@ -1624,6 +1627,12 @@ static int wm5102_probe(struct platform_device *pdev) ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK, &wm5102->fll[1]); + /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */ + regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2, + ARIZONA_SAMPLE_RATE_2_MASK, 0x11); + regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3, + ARIZONA_SAMPLE_RATE_3_MASK, 0x12); + for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++) arizona_init_dai(&wm5102->core, i); diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f3f7e75f8628..3a481fd1bf9a 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -31,6 +31,7 @@ #include +#include "arizona.h" #include "wm_adsp.h" #define adsp_crit(_dsp, fmt, ...) \ @@ -246,15 +247,38 @@ static const struct soc_enum wm_adsp_fw_enum[] = { SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), }; +static const struct soc_enum wm_adsp_rate_enum[] = { + SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1, + ARIZONA_DSP1_RATE_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), + SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1, + ARIZONA_DSP1_RATE_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), + SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1, + ARIZONA_DSP1_RATE_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), + SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1, + ARIZONA_DSP1_RATE_SHIFT, 0xf, + ARIZONA_RATE_ENUM_SIZE, + arizona_rate_text, arizona_rate_val), +}; + const struct snd_kcontrol_new wm_adsp_fw_controls[] = { SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], wm_adsp_fw_get, wm_adsp_fw_put), + SOC_ENUM("DSP1 Rate", wm_adsp_rate_enum[0]), SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], wm_adsp_fw_get, wm_adsp_fw_put), + SOC_ENUM("DSP2 Rate", wm_adsp_rate_enum[1]), SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], wm_adsp_fw_get, wm_adsp_fw_put), + SOC_ENUM("DSP3 Rate", wm_adsp_rate_enum[2]), SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], wm_adsp_fw_get, wm_adsp_fw_put), + SOC_ENUM("DSP4 Rate", wm_adsp_rate_enum[3]), }; EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); -- cgit v1.2.3 From d3725761ee3d4813c6071ea1d952de1094d8b68f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 29 Jan 2013 23:17:12 +0800 Subject: ASoC: wm8994: Restore AIFnCLK after reducing it for low clock rates This helps to ensure a smooth startup when we restore. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 32 ++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8994.h | 1 + 2 files changed, 33 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 318ea64b9800..1c02a47910e4 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2268,10 +2268,26 @@ out: */ if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); + + wm8994->aifdiv[0] = snd_soc_read(codec, WM8994_AIF1_RATE) + & WM8994_AIF1CLK_RATE_MASK; + wm8994->aifdiv[1] = snd_soc_read(codec, WM8994_AIF2_RATE) + & WM8994_AIF1CLK_RATE_MASK; + snd_soc_update_bits(codec, WM8994_AIF1_RATE, WM8994_AIF1CLK_RATE_MASK, 0x1); snd_soc_update_bits(codec, WM8994_AIF2_RATE, WM8994_AIF2CLK_RATE_MASK, 0x1); + } else if (wm8994->aifdiv[0]) { + snd_soc_update_bits(codec, WM8994_AIF1_RATE, + WM8994_AIF1CLK_RATE_MASK, + wm8994->aifdiv[0]); + snd_soc_update_bits(codec, WM8994_AIF2_RATE, + WM8994_AIF2CLK_RATE_MASK, + wm8994->aifdiv[1]); + + wm8994->aifdiv[0] = 0; + wm8994->aifdiv[1] = 0; } return 0; @@ -2368,10 +2384,26 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, */ if (max(wm8994->aifclk[0], wm8994->aifclk[1]) < 50000) { dev_dbg(codec->dev, "Configuring AIFs for 128fs\n"); + + wm8994->aifdiv[0] = snd_soc_read(codec, WM8994_AIF1_RATE) + & WM8994_AIF1CLK_RATE_MASK; + wm8994->aifdiv[1] = snd_soc_read(codec, WM8994_AIF2_RATE) + & WM8994_AIF1CLK_RATE_MASK; + snd_soc_update_bits(codec, WM8994_AIF1_RATE, WM8994_AIF1CLK_RATE_MASK, 0x1); snd_soc_update_bits(codec, WM8994_AIF2_RATE, WM8994_AIF2CLK_RATE_MASK, 0x1); + } else if (wm8994->aifdiv[0]) { + snd_soc_update_bits(codec, WM8994_AIF1_RATE, + WM8994_AIF1CLK_RATE_MASK, + wm8994->aifdiv[0]); + snd_soc_update_bits(codec, WM8994_AIF2_RATE, + WM8994_AIF2CLK_RATE_MASK, + wm8994->aifdiv[1]); + + wm8994->aifdiv[0] = 0; + wm8994->aifdiv[1] = 0; } return 0; diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 45f192702024..928e2c256450 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -79,6 +79,7 @@ struct wm8994_priv { int sysclk_rate[2]; int mclk[2]; int aifclk[2]; + int aifdiv[2]; int channels[2]; struct wm8994_fll_config fll[2], fll_suspend[2]; struct completion fll_locked[2]; -- cgit v1.2.3 From 8abfc2608ba6f6c4bae0931149504fe33d1332a6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:27:59 -0700 Subject: ASoC: pxa2xx-ac97: move EXPORT_SYMBOL_GPL() next to definition Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/pxa/pxa2xx-ac97.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 4b0a009bd683..88d2cc6a0ae2 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -47,6 +47,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = { .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", @@ -232,8 +233,6 @@ static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = { }, }; -EXPORT_SYMBOL_GPL(soc_ac97_ops); - static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) { if (pdev->id != -1) { -- cgit v1.2.3 From fa659d830df0bad8fc3a3815a7f36bd8b7ed9254 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 25 Mar 2013 11:19:12 +0800 Subject: ASoC: imx-sgtl5000: use of_node to match cpu dai Since imx-sgtl5000 is only used on DT platform, it makes more sense to use cpu_of_node rather than cpu_dai_name to match cpu dai. Signed-off-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/fsl/imx-sgtl5000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 424347e9b2d7..9584e78858df 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -148,7 +148,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) data->dai.stream_name = "HiFi"; data->dai.codec_dai_name = "sgtl5000"; data->dai.codec_of_node = codec_np; - data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev); + data->dai.cpu_of_node = ssi_np; data->dai.platform_name = "imx-pcm-audio"; data->dai.init = &imx_sgtl5000_dai_init; data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -- cgit v1.2.3 From 95d36075694b0431da22c3aef3d0dccdcc781344 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 21 Mar 2013 13:56:41 -0600 Subject: ASoC: tegra: add Tegra114 support to the AHUB driver Tegra114's AHUB shares a design with Tegra30, with the followin changes: * Supports more (10 vs. 4) bi-directional FIFO channels into RAM. * Requires a separate block of registers to support the above. * Supports more attached clients, i.e. new audio multiplexing and de-multiplexing modules. * Is affected by more clocks due to the above. This change fully defines the device tree binding changes required to represent these changes, and minimally extends the driver to support the new hardware, without exposing any of the new FIFO channels. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- .../bindings/sound/nvidia,tegra30-ahub.txt | 26 +++++++-- sound/soc/tegra/tegra30_ahub.c | 64 ++++++++++++++++------ sound/soc/tegra/tegra30_ahub.h | 16 ++++++ 3 files changed, 84 insertions(+), 22 deletions(-) (limited to 'sound/soc') diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt index 1ac7b1642186..0e5c12c66523 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra30-ahub.txt @@ -1,12 +1,22 @@ NVIDIA Tegra30 AHUB (Audio Hub) Required properties: -- compatible : "nvidia,tegra30-ahub" +- compatible : "nvidia,tegra30-ahub", "nvidia,tegra114-ahub", etc. - reg : Should contain the register physical address and length for each of - the AHUB's APBIF registers and the AHUB's own registers. + the AHUB's register blocks. + - Tegra30 requires 2 entries, for the APBIF and AHUB/AUDIO register blocks. + - Tegra114 requires an additional entry, for the APBIF2 register block. - interrupts : Should contain AHUB interrupt -- nvidia,dma-request-selector : The Tegra DMA controller's phandle and - request selector for the first APBIF channel. +- nvidia,dma-request-selector : A list of the DMA channel specifiers. Each + entry contains the Tegra DMA controller's phandle and request selector. + If a single entry is present, the request selectors for the channels are + assumed to be contiguous, and increment from this value. + If multiple values are given, one value must be given per channel. +- clocks : Must contain an entry for each required entry in clock-names. +- clock-names : Must include the following entries: + - Tegra30: Requires d_audio, apbif, i2s0, i2s1, i2s2, i2s3, i2s4, dam0, + dam1, dam2, spdif_in. + - Tegra114: Additionally requires amx, adx. - ranges : The bus address mapping for the configlink register bus. Can be empty since the mapping is 1:1. - #address-cells : For the configlink bus. Should be <1>; @@ -25,7 +35,13 @@ ahub@70080000 { reg = <0x70080000 0x200 0x70080200 0x100>; interrupts = < 0 103 0x04 >; nvidia,dma-request-selector = <&apbdma 1>; - + clocks = <&tegra_car 106>, <&tegra_car 107>, <&tegra_car 30>, + <&tegra_car 11>, <&tegra_car 18>, <&tegra_car 101>, + <&tegra_car 102>, <&tegra_car 108>, <&tegra_car 109>, + <&tegra_car 110>, <&tegra_car 162>; + clock-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2", + "i2s3", "i2s4", "dam0", "dam1", "dam2", + "spdif_in"; ranges; #address-cells = <1>; #size-cells = <1>; diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index e5cfb4ac41ba..4405c3a8c08c 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -287,16 +287,27 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif) } EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); -static const char * const configlink_clocks[] = { - "i2s0", - "i2s1", - "i2s2", - "i2s3", - "i2s4", - "dam0", - "dam1", - "dam2", - "spdif_in", +#define CLK_LIST_MASK_TEGRA30 BIT(0) +#define CLK_LIST_MASK_TEGRA114 BIT(1) + +#define CLK_LIST_MASK_TEGRA30_OR_LATER \ + (CLK_LIST_MASK_TEGRA30 | CLK_LIST_MASK_TEGRA114) + +static const struct { + const char *clk_name; + u32 clk_list_mask; +} configlink_clocks[] = { + { "i2s0", CLK_LIST_MASK_TEGRA30_OR_LATER }, + { "i2s1", CLK_LIST_MASK_TEGRA30_OR_LATER }, + { "i2s2", CLK_LIST_MASK_TEGRA30_OR_LATER }, + { "i2s3", CLK_LIST_MASK_TEGRA30_OR_LATER }, + { "i2s4", CLK_LIST_MASK_TEGRA30_OR_LATER }, + { "dam0", CLK_LIST_MASK_TEGRA30_OR_LATER }, + { "dam1", CLK_LIST_MASK_TEGRA30_OR_LATER }, + { "dam2", CLK_LIST_MASK_TEGRA30_OR_LATER }, + { "spdif_in", CLK_LIST_MASK_TEGRA30_OR_LATER }, + { "amx", CLK_LIST_MASK_TEGRA114 }, + { "adx", CLK_LIST_MASK_TEGRA114 }, }; #define LAST_REG(name) \ @@ -424,8 +435,24 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = { .cache_type = REGCACHE_RBTREE, }; +static struct tegra30_ahub_soc_data soc_data_tegra30 = { + .clk_list_mask = CLK_LIST_MASK_TEGRA30, +}; + +static struct tegra30_ahub_soc_data soc_data_tegra114 = { + .clk_list_mask = CLK_LIST_MASK_TEGRA114, +}; + +static const struct of_device_id tegra30_ahub_of_match[] = { + { .compatible = "nvidia,tegra114-ahub", .data = &soc_data_tegra114 }, + { .compatible = "nvidia,tegra30-ahub", .data = &soc_data_tegra30 }, + {}, +}; + static int tegra30_ahub_probe(struct platform_device *pdev) { + const struct of_device_id *match; + const struct tegra30_ahub_soc_data *soc_data; struct clk *clk; int i; struct resource *res0, *res1, *region; @@ -436,16 +463,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev) if (ahub) return -ENODEV; + match = of_match_device(tegra30_ahub_of_match, &pdev->dev); + if (!match) + return -EINVAL; + soc_data = match->data; + /* * The AHUB hosts a register bus: the "configlink". For this to * operate correctly, all devices on this bus must be out of reset. * Ensure that here. */ for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { - clk = clk_get(&pdev->dev, configlink_clocks[i]); + if (!(configlink_clocks[i].clk_list_mask & + soc_data->clk_list_mask)) + continue; + clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name); if (IS_ERR(clk)) { dev_err(&pdev->dev, "Can't get clock %s\n", - configlink_clocks[i]); + configlink_clocks[i].clk_name); ret = PTR_ERR(clk); goto err; } @@ -592,11 +627,6 @@ static int tegra30_ahub_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id tegra30_ahub_of_match[] = { - { .compatible = "nvidia,tegra30-ahub", }, - {}, -}; - static const struct dev_pm_ops tegra30_ahub_pm_ops = { SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend, tegra30_ahub_runtime_resume, NULL) diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h index e690e2eecc92..7189be9e2970 100644 --- a/sound/soc/tegra/tegra30_ahub.h +++ b/sound/soc/tegra/tegra30_ahub.h @@ -468,7 +468,23 @@ extern int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif, enum tegra30_ahub_txcif txcif); extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif); +struct tegra30_ahub_soc_data { + u32 clk_list_mask; + /* + * FIXME: There are many more differences in HW, such as: + * - More APBIF channels. + * - Extra separate chunks of register address space to represent + * the extra APBIF channels. + * - More units connected to the AHUB, so that tegra30_ahub_[rt]xcif + * need expansion, coupled with there being more defined bits in + * the AHUB routing registers. + * However, the driver doesn't support those new features yet, so we + * don't represent them here yet. + */ +}; + struct tegra30_ahub { + const struct tegra30_ahub_soc_data *soc_data; struct device *dev; struct clk *clk_d_audio; struct clk *clk_apbif; -- cgit v1.2.3 From a7fc5d256be9fda27bb69e872e6a212542a84230 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 21 Mar 2013 13:56:42 -0600 Subject: ASoC: tegra: add Tegra114 support to tegra_asoc_utils.c Tegra114 requires different PLL rates. Modify the code to know about this. On Tegra114 only for now, use regular clk_get() rather than clk_get_sys() to retrieve clocks. This assumes that the clocks will be represented in device tree. We can assure that from the start of any Tegra114 audio support. For older chips, I'll add the required clocks properties to the device trees this kernel cycle, and switch this code to only support the "new_clocks" path next cycle. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_asoc_utils.c | 30 ++++++++++++++++++++++++------ sound/soc/tegra/tegra_asoc_utils.h | 1 + 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c index 49861c6ed874..24fb001be7f4 100644 --- a/sound/soc/tegra/tegra_asoc_utils.c +++ b/sound/soc/tegra/tegra_asoc_utils.c @@ -43,8 +43,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, case 88200: if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) new_baseclock = 56448000; - else + else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30) new_baseclock = 564480000; + else + new_baseclock = 282240000; break; case 8000: case 16000: @@ -54,8 +56,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate, case 96000: if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) new_baseclock = 73728000; - else + else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30) new_baseclock = 552960000; + else + new_baseclock = 368640000; break; default: return -EINVAL; @@ -169,6 +173,7 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev) { int ret; + bool new_clocks = false; data->dev = dev; @@ -176,24 +181,37 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; else if (of_machine_is_compatible("nvidia,tegra30")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; - else + else if (of_machine_is_compatible("nvidia,tegra114")) { + data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114; + new_clocks = true; + } else { + dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n"); return -EINVAL; + } - data->clk_pll_a = clk_get_sys(NULL, "pll_a"); + if (new_clocks) + data->clk_pll_a = clk_get(dev, "pll_a"); + else + data->clk_pll_a = clk_get_sys(NULL, "pll_a"); if (IS_ERR(data->clk_pll_a)) { dev_err(data->dev, "Can't retrieve clk pll_a\n"); ret = PTR_ERR(data->clk_pll_a); goto err; } - data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); + if (new_clocks) + data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0"); + else + data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); if (IS_ERR(data->clk_pll_a_out0)) { dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); ret = PTR_ERR(data->clk_pll_a_out0); goto err_put_pll_a; } - if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) + if (new_clocks) + data->clk_cdev1 = clk_get(dev, "mclk"); + else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); else data->clk_cdev1 = clk_get_sys("extern1", NULL); diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h index 974c9f8830f9..19fdcafed32f 100644 --- a/sound/soc/tegra/tegra_asoc_utils.h +++ b/sound/soc/tegra/tegra_asoc_utils.h @@ -29,6 +29,7 @@ struct device; enum tegra_asoc_utils_soc { TEGRA_ASOC_UTILS_SOC_TEGRA20, TEGRA_ASOC_UTILS_SOC_TEGRA30, + TEGRA_ASOC_UTILS_SOC_TEGRA114, }; struct tegra_asoc_utils_data { -- cgit v1.2.3 From aed9913e6fad5a7eccce2b7a3ee6daa96b575157 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 26 Mar 2013 14:47:08 +0800 Subject: ASoC: arizona: remove duplicated include from arizona.c Remove duplicated include. Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 26e1579c36cb..c979ff2b4191 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From abe99370b3c583cd0fc4185e7a776b7bb48311c3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 25 Mar 2013 16:58:16 +0100 Subject: ASoC: omap: Call omap_mcbsp_set_threshold() from mcbsp hw_params The omap PCM driver provides a set_threshold callback which gets called by the PCM driver when either playback or capture is started. The only DAI driver which sets this callback is the mcbsp driver. This patch removes the callback from the PCM driver and moves the invocation of the omap_mcbsp_set_threshold() function to the mcbsp hw_params callback since this is the only place where the threshold size can change. Doing so allows us to use the default dmaengine PCM trigger callback in the omap PCM driver. Signed-off-by: Lars-Peter Clausen Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 12 +++++------- sound/soc/omap/omap-pcm.c | 33 +-------------------------------- sound/soc/omap/omap-pcm.h | 1 - 3 files changed, 6 insertions(+), 40 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 8d2defd6fdbe..406fc8797229 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -62,24 +62,22 @@ enum { * Stream DMA parameters. DMA request line and port address are set runtime * since they are different between OMAP1 and later OMAPs */ -static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) +static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream, + unsigned int packet_size) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); - struct omap_pcm_dma_data *dma_data; int words; - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - /* * Configure McBSP threshold based on either: * packet_size, when the sDMA is in packet mode, or based on the * period size in THRESHOLD mode, otherwise use McBSP threshold = 1 * for mono streams. */ - if (dma_data->packet_size) - words = dma_data->packet_size; + if (packet_size) + words = packet_size; else words = 1; @@ -245,7 +243,6 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } if (mcbsp->pdata->buffer_size) { - dma_data->set_threshold = omap_mcbsp_set_threshold; if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { int period_words, max_thrsh; int divider = 0; @@ -276,6 +273,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, /* Use packet mode for non mono streams */ pkt_size = channels; } + omap_mcbsp_set_threshold(substream, pkt_size); } dma_data->packet_size = pkt_size; diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index c722c2ef9665..1626fb7d2cd2 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -129,37 +129,6 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream) return 0; } -static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct omap_pcm_dma_data *dma_data; - int ret = 0; - - dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - /* Configure McBSP internal buffer usage */ - if (dma_data->set_threshold) - dma_data->set_threshold(substream); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - break; - default: - ret = -EINVAL; - } - - if (ret == 0) - ret = snd_dmaengine_pcm_trigger(substream, cmd); - - return ret; -} - static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) { snd_pcm_uframes_t offset; @@ -208,7 +177,7 @@ static struct snd_pcm_ops omap_pcm_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = omap_pcm_hw_params, .hw_free = omap_pcm_hw_free, - .trigger = omap_pcm_trigger, + .trigger = snd_dmaengine_pcm_trigger, .pointer = omap_pcm_pointer, .mmap = omap_pcm_mmap, }; diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h index cabe74c4068b..39e6e4556b82 100644 --- a/sound/soc/omap/omap-pcm.h +++ b/sound/soc/omap/omap-pcm.h @@ -31,7 +31,6 @@ struct omap_pcm_dma_data { char *name; /* stream identifier */ int dma_req; /* DMA request line */ unsigned long port_addr; /* transmit/receive register */ - void (*set_threshold)(struct snd_pcm_substream *substream); int data_type; /* 8, 16, 32 (bits) or 0 to let omap-pcm * to decide the sDMA data type */ int packet_size; /* packet size only in PACKET mode */ -- cgit v1.2.3 From cb20d5757bbe79d9c9e4210e232934792be2336e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:01 +0100 Subject: ASoC: ux500_pcm: Remove duplicated SNDRV_PCM_HW_PARAM_PERIODS constraint The generic dmaengine based PCM driver code takes care of setting this constraint, there is no need of doing it manually in the ux500 driver. Signed-off-by: Lars-Peter Clausen Acked-by: Ola Lilja Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_pcm.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 846fa82a58d0..375ca6ba3ebb 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -111,15 +111,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) snd_soc_set_runtime_hwparams(substream, &ux500_pcm_hw_capture); - /* ensure that buffer size is a multiple of period size */ - ret = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) { - dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n", - __func__, ret); - return ret; - } - dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__, snd_pcm_stream_str(substream)); runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? -- cgit v1.2.3 From 023934b4052b1a955ac8d68c8d4b216d1c55c611 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:02 +0100 Subject: ASoC: spear_pcm: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Acked-by: Rajeev Kumar Signed-off-by: Mark Brown --- sound/soc/spear/spear_pcm.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 9b76cc5a1148..32431d619174 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -73,14 +73,6 @@ static int spear_pcm_open(struct snd_pcm_substream *substream) return 0; } -static int spear_pcm_close(struct snd_pcm_substream *substream) -{ - - snd_dmaengine_pcm_close(substream); - - return 0; -} - static int spear_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { @@ -93,7 +85,7 @@ static int spear_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops spear_pcm_ops = { .open = spear_pcm_open, - .close = spear_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = spear_pcm_hw_params, .hw_free = spear_pcm_hw_free, -- cgit v1.2.3 From 340af748bc4004982a1a11ea2d81a4bffe6eb975 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:03 +0100 Subject: ASoC: omap-pcm: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Acked-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/omap-pcm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 1626fb7d2cd2..6c842c7ef9e6 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -154,12 +154,6 @@ static int omap_pcm_open(struct snd_pcm_substream *substream) &dma_data->dma_req); } -static int omap_pcm_close(struct snd_pcm_substream *substream) -{ - snd_dmaengine_pcm_close(substream); - return 0; -} - static int omap_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { @@ -173,7 +167,7 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops omap_pcm_ops = { .open = omap_pcm_open, - .close = omap_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = omap_pcm_hw_params, .hw_free = omap_pcm_hw_free, -- cgit v1.2.3 From 3021bd38ed31380df5e270451162feca83aef40f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:04 +0100 Subject: ASoC: tegra_pcm: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Acked-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/tegra/tegra_pcm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index c925ab0adeb6..e67af0b5d35d 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -75,12 +75,6 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) return 0; } -static int tegra_pcm_close(struct snd_pcm_substream *substream) -{ - snd_dmaengine_pcm_close(substream); - return 0; -} - static int tegra_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -160,7 +154,7 @@ static int tegra_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops tegra_pcm_ops = { .open = tegra_pcm_open, - .close = tegra_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = tegra_pcm_hw_params, .hw_free = tegra_pcm_hw_free, -- cgit v1.2.3 From 8c4e56fd5595105128077c2bbdfde3c15a4c2d91 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:05 +0100 Subject: ASoC: ux500_pcm: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Acked-by: Ola Lilja Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_pcm.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 375ca6ba3ebb..d000ba271cab 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -160,18 +160,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) return 0; } -static int ux500_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *dai = rtd->cpu_dai; - - dev_dbg(dai->dev, "%s: Enter\n", __func__); - - snd_dmaengine_pcm_close(substream); - - return 0; -} - static int ux500_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { @@ -246,7 +234,7 @@ static int ux500_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops ux500_pcm_ops = { .open = ux500_pcm_open, - .close = ux500_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = ux500_pcm_hw_params, .hw_free = ux500_pcm_hw_free, -- cgit v1.2.3 From a85fc1b073406b3848661fcbb452497930dcc8af Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:06 +0100 Subject: ASoC: atmel-pcm-dma: No need to wrap snd_dmaengine_pcm_close() If a PCM driver using the dmaengine PCM helper functions doesn't need to do anything special in its pcm_close callback, snd_dmaengine_pcm_close can be used directly for as the pcm_close callback and there is no need to wrap it in a custom function. Signed-off-by: Lars-Peter Clausen Tested-by: Bo Shen Acked-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-pcm-dma.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index 30184a4a147a..396bf78c7a2d 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -199,16 +199,9 @@ static int atmel_pcm_open(struct snd_pcm_substream *substream) return 0; } -static int atmel_pcm_close(struct snd_pcm_substream *substream) -{ - snd_dmaengine_pcm_close(substream); - - return 0; -} - static struct snd_pcm_ops atmel_pcm_ops = { .open = atmel_pcm_open, - .close = atmel_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = atmel_pcm_hw_params, .prepare = atmel_pcm_dma_prepare, -- cgit v1.2.3 From ebd59b07ecd9d35d5bc88c91a4878fbb4549ed42 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:07 +0100 Subject: ASoC: ux500_pcm: No need to use snd_dmaengine_pcm_set_data() The driver never uses snd_dmaengine_pcm_get_data(), so there is no need to use snd_dmaengine_pcm_set_data(). Signed-off-by: Lars-Peter Clausen Acked-by: Ola Lilja Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_pcm.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index d000ba271cab..1ab36fa845cd 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c @@ -155,8 +155,6 @@ static int ux500_pcm_open(struct snd_pcm_substream *substream) return ret; } - snd_dmaengine_pcm_set_data(substream, dma_cfg); - return 0; } -- cgit v1.2.3 From 593b66fbbcac78b73ec17270c874f6db8eabd97c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:08 +0100 Subject: ASoC: speaer_pcm: No need to use snd_dmaengine_pcm_set_data() The driver never uses snd_dmaengine_pcm_get_data(), so there is no need to use snd_dmaengine_pcm_set_data(). Signed-off-by: Lars-Peter Clausen Acked-by: Rajeev Kumar Signed-off-by: Mark Brown --- sound/soc/spear/spear_pcm.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 32431d619174..db75d72c4805 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -64,13 +64,7 @@ static int spear_pcm_open(struct snd_pcm_substream *substream) if (ret) return ret; - ret = snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data); - if (ret) - return ret; - - snd_dmaengine_pcm_set_data(substream, dma_data); - - return 0; + return snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data) } static int spear_pcm_mmap(struct snd_pcm_substream *substream, -- cgit v1.2.3 From 5fe668a1d2c27223fea4991ebf90ee28b7d1941c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:09 +0100 Subject: ASoC: atmel-pcm-dma: Do not use snd_dmaengine_pcm_{set,get}_data() We want to get rid of snd_dmaengine_pcm_{set,get}_data(). All instances of snd_dmaengine_pcm_get_data() in the atmel pcm driver can easily be replaced with snd_soc_dai_get_dma_data(). Signed-off-by: Lars-Peter Clausen Tested-by: Bo Shen Acked-by: Bo Shen Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-pcm-dma.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index 396bf78c7a2d..b8570e3e1b57 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -67,9 +67,10 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = { static void atmel_pcm_dma_irq(u32 ssc_sr, struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_pcm_dma_params *prtd; - prtd = snd_dmaengine_pcm_get_data(substream); + prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); if (ssc_sr & prtd->mask->ssc_error) { if (snd_pcm_running(substream)) @@ -104,15 +105,13 @@ static bool filter(struct dma_chan *chan, void *slave) } static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params, struct atmel_pcm_dma_params *prtd) { - struct atmel_pcm_dma_params *prtd; struct ssc_device *ssc; struct dma_chan *dma_chan; struct dma_slave_config slave_config; int ret; - prtd = snd_dmaengine_pcm_get_data(substream); ssc = prtd->ssc; ret = snd_hwparams_to_dma_slave_config(substream, params, @@ -164,9 +163,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - snd_dmaengine_pcm_set_data(substream, prtd); - - ret = atmel_pcm_configure_dma(substream, params); + ret = atmel_pcm_configure_dma(substream, params, prtd); if (ret) { pr_err("atmel-pcm: failed to configure dmai\n"); goto err; @@ -182,9 +179,10 @@ err: static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) { + struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_pcm_dma_params *prtd; - prtd = snd_dmaengine_pcm_get_data(substream); + prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error); ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable); -- cgit v1.2.3 From 453807f3006757a5661c4000262d7d9284b5214c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:10 +0100 Subject: ASoC: ep93xx: Use ep93xx_dma_params instead of ep93xx_pcm_dma_params Currently the ep93xx_dma_params struct which is passed to the dmaengine driver is constructed at runtime from the ep93xx_pcm_dma_params that gets passed to the ep93xx PCM driver from one of the ep93xx DAI drivers. The ep93xx_pcm_dma_params struct is almost identical to the ep93xx_dma_params struct. The only missing field is the 'direction' field, which is computed at runtime in the PCM driver based on the current substream. Since we know in advance which ep93xx_pcm_dma_params struct is being used for which substream at compile time, we also already know which direction to use at compile time. So we can easily replace all instances of ep93xx_pcm_dma_params with their ep93xx_dma_params counterpart. This allows us to simplify the code in the ep93xx pcm driver quite a bit. Signed-off-by: Lars-Peter Clausen Reviewed-by: Ryan Mallon Signed-off-by: Mark Brown --- sound/soc/cirrus/edb93xx.c | 1 - sound/soc/cirrus/ep93xx-ac97.c | 9 +++++---- sound/soc/cirrus/ep93xx-i2s.c | 12 ++++++------ sound/soc/cirrus/ep93xx-pcm.c | 37 +++---------------------------------- sound/soc/cirrus/ep93xx-pcm.h | 20 -------------------- sound/soc/cirrus/simone.c | 2 -- sound/soc/cirrus/snappercl15.c | 1 - 7 files changed, 14 insertions(+), 68 deletions(-) delete mode 100644 sound/soc/cirrus/ep93xx-pcm.h (limited to 'sound/soc') diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c index 5db68cf7b281..c43fb214558a 100644 --- a/sound/soc/cirrus/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c @@ -27,7 +27,6 @@ #include #include #include -#include "ep93xx-pcm.h" static int edb93xx_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index 1738d28fb04f..8d3088647e44 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -23,7 +23,6 @@ #include #include -#include "ep93xx-pcm.h" /* * Per channel (1-4) registers. @@ -101,14 +100,16 @@ struct ep93xx_ac97_info { /* currently ALSA only supports a single AC97 device */ static struct ep93xx_ac97_info *ep93xx_ac97_info; -static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_out = { +static struct ep93xx_dma_data ep93xx_ac97_pcm_out = { .name = "ac97-pcm-out", .dma_port = EP93XX_DMA_AAC1, + .direction = DMA_MEM_TO_DEV, }; -static struct ep93xx_pcm_dma_params ep93xx_ac97_pcm_in = { +static struct ep93xx_dma_data ep93xx_ac97_pcm_in = { .name = "ac97-pcm-in", .dma_port = EP93XX_DMA_AAC1, + .direction = DMA_DEV_TO_MEM, }; static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info, @@ -316,7 +317,7 @@ static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct ep93xx_pcm_dma_params *dma_data; + struct ep93xx_dma_data *dma_data; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) dma_data = &ep93xx_ac97_pcm_out; diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 323ed69b7975..aa124f86f60e 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -30,8 +30,6 @@ #include #include -#include "ep93xx-pcm.h" - #define EP93XX_I2S_TXCLKCFG 0x00 #define EP93XX_I2S_RXCLKCFG 0x04 #define EP93XX_I2S_GLCTRL 0x0C @@ -62,18 +60,20 @@ struct ep93xx_i2s_info { struct clk *mclk; struct clk *sclk; struct clk *lrclk; - struct ep93xx_pcm_dma_params *dma_params; + struct ep93xx_dma_data *dma_data; void __iomem *regs; }; -struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = { +struct ep93xx_dma_data ep93xx_i2s_dma_data[] = { [SNDRV_PCM_STREAM_PLAYBACK] = { .name = "i2s-pcm-out", .dma_port = EP93XX_DMA_I2S1, + .direction = DMA_MEM_TO_DEV, }, [SNDRV_PCM_STREAM_CAPTURE] = { .name = "i2s-pcm-in", .dma_port = EP93XX_DMA_I2S1, + .direction = DMA_DEV_TO_MEM, }, }; @@ -147,7 +147,7 @@ static int ep93xx_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; snd_soc_dai_set_dma_data(cpu_dai, substream, - &info->dma_params[substream->stream]); + &info->dma_data[substream->stream]); return 0; } @@ -403,7 +403,7 @@ static int ep93xx_i2s_probe(struct platform_device *pdev) } dev_set_drvdata(&pdev->dev, info); - info->dma_params = ep93xx_i2s_dma_params; + info->dma_data = ep93xx_i2s_dma_data; err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai); if (err) diff --git a/sound/soc/cirrus/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c index 72eb7a49e16a..298946f790eb 100644 --- a/sound/soc/cirrus/ep93xx-pcm.c +++ b/sound/soc/cirrus/ep93xx-pcm.c @@ -29,8 +29,6 @@ #include #include -#include "ep93xx-pcm.h" - static const struct snd_pcm_hardware ep93xx_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -68,40 +66,11 @@ 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 *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct ep93xx_pcm_dma_params *dma_params; - struct ep93xx_dma_data *dma_data; - int ret; snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); - dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL); - if (!dma_data) - return -ENOMEM; - - dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream); - dma_data->port = dma_params->dma_port; - dma_data->name = dma_params->name; - dma_data->direction = snd_pcm_substream_to_dma_direction(substream); - - ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data); - if (ret) { - kfree(dma_data); - return ret; - } - - snd_dmaengine_pcm_set_data(substream, dma_data); - - return 0; -} - -static int ep93xx_pcm_close(struct snd_pcm_substream *substream) -{ - struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); - - snd_dmaengine_pcm_close(substream); - kfree(dma_data); - return 0; + return snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); } static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, @@ -131,7 +100,7 @@ static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops ep93xx_pcm_ops = { .open = ep93xx_pcm_open, - .close = ep93xx_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = ep93xx_pcm_hw_params, .hw_free = ep93xx_pcm_hw_free, diff --git a/sound/soc/cirrus/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h deleted file mode 100644 index 111e1121ecb8..000000000000 --- a/sound/soc/cirrus/ep93xx-pcm.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * sound/soc/ep93xx/ep93xx-pcm.h - EP93xx ALSA PCM interface - * - * Copyright (C) 2006 Lennert Buytenhek - * Copyright (C) 2006 Applied Data Systems - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _EP93XX_SND_SOC_PCM_H -#define _EP93XX_SND_SOC_PCM_H - -struct ep93xx_pcm_dma_params { - char *name; - int dma_port; -}; - -#endif /* _EP93XX_SND_SOC_PCM_H */ diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c index a397bb0d8179..4d094d00c34a 100644 --- a/sound/soc/cirrus/simone.c +++ b/sound/soc/cirrus/simone.c @@ -21,8 +21,6 @@ #include #include -#include "ep93xx-pcm.h" - static struct snd_soc_dai_link simone_dai = { .name = "AC97", .stream_name = "AC97 HiFi", diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c index 9d77fe28dfcc..69041074f2c1 100644 --- a/sound/soc/cirrus/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c @@ -21,7 +21,6 @@ #include #include "../codecs/tlv320aic23.h" -#include "ep93xx-pcm.h" #define CODEC_CLOCK 5644800 -- cgit v1.2.3 From ac581e60dfb4cc55ac20cca18202c7689d324aa7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:11 +0100 Subject: ASoC: mmp-pcm: Allocate dma filter parameters on the stack The dma filter parameters are only used within filter callback, so there is no need to allocate them on the heap and keep them around until the PCM has been closed. Signed-off-by: Lars-Peter Clausen Tested-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/pxa/mmp-pcm.c | 33 +++++---------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index 190eb0bccf5f..6c3980252bf6 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c @@ -118,9 +118,8 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct platform_device *pdev = to_platform_device(rtd->platform->dev); struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct mmp_dma_data *dma_data; + struct mmp_dma_data dma_data; struct resource *r; - int ret; r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream); if (!r) @@ -128,33 +127,11 @@ static int mmp_pcm_open(struct snd_pcm_substream *substream) snd_soc_set_runtime_hwparams(substream, &mmp_pcm_hardware[substream->stream]); - dma_data = devm_kzalloc(&pdev->dev, - sizeof(struct mmp_dma_data), GFP_KERNEL); - if (dma_data == NULL) - return -ENOMEM; - dma_data->dma_res = r; - dma_data->ssp_id = cpu_dai->id; + dma_data.dma_res = r; + dma_data.ssp_id = cpu_dai->id; - ret = snd_dmaengine_pcm_open(substream, filter, dma_data); - if (ret) { - devm_kfree(&pdev->dev, dma_data); - return ret; - } - - snd_dmaengine_pcm_set_data(substream, dma_data); - return 0; -} - -static int mmp_pcm_close(struct snd_pcm_substream *substream) -{ - struct mmp_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct platform_device *pdev = to_platform_device(rtd->platform->dev); - - snd_dmaengine_pcm_close(substream); - devm_kfree(&pdev->dev, dma_data); - return 0; + return snd_dmaengine_pcm_open(substream, filter, &dma_data); } static int mmp_pcm_mmap(struct snd_pcm_substream *substream, @@ -171,7 +148,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream, struct snd_pcm_ops mmp_pcm_ops = { .open = mmp_pcm_open, - .close = mmp_pcm_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = mmp_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, -- cgit v1.2.3 From 312bb4f626328fdc246c8d13082ab00e26e7d048 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:12 +0100 Subject: ASoC: imx-pcm: Embed the imx_dma_data struct in the dma_params struct Currently the imx_dma_data struct, which gets passed to the dmaengine driver, is allocated and constructed in the pcm driver from the data stored in the dma_params struct. The dma_params struct gets passed to the pcm driver from the dai driver. Instead of going this route of indirection embed the dma_data struct directly into the dma_params struct and let the dai driver fill it in. This allows us to simplify the imx-pcm-dma driver quite a bit, since it doesn't have care about memory managing the imx_dma_data struct anymore. Signed-off-by: Lars-Peter Clausen Tested-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 17 +++++++++-------- sound/soc/fsl/imx-pcm-dma.c | 35 ++--------------------------------- sound/soc/fsl/imx-pcm.h | 17 +++++++++++++++-- sound/soc/fsl/imx-ssi.c | 12 ++++++++---- 4 files changed, 34 insertions(+), 47 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 7decbd9b2340..2cce1ce1b7dd 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -649,6 +649,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) const uint32_t *iprop; struct resource res; char name[64]; + bool shared; /* SSIs that are not connected on the board should have a * status = "disabled" @@ -755,14 +756,14 @@ static int fsl_ssi_probe(struct platform_device *pdev) dev_err(&pdev->dev, "could not get dma events\n"); goto error_clk; } - ssi_private->dma_params_tx.dma = dma_events[0]; - ssi_private->dma_params_rx.dma = dma_events[1]; - - ssi_private->dma_params_tx.shared_peripheral = - of_device_is_compatible(of_get_parent(np), - "fsl,spba-bus"); - ssi_private->dma_params_rx.shared_peripheral = - ssi_private->dma_params_tx.shared_peripheral; + + shared = of_device_is_compatible(of_get_parent(np), + "fsl,spba-bus"); + + imx_pcm_dma_params_init_data(&ssi_private->dma_params_tx, + dma_events[0], shared); + imx_pcm_dma_params_init_data(&ssi_private->dma_params_rx, + dma_events[1], shared); } /* Initialize the the device_attribute structure */ diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index 500f8ce55d78..6832c498457a 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -30,8 +30,6 @@ #include #include -#include - #include "imx-pcm.h" static bool filter(struct dma_chan *chan, void *param) @@ -101,46 +99,17 @@ static int snd_imx_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct imx_pcm_dma_params *dma_params; - struct imx_dma_data *dma_data; - int ret; snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); - if (!dma_data) - return -ENOMEM; - - dma_data->peripheral_type = dma_params->shared_peripheral ? - IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI; - dma_data->priority = DMA_PRIO_HIGH; - dma_data->dma_request = dma_params->dma; - - ret = snd_dmaengine_pcm_open(substream, filter, dma_data); - if (ret) { - kfree(dma_data); - return ret; - } - - snd_dmaengine_pcm_set_data(substream, dma_data); - - return 0; -} - -static int snd_imx_close(struct snd_pcm_substream *substream) -{ - struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); - - snd_dmaengine_pcm_close(substream); - kfree(dma_data); - - return 0; + return snd_dmaengine_pcm_open(substream, filter, &dma_params->dma_data); } static struct snd_pcm_ops imx_pcm_ops = { .open = snd_imx_open, - .close = snd_imx_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_imx_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h index 5ae13a13a353..16eaf5a09f53 100644 --- a/sound/soc/fsl/imx-pcm.h +++ b/sound/soc/fsl/imx-pcm.h @@ -13,18 +13,31 @@ #ifndef _IMX_PCM_H #define _IMX_PCM_H +#include + /* * Do not change this as the FIQ handler depends on this size */ #define IMX_SSI_DMABUF_SIZE (64 * 1024) struct imx_pcm_dma_params { - int dma; unsigned long dma_addr; int burstsize; - bool shared_peripheral; /* The peripheral is on SPBA bus */ + struct imx_dma_data dma_data; }; +static inline void +imx_pcm_dma_params_init_data(struct imx_pcm_dma_params *params, + int dma, bool shared) +{ + params->dma_data.dma_request = dma; + params->dma_data.priority = DMA_PRIO_HIGH; + if (shared) + params->dma_data.peripheral_type = IMX_DMATYPE_SSI_SP; + else + params->dma_data.peripheral_type = IMX_DMATYPE_SSI; +} + int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma); int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 55464a5b0706..14018c4628ec 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -577,12 +577,16 @@ static int imx_ssi_probe(struct platform_device *pdev) ssi->dma_params_rx.burstsize = 4; res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); - if (res) - ssi->dma_params_tx.dma = res->start; + if (res) { + imx_pcm_dma_params_init_data(&ssi->dma_params_tx, res->start, + false); + } res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0"); - if (res) - ssi->dma_params_rx.dma = res->start; + if (res) { + imx_pcm_dma_params_init_data(&ssi->dma_params_rx, res->start, + false); + } platform_set_drvdata(pdev, ssi); -- cgit v1.2.3 From b7e5e91210fc9d40f93f87e386823e4ba9b32805 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:13 +0100 Subject: ASoC: mxs: Embed the mxs_dma_data struct in the mxs_pcm_dma_params struct Currently the mxs_dma_data struct, which gets passed to the dmaengine driver, is allocated in the pcm driver's open callback. The mxs_dma_data struct has exactly one field which is initialized from the the same field in the mxs_pcm_dma_params struct. The mxs_pcm_dma_params struct gets passed to the pcm driver from the dai driver. Instead of taking this indirection embed the mxs_dma_data struct directly in the mxs_pcm_dma_params struct. This allows us to simplify the pcm driver quite a bit, since we don't have to care about memory managing the mxs_dma_data struct anymore. Signed-off-by: Lars-Peter Clausen Tested-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-pcm.c | 43 +++++-------------------------------------- sound/soc/mxs/mxs-pcm.h | 4 +++- sound/soc/mxs/mxs-saif.c | 6 +++--- 3 files changed, 11 insertions(+), 42 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 564b5b60319d..ebbef8597554 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -39,11 +38,6 @@ #include "mxs-pcm.h" -struct mxs_pcm_dma_data { - struct mxs_dma_data dma_data; - struct mxs_pcm_dma_params *dma_params; -}; - static struct snd_pcm_hardware snd_mxs_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -66,8 +60,7 @@ static struct snd_pcm_hardware snd_mxs_hardware = { static bool filter(struct dma_chan *chan, void *param) { - struct mxs_pcm_dma_data *pcm_dma_data = param; - struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params; + struct mxs_pcm_dma_params *dma_params = param; if (!mxs_dma_is_apbx(chan)) return false; @@ -75,7 +68,7 @@ static bool filter(struct dma_chan *chan, void *param) if (chan->chan_id != dma_params->chan_num) return false; - chan->private = &pcm_dma_data->dma_data; + chan->private = &dma_params->dma_data; return true; } @@ -91,37 +84,11 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, static int snd_mxs_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct mxs_pcm_dma_data *pcm_dma_data; - int ret; - - pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL); - if (pcm_dma_data == NULL) - return -ENOMEM; - - pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq; - - ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data); - if (ret) { - kfree(pcm_dma_data); - return ret; - } snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); - snd_dmaengine_pcm_set_data(substream, pcm_dma_data); - - return 0; -} - -static int snd_mxs_close(struct snd_pcm_substream *substream) -{ - struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream); - - snd_dmaengine_pcm_close(substream); - kfree(pcm_dma_data); - - return 0; + return snd_dmaengine_pcm_open(substream, filter, + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream)); } static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, @@ -137,7 +104,7 @@ static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, static struct snd_pcm_ops mxs_pcm_ops = { .open = snd_mxs_open, - .close = snd_mxs_close, + .close = snd_dmaengine_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_mxs_pcm_hw_params, .trigger = snd_dmaengine_pcm_trigger, diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h index 35ba2ca42384..3aa918f9ed3e 100644 --- a/sound/soc/mxs/mxs-pcm.h +++ b/sound/soc/mxs/mxs-pcm.h @@ -19,8 +19,10 @@ #ifndef _MXS_PCM_H #define _MXS_PCM_H +#include + struct mxs_pcm_dma_params { - int chan_irq; + struct mxs_dma_data dma_data; int chan_num; }; diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 3a2aa1d19b93..f13bd8730b0f 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -753,9 +753,9 @@ static int mxs_saif_probe(struct platform_device *pdev) return ret; } - saif->dma_param.chan_irq = platform_get_irq(pdev, 1); - if (saif->dma_param.chan_irq < 0) { - ret = saif->dma_param.chan_irq; + saif->dma_param.dma_data.chan_irq = platform_get_irq(pdev, 1); + if (saif->dma_param.dma_data.chan_irq < 0) { + ret = saif->dma_param.dma_data.chan_irq; dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", ret); return ret; -- cgit v1.2.3 From b1bd7f62cf2b854316a9a8b2442a8014dbe29a47 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Mar 2013 14:12:14 +0100 Subject: ASoC: dmaengine-pcm: Remove snd_dmaengine_pcm_{set,get}_data These functions were initially added to be able to support some oddball dma drivers, but all users have been updated to deal with the situation without the help of snd_dmaengine_pcm_{set,get}_data, so these two functions can be removed. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/dmaengine_pcm.h | 3 --- sound/soc/soc-dmaengine-pcm.c | 29 ----------------------------- 2 files changed, 32 deletions(-) (limited to 'sound/soc') diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index b877334bbb0f..f8a70312adb8 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -32,9 +32,6 @@ snd_pcm_substream_to_dma_direction(const struct snd_pcm_substream *substream) return DMA_DEV_TO_MEM; } -void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data); -void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream); - int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, const struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config); int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd); diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 111b7d921e89..e8b1215b8c1b 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -33,8 +33,6 @@ struct dmaengine_pcm_runtime_data { dma_cookie_t cookie; unsigned int pos; - - void *data; }; static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( @@ -43,33 +41,6 @@ static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( return substream->runtime->private_data; } -/** - * snd_dmaengine_pcm_set_data - Set dmaengine substream private data - * @substream: PCM substream - * @data: Data to set - */ -void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data) -{ - struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - - prtd->data = data; -} -EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data); - -/** - * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data - * @substream: PCM substream - * - * Returns the data previously set with snd_dmaengine_pcm_set_data - */ -void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream) -{ - struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); - - return prtd->data; -} -EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data); - struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) { struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); -- cgit v1.2.3 From f607e31ce3963327f749b56c65dfec2642aa623c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 22 Feb 2013 18:36:53 +0000 Subject: ASoC: arizona: Fix interaction between headphone outputs and identification Running HPDET while the headphone outputs are enabled can disrupt the operation of HPDET. In order to avoid this HPDET needs to disable the headphone outputs and ASoC needs to not enable them while HPDET is running. Do the ASoC side of this by storing the enable state in the core driver structure and only writing to the device if a flag indicating that the accessory detection side is in a state where it can have the headphone output stage enabled. Signed-off-by: Mark Brown --- include/linux/mfd/arizona/core.h | 3 +++ sound/soc/codecs/arizona.c | 33 +++++++++++++++++++++++++++++++++ sound/soc/codecs/arizona.h | 3 +++ sound/soc/codecs/wm5102.c | 8 ++++---- sound/soc/codecs/wm5110.c | 8 ++++---- 5 files changed, 47 insertions(+), 8 deletions(-) (limited to 'sound/soc') diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index a710255528d7..cc281368dc55 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h @@ -100,6 +100,9 @@ struct arizona { struct regmap_irq_chip_data *aod_irq_chip; struct regmap_irq_chip_data *irq_chip; + bool hpdet_magic; + unsigned int hp_ena; + struct mutex clk_lock; int clk32k_ref; diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index ac948a671ea6..e7d34711412c 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -364,6 +364,39 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(arizona_out_ev); +int arizona_hp_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec); + unsigned int mask = 1 << w->shift; + unsigned int val; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + val = mask; + break; + case SND_SOC_DAPM_PRE_PMD: + val = 0; + break; + default: + return -EINVAL; + } + + /* Store the desired state for the HP outputs */ + priv->arizona->hp_ena &= ~mask; + priv->arizona->hp_ena |= val; + + /* Force off if HPDET magic is active */ + if (priv->arizona->hpdet_magic) + val = 0; + + snd_soc_update_bits(w->codec, ARIZONA_OUTPUT_ENABLES_1, mask, val); + + return arizona_out_ev(w, kcontrol, event); +} +EXPORT_SYMBOL_GPL(arizona_hp_ev); + static unsigned int arizona_sysclk_48k_rates[] = { 6144000, 12288000, diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 116372c91f5d..13dd2916b721 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -184,6 +184,9 @@ extern int arizona_in_ev(struct snd_soc_dapm_widget *w, extern int arizona_out_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); +extern int arizona_hp_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event); extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id, int source, unsigned int freq, int dir); diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index b82bbf584146..2657aad3f8b1 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1131,11 +1131,11 @@ 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), -SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, +SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, + ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, +SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, + ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index cdeb301da1f6..7841b42a819c 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -551,11 +551,11 @@ SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0, SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0, ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0), -SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, +SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM, + ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1, - ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, +SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM, + ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1, ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev, -- cgit v1.2.3 From 36953d98149674d218420e29f3ea2af827a68e74 Mon Sep 17 00:00:00 2001 From: Jeeja KP Date: Tue, 26 Mar 2013 21:22:28 +0530 Subject: ASoC: compress - add support for metadata apis Compress core added metadata apis in 9727b4, so add same in ASoC Signed-off-by: Jeeja KP Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/soc-compress.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index b5b3db71e253..f9b219772a8d 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -322,11 +322,38 @@ static int soc_compr_copy(struct snd_compr_stream *cstream, return ret; } +static int sst_compr_set_metadata(struct snd_compr_stream *cstream, + struct snd_compr_metadata *metadata) +{ + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct snd_soc_platform *platform = rtd->platform; + int ret = 0; + + if (platform->driver->compr_ops && platform->driver->compr_ops->set_metadata) + ret = platform->driver->compr_ops->set_metadata(cstream, metadata); + + return ret; +} + +static int sst_compr_get_metadata(struct snd_compr_stream *cstream, + struct snd_compr_metadata *metadata) +{ + struct snd_soc_pcm_runtime *rtd = cstream->private_data; + struct snd_soc_platform *platform = rtd->platform; + int ret = 0; + + if (platform->driver->compr_ops && platform->driver->compr_ops->get_metadata) + ret = platform->driver->compr_ops->get_metadata(cstream, metadata); + + return ret; +} /* ASoC Compress operations */ static struct snd_compr_ops soc_compr_ops = { .open = soc_compr_open, .free = soc_compr_free, .set_params = soc_compr_set_params, + .set_metadata = sst_compr_set_metadata, + .get_metadata = sst_compr_get_metadata, .get_params = soc_compr_get_params, .trigger = soc_compr_trigger, .pointer = soc_compr_pointer, -- cgit v1.2.3 From 1a2c7d568f624307c5821f31e54727a4b374855c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 24 Mar 2013 22:50:23 +0000 Subject: ASoC: arizona: Add delay after powering up line level outputs Ensure that the outputs are fully enabled before we begin passing audio through them. Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index abdd019c5b6e..389f23253831 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -579,6 +579,24 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { + switch (event) { + case SND_SOC_DAPM_POST_PMU: + switch (w->shift) { + case ARIZONA_OUT1L_ENA_SHIFT: + case ARIZONA_OUT1R_ENA_SHIFT: + case ARIZONA_OUT2L_ENA_SHIFT: + case ARIZONA_OUT2R_ENA_SHIFT: + case ARIZONA_OUT3L_ENA_SHIFT: + case ARIZONA_OUT3R_ENA_SHIFT: + msleep(17); + break; + + default: + break; + } + break; + } + return 0; } EXPORT_SYMBOL_GPL(arizona_out_ev); -- cgit v1.2.3 From a1422b8cb443c6cfc58da38394673b8b8eda6458 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:27:13 -0700 Subject: ASoC: snd_soc_register_component() uses properly snd_soc_register_dai[s]() snd_soc_register_dai() uses fmt_single_name(), and snd_soc_register_dais() uses fmt_multiple_name() for dai->name which is used for name based matching. This patch uses properly snd_soc_register_dai() it it was single driver, and uses snd_register_dais() if it were multiple drivers. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 9e6118573fef..2ecaaf13e319 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4169,7 +4169,15 @@ int snd_soc_register_component(struct device *dev, cmpnt->driver = cmpnt_drv; cmpnt->num_dai = num_dai; - ret = snd_soc_register_dais(dev, dai_drv, num_dai); + /* + * snd_soc_register_dai() uses fmt_single_name(), and + * snd_soc_register_dais() uses fmt_multiple_name() + * for dai->name which is used for name based matching + */ + if (1 == num_dai) + ret = snd_soc_register_dai(dev, dai_drv); + else + ret = snd_soc_register_dais(dev, dai_drv, num_dai); if (ret < 0) { dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret); goto error_component_name; -- cgit v1.2.3 From bfcb921caf37ceccb4bb474d7f426f016bf81efa Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:30:54 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on davinci i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-i2s.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 821831207180..ebe82947bab3 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -645,6 +645,10 @@ static struct snd_soc_dai_driver davinci_i2s_dai = { }; +static const struct snd_soc_component_driver davinci_i2s_component = { + .name = "davinci-i2s", +}; + static int davinci_i2s_probe(struct platform_device *pdev) { struct snd_platform_data *pdata = pdev->dev.platform_data; @@ -727,20 +731,21 @@ static int davinci_i2s_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, dev); - ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai); + ret = snd_soc_register_component(&pdev->dev, &davinci_i2s_component, + &davinci_i2s_dai, 1); if (ret != 0) goto err_release_clk; ret = davinci_soc_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "register PCM failed: %d\n", ret); - goto err_unregister_dai; + goto err_unregister_component; } return 0; -err_unregister_dai: - snd_soc_unregister_dai(&pdev->dev); +err_unregister_component: + snd_soc_unregister_component(&pdev->dev); err_release_clk: clk_disable(dev->clk); clk_put(dev->clk); @@ -751,7 +756,7 @@ static int davinci_i2s_remove(struct platform_device *pdev) { struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); davinci_soc_platform_unregister(&pdev->dev); clk_disable(dev->clk); -- cgit v1.2.3 From ee226ce19557cd5dce12f818462c9c331570cac6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:31:07 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on davinci vcif Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-vcif.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index 07bde2e6f84e..30587c0cdbd2 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c @@ -204,6 +204,10 @@ static struct snd_soc_dai_driver davinci_vcif_dai = { }; +static const struct snd_soc_component_driver davinci_vcif_component = { + .name = "davinci-vcif", +}; + static int davinci_vcif_probe(struct platform_device *pdev) { struct davinci_vc *davinci_vc = pdev->dev.platform_data; @@ -234,7 +238,8 @@ static int davinci_vcif_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, davinci_vcif_dev); - ret = snd_soc_register_dai(&pdev->dev, &davinci_vcif_dai); + ret = snd_soc_register_component(&pdev->dev, &davinci_vcif_component, + &davinci_vcif_dai, 1); if (ret != 0) { dev_err(&pdev->dev, "could not register dai\n"); return ret; @@ -243,7 +248,7 @@ static int davinci_vcif_probe(struct platform_device *pdev) ret = davinci_soc_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "register PCM failed: %d\n", ret); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return ret; } @@ -252,7 +257,7 @@ static int davinci_vcif_probe(struct platform_device *pdev) static int davinci_vcif_remove(struct platform_device *pdev) { - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); davinci_soc_platform_unregister(&pdev->dev); return 0; -- cgit v1.2.3 From eeef0eda7ac42b19a17cc3de8f826a160f1f102e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:31:19 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on davinci mcasp Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 9321e5c9d8c1..c2e67f1f194c 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -962,6 +962,10 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { }; +static const struct snd_soc_component_driver davinci_mcasp_component = { + .name = "davinci-mcasp", +}; + static const struct of_device_id mcasp_dt_ids[] = { { .compatible = "ti,dm646x-mcasp-audio", @@ -1170,7 +1174,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dma_data->channel = res->start; dev_set_drvdata(&pdev->dev, dev); - ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]); + ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, + &davinci_mcasp_dai[pdata->op_mode], 1); if (ret != 0) goto err_release_clk; @@ -1178,13 +1183,13 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ret = davinci_soc_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "register PCM failed: %d\n", ret); - goto err_unregister_dai; + goto err_unregister_component; } return 0; -err_unregister_dai: - snd_soc_unregister_dai(&pdev->dev); +err_unregister_component: + snd_soc_unregister_component(&pdev->dev); err_release_clk: pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -1194,7 +1199,7 @@ err_release_clk: static int davinci_mcasp_remove(struct platform_device *pdev) { - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); davinci_soc_platform_unregister(&pdev->dev); pm_runtime_put_sync(&pdev->dev); -- cgit v1.2.3 From 92eaa328f2789c65441a85d50b5acea1375cb692 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:31:30 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on dw i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/dwc/designware_i2s.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c index deb30d59965e..593a3ea12d4c 100644 --- a/sound/soc/dwc/designware_i2s.c +++ b/sound/soc/dwc/designware_i2s.c @@ -297,6 +297,10 @@ static struct snd_soc_dai_ops dw_i2s_dai_ops = { .trigger = dw_i2s_trigger, }; +static const struct snd_soc_component_driver dw_i2s_component = { + .name = "dw-i2s", +}; + #ifdef CONFIG_PM static int dw_i2s_suspend(struct snd_soc_dai *dai) @@ -413,7 +417,8 @@ static int dw_i2s_probe(struct platform_device *pdev) dev->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, dev); - ret = snd_soc_register_dai(&pdev->dev, dw_i2s_dai); + ret = snd_soc_register_component(&pdev->dev, &dw_i2s_component, + dw_i2s_dai, 1); if (ret != 0) { dev_err(&pdev->dev, "not able to register dai\n"); goto err_set_drvdata; @@ -434,7 +439,7 @@ static int dw_i2s_remove(struct platform_device *pdev) { struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); dev_set_drvdata(&pdev->dev, NULL); clk_put(dev->clk); -- cgit v1.2.3 From f298a0ffa4b6169d665721962cd0723e34078be0 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:31:41 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on mpc5200 ac97 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/fsl/mpc5200_psc_ac97.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index a4aec0488dd3..4141b35ef0bb 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -270,6 +270,9 @@ static struct snd_soc_dai_driver psc_ac97_dai[] = { .ops = &psc_ac97_digital_ops, } }; +static const struct snd_soc_component_driver psc_ac97_component = { + .name = DRV_NAME, +}; /* --------------------------------------------------------------------- @@ -287,7 +290,8 @@ static int psc_ac97_of_probe(struct platform_device *op) if (rc != 0) return rc; - rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); + rc = snd_soc_register_component(&op->dev, &psc_ac97_component, + psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); if (rc != 0) { dev_err(&op->dev, "Failed to register DAI\n"); return rc; @@ -313,7 +317,7 @@ static int psc_ac97_of_probe(struct platform_device *op) static int psc_ac97_of_remove(struct platform_device *op) { mpc5200_audio_dma_destroy(op); - snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai)); + snd_soc_unregister_component(&op->dev); return 0; } -- cgit v1.2.3 From a2c662c0e5df335010a9bfa1a0c43332fadebe4b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:28:24 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on atmel ssc Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/atmel/atmel_ssc_dai.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index e13580d6c476..1435f3067d16 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -707,13 +707,18 @@ static struct snd_soc_dai_driver atmel_ssc_dai = { .ops = &atmel_ssc_dai_ops, }; +static const struct snd_soc_component_driver atmel_ssc_component = { + .name = "atmel-ssc", +}; + static int asoc_ssc_init(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct ssc_device *ssc = platform_get_drvdata(pdev); int ret; - ret = snd_soc_register_dai(dev, &atmel_ssc_dai); + ret = snd_soc_register_component(dev, &atmel_ssc_component, + &atmel_ssc_dai, 1); if (ret) { dev_err(dev, "Could not register DAI: %d\n", ret); goto err; @@ -732,7 +737,7 @@ static int asoc_ssc_init(struct device *dev) return 0; err_unregister_dai: - snd_soc_unregister_dai(dev); + snd_soc_unregister_component(dev); err: return ret; } @@ -747,7 +752,7 @@ static void asoc_ssc_exit(struct device *dev) else atmel_pcm_pdc_platform_unregister(dev); - snd_soc_unregister_dai(dev); + snd_soc_unregister_component(dev); } /** -- cgit v1.2.3 From 8b1be63bdfde194b834448e8ef1615c28a6d695c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:28:37 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on au1x i2sc Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/au1x/i2sc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index 072448afc219..b3f37f6edbcb 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c @@ -225,6 +225,10 @@ static struct snd_soc_dai_driver au1xi2s_dai_driver = { .ops = &au1xi2s_dai_ops, }; +static const struct snd_soc_component_driver au1xi2s_component = { + .name = "au1xi2s", +}; + static int au1xi2s_drvprobe(struct platform_device *pdev) { struct resource *iores, *dmares; @@ -260,14 +264,15 @@ static int au1xi2s_drvprobe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); - return snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver); + return snd_soc_register_component(&pdev->dev, &au1xi2s_component, + &au1xi2s_dai_driver, 1); } static int au1xi2s_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */ -- cgit v1.2.3 From a4ff200c00f836f6d0c4d9ac954596b5df40d157 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:28:50 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on au1x psc-ac97 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/au1x/psc-ac97.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 6ba07e365967..8f1862aa7333 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -361,6 +361,10 @@ static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = { .ops = &au1xpsc_ac97_dai_ops, }; +static const struct snd_soc_component_driver au1xpsc_ac97_component = { + .name = "au1xpsc-ac97", +}; + static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) { int ret; @@ -419,7 +423,8 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) platform_set_drvdata(pdev, wd); - ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); + ret = snd_soc_register_component(&pdev->dev, &au1xpsc_ac97_component, + &wd->dai_drv, 1); if (ret) return ret; @@ -431,7 +436,7 @@ static int au1xpsc_ac97_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); /* disable PSC completely */ au_writel(0, AC97_CFG(wd)); -- cgit v1.2.3 From 4edf87f5f7984812ce7dfb5320f198e91e60bb9c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:29:24 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on au1x psc-i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/au1x/psc-i2s.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 360b4e50d7c8..fe923a7bdc39 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -288,6 +288,10 @@ static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = { .ops = &au1xpsc_i2s_dai_ops, }; +static const struct snd_soc_component_driver au1xpsc_i2s_component = { + .name = "au1xpsc-i2s", +}; + static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) { struct resource *iores, *dmares; @@ -350,14 +354,15 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) platform_set_drvdata(pdev, wd); - return snd_soc_register_dai(&pdev->dev, &wd->dai_drv); + return snd_soc_register_component(&pdev->dev, &au1xpsc_i2s_component, + &wd->dai_drv, 1); } static int au1xpsc_i2s_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); au_writel(0, I2S_CFG(wd)); au_sync(); -- cgit v1.2.3 From bbedf1b25586d1b148a85600f29aad2241514c6f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:29:34 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on au1x ac97c Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/au1x/ac97c.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index ea7d9d157022..44b8dcecf571 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c @@ -223,6 +223,10 @@ static struct snd_soc_dai_driver au1xac97c_dai_driver = { .ops = &alchemy_ac97c_ops, }; +static const struct snd_soc_component_driver au1xac97c_component = { + .name = "au1xac97c", +}; + static int au1xac97c_drvprobe(struct platform_device *pdev) { int ret; @@ -268,7 +272,8 @@ static int au1xac97c_drvprobe(struct platform_device *pdev) platform_set_drvdata(pdev, ctx); - ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver); + ret = snd_soc_register_component(&pdev->dev, &au1xac97c_component, + &au1xac97c_dai_driver, 1); if (ret) return ret; @@ -280,7 +285,7 @@ static int au1xac97c_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */ -- cgit v1.2.3 From 3272c51bfab7db6e9dfd4deb4b99284abf2ed27c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:29:46 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on bf6xx i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/blackfin/bf6xx-i2s.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c index 8f337972f438..c02405cc007d 100644 --- a/sound/soc/blackfin/bf6xx-i2s.c +++ b/sound/soc/blackfin/bf6xx-i2s.c @@ -186,6 +186,10 @@ static struct snd_soc_dai_driver bfin_i2s_dai = { .ops = &bfin_i2s_dai_ops, }; +static const struct snd_soc_component_driver bfin_i2s_component = { + .name = "bfin-i2s", +}; + static int bfin_i2s_probe(struct platform_device *pdev) { struct sport_device *sport; @@ -197,7 +201,8 @@ static int bfin_i2s_probe(struct platform_device *pdev) return -ENODEV; /* register with the ASoC layers */ - ret = snd_soc_register_dai(dev, &bfin_i2s_dai); + ret = snd_soc_register_component(dev, &bfin_i2s_component, + &bfin_i2s_dai, 1); if (ret) { dev_err(dev, "Failed to register DAI: %d\n", ret); sport_delete(sport); @@ -212,7 +217,7 @@ static int bfin_i2s_remove(struct platform_device *pdev) { struct sport_device *sport = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); sport_delete(sport); return 0; -- cgit v1.2.3 From 514f6ac78b0b915760dd9b0f141504b262fa7ada Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:29:57 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on bf5xx ac97 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-ac97.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index 8e41bcb020eb..490217325975 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c @@ -282,6 +282,10 @@ static struct snd_soc_dai_driver bfin_ac97_dai = { .formats = SNDRV_PCM_FMTBIT_S16_LE, }, }; +static const struct snd_soc_component_driver bfin_ac97_component = { + .name = "bfin-ac97", +}; + static int asoc_bfin_ac97_probe(struct platform_device *pdev) { struct sport_device *sport_handle; @@ -331,7 +335,8 @@ static int asoc_bfin_ac97_probe(struct platform_device *pdev) goto sport_config_err; } - ret = snd_soc_register_dai(&pdev->dev, &bfin_ac97_dai); + ret = snd_soc_register_component(&pdev->dev, &bfin_ac97_component, + &bfin_ac97_dai, 1); if (ret) { pr_err("Failed to register DAI: %d\n", ret); goto sport_config_err; @@ -356,7 +361,7 @@ static int asoc_bfin_ac97_remove(struct platform_device *pdev) { struct sport_device *sport_handle = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + 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); -- cgit v1.2.3 From b56733bd2bd05aa28b44d42a807162c0922fc207 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:30:08 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on bf5xx i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-i2s.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 168d88bccb41..dd0c2a4f83a3 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -245,6 +245,10 @@ static struct snd_soc_dai_driver bf5xx_i2s_dai = { .ops = &bf5xx_i2s_dai_ops, }; +static const struct snd_soc_component_driver bf5xx_i2s_component = { + .name = "bf5xx-i2s", +}; + static int bf5xx_i2s_probe(struct platform_device *pdev) { struct sport_device *sport_handle; @@ -257,7 +261,8 @@ static int bf5xx_i2s_probe(struct platform_device *pdev) return -ENODEV; /* register with the ASoC layers */ - ret = snd_soc_register_dai(&pdev->dev, &bf5xx_i2s_dai); + ret = snd_soc_register_component(&pdev->dev, &bf5xx_i2s_component, + &bf5xx_i2s_dai, 1); if (ret) { pr_err("Failed to register DAI: %d\n", ret); sport_done(sport_handle); @@ -273,7 +278,7 @@ static int bf5xx_i2s_remove(struct platform_device *pdev) pr_debug("%s enter\n", __func__); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); sport_done(sport_handle); return 0; -- cgit v1.2.3 From 58309649b4feadea44c5cc3e5d410c34d81ef5d1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:30:20 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on bf5xx tdm Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/blackfin/bf5xx-tdm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c index c1e516ec53ad..69e9a3e935bd 100644 --- a/sound/soc/blackfin/bf5xx-tdm.c +++ b/sound/soc/blackfin/bf5xx-tdm.c @@ -249,6 +249,10 @@ static struct snd_soc_dai_driver bf5xx_tdm_dai = { .ops = &bf5xx_tdm_dai_ops, }; +static const struct snd_soc_component_driver bf5xx_tdm_component = { + .name = "bf5xx-tdm", +}; + static int bfin_tdm_probe(struct platform_device *pdev) { struct sport_device *sport_handle; @@ -282,7 +286,8 @@ static int bfin_tdm_probe(struct platform_device *pdev) goto sport_config_err; } - ret = snd_soc_register_dai(&pdev->dev, &bf5xx_tdm_dai); + ret = snd_soc_register_component(&pdev->dev, &bf5xx_tdm_component, + &bf5xx_tdm_dai, 1); if (ret) { pr_err("Failed to register DAI: %d\n", ret); goto sport_config_err; @@ -299,7 +304,7 @@ static int bfin_tdm_remove(struct platform_device *pdev) { struct sport_device *sport_handle = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); sport_done(sport_handle); return 0; -- cgit v1.2.3 From 426c340853da49e7c55fe856408ea44f8852d8c8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:30:32 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on ep93xx ac97 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/cirrus/ep93xx-ac97.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index 1738d28fb04f..e593c1e4e1dd 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c @@ -353,6 +353,10 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = { .ops = &ep93xx_ac97_dai_ops, }; +static const struct snd_soc_component_driver ep93xx_ac97_component = { + .name = "ep93xx-ac97", +}; + static int ep93xx_ac97_probe(struct platform_device *pdev) { struct ep93xx_ac97_info *info; @@ -390,7 +394,8 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) ep93xx_ac97_info = info; platform_set_drvdata(pdev, info); - ret = snd_soc_register_dai(&pdev->dev, &ep93xx_ac97_dai); + ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component, + &ep93xx_ac97_dai, 1); if (ret) goto fail; @@ -407,7 +412,7 @@ static int ep93xx_ac97_remove(struct platform_device *pdev) { struct ep93xx_ac97_info *info = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); /* disable the AC97 controller */ ep93xx_ac97_write_reg(info, AC97GCR, 0); -- cgit v1.2.3 From ec05085170fcac5cba66306155083f120dec6ff6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:30:43 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on ep93xx i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/cirrus/ep93xx-i2s.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c index 323ed69b7975..8d244be275d6 100644 --- a/sound/soc/cirrus/ep93xx-i2s.c +++ b/sound/soc/cirrus/ep93xx-i2s.c @@ -366,6 +366,10 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = { .ops = &ep93xx_i2s_dai_ops, }; +static const struct snd_soc_component_driver ep93xx_i2s_component = { + .name = "ep93xx-i2s", +}; + static int ep93xx_i2s_probe(struct platform_device *pdev) { struct ep93xx_i2s_info *info; @@ -405,7 +409,8 @@ static int ep93xx_i2s_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, info); info->dma_params = ep93xx_i2s_dma_params; - err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai); + err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component, + &ep93xx_i2s_dai, 1); if (err) goto fail_put_lrclk; @@ -426,7 +431,7 @@ static int ep93xx_i2s_remove(struct platform_device *pdev) { struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); dev_set_drvdata(&pdev->dev, NULL); clk_put(info->lrclk); clk_put(info->sclk); -- cgit v1.2.3 From f200c02beb5ddf4d886b4aca53f9f9f8bf332d06 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:31:53 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on mpc5200 i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/fsl/mpc5200_psc_i2s.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index b95b966f25a0..f4efaadb80a2 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -148,6 +148,10 @@ static struct snd_soc_dai_driver psc_i2s_dai[] = {{ .ops = &psc_i2s_dai_ops, } }; +static const struct snd_soc_component_driver psc_i2s_component = { + .name = "mpc5200-i2s", +}; + /* --------------------------------------------------------------------- * OF platform bus binding code: * - Probe/remove operations @@ -163,7 +167,8 @@ static int psc_i2s_of_probe(struct platform_device *op) if (rc != 0) return rc; - rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); + rc = snd_soc_register_component(&op->dev, &psc_i2s_component, + psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); if (rc != 0) { pr_err("Failed to register DAI\n"); return rc; @@ -208,7 +213,7 @@ static int psc_i2s_of_probe(struct platform_device *op) static int psc_i2s_of_remove(struct platform_device *op) { mpc5200_audio_dma_destroy(op); - snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai)); + snd_soc_unregister_component(&op->dev); return 0; } -- cgit v1.2.3 From 3580aa10fbb3a0ffbca9853dc827ea84f1073748 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:32:04 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on fsl ssi Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 7decbd9b2340..fe04c67f8fb8 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -574,6 +574,10 @@ static struct snd_soc_dai_driver fsl_ssi_dai_template = { .ops = &fsl_ssi_dai_ops, }; +static const struct snd_soc_component_driver fsl_ssi_component = { + .name = "fsl-ssi", +}; + /* Show the statistics of a flag only if its interrupt is enabled. The * compiler will optimze this code to a no-op if the interrupt is not * enabled. @@ -782,7 +786,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) /* Register with ASoC */ dev_set_drvdata(&pdev->dev, ssi_private); - ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); + ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component, + &ssi_private->cpu_dai_drv, 1); if (ret) { dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); goto error_dev; @@ -835,7 +840,7 @@ done: error_dai: if (ssi_private->ssi_on_imx) platform_device_unregister(ssi_private->imx_pcm_pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); error_dev: dev_set_drvdata(&pdev->dev, NULL); @@ -873,7 +878,7 @@ static int fsl_ssi_remove(struct platform_device *pdev) clk_disable_unprepare(ssi_private->clk); clk_put(ssi_private->clk); } - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); device_remove_file(&pdev->dev, &ssi_private->dev_attr); free_irq(ssi_private->irq, ssi_private); -- cgit v1.2.3 From c22fd5ef0fcccc8e960f307893fc5b3de68512d7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:32:15 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on imx ssi Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/fsl/imx-ssi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 55464a5b0706..90110ada270d 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -413,6 +413,10 @@ static struct snd_soc_dai_driver imx_ac97_dai = { .ops = &imx_ssi_pcm_dai_ops, }; +static const struct snd_soc_component_driver imx_component = { + .name = DRV_NAME, +}; + static void setup_channel_to_ac97(struct imx_ssi *imx_ssi) { void __iomem *base = imx_ssi->base; @@ -586,7 +590,8 @@ static int imx_ssi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ssi); - ret = snd_soc_register_dai(&pdev->dev, dai); + ret = snd_soc_register_component(&pdev->dev, &imx_component, + dai, 1); if (ret) { dev_err(&pdev->dev, "register DAI failed\n"); goto failed_register; @@ -627,7 +632,7 @@ failed_pdev_alloc: failed_pdev_fiq_add: platform_device_put(ssi->soc_platform_pdev_fiq); failed_pdev_fiq_alloc: - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); failed_register: release_mem_region(res->start, resource_size(res)); failed_get_resource: @@ -645,7 +650,7 @@ static int imx_ssi_remove(struct platform_device *pdev) platform_device_unregister(ssi->soc_platform_pdev); platform_device_unregister(ssi->soc_platform_pdev_fiq); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); if (ssi->flags & IMX_SSI_USE_AC97) ac97_ssi = NULL; -- cgit v1.2.3 From 29cc15cfd2db4045d1c89d867d05bce6db76037e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:32:28 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on jz4740 i2s Signed-off-by: Kuninori Morimoto Acked-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/jz4740/jz4740-i2s.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 6cef491f4823..9a126441c5f3 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -425,6 +425,10 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = { .resume = jz4740_i2s_resume, }; +static const struct snd_soc_component_driver jz4740_i2s_component = { + .name = "jz4740-i2s", +}; + static int jz4740_i2s_dev_probe(struct platform_device *pdev) { struct jz4740_i2s *i2s; @@ -469,7 +473,8 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, i2s); - ret = snd_soc_register_dai(&pdev->dev, &jz4740_i2s_dai); + ret = snd_soc_register_component(&pdev->dev, &jz4740_i2s_component, + &jz4740_i2s_dai, 1); if (ret) { dev_err(&pdev->dev, "Failed to register DAI\n"); @@ -496,7 +501,7 @@ static int jz4740_i2s_dev_remove(struct platform_device *pdev) { struct jz4740_i2s *i2s = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); clk_put(i2s->clk_i2s); clk_put(i2s->clk_aic); -- cgit v1.2.3 From 83d85f53adf38f5021afd921a84efd53c44aff56 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:32:39 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on kirkwood i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-i2s.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index c74c89065493..befe68f59285 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -451,6 +451,10 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = { .ops = &kirkwood_i2s_dai_ops, }; +static const struct snd_soc_component_driver kirkwood_i2s_component = { + .name = DRV_NAME, +}; + static int kirkwood_i2s_dev_probe(struct platform_device *pdev) { struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; @@ -524,10 +528,11 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; } - err = snd_soc_register_dai(&pdev->dev, soc_dai); + err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component, + soc_dai, 1); if (!err) return 0; - dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); + dev_err(&pdev->dev, "snd_soc_register_component failed\n"); if (!IS_ERR(priv->extclk)) { clk_disable_unprepare(priv->extclk); @@ -542,7 +547,7 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev) { struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); if (!IS_ERR(priv->extclk)) { clk_disable_unprepare(priv->extclk); -- cgit v1.2.3 From b1c36861315ce37c2fee8c1c90433068866a8871 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:32:50 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on sst Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/mid-x86/sst_platform.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index a263cbed8624..31a829cca5ef 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -165,6 +165,10 @@ static struct snd_soc_dai_driver sst_platform_dai[] = { }, }; +static const struct snd_soc_component_driver sst_component = { + .name = "sst", +}; + /* helper functions */ static inline void sst_set_stream_status(struct sst_runtime_stream *stream, int state) @@ -683,7 +687,7 @@ static int sst_platform_probe(struct platform_device *pdev) return ret; } - ret = snd_soc_register_dais(&pdev->dev, + ret = snd_soc_register_component(&pdev->dev, &sst_component, sst_platform_dai, ARRAY_SIZE(sst_platform_dai)); if (ret) { pr_err("registering cpu dais failed\n"); @@ -695,7 +699,7 @@ static int sst_platform_probe(struct platform_device *pdev) static int sst_platform_remove(struct platform_device *pdev) { - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sst_platform_dai)); + snd_soc_unregister_component(&pdev->dev); snd_soc_unregister_platform(&pdev->dev); pr_debug("sst_platform_remove success\n"); return 0; -- cgit v1.2.3 From 026240bb155bb8f83b9425812f52661fcbaa0629 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:33:02 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on mxs saif Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 3a2aa1d19b93..3e78ba866681 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -627,6 +627,10 @@ static struct snd_soc_dai_driver mxs_saif_dai = { .ops = &mxs_saif_dai_ops, }; +static const struct snd_soc_component_driver mxs_saif_component = { + .name = "mxs-saif", +}; + static irqreturn_t mxs_saif_irq(int irq, void *dev_id) { struct mxs_saif *saif = dev_id; @@ -763,7 +767,8 @@ static int mxs_saif_probe(struct platform_device *pdev) platform_set_drvdata(pdev, saif); - ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); + ret = snd_soc_register_component(&pdev->dev, &mxs_saif_component, + &mxs_saif_dai, 1); if (ret) { dev_err(&pdev->dev, "register DAI failed\n"); return ret; @@ -778,7 +783,7 @@ static int mxs_saif_probe(struct platform_device *pdev) return 0; failed_pdev_alloc: - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return ret; } @@ -786,7 +791,7 @@ failed_pdev_alloc: static int mxs_saif_remove(struct platform_device *pdev) { mxs_pcm_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From 7fc34cc3f3c7a0827115bed2139476bc01638a27 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:33:13 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on nuc900 ac97 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/nuc900/nuc900-ac97.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c index 0418467a4848..fe3285ceaf5b 100644 --- a/sound/soc/nuc900/nuc900-ac97.c +++ b/sound/soc/nuc900/nuc900-ac97.c @@ -314,6 +314,10 @@ static struct snd_soc_dai_driver nuc900_ac97_dai = { .ops = &nuc900_ac97_dai_ops, }; +static const struct snd_soc_component_driver nuc900_ac97_component = { + .name = "nuc900-ac97", +}; + static int nuc900_ac97_drvprobe(struct platform_device *pdev) { struct nuc900_audio *nuc900_audio; @@ -361,7 +365,8 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev) nuc900_ac97_data = nuc900_audio; - ret = snd_soc_register_dai(&pdev->dev, &nuc900_ac97_dai); + ret = snd_soc_register_component(&pdev->dev, &nuc900_ac97_component, + &nuc900_ac97_dai, 1); if (ret) goto out3; @@ -384,7 +389,7 @@ out0: static int nuc900_ac97_drvremove(struct platform_device *pdev) { - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); clk_put(nuc900_ac97_data->clk); iounmap(nuc900_ac97_data->mmio); -- cgit v1.2.3 From 43cd814a73903779ab5523ef7a709864456fe9c4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:33:25 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on omap mcbsp Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 8d2defd6fdbe..f51685d72fdb 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -586,6 +586,10 @@ static struct snd_soc_dai_driver omap_mcbsp_dai = { .ops = &mcbsp_dai_ops, }; +static const struct snd_soc_component_driver omap_mcbsp_component = { + .name = "omap-mcbsp", +}; + static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -793,7 +797,8 @@ static int asoc_mcbsp_probe(struct platform_device *pdev) ret = omap_mcbsp_init(pdev); if (!ret) - return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai); + return snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, + &omap_mcbsp_dai, 1); return ret; } @@ -802,7 +807,7 @@ static int asoc_mcbsp_remove(struct platform_device *pdev) { struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); if (mcbsp->pdata->ops && mcbsp->pdata->ops->free) mcbsp->pdata->ops->free(mcbsp->id); -- cgit v1.2.3 From 58709a329eaf4b61bc348305ec387b7964bb0320 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:33:37 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on omap mcpdm Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 5ca11bdac21e..4cc98071aa91 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -420,6 +420,10 @@ static struct snd_soc_dai_driver omap_mcpdm_dai = { .ops = &omap_mcpdm_dai_ops, }; +static const struct snd_soc_component_driver omap_mcpdm_component = { + .name = "omap-mcpdm", +}; + void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, u8 rx1, u8 rx2) { @@ -480,12 +484,13 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) mcpdm->dev = &pdev->dev; - return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); + return snd_soc_register_component(&pdev->dev, &omap_mcpdm_component, + &omap_mcpdm_dai, 1); } static int asoc_mcpdm_remove(struct platform_device *pdev) { - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From ed22853a5bf51736e5f7e42fddacd053e38ddf01 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:33:51 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on omap dmic Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index ba49ccd9eed9..4c54542895b0 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -448,6 +448,10 @@ static struct snd_soc_dai_driver omap_dmic_dai = { .ops = &omap_dmic_dai_ops, }; +static const struct snd_soc_component_driver omap_dmic_component = { + .name = "omap-dmic", +}; + static int asoc_dmic_probe(struct platform_device *pdev) { struct omap_dmic *dmic; @@ -507,7 +511,8 @@ static int asoc_dmic_probe(struct platform_device *pdev) goto err_put_clk; } - ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai); + ret = snd_soc_register_component(&pdev->dev, &omap_dmic_component, + &omap_dmic_dai, 1); if (ret) goto err_put_clk; @@ -522,7 +527,7 @@ static int asoc_dmic_remove(struct platform_device *pdev) { struct omap_dmic *dmic = platform_get_drvdata(pdev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); clk_put(dmic->fclk); return 0; -- cgit v1.2.3 From 0ba7f849eceed0564928f83aa8ec51906e69336d Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:34:01 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on omap hdmi Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/omap/omap-hdmi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index 32fa840c493e..7e120ccc20e1 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c @@ -264,6 +264,10 @@ static struct snd_soc_dai_driver omap_hdmi_dai = { .ops = &omap_hdmi_dai_ops, }; +static const struct snd_soc_component_driver omap_hdmi_component = { + .name = DRV_NAME, +}; + static int omap_hdmi_probe(struct platform_device *pdev) { int ret; @@ -321,7 +325,8 @@ static int omap_hdmi_probe(struct platform_device *pdev) } dev_set_drvdata(&pdev->dev, hdmi_data); - ret = snd_soc_register_dai(&pdev->dev, &omap_hdmi_dai); + ret = snd_soc_register_component(&pdev->dev, &omap_hdmi_component, + &omap_hdmi_dai, 1); return ret; } @@ -330,7 +335,7 @@ static int omap_hdmi_remove(struct platform_device *pdev) { struct hdmi_priv *hdmi_data = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); if (hdmi_data == NULL) { dev_err(&pdev->dev, "cannot obtain HDMi data\n"); -- cgit v1.2.3 From e580f1ced92e0911cce71c3cae7c6e82159c82b4 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:34:12 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on pxa ssp Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/pxa/pxa-ssp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index d3eb0c2eec77..6f4dd7543e82 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -794,14 +794,19 @@ static struct snd_soc_dai_driver pxa_ssp_dai = { .ops = &pxa_ssp_dai_ops, }; +static const struct snd_soc_component_driver pxa_ssp_component = { + .name = "pxa-ssp", +}; + static int asoc_ssp_probe(struct platform_device *pdev) { - return snd_soc_register_dai(&pdev->dev, &pxa_ssp_dai); + return snd_soc_register_component(&pdev->dev, &pxa_ssp_component, + &pxa_ssp_dai, 1); } static int asoc_ssp_remove(struct platform_device *pdev) { - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From ad53232c1f364a1c4172218856c4e44c527b541e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:34:23 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on pxa2xx ac97 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/pxa/pxa2xx-ac97.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 88d2cc6a0ae2..57ea8e6c5488 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -233,6 +233,10 @@ static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = { }, }; +static const struct snd_soc_component_driver pxa_ac97_component = { + .name = "pxa-ac97", +}; + static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) { if (pdev->id != -1) { @@ -244,13 +248,13 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) * driver to do interesting things with the clocking to get us up * and running. */ - return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai_driver, - ARRAY_SIZE(pxa_ac97_dai_driver)); + return snd_soc_register_component(&pdev->dev, &pxa_ac97_component, + pxa_ac97_dai_driver, ARRAY_SIZE(pxa_ac97_dai_driver)); } static int pxa2xx_ac97_dev_remove(struct platform_device *pdev) { - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver)); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From bccf7d8bf96bd0c31c94754a2f5e2d1f295df2b7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:34:37 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on pxa2xx i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/pxa/pxa2xx-i2s.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 6b1a06f67564..f7ca71664112 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -360,14 +360,19 @@ static struct snd_soc_dai_driver pxa_i2s_dai = { .symmetric_rates = 1, }; +static const struct snd_soc_component_driver pxa_i2s_component = { + .name = "pxa-i2s", +}; + static int pxa2xx_i2s_drv_probe(struct platform_device *pdev) { - return snd_soc_register_dai(&pdev->dev, &pxa_i2s_dai); + return snd_soc_register_component(&pdev->dev, &pxa_i2s_component, + &pxa_i2s_dai, 1); } static int pxa2xx_i2s_drv_remove(struct platform_device *pdev) { - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From 425f3708949a54aa2f01537eeb6fae33f937279b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:34:48 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on mmp sspa Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/pxa/mmp-sspa.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 9140c4abafbc..a64779980177 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -405,6 +405,10 @@ struct snd_soc_dai_driver mmp_sspa_dai = { .ops = &mmp_sspa_dai_ops, }; +static const struct snd_soc_component_driver mmp_sspa_component = { + .name = "mmp-sspa", +}; + static int asoc_mmp_sspa_probe(struct platform_device *pdev) { struct sspa_priv *priv; @@ -450,7 +454,8 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev) priv->dai_fmt = (unsigned int) -1; platform_set_drvdata(pdev, priv); - return snd_soc_register_dai(&pdev->dev, &mmp_sspa_dai); + return snd_soc_register_component(&pdev->dev, &mmp_sspa_component, + &mmp_sspa_dai, 1); } static int asoc_mmp_sspa_remove(struct platform_device *pdev) @@ -460,7 +465,7 @@ static int asoc_mmp_sspa_remove(struct platform_device *pdev) clk_disable(priv->audio_clk); clk_put(priv->audio_clk); clk_put(priv->sysclk); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From cd5e4d0b2f7065eaef56725ebcd6bf3278d33b20 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:34:59 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on s6000 i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/s6000/s6000-i2s.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index fee4d477a49c..73bb99f0109a 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c @@ -436,6 +436,10 @@ static struct snd_soc_dai_driver s6000_i2s_dai = { .ops = &s6000_i2s_dai_ops, }; +static const struct snd_soc_component_driver s6000_i2s_component = { + .name = "s6000-i2s", +}; + static int s6000_i2s_probe(struct platform_device *pdev) { struct s6000_i2s_dev *dev; @@ -543,7 +547,8 @@ static int s6000_i2s_probe(struct platform_device *pdev) S6_I2S_INT_UNDERRUN | S6_I2S_INT_OVERRUN); - ret = snd_soc_register_dai(&pdev->dev, &s6000_i2s_dai); + ret = snd_soc_register_component(&pdev->dev, &s6000_i2s_component, + &s6000_i2s_dai, 1); if (ret) goto err_release_dev; @@ -572,7 +577,7 @@ static void s6000_i2s_remove(struct platform_device *pdev) struct resource *region; void __iomem *mmio = dev->scbbase; - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); s6000_i2s_stop_channel(dev, 0); s6000_i2s_stop_channel(dev, 1); -- cgit v1.2.3 From 5642ddff274172b42bb9d1f77b75e006a33b65b2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:35:11 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on s3c24xx i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/samsung/s3c24xx-i2s.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 13f6dd1ceb00..5403176b2aa3 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -465,11 +465,16 @@ static struct snd_soc_dai_driver s3c24xx_i2s_dai = { .ops = &s3c24xx_i2s_dai_ops, }; +static const struct snd_soc_component_driver s3c24xx_i2s_component = { + .name = "s3c24xx-i2s", +}; + static int s3c24xx_iis_dev_probe(struct platform_device *pdev) { int ret = 0; - ret = snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai); + ret = snd_soc_register_component(&pdev->dev, &s3c24xx_i2s_component, + &s3c24xx_i2s_dai, 1); if (ret) { pr_err("failed to register the dai\n"); return ret; @@ -483,14 +488,14 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev) return 0; err: - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return ret; } static int s3c24xx_iis_dev_remove(struct platform_device *pdev) { asoc_dma_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From eca3b01d0885544cbf452c5298afd7c3ccb53a50 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:35:22 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on s3c i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/samsung/s3c-i2s-v2.c | 9 +++++---- sound/soc/samsung/s3c-i2s-v2.h | 7 ++++--- sound/soc/samsung/s3c2412-i2s.c | 12 +++++++++--- 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 7a73380b3560..20e98d1dded2 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -731,8 +731,9 @@ static int s3c2412_i2s_resume(struct snd_soc_dai *dai) #define s3c2412_i2s_resume NULL #endif -int s3c_i2sv2_register_dai(struct device *dev, int id, - struct snd_soc_dai_driver *drv) +int s3c_i2sv2_register_component(struct device *dev, int id, + struct snd_soc_component_driver *cmp_drv, + struct snd_soc_dai_driver *dai_drv) { struct snd_soc_dai_ops *ops = drv->ops; @@ -750,8 +751,8 @@ int s3c_i2sv2_register_dai(struct device *dev, int id, drv->suspend = s3c2412_i2s_suspend; drv->resume = s3c2412_i2s_resume; - return snd_soc_register_dai(dev, drv); + return snd_soc_register_component(dev, cmp_drv, dai_drv, 1); } -EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai); +EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component); MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h index f8297d9bb8a3..90abab364b49 100644 --- a/sound/soc/samsung/s3c-i2s-v2.h +++ b/sound/soc/samsung/s3c-i2s-v2.h @@ -92,7 +92,7 @@ extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, unsigned long base); /** - * s3c_i2sv2_register_dai - register dai with soc core + * s3c_i2sv2_register_component - register component and dai with soc core * @dev: DAI device * @id: DAI ID * @drv: The driver structure to register @@ -100,7 +100,8 @@ extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, * Fill in any missing fields and then register the given dai with the * soc core. */ -extern int s3c_i2sv2_register_dai(struct device *dev, int id, - struct snd_soc_dai_driver *drv); +extern int s3c_i2sv2_register_component(struct device *dev, int id, + struct snd_soc_component_driver *cmp_drv, + struct snd_soc_dai_driver *dai_drv); #endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 221337716393..47e23864ea72 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -160,11 +160,17 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = { .ops = &s3c2412_i2s_dai_ops, }; +static const struct snd_soc_component_driver s3c2412_i2s_component = { + .name = "s3c2412-i2s", +}; + static int s3c2412_iis_dev_probe(struct platform_device *pdev) { int ret = 0; - ret = s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); + ret = s3c_i2sv2_register_component(&pdev->dev, -1, + &s3c2412_i2s_component, + &s3c2412_i2s_dai); if (ret) { pr_err("failed to register the dai\n"); return ret; @@ -178,14 +184,14 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev) return 0; err: - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return ret; } static int s3c2412_iis_dev_remove(struct platform_device *pdev) { asoc_dma_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From 6d717f3ef571e98be54b9f6b12cb5b03fbd515cd Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:35:33 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on s3c ac97 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/samsung/ac97.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 0df3c5644cfa..32ff594954bc 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -370,6 +370,10 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { }, }; +static const struct snd_soc_component_driver s3c_ac97_component = { + .name = "s3c-ac97", +}; + static int s3c_ac97_probe(struct platform_device *pdev) { struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; @@ -457,8 +461,8 @@ static int s3c_ac97_probe(struct platform_device *pdev) goto err4; } - ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai, - ARRAY_SIZE(s3c_ac97_dai)); + ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component, + s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); if (ret) goto err5; @@ -470,7 +474,7 @@ static int s3c_ac97_probe(struct platform_device *pdev) return 0; err6: - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); + snd_soc_unregister_component(&pdev->dev); err5: free_irq(irq_res->start, NULL); err4: @@ -490,7 +494,7 @@ static int s3c_ac97_remove(struct platform_device *pdev) struct resource *mem_res, *irq_res; asoc_dma_platform_unregister(&pdev->dev); - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); + snd_soc_unregister_component(&pdev->dev); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq_res) -- cgit v1.2.3 From c3764d8bb49dd64be3cba20413ace5887e8dbdcb Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:35:44 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on samsung spdif Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/samsung/spdif.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 5008e5bd6ed8..2e5ebb2f1982 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -357,6 +357,10 @@ static struct snd_soc_dai_driver samsung_spdif_dai = { .resume = spdif_resume, }; +static const struct snd_soc_component_driver samsung_spdif_component = { + .name = "samsung-spdif", +}; + static int spdif_probe(struct platform_device *pdev) { struct s3c_audio_pdata *spdif_pdata; @@ -424,7 +428,8 @@ static int spdif_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, spdif); - ret = snd_soc_register_dai(&pdev->dev, &samsung_spdif_dai); + ret = snd_soc_register_component(&pdev->dev, &samsung_spdif_component, + &samsung_spdif_dai, 1); if (ret != 0) { dev_err(&pdev->dev, "fail to register dai\n"); goto err4; @@ -445,7 +450,7 @@ static int spdif_probe(struct platform_device *pdev) return 0; err5: - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); err4: iounmap(spdif->regs); err3: @@ -466,7 +471,7 @@ static int spdif_remove(struct platform_device *pdev) struct resource *mem_res; asoc_dma_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); iounmap(spdif->regs); -- cgit v1.2.3 From 4b828535f710604b28d3d9de8916bf99b33817f7 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:35:55 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on samsung i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index d7231e336a7c..efa73147dfb8 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -963,6 +963,10 @@ static const struct snd_soc_dai_ops samsung_i2s_dai_ops = { .delay = i2s_delay, }; +static const struct snd_soc_component_driver samsung_i2s_component = { + .name = "samsung-i2s", +}; + #define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ @@ -1107,8 +1111,9 @@ static int samsung_i2s_probe(struct platform_device *pdev) if (samsung_dai_type == TYPE_SEC) { sec_dai = dev_get_drvdata(&pdev->dev); - snd_soc_register_dai(&sec_dai->pdev->dev, - &sec_dai->i2s_dai_drv); + snd_soc_register_component(&sec_dai->pdev->dev, + &samsung_i2s_component, + &sec_dai->i2s_dai_drv, 1); asoc_dma_platform_register(&pdev->dev); return 0; } @@ -1237,7 +1242,8 @@ static int samsung_i2s_probe(struct platform_device *pdev) } } - snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); + snd_soc_register_component(&pri_dai->pdev->dev, &samsung_i2s_component, + &pri_dai->i2s_dai_drv, 1); pm_runtime_enable(&pdev->dev); @@ -1276,7 +1282,7 @@ static int samsung_i2s_remove(struct platform_device *pdev) i2s->sec_dai = NULL; asoc_dma_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From fc466ba3ee01cef840523f9bbbf6811e111168c3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:36:06 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on samsung pcm Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/samsung/pcm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 13bab79ad93d..1566afe9ef52 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -490,6 +490,10 @@ static struct snd_soc_dai_driver s3c_pcm_dai[] = { }, }; +static const struct snd_soc_component_driver s3c_pcm_component = { + .name = "s3c-pcm", +}; + static int s3c_pcm_dev_probe(struct platform_device *pdev) { struct s3c_pcm_info *pcm; @@ -583,7 +587,8 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]); + ret = snd_soc_register_component(&pdev->dev, &s3c_pcm_component, + &s3c_pcm_dai[pdev->id], 1); if (ret != 0) { dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); goto err5; @@ -598,7 +603,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) return 0; err6: - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); err5: clk_disable_unprepare(pcm->pclk); clk_put(pcm->pclk); @@ -619,7 +624,7 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev) struct resource *mem_res; asoc_dma_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); pm_runtime_disable(&pdev->dev); -- cgit v1.2.3 From 1dfec3954e9884c79ee29c430811264318268365 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:36:17 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on goni_wm8994 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/samsung/goni_wm8994.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index d37ede58e0a8..415ad81999c4 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c @@ -218,6 +218,10 @@ static struct snd_soc_dai_driver voice_dai = { .formats = SNDRV_PCM_FMTBIT_S16_LE,}, }; +static const struct snd_soc_component_driver voice_component = { + .name = "goni-voice", +}; + static struct snd_soc_ops goni_voice_ops = { .hw_params = goni_voice_hw_params, }; @@ -270,7 +274,8 @@ static int __init goni_init(void) return -ENOMEM; /* register voice DAI here */ - ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai); + ret = snd_soc_register_component(&goni_snd_device->dev, &voice_component, + &voice_dai, 1); if (ret) { platform_device_put(goni_snd_device); return ret; @@ -280,7 +285,7 @@ static int __init goni_init(void) ret = platform_device_add(goni_snd_device); if (ret) { - snd_soc_unregister_dai(&goni_snd_device->dev); + snd_soc_unregister_component(&goni_snd_device->dev); platform_device_put(goni_snd_device); } @@ -289,7 +294,7 @@ static int __init goni_init(void) static void __exit goni_exit(void) { - snd_soc_unregister_dai(&goni_snd_device->dev); + snd_soc_unregister_component(&goni_snd_device->dev); platform_device_unregister(goni_snd_device); } -- cgit v1.2.3 From cd9003a200ad1fdde20e7e687d8e376b62e171cf Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:36:27 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on sh4 ssi Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/ssi.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index c8e73a703934..e889405ebd38 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c @@ -379,15 +379,19 @@ static struct snd_soc_dai_driver sh4_ssi_dai[] = { #endif }; +static const struct snd_soc_component_driver sh4_ssi_component = { + .name = "sh4-ssi", +}; + static int sh4_soc_dai_probe(struct platform_device *pdev) { - return snd_soc_register_dais(&pdev->dev, sh4_ssi_dai, - ARRAY_SIZE(sh4_ssi_dai)); + return snd_soc_register_component(&pdev->dev, &sh4_ssi_component, + sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai)); } static int sh4_soc_dai_remove(struct platform_device *pdev) { - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_ssi_dai)); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From 73d86d9808ce4885d515a05454a26d5a8533c01a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:36:49 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on sh4 hac Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/hac.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index 4cc2d64ef476..af19f77b7bf0 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -310,15 +310,19 @@ static struct snd_soc_dai_driver sh4_hac_dai[] = { #endif }; +static const struct snd_soc_component_driver sh4_hac_component = { + .name = "sh4-hac", +}; + static int hac_soc_platform_probe(struct platform_device *pdev) { - return snd_soc_register_dais(&pdev->dev, sh4_hac_dai, - ARRAY_SIZE(sh4_hac_dai)); + return snd_soc_register_component(&pdev->dev, &sh4_hac_component, + sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); } static int hac_soc_platform_remove(struct platform_device *pdev) { - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(sh4_hac_dai)); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From a582d44b1352176df012f512124c4395bb60eaf5 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:37:00 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on spear spdif out Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/spear/spdif_out.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c index 5eac4cda2fd7..1e3c3dda3598 100644 --- a/sound/soc/spear/spdif_out.c +++ b/sound/soc/spear/spdif_out.c @@ -270,6 +270,10 @@ static struct snd_soc_dai_driver spdif_out_dai = { .ops = &spdif_out_dai_ops, }; +static const struct snd_soc_component_driver spdif_out_component = { + .name = "spdif-out", +}; + static int spdif_out_probe(struct platform_device *pdev) { struct spdif_out_dev *host; @@ -314,7 +318,8 @@ static int spdif_out_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, host); - ret = snd_soc_register_dai(&pdev->dev, &spdif_out_dai); + ret = snd_soc_register_component(&pdev->dev, &spdif_out_component, + &spdif_out_dai, 1); if (ret != 0) { clk_put(host->clk); return ret; @@ -327,7 +332,7 @@ static int spdif_out_remove(struct platform_device *pdev) { struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); dev_set_drvdata(&pdev->dev, NULL); clk_put(host->clk); -- cgit v1.2.3 From 669b497674b81062a2fbd735a23c7ae48ac43a35 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:37:11 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on spear spdif in Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/spear/spdif_in.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c index c7c4b20395bb..14d57e89bcba 100644 --- a/sound/soc/spear/spdif_in.c +++ b/sound/soc/spear/spdif_in.c @@ -170,6 +170,10 @@ struct snd_soc_dai_driver spdif_in_dai = { .ops = &spdif_in_dai_ops, }; +static const struct snd_soc_component_driver spdif_in_component = { + .name = "spdif-in", +}; + static irqreturn_t spdif_in_irq(int irq, void *arg) { struct spdif_in_dev *host = (struct spdif_in_dev *)arg; @@ -258,7 +262,8 @@ static int spdif_in_probe(struct platform_device *pdev) return ret; } - ret = snd_soc_register_dai(&pdev->dev, &spdif_in_dai); + ret = snd_soc_register_component(&pdev->dev, &spdif_in_component, + &spdif_in_dai, 1); if (ret != 0) { clk_put(host->clk); return ret; @@ -271,7 +276,7 @@ static int spdif_in_remove(struct platform_device *pdev) { struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); dev_set_drvdata(&pdev->dev, NULL); clk_put(host->clk); -- cgit v1.2.3 From 65328454fbf7d76dbaadc699c2692366af9fe441 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:37:22 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on tegra30 i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/tegra/tegra30_i2s.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index f4e1ce82750a..f138d8fea977 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -336,6 +336,10 @@ static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { .symmetric_rates = 1, }; +static const struct snd_soc_component_driver tegra30_i2s_component = { + .name = DRV_NAME, +}; + static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -464,7 +468,8 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) goto err_pm_disable; } - ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); + ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component, + &i2s->dai, 1); if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; @@ -474,13 +479,13 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev) ret = tegra_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); - goto err_unregister_dai; + goto err_unregister_component; } return 0; -err_unregister_dai: - snd_soc_unregister_dai(&pdev->dev); +err_unregister_component: + snd_soc_unregister_component(&pdev->dev); err_suspend: if (!pm_runtime_status_suspended(&pdev->dev)) tegra30_i2s_runtime_suspend(&pdev->dev); @@ -501,7 +506,7 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev) tegra30_i2s_runtime_suspend(&pdev->dev); tegra_pcm_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); clk_put(i2s->clk_i2s); -- cgit v1.2.3 From 094e1a3d7d7d456b504058ed40ea19d40e05a7ff Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:37:33 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on tegra20 spdif Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_spdif.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index 04771d14d343..6fce0be5eaa3 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -182,6 +182,10 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = { .ops = &tegra20_spdif_dai_ops, }; +static const struct snd_soc_component_driver tegra20_spdif_component = { + .name = DRV_NAME, +}; + static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -329,7 +333,8 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) goto err_pm_disable; } - ret = snd_soc_register_dai(&pdev->dev, &tegra20_spdif_dai); + ret = snd_soc_register_component(&pdev->dev, &tegra20_spdif_component, + &tegra20_spdif_dai, 1); if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; @@ -339,13 +344,13 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) ret = tegra_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); - goto err_unregister_dai; + goto err_unregister_component; } return 0; -err_unregister_dai: - snd_soc_unregister_dai(&pdev->dev); +err_unregister_component: + snd_soc_unregister_component(&pdev->dev); err_suspend: if (!pm_runtime_status_suspended(&pdev->dev)) tegra20_spdif_runtime_suspend(&pdev->dev); @@ -366,7 +371,7 @@ static int tegra20_spdif_platform_remove(struct platform_device *pdev) tegra20_spdif_runtime_suspend(&pdev->dev); tegra_pcm_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); clk_put(spdif->clk_spdif_out); -- cgit v1.2.3 From 359e2cb749a896ab7d2e2320892e6fe8457d1cfc Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:37:44 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on tegra20 ac97 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_ac97.c | 15 ++++++++++----- sound/soc/tegra/tegra_wm9712.c | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c index 336dcdd3e8a4..b5cee92f82e8 100644 --- a/sound/soc/tegra/tegra20_ac97.c +++ b/sound/soc/tegra/tegra20_ac97.c @@ -248,6 +248,10 @@ static struct snd_soc_dai_driver tegra20_ac97_dai = { .ops = &tegra20_ac97_dai_ops, }; +static const struct snd_soc_component_driver tegra20_ac97_component = { + .name = DRV_NAME, +}; + static bool tegra20_ac97_wr_rd_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -398,7 +402,8 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) ac97->playback_dma_data.width = 32; ac97->playback_dma_data.req_sel = of_dma[1]; - ret = snd_soc_register_dais(&pdev->dev, &tegra20_ac97_dai, 1); + 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; @@ -408,7 +413,7 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev) ret = tegra_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); - goto err_unregister_dai; + goto err_unregister_component; } ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); @@ -434,8 +439,8 @@ err_asoc_utils_fini: tegra_asoc_utils_fini(&ac97->util_data); err_unregister_pcm: tegra_pcm_platform_unregister(&pdev->dev); -err_unregister_dai: - snd_soc_unregister_dai(&pdev->dev); +err_unregister_component: + snd_soc_unregister_component(&pdev->dev); err_clk_put: clk_put(ac97->clk_ac97); err: @@ -447,7 +452,7 @@ static int tegra20_ac97_platform_remove(struct platform_device *pdev) struct tegra20_ac97 *ac97 = dev_get_drvdata(&pdev->dev); tegra_pcm_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); tegra_asoc_utils_fini(&ac97->util_data); diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index 68d42403d9b5..6839f88167d0 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c @@ -55,7 +55,7 @@ static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd) static struct snd_soc_dai_link tegra_wm9712_dai = { .name = "AC97 HiFi", .stream_name = "AC97 HiFi", - .cpu_dai_name = "tegra-ac97-pcm", + .cpu_dai_name = "tegra20-ac97", .codec_dai_name = "wm9712-hifi", .codec_name = "wm9712-codec", .init = tegra_wm9712_init, -- cgit v1.2.3 From a413a3c282c143da11b7d6dfb859885e5f8b48be Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:37:55 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on tegra20 i2s Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/tegra/tegra20_i2s.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c index caa772de5a18..8b1ceb82c86f 100644 --- a/sound/soc/tegra/tegra20_i2s.c +++ b/sound/soc/tegra/tegra20_i2s.c @@ -276,6 +276,10 @@ static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { .symmetric_rates = 1, }; +static const struct snd_soc_component_driver tegra20_i2s_component = { + .name = DRV_NAME, +}; + static bool tegra20_i2s_wr_rd_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -419,7 +423,8 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) goto err_pm_disable; } - ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); + ret = snd_soc_register_component(&pdev->dev, &tegra20_i2s_component, + &i2s->dai, 1); if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; @@ -429,13 +434,13 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev) ret = tegra_pcm_platform_register(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); - goto err_unregister_dai; + goto err_unregister_component; } return 0; -err_unregister_dai: - snd_soc_unregister_dai(&pdev->dev); +err_unregister_component: + snd_soc_unregister_component(&pdev->dev); err_suspend: if (!pm_runtime_status_suspended(&pdev->dev)) tegra20_i2s_runtime_suspend(&pdev->dev); @@ -456,7 +461,7 @@ static int tegra20_i2s_platform_remove(struct platform_device *pdev) tegra20_i2s_runtime_suspend(&pdev->dev); tegra_pcm_platform_unregister(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); clk_put(i2s->clk_i2s); -- cgit v1.2.3 From b00e2fa1ab1ff4c4ada4324866516c21c7ce5057 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:38:07 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on txx9aclc ac97 Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/txx9/txx9aclc-ac97.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 16ab69635e2e..8a2840304d28 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c @@ -170,6 +170,10 @@ static struct snd_soc_dai_driver txx9aclc_ac97_dai = { }, }; +static const struct snd_soc_component_driver txx9aclc_ac97_component = { + .name = "txx9aclc-ac97", +}; + static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) { struct txx9aclc_plat_drvdata *drvdata; @@ -205,12 +209,13 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev) if (err < 0) return err; - return snd_soc_register_dai(&pdev->dev, &txx9aclc_ac97_dai); + return snd_soc_register_component(&pdev->dev, &txx9aclc_ac97_component, + &txx9aclc_ac97_dai, 1); } static int txx9aclc_ac97_dev_remove(struct platform_device *pdev) { - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); return 0; } -- cgit v1.2.3 From 42277bddc6ad7ab31ad51411578e3e0d8d168963 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:38:19 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on ux500 msp Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/ux500/ux500_msp_dai.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 94a3e5705aaa..f1e8a5ecb00b 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -768,6 +768,11 @@ static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { }, }; +static const struct snd_soc_component_driver ux500_msp_component = { + .name = "ux500-msp", +}; + + static int ux500_msp_drv_probe(struct platform_device *pdev) { struct ux500_msp_i2s_drvdata *drvdata; @@ -825,8 +830,8 @@ static int ux500_msp_drv_probe(struct platform_device *pdev) } dev_set_drvdata(&pdev->dev, drvdata); - ret = snd_soc_register_dai(&pdev->dev, - &ux500_msp_dai_drv[drvdata->msp->id]); + ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component, + &ux500_msp_dai_drv[drvdata->msp->id], 1); if (ret < 0) { dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", __func__, drvdata->msp->id); @@ -844,7 +849,7 @@ static int ux500_msp_drv_probe(struct platform_device *pdev) return 0; err_reg_plat: - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); + snd_soc_unregister_component(&pdev->dev); err_init_msp: clk_put(drvdata->clk); err_clk: @@ -861,7 +866,7 @@ static int ux500_msp_drv_remove(struct platform_device *pdev) ux500_pcm_unregister_platform(pdev); - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv)); + snd_soc_unregister_component(&pdev->dev); devm_regulator_put(drvdata->reg_vape); prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s"); -- cgit v1.2.3 From f53179c026b11bef674d75154f5ea47ca3248ca9 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 21 Mar 2013 03:38:30 -0700 Subject: ASoC: snd_soc_[un]register_dai[s]() become non global function All drivers are using snd_soc_register_component() instead of snd_soc_register_dai[s]() snd_soc_[un]register_dai[s]() are no longer needed Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 8 -------- sound/soc/soc-core.c | 12 ++++-------- 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'sound/soc') diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 3d84808952b9..ae9a227d35d3 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -95,14 +95,6 @@ struct snd_soc_dai_driver; struct snd_soc_dai; struct snd_ac97_bus_ops; -/* Digital Audio Interface registration */ -int snd_soc_register_dai(struct device *dev, - struct snd_soc_dai_driver *dai_drv); -void snd_soc_unregister_dai(struct device *dev); -int snd_soc_register_dais(struct device *dev, - struct snd_soc_dai_driver *dai_drv, size_t count); -void snd_soc_unregister_dais(struct device *dev, size_t count); - /* Digital Audio Interface clocking API.*/ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2ecaaf13e319..f6cda7b6ce44 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3739,7 +3739,7 @@ static inline char *fmt_multiple_name(struct device *dev, * * @dai: DAI to register */ -int snd_soc_register_dai(struct device *dev, +static int snd_soc_register_dai(struct device *dev, struct snd_soc_dai_driver *dai_drv) { struct snd_soc_codec *codec; @@ -3786,14 +3786,13 @@ int snd_soc_register_dai(struct device *dev, return 0; } -EXPORT_SYMBOL_GPL(snd_soc_register_dai); /** * snd_soc_unregister_dai - Unregister a DAI from the ASoC core * * @dai: DAI to unregister */ -void snd_soc_unregister_dai(struct device *dev) +static void snd_soc_unregister_dai(struct device *dev) { struct snd_soc_dai *dai; @@ -3812,7 +3811,6 @@ found: kfree(dai->name); kfree(dai); } -EXPORT_SYMBOL_GPL(snd_soc_unregister_dai); /** * snd_soc_register_dais - Register multiple DAIs with the ASoC core @@ -3820,7 +3818,7 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_dai); * @dai: Array of DAIs to register * @count: Number of DAIs */ -int snd_soc_register_dais(struct device *dev, +static int snd_soc_register_dais(struct device *dev, struct snd_soc_dai_driver *dai_drv, size_t count) { struct snd_soc_codec *codec; @@ -3884,7 +3882,6 @@ err: return ret; } -EXPORT_SYMBOL_GPL(snd_soc_register_dais); /** * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core @@ -3892,14 +3889,13 @@ EXPORT_SYMBOL_GPL(snd_soc_register_dais); * @dai: Array of DAIs to unregister * @count: Number of DAIs */ -void snd_soc_unregister_dais(struct device *dev, size_t count) +static void snd_soc_unregister_dais(struct device *dev, size_t count) { int i; for (i = 0; i < count; i++) snd_soc_unregister_dai(dev); } -EXPORT_SYMBOL_GPL(snd_soc_unregister_dais); /** * snd_soc_register_platform - Register a platform with the ASoC core -- cgit v1.2.3 From 0a09dfa04177df5a2e9eeeeaf527efd35c531d11 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 22 Mar 2013 00:54:50 -0700 Subject: ASoC: switch over to use snd_soc_register_component() on sh4 siu siu_dai.c is using snd_soc_register_dais(), even though array size of siu_i2s_dai is 1. OTOH, new API snd_soc_register_component() uses properly snd_soc_register_dai() (henceforth dai()) or snd_soc_register_dais() (henceforth dais()) via num_dai. Then, cpu_dai_name will be "siu-i2s-dai" if dais() was used, and it will be "siu-pcm-audio" if dai() was used. Therefore this patch fixup migor_dai :: cpu_dai_name too. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/migor.c | 2 +- sound/soc/sh/siu_dai.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index 8526e1edaf45..5014a884afee 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c @@ -153,7 +153,7 @@ static int migor_dai_init(struct snd_soc_pcm_runtime *rtd) static struct snd_soc_dai_link migor_dai = { .name = "wm8978", .stream_name = "WM8978", - .cpu_dai_name = "siu-i2s-dai", + .cpu_dai_name = "siu-pcm-audio", .codec_dai_name = "wm8978-hifi", .platform_name = "siu-pcm-audio", .codec_name = "wm8978.0-001a", diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index 34facdc9e4ac..9dc24ffa892a 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -726,6 +726,10 @@ static struct snd_soc_dai_driver siu_i2s_dai = { .ops = &siu_dai_ops, }; +static const struct snd_soc_component_driver siu_i2s_component = { + .name = "siu-i2s", +}; + static int siu_probe(struct platform_device *pdev) { const struct firmware *fw_entry; @@ -783,7 +787,8 @@ static int siu_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, info); /* register using ARRAY version so we can keep dai name */ - ret = snd_soc_register_dais(&pdev->dev, &siu_i2s_dai, 1); + ret = snd_soc_register_component(&pdev->dev, &siu_i2s_component, + &siu_i2s_dai, 1); if (ret < 0) goto edaiinit; @@ -796,7 +801,7 @@ static int siu_probe(struct platform_device *pdev) return ret; esocregp: - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); edaiinit: iounmap(info->reg); emapreg: @@ -823,7 +828,7 @@ static int siu_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); snd_soc_unregister_platform(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); + snd_soc_unregister_component(&pdev->dev); iounmap(info->reg); iounmap(info->yram); -- cgit v1.2.3 From 2e1cc199fc8666ac5fda200e8a99f1e4dea07175 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 26 Mar 2013 16:38:19 -0600 Subject: ASoC: export snd_soc_register_component Without this, modules will fail to link against those symbols. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f6cda7b6ce44..fb50e00a71e4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4192,6 +4192,7 @@ error_component_name: return ret; } +EXPORT_SYMBOL_GPL(snd_soc_register_component); /** * snd_soc_unregister_component - Unregister a component from the ASoC core @@ -4217,6 +4218,7 @@ found: dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name); kfree(cmpnt->name); } +EXPORT_SYMBOL_GPL(snd_soc_unregister_component); /* Retrieve a card's name from device tree */ int snd_soc_of_parse_card_name(struct snd_soc_card *card, -- cgit v1.2.3 From 658e6101d045ae0bc97d31f5d6a5ea117a86c92a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 25 Mar 2013 15:50:22 +0000 Subject: ASoC: wm5102: Implement OSR support Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index b7a3fdceec7f..a1ff43c8b479 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -612,6 +612,26 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, return 0; } +static const char *wm5102_osr_text[] = { + "Low power", "Normal", "High performance", +}; + +static const unsigned int wm5102_osr_val[] = { + 0x0, 0x3, 0x5, +}; + +static const struct soc_enum wm5102_hpout_osr[] = { + SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L, + ARIZONA_OUT1_OSR_SHIFT, 0x7, 3, + wm5102_osr_text, wm5102_osr_val), + SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_2L, + ARIZONA_OUT2_OSR_SHIFT, 0x7, 3, + wm5102_osr_text, wm5102_osr_val), + SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L, + ARIZONA_OUT3_OSR_SHIFT, 0x7, 3, + wm5102_osr_text, wm5102_osr_val), +}; + #define WM5102_NG_SRC(name, base) \ SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \ SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \ @@ -761,6 +781,8 @@ ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE), +SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L, + ARIZONA_OUT4_OSR_SHIFT, 1, 0), SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, ARIZONA_OUT5_OSR_SHIFT, 1, 0), @@ -790,6 +812,10 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), +SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), +SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), +SOC_VALUE_ENUM("HPOUT3 OSR", wm5102_hpout_osr[2]), + SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), -- cgit v1.2.3 From a96f5e9394d298689eb3b876e6619166f1a37cc4 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 27 Mar 2013 10:50:53 +0000 Subject: ASoC: wm5102: Correctly use SOC_VALUE_ENUM for ISRC FSL controls Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index a1ff43c8b479..d1b43ebec087 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -762,8 +762,8 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), -SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), -SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), -- cgit v1.2.3 From 961b0fc840bf70511ef87d2f799eab014b4d2d37 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 29 Mar 2013 09:45:34 +0000 Subject: ASoC: wm0010: Constify usage of firmware filenames Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm0010.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index ad2fee4bb4cd..55fdf0f4406c 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c @@ -342,7 +342,7 @@ static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len) data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); } -static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec) +static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec) { struct spi_device *spi = to_spi_device(codec->dev); struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); -- cgit v1.2.3 From 3e112af51eedda46fe87d2cba427d48c4b7695fd Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Fri, 29 Mar 2013 09:45:35 +0000 Subject: ASoC: wm0010: Report filename when we fail to load firmware Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm0010.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index 55fdf0f4406c..8df2b6e1a1a6 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c @@ -361,8 +361,8 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec) ret = request_firmware(&fw, name, codec->dev); if (ret != 0) { - dev_err(codec->dev, "Failed to request application: %d\n", - ret); + dev_err(codec->dev, "Failed to request application(%s): %d\n", + name, ret); return ret; } -- cgit v1.2.3 From 939dc51bddc245df51c1e8ee44bf136621475149 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 29 Mar 2013 13:03:39 +0800 Subject: ASoC: wm2000: Expose some more registers for diagnostics Signed-off-by: Mark Brown --- sound/soc/codecs/wm2000.c | 4 +++- sound/soc/codecs/wm2000.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index f2ac38b61a1b..7fefd766b582 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -761,6 +761,8 @@ static bool wm2000_readable_reg(struct device *dev, unsigned int reg) case WM2000_REG_SYS_CTL2: case WM2000_REG_ANC_STAT: case WM2000_REG_IF_CTL: + case WM2000_REG_ANA_MIC_CTL: + case WM2000_REG_SPK_CTL: return true; default: return false; @@ -771,7 +773,7 @@ static const struct regmap_config wm2000_regmap = { .reg_bits = 16, .val_bits = 8, - .max_register = WM2000_REG_IF_CTL, + .max_register = WM2000_REG_SPK_CTL, .readable_reg = wm2000_readable_reg, }; diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h index fb812cd9e77d..3870c0e1d246 100644 --- a/sound/soc/codecs/wm2000.h +++ b/sound/soc/codecs/wm2000.h @@ -30,6 +30,8 @@ #define WM2000_REG_SYS_CTL2 0xf004 #define WM2000_REG_ANC_STAT 0xf005 #define WM2000_REG_IF_CTL 0xf006 +#define WM2000_REG_ANA_MIC_CTL 0xf028 +#define WM2000_REG_SPK_CTL 0xf034 /* SPEECH_CLARITY */ #define WM2000_SPEECH_CLARITY 0x01 -- cgit v1.2.3 From dd84f9259bfe8454ee7c9e6faf6ac13f45bb1ed2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 8 Mar 2013 15:25:58 +0800 Subject: ASoC: wm_adsp: Provide defines for firmwares For future work to have specific handling for some firmwares. Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index febb4c76535e..68eda929fbde 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -193,17 +193,25 @@ static void wm_adsp_buf_free(struct list_head *list) #define WM_ADSP_NUM_FW 4 +#define WM_ADSP_FW_MBC_VSS 0 +#define WM_ADSP_FW_TX 1 +#define WM_ADSP_FW_TX_SPK 2 +#define WM_ADSP_FW_RX_ANC 3 + static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { - "MBC/VSS", "Tx", "Tx Speaker", "Rx ANC" + [WM_ADSP_FW_MBC_VSS] = "MBC/VSS", + [WM_ADSP_FW_TX] = "Tx", + [WM_ADSP_FW_TX_SPK] = "Tx Speaker", + [WM_ADSP_FW_RX_ANC] = "Rx ANC", }; static struct { const char *file; } wm_adsp_fw[WM_ADSP_NUM_FW] = { - { .file = "mbc-vss" }, - { .file = "tx" }, - { .file = "tx-spk" }, - { .file = "rx-anc" }, + [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, + [WM_ADSP_FW_TX] = { .file = "tx" }, + [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" }, + [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, }; static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, -- cgit v1.2.3 From b6ed61cfa24786e36164869b593d44d411a700ad Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 29 Mar 2013 18:00:24 +0000 Subject: ASoC: wm_adsp: Split ADSP1 and ADSP2 firmware controls Now that we have regular register mapped controls we should be splitting the control sets for ADSP1 and ADSP2 as the register maps are not identical. Do that. Signed-off-by: Mark Brown --- sound/soc/codecs/wm2200.c | 2 +- sound/soc/codecs/wm5102.c | 2 +- sound/soc/codecs/wm_adsp.c | 26 +++++++++++++++++++------- sound/soc/codecs/wm_adsp.h | 3 ++- 4 files changed, 23 insertions(+), 10 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index ddc98f02ecbd..57ba315d0c84 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -1565,7 +1565,7 @@ static int wm2200_probe(struct snd_soc_codec *codec) return ret; } - ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2); + ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2); if (ret != 0) return ret; diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index d1b43ebec087..cb03cc448da6 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1572,7 +1572,7 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; - ret = snd_soc_add_codec_controls(codec, wm_adsp_fw_controls, 2); + ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2); if (ret != 0) return ret; diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 3a481fd1bf9a..bc03baef39fa 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -247,7 +247,18 @@ static const struct soc_enum wm_adsp_fw_enum[] = { SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), }; -static const struct soc_enum wm_adsp_rate_enum[] = { +const struct snd_kcontrol_new wm_adsp1_fw_controls[] = { + SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], + wm_adsp_fw_get, wm_adsp_fw_put), + SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], + wm_adsp_fw_get, wm_adsp_fw_put), + SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], + wm_adsp_fw_get, wm_adsp_fw_put), +}; +EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls); + +#if IS_ENABLED(CONFIG_SND_SOC_ARIZONA) +static const struct soc_enum wm_adsp2_rate_enum[] = { SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1, ARIZONA_DSP1_RATE_SHIFT, 0xf, ARIZONA_RATE_ENUM_SIZE, @@ -266,21 +277,22 @@ static const struct soc_enum wm_adsp_rate_enum[] = { arizona_rate_text, arizona_rate_val), }; -const struct snd_kcontrol_new wm_adsp_fw_controls[] = { +const struct snd_kcontrol_new wm_adsp2_fw_controls[] = { SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], wm_adsp_fw_get, wm_adsp_fw_put), - SOC_ENUM("DSP1 Rate", wm_adsp_rate_enum[0]), + SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]), SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], wm_adsp_fw_get, wm_adsp_fw_put), - SOC_ENUM("DSP2 Rate", wm_adsp_rate_enum[1]), + SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]), SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], wm_adsp_fw_get, wm_adsp_fw_put), - SOC_ENUM("DSP3 Rate", wm_adsp_rate_enum[2]), + SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]), SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], wm_adsp_fw_get, wm_adsp_fw_put), - SOC_ENUM("DSP4 Rate", wm_adsp_rate_enum[3]), + SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]), }; -EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); +EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls); +#endif static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, int type) diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index cb8871a3ec00..9f90c9fea842 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -65,7 +65,8 @@ struct wm_adsp { .shift = num, .event = wm_adsp2_event, \ .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } -extern const struct snd_kcontrol_new wm_adsp_fw_controls[]; +extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; +extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; int wm_adsp1_init(struct wm_adsp *adsp); int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs); -- cgit v1.2.3 From 0cd5751ab360573f607d1cbf97aa072667f888c8 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 29 Mar 2013 23:41:42 +0530 Subject: ASoC: mid-x86 - add support for meaadata apis while at it, update the copyright timeline too Signed-off-by: Jeeja KP Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/mid-x86/sst_platform.c | 12 +++++++++++- sound/soc/mid-x86/sst_platform.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index a263cbed8624..968656ceb39e 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -1,7 +1,7 @@ /* * sst_platform.c - Intel MID Platform driver * - * Copyright (C) 2010-2012 Intel Corp + * Copyright (C) 2010-2013 Intel Corp * Author: Vinod Koul * Author: Harsha Priya * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -652,11 +652,21 @@ static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream, return stream->compr_ops->get_codec_caps(codec); } +static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream, + struct snd_compr_metadata *metadata) +{ + struct sst_runtime_stream *stream = + cstream->runtime->private_data; + + return stream->compr_ops->set_metadata(stream->id, metadata); +} + static struct snd_compr_ops sst_platform_compr_ops = { .open = sst_platform_compr_open, .free = sst_platform_compr_free, .set_params = sst_platform_compr_set_params, + .set_metadata = sst_platform_compr_set_metadata, .trigger = sst_platform_compr_trigger, .pointer = sst_platform_compr_pointer, .ack = sst_platform_compr_ack, diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h index d61c5d514ffa..cacc9066ec52 100644 --- a/sound/soc/mid-x86/sst_platform.h +++ b/sound/soc/mid-x86/sst_platform.h @@ -124,6 +124,8 @@ struct compress_sst_ops { int (*close) (unsigned int str_id); int (*get_caps) (struct snd_compr_caps *caps); int (*get_codec_caps) (struct snd_compr_codec_caps *codec); + int (*set_metadata) (unsigned int str_id, + struct snd_compr_metadata *mdata); }; -- cgit v1.2.3 From 85762e71f17b59a76e6333d1a796737d080b7517 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 29 Mar 2013 15:40:10 -0600 Subject: ASoC: dapm: Implement mixer control sharing This is the equivalent of commit af46800 "ASoC: Implement mux control sharing", but applied to mixers instead of muxes. This allows a single control to affect multiple mixer widgets at once, which is useful when there is a single set of register bits that affects multiple mixers in HW, for example both the L and R mixers of a stereo path. Without this, you either: 1) End up with multiple controls that affect the same register bits, but whose DAPM state falls out of sync with HW, since the DAPM state is only updated for the specific control that is modified, and not for other paths that are affected by the register bit(s). 2) False paths through DAPM, since you end up merging unconnected stereo paths together into a single widget which hosts the single control, and then branching back out again, thus conjoining the enable states of the two input paths. Now that the kcontrol creation logic is split out into a separate function, dapm_create_or_share_mixmux_kcontrol(), also use that to replace most of the body of dapm_new_mux(). This should produce no functional change, but simply eliminates some mostly duplicated code. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 270 ++++++++++++++++++++++++++------------------------- 1 file changed, 136 insertions(+), 134 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1d6a9b3ceb27..687784463db9 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -504,17 +504,27 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm, return 0; } -/* create new dapm mixer control */ -static int dapm_new_mixer(struct snd_soc_dapm_widget *w) +/* + * Determine if a kcontrol is shared. If it is, look it up. If it isn't, + * create it. Either way, add the widget into the control's widget list + */ +static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w, + int kci, struct snd_soc_dapm_path *path) { struct snd_soc_dapm_context *dapm = w->dapm; - int i, ret = 0; - size_t name_len, prefix_len; - struct snd_soc_dapm_path *path; struct snd_card *card = dapm->card->snd_card; const char *prefix; + size_t prefix_len; + int shared; + struct snd_kcontrol *kcontrol; struct snd_soc_dapm_widget_list *wlist; + int wlistentries; size_t wlistsize; + bool wname_in_long_name, kcname_in_long_name; + size_t name_len; + char *long_name; + const char *name; + int ret; if (dapm->codec) prefix = dapm->codec->name_prefix; @@ -526,103 +536,141 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) else prefix_len = 0; - /* add kcontrol */ - for (i = 0; i < w->num_kcontrols; i++) { + shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci], + &kcontrol); - /* match name */ - list_for_each_entry(path, &w->sources, list_sink) { + if (kcontrol) { + wlist = kcontrol->private_data; + wlistentries = wlist->num_widgets + 1; + } else { + wlist = NULL; + wlistentries = 1; + } - /* mixer/mux paths name must match control name */ - if (path->name != (char *)w->kcontrol_news[i].name) - continue; + wlistsize = sizeof(struct snd_soc_dapm_widget_list) + + wlistentries * sizeof(struct snd_soc_dapm_widget *); + wlist = krealloc(wlist, wlistsize, GFP_KERNEL); + if (wlist == NULL) { + dev_err(dapm->dev, "ASoC: can't allocate widget list for %s\n", + w->name); + return -ENOMEM; + } + wlist->num_widgets = wlistentries; + wlist->widgets[wlistentries - 1] = w; - if (w->kcontrols[i]) { - path->kcontrol = w->kcontrols[i]; - continue; + if (!kcontrol) { + if (shared) { + wname_in_long_name = false; + kcname_in_long_name = true; + } else { + switch (w->id) { + case snd_soc_dapm_switch: + case snd_soc_dapm_mixer: + wname_in_long_name = true; + kcname_in_long_name = true; + break; + case snd_soc_dapm_mixer_named_ctl: + wname_in_long_name = false; + kcname_in_long_name = true; + break; + case snd_soc_dapm_mux: + case snd_soc_dapm_virt_mux: + case snd_soc_dapm_value_mux: + wname_in_long_name = true; + kcname_in_long_name = false; + break; + default: + kfree(wlist); + return -EINVAL; } + } + + if (wname_in_long_name && kcname_in_long_name) { + name_len = strlen(w->name) - prefix_len + 1 + + strlen(w->kcontrol_news[kci].name) + 1; - wlistsize = sizeof(struct snd_soc_dapm_widget_list) + - sizeof(struct snd_soc_dapm_widget *), - wlist = kzalloc(wlistsize, GFP_KERNEL); - if (wlist == NULL) { - dev_err(dapm->dev, - "ASoC: can't allocate widget list for %s\n", - w->name); + long_name = kmalloc(name_len, GFP_KERNEL); + if (long_name == NULL) { + kfree(wlist); return -ENOMEM; } - wlist->num_widgets = 1; - wlist->widgets[0] = w; - - /* add dapm control with long name. - * for dapm_mixer this is the concatenation of the - * mixer and kcontrol name. - * for dapm_mixer_named_ctl this is simply the - * kcontrol name. + + /* + * The control will get a prefix from the control + * creation process but we're also using the same + * prefix for widgets so cut the prefix off the + * front of the widget name. */ - name_len = strlen(w->kcontrol_news[i].name) + 1; - if (w->id != snd_soc_dapm_mixer_named_ctl) - name_len += 1 + strlen(w->name); + snprintf(long_name, name_len, "%s %s", + w->name + prefix_len, + w->kcontrol_news[kci].name); + long_name[name_len - 1] = '\0'; + + name = long_name; + } else if (wname_in_long_name) { + long_name = NULL; + name = w->name + prefix_len; + } else { + long_name = NULL; + name = w->kcontrol_news[kci].name; + } - path->long_name = kmalloc(name_len, GFP_KERNEL); + kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], wlist, name, + prefix); + ret = snd_ctl_add(card, kcontrol); + if (ret < 0) { + dev_err(dapm->dev, + "ASoC: failed to add widget %s dapm kcontrol %s: %d\n", + w->name, name, ret); + kfree(wlist); + kfree(long_name); + return ret; + } - if (path->long_name == NULL) { - kfree(wlist); - return -ENOMEM; - } + path->long_name = long_name; + } - switch (w->id) { - default: - /* The control will get a prefix from - * the control creation process but - * we're also using the same prefix - * for widgets so cut the prefix off - * the front of the widget name. - */ - snprintf((char *)path->long_name, name_len, - "%s %s", w->name + prefix_len, - w->kcontrol_news[i].name); - break; - case snd_soc_dapm_mixer_named_ctl: - snprintf((char *)path->long_name, name_len, - "%s", w->kcontrol_news[i].name); - break; - } + kcontrol->private_data = wlist; + w->kcontrols[kci] = kcontrol; + path->kcontrol = kcontrol; - ((char *)path->long_name)[name_len - 1] = '\0'; + return 0; +} - path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i], - wlist, path->long_name, - prefix); - ret = snd_ctl_add(card, path->kcontrol); - if (ret < 0) { - dev_err(dapm->dev, "ASoC: failed to add widget" - " %s dapm kcontrol %s: %d\n", - w->name, path->long_name, ret); - kfree(wlist); - kfree(path->long_name); - path->long_name = NULL; - return ret; +/* create new dapm mixer control */ +static int dapm_new_mixer(struct snd_soc_dapm_widget *w) +{ + int i, ret; + struct snd_soc_dapm_path *path; + + /* add kcontrol */ + for (i = 0; i < w->num_kcontrols; i++) { + /* match name */ + list_for_each_entry(path, &w->sources, list_sink) { + /* mixer/mux paths name must match control name */ + if (path->name != (char *)w->kcontrol_news[i].name) + continue; + + if (w->kcontrols[i]) { + path->kcontrol = w->kcontrols[i]; + continue; } - w->kcontrols[i] = path->kcontrol; + + ret = dapm_create_or_share_mixmux_kcontrol(w, i, path); + if (ret < 0) + return ret; } } - return ret; + + return 0; } /* create new dapm mux control */ static int dapm_new_mux(struct snd_soc_dapm_widget *w) { struct snd_soc_dapm_context *dapm = w->dapm; - struct snd_soc_dapm_path *path = NULL; - struct snd_kcontrol *kcontrol; - struct snd_card *card = dapm->card->snd_card; - const char *prefix; - size_t prefix_len; + struct snd_soc_dapm_path *path; int ret; - struct snd_soc_dapm_widget_list *wlist; - int shared, wlistentries; - size_t wlistsize; - const char *name; if (w->num_kcontrols != 1) { dev_err(dapm->dev, @@ -631,65 +679,19 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) return -EINVAL; } - shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[0], - &kcontrol); - if (kcontrol) { - wlist = kcontrol->private_data; - wlistentries = wlist->num_widgets + 1; - } else { - wlist = NULL; - wlistentries = 1; - } - wlistsize = sizeof(struct snd_soc_dapm_widget_list) + - wlistentries * sizeof(struct snd_soc_dapm_widget *), - wlist = krealloc(wlist, wlistsize, GFP_KERNEL); - if (wlist == NULL) { - dev_err(dapm->dev, - "ASoC: can't allocate widget list for %s\n", w->name); - return -ENOMEM; - } - wlist->num_widgets = wlistentries; - wlist->widgets[wlistentries - 1] = w; - - if (!kcontrol) { - if (dapm->codec) - prefix = dapm->codec->name_prefix; - else - prefix = NULL; - - if (shared) { - name = w->kcontrol_news[0].name; - prefix_len = 0; - } else { - name = w->name; - if (prefix) - prefix_len = strlen(prefix) + 1; - else - prefix_len = 0; - } - - /* - * The control will get a prefix from the control creation - * process but we're also using the same prefix for widgets so - * cut the prefix off the front of the widget name. - */ - kcontrol = snd_soc_cnew(&w->kcontrol_news[0], wlist, - name + prefix_len, prefix); - ret = snd_ctl_add(card, kcontrol); - if (ret < 0) { - dev_err(dapm->dev, "ASoC: failed to add kcontrol %s: %d\n", - w->name, ret); - kfree(wlist); - return ret; - } + path = list_first_entry(&w->sources, struct snd_soc_dapm_path, + list_sink); + if (!path) { + dev_err(dapm->dev, "ASoC: mux %s has no paths\n", w->name); + return -EINVAL; } - kcontrol->private_data = wlist; - - w->kcontrols[0] = kcontrol; + ret = dapm_create_or_share_mixmux_kcontrol(w, 0, path); + if (ret < 0) + return ret; list_for_each_entry(path, &w->sources, list_sink) - path->kcontrol = kcontrol; + path->kcontrol = w->kcontrols[0]; return 0; } -- cgit v1.2.3 From 0e669246dcd11ad3ecb33a6170a963c4badaa10b Mon Sep 17 00:00:00 2001 From: Ryo Tsutsui Date: Sun, 31 Mar 2013 19:19:09 +0100 Subject: ASoC: dapm: Remove redundant clear_walk() for supply widgets We already clear the walked state in dapm_widget_power_check(), no need to do it again. Signed-off-by: Ryo Tsutsui Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 687784463db9..7a61b5cc2d4f 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1165,8 +1165,6 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) return 1; } - dapm_clear_walk(w->dapm); - return 0; } -- cgit v1.2.3 From 1059ecfa0f1eb38eba592b2f939499504013b6d5 Mon Sep 17 00:00:00 2001 From: Ryo Tsutsui Date: Mon, 1 Apr 2013 12:50:01 +0100 Subject: ASoC: dapm: Only clear paths we've walked When clearing the walked flags there is no need to clear all paths, we only need to clear the paths we actually walked. This means we can split dapm_clear_walk() into input and output versions and rather than going through all DAPM paths we can recurse down the path until we encounter paths we have not yet walked. This reduces the number of operations we need to perform and improves cache locality. [Pulled out of the vendor tree that the patch was originally generated for by me, any bugs were introduced in that process -- broonie] Signed-off-by: Ryo Tsutsui Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7a61b5cc2d4f..68acec667242 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -707,14 +707,33 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w) } /* reset 'walked' bit for each dapm path */ -static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) +static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm, + struct list_head *sink) { struct snd_soc_dapm_path *p; - list_for_each_entry(p, &dapm->card->paths, list) - p->walked = 0; + list_for_each_entry(p, sink, list_source) { + if (p->walked) { + p->walked = 0; + dapm_clear_walk_output(dapm, &p->sink->sinks); + } + } +} + +static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm, + struct list_head *source) +{ + struct snd_soc_dapm_path *p; + + list_for_each_entry(p, source, list_sink) { + if (p->walked) { + p->walked = 0; + dapm_clear_walk_input(dapm, &p->source->sources); + } + } } + /* We implement power down on suspend by checking the power state of * the ALSA card - when we are suspending the ALSA state for the card * is set to D3. @@ -983,13 +1002,17 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); dapm_reset(card); - if (stream == SNDRV_PCM_STREAM_PLAYBACK) + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { paths = is_connected_output_ep(dai->playback_widget, list); - else + dapm_clear_walk_output(&card->dapm, + &dai->playback_widget->sinks); + } else { paths = is_connected_input_ep(dai->capture_widget, list); + dapm_clear_walk_input(&card->dapm, + &dai->capture_widget->sources); + } trace_snd_soc_dapm_connected(paths, stream); - dapm_clear_walk(&card->dapm); mutex_unlock(&card->dapm_mutex); return paths; @@ -1092,9 +1115,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) DAPM_UPDATE_STAT(w, power_checks); in = is_connected_input_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_input(w->dapm, &w->sources); out = is_connected_output_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_output(w->dapm, &w->sinks); return out != 0 && in != 0; } @@ -1117,7 +1140,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) if (w->active) { in = is_connected_input_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_input(w->dapm, &w->sources); return in != 0; } else { return dapm_generic_check_power(w); @@ -1133,7 +1156,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) if (w->active) { out = is_connected_output_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_output(w->dapm, &w->sinks); return out != 0; } else { return dapm_generic_check_power(w); @@ -1745,9 +1768,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file, return -ENOMEM; in = is_connected_input_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_input(w->dapm, &w->sources); out = is_connected_output_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_output(w->dapm, &w->sinks); ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", w->name, w->power ? "On" : "Off", -- cgit v1.2.3 From 5fa70f71dbf33603b0d29b33d8da128b266eb733 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 3 Apr 2013 11:02:56 +0200 Subject: ASoC: dmaengine_pcm: Setup device_fc in snd_hwparams_to_dma_slave_config Usually device_fc should be set to false for audio DMAs. Initialize it in a common place so drivers don't have to do this manually. Signed-off-by: Lars-Peter Clausen Tested-by: Peter Ujfalusi Acked-by: Nicolas Ferre Signed-off-by: Mark Brown --- sound/soc/atmel/atmel-pcm-dma.c | 2 -- sound/soc/fsl/imx-pcm-dma.c | 2 -- sound/soc/soc-dmaengine-pcm.c | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c index b8570e3e1b57..bb07989762d5 100644 --- a/sound/soc/atmel/atmel-pcm-dma.c +++ b/sound/soc/atmel/atmel-pcm-dma.c @@ -129,8 +129,6 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, slave_config.src_maxburst = 1; } - slave_config.device_fc = false; - dma_chan = snd_dmaengine_pcm_get_chan(substream); if (dmaengine_slave_config(dma_chan, &slave_config)) { pr_err("atmel-pcm: failed to configure dma channel\n"); diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index 6832c498457a..64af57336dbb 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c @@ -57,8 +57,6 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; - slave_config.device_fc = false; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { slave_config.dst_addr = dma_params->dma_addr; slave_config.dst_maxburst = dma_params->burstsize; diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index e8b1215b8c1b..7c24dedff971 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -89,6 +89,8 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, slave_config->src_addr_width = buswidth; } + slave_config->device_fc = false; + return 0; } EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); -- cgit v1.2.3 From 85c9f9c5f9d09ea43daf4f1a8b81d3c7b7394d27 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 3 Apr 2013 11:06:02 +0200 Subject: ASoC: dmaengine-pcm: Add a common DAI DMA data struct This patch adds a common DMA data struct which can be used by DAI drivers to communicate their DMA configuration requirements to the DMA pcm driver. Having a common data structure for this allows us to implement common functions on top of them, which can be used by multiple platforms. This patch also introduces a new function to initialize certain fields of a dma_slave_config struct from the common DAI DMA data struct. Signed-off-by: Lars-Peter Clausen Reviewed-by: Stephen Warren Tested-by: Stephen Warren Signed-off-by: Mark Brown --- include/sound/dmaengine_pcm.h | 24 ++++++++++++++++++++++++ sound/soc/soc-dmaengine-pcm.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) (limited to 'sound/soc') diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h index f8a70312adb8..95620428a59b 100644 --- a/include/sound/dmaengine_pcm.h +++ b/include/sound/dmaengine_pcm.h @@ -44,4 +44,28 @@ int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream); struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream); +/** + * struct snd_dmaengine_dai_dma_data - DAI DMA configuration data + * @addr: Address of the DAI data source or destination register. + * @addr_width: Width of the DAI data source or destination register. + * @maxburst: Maximum number of words(note: words, as in units of the + * src_addr_width member, not bytes) that can be send to or received from the + * DAI in one burst. + * @slave_id: Slave requester id for the DMA channel. + * @filter_data: Custom DMA channel filter data, this will usually be used when + * requesting the DMA channel. + */ +struct snd_dmaengine_dai_dma_data { + dma_addr_t addr; + enum dma_slave_buswidth addr_width; + u32 maxburst; + unsigned int slave_id; + void *filter_data; +}; + +void snd_dmaengine_pcm_set_config_from_dai_data( + const struct snd_pcm_substream *substream, + const struct snd_dmaengine_dai_dma_data *dma_data, + struct dma_slave_config *config); + #endif diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c index 7c24dedff971..a9a300acb506 100644 --- a/sound/soc/soc-dmaengine-pcm.c +++ b/sound/soc/soc-dmaengine-pcm.c @@ -95,6 +95,43 @@ int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, } EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); +/** + * snd_dmaengine_pcm_set_config_from_dai_data() - Initializes a dma slave config + * using DAI DMA data. + * @substream: PCM substream + * @dma_data: DAI DMA data + * @slave_config: DMA slave configuration + * + * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and + * slave_id fields of the DMA slave config from the same fields of the DAI DMA + * data struct. The src and dst fields will be initialized depending on the + * direction of the substream. If the substream is a playback stream the dst + * fields will be initialized, if it is a capture stream the src fields will be + * initialized. The {dst,src}_addr_width field will only be initialized if the + * addr_width field of the DAI DMA data struct is not equal to + * DMA_SLAVE_BUSWIDTH_UNDEFINED. + */ +void snd_dmaengine_pcm_set_config_from_dai_data( + const struct snd_pcm_substream *substream, + const struct snd_dmaengine_dai_dma_data *dma_data, + struct dma_slave_config *slave_config) +{ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + slave_config->dst_addr = dma_data->addr; + slave_config->dst_maxburst = dma_data->maxburst; + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED) + slave_config->dst_addr_width = dma_data->addr_width; + } else { + slave_config->src_addr = dma_data->addr; + slave_config->src_maxburst = dma_data->maxburst; + if (dma_data->addr_width != DMA_SLAVE_BUSWIDTH_UNDEFINED) + slave_config->src_addr_width = dma_data->addr_width; + } + + slave_config->slave_id = dma_data->slave_id; +} +EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data); + static void dmaengine_pcm_dma_complete(void *arg) { struct snd_pcm_substream *substream = arg; -- cgit v1.2.3 From 09ae3aaf3cd28422d76b7b78d9491b17330b276a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 3 Apr 2013 11:06:05 +0200 Subject: ASoC: omap: Use common DAI DMA data Use the common DAI DMA data struct for omap, this allows us to use the common helper function to configure the DMA slave config based on the DAI DMA data. For omap-dmic and omap-mcpdm also move the DMA data from a global variable to the driver state struct. Signed-off-by: Lars-Peter Clausen Acked-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/am3517evm.c | 1 - sound/soc/omap/ams-delta.c | 1 - sound/soc/omap/mcbsp.c | 14 +++++++------ sound/soc/omap/mcbsp.h | 7 ++++--- sound/soc/omap/n810.c | 1 - sound/soc/omap/omap-abe-twl6040.c | 1 - sound/soc/omap/omap-dmic.c | 22 ++++++++++---------- sound/soc/omap/omap-hdmi.c | 24 ++++++++++------------ sound/soc/omap/omap-mcbsp.c | 6 +++--- sound/soc/omap/omap-mcpdm.c | 31 +++++++++++++---------------- sound/soc/omap/omap-pcm.c | 42 +++++---------------------------------- sound/soc/omap/omap-pcm.h | 39 ------------------------------------ sound/soc/omap/omap-twl4030.c | 1 - sound/soc/omap/omap3pandora.c | 1 - sound/soc/omap/osk5912.c | 1 - sound/soc/omap/rx51.c | 1 - 16 files changed, 54 insertions(+), 139 deletions(-) delete mode 100644 sound/soc/omap/omap-pcm.h (limited to 'sound/soc') diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index c1900b2a6f28..994dcf345975 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c @@ -28,7 +28,6 @@ #include #include "omap-mcbsp.h" -#include "omap-pcm.h" #include "../codecs/tlv320aic23.h" diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 2600447fa74f..629446482a91 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -36,7 +36,6 @@ #include #include "omap-mcbsp.h" -#include "omap-pcm.h" #include "../codecs/cx20442.h" diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 285c8368cb47..eb68c7db1cf3 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c @@ -1018,9 +1018,10 @@ int omap_mcbsp_init(struct platform_device *pdev) return -ENODEV; } /* RX DMA request number, and port address configuration */ - mcbsp->dma_data[1].name = "Audio Capture"; - mcbsp->dma_data[1].dma_req = res->start; - mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1); + mcbsp->dma_req[1] = res->start; + mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1]; + mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1); + mcbsp->dma_data[1].maxburst = 4; res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); if (!res) { @@ -1028,9 +1029,10 @@ int omap_mcbsp_init(struct platform_device *pdev) return -ENODEV; } /* TX DMA request number, and port address configuration */ - mcbsp->dma_data[0].name = "Audio Playback"; - mcbsp->dma_data[0].dma_req = res->start; - mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0); + mcbsp->dma_req[0] = res->start; + mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0]; + mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0); + mcbsp->dma_data[0].maxburst = 4; mcbsp->fclk = clk_get(&pdev->dev, "fck"); if (IS_ERR(mcbsp->fclk)) { diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h index f93e0b0af303..96d1b086bcf8 100644 --- a/sound/soc/omap/mcbsp.h +++ b/sound/soc/omap/mcbsp.h @@ -24,14 +24,14 @@ #ifndef __ASOC_MCBSP_H #define __ASOC_MCBSP_H -#include "omap-pcm.h" - #ifdef CONFIG_ARCH_OMAP1 #define mcbsp_omap1() 1 #else #define mcbsp_omap1() 0 #endif +#include + /* McBSP register numbers. Register address offset = num * reg_step */ enum { /* Common registers */ @@ -312,7 +312,8 @@ struct omap_mcbsp { struct omap_mcbsp_platform_data *pdata; struct omap_mcbsp_st_data *st_data; struct omap_mcbsp_reg_cfg cfg_regs; - struct omap_pcm_dma_data dma_data[2]; + struct snd_dmaengine_dai_dma_data dma_data[2]; + unsigned int dma_req[2]; int dma_op_mode; u16 max_tx_thres; u16 max_rx_thres; diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index ee7cd53aa3ee..5e8d640d314f 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -34,7 +34,6 @@ #include #include "omap-mcbsp.h" -#include "omap-pcm.h" #define N810_HEADSET_AMP_GPIO 10 #define N810_SPEAKER_AMP_GPIO 101 diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index e7d93fa412a9..70cd5c7b2e14 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -34,7 +34,6 @@ #include "omap-dmic.h" #include "omap-mcpdm.h" -#include "omap-pcm.h" #include "../codecs/twl6040.h" struct abe_twl6040 { diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 8ebaf117d81f..a2597fab33a3 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -39,8 +39,8 @@ #include #include #include +#include -#include "omap-pcm.h" #include "omap-dmic.h" struct omap_dmic { @@ -55,13 +55,9 @@ struct omap_dmic { u32 ch_enabled; bool active; struct mutex mutex; -}; -/* - * Stream DMA parameters - */ -static struct omap_pcm_dma_data omap_dmic_dai_dma_params = { - .name = "DMIC capture", + struct snd_dmaengine_dai_dma_data dma_data; + unsigned int dma_req; }; static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) @@ -118,7 +114,7 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, mutex_unlock(&dmic->mutex); - snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params); + snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data); return ret; } @@ -203,7 +199,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); - struct omap_pcm_dma_data *dma_data; + struct snd_dmaengine_dai_dma_data *dma_data; int channels; dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); @@ -230,7 +226,7 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, /* packet size is threshold * channels */ dma_data = snd_soc_dai_get_dma_data(dai, substream); - dma_data->packet_size = dmic->threshold * channels; + dma_data->maxburst = dmic->threshold * channels; return 0; } @@ -476,7 +472,7 @@ static int asoc_dmic_probe(struct platform_device *pdev) ret = -ENODEV; goto err_put_clk; } - omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG; + dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG; res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { @@ -484,7 +480,9 @@ static int asoc_dmic_probe(struct platform_device *pdev) ret = -ENODEV; goto err_put_clk; } - omap_dmic_dai_dma_params.dma_req = res->start; + + dmic->dma_req = res->start; + dmic->dma_data.filter_data = &dmic->dma_req; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); if (!res) { diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index 32fa840c493e..b4bfab9f33e8 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c @@ -32,15 +32,16 @@ #include #include #include +#include #include