aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorPhilippe Langlais <philippe.langlais@linaro.org>2011-05-10 16:46:28 +0200
committerHenrik Aberg <henrik.aberg@stericsson.com>2011-05-18 09:40:09 +0200
commita24a30b8dc6f8569e167b0a1398b2a6d964c5818 (patch)
treefe012aed3940587fda3cd87b014c42751fedbdfa /sound
parent07b1957db20e13f5e96ffdcb3861c9cda4ee8e99 (diff)
Ux500 ASoC: Move enabling of regulators
Regulators is no longer enabled during machine-driver init, but rather done before playback, and disabled after playback is finished. Change-Id: I5f6bfc3dd60b139ce4e786160104e4daaa4040fc Signed-off-by: Ola Lilja <ola.o.lilja@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/21788 Reviewed-by: Roger NILSSON1 <roger.xr.nilsson@stericsson.com> Conflicts: arch/arm/mach-ux500/board-mop500.c include/sound/ux500_ab8500_ext.h sound/soc/codecs/ab8500_audio.c sound/soc/ux500/ux500_ab8500.c
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/ab8500_audio.c54
-rw-r--r--sound/soc/ux500/ux500_ab8500.c173
2 files changed, 99 insertions, 128 deletions
diff --git a/sound/soc/codecs/ab8500_audio.c b/sound/soc/codecs/ab8500_audio.c
index 10b61b7c479..94e0b991d84 100644
--- a/sound/soc/codecs/ab8500_audio.c
+++ b/sound/soc/codecs/ab8500_audio.c
@@ -177,7 +177,6 @@ static struct clk *clk_ptr_audioclk;
static struct clk *clk_ptr_sysclk;
static DEFINE_MUTEX(power_lock);
static int ab8500_power_count;
-static bool ab8500_vibra_on;
/* Reads an arbitrary register from the ab8500 chip.
*/
@@ -1622,6 +1621,28 @@ static int ab8500_codec_set_bit_delay_if1(struct snd_soc_codec *codec, unsigned
return 0;
}
+/* Configures audio macrocell into the AB8500 Chip */
+static void ab8500_codec_configure_audio_macrocell(struct snd_soc_codec *codec)
+{
+ int data;
+
+ data = ab8500_codec_read_reg(codec, AB8500_SYS_CTRL2_BLOCK, AB8500_CTRL3_REG);
+ data &= ~CLK_32K_OUT2_DISABLE;
+ ab8500_codec_write_reg(codec, AB8500_SYS_CTRL2_BLOCK, AB8500_CTRL3_REG, data);
+ data |= INACTIVE_RESET_AUDIO;
+ ab8500_codec_write_reg(codec, AB8500_SYS_CTRL2_BLOCK, AB8500_CTRL3_REG, data);
+
+ data = ab8500_codec_read_reg(codec, AB8500_SYS_CTRL2_BLOCK,
+ AB8500_SYSULPCLK_CTRL1_REG);
+ data |= ENABLE_AUDIO_CLK_TO_AUDIO_BLK;
+ ab8500_codec_write_reg(codec, AB8500_SYS_CTRL2_BLOCK,
+ AB8500_SYSULPCLK_CTRL1_REG, data);
+
+ data = ab8500_codec_read_reg(codec, AB8500_MISC, AB8500_GPIO_DIR4_REG);
+ data |= GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT | GPIO31_DIR_OUTPUT;
+ ab8500_codec_write_reg(codec, AB8500_MISC, AB8500_GPIO_DIR4_REG, data);
+}
+
static int ab8500_codec_power_control_inc(struct snd_soc_codec *codec)
{
int ret;
@@ -1795,7 +1816,6 @@ static int ab8500_codec_pcm_startup(struct snd_pcm_substream *substream,
{
pr_debug("%s Enter.\n", __func__);
-
return 0;
}
@@ -2121,35 +2141,6 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = {
}
};
-/* Configures audio macrocell into the AB8500 Chip */
-static void ab8500_codec_configure_audio_macrocell(struct snd_soc_codec *codec)
-{
- int data;
-
- data = ab8500_codec_read_reg(codec, AB8500_SYS_CTRL2_BLOCK, AB8500_CTRL3_REG);
- data &= ~CLK_32K_OUT2_DISABLE;
- ab8500_codec_write_reg(codec, AB8500_SYS_CTRL2_BLOCK, AB8500_CTRL3_REG, data);
- data |= INACTIVE_RESET_AUDIO;
- ab8500_codec_write_reg(codec, AB8500_SYS_CTRL2_BLOCK, AB8500_CTRL3_REG, data);
-
- data = ab8500_codec_read_reg(codec, AB8500_SYS_CTRL2_BLOCK,
- AB8500_SYSULPCLK_CTRL1_REG);
- data |= ENABLE_AUDIO_CLK_TO_AUDIO_BLK;
- ab8500_codec_write_reg(codec, AB8500_SYS_CTRL2_BLOCK,
- AB8500_SYSULPCLK_CTRL1_REG, data);
-
- data = ab8500_codec_read_reg(codec, AB8500_MISC, AB8500_GPIO_DIR4_REG);
- data |= GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT | GPIO31_DIR_OUTPUT;
- ab8500_codec_write_reg(codec, AB8500_MISC, AB8500_GPIO_DIR4_REG, data);
-
- data = ab8500_codec_read_reg(codec, AB8500_MISC, AB8500_GPIO_DIR5_REG);
- data |= GPIO35_DIR_OUTPUT;
- ab8500_codec_write_reg(codec, AB8500_MISC, AB8500_GPIO_DIR5_REG, data);
- data = ab8500_codec_read_reg(codec, AB8500_MISC, AB8500_GPIO_OUT5_REG);
- data |= GPIO35_DIR_OUTPUT;
- ab8500_codec_write_reg(codec, AB8500_MISC, AB8500_GPIO_OUT5_REG, data);
-}
-
static int ab8500_codec_probe(struct snd_soc_codec *codec)
{
int i, ret;
@@ -2177,7 +2168,6 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
}
ab8500_codec = codec;
- ab8500_vibra_on = false;
ab8500_power_count = 0;
clk_ptr_sysclk = clk_get(codec->dev, "sysclk");
diff --git a/sound/soc/ux500/ux500_ab8500.c b/sound/soc/ux500/ux500_ab8500.c
index 117f3aaad5d..ec6972478dd 100644
--- a/sound/soc/ux500/ux500_ab8500.c
+++ b/sound/soc/ux500/ux500_ab8500.c
@@ -49,50 +49,14 @@ static unsigned int tx_slots = DEF_TX_SLOTS;
static unsigned int rx_slots = DEF_RX_SLOTS;
/* List the regulators that are to be controlled.. */
-static struct regulator_bulk_data ab8500_regus[5] = {
+static struct regulator_bulk_data ab8500_regus[4] = {
{ .supply = "v-dmic" },
{ .supply = "v-audio" },
{ .supply = "v-amic1" },
- { .supply = "v-amic2" },
- { .supply = "vcc-N2158" }
+ { .supply = "v-amic2" }
};
-static int create_regulators(struct device *dev)
-{
- int i, status = 0;
-
- pr_debug("%s: Enter.\n", __func__);
-
- for (i = 0; i < ARRAY_SIZE(ab8500_regus); ++i)
- ab8500_regus[i].consumer = NULL;
-
- for (i = 0; i < ARRAY_SIZE(ab8500_regus); ++i) {
- ab8500_regus[i].consumer = regulator_get(
- dev, ab8500_regus[i].supply);
- if (IS_ERR(ab8500_regus[i].consumer)) {
- status = PTR_ERR(ab8500_regus[i].consumer);
- pr_err("%s: Failed to get supply '%s' (%d)\n",
- __func__, ab8500_regus[i].supply, status);
- ab8500_regus[i].consumer = NULL;
- goto err_get;
- }
- }
-
- return 0;
-
-err_get:
-
- for (i = 0; i < ARRAY_SIZE(ab8500_regus); ++i) {
- if (ab8500_regus[i].consumer) {
- regulator_put(ab8500_regus[i].consumer);
- ab8500_regus[i].consumer = NULL;
- }
- }
-
- return status;
-}
-
-int enable_regulator(const char *name)
+static int enable_regulator(const char *name)
{
int i, status;
@@ -101,30 +65,27 @@ int enable_regulator(const char *name)
continue;
status = regulator_enable(ab8500_regus[i].consumer);
-
if (status != 0) {
pr_err("%s: Failure with regulator %s (%d)\n",
__func__, name, status);
return status;
- } else {
- pr_debug("%s: Enabled regulator %s.\n",
- __func__, name);
- return 0;
- }
+ };
+
+ pr_debug("%s: Enabled regulator %s.\n", __func__, name);
+ return 0;
}
return -EINVAL;
}
-void disable_regulator(const char *name)
+static void disable_regulator(const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(ab8500_regus); ++i) {
if (strcmp(name, ab8500_regus[i].supply) == 0) {
regulator_disable(ab8500_regus[i].consumer);
- pr_debug("%s: Disabled regulator %s.\n",
- __func__, name);
+ pr_debug("%s: Disabled regulator %s.\n", __func__, name);
return;
}
}
@@ -132,13 +93,22 @@ void disable_regulator(const char *name)
int ux500_ab8500_startup(struct snd_pcm_substream *substream)
{
+ int i;
+ int status = 0;
+
pr_info("%s: Enter\n", __func__);
- return 0;
+ /* Enable regulators */
+ for (i = 0; i < ARRAY_SIZE(ab8500_regus); ++i)
+ status += enable_regulator(ab8500_regus[i].supply);
+
+ return status;
}
void ux500_ab8500_shutdown(struct snd_pcm_substream *substream)
{
+ int i;
+
pr_info("%s: Enter\n", __func__);
/* Reset slots configuration to default(s) */
@@ -146,6 +116,10 @@ void ux500_ab8500_shutdown(struct snd_pcm_substream *substream)
tx_slots = DEF_TX_SLOTS;
else
rx_slots = DEF_RX_SLOTS;
+
+ /* Disable regulators */
+ for (i = 0; i < ARRAY_SIZE(ab8500_regus); ++i)
+ disable_regulator(ab8500_regus[i].supply);
}
int ux500_ab8500_hw_params(struct snd_pcm_substream *substream,
@@ -259,39 +233,6 @@ int ux500_ab8500_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static int regulator_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *k, int event)
-{
- if (SND_SOC_DAPM_EVENT_ON(event))
- enable_regulator(w->name);
- else
- disable_regulator(w->name);
- return 0;
-}
-
-static const struct snd_soc_dapm_widget dapm_widgets[] = {
- SND_SOC_DAPM_MIC("v-dmic", regulator_event),
- SND_SOC_DAPM_MIC("v-amic1", regulator_event),
- SND_SOC_DAPM_MIC("v-amic2", regulator_event),
- SND_SOC_DAPM_MIC("vcc-N2158", regulator_event),
-};
-
-static const struct snd_soc_dapm_route dapm_routes[] = {
- {"MIC1A", NULL, "v-amic1"},
-
- {"MIC1B", NULL, "vcc-N2158"},
- {"vcc-N2158", NULL, "v-amic1"},
-
- {"MIC2", NULL, "v-amic2"},
-
- {"DMIC1", NULL, "v-dmic"},
- {"DMIC2", NULL, "v-dmic"},
- {"DMIC3", NULL, "v-dmic"},
- {"DMIC4", NULL, "v-dmic"},
- {"DMIC5", NULL, "v-dmic"},
- {"DMIC6", NULL, "v-dmic"},
-};
-
static int create_jack(struct snd_soc_codec *codec)
{
return snd_soc_jack_new(codec,
@@ -312,19 +253,15 @@ void ux500_ab8500_jack_report(int value)
}
EXPORT_SYMBOL_GPL(ux500_ab8500_jack_report);
+
int ux500_ab8500_machine_codec_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
- int status = 0;
+ int status;
- pr_info("%s: Enter.\n", __func__);
+ pr_info("%s Enter.\n", __func__);
- status = create_regulators(codec->dev);
- if (status < 0) {
- pr_err("%s: Failed to instantiate regulators (%d).\n",
- __func__, status);
- return status;
- }
+ /* TODO: Add required DAPM routes to control regulators on demand */
status = create_jack(codec);
if (status < 0) {
@@ -332,19 +269,63 @@ int ux500_ab8500_machine_codec_init(struct snd_soc_pcm_runtime *rtd)
return status;
}
- snd_soc_dapm_new_controls(codec, dapm_widgets,
- ARRAY_SIZE(dapm_widgets));
- snd_soc_dapm_add_routes(codec, dapm_routes,
- ARRAY_SIZE(dapm_routes));
- snd_soc_dapm_sync(codec);
+ return 0;
+}
+
+static int create_regulators(void)
+{
+ int i, status = 0;
+
+ pr_debug("%s: Enter.\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(ab8500_regus); ++i)
+ ab8500_regus[i].consumer = NULL;
+
+ for (i = 0; i < ARRAY_SIZE(ab8500_regus); ++i) {
+ ab8500_regus[i].consumer = regulator_get(NULL,
+ ab8500_regus[i].supply);
+ if (IS_ERR(ab8500_regus[i].consumer)) {
+ status = PTR_ERR(ab8500_regus[i].consumer);
+ pr_err("%s: Failed to get supply '%s' (%d)\n",
+ __func__, ab8500_regus[i].supply, status);
+ ab8500_regus[i].consumer = NULL;
+ goto err_get;
+ }
+ }
+
+ return 0;
+
+err_get:
+
+ for (i = 0; i < ARRAY_SIZE(ab8500_regus); ++i) {
+ if (ab8500_regus[i].consumer) {
+ regulator_put(ab8500_regus[i].consumer);
+ ab8500_regus[i].consumer = NULL;
+ }
+ }
return status;
}
-void ux500_ab8500_soc_machine_drv_cleanup(void)
+int ux500_ab8500_soc_machine_drv_init(void)
{
+ int status = 0;
+
pr_info("%s: Enter.\n", __func__);
+ status = create_regulators();
+ if (status < 0) {
+ pr_err("%s: Failed to instantiate regulators (%d).\n",
+ __func__, status);
+ return status;
+ }
+
+ return 0;
+}
+
+void ux500_ab8500_soc_machine_drv_cleanup(void)
+{
+ pr_info("%s: Enter.\n", __func__);
regulator_bulk_free(ARRAY_SIZE(ab8500_regus), ab8500_regus);
}