aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/codecs/cx20442.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/cx20442.c')
-rw-r--r--sound/soc/codecs/cx20442.c90
1 files changed, 59 insertions, 31 deletions
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index e8d27c8f9ba..d5fd00a6474 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -15,18 +15,19 @@
#include <linux/tty.h>
#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
#include <sound/core.h>
#include <sound/initval.h>
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
#include "cx20442.h"
struct cx20442_priv {
- enum snd_soc_control_type control_type;
void *control_data;
- u8 reg_cache[1];
+ struct regulator *por;
};
#define CX20442_PM 0x0
@@ -87,17 +88,6 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
{"ADC", NULL, "Input Mixer"},
};
-static int cx20442_add_widgets(struct snd_soc_codec *codec)
-{
- snd_soc_dapm_new_controls(codec, cx20442_dapm_widgets,
- ARRAY_SIZE(cx20442_dapm_widgets));
-
- snd_soc_dapm_add_routes(codec, cx20442_audio_map,
- ARRAY_SIZE(cx20442_audio_map));
-
- return 0;
-}
-
static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
unsigned int reg)
{
@@ -263,7 +253,7 @@ static void v253_close(struct tty_struct *tty)
/* Prevent the codec driver from further accessing the modem */
codec->hw_write = NULL;
cx20442->control_data = NULL;
- codec->pop_time = 0;
+ codec->card->pop_time = 0;
}
/* Line discipline .hangup() */
@@ -291,7 +281,7 @@ static void v253_receive(struct tty_struct *tty,
/* Set up codec driver access to modem controls */
cx20442->control_data = tty;
codec->hw_write = (hw_write_t)tty->ops->write;
- codec->pop_time = 1;
+ codec->card->pop_time = 1;
}
}
@@ -335,6 +325,38 @@ static struct snd_soc_dai_driver cx20442_dai = {
},
};
+static int cx20442_set_bias_level(struct snd_soc_codec *codec,
+ enum snd_soc_bias_level level)
+{
+ struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+ int err = 0;
+
+ switch (level) {
+ case SND_SOC_BIAS_PREPARE:
+ if (codec->dapm.bias_level != SND_SOC_BIAS_STANDBY)
+ break;
+ if (IS_ERR(cx20442->por))
+ err = PTR_ERR(cx20442->por);
+ else
+ err = regulator_enable(cx20442->por);
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ if (codec->dapm.bias_level != SND_SOC_BIAS_PREPARE)
+ break;
+ if (IS_ERR(cx20442->por))
+ err = PTR_ERR(cx20442->por);
+ else
+ err = regulator_disable(cx20442->por);
+ break;
+ default:
+ break;
+ }
+ if (!err)
+ codec->dapm.bias_level = level;
+
+ return err;
+}
+
static int cx20442_codec_probe(struct snd_soc_codec *codec)
{
struct cx20442_priv *cx20442;
@@ -342,13 +364,15 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
if (cx20442 == NULL)
return -ENOMEM;
- snd_soc_codec_set_drvdata(codec, cx20442);
-
- cx20442_add_widgets(codec);
+ cx20442->por = regulator_get(codec->dev, "POR");
+ if (IS_ERR(cx20442->por))
+ dev_warn(codec->dev, "failed to get the regulator");
cx20442->control_data = NULL;
+
+ snd_soc_codec_set_drvdata(codec, cx20442);
codec->hw_write = NULL;
- codec->pop_time = 0;
+ codec->card->pop_time = 0;
return 0;
}
@@ -363,17 +387,31 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
tty_hangup(tty);
}
+ if (!IS_ERR(cx20442->por)) {
+ /* should be already in STANDBY, hence disabled */
+ regulator_put(cx20442->por);
+ }
+
+ snd_soc_codec_set_drvdata(codec, NULL);
kfree(cx20442);
return 0;
}
+static const u8 cx20442_reg;
+
static struct snd_soc_codec_driver cx20442_codec_dev = {
.probe = cx20442_codec_probe,
.remove = cx20442_codec_remove,
+ .set_bias_level = cx20442_set_bias_level,
+ .reg_cache_default = &cx20442_reg,
.reg_cache_size = 1,
.reg_word_size = sizeof(u8),
.read = cx20442_read_reg_cache,
.write = cx20442_write,
+ .dapm_widgets = cx20442_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets),
+ .dapm_routes = cx20442_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(cx20442_audio_map),
};
static int cx20442_platform_probe(struct platform_device *pdev)
@@ -397,17 +435,7 @@ static struct platform_driver cx20442_platform_driver = {
.remove = __exit_p(cx20442_platform_remove),
};
-static int __init cx20442_init(void)
-{
- return platform_driver_register(&cx20442_platform_driver);
-}
-module_init(cx20442_init);
-
-static void __exit cx20442_exit(void)
-{
- platform_driver_unregister(&cx20442_platform_driver);
-}
-module_exit(cx20442_exit);
+module_platform_driver(cx20442_platform_driver);
MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
MODULE_AUTHOR("Janusz Krzysztofik");